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