Back to index

cell-binutils  2.17cvs20070401
tc-ns32k.c
Go to the documentation of this file.
00001 /* ns32k.c  -- Assemble on the National Semiconductor 32k series
00002    Copyright 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
00003    2001, 2002, 2003, 2005, 2006
00004    Free Software Foundation, Inc.
00005 
00006    This file is part of GAS, the GNU Assembler.
00007 
00008    GAS is free software; you can redistribute it and/or modify
00009    it under the terms of the GNU General Public License as published by
00010    the Free Software Foundation; either version 2, or (at your option)
00011    any later version.
00012 
00013    GAS is distributed in the hope that it will be useful,
00014    but WITHOUT ANY WARRANTY; without even the implied warranty of
00015    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016    GNU General Public License for more details.
00017 
00018    You should have received a copy of the GNU General Public License
00019    along with GAS; see the file COPYING.  If not, write to the Free
00020    Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
00021    02110-1301, USA.  */
00022 
00023 /*#define SHOW_NUM 1*//* Uncomment for debugging.  */
00024 
00025 #include "as.h"
00026 #include "opcode/ns32k.h"
00027 
00028 #include "obstack.h"
00029 
00030 /* Macros.  */
00031 #define IIF_ENTRIES 13             /* Number of entries in iif.  */
00032 #define PRIVATE_SIZE 256    /* Size of my garbage memory.  */
00033 #define MAX_ARGS 4
00034 #define DEFAULT      -1            /* addr_mode returns this value when
00035                                    plain constant or label is
00036                                    encountered.  */
00037 
00038 #define IIF(ptr,a1,c1,e1,g1,i1,k1,m1,o1,q1,s1,u1)       \
00039     iif.iifP[ptr].type = a1;                            \
00040     iif.iifP[ptr].size = c1;                            \
00041     iif.iifP[ptr].object = e1;                          \
00042     iif.iifP[ptr].object_adjust = g1;                   \
00043     iif.iifP[ptr].pcrel = i1;                           \
00044     iif.iifP[ptr].pcrel_adjust = k1;                    \
00045     iif.iifP[ptr].im_disp = m1;                         \
00046     iif.iifP[ptr].relax_substate = o1;                  \
00047     iif.iifP[ptr].bit_fixP = q1;                 \
00048     iif.iifP[ptr].addr_mode = s1;                \
00049     iif.iifP[ptr].bsr = u1;
00050 
00051 #ifdef SEQUENT_COMPATABILITY
00052 #define LINE_COMMENT_CHARS "|"
00053 #define ABSOLUTE_PREFIX '@'
00054 #define IMMEDIATE_PREFIX '#'
00055 #endif
00056 
00057 #ifndef LINE_COMMENT_CHARS
00058 #define LINE_COMMENT_CHARS "#"
00059 #endif
00060 
00061 const char comment_chars[] = "#";
00062 const char line_comment_chars[] = LINE_COMMENT_CHARS;
00063 const char line_separator_chars[] = ";";
00064 static int default_disp_size = 4; /* Displacement size for external refs.  */
00065 
00066 #if !defined(ABSOLUTE_PREFIX) && !defined(IMMEDIATE_PREFIX)
00067 #define ABSOLUTE_PREFIX '@' /* One or the other MUST be defined.  */
00068 #endif
00069 
00070 struct addr_mode
00071 {
00072   signed char mode;         /* Addressing mode of operand (0-31).  */
00073   signed char scaled_mode;  /* Mode combined with scaled mode.  */
00074   char scaled_reg;          /* Register used in scaled+1 (1-8).  */
00075   char float_flag;          /* Set if R0..R7 was F0..F7 ie a
00076                                floating-point-register.  */
00077   char am_size;                    /* Estimated max size of general addr-mode
00078                                parts.  */
00079   char im_disp;                    /* If im_disp==1 we have a displacement.  */
00080   char pcrel;               /* 1 if pcrel, this is really redundant info.  */
00081   char disp_suffix[2];             /* Length of displacement(s), 0=undefined.  */
00082   char *disp[2];            /* Pointer(s) at displacement(s)
00083                                or immediates(s)     (ascii).  */
00084   char index_byte;          /* Index byte.  */
00085 };
00086 typedef struct addr_mode addr_modeS;
00087 
00088 char *freeptr, *freeptr_static;    /* Points at some number of free bytes.  */
00089 struct hash_control *inst_hash_handle;
00090 
00091 struct ns32k_opcode *desc;  /* Pointer at description of instruction.  */
00092 addr_modeS addr_modeP;
00093 const char EXP_CHARS[] = "eE";
00094 const char FLT_CHARS[] = "fd";     /* We don't want to support lowercase,
00095                                    do we?  */
00096 
00097 /* UPPERCASE denotes live names when an instruction is built, IIF is
00098    used as an intermediate form to store the actual parts of the
00099    instruction. A ns32k machine instruction can be divided into a
00100    couple of sub PARTs. When an instruction is assembled the
00101    appropriate PART get an assignment. When an IIF has been completed
00102    it is converted to a FRAGment as specified in AS.H.  */
00103 
00104 /* Internal structs.  */
00105 struct ns32k_option
00106 {
00107   char *pattern;
00108   unsigned long or;
00109   unsigned long and;
00110 };
00111 
00112 typedef struct
00113 {
00114   int type;                 /* How to interpret object.  */
00115   int size;                 /* Estimated max size of object.  */
00116   unsigned long object;            /* Binary data.  */
00117   int object_adjust;        /* Number added to object.  */
00118   int pcrel;                /* True if object is pcrel.  */
00119   int pcrel_adjust;         /* Length in bytes from the instruction
00120                                start to the      displacement.  */
00121   int im_disp;                     /* True if the object is a displacement.  */
00122   relax_substateT relax_substate;/*Initial relaxsubstate.  */
00123   bit_fixS *bit_fixP;              /* Pointer at bit_fix struct.  */
00124   int addr_mode;            /* What addrmode do we associate with this
00125                                iif-entry.  */
00126   char bsr;                 /* Sequent hack.  */
00127 } iif_entryT;               /* Internal Instruction Format.  */
00128 
00129 struct int_ins_form
00130 {
00131   int instr_size;           /* Max size of instruction in bytes.  */
00132   iif_entryT iifP[IIF_ENTRIES + 1];
00133 };
00134 
00135 struct int_ins_form iif;
00136 expressionS exprP;
00137 char *input_line_pointer;
00138 
00139 /* Description of the PARTs in IIF
00140   object[n]:
00141    0   total length in bytes of entries in iif
00142    1   opcode
00143    2   index_byte_a
00144    3   index_byte_b
00145    4   disp_a_1
00146    5   disp_a_2
00147    6   disp_b_1
00148    7   disp_b_2
00149    8   imm_a
00150    9   imm_b
00151    10  implied1
00152    11  implied2
00153 
00154    For every entry there is a datalength in bytes. This is stored in size[n].
00155         0,    the objectlength is not explicitly given by the instruction
00156               and the operand is undefined. This is a case for relaxation.
00157               Reserve 4 bytes for the final object.
00158 
00159         1,    the entry contains one byte
00160         2,    the entry contains two bytes
00161         3,    the entry contains three bytes
00162         4,    the entry contains four bytes
00163        etc
00164 
00165    Furthermore, every entry has a data type identifier in type[n].
00166 
00167         0,    the entry is void, ignore it.
00168         1,    the entry is a binary number.
00169         2,    the entry is a pointer at an expression.
00170               Where expression may be as simple as a single '1',
00171               and as complicated as  foo-bar+12,
00172               foo and bar may be undefined but suffixed by :{b|w|d} to
00173               control the length of the object.
00174 
00175         3,    the entry is a pointer at a bignum struct
00176 
00177    The low-order-byte corresponds to low physical memory.
00178    Obviously a FRAGment must be created for each valid disp in PART whose
00179    datalength is undefined (to bad) .
00180    The case where just the expression is undefined is less severe and is
00181    handled by fix. Here the number of bytes in the objectfile is known.
00182    With this representation we simplify the assembly and separates the
00183    machine dependent/independent parts in a more clean way (said OE).  */
00184 
00185 struct ns32k_option opt1[] =              /* restore, exit.  */
00186 {
00187   {"r0", 0x80, 0xff},
00188   {"r1", 0x40, 0xff},
00189   {"r2", 0x20, 0xff},
00190   {"r3", 0x10, 0xff},
00191   {"r4", 0x08, 0xff},
00192   {"r5", 0x04, 0xff},
00193   {"r6", 0x02, 0xff},
00194   {"r7", 0x01, 0xff},
00195   {0, 0x00, 0xff}
00196 };
00197 struct ns32k_option opt2[] =              /* save, enter.  */
00198 {
00199   {"r0", 0x01, 0xff},
00200   {"r1", 0x02, 0xff},
00201   {"r2", 0x04, 0xff},
00202   {"r3", 0x08, 0xff},
00203   {"r4", 0x10, 0xff},
00204   {"r5", 0x20, 0xff},
00205   {"r6", 0x40, 0xff},
00206   {"r7", 0x80, 0xff},
00207   {0, 0x00, 0xff}
00208 };
00209 struct ns32k_option opt3[] =              /* setcfg.  */
00210 {
00211   {"c", 0x8, 0xff},
00212   {"m", 0x4, 0xff},
00213   {"f", 0x2, 0xff},
00214   {"i", 0x1, 0xff},
00215   {0, 0x0, 0xff}
00216 };
00217 struct ns32k_option opt4[] =              /* cinv.  */
00218 {
00219   {"a", 0x4, 0xff},
00220   {"i", 0x2, 0xff},
00221   {"d", 0x1, 0xff},
00222   {0, 0x0, 0xff}
00223 };
00224 struct ns32k_option opt5[] =              /* String inst.  */
00225 {
00226   {"b", 0x2, 0xff},
00227   {"u", 0xc, 0xff},
00228   {"w", 0x4, 0xff},
00229   {0, 0x0, 0xff}
00230 };
00231 struct ns32k_option opt6[] =              /* Plain reg ext,cvtp etc.  */
00232 {
00233   {"r0", 0x00, 0xff},
00234   {"r1", 0x01, 0xff},
00235   {"r2", 0x02, 0xff},
00236   {"r3", 0x03, 0xff},
00237   {"r4", 0x04, 0xff},
00238   {"r5", 0x05, 0xff},
00239   {"r6", 0x06, 0xff},
00240   {"r7", 0x07, 0xff},
00241   {0, 0x00, 0xff}
00242 };
00243 
00244 #if !defined(NS32032) && !defined(NS32532)
00245 #define NS32532
00246 #endif
00247 
00248 struct ns32k_option cpureg_532[] = /* lpr spr.  */
00249 {
00250   {"us", 0x0, 0xff},
00251   {"dcr", 0x1, 0xff},
00252   {"bpc", 0x2, 0xff},
00253   {"dsr", 0x3, 0xff},
00254   {"car", 0x4, 0xff},
00255   {"fp", 0x8, 0xff},
00256   {"sp", 0x9, 0xff},
00257   {"sb", 0xa, 0xff},
00258   {"usp", 0xb, 0xff},
00259   {"cfg", 0xc, 0xff},
00260   {"psr", 0xd, 0xff},
00261   {"intbase", 0xe, 0xff},
00262   {"mod", 0xf, 0xff},
00263   {0, 0x00, 0xff}
00264 };
00265 struct ns32k_option mmureg_532[] = /* lmr smr.  */
00266 {
00267   {"mcr", 0x9, 0xff},
00268   {"msr", 0xa, 0xff},
00269   {"tear", 0xb, 0xff},
00270   {"ptb0", 0xc, 0xff},
00271   {"ptb1", 0xd, 0xff},
00272   {"ivar0", 0xe, 0xff},
00273   {"ivar1", 0xf, 0xff},
00274   {0, 0x0, 0xff}
00275 };
00276 
00277 struct ns32k_option cpureg_032[] = /* lpr spr.  */
00278 {
00279   {"upsr", 0x0, 0xff},
00280   {"fp", 0x8, 0xff},
00281   {"sp", 0x9, 0xff},
00282   {"sb", 0xa, 0xff},
00283   {"psr", 0xd, 0xff},
00284   {"intbase", 0xe, 0xff},
00285   {"mod", 0xf, 0xff},
00286   {0, 0x0, 0xff}
00287 };
00288 struct ns32k_option mmureg_032[] = /* lmr smr.  */
00289 {
00290   {"bpr0", 0x0, 0xff},
00291   {"bpr1", 0x1, 0xff},
00292   {"pf0", 0x4, 0xff},
00293   {"pf1", 0x5, 0xff},
00294   {"sc", 0x8, 0xff},
00295   {"msr", 0xa, 0xff},
00296   {"bcnt", 0xb, 0xff},
00297   {"ptb0", 0xc, 0xff},
00298   {"ptb1", 0xd, 0xff},
00299   {"eia", 0xf, 0xff},
00300   {0, 0x0, 0xff}
00301 };
00302 
00303 #if defined(NS32532)
00304 struct ns32k_option *cpureg = cpureg_532;
00305 struct ns32k_option *mmureg = mmureg_532;
00306 #else
00307 struct ns32k_option *cpureg = cpureg_032;
00308 struct ns32k_option *mmureg = mmureg_032;
00309 #endif
00310 
00311 
00312 const pseudo_typeS md_pseudo_table[] =
00313 {                                  /* So far empty.  */
00314   {0, 0, 0}
00315 };
00316 
00317 #define IND(x,y)     (((x)<<2)+(y))
00318 
00319 /* Those are index's to relax groups in md_relax_table ie it must be
00320    multiplied by 4 to point at a group start. Viz IND(x,y) Se function
00321    relax_segment in write.c for more info.  */
00322 
00323 #define BRANCH              1
00324 #define PCREL        2
00325 
00326 /* Those are index's to entries in a relax group.  */
00327 
00328 #define BYTE         0
00329 #define WORD         1
00330 #define DOUBLE              2
00331 #define UNDEF           3
00332 /* Those limits are calculated from the displacement start in memory.
00333    The ns32k uses the beginning of the instruction as displacement
00334    base.  This type of displacements could be handled here by moving
00335    the limit window up or down. I choose to use an internal
00336    displacement base-adjust as there are other routines that must
00337    consider this. Also, as we have two various offset-adjusts in the
00338    ns32k (acb versus br/brs/jsr/bcond), two set of limits would have
00339    had to be used.  Now we dont have to think about that.  */
00340 
00341 const relax_typeS md_relax_table[] =
00342 {
00343   {1, 1, 0, 0},
00344   {1, 1, 0, 0},
00345   {1, 1, 0, 0},
00346   {1, 1, 0, 0},
00347 
00348   {(63), (-64), 1, IND (BRANCH, WORD)},
00349   {(8192), (-8192), 2, IND (BRANCH, DOUBLE)},
00350   {0, 0, 4, 0},
00351   {1, 1, 0, 0}
00352 };
00353 
00354 /* Array used to test if mode contains displacements.
00355    Value is true if mode contains displacement.  */
00356 
00357 char disp_test[] =
00358 {0, 0, 0, 0, 0, 0, 0, 0,
00359  1, 1, 1, 1, 1, 1, 1, 1,
00360  1, 1, 1, 0, 0, 1, 1, 0,
00361  1, 1, 1, 1, 1, 1, 1, 1};
00362 
00363 /* Array used to calculate max size of displacements.  */
00364 
00365 char disp_size[] =
00366 {4, 1, 2, 0, 4};
00367 
00368 /* Parse a general operand into an addressingmode struct
00369 
00370    In:  pointer at operand in ascii form
00371         pointer at addr_mode struct for result
00372         the level of recursion. (always 0 or 1)
00373 
00374    Out: data in addr_mode struct.  */
00375 
00376 static int
00377 addr_mode (char *operand,
00378           addr_modeS *addr_modeP,
00379           int recursive_level)
00380 {
00381   char *str;
00382   int i;
00383   int strl;
00384   int mode;
00385   int j;
00386 
00387   mode = DEFAULT;           /* Default.  */
00388   addr_modeP->scaled_mode = 0;     /* Why not.  */
00389   addr_modeP->scaled_reg = 0;      /* If 0, not scaled index.  */
00390   addr_modeP->float_flag = 0;
00391   addr_modeP->am_size = 0;
00392   addr_modeP->im_disp = 0;
00393   addr_modeP->pcrel = 0;    /* Not set in this function.  */
00394   addr_modeP->disp_suffix[0] = 0;
00395   addr_modeP->disp_suffix[1] = 0;
00396   addr_modeP->disp[0] = NULL;
00397   addr_modeP->disp[1] = NULL;
00398   str = operand;
00399 
00400   if (str[0] == 0)
00401     return 0;
00402 
00403   strl = strlen (str);
00404 
00405   switch (str[0])
00406     {
00407       /* The following three case statements controls the mode-chars
00408         this is the place to ed if you want to change them.  */
00409 #ifdef ABSOLUTE_PREFIX
00410     case ABSOLUTE_PREFIX:
00411       if (str[strl - 1] == ']')
00412        break;
00413       addr_modeP->mode = 21;       /* absolute */
00414       addr_modeP->disp[0] = str + 1;
00415       return -1;
00416 #endif
00417 #ifdef IMMEDIATE_PREFIX
00418     case IMMEDIATE_PREFIX:
00419       if (str[strl - 1] == ']')
00420        break;
00421       addr_modeP->mode = 20;       /* immediate */
00422       addr_modeP->disp[0] = str + 1;
00423       return -1;
00424 #endif
00425     case '.':
00426       if (str[strl - 1] != ']')
00427        {
00428          switch (str[1])
00429            {
00430            case '-':
00431            case '+':
00432              if (str[2] != '\000')
00433               {
00434                 addr_modeP->mode = 27;    /* pc-relative */
00435                 addr_modeP->disp[0] = str + 2;
00436                 return -1;
00437               }
00438            default:
00439              as_bad (_("Invalid syntax in PC-relative addressing mode"));
00440              return 0;
00441            }
00442        }
00443       break;
00444     case 'e':
00445       if (str[strl - 1] != ']')
00446        {
00447          if ((!strncmp (str, "ext(", 4)) && strl > 7)
00448            {                       /* external */
00449              addr_modeP->disp[0] = str + 4;
00450              i = 0;
00451              j = 2;
00452              do
00453               {                    /* disp[0]'s termination point.  */
00454                 j += 1;
00455                 if (str[j] == '(')
00456                   i++;
00457                 if (str[j] == ')')
00458                   i--;
00459               }
00460              while (j < strl && i != 0);
00461              if (i != 0 || !(str[j + 1] == '-' || str[j + 1] == '+'))
00462               {
00463                 as_bad (_("Invalid syntax in External addressing mode"));
00464                 return (0);
00465               }
00466              str[j] = '\000';             /* null terminate disp[0] */
00467              addr_modeP->disp[1] = str + j + 2;
00468              addr_modeP->mode = 22;
00469              return -1;
00470            }
00471        }
00472       break;
00473 
00474     default:
00475       ;
00476     }
00477 
00478   strl = strlen (str);
00479 
00480   switch (strl)
00481     {
00482     case 2:
00483       switch (str[0])
00484        {
00485        case 'f':
00486          addr_modeP->float_flag = 1;
00487          /* Drop through.  */
00488        case 'r':
00489          if (str[1] >= '0' && str[1] < '8')
00490            {
00491              addr_modeP->mode = str[1] - '0';
00492              return -1;
00493            }
00494          break;
00495        default:
00496          break;
00497        }
00498       /* Drop through.  */
00499 
00500     case 3:
00501       if (!strncmp (str, "tos", 3))
00502        {
00503          addr_modeP->mode = 23;    /* TopOfStack */
00504          return -1;
00505        }
00506       break;
00507 
00508     default:
00509       break;
00510     }
00511 
00512   if (strl > 4)
00513     {
00514       if (str[strl - 1] == ')')
00515        {
00516          if (str[strl - 2] == ')')
00517            {
00518              if (!strncmp (&str[strl - 5], "(fp", 3))
00519               mode = 16;           /* Memory Relative.  */
00520              else if (!strncmp (&str[strl - 5], "(sp", 3))
00521               mode = 17;
00522              else if (!strncmp (&str[strl - 5], "(sb", 3))
00523               mode = 18;
00524 
00525              if (mode != DEFAULT)
00526               {
00527                 /* Memory relative.  */
00528                 addr_modeP->mode = mode;
00529                 j = strl - 5;             /* Temp for end of disp[0].  */
00530                 i = 0;
00531 
00532                 do
00533                   {
00534                     strl -= 1;
00535                     if (str[strl] == ')')
00536                      i++;
00537                     if (str[strl] == '(')
00538                      i--;
00539                   }
00540                 while (strl > -1 && i != 0);
00541 
00542                 if (i != 0)
00543                   {
00544                     as_bad (_("Invalid syntax in Memory Relative addressing mode"));
00545                     return (0);
00546                   }
00547 
00548                 addr_modeP->disp[1] = str;
00549                 addr_modeP->disp[0] = str + strl + 1;
00550                 str[j] = '\000';   /* Null terminate disp[0] .  */
00551                 str[strl] = '\000';       /* Null terminate disp[1].  */
00552 
00553                 return -1;
00554               }
00555            }
00556 
00557          switch (str[strl - 3])
00558            {
00559            case 'r':
00560            case 'R':
00561              if (str[strl - 2] >= '0'
00562                 && str[strl - 2] < '8'
00563                 && str[strl - 4] == '(')
00564               {
00565                 addr_modeP->mode = str[strl - 2] - '0' + 8;
00566                 addr_modeP->disp[0] = str;
00567                 str[strl - 4] = 0;
00568                 return -1;         /* reg rel */
00569               }
00570              /* Drop through.  */
00571 
00572            default:
00573              if (!strncmp (&str[strl - 4], "(fp", 3))
00574               mode = 24;
00575              else if (!strncmp (&str[strl - 4], "(sp", 3))
00576               mode = 25;
00577              else if (!strncmp (&str[strl - 4], "(sb", 3))
00578               mode = 26;
00579              else if (!strncmp (&str[strl - 4], "(pc", 3))
00580               mode = 27;
00581 
00582              if (mode != DEFAULT)
00583               {
00584                 addr_modeP->mode = mode;
00585                 addr_modeP->disp[0] = str;
00586                 str[strl - 4] = '\0';
00587 
00588                 return -1;         /* Memory space.  */
00589               }
00590            }
00591        }
00592 
00593       /* No trailing ')' do we have a ']' ?  */
00594       if (str[strl - 1] == ']')
00595        {
00596          switch (str[strl - 2])
00597            {
00598            case 'b':
00599              mode = 28;
00600              break;
00601            case 'w':
00602              mode = 29;
00603              break;
00604            case 'd':
00605              mode = 30;
00606              break;
00607            case 'q':
00608              mode = 31;
00609              break;
00610            default:
00611              as_bad (_("Invalid scaled-indexed mode, use (b,w,d,q)"));
00612 
00613              if (str[strl - 3] != ':' || str[strl - 6] != '['
00614                 || str[strl - 5] == 'r' || str[strl - 4] < '0'
00615                 || str[strl - 4] > '7')
00616               as_bad (_("Syntax in scaled-indexed mode, use [Rn:m] where n=[0..7] m={b,w,d,q}"));
00617            } /* Scaled index.  */
00618 
00619          if (recursive_level > 0)
00620            {
00621              as_bad (_("Scaled-indexed addressing mode combined with scaled-index"));
00622              return 0;
00623            }
00624 
00625          addr_modeP->am_size += 1; /* scaled index byte.  */
00626          j = str[strl - 4] - '0';  /* store temporary.  */
00627          str[strl - 6] = '\000';   /* nullterminate for recursive call.  */
00628          i = addr_mode (str, addr_modeP, 1);
00629 
00630          if (!i || addr_modeP->mode == 20)
00631            {
00632              as_bad (_("Invalid or illegal addressing mode combined with scaled-index"));
00633              return 0;
00634            }
00635 
00636          addr_modeP->scaled_mode = addr_modeP->mode;    /* Store the inferior mode.  */
00637          addr_modeP->mode = mode;
00638          addr_modeP->scaled_reg = j + 1;
00639 
00640          return -1;
00641        }
00642     }
00643 
00644   addr_modeP->mode = DEFAULT;      /* Default to whatever.  */
00645   addr_modeP->disp[0] = str;
00646 
00647   return -1;
00648 }
00649 
00650 static void
00651 evaluate_expr (expressionS *resultP, char *ptr)
00652 {
00653   char *tmp_line;
00654 
00655   tmp_line = input_line_pointer;
00656   input_line_pointer = ptr;
00657   expression (resultP);
00658   input_line_pointer = tmp_line;
00659 }
00660 
00661 /* ptr points at string addr_modeP points at struct with result This
00662    routine calls addr_mode to determine the general addr.mode of the
00663    operand. When this is ready it parses the displacements for size
00664    specifying suffixes and determines size of immediate mode via
00665    ns32k-opcode.  Also builds index bytes if needed.  */
00666 
00667 static int
00668 get_addr_mode (char *ptr, addr_modeS *addr_modeP)
00669 {
00670   int tmp;
00671 
00672   addr_mode (ptr, addr_modeP, 0);
00673 
00674   if (addr_modeP->mode == DEFAULT || addr_modeP->scaled_mode == -1)
00675     {
00676       /* Resolve ambiguous operands, this shouldn't be necessary if
00677         one uses standard NSC operand syntax. But the sequent
00678         compiler doesn't!!!  This finds a proper addressing mode
00679         if it is implicitly stated. See ns32k-opcode.h.  */
00680       (void) evaluate_expr (&exprP, ptr); /* This call takes time Sigh!  */
00681 
00682       if (addr_modeP->mode == DEFAULT)
00683        {
00684          if (exprP.X_add_symbol || exprP.X_op_symbol)
00685            addr_modeP->mode = desc->default_model; /* We have a label.  */
00686          else
00687            addr_modeP->mode = desc->default_modec; /* We have a constant.  */
00688        }
00689       else
00690        {
00691          if (exprP.X_add_symbol || exprP.X_op_symbol)
00692            addr_modeP->scaled_mode = desc->default_model;
00693          else
00694            addr_modeP->scaled_mode = desc->default_modec;
00695        }
00696 
00697       /* Must put this mess down in addr_mode to handle the scaled
00698          case better.  */
00699     }
00700 
00701   /* It appears as the sequent compiler wants an absolute when we have
00702      a label without @. Constants becomes immediates besides the addr
00703      case.  Think it does so with local labels too, not optimum, pcrel
00704      is better.  When I have time I will make gas check this and
00705      select pcrel when possible Actually that is trivial.  */
00706   if ((tmp = addr_modeP->scaled_reg))
00707     {                       /* Build indexbyte.  */
00708       tmp--;                /* Remember regnumber comes incremented for
00709                                flagpurpose.  */
00710       tmp |= addr_modeP->scaled_mode << 3;
00711       addr_modeP->index_byte = (char) tmp;
00712       addr_modeP->am_size += 1;
00713     }
00714 
00715   assert (addr_modeP->mode >= 0); 
00716   if (disp_test[(unsigned int) addr_modeP->mode])
00717     {
00718       char c;
00719       char suffix;
00720       char suffix_sub;
00721       int i;
00722       char *toP;
00723       char *fromP;
00724 
00725       /* There was a displacement, probe for length  specifying suffix.  */
00726       addr_modeP->pcrel = 0;
00727 
00728       assert(addr_modeP->mode >= 0);
00729       if (disp_test[(unsigned int) addr_modeP->mode])
00730        {
00731          /* There is a displacement.  */
00732          if (addr_modeP->mode == 27 || addr_modeP->scaled_mode == 27)
00733            /* Do we have pcrel. mode.  */
00734            addr_modeP->pcrel = 1;
00735 
00736          addr_modeP->im_disp = 1;
00737 
00738          for (i = 0; i < 2; i++)
00739            {
00740              suffix_sub = suffix = 0;
00741 
00742              if ((toP = addr_modeP->disp[i]))
00743               {
00744                 /* Suffix of expression, the largest size rules.  */
00745                 fromP = toP;
00746 
00747                 while ((c = *fromP++))
00748                   {
00749                     *toP++ = c;
00750                     if (c == ':')
00751                      {
00752                        switch (*fromP)
00753                          {
00754                          case '\0':
00755                            as_warn (_("Premature end of suffix -- Defaulting to d"));
00756                            suffix = 4;
00757                            continue;
00758                          case 'b':
00759                            suffix_sub = 1;
00760                            break;
00761                          case 'w':
00762                            suffix_sub = 2;
00763                            break;
00764                          case 'd':
00765                            suffix_sub = 4;
00766                            break;
00767                          default:
00768                            as_warn (_("Bad suffix after ':' use {b|w|d} Defaulting to d"));
00769                            suffix = 4;
00770                          }
00771 
00772                        fromP ++;
00773                        toP --;     /* So we write over the ':' */
00774 
00775                        if (suffix < suffix_sub)
00776                          suffix = suffix_sub;
00777                      }
00778                   }
00779 
00780                 *toP = '\0'; /* Terminate properly.  */
00781                 addr_modeP->disp_suffix[i] = suffix;
00782                 addr_modeP->am_size += suffix ? suffix : 4;
00783               }
00784            }
00785        }
00786     }
00787   else
00788     {
00789       if (addr_modeP->mode == 20)
00790        {
00791          /* Look in ns32k_opcode for size.  */
00792          addr_modeP->disp_suffix[0] = addr_modeP->am_size = desc->im_size;
00793          addr_modeP->im_disp = 0;
00794        }
00795     }
00796 
00797   return addr_modeP->mode;
00798 }
00799 
00800 /* Read an optionlist.  */
00801 
00802 static void
00803 optlist (char *str,                /* The string to extract options from.  */
00804         struct ns32k_option *optionP,     /* How to search the string.  */
00805         unsigned long *default_map)       /* Default pattern and output.  */
00806 {
00807   int i, j, k, strlen1, strlen2;
00808   char *patternP, *strP;
00809 
00810   strlen1 = strlen (str);
00811 
00812   if (strlen1 < 1)
00813     as_fatal (_("Very short instr to option, ie you can't do it on a NULLstr"));
00814 
00815   for (i = 0; optionP[i].pattern != 0; i++)
00816     {
00817       strlen2 = strlen (optionP[i].pattern);
00818 
00819       for (j = 0; j < strlen1; j++)
00820        {
00821          patternP = optionP[i].pattern;
00822          strP = &str[j];
00823 
00824          for (k = 0; k < strlen2; k++)
00825            {
00826              if (*(strP++) != *(patternP++))
00827               break;
00828            }
00829 
00830          if (k == strlen2)
00831            {                /* match */
00832              *default_map |= optionP[i].or;
00833              *default_map &= optionP[i].and;
00834            }
00835        }
00836     }
00837 }
00838 
00839 /* Search struct for symbols.
00840    This function is used to get the short integer form of reg names in
00841    the instructions lmr, smr, lpr, spr return true if str is found in
00842    list.  */
00843 
00844 static int
00845 list_search (char *str,                          /* The string to match.  */
00846             struct ns32k_option *optionP, /* List to search.  */
00847             unsigned long *default_map)   /* Default pattern and output.  */
00848 {
00849   int i;
00850 
00851   for (i = 0; optionP[i].pattern != 0; i++)
00852     {
00853       if (!strncmp (optionP[i].pattern, str, 20))
00854        {
00855          /* Use strncmp to be safe.  */
00856          *default_map |= optionP[i].or;
00857          *default_map &= optionP[i].and;
00858 
00859          return -1;
00860        }
00861     }
00862 
00863   as_bad (_("No such entry in list. (cpu/mmu register)"));
00864   return 0;
00865 }
00866 
00867 /* Create a bit_fixS in obstack 'notes'.
00868    This struct is used to profile the normal fix. If the bit_fixP is a
00869    valid pointer (not NULL) the bit_fix data will be used to format
00870    the fix.  */
00871 
00872 static bit_fixS *
00873 bit_fix_new (int size,             /* Length of bitfield.  */
00874             int offset,     /* Bit offset to bitfield.  */
00875             long min,              /* Signextended min for bitfield.  */
00876             long max,              /* Signextended max for bitfield.  */
00877             long add,              /* Add mask, used for huffman prefix.  */
00878             long base_type, /* 0 or 1, if 1 it's exploded to opcode ptr.  */
00879             long base_adj)
00880 {
00881   bit_fixS *bit_fixP;
00882 
00883   bit_fixP = (bit_fixS *) obstack_alloc (&notes, sizeof (bit_fixS));
00884 
00885   bit_fixP->fx_bit_size = size;
00886   bit_fixP->fx_bit_offset = offset;
00887   bit_fixP->fx_bit_base = base_type;
00888   bit_fixP->fx_bit_base_adj = base_adj;
00889   bit_fixP->fx_bit_max = max;
00890   bit_fixP->fx_bit_min = min;
00891   bit_fixP->fx_bit_add = add;
00892 
00893   return bit_fixP;
00894 }
00895 
00896 /* Convert operands to iif-format and adds bitfields to the opcode.
00897    Operands are parsed in such an order that the opcode is updated from
00898    its most significant bit, that is when the operand need to alter the
00899    opcode.
00900    Be careful not to put to objects in the same iif-slot.  */
00901 
00902 static void
00903 encode_operand (int argc,
00904               char **argv,
00905               const char *operandsP,
00906               const char *suffixP,
00907               char im_size ATTRIBUTE_UNUSED,
00908               char opcode_bit_ptr)
00909 {
00910   int i, j;
00911   char d;
00912   int pcrel, b, loop, pcrel_adjust;
00913   unsigned long tmp;
00914 
00915   for (loop = 0; loop < argc; loop++)
00916     {
00917       /* What operand are we supposed to work on.  */
00918       i = operandsP[loop << 1] - '1';
00919       if (i > 3)
00920        as_fatal (_("Internal consistency error.  check ns32k-opcode.h"));
00921 
00922       pcrel = 0;
00923       pcrel_adjust = 0;
00924       tmp = 0;
00925 
00926       switch ((d = operandsP[(loop << 1) + 1]))
00927        {
00928        case 'f':            /* Operand of sfsr turns out to be a nasty
00929                                specialcase.  */
00930          opcode_bit_ptr -= 5;
00931        case 'Z':            /* Float not immediate.  */
00932        case 'F':            /* 32 bit float      general form.  */
00933        case 'L':            /* 64 bit float.  */
00934        case 'I':            /* Integer not immediate.  */
00935        case 'B':            /* Byte        */
00936        case 'W':            /* Word        */
00937        case 'D':            /* Double-word.  */
00938        case 'A':            /* Double-word       gen-address-form ie no regs
00939                                allowed.  */
00940          get_addr_mode (argv[i], &addr_modeP);
00941 
00942          if ((addr_modeP.mode == 20) &&
00943             (d == 'I' || d == 'Z' || d == 'A'))
00944            as_fatal (d == 'A'? _("Address of immediate operand"):
00945                      _("Invalid immediate write operand."));
00946 
00947          if (opcode_bit_ptr == desc->opcode_size)
00948            b = 4;
00949          else
00950            b = 6;
00951 
00952          for (j = b; j < (b + 2); j++)
00953            {
00954              if (addr_modeP.disp[j - b])
00955               {
00956                 IIF (j,
00957                      2,
00958                      addr_modeP.disp_suffix[j - b],
00959                      (unsigned long) addr_modeP.disp[j - b],
00960                      0,
00961                      addr_modeP.pcrel,
00962                      iif.instr_size,
00963                      addr_modeP.im_disp,
00964                      IND (BRANCH, BYTE),
00965                      NULL,
00966                      (addr_modeP.scaled_reg ? addr_modeP.scaled_mode
00967                      : addr_modeP.mode),
00968                      0);
00969               }
00970            }
00971 
00972          opcode_bit_ptr -= 5;
00973          iif.iifP[1].object |= ((long) addr_modeP.mode) << opcode_bit_ptr;
00974 
00975          if (addr_modeP.scaled_reg)
00976            {
00977              j = b / 2;
00978              IIF (j, 1, 1, (unsigned long) addr_modeP.index_byte,
00979                  0, 0, 0, 0, 0, NULL, -1, 0);
00980            }
00981          break;
00982 
00983        case 'b':            /* Multiple instruction disp.  */
00984          freeptr++;         /* OVE:this is an useful hack.  */
00985          sprintf (freeptr, "((%s-1)*%d)", argv[i], desc->im_size);
00986          argv[i] = freeptr;
00987          pcrel -= 1;        /* Make pcrel 0 in spite of what case 'p':
00988                                wants.  */
00989          /* fall thru */
00990        case 'p':            /* Displacement - pc relative addressing.  */
00991          pcrel += 1;
00992          /* fall thru */
00993        case 'd':            /* Displacement.  */
00994          iif.instr_size += suffixP[i] ? suffixP[i] : 4;
00995          IIF (12, 2, suffixP[i], (unsigned long) argv[i], 0,
00996               pcrel, pcrel_adjust, 1, IND (BRANCH, BYTE), NULL, -1, 0);
00997          break;
00998        case 'H':            /* Sequent-hack: the linker wants a bit set
00999                                when bsr.  */
01000          pcrel = 1;
01001          iif.instr_size += suffixP[i] ? suffixP[i] : 4;
01002          IIF (12, 2, suffixP[i], (unsigned long) argv[i], 0,
01003               pcrel, pcrel_adjust, 1, IND (BRANCH, BYTE), NULL, -1, 1);
01004          break;
01005        case 'q':            /* quick */
01006          opcode_bit_ptr -= 4;
01007          IIF (11, 2, 42, (unsigned long) argv[i], 0, 0, 0, 0, 0,
01008               bit_fix_new (4, opcode_bit_ptr, -8, 7, 0, 1, 0), -1, 0);
01009          break;
01010        case 'r':            /* Register number (3 bits).  */
01011          list_search (argv[i], opt6, &tmp);
01012          opcode_bit_ptr -= 3;
01013          iif.iifP[1].object |= tmp << opcode_bit_ptr;
01014          break;
01015        case 'O':            /* Setcfg instruction optionslist.  */
01016          optlist (argv[i], opt3, &tmp);
01017          opcode_bit_ptr -= 4;
01018          iif.iifP[1].object |= tmp << 15;
01019          break;
01020        case 'C':            /* Cinv instruction optionslist.  */
01021          optlist (argv[i], opt4, &tmp);
01022          opcode_bit_ptr -= 4;
01023          iif.iifP[1].object |= tmp << 15; /* Insert the regtype in opcode.  */
01024          break;
01025        case 'S':            /* String instruction options list.  */
01026          optlist (argv[i], opt5, &tmp);
01027          opcode_bit_ptr -= 4;
01028          iif.iifP[1].object |= tmp << 15;
01029          break;
01030        case 'u':
01031        case 'U':            /* Register list.  */
01032          IIF (10, 1, 1, 0, 0, 0, 0, 0, 0, NULL, -1, 0);
01033          switch (operandsP[(i << 1) + 1])
01034            {
01035            case 'u':        /* Restore, exit.  */
01036              optlist (argv[i], opt1, &iif.iifP[10].object);
01037              break;
01038            case 'U':        /* Save, enter.  */
01039              optlist (argv[i], opt2, &iif.iifP[10].object);
01040              break;
01041            }
01042          iif.instr_size += 1;
01043          break;
01044        case 'M':            /* MMU register.  */
01045          list_search (argv[i], mmureg, &tmp);
01046          opcode_bit_ptr -= 4;
01047          iif.iifP[1].object |= tmp << opcode_bit_ptr;
01048          break;
01049        case 'P':            /* CPU register.  */
01050          list_search (argv[i], cpureg, &tmp);
01051          opcode_bit_ptr -= 4;
01052          iif.iifP[1].object |= tmp << opcode_bit_ptr;
01053          break;
01054        case 'g':            /* Inss exts.  */
01055          iif.instr_size += 1;      /* 1 byte is allocated after the opcode.  */
01056          IIF (10, 2, 1,
01057               (unsigned long) argv[i],    /* i always 2 here.  */
01058               0, 0, 0, 0, 0,
01059               bit_fix_new (3, 5, 0, 7, 0, 0, 0), /* A bit_fix is targeted to
01060                                                the byte.  */
01061               -1, 0);
01062          break;
01063        case 'G':
01064          IIF (11, 2, 42,
01065               (unsigned long) argv[i],    /* i always 3 here.  */
01066               0, 0, 0, 0, 0,
01067               bit_fix_new (5, 0, 1, 32, -1, 0, -1), -1, 0);
01068          break;
01069        case 'i':
01070          iif.instr_size += 1;
01071          b = 2 + i;         /* Put the extension byte after opcode.  */
01072          IIF (b, 2, 1, 0, 0, 0, 0, 0, 0, 0, -1, 0);
01073          break;
01074        default:
01075          as_fatal (_("Bad opcode-table-option, check in file ns32k-opcode.h"));
01076        }
01077     }
01078 }
01079 
01080 /* in:  instruction line
01081    out: internal structure of instruction
01082    that has been prepared for direct conversion to fragment(s) and
01083    fixes in a systematical fashion
01084    Return-value = recursive_level.  */
01085 /* Build iif of one assembly text line.  */
01086 
01087 static int
01088 parse (const char *line, int recursive_level)
01089 {
01090   const char *lineptr;
01091   char c, suffix_separator;
01092   int i;
01093   unsigned int argc;
01094   int arg_type;
01095   char sqr, sep;
01096   char suffix[MAX_ARGS], *argv[MAX_ARGS]; /* No more than 4 operands.  */
01097 
01098   if (recursive_level <= 0)
01099     {
01100       /* Called from md_assemble.  */
01101       for (lineptr = line; (*lineptr) != '\0' && (*lineptr) != ' '; lineptr++)
01102        continue;
01103 
01104       c = *lineptr;
01105       *(char *) lineptr = '\0';
01106 
01107       if (!(desc = (struct ns32k_opcode *) hash_find (inst_hash_handle, line)))
01108        as_fatal (_("No such opcode"));
01109 
01110       *(char *) lineptr = c;
01111     }
01112   else
01113     lineptr = line;
01114 
01115   argc = 0;
01116 
01117   if (*desc->operands)
01118     {
01119       if (*lineptr++ != '\0')
01120        {
01121          sqr = '[';
01122          sep = ',';
01123 
01124          while (*lineptr != '\0')
01125            {
01126              if (desc->operands[argc << 1])
01127               {
01128                 suffix[argc] = 0;
01129                 arg_type = desc->operands[(argc << 1) + 1];
01130 
01131                 switch (arg_type)
01132                   {
01133                   case 'd':
01134                   case 'b':
01135                   case 'p':
01136                   case 'H':
01137                     /* The operand is supposed to be a displacement.  */
01138                     /* Hackwarning: do not forget to update the 4
01139                          cases above when editing ns32k-opcode.h.  */
01140                     suffix_separator = ':';
01141                     break;
01142                   default:
01143                     /* If this char occurs we loose.  */
01144                     suffix_separator = '\255';
01145                     break;
01146                   }
01147 
01148                 suffix[argc] = 0; /* 0 when no ':' is encountered.  */
01149                 argv[argc] = freeptr;
01150                 *freeptr = '\0';
01151 
01152                 while ((c = *lineptr) != '\0' && c != sep)
01153                   {
01154                     if (c == sqr)
01155                      {
01156                        if (sqr == '[')
01157                          {
01158                            sqr = ']';
01159                            sep = '\0';
01160                          }
01161                        else
01162                          {
01163                            sqr = '[';
01164                            sep = ',';
01165                          }
01166                      }
01167 
01168                     if (c == suffix_separator)
01169                      {
01170                        /* ':' - label/suffix separator.  */
01171                        switch (lineptr[1])
01172                          {
01173                          case 'b':
01174                            suffix[argc] = 1;
01175                            break;
01176                          case 'w':
01177                            suffix[argc] = 2;
01178                            break;
01179                          case 'd':
01180                            suffix[argc] = 4;
01181                            break;
01182                          default:
01183                            as_warn (_("Bad suffix, defaulting to d"));
01184                            suffix[argc] = 4;
01185                            if (lineptr[1] == '\0' || lineptr[1] == sep)
01186                             {
01187                               lineptr += 1;
01188                               continue;
01189                             }
01190                            break;
01191                          }
01192 
01193                        lineptr += 2;
01194                        continue;
01195                      }
01196 
01197                     *freeptr++ = c;
01198                     lineptr++;
01199                   }
01200 
01201                 *freeptr++ = '\0';
01202                 argc += 1;
01203 
01204                 if (*lineptr == '\0')
01205                   continue;
01206 
01207                 lineptr += 1;
01208               }
01209              else
01210               as_fatal (_("Too many operands passed to instruction"));
01211            }
01212        }
01213     }
01214 
01215   if (argc != strlen (desc->operands) / 2)
01216     {
01217       if (strlen (desc->default_args))
01218        {
01219          /* We can apply default, don't goof.  */
01220          if (parse (desc->default_args, 1) != 1)
01221            /* Check error in default.  */
01222            as_fatal (_("Wrong numbers of operands in default, check ns32k-opcodes.h"));
01223        }
01224       else
01225        as_fatal (_("Wrong number of operands"));
01226     }
01227 
01228   for (i = 0; i < IIF_ENTRIES; i++)
01229     /* Mark all entries as void.  */
01230     iif.iifP[i].type = 0;
01231 
01232   /* Build opcode iif-entry.  */
01233   iif.instr_size = desc->opcode_size / 8;
01234   IIF (1, 1, iif.instr_size, desc->opcode_seed, 0, 0, 0, 0, 0, 0, -1, 0);
01235 
01236   /* This call encodes operands to iif format.  */
01237   if (argc)
01238     encode_operand (argc, argv, &desc->operands[0],
01239                   &suffix[0], desc->im_size, desc->opcode_size);
01240 
01241   return recursive_level;
01242 }
01243 
01244 /* This functionality should really be in the bfd library.  */
01245 
01246 static bfd_reloc_code_real_type
01247 reloc (int size, int pcrel, int type)
01248 {
01249   int length, index;
01250   bfd_reloc_code_real_type relocs[] =
01251   {
01252     BFD_RELOC_NS32K_IMM_8,
01253     BFD_RELOC_NS32K_IMM_16,
01254     BFD_RELOC_NS32K_IMM_32,
01255     BFD_RELOC_NS32K_IMM_8_PCREL,
01256     BFD_RELOC_NS32K_IMM_16_PCREL,
01257     BFD_RELOC_NS32K_IMM_32_PCREL,
01258 
01259     /* ns32k displacements.  */
01260     BFD_RELOC_NS32K_DISP_8,
01261     BFD_RELOC_NS32K_DISP_16,
01262     BFD_RELOC_NS32K_DISP_32,
01263     BFD_RELOC_NS32K_DISP_8_PCREL,
01264     BFD_RELOC_NS32K_DISP_16_PCREL,
01265     BFD_RELOC_NS32K_DISP_32_PCREL,
01266 
01267     /* Normal 2's complement.  */
01268     BFD_RELOC_8,
01269     BFD_RELOC_16,
01270     BFD_RELOC_32,
01271     BFD_RELOC_8_PCREL,
01272     BFD_RELOC_16_PCREL,
01273     BFD_RELOC_32_PCREL
01274   };
01275 
01276   switch (size)
01277     {
01278     case 1:
01279       length = 0;
01280       break;
01281     case 2:
01282       length = 1;
01283       break;
01284     case 4:
01285       length = 2;
01286       break;
01287     default:
01288       length = -1;
01289       break;
01290     }
01291 
01292   index = length + 3 * pcrel + 6 * type;
01293 
01294   if (index >= 0 && (unsigned int) index < sizeof (relocs) / sizeof (relocs[0]))
01295     return relocs[index];
01296 
01297   if (pcrel)
01298     as_bad (_("Can not do %d byte pc-relative relocation for storage type %d"),
01299            size, type);
01300   else
01301     as_bad (_("Can not do %d byte relocation for storage type %d"),
01302            size, type);
01303 
01304   return BFD_RELOC_NONE;
01305 
01306 }
01307 
01308 static void
01309 fix_new_ns32k (fragS *frag,        /* Which frag? */
01310               int where,           /* Where in that frag? */
01311               int size,            /* 1, 2  or 4 usually.  */
01312               symbolS *add_symbol, /* X_add_symbol.  */
01313               long offset,         /* X_add_number.  */
01314               int pcrel,           /* True if PC-relative relocation.  */
01315               char im_disp,        /* True if the value to write is a
01316                                       displacement.  */
01317               bit_fixS *bit_fixP,  /* Pointer at struct of bit_fix's, ignored if
01318                                       NULL.  */
01319               char bsr,            /* Sequent-linker-hack: 1 when relocobject is
01320                                       a bsr.  */
01321               fragS *opcode_frag,
01322               unsigned int opcode_offset)
01323 {
01324   fixS *fixP = fix_new (frag, where, size, add_symbol,
01325                      offset, pcrel,
01326                      bit_fixP ? NO_RELOC : reloc (size, pcrel, im_disp)
01327                      );
01328 
01329   fix_opcode_frag (fixP) = opcode_frag;
01330   fix_opcode_offset (fixP) = opcode_offset;
01331   fix_im_disp (fixP) = im_disp;
01332   fix_bsr (fixP) = bsr;
01333   fix_bit_fixP (fixP) = bit_fixP;
01334   /* We have a MD overflow check for displacements.  */
01335   fixP->fx_no_overflow = (im_disp != 0);
01336 }
01337 
01338 static void
01339 fix_new_ns32k_exp (fragS *frag,           /* Which frag? */
01340                  int where,        /* Where in that frag? */
01341                  int size,         /* 1, 2  or 4 usually.  */
01342                  expressionS *exp, /* Expression.  */
01343                  int pcrel,        /* True if PC-relative relocation.  */
01344                  char im_disp,     /* True if the value to write is a
01345                                       displacement.  */
01346                  bit_fixS *bit_fixP,      /* Pointer at struct of bit_fix's, ignored if
01347                                       NULL.  */
01348                  char bsr,         /* Sequent-linker-hack: 1 when relocobject is
01349                                       a bsr.  */
01350                  fragS *opcode_frag,
01351                  unsigned int opcode_offset)
01352 {
01353   fixS *fixP = fix_new_exp (frag, where, size, exp, pcrel,
01354                          bit_fixP ? NO_RELOC : reloc (size, pcrel, im_disp)
01355                          );
01356 
01357   fix_opcode_frag (fixP) = opcode_frag;
01358   fix_opcode_offset (fixP) = opcode_offset;
01359   fix_im_disp (fixP) = im_disp;
01360   fix_bsr (fixP) = bsr;
01361   fix_bit_fixP (fixP) = bit_fixP;
01362   /* We have a MD overflow check for displacements.  */
01363   fixP->fx_no_overflow = (im_disp != 0);
01364 }
01365 
01366 /* Convert number to chars in correct order.  */
01367 
01368 void
01369 md_number_to_chars (char *buf, valueT value, int nbytes)
01370 {
01371   number_to_chars_littleendian (buf, value, nbytes);
01372 }
01373 
01374 /* This is a variant of md_numbers_to_chars. The reason for its'
01375    existence is the fact that ns32k uses Huffman coded
01376    displacements. This implies that the bit order is reversed in
01377    displacements and that they are prefixed with a size-tag.
01378 
01379    binary: msb -> lsb
01380    0xxxxxxx                        byte
01381    10xxxxxx xxxxxxxx               word
01382    11xxxxxx xxxxxxxx xxxxxxxx xxxxxxxx    double word
01383 
01384    This must be taken care of and we do it here!  */
01385 
01386 static void
01387 md_number_to_disp (char *buf, long val, int n)
01388 {
01389   switch (n)
01390     {
01391     case 1:
01392       if (val < -64 || val > 63)
01393        as_bad (_("value of %ld out of byte displacement range."), val);
01394       val &= 0x7f;
01395 #ifdef SHOW_NUM
01396       printf ("%x ", val & 0xff);
01397 #endif
01398       *buf++ = val;
01399       break;
01400 
01401     case 2:
01402       if (val < -8192 || val > 8191)
01403        as_bad (_("value of %ld out of word displacement range."), val);
01404       val &= 0x3fff;
01405       val |= 0x8000;
01406 #ifdef SHOW_NUM
01407       printf ("%x ", val >> 8 & 0xff);
01408 #endif
01409       *buf++ = (val >> 8);
01410 #ifdef SHOW_NUM
01411       printf ("%x ", val & 0xff);
01412 #endif
01413       *buf++ = val;
01414       break;
01415 
01416     case 4:
01417       if (val < -0x20000000 || val >= 0x20000000)
01418        as_bad (_("value of %ld out of double word displacement range."), val);
01419       val |= 0xc0000000;
01420 #ifdef SHOW_NUM
01421       printf ("%x ", val >> 24 & 0xff);
01422 #endif
01423       *buf++ = (val >> 24);
01424 #ifdef SHOW_NUM
01425       printf ("%x ", val >> 16 & 0xff);
01426 #endif
01427       *buf++ = (val >> 16);
01428 #ifdef SHOW_NUM
01429       printf ("%x ", val >> 8 & 0xff);
01430 #endif
01431       *buf++ = (val >> 8);
01432 #ifdef SHOW_NUM
01433       printf ("%x ", val & 0xff);
01434 #endif
01435       *buf++ = val;
01436       break;
01437 
01438     default:
01439       as_fatal (_("Internal logic error.  line %d, file \"%s\""),
01440               __LINE__, __FILE__);
01441     }
01442 }
01443 
01444 static void
01445 md_number_to_imm (char *buf, long val, int n)
01446 {
01447   switch (n)
01448     {
01449     case 1:
01450 #ifdef SHOW_NUM
01451       printf ("%x ", val & 0xff);
01452 #endif
01453       *buf++ = val;
01454       break;
01455 
01456     case 2:
01457 #ifdef SHOW_NUM
01458       printf ("%x ", val >> 8 & 0xff);
01459 #endif
01460       *buf++ = (val >> 8);
01461 #ifdef SHOW_NUM
01462       printf ("%x ", val & 0xff);
01463 #endif
01464       *buf++ = val;
01465       break;
01466 
01467     case 4:
01468 #ifdef SHOW_NUM
01469       printf ("%x ", val >> 24 & 0xff);
01470 #endif
01471       *buf++ = (val >> 24);
01472 #ifdef SHOW_NUM
01473       printf ("%x ", val >> 16 & 0xff);
01474 #endif
01475       *buf++ = (val >> 16);
01476 #ifdef SHOW_NUM
01477       printf ("%x ", val >> 8 & 0xff);
01478 #endif
01479       *buf++ = (val >> 8);
01480 #ifdef SHOW_NUM
01481       printf ("%x ", val & 0xff);
01482 #endif
01483       *buf++ = val;
01484       break;
01485 
01486     default:
01487       as_fatal (_("Internal logic error. line %d, file \"%s\""),
01488               __LINE__, __FILE__);
01489     }
01490 }
01491 
01492 /* Fast bitfiddling support.  */
01493 /* Mask used to zero bitfield before oring in the true field.  */
01494 
01495 static unsigned long l_mask[] =
01496 {
01497   0xffffffff, 0xfffffffe, 0xfffffffc, 0xfffffff8,
01498   0xfffffff0, 0xffffffe0, 0xffffffc0, 0xffffff80,
01499   0xffffff00, 0xfffffe00, 0xfffffc00, 0xfffff800,
01500   0xfffff000, 0xffffe000, 0xffffc000, 0xffff8000,
01501   0xffff0000, 0xfffe0000, 0xfffc0000, 0xfff80000,
01502   0xfff00000, 0xffe00000, 0xffc00000, 0xff800000,
01503   0xff000000, 0xfe000000, 0xfc000000, 0xf8000000,
01504   0xf0000000, 0xe0000000, 0xc0000000, 0x80000000,
01505 };
01506 static unsigned long r_mask[] =
01507 {
01508   0x00000000, 0x00000001, 0x00000003, 0x00000007,
01509   0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f,
01510   0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff,
01511   0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff,
01512   0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff,
01513   0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff,
01514   0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff,
01515   0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff,
01516 };
01517 #define MASK_BITS 31
01518 /* Insert bitfield described by field_ptr and val at buf
01519    This routine is written for modification of the first 4 bytes pointed
01520    to by buf, to yield speed.
01521    The ifdef stuff is for selection between a ns32k-dependent routine
01522    and a general version. (My advice: use the general version!).  */
01523 
01524 static void
01525 md_number_to_field (char *buf, long val, bit_fixS *field_ptr)
01526 {
01527   unsigned long object;
01528   unsigned long mask;
01529   /* Define ENDIAN on a ns32k machine.  */
01530 #ifdef ENDIAN
01531   unsigned long *mem_ptr;
01532 #else
01533   char *mem_ptr;
01534 #endif
01535 
01536   if (field_ptr->fx_bit_min <= val && val <= field_ptr->fx_bit_max)
01537     {
01538 #ifdef ENDIAN
01539       if (field_ptr->fx_bit_base)
01540        /* Override buf.  */
01541        mem_ptr = (unsigned long *) field_ptr->fx_bit_base;
01542       else
01543        mem_ptr = (unsigned long *) buf;
01544 
01545       mem_ptr = ((unsigned long *)
01546                ((char *) mem_ptr + field_ptr->fx_bit_base_adj));
01547 #else
01548       if (field_ptr->fx_bit_base)
01549        mem_ptr = (char *) field_ptr->fx_bit_base;
01550       else
01551        mem_ptr = buf;
01552 
01553       mem_ptr += field_ptr->fx_bit_base_adj;
01554 #endif
01555 #ifdef ENDIAN
01556       /* We have a nice ns32k machine with lowbyte at low-physical mem.  */
01557       object = *mem_ptr;    /* get some bytes */
01558 #else /* OVE Goof! the machine is a m68k or dito.  */
01559       /* That takes more byte fiddling.  */
01560       object = 0;
01561       object |= mem_ptr[3] & 0xff;
01562       object <<= 8;
01563       object |= mem_ptr[2] & 0xff;
01564       object <<= 8;
01565       object |= mem_ptr[1] & 0xff;
01566       object <<= 8;
01567       object |= mem_ptr[0] & 0xff;
01568 #endif
01569       mask = 0;
01570       mask |= (r_mask[field_ptr->fx_bit_offset]);
01571       mask |= (l_mask[field_ptr->fx_bit_offset + field_ptr->fx_bit_size]);
01572       object &= mask;
01573       val += field_ptr->fx_bit_add;
01574       object |= ((val << field_ptr->fx_bit_offset) & (mask ^ 0xffffffff));
01575 #ifdef ENDIAN
01576       *mem_ptr = object;
01577 #else
01578       mem_ptr[0] = (char) object;
01579       object >>= 8;
01580       mem_ptr[1] = (char) object;
01581       object >>= 8;
01582       mem_ptr[2] = (char) object;
01583       object >>= 8;
01584       mem_ptr[3] = (char) object;
01585 #endif
01586     }
01587   else
01588     as_bad (_("Bit field out of range"));
01589 }
01590 
01591 /* Convert iif to fragments.  From this point we start to dribble with
01592    functions in other files than this one.(Except hash.c) So, if it's
01593    possible to make an iif for an other CPU, you don't need to know
01594    what frags, relax, obstacks, etc is in order to port this
01595    assembler. You only need to know if it's possible to reduce your
01596    cpu-instruction to iif-format (takes some work) and adopt the other
01597    md_? parts according to given instructions Note that iif was
01598    invented for the clean ns32k`s architecture.  */
01599 
01600 /* GAS for the ns32k has a problem. PC relative displacements are
01601    relative to the address of the opcode, not the address of the
01602    operand. We used to keep track of the offset between the operand
01603    and the opcode in pcrel_adjust for each frag and each fix. However,
01604    we get into trouble where there are two or more pc-relative
01605    operands and the size of the first one can't be determined. Then in
01606    the relax phase, the size of the first operand will change and
01607    pcrel_adjust will no longer be correct.  The current solution is
01608    keep a pointer to the frag with the opcode in it and the offset in
01609    that frag for each frag and each fix. Then, when needed, we can
01610    always figure out how far it is between the opcode and the pcrel
01611    object.  See also md_pcrel_adjust and md_fix_pcrel_adjust.  For
01612    objects not part of an instruction, the pointer to the opcode frag
01613    is always zero.  */
01614 
01615 static void
01616 convert_iif (void)
01617 {
01618   int i;
01619   bit_fixS *j;
01620   fragS *inst_frag;
01621   unsigned int inst_offset;
01622   char *inst_opcode;
01623   char *memP;
01624   int l;
01625   int k;
01626   char type;
01627   char size = 0;
01628 
01629   frag_grow (iif.instr_size);      /* This is important.  */
01630   memP = frag_more (0);
01631   inst_opcode = memP;
01632   inst_offset = (memP - frag_now->fr_literal);
01633   inst_frag = frag_now;
01634 
01635   for (i = 0; i < IIF_ENTRIES; i++)
01636     {
01637       if ((type = iif.iifP[i].type))
01638        {
01639          /* The object exist, so handle it.  */
01640          switch (size = iif.iifP[i].size)
01641            {
01642            case 42:
01643              size = 0;
01644              /* It's a bitfix that operates on an existing object.  */
01645              if (iif.iifP[i].bit_fixP->fx_bit_base)
01646               /* Expand fx_bit_base to point at opcode.  */
01647               iif.iifP[i].bit_fixP->fx_bit_base = (long) inst_opcode;
01648              /* Fall through.  */
01649 
01650            case 8:          /* bignum or doublefloat.  */
01651            case 1:
01652            case 2:
01653            case 3:
01654            case 4:
01655              /* The final size in objectmemory is known.  */
01656              memP = frag_more (size);
01657              j = iif.iifP[i].bit_fixP;
01658 
01659              switch (type)
01660               {
01661               case 1:       /* The object is pure binary.  */
01662                 if (j)
01663                   md_number_to_field (memP, exprP.X_add_number, j);
01664 
01665                 else if (iif.iifP[i].pcrel)
01666                   fix_new_ns32k (frag_now,
01667                                (long) (memP - frag_now->fr_literal),
01668                                size,
01669                                0,
01670                                iif.iifP[i].object,
01671                                iif.iifP[i].pcrel,
01672                                iif.iifP[i].im_disp,
01673                                0,
01674                                iif.iifP[i].bsr,  /* Sequent hack.  */
01675                                inst_frag, inst_offset);
01676                 else
01677                   {
01678                     /* Good, just put them bytes out.  */
01679                     switch (iif.iifP[i].im_disp)
01680                      {
01681                      case 0:
01682                        md_number_to_chars (memP, iif.iifP[i].object, size);
01683                        break;
01684                      case 1:
01685                        md_number_to_disp (memP, iif.iifP[i].object, size);
01686                        break;
01687                      default:
01688                        as_fatal (_("iif convert internal pcrel/binary"));
01689                      }
01690                   }
01691                 break;
01692 
01693               case 2:
01694                 /* The object is a pointer at an expression, so
01695                      unpack it, note that bignums may result from the
01696                      expression.  */
01697                 evaluate_expr (&exprP, (char *) iif.iifP[i].object);
01698                 if (exprP.X_op == O_big || size == 8)
01699                   {
01700                     if ((k = exprP.X_add_number) > 0)
01701                      {
01702                        /* We have a bignum ie a quad. This can only
01703                              happens in a long suffixed instruction.  */
01704                        if (k * 2 > size)
01705                          as_bad (_("Bignum too big for long"));
01706 
01707                        if (k == 3)
01708                          memP += 2;
01709 
01710                        for (l = 0; k > 0; k--, l += 2)
01711                          md_number_to_chars (memP + l,
01712                                           generic_bignum[l >> 1],
01713                                           sizeof (LITTLENUM_TYPE));
01714                      }
01715                     else
01716                      {
01717                        /* flonum.  */
01718                        LITTLENUM_TYPE words[4];
01719 
01720                        switch (size)
01721                          {
01722                          case 4:
01723                            gen_to_words (words, 2, 8);
01724                            md_number_to_imm (memP, (long) words[0],
01725                                           sizeof (LITTLENUM_TYPE));
01726                            md_number_to_imm (memP + sizeof (LITTLENUM_TYPE),
01727                                           (long) words[1],
01728                                           sizeof (LITTLENUM_TYPE));
01729                            break;
01730                          case 8:
01731                            gen_to_words (words, 4, 11);
01732                            md_number_to_imm (memP, (long) words[0],
01733                                           sizeof (LITTLENUM_TYPE));
01734                            md_number_to_imm (memP + sizeof (LITTLENUM_TYPE),
01735                                           (long) words[1],
01736                                           sizeof (LITTLENUM_TYPE));
01737                            md_number_to_imm ((memP + 2
01738                                            * sizeof (LITTLENUM_TYPE)),
01739                                           (long) words[2],
01740                                           sizeof (LITTLENUM_TYPE));
01741                            md_number_to_imm ((memP + 3
01742                                            * sizeof (LITTLENUM_TYPE)),
01743                                           (long) words[3],
01744                                           sizeof (LITTLENUM_TYPE));
01745                            break;
01746                          }
01747                      }
01748                     break;
01749                   }
01750                 if (exprP.X_add_symbol ||
01751                     exprP.X_op_symbol ||
01752                     iif.iifP[i].pcrel)
01753                   {
01754                     /* The expression was undefined due to an
01755                          undefined label. Create a fix so we can fix
01756                          the object later.  */
01757                     exprP.X_add_number += iif.iifP[i].object_adjust;
01758                     fix_new_ns32k_exp (frag_now,
01759                                     (long) (memP - frag_now->fr_literal),
01760                                     size,
01761                                     &exprP,
01762                                     iif.iifP[i].pcrel,
01763                                     iif.iifP[i].im_disp,
01764                                     j,
01765                                     iif.iifP[i].bsr,
01766                                     inst_frag, inst_offset);
01767                   }
01768                 else if (j)
01769                   md_number_to_field (memP, exprP.X_add_number, j);
01770                 else
01771                   {
01772                     /* Good, just put them bytes out.  */
01773                     switch (iif.iifP[i].im_disp)
01774                      {
01775                      case 0:
01776                        md_number_to_imm (memP, exprP.X_add_number, size);
01777                        break;
01778                      case 1:
01779                        md_number_to_disp (memP, exprP.X_add_number, size);
01780                        break;
01781                      default:
01782                        as_fatal (_("iif convert internal pcrel/pointer"));
01783                      }
01784                   }
01785                 break;
01786               default:
01787                 as_fatal (_("Internal logic error in iif.iifP[n].type"));
01788               }
01789              break;
01790 
01791            case 0:
01792              /* Too bad, the object may be undefined as far as its
01793                final nsize in object memory is concerned.  The size
01794                of the object in objectmemory is not explicitly
01795                given.  If the object is defined its length can be
01796                determined and a fix can replace the frag.  */
01797              {
01798               evaluate_expr (&exprP, (char *) iif.iifP[i].object);
01799 
01800               if ((exprP.X_add_symbol || exprP.X_op_symbol) &&
01801                   !iif.iifP[i].pcrel)
01802                 {
01803                   /* Size is unknown until link time so have to default.  */
01804                   size = default_disp_size; /* Normally 4 bytes.  */
01805                   memP = frag_more (size);
01806                   fix_new_ns32k_exp (frag_now,
01807                                    (long) (memP - frag_now->fr_literal),
01808                                    size,
01809                                    &exprP,
01810                                    0, /* never iif.iifP[i].pcrel, */
01811                                    1, /* always iif.iifP[i].im_disp */
01812                                    (bit_fixS *) 0, 0,
01813                                    inst_frag,
01814                                    inst_offset);
01815                   break;           /* Exit this absolute hack.  */
01816                 }
01817 
01818               if (exprP.X_add_symbol || exprP.X_op_symbol)
01819                 {
01820                   /* Frag it.  */
01821                   if (exprP.X_op_symbol)
01822                     /* We cant relax this case.  */
01823                     as_fatal (_("Can't relax difference"));
01824                   else
01825                     {
01826                      /* Size is not important.  This gets fixed by
01827                         relax, but we assume 0 in what follows.  */
01828                      memP = frag_more (4); /* Max size.  */
01829                      size = 0;
01830 
01831                      {
01832                        fragS *old_frag = frag_now;
01833                        frag_variant (rs_machine_dependent,
01834                                    4, /* Max size.  */
01835                                    0, /* Size.  */
01836                                    IND (BRANCH, UNDEF), /* Expecting
01837                                                                 the worst.  */
01838                                    exprP.X_add_symbol,
01839                                    exprP.X_add_number,
01840                                    inst_opcode);
01841                        frag_opcode_frag (old_frag) = inst_frag;
01842                        frag_opcode_offset (old_frag) = inst_offset;
01843                        frag_bsr (old_frag) = iif.iifP[i].bsr;
01844                      }
01845                     }
01846                 }
01847               else
01848                 {
01849                   /* This duplicates code in md_number_to_disp.  */
01850                   if (-64 <= exprP.X_add_number && exprP.X_add_number <= 63)
01851                     size = 1;
01852                   else
01853                     {
01854                      if (-8192 <= exprP.X_add_number
01855                          && exprP.X_add_number <= 8191)
01856                        size = 2;
01857                      else
01858                        {
01859                          if (-0x20000000 <= exprP.X_add_number
01860                             && exprP.X_add_number<=0x1fffffff)
01861                            size = 4;
01862                          else
01863                            {
01864                             as_bad (_("Displacement too large for :d"));
01865                             size = 4;
01866                            }
01867                        }
01868                     }
01869 
01870                   memP = frag_more (size);
01871                   md_number_to_disp (memP, exprP.X_add_number, size);
01872                 }
01873              }
01874              break;
01875 
01876            default:
01877              as_fatal (_("Internal logic error in iif.iifP[].type"));
01878            }
01879        }
01880     }
01881 }
01882 
01883 void
01884 md_assemble (char *line)
01885 {
01886   freeptr = freeptr_static;
01887   parse (line, 0);          /* Explode line to more fix form in iif.  */
01888   convert_iif ();           /* Convert iif to frags, fix's etc.  */
01889 #ifdef SHOW_NUM
01890   printf (" \t\t\t%s\n", line);
01891 #endif
01892 }
01893 
01894 void
01895 md_begin (void)
01896 {
01897   /* Build a hashtable of the instructions.  */
01898   const struct ns32k_opcode *ptr;
01899   const char *stat;
01900   const struct ns32k_opcode *endop;
01901 
01902   inst_hash_handle = hash_new ();
01903 
01904   endop = ns32k_opcodes + sizeof (ns32k_opcodes) / sizeof (ns32k_opcodes[0]);
01905   for (ptr = ns32k_opcodes; ptr < endop; ptr++)
01906     {
01907       if ((stat = hash_insert (inst_hash_handle, ptr->name, (char *) ptr)))
01908        /* Fatal.  */
01909        as_fatal (_("Can't hash %s: %s"), ptr->name, stat);
01910     }
01911 
01912   /* Some private space please!  */
01913   freeptr_static = (char *) malloc (PRIVATE_SIZE);
01914 }
01915 
01916 /* Must be equal to MAX_PRECISON in atof-ieee.c.  */
01917 #define MAX_LITTLENUMS 6
01918 
01919 /* Turn the string pointed to by litP into a floating point constant
01920    of type TYPE, and emit the appropriate bytes.  The number of
01921    LITTLENUMS emitted is stored in *SIZEP.  An error message is
01922    returned, or NULL on OK.  */
01923 
01924 char *
01925 md_atof (int type, char *litP, int *sizeP)
01926 {
01927   int prec;
01928   LITTLENUM_TYPE words[MAX_LITTLENUMS];
01929   LITTLENUM_TYPE *wordP;
01930   char *t;
01931 
01932   switch (type)
01933     {
01934     case 'f':
01935       prec = 2;
01936       break;
01937 
01938     case 'd':
01939       prec = 4;
01940       break;
01941     default:
01942       *sizeP = 0;
01943       return _("Bad call to MD_ATOF()");
01944     }
01945 
01946   t = atof_ieee (input_line_pointer, type, words);
01947   if (t)
01948     input_line_pointer = t;
01949 
01950   *sizeP = prec * sizeof (LITTLENUM_TYPE);
01951 
01952   for (wordP = words + prec; prec--;)
01953     {
01954       md_number_to_chars (litP, (long) (*--wordP), sizeof (LITTLENUM_TYPE));
01955       litP += sizeof (LITTLENUM_TYPE);
01956     }
01957 
01958   return 0;
01959 }
01960 
01961 int
01962 md_pcrel_adjust (fragS *fragP)
01963 {
01964   fragS *opcode_frag;
01965   addressT opcode_address;
01966   unsigned int offset;
01967 
01968   opcode_frag = frag_opcode_frag (fragP);
01969   if (opcode_frag == 0)
01970     return 0;
01971 
01972   offset = frag_opcode_offset (fragP);
01973   opcode_address = offset + opcode_frag->fr_address;
01974 
01975   return fragP->fr_address + fragP->fr_fix - opcode_address;
01976 }
01977 
01978 static int
01979 md_fix_pcrel_adjust (fixS *fixP)
01980 {
01981   fragS *opcode_frag;
01982   addressT opcode_address;
01983   unsigned int offset;
01984 
01985   opcode_frag = fix_opcode_frag (fixP);
01986   if (opcode_frag == 0)
01987     return 0;
01988 
01989   offset = fix_opcode_offset (fixP);
01990   opcode_address = offset + opcode_frag->fr_address;
01991 
01992   return fixP->fx_where + fixP->fx_frag->fr_address - opcode_address;
01993 }
01994 
01995 /* Apply a fixS (fixup of an instruction or data that we didn't have
01996    enough info to complete immediately) to the data in a frag.
01997 
01998    On the ns32k, everything is in a different format, so we have broken
01999    out separate functions for each kind of thing we could be fixing.
02000    They all get called from here.  */
02001 
02002 void
02003 md_apply_fix (fixS *fixP, valueT * valP, segT seg ATTRIBUTE_UNUSED)
02004 {
02005   long val = * (long *) valP;
02006   char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
02007 
02008   if (fix_bit_fixP (fixP))
02009     /* Bitfields to fix, sigh.  */
02010     md_number_to_field (buf, val, fix_bit_fixP (fixP));
02011   else switch (fix_im_disp (fixP))
02012     {
02013     case 0:
02014       /* Immediate field.  */
02015       md_number_to_imm (buf, val, fixP->fx_size);
02016       break;
02017 
02018     case 1:
02019       /* Displacement field.  */
02020       /* Calculate offset.  */
02021       md_number_to_disp (buf,
02022                       (fixP->fx_pcrel ? val + md_fix_pcrel_adjust (fixP)
02023                        : val), fixP->fx_size);
02024       break;
02025 
02026     case 2:
02027       /* Pointer in a data object.  */
02028       md_number_to_chars (buf, val, fixP->fx_size);
02029       break;
02030     }
02031 
02032   if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
02033     fixP->fx_done = 1;
02034 }
02035 
02036 /* Convert a relaxed displacement to ditto in final output.  */
02037 
02038 void
02039 md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
02040                segT sec ATTRIBUTE_UNUSED,
02041                fragS *fragP)
02042 {
02043   long disp;
02044   long ext = 0;
02045   /* Address in gas core of the place to store the displacement.  */
02046   char *buffer_address = fragP->fr_fix + fragP->fr_literal;
02047   /* Address in object code of the displacement.  */
02048   int object_address;
02049 
02050   switch (fragP->fr_subtype)
02051     {
02052     case IND (BRANCH, BYTE):
02053       ext = 1;
02054       break;
02055     case IND (BRANCH, WORD):
02056       ext = 2;
02057       break;
02058     case IND (BRANCH, DOUBLE):
02059       ext = 4;
02060       break;
02061     }
02062 
02063   if (ext == 0)
02064     return;
02065 
02066   know (fragP->fr_symbol);
02067 
02068   object_address = fragP->fr_fix + fragP->fr_address;
02069 
02070   /* The displacement of the address, from current location.  */
02071   disp = (S_GET_VALUE (fragP->fr_symbol) + fragP->fr_offset) - object_address;
02072   disp += md_pcrel_adjust (fragP);
02073 
02074   md_number_to_disp (buffer_address, (long) disp, (int) ext);
02075   fragP->fr_fix += ext;
02076 }
02077 
02078 /* This function returns the estimated size a variable object will occupy,
02079    one can say that we tries to guess the size of the objects before we
02080    actually know it.  */
02081 
02082 int
02083 md_estimate_size_before_relax (fragS *fragP, segT segment)
02084 {
02085   if (fragP->fr_subtype == IND (BRANCH, UNDEF))
02086     {
02087       if (S_GET_SEGMENT (fragP->fr_symbol) != segment)
02088        {
02089          /* We don't relax symbols defined in another segment.  The
02090             thing to do is to assume the object will occupy 4 bytes.  */
02091          fix_new_ns32k (fragP,
02092                       (int) (fragP->fr_fix),
02093                       4,
02094                       fragP->fr_symbol,
02095                       fragP->fr_offset,
02096                       1,
02097                       1,
02098                       0,
02099                       frag_bsr(fragP), /* Sequent hack.  */
02100                       frag_opcode_frag (fragP),
02101                       frag_opcode_offset (fragP));
02102          fragP->fr_fix += 4;
02103          frag_wane (fragP);
02104          return 4;
02105        }
02106 
02107       /* Relaxable case.  Set up the initial guess for the variable
02108         part of the frag.  */
02109       fragP->fr_subtype = IND (BRANCH, BYTE);
02110     }
02111 
02112   if (fragP->fr_subtype >= sizeof (md_relax_table) / sizeof (md_relax_table[0]))
02113     abort ();
02114 
02115   /* Return the size of the variable part of the frag.  */
02116   return md_relax_table[fragP->fr_subtype].rlx_length;
02117 }
02118 
02119 int md_short_jump_size = 3;
02120 int md_long_jump_size = 5;
02121 
02122 void
02123 md_create_short_jump (char *ptr,
02124                     addressT from_addr,
02125                     addressT to_addr,
02126                     fragS *frag ATTRIBUTE_UNUSED,
02127                     symbolS *to_symbol ATTRIBUTE_UNUSED)
02128 {
02129   valueT offset;
02130 
02131   offset = to_addr - from_addr;
02132   md_number_to_chars (ptr, (valueT) 0xEA, 1);
02133   md_number_to_disp (ptr + 1, (valueT) offset, 2);
02134 }
02135 
02136 void
02137 md_create_long_jump (char *ptr,
02138                    addressT from_addr,
02139                    addressT to_addr,
02140                    fragS *frag ATTRIBUTE_UNUSED,
02141                    symbolS *to_symbol ATTRIBUTE_UNUSED)
02142 {
02143   valueT offset;
02144 
02145   offset = to_addr - from_addr;
02146   md_number_to_chars (ptr, (valueT) 0xEA, 1);
02147   md_number_to_disp (ptr + 1, (valueT) offset, 4);
02148 }
02149 
02150 const char *md_shortopts = "m:";
02151 
02152 struct option md_longopts[] =
02153 {
02154 #define OPTION_DISP_SIZE (OPTION_MD_BASE)
02155   {"disp-size-default", required_argument , NULL, OPTION_DISP_SIZE},
02156   {NULL, no_argument, NULL, 0}
02157 };
02158 
02159 size_t md_longopts_size = sizeof (md_longopts);
02160 
02161 int
02162 md_parse_option (int c, char *arg)
02163 {
02164   switch (c)
02165     {
02166     case 'm':
02167       if (!strcmp (arg, "32032"))
02168        {
02169          cpureg = cpureg_032;
02170          mmureg = mmureg_032;
02171        }
02172       else if (!strcmp (arg, "32532"))
02173        {
02174          cpureg = cpureg_532;
02175          mmureg = mmureg_532;
02176        }
02177       else
02178        {
02179          as_warn (_("invalid architecture option -m%s, ignored"), arg);
02180          return 0;
02181        }
02182       break;
02183     case OPTION_DISP_SIZE:
02184       {
02185        int size = atoi(arg);
02186        switch (size)
02187          {
02188          case 1: case 2: case 4:
02189            default_disp_size = size;
02190            break;
02191          default:
02192            as_warn (_("invalid default displacement size \"%s\". Defaulting to %d."),
02193                    arg, default_disp_size);
02194          }
02195        break;
02196       }
02197 
02198     default:
02199       return 0;
02200     }
02201 
02202   return 1;
02203 }
02204 
02205 void
02206 md_show_usage (FILE *stream)
02207 {
02208   fprintf (stream, _("\
02209 NS32K options:\n\
02210 -m32032 | -m32532    select variant of NS32K architecture\n\
02211 --disp-size-default=<1|2|4>\n"));
02212 }
02213 
02214 /* This is TC_CONS_FIX_NEW, called by emit_expr in read.c.  */
02215 
02216 void
02217 cons_fix_new_ns32k (fragS *frag,   /* Which frag? */
02218                   int where,              /* Where in that frag? */
02219                   int size,        /* 1, 2  or 4 usually.  */
02220                   expressionS *exp)       /* Expression.  */
02221 {
02222   fix_new_ns32k_exp (frag, where, size, exp,
02223                    0, 2, 0, 0, 0, 0);
02224 }
02225 
02226 /* We have no need to default values of symbols.  */
02227 
02228 symbolS *
02229 md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
02230 {
02231   return 0;
02232 }
02233 
02234 /* Round up a section size to the appropriate boundary.  */
02235 
02236 valueT
02237 md_section_align (segT segment ATTRIBUTE_UNUSED, valueT size)
02238 {
02239   return size;                     /* Byte alignment is fine.  */
02240 }
02241 
02242 /* Exactly what point is a PC-relative offset relative TO?  On the
02243    ns32k, they're relative to the start of the instruction.  */
02244 
02245 long
02246 md_pcrel_from (fixS *fixP)
02247 {
02248   long res;
02249 
02250   res = fixP->fx_where + fixP->fx_frag->fr_address;
02251 #ifdef SEQUENT_COMPATABILITY
02252   if (frag_bsr (fixP->fx_frag))
02253     res += 0x12                    /* FOO Kludge alert!  */
02254 #endif
02255       return res;
02256 }
02257 
02258 arelent *
02259 tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
02260 {
02261   arelent *rel;
02262   bfd_reloc_code_real_type code;
02263 
02264   code = reloc (fixp->fx_size, fixp->fx_pcrel, fix_im_disp (fixp));
02265 
02266   rel = xmalloc (sizeof (arelent));
02267   rel->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
02268   *rel->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
02269   rel->address = fixp->fx_frag->fr_address + fixp->fx_where;
02270   if (fixp->fx_pcrel)
02271     rel->addend = fixp->fx_addnumber;
02272   else
02273     rel->addend = 0;
02274 
02275   rel->howto = bfd_reloc_type_lookup (stdoutput, code);
02276   if (!rel->howto)
02277     {
02278       const char *name;
02279 
02280       name = S_GET_NAME (fixp->fx_addsy);
02281       if (name == NULL)
02282        name = _("<unknown>");
02283       as_fatal (_("Cannot find relocation type for symbol %s, code %d"),
02284               name, (int) code);
02285     }
02286 
02287   return rel;
02288 }