home *** CD-ROM | disk | FTP | other *** search
/ NeXTSTEP 3.2 (Developer) / NS_dev_3.2.iso / NextDeveloper / Source / GNU / cctools / as / m98k.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-02-05  |  42.5 KB  |  1,796 lines

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