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

1.1     ! root        1: #include <ctype.h>
        !             2: #include <string.h>
        !             3: #include <mach-o/m98k/reloc.h>
        !             4: #include "m98k-opcode.h"
        !             5: #include "as.h"
        !             6: #include "flonum.h"
        !             7: #include "expr.h"
        !             8: #include "hash.h"
        !             9: #include "read.h"
        !            10: #include "md.h"
        !            11: #include "obstack.h"
        !            12: #include "symbols.h"
        !            13: #include "messages.h"
        !            14: #include "atof-ieee.h"
        !            15: #include "input-scrub.h"
        !            16: #include "sections.h"
        !            17: 
        !            18: 
        !            19: /*
        !            20:  * These are the default cputype and cpusubtype for the m98k architecture.
        !            21:  */
        !            22: const cpu_type_t md_cputype = CPU_TYPE_MC98000;
        !            23: cpu_subtype_t md_cpusubtype = CPU_SUBTYPE_MC98000_ALL;
        !            24: 
        !            25: /* This is the byte sex for the m98k architecture */
        !            26: const enum byte_sex md_target_byte_sex = BIG_ENDIAN_BYTE_SEX;
        !            27: 
        !            28: /* These characters start a comment anywhere on the line */
        !            29: const char md_comment_chars[] = ";";
        !            30: 
        !            31: /* These characters only start a comment at the beginning of a line */
        !            32: const char md_line_comment_chars[] = "#";
        !            33: 
        !            34: /*
        !            35:  * These characters can be used to separate mantissa decimal digits from 
        !            36:  * exponent decimal digits in floating point numbers.
        !            37:  */
        !            38: const char md_EXP_CHARS[] = "eE";
        !            39: 
        !            40: /*
        !            41:  * The characters after a leading 0 that means this number is a floating point
        !            42:  * constant as in 0f123.456 or 0d1.234E-12 (see md_EXP_CHARS above).
        !            43:  */
        !            44: const char md_FLT_CHARS[] = "dDfF";
        !            45: 
        !            46: /*
        !            47:  * This is the machine dependent pseudo opcode table for this target machine.
        !            48:  */
        !            49: static void s_reg(
        !            50:     int reg);
        !            51: const pseudo_typeS md_pseudo_table[] =
        !            52: {
        !            53:     {"greg", s_reg, 'r' },
        !            54:     {0} /* end of table marker */
        !            55: };
        !            56: 
        !            57: #define RT(x)           (((x) >> 21) & 0x1f)
        !            58: #define RA(x)           (((x) >> 16) & 0x1f)
        !            59: 
        !            60: struct m98k_insn {
        !            61:     unsigned long opcode;
        !            62:     expressionS exp;
        !            63:     enum reloc_type_m98k reloc;
        !            64:     long pcrel;
        !            65:     long pcrel_reloc;
        !            66: };
        !            67: 
        !            68: /*
        !            69:  * The pointer to the opcode hash table built by md_begin() and used by
        !            70:  * md_assemble() to look up opcodes.
        !            71:  */
        !            72: static struct hash_control *op_hash = NULL;
        !            73: 
        !            74: /*
        !            75:  * These aid in the printing of better error messages for parameter syntax
        !            76:  * errors when there is only one mnemonic in the tables.
        !            77:  */
        !            78: static unsigned long error_param_count = 0;
        !            79: static char *error_param_message = NULL;
        !            80: 
        !            81: /*
        !            82:  * These are name names of the known special registers and the numbers assigned
        !            83:  * to them.
        !            84:  */
        !            85: struct special_register {
        !            86:     unsigned long number;
        !            87:     char *name;
        !            88: };
        !            89: static const struct special_register special_registers[] = {
        !            90:     { 0,   "mq" }, /* 601 only */
        !            91:     { 1,   "xer" },
        !            92:     { 4,   "rtcu" },
        !            93:     { 5,   "rtcl" },
        !            94:     { 8,   "lr" },
        !            95:     { 9,   "ctr" },
        !            96:     { 18,  "dsisr" },
        !            97:     { 19,  "dar" },
        !            98:     { 22,  "dec" },
        !            99:     { 25,  "sdr1" },
        !           100:     { 26,  "srr0" },
        !           101:     { 27,  "srr1" },
        !           102:     { 272, "sprg0" },
        !           103:     { 273, "sprg1" },
        !           104:     { 274, "sprg2" },
        !           105:     { 275, "sprg3" },
        !           106:     { 280, "asr" },
        !           107:     { 281, "rtcd" },
        !           108:     { 282, "rtci" },
        !           109:     { 287, "pvr" },
        !           110:     { 528, "ibat0u" },
        !           111:     { 529, "ibat0l" },
        !           112:     { 530, "ibat1u" },
        !           113:     { 531, "ibat1l" },
        !           114:     { 532, "ibat2u" },
        !           115:     { 533, "ibat2l" },
        !           116:     { 534, "ibat3u" },
        !           117:     { 535, "ibat3l" },
        !           118:     { 528, "bat0u" }, /* 601 only */
        !           119:     { 529, "bat0l" }, /* 601 only */
        !           120:     { 530, "bat1u" }, /* 601 only */
        !           121:     { 531, "bat1l" }, /* 601 only */
        !           122:     { 532, "bat2u" }, /* 601 only */
        !           123:     { 533, "bat2l" }, /* 601 only */
        !           124:     { 534, "bat3u" }, /* 601 only */
        !           125:     { 535, "bat3l" }, /* 601 only */
        !           126:     { 536, "dbat0u" },
        !           127:     { 537, "dbat0l" },
        !           128:     { 538, "dbat1u" },
        !           129:     { 539, "dbat1l" },
        !           130:     { 540, "dbat2u" },
        !           131:     { 541, "dbat2l" },
        !           132:     { 542, "dbat3u" },
        !           133:     { 543, "dbat3l" },
        !           134:     { 1008,"hid0" }, /* 601 only */
        !           135:     { 1009,"hid1" }, /* 601 only */
        !           136:     { 1010,"hid2" }, /* 601 only */
        !           137:     { 1013,"hid5" }, /* 601 only */
        !           138:     { 1013,"dabr" }, /* 601 only */
        !           139:     { 1022,"fpecr" },
        !           140:     { 1023,"pid" }, /* 601 only */
        !           141:     { 0, "" } /* end of table marker */
        !           142: };
        !           143: 
        !           144: /*
        !           145:  * These are name names of the condition field special registers and the
        !           146:  * numbers assigned to them.
        !           147:  */
        !           148: struct condition_symbol {
        !           149:     unsigned long value;
        !           150:     char *name;
        !           151: };
        !           152: static const struct condition_symbol condition_symbols[] = {
        !           153:     { 0, "lt" }, /* less than */
        !           154:     { 1, "gt" }, /* greater than */
        !           155:     { 2, "eq" }, /* equal */
        !           156:     { 3, "so" }, /* summary overflow */
        !           157:     { 3, "un" }, /* unordered */
        !           158:     { 0, "" } /* end of table marker */
        !           159: };
        !           160: 
        !           161: struct CR_field {
        !           162:     unsigned long value;
        !           163:     char *name;
        !           164: };
        !           165: static const struct CR_field CR_fields[] = {
        !           166:     { 0,  "cr0" }, /* CR field 0 */
        !           167:     { 4,  "cr1" }, /* CR field 1 */
        !           168:     { 8,  "cr2" }, /* CR field 2 */
        !           169:     { 12, "cr3" }, /* CR field 3 */
        !           170:     { 16, "cr4" }, /* CR field 4 */
        !           171:     { 20, "cr5" }, /* CR field 5 */
        !           172:     { 24, "cr6" }, /* CR field 6 */
        !           173:     { 28, "cr7" }, /* CR field 7 */
        !           174:     { 0, "" } /* end of table marker */
        !           175: };
        !           176: 
        !           177: /*
        !           178:  * These are built in macros because they are trivial to implement as macros
        !           179:  * which otherwise be less obvious to do special entries for them.
        !           180:  */
        !           181: struct macros {
        !           182:     char *name;
        !           183:     char *body;
        !           184: };
        !           185: static const struct macros m98k_macros[] = {
        !           186:     { "extldi\n",  "rldicr $0,$1,$3,$2-1\n" },
        !           187:     { "extldi.\n", "rldicr. $0,$1,$3,$2-1\n" },
        !           188:     { "extrdi\n",  "rldicl $0,$1,$2+$3,64-$2\n" },
        !           189:     { "extrdi.\n", "rldicl. $0,$1,$2+$3,64-$2\n" },
        !           190:     { "insrdi\n",  "rldimi $0,$1,64-($3+$2),$3\n" },
        !           191:     { "insrdi.\n", "rldimi. $0,$1,64-($3+$2),$3\n" },
        !           192:     { "rotldi\n",  "rldicl $0,$1,$2,0\n" },
        !           193:     { "rotldi.\n", "rldicl. $0,$1,$2,0\n" },
        !           194:     { "rotrdi\n",  "rldicl $0,$1,64-$2,0\n" },
        !           195:     { "rotrdi.\n", "rldicl. $0,$1,64-$2,0\n" },
        !           196:     { "rotld\n",   "rldcl $0,$1,$2,0\n" },
        !           197:     { "rotld.\n",  "rldcl. $0,$1,$2,0\n" },
        !           198:     { "sldi\n",    "rldicr $0,$1,$2,63-$2\n" },
        !           199:     { "sldi.\n",   "rldicr. $0,$1,$2,63-$2\n" },
        !           200:     { "srdi\n",    "rldicl $0,$1,64-$2,$2\n" },
        !           201:     { "srdi.\n",   "rldicl. $0,$1,64-$2,$2\n" },
        !           202:     { "clrldi\n",  "rldicl $0,$1,0,$2\n" },
        !           203:     { "clrldi.\n", "rldicl. $0,$1,0,$2\n" },
        !           204:     { "clrrdi\n",  "rldicl $0,$1,0,63-$2\n" },
        !           205:     { "clrrdi.\n", "rldicl. $0,$1,0,63-$2\n" },
        !           206:     { "clrlsldi\n","rldic $0,$1,$3,$2-$3\n" },
        !           207:     { "clrlsldi.\n","rldic. $0,$1,$3,$2-$3\n" },
        !           208: 
        !           209:     { "extlwi\n",  "rlwinm $0,$1,$3,0,$2-1\n" },
        !           210:     { "extlwi.\n", "rlwinm. $0,$1,$3,0,$2-1\n" },
        !           211:     { "extrwi\n",  "rlwinm $0,$1,$2+$3,32-$2,31\n" },
        !           212:     { "extrwi.\n", "rlwinm. $0,$1,$2+$3,32-$2,31\n" },
        !           213:     { "inslwi\n",  "rlwimi $0,$1,32-$3,$3,($3+$2)-1\n" },
        !           214:     { "inslwi.\n", "rlwimi. $0,$1,32-$3,$3,($3+$2)-1\n" },
        !           215:     { "insrwi\n",  "rlwimi $0,$1,32-($3+$2),$3,($3+$2)-1\n" },
        !           216:     { "insrwi.\n", "rlwimi. $0,$1,32-($3+$2),$3,($3+$2)-1\n" },
        !           217:     { "rotlwi\n",  "rlwinm $0,$1,$2,0,31\n" },
        !           218:     { "rotlwi.\n", "rlwinm. $0,$1,$2,0,31\n" },
        !           219:     { "rotrwi\n",  "rlwinm $0,$1,32-$2,0,31\n" },
        !           220:     { "rotrwi.\n", "rlwinm. $0,$1,32-$2,0,31\n" },
        !           221:     { "rotlw\n",   "rlwnm $0,$1,$2,0,31\n" },
        !           222:     { "rotlw.\n",  "rlwnm. $0,$1,$2,0,31\n" },
        !           223:     { "slwi\n",    "rlwinm $0,$1,$2,0,31-$2\n" },
        !           224:     { "slwi.\n",   "rlwinm. $0,$1,$2,0,31-$2\n" },
        !           225:     { "srwi\n",    "rlwinm $0,$1,32-$2,$2,31\n" },
        !           226:     { "srwi.\n",   "rlwinm. $0,$1,32-$2,$2,31\n" },
        !           227:     { "clrlwi\n",  "rlwinm $0,$1,0,$2,31\n" },
        !           228:     { "clrlwi.\n", "rlwinm. $0,$1,0,$2,31\n" },
        !           229:     { "clrrwi\n",  "rlwinm $0,$1,0,0,31-$2\n" },
        !           230:     { "clrrwi.\n", "rlwinm. $0,$1,0,0,31-$2\n" },
        !           231:     { "clrlslwi\n","rlwinm $0,$1,$3,$2-$3,31-$2\n" },
        !           232:     { "clrlslwi.\n","rlwinm. $0,$1,$3,$2-$3,31-$2\n" },
        !           233: 
        !           234:     { "mtxer\n",   "mtspr 1,$0\n"},
        !           235:     { "mfxer\n",   "mfspr $0,1\n"},
        !           236:     { "mtlr\n",    "mtspr 8,$0\n"},
        !           237:     { "mflr\n",    "mfspr $0,8\n"},
        !           238:     { "mtctr\n",   "mtspr 9,$0\n"},
        !           239:     { "mfctr\n",   "mfspr $0,9\n"},
        !           240:     { "mtdsisr\n", "mtspr 18,$0\n"},
        !           241:     { "mfdsisr\n", "mfspr $0,18\n"},
        !           242:     { "mtdar\n",   "mtspr 19,$0\n"},
        !           243:     { "mfdar\n",   "mfspr $0,19\n"},
        !           244:     { "mtdec\n",   "mtspr 22,$0\n"},
        !           245:     { "mfdec\n",   "mfspr $0,22\n"},
        !           246:     { "mtsdr1\n",  "mtspr 25,$0\n"},
        !           247:     { "mfsdr1\n",  "mfspr $0,25\n"},
        !           248:     { "mtsrr0\n",  "mtspr 26,$0\n"},
        !           249:     { "mfsrr0\n",  "mfspr $0,26\n"},
        !           250:     { "mtsrr1\n",  "mtspr 27,$0\n"},
        !           251:     { "mfsrr1\n",  "mfspr $0,27\n"},
        !           252:     { "mtsprg\n",  "mtspr 272+$0,$1\n"},
        !           253:     { "mfsprg\n",  "mfspr $0,272+$1\n"},
        !           254:     { "mtasr\n",   "mtspr 280,$0\n"},
        !           255:     { "mfasr\n",   "mfspr $0,280\n"},
        !           256:     { "mtrtcd\n",  "mtspr 281,$0\n"},
        !           257:     { "mfrtcd\n",  "mfspr $0,281\n"},
        !           258:     { "mtrtci\n",  "mtspr 282,$0\n"},
        !           259:     { "mfrtci\n",  "mfspr $0,282\n"},
        !           260:     { "mfpvr\n",   "mfspr $0,287\n"},
        !           261:     { "mtibatu\n", "mtspr 528+2*$0,$1\n"},
        !           262:     { "mfibatu\n", "mfspr $0,528+2*$1\n"},
        !           263:     { "mtibatl\n", "mtspr 529+2*$0,$1\n"},
        !           264:     { "mfibatl\n", "mfspr $0,529+2*$1\n"},
        !           265:     { "mtdbatu\n", "mtspr 536+2*$0,$1\n"},
        !           266:     { "mfdbatu\n", "mfspr $0,536+2*$1\n"},
        !           267:     { "mtdbatl\n", "mtspr 537+2*$0,$1\n"},
        !           268:     { "mfdbatl\n", "mfspr $0,537+2*$1\n"},
        !           269: 
        !           270:     { "mtbatu\n",  "mtspr 528+2*$0,$1\n"},
        !           271:     { "mfbatu\n",  "mfspr $0,528+2*$1\n"},
        !           272:     { "mtbatl\n",  "mtspr 529+2*$0,$1\n"},
        !           273:     { "mfbatl\n",  "mfspr $0,529+2*$1\n"},
        !           274: 
        !           275:     { "subi\n",    "addi $0,$1,-($2)\n"},
        !           276:     { "subis\n",   "addis $0,$1,-($2)\n"},
        !           277:     { "subic\n",   "addic $0,$1,-($2)\n"},
        !           278:     { "subic.\n",  "addic. $0,$1,-($2)\n"},
        !           279: 
        !           280:     {  "", "" } /* end of table marker */
        !           281: };
        !           282: 
        !           283: static int calcop(
        !           284:     struct m98k_opcode *format,
        !           285:     char *param,
        !           286:     struct m98k_insn *insn,
        !           287:     char *op,
        !           288:     char prediction);
        !           289: static char *parse_branch(
        !           290:     char *param,
        !           291:     struct m98k_insn *insn,
        !           292:     struct m98k_opcode *format,
        !           293:     int parcnt);
        !           294: static char *parse_displacement(
        !           295:     char *param,
        !           296:     struct m98k_insn *insn,
        !           297:     struct m98k_opcode *format,
        !           298:     int parcnt);
        !           299: static char *parse_immediate(
        !           300:     char *param,
        !           301:     struct m98k_insn *insn,
        !           302:     struct m98k_opcode *format,
        !           303:     int parcnt);
        !           304: static char *parse_reg(
        !           305:     char *reg_name,
        !           306:     char *param,
        !           307:     struct m98k_insn *insn,
        !           308:     struct m98k_opcode *format,
        !           309:     unsigned long parcnt);
        !           310: static char *parse_spreg(
        !           311:     char *param,
        !           312:     struct m98k_insn *insn,
        !           313:     struct m98k_opcode *format,
        !           314:     unsigned long parcnt);
        !           315: static char *parse_bcnd(
        !           316:     char *param,
        !           317:     struct m98k_insn *insn,
        !           318:     struct m98k_opcode *format,
        !           319:     unsigned long parcnt);
        !           320: static char *parse_crf(
        !           321:     char *param,
        !           322:     struct m98k_insn *insn,
        !           323:     struct m98k_opcode *format,
        !           324:     unsigned long parcnt);
        !           325: static char *parse_num(
        !           326:     char *param,
        !           327:     struct m98k_insn *insn,
        !           328:     struct m98k_opcode *format,
        !           329:     unsigned long parcnt,
        !           330:     long max_width_zero);
        !           331: static char *parse_sh(
        !           332:     char *param,
        !           333:     struct m98k_insn *insn,
        !           334:     struct m98k_opcode *format,
        !           335:     unsigned long parcnt);
        !           336: static char *parse_mb(
        !           337:     char *param,
        !           338:     struct m98k_insn *insn,
        !           339:     struct m98k_opcode *format,
        !           340:     unsigned long parcnt);
        !           341: 
        !           342: /*
        !           343:  * md_begin() is called from main() in as.c before assembly begins.  It is used
        !           344:  * to allow target machine dependent initialization.
        !           345:  */
        !           346: void
        !           347: md_begin(void)
        !           348: {
        !           349:     unsigned long i;
        !           350:     char *name, *retval;
        !           351: 
        !           352:        /* initialize the opcode hash table */
        !           353:        op_hash = hash_new();
        !           354:        if(op_hash == NULL)
        !           355:            as_fatal("Could not initialize the opcode hash table");
        !           356: 
        !           357:        /* loop until you see the end of the list */
        !           358:        i = 0;
        !           359:        while(*m98k_opcodes[i].name){
        !           360:            name = m98k_opcodes[i].name;
        !           361: 
        !           362:            /* hash each mnemonic and record its position */
        !           363:            retval = hash_insert(op_hash, name, (char *)&m98k_opcodes[i]);
        !           364:            if(retval != NULL && *retval != '\0')
        !           365:                as_fatal("Can't hash instruction '%s':%s",
        !           366:                         m98k_opcodes[i].name, retval);
        !           367: 
        !           368:            /* skip to next unique mnemonic or end of list */
        !           369:            for(i++; strcmp(m98k_opcodes[i].name, name) == 0; i++)
        !           370:                ;
        !           371:        }
        !           372: 
        !           373:        /*
        !           374:         * Load the builtin macros for extended mnemonics for rotate and
        !           375:         * shift mnemonics.
        !           376:         */
        !           377:        for(i = 0; *m98k_macros[i].name != '\0'; i++){
        !           378:            input_line_pointer = m98k_macros[i].name;
        !           379:            s_macro(0);
        !           380:            add_to_macro_definition(m98k_macros[i].body);
        !           381:            s_endmacro(0);
        !           382:        }
        !           383: }
        !           384: 
        !           385: /*
        !           386:  * md_end() is called from main() in as.c after assembly ends.  It is used
        !           387:  * to allow target machine dependent clean up.
        !           388:  */
        !           389: void
        !           390: md_end(void)
        !           391: {
        !           392: }
        !           393: 
        !           394: /*
        !           395:  * md_parse_option() is called from main() in as.c to parse target machine
        !           396:  * dependent command line options.  This routine returns 0 if it is passed an
        !           397:  * option that is not recognized non-zero otherwise.
        !           398:  */
        !           399: int
        !           400: md_parse_option(
        !           401: char **argP,
        !           402: int *cntP,
        !           403: char ***vecP)
        !           404: {
        !           405:        return(0);
        !           406: }
        !           407: 
        !           408: /*
        !           409:  * s_reg() is used to implement ".greg symbol,exp" and ".xreg symbol,exp"
        !           410:  * which set symbol to 1 or 0 depending on if the expression is a general
        !           411:  * register or extended register respectfully.  These are intended for use in
        !           412:  * macros.
        !           413:  */
        !           414: static
        !           415: void
        !           416: s_reg(
        !           417: int reg)
        !           418: {
        !           419:        char *name, *end_name, delim;
        !           420:        symbolS *symbolP;
        !           421:        unsigned long n_value, val;
        !           422: 
        !           423:        if( * input_line_pointer == '"')
        !           424:          name = input_line_pointer + 1;
        !           425:        else
        !           426:          name = input_line_pointer;
        !           427:        delim = get_symbol_end();
        !           428:        end_name = input_line_pointer;
        !           429:        *end_name = delim;
        !           430:        SKIP_WHITESPACE();
        !           431:        if ( * input_line_pointer != ',' ) {
        !           432:                *end_name = 0;
        !           433:                as_warn("Expected comma after name \"%s\"", name);
        !           434:                *end_name = delim;
        !           435:                ignore_rest_of_line();
        !           436:                return;
        !           437:        }
        !           438:        input_line_pointer ++;
        !           439:        *end_name = 0;
        !           440: 
        !           441:        SKIP_WHITESPACE();
        !           442:        n_value = 0;
        !           443:        if (*input_line_pointer == reg || *input_line_pointer == toupper(reg)){
        !           444:            input_line_pointer++;
        !           445:            if(isdigit(*input_line_pointer)){
        !           446:                val = 0;
        !           447:                while (isdigit(*input_line_pointer)){
        !           448:                    if ((val = val * 10 + *input_line_pointer++ - '0') > 31)
        !           449:                        break;
        !           450:                }
        !           451:                SKIP_WHITESPACE();
        !           452:                if(val <= 31 &&
        !           453:                   (*input_line_pointer == '\n' || *input_line_pointer == '@'))
        !           454:                    n_value = 1;
        !           455:            }
        !           456:        }
        !           457: 
        !           458:        symbolP = symbol_find_or_make (name);
        !           459:        symbolP -> sy_type = N_ABS;
        !           460:        symbolP -> sy_other = 0; /* NO_SECT */
        !           461:        symbolP -> sy_value = n_value;
        !           462:        symbolP -> sy_frag = & zero_address_frag;
        !           463: 
        !           464:        *end_name = delim;
        !           465:        totally_ignore_line();
        !           466: }
        !           467: 
        !           468: /*
        !           469:  * md_assemble() is passed a pointer to a string that should be a assembly
        !           470:  * statement for the target machine.
        !           471:  */
        !           472: void
        !           473: md_assemble(
        !           474: char *op)
        !           475: {
        !           476:     char *param, *thisfrag, prediction;
        !           477:     struct m98k_opcode *format;
        !           478:     struct m98k_insn insn;
        !           479:     unsigned long retry;
        !           480: 
        !           481:        /*
        !           482:         * Pick up the instruction and any trailing branch prediction character
        !           483:         * (a trailing '+' or '-' on the instruction).
        !           484:         */
        !           485:        prediction = '\0';
        !           486:        for(param = op; !isspace(*param) && *param != '\0' ; param++)
        !           487:            prediction = *param;
        !           488:        if(prediction == '+' || prediction == '-')
        !           489:            param[-1] = '\0';
        !           490:        else
        !           491:            prediction = '\0';
        !           492:        if(*param != '\0')
        !           493:            *param++ = '\0';
        !           494: 
        !           495:        /* try to find the instruction in the hash table */
        !           496:        if((format = (struct m98k_opcode *)hash_find(op_hash, op)) == NULL){
        !           497:            as_warn("Invalid mnemonic '%s'", op);
        !           498:            return;
        !           499:        }
        !           500: 
        !           501:        /* try parsing this instruction into insn */
        !           502:        retry = 0;
        !           503:        error_param_count = 0;
        !           504:        error_param_message = NULL;
        !           505:        while(calcop(format, param, &insn, op, prediction) == 0){
        !           506:            /* if it doesn't parse try the next instruction */
        !           507:            if(strcmp(format->name, format[1].name) == 0){
        !           508:                format++;
        !           509:                retry = 1;
        !           510:            }
        !           511:            else{
        !           512:                if(retry == 0){
        !           513:                    if(error_param_message != NULL)
        !           514:                        as_warn(error_param_message, error_param_count + 1);
        !           515:                    else
        !           516:                        as_warn("Parameter syntax error (parameter %lu)",
        !           517:                                error_param_count + 1);
        !           518:                }
        !           519:                else
        !           520:                    as_warn("Parameter syntax error");
        !           521:                return;
        !           522:            }
        !           523:        }
        !           524: 
        !           525:        /*
        !           526:         * Check for invalid forms of instructions.  For the following
        !           527:         * instructions: lbzu, lbzux, lhzu, lhzux, lhau, lhaux, lwzu, lwzux,
        !           528:         * lwaux, ldu, ldux
        !           529:         * if RA == 0 or RA == RT the instruction form is invalid.
        !           530:         */
        !           531:        if((insn.opcode & 0xfc000000) == 0x8c000000 || /* lbzu */
        !           532:           (insn.opcode & 0xfc0007fe) == 0x7c0000ee || /* lbzux */
        !           533:           (insn.opcode & 0xfc000000) == 0xa4000000 || /* lhzu */
        !           534:           (insn.opcode & 0xfc0007fe) == 0x7c00026e || /* lbzux */
        !           535:           (insn.opcode & 0xfc000000) == 0xac000000 || /* lhau */
        !           536:           (insn.opcode & 0xfc0007fe) == 0x7c0002ee || /* lhaux */
        !           537:           (insn.opcode & 0xfc000000) == 0x84000000 || /* lwzu */
        !           538:           (insn.opcode & 0xfc0007fe) == 0x7c00006e || /* lwzux */
        !           539:           (insn.opcode & 0xfc0007fe) == 0x7c0002ea || /* lwaux */
        !           540:           (insn.opcode & 0xfc000000) == 0xe8000000 || /* ldu */
        !           541:           (insn.opcode & 0xfc0007fe) == 0x7c00006a){  /* ldux */
        !           542:            if(RA(insn.opcode) == 0)
        !           543:                as_warn("Invalid form of the instruction (RA must not be 0)");
        !           544:            if(RA(insn.opcode) == RT(insn.opcode))
        !           545:                as_warn("Invalid form of the instruction (RA must not the same "
        !           546:                        "as RT)");
        !           547:        }
        !           548:        /*
        !           549:         * For the following instructions: stbu, stbux, sthu, sthux, stwu,
        !           550:         * stwux, stdu, stdux, lfsu, lfsux, lfdu, lfdux, stfsu, stfsux, stfdu,
        !           551:         * stfdux
        !           552:         * if RA == 0 the instruction form is invalid.
        !           553:         */
        !           554:        if((insn.opcode & 0xfc000000) == 0x9c000000 || /* stbu */
        !           555:           (insn.opcode & 0xfc0007fe) == 0x7c0001ee || /* stbux */
        !           556:           (insn.opcode & 0xfc000000) == 0xb4000000 || /* sthu */
        !           557:           (insn.opcode & 0xfc0007fe) == 0x7c00036e || /* sthux */
        !           558:           (insn.opcode & 0xfc000000) == 0x94000000 || /* stwu */
        !           559:           (insn.opcode & 0xfc0007fe) == 0x7c00016e || /* stwux */
        !           560:           (insn.opcode & 0xfc000003) == 0xf8000001 || /* stdu */
        !           561:           (insn.opcode & 0xfc0007fe) == 0x7c00016a || /* stdux */
        !           562:           (insn.opcode & 0xfc000000) == 0xc4000000 || /* lfsu */
        !           563:           (insn.opcode & 0xfc0007fe) == 0x7c00046e || /* lfsux */
        !           564:           (insn.opcode & 0xfc000000) == 0xcc000000 || /* lfdu */
        !           565:           (insn.opcode & 0xfc0007fe) == 0x7c0004ee || /* lfdux */
        !           566:           (insn.opcode & 0xfc000000) == 0xd4000000 || /* stfsu */
        !           567:           (insn.opcode & 0xfc0007fe) == 0x7c00056e || /* stfsux */
        !           568:           (insn.opcode & 0xfc000000) == 0xdc000000 || /* stfdu */
        !           569:           (insn.opcode & 0xfc0007fe) == 0x7c0005ee){  /* stfdux */
        !           570:            if(RA(insn.opcode) == 0)
        !           571:                as_warn("Invalid form of the instruction (RA must not be 0)");
        !           572:        }
        !           573:        /*
        !           574:         * For the following instructions: lmw, lmd, lswi, lswx
        !           575:         * if RA is in the range of registers to be loaded or RT == RA == 0
        !           576:         * the instruction form is invalid.  WHAT does this mean?
        !           577:         */
        !           578:        if((insn.opcode & 0xfc000000) == 0xb8000000 || /* lmw */
        !           579:           (insn.opcode & 0xfc000003) == 0xe8000003 || /* lmw */
        !           580:           (insn.opcode & 0xfc0007fe) == 0x7c0004aa || /* lswi */
        !           581:           (insn.opcode & 0xfc0007fe) == 0x7c00042a){  /* lswx */
        !           582:        }
        !           583: 
        !           584:        /* grow the current frag and plop in the opcode */
        !           585:        thisfrag = frag_more(4);
        !           586:        md_number_to_chars(thisfrag, insn.opcode, 4);
        !           587: 
        !           588:        /*
        !           589:         * If the -g flag is present generate a line number stab for the
        !           590:         * instruction.
        !           591:         * 
        !           592:         * See the detailed comments about stabs in read_a_source_file() for a
        !           593:         * description of what is going on here.
        !           594:         */
        !           595:        if(flagseen['g'] && frchain_now->frch_nsect == text_nsect){
        !           596:            (void)symbol_new(
        !           597:                  "",
        !           598:                  68 /* N_SLINE */,
        !           599:                  text_nsect,
        !           600:                  logical_input_line /* n_desc, line number */,
        !           601:                  obstack_next_free(&frags) - frag_now->fr_literal,
        !           602:                  frag_now);
        !           603:        }
        !           604: 
        !           605:        /* if this instruction requires labels mark it for later */
        !           606:        switch(insn.reloc){
        !           607:        case NO_RELOC:
        !           608:            break;
        !           609:        case M98K_RELOC_HI16:
        !           610:        case M98K_RELOC_LO16:
        !           611:        case M98K_RELOC_HA16:
        !           612:        case M98K_RELOC_LO14:
        !           613:            fix_new(frag_now,
        !           614:                    thisfrag - frag_now->fr_literal,
        !           615:                    4,
        !           616:                    insn.exp.X_add_symbol,
        !           617:                    insn.exp.X_subtract_symbol,
        !           618:                    insn.exp.X_add_number,
        !           619:                    0, 0,
        !           620:                    insn.reloc);
        !           621:            break;
        !           622:        case M98K_RELOC_BR14:
        !           623:            fix_new(frag_now,
        !           624:                    thisfrag - frag_now->fr_literal,
        !           625:                    4,
        !           626:                    insn.exp.X_add_symbol,
        !           627:                    insn.exp.X_subtract_symbol,
        !           628:                    insn.exp.X_add_number,
        !           629:                    insn.pcrel,
        !           630:                    insn.pcrel_reloc,
        !           631:                    insn.reloc);
        !           632:            break;
        !           633: 
        !           634:        case M98K_RELOC_BR24:
        !           635:            fix_new(frag_now,
        !           636:                    thisfrag - frag_now->fr_literal,
        !           637:                    4,
        !           638:                    insn.exp.X_add_symbol,
        !           639:                    insn.exp.X_subtract_symbol,
        !           640:                    insn.exp.X_add_number,
        !           641:                    insn.pcrel,
        !           642:                    insn.pcrel_reloc,
        !           643:                    insn.reloc);
        !           644:            break;
        !           645:        default:
        !           646:            as_warn("Unknown relocation type");
        !           647:            break;
        !           648:        }
        !           649: }
        !           650: 
        !           651: static
        !           652: int
        !           653: calcop(
        !           654: struct m98k_opcode *format,
        !           655: char *param,
        !           656: struct m98k_insn *insn,
        !           657: char *op,
        !           658: char prediction)
        !           659: {
        !           660:     unsigned long parcnt;
        !           661: 
        !           662:        /* initial the passed structure */
        !           663:        memset(insn, '\0', sizeof(struct m98k_insn));
        !           664:        insn->opcode = format->opcode;
        !           665:        insn->reloc = NO_RELOC;
        !           666: 
        !           667:        /* parse all parameters */
        !           668:        for(parcnt = 0; parcnt < 5 &&
        !           669:                        format->ops[parcnt].type != NONE; parcnt++){
        !           670:            error_param_count = parcnt;
        !           671: 
        !           672:            switch(format->ops[parcnt].type){
        !           673:            case PCREL:
        !           674:            case BADDR:
        !           675:                param = parse_branch(param, insn, format, parcnt);
        !           676:                break;
        !           677:            case D:
        !           678:            case DS:
        !           679:                param = parse_displacement(param, insn, format, parcnt);
        !           680:                break;
        !           681:            case SI:
        !           682:            case UI:
        !           683:                param = parse_immediate(param, insn, format, parcnt);
        !           684:                break;
        !           685:            case GREG:
        !           686:            case G0REG:
        !           687:                param = parse_reg("r", param, insn, format, parcnt);
        !           688:                break;
        !           689:            case FREG:
        !           690:                param = parse_reg("f", param, insn, format, parcnt);
        !           691:                break;
        !           692:            case SGREG:
        !           693:                param = parse_reg("sr", param, insn, format, parcnt);
        !           694:                break;
        !           695:            case SPREG:
        !           696:                param = parse_spreg(param, insn, format, parcnt);
        !           697:                break;
        !           698:            case BCND:
        !           699:                param = parse_bcnd(param, insn, format, parcnt);
        !           700:                break;
        !           701:            case CRF:
        !           702:            case CRFONLY:
        !           703:                param = parse_crf(param, insn, format, parcnt);
        !           704:                break;
        !           705:            case NUM:
        !           706:                param = parse_num(param, insn, format, parcnt, 0);
        !           707:                break;
        !           708:            case NUM0:
        !           709:                param = parse_num(param, insn, format, parcnt, 1);
        !           710:                break;
        !           711:            case sh:
        !           712:                param = parse_sh(param, insn, format, parcnt);
        !           713:                break;
        !           714:            case mb:
        !           715:                param = parse_mb(param, insn, format, parcnt);
        !           716:                break;
        !           717:            default:
        !           718:                as_fatal("Unknown parameter type");
        !           719:            }
        !           720: 
        !           721:            /* see if parser failed or not */
        !           722:            if (param == NULL)
        !           723:                return(0);
        !           724:        }
        !           725:        if(format->ops[0].type == NONE && *param != '\0'){
        !           726:            error_param_message = "too many parameters";
        !           727:            return(0);
        !           728:        }
        !           729: 
        !           730:        if(IS_BRANCH_CONDITIONAL(insn->opcode)){
        !           731:            if(prediction != '\0'){
        !           732:                /*
        !           733:                 * Set the Y_BIT assuming the displacement is non-negitive.
        !           734:                 * If the displacement is negitive then the Y_BIT is flipped
        !           735:                 * in md_number_to_imm().
        !           736:                 */
        !           737:                if(prediction == '+')
        !           738:                    insn->opcode |= Y_BIT;
        !           739:                else{ /* prediction == '-' */
        !           740:                    if((insn->opcode & Y_BIT) != 0)
        !           741:                        as_warn("branch prediction ('-') ignored (specified "
        !           742:                                "operand has prediction bit set)");
        !           743:                    else
        !           744:                        insn->opcode &= ~(Y_BIT);
        !           745:                }
        !           746:            }
        !           747:        }
        !           748:        else{
        !           749:            if(prediction != '\0')
        !           750:                as_warn("branch prediction ignored (instruction is not a "
        !           751:                        "conditional branch)");
        !           752:        }
        !           753:        return(1);
        !           754: }
        !           755: 
        !           756: static
        !           757: char *
        !           758: parse_displacement(
        !           759: char *param,
        !           760: struct m98k_insn *insn,
        !           761: struct m98k_opcode *format,
        !           762: int parcnt)
        !           763: {
        !           764:     unsigned long val;
        !           765:     char *end, *saveptr, *saveparam;
        !           766:     segT seg;
        !           767: 
        !           768: 
        !           769:        if(parcnt != 1 || format->ops[2].type != G0REG)
        !           770:             as_fatal("internal error, bad table entry for instruction %s "
        !           771:                      "(displacement operand not second operand or general "
        !           772:                      "register not third operand)", format->name);
        !           773: 
        !           774:        /*
        !           775:         * There must be "(rX)" (where X is a number between 0-31) or "(0)"
        !           776:         * at the end of the parameter string.  To know out where the
        !           777:         * displacement expression ends determine the begining the "(rX)"
        !           778:         * by looking for the last '(' in the string.  The parsing of this
        !           779:         * trailing string will be done in another routine.
        !           780:         */
        !           781:        end = strrchr(param, '(');
        !           782:        if(end == NULL)
        !           783:            return(NULL);
        !           784:        *end = '\0';
        !           785: 
        !           786:        /*
        !           787:         * The expression may have one of the following: hi16(exp), ha16(exp),
        !           788:         * or lo16(exp) around the expression which determines the relocation
        !           789:         * type.
        !           790:         */
        !           791:        if(strncmp(param,"hi16(",5) == 0){
        !           792:            insn->reloc = M98K_RELOC_HI16;
        !           793:            param += 5;
        !           794:        }
        !           795:        else if(strncmp(param,"ha16(",5) == 0){
        !           796:            insn->reloc = M98K_RELOC_HA16;
        !           797:            param += 5;
        !           798:        }
        !           799:        else if(strncmp(param,"lo16(",5) == 0){
        !           800:            if(format->ops[parcnt].type == DS)
        !           801:                insn->reloc = M98K_RELOC_LO14;
        !           802:            else
        !           803:                insn->reloc = M98K_RELOC_LO16;
        !           804:            param += 5;
        !           805:        }
        !           806: 
        !           807:        saveptr = input_line_pointer;
        !           808:        input_line_pointer = param;
        !           809: 
        !           810:        seg = expression(&insn->exp);
        !           811:        try_to_make_absolute(&insn->exp);
        !           812:        seg = insn->exp.X_seg;
        !           813: 
        !           814:        saveparam = input_line_pointer;
        !           815:        input_line_pointer = saveptr;
        !           816:        *end = '(';
        !           817: 
        !           818:        if(insn->reloc != NO_RELOC){
        !           819:            if(*saveparam != ')' || ++saveparam != end)
        !           820:                return(NULL);
        !           821:        }
        !           822:        else{
        !           823:            if(saveparam != end)
        !           824:                return(NULL);
        !           825:            val = insn->exp.X_add_number;
        !           826:            if(seg != SEG_ABSOLUTE){
        !           827:                error_param_message = "Parameter error: expression must be "
        !           828:                                      "absolute (parameter %lu)";
        !           829:                return(NULL);
        !           830:            }
        !           831:            if(val & 0x8000){
        !           832:                if((val & 0xffff0000) != 0xffff0000){
        !           833:                    error_param_message = "Parameter error: expression out of "
        !           834:                                          "range (parameter %lu)";
        !           835:                    return(NULL);
        !           836:                }
        !           837:                val = val & 0xffff;
        !           838:            }
        !           839:            else{
        !           840:                if((val & 0xffff0000) != 0){
        !           841:                    error_param_message = "Parameter error: expression out of "
        !           842:                                          "range (parameter %lu)";
        !           843:                    return(NULL);
        !           844:                }
        !           845:            }
        !           846:            if(format->ops[parcnt].type == DS){
        !           847:                if((val & 0x3) != 0){
        !           848:                    error_param_message = "Parameter error: expression must be "
        !           849:                                          "a multiple of 4 (parameter %lu)";
        !           850:                    return(NULL);
        !           851:                }
        !           852:                val >>= 2;
        !           853:            }
        !           854:            insn->opcode |= val << format->ops[parcnt].offset;
        !           855:        }
        !           856:        return(saveparam);
        !           857: }
        !           858: 
        !           859: static
        !           860: char *
        !           861: parse_immediate(
        !           862: char *param,
        !           863: struct m98k_insn *insn,
        !           864: struct m98k_opcode *format,
        !           865: int parcnt)
        !           866: {
        !           867:     unsigned long val;
        !           868:     char *saveptr, *saveparam;
        !           869:     segT seg;
        !           870: 
        !           871:        /*
        !           872:         * The expression may have one of the following: hi16(exp), ha16(exp),
        !           873:         * or lo16(exp) around the expression which determines the relocation
        !           874:         * type.
        !           875:         */
        !           876:        if(strncmp(param,"hi16(",5) == 0){
        !           877:            insn->reloc = M98K_RELOC_HI16;
        !           878:            param += 5;
        !           879:        }
        !           880:        else if(strncmp(param,"ha16(",5) == 0){
        !           881:            insn->reloc = M98K_RELOC_HA16;
        !           882:            param += 5;
        !           883:        }
        !           884:        else if(strncmp(param,"lo16(",5) == 0){
        !           885:            if(format->ops[parcnt].type == DS)
        !           886:                insn->reloc = M98K_RELOC_LO14;
        !           887:            else
        !           888:                insn->reloc = M98K_RELOC_LO16;
        !           889:            param += 5;
        !           890:        }
        !           891: 
        !           892:        saveptr = input_line_pointer;
        !           893:        input_line_pointer = param;
        !           894: 
        !           895:        seg = expression(&insn->exp);
        !           896:        try_to_make_absolute(&insn->exp);
        !           897:        seg = insn->exp.X_seg;
        !           898: 
        !           899:        saveparam = input_line_pointer;
        !           900:        input_line_pointer = saveptr;
        !           901: 
        !           902:        if(insn->reloc != NO_RELOC){
        !           903:            if(*saveparam != ')')
        !           904:                return(NULL);
        !           905:            saveparam++;
        !           906:            if(*saveparam == '\0'){
        !           907:                if(parcnt == 4 || format->ops[parcnt+1].type == NONE)
        !           908:                    return(saveparam);
        !           909:                else
        !           910:                    return(NULL);
        !           911:            }
        !           912:            else if(*saveparam == ','){
        !           913:                if(parcnt != 4 && format->ops[parcnt+1].type != NONE)
        !           914:                    return(saveparam+1);
        !           915:                else
        !           916:                    return(NULL);
        !           917:            }
        !           918:            else
        !           919:                return(NULL);
        !           920:        }
        !           921:        else{
        !           922:            val = insn->exp.X_add_number;
        !           923:            if(seg != SEG_ABSOLUTE){
        !           924:                error_param_message = "Parameter error: expression must be "
        !           925:                                      "absolute (parameter %lu)";
        !           926:                return(NULL);
        !           927:            }
        !           928:            if(format->ops[parcnt].type == SI){
        !           929:                if(val & 0x8000){
        !           930:                    if((val & 0xffff0000) != 0xffff0000){
        !           931:                        error_param_message = "Parameter error: expression out "
        !           932:                                              "of range (parameter %lu)";
        !           933:                        return(NULL);
        !           934:                    }
        !           935:                    val = val & 0xffff;
        !           936:                }
        !           937:                else{
        !           938:                    if((val & 0xffff0000) != 0){
        !           939:                        error_param_message = "Parameter error: expression out "
        !           940:                                              "of range (parameter %lu)";
        !           941:                        return(NULL);
        !           942:                    }
        !           943:                }
        !           944:            }
        !           945:            else{
        !           946:                if((val & 0xffff0000) != 0){
        !           947:                    error_param_message = "Parameter error: expression out "
        !           948:                                          "of range (parameter %lu)";
        !           949:                    return(NULL);
        !           950:                }
        !           951:            }
        !           952:            if(*saveparam == '\0'){
        !           953:                if(parcnt == 4 || format->ops[parcnt+1].type == NONE){
        !           954:                    insn->opcode |= val << format->ops[parcnt].offset;
        !           955:                    return(saveparam);
        !           956:                }
        !           957:                else
        !           958:                    return(NULL);
        !           959:            }
        !           960:            else if(*saveparam == ','){
        !           961:                if(parcnt != 4 && format->ops[parcnt+1].type != NONE){
        !           962:                    insn->opcode |= val << format->ops[parcnt].offset;
        !           963:                    return(saveparam+1);
        !           964:                }
        !           965:                else
        !           966:                    return(NULL);
        !           967:            }
        !           968:            else
        !           969:                return(NULL);
        !           970:        }
        !           971:        return(saveparam);
        !           972: }
        !           973: 
        !           974: static
        !           975: char *
        !           976: parse_branch(
        !           977: char *param,
        !           978: struct m98k_insn *insn,
        !           979: struct m98k_opcode *format,
        !           980: int parcnt)
        !           981: {
        !           982:     char *saveptr, *saveparam;
        !           983:     segT seg;
        !           984: 
        !           985:        saveptr = input_line_pointer;
        !           986:        input_line_pointer = param;
        !           987: 
        !           988:        seg = expression(&insn->exp);
        !           989:        try_to_make_absolute(&insn->exp);
        !           990:        seg = insn->exp.X_seg;
        !           991: 
        !           992:        saveparam = input_line_pointer;
        !           993:        input_line_pointer = saveptr;
        !           994: 
        !           995:        insn->pcrel = 0;
        !           996:        insn->pcrel_reloc = 0;
        !           997:        if(format->ops[parcnt].type == PCREL){
        !           998:            /*
        !           999:             * The NeXT linker has the ability to scatter blocks of
        !          1000:             * sections between labels.  This requires that brances to
        !          1001:             * labels that survive to the link phase must be able to
        !          1002:             * be relocated.
        !          1003:             */
        !          1004:            if(insn->exp.X_add_symbol != NULL &&
        !          1005:               (insn->exp.X_add_symbol->sy_name[0] != 'L' || flagseen ['L']))
        !          1006:                insn->pcrel_reloc = 1;
        !          1007:            else
        !          1008:                insn->pcrel_reloc = 0;
        !          1009:            insn->pcrel = 1;
        !          1010:        }
        !          1011:        switch(format->ops[parcnt].width){
        !          1012:        case 14:
        !          1013:            insn->reloc = M98K_RELOC_BR14;
        !          1014:            break;
        !          1015:        case 24:
        !          1016:            insn->reloc = M98K_RELOC_BR24;
        !          1017:            break;
        !          1018:        default:
        !          1019:            as_fatal("Unknown branch instruction width %d",
        !          1020:                    format->ops[parcnt].width);
        !          1021:            break;
        !          1022:        }
        !          1023:        return(saveparam);
        !          1024: }
        !          1025: 
        !          1026: static
        !          1027: char *
        !          1028: parse_reg(
        !          1029: char *reg_name,
        !          1030: char *param,
        !          1031: struct m98k_insn *insn,
        !          1032: struct m98k_opcode *format,
        !          1033: unsigned long parcnt)
        !          1034: {
        !          1035:     unsigned long val, d;
        !          1036: 
        !          1037:        d = 0;
        !          1038:        if(*param == '(' && parcnt == 2 &&
        !          1039:           (format->ops[1].type == D || format->ops[1].type == DS)){
        !          1040:            d = 1;
        !          1041:            param++;
        !          1042:        }
        !          1043: 
        !          1044:        if(format->ops[parcnt].type == G0REG && *param == '0'){
        !          1045:            val = 0;
        !          1046:            param++;
        !          1047:        }
        !          1048:        else{
        !          1049:            val = 0;
        !          1050:            while(*reg_name){
        !          1051:                if(*param++ != *reg_name++)
        !          1052:                    return(NULL);
        !          1053:            }
        !          1054:            if(!isdigit(*param))
        !          1055:                return(NULL);
        !          1056: 
        !          1057:            while(isdigit(*param))
        !          1058:                if((val = val * 10 + *param++ - '0') >=
        !          1059:                   1 << format->ops[parcnt].width)
        !          1060:                return(NULL);
        !          1061: 
        !          1062:            if(format->ops[parcnt].type == G0REG && val == 0){
        !          1063:                error_param_message = "Parameter error: r0 not allowed "
        !          1064:                                      "for parameter %lu (code as 0 not r0)";
        !          1065:                return(NULL);
        !          1066:            }
        !          1067:        }
        !          1068: 
        !          1069:        if(*param == '\0'){
        !          1070:            if(parcnt == 4 || format->ops[parcnt+1].type == NONE){
        !          1071:                insn->opcode |= val << format->ops[parcnt].offset;
        !          1072:                return(param);
        !          1073:            }
        !          1074:            else
        !          1075:                return(NULL);
        !          1076:        }
        !          1077:        else if(*param == ','){
        !          1078:            if(parcnt != 4 && format->ops[parcnt+1].type != NONE){
        !          1079:                insn->opcode |= val << format->ops[parcnt].offset;
        !          1080:                return(param+1);
        !          1081:            }
        !          1082:            else
        !          1083:                return(NULL);
        !          1084:        }
        !          1085:        else if(d == 1 && *param == ')' && param[1] == '\0'){
        !          1086:            if(parcnt == 4 || format->ops[parcnt+1].type == NONE){
        !          1087:                insn->opcode |= val << format->ops[parcnt].offset;
        !          1088:                return(++param);
        !          1089:            }
        !          1090:            else
        !          1091:                return(NULL);
        !          1092:        }
        !          1093:        return(NULL);
        !          1094: }
        !          1095: 
        !          1096: static
        !          1097: char *
        !          1098: parse_spreg(
        !          1099: char *param,
        !          1100: struct m98k_insn *insn,
        !          1101: struct m98k_opcode *format,
        !          1102: unsigned long parcnt)
        !          1103: {
        !          1104:     int val;
        !          1105:     unsigned long i;
        !          1106:     char *saveptr, save_c;
        !          1107:     expressionS exp;
        !          1108:     segT seg;
        !          1109: 
        !          1110:        saveptr = input_line_pointer;
        !          1111:        input_line_pointer = param;
        !          1112:        while(*param != ',' && *param != '\0')
        !          1113:                param++;
        !          1114:        save_c = *param;
        !          1115:        *param = '\0';
        !          1116: 
        !          1117:        seg = SEG_ABSOLUTE;
        !          1118:        val = 0;
        !          1119:        for(i = 0; *special_registers[i].name != '\0'; i++){
        !          1120:            if(strcmp(input_line_pointer, special_registers[i].name) == 0){
        !          1121:                val = special_registers[i].number;
        !          1122:                break;
        !          1123:            }
        !          1124:        }
        !          1125:        if(*special_registers[i].name == '\0'){
        !          1126:            seg = expression(&exp);
        !          1127:            try_to_make_absolute(&exp);
        !          1128:            seg = exp.X_seg;
        !          1129:            val = exp.X_add_number;
        !          1130:        }
        !          1131:        *param = save_c;
        !          1132:        input_line_pointer = saveptr;
        !          1133: 
        !          1134:        if(seg != SEG_ABSOLUTE){
        !          1135:            error_param_message = "Parameter error: expression must be "
        !          1136:                                  "absolute (parameter %lu)";
        !          1137:            return(NULL);
        !          1138:        }
        !          1139:        if(val > 1024 || val < 0){
        !          1140:            error_param_message = "Parameter error: expression out "
        !          1141:                                  "of range (parameter %lu)";
        !          1142:            return(NULL);
        !          1143:        }
        !          1144: 
        !          1145:        val = ((val & 0x1f) << 5) | ((val >> 5) & 0x1f);
        !          1146: 
        !          1147:        if(*param == '\0'){
        !          1148:            if(parcnt == 4 || format->ops[parcnt+1].type == NONE){
        !          1149:                insn->opcode |= val << format->ops[parcnt].offset;
        !          1150:                return(param);
        !          1151:            }
        !          1152:            else
        !          1153:                return(NULL);
        !          1154:        }
        !          1155:        else if(*param == ','){
        !          1156:            if(parcnt != 4 && format->ops[parcnt+1].type != NONE){
        !          1157:                insn->opcode |= val << format->ops[parcnt].offset;
        !          1158:                return(param+1);
        !          1159:            }
        !          1160:            else
        !          1161:                return(NULL);
        !          1162:        }
        !          1163:        return(NULL);
        !          1164: }
        !          1165: 
        !          1166: static
        !          1167: char *
        !          1168: parse_bcnd(
        !          1169: char *param,
        !          1170: struct m98k_insn *insn,
        !          1171: struct m98k_opcode *format,
        !          1172: unsigned long parcnt)
        !          1173: {
        !          1174:     int val;
        !          1175:     unsigned long i, j;
        !          1176:     char *saveptr, save_c, *plus, save_plus;
        !          1177:     expressionS exp;
        !          1178:     segT seg;
        !          1179: 
        !          1180:        saveptr = input_line_pointer;
        !          1181:        input_line_pointer = param;
        !          1182:        while(*param != ',' && *param != '\0')
        !          1183:            param++;
        !          1184:        save_c = *param;
        !          1185:        *param = '\0';
        !          1186: 
        !          1187:        /*
        !          1188:         * look for "[CR_field+]condition_symbol".
        !          1189:         */
        !          1190:        val = -1;
        !          1191:        for(plus = input_line_pointer; *plus != '+' && *plus != '\0'; plus++)
        !          1192:            ;
        !          1193:        if(*plus == '+'){
        !          1194:            save_plus = *plus;
        !          1195:            *plus = '\0';
        !          1196:            for(i = 0; *CR_fields[i].name != '\0'; i++)
        !          1197:                if(strcmp(input_line_pointer, CR_fields[i].name) == 0)
        !          1198:                    break;
        !          1199:            *plus = save_plus;
        !          1200:            if(*CR_fields[i].name != '\0'){
        !          1201:                for(j = 0; *condition_symbols[j].name != '\0'; j++)
        !          1202:                    if(strcmp(plus+1, condition_symbols[j].name) == 0)
        !          1203:                        break;
        !          1204:                if(*condition_symbols[j].name != '\0'){
        !          1205:                    val = CR_fields[i].value + condition_symbols[j].value;
        !          1206:                }
        !          1207:            }
        !          1208:        }
        !          1209:        else{
        !          1210:            for(i = 0; *condition_symbols[i].name != '\0'; i++)
        !          1211:                if(strcmp(input_line_pointer, condition_symbols[i].name) == 0)
        !          1212:                    break;
        !          1213:            if(*condition_symbols[i].name != '\0')
        !          1214:                val = condition_symbols[i].value;
        !          1215:        }
        !          1216:        if(val == -1){
        !          1217:            seg = expression(&exp);
        !          1218:            try_to_make_absolute(&exp);
        !          1219:            seg = exp.X_seg;
        !          1220:            val = exp.X_add_number;
        !          1221:            if(seg != SEG_ABSOLUTE){
        !          1222:                error_param_message = "Parameter error: expression must be "
        !          1223:                                      "absolute (parameter %lu)";
        !          1224:                *param = save_c;
        !          1225:                input_line_pointer = saveptr;
        !          1226:                return(NULL);
        !          1227:            }
        !          1228:            if(val >= (1 << format->ops[parcnt].width) || val < 0){
        !          1229:                error_param_message = "Parameter error: expression out "
        !          1230:                                      "of range (parameter %lu)";
        !          1231:                *param = save_c;
        !          1232:                input_line_pointer = saveptr;
        !          1233:                return(NULL);
        !          1234:            }
        !          1235:        }
        !          1236: 
        !          1237:        *param = save_c;
        !          1238:        input_line_pointer = saveptr;
        !          1239: 
        !          1240: 
        !          1241:        if(*param == '\0'){
        !          1242:            if(parcnt == 4 || format->ops[parcnt+1].type == NONE){
        !          1243:                insn->opcode |= val << format->ops[parcnt].offset;
        !          1244:                return(param);
        !          1245:            }
        !          1246:            else
        !          1247:                return(NULL);
        !          1248:        }
        !          1249:        else if(*param == ','){
        !          1250:            if(parcnt != 4 && format->ops[parcnt+1].type != NONE){
        !          1251:                insn->opcode |= val << format->ops[parcnt].offset;
        !          1252:                return(param+1);
        !          1253:            }
        !          1254:            else
        !          1255:                return(NULL);
        !          1256:        }
        !          1257:        return(NULL);
        !          1258: 
        !          1259: }
        !          1260: 
        !          1261: static
        !          1262: char *
        !          1263: parse_crf(
        !          1264: char *param,
        !          1265: struct m98k_insn *insn,
        !          1266: struct m98k_opcode *format,
        !          1267: unsigned long parcnt)
        !          1268: {
        !          1269:     int val;
        !          1270:     unsigned long i;
        !          1271:     char *saveptr, save_c;
        !          1272:     expressionS exp;
        !          1273:     segT seg;
        !          1274: 
        !          1275:        saveptr = input_line_pointer;
        !          1276:        input_line_pointer = param;
        !          1277:        while(*param != ',' && *param != '\0')
        !          1278:            param++;
        !          1279:        save_c = *param;
        !          1280:        *param = '\0';
        !          1281:        val = -1;
        !          1282:        for(i = 0; *CR_fields[i].name != '\0'; i++){
        !          1283:            if(strcmp(input_line_pointer, CR_fields[i].name) == 0){
        !          1284:                val = CR_fields[i].value;
        !          1285:                break;
        !          1286:            }
        !          1287:        }
        !          1288:        if(val == -1){
        !          1289:            if(format->ops[parcnt].type == CRFONLY){
        !          1290:                *param = save_c;
        !          1291:                input_line_pointer = saveptr;
        !          1292:                return(NULL);
        !          1293:            }
        !          1294:            seg = expression(&exp);
        !          1295:            try_to_make_absolute(&exp);
        !          1296:            seg = exp.X_seg;
        !          1297:            val = exp.X_add_number;
        !          1298:            if(seg != SEG_ABSOLUTE){
        !          1299:                error_param_message = "Parameter error: expression must be "
        !          1300:                                      "absolute (parameter %lu)";
        !          1301:                *param = save_c;
        !          1302:                input_line_pointer = saveptr;
        !          1303:                return(NULL);
        !          1304:            }
        !          1305:            if(val >= (1 << format->ops[parcnt].width) || val < 0){
        !          1306:                error_param_message = "Parameter error: expression out "
        !          1307:                                      "of range (parameter %lu)";
        !          1308:                *param = save_c;
        !          1309:                input_line_pointer = saveptr;
        !          1310:                return(NULL);
        !          1311:            }
        !          1312:        }
        !          1313:        *param = save_c;
        !          1314:        input_line_pointer = saveptr;
        !          1315: 
        !          1316:        if(*param == '\0'){
        !          1317:            if(parcnt == 4 || format->ops[parcnt+1].type == NONE){
        !          1318:                insn->opcode |= val << format->ops[parcnt].offset;
        !          1319:                return(param);
        !          1320:            }
        !          1321:            else
        !          1322:                return(NULL);
        !          1323:        }
        !          1324:        else if(*param == ','){
        !          1325:            if(parcnt != 4 && format->ops[parcnt+1].type != NONE){
        !          1326:                insn->opcode |= val << format->ops[parcnt].offset;
        !          1327:                return(param+1);
        !          1328:            }
        !          1329:            else
        !          1330:                return(NULL);
        !          1331:        }
        !          1332:        return(NULL);
        !          1333: }
        !          1334: 
        !          1335: static
        !          1336: char *
        !          1337: parse_num(
        !          1338: char *param,
        !          1339: struct m98k_insn *insn,
        !          1340: struct m98k_opcode *format,
        !          1341: unsigned long parcnt,
        !          1342: long max_width_zero)
        !          1343: {
        !          1344:     int val;
        !          1345:     char *saveptr, save_c;
        !          1346:     expressionS exp;
        !          1347:     segT seg;
        !          1348: 
        !          1349:        saveptr = input_line_pointer;
        !          1350:        input_line_pointer = param;
        !          1351:        while(*param != ',' && *param != '\0')
        !          1352:                param++;
        !          1353:        save_c = *param;
        !          1354:        *param = '\0';
        !          1355:        seg = expression(&exp);
        !          1356:        try_to_make_absolute(&exp);
        !          1357:        seg = exp.X_seg;
        !          1358:        *param = save_c;
        !          1359:        input_line_pointer = saveptr;
        !          1360: 
        !          1361:        val = exp.X_add_number;
        !          1362:        if(seg != SEG_ABSOLUTE){
        !          1363:            error_param_message = "Parameter error: expression must be "
        !          1364:                                  "absolute (parameter %lu)";
        !          1365:            return(NULL);
        !          1366:        }
        !          1367:        if(max_width_zero){
        !          1368:            if(val == (1 << format->ops[parcnt].width))
        !          1369:                val = 0;
        !          1370:        }
        !          1371:        if(val >= (1 << format->ops[parcnt].width) || val < 0){
        !          1372:            error_param_message = "Parameter error: expression out "
        !          1373:                                  "of range (parameter %lu)";
        !          1374:            return(NULL);
        !          1375:        }
        !          1376: 
        !          1377:        if(*param == '\0'){
        !          1378:            if(parcnt == 4 || format->ops[parcnt+1].type == NONE){
        !          1379:                insn->opcode |= val << format->ops[parcnt].offset;
        !          1380:                return(param);
        !          1381:            }
        !          1382:            else
        !          1383:                return(NULL);
        !          1384:        }
        !          1385:        else if(*param == ','){
        !          1386:            if(parcnt != 4 && format->ops[parcnt+1].type != NONE){
        !          1387:                insn->opcode |= val << format->ops[parcnt].offset;
        !          1388:                return(param+1);
        !          1389:            }
        !          1390:            else
        !          1391:                return(NULL);
        !          1392:        }
        !          1393:        return(NULL);
        !          1394: 
        !          1395: }
        !          1396: 
        !          1397: static
        !          1398: char *
        !          1399: parse_sh(
        !          1400: char *param,
        !          1401: struct m98k_insn *insn,
        !          1402: struct m98k_opcode *format,
        !          1403: unsigned long parcnt)
        !          1404: {
        !          1405:     int val;
        !          1406:     char *saveptr, save_c;
        !          1407:     expressionS exp;
        !          1408:     segT seg;
        !          1409: 
        !          1410:        saveptr = input_line_pointer;
        !          1411:        input_line_pointer = param;
        !          1412:        while(*param != ',' && *param != '\0')
        !          1413:                param++;
        !          1414:        save_c = *param;
        !          1415:        *param = '\0';
        !          1416:        seg = expression(&exp);
        !          1417:        try_to_make_absolute(&exp);
        !          1418:        seg = exp.X_seg;
        !          1419:        *param = save_c;
        !          1420:        input_line_pointer = saveptr;
        !          1421: 
        !          1422:        val = exp.X_add_number;
        !          1423:        if(seg != SEG_ABSOLUTE){
        !          1424:            error_param_message = "Parameter error: expression must be "
        !          1425:                                  "absolute (parameter %lu)";
        !          1426:            return(NULL);
        !          1427:        }
        !          1428:        if(val == 64)
        !          1429:            val = 0;
        !          1430:        if(val >= 64 || val < 0){
        !          1431:            error_param_message = "Parameter error: expression out "
        !          1432:                                  "of range (parameter %lu)";
        !          1433:            return(NULL);
        !          1434:        }
        !          1435: 
        !          1436:        if(*param == '\0'){
        !          1437:            if(parcnt == 4 || format->ops[parcnt+1].type == NONE){
        !          1438:                insn->opcode |= (val & 0x1f) << 11;
        !          1439:                insn->opcode |= ((val >> 5) & 0x1) << 1;
        !          1440:                return(param);
        !          1441:            }
        !          1442:            else
        !          1443:                return(NULL);
        !          1444:        }
        !          1445:        else if(*param == ','){
        !          1446:            if(parcnt != 4 && format->ops[parcnt+1].type != NONE){
        !          1447:                insn->opcode |= (val & 0x1f) << 11;
        !          1448:                insn->opcode |= ((val >> 5) & 0x1) << 1;
        !          1449:                return(param+1);
        !          1450:            }
        !          1451:            else
        !          1452:                return(NULL);
        !          1453:        }
        !          1454:        return(NULL);
        !          1455: 
        !          1456: }
        !          1457: 
        !          1458: static
        !          1459: char *
        !          1460: parse_mb(
        !          1461: char *param,
        !          1462: struct m98k_insn *insn,
        !          1463: struct m98k_opcode *format,
        !          1464: unsigned long parcnt)
        !          1465: {
        !          1466:     int val;
        !          1467:     char *saveptr, save_c;
        !          1468:     expressionS exp;
        !          1469:     segT seg;
        !          1470: 
        !          1471:        saveptr = input_line_pointer;
        !          1472:        input_line_pointer = param;
        !          1473:        while(*param != ',' && *param != '\0')
        !          1474:                param++;
        !          1475:        save_c = *param;
        !          1476:        *param = '\0';
        !          1477:        seg = expression(&exp);
        !          1478:        try_to_make_absolute(&exp);
        !          1479:        seg = exp.X_seg;
        !          1480:        *param = save_c;
        !          1481:        input_line_pointer = saveptr;
        !          1482: 
        !          1483:        val = exp.X_add_number;
        !          1484:        if(seg != SEG_ABSOLUTE){
        !          1485:            error_param_message = "Parameter error: expression must be "
        !          1486:                                  "absolute (parameter %lu)";
        !          1487:            return(NULL);
        !          1488:        }
        !          1489:        if(val > 64 || val < 0){
        !          1490:            error_param_message = "Parameter error: expression out "
        !          1491:                                  "of range (parameter %lu)";
        !          1492:            return(NULL);
        !          1493:        }
        !          1494: 
        !          1495:        if(*param == '\0'){
        !          1496:            if(parcnt == 4 || format->ops[parcnt+1].type == NONE){
        !          1497:                insn->opcode |= (val & 0x1f) << 6;
        !          1498:                insn->opcode |= ((val >> 5) & 0x1) << 5;
        !          1499:                return(param);
        !          1500:            }
        !          1501:            else
        !          1502:                return(NULL);
        !          1503:        }
        !          1504:        else if(*param == ','){
        !          1505:            if(parcnt != 4 && format->ops[parcnt+1].type != NONE){
        !          1506:                insn->opcode |= (val & 0x1f) << 6;
        !          1507:                insn->opcode |= ((val >> 5) & 0x1) << 5;
        !          1508:                return(param+1);
        !          1509:            }
        !          1510:            else
        !          1511:                return(NULL);
        !          1512:        }
        !          1513:        return(NULL);
        !          1514: 
        !          1515: }
        !          1516: 
        !          1517: /*
        !          1518:  * md_number_to_chars() is the target machine dependent routine that puts out
        !          1519:  * a binary value of size 4, 2, or 1 bytes into the specified buffer.  This is
        !          1520:  * done in the target machine's byte sex.  In this case the byte order is
        !          1521:  * big endian.
        !          1522:  */
        !          1523: void
        !          1524: md_number_to_chars(
        !          1525: char *buf,
        !          1526: long val,
        !          1527: int nbytes)
        !          1528: {
        !          1529:        switch(nbytes){
        !          1530:        case 4:
        !          1531:            *buf++ = val >> 24;
        !          1532:            *buf++ = val >> 16;
        !          1533:        case 2:
        !          1534:            *buf++ = val >> 8;
        !          1535:        case 1:
        !          1536:            *buf = val;
        !          1537:            break;
        !          1538: 
        !          1539:        default:
        !          1540:            abort();
        !          1541:        }
        !          1542: }
        !          1543: 
        !          1544: /*
        !          1545:  * md_number_to_imm() is the target machine dependent routine that puts out
        !          1546:  * a binary value of size 4, 2, or 1 bytes into the specified buffer with
        !          1547:  * reguard to a possible relocation entry (the fixP->fx_r_type field in the fixS
        !          1548:  * structure pointed to by fixP) for the section with the ordinal nsect.  This
        !          1549:  * is done in the target machine's byte sex using it's relocation types.
        !          1550:  * In this case the byte order is big endian.
        !          1551:  */
        !          1552: void
        !          1553: md_number_to_imm(
        !          1554: unsigned char *buf,
        !          1555: long val,
        !          1556: int nbytes,
        !          1557: fixS *fixP,
        !          1558: int nsect)
        !          1559: {
        !          1560:     unsigned long opcode;
        !          1561: 
        !          1562:        if(fixP->fx_r_type == NO_RELOC ||
        !          1563:           fixP->fx_r_type == M98K_RELOC_VANILLA){
        !          1564:            switch(nbytes){
        !          1565:            case 4:
        !          1566:                *buf++ = val >> 24;
        !          1567:                *buf++ = val >> 16;
        !          1568:            case 2:
        !          1569:                *buf++ = val >> 8;
        !          1570:            case 1:
        !          1571:                *buf = val;
        !          1572:                break;
        !          1573: 
        !          1574:            default:
        !          1575:                abort();
        !          1576:            }
        !          1577:            return;
        !          1578:        }
        !          1579:        switch(fixP->fx_r_type){
        !          1580:        case M98K_RELOC_HI16:
        !          1581:            buf[2] = val >> 24;
        !          1582:            buf[3] = val >> 16;
        !          1583:            break;
        !          1584: 
        !          1585:        case M98K_RELOC_LO16:
        !          1586:            buf[2] = val >> 8;
        !          1587:            buf[3] = val;
        !          1588:            break;
        !          1589: 
        !          1590:        case M98K_RELOC_HA16:
        !          1591:            val += 0x00008000;
        !          1592:            buf[2] = val >> 24;
        !          1593:            buf[3] = val >> 16;
        !          1594:            break;
        !          1595: 
        !          1596:        case M98K_RELOC_LO14:
        !          1597:            buf[2] = val >> 8;
        !          1598:            buf[3] = val & 0xfc;
        !          1599:            break;
        !          1600: 
        !          1601:        case M98K_RELOC_BR14:
        !          1602:            if((val & 0x00008000) != 0){
        !          1603:                opcode = buf[0] << 24 | buf[1] << 16 | buf[2] << 8 | buf[3];
        !          1604:                if(((opcode) & 0x03e00000) != 0x02800000){
        !          1605:                    opcode ^= Y_BIT;
        !          1606:                    buf[0] = opcode >> 24;
        !          1607:                    buf[1] = opcode >> 16;
        !          1608:                    buf[2] = opcode >> 8;
        !          1609:                    buf[3] = opcode;
        !          1610:                }
        !          1611:            }
        !          1612:            if(fixP->fx_pcrel)
        !          1613:                val += 4;
        !          1614:            buf[2] = val >> 8;
        !          1615:            buf[3] |= val & 0xfc;
        !          1616:            break;
        !          1617: 
        !          1618:        case M98K_RELOC_BR24:
        !          1619:            if(fixP->fx_pcrel)
        !          1620:                val += 4;
        !          1621:            buf[0] |= (val >> 24) & 0x03;
        !          1622:            buf[1] = val >> 16;
        !          1623:            buf[2] = val >> 8;
        !          1624:            buf[3] |= val & 0xfc;
        !          1625:            break;
        !          1626: 
        !          1627:        default:
        !          1628:            as_warn("Bad relocation type");
        !          1629:            break;
        !          1630:        }
        !          1631: }
        !          1632: 
        !          1633: /*
        !          1634:  * md_atof() turns a string pointed to by input_line_pointer into a floating
        !          1635:  * point constant of type type, and store the appropriate bytes in *litP.
        !          1636:  * The number of LITTLENUMS emitted is stored indirectly through *sizeP.
        !          1637:  * An error message is returned, or a string containg only a '\0' for OK.
        !          1638:  * For this machine only IEEE single and IEEE double floating-point formats
        !          1639:  * are allowed.
        !          1640:  */
        !          1641: char *
        !          1642: md_atof(
        !          1643: int type,
        !          1644: char *litP,
        !          1645: int *sizeP)
        !          1646: {
        !          1647:     int        prec;
        !          1648:     LITTLENUM_TYPE words[6];
        !          1649:     LITTLENUM_TYPE *wordP;
        !          1650:     char *t;
        !          1651: 
        !          1652:        switch(type){
        !          1653:        case 'f':
        !          1654:        case 'F':
        !          1655:        case 's':
        !          1656:        case 'S':
        !          1657:            prec = 2;
        !          1658:            break;
        !          1659: 
        !          1660:        case 'd':
        !          1661:        case 'D':
        !          1662:        case 'r':
        !          1663:        case 'R':
        !          1664:            prec = 4;
        !          1665:            break;
        !          1666: 
        !          1667:        default:
        !          1668:            *sizeP = 0;
        !          1669:            return("Bad call to MD_ATOF()");
        !          1670:        }
        !          1671:        t = atof_ieee(input_line_pointer, type, words);
        !          1672:        if(t != NULL)
        !          1673:            input_line_pointer = t;
        !          1674: 
        !          1675:        *sizeP = prec * sizeof(LITTLENUM_TYPE);
        !          1676:        for(wordP = words; prec--; ){
        !          1677:            md_number_to_chars(litP, (long)(*wordP++), sizeof(LITTLENUM_TYPE));
        !          1678:            litP += sizeof(LITTLENUM_TYPE);
        !          1679:        }
        !          1680:        return ""; /* OK */
        !          1681: }
        !          1682: 
        !          1683: int
        !          1684: md_estimate_size_before_relax(
        !          1685: fragS *fragP,
        !          1686: int segment_type)
        !          1687: {
        !          1688:        as_warn("Relaxation should never occur");
        !          1689:        return(sizeof(long));
        !          1690: }
        !          1691: 
        !          1692: const relax_typeS md_relax_table[] = {0};
        !          1693: 
        !          1694: void
        !          1695: md_convert_frag(
        !          1696: fragS *fragP)
        !          1697: {
        !          1698:        as_warn("Relaxation should never occur");
        !          1699: }

unix.superglobalmegacorp.com

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