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