xref: /netbsd-src/external/gpl3/binutils/dist/gas/config/tc-score.c (revision 7a6a7ae08ac6c612f0fbb0d4425825c6be2a9050)
1 /* tc-score.c -- Assembler for Score
2    Copyright 2006, 2007 Free Software Foundation, Inc.
3    Contributed by:
4    Mei Ligang (ligang@sunnorth.com.cn)
5    Pei-Lin Tsai (pltsai@sunplus.com)
6 
7    This file is part of GAS, the GNU Assembler.
8 
9    GAS is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 3, or (at your option)
12    any later version.
13 
14    GAS is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18 
19    You should have received a copy of the GNU General Public License
20    along with GAS; see the file COPYING.  If not, write to the Free
21    Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
22    02110-1301, USA.  */
23 
24 #include "as.h"
25 #include "config.h"
26 #include "subsegs.h"
27 #include "safe-ctype.h"
28 #include "opcode/score-inst.h"
29 #include "opcode/score-datadep.h"
30 #include "struc-symbol.h"
31 
32 #ifdef OBJ_ELF
33 #include "elf/score.h"
34 #include "dwarf2dbg.h"
35 #endif
36 
37 #define GP                     28
38 #define PIC_CALL_REG           29
39 #define MAX_LITERAL_POOL_SIZE  1024
40 #define FAIL	               0x80000000
41 #define SUCCESS         0
42 #define INSN_SIZE       4
43 #define INSN16_SIZE     2
44 #define RELAX_INST_NUM  3
45 
46 /* For score5u : div/mul will pop warning message, mmu/alw/asw will pop error message.  */
47 #define BAD_ARGS 	          _("bad arguments to instruction")
48 #define BAD_PC 		          _("r15 not allowed here")
49 #define BAD_COND 	          _("instruction is not conditional")
50 #define ERR_NO_ACCUM	          _("acc0 expected")
51 #define ERR_FOR_SCORE5U_MUL_DIV   _("div / mul are reserved instructions")
52 #define ERR_FOR_SCORE5U_MMU       _("This architecture doesn't support mmu")
53 #define ERR_FOR_SCORE5U_ATOMIC    _("This architecture doesn't support atomic instruction")
54 #define LONG_LABEL_LEN            _("the label length is longer than 1024");
55 #define BAD_SKIP_COMMA            BAD_ARGS
56 #define BAD_GARBAGE               _("garbage following instruction");
57 
58 #define skip_whitespace(str)  while (*(str) == ' ') ++(str)
59 
60 /* The name of the readonly data section.  */
61 #define RDATA_SECTION_NAME (OUTPUT_FLAVOR == bfd_target_aout_flavour \
62 			    ? ".data" \
63 			    : OUTPUT_FLAVOR == bfd_target_ecoff_flavour \
64 			    ? ".rdata" \
65 			    : OUTPUT_FLAVOR == bfd_target_coff_flavour \
66 			    ? ".rdata" \
67 			    : OUTPUT_FLAVOR == bfd_target_elf_flavour \
68 			    ? ".rodata" \
69 			    : (abort (), ""))
70 
71 #define RELAX_ENCODE(old, new, type, reloc1, reloc2, opt) \
72   ((relax_substateT) \
73    (((old) << 23) \
74     | ((new) << 16) \
75     | ((type) << 9) \
76     | ((reloc1) << 5) \
77     | ((reloc2) << 1) \
78     | ((opt) ? 1 : 0)))
79 
80 #define RELAX_OLD(i)       (((i) >> 23) & 0x7f)
81 #define RELAX_NEW(i)       (((i) >> 16) & 0x7f)
82 #define RELAX_TYPE(i)      (((i) >> 9) & 0x7f)
83 #define RELAX_RELOC1(i)    ((valueT) ((i) >> 5) & 0xf)
84 #define RELAX_RELOC2(i)    ((valueT) ((i) >> 1) & 0xf)
85 #define RELAX_OPT(i)       ((i) & 1)
86 #define RELAX_OPT_CLEAR(i) ((i) & ~1)
87 
88 #define SET_INSN_ERROR(s) (inst.error = (s))
89 #define INSN_IS_PCE_P(s)  (strstr (str, "||") != NULL)
90 
91 #define GET_INSN_CLASS(type) (get_insn_class_from_type (type))
92 
93 #define GET_INSN_SIZE(type) ((GET_INSN_CLASS (type) == INSN_CLASS_16) \
94                              ? INSN16_SIZE : INSN_SIZE)
95 
96 /* This array holds the chars that always start a comment.  If the
97    pre-processor is disabled, these aren't very useful.  */
98 const char comment_chars[] = "#";
99 const char line_comment_chars[] = "#";
100 const char line_separator_chars[] = ";";
101 
102 /* Chars that can be used to separate mant from exp in floating point numbers.  */
103 const char EXP_CHARS[] = "eE";
104 const char FLT_CHARS[] = "rRsSfFdDxXeEpP";
105 
106 /* Used to contain constructed error messages.  */
107 static char err_msg[255];
108 
109 fragS *score_fragp = 0;
110 static int fix_data_dependency = 0;
111 static int warn_fix_data_dependency = 1;
112 static int score7 = 1;
113 static int university_version = 0;
114 
115 static int in_my_get_expression = 0;
116 
117 #define USE_GLOBAL_POINTER_OPT 1
118 #define SCORE_BI_ENDIAN
119 
120 /* Default, pop warning message when using r1.  */
121 static int nor1 = 1;
122 
123 /* Default will do instruction relax, -O0 will set g_opt = 0.  */
124 static unsigned int g_opt = 1;
125 
126 /* The size of the small data section.  */
127 static unsigned int g_switch_value = 8;
128 
129 #ifdef OBJ_ELF
130 /* Pre-defined "_GLOBAL_OFFSET_TABLE_"  */
131 symbolS *GOT_symbol;
132 #endif
133 static segT pdr_seg;
134 
135 enum score_pic_level score_pic = NO_PIC;
136 
137 #define INSN_NAME_LEN 16
138 struct score_it
139 {
140   char name[INSN_NAME_LEN];
141   unsigned long instruction;
142   unsigned long relax_inst;
143   int size;
144   int relax_size;
145   enum score_insn_type type;
146   char str[MAX_LITERAL_POOL_SIZE];
147   const char *error;
148   int bwarn;
149   char reg[INSN_NAME_LEN];
150   struct
151   {
152     bfd_reloc_code_real_type type;
153     expressionS exp;
154     int pc_rel;
155   }reloc;
156 };
157 struct score_it inst;
158 
159 typedef struct proc
160 {
161   symbolS *isym;
162   unsigned long reg_mask;
163   unsigned long reg_offset;
164   unsigned long fpreg_mask;
165   unsigned long leaf;
166   unsigned long frame_offset;
167   unsigned long frame_reg;
168   unsigned long pc_reg;
169 }
170 procS;
171 
172 static procS cur_proc;
173 static procS *cur_proc_ptr;
174 static int numprocs;
175 
176 #define SCORE7_PIPELINE 7
177 #define SCORE5_PIPELINE 5
178 static int vector_size = SCORE7_PIPELINE;
179 struct score_it dependency_vector[SCORE7_PIPELINE];
180 
181 /* Relax will need some padding for alignment.  */
182 #define RELAX_PAD_BYTE 3
183 
184 /* Structure for a hash table entry for a register.  */
185 struct reg_entry
186 {
187   const char *name;
188   int number;
189 };
190 
191 static const struct reg_entry score_rn_table[] =
192 {
193   {"r0", 0}, {"r1", 1}, {"r2", 2}, {"r3", 3},
194   {"r4", 4}, {"r5", 5}, {"r6", 6}, {"r7", 7},
195   {"r8", 8}, {"r9", 9}, {"r10", 10}, {"r11", 11},
196   {"r12", 12}, {"r13", 13}, {"r14", 14}, {"r15", 15},
197   {"r16", 16}, {"r17", 17}, {"r18", 18}, {"r19", 19},
198   {"r20", 20}, {"r21", 21}, {"r22", 22}, {"r23", 23},
199   {"r24", 24}, {"r25", 25}, {"r26", 26}, {"r27", 27},
200   {"r28", 28}, {"r29", 29}, {"r30", 30}, {"r31", 31},
201   {NULL, 0}
202 };
203 
204 static const struct reg_entry score_srn_table[] =
205 {
206   {"sr0", 0}, {"sr1", 1}, {"sr2", 2},
207   {NULL, 0}
208 };
209 
210 static const struct reg_entry score_crn_table[] =
211 {
212   {"cr0", 0}, {"cr1", 1}, {"cr2", 2}, {"cr3", 3},
213   {"cr4", 4}, {"cr5", 5}, {"cr6", 6}, {"cr7", 7},
214   {"cr8", 8}, {"cr9", 9}, {"cr10", 10}, {"cr11", 11},
215   {"cr12", 12}, {"cr13", 13}, {"cr14", 14}, {"cr15", 15},
216   {"cr16", 16}, {"cr17", 17}, {"cr18", 18}, {"cr19", 19},
217   {"cr20", 20}, {"cr21", 21}, {"cr22", 22}, {"cr23", 23},
218   {"cr24", 24}, {"cr25", 25}, {"cr26", 26}, {"cr27", 27},
219   {"cr28", 28}, {"cr29", 29}, {"cr30", 30}, {"cr31", 31},
220   {NULL, 0}
221 };
222 
223 struct reg_map
224 {
225   const struct reg_entry *names;
226   int max_regno;
227   struct hash_control *htab;
228   const char *expected;
229 };
230 
231 struct reg_map all_reg_maps[] =
232 {
233   {score_rn_table, 31, NULL, N_("S+core register expected")},
234   {score_srn_table, 2, NULL, N_("S+core special-register expected")},
235   {score_crn_table, 31, NULL, N_("S+core co-processor register expected")},
236 };
237 
238 static struct hash_control *score_ops_hsh = NULL;
239 
240 static struct hash_control *dependency_insn_hsh = NULL;
241 
242 /* Enumeration matching entries in table above.  */
243 enum score_reg_type
244 {
245   REG_TYPE_SCORE = 0,
246 #define REG_TYPE_FIRST REG_TYPE_SCORE
247   REG_TYPE_SCORE_SR = 1,
248   REG_TYPE_SCORE_CR = 2,
249   REG_TYPE_MAX = 3
250 };
251 
252 typedef struct literalS
253 {
254   struct expressionS exp;
255   struct score_it *inst;
256 }
257 literalT;
258 
259 literalT literals[MAX_LITERAL_POOL_SIZE];
260 
261 static void do_ldst_insn (char *);
262 static void do_crdcrscrsimm5 (char *);
263 static void do_ldst_unalign (char *);
264 static void do_ldst_atomic (char *);
265 static void do_ldst_cop (char *);
266 static void do_macro_li_rdi32 (char *);
267 static void do_macro_la_rdi32 (char *);
268 static void do_macro_rdi32hi (char *);
269 static void do_macro_rdi32lo (char *);
270 static void do_macro_mul_rdrsrs (char *);
271 static void do_macro_ldst_label (char *);
272 static void do_branch (char *);
273 static void do_jump (char *);
274 static void do_empty (char *);
275 static void do_rdrsrs (char *);
276 static void do_rdsi16 (char *);
277 static void do_rdrssi14 (char *);
278 static void do_sub_rdsi16 (char *);
279 static void do_sub_rdrssi14 (char *);
280 static void do_rdrsi5 (char *);
281 static void do_rdrsi14 (char *);
282 static void do_rdi16 (char *);
283 static void do_xrsi5 (char *);
284 static void do_rdrs (char *);
285 static void do_rdxrs (char *);
286 static void do_rsrs (char *);
287 static void do_rdcrs (char *);
288 static void do_rdsrs (char *);
289 static void do_rd (char *);
290 static void do_rs (char *);
291 static void do_i15 (char *);
292 static void do_xi5x (char *);
293 static void do_ceinst (char *);
294 static void do_cache (char *);
295 static void do16_rdrs (char *);
296 static void do16_rs (char *);
297 static void do16_xrs (char *);
298 static void do16_mv_rdrs (char *);
299 static void do16_hrdrs (char *);
300 static void do16_rdhrs (char *);
301 static void do16_rdi4 (char *);
302 static void do16_rdi5 (char *);
303 static void do16_xi5 (char *);
304 static void do16_ldst_insn (char *);
305 static void do16_ldst_imm_insn (char *);
306 static void do16_push_pop (char *);
307 static void do16_branch (char *);
308 static void do16_jump (char *);
309 static void do_rdi16_pic (char *);
310 static void do_addi_s_pic (char *);
311 static void do_addi_u_pic (char *);
312 static void do_lw_pic (char *);
313 
314 static const struct asm_opcode score_ldst_insns[] =
315 {
316   {"lw",        0x20000000, 0x3e000000, 0x2008,     Rd_rvalueRs_SI15,     do_ldst_insn},
317   {"lw",        0x06000000, 0x3e000007, 0x8000,     Rd_rvalueRs_preSI12,  do_ldst_insn},
318   {"lw",        0x0e000000, 0x3e000007, 0x200a,     Rd_rvalueRs_postSI12, do_ldst_insn},
319   {"lh",        0x22000000, 0x3e000000, 0x2009,     Rd_rvalueRs_SI15,     do_ldst_insn},
320   {"lh",        0x06000001, 0x3e000007, 0x8000,     Rd_rvalueRs_preSI12,  do_ldst_insn},
321   {"lh",        0x0e000001, 0x3e000007, 0x8000,     Rd_rvalueRs_postSI12, do_ldst_insn},
322   {"lhu",       0x24000000, 0x3e000000, 0x8000,     Rd_rvalueRs_SI15,     do_ldst_insn},
323   {"lhu",       0x06000002, 0x3e000007, 0x8000,     Rd_rvalueRs_preSI12,  do_ldst_insn},
324   {"lhu",       0x0e000002, 0x3e000007, 0x8000,     Rd_rvalueRs_postSI12, do_ldst_insn},
325   {"lb",        0x26000000, 0x3e000000, 0x8000,     Rd_rvalueRs_SI15,     do_ldst_insn},
326   {"lb",        0x06000003, 0x3e000007, 0x8000,     Rd_rvalueRs_preSI12,  do_ldst_insn},
327   {"lb",        0x0e000003, 0x3e000007, 0x8000,     Rd_rvalueRs_postSI12, do_ldst_insn},
328   {"sw",        0x28000000, 0x3e000000, 0x200c,     Rd_lvalueRs_SI15,     do_ldst_insn},
329   {"sw",        0x06000004, 0x3e000007, 0x200e,     Rd_lvalueRs_preSI12,  do_ldst_insn},
330   {"sw",        0x0e000004, 0x3e000007, 0x8000,     Rd_lvalueRs_postSI12, do_ldst_insn},
331   {"sh",        0x2a000000, 0x3e000000, 0x200d,     Rd_lvalueRs_SI15,     do_ldst_insn},
332   {"sh",        0x06000005, 0x3e000007, 0x8000,     Rd_lvalueRs_preSI12,  do_ldst_insn},
333   {"sh",        0x0e000005, 0x3e000007, 0x8000,     Rd_lvalueRs_postSI12, do_ldst_insn},
334   {"lbu",       0x2c000000, 0x3e000000, 0x200b,     Rd_rvalueRs_SI15,     do_ldst_insn},
335   {"lbu",       0x06000006, 0x3e000007, 0x8000,     Rd_rvalueRs_preSI12,  do_ldst_insn},
336   {"lbu",       0x0e000006, 0x3e000007, 0x8000,     Rd_rvalueRs_postSI12, do_ldst_insn},
337   {"sb",        0x2e000000, 0x3e000000, 0x200f,     Rd_lvalueRs_SI15,     do_ldst_insn},
338   {"sb",        0x06000007, 0x3e000007, 0x8000,     Rd_lvalueRs_preSI12,  do_ldst_insn},
339   {"sb",        0x0e000007, 0x3e000007, 0x8000,     Rd_lvalueRs_postSI12, do_ldst_insn},
340 };
341 
342 static const struct asm_opcode score_insns[] =
343 {
344   {"abs",       0x3800000a, 0x3e007fff, 0x8000,     Rd_Rs_x,              do_rdrs},
345   {"abs.s",     0x3800004b, 0x3e007fff, 0x8000,     Rd_Rs_x,              do_rdrs},
346   {"add",       0x00000010, 0x3e0003ff, 0x8000,     Rd_Rs_Rs,             do_rdrsrs},
347   {"add.c",     0x00000011, 0x3e0003ff, 0x2000,     Rd_Rs_Rs,             do_rdrsrs},
348   {"add.s",     0x38000048, 0x3e0003ff, 0x8000,     Rd_Rs_Rs,             do_rdrsrs},
349   {"addc",      0x00000012, 0x3e0003ff, 0x8000,     Rd_Rs_Rs,             do_rdrsrs},
350   {"addc.c",    0x00000013, 0x3e0003ff, 0x0009,     Rd_Rs_Rs,             do_rdrsrs},
351   {"addi",      0x02000000, 0x3e0e0001, 0x8000,     Rd_SI16,              do_rdsi16},
352   {"addi.c",    0x02000001, 0x3e0e0001, 0x8000,     Rd_SI16,              do_rdsi16},
353   {"addis",     0x0a000000, 0x3e0e0001, 0x8000,     Rd_SI16,              do_rdi16},
354   {"addis.c",   0x0a000001, 0x3e0e0001, 0x8000,     Rd_SI16,              do_rdi16},
355   {"addri",     0x10000000, 0x3e000001, 0x8000,     Rd_Rs_SI14,           do_rdrssi14},
356   {"addri.c",   0x10000001, 0x3e000001, 0x8000,     Rd_Rs_SI14,           do_rdrssi14},
357   {"addc!",     0x0009,     0x700f,     0x00000013, Rd_Rs,                do16_rdrs},
358   {"add!",      0x2000,     0x700f,     0x00000011, Rd_Rs,                do16_rdrs},
359   {"addei!",    0x6000    , 0x7087,     0x02000001, Rd_I4,                do16_rdi4},
360   {"subi",      0x02000000, 0x3e0e0001, 0x8000,     Rd_SI16,              do_sub_rdsi16},
361   {"subi.c",    0x02000001, 0x3e0e0001, 0x8000,     Rd_SI16,              do_sub_rdsi16},
362   {"subri",     0x10000000, 0x3e000001, 0x8000,     Rd_Rs_SI14,           do_sub_rdrssi14},
363   {"subri.c",   0x10000001, 0x3e000001, 0x8000,     Rd_Rs_SI14,           do_sub_rdrssi14},
364   {"and",       0x00000020, 0x3e0003ff, 0x8000,     Rd_Rs_Rs,             do_rdrsrs},
365   {"and.c",     0x00000021, 0x3e0003ff, 0x2004,     Rd_Rs_Rs,             do_rdrsrs},
366   {"andi",      0x02080000, 0x3e0e0001, 0x8000,     Rd_I16,               do_rdi16},
367   {"andi.c",    0x02080001, 0x3e0e0001, 0x8000,     Rd_I16,               do_rdi16},
368   {"andis",     0x0a080000, 0x3e0e0001, 0x8000,     Rd_I16,               do_rdi16},
369   {"andis.c",   0x0a080001, 0x3e0e0001, 0x8000,     Rd_I16,               do_rdi16},
370   {"andri",     0x18000000, 0x3e000001, 0x8000,     Rd_Rs_I14,            do_rdrsi14},
371   {"andri.c",   0x18000001, 0x3e000001, 0x8000,     Rd_Rs_I14,            do_rdrsi14},
372   {"and!",      0x2004,     0x700f,     0x00000021, Rd_Rs,                do16_rdrs},
373   {"bcs",       0x08000000, 0x3e007c01, 0x4000,     PC_DISP19div2,        do_branch},
374   {"bcc",       0x08000400, 0x3e007c01, 0x4000,     PC_DISP19div2,        do_branch},
375   {"bcnz",      0x08003800, 0x3e007c01, 0x4000,     PC_DISP19div2,        do_branch},
376   {"bcsl",      0x08000001, 0x3e007c01, 0x8000,     PC_DISP19div2,        do_branch},
377   {"bccl",      0x08000401, 0x3e007c01, 0x8000,     PC_DISP19div2,        do_branch},
378   {"bcnzl",     0x08003801, 0x3e007c01, 0x8000,     PC_DISP19div2,        do_branch},
379   {"bcs!",      0x4000,     0x7f00,     0x08000000, PC_DISP8div2,         do16_branch},
380   {"bcc!",      0x4100,     0x7f00,     0x08000400, PC_DISP8div2,         do16_branch},
381   {"bcnz!",     0x4e00,     0x7f00,     0x08003800, PC_DISP8div2,         do16_branch},
382   {"beq",       0x08001000, 0x3e007c01, 0x4000,     PC_DISP19div2,        do_branch},
383   {"beql",      0x08001001, 0x3e007c01, 0x8000,     PC_DISP19div2,        do_branch},
384   {"beq!",      0x4400,     0x7f00,     0x08001000, PC_DISP8div2,         do16_branch},
385   {"bgtu",      0x08000800, 0x3e007c01, 0x4000,     PC_DISP19div2,        do_branch},
386   {"bgt",       0x08001800, 0x3e007c01, 0x4000,     PC_DISP19div2,        do_branch},
387   {"bge",       0x08002000, 0x3e007c01, 0x4000,     PC_DISP19div2,        do_branch},
388   {"bgtul",     0x08000801, 0x3e007c01, 0x8000,     PC_DISP19div2,        do_branch},
389   {"bgtl",      0x08001801, 0x3e007c01, 0x8000,     PC_DISP19div2,        do_branch},
390   {"bgel",      0x08002001, 0x3e007c01, 0x8000,     PC_DISP19div2,        do_branch},
391   {"bgtu!",     0x4200,     0x7f00,     0x08000800, PC_DISP8div2,         do16_branch},
392   {"bgt!",      0x4600,     0x7f00,     0x08001800, PC_DISP8div2,         do16_branch},
393   {"bge!",      0x4800,     0x7f00,     0x08002000, PC_DISP8div2,         do16_branch},
394   {"bitclr.c",  0x00000029, 0x3e0003ff, 0x6004,     Rd_Rs_I5,             do_rdrsi5},
395   {"bitrev",    0x3800000c, 0x3e0003ff, 0x8000,     Rd_Rs_Rs,             do_rdrsrs},
396   {"bitset.c",  0x0000002b, 0x3e0003ff, 0x6005,     Rd_Rs_I5,             do_rdrsi5},
397   {"bittst.c",  0x0000002d, 0x3e0003ff, 0x6006,     x_Rs_I5,              do_xrsi5},
398   {"bittgl.c",  0x0000002f, 0x3e0003ff, 0x6007,     Rd_Rs_I5,             do_rdrsi5},
399   {"bitclr!",   0x6004,     0x7007,     0x00000029, Rd_I5,                do16_rdi5},
400   {"bitset!",   0x6005,     0x7007,     0x0000002b, Rd_I5,                do16_rdi5},
401   {"bittst!",   0x6006,     0x7007,     0x0000002d, Rd_I5,                do16_rdi5},
402   {"bittgl!",   0x6007,     0x7007,     0x0000002f, Rd_I5,                do16_rdi5},
403   {"bleu",      0x08000c00, 0x3e007c01, 0x4000,     PC_DISP19div2,        do_branch},
404   {"ble",       0x08001c00, 0x3e007c01, 0x4000,     PC_DISP19div2,        do_branch},
405   {"blt",       0x08002400, 0x3e007c01, 0x4000,     PC_DISP19div2,        do_branch},
406   {"bleul",     0x08000c01, 0x3e007c01, 0x8000,     PC_DISP19div2,        do_branch},
407   {"blel",      0x08001c01, 0x3e007c01, 0x8000,     PC_DISP19div2,        do_branch},
408   {"bltl",      0x08002401, 0x3e007c01, 0x8000,     PC_DISP19div2,        do_branch},
409   {"bl",        0x08003c01, 0x3e007c01, 0x8000,     PC_DISP19div2,        do_branch},
410   {"bleu!",     0x4300,     0x7f00,     0x08000c00, PC_DISP8div2,         do16_branch},
411   {"ble!",      0x4700,     0x7f00,     0x08001c00, PC_DISP8div2,         do16_branch},
412   {"blt!",      0x4900,     0x7f00,     0x08002400, PC_DISP8div2,         do16_branch},
413   {"bmi",       0x08002800, 0x3e007c01, 0x4000,     PC_DISP19div2,        do_branch},
414   {"bmil",      0x08002801, 0x3e007c01, 0x8000,     PC_DISP19div2,        do_branch},
415   {"bmi!",      0x00004a00, 0x00007f00, 0x08002800, PC_DISP8div2,         do16_branch},
416   {"bne",       0x08001400, 0x3e007c01, 0x4000,     PC_DISP19div2,        do_branch},
417   {"bnel",      0x08001401, 0x3e007c01, 0x8000,     PC_DISP19div2,        do_branch},
418   {"bne!",      0x4500,     0x7f00,     0x08001400, PC_DISP8div2,         do16_branch},
419   {"bpl",       0x08002c00, 0x3e007c01, 0x4000,     PC_DISP19div2,        do_branch},
420   {"bpll",      0x08002c01, 0x3e007c01, 0x8000,     PC_DISP19div2,        do_branch},
421   {"bpl!",      0x4b00,     0x7f00,     0x08002c00, PC_DISP8div2,         do16_branch},
422   {"brcs",      0x00000008, 0x3e007fff, 0x0004,     x_Rs_x,               do_rs},
423   {"brcc",      0x00000408, 0x3e007fff, 0x0104,     x_Rs_x,               do_rs},
424   {"brgtu",     0x00000808, 0x3e007fff, 0x0204,     x_Rs_x,               do_rs},
425   {"brleu",     0x00000c08, 0x3e007fff, 0x0304,     x_Rs_x,               do_rs},
426   {"breq",      0x00001008, 0x3e007fff, 0x0404,     x_Rs_x,               do_rs},
427   {"brne",      0x00001408, 0x3e007fff, 0x0504,     x_Rs_x,               do_rs},
428   {"brgt",      0x00001808, 0x3e007fff, 0x0604,     x_Rs_x,               do_rs},
429   {"brle",      0x00001c08, 0x3e007fff, 0x0704,     x_Rs_x,               do_rs},
430   {"brge",      0x00002008, 0x3e007fff, 0x0804,     x_Rs_x,               do_rs},
431   {"brlt",      0x00002408, 0x3e007fff, 0x0904,     x_Rs_x,               do_rs},
432   {"brmi",      0x00002808, 0x3e007fff, 0x0a04,     x_Rs_x,               do_rs},
433   {"brpl",      0x00002c08, 0x3e007fff, 0x0b04,     x_Rs_x,               do_rs},
434   {"brvs",      0x00003008, 0x3e007fff, 0x0c04,     x_Rs_x,               do_rs},
435   {"brvc",      0x00003408, 0x3e007fff, 0x0d04,     x_Rs_x,               do_rs},
436   {"brcnz",     0x00003808, 0x3e007fff, 0x0e04,     x_Rs_x,               do_rs},
437   {"br",        0x00003c08, 0x3e007fff, 0x0f04,     x_Rs_x,               do_rs},
438   {"brcsl",     0x00000009, 0x3e007fff, 0x000c,     x_Rs_x,               do_rs},
439   {"brccl",     0x00000409, 0x3e007fff, 0x010c,     x_Rs_x,               do_rs},
440   {"brgtul",    0x00000809, 0x3e007fff, 0x020c,     x_Rs_x,               do_rs},
441   {"brleul",    0x00000c09, 0x3e007fff, 0x030c,     x_Rs_x,               do_rs},
442   {"breql",     0x00001009, 0x3e007fff, 0x040c,     x_Rs_x,               do_rs},
443   {"brnel",     0x00001409, 0x3e007fff, 0x050c,     x_Rs_x,               do_rs},
444   {"brgtl",     0x00001809, 0x3e007fff, 0x060c,     x_Rs_x,               do_rs},
445   {"brlel",     0x00001c09, 0x3e007fff, 0x070c,     x_Rs_x,               do_rs},
446   {"brgel",     0x00002009, 0x3e007fff, 0x080c,     x_Rs_x,               do_rs},
447   {"brltl",     0x00002409, 0x3e007fff, 0x090c,     x_Rs_x,               do_rs},
448   {"brmil",     0x00002809, 0x3e007fff, 0x0a0c,     x_Rs_x,               do_rs},
449   {"brpll",     0x00002c09, 0x3e007fff, 0x0b0c,     x_Rs_x,               do_rs},
450   {"brvsl",     0x00003009, 0x3e007fff, 0x0c0c,     x_Rs_x,               do_rs},
451   {"brvcl",     0x00003409, 0x3e007fff, 0x0d0c,     x_Rs_x,               do_rs},
452   {"brcnzl",    0x00003809, 0x3e007fff, 0x0e0c,     x_Rs_x,               do_rs},
453   {"brl",       0x00003c09, 0x3e007fff, 0x0f0c,     x_Rs_x,               do_rs},
454   {"brcs!",     0x0004,     0x7f0f,     0x00000008, x_Rs,                 do16_xrs},
455   {"brcc!",     0x0104,     0x7f0f,     0x00000408, x_Rs,                 do16_xrs},
456   {"brgtu!",    0x0204,     0x7f0f,     0x00000808, x_Rs,                 do16_xrs},
457   {"brleu!",    0x0304,     0x7f0f,     0x00000c08, x_Rs,                 do16_xrs},
458   {"breq!",     0x0404,     0x7f0f,     0x00001008, x_Rs,                 do16_xrs},
459   {"brne!",     0x0504,     0x7f0f,     0x00001408, x_Rs,                 do16_xrs},
460   {"brgt!",     0x0604,     0x7f0f,     0x00001808, x_Rs,                 do16_xrs},
461   {"brle!",     0x0704,     0x7f0f,     0x00001c08, x_Rs,                 do16_xrs},
462   {"brge!",     0x0804,     0x7f0f,     0x00002008, x_Rs,                 do16_xrs},
463   {"brlt!",     0x0904,     0x7f0f,     0x00002408, x_Rs,                 do16_xrs},
464   {"brmi!",     0x0a04,     0x7f0f,     0x00002808, x_Rs,                 do16_xrs},
465   {"brpl!",     0x0b04,     0x7f0f,     0x00002c08, x_Rs,                 do16_xrs},
466   {"brvs!",     0x0c04,     0x7f0f,     0x00003008, x_Rs,                 do16_xrs},
467   {"brvc!",     0x0d04,     0x7f0f,     0x00003408, x_Rs,                 do16_xrs},
468   {"brcnz!",    0x0e04,     0x7f0f,     0x00003808, x_Rs,                 do16_xrs},
469   {"br!",       0x0f04,     0x7f0f,     0x00003c08, x_Rs,                 do16_xrs},
470   {"brcsl!",    0x000c,     0x7f0f,     0x00000009, x_Rs,                 do16_xrs},
471   {"brccl!",    0x010c,     0x7f0f,     0x00000409, x_Rs,                 do16_xrs},
472   {"brgtul!",   0x020c,     0x7f0f,     0x00000809, x_Rs,                 do16_xrs},
473   {"brleul!",   0x030c,     0x7f0f,     0x00000c09, x_Rs,                 do16_xrs},
474   {"breql!",    0x040c,     0x7f0f,     0x00001009, x_Rs,                 do16_xrs},
475   {"brnel!",    0x050c,     0x7f0f,     0x00001409, x_Rs,                 do16_xrs},
476   {"brgtl!",    0x060c,     0x7f0f,     0x00001809, x_Rs,                 do16_xrs},
477   {"brlel!",    0x070c,     0x7f0f,     0x00001c09, x_Rs,                 do16_xrs},
478   {"brgel!",    0x080c,     0x7f0f,     0x00002009, x_Rs,                 do16_xrs},
479   {"brltl!",    0x090c,     0x7f0f,     0x00002409, x_Rs,                 do16_xrs},
480   {"brmil!",    0x0a0c,     0x7f0f,     0x00002809, x_Rs,                 do16_xrs},
481   {"brpll!",    0x0b0c,     0x7f0f,     0x00002c09, x_Rs,                 do16_xrs},
482   {"brvsl!",    0x0c0c,     0x7f0f,     0x00003009, x_Rs,                 do16_xrs},
483   {"brvcl!",    0x0d0c,     0x7f0f,     0x00003409, x_Rs,                 do16_xrs},
484   {"brcnzl!",   0x0e0c,     0x7f0f,     0x00003809, x_Rs,                 do16_xrs},
485   {"brl!",      0x0f0c,     0x7f0f,     0x00003c09, x_Rs,                 do16_xrs},
486   {"bvs",       0x08003000, 0x3e007c01, 0x4000,     PC_DISP19div2,        do_branch},
487   {"bvc",       0x08003400, 0x3e007c01, 0x4000,     PC_DISP19div2,        do_branch},
488   {"bvsl",      0x08003001, 0x3e007c01, 0x8000,     PC_DISP19div2,        do_branch},
489   {"bvcl",      0x08003401, 0x3e007c01, 0x8000,     PC_DISP19div2,        do_branch},
490   {"bvs!",      0x4c00,     0x7f00,     0x08003000, PC_DISP8div2,         do16_branch},
491   {"bvc!",      0x4d00,     0x7f00,     0x08003400, PC_DISP8div2,         do16_branch},
492   {"b!",        0x4f00,     0x7f00,     0x08003c00, PC_DISP8div2,         do16_branch},
493   {"b",         0x08003c00, 0x3e007c01, 0x4000,     PC_DISP19div2,        do_branch},
494   {"cache",     0x30000000, 0x3ff00000, 0x8000,     OP5_rvalueRs_SI15,    do_cache},
495   {"ceinst",    0x38000000, 0x3e000000, 0x8000,     I5_Rs_Rs_I5_OP5,      do_ceinst},
496   {"clz",       0x3800000d, 0x3e007fff, 0x8000,     Rd_Rs_x,              do_rdrs},
497   {"cmpteq.c",  0x00000019, 0x3ff003ff, 0x8000,     x_Rs_Rs,              do_rsrs},
498   {"cmptmi.c",  0x00100019, 0x3ff003ff, 0x8000,     x_Rs_Rs,              do_rsrs},
499   {"cmp.c",     0x00300019, 0x3ff003ff, 0x2003,     x_Rs_Rs,              do_rsrs},
500   {"cmpzteq.c", 0x0000001b, 0x3ff07fff, 0x8000,     x_Rs_x,               do_rs},
501   {"cmpztmi.c", 0x0010001b, 0x3ff07fff, 0x8000,     x_Rs_x,               do_rs},
502   {"cmpz.c",    0x0030001b, 0x3ff07fff, 0x8000,     x_Rs_x,               do_rs},
503   {"cmpi.c",    0x02040001, 0x3e0e0001, 0x8000,     Rd_SI16,              do_rdsi16},
504   {"cmp!",      0x2003,     0x700f,     0x00300019, Rd_Rs,                do16_rdrs},
505   {"cop1",      0x0c00000c, 0x3e00001f, 0x8000,     Rd_Rs_Rs_imm,         do_crdcrscrsimm5},
506   {"cop2",      0x0c000014, 0x3e00001f, 0x8000,     Rd_Rs_Rs_imm,         do_crdcrscrsimm5},
507   {"cop3",      0x0c00001c, 0x3e00001f, 0x8000,     Rd_Rs_Rs_imm,         do_crdcrscrsimm5},
508   {"drte",      0x0c0000a4, 0x3e0003ff, 0x8000,     NO_OPD,               do_empty},
509   {"extsb",     0x00000058, 0x3e0003ff, 0x8000,     Rd_Rs_x,              do_rdrs},
510   {"extsb.c",   0x00000059, 0x3e0003ff, 0x8000,     Rd_Rs_x,              do_rdrs},
511   {"extsh",     0x0000005a, 0x3e0003ff, 0x8000,     Rd_Rs_x,              do_rdrs},
512   {"extsh.c",   0x0000005b, 0x3e0003ff, 0x8000,     Rd_Rs_x,              do_rdrs},
513   {"extzb",     0x0000005c, 0x3e0003ff, 0x8000,     Rd_Rs_x,              do_rdrs},
514   {"extzb.c",   0x0000005d, 0x3e0003ff, 0x8000,     Rd_Rs_x,              do_rdrs},
515   {"extzh",     0x0000005e, 0x3e0003ff, 0x8000,     Rd_Rs_x,              do_rdrs},
516   {"extzh.c",   0x0000005f, 0x3e0003ff, 0x8000,     Rd_Rs_x,              do_rdrs},
517   {"jl",        0x04000001, 0x3e000001, 0x8000,     PC_DISP24div2,        do_jump},
518   {"jl!",       0x3001,     0x7001,     0x04000001, PC_DISP11div2,        do16_jump},
519   {"j!",        0x3000,     0x7001,     0x04000000, PC_DISP11div2,        do16_jump},
520   {"j",         0x04000000, 0x3e000001, 0x8000,     PC_DISP24div2,        do_jump},
521   {"lbu!",      0x200b,     0x0000700f, 0x2c000000, Rd_rvalueRs,          do16_ldst_insn},
522   {"lbup!",     0x7003,     0x7007,     0x2c000000, Rd_rvalueBP_I5,       do16_ldst_imm_insn},
523   {"alw",       0x0000000c, 0x3e0003ff, 0x8000,     Rd_rvalue32Rs,        do_ldst_atomic},
524   {"lcb",       0x00000060, 0x3e0003ff, 0x8000,     x_rvalueRs_post4,     do_ldst_unalign},
525   {"lcw",       0x00000062, 0x3e0003ff, 0x8000,     Rd_rvalueRs_post4,    do_ldst_unalign},
526   {"lce",       0x00000066, 0x3e0003ff, 0x8000,     Rd_rvalueRs_post4,    do_ldst_unalign},
527   {"ldc1",      0x0c00000a, 0x3e00001f, 0x8000,     Rd_rvalueRs_SI10,     do_ldst_cop},
528   {"ldc2",      0x0c000012, 0x3e00001f, 0x8000,     Rd_rvalueRs_SI10,     do_ldst_cop},
529   {"ldc3",      0x0c00001a, 0x3e00001f, 0x8000,     Rd_rvalueRs_SI10,     do_ldst_cop},
530   {"lh!",       0x2009,     0x700f,     0x22000000, Rd_rvalueRs,          do16_ldst_insn},
531   {"lhp!",      0x7001,     0x7007,     0x22000000, Rd_rvalueBP_I5,       do16_ldst_imm_insn},
532   {"ldi",       0x020c0000, 0x3e0e0000, 0x5000,     Rd_SI16,              do_rdsi16},
533   {"ldis",      0x0a0c0000, 0x3e0e0000, 0x8000,     Rd_I16,               do_rdi16},
534   {"ldiu!",     0x5000,     0x7000,     0x020c0000, Rd_I8,                do16_ldst_imm_insn},
535   {"lw!",       0x2008,     0x700f,     0x20000000, Rd_rvalueRs,          do16_ldst_insn},
536   {"lwp!",      0x7000,     0x7007,     0x20000000, Rd_rvalueBP_I5,       do16_ldst_imm_insn},
537   {"mfcel",     0x00000448, 0x3e007fff, 0x8000,     Rd_x_x,               do_rd},
538   {"mfcel!",    0x1001,     0x7f0f,     0x00000448, x_Rs,                 do16_rs},
539   {"mad",       0x38000000, 0x3ff003ff, 0x8000,     x_Rs_Rs,              do_rsrs},
540   {"mad.f!",    0x1004,     0x700f,     0x38000080, Rd_Rs,                do16_rdrs},
541   {"madh",      0x38000203, 0x3ff003ff, 0x8000,     x_Rs_Rs,              do_rsrs},
542   {"madh.fs",   0x380002c3, 0x3ff003ff, 0x8000,     x_Rs_Rs,              do_rsrs},
543   {"madh.fs!",  0x100b,     0x700f,     0x380002c3, Rd_Rs,                do16_rdrs},
544   {"madl",      0x38000002, 0x3ff003ff, 0x8000,     x_Rs_Rs,              do_rsrs},
545   {"madl.fs",   0x380000c2, 0x3ff003ff, 0x8000,     x_Rs_Rs,              do_rsrs},
546   {"madl.fs!",  0x100a,     0x700f,     0x380000c2, Rd_Rs,                do16_rdrs},
547   {"madu",      0x38000020, 0x3ff003ff, 0x8000,     x_Rs_Rs,              do_rsrs},
548   {"madu!",     0x1005,     0x700f,     0x38000020, Rd_Rs,                do16_rdrs},
549   {"mad.f",     0x38000080, 0x3ff003ff, 0x8000,     x_Rs_Rs,              do_rsrs},
550   {"max",       0x38000007, 0x3e0003ff, 0x8000,     Rd_Rs_Rs,             do_rdrsrs},
551   {"mazh",      0x38000303, 0x3ff003ff, 0x8000,     x_Rs_Rs,              do_rsrs},
552   {"mazh.f",    0x38000383, 0x3ff003ff, 0x8000,     x_Rs_Rs,              do_rsrs},
553   {"mazh.f!",   0x1009,     0x700f,     0x3800038c, Rd_Rs,                do16_rdrs},
554   {"mazl",      0x38000102, 0x3ff003ff, 0x8000,     x_Rs_Rs,              do_rsrs},
555   {"mazl.f",    0x38000182, 0x3ff003ff, 0x8000,     x_Rs_Rs,              do_rsrs},
556   {"mazl.f!",   0x1008,     0x700f,     0x38000182, Rd_Rs,                do16_rdrs},
557   {"mfceh",     0x00000848, 0x3e007fff, 0x8000,     Rd_x_x,               do_rd},
558   {"mfceh!",    0x1101,     0x7f0f,     0x00000848, x_Rs,                 do16_rs},
559   {"mfcehl",    0x00000c48, 0x3e007fff, 0x8000,     Rd_Rs_x,              do_rdrs},
560   {"mfsr",      0x00000050, 0x3e0003ff, 0x8000,     Rd_x_I5,              do_rdsrs},
561   {"mfcr",      0x0c000001, 0x3e00001f, 0x8000,     Rd_Rs_x,              do_rdcrs},
562   {"mfc1",      0x0c000009, 0x3e00001f, 0x8000,     Rd_Rs_x,              do_rdcrs},
563   {"mfc2",      0x0c000011, 0x3e00001f, 0x8000,     Rd_Rs_x,              do_rdcrs},
564   {"mfc3",      0x0c000019, 0x3e00001f, 0x8000,     Rd_Rs_x,              do_rdcrs},
565   {"mfcc1",     0x0c00000f, 0x3e00001f, 0x8000,     Rd_Rs_x,              do_rdcrs},
566   {"mfcc2",     0x0c000017, 0x3e00001f, 0x8000,     Rd_Rs_x,              do_rdcrs},
567   {"mfcc3",     0x0c00001f, 0x3e00001f, 0x8000,     Rd_Rs_x,              do_rdcrs},
568   {"mhfl!",     0x0002,     0x700f,     0x00003c56, Rd_LowRs,             do16_hrdrs},
569   {"min",       0x38000006, 0x3e0003ff, 0x8000,     Rd_Rs_Rs,             do_rdrsrs},
570   {"mlfh!",     0x0001,     0x700f,     0x00003c56, Rd_HighRs,            do16_rdhrs},
571   {"msb",       0x38000001, 0x3ff003ff, 0x8000,     x_Rs_Rs,              do_rsrs},
572   {"msb.f!",    0x1006,     0x700f,     0x38000081, Rd_Rs,                do16_rdrs},
573   {"msbh",      0x38000205, 0x3ff003ff, 0x8000,     x_Rs_Rs,              do_rsrs},
574   {"msbh.fs",   0x380002c5, 0x3ff003ff, 0x8000,     x_Rs_Rs,              do_rsrs},
575   {"msbh.fs!",  0x100f,     0x700f,     0x380002c5, Rd_Rs,                do16_rdrs},
576   {"msbl",      0x38000004, 0x3ff003ff, 0x8000,     x_Rs_Rs,              do_rsrs},
577   {"msbl.fs",   0x380000c4, 0x3ff003ff, 0x8000,     x_Rs_Rs,              do_rsrs},
578   {"msbl.fs!",  0x100e,     0x700f,     0x380000c4, Rd_Rs,                do16_rdrs},
579   {"msbu",      0x38000021, 0x3ff003ff, 0x8000,     x_Rs_Rs,              do_rsrs},
580   {"msbu!",     0x1007,     0x700f,     0x38000021, Rd_Rs,                do16_rdrs},
581   {"msb.f",     0x38000081, 0x3ff003ff, 0x8000,     x_Rs_Rs,              do_rsrs},
582   {"mszh",      0x38000305, 0x3ff003ff, 0x8000,     x_Rs_Rs,              do_rsrs},
583   {"mszh.f",    0x38000385, 0x3ff003ff, 0x8000,     x_Rs_Rs,              do_rsrs},
584   {"mszh.f!",   0x100d,     0x700f,     0x38000385, Rd_Rs,                do16_rdrs},
585   {"mszl",      0x38000104, 0x3ff003ff, 0x8000,     x_Rs_Rs,              do_rsrs},
586   {"mszl.f",    0x38000184, 0x3ff003ff, 0x8000,     x_Rs_Rs,              do_rsrs},
587   {"mszl.f!",   0x100c,     0x700f,     0x38000184, Rd_Rs,                do16_rdrs},
588   {"mtcel!",    0x1000,     0x7f0f,     0x0000044a, x_Rs,                 do16_rs},
589   {"mtcel",     0x0000044a, 0x3e007fff, 0x8000,     Rd_x_x,               do_rd},
590   {"mtceh",     0x0000084a, 0x3e007fff, 0x8000,     Rd_x_x,               do_rd},
591   {"mtceh!",    0x1100,     0x7f0f,     0x0000084a, x_Rs,                 do16_rs},
592   {"mtcehl",    0x00000c4a, 0x3e007fff, 0x8000,     Rd_Rs_x,              do_rdrs},
593   {"mtsr",      0x00000052, 0x3e0003ff, 0x8000,     x_Rs_I5,              do_rdsrs},
594   {"mtcr",      0x0c000000, 0x3e00001f, 0x8000,     Rd_Rs_x,              do_rdcrs},
595   {"mtc1",      0x0c000008, 0x3e00001f, 0x8000,     Rd_Rs_x,              do_rdcrs},
596   {"mtc2",      0x0c000010, 0x3e00001f, 0x8000,     Rd_Rs_x,              do_rdcrs},
597   {"mtc3",      0x0c000018, 0x3e00001f, 0x8000,     Rd_Rs_x,              do_rdcrs},
598   {"mtcc1",     0x0c00000e, 0x3e00001f, 0x8000,     Rd_Rs_x,              do_rdcrs},
599   {"mtcc2",     0x0c000016, 0x3e00001f, 0x8000,     Rd_Rs_x,              do_rdcrs},
600   {"mtcc3",     0x0c00001e, 0x3e00001f, 0x8000,     Rd_Rs_x,              do_rdcrs},
601   {"mul.f!",    0x1002,     0x700f,     0x00000041, Rd_Rs,                do16_rdrs},
602   {"mulu!",     0x1003,     0x700f,     0x00000042, Rd_Rs,                do16_rdrs},
603   {"mvcs",      0x00000056, 0x3e007fff, 0x8000,     Rd_Rs_x,              do_rdrs},
604   {"mvcc",      0x00000456, 0x3e007fff, 0x8000,     Rd_Rs_x,              do_rdrs},
605   {"mvgtu",     0x00000856, 0x3e007fff, 0x8000,     Rd_Rs_x,              do_rdrs},
606   {"mvleu",     0x00000c56, 0x3e007fff, 0x8000,     Rd_Rs_x,              do_rdrs},
607   {"mveq",      0x00001056, 0x3e007fff, 0x8000,     Rd_Rs_x,              do_rdrs},
608   {"mvne",      0x00001456, 0x3e007fff, 0x8000,     Rd_Rs_x,              do_rdrs},
609   {"mvgt",      0x00001856, 0x3e007fff, 0x8000,     Rd_Rs_x,              do_rdrs},
610   {"mvle",      0x00001c56, 0x3e007fff, 0x8000,     Rd_Rs_x,              do_rdrs},
611   {"mvge",      0x00002056, 0x3e007fff, 0x8000,     Rd_Rs_x,              do_rdrs},
612   {"mvlt",      0x00002456, 0x3e007fff, 0x8000,     Rd_Rs_x,              do_rdrs},
613   {"mvmi",      0x00002856, 0x3e007fff, 0x8000,     Rd_Rs_x,              do_rdrs},
614   {"mvpl",      0x00002c56, 0x3e007fff, 0x8000,     Rd_Rs_x,              do_rdrs},
615   {"mvvs",      0x00003056, 0x3e007fff, 0x8000,     Rd_Rs_x,              do_rdrs},
616   {"mvvc",      0x00003456, 0x3e007fff, 0x8000,     Rd_Rs_x,              do_rdrs},
617   {"mv",        0x00003c56, 0x3e007fff, 0x0003,     Rd_Rs_x,              do_rdrs},
618   {"mv!",       0x0003,     0x700f,     0x00003c56, Rd_Rs,                do16_mv_rdrs},
619   {"neg",       0x0000001e, 0x3e0003ff, 0x8000,     Rd_x_Rs,              do_rdxrs},
620   {"neg.c",     0x0000001f, 0x3e0003ff, 0x2002,     Rd_x_Rs,              do_rdxrs},
621   {"neg!",      0x2002,     0x700f,     0x0000001f, Rd_Rs,                do16_rdrs},
622   {"nop",       0x00000000, 0x3e0003ff, 0x0000,     NO_OPD,               do_empty},
623   {"not",       0x00000024, 0x3e0003ff, 0x8000,     Rd_Rs_x,              do_rdrs},
624   {"not.c",     0x00000025, 0x3e0003ff, 0x2006,     Rd_Rs_x,              do_rdrs},
625   {"nop!",      0x0000,     0x700f,     0x00000000, NO16_OPD,               do_empty},
626   {"not!",      0x2006,     0x700f,     0x00000025, Rd_Rs,                do16_rdrs},
627   {"or",        0x00000022, 0x3e0003ff, 0x8000,     Rd_Rs_Rs,             do_rdrsrs},
628   {"or.c",      0x00000023, 0x3e0003ff, 0x2005,     Rd_Rs_Rs,             do_rdrsrs},
629   {"ori",       0x020a0000, 0x3e0e0001, 0x8000,     Rd_I16,               do_rdi16},
630   {"ori.c",     0x020a0001, 0x3e0e0001, 0x8000,     Rd_I16,               do_rdi16},
631   {"oris",      0x0a0a0000, 0x3e0e0001, 0x8000,     Rd_I16,               do_rdi16},
632   {"oris.c",    0x0a0a0001, 0x3e0e0001, 0x8000,     Rd_I16,               do_rdi16},
633   {"orri",      0x1a000000, 0x3e000001, 0x8000,     Rd_Rs_I14,            do_rdrsi14},
634   {"orri.c",    0x1a000001, 0x3e000001, 0x8000,     Rd_Rs_I14,            do_rdrsi14},
635   {"or!",       0x2005,     0x700f,     0x00000023, Rd_Rs,                do16_rdrs},
636   {"pflush",    0x0000000a, 0x3e0003ff, 0x8000,     NO_OPD,               do_empty},
637   {"pop!",      0x200a,     0x700f,     0x0e000000, Rd_rvalueRs,          do16_push_pop},
638   {"push!",     0x200e,     0x700f,     0x06000004, Rd_lvalueRs,          do16_push_pop},
639   {"ror",       0x00000038, 0x3e0003ff, 0x8000,     Rd_Rs_Rs,             do_rdrsrs},
640   {"ror.c",     0x00000039, 0x3e0003ff, 0x8000,     Rd_Rs_Rs,             do_rdrsrs},
641   {"rorc.c",    0x0000003b, 0x3e0003ff, 0x8000,     Rd_Rs_Rs,             do_rdrsrs},
642   {"rol",       0x0000003c, 0x3e0003ff, 0x8000,     Rd_Rs_Rs,             do_rdrsrs},
643   {"rol.c",     0x0000003d, 0x3e0003ff, 0x8000,     Rd_Rs_Rs,             do_rdrsrs},
644   {"rolc.c",    0x0000003f, 0x3e0003ff, 0x8000,     Rd_Rs_Rs,             do_rdrsrs},
645   {"rori",      0x00000078, 0x3e0003ff, 0x8000,     Rd_Rs_I5,             do_rdrsi5},
646   {"rori.c",    0x00000079, 0x3e0003ff, 0x8000,     Rd_Rs_I5,             do_rdrsi5},
647   {"roric.c",   0x0000007b, 0x3e0003ff, 0x8000,     Rd_Rs_I5,             do_rdrsi5},
648   {"roli",      0x0000007c, 0x3e0003ff, 0x8000,     Rd_Rs_I5,             do_rdrsi5},
649   {"roli.c",    0x0000007d, 0x3e0003ff, 0x8000,     Rd_Rs_I5,             do_rdrsi5},
650   {"rolic.c",   0x0000007f, 0x3e0003ff, 0x8000,     Rd_Rs_I5,             do_rdrsi5},
651   {"rte",       0x0c000084, 0x3e0003ff, 0x8000,     NO_OPD,               do_empty},
652   {"sb!",       0x200f,     0x700f,     0x2e000000, Rd_lvalueRs,          do16_ldst_insn},
653   {"sbp!",      0x7007,     0x7007,     0x2e000000, Rd_lvalueBP_I5,       do16_ldst_imm_insn},
654   {"asw",       0x0000000e, 0x3e0003ff, 0x8000,     Rd_lvalue32Rs,        do_ldst_atomic},
655   {"scb",       0x00000068, 0x3e0003ff, 0x8000,     Rd_lvalueRs_post4,    do_ldst_unalign},
656   {"scw",       0x0000006a, 0x3e0003ff, 0x8000,     Rd_lvalueRs_post4,    do_ldst_unalign},
657   {"sce",       0x0000006e, 0x3e0003ff, 0x8000,     x_lvalueRs_post4,     do_ldst_unalign},
658   {"sdbbp",     0x00000006, 0x3e0003ff, 0x6002,     x_I5_x,               do_xi5x},
659   {"sdbbp!",    0x6002,     0x7007,     0x00000006, Rd_I5,                do16_xi5},
660   {"sh!",       0x200d,     0x700f,     0x2a000000, Rd_lvalueRs,          do16_ldst_insn},
661   {"shp!",      0x7005,     0x7007,     0x2a000000, Rd_lvalueBP_I5,       do16_ldst_imm_insn},
662   {"sleep",     0x0c0000c4, 0x3e0003ff, 0x8000,     NO_OPD,               do_empty},
663   {"sll",       0x00000030, 0x3e0003ff, 0x8000,     Rd_Rs_Rs,             do_rdrsrs},
664   {"sll.c",     0x00000031, 0x3e0003ff, 0x0008,     Rd_Rs_Rs,             do_rdrsrs},
665   {"sll.s",     0x3800004e, 0x3e0003ff, 0x8000,     Rd_Rs_Rs,             do_rdrsrs},
666   {"slli",      0x00000070, 0x3e0003ff, 0x8000,     Rd_Rs_I5,             do_rdrsi5},
667   {"slli.c",    0x00000071, 0x3e0003ff, 0x6001,     Rd_Rs_I5,             do_rdrsi5},
668   {"sll!",      0x0008,     0x700f,     0x00000031, Rd_Rs,                do16_rdrs},
669   {"slli!",     0x6001,     0x7007,     0x00000071, Rd_I5,                do16_rdi5},
670   {"srl",       0x00000034, 0x3e0003ff, 0x8000,     Rd_Rs_Rs,             do_rdrsrs},
671   {"srl.c",     0x00000035, 0x3e0003ff, 0x000a,     Rd_Rs_Rs,             do_rdrsrs},
672   {"sra",       0x00000036, 0x3e0003ff, 0x8000,     Rd_Rs_Rs,             do_rdrsrs},
673   {"sra.c",     0x00000037, 0x3e0003ff, 0x000b,     Rd_Rs_Rs,             do_rdrsrs},
674   {"srli",      0x00000074, 0x3e0003ff, 0x8000,     Rd_Rs_I5,             do_rdrsi5},
675   {"srli.c",    0x00000075, 0x3e0003ff, 0x6003,     Rd_Rs_I5,             do_rdrsi5},
676   {"srai",      0x00000076, 0x3e0003ff, 0x8000,     Rd_Rs_I5,             do_rdrsi5},
677   {"srai.c",    0x00000077, 0x3e0003ff, 0x8000,     Rd_Rs_I5,             do_rdrsi5},
678   {"srl!",      0x000a,     0x700f,     0x00000035, Rd_Rs,                do16_rdrs},
679   {"sra!",      0x000b,     0x700f,     0x00000037, Rd_Rs,                do16_rdrs},
680   {"srli!",     0x6003,     0x7007,     0x00000075, Rd_Rs,                do16_rdi5},
681   {"stc1",      0x0c00000b, 0x3e00001f, 0x8000,     Rd_lvalueRs_SI10,     do_ldst_cop},
682   {"stc2",      0x0c000013, 0x3e00001f, 0x8000,     Rd_lvalueRs_SI10,     do_ldst_cop},
683   {"stc3",      0x0c00001b, 0x3e00001f, 0x8000,     Rd_lvalueRs_SI10,     do_ldst_cop},
684   {"sub",       0x00000014, 0x3e0003ff, 0x8000,     Rd_Rs_Rs,             do_rdrsrs},
685   {"sub.c",     0x00000015, 0x3e0003ff, 0x2001,     Rd_Rs_Rs,             do_rdrsrs},
686   {"sub.s",     0x38000049, 0x3e0003ff, 0x8000,     Rd_Rs_Rs,             do_rdrsrs},
687   {"subc",      0x00000016, 0x3e0003ff, 0x8000,     Rd_Rs_Rs,             do_rdrsrs},
688   {"subc.c",    0x00000017, 0x3e0003ff, 0x8000,     Rd_Rs_Rs,             do_rdrsrs},
689   {"sub!",      0x2001,     0x700f,     0x00000015, Rd_Rs,                do16_rdrs},
690   {"subei!",    0x6080,     0x7087,     0x02000001, Rd_I4,                do16_rdi4},
691   {"sw!",       0x200c,     0x700f,     0x28000000, Rd_lvalueRs,          do16_ldst_insn},
692   {"swp!",      0x7004,     0x7007,     0x28000000, Rd_lvalueBP_I5,       do16_ldst_imm_insn},
693   {"syscall",   0x00000002, 0x3e0003ff, 0x8000,     I15,                  do_i15},
694   {"tcs",       0x00000054, 0x3e007fff, 0x0005,     NO_OPD,               do_empty},
695   {"tcc",       0x00000454, 0x3e007fff, 0x0105,     NO_OPD,               do_empty},
696   {"tcnz",      0x00003854, 0x3e007fff, 0x0e05,     NO_OPD,               do_empty},
697   {"tcs!",      0x0005,     0x7f0f,     0x00000054, NO16_OPD,             do_empty},
698   {"tcc!",      0x0105,     0x7f0f,     0x00000454, NO16_OPD,             do_empty},
699   {"tcnz!",     0x0e05,     0x7f0f,     0x00003854, NO16_OPD,             do_empty},
700   {"teq",       0x00001054, 0x3e007fff, 0x0405,     NO_OPD,               do_empty},
701   {"teq!",      0x0405,     0x7f0f,     0x00001054, NO16_OPD,             do_empty},
702   {"tgtu",      0x00000854, 0x3e007fff, 0x0205,     NO_OPD,               do_empty},
703   {"tgt",       0x00001854, 0x3e007fff, 0x0605,     NO_OPD,               do_empty},
704   {"tge",       0x00002054, 0x3e007fff, 0x0805,     NO_OPD,               do_empty},
705   {"tgtu!",     0x0205,     0x7f0f,     0x00000854, NO16_OPD,             do_empty},
706   {"tgt!",      0x0605,     0x7f0f,     0x00001854, NO16_OPD,             do_empty},
707   {"tge!",      0x0805,     0x7f0f,     0x00002054, NO16_OPD,             do_empty},
708   {"tleu",      0x00000c54, 0x3e007fff, 0x0305,     NO_OPD,               do_empty},
709   {"tle",       0x00001c54, 0x3e007fff, 0x0705,     NO_OPD,               do_empty},
710   {"tlt",       0x00002454, 0x3e007fff, 0x0905,     NO_OPD,               do_empty},
711   {"stlb",      0x0c000004, 0x3e0003ff, 0x8000,     NO_OPD,               do_empty},
712   {"mftlb",     0x0c000024, 0x3e0003ff, 0x8000,     NO_OPD,               do_empty},
713   {"mtptlb",    0x0c000044, 0x3e0003ff, 0x8000,     NO_OPD,               do_empty},
714   {"mtrtlb",    0x0c000064, 0x3e0003ff, 0x8000,     NO_OPD,               do_empty},
715   {"tleu!",     0x0305,     0x7f0f,     0x00000c54, NO16_OPD,             do_empty},
716   {"tle!",      0x0705,     0x7f0f,     0x00001c54, NO16_OPD,             do_empty},
717   {"tlt!",      0x0905,     0x7f0f,     0x00002454, NO16_OPD,             do_empty},
718   {"tmi",       0x00002854, 0x3e007fff, 0x0a05,     NO_OPD,               do_empty},
719   {"tmi!",      0x0a05,     0x7f0f,     0x00002854, NO16_OPD,             do_empty},
720   {"tne",       0x00001454, 0x3e007fff, 0x0505,     NO_OPD,               do_empty},
721   {"tne!",      0x0505,     0x7f0f,     0x00001454, NO16_OPD,             do_empty},
722   {"tpl",       0x00002c54, 0x3e007fff, 0x0b05,     NO_OPD,               do_empty},
723   {"tpl!",      0x0b05,     0x7f0f,     0x00002c54, NO16_OPD,             do_empty},
724   {"trapcs",    0x00000004, 0x3e007fff, 0x8000,     x_I5_x,               do_xi5x},
725   {"trapcc",    0x00000404, 0x3e007fff, 0x8000,     x_I5_x,               do_xi5x},
726   {"trapgtu",   0x00000804, 0x3e007fff, 0x8000,     x_I5_x,               do_xi5x},
727   {"trapleu",   0x00000c04, 0x3e007fff, 0x8000,     x_I5_x,               do_xi5x},
728   {"trapeq",    0x00001004, 0x3e007fff, 0x8000,     x_I5_x,               do_xi5x},
729   {"trapne",    0x00001404, 0x3e007fff, 0x8000,     x_I5_x,               do_xi5x},
730   {"trapgt",    0x00001804, 0x3e007fff, 0x8000,     x_I5_x,               do_xi5x},
731   {"traple",    0x00001c04, 0x3e007fff, 0x8000,     x_I5_x,               do_xi5x},
732   {"trapge",    0x00002004, 0x3e007fff, 0x8000,     x_I5_x,               do_xi5x},
733   {"traplt",    0x00002404, 0x3e007fff, 0x8000,     x_I5_x,               do_xi5x},
734   {"trapmi",    0x00002804, 0x3e007fff, 0x8000,     x_I5_x,               do_xi5x},
735   {"trappl",    0x00002c04, 0x3e007fff, 0x8000,     x_I5_x,               do_xi5x},
736   {"trapvs",    0x00003004, 0x3e007fff, 0x8000,     x_I5_x,               do_xi5x},
737   {"trapvc",    0x00003404, 0x3e007fff, 0x8000,     x_I5_x,               do_xi5x},
738   {"trap",      0x00003c04, 0x3e007fff, 0x8000,     x_I5_x,               do_xi5x},
739   {"tset",      0x00003c54, 0x3e007fff, 0x0f05,     NO_OPD,               do_empty},
740   {"tset!",     0x0f05,     0x00007f0f, 0x00003c54, NO16_OPD,             do_empty},
741   {"tvs",       0x00003054, 0x3e007fff, 0x0c05,     NO_OPD,               do_empty},
742   {"tvc",       0x00003454, 0x3e007fff, 0x0d05,     NO_OPD,               do_empty},
743   {"tvs!",      0x0c05,     0x7f0f,     0x00003054, NO16_OPD,             do_empty},
744   {"tvc!",      0x0d05,     0x7f0f,     0x00003454, NO16_OPD,             do_empty},
745   {"xor",       0x00000026, 0x3e0003ff, 0x8000,     Rd_Rs_Rs,             do_rdrsrs},
746   {"xor.c",     0x00000027, 0x3e0003ff, 0x2007,     Rd_Rs_Rs,             do_rdrsrs},
747   {"xor!",      0x2007,     0x700f,     0x00000027, Rd_Rs,                do16_rdrs},
748   /* Macro instruction.  */
749   {"li",        0x020c0000, 0x3e0e0000, 0x8000,     Insn_Type_SYN,        do_macro_li_rdi32},
750   /* la reg, imm32        -->(1)  ldi  reg, simm16
751                              (2)  ldis reg, %HI(imm32)
752                                   ori  reg, %LO(imm32)
753 
754      la reg, symbol       -->(1)  lis  reg, %HI(imm32)
755                                   ori  reg, %LO(imm32)  */
756   {"la",        0x020c0000, 0x3e0e0000, 0x8000,     Insn_Type_SYN,        do_macro_la_rdi32},
757   {"div",       0x00000044, 0x3e0003ff, 0x8000,     Insn_Type_SYN,        do_macro_mul_rdrsrs},
758   {"divu",      0x00000046, 0x3e0003ff, 0x8000,     Insn_Type_SYN,        do_macro_mul_rdrsrs},
759   {"rem",       0x00000044, 0x3e0003ff, 0x8000,     Insn_Type_SYN,        do_macro_mul_rdrsrs},
760   {"remu",      0x00000046, 0x3e0003ff, 0x8000,     Insn_Type_SYN,        do_macro_mul_rdrsrs},
761   {"mul",       0x00000040, 0x3e0003ff, 0x8000,     Insn_Type_SYN,        do_macro_mul_rdrsrs},
762   {"mulu",      0x00000042, 0x3e0003ff, 0x8000,     Insn_Type_SYN,        do_macro_mul_rdrsrs},
763   {"maz",       0x00000040, 0x3e0003ff, 0x8000,     Insn_Type_SYN,        do_macro_mul_rdrsrs},
764   {"mazu",      0x00000042, 0x3e0003ff, 0x8000,     Insn_Type_SYN,        do_macro_mul_rdrsrs},
765   {"mul.f",     0x00000041, 0x3e0003ff, 0x8000,     Insn_Type_SYN,        do_macro_mul_rdrsrs},
766   {"maz.f",     0x00000041, 0x3e0003ff, 0x8000,     Insn_Type_SYN,        do_macro_mul_rdrsrs},
767   {"lb",        INSN_LB,    0x00000000, 0x8000,     Insn_Type_SYN,        do_macro_ldst_label},
768   {"lbu",       INSN_LBU,   0x00000000, 0x200b,     Insn_Type_SYN,        do_macro_ldst_label},
769   {"lh",        INSN_LH,    0x00000000, 0x2009,     Insn_Type_SYN,        do_macro_ldst_label},
770   {"lhu",       INSN_LHU,   0x00000000, 0x8000,     Insn_Type_SYN,        do_macro_ldst_label},
771   {"lw",        INSN_LW,    0x00000000, 0x2008,     Insn_Type_SYN,        do_macro_ldst_label},
772   {"sb",        INSN_SB,    0x00000000, 0x200f,     Insn_Type_SYN,        do_macro_ldst_label},
773   {"sh",        INSN_SH,    0x00000000, 0x200d,     Insn_Type_SYN,        do_macro_ldst_label},
774   {"sw",        INSN_SW,    0x00000000, 0x200c,     Insn_Type_SYN,        do_macro_ldst_label},
775   /* Assembler use internal.  */
776   {"ld_i32hi",  0x0a0c0000, 0x3e0e0000, 0x8000,     Insn_internal, do_macro_rdi32hi},
777   {"ld_i32lo",  0x020a0000, 0x3e0e0001, 0x8000,     Insn_internal, do_macro_rdi32lo},
778   {"ldis_pic",  0x0a0c0000, 0x3e0e0000, 0x5000,     Insn_internal, do_rdi16_pic},
779   {"addi_s_pic",0x02000000, 0x3e0e0001, 0x8000,     Insn_internal, do_addi_s_pic},
780   {"addi_u_pic",0x02000000, 0x3e0e0001, 0x8000,     Insn_internal, do_addi_u_pic},
781   {"lw_pic",    0x20000000, 0x3e000000, 0x8000,     Insn_internal, do_lw_pic},
782 };
783 
784 /* Next free entry in the pool.  */
785 int next_literal_pool_place = 0;
786 
787 /* Next literal pool number.  */
788 int lit_pool_num = 1;
789 symbolS *current_poolP = NULL;
790 
791 
792 static int
793 end_of_line (char *str)
794 {
795   int retval = SUCCESS;
796 
797   skip_whitespace (str);
798   if (*str != '\0')
799     {
800       retval = (int) FAIL;
801 
802       if (!inst.error)
803         inst.error = BAD_GARBAGE;
804     }
805 
806   return retval;
807 }
808 
809 static int
810 score_reg_parse (char **ccp, struct hash_control *htab)
811 {
812   char *start = *ccp;
813   char c;
814   char *p;
815   struct reg_entry *reg;
816 
817   p = start;
818   if (!ISALPHA (*p) || !is_name_beginner (*p))
819     return (int) FAIL;
820 
821   c = *p++;
822 
823   while (ISALPHA (c) || ISDIGIT (c) || c == '_')
824     c = *p++;
825 
826   *--p = 0;
827   reg = (struct reg_entry *) hash_find (htab, start);
828   *p = c;
829 
830   if (reg)
831     {
832       *ccp = p;
833       return reg->number;
834     }
835   return (int) FAIL;
836 }
837 
838 /* If shift <= 0, only return reg.  */
839 
840 static int
841 reg_required_here (char **str, int shift, enum score_reg_type reg_type)
842 {
843   static char buff[MAX_LITERAL_POOL_SIZE];
844   int reg = (int) FAIL;
845   char *start = *str;
846 
847   if ((reg = score_reg_parse (str, all_reg_maps[reg_type].htab)) != (int) FAIL)
848     {
849       if (reg_type == REG_TYPE_SCORE)
850         {
851           if ((reg == 1) && (nor1 == 1) && (inst.bwarn == 0))
852             {
853               as_warn (_("Using temp register(r1)"));
854               inst.bwarn = 1;
855             }
856         }
857       if (shift >= 0)
858 	{
859           if (reg_type == REG_TYPE_SCORE_CR)
860 	    strcpy (inst.reg, score_crn_table[reg].name);
861           else if (reg_type == REG_TYPE_SCORE_SR)
862 	    strcpy (inst.reg, score_srn_table[reg].name);
863           else
864 	    strcpy (inst.reg, "");
865 
866           inst.instruction |= reg << shift;
867 	}
868     }
869   else
870     {
871       *str = start;
872       sprintf (buff, _("register expected, not '%.100s'"), start);
873       inst.error = buff;
874     }
875 
876   return reg;
877 }
878 
879 static int
880 skip_past_comma (char **str)
881 {
882   char *p = *str;
883   char c;
884   int comma = 0;
885 
886   while ((c = *p) == ' ' || c == ',')
887     {
888       p++;
889       if (c == ',' && comma++)
890         {
891           inst.error = BAD_SKIP_COMMA;
892           return (int) FAIL;
893         }
894     }
895 
896   if ((c == '\0') || (comma == 0))
897     {
898       inst.error = BAD_SKIP_COMMA;
899       return (int) FAIL;
900     }
901 
902   *str = p;
903   return comma ? SUCCESS : (int) FAIL;
904 }
905 
906 static void
907 do_rdrsrs (char *str)
908 {
909   skip_whitespace (str);
910 
911   if (reg_required_here (&str, 20, REG_TYPE_SCORE) == (int) FAIL
912       || skip_past_comma (&str) == (int) FAIL
913       || reg_required_here (&str, 15, REG_TYPE_SCORE) == (int) FAIL
914       || skip_past_comma (&str) == (int) FAIL
915       || reg_required_here (&str, 10, REG_TYPE_SCORE) == (int) FAIL
916       || end_of_line (str) == (int) FAIL)
917     {
918       return;
919     }
920   else
921     {
922       if ((((inst.instruction >> 15) & 0x10) == 0)
923           && (((inst.instruction >> 10) & 0x10) == 0)
924           && (((inst.instruction >> 20) & 0x10) == 0)
925           && (inst.relax_inst != 0x8000)
926           && (((inst.instruction >> 20) & 0xf) == ((inst.instruction >> 15) & 0xf)))
927         {
928           inst.relax_inst |= (((inst.instruction >> 10) & 0xf) << 4)
929             | (((inst.instruction >> 15) & 0xf) << 8);
930           inst.relax_size = 2;
931         }
932       else
933         {
934           inst.relax_inst = 0x8000;
935         }
936     }
937 }
938 
939 static int
940 walk_no_bignums (symbolS * sp)
941 {
942   if (symbol_get_value_expression (sp)->X_op == O_big)
943     return 1;
944 
945   if (symbol_get_value_expression (sp)->X_add_symbol)
946     return (walk_no_bignums (symbol_get_value_expression (sp)->X_add_symbol)
947 	    || (symbol_get_value_expression (sp)->X_op_symbol
948 		&& walk_no_bignums (symbol_get_value_expression (sp)->X_op_symbol)));
949 
950   return 0;
951 }
952 
953 static int
954 my_get_expression (expressionS * ep, char **str)
955 {
956   char *save_in;
957   segT seg;
958 
959   save_in = input_line_pointer;
960   input_line_pointer = *str;
961   in_my_get_expression = 1;
962   seg = expression (ep);
963   in_my_get_expression = 0;
964 
965   if (ep->X_op == O_illegal)
966     {
967       *str = input_line_pointer;
968       input_line_pointer = save_in;
969       inst.error = _("illegal expression");
970       return (int) FAIL;
971     }
972   /* Get rid of any bignums now, so that we don't generate an error for which
973      we can't establish a line number later on.  Big numbers are never valid
974      in instructions, which is where this routine is always called.  */
975   if (ep->X_op == O_big
976       || (ep->X_add_symbol
977           && (walk_no_bignums (ep->X_add_symbol)
978               || (ep->X_op_symbol && walk_no_bignums (ep->X_op_symbol)))))
979     {
980       inst.error = _("invalid constant");
981       *str = input_line_pointer;
982       input_line_pointer = save_in;
983       return (int) FAIL;
984     }
985 
986   if ((ep->X_add_symbol != NULL)
987       && (inst.type != PC_DISP19div2)
988       && (inst.type != PC_DISP8div2)
989       && (inst.type != PC_DISP24div2)
990       && (inst.type != PC_DISP11div2)
991       && (inst.type != Insn_Type_SYN)
992       && (inst.type != Rd_rvalueRs_SI15)
993       && (inst.type != Rd_lvalueRs_SI15)
994       && (inst.type != Insn_internal))
995     {
996       inst.error = BAD_ARGS;
997       *str = input_line_pointer;
998       input_line_pointer = save_in;
999       return (int) FAIL;
1000     }
1001 
1002   *str = input_line_pointer;
1003   input_line_pointer = save_in;
1004   return SUCCESS;
1005 }
1006 
1007 /* Check if an immediate is valid.  If so, convert it to the right format.  */
1008 
1009 static int
1010 validate_immediate (int val, unsigned int data_type, int hex_p)
1011 {
1012   switch (data_type)
1013     {
1014     case _VALUE_HI16:
1015       {
1016         int val_hi = ((val & 0xffff0000) >> 16);
1017 
1018         if (score_df_range[data_type].range[0] <= val_hi
1019             && val_hi <= score_df_range[data_type].range[1])
1020 	  return val_hi;
1021       }
1022       break;
1023 
1024     case _VALUE_LO16:
1025       {
1026         int val_lo = (val & 0xffff);
1027 
1028         if (score_df_range[data_type].range[0] <= val_lo
1029             && val_lo <= score_df_range[data_type].range[1])
1030 	  return val_lo;
1031       }
1032       break;
1033 
1034     case _VALUE:
1035       return val;
1036       break;
1037 
1038     case _SIMM14:
1039       if (hex_p == 1)
1040         {
1041           if (!(val >= -0x2000 && val <= 0x3fff))
1042             {
1043               return (int) FAIL;
1044             }
1045         }
1046       else
1047         {
1048           if (!(val >= -8192 && val <= 8191))
1049             {
1050               return (int) FAIL;
1051             }
1052         }
1053 
1054       return val;
1055       break;
1056 
1057     case _SIMM16_NEG:
1058       if (hex_p == 1)
1059         {
1060           if (!(val >= -0x7fff && val <= 0xffff && val != 0x8000))
1061             {
1062               return (int) FAIL;
1063             }
1064         }
1065       else
1066         {
1067           if (!(val >= -32767 && val <= 32768))
1068             {
1069               return (int) FAIL;
1070             }
1071         }
1072 
1073       val = -val;
1074       return val;
1075       break;
1076 
1077     default:
1078       if (data_type == _SIMM14_NEG || data_type == _IMM16_NEG)
1079 	val = -val;
1080 
1081       if (score_df_range[data_type].range[0] <= val
1082           && val <= score_df_range[data_type].range[1])
1083 	return val;
1084 
1085       break;
1086     }
1087 
1088   return (int) FAIL;
1089 }
1090 
1091 static int
1092 data_op2 (char **str, int shift, enum score_data_type data_type)
1093 {
1094   int value;
1095   char data_exp[MAX_LITERAL_POOL_SIZE];
1096   char *dataptr;
1097   int cnt = 0;
1098   char *pp = NULL;
1099 
1100   skip_whitespace (*str);
1101   inst.error = NULL;
1102   dataptr = * str;
1103 
1104   /* Set hex_p to zero.  */
1105   int hex_p = 0;
1106 
1107   while ((*dataptr != '\0') && (*dataptr != '|') && (cnt <= MAX_LITERAL_POOL_SIZE))     /* 0x7c = ='|' */
1108     {
1109       data_exp[cnt] = *dataptr;
1110       dataptr++;
1111       cnt++;
1112     }
1113 
1114   data_exp[cnt] = '\0';
1115   pp = (char *)&data_exp;
1116 
1117   if (*dataptr == '|')          /* process PCE */
1118     {
1119       if (my_get_expression (&inst.reloc.exp, &pp) == (int) FAIL)
1120         return (int) FAIL;
1121       end_of_line (pp);
1122       if (inst.error != 0)
1123         return (int) FAIL;       /* to ouptut_inst to printf out the error */
1124       *str = dataptr;
1125     }
1126   else                          /* process  16 bit */
1127     {
1128       if (my_get_expression (&inst.reloc.exp, str) == (int) FAIL)
1129         {
1130           return (int) FAIL;
1131         }
1132 
1133       dataptr = (char *)data_exp;
1134       for (; *dataptr != '\0'; dataptr++)
1135         {
1136           *dataptr = TOLOWER (*dataptr);
1137           if (*dataptr == '!' || *dataptr == ' ')
1138             break;
1139         }
1140       dataptr = (char *)data_exp;
1141 
1142       if ((dataptr != NULL)
1143           && (((strstr (dataptr, "0x")) != NULL)
1144               || ((strstr (dataptr, "0X")) != NULL)))
1145         {
1146           hex_p = 1;
1147           if ((data_type != _SIMM16_LA)
1148               && (data_type != _VALUE_HI16)
1149               && (data_type != _VALUE_LO16)
1150               && (data_type != _IMM16)
1151               && (data_type != _IMM15)
1152               && (data_type != _IMM14)
1153               && (data_type != _IMM4)
1154               && (data_type != _IMM5)
1155               && (data_type != _IMM8)
1156               && (data_type != _IMM5_RSHIFT_1)
1157               && (data_type != _IMM5_RSHIFT_2)
1158               && (data_type != _SIMM14)
1159               && (data_type != _SIMM14_NEG)
1160               && (data_type != _SIMM16_NEG)
1161               && (data_type != _IMM10_RSHIFT_2)
1162               && (data_type != _GP_IMM15))
1163             {
1164               data_type += 24;
1165             }
1166         }
1167 
1168       if ((inst.reloc.exp.X_add_number == 0)
1169           && (inst.type != Insn_Type_SYN)
1170           && (inst.type != Rd_rvalueRs_SI15)
1171           && (inst.type != Rd_lvalueRs_SI15)
1172           && (inst.type != Insn_internal)
1173           && (((*dataptr >= 'a') && (*dataptr <= 'z'))
1174              || ((*dataptr == '0') && (*(dataptr + 1) == 'x') && (*(dataptr + 2) != '0'))
1175              || ((*dataptr == '+') && (*(dataptr + 1) != '0'))
1176              || ((*dataptr == '-') && (*(dataptr + 1) != '0'))))
1177         {
1178           inst.error = BAD_ARGS;
1179           return (int) FAIL;
1180         }
1181     }
1182 
1183   if ((inst.reloc.exp.X_add_symbol)
1184       && ((data_type == _SIMM16)
1185           || (data_type == _SIMM16_NEG)
1186           || (data_type == _IMM16_NEG)
1187           || (data_type == _SIMM14)
1188           || (data_type == _SIMM14_NEG)
1189           || (data_type == _IMM5)
1190           || (data_type == _IMM14)
1191           || (data_type == _IMM20)
1192           || (data_type == _IMM16)
1193           || (data_type == _IMM15)
1194           || (data_type == _IMM4)))
1195     {
1196       inst.error = BAD_ARGS;
1197       return (int) FAIL;
1198     }
1199 
1200   if (inst.reloc.exp.X_add_symbol)
1201     {
1202       switch (data_type)
1203         {
1204         case _SIMM16_LA:
1205           return (int) FAIL;
1206         case _VALUE_HI16:
1207           inst.reloc.type = BFD_RELOC_HI16_S;
1208           inst.reloc.pc_rel = 0;
1209           break;
1210         case _VALUE_LO16:
1211           inst.reloc.type = BFD_RELOC_LO16;
1212           inst.reloc.pc_rel = 0;
1213           break;
1214         case _GP_IMM15:
1215           inst.reloc.type = BFD_RELOC_SCORE_GPREL15;
1216           inst.reloc.pc_rel = 0;
1217           break;
1218         case _SIMM16_pic:
1219         case _IMM16_LO16_pic:
1220           inst.reloc.type = BFD_RELOC_SCORE_GOT_LO16;
1221           inst.reloc.pc_rel = 0;
1222           break;
1223         default:
1224           inst.reloc.type = BFD_RELOC_32;
1225           inst.reloc.pc_rel = 0;
1226           break;
1227         }
1228     }
1229   else
1230     {
1231       if (data_type == _IMM16_pic)
1232 	{
1233           inst.reloc.type = BFD_RELOC_SCORE_DUMMY_HI16;
1234           inst.reloc.pc_rel = 0;
1235 	}
1236 
1237       if (data_type == _SIMM16_LA && inst.reloc.exp.X_unsigned == 1)
1238         {
1239           value = validate_immediate (inst.reloc.exp.X_add_number, _SIMM16_LA_POS, hex_p);
1240           if (value == (int) FAIL)       /* for advance to check if this is ldis */
1241             if ((inst.reloc.exp.X_add_number & 0xffff) == 0)
1242               {
1243                 inst.instruction |= 0x8000000;
1244                 inst.instruction |= ((inst.reloc.exp.X_add_number >> 16) << 1) & 0x1fffe;
1245                 return SUCCESS;
1246               }
1247         }
1248       else
1249         {
1250           value = validate_immediate (inst.reloc.exp.X_add_number, data_type, hex_p);
1251         }
1252 
1253       if (value == (int) FAIL)
1254         {
1255           if ((data_type != _SIMM14_NEG) && (data_type != _SIMM16_NEG) && (data_type != _IMM16_NEG))
1256             {
1257               sprintf (err_msg,
1258                        _("invalid constant: %d bit expression not in range %d..%d"),
1259                        score_df_range[data_type].bits,
1260                        score_df_range[data_type].range[0], score_df_range[data_type].range[1]);
1261             }
1262           else
1263             {
1264               sprintf (err_msg,
1265                        _("invalid constant: %d bit expression not in range %d..%d"),
1266                        score_df_range[data_type].bits,
1267                        -score_df_range[data_type].range[1], -score_df_range[data_type].range[0]);
1268             }
1269 
1270           inst.error = err_msg;
1271           return (int) FAIL;
1272         }
1273 
1274       if ((score_df_range[data_type].range[0] != 0) || (data_type == _IMM5_RANGE_8_31))
1275         {
1276           value &= (1 << score_df_range[data_type].bits) - 1;
1277         }
1278 
1279       inst.instruction |= value << shift;
1280     }
1281 
1282   if ((inst.instruction & 0xf0000000) == 0x30000000)
1283     {
1284       if ((((inst.instruction >> 20) & 0x1F) != 0)
1285           && (((inst.instruction >> 20) & 0x1F) != 1)
1286           && (((inst.instruction >> 20) & 0x1F) != 2)
1287           && (((inst.instruction >> 20) & 0x1F) != 3)
1288           && (((inst.instruction >> 20) & 0x1F) != 4)
1289           && (((inst.instruction >> 20) & 0x1F) != 8)
1290           && (((inst.instruction >> 20) & 0x1F) != 9)
1291           && (((inst.instruction >> 20) & 0x1F) != 0xa)
1292           && (((inst.instruction >> 20) & 0x1F) != 0xb)
1293           && (((inst.instruction >> 20) & 0x1F) != 0xc)
1294           && (((inst.instruction >> 20) & 0x1F) != 0xd)
1295           && (((inst.instruction >> 20) & 0x1F) != 0xe)
1296           && (((inst.instruction >> 20) & 0x1F) != 0x10)
1297           && (((inst.instruction >> 20) & 0x1F) != 0x11)
1298           && (((inst.instruction >> 20) & 0x1F) != 0x18)
1299           && (((inst.instruction >> 20) & 0x1F) != 0x1A)
1300           && (((inst.instruction >> 20) & 0x1F) != 0x1B)
1301           && (((inst.instruction >> 20) & 0x1F) != 0x1d)
1302           && (((inst.instruction >> 20) & 0x1F) != 0x1e)
1303           && (((inst.instruction >> 20) & 0x1F) != 0x1f))
1304         {
1305           inst.error = _("invalid constant: bit expression not defined");
1306           return (int) FAIL;
1307         }
1308     }
1309 
1310   return SUCCESS;
1311 }
1312 
1313 /* Handle addi/addi.c/addis.c/cmpi.c/addis.c/ldi.  */
1314 
1315 static void
1316 do_rdsi16 (char *str)
1317 {
1318   skip_whitespace (str);
1319 
1320   if (reg_required_here (&str, 20, REG_TYPE_SCORE) == (int) FAIL
1321       || skip_past_comma (&str) == (int) FAIL
1322       || data_op2 (&str, 1, _SIMM16) == (int) FAIL
1323       || end_of_line (str) == (int) FAIL)
1324     return;
1325 
1326   /* ldi.  */
1327   if ((inst.instruction & 0x20c0000) == 0x20c0000)
1328     {
1329       if ((((inst.instruction >> 20) & 0x10) == 0x10) || ((inst.instruction & 0x1fe00) != 0))
1330         {
1331           inst.relax_inst = 0x8000;
1332         }
1333       else
1334         {
1335           inst.relax_inst |= (inst.instruction >> 1) & 0xff;
1336           inst.relax_inst |= (((inst.instruction >> 20) & 0xf) << 8);
1337           inst.relax_size = 2;
1338         }
1339     }
1340   else if (((inst.instruction >> 20) & 0x10) == 0x10)
1341     {
1342       inst.relax_inst = 0x8000;
1343     }
1344 }
1345 
1346 /* Handle subi/subi.c.  */
1347 
1348 static void
1349 do_sub_rdsi16 (char *str)
1350 {
1351   skip_whitespace (str);
1352 
1353   if (reg_required_here (&str, 20, REG_TYPE_SCORE) != (int) FAIL
1354       && skip_past_comma (&str) != (int) FAIL
1355       && data_op2 (&str, 1, _SIMM16_NEG) != (int) FAIL)
1356     end_of_line (str);
1357 }
1358 
1359 /* Handle addri/addri.c.  */
1360 
1361 static void
1362 do_rdrssi14 (char *str)         /* -(2^13)~((2^13)-1) */
1363 {
1364   skip_whitespace (str);
1365 
1366   if (reg_required_here (&str, 20, REG_TYPE_SCORE) != (int) FAIL
1367       && skip_past_comma (&str) != (int) FAIL
1368       && reg_required_here (&str, 15, REG_TYPE_SCORE) != (int) FAIL
1369       && skip_past_comma (&str) != (int) FAIL)
1370     data_op2 (&str, 1, _SIMM14);
1371 }
1372 
1373 /* Handle subri.c/subri.  */
1374 static void
1375 do_sub_rdrssi14 (char *str)     /* -(2^13)~((2^13)-1) */
1376 {
1377   skip_whitespace (str);
1378 
1379   if (reg_required_here (&str, 20, REG_TYPE_SCORE) != (int) FAIL
1380       && skip_past_comma (&str) != (int) FAIL
1381       && reg_required_here (&str, 15, REG_TYPE_SCORE) != (int) FAIL
1382       && skip_past_comma (&str) != (int) FAIL
1383       && data_op2 (&str, 1, _SIMM14_NEG) != (int) FAIL)
1384     end_of_line (str);
1385 }
1386 
1387 /* Handle bitclr.c/bitset.c/bittgl.c/slli.c/srai.c/srli.c/roli.c/rori.c/rolic.c.  */
1388 static void
1389 do_rdrsi5 (char *str)           /* 0~((2^14)-1) */
1390 {
1391   skip_whitespace (str);
1392 
1393   if (reg_required_here (&str, 20, REG_TYPE_SCORE) == (int) FAIL
1394       || skip_past_comma (&str) == (int) FAIL
1395       || reg_required_here (&str, 15, REG_TYPE_SCORE) == (int) FAIL
1396       || skip_past_comma (&str) == (int) FAIL
1397       || data_op2 (&str, 10, _IMM5) == (int) FAIL
1398       || end_of_line (str) == (int) FAIL)
1399     return;
1400 
1401   if ((((inst.instruction >> 20) & 0x1f) == ((inst.instruction >> 15) & 0x1f))
1402       && (inst.relax_inst != 0x8000) && (((inst.instruction >> 15) & 0x10) == 0))
1403     {
1404       inst.relax_inst |= (((inst.instruction >> 10) & 0x1f) << 3) | (((inst.instruction >> 15) & 0xf) << 8);
1405       inst.relax_size = 2;
1406     }
1407   else
1408     inst.relax_inst = 0x8000;
1409 }
1410 
1411 /* Handle andri/orri/andri.c/orri.c.  */
1412 
1413 static void
1414 do_rdrsi14 (char *str)          /* 0 ~ ((2^14)-1)  */
1415 {
1416   skip_whitespace (str);
1417 
1418   if (reg_required_here (&str, 20, REG_TYPE_SCORE) != (int) FAIL
1419       && skip_past_comma (&str) != (int) FAIL
1420       && reg_required_here (&str, 15, REG_TYPE_SCORE) != (int) FAIL
1421       && skip_past_comma (&str) != (int) FAIL
1422       && data_op2 (&str, 1, _IMM14) != (int) FAIL)
1423     end_of_line (str);
1424 }
1425 
1426 /* Handle bittst.c.  */
1427 static void
1428 do_xrsi5 (char *str)
1429 {
1430   skip_whitespace (str);
1431 
1432   if (reg_required_here (&str, 15, REG_TYPE_SCORE) == (int) FAIL
1433       || skip_past_comma (&str) == (int) FAIL
1434       || data_op2 (&str, 10, _IMM5) == (int) FAIL
1435       || end_of_line (str) == (int) FAIL)
1436     return;
1437 
1438   if ((inst.relax_inst != 0x8000) && (((inst.instruction >> 15) & 0x10) == 0))
1439     {
1440       inst.relax_inst |= (((inst.instruction >> 10) & 0x1f) << 3) | (((inst.instruction >> 15) & 0xf) << 8);
1441       inst.relax_size = 2;
1442     }
1443   else
1444     inst.relax_inst = 0x8000;
1445 }
1446 
1447 /* Handle addis/andi/ori/andis/oris/ldis.  */
1448 static void
1449 do_rdi16 (char *str)
1450 {
1451   skip_whitespace (str);
1452 
1453   if (reg_required_here (&str, 20, REG_TYPE_SCORE) == (int) FAIL
1454       || skip_past_comma (&str) == (int) FAIL
1455       || data_op2 (&str, 1, _IMM16) == (int) FAIL
1456       || end_of_line (str) == (int) FAIL)
1457     return;
1458   /*
1459   if (((inst.instruction & 0xa0dfffe) != 0xa0c0000) || ((((inst.instruction >> 20) & 0x1f) & 0x10) == 0x10))
1460     inst.relax_inst = 0x8000;
1461   else
1462     inst.relax_size = 2;
1463   */
1464 }
1465 
1466 static void
1467 do_macro_rdi32hi (char *str)
1468 {
1469   skip_whitespace (str);
1470 
1471   /* Do not handle end_of_line().  */
1472   if (reg_required_here (&str, 20, REG_TYPE_SCORE) != (int) FAIL
1473       && skip_past_comma (&str) != (int) FAIL)
1474     data_op2 (&str, 1, _VALUE_HI16);
1475 }
1476 
1477 static void
1478 do_macro_rdi32lo (char *str)
1479 {
1480   skip_whitespace (str);
1481 
1482   /* Do not handle end_of_line().  */
1483   if (reg_required_here (&str, 20, REG_TYPE_SCORE) != (int) FAIL
1484       && skip_past_comma (&str) != (int) FAIL)
1485     data_op2 (&str, 1, _VALUE_LO16);
1486 }
1487 
1488 /* Handle ldis_pic.  */
1489 
1490 static void
1491 do_rdi16_pic (char *str)
1492 {
1493   skip_whitespace (str);
1494 
1495   if (reg_required_here (&str, 20, REG_TYPE_SCORE) != (int) FAIL
1496       && skip_past_comma (&str) != (int) FAIL
1497       && data_op2 (&str, 1, _IMM16_pic) != (int) FAIL)
1498     end_of_line (str);
1499 }
1500 
1501 /* Handle addi_s_pic to generate R_SCORE_GOT_LO16 .  */
1502 
1503 static void
1504 do_addi_s_pic (char *str)
1505 {
1506   skip_whitespace (str);
1507 
1508   if (reg_required_here (&str, 20, REG_TYPE_SCORE) != (int) FAIL
1509       && skip_past_comma (&str) != (int) FAIL
1510       && data_op2 (&str, 1, _SIMM16_pic) != (int) FAIL)
1511     end_of_line (str);
1512 }
1513 
1514 /* Handle addi_u_pic to generate R_SCORE_GOT_LO16 .  */
1515 
1516 static void
1517 do_addi_u_pic (char *str)
1518 {
1519   skip_whitespace (str);
1520 
1521   if (reg_required_here (&str, 20, REG_TYPE_SCORE) != (int) FAIL
1522       && skip_past_comma (&str) != (int) FAIL
1523       && data_op2 (&str, 1, _IMM16_LO16_pic) != (int) FAIL)
1524     end_of_line (str);
1525 }
1526 
1527 /* Handle mfceh/mfcel/mtceh/mtchl.  */
1528 
1529 static void
1530 do_rd (char *str)
1531 {
1532   skip_whitespace (str);
1533 
1534   if (reg_required_here (&str, 20, REG_TYPE_SCORE) != (int) FAIL)
1535     end_of_line (str);
1536 }
1537 
1538 static void
1539 do_rs (char *str)
1540 {
1541   skip_whitespace (str);
1542 
1543   if (reg_required_here (&str, 15, REG_TYPE_SCORE) == (int) FAIL
1544       || end_of_line (str) == (int) FAIL)
1545     return;
1546 
1547   if ((inst.relax_inst != 0x8000) && (((inst.instruction >> 15) & 0x10) == 0))
1548     {
1549       inst.relax_inst |= (((inst.instruction >> 10) & 0xf) << 8) | (((inst.instruction >> 15) & 0xf) << 4);
1550       inst.relax_size = 2;
1551     }
1552   else
1553     inst.relax_inst = 0x8000;
1554 }
1555 
1556 static void
1557 do_i15 (char *str)
1558 {
1559   skip_whitespace (str);
1560 
1561   if (data_op2 (&str, 10, _IMM15) != (int) FAIL)
1562     end_of_line (str);
1563 }
1564 
1565 static void
1566 do_xi5x (char *str)
1567 {
1568   skip_whitespace (str);
1569 
1570   if (data_op2 (&str, 15, _IMM5) == (int) FAIL || end_of_line (str) == (int) FAIL)
1571     return;
1572 
1573   if (inst.relax_inst != 0x8000)
1574     {
1575       inst.relax_inst |= (((inst.instruction >> 15) & 0x1f) << 3);
1576       inst.relax_size = 2;
1577     }
1578 }
1579 
1580 static void
1581 do_rdrs (char *str)
1582 {
1583   skip_whitespace (str);
1584 
1585   if (reg_required_here (&str, 20, REG_TYPE_SCORE) == (int) FAIL
1586       || skip_past_comma (&str) == (int) FAIL
1587       || reg_required_here (&str, 15, REG_TYPE_SCORE) == (int) FAIL
1588       || end_of_line (str) == (int) FAIL)
1589     return;
1590 
1591   if (inst.relax_inst != 0x8000)
1592     {
1593       if (((inst.instruction & 0x7f) == 0x56))  /* adjust mv -> mv! / mlfh! / mhfl! */
1594         {
1595           /* mlfh */
1596           if ((((inst.instruction >> 15) & 0x10) != 0x0) && (((inst.instruction >> 20) & 0x10) == 0))
1597             {
1598               inst.relax_inst = 0x00000001 | (((inst.instruction >> 15) & 0xf) << 4)
1599                 | (((inst.instruction >> 20) & 0xf) << 8);
1600               inst.relax_size = 2;
1601             }
1602           /* mhfl */
1603           else if ((((inst.instruction >> 15) & 0x10) == 0x0) && ((inst.instruction >> 20) & 0x10) != 0)
1604             {
1605               inst.relax_inst = 0x00000002 | (((inst.instruction >> 15) & 0xf) << 4)
1606                 | (((inst.instruction >> 20) & 0xf) << 8);
1607               inst.relax_size = 2;
1608             }
1609           else if ((((inst.instruction >> 15) & 0x10) == 0x0) && (((inst.instruction >> 20) & 0x10) == 0))
1610             {
1611               inst.relax_inst |= (((inst.instruction >> 15) & 0xf) << 4)
1612                 | (((inst.instruction >> 20) & 0xf) << 8);
1613               inst.relax_size = 2;
1614             }
1615           else
1616             {
1617               inst.relax_inst = 0x8000;
1618             }
1619         }
1620       else if ((((inst.instruction >> 15) & 0x10) == 0x0) && (((inst.instruction >> 20) & 0x10) == 0))
1621         {
1622           inst.relax_inst |= (((inst.instruction >> 15) & 0xf) << 4)
1623             | (((inst.instruction >> 20) & 0xf) << 8);
1624           inst.relax_size = 2;
1625         }
1626       else
1627         {
1628           inst.relax_inst = 0x8000;
1629         }
1630     }
1631 }
1632 
1633 /* Handle mfcr/mtcr.  */
1634 static void
1635 do_rdcrs (char *str)
1636 {
1637   skip_whitespace (str);
1638 
1639   if (reg_required_here (&str, 20, REG_TYPE_SCORE) != (int) FAIL
1640       && skip_past_comma (&str) != (int) FAIL
1641       && reg_required_here (&str, 15, REG_TYPE_SCORE_CR) != (int) FAIL)
1642     end_of_line (str);
1643 }
1644 
1645 /* Handle mfsr/mtsr.  */
1646 
1647 static void
1648 do_rdsrs (char *str)
1649 {
1650   skip_whitespace (str);
1651 
1652   /* mfsr */
1653   if ((inst.instruction & 0xff) == 0x50)
1654     {
1655       if (reg_required_here (&str, 20, REG_TYPE_SCORE) != (int) FAIL
1656           && skip_past_comma (&str) != (int) FAIL
1657           && reg_required_here (&str, 10, REG_TYPE_SCORE_SR) != (int) FAIL)
1658 	end_of_line (str);
1659     }
1660   else
1661     {
1662       if (reg_required_here (&str, 15, REG_TYPE_SCORE) != (int) FAIL
1663           && skip_past_comma (&str) != (int) FAIL)
1664 	reg_required_here (&str, 10, REG_TYPE_SCORE_SR);
1665     }
1666 }
1667 
1668 /* Handle neg.  */
1669 
1670 static void
1671 do_rdxrs (char *str)
1672 {
1673   skip_whitespace (str);
1674 
1675   if (reg_required_here (&str, 20, REG_TYPE_SCORE) == (int) FAIL
1676       || skip_past_comma (&str) == (int) FAIL
1677       || reg_required_here (&str, 10, REG_TYPE_SCORE) == (int) FAIL
1678       || end_of_line (str) == (int) FAIL)
1679     return;
1680 
1681   if ((inst.relax_inst != 0x8000) && (((inst.instruction >> 10) & 0x10) == 0)
1682       && (((inst.instruction >> 20) & 0x10) == 0))
1683     {
1684       inst.relax_inst |= (((inst.instruction >> 10) & 0xf) << 4) | (((inst.instruction >> 20) & 0xf) << 8);
1685       inst.relax_size = 2;
1686     }
1687   else
1688     inst.relax_inst = 0x8000;
1689 }
1690 
1691 /* Handle cmp.c/cmp<cond>.  */
1692 static void
1693 do_rsrs (char *str)
1694 {
1695   skip_whitespace (str);
1696 
1697   if (reg_required_here (&str, 15, REG_TYPE_SCORE) == (int) FAIL
1698       || skip_past_comma (&str) == (int) FAIL
1699       || reg_required_here (&str, 10, REG_TYPE_SCORE) == (int) FAIL
1700       || end_of_line (str) == (int) FAIL)
1701     return;
1702 
1703   if ((inst.relax_inst != 0x8000) && (((inst.instruction >> 20) & 0x1f) == 3)
1704       && (((inst.instruction >> 10) & 0x10) == 0) && (((inst.instruction >> 15) & 0x10) == 0))
1705     {
1706       inst.relax_inst |= (((inst.instruction >> 10) & 0xf) << 4) | (((inst.instruction >> 15) & 0xf) << 8);
1707       inst.relax_size = 2;
1708     }
1709   else
1710     inst.relax_inst = 0x8000;
1711 }
1712 
1713 static void
1714 do_ceinst (char *str)
1715 {
1716   char *strbak;
1717 
1718   strbak = str;
1719   skip_whitespace (str);
1720 
1721   if (data_op2 (&str, 20, _IMM5) == (int) FAIL
1722       || skip_past_comma (&str) == (int) FAIL
1723       || reg_required_here (&str, 15, REG_TYPE_SCORE) == (int) FAIL
1724       || skip_past_comma (&str) == (int) FAIL
1725       || reg_required_here (&str, 10, REG_TYPE_SCORE) == (int) FAIL
1726       || skip_past_comma (&str) == (int) FAIL
1727       || data_op2 (&str, 5, _IMM5) == (int) FAIL
1728       || skip_past_comma (&str) == (int) FAIL
1729       || data_op2 (&str, 0, _IMM5) == (int) FAIL
1730       || end_of_line (str) == (int) FAIL)
1731     {
1732       return;
1733     }
1734   else
1735     {
1736       str = strbak;
1737       if (data_op2 (&str, 0, _IMM25) == (int) FAIL)
1738 	return;
1739     }
1740 }
1741 
1742 static int
1743 reglow_required_here (char **str, int shift)
1744 {
1745   static char buff[MAX_LITERAL_POOL_SIZE];
1746   int reg;
1747   char *start = *str;
1748 
1749   if ((reg = score_reg_parse (str, all_reg_maps[REG_TYPE_SCORE].htab)) != (int) FAIL)
1750     {
1751       if ((reg == 1) && (nor1 == 1) && (inst.bwarn == 0))
1752         {
1753           as_warn (_("Using temp register(r1)"));
1754           inst.bwarn = 1;
1755         }
1756       if (reg < 16)
1757         {
1758           if (shift >= 0)
1759             inst.instruction |= reg << shift;
1760 
1761           return reg;
1762         }
1763     }
1764 
1765   /* Restore the start point, we may have got a reg of the wrong class.  */
1766   *str = start;
1767   sprintf (buff, _("low register(r0-r15)expected, not '%.100s'"), start);
1768   inst.error = buff;
1769   return (int) FAIL;
1770 }
1771 
1772 /* Handle addc!/add!/and!/cmp!/neg!/not!/or!/sll!/srl!/sra!/xor!/sub!.  */
1773 static void
1774 do16_rdrs (char *str)
1775 {
1776   skip_whitespace (str);
1777 
1778   if (reglow_required_here (&str, 8) == (int) FAIL
1779       || skip_past_comma (&str) == (int) FAIL
1780       || reglow_required_here (&str, 4) == (int) FAIL
1781       || end_of_line (str) == (int) FAIL)
1782     {
1783       return;
1784     }
1785   else
1786     {
1787       if ((inst.instruction & 0x700f) == 0x2003)        /* cmp!  */
1788         {
1789           inst.relax_inst |= (((inst.instruction >> 8) & 0xf) << 15)
1790             | (((inst.instruction >> 4) & 0xf) << 10);
1791         }
1792       else if ((inst.instruction & 0x700f) == 0x2006)   /* not!  */
1793 	{
1794 	  inst.relax_inst |= (((inst.instruction >> 8) & 0xf) << 20)
1795 	    | (((inst.instruction >> 4) & 0xf) << 15);
1796 	}
1797       else
1798         {
1799           inst.relax_inst |= (((inst.instruction >> 8) & 0xf) << 20)
1800             | (((inst.instruction >> 8) & 0xf) << 15) | (((inst.instruction >> 4) & 0xf) << 10);
1801         }
1802       inst.relax_size = 4;
1803     }
1804 }
1805 
1806 static void
1807 do16_rs (char *str)
1808 {
1809   int rd = 0;
1810 
1811   skip_whitespace (str);
1812 
1813   if ((rd = reglow_required_here (&str, 4)) == (int) FAIL
1814       || end_of_line (str) == (int) FAIL)
1815     {
1816       return;
1817     }
1818   else
1819     {
1820       inst.relax_inst |= rd << 20;
1821       inst.relax_size = 4;
1822     }
1823 }
1824 
1825 /* Handle br!/brl!.  */
1826 static void
1827 do16_xrs (char *str)
1828 {
1829   skip_whitespace (str);
1830 
1831   if (reglow_required_here (&str, 4) == (int) FAIL || end_of_line (str) == (int) FAIL)
1832     {
1833       return;
1834     }
1835   else
1836     {
1837       inst.relax_inst |= (((inst.instruction >> 8) & 0xf) << 10)
1838                       | (((inst.instruction >> 4) & 0xf) << 15);
1839       inst.relax_size = 4;
1840     }
1841 }
1842 
1843 static int
1844 reghigh_required_here (char **str, int shift)
1845 {
1846   static char buff[MAX_LITERAL_POOL_SIZE];
1847   int reg;
1848   char *start = *str;
1849 
1850   if ((reg = score_reg_parse (str, all_reg_maps[REG_TYPE_SCORE].htab)) != (int) FAIL)
1851     {
1852       if (15 < reg && reg < 32)
1853         {
1854           if (shift >= 0)
1855             inst.instruction |= (reg & 0xf) << shift;
1856 
1857           return reg;
1858         }
1859     }
1860 
1861   *str = start;
1862   sprintf (buff, _("high register(r16-r31)expected, not '%.100s'"), start);
1863   inst.error = buff;
1864   return (int) FAIL;
1865 }
1866 
1867 /* Handle mhfl!.  */
1868 static void
1869 do16_hrdrs (char *str)
1870 {
1871   skip_whitespace (str);
1872 
1873   if (reghigh_required_here (&str, 8) != (int) FAIL
1874       && skip_past_comma (&str) != (int) FAIL
1875       && reglow_required_here (&str, 4) != (int) FAIL
1876       && end_of_line (str) != (int) FAIL)
1877     {
1878       inst.relax_inst |= ((((inst.instruction >> 8) & 0xf) | 0x10) << 20)
1879         | (((inst.instruction >> 4) & 0xf) << 15) | (0xf << 10);
1880       inst.relax_size = 4;
1881     }
1882 }
1883 
1884 /* Handle mlfh!.  */
1885 static void
1886 do16_rdhrs (char *str)
1887 {
1888   skip_whitespace (str);
1889 
1890   if (reglow_required_here (&str, 8) != (int) FAIL
1891       && skip_past_comma (&str) != (int) FAIL
1892       && reghigh_required_here (&str, 4) != (int) FAIL
1893       && end_of_line (str) != (int) FAIL)
1894     {
1895       inst.relax_inst |= (((inst.instruction >> 8) & 0xf) << 20)
1896         | ((((inst.instruction >> 4) & 0xf) | 0x10) << 15) | (0xf << 10);
1897       inst.relax_size = 4;
1898     }
1899 }
1900 
1901 /* We need to be able to fix up arbitrary expressions in some statements.
1902    This is so that we can handle symbols that are an arbitrary distance from
1903    the pc.  The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
1904    which returns part of an address in a form which will be valid for
1905    a data instruction.  We do this by pushing the expression into a symbol
1906    in the expr_section, and creating a fix for that.  */
1907 static fixS *
1908 fix_new_score (fragS * frag, int where, short int size, expressionS * exp, int pc_rel, int reloc)
1909 {
1910   fixS *new_fix;
1911 
1912   switch (exp->X_op)
1913     {
1914     case O_constant:
1915     case O_symbol:
1916     case O_add:
1917     case O_subtract:
1918       new_fix = fix_new_exp (frag, where, size, exp, pc_rel, reloc);
1919       break;
1920     default:
1921       new_fix = fix_new (frag, where, size, make_expr_symbol (exp), 0, pc_rel, reloc);
1922       break;
1923     }
1924   return new_fix;
1925 }
1926 
1927 static void
1928 init_dependency_vector (void)
1929 {
1930   int i;
1931 
1932   for (i = 0; i < vector_size; i++)
1933     memset (&dependency_vector[i], '\0', sizeof (dependency_vector[i]));
1934 
1935   return;
1936 }
1937 
1938 static enum insn_type_for_dependency
1939 dependency_type_from_insn (char *insn_name)
1940 {
1941   char name[INSN_NAME_LEN];
1942   const struct insn_to_dependency *tmp;
1943 
1944   strcpy (name, insn_name);
1945   tmp = (const struct insn_to_dependency *) hash_find (dependency_insn_hsh, name);
1946 
1947   if (tmp)
1948     return tmp->type;
1949 
1950   return D_all_insn;
1951 }
1952 
1953 static int
1954 check_dependency (char *pre_insn, char *pre_reg,
1955                   char *cur_insn, char *cur_reg, int *warn_or_error)
1956 {
1957   int bubbles = 0;
1958   unsigned int i;
1959   enum insn_type_for_dependency pre_insn_type;
1960   enum insn_type_for_dependency cur_insn_type;
1961 
1962   pre_insn_type = dependency_type_from_insn (pre_insn);
1963   cur_insn_type = dependency_type_from_insn (cur_insn);
1964 
1965   for (i = 0; i < sizeof (data_dependency_table) / sizeof (data_dependency_table[0]); i++)
1966     {
1967       if ((pre_insn_type == data_dependency_table[i].pre_insn_type)
1968           && (D_all_insn == data_dependency_table[i].cur_insn_type
1969               || cur_insn_type == data_dependency_table[i].cur_insn_type)
1970           && (strcmp (data_dependency_table[i].pre_reg, "") == 0
1971               || strcmp (data_dependency_table[i].pre_reg, pre_reg) == 0)
1972           && (strcmp (data_dependency_table[i].cur_reg, "") == 0
1973               || strcmp (data_dependency_table[i].cur_reg, cur_reg) == 0))
1974         {
1975           bubbles = (score7) ? data_dependency_table[i].bubblenum_7 : data_dependency_table[i].bubblenum_5;
1976           *warn_or_error = data_dependency_table[i].warn_or_error;
1977           break;
1978         }
1979     }
1980 
1981   return bubbles;
1982 }
1983 
1984 static void
1985 build_one_frag (struct score_it one_inst)
1986 {
1987   char *p;
1988   int relaxable_p = g_opt;
1989   int relax_size = 0;
1990 
1991   /* Start a new frag if frag_now is not empty.  */
1992   if (frag_now_fix () != 0)
1993     {
1994       if (!frag_now->tc_frag_data.is_insn)
1995 	frag_wane (frag_now);
1996 
1997       frag_new (0);
1998     }
1999   frag_grow (20);
2000 
2001   p = frag_more (one_inst.size);
2002   md_number_to_chars (p, one_inst.instruction, one_inst.size);
2003 
2004 #ifdef OBJ_ELF
2005   dwarf2_emit_insn (one_inst.size);
2006 #endif
2007 
2008   relaxable_p &= (one_inst.relax_size != 0);
2009   relax_size = relaxable_p ? one_inst.relax_size : 0;
2010 
2011   p = frag_var (rs_machine_dependent, relax_size + RELAX_PAD_BYTE, 0,
2012                 RELAX_ENCODE (one_inst.size, one_inst.relax_size,
2013                               one_inst.type, 0, 0, relaxable_p),
2014                 NULL, 0, NULL);
2015 
2016   if (relaxable_p)
2017     md_number_to_chars (p, one_inst.relax_inst, relax_size);
2018 }
2019 
2020 static void
2021 handle_dependency (struct score_it *theinst)
2022 {
2023   int i;
2024   int warn_or_error = 0;   /* warn - 0; error - 1  */
2025   int bubbles = 0;
2026   int remainder_bubbles = 0;
2027   char cur_insn[INSN_NAME_LEN];
2028   char pre_insn[INSN_NAME_LEN];
2029   struct score_it nop_inst;
2030   struct score_it pflush_inst;
2031 
2032   nop_inst.instruction = 0x0000;
2033   nop_inst.size = 2;
2034   nop_inst.relax_inst = 0x80008000;
2035   nop_inst.relax_size = 4;
2036   nop_inst.type = NO16_OPD;
2037 
2038   pflush_inst.instruction = 0x8000800a;
2039   pflush_inst.size = 4;
2040   pflush_inst.relax_inst = 0x8000;
2041   pflush_inst.relax_size = 0;
2042   pflush_inst.type = NO_OPD;
2043 
2044   /* pflush will clear all data dependency.  */
2045   if (strcmp (theinst->name, "pflush") == 0)
2046     {
2047       init_dependency_vector ();
2048       return;
2049     }
2050 
2051   /* Push current instruction to dependency_vector[0].  */
2052   for (i = vector_size - 1; i > 0; i--)
2053     memcpy (&dependency_vector[i], &dependency_vector[i - 1], sizeof (dependency_vector[i]));
2054 
2055   memcpy (&dependency_vector[0], theinst, sizeof (dependency_vector[i]));
2056 
2057   /* There is no dependency between nop and any instruction.  */
2058   if (strcmp (dependency_vector[0].name, "nop") == 0
2059       || strcmp (dependency_vector[0].name, "nop!") == 0)
2060     return;
2061 
2062   /* "pce" is defined in insn_to_dependency_table.  */
2063 #define PCE_NAME "pce"
2064 
2065   if (dependency_vector[0].type == Insn_Type_PCE)
2066     strcpy (cur_insn, PCE_NAME);
2067   else
2068     strcpy (cur_insn, dependency_vector[0].name);
2069 
2070   for (i = 1; i < vector_size; i++)
2071     {
2072       /* The element of dependency_vector is NULL.  */
2073       if (dependency_vector[i].name[0] == '\0')
2074 	continue;
2075 
2076       if (dependency_vector[i].type == Insn_Type_PCE)
2077 	strcpy (pre_insn, PCE_NAME);
2078       else
2079 	strcpy (pre_insn, dependency_vector[i].name);
2080 
2081       bubbles = check_dependency (pre_insn, dependency_vector[i].reg,
2082                                   cur_insn, dependency_vector[0].reg, &warn_or_error);
2083       remainder_bubbles = bubbles - i + 1;
2084 
2085       if (remainder_bubbles > 0)
2086         {
2087           int j;
2088 
2089           if (fix_data_dependency == 1)
2090             {
2091 	      if (remainder_bubbles <= 2)
2092 		{
2093 		  if (warn_fix_data_dependency)
2094 		    as_warn (_("Fix data dependency: %s %s -- %s %s  (insert %d nop!/%d)"),
2095 			     dependency_vector[i].name, dependency_vector[i].reg,
2096 			     dependency_vector[0].name, dependency_vector[0].reg,
2097 			     remainder_bubbles, bubbles);
2098 
2099                   for (j = (vector_size - 1); (j - remainder_bubbles) > 0; j--)
2100 		    memcpy (&dependency_vector[j], &dependency_vector[j - remainder_bubbles],
2101 			    sizeof (dependency_vector[j]));
2102 
2103                   for (j = 1; j <= remainder_bubbles; j++)
2104                     {
2105                       memset (&dependency_vector[j], '\0', sizeof (dependency_vector[j]));
2106 		      /* Insert nop!.  */
2107     		      build_one_frag (nop_inst);
2108                     }
2109 		}
2110 	      else
2111 		{
2112 		  if (warn_fix_data_dependency)
2113 		    as_warn (_("Fix data dependency: %s %s -- %s %s  (insert 1 pflush/%d)"),
2114 			     dependency_vector[i].name, dependency_vector[i].reg,
2115 			     dependency_vector[0].name, dependency_vector[0].reg,
2116 			     bubbles);
2117 
2118                   for (j = 1; j < vector_size; j++)
2119 		    memset (&dependency_vector[j], '\0', sizeof (dependency_vector[j]));
2120 
2121                   /* Insert pflush.  */
2122                   build_one_frag (pflush_inst);
2123 		}
2124             }
2125           else
2126             {
2127 	      if (warn_or_error)
2128 		{
2129                   as_bad (_("data dependency: %s %s -- %s %s  (%d/%d bubble)"),
2130                            dependency_vector[i].name, dependency_vector[i].reg,
2131                            dependency_vector[0].name, dependency_vector[0].reg,
2132                            remainder_bubbles, bubbles);
2133 		}
2134 	      else
2135 		{
2136                   as_warn (_("data dependency: %s %s -- %s %s  (%d/%d bubble)"),
2137                            dependency_vector[i].name, dependency_vector[i].reg,
2138                            dependency_vector[0].name, dependency_vector[0].reg,
2139                            remainder_bubbles, bubbles);
2140 		}
2141             }
2142         }
2143     }
2144 }
2145 
2146 static enum insn_class
2147 get_insn_class_from_type (enum score_insn_type type)
2148 {
2149   enum insn_class retval = (int) FAIL;
2150 
2151   switch (type)
2152     {
2153     case Rd_I4:
2154     case Rd_I5:
2155     case Rd_rvalueBP_I5:
2156     case Rd_lvalueBP_I5:
2157     case Rd_I8:
2158     case PC_DISP8div2:
2159     case PC_DISP11div2:
2160     case Rd_Rs:
2161     case Rd_HighRs:
2162     case Rd_lvalueRs:
2163     case Rd_rvalueRs:
2164     case x_Rs:
2165     case Rd_LowRs:
2166     case NO16_OPD:
2167       retval = INSN_CLASS_16;
2168       break;
2169     case Rd_Rs_I5:
2170     case x_Rs_I5:
2171     case x_I5_x:
2172     case Rd_Rs_I14:
2173     case I15:
2174     case Rd_I16:
2175     case Rd_SI16:
2176     case Rd_rvalueRs_SI10:
2177     case Rd_lvalueRs_SI10:
2178     case Rd_rvalueRs_preSI12:
2179     case Rd_rvalueRs_postSI12:
2180     case Rd_lvalueRs_preSI12:
2181     case Rd_lvalueRs_postSI12:
2182     case Rd_Rs_SI14:
2183     case Rd_rvalueRs_SI15:
2184     case Rd_lvalueRs_SI15:
2185     case PC_DISP19div2:
2186     case PC_DISP24div2:
2187     case Rd_Rs_Rs:
2188     case x_Rs_x:
2189     case x_Rs_Rs:
2190     case Rd_Rs_x:
2191     case Rd_x_Rs:
2192     case Rd_x_x:
2193     case OP5_rvalueRs_SI15:
2194     case I5_Rs_Rs_I5_OP5:
2195     case x_rvalueRs_post4:
2196     case Rd_rvalueRs_post4:
2197     case Rd_x_I5:
2198     case Rd_lvalueRs_post4:
2199     case x_lvalueRs_post4:
2200     case Rd_Rs_Rs_imm:
2201     case NO_OPD:
2202     case Rd_lvalue32Rs:
2203     case Rd_rvalue32Rs:
2204     case Insn_GP:
2205     case Insn_PIC:
2206     case Insn_internal:
2207       retval = INSN_CLASS_32;
2208       break;
2209     case Insn_Type_PCE:
2210       retval = INSN_CLASS_PCE;
2211       break;
2212     case Insn_Type_SYN:
2213       retval = INSN_CLASS_SYN;
2214       break;
2215     default:
2216       abort ();
2217       break;
2218     }
2219   return retval;
2220 }
2221 
2222 static unsigned long
2223 adjust_paritybit (unsigned long m_code, enum insn_class class)
2224 {
2225   unsigned long result = 0;
2226   unsigned long m_code_high = 0;
2227   unsigned long m_code_low = 0;
2228   unsigned long pb_high = 0;
2229   unsigned long pb_low = 0;
2230 
2231   if (class == INSN_CLASS_32)
2232     {
2233       pb_high = 0x80000000;
2234       pb_low = 0x00008000;
2235     }
2236   else if (class == INSN_CLASS_16)
2237     {
2238       pb_high = 0;
2239       pb_low = 0;
2240     }
2241   else if (class == INSN_CLASS_PCE)
2242     {
2243       pb_high = 0;
2244       pb_low = 0x00008000;
2245     }
2246   else if (class == INSN_CLASS_SYN)
2247     {
2248       /* FIXME.  at this time, INSN_CLASS_SYN must be 32 bit, but, instruction type should
2249          be changed if macro instruction has been expanded.  */
2250       pb_high = 0x80000000;
2251       pb_low = 0x00008000;
2252     }
2253   else
2254     {
2255       abort ();
2256     }
2257 
2258   m_code_high = m_code & 0x3fff8000;
2259   m_code_low = m_code & 0x00007fff;
2260   result = pb_high | (m_code_high << 1) | pb_low | m_code_low;
2261   return result;
2262 
2263 }
2264 
2265 static void
2266 gen_insn_frag (struct score_it *part_1, struct score_it *part_2)
2267 {
2268   char *p;
2269   bfd_boolean pce_p = FALSE;
2270   int relaxable_p = g_opt;
2271   int relax_size = 0;
2272   struct score_it *inst1 = part_1;
2273   struct score_it *inst2 = part_2;
2274   struct score_it backup_inst1;
2275 
2276   pce_p = (inst2) ? TRUE : FALSE;
2277   memcpy (&backup_inst1, inst1, sizeof (struct score_it));
2278 
2279   /* Adjust instruction opcode and to be relaxed instruction opcode.  */
2280   if (pce_p)
2281     {
2282       backup_inst1.instruction = ((backup_inst1.instruction & 0x7FFF) << 15)
2283                                   | (inst2->instruction & 0x7FFF);
2284       backup_inst1.instruction = adjust_paritybit (backup_inst1.instruction, INSN_CLASS_PCE);
2285       backup_inst1.relax_inst = 0x8000;
2286       backup_inst1.size = INSN_SIZE;
2287       backup_inst1.relax_size = 0;
2288       backup_inst1.type = Insn_Type_PCE;
2289     }
2290   else
2291     {
2292       backup_inst1.instruction = adjust_paritybit (backup_inst1.instruction,
2293 						   GET_INSN_CLASS (backup_inst1.type));
2294     }
2295 
2296   if (backup_inst1.relax_size != 0)
2297     {
2298       enum insn_class tmp;
2299 
2300       tmp = (backup_inst1.size == INSN_SIZE) ? INSN_CLASS_16 : INSN_CLASS_32;
2301       backup_inst1.relax_inst = adjust_paritybit (backup_inst1.relax_inst, tmp);
2302     }
2303 
2304   /* Check data dependency.  */
2305   handle_dependency (&backup_inst1);
2306 
2307   /* Start a new frag if frag_now is not empty and is not instruction frag, maybe it contains
2308      data produced by .ascii etc.  Doing this is to make one instruction per frag.  */
2309   if (frag_now_fix () != 0)
2310     {
2311       if (!frag_now->tc_frag_data.is_insn)
2312 	frag_wane (frag_now);
2313 
2314       frag_new (0);
2315     }
2316 
2317   /* Here, we must call frag_grow in order to keep the instruction frag type is
2318      rs_machine_dependent.
2319      For, frag_var may change frag_now->fr_type to rs_fill by calling frag_grow which
2320      acturally will call frag_wane.
2321      Calling frag_grow first will create a new frag_now which free size is 20 that is enough
2322      for frag_var.  */
2323   frag_grow (20);
2324 
2325   p = frag_more (backup_inst1.size);
2326   md_number_to_chars (p, backup_inst1.instruction, backup_inst1.size);
2327 
2328 #ifdef OBJ_ELF
2329   dwarf2_emit_insn (backup_inst1.size);
2330 #endif
2331 
2332   /* Generate fixup structure.  */
2333   if (pce_p)
2334     {
2335       if (inst1->reloc.type != BFD_RELOC_NONE)
2336 	fix_new_score (frag_now, p - frag_now->fr_literal,
2337 		       inst1->size, &inst1->reloc.exp,
2338 		       inst1->reloc.pc_rel, inst1->reloc.type);
2339 
2340       if (inst2->reloc.type != BFD_RELOC_NONE)
2341 	fix_new_score (frag_now, p - frag_now->fr_literal + 2,
2342 		       inst2->size, &inst2->reloc.exp, inst2->reloc.pc_rel, inst2->reloc.type);
2343     }
2344   else
2345     {
2346       if (backup_inst1.reloc.type != BFD_RELOC_NONE)
2347 	fix_new_score (frag_now, p - frag_now->fr_literal,
2348 		       backup_inst1.size, &backup_inst1.reloc.exp,
2349 		       backup_inst1.reloc.pc_rel, backup_inst1.reloc.type);
2350     }
2351 
2352   /* relax_size may be 2, 4, 12 or 0, 0 indicates no relaxation.  */
2353   relaxable_p &= (backup_inst1.relax_size != 0);
2354   relax_size = relaxable_p ? backup_inst1.relax_size : 0;
2355 
2356   p = frag_var (rs_machine_dependent, relax_size + RELAX_PAD_BYTE, 0,
2357                 RELAX_ENCODE (backup_inst1.size, backup_inst1.relax_size,
2358                               backup_inst1.type, 0, 0, relaxable_p),
2359                 backup_inst1.reloc.exp.X_add_symbol, 0, NULL);
2360 
2361   if (relaxable_p)
2362     md_number_to_chars (p, backup_inst1.relax_inst, relax_size);
2363 
2364   memcpy (inst1, &backup_inst1, sizeof (struct score_it));
2365 }
2366 
2367 static void
2368 parse_16_32_inst (char *insnstr, bfd_boolean gen_frag_p)
2369 {
2370   char c;
2371   char *p;
2372   char *operator = insnstr;
2373   const struct asm_opcode *opcode;
2374 
2375   /* Parse operator and operands.  */
2376   skip_whitespace (operator);
2377 
2378   for (p = operator; *p != '\0'; p++)
2379     if ((*p == ' ') || (*p == '!'))
2380       break;
2381 
2382   if (*p == '!')
2383     p++;
2384 
2385   c = *p;
2386   *p = '\0';
2387 
2388   opcode = (const struct asm_opcode *) hash_find (score_ops_hsh, operator);
2389   *p = c;
2390 
2391   memset (&inst, '\0', sizeof (inst));
2392   sprintf (inst.str, "%s", insnstr);
2393   if (opcode)
2394     {
2395       inst.instruction = opcode->value;
2396       inst.relax_inst = opcode->relax_value;
2397       inst.type = opcode->type;
2398       inst.size = GET_INSN_SIZE (inst.type);
2399       inst.relax_size = 0;
2400       inst.bwarn = 0;
2401       sprintf (inst.name, "%s", opcode->template);
2402       strcpy (inst.reg, "");
2403       inst.error = NULL;
2404       inst.reloc.type = BFD_RELOC_NONE;
2405 
2406       (*opcode->parms) (p);
2407 
2408       /* It indicates current instruction is a macro instruction if inst.bwarn equals -1.  */
2409       if ((inst.bwarn != -1) && (!inst.error) && (gen_frag_p))
2410 	gen_insn_frag (&inst, NULL);
2411     }
2412   else
2413     inst.error = _("unrecognized opcode");
2414 }
2415 
2416 static int
2417 append_insn (char *str, bfd_boolean gen_frag_p)
2418 {
2419   int retval = SUCCESS;
2420 
2421   parse_16_32_inst (str, gen_frag_p);
2422 
2423   if (inst.error)
2424     {
2425       retval = (int) FAIL;
2426       as_bad (_("%s -- `%s'"), inst.error, inst.str);
2427       inst.error = NULL;
2428     }
2429 
2430   return retval;
2431 }
2432 
2433 /* Handle mv! reg_high, reg_low;
2434           mv! reg_low, reg_high;
2435           mv! reg_low, reg_low;  */
2436 static void
2437 do16_mv_rdrs (char *str)
2438 {
2439   int reg_rd;
2440   int reg_rs;
2441   char *backupstr = NULL;
2442 
2443   backupstr = str;
2444   skip_whitespace (str);
2445 
2446   if ((reg_rd = reg_required_here (&str, 8, REG_TYPE_SCORE)) == (int) FAIL
2447       || skip_past_comma (&str) == (int) FAIL
2448       || (reg_rs = reg_required_here (&str, 4, REG_TYPE_SCORE)) == (int) FAIL
2449       || end_of_line (str) == (int) FAIL)
2450     {
2451       return;
2452     }
2453   else
2454     {
2455       /* Case 1 : mv! or mlfh!.  */
2456       if (reg_rd < 16)
2457         {
2458           if (reg_rs < 16)
2459             {
2460               inst.relax_inst |= (((inst.instruction >> 8) & 0xf) << 20)
2461                 | (((inst.instruction >> 4) & 0xf) << 15) | (0xf << 10);
2462               inst.relax_size = 4;
2463             }
2464           else
2465             {
2466               char append_str[MAX_LITERAL_POOL_SIZE];
2467 
2468               sprintf (append_str, "mlfh! %s", backupstr);
2469               if (append_insn (append_str, TRUE) == (int) FAIL)
2470 		return;
2471               /* Set bwarn as -1, so macro instruction itself will not be generated frag.  */
2472               inst.bwarn = -1;
2473             }
2474         }
2475       /* Case 2 : mhfl!.  */
2476       else
2477         {
2478           if (reg_rs > 16)
2479             {
2480               SET_INSN_ERROR (BAD_ARGS);
2481               return;
2482             }
2483           else
2484             {
2485               char append_str[MAX_LITERAL_POOL_SIZE];
2486 
2487               sprintf (append_str, "mhfl! %s", backupstr);
2488               if (append_insn (append_str, TRUE) == (int) FAIL)
2489 		return;
2490 
2491               /* Set bwarn as -1, so macro instruction itself will not be generated frag.  */
2492               inst.bwarn = -1;
2493             }
2494         }
2495     }
2496 }
2497 
2498 static void
2499 do16_rdi4 (char *str)
2500 {
2501   skip_whitespace (str);
2502 
2503   if (reglow_required_here (&str, 8) == (int) FAIL
2504       || skip_past_comma (&str) == (int) FAIL
2505       || data_op2 (&str, 3, _IMM4) == (int) FAIL
2506       || end_of_line (str) == (int) FAIL)
2507     {
2508       return;
2509     }
2510   else
2511     {
2512       if (((inst.instruction >> 3) & 0x10) == 0)        /* for judge is addei or subei : bit 5 =0 : addei */
2513         {
2514           if (((inst.instruction >> 3) & 0xf) != 0xf)
2515             {
2516               inst.relax_inst |= (((inst.instruction >> 8) & 0xf) << 20)
2517                 | ((1 << ((inst.instruction >> 3) & 0xf)) << 1);
2518               inst.relax_size = 4;
2519             }
2520           else
2521             {
2522               inst.relax_inst = 0x8000;
2523             }
2524         }
2525       else
2526         {
2527           if (((inst.instruction >> 3) & 0xf) != 0xf)
2528             {
2529               inst.relax_inst |= (((inst.instruction >> 8) & 0xf) << 20)
2530                 | (((-(1 << ((inst.instruction >> 3) & 0xf))) & 0xffff) << 1);
2531               inst.relax_size = 4;
2532             }
2533           else
2534             {
2535               inst.relax_inst = 0x8000;
2536             }
2537         }
2538     }
2539 }
2540 
2541 static void
2542 do16_rdi5 (char *str)
2543 {
2544   skip_whitespace (str);
2545 
2546   if (reglow_required_here (&str, 8) == (int) FAIL
2547       || skip_past_comma (&str) == (int) FAIL
2548       || data_op2 (&str, 3, _IMM5) == (int) FAIL
2549       || end_of_line (str) == (int) FAIL)
2550     return;
2551   else
2552     {
2553       inst.relax_inst |= (((inst.instruction >> 8) & 0xf) << 20)
2554         | (((inst.instruction >> 8) & 0xf) << 15) | (((inst.instruction >> 3) & 0x1f) << 10);
2555       inst.relax_size = 4;
2556     }
2557 }
2558 
2559 /* Handle sdbbp.  */
2560 static void
2561 do16_xi5 (char *str)
2562 {
2563   skip_whitespace (str);
2564 
2565   if (data_op2 (&str, 3, _IMM5) == (int) FAIL || end_of_line (str) == (int) FAIL)
2566     return;
2567   else
2568     {
2569       inst.relax_inst |= (((inst.instruction >> 3) & 0x1f) << 15);
2570       inst.relax_size = 4;
2571     }
2572 }
2573 
2574 /* Check that an immediate is word alignment or half word alignment.
2575    If so, convert it to the right format.  */
2576 static int
2577 validate_immediate_align (int val, unsigned int data_type)
2578 {
2579   if (data_type == _IMM5_RSHIFT_1)
2580     {
2581       if (val % 2)
2582         {
2583           inst.error = _("address offset must be half word alignment");
2584           return (int) FAIL;
2585         }
2586     }
2587   else if ((data_type == _IMM5_RSHIFT_2) || (data_type == _IMM10_RSHIFT_2))
2588     {
2589       if (val % 4)
2590         {
2591           inst.error = _("address offset must be word alignment");
2592           return (int) FAIL;
2593         }
2594     }
2595 
2596   return SUCCESS;
2597 }
2598 
2599 static int
2600 exp_ldst_offset (char **str, int shift, unsigned int data_type)
2601 {
2602   char *dataptr;
2603 
2604   dataptr = * str;
2605 
2606   if ((*dataptr == '0') && (*(dataptr + 1) == 'x')
2607       && (data_type != _SIMM16_LA)
2608       && (data_type != _VALUE_HI16)
2609       && (data_type != _VALUE_LO16)
2610       && (data_type != _IMM16)
2611       && (data_type != _IMM15)
2612       && (data_type != _IMM14)
2613       && (data_type != _IMM4)
2614       && (data_type != _IMM5)
2615       && (data_type != _IMM8)
2616       && (data_type != _IMM5_RSHIFT_1)
2617       && (data_type != _IMM5_RSHIFT_2)
2618       && (data_type != _SIMM14_NEG)
2619       && (data_type != _IMM10_RSHIFT_2))
2620     {
2621       data_type += 24;
2622     }
2623 
2624   if (my_get_expression (&inst.reloc.exp, str) == (int) FAIL)
2625     return (int) FAIL;
2626 
2627   if (inst.reloc.exp.X_op == O_constant)
2628     {
2629       /* Need to check the immediate align.  */
2630       int value = validate_immediate_align (inst.reloc.exp.X_add_number, data_type);
2631 
2632       if (value == (int) FAIL)
2633 	return (int) FAIL;
2634 
2635       value = validate_immediate (inst.reloc.exp.X_add_number, data_type, 0);
2636       if (value == (int) FAIL)
2637         {
2638           if (data_type < 30)
2639             sprintf (err_msg,
2640                      _("invalid constant: %d bit expression not in range %d..%d"),
2641                      score_df_range[data_type].bits,
2642                      score_df_range[data_type].range[0], score_df_range[data_type].range[1]);
2643           else
2644             sprintf (err_msg,
2645                      _("invalid constant: %d bit expression not in range %d..%d"),
2646                      score_df_range[data_type - 24].bits,
2647                      score_df_range[data_type - 24].range[0], score_df_range[data_type - 24].range[1]);
2648           inst.error = err_msg;
2649           return (int) FAIL;
2650         }
2651 
2652       if (data_type == _IMM5_RSHIFT_1)
2653         {
2654           value >>= 1;
2655         }
2656       else if ((data_type == _IMM5_RSHIFT_2) || (data_type == _IMM10_RSHIFT_2))
2657         {
2658           value >>= 2;
2659         }
2660 
2661       if (score_df_range[data_type].range[0] != 0)
2662         {
2663           value &= (1 << score_df_range[data_type].bits) - 1;
2664         }
2665 
2666       inst.instruction |= value << shift;
2667     }
2668   else
2669     {
2670       inst.reloc.pc_rel = 0;
2671     }
2672 
2673   return SUCCESS;
2674 }
2675 
2676 static void
2677 do_ldst_insn (char *str)
2678 {
2679   int pre_inc = 0;
2680   int conflict_reg;
2681   int value;
2682   char * temp;
2683   char *strbak;
2684   char *dataptr;
2685   int reg;
2686   int ldst_idx = 0;
2687 
2688   strbak = str;
2689   skip_whitespace (str);
2690 
2691   if (((conflict_reg = reg_required_here (&str, 20, REG_TYPE_SCORE)) == (int) FAIL)
2692       || (skip_past_comma (&str) == (int) FAIL))
2693     return;
2694 
2695   /* ld/sw rD, [rA, simm15]    ld/sw rD, [rA]+, simm12     ld/sw rD, [rA, simm12]+.  */
2696   if (*str == '[')
2697     {
2698       str++;
2699       skip_whitespace (str);
2700 
2701       if ((reg = reg_required_here (&str, 15, REG_TYPE_SCORE)) == (int) FAIL)
2702 	return;
2703 
2704       /* Conflicts can occur on stores as well as loads.  */
2705       conflict_reg = (conflict_reg == reg);
2706       skip_whitespace (str);
2707       temp = str + 1;    /* The latter will process decimal/hex expression.  */
2708 
2709       /* ld/sw rD, [rA]+, simm12    ld/sw rD, [rA]+.  */
2710       if (*str == ']')
2711         {
2712           str++;
2713           if (*str == '+')
2714             {
2715               str++;
2716               /* ld/sw rD, [rA]+, simm12.  */
2717               if (skip_past_comma (&str) == SUCCESS)
2718                 {
2719                   if ((exp_ldst_offset (&str, 3, _SIMM12) == (int) FAIL)
2720                       || (end_of_line (str) == (int) FAIL))
2721 		    return;
2722 
2723                   if (conflict_reg)
2724                     {
2725                       unsigned int ldst_func = inst.instruction & OPC_PSEUDOLDST_MASK;
2726 
2727                       if ((ldst_func == INSN_LH)
2728                           || (ldst_func == INSN_LHU)
2729                           || (ldst_func == INSN_LW)
2730                           || (ldst_func == INSN_LB)
2731                           || (ldst_func == INSN_LBU))
2732                         {
2733                           inst.error = _("register same as write-back base");
2734                           return;
2735                         }
2736                     }
2737 
2738                   ldst_idx = inst.instruction & OPC_PSEUDOLDST_MASK;
2739                   inst.instruction &= ~OPC_PSEUDOLDST_MASK;
2740                   inst.instruction |= score_ldst_insns[ldst_idx * 3 + LDST_POST].value;
2741 
2742                   /* lw rD, [rA]+, 4 convert to pop rD, [rA].  */
2743                   if ((inst.instruction & 0x3e000007) == 0x0e000000)
2744                     {
2745                       /* rs =  r0-r7, offset = 4 */
2746                       if ((((inst.instruction >> 15) & 0x18) == 0)
2747                           && (((inst.instruction >> 3) & 0xfff) == 4))
2748                         {
2749                           /* Relax to pophi.  */
2750                           if ((((inst.instruction >> 20) & 0x10) == 0x10))
2751                             {
2752                               inst.relax_inst = 0x0000200a | (((inst.instruction >> 20) & 0xf)
2753                                                               << 8) | 1 << 7 |
2754                                 (((inst.instruction >> 15) & 0x7) << 4);
2755                             }
2756                           /* Relax to pop.  */
2757                           else
2758                             {
2759                               inst.relax_inst = 0x0000200a | (((inst.instruction >> 20) & 0xf)
2760                                                               << 8) | 0 << 7 |
2761                                 (((inst.instruction >> 15) & 0x7) << 4);
2762                             }
2763                           inst.relax_size = 2;
2764                         }
2765                     }
2766                   return;
2767                 }
2768               /* ld/sw rD, [rA]+ convert to ld/sw rD, [rA, 0]+.  */
2769               else
2770                 {
2771                   SET_INSN_ERROR (NULL);
2772                   if (end_of_line (str) == (int) FAIL)
2773                     {
2774                       return;
2775                     }
2776 
2777                   pre_inc = 1;
2778                   value = validate_immediate (inst.reloc.exp.X_add_number, _SIMM12, 0);
2779                   value &= (1 << score_df_range[_SIMM12].bits) - 1;
2780                   ldst_idx = inst.instruction & OPC_PSEUDOLDST_MASK;
2781                   inst.instruction &= ~OPC_PSEUDOLDST_MASK;
2782                   inst.instruction |= score_ldst_insns[ldst_idx * 3 + pre_inc].value;
2783                   inst.instruction |= value << 3;
2784                   inst.relax_inst = 0x8000;
2785                   return;
2786                 }
2787             }
2788           /* ld/sw rD, [rA] convert to ld/sw rD, [rA, simm15].  */
2789           else
2790             {
2791               if (end_of_line (str) == (int) FAIL)
2792 		return;
2793 
2794               ldst_idx = inst.instruction & OPC_PSEUDOLDST_MASK;
2795               inst.instruction &= ~OPC_PSEUDOLDST_MASK;
2796               inst.instruction |= score_ldst_insns[ldst_idx * 3 + LDST_NOUPDATE].value;
2797 
2798               /* lbu rd, [rs] -> lbu! rd, [rs]  */
2799               if (ldst_idx == INSN_LBU)
2800                 {
2801                   inst.relax_inst = INSN16_LBU;
2802                 }
2803               else if (ldst_idx == INSN_LH)
2804                 {
2805                   inst.relax_inst = INSN16_LH;
2806                 }
2807               else if (ldst_idx == INSN_LW)
2808                 {
2809                   inst.relax_inst = INSN16_LW;
2810                 }
2811               else if (ldst_idx == INSN_SB)
2812                 {
2813                   inst.relax_inst = INSN16_SB;
2814                 }
2815               else if (ldst_idx == INSN_SH)
2816                 {
2817                   inst.relax_inst = INSN16_SH;
2818                 }
2819               else if (ldst_idx == INSN_SW)
2820                 {
2821                   inst.relax_inst = INSN16_SW;
2822                 }
2823               else
2824                 {
2825                   inst.relax_inst = 0x8000;
2826                 }
2827 
2828               /* lw/lh/lbu/sw/sh/sb, offset = 0, relax to 16 bit instruction.  */
2829               if ((ldst_idx == INSN_LBU)
2830                   || (ldst_idx == INSN_LH)
2831                   || (ldst_idx == INSN_LW)
2832                   || (ldst_idx == INSN_SB) || (ldst_idx == INSN_SH) || (ldst_idx == INSN_SW))
2833                 {
2834                   if ((((inst.instruction >> 15) & 0x10) == 0) && (((inst.instruction >> 20) & 0x10) == 0))
2835                     {
2836                       inst.relax_inst |= (2 << 12) | (((inst.instruction >> 20) & 0xf) << 8) |
2837                         (((inst.instruction >> 15) & 0xf) << 4);
2838                       inst.relax_size = 2;
2839                     }
2840                 }
2841 
2842               return;
2843             }
2844         }
2845       /* ld/sw rD, [rA, simm15]    ld/sw rD, [rA, simm12]+.  */
2846       else
2847         {
2848           if (skip_past_comma (&str) == (int) FAIL)
2849             {
2850               inst.error = _("pre-indexed expression expected");
2851               return;
2852             }
2853 
2854           if (my_get_expression (&inst.reloc.exp, &str) == (int) FAIL)
2855 	    return;
2856 
2857           skip_whitespace (str);
2858           if (*str++ != ']')
2859             {
2860               inst.error = _("missing ]");
2861               return;
2862             }
2863 
2864           skip_whitespace (str);
2865           /* ld/sw rD, [rA, simm12]+.  */
2866           if (*str == '+')
2867             {
2868               str++;
2869               pre_inc = 1;
2870               if (conflict_reg)
2871                 {
2872                   unsigned int ldst_func = inst.instruction & OPC_PSEUDOLDST_MASK;
2873 
2874                   if ((ldst_func == INSN_LH)
2875                       || (ldst_func == INSN_LHU)
2876                       || (ldst_func == INSN_LW)
2877                       || (ldst_func == INSN_LB)
2878                       || (ldst_func == INSN_LBU))
2879                     {
2880                       inst.error = _("register same as write-back base");
2881                       return;
2882                     }
2883                 }
2884             }
2885 
2886           if (end_of_line (str) == (int) FAIL)
2887 	    return;
2888 
2889           if (inst.reloc.exp.X_op == O_constant)
2890             {
2891               int value;
2892               unsigned int data_type;
2893 
2894               if (pre_inc == 1)
2895                 data_type = _SIMM12;
2896               else
2897                 data_type = _SIMM15;
2898               dataptr = temp;
2899 
2900               if ((*dataptr == '0') && (*(dataptr + 1) == 'x')
2901                   && (data_type != _SIMM16_LA)
2902                   && (data_type != _VALUE_HI16)
2903                   && (data_type != _VALUE_LO16)
2904                   && (data_type != _IMM16)
2905                   && (data_type != _IMM15)
2906                   && (data_type != _IMM14)
2907                   && (data_type != _IMM4)
2908                   && (data_type != _IMM5)
2909                   && (data_type != _IMM8)
2910                   && (data_type != _IMM5_RSHIFT_1)
2911                   && (data_type != _IMM5_RSHIFT_2)
2912                   && (data_type != _SIMM14_NEG)
2913                   && (data_type != _IMM10_RSHIFT_2))
2914                 {
2915                   data_type += 24;
2916                 }
2917 
2918               value = validate_immediate (inst.reloc.exp.X_add_number, data_type, 0);
2919               if (value == (int) FAIL)
2920                 {
2921                   if (data_type < 30)
2922                     sprintf (err_msg,
2923                              _("invalid constant: %d bit expression not in range %d..%d"),
2924                              score_df_range[data_type].bits,
2925                              score_df_range[data_type].range[0], score_df_range[data_type].range[1]);
2926                   else
2927                     sprintf (err_msg,
2928                              _("invalid constant: %d bit expression not in range %d..%d"),
2929                              score_df_range[data_type - 24].bits,
2930                              score_df_range[data_type - 24].range[0],
2931                              score_df_range[data_type - 24].range[1]);
2932                   inst.error = err_msg;
2933                   return;
2934                 }
2935 
2936               value &= (1 << score_df_range[data_type].bits) - 1;
2937               ldst_idx = inst.instruction & OPC_PSEUDOLDST_MASK;
2938               inst.instruction &= ~OPC_PSEUDOLDST_MASK;
2939               inst.instruction |= score_ldst_insns[ldst_idx * 3 + pre_inc].value;
2940               if (pre_inc == 1)
2941                 inst.instruction |= value << 3;
2942               else
2943                 inst.instruction |= value;
2944 
2945               /* lw rD, [rA, simm15]  */
2946               if ((inst.instruction & 0x3e000000) == 0x20000000)
2947                 {
2948                   /* Both rD and rA are in [r0 - r15].  */
2949                   if ((((inst.instruction >> 15) & 0x10) == 0)
2950                       && (((inst.instruction >> 20) & 0x10) == 0))
2951                     {
2952                       /* simm15 = 0, lw -> lw!.  */
2953                       if ((inst.instruction & 0x7fff) == 0)
2954                         {
2955                           inst.relax_inst |= (((inst.instruction >> 15) & 0xf) << 4)
2956                             | (((inst.instruction >> 20) & 0xf) << 8);
2957                           inst.relax_size = 2;
2958                         }
2959                       /* rA = r2, lw -> lwp!.  */
2960                       else if ((((inst.instruction >> 15) & 0xf) == 2)
2961                                && ((inst.instruction & 0x3) == 0)
2962                                && ((inst.instruction & 0x7fff) < 128))
2963                         {
2964                           inst.relax_inst = 0x7000 | (((inst.instruction >> 20) & 0xf) << 8)
2965                             | (((inst.instruction & 0x7fff) >> 2) << 3);
2966                           inst.relax_size = 2;
2967                         }
2968                       else
2969                         {
2970                           inst.relax_inst = 0x8000;
2971                         }
2972                     }
2973                   else
2974                     {
2975                       inst.relax_inst = 0x8000;
2976                     }
2977                 }
2978               /* sw rD, [rA, simm15]  */
2979               else if ((inst.instruction & 0x3e000000) == 0x28000000)
2980                 {
2981                   /* Both rD and rA are in [r0 - r15].  */
2982                   if ((((inst.instruction >> 15) & 0x10) == 0) && (((inst.instruction >> 20) & 0x10) == 0))
2983                     {
2984                       /* simm15 = 0, sw -> sw!.  */
2985                       if ((inst.instruction & 0x7fff) == 0)
2986                         {
2987                           inst.relax_inst |= (((inst.instruction >> 15) & 0xf) << 4)
2988                             | (((inst.instruction >> 20) & 0xf) << 8);
2989                           inst.relax_size = 2;
2990                         }
2991                       /* rA = r2, sw -> swp!.  */
2992                       else if ((((inst.instruction >> 15) & 0xf) == 2)
2993                                && ((inst.instruction & 0x3) == 0)
2994                                && ((inst.instruction & 0x7fff) < 128))
2995                         {
2996                           inst.relax_inst = 0x7004 | (((inst.instruction >> 20) & 0xf) << 8)
2997                             | (((inst.instruction & 0x7fff) >> 2) << 3);
2998                           inst.relax_size = 2;
2999                         }
3000                       else
3001                         {
3002                           inst.relax_inst = 0x8000;
3003                         }
3004                     }
3005                   else
3006                     {
3007                       inst.relax_inst = 0x8000;
3008                     }
3009                 }
3010               /* sw rD, [rA, simm15]+    sw pre.  */
3011               else if ((inst.instruction & 0x3e000007) == 0x06000004)
3012                 {
3013                   /* rA is in [r0 - r7], and simm15 = -4.  */
3014                   if ((((inst.instruction >> 15) & 0x18) == 0)
3015                       && (((inst.instruction >> 3) & 0xfff) == 0xffc))
3016                     {
3017                       /* sw -> pushhi!.  */
3018                       if ((((inst.instruction >> 20) & 0x10) == 0x10))
3019                         {
3020                           inst.relax_inst = 0x0000200e | (((inst.instruction >> 20) & 0xf) << 8)
3021                             | 1 << 7 | (((inst.instruction >> 15) & 0x7) << 4);
3022                           inst.relax_size = 2;
3023                         }
3024                       /* sw -> push!.  */
3025                       else
3026                         {
3027                           inst.relax_inst = 0x0000200e | (((inst.instruction >> 20) & 0xf) << 8)
3028                             | 0 << 7 | (((inst.instruction >> 15) & 0x7) << 4);
3029                           inst.relax_size = 2;
3030                         }
3031                     }
3032                   else
3033                     {
3034                       inst.relax_inst = 0x8000;
3035                     }
3036                 }
3037               /* lh rD, [rA, simm15]  */
3038               else if ((inst.instruction & 0x3e000000) == 0x22000000)
3039                 {
3040                   /* Both rD and rA are in [r0 - r15].  */
3041                   if ((((inst.instruction >> 15) & 0x10) == 0) && (((inst.instruction >> 20) & 0x10) == 0))
3042                     {
3043                       /* simm15 = 0, lh -> lh!.  */
3044                       if ((inst.instruction & 0x7fff) == 0)
3045                         {
3046                           inst.relax_inst |= (((inst.instruction >> 15) & 0xf) << 4)
3047                             | (((inst.instruction >> 20) & 0xf) << 8);
3048                           inst.relax_size = 2;
3049                         }
3050                       /* rA = r2, lh -> lhp!.  */
3051                       else if ((((inst.instruction >> 15) & 0xf) == 2)
3052                                && ((inst.instruction & 0x1) == 0)
3053                                && ((inst.instruction & 0x7fff) < 64))
3054                         {
3055                           inst.relax_inst = 0x7001 | (((inst.instruction >> 20) & 0xf) << 8)
3056                             | (((inst.instruction & 0x7fff) >> 1) << 3);
3057                           inst.relax_size = 2;
3058                         }
3059                       else
3060                         {
3061                           inst.relax_inst = 0x8000;
3062                         }
3063                     }
3064                   else
3065                     {
3066                       inst.relax_inst = 0x8000;
3067                     }
3068                 }
3069               /* sh rD, [rA, simm15]  */
3070               else if ((inst.instruction & 0x3e000000) == 0x2a000000)
3071                 {
3072                   /* Both rD and rA are in [r0 - r15].  */
3073                   if ((((inst.instruction >> 15) & 0x10) == 0) && (((inst.instruction >> 20) & 0x10) == 0))
3074                     {
3075                       /* simm15 = 0, sh -> sh!.  */
3076                       if ((inst.instruction & 0x7fff) == 0)
3077                         {
3078                           inst.relax_inst |= (((inst.instruction >> 15) & 0xf) << 4)
3079                             | (((inst.instruction >> 20) & 0xf) << 8);
3080                           inst.relax_size = 2;
3081                         }
3082                       /* rA = r2, sh -> shp!.  */
3083                       else if ((((inst.instruction >> 15) & 0xf) == 2)
3084                                && ((inst.instruction & 0x1) == 0)
3085                                && ((inst.instruction & 0x7fff) < 64))
3086                         {
3087                           inst.relax_inst = 0x7005 | (((inst.instruction >> 20) & 0xf) << 8)
3088                             | (((inst.instruction & 0x7fff) >> 1) << 3);
3089                           inst.relax_size = 2;
3090                         }
3091                       else
3092                         {
3093                           inst.relax_inst = 0x8000;
3094                         }
3095                     }
3096                   else
3097                     {
3098                       inst.relax_inst = 0x8000;
3099                     }
3100                 }
3101               /* lbu rD, [rA, simm15]  */
3102               else if ((inst.instruction & 0x3e000000) == 0x2c000000)
3103                 {
3104                   /* Both rD and rA are in [r0 - r15].  */
3105                   if ((((inst.instruction >> 15) & 0x10) == 0) && (((inst.instruction >> 20) & 0x10) == 0))
3106                     {
3107                       /* simm15 = 0, lbu -> lbu!.  */
3108                       if ((inst.instruction & 0x7fff) == 0)
3109                         {
3110                           inst.relax_inst |= (((inst.instruction >> 15) & 0xf) << 4)
3111                             | (((inst.instruction >> 20) & 0xf) << 8);
3112                           inst.relax_size = 2;
3113                         }
3114                       /* rA = r2, lbu -> lbup!.  */
3115                       else if ((((inst.instruction >> 15) & 0xf) == 2)
3116                                && ((inst.instruction & 0x7fff) < 32))
3117                         {
3118                           inst.relax_inst = 0x7003 | (((inst.instruction >> 20) & 0xf) << 8)
3119                             | ((inst.instruction & 0x7fff) << 3);
3120                           inst.relax_size = 2;
3121                         }
3122                       else
3123                         {
3124                           inst.relax_inst = 0x8000;
3125                         }
3126                     }
3127                   else
3128                     {
3129                       inst.relax_inst = 0x8000;
3130                     }
3131                 }
3132               /* sb rD, [rA, simm15]  */
3133               else if ((inst.instruction & 0x3e000000) == 0x2e000000)
3134                 {
3135                   /* Both rD and rA are in [r0 - r15].  */
3136                   if ((((inst.instruction >> 15) & 0x10) == 0) && (((inst.instruction >> 20) & 0x10) == 0))
3137                     {
3138                       /* simm15 = 0, sb -> sb!.  */
3139                       if ((inst.instruction & 0x7fff) == 0)
3140                         {
3141                           inst.relax_inst |= (((inst.instruction >> 15) & 0xf) << 4)
3142                             | (((inst.instruction >> 20) & 0xf) << 8);
3143                           inst.relax_size = 2;
3144                         }
3145                       /* rA = r2, sb -> sb!.  */
3146                       else if ((((inst.instruction >> 15) & 0xf) == 2)
3147                                && ((inst.instruction & 0x7fff) < 32))
3148                         {
3149                           inst.relax_inst = 0x7007 | (((inst.instruction >> 20) & 0xf) << 8)
3150                             | ((inst.instruction & 0x7fff) << 3);
3151                           inst.relax_size = 2;
3152                         }
3153                       else
3154                         {
3155                           inst.relax_inst = 0x8000;
3156                         }
3157                     }
3158                   else
3159                     {
3160                       inst.relax_inst = 0x8000;
3161                     }
3162                 }
3163               else
3164                 {
3165                   inst.relax_inst = 0x8000;
3166                 }
3167 
3168               return;
3169             }
3170           else
3171             {
3172               /* FIXME: may set error, for there is no ld/sw rD, [rA, label] */
3173               inst.reloc.pc_rel = 0;
3174             }
3175         }
3176     }
3177   else
3178     {
3179       inst.error = BAD_ARGS;
3180     }
3181 }
3182 
3183 /* Handle cache.  */
3184 
3185 static void
3186 do_cache (char *str)
3187 {
3188   skip_whitespace (str);
3189 
3190   if ((data_op2 (&str, 20, _IMM5) == (int) FAIL) || (skip_past_comma (&str) == (int) FAIL))
3191     {
3192       return;
3193     }
3194   else
3195     {
3196       int cache_op;
3197 
3198       cache_op = (inst.instruction >> 20) & 0x1F;
3199       sprintf (inst.name, "cache %d", cache_op);
3200     }
3201 
3202   if (*str == '[')
3203     {
3204       str++;
3205       skip_whitespace (str);
3206 
3207       if (reg_required_here (&str, 15, REG_TYPE_SCORE) == (int) FAIL)
3208 	return;
3209 
3210       skip_whitespace (str);
3211 
3212       /* cache op, [rA]  */
3213       if (skip_past_comma (&str) == (int) FAIL)
3214         {
3215           SET_INSN_ERROR (NULL);
3216           if (*str != ']')
3217             {
3218               inst.error = _("missing ]");
3219               return;
3220             }
3221           str++;
3222         }
3223       /* cache op, [rA, simm15]  */
3224       else
3225         {
3226           if (exp_ldst_offset (&str, 0, _SIMM15) == (int) FAIL)
3227             {
3228               return;
3229             }
3230 
3231           skip_whitespace (str);
3232           if (*str++ != ']')
3233             {
3234               inst.error = _("missing ]");
3235               return;
3236             }
3237         }
3238 
3239       if (end_of_line (str) == (int) FAIL)
3240 	return;
3241     }
3242   else
3243     {
3244       inst.error = BAD_ARGS;
3245     }
3246 }
3247 
3248 static void
3249 do_crdcrscrsimm5 (char *str)
3250 {
3251   char *strbak;
3252 
3253   strbak = str;
3254   skip_whitespace (str);
3255 
3256   if (reg_required_here (&str, 20, REG_TYPE_SCORE_CR) == (int) FAIL
3257       || skip_past_comma (&str) == (int) FAIL
3258       || reg_required_here (&str, 15, REG_TYPE_SCORE_CR) == (int) FAIL
3259       || skip_past_comma (&str) == (int) FAIL
3260       || reg_required_here (&str, 10, REG_TYPE_SCORE_CR) == (int) FAIL
3261       || skip_past_comma (&str) == (int) FAIL)
3262     {
3263       str = strbak;
3264       /* cop1 cop_code20.  */
3265       if (data_op2 (&str, 5, _IMM20) == (int) FAIL)
3266 	return;
3267     }
3268   else
3269     {
3270       if (data_op2 (&str, 5, _IMM5) == (int) FAIL)
3271 	return;
3272     }
3273 
3274   end_of_line (str);
3275 }
3276 
3277 /* Handle ldc/stc.  */
3278 static void
3279 do_ldst_cop (char *str)
3280 {
3281   skip_whitespace (str);
3282 
3283   if ((reg_required_here (&str, 15, REG_TYPE_SCORE_CR) == (int) FAIL)
3284       || (skip_past_comma (&str) == (int) FAIL))
3285     return;
3286 
3287   if (*str == '[')
3288     {
3289       str++;
3290       skip_whitespace (str);
3291 
3292       if (reg_required_here (&str, 20, REG_TYPE_SCORE) == (int) FAIL)
3293 	return;
3294 
3295       skip_whitespace (str);
3296 
3297       if (*str++ != ']')
3298         {
3299           if (exp_ldst_offset (&str, 5, _IMM10_RSHIFT_2) == (int) FAIL)
3300 	    return;
3301 
3302           skip_whitespace (str);
3303           if (*str++ != ']')
3304             {
3305               inst.error = _("missing ]");
3306               return;
3307             }
3308         }
3309 
3310       end_of_line (str);
3311     }
3312   else
3313     inst.error = BAD_ARGS;
3314 }
3315 
3316 static void
3317 do16_ldst_insn (char *str)
3318 {
3319   skip_whitespace (str);
3320 
3321   if ((reglow_required_here (&str, 8) == (int) FAIL) || (skip_past_comma (&str) == (int) FAIL))
3322     return;
3323 
3324   if (*str == '[')
3325     {
3326       int reg;
3327 
3328       str++;
3329       skip_whitespace (str);
3330 
3331       if ((reg = reglow_required_here (&str, 4)) == (int) FAIL)
3332 	return;
3333 
3334       skip_whitespace (str);
3335       if (*str++ == ']')
3336         {
3337           if (end_of_line (str) == (int) FAIL)
3338 	    return;
3339           else
3340             {
3341               inst.relax_inst |= (((inst.instruction >> 8) & 0xf) << 20)
3342                               | (((inst.instruction >> 4) & 0xf) << 15);
3343 	      inst.relax_size = 4;
3344             }
3345         }
3346       else
3347         {
3348           inst.error = _("missing ]");
3349         }
3350     }
3351   else
3352     {
3353       inst.error = BAD_ARGS;
3354     }
3355 }
3356 
3357 /* Handle lbup!/lhp!/ldiu!/lwp!/sbp!/shp!/swp!.  */
3358 static void
3359 do16_ldst_imm_insn (char *str)
3360 {
3361   char data_exp[MAX_LITERAL_POOL_SIZE];
3362   int reg_rd;
3363   char *dataptr = NULL, *pp = NULL;
3364   int cnt = 0;
3365   int assign_data = (int) FAIL;
3366   unsigned int ldst_func;
3367 
3368   skip_whitespace (str);
3369 
3370   if (((reg_rd = reglow_required_here (&str, 8)) == (int) FAIL)
3371       || (skip_past_comma (&str) == (int) FAIL))
3372     return;
3373 
3374   skip_whitespace (str);
3375   dataptr = str;
3376 
3377   while ((*dataptr != '\0') && (*dataptr != '|') && (cnt <= MAX_LITERAL_POOL_SIZE))
3378     {
3379       data_exp[cnt] = *dataptr;
3380       dataptr++;
3381       cnt++;
3382     }
3383 
3384   data_exp[cnt] = '\0';
3385   pp = &data_exp[0];
3386 
3387   str = dataptr;
3388 
3389   ldst_func = inst.instruction & LDST16_RI_MASK;
3390   if (ldst_func == N16_LIU)
3391     assign_data = exp_ldst_offset (&pp, 0, _IMM8);
3392   else if (ldst_func == N16_LHP || ldst_func == N16_SHP)
3393     assign_data = exp_ldst_offset (&pp, 3, _IMM5_RSHIFT_1);
3394   else if (ldst_func == N16_LWP || ldst_func == N16_SWP)
3395     assign_data = exp_ldst_offset (&pp, 3, _IMM5_RSHIFT_2);
3396   else
3397     assign_data = exp_ldst_offset (&pp, 3, _IMM5);
3398 
3399   if ((assign_data == (int) FAIL) || (end_of_line (pp) == (int) FAIL))
3400     return;
3401   else
3402     {
3403       if ((inst.instruction & 0x7000) == N16_LIU)
3404         {
3405           inst.relax_inst |= ((inst.instruction >> 8) & 0xf) << 20
3406                           | ((inst.instruction & 0xff) << 1);
3407         }
3408       else if (((inst.instruction & 0x7007) == N16_LHP)
3409                || ((inst.instruction & 0x7007) == N16_SHP))
3410         {
3411           inst.relax_inst |= ((inst.instruction >> 8) & 0xf) << 20 | 2 << 15
3412                           | (((inst.instruction >> 3) & 0x1f) << 1);
3413         }
3414       else if (((inst.instruction & 0x7007) == N16_LWP)
3415                || ((inst.instruction & 0x7007) == N16_SWP))
3416         {
3417           inst.relax_inst |= ((inst.instruction >> 8) & 0xf) << 20 | 2 << 15
3418                           | (((inst.instruction >> 3) & 0x1f) << 2);
3419         }
3420       else if (((inst.instruction & 0x7007) == N16_LBUP)
3421                || ((inst.instruction & 0x7007) == N16_SBP))
3422         {
3423           inst.relax_inst |= ((inst.instruction >> 8) & 0xf) << 20 | 2 << 15
3424                           | (((inst.instruction >> 3) & 0x1f));
3425         }
3426 
3427       inst.relax_size = 4;
3428     }
3429 }
3430 
3431 static void
3432 do16_push_pop (char *str)
3433 {
3434   int reg_rd;
3435   int H_bit_mask = 0;
3436 
3437   skip_whitespace (str);
3438   if (((reg_rd = reg_required_here (&str, 8, REG_TYPE_SCORE)) == (int) FAIL)
3439       || (skip_past_comma (&str) == (int) FAIL))
3440     return;
3441 
3442   if (reg_rd >= 16)
3443     H_bit_mask = 1;
3444 
3445   /* reg_required_here will change bit 12 of opcode, so we must restore bit 12.  */
3446   inst.instruction &= ~(1 << 12);
3447 
3448   inst.instruction |= H_bit_mask << 7;
3449 
3450   if (*str == '[')
3451     {
3452       int reg;
3453 
3454       str++;
3455       skip_whitespace (str);
3456       if ((reg = reg_required_here (&str, 4, REG_TYPE_SCORE)) == (int) FAIL)
3457 	return;
3458       else if (reg > 7)
3459         {
3460           if (!inst.error)
3461 	    inst.error = _("base register nums are over 3 bit");
3462 
3463           return;
3464         }
3465 
3466       skip_whitespace (str);
3467       if ((*str++ != ']') || (end_of_line (str) == (int) FAIL))
3468         {
3469           if (!inst.error)
3470 	    inst.error = _("missing ]");
3471 
3472           return;
3473         }
3474 
3475       /* pop! */
3476       if ((inst.instruction & 0xf) == 0xa)
3477         {
3478           if (H_bit_mask)
3479             {
3480               inst.relax_inst |= ((((inst.instruction >> 8) & 0xf) | 0x10) << 20)
3481                                   | (((inst.instruction >> 4) & 0x7) << 15) | (4 << 3);
3482             }
3483           else
3484             {
3485               inst.relax_inst |= (((inst.instruction >> 8) & 0xf) << 20)
3486                                   | (((inst.instruction >> 4) & 0x7) << 15) | (4 << 3);
3487             }
3488         }
3489       /* push! */
3490       else
3491         {
3492           if (H_bit_mask)
3493             {
3494               inst.relax_inst |= ((((inst.instruction >> 8) & 0xf) | 0x10) << 20)
3495                                   | (((inst.instruction >> 4) & 0x7) << 15) | (((-4) & 0xfff) << 3);
3496             }
3497           else
3498             {
3499               inst.relax_inst |= (((inst.instruction >> 8) & 0xf) << 20)
3500                                   | (((inst.instruction >> 4) & 0x7) << 15) | (((-4) & 0xfff) << 3);
3501             }
3502         }
3503       inst.relax_size = 4;
3504     }
3505   else
3506     {
3507       inst.error = BAD_ARGS;
3508     }
3509 }
3510 
3511 /* Handle lcb/lcw/lce/scb/scw/sce.  */
3512 static void
3513 do_ldst_unalign (char *str)
3514 {
3515   int conflict_reg;
3516 
3517   if (university_version == 1)
3518     {
3519       inst.error = ERR_FOR_SCORE5U_ATOMIC;
3520       return;
3521     }
3522 
3523   skip_whitespace (str);
3524 
3525   /* lcb/scb [rA]+.  */
3526   if (*str == '[')
3527     {
3528       str++;
3529       skip_whitespace (str);
3530 
3531       if (reg_required_here (&str, 15, REG_TYPE_SCORE) == (int) FAIL)
3532 	return;
3533 
3534       if (*str++ == ']')
3535         {
3536           if (*str++ != '+')
3537             {
3538               inst.error = _("missing +");
3539               return;
3540             }
3541         }
3542       else
3543         {
3544           inst.error = _("missing ]");
3545           return;
3546         }
3547 
3548       if (end_of_line (str) == (int) FAIL)
3549 	return;
3550     }
3551   /* lcw/lce/scb/sce rD, [rA]+.  */
3552   else
3553     {
3554       if (((conflict_reg = reg_required_here (&str, 20, REG_TYPE_SCORE)) == (int) FAIL)
3555           || (skip_past_comma (&str) == (int) FAIL))
3556         {
3557           return;
3558         }
3559 
3560       skip_whitespace (str);
3561       if (*str++ == '[')
3562         {
3563           int reg;
3564 
3565           skip_whitespace (str);
3566           if ((reg = reg_required_here (&str, 15, REG_TYPE_SCORE)) == (int) FAIL)
3567             {
3568               return;
3569             }
3570 
3571           /* Conflicts can occur on stores as well as loads.  */
3572           conflict_reg = (conflict_reg == reg);
3573           skip_whitespace (str);
3574           if (*str++ == ']')
3575             {
3576               unsigned int ldst_func = inst.instruction & LDST_UNALIGN_MASK;
3577 
3578               if (*str++ == '+')
3579                 {
3580                   if (conflict_reg)
3581                     {
3582                       as_warn (_("%s register same as write-back base"),
3583                                ((ldst_func & UA_LCE) || (ldst_func & UA_LCW)
3584                                 ? _("destination") : _("source")));
3585                     }
3586                 }
3587               else
3588                 {
3589                   inst.error = _("missing +");
3590                   return;
3591                 }
3592 
3593               if (end_of_line (str) == (int) FAIL)
3594 		return;
3595             }
3596           else
3597             {
3598               inst.error = _("missing ]");
3599               return;
3600             }
3601         }
3602       else
3603         {
3604           inst.error = BAD_ARGS;
3605           return;
3606         }
3607     }
3608 }
3609 
3610 /* Handle alw/asw.  */
3611 static void
3612 do_ldst_atomic (char *str)
3613 {
3614   if (university_version == 1)
3615     {
3616       inst.error = ERR_FOR_SCORE5U_ATOMIC;
3617       return;
3618     }
3619 
3620   skip_whitespace (str);
3621 
3622   if ((reg_required_here (&str, 20, REG_TYPE_SCORE) == (int) FAIL)
3623       || (skip_past_comma (&str) == (int) FAIL))
3624     {
3625       return;
3626     }
3627   else
3628     {
3629 
3630       skip_whitespace (str);
3631       if (*str++ == '[')
3632         {
3633           int reg;
3634 
3635           skip_whitespace (str);
3636           if ((reg = reg_required_here (&str, 15, REG_TYPE_SCORE)) == (int) FAIL)
3637             {
3638               return;
3639             }
3640 
3641           skip_whitespace (str);
3642           if (*str++ != ']')
3643             {
3644               inst.error = _("missing ]");
3645               return;
3646             }
3647 
3648           end_of_line (str);
3649         }
3650       else
3651 	inst.error = BAD_ARGS;
3652     }
3653 }
3654 
3655 static void
3656 build_relax_frag (struct score_it fix_insts[RELAX_INST_NUM], int fix_num ATTRIBUTE_UNUSED,
3657                   struct score_it var_insts[RELAX_INST_NUM], int var_num,
3658                   symbolS *add_symbol)
3659 {
3660   int i;
3661   char *p;
3662   fixS *fixp = NULL;
3663   fixS *cur_fixp = NULL;
3664   long where;
3665   struct score_it inst_main;
3666 
3667   memcpy (&inst_main, &fix_insts[0], sizeof (struct score_it));
3668 
3669   /* Adjust instruction opcode and to be relaxed instruction opcode.  */
3670   inst_main.instruction = adjust_paritybit (inst_main.instruction, GET_INSN_CLASS (inst_main.type));
3671   inst_main.type = Insn_PIC;
3672 
3673   for (i = 0; i < var_num; i++)
3674     {
3675       inst_main.relax_size += var_insts[i].size;
3676       var_insts[i].instruction = adjust_paritybit (var_insts[i].instruction,
3677                                                    GET_INSN_CLASS (var_insts[i].type));
3678     }
3679 
3680   /* Check data dependency.  */
3681   handle_dependency (&inst_main);
3682 
3683   /* Start a new frag if frag_now is not empty.  */
3684   if (frag_now_fix () != 0)
3685     {
3686       if (!frag_now->tc_frag_data.is_insn)
3687 	{
3688           frag_wane (frag_now);
3689 	}
3690       frag_new (0);
3691     }
3692   frag_grow (20);
3693 
3694   /* Write fr_fix part.  */
3695   p = frag_more (inst_main.size);
3696   md_number_to_chars (p, inst_main.instruction, inst_main.size);
3697 
3698   if (inst_main.reloc.type != BFD_RELOC_NONE)
3699     fixp = fix_new_score (frag_now, p - frag_now->fr_literal, inst_main.size,
3700 			  &inst_main.reloc.exp, inst_main.reloc.pc_rel, inst_main.reloc.type);
3701 
3702   frag_now->tc_frag_data.fixp = fixp;
3703   cur_fixp = frag_now->tc_frag_data.fixp;
3704 
3705 #ifdef OBJ_ELF
3706   dwarf2_emit_insn (inst_main.size);
3707 #endif
3708 
3709   where = p - frag_now->fr_literal + inst_main.size;
3710   for (i = 0; i < var_num; i++)
3711     {
3712       if (i > 0)
3713         where += var_insts[i - 1].size;
3714 
3715       if (var_insts[i].reloc.type != BFD_RELOC_NONE)
3716         {
3717           fixp = fix_new_score (frag_now, where, var_insts[i].size,
3718                                 &var_insts[i].reloc.exp, var_insts[i].reloc.pc_rel,
3719                                 var_insts[i].reloc.type);
3720           if (fixp)
3721             {
3722               if (cur_fixp)
3723                 {
3724                   cur_fixp->fx_next = fixp;
3725                   cur_fixp = cur_fixp->fx_next;
3726                 }
3727               else
3728                 {
3729                   frag_now->tc_frag_data.fixp = fixp;
3730                   cur_fixp = frag_now->tc_frag_data.fixp;
3731                 }
3732 	    }
3733         }
3734     }
3735 
3736   p = frag_var (rs_machine_dependent, inst_main.relax_size + RELAX_PAD_BYTE, 0,
3737                 RELAX_ENCODE (inst_main.size, inst_main.relax_size, inst_main.type,
3738                 0, inst_main.size, 0), add_symbol, 0, NULL);
3739 
3740   /* Write fr_var part.
3741      no calling gen_insn_frag, no fixS will be generated.  */
3742   for (i = 0; i < var_num; i++)
3743     {
3744       md_number_to_chars (p, var_insts[i].instruction, var_insts[i].size);
3745       p += var_insts[i].size;
3746     }
3747   /* Set bwarn as -1, so macro instruction itself will not be generated frag.  */
3748   inst.bwarn = -1;
3749 }
3750 
3751 /* Build a relax frag for la instruction when generating PIC,
3752    external symbol first and local symbol second.  */
3753 
3754 static void
3755 build_la_pic (int reg_rd, expressionS exp)
3756 {
3757   symbolS *add_symbol = exp.X_add_symbol;
3758   offsetT add_number = exp.X_add_number;
3759   struct score_it fix_insts[RELAX_INST_NUM];
3760   struct score_it var_insts[RELAX_INST_NUM];
3761   int fix_num = 0;
3762   int var_num = 0;
3763   char tmp[MAX_LITERAL_POOL_SIZE];
3764   int r1_bak;
3765 
3766   r1_bak = nor1;
3767   nor1 = 0;
3768 
3769   if (add_number == 0)
3770     {
3771       fix_num = 1;
3772       var_num = 2;
3773 
3774       /* For an external symbol, only one insn is generated;
3775          For a local symbol, two insns are generated.  */
3776       /* Fix part
3777          For an external symbol: lw rD, <sym>($gp)
3778                                  (BFD_RELOC_SCORE_GOT15 or BFD_RELOC_SCORE_CALL15)  */
3779       sprintf (tmp, "lw_pic r%d, %s", reg_rd, add_symbol->bsym->name);
3780       if (append_insn (tmp, FALSE) == (int) FAIL)
3781 	return;
3782 
3783       if (reg_rd == PIC_CALL_REG)
3784         inst.reloc.type = BFD_RELOC_SCORE_CALL15;
3785       memcpy (&fix_insts[0], &inst, sizeof (struct score_it));
3786 
3787       /* Var part
3788 	 For a local symbol :
3789          lw rD, <sym>($gp)    (BFD_RELOC_SCORE_GOT15)
3790 	 addi rD, <sym>       (BFD_RELOC_GOT_LO16) */
3791       inst.reloc.type = BFD_RELOC_SCORE_GOT15;
3792       memcpy (&var_insts[0], &inst, sizeof (struct score_it));
3793       sprintf (tmp, "addi_s_pic r%d, %s", reg_rd, add_symbol->bsym->name);
3794       if (append_insn (tmp, FALSE) == (int) FAIL)
3795 	return;
3796 
3797       memcpy (&var_insts[1], &inst, sizeof (struct score_it));
3798       build_relax_frag (fix_insts, fix_num, var_insts, var_num, add_symbol);
3799     }
3800   else if (add_number >= -0x8000 && add_number <= 0x7fff)
3801     {
3802       /* Insn 1: lw rD, <sym>($gp)    (BFD_RELOC_SCORE_GOT15)  */
3803       sprintf (tmp, "lw_pic r%d, %s", reg_rd, add_symbol->bsym->name);
3804       if (append_insn (tmp, TRUE) == (int) FAIL)
3805 	return;
3806 
3807       /* Insn 2  */
3808       fix_num = 1;
3809       var_num = 1;
3810       /* Fix part
3811          For an external symbol: addi rD, <constant> */
3812       sprintf (tmp, "addi r%d, %d", reg_rd, (int)add_number);
3813       if (append_insn (tmp, FALSE) == (int) FAIL)
3814 	return;
3815 
3816       memcpy (&fix_insts[0], &inst, sizeof (struct score_it));
3817 
3818       /* Var part
3819  	 For a local symbol: addi rD, <sym>+<constant>    (BFD_RELOC_GOT_LO16)  */
3820       sprintf (tmp, "addi_s_pic r%d, %s + %d", reg_rd, add_symbol->bsym->name, (int)add_number);
3821       if (append_insn (tmp, FALSE) == (int) FAIL)
3822 	return;
3823 
3824       memcpy (&var_insts[0], &inst, sizeof (struct score_it));
3825       build_relax_frag (fix_insts, fix_num, var_insts, var_num, add_symbol);
3826     }
3827   else
3828     {
3829       int hi = (add_number >> 16) & 0x0000FFFF;
3830       int lo = add_number & 0x0000FFFF;
3831 
3832       /* Insn 1: lw rD, <sym>($gp)    (BFD_RELOC_SCORE_GOT15)  */
3833       sprintf (tmp, "lw_pic r%d, %s", reg_rd, add_symbol->bsym->name);
3834       if (append_insn (tmp, TRUE) == (int) FAIL)
3835 	return;
3836 
3837       /* Insn 2  */
3838       fix_num = 1;
3839       var_num = 1;
3840       /* Fix part
3841 	 For an external symbol: ldis r1, HI%<constant>  */
3842       sprintf (tmp, "ldis r1, %d", hi);
3843       if (append_insn (tmp, FALSE) == (int) FAIL)
3844 	return;
3845 
3846       memcpy (&fix_insts[0], &inst, sizeof (struct score_it));
3847 
3848       /* Var part
3849 	 For a local symbol: ldis r1, HI%<constant>
3850          but, if lo is outof 16 bit, make hi plus 1  */
3851       if ((lo < -0x8000) || (lo > 0x7fff))
3852 	{
3853 	  hi += 1;
3854 	}
3855       sprintf (tmp, "ldis_pic r1, %d", hi);
3856       if (append_insn (tmp, FALSE) == (int) FAIL)
3857 	return;
3858 
3859       memcpy (&var_insts[0], &inst, sizeof (struct score_it));
3860       build_relax_frag (fix_insts, fix_num, var_insts, var_num, add_symbol);
3861 
3862       /* Insn 3  */
3863       fix_num = 1;
3864       var_num = 1;
3865       /* Fix part
3866 	 For an external symbol: ori r1, LO%<constant>  */
3867       sprintf (tmp, "ori r1, %d", lo);
3868       if (append_insn (tmp, FALSE) == (int) FAIL)
3869 	return;
3870 
3871       memcpy (&fix_insts[0], &inst, sizeof (struct score_it));
3872 
3873       /* Var part
3874   	 For a local symbol: addi r1, <sym>+LO%<constant>    (BFD_RELOC_GOT_LO16)  */
3875       sprintf (tmp, "addi_u_pic r1, %s + %d", add_symbol->bsym->name, lo);
3876       if (append_insn (tmp, FALSE) == (int) FAIL)
3877 	return;
3878 
3879       memcpy (&var_insts[0], &inst, sizeof (struct score_it));
3880       build_relax_frag (fix_insts, fix_num, var_insts, var_num, add_symbol);
3881 
3882       /* Insn 4: add rD, rD, r1  */
3883       sprintf (tmp, "add r%d, r%d, r1", reg_rd, reg_rd);
3884       if (append_insn (tmp, TRUE) == (int) FAIL)
3885 	return;
3886 
3887      /* Set bwarn as -1, so macro instruction itself will not be generated frag.  */
3888      inst.bwarn = -1;
3889     }
3890 
3891   nor1 = r1_bak;
3892 }
3893 
3894 /* Handle la.  */
3895 static void
3896 do_macro_la_rdi32 (char *str)
3897 {
3898   int reg_rd;
3899 
3900   skip_whitespace (str);
3901   if ((reg_rd = reg_required_here (&str, 20, REG_TYPE_SCORE)) == (int) FAIL
3902       || skip_past_comma (&str) == (int) FAIL)
3903     {
3904       return;
3905     }
3906   else
3907     {
3908       char append_str[MAX_LITERAL_POOL_SIZE];
3909       char *keep_data = str;
3910 
3911       /* la rd, simm16.  */
3912       if (data_op2 (&str, 1, _SIMM16_LA) != (int) FAIL)
3913         {
3914           end_of_line (str);
3915           return;
3916         }
3917       /* la rd, imm32 or la rd, label.  */
3918       else
3919         {
3920           SET_INSN_ERROR (NULL);
3921           str = keep_data;
3922           if ((data_op2 (&str, 1, _VALUE_HI16) == (int) FAIL)
3923               || (end_of_line (str) == (int) FAIL))
3924             {
3925               return;
3926             }
3927           else
3928             {
3929               if ((score_pic == NO_PIC) || (!inst.reloc.exp.X_add_symbol))
3930                 {
3931                   sprintf (append_str, "ld_i32hi r%d, %s", reg_rd, keep_data);
3932                   if (append_insn (append_str, TRUE) == (int) FAIL)
3933 		    return;
3934 
3935                   sprintf (append_str, "ld_i32lo r%d, %s", reg_rd, keep_data);
3936                   if (append_insn (append_str, TRUE) == (int) FAIL)
3937 		    return;
3938 		}
3939 	      else
3940 		{
3941 		  assert (inst.reloc.exp.X_add_symbol);
3942 		  build_la_pic (reg_rd, inst.reloc.exp);
3943 		}
3944 
3945               /* Set bwarn as -1, so macro instruction itself will not be generated frag.  */
3946               inst.bwarn = -1;
3947             }
3948         }
3949     }
3950 }
3951 
3952 /* Handle li.  */
3953 static void
3954 do_macro_li_rdi32 (char *str){
3955 
3956   int reg_rd;
3957 
3958   skip_whitespace (str);
3959   if ((reg_rd = reg_required_here (&str, 20, REG_TYPE_SCORE)) == (int) FAIL
3960       || skip_past_comma (&str) == (int) FAIL)
3961     {
3962       return;
3963     }
3964   else
3965     {
3966       char *keep_data = str;
3967 
3968       /* li rd, simm16.  */
3969       if (data_op2 (&str, 1, _SIMM16_LA) != (int) FAIL)
3970         {
3971           end_of_line (str);
3972           return;
3973         }
3974       /* li rd, imm32.  */
3975       else
3976         {
3977           char append_str[MAX_LITERAL_POOL_SIZE];
3978 
3979           str = keep_data;
3980 
3981           if ((data_op2 (&str, 1, _VALUE_HI16) == (int) FAIL)
3982               || (end_of_line (str) == (int) FAIL))
3983             {
3984               return;
3985             }
3986           else if (inst.reloc.exp.X_add_symbol)
3987             {
3988               inst.error = _("li rd label isn't correct instruction form");
3989               return;
3990             }
3991           else
3992             {
3993               sprintf (append_str, "ld_i32hi r%d, %s", reg_rd, keep_data);
3994 
3995               if (append_insn (append_str, TRUE) == (int) FAIL)
3996 		return;
3997               else
3998                 {
3999                   sprintf (append_str, "ld_i32lo r%d, %s", reg_rd, keep_data);
4000                   if (append_insn (append_str, TRUE) == (int) FAIL)
4001 		    return;
4002 
4003                   /* Set bwarn as -1, so macro instruction itself will not be generated frag.  */
4004                   inst.bwarn = -1;
4005                 }
4006             }
4007         }
4008     }
4009 }
4010 
4011 /* Handle mul/mulu/div/divu/rem/remu.  */
4012 static void
4013 do_macro_mul_rdrsrs (char *str)
4014 {
4015   int reg_rd;
4016   int reg_rs1;
4017   int reg_rs2;
4018   char *backupstr;
4019   char append_str[MAX_LITERAL_POOL_SIZE];
4020 
4021   if (university_version == 1)
4022     as_warn ("%s", ERR_FOR_SCORE5U_MUL_DIV);
4023 
4024   strcpy (append_str, str);
4025   backupstr = append_str;
4026   skip_whitespace (backupstr);
4027   if (((reg_rd = reg_required_here (&backupstr, -1, REG_TYPE_SCORE)) == (int) FAIL)
4028       || (skip_past_comma (&backupstr) == (int) FAIL)
4029       || ((reg_rs1 = reg_required_here (&backupstr, -1, REG_TYPE_SCORE)) == (int) FAIL))
4030     {
4031       inst.error = BAD_ARGS;
4032       return;
4033     }
4034 
4035   if (skip_past_comma (&backupstr) == (int) FAIL)
4036     {
4037       /* rem/remu rA, rB is error format.  */
4038       if (strcmp (inst.name, "rem") == 0 || strcmp (inst.name, "remu") == 0)
4039         {
4040           SET_INSN_ERROR (BAD_ARGS);
4041         }
4042       else
4043         {
4044           SET_INSN_ERROR (NULL);
4045           do_rsrs (str);
4046         }
4047       return;
4048     }
4049   else
4050     {
4051       SET_INSN_ERROR (NULL);
4052       if (((reg_rs2 = reg_required_here (&backupstr, -1, REG_TYPE_SCORE)) == (int) FAIL)
4053           || (end_of_line (backupstr) == (int) FAIL))
4054         {
4055           return;
4056         }
4057       else
4058         {
4059           char append_str1[MAX_LITERAL_POOL_SIZE];
4060 
4061           if (strcmp (inst.name, "rem") == 0)
4062             {
4063               sprintf (append_str, "mul r%d, r%d", reg_rs1, reg_rs2);
4064               sprintf (append_str1, "mfceh  r%d", reg_rd);
4065             }
4066           else if (strcmp (inst.name, "remu") == 0)
4067             {
4068               sprintf (append_str, "mulu r%d, r%d", reg_rs1, reg_rs2);
4069               sprintf (append_str1, "mfceh  r%d", reg_rd);
4070             }
4071           else
4072             {
4073               sprintf (append_str, "%s r%d, r%d", inst.name, reg_rs1, reg_rs2);
4074               sprintf (append_str1, "mfcel  r%d", reg_rd);
4075             }
4076 
4077           /* Output mul/mulu or div/divu or rem/remu.  */
4078           if (append_insn (append_str, TRUE) == (int) FAIL)
4079 	    return;
4080 
4081           /* Output mfcel or mfceh.  */
4082           if (append_insn (append_str1, TRUE) == (int) FAIL)
4083 	    return;
4084 
4085           /* Set bwarn as -1, so macro instruction itself will not be generated frag.  */
4086           inst.bwarn = -1;
4087         }
4088     }
4089 }
4090 
4091 static void
4092 exp_macro_ldst_abs (char *str)
4093 {
4094   int reg_rd;
4095   char *backupstr, *tmp;
4096   char append_str[MAX_LITERAL_POOL_SIZE];
4097   char verifystr[MAX_LITERAL_POOL_SIZE];
4098   struct score_it inst_backup;
4099   int r1_bak = 0;
4100 
4101   r1_bak = nor1;
4102   nor1 = 0;
4103   memcpy (&inst_backup, &inst, sizeof (struct score_it));
4104 
4105   strcpy (verifystr, str);
4106   backupstr = verifystr;
4107   skip_whitespace (backupstr);
4108   if ((reg_rd = reg_required_here (&backupstr, -1, REG_TYPE_SCORE)) == (int) FAIL)
4109     return;
4110 
4111   tmp = backupstr;
4112   if (skip_past_comma (&backupstr) == (int) FAIL)
4113     return;
4114 
4115   backupstr = tmp;
4116   sprintf (append_str, "li r1  %s", backupstr);
4117   append_insn (append_str, TRUE);
4118 
4119   memcpy (&inst, &inst_backup, sizeof (struct score_it));
4120   sprintf (append_str, " r%d, [r1,0]", reg_rd);
4121   do_ldst_insn (append_str);
4122 
4123   nor1 = r1_bak;
4124 }
4125 
4126 static int
4127 nopic_need_relax (symbolS * sym, int before_relaxing)
4128 {
4129   if (sym == NULL)
4130     return 0;
4131   else if (USE_GLOBAL_POINTER_OPT && g_switch_value > 0)
4132     {
4133       const char *symname;
4134       const char *segname;
4135 
4136       /* Find out whether this symbol can be referenced off the $gp
4137          register.  It can be if it is smaller than the -G size or if
4138          it is in the .sdata or .sbss section.  Certain symbols can
4139          not be referenced off the $gp, although it appears as though
4140          they can.  */
4141       symname = S_GET_NAME (sym);
4142       if (symname != (const char *)NULL
4143           && (strcmp (symname, "eprol") == 0
4144               || strcmp (symname, "etext") == 0
4145               || strcmp (symname, "_gp") == 0
4146               || strcmp (symname, "edata") == 0
4147               || strcmp (symname, "_fbss") == 0
4148               || strcmp (symname, "_fdata") == 0
4149               || strcmp (symname, "_ftext") == 0
4150               || strcmp (symname, "end") == 0
4151               || strcmp (symname, GP_DISP_LABEL) == 0))
4152         {
4153           return 1;
4154         }
4155       else if ((!S_IS_DEFINED (sym) || S_IS_COMMON (sym)) && (0
4156       /* We must defer this decision until after the whole file has been read,
4157          since there might be a .extern after the first use of this symbol.  */
4158                || (before_relaxing
4159                    && S_GET_VALUE (sym) == 0)
4160                || (S_GET_VALUE (sym) != 0
4161                    && S_GET_VALUE (sym) <= g_switch_value)))
4162         {
4163           return 0;
4164         }
4165 
4166       segname = segment_name (S_GET_SEGMENT (sym));
4167       return (strcmp (segname, ".sdata") != 0
4168 	      && strcmp (segname, ".sbss") != 0
4169 	      && strncmp (segname, ".sdata.", 7) != 0
4170 	      && strncmp (segname, ".gnu.linkonce.s.", 16) != 0);
4171     }
4172   /* We are not optimizing for the $gp register.  */
4173   else
4174     return 1;
4175 }
4176 
4177 /* Build a relax frag for lw/st instruction when generating PIC,
4178    external symbol first and local symbol second.  */
4179 
4180 static void
4181 build_lwst_pic (int reg_rd, expressionS exp, const char *insn_name)
4182 {
4183   symbolS *add_symbol = exp.X_add_symbol;
4184   int add_number = exp.X_add_number;
4185   struct score_it fix_insts[RELAX_INST_NUM];
4186   struct score_it var_insts[RELAX_INST_NUM];
4187   int fix_num = 0;
4188   int var_num = 0;
4189   char tmp[MAX_LITERAL_POOL_SIZE];
4190   int r1_bak;
4191 
4192   r1_bak = nor1;
4193   nor1 = 0;
4194 
4195   if ((add_number == 0) || (add_number >= -0x8000 && add_number <= 0x7fff))
4196     {
4197       fix_num = 1;
4198       var_num = 2;
4199 
4200       /* For an external symbol, two insns are generated;
4201          For a local symbol, three insns are generated.  */
4202       /* Fix part
4203          For an external symbol: lw rD, <sym>($gp)
4204                                  (BFD_RELOC_SCORE_GOT15)  */
4205       sprintf (tmp, "lw_pic r1, %s", add_symbol->bsym->name);
4206       if (append_insn (tmp, FALSE) == (int) FAIL)
4207         return;
4208 
4209       memcpy (&fix_insts[0], &inst, sizeof (struct score_it));
4210 
4211       /* Var part
4212 	 For a local symbol :
4213          lw rD, <sym>($gp)    (BFD_RELOC_SCORE_GOT15)
4214 	 addi rD, <sym>       (BFD_RELOC_GOT_LO16) */
4215       inst.reloc.type = BFD_RELOC_SCORE_GOT15;
4216       memcpy (&var_insts[0], &inst, sizeof (struct score_it));
4217       sprintf (tmp, "addi_s_pic r1, %s", add_symbol->bsym->name);
4218       if (append_insn (tmp, FALSE) == (int) FAIL)
4219         return;
4220 
4221       memcpy (&var_insts[1], &inst, sizeof (struct score_it));
4222       build_relax_frag (fix_insts, fix_num, var_insts, var_num, add_symbol);
4223 
4224       /* Insn 2 or Insn 3: lw/st rD, [r1, constant]  */
4225       sprintf (tmp, "%s r%d, [r1, %d]", insn_name, reg_rd, add_number);
4226       if (append_insn (tmp, TRUE) == (int) FAIL)
4227         return;
4228 
4229       /* Set bwarn as -1, so macro instruction itself will not be generated frag.  */
4230       inst.bwarn = -1;
4231     }
4232   else
4233     {
4234       inst.error = _("PIC code offset overflow (max 16 signed bits)");
4235       return;
4236     }
4237 
4238   nor1 = r1_bak;
4239 }
4240 
4241 static void
4242 do_macro_ldst_label (char *str)
4243 {
4244   int i;
4245   int ldst_gp_p = 0;
4246   int reg_rd;
4247   int r1_bak;
4248   char *backup_str;
4249   char *label_str;
4250   char *absolute_value;
4251   char append_str[3][MAX_LITERAL_POOL_SIZE];
4252   char verifystr[MAX_LITERAL_POOL_SIZE];
4253   struct score_it inst_backup;
4254   struct score_it inst_expand[3];
4255   struct score_it inst_main;
4256 
4257   memcpy (&inst_backup, &inst, sizeof (struct score_it));
4258   strcpy (verifystr, str);
4259   backup_str = verifystr;
4260 
4261   skip_whitespace (backup_str);
4262   if ((reg_rd = reg_required_here (&backup_str, -1, REG_TYPE_SCORE)) == (int) FAIL)
4263     return;
4264 
4265   if (skip_past_comma (&backup_str) == (int) FAIL)
4266     return;
4267 
4268   label_str = backup_str;
4269 
4270   /* Ld/st rD, [rA, imm]      ld/st rD, [rA]+, imm      ld/st rD, [rA, imm]+.  */
4271   if (*backup_str == '[')
4272     {
4273       inst.type = Rd_rvalueRs_preSI12;
4274       do_ldst_insn (str);
4275       return;
4276     }
4277 
4278   /* Ld/st rD, imm.  */
4279   absolute_value = backup_str;
4280   inst.type = Rd_rvalueRs_SI15;
4281   if ((my_get_expression (&inst.reloc.exp, &backup_str) == (int) FAIL)
4282       || (validate_immediate (inst.reloc.exp.X_add_number, _VALUE, 0) == (int) FAIL)
4283       || (end_of_line (backup_str) == (int) FAIL))
4284     {
4285       return;
4286     }
4287   else
4288     {
4289       if (inst.reloc.exp.X_add_symbol == 0)
4290         {
4291           memcpy (&inst, &inst_backup, sizeof (struct score_it));
4292           exp_macro_ldst_abs (str);
4293           return;
4294         }
4295     }
4296 
4297   /* Ld/st rD, label.  */
4298   inst.type = Rd_rvalueRs_SI15;
4299   backup_str = absolute_value;
4300   if ((data_op2 (&backup_str, 1, _GP_IMM15) == (int) FAIL)
4301       || (end_of_line (backup_str) == (int) FAIL))
4302     {
4303       return;
4304     }
4305   else
4306     {
4307       if (inst.reloc.exp.X_add_symbol == 0)
4308         {
4309           if (!inst.error)
4310 	    inst.error = BAD_ARGS;
4311 
4312           return;
4313         }
4314 
4315       if (score_pic == PIC)
4316         {
4317           int ldst_idx = 0;
4318           ldst_idx = inst.instruction & OPC_PSEUDOLDST_MASK;
4319           build_lwst_pic (reg_rd, inst.reloc.exp, score_ldst_insns[ldst_idx * 3 + 0].template);
4320           return;
4321         }
4322       else
4323 	{
4324           if ((inst.reloc.exp.X_add_number <= 0x3fff)
4325                && (inst.reloc.exp.X_add_number >= -0x4000)
4326                && (!nopic_need_relax (inst.reloc.exp.X_add_symbol, 1)))
4327 	    {
4328               int ldst_idx = 0;
4329 
4330               /* Assign the real opcode.  */
4331               ldst_idx = inst.instruction & OPC_PSEUDOLDST_MASK;
4332               inst.instruction &= ~OPC_PSEUDOLDST_MASK;
4333               inst.instruction |= score_ldst_insns[ldst_idx * 3 + 0].value;
4334               inst.instruction |= reg_rd << 20;
4335               inst.instruction |= GP << 15;
4336               inst.relax_inst = 0x8000;
4337               inst.relax_size = 0;
4338               ldst_gp_p = 1;
4339 	    }
4340 	}
4341     }
4342 
4343   /* Backup inst.  */
4344   memcpy (&inst_main, &inst, sizeof (struct score_it));
4345   r1_bak = nor1;
4346   nor1 = 0;
4347 
4348   /* Determine which instructions should be output.  */
4349   sprintf (append_str[0], "ld_i32hi r1, %s", label_str);
4350   sprintf (append_str[1], "ld_i32lo r1, %s", label_str);
4351   sprintf (append_str[2], "%s r%d, [r1, 0]", inst_backup.name, reg_rd);
4352 
4353   /* Generate three instructions.
4354      la r1, label
4355      ld/st rd, [r1, 0]  */
4356   for (i = 0; i < 3; i++)
4357     {
4358       if (append_insn (append_str[i], FALSE) == (int) FAIL)
4359 	return;
4360 
4361       memcpy (&inst_expand[i], &inst, sizeof (struct score_it));
4362     }
4363 
4364   if (ldst_gp_p)
4365     {
4366       char *p;
4367 
4368       /* Adjust instruction opcode and to be relaxed instruction opcode.  */
4369       inst_main.instruction = adjust_paritybit (inst_main.instruction, GET_INSN_CLASS (inst_main.type));
4370       inst_main.relax_size = inst_expand[0].size + inst_expand[1].size + inst_expand[2].size;
4371       inst_main.type = Insn_GP;
4372 
4373       for (i = 0; i < 3; i++)
4374 	inst_expand[i].instruction = adjust_paritybit (inst_expand[i].instruction
4375 						       , GET_INSN_CLASS (inst_expand[i].type));
4376 
4377       /* Check data dependency.  */
4378       handle_dependency (&inst_main);
4379 
4380       /* Start a new frag if frag_now is not empty.  */
4381       if (frag_now_fix () != 0)
4382         {
4383           if (!frag_now->tc_frag_data.is_insn)
4384 	    frag_wane (frag_now);
4385 
4386           frag_new (0);
4387         }
4388       frag_grow (20);
4389 
4390       /* Write fr_fix part.  */
4391       p = frag_more (inst_main.size);
4392       md_number_to_chars (p, inst_main.instruction, inst_main.size);
4393 
4394       if (inst_main.reloc.type != BFD_RELOC_NONE)
4395         {
4396           fix_new_score (frag_now, p - frag_now->fr_literal, inst_main.size,
4397                          &inst_main.reloc.exp, inst_main.reloc.pc_rel, inst_main.reloc.type);
4398         }
4399 
4400 #ifdef OBJ_ELF
4401       dwarf2_emit_insn (inst_main.size);
4402 #endif
4403 
4404       /* GP instruction can not do optimization, only can do relax between
4405          1 instruction and 3 instructions.  */
4406       p = frag_var (rs_machine_dependent, inst_main.relax_size + RELAX_PAD_BYTE, 0,
4407                     RELAX_ENCODE (inst_main.size, inst_main.relax_size, inst_main.type, 0, 4, 0),
4408                     inst_main.reloc.exp.X_add_symbol, 0, NULL);
4409 
4410       /* Write fr_var part.
4411          no calling gen_insn_frag, no fixS will be generated.  */
4412       md_number_to_chars (p, inst_expand[0].instruction, inst_expand[0].size);
4413       p += inst_expand[0].size;
4414       md_number_to_chars (p, inst_expand[1].instruction, inst_expand[1].size);
4415       p += inst_expand[1].size;
4416       md_number_to_chars (p, inst_expand[2].instruction, inst_expand[2].size);
4417     }
4418   else
4419     {
4420       gen_insn_frag (&inst_expand[0], NULL);
4421       gen_insn_frag (&inst_expand[1], NULL);
4422       gen_insn_frag (&inst_expand[2], NULL);
4423     }
4424   nor1 = r1_bak;
4425 
4426   /* Set bwarn as -1, so macro instruction itself will not be generated frag.  */
4427   inst.bwarn = -1;
4428 }
4429 
4430 static void
4431 do_lw_pic (char *str)
4432 {
4433   int reg_rd;
4434 
4435   skip_whitespace (str);
4436   if (((reg_rd = reg_required_here (&str, 20, REG_TYPE_SCORE)) == (int) FAIL)
4437       || (skip_past_comma (&str) == (int) FAIL)
4438       || (my_get_expression (&inst.reloc.exp, &str) == (int) FAIL)
4439       || (end_of_line (str) == (int) FAIL))
4440     {
4441       return;
4442     }
4443   else
4444     {
4445       if (inst.reloc.exp.X_add_symbol == 0)
4446         {
4447           if (!inst.error)
4448 	    inst.error = BAD_ARGS;
4449 
4450           return;
4451         }
4452 
4453       inst.instruction |= GP << 15;
4454       inst.reloc.type = BFD_RELOC_SCORE_GOT15;
4455     }
4456 }
4457 
4458 static void
4459 do_empty (char *str)
4460 {
4461   str = str;
4462   if (university_version == 1)
4463     {
4464       if (((inst.instruction & 0x3e0003ff) == 0x0c000004)
4465           || ((inst.instruction & 0x3e0003ff) == 0x0c000024)
4466           || ((inst.instruction & 0x3e0003ff) == 0x0c000044)
4467           || ((inst.instruction & 0x3e0003ff) == 0x0c000064))
4468         {
4469           inst.error = ERR_FOR_SCORE5U_MMU;
4470           return;
4471         }
4472     }
4473   if (end_of_line (str) == (int) FAIL)
4474     return;
4475 
4476   if (inst.relax_inst != 0x8000)
4477     {
4478       if (inst.type == NO_OPD)
4479         {
4480           inst.relax_size = 2;
4481         }
4482       else
4483         {
4484           inst.relax_size = 4;
4485         }
4486     }
4487 }
4488 
4489 static void
4490 do_jump (char *str)
4491 {
4492   char *save_in;
4493 
4494   skip_whitespace (str);
4495   if (my_get_expression (&inst.reloc.exp, &str) == (int) FAIL
4496       || end_of_line (str) == (int) FAIL)
4497     return;
4498 
4499   if (inst.reloc.exp.X_add_symbol == 0)
4500     {
4501       inst.error = _("lacking label  ");
4502       return;
4503     }
4504 
4505   if (((inst.reloc.exp.X_add_number & 0xff000000) != 0)
4506       && ((inst.reloc.exp.X_add_number & 0xff000000) != 0xff000000))
4507     {
4508       inst.error = _("invalid constant: 25 bit expression not in range -2^24..2^24");
4509       return;
4510     }
4511 
4512   save_in = input_line_pointer;
4513   input_line_pointer = str;
4514   inst.reloc.type = BFD_RELOC_SCORE_JMP;
4515   inst.reloc.pc_rel = 1;
4516   input_line_pointer = save_in;
4517 }
4518 
4519 static void
4520 do16_jump (char *str)
4521 {
4522   skip_whitespace (str);
4523   if (my_get_expression (&inst.reloc.exp, &str) == (int) FAIL
4524       || end_of_line (str) == (int) FAIL)
4525     {
4526       return;
4527     }
4528   else if (inst.reloc.exp.X_add_symbol == 0)
4529     {
4530       inst.error = _("lacking label  ");
4531       return;
4532     }
4533   else if (((inst.reloc.exp.X_add_number & 0xfffff800) != 0)
4534            && ((inst.reloc.exp.X_add_number & 0xfffff800) != 0xfffff800))
4535     {
4536       inst.error = _("invalid constant: 12 bit expression not in range -2^11..2^11");
4537       return;
4538     }
4539 
4540   inst.reloc.type = BFD_RELOC_SCORE16_JMP;
4541   inst.reloc.pc_rel = 1;
4542 }
4543 
4544 static void
4545 do_branch (char *str)
4546 {
4547   unsigned long abs_value = 0;
4548 
4549   if (my_get_expression (&inst.reloc.exp, &str) == (int) FAIL
4550       || end_of_line (str) == (int) FAIL)
4551     {
4552       return;
4553     }
4554   else if (inst.reloc.exp.X_add_symbol == 0)
4555     {
4556       inst.error = _("lacking label  ");
4557       return;
4558     }
4559   else if (((inst.reloc.exp.X_add_number & 0xff000000) != 0)
4560            && ((inst.reloc.exp.X_add_number & 0xff000000) != 0xff000000))
4561     {
4562       inst.error = _("invalid constant: 20 bit expression not in range -2^19..2^19");
4563       return;
4564     }
4565 
4566   inst.reloc.type = BFD_RELOC_SCORE_BRANCH;
4567   inst.reloc.pc_rel = 1;
4568 
4569   /* Branch 32  offset field : 20 bit, 16 bit branch offset field : 8 bit.  */
4570   inst.instruction |= (inst.reloc.exp.X_add_number & 0x3fe) | ((inst.reloc.exp.X_add_number & 0xffc00) << 5);
4571 
4572   /* Compute 16 bit branch instruction.  */
4573   if ((inst.relax_inst != 0x8000) && (abs_value & 0xfffffe00) == 0)
4574     {
4575       inst.relax_inst |= (((inst.instruction >> 10) & 0xf) << 8);
4576       inst.relax_inst |= ((inst.reloc.exp.X_add_number >> 1) & 0xff);
4577       inst.relax_size = 2;
4578     }
4579   else
4580     {
4581       inst.relax_inst = 0x8000;
4582     }
4583 }
4584 
4585 static void
4586 do16_branch (char *str)
4587 {
4588   if ((my_get_expression (&inst.reloc.exp, &str) == (int) FAIL
4589       || end_of_line (str) == (int) FAIL))
4590     {
4591       ;
4592     }
4593   else if (inst.reloc.exp.X_add_symbol == 0)
4594     {
4595       inst.error = _("lacking label");
4596     }
4597   else if (((inst.reloc.exp.X_add_number & 0xffffff00) != 0)
4598            && ((inst.reloc.exp.X_add_number & 0xffffff00) != 0xffffff00))
4599     {
4600       inst.error = _("invalid constant: 9 bit expression not in range -2^8..2^8");
4601     }
4602   else
4603     {
4604       inst.reloc.type = BFD_RELOC_SCORE16_BRANCH;
4605       inst.reloc.pc_rel = 1;
4606       inst.instruction |= ((inst.reloc.exp.X_add_number >> 1) & 0xff);
4607     }
4608 }
4609 
4610 /* Iterate over the base tables to create the instruction patterns.  */
4611 static void
4612 build_score_ops_hsh (void)
4613 {
4614   unsigned int i;
4615   static struct obstack insn_obstack;
4616 
4617   obstack_begin (&insn_obstack, 4000);
4618   for (i = 0; i < sizeof (score_insns) / sizeof (struct asm_opcode); i++)
4619     {
4620       const struct asm_opcode *insn = score_insns + i;
4621       unsigned len = strlen (insn->template);
4622       struct asm_opcode *new;
4623       char *template;
4624       new = obstack_alloc (&insn_obstack, sizeof (struct asm_opcode));
4625       template = obstack_alloc (&insn_obstack, len + 1);
4626 
4627       strcpy (template, insn->template);
4628       new->template = template;
4629       new->parms = insn->parms;
4630       new->value = insn->value;
4631       new->relax_value = insn->relax_value;
4632       new->type = insn->type;
4633       new->bitmask = insn->bitmask;
4634       hash_insert (score_ops_hsh, new->template, (void *) new);
4635     }
4636 }
4637 
4638 static void
4639 build_dependency_insn_hsh (void)
4640 {
4641   unsigned int i;
4642   static struct obstack dependency_obstack;
4643 
4644   obstack_begin (&dependency_obstack, 4000);
4645   for (i = 0; i < sizeof (insn_to_dependency_table) / sizeof (insn_to_dependency_table[0]); i++)
4646     {
4647       const struct insn_to_dependency *tmp = insn_to_dependency_table + i;
4648       unsigned len = strlen (tmp->insn_name);
4649       struct insn_to_dependency *new;
4650 
4651       new = obstack_alloc (&dependency_obstack, sizeof (struct insn_to_dependency));
4652       new->insn_name = obstack_alloc (&dependency_obstack, len + 1);
4653 
4654       strcpy (new->insn_name, tmp->insn_name);
4655       new->type = tmp->type;
4656       hash_insert (dependency_insn_hsh, new->insn_name, (void *) new);
4657     }
4658 }
4659 
4660 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
4661    for use in the a.out file, and stores them in the array pointed to by buf.
4662    This knows about the endian-ness of the target machine and does
4663    THE RIGHT THING, whatever it is.  Possible values for n are 1 (byte)
4664    2 (short) and 4 (long)  Floating numbers are put out as a series of
4665    LITTLENUMS (shorts, here at least).  */
4666 
4667 void
4668 md_number_to_chars (char *buf, valueT val, int n)
4669 {
4670   if (target_big_endian)
4671     number_to_chars_bigendian (buf, val, n);
4672   else
4673     number_to_chars_littleendian (buf, val, n);
4674 }
4675 
4676 static valueT
4677 md_chars_to_number (char *buf, int n)
4678 {
4679   valueT result = 0;
4680   unsigned char *where = (unsigned char *)buf;
4681 
4682   if (target_big_endian)
4683     {
4684       while (n--)
4685         {
4686           result <<= 8;
4687           result |= (*where++ & 255);
4688         }
4689     }
4690   else
4691     {
4692       while (n--)
4693         {
4694           result <<= 8;
4695           result |= (where[n] & 255);
4696         }
4697     }
4698 
4699   return result;
4700 }
4701 
4702 char *
4703 md_atof (int type, char *litP, int *sizeP)
4704 {
4705   return ieee_md_atof (type, litP, sizeP, target_big_endian);
4706 }
4707 
4708 /* Return true if the given symbol should be considered local for PIC.  */
4709 
4710 static bfd_boolean
4711 pic_need_relax (symbolS *sym, asection *segtype)
4712 {
4713   asection *symsec;
4714   bfd_boolean linkonce;
4715 
4716   /* Handle the case of a symbol equated to another symbol.  */
4717   while (symbol_equated_reloc_p (sym))
4718     {
4719       symbolS *n;
4720 
4721       /* It's possible to get a loop here in a badly written
4722 	 program.  */
4723       n = symbol_get_value_expression (sym)->X_add_symbol;
4724       if (n == sym)
4725 	break;
4726       sym = n;
4727     }
4728 
4729   symsec = S_GET_SEGMENT (sym);
4730 
4731   /* duplicate the test for LINK_ONCE sections as in adjust_reloc_syms */
4732   linkonce = FALSE;
4733   if (symsec != segtype && ! S_IS_LOCAL (sym))
4734     {
4735       if ((bfd_get_section_flags (stdoutput, symsec) & SEC_LINK_ONCE) != 0)
4736 	linkonce = TRUE;
4737 
4738       /* The GNU toolchain uses an extension for ELF: a section
4739 	  beginning with the magic string .gnu.linkonce is a linkonce
4740 	  section.  */
4741       if (strncmp (segment_name (symsec), ".gnu.linkonce",
4742 		   sizeof ".gnu.linkonce" - 1) == 0)
4743 	linkonce = TRUE;
4744     }
4745 
4746   /* This must duplicate the test in adjust_reloc_syms.  */
4747   return (symsec != &bfd_und_section
4748 	    && symsec != &bfd_abs_section
4749 	  && ! bfd_is_com_section (symsec)
4750 	    && !linkonce
4751 #ifdef OBJ_ELF
4752 	  /* A global or weak symbol is treated as external.  */
4753 	  && (OUTPUT_FLAVOR != bfd_target_elf_flavour
4754 	      || (! S_IS_WEAK (sym) && ! S_IS_EXTERNAL (sym)))
4755 #endif
4756 	  );
4757 }
4758 
4759 static int
4760 judge_size_before_relax (fragS * fragp, asection *sec)
4761 {
4762   int change = 0;
4763 
4764   if (score_pic == NO_PIC)
4765     change = nopic_need_relax (fragp->fr_symbol, 0);
4766   else
4767     change = pic_need_relax (fragp->fr_symbol, sec);
4768 
4769   if (change == 1)
4770     {
4771       /* Only at the first time determining whether GP instruction relax should be done,
4772          return the difference between insntruction size and instruction relax size.  */
4773       if (fragp->fr_opcode == NULL)
4774 	{
4775 	  fragp->fr_fix = RELAX_NEW (fragp->fr_subtype);
4776 	  fragp->fr_opcode = fragp->fr_literal + RELAX_RELOC1 (fragp->fr_subtype);
4777           return RELAX_NEW (fragp->fr_subtype) - RELAX_OLD (fragp->fr_subtype);
4778 	}
4779     }
4780 
4781   return 0;
4782 }
4783 
4784 /* In this function, we determine whether GP instruction should do relaxation,
4785    for the label being against was known now.
4786    Doing this here but not in md_relax_frag() can induce iteration times
4787    in stage of doing relax.  */
4788 int
4789 md_estimate_size_before_relax (fragS * fragp, asection * sec ATTRIBUTE_UNUSED)
4790 {
4791   if ((RELAX_TYPE (fragp->fr_subtype) == Insn_GP)
4792       || (RELAX_TYPE (fragp->fr_subtype) == Insn_PIC))
4793     return judge_size_before_relax (fragp, sec);
4794 
4795   return 0;
4796 }
4797 
4798 static int
4799 b32_relax_to_b16 (fragS * fragp)
4800 {
4801   int grows = 0;
4802   int relaxable_p = 0;
4803   int old;
4804   int new;
4805   int frag_addr = fragp->fr_address + fragp->insn_addr;
4806 
4807   addressT symbol_address = 0;
4808   symbolS *s;
4809   offsetT offset;
4810   unsigned long value;
4811   unsigned long abs_value;
4812 
4813   /* FIXME : here may be able to modify better .
4814      I don't know how to get the fragp's section ,
4815      so in relax stage , it may be wrong to calculate the symbol's offset when the frag's section
4816      is different from the symbol's.  */
4817 
4818   old = RELAX_OLD (fragp->fr_subtype);
4819   new = RELAX_NEW (fragp->fr_subtype);
4820   relaxable_p = RELAX_OPT (fragp->fr_subtype);
4821 
4822   s = fragp->fr_symbol;
4823   /* b/bl immediate  */
4824   if (s == NULL)
4825     frag_addr = 0;
4826   else
4827     {
4828       if (s->bsym != 0)
4829 	symbol_address = (addressT) s->sy_frag->fr_address;
4830     }
4831 
4832   value = md_chars_to_number (fragp->fr_literal, INSN_SIZE);
4833 
4834   /* b 32's offset : 20 bit, b 16's tolerate field : 0xff.  */
4835   offset = ((value & 0x3ff0000) >> 6) | (value & 0x3fe);
4836   if ((offset & 0x80000) == 0x80000)
4837     offset |= 0xfff00000;
4838 
4839   abs_value = offset + symbol_address - frag_addr;
4840   if ((abs_value & 0x80000000) == 0x80000000)
4841     abs_value = 0xffffffff - abs_value + 1;
4842 
4843   /* Relax branch 32 to branch 16.  */
4844   if (relaxable_p && (s->bsym != NULL) && ((abs_value & 0xffffff00) == 0)
4845       && (S_IS_DEFINED (s) && !S_IS_COMMON (s) && !S_IS_EXTERNAL (s)))
4846     {
4847       /* do nothing.  */
4848     }
4849   else
4850     {
4851       /* Branch 32 can not be relaxed to b 16, so clear OPT bit.  */
4852       fragp->fr_opcode = NULL;
4853       fragp->fr_subtype = RELAX_OPT_CLEAR (fragp->fr_subtype);
4854     }
4855 
4856   return grows;
4857 }
4858 
4859 /* Main purpose is to determine whether one frag should do relax.
4860    frag->fr_opcode indicates this point.  */
4861 
4862 int
4863 score_relax_frag (asection * sec ATTRIBUTE_UNUSED, fragS * fragp, long stretch ATTRIBUTE_UNUSED)
4864 {
4865   int grows = 0;
4866   int insn_size;
4867   int insn_relax_size;
4868   int do_relax_p = 0;           /* Indicate doing relaxation for this frag.  */
4869   int relaxable_p = 0;
4870   bfd_boolean word_align_p = FALSE;
4871   fragS *next_fragp;
4872 
4873   /* If the instruction address is odd, make it half word align first.  */
4874   if ((fragp->fr_address) % 2 != 0)
4875     {
4876       if ((fragp->fr_address + fragp->insn_addr) % 2 != 0)
4877 	{
4878           fragp->insn_addr = 1;
4879           grows += 1;
4880 	}
4881     }
4882 
4883   word_align_p = ((fragp->fr_address + fragp->insn_addr) % 4 == 0) ? TRUE : FALSE;
4884 
4885   /* Get instruction size and relax size after the last relaxation.  */
4886   if (fragp->fr_opcode)
4887     {
4888       insn_size = RELAX_NEW (fragp->fr_subtype);
4889       insn_relax_size = RELAX_OLD (fragp->fr_subtype);
4890     }
4891   else
4892     {
4893       insn_size = RELAX_OLD (fragp->fr_subtype);
4894       insn_relax_size = RELAX_NEW (fragp->fr_subtype);
4895     }
4896 
4897   /* Handle specially for GP instruction.  for, judge_size_before_relax() has already determine
4898      whether the GP instruction should do relax.  */
4899   if ((RELAX_TYPE (fragp->fr_subtype) == Insn_GP)
4900       || (RELAX_TYPE (fragp->fr_subtype) == Insn_PIC))
4901     {
4902       if (!word_align_p)
4903         {
4904           if (fragp->insn_addr < 2)
4905             {
4906               fragp->insn_addr += 2;
4907               grows += 2;
4908             }
4909           else
4910             {
4911               fragp->insn_addr -= 2;
4912               grows -= 2;
4913             }
4914         }
4915 
4916       if (fragp->fr_opcode)
4917 	fragp->fr_fix = RELAX_NEW (fragp->fr_subtype) + fragp->insn_addr;
4918       else
4919 	fragp->fr_fix = RELAX_OLD (fragp->fr_subtype) + fragp->insn_addr;
4920     }
4921   else
4922     {
4923       if (RELAX_TYPE (fragp->fr_subtype) == PC_DISP19div2)
4924 	b32_relax_to_b16 (fragp);
4925 
4926       relaxable_p = RELAX_OPT (fragp->fr_subtype);
4927       next_fragp = fragp->fr_next;
4928       while ((next_fragp) && (next_fragp->fr_type != rs_machine_dependent))
4929 	{
4930           next_fragp = next_fragp->fr_next;
4931 	}
4932 
4933       if (next_fragp)
4934         {
4935           int n_insn_size;
4936           int n_relaxable_p = 0;
4937 
4938           if (next_fragp->fr_opcode)
4939             {
4940               n_insn_size = RELAX_NEW (next_fragp->fr_subtype);
4941             }
4942           else
4943             {
4944               n_insn_size = RELAX_OLD (next_fragp->fr_subtype);
4945             }
4946 
4947           if (RELAX_TYPE (next_fragp->fr_subtype) == PC_DISP19div2)
4948             b32_relax_to_b16 (next_fragp);
4949           n_relaxable_p = RELAX_OPT (next_fragp->fr_subtype);
4950 
4951           if (word_align_p)
4952             {
4953               if (insn_size == 4)
4954                 {
4955                   /* 32 -> 16.  */
4956                   if (relaxable_p && ((n_insn_size == 2) || n_relaxable_p))
4957                     {
4958                       grows -= 2;
4959                       do_relax_p = 1;
4960                     }
4961                 }
4962               else if (insn_size == 2)
4963                 {
4964                   /* 16 -> 32.  */
4965                   if (relaxable_p && (((n_insn_size == 4) && !n_relaxable_p) || (n_insn_size > 4)))
4966                     {
4967                       grows += 2;
4968                       do_relax_p = 1;
4969                     }
4970                 }
4971               else
4972                 {
4973 		  abort ();
4974                 }
4975             }
4976           else
4977             {
4978               if (insn_size == 4)
4979                 {
4980                   /* 32 -> 16.  */
4981                   if (relaxable_p)
4982                     {
4983                       grows -= 2;
4984                       do_relax_p = 1;
4985                     }
4986                   /* Make the 32 bit insturction word align.  */
4987                   else
4988                     {
4989                       fragp->insn_addr += 2;
4990                       grows += 2;
4991 		    }
4992                 }
4993               else if (insn_size == 2)
4994                 {
4995                   /* Do nothing.  */
4996                 }
4997               else
4998                 {
4999 		  abort ();
5000                 }
5001             }
5002         }
5003       else
5004         {
5005 	  /* Here, try best to do relax regardless fragp->fr_next->fr_type.  */
5006           if (word_align_p == FALSE)
5007             {
5008               if (insn_size % 4 == 0)
5009                 {
5010                   /* 32 -> 16.  */
5011                   if (relaxable_p)
5012                     {
5013                       grows -= 2;
5014                       do_relax_p = 1;
5015                     }
5016                   else
5017                     {
5018                       fragp->insn_addr += 2;
5019                       grows += 2;
5020                     }
5021                 }
5022             }
5023           else
5024             {
5025 	      /* Do nothing.  */
5026             }
5027         }
5028 
5029       /* fragp->fr_opcode indicates whether this frag should be relaxed.  */
5030       if (do_relax_p)
5031         {
5032           if (fragp->fr_opcode)
5033             {
5034               fragp->fr_opcode = NULL;
5035 	      /* Guarantee estimate stage is correct.  */
5036               fragp->fr_fix = RELAX_OLD (fragp->fr_subtype);
5037               fragp->fr_fix += fragp->insn_addr;
5038             }
5039           else
5040             {
5041               fragp->fr_opcode = fragp->fr_literal + RELAX_RELOC1 (fragp->fr_subtype);
5042 	      /* Guarantee estimate stage is correct.  */
5043               fragp->fr_fix = RELAX_NEW (fragp->fr_subtype);
5044               fragp->fr_fix += fragp->insn_addr;
5045             }
5046         }
5047       else
5048 	{
5049           if (fragp->fr_opcode)
5050             {
5051 	      /* Guarantee estimate stage is correct.  */
5052               fragp->fr_fix = RELAX_NEW (fragp->fr_subtype);
5053               fragp->fr_fix += fragp->insn_addr;
5054             }
5055           else
5056             {
5057 	      /* Guarantee estimate stage is correct.  */
5058               fragp->fr_fix = RELAX_OLD (fragp->fr_subtype);
5059               fragp->fr_fix += fragp->insn_addr;
5060             }
5061 	}
5062     }
5063 
5064   return grows;
5065 }
5066 
5067 void
5068 md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED, segT sec ATTRIBUTE_UNUSED, fragS * fragp)
5069 {
5070   int old;
5071   int new;
5072   char backup[20];
5073   fixS *fixp;
5074 
5075   old = RELAX_OLD (fragp->fr_subtype);
5076   new = RELAX_NEW (fragp->fr_subtype);
5077 
5078   /* fragp->fr_opcode indicates whether this frag should be relaxed.  */
5079   if (fragp->fr_opcode == NULL)
5080     {
5081       memcpy (backup, fragp->fr_literal, old);
5082       fragp->fr_fix = old;
5083     }
5084   else
5085     {
5086       memcpy (backup, fragp->fr_literal + old, new);
5087       fragp->fr_fix = new;
5088     }
5089 
5090   fixp = fragp->tc_frag_data.fixp;
5091   while (fixp && fixp->fx_frag == fragp && fixp->fx_where < old)
5092     {
5093       if (fragp->fr_opcode)
5094 	fixp->fx_done = 1;
5095       fixp = fixp->fx_next;
5096     }
5097   while (fixp && fixp->fx_frag == fragp)
5098     {
5099       if (fragp->fr_opcode)
5100 	fixp->fx_where -= old + fragp->insn_addr;
5101       else
5102 	fixp->fx_done = 1;
5103       fixp = fixp->fx_next;
5104     }
5105 
5106   if (fragp->insn_addr)
5107     {
5108       md_number_to_chars (fragp->fr_literal, 0x0, fragp->insn_addr);
5109     }
5110   memcpy (fragp->fr_literal + fragp->insn_addr, backup, fragp->fr_fix);
5111   fragp->fr_fix += fragp->insn_addr;
5112 }
5113 
5114 /* Implementation of md_frag_check.
5115    Called after md_convert_frag().  */
5116 
5117 void
5118 score_frag_check (fragS * fragp ATTRIBUTE_UNUSED)
5119 {
5120   know (fragp->insn_addr <= RELAX_PAD_BYTE);
5121 }
5122 
5123 bfd_boolean
5124 score_fix_adjustable (fixS * fixP)
5125 {
5126   if (fixP->fx_addsy == NULL)
5127     {
5128       return 1;
5129     }
5130   else if (OUTPUT_FLAVOR == bfd_target_elf_flavour
5131       && (S_IS_EXTERNAL (fixP->fx_addsy) || S_IS_WEAK (fixP->fx_addsy)))
5132     {
5133       return 0;
5134     }
5135   else if (fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
5136       || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
5137     {
5138       return 0;
5139     }
5140 
5141   return 1;
5142 }
5143 
5144 /* Implementation of TC_VALIDATE_FIX.
5145    Called before md_apply_fix() and after md_convert_frag().  */
5146 void
5147 score_validate_fix (fixS *fixP)
5148 {
5149   fixP->fx_where += fixP->fx_frag->insn_addr;
5150 }
5151 
5152 long
5153 md_pcrel_from (fixS * fixP)
5154 {
5155   long retval = 0;
5156 
5157   if (fixP->fx_addsy
5158       && (S_GET_SEGMENT (fixP->fx_addsy) == undefined_section)
5159       && (fixP->fx_subsy == NULL))
5160     {
5161       retval = 0;
5162     }
5163   else
5164     {
5165       retval = fixP->fx_where + fixP->fx_frag->fr_address;
5166     }
5167 
5168   return retval;
5169 }
5170 
5171 int
5172 score_force_relocation (struct fix *fixp)
5173 {
5174   int retval = 0;
5175 
5176   if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
5177       || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY
5178       || fixp->fx_r_type == BFD_RELOC_SCORE_JMP
5179       || fixp->fx_r_type == BFD_RELOC_SCORE_BRANCH
5180       || fixp->fx_r_type == BFD_RELOC_SCORE16_JMP
5181       || fixp->fx_r_type == BFD_RELOC_SCORE16_BRANCH)
5182     {
5183       retval = 1;
5184     }
5185 
5186   return retval;
5187 }
5188 
5189 /* Round up a section size to the appropriate boundary.  */
5190 valueT
5191 md_section_align (segT segment ATTRIBUTE_UNUSED, valueT size)
5192 {
5193   int align = bfd_get_section_alignment (stdoutput, segment);
5194 
5195   return ((size + (1 << align) - 1) & (-1 << align));
5196 }
5197 
5198 void
5199 md_apply_fix (fixS *fixP, valueT *valP, segT seg)
5200 {
5201   offsetT value = *valP;
5202   offsetT abs_value = 0;
5203   offsetT newval;
5204   offsetT content;
5205   unsigned short HI, LO;
5206 
5207   char *buf = fixP->fx_frag->fr_literal + fixP->fx_where;
5208 
5209   assert (fixP->fx_r_type < BFD_RELOC_UNUSED);
5210   if (fixP->fx_addsy == 0 && !fixP->fx_pcrel)
5211     {
5212       if (fixP->fx_r_type != BFD_RELOC_SCORE_DUMMY_HI16)
5213         fixP->fx_done = 1;
5214     }
5215 
5216   /* If this symbol is in a different section then we need to leave it for
5217      the linker to deal with.  Unfortunately, md_pcrel_from can't tell,
5218      so we have to undo it's effects here.  */
5219   if (fixP->fx_pcrel)
5220     {
5221       if (fixP->fx_addsy != NULL
5222 	  && S_IS_DEFINED (fixP->fx_addsy)
5223 	  && S_GET_SEGMENT (fixP->fx_addsy) != seg)
5224 	value += md_pcrel_from (fixP);
5225     }
5226 
5227   /* Remember value for emit_reloc.  */
5228   fixP->fx_addnumber = value;
5229 
5230   switch (fixP->fx_r_type)
5231     {
5232     case BFD_RELOC_HI16_S:
5233       if (fixP->fx_done)
5234         {                       /* For la rd, imm32.  */
5235           newval = md_chars_to_number (buf, INSN_SIZE);
5236           HI = (value) >> 16;   /* mul to 2, then take the hi 16 bit.  */
5237           newval |= (HI & 0x3fff) << 1;
5238           newval |= ((HI >> 14) & 0x3) << 16;
5239           md_number_to_chars (buf, newval, INSN_SIZE);
5240         }
5241       break;
5242     case BFD_RELOC_LO16:
5243       if (fixP->fx_done)        /* For la rd, imm32.  */
5244         {
5245           newval = md_chars_to_number (buf, INSN_SIZE);
5246           LO = (value) & 0xffff;
5247           newval |= (LO & 0x3fff) << 1; /* 16 bit: imm -> 14 bit in lo, 2 bit in hi.  */
5248           newval |= ((LO >> 14) & 0x3) << 16;
5249           md_number_to_chars (buf, newval, INSN_SIZE);
5250         }
5251       break;
5252     case BFD_RELOC_SCORE_JMP:
5253       {
5254         content = md_chars_to_number (buf, INSN_SIZE);
5255         value = fixP->fx_offset;
5256         content = (content & ~0x3ff7ffe) | ((value << 1) & 0x3ff0000) | (value & 0x7fff);
5257         md_number_to_chars (buf, content, INSN_SIZE);
5258       }
5259       break;
5260     case BFD_RELOC_SCORE_BRANCH:
5261       if ((S_GET_SEGMENT (fixP->fx_addsy) != seg) || (fixP->fx_addsy != NULL && S_IS_EXTERNAL (fixP->fx_addsy)))
5262         value = fixP->fx_offset;
5263       else
5264         fixP->fx_done = 1;
5265 
5266       content = md_chars_to_number (buf, INSN_SIZE);
5267       if ((fixP->fx_frag->fr_opcode != 0) && ((content & 0x80008000) != 0x80008000))
5268         {
5269           if ((value & 0x80000000) == 0x80000000)
5270             abs_value = 0xffffffff - value + 1;
5271           if ((abs_value & 0xffffff00) != 0)
5272             {
5273               as_bad_where (fixP->fx_file, fixP->fx_line,
5274                             _(" branch relocation truncate (0x%x) [-2^8 ~ 2^8]"), (unsigned int)value);
5275               return;
5276             }
5277           content = md_chars_to_number (buf, INSN16_SIZE);
5278           content &= 0xff00;
5279           content = (content & 0xff00) | ((value >> 1) & 0xff);
5280           md_number_to_chars (buf, content, INSN16_SIZE);
5281           fixP->fx_r_type = BFD_RELOC_SCORE16_BRANCH;
5282           fixP->fx_size = 2;
5283         }
5284       else
5285         {
5286           if ((value & 0x80000000) == 0x80000000)
5287             abs_value = 0xffffffff - value + 1;
5288           if ((abs_value & 0xfff80000) != 0)
5289             {
5290               as_bad_where (fixP->fx_file, fixP->fx_line,
5291                             _(" branch relocation truncate (0x%x) [-2^19 ~ 2^19]"), (unsigned int)value);
5292               return;
5293             }
5294           content = md_chars_to_number (buf, INSN_SIZE);
5295           content &= 0xfc00fc01;
5296           content = (content & 0xfc00fc01) | (value & 0x3fe) | ((value << 6) & 0x3ff0000);
5297           md_number_to_chars (buf, content, INSN_SIZE);
5298         }
5299       break;
5300     case BFD_RELOC_SCORE16_JMP:
5301       content = md_chars_to_number (buf, INSN16_SIZE);
5302       content &= 0xf001;
5303       value = fixP->fx_offset & 0xfff;
5304       content = (content & 0xfc01) | (value & 0xffe);
5305       md_number_to_chars (buf, content, INSN16_SIZE);
5306       break;
5307     case BFD_RELOC_SCORE16_BRANCH:
5308       content = md_chars_to_number (buf, INSN_SIZE);
5309       if ((fixP->fx_frag->fr_opcode != 0) && ((content & 0x80008000) == 0x80008000))
5310         {
5311           if ((S_GET_SEGMENT (fixP->fx_addsy) != seg) ||
5312               (fixP->fx_addsy != NULL && S_IS_EXTERNAL (fixP->fx_addsy)))
5313             value = fixP->fx_offset;
5314           else
5315             fixP->fx_done = 1;
5316           if ((value & 0x80000000) == 0x80000000)
5317             abs_value = 0xffffffff - value + 1;
5318           if ((abs_value & 0xfff80000) != 0)
5319             {
5320               as_bad_where (fixP->fx_file, fixP->fx_line,
5321                             _(" branch relocation truncate (0x%x) [-2^19 ~ 2^19]"), (unsigned int)value);
5322               return;
5323             }
5324           content = md_chars_to_number (buf, INSN_SIZE);
5325           content = (content & 0xfc00fc01) | (value & 0x3fe) | ((value << 6) & 0x3ff0000);
5326           md_number_to_chars (buf, content, INSN_SIZE);
5327           fixP->fx_r_type = BFD_RELOC_SCORE_BRANCH;
5328           fixP->fx_size = 4;
5329           break;
5330         }
5331       else
5332         {
5333           /* In differnt section.  */
5334           if ((S_GET_SEGMENT (fixP->fx_addsy) != seg) ||
5335               (fixP->fx_addsy != NULL && S_IS_EXTERNAL (fixP->fx_addsy)))
5336             value = fixP->fx_offset;
5337           else
5338             fixP->fx_done = 1;
5339 
5340           if ((value & 0x80000000) == 0x80000000)
5341             abs_value = 0xffffffff - value + 1;
5342           if ((abs_value & 0xffffff00) != 0)
5343             {
5344               as_bad_where (fixP->fx_file, fixP->fx_line,
5345                             _(" branch relocation truncate (0x%x)  [-2^8 ~ 2^8]"), (unsigned int)value);
5346               return;
5347             }
5348           content = md_chars_to_number (buf, INSN16_SIZE);
5349           content = (content & 0xff00) | ((value >> 1) & 0xff);
5350           md_number_to_chars (buf, content, INSN16_SIZE);
5351           break;
5352         }
5353     case BFD_RELOC_8:
5354       if (fixP->fx_done || fixP->fx_pcrel)
5355 	md_number_to_chars (buf, value, 1);
5356 #ifdef OBJ_ELF
5357       else
5358         {
5359           value = fixP->fx_offset;
5360           md_number_to_chars (buf, value, 1);
5361         }
5362 #endif
5363       break;
5364 
5365     case BFD_RELOC_16:
5366       if (fixP->fx_done || fixP->fx_pcrel)
5367         md_number_to_chars (buf, value, 2);
5368 #ifdef OBJ_ELF
5369       else
5370         {
5371           value = fixP->fx_offset;
5372           md_number_to_chars (buf, value, 2);
5373         }
5374 #endif
5375       break;
5376     case BFD_RELOC_RVA:
5377     case BFD_RELOC_32:
5378       if (fixP->fx_done || fixP->fx_pcrel)
5379         md_number_to_chars (buf, value, 4);
5380 #ifdef OBJ_ELF
5381       else
5382         {
5383           value = fixP->fx_offset;
5384           md_number_to_chars (buf, value, 4);
5385         }
5386 #endif
5387       break;
5388     case BFD_RELOC_VTABLE_INHERIT:
5389       fixP->fx_done = 0;
5390       if (fixP->fx_addsy && !S_IS_DEFINED (fixP->fx_addsy) && !S_IS_WEAK (fixP->fx_addsy))
5391         S_SET_WEAK (fixP->fx_addsy);
5392       break;
5393     case BFD_RELOC_VTABLE_ENTRY:
5394       fixP->fx_done = 0;
5395       break;
5396     case BFD_RELOC_SCORE_GPREL15:
5397       content = md_chars_to_number (buf, INSN_SIZE);
5398       if ((fixP->fx_frag->fr_opcode != 0) && ((content & 0xfc1c8000) != 0x94188000))
5399         fixP->fx_r_type = BFD_RELOC_NONE;
5400       fixP->fx_done = 0;
5401       break;
5402     case BFD_RELOC_SCORE_GOT15:
5403     case BFD_RELOC_SCORE_DUMMY_HI16:
5404     case BFD_RELOC_SCORE_GOT_LO16:
5405     case BFD_RELOC_SCORE_CALL15:
5406     case BFD_RELOC_GPREL32:
5407       break;
5408     case BFD_RELOC_NONE:
5409     default:
5410       as_bad_where (fixP->fx_file, fixP->fx_line, _("bad relocation fixup type (%d)"), fixP->fx_r_type);
5411     }
5412 }
5413 
5414 /* Translate internal representation of relocation info to BFD target format.  */
5415 arelent **
5416 tc_gen_reloc (asection * section ATTRIBUTE_UNUSED, fixS * fixp)
5417 {
5418   static arelent *retval[MAX_RELOC_EXPANSION + 1];  /* MAX_RELOC_EXPANSION equals 2.  */
5419   arelent *reloc;
5420   bfd_reloc_code_real_type code;
5421   char *type;
5422   fragS *f;
5423   symbolS *s;
5424   expressionS e;
5425 
5426   reloc = retval[0] = xmalloc (sizeof (arelent));
5427   retval[1] = NULL;
5428 
5429   reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
5430   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
5431   reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
5432   reloc->addend = fixp->fx_offset;
5433 
5434   /* If this is a variant frag, we may need to adjust the existing
5435      reloc and generate a new one.  */
5436   if (fixp->fx_frag->fr_opcode != NULL && (fixp->fx_r_type == BFD_RELOC_SCORE_GPREL15))
5437     {
5438       /* Update instruction imm bit.  */
5439       offsetT newval;
5440       unsigned short off;
5441       char *buf;
5442 
5443       buf = fixp->fx_frag->fr_literal + fixp->fx_frag->insn_addr;
5444       newval = md_chars_to_number (buf, INSN_SIZE);
5445       off = fixp->fx_offset >> 16;
5446       newval |= (off & 0x3fff) << 1;
5447       newval |= ((off >> 14) & 0x3) << 16;
5448       md_number_to_chars (buf, newval, INSN_SIZE);
5449 
5450       buf += INSN_SIZE;
5451       newval = md_chars_to_number (buf, INSN_SIZE);
5452       off = fixp->fx_offset & 0xffff;
5453       newval |= ((off & 0x3fff) << 1);
5454       newval |= (((off >> 14) & 0x3) << 16);
5455       md_number_to_chars (buf, newval, INSN_SIZE);
5456 
5457       retval[1] = xmalloc (sizeof (arelent));
5458       retval[2] = NULL;
5459       retval[1]->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
5460       *retval[1]->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
5461       retval[1]->address = (reloc->address + RELAX_RELOC2 (fixp->fx_frag->fr_subtype));
5462 
5463       f = fixp->fx_frag;
5464       s = f->fr_symbol;
5465       e = s->sy_value;
5466 
5467       retval[1]->addend = 0;
5468       retval[1]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_LO16);
5469       assert (retval[1]->howto != NULL);
5470 
5471       fixp->fx_r_type = BFD_RELOC_HI16_S;
5472     }
5473 
5474   code = fixp->fx_r_type;
5475   switch (fixp->fx_r_type)
5476     {
5477     case BFD_RELOC_32:
5478       if (fixp->fx_pcrel)
5479         {
5480           code = BFD_RELOC_32_PCREL;
5481           break;
5482         }
5483     case BFD_RELOC_HI16_S:
5484     case BFD_RELOC_LO16:
5485     case BFD_RELOC_SCORE_JMP:
5486     case BFD_RELOC_SCORE_BRANCH:
5487     case BFD_RELOC_SCORE16_JMP:
5488     case BFD_RELOC_SCORE16_BRANCH:
5489     case BFD_RELOC_VTABLE_ENTRY:
5490     case BFD_RELOC_VTABLE_INHERIT:
5491     case BFD_RELOC_SCORE_GPREL15:
5492     case BFD_RELOC_SCORE_GOT15:
5493     case BFD_RELOC_SCORE_DUMMY_HI16:
5494     case BFD_RELOC_SCORE_GOT_LO16:
5495     case BFD_RELOC_SCORE_CALL15:
5496     case BFD_RELOC_GPREL32:
5497     case BFD_RELOC_NONE:
5498       code = fixp->fx_r_type;
5499       break;
5500     default:
5501       type = _("<unknown>");
5502       as_bad_where (fixp->fx_file, fixp->fx_line,
5503                     _("cannot represent %s relocation in this object file format"), type);
5504       return NULL;
5505     }
5506 
5507   reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
5508   if (reloc->howto == NULL)
5509     {
5510       as_bad_where (fixp->fx_file, fixp->fx_line,
5511                     _("cannot represent %s relocation in this object file format1"),
5512                     bfd_get_reloc_code_name (code));
5513       return NULL;
5514     }
5515   /* HACK: Since arm ELF uses Rel instead of Rela, encode the
5516      vtable entry to be used in the relocation's section offset.  */
5517   if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
5518     reloc->address = fixp->fx_offset;
5519 
5520   return retval;
5521 }
5522 
5523 void
5524 score_elf_final_processing (void)
5525 {
5526   if (fix_data_dependency == 1)
5527     {
5528       elf_elfheader (stdoutput)->e_flags |= EF_SCORE_FIXDEP;
5529     }
5530   if (score_pic == PIC)
5531     {
5532       elf_elfheader (stdoutput)->e_flags |= EF_SCORE_PIC;
5533     }
5534 }
5535 
5536 static void
5537 parse_pce_inst (char *insnstr)
5538 {
5539   char c;
5540   char *p;
5541   char first[MAX_LITERAL_POOL_SIZE];
5542   char second[MAX_LITERAL_POOL_SIZE];
5543   struct score_it pec_part_1;
5544 
5545   /* Get first part string of PCE.  */
5546   p = strstr (insnstr, "||");
5547   c = *p;
5548   *p = '\0';
5549   sprintf (first, "%s", insnstr);
5550 
5551   /* Get second part string of PCE.  */
5552   *p = c;
5553   p += 2;
5554   sprintf (second, "%s", p);
5555 
5556   parse_16_32_inst (first, FALSE);
5557   if (inst.error)
5558     return;
5559 
5560   memcpy (&pec_part_1, &inst, sizeof (inst));
5561 
5562   parse_16_32_inst (second, FALSE);
5563   if (inst.error)
5564     return;
5565 
5566   if (   ((pec_part_1.size == INSN_SIZE) && (inst.size == INSN_SIZE))
5567       || ((pec_part_1.size == INSN_SIZE) && (inst.size == INSN16_SIZE))
5568       || ((pec_part_1.size == INSN16_SIZE) && (inst.size == INSN_SIZE)))
5569     {
5570       inst.error = _("pce instruction error (16 bit || 16 bit)'");
5571       sprintf (inst.str, insnstr);
5572       return;
5573     }
5574 
5575   if (!inst.error)
5576     gen_insn_frag (&pec_part_1, &inst);
5577 }
5578 
5579 void
5580 md_assemble (char *str)
5581 {
5582   know (str);
5583   know (strlen (str) < MAX_LITERAL_POOL_SIZE);
5584 
5585   memset (&inst, '\0', sizeof (inst));
5586   if (INSN_IS_PCE_P (str))
5587     parse_pce_inst (str);
5588   else
5589     parse_16_32_inst (str, TRUE);
5590 
5591   if (inst.error)
5592     as_bad (_("%s -- `%s'"), inst.error, inst.str);
5593 }
5594 
5595 /* We handle all bad expressions here, so that we can report the faulty
5596    instruction in the error message.  */
5597 void
5598 md_operand (expressionS * expr)
5599 {
5600   if (in_my_get_expression)
5601     {
5602       expr->X_op = O_illegal;
5603       if (inst.error == NULL)
5604         {
5605           inst.error = _("bad expression");
5606         }
5607     }
5608 }
5609 
5610 const char *md_shortopts = "nO::g::G:";
5611 
5612 #ifdef SCORE_BI_ENDIAN
5613 #define OPTION_EB             (OPTION_MD_BASE + 0)
5614 #define OPTION_EL             (OPTION_MD_BASE + 1)
5615 #else
5616 #if TARGET_BYTES_BIG_ENDIAN
5617 #define OPTION_EB             (OPTION_MD_BASE + 0)
5618 #else
5619 #define OPTION_EL             (OPTION_MD_BASE + 1)
5620 #endif
5621 #endif
5622 #define OPTION_FIXDD          (OPTION_MD_BASE + 2)
5623 #define OPTION_NWARN          (OPTION_MD_BASE + 3)
5624 #define OPTION_SCORE5         (OPTION_MD_BASE + 4)
5625 #define OPTION_SCORE5U        (OPTION_MD_BASE + 5)
5626 #define OPTION_SCORE7         (OPTION_MD_BASE + 6)
5627 #define OPTION_R1             (OPTION_MD_BASE + 7)
5628 #define OPTION_O0             (OPTION_MD_BASE + 8)
5629 #define OPTION_SCORE_VERSION  (OPTION_MD_BASE + 9)
5630 #define OPTION_PIC            (OPTION_MD_BASE + 10)
5631 
5632 struct option md_longopts[] =
5633 {
5634 #ifdef OPTION_EB
5635   {"EB"     , no_argument, NULL, OPTION_EB},
5636 #endif
5637 #ifdef OPTION_EL
5638   {"EL"     , no_argument, NULL, OPTION_EL},
5639 #endif
5640   {"FIXDD"  , no_argument, NULL, OPTION_FIXDD},
5641   {"NWARN"  , no_argument, NULL, OPTION_NWARN},
5642   {"SCORE5" , no_argument, NULL, OPTION_SCORE5},
5643   {"SCORE5U", no_argument, NULL, OPTION_SCORE5U},
5644   {"SCORE7" , no_argument, NULL, OPTION_SCORE7},
5645   {"USE_R1" , no_argument, NULL, OPTION_R1},
5646   {"O0"     , no_argument, NULL, OPTION_O0},
5647   {"V"      , no_argument, NULL, OPTION_SCORE_VERSION},
5648   {"KPIC"   , no_argument, NULL, OPTION_PIC},
5649   {NULL     , no_argument, NULL, 0}
5650 };
5651 
5652 size_t md_longopts_size = sizeof (md_longopts);
5653 
5654 int
5655 md_parse_option (int c, char *arg)
5656 {
5657   switch (c)
5658     {
5659 #ifdef OPTION_EB
5660     case OPTION_EB:
5661       target_big_endian = 1;
5662       break;
5663 #endif
5664 #ifdef OPTION_EL
5665     case OPTION_EL:
5666       target_big_endian = 0;
5667       break;
5668 #endif
5669     case OPTION_FIXDD:
5670       fix_data_dependency = 1;
5671       break;
5672     case OPTION_NWARN:
5673       warn_fix_data_dependency = 0;
5674       break;
5675     case OPTION_SCORE5:
5676       score7 = 0;
5677       university_version = 0;
5678       vector_size = SCORE5_PIPELINE;
5679       break;
5680     case OPTION_SCORE5U:
5681       score7 = 0;
5682       university_version = 1;
5683       vector_size = SCORE5_PIPELINE;
5684       break;
5685     case OPTION_SCORE7:
5686       score7 = 1;
5687       university_version = 0;
5688       vector_size = SCORE7_PIPELINE;
5689       break;
5690     case OPTION_R1:
5691       nor1 = 0;
5692       break;
5693     case 'G':
5694       g_switch_value = atoi (arg);
5695       break;
5696     case OPTION_O0:
5697       g_opt = 0;
5698       break;
5699     case OPTION_SCORE_VERSION:
5700       printf (_("Sunplus-v2-0-0-20060510\n"));
5701       break;
5702     case OPTION_PIC:
5703       score_pic = PIC;
5704       g_switch_value = 0;    /* Must set -G num as 0 to generate PIC code.  */
5705       break;
5706     default:
5707       /* as_bad (_("unrecognized option `-%c%s'"), c, arg ? arg : "");  */
5708       return 0;
5709     }
5710   return 1;
5711 }
5712 
5713 void
5714 md_show_usage (FILE * fp)
5715 {
5716   fprintf (fp, _(" Score-specific assembler options:\n"));
5717 #ifdef OPTION_EB
5718   fprintf (fp, _("\
5719         -EB\t\tassemble code for a big-endian cpu\n"));
5720 #endif
5721 
5722 #ifdef OPTION_EL
5723   fprintf (fp, _("\
5724         -EL\t\tassemble code for a little-endian cpu\n"));
5725 #endif
5726 
5727   fprintf (fp, _("\
5728         -FIXDD\t\tassemble code for fix data dependency\n"));
5729   fprintf (fp, _("\
5730         -NWARN\t\tassemble code for no warning message for fix data dependency\n"));
5731   fprintf (fp, _("\
5732         -SCORE5\t\tassemble code for target is SCORE5\n"));
5733   fprintf (fp, _("\
5734         -SCORE5U\tassemble code for target is SCORE5U\n"));
5735   fprintf (fp, _("\
5736         -SCORE7\t\tassemble code for target is SCORE7, this is default setting\n"));
5737   fprintf (fp, _("\
5738         -USE_R1\t\tassemble code for no warning message when using temp register r1\n"));
5739   fprintf (fp, _("\
5740         -KPIC\t\tassemble code for PIC\n"));
5741   fprintf (fp, _("\
5742         -O0\t\tassembler will not perform any optimizations\n"));
5743   fprintf (fp, _("\
5744         -G gpnum\tassemble code for setting gpsize and default is 8 byte\n"));
5745   fprintf (fp, _("\
5746         -V \t\tSunplus release version \n"));
5747 }
5748 
5749 
5750 /* Pesudo handling functions.  */
5751 
5752 /* If we change section we must dump the literal pool first.  */
5753 static void
5754 s_score_bss (int ignore ATTRIBUTE_UNUSED)
5755 {
5756   subseg_set (bss_section, (subsegT) get_absolute_expression ());
5757   demand_empty_rest_of_line ();
5758 }
5759 
5760 static void
5761 s_score_text (int ignore)
5762 {
5763   obj_elf_text (ignore);
5764   record_alignment (now_seg, 2);
5765 }
5766 
5767 static void
5768 score_s_section (int ignore)
5769 {
5770   obj_elf_section (ignore);
5771   if ((bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) != 0)
5772     record_alignment (now_seg, 2);
5773 
5774 }
5775 
5776 static void
5777 s_change_sec (int sec)
5778 {
5779   segT seg;
5780 
5781 #ifdef OBJ_ELF
5782   /* The ELF backend needs to know that we are changing sections, so
5783      that .previous works correctly.  We could do something like check
5784      for an obj_section_change_hook macro, but that might be confusing
5785      as it would not be appropriate to use it in the section changing
5786      functions in read.c, since obj-elf.c intercepts those.  FIXME:
5787      This should be cleaner, somehow.  */
5788   obj_elf_section_change_hook ();
5789 #endif
5790   switch (sec)
5791     {
5792     case 'r':
5793       seg = subseg_new (RDATA_SECTION_NAME, (subsegT) get_absolute_expression ());
5794       bfd_set_section_flags (stdoutput, seg, (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_RELOC | SEC_DATA));
5795       if (strcmp (TARGET_OS, "elf") != 0)
5796         record_alignment (seg, 4);
5797       demand_empty_rest_of_line ();
5798       break;
5799     case 's':
5800       seg = subseg_new (".sdata", (subsegT) get_absolute_expression ());
5801       bfd_set_section_flags (stdoutput, seg, SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA);
5802       if (strcmp (TARGET_OS, "elf") != 0)
5803         record_alignment (seg, 4);
5804       demand_empty_rest_of_line ();
5805       break;
5806     }
5807 }
5808 
5809 static void
5810 s_score_mask (int reg_type ATTRIBUTE_UNUSED)
5811 {
5812   long mask, off;
5813 
5814   if (cur_proc_ptr == (procS *) NULL)
5815     {
5816       as_warn (_(".mask outside of .ent"));
5817       demand_empty_rest_of_line ();
5818       return;
5819     }
5820   if (get_absolute_expression_and_terminator (&mask) != ',')
5821     {
5822       as_warn (_("Bad .mask directive"));
5823       --input_line_pointer;
5824       demand_empty_rest_of_line ();
5825       return;
5826     }
5827   off = get_absolute_expression ();
5828   cur_proc_ptr->reg_mask = mask;
5829   cur_proc_ptr->reg_offset = off;
5830   demand_empty_rest_of_line ();
5831 }
5832 
5833 static symbolS *
5834 get_symbol (void)
5835 {
5836   int c;
5837   char *name;
5838   symbolS *p;
5839 
5840   name = input_line_pointer;
5841   c = get_symbol_end ();
5842   p = (symbolS *) symbol_find_or_make (name);
5843   *input_line_pointer = c;
5844   return p;
5845 }
5846 
5847 static long
5848 get_number (void)
5849 {
5850   int negative = 0;
5851   long val = 0;
5852 
5853   if (*input_line_pointer == '-')
5854     {
5855       ++input_line_pointer;
5856       negative = 1;
5857     }
5858   if (!ISDIGIT (*input_line_pointer))
5859     as_bad (_("expected simple number"));
5860   if (input_line_pointer[0] == '0')
5861     {
5862       if (input_line_pointer[1] == 'x')
5863         {
5864           input_line_pointer += 2;
5865           while (ISXDIGIT (*input_line_pointer))
5866             {
5867               val <<= 4;
5868               val |= hex_value (*input_line_pointer++);
5869             }
5870           return negative ? -val : val;
5871         }
5872       else
5873         {
5874           ++input_line_pointer;
5875           while (ISDIGIT (*input_line_pointer))
5876             {
5877               val <<= 3;
5878               val |= *input_line_pointer++ - '0';
5879             }
5880           return negative ? -val : val;
5881         }
5882     }
5883   if (!ISDIGIT (*input_line_pointer))
5884     {
5885       printf (_(" *input_line_pointer == '%c' 0x%02x\n"), *input_line_pointer, *input_line_pointer);
5886       as_warn (_("invalid number"));
5887       return -1;
5888     }
5889   while (ISDIGIT (*input_line_pointer))
5890     {
5891       val *= 10;
5892       val += *input_line_pointer++ - '0';
5893     }
5894   return negative ? -val : val;
5895 }
5896 
5897 /* The .aent and .ent directives.  */
5898 
5899 static void
5900 s_score_ent (int aent)
5901 {
5902   symbolS *symbolP;
5903   int maybe_text;
5904 
5905   symbolP = get_symbol ();
5906   if (*input_line_pointer == ',')
5907     ++input_line_pointer;
5908   SKIP_WHITESPACE ();
5909   if (ISDIGIT (*input_line_pointer) || *input_line_pointer == '-')
5910     get_number ();
5911 
5912 #ifdef BFD_ASSEMBLER
5913   if ((bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) != 0)
5914     maybe_text = 1;
5915   else
5916     maybe_text = 0;
5917 #else
5918   if (now_seg != data_section && now_seg != bss_section)
5919     maybe_text = 1;
5920   else
5921     maybe_text = 0;
5922 #endif
5923   if (!maybe_text)
5924     as_warn (_(".ent or .aent not in text section."));
5925   if (!aent && cur_proc_ptr)
5926     as_warn (_("missing .end"));
5927   if (!aent)
5928     {
5929       cur_proc_ptr = &cur_proc;
5930       cur_proc_ptr->reg_mask = 0xdeadbeaf;
5931       cur_proc_ptr->reg_offset = 0xdeadbeaf;
5932       cur_proc_ptr->fpreg_mask = 0xdeafbeaf;
5933       cur_proc_ptr->leaf = 0xdeafbeaf;
5934       cur_proc_ptr->frame_offset = 0xdeafbeaf;
5935       cur_proc_ptr->frame_reg = 0xdeafbeaf;
5936       cur_proc_ptr->pc_reg = 0xdeafbeaf;
5937       cur_proc_ptr->isym = symbolP;
5938       symbol_get_bfdsym (symbolP)->flags |= BSF_FUNCTION;
5939       ++numprocs;
5940       if (debug_type == DEBUG_STABS)
5941         stabs_generate_asm_func (S_GET_NAME (symbolP), S_GET_NAME (symbolP));
5942     }
5943   demand_empty_rest_of_line ();
5944 }
5945 
5946 static void
5947 s_score_frame (int ignore ATTRIBUTE_UNUSED)
5948 {
5949   char *backupstr;
5950   char str[30];
5951   long val;
5952   int i = 0;
5953 
5954   backupstr = input_line_pointer;
5955 
5956 #ifdef OBJ_ELF
5957   if (cur_proc_ptr == (procS *) NULL)
5958     {
5959       as_warn (_(".frame outside of .ent"));
5960       demand_empty_rest_of_line ();
5961       return;
5962     }
5963   cur_proc_ptr->frame_reg = reg_required_here ((&backupstr), 0, REG_TYPE_SCORE);
5964   SKIP_WHITESPACE ();
5965   skip_past_comma (&backupstr);
5966   while (*backupstr != ',')
5967     {
5968       str[i] = *backupstr;
5969       i++;
5970       backupstr++;
5971     }
5972   str[i] = '\0';
5973   val = atoi (str);
5974 
5975   SKIP_WHITESPACE ();
5976   skip_past_comma (&backupstr);
5977   cur_proc_ptr->frame_offset = val;
5978   cur_proc_ptr->pc_reg = reg_required_here ((&backupstr), 0, REG_TYPE_SCORE);
5979 
5980   SKIP_WHITESPACE ();
5981   skip_past_comma (&backupstr);
5982   i = 0;
5983   while (*backupstr != '\n')
5984     {
5985       str[i] = *backupstr;
5986       i++;
5987       backupstr++;
5988     }
5989   str[i] = '\0';
5990   val = atoi (str);
5991   cur_proc_ptr->leaf = val;
5992   SKIP_WHITESPACE ();
5993   skip_past_comma (&backupstr);
5994 
5995 #endif /* OBJ_ELF */
5996   while (input_line_pointer != backupstr)
5997     input_line_pointer++;
5998 }
5999 
6000 /* The .end directive.  */
6001 static void
6002 s_score_end (int x ATTRIBUTE_UNUSED)
6003 {
6004   symbolS *p;
6005   int maybe_text;
6006 
6007   /* Generate a .pdr section.  */
6008   segT saved_seg = now_seg;
6009   subsegT saved_subseg = now_subseg;
6010   valueT dot;
6011   expressionS exp;
6012   char *fragp;
6013 
6014   if (!is_end_of_line[(unsigned char)*input_line_pointer])
6015     {
6016       p = get_symbol ();
6017       demand_empty_rest_of_line ();
6018     }
6019   else
6020     p = NULL;
6021 
6022 #ifdef BFD_ASSEMBLER
6023   if ((bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) != 0)
6024     maybe_text = 1;
6025   else
6026     maybe_text = 0;
6027 #else
6028   if (now_seg != data_section && now_seg != bss_section)
6029     maybe_text = 1;
6030   else
6031     maybe_text = 0;
6032 #endif
6033 
6034   if (!maybe_text)
6035     as_warn (_(".end not in text section"));
6036   if (!cur_proc_ptr)
6037     {
6038       as_warn (_(".end directive without a preceding .ent directive."));
6039       demand_empty_rest_of_line ();
6040       return;
6041     }
6042   if (p != NULL)
6043     {
6044       assert (S_GET_NAME (p));
6045       if (strcmp (S_GET_NAME (p), S_GET_NAME (cur_proc_ptr->isym)))
6046         as_warn (_(".end symbol does not match .ent symbol."));
6047       if (debug_type == DEBUG_STABS)
6048         stabs_generate_asm_endfunc (S_GET_NAME (p), S_GET_NAME (p));
6049     }
6050   else
6051     as_warn (_(".end directive missing or unknown symbol"));
6052 
6053   if ((cur_proc_ptr->reg_mask == 0xdeadbeaf) ||
6054       (cur_proc_ptr->reg_offset == 0xdeadbeaf) ||
6055       (cur_proc_ptr->leaf == 0xdeafbeaf) ||
6056       (cur_proc_ptr->frame_offset == 0xdeafbeaf) ||
6057       (cur_proc_ptr->frame_reg == 0xdeafbeaf) || (cur_proc_ptr->pc_reg == 0xdeafbeaf));
6058 
6059   else
6060     {
6061       dot = frag_now_fix ();
6062       assert (pdr_seg);
6063       subseg_set (pdr_seg, 0);
6064       /* Write the symbol.  */
6065       exp.X_op = O_symbol;
6066       exp.X_add_symbol = p;
6067       exp.X_add_number = 0;
6068       emit_expr (&exp, 4);
6069       fragp = frag_more (7 * 4);
6070       md_number_to_chars (fragp, (valueT) cur_proc_ptr->reg_mask, 4);
6071       md_number_to_chars (fragp + 4, (valueT) cur_proc_ptr->reg_offset, 4);
6072       md_number_to_chars (fragp + 8, (valueT) cur_proc_ptr->fpreg_mask, 4);
6073       md_number_to_chars (fragp + 12, (valueT) cur_proc_ptr->leaf, 4);
6074       md_number_to_chars (fragp + 16, (valueT) cur_proc_ptr->frame_offset, 4);
6075       md_number_to_chars (fragp + 20, (valueT) cur_proc_ptr->frame_reg, 4);
6076       md_number_to_chars (fragp + 24, (valueT) cur_proc_ptr->pc_reg, 4);
6077       subseg_set (saved_seg, saved_subseg);
6078 
6079     }
6080   cur_proc_ptr = NULL;
6081 }
6082 
6083 /* Handle the .set pseudo-op.  */
6084 static void
6085 s_score_set (int x ATTRIBUTE_UNUSED)
6086 {
6087   int i = 0;
6088   char name[MAX_LITERAL_POOL_SIZE];
6089   char * orig_ilp = input_line_pointer;
6090 
6091   while (!is_end_of_line[(unsigned char)*input_line_pointer])
6092     {
6093       name[i] = (char) * input_line_pointer;
6094       i++;
6095       ++input_line_pointer;
6096     }
6097 
6098   name[i] = '\0';
6099 
6100   if (strcmp (name, "nwarn") == 0)
6101     {
6102       warn_fix_data_dependency = 0;
6103     }
6104   else if (strcmp (name, "fixdd") == 0)
6105     {
6106       fix_data_dependency = 1;
6107     }
6108   else if (strcmp (name, "nofixdd") == 0)
6109     {
6110       fix_data_dependency = 0;
6111     }
6112   else if (strcmp (name, "r1") == 0)
6113     {
6114       nor1 = 0;
6115     }
6116   else if (strcmp (name, "nor1") == 0)
6117     {
6118       nor1 = 1;
6119     }
6120   else if (strcmp (name, "optimize") == 0)
6121     {
6122       g_opt = 1;
6123     }
6124   else if (strcmp (name, "volatile") == 0)
6125     {
6126       g_opt = 0;
6127     }
6128   else if (strcmp (name, "pic") == 0)
6129     {
6130       score_pic = PIC;
6131     }
6132   else
6133     {
6134       input_line_pointer = orig_ilp;
6135       s_set (0);
6136     }
6137 }
6138 
6139 /* Handle the .cpload pseudo-op.  This is used when generating PIC code.  It sets the
6140    $gp register for the function based on the function address, which is in the register
6141    named in the argument. This uses a relocation against GP_DISP_LABEL, which is handled
6142    specially by the linker.  The result is:
6143    ldis gp, %hi(GP_DISP_LABEL)
6144    ori  gp, %low(GP_DISP_LABEL)
6145    add  gp, gp, .cpload argument
6146    The .cpload argument is normally r29.  */
6147 
6148 static void
6149 s_score_cpload (int ignore ATTRIBUTE_UNUSED)
6150 {
6151   int reg;
6152   char insn_str[MAX_LITERAL_POOL_SIZE];
6153 
6154   /* If we are not generating PIC code, .cpload is ignored.  */
6155   if (score_pic == NO_PIC)
6156     {
6157       s_ignore (0);
6158       return;
6159     }
6160 
6161   if ((reg = reg_required_here (&input_line_pointer, -1, REG_TYPE_SCORE)) == (int) FAIL)
6162     return;
6163 
6164   demand_empty_rest_of_line ();
6165 
6166   sprintf (insn_str, "ld_i32hi r%d, %s", GP, GP_DISP_LABEL);
6167   if (append_insn (insn_str, TRUE) == (int) FAIL)
6168     return;
6169 
6170   sprintf (insn_str, "ld_i32lo r%d, %s", GP, GP_DISP_LABEL);
6171   if (append_insn (insn_str, TRUE) == (int) FAIL)
6172     return;
6173 
6174   sprintf (insn_str, "add r%d, r%d, r%d", GP, GP, reg);
6175   if (append_insn (insn_str, TRUE) == (int) FAIL)
6176     return;
6177 }
6178 
6179 /* Handle the .cprestore pseudo-op.  This stores $gp into a given
6180    offset from $sp.  The offset is remembered, and after making a PIC
6181    call $gp is restored from that location.  */
6182 
6183 static void
6184 s_score_cprestore (int ignore ATTRIBUTE_UNUSED)
6185 {
6186   int reg;
6187   int cprestore_offset;
6188   char insn_str[MAX_LITERAL_POOL_SIZE];
6189 
6190   /* If we are not generating PIC code, .cprestore is ignored.  */
6191   if (score_pic == NO_PIC)
6192     {
6193       s_ignore (0);
6194       return;
6195     }
6196 
6197   if ((reg = reg_required_here (&input_line_pointer, -1, REG_TYPE_SCORE)) == (int) FAIL
6198       || skip_past_comma (&input_line_pointer) == (int) FAIL)
6199     {
6200       return;
6201     }
6202 
6203   cprestore_offset = get_absolute_expression ();
6204 
6205   if (cprestore_offset <= 0x3fff)
6206     {
6207       sprintf (insn_str, "sw r%d, [r%d, %d]", GP, reg, cprestore_offset);
6208       if (append_insn (insn_str, TRUE) == (int) FAIL)
6209         return;
6210     }
6211   else
6212     {
6213       int r1_bak;
6214 
6215       r1_bak = nor1;
6216       nor1 = 0;
6217 
6218       sprintf (insn_str, "li r1, %d", cprestore_offset);
6219       if (append_insn (insn_str, TRUE) == (int) FAIL)
6220         return;
6221 
6222       sprintf (insn_str, "add r1, r1, r%d", reg);
6223       if (append_insn (insn_str, TRUE) == (int) FAIL)
6224         return;
6225 
6226       sprintf (insn_str, "sw r%d, [r1]", GP);
6227       if (append_insn (insn_str, TRUE) == (int) FAIL)
6228         return;
6229 
6230       nor1 = r1_bak;
6231     }
6232 
6233   demand_empty_rest_of_line ();
6234 }
6235 
6236 /* Handle the .gpword pseudo-op.  This is used when generating PIC
6237    code.  It generates a 32 bit GP relative reloc.  */
6238 static void
6239 s_score_gpword (int ignore ATTRIBUTE_UNUSED)
6240 {
6241   expressionS ex;
6242   char *p;
6243 
6244   /* When not generating PIC code, this is treated as .word.  */
6245   if (score_pic == NO_PIC)
6246     {
6247       cons (4);
6248       return;
6249     }
6250   expression (&ex);
6251   if (ex.X_op != O_symbol || ex.X_add_number != 0)
6252     {
6253       as_bad (_("Unsupported use of .gpword"));
6254       ignore_rest_of_line ();
6255     }
6256   p = frag_more (4);
6257   md_number_to_chars (p, (valueT) 0, 4);
6258   fix_new_exp (frag_now, p - frag_now->fr_literal, 4, &ex, FALSE, BFD_RELOC_GPREL32);
6259   demand_empty_rest_of_line ();
6260 }
6261 
6262 /* Handle the .cpadd pseudo-op.  This is used when dealing with switch
6263    tables in PIC code.  */
6264 
6265 static void
6266 s_score_cpadd (int ignore ATTRIBUTE_UNUSED)
6267 {
6268   int reg;
6269   char insn_str[MAX_LITERAL_POOL_SIZE];
6270 
6271   /* If we are not generating PIC code, .cpload is ignored.  */
6272   if (score_pic == NO_PIC)
6273     {
6274       s_ignore (0);
6275       return;
6276     }
6277 
6278   if ((reg = reg_required_here (&input_line_pointer, -1, REG_TYPE_SCORE)) == (int) FAIL)
6279     {
6280       return;
6281     }
6282   demand_empty_rest_of_line ();
6283 
6284   /* Add $gp to the register named as an argument.  */
6285   sprintf (insn_str, "add r%d, r%d, r%d", reg, reg, GP);
6286   if (append_insn (insn_str, TRUE) == (int) FAIL)
6287     return;
6288 }
6289 
6290 #ifndef TC_IMPLICIT_LCOMM_ALIGNMENT
6291 #define TC_IMPLICIT_LCOMM_ALIGNMENT(SIZE, P2VAR)        	\
6292     do								\
6293     {                                                   	\
6294     if ((SIZE) >= 8)                                      	\
6295     (P2VAR) = 3;                                        	\
6296     else if ((SIZE) >= 4)                                 	\
6297     (P2VAR) = 2;                                        	\
6298     else if ((SIZE) >= 2)                                 	\
6299     (P2VAR) = 1;                                        	\
6300     else                                                  	\
6301     (P2VAR) = 0;                                        	\
6302     }								\
6303   while (0)
6304 #endif
6305 
6306 static void
6307 s_score_lcomm (int bytes_p)
6308 {
6309   char *name;
6310   char c;
6311   char *p;
6312   int temp;
6313   symbolS *symbolP;
6314   segT current_seg = now_seg;
6315   subsegT current_subseg = now_subseg;
6316   const int max_alignment = 15;
6317   int align = 0;
6318   segT bss_seg = bss_section;
6319   int needs_align = 0;
6320 
6321   name = input_line_pointer;
6322   c = get_symbol_end ();
6323   p = input_line_pointer;
6324   *p = c;
6325 
6326   if (name == p)
6327     {
6328       as_bad (_("expected symbol name"));
6329       discard_rest_of_line ();
6330       return;
6331     }
6332 
6333   SKIP_WHITESPACE ();
6334 
6335   /* Accept an optional comma after the name.  The comma used to be
6336      required, but Irix 5 cc does not generate it.  */
6337   if (*input_line_pointer == ',')
6338     {
6339       ++input_line_pointer;
6340       SKIP_WHITESPACE ();
6341     }
6342 
6343   if (is_end_of_line[(unsigned char)*input_line_pointer])
6344     {
6345       as_bad (_("missing size expression"));
6346       return;
6347     }
6348 
6349   if ((temp = get_absolute_expression ()) < 0)
6350     {
6351       as_warn (_("BSS length (%d) < 0 ignored"), temp);
6352       ignore_rest_of_line ();
6353       return;
6354     }
6355 
6356 #if defined (TC_SCORE)
6357   if (OUTPUT_FLAVOR == bfd_target_ecoff_flavour || OUTPUT_FLAVOR == bfd_target_elf_flavour)
6358     {
6359       /* For Score and Alpha ECOFF or ELF, small objects are put in .sbss.  */
6360       if ((unsigned)temp <= bfd_get_gp_size (stdoutput))
6361         {
6362           bss_seg = subseg_new (".sbss", 1);
6363           seg_info (bss_seg)->bss = 1;
6364 #ifdef BFD_ASSEMBLER
6365           if (!bfd_set_section_flags (stdoutput, bss_seg, SEC_ALLOC))
6366             as_warn (_("error setting flags for \".sbss\": %s"), bfd_errmsg (bfd_get_error ()));
6367 #endif
6368         }
6369     }
6370 #endif
6371 
6372   SKIP_WHITESPACE ();
6373   if (*input_line_pointer == ',')
6374     {
6375       ++input_line_pointer;
6376       SKIP_WHITESPACE ();
6377 
6378       if (is_end_of_line[(unsigned char)*input_line_pointer])
6379         {
6380           as_bad (_("missing alignment"));
6381           return;
6382         }
6383       else
6384         {
6385           align = get_absolute_expression ();
6386           needs_align = 1;
6387         }
6388     }
6389 
6390   if (!needs_align)
6391     {
6392       TC_IMPLICIT_LCOMM_ALIGNMENT (temp, align);
6393 
6394       /* Still zero unless TC_IMPLICIT_LCOMM_ALIGNMENT set it.  */
6395       if (align)
6396         record_alignment (bss_seg, align);
6397     }
6398 
6399   if (needs_align)
6400     {
6401       if (bytes_p)
6402         {
6403           /* Convert to a power of 2.  */
6404           if (align != 0)
6405             {
6406               unsigned int i;
6407 
6408               for (i = 0; align != 0; align >>= 1, ++i)
6409                 ;
6410               align = i - 1;
6411             }
6412         }
6413 
6414       if (align > max_alignment)
6415         {
6416           align = max_alignment;
6417           as_warn (_("alignment too large; %d assumed"), align);
6418         }
6419       else if (align < 0)
6420         {
6421           align = 0;
6422           as_warn (_("alignment negative; 0 assumed"));
6423         }
6424 
6425       record_alignment (bss_seg, align);
6426     }
6427   else
6428     {
6429       /* Assume some objects may require alignment on some systems.  */
6430 #if defined (TC_ALPHA) && ! defined (VMS)
6431       if (temp > 1)
6432         {
6433           align = ffs (temp) - 1;
6434           if (temp % (1 << align))
6435             abort ();
6436         }
6437 #endif
6438     }
6439 
6440   *p = 0;
6441   symbolP = symbol_find_or_make (name);
6442   *p = c;
6443 
6444   if (
6445 #if (defined (OBJ_AOUT) || defined (OBJ_MAYBE_AOUT) \
6446      || defined (OBJ_BOUT) || defined (OBJ_MAYBE_BOUT))
6447 #ifdef BFD_ASSEMBLER
6448        (OUTPUT_FLAVOR != bfd_target_aout_flavour
6449         || (S_GET_OTHER (symbolP) == 0 && S_GET_DESC (symbolP) == 0)) &&
6450 #else
6451        (S_GET_OTHER (symbolP) == 0 && S_GET_DESC (symbolP) == 0) &&
6452 #endif
6453 #endif
6454        (S_GET_SEGMENT (symbolP) == bss_seg || (!S_IS_DEFINED (symbolP) && S_GET_VALUE (symbolP) == 0)))
6455     {
6456       char *pfrag;
6457 
6458       subseg_set (bss_seg, 1);
6459 
6460       if (align)
6461         frag_align (align, 0, 0);
6462 
6463       /* Detach from old frag.  */
6464       if (S_GET_SEGMENT (symbolP) == bss_seg)
6465         symbol_get_frag (symbolP)->fr_symbol = NULL;
6466 
6467       symbol_set_frag (symbolP, frag_now);
6468       pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP, (offsetT) temp, NULL);
6469       *pfrag = 0;
6470 
6471 
6472       S_SET_SEGMENT (symbolP, bss_seg);
6473 
6474 #ifdef OBJ_COFF
6475       /* The symbol may already have been created with a preceding
6476          ".globl" directive -- be careful not to step on storage class
6477          in that case.  Otherwise, set it to static.  */
6478       if (S_GET_STORAGE_CLASS (symbolP) != C_EXT)
6479         {
6480           S_SET_STORAGE_CLASS (symbolP, C_STAT);
6481         }
6482 #endif /* OBJ_COFF */
6483 
6484 #ifdef S_SET_SIZE
6485       S_SET_SIZE (symbolP, temp);
6486 #endif
6487     }
6488   else
6489     as_bad (_("symbol `%s' is already defined"), S_GET_NAME (symbolP));
6490 
6491   subseg_set (current_seg, current_subseg);
6492 
6493   demand_empty_rest_of_line ();
6494 }
6495 
6496 static void
6497 insert_reg (const struct reg_entry *r, struct hash_control *htab)
6498 {
6499   int i = 0;
6500   int len = strlen (r->name) + 2;
6501   char *buf = xmalloc (len);
6502   char *buf2 = xmalloc (len);
6503 
6504   strcpy (buf + i, r->name);
6505   for (i = 0; buf[i]; i++)
6506     {
6507       buf2[i] = TOUPPER (buf[i]);
6508     }
6509   buf2[i] = '\0';
6510 
6511   hash_insert (htab, buf, (void *) r);
6512   hash_insert (htab, buf2, (void *) r);
6513 }
6514 
6515 static void
6516 build_reg_hsh (struct reg_map *map)
6517 {
6518   const struct reg_entry *r;
6519 
6520   if ((map->htab = hash_new ()) == NULL)
6521     {
6522       as_fatal (_("virtual memory exhausted"));
6523     }
6524   for (r = map->names; r->name != NULL; r++)
6525     {
6526       insert_reg (r, map->htab);
6527     }
6528 }
6529 
6530 void
6531 md_begin (void)
6532 {
6533   unsigned int i;
6534   segT seg;
6535   subsegT subseg;
6536 
6537   if ((score_ops_hsh = hash_new ()) == NULL)
6538     as_fatal (_("virtual memory exhausted"));
6539 
6540   build_score_ops_hsh ();
6541 
6542   if ((dependency_insn_hsh = hash_new ()) == NULL)
6543     as_fatal (_("virtual memory exhausted"));
6544 
6545   build_dependency_insn_hsh ();
6546 
6547   for (i = (int)REG_TYPE_FIRST; i < (int)REG_TYPE_MAX; i++)
6548     build_reg_hsh (all_reg_maps + i);
6549 
6550   /* Initialize dependency vector.  */
6551   init_dependency_vector ();
6552 
6553   bfd_set_arch_mach (stdoutput, TARGET_ARCH, 0);
6554   seg = now_seg;
6555   subseg = now_subseg;
6556   pdr_seg = subseg_new (".pdr", (subsegT) 0);
6557   (void)bfd_set_section_flags (stdoutput, pdr_seg, SEC_READONLY | SEC_RELOC | SEC_DEBUGGING);
6558   (void)bfd_set_section_alignment (stdoutput, pdr_seg, 2);
6559   subseg_set (seg, subseg);
6560 
6561   if (USE_GLOBAL_POINTER_OPT)
6562     bfd_set_gp_size (stdoutput, g_switch_value);
6563 }
6564 
6565 
6566 const pseudo_typeS md_pseudo_table[] =
6567 {
6568   {"bss", s_score_bss, 0},
6569   {"text", s_score_text, 0},
6570   {"word", cons, 4},
6571   {"long", cons, 4},
6572   {"extend", float_cons, 'x'},
6573   {"ldouble", float_cons, 'x'},
6574   {"packed", float_cons, 'p'},
6575   {"end", s_score_end, 0},
6576   {"ent", s_score_ent, 0},
6577   {"frame", s_score_frame, 0},
6578   {"rdata", s_change_sec, 'r'},
6579   {"sdata", s_change_sec, 's'},
6580   {"set", s_score_set, 0},
6581   {"mask", s_score_mask, 'R'},
6582   {"dword", cons, 8},
6583   {"lcomm", s_score_lcomm, 1},
6584   {"section", score_s_section, 0},
6585   {"cpload", s_score_cpload, 0},
6586   {"cprestore", s_score_cprestore, 0},
6587   {"gpword", s_score_gpword, 0},
6588   {"cpadd", s_score_cpadd, 0},
6589   {0, 0, 0}
6590 };
6591 
6592