Annotation of GNUtools/cctools/as/i860.c, revision 1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.