Home | History | Annotate | Download | only in config
      1 /* tc-score.c -- Assembler for Score
      2    Copyright (C) 2006-2014 Free Software Foundation, Inc.
      3    Contributed by:
      4    Brain.lin (brain.lin (at) sunplusct.com)
      5    Mei Ligang (ligang (at) sunnorth.com.cn)
      6    Pei-Lin Tsai (pltsai (at) sunplus.com)
      7 
      8    This file is part of GAS, the GNU Assembler.
      9 
     10    GAS is free software; you can redistribute it and/or modify
     11    it under the terms of the GNU General Public License as published by
     12    the Free Software Foundation; either version 3, or (at your option)
     13    any later version.
     14 
     15    GAS is distributed in the hope that it will be useful,
     16    but WITHOUT ANY WARRANTY; without even the implied warranty of
     17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     18    GNU General Public License for more details.
     19 
     20    You should have received a copy of the GNU General Public License
     21    along with GAS; see the file COPYING.  If not, write to the Free
     22    Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
     23    02110-1301, USA.  */
     24 
     25 #include "tc-score7.c"
     26 
     27 static void s3_s_score_bss (int ignore ATTRIBUTE_UNUSED);
     28 static void s3_s_score_text (int ignore);
     29 static void s3_score_s_section (int ignore);
     30 static void s3_s_change_sec (int sec);
     31 static void s3_s_score_mask (int reg_type ATTRIBUTE_UNUSED);
     32 static void s3_s_score_ent (int aent);
     33 static void s3_s_score_frame (int ignore ATTRIBUTE_UNUSED);
     34 static void s3_s_score_end (int x ATTRIBUTE_UNUSED);
     35 static void s3_s_score_set (int x ATTRIBUTE_UNUSED);
     36 static void s3_s_score_cpload (int ignore ATTRIBUTE_UNUSED);
     37 static void s3_s_score_cprestore (int ignore ATTRIBUTE_UNUSED);
     38 static void s3_s_score_gpword (int ignore ATTRIBUTE_UNUSED);
     39 static void s3_s_score_cpadd (int ignore ATTRIBUTE_UNUSED);
     40 static void s3_s_score_lcomm (int bytes_p);
     41 
     42 static void s_score_bss (int ignore ATTRIBUTE_UNUSED);
     43 static void s_score_text (int ignore);
     44 static void s_section (int ignore);
     45 static void s_change_sec (int sec);
     46 static void s_score_mask (int reg_type ATTRIBUTE_UNUSED);
     47 static void s_score_ent (int aent);
     48 static void s_score_frame (int ignore ATTRIBUTE_UNUSED);
     49 static void s_score_end (int x ATTRIBUTE_UNUSED);
     50 static void s_score_set (int x ATTRIBUTE_UNUSED);
     51 static void s_score_cpload (int ignore ATTRIBUTE_UNUSED);
     52 static void s_score_cprestore (int ignore ATTRIBUTE_UNUSED);
     53 static void s_score_gpword (int ignore ATTRIBUTE_UNUSED);
     54 static void s_score_cpadd (int ignore ATTRIBUTE_UNUSED);
     55 static void s_score_lcomm (int bytes_p);
     56 
     57 /* s3: hooks.  */
     58 static void s3_md_number_to_chars (char *buf, valueT val, int n);
     59 static valueT s3_md_chars_to_number (char *buf, int n);
     60 static void s3_assemble (char *str);
     61 static void s3_operand (expressionS *);
     62 static void s3_begin (void);
     63 static void s3_number_to_chars (char *buf, valueT val, int n);
     64 static char *s3_atof (int type, char *litP, int *sizeP);
     65 static void s3_frag_check (fragS * fragp ATTRIBUTE_UNUSED);
     66 static void s3_validate_fix (fixS *fixP);
     67 static int s3_force_relocation (struct fix *fixp);
     68 static bfd_boolean s3_fix_adjustable (fixS * fixP);
     69 static void s3_elf_final_processing (void);
     70 static int s3_estimate_size_before_relax (fragS * fragp, asection * sec ATTRIBUTE_UNUSED);
     71 static int s3_relax_frag (asection * sec ATTRIBUTE_UNUSED, fragS * fragp, long stretch ATTRIBUTE_UNUSED);
     72 static void s3_convert_frag (bfd * abfd ATTRIBUTE_UNUSED, segT sec ATTRIBUTE_UNUSED, fragS * fragp);
     73 static long s3_pcrel_from (fixS * fixP);
     74 static valueT s3_section_align (segT segment ATTRIBUTE_UNUSED, valueT size);
     75 static void s3_apply_fix (fixS *fixP, valueT *valP, segT seg);
     76 static arelent **s3_gen_reloc (asection * section ATTRIBUTE_UNUSED, fixS * fixp);
     77 
     78 /* s3: utils.  */
     79 static void s3_do_ldst_insn (char *);
     80 static void s3_do_crdcrscrsimm5 (char *);
     81 static void s3_do_ldst_unalign (char *);
     82 static void s3_do_ldst_atomic (char *);
     83 static void s3_do_ldst_cop (char *);
     84 static void s3_do_macro_li_rdi32 (char *);
     85 static void s3_do_macro_la_rdi32 (char *);
     86 static void s3_do_macro_rdi32hi (char *);
     87 static void s3_do_macro_rdi32lo (char *);
     88 static void s3_do_macro_mul_rdrsrs (char *);
     89 static void s3_do_macro_bcmp (char *);
     90 static void s3_do_macro_bcmpz (char *);
     91 static void s3_do_macro_ldst_label (char *);
     92 static void s3_do_branch (char *);
     93 static void s3_do_jump (char *);
     94 static void s3_do_empty (char *);
     95 static void s3_do16_int (char *);
     96 static void s3_do_rdrsrs (char *);
     97 static void s3_do_rdsi16 (char *);
     98 static void s3_do_rdrssi14 (char *);
     99 static void s3_do_sub_rdsi16 (char *);
    100 static void s3_do_sub_rdi16 (char *);
    101 static void s3_do_sub_rdrssi14 (char *);
    102 static void s3_do_rdrsi5 (char *);
    103 static void s3_do_rdrsi14 (char *);
    104 static void s3_do_rdi16 (char *);
    105 static void s3_do_ldis (char *);
    106 static void s3_do_xrsi5 (char *);
    107 static void s3_do_rdrs (char *);
    108 static void s3_do_rdxrs (char *);
    109 static void s3_do_rsrs (char *);
    110 static void s3_do_rdcrs (char *);
    111 static void s3_do_rdsrs (char *);
    112 static void s3_do_rd (char *);
    113 static void s3_do16_dsp (char *);
    114 static void s3_do16_dsp2 (char *);
    115 static void s3_do_dsp (char *);
    116 static void s3_do_dsp2 (char *);
    117 static void s3_do_dsp3 (char *);
    118 static void s3_do_rs (char *);
    119 static void s3_do_i15 (char *);
    120 static void s3_do_xi5x (char *);
    121 static void s3_do_ceinst (char *);
    122 static void s3_do_cache (char *);
    123 static void s3_do16_rdrs2 (char *);
    124 static void s3_do16_br (char *);
    125 static void s3_do16_brr (char *);
    126 static void s3_do_ltb (char *);
    127 static void s3_do16_mv_cmp (char *);
    128 static void s3_do16_addi (char *);
    129 static void s3_do16_cmpi (char *);
    130 static void s3_do16_rdi5 (char *);
    131 static void s3_do16_xi5 (char *);
    132 static void s3_do16_ldst_insn (char *);
    133 static void s3_do16_slli_srli (char *);
    134 static void s3_do16_ldiu (char *);
    135 static void s3_do16_push_pop (char *);
    136 static void s3_do16_rpush (char *);
    137 static void s3_do16_rpop (char *);
    138 static void s3_do16_branch (char *);
    139 static void s3_do_lw48 (char *);
    140 static void s3_do_sw48 (char *);
    141 static void s3_do_ldi48 (char *);
    142 static void s3_do_sdbbp48 (char *);
    143 static void s3_do_and48 (char *);
    144 static void s3_do_or48 (char *);
    145 static void s3_do_mbitclr (char *);
    146 static void s3_do_mbitset (char *);
    147 static void s3_do_rdi16_pic (char *);
    148 static void s3_do_addi_s_pic (char *);
    149 static void s3_do_addi_u_pic (char *);
    150 static void s3_do_lw_pic (char *);
    151 
    152 #define MARCH_SCORE3   "score3"
    153 #define MARCH_SCORE3D  "score3d"
    154 #define MARCH_SCORE7   "score7"
    155 #define MARCH_SCORE7D  "score7d"
    156 #define MARCH_SCORE5   "score5"
    157 #define MARCH_SCORE5U  "score5u"
    158 
    159 #define SCORE_BI_ENDIAN
    160 
    161 #ifdef SCORE_BI_ENDIAN
    162 #define OPTION_EB             (OPTION_MD_BASE + 0)
    163 #define OPTION_EL             (OPTION_MD_BASE + 1)
    164 #else
    165 #if TARGET_BYTES_BIG_ENDIAN
    166 #define OPTION_EB             (OPTION_MD_BASE + 0)
    167 #else
    168 #define OPTION_EL             (OPTION_MD_BASE + 1)
    169 #endif
    170 #endif
    171 #define OPTION_FIXDD          (OPTION_MD_BASE + 2)
    172 #define OPTION_NWARN          (OPTION_MD_BASE + 3)
    173 #define OPTION_SCORE5         (OPTION_MD_BASE + 4)
    174 #define OPTION_SCORE5U        (OPTION_MD_BASE + 5)
    175 #define OPTION_SCORE7         (OPTION_MD_BASE + 6)
    176 #define OPTION_R1             (OPTION_MD_BASE + 7)
    177 #define OPTION_O0             (OPTION_MD_BASE + 8)
    178 #define OPTION_SCORE_VERSION  (OPTION_MD_BASE + 9)
    179 #define OPTION_PIC            (OPTION_MD_BASE + 10)
    180 #define OPTION_MARCH          (OPTION_MD_BASE + 11)
    181 #define OPTION_SCORE3         (OPTION_MD_BASE + 12)
    182 
    183 /* This array holds the chars that always start a comment.  If the
    184    pre-processor is disabled, these aren't very useful.  */
    185 const char comment_chars[] = "#";
    186 const char line_comment_chars[] = "#";
    187 const char line_separator_chars[] = ";";
    188 /* Chars that can be used to separate mant from exp in floating point numbers.  */
    189 const char EXP_CHARS[] = "eE";
    190 const char FLT_CHARS[] = "rRsSfFdDxXeEpP";
    191 
    192 #ifdef OBJ_ELF
    193 /* Pre-defined "_GLOBAL_OFFSET_TABLE_"  */
    194 symbolS *GOT_symbol;
    195 #endif
    196 
    197 const pseudo_typeS md_pseudo_table[] =
    198 {
    199   {"bss", s_score_bss, 0},
    200   {"text", s_score_text, 0},
    201   {"word", cons, 4},
    202   {"long", cons, 4},
    203   {"extend", float_cons, 'x'},
    204   {"ldouble", float_cons, 'x'},
    205   {"packed", float_cons, 'p'},
    206   {"end", s_score_end, 0},
    207   {"ent", s_score_ent, 0},
    208   {"frame", s_score_frame, 0},
    209   {"rdata", s_change_sec, 'r'},
    210   {"sdata", s_change_sec, 's'},
    211   {"set", s_score_set, 0},
    212   {"mask", s_score_mask, 'R'},
    213   {"dword", cons, 8},
    214   {"lcomm", s_score_lcomm, 1},
    215   {"section", s_section, 0},
    216   {"cpload", s_score_cpload, 0},
    217   {"cprestore", s_score_cprestore, 0},
    218   {"gpword", s_score_gpword, 0},
    219   {"cpadd", s_score_cpadd, 0},
    220   {0, 0, 0}
    221 };
    222 
    223 const char *md_shortopts = "nO::g::G:";
    224 struct option md_longopts[] =
    225 {
    226 #ifdef OPTION_EB
    227   {"EB"     , no_argument, NULL, OPTION_EB},
    228 #endif
    229 #ifdef OPTION_EL
    230   {"EL"     , no_argument, NULL, OPTION_EL},
    231 #endif
    232   {"FIXDD"  , no_argument, NULL, OPTION_FIXDD},
    233   {"NWARN"  , no_argument, NULL, OPTION_NWARN},
    234   {"SCORE5" , no_argument, NULL, OPTION_SCORE5},
    235   {"SCORE5U", no_argument, NULL, OPTION_SCORE5U},
    236   {"SCORE7" , no_argument, NULL, OPTION_SCORE7},
    237   {"USE_R1" , no_argument, NULL, OPTION_R1},
    238   {"O0"     , no_argument, NULL, OPTION_O0},
    239   {"V"      , no_argument, NULL, OPTION_SCORE_VERSION},
    240   {"KPIC"   , no_argument, NULL, OPTION_PIC},
    241   {"march=" , required_argument, NULL, OPTION_MARCH},
    242   {"SCORE3" , no_argument, NULL, OPTION_SCORE3},
    243   {NULL     , no_argument, NULL, 0}
    244 };
    245 
    246 size_t md_longopts_size = sizeof (md_longopts);
    247 
    248 #define s3_GP                     28
    249 #define s3_PIC_CALL_REG           29
    250 #define s3_MAX_LITERAL_POOL_SIZE  1024
    251 #define s3_FAIL	                  0x80000000
    252 #define s3_SUCCESS                0
    253 #define s3_INSN48_SIZE            6
    254 #define s3_INSN_SIZE              4
    255 #define s3_INSN16_SIZE            2
    256 #define s3_RELAX_INST_NUM         3
    257 
    258 /* For score5u : div/mul will pop warning message, mmu/alw/asw will pop error message.  */
    259 #define s3_BAD_ARGS 	          _("bad arguments to instruction")
    260 #define s3_ERR_FOR_SCORE5U_MUL_DIV   _("div / mul are reserved instructions")
    261 #define s3_ERR_FOR_SCORE5U_MMU       _("This architecture doesn't support mmu")
    262 #define s3_ERR_FOR_SCORE5U_ATOMIC    _("This architecture doesn't support atomic instruction")
    263 #define s3_BAD_SKIP_COMMA            s3_BAD_ARGS
    264 #define s3_BAD_GARBAGE               _("garbage following instruction");
    265 
    266 #define s3_skip_whitespace(str)  while (*(str) == ' ') ++(str)
    267 
    268 /* The name of the readonly data section.  */
    269 #define s3_RDATA_SECTION_NAME (OUTPUT_FLAVOR == bfd_target_aout_flavour \
    270 			    ? ".data" \
    271 			    : OUTPUT_FLAVOR == bfd_target_ecoff_flavour \
    272 			    ? ".rdata" \
    273 			    : OUTPUT_FLAVOR == bfd_target_coff_flavour \
    274 			    ? ".rdata" \
    275 			    : OUTPUT_FLAVOR == bfd_target_elf_flavour \
    276 			    ? ".rodata" \
    277 			    : (abort (), ""))
    278 
    279 #define s3_RELAX_ENCODE(old, new, type, reloc1, reloc2, opt) \
    280   ((relax_substateT) \
    281    (((old) << 23) \
    282     | ((new) << 16) \
    283     | ((type) << 9) \
    284     | ((reloc1) << 5) \
    285     | ((reloc2) << 1) \
    286     | ((opt) ? 1 : 0)))
    287 
    288 #define s3_RELAX_OLD(i)       (((i) >> 23) & 0x7f)
    289 #define s3_RELAX_NEW(i)       (((i) >> 16) & 0x7f)
    290 #define s3_RELAX_TYPE(i)      (((i) >> 9) & 0x7f)
    291 #define s3_RELAX_RELOC1(i)    ((valueT) ((i) >> 5) & 0xf)
    292 #define s3_RELAX_RELOC2(i)    ((valueT) ((i) >> 1) & 0xf)
    293 #define s3_RELAX_OPT(i)       ((i) & 1)
    294 
    295 #define s3_SET_INSN_ERROR(s) (s3_inst.error = (s))
    296 #define s3_INSN_IS_PCE_P(s)  (strstr (str, "||") != NULL)
    297 #define s3_INSN_IS_48_P(s)  (strstr (str, "48") != NULL)
    298 #define s3_GET_INSN_CLASS(type) (s3_get_insn_class_from_type (type))
    299 #define s3_GET_INSN_SIZE(type) ((s3_GET_INSN_CLASS (type) == INSN_CLASS_16) \
    300                              ? s3_INSN16_SIZE : (s3_GET_INSN_CLASS (type) == INSN_CLASS_48) \
    301                                              ? s3_INSN48_SIZE : s3_INSN_SIZE)
    302 
    303 #define s3_MAX_LITTLENUMS 6
    304 #define s3_INSN_NAME_LEN 16
    305 
    306 /* Relax will need some padding for alignment.  */
    307 #define s3_RELAX_PAD_BYTE 3
    308 
    309 
    310 #define s3_USE_GLOBAL_POINTER_OPT 1
    311 
    312 /* Enumeration matching entries in table above.  */
    313 enum s3_score_reg_type
    314 {
    315   s3_REG_TYPE_SCORE = 0,
    316 #define s3_REG_TYPE_FIRST s3_REG_TYPE_SCORE
    317   s3_REG_TYPE_SCORE_SR = 1,
    318   s3_REG_TYPE_SCORE_CR = 2,
    319   s3_REG_TYPE_MAX = 3
    320 };
    321 
    322 enum s3_score_pic_level
    323 {
    324   s3_NO_PIC,
    325   s3_PIC
    326 };
    327 static enum s3_score_pic_level s3_score_pic = s3_NO_PIC;
    328 
    329 enum s3_insn_type_for_dependency
    330 {
    331   s3_D_mtcr,
    332   s3_D_all_insn
    333 };
    334 
    335 struct s3_insn_to_dependency
    336 {
    337   char *insn_name;
    338   enum s3_insn_type_for_dependency type;
    339 };
    340 
    341 struct s3_data_dependency
    342 {
    343   enum s3_insn_type_for_dependency pre_insn_type;
    344   char pre_reg[6];
    345   enum s3_insn_type_for_dependency cur_insn_type;
    346   char cur_reg[6];
    347   int bubblenum_7;
    348   int bubblenum_3;
    349   int warn_or_error;           /* warning - 0; error - 1  */
    350 };
    351 
    352 static const struct s3_insn_to_dependency s3_insn_to_dependency_table[] =
    353 {
    354   /* move spectial instruction.  */
    355   {"mtcr",      s3_D_mtcr},
    356 };
    357 
    358 static const struct s3_data_dependency s3_data_dependency_table[] =
    359 {
    360   /* Status regiser.  */
    361   {s3_D_mtcr, "cr0", s3_D_all_insn, "", 5, 1, 0},
    362 };
    363 
    364 /* Used to contain constructed error messages.  */
    365 static char s3_err_msg[255];
    366 
    367 static int s3_fix_data_dependency = 0;
    368 static int s3_warn_fix_data_dependency = 1;
    369 
    370 static int s3_in_my_get_expression = 0;
    371 
    372 /* Default, pop warning message when using r1.  */
    373 static int s3_nor1 = 1;
    374 
    375 /* Default will do instruction relax, -O0 will set s3_g_opt = 0.  */
    376 static unsigned int s3_g_opt = 1;
    377 
    378 /* The size of the small data section.  */
    379 static unsigned int s3_g_switch_value = 8;
    380 
    381 static segT s3_pdr_seg;
    382 
    383 struct s3_score_it
    384 {
    385   char name[s3_INSN_NAME_LEN];
    386   bfd_vma instruction;
    387   bfd_vma relax_inst;
    388   int size;
    389   int relax_size;
    390   enum score_insn_type type;
    391   char str[s3_MAX_LITERAL_POOL_SIZE];
    392   const char *error;
    393   int bwarn;
    394   char reg[s3_INSN_NAME_LEN];
    395   struct
    396   {
    397     bfd_reloc_code_real_type type;
    398     expressionS exp;
    399     int pc_rel;
    400   }reloc;
    401 };
    402 static struct s3_score_it s3_inst;
    403 
    404 typedef struct s3_proc
    405 {
    406   symbolS *isym;
    407   unsigned long reg_mask;
    408   unsigned long reg_offset;
    409   unsigned long fpreg_mask;
    410   unsigned long leaf;
    411   unsigned long frame_offset;
    412   unsigned long frame_reg;
    413   unsigned long pc_reg;
    414 } s3_procS;
    415 static s3_procS s3_cur_proc;
    416 static s3_procS *s3_cur_proc_ptr;
    417 static int s3_numprocs;
    418 
    419 
    420 /* Structure for a hash table entry for a register.  */
    421 struct s3_reg_entry
    422 {
    423   const char *name;
    424   int number;
    425 };
    426 
    427 static const struct s3_reg_entry s3_score_rn_table[] =
    428 {
    429   {"r0", 0}, {"r1", 1}, {"r2", 2}, {"r3", 3},
    430   {"r4", 4}, {"r5", 5}, {"r6", 6}, {"r7", 7},
    431   {"r8", 8}, {"r9", 9}, {"r10", 10}, {"r11", 11},
    432   {"r12", 12}, {"r13", 13}, {"r14", 14}, {"r15", 15},
    433   {"r16", 16}, {"r17", 17}, {"r18", 18}, {"r19", 19},
    434   {"r20", 20}, {"r21", 21}, {"r22", 22}, {"r23", 23},
    435   {"r24", 24}, {"r25", 25}, {"r26", 26}, {"r27", 27},
    436   {"r28", 28}, {"r29", 29}, {"r30", 30}, {"r31", 31},
    437   {NULL, 0}
    438 };
    439 
    440 static const struct s3_reg_entry s3_score_srn_table[] =
    441 {
    442   {"sr0", 0}, {"sr1", 1}, {"sr2", 2},
    443   {NULL, 0}
    444 };
    445 
    446 static const struct s3_reg_entry s3_score_crn_table[] =
    447 {
    448   {"cr0", 0}, {"cr1", 1}, {"cr2", 2}, {"cr3", 3},
    449   {"cr4", 4}, {"cr5", 5}, {"cr6", 6}, {"cr7", 7},
    450   {"cr8", 8}, {"cr9", 9}, {"cr10", 10}, {"cr11", 11},
    451   {"cr12", 12}, {"cr13", 13}, {"cr14", 14}, {"cr15", 15},
    452   {"cr16", 16}, {"cr17", 17}, {"cr18", 18}, {"cr19", 19},
    453   {"cr20", 20}, {"cr21", 21}, {"cr22", 22}, {"cr23", 23},
    454   {"cr24", 24}, {"cr25", 25}, {"cr26", 26}, {"cr27", 27},
    455   {"cr28", 28}, {"cr29", 29}, {"cr30", 30}, {"cr31", 31},
    456   {NULL, 0}
    457 };
    458 
    459 struct s3_reg_map
    460 {
    461   const struct s3_reg_entry *names;
    462   int max_regno;
    463   struct hash_control *htab;
    464   const char *expected;
    465 };
    466 
    467 static struct s3_reg_map s3_all_reg_maps[] =
    468 {
    469   {s3_score_rn_table, 31, NULL, N_("S+core register expected")},
    470   {s3_score_srn_table, 2, NULL, N_("S+core special-register expected")},
    471   {s3_score_crn_table, 31, NULL, N_("S+core co-processor register expected")},
    472 };
    473 
    474 static struct hash_control *s3_score_ops_hsh = NULL;
    475 static struct hash_control *s3_dependency_insn_hsh = NULL;
    476 
    477 
    478 struct s3_datafield_range
    479 {
    480   int data_type;
    481   int bits;
    482   int range[2];
    483 };
    484 
    485 static struct s3_datafield_range s3_score_df_range[] =
    486 {
    487   {_IMM4,             4,  {0, (1 << 4) - 1}},	        /* (     0 ~ 15   ) */
    488   {_IMM5,             5,  {0, (1 << 5) - 1}},	        /* (     0 ~ 31   ) */
    489   {_IMM8,             8,  {0, (1 << 8) - 1}},	        /* (     0 ~ 255  ) */
    490   {_IMM14,            14, {0, (1 << 14) - 1}},	        /* (     0 ~ 16383) */
    491   {_IMM15,            15, {0, (1 << 15) - 1}},	        /* (     0 ~ 32767) */
    492   {_IMM16,            16, {0, (1 << 16) - 1}},	        /* (     0 ~ 65535) */
    493   {_SIMM10,           10, {-(1 << 9), (1 << 9) - 1}},	/* (  -512 ~ 511  ) */
    494   {_SIMM12,           12, {-(1 << 11), (1 << 11) - 1}},	/* ( -2048 ~ 2047 ) */
    495   {_SIMM14,           14, {-(1 << 13), (1 << 13) - 1}},	/* ( -8192 ~ 8191 ) */
    496   {_SIMM15,           15, {-(1 << 14), (1 << 14) - 1}},	/* (-16384 ~ 16383) */
    497   {_SIMM16,           16, {-(1 << 15), (1 << 15) - 1}},	/* (-32768 ~ 32767) */
    498   {_SIMM14_NEG,       14, {-(1 << 13), (1 << 13) - 1}},	/* ( -8191 ~ 8192 ) */
    499   {_IMM16_NEG,        16, {0, (1 << 16) - 1}},	        /* (-65535 ~ 0    ) */
    500   {_SIMM16_NEG,       16, {-(1 << 15), (1 << 15) - 1}},	/* (-32768 ~ 32767) */
    501   {_IMM20,            20, {0, (1 << 20) - 1}},
    502   {_IMM25,            25, {0, (1 << 25) - 1}},
    503   {_DISP8div2,        8,  {-(1 << 8), (1 << 8) - 1}},	/* (  -256 ~ 255  ) */
    504   {_DISP11div2,       11, {0, 0}},
    505   {_DISP19div2,       19, {-(1 << 19), (1 << 19) - 1}},	/* (-524288 ~ 524287) */
    506   {_DISP24div2,       24, {0, 0}},
    507   {_VALUE,            32, {0, ((unsigned int)1 << 31) - 1}},
    508   {_VALUE_HI16,       16, {0, (1 << 16) - 1}},
    509   {_VALUE_LO16,       16, {0, (1 << 16) - 1}},
    510   {_VALUE_LDST_LO16,  16, {0, (1 << 16) - 1}},
    511   {_SIMM16_LA,        16, {-(1 << 15), (1 << 15) - 1}},	/* (-32768 ~ 32767) */
    512   {_IMM5_RSHIFT_1,    5,  {0, (1 << 6) - 1}},	        /* (     0 ~ 63   ) */
    513   {_IMM5_RSHIFT_2,    5,  {0, (1 << 7) - 1}},	        /* (     0 ~ 127  ) */
    514   {_SIMM16_LA_POS,    16, {0, (1 << 15) - 1}},	        /* (     0 ~ 32767) */
    515   {_IMM5_RANGE_8_31,  5,  {8, 31}},	                /* But for cop0 the valid data : (8 ~ 31). */
    516   {_IMM10_RSHIFT_2,   10, {-(1 << 11), (1 << 11) - 1}},	/* For ldc#, stc#. */
    517   {_SIMM10,           10, {0, (1 << 10) - 1}},	        /* ( -1024 ~ 1023 ) */
    518   {_SIMM12,           12, {0, (1 << 12) - 1}},	        /* ( -2048 ~ 2047 ) */
    519   {_SIMM14,           14, {0, (1 << 14) - 1}},          /* ( -8192 ~ 8191 ) */
    520   {_SIMM15,           15, {0, (1 << 15) - 1}},	        /* (-16384 ~ 16383) */
    521   {_SIMM16,           16, {0, (1 << 16) - 1}},	        /* (-65536 ~ 65536) */
    522   {_SIMM14_NEG,       14, {0, (1 << 16) - 1}},          /* ( -8191 ~ 8192 ) */
    523   {_IMM16_NEG,        16, {0, (1 << 16) - 1}},	        /* ( 65535 ~ 0    ) */
    524   {_SIMM16_NEG,       16, {0, (1 << 16) - 1}},	        /* ( 65535 ~ 0    ) */
    525   {_IMM20,            20, {0, (1 << 20) - 1}},	        /* (-32768 ~ 32767) */
    526   {_IMM25,            25, {0, (1 << 25) - 1}},	        /* (-32768 ~ 32767) */
    527   {_GP_IMM15,         15, {0, (1 << 15) - 1}},	        /* (     0 ~ 65535) */
    528   {_GP_IMM14,         14, {0, (1 << 14) - 1}},	        /* (     0 ~ 65535) */
    529   {_SIMM16_pic,       16, {-(1 << 15), (1 << 15) - 1}},	/* (-32768 ~ 32767) */
    530   {_IMM16_LO16_pic,   16, {0, (1 << 16) - 1}},	        /* ( 65535 ~ 0    ) */
    531   {_IMM16_pic,        16, {0, (1 << 16) - 1}},	        /* (     0 ~ 65535) */
    532   {_SIMM5,            5,  {-(1 << 4), (1 << 4) - 1}},	/* (   -16 ~ 15   ) */
    533   {_SIMM6,            6,  {-(1 << 5), (1 << 5) - 1}},	/* (   -32 ~ 31   ) */
    534   {_IMM32,            32, {0, 0xfffffff}},
    535   {_SIMM32,           32, {-0x80000000, 0x7fffffff}},
    536   {_IMM11,            11, {0, (1 << 11) - 1}},
    537 };
    538 
    539 struct s3_asm_opcode
    540 {
    541   /* Instruction name.  */
    542   const char *template_name;
    543 
    544   /* Instruction Opcode.  */
    545   bfd_vma value;
    546 
    547   /* Instruction bit mask.  */
    548   bfd_vma bitmask;
    549 
    550   /* Relax instruction opcode.  0x8000 imply no relaxation.  */
    551   bfd_vma relax_value;
    552 
    553   /* Instruction type.  */
    554   enum score_insn_type type;
    555 
    556   /* Function to call to parse args.  */
    557   void (*parms) (char *);
    558 };
    559 
    560 static const struct s3_asm_opcode s3_score_ldst_insns[] =
    561 {
    562   {"lw",        0x20000000, 0x3e000000, 0x1000,     Rd_rvalueRs_SI15,     s3_do_ldst_insn},
    563   {"lw",        0x06000000, 0x3e000007, 0x8000,     Rd_rvalueRs_preSI12,  s3_do_ldst_insn},
    564   {"lw",        0x0e000000, 0x3e000007, 0x0040,     Rd_rvalueRs_postSI12, s3_do_ldst_insn},
    565   {"lh",        0x22000000, 0x3e000000, 0x8000,     Rd_rvalueRs_SI15,     s3_do_ldst_insn},
    566   {"lh",        0x06000001, 0x3e000007, 0x8000,     Rd_rvalueRs_preSI12,  s3_do_ldst_insn},
    567   {"lh",        0x0e000001, 0x3e000007, 0x8000,     Rd_rvalueRs_postSI12, s3_do_ldst_insn},
    568   {"lhu",       0x24000000, 0x3e000000, 0x8000,     Rd_rvalueRs_SI15,     s3_do_ldst_insn},
    569   {"lhu",       0x06000002, 0x3e000007, 0x8000,     Rd_rvalueRs_preSI12,  s3_do_ldst_insn},
    570   {"lhu",       0x0e000002, 0x3e000007, 0x8000,     Rd_rvalueRs_postSI12, s3_do_ldst_insn},
    571   {"lb",        0x26000000, 0x3e000000, 0x8000,     Rd_rvalueRs_SI15,     s3_do_ldst_insn},
    572   {"lb",        0x06000003, 0x3e000007, 0x8000,     Rd_rvalueRs_preSI12,  s3_do_ldst_insn},
    573   {"lb",        0x0e000003, 0x3e000007, 0x8000,     Rd_rvalueRs_postSI12, s3_do_ldst_insn},
    574   {"sw",        0x28000000, 0x3e000000, 0x2000,     Rd_lvalueRs_SI15,     s3_do_ldst_insn},
    575   {"sw",        0x06000004, 0x3e000007, 0x0060,     Rd_lvalueRs_preSI12,  s3_do_ldst_insn},
    576   {"sw",        0x0e000004, 0x3e000007, 0x8000,     Rd_lvalueRs_postSI12, s3_do_ldst_insn},
    577   {"sh",        0x2a000000, 0x3e000000, 0x8000,     Rd_lvalueRs_SI15,     s3_do_ldst_insn},
    578   {"sh",        0x06000005, 0x3e000007, 0x8000,     Rd_lvalueRs_preSI12,  s3_do_ldst_insn},
    579   {"sh",        0x0e000005, 0x3e000007, 0x8000,     Rd_lvalueRs_postSI12, s3_do_ldst_insn},
    580   {"lbu",       0x2c000000, 0x3e000000, 0x8000,     Rd_rvalueRs_SI15,     s3_do_ldst_insn},
    581   {"lbu",       0x06000006, 0x3e000007, 0x8000,     Rd_rvalueRs_preSI12,  s3_do_ldst_insn},
    582   {"lbu",       0x0e000006, 0x3e000007, 0x8000,     Rd_rvalueRs_postSI12, s3_do_ldst_insn},
    583   {"sb",        0x2e000000, 0x3e000000, 0x8000,     Rd_lvalueRs_SI15,     s3_do_ldst_insn},
    584   {"sb",        0x06000007, 0x3e000007, 0x8000,     Rd_lvalueRs_preSI12,  s3_do_ldst_insn},
    585   {"sb",        0x0e000007, 0x3e000007, 0x8000,     Rd_lvalueRs_postSI12, s3_do_ldst_insn},
    586 };
    587 
    588 static const struct s3_asm_opcode s3_score_insns[] =
    589 {
    590   {"abs",       0x3800000a, 0x3e007fff, 0x8000,     Rd_Rs_x,              s3_do_dsp3},
    591   {"abs.s",     0x3800004b, 0x3e007fff, 0x8000,     Rd_Rs_x,              s3_do_dsp3},
    592   {"add",       0x00000010, 0x3e0003ff, 0x4800,     Rd_Rs_Rs,             s3_do_rdrsrs},
    593   {"add.c",     0x00000011, 0x3e0003ff, 0x8000,     Rd_Rs_Rs,             s3_do_rdrsrs},
    594   {"add.s",     0x38000048, 0x3e0003ff, 0x8000,     Rd_Rs_Rs,             s3_do_dsp2},
    595   {"addc",      0x00000012, 0x3e0003ff, 0x8000,     Rd_Rs_Rs,             s3_do_rdrsrs},
    596   {"addc.c",    0x00000013, 0x3e0003ff, 0x8000,     Rd_Rs_Rs,             s3_do_rdrsrs},
    597   {"addi",      0x02000000, 0x3e0e0001, 0x5c00,     Rd_SI16,              s3_do_rdsi16},
    598   {"addi.c",    0x02000001, 0x3e0e0001, 0x8000,     Rd_SI16,              s3_do_rdsi16},
    599   {"addis",     0x0a000000, 0x3e0e0001, 0x8000,     Rd_SI16,              s3_do_rdi16},
    600   {"addis.c",   0x0a000001, 0x3e0e0001, 0x8000,     Rd_SI16,              s3_do_rdi16},
    601   {"addi!",     0x5c00,     0x7c00,     0x8000,     Rd_SI6,               s3_do16_addi},
    602   {"addri",     0x10000000, 0x3e000001, 0x8000,     Rd_Rs_SI14,           s3_do_rdrssi14},
    603   {"addri.c",   0x10000001, 0x3e000001, 0x8000,     Rd_Rs_SI14,           s3_do_rdrssi14},
    604 
    605   /* add.c <-> add!.  */
    606   {"add!",      0x4800,     0x7f00,     0x8000,     Rd_Rs,                s3_do16_rdrs2},
    607   {"subi",      0x02000000, 0x3e0e0001, 0x8000,     Rd_SI16,              s3_do_sub_rdsi16},
    608   {"subi.c",    0x02000001, 0x3e0e0001, 0x8000,     Rd_SI16,              s3_do_sub_rdsi16},
    609   {"subis",     0x0a000000, 0x3e0e0001, 0x8000,     Rd_SI16,              s3_do_sub_rdi16},
    610   {"subis.c",   0x0a000001, 0x3e0e0001, 0x8000,     Rd_SI16,              s3_do_sub_rdi16},
    611   {"subri",     0x10000000, 0x3e000001, 0x8000,     Rd_Rs_SI14,           s3_do_sub_rdrssi14},
    612   {"subri.c",   0x10000001, 0x3e000001, 0x8000,     Rd_Rs_SI14,           s3_do_sub_rdrssi14},
    613   {"and",       0x00000020, 0x3e0003ff, 0x4b00,     Rd_Rs_Rs,             s3_do_rdrsrs},
    614   {"and.c",     0x00000021, 0x3e0003ff, 0x8000,     Rd_Rs_Rs,             s3_do_rdrsrs},
    615   {"andi",      0x02080000, 0x3e0e0001, 0x8000,     Rd_I16,               s3_do_rdi16},
    616   {"andi.c",    0x02080001, 0x3e0e0001, 0x8000,     Rd_I16,               s3_do_rdi16},
    617   {"andis",     0x0a080000, 0x3e0e0001, 0x8000,     Rd_I16,               s3_do_rdi16},
    618   {"andis.c",   0x0a080001, 0x3e0e0001, 0x8000,     Rd_I16,               s3_do_rdi16},
    619   {"andri",     0x18000000, 0x3e000001, 0x8000,     Rd_Rs_I14,            s3_do_rdrsi14},
    620   {"andri.c",   0x18000001, 0x3e000001, 0x8000,     Rd_Rs_I14,            s3_do_rdrsi14},
    621 
    622   /* and.c <-> and!.  */
    623   {"and!",      0x4b00,     0x7f00,     0x8000,     Rd_Rs,                s3_do16_rdrs2},
    624   {"bcs",       0x08000000, 0x3e007c01, 0x8000,     PC_DISP19div2,        s3_do_branch},
    625   {"bcc",       0x08000400, 0x3e007c01, 0x8000,     PC_DISP19div2,        s3_do_branch},
    626   {"bcnz",      0x08003800, 0x3e007c01, 0x3200,     PC_DISP19div2,        s3_do_branch},
    627   {"bcsl",      0x08000001, 0x3e007c01, 0x8000,     PC_DISP19div2,        s3_do_branch},
    628   {"bccl",      0x08000401, 0x3e007c01, 0x8000,     PC_DISP19div2,        s3_do_branch},
    629   {"bcnzl",     0x08003801, 0x3e007c01, 0x8000,     PC_DISP19div2,        s3_do_branch},
    630   {"bcnz!",     0x3200,     0x7f00,     0x08003800, PC_DISP8div2,         s3_do16_branch},
    631   {"beq",       0x08001000, 0x3e007c01, 0x3800,     PC_DISP19div2,        s3_do_branch},
    632   {"beql",      0x08001001, 0x3e007c01, 0x8000,     PC_DISP19div2,        s3_do_branch},
    633   {"beq!",      0x3800,     0x7e00,     0x08001000, PC_DISP8div2,         s3_do16_branch},
    634   {"bgtu",      0x08000800, 0x3e007c01, 0x3400,     PC_DISP19div2,        s3_do_branch},
    635   {"bgt",       0x08001800, 0x3e007c01, 0x3c00,     PC_DISP19div2,        s3_do_branch},
    636   {"bge",       0x08002000, 0x3e007c01, 0x8000,     PC_DISP19div2,        s3_do_branch},
    637   {"bgtul",     0x08000801, 0x3e007c01, 0x8000,     PC_DISP19div2,        s3_do_branch},
    638   {"bgtl",      0x08001801, 0x3e007c01, 0x8000,     PC_DISP19div2,        s3_do_branch},
    639   {"bgel",      0x08002001, 0x3e007c01, 0x8000,     PC_DISP19div2,        s3_do_branch},
    640   {"bgtu!",     0x3400,     0x7e00,     0x08000800, PC_DISP8div2,         s3_do16_branch},
    641   {"bgt!",      0x3c00,     0x7e00,     0x08001800, PC_DISP8div2,         s3_do16_branch},
    642   {"bitclr",    0x00000028, 0x3e0003ff, 0x5000,     Rd_Rs_I5,             s3_do_rdrsi5},
    643   {"bitclr.c",  0x00000029, 0x3e0003ff, 0x8000,     Rd_Rs_I5,             s3_do_rdrsi5},
    644 
    645   {"mbitclr",   0x00000064, 0x3e00007e, 0x8000,     Ra_I9_I5,             s3_do_mbitclr},
    646   {"mbitset",   0x0000006c, 0x3e00007e, 0x8000,     Ra_I9_I5,             s3_do_mbitset},
    647 
    648   {"bitrev",    0x3800000c, 0x3e0003ff, 0x8000,     Rd_Rs_Rs,             s3_do_dsp2},
    649   {"bitset",    0x0000002a, 0x3e0003ff, 0x5200,     Rd_Rs_I5,             s3_do_rdrsi5},
    650   {"bitset.c",  0x0000002b, 0x3e0003ff, 0x8000,     Rd_Rs_I5,             s3_do_rdrsi5},
    651   {"bittst.c",  0x0000002d, 0x3e0003ff, 0x5400,     x_Rs_I5,              s3_do_xrsi5},
    652   {"bittgl",    0x0000002e, 0x3e0003ff, 0x5600,     Rd_Rs_I5,             s3_do_rdrsi5},
    653   {"bittgl.c",  0x0000002f, 0x3e0003ff, 0x8000,     Rd_Rs_I5,             s3_do_rdrsi5},
    654   {"bitclr!",   0x5000,     0x7e00,     0x8000,     Rd_I5,                s3_do16_rdi5},
    655   {"bitset!",   0x5200,     0x7e00,     0x8000,     Rd_I5,                s3_do16_rdi5},
    656   {"bittst!",   0x5400,     0x7e00,     0x8000,     Rd_I5,                s3_do16_rdi5},
    657   {"bittgl!",   0x5600,     0x7e00,     0x8000,     Rd_I5,                s3_do16_rdi5},
    658   {"bleu",      0x08000c00, 0x3e007c01, 0x3600,     PC_DISP19div2,        s3_do_branch},
    659   {"ble",       0x08001c00, 0x3e007c01, 0x3e00,     PC_DISP19div2,        s3_do_branch},
    660   {"blt",       0x08002400, 0x3e007c01, 0x8000,     PC_DISP19div2,        s3_do_branch},
    661   {"bleul",     0x08000c01, 0x3e007c01, 0x8000,     PC_DISP19div2,        s3_do_branch},
    662   {"blel",      0x08001c01, 0x3e007c01, 0x8000,     PC_DISP19div2,        s3_do_branch},
    663   {"bltl",      0x08002401, 0x3e007c01, 0x8000,     PC_DISP19div2,        s3_do_branch},
    664   {"bl",        0x08003c01, 0x3e007c01, 0x8000,     PC_DISP19div2,        s3_do_branch},
    665   {"bleu!",     0x3600,     0x7e00,     0x08000c00, PC_DISP8div2,         s3_do16_branch},
    666   {"ble!",      0x3e00,     0x7e00,     0x08001c00, PC_DISP8div2,         s3_do16_branch},
    667   {"bmi",       0x08002800, 0x3e007c01, 0x8000,     PC_DISP19div2,        s3_do_branch},
    668   {"bmil",      0x08002801, 0x3e007c01, 0x8000,     PC_DISP19div2,        s3_do_branch},
    669   {"bne",       0x08001400, 0x3e007c01, 0x3a00,     PC_DISP19div2,        s3_do_branch},
    670   {"bnel",      0x08001401, 0x3e007c01, 0x8000,     PC_DISP19div2,        s3_do_branch},
    671   {"bne!",      0x3a00,     0x7e00,     0x08001400, PC_DISP8div2,         s3_do16_branch},
    672   {"bpl",       0x08002c00, 0x3e007c01, 0x8000,     PC_DISP19div2,        s3_do_branch},
    673   {"bpll",      0x08002c01, 0x3e007c01, 0x8000,     PC_DISP19div2,        s3_do_branch},
    674   {"brcs",      0x00000008, 0x3e007fff, 0x8000,     x_Rs_x,               s3_do_rs},
    675   {"brcc",      0x00000408, 0x3e007fff, 0x8000,     x_Rs_x,               s3_do_rs},
    676   {"brgtu",     0x00000808, 0x3e007fff, 0x8000,     x_Rs_x,               s3_do_rs},
    677   {"brleu",     0x00000c08, 0x3e007fff, 0x8000,     x_Rs_x,               s3_do_rs},
    678   {"breq",      0x00001008, 0x3e007fff, 0x8000,     x_Rs_x,               s3_do_rs},
    679   {"brne",      0x00001408, 0x3e007fff, 0x8000,     x_Rs_x,               s3_do_rs},
    680   {"brgt",      0x00001808, 0x3e007fff, 0x8000,     x_Rs_x,               s3_do_rs},
    681   {"brle",      0x00001c08, 0x3e007fff, 0x8000,     x_Rs_x,               s3_do_rs},
    682   {"brge",      0x00002008, 0x3e007fff, 0x8000,     x_Rs_x,               s3_do_rs},
    683   {"brlt",      0x00002408, 0x3e007fff, 0x8000,     x_Rs_x,               s3_do_rs},
    684   {"brmi",      0x00002808, 0x3e007fff, 0x8000,     x_Rs_x,               s3_do_rs},
    685   {"brpl",      0x00002c08, 0x3e007fff, 0x8000,     x_Rs_x,               s3_do_rs},
    686   {"brvs",      0x00003008, 0x3e007fff, 0x8000,     x_Rs_x,               s3_do_rs},
    687   {"brvc",      0x00003408, 0x3e007fff, 0x8000,     x_Rs_x,               s3_do_rs},
    688   {"brcnz",     0x00003808, 0x3e007fff, 0x8000,     x_Rs_x,               s3_do_rs},
    689   {"br",        0x00003c08, 0x3e007fff, 0x0080,     x_Rs_x,               s3_do_rs},
    690   {"brcsl",     0x00000009, 0x3e007fff, 0x8000,     x_Rs_x,               s3_do_rs},
    691   {"brccl",     0x00000409, 0x3e007fff, 0x8000,     x_Rs_x,               s3_do_rs},
    692   {"brgtul",    0x00000809, 0x3e007fff, 0x8000,     x_Rs_x,               s3_do_rs},
    693   {"brleul",    0x00000c09, 0x3e007fff, 0x8000,     x_Rs_x,               s3_do_rs},
    694   {"breql",     0x00001009, 0x3e007fff, 0x8000,     x_Rs_x,               s3_do_rs},
    695   {"brnel",     0x00001409, 0x3e007fff, 0x8000,     x_Rs_x,               s3_do_rs},
    696   {"brgtl",     0x00001809, 0x3e007fff, 0x8000,     x_Rs_x,               s3_do_rs},
    697   {"brlel",     0x00001c09, 0x3e007fff, 0x8000,     x_Rs_x,               s3_do_rs},
    698   {"brgel",     0x00002009, 0x3e007fff, 0x8000,     x_Rs_x,               s3_do_rs},
    699   {"brltl",     0x00002409, 0x3e007fff, 0x8000,     x_Rs_x,               s3_do_rs},
    700   {"brmil",     0x00002809, 0x3e007fff, 0x8000,     x_Rs_x,               s3_do_rs},
    701   {"brpll",     0x00002c09, 0x3e007fff, 0x8000,     x_Rs_x,               s3_do_rs},
    702   {"brvsl",     0x00003009, 0x3e007fff, 0x8000,     x_Rs_x,               s3_do_rs},
    703   {"brvcl",     0x00003409, 0x3e007fff, 0x8000,     x_Rs_x,               s3_do_rs},
    704   {"brcnzl",    0x00003809, 0x3e007fff, 0x8000,     x_Rs_x,               s3_do_rs},
    705   {"brl",       0x00003c09, 0x3e007fff, 0x00a0,     x_Rs_x,               s3_do_rs},
    706   {"br!",       0x0080,     0x7fe0,     0x8000,     x_Rs,                 s3_do16_br},
    707   {"brl!",      0x00a0,     0x7fe0,     0x8000,     x_Rs,                 s3_do16_br},
    708   {"brr!",      0x00c0,     0x7fe0,     0x8000,     x_Rs,                 s3_do16_brr},
    709   {"bvs",       0x08003000, 0x3e007c01, 0x8000,     PC_DISP19div2,        s3_do_branch},
    710   {"bvc",       0x08003400, 0x3e007c01, 0x8000,     PC_DISP19div2,        s3_do_branch},
    711   {"bvsl",      0x08003001, 0x3e007c01, 0x8000,     PC_DISP19div2,        s3_do_branch},
    712   {"bvcl",      0x08003401, 0x3e007c01, 0x8000,     PC_DISP19div2,        s3_do_branch},
    713   {"b!",        0x3000,     0x7e00,     0x08003c00, PC_DISP8div2,         s3_do16_branch},
    714   {"b",         0x08003c00, 0x3e007c01, 0x3000,     PC_DISP19div2,        s3_do_branch},
    715   {"cache",     0x30000000, 0x3ff00000, 0x8000,     OP5_rvalueRs_SI15,    s3_do_cache},
    716   {"ceinst",    0x38000000, 0x3e000000, 0x8000,     I5_Rs_Rs_I5_OP5,      s3_do_ceinst},
    717   {"clz",       0x0000001c, 0x3e007fff, 0x8000,     Rd_Rs_x,              s3_do_rdrs},
    718   {"cmp.c",     0x00300019, 0x3ff003ff, 0x4400,     x_Rs_Rs,              s3_do_rsrs},
    719   {"cmpz.c",    0x0030001b, 0x3ff07fff, 0x8000,     x_Rs_x,               s3_do_rs},
    720   {"cmpi.c",    0x02040001, 0x3e0e0001, 0x6000,     Rd_SI16,              s3_do_rdsi16},
    721 
    722   /* cmp.c <-> cmp!.  */
    723   {"cmp!",      0x4400,     0x7c00,     0x8000,     Rd_Rs,                s3_do16_mv_cmp},
    724   {"cmpi!",     0x6000,     0x7c00,     0x8000,     Rd_SI5,               s3_do16_cmpi},
    725   {"cop1",      0x0c00000c, 0x3e00001f, 0x8000,     Rd_Rs_Rs_imm,         s3_do_crdcrscrsimm5},
    726   {"cop2",      0x0c000014, 0x3e00001f, 0x8000,     Rd_Rs_Rs_imm,         s3_do_crdcrscrsimm5},
    727   {"cop3",      0x0c00001c, 0x3e00001f, 0x8000,     Rd_Rs_Rs_imm,         s3_do_crdcrscrsimm5},
    728   {"drte",      0x0c0000a4, 0x3e0003ff, 0x8000,     NO_OPD,               s3_do_empty},
    729   {"disint!",    0x00e0,     0xffe1,     0x8000,     NO16_OPD,               s3_do16_int},
    730   {"enint!",     0x00e1,     0xffe1,     0x8000,     NO16_OPD,               s3_do16_int},
    731   {"extsb",     0x00000058, 0x3e0003ff, 0x8000,     Rd_Rs_x,              s3_do_rdrs},
    732   {"extsb.c",   0x00000059, 0x3e0003ff, 0x8000,     Rd_Rs_x,              s3_do_rdrs},
    733   {"extsh",     0x0000005a, 0x3e0003ff, 0x8000,     Rd_Rs_x,              s3_do_rdrs},
    734   {"extsh.c",   0x0000005b, 0x3e0003ff, 0x8000,     Rd_Rs_x,              s3_do_rdrs},
    735   {"extzb",     0x0000005c, 0x3e0003ff, 0x8000,     Rd_Rs_x,              s3_do_rdrs},
    736   {"extzb.c",   0x0000005d, 0x3e0003ff, 0x8000,     Rd_Rs_x,              s3_do_rdrs},
    737   {"extzh",     0x0000005e, 0x3e0003ff, 0x8000,     Rd_Rs_x,              s3_do_rdrs},
    738   {"extzh.c",   0x0000005f, 0x3e0003ff, 0x8000,     Rd_Rs_x,              s3_do_rdrs},
    739   {"jl",        0x04000001, 0x3e000001, 0x8000,     PC_DISP24div2,        s3_do_jump},
    740   {"j",         0x04000000, 0x3e000001, 0x8000,     PC_DISP24div2,        s3_do_jump},
    741   {"alw",       0x0000000c, 0x3e0003ff, 0x8000,     Rd_rvalue32Rs,        s3_do_ldst_atomic},
    742   {"lcb",       0x00000060, 0x3e0003ff, 0x8000,     x_rvalueRs_post4,     s3_do_ldst_unalign},
    743   {"lcw",       0x00000062, 0x3e0003ff, 0x8000,     Rd_rvalueRs_post4,    s3_do_ldst_unalign},
    744   {"lce",       0x00000066, 0x3e0003ff, 0x8000,     Rd_rvalueRs_post4,    s3_do_ldst_unalign},
    745   {"ldc1",      0x0c00000a, 0x3e00001f, 0x8000,     Rd_rvalueRs_SI10,     s3_do_ldst_cop},
    746   {"ldc2",      0x0c000012, 0x3e00001f, 0x8000,     Rd_rvalueRs_SI10,     s3_do_ldst_cop},
    747   {"ldc3",      0x0c00001a, 0x3e00001f, 0x8000,     Rd_rvalueRs_SI10,     s3_do_ldst_cop},
    748 
    749   /* s3_inst.relax */
    750   {"ldi",       0x020c0000, 0x3e0e0000, 0x6400,     Rd_SI16,              s3_do_rdsi16},
    751   {"ldis",      0x0a0c0000, 0x3e0e0000, 0x8000,     Rd_I16,               s3_do_ldis},
    752 
    753   /* ldi <-> ldiu!.  */
    754   {"ldiu!",     0x6400,     0x7c00,     0x8000,     Rd_I5,                s3_do16_ldiu},
    755 
    756   /*ltbb! , ltbh! ltbw! */
    757   {"ltbw",      0x00000032, 0x03ff,     0x8000,     Rd_Rs_Rs,             s3_do_ltb},
    758   {"ltbh",      0x00000132, 0x03ff,     0x8000,     Rd_Rs_Rs,             s3_do_ltb},
    759   {"ltbb",      0x00000332, 0x03ff,     0x8000,     Rd_Rs_Rs,             s3_do_ltb},
    760   {"lw!",       0x1000,     0x7000,     0x8000,     Rd_rvalueRs,          s3_do16_ldst_insn},
    761   {"mfcel",     0x00000448, 0x3e007fff, 0x8000,     Rd_x_x,               s3_do_rd},
    762   {"mfcel!",    0x7100,     0x7ff0,     0x00000448, x_Rs,                 s3_do16_dsp},
    763   {"mad",       0x38000000, 0x3ff003ff, 0x8000,     x_Rs_Rs,              s3_do_dsp},
    764   {"mad.f!",    0x7400,     0x7f00,     0x38000080, Rd_Rs,                s3_do16_dsp2},
    765   {"madh",      0x38000203, 0x3ff003ff, 0x8000,     x_Rs_Rs,              s3_do_dsp},
    766   {"madh.fs",   0x380002c3, 0x3ff003ff, 0x8000,     x_Rs_Rs,              s3_do_dsp},
    767   {"madh.fs!",  0x7b00,     0x7f00,     0x380002c3, Rd_Rs,                s3_do16_dsp2},
    768   {"madl",      0x38000002, 0x3ff003ff, 0x8000,     x_Rs_Rs,              s3_do_dsp},
    769   {"madl.fs",   0x380000c2, 0x3ff003ff, 0x8000,     x_Rs_Rs,              s3_do_dsp},
    770   {"madl.fs!",  0x7a00,     0x7f00,     0x380000c2, Rd_Rs,                s3_do16_dsp2},
    771   {"madu",      0x38000020, 0x3ff003ff, 0x8000,     x_Rs_Rs,              s3_do_dsp},
    772   {"madu!",     0x7500,     0x7f00,     0x38000020, Rd_Rs,                s3_do16_dsp2},
    773   {"mad.f",     0x38000080, 0x3ff003ff, 0x8000,     x_Rs_Rs,              s3_do_dsp},
    774   {"max",       0x38000007, 0x3e0003ff, 0x8000,     Rd_Rs_Rs,             s3_do_dsp2},
    775   {"mazh",      0x38000303, 0x3ff003ff, 0x8000,     x_Rs_Rs,              s3_do_dsp},
    776   {"mazh.f",    0x38000383, 0x3ff003ff, 0x8000,     x_Rs_Rs,              s3_do_dsp},
    777   {"mazh.f!",   0x7900,     0x7f00,     0x3800038c, Rd_Rs,                s3_do16_dsp2},
    778   {"mazl",      0x38000102, 0x3ff003ff, 0x8000,     x_Rs_Rs,              s3_do_dsp},
    779   {"mazl.f",    0x38000182, 0x3ff003ff, 0x8000,     x_Rs_Rs,              s3_do_dsp},
    780   {"mazl.f!",   0x7800,     0x7f00,     0x38000182, Rd_Rs,                s3_do16_dsp2},
    781   {"mfceh",     0x00000848, 0x3e007fff, 0x8000,     Rd_x_x,               s3_do_rd},
    782   {"mfceh!",    0x7110,     0x7ff0,     0x00000848, x_Rs,                 s3_do16_dsp},
    783   {"mfcehl",    0x00000c48, 0x3e007fff, 0x8000,     Rd_Rs_x,              s3_do_rdrs},
    784   {"mfsr",      0x00000050, 0x3e0003ff, 0x8000,     Rd_x_I5,              s3_do_rdsrs},
    785   {"mfcr",      0x0c000001, 0x3e00001f, 0x8000,     Rd_Rs_x,              s3_do_rdcrs},
    786   {"mfc1",      0x0c000009, 0x3e00001f, 0x8000,     Rd_Rs_x,              s3_do_rdcrs},
    787   {"mfc2",      0x0c000011, 0x3e00001f, 0x8000,     Rd_Rs_x,              s3_do_rdcrs},
    788   {"mfc3",      0x0c000019, 0x3e00001f, 0x8000,     Rd_Rs_x,              s3_do_rdcrs},
    789   {"mfcc1",     0x0c00000f, 0x3e00001f, 0x8000,     Rd_Rs_x,              s3_do_rdcrs},
    790   {"mfcc2",     0x0c000017, 0x3e00001f, 0x8000,     Rd_Rs_x,              s3_do_rdcrs},
    791   {"mfcc3",     0x0c00001f, 0x3e00001f, 0x8000,     Rd_Rs_x,              s3_do_rdcrs},
    792   {"min",       0x38000006, 0x3e0003ff, 0x8000,     Rd_Rs_Rs,             s3_do_dsp2},
    793   {"msb",       0x38000001, 0x3ff003ff, 0x8000,     x_Rs_Rs,              s3_do_dsp},
    794   {"msb.f!",    0x7600,     0x7f00,     0x38000081, Rd_Rs,                s3_do16_dsp2},
    795   {"msbh",      0x38000205, 0x3ff003ff, 0x8000,     x_Rs_Rs,              s3_do_dsp},
    796   {"msbh.fs",   0x380002c5, 0x3ff003ff, 0x8000,     x_Rs_Rs,              s3_do_dsp},
    797   {"msbh.fs!",  0x7f00,     0x7f00,     0x380002c5, Rd_Rs,                s3_do16_dsp2},
    798   {"msbl",      0x38000004, 0x3ff003ff, 0x8000,     x_Rs_Rs,              s3_do_dsp},
    799   {"msbl.fs",   0x380000c4, 0x3ff003ff, 0x8000,     x_Rs_Rs,              s3_do_dsp},
    800   {"msbl.fs!",  0x7e00,     0x7f00,     0x380000c4, Rd_Rs,                s3_do16_dsp2},
    801   {"msbu",      0x38000021, 0x3ff003ff, 0x8000,     x_Rs_Rs,              s3_do_dsp},
    802   {"msbu!",     0x7700,     0x7f00,     0x38000021, Rd_Rs,                s3_do16_dsp2},
    803   {"msb.f",     0x38000081, 0x3ff003ff, 0x8000,     x_Rs_Rs,              s3_do_dsp},
    804   {"mszh",      0x38000305, 0x3ff003ff, 0x8000,     x_Rs_Rs,              s3_do_dsp},
    805   {"mszh.f",    0x38000385, 0x3ff003ff, 0x8000,     x_Rs_Rs,              s3_do_dsp},
    806   {"mszh.f!",   0x7d00,     0x7f00,     0x38000385, Rd_Rs,                s3_do16_dsp2},
    807   {"mszl",      0x38000104, 0x3ff003ff, 0x8000,     x_Rs_Rs,              s3_do_dsp},
    808   {"mszl.f",    0x38000184, 0x3ff003ff, 0x8000,     x_Rs_Rs,              s3_do_dsp},
    809   {"mszl.f!",   0x7c00,     0x7f00,     0x38000184, Rd_Rs,                s3_do16_dsp2},
    810   {"mtcel!",    0x7000,     0x7ff0,     0x0000044a, x_Rs,                 s3_do16_dsp},
    811   {"mtcel",     0x0000044a, 0x3e007fff, 0x8000,     Rd_x_x,               s3_do_rd},
    812   {"mtceh",     0x0000084a, 0x3e007fff, 0x8000,     Rd_x_x,               s3_do_rd},
    813   {"mtceh!",    0x7010,     0x7ff0,     0x0000084a, x_Rs,                 s3_do16_dsp},
    814   {"mtcehl",    0x00000c4a, 0x3e007fff, 0x8000,     Rd_Rs_x,              s3_do_rdrs},
    815   {"mtsr",      0x00000052, 0x3e0003ff, 0x8000,     x_Rs_I5,              s3_do_rdsrs},
    816   {"mtcr",      0x0c000000, 0x3e00001f, 0x8000,     Rd_Rs_x,              s3_do_rdcrs},
    817   {"mtc1",      0x0c000008, 0x3e00001f, 0x8000,     Rd_Rs_x,              s3_do_rdcrs},
    818   {"mtc2",      0x0c000010, 0x3e00001f, 0x8000,     Rd_Rs_x,              s3_do_rdcrs},
    819   {"mtc3",      0x0c000018, 0x3e00001f, 0x8000,     Rd_Rs_x,              s3_do_rdcrs},
    820   {"mtcc1",     0x0c00000e, 0x3e00001f, 0x8000,     Rd_Rs_x,              s3_do_rdcrs},
    821   {"mtcc2",     0x0c000016, 0x3e00001f, 0x8000,     Rd_Rs_x,              s3_do_rdcrs},
    822   {"mtcc3",     0x0c00001e, 0x3e00001f, 0x8000,     Rd_Rs_x,              s3_do_rdcrs},
    823   {"mul.f!",    0x7200,     0x7f00,     0x00000041, Rd_Rs,                s3_do16_dsp2},
    824   {"mulu!",     0x7300,     0x7f00,     0x00000042, Rd_Rs,                s3_do16_dsp2},
    825   {"mulr.l",    0x00000140, 0x3e0003ff, 0x8000,     Insn_Type_SYN,        s3_do_rdrsrs},
    826   {"mulr.h",    0x00000240, 0x3e0003ff, 0x8000,     Insn_Type_SYN,        s3_do_rdrsrs},
    827   {"mulr",      0x00000340, 0x3e0003ff, 0x8000,     Insn_Type_SYN,        s3_do_rdrsrs},
    828   {"mulr.lf",   0x00000141, 0x3e0003ff, 0x8000,     Insn_Type_SYN,        s3_do_rdrsrs},
    829   {"mulr.hf",   0x00000241, 0x3e0003ff, 0x8000,     Insn_Type_SYN,        s3_do_rdrsrs},
    830   {"mulr.f",    0x00000341, 0x3e0003ff, 0x8000,     Insn_Type_SYN,        s3_do_rdrsrs},
    831   {"mulur.l",   0x00000142, 0x3e0003ff, 0x8000,     Insn_Type_SYN,        s3_do_rdrsrs},
    832   {"mulur.h",   0x00000242, 0x3e0003ff, 0x8000,     Insn_Type_SYN,        s3_do_rdrsrs},
    833   {"mulur",     0x00000342, 0x3e0003ff, 0x8000,     Insn_Type_SYN,        s3_do_rdrsrs},
    834   {"divr.q",    0x00000144, 0x3e0003ff, 0x8000,     Insn_Type_SYN,        s3_do_rdrsrs},
    835   {"divr.r",    0x00000244, 0x3e0003ff, 0x8000,     Insn_Type_SYN,        s3_do_rdrsrs},
    836   {"divr",      0x00000344, 0x3e0003ff, 0x8000,     Insn_Type_SYN,        s3_do_rdrsrs},
    837   {"divur.q",   0x00000146, 0x3e0003ff, 0x8000,     Insn_Type_SYN,        s3_do_rdrsrs},
    838   {"divur.r",   0x00000246, 0x3e0003ff, 0x8000,     Insn_Type_SYN,        s3_do_rdrsrs},
    839   {"divur",     0x00000346, 0x3e0003ff, 0x8000,     Insn_Type_SYN,        s3_do_rdrsrs},
    840   {"mvcs",      0x00000056, 0x3e007fff, 0x8000,     Rd_Rs_x,              s3_do_rdrs},
    841   {"mvcc",      0x00000456, 0x3e007fff, 0x8000,     Rd_Rs_x,              s3_do_rdrs},
    842   {"mvgtu",     0x00000856, 0x3e007fff, 0x8000,     Rd_Rs_x,              s3_do_rdrs},
    843   {"mvleu",     0x00000c56, 0x3e007fff, 0x8000,     Rd_Rs_x,              s3_do_rdrs},
    844   {"mveq",      0x00001056, 0x3e007fff, 0x8000,     Rd_Rs_x,              s3_do_rdrs},
    845   {"mvne",      0x00001456, 0x3e007fff, 0x8000,     Rd_Rs_x,              s3_do_rdrs},
    846   {"mvgt",      0x00001856, 0x3e007fff, 0x8000,     Rd_Rs_x,              s3_do_rdrs},
    847   {"mvle",      0x00001c56, 0x3e007fff, 0x8000,     Rd_Rs_x,              s3_do_rdrs},
    848   {"mvge",      0x00002056, 0x3e007fff, 0x8000,     Rd_Rs_x,              s3_do_rdrs},
    849   {"mvlt",      0x00002456, 0x3e007fff, 0x8000,     Rd_Rs_x,              s3_do_rdrs},
    850   {"mvmi",      0x00002856, 0x3e007fff, 0x8000,     Rd_Rs_x,              s3_do_rdrs},
    851   {"mvpl",      0x00002c56, 0x3e007fff, 0x8000,     Rd_Rs_x,              s3_do_rdrs},
    852   {"mvvs",      0x00003056, 0x3e007fff, 0x8000,     Rd_Rs_x,              s3_do_rdrs},
    853   {"mvvc",      0x00003456, 0x3e007fff, 0x8000,     Rd_Rs_x,              s3_do_rdrs},
    854 
    855   /* mv <-> mv!.  */
    856   {"mv",        0x00003c56, 0x3e007fff, 0x4000,     Rd_Rs_x,              s3_do_rdrs},
    857   {"mv!",       0x4000,     0x7c00,     0x8000,     Rd_Rs,                s3_do16_mv_cmp},
    858   {"neg",       0x0000001e, 0x3e0003ff, 0x8000,     Rd_x_Rs,              s3_do_rdxrs},
    859   {"neg.c",     0x0000001f, 0x3e0003ff, 0x8000,     Rd_x_Rs,              s3_do_rdxrs},
    860   {"nop",       0x00000000, 0x3e0003ff, 0x0000,     NO_OPD,               s3_do_empty},
    861   {"not",       0x00000024, 0x3e0003ff, 0x8000,     Rd_Rs_x,              s3_do_rdrs},
    862   {"not.c",     0x00000025, 0x3e0003ff, 0x8000,     Rd_Rs_x,              s3_do_rdrs},
    863   {"nop!",      0x0000,     0x7fff,     0x8000,     NO16_OPD,             s3_do_empty},
    864   {"or",        0x00000022, 0x3e0003ff, 0x4a00,     Rd_Rs_Rs,             s3_do_rdrsrs},
    865   {"or.c",      0x00000023, 0x3e0003ff, 0x8000,     Rd_Rs_Rs,             s3_do_rdrsrs},
    866   {"ori",       0x020a0000, 0x3e0e0001, 0x8000,     Rd_I16,               s3_do_rdi16},
    867   {"ori.c",     0x020a0001, 0x3e0e0001, 0x8000,     Rd_I16,               s3_do_rdi16},
    868   {"oris",      0x0a0a0000, 0x3e0e0001, 0x8000,     Rd_I16,               s3_do_rdi16},
    869   {"oris.c",    0x0a0a0001, 0x3e0e0001, 0x8000,     Rd_I16,               s3_do_rdi16},
    870   {"orri",      0x1a000000, 0x3e000001, 0x8000,     Rd_Rs_I14,            s3_do_rdrsi14},
    871   {"orri.c",    0x1a000001, 0x3e000001, 0x8000,     Rd_Rs_I14,            s3_do_rdrsi14},
    872 
    873   /* or.c <-> or!.  */
    874   {"or!",       0x4a00,     0x7f00,     0x8000,     Rd_Rs,                s3_do16_rdrs2},
    875   {"pflush",    0x0000000a, 0x3e0003ff, 0x8000,     NO_OPD,               s3_do_empty},
    876   {"pop!",      0x0040,     0x7fe0,     0x8000,     Rd_rvalueRs,          s3_do16_push_pop},
    877   {"push!",     0x0060,     0x7fe0,     0x8000,     Rd_lvalueRs,          s3_do16_push_pop},
    878 
    879   {"rpop!",     0x6800,     0x7c00,     0x8000,     Rd_I5,                s3_do16_rpop},
    880   {"rpush!",    0x6c00,     0x7c00,     0x8000,     Rd_I5,                s3_do16_rpush},
    881 
    882   {"ror",       0x00000038, 0x3e0003ff, 0x8000,     Rd_Rs_Rs,             s3_do_rdrsrs},
    883   {"ror.c",     0x00000039, 0x3e0003ff, 0x8000,     Rd_Rs_Rs,             s3_do_rdrsrs},
    884   {"rorc.c",    0x0000003b, 0x3e0003ff, 0x8000,     Rd_Rs_Rs,             s3_do_rdrsrs},
    885   {"rol",       0x0000003c, 0x3e0003ff, 0x8000,     Rd_Rs_Rs,             s3_do_rdrsrs},
    886   {"rol.c",     0x0000003d, 0x3e0003ff, 0x8000,     Rd_Rs_Rs,             s3_do_rdrsrs},
    887   {"rolc.c",    0x0000003f, 0x3e0003ff, 0x8000,     Rd_Rs_Rs,             s3_do_rdrsrs},
    888   {"rori",      0x00000078, 0x3e0003ff, 0x8000,     Rd_Rs_I5,             s3_do_rdrsi5},
    889   {"rori.c",    0x00000079, 0x3e0003ff, 0x8000,     Rd_Rs_I5,             s3_do_rdrsi5},
    890   {"roric.c",   0x0000007b, 0x3e0003ff, 0x8000,     Rd_Rs_I5,             s3_do_rdrsi5},
    891   {"roli",      0x0000007c, 0x3e0003ff, 0x8000,     Rd_Rs_I5,             s3_do_rdrsi5},
    892   {"roli.c",    0x0000007d, 0x3e0003ff, 0x8000,     Rd_Rs_I5,             s3_do_rdrsi5},
    893   {"rolic.c",   0x0000007f, 0x3e0003ff, 0x8000,     Rd_Rs_I5,             s3_do_rdrsi5},
    894   {"rte",       0x0c000084, 0x3e0003ff, 0x8000,     NO_OPD,               s3_do_empty},
    895   {"asw",       0x0000000e, 0x3e0003ff, 0x8000,     Rd_lvalue32Rs,        s3_do_ldst_atomic},
    896   {"scb",       0x00000068, 0x3e0003ff, 0x8000,     Rd_lvalueRs_post4,    s3_do_ldst_unalign},
    897   {"scw",       0x0000006a, 0x3e0003ff, 0x8000,     Rd_lvalueRs_post4,    s3_do_ldst_unalign},
    898   {"sce",       0x0000006e, 0x3e0003ff, 0x8000,     x_lvalueRs_post4,     s3_do_ldst_unalign},
    899   {"sdbbp",     0x00000006, 0x3e0003ff, 0x0020,     x_I5_x,               s3_do_xi5x},
    900   {"sdbbp!",    0x0020,     0x7fe0,     0x8000,     Rd_I5,                s3_do16_xi5},
    901   {"sleep",     0x0c0000c4, 0x3e0003ff, 0x8000,     NO_OPD,               s3_do_empty},
    902   {"rti",       0x0c0000e4, 0x3e0003ff, 0x8000,     NO_OPD,               s3_do_empty},
    903   {"sll",       0x00000030, 0x3e0003ff, 0x8000,     Rd_Rs_Rs,             s3_do_rdrsrs},
    904   {"sll.c",     0x00000031, 0x3e0003ff, 0x8000,     Rd_Rs_Rs,             s3_do_rdrsrs},
    905   {"sll.s",     0x3800004e, 0x3e0003ff, 0x8000,     Rd_Rs_Rs,             s3_do_dsp2},
    906   {"slli",      0x00000070, 0x3e0003ff, 0x5800,     Rd_Rs_I5,             s3_do_rdrsi5},
    907   {"slli.c",    0x00000071, 0x3e0003ff, 0x8000,     Rd_Rs_I5,             s3_do_rdrsi5},
    908 
    909   /* slli.c <-> slli!.  */
    910   {"slli!",     0x5800,     0x7e00,     0x8000,     Rd_I5,                s3_do16_slli_srli},
    911   {"srl",       0x00000034, 0x3e0003ff, 0x8000,     Rd_Rs_Rs,             s3_do_rdrsrs},
    912   {"srl.c",     0x00000035, 0x3e0003ff, 0x8000,     Rd_Rs_Rs,             s3_do_rdrsrs},
    913   {"sra",       0x00000036, 0x3e0003ff, 0x8000,     Rd_Rs_Rs,             s3_do_rdrsrs},
    914   {"sra.c",     0x00000037, 0x3e0003ff, 0x8000,     Rd_Rs_Rs,             s3_do_rdrsrs},
    915   {"srli",      0x00000074, 0x3e0003ff, 0x5a00,     Rd_Rs_I5,             s3_do_rdrsi5},
    916   {"srli.c",    0x00000075, 0x3e0003ff, 0x8000,     Rd_Rs_I5,             s3_do_rdrsi5},
    917   {"srai",      0x00000076, 0x3e0003ff, 0x8000,     Rd_Rs_I5,             s3_do_rdrsi5},
    918   {"srai.c",    0x00000077, 0x3e0003ff, 0x8000,     Rd_Rs_I5,             s3_do_rdrsi5},
    919 
    920   /* srli.c <-> srli!.  */
    921   {"srli!",     0x5a00,     0x7e00,     0x8000,     Rd_Rs,                s3_do16_slli_srli},
    922   {"stc1",      0x0c00000b, 0x3e00001f, 0x8000,     Rd_lvalueRs_SI10,     s3_do_ldst_cop},
    923   {"stc2",      0x0c000013, 0x3e00001f, 0x8000,     Rd_lvalueRs_SI10,     s3_do_ldst_cop},
    924   {"stc3",      0x0c00001b, 0x3e00001f, 0x8000,     Rd_lvalueRs_SI10,     s3_do_ldst_cop},
    925   {"sub",       0x00000014, 0x3e0003ff, 0x4900,     Rd_Rs_Rs,             s3_do_rdrsrs},
    926   {"sub.c",     0x00000015, 0x3e0003ff, 0x8000,     Rd_Rs_Rs,             s3_do_rdrsrs},
    927   {"sub.s",     0x38000049, 0x3e0003ff, 0x8000,     Rd_Rs_Rs,             s3_do_dsp2},
    928   {"subc",      0x00000016, 0x3e0003ff, 0x8000,     Rd_Rs_Rs,             s3_do_rdrsrs},
    929   {"subc.c",    0x00000017, 0x3e0003ff, 0x8000,     Rd_Rs_Rs,             s3_do_rdrsrs},
    930 
    931   /* sub.c <-> sub!.  */
    932   {"sub!",      0x4900,     0x7f00,     0x8000,     Rd_Rs,                s3_do16_rdrs2},
    933   {"sw!",       0x2000,     0x7000,     0x8000,     Rd_lvalueRs,          s3_do16_ldst_insn},
    934   {"syscall",   0x00000002, 0x3e0003ff, 0x8000,     I15,                  s3_do_i15},
    935   {"trapcs",    0x00000004, 0x3e007fff, 0x8000,     x_I5_x,               s3_do_xi5x},
    936   {"trapcc",    0x00000404, 0x3e007fff, 0x8000,     x_I5_x,               s3_do_xi5x},
    937   {"trapgtu",   0x00000804, 0x3e007fff, 0x8000,     x_I5_x,               s3_do_xi5x},
    938   {"trapleu",   0x00000c04, 0x3e007fff, 0x8000,     x_I5_x,               s3_do_xi5x},
    939   {"trapeq",    0x00001004, 0x3e007fff, 0x8000,     x_I5_x,               s3_do_xi5x},
    940   {"trapne",    0x00001404, 0x3e007fff, 0x8000,     x_I5_x,               s3_do_xi5x},
    941   {"trapgt",    0x00001804, 0x3e007fff, 0x8000,     x_I5_x,               s3_do_xi5x},
    942   {"traple",    0x00001c04, 0x3e007fff, 0x8000,     x_I5_x,               s3_do_xi5x},
    943   {"trapge",    0x00002004, 0x3e007fff, 0x8000,     x_I5_x,               s3_do_xi5x},
    944   {"traplt",    0x00002404, 0x3e007fff, 0x8000,     x_I5_x,               s3_do_xi5x},
    945   {"trapmi",    0x00002804, 0x3e007fff, 0x8000,     x_I5_x,               s3_do_xi5x},
    946   {"trappl",    0x00002c04, 0x3e007fff, 0x8000,     x_I5_x,               s3_do_xi5x},
    947   {"trapvs",    0x00003004, 0x3e007fff, 0x8000,     x_I5_x,               s3_do_xi5x},
    948   {"trapvc",    0x00003404, 0x3e007fff, 0x8000,     x_I5_x,               s3_do_xi5x},
    949   {"trap",      0x00003c04, 0x3e007fff, 0x8000,     x_I5_x,               s3_do_xi5x},
    950   {"xor",       0x00000026, 0x3e0003ff, 0x8000,     Rd_Rs_Rs,             s3_do_rdrsrs},
    951   {"xor.c",     0x00000027, 0x3e0003ff, 0x8000,     Rd_Rs_Rs,             s3_do_rdrsrs},
    952 
    953   /* Macro instruction.  */
    954   {"li",        0x020c0000, 0x3e0e0000, 0x8000,     Insn_Type_SYN,        s3_do_macro_li_rdi32},
    955 
    956   /* la reg, imm32        -->(1)  ldi  reg, simm16
    957                              (2)  ldis reg, %HI(imm32)
    958                                   ori  reg, %LO(imm32)
    959 
    960      la reg, symbol       -->(1)  lis  reg, %HI(imm32)
    961                                   ori  reg, %LO(imm32)  */
    962   {"la",        0x020c0000, 0x3e0e0000, 0x8000,     Insn_Type_SYN,        s3_do_macro_la_rdi32},
    963   {"bcmpeqz",       0x0000004c, 0x3e00007e, 0x8000,     Insn_BCMP,        s3_do_macro_bcmpz},
    964   {"bcmpeq",       0x0000004c, 0x3e00007e, 0x8000,     Insn_BCMP,        s3_do_macro_bcmp},
    965   {"bcmpnez",       0x0000004e, 0x3e00007e, 0x8000,     Insn_BCMP,        s3_do_macro_bcmpz},
    966   {"bcmpne",       0x0000004e, 0x3e00007e, 0x8000,     Insn_BCMP,        s3_do_macro_bcmp},
    967   {"div",       0x00000044, 0x3e0003ff, 0x8000,     Insn_Type_SYN,        s3_do_macro_mul_rdrsrs},
    968   {"divu",      0x00000046, 0x3e0003ff, 0x8000,     Insn_Type_SYN,        s3_do_macro_mul_rdrsrs},
    969   {"rem",       0x00000044, 0x3e0003ff, 0x8000,     Insn_Type_SYN,        s3_do_macro_mul_rdrsrs},
    970   {"remu",      0x00000046, 0x3e0003ff, 0x8000,     Insn_Type_SYN,        s3_do_macro_mul_rdrsrs},
    971   {"mul",       0x00000040, 0x3e0003ff, 0x8000,     Insn_Type_SYN,        s3_do_macro_mul_rdrsrs},
    972   {"mulu",      0x00000042, 0x3e0003ff, 0x8000,     Insn_Type_SYN,        s3_do_macro_mul_rdrsrs},
    973   {"maz",       0x00000040, 0x3e0003ff, 0x8000,     Insn_Type_SYN,        s3_do_macro_mul_rdrsrs},
    974   {"mazu",      0x00000042, 0x3e0003ff, 0x8000,     Insn_Type_SYN,        s3_do_macro_mul_rdrsrs},
    975   {"mul.f",     0x00000041, 0x3e0003ff, 0x8000,     Insn_Type_SYN,        s3_do_macro_mul_rdrsrs},
    976   {"maz.f",     0x00000041, 0x3e0003ff, 0x8000,     Insn_Type_SYN,        s3_do_macro_mul_rdrsrs},
    977   {"lb",        INSN_LB,    0x00000000, 0x8000,     Insn_Type_SYN,        s3_do_macro_ldst_label},
    978   {"lbu",       INSN_LBU,   0x00000000, 0x8000,     Insn_Type_SYN,        s3_do_macro_ldst_label},
    979   {"lh",        INSN_LH,    0x00000000, 0x8000,     Insn_Type_SYN,        s3_do_macro_ldst_label},
    980   {"lhu",       INSN_LHU,   0x00000000, 0x8000,     Insn_Type_SYN,        s3_do_macro_ldst_label},
    981   {"lw",        INSN_LW,    0x00000000, 0x1000,     Insn_Type_SYN,        s3_do_macro_ldst_label},
    982   {"sb",        INSN_SB,    0x00000000, 0x8000,     Insn_Type_SYN,        s3_do_macro_ldst_label},
    983   {"sh",        INSN_SH,    0x00000000, 0x8000,     Insn_Type_SYN,        s3_do_macro_ldst_label},
    984   {"sw",        INSN_SW,    0x00000000, 0x2000,     Insn_Type_SYN,        s3_do_macro_ldst_label},
    985 
    986   /* Assembler use internal.  */
    987   {"ld_i32hi",  0x0a0c0000, 0x3e0e0000, 0x8000,     Insn_internal, s3_do_macro_rdi32hi},
    988   {"ld_i32lo",  0x020a0000, 0x3e0e0001, 0x8000,     Insn_internal, s3_do_macro_rdi32lo},
    989   {"ldis_pic",  0x0a0c0000, 0x3e0e0000, 0x8000,     Insn_internal, s3_do_rdi16_pic},
    990   {"addi_s_pic",0x02000000, 0x3e0e0001, 0x8000,     Insn_internal, s3_do_addi_s_pic},
    991   {"addi_u_pic",0x02000000, 0x3e0e0001, 0x8000,     Insn_internal, s3_do_addi_u_pic},
    992   {"lw_pic",    0x20000000, 0x3e000000, 0x8000,     Insn_internal, s3_do_lw_pic},
    993 
    994   /* 48-bit instructions.  */
    995   {"sdbbp48",   0x000000000000LL,   0x1c000000001fLL,   0x8000,     Rd_I32,    s3_do_sdbbp48},
    996   {"ldi48",     0x000000000001LL,   0x1c000000001fLL,   0x8000,     Rd_I32,    s3_do_ldi48},
    997   {"lw48",      0x000000000002LL,   0x1c000000001fLL,   0x8000,     Rd_I30,    s3_do_lw48},
    998   {"sw48",      0x000000000003LL,   0x1c000000001fLL,   0x8000,     Rd_I30,    s3_do_sw48},
    999   {"andri48",   0x040000000000LL,   0x1c0000000003LL,   0x8000,     Rd_I32,    s3_do_and48},
   1000   {"andri48.c", 0x040000000001LL,   0x1c0000000003LL,   0x8000,     Rd_I32,    s3_do_and48},
   1001   {"orri48",    0x040000000002LL,   0x1c0000000003LL,   0x8000,     Rd_I32,    s3_do_or48},
   1002   {"orri48.c",  0x040000000003LL,   0x1c0000000003LL,   0x8000,     Rd_I32,    s3_do_or48},
   1003 };
   1004 
   1005 #define s3_SCORE3_PIPELINE 3
   1006 
   1007 static int s3_university_version = 0;
   1008 static int s3_vector_size = s3_SCORE3_PIPELINE;
   1009 static struct s3_score_it s3_dependency_vector[s3_SCORE3_PIPELINE];
   1010 
   1011 static int s3_score3d = 1;
   1012 
   1013 static int
   1014 s3_end_of_line (char *str)
   1015 {
   1016   int retval = s3_SUCCESS;
   1017 
   1018   s3_skip_whitespace (str);
   1019   if (*str != '\0')
   1020     {
   1021       retval = (int) s3_FAIL;
   1022 
   1023       if (!s3_inst.error)
   1024         s3_inst.error = s3_BAD_GARBAGE;
   1025     }
   1026 
   1027   return retval;
   1028 }
   1029 
   1030 static int
   1031 s3_score_reg_parse (char **ccp, struct hash_control *htab)
   1032 {
   1033   char *start = *ccp;
   1034   char c;
   1035   char *p;
   1036   struct s3_reg_entry *reg;
   1037 
   1038   p = start;
   1039   if (!ISALPHA (*p) || !is_name_beginner (*p))
   1040     return (int) s3_FAIL;
   1041 
   1042   c = *p++;
   1043 
   1044   while (ISALPHA (c) || ISDIGIT (c) || c == '_')
   1045     c = *p++;
   1046 
   1047   *--p = 0;
   1048   reg = (struct s3_reg_entry *) hash_find (htab, start);
   1049   *p = c;
   1050 
   1051   if (reg)
   1052     {
   1053       *ccp = p;
   1054       return reg->number;
   1055     }
   1056   return (int) s3_FAIL;
   1057 }
   1058 
   1059 /* If shift <= 0, only return reg.  */
   1060 
   1061 static int
   1062 s3_reg_required_here (char **str, int shift, enum s3_score_reg_type reg_type)
   1063 {
   1064   static char buff[s3_MAX_LITERAL_POOL_SIZE];
   1065   int reg = (int) s3_FAIL;
   1066   char *start = *str;
   1067 
   1068   if ((reg = s3_score_reg_parse (str, s3_all_reg_maps[reg_type].htab)) != (int) s3_FAIL)
   1069     {
   1070       if (reg_type == s3_REG_TYPE_SCORE)
   1071         {
   1072           if ((reg == 1) && (s3_nor1 == 1) && (s3_inst.bwarn == 0))
   1073             {
   1074               as_warn (_("Using temp register(r1)"));
   1075               s3_inst.bwarn = 1;
   1076             }
   1077         }
   1078       if (shift >= 0)
   1079 	{
   1080           if (reg_type == s3_REG_TYPE_SCORE_CR)
   1081 	    strcpy (s3_inst.reg, s3_score_crn_table[reg].name);
   1082           else if (reg_type == s3_REG_TYPE_SCORE_SR)
   1083 	    strcpy (s3_inst.reg, s3_score_srn_table[reg].name);
   1084           else
   1085 	    strcpy (s3_inst.reg, "");
   1086 
   1087           s3_inst.instruction |= (bfd_vma) reg << shift;
   1088 	}
   1089     }
   1090   else
   1091     {
   1092       *str = start;
   1093       sprintf (buff, _("register expected, not '%.100s'"), start);
   1094       s3_inst.error = buff;
   1095     }
   1096 
   1097   return reg;
   1098 }
   1099 
   1100 static int
   1101 s3_skip_past_comma (char **str)
   1102 {
   1103   char *p = *str;
   1104   char c;
   1105   int comma = 0;
   1106 
   1107   while ((c = *p) == ' ' || c == ',')
   1108     {
   1109       p++;
   1110       if (c == ',' && comma++)
   1111         {
   1112           s3_inst.error = s3_BAD_SKIP_COMMA;
   1113           return (int) s3_FAIL;
   1114         }
   1115     }
   1116 
   1117   if ((c == '\0') || (comma == 0))
   1118     {
   1119       s3_inst.error = s3_BAD_SKIP_COMMA;
   1120       return (int) s3_FAIL;
   1121     }
   1122 
   1123   *str = p;
   1124   return comma ? s3_SUCCESS : (int) s3_FAIL;
   1125 }
   1126 
   1127 static void
   1128 s3_do_rdrsrs (char *str)
   1129 {
   1130   int reg;
   1131   s3_skip_whitespace (str);
   1132 
   1133   if ((reg = s3_reg_required_here (&str, 20, s3_REG_TYPE_SCORE)) == (int) s3_FAIL
   1134       || s3_skip_past_comma (&str) == (int) s3_FAIL
   1135       || s3_reg_required_here (&str, 15, s3_REG_TYPE_SCORE) == (int) s3_FAIL
   1136       || s3_skip_past_comma (&str) == (int) s3_FAIL
   1137       || s3_reg_required_here (&str, 10, s3_REG_TYPE_SCORE) == (int) s3_FAIL
   1138       || s3_end_of_line (str) == (int) s3_FAIL)
   1139     {
   1140       return;
   1141     }
   1142   else
   1143     {
   1144       /* Check mulr, mulur rd is even number.  */
   1145       if (((s3_inst.instruction & 0x3e0003ff) == 0x00000340
   1146 	   || (s3_inst.instruction & 0x3e0003ff) == 0x00000342)
   1147           && (reg % 2))
   1148         {
   1149           s3_inst.error = _("rd must be even number.");
   1150           return;
   1151         }
   1152 
   1153       if ((((s3_inst.instruction >> 15) & 0x10) == 0)
   1154           && (((s3_inst.instruction >> 10) & 0x10) == 0)
   1155           && (((s3_inst.instruction >> 20) & 0x10) == 0)
   1156           && (s3_inst.relax_inst != 0x8000)
   1157           && (((s3_inst.instruction >> 20) & 0xf) == ((s3_inst.instruction >> 15) & 0xf)))
   1158         {
   1159           s3_inst.relax_inst |= (((s3_inst.instruction >> 10) & 0xf) )
   1160             | (((s3_inst.instruction >> 15) & 0xf) << 4);
   1161           s3_inst.relax_size = 2;
   1162         }
   1163       else
   1164         {
   1165           s3_inst.relax_inst = 0x8000;
   1166         }
   1167     }
   1168 }
   1169 
   1170 static int
   1171 s3_walk_no_bignums (symbolS * sp)
   1172 {
   1173   if (symbol_get_value_expression (sp)->X_op == O_big)
   1174     return 1;
   1175 
   1176   if (symbol_get_value_expression (sp)->X_add_symbol)
   1177     return (s3_walk_no_bignums (symbol_get_value_expression (sp)->X_add_symbol)
   1178 	    || (symbol_get_value_expression (sp)->X_op_symbol
   1179 		&& s3_walk_no_bignums (symbol_get_value_expression (sp)->X_op_symbol)));
   1180 
   1181   return 0;
   1182 }
   1183 
   1184 static int
   1185 s3_my_get_expression (expressionS * ep, char **str)
   1186 {
   1187   char *save_in;
   1188 
   1189   save_in = input_line_pointer;
   1190   input_line_pointer = *str;
   1191   s3_in_my_get_expression = 1;
   1192   (void) expression (ep);
   1193   s3_in_my_get_expression = 0;
   1194 
   1195   if (ep->X_op == O_illegal)
   1196     {
   1197       *str = input_line_pointer;
   1198       input_line_pointer = save_in;
   1199       s3_inst.error = _("illegal expression");
   1200       return (int) s3_FAIL;
   1201     }
   1202   /* Get rid of any bignums now, so that we don't generate an error for which
   1203      we can't establish a line number later on.  Big numbers are never valid
   1204      in instructions, which is where this routine is always called.  */
   1205   if (ep->X_op == O_big
   1206       || (ep->X_add_symbol
   1207           && (s3_walk_no_bignums (ep->X_add_symbol)
   1208               || (ep->X_op_symbol && s3_walk_no_bignums (ep->X_op_symbol)))))
   1209     {
   1210       s3_inst.error = _("invalid constant");
   1211       *str = input_line_pointer;
   1212       input_line_pointer = save_in;
   1213       return (int) s3_FAIL;
   1214     }
   1215 
   1216   if ((ep->X_add_symbol != NULL)
   1217       && (s3_inst.type != PC_DISP19div2)
   1218       && (s3_inst.type != PC_DISP8div2)
   1219       && (s3_inst.type != PC_DISP24div2)
   1220       && (s3_inst.type != PC_DISP11div2)
   1221       && (s3_inst.type != Insn_Type_SYN)
   1222       && (s3_inst.type != Rd_rvalueRs_SI15)
   1223       && (s3_inst.type != Rd_lvalueRs_SI15)
   1224       && (s3_inst.type != Insn_internal)
   1225       && (s3_inst.type != Rd_I30)
   1226       && (s3_inst.type != Rd_I32)
   1227       && (s3_inst.type != Insn_BCMP))
   1228     {
   1229       s3_inst.error = s3_BAD_ARGS;
   1230       *str = input_line_pointer;
   1231       input_line_pointer = save_in;
   1232       return (int) s3_FAIL;
   1233     }
   1234 
   1235   *str = input_line_pointer;
   1236   input_line_pointer = save_in;
   1237   return s3_SUCCESS;
   1238 }
   1239 
   1240 /* Check if an immediate is valid.  If so, convert it to the right format.  */
   1241 static bfd_signed_vma
   1242 s3_validate_immediate (bfd_signed_vma val, unsigned int data_type, int hex_p)
   1243 {
   1244   switch (data_type)
   1245     {
   1246     case _VALUE_HI16:
   1247       {
   1248         bfd_signed_vma val_hi = ((val & 0xffff0000) >> 16);
   1249 
   1250         if (s3_score_df_range[data_type].range[0] <= val_hi
   1251             && val_hi <= s3_score_df_range[data_type].range[1])
   1252 	  return val_hi;
   1253       }
   1254       break;
   1255 
   1256     case _VALUE_LO16:
   1257       {
   1258         bfd_signed_vma val_lo = (val & 0xffff);
   1259 
   1260         if (s3_score_df_range[data_type].range[0] <= val_lo
   1261             && val_lo <= s3_score_df_range[data_type].range[1])
   1262 	  return val_lo;
   1263       }
   1264       break;
   1265 
   1266     case _SIMM14:
   1267       if (hex_p == 1)
   1268         {
   1269           if (!(val >= -0x2000 && val <= 0x3fff))
   1270             {
   1271               return (int) s3_FAIL;
   1272             }
   1273         }
   1274       else
   1275         {
   1276           if (!(val >= -8192 && val <= 8191))
   1277             {
   1278               return (int) s3_FAIL;
   1279             }
   1280         }
   1281 
   1282       return val;
   1283       break;
   1284 
   1285     case _SIMM16_NEG:
   1286       if (hex_p == 1)
   1287         {
   1288           if (!(val >= -0x7fff && val <= 0xffff && val != 0x8000))
   1289             {
   1290               return (int) s3_FAIL;
   1291             }
   1292         }
   1293       else
   1294         {
   1295           if (!(val >= -32767 && val <= 32768))
   1296             {
   1297               return (int) s3_FAIL;
   1298             }
   1299         }
   1300 
   1301       val = -val;
   1302       return val;
   1303       break;
   1304 
   1305     case _IMM5_MULTI_LOAD:
   1306       if (val >= 2 && val <= 32)
   1307         {
   1308           if (val == 32)
   1309 	    val = 0;
   1310           return val;
   1311         }
   1312       return (int) s3_FAIL;
   1313 
   1314     case _IMM32:
   1315       if (val >= 0 && val <= 0xffffffff)
   1316         {
   1317           return val;
   1318         }
   1319       else
   1320         {
   1321           return (int) s3_FAIL;
   1322         }
   1323 
   1324     default:
   1325       if (data_type == _SIMM14_NEG || data_type == _IMM16_NEG)
   1326 	val = -val;
   1327 
   1328       if (s3_score_df_range[data_type].range[0] <= val
   1329           && val <= s3_score_df_range[data_type].range[1])
   1330 	return val;
   1331 
   1332       break;
   1333     }
   1334 
   1335   return (int) s3_FAIL;
   1336 }
   1337 
   1338 static int
   1339 s3_data_op2 (char **str, int shift, enum score_data_type data_type)
   1340 {
   1341   bfd_signed_vma value;
   1342   char data_exp[s3_MAX_LITERAL_POOL_SIZE];
   1343   char *dataptr;
   1344   int cnt = 0;
   1345   char *pp = NULL;
   1346 
   1347   s3_skip_whitespace (*str);
   1348   s3_inst.error = NULL;
   1349   dataptr = * str;
   1350 
   1351   /* Set hex_p to zero.  */
   1352   int hex_p = 0;
   1353 
   1354   while ((*dataptr != '\0') && (*dataptr != '|') && (cnt <= s3_MAX_LITERAL_POOL_SIZE))     /* 0x7c = ='|' */
   1355     {
   1356       data_exp[cnt] = *dataptr;
   1357       dataptr++;
   1358       cnt++;
   1359     }
   1360 
   1361   data_exp[cnt] = '\0';
   1362   pp = (char *)&data_exp;
   1363 
   1364   if (*dataptr == '|')          /* process PCE */
   1365     {
   1366       if (s3_my_get_expression (&s3_inst.reloc.exp, &pp) == (int) s3_FAIL)
   1367         return (int) s3_FAIL;
   1368       s3_end_of_line (pp);
   1369       if (s3_inst.error != 0)
   1370         return (int) s3_FAIL;       /* to ouptut_inst to printf out the error */
   1371       *str = dataptr;
   1372     }
   1373   else                          /* process  16 bit */
   1374     {
   1375       if (s3_my_get_expression (&s3_inst.reloc.exp, str) == (int) s3_FAIL)
   1376         {
   1377           return (int) s3_FAIL;
   1378         }
   1379 
   1380       dataptr = (char *)data_exp;
   1381       for (; *dataptr != '\0'; dataptr++)
   1382         {
   1383           *dataptr = TOLOWER (*dataptr);
   1384           if (*dataptr == '!' || *dataptr == ' ')
   1385             break;
   1386         }
   1387       dataptr = (char *)data_exp;
   1388 
   1389       if ((dataptr != NULL)
   1390           && (((strstr (dataptr, "0x")) != NULL)
   1391               || ((strstr (dataptr, "0X")) != NULL)))
   1392         {
   1393           hex_p = 1;
   1394           if ((data_type != _SIMM16_LA)
   1395               && (data_type != _VALUE_HI16)
   1396               && (data_type != _VALUE_LO16)
   1397               && (data_type != _IMM16)
   1398               && (data_type != _IMM15)
   1399               && (data_type != _IMM14)
   1400               && (data_type != _IMM4)
   1401               && (data_type != _IMM5)
   1402               && (data_type != _IMM5_MULTI_LOAD)
   1403               && (data_type != _IMM11)
   1404               && (data_type != _IMM8)
   1405               && (data_type != _IMM5_RSHIFT_1)
   1406               && (data_type != _IMM5_RSHIFT_2)
   1407               && (data_type != _SIMM14)
   1408               && (data_type != _SIMM14_NEG)
   1409               && (data_type != _SIMM16_NEG)
   1410               && (data_type != _IMM10_RSHIFT_2)
   1411               && (data_type != _GP_IMM15)
   1412               && (data_type != _SIMM5)
   1413               && (data_type != _SIMM6)
   1414               && (data_type != _IMM32)
   1415               && (data_type != _SIMM32))
   1416             {
   1417               data_type += 24;
   1418             }
   1419         }
   1420 
   1421       if ((s3_inst.reloc.exp.X_add_number == 0)
   1422           && (s3_inst.type != Insn_Type_SYN)
   1423           && (s3_inst.type != Rd_rvalueRs_SI15)
   1424           && (s3_inst.type != Rd_lvalueRs_SI15)
   1425           && (s3_inst.type != Insn_internal)
   1426           && (((*dataptr >= 'a') && (*dataptr <= 'z'))
   1427 	      || ((*dataptr == '0') && (*(dataptr + 1) == 'x') && (*(dataptr + 2) != '0'))
   1428 	      || ((*dataptr == '+') && (*(dataptr + 1) != '0'))
   1429 	      || ((*dataptr == '-') && (*(dataptr + 1) != '0'))))
   1430         {
   1431           s3_inst.error = s3_BAD_ARGS;
   1432           return (int) s3_FAIL;
   1433         }
   1434     }
   1435 
   1436   if ((s3_inst.reloc.exp.X_add_symbol)
   1437       && ((data_type == _SIMM16)
   1438           || (data_type == _SIMM16_NEG)
   1439           || (data_type == _IMM16_NEG)
   1440           || (data_type == _SIMM14)
   1441           || (data_type == _SIMM14_NEG)
   1442           || (data_type == _IMM5)
   1443           || (data_type == _IMM5_MULTI_LOAD)
   1444           || (data_type == _IMM11)
   1445           || (data_type == _IMM14)
   1446           || (data_type == _IMM20)
   1447           || (data_type == _IMM16)
   1448           || (data_type == _IMM15)
   1449           || (data_type == _IMM4)))
   1450     {
   1451       s3_inst.error = s3_BAD_ARGS;
   1452       return (int) s3_FAIL;
   1453     }
   1454 
   1455   if (s3_inst.reloc.exp.X_add_symbol)
   1456     {
   1457       switch (data_type)
   1458         {
   1459         case _SIMM16_LA:
   1460           return (int) s3_FAIL;
   1461         case _VALUE_HI16:
   1462           s3_inst.reloc.type = BFD_RELOC_HI16_S;
   1463           s3_inst.reloc.pc_rel = 0;
   1464           break;
   1465         case _VALUE_LO16:
   1466           s3_inst.reloc.type = BFD_RELOC_LO16;
   1467           s3_inst.reloc.pc_rel = 0;
   1468           break;
   1469         case _GP_IMM15:
   1470           s3_inst.reloc.type = BFD_RELOC_SCORE_GPREL15;
   1471           s3_inst.reloc.pc_rel = 0;
   1472           break;
   1473         case _SIMM16_pic:
   1474         case _IMM16_LO16_pic:
   1475           s3_inst.reloc.type = BFD_RELOC_SCORE_GOT_LO16;
   1476           s3_inst.reloc.pc_rel = 0;
   1477           break;
   1478         default:
   1479           s3_inst.reloc.type = BFD_RELOC_32;
   1480           s3_inst.reloc.pc_rel = 0;
   1481           break;
   1482         }
   1483     }
   1484   else
   1485     {
   1486       if (data_type == _IMM16_pic)
   1487 	{
   1488           s3_inst.reloc.type = BFD_RELOC_SCORE_DUMMY_HI16;
   1489           s3_inst.reloc.pc_rel = 0;
   1490 	}
   1491 
   1492       if (data_type == _SIMM16_LA && s3_inst.reloc.exp.X_unsigned == 1)
   1493         {
   1494           value = s3_validate_immediate (s3_inst.reloc.exp.X_add_number, _SIMM16_LA_POS, hex_p);
   1495           if (value == (int) s3_FAIL)       /* for advance to check if this is ldis */
   1496             if ((s3_inst.reloc.exp.X_add_number & 0xffff) == 0)
   1497               {
   1498                 s3_inst.instruction |= 0x8000000;
   1499                 s3_inst.instruction |= ((s3_inst.reloc.exp.X_add_number >> 16) << 1) & 0x1fffe;
   1500                 return s3_SUCCESS;
   1501               }
   1502         }
   1503       else
   1504         {
   1505           value = s3_validate_immediate (s3_inst.reloc.exp.X_add_number, data_type, hex_p);
   1506         }
   1507 
   1508       if (value == (int) s3_FAIL)
   1509         {
   1510           if (data_type == _IMM32)
   1511             {
   1512               sprintf (s3_err_msg,
   1513                        _("invalid constant: %d bit expression not in range %u..%u"),
   1514                        s3_score_df_range[data_type].bits,
   1515                        0, (unsigned)0xffffffff);
   1516             }
   1517           else if (data_type == _IMM5_MULTI_LOAD)
   1518             {
   1519               sprintf (s3_err_msg,
   1520                        _("invalid constant: %d bit expression not in range %u..%u"),
   1521                        5, 2, 32);
   1522             }
   1523           else if ((data_type != _SIMM14_NEG) && (data_type != _SIMM16_NEG) && (data_type != _IMM16_NEG))
   1524             {
   1525               sprintf (s3_err_msg,
   1526                        _("invalid constant: %d bit expression not in range %d..%d"),
   1527                        s3_score_df_range[data_type].bits,
   1528                        s3_score_df_range[data_type].range[0], s3_score_df_range[data_type].range[1]);
   1529             }
   1530           else
   1531             {
   1532               sprintf (s3_err_msg,
   1533                        _("invalid constant: %d bit expression not in range %d..%d"),
   1534                        s3_score_df_range[data_type].bits,
   1535                        -s3_score_df_range[data_type].range[1], -s3_score_df_range[data_type].range[0]);
   1536             }
   1537 
   1538           s3_inst.error = s3_err_msg;
   1539           return (int) s3_FAIL;
   1540         }
   1541 
   1542       if (((s3_score_df_range[data_type].range[0] != 0) || (data_type == _IMM5_RANGE_8_31))
   1543           && data_type != _IMM5_MULTI_LOAD)
   1544         {
   1545           value &= (1 << s3_score_df_range[data_type].bits) - 1;
   1546         }
   1547 
   1548       s3_inst.instruction |= value << shift;
   1549     }
   1550 
   1551   if ((s3_inst.instruction & 0x3e000000) == 0x30000000)
   1552     {
   1553       if ((((s3_inst.instruction >> 20) & 0x1F) != 0)
   1554           && (((s3_inst.instruction >> 20) & 0x1F) != 1)
   1555           && (((s3_inst.instruction >> 20) & 0x1F) != 2)
   1556           && (((s3_inst.instruction >> 20) & 0x1F) != 0x10))
   1557         {
   1558           s3_inst.error = _("invalid constant: bit expression not defined");
   1559           return (int) s3_FAIL;
   1560         }
   1561     }
   1562 
   1563   return s3_SUCCESS;
   1564 }
   1565 
   1566 /* Handle addi/addi.c/addis.c/cmpi.c/addis.c/ldi.  */
   1567 static void
   1568 s3_do_rdsi16 (char *str)
   1569 {
   1570   s3_skip_whitespace (str);
   1571 
   1572   if (s3_reg_required_here (&str, 20, s3_REG_TYPE_SCORE) == (int) s3_FAIL
   1573       || s3_skip_past_comma (&str) == (int) s3_FAIL
   1574       || s3_data_op2 (&str, 1, _SIMM16) == (int) s3_FAIL
   1575       || s3_end_of_line (str) == (int) s3_FAIL)
   1576     return;
   1577 
   1578   /* ldi.->ldiu! only for imm5  */
   1579   if ((s3_inst.instruction & 0x20c0000) == 0x20c0000)
   1580     {
   1581       if  ((s3_inst.instruction & 0x1ffc0) != 0)
   1582         {
   1583           s3_inst.relax_inst = 0x8000;
   1584         }
   1585       else
   1586         {
   1587           s3_inst.relax_inst |= (s3_inst.instruction >> 1) & 0x1f;
   1588           s3_inst.relax_inst |= (((s3_inst.instruction >> 20)& 0x1f)  <<5);
   1589           s3_inst.relax_size = 2;
   1590         }
   1591     }
   1592   /*cmpi.c */
   1593   else  if ((s3_inst.instruction & 0x02040001) == 0x02040001)
   1594     {
   1595       /*  imm <=0x3f  (5 bit<<1)*/
   1596       if (((s3_inst.instruction & 0x1ffe0) == 0)
   1597 	  || (((s3_inst.instruction & 0x1ffe0) == 0x1ffe0)
   1598 	      && (s3_inst.instruction & 0x003e) != 0))
   1599         {
   1600           s3_inst.relax_inst |= (s3_inst.instruction >> 1) & 0x1f;
   1601           s3_inst.relax_inst |= (((s3_inst.instruction >> 20) & 0x1f) << 5);
   1602           s3_inst.relax_size = 2;
   1603         }
   1604       else
   1605         {
   1606           s3_inst.relax_inst =0x8000;
   1607 
   1608         }
   1609     }
   1610   /* addi */
   1611   else  if (((s3_inst.instruction & 0x2000000) == 0x02000000) && (s3_inst.relax_inst!=0x8000))
   1612     {
   1613       /* rd : 0-16 ; imm <=0x7f  (6 bit<<1)*/
   1614       if ((((s3_inst.instruction >> 20) & 0x10) != 0x10)
   1615 	  && (((s3_inst.instruction & 0x1ffc0) == 0)
   1616 	      || (((s3_inst.instruction & 0x1ffc0) == 0x1ffc0)
   1617 		  && (s3_inst.instruction & 0x007e) != 0)))
   1618         {
   1619           s3_inst.relax_inst |= (s3_inst.instruction >> 1) & 0x3f;
   1620           s3_inst.relax_inst |= (((s3_inst.instruction >> 20) & 0xf) << 6);
   1621           s3_inst.relax_size = 2;
   1622         }
   1623       else
   1624         {
   1625           s3_inst.relax_inst =0x8000;
   1626         }
   1627     }
   1628 
   1629   else if (((s3_inst.instruction >> 20) & 0x10) == 0x10)
   1630     {
   1631       s3_inst.relax_inst = 0x8000;
   1632     }
   1633 }
   1634 
   1635 static void
   1636 s3_do_ldis (char *str)
   1637 {
   1638   s3_skip_whitespace (str);
   1639 
   1640   if (s3_reg_required_here (&str, 20, s3_REG_TYPE_SCORE) == (int) s3_FAIL
   1641       || s3_skip_past_comma (&str) == (int) s3_FAIL
   1642       || s3_data_op2 (&str, 1, _IMM16) == (int) s3_FAIL
   1643       || s3_end_of_line (str) == (int) s3_FAIL)
   1644     return;
   1645 }
   1646 
   1647 /* Handle subi/subi.c.  */
   1648 static void
   1649 s3_do_sub_rdsi16 (char *str)
   1650 {
   1651   s3_skip_whitespace (str);
   1652 
   1653   if (s3_reg_required_here (&str, 20, s3_REG_TYPE_SCORE) != (int) s3_FAIL
   1654       && s3_skip_past_comma (&str) != (int) s3_FAIL
   1655       && s3_data_op2 (&str, 1, _SIMM16_NEG) != (int) s3_FAIL)
   1656     s3_end_of_line (str);
   1657 }
   1658 
   1659 /* Handle subis/subis.c.  */
   1660 static void
   1661 s3_do_sub_rdi16 (char *str)
   1662 {
   1663   s3_skip_whitespace (str);
   1664 
   1665   if (s3_reg_required_here (&str, 20, s3_REG_TYPE_SCORE) != (int) s3_FAIL
   1666       && s3_skip_past_comma (&str) != (int) s3_FAIL
   1667       && s3_data_op2 (&str, 1, _IMM16_NEG) != (int) s3_FAIL)
   1668     s3_end_of_line (str);
   1669 }
   1670 
   1671 /* Handle addri/addri.c.  */
   1672 static void
   1673 s3_do_rdrssi14 (char *str)         /* -(2^13)~((2^13)-1) */
   1674 {
   1675   s3_skip_whitespace (str);
   1676 
   1677   if (s3_reg_required_here (&str, 20, s3_REG_TYPE_SCORE) != (int) s3_FAIL
   1678       && s3_skip_past_comma (&str) != (int) s3_FAIL
   1679       && s3_reg_required_here (&str, 15, s3_REG_TYPE_SCORE) != (int) s3_FAIL
   1680       && s3_skip_past_comma (&str) != (int) s3_FAIL)
   1681     s3_data_op2 (&str, 1, _SIMM14);
   1682 }
   1683 
   1684 /* Handle subri.c/subri.  */
   1685 static void
   1686 s3_do_sub_rdrssi14 (char *str)     /* -(2^13)~((2^13)-1) */
   1687 {
   1688   s3_skip_whitespace (str);
   1689 
   1690   if (s3_reg_required_here (&str, 20, s3_REG_TYPE_SCORE) != (int) s3_FAIL
   1691       && s3_skip_past_comma (&str) != (int) s3_FAIL
   1692       && s3_reg_required_here (&str, 15, s3_REG_TYPE_SCORE) != (int) s3_FAIL
   1693       && s3_skip_past_comma (&str) != (int) s3_FAIL
   1694       && s3_data_op2 (&str, 1, _SIMM14_NEG) != (int) s3_FAIL)
   1695     s3_end_of_line (str);
   1696 }
   1697 
   1698 /* Handle bitclr.c/bitset.c/bittgl.c/slli.c/srai.c/srli.c/roli.c/rori.c/rolic.c.
   1699    0~((2^14)-1) */
   1700 static void
   1701 s3_do_rdrsi5 (char *str)
   1702 {
   1703   s3_skip_whitespace (str);
   1704 
   1705   if (s3_reg_required_here (&str, 20, s3_REG_TYPE_SCORE) == (int) s3_FAIL
   1706       || s3_skip_past_comma (&str) == (int) s3_FAIL
   1707       || s3_reg_required_here (&str, 15, s3_REG_TYPE_SCORE) == (int) s3_FAIL
   1708       || s3_skip_past_comma (&str) == (int) s3_FAIL
   1709       || s3_data_op2 (&str, 10, _IMM5) == (int) s3_FAIL
   1710       || s3_end_of_line (str) == (int) s3_FAIL)
   1711     return;
   1712 
   1713   if ((((s3_inst.instruction >> 20) & 0x1f) == ((s3_inst.instruction >> 15) & 0x1f))
   1714       && (s3_inst.relax_inst != 0x8000) && (((s3_inst.instruction >> 15) & 0x10) == 0))
   1715     {
   1716       s3_inst.relax_inst |= (((s3_inst.instruction >> 10) & 0x1f) ) | (((s3_inst.instruction >> 15) & 0xf) << 5);
   1717       s3_inst.relax_size = 2;
   1718     }
   1719   else
   1720     s3_inst.relax_inst = 0x8000;
   1721 }
   1722 
   1723 /* Handle andri/orri/andri.c/orri.c.
   1724    0 ~ ((2^14)-1)  */
   1725 static void
   1726 s3_do_rdrsi14 (char *str)
   1727 {
   1728   s3_skip_whitespace (str);
   1729 
   1730   if (s3_reg_required_here (&str, 20, s3_REG_TYPE_SCORE) != (int) s3_FAIL
   1731       && s3_skip_past_comma (&str) != (int) s3_FAIL
   1732       && s3_reg_required_here (&str, 15, s3_REG_TYPE_SCORE) != (int) s3_FAIL
   1733       && s3_skip_past_comma (&str) != (int) s3_FAIL
   1734       && s3_data_op2 (&str, 1, _IMM14) != (int) s3_FAIL)
   1735     s3_end_of_line (str);
   1736 }
   1737 
   1738 /* Handle bittst.c.  */
   1739 static void
   1740 s3_do_xrsi5 (char *str)
   1741 {
   1742   s3_skip_whitespace (str);
   1743 
   1744   if (s3_reg_required_here (&str, 15, s3_REG_TYPE_SCORE) == (int) s3_FAIL
   1745       || s3_skip_past_comma (&str) == (int) s3_FAIL
   1746       || s3_data_op2 (&str, 10, _IMM5) == (int) s3_FAIL
   1747       || s3_end_of_line (str) == (int) s3_FAIL)
   1748     return;
   1749 
   1750   if ((s3_inst.relax_inst != 0x8000) && (((s3_inst.instruction >> 15) & 0x10) == 0))
   1751     {
   1752       s3_inst.relax_inst |= ((s3_inst.instruction >> 10) & 0x1f)  | (((s3_inst.instruction >> 15) & 0xf) << 5);
   1753       s3_inst.relax_size = 2;
   1754     }
   1755   else
   1756     s3_inst.relax_inst = 0x8000;
   1757 }
   1758 
   1759 /* Handle addis/andi/ori/andis/oris/ldis.  */
   1760 static void
   1761 s3_do_rdi16 (char *str)
   1762 {
   1763   s3_skip_whitespace (str);
   1764 
   1765   if (s3_reg_required_here (&str, 20, s3_REG_TYPE_SCORE) == (int) s3_FAIL
   1766       || s3_skip_past_comma (&str) == (int) s3_FAIL
   1767       || s3_data_op2 (&str, 1, _IMM16) == (int) s3_FAIL
   1768       || s3_end_of_line (str) == (int) s3_FAIL)
   1769     return;
   1770 
   1771   /* ldis */
   1772   if ((s3_inst.instruction & 0x3e0e0000) == 0x0a0c0000)
   1773     {
   1774       /* rd : 0-16 ;imm =0 -> can transform to addi!*/
   1775       if ((((s3_inst.instruction >> 20) & 0x10) != 0x10) && ((s3_inst.instruction & 0x1ffff)==0))
   1776         {
   1777           s3_inst.relax_inst =0x5400; /* ldiu! */
   1778           s3_inst.relax_inst |= (s3_inst.instruction >> 1) & 0x1f;
   1779           s3_inst.relax_inst |= (((s3_inst.instruction >> 20) & 0xf) << 5);
   1780           s3_inst.relax_size = 2;
   1781         }
   1782       else
   1783         {
   1784           s3_inst.relax_inst =0x8000;
   1785 
   1786         }
   1787     }
   1788 
   1789   /* addis */
   1790   else if ((s3_inst.instruction & 0x3e0e0001) == 0x0a000000)
   1791     {
   1792       /* rd : 0-16 ;imm =0 -> can transform to addi!*/
   1793       if ((((s3_inst.instruction >> 20) & 0x10) != 0x10) && ((s3_inst.instruction & 0x1ffff)==0))
   1794         {
   1795 	  s3_inst.relax_inst =0x5c00; /* addi! */
   1796           s3_inst.relax_inst |= (s3_inst.instruction >> 1) & 0x3f;
   1797           s3_inst.relax_inst |= (((s3_inst.instruction >> 20) & 0xf) << 6);
   1798           s3_inst.relax_size = 2;
   1799         }
   1800       else
   1801         {
   1802           s3_inst.relax_inst =0x8000;
   1803 
   1804         }
   1805     }
   1806 }
   1807 
   1808 static void
   1809 s3_do_macro_rdi32hi (char *str)
   1810 {
   1811   s3_skip_whitespace (str);
   1812 
   1813   /* Do not handle s3_end_of_line().  */
   1814   if (s3_reg_required_here (&str, 20, s3_REG_TYPE_SCORE) != (int) s3_FAIL
   1815       && s3_skip_past_comma (&str) != (int) s3_FAIL)
   1816     s3_data_op2 (&str, 1, _VALUE_HI16);
   1817 }
   1818 
   1819 static void
   1820 s3_do_macro_rdi32lo (char *str)
   1821 {
   1822   s3_skip_whitespace (str);
   1823 
   1824   /* Do not handle s3_end_of_line().  */
   1825   if (s3_reg_required_here (&str, 20, s3_REG_TYPE_SCORE) != (int) s3_FAIL
   1826       && s3_skip_past_comma (&str) != (int) s3_FAIL)
   1827     s3_data_op2 (&str, 1, _VALUE_LO16);
   1828 }
   1829 
   1830 /* Handle ldis_pic.  */
   1831 static void
   1832 s3_do_rdi16_pic (char *str)
   1833 {
   1834   s3_skip_whitespace (str);
   1835 
   1836   if (s3_reg_required_here (&str, 20, s3_REG_TYPE_SCORE) != (int) s3_FAIL
   1837       && s3_skip_past_comma (&str) != (int) s3_FAIL
   1838       && s3_data_op2 (&str, 1, _IMM16_pic) != (int) s3_FAIL)
   1839     s3_end_of_line (str);
   1840 }
   1841 
   1842 /* Handle addi_s_pic to generate R_SCORE_GOT_LO16 .  */
   1843 static void
   1844 s3_do_addi_s_pic (char *str)
   1845 {
   1846   s3_skip_whitespace (str);
   1847 
   1848   if (s3_reg_required_here (&str, 20, s3_REG_TYPE_SCORE) != (int) s3_FAIL
   1849       && s3_skip_past_comma (&str) != (int) s3_FAIL
   1850       && s3_data_op2 (&str, 1, _SIMM16_pic) != (int) s3_FAIL)
   1851     s3_end_of_line (str);
   1852 }
   1853 
   1854 /* Handle addi_u_pic to generate R_SCORE_GOT_LO16 .  */
   1855 static void
   1856 s3_do_addi_u_pic (char *str)
   1857 {
   1858   s3_skip_whitespace (str);
   1859 
   1860   if (s3_reg_required_here (&str, 20, s3_REG_TYPE_SCORE) != (int) s3_FAIL
   1861       && s3_skip_past_comma (&str) != (int) s3_FAIL
   1862       && s3_data_op2 (&str, 1, _IMM16_LO16_pic) != (int) s3_FAIL)
   1863     s3_end_of_line (str);
   1864 }
   1865 
   1866 /* Handle mfceh/mfcel/mtceh/mtchl.  */
   1867 static void
   1868 s3_do_rd (char *str)
   1869 {
   1870   s3_skip_whitespace (str);
   1871 
   1872   if (s3_reg_required_here (&str, 20, s3_REG_TYPE_SCORE) != (int) s3_FAIL)
   1873     s3_end_of_line (str);
   1874 }
   1875 
   1876 /* Handle br{cond},cmpzteq.c ,cmpztmi.c ,cmpz.c */
   1877 static void
   1878 s3_do_rs (char *str)
   1879 {
   1880   s3_skip_whitespace (str);
   1881 
   1882   if (s3_reg_required_here (&str, 15, s3_REG_TYPE_SCORE) == (int) s3_FAIL
   1883       || s3_end_of_line (str) == (int) s3_FAIL)
   1884     return;
   1885 
   1886   if ((s3_inst.relax_inst != 0x8000) )
   1887     {
   1888       s3_inst.relax_inst |=  ((s3_inst.instruction >> 15) &0x1f);
   1889       s3_inst.relax_size = 2;
   1890     }
   1891   else
   1892     s3_inst.relax_inst = 0x8000;
   1893 }
   1894 
   1895 static void
   1896 s3_do_i15 (char *str)
   1897 {
   1898   s3_skip_whitespace (str);
   1899 
   1900   if (s3_data_op2 (&str, 10, _IMM15) != (int) s3_FAIL)
   1901     s3_end_of_line (str);
   1902 }
   1903 
   1904 static void
   1905 s3_do_xi5x (char *str)
   1906 {
   1907   s3_skip_whitespace (str);
   1908 
   1909   if (s3_data_op2 (&str, 15, _IMM5) == (int) s3_FAIL || s3_end_of_line (str) == (int) s3_FAIL)
   1910     return;
   1911 
   1912   if (s3_inst.relax_inst != 0x8000)
   1913     {
   1914       s3_inst.relax_inst |= ((s3_inst.instruction >> 15) & 0x1f);
   1915       s3_inst.relax_size = 2;
   1916     }
   1917 }
   1918 
   1919 static void
   1920 s3_do_rdrs (char *str)
   1921 {
   1922   s3_skip_whitespace (str);
   1923 
   1924   if (s3_reg_required_here (&str, 20, s3_REG_TYPE_SCORE) == (int) s3_FAIL
   1925       || s3_skip_past_comma (&str) == (int) s3_FAIL
   1926       || s3_reg_required_here (&str, 15, s3_REG_TYPE_SCORE) == (int) s3_FAIL
   1927       || s3_end_of_line (str) == (int) s3_FAIL)
   1928     return;
   1929 
   1930   if (s3_inst.relax_inst != 0x8000)
   1931     {
   1932       if (((s3_inst.instruction & 0x7f) == 0x56))  /* adjust mv -> mv!*/
   1933         {
   1934           /* mv! rd : 5bit , ra : 5bit */
   1935           s3_inst.relax_inst |= ((s3_inst.instruction >> 15) & 0x1f)  | (((s3_inst.instruction >> 20) & 0x1f) << 5);
   1936           s3_inst.relax_size = 2;
   1937         }
   1938       else if ((((s3_inst.instruction >> 15) & 0x10) == 0x0) && (((s3_inst.instruction >> 20) & 0x10) == 0))
   1939         {
   1940           s3_inst.relax_inst |= (((s3_inst.instruction >> 15) & 0xf) << 4)
   1941             | (((s3_inst.instruction >> 20) & 0xf) << 8);
   1942           s3_inst.relax_size = 2;
   1943         }
   1944       else
   1945         {
   1946           s3_inst.relax_inst = 0x8000;
   1947         }
   1948     }
   1949 }
   1950 
   1951 /* Handle mfcr/mtcr.  */
   1952 static void
   1953 s3_do_rdcrs (char *str)
   1954 {
   1955   s3_skip_whitespace (str);
   1956 
   1957   if (s3_reg_required_here (&str, 20, s3_REG_TYPE_SCORE) != (int) s3_FAIL
   1958       && s3_skip_past_comma (&str) != (int) s3_FAIL
   1959       && s3_reg_required_here (&str, 15, s3_REG_TYPE_SCORE_CR) != (int) s3_FAIL)
   1960     s3_end_of_line (str);
   1961 }
   1962 
   1963 /* Handle mfsr/mtsr.  */
   1964 static void
   1965 s3_do_rdsrs (char *str)
   1966 {
   1967   s3_skip_whitespace (str);
   1968 
   1969   /* mfsr */
   1970   if ((s3_inst.instruction & 0xff) == 0x50)
   1971     {
   1972       if (s3_reg_required_here (&str, 20, s3_REG_TYPE_SCORE) != (int) s3_FAIL
   1973           && s3_skip_past_comma (&str) != (int) s3_FAIL
   1974           && s3_reg_required_here (&str, 10, s3_REG_TYPE_SCORE_SR) != (int) s3_FAIL)
   1975 	s3_end_of_line (str);
   1976     }
   1977   else
   1978     {
   1979       if (s3_reg_required_here (&str, 15, s3_REG_TYPE_SCORE) != (int) s3_FAIL
   1980           && s3_skip_past_comma (&str) != (int) s3_FAIL)
   1981 	s3_reg_required_here (&str, 10, s3_REG_TYPE_SCORE_SR);
   1982     }
   1983 }
   1984 
   1985 /* Handle neg.  */
   1986 static void
   1987 s3_do_rdxrs (char *str)
   1988 {
   1989   s3_skip_whitespace (str);
   1990 
   1991   if (s3_reg_required_here (&str, 20, s3_REG_TYPE_SCORE) == (int) s3_FAIL
   1992       || s3_skip_past_comma (&str) == (int) s3_FAIL
   1993       || s3_reg_required_here (&str, 10, s3_REG_TYPE_SCORE) == (int) s3_FAIL
   1994       || s3_end_of_line (str) == (int) s3_FAIL)
   1995     return;
   1996 
   1997   if ((s3_inst.relax_inst != 0x8000) && (((s3_inst.instruction >> 10) & 0x10) == 0)
   1998       && (((s3_inst.instruction >> 20) & 0x10) == 0))
   1999     {
   2000       s3_inst.relax_inst |= (((s3_inst.instruction >> 10) & 0xf) << 4) | (((s3_inst.instruction >> 20) & 0xf) << 8);
   2001       s3_inst.relax_size = 2;
   2002     }
   2003   else
   2004     s3_inst.relax_inst = 0x8000;
   2005 }
   2006 
   2007 /* Handle cmp.c/cmp<cond>.  */
   2008 static void
   2009 s3_do_rsrs (char *str)
   2010 {
   2011   s3_skip_whitespace (str);
   2012 
   2013   if (s3_reg_required_here (&str, 15, s3_REG_TYPE_SCORE) == (int) s3_FAIL
   2014       || s3_skip_past_comma (&str) == (int) s3_FAIL
   2015       || s3_reg_required_here (&str, 10, s3_REG_TYPE_SCORE) == (int) s3_FAIL
   2016       || s3_end_of_line (str) == (int) s3_FAIL)
   2017     return;
   2018 
   2019   if ((s3_inst.relax_inst != 0x8000) && (((s3_inst.instruction >> 20) & 0x1f) == 3) )
   2020     {
   2021       s3_inst.relax_inst |= (((s3_inst.instruction >> 10) & 0x1f)) | (((s3_inst.instruction >> 15) & 0x1f) << 5);
   2022       s3_inst.relax_size = 2;
   2023     }
   2024   else
   2025     s3_inst.relax_inst = 0x8000;
   2026 }
   2027 
   2028 static void
   2029 s3_do_ceinst (char *str)
   2030 {
   2031   char *strbak;
   2032 
   2033   strbak = str;
   2034   s3_skip_whitespace (str);
   2035 
   2036   if (s3_data_op2 (&str, 20, _IMM5) == (int) s3_FAIL
   2037       || s3_skip_past_comma (&str) == (int) s3_FAIL
   2038       || s3_reg_required_here (&str, 15, s3_REG_TYPE_SCORE) == (int) s3_FAIL
   2039       || s3_skip_past_comma (&str) == (int) s3_FAIL
   2040       || s3_reg_required_here (&str, 10, s3_REG_TYPE_SCORE) == (int) s3_FAIL
   2041       || s3_skip_past_comma (&str) == (int) s3_FAIL
   2042       || s3_data_op2 (&str, 5, _IMM5) == (int) s3_FAIL
   2043       || s3_skip_past_comma (&str) == (int) s3_FAIL
   2044       || s3_data_op2 (&str, 0, _IMM5) == (int) s3_FAIL
   2045       || s3_end_of_line (str) == (int) s3_FAIL)
   2046     {
   2047       return;
   2048     }
   2049   else
   2050     {
   2051       str = strbak;
   2052       if (s3_data_op2 (&str, 0, _IMM25) == (int) s3_FAIL)
   2053 	return;
   2054     }
   2055 }
   2056 
   2057 static int
   2058 s3_reglow_required_here (char **str, int shift)
   2059 {
   2060   static char buff[s3_MAX_LITERAL_POOL_SIZE];
   2061   int reg;
   2062   char *start = *str;
   2063 
   2064   if ((reg = s3_score_reg_parse (str, s3_all_reg_maps[s3_REG_TYPE_SCORE].htab)) != (int) s3_FAIL)
   2065     {
   2066       if ((reg == 1) && (s3_nor1 == 1) && (s3_inst.bwarn == 0))
   2067         {
   2068           as_warn (_("Using temp register(r1)"));
   2069           s3_inst.bwarn = 1;
   2070         }
   2071       if (reg < 16)
   2072         {
   2073           if (shift >= 0)
   2074             s3_inst.instruction |= (bfd_vma) reg << shift;
   2075 
   2076           return reg;
   2077         }
   2078     }
   2079 
   2080   /* Restore the start point, we may have got a reg of the wrong class.  */
   2081   *str = start;
   2082   sprintf (buff, _("low register(r0-r15)expected, not '%.100s'"), start);
   2083   s3_inst.error = buff;
   2084   return (int) s3_FAIL;
   2085 }
   2086 
   2087 /* Handle add!/and!/or!/sub!.  */
   2088 static void
   2089 s3_do16_rdrs2 (char *str)
   2090 {
   2091   s3_skip_whitespace (str);
   2092 
   2093   if (s3_reglow_required_here (&str, 4) == (int) s3_FAIL
   2094       || s3_skip_past_comma (&str) == (int) s3_FAIL
   2095       || s3_reglow_required_here (&str, 0) == (int) s3_FAIL
   2096       || s3_end_of_line (str) == (int) s3_FAIL)
   2097     {
   2098       return;
   2099     }
   2100 }
   2101 
   2102 /* Handle br!/brl!.  */
   2103 static void
   2104 s3_do16_br (char *str)
   2105 {
   2106   s3_skip_whitespace (str);
   2107 
   2108   if (s3_reg_required_here (&str, 0, s3_REG_TYPE_SCORE) == (int) s3_FAIL
   2109       || s3_end_of_line (str) == (int) s3_FAIL)
   2110     {
   2111       return;
   2112     }
   2113 }
   2114 
   2115 /* Handle brr!.  */
   2116 static void
   2117 s3_do16_brr (char *str)
   2118 {
   2119   int rd = 0;
   2120 
   2121   s3_skip_whitespace (str);
   2122 
   2123   if ((rd = s3_reg_required_here (&str, 0,s3_REG_TYPE_SCORE)) == (int) s3_FAIL
   2124       || s3_end_of_line (str) == (int) s3_FAIL)
   2125     {
   2126       return;
   2127     }
   2128 }
   2129 
   2130 /*Handle ltbw / ltbh / ltbb */
   2131 static void
   2132 s3_do_ltb (char *str)
   2133 {
   2134   s3_skip_whitespace (str);
   2135   if (s3_reg_required_here (&str, 20, s3_REG_TYPE_SCORE) == (int) s3_FAIL
   2136       || s3_skip_past_comma (&str) == (int) s3_FAIL)
   2137     {
   2138       return;
   2139     }
   2140 
   2141   s3_skip_whitespace (str);
   2142   if (*str++ != '[')
   2143     {
   2144       s3_inst.error = _("missing [");
   2145       return;
   2146     }
   2147 
   2148   if (s3_reg_required_here (&str, 15, s3_REG_TYPE_SCORE) == (int) s3_FAIL
   2149       || s3_skip_past_comma (&str) == (int) s3_FAIL
   2150       || s3_reg_required_here (&str, 10, s3_REG_TYPE_SCORE) == (int) s3_FAIL)
   2151     {
   2152       return;
   2153     }
   2154 
   2155   s3_skip_whitespace (str);
   2156   if (*str++ != ']')
   2157     {
   2158       s3_inst.error = _("missing ]");
   2159       return;
   2160     }
   2161 }
   2162 
   2163 /* We need to be able to fix up arbitrary expressions in some statements.
   2164    This is so that we can handle symbols that are an arbitrary distance from
   2165    the pc.  The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
   2166    which returns part of an address in a form which will be valid for
   2167    a data instruction.  We do this by pushing the expression into a symbol
   2168    in the expr_section, and creating a fix for that.  */
   2169 static fixS *
   2170 s3_fix_new_score (fragS * frag, int where, short int size, expressionS * exp, int pc_rel, int reloc)
   2171 {
   2172   fixS *new_fix;
   2173 
   2174   switch (exp->X_op)
   2175     {
   2176     case O_constant:
   2177     case O_symbol:
   2178     case O_add:
   2179     case O_subtract:
   2180       new_fix = fix_new_exp (frag, where, size, exp, pc_rel, reloc);
   2181       break;
   2182     default:
   2183       new_fix = fix_new (frag, where, size, make_expr_symbol (exp), 0, pc_rel, reloc);
   2184       break;
   2185     }
   2186   return new_fix;
   2187 }
   2188 
   2189 static void
   2190 s3_init_dependency_vector (void)
   2191 {
   2192   int i;
   2193 
   2194   for (i = 0; i < s3_vector_size; i++)
   2195     memset (&s3_dependency_vector[i], '\0', sizeof (s3_dependency_vector[i]));
   2196 
   2197   return;
   2198 }
   2199 
   2200 static enum s3_insn_type_for_dependency
   2201 s3_dependency_type_from_insn (char *insn_name)
   2202 {
   2203   char name[s3_INSN_NAME_LEN];
   2204   const struct s3_insn_to_dependency *tmp;
   2205 
   2206   strcpy (name, insn_name);
   2207   tmp = (const struct s3_insn_to_dependency *) hash_find (s3_dependency_insn_hsh, name);
   2208 
   2209   if (tmp)
   2210     return tmp->type;
   2211 
   2212   return s3_D_all_insn;
   2213 }
   2214 
   2215 static int
   2216 s3_check_dependency (char *pre_insn, char *pre_reg,
   2217 		     char *cur_insn, char *cur_reg, int *warn_or_error)
   2218 {
   2219   int bubbles = 0;
   2220   unsigned int i;
   2221   enum s3_insn_type_for_dependency pre_insn_type;
   2222   enum s3_insn_type_for_dependency cur_insn_type;
   2223 
   2224   pre_insn_type = s3_dependency_type_from_insn (pre_insn);
   2225   cur_insn_type = s3_dependency_type_from_insn (cur_insn);
   2226 
   2227   for (i = 0; i < sizeof (s3_data_dependency_table) / sizeof (s3_data_dependency_table[0]); i++)
   2228     {
   2229       if ((pre_insn_type == s3_data_dependency_table[i].pre_insn_type)
   2230           && (s3_D_all_insn == s3_data_dependency_table[i].cur_insn_type
   2231               || cur_insn_type == s3_data_dependency_table[i].cur_insn_type)
   2232           && (strcmp (s3_data_dependency_table[i].pre_reg, "") == 0
   2233               || strcmp (s3_data_dependency_table[i].pre_reg, pre_reg) == 0)
   2234           && (strcmp (s3_data_dependency_table[i].cur_reg, "") == 0
   2235               || strcmp (s3_data_dependency_table[i].cur_reg, cur_reg) == 0))
   2236         {
   2237           bubbles = s3_data_dependency_table[i].bubblenum_3;
   2238           *warn_or_error = s3_data_dependency_table[i].warn_or_error;
   2239           break;
   2240         }
   2241     }
   2242 
   2243   return bubbles;
   2244 }
   2245 
   2246 static void
   2247 s3_build_one_frag (struct s3_score_it one_inst)
   2248 {
   2249   char *p;
   2250   int relaxable_p = s3_g_opt;
   2251   int relax_size = 0;
   2252 
   2253   /* Start a new frag if frag_now is not empty.  */
   2254   if (frag_now_fix () != 0)
   2255     {
   2256       if (!frag_now->tc_frag_data.is_insn)
   2257 	frag_wane (frag_now);
   2258 
   2259       frag_new (0);
   2260     }
   2261   frag_grow (20);
   2262 
   2263   p = frag_more (one_inst.size);
   2264   s3_md_number_to_chars (p, one_inst.instruction, one_inst.size);
   2265 
   2266 #ifdef OBJ_ELF
   2267   dwarf2_emit_insn (one_inst.size);
   2268 #endif
   2269 
   2270   relaxable_p &= (one_inst.relax_size != 0);
   2271   relax_size = relaxable_p ? one_inst.relax_size : 0;
   2272 
   2273   p = frag_var (rs_machine_dependent, relax_size + s3_RELAX_PAD_BYTE, 0,
   2274                 s3_RELAX_ENCODE (one_inst.size, one_inst.relax_size,
   2275 				 one_inst.type, 0, 0, relaxable_p),
   2276                 NULL, 0, NULL);
   2277 
   2278   if (relaxable_p)
   2279     s3_md_number_to_chars (p, one_inst.relax_inst, relax_size);
   2280 }
   2281 
   2282 static void
   2283 s3_handle_dependency (struct s3_score_it *theinst)
   2284 {
   2285   int i;
   2286   int warn_or_error = 0;   /* warn - 0; error - 1  */
   2287   int bubbles = 0;
   2288   int remainder_bubbles = 0;
   2289   char cur_insn[s3_INSN_NAME_LEN];
   2290   char pre_insn[s3_INSN_NAME_LEN];
   2291   struct s3_score_it nop_inst;
   2292   struct s3_score_it pflush_inst;
   2293 
   2294   nop_inst.instruction = 0x0000;
   2295   nop_inst.size = 2;
   2296   nop_inst.relax_inst = 0x80008000;
   2297   nop_inst.relax_size = 4;
   2298   nop_inst.type = NO16_OPD;
   2299 
   2300   pflush_inst.instruction = 0x8000800a;
   2301   pflush_inst.size = 4;
   2302   pflush_inst.relax_inst = 0x8000;
   2303   pflush_inst.relax_size = 0;
   2304   pflush_inst.type = NO_OPD;
   2305 
   2306   /* pflush will clear all data dependency.  */
   2307   if (strcmp (theinst->name, "pflush") == 0)
   2308     {
   2309       s3_init_dependency_vector ();
   2310       return;
   2311     }
   2312 
   2313   /* Push current instruction to s3_dependency_vector[0].  */
   2314   for (i = s3_vector_size - 1; i > 0; i--)
   2315     memcpy (&s3_dependency_vector[i], &s3_dependency_vector[i - 1], sizeof (s3_dependency_vector[i]));
   2316 
   2317   memcpy (&s3_dependency_vector[0], theinst, sizeof (s3_dependency_vector[i]));
   2318 
   2319   /* There is no dependency between nop and any instruction.  */
   2320   if (strcmp (s3_dependency_vector[0].name, "nop") == 0
   2321       || strcmp (s3_dependency_vector[0].name, "nop!") == 0)
   2322     return;
   2323 
   2324   strcpy (cur_insn, s3_dependency_vector[0].name);
   2325 
   2326   for (i = 1; i < s3_vector_size; i++)
   2327     {
   2328       /* The element of s3_dependency_vector is NULL.  */
   2329       if (s3_dependency_vector[i].name[0] == '\0')
   2330 	continue;
   2331 
   2332       strcpy (pre_insn, s3_dependency_vector[i].name);
   2333 
   2334       bubbles = s3_check_dependency (pre_insn, s3_dependency_vector[i].reg,
   2335 				     cur_insn, s3_dependency_vector[0].reg, &warn_or_error);
   2336       remainder_bubbles = bubbles - i + 1;
   2337 
   2338       if (remainder_bubbles > 0)
   2339         {
   2340           int j;
   2341 
   2342           if (s3_fix_data_dependency == 1)
   2343             {
   2344 	      if (remainder_bubbles <= 2)
   2345 		{
   2346 		  if (s3_warn_fix_data_dependency)
   2347 		    as_warn (_("Fix data dependency: %s %s -- %s %s  (insert %d nop!/%d)"),
   2348 			     s3_dependency_vector[i].name, s3_dependency_vector[i].reg,
   2349 			     s3_dependency_vector[0].name, s3_dependency_vector[0].reg,
   2350 			     remainder_bubbles, bubbles);
   2351 
   2352                   for (j = (s3_vector_size - 1); (j - remainder_bubbles) > 0; j--)
   2353 		    memcpy (&s3_dependency_vector[j], &s3_dependency_vector[j - remainder_bubbles],
   2354 			    sizeof (s3_dependency_vector[j]));
   2355 
   2356                   for (j = 1; j <= remainder_bubbles; j++)
   2357                     {
   2358                       memset (&s3_dependency_vector[j], '\0', sizeof (s3_dependency_vector[j]));
   2359 		      /* Insert nop!.  */
   2360     		      s3_build_one_frag (nop_inst);
   2361                     }
   2362 		}
   2363 	      else
   2364 		{
   2365 		  if (s3_warn_fix_data_dependency)
   2366 		    as_warn (_("Fix data dependency: %s %s -- %s %s  (insert 1 pflush/%d)"),
   2367 			     s3_dependency_vector[i].name, s3_dependency_vector[i].reg,
   2368 			     s3_dependency_vector[0].name, s3_dependency_vector[0].reg,
   2369 			     bubbles);
   2370 
   2371                   for (j = 1; j < s3_vector_size; j++)
   2372 		    memset (&s3_dependency_vector[j], '\0', sizeof (s3_dependency_vector[j]));
   2373 
   2374                   /* Insert pflush.  */
   2375                   s3_build_one_frag (pflush_inst);
   2376 		}
   2377             }
   2378           else
   2379             {
   2380 	      if (warn_or_error)
   2381 		{
   2382                   as_bad (_("data dependency: %s %s -- %s %s  (%d/%d bubble)"),
   2383 			  s3_dependency_vector[i].name, s3_dependency_vector[i].reg,
   2384 			  s3_dependency_vector[0].name, s3_dependency_vector[0].reg,
   2385 			  remainder_bubbles, bubbles);
   2386 		}
   2387 	      else
   2388 		{
   2389                   as_warn (_("data dependency: %s %s -- %s %s  (%d/%d bubble)"),
   2390                            s3_dependency_vector[i].name, s3_dependency_vector[i].reg,
   2391                            s3_dependency_vector[0].name, s3_dependency_vector[0].reg,
   2392                            remainder_bubbles, bubbles);
   2393 		}
   2394             }
   2395         }
   2396     }
   2397 }
   2398 
   2399 static enum insn_class
   2400 s3_get_insn_class_from_type (enum score_insn_type type)
   2401 {
   2402   enum insn_class retval = (int) s3_FAIL;
   2403 
   2404   switch (type)
   2405     {
   2406     case Rd_I4:
   2407     case Rd_I5:
   2408     case Rd_rvalueBP_I5:
   2409     case Rd_lvalueBP_I5:
   2410     case Rd_I8:
   2411     case PC_DISP8div2:
   2412     case PC_DISP11div2:
   2413     case Rd_Rs:
   2414     case Rd_HighRs:
   2415     case Rd_lvalueRs:
   2416     case Rd_rvalueRs:
   2417     case x_Rs:
   2418     case Rd_LowRs:
   2419     case NO16_OPD:
   2420     case Rd_SI5:
   2421     case Rd_SI6:
   2422       retval = INSN_CLASS_16;
   2423       break;
   2424     case Rd_Rs_I5:
   2425     case x_Rs_I5:
   2426     case x_I5_x:
   2427     case Rd_Rs_I14:
   2428     case I15:
   2429     case Rd_I16:
   2430     case Rd_SI16:
   2431     case Rd_rvalueRs_SI10:
   2432     case Rd_lvalueRs_SI10:
   2433     case Rd_rvalueRs_preSI12:
   2434     case Rd_rvalueRs_postSI12:
   2435     case Rd_lvalueRs_preSI12:
   2436     case Rd_lvalueRs_postSI12:
   2437     case Rd_Rs_SI14:
   2438     case Rd_rvalueRs_SI15:
   2439     case Rd_lvalueRs_SI15:
   2440     case PC_DISP19div2:
   2441     case PC_DISP24div2:
   2442     case Rd_Rs_Rs:
   2443     case x_Rs_x:
   2444     case x_Rs_Rs:
   2445     case Rd_Rs_x:
   2446     case Rd_x_Rs:
   2447     case Rd_x_x:
   2448     case OP5_rvalueRs_SI15:
   2449     case I5_Rs_Rs_I5_OP5:
   2450     case x_rvalueRs_post4:
   2451     case Rd_rvalueRs_post4:
   2452     case Rd_x_I5:
   2453     case Rd_lvalueRs_post4:
   2454     case x_lvalueRs_post4:
   2455     case Rd_Rs_Rs_imm:
   2456     case NO_OPD:
   2457     case Rd_lvalue32Rs:
   2458     case Rd_rvalue32Rs:
   2459     case Insn_GP:
   2460     case Insn_PIC:
   2461     case Insn_internal:
   2462     case Insn_BCMP:
   2463     case Ra_I9_I5:
   2464       retval = INSN_CLASS_32;
   2465       break;
   2466     case Insn_Type_PCE:
   2467       retval = INSN_CLASS_PCE;
   2468       break;
   2469     case Insn_Type_SYN:
   2470       retval = INSN_CLASS_SYN;
   2471       break;
   2472     case Rd_I30:
   2473     case Rd_I32:
   2474       retval = INSN_CLASS_48;
   2475       break;
   2476     default:
   2477       abort ();
   2478       break;
   2479     }
   2480   return retval;
   2481 }
   2482 
   2483 /* Type of p-bits:
   2484    48-bit instruction: 1, 1, 0.
   2485    32-bit instruction: 1, 0.
   2486    16-bit instruction: 0.  */
   2487 static bfd_vma
   2488 s3_adjust_paritybit (bfd_vma m_code, enum insn_class i_class)
   2489 {
   2490   bfd_vma result = 0;
   2491   bfd_vma m_code_high = 0;
   2492   unsigned long m_code_middle = 0;
   2493   unsigned long m_code_low = 0;
   2494   bfd_vma pb_high = 0;
   2495   unsigned long pb_middle = 0;
   2496   unsigned long pb_low = 0;
   2497 
   2498   if (i_class == INSN_CLASS_48)
   2499     {
   2500       pb_high = 0x800000000000LL;
   2501       pb_middle = 0x80000000;
   2502       pb_low = 0x00000000;
   2503       m_code_high = m_code & 0x1fffc0000000LL;
   2504       m_code_middle = m_code & 0x3fff8000;
   2505       m_code_low = m_code & 0x00007fff;
   2506       result = pb_high | (m_code_high << 2) |
   2507 	pb_middle | (m_code_middle << 1) |
   2508 	pb_low | m_code_low;
   2509     }
   2510   else if (i_class == INSN_CLASS_32 || i_class == INSN_CLASS_SYN)
   2511     {
   2512       pb_high = 0x80000000;
   2513       pb_low = 0x00000000;
   2514       m_code_high = m_code & 0x3fff8000;
   2515       m_code_low = m_code & 0x00007fff;
   2516       result = pb_high | (m_code_high << 1) | pb_low | m_code_low;
   2517     }
   2518   else if (i_class == INSN_CLASS_16)
   2519     {
   2520       pb_high = 0;
   2521       pb_low = 0;
   2522       m_code_high = m_code & 0x3fff8000;
   2523       m_code_low = m_code & 0x00007fff;
   2524       result = pb_high | (m_code_high << 1) | pb_low | m_code_low;
   2525     }
   2526   else if (i_class == INSN_CLASS_PCE)
   2527     {
   2528       /* Keep original.  */
   2529       pb_high = 0;
   2530       pb_low = 0x00008000;
   2531       m_code_high = m_code & 0x3fff8000;
   2532       m_code_low = m_code & 0x00007fff;
   2533       result = pb_high | (m_code_high << 1) | pb_low | m_code_low;
   2534     }
   2535   else
   2536     {
   2537       abort ();
   2538     }
   2539 
   2540   return result;
   2541 }
   2542 
   2543 static void
   2544 s3_gen_insn_frag (struct s3_score_it *part_1, struct s3_score_it *part_2)
   2545 {
   2546   char *p;
   2547   bfd_boolean pce_p = FALSE;
   2548   int relaxable_p = s3_g_opt;
   2549   int relax_size = 0;
   2550   struct s3_score_it *inst1 = part_1;
   2551   struct s3_score_it *inst2 = part_2;
   2552   struct s3_score_it backup_inst1;
   2553 
   2554   pce_p = (inst2) ? TRUE : FALSE;
   2555   memcpy (&backup_inst1, inst1, sizeof (struct s3_score_it));
   2556 
   2557   /* Adjust instruction opcode and to be relaxed instruction opcode.  */
   2558   if (pce_p)
   2559     {
   2560       backup_inst1.instruction = ((backup_inst1.instruction & 0x7FFF) << 15)
   2561 	| (inst2->instruction & 0x7FFF);
   2562       backup_inst1.instruction = s3_adjust_paritybit (backup_inst1.instruction, INSN_CLASS_PCE);
   2563       backup_inst1.relax_inst = 0x8000;
   2564       backup_inst1.size = s3_INSN_SIZE;
   2565       backup_inst1.relax_size = 0;
   2566       backup_inst1.type = Insn_Type_PCE;
   2567     }
   2568   else
   2569     {
   2570       backup_inst1.instruction = s3_adjust_paritybit (backup_inst1.instruction,
   2571 						      s3_GET_INSN_CLASS (backup_inst1.type));
   2572     }
   2573 
   2574   if (backup_inst1.relax_size != 0)
   2575     {
   2576       enum insn_class tmp;
   2577 
   2578       tmp = (backup_inst1.size == s3_INSN_SIZE) ? INSN_CLASS_16 : INSN_CLASS_32;
   2579       backup_inst1.relax_inst = s3_adjust_paritybit (backup_inst1.relax_inst, tmp);
   2580     }
   2581 
   2582   /* Check data dependency.  */
   2583   s3_handle_dependency (&backup_inst1);
   2584 
   2585   /* Start a new frag if frag_now is not empty and is not instruction frag, maybe it contains
   2586      data produced by .ascii etc.  Doing this is to make one instruction per frag.  */
   2587   if (frag_now_fix () != 0)
   2588     {
   2589       if (!frag_now->tc_frag_data.is_insn)
   2590 	frag_wane (frag_now);
   2591 
   2592       frag_new (0);
   2593     }
   2594 
   2595   /* Here, we must call frag_grow in order to keep the instruction frag type is
   2596      rs_machine_dependent.
   2597      For, frag_var may change frag_now->fr_type to rs_fill by calling frag_grow which
   2598      acturally will call frag_wane.
   2599      Calling frag_grow first will create a new frag_now which free size is 20 that is enough
   2600      for frag_var.  */
   2601   frag_grow (20);
   2602 
   2603   p = frag_more (backup_inst1.size);
   2604   s3_md_number_to_chars (p, backup_inst1.instruction, backup_inst1.size);
   2605 
   2606 #ifdef OBJ_ELF
   2607   dwarf2_emit_insn (backup_inst1.size);
   2608 #endif
   2609 
   2610   /* Generate fixup structure.  */
   2611   if (pce_p)
   2612     {
   2613       if (inst1->reloc.type != BFD_RELOC_NONE)
   2614 	s3_fix_new_score (frag_now, p - frag_now->fr_literal,
   2615 			  inst1->size, &inst1->reloc.exp,
   2616 			  inst1->reloc.pc_rel, inst1->reloc.type);
   2617 
   2618       if (inst2->reloc.type != BFD_RELOC_NONE)
   2619 	s3_fix_new_score (frag_now, p - frag_now->fr_literal + 2,
   2620 			  inst2->size, &inst2->reloc.exp, inst2->reloc.pc_rel, inst2->reloc.type);
   2621     }
   2622   else
   2623     {
   2624       if (backup_inst1.reloc.type != BFD_RELOC_NONE)
   2625 	s3_fix_new_score (frag_now, p - frag_now->fr_literal,
   2626 			  backup_inst1.size, &backup_inst1.reloc.exp,
   2627 			  backup_inst1.reloc.pc_rel, backup_inst1.reloc.type);
   2628     }
   2629 
   2630   /* relax_size may be 2, 4, 12 or 0, 0 indicates no relaxation.  */
   2631   relaxable_p &= (backup_inst1.relax_size != 0);
   2632   relax_size = relaxable_p ? backup_inst1.relax_size : 0;
   2633 
   2634   p = frag_var (rs_machine_dependent, relax_size + s3_RELAX_PAD_BYTE, 0,
   2635                 s3_RELAX_ENCODE (backup_inst1.size, backup_inst1.relax_size,
   2636 				 backup_inst1.type, 0, 0, relaxable_p),
   2637                 backup_inst1.reloc.exp.X_add_symbol, 0, NULL);
   2638 
   2639   if (relaxable_p)
   2640     s3_md_number_to_chars (p, backup_inst1.relax_inst, relax_size);
   2641 
   2642   memcpy (inst1, &backup_inst1, sizeof (struct s3_score_it));
   2643 }
   2644 
   2645 static void
   2646 s3_parse_16_32_inst (char *insnstr, bfd_boolean gen_frag_p)
   2647 {
   2648   char c;
   2649   char *p;
   2650   char *operator = insnstr;
   2651   const struct s3_asm_opcode *opcode;
   2652 
   2653   /* Parse operator and operands.  */
   2654   s3_skip_whitespace (operator);
   2655 
   2656   for (p = operator; *p != '\0'; p++)
   2657     if ((*p == ' ') || (*p == '!'))
   2658       break;
   2659 
   2660   if (*p == '!')
   2661     p++;
   2662 
   2663   c = *p;
   2664   *p = '\0';
   2665 
   2666   opcode = (const struct s3_asm_opcode *) hash_find (s3_score_ops_hsh, operator);
   2667   *p = c;
   2668 
   2669   memset (&s3_inst, '\0', sizeof (s3_inst));
   2670   sprintf (s3_inst.str, "%s", insnstr);
   2671   if (opcode)
   2672     {
   2673       s3_inst.instruction = opcode->value;
   2674       s3_inst.relax_inst = opcode->relax_value;
   2675       s3_inst.type = opcode->type;
   2676       s3_inst.size = s3_GET_INSN_SIZE (s3_inst.type);
   2677       s3_inst.relax_size = 0;
   2678       s3_inst.bwarn = 0;
   2679       sprintf (s3_inst.name, "%s", opcode->template_name);
   2680       strcpy (s3_inst.reg, "");
   2681       s3_inst.error = NULL;
   2682       s3_inst.reloc.type = BFD_RELOC_NONE;
   2683 
   2684       (*opcode->parms) (p);
   2685 
   2686       /* It indicates current instruction is a macro instruction if s3_inst.bwarn equals -1.  */
   2687       if ((s3_inst.bwarn != -1) && (!s3_inst.error) && (gen_frag_p))
   2688 	s3_gen_insn_frag (&s3_inst, NULL);
   2689     }
   2690   else
   2691     s3_inst.error = _("unrecognized opcode");
   2692 }
   2693 
   2694 static void
   2695 s3_parse_48_inst (char *insnstr, bfd_boolean gen_frag_p)
   2696 {
   2697   char c;
   2698   char *p;
   2699   char *operator = insnstr;
   2700   const struct s3_asm_opcode *opcode;
   2701 
   2702   /* Parse operator and operands.  */
   2703   s3_skip_whitespace (operator);
   2704 
   2705   for (p = operator; *p != '\0'; p++)
   2706     if (*p == ' ')
   2707       break;
   2708 
   2709   c = *p;
   2710   *p = '\0';
   2711 
   2712   opcode = (const struct s3_asm_opcode *) hash_find (s3_score_ops_hsh, operator);
   2713   *p = c;
   2714 
   2715   memset (&s3_inst, '\0', sizeof (s3_inst));
   2716   sprintf (s3_inst.str, "%s", insnstr);
   2717   if (opcode)
   2718     {
   2719       s3_inst.instruction = opcode->value;
   2720       s3_inst.relax_inst = opcode->relax_value;
   2721       s3_inst.type = opcode->type;
   2722       s3_inst.size = s3_GET_INSN_SIZE (s3_inst.type);
   2723       s3_inst.relax_size = 0;
   2724       s3_inst.bwarn = 0;
   2725       sprintf (s3_inst.name, "%s", opcode->template_name);
   2726       strcpy (s3_inst.reg, "");
   2727       s3_inst.error = NULL;
   2728       s3_inst.reloc.type = BFD_RELOC_NONE;
   2729 
   2730       (*opcode->parms) (p);
   2731 
   2732       /* It indicates current instruction is a macro instruction if s3_inst.bwarn equals -1.  */
   2733       if ((s3_inst.bwarn != -1) && (!s3_inst.error) && (gen_frag_p))
   2734 	s3_gen_insn_frag (&s3_inst, NULL);
   2735     }
   2736   else
   2737     s3_inst.error = _("unrecognized opcode");
   2738 }
   2739 
   2740 static int
   2741 s3_append_insn (char *str, bfd_boolean gen_frag_p)
   2742 {
   2743   int retval = s3_SUCCESS;
   2744 
   2745   s3_parse_16_32_inst (str, gen_frag_p);
   2746 
   2747   if (s3_inst.error)
   2748     {
   2749       retval = (int) s3_FAIL;
   2750       as_bad (_("%s -- `%s'"), s3_inst.error, s3_inst.str);
   2751       s3_inst.error = NULL;
   2752     }
   2753 
   2754   return retval;
   2755 }
   2756 
   2757 static void
   2758 s3_do16_mv_cmp (char *str)
   2759 {
   2760   s3_skip_whitespace (str);
   2761 
   2762   if (s3_reg_required_here (&str, 5, s3_REG_TYPE_SCORE) == (int) s3_FAIL
   2763       || s3_skip_past_comma (&str) == (int) s3_FAIL
   2764       || s3_reg_required_here (&str, 0, s3_REG_TYPE_SCORE) == (int) s3_FAIL
   2765       || s3_end_of_line (str) == (int) s3_FAIL)
   2766     {
   2767       return;
   2768     }
   2769 }
   2770 
   2771 static void
   2772 s3_do16_cmpi (char *str)
   2773 {
   2774   s3_skip_whitespace (str);
   2775 
   2776   if (s3_reg_required_here (&str, 5, s3_REG_TYPE_SCORE) == (int) s3_FAIL
   2777       || s3_skip_past_comma (&str) == (int) s3_FAIL
   2778       || s3_data_op2 (&str, 0, _SIMM5) == (int) s3_FAIL
   2779       || s3_end_of_line (str) == (int) s3_FAIL)
   2780     {
   2781       return;
   2782     }
   2783 }
   2784 
   2785 static void
   2786 s3_do16_addi (char *str)
   2787 {
   2788   s3_skip_whitespace (str);
   2789 
   2790   if (s3_reglow_required_here (&str, 6) == (int) s3_FAIL
   2791       || s3_skip_past_comma (&str) == (int) s3_FAIL
   2792       || s3_data_op2 (&str, 0, _SIMM6) == (int) s3_FAIL
   2793       || s3_end_of_line (str) == (int) s3_FAIL)
   2794     {
   2795       return;
   2796     }
   2797 }
   2798 
   2799 /* Handle bitclr! / bitset! / bittst! / bittgl! */
   2800 static void
   2801 s3_do16_rdi5 (char *str)
   2802 {
   2803   s3_skip_whitespace (str);
   2804 
   2805   if (s3_reglow_required_here (&str, 5) == (int) s3_FAIL
   2806       || s3_skip_past_comma (&str) == (int) s3_FAIL
   2807       || s3_data_op2 (&str, 0, _IMM5) == (int) s3_FAIL
   2808       || s3_end_of_line (str) == (int) s3_FAIL)
   2809     return;
   2810   else
   2811     {
   2812       s3_inst.relax_inst |= (((s3_inst.instruction >>5) & 0xf) << 20)
   2813         | (((s3_inst.instruction >> 5) & 0xf) << 15) | (((s3_inst.instruction ) & 0x1f) << 10);
   2814       s3_inst.relax_size = 4;
   2815     }
   2816 }
   2817 
   2818 
   2819 /* Handle sdbbp!.  */
   2820 static void
   2821 s3_do16_xi5 (char *str)
   2822 {
   2823   s3_skip_whitespace (str);
   2824 
   2825   if (s3_data_op2 (&str, 0, _IMM5) == (int) s3_FAIL || s3_end_of_line (str) == (int) s3_FAIL)
   2826     return;
   2827 }
   2828 
   2829 /* Check that an immediate is word alignment or half word alignment.
   2830    If so, convert it to the right format.  */
   2831 static int
   2832 s3_validate_immediate_align (int val, unsigned int data_type)
   2833 {
   2834   if (data_type == _IMM5_RSHIFT_1)
   2835     {
   2836       if (val % 2)
   2837         {
   2838           s3_inst.error = _("address offset must be half word alignment");
   2839           return (int) s3_FAIL;
   2840         }
   2841     }
   2842   else if ((data_type == _IMM5_RSHIFT_2) || (data_type == _IMM10_RSHIFT_2))
   2843     {
   2844       if (val % 4)
   2845         {
   2846           s3_inst.error = _("address offset must be word alignment");
   2847           return (int) s3_FAIL;
   2848         }
   2849     }
   2850 
   2851   return s3_SUCCESS;
   2852 }
   2853 
   2854 static int
   2855 s3_exp_ldst_offset (char **str, int shift, unsigned int data_type)
   2856 {
   2857   char *dataptr;
   2858 
   2859   dataptr = * str;
   2860 
   2861   if ((*dataptr == '0') && (*(dataptr + 1) == 'x')
   2862       && (data_type != _SIMM16_LA)
   2863       && (data_type != _VALUE_HI16)
   2864       && (data_type != _VALUE_LO16)
   2865       && (data_type != _IMM16)
   2866       && (data_type != _IMM15)
   2867       && (data_type != _IMM14)
   2868       && (data_type != _IMM4)
   2869       && (data_type != _IMM5)
   2870       && (data_type != _IMM8)
   2871       && (data_type != _IMM5_RSHIFT_1)
   2872       && (data_type != _IMM5_RSHIFT_2)
   2873       && (data_type != _SIMM14_NEG)
   2874       && (data_type != _IMM10_RSHIFT_2))
   2875     {
   2876       data_type += 24;
   2877     }
   2878 
   2879   if (s3_my_get_expression (&s3_inst.reloc.exp, str) == (int) s3_FAIL)
   2880     return (int) s3_FAIL;
   2881 
   2882   if (s3_inst.reloc.exp.X_op == O_constant)
   2883     {
   2884       /* Need to check the immediate align.  */
   2885       int value = s3_validate_immediate_align (s3_inst.reloc.exp.X_add_number, data_type);
   2886 
   2887       if (value == (int) s3_FAIL)
   2888 	return (int) s3_FAIL;
   2889 
   2890       value = s3_validate_immediate (s3_inst.reloc.exp.X_add_number, data_type, 0);
   2891       if (value == (int) s3_FAIL)
   2892         {
   2893           if (data_type < 30)
   2894             sprintf (s3_err_msg,
   2895                      _("invalid constant: %d bit expression not in range %d..%d"),
   2896                      s3_score_df_range[data_type].bits,
   2897                      s3_score_df_range[data_type].range[0], s3_score_df_range[data_type].range[1]);
   2898           else
   2899             sprintf (s3_err_msg,
   2900                      _("invalid constant: %d bit expression not in range %d..%d"),
   2901                      s3_score_df_range[data_type - 24].bits,
   2902                      s3_score_df_range[data_type - 24].range[0], s3_score_df_range[data_type - 24].range[1]);
   2903           s3_inst.error = s3_err_msg;
   2904           return (int) s3_FAIL;
   2905         }
   2906 
   2907       if (data_type == _IMM5_RSHIFT_1)
   2908         {
   2909           value >>= 1;
   2910         }
   2911       else if ((data_type == _IMM5_RSHIFT_2) || (data_type == _IMM10_RSHIFT_2))
   2912         {
   2913           value >>= 2;
   2914         }
   2915 
   2916       if (s3_score_df_range[data_type].range[0] != 0)
   2917         {
   2918           value &= (1 << s3_score_df_range[data_type].bits) - 1;
   2919         }
   2920 
   2921       s3_inst.instruction |= value << shift;
   2922     }
   2923   else
   2924     {
   2925       s3_inst.reloc.pc_rel = 0;
   2926     }
   2927 
   2928   return s3_SUCCESS;
   2929 }
   2930 
   2931 static void
   2932 s3_do_ldst_insn (char *str)
   2933 {
   2934   int pre_inc = 0;
   2935   int conflict_reg;
   2936   int value;
   2937   char * temp;
   2938   char *dataptr;
   2939   int reg;
   2940   int ldst_idx = 0;
   2941 
   2942   s3_skip_whitespace (str);
   2943 
   2944   if (((conflict_reg = s3_reg_required_here (&str, 20, s3_REG_TYPE_SCORE)) == (int) s3_FAIL)
   2945       || (s3_skip_past_comma (&str) == (int) s3_FAIL))
   2946     return;
   2947 
   2948   /* ld/sw rD, [rA, simm15]    ld/sw rD, [rA]+, simm12     ld/sw rD, [rA, simm12]+.  */
   2949   if (*str == '[')
   2950     {
   2951       str++;
   2952       s3_skip_whitespace (str);
   2953 
   2954       if ((reg = s3_reg_required_here (&str, 15, s3_REG_TYPE_SCORE)) == (int) s3_FAIL)
   2955 	return;
   2956 
   2957       /* Conflicts can occur on stores as well as loads.  */
   2958       conflict_reg = (conflict_reg == reg);
   2959       s3_skip_whitespace (str);
   2960       temp = str + 1;    /* The latter will process decimal/hex expression.  */
   2961 
   2962       /* ld/sw rD, [rA]+, simm12    ld/sw rD, [rA]+.  */
   2963       if (*str == ']')
   2964         {
   2965           str++;
   2966           if (*str == '+')
   2967             {
   2968               str++;
   2969               /* ld/sw rD, [rA]+, simm12.  */
   2970               if (s3_skip_past_comma (&str) == s3_SUCCESS)
   2971                 {
   2972                   if ((s3_exp_ldst_offset (&str, 3, _SIMM12) == (int) s3_FAIL)
   2973                       || (s3_end_of_line (str) == (int) s3_FAIL))
   2974 		    return;
   2975 
   2976                   if (conflict_reg)
   2977                     {
   2978                       unsigned int ldst_func = s3_inst.instruction & OPC_PSEUDOLDST_MASK;
   2979 
   2980                       if ((ldst_func == INSN_LH)
   2981                           || (ldst_func == INSN_LHU)
   2982                           || (ldst_func == INSN_LW)
   2983                           || (ldst_func == INSN_LB)
   2984                           || (ldst_func == INSN_LBU))
   2985                         {
   2986                           s3_inst.error = _("register same as write-back base");
   2987                           return;
   2988                         }
   2989                     }
   2990 
   2991                   ldst_idx = s3_inst.instruction & OPC_PSEUDOLDST_MASK;
   2992                   s3_inst.instruction &= ~OPC_PSEUDOLDST_MASK;
   2993                   s3_inst.instruction |= s3_score_ldst_insns[ldst_idx * 3 + LDST_POST].value;
   2994 
   2995                   /* lw rD, [rA]+, 4 convert to pop rD, [rA].  */
   2996                   if ((s3_inst.instruction & 0x3e000007) == 0x0e000000)
   2997                     {
   2998                       /* rs =  r0, offset = 4 */
   2999                       if ((((s3_inst.instruction >> 15) & 0x1f) == 0)
   3000                           && (((s3_inst.instruction >> 3) & 0xfff) == 4))
   3001                         {
   3002                           /* Relax to pop!.  */
   3003                           s3_inst.relax_inst = 0x0040 | ((s3_inst.instruction >> 20) & 0x1f);
   3004                           s3_inst.relax_size = 2;
   3005                         }
   3006                     }
   3007                   return;
   3008                 }
   3009               /* ld/sw rD, [rA]+ convert to ld/sw rD, [rA, 0]+.  */
   3010               else
   3011                 {
   3012                   s3_SET_INSN_ERROR (NULL);
   3013                   if (s3_end_of_line (str) == (int) s3_FAIL)
   3014                     {
   3015                       return;
   3016                     }
   3017 
   3018                   pre_inc = 1;
   3019                   value = s3_validate_immediate (s3_inst.reloc.exp.X_add_number, _SIMM12, 0);
   3020                   value &= (1 << s3_score_df_range[_SIMM12].bits) - 1;
   3021                   ldst_idx = s3_inst.instruction & OPC_PSEUDOLDST_MASK;
   3022                   s3_inst.instruction &= ~OPC_PSEUDOLDST_MASK;
   3023                   s3_inst.instruction |= s3_score_ldst_insns[ldst_idx * 3 + pre_inc].value;
   3024                   s3_inst.instruction |= value << 3;
   3025                   s3_inst.relax_inst = 0x8000;
   3026                   return;
   3027                 }
   3028             }
   3029           /* ld/sw rD, [rA] convert to ld/sw rD, [rA, simm15].  */
   3030           else
   3031             {
   3032               if (s3_end_of_line (str) == (int) s3_FAIL)
   3033 		return;
   3034 
   3035               ldst_idx = s3_inst.instruction & OPC_PSEUDOLDST_MASK;
   3036               s3_inst.instruction &= ~OPC_PSEUDOLDST_MASK;
   3037               s3_inst.instruction |= s3_score_ldst_insns[ldst_idx * 3 + LDST_NOUPDATE].value;
   3038 
   3039               /* lbu rd, [rs] -> lbu! rd, [rs]  */
   3040               if (ldst_idx == INSN_LBU)
   3041                 {
   3042                   s3_inst.relax_inst = INSN16_LBU;
   3043                 }
   3044               else if (ldst_idx == INSN_LH)
   3045                 {
   3046                   s3_inst.relax_inst = INSN16_LH;
   3047                 }
   3048               else if (ldst_idx == INSN_LW)
   3049                 {
   3050                   s3_inst.relax_inst = INSN16_LW;
   3051                 }
   3052               else if (ldst_idx == INSN_SB)
   3053                 {
   3054                   s3_inst.relax_inst = INSN16_SB;
   3055                 }
   3056               else if (ldst_idx == INSN_SH)
   3057                 {
   3058                   s3_inst.relax_inst = INSN16_SH;
   3059                 }
   3060               else if (ldst_idx == INSN_SW)
   3061                 {
   3062                   s3_inst.relax_inst = INSN16_SW;
   3063                 }
   3064               else
   3065                 {
   3066                   s3_inst.relax_inst = 0x8000;
   3067                 }
   3068 
   3069               /* lw/lh/lbu/sw/sh/sb, offset = 0, relax to 16 bit instruction.  */
   3070               /* if ((ldst_idx == INSN_LBU)
   3071 		 || (ldst_idx == INSN_LH)
   3072 		 || (ldst_idx == INSN_LW)
   3073 		 || (ldst_idx == INSN_SB) || (ldst_idx == INSN_SH) || (ldst_idx == INSN_SW))*/
   3074               if ( (ldst_idx == INSN_LW)|| (ldst_idx == INSN_SW))
   3075                 {
   3076                   /* ra only 3 bit , rd only 4 bit for lw! and sw! */
   3077                   if ((((s3_inst.instruction >> 15) & 0x18) == 0) && (((s3_inst.instruction >> 20) & 0x10) == 0))
   3078                     {
   3079                       s3_inst.relax_inst |= (((s3_inst.instruction >> 20) & 0xf) << 8) |
   3080                         (((s3_inst.instruction >> 15) & 0x7) << 5);
   3081                       s3_inst.relax_size = 2;
   3082                     }
   3083                 }
   3084 
   3085               return;
   3086             }
   3087         }
   3088       /* ld/sw rD, [rA, simm15]    ld/sw rD, [rA, simm12]+.  */
   3089       else
   3090         {
   3091           if (s3_skip_past_comma (&str) == (int) s3_FAIL)
   3092             {
   3093               s3_inst.error = _("pre-indexed expression expected");
   3094               return;
   3095             }
   3096 
   3097           if (s3_my_get_expression (&s3_inst.reloc.exp, &str) == (int) s3_FAIL)
   3098 	    return;
   3099 
   3100           s3_skip_whitespace (str);
   3101           if (*str++ != ']')
   3102             {
   3103               s3_inst.error = _("missing ]");
   3104               return;
   3105             }
   3106 
   3107           s3_skip_whitespace (str);
   3108           /* ld/sw rD, [rA, simm12]+.  */
   3109           if (*str == '+')
   3110             {
   3111               str++;
   3112               pre_inc = 1;
   3113               if (conflict_reg)
   3114                 {
   3115                   unsigned int ldst_func = s3_inst.instruction & OPC_PSEUDOLDST_MASK;
   3116 
   3117                   if ((ldst_func == INSN_LH)
   3118                       || (ldst_func == INSN_LHU)
   3119                       || (ldst_func == INSN_LW)
   3120                       || (ldst_func == INSN_LB)
   3121                       || (ldst_func == INSN_LBU))
   3122                     {
   3123                       s3_inst.error = _("register same as write-back base");
   3124                       return;
   3125                     }
   3126                 }
   3127             }
   3128 
   3129           if (s3_end_of_line (str) == (int) s3_FAIL)
   3130 	    return;
   3131 
   3132           if (s3_inst.reloc.exp.X_op == O_constant)
   3133             {
   3134               unsigned int data_type;
   3135 
   3136               if (pre_inc == 1)
   3137                 data_type = _SIMM12;
   3138               else
   3139                 data_type = _SIMM15;
   3140               dataptr = temp;
   3141 
   3142               if ((*dataptr == '0') && (*(dataptr + 1) == 'x')
   3143                   && (data_type != _SIMM16_LA)
   3144                   && (data_type != _VALUE_HI16)
   3145                   && (data_type != _VALUE_LO16)
   3146                   && (data_type != _IMM16)
   3147                   && (data_type != _IMM15)
   3148                   && (data_type != _IMM14)
   3149                   && (data_type != _IMM4)
   3150                   && (data_type != _IMM5)
   3151                   && (data_type != _IMM8)
   3152                   && (data_type != _IMM5_RSHIFT_1)
   3153                   && (data_type != _IMM5_RSHIFT_2)
   3154                   && (data_type != _SIMM14_NEG)
   3155                   && (data_type != _IMM10_RSHIFT_2))
   3156                 {
   3157                   data_type += 24;
   3158                 }
   3159 
   3160               value = s3_validate_immediate (s3_inst.reloc.exp.X_add_number, data_type, 0);
   3161               if (value == (int) s3_FAIL)
   3162                 {
   3163                   if (data_type < 30)
   3164                     sprintf (s3_err_msg,
   3165                              _("invalid constant: %d bit expression not in range %d..%d"),
   3166                              s3_score_df_range[data_type].bits,
   3167                              s3_score_df_range[data_type].range[0], s3_score_df_range[data_type].range[1]);
   3168                   else
   3169                     sprintf (s3_err_msg,
   3170                              _("invalid constant: %d bit expression not in range %d..%d"),
   3171                              s3_score_df_range[data_type - 24].bits,
   3172                              s3_score_df_range[data_type - 24].range[0],
   3173                              s3_score_df_range[data_type - 24].range[1]);
   3174                   s3_inst.error = s3_err_msg;
   3175                   return;
   3176                 }
   3177 
   3178               value &= (1 << s3_score_df_range[data_type].bits) - 1;
   3179               ldst_idx = s3_inst.instruction & OPC_PSEUDOLDST_MASK;
   3180               s3_inst.instruction &= ~OPC_PSEUDOLDST_MASK;
   3181               s3_inst.instruction |= s3_score_ldst_insns[ldst_idx * 3 + pre_inc].value;
   3182               if (pre_inc == 1)
   3183                 s3_inst.instruction |= value << 3;
   3184               else
   3185                 s3_inst.instruction |= value;
   3186 
   3187               /* lw rD, [rA, simm15]  */
   3188               if ((s3_inst.instruction & 0x3e000000) == 0x20000000)
   3189                 {
   3190                   /*  rD  in [r0 - r15]. , ra in [r0-r7] */
   3191                   if ((((s3_inst.instruction >> 15) & 0x18) == 0)
   3192                       && (((s3_inst.instruction >> 20) & 0x10) == 0))
   3193                     {
   3194                       /* simm = [bit 7], lw -> lw!.  */
   3195                       if (((s3_inst.instruction & 0x7f80) == 0)&&((s3_inst.instruction &0x3)==0))
   3196                         {
   3197                           s3_inst.relax_inst |= (((s3_inst.instruction >> 15) & 0x7) << 5)
   3198                             | (((s3_inst.instruction >> 20) & 0xf) << 8)|(value>>2);
   3199                           s3_inst.relax_size = 2;
   3200                         }
   3201                       else
   3202                         {
   3203                           s3_inst.relax_inst = 0x8000;
   3204                         }
   3205                     }
   3206                   else
   3207                     {
   3208                       s3_inst.relax_inst = 0x8000;
   3209                     }
   3210                 }
   3211               /* sw rD, [rA, simm15]  */
   3212               else if ((s3_inst.instruction & 0x3e000000) == 0x28000000)
   3213                 {
   3214                   /* rD is  in [r0 - r15] and ra in [r0-r7] */
   3215                   if ((((s3_inst.instruction >> 15) & 0x18) == 0) && (((s3_inst.instruction >> 20) & 0x10) == 0))
   3216                     {
   3217                       /* simm15 =7 bit  , sw -> sw!.  */
   3218                       if (((s3_inst.instruction & 0x7f80) == 0)&&((s3_inst.instruction &0x3)==0))
   3219                         {
   3220                           s3_inst.relax_inst |= (((s3_inst.instruction >> 15) & 0xf) << 5)
   3221                             | (((s3_inst.instruction >> 20) & 0xf) << 8)|(value>>2);
   3222                           s3_inst.relax_size = 2;
   3223                         }
   3224                       /* rA = r2, sw -> swp!.  */
   3225                       else
   3226                         {
   3227                           s3_inst.relax_inst = 0x8000;
   3228                         }
   3229                     }
   3230                   else
   3231                     {
   3232                       s3_inst.relax_inst = 0x8000;
   3233                     }
   3234                 }
   3235               /* sw rD, [rA, simm15]+    sw pre.  */
   3236               else if ((s3_inst.instruction & 0x3e000007) == 0x06000004)
   3237                 {
   3238                   /* simm15 = -4. and ra==r0 */
   3239                   if ((((s3_inst.instruction >> 15) & 0x1f) == 0)
   3240                       && (((s3_inst.instruction >> 3) & 0xfff) == 0xffc))
   3241                     {
   3242                       /* sw -> push!.  */
   3243                       s3_inst.relax_inst = 0x0060 | ((s3_inst.instruction >> 20) & 0x1f);
   3244                       s3_inst.relax_size = 2;
   3245                     }
   3246                   else
   3247                     {
   3248                       s3_inst.relax_inst = 0x8000;
   3249                     }
   3250                 }
   3251               else
   3252                 {
   3253                   s3_inst.relax_inst = 0x8000;
   3254                 }
   3255 
   3256               return;
   3257             }
   3258           else
   3259             {
   3260               /* FIXME: may set error, for there is no ld/sw rD, [rA, label] */
   3261               s3_inst.reloc.pc_rel = 0;
   3262             }
   3263         }
   3264     }
   3265   else
   3266     {
   3267       s3_inst.error = s3_BAD_ARGS;
   3268     }
   3269 }
   3270 
   3271 /* Handle cache.  */
   3272 static void
   3273 s3_do_cache (char *str)
   3274 {
   3275   s3_skip_whitespace (str);
   3276 
   3277   if ((s3_data_op2 (&str, 20, _IMM5) == (int) s3_FAIL) || (s3_skip_past_comma (&str) == (int) s3_FAIL))
   3278     {
   3279       return;
   3280     }
   3281   else
   3282     {
   3283       int cache_op;
   3284 
   3285       cache_op = (s3_inst.instruction >> 20) & 0x1F;
   3286       sprintf (s3_inst.name, "cache %d", cache_op);
   3287     }
   3288 
   3289   if (*str == '[')
   3290     {
   3291       str++;
   3292       s3_skip_whitespace (str);
   3293 
   3294       if (s3_reg_required_here (&str, 15, s3_REG_TYPE_SCORE) == (int) s3_FAIL)
   3295 	return;
   3296 
   3297       s3_skip_whitespace (str);
   3298 
   3299       /* cache op, [rA]  */
   3300       if (s3_skip_past_comma (&str) == (int) s3_FAIL)
   3301         {
   3302           s3_SET_INSN_ERROR (NULL);
   3303           if (*str != ']')
   3304             {
   3305               s3_inst.error = _("missing ]");
   3306               return;
   3307             }
   3308           str++;
   3309         }
   3310       /* cache op, [rA, simm15]  */
   3311       else
   3312         {
   3313           if (s3_exp_ldst_offset (&str, 0, _SIMM15) == (int) s3_FAIL)
   3314             {
   3315               return;
   3316             }
   3317 
   3318           s3_skip_whitespace (str);
   3319           if (*str++ != ']')
   3320             {
   3321               s3_inst.error = _("missing ]");
   3322               return;
   3323             }
   3324         }
   3325 
   3326       if (s3_end_of_line (str) == (int) s3_FAIL)
   3327 	return;
   3328     }
   3329   else
   3330     {
   3331       s3_inst.error = s3_BAD_ARGS;
   3332     }
   3333 }
   3334 
   3335 static void
   3336 s3_do_crdcrscrsimm5 (char *str)
   3337 {
   3338   char *strbak;
   3339 
   3340   strbak = str;
   3341   s3_skip_whitespace (str);
   3342 
   3343   if (s3_reg_required_here (&str, 20, s3_REG_TYPE_SCORE_CR) == (int) s3_FAIL
   3344       || s3_skip_past_comma (&str) == (int) s3_FAIL
   3345       || s3_reg_required_here (&str, 15, s3_REG_TYPE_SCORE_CR) == (int) s3_FAIL
   3346       || s3_skip_past_comma (&str) == (int) s3_FAIL
   3347       || s3_reg_required_here (&str, 10, s3_REG_TYPE_SCORE_CR) == (int) s3_FAIL
   3348       || s3_skip_past_comma (&str) == (int) s3_FAIL)
   3349     {
   3350       str = strbak;
   3351       /* cop1 cop_code20.  */
   3352       if (s3_data_op2 (&str, 5, _IMM20) == (int) s3_FAIL)
   3353 	return;
   3354     }
   3355   else
   3356     {
   3357       if (s3_data_op2 (&str, 5, _IMM5) == (int) s3_FAIL)
   3358 	return;
   3359     }
   3360 
   3361   s3_end_of_line (str);
   3362 }
   3363 
   3364 /* Handle ldc/stc.  */
   3365 static void
   3366 s3_do_ldst_cop (char *str)
   3367 {
   3368   s3_skip_whitespace (str);
   3369 
   3370   if ((s3_reg_required_here (&str, 15, s3_REG_TYPE_SCORE_CR) == (int) s3_FAIL)
   3371       || (s3_skip_past_comma (&str) == (int) s3_FAIL))
   3372     return;
   3373 
   3374   if (*str == '[')
   3375     {
   3376       str++;
   3377       s3_skip_whitespace (str);
   3378 
   3379       if (s3_reg_required_here (&str, 20, s3_REG_TYPE_SCORE) == (int) s3_FAIL)
   3380 	return;
   3381 
   3382       s3_skip_whitespace (str);
   3383 
   3384       if (*str++ != ']')
   3385         {
   3386           if (s3_exp_ldst_offset (&str, 5, _IMM10_RSHIFT_2) == (int) s3_FAIL)
   3387 	    return;
   3388 
   3389           s3_skip_whitespace (str);
   3390           if (*str++ != ']')
   3391             {
   3392               s3_inst.error = _("missing ]");
   3393               return;
   3394             }
   3395         }
   3396 
   3397       s3_end_of_line (str);
   3398     }
   3399   else
   3400     s3_inst.error = s3_BAD_ARGS;
   3401 }
   3402 
   3403 static void
   3404 s3_do16_ldst_insn (char *str)
   3405 {
   3406   int conflict_reg = 0;
   3407   s3_skip_whitespace (str);
   3408 
   3409   if ((s3_reglow_required_here (&str, 8) == (int) s3_FAIL) || (s3_skip_past_comma (&str) == (int) s3_FAIL))
   3410     return;
   3411 
   3412   if (*str == '[')
   3413     {
   3414 
   3415       str++;
   3416       s3_skip_whitespace (str);
   3417 
   3418       if ((conflict_reg = s3_reglow_required_here (&str, 5)) == (int) s3_FAIL)
   3419 	return;
   3420       if (conflict_reg&0x8)
   3421         {
   3422           sprintf (s3_err_msg,  _("invalid register number: %d is not in [r0--r7]"),conflict_reg);
   3423           s3_inst.error = s3_err_msg;
   3424           return;
   3425         }
   3426 
   3427       s3_skip_whitespace (str);
   3428 
   3429       if (*str == ']')
   3430         {
   3431           str++;
   3432           if (s3_end_of_line (str) == (int) s3_FAIL)
   3433 	    return;
   3434         }
   3435       else
   3436         {
   3437           if (s3_skip_past_comma (&str) == (int) s3_FAIL)
   3438 	    {
   3439 	      s3_inst.error = _("comma is  expected");
   3440               return;
   3441 	    }
   3442           if (s3_my_get_expression (&s3_inst.reloc.exp, &str) == (int) s3_FAIL)
   3443 	    return;
   3444           s3_skip_whitespace (str);
   3445 	  if (*str++ != ']')
   3446 	    {
   3447 	      s3_inst.error = _("missing ]");
   3448 	      return;
   3449 	    }
   3450           if (s3_end_of_line (str) == (int) s3_FAIL)
   3451 	    return;
   3452           if (s3_inst.reloc.exp.X_op == O_constant)
   3453             {
   3454               int value;
   3455 	      unsigned int data_type;
   3456               data_type = _IMM5_RSHIFT_2;
   3457               value = s3_validate_immediate (s3_inst.reloc.exp.X_add_number, data_type, 0);
   3458               if (value == (int) s3_FAIL)
   3459 		{
   3460 		  if (data_type < 30)
   3461 		    sprintf (s3_err_msg,
   3462 			     _("invalid constant: %d bit expression not in range %d..%d"),
   3463 			     s3_score_df_range[data_type].bits,
   3464 			     s3_score_df_range[data_type].range[0], s3_score_df_range[data_type].range[1]);
   3465                   s3_inst.error = s3_err_msg;
   3466 	          return;
   3467 	        }
   3468               if (value & 0x3)
   3469                 {
   3470                   sprintf (s3_err_msg,  _("invalid constant: %d is not word align integer"),value);
   3471                   s3_inst.error = s3_err_msg;
   3472                   return;
   3473                 }
   3474 
   3475               value >>= 2;
   3476               s3_inst.instruction |= value;
   3477             }
   3478         }
   3479     }
   3480   else
   3481     {
   3482       sprintf (s3_err_msg,  _("missing ["));
   3483       s3_inst.error = s3_err_msg;
   3484       return;
   3485     }
   3486 }
   3487 
   3488 static void
   3489 s3_do_lw48 (char *str)
   3490 {
   3491   bfd_signed_vma val = 0;
   3492 
   3493   s3_skip_whitespace (str);
   3494 
   3495   if ((s3_reg_required_here (&str, 37, s3_REG_TYPE_SCORE) == (int) s3_FAIL)
   3496       || (s3_skip_past_comma (&str) == (int) s3_FAIL))
   3497     return;
   3498 
   3499   if (s3_my_get_expression (&s3_inst.reloc.exp, &str) == (int) s3_FAIL
   3500       || s3_end_of_line (str) == (int) s3_FAIL)
   3501     {
   3502       return;
   3503     }
   3504 
   3505   /* Check word align for lw48 rd, value.  */
   3506   if ((s3_inst.reloc.exp.X_add_symbol == NULL)
   3507       && ((s3_inst.reloc.exp.X_add_number & 0x3) != 0))
   3508     {
   3509       s3_inst.error = _("invalid constant: 32 bit expression not word align");
   3510       return;
   3511     }
   3512 
   3513   /* Check and set offset.  */
   3514   val = s3_inst.reloc.exp.X_add_number;
   3515   if ((s3_inst.reloc.exp.X_add_symbol == NULL)
   3516       && (!(val >= 0 && val <= 0xffffffffLL)))
   3517     {
   3518       s3_inst.error = _("invalid constant: 32 bit expression not in range [0, 0xffffffff]");
   3519       return;
   3520     }
   3521 
   3522   val &= 0xffffffff;
   3523   val >>= 2;
   3524   s3_inst.instruction |= (val << 7);
   3525 
   3526   /* Set reloc type.  */
   3527   s3_inst.reloc.type = BFD_RELOC_SCORE_IMM30;
   3528 
   3529 }
   3530 
   3531 static void
   3532 s3_do_sw48 (char *str)
   3533 {
   3534   bfd_signed_vma val = 0;
   3535 
   3536   s3_skip_whitespace (str);
   3537 
   3538   if ((s3_reg_required_here (&str, 37, s3_REG_TYPE_SCORE) == (int) s3_FAIL)
   3539       || (s3_skip_past_comma (&str) == (int) s3_FAIL))
   3540     return;
   3541 
   3542   if (s3_my_get_expression (&s3_inst.reloc.exp, &str) == (int) s3_FAIL
   3543       || s3_end_of_line (str) == (int) s3_FAIL)
   3544     {
   3545       return;
   3546     }
   3547 
   3548   /* Check word align for lw48 rd, value.  */
   3549   if ((s3_inst.reloc.exp.X_add_symbol == NULL)
   3550       && ((s3_inst.reloc.exp.X_add_number & 0x3) != 0))
   3551     {
   3552       s3_inst.error = _("invalid constant: 32 bit expression not word align");
   3553       return;
   3554     }
   3555 
   3556   /* Check and set offset.  */
   3557   val = s3_inst.reloc.exp.X_add_number;
   3558   if ((s3_inst.reloc.exp.X_add_symbol == NULL)
   3559       && (!(val >= 0 && val <= 0xffffffffLL)))
   3560     {
   3561       s3_inst.error = _("invalid constant: 32 bit expression not in range [0, 0xffffffff]");
   3562       return;
   3563     }
   3564 
   3565   val &= 0xffffffff;
   3566   val >>= 2;
   3567   s3_inst.instruction |= (val << 7);
   3568 
   3569   /* Set reloc type.  */
   3570   s3_inst.reloc.type = BFD_RELOC_SCORE_IMM30;
   3571 }
   3572 
   3573 static void
   3574 s3_do_ldi48 (char *str)
   3575 {
   3576   bfd_signed_vma val;
   3577 
   3578   s3_skip_whitespace (str);
   3579 
   3580   if (s3_reg_required_here (&str, 37, s3_REG_TYPE_SCORE) == (int) s3_FAIL
   3581       || s3_skip_past_comma (&str) == (int) s3_FAIL)
   3582     return;
   3583 
   3584   if (s3_my_get_expression (&s3_inst.reloc.exp, &str) == (int) s3_FAIL
   3585       || s3_end_of_line (str) == (int) s3_FAIL)
   3586     {
   3587       return;
   3588     }
   3589 
   3590   /* Check and set offset.  */
   3591   val = s3_inst.reloc.exp.X_add_number;
   3592   if (!(val >= -0xffffffffLL && val <= 0xffffffffLL))
   3593     {
   3594       s3_inst.error = _("invalid constant: 32 bit expression not in range [-0x80000000, 0x7fffffff]");
   3595       return;
   3596     }
   3597 
   3598   val &= 0xffffffff;
   3599   s3_inst.instruction |= (val << 5);
   3600 
   3601   /* Set reloc type.  */
   3602   s3_inst.reloc.type = BFD_RELOC_SCORE_IMM32;
   3603 }
   3604 
   3605 static void
   3606 s3_do_sdbbp48 (char *str)
   3607 {
   3608   s3_skip_whitespace (str);
   3609 
   3610   if (s3_data_op2 (&str, 5, _IMM5) == (int) s3_FAIL || s3_end_of_line (str) == (int) s3_FAIL)
   3611     return;
   3612 }
   3613 
   3614 static void
   3615 s3_do_and48 (char *str)
   3616 {
   3617   s3_skip_whitespace (str);
   3618 
   3619   if (s3_reglow_required_here (&str, 38) == (int) s3_FAIL
   3620       || s3_skip_past_comma (&str) == (int) s3_FAIL
   3621       || s3_reglow_required_here (&str, 34) == (int) s3_FAIL
   3622       || s3_skip_past_comma (&str) == (int) s3_FAIL
   3623       || s3_data_op2 (&str, 2, _IMM32) == (int) s3_FAIL
   3624       || s3_end_of_line (str) == (int) s3_FAIL)
   3625     return;
   3626 }
   3627 
   3628 static void
   3629 s3_do_or48 (char *str)
   3630 {
   3631   s3_skip_whitespace (str);
   3632 
   3633   if (s3_reglow_required_here (&str, 38) == (int) s3_FAIL
   3634       || s3_skip_past_comma (&str) == (int) s3_FAIL
   3635       || s3_reglow_required_here (&str, 34) == (int) s3_FAIL
   3636       || s3_skip_past_comma (&str) == (int) s3_FAIL
   3637       || s3_data_op2 (&str, 2, _IMM32) == (int) s3_FAIL
   3638       || s3_end_of_line (str) == (int) s3_FAIL)
   3639     return;
   3640 }
   3641 
   3642 static void
   3643 s3_do_mbitclr (char *str)
   3644 {
   3645   int val;
   3646   s3_skip_whitespace (str);
   3647 
   3648   if (*str != '[')
   3649     {
   3650       sprintf (s3_err_msg,  _("missing ["));
   3651       s3_inst.error = s3_err_msg;
   3652       return;
   3653     }
   3654   str++;
   3655 
   3656   s3_inst.instruction &= 0x0;
   3657 
   3658   if ((s3_reg_required_here (&str, 15, s3_REG_TYPE_SCORE) == (int) s3_FAIL)
   3659       || (s3_skip_past_comma (&str) == (int) s3_FAIL)
   3660       || (s3_data_op2 (&str, 0, _IMM11) == (int) s3_FAIL))
   3661     return;
   3662 
   3663   /* Get imm11 and refill opcode.  */
   3664   val = s3_inst.instruction & 0x7ff;
   3665   val >>= 2;
   3666   s3_inst.instruction &= 0x000f8000;
   3667   s3_inst.instruction |= 0x00000064;
   3668 
   3669   if (*str != ']')
   3670     {
   3671       sprintf (s3_err_msg,  _("missing ]"));
   3672       s3_inst.error = s3_err_msg;
   3673       return;
   3674     }
   3675   str++;
   3676 
   3677   if ((s3_skip_past_comma (&str) == (int) s3_FAIL)
   3678       || (s3_data_op2 (&str, 10, _IMM5) == (int) s3_FAIL))
   3679     return;
   3680 
   3681   /* Set imm11 to opcode.  */
   3682   s3_inst.instruction |= (val & 0x1)
   3683     | (((val >> 1 ) & 0x7) << 7)
   3684     | (((val >> 4 ) & 0x1f) << 20);
   3685 }
   3686 
   3687 static void
   3688 s3_do_mbitset (char *str)
   3689 {
   3690   int val;
   3691   s3_skip_whitespace (str);
   3692 
   3693   if (*str != '[')
   3694     {
   3695       sprintf (s3_err_msg,  _("missing ["));
   3696       s3_inst.error = s3_err_msg;
   3697       return;
   3698     }
   3699   str++;
   3700 
   3701   s3_inst.instruction &= 0x0;
   3702 
   3703   if ((s3_reg_required_here (&str, 15, s3_REG_TYPE_SCORE) == (int) s3_FAIL)
   3704       || (s3_skip_past_comma (&str) == (int) s3_FAIL)
   3705       || (s3_data_op2 (&str, 0, _IMM11) == (int) s3_FAIL))
   3706     return;
   3707 
   3708   /* Get imm11 and refill opcode.  */
   3709   val = s3_inst.instruction & 0x7ff;
   3710   val >>= 2;
   3711   s3_inst.instruction &= 0x000f8000;
   3712   s3_inst.instruction |= 0x0000006c;
   3713 
   3714   if (*str != ']')
   3715     {
   3716       sprintf (s3_err_msg,  _("missing ]"));
   3717       s3_inst.error = s3_err_msg;
   3718       return;
   3719     }
   3720   str++;
   3721 
   3722   if ((s3_skip_past_comma (&str) == (int) s3_FAIL)
   3723       || (s3_data_op2 (&str, 10, _IMM5) == (int) s3_FAIL))
   3724     return;
   3725 
   3726   /* Set imm11 to opcode.  */
   3727   s3_inst.instruction |= (val & 0x1)
   3728     | (((val >> 1 ) & 0x7) << 7)
   3729     | (((val >> 4 ) & 0x1f) << 20);
   3730 }
   3731 
   3732 static void
   3733 s3_do16_slli_srli (char *str)
   3734 {
   3735   s3_skip_whitespace (str);
   3736 
   3737   if ((s3_reglow_required_here (&str, 5) == (int) s3_FAIL)
   3738       || (s3_skip_past_comma (&str) == (int) s3_FAIL)
   3739       || s3_data_op2 (&str, 0, _IMM5) == (int) s3_FAIL
   3740       || s3_end_of_line (str) == (int) s3_FAIL)
   3741     return;
   3742 }
   3743 
   3744 static void
   3745 s3_do16_ldiu (char *str)
   3746 {
   3747   s3_skip_whitespace (str);
   3748 
   3749   if ((s3_reg_required_here (&str, 5,s3_REG_TYPE_SCORE) == (int) s3_FAIL)
   3750       || (s3_skip_past_comma (&str) == (int) s3_FAIL)
   3751       || s3_data_op2 (&str, 0, _IMM5) == (int) s3_FAIL
   3752       || s3_end_of_line (str) == (int) s3_FAIL)
   3753     return;
   3754 }
   3755 
   3756 static void
   3757 s3_do16_push_pop (char *str)
   3758 {
   3759   s3_skip_whitespace (str);
   3760   if ((s3_reg_required_here (&str, 0, s3_REG_TYPE_SCORE)) == (int) s3_FAIL
   3761       || s3_end_of_line (str) == (int) s3_FAIL)
   3762     return;
   3763 }
   3764 
   3765 static void
   3766 s3_do16_rpush (char *str)
   3767 {
   3768   int reg;
   3769   int val;
   3770   s3_skip_whitespace (str);
   3771   if ((reg = (s3_reg_required_here (&str, 5, s3_REG_TYPE_SCORE))) == (int) s3_FAIL
   3772       || s3_skip_past_comma (&str) == (int) s3_FAIL
   3773       || s3_data_op2 (&str, 0, _IMM5_MULTI_LOAD) == (int) s3_FAIL
   3774       || s3_end_of_line (str) == (int) s3_FAIL)
   3775     return;
   3776 
   3777   /* 0: indicate 32.
   3778      1: invalide value.
   3779      2: to 31: normal value.  */
   3780   val = s3_inst.instruction & 0x1f;
   3781   if (val == 1)
   3782     {
   3783       s3_inst.error = _("imm5 should >= 2");
   3784       return;
   3785     }
   3786   if (reg >= 32)
   3787     {
   3788       s3_inst.error = _("reg should <= 31");
   3789       return;
   3790     }
   3791 }
   3792 
   3793 static void
   3794 s3_do16_rpop (char *str)
   3795 {
   3796   int reg;
   3797   int val;
   3798   s3_skip_whitespace (str);
   3799   if ((reg = (s3_reg_required_here (&str, 5, s3_REG_TYPE_SCORE))) == (int) s3_FAIL
   3800       || s3_skip_past_comma (&str) == (int) s3_FAIL
   3801       || s3_data_op2 (&str, 0, _IMM5_MULTI_LOAD) == (int) s3_FAIL
   3802       || s3_end_of_line (str) == (int) s3_FAIL)
   3803     return;
   3804 
   3805   /* 0: indicate 32.
   3806      1: invalide value.
   3807      2: to 31: normal value.  */
   3808   val = s3_inst.instruction & 0x1f;
   3809   if (val == 1)
   3810     {
   3811       s3_inst.error = _("imm5 should >= 2");
   3812       return;
   3813     }
   3814 
   3815   if (reg >= 32)
   3816     {
   3817       s3_inst.error = _("reg should <= 31");
   3818       return;
   3819     }
   3820   else
   3821     {
   3822       if ((reg + val) <= 32)
   3823         reg = reg + val - 1;
   3824       else
   3825         reg = reg + val - 33;
   3826       s3_inst.instruction &= 0x7c1f;
   3827       s3_inst.instruction |= (reg << 5);
   3828       return;
   3829     }
   3830 }
   3831 
   3832 /* Handle lcb/lcw/lce/scb/scw/sce.  */
   3833 static void
   3834 s3_do_ldst_unalign (char *str)
   3835 {
   3836   int conflict_reg;
   3837 
   3838   if (s3_university_version == 1)
   3839     {
   3840       s3_inst.error = s3_ERR_FOR_SCORE5U_ATOMIC;
   3841       return;
   3842     }
   3843 
   3844   s3_skip_whitespace (str);
   3845 
   3846   /* lcb/scb [rA]+.  */
   3847   if (*str == '[')
   3848     {
   3849       str++;
   3850       s3_skip_whitespace (str);
   3851 
   3852       if (s3_reg_required_here (&str, 15, s3_REG_TYPE_SCORE) == (int) s3_FAIL)
   3853 	return;
   3854 
   3855       if (*str++ == ']')
   3856         {
   3857           if (*str++ != '+')
   3858             {
   3859               s3_inst.error = _("missing +");
   3860               return;
   3861             }
   3862         }
   3863       else
   3864         {
   3865           s3_inst.error = _("missing ]");
   3866           return;
   3867         }
   3868 
   3869       if (s3_end_of_line (str) == (int) s3_FAIL)
   3870 	return;
   3871     }
   3872   /* lcw/lce/scb/sce rD, [rA]+.  */
   3873   else
   3874     {
   3875       if (((conflict_reg = s3_reg_required_here (&str, 20, s3_REG_TYPE_SCORE)) == (int) s3_FAIL)
   3876           || (s3_skip_past_comma (&str) == (int) s3_FAIL))
   3877         {
   3878           return;
   3879         }
   3880 
   3881       s3_skip_whitespace (str);
   3882       if (*str++ == '[')
   3883         {
   3884           int reg;
   3885 
   3886           s3_skip_whitespace (str);
   3887           if ((reg = s3_reg_required_here (&str, 15, s3_REG_TYPE_SCORE)) == (int) s3_FAIL)
   3888             {
   3889               return;
   3890             }
   3891 
   3892           /* Conflicts can occur on stores as well as loads.  */
   3893           conflict_reg = (conflict_reg == reg);
   3894           s3_skip_whitespace (str);
   3895           if (*str++ == ']')
   3896             {
   3897               unsigned int ldst_func = s3_inst.instruction & LDST_UNALIGN_MASK;
   3898 
   3899               if (*str++ == '+')
   3900                 {
   3901                   if (conflict_reg)
   3902                     {
   3903                       as_warn (_("%s register same as write-back base"),
   3904                                ((ldst_func & UA_LCE) || (ldst_func & UA_LCW)
   3905                                 ? _("destination") : _("source")));
   3906                     }
   3907                 }
   3908               else
   3909                 {
   3910                   s3_inst.error = _("missing +");
   3911                   return;
   3912                 }
   3913 
   3914               if (s3_end_of_line (str) == (int) s3_FAIL)
   3915 		return;
   3916             }
   3917           else
   3918             {
   3919               s3_inst.error = _("missing ]");
   3920               return;
   3921             }
   3922         }
   3923       else
   3924         {
   3925           s3_inst.error = s3_BAD_ARGS;
   3926           return;
   3927         }
   3928     }
   3929 }
   3930 
   3931 /* Handle alw/asw.  */
   3932 static void
   3933 s3_do_ldst_atomic (char *str)
   3934 {
   3935   if (s3_university_version == 1)
   3936     {
   3937       s3_inst.error = s3_ERR_FOR_SCORE5U_ATOMIC;
   3938       return;
   3939     }
   3940 
   3941   s3_skip_whitespace (str);
   3942 
   3943   if ((s3_reg_required_here (&str, 20, s3_REG_TYPE_SCORE) == (int) s3_FAIL)
   3944       || (s3_skip_past_comma (&str) == (int) s3_FAIL))
   3945     {
   3946       return;
   3947     }
   3948   else
   3949     {
   3950 
   3951       s3_skip_whitespace (str);
   3952       if (*str++ == '[')
   3953         {
   3954           int reg;
   3955 
   3956           s3_skip_whitespace (str);
   3957           if ((reg = s3_reg_required_here (&str, 15, s3_REG_TYPE_SCORE)) == (int) s3_FAIL)
   3958             {
   3959               return;
   3960             }
   3961 
   3962           s3_skip_whitespace (str);
   3963           if (*str++ != ']')
   3964             {
   3965               s3_inst.error = _("missing ]");
   3966               return;
   3967             }
   3968 
   3969           s3_end_of_line (str);
   3970         }
   3971       else
   3972 	s3_inst.error = s3_BAD_ARGS;
   3973     }
   3974 }
   3975 
   3976 static void
   3977 s3_build_relax_frag (struct s3_score_it fix_insts[s3_RELAX_INST_NUM], int fix_num ATTRIBUTE_UNUSED,
   3978 		     struct s3_score_it var_insts[s3_RELAX_INST_NUM], int var_num,
   3979 		     symbolS *add_symbol)
   3980 {
   3981   int i;
   3982   char *p;
   3983   fixS *fixp = NULL;
   3984   fixS *cur_fixp = NULL;
   3985   long where;
   3986   struct s3_score_it inst_main;
   3987 
   3988   memcpy (&inst_main, &fix_insts[0], sizeof (struct s3_score_it));
   3989 
   3990   /* Adjust instruction opcode and to be relaxed instruction opcode.  */
   3991   inst_main.instruction = s3_adjust_paritybit (inst_main.instruction, s3_GET_INSN_CLASS (inst_main.type));
   3992   inst_main.type = Insn_PIC;
   3993 
   3994   for (i = 0; i < var_num; i++)
   3995     {
   3996       inst_main.relax_size += var_insts[i].size;
   3997       var_insts[i].instruction = s3_adjust_paritybit (var_insts[i].instruction,
   3998 						      s3_GET_INSN_CLASS (var_insts[i].type));
   3999     }
   4000 
   4001   /* Check data dependency.  */
   4002   s3_handle_dependency (&inst_main);
   4003 
   4004   /* Start a new frag if frag_now is not empty.  */
   4005   if (frag_now_fix () != 0)
   4006     {
   4007       if (!frag_now->tc_frag_data.is_insn)
   4008 	{
   4009           frag_wane (frag_now);
   4010 	}
   4011       frag_new (0);
   4012     }
   4013   frag_grow (20);
   4014 
   4015   /* Write fr_fix part.  */
   4016   p = frag_more (inst_main.size);
   4017   s3_md_number_to_chars (p, inst_main.instruction, inst_main.size);
   4018 
   4019   if (inst_main.reloc.type != BFD_RELOC_NONE)
   4020     fixp = s3_fix_new_score (frag_now, p - frag_now->fr_literal, inst_main.size,
   4021 			     &inst_main.reloc.exp, inst_main.reloc.pc_rel, inst_main.reloc.type);
   4022 
   4023   frag_now->tc_frag_data.fixp = fixp;
   4024   cur_fixp = frag_now->tc_frag_data.fixp;
   4025 
   4026 #ifdef OBJ_ELF
   4027   dwarf2_emit_insn (inst_main.size);
   4028 #endif
   4029 
   4030   where = p - frag_now->fr_literal + inst_main.size;
   4031   for (i = 0; i < var_num; i++)
   4032     {
   4033       if (i > 0)
   4034         where += var_insts[i - 1].size;
   4035 
   4036       if (var_insts[i].reloc.type != BFD_RELOC_NONE)
   4037         {
   4038           fixp = s3_fix_new_score (frag_now, where, var_insts[i].size,
   4039 				   &var_insts[i].reloc.exp, var_insts[i].reloc.pc_rel,
   4040 				   var_insts[i].reloc.type);
   4041           if (fixp)
   4042             {
   4043               if (cur_fixp)
   4044                 {
   4045                   cur_fixp->fx_next = fixp;
   4046                   cur_fixp = cur_fixp->fx_next;
   4047                 }
   4048               else
   4049                 {
   4050                   frag_now->tc_frag_data.fixp = fixp;
   4051                   cur_fixp = frag_now->tc_frag_data.fixp;
   4052                 }
   4053 	    }
   4054         }
   4055     }
   4056 
   4057   p = frag_var (rs_machine_dependent, inst_main.relax_size + s3_RELAX_PAD_BYTE, 0,
   4058                 s3_RELAX_ENCODE (inst_main.size, inst_main.relax_size, inst_main.type,
   4059 				 0, inst_main.size, 0), add_symbol, 0, NULL);
   4060 
   4061   /* Write fr_var part.
   4062      no calling s3_gen_insn_frag, no fixS will be generated.  */
   4063   for (i = 0; i < var_num; i++)
   4064     {
   4065       s3_md_number_to_chars (p, var_insts[i].instruction, var_insts[i].size);
   4066       p += var_insts[i].size;
   4067     }
   4068   /* Set bwarn as -1, so macro instruction itself will not be generated frag.  */
   4069   s3_inst.bwarn = -1;
   4070 }
   4071 
   4072 /* Build a relax frag for la instruction when generating s3_PIC,
   4073    external symbol first and local symbol second.  */
   4074 static void
   4075 s3_build_la_pic (int reg_rd, expressionS exp)
   4076 {
   4077   symbolS *add_symbol = exp.X_add_symbol;
   4078   offsetT add_number = exp.X_add_number;
   4079   struct s3_score_it fix_insts[s3_RELAX_INST_NUM];
   4080   struct s3_score_it var_insts[s3_RELAX_INST_NUM];
   4081   int fix_num = 0;
   4082   int var_num = 0;
   4083   char tmp[s3_MAX_LITERAL_POOL_SIZE];
   4084   int r1_bak;
   4085 
   4086   r1_bak = s3_nor1;
   4087   s3_nor1 = 0;
   4088 
   4089   if (add_number == 0)
   4090     {
   4091       fix_num = 1;
   4092       var_num = 2;
   4093 
   4094       /* For an external symbol, only one insn is generated;
   4095          For a local symbol, two insns are generated.  */
   4096       /* Fix part
   4097          For an external symbol: lw rD, <sym>($gp)
   4098 	 (BFD_RELOC_SCORE_GOT15 or BFD_RELOC_SCORE_CALL15)  */
   4099       sprintf (tmp, "lw_pic r%d, %s", reg_rd, add_symbol->bsym->name);
   4100       if (s3_append_insn (tmp, FALSE) == (int) s3_FAIL)
   4101 	return;
   4102 
   4103       if (reg_rd == s3_PIC_CALL_REG)
   4104         s3_inst.reloc.type = BFD_RELOC_SCORE_CALL15;
   4105       memcpy (&fix_insts[0], &s3_inst, sizeof (struct s3_score_it));
   4106 
   4107       /* Var part
   4108 	 For a local symbol :
   4109          lw rD, <sym>($gp)    (BFD_RELOC_SCORE_GOT15)
   4110 	 addi rD, <sym>       (BFD_RELOC_GOT_LO16) */
   4111       s3_inst.reloc.type = BFD_RELOC_SCORE_GOT15;
   4112       memcpy (&var_insts[0], &s3_inst, sizeof (struct s3_score_it));
   4113       sprintf (tmp, "addi_s_pic r%d, %s", reg_rd, add_symbol->bsym->name);
   4114       if (s3_append_insn (tmp, FALSE) == (int) s3_FAIL)
   4115 	return;
   4116 
   4117       memcpy (&var_insts[1], &s3_inst, sizeof (struct s3_score_it));
   4118       s3_build_relax_frag (fix_insts, fix_num, var_insts, var_num, add_symbol);
   4119     }
   4120   else if (add_number >= -0x8000 && add_number <= 0x7fff)
   4121     {
   4122       /* Insn 1: lw rD, <sym>($gp)    (BFD_RELOC_SCORE_GOT15)  */
   4123       sprintf (tmp, "lw_pic r%d, %s", reg_rd, add_symbol->bsym->name);
   4124       if (s3_append_insn (tmp, TRUE) == (int) s3_FAIL)
   4125 	return;
   4126 
   4127       /* Insn 2  */
   4128       fix_num = 1;
   4129       var_num = 1;
   4130       /* Fix part
   4131          For an external symbol: addi rD, <constant> */
   4132       sprintf (tmp, "addi r%d, %d", reg_rd, (int)add_number);
   4133       if (s3_append_insn (tmp, FALSE) == (int) s3_FAIL)
   4134 	return;
   4135 
   4136       memcpy (&fix_insts[0], &s3_inst, sizeof (struct s3_score_it));
   4137 
   4138       /* Var part
   4139  	 For a local symbol: addi rD, <sym>+<constant>    (BFD_RELOC_GOT_LO16)  */
   4140       sprintf (tmp, "addi_s_pic r%d, %s + %d", reg_rd, add_symbol->bsym->name, (int)add_number);
   4141       if (s3_append_insn (tmp, FALSE) == (int) s3_FAIL)
   4142 	return;
   4143 
   4144       memcpy (&var_insts[0], &s3_inst, sizeof (struct s3_score_it));
   4145       s3_build_relax_frag (fix_insts, fix_num, var_insts, var_num, add_symbol);
   4146     }
   4147   else
   4148     {
   4149       int hi = (add_number >> 16) & 0x0000FFFF;
   4150       int lo = add_number & 0x0000FFFF;
   4151 
   4152       /* Insn 1: lw rD, <sym>($gp)    (BFD_RELOC_SCORE_GOT15)  */
   4153       sprintf (tmp, "lw_pic r%d, %s", reg_rd, add_symbol->bsym->name);
   4154       if (s3_append_insn (tmp, TRUE) == (int) s3_FAIL)
   4155 	return;
   4156 
   4157       /* Insn 2  */
   4158       fix_num = 1;
   4159       var_num = 1;
   4160       /* Fix part
   4161 	 For an external symbol: ldis r1, HI%<constant>  */
   4162       sprintf (tmp, "ldis r1, %d", hi);
   4163       if (s3_append_insn (tmp, FALSE) == (int) s3_FAIL)
   4164 	return;
   4165 
   4166       memcpy (&fix_insts[0], &s3_inst, sizeof (struct s3_score_it));
   4167 
   4168       /* Var part
   4169 	 For a local symbol: ldis r1, HI%<constant>
   4170          but, if lo is outof 16 bit, make hi plus 1  */
   4171       if ((lo < -0x8000) || (lo > 0x7fff))
   4172 	{
   4173 	  hi += 1;
   4174 	}
   4175       sprintf (tmp, "ldis_pic r1, %d", hi);
   4176       if (s3_append_insn (tmp, FALSE) == (int) s3_FAIL)
   4177 	return;
   4178 
   4179       memcpy (&var_insts[0], &s3_inst, sizeof (struct s3_score_it));
   4180       s3_build_relax_frag (fix_insts, fix_num, var_insts, var_num, add_symbol);
   4181 
   4182       /* Insn 3  */
   4183       fix_num = 1;
   4184       var_num = 1;
   4185       /* Fix part
   4186 	 For an external symbol: ori r1, LO%<constant>  */
   4187       sprintf (tmp, "ori r1, %d", lo);
   4188       if (s3_append_insn (tmp, FALSE) == (int) s3_FAIL)
   4189 	return;
   4190 
   4191       memcpy (&fix_insts[0], &s3_inst, sizeof (struct s3_score_it));
   4192 
   4193       /* Var part
   4194   	 For a local symbol: addi r1, <sym>+LO%<constant>    (BFD_RELOC_GOT_LO16)  */
   4195       sprintf (tmp, "addi_u_pic r1, %s + %d", add_symbol->bsym->name, lo);
   4196       if (s3_append_insn (tmp, FALSE) == (int) s3_FAIL)
   4197 	return;
   4198 
   4199       memcpy (&var_insts[0], &s3_inst, sizeof (struct s3_score_it));
   4200       s3_build_relax_frag (fix_insts, fix_num, var_insts, var_num, add_symbol);
   4201 
   4202       /* Insn 4: add rD, rD, r1  */
   4203       sprintf (tmp, "add r%d, r%d, r1", reg_rd, reg_rd);
   4204       if (s3_append_insn (tmp, TRUE) == (int) s3_FAIL)
   4205 	return;
   4206 
   4207       /* Set bwarn as -1, so macro instruction itself will not be generated frag.  */
   4208       s3_inst.bwarn = -1;
   4209     }
   4210 
   4211   s3_nor1 = r1_bak;
   4212 }
   4213 
   4214 /* Handle la.  */
   4215 static void
   4216 s3_do_macro_la_rdi32 (char *str)
   4217 {
   4218   int reg_rd;
   4219 
   4220   s3_skip_whitespace (str);
   4221   if ((reg_rd = s3_reg_required_here (&str, 20, s3_REG_TYPE_SCORE)) == (int) s3_FAIL
   4222       || s3_skip_past_comma (&str) == (int) s3_FAIL)
   4223     {
   4224       return;
   4225     }
   4226   else
   4227     {
   4228       /* Save str.  */
   4229       char *keep_data = str;
   4230       char append_str[s3_MAX_LITERAL_POOL_SIZE];
   4231 
   4232       /* Check immediate value.  */
   4233       if (s3_my_get_expression (&s3_inst.reloc.exp, &str) == (int) s3_FAIL)
   4234         {
   4235           s3_inst.error = _("expression error");
   4236           return;
   4237         }
   4238       else if ((s3_inst.reloc.exp.X_add_symbol == NULL)
   4239                && (s3_validate_immediate (s3_inst.reloc.exp.X_add_number, _IMM32, 0) == (int) s3_FAIL))
   4240         {
   4241           s3_inst.error = _("value not in range [0, 0xffffffff]");
   4242           return;
   4243         }
   4244 
   4245       /* Reset str.  */
   4246       str = keep_data;
   4247 
   4248       /* la rd, simm16.  */
   4249       if (s3_data_op2 (&str, 1, _SIMM16_LA) != (int) s3_FAIL)
   4250         {
   4251           s3_end_of_line (str);
   4252           return;
   4253         }
   4254       /* la rd, imm32 or la rd, label.  */
   4255       else
   4256         {
   4257           s3_SET_INSN_ERROR (NULL);
   4258           /* Reset str.  */
   4259           str = keep_data;
   4260           if ((s3_data_op2 (&str, 1, _VALUE_HI16) == (int) s3_FAIL)
   4261               || (s3_end_of_line (str) == (int) s3_FAIL))
   4262             {
   4263               return;
   4264             }
   4265           else
   4266             {
   4267               if ((s3_score_pic == s3_NO_PIC) || (!s3_inst.reloc.exp.X_add_symbol))
   4268                 {
   4269                   sprintf (append_str, "ld_i32hi r%d, %s", reg_rd, keep_data);
   4270                   if (s3_append_insn (append_str, TRUE) == (int) s3_FAIL)
   4271 		    return;
   4272 
   4273                   sprintf (append_str, "ld_i32lo r%d, %s", reg_rd, keep_data);
   4274                   if (s3_append_insn (append_str, TRUE) == (int) s3_FAIL)
   4275 		    return;
   4276 		}
   4277 	      else
   4278 		{
   4279 		  gas_assert (s3_inst.reloc.exp.X_add_symbol);
   4280 		  s3_build_la_pic (reg_rd, s3_inst.reloc.exp);
   4281 		}
   4282 
   4283               /* Set bwarn as -1, so macro instruction itself will not be generated frag.  */
   4284               s3_inst.bwarn = -1;
   4285             }
   4286         }
   4287     }
   4288 }
   4289 
   4290 /* Handle li.  */
   4291 static void
   4292 s3_do_macro_li_rdi32 (char *str)
   4293 {
   4294 
   4295   int reg_rd;
   4296 
   4297   s3_skip_whitespace (str);
   4298   if ((reg_rd = s3_reg_required_here (&str, 20, s3_REG_TYPE_SCORE)) == (int) s3_FAIL
   4299       || s3_skip_past_comma (&str) == (int) s3_FAIL)
   4300     {
   4301       return;
   4302     }
   4303   else
   4304     {
   4305       /* Save str.  */
   4306       char *keep_data = str;
   4307 
   4308       /* Check immediate value.  */
   4309       if (s3_my_get_expression (&s3_inst.reloc.exp, &str) == (int) s3_FAIL)
   4310         {
   4311           s3_inst.error = _("expression error");
   4312           return;
   4313         }
   4314       else if (!(s3_inst.reloc.exp.X_add_number >= -0xffffffffLL
   4315                  && s3_inst.reloc.exp.X_add_number <= 0xffffffffLL))
   4316         {
   4317           s3_inst.error = _("value not in range [-0xffffffff, 0xffffffff]");
   4318           return;
   4319         }
   4320 
   4321       /* Reset str.  */
   4322       str = keep_data;
   4323 
   4324       /* li rd, simm16.  */
   4325       if (s3_data_op2 (&str, 1, _SIMM16_LA) != (int) s3_FAIL)
   4326         {
   4327           s3_end_of_line (str);
   4328           return;
   4329         }
   4330       /* li rd, imm32.  */
   4331       else
   4332         {
   4333           char append_str[s3_MAX_LITERAL_POOL_SIZE];
   4334 
   4335           /* Reset str.  */
   4336           str = keep_data;
   4337 
   4338           if ((s3_data_op2 (&str, 1, _VALUE_HI16) == (int) s3_FAIL)
   4339               || (s3_end_of_line (str) == (int) s3_FAIL))
   4340             {
   4341               return;
   4342             }
   4343           else if (s3_inst.reloc.exp.X_add_symbol)
   4344             {
   4345               s3_inst.error = _("li rd label isn't correct instruction form");
   4346               return;
   4347             }
   4348           else
   4349             {
   4350               sprintf (append_str, "ld_i32hi r%d, %s", reg_rd, keep_data);
   4351 
   4352               if (s3_append_insn (append_str, TRUE) == (int) s3_FAIL)
   4353 		return;
   4354               else
   4355                 {
   4356                   sprintf (append_str, "ld_i32lo r%d, %s", reg_rd, keep_data);
   4357                   if (s3_append_insn (append_str, TRUE) == (int) s3_FAIL)
   4358 		    return;
   4359 
   4360                   /* Set bwarn as -1, so macro instruction itself will not be generated frag.  */
   4361                   s3_inst.bwarn = -1;
   4362                 }
   4363             }
   4364         }
   4365     }
   4366 }
   4367 
   4368 /* Handle mul/mulu/div/divu/rem/remu.  */
   4369 static void
   4370 s3_do_macro_mul_rdrsrs (char *str)
   4371 {
   4372   int reg_rd;
   4373   int reg_rs1;
   4374   int reg_rs2;
   4375   char *backupstr;
   4376   char append_str[s3_MAX_LITERAL_POOL_SIZE];
   4377 
   4378   if (s3_university_version == 1)
   4379     as_warn ("%s", s3_ERR_FOR_SCORE5U_MUL_DIV);
   4380 
   4381   strcpy (append_str, str);
   4382   backupstr = append_str;
   4383   s3_skip_whitespace (backupstr);
   4384   if (((reg_rd = s3_reg_required_here (&backupstr, -1, s3_REG_TYPE_SCORE)) == (int) s3_FAIL)
   4385       || (s3_skip_past_comma (&backupstr) == (int) s3_FAIL)
   4386       || ((reg_rs1 = s3_reg_required_here (&backupstr, -1, s3_REG_TYPE_SCORE)) == (int) s3_FAIL))
   4387     {
   4388       s3_inst.error = s3_BAD_ARGS;
   4389       return;
   4390     }
   4391 
   4392   if (s3_skip_past_comma (&backupstr) == (int) s3_FAIL)
   4393     {
   4394       /* rem/remu rA, rB is error format.  */
   4395       if (strcmp (s3_inst.name, "rem") == 0 || strcmp (s3_inst.name, "remu") == 0)
   4396         {
   4397           s3_SET_INSN_ERROR (s3_BAD_ARGS);
   4398         }
   4399       else
   4400         {
   4401           s3_SET_INSN_ERROR (NULL);
   4402           s3_do_rsrs (str);
   4403         }
   4404       return;
   4405     }
   4406   else
   4407     {
   4408       s3_SET_INSN_ERROR (NULL);
   4409       if (((reg_rs2 = s3_reg_required_here (&backupstr, -1, s3_REG_TYPE_SCORE)) == (int) s3_FAIL)
   4410           || (s3_end_of_line (backupstr) == (int) s3_FAIL))
   4411         {
   4412           return;
   4413         }
   4414       else
   4415         {
   4416           char append_str1[s3_MAX_LITERAL_POOL_SIZE];
   4417 
   4418           if (strcmp (s3_inst.name, "rem") == 0)
   4419             {
   4420               sprintf (append_str, "mul r%d, r%d", reg_rs1, reg_rs2);
   4421               sprintf (append_str1, "mfceh  r%d", reg_rd);
   4422             }
   4423           else if (strcmp (s3_inst.name, "remu") == 0)
   4424             {
   4425               sprintf (append_str, "mulu r%d, r%d", reg_rs1, reg_rs2);
   4426               sprintf (append_str1, "mfceh  r%d", reg_rd);
   4427             }
   4428           else
   4429             {
   4430               sprintf (append_str, "%s r%d, r%d", s3_inst.name, reg_rs1, reg_rs2);
   4431               sprintf (append_str1, "mfcel  r%d", reg_rd);
   4432             }
   4433 
   4434           /* Output mul/mulu or div/divu or rem/remu.  */
   4435           if (s3_append_insn (append_str, TRUE) == (int) s3_FAIL)
   4436 	    return;
   4437 
   4438           /* Output mfcel or mfceh.  */
   4439           if (s3_append_insn (append_str1, TRUE) == (int) s3_FAIL)
   4440 	    return;
   4441 
   4442           /* Set bwarn as -1, so macro instruction itself will not be generated frag.  */
   4443           s3_inst.bwarn = -1;
   4444         }
   4445     }
   4446 }
   4447 
   4448 static void
   4449 s3_exp_macro_ldst_abs (char *str)
   4450 {
   4451   int reg_rd;
   4452   char *backupstr, *tmp;
   4453   char append_str[s3_MAX_LITERAL_POOL_SIZE];
   4454   char verifystr[s3_MAX_LITERAL_POOL_SIZE];
   4455   struct s3_score_it inst_backup;
   4456   int r1_bak = 0;
   4457 
   4458   r1_bak = s3_nor1;
   4459   s3_nor1 = 0;
   4460   memcpy (&inst_backup, &s3_inst, sizeof (struct s3_score_it));
   4461 
   4462   strcpy (verifystr, str);
   4463   backupstr = verifystr;
   4464   s3_skip_whitespace (backupstr);
   4465   if ((reg_rd = s3_reg_required_here (&backupstr, -1, s3_REG_TYPE_SCORE)) == (int) s3_FAIL)
   4466     return;
   4467 
   4468   tmp = backupstr;
   4469   if (s3_skip_past_comma (&backupstr) == (int) s3_FAIL)
   4470     return;
   4471 
   4472   backupstr = tmp;
   4473   sprintf (append_str, "li r1  %s", backupstr);
   4474   s3_append_insn (append_str, TRUE);
   4475 
   4476   memcpy (&s3_inst, &inst_backup, sizeof (struct s3_score_it));
   4477   sprintf (append_str, " r%d, [r1,0]", reg_rd);
   4478   s3_do_ldst_insn (append_str);
   4479 
   4480   s3_nor1 = r1_bak;
   4481 }
   4482 
   4483 /* Handle bcmpeq / bcmpne  */
   4484 static void
   4485 s3_do_macro_bcmp (char *str)
   4486 {
   4487   int reg_a , reg_b;
   4488   char keep_data[s3_MAX_LITERAL_POOL_SIZE];
   4489   char* ptemp;
   4490   int i = 0;
   4491   struct s3_score_it inst_expand[2];
   4492   struct s3_score_it inst_main;
   4493 
   4494   memset (inst_expand, 0, sizeof inst_expand);
   4495   s3_skip_whitespace (str);
   4496   if (( reg_a = s3_reg_required_here (&str, 15, s3_REG_TYPE_SCORE)) == (int) s3_FAIL
   4497       || s3_skip_past_comma (&str) == (int) s3_FAIL
   4498       ||(reg_b = s3_reg_required_here (&str, 10, s3_REG_TYPE_SCORE)) == (int) s3_FAIL
   4499       || s3_skip_past_comma (&str) == (int) s3_FAIL)
   4500     return;
   4501   ptemp = str;
   4502   while (*ptemp != 0)
   4503     {
   4504       keep_data[i] = *ptemp;
   4505       i++;
   4506       ptemp++;
   4507     }
   4508   keep_data[i] = 0;
   4509   if (s3_my_get_expression (&s3_inst.reloc.exp, &str) == (int) s3_FAIL
   4510       ||reg_b == 0
   4511       || s3_end_of_line (str) == (int) s3_FAIL)
   4512     return;
   4513   else if (s3_inst.reloc.exp.X_add_symbol == 0)
   4514     {
   4515       s3_inst.error = _("lacking label  ");
   4516       return;
   4517     }
   4518   else
   4519     {
   4520       char append_str[s3_MAX_LITERAL_POOL_SIZE];
   4521       s3_SET_INSN_ERROR (NULL);
   4522 
   4523       s3_inst.reloc.type = BFD_RELOC_SCORE_BCMP;
   4524       s3_inst.reloc.pc_rel = 1;
   4525       bfd_signed_vma val = s3_inst.reloc.exp.X_add_number;
   4526 
   4527       /* Branch 32  offset field : 20 bit, 16 bit branch offset field : 8 bit.  */
   4528       s3_inst.instruction |= ((s3_inst.reloc.exp.X_add_number >> 1) & 0x1)
   4529 	| ((s3_inst.reloc.exp.X_add_number >> 2) & 0x7) << 7
   4530 	| ((s3_inst.reloc.exp.X_add_number >> 5) & 0x1f) << 20;
   4531 
   4532       /* Check and set offset.  */
   4533       if (((val & 0xfffffe00) != 0)
   4534 	  && ((val & 0xfffffe00) != 0xfffffe00))
   4535         {
   4536           /* support bcmp --> cmp!+beq (bne) */
   4537           if (s3_score_pic == s3_NO_PIC)
   4538             {
   4539               sprintf (&append_str[0], "cmp! r%d, r%d", reg_a, reg_b);
   4540               if (s3_append_insn (&append_str[0], TRUE) == (int) s3_FAIL)
   4541                 return;
   4542               if ((inst_main.instruction & 0x3e00007e) == 0x0000004c)
   4543                 sprintf (&append_str[1], "beq %s", keep_data);
   4544               else
   4545                 sprintf (&append_str[1], "bne %s", keep_data);
   4546               if (s3_append_insn (&append_str[1], TRUE) == (int) s3_FAIL)
   4547                 return;
   4548 	    }
   4549 	  else
   4550 	    {
   4551 	      gas_assert (s3_inst.reloc.exp.X_add_symbol);
   4552 	    }
   4553 	  /* Set bwarn as -1, so macro instruction itself will not be generated frag.  */
   4554 	  s3_inst.bwarn = -1;
   4555 	  return;
   4556         }
   4557       else
   4558         {
   4559           val >>= 1;
   4560           s3_inst.instruction |= (val & 0x1)
   4561 	    | (((val >> 1) & 0x7) << 7)
   4562 	    | (((val >> 4) & 0x1f) << 20);
   4563         }
   4564 
   4565       /* Backup s3_inst.  */
   4566       memcpy (&inst_main, &s3_inst, sizeof (struct s3_score_it));
   4567 
   4568       if (s3_score_pic == s3_NO_PIC)
   4569         {
   4570           sprintf (&append_str[0], "cmp! r%d, r%d", reg_a, reg_b);
   4571           if (s3_append_insn (&append_str[0], FALSE) == (int) s3_FAIL)
   4572             return;
   4573           memcpy (&inst_expand[0], &s3_inst, sizeof (struct s3_score_it));
   4574 
   4575           if ((inst_main.instruction & 0x3e00007e) == 0x0000004c)
   4576             sprintf (&append_str[1], "beq %s", keep_data);
   4577           else
   4578             sprintf (&append_str[1], "bne %s", keep_data);
   4579           if (s3_append_insn (&append_str[1], FALSE) == (int) s3_FAIL)
   4580             return;
   4581           memcpy (&inst_expand[1], &s3_inst, sizeof (struct s3_score_it));
   4582         }
   4583       else
   4584         {
   4585           gas_assert (s3_inst.reloc.exp.X_add_symbol);
   4586         }
   4587       inst_main.relax_size = inst_expand[0].size + inst_expand[1].size;
   4588       inst_main.type = Insn_BCMP;
   4589 
   4590       /* Adjust instruction opcode and to be relaxed instruction opcode.  */
   4591       inst_main.instruction = s3_adjust_paritybit (inst_main.instruction, s3_GET_INSN_CLASS (inst_main.type));
   4592 
   4593       for (i = 0; i < 2; i++)
   4594         inst_expand[i].instruction = s3_adjust_paritybit (inst_expand[i].instruction,
   4595                                                           s3_GET_INSN_CLASS (inst_expand[i].type));
   4596       /* Check data dependency.  */
   4597       s3_handle_dependency (&inst_main);
   4598       /* Start a new frag if frag_now is not empty.  */
   4599       if (frag_now_fix () != 0)
   4600 	{
   4601 	  if (!frag_now->tc_frag_data.is_insn)
   4602 	    frag_wane (frag_now);
   4603 	  frag_new (0);
   4604 	}
   4605       frag_grow (20);
   4606 
   4607       /* Write fr_fix part.  */
   4608       char *p;
   4609       p = frag_more (inst_main.size);
   4610       s3_md_number_to_chars (p, inst_main.instruction, inst_main.size);
   4611 
   4612       if (inst_main.reloc.type != BFD_RELOC_NONE)
   4613 	{
   4614 	  s3_fix_new_score (frag_now, p - frag_now->fr_literal, inst_main.size,
   4615 			    &inst_main.reloc.exp, inst_main.reloc.pc_rel, inst_main.reloc.type);
   4616 	}
   4617 #ifdef OBJ_ELF
   4618       dwarf2_emit_insn (inst_main.size);
   4619 #endif
   4620 
   4621       /* s3_GP instruction can not do optimization, only can do relax between
   4622          1 instruction and 3 instructions.  */
   4623       p = frag_var (rs_machine_dependent, inst_main.relax_size + s3_RELAX_PAD_BYTE, 0,
   4624                     s3_RELAX_ENCODE (inst_main.size, inst_main.relax_size, inst_main.type, 0, 4, 1),
   4625                     inst_main.reloc.exp.X_add_symbol, 0, NULL);
   4626 
   4627       /* Write fr_var part.
   4628          no calling s3_gen_insn_frag, no fixS will be generated.  */
   4629       s3_md_number_to_chars (p, inst_expand[0].instruction, inst_expand[0].size);
   4630       p += inst_expand[0].size;
   4631       s3_md_number_to_chars (p, inst_expand[1].instruction, inst_expand[1].size);
   4632       p += inst_expand[1].size;
   4633 
   4634       /* Set bwarn as -1, so macro instruction itself will not be generated frag.  */
   4635       s3_inst.bwarn = -1;
   4636     }
   4637 }
   4638 
   4639 /* Handle bcmpeqz / bcmpnez  */
   4640 static void
   4641 s3_do_macro_bcmpz (char *str)
   4642 {
   4643   int reg_a;
   4644   char keep_data[s3_MAX_LITERAL_POOL_SIZE];
   4645   char* ptemp;
   4646   int i = 0;
   4647   struct s3_score_it inst_expand[2];
   4648   struct s3_score_it inst_main;
   4649 
   4650   memset (inst_expand, 0, sizeof inst_expand);
   4651   s3_skip_whitespace (str);
   4652   if (( reg_a = s3_reg_required_here (&str, 15, s3_REG_TYPE_SCORE)) == (int) s3_FAIL
   4653       || s3_skip_past_comma (&str) == (int) s3_FAIL)
   4654     return;
   4655   ptemp = str;
   4656   while (*ptemp != 0)
   4657     {
   4658       keep_data[i] = *ptemp;
   4659       i++;
   4660       ptemp++;
   4661     }
   4662 
   4663   keep_data[i] = 0;
   4664 
   4665   if (s3_my_get_expression (&s3_inst.reloc.exp, &str) == (int) s3_FAIL
   4666       || s3_end_of_line (str) == (int) s3_FAIL)
   4667     return;
   4668   else if (s3_inst.reloc.exp.X_add_symbol == 0)
   4669     {
   4670       s3_inst.error = _("lacking label  ");
   4671       return;
   4672     }
   4673   else
   4674     {
   4675       char append_str[s3_MAX_LITERAL_POOL_SIZE];
   4676       s3_SET_INSN_ERROR (NULL);
   4677       s3_inst.reloc.type = BFD_RELOC_SCORE_BCMP;
   4678       s3_inst.reloc.pc_rel = 1;
   4679       bfd_signed_vma val = s3_inst.reloc.exp.X_add_number;
   4680 
   4681       /* Branch 32  offset field : 20 bit, 16 bit branch offset field : 8 bit.  */
   4682       s3_inst.instruction |= ((s3_inst.reloc.exp.X_add_number>>1) & 0x1) | ((s3_inst.reloc.exp.X_add_number>>2) & 0x7)<<7 |((s3_inst.reloc.exp.X_add_number>>5) & 0x1f)<<20;
   4683 
   4684       /* Check and set offset.  */
   4685       if (((val & 0xfffffe00) != 0)
   4686 	  && ((val & 0xfffffe00) != 0xfffffe00))
   4687         {
   4688           if (s3_score_pic == s3_NO_PIC)
   4689             {
   4690               sprintf (&append_str[0], "cmpi! r%d,0", reg_a);
   4691               if (s3_append_insn (&append_str[0], TRUE) == (int) s3_FAIL)
   4692                 return;
   4693               if ((inst_main.instruction & 0x3e00007e) == 0x0000004c)
   4694                 sprintf (&append_str[1], "beq %s", keep_data);
   4695               else
   4696                 sprintf (&append_str[1], "bne %s", keep_data);
   4697               if (s3_append_insn (&append_str[1], TRUE) == (int) s3_FAIL)
   4698                 return;
   4699             }
   4700           else
   4701             {
   4702               gas_assert (s3_inst.reloc.exp.X_add_symbol);
   4703             }
   4704           /* Set bwarn as -1, so macro instruction itself will not be generated frag.  */
   4705           s3_inst.bwarn = -1;
   4706           return;
   4707         }
   4708       else
   4709         {
   4710           val >>= 1;
   4711           s3_inst.instruction |= (val & 0x1)
   4712 	    | (((val >> 1) & 0x7) << 7)
   4713 	    | (((val >> 4) & 0x1f) << 20);
   4714         }
   4715 
   4716       /* Backup s3_inst.  */
   4717       memcpy (&inst_main, &s3_inst, sizeof (struct s3_score_it));
   4718 
   4719       if (s3_score_pic == s3_NO_PIC)
   4720         {
   4721           sprintf (&append_str[0], "cmpi! r%d, 0", reg_a);
   4722           if (s3_append_insn (&append_str[0], FALSE) == (int) s3_FAIL)
   4723             return;
   4724           memcpy (&inst_expand[0], &s3_inst, sizeof (struct s3_score_it));
   4725           if ((inst_main.instruction & 0x3e00007e) == 0x0000004c)
   4726             sprintf (&append_str[1], "beq %s", keep_data);
   4727           else
   4728             sprintf (&append_str[1], "bne %s", keep_data);
   4729           if (s3_append_insn (&append_str[1], FALSE) == (int) s3_FAIL)
   4730             return;
   4731           memcpy (&inst_expand[1], &s3_inst, sizeof (struct s3_score_it));
   4732         }
   4733       else
   4734         {
   4735           gas_assert (s3_inst.reloc.exp.X_add_symbol);
   4736         }
   4737       inst_main.relax_size = inst_expand[0].size + inst_expand[1].size;
   4738       inst_main.type = Insn_BCMP;
   4739 
   4740       /* Adjust instruction opcode and to be relaxed instruction opcode.  */
   4741       inst_main.instruction = s3_adjust_paritybit (inst_main.instruction, s3_GET_INSN_CLASS (inst_main.type));
   4742 
   4743       for (i = 0; i < 2; i++)
   4744         inst_expand[i].instruction = s3_adjust_paritybit (inst_expand[i].instruction ,
   4745 							  s3_GET_INSN_CLASS (inst_expand[i].type));
   4746       /* Check data dependency.  */
   4747       s3_handle_dependency (&inst_main);
   4748       /* Start a new frag if frag_now is not empty.  */
   4749       if (frag_now_fix () != 0)
   4750 	{
   4751 	  if (!frag_now->tc_frag_data.is_insn)
   4752 	    frag_wane (frag_now);
   4753 	  frag_new (0);
   4754 	}
   4755       frag_grow (20);
   4756 
   4757       /* Write fr_fix part.  */
   4758       char *p;
   4759       p = frag_more (inst_main.size);
   4760       s3_md_number_to_chars (p, inst_main.instruction, inst_main.size);
   4761 
   4762       if (inst_main.reloc.type != BFD_RELOC_NONE)
   4763 	{
   4764 	  s3_fix_new_score (frag_now, p - frag_now->fr_literal, inst_main.size,
   4765 			    &inst_main.reloc.exp, inst_main.reloc.pc_rel, inst_main.reloc.type);
   4766 	}
   4767 #ifdef OBJ_ELF
   4768       dwarf2_emit_insn (inst_main.size);
   4769 #endif
   4770 
   4771       /* s3_GP instruction can not do optimization, only can do relax between
   4772          1 instruction and 3 instructions.  */
   4773       p = frag_var (rs_machine_dependent, inst_main.relax_size + s3_RELAX_PAD_BYTE, 0,
   4774                     s3_RELAX_ENCODE (inst_main.size, inst_main.relax_size, inst_main.type, 0, 4, 1),
   4775                     inst_main.reloc.exp.X_add_symbol, 0, NULL);
   4776 
   4777       /* Write fr_var part.
   4778          no calling s3_gen_insn_frag, no fixS will be generated.  */
   4779       s3_md_number_to_chars (p, inst_expand[0].instruction, inst_expand[0].size);
   4780       p += inst_expand[0].size;
   4781       s3_md_number_to_chars (p, inst_expand[1].instruction, inst_expand[1].size);
   4782       p += inst_expand[1].size;
   4783 
   4784       /* Set bwarn as -1, so macro instruction itself will not be generated frag.  */
   4785       s3_inst.bwarn = -1;
   4786     }
   4787 }
   4788 
   4789 static int
   4790 s3_nopic_need_relax (symbolS * sym, int before_relaxing)
   4791 {
   4792   if (sym == NULL)
   4793     return 0;
   4794   else if (s3_USE_GLOBAL_POINTER_OPT && s3_g_switch_value > 0)
   4795     {
   4796       const char *symname;
   4797       const char *segname;
   4798 
   4799       /* Find out whether this symbol can be referenced off the $gp
   4800          register.  It can be if it is smaller than the -G size or if
   4801          it is in the .sdata or .sbss section.  Certain symbols can
   4802          not be referenced off the $gp, although it appears as though
   4803          they can.  */
   4804       symname = S_GET_NAME (sym);
   4805       if (symname != (const char *)NULL
   4806           && (strcmp (symname, "eprol") == 0
   4807               || strcmp (symname, "etext") == 0
   4808               || strcmp (symname, "_gp") == 0
   4809               || strcmp (symname, "edata") == 0
   4810               || strcmp (symname, "_fbss") == 0
   4811               || strcmp (symname, "_fdata") == 0
   4812               || strcmp (symname, "_ftext") == 0
   4813               || strcmp (symname, "end") == 0
   4814               || strcmp (symname, GP_DISP_LABEL) == 0))
   4815         {
   4816           return 1;
   4817         }
   4818       else if ((!S_IS_DEFINED (sym) || S_IS_COMMON (sym)) && (0
   4819 							      /* We must defer this decision until after the whole file has been read,
   4820 								 since there might be a .extern after the first use of this symbol.  */
   4821 							      || (before_relaxing
   4822 								  && S_GET_VALUE (sym) == 0)
   4823 							      || (S_GET_VALUE (sym) != 0
   4824 								  && S_GET_VALUE (sym) <= s3_g_switch_value)))
   4825         {
   4826           return 0;
   4827         }
   4828 
   4829       segname = segment_name (S_GET_SEGMENT (sym));
   4830       return (strcmp (segname, ".sdata") != 0
   4831 	      && strcmp (segname, ".sbss") != 0
   4832 	      && strncmp (segname, ".sdata.", 7) != 0
   4833 	      && strncmp (segname, ".gnu.linkonce.s.", 16) != 0);
   4834     }
   4835   /* We are not optimizing for the $gp register.  */
   4836   else
   4837     return 1;
   4838 }
   4839 
   4840 /* Build a relax frag for lw/st instruction when generating s3_PIC,
   4841    external symbol first and local symbol second.  */
   4842 static void
   4843 s3_build_lwst_pic (int reg_rd, expressionS exp, const char *insn_name)
   4844 {
   4845   symbolS *add_symbol = exp.X_add_symbol;
   4846   int add_number = exp.X_add_number;
   4847   struct s3_score_it fix_insts[s3_RELAX_INST_NUM];
   4848   struct s3_score_it var_insts[s3_RELAX_INST_NUM];
   4849   int fix_num = 0;
   4850   int var_num = 0;
   4851   char tmp[s3_MAX_LITERAL_POOL_SIZE];
   4852   int r1_bak;
   4853 
   4854   r1_bak = s3_nor1;
   4855   s3_nor1 = 0;
   4856 
   4857   if ((add_number == 0) || (add_number >= -0x8000 && add_number <= 0x7fff))
   4858     {
   4859       fix_num = 1;
   4860       var_num = 2;
   4861 
   4862       /* For an external symbol, two insns are generated;
   4863          For a local symbol, three insns are generated.  */
   4864       /* Fix part
   4865          For an external symbol: lw rD, <sym>($gp)
   4866 	 (BFD_RELOC_SCORE_GOT15)  */
   4867       sprintf (tmp, "lw_pic r1, %s", add_symbol->bsym->name);
   4868       if (s3_append_insn (tmp, FALSE) == (int) s3_FAIL)
   4869         return;
   4870 
   4871       memcpy (&fix_insts[0], &s3_inst, sizeof (struct s3_score_it));
   4872 
   4873       /* Var part
   4874 	 For a local symbol :
   4875          lw rD, <sym>($gp)    (BFD_RELOC_SCORE_GOT15)
   4876 	 addi rD, <sym>       (BFD_RELOC_GOT_LO16) */
   4877       s3_inst.reloc.type = BFD_RELOC_SCORE_GOT15;
   4878       memcpy (&var_insts[0], &s3_inst, sizeof (struct s3_score_it));
   4879       sprintf (tmp, "addi_s_pic r1, %s", add_symbol->bsym->name);
   4880       if (s3_append_insn (tmp, FALSE) == (int) s3_FAIL)
   4881         return;
   4882 
   4883       memcpy (&var_insts[1], &s3_inst, sizeof (struct s3_score_it));
   4884       s3_build_relax_frag (fix_insts, fix_num, var_insts, var_num, add_symbol);
   4885 
   4886       /* Insn 2 or Insn 3: lw/st rD, [r1, constant]  */
   4887       sprintf (tmp, "%s r%d, [r1, %d]", insn_name, reg_rd, add_number);
   4888       if (s3_append_insn (tmp, TRUE) == (int) s3_FAIL)
   4889         return;
   4890 
   4891       /* Set bwarn as -1, so macro instruction itself will not be generated frag.  */
   4892       s3_inst.bwarn = -1;
   4893     }
   4894   else
   4895     {
   4896       s3_inst.error = _("s3_PIC code offset overflow (max 16 signed bits)");
   4897       return;
   4898     }
   4899 
   4900   s3_nor1 = r1_bak;
   4901 }
   4902 
   4903 static void
   4904 s3_do_macro_ldst_label (char *str)
   4905 {
   4906   int i;
   4907   int ldst_gp_p = 0;
   4908   int reg_rd;
   4909   int r1_bak;
   4910   char *backup_str;
   4911   char *label_str;
   4912   char *absolute_value;
   4913   char append_str[3][s3_MAX_LITERAL_POOL_SIZE];
   4914   char verifystr[s3_MAX_LITERAL_POOL_SIZE];
   4915   struct s3_score_it inst_backup;
   4916   struct s3_score_it inst_expand[3];
   4917   struct s3_score_it inst_main;
   4918 
   4919   memcpy (&inst_backup, &s3_inst, sizeof (struct s3_score_it));
   4920   strcpy (verifystr, str);
   4921   backup_str = verifystr;
   4922 
   4923   s3_skip_whitespace (backup_str);
   4924   if ((reg_rd = s3_reg_required_here (&backup_str, -1, s3_REG_TYPE_SCORE)) == (int) s3_FAIL)
   4925     return;
   4926 
   4927   if (s3_skip_past_comma (&backup_str) == (int) s3_FAIL)
   4928     return;
   4929 
   4930   label_str = backup_str;
   4931 
   4932   /* Ld/st rD, [rA, imm]      ld/st rD, [rA]+, imm      ld/st rD, [rA, imm]+.  */
   4933   if (*backup_str == '[')
   4934     {
   4935       s3_inst.type = Rd_rvalueRs_preSI12;
   4936       s3_do_ldst_insn (str);
   4937       return;
   4938     }
   4939 
   4940   /* Ld/st rD, imm.  */
   4941   absolute_value = backup_str;
   4942   s3_inst.type = Rd_rvalueRs_SI15;
   4943 
   4944   if (s3_my_get_expression (&s3_inst.reloc.exp, &backup_str) == (int) s3_FAIL)
   4945     {
   4946       s3_inst.error = _("expression error");
   4947       return;
   4948     }
   4949   else if ((s3_inst.reloc.exp.X_add_symbol == NULL)
   4950            && (s3_validate_immediate (s3_inst.reloc.exp.X_add_number, _VALUE, 0) == (int) s3_FAIL))
   4951     {
   4952       s3_inst.error = _("value not in range [0, 0x7fffffff]");
   4953       return;
   4954     }
   4955   else if (s3_end_of_line (backup_str) == (int) s3_FAIL)
   4956     {
   4957       s3_inst.error = _("end on line error");
   4958       return;
   4959     }
   4960   else
   4961     {
   4962       if (s3_inst.reloc.exp.X_add_symbol == 0)
   4963         {
   4964           memcpy (&s3_inst, &inst_backup, sizeof (struct s3_score_it));
   4965           s3_exp_macro_ldst_abs (str);
   4966           return;
   4967         }
   4968     }
   4969 
   4970   /* Ld/st rD, label.  */
   4971   s3_inst.type = Rd_rvalueRs_SI15;
   4972   backup_str = absolute_value;
   4973   if ((s3_data_op2 (&backup_str, 1, _GP_IMM15) == (int) s3_FAIL)
   4974       || (s3_end_of_line (backup_str) == (int) s3_FAIL))
   4975     {
   4976       return;
   4977     }
   4978   else
   4979     {
   4980       if (s3_inst.reloc.exp.X_add_symbol == 0)
   4981         {
   4982           if (!s3_inst.error)
   4983 	    s3_inst.error = s3_BAD_ARGS;
   4984 
   4985           return;
   4986         }
   4987 
   4988       if (s3_score_pic == s3_PIC)
   4989         {
   4990           int ldst_idx = 0;
   4991           ldst_idx = s3_inst.instruction & OPC_PSEUDOLDST_MASK;
   4992           s3_build_lwst_pic (reg_rd, s3_inst.reloc.exp,
   4993                              s3_score_ldst_insns[ldst_idx * 3 + 0].template_name);
   4994           return;
   4995         }
   4996       else
   4997 	{
   4998           if ((s3_inst.reloc.exp.X_add_number <= 0x3fff)
   4999 	      && (s3_inst.reloc.exp.X_add_number >= -0x4000)
   5000 	      && (!s3_nopic_need_relax (s3_inst.reloc.exp.X_add_symbol, 1)))
   5001 	    {
   5002               int ldst_idx = 0;
   5003 
   5004               /* Assign the real opcode.  */
   5005               ldst_idx = s3_inst.instruction & OPC_PSEUDOLDST_MASK;
   5006               s3_inst.instruction &= ~OPC_PSEUDOLDST_MASK;
   5007               s3_inst.instruction |= s3_score_ldst_insns[ldst_idx * 3 + 0].value;
   5008               s3_inst.instruction |= reg_rd << 20;
   5009               s3_inst.instruction |= s3_GP << 15;
   5010               s3_inst.relax_inst = 0x8000;
   5011               s3_inst.relax_size = 0;
   5012               ldst_gp_p = 1;
   5013 	    }
   5014 	}
   5015     }
   5016 
   5017   /* Backup s3_inst.  */
   5018   memcpy (&inst_main, &s3_inst, sizeof (struct s3_score_it));
   5019   r1_bak = s3_nor1;
   5020   s3_nor1 = 0;
   5021 
   5022   /* Determine which instructions should be output.  */
   5023   sprintf (append_str[0], "ld_i32hi r1, %s", label_str);
   5024   sprintf (append_str[1], "ld_i32lo r1, %s", label_str);
   5025   sprintf (append_str[2], "%s r%d, [r1, 0]", inst_backup.name, reg_rd);
   5026 
   5027   /* Generate three instructions.
   5028      la r1, label
   5029      ld/st rd, [r1, 0]  */
   5030   for (i = 0; i < 3; i++)
   5031     {
   5032       if (s3_append_insn (append_str[i], FALSE) == (int) s3_FAIL)
   5033 	return;
   5034 
   5035       memcpy (&inst_expand[i], &s3_inst, sizeof (struct s3_score_it));
   5036     }
   5037 
   5038   if (ldst_gp_p)
   5039     {
   5040       char *p;
   5041 
   5042       /* Adjust instruction opcode and to be relaxed instruction opcode.  */
   5043       inst_main.instruction = s3_adjust_paritybit (inst_main.instruction, s3_GET_INSN_CLASS (inst_main.type));
   5044 
   5045       /* relax lw rd, label -> ldis rs, imm16
   5046 	 ori  rd, imm16
   5047 	 lw rd, [rs, imm15] or lw! rd, [rs, imm5].  */
   5048       if (inst_expand[2].relax_size == 0)
   5049         inst_main.relax_size = inst_expand[0].size + inst_expand[1].size + inst_expand[2].size;
   5050       else
   5051         inst_main.relax_size = inst_expand[0].size + inst_expand[1].size + inst_expand[2].relax_size;
   5052 
   5053       inst_main.type = Insn_GP;
   5054 
   5055       for (i = 0; i < 3; i++)
   5056 	inst_expand[i].instruction = s3_adjust_paritybit (inst_expand[i].instruction,
   5057                                                           s3_GET_INSN_CLASS (inst_expand[i].type));
   5058 
   5059       /* Check data dependency.  */
   5060       s3_handle_dependency (&inst_main);
   5061 
   5062       /* Start a new frag if frag_now is not empty.  */
   5063       if (frag_now_fix () != 0)
   5064         {
   5065           if (!frag_now->tc_frag_data.is_insn)
   5066 	    frag_wane (frag_now);
   5067 
   5068           frag_new (0);
   5069         }
   5070       frag_grow (20);
   5071 
   5072       /* Write fr_fix part.  */
   5073       p = frag_more (inst_main.size);
   5074       s3_md_number_to_chars (p, inst_main.instruction, inst_main.size);
   5075 
   5076       if (inst_main.reloc.type != BFD_RELOC_NONE)
   5077         {
   5078           s3_fix_new_score (frag_now, p - frag_now->fr_literal, inst_main.size,
   5079 			    &inst_main.reloc.exp, inst_main.reloc.pc_rel, inst_main.reloc.type);
   5080         }
   5081 
   5082 #ifdef OBJ_ELF
   5083       dwarf2_emit_insn (inst_main.size);
   5084 #endif
   5085 
   5086       /* s3_GP instruction can not do optimization, only can do relax between
   5087          1 instruction and 3 instructions.  */
   5088       p = frag_var (rs_machine_dependent, inst_main.relax_size + s3_RELAX_PAD_BYTE, 0,
   5089                     s3_RELAX_ENCODE (inst_main.size, inst_main.relax_size, inst_main.type, 0, 4, 0),
   5090                     inst_main.reloc.exp.X_add_symbol, 0, NULL);
   5091 
   5092       /* Write fr_var part.
   5093          no calling s3_gen_insn_frag, no fixS will be generated.  */
   5094       s3_md_number_to_chars (p, inst_expand[0].instruction, inst_expand[0].size);
   5095       p += inst_expand[0].size;
   5096       s3_md_number_to_chars (p, inst_expand[1].instruction, inst_expand[1].size);
   5097       p += inst_expand[1].size;
   5098 
   5099       /* relax lw rd, label -> ldis rs, imm16
   5100 	 ori  rd, imm16
   5101 	 lw rd, [rs, imm15] or lw! rd, [rs, imm5].  */
   5102       if (inst_expand[2].relax_size == 0)
   5103         s3_md_number_to_chars (p, inst_expand[2].instruction, inst_expand[2].size);
   5104       else
   5105         s3_md_number_to_chars (p, inst_expand[2].relax_inst, inst_expand[2].relax_size);
   5106     }
   5107   else
   5108     {
   5109       s3_gen_insn_frag (&inst_expand[0], NULL);
   5110       s3_gen_insn_frag (&inst_expand[1], NULL);
   5111       s3_gen_insn_frag (&inst_expand[2], NULL);
   5112     }
   5113   s3_nor1 = r1_bak;
   5114 
   5115   /* Set bwarn as -1, so macro instruction itself will not be generated frag.  */
   5116   s3_inst.bwarn = -1;
   5117 }
   5118 
   5119 static void
   5120 s3_do_lw_pic (char *str)
   5121 {
   5122   int reg_rd;
   5123 
   5124   s3_skip_whitespace (str);
   5125   if (((reg_rd = s3_reg_required_here (&str, 20, s3_REG_TYPE_SCORE)) == (int) s3_FAIL)
   5126       || (s3_skip_past_comma (&str) == (int) s3_FAIL)
   5127       || (s3_my_get_expression (&s3_inst.reloc.exp, &str) == (int) s3_FAIL)
   5128       || (s3_end_of_line (str) == (int) s3_FAIL))
   5129     {
   5130       return;
   5131     }
   5132   else
   5133     {
   5134       if (s3_inst.reloc.exp.X_add_symbol == 0)
   5135         {
   5136           if (!s3_inst.error)
   5137 	    s3_inst.error = s3_BAD_ARGS;
   5138 
   5139           return;
   5140         }
   5141 
   5142       s3_inst.instruction |= s3_GP << 15;
   5143       s3_inst.reloc.type = BFD_RELOC_SCORE_GOT15;
   5144     }
   5145 }
   5146 
   5147 static void
   5148 s3_do_empty (char *str)
   5149 {
   5150   str = str;
   5151   if (s3_university_version == 1)
   5152     {
   5153       if (((s3_inst.instruction & 0x3e0003ff) == 0x0c000004)
   5154           || ((s3_inst.instruction & 0x3e0003ff) == 0x0c000024)
   5155           || ((s3_inst.instruction & 0x3e0003ff) == 0x0c000044)
   5156           || ((s3_inst.instruction & 0x3e0003ff) == 0x0c000064))
   5157         {
   5158           s3_inst.error = s3_ERR_FOR_SCORE5U_MMU;
   5159           return;
   5160         }
   5161     }
   5162   if (s3_end_of_line (str) == (int) s3_FAIL)
   5163     return;
   5164 
   5165   if (s3_inst.relax_inst != 0x8000)
   5166     {
   5167       if (s3_inst.type == NO_OPD)
   5168         {
   5169           s3_inst.relax_size = 2;
   5170         }
   5171       else
   5172         {
   5173           s3_inst.relax_size = 4;
   5174         }
   5175     }
   5176 }
   5177 
   5178 static void
   5179 s3_do16_int (char *str)
   5180 {
   5181   s3_skip_whitespace (str);
   5182   return;
   5183 }
   5184 
   5185 static void
   5186 s3_do_jump (char *str)
   5187 {
   5188   char *save_in;
   5189 
   5190   s3_skip_whitespace (str);
   5191   if (s3_my_get_expression (&s3_inst.reloc.exp, &str) == (int) s3_FAIL
   5192       || s3_end_of_line (str) == (int) s3_FAIL)
   5193     return;
   5194 
   5195   if (s3_inst.reloc.exp.X_add_symbol == 0)
   5196     {
   5197       s3_inst.error = _("lacking label  ");
   5198       return;
   5199     }
   5200 
   5201   if (!(s3_inst.reloc.exp.X_add_number >= -16777216
   5202 	&& s3_inst.reloc.exp.X_add_number <= 16777215))
   5203     {
   5204       s3_inst.error = _("invalid constant: 25 bit expression not in range [-16777216, 16777215]");
   5205       return;
   5206     }
   5207 
   5208   save_in = input_line_pointer;
   5209   input_line_pointer = str;
   5210   s3_inst.reloc.type = BFD_RELOC_SCORE_JMP;
   5211   s3_inst.reloc.pc_rel = 1;
   5212   input_line_pointer = save_in;
   5213 }
   5214 
   5215 static void
   5216 s3_do_branch (char *str)
   5217 {
   5218   if (s3_my_get_expression (&s3_inst.reloc.exp, &str) == (int) s3_FAIL
   5219       || s3_end_of_line (str) == (int) s3_FAIL)
   5220     {
   5221       return;
   5222     }
   5223   else if (s3_inst.reloc.exp.X_add_symbol == 0)
   5224     {
   5225       s3_inst.error = _("lacking label  ");
   5226       return;
   5227     }
   5228   else if (!(s3_inst.reloc.exp.X_add_number >= -524288
   5229 	     && s3_inst.reloc.exp.X_add_number <= 524287))
   5230     {
   5231       s3_inst.error = _("invalid constant: 20 bit expression not in range -2^19..2^19");
   5232       return;
   5233     }
   5234 
   5235   s3_inst.reloc.type = BFD_RELOC_SCORE_BRANCH;
   5236   s3_inst.reloc.pc_rel = 1;
   5237 
   5238   /* Branch 32  offset field : 20 bit, 16 bit branch offset field : 8 bit.  */
   5239   s3_inst.instruction |= (s3_inst.reloc.exp.X_add_number & 0x3fe) | ((s3_inst.reloc.exp.X_add_number & 0xffc00) << 5);
   5240 
   5241   /* Compute 16 bit branch instruction.  */
   5242   if ((s3_inst.relax_inst != 0x8000)
   5243       && (s3_inst.reloc.exp.X_add_number >= -512 && s3_inst.reloc.exp.X_add_number <= 511))
   5244     {
   5245       s3_inst.relax_inst |= ((s3_inst.reloc.exp.X_add_number >> 1) & 0x1ff);/*b! :disp 9 bit */
   5246       s3_inst.relax_size = 2;
   5247     }
   5248   else
   5249     {
   5250       s3_inst.relax_inst = 0x8000;
   5251     }
   5252 }
   5253 
   5254 static void
   5255 s3_do16_branch (char *str)
   5256 {
   5257   if ((s3_my_get_expression (&s3_inst.reloc.exp, &str) == (int) s3_FAIL
   5258        || s3_end_of_line (str) == (int) s3_FAIL))
   5259     {
   5260       ;
   5261     }
   5262   else if (s3_inst.reloc.exp.X_add_symbol == 0)
   5263     {
   5264       s3_inst.error = _("lacking label");
   5265     }
   5266   else if (!(s3_inst.reloc.exp.X_add_number >= -512
   5267 	     && s3_inst.reloc.exp.X_add_number <= 511))
   5268     {
   5269       s3_inst.error = _("invalid constant: 10 bit expression not in range [-2^9, 2^9-1]");
   5270     }
   5271   else
   5272     {
   5273       s3_inst.reloc.type = BFD_RELOC_SCORE16_BRANCH;
   5274       s3_inst.reloc.pc_rel = 1;
   5275       s3_inst.instruction |= ((s3_inst.reloc.exp.X_add_number >> 1) & 0x1ff);
   5276       s3_inst.relax_inst |= ((s3_inst.reloc.exp.X_add_number ) & 0x1ff);
   5277       s3_inst.relax_size = 4;
   5278     }
   5279 }
   5280 
   5281 /* Return true if the given symbol should be considered local for s3_PIC.  */
   5282 static bfd_boolean
   5283 s3_pic_need_relax (symbolS *sym, asection *segtype)
   5284 {
   5285   asection *symsec;
   5286   bfd_boolean linkonce;
   5287 
   5288   /* Handle the case of a symbol equated to another symbol.  */
   5289   while (symbol_equated_reloc_p (sym))
   5290     {
   5291       symbolS *n;
   5292 
   5293       /* It's possible to get a loop here in a badly written
   5294 	 program.  */
   5295       n = symbol_get_value_expression (sym)->X_add_symbol;
   5296       if (n == sym)
   5297 	break;
   5298       sym = n;
   5299     }
   5300 
   5301   symsec = S_GET_SEGMENT (sym);
   5302 
   5303   /* duplicate the test for LINK_ONCE sections as in adjust_reloc_syms */
   5304   linkonce = FALSE;
   5305   if (symsec != segtype && ! S_IS_LOCAL (sym))
   5306     {
   5307       if ((bfd_get_section_flags (stdoutput, symsec) & SEC_LINK_ONCE) != 0)
   5308 	linkonce = TRUE;
   5309 
   5310       /* The GNU toolchain uses an extension for ELF: a section
   5311 	 beginning with the magic string .gnu.linkonce is a linkonce
   5312 	 section.  */
   5313       if (strncmp (segment_name (symsec), ".gnu.linkonce",
   5314 		   sizeof ".gnu.linkonce" - 1) == 0)
   5315 	linkonce = TRUE;
   5316     }
   5317 
   5318   /* This must duplicate the test in adjust_reloc_syms.  */
   5319   return (!bfd_is_und_section (symsec)
   5320 	  && !bfd_is_abs_section (symsec)
   5321 	  && !bfd_is_com_section (symsec)
   5322 	  && !linkonce
   5323 #ifdef OBJ_ELF
   5324 	  /* A global or weak symbol is treated as external.  */
   5325 	  && (OUTPUT_FLAVOR != bfd_target_elf_flavour
   5326 	      || (! S_IS_WEAK (sym) && ! S_IS_EXTERNAL (sym)))
   5327 #endif
   5328 	  );
   5329 }
   5330 
   5331 static void
   5332 s3_parse_pce_inst (char *insnstr)
   5333 {
   5334   char c;
   5335   char *p;
   5336   char first[s3_MAX_LITERAL_POOL_SIZE];
   5337   char second[s3_MAX_LITERAL_POOL_SIZE];
   5338   struct s3_score_it pec_part_1;
   5339 
   5340   /* Get first part string of PCE.  */
   5341   p = strstr (insnstr, "||");
   5342   c = *p;
   5343   *p = '\0';
   5344   sprintf (first, "%s", insnstr);
   5345 
   5346   /* Get second part string of PCE.  */
   5347   *p = c;
   5348   p += 2;
   5349   sprintf (second, "%s", p);
   5350 
   5351   s3_parse_16_32_inst (first, FALSE);
   5352   if (s3_inst.error)
   5353     return;
   5354 
   5355   memcpy (&pec_part_1, &s3_inst, sizeof (s3_inst));
   5356 
   5357   s3_parse_16_32_inst (second, FALSE);
   5358   if (s3_inst.error)
   5359     return;
   5360 
   5361   if (   ((pec_part_1.size == s3_INSN_SIZE) && (s3_inst.size == s3_INSN_SIZE))
   5362 	 || ((pec_part_1.size == s3_INSN_SIZE) && (s3_inst.size == s3_INSN16_SIZE))
   5363 	 || ((pec_part_1.size == s3_INSN16_SIZE) && (s3_inst.size == s3_INSN_SIZE)))
   5364     {
   5365       s3_inst.error = _("pce instruction error (16 bit || 16 bit)'");
   5366       sprintf (s3_inst.str, "%s", insnstr);
   5367       return;
   5368     }
   5369 
   5370   if (!s3_inst.error)
   5371     s3_gen_insn_frag (&pec_part_1, &s3_inst);
   5372 }
   5373 
   5374 /* s3: dsp.  */
   5375 static void
   5376 s3_do16_dsp (char *str)
   5377 {
   5378   int rd = 0;
   5379 
   5380   /* Check 3d.  */
   5381   if (s3_score3d == 0)
   5382     {
   5383       s3_inst.error = _("score3d instruction.");
   5384       return;
   5385     }
   5386 
   5387   s3_skip_whitespace (str);
   5388 
   5389   if ((rd = s3_reglow_required_here (&str, 0)) == (int) s3_FAIL
   5390       || s3_end_of_line (str) == (int) s3_FAIL)
   5391     {
   5392       return;
   5393     }
   5394   else
   5395     {
   5396       s3_inst.relax_inst |= rd << 20;
   5397       s3_inst.relax_size = 4;
   5398     }
   5399 }
   5400 
   5401 static void
   5402 s3_do16_dsp2 (char *str)
   5403 {
   5404   /* Check 3d.  */
   5405   if (s3_score3d == 0)
   5406     {
   5407       s3_inst.error = _("score3d instruction.");
   5408       return;
   5409     }
   5410 
   5411   s3_skip_whitespace (str);
   5412 
   5413   if (s3_reglow_required_here (&str, 4) == (int) s3_FAIL
   5414       || s3_skip_past_comma (&str) == (int) s3_FAIL
   5415       || s3_reglow_required_here (&str, 0) == (int) s3_FAIL
   5416       || s3_end_of_line (str) == (int) s3_FAIL)
   5417     {
   5418       return;
   5419     }
   5420   else
   5421     {
   5422       s3_inst.relax_inst |= (((s3_inst.instruction >> 8) & 0xf) << 20)
   5423         | (((s3_inst.instruction >> 8) & 0xf) << 15) | (((s3_inst.instruction >> 4) & 0xf) << 10);
   5424       s3_inst.relax_size = 4;
   5425     }
   5426 }
   5427 
   5428 static void
   5429 s3_do_dsp (char *str)
   5430 {
   5431   /* Check 3d.  */
   5432   if (s3_score3d == 0)
   5433     {
   5434       s3_inst.error = _("score3d instruction.");
   5435       return;
   5436     }
   5437 
   5438   s3_skip_whitespace (str);
   5439 
   5440   if (s3_reg_required_here (&str, 15, s3_REG_TYPE_SCORE) == (int) s3_FAIL
   5441       || s3_skip_past_comma (&str) == (int) s3_FAIL
   5442       || s3_reg_required_here (&str, 10, s3_REG_TYPE_SCORE) == (int) s3_FAIL
   5443       || s3_end_of_line (str) == (int) s3_FAIL)
   5444     return;
   5445 
   5446   if ((s3_inst.relax_inst != 0x8000) && (((s3_inst.instruction >> 20) & 0x1f) == 3) )
   5447     {
   5448       s3_inst.relax_inst |= (((s3_inst.instruction >> 10) & 0x1f)) | (((s3_inst.instruction >> 15) & 0x1f) << 5);
   5449       s3_inst.relax_size = 2;
   5450     }
   5451   else
   5452     s3_inst.relax_inst = 0x8000;
   5453 }
   5454 
   5455 static void
   5456 s3_do_dsp2 (char *str)
   5457 {
   5458   int reg;
   5459 
   5460   /* Check 3d.  */
   5461   if (s3_score3d == 0)
   5462     {
   5463       s3_inst.error = _("score3d instruction.");
   5464       return;
   5465     }
   5466 
   5467   s3_skip_whitespace (str);
   5468 
   5469   if ((reg = s3_reg_required_here (&str, 20, s3_REG_TYPE_SCORE)) == (int) s3_FAIL
   5470       || s3_skip_past_comma (&str) == (int) s3_FAIL
   5471       || s3_reg_required_here (&str, 15, s3_REG_TYPE_SCORE) == (int) s3_FAIL
   5472       || s3_skip_past_comma (&str) == (int) s3_FAIL
   5473       || s3_reg_required_here (&str, 10, s3_REG_TYPE_SCORE) == (int) s3_FAIL
   5474       || s3_end_of_line (str) == (int) s3_FAIL)
   5475     {
   5476       return;
   5477     }
   5478   else
   5479     {
   5480       /* Check mulr, mulur rd is even number.  */
   5481       if (((s3_inst.instruction & 0x3e0003ff) == 0x00000340
   5482 	   || (s3_inst.instruction & 0x3e0003ff) == 0x00000342)
   5483           && (reg % 2))
   5484         {
   5485           s3_inst.error = _("rd must be even number.");
   5486           return;
   5487         }
   5488 
   5489       if ((((s3_inst.instruction >> 15) & 0x10) == 0)
   5490           && (((s3_inst.instruction >> 10) & 0x10) == 0)
   5491           && (((s3_inst.instruction >> 20) & 0x10) == 0)
   5492           && (s3_inst.relax_inst != 0x8000)
   5493           && (((s3_inst.instruction >> 20) & 0xf) == ((s3_inst.instruction >> 15) & 0xf)))
   5494         {
   5495           s3_inst.relax_inst |= (((s3_inst.instruction >> 10) & 0xf) )
   5496             | (((s3_inst.instruction >> 15) & 0xf) << 4);
   5497           s3_inst.relax_size = 2;
   5498         }
   5499       else
   5500         {
   5501           s3_inst.relax_inst = 0x8000;
   5502         }
   5503     }
   5504 }
   5505 
   5506 static void
   5507 s3_do_dsp3 (char *str)
   5508 {
   5509   /* Check 3d.  */
   5510   if (s3_score3d == 0)
   5511     {
   5512       s3_inst.error = _("score3d instruction.");
   5513       return;
   5514     }
   5515 
   5516   s3_skip_whitespace (str);
   5517 
   5518   if (s3_reg_required_here (&str, 20, s3_REG_TYPE_SCORE) == (int) s3_FAIL
   5519       || s3_skip_past_comma (&str) == (int) s3_FAIL
   5520       || s3_reg_required_here (&str, 15, s3_REG_TYPE_SCORE) == (int) s3_FAIL
   5521       || s3_end_of_line (str) == (int) s3_FAIL)
   5522     return;
   5523 
   5524   if ((s3_inst.relax_inst != 0x8000) && (((s3_inst.instruction >> 20) & 0x1f) == 3) )
   5525     {
   5526       s3_inst.relax_inst |= (((s3_inst.instruction >> 10) & 0x1f)) | (((s3_inst.instruction >> 15) & 0x1f) << 5);
   5527       s3_inst.relax_size = 2;
   5528     }
   5529   else
   5530     s3_inst.relax_inst = 0x8000;
   5531 }
   5532 
   5533 
   5534 /* If we change section we must dump the literal pool first.  */
   5535 static void
   5536 s3_s_score_bss (int ignore ATTRIBUTE_UNUSED)
   5537 {
   5538   subseg_set (bss_section, (subsegT) get_absolute_expression ());
   5539   demand_empty_rest_of_line ();
   5540 }
   5541 
   5542 static void
   5543 s3_s_score_text (int ignore)
   5544 {
   5545   obj_elf_text (ignore);
   5546   record_alignment (now_seg, 2);
   5547 }
   5548 
   5549 static void
   5550 s3_score_s_section (int ignore)
   5551 {
   5552   obj_elf_section (ignore);
   5553   if ((bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) != 0)
   5554     record_alignment (now_seg, 2);
   5555 
   5556 }
   5557 
   5558 static void
   5559 s3_s_change_sec (int sec)
   5560 {
   5561   segT seg;
   5562 
   5563 #ifdef OBJ_ELF
   5564   /* The ELF backend needs to know that we are changing sections, so
   5565      that .previous works correctly.  We could do something like check
   5566      for an obj_section_change_hook macro, but that might be confusing
   5567      as it would not be appropriate to use it in the section changing
   5568      functions in read.c, since obj-elf.c intercepts those.  FIXME:
   5569      This should be cleaner, somehow.  */
   5570   obj_elf_section_change_hook ();
   5571 #endif
   5572   switch (sec)
   5573     {
   5574     case 'r':
   5575       seg = subseg_new (s3_RDATA_SECTION_NAME, (subsegT) get_absolute_expression ());
   5576       bfd_set_section_flags (stdoutput, seg, (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_RELOC | SEC_DATA));
   5577       if (strcmp (TARGET_OS, "elf") != 0)
   5578         record_alignment (seg, 4);
   5579       demand_empty_rest_of_line ();
   5580       break;
   5581     case 's':
   5582       seg = subseg_new (".sdata", (subsegT) get_absolute_expression ());
   5583       bfd_set_section_flags (stdoutput, seg, SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA);
   5584       if (strcmp (TARGET_OS, "elf") != 0)
   5585         record_alignment (seg, 4);
   5586       demand_empty_rest_of_line ();
   5587       break;
   5588     }
   5589 }
   5590 
   5591 static void
   5592 s3_s_score_mask (int reg_type ATTRIBUTE_UNUSED)
   5593 {
   5594   long mask, off;
   5595 
   5596   if (s3_cur_proc_ptr == (s3_procS *) NULL)
   5597     {
   5598       as_warn (_(".mask outside of .ent"));
   5599       demand_empty_rest_of_line ();
   5600       return;
   5601     }
   5602   if (get_absolute_expression_and_terminator (&mask) != ',')
   5603     {
   5604       as_warn (_("Bad .mask directive"));
   5605       --input_line_pointer;
   5606       demand_empty_rest_of_line ();
   5607       return;
   5608     }
   5609   off = get_absolute_expression ();
   5610   s3_cur_proc_ptr->reg_mask = mask;
   5611   s3_cur_proc_ptr->reg_offset = off;
   5612   demand_empty_rest_of_line ();
   5613 }
   5614 
   5615 static symbolS *
   5616 s3_get_symbol (void)
   5617 {
   5618   int c;
   5619   char *name;
   5620   symbolS *p;
   5621 
   5622   name = input_line_pointer;
   5623   c = get_symbol_end ();
   5624   p = (symbolS *) symbol_find_or_make (name);
   5625   *input_line_pointer = c;
   5626   return p;
   5627 }
   5628 
   5629 static long
   5630 s3_get_number (void)
   5631 {
   5632   int negative = 0;
   5633   long val = 0;
   5634 
   5635   if (*input_line_pointer == '-')
   5636     {
   5637       ++input_line_pointer;
   5638       negative = 1;
   5639     }
   5640   if (!ISDIGIT (*input_line_pointer))
   5641     as_bad (_("expected simple number"));
   5642   if (input_line_pointer[0] == '0')
   5643     {
   5644       if (input_line_pointer[1] == 'x')
   5645         {
   5646           input_line_pointer += 2;
   5647           while (ISXDIGIT (*input_line_pointer))
   5648             {
   5649               val <<= 4;
   5650               val |= hex_value (*input_line_pointer++);
   5651             }
   5652           return negative ? -val : val;
   5653         }
   5654       else
   5655         {
   5656           ++input_line_pointer;
   5657           while (ISDIGIT (*input_line_pointer))
   5658             {
   5659               val <<= 3;
   5660               val |= *input_line_pointer++ - '0';
   5661             }
   5662           return negative ? -val : val;
   5663         }
   5664     }
   5665   if (!ISDIGIT (*input_line_pointer))
   5666     {
   5667       printf (_(" *input_line_pointer == '%c' 0x%02x\n"), *input_line_pointer, *input_line_pointer);
   5668       as_warn (_("invalid number"));
   5669       return -1;
   5670     }
   5671   while (ISDIGIT (*input_line_pointer))
   5672     {
   5673       val *= 10;
   5674       val += *input_line_pointer++ - '0';
   5675     }
   5676   return negative ? -val : val;
   5677 }
   5678 
   5679 /* The .aent and .ent directives.  */
   5680 static void
   5681 s3_s_score_ent (int aent)
   5682 {
   5683   symbolS *symbolP;
   5684   int maybe_text;
   5685 
   5686   symbolP = s3_get_symbol ();
   5687   if (*input_line_pointer == ',')
   5688     ++input_line_pointer;
   5689   SKIP_WHITESPACE ();
   5690   if (ISDIGIT (*input_line_pointer) || *input_line_pointer == '-')
   5691     s3_get_number ();
   5692 
   5693 #ifdef BFD_ASSEMBLER
   5694   if ((bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) != 0)
   5695     maybe_text = 1;
   5696   else
   5697     maybe_text = 0;
   5698 #else
   5699   if (now_seg != data_section && now_seg != bss_section)
   5700     maybe_text = 1;
   5701   else
   5702     maybe_text = 0;
   5703 #endif
   5704   if (!maybe_text)
   5705     as_warn (_(".ent or .aent not in text section."));
   5706   if (!aent && s3_cur_proc_ptr)
   5707     as_warn (_("missing .end"));
   5708   if (!aent)
   5709     {
   5710       s3_cur_proc_ptr = &s3_cur_proc;
   5711       s3_cur_proc_ptr->reg_mask = 0xdeadbeaf;
   5712       s3_cur_proc_ptr->reg_offset = 0xdeadbeaf;
   5713       s3_cur_proc_ptr->fpreg_mask = 0xdeafbeaf;
   5714       s3_cur_proc_ptr->leaf = 0xdeafbeaf;
   5715       s3_cur_proc_ptr->frame_offset = 0xdeafbeaf;
   5716       s3_cur_proc_ptr->frame_reg = 0xdeafbeaf;
   5717       s3_cur_proc_ptr->pc_reg = 0xdeafbeaf;
   5718       s3_cur_proc_ptr->isym = symbolP;
   5719       symbol_get_bfdsym (symbolP)->flags |= BSF_FUNCTION;
   5720       ++s3_numprocs;
   5721       if (debug_type == DEBUG_STABS)
   5722         stabs_generate_asm_func (S_GET_NAME (symbolP), S_GET_NAME (symbolP));
   5723     }
   5724   demand_empty_rest_of_line ();
   5725 }
   5726 
   5727 static void
   5728 s3_s_score_frame (int ignore ATTRIBUTE_UNUSED)
   5729 {
   5730   char *backupstr;
   5731   char str[30];
   5732   long val;
   5733   int i = 0;
   5734 
   5735   backupstr = input_line_pointer;
   5736 
   5737 #ifdef OBJ_ELF
   5738   if (s3_cur_proc_ptr == (s3_procS *) NULL)
   5739     {
   5740       as_warn (_(".frame outside of .ent"));
   5741       demand_empty_rest_of_line ();
   5742       return;
   5743     }
   5744   s3_cur_proc_ptr->frame_reg = s3_reg_required_here ((&backupstr), 0, s3_REG_TYPE_SCORE);
   5745   SKIP_WHITESPACE ();
   5746   s3_skip_past_comma (&backupstr);
   5747   while (*backupstr != ',')
   5748     {
   5749       str[i] = *backupstr;
   5750       i++;
   5751       backupstr++;
   5752     }
   5753   str[i] = '\0';
   5754   val = atoi (str);
   5755 
   5756   SKIP_WHITESPACE ();
   5757   s3_skip_past_comma (&backupstr);
   5758   s3_cur_proc_ptr->frame_offset = val;
   5759   s3_cur_proc_ptr->pc_reg = s3_reg_required_here ((&backupstr), 0, s3_REG_TYPE_SCORE);
   5760 
   5761   SKIP_WHITESPACE ();
   5762   s3_skip_past_comma (&backupstr);
   5763   i = 0;
   5764   while (*backupstr != '\n')
   5765     {
   5766       str[i] = *backupstr;
   5767       i++;
   5768       backupstr++;
   5769     }
   5770   str[i] = '\0';
   5771   val = atoi (str);
   5772   s3_cur_proc_ptr->leaf = val;
   5773   SKIP_WHITESPACE ();
   5774   s3_skip_past_comma (&backupstr);
   5775 
   5776 #endif /* OBJ_ELF */
   5777   while (input_line_pointer != backupstr)
   5778     input_line_pointer++;
   5779 }
   5780 
   5781 /* The .end directive.  */
   5782 static void
   5783 s3_s_score_end (int x ATTRIBUTE_UNUSED)
   5784 {
   5785   symbolS *p;
   5786   int maybe_text;
   5787 
   5788   /* Generate a .pdr section.  */
   5789   segT saved_seg = now_seg;
   5790   subsegT saved_subseg = now_subseg;
   5791   expressionS exp;
   5792   char *fragp;
   5793 
   5794   if (!is_end_of_line[(unsigned char)*input_line_pointer])
   5795     {
   5796       p = s3_get_symbol ();
   5797       demand_empty_rest_of_line ();
   5798     }
   5799   else
   5800     p = NULL;
   5801 
   5802 #ifdef BFD_ASSEMBLER
   5803   if ((bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) != 0)
   5804     maybe_text = 1;
   5805   else
   5806     maybe_text = 0;
   5807 #else
   5808   if (now_seg != data_section && now_seg != bss_section)
   5809     maybe_text = 1;
   5810   else
   5811     maybe_text = 0;
   5812 #endif
   5813 
   5814   if (!maybe_text)
   5815     as_warn (_(".end not in text section"));
   5816   if (!s3_cur_proc_ptr)
   5817     {
   5818       as_warn (_(".end directive without a preceding .ent directive."));
   5819       demand_empty_rest_of_line ();
   5820       return;
   5821     }
   5822   if (p != NULL)
   5823     {
   5824       gas_assert (S_GET_NAME (p));
   5825       if (strcmp (S_GET_NAME (p), S_GET_NAME (s3_cur_proc_ptr->isym)))
   5826         as_warn (_(".end symbol does not match .ent symbol."));
   5827       if (debug_type == DEBUG_STABS)
   5828         stabs_generate_asm_endfunc (S_GET_NAME (p), S_GET_NAME (p));
   5829     }
   5830   else
   5831     as_warn (_(".end directive missing or unknown symbol"));
   5832 
   5833   if ((s3_cur_proc_ptr->reg_mask == 0xdeadbeaf) ||
   5834       (s3_cur_proc_ptr->reg_offset == 0xdeadbeaf) ||
   5835       (s3_cur_proc_ptr->leaf == 0xdeafbeaf) ||
   5836       (s3_cur_proc_ptr->frame_offset == 0xdeafbeaf) ||
   5837       (s3_cur_proc_ptr->frame_reg == 0xdeafbeaf) || (s3_cur_proc_ptr->pc_reg == 0xdeafbeaf));
   5838 
   5839   else
   5840     {
   5841       (void) frag_now_fix ();
   5842       gas_assert (s3_pdr_seg);
   5843       subseg_set (s3_pdr_seg, 0);
   5844       /* Write the symbol.  */
   5845       exp.X_op = O_symbol;
   5846       exp.X_add_symbol = p;
   5847       exp.X_add_number = 0;
   5848       emit_expr (&exp, 4);
   5849       fragp = frag_more (7 * 4);
   5850       md_number_to_chars (fragp, (valueT) s3_cur_proc_ptr->reg_mask, 4);
   5851       md_number_to_chars (fragp + 4, (valueT) s3_cur_proc_ptr->reg_offset, 4);
   5852       md_number_to_chars (fragp + 8, (valueT) s3_cur_proc_ptr->fpreg_mask, 4);
   5853       md_number_to_chars (fragp + 12, (valueT) s3_cur_proc_ptr->leaf, 4);
   5854       md_number_to_chars (fragp + 16, (valueT) s3_cur_proc_ptr->frame_offset, 4);
   5855       md_number_to_chars (fragp + 20, (valueT) s3_cur_proc_ptr->frame_reg, 4);
   5856       md_number_to_chars (fragp + 24, (valueT) s3_cur_proc_ptr->pc_reg, 4);
   5857       subseg_set (saved_seg, saved_subseg);
   5858 
   5859     }
   5860   s3_cur_proc_ptr = NULL;
   5861 }
   5862 
   5863 /* Handle the .set pseudo-op.  */
   5864 static void
   5865 s3_s_score_set (int x ATTRIBUTE_UNUSED)
   5866 {
   5867   int i = 0;
   5868   char name[s3_MAX_LITERAL_POOL_SIZE];
   5869   char * orig_ilp = input_line_pointer;
   5870 
   5871   while (!is_end_of_line[(unsigned char)*input_line_pointer])
   5872     {
   5873       name[i] = (char) * input_line_pointer;
   5874       i++;
   5875       ++input_line_pointer;
   5876     }
   5877 
   5878   name[i] = '\0';
   5879 
   5880   if (strcmp (name, "nwarn") == 0)
   5881     {
   5882       s3_warn_fix_data_dependency = 0;
   5883     }
   5884   else if (strcmp (name, "fixdd") == 0)
   5885     {
   5886       s3_fix_data_dependency = 1;
   5887     }
   5888   else if (strcmp (name, "nofixdd") == 0)
   5889     {
   5890       s3_fix_data_dependency = 0;
   5891     }
   5892   else if (strcmp (name, "r1") == 0)
   5893     {
   5894       s3_nor1 = 0;
   5895     }
   5896   else if (strcmp (name, "nor1") == 0)
   5897     {
   5898       s3_nor1 = 1;
   5899     }
   5900   else if (strcmp (name, "optimize") == 0)
   5901     {
   5902       s3_g_opt = 1;
   5903     }
   5904   else if (strcmp (name, "volatile") == 0)
   5905     {
   5906       s3_g_opt = 0;
   5907     }
   5908   else if (strcmp (name, "pic") == 0)
   5909     {
   5910       s3_score_pic = s3_PIC;
   5911     }
   5912   else
   5913     {
   5914       input_line_pointer = orig_ilp;
   5915       s_set (0);
   5916     }
   5917 }
   5918 
   5919 /* Handle the .cpload pseudo-op.  This is used when generating s3_PIC code.  It sets the
   5920    $gp register for the function based on the function address, which is in the register
   5921    named in the argument. This uses a relocation against GP_DISP_LABEL, which is handled
   5922    specially by the linker.  The result is:
   5923    ldis gp, %hi(GP_DISP_LABEL)
   5924    ori  gp, %low(GP_DISP_LABEL)
   5925    add  gp, gp, .cpload argument
   5926    The .cpload argument is normally r29.  */
   5927 static void
   5928 s3_s_score_cpload (int ignore ATTRIBUTE_UNUSED)
   5929 {
   5930   int reg;
   5931   char insn_str[s3_MAX_LITERAL_POOL_SIZE];
   5932 
   5933   /* If we are not generating s3_PIC code, .cpload is ignored.  */
   5934   if (s3_score_pic == s3_NO_PIC)
   5935     {
   5936       s_ignore (0);
   5937       return;
   5938     }
   5939 
   5940   if ((reg = s3_reg_required_here (&input_line_pointer, -1, s3_REG_TYPE_SCORE)) == (int) s3_FAIL)
   5941     return;
   5942 
   5943   demand_empty_rest_of_line ();
   5944 
   5945   sprintf (insn_str, "ld_i32hi r%d, %s", s3_GP, GP_DISP_LABEL);
   5946   if (s3_append_insn (insn_str, TRUE) == (int) s3_FAIL)
   5947     return;
   5948 
   5949   sprintf (insn_str, "ld_i32lo r%d, %s", s3_GP, GP_DISP_LABEL);
   5950   if (s3_append_insn (insn_str, TRUE) == (int) s3_FAIL)
   5951     return;
   5952 
   5953   sprintf (insn_str, "add r%d, r%d, r%d", s3_GP, s3_GP, reg);
   5954   if (s3_append_insn (insn_str, TRUE) == (int) s3_FAIL)
   5955     return;
   5956 }
   5957 
   5958 /* Handle the .cprestore pseudo-op.  This stores $gp into a given
   5959    offset from $sp.  The offset is remembered, and after making a s3_PIC
   5960    call $gp is restored from that location.  */
   5961 static void
   5962 s3_s_score_cprestore (int ignore ATTRIBUTE_UNUSED)
   5963 {
   5964   int reg;
   5965   int cprestore_offset;
   5966   char insn_str[s3_MAX_LITERAL_POOL_SIZE];
   5967 
   5968   /* If we are not generating s3_PIC code, .cprestore is ignored.  */
   5969   if (s3_score_pic == s3_NO_PIC)
   5970     {
   5971       s_ignore (0);
   5972       return;
   5973     }
   5974 
   5975   if ((reg = s3_reg_required_here (&input_line_pointer, -1, s3_REG_TYPE_SCORE)) == (int) s3_FAIL
   5976       || s3_skip_past_comma (&input_line_pointer) == (int) s3_FAIL)
   5977     {
   5978       return;
   5979     }
   5980 
   5981   cprestore_offset = get_absolute_expression ();
   5982 
   5983   if (cprestore_offset <= 0x3fff)
   5984     {
   5985       sprintf (insn_str, "sw r%d, [r%d, %d]", s3_GP, reg, cprestore_offset);
   5986       if (s3_append_insn (insn_str, TRUE) == (int) s3_FAIL)
   5987         return;
   5988     }
   5989   else
   5990     {
   5991       int r1_bak;
   5992 
   5993       r1_bak = s3_nor1;
   5994       s3_nor1 = 0;
   5995 
   5996       sprintf (insn_str, "li r1, %d", cprestore_offset);
   5997       if (s3_append_insn (insn_str, TRUE) == (int) s3_FAIL)
   5998         return;
   5999 
   6000       sprintf (insn_str, "add r1, r1, r%d", reg);
   6001       if (s3_append_insn (insn_str, TRUE) == (int) s3_FAIL)
   6002         return;
   6003 
   6004       sprintf (insn_str, "sw r%d, [r1]", s3_GP);
   6005       if (s3_append_insn (insn_str, TRUE) == (int) s3_FAIL)
   6006         return;
   6007 
   6008       s3_nor1 = r1_bak;
   6009     }
   6010 
   6011   demand_empty_rest_of_line ();
   6012 }
   6013 
   6014 /* Handle the .gpword pseudo-op.  This is used when generating s3_PIC
   6015    code.  It generates a 32 bit s3_GP relative reloc.  */
   6016 static void
   6017 s3_s_score_gpword (int ignore ATTRIBUTE_UNUSED)
   6018 {
   6019   expressionS ex;
   6020   char *p;
   6021 
   6022   /* When not generating s3_PIC code, this is treated as .word.  */
   6023   if (s3_score_pic == s3_NO_PIC)
   6024     {
   6025       cons (4);
   6026       return;
   6027     }
   6028   expression (&ex);
   6029   if (ex.X_op != O_symbol || ex.X_add_number != 0)
   6030     {
   6031       as_bad (_("Unsupported use of .gpword"));
   6032       ignore_rest_of_line ();
   6033     }
   6034   p = frag_more (4);
   6035   s3_md_number_to_chars (p, (valueT) 0, 4);
   6036   fix_new_exp (frag_now, p - frag_now->fr_literal, 4, &ex, FALSE, BFD_RELOC_GPREL32);
   6037   demand_empty_rest_of_line ();
   6038 }
   6039 
   6040 /* Handle the .cpadd pseudo-op.  This is used when dealing with switch
   6041    tables in s3_PIC code.  */
   6042 static void
   6043 s3_s_score_cpadd (int ignore ATTRIBUTE_UNUSED)
   6044 {
   6045   int reg;
   6046   char insn_str[s3_MAX_LITERAL_POOL_SIZE];
   6047 
   6048   /* If we are not generating s3_PIC code, .cpload is ignored.  */
   6049   if (s3_score_pic == s3_NO_PIC)
   6050     {
   6051       s_ignore (0);
   6052       return;
   6053     }
   6054 
   6055   if ((reg = s3_reg_required_here (&input_line_pointer, -1, s3_REG_TYPE_SCORE)) == (int) s3_FAIL)
   6056     {
   6057       return;
   6058     }
   6059   demand_empty_rest_of_line ();
   6060 
   6061   /* Add $gp to the register named as an argument.  */
   6062   sprintf (insn_str, "add r%d, r%d, r%d", reg, reg, s3_GP);
   6063   if (s3_append_insn (insn_str, TRUE) == (int) s3_FAIL)
   6064     return;
   6065 }
   6066 
   6067 #ifndef TC_IMPLICIT_LCOMM_ALIGNMENT
   6068 #define TC_IMPLICIT_LCOMM_ALIGNMENT(SIZE, P2VAR)	\
   6069   do							\
   6070     {							\
   6071       if ((SIZE) >= 8)					\
   6072 	(P2VAR) = 3;					\
   6073       else if ((SIZE) >= 4)				\
   6074 	(P2VAR) = 2;					\
   6075       else if ((SIZE) >= 2)				\
   6076 	(P2VAR) = 1;					\
   6077       else						\
   6078 	(P2VAR) = 0;					\
   6079     }							\
   6080   while (0)
   6081 #endif
   6082 
   6083 static void
   6084 s3_s_score_lcomm (int bytes_p)
   6085 {
   6086   char *name;
   6087   char c;
   6088   char *p;
   6089   int temp;
   6090   symbolS *symbolP;
   6091   segT current_seg = now_seg;
   6092   subsegT current_subseg = now_subseg;
   6093   const int max_alignment = 15;
   6094   int align = 0;
   6095   segT bss_seg = bss_section;
   6096   int needs_align = 0;
   6097 
   6098   name = input_line_pointer;
   6099   c = get_symbol_end ();
   6100   p = input_line_pointer;
   6101   *p = c;
   6102 
   6103   if (name == p)
   6104     {
   6105       as_bad (_("expected symbol name"));
   6106       discard_rest_of_line ();
   6107       return;
   6108     }
   6109 
   6110   SKIP_WHITESPACE ();
   6111 
   6112   /* Accept an optional comma after the name.  The comma used to be
   6113      required, but Irix 5 cc does not generate it.  */
   6114   if (*input_line_pointer == ',')
   6115     {
   6116       ++input_line_pointer;
   6117       SKIP_WHITESPACE ();
   6118     }
   6119 
   6120   if (is_end_of_line[(unsigned char)*input_line_pointer])
   6121     {
   6122       as_bad (_("missing size expression"));
   6123       return;
   6124     }
   6125 
   6126   if ((temp = get_absolute_expression ()) < 0)
   6127     {
   6128       as_warn (_("BSS length (%d) < 0 ignored"), temp);
   6129       ignore_rest_of_line ();
   6130       return;
   6131     }
   6132 
   6133 #if defined (TC_SCORE)
   6134   if (OUTPUT_FLAVOR == bfd_target_ecoff_flavour || OUTPUT_FLAVOR == bfd_target_elf_flavour)
   6135     {
   6136       /* For Score and Alpha ECOFF or ELF, small objects are put in .sbss.  */
   6137       if ((unsigned)temp <= bfd_get_gp_size (stdoutput))
   6138         {
   6139           bss_seg = subseg_new (".sbss", 1);
   6140           seg_info (bss_seg)->bss = 1;
   6141 #ifdef BFD_ASSEMBLER
   6142           if (!bfd_set_section_flags (stdoutput, bss_seg, SEC_ALLOC))
   6143             as_warn (_("error setting flags for \".sbss\": %s"), bfd_errmsg (bfd_get_error ()));
   6144 #endif
   6145         }
   6146     }
   6147 #endif
   6148 
   6149   SKIP_WHITESPACE ();
   6150   if (*input_line_pointer == ',')
   6151     {
   6152       ++input_line_pointer;
   6153       SKIP_WHITESPACE ();
   6154 
   6155       if (is_end_of_line[(unsigned char)*input_line_pointer])
   6156         {
   6157           as_bad (_("missing alignment"));
   6158           return;
   6159         }
   6160       else
   6161         {
   6162           align = get_absolute_expression ();
   6163           needs_align = 1;
   6164         }
   6165     }
   6166 
   6167   if (!needs_align)
   6168     {
   6169       TC_IMPLICIT_LCOMM_ALIGNMENT (temp, align);
   6170 
   6171       /* Still zero unless TC_IMPLICIT_LCOMM_ALIGNMENT set it.  */
   6172       if (align)
   6173         record_alignment (bss_seg, align);
   6174     }
   6175 
   6176   if (needs_align)
   6177     {
   6178       if (bytes_p)
   6179         {
   6180           /* Convert to a power of 2.  */
   6181           if (align != 0)
   6182             {
   6183               unsigned int i;
   6184 
   6185               for (i = 0; align != 0; align >>= 1, ++i)
   6186                 ;
   6187               align = i - 1;
   6188             }
   6189         }
   6190 
   6191       if (align > max_alignment)
   6192         {
   6193           align = max_alignment;
   6194           as_warn (_("alignment too large; %d assumed"), align);
   6195         }
   6196       else if (align < 0)
   6197         {
   6198           align = 0;
   6199           as_warn (_("alignment negative; 0 assumed"));
   6200         }
   6201 
   6202       record_alignment (bss_seg, align);
   6203     }
   6204   else
   6205     {
   6206       /* Assume some objects may require alignment on some systems.  */
   6207 #if defined (TC_ALPHA) && ! defined (VMS)
   6208       if (temp > 1)
   6209         {
   6210           align = ffs (temp) - 1;
   6211           if (temp % (1 << align))
   6212             abort ();
   6213         }
   6214 #endif
   6215     }
   6216 
   6217   *p = 0;
   6218   symbolP = symbol_find_or_make (name);
   6219   *p = c;
   6220 
   6221   if (
   6222 #if (defined (OBJ_AOUT) || defined (OBJ_MAYBE_AOUT)	\
   6223      || defined (OBJ_BOUT) || defined (OBJ_MAYBE_BOUT))
   6224 #ifdef BFD_ASSEMBLER
   6225       (OUTPUT_FLAVOR != bfd_target_aout_flavour
   6226        || (S_GET_OTHER (symbolP) == 0 && S_GET_DESC (symbolP) == 0)) &&
   6227 #else
   6228       (S_GET_OTHER (symbolP) == 0 && S_GET_DESC (symbolP) == 0) &&
   6229 #endif
   6230 #endif
   6231       (S_GET_SEGMENT (symbolP) == bss_seg || (!S_IS_DEFINED (symbolP) && S_GET_VALUE (symbolP) == 0)))
   6232     {
   6233       char *pfrag;
   6234 
   6235       subseg_set (bss_seg, 1);
   6236 
   6237       if (align)
   6238         frag_align (align, 0, 0);
   6239 
   6240       /* Detach from old frag.  */
   6241       if (S_GET_SEGMENT (symbolP) == bss_seg)
   6242         symbol_get_frag (symbolP)->fr_symbol = NULL;
   6243 
   6244       symbol_set_frag (symbolP, frag_now);
   6245       pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP, (offsetT) temp, NULL);
   6246       *pfrag = 0;
   6247 
   6248 
   6249       S_SET_SEGMENT (symbolP, bss_seg);
   6250 
   6251 #ifdef OBJ_COFF
   6252       /* The symbol may already have been created with a preceding
   6253          ".globl" directive -- be careful not to step on storage class
   6254          in that case.  Otherwise, set it to static.  */
   6255       if (S_GET_STORAGE_CLASS (symbolP) != C_EXT)
   6256         {
   6257           S_SET_STORAGE_CLASS (symbolP, C_STAT);
   6258         }
   6259 #endif /* OBJ_COFF */
   6260 
   6261 #ifdef S_SET_SIZE
   6262       S_SET_SIZE (symbolP, temp);
   6263 #endif
   6264     }
   6265   else
   6266     as_bad (_("symbol `%s' is already defined"), S_GET_NAME (symbolP));
   6267 
   6268   subseg_set (current_seg, current_subseg);
   6269 
   6270   demand_empty_rest_of_line ();
   6271 }
   6272 
   6273 static void
   6274 s3_insert_reg (const struct s3_reg_entry *r, struct hash_control *htab)
   6275 {
   6276   int i = 0;
   6277   int len = strlen (r->name) + 2;
   6278   char *buf = xmalloc (len);
   6279   char *buf2 = xmalloc (len);
   6280 
   6281   strcpy (buf + i, r->name);
   6282   for (i = 0; buf[i]; i++)
   6283     {
   6284       buf2[i] = TOUPPER (buf[i]);
   6285     }
   6286   buf2[i] = '\0';
   6287 
   6288   hash_insert (htab, buf, (void *) r);
   6289   hash_insert (htab, buf2, (void *) r);
   6290 }
   6291 
   6292 static void
   6293 s3_build_reg_hsh (struct s3_reg_map *map)
   6294 {
   6295   const struct s3_reg_entry *r;
   6296 
   6297   if ((map->htab = hash_new ()) == NULL)
   6298     {
   6299       as_fatal (_("virtual memory exhausted"));
   6300     }
   6301   for (r = map->names; r->name != NULL; r++)
   6302     {
   6303       s3_insert_reg (r, map->htab);
   6304     }
   6305 }
   6306 
   6307 /* Iterate over the base tables to create the instruction patterns.  */
   6308 static void
   6309 s3_build_score_ops_hsh (void)
   6310 {
   6311   unsigned int i;
   6312   static struct obstack insn_obstack;
   6313 
   6314   obstack_begin (&insn_obstack, 4000);
   6315   for (i = 0; i < sizeof (s3_score_insns) / sizeof (struct s3_asm_opcode); i++)
   6316     {
   6317       const struct s3_asm_opcode *insn = s3_score_insns + i;
   6318       size_t len = strlen (insn->template_name);
   6319       struct s3_asm_opcode *new_opcode;
   6320       char *template_name;
   6321       new_opcode = (struct s3_asm_opcode *)
   6322 	obstack_alloc (&insn_obstack, sizeof (struct s3_asm_opcode));
   6323       template_name = (char *) obstack_alloc (& insn_obstack, len + 1);
   6324 
   6325       strcpy (template_name, insn->template_name);
   6326       new_opcode->template_name = template_name;
   6327       new_opcode->parms = insn->parms;
   6328       new_opcode->value = insn->value;
   6329       new_opcode->relax_value = insn->relax_value;
   6330       new_opcode->type = insn->type;
   6331       new_opcode->bitmask = insn->bitmask;
   6332       hash_insert (s3_score_ops_hsh, new_opcode->template_name,
   6333                    (void *) new_opcode);
   6334     }
   6335 }
   6336 
   6337 static void
   6338 s3_build_dependency_insn_hsh (void)
   6339 {
   6340   unsigned int i;
   6341   static struct obstack dependency_obstack;
   6342 
   6343   obstack_begin (&dependency_obstack, 4000);
   6344   for (i = 0; i < sizeof (s3_insn_to_dependency_table) / sizeof (s3_insn_to_dependency_table[0]); i++)
   6345     {
   6346       const struct s3_insn_to_dependency *tmp = s3_insn_to_dependency_table + i;
   6347       size_t len = strlen (tmp->insn_name);
   6348       struct s3_insn_to_dependency *new_i2n;
   6349 
   6350       new_i2n = (struct s3_insn_to_dependency *)
   6351 	obstack_alloc (&dependency_obstack,
   6352 		       sizeof (struct s3_insn_to_dependency));
   6353       new_i2n->insn_name = (char *) obstack_alloc (&dependency_obstack,
   6354                                                    len + 1);
   6355 
   6356       strcpy (new_i2n->insn_name, tmp->insn_name);
   6357       new_i2n->type = tmp->type;
   6358       hash_insert (s3_dependency_insn_hsh, new_i2n->insn_name,
   6359                    (void *) new_i2n);
   6360     }
   6361 }
   6362 
   6363 static void
   6364 s_score_bss (int ignore ATTRIBUTE_UNUSED)
   6365 {
   6366   if (score3)
   6367     return s3_s_score_bss (ignore);
   6368   else
   6369     return s7_s_score_bss (ignore);
   6370 }
   6371 
   6372 static void
   6373 s_score_text (int ignore)
   6374 {
   6375   if (score3)
   6376     return s3_s_score_text (ignore);
   6377   else
   6378     return s7_s_score_text (ignore);
   6379 }
   6380 
   6381 static void
   6382 s_section (int ignore)
   6383 {
   6384   if (score3)
   6385     return s3_score_s_section (ignore);
   6386   else
   6387     return s7_s_section (ignore);
   6388 }
   6389 
   6390 static void
   6391 s_change_sec (int sec)
   6392 {
   6393   if (score3)
   6394     return s3_s_change_sec (sec);
   6395   else
   6396     return s7_s_change_sec (sec);
   6397 }
   6398 
   6399 static void
   6400 s_score_mask (int reg_type ATTRIBUTE_UNUSED)
   6401 {
   6402   if (score3)
   6403     return s3_s_score_mask (reg_type);
   6404   else
   6405     return s7_s_score_mask (reg_type);
   6406 }
   6407 
   6408 static void
   6409 s_score_ent (int aent)
   6410 {
   6411   if (score3)
   6412     return s3_s_score_ent (aent);
   6413   else
   6414     return s7_s_score_ent (aent);
   6415 }
   6416 
   6417 static void
   6418 s_score_frame (int ignore ATTRIBUTE_UNUSED)
   6419 {
   6420   if (score3)
   6421     return s3_s_score_frame (ignore);
   6422   else
   6423     return s7_s_score_frame (ignore);
   6424 }
   6425 
   6426 static void
   6427 s_score_end (int x ATTRIBUTE_UNUSED)
   6428 {
   6429   if (score3)
   6430     return s3_s_score_end (x);
   6431   else
   6432     return s7_s_score_end (x);
   6433 }
   6434 
   6435 static void
   6436 s_score_set (int x ATTRIBUTE_UNUSED)
   6437 {
   6438   if (score3)
   6439     return s3_s_score_set (x);
   6440   else
   6441     return s7_s_score_set (x);
   6442 }
   6443 
   6444 static void
   6445 s_score_cpload (int ignore ATTRIBUTE_UNUSED)
   6446 {
   6447   if (score3)
   6448     return s3_s_score_cpload (ignore);
   6449   else
   6450     return s7_s_score_cpload (ignore);
   6451 }
   6452 
   6453 static void
   6454 s_score_cprestore (int ignore ATTRIBUTE_UNUSED)
   6455 {
   6456   if (score3)
   6457     return s3_s_score_cprestore (ignore);
   6458   else
   6459     return s7_s_score_cprestore (ignore);
   6460 }
   6461 
   6462 static void
   6463 s_score_gpword (int ignore ATTRIBUTE_UNUSED)
   6464 {
   6465   if (score3)
   6466     return s3_s_score_gpword (ignore);
   6467   else
   6468     return s7_s_score_gpword (ignore);
   6469 }
   6470 
   6471 static void
   6472 s_score_cpadd (int ignore ATTRIBUTE_UNUSED)
   6473 {
   6474   if (score3)
   6475     return s3_s_score_cpadd (ignore);
   6476   else
   6477     return s7_s_score_cpadd (ignore);
   6478 }
   6479 
   6480 static void
   6481 s_score_lcomm (int bytes_p)
   6482 {
   6483   if (score3)
   6484     return s3_s_score_lcomm (bytes_p);
   6485   else
   6486     return s7_s_score_lcomm (bytes_p);
   6487 }
   6488 
   6489 static void
   6490 s3_assemble (char *str)
   6491 {
   6492   know (str);
   6493   know (strlen (str) < s3_MAX_LITERAL_POOL_SIZE);
   6494 
   6495   memset (&s3_inst, '\0', sizeof (s3_inst));
   6496   if (s3_INSN_IS_PCE_P (str))
   6497     s3_parse_pce_inst (str);
   6498   else if (s3_INSN_IS_48_P (str))
   6499     s3_parse_48_inst (str, TRUE);
   6500   else
   6501     s3_parse_16_32_inst (str, TRUE);
   6502 
   6503   if (s3_inst.error)
   6504     as_bad (_("%s -- `%s'"), s3_inst.error, s3_inst.str);
   6505 }
   6506 
   6507 static void
   6508 s3_operand (expressionS * exp)
   6509 {
   6510   if (s3_in_my_get_expression)
   6511     {
   6512       exp->X_op = O_illegal;
   6513       if (s3_inst.error == NULL)
   6514         {
   6515           s3_inst.error = _("bad expression");
   6516         }
   6517     }
   6518 }
   6519 
   6520 static void
   6521 s3_begin (void)
   6522 {
   6523   unsigned int i;
   6524   segT seg;
   6525   subsegT subseg;
   6526 
   6527   if ((s3_score_ops_hsh = hash_new ()) == NULL)
   6528     as_fatal (_("virtual memory exhausted"));
   6529 
   6530   s3_build_score_ops_hsh ();
   6531 
   6532   if ((s3_dependency_insn_hsh = hash_new ()) == NULL)
   6533     as_fatal (_("virtual memory exhausted"));
   6534 
   6535   s3_build_dependency_insn_hsh ();
   6536 
   6537   for (i = (int)s3_REG_TYPE_FIRST; i < (int)s3_REG_TYPE_MAX; i++)
   6538     s3_build_reg_hsh (s3_all_reg_maps + i);
   6539 
   6540   /* Initialize dependency vector.  */
   6541   s3_init_dependency_vector ();
   6542 
   6543   bfd_set_arch_mach (stdoutput, TARGET_ARCH, 0);
   6544   seg = now_seg;
   6545   subseg = now_subseg;
   6546   s3_pdr_seg = subseg_new (".pdr", (subsegT) 0);
   6547   (void)bfd_set_section_flags (stdoutput, s3_pdr_seg, SEC_READONLY | SEC_RELOC | SEC_DEBUGGING);
   6548   (void)bfd_set_section_alignment (stdoutput, s3_pdr_seg, 2);
   6549   subseg_set (seg, subseg);
   6550 
   6551   if (s3_USE_GLOBAL_POINTER_OPT)
   6552     bfd_set_gp_size (stdoutput, s3_g_switch_value);
   6553 }
   6554 
   6555 static void
   6556 s3_number_to_chars (char *buf, valueT val, int n)
   6557 {
   6558   if (target_big_endian)
   6559     number_to_chars_bigendian (buf, val, n);
   6560   else
   6561     number_to_chars_littleendian (buf, val, n);
   6562 }
   6563 
   6564 static valueT
   6565 s3_normal_chars_to_number (char *buf, int n)
   6566 {
   6567   valueT result = 0;
   6568   unsigned char *where = (unsigned char *)buf;
   6569 
   6570   if (target_big_endian)
   6571     {
   6572       while (n--)
   6573         {
   6574           result <<= 8;
   6575           result |= (*where++ & 255);
   6576         }
   6577     }
   6578   else
   6579     {
   6580       while (n--)
   6581         {
   6582           result <<= 8;
   6583           result |= (where[n] & 255);
   6584         }
   6585     }
   6586 
   6587   return result;
   6588 }
   6589 
   6590 static void
   6591 s3_number_to_chars_littleendian (void *p, valueT data, int n)
   6592 {
   6593   char *buf = (char *) p;
   6594 
   6595   switch (n)
   6596     {
   6597     case 4:
   6598       md_number_to_chars (buf, data >> 16, 2);
   6599       md_number_to_chars (buf + 2, data, 2);
   6600       break;
   6601     case 6:
   6602       md_number_to_chars (buf, data >> 32, 2);
   6603       md_number_to_chars (buf + 2, data >> 16, 2);
   6604       md_number_to_chars (buf + 4, data, 2);
   6605       break;
   6606     default:
   6607       /* Error routine.  */
   6608       as_bad_where (__FILE__, __LINE__, _("size is not 4 or 6"));
   6609       break;
   6610     }
   6611 }
   6612 
   6613 static valueT
   6614 s3_chars_to_number_littleendian (const void *p, int n)
   6615 {
   6616   char *buf = (char *) p;
   6617   valueT result = 0;
   6618 
   6619   switch (n)
   6620     {
   6621     case 4:
   6622       result =  s3_normal_chars_to_number (buf, 2) << 16;
   6623       result |= s3_normal_chars_to_number (buf + 2, 2);
   6624       break;
   6625     case 6:
   6626       result =  s3_normal_chars_to_number (buf, 2) << 32;
   6627       result |= s3_normal_chars_to_number (buf + 2, 2) << 16;
   6628       result |= s3_normal_chars_to_number (buf + 4, 2);
   6629       break;
   6630     default:
   6631       /* Error routine.  */
   6632       as_bad_where (__FILE__, __LINE__, _("size is not 4 or 6"));
   6633       break;
   6634     }
   6635 
   6636   return result;
   6637 }
   6638 
   6639 static void
   6640 s3_md_number_to_chars (char *buf, valueT val, int n)
   6641 {
   6642   if (!target_big_endian && n >= 4)
   6643     s3_number_to_chars_littleendian (buf, val, n);
   6644   else
   6645     md_number_to_chars (buf, val, n);
   6646 }
   6647 
   6648 static valueT
   6649 s3_md_chars_to_number (char *buf, int n)
   6650 {
   6651   valueT result = 0;
   6652 
   6653   if (!target_big_endian && n >= 4)
   6654     result = s3_chars_to_number_littleendian (buf, n);
   6655   else
   6656     result = s3_normal_chars_to_number (buf, n);
   6657 
   6658   return result;
   6659 }
   6660 
   6661 static char *
   6662 s3_atof (int type, char *litP, int *sizeP)
   6663 {
   6664   int prec;
   6665   LITTLENUM_TYPE words[s3_MAX_LITTLENUMS];
   6666   char *t;
   6667   int i;
   6668 
   6669   switch (type)
   6670     {
   6671     case 'f':
   6672     case 'F':
   6673     case 's':
   6674     case 'S':
   6675       prec = 2;
   6676       break;
   6677     case 'd':
   6678     case 'D':
   6679     case 'r':
   6680     case 'R':
   6681       prec = 4;
   6682       break;
   6683     case 'x':
   6684     case 'X':
   6685     case 'p':
   6686     case 'P':
   6687       prec = 6;
   6688       break;
   6689     default:
   6690       *sizeP = 0;
   6691       return _("bad call to MD_ATOF()");
   6692     }
   6693 
   6694   t = atof_ieee (input_line_pointer, type, words);
   6695   if (t)
   6696     input_line_pointer = t;
   6697   *sizeP = prec * 2;
   6698 
   6699   if (target_big_endian)
   6700     {
   6701       for (i = 0; i < prec; i++)
   6702         {
   6703           s3_md_number_to_chars (litP, (valueT) words[i], 2);
   6704           litP += 2;
   6705         }
   6706     }
   6707   else
   6708     {
   6709       for (i = 0; i < prec; i += 2)
   6710         {
   6711           s3_md_number_to_chars (litP, (valueT) words[i + 1], 2);
   6712           s3_md_number_to_chars (litP + 2, (valueT) words[i], 2);
   6713           litP += 4;
   6714         }
   6715     }
   6716 
   6717   return 0;
   6718 }
   6719 
   6720 static void
   6721 s3_frag_check (fragS * fragp ATTRIBUTE_UNUSED)
   6722 {
   6723   know (fragp->insn_addr <= s3_RELAX_PAD_BYTE);
   6724 }
   6725 
   6726 static void
   6727 s3_validate_fix (fixS *fixP)
   6728 {
   6729   fixP->fx_where += fixP->fx_frag->insn_addr;
   6730 }
   6731 
   6732 static int
   6733 s3_force_relocation (struct fix *fixp)
   6734 {
   6735   int retval = 0;
   6736 
   6737   if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
   6738       || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY
   6739       || fixp->fx_r_type == BFD_RELOC_SCORE_JMP
   6740       || fixp->fx_r_type == BFD_RELOC_SCORE_BRANCH
   6741       || fixp->fx_r_type == BFD_RELOC_SCORE16_JMP
   6742       || fixp->fx_r_type == BFD_RELOC_SCORE16_BRANCH
   6743       || fixp->fx_r_type == BFD_RELOC_SCORE_BCMP)
   6744     {
   6745       retval = 1;
   6746     }
   6747   return retval;
   6748 }
   6749 
   6750 static bfd_boolean
   6751 s3_fix_adjustable (fixS * fixP)
   6752 {
   6753   if (fixP->fx_addsy == NULL)
   6754     {
   6755       return 1;
   6756     }
   6757   else if (OUTPUT_FLAVOR == bfd_target_elf_flavour
   6758 	   && (S_IS_EXTERNAL (fixP->fx_addsy) || S_IS_WEAK (fixP->fx_addsy)))
   6759     {
   6760       return 0;
   6761     }
   6762   else if (fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
   6763            || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY
   6764            || fixP->fx_r_type == BFD_RELOC_SCORE_JMP
   6765            || fixP->fx_r_type == BFD_RELOC_SCORE16_JMP)
   6766     {
   6767       return 0;
   6768     }
   6769 
   6770   return 1;
   6771 }
   6772 
   6773 static void
   6774 s3_elf_final_processing (void)
   6775 {
   6776   unsigned long val = 0;
   6777 
   6778   if (score3)
   6779     val = E_SCORE_MACH_SCORE3;
   6780   else if (score7)
   6781     val = E_SCORE_MACH_SCORE7;
   6782 
   6783   elf_elfheader (stdoutput)->e_machine = EM_SCORE;
   6784   elf_elfheader (stdoutput)->e_flags &= ~EF_SCORE_MACH;
   6785   elf_elfheader (stdoutput)->e_flags |= val;
   6786 
   6787   if (s3_fix_data_dependency == 1)
   6788     {
   6789       elf_elfheader (stdoutput)->e_flags |= EF_SCORE_FIXDEP;
   6790     }
   6791   if (s3_score_pic == s3_PIC)
   6792     {
   6793       elf_elfheader (stdoutput)->e_flags |= EF_SCORE_PIC;
   6794     }
   6795 }
   6796 
   6797 static int
   6798 s3_judge_size_before_relax (fragS * fragp, asection *sec)
   6799 {
   6800   int change = 0;
   6801 
   6802   if (s3_score_pic == s3_NO_PIC)
   6803     change = s3_nopic_need_relax (fragp->fr_symbol, 0);
   6804   else
   6805     change = s3_pic_need_relax (fragp->fr_symbol, sec);
   6806 
   6807   if (change == 1)
   6808     {
   6809       /* Only at the first time determining whether s3_GP instruction relax should be done,
   6810          return the difference between insntruction size and instruction relax size.  */
   6811       if (fragp->fr_opcode == NULL)
   6812 	{
   6813 	  fragp->fr_fix = s3_RELAX_NEW (fragp->fr_subtype);
   6814 	  fragp->fr_opcode = fragp->fr_literal + s3_RELAX_RELOC1 (fragp->fr_subtype);
   6815           return s3_RELAX_NEW (fragp->fr_subtype) - s3_RELAX_OLD (fragp->fr_subtype);
   6816 	}
   6817     }
   6818 
   6819   return 0;
   6820 }
   6821 
   6822 static int
   6823 s3_estimate_size_before_relax (fragS * fragp, asection * sec ATTRIBUTE_UNUSED)
   6824 {
   6825   if ((s3_RELAX_TYPE (fragp->fr_subtype) == Insn_GP)
   6826       || (s3_RELAX_TYPE (fragp->fr_subtype) == Insn_PIC))
   6827     return s3_judge_size_before_relax (fragp, sec);
   6828 
   6829   return 0;
   6830 }
   6831 
   6832 static int
   6833 s3_relax_branch_inst32 (fragS * fragp)
   6834 {
   6835   fragp->fr_opcode = NULL;
   6836   return 0;
   6837 }
   6838 
   6839 static int
   6840 s3_relax_branch_inst16 (fragS * fragp)
   6841 {
   6842   int relaxable_p = 0;
   6843   int frag_addr = fragp->fr_address + fragp->insn_addr;
   6844   addressT symbol_address = 0;
   6845   symbolS *s;
   6846   offsetT offset;
   6847   long value;
   6848   unsigned long inst_value;
   6849 
   6850   relaxable_p = s3_RELAX_OPT (fragp->fr_subtype);
   6851 
   6852   s = fragp->fr_symbol;
   6853   if (s == NULL)
   6854     frag_addr = 0;
   6855   else
   6856     {
   6857       if (s->bsym != NULL)
   6858         symbol_address = (addressT) symbol_get_frag (s)->fr_address;
   6859     }
   6860 
   6861   inst_value = s3_md_chars_to_number (fragp->fr_literal, s3_INSN16_SIZE);
   6862   offset = (inst_value & 0x1ff) << 1;
   6863   if ((offset & 0x200) == 0x200)
   6864     offset |= 0xfffffc00;
   6865 
   6866   value = offset + symbol_address - frag_addr;
   6867 
   6868   if (relaxable_p
   6869       && (!((value & 0xfffffe00) == 0 || (value & 0xfffffe00) == 0xfffffe00))
   6870       && fragp->fr_fix == 2
   6871       && (s->bsym != NULL)
   6872       && (S_IS_DEFINED (s)
   6873           && !S_IS_COMMON (s)
   6874           && !S_IS_EXTERNAL (s)))
   6875     {
   6876       /* Relax branch 32 to branch 16.  */
   6877       fragp->fr_opcode = fragp->fr_literal + s3_RELAX_RELOC1 (fragp->fr_subtype);
   6878       fragp->fr_fix = 4;
   6879       return 2;
   6880     }
   6881   else
   6882     return 0;
   6883 }
   6884 
   6885 static int
   6886 s3_relax_cmpbranch_inst32 (fragS * fragp)
   6887 {
   6888   int relaxable_p = 0;
   6889   symbolS *s;
   6890   /* For sign bit.  */
   6891   long offset;
   6892   long frag_addr = fragp->fr_address + fragp->insn_addr;
   6893   long symbol_address = 0;
   6894   long value;
   6895   unsigned long inst_value;
   6896 
   6897   relaxable_p = s3_RELAX_OPT (fragp->fr_subtype);
   6898 
   6899   s = fragp->fr_symbol;
   6900   if (s == NULL)
   6901     frag_addr = 0;
   6902   else
   6903     {
   6904       if (s->bsym != NULL)
   6905 	symbol_address = (addressT) symbol_get_frag (s)->fr_address;
   6906     }
   6907 
   6908   inst_value = s3_md_chars_to_number (fragp->fr_literal, s3_INSN_SIZE);
   6909   offset = (inst_value & 0x1)
   6910     | (((inst_value >> 7) & 0x7) << 1)
   6911     | (((inst_value >> 21) & 0x1f) << 4);
   6912   offset <<= 1;
   6913   if ((offset & 0x200) == 0x200)
   6914     offset |= 0xfffffe00;
   6915 
   6916   value = offset + symbol_address - frag_addr;
   6917   /* change the order of judging rule is because
   6918      1.not defined symbol or common sysbol or external symbol will change
   6919      bcmp to cmp!+beq/bne ,here need to record fragp->fr_opcode
   6920      2.if the flow is as before : it will results to recursive loop
   6921   */
   6922   if (fragp->fr_fix == 6)
   6923     {
   6924       /* Have already relaxed!  Just return 0 to terminate the loop.  */
   6925       return 0;
   6926     }
   6927   /* need to translate when extern or not defind or common sysbol */
   6928   else if ((relaxable_p
   6929 	    && (!((value & 0xfffffe00) == 0 || (value & 0xfffffe00) == 0xfffffe00))
   6930 	    && fragp->fr_fix == 4
   6931 	    && (s->bsym != NULL))
   6932 	   || !S_IS_DEFINED (s)
   6933 	   ||S_IS_COMMON (s)
   6934 	   ||S_IS_EXTERNAL (s))
   6935     {
   6936       fragp->fr_opcode = fragp->fr_literal + s3_RELAX_RELOC1 (fragp->fr_subtype);
   6937       fragp->fr_fix = 6;
   6938       return 2;
   6939     }
   6940   else
   6941     {
   6942       /* Never relax.  Modify fr_opcode to NULL to verify it's value in
   6943          md_apply_fix.  */
   6944       fragp->fr_opcode = NULL;
   6945       return 0;
   6946     }
   6947 }
   6948 
   6949 
   6950 static int
   6951 s3_relax_other_inst32 (fragS * fragp)
   6952 {
   6953   int relaxable_p = s3_RELAX_OPT (fragp->fr_subtype);
   6954 
   6955   if (relaxable_p
   6956       && fragp->fr_fix == 4)
   6957     {
   6958       fragp->fr_opcode = fragp->fr_literal + s3_RELAX_RELOC1 (fragp->fr_subtype);
   6959       fragp->fr_fix = 2;
   6960       return -2;
   6961     }
   6962   else
   6963     return 0;
   6964 }
   6965 
   6966 static int
   6967 s3_relax_gp_and_pic_inst32 (void)
   6968 {
   6969   /* md_estimate_size_before_relax has already relaxed s3_GP and s3_PIC
   6970      instructions.  We don't change relax size here.  */
   6971   return 0;
   6972 }
   6973 
   6974 static int
   6975 s3_relax_frag (asection * sec ATTRIBUTE_UNUSED, fragS * fragp, long stretch ATTRIBUTE_UNUSED)
   6976 {
   6977   int grows = 0;
   6978   int adjust_align_p = 0;
   6979 
   6980   /* If the instruction address is odd, make it half word align first.  */
   6981   if ((fragp->fr_address) % 2 != 0)
   6982     {
   6983       if ((fragp->fr_address + fragp->insn_addr) % 2 != 0)
   6984 	{
   6985           fragp->insn_addr = 1;
   6986           grows += 1;
   6987           adjust_align_p = 1;
   6988 	}
   6989     }
   6990 
   6991   switch (s3_RELAX_TYPE (fragp->fr_subtype))
   6992     {
   6993     case PC_DISP19div2:
   6994       grows += s3_relax_branch_inst32 (fragp);
   6995       break;
   6996 
   6997     case PC_DISP8div2:
   6998       grows += s3_relax_branch_inst16 (fragp);
   6999       break;
   7000 
   7001     case Insn_BCMP :
   7002       grows += s3_relax_cmpbranch_inst32 (fragp);
   7003       break;
   7004 
   7005     case Insn_GP:
   7006     case Insn_PIC:
   7007       grows += s3_relax_gp_and_pic_inst32 ();
   7008       break;
   7009 
   7010     default:
   7011       grows += s3_relax_other_inst32 (fragp);
   7012       break;
   7013     }
   7014 
   7015   /* newly added */
   7016   if (adjust_align_p && fragp->insn_addr)
   7017     {
   7018       fragp->fr_fix += fragp->insn_addr;
   7019     }
   7020 
   7021   return grows;
   7022 }
   7023 
   7024 static void
   7025 s3_convert_frag (bfd * abfd ATTRIBUTE_UNUSED, segT sec ATTRIBUTE_UNUSED, fragS * fragp)
   7026 {
   7027   int r_old;
   7028   int r_new;
   7029   char backup[20];
   7030   fixS *fixp;
   7031 
   7032   r_old = s3_RELAX_OLD (fragp->fr_subtype);
   7033   r_new = s3_RELAX_NEW (fragp->fr_subtype);
   7034 
   7035   /* fragp->fr_opcode indicates whether this frag should be relaxed.  */
   7036   if (fragp->fr_opcode == NULL)
   7037     {
   7038       memcpy (backup, fragp->fr_literal, r_old);
   7039       fragp->fr_fix = r_old;
   7040     }
   7041   else
   7042     {
   7043       memcpy (backup, fragp->fr_literal + r_old, r_new);
   7044       fragp->fr_fix = r_new;
   7045     }
   7046 
   7047   fixp = fragp->tc_frag_data.fixp;
   7048   while (fixp && fixp->fx_frag == fragp && fixp->fx_where < r_old)
   7049     {
   7050       if (fragp->fr_opcode)
   7051 	fixp->fx_done = 1;
   7052       fixp = fixp->fx_next;
   7053     }
   7054   while (fixp && fixp->fx_frag == fragp)
   7055     {
   7056       if (fragp->fr_opcode)
   7057 	fixp->fx_where -= r_old + fragp->insn_addr;
   7058       else
   7059 	fixp->fx_done = 1;
   7060       fixp = fixp->fx_next;
   7061     }
   7062 
   7063   if (fragp->insn_addr)
   7064     {
   7065       s3_md_number_to_chars (fragp->fr_literal, 0x0, fragp->insn_addr);
   7066     }
   7067   memcpy (fragp->fr_literal + fragp->insn_addr, backup, fragp->fr_fix);
   7068   fragp->fr_fix += fragp->insn_addr;
   7069 }
   7070 
   7071 static long
   7072 s3_pcrel_from (fixS * fixP)
   7073 {
   7074   long retval = 0;
   7075 
   7076   if (fixP->fx_addsy
   7077       && (S_GET_SEGMENT (fixP->fx_addsy) == undefined_section)
   7078       && (fixP->fx_subsy == NULL))
   7079     {
   7080       retval = 0;
   7081     }
   7082   else
   7083     {
   7084       retval = fixP->fx_where + fixP->fx_frag->fr_address;
   7085     }
   7086 
   7087   return retval;
   7088 }
   7089 
   7090 static valueT
   7091 s3_section_align (segT segment ATTRIBUTE_UNUSED, valueT size)
   7092 {
   7093   int align = bfd_get_section_alignment (stdoutput, segment);
   7094   return ((size + (1 << align) - 1) & (-1 << align));
   7095 }
   7096 
   7097 static void
   7098 s3_apply_fix (fixS *fixP, valueT *valP, segT seg)
   7099 {
   7100   offsetT value = *valP;
   7101   offsetT newval;
   7102   offsetT content;
   7103   unsigned short HI, LO;
   7104 
   7105   char *buf = fixP->fx_frag->fr_literal + fixP->fx_where;
   7106 
   7107   gas_assert (fixP->fx_r_type < BFD_RELOC_UNUSED);
   7108   if (fixP->fx_addsy == 0 && !fixP->fx_pcrel)
   7109     {
   7110       if (fixP->fx_r_type != BFD_RELOC_SCORE_DUMMY_HI16)
   7111         fixP->fx_done = 1;
   7112     }
   7113 
   7114   /* If this symbol is in a different section then we need to leave it for
   7115      the linker to deal with.  Unfortunately, md_pcrel_from can't tell,
   7116      so we have to undo it's effects here.  */
   7117   if (fixP->fx_pcrel)
   7118     {
   7119       if (fixP->fx_addsy != NULL
   7120 	  && S_IS_DEFINED (fixP->fx_addsy)
   7121 	  && S_GET_SEGMENT (fixP->fx_addsy) != seg)
   7122 	value += md_pcrel_from (fixP);
   7123     }
   7124 
   7125   /* Remember value for emit_reloc.  */
   7126   fixP->fx_addnumber = value;
   7127 
   7128   switch (fixP->fx_r_type)
   7129     {
   7130     case BFD_RELOC_HI16_S:
   7131       if (fixP->fx_done)        /* For la rd, imm32.  */
   7132         {
   7133           newval = s3_md_chars_to_number (buf, s3_INSN_SIZE);
   7134           HI = (value) >> 16;   /* mul to 2, then take the hi 16 bit.  */
   7135           newval |= (HI & 0x3fff) << 1;
   7136           newval |= ((HI >> 14) & 0x3) << 16;
   7137           s3_md_number_to_chars (buf, newval, s3_INSN_SIZE);
   7138         }
   7139       break;
   7140     case BFD_RELOC_LO16:
   7141       if (fixP->fx_done)        /* For la rd, imm32.  */
   7142         {
   7143           newval = s3_md_chars_to_number (buf, s3_INSN_SIZE);
   7144           LO = (value) & 0xffff;
   7145           newval |= (LO & 0x3fff) << 1; /* 16 bit: imm -> 14 bit in lo, 2 bit in hi.  */
   7146           newval |= ((LO >> 14) & 0x3) << 16;
   7147           s3_md_number_to_chars (buf, newval, s3_INSN_SIZE);
   7148         }
   7149       break;
   7150     case BFD_RELOC_SCORE_JMP:
   7151       {
   7152         content = s3_md_chars_to_number (buf, s3_INSN_SIZE);
   7153         value = fixP->fx_offset;
   7154         content = (content & ~0x3ff7ffe) | ((value << 1) & 0x3ff0000) | (value & 0x7fff);
   7155         s3_md_number_to_chars (buf, content, s3_INSN_SIZE);
   7156       }
   7157       break;
   7158 
   7159     case BFD_RELOC_SCORE_IMM30:
   7160       {
   7161         content = s3_md_chars_to_number (buf, s3_INSN48_SIZE);
   7162         value = fixP->fx_offset;
   7163         value >>= 2;
   7164         content = (content & ~0x7f7fff7f80LL)
   7165 	  | (((value & 0xff) >> 0) << 7)
   7166 	  | (((value & 0x7fff00) >> 8) << 16)
   7167 	  | (((value & 0x3f800000) >> 23) << 32);
   7168         s3_md_number_to_chars (buf, content, s3_INSN48_SIZE);
   7169         break;
   7170       }
   7171 
   7172     case BFD_RELOC_SCORE_IMM32:
   7173       {
   7174         content = s3_md_chars_to_number (buf, s3_INSN48_SIZE);
   7175         value = fixP->fx_offset;
   7176         content = (content & ~0x7f7fff7fe0LL)
   7177 	  | ((value & 0x3ff) << 5)
   7178 	  | (((value >> 10) & 0x7fff) << 16)
   7179 	  | (((value >> 25) & 0x7f) << 32);
   7180         s3_md_number_to_chars (buf, content, s3_INSN48_SIZE);
   7181         break;
   7182       }
   7183 
   7184     case BFD_RELOC_SCORE_BRANCH:
   7185       if ((S_GET_SEGMENT (fixP->fx_addsy) != seg) || (fixP->fx_addsy != NULL && S_IS_EXTERNAL (fixP->fx_addsy)))
   7186         value = fixP->fx_offset;
   7187       else
   7188         fixP->fx_done = 1;
   7189 
   7190       content = s3_md_chars_to_number (buf, s3_INSN_SIZE);
   7191 
   7192       /* Don't check c-bit.  */
   7193       if (fixP->fx_frag->fr_opcode != 0)
   7194         {
   7195           if ((value & 0xfffffe00) != 0 && (value & 0xfffffe00) != 0xfffffe00)
   7196             {
   7197               as_bad_where (fixP->fx_file, fixP->fx_line,
   7198                             _(" branch relocation truncate (0x%x) [-2^9 ~ 2^9]"), (unsigned int)value);
   7199               return;
   7200             }
   7201           content = s3_md_chars_to_number (buf, s3_INSN16_SIZE);
   7202           content &= 0xfe00;
   7203           content = (content & 0xfe00) | ((value >> 1) & 0x1ff);
   7204           s3_md_number_to_chars (buf, content, s3_INSN16_SIZE);
   7205           fixP->fx_r_type = BFD_RELOC_SCORE16_BRANCH;
   7206           fixP->fx_size = 2;
   7207         }
   7208       else
   7209         {
   7210           if ((value & 0xfff80000) != 0 && (value & 0xfff80000) != 0xfff80000)
   7211             {
   7212               as_bad_where (fixP->fx_file, fixP->fx_line,
   7213                             _(" branch relocation truncate (0x%x) [-2^19 ~ 2^19]"), (unsigned int)value);
   7214               return;
   7215             }
   7216           content = s3_md_chars_to_number (buf, s3_INSN_SIZE);
   7217           content &= 0xfc00fc01;
   7218           content = (content & 0xfc00fc01) | (value & 0x3fe) | ((value << 6) & 0x3ff0000);
   7219           s3_md_number_to_chars (buf, content, s3_INSN_SIZE);
   7220         }
   7221       break;
   7222     case BFD_RELOC_SCORE16_JMP:
   7223       content = s3_md_chars_to_number (buf, s3_INSN16_SIZE);
   7224       content &= 0xf001;
   7225       value = fixP->fx_offset & 0xfff;
   7226       content = (content & 0xfc01) | (value & 0xffe);
   7227       s3_md_number_to_chars (buf, content, s3_INSN16_SIZE);
   7228       break;
   7229     case BFD_RELOC_SCORE16_BRANCH:
   7230       content = s3_md_chars_to_number (buf, s3_INSN_SIZE);
   7231       /* Don't check c-bit.  */
   7232       if (fixP->fx_frag->fr_opcode != 0)
   7233         {
   7234           if ((S_GET_SEGMENT (fixP->fx_addsy) != seg) ||
   7235               (fixP->fx_addsy != NULL && S_IS_EXTERNAL (fixP->fx_addsy)))
   7236             value = fixP->fx_offset;
   7237           else
   7238             fixP->fx_done = 1;
   7239           if ((value & 0xfff80000) != 0 && (value & 0xfff80000) != 0xfff80000)
   7240             {
   7241               as_bad_where (fixP->fx_file, fixP->fx_line,
   7242                             _(" branch relocation truncate (0x%x) [-2^19 ~ 2^19]"), (unsigned int)value);
   7243               return;
   7244             }
   7245           content = s3_md_chars_to_number (buf, s3_INSN_SIZE);
   7246           content = (content & 0xfc00fc01) | (value & 0x3fe) | ((value << 6) & 0x3ff0000);
   7247           s3_md_number_to_chars (buf, content, s3_INSN_SIZE);
   7248           fixP->fx_r_type = BFD_RELOC_SCORE_BRANCH;
   7249           fixP->fx_size = 4;
   7250           break;
   7251         }
   7252       else
   7253         {
   7254           /* In differnt section.  */
   7255           if ((S_GET_SEGMENT (fixP->fx_addsy) != seg) ||
   7256               (fixP->fx_addsy != NULL && S_IS_EXTERNAL (fixP->fx_addsy)))
   7257             value = fixP->fx_offset;
   7258           else
   7259             fixP->fx_done = 1;
   7260 
   7261           if ((value & 0xfffffe00) != 0 && (value & 0xfffffe00) != 0xfffffe00)
   7262             {
   7263               as_bad_where (fixP->fx_file, fixP->fx_line,
   7264                             _(" branch relocation truncate (0x%x)  [-2^9 ~ 2^9]"), (unsigned int)value);
   7265               return;
   7266             }
   7267 
   7268           content = s3_md_chars_to_number (buf, s3_INSN16_SIZE);
   7269           content = (content & 0xfe00) | ((value >> 1) & 0x1ff);
   7270           s3_md_number_to_chars (buf, content, s3_INSN16_SIZE);
   7271           break;
   7272         }
   7273 
   7274       break;
   7275 
   7276     case BFD_RELOC_SCORE_BCMP:
   7277       if (fixP->fx_frag->fr_opcode != 0)
   7278         {
   7279           char *buf_ptr = buf;
   7280           buf_ptr += 2;
   7281 
   7282           if ((S_GET_SEGMENT (fixP->fx_addsy) != seg) || (fixP->fx_addsy != NULL && S_IS_EXTERNAL (fixP->fx_addsy)))
   7283             value = fixP->fx_offset;
   7284           else
   7285             fixP->fx_done = 1;
   7286 
   7287           /* NOTE!!!
   7288              bcmp -> cmp! and branch, so value -= 2.  */
   7289           value -= 2;
   7290 
   7291           if ((value & 0xfff80000) != 0 && (value & 0xfff80000) != 0xfff80000)
   7292             {
   7293               as_bad_where (fixP->fx_file, fixP->fx_line,
   7294                             _(" branch relocation truncate (0x%x) [-2^19 ~ 2^19]"), (unsigned int)value);
   7295               return;
   7296             }
   7297 
   7298           content = s3_md_chars_to_number (buf_ptr, s3_INSN_SIZE);
   7299           content &= 0xfc00fc01;
   7300           content = (content & 0xfc00fc01) | (value & 0x3fe) | ((value << 6) & 0x3ff0000);
   7301           s3_md_number_to_chars (buf_ptr, content, s3_INSN_SIZE);
   7302           /* change relocation type to BFD_RELOC_SCORE_BRANCH */
   7303           fixP->fx_r_type = BFD_RELOC_SCORE_BRANCH;
   7304           fixP->fx_where+=2; /* first insn is cmp! , the second insn is beq/bne */
   7305           break;
   7306         }
   7307       else
   7308         {
   7309           if ((S_GET_SEGMENT (fixP->fx_addsy) != seg) || (fixP->fx_addsy != NULL && S_IS_EXTERNAL (fixP->fx_addsy)))
   7310             value = fixP->fx_offset;
   7311           else
   7312             fixP->fx_done = 1;
   7313 
   7314           content = s3_md_chars_to_number (buf, s3_INSN_SIZE);
   7315 
   7316           if ((value & 0xfffffe00) != 0 && (value & 0xfffffe00) != 0xfffffe00)
   7317             {
   7318               as_bad_where (fixP->fx_file, fixP->fx_line,
   7319 			    _(" branch relocation truncate (0x%x)  [-2^9 ~ 2^9]"), (unsigned int)value);
   7320               return;
   7321             }
   7322 
   7323           value >>= 1;
   7324           content &= ~0x03e00381;
   7325           content = content
   7326 	    | (value & 0x1)
   7327 	    | (((value & 0xe) >> 1) << 7)
   7328 	    | (((value & 0x1f0) >> 4) << 21);
   7329 
   7330           s3_md_number_to_chars (buf, content, s3_INSN_SIZE);
   7331           break;
   7332         }
   7333 
   7334     case BFD_RELOC_8:
   7335       if (fixP->fx_done || fixP->fx_pcrel)
   7336 	s3_md_number_to_chars (buf, value, 1);
   7337 #ifdef OBJ_ELF
   7338       else
   7339         {
   7340           value = fixP->fx_offset;
   7341           s3_md_number_to_chars (buf, value, 1);
   7342         }
   7343 #endif
   7344       break;
   7345 
   7346     case BFD_RELOC_16:
   7347       if (fixP->fx_done || fixP->fx_pcrel)
   7348         s3_md_number_to_chars (buf, value, 2);
   7349 #ifdef OBJ_ELF
   7350       else
   7351         {
   7352           value = fixP->fx_offset;
   7353           s3_md_number_to_chars (buf, value, 2);
   7354         }
   7355 #endif
   7356       break;
   7357     case BFD_RELOC_RVA:
   7358     case BFD_RELOC_32:
   7359       if (fixP->fx_done || fixP->fx_pcrel)
   7360         md_number_to_chars (buf, value, 4);
   7361 #ifdef OBJ_ELF
   7362       else
   7363         {
   7364           value = fixP->fx_offset;
   7365           md_number_to_chars (buf, value, 4);
   7366         }
   7367 #endif
   7368       break;
   7369     case BFD_RELOC_VTABLE_INHERIT:
   7370       fixP->fx_done = 0;
   7371       if (fixP->fx_addsy && !S_IS_DEFINED (fixP->fx_addsy) && !S_IS_WEAK (fixP->fx_addsy))
   7372         S_SET_WEAK (fixP->fx_addsy);
   7373       break;
   7374     case BFD_RELOC_VTABLE_ENTRY:
   7375       fixP->fx_done = 0;
   7376       break;
   7377     case BFD_RELOC_SCORE_GPREL15:
   7378       content = s3_md_chars_to_number (buf, s3_INSN_SIZE);
   7379       /* c-bit.  */
   7380       if ((fixP->fx_frag->fr_opcode != 0) && ((content & 0xfc1c8000) != 0x94180000))
   7381         fixP->fx_r_type = BFD_RELOC_NONE;
   7382       fixP->fx_done = 0;
   7383       break;
   7384     case BFD_RELOC_SCORE_GOT15:
   7385     case BFD_RELOC_SCORE_DUMMY_HI16:
   7386     case BFD_RELOC_SCORE_GOT_LO16:
   7387     case BFD_RELOC_SCORE_CALL15:
   7388     case BFD_RELOC_GPREL32:
   7389       break;
   7390     case BFD_RELOC_NONE:
   7391     default:
   7392       as_bad_where (fixP->fx_file, fixP->fx_line, _("bad relocation fixup type (%d)"), fixP->fx_r_type);
   7393     }
   7394 }
   7395 
   7396 static arelent **
   7397 s3_gen_reloc (asection * section ATTRIBUTE_UNUSED, fixS * fixp)
   7398 {
   7399   static arelent *retval[MAX_RELOC_EXPANSION + 1];  /* MAX_RELOC_EXPANSION equals 2.  */
   7400   arelent *reloc;
   7401   bfd_reloc_code_real_type code;
   7402   char *type;
   7403 
   7404   reloc = retval[0] = xmalloc (sizeof (arelent));
   7405   retval[1] = NULL;
   7406 
   7407   reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
   7408   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
   7409   reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
   7410   reloc->addend = fixp->fx_offset;
   7411 
   7412   /* If this is a variant frag, we may need to adjust the existing
   7413      reloc and generate a new one.  */
   7414   if (fixp->fx_frag->fr_opcode != NULL && (fixp->fx_r_type == BFD_RELOC_SCORE_GPREL15))
   7415     {
   7416       /* Update instruction imm bit.  */
   7417       offsetT newval;
   7418       unsigned short off;
   7419       char *buf;
   7420 
   7421       buf = fixp->fx_frag->fr_literal + fixp->fx_frag->insn_addr;
   7422       newval = s3_md_chars_to_number (buf, s3_INSN_SIZE);
   7423       off = fixp->fx_offset >> 16;
   7424       newval |= (off & 0x3fff) << 1;
   7425       newval |= ((off >> 14) & 0x3) << 16;
   7426       s3_md_number_to_chars (buf, newval, s3_INSN_SIZE);
   7427 
   7428       buf += s3_INSN_SIZE;
   7429       newval = s3_md_chars_to_number (buf, s3_INSN_SIZE);
   7430       off = fixp->fx_offset & 0xffff;
   7431       newval |= ((off & 0x3fff) << 1);
   7432       newval |= (((off >> 14) & 0x3) << 16);
   7433       s3_md_number_to_chars (buf, newval, s3_INSN_SIZE);
   7434 
   7435       retval[1] = xmalloc (sizeof (arelent));
   7436       retval[2] = NULL;
   7437       retval[1]->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
   7438       *retval[1]->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
   7439       retval[1]->address = (reloc->address + s3_RELAX_RELOC2 (fixp->fx_frag->fr_subtype));
   7440 
   7441       retval[1]->addend = 0;
   7442       retval[1]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_LO16);
   7443       gas_assert (retval[1]->howto != NULL);
   7444 
   7445       fixp->fx_r_type = BFD_RELOC_HI16_S;
   7446     }
   7447 
   7448   code = fixp->fx_r_type;
   7449   switch (fixp->fx_r_type)
   7450     {
   7451     case BFD_RELOC_32:
   7452       if (fixp->fx_pcrel)
   7453         {
   7454           code = BFD_RELOC_32_PCREL;
   7455           break;
   7456         }
   7457     case BFD_RELOC_HI16_S:
   7458     case BFD_RELOC_LO16:
   7459     case BFD_RELOC_SCORE_JMP:
   7460     case BFD_RELOC_SCORE_BRANCH:
   7461     case BFD_RELOC_SCORE16_JMP:
   7462     case BFD_RELOC_SCORE16_BRANCH:
   7463     case BFD_RELOC_SCORE_BCMP:
   7464     case BFD_RELOC_VTABLE_ENTRY:
   7465     case BFD_RELOC_VTABLE_INHERIT:
   7466     case BFD_RELOC_SCORE_GPREL15:
   7467     case BFD_RELOC_SCORE_GOT15:
   7468     case BFD_RELOC_SCORE_DUMMY_HI16:
   7469     case BFD_RELOC_SCORE_GOT_LO16:
   7470     case BFD_RELOC_SCORE_CALL15:
   7471     case BFD_RELOC_GPREL32:
   7472     case BFD_RELOC_NONE:
   7473     case BFD_RELOC_SCORE_IMM30:
   7474     case BFD_RELOC_SCORE_IMM32:
   7475       code = fixp->fx_r_type;
   7476       break;
   7477     default:
   7478       type = _("<unknown>");
   7479       as_bad_where (fixp->fx_file, fixp->fx_line,
   7480                     _("cannot represent %s relocation in this object file format"), type);
   7481       return NULL;
   7482     }
   7483 
   7484   reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
   7485   if (reloc->howto == NULL)
   7486     {
   7487       as_bad_where (fixp->fx_file, fixp->fx_line,
   7488                     _("cannot represent %s relocation in this object file format1"),
   7489                     bfd_get_reloc_code_name (code));
   7490       return NULL;
   7491     }
   7492   /* HACK: Since arm ELF uses Rel instead of Rela, encode the
   7493      vtable entry to be used in the relocation's section offset.  */
   7494   if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
   7495     reloc->address = fixp->fx_offset;
   7496 
   7497   return retval;
   7498 }
   7499 
   7500 void
   7501 md_assemble (char *str)
   7502 {
   7503   if (score3)
   7504     s3_assemble (str);
   7505   else
   7506     s7_assemble (str);
   7507 }
   7508 
   7509 /* We handle all bad expressions here, so that we can report the faulty
   7510    instruction in the error message.  */
   7511 void
   7512 md_operand (expressionS * exp)
   7513 {
   7514   if (score3)
   7515     s3_operand (exp);
   7516   else
   7517     s7_operand (exp);
   7518 }
   7519 
   7520 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
   7521    for use in the a.out file, and stores them in the array pointed to by buf.
   7522    This knows about the endian-ness of the target machine and does
   7523    THE RIGHT THING, whatever it is.  Possible values for n are 1 (byte)
   7524    2 (short) and 4 (long)  Floating numbers are put out as a series of
   7525    LITTLENUMS (shorts, here at least).  */
   7526 void
   7527 md_number_to_chars (char *buf, valueT val, int n)
   7528 {
   7529   if (score3)
   7530     s3_number_to_chars (buf, val, n);
   7531   else
   7532     s7_number_to_chars (buf, val, n);
   7533 }
   7534 
   7535 /* Turn a string in input_line_pointer into a floating point constant
   7536    of type TYPE, and store the appropriate bytes in *LITP.  The number
   7537    of LITTLENUMS emitted is stored in *SIZEP.  An error message is
   7538    returned, or NULL on OK.
   7539 
   7540    Note that fp constants aren't represent in the normal way on the ARM.
   7541    In big endian mode, things are as expected.  However, in little endian
   7542    mode fp constants are big-endian word-wise, and little-endian byte-wise
   7543    within the words.  For example, (double) 1.1 in big endian mode is
   7544    the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
   7545    the byte sequence 99 99 f1 3f 9a 99 99 99.  */
   7546 char *
   7547 md_atof (int type, char *litP, int *sizeP)
   7548 {
   7549   if (score3)
   7550     return s3_atof (type, litP, sizeP);
   7551   else
   7552     return s7_atof (type, litP, sizeP);
   7553 }
   7554 
   7555 void
   7556 score_frag_check (fragS * fragp ATTRIBUTE_UNUSED)
   7557 {
   7558   if (score3)
   7559     s3_frag_check (fragp);
   7560   else
   7561     s7_frag_check (fragp);
   7562 }
   7563 
   7564 /* Implementation of TC_VALIDATE_FIX.
   7565    Called before md_apply_fix() and after md_convert_frag().  */
   7566 void
   7567 score_validate_fix (fixS *fixP)
   7568 {
   7569   if (score3)
   7570     s3_validate_fix (fixP);
   7571   else
   7572     s7_validate_fix (fixP);
   7573 }
   7574 
   7575 int
   7576 score_force_relocation (struct fix *fixp)
   7577 {
   7578   if (score3)
   7579     return s3_force_relocation (fixp);
   7580   else
   7581     return s7_force_relocation (fixp);
   7582 }
   7583 
   7584 /* Implementation of md_frag_check.
   7585    Called after md_convert_frag().  */
   7586 bfd_boolean
   7587 score_fix_adjustable (fixS * fixP)
   7588 {
   7589   if (score3)
   7590     return s3_fix_adjustable (fixP);
   7591   else
   7592     return s7_fix_adjustable (fixP);
   7593 }
   7594 
   7595 void
   7596 score_elf_final_processing (void)
   7597 {
   7598   if (score3)
   7599     s3_elf_final_processing ();
   7600   else
   7601     s7_elf_final_processing ();
   7602 }
   7603 
   7604 /* In this function, we determine whether s3_GP instruction should do relaxation,
   7605    for the label being against was known now.
   7606    Doing this here but not in md_relax_frag() can induce iteration times
   7607    in stage of doing relax.  */
   7608 int
   7609 md_estimate_size_before_relax (fragS * fragp, asection * sec ATTRIBUTE_UNUSED)
   7610 {
   7611   if (score3)
   7612     return s3_estimate_size_before_relax (fragp, sec);
   7613   else
   7614     return s7_estimate_size_before_relax (fragp, sec);
   7615 }
   7616 
   7617 int
   7618 score_relax_frag (asection * sec ATTRIBUTE_UNUSED, fragS * fragp, long stretch ATTRIBUTE_UNUSED)
   7619 {
   7620   if (score3)
   7621     return s3_relax_frag (sec, fragp, stretch);
   7622   else
   7623     return s7_relax_frag (sec, fragp, stretch);
   7624 }
   7625 
   7626 void
   7627 md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED, segT sec ATTRIBUTE_UNUSED, fragS * fragp)
   7628 {
   7629   if (score3)
   7630     return s3_convert_frag (abfd, sec, fragp);
   7631   else
   7632     return s7_convert_frag (abfd, sec, fragp);
   7633 }
   7634 
   7635 long
   7636 md_pcrel_from (fixS * fixP)
   7637 {
   7638   if (score3)
   7639     return s3_pcrel_from (fixP);
   7640   else
   7641     return s7_pcrel_from (fixP);
   7642 }
   7643 
   7644 /* Round up a section size to the appropriate boundary.  */
   7645 valueT
   7646 md_section_align (segT segment ATTRIBUTE_UNUSED, valueT size)
   7647 {
   7648   if (score3)
   7649     return s3_section_align (segment, size);
   7650   else
   7651     return s7_section_align (segment, size);
   7652 }
   7653 
   7654 void
   7655 md_apply_fix (fixS *fixP, valueT *valP, segT seg)
   7656 {
   7657   if (score3)
   7658     return s3_apply_fix (fixP, valP, seg);
   7659   else
   7660     return s7_apply_fix (fixP, valP, seg);
   7661 }
   7662 
   7663 /* Translate internal representation of relocation info to BFD target format.  */
   7664 arelent **
   7665 tc_gen_reloc (asection * section ATTRIBUTE_UNUSED, fixS * fixp)
   7666 {
   7667   if (score3)
   7668     return s3_gen_reloc (section, fixp);
   7669   else
   7670     return s7_gen_reloc (section, fixp);
   7671 }
   7672 
   7673 void
   7674 md_begin (void)
   7675 {
   7676   s3_begin ();
   7677   s7_begin ();
   7678 }
   7679 
   7680 static void
   7681 score_set_mach (const char *arg)
   7682 {
   7683   if (strcmp (arg, MARCH_SCORE3) == 0)
   7684     {
   7685       score3 = 1;
   7686       score7 = 0;
   7687       s3_score3d = 1;
   7688     }
   7689   else if (strcmp (arg, MARCH_SCORE7) == 0)
   7690     {
   7691       score3 = 0;
   7692       score7 = 1;
   7693       s7_score7d = 1;
   7694       s7_university_version = 0;
   7695       s7_vector_size = s7_SCORE7_PIPELINE;
   7696     }
   7697   else if (strcmp (arg, MARCH_SCORE5) == 0)
   7698     {
   7699       score3 = 0;
   7700       score7 = 1;
   7701       s7_score7d = 1;
   7702       s7_university_version = 0;
   7703       s7_vector_size = s7_SCORE5_PIPELINE;
   7704     }
   7705   else if (strcmp (arg, MARCH_SCORE5U) == 0)
   7706     {
   7707       score3 = 0;
   7708       score7 = 1;
   7709       s7_score7d = 1;
   7710       s7_university_version = 1;
   7711       s7_vector_size = s7_SCORE5_PIPELINE;
   7712     }
   7713   else
   7714     {
   7715       as_bad (_("unknown architecture `%s'\n"), arg);
   7716     }
   7717 }
   7718 
   7719 int
   7720 md_parse_option (int c, char *arg)
   7721 {
   7722   switch (c)
   7723     {
   7724 #ifdef OPTION_EB
   7725     case OPTION_EB:
   7726       target_big_endian = 1;
   7727       break;
   7728 #endif
   7729 #ifdef OPTION_EL
   7730     case OPTION_EL:
   7731       target_big_endian = 0;
   7732       break;
   7733 #endif
   7734     case OPTION_FIXDD:
   7735       s3_fix_data_dependency = 1;
   7736       s7_fix_data_dependency = 1;
   7737       break;
   7738     case OPTION_NWARN:
   7739       s3_warn_fix_data_dependency = 0;
   7740       s7_warn_fix_data_dependency = 0;
   7741       break;
   7742     case OPTION_SCORE5:
   7743       score3 = 0;
   7744       score7 = 1;
   7745       s7_university_version = 0;
   7746       s7_vector_size = s7_SCORE5_PIPELINE;
   7747       break;
   7748     case OPTION_SCORE5U:
   7749       score3 = 0;
   7750       score7 = 1;
   7751       s7_university_version = 1;
   7752       s7_vector_size = s7_SCORE5_PIPELINE;
   7753       break;
   7754     case OPTION_SCORE7:
   7755       score3 = 0;
   7756       score7 = 1;
   7757       s7_score7d = 1;
   7758       s7_university_version = 0;
   7759       s7_vector_size = s7_SCORE7_PIPELINE;
   7760       break;
   7761     case OPTION_SCORE3:
   7762       score3 = 1;
   7763       score7 = 0;
   7764       s3_score3d = 1;
   7765       break;
   7766     case OPTION_R1:
   7767       s3_nor1 = 0;
   7768       s7_nor1 = 0;
   7769       break;
   7770     case 'G':
   7771       s3_g_switch_value = atoi (arg);
   7772       s7_g_switch_value = atoi (arg);
   7773       break;
   7774     case OPTION_O0:
   7775       s3_g_opt = 0;
   7776       s7_g_opt = 0;
   7777       break;
   7778     case OPTION_SCORE_VERSION:
   7779       printf (_("Sunplus-v2-0-0-20060510\n"));
   7780       break;
   7781     case OPTION_PIC:
   7782       s3_score_pic = s3_NO_PIC; /* Score3 doesn't support PIC now.  */
   7783       s7_score_pic = s7_PIC;
   7784       s3_g_switch_value = 0;    /* Must set -G num as 0 to generate s3_PIC code.  */
   7785       s7_g_switch_value = 0;    /* Must set -G num as 0 to generate s7_PIC code.  */
   7786       break;
   7787     case OPTION_MARCH:
   7788       score_set_mach (arg);
   7789       break;
   7790     default:
   7791       return 0;
   7792     }
   7793   return 1;
   7794 }
   7795 
   7796 void
   7797 md_show_usage (FILE * fp)
   7798 {
   7799   fprintf (fp, _(" Score-specific assembler options:\n"));
   7800 #ifdef OPTION_EB
   7801   fprintf (fp, _("\
   7802         -EB\t\tassemble code for a big-endian cpu\n"));
   7803 #endif
   7804 
   7805 #ifdef OPTION_EL
   7806   fprintf (fp, _("\
   7807         -EL\t\tassemble code for a little-endian cpu\n"));
   7808 #endif
   7809 
   7810   fprintf (fp, _("\
   7811         -FIXDD\t\tassemble code for fix data dependency\n"));
   7812   fprintf (fp, _("\
   7813         -NWARN\t\tassemble code for no warning message for fix data dependency\n"));
   7814   fprintf (fp, _("\
   7815         -SCORE5\t\tassemble code for target is SCORE5\n"));
   7816   fprintf (fp, _("\
   7817         -SCORE5U\tassemble code for target is SCORE5U\n"));
   7818   fprintf (fp, _("\
   7819         -SCORE7\t\tassemble code for target is SCORE7, this is default setting\n"));
   7820   fprintf (fp, _("\
   7821         -SCORE3\t\tassemble code for target is SCORE3\n"));
   7822   fprintf (fp, _("\
   7823         -march=score7\tassemble code for target is SCORE7, this is default setting\n"));
   7824   fprintf (fp, _("\
   7825         -march=score3\tassemble code for target is SCORE3\n"));
   7826   fprintf (fp, _("\
   7827         -USE_R1\t\tassemble code for no warning message when using temp register r1\n"));
   7828   fprintf (fp, _("\
   7829         -KPIC\t\tassemble code for PIC\n"));
   7830   fprintf (fp, _("\
   7831         -O0\t\tassembler will not perform any optimizations\n"));
   7832   fprintf (fp, _("\
   7833         -G gpnum\tassemble code for setting gpsize and default is 8 byte\n"));
   7834   fprintf (fp, _("\
   7835         -V \t\tSunplus release version \n"));
   7836 }
   7837