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