home *** CD-ROM | disk | FTP | other *** search
/ NeXTSTEP 3.2 (Developer) / NS_dev_3.2.iso / NextDeveloper / Source / GNU / cctools / as / i860.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-09-06  |  29.2 KB  |  1,268 lines

  1. /* i860.c -- Assemble for the i860
  2.    Copyright (C) 1989 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.  
  21. #include <stdio.h>
  22. #include <ctype.h>
  23.  
  24. #include "i860-opcode.h"
  25. #include "as.h"
  26. #include "frags.h"
  27. #include "struc-symbol.h"
  28. #include "flonum.h"
  29. #include "expr.h"
  30. #include "hash.h"
  31. #include "md.h"
  32. #include "write.h"
  33. #include "read.h"
  34. #include "symbols.h"
  35. #include "i860.h"
  36.  
  37. void md_begin();
  38. void md_end();
  39. void md_number_to_chars();
  40. void md_insn_to_chars();
  41. void md_assemble();
  42. char *md_atof();
  43. void md_convert_frag();
  44. void md_create_short_jump();
  45. void md_create_long_jump();
  46. int  md_estimate_size_before_relax();
  47. void md_number_to_imm();
  48. void md_number_to_disp();
  49. void md_number_to_field();
  50. void md_ri_to_chars();
  51. void emit_relocations();
  52. static int i860_ip();
  53.  
  54. const relax_typeS md_relax_table[] = { 0 };
  55.  
  56. /* handle of the OPCODE hash table */
  57. static struct hash_control *op_hash = NULL;
  58.  
  59. static void s_dual(), s_i860_align(), s_i860_org();
  60. extern void s_globl(), s_line(), s_space(), big_cons(), stringer();
  61.  
  62. const
  63. pseudo_typeS
  64. md_pseudo_table[] = {
  65.     { "align",        s_i860_align,    0 },    /* Alignment is in bytes */
  66.     { "blkb",        s_space,    0 },    /* Reserve space, in bytes */
  67.     { "dual",        s_dual,    1 },        /* Dual insn mode crock */
  68.     { "enddual",    s_dual,    0 },
  69.     { "extern",    s_globl,    0    },    /* as860 equiv of .globl */
  70.     { "ln",    s_line,        0    },    /* as860 equiv of .line */
  71.     { "org",    s_i860_org,        0    },
  72. #ifndef NeXT
  73.     { "quad",    big_cons,    16    },    /* A quad is 16 bytes on 860 */
  74. #endif NeXT
  75.     { "string",    stringer,    1    },    /* as860 equiv of .asciz */
  76.     { NULL,         0,          0 },
  77. };
  78.  
  79. static int dual_insn_mode = 0;
  80.  
  81. int md_short_jump_size = 4;
  82. int md_long_jump_size = 4;
  83. int omagic  =  (0x14D << 16) | OMAGIC;  /* Magic number for header */
  84.  
  85. /* This array holds the chars that always start a comment.  If the
  86.     pre-processor is disabled, these aren't very useful */
  87. char comment_chars[] = "|!";
  88.  
  89. /* This array holds the chars that only start a comment at the beginning of
  90.    a line.  If the line seems to have the form '# 123 filename'
  91.    .line and .file directives will appear in the pre-processed output */
  92. /* Note that input_file.c hand checks for '#' at the beginning of the
  93.    first line of the input file.  This is because the compiler outputs
  94.    #NO_APP at the beginning of its output. */
  95. /* Also note that '/*' will always start a comment */
  96. char line_comment_chars[] = "#";
  97.  
  98. /* Chars that can be used to separate mant from exp in floating point nums */
  99. char EXP_CHARS[] = "eE";
  100.  
  101. /* Chars that mean this number is a floating point constant */
  102. /* As in 0f12.456 */
  103. /* or    0d1.2345e12 */
  104. char FLT_CHARS[] = "rRsSfFdDxXpP";
  105.  
  106. /* Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be
  107.    changed in read.c .  Ideally it shouldn't have to know about it at all,
  108.    but nothing is ideal around here.
  109.  */
  110. int size_reloc_info = sizeof(struct relocation_info);
  111.  
  112. static unsigned char octal[256];
  113. #define isoctal(c)  octal[c]
  114. static unsigned char toHex[256];
  115.  
  116. /* Local fatal error flag.  Used to bomb assembler in md_end after scanning input */
  117. static int I860_errors;
  118.  
  119. static int insn_count;    /* Track insns assembled, as a word count */
  120.  
  121. struct i860_it {
  122.     char    *error;
  123.     unsigned long opcode;
  124.     struct nlist *nlistp;
  125.     expressionS exp;
  126.     int pcrel;
  127.     enum reloc_type_i860 reloc;
  128. } the_insn, set_insn;
  129.  
  130. #ifdef __STDC__
  131. static void print_insn(struct i860_it *insn);
  132. static int getExpression(char *str);
  133. #else
  134. static void print_insn();
  135. static int getExpression();
  136. #endif
  137. static char *expr_end;
  138. static int special_case;
  139.  
  140. #define SPECIAL_CASE_SET    1
  141.  
  142. /* Flags returned by i860_ip() */
  143. #define INSERT_NOP    0x00000001
  144.  
  145.  static void
  146. s_dual(mode)
  147.     int mode;
  148. {
  149.     dual_insn_mode = mode;
  150. }
  151.  
  152.  
  153. static void
  154. s_i860_align()
  155. {
  156.     register unsigned int temp;
  157.     register long int temp_fill;
  158.     unsigned int i;
  159.     unsigned int bytes;
  160.     char *toP;
  161.  
  162.     bytes = temp = get_absolute_expression ();
  163. #define MAX_ALIGNMENT (1 << 15)
  164.     if ( temp > MAX_ALIGNMENT ) {
  165.     as_warn("Alignment too large: %d. assumed.", temp = MAX_ALIGNMENT);
  166.     }
  167.  
  168.     /*
  169.      * For the i860, `.align (1<<n)' actually means `.align n'
  170.      * so we have to convert it.
  171.      */
  172.     if (temp != 0) {
  173.     for (i = 0; (temp & 1) == 0; temp >>= 1, ++i)
  174.         ;
  175.     }
  176.     if (temp != 1) {
  177.     as_warn("Alignment not a power of 2");
  178.     }
  179.     temp = i;
  180.     if (*input_line_pointer == ',') {
  181.     input_line_pointer ++;
  182.     temp_fill = get_absolute_expression ();
  183.     } else {
  184.         if ( now_seg == SEG_TEXT )
  185.             temp_fill = OP_NOP;
  186.     else
  187.         temp_fill = 0;
  188.     }
  189.     if ( now_seg == SEG_TEXT )    /* emit NOPs! */
  190.     {    /* Grow the code frag as needed and dump nops into it. */
  191.     if ( bytes & 3 )
  192.         as_warn( "Instruction alignment must be a multiple of 4." );
  193.     bytes &= ~3;
  194.     /* This is really tacky, but works for a fixed width insn machine */
  195.         while ( bytes && ((insn_count * 4) % bytes) != 0 ) 
  196.     {
  197.         toP = frag_more(4);    /* Add an instruction */
  198.         /* put out the opcode */
  199.         md_insn_to_chars(toP, temp_fill, 4);    /* Fill instruction */
  200.         insn_count++;
  201.     }
  202.         /* Clean up */
  203.     demand_empty_rest_of_line();
  204.     return;
  205.     }
  206.     /* Only make a frag if we HAVE to. . . */
  207.     if (temp && ! need_pass_2) {
  208.     frag_align (temp, (int)temp_fill);
  209.     }
  210.     demand_empty_rest_of_line();
  211.     return;
  212. }
  213.  
  214.  static void
  215. s_i860_org()
  216. {
  217.     register segT segment;
  218.     expressionS exp;
  219.     register long int temp_fill;
  220.     register char *p;
  221.     extern segT get_known_segmented_expression();
  222.  
  223. /*
  224.  * Don't believe the documentation of BSD 4.2 AS.
  225.  * There is no such thing as a sub-segment-relative origin.
  226.  * Any absolute origin is given a warning, then assumed to be segment-relative.
  227.  * Any segmented origin expression ("foo+42") had better be in the right
  228.  * segment or the .org is ignored.
  229.  *
  230.  * BSD 4.2 AS warns if you try to .org backwards. We cannot because we
  231.  * never know sub-segment sizes when we are reading code.
  232.  * BSD will crash trying to emit -ve numbers of filler bytes in certain
  233.  * .orgs. We don't crash, but see as-write for that code.
  234.  */
  235. /*
  236.  * Don't make frag if need_pass_2==TRUE.
  237.  */
  238.     segment = get_known_segmented_expression(& exp);
  239.     if ( *input_line_pointer == ',' ) {
  240.         input_line_pointer ++;
  241.         temp_fill = get_absolute_expression ();
  242.     } else
  243.         temp_fill = 0;
  244.     if ( ! need_pass_2 ) {
  245.         if (segment != now_seg && segment != SEG_ABSOLUTE)
  246.             as_warn("Illegal segment \"%s\". Segment \"%s\" assumed.",
  247.  seg_name [(int) segment], seg_name [(int) now_seg]);
  248.          if ( exp.X_add_symbol != NULL )
  249.             as_warn("Symbol relative .org may corrupt alignment.");
  250.         else if ( exp.X_add_number & 3 )
  251.         {
  252.             exp.X_add_number &= ~3;
  253.             as_warn(".org not on instruction boundry. Adjusted to \".org %d\"",
  254.                 exp.X_add_number);
  255.         }
  256.         if ( exp.X_add_symbol == NULL )
  257.             insn_count = exp.X_add_number >> 2;
  258.         p = frag_var (rs_org, 1, 1, (relax_substateT)0, exp . X_add_symbol,
  259.  exp . X_add_number, (char *)0);
  260.         * p = temp_fill;
  261.     } /* if (ok to make frag) */
  262.     demand_empty_rest_of_line();
  263. }
  264.  
  265.  
  266. /*
  267.  * This function is called once, at assembler startup time.  This should
  268.  * set up all the tables, etc that the MD part of the assembler needs
  269.  */
  270. void
  271. md_begin()
  272. {
  273.     register char *retval = NULL;
  274.     register int i;
  275.     int j = 0;
  276.  
  277.     insn_count = 0;
  278.     if ((op_hash = hash_new()) == NULL)
  279.     as_fatal("Virtual memory exhausted");
  280.  
  281.     for (i = 0; i < NUMOPCODES; ++i) {
  282.     if (~i860_opcodes[i].mask & i860_opcodes[i].match) {
  283.         printf("bad opcode - `%s %s'\n",
  284.         i860_opcodes[i].name, i860_opcodes[i].args);
  285.         ++j;
  286.     }
  287.     }
  288.  
  289.     if (j)
  290.     exit(1);
  291.  
  292.     for (i = 0; i < NUMOPCODES; ++i) {
  293.       retval = hash_insert(op_hash, i860_opcodes[i].name, &i860_opcodes[i]);
  294.       if(retval && *retval) {
  295.       as_fatal("Internal Error:  Can't hash %s: %s",
  296.         i860_opcodes[i].name, retval);
  297.       }
  298.       while (!i860_opcodes[i].last)
  299.       ++i;
  300.     }
  301.     for (i = '0'; i < '8'; ++i)
  302.     octal[i] = 1;
  303.     for (i = '0'; i <= '9'; ++i)
  304.     toHex[i] = i - '0';
  305.     for (i = 'a'; i <= 'f'; ++i)
  306.     toHex[i] = i + 10 - 'a';
  307.     for (i = 'A'; i <= 'F'; ++i)
  308.     toHex[i] = i + 10 - 'A';
  309.  
  310.     I860_errors = 0;
  311.     return;
  312. }
  313.  
  314. void
  315. md_end()
  316. {
  317.     if ( I860_errors )
  318.     {
  319.         fprintf( stderr, "%d fatal %s encountered during assembly.\n", I860_errors,
  320.         (I860_errors == 1 ? "error" : "errors") );
  321.         exit( 42 );    /* Fatal errors seen during assembly */
  322.     }
  323.  
  324.     return;
  325. }
  326.  
  327. void
  328. md_assemble(str)
  329.     char *str;
  330. {
  331.     char *toP;
  332.     int flags;
  333.  
  334.     assert(str);
  335.     flags = i860_ip(str);
  336.     if ( flags & INSERT_NOP )
  337.     {
  338.         toP = frag_more(4);
  339.         /* put out the opcode */
  340.         md_insn_to_chars(toP, OP_NOP, 4);
  341.     ++insn_count;
  342.     }
  343.     toP = frag_more(4);
  344.     /* put out the opcode */
  345.     md_insn_to_chars(toP, the_insn.opcode, 4);
  346.     ++insn_count;
  347.  
  348.     /* put out the symbol-dependent stuff */
  349.     if (the_insn.reloc != NO_RELOC) {
  350.     fix_new(
  351.         frag_now,                           /* which frag */
  352.         (toP - frag_now->fr_literal), /* where */
  353.         4,                                  /* size */
  354.         the_insn.exp.X_add_symbol,
  355.         the_insn.exp.X_subtract_symbol,
  356.         the_insn.exp.X_add_number,
  357.         the_insn.pcrel,
  358.         the_insn.reloc
  359.     );
  360.     }
  361. }
  362.  
  363. static int
  364. i860_ip(str)
  365.     char *str;
  366. {
  367.     char *s;
  368.     char *op;
  369.     const char *args;
  370.     char c;
  371.     unsigned long i;
  372.     struct i860_opcode *insn;
  373.     char *argsStart;
  374.     char *s1;
  375.     unsigned long   opcode;
  376.     unsigned int mask;
  377.     int this_insn_is_dual = 0;
  378.     int adjustment;
  379.     int    align_mask;
  380.     int match = FALSE;
  381.     int comma = 0;
  382.     int flags = 0;
  383.     static int expect_int_insn;    /* Tracking for fp/int insns in dual mode. */
  384.  
  385.     /* Advance s to end of opcode */
  386.     for (s = str; islower(*s) || *s == '.' || isdigit(*s); ++s)
  387.     ;
  388.     switch (*s) {
  389.  
  390.     case '\0':
  391.     break;
  392.  
  393.     case ',':
  394.     comma = 1;
  395.  
  396.     /*FALLTHROUGH*/
  397.  
  398.     case ' ':
  399.     case '\t':
  400.     *s++ = '\0';
  401.     break;
  402.  
  403.     default:
  404.         as_warn("Unknown opcode: `%s'", str);
  405.         exit(1);
  406.     }
  407.     /* Code to sniff for 'd.' prefix here and flag for dual insn mode */
  408.     op = str;
  409.     if ( *op == 'd' && *(op + 1) == '.' )
  410.     {
  411.         op += 2;
  412.     this_insn_is_dual = 1;
  413.     }
  414.         
  415.     if ((insn = (struct i860_opcode *) hash_find(op_hash, op)) == NULL) {
  416.     as_warn("Unknown instruction or format: `%s'.", str);
  417.     bzero(&the_insn, sizeof(the_insn));    /* Patch in no-op to hold alignment */
  418.     the_insn.reloc = NO_RELOC;
  419.     the_insn.opcode = OP_NOP;
  420.     ++I860_errors;                /* Flag as fatal error */
  421.     return flags;
  422.     }
  423.     if (comma) {
  424.     *--s = ',';
  425.     }
  426.     argsStart = s;
  427.     for (;;) {
  428.     opcode = insn->match;
  429.     bzero(&the_insn, sizeof(the_insn));
  430.     the_insn.reloc = NO_RELOC;
  431.  
  432.     /*
  433.      * Build the opcode, checking as we go to make
  434.      * sure that the operands match
  435.      */
  436.     for (args = insn->args; ; ++args) {
  437.         align_mask = 0;
  438.         switch (*args) {
  439.  
  440.         case '\0':  /* end of args */
  441.         if (*s == '\0') {
  442.             match = TRUE;
  443.         }
  444.         break;
  445.  
  446.         case '+':
  447.         case '(':   /* these must match exactly */
  448.         case ')':
  449.         case ',':
  450.         case ' ':
  451.         if (*s++ == *args)
  452.             continue;
  453.         break;
  454.         
  455.         case 'C':   /* Control register */
  456.         if (strncmp(s, "fir", 3) == 0) {
  457.             s += 3;
  458.             SET_RS2(opcode, 0);
  459.             continue;
  460.         }
  461.         if (strncmp(s, "psr", 3) == 0) {
  462.             s += 3;
  463.             SET_RS2(opcode, 1);
  464.             continue;
  465.         }
  466.         if (strncmp(s, "dirbase", 7) == 0) {
  467.             s += 7;
  468.             SET_RS2(opcode, 2);
  469.             continue;
  470.         }
  471.         if (strncmp(s, "db", 2) == 0) {
  472.             s += 2;
  473.             SET_RS2(opcode, 3);
  474.             continue;
  475.         }
  476.         if (strncmp(s, "fsr", 3) == 0) {
  477.             s += 3;
  478.             SET_RS2(opcode, 4);
  479.             continue;
  480.         }
  481.         if (strncmp(s, "epsr", 4) == 0) {
  482.             s += 4;
  483.             SET_RS2(opcode, 5);
  484.             continue;
  485.         }
  486.         break;
  487.  
  488.         case '1':    /* next operand must be a register */
  489.         case '2':
  490.         case 'd':
  491.         {
  492.             switch (c = *s++) {
  493.  
  494.             case 'f':   /* frame pointer */
  495.                 if (*s++ == 'p') {
  496.                 mask = 3;    /* register fp is alias for r3 */
  497.                 break;
  498.             }
  499.             goto error;
  500.  
  501.             case 's':   /* global register */
  502.             if (*s++ == 'p') {
  503.                 mask = 2;    /* register sp is alias for r2 */
  504.                 break;
  505.             }
  506.             goto error;
  507.  
  508.             case 'r': /* any register */
  509.                 if (!isdigit(c = *s++)) {
  510.                 goto error;
  511.             }
  512.             if (isdigit(*s)) {
  513.                 if ((c = 10 * (c - '0') + (*s++ - '0')) >= 32) {
  514.                 goto error;
  515.                 }
  516.             } else {
  517.                 c -= '0';
  518.             }
  519.             mask= c;
  520.             break;
  521.  
  522.             default:
  523.             goto error;
  524.             }
  525.             /*
  526.              * Got the register, now figure out where
  527.              * it goes in the opcode.
  528.              */
  529.             switch (*args) {
  530.  
  531.             case '1':
  532.                 SET_RS1(opcode, mask);
  533.             continue;
  534.  
  535.             case '2':
  536.                 SET_RS2(opcode, mask);
  537.             continue;
  538.  
  539.             case 'd':
  540.                 SET_RD(opcode, mask);
  541.             continue;
  542.             }
  543.         }
  544.         break;
  545.  
  546.         case 'e':    /* next operand is a floating point register */
  547.         case 'f':
  548.         case 'g':
  549.         case 'E':
  550.         case 'F':
  551.         case 'G':
  552.         case 'H':
  553.             if (*s++ == 'f' && isdigit(*s)) {
  554.             mask = *s++;
  555.             if (isdigit(*s)) {
  556.             mask = 10 * (mask - '0') + (*s++ - '0');
  557.             if (mask >= 32) {
  558.                 break;
  559.             }
  560.             } else {
  561.             mask -= '0';
  562.             }
  563.             if ( (*args == 'E' || *args == 'F' || *args == 'G') && (mask & 1) )
  564.             {
  565.                 as_warn( "f%d: Even register required.  Adjusted to f%d.",
  566.                 mask, mask & 0x1E );
  567.             mask &= 0x1E;
  568.             }
  569.             else if ( *args == 'H' && (mask & 3) )
  570.             {
  571.                 as_warn( "f%d: Quad register required.  Adjusted to f%d.",
  572.                 mask, mask & 0x1C );
  573.             mask &= 0x1C;
  574.             }
  575.             switch (*args) {
  576.  
  577.             case 'e':
  578.             case 'E':
  579.                 SET_RS1(opcode, mask);
  580.             continue;
  581.  
  582.             case 'f':
  583.             case 'F':
  584.                 SET_RS2(opcode, mask);
  585.             continue;
  586.  
  587.             case 'g':
  588.             case 'G':
  589.             case 'H':
  590.                 SET_RD(opcode, mask);
  591.             continue;
  592.             }
  593.         }
  594.         break;
  595.     
  596.         case 'B':    /* 5 bit immediate unsigned constant */    
  597.           (void)getExpression(s);
  598.         s = expr_end;
  599.         if ( the_insn.exp.X_seg != SEG_ABSOLUTE )
  600.         {
  601.             as_warn( "Constant expression expected" );
  602.             ++I860_errors;
  603.         }
  604.         if ( the_insn.exp.X_add_number < 0 || the_insn.exp.X_add_number > 31 )
  605.             as_warn( "Constant must be between 0 and 31. Modulo 32 applied." );
  606.         SET_RS1(opcode, the_insn.exp.X_add_number); /* Takes const modulo 32 */
  607.         continue;
  608.         
  609.         case 'D':    /* immediate unsigned constant used in shift opcodes */    
  610.           (void)getExpression(s);
  611.         s = expr_end;
  612.         if ( the_insn.exp.X_seg != SEG_ABSOLUTE )
  613.         {
  614.             as_warn( "Constant expression expected" );
  615.             ++I860_errors;
  616.         }
  617.         if ( the_insn.exp.X_add_number < 0 || the_insn.exp.X_add_number > 31 )
  618.             as_warn( "Constant must be between 0 and 31. Modulo 32 applied." );
  619.         opcode |= (the_insn.exp.X_add_number & 0x1F);
  620.         continue;
  621.  
  622.         case 'i':       /* low 16 bits, byte aligned */
  623.             the_insn.reloc = RELOC_LOW0;
  624.         goto immediate;
  625.         
  626.         case 'I':       /* high 16 bits */
  627.             the_insn.reloc = RELOC_HIGH;
  628.         goto immediate;
  629.  
  630.         case 'j':       /* low 16 bits, short aligned */
  631.             the_insn.reloc = RELOC_LOW1;
  632.         align_mask = 1;
  633.         goto immediate;
  634.  
  635.         case 'k':       /* low 16 bits, int aligned */
  636.             the_insn.reloc = RELOC_LOW2;
  637.         align_mask = 3;
  638.         goto immediate;
  639.  
  640.         case 'l':       /* low 16 bits, double aligned */
  641.             the_insn.reloc = RELOC_LOW3;
  642.         align_mask = 7;
  643.         goto immediate;
  644.  
  645.         case 'm':       /* low 16 bits, quad aligned */
  646.             the_insn.reloc = RELOC_LOW4;
  647.         align_mask = 15;
  648.         goto immediate;
  649.  
  650.         case 'n':       /* low 16 bits, byte aligned, split field */
  651.             the_insn.reloc = RELOC_SPLIT0;
  652.         goto immediate;
  653.  
  654.         case 'o':       /* low 16 bits, short aligned, split field */
  655.             the_insn.reloc = RELOC_SPLIT1;
  656.         align_mask = 1;
  657.         goto immediate;
  658.  
  659.         case 'p':       /* low 16 bits, int aligned, split field */
  660.             the_insn.reloc = RELOC_SPLIT2;
  661.         align_mask = 3;
  662.         goto immediate;
  663.  
  664.         case 'J':       /* High 16 bits, requiring adjustment */
  665.             the_insn.reloc = RELOC_HIGHADJ;
  666.         goto immediate;
  667.  
  668.  
  669.         case 'K':   /* 26 bit PC relative immediate */
  670.             the_insn.reloc = RELOC_BRADDR;
  671.         the_insn.pcrel = 1;
  672.         goto immediate;
  673.  
  674.         case 'L':   /* 16 bit PC relative split format immediate */
  675.             the_insn.reloc = RELOC_SPLIT0;
  676.         the_insn.pcrel = 1;
  677.         goto immediate;
  678.         /*FALLTHROUGH*/
  679.  
  680.         immediate:
  681.         if(*s==' ')
  682.           s++;
  683.         adjustment = 0;
  684.         if ( *s == 'h' && *(s + 1) == '%' )
  685.         {
  686.             adjustment = RELOC_HIGH;
  687.             if ( the_insn.reloc == RELOC_LOW0 && the_insn.pcrel == 0 )
  688.             {
  689.                 the_insn.reloc = RELOC_HIGH;
  690.             }
  691.             else
  692.                 as_warn("Improper use of h%.");
  693.             s += 2;
  694.         }
  695.         else if ( *s == 'h' && *(s + 1) == 'a' && *(s + 2) == '%' )
  696.         {
  697.             adjustment = RELOC_HIGHADJ;
  698.             if ( the_insn.reloc == RELOC_LOW0 && the_insn.pcrel == 0 )
  699.             {
  700.                 the_insn.reloc = RELOC_HIGHADJ;
  701.             }
  702.             else
  703.                 as_warn("Improper use of ha%.");
  704.  
  705.             s += 3;
  706.         }
  707.         else if ( *s == 'l' &&  *(s + 1) == '%' )
  708.         {    /* the_insn.reloc is correct as is. */
  709.             adjustment = RELOC_LOW0;
  710.             s += 2;
  711.         }
  712.         /* Note that if the getExpression() fails, we will still have
  713.            created U entries in the symbol table for the 'symbols'
  714.            in the input string.  Try not to create U symbols for
  715.            registers, etc. */
  716.            
  717.         /* This stuff checks to see if the expression ends
  718.            in '(', as in ld.l foo(r20). If it does, it
  719.            removes the '(' from the expression, and 
  720.            re-sets 's' to point to the right place */
  721.  
  722.         for(s1=s;*s1 && *s1!=','&& *s1!=')';s1++)
  723.             ;
  724.  
  725.         if( s1 != s && *s1 == '(' && s1[1] == 'r' && isdigit(s1[2])
  726.             && (s1[3]==')' || (isdigit(s1[3]) && s1[4] == ')')) ) {
  727.                 *s1='\0';
  728.                 (void)getExpression(s);
  729.                 *s1='(';
  730.                 s=s1;
  731.         }
  732.         else
  733.         {
  734.             (void)getExpression(s);
  735.             s = expr_end;
  736.         }
  737.         /*
  738.          * If there is an adjustment, we assume the user knows what
  739.          * they are doing.  If no adjustment, we very carefully range 
  740.          * check for both signed and unsigned operations, to avoid 
  741.          * unpleasant suprises.  The checks are skipped for branch and
  742.          * call instructions, matching the behavior of the Intel assembler.
  743.          */
  744.         if ( ! adjustment && *op != 'b' && *op != 'c' )
  745.         {
  746.             if ( the_insn.exp.X_seg != SEG_ABSOLUTE )
  747.             {
  748.             as_warn(
  749.               "Non-absolute expression requires h%%, l%%, or ha%% prefix."
  750.             );
  751.             }
  752.             else
  753.             {
  754.                 if ( IS_LOGOP(opcode) )
  755.             {
  756.                 if ( ((unsigned)the_insn.exp.X_add_number) > 0xFFFF )
  757.                     as_warn("%u is too big for 16 bit unsigned value!",
  758.                     the_insn.exp.X_add_number);
  759.             }
  760.             else
  761.             {
  762.                 if ( ((int)the_insn.exp.X_add_number) > 32767 ||
  763.                      ((int)the_insn.exp.X_add_number) < -32768 )
  764.                 as_warn("%d is out of range for 16 bit signed value!",
  765.                     the_insn.exp.X_add_number);
  766.                     
  767.                 if ((align_mask & the_insn.exp.X_add_number) != 0)
  768.                     as_warn("Const offset 0x%x incorrectly aligned.",
  769.                     the_insn.exp.X_add_number);
  770.             }
  771.             }
  772.         }
  773.         continue;
  774.         
  775.         default:
  776.         abort();
  777.         }
  778.         break;
  779.     }
  780.     error:
  781.     if (match == FALSE) {
  782.         /* args don't match */
  783.         if (!insn->last) {
  784.         ++insn;
  785.         s = argsStart;
  786.         continue;
  787.         } else {
  788.         as_warn("Illegal operands (%s %s).", str, argsStart);
  789.         ++I860_errors;
  790.         return flags;
  791.         }
  792.     }
  793.     break;
  794.     }
  795.     /* If the last insn was dual, check and make sure that this insn is integer insn */
  796.     if ( expect_int_insn && (dual_insn_mode || this_insn_is_dual) )
  797.     {
  798.             if ( (opcode & OP_PREFIX_MASK) == PREFIX_FPU || opcode == OP_FNOP )
  799.         {
  800.         as_warn( "Core half of prev dual insn pair missing." );
  801.         }
  802.         expect_int_insn = 0;
  803.     }
  804.     /* Check the insn format and fold in the dual mode bit if appropriate. */
  805.     if ( dual_insn_mode || this_insn_is_dual )
  806.     {
  807.         if ( (opcode & OP_PREFIX_MASK) == PREFIX_FPU || opcode == OP_FNOP )
  808.         {
  809.                 if ( insn_count & 1 )    /* Odd insn, not on 64 bit bound! */
  810.             {
  811.             as_warn( "Dual FP insn on odd addr." );
  812.             }
  813.             opcode |= DUAL_INSN_MODE_BIT;
  814.             expect_int_insn = 1;
  815.         }
  816.         else if ( this_insn_is_dual ) /* d. prefix on a non-FPU insn error */
  817.         {
  818.             as_warn("d. prefix not allowed for `%s'. (Ignored!)", op);
  819.         } 
  820.     }
  821.     else
  822.             expect_int_insn = 0;    /* Single insn mode. */
  823.     /* Check for correct alignment of const in branch to label + offset */
  824.     if (    (the_insn.reloc == RELOC_BRADDR
  825.              || (the_insn.pcrel && the_insn.reloc == RELOC_SPLIT0)
  826.         ) && (the_insn.exp.X_add_number & 3) )
  827.             as_warn( "Branch offset is not aligned to instruction boundry!" );
  828.     the_insn.opcode = opcode;
  829.     return flags;
  830. }
  831.  
  832. static int
  833. getExpression(str)
  834.     char *str;
  835. {
  836.     char *save_in;
  837.     segT seg;
  838.  
  839.     save_in = input_line_pointer;
  840.     input_line_pointer = str;
  841.     switch (seg = expression(&the_insn.exp)) {
  842.  
  843.     case SEG_ABSOLUTE:
  844.     case SEG_TEXT:
  845.     case SEG_DATA:
  846.     case SEG_BSS:
  847.     case SEG_UNKNOWN:
  848.     case SEG_DIFFERENCE:
  849.     case SEG_BIG:
  850.     case SEG_NONE:
  851.     break;
  852.  
  853.     default:
  854.     the_insn.error = "bad segment";
  855.     expr_end = input_line_pointer;
  856.     input_line_pointer=save_in;
  857.     return 1;
  858.     }
  859.     expr_end = input_line_pointer;
  860.     input_line_pointer = save_in;
  861.     return 0;
  862. }
  863.  
  864.  
  865. #define MAX_LITTLENUMS 6
  866.  
  867. /*
  868.     This is identical to the md_atof in m68k.c.  I think this is right,
  869.     but I'm not sure.
  870.  
  871.    Turn a string in input_line_pointer into a floating point constant of type
  872.    type, and store the appropriate bytes in *litP.  The number of LITTLENUMS
  873.    emitted is stored in *sizeP .  An error message is returned, or NULL on OK.
  874.  */
  875. char *
  876. md_atof(type,litP,sizeP)
  877.     char type;
  878.     char *litP;
  879.     int *sizeP;
  880. {
  881.     int    prec;
  882.     LITTLENUM_TYPE words[MAX_LITTLENUMS];
  883.     LITTLENUM_TYPE *wordP;
  884.     char    *t;
  885.     char    *atof_ieee();
  886.  
  887.     switch(type) {
  888.  
  889.     case 'f':
  890.     case 'F':
  891.     case 's':
  892.     case 'S':
  893.     prec = 2;
  894.     break;
  895.  
  896.     case 'd':
  897.     case 'D':
  898.     case 'r':
  899.     case 'R':
  900.     prec = 4;
  901.     break;
  902.     /* The following two formats get reduced to doubles. */
  903.     case 'x':
  904.     case 'X':
  905.         type = 'd';
  906.     prec = 4;
  907.     break;
  908.  
  909.     case 'p':
  910.     case 'P':
  911.         type = 'd';
  912.     prec = 4;
  913.     break;
  914.  
  915.     default:
  916.     *sizeP=0;
  917.     return "Bad call to MD_ATOF()";
  918.     }
  919.     t=atof_ieee(input_line_pointer,type,words);
  920.     if(t)
  921.     input_line_pointer=t;
  922.     *sizeP=prec * sizeof(LITTLENUM_TYPE);
  923.     for(wordP=words;prec--;) {
  924.     md_number_to_chars(litP,(long)(*wordP++),sizeof(LITTLENUM_TYPE));
  925.     litP+=sizeof(LITTLENUM_TYPE);
  926.     }
  927.     return "";    /* Someone should teach Dean about null pointers */
  928. }
  929.  
  930. /*
  931.  * Write out big-endian.  Valid for data only in our I860 implementation.
  932.  */
  933. void
  934. md_number_to_chars(buf,val,n)
  935.     char *buf;
  936.     long val;
  937.     int n;
  938. {
  939.  
  940.     switch(n) {
  941.  
  942.     case 4:
  943.     *buf++ = val >> 24;
  944.     *buf++ = val >> 16;
  945.     case 2:
  946.     *buf++ = val >> 8;
  947.     case 1:
  948.     *buf = val;
  949.     break;
  950.  
  951.     default:
  952.     abort();
  953.     }
  954.     return;
  955. }
  956.  
  957. #ifdef BYTE_SWAP
  958. /*
  959.  * Write out little-endian.  Valid for instructions only in
  960.  * our i860 implementation.
  961.  */
  962. void
  963. md_insn_to_chars(buf,val,n)
  964.     char *buf;
  965.     long val;
  966.     int n;
  967. {
  968.  
  969.     switch(n) {
  970.  
  971.     case 4:
  972.     *buf++ = val;
  973.     *buf++ = val >> 8;
  974.     *buf++ = val >> 16;
  975.     *buf++ = val >> 24;
  976.     break;
  977.     case 2:
  978.     *buf++ = val;
  979.     *buf++ = val >> 8;
  980.     break;
  981.     case 1:
  982.     *buf = val;
  983.     break;
  984.  
  985.     default:
  986.     abort();
  987.     }
  988.     return;
  989. }
  990. #else
  991. void
  992. md_insn_to_chars(buf,val,n)
  993.     char *buf;
  994.     long val;
  995.     int n;
  996. {
  997.     md_number_to_chars(buf,val,n);
  998. }
  999. #endif
  1000.  
  1001. void
  1002. md_number_to_imm(buf,val,n, fixP, seg_type)
  1003.     unsigned char *buf;
  1004.     unsigned long val;
  1005.     int n;
  1006.     fixS *fixP;
  1007.     int seg_type;
  1008. {
  1009.     unsigned long opcode;
  1010.     if ( seg_type == N_TEXT  && (n % 4) != 0 )
  1011.         as_warn("Immediate write of non-aligned data into text segment." );
  1012.     
  1013.     if (seg_type != N_TEXT ||
  1014.         fixP->fx_r_type == NO_RELOC ||
  1015.     fixP->fx_r_type == RELOC_VANILLA)
  1016.     {
  1017.     switch (n) {    /* Write out the data big-endian style. */
  1018.     case 1:
  1019.         *buf = val;
  1020.         break;
  1021.     case 2:
  1022.         *buf++ = (val>>8);
  1023.         *buf = val;
  1024.         break;
  1025.     case 4:
  1026.         *buf++ = (val>>24);
  1027.         *buf++ = (val>>16);
  1028.         *buf++ = (val>>8);
  1029.         *buf = val;
  1030.         break;
  1031.     default:
  1032.         abort();
  1033.     }
  1034.     return;
  1035.     }
  1036.  
  1037.     assert(n == 4);    /* Better be an instruction with relocation data.... */
  1038.     assert(fixP->fx_r_type < NO_RELOC && fixP->fx_r_type > RELOC_VANILLA);
  1039.     /*
  1040.      * Here is where we do initial bit fiddling to load immediate 
  1041.      * values into the i860 bit fields.
  1042.      */
  1043. #ifdef BYTE_SWAP     
  1044.     /* Note that all of these insns are ultimately little-endian */
  1045.     /* Get the opcode from the buffer.  Less efficient, but more coherent... */
  1046.     opcode = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];
  1047. #else
  1048.     opcode = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
  1049. #endif  
  1050.     /* Apply the relocation value 'val' */
  1051.     switch (fixP->fx_r_type) { 
  1052.         case RELOC_PAIR:
  1053.         as_warn("questionable relocation type RELOC_PAIR");
  1054.         break;
  1055.         case RELOC_HIGH:
  1056.         opcode &= ~0xFFFF;
  1057.         opcode |= ((val >> 16) & 0xFFFF);
  1058.         break;
  1059.         case RELOC_LOW0:
  1060.         opcode &= ~0xFFFF;
  1061.         opcode |= (val & 0xFFFF);
  1062.         break;
  1063.         case RELOC_LOW1:
  1064.         opcode &= 0xFFFF0001;
  1065.         opcode |= (val & 0xFFFE);    /* Bit 0 is an insn bit! */
  1066.         break;
  1067.         case RELOC_LOW2:
  1068.         opcode &= 0xFFFF0003;
  1069.         opcode |= (val & 0xFFFC);    /* Bits 0 and 1 are insn bits! */
  1070.         break;
  1071.         case RELOC_LOW3:
  1072.         opcode &= 0xFFFF0007;
  1073.         opcode |= (val & 0xFFF8);    /* Bits 0 thru 2 are insn bits! */
  1074.         break;
  1075.         case RELOC_LOW4:
  1076.         opcode &= 0xFFFF000F;
  1077.         opcode |= (val & 0xFFF0);    /* Bits 0 thru 3 are insn bits! */
  1078.         break;
  1079.         case RELOC_SPLIT0:
  1080.         opcode &= 0xFFE0F800;
  1081.         if ( fixP->fx_pcrel )         /* A 16 bit branch relative insn? */
  1082.             val >>= 2;        /* Convert to word address */
  1083.         opcode |= ((val & 0xF800) << 5) | (val & 0x7FF);
  1084.         break;
  1085.         case RELOC_SPLIT1:
  1086.         opcode &= 0xFFE0F801;        /* Again, bit 0 is an insn bit! */
  1087.         opcode |= ((val & 0xF800) << 5) | (val & 0x7FE);
  1088.         break;
  1089.         case RELOC_SPLIT2:
  1090.         opcode &= 0xFFE0F803;        /* Bits 0 and 1 are insn bits! */
  1091.         opcode |= ((val & 0xF800) << 5) | (val & 0x7FC);
  1092.         break;
  1093.         case RELOC_HIGHADJ:            /* Adjusted variant */
  1094.         opcode &= ~0xFFFF;
  1095.         /* If the low half would be negative, compensate by adding 1 to 
  1096.          * high half.
  1097.          */
  1098.         if ( (val & 0x8000) != 0 )
  1099.             val = (val >> 16) + 1;
  1100.         else
  1101.             val = (val >> 16);
  1102.         opcode |= val;
  1103.         break;
  1104.         case RELOC_BRADDR:
  1105.         if ( fixP->fx_pcrel )         /* A 26 bit branch relative insn? */
  1106.             val >>= 2;        /* Convert to word address */
  1107.         opcode &= 0xFC000000;
  1108.         opcode |= (val & 0x03FFFFFF);
  1109.         break;
  1110.     
  1111.     default:
  1112.         as_warn("bad relocation type: 0x%02x", fixP->fx_r_type);
  1113.         break;
  1114.     }
  1115. #ifdef BYTE_SWAP
  1116.     buf[0] = opcode;
  1117.     buf[1] = opcode >> 8;
  1118.     buf[2] = opcode >> 16;
  1119.     buf[3] = opcode >> 24;
  1120. #else
  1121.     buf[3] = opcode;
  1122.     buf[2] = opcode >> 8;
  1123.     buf[1] = opcode >> 16;
  1124.     buf[0] = opcode >> 24;
  1125. #endif
  1126.     return;
  1127. }
  1128.  
  1129. /* should never be called for i860 */
  1130. void
  1131. md_create_short_jump(ptr, from_addr, to_addr, frag, to_symbol)
  1132.     char *ptr;
  1133.     long from_addr, to_addr;
  1134. {
  1135.     fprintf(stderr, "i860_create_short_jmp\n");
  1136.     abort();
  1137. }
  1138.  
  1139. /* should never be called for i860 */
  1140. void
  1141. md_number_to_disp(buf,val,n)
  1142.     char    *buf;
  1143.     long    val;
  1144. {
  1145.     fprintf(stderr, "md_number_to_disp\n");
  1146.     abort();
  1147. }
  1148.  
  1149. /* should never be called for i860 */
  1150. void
  1151. md_number_to_field(buf,val,fix)
  1152.     char *buf;
  1153.     long val;
  1154.     void *fix;
  1155. {
  1156.     fprintf(stderr, "i860_number_to_field\n");
  1157.     abort();
  1158. }
  1159.  
  1160. void
  1161. md_ri_to_chars(ri_p, ri)
  1162.      struct relocation_info *ri_p, ri;
  1163. {
  1164.     /* 
  1165.      * if you want to cross-assemble from
  1166.      * a little-endian then you might need to
  1167.      * do some byte-swapping here.
  1168.      */
  1169.     return;
  1170. }
  1171.  
  1172. /* should never be called for i860 */
  1173. void
  1174. md_convert_frag(fragP)
  1175.     register fragS *fragP;
  1176. {
  1177.     fprintf(stderr, "i860_convert_frag\n");
  1178.     abort();
  1179. }
  1180.  
  1181. /* should never be called for i860 */
  1182. void
  1183. md_create_long_jump(ptr, from_addr, to_addr, frag, to_symbol)
  1184.     char    *ptr;
  1185.     long    from_addr,
  1186.             to_addr;
  1187.     fragS    *frag;
  1188.     symbolS    *to_symbol;
  1189. {
  1190.     fprintf(stderr, "i860_create_long_jump\n");
  1191.     abort();
  1192. }
  1193.  
  1194. /* should never be called for i860 */
  1195. int
  1196. md_estimate_size_before_relax(fragP, segtype)
  1197.     register fragS *fragP;
  1198. {
  1199.     fprintf(stderr, "i860_estimate_size_before_relax\n");
  1200.     abort();
  1201.     return 0;
  1202. }
  1203.  
  1204. #if 0
  1205. /* for debugging only */
  1206. static void
  1207. print_insn(insn)
  1208.     struct i860_it *insn;
  1209. {
  1210.     char *Reloc[] = {
  1211.     "RELOC_8",
  1212.     "RELOC_16",
  1213.     "RELOC_32",
  1214.     "RELOC_DISP8",
  1215.     "RELOC_DISP16",
  1216.     "RELOC_DISP32",
  1217.     "RELOC_WDISP30",
  1218.     "RELOC_WDISP22",
  1219.     "RELOC_HI22",
  1220.     "RELOC_22",
  1221.     "RELOC_13",
  1222.     "RELOC_LO10",
  1223.     "RELOC_SFA_BASE",
  1224.     "RELOC_SFA_OFF13",
  1225.     "RELOC_BASE10",
  1226.     "RELOC_BASE13",
  1227.     "RELOC_BASE22",
  1228.     "RELOC_PC10",
  1229.     "RELOC_PC22",
  1230.     "RELOC_JMP_TBL",
  1231.     "RELOC_SEGOFF16",
  1232.     "RELOC_GLOB_DAT",
  1233.     "RELOC_JMP_SLOT",
  1234.     "RELOC_RELATIVE",
  1235.     "NO_RELOC"
  1236.     };
  1237.  
  1238.     if (insn->error) {
  1239.     fprintf(stderr, "ERROR: %s\n");
  1240.     }
  1241.     fprintf(stderr, "opcode=0x%08x\n", insn->opcode);
  1242.     fprintf(stderr, "reloc = %s\n", Reloc[insn->reloc]);
  1243.     fprintf(stderr, "exp =  {\n");
  1244.     fprintf(stderr, "\t\tX_add_symbol = %s\n",
  1245.     insn->exp.X_add_symbol ?
  1246.     (insn->exp.X_add_symbol->sy_name ? 
  1247.     insn->exp.X_add_symbol->sy_name : "???") : "0");
  1248.     fprintf(stderr, "\t\tX_sub_symbol = %s\n",
  1249.     insn->exp.X_subtract_symbol ?
  1250.         (insn->exp.X_subtract_symbol->sy_name ? 
  1251.             insn->exp.X_subtract_symbol->sy_name : "???") : "0");
  1252.     fprintf(stderr, "\t\tX_add_number = %d\n",
  1253.     insn->exp.X_add_number);
  1254.     fprintf(stderr, "}\n");
  1255.     return;
  1256. }
  1257. #endif
  1258.  
  1259. int
  1260. md_parse_option(argP,cntP,vecP)
  1261.     char **argP;
  1262.     int *cntP;
  1263.     char ***vecP;
  1264. {
  1265.     return 1;
  1266. }
  1267.  
  1268.