home *** CD-ROM | disk | FTP | other *** search
/ Dream 52 / Amiga_Dream_52.iso / Atari / Gnu / gassrc04.zoo / ns32k.c < prev    next >
C/C++ Source or Header  |  1991-01-24  |  51KB  |  1,769 lines

  1. /* ns32k.c  -- Assemble on the National Semiconductor 32k series
  2.    Copyright (C) 1987 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 1, 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, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20. #define NS32K
  21. /*#define SHOW_NUM 1*/ /* uncomment for debugging */
  22.  
  23. #include <stdio.h>
  24. #include <ctype.h>
  25. #ifdef USG
  26. #include <string.h>
  27. #else
  28. #include <strings.h>
  29. #endif
  30. #include "ns32k-opcode.h"
  31. #include "as.h"
  32. #include "obstack.h"
  33. #include "frags.h"
  34. #include "struc-symbol.h"
  35. #include "flonum.h"
  36. #include "expr.h"
  37. #include "md.h"
  38. #include "hash.h"
  39. #include "write.h"
  40. #include "symbols.h"
  41.  
  42. /* Macros */
  43. #define IIF_ENTRIES 13                /* number of entries in iif */ 
  44. #define PRIVATE_SIZE 256            /* size of my garbage memory */
  45. #define MAX_ARGS 4
  46. #define DEFAULT    -1        /* addr_mode returns this value when plain constant or label is encountered */
  47.  
  48. #define IIF(ptr,a1,c1,e1,g1,i1,k1,m1,o1,q1,s1,u1) \
  49.   iif.iifP[ptr].type= a1; \
  50.   iif.iifP[ptr].size= c1; \
  51.   iif.iifP[ptr].object= e1; \
  52.   iif.iifP[ptr].object_adjust= g1; \
  53.   iif.iifP[ptr].pcrel= i1; \
  54.   iif.iifP[ptr].pcrel_adjust= k1; \
  55.   iif.iifP[ptr].im_disp= m1; \
  56.   iif.iifP[ptr].relax_substate= o1; \
  57.   iif.iifP[ptr].bit_fixP= q1; \
  58.   iif.iifP[ptr].addr_mode= s1; \
  59.   iif.iifP[ptr].bsr= u1;
  60.  
  61. #ifdef SEQUENT_COMPATABILITY
  62. #define LINE_COMMENT_CHARS "|"
  63. #define ABSOLUTE_PREFIX '@'
  64. #define IMMEDIATE_PREFIX '#'
  65. #endif
  66.  
  67. #ifndef LINE_COMMENT_CHARS
  68. #define LINE_COMMENT_CHARS "#"
  69. #endif
  70.  
  71. char comment_chars[] = "#";
  72. char line_comment_chars[] = LINE_COMMENT_CHARS;
  73. #if !defined(ABSOLUTE_PREFIX) && !defined(IMMEDIATE_PREFIX)
  74. #define ABSOLUTE_PREFIX '@'    /* One or the other MUST be defined */
  75. #endif
  76.  
  77. struct addr_mode {
  78.   char mode;            /* addressing mode of operand (0-31) */
  79.   char scaled_mode;        /* mode combined with scaled mode */
  80.   char scaled_reg;        /* register used in scaled+1 (1-8) */
  81.   char float_flag;        /* set if R0..R7 was F0..F7 ie a floating-point-register */
  82.   char am_size;            /* estimated max size of general addr-mode parts*/
  83.   char im_disp;            /* if im_disp==1 we have a displacement */
  84.   char pcrel;            /* 1 if pcrel, this is really redundant info */
  85.   char disp_suffix[2];        /* length of displacement(s), 0=undefined */
  86.   char *disp[2];        /* pointer(s) at displacement(s)
  87.                               or immediates(s)     (ascii) */
  88.   char index_byte;        /* index byte */
  89. };
  90. typedef struct addr_mode addr_modeS;
  91.  
  92.  
  93. char *freeptr,*freeptr_static; /* points at some number of free bytes */
  94. struct hash_control *inst_hash_handle;
  95.  
  96. struct ns32k_opcode *desc; /* pointer at description of instruction */
  97. addr_modeS addr_modeP;
  98. char EXP_CHARS[] = "eE";
  99. char FLT_CHARS[] = "fd"; /* we don't want to support lowercase, do we */
  100. long omagic = OMAGIC;
  101. void md_number_to_disp();
  102. void md_number_to_imm();
  103. segT evaluate_expr();
  104. void fix_new_ns32k();
  105.  
  106. /* UPPERCASE denotes live names 
  107.  * when an instruction is built, IIF is used as an intermidiate form to store
  108.  * the actual parts of the instruction. A ns32k machine instruction can
  109.  * be divided into a couple of sub PARTs. When an instruction is assembled
  110.  * the appropriate PART get an assignment. When an IIF has been completed it's
  111.  * converted to a FRAGment as specified in AS.H */
  112.  
  113. /* internal structs */
  114. struct option {
  115.   char *pattern;
  116.   unsigned long or;
  117.   unsigned long and;
  118. };
  119.  
  120. typedef struct {
  121.   int            type;        /* how to interpret object */
  122.   int            size;        /* Estimated max size of object */
  123.   unsigned long        object;        /* binary data */
  124.   int            object_adjust;    /* number added to object */
  125.   int            pcrel;        /* True if object is pcrel */
  126.   int            pcrel_adjust;    /* It's value reflects the length in bytes from the instruction start to the displacement */
  127.   int            im_disp;    /* True if the object is a displacement */
  128.   relax_substateT    relax_substate; /* Initial relaxsubstate */
  129.   bit_fixS        *bit_fixP;    /* Pointer at bit_fix struct */ 
  130.   int            addr_mode;    /* What addrmode do we associate with this iif-entry */
  131.   char            bsr;        /* Sequent hack */
  132. }iif_entryT;                /* Internal Instruction Format */
  133. struct int_ins_form {
  134.   int        instr_size;        /* Max size of instruction in bytes. */
  135.   iif_entryT    iifP[IIF_ENTRIES+1];
  136. };
  137. struct int_ins_form iif;
  138. expressionS exprP;
  139. char *input_line_pointer;
  140. /* description of the PARTs in IIF 
  141.  *object[n]:
  142.  * 0    total length in bytes of entries in iif
  143.  * 1    opcode
  144.  * 2    index_byte_a
  145.  * 3    index_byte_b
  146.  * 4    disp_a_1
  147.  * 5    disp_a_2
  148.  * 6    disp_b_1
  149.  * 7    disp_b_2
  150.  * 8    imm_a
  151.  * 9    imm_b
  152.  * 10    implied1
  153.  * 11    implied2
  154.  * 
  155.  * For every entry there is a datalength in bytes. This is stored in size[n].
  156.  *     0,    the objectlength is not explicitly given by the instruction
  157.  *        and the operand is undefined. This is a case for relaxation.
  158.  *        Reserve 4 bytes for the final object.
  159.  *
  160.  *     1,    the entry contains one byte
  161.  *     2,    the entry contains two bytes
  162.  *     3,    the entry contains three bytes
  163.  *     4,    the entry contains four bytes
  164.  *    etc
  165.  *
  166.  * Furthermore, every entry has a data type identifier in type[n].
  167.  *
  168.  *      0,    the entry is void, ignore it.
  169.  *      1,    the entry is a binary number.
  170.  *     2,    the entry is a pointer at an expression.
  171.  *        Where expression may be as simple as a single '1',
  172.  *        and as complicated as  foo-bar+12,
  173.  *         foo and bar may be undefined but suffixed by :{b|w|d} to
  174.  *        control the length of the object.
  175.  *
  176.  *     3,    the entry is a pointer at a bignum struct
  177.  *
  178.  *
  179.  * The low-order-byte coresponds to low physical memory.
  180.  * Obviously a FRAGment must be created for each valid disp in PART whose
  181.  * datalength is undefined (to bad) .
  182.  * The case where just the expression is undefined is less severe and is
  183.  * handled by fix. Here the number of bytes in the objectfile is known.
  184.  * With this representation we simplify the assembly and separates the
  185.  * machine dependent/independent parts in a more clean way (said OE)
  186.  */
  187.  
  188. struct option opt1[]= /* restore, exit */
  189. {
  190.   { "r0",    0x80,    0xff    },
  191.   { "r1",    0x40,    0xff    },
  192.   { "r2",    0x20,    0xff    },
  193.   { "r3",    0x10,    0xff    },
  194.   { "r4",    0x08,    0xff    },
  195.   { "r5",    0x04,    0xff    },
  196.   { "r6",    0x02,    0xff    },
  197.   { "r7",    0x01,    0xff    },
  198.   {  0 ,    0x00,    0xff    }
  199. };
  200. struct option opt2[]= /* save, enter */
  201. {
  202.   { "r0",    0x01,    0xff    },
  203.   { "r1",    0x02,    0xff    },
  204.   { "r2",    0x04,    0xff    },
  205.   { "r3",    0x08,    0xff    },
  206.   { "r4",    0x10,    0xff    },
  207.   { "r5",    0x20,    0xff    },
  208.   { "r6",    0x40,    0xff    },
  209.   { "r7",    0x80,    0xff    },
  210.   {  0 ,    0x00,    0xff    }
  211. };
  212. struct option opt3[]= /* setcfg */
  213. {
  214.   { "c",    0x8,    0xff    },
  215.   { "m",    0x4,    0xff    },
  216.   { "f",    0x2,    0xff    },
  217.   { "i",    0x1,    0xff    },
  218.   {  0 ,    0x0,    0xff    }
  219. };
  220. struct option opt4[]= /* cinv */
  221. {
  222.   { "a",    0x4,    0xff    },
  223.   { "i",    0x2,    0xff    },
  224.   { "d",    0x1,    0xff    },
  225.   {  0 ,    0x0,    0xff    }
  226. };
  227. struct option opt5[]= /* string inst */
  228. {
  229.   { "b",    0x2,    0xff    },
  230.   { "u",    0xc,    0xff    },
  231.   { "w",    0x4,    0xff    },
  232.   {  0 ,    0x0,    0xff    }
  233. };
  234. struct option opt6[]= /* plain reg ext,cvtp etc */
  235. {
  236.   { "r0",    0x00,    0xff    },
  237.   { "r1",    0x01,    0xff    },
  238.   { "r2",    0x02,    0xff    },
  239.   { "r3",    0x03,    0xff    },
  240.   { "r4",    0x04,    0xff    },
  241.   { "r5",    0x05,    0xff    },
  242.   { "r6",    0x06,    0xff    },
  243.   { "r7",    0x07,    0xff    },
  244.   {  0 ,    0x00,    0xff    }
  245. };
  246.  
  247. #if !defined(NS32032) && !defined(NS32532)
  248. #define NS32032
  249. #endif
  250.  
  251. struct option cpureg_532[]= /* lpr spr */
  252. {
  253.   { "us",    0x0,    0xff    },
  254.   { "dcr",    0x1,    0xff    },
  255.   { "bpc",    0x2,    0xff    },
  256.   { "dsr",    0x3,    0xff    },
  257.   { "car",    0x4,    0xff    },
  258.   { "fp",    0x8,    0xff    },
  259.   { "sp",    0x9,    0xff    },
  260.   { "sb",    0xa,    0xff    },
  261.   { "usp",    0xb,    0xff    },
  262.   { "cfg",    0xc,    0xff    },
  263.   { "psr",    0xd,    0xff    },
  264.   { "intbase",    0xe,    0xff    },
  265.   { "mod",    0xf,    0xff    },
  266.   {  0 ,    0x00,    0xff    }
  267. };
  268. struct option mmureg_532[]= /* lmr smr */
  269. {
  270.   { "mcr",    0x9,    0xff    },
  271.   { "msr",    0xa,    0xff    },
  272.   { "tear",    0xb,    0xff    },
  273.   { "ptb0",    0xc,    0xff    },
  274.   { "ptb1",    0xd,    0xff    },
  275.   { "ivar0",    0xe,    0xff    },
  276.   { "ivar1",    0xf,    0xff    },
  277.   {  0 ,    0x0,    0xff    }
  278. };
  279.  
  280. struct option cpureg_032[]= /* lpr spr */
  281. {
  282.   { "upsr",    0x0,    0xff    },
  283.   { "fp",    0x8,    0xff    },
  284.   { "sp",    0x9,    0xff    },
  285.   { "sb",    0xa,    0xff    },
  286.   { "psr",    0xd,    0xff    },
  287.   { "intbase",    0xe,    0xff    },
  288.   { "mod",    0xf,    0xff    },
  289.   {  0 ,    0x0,    0xff    }
  290. };
  291. struct option mmureg_032[]= /* lmr smr */
  292. {
  293.   { "bpr0",    0x0,    0xff    },
  294.   { "bpr1",    0x1,    0xff    },
  295.   { "pf0",    0x4,    0xff    },
  296.   { "pf1",    0x5,    0xff    },
  297.   { "sc",    0x8,    0xff    },
  298.   { "msr",    0xa,    0xff    },
  299.   { "bcnt",    0xb,    0xff    },
  300.   { "ptb0",    0xc,    0xff    },
  301.   { "ptb1",    0xd,    0xff    },
  302.   { "eia",    0xf,    0xff    },
  303.   {  0 ,    0x0,    0xff    }
  304. };
  305.  
  306. #if defined(NS32532)
  307. struct option *cpureg = cpureg_532;
  308. struct option *mmureg = mmureg_532;
  309. #else
  310. struct option *cpureg = cpureg_032;
  311. struct option *mmureg = mmureg_032;
  312. #endif
  313.  
  314.  
  315. const pseudo_typeS md_pseudo_table[]={ /* so far empty */
  316.   { 0,    0,    0    }
  317. };
  318.  
  319. #define IND(x,y)    (((x)<<2)+(y))
  320.  
  321. /* those are index's to relax groups in md_relax_table 
  322.    ie it must be multiplied by 4 to point at a group start. Viz IND(x,y)
  323.    Se function relax_segment in write.c for more info */
  324.  
  325. #define BRANCH        1
  326. #define PCREL        2 
  327.  
  328. /* those are index's to entries in a relax group */
  329.  
  330. #define BYTE        0
  331. #define WORD        1
  332. #define DOUBLE        2
  333. #define UNDEF           3
  334. /* Those limits are calculated from the displacement start in memory.
  335.    The ns32k uses the begining of the instruction as displacement base.
  336.    This type of displacements could be handled here by moving the limit window
  337.    up or down. I choose to use an internal displacement base-adjust as there
  338.    are other routines that must consider this. Also, as we have two various
  339.    offset-adjusts in the ns32k (acb versus br/brs/jsr/bcond), two set of limits
  340.    would have had to be used.
  341.    Now we dont have to think about that. */
  342.  
  343.  
  344. const relax_typeS md_relax_table[]={
  345.   { 1,        1,        0,    0            },
  346.   { 1,        1,        0,    0            },
  347.   { 1,        1,        0,    0            },
  348.   { 1,        1,        0,    0            },
  349.  
  350.   { (63),    (-64),        1,    IND(BRANCH,WORD)    },
  351.   { (8192),    (-8192),    2,    IND(BRANCH,DOUBLE)    },
  352.   { 0,        0,        4,    0            },
  353.   { 1,        1,        0,    0            }
  354. };
  355.  
  356. /* Array used to test if mode contains displacements.
  357.    Value is true if mode contains displacement. */
  358.  
  359. char disp_test[]={ 0,0,0,0,0,0,0,0,
  360.            1,1,1,1,1,1,1,1,
  361.            1,1,1,0,0,1,1,0,
  362.            1,1,1,1,1,1,1,1 };
  363.  
  364. /* Array used to calculate max size of displacements */
  365.  
  366. char disp_size[]={ 4,1,2,0,4 };
  367.  
  368. /* Parses a general operand into an addressingmode struct 
  369.  
  370.    in:  pointer at operand in ascii form
  371.         pointer at addr_mode struct for result
  372.     the level of recursion. (always 0 or 1)
  373.  
  374.    out: data in addr_mode struct
  375.  */
  376. int addr_mode(operand,addr_modeP,recursive_level)
  377.      char *operand;
  378.      register addr_modeS *addr_modeP;
  379. int recursive_level;
  380. {
  381.   register char *str;
  382.   register int i;
  383.   register int strl;
  384.   register int mode;
  385.   int j;
  386.   mode = DEFAULT;                 /* default */
  387.   addr_modeP->scaled_mode=0;        /* why not */
  388.   addr_modeP->scaled_reg=0;        /* if 0, not scaled index */
  389.   addr_modeP->float_flag=0;
  390.   addr_modeP->am_size=0;
  391.   addr_modeP->im_disp=0;
  392.   addr_modeP->pcrel=0;            /* not set in this function */
  393.   addr_modeP->disp_suffix[0]=0;
  394.   addr_modeP->disp_suffix[1]=0;
  395.   addr_modeP->disp[0]=NULL;
  396.   addr_modeP->disp[1]=NULL;
  397.   str=operand;
  398.   if (str[0]==0) {return (0);}        /* we don't want this */
  399.   strl=strlen(str);               
  400.   switch (str[0]) {
  401.     /* the following three case statements controls the mode-chars
  402.        this is the place to ed if you want to change them */
  403. #ifdef ABSOLUTE_PREFIX
  404.   case ABSOLUTE_PREFIX:
  405.     if (str[strl-1]==']') break;
  406.     addr_modeP->mode=21;        /* absolute */
  407.     addr_modeP->disp[0]=str+1;
  408.     return (-1);
  409. #endif
  410. #ifdef IMMEDIATE_PREFIX
  411.   case IMMEDIATE_PREFIX:
  412.     if (str[strl-1]==']') break;
  413.     addr_modeP->mode=20;        /* immediate */
  414.     addr_modeP->disp[0]=str+1;
  415.     return (-1);
  416. #endif
  417.   case '.':
  418.     if (str[strl-1]!=']') {
  419.       switch (str[1]) {
  420.       case'-':case'+':
  421.         if (str[2]!='\000') {
  422.       addr_modeP->mode=27;        /* pc-relativ */
  423.       addr_modeP->disp[0]=str+2;
  424.       return (-1);
  425.     }
  426.       default:
  427.         as_warn("Invalid syntax in PC-relative addressing mode");
  428.         return(0);
  429.       }
  430.     }
  431.     break;
  432.   case'e':
  433.     if (str[strl-1]!=']') {
  434.       if((!strncmp(str,"ext(",4)) && strl>7) {    /* external */
  435.     addr_modeP->disp[0]=str+4;
  436.     i=0;
  437.     j=2;
  438.     do {                 /* disp[0]'s termination point */
  439.       j+=1;
  440.       if (str[j]=='(') i++;
  441.       if (str[j]==')') i--;
  442.     } while (j<strl && i!=0);
  443.     if (i!=0 || !(str[j+1]=='-' || str[j+1]=='+') ) {
  444.       as_warn("Invalid syntax in External addressing mode");
  445.       return(0);
  446.     }
  447.     str[j]='\000';            /* null terminate disp[0] */
  448.     addr_modeP->disp[1]=str+j+2;
  449.     addr_modeP->mode=22;
  450.     return (-1);
  451.       }
  452.     }
  453.   break;
  454.   default:;
  455.   }
  456.   strl=strlen(str);               
  457.   switch(strl) {
  458.   case 2:
  459.     switch (str[0]) {
  460.     case'f':addr_modeP->float_flag=1;
  461.     case'r':
  462.       if (str[1]>='0' && str[1]<'8') {
  463.     addr_modeP->mode=str[1]-'0';
  464.     return (-1);
  465.       }
  466.     }
  467.   case 3:
  468.     if (!strncmp(str,"tos",3)) {
  469.       addr_modeP->mode=23; /* TopOfStack */
  470.       return (-1);
  471.     }
  472.   default:;
  473.   }
  474.   if (strl>4) {
  475.     if (str[strl-1]==')') {
  476.       if (str[strl-2]==')') {
  477.     if (!strncmp(&str[strl-5],"(fp",3)) {
  478.       mode=16; /* Memory Relative */
  479.     }
  480.     if (!strncmp(&str[strl-5],"(sp",3)) {
  481.       mode=17;
  482.     }
  483.     if (!strncmp(&str[strl-5],"(sb",3)) {
  484.       mode=18;
  485.     }
  486.     if (mode!=DEFAULT) {          /* memory relative */
  487.       addr_modeP->mode=mode;
  488.       j=strl-5; /* temp for end of disp[0] */
  489.       i=0;
  490.       do {
  491.         strl-=1;
  492.         if (str[strl]==')') i++;
  493.         if (str[strl]=='(') i--;
  494.       } while (strl>-1 && i!=0);
  495.       if (i!=0) {
  496.         as_warn("Invalid syntax in Memory Relative addressing mode");
  497.         return(0);
  498.       }
  499.       addr_modeP->disp[1]=str;
  500.       addr_modeP->disp[0]=str+strl+1;
  501.       str[j]='\000'; /* null terminate disp[0] */
  502.       str[strl]='\000'; /* null terminate disp[1] */
  503.       return (-1);
  504.     }
  505.       }
  506.       switch (str[strl-3]) {
  507.       case'r':case'R':
  508.         if (str[strl-2]>='0' && str[strl-2]<'8' && str[strl-4]=='(') {
  509.       addr_modeP->mode=str[strl-2]-'0'+8;
  510.       addr_modeP->disp[0]=str;
  511.       str[strl-4]=0;
  512.       return (-1); /* reg rel */
  513.     }
  514.       default:
  515.         if (!strncmp(&str[strl-4],"(fp",3)) {
  516.       mode=24;
  517.     }
  518.         if (!strncmp(&str[strl-4],"(sp",3)) {
  519.       mode=25;
  520.     }
  521.         if (!strncmp(&str[strl-4],"(sb",3)) {
  522.       mode=26;
  523.     }
  524.     if (!strncmp(&str[strl-4],"(pc",3)) {
  525.       mode=27;
  526.     }
  527.         if (mode!=DEFAULT) {
  528.       addr_modeP->mode=mode;
  529.       addr_modeP->disp[0]=str;
  530.       str[strl-4]='\0';
  531.       return (-1); /* memory space */
  532.     }
  533.       }
  534.     }
  535.      /* no trailing ')' do we have a ']' ? */
  536.     if (str[strl-1]==']') {
  537.       switch (str[strl-2]) {
  538.       case'b':mode=28;break;
  539.       case'w':mode=29;break;
  540.       case'd':mode=30;break;
  541.       case'q':mode=31;break;
  542.       default:;
  543.         as_warn("Invalid scaled-indexed mode, use (b,w,d,q)");
  544.         if (str[strl-3]!=':' || str[strl-6]!='[' ||
  545.         str[strl-5]=='r' || str[strl-4]<'0' || str[strl-4]>'7') {
  546.       as_warn("Syntax in scaled-indexed mode, use [Rn:m] where n=[0..7] m={b,w,d,q}");
  547.     }
  548.       }  /* scaled index */
  549.       {
  550.     if (recursive_level>0) {
  551.       as_warn("Scaled-indexed addressing mode combined with scaled-index");
  552.       return(0);
  553.     }
  554.     addr_modeP->am_size+=1;        /* scaled index byte */
  555.     j=str[strl-4]-'0';        /* store temporary */
  556.     str[strl-6]='\000';        /* nullterminate for recursive call */
  557.     i=addr_mode(str,addr_modeP,1);
  558.     if (!i || addr_modeP->mode==20) {
  559.       as_warn("Invalid or illegal addressing mode combined with scaled-index");
  560.       return(0);
  561.     }
  562.     addr_modeP->scaled_mode=addr_modeP->mode; /* store the inferior mode */
  563.     addr_modeP->mode=mode;
  564.     addr_modeP->scaled_reg=j+1;
  565.     return (-1);
  566.       }
  567.     }
  568.   }
  569.   addr_modeP->mode = DEFAULT;    /* default to whatever */
  570.   addr_modeP->disp[0]=str;
  571.   return (-1);
  572. }
  573.  
  574. /* ptr points at string
  575.    addr_modeP points at struct with result
  576.    This routine calls addr_mode to determine the general addr.mode of
  577.    the operand. When this is ready it parses the displacements for size
  578.    specifying suffixes and determines size of immediate mode via ns32k-opcode.
  579.    Also builds index bytes if needed.
  580.  */
  581. int get_addr_mode(ptr,addr_modeP)
  582.      char *ptr;
  583.      addr_modeS *addr_modeP;
  584. {
  585.   int tmp;
  586.   addr_mode(ptr,addr_modeP,0);
  587.   if (addr_modeP->mode == DEFAULT || addr_modeP->scaled_mode == -1) {
  588.                    /* resolve ambigious operands, this shouldn't
  589.                   be necessary if one uses standard NSC operand
  590.                   syntax. But the sequent compiler doesn't!!!
  591.                   This finds a proper addressinging mode if it
  592.                   is implicitly stated. See ns32k-opcode.h */
  593.     (void)evaluate_expr(&exprP,ptr); /* this call takes time Sigh! */
  594.     if (addr_modeP->mode == DEFAULT) {
  595.       if (exprP.X_add_symbol || exprP.X_subtract_symbol) {
  596.     addr_modeP->mode=desc->default_model; /* we have a label */
  597.       } else {
  598.     addr_modeP->mode=desc->default_modec; /* we have a constant */
  599.       }
  600.     } else {
  601.       if (exprP.X_add_symbol || exprP.X_subtract_symbol) {
  602.     addr_modeP->scaled_mode=desc->default_model;
  603.       } else {
  604.     addr_modeP->scaled_mode=desc->default_modec;
  605.       }
  606.     }
  607.     /* must put this mess down in addr_mode to handle the scaled case better */
  608.   }
  609.   /* It appears as the sequent compiler wants an absolute when we have a
  610.      label without @. Constants becomes immediates besides the addr case.
  611.      Think it does so with local labels too, not optimum, pcrel is better.
  612.      When I have time I will make gas check this and select pcrel when possible
  613.      Actually that is trivial.
  614.      */
  615.   if (tmp=addr_modeP->scaled_reg) { /* build indexbyte */
  616.     tmp--; /* remember regnumber comes incremented for flagpurpose */
  617.     tmp|=addr_modeP->scaled_mode<<3;
  618.     addr_modeP->index_byte=(char)tmp;
  619.     addr_modeP->am_size+=1;
  620.   }
  621.   if (disp_test[addr_modeP->mode]) { /* there was a displacement, probe for length specifying suffix*/
  622.     {
  623.       register char c;
  624.       register char suffix;
  625.       register char suffix_sub;
  626.       register int i;
  627.       register char *toP;
  628.       register char *fromP;
  629.  
  630.       addr_modeP->pcrel=0;
  631.       if (disp_test[addr_modeP->mode]) { /* there is a displacement */
  632.     if (addr_modeP->mode==27 || addr_modeP->scaled_mode==27) { /* do we have pcrel. mode */
  633.       addr_modeP->pcrel=1;
  634.     }
  635.     addr_modeP->im_disp=1;
  636.     for(i=0;i<2;i++) {
  637.       suffix_sub=suffix=0;
  638.       if (toP=addr_modeP->disp[i]) { /* suffix of expression, the largest size rules */
  639.         fromP=toP;
  640.         while (c = *fromP++) {
  641.           *toP++=c;
  642.           if (c==':') {
  643.         switch (*fromP) {
  644.         case '\0':
  645.           as_warn("Premature end of suffix--Defaulting to d");
  646.           suffix=4;
  647.           continue;
  648.         case 'b':suffix_sub=1;break;
  649.         case 'w':suffix_sub=2;break;
  650.         case 'd':suffix_sub=4;break;
  651.         default:
  652.           as_warn("Bad suffix after ':' use {b|w|d} Defaulting to d");
  653.           suffix=4;
  654.         }
  655.         fromP++;
  656.         toP--; /* So we write over the ':' */
  657.         if (suffix<suffix_sub) suffix=suffix_sub;
  658.           }
  659.         }
  660.         *toP='\0'; /* terminate properly */
  661.         addr_modeP->disp_suffix[i]=suffix;
  662.         addr_modeP->am_size+=suffix ? suffix : 4;
  663.       }
  664.     }
  665.       }
  666.     }
  667.   } else {
  668.     if (addr_modeP->mode==20) { /* look in ns32k_opcode for size */
  669.       addr_modeP->disp_suffix[0]=addr_modeP->am_size=desc->im_size;
  670.       addr_modeP->im_disp=0;
  671.     }
  672.   }
  673.   return addr_modeP->mode;
  674. }
  675.  
  676.  
  677. /* read an optionlist */
  678. void optlist(str,optionP,default_map)
  679.      char *str;             /* the string to extract options from */
  680.      struct option *optionP;     /* how to search the string */
  681.      unsigned long *default_map; /* default pattern and output */
  682. {
  683.   register int i,j,k,strlen1,strlen2;
  684.   register char *patternP,*strP;
  685.   strlen1=strlen(str);
  686.   if (strlen1<1) { 
  687.     as_fatal("Very short instr to option, ie you can't do it on a NULLstr");
  688.   }
  689.   for (i=0;optionP[i].pattern!=0;i++) {
  690.     strlen2=strlen(optionP[i].pattern);
  691.     for (j=0;j<strlen1;j++) {
  692.       patternP=optionP[i].pattern;
  693.       strP = &str[j];
  694.       for (k=0;k<strlen2;k++) {
  695.     if (*(strP++)!=*(patternP++)) break;
  696.       }
  697.       if (k==strlen2) { /* match */
  698.     *default_map|=optionP[i].or;
  699.     *default_map&=optionP[i].and;
  700.       }
  701.     }
  702.   }
  703. }
  704. /* search struct for symbols 
  705.    This function is used to get the short integer form of reg names
  706.    in the instructions lmr, smr, lpr, spr
  707.    return true if str is found in list */
  708.  
  709. int list_search(str,optionP,default_map)
  710.      char *str;             /* the string to match */
  711.      struct option *optionP;     /* list to search */
  712.      unsigned long *default_map; /* default pattern and output */
  713. {
  714.   register int i;
  715.   for (i=0;optionP[i].pattern!=0;i++) {
  716.     if (!strncmp(optionP[i].pattern,str,20)) { /* use strncmp to be safe */
  717.       *default_map|=optionP[i].or;
  718.       *default_map&=optionP[i].and;
  719.       return -1;
  720.     }
  721.   }
  722.   as_warn("No such entry in list. (cpu/mmu register)");
  723.   return 0;
  724. }
  725. segT evaluate_expr(resultP,ptr)
  726. expressionS *resultP;
  727. char *ptr;
  728. {
  729.   register char *tmp_line;
  730.   register segT segment;
  731.   tmp_line=input_line_pointer;
  732.   input_line_pointer=ptr;
  733.   segment=expression(&exprP);
  734.   input_line_pointer=tmp_line;
  735.   return (segment);
  736. }
  737.  
  738. /* Convert operands to iif-format and adds bitfields to the opcode.
  739.    Operands are parsed in such an order that the opcode is updated from
  740.    its most significant bit, that is when the operand need to alter the
  741.    opcode.
  742.    Be carefull not to put to objects in the same iif-slot.
  743.    */
  744.  
  745. encode_operand(argc,argv,operandsP,suffixP,im_size,opcode_bit_ptr)
  746.      int argc;
  747.      char **argv;
  748.      char *operandsP;
  749.      char *suffixP;
  750.      char im_size;
  751.      char opcode_bit_ptr;
  752. {
  753.   register int i,j;
  754.   int pcrel,tmp,b,loop,pcrel_adjust;
  755.   for(loop=0;loop<argc;loop++) {
  756.     i=operandsP[loop<<1]-'1'; /* what operand are we supposed to work on */
  757.     if (i>3) as_fatal("Internal error check ns32k-opcode.h");
  758.     pcrel=0;
  759.     pcrel_adjust=0;
  760.     tmp=0;
  761.     switch (operandsP[(loop<<1)+1]) {
  762.     case 'f':  /* operand of sfsr turns out to be a nasty specialcase */
  763.       opcode_bit_ptr-=5;
  764.     case 'F':        /* 32 bit float    general form */
  765.     case 'L':        /* 64 bit float    */
  766.     case 'Q':        /* quad-word    */
  767.     case 'B':        /* byte     */
  768.     case 'W':        /* word     */
  769.     case 'D':        /* double-word    */
  770.     case 'A':        /* double-word    gen-address-form ie no regs allowed */
  771.       get_addr_mode(argv[i],&addr_modeP);
  772.       iif.instr_size+=addr_modeP.am_size;
  773.       if (opcode_bit_ptr==desc->opcode_size) b=4; else b=6;
  774.       for (j=b;j<(b+2);j++) { 
  775.     if (addr_modeP.disp[j-b]) { 
  776.       IIF(j,
  777.           2,
  778.           addr_modeP.disp_suffix[j-b],
  779.           (unsigned long)addr_modeP.disp[j-b],
  780.           0,
  781.           addr_modeP.pcrel,
  782.           iif.instr_size-addr_modeP.am_size, /* this aint used (now) */
  783.           addr_modeP.im_disp,
  784.           IND(BRANCH,BYTE),
  785.           NULL,
  786.           addr_modeP.scaled_reg ? addr_modeP.scaled_mode:addr_modeP.mode,
  787.           0);
  788.     }
  789.       }
  790.       opcode_bit_ptr-=5;
  791.       iif.iifP[1].object|=((long)addr_modeP.mode)<<opcode_bit_ptr;
  792.       if (addr_modeP.scaled_reg) { 
  793.     j=b/2;
  794.     IIF(j,1,1, (unsigned long)addr_modeP.index_byte,0,0,0,0,0, NULL,-1,0);
  795.       }
  796.       break;
  797.     case 'b':        /* multiple instruction disp */
  798.       freeptr++;    /* OVE:this is an useful hack */
  799.       tmp=(int)sprintf(freeptr,"((%s-1)*%d)\000",argv[i],desc->im_size);
  800.       argv[i]=freeptr;
  801.       freeptr=(char*)tmp;
  802.       pcrel-=1; /* make pcrel 0 inspite of what case 'p': wants */
  803.       /* fall thru */
  804.     case 'p':        /* displacement - pc relative addressing */
  805.       pcrel+=1;
  806.       /* fall thru */
  807.     case 'd':                    /* displacement */
  808.       iif.instr_size+=suffixP[i] ? suffixP[i] : 4;
  809.       IIF(12, 2, suffixP[i], (unsigned long)argv[i], 0,
  810.       pcrel, pcrel_adjust, 1, IND(BRANCH,BYTE), NULL,-1,0);
  811.       break;
  812.     case 'H': /* sequent-hack: the linker wants a bit set when bsr */
  813.       pcrel=1;
  814.       iif.instr_size+=suffixP[i] ? suffixP[i] : 4;
  815.       IIF(12, 2, suffixP[i], (unsigned long)argv[i], 0,
  816.       pcrel, pcrel_adjust, 1, IND(BRANCH,BYTE), NULL,-1,1);break;
  817.     case 'q':                    /* quick */
  818.       opcode_bit_ptr-=4;
  819.       IIF(11,2,42,(unsigned long)argv[i],0,0,0,0,0,
  820.       bit_fix_new(4,opcode_bit_ptr,-8,7,0,1,0),-1,0);
  821.       break;
  822.     case 'r':                /* register number (3 bits) */
  823.       list_search(argv[i],opt6,&tmp);
  824.       opcode_bit_ptr-=3;
  825.       iif.iifP[1].object|=tmp<<opcode_bit_ptr;
  826.       break;
  827.     case 'O':                /* setcfg instruction optionslist */
  828.       optlist(argv[i],opt3,&tmp);
  829.       opcode_bit_ptr-=4;
  830.       iif.iifP[1].object|=tmp<<15;
  831.       break;
  832.     case 'C':                /* cinv instruction optionslist */
  833.       optlist(argv[i],opt4,&tmp);
  834.       opcode_bit_ptr-=4;
  835.       iif.iifP[1].object|=tmp<<15;/*insert the regtype in opcode */
  836.       break;
  837.     case 'S':                /* stringinstruction optionslist */
  838.       optlist(argv[i],opt5,&tmp);
  839.       opcode_bit_ptr-=4;
  840.       iif.iifP[1].object|=tmp<<15;
  841.       break;
  842.     case 'u':case 'U':                /* registerlist */
  843.       IIF(10,1,1,0,0,0,0,0,0,NULL,-1,0);
  844.       switch (operandsP[(i<<1)+1]) {
  845.       case 'u':                       /* restore, exit */
  846.     optlist(argv[i],opt1,&iif.iifP[10].object);
  847.     break;
  848.       case 'U':                    /* save,enter */
  849.     optlist(argv[i],opt2,&iif.iifP[10].object);
  850.     break;
  851.       }
  852.       iif.instr_size+=1;
  853.       break;
  854.     case 'M':                    /* mmu register */
  855.       list_search(argv[i],mmureg,&tmp);
  856.       opcode_bit_ptr-=4;
  857.       iif.iifP[1].object|=tmp<<opcode_bit_ptr;
  858.       break;
  859.     case 'P':                    /* cpu register  */
  860.       list_search(argv[i],cpureg,&tmp);
  861.       opcode_bit_ptr-=4;
  862.       iif.iifP[1].object|=tmp<<opcode_bit_ptr;
  863.       break;
  864.     case 'g': /* inss exts */
  865.       iif.instr_size+=1; /* 1 byte is allocated after the opcode */
  866.       IIF(10,2,1,
  867.       (unsigned long)argv[i], /* i always 2 here */
  868.       0,0,0,0,0,
  869.       bit_fix_new(3,5,0,7,0,0,0), /* a bit_fix is targeted to the byte */
  870.       -1,0);
  871.     case 'G':
  872.       IIF(11,2,42,
  873.       (unsigned long)argv[i], /* i always 3 here */
  874.       0,0,0,0,0,
  875.       bit_fix_new(5,0,1,32,-1,0,-1),-1,0);
  876.       break;
  877.     case 'i':
  878.       iif.instr_size+=1;
  879.       b=2+i;  /* put the extension byte after opcode */
  880.       IIF(b,2,1,0,0,0,0,0,0,0,-1,0);
  881.     default:
  882.       as_fatal("Bad opcode-table-option, check in file ns32k-opcode.h");
  883.     }
  884.   }
  885. }
  886.  
  887. /* in:  instruction line
  888.    out: internal structure of instruction
  889.         that has been prepared for direct conversion to fragment(s) and
  890.     fixes in a systematical fashion
  891.     Return-value = recursive_level
  892. */
  893. /* build iif of one assembly text line */
  894. int parse(line,recursive_level)
  895.      char *line;
  896.      int recursive_level;
  897. {
  898.   register char            *lineptr,c,suffix_separator;
  899.   register int            i;
  900.   int                argc,arg_type;
  901.   char                sqr,sep;
  902.   char suffix[MAX_ARGS],*argv[MAX_ARGS];/* no more than 4 operands */
  903.   if (recursive_level<=0) { /* called from md_assemble */
  904.     for (lineptr=line;(*lineptr)!='\0' && (*lineptr)!=' ';lineptr++); 
  905.     c = *lineptr;
  906.     *lineptr='\0';
  907.     if (!(desc=(struct ns32k_opcode*)hash_find(inst_hash_handle,line))) {
  908.       as_fatal("No such opcode");
  909.     }
  910.     *lineptr=c;
  911.   } else {
  912.     lineptr=line;
  913.   }
  914.   argc=0;
  915.   if (*desc->operands) {
  916.     if (*lineptr++!='\0') {
  917.       sqr='[';
  918.       sep=',';
  919.       while (*lineptr!='\0') {
  920.     if (desc->operands[argc<<1]) {
  921.       suffix[argc]=0;
  922.       arg_type=desc->operands[(argc<<1)+1];
  923.       switch (arg_type) {
  924.       case 'd': case 'b': case 'p': case 'H':  /* the operand is supposed to be a displacement */
  925.         /* Hackwarning: do not forget to update the 4 cases above when editing ns32k-opcode.h */
  926.         suffix_separator=':';
  927.         break;
  928.       default:
  929.         suffix_separator='\255'; /* if this char occurs we loose */
  930.       }
  931.       suffix[argc]=0; /* 0 when no ':' is encountered */
  932.       argv[argc]=freeptr;
  933.       *freeptr='\0';
  934.       while ((c = *lineptr)!='\0' && c!=sep) {
  935.         if (c==sqr) {
  936.           if (sqr=='[') {
  937.         sqr=']';sep='\0';
  938.           } else {
  939.         sqr='[';sep=',';
  940.           }
  941.         }
  942.         if (c==suffix_separator) { /* ':' - label/suffix separator */
  943.           switch (lineptr[1]) {
  944.           case 'b':suffix[argc]=1;break;
  945.           case 'w':suffix[argc]=2;break;
  946.           case 'd':suffix[argc]=4;break;
  947.           default: as_warn("Bad suffix, defaulting to d");
  948.         suffix[argc]=4;
  949.         if (lineptr[1]=='\0' || lineptr[1]==sep) {
  950.           lineptr+=1;
  951.           continue;
  952.         }
  953.           }
  954.           lineptr+=2;
  955.           continue;
  956.         }
  957.         *freeptr++=c;
  958.         lineptr++;
  959.       }
  960.       *freeptr++='\0';
  961.       argc+=1;
  962.       if (*lineptr=='\0') continue;
  963.       lineptr+=1;
  964.     } else {
  965.       as_fatal("Too many operands passed to instruction");
  966.     }
  967.       }
  968.     }
  969.   }
  970.   if (argc!=strlen(desc->operands)/2) {
  971.     if (strlen(desc->default_args)) { /* we can apply default, dont goof */
  972.       if (parse(desc->default_args,1)!=1) { /* check error in default */
  973.     as_fatal("Wrong numbers of operands in default, check ns32k-opcodes.h");
  974.       }
  975.     } else {
  976.       as_fatal("Wrong number of operands");
  977.     }
  978.  
  979.   }
  980.   for (i=0;i<IIF_ENTRIES;i++) {
  981.     iif.iifP[i].type=0; /* mark all entries as void*/
  982.   }
  983.  
  984.     /* build opcode iif-entry */
  985.   iif.instr_size=desc->opcode_size/8;
  986.   IIF(1,1,iif.instr_size,desc->opcode_seed,0,0,0,0,0,0,-1,0);
  987.  
  988.     /* this call encodes operands to iif format */
  989.   if (argc) {
  990.     encode_operand(argc,
  991.            argv,
  992.            &desc->operands[0],
  993.            &suffix[0],
  994.            desc->im_size,
  995.            desc->opcode_size);
  996.   }
  997.   return recursive_level;
  998. }
  999.  
  1000.  
  1001.   /* Convert iif to fragments.
  1002.      From this point we start to dribble with functions in other files than
  1003.      this one.(Except hash.c) So, if it's possible to make an iif for an other
  1004.      CPU, you don't need to know what frags, relax, obstacks, etc is in order
  1005.      to port this assembler. You only need to know if it's possible to reduce
  1006.      your cpu-instruction to iif-format (takes some work) and adopt the other
  1007.      md_? parts according to given instructions
  1008.      Note that iif was invented for the clean ns32k`s architecure.
  1009.      */
  1010. convert_iif()
  1011. {
  1012.   register int            i,j;
  1013.   fragS             *inst_frag;
  1014.   char                *inst_offset,*inst_opcode;
  1015.   char                *memP;
  1016.   segT                segment;
  1017.   int                l,k;
  1018.   register int rem_size; /* count the remaining bytes of instruction */
  1019.   register char type;
  1020.   register char size = 0;
  1021.   int    size_so_far=0; /* used to calculate pcrel_adjust */
  1022.  
  1023.     rem_size=iif.instr_size;
  1024.     memP=frag_more(iif.instr_size); /* make sure we have enough bytes for instruction */
  1025.     inst_opcode=memP;
  1026.     inst_offset=(char*)(memP-frag_now->fr_literal);
  1027.     inst_frag=frag_now;
  1028.     for (i=0;i<IIF_ENTRIES;i++) {
  1029.       if (type=iif.iifP[i].type) {            /* the object exist, so handle it */
  1030.     switch (size=iif.iifP[i].size) {
  1031.     case 42: size=0; /* it's a bitfix that operates on an existing object*/
  1032.       if (iif.iifP[i].bit_fixP->fx_bit_base) { /* expand fx_bit_base to point at opcode */
  1033.         iif.iifP[i].bit_fixP->fx_bit_base=(long)inst_opcode;
  1034.       }
  1035.     case 8: /* bignum or doublefloat */
  1036.       bzero (memP,8);
  1037.     case 1:case 2:case 3:case 4:/* the final size in objectmemory is known */
  1038.       j=(unsigned long)iif.iifP[i].bit_fixP;
  1039.       switch (type) {
  1040.       case 1:                /* the object is pure binary */
  1041.         if (j || iif.iifP[i].pcrel) {
  1042.           fix_new_ns32k(frag_now,
  1043.                 (long)(memP-frag_now->fr_literal),
  1044.                 size,
  1045.                 0,
  1046.                 0,
  1047.                 iif.iifP[i].object,
  1048.                 iif.iifP[i].pcrel,
  1049.                 (char)size_so_far, /*iif.iifP[i].pcrel_adjust,*/
  1050.                 iif.iifP[i].im_disp,
  1051.                 j,
  1052.                 iif.iifP[i].bsr); /* sequent hack */
  1053.         } else {            /* good, just put them bytes out */
  1054.           switch (iif.iifP[i].im_disp) {
  1055.           case 0:
  1056.         md_number_to_chars(memP,iif.iifP[i].object,size);break;
  1057.           case 1:
  1058.         md_number_to_disp(memP,iif.iifP[i].object,size);break;
  1059.           default: as_fatal("iif convert internal pcrel/binary");
  1060.           }
  1061.         }
  1062.         memP+=size;
  1063.         rem_size-=size;
  1064.         break;
  1065.       case 2:    /* the object is a pointer at an expression, so unpack
  1066.                  it, note that bignums may result from the expression
  1067.              */
  1068.         if ((segment=evaluate_expr(&exprP,(char*)iif.iifP[i].object))==SEG_BIG || size==8) {
  1069.           if ((k=exprP.X_add_number)>0) { /* we have a bignum ie a quad */
  1070.         /* this can only happens in a long suffixed instruction */
  1071.         bzero(memP,size); /* size normally is 8 */
  1072.         if (k*2>size) as_warn("Bignum too big for long");
  1073.         if (k==3) memP+=2;
  1074.         for (l=0;k>0;k--,l+=2) {
  1075.           md_number_to_chars(memP+l,generic_bignum[l>>1],sizeof(LITTLENUM_TYPE));
  1076.         }
  1077.           } else { /* flonum */
  1078.         LITTLENUM_TYPE words[4];
  1079.  
  1080.         switch(size) {
  1081.         case 4:
  1082.           gen_to_words(words,2,8);
  1083.           md_number_to_imm(memP                       ,(long)words[0],sizeof(LITTLENUM_TYPE));
  1084.           md_number_to_imm(memP+sizeof(LITTLENUM_TYPE),(long)words[1],sizeof(LITTLENUM_TYPE));
  1085.           break;
  1086.         case 8:
  1087.           gen_to_words(words,4,11);
  1088.           md_number_to_imm(memP                         ,(long)words[0],sizeof(LITTLENUM_TYPE));
  1089.           md_number_to_imm(memP+sizeof(LITTLENUM_TYPE)  ,(long)words[1],sizeof(LITTLENUM_TYPE));
  1090.           md_number_to_imm(memP+2*sizeof(LITTLENUM_TYPE),(long)words[2],sizeof(LITTLENUM_TYPE));
  1091.           md_number_to_imm(memP+3*sizeof(LITTLENUM_TYPE),(long)words[3],sizeof(LITTLENUM_TYPE));
  1092.           break;
  1093.         }
  1094.           }
  1095.         memP+=size;
  1096.         rem_size-=size;
  1097.         break;
  1098.         }
  1099.         if (j ||
  1100.         exprP.X_add_symbol ||
  1101.         exprP.X_subtract_symbol ||
  1102.         iif.iifP[i].pcrel) {        /* fixit */
  1103.           /* the expression was undefined due to an undefined label */
  1104.           /* create a fix so we can fix the object later */
  1105.           exprP.X_add_number+=iif.iifP[i].object_adjust;
  1106.           fix_new_ns32k(frag_now,
  1107.                 (long)(memP-frag_now->fr_literal),
  1108.                 size,
  1109.                 exprP.X_add_symbol,
  1110.                 exprP.X_subtract_symbol,
  1111.                 exprP.X_add_number,
  1112.                 iif.iifP[i].pcrel,
  1113.                 (char)size_so_far, /*iif.iifP[i].pcrel_adjust,*/
  1114.                 iif.iifP[i].im_disp,
  1115.                 j,
  1116.                 iif.iifP[i].bsr); /* sequent hack */
  1117.           
  1118.         } else {            /* good, just put them bytes out */
  1119.           switch (iif.iifP[i].im_disp) {
  1120.           case 0:
  1121.         md_number_to_imm(memP,exprP.X_add_number,size);break;
  1122.           case 1:
  1123.         md_number_to_disp(memP,exprP.X_add_number,size);break;
  1124.           default: as_fatal("iif convert internal pcrel/pointer");
  1125.           }
  1126.         }
  1127.         memP+=size;
  1128.         rem_size-=size;
  1129.         break;
  1130.       default: as_fatal("Internal logic error in iif.iifP[n].type");
  1131.       }
  1132.       break;
  1133.     case 0:      /* To bad, the object may be undefined as far as its final
  1134.                 nsize in object memory is concerned. The size of the object
  1135.                 in objectmemory is not explicitly given.
  1136.                 If the object is defined its length can be determined and
  1137.                 a fix can replace the frag.
  1138.                 */
  1139.       {
  1140.         int temp;
  1141.         segment=evaluate_expr(&exprP,(char*)iif.iifP[i].object);
  1142.         if ((exprP.X_add_symbol || exprP.X_subtract_symbol) &&
  1143.         !iif.iifP[i].pcrel) { /* OVE: hack, clamp to 4 bytes */
  1144.           size=4; /* we dont wan't to frag this, use 4 so it reaches */
  1145.           fix_new_ns32k(frag_now,
  1146.                 (long)(memP-frag_now->fr_literal),
  1147.                 size,
  1148.                 exprP.X_add_symbol,
  1149.                 exprP.X_subtract_symbol,
  1150.                 exprP.X_add_number,
  1151.                 0, /* never iif.iifP[i].pcrel, */
  1152.                 (char)size_so_far, /*iif.iifP[i].pcrel_adjust,*/
  1153.                 1, /* always iif.iifP[i].im_disp, */
  1154.                 0,0);
  1155.           memP+=size;
  1156.           rem_size-=4;
  1157.           break; /* exit this absolute hack */
  1158.         }
  1159.  
  1160.         if (exprP.X_add_symbol || exprP.X_subtract_symbol) { /* frag it */
  1161.           if (exprP.X_subtract_symbol) { /* We cant relax this case */
  1162.         as_fatal("Can't relax difference");
  1163.           }
  1164.           else {
  1165.         /* at this stage we must undo some of the effect caused
  1166.            by frag_more, ie we must make sure that frag_var causes
  1167.            frag_new to creat a valid fix-size in the frag it`s closing
  1168.            */
  1169.         temp = -(rem_size-4);
  1170.         obstack_blank_fast(&frags,temp);
  1171.           /* we rewind none, some or all of the requested size we
  1172.              requested by the first frag_more for this iif chunk.
  1173.              Note: that we allocate 4 bytes to an object we NOT YET 
  1174.              know the size of, thus rem_size-4.
  1175.              */
  1176.         (void)frag_variant(rs_machine_dependent,
  1177.                    4,
  1178.                    0,
  1179.                    IND(BRANCH,UNDEF), /* expecting the worst */
  1180.                    exprP.X_add_symbol,
  1181.                    exprP.X_add_number,
  1182.                    (char*)inst_opcode,
  1183.                    (char)size_so_far, /*iif.iifP[i].pcrel_adjust);*/
  1184.                            iif.iifP[i].bsr); /* sequent linker hack */
  1185.         rem_size-=4;
  1186.         if (rem_size>0) {
  1187.           memP=frag_more(rem_size);
  1188.         }
  1189.           }
  1190.         }
  1191.         else {/* Double work, this is done in md_number_to_disp */
  1192.           exprP.X_add_number;
  1193.           if (-64<=exprP.X_add_number && exprP.X_add_number<=63) {
  1194.         size=1;
  1195.           } else {
  1196.         if (-8192<=exprP.X_add_number && exprP.X_add_number<=8191) {
  1197.           size=2;
  1198.         } else {
  1199.           if (-0x1f000000<=exprP.X_add_number &&
  1200.               exprP.X_add_number<=0x1fffffff)
  1201.           /* if (-0x40000000<=exprP.X_add_number &&
  1202.               exprP.X_add_number<=0x3fffffff) */
  1203.           {
  1204.             size=4;
  1205.           } else {
  1206.             as_warn("Displacement to large for :d");
  1207.             size=4;
  1208.           }
  1209.         }
  1210.           }
  1211.           /* rewind the bytes not used */
  1212.           temp = -(4-size);
  1213.           md_number_to_disp(memP,exprP.X_add_number,size);
  1214.           obstack_blank_fast(&frags,temp);
  1215.           memP+=size;
  1216.           rem_size-=4; /* we allocated this amount */
  1217.         }
  1218.       }
  1219.       break;
  1220.     default:
  1221.       as_fatal("Internal logic error in iif.iifP[].type");
  1222.     }
  1223.     size_so_far+=size;
  1224.     size=0;
  1225.       }
  1226.     }
  1227. }
  1228.  
  1229. void md_assemble(line)
  1230. char *line;
  1231. {
  1232.   freeptr=freeptr_static;
  1233.   parse(line,0); /* explode line to more fix form in iif */
  1234.   convert_iif(); /* convert iif to frags, fix's etc */
  1235. #ifdef SHOW_NUM
  1236.   printf(" \t\t\t%s\n",line);
  1237. #endif
  1238. }
  1239.  
  1240.  
  1241. void md_begin()
  1242. {
  1243.   /* build a hashtable of the instructions */
  1244.   register struct ns32k_opcode *ptr;
  1245.   register char *stat;
  1246.   inst_hash_handle=hash_new();
  1247.   for (ptr=ns32k_opcodes;ptr<endop;ptr++) {
  1248.     if (*(stat=hash_insert(inst_hash_handle,ptr->name,(char*)ptr))) {
  1249.     as_fatal("Can't hash %s: %s",ptr->name,stat); /*fatal*/
  1250.       exit(0);
  1251.     }
  1252.   }
  1253.   freeptr_static=(char*)malloc(PRIVATE_SIZE); /* some private space please! */
  1254. }
  1255.  
  1256.  
  1257. void
  1258. md_end()
  1259. {
  1260.   free(freeptr_static);
  1261. }
  1262.  
  1263. /* Must be equal to MAX_PRECISON in atof-ieee.c */
  1264. #define MAX_LITTLENUMS 6
  1265.  
  1266. /* Turn the string pointed to by litP into a floating point constant of type
  1267.    type, and emit the appropriate bytes.  The number of LITTLENUMS emitted
  1268.    is stored in *sizeP .  An error message is returned, or NULL on OK.
  1269.  */
  1270. char *
  1271. md_atof(type,litP,sizeP)
  1272. char type;
  1273. char *litP;
  1274. int *sizeP;
  1275. {
  1276.     int    prec;
  1277.     LITTLENUM_TYPE words[MAX_LITTLENUMS];
  1278.     LITTLENUM_TYPE *wordP;
  1279.     char    *t;
  1280.     char    *atof_ieee();
  1281.  
  1282.     switch(type) {
  1283.     case 'f':
  1284.         prec = 2;
  1285.         break;
  1286.  
  1287.     case 'd':
  1288.         prec = 4;
  1289.         break;
  1290.     default:
  1291.         *sizeP=0;
  1292.         return "Bad call to MD_ATOF()";
  1293.     }
  1294.     t=atof_ieee(input_line_pointer,type,words);
  1295.     if(t)
  1296.         input_line_pointer=t;
  1297.  
  1298.     *sizeP=prec * sizeof(LITTLENUM_TYPE);
  1299.     for(wordP=words+prec;prec--;) {
  1300.         md_number_to_chars(litP,(long)(*--wordP),sizeof(LITTLENUM_TYPE));
  1301.         litP+=sizeof(LITTLENUM_TYPE);
  1302.     }
  1303.     return "";    /* Someone should teach Dean about null pointers */
  1304. }
  1305.  
  1306. /* Convert number to chars in correct order */
  1307.  
  1308. void
  1309. md_number_to_chars (buf, value, nbytes)
  1310.      char    *buf;
  1311.      long int    value;
  1312.      int    nbytes;
  1313. {
  1314.   while (nbytes--)
  1315.     {
  1316. #ifdef SHOW_NUM
  1317.       printf("%x ",value & 0xff);
  1318. #endif
  1319.       *buf++ = value;        /* Lint wants & MASK_CHAR. */
  1320.       value >>= BITS_PER_CHAR;
  1321.     }
  1322. }
  1323. /* Convert number to chars in correct order */
  1324.  
  1325.  
  1326.  
  1327. /* This is a variant of md_numbers_to_chars. The reason for its' existence
  1328.    is the fact that ns32k uses Huffman coded displacements. This implies
  1329.    that the bit order is reversed in displacements and that they are prefixed
  1330.    with a size-tag.
  1331.  
  1332.    binary: msb -> lsb    0xxxxxxx                byte
  1333.                10xxxxxx xxxxxxxx            word
  1334.                11xxxxxx xxxxxxxx xxxxxxxx xxxxxxxx    double word
  1335.           
  1336.    This must be taken care of and we do it here!           
  1337.  */
  1338. void md_number_to_disp(buf,val,n)
  1339.      char    *buf;
  1340.      long    val;
  1341.      char       n;
  1342.   switch(n) {
  1343.   case 1:
  1344.     if (val < -64 || val > 63)
  1345.       as_warn("Byte displacement out of range.  line number not valid");
  1346.     val&=0x7f;
  1347. #ifdef SHOW_NUM
  1348.         printf("%x ",val & 0xff);
  1349. #endif
  1350.     *buf++=val;
  1351.     break;
  1352.   case 2:
  1353.     if (val < -8192 || val > 8191)
  1354.       as_warn("Word displacement out of range.  line number not valid");
  1355.     val&=0x3fff;
  1356.     val|=0x8000;
  1357. #ifdef SHOW_NUM
  1358.         printf("%x ",val>>8 & 0xff);
  1359. #endif
  1360.     *buf++=(val>>8);
  1361. #ifdef SHOW_NUM
  1362.         printf("%x ",val & 0xff);
  1363. #endif
  1364.     *buf++=val;
  1365.     break;
  1366.   case 4:
  1367.     if (val < -0x1f000000 || val >= 0x20000000)
  1368.     /* if (val < -0x20000000 || val >= 0x20000000) */
  1369.       as_warn("Double word displacement out of range");
  1370.     val|=0xc0000000;
  1371. #ifdef SHOW_NUM
  1372.         printf("%x ",val>>24 & 0xff);
  1373. #endif
  1374.     *buf++=(val>>24);
  1375. #ifdef SHOW_NUM
  1376.         printf("%x ",val>>16 & 0xff);
  1377. #endif
  1378.     *buf++=(val>>16);
  1379. #ifdef SHOW_NUM
  1380.         printf("%x ",val>>8 & 0xff);
  1381. #endif
  1382.     *buf++=(val>>8);
  1383. #ifdef SHOW_NUM
  1384.         printf("%x ",val & 0xff);
  1385. #endif
  1386.     *buf++=val;
  1387.     break;
  1388.   default:
  1389.     as_fatal("Internal logic error");
  1390.   }
  1391. }
  1392. void md_number_to_imm(buf,val,n)
  1393.      char    *buf;
  1394.      long    val;
  1395.      char       n;
  1396.   switch(n) {
  1397.   case 1:
  1398. #ifdef SHOW_NUM
  1399.     printf("%x ",val & 0xff);
  1400. #endif
  1401.     *buf++=val;
  1402.     break;
  1403.   case 2:
  1404. #ifdef SHOW_NUM
  1405.         printf("%x ",val>>8 & 0xff);
  1406. #endif
  1407.     *buf++=(val>>8);
  1408. #ifdef SHOW_NUM
  1409.         printf("%x ",val & 0xff);
  1410. #endif
  1411.     *buf++=val;
  1412.     break;
  1413.   case 4:
  1414. #ifdef SHOW_NUM
  1415.         printf("%x ",val>>24 & 0xff);
  1416. #endif
  1417.     *buf++=(val>>24);
  1418. #ifdef SHOW_NUM
  1419.         printf("%x ",val>>16 & 0xff);
  1420. #endif
  1421.     *buf++=(val>>16);
  1422. #ifdef SHOW_NUM
  1423.         printf("%x ",val>>8 & 0xff);
  1424. #endif
  1425.     *buf++=(val>>8);
  1426. #ifdef SHOW_NUM
  1427.         printf("%x ",val & 0xff);
  1428. #endif
  1429.     *buf++=val;
  1430.     break;
  1431.   default:
  1432.     as_fatal("Internal logic error");
  1433.   }
  1434. }
  1435. /* the bit-field entries in the relocation_info struct plays hell 
  1436.    with the byte-order problems of cross-assembly.  So as a hack,
  1437.    I added this mach. dependent ri twiddler.  Ugly, but it gets
  1438.    you there. -KWK */
  1439. /* OVE: on a ns32k the twiddling continues at an even deeper level
  1440.    here we have to distinguish between displacements and immediates.
  1441.  
  1442.    The sequent has a bit for this. It also has a bit for relocobjects that
  1443.    points at the target for a bsr (BranchSubRoutine) !?!?!?!
  1444.  
  1445.    Using [] is importable but fast!! still, its rather funny :-)
  1446.    This md_ri.... is tailored for sequent.
  1447.    */
  1448.  
  1449. void md_ri_to_chars(ri_p, ri)
  1450.      struct relocation_info *ri_p, ri;
  1451. {    
  1452.   if (ri.r_bsr) {ri.r_pcrel=0;} /* sequent seems to want this */
  1453.   md_number_to_chars((char*)ri_p, ri.r_address, sizeof(ri.r_address));
  1454.   md_number_to_chars((char*)ri_p+4,
  1455.              (long)(ri.r_symbolnum       ) |
  1456.              (long)(ri.r_pcrel     << 24 ) |
  1457.              (long)(ri.r_length       << 25 ) |
  1458.              (long)(ri.r_extern       << 27 ) |
  1459.              (long)(ri.r_bsr       << 28 ) |
  1460.              (long)(ri.r_disp       << 29 ),
  1461.              4);
  1462.   /* the first and second md_number_to_chars never overlaps (32bit cpu case) */
  1463. }
  1464.  
  1465. /* fast bitfiddling support */
  1466. /* mask used to zero bitfield before oring in the true field */
  1467.  
  1468. static unsigned long l_mask[]={    0xffffffff, 0xfffffffe, 0xfffffffc, 0xfffffff8,
  1469.                 0xfffffff0, 0xffffffe0, 0xffffffc0, 0xffffff80,
  1470.                 0xffffff00, 0xfffffe00, 0xfffffc00, 0xfffff800,
  1471.                 0xfffff000, 0xffffe000, 0xffffc000, 0xffff8000,
  1472.                 0xffff0000, 0xfffe0000, 0xfffc0000, 0xfff80000,
  1473.                 0xfff00000, 0xffe00000, 0xffc00000, 0xff800000,
  1474.                 0xff000000, 0xfe000000, 0xfc000000, 0xf8000000,
  1475.                 0xf0000000, 0xe0000000, 0xc0000000, 0x80000000,
  1476.                 };
  1477. static unsigned long r_mask[]={    0x00000000, 0x00000001, 0x00000003, 0x00000007,
  1478.                 0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f,
  1479.                 0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff,
  1480.                 0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff,
  1481.                 0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff,
  1482.                 0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff,
  1483.                 0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff,
  1484.                 0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff,
  1485.                 };
  1486. #define MASK_BITS 31
  1487. /* Insert bitfield described by field_ptr and val at buf
  1488.    This routine is written for modification of the first 4 bytes pointed
  1489.    to by buf, to yield speed.
  1490.    The ifdef stuff is for selection between a ns32k-dependent routine
  1491.    and a general version. (My advice: use the general version!)
  1492.  */
  1493.  
  1494. void md_number_to_field(buf,val,field_ptr)
  1495.      register char    *buf;
  1496.      register long    val;
  1497.      register bit_fixS  *field_ptr;
  1498.   register unsigned long object;
  1499.   register unsigned long mask;
  1500. /* define ENDIAN on a ns32k machine */
  1501. #ifdef ENDIAN
  1502.   register unsigned long *mem_ptr;
  1503. #else
  1504.   register char *mem_ptr;
  1505. #endif
  1506.   if (field_ptr->fx_bit_min<=val && val<=field_ptr->fx_bit_max) {
  1507. #ifdef ENDIAN
  1508.     if (field_ptr->fx_bit_base) { /* override buf */
  1509.       mem_ptr=(unsigned long*)field_ptr->fx_bit_base;
  1510.     } else {
  1511.       mem_ptr=(unsigned long*)buf;
  1512.     }
  1513. #else
  1514.     if (field_ptr->fx_bit_base) { /* override buf */
  1515.       mem_ptr=(char*)field_ptr->fx_bit_base;
  1516.     } else {
  1517.       mem_ptr=buf;
  1518.     }
  1519. #endif
  1520.     mem_ptr+=field_ptr->fx_bit_base_adj;
  1521. #ifdef ENDIAN  /* we have a nice ns32k machine with lowbyte at low-physical mem */
  1522.     object = *mem_ptr; /* get some bytes */
  1523. #else /* OVE Goof! the machine is a m68k or dito */
  1524.       /* That takes more byte fiddling */
  1525.     object=0;
  1526.     object|=mem_ptr[3] & 0xff;
  1527.     object<<=8;
  1528.     object|=mem_ptr[2] & 0xff;
  1529.     object<<=8;
  1530.     object|=mem_ptr[1] & 0xff;
  1531.     object<<=8;
  1532.     object|=mem_ptr[0] & 0xff;
  1533. #endif
  1534.     mask=0;
  1535.     mask|=(r_mask[field_ptr->fx_bit_offset]);
  1536.     mask|=(l_mask[field_ptr->fx_bit_offset+field_ptr->fx_bit_size]);
  1537.     object&=mask;
  1538.     val+=field_ptr->fx_bit_add;
  1539.     object|=((val<<field_ptr->fx_bit_offset) & (mask ^ 0xffffffff));
  1540. #ifdef ENDIAN
  1541.     *mem_ptr=object;
  1542. #else
  1543.     mem_ptr[0]=(char)object;
  1544.     object>>=8;
  1545.     mem_ptr[1]=(char)object;
  1546.     object>>=8;
  1547.     mem_ptr[2]=(char)object;
  1548.     object>>=8;
  1549.     mem_ptr[3]=(char)object;
  1550. #endif
  1551.   } else {
  1552.     as_warn("Bit field out of range");
  1553.   }
  1554. }
  1555.  
  1556. /* Convert a relaxed displacement to dito in final output */
  1557.  
  1558. void
  1559.   md_convert_frag(fragP)
  1560. register fragS *fragP;
  1561. {
  1562.   long disp;
  1563.   long ext;
  1564.  
  1565.   /* Address in gas core of the place to store the displacement.  */
  1566.   register char *buffer_address = fragP -> fr_fix + fragP -> fr_literal;
  1567.   /* Address in object code of the displacement.  */
  1568.   register int object_address = fragP -> fr_fix + fragP -> fr_address;
  1569.  
  1570.   know(fragP->fr_symbol);
  1571.  
  1572.   /* The displacement of the address, from current location.  */
  1573.   disp = (fragP->fr_symbol->sy_value + fragP->fr_offset) - object_address;
  1574.   disp+= fragP->fr_pcrel_adjust;
  1575.  
  1576.   switch(fragP->fr_subtype) {
  1577.   case IND(BRANCH,BYTE):
  1578.     ext=1;
  1579.     break;
  1580.   case IND(BRANCH,WORD):
  1581.     ext=2;
  1582.     break;
  1583.   case IND(BRANCH,DOUBLE):
  1584.     ext=4;
  1585.     break;
  1586.   }
  1587.   if(ext) {
  1588.     md_number_to_disp(buffer_address,(long)disp,(int)ext);
  1589.     fragP->fr_fix+=ext;
  1590.   }
  1591. }
  1592.  
  1593.  
  1594.  
  1595. /* This function returns the estimated size a variable object will occupy,
  1596.    one can say that we tries to guess the size of the objects before we
  1597.    actually know it */
  1598.    
  1599. md_estimate_size_before_relax(fragP,segtype)
  1600.      register fragS *fragP;
  1601. {
  1602.   int    old_fix;
  1603.   old_fix=fragP->fr_fix;
  1604.   switch(fragP->fr_subtype) {
  1605.   case IND(BRANCH,UNDEF):
  1606.     if((fragP->fr_symbol->sy_type&N_TYPE)==segtype) {
  1607.       /* the symbol has been assigned a value */
  1608.       fragP->fr_subtype=IND(BRANCH,BYTE);
  1609.     } else {
  1610.       /* we don't relax symbols defined in an other segment
  1611.          the thing to do is to assume the object will occupy 4 bytes */
  1612.       fix_new_ns32k(fragP,
  1613.             (int)(fragP->fr_fix),
  1614.             4,
  1615.             fragP->fr_symbol,
  1616.             (symbolS *)0,
  1617.             fragP->fr_offset,
  1618.             1,
  1619.             fragP->fr_pcrel_adjust,
  1620.             1,
  1621.             0,
  1622.             fragP->fr_bsr); /*sequent hack */
  1623.       fragP->fr_fix+=4;
  1624.       /* fragP->fr_opcode[1]=0xff; */
  1625.       frag_wane(fragP);
  1626.       break;
  1627.     }
  1628.   case IND(BRANCH,BYTE):
  1629.     fragP->fr_var+=1;
  1630.     break;
  1631.   default:
  1632.     break;
  1633.   }
  1634.   return fragP->fr_var + fragP->fr_fix - old_fix;
  1635. }
  1636.  
  1637. int md_short_jump_size = 3;
  1638. int md_long_jump_size  = 5;
  1639.  
  1640. void
  1641. md_create_short_jump(ptr,from_addr,to_addr,frag,to_symbol)
  1642. char    *ptr;
  1643. long    from_addr,
  1644.     to_addr;
  1645. fragS    *frag;
  1646. symbolS    *to_symbol;
  1647. {
  1648.     long offset;
  1649.  
  1650.     offset = to_addr - from_addr;
  1651.     md_number_to_chars(ptr, (long)0xEA  ,1);
  1652.     md_number_to_disp(ptr+1,(long)offset,2);
  1653. }
  1654.  
  1655. void
  1656. md_create_long_jump(ptr,from_addr,to_addr,frag,to_symbol)
  1657. char    *ptr;
  1658. long    from_addr,
  1659.     to_addr;
  1660. fragS    *frag;
  1661. symbolS    *to_symbol;
  1662. {
  1663.     long offset;
  1664.  
  1665.     offset= to_addr - from_addr;
  1666.     md_number_to_chars(ptr, (long)0xEA,  2);
  1667.     md_number_to_disp(ptr+2,(long)offset,4);
  1668. }
  1669.  
  1670. /* JF this is a new function to parse machine-dep options */
  1671. int
  1672. md_parse_option(argP,cntP,vecP)
  1673. char **argP;
  1674. int *cntP;
  1675. char ***vecP;
  1676. {
  1677.     switch(**argP) {
  1678.     case 'm':
  1679.       (*argP)++;
  1680.  
  1681.       if(!strcmp(*argP,"32032")) {
  1682.         cpureg = cpureg_032;
  1683.         mmureg = mmureg_032;
  1684.       } else if(!strcmp(*argP, "32532")) {
  1685.         cpureg = cpureg_532;
  1686.         mmureg = mmureg_532;
  1687.       } else
  1688.         as_warn("Unknown -m option ignored");
  1689.  
  1690.       while(**argP)
  1691.         (*argP)++;
  1692.       break;
  1693.  
  1694.     default:
  1695.       return 0;
  1696.     }
  1697.     return 1;
  1698. }
  1699.  
  1700. /*
  1701.  *            bit_fix_new()
  1702.  *
  1703.  * Create a bit_fixS in obstack 'notes'.
  1704.  * This struct is used to profile the normal fix. If the bit_fixP is a
  1705.  * valid pointer (not NULL) the bit_fix data will be used to format the fix.
  1706.  */
  1707. bit_fixS *
  1708. bit_fix_new (size,offset,min,max,add,base_type,base_adj)
  1709.      char    size;        /* Length of bitfield        */
  1710.      char    offset;        /* Bit offset to bitfield    */
  1711.      long    base_type;    /* 0 or 1, if 1 it's exploded to opcode ptr */
  1712.      long    base_adj;
  1713.      long    min;        /* Signextended min for bitfield */
  1714.      long    max;        /* Signextended max for bitfield */
  1715.      long    add;        /* Add mask, used for huffman prefix */
  1716. {
  1717.   register bit_fixS *    bit_fixP;
  1718.  
  1719.   bit_fixP = (bit_fixS *)obstack_alloc(¬es,sizeof(bit_fixS));
  1720.  
  1721.   bit_fixP -> fx_bit_size    = size;
  1722.   bit_fixP -> fx_bit_offset    = offset;
  1723.   bit_fixP -> fx_bit_base    = base_type;
  1724.   bit_fixP -> fx_bit_base_adj    = base_adj;
  1725.   bit_fixP -> fx_bit_max    = max;
  1726.   bit_fixP -> fx_bit_min    = min;
  1727.   bit_fixP -> fx_bit_add    = add;
  1728.  
  1729.   return bit_fixP;
  1730. }
  1731.  
  1732. void
  1733. fix_new_ns32k (frag, where, size, add_symbol, sub_symbol, offset, pcrel,
  1734.      pcrel_adjust, im_disp, bit_fixP, bsr)
  1735.      fragS *    frag;        /* Which frag? */
  1736.      int    where;        /* Where in that frag? */
  1737.      short int    size;        /* 1, 2  or 4 usually. */
  1738.      symbolS *    add_symbol;    /* X_add_symbol. */
  1739.      symbolS *    sub_symbol;    /* X_subtract_symbol. */
  1740.      long int    offset;        /* X_add_number. */
  1741.      int    pcrel;        /* TRUE if PC-relative relocation. */
  1742.      char    pcrel_adjust;    /* not zero if adjustment of pcrel offset is needed */
  1743.      char    im_disp;    /* true if the value to write is a displacement */
  1744.      bit_fixS *bit_fixP;    /* pointer at struct of bit_fix's, ignored if NULL */
  1745.      char    bsr;        /* sequent-linker-hack: 1 when relocobject is a bsr */
  1746.      
  1747. {
  1748.   register fixS *    fixP;
  1749.  
  1750.   fixP = (fixS *)obstack_alloc(¬es,sizeof(fixS));
  1751.   fixP -> fx_frag        = frag;
  1752.   fixP -> fx_where        = where;
  1753.   fixP -> fx_size        = size;
  1754.   fixP -> fx_addsy        = add_symbol;
  1755.   fixP -> fx_subsy        = sub_symbol;
  1756.   fixP -> fx_offset        = offset;
  1757.   fixP -> fx_pcrel        = pcrel;
  1758.   fixP -> fx_pcrel_adjust    = pcrel_adjust;
  1759.   fixP -> fx_im_disp        = im_disp;
  1760.   fixP -> fx_bit_fixP        = bit_fixP;
  1761.   fixP -> fx_bsr        = bsr;
  1762.   fixP -> fx_next        = * seg_fix_rootP;
  1763.  
  1764.   * seg_fix_rootP = fixP;
  1765. }
  1766.