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