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.  */
98const char comment_chars[] = "#";
99const char line_comment_chars[] = "#";
100const char line_separator_chars[] = ";";
101
102/* Chars that can be used to separate mant from exp in floating point numbers.  */
103const char EXP_CHARS[] = "eE";
104const char FLT_CHARS[] = "rRsSfFdDxXeEpP";
105
106/* Used to contain constructed error messages.  */
107static char err_msg[255];
108
109fragS *score_fragp = 0;
110static int fix_data_dependency = 0;
111static int warn_fix_data_dependency = 1;
112static int score7 = 1;
113static int university_version = 0;
114
115static 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.  */
121static int nor1 = 1;
122
123/* Default will do instruction relax, -O0 will set g_opt = 0.  */
124static unsigned int g_opt = 1;
125
126/* The size of the small data section.  */
127static unsigned int g_switch_value = 8;
128
129#ifdef OBJ_ELF
130/* Pre-defined "_GLOBAL_OFFSET_TABLE_"  */
131symbolS *GOT_symbol;
132#endif
133static segT pdr_seg;
134
135enum score_pic_level score_pic = NO_PIC;
136
137#define INSN_NAME_LEN 16
138struct 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};
157struct score_it inst;
158
159typedef 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}
170procS;
171
172static procS cur_proc;
173static procS *cur_proc_ptr;
174static int numprocs;
175
176#define SCORE7_PIPELINE 7
177#define SCORE5_PIPELINE 5
178static int vector_size = SCORE7_PIPELINE;
179struct 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
187LITTLENUM_TYPE fp_values[NUM_FLOAT_VALS][MAX_LITTLENUMS];
188
189/* Structure for a hash table entry for a register.  */
190struct reg_entry
191{
192  const char *name;
193  int number;
194};
195
196static 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
209static const struct reg_entry score_srn_table[] =
210{
211  {"sr0", 0}, {"sr1", 1}, {"sr2", 2},
212  {NULL, 0}
213};
214
215static 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
228struct reg_map
229{
230  const struct reg_entry *names;
231  int max_regno;
232  struct hash_control *htab;
233  const char *expected;
234};
235
236struct 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
243static struct hash_control *score_ops_hsh = NULL;
244
245static struct hash_control *dependency_insn_hsh = NULL;
246
247/* Enumeration matching entries in table above.  */
248enum 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
257typedef struct literalS
258{
259  struct expressionS exp;
260  struct score_it *inst;
261}
262literalT;
263
264literalT literals[MAX_LITERAL_POOL_SIZE];
265
266static void do_ldst_insn (char *);
267static void do_crdcrscrsimm5 (char *);
268static void do_ldst_unalign (char *);
269static void do_ldst_atomic (char *);
270static void do_ldst_cop (char *);
271static void do_macro_li_rdi32 (char *);
272static void do_macro_la_rdi32 (char *);
273static void do_macro_rdi32hi (char *);
274static void do_macro_rdi32lo (char *);
275static void do_macro_mul_rdrsrs (char *);
276static void do_macro_ldst_label (char *);
277static void do_branch (char *);
278static void do_jump (char *);
279static void do_empty (char *);
280static void do_rdrsrs (char *);
281static void do_rdsi16 (char *);
282static void do_rdrssi14 (char *);
283static void do_sub_rdsi16 (char *);
284static void do_sub_rdrssi14 (char *);
285static void do_rdrsi5 (char *);
286static void do_rdrsi14 (char *);
287static void do_rdi16 (char *);
288static void do_xrsi5 (char *);
289static void do_rdrs (char *);
290static void do_rdxrs (char *);
291static void do_rsrs (char *);
292static void do_rdcrs (char *);
293static void do_rdsrs (char *);
294static void do_rd (char *);
295static void do_rs (char *);
296static void do_i15 (char *);
297static void do_xi5x (char *);
298static void do_ceinst (char *);
299static void do_cache (char *);
300static void do16_rdrs (char *);
301static void do16_rs (char *);
302static void do16_xrs (char *);
303static void do16_mv_rdrs (char *);
304static void do16_hrdrs (char *);
305static void do16_rdhrs (char *);
306static void do16_rdi4 (char *);
307static void do16_rdi5 (char *);
308static void do16_xi5 (char *);
309static void do16_ldst_insn (char *);
310static void do16_ldst_imm_insn (char *);
311static void do16_push_pop (char *);
312static void do16_branch (char *);
313static void do16_jump (char *);
314static void do_rdi16_pic (char *);
315static void do_addi_s_pic (char *);
316static void do_addi_u_pic (char *);
317static void do_lw_pic (char *);
318
319static 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
347static 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.  */
790int next_literal_pool_place = 0;
791
792/* Next literal pool number.  */
793int lit_pool_num = 1;
794symbolS *current_poolP = NULL;
795
796
797static int
798end_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
814static int
815score_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
845static int
846reg_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
884static int
885skip_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
911static void
912do_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
944static int
945walk_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
958static int
959my_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
1014static int
1015validate_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
1096static int
1097data_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
1320static void
1321do_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
1353static void
1354do_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
1366static void
1367do_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.  */
1379static void
1380do_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.  */
1393static void
1394do_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
1418static void
1419do_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.  */
1432static void
1433do_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.  */
1453static void
1454do_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
1471static void
1472do_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
1482static void
1483do_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
1495static void
1496do_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
1508static void
1509do_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
1521static void
1522do_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
1534static void
1535do_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
1543static void
1544do_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
1561static void
1562do_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
1570static void
1571do_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
1585static void
1586do_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.  */
1639static void
1640do_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
1652static void
1653do_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
1675static void
1676do_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>.  */
1697static void
1698do_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
1718static void
1719do_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
1747static int
1748reglow_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!.  */
1778static void
1779do16_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
1811static void
1812do16_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!.  */
1831static void
1832do16_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
1848static int
1849reghigh_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!.  */
1873static void
1874do16_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!.  */
1890static void
1891do16_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.  */
1912static fixS *
1913fix_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
1932static void
1933init_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
1943static enum insn_type_for_dependency
1944dependency_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
1958static int
1959check_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
1989static void
1990build_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
2025static void
2026handle_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
2151static enum insn_class
2152get_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
2227static unsigned long
2228adjust_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
2270static void
2271gen_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
2372static void
2373parse_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
2421static int
2422append_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;  */
2441static void
2442do16_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
2503static void
2504do16_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
2546static void
2547do16_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.  */
2565static void
2566do16_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.  */
2581static int
2582validate_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
2604static int
2605exp_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
2681static void
2682do_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
3190static void
3191do_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
3253static void
3254do_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.  */
3283static void
3284do_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
3321static void
3322do16_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!.  */
3363static void
3364do16_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
3436static void
3437do16_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.  */
3517static void
3518do_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.  */
3616static void
3617do_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
3660static void
3661build_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
3759static void
3760build_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.  */
3900static void
3901do_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.  */
3958static void
3959do_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.  */
4017static void
4018do_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
4096static void
4097exp_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
4131static int
4132nopic_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
4185static void
4186build_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
4246static void
4247do_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
4435static void
4436do_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
4463static void
4464do_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
4494static void
4495do_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
4524static void
4525do16_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
4549static void
4550do_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
4590static void
4591do16_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.  */
4616static void
4617build_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
4643static void
4644build_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
4672void
4673md_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
4681static valueT
4682md_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
4719char *
4720md_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
4780static bfd_boolean
4781pic_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
4829static int
4830judge_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.  */
4858int
4859md_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
4868static int
4869b32_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
4932int
4933score_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
5137void
5138md_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
5187void
5188score_frag_check (fragS * fragp ATTRIBUTE_UNUSED)
5189{
5190  know (fragp->insn_addr <= RELAX_PAD_BYTE);
5191}
5192
5193bfd_boolean
5194score_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().  */
5216void
5217score_validate_fix (fixS *fixP)
5218{
5219  fixP->fx_where += fixP->fx_frag->insn_addr;
5220}
5221
5222long
5223md_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
5241int
5242score_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.  */
5260valueT
5261md_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
5268void
5269md_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.  */
5485arelent **
5486tc_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
5593void
5594score_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
5606static void
5607parse_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
5649void
5650md_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.  */
5667void
5668md_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
5680const 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
5702struct 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
5722size_t md_longopts_size = sizeof (md_longopts);
5723
5724int
5725md_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
5783void
5784md_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.  */
5823static void
5824s_score_bss (int ignore ATTRIBUTE_UNUSED)
5825{
5826  subseg_set (bss_section, (subsegT) get_absolute_expression ());
5827  demand_empty_rest_of_line ();
5828}
5829
5830static void
5831s_score_text (int ignore)
5832{
5833  obj_elf_text (ignore);
5834  record_alignment (now_seg, 2);
5835}
5836
5837static void
5838score_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
5846static void
5847s_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
5879static void
5880s_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
5903static symbolS *
5904get_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
5917static long
5918get_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
5969static void
5970s_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
6016static void
6017s_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.  */
6071static void
6072s_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.  */
6154static void
6155s_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
6218static void
6219s_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
6253static void
6254s_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.  */
6308static void
6309s_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
6335static void
6336s_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
6376static void
6377s_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
6566static void
6567insert_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
6585static void
6586build_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
6600void
6601md_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
6636const 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
6662