home *** CD-ROM | disk | FTP | other *** search
/ OpenStep 4.2J (Developer) / os42jdev.iso / NextDeveloper / Source / GNU / cctools / as / m98k.c < prev    next >
C/C++ Source or Header  |  1997-01-24  |  43KB  |  1,706 lines

  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.     /*
  606.      * We are putting a machine instruction in this section so mark it as
  607.      * containg some machine instructions.
  608.      */
  609.     frchain_now->frch_section.flags |= S_ATTR_SOME_INSTRUCTIONS;
  610.  
  611.     /* if this instruction requires labels mark it for later */
  612.     switch(insn.reloc){
  613.     case NO_RELOC:
  614.         break;
  615.     case M98K_RELOC_HI16:
  616.     case M98K_RELOC_LO16:
  617.     case M98K_RELOC_HA16:
  618.     case M98K_RELOC_LO14:
  619.         fix_new(frag_now,
  620.             thisfrag - frag_now->fr_literal,
  621.             4,
  622.             insn.exp.X_add_symbol,
  623.             insn.exp.X_subtract_symbol,
  624.             insn.exp.X_add_number,
  625.             0, 0,
  626.             insn.reloc);
  627.         break;
  628.     case M98K_RELOC_BR14:
  629.         fix_new(frag_now,
  630.             thisfrag - frag_now->fr_literal,
  631.             4,
  632.             insn.exp.X_add_symbol,
  633.             insn.exp.X_subtract_symbol,
  634.             insn.exp.X_add_number,
  635.             insn.pcrel,
  636.             insn.pcrel_reloc,
  637.             insn.reloc);
  638.         break;
  639.  
  640.     case M98K_RELOC_BR24:
  641.         fix_new(frag_now,
  642.             thisfrag - frag_now->fr_literal,
  643.             4,
  644.             insn.exp.X_add_symbol,
  645.             insn.exp.X_subtract_symbol,
  646.             insn.exp.X_add_number,
  647.             insn.pcrel,
  648.             insn.pcrel_reloc,
  649.             insn.reloc);
  650.         break;
  651.     default:
  652.         as_warn("Unknown relocation type");
  653.         break;
  654.     }
  655. }
  656.  
  657. static
  658. int
  659. calcop(
  660. struct m98k_opcode *format,
  661. char *param,
  662. struct m98k_insn *insn,
  663. char *op,
  664. char prediction)
  665. {
  666.     unsigned long parcnt;
  667.  
  668.     /* initial the passed structure */
  669.     memset(insn, '\0', sizeof(struct m98k_insn));
  670.     insn->opcode = format->opcode;
  671.     insn->reloc = NO_RELOC;
  672.  
  673.     /* parse all parameters */
  674.     for(parcnt = 0; parcnt < 5 &&
  675.             format->ops[parcnt].type != NONE; parcnt++){
  676.         error_param_count = parcnt;
  677.  
  678.         switch(format->ops[parcnt].type){
  679.         case PCREL:
  680.         case BADDR:
  681.         param = parse_branch(param, insn, format, parcnt);
  682.         break;
  683.         case D:
  684.         case DS:
  685.         param = parse_displacement(param, insn, format, parcnt);
  686.         break;
  687.         case SI:
  688.         case UI:
  689.         param = parse_immediate(param, insn, format, parcnt);
  690.         break;
  691.         case GREG:
  692.         case G0REG:
  693.         param = parse_reg("r", param, insn, format, parcnt);
  694.         break;
  695.         case FREG:
  696.         param = parse_reg("f", param, insn, format, parcnt);
  697.         break;
  698.         case SGREG:
  699.         param = parse_reg("sr", param, insn, format, parcnt);
  700.         break;
  701.         case SPREG:
  702.         param = parse_spreg(param, insn, format, parcnt);
  703.         break;
  704.         case BCND:
  705.         param = parse_bcnd(param, insn, format, parcnt);
  706.         break;
  707.         case CRF:
  708.         case CRFONLY:
  709.         param = parse_crf(param, insn, format, parcnt);
  710.         break;
  711.         case NUM:
  712.         param = parse_num(param, insn, format, parcnt, 0);
  713.         break;
  714.         case NUM0:
  715.         param = parse_num(param, insn, format, parcnt, 1);
  716.         break;
  717.         case sh:
  718.         param = parse_sh(param, insn, format, parcnt);
  719.         break;
  720.         case mb:
  721.         param = parse_mb(param, insn, format, parcnt);
  722.         break;
  723.         default:
  724.         as_fatal("Unknown parameter type");
  725.         }
  726.  
  727.         /* see if parser failed or not */
  728.         if (param == NULL)
  729.         return(0);
  730.     }
  731.     if(format->ops[0].type == NONE && *param != '\0'){
  732.         error_param_message = "too many parameters";
  733.         return(0);
  734.     }
  735.  
  736.     if(IS_BRANCH_CONDITIONAL(insn->opcode)){
  737.         if(prediction != '\0'){
  738.         /*
  739.          * Set the Y_BIT assuming the displacement is non-negitive.
  740.          * If the displacement is negitive then the Y_BIT is flipped
  741.          * in md_number_to_imm().
  742.          */
  743.         if(prediction == '+')
  744.             insn->opcode |= Y_BIT;
  745.         else{ /* prediction == '-' */
  746.             if((insn->opcode & Y_BIT) != 0)
  747.             as_warn("branch prediction ('-') ignored (specified "
  748.                 "operand has prediction bit set)");
  749.             else
  750.             insn->opcode &= ~(Y_BIT);
  751.         }
  752.         }
  753.     }
  754.     else{
  755.         if(prediction != '\0')
  756.         as_warn("branch prediction ignored (instruction is not a "
  757.             "conditional branch)");
  758.     }
  759.     return(1);
  760. }
  761.  
  762. static
  763. char *
  764. parse_displacement(
  765. char *param,
  766. struct m98k_insn *insn,
  767. struct m98k_opcode *format,
  768. int parcnt)
  769. {
  770.     unsigned long val;
  771.     char *end, *saveptr, *saveparam;
  772.     segT seg;
  773.  
  774.  
  775.     if(parcnt != 1 || format->ops[2].type != G0REG)
  776.          as_fatal("internal error, bad table entry for instruction %s "
  777.               "(displacement operand not second operand or general "
  778.               "register not third operand)", format->name);
  779.  
  780.     /*
  781.      * There must be "(rX)" (where X is a number between 0-31) or "(0)"
  782.      * at the end of the parameter string.  To know out where the
  783.      * displacement expression ends determine the begining the "(rX)"
  784.      * by looking for the last '(' in the string.  The parsing of this
  785.      * trailing string will be done in another routine.
  786.      */
  787.     end = strrchr(param, '(');
  788.     if(end == NULL)
  789.         return(NULL);
  790.     *end = '\0';
  791.  
  792.     /*
  793.      * The expression may have one of the following: hi16(exp), ha16(exp),
  794.      * or lo16(exp) around the expression which determines the relocation
  795.      * type.
  796.      */
  797.     if(strncmp(param,"hi16(",5) == 0){
  798.         insn->reloc = M98K_RELOC_HI16;
  799.         param += 5;
  800.     }
  801.     else if(strncmp(param,"ha16(",5) == 0){
  802.         insn->reloc = M98K_RELOC_HA16;
  803.         param += 5;
  804.     }
  805.     else if(strncmp(param,"lo16(",5) == 0){
  806.         if(format->ops[parcnt].type == DS)
  807.         insn->reloc = M98K_RELOC_LO14;
  808.         else
  809.         insn->reloc = M98K_RELOC_LO16;
  810.         param += 5;
  811.     }
  812.  
  813.     saveptr = input_line_pointer;
  814.     input_line_pointer = param;
  815.  
  816.     seg = expression(&insn->exp);
  817.     try_to_make_absolute(&insn->exp);
  818.     seg = insn->exp.X_seg;
  819.  
  820.     saveparam = input_line_pointer;
  821.     input_line_pointer = saveptr;
  822.     *end = '(';
  823.  
  824.     if(insn->reloc != NO_RELOC){
  825.         if(*saveparam != ')' || ++saveparam != end)
  826.         return(NULL);
  827.     }
  828.     else{
  829.         if(saveparam != end)
  830.         return(NULL);
  831.         val = insn->exp.X_add_number;
  832.         if(seg != SEG_ABSOLUTE){
  833.         error_param_message = "Parameter error: expression must be "
  834.                       "absolute (parameter %lu)";
  835.         return(NULL);
  836.         }
  837.         if(val & 0x8000){
  838.         if((val & 0xffff0000) != 0xffff0000){
  839.             error_param_message = "Parameter error: expression out of "
  840.                       "range (parameter %lu)";
  841.             return(NULL);
  842.         }
  843.         val = val & 0xffff;
  844.         }
  845.         else{
  846.         if((val & 0xffff0000) != 0){
  847.             error_param_message = "Parameter error: expression out of "
  848.                       "range (parameter %lu)";
  849.             return(NULL);
  850.         }
  851.         }
  852.         if(format->ops[parcnt].type == DS){
  853.         if((val & 0x3) != 0){
  854.             error_param_message = "Parameter error: expression must be "
  855.                       "a multiple of 4 (parameter %lu)";
  856.             return(NULL);
  857.         }
  858.         val >>= 2;
  859.         }
  860.         insn->opcode |= val << format->ops[parcnt].offset;
  861.     }
  862.     return(saveparam);
  863. }
  864.  
  865. static
  866. char *
  867. parse_immediate(
  868. char *param,
  869. struct m98k_insn *insn,
  870. struct m98k_opcode *format,
  871. int parcnt)
  872. {
  873.     unsigned long val;
  874.     char *saveptr, *saveparam;
  875.     segT seg;
  876.  
  877.     /*
  878.      * The expression may have one of the following: hi16(exp), ha16(exp),
  879.      * or lo16(exp) around the expression which determines the relocation
  880.      * type.
  881.      */
  882.     if(strncmp(param,"hi16(",5) == 0){
  883.         insn->reloc = M98K_RELOC_HI16;
  884.         param += 5;
  885.     }
  886.     else if(strncmp(param,"ha16(",5) == 0){
  887.         insn->reloc = M98K_RELOC_HA16;
  888.         param += 5;
  889.     }
  890.     else if(strncmp(param,"lo16(",5) == 0){
  891.         if(format->ops[parcnt].type == DS)
  892.         insn->reloc = M98K_RELOC_LO14;
  893.         else
  894.         insn->reloc = M98K_RELOC_LO16;
  895.         param += 5;
  896.     }
  897.  
  898.     saveptr = input_line_pointer;
  899.     input_line_pointer = param;
  900.  
  901.     seg = expression(&insn->exp);
  902.     try_to_make_absolute(&insn->exp);
  903.     seg = insn->exp.X_seg;
  904.  
  905.     saveparam = input_line_pointer;
  906.     input_line_pointer = saveptr;
  907.  
  908.     if(insn->reloc != NO_RELOC){
  909.         if(*saveparam != ')')
  910.         return(NULL);
  911.         saveparam++;
  912.         if(*saveparam == '\0'){
  913.         if(parcnt == 4 || format->ops[parcnt+1].type == NONE)
  914.             return(saveparam);
  915.         else
  916.             return(NULL);
  917.         }
  918.         else if(*saveparam == ','){
  919.         if(parcnt != 4 && format->ops[parcnt+1].type != NONE)
  920.             return(saveparam+1);
  921.         else
  922.             return(NULL);
  923.         }
  924.         else
  925.         return(NULL);
  926.     }
  927.     else{
  928.         val = insn->exp.X_add_number;
  929.         if(seg != SEG_ABSOLUTE){
  930.         error_param_message = "Parameter error: expression must be "
  931.                       "absolute (parameter %lu)";
  932.         return(NULL);
  933.         }
  934.         if(format->ops[parcnt].type == SI){
  935.         if(val & 0x8000){
  936.             if((val & 0xffff0000) != 0xffff0000){
  937.             error_param_message = "Parameter error: expression out "
  938.                           "of range (parameter %lu)";
  939.             return(NULL);
  940.             }
  941.             val = val & 0xffff;
  942.         }
  943.         else{
  944.             if((val & 0xffff0000) != 0){
  945.             error_param_message = "Parameter error: expression out "
  946.                           "of range (parameter %lu)";
  947.             return(NULL);
  948.             }
  949.         }
  950.         }
  951.         else{
  952.         if((val & 0xffff0000) != 0){
  953.             error_param_message = "Parameter error: expression out "
  954.                       "of range (parameter %lu)";
  955.             return(NULL);
  956.         }
  957.         }
  958.         if(*saveparam == '\0'){
  959.         if(parcnt == 4 || format->ops[parcnt+1].type == NONE){
  960.             insn->opcode |= val << format->ops[parcnt].offset;
  961.             return(saveparam);
  962.         }
  963.         else
  964.             return(NULL);
  965.         }
  966.         else if(*saveparam == ','){
  967.         if(parcnt != 4 && format->ops[parcnt+1].type != NONE){
  968.             insn->opcode |= val << format->ops[parcnt].offset;
  969.             return(saveparam+1);
  970.         }
  971.         else
  972.             return(NULL);
  973.         }
  974.         else
  975.         return(NULL);
  976.     }
  977.     return(saveparam);
  978. }
  979.  
  980. static
  981. char *
  982. parse_branch(
  983. char *param,
  984. struct m98k_insn *insn,
  985. struct m98k_opcode *format,
  986. int parcnt)
  987. {
  988.     char *saveptr, *saveparam;
  989.     segT seg;
  990.  
  991.     saveptr = input_line_pointer;
  992.     input_line_pointer = param;
  993.  
  994.     seg = expression(&insn->exp);
  995.     try_to_make_absolute(&insn->exp);
  996.     seg = insn->exp.X_seg;
  997.  
  998.     saveparam = input_line_pointer;
  999.     input_line_pointer = saveptr;
  1000.  
  1001.     insn->pcrel = 0;
  1002.     insn->pcrel_reloc = 0;
  1003.     if(format->ops[parcnt].type == PCREL){
  1004.         /*
  1005.          * The NeXT linker has the ability to scatter blocks of
  1006.          * sections between labels.  This requires that brances to
  1007.          * labels that survive to the link phase must be able to
  1008.          * be relocated.
  1009.          */
  1010.         if(insn->exp.X_add_symbol != NULL &&
  1011.            (insn->exp.X_add_symbol->sy_name[0] != 'L' || flagseen ['L']))
  1012.         insn->pcrel_reloc = 1;
  1013.         else
  1014.         insn->pcrel_reloc = 0;
  1015.         insn->pcrel = 1;
  1016.     }
  1017.     switch(format->ops[parcnt].width){
  1018.     case 14:
  1019.         insn->reloc = M98K_RELOC_BR14;
  1020.         break;
  1021.     case 24:
  1022.         insn->reloc = M98K_RELOC_BR24;
  1023.         break;
  1024.     default:
  1025.         as_fatal("Unknown branch instruction width %d",
  1026.             format->ops[parcnt].width);
  1027.         break;
  1028.     }
  1029.     return(saveparam);
  1030. }
  1031.  
  1032. static
  1033. char *
  1034. parse_reg(
  1035. char *reg_name,
  1036. char *param,
  1037. struct m98k_insn *insn,
  1038. struct m98k_opcode *format,
  1039. unsigned long parcnt)
  1040. {
  1041.     unsigned long val, d;
  1042.  
  1043.     d = 0;
  1044.     if(*param == '(' && parcnt == 2 &&
  1045.        (format->ops[1].type == D || format->ops[1].type == DS)){
  1046.         d = 1;
  1047.         param++;
  1048.     }
  1049.  
  1050.     if(format->ops[parcnt].type == G0REG && *param == '0'){
  1051.         val = 0;
  1052.         param++;
  1053.     }
  1054.     else{
  1055.         val = 0;
  1056.         while(*reg_name){
  1057.         if(*param++ != *reg_name++)
  1058.             return(NULL);
  1059.         }
  1060.         if(!isdigit(*param))
  1061.         return(NULL);
  1062.  
  1063.         while(isdigit(*param))
  1064.         if((val = val * 10 + *param++ - '0') >=
  1065.            1 << format->ops[parcnt].width)
  1066.         return(NULL);
  1067.  
  1068.         if(format->ops[parcnt].type == G0REG && val == 0){
  1069.         error_param_message = "Parameter error: r0 not allowed "
  1070.                       "for parameter %lu (code as 0 not r0)";
  1071.         return(NULL);
  1072.         }
  1073.     }
  1074.  
  1075.     if(*param == '\0'){
  1076.         if(parcnt == 4 || format->ops[parcnt+1].type == NONE){
  1077.         insn->opcode |= val << format->ops[parcnt].offset;
  1078.         return(param);
  1079.         }
  1080.         else
  1081.         return(NULL);
  1082.     }
  1083.     else if(*param == ','){
  1084.         if(parcnt != 4 && format->ops[parcnt+1].type != NONE){
  1085.         insn->opcode |= val << format->ops[parcnt].offset;
  1086.         return(param+1);
  1087.         }
  1088.         else
  1089.         return(NULL);
  1090.     }
  1091.     else if(d == 1 && *param == ')' && param[1] == '\0'){
  1092.         if(parcnt == 4 || format->ops[parcnt+1].type == NONE){
  1093.         insn->opcode |= val << format->ops[parcnt].offset;
  1094.         return(++param);
  1095.         }
  1096.         else
  1097.         return(NULL);
  1098.     }
  1099.     return(NULL);
  1100. }
  1101.  
  1102. static
  1103. char *
  1104. parse_spreg(
  1105. char *param,
  1106. struct m98k_insn *insn,
  1107. struct m98k_opcode *format,
  1108. unsigned long parcnt)
  1109. {
  1110.     int val;
  1111.     unsigned long i;
  1112.     char *saveptr, save_c;
  1113.     expressionS exp;
  1114.     segT seg;
  1115.  
  1116.     saveptr = input_line_pointer;
  1117.     input_line_pointer = param;
  1118.     while(*param != ',' && *param != '\0')
  1119.         param++;
  1120.     save_c = *param;
  1121.     *param = '\0';
  1122.  
  1123.     seg = SEG_ABSOLUTE;
  1124.     val = 0;
  1125.     for(i = 0; *special_registers[i].name != '\0'; i++){
  1126.         if(strcmp(input_line_pointer, special_registers[i].name) == 0){
  1127.         val = special_registers[i].number;
  1128.         break;
  1129.         }
  1130.     }
  1131.     if(*special_registers[i].name == '\0'){
  1132.         seg = expression(&exp);
  1133.         try_to_make_absolute(&exp);
  1134.         seg = exp.X_seg;
  1135.         val = exp.X_add_number;
  1136.     }
  1137.     *param = save_c;
  1138.     input_line_pointer = saveptr;
  1139.  
  1140.     if(seg != SEG_ABSOLUTE){
  1141.         error_param_message = "Parameter error: expression must be "
  1142.                   "absolute (parameter %lu)";
  1143.         return(NULL);
  1144.     }
  1145.     if(val > 1024 || val < 0){
  1146.         error_param_message = "Parameter error: expression out "
  1147.                   "of range (parameter %lu)";
  1148.         return(NULL);
  1149.     }
  1150.  
  1151.     val = ((val & 0x1f) << 5) | ((val >> 5) & 0x1f);
  1152.  
  1153.     if(*param == '\0'){
  1154.         if(parcnt == 4 || format->ops[parcnt+1].type == NONE){
  1155.         insn->opcode |= val << format->ops[parcnt].offset;
  1156.         return(param);
  1157.         }
  1158.         else
  1159.         return(NULL);
  1160.     }
  1161.     else if(*param == ','){
  1162.         if(parcnt != 4 && format->ops[parcnt+1].type != NONE){
  1163.         insn->opcode |= val << format->ops[parcnt].offset;
  1164.         return(param+1);
  1165.         }
  1166.         else
  1167.         return(NULL);
  1168.     }
  1169.     return(NULL);
  1170. }
  1171.  
  1172. static
  1173. char *
  1174. parse_bcnd(
  1175. char *param,
  1176. struct m98k_insn *insn,
  1177. struct m98k_opcode *format,
  1178. unsigned long parcnt)
  1179. {
  1180.     int val;
  1181.     unsigned long i, j;
  1182.     char *saveptr, save_c, *plus, save_plus;
  1183.     expressionS exp;
  1184.     segT seg;
  1185.  
  1186.     saveptr = input_line_pointer;
  1187.     input_line_pointer = param;
  1188.     while(*param != ',' && *param != '\0')
  1189.         param++;
  1190.     save_c = *param;
  1191.     *param = '\0';
  1192.  
  1193.     /*
  1194.      * look for "[CR_field+]condition_symbol".
  1195.      */
  1196.     val = -1;
  1197.     for(plus = input_line_pointer; *plus != '+' && *plus != '\0'; plus++)
  1198.         ;
  1199.     if(*plus == '+'){
  1200.         save_plus = *plus;
  1201.         *plus = '\0';
  1202.         for(i = 0; *CR_fields[i].name != '\0'; i++)
  1203.         if(strcmp(input_line_pointer, CR_fields[i].name) == 0)
  1204.             break;
  1205.         *plus = save_plus;
  1206.         if(*CR_fields[i].name != '\0'){
  1207.         for(j = 0; *condition_symbols[j].name != '\0'; j++)
  1208.             if(strcmp(plus+1, condition_symbols[j].name) == 0)
  1209.             break;
  1210.         if(*condition_symbols[j].name != '\0'){
  1211.             val = CR_fields[i].value + condition_symbols[j].value;
  1212.         }
  1213.         }
  1214.     }
  1215.     else{
  1216.         for(i = 0; *condition_symbols[i].name != '\0'; i++)
  1217.         if(strcmp(input_line_pointer, condition_symbols[i].name) == 0)
  1218.             break;
  1219.         if(*condition_symbols[i].name != '\0')
  1220.         val = condition_symbols[i].value;
  1221.     }
  1222.     if(val == -1){
  1223.         seg = expression(&exp);
  1224.         try_to_make_absolute(&exp);
  1225.         seg = exp.X_seg;
  1226.         val = exp.X_add_number;
  1227.         if(seg != SEG_ABSOLUTE){
  1228.         error_param_message = "Parameter error: expression must be "
  1229.                       "absolute (parameter %lu)";
  1230.         *param = save_c;
  1231.         input_line_pointer = saveptr;
  1232.         return(NULL);
  1233.         }
  1234.         if(val >= (1 << format->ops[parcnt].width) || val < 0){
  1235.         error_param_message = "Parameter error: expression out "
  1236.                       "of range (parameter %lu)";
  1237.         *param = save_c;
  1238.         input_line_pointer = saveptr;
  1239.         return(NULL);
  1240.         }
  1241.     }
  1242.  
  1243.     *param = save_c;
  1244.     input_line_pointer = saveptr;
  1245.  
  1246.  
  1247.     if(*param == '\0'){
  1248.         if(parcnt == 4 || format->ops[parcnt+1].type == NONE){
  1249.         insn->opcode |= val << format->ops[parcnt].offset;
  1250.         return(param);
  1251.         }
  1252.         else
  1253.         return(NULL);
  1254.     }
  1255.     else if(*param == ','){
  1256.         if(parcnt != 4 && format->ops[parcnt+1].type != NONE){
  1257.         insn->opcode |= val << format->ops[parcnt].offset;
  1258.         return(param+1);
  1259.         }
  1260.         else
  1261.         return(NULL);
  1262.     }
  1263.     return(NULL);
  1264.  
  1265. }
  1266.  
  1267. static
  1268. char *
  1269. parse_crf(
  1270. char *param,
  1271. struct m98k_insn *insn,
  1272. struct m98k_opcode *format,
  1273. unsigned long parcnt)
  1274. {
  1275.     int val;
  1276.     unsigned long i;
  1277.     char *saveptr, save_c;
  1278.     expressionS exp;
  1279.     segT seg;
  1280.  
  1281.     saveptr = input_line_pointer;
  1282.     input_line_pointer = param;
  1283.     while(*param != ',' && *param != '\0')
  1284.         param++;
  1285.     save_c = *param;
  1286.     *param = '\0';
  1287.     val = -1;
  1288.     for(i = 0; *CR_fields[i].name != '\0'; i++){
  1289.         if(strcmp(input_line_pointer, CR_fields[i].name) == 0){
  1290.         val = CR_fields[i].value;
  1291.         break;
  1292.         }
  1293.     }
  1294.     if(val == -1){
  1295.         if(format->ops[parcnt].type == CRFONLY){
  1296.         *param = save_c;
  1297.         input_line_pointer = saveptr;
  1298.         return(NULL);
  1299.         }
  1300.         seg = expression(&exp);
  1301.         try_to_make_absolute(&exp);
  1302.         seg = exp.X_seg;
  1303.         val = exp.X_add_number;
  1304.         if(seg != SEG_ABSOLUTE){
  1305.         error_param_message = "Parameter error: expression must be "
  1306.                       "absolute (parameter %lu)";
  1307.         *param = save_c;
  1308.         input_line_pointer = saveptr;
  1309.         return(NULL);
  1310.         }
  1311.         if(val >= (1 << format->ops[parcnt].width) || val < 0){
  1312.         error_param_message = "Parameter error: expression out "
  1313.                       "of range (parameter %lu)";
  1314.         *param = save_c;
  1315.         input_line_pointer = saveptr;
  1316.         return(NULL);
  1317.         }
  1318.     }
  1319.     *param = save_c;
  1320.     input_line_pointer = saveptr;
  1321.  
  1322.     if(*param == '\0'){
  1323.         if(parcnt == 4 || format->ops[parcnt+1].type == NONE){
  1324.         insn->opcode |= val << format->ops[parcnt].offset;
  1325.         return(param);
  1326.         }
  1327.         else
  1328.         return(NULL);
  1329.     }
  1330.     else if(*param == ','){
  1331.         if(parcnt != 4 && format->ops[parcnt+1].type != NONE){
  1332.         insn->opcode |= val << format->ops[parcnt].offset;
  1333.         return(param+1);
  1334.         }
  1335.         else
  1336.         return(NULL);
  1337.     }
  1338.     return(NULL);
  1339. }
  1340.  
  1341. static
  1342. char *
  1343. parse_num(
  1344. char *param,
  1345. struct m98k_insn *insn,
  1346. struct m98k_opcode *format,
  1347. unsigned long parcnt,
  1348. long max_width_zero)
  1349. {
  1350.     int val;
  1351.     char *saveptr, save_c;
  1352.     expressionS exp;
  1353.     segT seg;
  1354.  
  1355.     saveptr = input_line_pointer;
  1356.     input_line_pointer = param;
  1357.     while(*param != ',' && *param != '\0')
  1358.         param++;
  1359.     save_c = *param;
  1360.     *param = '\0';
  1361.     seg = expression(&exp);
  1362.     try_to_make_absolute(&exp);
  1363.     seg = exp.X_seg;
  1364.     *param = save_c;
  1365.     input_line_pointer = saveptr;
  1366.  
  1367.     val = exp.X_add_number;
  1368.     if(seg != SEG_ABSOLUTE){
  1369.         error_param_message = "Parameter error: expression must be "
  1370.                   "absolute (parameter %lu)";
  1371.         return(NULL);
  1372.     }
  1373.     if(max_width_zero){
  1374.         if(val == (1 << format->ops[parcnt].width))
  1375.         val = 0;
  1376.     }
  1377.     if(val >= (1 << format->ops[parcnt].width) || val < 0){
  1378.         error_param_message = "Parameter error: expression out "
  1379.                   "of range (parameter %lu)";
  1380.         return(NULL);
  1381.     }
  1382.  
  1383.     if(*param == '\0'){
  1384.         if(parcnt == 4 || format->ops[parcnt+1].type == NONE){
  1385.         insn->opcode |= val << format->ops[parcnt].offset;
  1386.         return(param);
  1387.         }
  1388.         else
  1389.         return(NULL);
  1390.     }
  1391.     else if(*param == ','){
  1392.         if(parcnt != 4 && format->ops[parcnt+1].type != NONE){
  1393.         insn->opcode |= val << format->ops[parcnt].offset;
  1394.         return(param+1);
  1395.         }
  1396.         else
  1397.         return(NULL);
  1398.     }
  1399.     return(NULL);
  1400.  
  1401. }
  1402.  
  1403. static
  1404. char *
  1405. parse_sh(
  1406. char *param,
  1407. struct m98k_insn *insn,
  1408. struct m98k_opcode *format,
  1409. unsigned long parcnt)
  1410. {
  1411.     int val;
  1412.     char *saveptr, save_c;
  1413.     expressionS exp;
  1414.     segT seg;
  1415.  
  1416.     saveptr = input_line_pointer;
  1417.     input_line_pointer = param;
  1418.     while(*param != ',' && *param != '\0')
  1419.         param++;
  1420.     save_c = *param;
  1421.     *param = '\0';
  1422.     seg = expression(&exp);
  1423.     try_to_make_absolute(&exp);
  1424.     seg = exp.X_seg;
  1425.     *param = save_c;
  1426.     input_line_pointer = saveptr;
  1427.  
  1428.     val = exp.X_add_number;
  1429.     if(seg != SEG_ABSOLUTE){
  1430.         error_param_message = "Parameter error: expression must be "
  1431.                   "absolute (parameter %lu)";
  1432.         return(NULL);
  1433.     }
  1434.     if(val == 64)
  1435.         val = 0;
  1436.     if(val >= 64 || val < 0){
  1437.         error_param_message = "Parameter error: expression out "
  1438.                   "of range (parameter %lu)";
  1439.         return(NULL);
  1440.     }
  1441.  
  1442.     if(*param == '\0'){
  1443.         if(parcnt == 4 || format->ops[parcnt+1].type == NONE){
  1444.         insn->opcode |= (val & 0x1f) << 11;
  1445.         insn->opcode |= ((val >> 5) & 0x1) << 1;
  1446.         return(param);
  1447.         }
  1448.         else
  1449.         return(NULL);
  1450.     }
  1451.     else if(*param == ','){
  1452.         if(parcnt != 4 && format->ops[parcnt+1].type != NONE){
  1453.         insn->opcode |= (val & 0x1f) << 11;
  1454.         insn->opcode |= ((val >> 5) & 0x1) << 1;
  1455.         return(param+1);
  1456.         }
  1457.         else
  1458.         return(NULL);
  1459.     }
  1460.     return(NULL);
  1461.  
  1462. }
  1463.  
  1464. static
  1465. char *
  1466. parse_mb(
  1467. char *param,
  1468. struct m98k_insn *insn,
  1469. struct m98k_opcode *format,
  1470. unsigned long parcnt)
  1471. {
  1472.     int val;
  1473.     char *saveptr, save_c;
  1474.     expressionS exp;
  1475.     segT seg;
  1476.  
  1477.     saveptr = input_line_pointer;
  1478.     input_line_pointer = param;
  1479.     while(*param != ',' && *param != '\0')
  1480.         param++;
  1481.     save_c = *param;
  1482.     *param = '\0';
  1483.     seg = expression(&exp);
  1484.     try_to_make_absolute(&exp);
  1485.     seg = exp.X_seg;
  1486.     *param = save_c;
  1487.     input_line_pointer = saveptr;
  1488.  
  1489.     val = exp.X_add_number;
  1490.     if(seg != SEG_ABSOLUTE){
  1491.         error_param_message = "Parameter error: expression must be "
  1492.                   "absolute (parameter %lu)";
  1493.         return(NULL);
  1494.     }
  1495.     if(val > 64 || val < 0){
  1496.         error_param_message = "Parameter error: expression out "
  1497.                   "of range (parameter %lu)";
  1498.         return(NULL);
  1499.     }
  1500.  
  1501.     if(*param == '\0'){
  1502.         if(parcnt == 4 || format->ops[parcnt+1].type == NONE){
  1503.         insn->opcode |= (val & 0x1f) << 6;
  1504.         insn->opcode |= ((val >> 5) & 0x1) << 5;
  1505.         return(param);
  1506.         }
  1507.         else
  1508.         return(NULL);
  1509.     }
  1510.     else if(*param == ','){
  1511.         if(parcnt != 4 && format->ops[parcnt+1].type != NONE){
  1512.         insn->opcode |= (val & 0x1f) << 6;
  1513.         insn->opcode |= ((val >> 5) & 0x1) << 5;
  1514.         return(param+1);
  1515.         }
  1516.         else
  1517.         return(NULL);
  1518.     }
  1519.     return(NULL);
  1520.  
  1521. }
  1522.  
  1523. /*
  1524.  * md_number_to_chars() is the target machine dependent routine that puts out
  1525.  * a binary value of size 4, 2, or 1 bytes into the specified buffer.  This is
  1526.  * done in the target machine's byte sex.  In this case the byte order is
  1527.  * big endian.
  1528.  */
  1529. void
  1530. md_number_to_chars(
  1531. char *buf,
  1532. long val,
  1533. int nbytes)
  1534. {
  1535.     switch(nbytes){
  1536.     case 4:
  1537.         *buf++ = val >> 24;
  1538.         *buf++ = val >> 16;
  1539.     case 2:
  1540.         *buf++ = val >> 8;
  1541.     case 1:
  1542.         *buf = val;
  1543.         break;
  1544.  
  1545.     default:
  1546.         abort();
  1547.     }
  1548. }
  1549.  
  1550. /*
  1551.  * md_number_to_imm() is the target machine dependent routine that puts out
  1552.  * a binary value of size 4, 2, or 1 bytes into the specified buffer with
  1553.  * reguard to a possible relocation entry (the fixP->fx_r_type field in the fixS
  1554.  * structure pointed to by fixP) for the section with the ordinal nsect.  This
  1555.  * is done in the target machine's byte sex using it's relocation types.
  1556.  * In this case the byte order is big endian.
  1557.  */
  1558. void
  1559. md_number_to_imm(
  1560. unsigned char *buf,
  1561. long val,
  1562. int nbytes,
  1563. fixS *fixP,
  1564. int nsect)
  1565. {
  1566.     unsigned long opcode;
  1567.  
  1568.     if(fixP->fx_r_type == NO_RELOC ||
  1569.        fixP->fx_r_type == M98K_RELOC_VANILLA){
  1570.         switch(nbytes){
  1571.         case 4:
  1572.         *buf++ = val >> 24;
  1573.         *buf++ = val >> 16;
  1574.         case 2:
  1575.         *buf++ = val >> 8;
  1576.         case 1:
  1577.         *buf = val;
  1578.         break;
  1579.  
  1580.         default:
  1581.         abort();
  1582.         }
  1583.         return;
  1584.     }
  1585.     switch(fixP->fx_r_type){
  1586.     case M98K_RELOC_HI16:
  1587.         buf[2] = val >> 24;
  1588.         buf[3] = val >> 16;
  1589.         break;
  1590.  
  1591.     case M98K_RELOC_LO16:
  1592.         buf[2] = val >> 8;
  1593.         buf[3] = val;
  1594.         break;
  1595.  
  1596.     case M98K_RELOC_HA16:
  1597.         val += 0x00008000;
  1598.         buf[2] = val >> 24;
  1599.         buf[3] = val >> 16;
  1600.         break;
  1601.  
  1602.     case M98K_RELOC_LO14:
  1603.         buf[2] = val >> 8;
  1604.         buf[3] = val & 0xfc;
  1605.         break;
  1606.  
  1607.     case M98K_RELOC_BR14:
  1608.         if((val & 0x00008000) != 0){
  1609.         opcode = buf[0] << 24 | buf[1] << 16 | buf[2] << 8 | buf[3];
  1610.         if(((opcode) & 0x03e00000) != 0x02800000){
  1611.             opcode ^= Y_BIT;
  1612.             buf[0] = opcode >> 24;
  1613.             buf[1] = opcode >> 16;
  1614.             buf[2] = opcode >> 8;
  1615.             buf[3] = opcode;
  1616.         }
  1617.         }
  1618.         if(fixP->fx_pcrel)
  1619.         val += 4;
  1620.         buf[2] = val >> 8;
  1621.         buf[3] |= val & 0xfc;
  1622.         break;
  1623.  
  1624.     case M98K_RELOC_BR24:
  1625.         if(fixP->fx_pcrel)
  1626.         val += 4;
  1627.         buf[0] |= (val >> 24) & 0x03;
  1628.         buf[1] = val >> 16;
  1629.         buf[2] = val >> 8;
  1630.         buf[3] |= val & 0xfc;
  1631.         break;
  1632.  
  1633.     default:
  1634.         as_warn("Bad relocation type");
  1635.         break;
  1636.     }
  1637. }
  1638.  
  1639. /*
  1640.  * md_atof() turns a string pointed to by input_line_pointer into a floating
  1641.  * point constant of type type, and store the appropriate bytes in *litP.
  1642.  * The number of LITTLENUMS emitted is stored indirectly through *sizeP.
  1643.  * An error message is returned, or a string containg only a '\0' for OK.
  1644.  * For this machine only IEEE single and IEEE double floating-point formats
  1645.  * are allowed.
  1646.  */
  1647. char *
  1648. md_atof(
  1649. int type,
  1650. char *litP,
  1651. int *sizeP)
  1652. {
  1653.     int    prec;
  1654.     LITTLENUM_TYPE words[6];
  1655.     LITTLENUM_TYPE *wordP;
  1656.     char *t;
  1657.  
  1658.     switch(type){
  1659.     case 'f':
  1660.     case 'F':
  1661.     case 's':
  1662.     case 'S':
  1663.         prec = 2;
  1664.         break;
  1665.  
  1666.     case 'd':
  1667.     case 'D':
  1668.     case 'r':
  1669.     case 'R':
  1670.         prec = 4;
  1671.         break;
  1672.  
  1673.     default:
  1674.         *sizeP = 0;
  1675.         return("Bad call to MD_ATOF()");
  1676.     }
  1677.     t = atof_ieee(input_line_pointer, type, words);
  1678.     if(t != NULL)
  1679.         input_line_pointer = t;
  1680.  
  1681.     *sizeP = prec * sizeof(LITTLENUM_TYPE);
  1682.     for(wordP = words; prec--; ){
  1683.         md_number_to_chars(litP, (long)(*wordP++), sizeof(LITTLENUM_TYPE));
  1684.         litP += sizeof(LITTLENUM_TYPE);
  1685.     }
  1686.     return ""; /* OK */
  1687. }
  1688.  
  1689. int
  1690. md_estimate_size_before_relax(
  1691. fragS *fragP,
  1692. int segment_type)
  1693. {
  1694.     as_warn("Relaxation should never occur");
  1695.     return(sizeof(long));
  1696. }
  1697.  
  1698. const relax_typeS md_relax_table[] = { {0} };
  1699.  
  1700. void
  1701. md_convert_frag(
  1702. fragS *fragP)
  1703. {
  1704.     as_warn("Relaxation should never occur");
  1705. }
  1706.