Add support for Score target.
[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 *head_fixp = NULL;
3606 long where;
3607 struct score_it inst_main;
3608
3609 memcpy (&inst_main, &fix_insts[0], sizeof (struct score_it));
3610
3611 /* Adjust instruction opcode and to be relaxed instruction opcode. */
3612 inst_main.instruction = adjust_paritybit (inst_main.instruction, GET_INSN_CLASS (inst_main.type));
3613 inst_main.type = Insn_PIC;
3614
3615 for (i = 0; i < var_num; i++)
3616 {
3617 inst_main.relax_size += var_insts[i].size;
3618 var_insts[i].instruction = adjust_paritybit (var_insts[i].instruction,
3619 GET_INSN_CLASS (var_insts[i].type));
3620 }
3621
3622 /* Check data dependency. */
3623 handle_dependency (&inst_main);
3624
3625 /* Start a new frag if frag_now is not empty. */
3626 if (frag_now_fix () != 0)
3627 {
3628 if (!frag_now->tc_frag_data.is_insn)
3629 {
3630 frag_wane (frag_now);
3631 }
3632 frag_new (0);
3633 }
3634 frag_grow (20);
3635
3636 /* Write fr_fix part. */
3637 p = frag_more (inst_main.size);
3638 md_number_to_chars (p, inst_main.instruction, inst_main.size);
3639
3640 if (inst_main.reloc.type != BFD_RELOC_NONE)
3641 {
3642 fixp = fix_new_score (frag_now, p - frag_now->fr_literal, inst_main.size,
3643 &inst_main.reloc.exp, inst_main.reloc.pc_rel, inst_main.reloc.type);
3644 }
3645
3646 head_fixp = xmalloc (sizeof (fixS *));
3647 frag_now->tc_frag_data.fixp = head_fixp;
3648
3649 if (fixp)
3650 {
3651 head_fixp->fx_next = fixp;
3652 head_fixp = head_fixp->fx_next;
3653 }
3654
3655 #ifdef OBJ_ELF
3656 dwarf2_emit_insn (inst_main.size);
3657 #endif
3658
3659 where = p - frag_now->fr_literal + inst_main.size;
3660 for (i = 0; i < var_num; i++)
3661 {
3662 if (i > 0)
3663 where += var_insts[i - 1].size;
3664
3665 if (var_insts[i].reloc.type != BFD_RELOC_NONE)
3666 {
3667 fixp = fix_new_score (frag_now, where, var_insts[i].size,
3668 &var_insts[i].reloc.exp, var_insts[i].reloc.pc_rel,
3669 var_insts[i].reloc.type);
3670 if (fixp)
3671 {
3672 head_fixp->fx_next = fixp;
3673 head_fixp = head_fixp->fx_next;
3674 }
3675 }
3676 }
3677
3678 head_fixp = frag_now->tc_frag_data.fixp;
3679 frag_now->tc_frag_data.fixp = head_fixp->fx_next;
3680 free (head_fixp);
3681
3682 p = frag_var (rs_machine_dependent, inst_main.relax_size + RELAX_PAD_BYTE, 0,
3683 RELAX_ENCODE (inst_main.size, inst_main.relax_size, inst_main.type,
3684 0, inst_main.size, 0), add_symbol, 0, NULL);
3685
3686 /* Write fr_var part.
3687 no calling gen_insn_frag, no fixS will be generated. */
3688 for (i = 0; i < var_num; i++)
3689 {
3690 md_number_to_chars (p, var_insts[i].instruction, var_insts[i].size);
3691 p += var_insts[i].size;
3692 }
3693 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
3694 inst.bwarn = -1;
3695 }
3696
3697 /* Build a relax frag for la instruction when generating PIC,
3698 external symbol first and local symbol second. */
3699
3700 static void
3701 build_la_pic (int reg_rd, expressionS exp)
3702 {
3703 symbolS *add_symbol = exp.X_add_symbol;
3704 offsetT add_number = exp.X_add_number;
3705 struct score_it fix_insts[RELAX_INST_NUM];
3706 struct score_it var_insts[RELAX_INST_NUM];
3707 int fix_num = 0;
3708 int var_num = 0;
3709 char tmp[MAX_LITERAL_POOL_SIZE];
3710 int r1_bak;
3711
3712 r1_bak = nor1;
3713 nor1 = 0;
3714
3715 if (add_number == 0)
3716 {
3717 fix_num = 1;
3718 var_num = 2;
3719
3720 /* Insn 1 and Insn 2 */
3721 /* Fix part
3722 For an external symbol: lw rD, <sym>($gp)
3723 (BFD_RELOC_SCORE_GOT15 or BFD_RELOC_SCORE_CALL15) */
3724 sprintf (tmp, "lw_pic r%d, %s", reg_rd, add_symbol->bsym->name);
3725 if (append_insn (tmp, FALSE) == (int) FAIL)
3726 return;
3727
3728 if (reg_rd == PIC_CALL_REG)
3729 inst.reloc.type = BFD_RELOC_SCORE_CALL15;
3730 memcpy (&fix_insts[0], &inst, sizeof (struct score_it));
3731
3732 /* Var part
3733 For a local symbol :
3734 lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15)
3735 addi rD, <sym> (BFD_RELOC_GOT_LO16) */
3736 inst.reloc.type = BFD_RELOC_SCORE_GOT15;
3737 memcpy (&var_insts[0], &inst, sizeof (struct score_it));
3738 sprintf (tmp, "addi_s_pic r%d, %s", reg_rd, add_symbol->bsym->name);
3739 if (append_insn (tmp, FALSE) == (int) FAIL)
3740 return;
3741
3742 memcpy (&var_insts[1], &inst, sizeof (struct score_it));
3743 build_relax_frag (fix_insts, fix_num, var_insts, var_num, add_symbol);
3744 }
3745 else if (add_number >= -0x8000 && add_number <= 0x7fff)
3746 {
3747 /* Insn 1: lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15) */
3748 sprintf (tmp, "lw_pic r%d, %s", reg_rd, add_symbol->bsym->name);
3749 if (append_insn (tmp, TRUE) == (int) FAIL)
3750 return;
3751
3752 /* Insn 2 */
3753 fix_num = 1;
3754 var_num = 1;
3755 /* Fix part
3756 For an external symbol: addi rD, <constant> */
3757 sprintf (tmp, "addi r%d, %d", reg_rd, (int)add_number);
3758 if (append_insn (tmp, FALSE) == (int) FAIL)
3759 return;
3760
3761 memcpy (&fix_insts[0], &inst, sizeof (struct score_it));
3762
3763 /* Var part
3764 For a local symbol: addi rD, <sym>+<constant> (BFD_RELOC_GOT_LO16) */
3765 sprintf (tmp, "addi_s_pic r%d, %s + %d", reg_rd, add_symbol->bsym->name, (int)add_number);
3766 if (append_insn (tmp, FALSE) == (int) FAIL)
3767 return;
3768
3769 memcpy (&var_insts[0], &inst, sizeof (struct score_it));
3770 build_relax_frag (fix_insts, fix_num, var_insts, var_num, add_symbol);
3771 }
3772 else
3773 {
3774 int hi = (add_number >> 16) & 0x0000FFFF;
3775 int lo = add_number & 0x0000FFFF;
3776
3777 /* Insn 1: lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15) */
3778 sprintf (tmp, "lw_pic r%d, %s", reg_rd, add_symbol->bsym->name);
3779 if (append_insn (tmp, TRUE) == (int) FAIL)
3780 return;
3781
3782 /* Insn 2 */
3783 fix_num = 1;
3784 var_num = 1;
3785 /* Fix part
3786 For an external symbol: ldis r1, HI%<constant> */
3787 sprintf (tmp, "ldis %s, %d", "r1", hi);
3788 if (append_insn (tmp, FALSE) == (int) FAIL)
3789 return;
3790
3791 memcpy (&fix_insts[0], &inst, sizeof (struct score_it));
3792
3793 /* Var part
3794 For a local symbol: ldis r1, HI%<constant>
3795 but, if lo is outof 16 bit, make hi plus 1 */
3796 if ((lo < -0x8000) || (lo > 0x7fff))
3797 {
3798 hi += 1;
3799 }
3800 sprintf (tmp, "ldis_pic %s, %d", "r1", hi);
3801 if (append_insn (tmp, FALSE) == (int) FAIL)
3802 return;
3803
3804 memcpy (&var_insts[0], &inst, sizeof (struct score_it));
3805 build_relax_frag (fix_insts, fix_num, var_insts, var_num, add_symbol);
3806
3807 /* Insn 3 */
3808 fix_num = 1;
3809 var_num = 1;
3810 /* Fix part
3811 For an external symbol: ori r1, LO%<constant> */
3812 sprintf (tmp, "ori %s, %d", "r1", lo);
3813 if (append_insn (tmp, FALSE) == (int) FAIL)
3814 return;
3815
3816 memcpy (&fix_insts[0], &inst, sizeof (struct score_it));
3817
3818 /* Var part
3819 For a local symbol: addi r1, <sym>+LO%<constant> (BFD_RELOC_GOT_LO16) */
3820 sprintf (tmp, "addi_u_pic %s, %s + %d", "r1", add_symbol->bsym->name, lo);
3821 if (append_insn (tmp, FALSE) == (int) FAIL)
3822 return;
3823
3824 memcpy (&var_insts[0], &inst, sizeof (struct score_it));
3825 build_relax_frag (fix_insts, fix_num, var_insts, var_num, add_symbol);
3826
3827 /* Insn 4: add rD, rD, r1 */
3828 sprintf (tmp, "add r%d, r%d, %s", reg_rd, reg_rd, "r1");
3829 if (append_insn (tmp, TRUE) == (int) FAIL)
3830 return;
3831
3832 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
3833 inst.bwarn = -1;
3834 }
3835
3836 nor1 = r1_bak;
3837 }
3838
3839 /* Handle la. */
3840 static void
3841 do_macro_la_rdi32 (char *str)
3842 {
3843 int reg_rd;
3844
3845 skip_whitespace (str);
3846 if ((reg_rd = reg_required_here (&str, 20, REG_TYPE_SCORE)) == (int) FAIL
3847 || skip_past_comma (&str) == (int) FAIL)
3848 {
3849 return;
3850 }
3851 else
3852 {
3853 char append_str[MAX_LITERAL_POOL_SIZE];
3854 char *keep_data = str;
3855
3856 /* la rd, simm16. */
3857 if (data_op2 (&str, 1, _SIMM16_LA) != (int) FAIL)
3858 {
3859 end_of_line (str);
3860 return;
3861 }
3862 /* la rd, imm32 or la rd, label. */
3863 else
3864 {
3865 SET_INSN_ERROR (NULL);
3866 str = keep_data;
3867 if ((data_op2 (&str, 1, _VALUE_HI16) == (int) FAIL)
3868 || (end_of_line (str) == (int) FAIL))
3869 {
3870 return;
3871 }
3872 else
3873 {
3874 if ((score_pic == NO_PIC) || (!inst.reloc.exp.X_add_symbol))
3875 {
3876 sprintf (append_str, "ld_i32hi r%d, %s", reg_rd, keep_data);
3877 if (append_insn (append_str, TRUE) == (int) FAIL)
3878 return;
3879
3880 sprintf (append_str, "ld_i32lo r%d, %s", reg_rd, keep_data);
3881 if (append_insn (append_str, TRUE) == (int) FAIL)
3882 return;
3883 }
3884 else
3885 {
3886 assert (inst.reloc.exp.X_add_symbol);
3887 build_la_pic (reg_rd, inst.reloc.exp);
3888 }
3889
3890 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
3891 inst.bwarn = -1;
3892 }
3893 }
3894 }
3895 }
3896
3897 /* Handle li. */
3898 static void
3899 do_macro_li_rdi32 (char *str){
3900
3901 int reg_rd;
3902
3903 skip_whitespace (str);
3904 if ((reg_rd = reg_required_here (&str, 20, REG_TYPE_SCORE)) == (int) FAIL
3905 || skip_past_comma (&str) == (int) FAIL)
3906 {
3907 return;
3908 }
3909 else
3910 {
3911 char *keep_data = str;
3912
3913 /* li rd, simm16. */
3914 if (data_op2 (&str, 1, _SIMM16_LA) != (int) FAIL)
3915 {
3916 end_of_line (str);
3917 return;
3918 }
3919 /* li rd, imm32. */
3920 else
3921 {
3922 char append_str[MAX_LITERAL_POOL_SIZE];
3923
3924 str = keep_data;
3925
3926 if ((data_op2 (&str, 1, _VALUE_HI16) == (int) FAIL)
3927 || (end_of_line (str) == (int) FAIL))
3928 {
3929 return;
3930 }
3931 else if (inst.reloc.exp.X_add_symbol)
3932 {
3933 inst.error = _("li rd label isn't correct instruction form");
3934 return;
3935 }
3936 else
3937 {
3938 sprintf (append_str, "ld_i32hi r%d, %s", reg_rd, keep_data);
3939
3940 if (append_insn (append_str, TRUE) == (int) FAIL)
3941 return;
3942 else
3943 {
3944 sprintf (append_str, "ld_i32lo r%d, %s", reg_rd, keep_data);
3945 if (append_insn (append_str, TRUE) == (int) FAIL)
3946 return;
3947
3948 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
3949 inst.bwarn = -1;
3950 }
3951 }
3952 }
3953 }
3954 }
3955
3956 /* Handle mul/mulu/div/divu/rem/remu. */
3957 static void
3958 do_macro_mul_rdrsrs (char *str)
3959 {
3960 int reg_rd;
3961 int reg_rs1;
3962 int reg_rs2;
3963 char *backupstr;
3964 char append_str[MAX_LITERAL_POOL_SIZE];
3965
3966 if (university_version == 1)
3967 as_warn ("%s", ERR_FOR_SCORE5U_MUL_DIV);
3968
3969 strcpy (append_str, str);
3970 backupstr = append_str;
3971 skip_whitespace (backupstr);
3972 if (((reg_rd = reg_required_here (&backupstr, -1, REG_TYPE_SCORE)) == (int) FAIL)
3973 || (skip_past_comma (&backupstr) == (int) FAIL)
3974 || ((reg_rs1 = reg_required_here (&backupstr, -1, REG_TYPE_SCORE)) == (int) FAIL))
3975 {
3976 inst.error = BAD_ARGS;
3977 return;
3978 }
3979
3980 if (skip_past_comma (&backupstr) == (int) FAIL)
3981 {
3982 /* rem/remu rA, rB is error format. */
3983 if (strcmp (inst.name, "rem") == 0 || strcmp (inst.name, "remu") == 0)
3984 {
3985 SET_INSN_ERROR (BAD_ARGS);
3986 }
3987 else
3988 {
3989 SET_INSN_ERROR (NULL);
3990 do_rsrs (str);
3991 }
3992 return;
3993 }
3994 else
3995 {
3996 SET_INSN_ERROR (NULL);
3997 if (((reg_rs2 = reg_required_here (&backupstr, -1, REG_TYPE_SCORE)) == (int) FAIL)
3998 || (end_of_line (backupstr) == (int) FAIL))
3999 {
4000 return;
4001 }
4002 else
4003 {
4004 char append_str1[MAX_LITERAL_POOL_SIZE];
4005
4006 if (strcmp (inst.name, "rem") == 0)
4007 {
4008 sprintf (append_str, "%s r%d, r%d", "mul", reg_rs1, reg_rs2);
4009 sprintf (append_str1, "mfceh r%d", reg_rd);
4010 }
4011 else if (strcmp (inst.name, "remu") == 0)
4012 {
4013 sprintf (append_str, "%s r%d, r%d", "mulu", reg_rs1, reg_rs2);
4014 sprintf (append_str1, "mfceh r%d", reg_rd);
4015 }
4016 else
4017 {
4018 sprintf (append_str, "%s r%d, r%d", inst.name, reg_rs1, reg_rs2);
4019 sprintf (append_str1, "mfcel r%d", reg_rd);
4020 }
4021
4022 /* Output mul/mulu or div/divu or rem/remu. */
4023 if (append_insn (append_str, TRUE) == (int) FAIL)
4024 return;
4025
4026 /* Output mfcel or mfceh. */
4027 if (append_insn (append_str1, TRUE) == (int) FAIL)
4028 return;
4029
4030 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4031 inst.bwarn = -1;
4032 }
4033 }
4034 }
4035
4036 static void
4037 exp_macro_ldst_abs (char *str)
4038 {
4039 int reg_rd;
4040 char *backupstr, *tmp;
4041 char append_str[MAX_LITERAL_POOL_SIZE];
4042 char verifystr[MAX_LITERAL_POOL_SIZE];
4043 struct score_it inst_backup;
4044 int r1_bak = 0;
4045
4046 r1_bak = nor1;
4047 nor1 = 0;
4048 memcpy (&inst_backup, &inst, sizeof (struct score_it));
4049
4050 strcpy (verifystr, str);
4051 backupstr = verifystr;
4052 skip_whitespace (backupstr);
4053 if ((reg_rd = reg_required_here (&backupstr, -1, REG_TYPE_SCORE)) == (int) FAIL)
4054 return;
4055
4056 tmp = backupstr;
4057 if (skip_past_comma (&backupstr) == (int) FAIL)
4058 return;
4059
4060 backupstr = tmp;
4061 sprintf (append_str, "li r1 %s", backupstr);
4062 append_insn (append_str, TRUE);
4063
4064 memcpy (&inst, &inst_backup, sizeof (struct score_it));
4065 sprintf (append_str, " r%d, [r1,0]", reg_rd);
4066 do_ldst_insn (append_str);
4067
4068 nor1 = r1_bak;
4069 }
4070
4071 static int
4072 nopic_need_relax (symbolS * sym, int before_relaxing)
4073 {
4074 if (sym == NULL)
4075 return 0;
4076 else if (USE_GLOBAL_POINTER_OPT && g_switch_value > 0)
4077 {
4078 const char *symname;
4079 const char *segname;
4080
4081 /* Find out whether this symbol can be referenced off the $gp
4082 register. It can be if it is smaller than the -G size or if
4083 it is in the .sdata or .sbss section. Certain symbols can
4084 not be referenced off the $gp, although it appears as though
4085 they can. */
4086 symname = S_GET_NAME (sym);
4087 if (symname != (const char *)NULL
4088 && (strcmp (symname, "eprol") == 0
4089 || strcmp (symname, "etext") == 0
4090 || strcmp (symname, "_gp") == 0
4091 || strcmp (symname, "edata") == 0
4092 || strcmp (symname, "_fbss") == 0
4093 || strcmp (symname, "_fdata") == 0
4094 || strcmp (symname, "_ftext") == 0
4095 || strcmp (symname, "end") == 0
4096 || strcmp (symname, GP_DISP_LABEL) == 0))
4097 {
4098 return 1;
4099 }
4100 else if ((!S_IS_DEFINED (sym) || S_IS_COMMON (sym)) && (0
4101 /* We must defer this decision until after the whole file has been read,
4102 since there might be a .extern after the first use of this symbol. */
4103 || (before_relaxing
4104 && S_GET_VALUE (sym) == 0)
4105 || (S_GET_VALUE (sym) != 0
4106 && S_GET_VALUE (sym) <= g_switch_value)))
4107 {
4108 return 0;
4109 }
4110
4111 segname = segment_name (S_GET_SEGMENT (sym));
4112 return (strcmp (segname, ".sdata") != 0
4113 && strcmp (segname, ".sbss") != 0
4114 && strncmp (segname, ".sdata.", 7) != 0
4115 && strncmp (segname, ".gnu.linkonce.s.", 16) != 0);
4116 }
4117 /* We are not optimizing for the $gp register. */
4118 else
4119 return 1;
4120 }
4121
4122 /* Build a relax frag for lw instruction when generating PIC,
4123 external symbol first and local symbol second. */
4124
4125 static void
4126 build_lw_pic (int reg_rd, expressionS exp)
4127 {
4128 symbolS *add_symbol = exp.X_add_symbol;
4129 int add_number = exp.X_add_number;
4130 struct score_it fix_insts[RELAX_INST_NUM];
4131 struct score_it var_insts[RELAX_INST_NUM];
4132 int fix_num = 0;
4133 int var_num = 0;
4134 char tmp[MAX_LITERAL_POOL_SIZE];
4135 int r1_bak;
4136
4137 r1_bak = nor1;
4138 nor1 = 0;
4139
4140 if ((add_number == 0) || (add_number >= -0x8000 && add_number <= 0x7fff))
4141 {
4142 fix_num = 1;
4143 var_num = 2;
4144
4145 /* Insn 1 and Insn 2 */
4146 /* Fix part
4147 For an external symbol: lw rD, <sym>($gp)
4148 (BFD_RELOC_SCORE_GOT15) */
4149 sprintf (tmp, "lw_pic r%d, %s", reg_rd, add_symbol->bsym->name);
4150 if (append_insn (tmp, FALSE) == (int) FAIL)
4151 return;
4152
4153 memcpy (&fix_insts[0], &inst, sizeof (struct score_it));
4154
4155 /* Var part
4156 For a local symbol :
4157 lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15)
4158 addi rD, <sym> (BFD_RELOC_GOT_LO16) */
4159 inst.reloc.type = BFD_RELOC_SCORE_GOT15;
4160 memcpy (&var_insts[0], &inst, sizeof (struct score_it));
4161 sprintf (tmp, "addi_s_pic r%d, %s", reg_rd, add_symbol->bsym->name);
4162 if (append_insn (tmp, FALSE) == (int) FAIL)
4163 return;
4164
4165 memcpy (&var_insts[1], &inst, sizeof (struct score_it));
4166 build_relax_frag (fix_insts, fix_num, var_insts, var_num, add_symbol);
4167
4168 /* Insn 2: lw rD, [rD, constant] */
4169 sprintf (tmp, "lw r%d, [r%d, %d]", reg_rd, reg_rd, add_number);
4170 if (append_insn (tmp, TRUE) == (int) FAIL)
4171 return;
4172
4173 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4174 inst.bwarn = -1;
4175 }
4176 else
4177 {
4178 int hi = (add_number >> 16) & 0x0000FFFF;
4179 int lo = add_number & 0x0000FFFF;
4180
4181 /* Insn 1: lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15) */
4182 sprintf (tmp, "lw_pic r%d, %s", reg_rd, add_symbol->bsym->name);
4183 if (append_insn (tmp, TRUE) == (int) FAIL)
4184 return;
4185
4186 /* Insn 2 */
4187 fix_num = 1;
4188 var_num = 1;
4189 /* Fix part
4190 For an external symbol: ldis r1, HI%<constant> */
4191 sprintf (tmp, "ldis %s, %d", "r1", hi);
4192 if (append_insn (tmp, FALSE) == (int) FAIL)
4193 return;
4194
4195 memcpy (&fix_insts[0], &inst, sizeof (struct score_it));
4196
4197 /* Var part
4198 For a local symbol: ldis r1, HI%<constant>
4199 but, if lo is outof 16 bit, make hi plus 1 */
4200 if ((lo < -0x8000) || (lo > 0x7fff))
4201 {
4202 hi += 1;
4203 }
4204 sprintf (tmp, "ldis_pic %s, %d", "r1", hi);
4205 if (append_insn (tmp, FALSE) == (int) FAIL)
4206 return;
4207
4208 memcpy (&var_insts[0], &inst, sizeof (struct score_it));
4209 build_relax_frag (fix_insts, fix_num, var_insts, var_num, add_symbol);
4210
4211 /* Insn 3 */
4212 fix_num = 1;
4213 var_num = 1;
4214 /* Fix part
4215 For an external symbol: ori r1, LO%<constant> */
4216 sprintf (tmp, "ori %s, %d", "r1", lo);
4217 if (append_insn (tmp, FALSE) == (int) FAIL)
4218 return;
4219
4220 memcpy (&fix_insts[0], &inst, sizeof (struct score_it));
4221
4222 /* Var part
4223 For a local symbol: addi r1, <sym>+LO%<constant> (BFD_RELOC_GOT_LO16) */
4224 sprintf (tmp, "addi_u_pic %s, %s + %d", "r1", add_symbol->bsym->name, lo);
4225 if (append_insn (tmp, FALSE) == (int) FAIL)
4226 return;
4227
4228 memcpy (&var_insts[0], &inst, sizeof (struct score_it));
4229 build_relax_frag (fix_insts, fix_num, var_insts, var_num, add_symbol);
4230
4231 /* Insn 4: add rD, rD, r1 */
4232 sprintf (tmp, "add r%d, r%d, %s", reg_rd, reg_rd, "r1");
4233 if (append_insn (tmp, TRUE) == (int) FAIL)
4234 return;
4235
4236 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4237 inst.bwarn = -1;
4238
4239 /* Insn 5: lw rD, [rD, 0] */
4240 sprintf (tmp, "lw r%d, [r%d, 0]", reg_rd, reg_rd);
4241 if (append_insn (tmp, TRUE) == (int) FAIL)
4242 return;
4243
4244 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4245 inst.bwarn = -1;
4246 }
4247
4248 nor1 = r1_bak;
4249 }
4250
4251 static void
4252 do_macro_ldst_label (char *str)
4253 {
4254 int i;
4255 int ldst_gp_p = 0;
4256 int reg_rd;
4257 int r1_bak;
4258 char *backup_str;
4259 char *label_str;
4260 char *absolute_value;
4261 char append_str[3][MAX_LITERAL_POOL_SIZE];
4262 char verifystr[MAX_LITERAL_POOL_SIZE];
4263 struct score_it inst_backup;
4264 struct score_it inst_expand[3];
4265 struct score_it inst_main;
4266
4267 memcpy (&inst_backup, &inst, sizeof (struct score_it));
4268 strcpy (verifystr, str);
4269 backup_str = verifystr;
4270
4271 skip_whitespace (backup_str);
4272 if ((reg_rd = reg_required_here (&backup_str, -1, REG_TYPE_SCORE)) == (int) FAIL)
4273 return;
4274
4275 if (skip_past_comma (&backup_str) == (int) FAIL)
4276 return;
4277
4278 label_str = backup_str;
4279
4280 /* Ld/st rD, [rA, imm] ld/st rD, [rA]+, imm ld/st rD, [rA, imm]+. */
4281 if (*backup_str == '[')
4282 {
4283 do_ldst_insn (str);
4284 return;
4285 }
4286
4287 /* Ld/st rD, imm. */
4288 absolute_value = backup_str;
4289 if ((my_get_expression (&inst.reloc.exp, &backup_str) == (int) FAIL)
4290 || (validate_immediate (inst.reloc.exp.X_add_number, _VALUE) == (int) FAIL)
4291 || (end_of_line (backup_str) == (int) FAIL))
4292 {
4293 return;
4294 }
4295 else
4296 {
4297 if (inst.reloc.exp.X_add_symbol == 0)
4298 {
4299 memcpy (&inst, &inst_backup, sizeof (struct score_it));
4300 exp_macro_ldst_abs (str);
4301 return;
4302 }
4303 }
4304
4305 /* Ld/st rD, label. */
4306 backup_str = absolute_value;
4307 if ((data_op2 (&backup_str, 1, _GP_IMM15) == (int) FAIL)
4308 || (end_of_line (backup_str) == (int) FAIL))
4309 {
4310 return;
4311 }
4312 else
4313 {
4314 if (inst.reloc.exp.X_add_symbol == 0)
4315 {
4316 if (!inst.error)
4317 inst.error = BAD_ARGS;
4318
4319 return;
4320 }
4321
4322 if (score_pic == PIC)
4323 {
4324 build_lw_pic (reg_rd, inst.reloc.exp);
4325 return;
4326 }
4327 else
4328 {
4329 if ((inst.reloc.exp.X_add_number <= 0x3fff)
4330 && (inst.reloc.exp.X_add_number >= -0x4000)
4331 && (!nopic_need_relax (inst.reloc.exp.X_add_symbol, 1)))
4332 {
4333 int ldst_idx = 0;
4334
4335 /* Assign the real opcode. */
4336 ldst_idx = inst.instruction & OPC_PSEUDOLDST_MASK;
4337 inst.instruction &= ~OPC_PSEUDOLDST_MASK;
4338 inst.instruction |= score_ldst_insns[ldst_idx * 3 + 0].value;
4339 inst.instruction |= reg_rd << 20;
4340 inst.instruction |= GP << 15;
4341 inst.relax_inst = 0x8000;
4342 inst.relax_size = 0;
4343 ldst_gp_p = 1;
4344 }
4345 }
4346 }
4347
4348 /* Backup inst. */
4349 memcpy (&inst_main, &inst, sizeof (struct score_it));
4350 r1_bak = nor1;
4351 nor1 = 0;
4352
4353 /* Determine which instructions should be output. */
4354 sprintf (append_str[0], "ld_i32hi r1, %s", label_str);
4355 sprintf (append_str[1], "ld_i32lo r1, %s", label_str);
4356 sprintf (append_str[2], "%s r%d, [r1, 0]", inst_backup.name, reg_rd);
4357
4358 /* Generate three instructions.
4359 la r1, label
4360 ld/st rd, [r1, 0] */
4361 for (i = 0; i < 3; i++)
4362 {
4363 if (append_insn (append_str[i], FALSE) == (int) FAIL)
4364 return;
4365
4366 memcpy (&inst_expand[i], &inst, sizeof (struct score_it));
4367 }
4368
4369 if (ldst_gp_p)
4370 {
4371 char *p;
4372
4373 /* Adjust instruction opcode and to be relaxed instruction opcode. */
4374 inst_main.instruction = adjust_paritybit (inst_main.instruction, GET_INSN_CLASS (inst_main.type));
4375 inst_main.relax_size = inst_expand[0].size + inst_expand[1].size + inst_expand[2].size;
4376 inst_main.type = Insn_GP;
4377
4378 for (i = 0; i < 3; i++)
4379 inst_expand[i].instruction = adjust_paritybit (inst_expand[i].instruction
4380 , GET_INSN_CLASS (inst_expand[i].type));
4381
4382 /* Check data dependency. */
4383 handle_dependency (&inst_main);
4384
4385 /* Start a new frag if frag_now is not empty. */
4386 if (frag_now_fix () != 0)
4387 {
4388 if (!frag_now->tc_frag_data.is_insn)
4389 frag_wane (frag_now);
4390
4391 frag_new (0);
4392 }
4393 frag_grow (20);
4394
4395 /* Write fr_fix part. */
4396 p = frag_more (inst_main.size);
4397 md_number_to_chars (p, inst_main.instruction, inst_main.size);
4398
4399 if (inst_main.reloc.type != BFD_RELOC_NONE)
4400 {
4401 fix_new_score (frag_now, p - frag_now->fr_literal, inst_main.size,
4402 &inst_main.reloc.exp, inst_main.reloc.pc_rel, inst_main.reloc.type);
4403 }
4404
4405 #ifdef OBJ_ELF
4406 dwarf2_emit_insn (inst_main.size);
4407 #endif
4408
4409 /* GP instruction can not do optimization, only can do relax between
4410 1 instruction and 3 instructions. */
4411 p = frag_var (rs_machine_dependent, inst_main.relax_size + RELAX_PAD_BYTE, 0,
4412 RELAX_ENCODE (inst_main.size, inst_main.relax_size, inst_main.type, 0, 4, 0),
4413 inst_main.reloc.exp.X_add_symbol, 0, NULL);
4414
4415 /* Write fr_var part.
4416 no calling gen_insn_frag, no fixS will be generated. */
4417 md_number_to_chars (p, inst_expand[0].instruction, inst_expand[0].size);
4418 p += inst_expand[0].size;
4419 md_number_to_chars (p, inst_expand[1].instruction, inst_expand[1].size);
4420 p += inst_expand[1].size;
4421 md_number_to_chars (p, inst_expand[2].instruction, inst_expand[2].size);
4422 }
4423 else
4424 {
4425 gen_insn_frag (&inst_expand[0], NULL);
4426 gen_insn_frag (&inst_expand[1], NULL);
4427 gen_insn_frag (&inst_expand[2], NULL);
4428 }
4429 nor1 = r1_bak;
4430
4431 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4432 inst.bwarn = -1;
4433 }
4434
4435 static void
4436 do_lw_pic (char *str)
4437 {
4438 int reg_rd;
4439
4440 skip_whitespace (str);
4441 if (((reg_rd = reg_required_here (&str, 20, REG_TYPE_SCORE)) == (int) FAIL)
4442 || (skip_past_comma (&str) == (int) FAIL)
4443 || (my_get_expression (&inst.reloc.exp, &str) == (int) FAIL)
4444 || (end_of_line (str) == (int) FAIL))
4445 {
4446 return;
4447 }
4448 else
4449 {
4450 if (inst.reloc.exp.X_add_symbol == 0)
4451 {
4452 if (!inst.error)
4453 inst.error = BAD_ARGS;
4454
4455 return;
4456 }
4457
4458 inst.instruction |= GP << 15;
4459 inst.reloc.type = BFD_RELOC_SCORE_GOT15;
4460 }
4461 }
4462
4463 static void
4464 do_empty (char *str)
4465 {
4466 str = str;
4467 if (university_version == 1)
4468 {
4469 if (((inst.instruction & 0x3e0003ff) == 0x0c000004)
4470 || ((inst.instruction & 0x3e0003ff) == 0x0c000024)
4471 || ((inst.instruction & 0x3e0003ff) == 0x0c000044)
4472 || ((inst.instruction & 0x3e0003ff) == 0x0c000064))
4473 {
4474 inst.error = ERR_FOR_SCORE5U_MMU;
4475 return;
4476 }
4477 }
4478 if (end_of_line (str) == (int) FAIL)
4479 return;
4480
4481 if (inst.relax_inst != 0x8000)
4482 {
4483 if (inst.type == NO_OPD)
4484 {
4485 inst.relax_size = 2;
4486 }
4487 else
4488 {
4489 inst.relax_size = 4;
4490 }
4491 }
4492 }
4493
4494 static void
4495 do_jump (char *str)
4496 {
4497 char *save_in;
4498 char err_msg[100];
4499
4500 skip_whitespace (str);
4501 if (my_get_expression (&inst.reloc.exp, &str) == (int) FAIL
4502 || end_of_line (str) == (int) FAIL)
4503 return;
4504
4505 if (inst.reloc.exp.X_add_symbol == 0)
4506 {
4507 inst.error = _("lacking label ");
4508 return;
4509 }
4510
4511 if (((inst.reloc.exp.X_add_number & 0xff000000) != 0)
4512 && ((inst.reloc.exp.X_add_number & 0xff000000) != 0xff000000))
4513 {
4514 sprintf (err_msg, "invalid constant: 25 bit expression not in range -2^24..2^24");
4515 inst.error = _(err_msg);
4516 return;
4517 }
4518
4519 save_in = input_line_pointer;
4520 input_line_pointer = str;
4521 inst.reloc.type = BFD_RELOC_SCORE_JMP;
4522 inst.reloc.pc_rel = 1;
4523 input_line_pointer = save_in;
4524 }
4525
4526 static void
4527 do16_jump (char *str)
4528 {
4529 skip_whitespace (str);
4530 if (my_get_expression (&inst.reloc.exp, &str) == (int) FAIL
4531 || end_of_line (str) == (int) FAIL)
4532 {
4533 return;
4534 }
4535 else if (inst.reloc.exp.X_add_symbol == 0)
4536 {
4537 inst.error = _("lacking label ");
4538 return;
4539 }
4540 else if (((inst.reloc.exp.X_add_number & 0xfffff800) != 0)
4541 && ((inst.reloc.exp.X_add_number & 0xfffff800) != 0xfffff800))
4542 {
4543 inst.error = _("invalid constant: 12 bit expression not in range -2^11..2^11");
4544 return;
4545 }
4546
4547 inst.reloc.type = BFD_RELOC_SCORE16_JMP;
4548 inst.reloc.pc_rel = 1;
4549 }
4550
4551 static void
4552 do_branch (char *str)
4553 {
4554 unsigned long abs_value = 0;
4555
4556 if (my_get_expression (&inst.reloc.exp, &str) == (int) FAIL
4557 || end_of_line (str) == (int) FAIL)
4558 {
4559 return;
4560 }
4561 else if (inst.reloc.exp.X_add_symbol == 0)
4562 {
4563 inst.error = _("lacking label ");
4564 return;
4565 }
4566 else if (((inst.reloc.exp.X_add_number & 0xff000000) != 0)
4567 && ((inst.reloc.exp.X_add_number & 0xff000000) != 0xff000000))
4568 {
4569 inst.error = "invalid constant: 20 bit expression not in range -2^19..2^19";
4570 return;
4571 }
4572
4573 inst.reloc.type = BFD_RELOC_SCORE_BRANCH;
4574 inst.reloc.pc_rel = 1;
4575
4576 /* Branch 32 offset field : 20 bit, 16 bit branch offset field : 8 bit. */
4577 inst.instruction |= (inst.reloc.exp.X_add_number & 0x3fe) | ((inst.reloc.exp.X_add_number & 0xffc00) << 5);
4578
4579 /* Take the branch condition code. */
4580 inst.relax_inst = 0x4000 | (((inst.instruction >> 10) & 0xf) << 8);
4581
4582 if ((abs_value & 0xfffffe00) == 0)
4583 {
4584 inst.relax_inst |= ((inst.reloc.exp.X_add_number >> 1) & 0xff);
4585 inst.relax_size = 2;
4586 }
4587 else
4588 {
4589 inst.relax_inst = 0x8000;
4590 }
4591
4592 if (inst.instruction & 1)
4593 inst.relax_inst = 0x8000;
4594 }
4595
4596 static void
4597 do16_branch (char *str)
4598 {
4599 if ((my_get_expression (&inst.reloc.exp, &str) == (int) FAIL
4600 || end_of_line (str) == (int) FAIL))
4601 {
4602 ;
4603 }
4604 else if (inst.reloc.exp.X_add_symbol == 0)
4605 {
4606 inst.error = _("lacking label");
4607 }
4608 else if (((inst.reloc.exp.X_add_number & 0xffffff00) != 0)
4609 && ((inst.reloc.exp.X_add_number & 0xffffff00) != 0xffffff00))
4610 {
4611 inst.error = _("invalid constant: 9 bit expression not in range -2^8..2^8");
4612 }
4613 else
4614 {
4615 inst.reloc.type = BFD_RELOC_SCORE16_BRANCH;
4616 inst.reloc.pc_rel = 1;
4617 inst.instruction |= ((inst.reloc.exp.X_add_number >> 1) & 0xff);
4618 }
4619 }
4620
4621 /* Iterate over the base tables to create the instruction patterns. */
4622 static void
4623 build_score_ops_hsh (void)
4624 {
4625 unsigned int i;
4626 static struct obstack insn_obstack;
4627
4628 obstack_begin (&insn_obstack, 4000);
4629 for (i = 0; i < sizeof (score_insns) / sizeof (struct asm_opcode); i++)
4630 {
4631 const struct asm_opcode *insn = score_insns + i;
4632 unsigned len = strlen (insn->template);
4633 struct asm_opcode *new;
4634 char *template;
4635 new = obstack_alloc (&insn_obstack, sizeof (struct asm_opcode));
4636 template = obstack_alloc (&insn_obstack, len + 1);
4637
4638 strcpy (template, insn->template);
4639 new->template = template;
4640 new->parms = insn->parms;
4641 new->value = insn->value;
4642 new->relax_value = insn->relax_value;
4643 new->type = insn->type;
4644 new->bitmask = insn->bitmask;
4645 hash_insert (score_ops_hsh, new->template, (void *) new);
4646 }
4647 }
4648
4649 static void
4650 build_dependency_insn_hsh (void)
4651 {
4652 unsigned int i;
4653 static struct obstack dependency_obstack;
4654
4655 obstack_begin (&dependency_obstack, 4000);
4656 for (i = 0; i < sizeof (insn_to_dependency_table) / sizeof (insn_to_dependency_table[0]); i++)
4657 {
4658 const struct insn_to_dependency *tmp = insn_to_dependency_table + i;
4659 unsigned len = strlen (tmp->insn_name);
4660 struct insn_to_dependency *new;
4661
4662 new = obstack_alloc (&dependency_obstack, sizeof (struct insn_to_dependency));
4663 new->insn_name = obstack_alloc (&dependency_obstack, len + 1);
4664
4665 strcpy (new->insn_name, tmp->insn_name);
4666 new->type = tmp->type;
4667 hash_insert (dependency_insn_hsh, new->insn_name, (void *) new);
4668 }
4669 }
4670
4671 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
4672 for use in the a.out file, and stores them in the array pointed to by buf.
4673 This knows about the endian-ness of the target machine and does
4674 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
4675 2 (short) and 4 (long) Floating numbers are put out as a series of
4676 LITTLENUMS (shorts, here at least). */
4677
4678 void
4679 md_number_to_chars (char *buf, valueT val, int n)
4680 {
4681 if (target_big_endian)
4682 number_to_chars_bigendian (buf, val, n);
4683 else
4684 number_to_chars_littleendian (buf, val, n);
4685 }
4686
4687 static valueT
4688 md_chars_to_number (char *buf, int n)
4689 {
4690 valueT result = 0;
4691 unsigned char *where = (unsigned char *)buf;
4692
4693 if (target_big_endian)
4694 {
4695 while (n--)
4696 {
4697 result <<= 8;
4698 result |= (*where++ & 255);
4699 }
4700 }
4701 else
4702 {
4703 while (n--)
4704 {
4705 result <<= 8;
4706 result |= (where[n] & 255);
4707 }
4708 }
4709
4710 return result;
4711 }
4712
4713 /* Turn a string in input_line_pointer into a floating point constant
4714 of type TYPE, and store the appropriate bytes in *LITP. The number
4715 of LITTLENUMS emitted is stored in *SIZEP. An error message is
4716 returned, or NULL on OK.
4717
4718 Note that fp constants aren't represent in the normal way on the ARM.
4719 In big endian mode, things are as expected. However, in little endian
4720 mode fp constants are big-endian word-wise, and little-endian byte-wise
4721 within the words. For example, (double) 1.1 in big endian mode is
4722 the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
4723 the byte sequence 99 99 f1 3f 9a 99 99 99. */
4724
4725 char *
4726 md_atof (int type, char *litP, int *sizeP)
4727 {
4728 int prec;
4729 LITTLENUM_TYPE words[MAX_LITTLENUMS];
4730 char *t;
4731 int i;
4732
4733 switch (type)
4734 {
4735 case 'f':
4736 case 'F':
4737 case 's':
4738 case 'S':
4739 prec = 2;
4740 break;
4741 case 'd':
4742 case 'D':
4743 case 'r':
4744 case 'R':
4745 prec = 4;
4746 break;
4747 case 'x':
4748 case 'X':
4749 case 'p':
4750 case 'P':
4751 prec = 6;
4752 break;
4753 default:
4754 *sizeP = 0;
4755 return _("bad call to MD_ATOF()");
4756 }
4757
4758 t = atof_ieee (input_line_pointer, type, words);
4759 if (t)
4760 input_line_pointer = t;
4761 *sizeP = prec * 2;
4762
4763 if (target_big_endian)
4764 {
4765 for (i = 0; i < prec; i++)
4766 {
4767 md_number_to_chars (litP, (valueT) words[i], 2);
4768 litP += 2;
4769 }
4770 }
4771 else
4772 {
4773 for (i = 0; i < prec; i += 2)
4774 {
4775 md_number_to_chars (litP, (valueT) words[i + 1], 2);
4776 md_number_to_chars (litP + 2, (valueT) words[i], 2);
4777 litP += 4;
4778 }
4779 }
4780
4781 return 0;
4782 }
4783
4784 /* Return true if the given symbol should be considered local for PIC. */
4785
4786 static bfd_boolean
4787 pic_need_relax (symbolS *sym, asection *segtype)
4788 {
4789 asection *symsec;
4790 bfd_boolean linkonce;
4791
4792 /* Handle the case of a symbol equated to another symbol. */
4793 while (symbol_equated_reloc_p (sym))
4794 {
4795 symbolS *n;
4796
4797 /* It's possible to get a loop here in a badly written
4798 program. */
4799 n = symbol_get_value_expression (sym)->X_add_symbol;
4800 if (n == sym)
4801 break;
4802 sym = n;
4803 }
4804
4805 symsec = S_GET_SEGMENT (sym);
4806
4807 /* duplicate the test for LINK_ONCE sections as in adjust_reloc_syms */
4808 linkonce = FALSE;
4809 if (symsec != segtype && ! S_IS_LOCAL (sym))
4810 {
4811 if ((bfd_get_section_flags (stdoutput, symsec) & SEC_LINK_ONCE) != 0)
4812 linkonce = TRUE;
4813
4814 /* The GNU toolchain uses an extension for ELF: a section
4815 beginning with the magic string .gnu.linkonce is a linkonce
4816 section. */
4817 if (strncmp (segment_name (symsec), ".gnu.linkonce",
4818 sizeof ".gnu.linkonce" - 1) == 0)
4819 linkonce = TRUE;
4820 }
4821
4822 /* This must duplicate the test in adjust_reloc_syms. */
4823 return (symsec != &bfd_und_section
4824 && symsec != &bfd_abs_section
4825 && ! bfd_is_com_section (symsec)
4826 && !linkonce
4827 #ifdef OBJ_ELF
4828 /* A global or weak symbol is treated as external. */
4829 && (OUTPUT_FLAVOR != bfd_target_elf_flavour
4830 || (! S_IS_WEAK (sym) && ! S_IS_EXTERNAL (sym)))
4831 #endif
4832 );
4833 }
4834
4835 static int
4836 judge_size_before_relax (fragS * fragp, asection *sec)
4837 {
4838 int change = 0;
4839
4840 if (score_pic == NO_PIC)
4841 change = nopic_need_relax (fragp->fr_symbol, 0);
4842 else
4843 change = pic_need_relax (fragp->fr_symbol, sec);
4844
4845 if (change == 1)
4846 {
4847 /* Only at the first time determining whether GP instruction relax should be done,
4848 return the difference between insntruction size and instruction relax size. */
4849 if (fragp->fr_opcode == NULL)
4850 {
4851 fragp->fr_fix = RELAX_NEW (fragp->fr_subtype);
4852 fragp->fr_opcode = fragp->fr_literal + RELAX_RELOC1 (fragp->fr_subtype);
4853 return RELAX_NEW (fragp->fr_subtype) - RELAX_OLD (fragp->fr_subtype);
4854 }
4855 }
4856
4857 return 0;
4858 }
4859
4860 /* In this function, we determine whether GP instruction should do relaxation,
4861 for the label being against was known now.
4862 Doing this here but not in md_relax_frag() can induce iteration times
4863 in stage of doing relax. */
4864 int
4865 md_estimate_size_before_relax (fragS * fragp, asection * sec ATTRIBUTE_UNUSED)
4866 {
4867 if ((RELAX_TYPE (fragp->fr_subtype) == Insn_GP)
4868 || (RELAX_TYPE (fragp->fr_subtype) == Insn_PIC))
4869 return judge_size_before_relax (fragp, sec);
4870
4871 return 0;
4872 }
4873
4874 static int
4875 b32_relax_to_b16 (fragS * fragp)
4876 {
4877 int grows = 0;
4878 int relaxable_p = 0;
4879 int old;
4880 int new;
4881 int frag_addr = fragp->fr_address + fragp->insn_addr;
4882
4883 addressT symbol_address = 0;
4884 symbolS *s;
4885 offsetT offset;
4886 unsigned long value;
4887 unsigned long abs_value;
4888
4889 /* FIXME : here may be able to modify better .
4890 I don't know how to get the fragp's section ,
4891 so in relax stage , it may be wrong to calculate the symbol's offset when the frag's section
4892 is different from the symbol's. */
4893
4894 old = RELAX_OLD (fragp->fr_subtype);
4895 new = RELAX_NEW (fragp->fr_subtype);
4896 relaxable_p = RELAX_OPT (fragp->fr_subtype);
4897
4898 s = fragp->fr_symbol;
4899 /* b/bl immediate */
4900 if (s == NULL)
4901 frag_addr = 0;
4902 else
4903 {
4904 if (s->bsym != 0)
4905 symbol_address = (addressT) s->sy_frag->fr_address;
4906 }
4907
4908 value = md_chars_to_number (fragp->fr_literal, INSN_SIZE);
4909
4910 /* b 32's offset : 20 bit, b 16's tolerate field : 0xff. */
4911 offset = ((value & 0x3ff0000) >> 6) | (value & 0x3fe);
4912 if ((offset & 0x80000) == 0x80000)
4913 offset |= 0xfff00000;
4914
4915 abs_value = offset + symbol_address - frag_addr;
4916 if ((abs_value & 0x80000000) == 0x80000000)
4917 abs_value = 0xffffffff - abs_value + 1;
4918
4919 /* Relax branch 32 to branch 16. */
4920 if (relaxable_p && (s->bsym != NULL) && ((abs_value & 0xffffff00) == 0)
4921 && (S_IS_DEFINED (s) && !S_IS_COMMON (s) && !S_IS_EXTERNAL (s)))
4922 {
4923 /* do nothing. */
4924 }
4925 else
4926 {
4927 /* Branch 32 can not be relaxed to b 16, so clear OPT bit. */
4928 fragp->fr_opcode = NULL;
4929 fragp->fr_subtype = RELAX_OPT_CLEAR (fragp->fr_subtype);
4930 }
4931
4932 return grows;
4933 }
4934
4935 /* Main purpose is to determine whether one frag should do relax.
4936 frag->fr_opcode indicates this point. */
4937
4938 int
4939 score_relax_frag (asection * sec ATTRIBUTE_UNUSED, fragS * fragp, long stretch ATTRIBUTE_UNUSED)
4940 {
4941 int grows = 0;
4942 int insn_size;
4943 int insn_relax_size;
4944 int do_relax_p = 0; /* Indicate doing relaxation for this frag. */
4945 int relaxable_p = 0;
4946 bfd_boolean word_align_p = FALSE;
4947 fragS *next_fragp;
4948
4949 /* If the instruction address is odd, make it half word align first. */
4950 if ((fragp->fr_address) % 2 != 0)
4951 {
4952 if ((fragp->fr_address + fragp->insn_addr) % 2 != 0)
4953 {
4954 fragp->insn_addr = 1;
4955 grows += 1;
4956 }
4957 }
4958
4959 word_align_p = ((fragp->fr_address + fragp->insn_addr) % 4 == 0) ? TRUE : FALSE;
4960
4961 /* Get instruction size and relax size after the last relaxation. */
4962 if (fragp->fr_opcode)
4963 {
4964 insn_size = RELAX_NEW (fragp->fr_subtype);
4965 insn_relax_size = RELAX_OLD (fragp->fr_subtype);
4966 }
4967 else
4968 {
4969 insn_size = RELAX_OLD (fragp->fr_subtype);
4970 insn_relax_size = RELAX_NEW (fragp->fr_subtype);
4971 }
4972
4973 /* Handle specially for GP instruction. for, judge_size_before_relax() has already determine
4974 whether the GP instruction should do relax. */
4975 if ((RELAX_TYPE (fragp->fr_subtype) == Insn_GP)
4976 || (RELAX_TYPE (fragp->fr_subtype) == Insn_PIC))
4977 {
4978 if (!word_align_p)
4979 {
4980 fragp->insn_addr += 2;
4981 grows += 2;
4982 }
4983
4984 if (fragp->fr_opcode)
4985 fragp->fr_fix = RELAX_NEW (fragp->fr_subtype) + fragp->insn_addr;
4986 else
4987 fragp->fr_fix = RELAX_OLD (fragp->fr_subtype) + fragp->insn_addr;
4988 }
4989 else
4990 {
4991 if (RELAX_TYPE (fragp->fr_subtype) == PC_DISP19div2)
4992 b32_relax_to_b16 (fragp);
4993
4994 relaxable_p = RELAX_OPT (fragp->fr_subtype);
4995 next_fragp = fragp->fr_next;
4996 while ((next_fragp) && (next_fragp->fr_type != rs_machine_dependent))
4997 {
4998 next_fragp = next_fragp->fr_next;
4999 }
5000
5001 if (next_fragp)
5002 {
5003 int n_insn_size;
5004 int n_relaxable_p = 0;
5005
5006 if (next_fragp->fr_opcode)
5007 {
5008 n_insn_size = RELAX_NEW (next_fragp->fr_subtype);
5009 }
5010 else
5011 {
5012 n_insn_size = RELAX_OLD (next_fragp->fr_subtype);
5013 }
5014
5015 n_relaxable_p = RELAX_OPT (next_fragp->fr_subtype);
5016
5017 if (word_align_p)
5018 {
5019 if (insn_size == 4)
5020 {
5021 /* 32 -> 16. */
5022 if (relaxable_p && ((n_insn_size == 2) || n_relaxable_p))
5023 {
5024 grows -= 2;
5025 do_relax_p = 1;
5026 }
5027 }
5028 else if (insn_size == 2)
5029 {
5030 /* 16 -> 32. */
5031 if (relaxable_p && ((n_insn_size == 4) && !n_relaxable_p))
5032 {
5033 grows += 2;
5034 do_relax_p = 1;
5035 }
5036 }
5037 else
5038 {
5039 abort ();
5040 }
5041 }
5042 else
5043 {
5044 if (insn_size == 4)
5045 {
5046 /* 32 -> 16. */
5047 if (relaxable_p)
5048 {
5049 grows -= 2;
5050 do_relax_p = 1;
5051 }
5052 /* Make the 32 bit insturction word align. */
5053 else
5054 {
5055 fragp->insn_addr += 2;
5056 grows += 2;
5057 }
5058 }
5059 else if (insn_size == 2)
5060 {
5061 /* Do nothing. */
5062 }
5063 else
5064 {
5065 abort ();
5066 }
5067 }
5068 }
5069 else
5070 {
5071 /* Here, try best to do relax regardless fragp->fr_next->fr_type. */
5072 if (word_align_p == FALSE)
5073 {
5074 if (insn_size % 4 == 0)
5075 {
5076 /* 32 -> 16. */
5077 if (relaxable_p)
5078 {
5079 grows -= 2;
5080 do_relax_p = 1;
5081 }
5082 else
5083 {
5084 fragp->insn_addr += 2;
5085 grows += 2;
5086 }
5087 }
5088 }
5089 else
5090 {
5091 /* Do nothing. */
5092 }
5093 }
5094
5095 /* fragp->fr_opcode indicates whether this frag should be relaxed. */
5096 if (do_relax_p)
5097 {
5098 if (fragp->fr_opcode)
5099 {
5100 fragp->fr_opcode = NULL;
5101 /* Guarantee estimate stage is correct. */
5102 fragp->fr_fix = RELAX_OLD (fragp->fr_subtype);
5103 fragp->fr_fix += fragp->insn_addr;
5104 }
5105 else
5106 {
5107 fragp->fr_opcode = fragp->fr_literal + RELAX_RELOC1 (fragp->fr_subtype);
5108 /* Guarantee estimate stage is correct. */
5109 fragp->fr_fix = RELAX_NEW (fragp->fr_subtype);
5110 fragp->fr_fix += fragp->insn_addr;
5111 }
5112 }
5113 else
5114 {
5115 if (fragp->fr_opcode)
5116 {
5117 /* Guarantee estimate stage is correct. */
5118 fragp->fr_fix = RELAX_NEW (fragp->fr_subtype);
5119 fragp->fr_fix += fragp->insn_addr;
5120 }
5121 else
5122 {
5123 /* Guarantee estimate stage is correct. */
5124 fragp->fr_fix = RELAX_OLD (fragp->fr_subtype);
5125 fragp->fr_fix += fragp->insn_addr;
5126 }
5127 }
5128 }
5129
5130 return grows;
5131 }
5132
5133 void
5134 md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED, segT sec ATTRIBUTE_UNUSED, fragS * fragp)
5135 {
5136 int old;
5137 int new;
5138 char backup[20];
5139 fixS *fixp;
5140
5141 old = RELAX_OLD (fragp->fr_subtype);
5142 new = RELAX_NEW (fragp->fr_subtype);
5143
5144 /* fragp->fr_opcode indicates whether this frag should be relaxed. */
5145 if (fragp->fr_opcode == NULL)
5146 {
5147 memcpy (backup, fragp->fr_literal, old);
5148 fragp->fr_fix = old;
5149 }
5150 else
5151 {
5152 memcpy (backup, fragp->fr_literal + old, new);
5153 fragp->fr_fix = new;
5154 }
5155
5156 fixp = fragp->tc_frag_data.fixp;
5157 while (fixp && fixp->fx_frag == fragp && fixp->fx_where < old)
5158 {
5159 if (fragp->fr_opcode)
5160 fixp->fx_done = 1;
5161 fixp = fixp->fx_next;
5162 }
5163 while (fixp && fixp->fx_frag == fragp)
5164 {
5165 if (fragp->fr_opcode)
5166 fixp->fx_where -= old + fragp->insn_addr;
5167 else
5168 fixp->fx_done = 1;
5169 fixp = fixp->fx_next;
5170 }
5171
5172 if (fragp->insn_addr)
5173 {
5174 md_number_to_chars (fragp->fr_literal, 0x0, fragp->insn_addr);
5175 }
5176 memcpy (fragp->fr_literal + fragp->insn_addr, backup, fragp->fr_fix);
5177 fragp->fr_fix += fragp->insn_addr;
5178 }
5179
5180 /* Implementation of md_frag_check.
5181 Called after md_convert_frag(). */
5182
5183 void
5184 score_frag_check (fragS * fragp ATTRIBUTE_UNUSED)
5185 {
5186 know (fragp->insn_addr <= RELAX_PAD_BYTE);
5187 }
5188
5189 bfd_boolean
5190 score_fix_adjustable (fixS * fixP)
5191 {
5192 if (fixP->fx_addsy == NULL)
5193 {
5194 return 1;
5195 }
5196 else if (OUTPUT_FLAVOR == bfd_target_elf_flavour
5197 && (S_IS_EXTERNAL (fixP->fx_addsy) || S_IS_WEAK (fixP->fx_addsy)))
5198 {
5199 return 0;
5200 }
5201 else if (fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
5202 || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
5203 {
5204 return 0;
5205 }
5206
5207 return 1;
5208 }
5209
5210 /* Implementation of TC_VALIDATE_FIX.
5211 Called before md_apply_fix() and after md_convert_frag(). */
5212 void
5213 score_validate_fix (fixS *fixP)
5214 {
5215 fixP->fx_where += fixP->fx_frag->insn_addr;
5216 }
5217
5218 long
5219 md_pcrel_from (fixS * fixP)
5220 {
5221 long retval = 0;
5222
5223 if (fixP->fx_addsy
5224 && (S_GET_SEGMENT (fixP->fx_addsy) == undefined_section)
5225 && (fixP->fx_subsy == NULL))
5226 {
5227 retval = 0;
5228 }
5229 else
5230 {
5231 retval = fixP->fx_where + fixP->fx_frag->fr_address;
5232 }
5233
5234 return retval;
5235 }
5236
5237 int
5238 score_force_relocation (struct fix *fixp)
5239 {
5240 int retval = 0;
5241
5242 if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
5243 || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY
5244 || fixp->fx_r_type == BFD_RELOC_SCORE_JMP
5245 || fixp->fx_r_type == BFD_RELOC_SCORE_BRANCH
5246 || fixp->fx_r_type == BFD_RELOC_SCORE16_JMP
5247 || fixp->fx_r_type == BFD_RELOC_SCORE16_BRANCH)
5248 {
5249 retval = 1;
5250 }
5251
5252 return retval;
5253 }
5254
5255 /* Round up a section size to the appropriate boundary. */
5256 valueT
5257 md_section_align (segT segment ATTRIBUTE_UNUSED, valueT size)
5258 {
5259 int align = bfd_get_section_alignment (stdoutput, segment);
5260
5261 #ifdef OBJ_ELF
5262 /* We don't need to align ELF sections to the full alignment.
5263 However, Irix 5 may prefer that we align them at least to a 16
5264 byte boundary. We don't bother to align the sections if we are
5265 targeted for an embedded system. */
5266 if (strcmp (TARGET_OS, "elf") == 0)
5267 return size;
5268 if (align > 4)
5269 align = 4;
5270 #endif
5271
5272 return ((size + (1 << align) - 1) & (-1 << align));
5273 }
5274
5275 void
5276 md_apply_fix (fixS *fixP, valueT *valP, segT seg)
5277 {
5278 offsetT value = *valP;
5279 offsetT abs_value = 0;
5280 offsetT newval;
5281 offsetT content;
5282 unsigned short HI, LO;
5283
5284 char *buf = fixP->fx_frag->fr_literal + fixP->fx_where;
5285
5286 assert (fixP->fx_r_type < BFD_RELOC_UNUSED);
5287 if (fixP->fx_addsy == 0 && !fixP->fx_pcrel)
5288 {
5289 if (fixP->fx_r_type != BFD_RELOC_SCORE_DUMMY_HI16)
5290 fixP->fx_done = 1;
5291 }
5292
5293 /* If this symbol is in a different section then we need to leave it for
5294 the linker to deal with. Unfortunately, md_pcrel_from can't tell,
5295 so we have to undo it's effects here. */
5296 if (fixP->fx_pcrel)
5297 {
5298 if (fixP->fx_addsy != NULL
5299 && S_IS_DEFINED (fixP->fx_addsy)
5300 && S_GET_SEGMENT (fixP->fx_addsy) != seg)
5301 value += md_pcrel_from (fixP);
5302 }
5303
5304 /* Remember value for emit_reloc. */
5305 fixP->fx_addnumber = value;
5306
5307 switch (fixP->fx_r_type)
5308 {
5309 case BFD_RELOC_HI16_S:
5310 if (fixP->fx_done)
5311 { /* For la rd, imm32. */
5312 newval = md_chars_to_number (buf, INSN_SIZE);
5313 HI = (value) >> 16; /* mul to 2, then take the hi 16 bit. */
5314 newval |= (HI & 0x3fff) << 1;
5315 newval |= ((HI >> 14) & 0x3) << 16;
5316 md_number_to_chars (buf, newval, INSN_SIZE);
5317 }
5318 break;
5319 case BFD_RELOC_LO16:
5320 if (fixP->fx_done) /* For la rd, imm32. */
5321 {
5322 newval = md_chars_to_number (buf, INSN_SIZE);
5323 LO = (value) & 0xffff;
5324 newval |= (LO & 0x3fff) << 1; /* 16 bit: imm -> 14 bit in lo, 2 bit in hi. */
5325 newval |= ((LO >> 14) & 0x3) << 16;
5326 md_number_to_chars (buf, newval, INSN_SIZE);
5327 }
5328 break;
5329 case BFD_RELOC_SCORE_JMP:
5330 {
5331 content = md_chars_to_number (buf, INSN_SIZE);
5332 value = fixP->fx_offset;
5333 content = (content & ~0x3ff7ffe) | ((value << 1) & 0x3ff0000) | (value & 0x7fff);
5334 md_number_to_chars (buf, content, INSN_SIZE);
5335 }
5336 break;
5337 case BFD_RELOC_SCORE_BRANCH:
5338 if ((S_GET_SEGMENT (fixP->fx_addsy) != seg) || (fixP->fx_addsy != NULL && S_IS_EXTERNAL (fixP->fx_addsy)))
5339 value = fixP->fx_offset;
5340 else
5341 fixP->fx_done = 1;
5342
5343 content = md_chars_to_number (buf, INSN_SIZE);
5344 if ((fixP->fx_frag->fr_opcode != 0) && ((content & 0x80008000) != 0x80008000))
5345 {
5346 if ((value & 0x80000000) == 0x80000000)
5347 abs_value = 0xffffffff - value + 1;
5348 if ((abs_value & 0xffffff00) != 0)
5349 {
5350 as_bad_where (fixP->fx_file, fixP->fx_line,
5351 _(" branch relocation truncate (0x%x) [-2^8 ~ 2^8]"), (unsigned int)value);
5352 return;
5353 }
5354 content = md_chars_to_number (buf, INSN16_SIZE);
5355 content &= 0xff00;
5356 content = (content & 0xff00) | ((value >> 1) & 0xff);
5357 md_number_to_chars (buf, content, INSN16_SIZE);
5358 fixP->fx_r_type = BFD_RELOC_SCORE16_BRANCH;
5359 fixP->fx_size = 2;
5360 }
5361 else
5362 {
5363 if ((value & 0x80000000) == 0x80000000)
5364 abs_value = 0xffffffff - value + 1;
5365 if ((abs_value & 0xfff80000) != 0)
5366 {
5367 as_bad_where (fixP->fx_file, fixP->fx_line,
5368 _(" branch relocation truncate (0x%x) [-2^19 ~ 2^19]"), (unsigned int)value);
5369 return;
5370 }
5371 content = md_chars_to_number (buf, INSN_SIZE);
5372 content &= 0xfc00fc01;
5373 content = (content & 0xfc00fc01) | (value & 0x3fe) | ((value << 6) & 0x3ff0000);
5374 md_number_to_chars (buf, content, INSN_SIZE);
5375 }
5376 break;
5377 case BFD_RELOC_SCORE16_JMP:
5378 content = md_chars_to_number (buf, INSN16_SIZE);
5379 content &= 0xf001;
5380 value = fixP->fx_offset & 0xfff;
5381 content = (content & 0xfc01) | (value & 0xffe);
5382 md_number_to_chars (buf, content, INSN16_SIZE);
5383 break;
5384 case BFD_RELOC_SCORE16_BRANCH:
5385 content = md_chars_to_number (buf, INSN_SIZE);
5386 if ((fixP->fx_frag->fr_opcode != 0) && ((content & 0x80008000) == 0x80008000))
5387 {
5388 if ((S_GET_SEGMENT (fixP->fx_addsy) != seg) ||
5389 (fixP->fx_addsy != NULL && S_IS_EXTERNAL (fixP->fx_addsy)))
5390 value = fixP->fx_offset;
5391 else
5392 fixP->fx_done = 1;
5393 if ((value & 0x80000000) == 0x80000000)
5394 abs_value = 0xffffffff - value + 1;
5395 if ((abs_value & 0xfff80000) != 0)
5396 {
5397 as_bad_where (fixP->fx_file, fixP->fx_line,
5398 _(" branch relocation truncate (0x%x) [-2^19 ~ 2^19]"), (unsigned int)value);
5399 return;
5400 }
5401 content = md_chars_to_number (buf, INSN_SIZE);
5402 content = (content & 0xfc00fc01) | (value & 0x3fe) | ((value << 6) & 0x3ff0000);
5403 md_number_to_chars (buf, content, INSN_SIZE);
5404 fixP->fx_r_type = BFD_RELOC_SCORE_BRANCH;
5405 fixP->fx_size = 4;
5406 break;
5407 }
5408 else
5409 {
5410 /* In differnt section. */
5411 if ((S_GET_SEGMENT (fixP->fx_addsy) != seg) ||
5412 (fixP->fx_addsy != NULL && S_IS_EXTERNAL (fixP->fx_addsy)))
5413 value = fixP->fx_offset;
5414 else
5415 fixP->fx_done = 1;
5416
5417 if ((value & 0x80000000) == 0x80000000)
5418 abs_value = 0xffffffff - value + 1;
5419 if ((abs_value & 0xffffff00) != 0)
5420 {
5421 as_bad_where (fixP->fx_file, fixP->fx_line,
5422 _(" branch relocation truncate (0x%x) [-2^8 ~ 2^8]"), (unsigned int)value);
5423 return;
5424 }
5425 content = md_chars_to_number (buf, INSN16_SIZE);
5426 content = (content & 0xff00) | ((value >> 1) & 0xff);
5427 md_number_to_chars (buf, content, INSN16_SIZE);
5428 break;
5429 }
5430 case BFD_RELOC_8:
5431 if (fixP->fx_done || fixP->fx_pcrel)
5432 md_number_to_chars (buf, value, 1);
5433 #ifdef OBJ_ELF
5434 else
5435 {
5436 value = fixP->fx_offset;
5437 md_number_to_chars (buf, value, 1);
5438 }
5439 #endif
5440 break;
5441
5442 case BFD_RELOC_16:
5443 if (fixP->fx_done || fixP->fx_pcrel)
5444 md_number_to_chars (buf, value, 2);
5445 #ifdef OBJ_ELF
5446 else
5447 {
5448 value = fixP->fx_offset;
5449 md_number_to_chars (buf, value, 2);
5450 }
5451 #endif
5452 break;
5453 case BFD_RELOC_RVA:
5454 case BFD_RELOC_32:
5455 if (fixP->fx_done || fixP->fx_pcrel)
5456 md_number_to_chars (buf, value, 4);
5457 #ifdef OBJ_ELF
5458 else
5459 {
5460 value = fixP->fx_offset;
5461 md_number_to_chars (buf, value, 4);
5462 }
5463 #endif
5464 break;
5465 case BFD_RELOC_VTABLE_INHERIT:
5466 fixP->fx_done = 0;
5467 if (fixP->fx_addsy && !S_IS_DEFINED (fixP->fx_addsy) && !S_IS_WEAK (fixP->fx_addsy))
5468 S_SET_WEAK (fixP->fx_addsy);
5469 break;
5470 case BFD_RELOC_VTABLE_ENTRY:
5471 fixP->fx_done = 0;
5472 break;
5473 case BFD_RELOC_SCORE_GPREL15:
5474 content = md_chars_to_number (buf, INSN_SIZE);
5475 if ((fixP->fx_frag->fr_opcode != 0) && ((content & 0xfc1c8000) != 0x94188000))
5476 fixP->fx_r_type = BFD_RELOC_NONE;
5477 fixP->fx_done = 0;
5478 break;
5479 case BFD_RELOC_SCORE_GOT15:
5480 case BFD_RELOC_SCORE_DUMMY_HI16:
5481 case BFD_RELOC_SCORE_GOT_LO16:
5482 case BFD_RELOC_SCORE_CALL15:
5483 case BFD_RELOC_GPREL32:
5484 break;
5485 case BFD_RELOC_NONE:
5486 default:
5487 as_bad_where (fixP->fx_file, fixP->fx_line, _("bad relocation fixup type (%d)"), fixP->fx_r_type);
5488 }
5489 }
5490
5491 /* Translate internal representation of relocation info to BFD target format. */
5492 arelent **
5493 tc_gen_reloc (asection * section ATTRIBUTE_UNUSED, fixS * fixp)
5494 {
5495 static arelent *retval[MAX_RELOC_EXPANSION + 1]; /* MAX_RELOC_EXPANSION equals 2. */
5496 arelent *reloc;
5497 bfd_reloc_code_real_type code;
5498 char *type;
5499 fragS *f;
5500 symbolS *s;
5501 expressionS e;
5502
5503 reloc = retval[0] = xmalloc (sizeof (arelent));
5504 retval[1] = NULL;
5505
5506 reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
5507 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
5508 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
5509 reloc->addend = fixp->fx_offset;
5510
5511 /* If this is a variant frag, we may need to adjust the existing
5512 reloc and generate a new one. */
5513 if (fixp->fx_frag->fr_opcode != NULL && (fixp->fx_r_type == BFD_RELOC_SCORE_GPREL15))
5514 {
5515 /* Update instruction imm bit. */
5516 offsetT newval;
5517 unsigned short off;
5518 char *buf;
5519
5520 buf = fixp->fx_frag->fr_literal + fixp->fx_frag->insn_addr;
5521 newval = md_chars_to_number (buf, INSN_SIZE);
5522 off = fixp->fx_offset >> 16;
5523 newval |= (off & 0x3fff) << 1;
5524 newval |= ((off >> 14) & 0x3) << 16;
5525 md_number_to_chars (buf, newval, INSN_SIZE);
5526
5527 buf += INSN_SIZE;
5528 newval = md_chars_to_number (buf, INSN_SIZE);
5529 off = fixp->fx_offset & 0xffff;
5530 newval |= ((off & 0x3fff) << 1);
5531 newval |= (((off >> 14) & 0x3) << 16);
5532 md_number_to_chars (buf, newval, INSN_SIZE);
5533
5534 retval[1] = xmalloc (sizeof (arelent));
5535 retval[2] = NULL;
5536 retval[1]->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
5537 *retval[1]->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
5538 retval[1]->address = (reloc->address + RELAX_RELOC2 (fixp->fx_frag->fr_subtype));
5539
5540 f = fixp->fx_frag;
5541 s = f->fr_symbol;
5542 e = s->sy_value;
5543
5544 retval[1]->addend = 0;
5545 retval[1]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_LO16);
5546 assert (retval[1]->howto != NULL);
5547
5548 fixp->fx_r_type = BFD_RELOC_HI16_S;
5549 }
5550
5551 code = fixp->fx_r_type;
5552 switch (fixp->fx_r_type)
5553 {
5554 case BFD_RELOC_32:
5555 if (fixp->fx_pcrel)
5556 {
5557 code = BFD_RELOC_32_PCREL;
5558 break;
5559 }
5560 case BFD_RELOC_HI16_S:
5561 case BFD_RELOC_LO16:
5562 case BFD_RELOC_SCORE_JMP:
5563 case BFD_RELOC_SCORE_BRANCH:
5564 case BFD_RELOC_SCORE16_JMP:
5565 case BFD_RELOC_SCORE16_BRANCH:
5566 case BFD_RELOC_VTABLE_ENTRY:
5567 case BFD_RELOC_VTABLE_INHERIT:
5568 case BFD_RELOC_SCORE_GPREL15:
5569 case BFD_RELOC_SCORE_GOT15:
5570 case BFD_RELOC_SCORE_DUMMY_HI16:
5571 case BFD_RELOC_SCORE_GOT_LO16:
5572 case BFD_RELOC_SCORE_CALL15:
5573 case BFD_RELOC_GPREL32:
5574 case BFD_RELOC_NONE:
5575 code = fixp->fx_r_type;
5576 break;
5577 default:
5578 type = _("<unknown>");
5579 as_bad_where (fixp->fx_file, fixp->fx_line,
5580 _("cannot represent %s relocation in this object file format"), type);
5581 return NULL;
5582 }
5583
5584 reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
5585 if (reloc->howto == NULL)
5586 {
5587 as_bad_where (fixp->fx_file, fixp->fx_line,
5588 _("cannot represent %s relocation in this object file format1"),
5589 bfd_get_reloc_code_name (code));
5590 return NULL;
5591 }
5592 /* HACK: Since arm ELF uses Rel instead of Rela, encode the
5593 vtable entry to be used in the relocation's section offset. */
5594 if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
5595 reloc->address = fixp->fx_offset;
5596
5597 return retval;
5598 }
5599
5600 void
5601 score_elf_final_processing (void)
5602 {
5603 if (fix_data_dependency == 1)
5604 {
5605 elf_elfheader (stdoutput)->e_flags |= EF_SCORE_FIXDEP;
5606 }
5607 if (score_pic == PIC)
5608 {
5609 elf_elfheader (stdoutput)->e_flags |= EF_SCORE_PIC;
5610 }
5611 }
5612
5613 static void
5614 parse_pce_inst (char *insnstr)
5615 {
5616 char c;
5617 char *p;
5618 char first[MAX_LITERAL_POOL_SIZE];
5619 char second[MAX_LITERAL_POOL_SIZE];
5620 struct score_it pec_part_1;
5621
5622 /* Get first part string of PCE. */
5623 p = strstr (insnstr, "||");
5624 c = *p;
5625 *p = '\0';
5626 sprintf (first, "%s", insnstr);
5627
5628 /* Get second part string of PCE. */
5629 *p = c;
5630 p += 2;
5631 sprintf (second, "%s", p);
5632
5633 parse_16_32_inst (first, FALSE);
5634 if (inst.error)
5635 return;
5636
5637 memcpy (&pec_part_1, &inst, sizeof (inst));
5638
5639 parse_16_32_inst (second, FALSE);
5640 if (inst.error)
5641 return;
5642
5643 if ( ((pec_part_1.size == INSN_SIZE) && (inst.size == INSN_SIZE))
5644 || ((pec_part_1.size == INSN_SIZE) && (inst.size == INSN16_SIZE))
5645 || ((pec_part_1.size == INSN16_SIZE) && (inst.size == INSN_SIZE)))
5646 {
5647 inst.error = _("pce instruction error (16 bit || 16 bit)'");
5648 sprintf (inst.str, "%s", insnstr);
5649 return;
5650 }
5651
5652 if (!inst.error)
5653 gen_insn_frag (&pec_part_1, &inst);
5654 }
5655
5656 void
5657 md_assemble (char *str)
5658 {
5659 know (str);
5660 know (strlen (str) < MAX_LITERAL_POOL_SIZE);
5661
5662 memset (&inst, '\0', sizeof (inst));
5663 if (INSN_IS_PCE_P (str))
5664 parse_pce_inst (str);
5665 else
5666 parse_16_32_inst (str, TRUE);
5667
5668 if (inst.error)
5669 as_bad ("%s -- `%s'", inst.error, inst.str);
5670 }
5671
5672 /* We handle all bad expressions here, so that we can report the faulty
5673 instruction in the error message. */
5674 void
5675 md_operand (expressionS * expr)
5676 {
5677 if (in_my_get_expression)
5678 {
5679 expr->X_op = O_illegal;
5680 if (inst.error == NULL)
5681 {
5682 inst.error = _("bad expression");
5683 }
5684 }
5685 }
5686
5687 const char *md_shortopts = "nO::g::G:";
5688
5689 #ifdef SCORE_BI_ENDIAN
5690 #define OPTION_EB (OPTION_MD_BASE + 0)
5691 #define OPTION_EL (OPTION_MD_BASE + 1)
5692 #else
5693 #if TARGET_BYTES_BIG_ENDIAN
5694 #define OPTION_EB (OPTION_MD_BASE + 0)
5695 #else
5696 #define OPTION_EL (OPTION_MD_BASE + 1)
5697 #endif
5698 #endif
5699 #define OPTION_FIXDD (OPTION_MD_BASE + 2)
5700 #define OPTION_NWARN (OPTION_MD_BASE + 3)
5701 #define OPTION_SCORE5 (OPTION_MD_BASE + 4)
5702 #define OPTION_SCORE5U (OPTION_MD_BASE + 5)
5703 #define OPTION_SCORE7 (OPTION_MD_BASE + 6)
5704 #define OPTION_R1 (OPTION_MD_BASE + 7)
5705 #define OPTION_O0 (OPTION_MD_BASE + 8)
5706 #define OPTION_SCORE_VERSION (OPTION_MD_BASE + 9)
5707 #define OPTION_PIC (OPTION_MD_BASE + 10)
5708
5709 struct option md_longopts[] =
5710 {
5711 #ifdef OPTION_EB
5712 {"EB" , no_argument, NULL, OPTION_EB},
5713 #endif
5714 #ifdef OPTION_EL
5715 {"EL" , no_argument, NULL, OPTION_EL},
5716 #endif
5717 {"FIXDD" , no_argument, NULL, OPTION_FIXDD},
5718 {"NWARN" , no_argument, NULL, OPTION_NWARN},
5719 {"SCORE5" , no_argument, NULL, OPTION_SCORE5},
5720 {"SCORE5U", no_argument, NULL, OPTION_SCORE5U},
5721 {"SCORE7" , no_argument, NULL, OPTION_SCORE7},
5722 {"USE_R1" , no_argument, NULL, OPTION_R1},
5723 {"O0" , no_argument, NULL, OPTION_O0},
5724 {"V" , no_argument, NULL, OPTION_SCORE_VERSION},
5725 {"KPIC" , no_argument, NULL, OPTION_PIC},
5726 {NULL , no_argument, NULL, 0}
5727 };
5728
5729 size_t md_longopts_size = sizeof (md_longopts);
5730
5731 int
5732 md_parse_option (int c, char *arg)
5733 {
5734 switch (c)
5735 {
5736 #ifdef OPTION_EB
5737 case OPTION_EB:
5738 target_big_endian = 1;
5739 break;
5740 #endif
5741 #ifdef OPTION_EL
5742 case OPTION_EL:
5743 target_big_endian = 0;
5744 break;
5745 #endif
5746 case OPTION_FIXDD:
5747 fix_data_dependency = 1;
5748 break;
5749 case OPTION_NWARN:
5750 warn_fix_data_dependency = 0;
5751 break;
5752 case OPTION_SCORE5:
5753 score7 = 0;
5754 university_version = 0;
5755 vector_size = SCORE5_PIPELINE;
5756 break;
5757 case OPTION_SCORE5U:
5758 score7 = 0;
5759 university_version = 1;
5760 vector_size = SCORE5_PIPELINE;
5761 break;
5762 case OPTION_SCORE7:
5763 score7 = 1;
5764 university_version = 0;
5765 vector_size = SCORE7_PIPELINE;
5766 break;
5767 case OPTION_R1:
5768 nor1 = 0;
5769 break;
5770 case 'G':
5771 g_switch_value = atoi (arg);
5772 break;
5773 case OPTION_O0:
5774 g_opt = 0;
5775 break;
5776 case OPTION_SCORE_VERSION:
5777 printf (_("Sunplus-v2-0-0-20060510\n"));
5778 break;
5779 case OPTION_PIC:
5780 score_pic = PIC;
5781 g_switch_value = 0; /* Must set -G num as 0 to generate PIC code. */
5782 break;
5783 default:
5784 /* as_bad (_("unrecognized option `-%c%s'"), c, arg ? arg : ""); */
5785 return 0;
5786 }
5787 return 1;
5788 }
5789
5790 void
5791 md_show_usage (FILE * fp)
5792 {
5793 fprintf (fp, _(" Score-specific assembler options:\n"));
5794 #ifdef OPTION_EB
5795 fprintf (fp, _("\
5796 -EB\t\tassemble code for a big-endian cpu\n"));
5797 #endif
5798
5799 #ifdef OPTION_EL
5800 fprintf (fp, _("\
5801 -EL\t\tassemble code for a little-endian cpu\n"));
5802 #endif
5803
5804 fprintf (fp, _("\
5805 -FIXDD\t\tassemble code for fix data dependency\n"));
5806 fprintf (fp, _("\
5807 -NWARN\t\tassemble code for no warning message for fix data dependency\n"));
5808 fprintf (fp, _("\
5809 -SCORE5\t\tassemble code for target is SCORE5\n"));
5810 fprintf (fp, _("\
5811 -SCORE5U\tassemble code for target is SCORE5U\n"));
5812 fprintf (fp, _("\
5813 -SCORE7\t\tassemble code for target is SCORE7, this is default setting\n"));
5814 fprintf (fp, _("\
5815 -USE_R1\t\tassemble code for no warning message when using temp register r1\n"));
5816 fprintf (fp, _("\
5817 -O0\t\tassemble will not any optimization \n"));
5818 fprintf (fp, _("\
5819 -G gpnum\tassemble code for setting gpsize and default is 8 byte \n"));
5820 fprintf (fp, _("\
5821 -V \t\tSunplus release version \n"));
5822 }
5823
5824
5825 /* Pesudo handling functions. */
5826
5827 /* If we change section we must dump the literal pool first. */
5828 static void
5829 s_score_bss (int ignore ATTRIBUTE_UNUSED)
5830 {
5831 subseg_set (bss_section, (subsegT) get_absolute_expression ());
5832 demand_empty_rest_of_line ();
5833 }
5834
5835 static void
5836 s_score_text (int ignore)
5837 {
5838 obj_elf_text (ignore);
5839 record_alignment (now_seg, 2);
5840 }
5841
5842 static void
5843 score_s_section (int ignore)
5844 {
5845 obj_elf_section (ignore);
5846 if ((bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) != 0)
5847 record_alignment (now_seg, 2);
5848
5849 }
5850
5851 static void
5852 s_change_sec (int sec)
5853 {
5854 segT seg;
5855
5856 #ifdef OBJ_ELF
5857 /* The ELF backend needs to know that we are changing sections, so
5858 that .previous works correctly. We could do something like check
5859 for an obj_section_change_hook macro, but that might be confusing
5860 as it would not be appropriate to use it in the section changing
5861 functions in read.c, since obj-elf.c intercepts those. FIXME:
5862 This should be cleaner, somehow. */
5863 obj_elf_section_change_hook ();
5864 #endif
5865 switch (sec)
5866 {
5867 case 'r':
5868 seg = subseg_new (RDATA_SECTION_NAME, (subsegT) get_absolute_expression ());
5869 bfd_set_section_flags (stdoutput, seg, (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_RELOC | SEC_DATA));
5870 if (strcmp (TARGET_OS, "elf") != 0)
5871 record_alignment (seg, 4);
5872 demand_empty_rest_of_line ();
5873 break;
5874 case 's':
5875 seg = subseg_new (".sdata", (subsegT) get_absolute_expression ());
5876 bfd_set_section_flags (stdoutput, seg, SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA);
5877 if (strcmp (TARGET_OS, "elf") != 0)
5878 record_alignment (seg, 4);
5879 demand_empty_rest_of_line ();
5880 break;
5881 }
5882 }
5883
5884 static void
5885 s_score_mask (int reg_type ATTRIBUTE_UNUSED)
5886 {
5887 long mask, off;
5888
5889 if (cur_proc_ptr == (procS *) NULL)
5890 {
5891 as_warn (_(".mask outside of .ent"));
5892 demand_empty_rest_of_line ();
5893 return;
5894 }
5895 if (get_absolute_expression_and_terminator (&mask) != ',')
5896 {
5897 as_warn (_("Bad .mask directive"));
5898 --input_line_pointer;
5899 demand_empty_rest_of_line ();
5900 return;
5901 }
5902 off = get_absolute_expression ();
5903 cur_proc_ptr->reg_mask = mask;
5904 cur_proc_ptr->reg_offset = off;
5905 demand_empty_rest_of_line ();
5906 }
5907
5908 static symbolS *
5909 get_symbol (void)
5910 {
5911 int c;
5912 char *name;
5913 symbolS *p;
5914
5915 name = input_line_pointer;
5916 c = get_symbol_end ();
5917 p = (symbolS *) symbol_find_or_make (name);
5918 *input_line_pointer = c;
5919 return p;
5920 }
5921
5922 static long
5923 get_number (void)
5924 {
5925 int negative = 0;
5926 long val = 0;
5927
5928 if (*input_line_pointer == '-')
5929 {
5930 ++input_line_pointer;
5931 negative = 1;
5932 }
5933 if (!ISDIGIT (*input_line_pointer))
5934 as_bad (_("expected simple number"));
5935 if (input_line_pointer[0] == '0')
5936 {
5937 if (input_line_pointer[1] == 'x')
5938 {
5939 input_line_pointer += 2;
5940 while (ISXDIGIT (*input_line_pointer))
5941 {
5942 val <<= 4;
5943 val |= hex_value (*input_line_pointer++);
5944 }
5945 return negative ? -val : val;
5946 }
5947 else
5948 {
5949 ++input_line_pointer;
5950 while (ISDIGIT (*input_line_pointer))
5951 {
5952 val <<= 3;
5953 val |= *input_line_pointer++ - '0';
5954 }
5955 return negative ? -val : val;
5956 }
5957 }
5958 if (!ISDIGIT (*input_line_pointer))
5959 {
5960 printf (_(" *input_line_pointer == '%c' 0x%02x\n"), *input_line_pointer, *input_line_pointer);
5961 as_warn (_("invalid number"));
5962 return -1;
5963 }
5964 while (ISDIGIT (*input_line_pointer))
5965 {
5966 val *= 10;
5967 val += *input_line_pointer++ - '0';
5968 }
5969 return negative ? -val : val;
5970 }
5971
5972 /* The .aent and .ent directives. */
5973
5974 static void
5975 s_score_ent (int aent)
5976 {
5977 symbolS *symbolP;
5978 int maybe_text;
5979
5980 symbolP = get_symbol ();
5981 if (*input_line_pointer == ',')
5982 ++input_line_pointer;
5983 SKIP_WHITESPACE ();
5984 if (ISDIGIT (*input_line_pointer) || *input_line_pointer == '-')
5985 get_number ();
5986
5987 #ifdef BFD_ASSEMBLER
5988 if ((bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) != 0)
5989 maybe_text = 1;
5990 else
5991 maybe_text = 0;
5992 #else
5993 if (now_seg != data_section && now_seg != bss_section)
5994 maybe_text = 1;
5995 else
5996 maybe_text = 0;
5997 #endif
5998 if (!maybe_text)
5999 as_warn (_(".ent or .aent not in text section."));
6000 if (!aent && cur_proc_ptr)
6001 as_warn (_("missing .end"));
6002 if (!aent)
6003 {
6004 cur_proc_ptr = &cur_proc;
6005 cur_proc_ptr->reg_mask = 0xdeadbeaf;
6006 cur_proc_ptr->reg_offset = 0xdeadbeaf;
6007 cur_proc_ptr->fpreg_mask = 0xdeafbeaf;
6008 cur_proc_ptr->leaf = 0xdeafbeaf;
6009 cur_proc_ptr->frame_offset = 0xdeafbeaf;
6010 cur_proc_ptr->frame_reg = 0xdeafbeaf;
6011 cur_proc_ptr->pc_reg = 0xdeafbeaf;
6012 cur_proc_ptr->isym = symbolP;
6013 symbol_get_bfdsym (symbolP)->flags |= BSF_FUNCTION;
6014 ++numprocs;
6015 if (debug_type == DEBUG_STABS)
6016 stabs_generate_asm_func (S_GET_NAME (symbolP), S_GET_NAME (symbolP));
6017 }
6018 demand_empty_rest_of_line ();
6019 }
6020
6021 static void
6022 s_score_frame (int ignore ATTRIBUTE_UNUSED)
6023 {
6024 char *backupstr;
6025 char str[30];
6026 long val;
6027 int i = 0;
6028
6029 backupstr = input_line_pointer;
6030
6031 #ifdef OBJ_ELF
6032 if (cur_proc_ptr == (procS *) NULL)
6033 {
6034 as_warn (_(".frame outside of .ent"));
6035 demand_empty_rest_of_line ();
6036 return;
6037 }
6038 cur_proc_ptr->frame_reg = reg_required_here ((&backupstr), 0, REG_TYPE_SCORE);
6039 SKIP_WHITESPACE ();
6040 skip_past_comma (&backupstr);
6041 while (*backupstr != ',')
6042 {
6043 str[i] = *backupstr;
6044 i++;
6045 backupstr++;
6046 }
6047 str[i] = '\0';
6048 val = atoi (str);
6049
6050 SKIP_WHITESPACE ();
6051 skip_past_comma (&backupstr);
6052 cur_proc_ptr->frame_offset = val;
6053 cur_proc_ptr->pc_reg = reg_required_here ((&backupstr), 0, REG_TYPE_SCORE);
6054
6055 SKIP_WHITESPACE ();
6056 skip_past_comma (&backupstr);
6057 i = 0;
6058 while (*backupstr != '\n')
6059 {
6060 str[i] = *backupstr;
6061 i++;
6062 backupstr++;
6063 }
6064 str[i] = '\0';
6065 val = atoi (str);
6066 cur_proc_ptr->leaf = val;
6067 SKIP_WHITESPACE ();
6068 skip_past_comma (&backupstr);
6069
6070 #endif /* OBJ_ELF */
6071 while (input_line_pointer != backupstr)
6072 input_line_pointer++;
6073 }
6074
6075 /* The .end directive. */
6076 static void
6077 s_score_end (int x ATTRIBUTE_UNUSED)
6078 {
6079 symbolS *p;
6080 int maybe_text;
6081
6082 /* Generate a .pdr section. */
6083 segT saved_seg = now_seg;
6084 subsegT saved_subseg = now_subseg;
6085 valueT dot;
6086 expressionS exp;
6087 char *fragp;
6088
6089 if (!is_end_of_line[(unsigned char)*input_line_pointer])
6090 {
6091 p = get_symbol ();
6092 demand_empty_rest_of_line ();
6093 }
6094 else
6095 p = NULL;
6096
6097 #ifdef BFD_ASSEMBLER
6098 if ((bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) != 0)
6099 maybe_text = 1;
6100 else
6101 maybe_text = 0;
6102 #else
6103 if (now_seg != data_section && now_seg != bss_section)
6104 maybe_text = 1;
6105 else
6106 maybe_text = 0;
6107 #endif
6108
6109 if (!maybe_text)
6110 as_warn (_(".end not in text section"));
6111 if (!cur_proc_ptr)
6112 {
6113 as_warn (_(".end directive without a preceding .ent directive."));
6114 demand_empty_rest_of_line ();
6115 return;
6116 }
6117 if (p != NULL)
6118 {
6119 assert (S_GET_NAME (p));
6120 if (strcmp (S_GET_NAME (p), S_GET_NAME (cur_proc_ptr->isym)))
6121 as_warn (_(".end symbol does not match .ent symbol."));
6122 if (debug_type == DEBUG_STABS)
6123 stabs_generate_asm_endfunc (S_GET_NAME (p), S_GET_NAME (p));
6124 }
6125 else
6126 as_warn (_(".end directive missing or unknown symbol"));
6127
6128 if ((cur_proc_ptr->reg_mask == 0xdeadbeaf) ||
6129 (cur_proc_ptr->reg_offset == 0xdeadbeaf) ||
6130 (cur_proc_ptr->leaf == 0xdeafbeaf) ||
6131 (cur_proc_ptr->frame_offset == 0xdeafbeaf) ||
6132 (cur_proc_ptr->frame_reg == 0xdeafbeaf) || (cur_proc_ptr->pc_reg == 0xdeafbeaf));
6133
6134 else
6135 {
6136 dot = frag_now_fix ();
6137 assert (pdr_seg);
6138 subseg_set (pdr_seg, 0);
6139 /* Write the symbol. */
6140 exp.X_op = O_symbol;
6141 exp.X_add_symbol = p;
6142 exp.X_add_number = 0;
6143 emit_expr (&exp, 4);
6144 fragp = frag_more (7 * 4);
6145 md_number_to_chars (fragp, (valueT) cur_proc_ptr->reg_mask, 4);
6146 md_number_to_chars (fragp + 4, (valueT) cur_proc_ptr->reg_offset, 4);
6147 md_number_to_chars (fragp + 8, (valueT) cur_proc_ptr->fpreg_mask, 4);
6148 md_number_to_chars (fragp + 12, (valueT) cur_proc_ptr->leaf, 4);
6149 md_number_to_chars (fragp + 16, (valueT) cur_proc_ptr->frame_offset, 4);
6150 md_number_to_chars (fragp + 20, (valueT) cur_proc_ptr->frame_reg, 4);
6151 md_number_to_chars (fragp + 24, (valueT) cur_proc_ptr->pc_reg, 4);
6152 subseg_set (saved_seg, saved_subseg);
6153
6154 }
6155 cur_proc_ptr = NULL;
6156 }
6157
6158 /* Handle the .set pseudo-op. */
6159 static void
6160 s_score_set (int x ATTRIBUTE_UNUSED)
6161 {
6162 int i = 0;
6163 char name[MAX_LITERAL_POOL_SIZE];
6164 char * orig_ilp = input_line_pointer;
6165
6166 while (!is_end_of_line[(unsigned char)*input_line_pointer])
6167 {
6168 name[i] = (char) * input_line_pointer;
6169 i++;
6170 ++input_line_pointer;
6171 }
6172
6173 name[i] = '\0';
6174
6175 if (strcmp (name, "nwarn") == 0)
6176 {
6177 warn_fix_data_dependency = 0;
6178 }
6179 else if (strcmp (name, "fixdd") == 0)
6180 {
6181 fix_data_dependency = 1;
6182 }
6183 else if (strcmp (name, "nofixdd") == 0)
6184 {
6185 fix_data_dependency = 0;
6186 }
6187 else if (strcmp (name, "r1") == 0)
6188 {
6189 nor1 = 0;
6190 }
6191 else if (strcmp (name, "nor1") == 0)
6192 {
6193 nor1 = 1;
6194 }
6195 else if (strcmp (name, "optimize") == 0)
6196 {
6197 g_opt = 1;
6198 }
6199 else if (strcmp (name, "volatile") == 0)
6200 {
6201 g_opt = 0;
6202 }
6203 else if (strcmp (name, "pic") == 0)
6204 {
6205 score_pic = PIC;
6206 }
6207 else
6208 {
6209 input_line_pointer = orig_ilp;
6210 s_set (0);
6211 }
6212 }
6213
6214 /* Handle the .cpload pseudo-op. This is used when generating PIC code. It sets the
6215 $gp register for the function based on the function address, which is in the register
6216 named in the argument. This uses a relocation against GP_DISP_LABEL, which is handled
6217 specially by the linker. The result is:
6218 ldis gp, %hi(GP_DISP_LABEL)
6219 ori gp, %low(GP_DISP_LABEL)
6220 add gp, gp, .cpload argument
6221 The .cpload argument is normally r29. */
6222
6223 static void
6224 s_score_cpload (int ignore ATTRIBUTE_UNUSED)
6225 {
6226 int reg;
6227 char insn_str[MAX_LITERAL_POOL_SIZE];
6228
6229 /* If we are not generating PIC code, .cpload is ignored. */
6230 if (score_pic == NO_PIC)
6231 {
6232 s_ignore (0);
6233 return;
6234 }
6235
6236 if ((reg = reg_required_here (&input_line_pointer, -1, REG_TYPE_SCORE)) == (int) FAIL)
6237 return;
6238
6239 demand_empty_rest_of_line ();
6240
6241 sprintf (insn_str, "ld_i32hi r%d, %s", GP, GP_DISP_LABEL);
6242 if (append_insn (insn_str, TRUE) == (int) FAIL)
6243 return;
6244
6245 sprintf (insn_str, "ld_i32lo r%d, %s", GP, GP_DISP_LABEL);
6246 if (append_insn (insn_str, TRUE) == (int) FAIL)
6247 return;
6248
6249 sprintf (insn_str, "add r%d, r%d, r%d", GP, GP, reg);
6250 if (append_insn (insn_str, TRUE) == (int) FAIL)
6251 return;
6252 }
6253
6254 /* Handle the .cprestore pseudo-op. This stores $gp into a given
6255 offset from $sp. The offset is remembered, and after making a PIC
6256 call $gp is restored from that location. */
6257
6258 static void
6259 s_score_cprestore (int ignore ATTRIBUTE_UNUSED)
6260 {
6261 #define SCORE_BP_REG 2
6262 int cprestore_offset;
6263 char insn_str[MAX_LITERAL_POOL_SIZE];
6264
6265 /* If we are not generating PIC code, .cprestore is ignored. */
6266 if (score_pic == NO_PIC)
6267 {
6268 s_ignore (0);
6269 return;
6270 }
6271
6272 cprestore_offset = get_absolute_expression ();
6273
6274 sprintf (insn_str, "sw r%d, [r%d, %d]", GP, SCORE_BP_REG, cprestore_offset);
6275 if (append_insn (insn_str, TRUE) == (int) FAIL)
6276 return;
6277 }
6278
6279 /* Handle the .gpword pseudo-op. This is used when generating PIC
6280 code. It generates a 32 bit GP relative reloc. */
6281 static void
6282 s_score_gpword (int ignore ATTRIBUTE_UNUSED)
6283 {
6284 expressionS ex;
6285 char *p;
6286
6287 /* When not generating PIC code, this is treated as .word. */
6288 if (score_pic == NO_PIC)
6289 {
6290 cons (4);
6291 return;
6292 }
6293 expression (&ex);
6294 if (ex.X_op != O_symbol || ex.X_add_number != 0)
6295 {
6296 as_bad (_("Unsupported use of .gpword"));
6297 ignore_rest_of_line ();
6298 }
6299 p = frag_more (4);
6300 md_number_to_chars (p, (valueT) 0, 4);
6301 fix_new_exp (frag_now, p - frag_now->fr_literal, 4, &ex, FALSE, BFD_RELOC_GPREL32);
6302 demand_empty_rest_of_line ();
6303 }
6304
6305 /* Handle the .cpadd pseudo-op. This is used when dealing with switch
6306 tables in PIC code. */
6307
6308 static void
6309 s_score_cpadd (int ignore ATTRIBUTE_UNUSED)
6310 {
6311 int reg;
6312 char insn_str[MAX_LITERAL_POOL_SIZE];
6313
6314 /* If we are not generating PIC code, .cpload is ignored. */
6315 if (score_pic == NO_PIC)
6316 {
6317 s_ignore (0);
6318 return;
6319 }
6320
6321 if ((reg = reg_required_here (&input_line_pointer, -1, REG_TYPE_SCORE)) == (int) FAIL)
6322 {
6323 return;
6324 }
6325 demand_empty_rest_of_line ();
6326
6327 /* Add $gp to the register named as an argument. */
6328 sprintf (insn_str, "add r%d, r%d, r%d", reg, reg, GP);
6329 if (append_insn (insn_str, TRUE) == (int) FAIL)
6330 return;
6331 }
6332
6333 #ifndef TC_IMPLICIT_LCOMM_ALIGNMENT
6334 #define TC_IMPLICIT_LCOMM_ALIGNMENT(SIZE, P2VAR) \
6335 do \
6336 { \
6337 if ((SIZE) >= 8) \
6338 (P2VAR) = 3; \
6339 else if ((SIZE) >= 4) \
6340 (P2VAR) = 2; \
6341 else if ((SIZE) >= 2) \
6342 (P2VAR) = 1; \
6343 else \
6344 (P2VAR) = 0; \
6345 } \
6346 while (0)
6347 #endif
6348
6349 static void
6350 s_score_lcomm (int bytes_p)
6351 {
6352 char *name;
6353 char c;
6354 char *p;
6355 int temp;
6356 symbolS *symbolP;
6357 segT current_seg = now_seg;
6358 subsegT current_subseg = now_subseg;
6359 const int max_alignment = 15;
6360 int align = 0;
6361 segT bss_seg = bss_section;
6362 int needs_align = 0;
6363
6364 name = input_line_pointer;
6365 c = get_symbol_end ();
6366 p = input_line_pointer;
6367 *p = c;
6368
6369 if (name == p)
6370 {
6371 as_bad (_("expected symbol name"));
6372 discard_rest_of_line ();
6373 return;
6374 }
6375
6376 SKIP_WHITESPACE ();
6377
6378 /* Accept an optional comma after the name. The comma used to be
6379 required, but Irix 5 cc does not generate it. */
6380 if (*input_line_pointer == ',')
6381 {
6382 ++input_line_pointer;
6383 SKIP_WHITESPACE ();
6384 }
6385
6386 if (is_end_of_line[(unsigned char)*input_line_pointer])
6387 {
6388 as_bad (_("missing size expression"));
6389 return;
6390 }
6391
6392 if ((temp = get_absolute_expression ()) < 0)
6393 {
6394 as_warn (_("BSS length (%d) < 0 ignored"), temp);
6395 ignore_rest_of_line ();
6396 return;
6397 }
6398
6399 #if defined (TC_SCORE)
6400 if (OUTPUT_FLAVOR == bfd_target_ecoff_flavour || OUTPUT_FLAVOR == bfd_target_elf_flavour)
6401 {
6402 /* For Score and Alpha ECOFF or ELF, small objects are put in .sbss. */
6403 if ((unsigned)temp <= bfd_get_gp_size (stdoutput))
6404 {
6405 bss_seg = subseg_new (".sbss", 1);
6406 seg_info (bss_seg)->bss = 1;
6407 #ifdef BFD_ASSEMBLER
6408 if (!bfd_set_section_flags (stdoutput, bss_seg, SEC_ALLOC))
6409 as_warn (_("error setting flags for \".sbss\": %s"), bfd_errmsg (bfd_get_error ()));
6410 #endif
6411 }
6412 }
6413 #endif
6414
6415 SKIP_WHITESPACE ();
6416 if (*input_line_pointer == ',')
6417 {
6418 ++input_line_pointer;
6419 SKIP_WHITESPACE ();
6420
6421 if (is_end_of_line[(unsigned char)*input_line_pointer])
6422 {
6423 as_bad (_("missing alignment"));
6424 return;
6425 }
6426 else
6427 {
6428 align = get_absolute_expression ();
6429 needs_align = 1;
6430 }
6431 }
6432
6433 if (!needs_align)
6434 {
6435 TC_IMPLICIT_LCOMM_ALIGNMENT (temp, align);
6436
6437 /* Still zero unless TC_IMPLICIT_LCOMM_ALIGNMENT set it. */
6438 if (align)
6439 record_alignment (bss_seg, align);
6440 }
6441
6442 if (needs_align)
6443 {
6444 if (bytes_p)
6445 {
6446 /* Convert to a power of 2. */
6447 if (align != 0)
6448 {
6449 unsigned int i;
6450
6451 for (i = 0; align != 0; align >>= 1, ++i)
6452 ;
6453 align = i - 1;
6454 }
6455 }
6456
6457 if (align > max_alignment)
6458 {
6459 align = max_alignment;
6460 as_warn (_("alignment too large; %d assumed"), align);
6461 }
6462 else if (align < 0)
6463 {
6464 align = 0;
6465 as_warn (_("alignment negative; 0 assumed"));
6466 }
6467
6468 record_alignment (bss_seg, align);
6469 }
6470 else
6471 {
6472 /* Assume some objects may require alignment on some systems. */
6473 #if defined (TC_ALPHA) && ! defined (VMS)
6474 if (temp > 1)
6475 {
6476 align = ffs (temp) - 1;
6477 if (temp % (1 << align))
6478 abort ();
6479 }
6480 #endif
6481 }
6482
6483 *p = 0;
6484 symbolP = symbol_find_or_make (name);
6485 *p = c;
6486
6487 if (
6488 #if (defined (OBJ_AOUT) || defined (OBJ_MAYBE_AOUT) \
6489 || defined (OBJ_BOUT) || defined (OBJ_MAYBE_BOUT))
6490 #ifdef BFD_ASSEMBLER
6491 (OUTPUT_FLAVOR != bfd_target_aout_flavour
6492 || (S_GET_OTHER (symbolP) == 0 && S_GET_DESC (symbolP) == 0)) &&
6493 #else
6494 (S_GET_OTHER (symbolP) == 0 && S_GET_DESC (symbolP) == 0) &&
6495 #endif
6496 #endif
6497 (S_GET_SEGMENT (symbolP) == bss_seg || (!S_IS_DEFINED (symbolP) && S_GET_VALUE (symbolP) == 0)))
6498 {
6499 char *pfrag;
6500
6501 subseg_set (bss_seg, 1);
6502
6503 if (align)
6504 frag_align (align, 0, 0);
6505
6506 /* Detach from old frag. */
6507 if (S_GET_SEGMENT (symbolP) == bss_seg)
6508 symbol_get_frag (symbolP)->fr_symbol = NULL;
6509
6510 symbol_set_frag (symbolP, frag_now);
6511 pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP, (offsetT) temp, NULL);
6512 *pfrag = 0;
6513
6514
6515 S_SET_SEGMENT (symbolP, bss_seg);
6516
6517 #ifdef OBJ_COFF
6518 /* The symbol may already have been created with a preceding
6519 ".globl" directive -- be careful not to step on storage class
6520 in that case. Otherwise, set it to static. */
6521 if (S_GET_STORAGE_CLASS (symbolP) != C_EXT)
6522 {
6523 S_SET_STORAGE_CLASS (symbolP, C_STAT);
6524 }
6525 #endif /* OBJ_COFF */
6526
6527 #ifdef S_SET_SIZE
6528 S_SET_SIZE (symbolP, temp);
6529 #endif
6530 }
6531 else
6532 as_bad (_("symbol `%s' is already defined"), S_GET_NAME (symbolP));
6533
6534 subseg_set (current_seg, current_subseg);
6535
6536 demand_empty_rest_of_line ();
6537 }
6538
6539 static void
6540 insert_reg (const struct reg_entry *r, struct hash_control *htab)
6541 {
6542 int i = 0;
6543 int len = strlen (r->name) + 2;
6544 char *buf = xmalloc (len);
6545 char *buf2 = xmalloc (len);
6546
6547 strcpy (buf + i, r->name);
6548 for (i = 0; buf[i]; i++)
6549 {
6550 buf2[i] = TOUPPER (buf[i]);
6551 }
6552 buf2[i] = '\0';
6553
6554 hash_insert (htab, buf, (void *) r);
6555 hash_insert (htab, buf2, (void *) r);
6556 }
6557
6558 static void
6559 build_reg_hsh (struct reg_map *map)
6560 {
6561 const struct reg_entry *r;
6562
6563 if ((map->htab = hash_new ()) == NULL)
6564 {
6565 as_fatal (_("virtual memory exhausted"));
6566 }
6567 for (r = map->names; r->name != NULL; r++)
6568 {
6569 insert_reg (r, map->htab);
6570 }
6571 }
6572
6573 void
6574 md_begin (void)
6575 {
6576 unsigned int i;
6577 segT seg;
6578 subsegT subseg;
6579
6580 if ((score_ops_hsh = hash_new ()) == NULL)
6581 as_fatal (_("virtual memory exhausted"));
6582
6583 build_score_ops_hsh ();
6584
6585 if ((dependency_insn_hsh = hash_new ()) == NULL)
6586 as_fatal (_("virtual memory exhausted"));
6587
6588 build_dependency_insn_hsh ();
6589
6590 for (i = (int)REG_TYPE_FIRST; i < (int)REG_TYPE_MAX; i++)
6591 build_reg_hsh (all_reg_maps + i);
6592
6593 /* Initialize dependency vector. */
6594 init_dependency_vector ();
6595
6596 bfd_set_arch_mach (stdoutput, TARGET_ARCH, 0);
6597 seg = now_seg;
6598 subseg = now_subseg;
6599 pdr_seg = subseg_new (".pdr", (subsegT) 0);
6600 (void)bfd_set_section_flags (stdoutput, pdr_seg, SEC_READONLY | SEC_RELOC | SEC_DEBUGGING);
6601 (void)bfd_set_section_alignment (stdoutput, pdr_seg, 2);
6602 subseg_set (seg, subseg);
6603
6604 if (USE_GLOBAL_POINTER_OPT)
6605 bfd_set_gp_size (stdoutput, g_switch_value);
6606 }
6607
6608
6609 const pseudo_typeS md_pseudo_table[] =
6610 {
6611 {"bss", s_score_bss, 0},
6612 {"text", s_score_text, 0},
6613 {"word", cons, 4},
6614 {"long", cons, 4},
6615 {"extend", float_cons, 'x'},
6616 {"ldouble", float_cons, 'x'},
6617 {"packed", float_cons, 'p'},
6618 {"end", s_score_end, 0},
6619 {"ent", s_score_ent, 0},
6620 {"frame", s_score_frame, 0},
6621 {"rdata", s_change_sec, 'r'},
6622 {"sdata", s_change_sec, 's'},
6623 {"set", s_score_set, 0},
6624 {"mask", s_score_mask, 'R'},
6625 {"dword", cons, 8},
6626 {"lcomm", s_score_lcomm, 1},
6627 {"section", score_s_section, 0},
6628 {"cpload", s_score_cpload, 0},
6629 {"cprestore", s_score_cprestore, 0},
6630 {"gpword", s_score_gpword, 0},
6631 {"cpadd", s_score_cpadd, 0},
6632 {0, 0, 0}
6633 };
6634
This page took 0.189496 seconds and 4 git commands to generate.