Remove duplicate definitions of the md_atof() function
[platform/upstream/binutils.git] / gas / config / tc-score.c
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