Back to index

cell-binutils  2.17cvs20070401
tc-maxq.c
Go to the documentation of this file.
00001 /* tc-maxq.c -- assembler code for a MAXQ chip.
00002 
00003    Copyright 2004, 2005, 2006 Free Software Foundation, Inc.
00004 
00005    Contributed by HCL Technologies Pvt. Ltd.
00006 
00007    Author: Vineet Sharma(vineets@noida.hcltech.com) Inderpreet
00008    S.(inderpreetb@noida.hcltech.com)
00009 
00010    This file is part of GAS.
00011 
00012    GAS is free software; you can redistribute it and/or modify it under the
00013    terms of the GNU General Public License as published by the Free Software
00014    Foundation; either version 2, or (at your option) any later version.
00015 
00016    GAS is distributed in the hope that it will be useful, but WITHOUT ANY
00017    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00018    FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
00019    details.
00020 
00021    You should have received a copy of the GNU General Public License along
00022    with GAS; see the file COPYING.  If not, write to the Free Software
00023    Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
00024 
00025 #include "as.h"
00026 #include "safe-ctype.h"
00027 #include "subsegs.h"
00028 #include "dwarf2dbg.h"
00029 #include "tc-maxq.h"
00030 #include "opcode/maxq.h"
00031 #include "ctype.h"
00032 
00033 #ifndef MAXQ10S
00034 #define MAXQ10S 1
00035 #endif
00036 
00037 #ifndef DEFAULT_ARCH
00038 #define DEFAULT_ARCH "MAXQ20"
00039 #endif
00040 
00041 #ifndef MAX_OPERANDS
00042 #define MAX_OPERANDS 2
00043 #endif
00044 
00045 #ifndef MAX_MNEM_SIZE
00046 #define MAX_MNEM_SIZE 8
00047 #endif
00048 
00049 #ifndef END_OF_INSN
00050 #define END_OF_INSN '\0'
00051 #endif
00052 
00053 #ifndef IMMEDIATE_PREFIX
00054 #define IMMEDIATE_PREFIX '#'
00055 #endif
00056 
00057 #ifndef MAX_REG_NAME_SIZE
00058 #define MAX_REG_NAME_SIZE 4
00059 #endif
00060 
00061 #ifndef MAX_MEM_NAME_SIZE
00062 #define MAX_MEM_NAME_SIZE 9
00063 #endif
00064 
00065 /* opcode for PFX[0].  */
00066 #define PFX0 0x0b
00067 
00068 /* Set default to MAXQ20.  */
00069 unsigned int max_version = bfd_mach_maxq20;
00070 
00071 const char *default_arch = DEFAULT_ARCH;
00072 
00073 /* Type of the operand: Register,Immediate,Memory access,flag or bit.  */
00074 
00075 union _maxq20_op
00076 {
00077   const reg_entry *  reg;
00078   char               imms; /* This is to store the immediate value operand.  */
00079   expressionS *      disps;
00080   symbolS *          data;
00081   const mem_access * mem;
00082   int                flag;
00083   const reg_bit *    r_bit;
00084 };
00085 
00086 typedef union _maxq20_op maxq20_opcode;
00087 
00088 /* For handling optional L/S in Maxq20.  */
00089 
00090 /* Exposed For Linker - maps indirectly to the liker relocations.  */
00091 #define LONG_PREFIX                MAXQ_LONGJUMP /* BFD_RELOC_16 */
00092 #define SHORT_PREFIX               MAXQ_SHORTJUMP       /* BFD_RELOC_16_PCREL_S2 */
00093 #define ABSOLUTE_ADDR_FOR_DATA     MAXQ_INTERSEGMENT
00094 
00095 #define NO_PREFIX                  0
00096 #define EXPLICT_LONG_PREFIX     14
00097 
00098 /* The main instruction structure containing fields to describe instrn */
00099 typedef struct _maxq20_insn
00100 {
00101   /* The opcode information for the MAXQ20 */
00102   MAXQ20_OPCODE_INFO op;
00103 
00104   /* The number of operands */
00105   unsigned int operands;
00106 
00107   /* Number of different types of operands - Comments can be removed if reqd. 
00108    */
00109   unsigned int reg_operands, mem_operands, disp_operands, data_operands;
00110   unsigned int imm_operands, imm_bit_operands, bit_operands, flag_operands;
00111 
00112   /* Types of the individual operands */
00113   UNKNOWN_OP types[MAX_OPERANDS];
00114 
00115   /* Relocation type for operand : to be investigated into */
00116   int reloc[MAX_OPERANDS];
00117 
00118   /* Complete information of the Operands */
00119   maxq20_opcode maxq20_op[MAX_OPERANDS];
00120 
00121   /* Choice of prefix register whenever needed */
00122   int prefix;
00123 
00124   /* Optional Prefix for Instructions like LJUMP, SJUMP etc */
00125   unsigned char Instr_Prefix;
00126 
00127   /* 16 bit Instruction word */
00128   unsigned char instr[2];
00129 }
00130 maxq20_insn;
00131 
00132 /* Definitions of all possible characters that can start an operand.  */
00133 const char *extra_symbol_chars = "@(#";
00134 
00135 /* Special Character that would start a comment.  */
00136 const char comment_chars[] = ";";
00137 
00138 /* Starts a comment when it appears at the start of a line.  */
00139 const char line_comment_chars[] = ";#";
00140 
00141 const char line_separator_chars[] = "";   /* originally may b by sudeep "\n".  */
00142 
00143 /*  The following are used for option processing.  */
00144 
00145 /* This is added to the mach independent string passed to getopt.  */
00146 const char *md_shortopts = "q";
00147 
00148 /* Characters for exponent and floating point.  */
00149 const char EXP_CHARS[] = "eE";
00150 const char FLT_CHARS[] = "";
00151 
00152 /* This is for the machine dependent option handling.  */
00153 #define OPTION_EB               (OPTION_MD_BASE + 0)
00154 #define OPTION_EL               (OPTION_MD_BASE + 1)
00155 #define MAXQ_10                 (OPTION_MD_BASE + 2)
00156 #define MAXQ_20                    (OPTION_MD_BASE + 3)
00157 
00158 struct option md_longopts[] =
00159 {
00160   {"MAXQ10", no_argument, NULL, MAXQ_10},
00161   {"MAXQ20", no_argument, NULL, MAXQ_20},
00162   {NULL, no_argument, NULL, 0}
00163 };
00164 size_t md_longopts_size = sizeof (md_longopts);
00165 
00166 /* md_undefined_symbol We have no need for this function.  */
00167 
00168 symbolS *
00169 md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
00170 {
00171   return NULL;
00172 }
00173 
00174 static void
00175 maxq_target (int target)
00176 {
00177   max_version = target;
00178   bfd_set_arch_mach (stdoutput, bfd_arch_maxq, max_version);
00179 }
00180 
00181 int
00182 md_parse_option (int c, char *arg ATTRIBUTE_UNUSED)
00183 {
00184   /* Any options support will be added onto this switch case.  */
00185   switch (c)
00186     {
00187     case MAXQ_10:
00188       max_version = bfd_mach_maxq10;
00189       break;
00190     case MAXQ_20:
00191       max_version = bfd_mach_maxq20;
00192       break;
00193 
00194     default:
00195       return 0;
00196     }
00197 
00198   return 1;
00199 }
00200 
00201 /* When a usage message is printed, this function is called and
00202    it prints a description of the machine specific options.  */
00203 
00204 void
00205 md_show_usage (FILE * stream)
00206 {
00207   /* Over here we will fill the description of the machine specific options.  */
00208 
00209   fprintf (stream, _(" MAXQ-specific assembler options:\n"));
00210 
00211   fprintf (stream, _("\
00212        -MAXQ20                     generate obj for MAXQ20(default)\n\
00213        -MAXQ10                     generate obj for MAXQ10\n\
00214        "));
00215 }
00216 
00217 unsigned long
00218 maxq20_mach (void)
00219 {
00220   if (!(strcmp (default_arch, "MAXQ20")))
00221     return 0;
00222 
00223   as_fatal (_("Unknown architecture"));
00224   return 1;
00225 }
00226 
00227 arelent *
00228 tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
00229 {
00230   arelent *rel;
00231   bfd_reloc_code_real_type code;
00232 
00233   switch (fixp->fx_r_type)
00234     {
00235     case MAXQ_INTERSEGMENT:
00236     case MAXQ_LONGJUMP:
00237     case BFD_RELOC_16_PCREL_S2:
00238       code = fixp->fx_r_type;
00239       break;
00240 
00241     case 0:
00242     default:
00243       switch (fixp->fx_size)
00244        {
00245        default:
00246          as_bad_where (fixp->fx_file, fixp->fx_line,
00247                      _("can not do %d byte relocation"), fixp->fx_size);
00248          code = BFD_RELOC_32;
00249          break;
00250 
00251        case 1:
00252          code = BFD_RELOC_8;
00253          break;
00254        case 2:
00255          code = BFD_RELOC_16;
00256          break;
00257        case 4:
00258          code = BFD_RELOC_32;
00259          break;
00260        }
00261     }
00262 
00263   rel = xmalloc (sizeof (arelent));
00264   rel->sym_ptr_ptr  = xmalloc (sizeof (asymbol *));
00265   *rel->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
00266 
00267   rel->address = fixp->fx_frag->fr_address + fixp->fx_where;
00268   rel->addend  = fixp->fx_addnumber;
00269   rel->howto   = bfd_reloc_type_lookup (stdoutput, code);
00270 
00271   if (rel->howto == NULL)
00272     {
00273       as_bad_where (fixp->fx_file, fixp->fx_line,
00274                   _("cannot represent relocation type %s"),
00275                   bfd_get_reloc_code_name (code));
00276 
00277       /* Set howto to a garbage value so that we can keep going.  */
00278       rel->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_32);
00279       assert (rel->howto != NULL);
00280     }
00281 
00282   return rel;
00283 }
00284 
00285 /* md_estimate_size_before_relax()
00286 
00287    Called just before relax() for rs_machine_dependent frags.  The MAXQ
00288    assembler uses these frags to handle 16 bit absolute jumps which require a 
00289    prefix instruction to be inserted. Any symbol that is now undefined will
00290    not become defined. Return the correct fr_subtype in the frag. Return the
00291    initial "guess for variable size of frag"(This will be eiter 2 or 0) to
00292    caller. The guess is actually the growth beyond the fixed part.  Whatever
00293    we do to grow the fixed or variable part contributes to our returned
00294    value.  */
00295 
00296 int
00297 md_estimate_size_before_relax (fragS *fragP, segT segment)
00298 {
00299   /* Check whether the symbol has been resolved or not.
00300      Otherwise we will have to generate a fixup.  */
00301   if ((S_GET_SEGMENT (fragP->fr_symbol) != segment)
00302       || fragP->fr_subtype == EXPLICT_LONG_PREFIX)
00303     {
00304       RELOC_ENUM reloc_type;
00305       unsigned char *opcode;
00306       int old_fr_fix;
00307 
00308       /* Now this symbol has not been defined in this file.
00309         Hence we will have to create a fixup.  */
00310       int size = 2;
00311 
00312       /* This is for the prefix instruction.  */
00313 
00314       if (fragP->fr_subtype == EXPLICT_LONG_PREFIX)
00315        fragP->fr_subtype = LONG_PREFIX;
00316 
00317       if (S_GET_SEGMENT (fragP->fr_symbol) != segment
00318          && ((!(fragP->fr_subtype) == EXPLICT_LONG_PREFIX)))
00319        fragP->fr_subtype = ABSOLUTE_ADDR_FOR_DATA;
00320 
00321       reloc_type =
00322        (fragP->fr_subtype ? fragP->fr_subtype : ABSOLUTE_ADDR_FOR_DATA);
00323 
00324       fragP->fr_subtype = reloc_type;
00325 
00326       if (reloc_type == SHORT_PREFIX)
00327        size = 0;
00328       old_fr_fix = fragP->fr_fix;
00329       opcode = (unsigned char *) fragP->fr_opcode;
00330 
00331       fragP->fr_fix += (size);
00332 
00333       fix_new (fragP, old_fr_fix - 2, size + 2,
00334               fragP->fr_symbol, fragP->fr_offset, 0, reloc_type);
00335       frag_wane (fragP);
00336       return fragP->fr_fix - old_fr_fix;
00337     }
00338 
00339   if (fragP->fr_subtype == SHORT_PREFIX)
00340     {
00341       fragP->fr_subtype = SHORT_PREFIX;
00342       return 0;
00343     }
00344 
00345   if (fragP->fr_subtype == NO_PREFIX || fragP->fr_subtype == LONG_PREFIX)
00346     {
00347       unsigned long instr;
00348       unsigned long call_addr;
00349       long diff;
00350       fragS *f;
00351       diff = diff ^ diff;;
00352       call_addr = call_addr ^ call_addr;
00353       instr = 0;
00354       f = NULL;
00355 
00356       /* segment_info_type *seginfo = seg_info (segment);  */
00357       instr = fragP->fr_address + fragP->fr_fix - 2;
00358 
00359       /* This is the offset if it is a PC relative jump.  */
00360       call_addr = S_GET_VALUE (fragP->fr_symbol) + fragP->fr_offset;
00361 
00362       /* PC stores the value of the next instruction.  */
00363       diff = (call_addr - instr) - 1;
00364 
00365       if (diff >= (-128 * 2) && diff <= (2 * 127))
00366        {
00367          /* Now as offset is an 8 bit value, we will pass
00368             that to the jump instruction directly.  */
00369          fragP->fr_subtype = NO_PREFIX;
00370          return 0;
00371        }
00372 
00373       fragP->fr_subtype = LONG_PREFIX;
00374       return 2;
00375     }
00376 
00377   as_fatal (_("Illegal Reloc type in md_estimate_size_before_relax for line : %d"),
00378            frag_now->fr_line);
00379   return 0;
00380 }
00381 
00382 /* Equal to MAX_PRECISION in atof-ieee.c */
00383 #define MAX_LITTLENUMS 6
00384 
00385 /* Turn a string in input_line_pointer into a floating point constant of type 
00386    TYPE, and store the appropriate bytes in *LITP.  The number of LITTLENUMS
00387    emitted is stored in *SIZEP.  An error message is returned, or NULL on OK.  */
00388 
00389 char *
00390 md_atof (int type, char * litP, int * sizeP)
00391 {
00392   int prec;
00393   LITTLENUM_TYPE words[4];
00394   char *t;
00395   int i;
00396 
00397   switch (type)
00398     {
00399     case 'f':
00400       prec = 2;
00401       break;
00402 
00403     case 'd':
00404       prec = 2;
00405       /* The size of Double has been changed to 2 words ie 32 bits.  */
00406       /* prec = 4; */
00407       break;
00408 
00409     default:
00410       *sizeP = 0;
00411       return _("bad call to md_atof");
00412     }
00413 
00414   t = atof_ieee (input_line_pointer, type, words);
00415   if (t)
00416     input_line_pointer = t;
00417 
00418   *sizeP = prec * 2;
00419 
00420   for (i = prec - 1; i >= 0; i--)
00421     {
00422       md_number_to_chars (litP, (valueT) words[i], 2);
00423       litP += 2;
00424     }
00425 
00426   return NULL;
00427 }
00428 
00429 void
00430 maxq20_cons_fix_new (fragS * frag, unsigned int off, unsigned int len,
00431                    expressionS * exp)
00432 {
00433   int r = 0;
00434 
00435   switch (len)
00436     {
00437     case 2:
00438       r = MAXQ_WORDDATA;    /* Word+n */
00439       break;
00440     case 4:
00441       r = MAXQ_LONGDATA;    /* Long+n */
00442       break;
00443     }
00444 
00445   fix_new_exp (frag, off, len, exp, 0, r);
00446   return;
00447 }
00448 
00449 /* GAS will call this for every rs_machine_dependent fragment. The
00450    instruction is completed using the data from the relaxation pass. It may
00451    also create any necessary relocations.  */
00452 void
00453 md_convert_frag (bfd *   headers ATTRIBUTE_UNUSED,
00454                segT    seg ATTRIBUTE_UNUSED,
00455                fragS * fragP)
00456 {
00457   char *opcode;
00458   offsetT target_address;
00459   offsetT opcode_address;
00460   offsetT displacement_from_opcode_start;
00461   int address;
00462 
00463   opcode = fragP->fr_opcode;
00464   address = 0;
00465   target_address = opcode_address = displacement_from_opcode_start = 0;
00466 
00467   target_address =
00468     (S_GET_VALUE (fragP->fr_symbol) / MAXQ_OCTETS_PER_BYTE) +
00469     (fragP->fr_offset / MAXQ_OCTETS_PER_BYTE);
00470 
00471   opcode_address =
00472     (fragP->fr_address / MAXQ_OCTETS_PER_BYTE) +
00473     ((fragP->fr_fix - 2) / MAXQ_OCTETS_PER_BYTE);
00474 
00475   /* PC points to the next Instruction.  */
00476   displacement_from_opcode_start = ((target_address - opcode_address)  - 1);
00477 
00478   if ((displacement_from_opcode_start >= -128
00479        && displacement_from_opcode_start <= 127)
00480       && (fragP->fr_subtype == SHORT_PREFIX
00481          || fragP->fr_subtype == NO_PREFIX))
00482     {
00483       /* Its a displacement.  */
00484       *opcode = (char) displacement_from_opcode_start;
00485     }
00486   else
00487     {
00488       /* Its an absolute 16 bit jump. Now we have to
00489         load the prefix operator with the upper 8 bits.  */
00490       if (fragP->fr_subtype == SHORT_PREFIX)
00491        {
00492          as_bad (_("Cant make long jump/call into short jump/call : %d"),
00493                 fragP->fr_line);
00494          return;
00495        }
00496 
00497       /* Check whether the symbol has been resolved or not.
00498         Otherwise we will have to generate a fixup.  */
00499 
00500       if (fragP->fr_subtype != SHORT_PREFIX)
00501        {
00502          RELOC_ENUM reloc_type;
00503          int old_fr_fix;
00504          int size = 2;
00505 
00506          /* Now this is a basolute jump/call.
00507             Hence we will have to create a fixup.  */
00508          if (fragP->fr_subtype == NO_PREFIX)
00509            fragP->fr_subtype = LONG_PREFIX;
00510 
00511          reloc_type =
00512            (fragP->fr_subtype ? fragP->fr_subtype : LONG_PREFIX);
00513 
00514          if (reloc_type == 1)
00515            size = 0;
00516          old_fr_fix = fragP->fr_fix;
00517 
00518          fragP->fr_fix += (size);
00519 
00520          fix_new (fragP, old_fr_fix - 2, size + 2,
00521                  fragP->fr_symbol, fragP->fr_offset, 0, reloc_type);
00522          frag_wane (fragP);
00523        }
00524     }
00525 }
00526 
00527 long
00528 md_pcrel_from (fixS *fixP)
00529 {
00530   return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
00531 }
00532 
00533 /* Writes the val to the buf, where n is the nuumber of bytes to write.  */
00534 
00535 void
00536 maxq_number_to_chars (char *buf, valueT val, int n)
00537 {
00538   if (target_big_endian)
00539     number_to_chars_bigendian (buf, val, n);
00540   else
00541     number_to_chars_littleendian (buf, val, n);
00542 }
00543 
00544 /* GAS will call this for each fixup. It's main objective is to store the
00545    correct value in the object file. 'fixup_segment' performs the generic
00546    overflow check on the 'valueT *val' argument after md_apply_fix returns.
00547    If the overflow check is relevant for the target machine, then
00548    'md_apply_fix' should modify 'valueT *val', typically to the value stored 
00549    in the object file (not to be done in MAXQ).  */
00550 
00551 void
00552 md_apply_fix (fixS *fixP, valueT *valT, segT seg ATTRIBUTE_UNUSED)
00553 {
00554   char *p = fixP->fx_frag->fr_literal + fixP->fx_where;
00555   char *frag_to_fix_at =
00556     fixP->fx_frag->fr_literal + fixP->fx_frag->fr_fix - 2;
00557 
00558   if (fixP)
00559     {
00560       if (fixP->fx_frag && valT)
00561        {
00562          /* If the relaxation substate is not defined we make it equal
00563             to the kind of relocation the fixup is generated for.  */
00564          if (!fixP->fx_frag->fr_subtype)
00565            fixP->fx_frag->fr_subtype = fixP->fx_r_type;
00566 
00567          /* For any instruction in which either we have specified an
00568             absolute address or it is a long jump we need to add a PFX0
00569             instruction to it. In this case as the instruction has already
00570             being written at 'fx_where' in the frag we copy it at the end of 
00571             the frag(which is where the relocation was generated) as when
00572             the relocation is generated the frag is grown by 2 type, this is 
00573             where we copy the contents of fx_where and add a pfx0 at
00574             fx_where.  */
00575          if ((fixP->fx_frag->fr_subtype == ABSOLUTE_ADDR_FOR_DATA)
00576              || (fixP->fx_frag->fr_subtype == LONG_PREFIX))
00577            {
00578              *(frag_to_fix_at + 1) = *(p + 1);
00579              maxq_number_to_chars (p + 1, PFX0, 1);
00580            }
00581 
00582          /* Remember value for tc_gen_reloc.  */
00583          fixP->fx_addnumber = *valT;
00584        }
00585 
00586       /* Some fixups generated by GAS which gets resovled before this this
00587          func. is called need to be wriiten to the frag as here we are going
00588          to go away with the relocations fx_done=1.  */
00589       if (fixP->fx_addsy == NULL)
00590        {
00591          maxq_number_to_chars (p, *valT, fixP->fx_size);
00592          fixP->fx_addnumber = *valT;
00593          fixP->fx_done = 1;
00594        }
00595     }
00596 }
00597 
00598 /* Tables for lexical analysis.  */
00599 static char mnemonic_chars[256];
00600 static char register_chars[256];
00601 static char operand_chars[256];
00602 static char identifier_chars[256];
00603 static char digit_chars[256];
00604 
00605 /* Lexical Macros.  */
00606 #define is_mnemonic_char(x)   (mnemonic_chars[(unsigned char)(x)])
00607 #define is_register_char(x)   (register_chars[(unsigned char)(x)])
00608 #define is_operand_char(x)    (operand_chars[(unsigned char)(x)])
00609 #define is_space_char(x)      (x==' ')
00610 #define is_identifier_char(x) (identifier_chars[(unsigned char)(x)])
00611 #define is_digit_char(x)      (identifier_chars[(unsigned char)(x)])
00612 
00613 /* Special characters for operands.  */
00614 static char operand_special_chars[] = "[]@.-+";
00615 
00616 /* md_assemble() will always leave the instruction passed to it unaltered.
00617    To do this we store the instruction in a special stack.  */
00618 static char save_stack[32];
00619 static char *save_stack_p;
00620 
00621 #define END_STRING_AND_SAVE(s)     \
00622   do                        \
00623     {                       \
00624       *save_stack_p++ = *(s);      \
00625       *s = '\0';            \
00626     }                       \
00627   while (0)
00628 
00629 #define RESTORE_END_STRING(s)      \
00630   do                        \
00631     {                       \
00632       *(s) = *(--save_stack_p);    \
00633     }                       \
00634   while (0)
00635 
00636 /* The instruction we are assembling.  */
00637 static maxq20_insn i;
00638 
00639 /* The current template.  */
00640 static MAXQ20_OPCODES *current_templates;
00641 
00642 /* The displacement operand if any.  */
00643 static expressionS disp_expressions;
00644 
00645 /* Current Operand we are working on (0:1st operand,1:2nd operand).  */
00646 static int this_operand;
00647 
00648 /* The prefix instruction if used.  */
00649 static char PFX_INSN[2];
00650 static char INSERT_BUFFER[2];
00651 
00652 /* For interface with expression() ????? */
00653 extern char *input_line_pointer;
00654 
00655 /* The HASH Tables:  */
00656 
00657 /* Operand Hash Table.  */
00658 static struct hash_control *op_hash;
00659 
00660 /* Register Hash Table.  */
00661 static struct hash_control *reg_hash;
00662 
00663 /* Memory reference Hash Table.  */
00664 static struct hash_control *mem_hash;
00665 
00666 /* Bit hash table.  */
00667 static struct hash_control *bit_hash;
00668 
00669 /* Memory Access syntax table.  */
00670 static struct hash_control *mem_syntax_hash;
00671 
00672 /* This is a mapping from pseudo-op names to functions.  */
00673 
00674 const pseudo_typeS md_pseudo_table[] =
00675 {
00676   {"int", cons, 2},         /* size of 'int' has been changed to 1 word
00677                                (i.e) 16 bits.  */
00678   {"maxq10", maxq_target, bfd_mach_maxq10},
00679   {"maxq20", maxq_target, bfd_mach_maxq20},
00680   {NULL, 0, 0},
00681 };
00682 
00683 #define SET_PFX_ARG(x) (PFX_INSN[1] = x)
00684 
00685 
00686 /* This function sets the PFX value corresponding to the specs. Source
00687    Destination Index Selection ---------------------------------- Write To|
00688    SourceRegRange | Dest Addr Range
00689    ------------------------------------------------------ PFX[0] | 0h-Fh |
00690    0h-7h PFX[1] | 10h-1Fh | 0h-7h PFX[2] | 0h-Fh | 8h-Fh PFX[3] | 10h-1Fh |
00691    8h-Fh PFX[4] | 0h-Fh | 10h-17h PFX[5] | 10h-1Fh | 10h-17h PFX[6] | 0h-Fh | 
00692    18h-1Fh PFX[7] | 0h-Fh | 18h-1Fh */
00693 
00694 static void
00695 set_prefix (void)
00696 {
00697   short int src_index = 0, dst_index = 0;
00698 
00699   if (i.operands == 0)
00700     return;
00701   if (i.operands == 1)             /* Only SRC is Present */
00702     {
00703       if (i.types[0] == REG)
00704        {
00705          if (!strcmp (i.op.name, "POP") || !strcmp (i.op.name, "POPI"))
00706            {
00707              dst_index = i.maxq20_op[0].reg[0].Mod_index;
00708              src_index = 0x00;
00709            }
00710          else
00711            {
00712              src_index = i.maxq20_op[0].reg[0].Mod_index;
00713              dst_index = 0x00;
00714            }
00715        }
00716     }
00717 
00718   if (i.operands == 2)
00719     {
00720       if (i.types[0] == REG && i.types[1] == REG)
00721        {
00722          dst_index = i.maxq20_op[0].reg[0].Mod_index;
00723          src_index = i.maxq20_op[1].reg[0].Mod_index;
00724        }
00725       else if (i.types[0] != REG && i.types[1] == REG)  /* DST is Absent */
00726        {
00727          src_index = i.maxq20_op[1].reg[0].Mod_index;
00728          dst_index = 0x00;
00729        }
00730       else if (i.types[0] == REG && i.types[1] != REG)  /* Id SRC is Absent */
00731        {
00732          dst_index = i.maxq20_op[0].reg[0].Mod_index;
00733          src_index = 0x00;
00734        }
00735       else if (i.types[0] == BIT && i.maxq20_op[0].r_bit)
00736        {
00737          dst_index = i.maxq20_op[0].r_bit->reg->Mod_index;
00738          src_index = 0x00;
00739        }
00740 
00741       else if (i.types[1] == BIT && i.maxq20_op[1].r_bit)
00742        {
00743          dst_index = 0x00;
00744          src_index = i.maxq20_op[1].r_bit->reg->Mod_index;
00745        }
00746     }
00747 
00748   if (src_index >= 0x00 && src_index <= 0xF)
00749     {
00750       if (dst_index >= 0x00 && dst_index <= 0x07)
00751        /* Set PFX[0] */
00752        i.prefix = 0;
00753 
00754       else if (dst_index >= 0x08 && dst_index <= 0x0F)
00755        /* Set PFX[2] */
00756        i.prefix = 2;
00757 
00758       else if (dst_index >= 0x10 && dst_index <= 0x17)
00759        /* Set PFX[4] */
00760        i.prefix = 4;
00761 
00762       else if (dst_index >= 0x18 && dst_index <= 0x1F)
00763        /* Set PFX[6] */
00764        i.prefix = 6;
00765     }
00766   else if (src_index >= 0x10 && src_index <= 0x1F)
00767     {
00768       if (dst_index >= 0x00 && dst_index <= 0x07)
00769        /* Set PFX[1] */
00770        i.prefix = 1;
00771 
00772       else if (dst_index >= 0x08 && dst_index <= 0x0F)
00773        /* Set PFX[3] */
00774        i.prefix = 3;
00775 
00776       else if (dst_index >= 0x10 && dst_index <= 0x17)
00777        /* Set PFX[5] */
00778        i.prefix = 5;
00779 
00780       else if (dst_index >= 0x18 && dst_index <= 0x1F)
00781        /* Set PFX[7] */
00782        i.prefix = 7;
00783     }
00784 }
00785 
00786 static unsigned char
00787 is_a_LSinstr (const char *ln_pointer)
00788 {
00789   int i = 0;
00790 
00791   for (i = 0; LSInstr[i] != NULL; i++)
00792     if (!strcmp (LSInstr[i], ln_pointer))
00793       return 1;
00794 
00795   return 0;
00796 }
00797 
00798 static void
00799 LS_processing (const char *line)
00800 {
00801   if (is_a_LSinstr (line))
00802     {
00803       if ((line[0] == 'L') || (line[0] == 'l'))
00804        {
00805          i.prefix = 0;
00806          INSERT_BUFFER[0] = PFX0;
00807          i.Instr_Prefix = LONG_PREFIX;
00808        }
00809       else if ((line[0] == 'S') || (line[0] == 's'))
00810        i.Instr_Prefix = SHORT_PREFIX;
00811       else
00812        i.Instr_Prefix = NO_PREFIX;
00813     }
00814   else
00815     i.Instr_Prefix = LONG_PREFIX;
00816 }
00817 
00818 /* Separate mnemonics and the operands.  */
00819 
00820 static char *
00821 parse_insn (char *line, char *mnemonic)
00822 {
00823   char *l = line;
00824   char *token_start = l;
00825   char *mnem_p;
00826   char temp[MAX_MNEM_SIZE];
00827   int ii = 0;
00828 
00829   memset (temp, END_OF_INSN, MAX_MNEM_SIZE);
00830   mnem_p = mnemonic;
00831 
00832   while ((*mnem_p = mnemonic_chars[(unsigned char) *l]) != 0)
00833     {
00834       ii++;
00835       mnem_p++;
00836       if (mnem_p >= mnemonic + MAX_MNEM_SIZE)
00837        {
00838          as_bad (_("no such instruction: `%s'"), token_start);
00839          return NULL;
00840        }
00841       l++;
00842     }
00843 
00844   if (!is_space_char (*l) && *l != END_OF_INSN)
00845     {
00846       as_bad (_("invalid character %s in mnemonic"), l);
00847       return NULL;
00848     }
00849 
00850   while (ii)
00851     {
00852       temp[ii - 1] = toupper ((char) mnemonic[ii - 1]);
00853       ii--;
00854     }
00855 
00856   LS_processing (temp);
00857 
00858   if (i.Instr_Prefix != 0 && is_a_LSinstr (temp))
00859     /* Skip the optional L-S.  */
00860     memcpy (temp, temp + 1, MAX_MNEM_SIZE);
00861 
00862   /* Look up instruction (or prefix) via hash table.  */
00863   current_templates = (MAXQ20_OPCODES *) hash_find (op_hash, temp);
00864 
00865   if (current_templates != NULL)
00866     return l;
00867 
00868   as_bad (_("no such instruction: `%s'"), token_start);
00869   return NULL;
00870 }
00871 
00872 /* Function to calculate x to the power of y.
00873    Just to avoid including the math libraries.  */
00874 
00875 static int
00876 pwr (int x, int y)
00877 {
00878   int k, ans = 1;
00879 
00880   for (k = 0; k < y; k++)
00881     ans *= x;
00882 
00883   return ans;
00884 }
00885 
00886 static reg_entry *
00887 parse_reg_by_index (char *imm_start)
00888 {
00889   int k = 0, mid = 0, rid = 0, val = 0, j = 0;
00890   char temp[4] = { 0 };
00891   reg_entry *reg = NULL;
00892 
00893   do
00894     {
00895       if (isdigit (imm_start[k]))
00896        temp[k] = imm_start[k] - '0';
00897 
00898       else if (isalpha (imm_start[k])
00899               && (imm_start[k] = tolower (imm_start[k])) < 'g')
00900        temp[k] = 10 + (int) (imm_start[k] - 'a');
00901 
00902       else if (imm_start[k] == 'h')
00903        break;
00904 
00905       else if (imm_start[k] == END_OF_INSN)
00906        {
00907          imm_start[k] = 'd';
00908          break;
00909        }
00910 
00911       else
00912        return NULL;         /* not a hex digit */
00913 
00914       k++;
00915     }
00916   while (imm_start[k] != '\n');
00917 
00918   switch (imm_start[k])
00919     {
00920     case 'h':
00921       for (j = 0; j < k; j++)
00922        val += temp[j] * pwr (16, k - j - 1);
00923       break;
00924 
00925     case 'd':
00926       for (j = 0; j < k; j++)
00927        {
00928          if (temp[j] > 9)
00929            return NULL;     /* not a number */
00930 
00931          val += temp[j] * pwr (10, k - j - 1);
00932          break;
00933        }
00934     }
00935 
00936   /* Get the module and register id's.  */
00937   mid = val & 0x0f;
00938   rid = (val >> 4) & 0x0f;
00939 
00940   if (mid < 6)
00941     {
00942       /* Search the pheripheral reg table.  */
00943       for (j = 0; j < num_of_reg; j++)
00944        {
00945          if (new_reg_table[j].opcode == val)
00946            {
00947              reg = (reg_entry *) & new_reg_table[j];
00948              break;
00949            }
00950        }
00951     }
00952 
00953   else
00954     {
00955       /* Search the system register table.  */
00956       j = 0;
00957 
00958       while (system_reg_table[j].reg_name != NULL)
00959        {
00960          if (system_reg_table[j].opcode == val)
00961            {
00962              reg = (reg_entry *) & system_reg_table[j];
00963              break;
00964            }
00965          j++;
00966        }
00967     }
00968 
00969   if (reg == NULL)
00970     {
00971       as_bad (_("Invalid register value %s"), imm_start);
00972       return reg;
00973     }
00974 
00975 #if CHANGE_PFX
00976   if (this_operand == 0 && reg != NULL)
00977     {
00978       if (reg->Mod_index > 7)
00979        i.prefix = 2;
00980       else
00981        i.prefix = 0;
00982     }
00983 #endif
00984   return (reg_entry *) reg;
00985 }
00986 
00987 /* REG_STRING starts *before* REGISTER_PREFIX.  */
00988 
00989 static reg_entry *
00990 parse_register (char *reg_string, char **end_op)
00991 {
00992   char *s = reg_string;
00993   char *p = NULL;
00994   char reg_name_given[MAX_REG_NAME_SIZE + 1];
00995   reg_entry *r = NULL;
00996 
00997   r = NULL;
00998   p = NULL;
00999 
01000   /* Skip possible REGISTER_PREFIX and possible whitespace.  */
01001   if (is_space_char (*s))
01002     ++s;
01003 
01004   p = reg_name_given;
01005   while ((*p++ = register_chars[(unsigned char) *s]) != '\0')
01006     {
01007       if (p >= reg_name_given + MAX_REG_NAME_SIZE)
01008        return (reg_entry *) NULL;
01009       s++;
01010     }
01011 
01012   *end_op = s;
01013 
01014   r = (reg_entry *) hash_find (reg_hash, reg_name_given);
01015 
01016 #if CHANGE_PFX
01017   if (this_operand == 0 && r != NULL)
01018     {
01019       if (r->Mod_index > 7)
01020        i.prefix = 2;
01021       else
01022        i.prefix = 0;
01023     }
01024 #endif
01025   return r;
01026 }
01027 
01028 static reg_bit *
01029 parse_register_bit (char *reg_string, char **end_op)
01030 {
01031   const char *s = reg_string;
01032   short k = 0;
01033   char diff = 0;
01034   reg_bit *rb = NULL;
01035   reg_entry *r = NULL;
01036   bit_name *b = NULL;
01037   char temp_bitname[MAX_REG_NAME_SIZE + 2];
01038   char temp[MAX_REG_NAME_SIZE + 1];
01039 
01040   memset (&temp, '\0', (MAX_REG_NAME_SIZE + 1));
01041   memset (&temp_bitname, '\0', (MAX_REG_NAME_SIZE + 2));
01042 
01043   diff = 0;
01044   r = NULL;
01045   rb = NULL;
01046   rb = xmalloc (sizeof (reg_bit));
01047   rb->reg = xmalloc (sizeof (reg_entry));
01048   k = 0;
01049 
01050   /* For supporting bit names.  */
01051   b = (bit_name *) hash_find (bit_hash, reg_string);
01052 
01053   if (b != NULL)
01054     {
01055       *end_op = reg_string + strlen (reg_string);
01056       strcpy (temp_bitname, b->reg_bit);
01057       s = temp_bitname;
01058     }
01059 
01060   if (strchr (s, '.'))
01061     {
01062       while (*s != '.')
01063        {
01064          if (*s == '\0')
01065            return NULL;
01066          temp[k] = *s++;
01067 
01068          k++;
01069        }
01070       temp[k] = '\0';
01071     }
01072 
01073   if ((r = parse_register (temp, end_op)) == NULL)
01074     return NULL;
01075 
01076   rb->reg = r;
01077 
01078   /* Skip the "."  */
01079   s++;
01080 
01081   if (isdigit ((char) *s))
01082     rb->bit = atoi (s);
01083   else if (isalpha ((char) *s))
01084     {
01085       rb->bit = (char) *s - 'a';
01086       rb->bit += 10;
01087       if (rb->bit > 15)
01088        {
01089          as_bad (_("Invalid bit number : '%c'"), (char) *s);
01090          return NULL;
01091        }
01092     }
01093 
01094   if (b != NULL)
01095     diff = strlen (temp_bitname) - strlen (temp) - 1;
01096   else
01097     diff = strlen (reg_string) - strlen (temp) - 1;
01098 
01099   if (*(s + diff) != '\0')
01100     {
01101       as_bad (_("Illegal character after operand '%s'"), reg_string);
01102       return NULL;
01103     }
01104 
01105   return rb;
01106 }
01107 
01108 static void
01109 pfx_for_imm_val (int arg)
01110 {
01111   if (i.prefix == -1)
01112     return;
01113 
01114   if (i.prefix == 0 && arg == 0 && PFX_INSN[1] == 0 && !(i.data_operands))
01115     return;
01116 
01117   if (!(i.prefix < 0) && !(i.prefix > 7))
01118     PFX_INSN[0] = (i.prefix << 4) | PFX0;
01119 
01120   if (!PFX_INSN[1])
01121     PFX_INSN[1] = arg;
01122 
01123 }
01124 
01125 static int
01126 maxq20_immediate (char *imm_start)
01127 {
01128   int val = 0, val_pfx = 0;
01129   char sign_val = 0;
01130   int k = 0, j;
01131   int temp[4] = { 0 };
01132 
01133   imm_start++;
01134 
01135   if (imm_start[1] == '\0' && (imm_start[0] == '0' || imm_start[0] == '1')
01136       && (this_operand == 1 && ((i.types[0] == BIT || i.types[0] == FLAG))))
01137     {
01138       val = imm_start[0] - '0';
01139       i.imm_bit_operands++;
01140       i.types[this_operand] = IMMBIT;
01141       i.maxq20_op[this_operand].imms = (char) val;
01142 #if CHANGE_PFX
01143       if (i.prefix == 2)
01144        pfx_for_imm_val (0);
01145 #endif
01146       return 1;
01147     }
01148 
01149   /* Check For Sign Character.  */
01150   sign_val = 0;
01151 
01152   do
01153     {
01154       if (imm_start[k] == '-' && k == 0)
01155        sign_val = -1;
01156 
01157       else if (imm_start[k] == '+' && k == 0)
01158        sign_val = 1;
01159 
01160       else if (isdigit (imm_start[k]))
01161        temp[k] = imm_start[k] - '0';
01162 
01163       else if (isalpha (imm_start[k])
01164               && (imm_start[k] = tolower (imm_start[k])) < 'g')
01165        temp[k] = 10 + (int) (imm_start[k] - 'a');
01166 
01167       else if (imm_start[k] == 'h')
01168        break;
01169 
01170       else if (imm_start[k] == '\0')
01171        {
01172          imm_start[k] = 'd';
01173          break;
01174        }
01175       else
01176        {
01177          as_bad (_("Invalid Character in immediate Value : %c"),
01178                 imm_start[k]);
01179          return 0;
01180        }
01181       k++;
01182     }
01183   while (imm_start[k] != '\n');
01184 
01185   switch (imm_start[k])
01186     {
01187     case 'h':
01188       for (j = (sign_val ? 1 : 0); j < k; j++)
01189        val += temp[j] * pwr (16, k - j - 1);
01190       break;
01191 
01192     case 'd':
01193       for (j = (sign_val ? 1 : 0); j < k; j++)
01194        {
01195          if (temp[j] > 9)
01196            {
01197              as_bad (_("Invalid Character in immediate value : %c"),
01198                     imm_start[j]);
01199              return 0;
01200            }
01201          val += temp[j] * pwr (10, k - j - 1);
01202        }
01203     }
01204 
01205   if (!sign_val)
01206     sign_val = 1;
01207 
01208   /* Now over here the value val stores the 8 bit/16 bit value. We will put a 
01209      check if we are moving a 16 bit immediate value into an 8 bit register. 
01210      In that case we will generate a warning and move only the lower 8 bits */
01211   if (val > 65535)
01212     {
01213       as_bad (_("Immediate value greater than 16 bits"));
01214       return 0;
01215     }
01216 
01217   val = val * sign_val;
01218 
01219   /* If it is a stack pointer and the value is greater than the maximum
01220      permissible size */
01221   if (this_operand == 1)
01222     {
01223       if ((val * sign_val) > MAX_STACK && i.types[0] == REG
01224          && !strcmp (i.maxq20_op[0].reg->reg_name, "SP"))
01225        {
01226          as_warn (_
01227                  ("Attempt to move a value in the stack pointer greater than the size of the stack"));
01228          val = val & MAX_STACK;
01229        }
01230 
01231       /* Check the range for 8 bit registers.  */
01232       else if (((val * sign_val) > 0xFF) && (i.types[0] == REG)
01233               && (i.maxq20_op[0].reg->rtype == Reg_8W))
01234        {
01235          as_warn (_
01236                  ("Attempt to move 16 bit value into an 8 bit register.Truncating..\n"));
01237          val = val & 0xfe;
01238        }
01239 
01240       else if (((sign_val == -1) || (val > 0xFF)) && (i.types[0] == REG)
01241               && (i.maxq20_op[0].reg->rtype == Reg_8W))
01242        {
01243          val_pfx = val >> 8;
01244          val = ((val) & 0x00ff);
01245          SET_PFX_ARG (val_pfx);
01246          i.maxq20_op[this_operand].imms = (char) val;
01247        }
01248 
01249       else if ((val <= 0xff) && (i.types[0] == REG)
01250               && (i.maxq20_op[0].reg->rtype == Reg_8W))
01251        i.maxq20_op[this_operand].imms = (char) val;
01252 
01253 
01254       /* Check for 16 bit registers.  */
01255       else if (((sign_val == -1) || val > 0xFE) && i.types[0] == REG
01256               && i.maxq20_op[0].reg->rtype == Reg_16W)
01257        {
01258          /* Add PFX for any negative value -> 16bit register.  */
01259          val_pfx = val >> 8;
01260          val = ((val) & 0x00ff);
01261          SET_PFX_ARG (val_pfx);
01262          i.maxq20_op[this_operand].imms = (char) val;
01263        }
01264 
01265       else if (val < 0xFF && i.types[0] == REG
01266               && i.maxq20_op[0].reg->rtype == Reg_16W)
01267        {
01268          i.maxq20_op[this_operand].imms = (char) val;
01269        }
01270 
01271       /* All the immediate memory access - no PFX.  */
01272       else if (i.types[0] == MEM)
01273        {
01274          if ((sign_val == -1) || val > 0xFE)
01275            {
01276              val_pfx = val >> 8;
01277              val = ((val) & 0x00ff);
01278              SET_PFX_ARG (val_pfx);
01279              i.maxq20_op[this_operand].imms = (char) val;
01280            }
01281          else
01282            i.maxq20_op[this_operand].imms = (char) val;
01283        }
01284 
01285       /* Special handling for immediate jumps like jump nz, #03h etc.  */
01286       else if (val < 0xFF && i.types[0] == FLAG)
01287        i.maxq20_op[this_operand].imms = (char) val;
01288 
01289       else if ((((sign_val == -1) || val > 0xFE)) && i.types[0] == FLAG)
01290        {
01291          val_pfx = val >> 8;
01292          val = ((val) & 0x00ff);
01293          SET_PFX_ARG (val_pfx);
01294          i.maxq20_op[this_operand].imms = (char) val;
01295        }
01296       else
01297        {
01298          as_bad (_("Invalid immediate move operation"));
01299          return 0;
01300        }
01301     }
01302   else
01303     {
01304       /* All the instruction with operation on ACC: like ADD src, etc.  */
01305       if ((sign_val == -1) || val > 0xFE)
01306        {
01307          val_pfx = val >> 8;
01308          val = ((val) & 0x00ff);
01309          SET_PFX_ARG (val_pfx);
01310          i.maxq20_op[this_operand].imms = (char) val;
01311        }
01312       else
01313        i.maxq20_op[this_operand].imms = (char) val;
01314     }
01315 
01316   i.imm_operands++;
01317   return 1;
01318 }
01319 
01320 static int
01321 extract_int_val (const char *imm_start)
01322 {
01323   int k, j, val;
01324   char sign_val;
01325   int temp[4];
01326 
01327   k = 0;
01328   j = 0;
01329   val = 0;
01330   sign_val = 0;
01331   do
01332     {
01333       if (imm_start[k] == '-' && k == 0)
01334        sign_val = -1;
01335 
01336       else if (imm_start[k] == '+' && k == 0)
01337        sign_val = 1;
01338 
01339       else if (isdigit (imm_start[k]))
01340        temp[k] = imm_start[k] - '0';
01341 
01342       else if (isalpha (imm_start[k]) && (tolower (imm_start[k])) < 'g')
01343        temp[k] = 10 + (int) (tolower (imm_start[k]) - 'a');
01344 
01345       else if (tolower (imm_start[k]) == 'h')
01346        break;
01347 
01348       else if ((imm_start[k] == '\0') || (imm_start[k] == ']'))
01349        /* imm_start[k]='d'; */
01350        break;
01351 
01352       else
01353        {
01354          as_bad (_("Invalid Character in immediate Value : %c"),
01355                 imm_start[k]);
01356          return 0;
01357        }
01358       k++;
01359     }
01360   while (imm_start[k] != '\n');
01361 
01362   switch (imm_start[k])
01363     {
01364     case 'h':
01365       for (j = (sign_val ? 1 : 0); j < k; j++)
01366        val += temp[j] * pwr (16, k - j - 1);
01367       break;
01368 
01369     default:
01370       for (j = (sign_val ? 1 : 0); j < k; j++)
01371        {
01372          if (temp[j] > 9)
01373            {
01374              as_bad (_("Invalid Character in immediate value : %c"),
01375                     imm_start[j]);
01376              return 0;
01377            }
01378          val += temp[j] * pwr (10, k - j - 1);
01379        }
01380     }
01381 
01382   if (!sign_val)
01383     sign_val = 1;
01384 
01385   return val * sign_val;
01386 }
01387 
01388 static char
01389 check_for_parse (const char *line)
01390 {
01391   int val;
01392 
01393   if (*(line + 1) == '[')
01394     {
01395       do
01396        {
01397          line++;
01398          if ((*line == '-') || (*line == '+'))
01399            break;
01400        }
01401       while (!is_space_char (*line));
01402 
01403       if ((*line == '-') || (*line == '+'))
01404        val = extract_int_val (line);
01405       else
01406        val = extract_int_val (line + 1);
01407 
01408       INSERT_BUFFER[0] = 0x3E;
01409       INSERT_BUFFER[1] = val;
01410 
01411       return 1;
01412     }
01413 
01414   return 0;
01415 }
01416 
01417 static mem_access *
01418 maxq20_mem_access (char *mem_string, char **end_op)
01419 {
01420   char *s = mem_string;
01421   char *p;
01422   char mem_name_given[MAX_MEM_NAME_SIZE + 1];
01423   mem_access *m;
01424 
01425   m = NULL;
01426 
01427   /* Skip possible whitespace.  */
01428   if (is_space_char (*s))
01429     ++s;
01430 
01431   p = mem_name_given;
01432   while ((*p++ = register_chars[(unsigned char) *s]) != '\0')
01433     {
01434       if (p >= mem_name_given + MAX_MEM_NAME_SIZE)
01435        return (mem_access *) NULL;
01436       s++;
01437     }
01438 
01439   *end_op = s;
01440 
01441   m = (mem_access *) hash_find (mem_hash, mem_name_given);
01442 
01443   return m;
01444 }
01445 
01446 /* This function checks whether the operand is a variable in the data segment 
01447    and if so, it returns its symbol entry from the symbol table.  */
01448 
01449 static symbolS *
01450 maxq20_data (char *op_string)
01451 {
01452   symbolS *symbolP;
01453   symbolP = symbol_find (op_string);
01454 
01455   if (symbolP != NULL
01456       && S_GET_SEGMENT (symbolP) != now_seg
01457       && S_GET_SEGMENT (symbolP) != bfd_und_section_ptr)
01458     {
01459       /* In case we do not want to always include the prefix instruction and
01460          let the loader handle the job or in case of a 8 bit addressing mode, 
01461          we will just check for val_pfx to be equal to zero and then load the 
01462          prefix instruction. Otherwise no prefix instruction needs to be
01463          loaded.  */
01464       /* The prefix register will have to be loaded automatically as we have 
01465         a 16 bit addressing field.  */
01466       pfx_for_imm_val (0);
01467       return symbolP;
01468     }
01469 
01470   return NULL;
01471 }
01472 
01473 static int
01474 maxq20_displacement (char *disp_start, char *disp_end)
01475 {
01476   expressionS *exp;
01477   segT exp_seg = 0;
01478   char *save_input_line_pointer;
01479 #ifndef LEX_AT
01480   char *gotfree_input_line;
01481 #endif
01482 
01483   gotfree_input_line = NULL;
01484   exp = &disp_expressions;
01485   i.maxq20_op[this_operand].disps = exp;
01486   i.disp_operands++;
01487   save_input_line_pointer = input_line_pointer;
01488   input_line_pointer = disp_start;
01489 
01490   END_STRING_AND_SAVE (disp_end);
01491 
01492 #ifndef LEX_AT
01493   /* gotfree_input_line = lex_got (&i.reloc[this_operand], NULL); if
01494      (gotfree_input_line) input_line_pointer = gotfree_input_line; */
01495 #endif
01496   exp_seg = expression (exp);
01497 
01498   SKIP_WHITESPACE ();
01499   if (*input_line_pointer)
01500     as_bad (_("junk `%s' after expression"), input_line_pointer);
01501 #if GCC_ASM_O_HACK
01502   RESTORE_END_STRING (disp_end + 1);
01503 #endif
01504   RESTORE_END_STRING (disp_end);
01505   input_line_pointer = save_input_line_pointer;
01506 #ifndef LEX_AT
01507   if (gotfree_input_line)
01508     free (gotfree_input_line);
01509 #endif
01510   if (exp->X_op == O_absent || exp->X_op == O_big)
01511     {
01512       /* Missing or bad expr becomes absolute 0.  */
01513       as_bad (_("missing or invalid displacement expression `%s' taken as 0"),
01514              disp_start);
01515       exp->X_op = O_constant;
01516       exp->X_add_number = 0;
01517       exp->X_add_symbol = (symbolS *) 0;
01518       exp->X_op_symbol = (symbolS *) 0;
01519     }
01520 #if (defined (OBJ_AOUT) || defined (OBJ_MAYBE_AOUT))
01521 
01522   if (exp->X_op != O_constant
01523       && OUTPUT_FLAVOR == bfd_target_aout_flavour
01524       && exp_seg != absolute_section
01525       && exp_seg != text_section
01526       && exp_seg != data_section
01527       && exp_seg != bss_section && exp_seg != undefined_section
01528       && !bfd_is_com_section (exp_seg))
01529     {
01530       as_bad (_("unimplemented segment %s in operand"), exp_seg->name);
01531       return 0;
01532     }
01533 #endif
01534   i.maxq20_op[this_operand].disps = exp;
01535   return 1;
01536 }
01537 
01538 /* Parse OPERAND_STRING into the maxq20_insn structure I.
01539    Returns non-zero on error.  */
01540 
01541 static int
01542 maxq20_operand (char *operand_string)
01543 {
01544   reg_entry *r = NULL;
01545   reg_bit *rb = NULL;
01546   mem_access *m = NULL;
01547   char *end_op = NULL;
01548   symbolS *sym = NULL;
01549   char *base_string = NULL;
01550   int ii = 0;
01551   /* Start and end of displacement string expression (if found).  */
01552   char *displacement_string_start = NULL;
01553   char *displacement_string_end = NULL;
01554   /* This maintains the  case sentivness.  */
01555   char case_str_op_string[MAX_OPERAND_SIZE + 1];
01556   char str_op_string[MAX_OPERAND_SIZE + 1];
01557   char *org_case_op_string = case_str_op_string;
01558   char *op_string = str_op_string;
01559 
01560   
01561   memset (op_string, END_OF_INSN, (MAX_OPERAND_SIZE + 1));
01562   memset (org_case_op_string, END_OF_INSN, (MAX_OPERAND_SIZE + 1));
01563 
01564   memcpy (op_string, operand_string, strlen (operand_string) + 1);
01565   memcpy (org_case_op_string, operand_string, strlen (operand_string) + 1);
01566 
01567   ii = strlen (operand_string) + 1;
01568 
01569   if (ii > MAX_OPERAND_SIZE)
01570     {
01571       as_bad (_("Size of Operand '%s' greater than %d"), op_string,
01572              MAX_OPERAND_SIZE);
01573       return 0;
01574     }
01575 
01576   while (ii)
01577     {
01578       op_string[ii - 1] = toupper ((char) op_string[ii - 1]);
01579       ii--;
01580     }
01581 
01582   if (is_space_char (*op_string))
01583     ++op_string;
01584 
01585   if (isxdigit (operand_string[0]))
01586     {
01587       /* Now the operands can start with an Integer.  */
01588       r = parse_reg_by_index (op_string);
01589       if (r != NULL)
01590        {
01591          if (is_space_char (*op_string))
01592            ++op_string;
01593          i.types[this_operand] = REG;     /* Set the type.  */
01594          i.maxq20_op[this_operand].reg = r;      /* Set the Register value.  */
01595          i.reg_operands++;
01596          return 1;
01597        }
01598 
01599       /* Get the original string.  */
01600       memcpy (op_string, operand_string, strlen (operand_string) + 1);
01601       ii = strlen (operand_string) + 1;
01602 
01603       while (ii)
01604        {
01605          op_string[ii - 1] = toupper ((char) op_string[ii - 1]);
01606          ii--;
01607        }
01608     }
01609 
01610   /* Check for flags.  */
01611   if (!strcmp (op_string, "Z"))
01612     {
01613       if (is_space_char (*op_string))
01614        ++op_string;
01615 
01616       i.types[this_operand] = FLAG;              /* Set the type.  */
01617       i.maxq20_op[this_operand].flag = FLAG_Z;   /* Set the Register value.  */
01618 
01619       i.flag_operands++;
01620 
01621       return 1;
01622     }
01623 
01624   else if (!strcmp (op_string, "NZ"))
01625     {
01626       if (is_space_char (*op_string))
01627        ++op_string;
01628 
01629       i.types[this_operand] = FLAG;              /* Set the type.  */
01630       i.maxq20_op[this_operand].flag = FLAG_NZ;  /* Set the Register value.  */
01631       i.flag_operands++;
01632       return 1;
01633     }
01634 
01635   else if (!strcmp (op_string, "NC"))
01636     {
01637       if (is_space_char (*op_string))
01638        ++op_string;
01639 
01640       i.types[this_operand] = FLAG;              /* Set the type.  */
01641       i.maxq20_op[this_operand].flag = FLAG_NC;  /* Set the Register value.  */
01642       i.flag_operands++;
01643       return 1;
01644     }
01645 
01646   else if (!strcmp (op_string, "E"))
01647     {
01648       if (is_space_char (*op_string))
01649        ++op_string;
01650 
01651       i.types[this_operand] = FLAG;              /* Set the type.  */
01652       i.maxq20_op[this_operand].flag = FLAG_E;   /* Set the Register value.  */
01653 
01654       i.flag_operands++;
01655 
01656       return 1;
01657     }
01658 
01659   else if (!strcmp (op_string, "S"))
01660     {
01661       if (is_space_char (*op_string))
01662        ++op_string;
01663 
01664       i.types[this_operand] = FLAG;       /* Set the type.  */
01665       i.maxq20_op[this_operand].flag = FLAG_S;   /* Set the Register value.  */
01666 
01667       i.flag_operands++;
01668 
01669       return 1;
01670     }
01671 
01672   else if (!strcmp (op_string, "C"))
01673     {
01674       if (is_space_char (*op_string))
01675        ++op_string;
01676 
01677       i.types[this_operand] = FLAG;       /* Set the type.  */
01678       i.maxq20_op[this_operand].flag = FLAG_C;   /* Set the Register value.  */
01679 
01680       i.flag_operands++;
01681 
01682       return 1;
01683     }
01684 
01685   else if (!strcmp (op_string, "NE"))
01686     {
01687 
01688       if (is_space_char (*op_string))
01689        ++op_string;
01690 
01691       i.types[this_operand] = FLAG;       /* Set the type.  */
01692 
01693       i.maxq20_op[this_operand].flag = FLAG_NE;  /* Set the Register value.  */
01694 
01695       i.flag_operands++;
01696 
01697       return 1;
01698     }
01699 
01700   /* CHECK FOR REGISTER BIT */
01701   else if ((rb = parse_register_bit (op_string, &end_op)) != NULL)
01702     {
01703       op_string = end_op;
01704 
01705       if (is_space_char (*op_string))
01706        ++op_string;
01707 
01708       i.types[this_operand] = BIT;
01709 
01710       i.maxq20_op[this_operand].r_bit = rb;
01711 
01712       i.bit_operands++;
01713 
01714       return 1;
01715     }
01716 
01717   else if (*op_string == IMMEDIATE_PREFIX)       /* FOR IMMEDITE.  */
01718     {
01719       if (is_space_char (*op_string))
01720        ++op_string;
01721 
01722       i.types[this_operand] = IMM;
01723 
01724       if (!maxq20_immediate (op_string))
01725        {
01726          as_bad (_("illegal immediate operand '%s'"), op_string);
01727          return 0;
01728        }
01729       return 1;
01730     }
01731 
01732   else if (*op_string == ABSOLUTE_PREFIX || !strcmp (op_string, "NUL"))
01733     {
01734      if (is_space_char (*op_string))
01735        ++op_string;
01736 
01737       /* For new requiremnt of copiler of for, @(BP,cons).  */
01738       if (check_for_parse (op_string))
01739        {
01740          memset (op_string, '\0', strlen (op_string) + 1);
01741          memcpy (op_string, "@BP[OFFS]\0", 11);
01742        }
01743 
01744       i.types[this_operand] = MEM;
01745 
01746       if ((m = maxq20_mem_access (op_string, &end_op)) == NULL)
01747        {
01748          as_bad (_("Invalid operand for memory access '%s'"), op_string);
01749          return 0;
01750        }
01751       i.maxq20_op[this_operand].mem = m;
01752 
01753       i.mem_operands++;
01754 
01755       return 1;
01756     }
01757 
01758   else if ((r = parse_register (op_string, &end_op)) != NULL)  /* Check for register.  */
01759     {
01760       op_string = end_op;
01761 
01762       if (is_space_char (*op_string))
01763        ++op_string;
01764 
01765       i.types[this_operand] = REG; /* Set the type.  */
01766       i.maxq20_op[this_operand].reg = r;  /* Set the Register value.  */
01767       i.reg_operands++;
01768       return 1;
01769     }
01770 
01771   if (this_operand == 1)
01772     {
01773       /* Changed for orginal case of data refrence on 30 Nov 2003.  */
01774       /* The operand can either be a data reference or a symbol reference.  */
01775       if ((sym = maxq20_data (org_case_op_string)) != NULL)    /* Check for data memory.  */
01776        {
01777          while (is_space_char (*op_string))
01778            ++op_string;
01779 
01780          /* Set the type of the operand.  */
01781          i.types[this_operand] = DATA;
01782 
01783          /* Set the value of the data.  */
01784          i.maxq20_op[this_operand].data = sym;
01785          i.data_operands++;
01786 
01787          return 1;
01788        }
01789 
01790       else if (is_digit_char (*op_string) || is_identifier_char (*op_string))
01791        {
01792          /* This is a memory reference of some sort. char *base_string;
01793             Start and end of displacement string expression (if found). char 
01794             *displacement_string_start; char *displacement_string_end.  */
01795          base_string = org_case_op_string + strlen (org_case_op_string);
01796 
01797          --base_string;
01798          if (is_space_char (*base_string))
01799            --base_string;
01800 
01801          /* If we only have a displacement, set-up for it to be parsed
01802             later.  */
01803          displacement_string_start = org_case_op_string;
01804          displacement_string_end = base_string + 1;
01805          if (displacement_string_start != displacement_string_end)
01806            {
01807              if (!maxq20_displacement (displacement_string_start,
01808                                    displacement_string_end))
01809               {
01810                 as_bad (_("illegal displacement operand "));
01811                 return 0;
01812               }
01813              /* A displacement operand found.  */
01814              i.types[this_operand] = DISP;       /* Set the type.  */
01815              return 1;
01816            }
01817        }
01818     }
01819   
01820   /* Check for displacement.  */
01821   else if (is_digit_char (*op_string) || is_identifier_char (*op_string))
01822     {
01823       /* This is a memory reference of some sort. char *base_string;
01824          Start and end of displacement string expression (if found). char
01825          *displacement_string_start; char *displacement_string_end;  */
01826       base_string = org_case_op_string + strlen (org_case_op_string);
01827 
01828       --base_string;
01829       if (is_space_char (*base_string))
01830        --base_string;
01831 
01832       /* If we only have a displacement, set-up for it to be parsed later.  */
01833       displacement_string_start = org_case_op_string;
01834       displacement_string_end = base_string + 1;
01835       if (displacement_string_start != displacement_string_end)
01836        {
01837          if (!maxq20_displacement (displacement_string_start,
01838                                 displacement_string_end))
01839            return 0;
01840          /* A displacement operand found.  */
01841          i.types[this_operand] = DISP;    /* Set the type.  */
01842        }
01843     }
01844   return 1;
01845 }
01846 
01847 /* Parse_operand takes as input instruction and operands and Parse operands
01848    and makes entry in the template.  */
01849 
01850 static char *
01851 parse_operands (char *l, const char *mnemonic)
01852 {
01853   char *token_start;
01854 
01855   /* 1 if operand is pending after ','.  */
01856   short int expecting_operand = 0;
01857 
01858   /* Non-zero if operand parens not balanced.  */
01859   short int paren_not_balanced;
01860 
01861   int operand_ok;
01862 
01863   /* For Overcoming Warning of unused variable.  */
01864   if (mnemonic)
01865     operand_ok = 0;
01866 
01867   while (*l != END_OF_INSN)
01868     {
01869       /* Skip optional white space before operand.  */
01870       if (is_space_char (*l))
01871        ++l;
01872 
01873       if (!is_operand_char (*l) && *l != END_OF_INSN)
01874        {
01875          as_bad (_("invalid character %c before operand %d"),
01876                 (char) (*l), i.operands + 1);
01877          return NULL;
01878        }
01879       token_start = l;
01880 
01881       paren_not_balanced = 0;
01882       while (paren_not_balanced || *l != ',')
01883        {
01884          if (*l == END_OF_INSN)
01885            {
01886              if (paren_not_balanced)
01887               {
01888                 as_bad (_("unbalanced brackets in operand %d."),
01889                        i.operands + 1);
01890                 return NULL;
01891               }
01892 
01893              break;
01894            }
01895          else if (!is_operand_char (*l) && !is_space_char (*l))
01896            {
01897              as_bad (_("invalid character %c in operand %d"),
01898                     (char) (*l), i.operands + 1);
01899              return NULL;
01900            }
01901          if (*l == '[')
01902            ++paren_not_balanced;
01903          if (*l == ']')
01904            --paren_not_balanced;
01905          l++;
01906        }
01907 
01908       if (l != token_start)
01909        {
01910          /* Yes, we've read in another operand.  */
01911          this_operand = i.operands++;
01912          if (i.operands > MAX_OPERANDS)
01913            {
01914              as_bad (_("spurious operands; (%d operands/instruction max)"),
01915                     MAX_OPERANDS);
01916              return NULL;
01917            }
01918 
01919          /* Now parse operand adding info to 'i' as we go along.  */
01920          END_STRING_AND_SAVE (l);
01921 
01922          operand_ok = maxq20_operand (token_start);
01923 
01924          RESTORE_END_STRING (l);
01925 
01926          if (!operand_ok)
01927            return NULL;
01928        }
01929       else
01930        {
01931          if (expecting_operand)
01932            {
01933            expecting_operand_after_comma:
01934              as_bad (_("expecting operand after ','; got nothing"));
01935              return NULL;
01936            }
01937        }
01938 
01939       if (*l == ',')
01940        {
01941          if (*(++l) == END_OF_INSN)
01942            /* Just skip it, if it's \n complain.  */
01943            goto expecting_operand_after_comma;
01944 
01945          expecting_operand = 1;
01946        }
01947     }
01948 
01949   return l;
01950 }
01951 
01952 static int
01953 match_operands (int type, MAX_ARG_TYPE flag_type, MAX_ARG_TYPE arg_type,
01954               int op_num)
01955 {
01956   switch (type)
01957     {
01958     case REG:
01959       if ((arg_type & A_REG) == A_REG)
01960        return 1;
01961       break;
01962     case IMM:
01963       if ((arg_type & A_IMM) == A_IMM)
01964        return 1;
01965       break;
01966     case IMMBIT:
01967       if ((arg_type & A_BIT_0) == A_BIT_0 && (i.maxq20_op[op_num].imms == 0))
01968        return 1;
01969       else if ((arg_type & A_BIT_1) == A_BIT_1
01970               && (i.maxq20_op[op_num].imms == 1))
01971        return 1;
01972       break;
01973     case MEM:
01974       if ((arg_type & A_MEM) == A_MEM)
01975        return 1;
01976       break;
01977 
01978     case FLAG:
01979       if ((arg_type & flag_type) == flag_type)
01980        return 1;
01981 
01982       break;
01983 
01984     case BIT:
01985       if ((arg_type & ACC_BIT) == ACC_BIT && !strcmp (i.maxq20_op[op_num].r_bit->reg->reg_name, "ACC"))
01986        return 1;
01987       else if ((arg_type & SRC_BIT) == SRC_BIT && (op_num == 1))
01988        return 1;
01989       else if ((op_num == 0) && (arg_type & DST_BIT) == DST_BIT)
01990        return 1;
01991       break;
01992     case DISP:
01993       if ((arg_type & A_DISP) == A_DISP)
01994        return 1;
01995     case DATA:
01996       if ((arg_type & A_DATA) == A_DATA)
01997        return 1;
01998     case BIT_BUCKET:
01999       if ((arg_type & A_BIT_BUCKET) == A_BIT_BUCKET)
02000        return 1;
02001     }
02002   return 0;
02003 }
02004 
02005 static int
02006 match_template (void)
02007 {
02008   /* Points to template once we've found it.  */
02009   const MAXQ20_OPCODE_INFO *t;
02010   char inv_oper;
02011   inv_oper = 0;
02012 
02013   for (t = current_templates->start; t < current_templates->end; t++)
02014     {
02015       /* Must have right number of operands.  */
02016       if (i.operands != t->op_number)
02017        continue;
02018       else if (!t->op_number)
02019        break;
02020 
02021       switch (i.operands)
02022        {
02023        case 2:
02024          if (!match_operands (i.types[1], i.maxq20_op[1].flag, t->arg[1], 1))
02025            {
02026              inv_oper = 1;
02027              continue;
02028            }
02029        case 1:
02030          if (!match_operands (i.types[0], i.maxq20_op[0].flag, t->arg[0], 0))
02031            {
02032              inv_oper = 2;
02033              continue;
02034            }
02035        }
02036       break;
02037     }
02038 
02039   if (t == current_templates->end)
02040     {
02041       /* We found no match.  */
02042       as_bad (_("operand %d is invalid for `%s'"),
02043              inv_oper, current_templates->start->name);
02044       return 0;
02045     }
02046 
02047   /* Copy the template we have found.  */
02048   i.op = *t;
02049   return 1;
02050 }
02051 
02052 /* This function filters out the various combinations of operands which are
02053    not allowed for a particular instruction.  */
02054 
02055 static int
02056 match_filters (void)
02057 {
02058   /* Now we have at our disposal the instruction i. We will be using the
02059      following fields i.op.name : This is the mnemonic name. i.types[2] :
02060      These are the types of the operands (REG/IMM/DISP/MEM/BIT/FLAG/IMMBIT)
02061      i.maxq20_op[2] : This contains the specific info of the operands.  */
02062 
02063   /* Our first filter : NO ALU OPERATIONS CAN HAVE THE ACTIVE ACCUMULATOR AS
02064      SOURCE.  */
02065   if (!strcmp (i.op.name, "AND") || !strcmp (i.op.name, "OR")
02066       || !strcmp (i.op.name, "XOR") || !strcmp (i.op.name, "ADD")
02067       || !strcmp (i.op.name, "ADDC") || !strcmp (i.op.name, "SUB")
02068       || !strcmp (i.op.name, "SUBB"))
02069     {
02070       if (i.types[0] == REG)
02071        {
02072          if (i.maxq20_op[0].reg->Mod_name == 0xa)
02073            {
02074              as_bad (_
02075                     ("The Accumulator cannot be used as a source in ALU instructions\n"));
02076              return 0;
02077            }
02078        }
02079     }
02080 
02081   if (!strcmp (i.op.name, "MOVE") && (i.types[0] == MEM || i.types[1] == MEM)
02082       && i.operands == 2)
02083     {
02084       mem_access_syntax *mem_op = NULL;
02085 
02086       if (i.types[0] == MEM)
02087        {
02088          mem_op =
02089            (mem_access_syntax *) hash_find (mem_syntax_hash,
02090                                         i.maxq20_op[0].mem->name);
02091          if ((mem_op->type == SRC) && mem_op)
02092            {
02093              as_bad (_("'%s' operand cant be used as destination in %s"),
02094                     mem_op->name, i.op.name);
02095              return 0;
02096            }
02097          else if ((mem_op->invalid_op != NULL) && (i.types[1] == MEM)
02098                  && mem_op)
02099            {
02100              int k = 0;
02101 
02102              for (k = 0; k < 5 || !mem_op->invalid_op[k]; k++)
02103               {
02104                 if (mem_op->invalid_op[k] != NULL)
02105                   if (!strcmp
02106                      (mem_op->invalid_op[k], i.maxq20_op[1].mem->name))
02107                     {
02108                      as_bad (_
02109                             ("Invalid Instruction '%s' operand cant be used with %s"),
02110                             mem_op->name, i.maxq20_op[1].mem->name);
02111                      return 0;
02112                     }
02113               }
02114            }
02115        }
02116 
02117       if (i.types[1] == MEM)
02118        {
02119          mem_op = NULL;
02120          mem_op =
02121            (mem_access_syntax *) hash_find (mem_syntax_hash,
02122                                         i.maxq20_op[1].mem->name);
02123          if (mem_op->type == DST && mem_op)
02124            {
02125              as_bad (_("'%s' operand cant be used as source in %s"),
02126                     mem_op->name, i.op.name);
02127              return 0;
02128            }
02129          else if (mem_op->invalid_op != NULL && i.types[0] == MEM && mem_op)
02130            {
02131              int k = 0;
02132 
02133              for (k = 0; k < 5 || !mem_op->invalid_op[k]; k++)
02134               {
02135                 if (mem_op->invalid_op[k] != NULL)
02136                   if (!strcmp
02137                      (mem_op->invalid_op[k], i.maxq20_op[0].mem->name))
02138                     {
02139                      as_bad (_
02140                             ("Invalid Instruction '%s' operand cant be used with %s"),
02141                             mem_op->name, i.maxq20_op[0].mem->name);
02142                      return 0;
02143                     }
02144               }
02145            }
02146          else if (i.types[0] == REG
02147                  && !strcmp (i.maxq20_op[0].reg->reg_name, "OFFS")
02148                  && mem_op)
02149            {
02150              if (!strcmp (mem_op->name, "@BP[OFFS--]")
02151                 || !strcmp (mem_op->name, "@BP[OFFS++]"))
02152               {
02153                 as_bad (_
02154                        ("Invalid Instruction '%s' operand cant be used with %s"),
02155                        mem_op->name, i.maxq20_op[0].mem->name);
02156                 return 0;
02157               }
02158            }
02159        }
02160     }
02161 
02162   /* Added for SRC and DST in one operand instructioni i.e OR @--DP[1] added
02163      on 10-March-2004.  */
02164   if ((i.types[0] == MEM) && (i.operands == 1)
02165       && !(!strcmp (i.op.name, "POP") || !strcmp (i.op.name, "POPI")))
02166     {
02167       mem_access_syntax *mem_op = NULL;
02168 
02169       if (i.types[0] == MEM)
02170        {
02171          mem_op =
02172            (mem_access_syntax *) hash_find (mem_syntax_hash,
02173                                         i.maxq20_op[0].mem->name);
02174          if (mem_op->type == DST && mem_op)
02175            {
02176              as_bad (_("'%s' operand cant be used as source in %s"),
02177                     mem_op->name, i.op.name);
02178              return 0;
02179            }
02180        }
02181     }
02182 
02183   if (i.operands == 2 && i.types[0] == IMM)
02184     {
02185       as_bad (_("'%s' instruction cant have first operand as Immediate vale"),
02186              i.op.name);
02187       return 0;
02188     }
02189 
02190   /* Our second filter : SP or @SP-- cannot be used with PUSH or POP */
02191   if (!strcmp (i.op.name, "PUSH") || !strcmp (i.op.name, "POP")
02192       || !strcmp (i.op.name, "POPI"))
02193     {
02194       if (i.types[0] == REG)
02195        {
02196          if (!strcmp (i.maxq20_op[0].reg->reg_name, "SP"))
02197            {
02198              as_bad (_("SP cannot be used with %s\n"), i.op.name);
02199              return 0;
02200            }
02201        }
02202       else if (i.types[0] == MEM
02203               && !strcmp (i.maxq20_op[0].mem->name, "@SP--"))
02204        {
02205          as_bad (_("@SP-- cannot be used with PUSH\n"));
02206          return 0;
02207        }
02208     }
02209 
02210   /* This filter checks that two memory references using DP's cannot be used
02211      together in an instruction */
02212   if (!strcmp (i.op.name, "MOVE") && i.mem_operands == 2)
02213     {
02214       if (strlen (i.maxq20_op[0].mem->name) != 6 ||
02215          strcmp (i.maxq20_op[0].mem->name, i.maxq20_op[1].mem->name))
02216        {
02217          if (!strncmp (i.maxq20_op[0].mem->name, "@DP", 3)
02218              && !strncmp (i.maxq20_op[1].mem->name, "@DP", 3))
02219            {
02220              as_bad (_
02221                     ("Operands either contradictory or use the data bus in read/write state together"));
02222              return 0;
02223            }
02224 
02225          if (!strncmp (i.maxq20_op[0].mem->name, "@SP", 3)
02226              && !strncmp (i.maxq20_op[1].mem->name, "@SP", 3))
02227            {
02228              as_bad (_
02229                     ("Operands either contradictory or use the data bus in read/write state together"));
02230              return 0;
02231            }
02232        }
02233       if ((i.maxq20_op[1].mem != NULL)
02234          && !strncmp (i.maxq20_op[1].mem->name, "NUL", 3))
02235        {
02236          as_bad (_("MOVE Cant Use NUL as SRC"));
02237          return 0;
02238        }
02239     }
02240 
02241   /* This filter checks that contradictory movement between DP register and
02242      Memory access using DP followed by increment or decrement.  */
02243 
02244   if (!strcmp (i.op.name, "MOVE") && i.mem_operands == 1
02245       && i.reg_operands == 1)
02246     {
02247       int memnum, regnum;
02248 
02249       memnum = (i.types[0] == MEM) ? 0 : 1;
02250       regnum = (memnum == 0) ? 1 : 0;
02251       if (!strncmp (i.maxq20_op[regnum].reg->reg_name, "DP", 2) &&
02252          !strncmp ((i.maxq20_op[memnum].mem->name) + 1,
02253                   i.maxq20_op[regnum].reg->reg_name, 5)
02254          && strcmp ((i.maxq20_op[memnum].mem->name) + 1,
02255                    i.maxq20_op[regnum].reg->reg_name))
02256        {
02257          as_bad (_
02258                 ("Contradictory movement between DP register and memory access using DP"));
02259          return 0;
02260        }
02261       else if (!strcmp (i.maxq20_op[regnum].reg->reg_name, "SP") &&
02262               !strncmp ((i.maxq20_op[memnum].mem->name) + 1,
02263                       i.maxq20_op[regnum].reg->reg_name, 2))
02264        {
02265          as_bad (_
02266                 ("SP and @SP-- cannot be used together in a move instruction"));
02267          return 0;
02268        }
02269     }
02270 
02271   /* This filter restricts the instructions containing source and destination 
02272      bits to only CTRL module of the serial registers. Peripheral registers
02273      yet to be defined.  */
02274 
02275   if (i.bit_operands == 1 && i.operands == 2)
02276     {
02277       int bitnum = (i.types[0] == BIT) ? 0 : 1;
02278 
02279       if (strcmp (i.maxq20_op[bitnum].r_bit->reg->reg_name, "ACC"))
02280        {
02281          if (i.maxq20_op[bitnum].r_bit->reg->Mod_name >= 0x7 &&
02282              i.maxq20_op[bitnum].r_bit->reg->Mod_name != CTRL)
02283            {
02284              as_bad (_
02285                     ("Only Module 8 system registers allowed in this operation"));
02286              return 0;
02287            }
02288        }
02289     }
02290 
02291   /* This filter is for checking the register bits.  */
02292   if (i.bit_operands == 1 || i.operands == 2)
02293     {
02294       int bitnum = 0, size = 0;
02295 
02296       bitnum = (i.types[0] == BIT) ? 0 : 1;
02297       if (i.bit_operands == 1)
02298        {
02299          switch (i.maxq20_op[bitnum].r_bit->reg->rtype)
02300            {
02301            case Reg_8W:
02302              size = 7;             /* 8 bit register, both read and write.  */
02303              break;
02304            case Reg_16W:
02305              size = 15;
02306              break;
02307            case Reg_8R:
02308              size = 7;
02309              if (bitnum == 0)
02310               {
02311                 as_fatal (_("Read only Register used as destination"));
02312                 return 0;
02313               }
02314              break;
02315 
02316            case Reg_16R:
02317              size = 15;
02318              if (bitnum == 0)
02319               {
02320                 as_fatal (_("Read only Register used as destination"));
02321                 return 0;
02322               }
02323              break;
02324            }
02325 
02326          if (size < (i.maxq20_op[bitnum].r_bit)->bit)
02327            {
02328              as_bad (_("Bit No '%d'exceeds register size in this operation"),
02329                     (i.maxq20_op[bitnum].r_bit)->bit);
02330              return 0;
02331            }
02332        }
02333 
02334       if (i.bit_operands == 2)
02335        {
02336          switch ((i.maxq20_op[0].r_bit)->reg->rtype)
02337            {
02338            case Reg_8W:
02339              size = 7;             /* 8 bit register, both read and write.  */
02340              break;
02341            case Reg_16W:
02342              size = 15;
02343              break;
02344            case Reg_8R:
02345            case Reg_16R:
02346              as_fatal (_("Read only Register used as destination"));
02347              return 0;
02348            }
02349 
02350          if (size < (i.maxq20_op[0].r_bit)->bit)
02351            {
02352              as_bad (_
02353                     ("Bit No '%d' exceeds register size in this operation"),
02354                     (i.maxq20_op[0].r_bit)->bit);
02355              return 0;
02356            }
02357 
02358          size = 0;
02359          switch ((i.maxq20_op[1].r_bit)->reg->rtype)
02360            {
02361            case Reg_8R:
02362            case Reg_8W:
02363              size = 7;             /* 8 bit register, both read and write.  */
02364              break;
02365            case Reg_16R:
02366            case Reg_16W:
02367              size = 15;
02368              break;
02369            }
02370 
02371          if (size < (i.maxq20_op[1].r_bit)->bit)
02372            {
02373              as_bad (_
02374                     ("Bit No '%d' exceeds register size in this operation"),
02375                     (i.maxq20_op[1].r_bit)->bit);
02376              return 0;
02377            }
02378        }
02379     }
02380 
02381   /* No branch operations should occur into the data memory. Hence any memory 
02382      references have to be filtered out when used with instructions like
02383      jump, djnz[] and call.  */
02384 
02385   if (!strcmp (i.op.name, "JUMP") || !strcmp (i.op.name, "CALL")
02386       || !strncmp (i.op.name, "DJNZ", 4))
02387     {
02388       if (i.mem_operands)
02389        as_warn (_
02390                ("Memory References cannot be used with branching operations\n"));
02391     }
02392 
02393   if (!strcmp (i.op.name, "DJNZ"))
02394     {
02395       if (!
02396          (strcmp (i.maxq20_op[0].reg->reg_name, "LC[0]")
02397           || strcmp (i.maxq20_op[0].reg->reg_name, "LC[1]")))
02398        {
02399          as_bad (_("DJNZ uses only LC[n] register \n"));
02400          return 0;
02401        }
02402     }
02403 
02404   /* No destination register used should be read only!  */
02405   if ((i.operands == 2 && i.types[0] == REG) || !strcmp (i.op.name, "POP")
02406       || !strcmp (i.op.name, "POPI"))
02407     {                       /* The destination is a register */
02408       int regnum = 0;
02409 
02410       if (!strcmp (i.op.name, "POP") || !strcmp (i.op.name, "POPI"))
02411        {
02412          regnum = 0;
02413 
02414          if (i.types[regnum] == MEM)
02415            {
02416              mem_access_syntax *mem_op = NULL;
02417 
02418              mem_op =
02419               (mem_access_syntax *) hash_find (mem_syntax_hash,
02420                                            i.maxq20_op[regnum].mem->
02421                                            name);
02422              if (mem_op->type == SRC && mem_op)
02423               {
02424                 as_bad (_
02425                        ("'%s' operand cant be used as destination  in %s"),
02426                        mem_op->name, i.op.name);
02427                 return 0;
02428               }
02429            }
02430        }
02431 
02432       if (i.maxq20_op[regnum].reg->rtype == Reg_8R
02433          || i.maxq20_op[regnum].reg->rtype == Reg_16R)
02434        {
02435          as_bad (_("Read only register used for writing purposes '%s'"),
02436                 i.maxq20_op[regnum].reg->reg_name);
02437          return 0;
02438        }
02439     }
02440 
02441   /* While moving the address of a data in the data section, the destination
02442      should be either data pointers only.  */
02443   if ((i.data_operands) && (i.operands == 2))
02444     {
02445       if ((i.types[0] != REG) && (i.types[0] != MEM))
02446        {
02447          as_bad (_("Invalid destination for this kind of source."));
02448          return 0;
02449        }
02450 
02451        if (i.types[0] == REG && i.maxq20_op[0].reg->rtype == Reg_8W)
02452          {
02453            as_bad (_
02454                   ("Invalid register as destination for this kind of source.Only data pointers can be used."));
02455            return 0;
02456          }
02457     }
02458   return 1;
02459 }
02460 
02461 static int
02462 decode_insn (void)
02463 {
02464   /* Check for the format Bit if defined.  */
02465   if (i.op.format == 0 || i.op.format == 1)
02466     i.instr[0] = i.op.format << 7;
02467   else
02468     {
02469       /* Format bit not defined. We will have to be find it out ourselves.  */
02470       if (i.imm_operands == 1 || i.data_operands == 1 || i.disp_operands == 1)
02471        i.op.format = 0;
02472       else
02473        i.op.format = 1;
02474       i.instr[0] = i.op.format << 7;
02475     }
02476 
02477   /* Now for the destination register.  */
02478 
02479   /* If destination register is already defined . The conditions are the
02480      following: (1) The second entry in the destination array should be 0 (2) 
02481      If there are two operands then the first entry should not be a register,
02482      memory or a register bit (3) If there are less than two operands and the
02483      it is not a pop operation (4) The second argument is the carry
02484      flag(applicable to move Acc.<b>,C.  */
02485   if (i.op.dst[1] == 0
02486       &&
02487       ((i.types[0] != REG && i.types[0] != MEM && i.types[0] != BIT
02488        && i.operands == 2) || (i.operands < 2 && strcmp (i.op.name, "POP")
02489                             && strcmp (i.op.name, "POPI"))
02490        || (i.op.arg[1] == FLAG_C)))
02491     {
02492       i.op.dst[0] &= 0x7f;
02493       i.instr[0] |= i.op.dst[0];
02494     }
02495   else if (i.op.dst[1] == 0 && !strcmp (i.op.name, "DJNZ")
02496           &&
02497           (((i.types[0] == REG)
02498             && (!strcmp (i.maxq20_op[0].reg->reg_name, "LC[0]")
02499                || !strcmp (i.maxq20_op[0].reg->reg_name, "LC[1]")))))
02500     {
02501       i.op.dst[0] &= 0x7f;
02502       if (!strcmp (i.maxq20_op[0].reg->reg_name, "LC[0]"))
02503        i.instr[0] |= 0x4D;
02504 
02505       if (!strcmp (i.maxq20_op[0].reg->reg_name, "LC[1]"))
02506        i.instr[0] |= 0x5D;
02507     }
02508   else
02509     {
02510       unsigned char temp;
02511 
02512       /* Target register will have to be specified.  */
02513       if (i.types[0] == REG
02514          && (i.op.dst[0] == REG || i.op.dst[0] == (REG | MEM)))
02515        {
02516          temp = (i.maxq20_op[0].reg)->opcode;
02517          temp &= 0x7f;
02518          i.instr[0] |= temp;
02519        }
02520       else if (i.types[0] == MEM && (i.op.dst[0] == (REG | MEM)))
02521        {
02522          temp = (i.maxq20_op[0].mem)->opcode;
02523          temp &= 0x7f;
02524          i.instr[0] |= temp;
02525        }
02526       else if (i.types[0] == BIT && (i.op.dst[0] == REG))
02527        {
02528          temp = (i.maxq20_op[0].r_bit)->reg->opcode;
02529          temp &= 0x7f;
02530          i.instr[0] |= temp;
02531        }
02532       else if (i.types[1] == BIT && (i.op.dst[0] == BIT))
02533        {
02534          temp = (i.maxq20_op[1].r_bit)->bit;
02535          temp = temp << 4;
02536          temp |= i.op.dst[1];
02537          temp &= 0x7f;
02538          i.instr[0] |= temp;
02539        }
02540       else
02541        {
02542          as_bad (_("Invalid Instruction"));
02543          return 0;
02544        }
02545     }
02546 
02547   /* Now for the source register.  */
02548 
02549   /* If Source register is already known. The following conditions are
02550      checked: (1) There are no operands (2) If there is only one operand and
02551      it is a flag (3) If the operation is MOVE C,#0/#1 (4) If it is a POP
02552      operation.  */
02553 
02554   if (i.operands == 0 || (i.operands == 1 && i.types[0] == FLAG)
02555       || (i.types[0] == FLAG && i.types[1] == IMMBIT)
02556       || !strcmp (i.op.name, "POP") || !strcmp (i.op.name, "POPI"))
02557     i.instr[1] = i.op.src[0];
02558 
02559   else if (i.imm_operands == 1 && ((i.op.src[0] & IMM) == IMM))
02560     i.instr[1] = i.maxq20_op[this_operand].imms;
02561   
02562   else if (i.types[this_operand] == REG && ((i.op.src[0] & REG) == REG))
02563     i.instr[1] = (char) ((i.maxq20_op[this_operand].reg)->opcode);
02564 
02565   else if (i.types[this_operand] == BIT && ((i.op.src[0] & REG) == REG))
02566     i.instr[1] = (char) (i.maxq20_op[this_operand].r_bit->reg->opcode);
02567 
02568   else if (i.types[this_operand] == MEM && ((i.op.src[0] & MEM) == MEM))
02569     i.instr[1] = (char) ((i.maxq20_op[this_operand].mem)->opcode);
02570 
02571   else if (i.types[this_operand] == DATA && ((i.op.src[0] & DATA) == DATA))
02572     /* This will copy only the lower order bytes into the instruction. The
02573        higher order bytes have already been copied into the prefix register.  */
02574     i.instr[1] = 0;
02575 
02576   /* Decoding the source in the case when the second array entry is not 0.
02577      This means that the source register has been divided into two nibbles.  */
02578 
02579   else if (i.op.src[1] != 0)
02580     {
02581       /* If the first operand is a accumulator bit then
02582         the first 4 bits will be filled with the bit number.  */
02583       if (i.types[0] == BIT && ((i.op.src[0] & BIT) == BIT))
02584        {
02585          unsigned char temp = (i.maxq20_op[0].r_bit)->bit;
02586 
02587          temp = temp << 4;
02588          temp |= i.op.src[1];
02589          i.instr[1] = temp;
02590        }
02591       /* In case of MOVE dst.<b>,#1 The first nibble in the source register
02592          has to start with a zero. This is called a ZEROBIT */
02593       else if (i.types[0] == BIT && ((i.op.src[0] & ZEROBIT) == ZEROBIT))
02594        {
02595          char temp = (i.maxq20_op[0].r_bit)->bit;
02596 
02597          temp = temp << 4;
02598          temp |= i.op.src[1];
02599          temp &= 0x7f;
02600          i.instr[1] = temp;
02601        }
02602       /* Similarly for a ONEBIT */
02603       else if (i.types[0] == BIT && ((i.op.src[0] & ONEBIT) == ONEBIT))
02604        {
02605          char temp = (i.maxq20_op[0].r_bit)->bit;
02606 
02607          temp = temp << 4;
02608          temp |= i.op.src[1];
02609          temp |= 0x80;
02610          i.instr[1] = temp;
02611        }
02612       /* In case the second operand is a register bit (MOVE C,Acc.<b> or MOVE 
02613          C,src.<b> */
02614       else if (i.types[1] == BIT)
02615        {
02616          if (i.op.src[1] == 0 && i.op.src[1] == REG)
02617            i.instr[1] = (i.maxq20_op[1].r_bit)->reg->opcode;
02618 
02619          else if (i.op.src[0] == BIT && i.op.src)
02620            {
02621              char temp = (i.maxq20_op[1].r_bit)->bit;
02622 
02623              temp = temp << 4;
02624              temp |= i.op.src[1];
02625              i.instr[1] = temp;
02626            }
02627        }
02628       else
02629        {
02630          as_bad (_("Invalid Instruction"));
02631          return 0;
02632        }
02633     }
02634   return 1;
02635 }
02636 
02637 /* This is a function for outputting displacement operands.  */
02638 
02639 static void
02640 output_disp (fragS *insn_start_frag, offsetT insn_start_off)
02641 {
02642   char *p;
02643   relax_substateT subtype;
02644   symbolS *sym;
02645   offsetT off;
02646   int diff;
02647 
02648   diff = 0;
02649   insn_start_frag = frag_now;
02650   insn_start_off = frag_now_fix ();
02651 
02652   switch (i.Instr_Prefix)
02653     {
02654     case LONG_PREFIX:
02655       subtype = EXPLICT_LONG_PREFIX;
02656       break;
02657     case SHORT_PREFIX:
02658       subtype = SHORT_PREFIX;
02659       break;
02660     default:
02661       subtype = NO_PREFIX;
02662       break;
02663     }
02664 
02665   /* Its a symbol. Here we end the frag and start the relaxation. Now in our
02666      case there is no need for relaxation. But we do need support for a
02667      prefix operator. Hence we will check whethere is room for 4 bytes ( 2
02668      for prefix + 2 for the current instruction ) Hence if at a particular
02669      time we find out whether the prefix operator is reqd , we shift the
02670      current instruction two places ahead and insert the prefix instruction.  */
02671   frag_grow (2 + 2);
02672   p = frag_more (2);
02673 
02674   sym = i.maxq20_op[this_operand].disps->X_add_symbol;
02675   off = i.maxq20_op[this_operand].disps->X_add_number;
02676 
02677   if (i.maxq20_op[this_operand].disps->X_add_symbol != NULL && sym && frag_now
02678       && (subtype != EXPLICT_LONG_PREFIX))
02679     {
02680       /* If in the same frag.  */
02681       if (frag_now == symbol_get_frag (sym))
02682        {
02683          diff =
02684            ((((expressionS *) symbol_get_value_expression (sym))->
02685              X_add_number) - insn_start_off);
02686 
02687          /* PC points to the next instruction.  */
02688          diff = (diff / MAXQ_OCTETS_PER_BYTE) - 1;
02689 
02690          if (diff >= -128 && diff <= 127)
02691            {
02692              i.instr[1] = (char) diff;
02693 
02694              /* This will be overwritten later when the symbol is resolved.  */
02695              *p = i.instr[1];
02696              *(p + 1) = i.instr[0];
02697 
02698              /* No Need to create a FIXUP.  */
02699              return;
02700            }
02701        }
02702     }
02703 
02704   /* This will be overwritten later when the symbol is resolved.  */
02705   *p = i.instr[1];
02706   *(p + 1) = i.instr[0];
02707 
02708   if (i.maxq20_op[this_operand].disps->X_op != O_constant
02709       && i.maxq20_op[this_operand].disps->X_op != O_symbol)
02710     {
02711       /* Handle complex expressions.  */
02712       sym = make_expr_symbol (i.maxq20_op[this_operand].disps);
02713       off = 0;
02714     }
02715 
02716   /* Vineet : This has been added for md_estimate_size_before_relax to
02717      estimate the correct size.  */
02718   if (subtype != SHORT_PREFIX)
02719     i.reloc[this_operand] = LONG_PREFIX;
02720 
02721   frag_var (rs_machine_dependent, 2, i.reloc[this_operand], subtype, sym, off,  p);
02722 }
02723 
02724 /* This is a function for outputting displacement operands.  */
02725 
02726 static void
02727 output_data (fragS *insn_start_frag, offsetT insn_start_off)
02728 {
02729   char *p;
02730   relax_substateT subtype;
02731   symbolS *sym;
02732   offsetT off;
02733   int diff;
02734 
02735   diff = 0;
02736   off = 0;
02737   insn_start_frag = frag_now;
02738   insn_start_off = frag_now_fix ();
02739 
02740   subtype = EXPLICT_LONG_PREFIX;
02741 
02742   frag_grow (2 + 2);
02743   p = frag_more (2);
02744 
02745   sym = i.maxq20_op[this_operand].data;
02746   off = 0;
02747 
02748   /* This will be overwritten later when the symbol is resolved.  */
02749   *p = i.instr[1];
02750   *(p + 1) = i.instr[0];
02751 
02752   if (i.maxq20_op[this_operand].disps->X_op != O_constant
02753       && i.maxq20_op[this_operand].disps->X_op != O_symbol)
02754     /* Handle complex expressions.  */
02755     /* Because data is already in terms of symbol so no
02756        need to convert it from expression to symbol.  */
02757     off = 0;
02758 
02759   frag_var (rs_machine_dependent, 2, i.reloc[this_operand], subtype, sym, off,  p);
02760 }
02761 
02762 static void
02763 output_insn (void)
02764 {
02765   fragS *insn_start_frag;
02766   offsetT insn_start_off;
02767   char *p;
02768 
02769   /* Tie dwarf2 debug info to the address at the start of the insn. We can't
02770      do this after the insn has been output as the current frag may have been 
02771      closed off.  eg. by frag_var.  */
02772   dwarf2_emit_insn (0);
02773 
02774   /* To ALign the text section on word.  */
02775 
02776   frag_align (1, 0, 1);
02777 
02778   /* We initialise the frags for this particular instruction.  */
02779   insn_start_frag = frag_now;
02780   insn_start_off = frag_now_fix ();
02781 
02782   /* If there are displacement operators(unresolved) present, then handle
02783      them separately.  */
02784   if (i.disp_operands)
02785     {
02786       output_disp (insn_start_frag, insn_start_off);
02787       return;
02788     }
02789 
02790   if (i.data_operands)
02791     {
02792       output_data (insn_start_frag, insn_start_off);
02793       return;
02794     }
02795 
02796   /* Check whether the INSERT_BUFFER has to be written.  */
02797   if (strcmp (INSERT_BUFFER, ""))
02798     {
02799       p = frag_more (2);
02800 
02801       *p++ = INSERT_BUFFER[1];
02802       *p = INSERT_BUFFER[0];
02803     }
02804 
02805   /* Check whether the prefix instruction has to be written.  */
02806   if (strcmp (PFX_INSN, ""))
02807     {
02808       p = frag_more (2);
02809 
02810       *p++ = PFX_INSN[1];
02811       *p = PFX_INSN[0];
02812     }
02813 
02814   p = frag_more (2);
02815   /* For Little endian.  */
02816   *p++ = i.instr[1];
02817   *p = i.instr[0];
02818 }
02819 
02820 static void
02821 make_new_reg_table (void)
02822 {
02823   unsigned long size_pm = sizeof (peripheral_reg_table);
02824   num_of_reg = ARRAY_SIZE (peripheral_reg_table);
02825 
02826   new_reg_table = xmalloc (size_pm);
02827   if (new_reg_table == NULL)
02828     as_bad (_("Cannot allocate memory"));
02829 
02830   memcpy (new_reg_table, peripheral_reg_table, size_pm);
02831 }
02832 
02833 /* pmmain performs the initilizations for the pheripheral modules. */
02834 
02835 static void
02836 pmmain (void)
02837 {
02838   make_new_reg_table ();
02839   return;
02840 }
02841 
02842 void
02843 md_begin (void)
02844 {
02845   const char *hash_err = NULL;
02846   int c = 0;
02847   char *p;
02848   const MAXQ20_OPCODE_INFO *optab;
02849   MAXQ20_OPCODES *core_optab;      /* For opcodes of the same name. This will
02850                                be inserted into the hash table.  */
02851   struct reg *reg_tab;
02852   struct mem_access_syntax const *memsyntab;
02853   struct mem_access *memtab;
02854   struct bit_name *bittab;
02855 
02856   /* Initilize pherioipheral modules.  */
02857   pmmain ();
02858 
02859   /* Initialise the opcode hash table.  */
02860   op_hash = hash_new ();
02861 
02862   optab = op_table;         /* Initialise it to the first entry of the
02863                                maxq20 operand table.  */
02864 
02865   /* Setup for loop.  */
02866   core_optab = xmalloc (sizeof (MAXQ20_OPCODES));
02867   core_optab->start = optab;
02868 
02869   while (1)
02870     {
02871       ++optab;
02872       if (optab->name == NULL || strcmp (optab->name, (optab - 1)->name) != 0)
02873        {
02874          /* different name --> ship out current template list; add to hash
02875             table; & begin anew.  */
02876 
02877          core_optab->end = optab;
02878 #ifdef MAXQ10S
02879          if (max_version == bfd_mach_maxq10)
02880            {
02881              if (((optab - 1)->arch == MAXQ10) || ((optab - 1)->arch == MAX))
02882               {
02883                 hash_err = hash_insert (op_hash,
02884                                      (optab - 1)->name,
02885                                      (PTR) core_optab);
02886               }
02887            }
02888          else if (max_version == bfd_mach_maxq20)
02889            {
02890              if (((optab - 1)->arch == MAXQ20) || ((optab - 1)->arch == MAX))
02891               {
02892 #endif
02893                 hash_err = hash_insert (op_hash,
02894                                      (optab - 1)->name,
02895                                      (PTR) core_optab);
02896 #if MAXQ10S
02897               }
02898            }
02899          else
02900            as_fatal (_("Internal Error: Illegal Architecure specified"));
02901 #endif
02902          if (hash_err)
02903            as_fatal (_("Internal Error:  Can't hash %s: %s"),
02904                     (optab - 1)->name, hash_err);
02905 
02906          if (optab->name == NULL)
02907            break;
02908          core_optab = xmalloc (sizeof (MAXQ20_OPCODES));
02909          core_optab->start = optab;
02910        }
02911     }
02912 
02913   /* Initialise a new register table.  */
02914   reg_hash = hash_new ();
02915 
02916   for (reg_tab = system_reg_table;
02917        reg_tab < (system_reg_table + ARRAY_SIZE (system_reg_table));
02918        reg_tab++)
02919     {
02920 #if MAXQ10S
02921       switch (max_version)
02922        {
02923        case bfd_mach_maxq10:
02924          if ((reg_tab->arch == MAXQ10) || (reg_tab->arch == MAX))
02925            hash_err = hash_insert (reg_hash, reg_tab->reg_name, (PTR) reg_tab);
02926          break;
02927 
02928        case bfd_mach_maxq20:
02929          if ((reg_tab->arch == MAXQ20) || (reg_tab->arch == MAX))
02930            {
02931 #endif
02932              hash_err =
02933               hash_insert (reg_hash, reg_tab->reg_name, (PTR) reg_tab);
02934 #if MAXQ10S
02935            }
02936          break;
02937        default:
02938          as_fatal (_("Invalid architecture type"));
02939        }
02940 #endif
02941 
02942       if (hash_err)
02943        as_fatal (_("Internal Error : Can't Hash %s : %s"),
02944                 reg_tab->reg_name, hash_err);
02945     }
02946 
02947   /* Pheripheral Registers Entry.  */
02948   for (reg_tab = new_reg_table;
02949        reg_tab < (new_reg_table + num_of_reg - 1); reg_tab++)
02950     {
02951       hash_err = hash_insert (reg_hash, reg_tab->reg_name, (PTR) reg_tab);
02952 
02953       if (hash_err)
02954        as_fatal (_("Internal Error : Can't Hash %s : %s"),
02955                 reg_tab->reg_name, hash_err);
02956     }
02957 
02958   /* Initialise a new memory operand table.  */
02959   mem_hash = hash_new ();
02960 
02961   for (memtab = mem_table;
02962        memtab < mem_table + ARRAY_SIZE (mem_table);
02963        memtab++)
02964     {
02965       hash_err = hash_insert (mem_hash, memtab->name, (PTR) memtab);
02966       if (hash_err)
02967        as_fatal (_("Internal Error : Can't Hash %s : %s"),
02968                 memtab->name, hash_err);
02969     }
02970 
02971   bit_hash = hash_new ();
02972 
02973   for (bittab = bit_table;
02974        bittab < bit_table + ARRAY_SIZE (bit_table);
02975        bittab++)
02976     {
02977       hash_err = hash_insert (bit_hash, bittab->name, (PTR) bittab);
02978       if (hash_err)
02979        as_fatal (_("Internal Error : Can't Hash %s : %s"),
02980                 bittab->name, hash_err);
02981     }
02982 
02983   mem_syntax_hash = hash_new ();
02984 
02985   for (memsyntab = mem_access_syntax_table;
02986        memsyntab < mem_access_syntax_table + ARRAY_SIZE (mem_access_syntax_table);
02987        memsyntab++)
02988     {
02989       hash_err =
02990        hash_insert (mem_syntax_hash, memsyntab->name, (PTR) memsyntab);
02991       if (hash_err)
02992        as_fatal (_("Internal Error : Can't Hash %s : %s"),
02993                 memsyntab->name, hash_err);
02994     }
02995 
02996   /* Initialise the lexical tables,mnemonic chars,operand chars.  */
02997   for (c = 0; c < 256; c++)
02998     {
02999       if (ISDIGIT (c))
03000        {
03001          digit_chars[c] = c;
03002          mnemonic_chars[c] = c;
03003          operand_chars[c] = c;
03004          register_chars[c] = c;
03005        }
03006       else if (ISLOWER (c))
03007        {
03008          mnemonic_chars[c] = c;
03009          operand_chars[c] = c;
03010          register_chars[c] = c;
03011        }
03012       else if (ISUPPER (c))
03013        {
03014          mnemonic_chars[c] = TOLOWER (c);
03015          register_chars[c] = c;
03016          operand_chars[c] = c;
03017        }
03018 
03019       if (ISALPHA (c) || ISDIGIT (c))
03020        {
03021          identifier_chars[c] = c;
03022        }
03023       else if (c > 128)
03024        {
03025          identifier_chars[c] = c;
03026          operand_chars[c] = c;
03027        }
03028     }
03029 
03030   /* All the special characters.  */
03031   register_chars['@'] = '@';
03032   register_chars['+'] = '+';
03033   register_chars['-'] = '-';
03034   digit_chars['-'] = '-';
03035   identifier_chars['_'] = '_';
03036   identifier_chars['.'] = '.';
03037   register_chars['['] = '[';
03038   register_chars[']'] = ']';
03039   operand_chars['_'] = '_';
03040   operand_chars['#'] = '#';
03041   mnemonic_chars['['] = '[';
03042   mnemonic_chars[']'] = ']';
03043 
03044   for (p = operand_special_chars; *p != '\0'; p++)
03045     operand_chars[(unsigned char) *p] = (unsigned char) *p;
03046 
03047   /* Set the maxq arch type.  */
03048   maxq_target (max_version);
03049 }
03050 
03051 /* md_assemble - Parse Instr - Seprate menmonics and operands - lookup the
03052    menmunonic in the operand table - Parse operands and populate the
03053    structure/template - Match the operand with opcode and its validity -
03054    Output Instr.  */
03055 
03056 void
03057 md_assemble (char *line)
03058 {
03059   int j;
03060 
03061   char mnemonic[MAX_MNEM_SIZE];
03062   char temp4prev[256];
03063   static char prev_insn[256];
03064 
03065   /* Initialize globals.  */
03066   memset (&i, '\0', sizeof (i));
03067   for (j = 0; j < MAX_OPERANDS; j++)
03068     i.reloc[j] = NO_RELOC;
03069 
03070   i.prefix = -1;
03071   PFX_INSN[0] = 0;
03072   PFX_INSN[1] = 0;
03073   INSERT_BUFFER[0] = 0;
03074   INSERT_BUFFER[1] = 0;
03075 
03076   memcpy (temp4prev, line, strlen (line) + 1);
03077 
03078   save_stack_p = save_stack;
03079 
03080   line = (char *) parse_insn (line, mnemonic);
03081   if (line == NULL)
03082     return;
03083 
03084   line = (char *) parse_operands (line, mnemonic);
03085   if (line == NULL)
03086     return;
03087 
03088   /* Next, we find a template that matches the given insn, making sure the
03089      overlap of the given operands types is consistent with the template
03090      operand types.  */
03091   if (!match_template ())
03092     return;
03093 
03094   /* In the MAXQ20, there are certain register combinations, and other
03095      restrictions which are not allowed. We will try to resolve these right
03096      now.  */
03097   if (!match_filters ())
03098     return;
03099 
03100   /* Check for the appropriate PFX register.  */
03101   set_prefix ();
03102   pfx_for_imm_val (0);
03103 
03104   if (!decode_insn ())             /* decode insn. */
03105     need_pass_2 = 1;
03106 
03107   /* Check for Exlipct PFX instruction.  */
03108   if (PFX_INSN[0] && (strstr (prev_insn, "PFX") || strstr (prev_insn, "pfx")))
03109     as_warn (_("Ineffective insntruction %s \n"), prev_insn);
03110 
03111   memcpy (prev_insn, temp4prev, strlen (temp4prev) + 1);
03112 
03113   /* We are ready to output the insn.  */
03114   output_insn ();
03115 }