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

1.1     ! root        1: /* hppa.c -- Assemble for the HP-PA
        !             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: /*
        !            22:    HP PA-RISC support was contributed by the Center for Software Science
        !            23:    at the University of Utah.
        !            24: */
        !            25: 
        !            26: /* HP-PA support for Mach-O ... USV */
        !            27: 
        !            28: #include <stdio.h>
        !            29: #include <ctype.h>
        !            30: #include <string.h>
        !            31: #include <mach-o/hppa/reloc.h>
        !            32: #define HPPA_RELOC_12BRANCH (127) /* only used internal in here */
        !            33: 
        !            34: #include "obstack.h"
        !            35: #include "hppa-opcode.h"
        !            36: #include "as.h"
        !            37: #include "frags.h"
        !            38: #include "flonum.h"
        !            39: #include "hash.h"
        !            40: #include "md.h"
        !            41: #include "symbols.h"
        !            42: #include "hppa-aux.h"
        !            43: #include "messages.h"
        !            44: #include "stuff/hppa.h"
        !            45: 
        !            46: /*
        !            47:  * These are the default cputype and cpusubtype for the hppa architecture.
        !            48:  */
        !            49: const cpu_type_t md_cputype = CPU_TYPE_HPPA;
        !            50: cpu_subtype_t md_cpusubtype = CPU_SUBTYPE_HPPA_ALL;
        !            51: 
        !            52: /* This is the byte sex for the hppa architecture */
        !            53: const enum byte_sex md_target_byte_sex = BIG_ENDIAN_BYTE_SEX;
        !            54: 
        !            55: /* These characters start a comment anywhere on the line */
        !            56: const char md_comment_chars[] = ";";
        !            57: 
        !            58: /* These characters only start a comment at the beginning of a line */
        !            59: const char md_line_comment_chars[] = "#";
        !            60: 
        !            61: /*
        !            62:  * These characters can be used to separate mantissa decimal digits from 
        !            63:  * exponent decimal digits in floating point numbers.
        !            64:  */
        !            65: const char md_EXP_CHARS[] = "eE";
        !            66: 
        !            67: /*
        !            68:  * The characters after a leading 0 that means this number is a floating point
        !            69:  * constant as in 0f123.456 or 0d1.234E-12 (see md_EXP_CHARS above).
        !            70:  */
        !            71: const char md_FLT_CHARS[] = "dDfF";
        !            72: 
        !            73: /*
        !            74:  * This is the machine dependent pseudo opcode table for this target machine.
        !            75:  */
        !            76: const pseudo_typeS md_pseudo_table[] =
        !            77: {
        !            78:     {0} /* end of table marker */
        !            79: };
        !            80: 
        !            81: 
        !            82: static int found_jbsr = 0;
        !            83: static char *toP;
        !            84: 
        !            85: const relax_typeS md_relax_table[] = { 0 };
        !            86: 
        !            87: /* handle of the OPCODE hash table */
        !            88: static struct hash_control *op_hash = NULL;
        !            89: 
        !            90: struct pa_it the_insn;   /* this structure is defined in pa-aux.h */
        !            91: 
        !            92: char *expr_end;
        !            93: 
        !            94: static void pa_ip(
        !            95:     char *str);
        !            96: static int parse_L_or_R(
        !            97:     char *str);
        !            98: static unsigned long parse_completer_with_cache_control_hint(
        !            99:        char    **s,       /* Note : the function changes '*s' */
        !           100:        int     option,    /* option = 0 for store instruction */
        !           101:                        /* option = 1 for load and clear instruction */
        !           102:        char    completer);/* 'c' or 'C' */
        !           103: static unsigned long parse_cache_control_hint(
        !           104:        char    **s,       /* Note : the function changes '*s' */
        !           105:        int     option);   /* option = 0 for store instruction */
        !           106:                        /* option = 1 for load and clear instruction */
        !           107: 
        !           108: /* This function is called once, at assembler startup time.  It should
        !           109:    set up all the tables, etc. that the MD part of the assembler will need.  */
        !           110: void
        !           111: md_begin(
        !           112: void)
        !           113: {
        !           114:        register char *retval = NULL;
        !           115:        int lose = 0;
        !           116:        register unsigned int i = 0;
        !           117: 
        !           118:        op_hash = hash_new();
        !           119:        if (op_hash == NULL)
        !           120:        as_fatal("Virtual memory exhausted");
        !           121: 
        !           122:        while (i < NUMOPCODES) {
        !           123:                const char *name = pa_opcodes[i].name;
        !           124:                retval = hash_insert(op_hash, (char *)name,
        !           125:                                     (char *)&pa_opcodes[i]);
        !           126:                if(retval != NULL && *retval != '\0')  {
        !           127:                        as_fatal("Internal error: can't hash `%s': %s\n",
        !           128:                        pa_opcodes[i].name, retval);
        !           129:                        lose = 1;
        !           130:                }
        !           131:                ++i;
        !           132:        }
        !           133: 
        !           134:        if (lose)
        !           135:                as_fatal ("Broken assembler.  No assembly attempted.");
        !           136: }
        !           137: 
        !           138: void
        !           139: md_end(
        !           140: void)
        !           141: {
        !           142:        return;
        !           143: }
        !           144: 
        !           145: void
        !           146: md_assemble(
        !           147: char *str)
        !           148: {
        !           149: 
        !           150:        assert(str);
        !           151:        pa_ip(str);
        !           152:        if (!found_jbsr)
        !           153:                toP = frag_more(4);
        !           154:        else
        !           155:                found_jbsr = 0;
        !           156: 
        !           157:     /* put out the opcode */
        !           158:     md_number_to_chars(toP, the_insn.opcode, 4);
        !           159: 
        !           160:     /* put out the symbol-dependent stuff */
        !           161:     if (the_insn.reloc != NO_RELOC) {
        !           162:            fix_new(frag_now,                     /* which frag */
        !           163:                    (toP - frag_now->fr_literal), /* where */
        !           164:                    4,                            /* size */
        !           165:                    the_insn.exp.X_add_symbol,
        !           166:                    the_insn.exp.X_subtract_symbol,
        !           167:                    the_insn.exp.X_add_number,    /* offset */
        !           168:                    the_insn.pcrel,
        !           169:                    the_insn.pcrel_reloc,
        !           170:                    the_insn.reloc);
        !           171:     }
        !           172: }
        !           173: 
        !           174: static
        !           175: void
        !           176: pa_ip(
        !           177: char *str)
        !           178: {
        !           179:        char *s;
        !           180:        const char *args;
        !           181:        char c;
        !           182:        unsigned long i;
        !           183:        struct pa_opcode *insn;
        !           184:        char *argsStart;
        !           185:        unsigned long   opcode;
        !           186:        int match = FALSE;
        !           187:        int comma = 0;
        !           188: 
        !           189:        int reg,reg1,reg2,s2,s3;
        !           190:        unsigned int im21,im14,im11,im5;
        !           191:        int m,a,u,f;
        !           192:        int cmpltr,nullif, flag;
        !           193:        int sfu, cond;
        !           194:        char *name;
        !           195:        char *save_s;
        !           196: 
        !           197: #ifdef PA_DEBUG
        !           198:        fprintf(stderr,"STATEMENT: \"%s\"\n",str);
        !           199: #endif
        !           200:        for (s = str; isupper(*s) || islower(*s) || (*s >= '0' && *s <= '3'); ++s)
        !           201:                ;
        !           202:        switch (*s) {
        !           203: 
        !           204:        case '\0':
        !           205:                break;
        !           206: 
        !           207:        case ',':
        !           208:                comma = 1;
        !           209: 
        !           210:        /*FALLTHROUGH*/
        !           211: 
        !           212:        case ' ':
        !           213:                *s++ = '\0';
        !           214:                break;
        !           215: 
        !           216:        default:
        !           217:                as_bad("Unknown opcode: `%s'", str);
        !           218:                exit(1);
        !           219:        }
        !           220: 
        !           221:        save_s = str;
        !           222: 
        !           223:        while ( *save_s ) {
        !           224:                if ( isupper(*save_s) )
        !           225:                        *save_s = tolower(*save_s);
        !           226:                save_s++;
        !           227:        }
        !           228: 
        !           229:        if ((insn = (struct pa_opcode *) hash_find(op_hash, str)) == NULL) {
        !           230:                as_bad("Unknown opcode: `%s'", str);
        !           231:                return;
        !           232:        }
        !           233:        if (comma) {
        !           234:                *--s = ',';
        !           235:        }
        !           236:        argsStart = s;
        !           237:        for (;;) {
        !           238:                opcode = insn->match;
        !           239:                memset(&the_insn, '\0', sizeof(the_insn));
        !           240:                the_insn.reloc = NO_RELOC;    /* USV */
        !           241: 
        !           242: /*
        !           243: * Build the opcode, checking as we go to make
        !           244: * sure that the operands match
        !           245: */
        !           246:                for (args = insn->args; ; ++args) {
        !           247: 
        !           248:                        switch (*args) {
        !           249: 
        !           250:                        case '\0':  /* end of args */
        !           251:                                if (*s == '\0') {
        !           252:                                        match = TRUE;
        !           253:                                }
        !           254:                                break;
        !           255: 
        !           256:                        case '(':   /* these must match exactly */
        !           257:                        case ')':
        !           258:                        case ',':
        !           259:                        case ' ':
        !           260:                                if (*s++ == *args)
        !           261:                                        continue;
        !           262:                                break;
        !           263: 
        !           264:                        case 'b':   /* 5 bit register field at 10 */
        !           265:                                reg = pa_parse_number(&s);
        !           266:                                if ( reg < 32 && reg >= 0 ) {
        !           267:                                        opcode |= reg << 21;
        !           268:                                        continue;
        !           269:                                }
        !           270:                                break;
        !           271:                        case 'x':   /* 5 bit register field at 15 */
        !           272:                                reg = pa_parse_number(&s);
        !           273:                                if ( reg < 32 && reg >= 0 ) {
        !           274:                                        opcode |= reg << 16;
        !           275:                                        continue;
        !           276:                                }
        !           277:                                break;
        !           278:                        case 't':   /* 5 bit register field at 31 */
        !           279:                                reg = pa_parse_number(&s);
        !           280:                                if ( reg < 32 && reg >= 0 ) {
        !           281:                                        opcode |= reg;
        !           282:                                        continue;
        !           283:                                }
        !           284:                                break;
        !           285:                        case 'T':   /* 5 bit field length at 31 (encoded as 32-T) */
        !           286:   /*
        !           287: reg = pa_parse_number(&s);
        !           288:    */
        !           289:                                getAbsoluteExpression(s);
        !           290:                                if ( the_insn.exp.X_seg == SEG_ABSOLUTE ) {
        !           291:                                        reg = the_insn.exp.X_add_number;
        !           292:                                        if ( reg <= 32 && reg > 0 ) {
        !           293:                                                opcode |= 32 - reg;
        !           294:                                                s = expr_end;
        !           295:                                                continue;
        !           296:                                        }
        !           297:                                }
        !           298:                                break;
        !           299:                        case '5':   /* 5 bit immediate at 15 */
        !           300:                                getAbsoluteExpression(s);
        !           301: /** PJH: The following 2 calls to as_bad() might eventually **/
        !           302: /**      want to end up as as_warn().  **/
        !           303:                                if (   the_insn.exp.X_add_number > 15 ) {
        !           304:                                        as_bad("5 bit immediate: %ld > 15. Set to 15",
        !           305:                                                the_insn.exp.X_add_number);
        !           306:                                        the_insn.exp.X_add_number = 15;
        !           307:                                }
        !           308:                                else if ( the_insn.exp.X_add_number < -16 ) {
        !           309:                                                as_bad("5 bit immediate: %ld < -16. Set to -16",
        !           310:                                                        the_insn.exp.X_add_number);
        !           311:                                                the_insn.exp.X_add_number = -16;
        !           312:                                        }
        !           313: 
        !           314:                                im5 = low_sign_unext(evaluateAbsolute(
        !           315:                                                     the_insn.exp,0),5);
        !           316:                                opcode |= ( im5 << 16 );
        !           317:                                s = expr_end;
        !           318:                                continue;
        !           319: 
        !           320:                        case 's':   /* 2 bit space identifier at 17 */
        !           321:                                s2 = pa_parse_number(&s);
        !           322:                                if ( s2 < 4 && s2 >= 0 ) {
        !           323:                                        opcode |= s2 << 14;
        !           324:                                        continue;
        !           325:                                }
        !           326:                                break;
        !           327:                        case 'S':   /* 3 bit space identifier at 18 */
        !           328:                                s3 = pa_parse_number(&s);
        !           329:                                if ( s3 < 8 && s3 >= 0 ) {
        !           330:                                        s3 = dis_assemble_3(s3);
        !           331:                                        opcode |= s3 << 13;
        !           332:                                        continue;
        !           333:                                }
        !           334:                                break;
        !           335:                        case 'c':   /* indexed load completer. */
        !           336:                                i = m = u = 0;
        !           337:                                while ( *s == ',' && i < 2 ) {
        !           338:                                        s++;
        !           339:                                        if ( strncasecmp(s,"sm",2) == 0 ) {
        !           340:                                                m = u = 1;
        !           341:                                                s++;
        !           342:                                                i++;
        !           343:                                        }
        !           344:                                        else if ( strncasecmp(s,"m",1) == 0 )
        !           345:                                                        m = 1;
        !           346:                                                else if ( strncasecmp(s,"s",1) == 0 )
        !           347:                                                                u = 1;
        !           348:                                                        else
        !           349:                                                                as_bad("Unrecognized Indexed Load"
        !           350:                                                                        "Completer...assuming 0");
        !           351:                                        s++;
        !           352:                                        i++;
        !           353:                                }
        !           354:                                if ( i > 2 )
        !           355:                                        as_bad("Illegal Indexed Load Completer Syntax..."
        !           356:                                                "extras ignored");
        !           357:                                while ( *s == ' ' || *s == '\t' )
        !           358:                                        s++;
        !           359:   
        !           360:                                opcode |= m << 5;
        !           361:                                opcode |= u << 13;
        !           362:                                continue;
        !           363:                        case 'C':   /* short load and store completer */
        !           364:                                m = a = 0;
        !           365:                                if ( *s == ',' ) {
        !           366:                                        s++;
        !           367:                                        if ( strncasecmp(s,"ma",2) == 0 ) {
        !           368:                                                a = 0;
        !           369:                                                m = 1;
        !           370:                                        }
        !           371:                                        else if ( strncasecmp(s,"mb",2) == 0 ) {
        !           372:                                                        m = a = 1;
        !           373:                                                }
        !           374:                                                else
        !           375:                                                        as_bad("Unrecognized Indexed Load Completer"
        !           376:                                                                "...assuming 0");
        !           377:                                        s += 2;
        !           378:                                }
        !           379:                                while ( *s == ' ' || *s == '\t' )
        !           380:                                        s++;
        !           381:                                opcode |= m << 5;
        !           382:                                opcode |= a << 13;
        !           383:                                continue;
        !           384: 
        !           385:                        /* bug #41317 .... [email protected]
        !           386:                         * Fri Jul 22 09:43:46 PDT 1994
        !           387:                         *
        !           388:                         * Modified to parse 'cache control hints'
        !           389:                         *
        !           390:                         * These parse ",cc" and encode "cc" in 2 bits at 20,
        !           391:                         * where "cc" encoding is as given in Tables 5-8, 5-9.
        !           392:                         * Refer to 'PA-RISC 1.1 Architecture and Instruction Set
        !           393:                         * Reference Manual, Second Edition' for the tables.
        !           394:                         */
        !           395:                        case 'Y':   /* Store Bytes Short completer */
        !           396:                                                /* with cache control hints    */
        !           397:                        {
        !           398:                                unsigned long result = (unsigned long)0UL;
        !           399:                                
        !           400:                                i = m = a = 0;
        !           401:                                while ( *s == ',' && i < 3 ) {
        !           402:                                        s++;
        !           403:                                        if ( strncasecmp(s,"m",1) == 0 )
        !           404:                                                m = 1;
        !           405:                                        else if ( strncasecmp(s,"b",1) == 0 &&
        !           406:                                                          (strncasecmp((s+1),"c",1) != 0) )
        !           407:                                                        a = 0;
        !           408:                                                else if ( strncasecmp(s,"e",1) == 0 )
        !           409:                                                                a = 1;
        !           410:                                                        else if ( strncmp(s,",",1) == 0 ) /* no completer */
        !           411:                                                                result |= parse_cache_control_hint(&s, 0);
        !           412:                                                        else if ( (strncasecmp(s,"c",1) == 0) ||
        !           413:                                                                (strncasecmp(s,"b",1) == 0) ) {/* just 1 completer */
        !           414:                                                                s--;
        !           415:                                                                result |= parse_cache_control_hint(&s, 0);
        !           416:                                                        }
        !           417:                                                        else
        !           418:                                                                as_bad("Unrecognized Store Bytes Short"
        !           419:                                                                        "Completer with cache control hints"
        !           420:                                                                        " ...assuming 0");
        !           421:                                        if (result == (unsigned long)0UL)
        !           422:                                                s++;
        !           423:                                        i++;
        !           424:                                }
        !           425: /**            if ( i >= 2 ) **/
        !           426:                                if ( i > 3 )
        !           427:                                        as_bad("Illegal Store Bytes Short Completer "
        !           428:                                                "with cache control hints ...  extras ignored");
        !           429:                                while ( *s == ' ' || *s == '\t' ) /* skip to next operand */
        !           430:                                        s++;
        !           431:                                opcode |= result;
        !           432:                                opcode |= m << 5;
        !           433:                                opcode |= a << 13;
        !           434:                                continue;
        !           435:                        }
        !           436:                        case '<':   /* non-negated compare/subtract conditions. */
        !           437:                                cmpltr = pa_parse_nonneg_cmpsub_cmpltr(&s);
        !           438:                                if ( cmpltr < 0 ) {
        !           439:                                        as_bad("Unrecognized Compare/Subtract Condition: %c",*s);
        !           440:                                        cmpltr = 0;
        !           441:                                }
        !           442:                                opcode |= cmpltr << 13;
        !           443:                                continue;
        !           444:                        case '?':   /* negated or non-negated cmp/sub conditions. */
        !           445:                                        /* used only by ``comb'' and ``comib'' pseudo-ops */
        !           446:                                save_s = s;
        !           447:                                cmpltr = pa_parse_nonneg_cmpsub_cmpltr(&s);
        !           448:                                if ( cmpltr < 0 ) {
        !           449:                                        s = save_s;
        !           450:                                        cmpltr = pa_parse_neg_cmpsub_cmpltr(&s);
        !           451:                                        if ( cmpltr < 0 ) {
        !           452:                                                as_bad("Unrecognized Compare/Subtract Condition: %c"
        !           453:                                                        ,*s);
        !           454:                                                cmpltr = 0;
        !           455:                                        }
        !           456:                                        else {
        !           457:                                                opcode |= 1 << 27; /* required opcode change to make
        !           458:                                                                                        COMIBT into a COMIBF or a
        !           459:                                                                                        COMBT into a COMBF or a
        !           460:                                                                                        ADDBT into a ADDBF or a
        !           461:                                                                                        ADDIBT into a ADDIBF */
        !           462:                                        }
        !           463:                                }
        !           464:                                opcode |= cmpltr << 13;
        !           465:                                continue;
        !           466:                        case '!':   /* negated or non-negated add conditions. */
        !           467:                                /* used only by ``addb'' and ``addib'' pseudo-ops */
        !           468:                                save_s = s;
        !           469:                                cmpltr = pa_parse_nonneg_add_cmpltr(&s);
        !           470:                                if ( cmpltr < 0 ) {
        !           471:                                        s = save_s;
        !           472:                                        cmpltr = pa_parse_neg_add_cmpltr(&s);
        !           473:                                        if ( cmpltr < 0 ) {
        !           474:                                                as_bad("Unrecognized Compare/Subtract Condition: %c",
        !           475:                                                        *s);
        !           476:                                                cmpltr = 0;
        !           477:                                        }
        !           478:                                        else {
        !           479:                                                opcode |= 1 << 27; /* required opcode change to make
        !           480:                                                                                        COMIBT into a COMIBF or a
        !           481:                                                                                        COMBT into a COMBF or a
        !           482:                                                                                        ADDBT into a ADDBF or a
        !           483:                                                                                        ADDIBT into a ADDIBF */
        !           484:                                        }
        !           485:                                }
        !           486:                                opcode |= cmpltr << 13;
        !           487:                                continue;
        !           488:                        case '-':   /* compare/subtract conditions */
        !           489:                                f = cmpltr = 0;
        !           490:                                save_s = s;
        !           491:                                if ( *s == ',' ) {
        !           492:                                        cmpltr = pa_parse_nonneg_cmpsub_cmpltr(&s);
        !           493:                                        if ( cmpltr < 0 ) {
        !           494:                                                f = 1;
        !           495:                                                s = save_s;
        !           496:                                                cmpltr = pa_parse_neg_cmpsub_cmpltr(&s);
        !           497:                                                if ( cmpltr < 0 ) {
        !           498:                                                        as_bad("Unrecognized Compare/Subtract Condition");
        !           499:                                                }
        !           500:                                        }
        !           501:                                }
        !           502:                                opcode |= cmpltr << 13;
        !           503:                                opcode |= f << 12;
        !           504:                                continue;
        !           505:                        case '+':   /* non-negated add conditions */
        !           506:                                flag = nullif = cmpltr = 0;
        !           507:                                if ( *s == ',' ) {
        !           508:                                        s++;
        !           509:                                        name = s;
        !           510:                                        while ( *s != ',' && *s != ' ' && *s != '\t' )
        !           511:                                                s += 1;
        !           512:                                        c = *s;
        !           513:                                        *s = 0x00;
        !           514:                                        if ( strcmp(name,"=") == 0 ) {
        !           515:                                                cmpltr = 1;
        !           516:                                                }
        !           517:                                                else if ( strcmp(name,"<") == 0 ) {
        !           518:                                                cmpltr = 2;
        !           519:                                                }
        !           520:                                                else if ( strcmp(name,"<=") == 0 ) {
        !           521:                                                cmpltr = 3;
        !           522:                                                }
        !           523:                                                else if ( strcasecmp(name,"nuv") == 0 ) {
        !           524:                                                cmpltr = 4;
        !           525:                                                }
        !           526:                                                else if ( strcasecmp(name,"znv") == 0 ) {
        !           527:                                                cmpltr = 5;
        !           528:                                                }
        !           529:                                                else if ( strcasecmp(name,"sv") == 0 ) {
        !           530:                                                cmpltr = 6;
        !           531:                                                }
        !           532:                                                else if ( strcasecmp(name,"od") == 0 ) {
        !           533:                                                cmpltr = 7;
        !           534:                                                }
        !           535:                                                else if ( strcasecmp(name,"n") == 0 ) {
        !           536:                                                nullif = 1;
        !           537:                                                }
        !           538:                                                else if ( strcasecmp(name,"tr") == 0 ) {
        !           539:                                                cmpltr = 0;
        !           540:                                                flag   = 1;
        !           541:                                                }
        !           542:                                                else if ( strcasecmp(name,"<>") == 0 ) {
        !           543:                                                flag = cmpltr = 1;
        !           544:                                                }
        !           545:                                                else if ( strcasecmp(name,">=") == 0 ) {
        !           546:                                                cmpltr = 2;
        !           547:                                                flag   = 1;
        !           548:                                                }
        !           549:                                                else if ( strcasecmp(name,">") == 0 ) {
        !           550:                                                cmpltr = 3;
        !           551:                                                flag   = 1;
        !           552:                                                }
        !           553:                                                else if ( strcasecmp(name,"uv") == 0 ) {
        !           554:                                                cmpltr = 4;
        !           555:                                                flag   = 1;
        !           556:                                                }
        !           557:                                                else if ( strcasecmp(name,"vnz") == 0 ) {
        !           558:                                                cmpltr = 5;
        !           559:                                                flag   = 1;
        !           560:                                                }
        !           561:                                                else if ( strcasecmp(name,"nsv") == 0 ) {
        !           562:                                                cmpltr = 6;
        !           563:                                                flag   = 1;
        !           564:                                                }
        !           565:                                                else if ( strcasecmp(name,"ev") == 0 ) {
        !           566:                                                cmpltr = 7;
        !           567:                                                flag   = 1;
        !           568:                                                }
        !           569:                                                else
        !           570:                                                as_bad("Unrecognized Add Condition: %s",name);
        !           571:                                        *s = c;
        !           572:                                }
        !           573:                                nullif = pa_parse_nullif(&s);
        !           574:                                opcode |= nullif << 1;
        !           575:                                opcode |= cmpltr << 13;
        !           576:                                opcode |= flag << 12;
        !           577:                                continue;               
        !           578:                        case '&':   /* logical instruction conditions */
        !           579:                                f = cmpltr = 0;
        !           580:                                if ( *s == ',' ) {
        !           581:                                        s++;
        !           582:                                        name = s;
        !           583:                                        while ( *s != ',' && *s != ' ' && *s != '\t' )
        !           584:                                                s += 1;
        !           585:                                        c = *s;
        !           586:                                        *s = 0x00;
        !           587:                                        if ( strcmp(name,"=") == 0 ) {
        !           588:                                                cmpltr = 1;
        !           589:                                                }
        !           590:                                                else if ( strcmp(name,"<") == 0 ) {
        !           591:                                                cmpltr = 2;
        !           592:                                                }
        !           593:                                                else if ( strcmp(name,"<=") == 0 ) {
        !           594:                                                cmpltr = 3;
        !           595:                                                }
        !           596:                                                else if ( strcasecmp(name,"od") == 0 ) {
        !           597:                                                cmpltr = 7;
        !           598:                                                }
        !           599:                                                else if ( strcasecmp(name,"tr") == 0 ) {
        !           600:                                                cmpltr = 0;
        !           601:                                                f = 1;
        !           602:                                                }
        !           603:                                                else if ( strcmp(name,"<>") == 0 ) {
        !           604:                                                f = cmpltr = 1;
        !           605:                                                }
        !           606:                                                else if ( strcmp(name,">=") == 0 ) {
        !           607:                                                cmpltr = 2;
        !           608:                                                f = 1;
        !           609:                                                }
        !           610:                                                else if ( strcmp(name,">") == 0 ) {
        !           611:                                                cmpltr = 3;
        !           612:                                                f = 1;
        !           613:                                                }
        !           614:                                                else if ( strcasecmp(name,"ev") == 0 ) {
        !           615:                                                cmpltr = 7;
        !           616:                                                f = 1;
        !           617:                                                }
        !           618:                                                else
        !           619:                                                as_bad("Unrecognized Logical Instruction Condition:"
        !           620:                                                        " %s",name);
        !           621:                                        *s = c;
        !           622:                                }
        !           623:                                opcode |= cmpltr << 13;
        !           624:                                opcode |= f << 12;              
        !           625:                                continue;
        !           626:                        case 'U':   /* unit instruction conditions */
        !           627:                                cmpltr = 0;
        !           628:                                f = 0;
        !           629:                                if ( *s == ',' ) {
        !           630:                                        s++;
        !           631:                                        if ( strncasecmp(s,"sbz",3) == 0 ) {
        !           632:                                                cmpltr = 2;
        !           633:                                                s += 3;
        !           634:                                                }
        !           635:                                                else if ( strncasecmp(s,"shz",3) == 0 ) {
        !           636:                                                cmpltr = 3;
        !           637:                                                s += 3;
        !           638:                                                }
        !           639:                                                else if ( strncasecmp(s,"sdc",3) == 0 ) {
        !           640:                                                cmpltr = 4;
        !           641:                                                s += 3;
        !           642:                                                }
        !           643:                                                else if ( strncasecmp(s,"sbc",3) == 0 ) {
        !           644:                                                cmpltr = 6;
        !           645:                                                s += 3;
        !           646:                                                }
        !           647:                                                else if ( strncasecmp(s,"shc",3) == 0 ) {
        !           648:                                                cmpltr = 7;
        !           649:                                                s += 3;
        !           650:                                                }
        !           651:                                                else if ( strncasecmp(s,"tr",2) == 0 ) {
        !           652:                                                cmpltr = 0;
        !           653:                                                f = 1;
        !           654:                                                s += 2;
        !           655:                                                }
        !           656:                                                else if ( strncasecmp(s,"nbz",3) == 0 ) {
        !           657:                                                cmpltr = 2;
        !           658:                                                f = 1;
        !           659:                                                s += 3;
        !           660:                                                }
        !           661:                                                else if ( strncasecmp(s,"nhz",3) == 0 ) {
        !           662:                                                cmpltr = 3;
        !           663:                                                f = 1;
        !           664:                                                s += 3;
        !           665:                                                }
        !           666:                                                else if ( strncasecmp(s,"ndc",3) == 0 ) {
        !           667:                                                cmpltr = 4;
        !           668:                                                f = 1;
        !           669:                                                s += 3;
        !           670:                                                }
        !           671:                                                else if ( strncasecmp(s,"nbc",3) == 0 ) {
        !           672:                                                cmpltr = 6;
        !           673:                                                f = 1;
        !           674:                                                s += 3;
        !           675:                                                }
        !           676:                                                else if ( strncasecmp(s,"nhc",3) == 0 ) {
        !           677:                                                cmpltr = 7;
        !           678:                                                f = 1;
        !           679:                                                s += 3;
        !           680:                                                }
        !           681:                                                else
        !           682:                                                as_bad("Unrecognized Logical Instruction Condition:"
        !           683:                                                        " %c",*s);
        !           684:                                }
        !           685:                                opcode |= cmpltr << 13;
        !           686:                                opcode |= f << 12;              
        !           687:                                continue;
        !           688:                        case '>':   /* shift/extract/deposit conditions. */
        !           689:                                cmpltr = 0;
        !           690:                                if ( *s == ',' ) {
        !           691:                                        s++;
        !           692:                                        name = s;
        !           693:                                        while ( *s != ',' && *s != ' ' && *s != '\t' )
        !           694:                                                s += 1;
        !           695:                                        c = *s;
        !           696:                                        *s = 0x00;
        !           697:                                        if ( strcmp(name,"=") == 0 ) {
        !           698:                                                cmpltr = 1;
        !           699:                                                }
        !           700:                                                else if ( strcmp(name,"<") == 0 ) {
        !           701:                                                cmpltr = 2;
        !           702:                                                }
        !           703:                                                else if ( strcasecmp(name,"od") == 0 ) {
        !           704:                                                cmpltr = 3;
        !           705:                                                }
        !           706:                                                else if ( strcasecmp(name,"tr") == 0 ) {
        !           707:                                                cmpltr = 4;
        !           708:                                                }
        !           709:                                                else if ( strcmp(name,"<>") == 0 ) {
        !           710:                                                cmpltr = 5;
        !           711:                                                }
        !           712:                                                else if ( strcmp(name,">=") == 0 ) {
        !           713:                                                cmpltr = 6;
        !           714:                                                }
        !           715:                                                else if ( strcasecmp(name,"ev") == 0 ) {
        !           716:                                                cmpltr = 7;
        !           717:                                                }
        !           718:                                                else
        !           719:                                                as_bad("Unrecognized Shift/Extract/Deposit"
        !           720:                                                        "Condition: %s",name);
        !           721:                                        *s = c;
        !           722:                                }
        !           723:                                opcode |= cmpltr << 13;
        !           724:                                continue;
        !           725:                        case '~':   /* bvb,bb conditions */
        !           726:                                cmpltr = 0;
        !           727:                                if ( *s == ',' ) {
        !           728:                                        s++;
        !           729:                                        if ( strncmp(s,"<",1) == 0 ) {
        !           730:                                                cmpltr = 2;
        !           731:                                                s++;
        !           732:                                                }
        !           733:                                                else if ( strncmp(s,">=",2) == 0 ) {
        !           734:                                                cmpltr = 6;
        !           735:                                                s += 2;
        !           736:                                                }
        !           737:                                                else
        !           738:                                                as_bad("Unrecognized Bit Branch Condition: %c",*s);
        !           739:                                }
        !           740:                                opcode |= cmpltr << 13;
        !           741:                                continue;
        !           742:                        case 'V':   /* 5  bit immediate at 31 */
        !           743:                                getExpression(s);
        !           744:                                im5 = low_sign_unext(evaluateAbsolute(
        !           745:                                                     the_insn.exp,0),5);
        !           746:                                opcode |= im5;
        !           747:                                s = expr_end;
        !           748:                                continue;
        !           749:                        case 'r':   /* 5  bit immediate at 31 */
        !           750:                                                /* (unsigned value for the break instruction) */
        !           751:                                getExpression(s);
        !           752:                                im5 = evaluateAbsolute(the_insn.exp,0);
        !           753:                                if ( im5 > 31 ) {
        !           754:                                        as_bad("Operand out of range. Was: %d. Should be"
        !           755:                                                "[0..31]. Assuming %d.\n",im5,im5&0x1f);
        !           756:                                        im5 = im5 & 0x1f;
        !           757:                                }
        !           758:                                opcode |= im5;
        !           759:                                s = expr_end;
        !           760:                                continue;
        !           761:                        case 'R':   /* 5  bit immediate at 15 */
        !           762: /* (unsigned value for the ssm and rsm instruction) */
        !           763:                                getExpression(s);
        !           764:                                im5 = evaluateAbsolute(the_insn.exp,0);
        !           765:                                if ( im5 > 31 ) {
        !           766:                                        as_bad("Operand out of range. Was: %d. Should be"
        !           767:                                                "[0..31]. Assuming %d.\n",im5,im5&0x1f);
        !           768:                                        im5 = im5 & 0x1f;
        !           769:                                }
        !           770:                                opcode |= im5 << 16;
        !           771:                                s = expr_end;
        !           772:                                continue;
        !           773:                        case 'i':   /* 11 bit immediate at 31 */
        !           774:                                getExpression(s);
        !           775:                                if ( the_insn.exp.X_seg == SEG_ABSOLUTE ) {
        !           776:                                        im11 = low_sign_unext(evaluateAbsolute(
        !           777:                                                        the_insn.exp,0),11);
        !           778:                                        opcode |= im11;
        !           779:                                }
        !           780:                                else {
        !           781:                                        the_insn.code = 'i';
        !           782:                                }
        !           783:                                s = expr_end;
        !           784:                                continue;
        !           785:                        case 'j':   /* 14 bit immediate at 31 --- LO14 */
        !           786:                        {
        !           787:                                int field_selector = parse_L_or_R(s);
        !           788:                                switch (field_selector) {
        !           789:                                case 2: /* found the field selector R`*/
        !           790:                                case 1: /* found the field selector L`*/
        !           791:                                        s += 2;  /* eat up L` or R` */
        !           792:                                case 0: /* not found */
        !           793:                                        getExpression(s);
        !           794:                                        break;
        !           795:                                default:
        !           796:                                        as_bad("Bad field selector. Was: %.2s. Should be either L` or R`\n",s);
        !           797:                                        break;
        !           798:                                }
        !           799:                                if ( the_insn.exp.X_seg == SEG_ABSOLUTE ) {
        !           800:                                        im14 = low_sign_unext(
        !           801: evaluateAbsolute(the_insn.exp,field_selector), 14);
        !           802: 
        !           803: /* I donot think the mask is necessary here  low_sign_unext() takes */
        !           804: /* care of putting only 14 bits in im14 ! ...       090993 ... USV  */
        !           805: /*                                     if (field_selector)
        !           806:                                                opcode |= (im14 & 0x7ff);
        !           807:                                        else
        !           808: */
        !           809:                                        opcode |= im14;
        !           810:                                }
        !           811:                                else {
        !           812:                                        the_insn.reloc = HPPA_RELOC_LO14;
        !           813:                                        the_insn.code = 'j';
        !           814:                                }
        !           815:                                s = expr_end;
        !           816:                                continue;
        !           817:                        }  
        !           818:                        case 'z':       /* 17 bit branch displacement (non-pc-relative) */
        !           819:                                /* for be, ble --- BR17*/
        !           820:                                /* bl, ble  in absence of L` or R` can have */
        !           821:                                /* a 17 bit immmidiate number */
        !           822:                        {
        !           823:                                unsigned long w, w1, w2;
        !           824:                                int field_selector = parse_L_or_R(s);
        !           825:                                switch (field_selector) {
        !           826:                                case 2: /* found the field selector R`*/
        !           827:                                case 1: /* found the field selector L`*/
        !           828:                                        s += 2;  /* eat up L` or R` */
        !           829:                                case 0: /* not found */
        !           830:                                        getExpression(s);
        !           831:                                        break;
        !           832:                                default:
        !           833:                                        as_bad("Bad field selector. Was: %.2s." "Should be either L` or R`\n",s);
        !           834:                                        break;
        !           835:                                }
        !           836:                                if ( the_insn.exp.X_seg == SEG_ABSOLUTE ) {
        !           837:                                        im14 = sign_unext(
        !           838:                                                evaluateAbsolute(the_insn.exp,field_selector),
        !           839:                                                17);
        !           840:                                        dis_assemble_17(im14>>2,&w1,&w2,&w);
        !           841:                                        opcode |= ( ( w2 << 2 ) | ( w1 << 16 ) | w );
        !           842:                                }
        !           843:                                else {
        !           844:                                        the_insn.reloc = HPPA_RELOC_BR17;
        !           845:                                        the_insn.code = 'z';
        !           846:                                }
        !           847:                                s = expr_end;
        !           848:                                continue;
        !           849:                        }
        !           850:                        case 'k':   /* 21 bit immediate at 31 --- HI21 */
        !           851:                        {
        !           852:                                int field_selector = parse_L_or_R(s);
        !           853:                                switch (field_selector) {
        !           854:                                case 2: /* found the field selector R`*/
        !           855:                                case 1: /* found the field selector L`*/
        !           856:                                        s += 2;  /* eat up L` or R` */
        !           857:                                case 0: /* not found */
        !           858:                                        getExpression(s);
        !           859:                                        break;
        !           860:                                default:
        !           861:                                        as_bad("Bad field selector. Was: %.2s." "Should be either L` or R`\n",s);
        !           862:                                        break;
        !           863:                                }
        !           864:                                if ( the_insn.exp.X_seg == SEG_ABSOLUTE ) {
        !           865:                                        im21 = dis_assemble_21(
        !           866: (evaluateAbsolute(the_insn.exp,field_selector) >> 11));
        !           867:                                        opcode |=  im21 ;
        !           868:                                }
        !           869:                                else {
        !           870:                                        the_insn.reloc = HPPA_RELOC_HI21;
        !           871:                                        the_insn.code = 'k';
        !           872:                                }
        !           873:                                s = expr_end;
        !           874:                                continue;
        !           875:                        }
        !           876:                        case 'n':   /* nullification for branch instructions */
        !           877:                                nullif = pa_parse_nullif(&s);
        !           878:                                opcode |= nullif << 1;
        !           879:                                continue;               
        !           880:                        case 'w':   /* 12 bit branch displacement */
        !           881:                                getExpression(s);
        !           882:                                the_insn.pcrel_reloc = 0;
        !           883:                                the_insn.pcrel = 1;
        !           884:                                if ( the_insn.exp.X_add_symbol ) {
        !           885:                                    if ( strcmp(
        !           886: the_insn.exp.X_add_symbol->sy_nlist.n_un.n_name,"L0\001") == 0 ) {
        !           887:                                        unsigned long w1,w,result;
        !           888:                                        result = sign_unext( (the_insn.exp.X_add_number
        !           889:                                                        - 8) >> 2,
        !           890:                                                        12);
        !           891:                                        dis_assemble_12(result,&w1,&w);
        !           892:                                        opcode |= ( ( w1 << 2 ) | w );
        !           893:                                    }
        !           894:                                    else {
        !           895: /* this has to be wrong -- dont know what is right! */
        !           896: /*  the_insn.reloc = R_PCREL_CALL; */
        !           897:                                        the_insn.reloc = HPPA_RELOC_12BRANCH;
        !           898:                                                the_insn.code = 'w';
        !           899:                                    }
        !           900:                                }
        !           901:                                else {
        !           902:                                    unsigned long w1,w,result;
        !           903:                                    result = sign_unext( the_insn.exp.X_add_number >> 
        !           904:                                        2,12);
        !           905:                                    dis_assemble_12(result,&w1,&w);
        !           906:                                    opcode |= ( ( w1 << 2 ) | w );
        !           907:                                }
        !           908:                                s = expr_end;
        !           909:                                continue;
        !           910:                        case 'W':   /* 17 bit branch displacement --- BL17 */
        !           911:                                getExpression(s);
        !           912:                                /*
        !           913:                                 * The NeXT linker has the ability to scatter
        !           914:                                 * blocks of sections between labels.  This
        !           915:                                 * requires that brances to labels that survive
        !           916:                                 * to the link phase must be able to be
        !           917:                                 * relocated.
        !           918:                                 */
        !           919:                                if(the_insn.exp.X_add_symbol != NULL &&
        !           920:                                   (the_insn.exp.X_add_symbol->sy_name[0] != 'L'
        !           921:                                    || flagseen['L']))
        !           922:                                    the_insn.pcrel_reloc = 1;
        !           923:                                else
        !           924:                                    the_insn.pcrel_reloc = 0;
        !           925:                                the_insn.pcrel = 1;
        !           926:                                if ( the_insn.exp.X_add_symbol ) {
        !           927:                                        if ( strcmp(the_insn.exp.X_add_symbol->sy_nlist.n_un.n_name,"L0\001") == 0 ) {
        !           928:                                                unsigned long w2,w1,w,result;
        !           929: 
        !           930:                                                result = sign_unext( 
        !           931:                                                        (the_insn.exp.X_add_number - 8) >> 2,17);
        !           932:                                                dis_assemble_17(result,&w1,&w2,&w);
        !           933:                                                opcode |= ( ( w2 << 2 ) | ( w1 << 16 ) | w );
        !           934:                                        }
        !           935:                                        else {
        !           936:                                                if ( (the_insn.reloc == HPPA_RELOC_JBSR) &&
        !           937:                                                 (the_insn.exp.X_add_symbol->sy_name[0] != 'L') )
        !           938:                                                        as_fatal("Stub label used in a JBSR must be "
        !           939:                                                                "non-relocatable");
        !           940:                                                the_insn.reloc = HPPA_RELOC_BL17;
        !           941:                                                the_insn.code = 'W';
        !           942:                                        }
        !           943:                                }
        !           944:                                else {
        !           945:                                        unsigned long w2,w1,w,result;
        !           946: 
        !           947:                                        result = sign_unext( the_insn.exp.X_add_number >> 2,17);
        !           948:                                        dis_assemble_17(result,&w1,&w2,&w);
        !           949:                                        opcode |= ( ( w2 << 2 ) | ( w1 << 16 ) | w );
        !           950:                                }
        !           951:                                s = expr_end;
        !           952:                                continue;
        !           953:                        case '@':   /* 17 bit branch displacement --- JBSR */
        !           954:                                getExpression(s);
        !           955: 
        !           956: /*
        !           957:  * assumption here is this will only be used in case of jbsr
        !           958:  * in which case the format is 
        !           959:  *             jbsr,n symbol,register,label
        !           960:  * and a relocation entry for symbol needs to be created
        !           961:  */
        !           962:  
        !           963:                                the_insn.pcrel = 0;
        !           964:                                the_insn.pcrel_reloc = 1;
        !           965:                                the_insn.reloc = HPPA_RELOC_JBSR;
        !           966:                                the_insn.code = '@';
        !           967:                                s = expr_end;
        !           968:  /*
        !           969:   * The code to hook a frag in the chain should be here.
        !           970:   * Then set a flag saying that the next 'W' should not create a relocation
        !           971:   * entry. The way 'jbsr' is expected to work is the label will always be
        !           972:   * local!
        !           973:   * This flag should be reset in 'W'.
        !           974:   */
        !           975:                                found_jbsr = 1;
        !           976:                                toP = frag_more(4);
        !           977:                                fix_new(frag_now,
        !           978:                                        (toP - frag_now->fr_literal),
        !           979:                                        4,
        !           980:                                        the_insn.exp.X_add_symbol,
        !           981:                                        the_insn.exp.X_subtract_symbol,
        !           982:                                        the_insn.exp.X_add_number,
        !           983:                                        the_insn.pcrel,
        !           984:                                        the_insn.pcrel_reloc,
        !           985:                                        the_insn.reloc);
        !           986: 
        !           987:                                continue;
        !           988:                        case 'B':   /* either "s,b" or "b" where b & s are defined above */
        !           989:                                reg1 = pa_parse_number(&s);
        !           990:                                if ( *s == ',' ) {
        !           991:                                        s++;
        !           992:                                        reg2 = pa_parse_number(&s);
        !           993:                                }
        !           994:                                else {
        !           995:                                        reg2 = reg1;
        !           996:                                        reg1 = 0;
        !           997:                                }
        !           998:                                if ( reg1 < 4 && reg1 >= 0 ) {
        !           999:                                        opcode |= reg1 << 14;
        !          1000:                                        opcode |= reg2 << 21;
        !          1001:                                        continue;
        !          1002:                                }
        !          1003:                                break;
        !          1004:                        case 'p':   /* 5 bit shift count at 26 (to support SHD instr.) */
        !          1005:                                                /* value is encoded in instr. as 31-p where p is   */
        !          1006:                                                /* the value scanned here */
        !          1007:                                getExpression(s);
        !          1008:                                if ( the_insn.exp.X_seg == SEG_ABSOLUTE ) {
        !          1009:                                        opcode |= ( ( (31 - the_insn.exp.X_add_number) & 0x1f ) << 5 );
        !          1010:                                }
        !          1011:                                s = expr_end;
        !          1012:                                continue;
        !          1013:                        case 'P':   /* 5-bit bit position at 26 */
        !          1014:                                getExpression(s);
        !          1015:                                if ( the_insn.exp.X_seg == SEG_ABSOLUTE ) {
        !          1016:                                        opcode |= ( the_insn.exp.X_add_number & 0x1f ) << 5;
        !          1017:                                }
        !          1018:                                s = expr_end;
        !          1019:                                continue;
        !          1020:                        case 'Q':   /* 5  bit immediate at 10 */
        !          1021:                                                /* (unsigned bit position value for the bb instruction) */
        !          1022:                                getExpression(s);
        !          1023:                                im5 = evaluateAbsolute(the_insn.exp,0);
        !          1024:                                if ( im5 > 31 ) {
        !          1025:                                        as_bad("Operand out of range. Was: %d. Should be"
        !          1026:                                                "[0..31]. Assuming %d.\n",im5,im5&0x1f);
        !          1027:                                        im5 = im5 & 0x1f;
        !          1028:                                }
        !          1029:                                opcode |= im5 << 21;
        !          1030:                                s = expr_end;
        !          1031:                                continue;
        !          1032:                        case 'A':   /* 13 bit immediate at 18 (to support BREAK instr.) */
        !          1033:                                getAbsoluteExpression(s);
        !          1034:                                if ( the_insn.exp.X_seg == SEG_ABSOLUTE )
        !          1035:                                opcode |= (the_insn.exp.X_add_number & 0x1fff) << 13;
        !          1036:                                s = expr_end;
        !          1037:                                continue;
        !          1038:                        case 'Z':   /* System Control Completer(for LDA, LHA, etc.) */
        !          1039:                                if ( *s == ',' && ( *(s+1) == 'm' || *(s+1) == 'M' ) ) {
        !          1040:                                        m = 1;
        !          1041:                                        s += 2;
        !          1042:                                }
        !          1043:                                else
        !          1044:                                        m = 0;
        !          1045:   
        !          1046:                                opcode |= m << 5;
        !          1047:                                while ( *s == ' ' || *s == '\t' ) /* skip to next operand */
        !          1048:                                        s++;
        !          1049:   
        !          1050:                                continue;
        !          1051:                        case 'D':   /* 26 bit immediate at 31 (to support DIAG instr.) */
        !          1052:                                                /* the action (and interpretation of this operand is
        !          1053:                                                        implementation dependent) */
        !          1054:                                getExpression(s);
        !          1055:                                if ( the_insn.exp.X_seg == SEG_ABSOLUTE ) {
        !          1056:                                        opcode |= ( (evaluateAbsolute(the_insn.exp,0) & 0x1ffffff) << 1 );
        !          1057:                                }
        !          1058:                                else
        !          1059:                                        as_bad("Illegal DIAG operand");
        !          1060:                                        s = expr_end;
        !          1061:                                continue;
        !          1062:                        case 'f':   /* 3 bit Special Function Unit (SFU) identifier at 25 */
        !          1063:                                sfu = pa_parse_number(&s);
        !          1064:                                if ( (sfu > 7) || (sfu < 0) )
        !          1065:                                        as_bad("Illegal SFU identifier: %02x", sfu);
        !          1066:                                opcode |= (sfu & 7) << 6;
        !          1067:                                continue;
        !          1068:                        case 'O':   /* 20 bit SFU op. split between 15 bits at 20 and 5 bits at 31 */
        !          1069:                                getExpression(s);
        !          1070:                                s = expr_end;
        !          1071:                                continue;
        !          1072:                        case 'o':   /* 15 bit Special Function Unit operation at 20 */
        !          1073:                                getExpression(s);
        !          1074:                                s = expr_end;
        !          1075:                                continue;
        !          1076:                        case '2':   /* 22 bit SFU op. split between 17 bits at 20
        !          1077:                                                        and 5 bits at 31 */
        !          1078:                                getExpression(s);
        !          1079:                                s = expr_end;
        !          1080:                                continue;
        !          1081:                        case '1':   /* 15 bit SFU op. split between 10 bits at 20
        !          1082:                                                        and 5 bits at 31 */
        !          1083:                                getExpression(s);
        !          1084:                                s = expr_end;
        !          1085:                                continue;
        !          1086:                        case '0':   /* 10 bit SFU op. split between 5 bits at 20
        !          1087:                                                        and 5 bits at 31 */
        !          1088:                                getExpression(s);
        !          1089:                                s = expr_end;
        !          1090:                                continue;
        !          1091:                        case 'u':   /* 3 bit coprocessor unit identifier at 25 */
        !          1092:                                getExpression(s);
        !          1093:                                s = expr_end;
        !          1094:                                continue;
        !          1095:                        case 'F':   /* Source FP Operand Format Completer (2 bits at 20) */
        !          1096:                                f = pa_parse_fp_format(&s);
        !          1097:                                opcode |= (int)f << 11;
        !          1098:                                the_insn.fpof1 = f;
        !          1099:                                continue;
        !          1100:                        case 'G':   /* Destination FP Operand Format Completer (2 bits at 18) */
        !          1101:                                s--;    /* need to pass the previous comma to pa_parse_fp_format */
        !          1102:                                f = pa_parse_fp_format(&s);
        !          1103:                                opcode |= (int)f << 13;
        !          1104:                                the_insn.fpof2 = f;
        !          1105:                                continue;
        !          1106:                        case 'M':   /* FP Compare Conditions (encoded as 5 bits at 31) */
        !          1107:                                cond = pa_parse_fp_cmp_cond(&s);
        !          1108:                                opcode |= cond;
        !          1109:                                continue;
        !          1110: 
        !          1111:                        case 'v':   /* a 't' type extended to handle L/R register halves. */
        !          1112:                                {
        !          1113:                                        struct pa_89_fp_reg_struct result;
        !          1114: 
        !          1115:                                        pa_89_parse_number(&s,&result);
        !          1116:                                        if ( result.number_part < 32 && result.number_part >= 0 ) {
        !          1117:                                                opcode |= (result.number_part & 0x1f);
        !          1118: 
        !          1119:                                                /* 0x30 opcodes are FP arithmetic operation opcodes */
        !          1120:                                                /* load/store FP opcodes do not get converted to 0x38 */
        !          1121:                                                /* opcodes like the 0x30 opcodes do */
        !          1122:                                                if ( need_89_opcode(&the_insn,&result) ) {
        !          1123:                                                        if ( (opcode & 0xfc000000) == 0x30000000 ) {
        !          1124:                                                                opcode |= (result.L_R_select & 1) << 6;
        !          1125:                                                                opcode |= 1 << 27;
        !          1126:                                                        }
        !          1127:                                                        else {
        !          1128:                                                                opcode |= (result.L_R_select & 1) << 6;
        !          1129:                                                        }
        !          1130:                                                }
        !          1131:                                                continue;
        !          1132:                                        }
        !          1133:                                }
        !          1134:                                break;
        !          1135:                        case 'E':   /* a 'b' type extended to handle L/R register halves. */
        !          1136:                                {
        !          1137:                                        struct pa_89_fp_reg_struct result;
        !          1138: 
        !          1139:                                        pa_89_parse_number(&s,&result);
        !          1140:                                        if ( result.number_part < 32 && result.number_part >= 0 ) {
        !          1141:                                                opcode |= (result.number_part & 0x1f) << 21;
        !          1142:                                                if ( need_89_opcode(&the_insn,&result) ) {
        !          1143:                                                        opcode |= (result.L_R_select & 1) << 7;
        !          1144:                                                        opcode |= 1 << 27;
        !          1145:                                                }
        !          1146:                                                continue;
        !          1147:                                        }
        !          1148:                                }
        !          1149:                                break;
        !          1150: 
        !          1151:                        case 'X':   /* an 'x' type extended to handle L/R register halves. */
        !          1152:                                {
        !          1153:                                        struct pa_89_fp_reg_struct result;
        !          1154: 
        !          1155: 
        !          1156:                                        pa_89_parse_number(&s,&result);
        !          1157:                                        if ( result.number_part < 32 && result.number_part >= 0 ) {
        !          1158:                                                opcode |= (result.number_part & 0x1f) << 16;
        !          1159:                                                if ( need_89_opcode(&the_insn,&result) ) {
        !          1160:                                                        opcode |= (result.L_R_select & 1) << 12;
        !          1161:                                                        opcode |= 1 << 27;
        !          1162:                                                }
        !          1163:                                                continue;
        !          1164:                                        }
        !          1165:                                }
        !          1166:                                break;
        !          1167: 
        !          1168:                        case '4':   /* 5 bit register field at 10
        !          1169:                                                (used in 'fmpyadd' and 'fmpysub') */
        !          1170:                                {
        !          1171:                                        struct pa_89_fp_reg_struct result;
        !          1172:                                        int status;
        !          1173: 
        !          1174:                                        status = pa_89_parse_number(&s,&result);
        !          1175:                                        if ( result.number_part < 32 && result.number_part >= 0 ) {
        !          1176:                                                if ( the_insn.fpof1 == SGL ) {
        !          1177:                                                        result.number_part &= 0xF;
        !          1178:                                                        result.number_part |= (result.L_R_select & 1) << 4;
        !          1179:                                                }
        !          1180:                                                opcode |= result.number_part << 21;
        !          1181:                                                continue;
        !          1182:                                        }
        !          1183:                                }
        !          1184:                                break;
        !          1185: 
        !          1186:                        case '6':   /* 5 bit register field at 15
        !          1187:                                                (used in 'fmpyadd' and 'fmpysub') */
        !          1188:                                {
        !          1189:                                        struct pa_89_fp_reg_struct result;
        !          1190:                                        int status;
        !          1191: 
        !          1192:                                        status = pa_89_parse_number(&s,&result);
        !          1193:                                        if ( result.number_part < 32 && result.number_part >= 0 ) {
        !          1194:                                                if ( the_insn.fpof1 == SGL ) {
        !          1195:                                                        result.number_part &= 0xF;
        !          1196:                                                        result.number_part |= (result.L_R_select & 1) << 4;
        !          1197:                                                }
        !          1198:                                                opcode |= result.number_part << 16;
        !          1199:                                                continue;
        !          1200:                                        }
        !          1201:                                }
        !          1202:                                break;
        !          1203: 
        !          1204:                        case '7':   /* 5 bit register field at 31
        !          1205:                                                (used in 'fmpyadd' and 'fmpysub') */
        !          1206:                                {
        !          1207:                                        struct pa_89_fp_reg_struct result;
        !          1208:                                        int status;
        !          1209: 
        !          1210:                                        status = pa_89_parse_number(&s,&result);
        !          1211:                                        if ( result.number_part < 32 && result.number_part >= 0 ) {
        !          1212:                                                if ( the_insn.fpof1 == SGL ) {
        !          1213:                                                        result.number_part &= 0xF;
        !          1214:                                                        result.number_part |= (result.L_R_select & 1) << 4;
        !          1215:                                                }
        !          1216:                                                opcode |= result.number_part;
        !          1217:                                                continue;
        !          1218:                                        }
        !          1219:                                }
        !          1220:                                break;
        !          1221: 
        !          1222:                        case '8':   /* 5 bit register field at 20
        !          1223:                                                (used in 'fmpyadd' and 'fmpysub') */
        !          1224:                                {
        !          1225:                                        struct pa_89_fp_reg_struct result;
        !          1226:                                        int status;
        !          1227: 
        !          1228:                                        status = pa_89_parse_number(&s,&result);
        !          1229:                                        if ( result.number_part < 32 && result.number_part >= 0 ) {
        !          1230:                                                if ( the_insn.fpof1 == SGL ) {
        !          1231:                                                        result.number_part &= 0xF;
        !          1232:                                                        result.number_part |= (result.L_R_select & 1) << 4;
        !          1233:                                                }
        !          1234:                                                opcode |= result.number_part << 11;
        !          1235:                                                continue;
        !          1236:                                        }
        !          1237:                                }
        !          1238:                                break;
        !          1239: 
        !          1240:                        case '9':   /* 5 bit register field at 25
        !          1241:                                                (used in 'fmpyadd' and 'fmpysub') */
        !          1242:                                {
        !          1243:                                        struct pa_89_fp_reg_struct result;
        !          1244:                                        int status;
        !          1245: 
        !          1246:                                        status = pa_89_parse_number(&s,&result);
        !          1247:                                        if ( result.number_part < 32 && result.number_part >= 0 ) {
        !          1248:                                                if ( the_insn.fpof1 == SGL ) {
        !          1249:                                                        result.number_part &= 0xF;
        !          1250:                                                        result.number_part |= (result.L_R_select & 1) << 4;
        !          1251:                                                }
        !          1252:                                                opcode |= result.number_part << 6;
        !          1253:                                                continue;
        !          1254:                                        }
        !          1255:                                }
        !          1256:                                break;
        !          1257: 
        !          1258:                        case 'H':  /* Floating Point Operand Format at 26 for       */
        !          1259:                                                /* 'fmpyadd' and 'fmpysub' (very similar to 'F') */
        !          1260:                                                /* bits are switched from other FP Operand       */
        !          1261:                                                /* formats. 1=SGL, 1=<none>, 0=DBL               */
        !          1262:                                f = pa_parse_fp_format(&s);
        !          1263:                                switch (f) {
        !          1264:                                case SGL:
        !          1265:                                        opcode |= 0x20;
        !          1266:                                case DBL:
        !          1267:                                        the_insn.fpof1 = f;
        !          1268:                                        continue;
        !          1269: 
        !          1270:                                case QUAD:
        !          1271:                                case ILLEGAL_FMT:
        !          1272:                                default:
        !          1273:                                        as_bad("Illegal Floating Point Operand Format for"
        !          1274:                                                "this instruction: '%s'",s);
        !          1275:                                }
        !          1276:                                break;
        !          1277: 
        !          1278:                        case 'y' :  /* nullify at 26 */
        !          1279:                                nullif = pa_parse_nullif(&s);
        !          1280:                                opcode |= nullif << 5;
        !          1281:                                continue;
        !          1282:                                                
        !          1283: /* bug #41317 .... [email protected] Mon May  2 17:53:29 PDT 1994
        !          1284: 
        !          1285:    These are for 'cache control hints'
        !          1286:        
        !          1287:        l       Store Instruction Cache Control Hint  (Table 5-8) with
        !          1288:                Short displacement load and store completers (Table 5-11) 
        !          1289:                 
        !          1290:        L       Load and Clear Word Cache Control Hint (Table 5-9) with
        !          1291:                Indexed load completers (Table 5-10)
        !          1292: 
        !          1293:        3       Store Instruction Cache Control Hint  (Table 5-8) with
        !          1294:                Indexed load completers (Table 5-10)
        !          1295: 
        !          1296:        a       Load and Clear Word Cache Control Hint (Table 5-9) with
        !          1297:                Short displacement load and store completers (Table 5-11)
        !          1298: 
        !          1299:        These parse ",cc" and encode "cc" in 2 bits at 20,
        !          1300:        where "cc" encoding is as given in Tables 5-8, 5-9.
        !          1301:     Refer to 'PA-RISC 1.1 Architecture and Instruction Set Reference
        !          1302:        Manual, Second Edition' for the tables.
        !          1303: */
        !          1304: 
        !          1305:                        case 'l' :  /* Store Instruction Cache Control Hint */
        !          1306:                                                /* Short displacement load and store completers */
        !          1307:                                opcode |= parse_completer_with_cache_control_hint(&s, 0, 'C');
        !          1308:                                continue;
        !          1309: 
        !          1310:                        case 'L' :  /* Load and Clear Word Cache Control Hint */
        !          1311:                                                /* Indexed load completers  */
        !          1312:                                opcode |= parse_completer_with_cache_control_hint(&s, 1, 'c');
        !          1313:                                continue;
        !          1314: 
        !          1315:                        case '3' :  /* Store Instruction Cache Control Hint */
        !          1316:                                                /* Indexed load completers */
        !          1317:                                opcode |= parse_completer_with_cache_control_hint(&s, 0, 'c');
        !          1318:                                continue;
        !          1319: 
        !          1320:                        case 'a' :  /* Load and Clear Word Cache Control Hint */
        !          1321:                                                /* Short displacement load and store completers */
        !          1322:                                opcode |= parse_completer_with_cache_control_hint(&s, 1, 'C');
        !          1323:                                continue;
        !          1324: 
        !          1325:                        default:
        !          1326:                                abort();
        !          1327:                        }
        !          1328:                        break;
        !          1329:                }
        !          1330: 
        !          1331:                if (match == FALSE)
        !          1332:                {
        !          1333:                /* Args don't match.  */
        !          1334:                        if (&insn[1] - pa_opcodes < NUMOPCODES
        !          1335:                                && !strcmp(insn->name, insn[1].name))
        !          1336:                        {
        !          1337:                                ++insn;
        !          1338:                                s = argsStart;
        !          1339:                                continue;
        !          1340:                        }
        !          1341:                        else
        !          1342:                        {
        !          1343:                                as_bad("Illegal operands");
        !          1344:                                return;
        !          1345:                        }
        !          1346:                }
        !          1347:                break;
        !          1348:        }
        !          1349: 
        !          1350:        the_insn.opcode = opcode;
        !          1351:        return;
        !          1352: }    /* end pa_ip() */
        !          1353: 
        !          1354: /*
        !          1355:     This is identical to the md_atof in m68k.c.  I think this is right,
        !          1356:     but I'm not sure.
        !          1357: 
        !          1358:    Turn a string in input_line_pointer into a floating point constant of type
        !          1359:    type, and store the appropriate bytes in *litP.  The number of LITTLENUMS
        !          1360:    emitted is stored in *sizeP .  An error message is returned, or NULL on OK.
        !          1361:  */
        !          1362: 
        !          1363: /* Equal to MAX_PRECISION in atof-ieee.c */
        !          1364: #define MAX_LITTLENUMS 6
        !          1365: 
        !          1366: char *
        !          1367: md_atof(
        !          1368: int type,
        !          1369: char *litP,
        !          1370: int *sizeP)
        !          1371: {
        !          1372:     int        prec;
        !          1373:     LITTLENUM_TYPE words[MAX_LITTLENUMS];
        !          1374:     LITTLENUM_TYPE *wordP;
        !          1375:     char       *t;
        !          1376:     char       *atof_ieee();
        !          1377: 
        !          1378:     switch(type) {
        !          1379: 
        !          1380:     case 'f':
        !          1381:     case 'F':
        !          1382:     case 's':
        !          1383:     case 'S':
        !          1384:        prec = 2;
        !          1385:        break;
        !          1386: 
        !          1387:     case 'd':
        !          1388:     case 'D':
        !          1389:     case 'r':
        !          1390:     case 'R':
        !          1391:        prec = 4;
        !          1392:        break;
        !          1393: 
        !          1394:     case 'x':
        !          1395:     case 'X':
        !          1396:        prec = 6;
        !          1397:        break;
        !          1398: 
        !          1399:     case 'p':
        !          1400:     case 'P':
        !          1401:        prec = 6;
        !          1402:        break;
        !          1403: 
        !          1404:     default:
        !          1405:        *sizeP=0;
        !          1406:        return "Bad call to MD_ATOF()";
        !          1407:     }
        !          1408:     t=atof_ieee(input_line_pointer,type,words);
        !          1409:     if(t)
        !          1410:        input_line_pointer=t;
        !          1411:     *sizeP=prec * sizeof(LITTLENUM_TYPE);
        !          1412:     for(wordP=words;prec--;) {
        !          1413:        md_number_to_chars(litP,(long)(*wordP++),sizeof(LITTLENUM_TYPE));
        !          1414:        litP+=sizeof(LITTLENUM_TYPE);
        !          1415:     }
        !          1416:     return ""; /* Someone should teach Dean about null pointers */
        !          1417: }
        !          1418: 
        !          1419: /*
        !          1420:  * Write out big-endian.
        !          1421:  */
        !          1422: void
        !          1423: md_number_to_chars(
        !          1424: char *buf,
        !          1425: long val,
        !          1426: int n)
        !          1427: {
        !          1428: 
        !          1429:     switch(n) {
        !          1430: 
        !          1431:     case 4:
        !          1432:        *buf++ = val >> 24;
        !          1433:        *buf++ = val >> 16;
        !          1434:     case 2:
        !          1435:        *buf++ = val >> 8;
        !          1436:     case 1:
        !          1437:        *buf = val;
        !          1438:        break;
        !          1439: 
        !          1440:     default:
        !          1441:        abort();
        !          1442:     }
        !          1443:     return;
        !          1444: }
        !          1445: 
        !          1446: void
        !          1447: md_number_to_imm(
        !          1448: unsigned char *buf,
        !          1449: long val,
        !          1450: int n,
        !          1451: fixS *fixP,
        !          1452: int nsect)
        !          1453: {
        !          1454:        unsigned long w1,w2,w;
        !          1455:        unsigned new_val = 0;
        !          1456:        unsigned long left21, right14;
        !          1457:        
        !          1458:        if(fixP->fx_r_type == NO_RELOC ||
        !          1459:           fixP->fx_r_type == HPPA_RELOC_VANILLA){
        !          1460:            switch(n){
        !          1461:            case 4:
        !          1462:                *buf++ = val >> 24;
        !          1463:                *buf++ = val >> 16;
        !          1464:            case 2:
        !          1465:                *buf++ = val >> 8;
        !          1466:            case 1:
        !          1467:                *buf = val;
        !          1468:                break;
        !          1469: 
        !          1470:            default:
        !          1471:                abort();
        !          1472:            }
        !          1473:            return;
        !          1474:        }
        !          1475: 
        !          1476: 
        !          1477:        calc_hppa_HILO(val - fixP->fx_offset, fixP->fx_offset,
        !          1478:                       &left21, &right14);
        !          1479: 
        !          1480:        switch (fixP->fx_r_type) {
        !          1481:     default:
        !          1482:                break;
        !          1483: /*     case 'j': */
        !          1484:     case HPPA_RELOC_LO14 :
        !          1485:                w = low_sign_unext(right14, 14); 
        !          1486:                goto fixit;
        !          1487: 
        !          1488: /*     case 'k': */
        !          1489:     case HPPA_RELOC_HI21 :
        !          1490:                w = dis_assemble_21((left21>>11));
        !          1491: fixit:
        !          1492:       /* There is no guarantee that buf is word-aligned,       */
        !          1493:       /* so the adjustment must be done the hard way.          */
        !          1494: 
        !          1495:                new_val  = (*buf & 0xff) << 24;
        !          1496:                new_val |= (*(buf+1) & 0xff) << 16;
        !          1497:                new_val |= (*(buf+2) & 0xff) << 8;
        !          1498:                new_val |= (*(buf+3) & 0xff);
        !          1499:                new_val |= w;   /* Now, make the adjustment */
        !          1500:                md_number_to_chars(buf,new_val,4);
        !          1501:                break;
        !          1502: 
        !          1503: /*     case 'W': */
        !          1504:        case HPPA_RELOC_BL17 :
        !          1505:                if ( !fixP->fx_addsy ) {
        !          1506:                        val -= 4;       /* PA adjustment: a 0 disp is actually 4 bytes */
        !          1507:                                                /* further because of the delay slot */
        !          1508:                        val >>= 2;
        !          1509:                        dis_assemble_17(val,&w1,&w2,&w);
        !          1510:                /* There is no guarantee that buf is word-aligned,      */
        !          1511:                /* so the adjustment must be done the hard way.         */
        !          1512: 
        !          1513:                new_val  = (*buf & 0xff) << 24;
        !          1514:                new_val |= (*(buf+1) & 0xff) << 16;
        !          1515:                new_val |= (*(buf+2) & 0xff) << 8;
        !          1516:                new_val |= (*(buf+3) & 0xff);
        !          1517:                new_val |= ( ( w2 << 2 ) | ( w1 << 16 ) | w );
        !          1518:                                      /* Now, do the adjustment */
        !          1519:                md_number_to_chars(buf,new_val,4);
        !          1520:       }
        !          1521:       else {
        !          1522:                unsigned long result;
        !          1523:                val -= 4;       /* PA adjustment: a 0 disp is actually 4 bytes */
        !          1524:                                                /* further because of the delay slot */
        !          1525:                val >>= 2;
        !          1526: 
        !          1527:                result = sign_unext( val,17);
        !          1528:                dis_assemble_17(result,&w1,&w2,&w);
        !          1529:                /* There is no guarantee that buf is word-aligned,      */
        !          1530:                /* so the adjustment must be done the hard way.         */
        !          1531: 
        !          1532:                new_val  = (*buf & 0xff) << 24;
        !          1533:                new_val |= (*(buf+1) & 0xff) << 16;
        !          1534:                new_val |= (*(buf+2) & 0xff) << 8;
        !          1535:                new_val |= (*(buf+3) & 0xff);
        !          1536:                new_val |= ( ( w2 << 2 ) | ( w1 << 16 ) | w );
        !          1537:                                      /* Now, do the adjustment */
        !          1538:                md_number_to_chars(buf,new_val,4);
        !          1539: 
        !          1540:                }
        !          1541:                break;
        !          1542: /*     case 'z': */
        !          1543:        case HPPA_RELOC_BR17 :
        !          1544:        {
        !          1545:                unsigned long result;
        !          1546:                right14 >>= 2;
        !          1547:                result = sign_unext(right14,17);
        !          1548:                dis_assemble_17(result,&w1,&w2,&w);
        !          1549:        /* There is no guarantee that buf is word-aligned,      */
        !          1550:        /* so the adjustment must be done the hard way.         */
        !          1551: 
        !          1552:                new_val  = (*buf & 0xff) << 24;
        !          1553:                new_val |= (*(buf+1) & 0xff) << 16;
        !          1554:                new_val |= (*(buf+2) & 0xff) << 8;
        !          1555:                new_val |= (*(buf+3) & 0xff);
        !          1556:                new_val |= ( ( w2 << 2 ) | ( w1 << 16 ) | w );
        !          1557:                                      /* Now, do the adjustment */
        !          1558:                md_number_to_chars(buf,new_val,4);
        !          1559:      }
        !          1560:                        break;
        !          1561: /*     case '@': */
        !          1562:     case HPPA_RELOC_JBSR :
        !          1563: /*
        !          1564:  * In case of the jbsr relocation no bytes are to be written to the 
        !          1565:  * output.
        !          1566:  * 
        !          1567:  * SO DO NOTHING!
        !          1568:  */
        !          1569:       break;
        !          1570:       
        !          1571: /*       case 'w': */
        !          1572: /* To take care of 12 bit label */
        !          1573:       case HPPA_RELOC_12BRANCH :
        !          1574:                if ( !fixP->fx_addsy ) {
        !          1575:                        val -= 4;       /* PA adjustment: a 0 disp is actually 4 bytes */
        !          1576:                                                /* further because of the delay slot */
        !          1577:                        val >>= 2;
        !          1578:                        dis_assemble_12(val,&w1,&w);
        !          1579:                        /* There is no guarantee that buf is word-aligned,      */
        !          1580:                        /* so the adjustment must be done the hard way.         */
        !          1581: 
        !          1582:                        new_val  = (*buf & 0xff) << 24;
        !          1583:                        new_val |= (*(buf+1) & 0xff) << 16;
        !          1584:                        new_val |= (*(buf+2) & 0xff) << 8;
        !          1585:                        new_val |= (*(buf+3) & 0xff);
        !          1586:                        new_val |= ( ( w1 << 2 ) | w ); /* Now, do the adjustment */
        !          1587:                        md_number_to_chars(buf,new_val,4);
        !          1588:                }
        !          1589:                else {
        !          1590:                        as_bad("Undefined symbol %s", fixP->fx_addsy->sy_name);
        !          1591:                }
        !          1592:                
        !          1593:                 break;
        !          1594:     }
        !          1595: }
        !          1596: 
        !          1597: void
        !          1598: md_convert_frag(
        !          1599: fragS *fragP)
        !          1600: {
        !          1601:   unsigned int address;
        !          1602: 
        !          1603:   if ( fragP -> fr_type == rs_machine_dependent ) {
        !          1604:     switch ( (int) fragP -> fr_subtype ) {
        !          1605:     case 0:
        !          1606:       fragP -> fr_type = rs_fill;
        !          1607:       know( fragP -> fr_var == 1 );
        !          1608:       know( fragP -> fr_next );
        !          1609:       address = fragP -> fr_address + fragP -> fr_fix;
        !          1610:       if ( address % fragP -> fr_offset ) {
        !          1611:        fragP -> fr_offset =
        !          1612:          fragP -> fr_next -> fr_address
        !          1613:            -   fragP -> fr_address
        !          1614:              - fragP -> fr_fix;
        !          1615:       }
        !          1616:       else
        !          1617:        fragP -> fr_offset = 0;
        !          1618:       break;
        !          1619:     }
        !          1620:   }
        !          1621: }
        !          1622: 
        !          1623: int
        !          1624: md_estimate_size_before_relax(
        !          1625: fragS *fragP,
        !          1626: int nsect)
        !          1627: {
        !          1628:   int size;
        !          1629: 
        !          1630:   size = 0;
        !          1631: 
        !          1632:   while ( (fragP->fr_fix + size) % fragP->fr_offset )
        !          1633:     size++;
        !          1634: 
        !          1635:   return size;
        !          1636: }
        !          1637: 
        !          1638: int
        !          1639: md_parse_option(
        !          1640: char **argP,
        !          1641: int *cntP,
        !          1642: char ***vecP)
        !          1643: {
        !          1644:     return 1;
        !          1645: }
        !          1646: 
        !          1647: /*
        !          1648: int is_end_of_statement()
        !          1649: {
        !          1650:   return (   (*input_line_pointer == '\n')
        !          1651:          || (*input_line_pointer == ';')
        !          1652:          || (*input_line_pointer == '!') );
        !          1653: }
        !          1654: */
        !          1655: 
        !          1656: static
        !          1657: int
        !          1658: parse_L_or_R(
        !          1659: char *str)
        !          1660: {
        !          1661: /* not much work done as yet! */
        !          1662:        switch (*str) {
        !          1663:        case '%':
        !          1664:        case '(':
        !          1665:                return 0;       /* ie. not found */
        !          1666:                break;
        !          1667:        case 'L':
        !          1668:        case 'l':
        !          1669:                if (*(str+1) == '\'' || *(str+1) == '`') /* check next character */
        !          1670:                        return 1; /* found */
        !          1671:                else
        !          1672:                        return 0; /* not found */
        !          1673:                break;
        !          1674:        case 'R':
        !          1675:        case 'r':
        !          1676:                if (*(str+1) == '\'' || *(str+1) == '`') /* check next character */
        !          1677:                        return 2; /* found */
        !          1678:                else
        !          1679:                        return 0; /* not found */
        !          1680:                break;
        !          1681:        default: /* default is not found ... at least for the time being */
        !          1682:                return 0;
        !          1683:                break;
        !          1684:        }
        !          1685: }    /* end parse_L_or_R() */
        !          1686: 
        !          1687: static
        !          1688: unsigned long
        !          1689: parse_cache_control_hint(
        !          1690: char   **s,       /* Note : the function changes '*s' */
        !          1691: int     option)    /* option = 0 for store instruction */
        !          1692:                    /* option = 1 for load and clear instruction */
        !          1693: {
        !          1694:        unsigned long cc = NO_CACHE_CONTROL_HINT;
        !          1695:                                
        !          1696:        if (**s == ',') {
        !          1697:                (*s)++;
        !          1698:                switch (option) {
        !          1699:                case 0 : /* Store Instruction Cache Control Hint */ 
        !          1700:                        if ( strncasecmp(*s,"bc",2) == 0 ) {
        !          1701:                                /* BLOCK_COPY */
        !          1702:                                (*s) += 2;
        !          1703:                                cc = BC_OR_CO_CACHE_CONTROL_HINT;
        !          1704:                                /* eat up extra blanks and tabs */
        !          1705:                                while ( **s == ' ' || **s == '\t' )
        !          1706:                                        (*s)++;
        !          1707:                        } else
        !          1708:                                as_fatal("Illegal Cache Control Hint: '%s'"
        !          1709:                                        " - expected 'bc'",*s);
        !          1710:                        break;
        !          1711:                        
        !          1712:                case 1 : /* Load and Clear Word Cache Control Hint */
        !          1713:                        if ( strncasecmp(*s,"co",2) == 0 ) {
        !          1714:                                /* COHERENT_OPERATION */
        !          1715:                                (*s) +=2;
        !          1716:                                cc = BC_OR_CO_CACHE_CONTROL_HINT;
        !          1717:                                /* eat up extra blanks and tabs */
        !          1718:                                while ( **s == ' ' || **s == '\t' )
        !          1719:                                        (*s)++;
        !          1720:                        } else
        !          1721:                                as_fatal("Illegal Cache Control Hint: '%s'"
        !          1722:                                        " - expected 'co'",*s);
        !          1723:                        break;
        !          1724:                        
        !          1725:                default :
        !          1726:                        as_fatal("Invalid option (%d) for parsing cache control hints",
        !          1727:                                option);
        !          1728:                        break;
        !          1729:                }
        !          1730:        }
        !          1731:                /* else NO_HINT */
        !          1732:                                
        !          1733:        /*
        !          1734:        * the completers have already eaten up extra blanks
        !          1735:        * and tabs. So there is no need to do that again here.
        !          1736:        */
        !          1737:                                 
        !          1738:        return cc;
        !          1739: 
        !          1740: }    /* end parse_cache_control_hint() */
        !          1741: 
        !          1742: static
        !          1743: unsigned long
        !          1744: parse_completer_with_cache_control_hint(
        !          1745: char   **s,       /* Note : the function changes '*s' */
        !          1746: int     option,    /* option = 0 for store instruction */
        !          1747:                    /* option = 1 for load and clear instruction */
        !          1748: char    completer) /* 'c' or 'C' */
        !          1749: {
        !          1750:        unsigned long i, result = (unsigned long) 0UL;
        !          1751:        int m, a, u;
        !          1752:        
        !          1753:        switch (completer) {
        !          1754:        case 'c':   /* indexed load completer. */
        !          1755:                i = m = u = 0;
        !          1756:                while ( **s == ',' && i < 3 ) {
        !          1757:                        (*s)++;
        !          1758:                        if ( strncasecmp((*s),"sm",2) == 0 ) {
        !          1759:                                m = u = 1;
        !          1760:                                (*s)++;
        !          1761:                                i++;
        !          1762:                        }
        !          1763:                        else if ( strncasecmp((*s),"m",1) == 0 )
        !          1764:                                m = 1;
        !          1765:                        else if ( strncasecmp((*s),"s",1) == 0 )
        !          1766:                                u = 1;
        !          1767:                        else if ( strncmp((*s),",",1) == 0 ) /* no completer */
        !          1768:                                result |= parse_cache_control_hint(s, option);
        !          1769:                        else if ( (strncasecmp((*s),"c",1) == 0) ||
        !          1770:                                  (strncasecmp((*s),"b",1) == 0) ) {/* just 1 completer */
        !          1771:                                (*s)--;
        !          1772:                                result |= parse_cache_control_hint(s, option);
        !          1773:                        }
        !          1774:                        else
        !          1775:                                as_bad("Unrecognized Indexed Load"
        !          1776:                                        "Completer with cache control hints...assuming 0");
        !          1777:                        if (result == (unsigned long)0UL)
        !          1778:                                (*s)++;
        !          1779:                        i++;
        !          1780:                }
        !          1781:                if ( i > 3 )
        !          1782:                        as_bad("Illegal Indexed Load Completer with cache control hints"
        !          1783:                        " Syntax... extras ignored");
        !          1784:                while ( **s == ' ' || **s == '\t' )
        !          1785:                        (*s)++;
        !          1786:   
        !          1787:                result |= m << 5;
        !          1788:                result |= u << 13;
        !          1789:                break;
        !          1790:        case 'C':   /* short load and store completer */
        !          1791:                i = m = a = 0;
        !          1792:                while ( **s == ',' && i < 2 ) {
        !          1793:                        (*s)++;
        !          1794:                        if ( strncasecmp((*s),"ma",2) == 0 ) {
        !          1795:                                a = 0;
        !          1796:                                m = 1;
        !          1797:                        }
        !          1798:                        else if ( strncasecmp((*s),"mb",2) == 0 ) {
        !          1799:                                m = a = 1;
        !          1800:                        }
        !          1801:                        else if ( strncmp((*s),",",1) == 0 ) /* no completer */
        !          1802:                                result |= parse_cache_control_hint(s, option);
        !          1803:                        else if ( (strncasecmp((*s),"c",1) == 0) ||
        !          1804:                                  (strncasecmp((*s),"b",1) == 0) ) {/* just 1 completer */
        !          1805:                                (*s)--;
        !          1806:                                result |= parse_cache_control_hint(s, option);
        !          1807:                        }
        !          1808:                        else
        !          1809:                                as_bad("Unrecognized Indexed Load Completer"
        !          1810:                                "...assuming 0");
        !          1811:                        i++;
        !          1812:                        (*s) += 2;
        !          1813:                }
        !          1814:                while ( **s == ' ' || **s == '\t' )
        !          1815:                        (*s)++;
        !          1816:                result |= m << 5;
        !          1817:                result |= a << 13;
        !          1818:                break;
        !          1819:                
        !          1820:                
        !          1821:        default :
        !          1822:                        as_fatal("Invalid completer (%c) for parsing cache control hints",
        !          1823:                                completer);
        !          1824:                        break;
        !          1825:        }
        !          1826:        return result;
        !          1827: }    /* end parse_completer_with_cache_control_hint() */
        !          1828: 
        !          1829: /* end hppa.c */

unix.superglobalmegacorp.com

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