OSDN Git Service

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