home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / binutils-2.7-src.tgz / tar.out / fsf / binutils / gas / config / tc-ns32k.c < prev    next >
C/C++ Source or Header  |  1996-09-28  |  63KB  |  2,387 lines

  1. /* ns32k.c  -- Assemble on the National Semiconductor 32k series
  2.    Copyright (C) 1987, 92, 93, 94, 95, 1996 Free Software Foundation, Inc.
  3.  
  4.    This file is part of GAS, the GNU Assembler.
  5.  
  6.    GAS is free software; you can redistribute it and/or modify
  7.    it under the terms of the GNU General Public License as published by
  8.    the Free Software Foundation; either version 2, or (at your option)
  9.    any later version.
  10.  
  11.    GAS is distributed in the hope that it will be useful,
  12.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.    GNU General Public License for more details.
  15.  
  16.    You should have received a copy of the GNU General Public License
  17.    along with GAS; see the file COPYING.  If not, write to
  18.    the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
  19.  
  20. /*#define SHOW_NUM 1*//* uncomment for debugging */
  21.  
  22. #include <stdio.h>
  23. #include <ctype.h>
  24.  
  25. #include "as.h"
  26. #include "opcode/ns32k.h"
  27.  
  28. #include "obstack.h"
  29.  
  30. /* Macros */
  31. #define IIF_ENTRIES 13        /* number of entries in iif */
  32. #define PRIVATE_SIZE 256    /* size of my garbage memory */
  33. #define MAX_ARGS 4
  34. #define DEFAULT    -1        /* addr_mode returns this value when plain constant or label is encountered */
  35.  
  36. #define IIF(ptr,a1,c1,e1,g1,i1,k1,m1,o1,q1,s1,u1) \
  37.     iif.iifP[ptr].type= a1; \
  38.     iif.iifP[ptr].size= c1; \
  39.     iif.iifP[ptr].object= e1; \
  40.     iif.iifP[ptr].object_adjust= g1; \
  41.     iif.iifP[ptr].pcrel= i1; \
  42.     iif.iifP[ptr].pcrel_adjust= k1; \
  43.     iif.iifP[ptr].im_disp= m1; \
  44.     iif.iifP[ptr].relax_substate= o1; \
  45.     iif.iifP[ptr].bit_fixP= q1; \
  46.     iif.iifP[ptr].addr_mode= s1; \
  47.     iif.iifP[ptr].bsr= u1;
  48.  
  49. #ifdef SEQUENT_COMPATABILITY
  50. #define LINE_COMMENT_CHARS "|"
  51. #define ABSOLUTE_PREFIX '@'
  52. #define IMMEDIATE_PREFIX '#'
  53. #endif
  54.  
  55. #ifndef LINE_COMMENT_CHARS
  56. #define LINE_COMMENT_CHARS "#"
  57. #endif
  58.  
  59. const char comment_chars[] = "#";
  60. const char line_comment_chars[] = LINE_COMMENT_CHARS;
  61. const char line_separator_chars[] = "";
  62. #if !defined(ABSOLUTE_PREFIX) && !defined(IMMEDIATE_PREFIX)
  63. #define ABSOLUTE_PREFIX '@'    /* One or the other MUST be defined */
  64. #endif
  65.  
  66. struct addr_mode
  67.   {
  68.     char mode;            /* addressing mode of operand (0-31) */
  69.     char scaled_mode;        /* mode combined with scaled mode */
  70.     char scaled_reg;        /* register used in scaled+1 (1-8) */
  71.     char float_flag;        /* set if R0..R7 was F0..F7 ie a floating-point-register */
  72.     char am_size;        /* estimated max size of general addr-mode parts*/
  73.     char im_disp;        /* if im_disp==1 we have a displacement */
  74.     char pcrel;            /* 1 if pcrel, this is really redundant info */
  75.     char disp_suffix[2];    /* length of displacement(s), 0=undefined */
  76.     char *disp[2];        /* pointer(s) at displacement(s)
  77.                    or immediates(s)     (ascii) */
  78.     char index_byte;        /* index byte */
  79.   };
  80. typedef struct addr_mode addr_modeS;
  81.  
  82.  
  83. char *freeptr, *freeptr_static;    /* points at some number of free bytes */
  84. struct hash_control *inst_hash_handle;
  85.  
  86. struct ns32k_opcode *desc;    /* pointer at description of instruction */
  87. addr_modeS addr_modeP;
  88. const char EXP_CHARS[] = "eE";
  89. const char FLT_CHARS[] = "fd";    /* we don't want to support lowercase, do we */
  90.  
  91. /* UPPERCASE denotes live names
  92.  * when an instruction is built, IIF is used as an intermidiate form to store
  93.  * the actual parts of the instruction. A ns32k machine instruction can
  94.  * be divided into a couple of sub PARTs. When an instruction is assembled
  95.  * the appropriate PART get an assignment. When an IIF has been completed it's
  96.  * converted to a FRAGment as specified in AS.H */
  97.  
  98. /* internal structs */
  99. struct ns32k_option
  100.   {
  101.     char *pattern;
  102.     unsigned long or;
  103.     unsigned long and;
  104.   };
  105.  
  106. typedef struct
  107.   {
  108.     int type;            /* how to interpret object */
  109.     int size;            /* Estimated max size of object */
  110.     unsigned long object;    /* binary data */
  111.     int object_adjust;        /* number added to object */
  112.     int pcrel;            /* True if object is pcrel */
  113.     int pcrel_adjust;        /* length in bytes from the
  114.                        instruction start to the
  115.                        displacement */
  116.     int im_disp;        /* True if the object is a displacement */
  117.     relax_substateT relax_substate;    /* Initial relaxsubstate */
  118.     bit_fixS *bit_fixP;        /* Pointer at bit_fix struct */
  119.     int addr_mode;        /* What addrmode do we associate with this iif-entry */
  120.     char bsr;            /* Sequent hack */
  121.   }
  122.  
  123. iif_entryT;            /* Internal Instruction Format */
  124.  
  125. struct int_ins_form
  126.   {
  127.     int instr_size;        /* Max size of instruction in bytes. */
  128.     iif_entryT iifP[IIF_ENTRIES + 1];
  129.   };
  130. struct int_ins_form iif;
  131. expressionS exprP;
  132. char *input_line_pointer;
  133. /* description of the PARTs in IIF
  134.  *object[n]:
  135.  * 0    total length in bytes of entries in iif
  136.  * 1    opcode
  137.  * 2    index_byte_a
  138.  * 3    index_byte_b
  139.  * 4    disp_a_1
  140.  * 5    disp_a_2
  141.  * 6    disp_b_1
  142.  * 7    disp_b_2
  143.  * 8    imm_a
  144.  * 9    imm_b
  145.  * 10    implied1
  146.  * 11    implied2
  147.  *
  148.  * For every entry there is a datalength in bytes. This is stored in size[n].
  149.  *     0,    the objectlength is not explicitly given by the instruction
  150.  *        and the operand is undefined. This is a case for relaxation.
  151.  *        Reserve 4 bytes for the final object.
  152.  *
  153.  *     1,    the entry contains one byte
  154.  *     2,    the entry contains two bytes
  155.  *     3,    the entry contains three bytes
  156.  *     4,    the entry contains four bytes
  157.  *    etc
  158.  *
  159.  * Furthermore, every entry has a data type identifier in type[n].
  160.  *
  161.  *      0,    the entry is void, ignore it.
  162.  *      1,    the entry is a binary number.
  163.  *     2,    the entry is a pointer at an expression.
  164.  *        Where expression may be as simple as a single '1',
  165.  *        and as complicated as  foo-bar+12,
  166.  *         foo and bar may be undefined but suffixed by :{b|w|d} to
  167.  *        control the length of the object.
  168.  *
  169.  *     3,    the entry is a pointer at a bignum struct
  170.  *
  171.  *
  172.  * The low-order-byte coresponds to low physical memory.
  173.  * Obviously a FRAGment must be created for each valid disp in PART whose
  174.  * datalength is undefined (to bad) .
  175.  * The case where just the expression is undefined is less severe and is
  176.  * handled by fix. Here the number of bytes in the objectfile is known.
  177.  * With this representation we simplify the assembly and separates the
  178.  * machine dependent/independent parts in a more clean way (said OE)
  179.  */
  180.  
  181. struct ns32k_option opt1[] =        /* restore, exit */
  182. {
  183.   {"r0", 0x80, 0xff},
  184.   {"r1", 0x40, 0xff},
  185.   {"r2", 0x20, 0xff},
  186.   {"r3", 0x10, 0xff},
  187.   {"r4", 0x08, 0xff},
  188.   {"r5", 0x04, 0xff},
  189.   {"r6", 0x02, 0xff},
  190.   {"r7", 0x01, 0xff},
  191.   {0, 0x00, 0xff}
  192. };
  193. struct ns32k_option opt2[] =        /* save, enter */
  194. {
  195.   {"r0", 0x01, 0xff},
  196.   {"r1", 0x02, 0xff},
  197.   {"r2", 0x04, 0xff},
  198.   {"r3", 0x08, 0xff},
  199.   {"r4", 0x10, 0xff},
  200.   {"r5", 0x20, 0xff},
  201.   {"r6", 0x40, 0xff},
  202.   {"r7", 0x80, 0xff},
  203.   {0, 0x00, 0xff}
  204. };
  205. struct ns32k_option opt3[] =        /* setcfg */
  206. {
  207.   {"c", 0x8, 0xff},
  208.   {"m", 0x4, 0xff},
  209.   {"f", 0x2, 0xff},
  210.   {"i", 0x1, 0xff},
  211.   {0, 0x0, 0xff}
  212. };
  213. struct ns32k_option opt4[] =        /* cinv */
  214. {
  215.   {"a", 0x4, 0xff},
  216.   {"i", 0x2, 0xff},
  217.   {"d", 0x1, 0xff},
  218.   {0, 0x0, 0xff}
  219. };
  220. struct ns32k_option opt5[] =        /* string inst */
  221. {
  222.   {"b", 0x2, 0xff},
  223.   {"u", 0xc, 0xff},
  224.   {"w", 0x4, 0xff},
  225.   {0, 0x0, 0xff}
  226. };
  227. struct ns32k_option opt6[] =        /* plain reg ext,cvtp etc */
  228. {
  229.   {"r0", 0x00, 0xff},
  230.   {"r1", 0x01, 0xff},
  231.   {"r2", 0x02, 0xff},
  232.   {"r3", 0x03, 0xff},
  233.   {"r4", 0x04, 0xff},
  234.   {"r5", 0x05, 0xff},
  235.   {"r6", 0x06, 0xff},
  236.   {"r7", 0x07, 0xff},
  237.   {0, 0x00, 0xff}
  238. };
  239.  
  240. #if !defined(NS32032) && !defined(NS32532)
  241. #define NS32532
  242. #endif
  243.  
  244. struct ns32k_option cpureg_532[] =    /* lpr spr */
  245. {
  246.   {"us", 0x0, 0xff},
  247.   {"dcr", 0x1, 0xff},
  248.   {"bpc", 0x2, 0xff},
  249.   {"dsr", 0x3, 0xff},
  250.   {"car", 0x4, 0xff},
  251.   {"fp", 0x8, 0xff},
  252.   {"sp", 0x9, 0xff},
  253.   {"sb", 0xa, 0xff},
  254.   {"usp", 0xb, 0xff},
  255.   {"cfg", 0xc, 0xff},
  256.   {"psr", 0xd, 0xff},
  257.   {"intbase", 0xe, 0xff},
  258.   {"mod", 0xf, 0xff},
  259.   {0, 0x00, 0xff}
  260. };
  261. struct ns32k_option mmureg_532[] =    /* lmr smr */
  262. {
  263.   {"mcr", 0x9, 0xff},
  264.   {"msr", 0xa, 0xff},
  265.   {"tear", 0xb, 0xff},
  266.   {"ptb0", 0xc, 0xff},
  267.   {"ptb1", 0xd, 0xff},
  268.   {"ivar0", 0xe, 0xff},
  269.   {"ivar1", 0xf, 0xff},
  270.   {0, 0x0, 0xff}
  271. };
  272.  
  273. struct ns32k_option cpureg_032[] =    /* lpr spr */
  274. {
  275.   {"upsr", 0x0, 0xff},
  276.   {"fp", 0x8, 0xff},
  277.   {"sp", 0x9, 0xff},
  278.   {"sb", 0xa, 0xff},
  279.   {"psr", 0xd, 0xff},
  280.   {"intbase", 0xe, 0xff},
  281.   {"mod", 0xf, 0xff},
  282.   {0, 0x0, 0xff}
  283. };
  284. struct ns32k_option mmureg_032[] =    /* lmr smr */
  285. {
  286.   {"bpr0", 0x0, 0xff},
  287.   {"bpr1", 0x1, 0xff},
  288.   {"pf0", 0x4, 0xff},
  289.   {"pf1", 0x5, 0xff},
  290.   {"sc", 0x8, 0xff},
  291.   {"msr", 0xa, 0xff},
  292.   {"bcnt", 0xb, 0xff},
  293.   {"ptb0", 0xc, 0xff},
  294.   {"ptb1", 0xd, 0xff},
  295.   {"eia", 0xf, 0xff},
  296.   {0, 0x0, 0xff}
  297. };
  298.  
  299. #if defined(NS32532)
  300. struct ns32k_option *cpureg = cpureg_532;
  301. struct ns32k_option *mmureg = mmureg_532;
  302. #else
  303. struct ns32k_option *cpureg = cpureg_032;
  304. struct ns32k_option *mmureg = mmureg_032;
  305. #endif
  306.  
  307.  
  308. const pseudo_typeS md_pseudo_table[] =
  309. {                /* so far empty */
  310.   {0, 0, 0}
  311. };
  312.  
  313. #define IND(x,y)    (((x)<<2)+(y))
  314.  
  315. /* those are index's to relax groups in md_relax_table
  316.    ie it must be multiplied by 4 to point at a group start. Viz IND(x,y)
  317.    Se function relax_segment in write.c for more info */
  318.  
  319. #define BRANCH        1
  320. #define PCREL        2
  321.  
  322. /* those are index's to entries in a relax group */
  323.  
  324. #define BYTE        0
  325. #define WORD        1
  326. #define DOUBLE        2
  327. #define UNDEF           3
  328. /* Those limits are calculated from the displacement start in memory.
  329.    The ns32k uses the begining of the instruction as displacement base.
  330.    This type of displacements could be handled here by moving the limit window
  331.    up or down. I choose to use an internal displacement base-adjust as there
  332.    are other routines that must consider this. Also, as we have two various
  333.    offset-adjusts in the ns32k (acb versus br/brs/jsr/bcond), two set of limits
  334.    would have had to be used.
  335.    Now we dont have to think about that. */
  336.  
  337.  
  338. const relax_typeS md_relax_table[] =
  339. {
  340.   {1, 1, 0, 0},
  341.   {1, 1, 0, 0},
  342.   {1, 1, 0, 0},
  343.   {1, 1, 0, 0},
  344.  
  345.   {(63), (-64), 1, IND (BRANCH, WORD)},
  346.   {(8192), (-8192), 2, IND (BRANCH, DOUBLE)},
  347.   {0, 0, 4, 0},
  348.   {1, 1, 0, 0}
  349. };
  350.  
  351. /* Array used to test if mode contains displacements.
  352.    Value is true if mode contains displacement. */
  353.  
  354. char disp_test[] =
  355. {0, 0, 0, 0, 0, 0, 0, 0,
  356.  1, 1, 1, 1, 1, 1, 1, 1,
  357.  1, 1, 1, 0, 0, 1, 1, 0,
  358.  1, 1, 1, 1, 1, 1, 1, 1};
  359.  
  360. /* Array used to calculate max size of displacements */
  361.  
  362. char disp_size[] =
  363. {4, 1, 2, 0, 4};
  364.  
  365. static void evaluate_expr PARAMS ((expressionS * resultP, char *ptr));
  366. static void md_number_to_disp PARAMS ((char *buf, long val, int n));
  367. static void md_number_to_imm PARAMS ((char *buf, long val, int n));
  368.  
  369. /* Parses a general operand into an addressingmode struct
  370.  
  371.    in:  pointer at operand in ascii form
  372.    pointer at addr_mode struct for result
  373.    the level of recursion. (always 0 or 1)
  374.  
  375.    out: data in addr_mode struct
  376.    */
  377. int
  378. addr_mode (operand, addr_modeP, recursive_level)
  379.      char *operand;
  380.      register addr_modeS *addr_modeP;
  381.      int recursive_level;
  382. {
  383.   register char *str;
  384.   register int i;
  385.   register int strl;
  386.   register int mode;
  387.   int j;
  388.   mode = DEFAULT;        /* default */
  389.   addr_modeP->scaled_mode = 0;    /* why not */
  390.   addr_modeP->scaled_reg = 0;    /* if 0, not scaled index */
  391.   addr_modeP->float_flag = 0;
  392.   addr_modeP->am_size = 0;
  393.   addr_modeP->im_disp = 0;
  394.   addr_modeP->pcrel = 0;    /* not set in this function */
  395.   addr_modeP->disp_suffix[0] = 0;
  396.   addr_modeP->disp_suffix[1] = 0;
  397.   addr_modeP->disp[0] = NULL;
  398.   addr_modeP->disp[1] = NULL;
  399.   str = operand;
  400.   if (str[0] == 0)
  401.     {
  402.       return (0);
  403.     }                /* we don't want this */
  404.   strl = strlen (str);
  405.   switch (str[0])
  406.     {
  407.       /* the following three case statements controls the mode-chars
  408.            this is the place to ed if you want to change them */
  409. #ifdef ABSOLUTE_PREFIX
  410.     case ABSOLUTE_PREFIX:
  411.       if (str[strl - 1] == ']')
  412.     break;
  413.       addr_modeP->mode = 21;    /* absolute */
  414.       addr_modeP->disp[0] = str + 1;
  415.       return (-1);
  416. #endif
  417. #ifdef IMMEDIATE_PREFIX
  418.     case IMMEDIATE_PREFIX:
  419.       if (str[strl - 1] == ']')
  420.     break;
  421.       addr_modeP->mode = 20;    /* immediate */
  422.       addr_modeP->disp[0] = str + 1;
  423.       return (-1);
  424. #endif
  425.     case '.':
  426.       if (str[strl - 1] != ']')
  427.     {
  428.       switch (str[1])
  429.         {
  430.         case '-':
  431.         case '+':
  432.           if (str[2] != '\000')
  433.         {
  434.           addr_modeP->mode = 27;    /* pc-relativ */
  435.           addr_modeP->disp[0] = str + 2;
  436.           return (-1);
  437.         }
  438.         default:
  439.           as_warn ("Invalid syntax in PC-relative addressing mode");
  440.           return (0);
  441.         }
  442.     }
  443.       break;
  444.     case 'e':
  445.       if (str[strl - 1] != ']')
  446.     {
  447.       if ((!strncmp (str, "ext(", 4)) && strl > 7)
  448.         {            /* external */
  449.           addr_modeP->disp[0] = str + 4;
  450.           i = 0;
  451.           j = 2;
  452.           do
  453.         {        /* disp[0]'s termination point */
  454.           j += 1;
  455.           if (str[j] == '(')
  456.             i++;
  457.           if (str[j] == ')')
  458.             i--;
  459.         }
  460.           while (j < strl && i != 0);
  461.           if (i != 0 || !(str[j + 1] == '-' || str[j + 1] == '+'))
  462.         {
  463.           as_warn ("Invalid syntax in External addressing mode");
  464.           return (0);
  465.         }
  466.           str[j] = '\000';    /* null terminate disp[0] */
  467.           addr_modeP->disp[1] = str + j + 2;
  468.           addr_modeP->mode = 22;
  469.           return (-1);
  470.         }
  471.     }
  472.       break;
  473.     default:;
  474.     }
  475.   strl = strlen (str);
  476.   switch (strl)
  477.     {
  478.     case 2:
  479.       switch (str[0])
  480.     {
  481.     case 'f':
  482.       addr_modeP->float_flag = 1;
  483.     case 'r':
  484.       if (str[1] >= '0' && str[1] < '8')
  485.         {
  486.           addr_modeP->mode = str[1] - '0';
  487.           return (-1);
  488.         }
  489.     }
  490.     case 3:
  491.       if (!strncmp (str, "tos", 3))
  492.     {
  493.       addr_modeP->mode = 23;/* TopOfStack */
  494.       return (-1);
  495.     }
  496.     default:;
  497.     }
  498.   if (strl > 4)
  499.     {
  500.       if (str[strl - 1] == ')')
  501.     {
  502.       if (str[strl - 2] == ')')
  503.         {
  504.           if (!strncmp (&str[strl - 5], "(fp", 3))
  505.         {
  506.           mode = 16;    /* Memory Relative */
  507.         }
  508.           if (!strncmp (&str[strl - 5], "(sp", 3))
  509.         {
  510.           mode = 17;
  511.         }
  512.           if (!strncmp (&str[strl - 5], "(sb", 3))
  513.         {
  514.           mode = 18;
  515.         }
  516.           if (mode != DEFAULT)
  517.         {        /* memory relative */
  518.           addr_modeP->mode = mode;
  519.           j = strl - 5;    /* temp for end of disp[0] */
  520.           i = 0;
  521.           do
  522.             {
  523.               strl -= 1;
  524.               if (str[strl] == ')')
  525.             i++;
  526.               if (str[strl] == '(')
  527.             i--;
  528.             }
  529.           while (strl > -1 && i != 0);
  530.           if (i != 0)
  531.             {
  532.               as_warn ("Invalid syntax in Memory Relative addressing mode");
  533.               return (0);
  534.             }
  535.           addr_modeP->disp[1] = str;
  536.           addr_modeP->disp[0] = str + strl + 1;
  537.           str[j] = '\000';    /* null terminate disp[0] */
  538.           str[strl] = '\000';    /* null terminate disp[1] */
  539.           return (-1);
  540.         }
  541.         }
  542.       switch (str[strl - 3])
  543.         {
  544.         case 'r':
  545.         case 'R':
  546.           if (str[strl - 2] >= '0' && str[strl - 2] < '8' && str[strl - 4] == '(')
  547.         {
  548.           addr_modeP->mode = str[strl - 2] - '0' + 8;
  549.           addr_modeP->disp[0] = str;
  550.           str[strl - 4] = 0;
  551.           return (-1);    /* reg rel */
  552.         }
  553.         default:
  554.           if (!strncmp (&str[strl - 4], "(fp", 3))
  555.         {
  556.           mode = 24;
  557.         }
  558.           if (!strncmp (&str[strl - 4], "(sp", 3))
  559.         {
  560.           mode = 25;
  561.         }
  562.           if (!strncmp (&str[strl - 4], "(sb", 3))
  563.         {
  564.           mode = 26;
  565.         }
  566.           if (!strncmp (&str[strl - 4], "(pc", 3))
  567.         {
  568.           mode = 27;
  569.         }
  570.           if (mode != DEFAULT)
  571.         {
  572.           addr_modeP->mode = mode;
  573.           addr_modeP->disp[0] = str;
  574.           str[strl - 4] = '\0';
  575.           return (-1);    /* memory space */
  576.         }
  577.         }
  578.     }
  579.       /* no trailing ')' do we have a ']' ? */
  580.       if (str[strl - 1] == ']')
  581.     {
  582.       switch (str[strl - 2])
  583.         {
  584.         case 'b':
  585.           mode = 28;
  586.           break;
  587.         case 'w':
  588.           mode = 29;
  589.           break;
  590.         case 'd':
  591.           mode = 30;
  592.           break;
  593.         case 'q':
  594.           mode = 31;
  595.           break;
  596.         default:;
  597.           as_warn ("Invalid scaled-indexed mode, use (b,w,d,q)");
  598.           if (str[strl - 3] != ':' || str[strl - 6] != '[' ||
  599.           str[strl - 5] == 'r' || str[strl - 4] < '0' || str[strl - 4] > '7')
  600.         {
  601.           as_warn ("Syntax in scaled-indexed mode, use [Rn:m] where n=[0..7] m={b,w,d,q}");
  602.         }
  603.         }            /* scaled index */
  604.       {
  605.         if (recursive_level > 0)
  606.           {
  607.         as_warn ("Scaled-indexed addressing mode combined with scaled-index");
  608.         return (0);
  609.           }
  610.         addr_modeP->am_size += 1;    /* scaled index byte */
  611.         j = str[strl - 4] - '0';    /* store temporary */
  612.         str[strl - 6] = '\000';    /* nullterminate for recursive call */
  613.         i = addr_mode (str, addr_modeP, 1);
  614.         if (!i || addr_modeP->mode == 20)
  615.           {
  616.         as_warn ("Invalid or illegal addressing mode combined with scaled-index");
  617.         return (0);
  618.           }
  619.         addr_modeP->scaled_mode = addr_modeP->mode;    /* store the inferior mode */
  620.         addr_modeP->mode = mode;
  621.         addr_modeP->scaled_reg = j + 1;
  622.         return (-1);
  623.       }
  624.     }
  625.     }
  626.   addr_modeP->mode = DEFAULT;    /* default to whatever */
  627.   addr_modeP->disp[0] = str;
  628.   return (-1);
  629. }
  630.  
  631. /* ptr points at string
  632.    addr_modeP points at struct with result
  633.    This routine calls addr_mode to determine the general addr.mode of
  634.    the operand. When this is ready it parses the displacements for size
  635.    specifying suffixes and determines size of immediate mode via ns32k-opcode.
  636.    Also builds index bytes if needed.
  637.    */
  638. int
  639. get_addr_mode (ptr, addr_modeP)
  640.      char *ptr;
  641.      addr_modeS *addr_modeP;
  642. {
  643.   int tmp;
  644.   addr_mode (ptr, addr_modeP, 0);
  645.   if (addr_modeP->mode == DEFAULT || addr_modeP->scaled_mode == -1)
  646.     {
  647.       /* resolve ambigious operands, this shouldn't
  648.      be necessary if one uses standard NSC operand
  649.      syntax. But the sequent compiler doesn't!!!
  650.      This finds a proper addressinging mode if it
  651.      is implicitly stated. See ns32k-opcode.h */
  652.       (void) evaluate_expr (&exprP, ptr);    /* this call takes time Sigh! */
  653.       if (addr_modeP->mode == DEFAULT)
  654.     {
  655.       if (exprP.X_add_symbol || exprP.X_op_symbol)
  656.         {
  657.           addr_modeP->mode = desc->default_model;    /* we have a label */
  658.         }
  659.       else
  660.         {
  661.           addr_modeP->mode = desc->default_modec;    /* we have a constant */
  662.         }
  663.     }
  664.       else
  665.     {
  666.       if (exprP.X_add_symbol || exprP.X_op_symbol)
  667.         {
  668.           addr_modeP->scaled_mode = desc->default_model;
  669.         }
  670.       else
  671.         {
  672.           addr_modeP->scaled_mode = desc->default_modec;
  673.         }
  674.     }
  675.       /* must put this mess down in addr_mode to handle the scaled case better */
  676.     }
  677.   /* It appears as the sequent compiler wants an absolute when we have a
  678.        label without @. Constants becomes immediates besides the addr case.
  679.        Think it does so with local labels too, not optimum, pcrel is better.
  680.        When I have time I will make gas check this and select pcrel when possible
  681.        Actually that is trivial.
  682.        */
  683.   if (tmp = addr_modeP->scaled_reg)
  684.     {                /* build indexbyte */
  685.       tmp--;            /* remember regnumber comes incremented for flagpurpose */
  686.       tmp |= addr_modeP->scaled_mode << 3;
  687.       addr_modeP->index_byte = (char) tmp;
  688.       addr_modeP->am_size += 1;
  689.     }
  690.   if (disp_test[addr_modeP->mode])
  691.     {                /* there was a displacement, probe for length specifying suffix*/
  692.       {
  693.     register char c;
  694.     register char suffix;
  695.     register char suffix_sub;
  696.     register int i;
  697.     register char *toP;
  698.     register char *fromP;
  699.  
  700.     addr_modeP->pcrel = 0;
  701.     if (disp_test[addr_modeP->mode])
  702.       {            /* there is a displacement */
  703.         if (addr_modeP->mode == 27 || addr_modeP->scaled_mode == 27)
  704.           {            /* do we have pcrel. mode */
  705.         addr_modeP->pcrel = 1;
  706.           }
  707.         addr_modeP->im_disp = 1;
  708.         for (i = 0; i < 2; i++)
  709.           {
  710.         suffix_sub = suffix = 0;
  711.         if (toP = addr_modeP->disp[i])
  712.           {        /* suffix of expression, the largest size rules */
  713.             fromP = toP;
  714.             while (c = *fromP++)
  715.               {
  716.             *toP++ = c;
  717.             if (c == ':')
  718.               {
  719.                 switch (*fromP)
  720.                   {
  721.                   case '\0':
  722.                 as_warn ("Premature end of suffix--Defaulting to d");
  723.                 suffix = 4;
  724.                 continue;
  725.                   case 'b':
  726.                 suffix_sub = 1;
  727.                 break;
  728.                   case 'w':
  729.                 suffix_sub = 2;
  730.                 break;
  731.                   case 'd':
  732.                 suffix_sub = 4;
  733.                 break;
  734.                   default:
  735.                 as_warn ("Bad suffix after ':' use {b|w|d} Defaulting to d");
  736.                 suffix = 4;
  737.                   }
  738.                 fromP++;
  739.                 toP--;    /* So we write over the ':' */
  740.                 if (suffix < suffix_sub)
  741.                   suffix = suffix_sub;
  742.               }
  743.               }
  744.             *toP = '\0';/* terminate properly */
  745.             addr_modeP->disp_suffix[i] = suffix;
  746.             addr_modeP->am_size += suffix ? suffix : 4;
  747.           }
  748.           }
  749.       }
  750.       }
  751.     }
  752.   else
  753.     {
  754.       if (addr_modeP->mode == 20)
  755.     {            /* look in ns32k_opcode for size */
  756.       addr_modeP->disp_suffix[0] = addr_modeP->am_size = desc->im_size;
  757.       addr_modeP->im_disp = 0;
  758.     }
  759.     }
  760.   return addr_modeP->mode;
  761. }
  762.  
  763.  
  764. /* read an optionlist */
  765. void
  766. optlist (str, optionP, default_map)
  767.      char *str;            /* the string to extract options from */
  768.      struct ns32k_option *optionP;    /* how to search the string */
  769.      unsigned long *default_map;/* default pattern and output */
  770. {
  771.   register int i, j, k, strlen1, strlen2;
  772.   register char *patternP, *strP;
  773.   strlen1 = strlen (str);
  774.   if (strlen1 < 1)
  775.     {
  776.       as_fatal ("Very short instr to option, ie you can't do it on a NULLstr");
  777.     }
  778.   for (i = 0; optionP[i].pattern != 0; i++)
  779.     {
  780.       strlen2 = strlen (optionP[i].pattern);
  781.       for (j = 0; j < strlen1; j++)
  782.     {
  783.       patternP = optionP[i].pattern;
  784.       strP = &str[j];
  785.       for (k = 0; k < strlen2; k++)
  786.         {
  787.           if (*(strP++) != *(patternP++))
  788.         break;
  789.         }
  790.       if (k == strlen2)
  791.         {            /* match */
  792.           *default_map |= optionP[i].or;
  793.           *default_map &= optionP[i].and;
  794.         }
  795.     }
  796.     }
  797. }
  798.  
  799. /* search struct for symbols
  800.    This function is used to get the short integer form of reg names
  801.    in the instructions lmr, smr, lpr, spr
  802.    return true if str is found in list */
  803.  
  804. int
  805. list_search (str, optionP, default_map)
  806.      char *str;            /* the string to match */
  807.      struct ns32k_option *optionP;    /* list to search */
  808.      unsigned long *default_map;/* default pattern and output */
  809. {
  810.   register int i;
  811.   for (i = 0; optionP[i].pattern != 0; i++)
  812.     {
  813.       if (!strncmp (optionP[i].pattern, str, 20))
  814.     {            /* use strncmp to be safe */
  815.       *default_map |= optionP[i].or;
  816.       *default_map &= optionP[i].and;
  817.       return -1;
  818.     }
  819.     }
  820.   as_warn ("No such entry in list. (cpu/mmu register)");
  821.   return 0;
  822. }
  823.  
  824. static void
  825. evaluate_expr (resultP, ptr)
  826.      expressionS *resultP;
  827.      char *ptr;
  828. {
  829.   register char *tmp_line;
  830.  
  831.   tmp_line = input_line_pointer;
  832.   input_line_pointer = ptr;
  833.   expression (&exprP);
  834.   input_line_pointer = tmp_line;
  835. }
  836.  
  837. /* Convert operands to iif-format and adds bitfields to the opcode.
  838.    Operands are parsed in such an order that the opcode is updated from
  839.    its most significant bit, that is when the operand need to alter the
  840.    opcode.
  841.    Be carefull not to put to objects in the same iif-slot.
  842.    */
  843.  
  844. void
  845. encode_operand (argc, argv, operandsP, suffixP, im_size, opcode_bit_ptr)
  846.      int argc;
  847.      char **argv;
  848.      char *operandsP;
  849.      char *suffixP;
  850.      char im_size;
  851.      char opcode_bit_ptr;
  852. {
  853.   register int i, j;
  854.   char d;
  855.   int pcrel, tmp, b, loop, pcrel_adjust;
  856.   for (loop = 0; loop < argc; loop++)
  857.     {
  858.       i = operandsP[loop << 1] - '1';    /* what operand are we supposed to work on */
  859.       if (i > 3)
  860.     as_fatal ("Internal consistency error.  check ns32k-opcode.h");
  861.       pcrel = 0;
  862.       pcrel_adjust = 0;
  863.       tmp = 0;
  864.       switch ((d = operandsP[(loop << 1) + 1]))
  865.     {
  866.     case 'f':        /* operand of sfsr turns out to be a nasty specialcase */
  867.       opcode_bit_ptr -= 5;
  868.     case 'Z':        /* float not immediate */
  869.     case 'F':        /* 32 bit float    general form */
  870.     case 'L':        /* 64 bit float    */
  871.     case 'I':        /* integer not immediate */
  872.     case 'B':        /* byte     */
  873.     case 'W':        /* word     */
  874.     case 'D':        /* double-word    */
  875.     case 'A':        /* double-word    gen-address-form ie no regs allowed */
  876.       get_addr_mode (argv[i], &addr_modeP);
  877.       if((addr_modeP.mode == 20) &&
  878.          (d == 'I' || d == 'Z' || d == 'A')) {
  879.         as_fatal(d == 'A'? "Address of immediate operand":
  880.              "Invalid immediate write operand.");
  881.       }
  882.       iif.instr_size += addr_modeP.am_size;
  883.       if (opcode_bit_ptr == desc->opcode_size)
  884.         b = 4;
  885.       else
  886.         b = 6;
  887.       for (j = b; j < (b + 2); j++)
  888.         {
  889.           if (addr_modeP.disp[j - b])
  890.         {
  891.           IIF (j,
  892.                2,
  893.                addr_modeP.disp_suffix[j - b],
  894.                (unsigned long) addr_modeP.disp[j - b],
  895.                0,
  896.                addr_modeP.pcrel,
  897.                iif.instr_size - addr_modeP.am_size,    /* this aint used (now) */
  898.                addr_modeP.im_disp,
  899.                IND (BRANCH, BYTE),
  900.                NULL,
  901.                addr_modeP.scaled_reg ? addr_modeP.scaled_mode : addr_modeP.mode,
  902.                0);
  903.         }
  904.         }
  905.       opcode_bit_ptr -= 5;
  906.       iif.iifP[1].object |= ((long) addr_modeP.mode) << opcode_bit_ptr;
  907.       if (addr_modeP.scaled_reg)
  908.         {
  909.           j = b / 2;
  910.           IIF (j, 1, 1, (unsigned long) addr_modeP.index_byte, 0, 0, 0, 0, 0, NULL, -1, 0);
  911.         }
  912.       break;
  913.     case 'b':        /* multiple instruction disp */
  914.       freeptr++;        /* OVE:this is an useful hack */
  915.       sprintf (freeptr, "((%s-1)*%d)\000", argv[i], desc->im_size);
  916.       argv[i] = freeptr;
  917.       pcrel -= 1;        /* make pcrel 0 inspite of what case 'p': wants */
  918.       /* fall thru */
  919.     case 'p':        /* displacement - pc relative addressing */
  920.       pcrel += 1;
  921.       /* fall thru */
  922.     case 'd':        /* displacement */
  923.       iif.instr_size += suffixP[i] ? suffixP[i] : 4;
  924.       IIF (12, 2, suffixP[i], (unsigned long) argv[i], 0,
  925.            pcrel, pcrel_adjust, 1, IND (BRANCH, BYTE), NULL, -1, 0);
  926.       break;
  927.     case 'H':        /* sequent-hack: the linker wants a bit set when bsr */
  928.       pcrel = 1;
  929.       iif.instr_size += suffixP[i] ? suffixP[i] : 4;
  930.       IIF (12, 2, suffixP[i], (unsigned long) argv[i], 0,
  931.            pcrel, pcrel_adjust, 1, IND (BRANCH, BYTE), NULL, -1, 1);
  932.       break;
  933.     case 'q':        /* quick */
  934.       opcode_bit_ptr -= 4;
  935.       IIF (11, 2, 42, (unsigned long) argv[i], 0, 0, 0, 0, 0,
  936.            bit_fix_new (4, opcode_bit_ptr, -8, 7, 0, 1, 0), -1, 0);
  937.       break;
  938.     case 'r':        /* register number (3 bits) */
  939.       list_search (argv[i], opt6, &tmp);
  940.       opcode_bit_ptr -= 3;
  941.       iif.iifP[1].object |= tmp << opcode_bit_ptr;
  942.       break;
  943.     case 'O':        /* setcfg instruction optionslist */
  944.       optlist (argv[i], opt3, &tmp);
  945.       opcode_bit_ptr -= 4;
  946.       iif.iifP[1].object |= tmp << 15;
  947.       break;
  948.     case 'C':        /* cinv instruction optionslist */
  949.       optlist (argv[i], opt4, &tmp);
  950.       opcode_bit_ptr -= 4;
  951.       iif.iifP[1].object |= tmp << 15;    /*insert the regtype in opcode */
  952.       break;
  953.     case 'S':        /* stringinstruction optionslist */
  954.       optlist (argv[i], opt5, &tmp);
  955.       opcode_bit_ptr -= 4;
  956.       iif.iifP[1].object |= tmp << 15;
  957.       break;
  958.     case 'u':
  959.     case 'U':        /* registerlist */
  960.       IIF (10, 1, 1, 0, 0, 0, 0, 0, 0, NULL, -1, 0);
  961.       switch (operandsP[(i << 1) + 1])
  962.         {
  963.         case 'u':        /* restore, exit */
  964.           optlist (argv[i], opt1, &iif.iifP[10].object);
  965.           break;
  966.         case 'U':        /* save,enter */
  967.           optlist (argv[i], opt2, &iif.iifP[10].object);
  968.           break;
  969.         }
  970.       iif.instr_size += 1;
  971.       break;
  972.     case 'M':        /* mmu register */
  973.       list_search (argv[i], mmureg, &tmp);
  974.       opcode_bit_ptr -= 4;
  975.       iif.iifP[1].object |= tmp << opcode_bit_ptr;
  976.       break;
  977.     case 'P':        /* cpu register  */
  978.       list_search (argv[i], cpureg, &tmp);
  979.       opcode_bit_ptr -= 4;
  980.       iif.iifP[1].object |= tmp << opcode_bit_ptr;
  981.       break;
  982.     case 'g':        /* inss exts */
  983.       iif.instr_size += 1;    /* 1 byte is allocated after the opcode */
  984.       IIF (10, 2, 1,
  985.            (unsigned long) argv[i],    /* i always 2 here */
  986.            0, 0, 0, 0, 0,
  987.            bit_fix_new (3, 5, 0, 7, 0, 0, 0),    /* a bit_fix is targeted to the byte */
  988.            -1, 0);
  989.       break;
  990.     case 'G':
  991.       IIF (11, 2, 42,
  992.            (unsigned long) argv[i],    /* i always 3 here */
  993.            0, 0, 0, 0, 0,
  994.            bit_fix_new (5, 0, 1, 32, -1, 0, -1), -1, 0);
  995.       break;
  996.     case 'i':
  997.       iif.instr_size += 1;
  998.       b = 2 + i;        /* put the extension byte after opcode */
  999.       IIF (b, 2, 1, 0, 0, 0, 0, 0, 0, 0, -1, 0);
  1000.       break;
  1001.     default:
  1002.       as_fatal ("Bad opcode-table-option, check in file ns32k-opcode.h");
  1003.     }
  1004.     }
  1005. }
  1006.  
  1007. /* in:  instruction line
  1008.    out: internal structure of instruction
  1009.    that has been prepared for direct conversion to fragment(s) and
  1010.    fixes in a systematical fashion
  1011.    Return-value = recursive_level
  1012.    */
  1013. /* build iif of one assembly text line */
  1014. int
  1015. parse (line, recursive_level)
  1016.      char *line;
  1017.      int recursive_level;
  1018. {
  1019.   register char *lineptr, c, suffix_separator;
  1020.   register int i;
  1021.   int argc, arg_type;
  1022.   char sqr, sep;
  1023.   char suffix[MAX_ARGS], *argv[MAX_ARGS];    /* no more than 4 operands */
  1024.   if (recursive_level <= 0)
  1025.     {                /* called from md_assemble */
  1026.       for (lineptr = line; (*lineptr) != '\0' && (*lineptr) != ' '; lineptr++);
  1027.       c = *lineptr;
  1028.       *lineptr = '\0';
  1029.       if (!(desc = (struct ns32k_opcode *) hash_find (inst_hash_handle, line)))
  1030.     {
  1031.       as_fatal ("No such opcode");
  1032.     }
  1033.       *lineptr = c;
  1034.     }
  1035.   else
  1036.     {
  1037.       lineptr = line;
  1038.     }
  1039.   argc = 0;
  1040.   if (*desc->operands)
  1041.     {
  1042.       if (*lineptr++ != '\0')
  1043.     {
  1044.       sqr = '[';
  1045.       sep = ',';
  1046.       while (*lineptr != '\0')
  1047.         {
  1048.           if (desc->operands[argc << 1])
  1049.         {
  1050.           suffix[argc] = 0;
  1051.           arg_type = desc->operands[(argc << 1) + 1];
  1052.           switch (arg_type)
  1053.             {
  1054.             case 'd':
  1055.             case 'b':
  1056.             case 'p':
  1057.             case 'H':    /* the operand is supposed to be a displacement */
  1058.               /* Hackwarning: do not forget to update the 4 cases above when editing ns32k-opcode.h */
  1059.               suffix_separator = ':';
  1060.               break;
  1061.             default:
  1062.               suffix_separator = '\255';    /* if this char occurs we loose */
  1063.             }
  1064.           suffix[argc] = 0;    /* 0 when no ':' is encountered */
  1065.           argv[argc] = freeptr;
  1066.           *freeptr = '\0';
  1067.           while ((c = *lineptr) != '\0' && c != sep)
  1068.             {
  1069.               if (c == sqr)
  1070.             {
  1071.               if (sqr == '[')
  1072.                 {
  1073.                   sqr = ']';
  1074.                   sep = '\0';
  1075.                 }
  1076.               else
  1077.                 {
  1078.                   sqr = '[';
  1079.                   sep = ',';
  1080.                 }
  1081.             }
  1082.               if (c == suffix_separator)
  1083.             {    /* ':' - label/suffix separator */
  1084.               switch (lineptr[1])
  1085.                 {
  1086.                 case 'b':
  1087.                   suffix[argc] = 1;
  1088.                   break;
  1089.                 case 'w':
  1090.                   suffix[argc] = 2;
  1091.                   break;
  1092.                 case 'd':
  1093.                   suffix[argc] = 4;
  1094.                   break;
  1095.                 default:
  1096.                   as_warn ("Bad suffix, defaulting to d");
  1097.                   suffix[argc] = 4;
  1098.                   if (lineptr[1] == '\0' || lineptr[1] == sep)
  1099.                 {
  1100.                   lineptr += 1;
  1101.                   continue;
  1102.                 }
  1103.                 }
  1104.               lineptr += 2;
  1105.               continue;
  1106.             }
  1107.               *freeptr++ = c;
  1108.               lineptr++;
  1109.             }
  1110.           *freeptr++ = '\0';
  1111.           argc += 1;
  1112.           if (*lineptr == '\0')
  1113.             continue;
  1114.           lineptr += 1;
  1115.         }
  1116.           else
  1117.         {
  1118.           as_fatal ("Too many operands passed to instruction");
  1119.         }
  1120.         }
  1121.     }
  1122.     }
  1123.   if (argc != strlen (desc->operands) / 2)
  1124.     {
  1125.       if (strlen (desc->default_args))
  1126.     {            /* we can apply default, dont goof */
  1127.       if (parse (desc->default_args, 1) != 1)
  1128.         {            /* check error in default */
  1129.           as_fatal ("Wrong numbers of operands in default, check ns32k-opcodes.h");
  1130.         }
  1131.     }
  1132.       else
  1133.     {
  1134.       as_fatal ("Wrong number of operands");
  1135.     }
  1136.  
  1137.     }
  1138.   for (i = 0; i < IIF_ENTRIES; i++)
  1139.     {
  1140.       iif.iifP[i].type = 0;    /* mark all entries as void*/
  1141.     }
  1142.  
  1143.   /* build opcode iif-entry */
  1144.   iif.instr_size = desc->opcode_size / 8;
  1145.   IIF (1, 1, iif.instr_size, desc->opcode_seed, 0, 0, 0, 0, 0, 0, -1, 0);
  1146.  
  1147.   /* this call encodes operands to iif format */
  1148.   if (argc)
  1149.     {
  1150.       encode_operand (argc,
  1151.               argv,
  1152.               &desc->operands[0],
  1153.               &suffix[0],
  1154.               desc->im_size,
  1155.               desc->opcode_size);
  1156.     }
  1157.   return recursive_level;
  1158. }
  1159.  
  1160.  
  1161. /* Convert iif to fragments.  From this point we start to dribble with
  1162.  * functions in other files than this one.(Except hash.c) So, if it's
  1163.  * possible to make an iif for an other CPU, you don't need to know
  1164.  * what frags, relax, obstacks, etc is in order to port this
  1165.  * assembler. You only need to know if it's possible to reduce your
  1166.  * cpu-instruction to iif-format (takes some work) and adopt the other
  1167.  * md_? parts according to given instructions Note that iif was
  1168.  * invented for the clean ns32k`s architecure.
  1169.    */
  1170.  
  1171. /* GAS for the ns32k has a problem. PC relative displacements are relative
  1172.  * to the address of the opcode, not the address of the operand. We can
  1173.  * keep track of the offset between the operand and the opcode in
  1174.  * pcrel_adjust. That is what it is for. However, we get into trouble
  1175.  * where there is two or more pc-relative operands and the size of the
  1176.  * first one can't be determined. Then in the relax phase, the size of the
  1177.  * first operand will change and pcrel_adjust will no longer be correct.
  1178.  * In an earlier attempt to fix this, I added an extra field to frags to
  1179.  * keep track of how much the pcrel_adjust had changed during relax.
  1180.  * That meant cluttering up write.c with (more) ns32k dependent things.
  1181.  * The current solution is to note that operands whose size isn't determined
  1182.  * yet must be in the variable part of a frag. The next operand (if any)]
  1183.  * must be in a new frag. What we need is a way to find out where in what
  1184.  * frag the opcode for this operand is.
  1185.  * What we do is allocate and extra structure and for frags which do not
  1186.  * contain the opcode, use the opcode pointer to point at this new
  1187.  * structure. Requires that a pointer to a struct can be cast to a pointer
  1188.  * to char * without loss.
  1189.  */
  1190. struct opcode_location {
  1191.   fragS *fragP;
  1192.   unsigned int offset;
  1193. };
  1194.  
  1195. void
  1196. convert_iif ()
  1197. {
  1198.   int i;
  1199.   bit_fixS *j;
  1200.   fragS *inst_frag;
  1201.   unsigned int inst_offset;
  1202.   char *inst_opcode;
  1203.   struct opcode_location *opcode_location;
  1204.   fragS *opcode_frag;
  1205.   char *memP;
  1206.   int l;
  1207.   int k;
  1208.   int rem_size;            /* count the remaining bytes of instruction */
  1209.   char type;
  1210.   char size = 0;
  1211.   int size_so_far = 0;        /* used to calculate pcrel_adjust */
  1212.   char first = 1;        /* true until after the first frag of this
  1213.                   * instruction has been done
  1214.                   */
  1215.  
  1216.   rem_size = iif.instr_size;
  1217.   memP = frag_more (iif.instr_size);    /* make sure we have enough bytes for instruction */
  1218.   inst_opcode = memP;
  1219.   inst_offset = (memP - frag_now->fr_literal);
  1220.   inst_frag = frag_now;
  1221.  
  1222.   for (i = 0; i < IIF_ENTRIES; i++)
  1223.     {
  1224.       if (type = iif.iifP[i].type)
  1225.     {            /* the object exist, so handle it */
  1226.       switch (size = iif.iifP[i].size)
  1227.         {
  1228.         case 42:
  1229.           size = 0;        /* it's a bitfix that operates on an existing object*/
  1230.           if (iif.iifP[i].bit_fixP->fx_bit_base)
  1231.         {        /* expand fx_bit_base to point at opcode */
  1232.           iif.iifP[i].bit_fixP->fx_bit_base = (long) inst_opcode;
  1233.         }
  1234.         case 8:        /* bignum or doublefloat */
  1235.           memset (memP, '\0', size);
  1236.         case 1:
  1237.         case 2:
  1238.         case 3:
  1239.         case 4:        /* the final size in objectmemory is known */
  1240.           j = iif.iifP[i].bit_fixP;
  1241.           switch (type)
  1242.         {
  1243.         case 1:    /* the object is pure binary */
  1244.           if (j || iif.iifP[i].pcrel)
  1245.             {
  1246.               fix_new_ns32k (frag_now,
  1247.                      (long) (memP - frag_now->fr_literal),
  1248.                      size,
  1249.                      0,
  1250.                      iif.iifP[i].object,
  1251.                      iif.iifP[i].pcrel,
  1252.                      (char) (first? size_so_far: 0),    /*iif.iifP[i].pcrel_adjust,*/
  1253.                      iif.iifP[i].im_disp,
  1254.                      j,
  1255.                      iif.iifP[i].bsr);    /* sequent hack */
  1256.             }
  1257.           else
  1258.             {        /* good, just put them bytes out */
  1259.               switch (iif.iifP[i].im_disp)
  1260.             {
  1261.             case 0:
  1262.               md_number_to_chars (memP, iif.iifP[i].object, size);
  1263.               break;
  1264.             case 1:
  1265.               md_number_to_disp (memP, iif.iifP[i].object, size);
  1266.               break;
  1267.             default:
  1268.               as_fatal ("iif convert internal pcrel/binary");
  1269.             }
  1270.             }
  1271.           memP += size;
  1272.           rem_size -= size;
  1273.           break;
  1274.         case 2:    /* the object is a pointer at an expression, so unpack
  1275.                        it, note that bignums may result from the expression
  1276.                        */
  1277.           evaluate_expr (&exprP, (char *) iif.iifP[i].object);
  1278.           if (exprP.X_op == O_big || size == 8)
  1279.             {
  1280.               if ((k = exprP.X_add_number) > 0)
  1281.             {    /* we have a bignum ie a quad */
  1282.               /* this can only happens in a long suffixed instruction */
  1283.               memset (memP, '\0', size);    /* size normally is 8 */
  1284.               if (k * 2 > size)
  1285.                 as_warn ("Bignum too big for long");
  1286.               if (k == 3)
  1287.                 memP += 2;
  1288.               for (l = 0; k > 0; k--, l += 2)
  1289.                 {
  1290.                   md_number_to_chars (memP + l, generic_bignum[l >> 1], sizeof (LITTLENUM_TYPE));
  1291.                 }
  1292.             }
  1293.               else
  1294.             {    /* flonum */
  1295.               LITTLENUM_TYPE words[4];
  1296.  
  1297.               switch (size)
  1298.                 {
  1299.                 case 4:
  1300.                   gen_to_words (words, 2, 8);
  1301.                   md_number_to_imm (memP, (long) words[0], sizeof (LITTLENUM_TYPE));
  1302.                   md_number_to_imm (memP + sizeof (LITTLENUM_TYPE), (long) words[1], sizeof (LITTLENUM_TYPE));
  1303.                   break;
  1304.                 case 8:
  1305.                   gen_to_words (words, 4, 11);
  1306.                   md_number_to_imm (memP, (long) words[0], sizeof (LITTLENUM_TYPE));
  1307.                   md_number_to_imm (memP + sizeof (LITTLENUM_TYPE), (long) words[1], sizeof (LITTLENUM_TYPE));
  1308.                   md_number_to_imm (memP + 2 * sizeof (LITTLENUM_TYPE), (long) words[2], sizeof (LITTLENUM_TYPE));
  1309.                   md_number_to_imm (memP + 3 * sizeof (LITTLENUM_TYPE), (long) words[3], sizeof (LITTLENUM_TYPE));
  1310.                   break;
  1311.                 }
  1312.             }
  1313.               memP += size;
  1314.               rem_size -= size;
  1315.               break;
  1316.             }
  1317.           if (j ||
  1318.               exprP.X_add_symbol ||
  1319.               exprP.X_op_symbol ||
  1320.               iif.iifP[i].pcrel)
  1321.             {        /* fixit */
  1322.               /* the expression was undefined due to an undefined label */
  1323.               /* create a fix so we can fix the object later */
  1324.               exprP.X_add_number += iif.iifP[i].object_adjust;
  1325.               fix_new_ns32k_exp (frag_now,
  1326.                      (long) (memP - frag_now->fr_literal),
  1327.                      size,
  1328.                      &exprP,
  1329.                      iif.iifP[i].pcrel,
  1330.                      (char) (first? size_so_far: 0),    /*iif.iifP[i].pcrel_adjust,*/
  1331.                      iif.iifP[i].im_disp,
  1332.                      j,
  1333.                      iif.iifP[i].bsr);    /* sequent hack */
  1334.  
  1335.             }
  1336.           else
  1337.             {        /* good, just put them bytes out */
  1338.               switch (iif.iifP[i].im_disp)
  1339.             {
  1340.             case 0:
  1341.               md_number_to_imm (memP, exprP.X_add_number, size);
  1342.               break;
  1343.             case 1:
  1344.               md_number_to_disp (memP, exprP.X_add_number, size);
  1345.               break;
  1346.             default:
  1347.               as_fatal ("iif convert internal pcrel/pointer");
  1348.             }
  1349.             }
  1350.           memP += size;
  1351.           rem_size -= size;
  1352.           break;
  1353.         default:
  1354.           as_fatal ("Internal logic error in iif.iifP[n].type");
  1355.         }
  1356.           break;
  1357.         case 0: /* To bad, the object may be undefined as far as
  1358.              * its final nsize in object memory is concerned.
  1359.              * The size of the object in objectmemory is not
  1360.              * explicitly given.  If the object is defined its
  1361.              * length can be determined and a fix can replace
  1362.              * the frag.
  1363.                         */
  1364.           {
  1365.         int temp;
  1366.         evaluate_expr (&exprP, (char *) iif.iifP[i].object);
  1367.         if ((exprP.X_add_symbol || exprP.X_op_symbol) &&
  1368.             !iif.iifP[i].pcrel)
  1369.           {        /* OVE: hack, clamp to 4 bytes */
  1370.             size = 4;    /* we dont wan't to frag this, use 4 so it reaches */
  1371.             fix_new_ns32k_exp (frag_now,
  1372.                        (long) (memP - frag_now->fr_literal),
  1373.                        size,
  1374.                        &exprP,
  1375.                        0,    /* never iif.iifP[i].pcrel, */
  1376.                        (char) (first? size_so_far: 0),    /*iif.iifP[i].pcrel_adjust,*/
  1377.                        1,    /* always iif.iifP[i].im_disp, */
  1378.                        (bit_fixS *) 0, 0);
  1379.             memP += size;
  1380.             rem_size -= 4;
  1381.             break;    /* exit this absolute hack */
  1382.           }
  1383.  
  1384.         if (exprP.X_add_symbol || exprP.X_op_symbol)
  1385.           {        /* frag it */
  1386.             if (exprP.X_op_symbol)
  1387.               {        /* We cant relax this case */
  1388.             as_fatal ("Can't relax difference");
  1389.               }
  1390.             else
  1391.               {
  1392.  
  1393.             /* at this stage we must undo some of the
  1394.              * effect caused by frag_more, ie we must make
  1395.              * sure that frag_var causes frag_new to creat
  1396.              * a valid fix-size in the frag it`s closing
  1397.              * * we rewind none, some or all of the
  1398.              * requested size we requested by the first
  1399.              * frag_more for this iif chunk.  Note: that
  1400.              * we allocate 4 bytes to an object we NOT YET
  1401.              * know the size of, thus rem_size-4.
  1402.                                */
  1403.  
  1404.             /* Size is not important. This gets fixed by relax,
  1405.              * but we assume 0 in what follows
  1406.              */
  1407.             size = 0;
  1408.  
  1409.             temp = -(rem_size - 4);
  1410.             frag_grow (temp);
  1411.  
  1412.             {
  1413.               fragS *old_frag = frag_now;
  1414.               frag_variant (rs_machine_dependent,
  1415.                     4,
  1416.                     0, /* size */
  1417.                     IND (BRANCH, UNDEF), /* expecting the worst */
  1418.                     exprP.X_add_symbol,
  1419.                     exprP.X_add_number,
  1420.                     (first
  1421.                      ? inst_opcode
  1422.                      : (char *) opcode_location));
  1423.               if (first)
  1424.                 old_frag->fr_pcrel_adjust = (char) size_so_far;
  1425.               old_frag->fr_bsr = iif.iifP[i].bsr;
  1426.             }
  1427.  
  1428.             if (first) {
  1429.               /* The opcode is really in the last frag.
  1430.                * overload the inst_opcode pointer.
  1431.                */
  1432.               opcode_location
  1433.                 = (struct opcode_location *) obstack_alloc(¬es, sizeof(struct opcode_location));
  1434.               opcode_location->fragP = inst_frag;
  1435.               opcode_location->offset = inst_offset;
  1436.  
  1437.               first = 0;
  1438.             }
  1439.  
  1440.             rem_size -= 4;
  1441.             if (rem_size > 0)
  1442.               {
  1443.                 memP = frag_more (rem_size);
  1444.               }
  1445.               }
  1446.           }
  1447.         else
  1448.           {        /* Double work, this is done in md_number_to_disp */
  1449.             /*          exprP.X_add_number; what was this supposed to be?
  1450.                                   xoxorich. */
  1451.             if (-64 <= exprP.X_add_number && exprP.X_add_number <= 63)
  1452.               {
  1453.             size = 1;
  1454.               }
  1455.             else
  1456.               {
  1457.             if (-8192 <= exprP.X_add_number && exprP.X_add_number <= 8191)
  1458.               {
  1459.                 size = 2;
  1460.               }
  1461.             else
  1462.               {
  1463.                 if (-0x20000000<=exprP.X_add_number &&
  1464.                 exprP.X_add_number<=0x1fffffff)
  1465.                   {
  1466.                 size = 4;
  1467.                   }
  1468.                 else
  1469.                   {
  1470.                 as_warn ("Displacement to large for :d");
  1471.                 size = 4;
  1472.                   }
  1473.               }
  1474.               }
  1475.             /* rewind the bytes not used */
  1476.             temp = -(4 - size);
  1477.             md_number_to_disp (memP, exprP.X_add_number, size);
  1478.             frag_grow (temp);
  1479.             memP += size;
  1480.             rem_size -= 4;    /* we allocated this amount */
  1481.           }
  1482.           }
  1483.           break;
  1484.         default:
  1485.           as_fatal ("Internal logic error in iif.iifP[].type");
  1486.         }
  1487.       size_so_far += size;
  1488.       size = 0;
  1489.     }
  1490.     }
  1491. }
  1492.  
  1493. #ifdef BFD_ASSEMBLER
  1494. /* This functionality should really be in the bfd library */
  1495. static bfd_reloc_code_real_type
  1496. reloc (int size, int pcrel, int type)
  1497. {
  1498.   int length, index;
  1499.   bfd_reloc_code_real_type relocs[] = {
  1500.     BFD_RELOC_NS32K_IMM_8,
  1501.     BFD_RELOC_NS32K_IMM_16,
  1502.     BFD_RELOC_NS32K_IMM_32,
  1503.     BFD_RELOC_NS32K_IMM_8_PCREL,
  1504.     BFD_RELOC_NS32K_IMM_16_PCREL,
  1505.     BFD_RELOC_NS32K_IMM_32_PCREL,
  1506.  
  1507.     /* ns32k displacements */
  1508.     BFD_RELOC_NS32K_DISP_8,
  1509.     BFD_RELOC_NS32K_DISP_16,
  1510.     BFD_RELOC_NS32K_DISP_32,
  1511.     BFD_RELOC_NS32K_DISP_8_PCREL,
  1512.     BFD_RELOC_NS32K_DISP_16_PCREL,
  1513.     BFD_RELOC_NS32K_DISP_32_PCREL,
  1514.  
  1515.     /* Normal 2's complement */
  1516.     BFD_RELOC_8,
  1517.     BFD_RELOC_16,
  1518.     BFD_RELOC_32,
  1519.     BFD_RELOC_8_PCREL,
  1520.     BFD_RELOC_16_PCREL,
  1521.     BFD_RELOC_32_PCREL
  1522.     };
  1523.   switch (size)
  1524.     {
  1525.     case 1:
  1526.       length = 0;
  1527.       break;
  1528.     case 2:
  1529.       length = 1;
  1530.       break;
  1531.     case 4:
  1532.       length = 2;
  1533.       break;
  1534.     default:
  1535.       length = -1;
  1536.       break;
  1537.     }
  1538.   index = length + 3 * pcrel + 6 * type;
  1539.   if (index >= 0 && index < sizeof(relocs)/sizeof(relocs[0]))
  1540.     return relocs[index];
  1541.   as_bad ("Can not do %d byte %s relocation for storage type %d", size,
  1542.       pcrel ? "pc-relative" : "", type);
  1543.   return BFD_RELOC_NONE;
  1544.  
  1545. }
  1546.  
  1547. #endif
  1548.  
  1549. void
  1550. md_assemble (line)
  1551.      char *line;
  1552. {
  1553.   freeptr = freeptr_static;
  1554.   parse (line, 0);        /* explode line to more fix form in iif */
  1555.   convert_iif ();        /* convert iif to frags, fix's etc */
  1556. #ifdef SHOW_NUM
  1557.   printf (" \t\t\t%s\n", line);
  1558. #endif
  1559. }
  1560.  
  1561.  
  1562. void
  1563. md_begin ()
  1564. {
  1565.   /* build a hashtable of the instructions */
  1566.   const struct ns32k_opcode *ptr;
  1567.   const char *stat;
  1568.   inst_hash_handle = hash_new ();
  1569.   for (ptr = ns32k_opcodes; ptr < endop; ptr++)
  1570.     {
  1571.       if ((stat = hash_insert (inst_hash_handle, ptr->name, (char *) ptr)))
  1572.     {
  1573.       as_fatal ("Can't hash %s: %s", ptr->name, stat);    /*fatal*/
  1574.     }
  1575.     }
  1576.   freeptr_static = (char *) malloc (PRIVATE_SIZE);    /* some private space please! */
  1577. }
  1578.  
  1579. /* Must be equal to MAX_PRECISON in atof-ieee.c */
  1580. #define MAX_LITTLENUMS 6
  1581.  
  1582. /* Turn the string pointed to by litP into a floating point constant of type
  1583.    type, and emit the appropriate bytes.  The number of LITTLENUMS emitted
  1584.    is stored in *sizeP .  An error message is returned, or NULL on OK.
  1585.    */
  1586. char *
  1587. md_atof (type, litP, sizeP)
  1588.      char type;
  1589.      char *litP;
  1590.      int *sizeP;
  1591. {
  1592.   int prec;
  1593.   LITTLENUM_TYPE words[MAX_LITTLENUMS];
  1594.   LITTLENUM_TYPE *wordP;
  1595.   char *t;
  1596.  
  1597.   switch (type)
  1598.     {
  1599.     case 'f':
  1600.       prec = 2;
  1601.       break;
  1602.  
  1603.     case 'd':
  1604.       prec = 4;
  1605.       break;
  1606.     default:
  1607.       *sizeP = 0;
  1608.       return "Bad call to MD_ATOF()";
  1609.     }
  1610.   t = atof_ieee (input_line_pointer, type, words);
  1611.   if (t)
  1612.     input_line_pointer = t;
  1613.  
  1614.   *sizeP = prec * sizeof (LITTLENUM_TYPE);
  1615.   for (wordP = words + prec; prec--;)
  1616.     {
  1617.       md_number_to_chars (litP, (long) (*--wordP), sizeof (LITTLENUM_TYPE));
  1618.       litP += sizeof (LITTLENUM_TYPE);
  1619.     }
  1620.   return 0;
  1621. }
  1622.  
  1623. /* Convert number to chars in correct order */
  1624.  
  1625. void
  1626. md_number_to_chars (buf, value, nbytes)
  1627.      char *buf;
  1628.      valueT value;
  1629.      int nbytes;
  1630. {
  1631.   number_to_chars_littleendian (buf, value, nbytes);
  1632. }
  1633.  
  1634.  
  1635. /* This is a variant of md_numbers_to_chars. The reason for its' existence
  1636.    is the fact that ns32k uses Huffman coded displacements. This implies
  1637.    that the bit order is reversed in displacements and that they are prefixed
  1638.    with a size-tag.
  1639.  
  1640.    binary: msb -> lsb
  1641.    0xxxxxxx                byte
  1642.    10xxxxxx xxxxxxxx            word
  1643.    11xxxxxx xxxxxxxx xxxxxxxx xxxxxxxx    double word
  1644.  
  1645.    This must be taken care of and we do it here!
  1646.    */
  1647. static void
  1648. md_number_to_disp (buf, val, n)
  1649.      char *buf;
  1650.      long val;
  1651.      char n;
  1652. {
  1653.   switch (n)
  1654.     {
  1655.     case 1:
  1656.       if (val < -64 || val > 63)
  1657.     as_warn ("Byte displacement out of range.  line number not valid");
  1658.       val &= 0x7f;
  1659. #ifdef SHOW_NUM
  1660.       printf ("%x ", val & 0xff);
  1661. #endif
  1662.       *buf++ = val;
  1663.       break;
  1664.     case 2:
  1665.       if (val < -8192 || val > 8191)
  1666.     as_warn ("Word displacement out of range.  line number not valid");
  1667.       val &= 0x3fff;
  1668.       val |= 0x8000;
  1669. #ifdef SHOW_NUM
  1670.       printf ("%x ", val >> 8 & 0xff);
  1671. #endif
  1672.       *buf++ = (val >> 8);
  1673. #ifdef SHOW_NUM
  1674.       printf ("%x ", val & 0xff);
  1675. #endif
  1676.       *buf++ = val;
  1677.       break;
  1678.     case 4:
  1679.       if (val < -0x20000000 || val >= 0x20000000)
  1680.     as_warn ("Double word displacement out of range");
  1681.       val |= 0xc0000000;
  1682. #ifdef SHOW_NUM
  1683.       printf ("%x ", val >> 24 & 0xff);
  1684. #endif
  1685.       *buf++ = (val >> 24);
  1686. #ifdef SHOW_NUM
  1687.       printf ("%x ", val >> 16 & 0xff);
  1688. #endif
  1689.       *buf++ = (val >> 16);
  1690. #ifdef SHOW_NUM
  1691.       printf ("%x ", val >> 8 & 0xff);
  1692. #endif
  1693.       *buf++ = (val >> 8);
  1694. #ifdef SHOW_NUM
  1695.       printf ("%x ", val & 0xff);
  1696. #endif
  1697.       *buf++ = val;
  1698.       break;
  1699.     default:
  1700.       as_fatal ("Internal logic error.  line %s, file \"%s\"", __LINE__, __FILE__);
  1701.     }
  1702. }
  1703.  
  1704. static void
  1705. md_number_to_imm (buf, val, n)
  1706.      char *buf;
  1707.      long val;
  1708.      char n;
  1709. {
  1710.   switch (n)
  1711.     {
  1712.     case 1:
  1713. #ifdef SHOW_NUM
  1714.       printf ("%x ", val & 0xff);
  1715. #endif
  1716.       *buf++ = val;
  1717.       break;
  1718.     case 2:
  1719. #ifdef SHOW_NUM
  1720.       printf ("%x ", val >> 8 & 0xff);
  1721. #endif
  1722.       *buf++ = (val >> 8);
  1723. #ifdef SHOW_NUM
  1724.       printf ("%x ", val & 0xff);
  1725. #endif
  1726.       *buf++ = val;
  1727.       break;
  1728.     case 4:
  1729. #ifdef SHOW_NUM
  1730.       printf ("%x ", val >> 24 & 0xff);
  1731. #endif
  1732.       *buf++ = (val >> 24);
  1733. #ifdef SHOW_NUM
  1734.       printf ("%x ", val >> 16 & 0xff);
  1735. #endif
  1736.       *buf++ = (val >> 16);
  1737. #ifdef SHOW_NUM
  1738.       printf ("%x ", val >> 8 & 0xff);
  1739. #endif
  1740.       *buf++ = (val >> 8);
  1741. #ifdef SHOW_NUM
  1742.       printf ("%x ", val & 0xff);
  1743. #endif
  1744.       *buf++ = val;
  1745.       break;
  1746.     default:
  1747.       as_fatal ("Internal logic error. line %s, file \"%s\"", __LINE__, __FILE__);
  1748.     }
  1749. }
  1750.  
  1751. /* Translate internal representation of relocation info into target format.
  1752.  
  1753.    OVE: on a ns32k the twiddling continues at an even deeper level
  1754.    here we have to distinguish between displacements and immediates.
  1755.  
  1756.    The sequent has a bit for this. It also has a bit for relocobjects that
  1757.    points at the target for a bsr (BranchSubRoutine) !?!?!?!
  1758.  
  1759.    This md_ri.... is tailored for sequent.
  1760.    */
  1761.  
  1762. #ifdef comment
  1763. void
  1764. md_ri_to_chars (the_bytes, ri)
  1765.      char *the_bytes;
  1766.      struct reloc_info_generic *ri;
  1767. {
  1768.   if (ri->r_bsr)
  1769.     {
  1770.       ri->r_pcrel = 0;
  1771.     }                /* sequent seems to want this */
  1772.   md_number_to_chars (the_bytes, ri->r_address, sizeof (ri->r_address));
  1773.   md_number_to_chars (the_bytes + 4, ((long) (ri->r_symbolnum)
  1774.                       | (long) (ri->r_pcrel << 24)
  1775.                       | (long) (ri->r_length << 25)
  1776.                       | (long) (ri->r_extern << 27)
  1777.                       | (long) (ri->r_bsr << 28)
  1778.                       | (long) (ri->r_disp << 29)),
  1779.               4);
  1780.   /* the first and second md_number_to_chars never overlaps (32bit cpu case) */
  1781. }
  1782.  
  1783. #endif /* comment */
  1784.  
  1785. /* fast bitfiddling support */
  1786. /* mask used to zero bitfield before oring in the true field */
  1787.  
  1788. static unsigned long l_mask[] =
  1789. {
  1790.   0xffffffff, 0xfffffffe, 0xfffffffc, 0xfffffff8,
  1791.   0xfffffff0, 0xffffffe0, 0xffffffc0, 0xffffff80,
  1792.   0xffffff00, 0xfffffe00, 0xfffffc00, 0xfffff800,
  1793.   0xfffff000, 0xffffe000, 0xffffc000, 0xffff8000,
  1794.   0xffff0000, 0xfffe0000, 0xfffc0000, 0xfff80000,
  1795.   0xfff00000, 0xffe00000, 0xffc00000, 0xff800000,
  1796.   0xff000000, 0xfe000000, 0xfc000000, 0xf8000000,
  1797.   0xf0000000, 0xe0000000, 0xc0000000, 0x80000000,
  1798. };
  1799. static unsigned long r_mask[] =
  1800. {
  1801.   0x00000000, 0x00000001, 0x00000003, 0x00000007,
  1802.   0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f,
  1803.   0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff,
  1804.   0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff,
  1805.   0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff,
  1806.   0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff,
  1807.   0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff,
  1808.   0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff,
  1809. };
  1810. #define MASK_BITS 31
  1811. /* Insert bitfield described by field_ptr and val at buf
  1812.    This routine is written for modification of the first 4 bytes pointed
  1813.    to by buf, to yield speed.
  1814.    The ifdef stuff is for selection between a ns32k-dependent routine
  1815.    and a general version. (My advice: use the general version!)
  1816.    */
  1817.  
  1818. static void
  1819. md_number_to_field (buf, val, field_ptr)
  1820.      register char *buf;
  1821.      register long val;
  1822.      register bit_fixS *field_ptr;
  1823. {
  1824.   register unsigned long object;
  1825.   register unsigned long mask;
  1826.   /* define ENDIAN on a ns32k machine */
  1827. #ifdef ENDIAN
  1828.   register unsigned long *mem_ptr;
  1829. #else
  1830.   register char *mem_ptr;
  1831. #endif
  1832.   if (field_ptr->fx_bit_min <= val && val <= field_ptr->fx_bit_max)
  1833.     {
  1834. #ifdef ENDIAN
  1835.       if (field_ptr->fx_bit_base)
  1836.     {            /* override buf */
  1837.       mem_ptr = (unsigned long *) field_ptr->fx_bit_base;
  1838.     }
  1839.       else
  1840.     {
  1841.       mem_ptr = (unsigned long *) buf;
  1842.     }
  1843.       mem_ptr = ((unsigned long *)
  1844.          ((char *) mem_ptr + field_ptr->fx_bit_base_adj));
  1845. #else
  1846.       if (field_ptr->fx_bit_base)
  1847.     {            /* override buf */
  1848.       mem_ptr = (char *) field_ptr->fx_bit_base;
  1849.     }
  1850.       else
  1851.     {
  1852.       mem_ptr = buf;
  1853.     }
  1854.       mem_ptr += field_ptr->fx_bit_base_adj;
  1855. #endif
  1856. #ifdef ENDIAN            /* we have a nice ns32k machine with lowbyte at low-physical mem */
  1857.       object = *mem_ptr;    /* get some bytes */
  1858. #else /* OVE Goof! the machine is a m68k or dito */
  1859.       /* That takes more byte fiddling */
  1860.       object = 0;
  1861.       object |= mem_ptr[3] & 0xff;
  1862.       object <<= 8;
  1863.       object |= mem_ptr[2] & 0xff;
  1864.       object <<= 8;
  1865.       object |= mem_ptr[1] & 0xff;
  1866.       object <<= 8;
  1867.       object |= mem_ptr[0] & 0xff;
  1868. #endif
  1869.       mask = 0;
  1870.       mask |= (r_mask[field_ptr->fx_bit_offset]);
  1871.       mask |= (l_mask[field_ptr->fx_bit_offset + field_ptr->fx_bit_size]);
  1872.       object &= mask;
  1873.       val += field_ptr->fx_bit_add;
  1874.       object |= ((val << field_ptr->fx_bit_offset) & (mask ^ 0xffffffff));
  1875. #ifdef ENDIAN
  1876.       *mem_ptr = object;
  1877. #else
  1878.       mem_ptr[0] = (char) object;
  1879.       object >>= 8;
  1880.       mem_ptr[1] = (char) object;
  1881.       object >>= 8;
  1882.       mem_ptr[2] = (char) object;
  1883.       object >>= 8;
  1884.       mem_ptr[3] = (char) object;
  1885. #endif
  1886.     }
  1887.   else
  1888.     {
  1889.       as_warn ("Bit field out of range");
  1890.     }
  1891. }
  1892.  
  1893. int md_pcrel_adjust (fragS *fragP)
  1894. {
  1895.   fragS *opcode_frag;
  1896.   int ret;
  1897.   int st = fragP->fr_subtype;
  1898.   unsigned int opcode_address;
  1899.   if ((st >> 2) == BRANCH && fragP->fr_pcrel_adjust == 0) {
  1900.     unsigned int offset;
  1901.     opcode_frag = ((struct opcode_location *) fragP->fr_opcode)->fragP;
  1902.     offset = ((struct opcode_location *) fragP->fr_opcode)->offset;
  1903.     opcode_address = offset + opcode_frag->fr_address;
  1904.     ret = fragP->fr_address - opcode_address;
  1905.   }
  1906.   else
  1907.     ret = fragP->fr_pcrel_adjust;
  1908.   return ret;
  1909. }
  1910.  
  1911. int md_fix_pcrel_adjust (fixS *fixP)
  1912. {
  1913.   fragS *fragP = fixP->fx_frag;
  1914.   fragS *opcode_frag;
  1915.   int ret;
  1916.   int st = fragP->fr_subtype;
  1917.   unsigned int opcode_address;
  1918.   if (fixP->fx_pcrel && fixP->fx_pcrel_adjust == 0) {
  1919.     unsigned int offset;
  1920.     opcode_frag = ((struct opcode_location *) fragP->fr_opcode)->fragP;
  1921.     offset = ((struct opcode_location *) fragP->fr_opcode)->offset;
  1922.     opcode_address = offset + opcode_frag->fr_address;
  1923.     ret = fragP->fr_address - opcode_address;
  1924.   }
  1925.   else
  1926.     ret = fixP->fx_pcrel_adjust;
  1927.   return ret;
  1928. }
  1929.  
  1930. /* Apply a fixS (fixup of an instruction or data that we didn't have
  1931.    enough info to complete immediately) to the data in a frag.
  1932.  
  1933.    On the ns32k, everything is in a different format, so we have broken
  1934.    out separate functions for each kind of thing we could be fixing.
  1935.    They all get called from here.  */
  1936.  
  1937. #ifdef BFD_ASSEMBLER
  1938. int
  1939. md_apply_fix (fixP, valp)
  1940.      fixS *fixP;
  1941.      valueT *valp;
  1942. #else
  1943. void
  1944. md_apply_fix (fixP, val)
  1945.      fixS *fixP;
  1946.      long val;
  1947. #endif
  1948. {
  1949. #ifdef BFD_ASSEMBLER
  1950.   long val = *valp;
  1951. #endif
  1952.   fragS *fragP = fixP->fx_frag;
  1953.  
  1954.   char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
  1955.  
  1956.   if (fixP->fx_bit_fixP)
  1957.     {                /* Bitfields to fix, sigh */
  1958.       md_number_to_field (buf, val, fixP->fx_bit_fixP);
  1959.     }
  1960.   else
  1961.     switch (fixP->fx_im_disp)
  1962.       {
  1963.  
  1964.       case 0:            /* Immediate field */
  1965.     md_number_to_imm (buf, val, fixP->fx_size);
  1966.     break;
  1967.  
  1968.       case 1:            /* Displacement field */
  1969.     /* Calculate offset */
  1970.     {
  1971.     md_number_to_disp (buf,
  1972.                  fixP->fx_pcrel ? val + md_fix_pcrel_adjust(fixP): val,
  1973.                fixP->fx_size);
  1974.     }
  1975.     break;
  1976.  
  1977.       case 2:            /* Pointer in a data object */
  1978.     md_number_to_chars (buf, val, fixP->fx_size);
  1979.     break;
  1980.       }
  1981. #ifdef BSD_ASSEMBLER
  1982.   return 1;
  1983. #endif
  1984. }
  1985.  
  1986. /* Convert a relaxed displacement to ditto in final output */
  1987.  
  1988. #ifndef BFD_ASSEMBLER
  1989. void
  1990. md_convert_frag (headers, sec, fragP)
  1991.      object_headers *headers;
  1992.      segT sec;
  1993.      register fragS *fragP;
  1994. #else
  1995. void
  1996. md_convert_frag (abfd, sec, fragP)
  1997.      bfd *abfd;
  1998.      segT sec;
  1999.      register fragS *fragP;
  2000. #endif
  2001. {
  2002.   long disp;
  2003.   long ext = 0;
  2004.  
  2005.   /* Address in gas core of the place to store the displacement.  */
  2006.   register char *buffer_address = fragP->fr_fix + fragP->fr_literal;
  2007.   /* Address in object code of the displacement.  */
  2008.   int object_address;
  2009.  
  2010.   fragS *opcode_frag;
  2011.  
  2012.   switch (fragP->fr_subtype)
  2013.     {
  2014.     case IND (BRANCH, BYTE):
  2015.       ext = 1;
  2016.       break;
  2017.     case IND (BRANCH, WORD):
  2018.       ext = 2;
  2019.       break;
  2020.     case IND (BRANCH, DOUBLE):
  2021.       ext = 4;
  2022.       break;
  2023.     }
  2024.  
  2025.   if(ext == 0)
  2026.     return;
  2027.  
  2028.   know (fragP->fr_symbol);
  2029.  
  2030.   object_address = fragP->fr_fix + fragP->fr_address;
  2031.   /* The displacement of the address, from current location.  */
  2032.   disp = (S_GET_VALUE (fragP->fr_symbol) + fragP->fr_offset) - object_address;
  2033. #ifdef BFD_ASSEMBLER
  2034.   disp += fragP->fr_symbol->sy_frag->fr_address;
  2035. #endif
  2036.   disp += md_pcrel_adjust(fragP);
  2037.  
  2038.       md_number_to_disp (buffer_address, (long) disp, (int) ext);
  2039.       fragP->fr_fix += ext;
  2040. }
  2041.  
  2042. /* This function returns the estimated size a variable object will occupy,
  2043.    one can say that we tries to guess the size of the objects before we
  2044.    actually know it */
  2045.  
  2046. int
  2047. md_estimate_size_before_relax (fragP, segment)
  2048.      register fragS *fragP;
  2049.      segT segment;
  2050. {
  2051.   int old_fix;
  2052.   old_fix = fragP->fr_fix;
  2053.   switch (fragP->fr_subtype)
  2054.     {
  2055.     case IND (BRANCH, UNDEF):
  2056.       if (S_GET_SEGMENT (fragP->fr_symbol) == segment)
  2057.     {
  2058.       /* the symbol has been assigned a value */
  2059.       fragP->fr_subtype = IND (BRANCH, BYTE);
  2060.     }
  2061.       else
  2062.     {
  2063.       /* we don't relax symbols defined in an other segment
  2064.                the thing to do is to assume the object will occupy 4 bytes */
  2065.       fix_new_ns32k (fragP,
  2066.              (int) (fragP->fr_fix),
  2067.              4,
  2068.              fragP->fr_symbol,
  2069.              fragP->fr_offset,
  2070.              1,
  2071.              fragP->fr_pcrel_adjust,
  2072.              1,
  2073.              0,
  2074.              fragP->fr_bsr);    /*sequent hack */
  2075.       fragP->fr_fix += 4;
  2076.       /* fragP->fr_opcode[1]=0xff; */
  2077.       frag_wane (fragP);
  2078.       break;
  2079.     }
  2080.     case IND (BRANCH, BYTE):
  2081.       fragP->fr_var += 1;
  2082.       break;
  2083.     default:
  2084.       break;
  2085.     }
  2086.   return fragP->fr_var + fragP->fr_fix - old_fix;
  2087. }
  2088.  
  2089. int md_short_jump_size = 3;
  2090. int md_long_jump_size = 5;
  2091. const int md_reloc_size = 8;    /* Size of relocation record */
  2092.  
  2093. void
  2094. md_create_short_jump (ptr, from_addr, to_addr, frag, to_symbol)
  2095.      char *ptr;
  2096.      addressT from_addr, to_addr;
  2097.      fragS *frag;
  2098.      symbolS *to_symbol;
  2099. {
  2100.   valueT offset;
  2101.  
  2102.   offset = to_addr - from_addr;
  2103.   md_number_to_chars (ptr, (valueT) 0xEA, 1);
  2104.   md_number_to_disp (ptr + 1, (valueT) offset, 2);
  2105. }
  2106.  
  2107. void
  2108. md_create_long_jump (ptr, from_addr, to_addr, frag, to_symbol)
  2109.      char *ptr;
  2110.      addressT from_addr, to_addr;
  2111.      fragS *frag;
  2112.      symbolS *to_symbol;
  2113. {
  2114.   valueT offset;
  2115.  
  2116.   offset = to_addr - from_addr;
  2117.   md_number_to_chars (ptr, (valueT) 0xEA, 1);
  2118.   md_number_to_disp (ptr + 1, (valueT) offset, 4);
  2119. }
  2120.  
  2121. CONST char *md_shortopts = "m:";
  2122. struct option md_longopts[] = {
  2123.   {NULL, no_argument, NULL, 0}
  2124. };
  2125. size_t md_longopts_size = sizeof(md_longopts);
  2126.  
  2127. int
  2128. md_parse_option (c, arg)
  2129.      int c;
  2130.      char *arg;
  2131. {
  2132.   switch (c)
  2133.     {
  2134.     case 'm':
  2135.       if (!strcmp (arg, "32032"))
  2136.     {
  2137.       cpureg = cpureg_032;
  2138.       mmureg = mmureg_032;
  2139.     }
  2140.       else if (!strcmp (arg, "32532"))
  2141.     {
  2142.       cpureg = cpureg_532;
  2143.       mmureg = mmureg_532;
  2144.     }
  2145.       else
  2146.     {
  2147.       as_bad ("invalid architecture option -m%s", arg);
  2148.       return 0;
  2149.     }
  2150.       break;
  2151.  
  2152.     default:
  2153.       return 0;
  2154.     }
  2155.  
  2156.   return 1;
  2157. }
  2158.  
  2159. void
  2160. md_show_usage (stream)
  2161.      FILE *stream;
  2162. {
  2163.   fprintf(stream, "\
  2164. NS32K options:\n\
  2165. -m32032 | -m32532    select variant of NS32K architecture\n");
  2166. }
  2167.  
  2168.  
  2169. /*
  2170.  *            bit_fix_new()
  2171.  *
  2172.  * Create a bit_fixS in obstack 'notes'.
  2173.  * This struct is used to profile the normal fix. If the bit_fixP is a
  2174.  * valid pointer (not NULL) the bit_fix data will be used to format the fix.
  2175.  */
  2176. bit_fixS *
  2177. bit_fix_new (size, offset, min, max, add, base_type, base_adj)
  2178.      char size;            /* Length of bitfield        */
  2179.      char offset;        /* Bit offset to bitfield    */
  2180.      long min;            /* Signextended min for bitfield */
  2181.      long max;            /* Signextended max for bitfield */
  2182.      long add;            /* Add mask, used for huffman prefix */
  2183.      long base_type;        /* 0 or 1, if 1 it's exploded to opcode ptr */
  2184.      long base_adj;
  2185. {
  2186.   register bit_fixS *bit_fixP;
  2187.  
  2188.   bit_fixP = (bit_fixS *) obstack_alloc (¬es, sizeof (bit_fixS));
  2189.  
  2190.   bit_fixP->fx_bit_size = size;
  2191.   bit_fixP->fx_bit_offset = offset;
  2192.   bit_fixP->fx_bit_base = base_type;
  2193.   bit_fixP->fx_bit_base_adj = base_adj;
  2194.   bit_fixP->fx_bit_max = max;
  2195.   bit_fixP->fx_bit_min = min;
  2196.   bit_fixP->fx_bit_add = add;
  2197.  
  2198.   return (bit_fixP);
  2199. }
  2200.  
  2201. void
  2202. fix_new_ns32k (frag, where, size, add_symbol, offset, pcrel,
  2203.            pcrel_adjust, im_disp, bit_fixP, bsr)
  2204.      fragS *frag;        /* Which frag? */
  2205.      int where;            /* Where in that frag? */
  2206.      int size;            /* 1, 2  or 4 usually. */
  2207.      symbolS *add_symbol;    /* X_add_symbol. */
  2208.      long offset;        /* X_add_number. */
  2209.      int pcrel;            /* TRUE if PC-relative relocation. */
  2210.      char pcrel_adjust;        /* not zero if adjustment of pcrel offset is needed */
  2211.      char im_disp;        /* true if the value to write is a displacement */
  2212.      bit_fixS *bit_fixP;    /* pointer at struct of bit_fix's, ignored if NULL */
  2213.      char bsr;            /* sequent-linker-hack: 1 when relocobject is a bsr */
  2214.  
  2215. {
  2216.   fixS *fixP = fix_new (frag, where, size, add_symbol,
  2217.             offset, pcrel,
  2218. #ifdef BFD_ASSEMBLER
  2219.             bit_fixP? NO_RELOC: reloc(size, pcrel, im_disp)
  2220. #else
  2221.             NO_RELOC
  2222. #endif
  2223.             );
  2224.  
  2225.   fixP->fx_pcrel_adjust = pcrel_adjust;
  2226.   fixP->fx_im_disp = im_disp;
  2227.   fixP->fx_bit_fixP = bit_fixP;
  2228.   fixP->fx_bsr = bsr;
  2229. }                /* fix_new_ns32k() */
  2230.  
  2231. void
  2232. fix_new_ns32k_exp (frag, where, size, exp, pcrel,
  2233.            pcrel_adjust, im_disp, bit_fixP, bsr)
  2234.      fragS *frag;        /* Which frag? */
  2235.      int where;            /* Where in that frag? */
  2236.      int size;            /* 1, 2  or 4 usually. */
  2237.      expressionS *exp;        /* Expression. */
  2238.      int pcrel;            /* TRUE if PC-relative relocation. */
  2239.      char pcrel_adjust;        /* not zero if adjustment of pcrel offset is needed */
  2240.      char im_disp;        /* true if the value to write is a displacement */
  2241.      bit_fixS *bit_fixP;    /* pointer at struct of bit_fix's, ignored if NULL */
  2242.      char bsr;            /* sequent-linker-hack: 1 when relocobject is a bsr */
  2243. {
  2244.   fixS *fixP = fix_new_exp (frag, where, size, exp, pcrel,
  2245. #ifdef BFD_ASSEMBLER
  2246.                 bit_fixP? NO_RELOC: reloc(size, pcrel, im_disp)
  2247. #else
  2248.                 NO_RELOC
  2249. #endif
  2250.                 );
  2251.  
  2252.   fixP->fx_pcrel_adjust = pcrel_adjust;
  2253.   fixP->fx_im_disp = im_disp;
  2254.   fixP->fx_bit_fixP = bit_fixP;
  2255.   fixP->fx_bsr = bsr;
  2256. }                /* fix_new_ns32k() */
  2257.  
  2258. /* This is TC_CONS_FIX_NEW, called by emit_expr in read.c.  */
  2259.  
  2260. void
  2261. cons_fix_new_ns32k (frag, where, size, exp)
  2262.      fragS *frag;        /* Which frag? */
  2263.      int where;            /* Where in that frag? */
  2264.      int size;            /* 1, 2  or 4 usually. */
  2265.      expressionS *exp;        /* Expression. */
  2266. {
  2267.   fix_new_ns32k_exp (frag, where, size, exp,
  2268.              0, 0, 2, 0, 0);
  2269. }
  2270.  
  2271. /* We have no need to default values of symbols.  */
  2272.  
  2273. symbolS *
  2274. md_undefined_symbol (name)
  2275.      char *name;
  2276. {
  2277.   return 0;
  2278. }
  2279.  
  2280. /* Round up a section size to the appropriate boundary.  */
  2281. valueT
  2282. md_section_align (segment, size)
  2283.      segT segment;
  2284.      valueT size;
  2285. {
  2286.   return size;            /* Byte alignment is fine */
  2287. }
  2288.  
  2289. /* Exactly what point is a PC-relative offset relative TO?
  2290.    On the National warts, they're relative to the address of the offset,
  2291.    with some funny adjustments in some circumstances during blue moons.
  2292.    (??? Is this right?  FIXME-SOON) */
  2293. long
  2294. md_pcrel_from (fixP)
  2295.      fixS *fixP;
  2296. {
  2297.   long res;
  2298.   res = fixP->fx_where + fixP->fx_frag->fr_address;
  2299. #ifdef SEQUENT_COMPATABILITY
  2300.   if (fixP->fx_frag->fr_bsr)
  2301.     res += 0x12            /* FOO Kludge alert! */
  2302. #endif
  2303.       return res;
  2304. }
  2305.  
  2306. #ifdef BFD_ASSEMBLER
  2307.  
  2308. arelent *
  2309. tc_gen_reloc (section, fixp)
  2310.      asection *section;
  2311.      fixS *fixp;
  2312. {
  2313.   arelent *rel;
  2314.   bfd_reloc_code_real_type code;
  2315.  
  2316.   code = reloc(fixp->fx_size, fixp->fx_pcrel, fixp->fx_im_disp);
  2317.  
  2318.   rel = (arelent *) bfd_alloc_by_size_t (stdoutput, sizeof (arelent));
  2319.   assert (rel != 0);
  2320.   rel->sym_ptr_ptr = &fixp->fx_addsy->bsym;
  2321.   rel->address = fixp->fx_frag->fr_address + fixp->fx_where;
  2322.   if (fixp->fx_pcrel)
  2323.     rel->addend = fixp->fx_addnumber;
  2324.   else
  2325.     rel->addend = 0;
  2326.  
  2327.   rel->howto = bfd_reloc_type_lookup (stdoutput, code);
  2328.   if (!rel->howto)
  2329.     {
  2330.       const char *name;
  2331.  
  2332.       name = S_GET_NAME (fixp->fx_addsy);
  2333.       if (name == NULL)
  2334.     name = "<unknown>";
  2335.       as_fatal ("Cannot find relocation type for symbol %s, code %d",
  2336.         name, (int) code);
  2337.     }
  2338.  
  2339.   return rel;
  2340. }
  2341. #else /* BFD_ASSEMBLER */
  2342.  
  2343. #ifdef OBJ_AOUT
  2344. void
  2345. tc_aout_fix_to_chars (where, fixP, segment_address_in_file)
  2346.      char *where;
  2347.      struct fix *fixP;
  2348.      relax_addressT segment_address_in_file;
  2349. {
  2350.   /*
  2351.    * In: length of relocation (or of address) in chars: 1, 2 or 4.
  2352.    * Out: GNU LD relocation length code: 0, 1, or 2.
  2353.    */
  2354.  
  2355.   static unsigned char nbytes_r_length[] = {42, 0, 1, 42, 2};
  2356.   long r_symbolnum;
  2357.  
  2358.   know (fixP->fx_addsy != NULL);
  2359.  
  2360.   md_number_to_chars (where,
  2361.        fixP->fx_frag->fr_address + fixP->fx_where - segment_address_in_file,
  2362.               4);
  2363.  
  2364.   r_symbolnum = (S_IS_DEFINED (fixP->fx_addsy)
  2365.          ? S_GET_TYPE (fixP->fx_addsy)
  2366.          : fixP->fx_addsy->sy_number);
  2367.  
  2368.   md_number_to_chars (where + 4,
  2369.               ((long) (r_symbolnum)
  2370.                | (long) (fixP->fx_pcrel << 24)
  2371.                | (long) (nbytes_r_length[fixP->fx_size] << 25)
  2372.                | (long) ((!S_IS_DEFINED (fixP->fx_addsy)) << 27)
  2373.                | (long) (fixP->fx_bsr << 28)
  2374.                | (long) (fixP->fx_im_disp << 29)),
  2375.               4);
  2376. }
  2377.  
  2378. #endif /* OBJ_AOUT */
  2379. #endif /* BFD_ASSMEBLER */
  2380. /*
  2381.  * Local Variables:
  2382.  * comment-column: 0
  2383.  * End:
  2384.  */
  2385.  
  2386. /* end of tc-ns32k.c */
  2387.