OSDN Git Service

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