OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [binutils-2.18.50/] [gas/] [config/] [tc-score.c] - Blame information for rev 856

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.