* tc-score.c (do16_rdrs): Handle not! instruction especially.
[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 if ((inst.instruction & 0x700f) == 0x2006) /* not! */
1765 {
1766 inst.relax_inst |= (((inst.instruction >> 8) & 0xf) << 20)
1767 | (((inst.instruction >> 4) & 0xf) << 15);
1768 }
1769 else
1770 {
1771 inst.relax_inst |= (((inst.instruction >> 8) & 0xf) << 20)
1772 | (((inst.instruction >> 8) & 0xf) << 15) | (((inst.instruction >> 4) & 0xf) << 10);
1773 }
1774 inst.relax_size = 4;
1775 }
1776 }
1777
1778 static void
1779 do16_rs (char *str)
1780 {
1781 int rd = 0;
1782
1783 skip_whitespace (str);
1784
1785 if ((rd = reglow_required_here (&str, 4)) == (int) FAIL
1786 || end_of_line (str) == (int) FAIL)
1787 {
1788 return;
1789 }
1790 else
1791 {
1792 inst.relax_inst |= rd << 20;
1793 inst.relax_size = 4;
1794 }
1795 }
1796
1797 /* Handle br!/brl!. */
1798 static void
1799 do16_xrs (char *str)
1800 {
1801 skip_whitespace (str);
1802
1803 if (reglow_required_here (&str, 4) == (int) FAIL || end_of_line (str) == (int) FAIL)
1804 {
1805 return;
1806 }
1807 else
1808 {
1809 inst.relax_inst |= (((inst.instruction >> 8) & 0xf) << 10)
1810 | (((inst.instruction >> 4) & 0xf) << 15);
1811 inst.relax_size = 4;
1812 }
1813 }
1814
1815 static int
1816 reghigh_required_here (char **str, int shift)
1817 {
1818 static char buff[MAX_LITERAL_POOL_SIZE];
1819 int reg;
1820 char *start = *str;
1821
1822 if ((reg = score_reg_parse (str, all_reg_maps[REG_TYPE_SCORE].htab)) != (int) FAIL)
1823 {
1824 if (15 < reg && reg < 32)
1825 {
1826 if (shift >= 0)
1827 inst.instruction |= (reg & 0xf) << shift;
1828
1829 return reg;
1830 }
1831 }
1832
1833 *str = start;
1834 sprintf (buff, _("high register(r16-r31)expected, not '%.100s'"), start);
1835 inst.error = buff;
1836 return (int) FAIL;
1837 }
1838
1839 /* Handle mhfl!. */
1840 static void
1841 do16_hrdrs (char *str)
1842 {
1843 skip_whitespace (str);
1844
1845 if (reghigh_required_here (&str, 8) != (int) FAIL
1846 && skip_past_comma (&str) != (int) FAIL
1847 && reglow_required_here (&str, 4) != (int) FAIL
1848 && end_of_line (str) != (int) FAIL)
1849 {
1850 inst.relax_inst |= ((((inst.instruction >> 8) & 0xf) | 0x10) << 20)
1851 | (((inst.instruction >> 4) & 0xf) << 15) | (0xf << 10);
1852 inst.relax_size = 4;
1853 }
1854 }
1855
1856 /* Handle mlfh!. */
1857 static void
1858 do16_rdhrs (char *str)
1859 {
1860 skip_whitespace (str);
1861
1862 if (reglow_required_here (&str, 8) != (int) FAIL
1863 && skip_past_comma (&str) != (int) FAIL
1864 && reghigh_required_here (&str, 4) != (int) FAIL
1865 && end_of_line (str) != (int) FAIL)
1866 {
1867 inst.relax_inst |= (((inst.instruction >> 8) & 0xf) << 20)
1868 | ((((inst.instruction >> 4) & 0xf) | 0x10) << 15) | (0xf << 10);
1869 inst.relax_size = 4;
1870 }
1871 }
1872
1873 /* We need to be able to fix up arbitrary expressions in some statements.
1874 This is so that we can handle symbols that are an arbitrary distance from
1875 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
1876 which returns part of an address in a form which will be valid for
1877 a data instruction. We do this by pushing the expression into a symbol
1878 in the expr_section, and creating a fix for that. */
1879 static fixS *
1880 fix_new_score (fragS * frag, int where, short int size, expressionS * exp, int pc_rel, int reloc)
1881 {
1882 fixS *new_fix;
1883
1884 switch (exp->X_op)
1885 {
1886 case O_constant:
1887 case O_symbol:
1888 case O_add:
1889 case O_subtract:
1890 new_fix = fix_new_exp (frag, where, size, exp, pc_rel, reloc);
1891 break;
1892 default:
1893 new_fix = fix_new (frag, where, size, make_expr_symbol (exp), 0, pc_rel, reloc);
1894 break;
1895 }
1896 return new_fix;
1897 }
1898
1899 static void
1900 init_dependency_vector (void)
1901 {
1902 int i;
1903
1904 for (i = 0; i < vector_size; i++)
1905 memset (&dependency_vector[i], '\0', sizeof (dependency_vector[i]));
1906
1907 return;
1908 }
1909
1910 static enum insn_type_for_dependency
1911 dependency_type_from_insn (char *insn_name)
1912 {
1913 char name[INSN_NAME_LEN];
1914 const struct insn_to_dependency *tmp;
1915
1916 strcpy (name, insn_name);
1917 tmp = (const struct insn_to_dependency *) hash_find (dependency_insn_hsh, name);
1918
1919 if (tmp)
1920 return tmp->type;
1921
1922 return D_all_insn;
1923 }
1924
1925 static int
1926 check_dependency (char *pre_insn, char *pre_reg,
1927 char *cur_insn, char *cur_reg, int *warn_or_error)
1928 {
1929 int bubbles = 0;
1930 unsigned int i;
1931 enum insn_type_for_dependency pre_insn_type;
1932 enum insn_type_for_dependency cur_insn_type;
1933
1934 pre_insn_type = dependency_type_from_insn (pre_insn);
1935 cur_insn_type = dependency_type_from_insn (cur_insn);
1936
1937 for (i = 0; i < sizeof (data_dependency_table) / sizeof (data_dependency_table[0]); i++)
1938 {
1939 if ((pre_insn_type == data_dependency_table[i].pre_insn_type)
1940 && (D_all_insn == data_dependency_table[i].cur_insn_type
1941 || cur_insn_type == data_dependency_table[i].cur_insn_type)
1942 && (strcmp (data_dependency_table[i].pre_reg, "") == 0
1943 || strcmp (data_dependency_table[i].pre_reg, pre_reg) == 0)
1944 && (strcmp (data_dependency_table[i].cur_reg, "") == 0
1945 || strcmp (data_dependency_table[i].cur_reg, cur_reg) == 0))
1946 {
1947 bubbles = (score7) ? data_dependency_table[i].bubblenum_7 : data_dependency_table[i].bubblenum_5;
1948 *warn_or_error = data_dependency_table[i].warn_or_error;
1949 break;
1950 }
1951 }
1952
1953 return bubbles;
1954 }
1955
1956 static void
1957 build_one_frag (struct score_it one_inst)
1958 {
1959 char *p;
1960 int relaxable_p = g_opt;
1961 int relax_size = 0;
1962
1963 /* Start a new frag if frag_now is not empty. */
1964 if (frag_now_fix () != 0)
1965 {
1966 if (!frag_now->tc_frag_data.is_insn)
1967 frag_wane (frag_now);
1968
1969 frag_new (0);
1970 }
1971 frag_grow (20);
1972
1973 p = frag_more (one_inst.size);
1974 md_number_to_chars (p, one_inst.instruction, one_inst.size);
1975
1976 #ifdef OBJ_ELF
1977 dwarf2_emit_insn (one_inst.size);
1978 #endif
1979
1980 relaxable_p &= (one_inst.relax_size != 0);
1981 relax_size = relaxable_p ? one_inst.relax_size : 0;
1982
1983 p = frag_var (rs_machine_dependent, relax_size + RELAX_PAD_BYTE, 0,
1984 RELAX_ENCODE (one_inst.size, one_inst.relax_size,
1985 one_inst.type, 0, 0, relaxable_p),
1986 NULL, 0, NULL);
1987
1988 if (relaxable_p)
1989 md_number_to_chars (p, one_inst.relax_inst, relax_size);
1990 }
1991
1992 static void
1993 handle_dependency (struct score_it *theinst)
1994 {
1995 int i;
1996 int warn_or_error = 0; /* warn - 0; error - 1 */
1997 int bubbles = 0;
1998 int remainder_bubbles = 0;
1999 char cur_insn[INSN_NAME_LEN];
2000 char pre_insn[INSN_NAME_LEN];
2001 struct score_it nop_inst;
2002 struct score_it pflush_inst;
2003
2004 nop_inst.instruction = 0x0000;
2005 nop_inst.size = 2;
2006 nop_inst.relax_inst = 0x80008000;
2007 nop_inst.relax_size = 4;
2008 nop_inst.type = NO16_OPD;
2009
2010 pflush_inst.instruction = 0x8000800a;
2011 pflush_inst.size = 4;
2012 pflush_inst.relax_inst = 0x8000;
2013 pflush_inst.relax_size = 0;
2014 pflush_inst.type = NO_OPD;
2015
2016 /* pflush will clear all data dependency. */
2017 if (strcmp (theinst->name, "pflush") == 0)
2018 {
2019 init_dependency_vector ();
2020 return;
2021 }
2022
2023 /* Push current instruction to dependency_vector[0]. */
2024 for (i = vector_size - 1; i > 0; i--)
2025 memcpy (&dependency_vector[i], &dependency_vector[i - 1], sizeof (dependency_vector[i]));
2026
2027 memcpy (&dependency_vector[0], theinst, sizeof (dependency_vector[i]));
2028
2029 /* There is no dependency between nop and any instruction. */
2030 if (strcmp (dependency_vector[0].name, "nop") == 0
2031 || strcmp (dependency_vector[0].name, "nop!") == 0)
2032 return;
2033
2034 /* "pce" is defined in insn_to_dependency_table. */
2035 #define PCE_NAME "pce"
2036
2037 if (dependency_vector[0].type == Insn_Type_PCE)
2038 strcpy (cur_insn, PCE_NAME);
2039 else
2040 strcpy (cur_insn, dependency_vector[0].name);
2041
2042 for (i = 1; i < vector_size; i++)
2043 {
2044 /* The element of dependency_vector is NULL. */
2045 if (dependency_vector[i].name[0] == '\0')
2046 continue;
2047
2048 if (dependency_vector[i].type == Insn_Type_PCE)
2049 strcpy (pre_insn, PCE_NAME);
2050 else
2051 strcpy (pre_insn, dependency_vector[i].name);
2052
2053 bubbles = check_dependency (pre_insn, dependency_vector[i].reg,
2054 cur_insn, dependency_vector[0].reg, &warn_or_error);
2055 remainder_bubbles = bubbles - i + 1;
2056
2057 if (remainder_bubbles > 0)
2058 {
2059 int j;
2060
2061 if (fix_data_dependency == 1)
2062 {
2063 if (remainder_bubbles <= 2)
2064 {
2065 if (warn_fix_data_dependency)
2066 as_warn ("Fix data dependency: %s %s -- %s %s (insert %d nop!/%d)",
2067 dependency_vector[i].name, dependency_vector[i].reg,
2068 dependency_vector[0].name, dependency_vector[0].reg,
2069 remainder_bubbles, bubbles);
2070
2071 for (j = (vector_size - 1); (j - remainder_bubbles) > 0; j--)
2072 memcpy (&dependency_vector[j], &dependency_vector[j - remainder_bubbles],
2073 sizeof (dependency_vector[j]));
2074
2075 for (j = 1; j <= remainder_bubbles; j++)
2076 {
2077 memset (&dependency_vector[j], '\0', sizeof (dependency_vector[j]));
2078 /* Insert nop!. */
2079 build_one_frag (nop_inst);
2080 }
2081 }
2082 else
2083 {
2084 if (warn_fix_data_dependency)
2085 as_warn ("Fix data dependency: %s %s -- %s %s (insert 1 pflush/%d)",
2086 dependency_vector[i].name, dependency_vector[i].reg,
2087 dependency_vector[0].name, dependency_vector[0].reg,
2088 bubbles);
2089
2090 for (j = 1; j < vector_size; j++)
2091 memset (&dependency_vector[j], '\0', sizeof (dependency_vector[j]));
2092
2093 /* Insert pflush. */
2094 build_one_frag (pflush_inst);
2095 }
2096 }
2097 else
2098 {
2099 if (warn_or_error)
2100 {
2101 as_bad ("data dependency: %s %s -- %s %s (%d/%d bubble)",
2102 dependency_vector[i].name, dependency_vector[i].reg,
2103 dependency_vector[0].name, dependency_vector[0].reg,
2104 remainder_bubbles, bubbles);
2105 }
2106 else
2107 {
2108 as_warn ("data dependency: %s %s -- %s %s (%d/%d bubble)",
2109 dependency_vector[i].name, dependency_vector[i].reg,
2110 dependency_vector[0].name, dependency_vector[0].reg,
2111 remainder_bubbles, bubbles);
2112 }
2113 }
2114 }
2115 }
2116 }
2117
2118 static enum insn_class
2119 get_insn_class_from_type (enum score_insn_type type)
2120 {
2121 enum insn_class retval = (int) FAIL;
2122
2123 switch (type)
2124 {
2125 case Rd_I4:
2126 case Rd_I5:
2127 case Rd_rvalueBP_I5:
2128 case Rd_lvalueBP_I5:
2129 case Rd_I8:
2130 case PC_DISP8div2:
2131 case PC_DISP11div2:
2132 case Rd_Rs:
2133 case Rd_HighRs:
2134 case Rd_lvalueRs:
2135 case Rd_rvalueRs:
2136 case x_Rs:
2137 case Rd_LowRs:
2138 case NO16_OPD:
2139 retval = INSN_CLASS_16;
2140 break;
2141 case Rd_Rs_I5:
2142 case x_Rs_I5:
2143 case x_I5_x:
2144 case Rd_Rs_I14:
2145 case I15:
2146 case Rd_I16:
2147 case Rd_SI16:
2148 case Rd_rvalueRs_SI10:
2149 case Rd_lvalueRs_SI10:
2150 case Rd_rvalueRs_preSI12:
2151 case Rd_rvalueRs_postSI12:
2152 case Rd_lvalueRs_preSI12:
2153 case Rd_lvalueRs_postSI12:
2154 case Rd_Rs_SI14:
2155 case Rd_rvalueRs_SI15:
2156 case Rd_lvalueRs_SI15:
2157 case PC_DISP19div2:
2158 case PC_DISP24div2:
2159 case Rd_Rs_Rs:
2160 case x_Rs_x:
2161 case x_Rs_Rs:
2162 case Rd_Rs_x:
2163 case Rd_x_Rs:
2164 case Rd_x_x:
2165 case OP5_rvalueRs_SI15:
2166 case I5_Rs_Rs_I5_OP5:
2167 case x_rvalueRs_post4:
2168 case Rd_rvalueRs_post4:
2169 case Rd_x_I5:
2170 case Rd_lvalueRs_post4:
2171 case x_lvalueRs_post4:
2172 case Rd_Rs_Rs_imm:
2173 case NO_OPD:
2174 case Rd_lvalue32Rs:
2175 case Rd_rvalue32Rs:
2176 case Insn_GP:
2177 case Insn_PIC:
2178 case Insn_internal:
2179 retval = INSN_CLASS_32;
2180 break;
2181 case Insn_Type_PCE:
2182 retval = INSN_CLASS_PCE;
2183 break;
2184 case Insn_Type_SYN:
2185 retval = INSN_CLASS_SYN;
2186 break;
2187 default:
2188 abort ();
2189 break;
2190 }
2191 return retval;
2192 }
2193
2194 static unsigned long
2195 adjust_paritybit (unsigned long m_code, enum insn_class class)
2196 {
2197 unsigned long result = 0;
2198 unsigned long m_code_high = 0;
2199 unsigned long m_code_low = 0;
2200 unsigned long pb_high = 0;
2201 unsigned long pb_low = 0;
2202
2203 if (class == INSN_CLASS_32)
2204 {
2205 pb_high = 0x80000000;
2206 pb_low = 0x00008000;
2207 }
2208 else if (class == INSN_CLASS_16)
2209 {
2210 pb_high = 0;
2211 pb_low = 0;
2212 }
2213 else if (class == INSN_CLASS_PCE)
2214 {
2215 pb_high = 0;
2216 pb_low = 0x00008000;
2217 }
2218 else if (class == INSN_CLASS_SYN)
2219 {
2220 /* FIXME. at this time, INSN_CLASS_SYN must be 32 bit, but, instruction type should
2221 be changed if macro instruction has been expanded. */
2222 pb_high = 0x80000000;
2223 pb_low = 0x00008000;
2224 }
2225 else
2226 {
2227 abort ();
2228 }
2229
2230 m_code_high = m_code & 0x3fff8000;
2231 m_code_low = m_code & 0x00007fff;
2232 result = pb_high | (m_code_high << 1) | pb_low | m_code_low;
2233 return result;
2234
2235 }
2236
2237 static void
2238 gen_insn_frag (struct score_it *part_1, struct score_it *part_2)
2239 {
2240 char *p;
2241 bfd_boolean pce_p = FALSE;
2242 int relaxable_p = g_opt;
2243 int relax_size = 0;
2244 struct score_it *inst1 = part_1;
2245 struct score_it *inst2 = part_2;
2246 struct score_it backup_inst1;
2247
2248 pce_p = (inst2) ? TRUE : FALSE;
2249 memcpy (&backup_inst1, inst1, sizeof (struct score_it));
2250
2251 /* Adjust instruction opcode and to be relaxed instruction opcode. */
2252 if (pce_p)
2253 {
2254 backup_inst1.instruction = ((backup_inst1.instruction & 0x7FFF) << 15)
2255 | (inst2->instruction & 0x7FFF);
2256 backup_inst1.instruction = adjust_paritybit (backup_inst1.instruction, INSN_CLASS_PCE);
2257 backup_inst1.relax_inst = 0x8000;
2258 backup_inst1.size = INSN_SIZE;
2259 backup_inst1.relax_size = 0;
2260 backup_inst1.type = Insn_Type_PCE;
2261 }
2262 else
2263 {
2264 backup_inst1.instruction = adjust_paritybit (backup_inst1.instruction,
2265 GET_INSN_CLASS (backup_inst1.type));
2266 }
2267
2268 if (backup_inst1.relax_size != 0)
2269 {
2270 enum insn_class tmp;
2271
2272 tmp = (backup_inst1.size == INSN_SIZE) ? INSN_CLASS_16 : INSN_CLASS_32;
2273 backup_inst1.relax_inst = adjust_paritybit (backup_inst1.relax_inst, tmp);
2274 }
2275
2276 /* Check data dependency. */
2277 handle_dependency (&backup_inst1);
2278
2279 /* Start a new frag if frag_now is not empty and is not instruction frag, maybe it contains
2280 data produced by .ascii etc. Doing this is to make one instruction per frag. */
2281 if (frag_now_fix () != 0)
2282 {
2283 if (!frag_now->tc_frag_data.is_insn)
2284 frag_wane (frag_now);
2285
2286 frag_new (0);
2287 }
2288
2289 /* Here, we must call frag_grow in order to keep the instruction frag type is
2290 rs_machine_dependent.
2291 For, frag_var may change frag_now->fr_type to rs_fill by calling frag_grow which
2292 acturally will call frag_wane.
2293 Calling frag_grow first will create a new frag_now which free size is 20 that is enough
2294 for frag_var. */
2295 frag_grow (20);
2296
2297 p = frag_more (backup_inst1.size);
2298 md_number_to_chars (p, backup_inst1.instruction, backup_inst1.size);
2299
2300 #ifdef OBJ_ELF
2301 dwarf2_emit_insn (backup_inst1.size);
2302 #endif
2303
2304 /* Generate fixup structure. */
2305 if (pce_p)
2306 {
2307 if (inst1->reloc.type != BFD_RELOC_NONE)
2308 fix_new_score (frag_now, p - frag_now->fr_literal,
2309 inst1->size, &inst1->reloc.exp,
2310 inst1->reloc.pc_rel, inst1->reloc.type);
2311
2312 if (inst2->reloc.type != BFD_RELOC_NONE)
2313 fix_new_score (frag_now, p - frag_now->fr_literal + 2,
2314 inst2->size, &inst2->reloc.exp, inst2->reloc.pc_rel, inst2->reloc.type);
2315 }
2316 else
2317 {
2318 if (backup_inst1.reloc.type != BFD_RELOC_NONE)
2319 fix_new_score (frag_now, p - frag_now->fr_literal,
2320 backup_inst1.size, &backup_inst1.reloc.exp,
2321 backup_inst1.reloc.pc_rel, backup_inst1.reloc.type);
2322 }
2323
2324 /* relax_size may be 2, 4, 12 or 0, 0 indicates no relaxation. */
2325 relaxable_p &= (backup_inst1.relax_size != 0);
2326 relax_size = relaxable_p ? backup_inst1.relax_size : 0;
2327
2328 p = frag_var (rs_machine_dependent, relax_size + RELAX_PAD_BYTE, 0,
2329 RELAX_ENCODE (backup_inst1.size, backup_inst1.relax_size,
2330 backup_inst1.type, 0, 0, relaxable_p),
2331 backup_inst1.reloc.exp.X_add_symbol, 0, NULL);
2332
2333 if (relaxable_p)
2334 md_number_to_chars (p, backup_inst1.relax_inst, relax_size);
2335
2336 memcpy (inst1, &backup_inst1, sizeof (struct score_it));
2337 }
2338
2339 static void
2340 parse_16_32_inst (char *insnstr, bfd_boolean gen_frag_p)
2341 {
2342 char c;
2343 char *p;
2344 char *operator = insnstr;
2345 const struct asm_opcode *opcode;
2346
2347 /* Parse operator and operands. */
2348 skip_whitespace (operator);
2349
2350 for (p = operator; *p != '\0'; p++)
2351 if ((*p == ' ') || (*p == '!'))
2352 break;
2353
2354 if (*p == '!')
2355 p++;
2356
2357 c = *p;
2358 *p = '\0';
2359
2360 opcode = (const struct asm_opcode *) hash_find (score_ops_hsh, operator);
2361 *p = c;
2362
2363 memset (&inst, '\0', sizeof (inst));
2364 sprintf (inst.str, "%s", insnstr);
2365 if (opcode)
2366 {
2367 inst.instruction = opcode->value;
2368 inst.relax_inst = opcode->relax_value;
2369 inst.type = opcode->type;
2370 inst.size = GET_INSN_SIZE (inst.type);
2371 inst.relax_size = 0;
2372 inst.bwarn = 0;
2373 sprintf (inst.name, "%s", opcode->template);
2374 strcpy (inst.reg, "");
2375 inst.error = NULL;
2376 inst.reloc.type = BFD_RELOC_NONE;
2377
2378 (*opcode->parms) (p);
2379
2380 /* It indicates current instruction is a macro instruction if inst.bwarn equals -1. */
2381 if ((inst.bwarn != -1) && (!inst.error) && (gen_frag_p))
2382 gen_insn_frag (&inst, NULL);
2383 }
2384 else
2385 inst.error = _("unrecognized opcode");
2386 }
2387
2388 static int
2389 append_insn (char *str, bfd_boolean gen_frag_p)
2390 {
2391 int retval = SUCCESS;
2392
2393 parse_16_32_inst (str, gen_frag_p);
2394
2395 if (inst.error)
2396 {
2397 retval = (int) FAIL;
2398 as_bad ("%s -- `%s'", inst.error, inst.str);
2399 inst.error = NULL;
2400 }
2401
2402 return retval;
2403 }
2404
2405 /* Handle mv! reg_high, reg_low;
2406 mv! reg_low, reg_high;
2407 mv! reg_low, reg_low; */
2408 static void
2409 do16_mv_rdrs (char *str)
2410 {
2411 int reg_rd;
2412 int reg_rs;
2413 char *backupstr = NULL;
2414
2415 backupstr = str;
2416 skip_whitespace (str);
2417
2418 if ((reg_rd = reg_required_here (&str, 8, REG_TYPE_SCORE)) == (int) FAIL
2419 || skip_past_comma (&str) == (int) FAIL
2420 || (reg_rs = reg_required_here (&str, 4, REG_TYPE_SCORE)) == (int) FAIL
2421 || end_of_line (str) == (int) FAIL)
2422 {
2423 return;
2424 }
2425 else
2426 {
2427 /* Case 1 : mv! or mlfh!. */
2428 if (reg_rd < 16)
2429 {
2430 if (reg_rs < 16)
2431 {
2432 inst.relax_inst |= (((inst.instruction >> 8) & 0xf) << 20)
2433 | (((inst.instruction >> 4) & 0xf) << 15) | (0xf << 10);
2434 inst.relax_size = 4;
2435 }
2436 else
2437 {
2438 char append_str[MAX_LITERAL_POOL_SIZE];
2439
2440 sprintf (append_str, "mlfh! %s", backupstr);
2441 if (append_insn (append_str, TRUE) == (int) FAIL)
2442 return;
2443 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
2444 inst.bwarn = -1;
2445 }
2446 }
2447 /* Case 2 : mhfl!. */
2448 else
2449 {
2450 if (reg_rs > 16)
2451 {
2452 SET_INSN_ERROR (BAD_ARGS);
2453 return;
2454 }
2455 else
2456 {
2457 char append_str[MAX_LITERAL_POOL_SIZE];
2458
2459 sprintf (append_str, "mhfl! %s", backupstr);
2460 if (append_insn (append_str, TRUE) == (int) FAIL)
2461 return;
2462
2463 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
2464 inst.bwarn = -1;
2465 }
2466 }
2467 }
2468 }
2469
2470 static void
2471 do16_rdi4 (char *str)
2472 {
2473 skip_whitespace (str);
2474
2475 if (reglow_required_here (&str, 8) == (int) FAIL
2476 || skip_past_comma (&str) == (int) FAIL
2477 || data_op2 (&str, 3, _IMM4) == (int) FAIL
2478 || end_of_line (str) == (int) FAIL)
2479 {
2480 return;
2481 }
2482 else
2483 {
2484 if (((inst.instruction >> 3) & 0x10) == 0) /* for judge is addei or subei : bit 5 =0 : addei */
2485 {
2486 if (((inst.instruction >> 3) & 0xf) != 0xf)
2487 {
2488 inst.relax_inst |= (((inst.instruction >> 8) & 0xf) << 20)
2489 | ((1 << ((inst.instruction >> 3) & 0xf)) << 1);
2490 inst.relax_size = 4;
2491 }
2492 else
2493 {
2494 inst.relax_inst = 0x8000;
2495 }
2496 }
2497 else
2498 {
2499 if (((inst.instruction >> 3) & 0xf) != 0xf)
2500 {
2501 inst.relax_inst |= (((inst.instruction >> 8) & 0xf) << 20)
2502 | (((-(1 << ((inst.instruction >> 3) & 0xf))) & 0xffff) << 1);
2503 inst.relax_size = 4;
2504 }
2505 else
2506 {
2507 inst.relax_inst = 0x8000;
2508 }
2509 }
2510 }
2511 }
2512
2513 static void
2514 do16_rdi5 (char *str)
2515 {
2516 skip_whitespace (str);
2517
2518 if (reglow_required_here (&str, 8) == (int) FAIL
2519 || skip_past_comma (&str) == (int) FAIL
2520 || data_op2 (&str, 3, _IMM5) == (int) FAIL
2521 || end_of_line (str) == (int) FAIL)
2522 return;
2523 else
2524 {
2525 inst.relax_inst |= (((inst.instruction >> 8) & 0xf) << 20)
2526 | (((inst.instruction >> 8) & 0xf) << 15) | (((inst.instruction >> 3) & 0x1f) << 10);
2527 inst.relax_size = 4;
2528 }
2529 }
2530
2531 /* Handle sdbbp. */
2532 static void
2533 do16_xi5 (char *str)
2534 {
2535 skip_whitespace (str);
2536
2537 if (data_op2 (&str, 3, _IMM5) == (int) FAIL || end_of_line (str) == (int) FAIL)
2538 return;
2539 else
2540 {
2541 inst.relax_inst |= (((inst.instruction >> 3) & 0x1f) << 15);
2542 inst.relax_size = 4;
2543 }
2544 }
2545
2546 /* Check that an immediate is word alignment or half word alignment.
2547 If so, convert it to the right format. */
2548 static int
2549 validate_immediate_align (int val, unsigned int data_type)
2550 {
2551 if (data_type == _IMM5_RSHIFT_1)
2552 {
2553 if (val % 2)
2554 {
2555 inst.error = _("address offset must be half word alignment");
2556 return (int) FAIL;
2557 }
2558 }
2559 else if ((data_type == _IMM5_RSHIFT_2) || (data_type == _IMM10_RSHIFT_2))
2560 {
2561 if (val % 4)
2562 {
2563 inst.error = _("address offset must be word alignment");
2564 return (int) FAIL;
2565 }
2566 }
2567
2568 return SUCCESS;
2569 }
2570
2571 static int
2572 exp_ldst_offset (char **str, int shift, unsigned int data_type)
2573 {
2574 char *dataptr;
2575
2576 dataptr = * str;
2577
2578 if ((*dataptr == '0') && (*(dataptr + 1) == 'x')
2579 && (data_type != _SIMM16_LA)
2580 && (data_type != _VALUE_HI16)
2581 && (data_type != _VALUE_LO16)
2582 && (data_type != _IMM16)
2583 && (data_type != _IMM15)
2584 && (data_type != _IMM14)
2585 && (data_type != _IMM4)
2586 && (data_type != _IMM5)
2587 && (data_type != _IMM8)
2588 && (data_type != _IMM5_RSHIFT_1)
2589 && (data_type != _IMM5_RSHIFT_2)
2590 && (data_type != _SIMM14_NEG)
2591 && (data_type != _IMM10_RSHIFT_2))
2592 {
2593 data_type += 24;
2594 }
2595
2596 if (my_get_expression (&inst.reloc.exp, str) == (int) FAIL)
2597 return (int) FAIL;
2598
2599 if (inst.reloc.exp.X_op == O_constant)
2600 {
2601 /* Need to check the immediate align. */
2602 int value = validate_immediate_align (inst.reloc.exp.X_add_number, data_type);
2603
2604 if (value == (int) FAIL)
2605 return (int) FAIL;
2606
2607 value = validate_immediate (inst.reloc.exp.X_add_number, data_type);
2608 if (value == (int) FAIL)
2609 {
2610 char err_msg[255];
2611
2612 if (data_type < 30)
2613 sprintf (err_msg,
2614 "invalid constant: %d bit expression not in range %d..%d",
2615 score_df_range[data_type].bits,
2616 score_df_range[data_type].range[0], score_df_range[data_type].range[1]);
2617 else
2618 sprintf (err_msg,
2619 "invalid constant: %d bit expression not in range %d..%d",
2620 score_df_range[data_type - 24].bits,
2621 score_df_range[data_type - 24].range[0], score_df_range[data_type - 24].range[1]);
2622 inst.error = _(err_msg);
2623 return (int) FAIL;
2624 }
2625
2626 if (data_type == _IMM5_RSHIFT_1)
2627 {
2628 value >>= 1;
2629 }
2630 else if ((data_type == _IMM5_RSHIFT_2) || (data_type == _IMM10_RSHIFT_2))
2631 {
2632 value >>= 2;
2633 }
2634
2635 if (score_df_range[data_type].range[0] != 0)
2636 {
2637 value &= (1 << score_df_range[data_type].bits) - 1;
2638 }
2639
2640 inst.instruction |= value << shift;
2641 }
2642 else
2643 {
2644 inst.reloc.pc_rel = 0;
2645 }
2646
2647 return SUCCESS;
2648 }
2649
2650 static void
2651 do_ldst_insn (char *str)
2652 {
2653 int pre_inc = 0;
2654 int conflict_reg;
2655 int value;
2656 char * temp;
2657 char *strbak;
2658 char *dataptr;
2659 int reg;
2660 int ldst_idx = 0;
2661
2662 strbak = str;
2663 skip_whitespace (str);
2664
2665 if (((conflict_reg = reg_required_here (&str, 20, REG_TYPE_SCORE)) == (int) FAIL)
2666 || (skip_past_comma (&str) == (int) FAIL))
2667 return;
2668
2669 /* ld/sw rD, [rA, simm15] ld/sw rD, [rA]+, simm12 ld/sw rD, [rA, simm12]+. */
2670 if (*str == '[')
2671 {
2672 str++;
2673 skip_whitespace (str);
2674
2675 if ((reg = reg_required_here (&str, 15, REG_TYPE_SCORE)) == (int) FAIL)
2676 return;
2677
2678 /* Conflicts can occur on stores as well as loads. */
2679 conflict_reg = (conflict_reg == reg);
2680 skip_whitespace (str);
2681 temp = str + 1; /* The latter will process decimal/hex expression. */
2682
2683 /* ld/sw rD, [rA]+, simm12 ld/sw rD, [rA]+. */
2684 if (*str == ']')
2685 {
2686 str++;
2687 if (*str == '+')
2688 {
2689 str++;
2690 /* ld/sw rD, [rA]+, simm12. */
2691 if (skip_past_comma (&str) == SUCCESS)
2692 {
2693 if ((exp_ldst_offset (&str, 3, _SIMM12) == (int) FAIL)
2694 || (end_of_line (str) == (int) FAIL))
2695 return;
2696
2697 if (conflict_reg)
2698 {
2699 unsigned int ldst_func = inst.instruction & OPC_PSEUDOLDST_MASK;
2700
2701 if ((ldst_func == INSN_LH)
2702 || (ldst_func == INSN_LHU)
2703 || (ldst_func == INSN_LW)
2704 || (ldst_func == INSN_LB)
2705 || (ldst_func == INSN_LBU))
2706 {
2707 inst.error = _("register same as write-back base");
2708 return;
2709 }
2710 }
2711
2712 ldst_idx = inst.instruction & OPC_PSEUDOLDST_MASK;
2713 inst.instruction &= ~OPC_PSEUDOLDST_MASK;
2714 inst.instruction |= score_ldst_insns[ldst_idx * 3 + LDST_POST].value;
2715
2716 /* lw rD, [rA]+, 4 convert to pop rD, [rA]. */
2717 if ((inst.instruction & 0x3e000007) == 0x0e000000)
2718 {
2719 /* rs = r0-r7, offset = 4 */
2720 if ((((inst.instruction >> 15) & 0x18) == 0)
2721 && (((inst.instruction >> 3) & 0xfff) == 4))
2722 {
2723 /* Relax to pophi. */
2724 if ((((inst.instruction >> 20) & 0x10) == 0x10))
2725 {
2726 inst.relax_inst = 0x0000200a | (((inst.instruction >> 20) & 0xf)
2727 << 8) | 1 << 7 |
2728 (((inst.instruction >> 15) & 0x7) << 4);
2729 }
2730 /* Relax to pop. */
2731 else
2732 {
2733 inst.relax_inst = 0x0000200a | (((inst.instruction >> 20) & 0xf)
2734 << 8) | 0 << 7 |
2735 (((inst.instruction >> 15) & 0x7) << 4);
2736 }
2737 inst.relax_size = 2;
2738 }
2739 }
2740 return;
2741 }
2742 /* ld/sw rD, [rA]+ convert to ld/sw rD, [rA, 0]+. */
2743 else
2744 {
2745 SET_INSN_ERROR (NULL);
2746 if (end_of_line (str) == (int) FAIL)
2747 {
2748 return;
2749 }
2750
2751 pre_inc = 1;
2752 value = validate_immediate (inst.reloc.exp.X_add_number, _SIMM12);
2753 value &= (1 << score_df_range[_SIMM12].bits) - 1;
2754 ldst_idx = inst.instruction & OPC_PSEUDOLDST_MASK;
2755 inst.instruction &= ~OPC_PSEUDOLDST_MASK;
2756 inst.instruction |= score_ldst_insns[ldst_idx * 3 + pre_inc].value;
2757 inst.instruction |= value << 3;
2758 inst.relax_inst = 0x8000;
2759 return;
2760 }
2761 }
2762 /* ld/sw rD, [rA] convert to ld/sw rD, [rA, simm15]. */
2763 else
2764 {
2765 if (end_of_line (str) == (int) FAIL)
2766 return;
2767
2768 ldst_idx = inst.instruction & OPC_PSEUDOLDST_MASK;
2769 inst.instruction &= ~OPC_PSEUDOLDST_MASK;
2770 inst.instruction |= score_ldst_insns[ldst_idx * 3 + LDST_NOUPDATE].value;
2771
2772 /* lbu rd, [rs] -> lbu! rd, [rs] */
2773 if (ldst_idx == INSN_LBU)
2774 {
2775 inst.relax_inst = INSN16_LBU;
2776 }
2777 else if (ldst_idx == INSN_LH)
2778 {
2779 inst.relax_inst = INSN16_LH;
2780 }
2781 else if (ldst_idx == INSN_LW)
2782 {
2783 inst.relax_inst = INSN16_LW;
2784 }
2785 else if (ldst_idx == INSN_SB)
2786 {
2787 inst.relax_inst = INSN16_SB;
2788 }
2789 else if (ldst_idx == INSN_SH)
2790 {
2791 inst.relax_inst = INSN16_SH;
2792 }
2793 else if (ldst_idx == INSN_SW)
2794 {
2795 inst.relax_inst = INSN16_SW;
2796 }
2797 else
2798 {
2799 inst.relax_inst = 0x8000;
2800 }
2801
2802 /* lw/lh/lbu/sw/sh/sb, offset = 0, relax to 16 bit instruction. */
2803 if ((ldst_idx == INSN_LBU)
2804 || (ldst_idx == INSN_LH)
2805 || (ldst_idx == INSN_LW)
2806 || (ldst_idx == INSN_SB) || (ldst_idx == INSN_SH) || (ldst_idx == INSN_SW))
2807 {
2808 if ((((inst.instruction >> 15) & 0x10) == 0) && (((inst.instruction >> 20) & 0x10) == 0))
2809 {
2810 inst.relax_inst |= (2 << 12) | (((inst.instruction >> 20) & 0xf) << 8) |
2811 (((inst.instruction >> 15) & 0xf) << 4);
2812 inst.relax_size = 2;
2813 }
2814 }
2815
2816 return;
2817 }
2818 }
2819 /* ld/sw rD, [rA, simm15] ld/sw rD, [rA, simm12]+. */
2820 else
2821 {
2822 if (skip_past_comma (&str) == (int) FAIL)
2823 {
2824 inst.error = _("pre-indexed expression expected");
2825 return;
2826 }
2827
2828 if (my_get_expression (&inst.reloc.exp, &str) == (int) FAIL)
2829 return;
2830
2831 skip_whitespace (str);
2832 if (*str++ != ']')
2833 {
2834 inst.error = _("missing ]");
2835 return;
2836 }
2837
2838 skip_whitespace (str);
2839 /* ld/sw rD, [rA, simm12]+. */
2840 if (*str == '+')
2841 {
2842 str++;
2843 pre_inc = 1;
2844 if (conflict_reg)
2845 {
2846 unsigned int ldst_func = inst.instruction & OPC_PSEUDOLDST_MASK;
2847
2848 if ((ldst_func == INSN_LH)
2849 || (ldst_func == INSN_LHU)
2850 || (ldst_func == INSN_LW)
2851 || (ldst_func == INSN_LB)
2852 || (ldst_func == INSN_LBU))
2853 {
2854 inst.error = _("register same as write-back base");
2855 return;
2856 }
2857 }
2858 }
2859
2860 if (end_of_line (str) == (int) FAIL)
2861 return;
2862
2863 if (inst.reloc.exp.X_op == O_constant)
2864 {
2865 int value;
2866 unsigned int data_type;
2867
2868 if (pre_inc == 1)
2869 data_type = _SIMM12;
2870 else
2871 data_type = _SIMM15;
2872 dataptr = temp;
2873
2874 if ((*dataptr == '0') && (*(dataptr + 1) == 'x')
2875 && (data_type != _SIMM16_LA)
2876 && (data_type != _VALUE_HI16)
2877 && (data_type != _VALUE_LO16)
2878 && (data_type != _IMM16)
2879 && (data_type != _IMM15)
2880 && (data_type != _IMM14)
2881 && (data_type != _IMM4)
2882 && (data_type != _IMM5)
2883 && (data_type != _IMM8)
2884 && (data_type != _IMM5_RSHIFT_1)
2885 && (data_type != _IMM5_RSHIFT_2)
2886 && (data_type != _SIMM14_NEG)
2887 && (data_type != _IMM10_RSHIFT_2))
2888 {
2889 data_type += 24;
2890 }
2891
2892 value = validate_immediate (inst.reloc.exp.X_add_number, data_type);
2893 if (value == (int) FAIL)
2894 {
2895 char err_msg[255];
2896
2897 if (data_type < 30)
2898 sprintf (err_msg,
2899 "invalid constant: %d bit expression not in range %d..%d",
2900 score_df_range[data_type].bits,
2901 score_df_range[data_type].range[0], score_df_range[data_type].range[1]);
2902 else
2903 sprintf (err_msg,
2904 "invalid constant: %d bit expression not in range %d..%d",
2905 score_df_range[data_type - 24].bits,
2906 score_df_range[data_type - 24].range[0],
2907 score_df_range[data_type - 24].range[1]);
2908 inst.error = _(err_msg);
2909 return;
2910 }
2911
2912 value &= (1 << score_df_range[data_type].bits) - 1;
2913 ldst_idx = inst.instruction & OPC_PSEUDOLDST_MASK;
2914 inst.instruction &= ~OPC_PSEUDOLDST_MASK;
2915 inst.instruction |= score_ldst_insns[ldst_idx * 3 + pre_inc].value;
2916 if (pre_inc == 1)
2917 inst.instruction |= value << 3;
2918 else
2919 inst.instruction |= value;
2920
2921 /* lw rD, [rA, simm15] */
2922 if ((inst.instruction & 0x3e000000) == 0x20000000)
2923 {
2924 /* Both rD and rA are in [r0 - r15]. */
2925 if ((((inst.instruction >> 15) & 0x10) == 0)
2926 && (((inst.instruction >> 20) & 0x10) == 0))
2927 {
2928 /* simm15 = 0, lw -> lw!. */
2929 if ((inst.instruction & 0x7fff) == 0)
2930 {
2931 inst.relax_inst |= (((inst.instruction >> 15) & 0xf) << 4)
2932 | (((inst.instruction >> 20) & 0xf) << 8);
2933 inst.relax_size = 2;
2934 }
2935 /* rA = r2, lw -> lwp!. */
2936 else if ((((inst.instruction >> 15) & 0xf) == 2)
2937 && ((inst.instruction & 0x3) == 0)
2938 && ((inst.instruction & 0x7fff) < 128))
2939 {
2940 inst.relax_inst = 0x7000 | (((inst.instruction >> 20) & 0xf) << 8)
2941 | (((inst.instruction & 0x7fff) >> 2) << 3);
2942 inst.relax_size = 2;
2943 }
2944 else
2945 {
2946 inst.relax_inst = 0x8000;
2947 }
2948 }
2949 else
2950 {
2951 inst.relax_inst = 0x8000;
2952 }
2953 }
2954 /* sw rD, [rA, simm15] */
2955 else if ((inst.instruction & 0x3e000000) == 0x28000000)
2956 {
2957 /* Both rD and rA are in [r0 - r15]. */
2958 if ((((inst.instruction >> 15) & 0x10) == 0) && (((inst.instruction >> 20) & 0x10) == 0))
2959 {
2960 /* simm15 = 0, sw -> sw!. */
2961 if ((inst.instruction & 0x7fff) == 0)
2962 {
2963 inst.relax_inst |= (((inst.instruction >> 15) & 0xf) << 4)
2964 | (((inst.instruction >> 20) & 0xf) << 8);
2965 inst.relax_size = 2;
2966 }
2967 /* rA = r2, sw -> swp!. */
2968 else if ((((inst.instruction >> 15) & 0xf) == 2)
2969 && ((inst.instruction & 0x3) == 0)
2970 && ((inst.instruction & 0x7fff) < 128))
2971 {
2972 inst.relax_inst = 0x7004 | (((inst.instruction >> 20) & 0xf) << 8)
2973 | (((inst.instruction & 0x7fff) >> 2) << 3);
2974 inst.relax_size = 2;
2975 }
2976 else
2977 {
2978 inst.relax_inst = 0x8000;
2979 }
2980 }
2981 else
2982 {
2983 inst.relax_inst = 0x8000;
2984 }
2985 }
2986 /* sw rD, [rA, simm15]+ sw pre. */
2987 else if ((inst.instruction & 0x3e000007) == 0x06000004)
2988 {
2989 /* rA is in [r0 - r7], and simm15 = -4. */
2990 if ((((inst.instruction >> 15) & 0x18) == 0)
2991 && (((inst.instruction >> 3) & 0xfff) == 0xffc))
2992 {
2993 /* sw -> pushhi!. */
2994 if ((((inst.instruction >> 20) & 0x10) == 0x10))
2995 {
2996 inst.relax_inst = 0x0000200e | (((inst.instruction >> 20) & 0xf) << 8)
2997 | 1 << 7 | (((inst.instruction >> 15) & 0x7) << 4);
2998 inst.relax_size = 2;
2999 }
3000 /* sw -> push!. */
3001 else
3002 {
3003 inst.relax_inst = 0x0000200e | (((inst.instruction >> 20) & 0xf) << 8)
3004 | 0 << 7 | (((inst.instruction >> 15) & 0x7) << 4);
3005 inst.relax_size = 2;
3006 }
3007 }
3008 else
3009 {
3010 inst.relax_inst = 0x8000;
3011 }
3012 }
3013 /* lh rD, [rA, simm15] */
3014 else if ((inst.instruction & 0x3e000000) == 0x22000000)
3015 {
3016 /* Both rD and rA are in [r0 - r15]. */
3017 if ((((inst.instruction >> 15) & 0x10) == 0) && (((inst.instruction >> 20) & 0x10) == 0))
3018 {
3019 /* simm15 = 0, lh -> lh!. */
3020 if ((inst.instruction & 0x7fff) == 0)
3021 {
3022 inst.relax_inst |= (((inst.instruction >> 15) & 0xf) << 4)
3023 | (((inst.instruction >> 20) & 0xf) << 8);
3024 inst.relax_size = 2;
3025 }
3026 /* rA = r2, lh -> lhp!. */
3027 else if ((((inst.instruction >> 15) & 0xf) == 2)
3028 && ((inst.instruction & 0x1) == 0)
3029 && ((inst.instruction & 0x7fff) < 64))
3030 {
3031 inst.relax_inst = 0x7001 | (((inst.instruction >> 20) & 0xf) << 8)
3032 | (((inst.instruction & 0x7fff) >> 1) << 3);
3033 inst.relax_size = 2;
3034 }
3035 else
3036 {
3037 inst.relax_inst = 0x8000;
3038 }
3039 }
3040 else
3041 {
3042 inst.relax_inst = 0x8000;
3043 }
3044 }
3045 /* sh rD, [rA, simm15] */
3046 else if ((inst.instruction & 0x3e000000) == 0x2a000000)
3047 {
3048 /* Both rD and rA are in [r0 - r15]. */
3049 if ((((inst.instruction >> 15) & 0x10) == 0) && (((inst.instruction >> 20) & 0x10) == 0))
3050 {
3051 /* simm15 = 0, sh -> sh!. */
3052 if ((inst.instruction & 0x7fff) == 0)
3053 {
3054 inst.relax_inst |= (((inst.instruction >> 15) & 0xf) << 4)
3055 | (((inst.instruction >> 20) & 0xf) << 8);
3056 inst.relax_size = 2;
3057 }
3058 /* rA = r2, sh -> shp!. */
3059 else if ((((inst.instruction >> 15) & 0xf) == 2)
3060 && ((inst.instruction & 0x1) == 0)
3061 && ((inst.instruction & 0x7fff) < 64))
3062 {
3063 inst.relax_inst = 0x7005 | (((inst.instruction >> 20) & 0xf) << 8)
3064 | (((inst.instruction & 0x7fff) >> 1) << 3);
3065 inst.relax_size = 2;
3066 }
3067 else
3068 {
3069 inst.relax_inst = 0x8000;
3070 }
3071 }
3072 else
3073 {
3074 inst.relax_inst = 0x8000;
3075 }
3076 }
3077 /* lbu rD, [rA, simm15] */
3078 else if ((inst.instruction & 0x3e000000) == 0x2c000000)
3079 {
3080 /* Both rD and rA are in [r0 - r15]. */
3081 if ((((inst.instruction >> 15) & 0x10) == 0) && (((inst.instruction >> 20) & 0x10) == 0))
3082 {
3083 /* simm15 = 0, lbu -> lbu!. */
3084 if ((inst.instruction & 0x7fff) == 0)
3085 {
3086 inst.relax_inst |= (((inst.instruction >> 15) & 0xf) << 4)
3087 | (((inst.instruction >> 20) & 0xf) << 8);
3088 inst.relax_size = 2;
3089 }
3090 /* rA = r2, lbu -> lbup!. */
3091 else if ((((inst.instruction >> 15) & 0xf) == 2)
3092 && ((inst.instruction & 0x7fff) < 32))
3093 {
3094 inst.relax_inst = 0x7003 | (((inst.instruction >> 20) & 0xf) << 8)
3095 | ((inst.instruction & 0x7fff) << 3);
3096 inst.relax_size = 2;
3097 }
3098 else
3099 {
3100 inst.relax_inst = 0x8000;
3101 }
3102 }
3103 else
3104 {
3105 inst.relax_inst = 0x8000;
3106 }
3107 }
3108 /* sb rD, [rA, simm15] */
3109 else if ((inst.instruction & 0x3e000000) == 0x2e000000)
3110 {
3111 /* Both rD and rA are in [r0 - r15]. */
3112 if ((((inst.instruction >> 15) & 0x10) == 0) && (((inst.instruction >> 20) & 0x10) == 0))
3113 {
3114 /* simm15 = 0, sb -> sb!. */
3115 if ((inst.instruction & 0x7fff) == 0)
3116 {
3117 inst.relax_inst |= (((inst.instruction >> 15) & 0xf) << 4)
3118 | (((inst.instruction >> 20) & 0xf) << 8);
3119 inst.relax_size = 2;
3120 }
3121 /* rA = r2, sb -> sb!. */
3122 else if ((((inst.instruction >> 15) & 0xf) == 2)
3123 && ((inst.instruction & 0x7fff) < 32))
3124 {
3125 inst.relax_inst = 0x7007 | (((inst.instruction >> 20) & 0xf) << 8)
3126 | ((inst.instruction & 0x7fff) << 3);
3127 inst.relax_size = 2;
3128 }
3129 else
3130 {
3131 inst.relax_inst = 0x8000;
3132 }
3133 }
3134 else
3135 {
3136 inst.relax_inst = 0x8000;
3137 }
3138 }
3139 else
3140 {
3141 inst.relax_inst = 0x8000;
3142 }
3143
3144 return;
3145 }
3146 else
3147 {
3148 /* FIXME: may set error, for there is no ld/sw rD, [rA, label] */
3149 inst.reloc.pc_rel = 0;
3150 }
3151 }
3152 }
3153 else
3154 {
3155 inst.error = BAD_ARGS;
3156 }
3157 }
3158
3159 /* Handle cache. */
3160
3161 static void
3162 do_cache (char *str)
3163 {
3164 skip_whitespace (str);
3165
3166 if ((data_op2 (&str, 20, _IMM5) == (int) FAIL) || (skip_past_comma (&str) == (int) FAIL))
3167 {
3168 return;
3169 }
3170 else
3171 {
3172 int cache_op;
3173
3174 cache_op = (inst.instruction >> 20) & 0x1F;
3175 sprintf (inst.name, "cache %d", cache_op);
3176 }
3177
3178 if (*str == '[')
3179 {
3180 str++;
3181 skip_whitespace (str);
3182
3183 if (reg_required_here (&str, 15, REG_TYPE_SCORE) == (int) FAIL)
3184 return;
3185
3186 skip_whitespace (str);
3187
3188 /* cache op, [rA] */
3189 if (skip_past_comma (&str) == (int) FAIL)
3190 {
3191 SET_INSN_ERROR (NULL);
3192 if (*str != ']')
3193 {
3194 inst.error = _("missing ]");
3195 return;
3196 }
3197 str++;
3198 }
3199 /* cache op, [rA, simm15] */
3200 else
3201 {
3202 if (exp_ldst_offset (&str, 0, _SIMM15) == (int) FAIL)
3203 {
3204 return;
3205 }
3206
3207 skip_whitespace (str);
3208 if (*str++ != ']')
3209 {
3210 inst.error = _("missing ]");
3211 return;
3212 }
3213 }
3214
3215 if (end_of_line (str) == (int) FAIL)
3216 return;
3217 }
3218 else
3219 {
3220 inst.error = BAD_ARGS;
3221 }
3222 }
3223
3224 static void
3225 do_crdcrscrsimm5 (char *str)
3226 {
3227 char *strbak;
3228
3229 strbak = str;
3230 skip_whitespace (str);
3231
3232 if (reg_required_here (&str, 20, REG_TYPE_SCORE_CR) == (int) FAIL
3233 || skip_past_comma (&str) == (int) FAIL
3234 || reg_required_here (&str, 15, REG_TYPE_SCORE_CR) == (int) FAIL
3235 || skip_past_comma (&str) == (int) FAIL
3236 || reg_required_here (&str, 10, REG_TYPE_SCORE_CR) == (int) FAIL
3237 || skip_past_comma (&str) == (int) FAIL)
3238 {
3239 str = strbak;
3240 /* cop1 cop_code20. */
3241 if (data_op2 (&str, 5, _IMM20) == (int) FAIL)
3242 return;
3243 }
3244 else
3245 {
3246 if (data_op2 (&str, 5, _IMM5) == (int) FAIL)
3247 return;
3248 }
3249
3250 end_of_line (str);
3251 }
3252
3253 /* Handle ldc/stc. */
3254 static void
3255 do_ldst_cop (char *str)
3256 {
3257 skip_whitespace (str);
3258
3259 if ((reg_required_here (&str, 15, REG_TYPE_SCORE_CR) == (int) FAIL)
3260 || (skip_past_comma (&str) == (int) FAIL))
3261 return;
3262
3263 if (*str == '[')
3264 {
3265 str++;
3266 skip_whitespace (str);
3267
3268 if (reg_required_here (&str, 20, REG_TYPE_SCORE) == (int) FAIL)
3269 return;
3270
3271 skip_whitespace (str);
3272
3273 if (*str++ != ']')
3274 {
3275 if (exp_ldst_offset (&str, 5, _IMM10_RSHIFT_2) == (int) FAIL)
3276 return;
3277
3278 skip_whitespace (str);
3279 if (*str++ != ']')
3280 {
3281 inst.error = _("missing ]");
3282 return;
3283 }
3284 }
3285
3286 end_of_line (str);
3287 }
3288 else
3289 inst.error = BAD_ARGS;
3290 }
3291
3292 static void
3293 do16_ldst_insn (char *str)
3294 {
3295 skip_whitespace (str);
3296
3297 if ((reglow_required_here (&str, 8) == (int) FAIL) || (skip_past_comma (&str) == (int) FAIL))
3298 return;
3299
3300 if (*str == '[')
3301 {
3302 int reg;
3303
3304 str++;
3305 skip_whitespace (str);
3306
3307 if ((reg = reglow_required_here (&str, 4)) == (int) FAIL)
3308 return;
3309
3310 skip_whitespace (str);
3311 if (*str++ == ']')
3312 {
3313 if (end_of_line (str) == (int) FAIL)
3314 return;
3315 else
3316 {
3317 inst.relax_inst |= (((inst.instruction >> 8) & 0xf) << 20)
3318 | (((inst.instruction >> 4) & 0xf) << 15);
3319 inst.relax_size = 4;
3320 }
3321 }
3322 else
3323 {
3324 inst.error = _("missing ]");
3325 }
3326 }
3327 else
3328 {
3329 inst.error = BAD_ARGS;
3330 }
3331 }
3332
3333 /* Handle lbup!/lhp!/ldiu!/lwp!/sbp!/shp!/swp!. */
3334 static void
3335 do16_ldst_imm_insn (char *str)
3336 {
3337 char data_exp[MAX_LITERAL_POOL_SIZE];
3338 int reg_rd;
3339 char *dataptr = NULL, *pp = NULL;
3340 int cnt = 0;
3341 int assign_data = (int) FAIL;
3342 unsigned int ldst_func;
3343
3344 skip_whitespace (str);
3345
3346 if (((reg_rd = reglow_required_here (&str, 8)) == (int) FAIL)
3347 || (skip_past_comma (&str) == (int) FAIL))
3348 return;
3349
3350 skip_whitespace (str);
3351 dataptr = str;
3352
3353 while ((*dataptr != '\0') && (*dataptr != '|') && (cnt <= MAX_LITERAL_POOL_SIZE))
3354 {
3355 data_exp[cnt] = *dataptr;
3356 dataptr++;
3357 cnt++;
3358 }
3359
3360 data_exp[cnt] = '\0';
3361 pp = &data_exp[0];
3362
3363 str = dataptr;
3364
3365 ldst_func = inst.instruction & LDST16_RI_MASK;
3366 if (ldst_func == N16_LIU)
3367 assign_data = exp_ldst_offset (&pp, 0, _IMM8);
3368 else if (ldst_func == N16_LHP || ldst_func == N16_SHP)
3369 assign_data = exp_ldst_offset (&pp, 3, _IMM5_RSHIFT_1);
3370 else if (ldst_func == N16_LWP || ldst_func == N16_SWP)
3371 assign_data = exp_ldst_offset (&pp, 3, _IMM5_RSHIFT_2);
3372 else
3373 assign_data = exp_ldst_offset (&pp, 3, _IMM5);
3374
3375 if ((assign_data == (int) FAIL) || (end_of_line (pp) == (int) FAIL))
3376 return;
3377 else
3378 {
3379 if ((inst.instruction & 0x7000) == N16_LIU)
3380 {
3381 inst.relax_inst |= ((inst.instruction >> 8) & 0xf) << 20
3382 | ((inst.instruction & 0xff) << 1);
3383 }
3384 else if (((inst.instruction & 0x7007) == N16_LHP)
3385 || ((inst.instruction & 0x7007) == N16_SHP))
3386 {
3387 inst.relax_inst |= ((inst.instruction >> 8) & 0xf) << 20 | 2 << 15
3388 | (((inst.instruction >> 3) & 0x1f) << 1);
3389 }
3390 else if (((inst.instruction & 0x7007) == N16_LWP)
3391 || ((inst.instruction & 0x7007) == N16_SWP))
3392 {
3393 inst.relax_inst |= ((inst.instruction >> 8) & 0xf) << 20 | 2 << 15
3394 | (((inst.instruction >> 3) & 0x1f) << 2);
3395 }
3396 else if (((inst.instruction & 0x7007) == N16_LBUP)
3397 || ((inst.instruction & 0x7007) == N16_SBP))
3398 {
3399 inst.relax_inst |= ((inst.instruction >> 8) & 0xf) << 20 | 2 << 15
3400 | (((inst.instruction >> 3) & 0x1f));
3401 }
3402
3403 inst.relax_size = 4;
3404 }
3405 }
3406
3407 static void
3408 do16_push_pop (char *str)
3409 {
3410 int reg_rd;
3411 int H_bit_mask = 0;
3412
3413 skip_whitespace (str);
3414 if (((reg_rd = reg_required_here (&str, 8, REG_TYPE_SCORE)) == (int) FAIL)
3415 || (skip_past_comma (&str) == (int) FAIL))
3416 return;
3417
3418 if (reg_rd >= 16)
3419 H_bit_mask = 1;
3420
3421 /* reg_required_here will change bit 12 of opcode, so we must restore bit 12. */
3422 inst.instruction &= ~(1 << 12);
3423
3424 inst.instruction |= H_bit_mask << 7;
3425
3426 if (*str == '[')
3427 {
3428 int reg;
3429
3430 str++;
3431 skip_whitespace (str);
3432 if ((reg = reg_required_here (&str, 4, REG_TYPE_SCORE)) == (int) FAIL)
3433 return;
3434 else if (reg > 7)
3435 {
3436 if (!inst.error)
3437 inst.error = _("base register nums are over 3 bit");
3438
3439 return;
3440 }
3441
3442 skip_whitespace (str);
3443 if ((*str++ != ']') || (end_of_line (str) == (int) FAIL))
3444 {
3445 if (!inst.error)
3446 inst.error = _("missing ]");
3447
3448 return;
3449 }
3450
3451 /* pop! */
3452 if ((inst.instruction & 0xf) == 0xa)
3453 {
3454 if (H_bit_mask)
3455 {
3456 inst.relax_inst |= ((((inst.instruction >> 8) & 0xf) | 0x10) << 20)
3457 | (((inst.instruction >> 4) & 0x7) << 15) | (4 << 3);
3458 }
3459 else
3460 {
3461 inst.relax_inst |= (((inst.instruction >> 8) & 0xf) << 20)
3462 | (((inst.instruction >> 4) & 0x7) << 15) | (4 << 3);
3463 }
3464 }
3465 /* push! */
3466 else
3467 {
3468 if (H_bit_mask)
3469 {
3470 inst.relax_inst |= ((((inst.instruction >> 8) & 0xf) | 0x10) << 20)
3471 | (((inst.instruction >> 4) & 0x7) << 15) | (((-4) & 0xfff) << 3);
3472 }
3473 else
3474 {
3475 inst.relax_inst |= (((inst.instruction >> 8) & 0xf) << 20)
3476 | (((inst.instruction >> 4) & 0x7) << 15) | (((-4) & 0xfff) << 3);
3477 }
3478 }
3479 inst.relax_size = 4;
3480 }
3481 else
3482 {
3483 inst.error = BAD_ARGS;
3484 }
3485 }
3486
3487 /* Handle lcb/lcw/lce/scb/scw/sce. */
3488 static void
3489 do_ldst_unalign (char *str)
3490 {
3491 int conflict_reg;
3492
3493 if (university_version == 1)
3494 {
3495 inst.error = ERR_FOR_SCORE5U_ATOMIC;
3496 return;
3497 }
3498
3499 skip_whitespace (str);
3500
3501 /* lcb/scb [rA]+. */
3502 if (*str == '[')
3503 {
3504 str++;
3505 skip_whitespace (str);
3506
3507 if (reg_required_here (&str, 15, REG_TYPE_SCORE) == (int) FAIL)
3508 return;
3509
3510 if (*str++ == ']')
3511 {
3512 if (*str++ != '+')
3513 {
3514 inst.error = _("missing +");
3515 return;
3516 }
3517 }
3518 else
3519 {
3520 inst.error = _("missing ]");
3521 return;
3522 }
3523
3524 if (end_of_line (str) == (int) FAIL)
3525 return;
3526 }
3527 /* lcw/lce/scb/sce rD, [rA]+. */
3528 else
3529 {
3530 if (((conflict_reg = reg_required_here (&str, 20, REG_TYPE_SCORE)) == (int) FAIL)
3531 || (skip_past_comma (&str) == (int) FAIL))
3532 {
3533 return;
3534 }
3535
3536 skip_whitespace (str);
3537 if (*str++ == '[')
3538 {
3539 int reg;
3540
3541 skip_whitespace (str);
3542 if ((reg = reg_required_here (&str, 15, REG_TYPE_SCORE)) == (int) FAIL)
3543 {
3544 return;
3545 }
3546
3547 /* Conflicts can occur on stores as well as loads. */
3548 conflict_reg = (conflict_reg == reg);
3549 skip_whitespace (str);
3550 if (*str++ == ']')
3551 {
3552 unsigned int ldst_func = inst.instruction & LDST_UNALIGN_MASK;
3553
3554 if (*str++ == '+')
3555 {
3556 if (conflict_reg)
3557 {
3558 as_warn (_("%s register same as write-back base"),
3559 ((ldst_func & UA_LCE) || (ldst_func & UA_LCW)
3560 ? _("destination") : _("source")));
3561 }
3562 }
3563 else
3564 {
3565 inst.error = _("missing +");
3566 return;
3567 }
3568
3569 if (end_of_line (str) == (int) FAIL)
3570 return;
3571 }
3572 else
3573 {
3574 inst.error = _("missing ]");
3575 return;
3576 }
3577 }
3578 else
3579 {
3580 inst.error = BAD_ARGS;
3581 return;
3582 }
3583 }
3584 }
3585
3586 /* Handle alw/asw. */
3587 static void
3588 do_ldst_atomic (char *str)
3589 {
3590 if (university_version == 1)
3591 {
3592 inst.error = ERR_FOR_SCORE5U_ATOMIC;
3593 return;
3594 }
3595
3596 skip_whitespace (str);
3597
3598 if ((reg_required_here (&str, 20, REG_TYPE_SCORE) == (int) FAIL)
3599 || (skip_past_comma (&str) == (int) FAIL))
3600 {
3601 return;
3602 }
3603 else
3604 {
3605
3606 skip_whitespace (str);
3607 if (*str++ == '[')
3608 {
3609 int reg;
3610
3611 skip_whitespace (str);
3612 if ((reg = reg_required_here (&str, 15, REG_TYPE_SCORE)) == (int) FAIL)
3613 {
3614 return;
3615 }
3616
3617 skip_whitespace (str);
3618 if (*str++ != ']')
3619 {
3620 inst.error = _("missing ]");
3621 return;
3622 }
3623
3624 end_of_line (str);
3625 }
3626 else
3627 inst.error = BAD_ARGS;
3628 }
3629 }
3630
3631 static void
3632 build_relax_frag (struct score_it fix_insts[RELAX_INST_NUM], int fix_num ATTRIBUTE_UNUSED,
3633 struct score_it var_insts[RELAX_INST_NUM], int var_num,
3634 symbolS *add_symbol)
3635 {
3636 int i;
3637 char *p;
3638 fixS *fixp = NULL;
3639 fixS *cur_fixp = NULL;
3640 long where;
3641 struct score_it inst_main;
3642
3643 memcpy (&inst_main, &fix_insts[0], sizeof (struct score_it));
3644
3645 /* Adjust instruction opcode and to be relaxed instruction opcode. */
3646 inst_main.instruction = adjust_paritybit (inst_main.instruction, GET_INSN_CLASS (inst_main.type));
3647 inst_main.type = Insn_PIC;
3648
3649 for (i = 0; i < var_num; i++)
3650 {
3651 inst_main.relax_size += var_insts[i].size;
3652 var_insts[i].instruction = adjust_paritybit (var_insts[i].instruction,
3653 GET_INSN_CLASS (var_insts[i].type));
3654 }
3655
3656 /* Check data dependency. */
3657 handle_dependency (&inst_main);
3658
3659 /* Start a new frag if frag_now is not empty. */
3660 if (frag_now_fix () != 0)
3661 {
3662 if (!frag_now->tc_frag_data.is_insn)
3663 {
3664 frag_wane (frag_now);
3665 }
3666 frag_new (0);
3667 }
3668 frag_grow (20);
3669
3670 /* Write fr_fix part. */
3671 p = frag_more (inst_main.size);
3672 md_number_to_chars (p, inst_main.instruction, inst_main.size);
3673
3674 if (inst_main.reloc.type != BFD_RELOC_NONE)
3675 fixp = fix_new_score (frag_now, p - frag_now->fr_literal, inst_main.size,
3676 &inst_main.reloc.exp, inst_main.reloc.pc_rel, inst_main.reloc.type);
3677
3678 frag_now->tc_frag_data.fixp = fixp;
3679 cur_fixp = frag_now->tc_frag_data.fixp;
3680
3681 #ifdef OBJ_ELF
3682 dwarf2_emit_insn (inst_main.size);
3683 #endif
3684
3685 where = p - frag_now->fr_literal + inst_main.size;
3686 for (i = 0; i < var_num; i++)
3687 {
3688 if (i > 0)
3689 where += var_insts[i - 1].size;
3690
3691 if (var_insts[i].reloc.type != BFD_RELOC_NONE)
3692 {
3693 fixp = fix_new_score (frag_now, where, var_insts[i].size,
3694 &var_insts[i].reloc.exp, var_insts[i].reloc.pc_rel,
3695 var_insts[i].reloc.type);
3696 if (fixp)
3697 {
3698 if (cur_fixp)
3699 {
3700 cur_fixp->fx_next = fixp;
3701 cur_fixp = cur_fixp->fx_next;
3702 }
3703 else
3704 {
3705 frag_now->tc_frag_data.fixp = fixp;
3706 cur_fixp = frag_now->tc_frag_data.fixp;
3707 }
3708 }
3709 }
3710 }
3711
3712 p = frag_var (rs_machine_dependent, inst_main.relax_size + RELAX_PAD_BYTE, 0,
3713 RELAX_ENCODE (inst_main.size, inst_main.relax_size, inst_main.type,
3714 0, inst_main.size, 0), add_symbol, 0, NULL);
3715
3716 /* Write fr_var part.
3717 no calling gen_insn_frag, no fixS will be generated. */
3718 for (i = 0; i < var_num; i++)
3719 {
3720 md_number_to_chars (p, var_insts[i].instruction, var_insts[i].size);
3721 p += var_insts[i].size;
3722 }
3723 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
3724 inst.bwarn = -1;
3725 }
3726
3727 /* Build a relax frag for la instruction when generating PIC,
3728 external symbol first and local symbol second. */
3729
3730 static void
3731 build_la_pic (int reg_rd, expressionS exp)
3732 {
3733 symbolS *add_symbol = exp.X_add_symbol;
3734 offsetT add_number = exp.X_add_number;
3735 struct score_it fix_insts[RELAX_INST_NUM];
3736 struct score_it var_insts[RELAX_INST_NUM];
3737 int fix_num = 0;
3738 int var_num = 0;
3739 char tmp[MAX_LITERAL_POOL_SIZE];
3740 int r1_bak;
3741
3742 r1_bak = nor1;
3743 nor1 = 0;
3744
3745 if (add_number == 0)
3746 {
3747 fix_num = 1;
3748 var_num = 2;
3749
3750 /* Insn 1 and Insn 2 */
3751 /* Fix part
3752 For an external symbol: lw rD, <sym>($gp)
3753 (BFD_RELOC_SCORE_GOT15 or BFD_RELOC_SCORE_CALL15) */
3754 sprintf (tmp, "lw_pic r%d, %s", reg_rd, add_symbol->bsym->name);
3755 if (append_insn (tmp, FALSE) == (int) FAIL)
3756 return;
3757
3758 if (reg_rd == PIC_CALL_REG)
3759 inst.reloc.type = BFD_RELOC_SCORE_CALL15;
3760 memcpy (&fix_insts[0], &inst, sizeof (struct score_it));
3761
3762 /* Var part
3763 For a local symbol :
3764 lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15)
3765 addi rD, <sym> (BFD_RELOC_GOT_LO16) */
3766 inst.reloc.type = BFD_RELOC_SCORE_GOT15;
3767 memcpy (&var_insts[0], &inst, sizeof (struct score_it));
3768 sprintf (tmp, "addi_s_pic r%d, %s", reg_rd, add_symbol->bsym->name);
3769 if (append_insn (tmp, FALSE) == (int) FAIL)
3770 return;
3771
3772 memcpy (&var_insts[1], &inst, sizeof (struct score_it));
3773 build_relax_frag (fix_insts, fix_num, var_insts, var_num, add_symbol);
3774 }
3775 else if (add_number >= -0x8000 && add_number <= 0x7fff)
3776 {
3777 /* Insn 1: lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15) */
3778 sprintf (tmp, "lw_pic r%d, %s", reg_rd, add_symbol->bsym->name);
3779 if (append_insn (tmp, TRUE) == (int) FAIL)
3780 return;
3781
3782 /* Insn 2 */
3783 fix_num = 1;
3784 var_num = 1;
3785 /* Fix part
3786 For an external symbol: addi rD, <constant> */
3787 sprintf (tmp, "addi r%d, %d", reg_rd, (int)add_number);
3788 if (append_insn (tmp, FALSE) == (int) FAIL)
3789 return;
3790
3791 memcpy (&fix_insts[0], &inst, sizeof (struct score_it));
3792
3793 /* Var part
3794 For a local symbol: addi rD, <sym>+<constant> (BFD_RELOC_GOT_LO16) */
3795 sprintf (tmp, "addi_s_pic r%d, %s + %d", reg_rd, add_symbol->bsym->name, (int)add_number);
3796 if (append_insn (tmp, FALSE) == (int) FAIL)
3797 return;
3798
3799 memcpy (&var_insts[0], &inst, sizeof (struct score_it));
3800 build_relax_frag (fix_insts, fix_num, var_insts, var_num, add_symbol);
3801 }
3802 else
3803 {
3804 int hi = (add_number >> 16) & 0x0000FFFF;
3805 int lo = add_number & 0x0000FFFF;
3806
3807 /* Insn 1: lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15) */
3808 sprintf (tmp, "lw_pic r%d, %s", reg_rd, add_symbol->bsym->name);
3809 if (append_insn (tmp, TRUE) == (int) FAIL)
3810 return;
3811
3812 /* Insn 2 */
3813 fix_num = 1;
3814 var_num = 1;
3815 /* Fix part
3816 For an external symbol: ldis r1, HI%<constant> */
3817 sprintf (tmp, "ldis %s, %d", "r1", hi);
3818 if (append_insn (tmp, FALSE) == (int) FAIL)
3819 return;
3820
3821 memcpy (&fix_insts[0], &inst, sizeof (struct score_it));
3822
3823 /* Var part
3824 For a local symbol: ldis r1, HI%<constant>
3825 but, if lo is outof 16 bit, make hi plus 1 */
3826 if ((lo < -0x8000) || (lo > 0x7fff))
3827 {
3828 hi += 1;
3829 }
3830 sprintf (tmp, "ldis_pic %s, %d", "r1", hi);
3831 if (append_insn (tmp, FALSE) == (int) FAIL)
3832 return;
3833
3834 memcpy (&var_insts[0], &inst, sizeof (struct score_it));
3835 build_relax_frag (fix_insts, fix_num, var_insts, var_num, add_symbol);
3836
3837 /* Insn 3 */
3838 fix_num = 1;
3839 var_num = 1;
3840 /* Fix part
3841 For an external symbol: ori r1, LO%<constant> */
3842 sprintf (tmp, "ori %s, %d", "r1", lo);
3843 if (append_insn (tmp, FALSE) == (int) FAIL)
3844 return;
3845
3846 memcpy (&fix_insts[0], &inst, sizeof (struct score_it));
3847
3848 /* Var part
3849 For a local symbol: addi r1, <sym>+LO%<constant> (BFD_RELOC_GOT_LO16) */
3850 sprintf (tmp, "addi_u_pic %s, %s + %d", "r1", add_symbol->bsym->name, lo);
3851 if (append_insn (tmp, FALSE) == (int) FAIL)
3852 return;
3853
3854 memcpy (&var_insts[0], &inst, sizeof (struct score_it));
3855 build_relax_frag (fix_insts, fix_num, var_insts, var_num, add_symbol);
3856
3857 /* Insn 4: add rD, rD, r1 */
3858 sprintf (tmp, "add r%d, r%d, %s", reg_rd, reg_rd, "r1");
3859 if (append_insn (tmp, TRUE) == (int) FAIL)
3860 return;
3861
3862 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
3863 inst.bwarn = -1;
3864 }
3865
3866 nor1 = r1_bak;
3867 }
3868
3869 /* Handle la. */
3870 static void
3871 do_macro_la_rdi32 (char *str)
3872 {
3873 int reg_rd;
3874
3875 skip_whitespace (str);
3876 if ((reg_rd = reg_required_here (&str, 20, REG_TYPE_SCORE)) == (int) FAIL
3877 || skip_past_comma (&str) == (int) FAIL)
3878 {
3879 return;
3880 }
3881 else
3882 {
3883 char append_str[MAX_LITERAL_POOL_SIZE];
3884 char *keep_data = str;
3885
3886 /* la rd, simm16. */
3887 if (data_op2 (&str, 1, _SIMM16_LA) != (int) FAIL)
3888 {
3889 end_of_line (str);
3890 return;
3891 }
3892 /* la rd, imm32 or la rd, label. */
3893 else
3894 {
3895 SET_INSN_ERROR (NULL);
3896 str = keep_data;
3897 if ((data_op2 (&str, 1, _VALUE_HI16) == (int) FAIL)
3898 || (end_of_line (str) == (int) FAIL))
3899 {
3900 return;
3901 }
3902 else
3903 {
3904 if ((score_pic == NO_PIC) || (!inst.reloc.exp.X_add_symbol))
3905 {
3906 sprintf (append_str, "ld_i32hi r%d, %s", reg_rd, keep_data);
3907 if (append_insn (append_str, TRUE) == (int) FAIL)
3908 return;
3909
3910 sprintf (append_str, "ld_i32lo r%d, %s", reg_rd, keep_data);
3911 if (append_insn (append_str, TRUE) == (int) FAIL)
3912 return;
3913 }
3914 else
3915 {
3916 assert (inst.reloc.exp.X_add_symbol);
3917 build_la_pic (reg_rd, inst.reloc.exp);
3918 }
3919
3920 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
3921 inst.bwarn = -1;
3922 }
3923 }
3924 }
3925 }
3926
3927 /* Handle li. */
3928 static void
3929 do_macro_li_rdi32 (char *str){
3930
3931 int reg_rd;
3932
3933 skip_whitespace (str);
3934 if ((reg_rd = reg_required_here (&str, 20, REG_TYPE_SCORE)) == (int) FAIL
3935 || skip_past_comma (&str) == (int) FAIL)
3936 {
3937 return;
3938 }
3939 else
3940 {
3941 char *keep_data = str;
3942
3943 /* li rd, simm16. */
3944 if (data_op2 (&str, 1, _SIMM16_LA) != (int) FAIL)
3945 {
3946 end_of_line (str);
3947 return;
3948 }
3949 /* li rd, imm32. */
3950 else
3951 {
3952 char append_str[MAX_LITERAL_POOL_SIZE];
3953
3954 str = keep_data;
3955
3956 if ((data_op2 (&str, 1, _VALUE_HI16) == (int) FAIL)
3957 || (end_of_line (str) == (int) FAIL))
3958 {
3959 return;
3960 }
3961 else if (inst.reloc.exp.X_add_symbol)
3962 {
3963 inst.error = _("li rd label isn't correct instruction form");
3964 return;
3965 }
3966 else
3967 {
3968 sprintf (append_str, "ld_i32hi r%d, %s", reg_rd, keep_data);
3969
3970 if (append_insn (append_str, TRUE) == (int) FAIL)
3971 return;
3972 else
3973 {
3974 sprintf (append_str, "ld_i32lo r%d, %s", reg_rd, keep_data);
3975 if (append_insn (append_str, TRUE) == (int) FAIL)
3976 return;
3977
3978 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
3979 inst.bwarn = -1;
3980 }
3981 }
3982 }
3983 }
3984 }
3985
3986 /* Handle mul/mulu/div/divu/rem/remu. */
3987 static void
3988 do_macro_mul_rdrsrs (char *str)
3989 {
3990 int reg_rd;
3991 int reg_rs1;
3992 int reg_rs2;
3993 char *backupstr;
3994 char append_str[MAX_LITERAL_POOL_SIZE];
3995
3996 if (university_version == 1)
3997 as_warn ("%s", ERR_FOR_SCORE5U_MUL_DIV);
3998
3999 strcpy (append_str, str);
4000 backupstr = append_str;
4001 skip_whitespace (backupstr);
4002 if (((reg_rd = reg_required_here (&backupstr, -1, REG_TYPE_SCORE)) == (int) FAIL)
4003 || (skip_past_comma (&backupstr) == (int) FAIL)
4004 || ((reg_rs1 = reg_required_here (&backupstr, -1, REG_TYPE_SCORE)) == (int) FAIL))
4005 {
4006 inst.error = BAD_ARGS;
4007 return;
4008 }
4009
4010 if (skip_past_comma (&backupstr) == (int) FAIL)
4011 {
4012 /* rem/remu rA, rB is error format. */
4013 if (strcmp (inst.name, "rem") == 0 || strcmp (inst.name, "remu") == 0)
4014 {
4015 SET_INSN_ERROR (BAD_ARGS);
4016 }
4017 else
4018 {
4019 SET_INSN_ERROR (NULL);
4020 do_rsrs (str);
4021 }
4022 return;
4023 }
4024 else
4025 {
4026 SET_INSN_ERROR (NULL);
4027 if (((reg_rs2 = reg_required_here (&backupstr, -1, REG_TYPE_SCORE)) == (int) FAIL)
4028 || (end_of_line (backupstr) == (int) FAIL))
4029 {
4030 return;
4031 }
4032 else
4033 {
4034 char append_str1[MAX_LITERAL_POOL_SIZE];
4035
4036 if (strcmp (inst.name, "rem") == 0)
4037 {
4038 sprintf (append_str, "%s r%d, r%d", "mul", reg_rs1, reg_rs2);
4039 sprintf (append_str1, "mfceh r%d", reg_rd);
4040 }
4041 else if (strcmp (inst.name, "remu") == 0)
4042 {
4043 sprintf (append_str, "%s r%d, r%d", "mulu", reg_rs1, reg_rs2);
4044 sprintf (append_str1, "mfceh r%d", reg_rd);
4045 }
4046 else
4047 {
4048 sprintf (append_str, "%s r%d, r%d", inst.name, reg_rs1, reg_rs2);
4049 sprintf (append_str1, "mfcel r%d", reg_rd);
4050 }
4051
4052 /* Output mul/mulu or div/divu or rem/remu. */
4053 if (append_insn (append_str, TRUE) == (int) FAIL)
4054 return;
4055
4056 /* Output mfcel or mfceh. */
4057 if (append_insn (append_str1, TRUE) == (int) FAIL)
4058 return;
4059
4060 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4061 inst.bwarn = -1;
4062 }
4063 }
4064 }
4065
4066 static void
4067 exp_macro_ldst_abs (char *str)
4068 {
4069 int reg_rd;
4070 char *backupstr, *tmp;
4071 char append_str[MAX_LITERAL_POOL_SIZE];
4072 char verifystr[MAX_LITERAL_POOL_SIZE];
4073 struct score_it inst_backup;
4074 int r1_bak = 0;
4075
4076 r1_bak = nor1;
4077 nor1 = 0;
4078 memcpy (&inst_backup, &inst, sizeof (struct score_it));
4079
4080 strcpy (verifystr, str);
4081 backupstr = verifystr;
4082 skip_whitespace (backupstr);
4083 if ((reg_rd = reg_required_here (&backupstr, -1, REG_TYPE_SCORE)) == (int) FAIL)
4084 return;
4085
4086 tmp = backupstr;
4087 if (skip_past_comma (&backupstr) == (int) FAIL)
4088 return;
4089
4090 backupstr = tmp;
4091 sprintf (append_str, "li r1 %s", backupstr);
4092 append_insn (append_str, TRUE);
4093
4094 memcpy (&inst, &inst_backup, sizeof (struct score_it));
4095 sprintf (append_str, " r%d, [r1,0]", reg_rd);
4096 do_ldst_insn (append_str);
4097
4098 nor1 = r1_bak;
4099 }
4100
4101 static int
4102 nopic_need_relax (symbolS * sym, int before_relaxing)
4103 {
4104 if (sym == NULL)
4105 return 0;
4106 else if (USE_GLOBAL_POINTER_OPT && g_switch_value > 0)
4107 {
4108 const char *symname;
4109 const char *segname;
4110
4111 /* Find out whether this symbol can be referenced off the $gp
4112 register. It can be if it is smaller than the -G size or if
4113 it is in the .sdata or .sbss section. Certain symbols can
4114 not be referenced off the $gp, although it appears as though
4115 they can. */
4116 symname = S_GET_NAME (sym);
4117 if (symname != (const char *)NULL
4118 && (strcmp (symname, "eprol") == 0
4119 || strcmp (symname, "etext") == 0
4120 || strcmp (symname, "_gp") == 0
4121 || strcmp (symname, "edata") == 0
4122 || strcmp (symname, "_fbss") == 0
4123 || strcmp (symname, "_fdata") == 0
4124 || strcmp (symname, "_ftext") == 0
4125 || strcmp (symname, "end") == 0
4126 || strcmp (symname, GP_DISP_LABEL) == 0))
4127 {
4128 return 1;
4129 }
4130 else if ((!S_IS_DEFINED (sym) || S_IS_COMMON (sym)) && (0
4131 /* We must defer this decision until after the whole file has been read,
4132 since there might be a .extern after the first use of this symbol. */
4133 || (before_relaxing
4134 && S_GET_VALUE (sym) == 0)
4135 || (S_GET_VALUE (sym) != 0
4136 && S_GET_VALUE (sym) <= g_switch_value)))
4137 {
4138 return 0;
4139 }
4140
4141 segname = segment_name (S_GET_SEGMENT (sym));
4142 return (strcmp (segname, ".sdata") != 0
4143 && strcmp (segname, ".sbss") != 0
4144 && strncmp (segname, ".sdata.", 7) != 0
4145 && strncmp (segname, ".gnu.linkonce.s.", 16) != 0);
4146 }
4147 /* We are not optimizing for the $gp register. */
4148 else
4149 return 1;
4150 }
4151
4152 /* Build a relax frag for lw instruction when generating PIC,
4153 external symbol first and local symbol second. */
4154
4155 static void
4156 build_lw_pic (int reg_rd, expressionS exp)
4157 {
4158 symbolS *add_symbol = exp.X_add_symbol;
4159 int add_number = exp.X_add_number;
4160 struct score_it fix_insts[RELAX_INST_NUM];
4161 struct score_it var_insts[RELAX_INST_NUM];
4162 int fix_num = 0;
4163 int var_num = 0;
4164 char tmp[MAX_LITERAL_POOL_SIZE];
4165 int r1_bak;
4166
4167 r1_bak = nor1;
4168 nor1 = 0;
4169
4170 if ((add_number == 0) || (add_number >= -0x8000 && add_number <= 0x7fff))
4171 {
4172 fix_num = 1;
4173 var_num = 2;
4174
4175 /* Insn 1 and Insn 2 */
4176 /* Fix part
4177 For an external symbol: lw rD, <sym>($gp)
4178 (BFD_RELOC_SCORE_GOT15) */
4179 sprintf (tmp, "lw_pic r%d, %s", reg_rd, add_symbol->bsym->name);
4180 if (append_insn (tmp, FALSE) == (int) FAIL)
4181 return;
4182
4183 memcpy (&fix_insts[0], &inst, sizeof (struct score_it));
4184
4185 /* Var part
4186 For a local symbol :
4187 lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15)
4188 addi rD, <sym> (BFD_RELOC_GOT_LO16) */
4189 inst.reloc.type = BFD_RELOC_SCORE_GOT15;
4190 memcpy (&var_insts[0], &inst, sizeof (struct score_it));
4191 sprintf (tmp, "addi_s_pic r%d, %s", reg_rd, add_symbol->bsym->name);
4192 if (append_insn (tmp, FALSE) == (int) FAIL)
4193 return;
4194
4195 memcpy (&var_insts[1], &inst, sizeof (struct score_it));
4196 build_relax_frag (fix_insts, fix_num, var_insts, var_num, add_symbol);
4197
4198 /* Insn 2: lw rD, [rD, constant] */
4199 sprintf (tmp, "lw r%d, [r%d, %d]", reg_rd, reg_rd, add_number);
4200 if (append_insn (tmp, TRUE) == (int) FAIL)
4201 return;
4202
4203 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4204 inst.bwarn = -1;
4205 }
4206 else
4207 {
4208 int hi = (add_number >> 16) & 0x0000FFFF;
4209 int lo = add_number & 0x0000FFFF;
4210
4211 /* Insn 1: lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15) */
4212 sprintf (tmp, "lw_pic r%d, %s", reg_rd, add_symbol->bsym->name);
4213 if (append_insn (tmp, TRUE) == (int) FAIL)
4214 return;
4215
4216 /* Insn 2 */
4217 fix_num = 1;
4218 var_num = 1;
4219 /* Fix part
4220 For an external symbol: ldis r1, HI%<constant> */
4221 sprintf (tmp, "ldis %s, %d", "r1", hi);
4222 if (append_insn (tmp, FALSE) == (int) FAIL)
4223 return;
4224
4225 memcpy (&fix_insts[0], &inst, sizeof (struct score_it));
4226
4227 /* Var part
4228 For a local symbol: ldis r1, HI%<constant>
4229 but, if lo is outof 16 bit, make hi plus 1 */
4230 if ((lo < -0x8000) || (lo > 0x7fff))
4231 {
4232 hi += 1;
4233 }
4234 sprintf (tmp, "ldis_pic %s, %d", "r1", hi);
4235 if (append_insn (tmp, FALSE) == (int) FAIL)
4236 return;
4237
4238 memcpy (&var_insts[0], &inst, sizeof (struct score_it));
4239 build_relax_frag (fix_insts, fix_num, var_insts, var_num, add_symbol);
4240
4241 /* Insn 3 */
4242 fix_num = 1;
4243 var_num = 1;
4244 /* Fix part
4245 For an external symbol: ori r1, LO%<constant> */
4246 sprintf (tmp, "ori %s, %d", "r1", lo);
4247 if (append_insn (tmp, FALSE) == (int) FAIL)
4248 return;
4249
4250 memcpy (&fix_insts[0], &inst, sizeof (struct score_it));
4251
4252 /* Var part
4253 For a local symbol: addi r1, <sym>+LO%<constant> (BFD_RELOC_GOT_LO16) */
4254 sprintf (tmp, "addi_u_pic %s, %s + %d", "r1", add_symbol->bsym->name, lo);
4255 if (append_insn (tmp, FALSE) == (int) FAIL)
4256 return;
4257
4258 memcpy (&var_insts[0], &inst, sizeof (struct score_it));
4259 build_relax_frag (fix_insts, fix_num, var_insts, var_num, add_symbol);
4260
4261 /* Insn 4: add rD, rD, r1 */
4262 sprintf (tmp, "add r%d, r%d, %s", reg_rd, reg_rd, "r1");
4263 if (append_insn (tmp, TRUE) == (int) FAIL)
4264 return;
4265
4266 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4267 inst.bwarn = -1;
4268
4269 /* Insn 5: lw rD, [rD, 0] */
4270 sprintf (tmp, "lw r%d, [r%d, 0]", reg_rd, reg_rd);
4271 if (append_insn (tmp, TRUE) == (int) FAIL)
4272 return;
4273
4274 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4275 inst.bwarn = -1;
4276 }
4277
4278 nor1 = r1_bak;
4279 }
4280
4281 static void
4282 do_macro_ldst_label (char *str)
4283 {
4284 int i;
4285 int ldst_gp_p = 0;
4286 int reg_rd;
4287 int r1_bak;
4288 char *backup_str;
4289 char *label_str;
4290 char *absolute_value;
4291 char append_str[3][MAX_LITERAL_POOL_SIZE];
4292 char verifystr[MAX_LITERAL_POOL_SIZE];
4293 struct score_it inst_backup;
4294 struct score_it inst_expand[3];
4295 struct score_it inst_main;
4296
4297 memcpy (&inst_backup, &inst, sizeof (struct score_it));
4298 strcpy (verifystr, str);
4299 backup_str = verifystr;
4300
4301 skip_whitespace (backup_str);
4302 if ((reg_rd = reg_required_here (&backup_str, -1, REG_TYPE_SCORE)) == (int) FAIL)
4303 return;
4304
4305 if (skip_past_comma (&backup_str) == (int) FAIL)
4306 return;
4307
4308 label_str = backup_str;
4309
4310 /* Ld/st rD, [rA, imm] ld/st rD, [rA]+, imm ld/st rD, [rA, imm]+. */
4311 if (*backup_str == '[')
4312 {
4313 inst.type = Rd_rvalueRs_preSI12;
4314 do_ldst_insn (str);
4315 return;
4316 }
4317
4318 /* Ld/st rD, imm. */
4319 absolute_value = backup_str;
4320 inst.type = Rd_rvalueRs_SI15;
4321 if ((my_get_expression (&inst.reloc.exp, &backup_str) == (int) FAIL)
4322 || (validate_immediate (inst.reloc.exp.X_add_number, _VALUE) == (int) FAIL)
4323 || (end_of_line (backup_str) == (int) FAIL))
4324 {
4325 return;
4326 }
4327 else
4328 {
4329 if (inst.reloc.exp.X_add_symbol == 0)
4330 {
4331 memcpy (&inst, &inst_backup, sizeof (struct score_it));
4332 exp_macro_ldst_abs (str);
4333 return;
4334 }
4335 }
4336
4337 /* Ld/st rD, label. */
4338 inst.type = Rd_rvalueRs_SI15;
4339 backup_str = absolute_value;
4340 if ((data_op2 (&backup_str, 1, _GP_IMM15) == (int) FAIL)
4341 || (end_of_line (backup_str) == (int) FAIL))
4342 {
4343 return;
4344 }
4345 else
4346 {
4347 if (inst.reloc.exp.X_add_symbol == 0)
4348 {
4349 if (!inst.error)
4350 inst.error = BAD_ARGS;
4351
4352 return;
4353 }
4354
4355 if (score_pic == PIC)
4356 {
4357 build_lw_pic (reg_rd, inst.reloc.exp);
4358 return;
4359 }
4360 else
4361 {
4362 if ((inst.reloc.exp.X_add_number <= 0x3fff)
4363 && (inst.reloc.exp.X_add_number >= -0x4000)
4364 && (!nopic_need_relax (inst.reloc.exp.X_add_symbol, 1)))
4365 {
4366 int ldst_idx = 0;
4367
4368 /* Assign the real opcode. */
4369 ldst_idx = inst.instruction & OPC_PSEUDOLDST_MASK;
4370 inst.instruction &= ~OPC_PSEUDOLDST_MASK;
4371 inst.instruction |= score_ldst_insns[ldst_idx * 3 + 0].value;
4372 inst.instruction |= reg_rd << 20;
4373 inst.instruction |= GP << 15;
4374 inst.relax_inst = 0x8000;
4375 inst.relax_size = 0;
4376 ldst_gp_p = 1;
4377 }
4378 }
4379 }
4380
4381 /* Backup inst. */
4382 memcpy (&inst_main, &inst, sizeof (struct score_it));
4383 r1_bak = nor1;
4384 nor1 = 0;
4385
4386 /* Determine which instructions should be output. */
4387 sprintf (append_str[0], "ld_i32hi r1, %s", label_str);
4388 sprintf (append_str[1], "ld_i32lo r1, %s", label_str);
4389 sprintf (append_str[2], "%s r%d, [r1, 0]", inst_backup.name, reg_rd);
4390
4391 /* Generate three instructions.
4392 la r1, label
4393 ld/st rd, [r1, 0] */
4394 for (i = 0; i < 3; i++)
4395 {
4396 if (append_insn (append_str[i], FALSE) == (int) FAIL)
4397 return;
4398
4399 memcpy (&inst_expand[i], &inst, sizeof (struct score_it));
4400 }
4401
4402 if (ldst_gp_p)
4403 {
4404 char *p;
4405
4406 /* Adjust instruction opcode and to be relaxed instruction opcode. */
4407 inst_main.instruction = adjust_paritybit (inst_main.instruction, GET_INSN_CLASS (inst_main.type));
4408 inst_main.relax_size = inst_expand[0].size + inst_expand[1].size + inst_expand[2].size;
4409 inst_main.type = Insn_GP;
4410
4411 for (i = 0; i < 3; i++)
4412 inst_expand[i].instruction = adjust_paritybit (inst_expand[i].instruction
4413 , GET_INSN_CLASS (inst_expand[i].type));
4414
4415 /* Check data dependency. */
4416 handle_dependency (&inst_main);
4417
4418 /* Start a new frag if frag_now is not empty. */
4419 if (frag_now_fix () != 0)
4420 {
4421 if (!frag_now->tc_frag_data.is_insn)
4422 frag_wane (frag_now);
4423
4424 frag_new (0);
4425 }
4426 frag_grow (20);
4427
4428 /* Write fr_fix part. */
4429 p = frag_more (inst_main.size);
4430 md_number_to_chars (p, inst_main.instruction, inst_main.size);
4431
4432 if (inst_main.reloc.type != BFD_RELOC_NONE)
4433 {
4434 fix_new_score (frag_now, p - frag_now->fr_literal, inst_main.size,
4435 &inst_main.reloc.exp, inst_main.reloc.pc_rel, inst_main.reloc.type);
4436 }
4437
4438 #ifdef OBJ_ELF
4439 dwarf2_emit_insn (inst_main.size);
4440 #endif
4441
4442 /* GP instruction can not do optimization, only can do relax between
4443 1 instruction and 3 instructions. */
4444 p = frag_var (rs_machine_dependent, inst_main.relax_size + RELAX_PAD_BYTE, 0,
4445 RELAX_ENCODE (inst_main.size, inst_main.relax_size, inst_main.type, 0, 4, 0),
4446 inst_main.reloc.exp.X_add_symbol, 0, NULL);
4447
4448 /* Write fr_var part.
4449 no calling gen_insn_frag, no fixS will be generated. */
4450 md_number_to_chars (p, inst_expand[0].instruction, inst_expand[0].size);
4451 p += inst_expand[0].size;
4452 md_number_to_chars (p, inst_expand[1].instruction, inst_expand[1].size);
4453 p += inst_expand[1].size;
4454 md_number_to_chars (p, inst_expand[2].instruction, inst_expand[2].size);
4455 }
4456 else
4457 {
4458 gen_insn_frag (&inst_expand[0], NULL);
4459 gen_insn_frag (&inst_expand[1], NULL);
4460 gen_insn_frag (&inst_expand[2], NULL);
4461 }
4462 nor1 = r1_bak;
4463
4464 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4465 inst.bwarn = -1;
4466 }
4467
4468 static void
4469 do_lw_pic (char *str)
4470 {
4471 int reg_rd;
4472
4473 skip_whitespace (str);
4474 if (((reg_rd = reg_required_here (&str, 20, REG_TYPE_SCORE)) == (int) FAIL)
4475 || (skip_past_comma (&str) == (int) FAIL)
4476 || (my_get_expression (&inst.reloc.exp, &str) == (int) FAIL)
4477 || (end_of_line (str) == (int) FAIL))
4478 {
4479 return;
4480 }
4481 else
4482 {
4483 if (inst.reloc.exp.X_add_symbol == 0)
4484 {
4485 if (!inst.error)
4486 inst.error = BAD_ARGS;
4487
4488 return;
4489 }
4490
4491 inst.instruction |= GP << 15;
4492 inst.reloc.type = BFD_RELOC_SCORE_GOT15;
4493 }
4494 }
4495
4496 static void
4497 do_empty (char *str)
4498 {
4499 str = str;
4500 if (university_version == 1)
4501 {
4502 if (((inst.instruction & 0x3e0003ff) == 0x0c000004)
4503 || ((inst.instruction & 0x3e0003ff) == 0x0c000024)
4504 || ((inst.instruction & 0x3e0003ff) == 0x0c000044)
4505 || ((inst.instruction & 0x3e0003ff) == 0x0c000064))
4506 {
4507 inst.error = ERR_FOR_SCORE5U_MMU;
4508 return;
4509 }
4510 }
4511 if (end_of_line (str) == (int) FAIL)
4512 return;
4513
4514 if (inst.relax_inst != 0x8000)
4515 {
4516 if (inst.type == NO_OPD)
4517 {
4518 inst.relax_size = 2;
4519 }
4520 else
4521 {
4522 inst.relax_size = 4;
4523 }
4524 }
4525 }
4526
4527 static void
4528 do_jump (char *str)
4529 {
4530 char *save_in;
4531 char err_msg[100];
4532
4533 skip_whitespace (str);
4534 if (my_get_expression (&inst.reloc.exp, &str) == (int) FAIL
4535 || end_of_line (str) == (int) FAIL)
4536 return;
4537
4538 if (inst.reloc.exp.X_add_symbol == 0)
4539 {
4540 inst.error = _("lacking label ");
4541 return;
4542 }
4543
4544 if (((inst.reloc.exp.X_add_number & 0xff000000) != 0)
4545 && ((inst.reloc.exp.X_add_number & 0xff000000) != 0xff000000))
4546 {
4547 sprintf (err_msg, "invalid constant: 25 bit expression not in range -2^24..2^24");
4548 inst.error = _(err_msg);
4549 return;
4550 }
4551
4552 save_in = input_line_pointer;
4553 input_line_pointer = str;
4554 inst.reloc.type = BFD_RELOC_SCORE_JMP;
4555 inst.reloc.pc_rel = 1;
4556 input_line_pointer = save_in;
4557 }
4558
4559 static void
4560 do16_jump (char *str)
4561 {
4562 skip_whitespace (str);
4563 if (my_get_expression (&inst.reloc.exp, &str) == (int) FAIL
4564 || end_of_line (str) == (int) FAIL)
4565 {
4566 return;
4567 }
4568 else if (inst.reloc.exp.X_add_symbol == 0)
4569 {
4570 inst.error = _("lacking label ");
4571 return;
4572 }
4573 else if (((inst.reloc.exp.X_add_number & 0xfffff800) != 0)
4574 && ((inst.reloc.exp.X_add_number & 0xfffff800) != 0xfffff800))
4575 {
4576 inst.error = _("invalid constant: 12 bit expression not in range -2^11..2^11");
4577 return;
4578 }
4579
4580 inst.reloc.type = BFD_RELOC_SCORE16_JMP;
4581 inst.reloc.pc_rel = 1;
4582 }
4583
4584 static void
4585 do_branch (char *str)
4586 {
4587 unsigned long abs_value = 0;
4588
4589 if (my_get_expression (&inst.reloc.exp, &str) == (int) FAIL
4590 || end_of_line (str) == (int) FAIL)
4591 {
4592 return;
4593 }
4594 else if (inst.reloc.exp.X_add_symbol == 0)
4595 {
4596 inst.error = _("lacking label ");
4597 return;
4598 }
4599 else if (((inst.reloc.exp.X_add_number & 0xff000000) != 0)
4600 && ((inst.reloc.exp.X_add_number & 0xff000000) != 0xff000000))
4601 {
4602 inst.error = "invalid constant: 20 bit expression not in range -2^19..2^19";
4603 return;
4604 }
4605
4606 inst.reloc.type = BFD_RELOC_SCORE_BRANCH;
4607 inst.reloc.pc_rel = 1;
4608
4609 /* Branch 32 offset field : 20 bit, 16 bit branch offset field : 8 bit. */
4610 inst.instruction |= (inst.reloc.exp.X_add_number & 0x3fe) | ((inst.reloc.exp.X_add_number & 0xffc00) << 5);
4611
4612 /* Take the branch condition code. */
4613 inst.relax_inst = 0x4000 | (((inst.instruction >> 10) & 0xf) << 8);
4614
4615 if ((abs_value & 0xfffffe00) == 0)
4616 {
4617 inst.relax_inst |= ((inst.reloc.exp.X_add_number >> 1) & 0xff);
4618 inst.relax_size = 2;
4619 }
4620 else
4621 {
4622 inst.relax_inst = 0x8000;
4623 }
4624
4625 if (inst.instruction & 1)
4626 inst.relax_inst = 0x8000;
4627 }
4628
4629 static void
4630 do16_branch (char *str)
4631 {
4632 if ((my_get_expression (&inst.reloc.exp, &str) == (int) FAIL
4633 || end_of_line (str) == (int) FAIL))
4634 {
4635 ;
4636 }
4637 else if (inst.reloc.exp.X_add_symbol == 0)
4638 {
4639 inst.error = _("lacking label");
4640 }
4641 else if (((inst.reloc.exp.X_add_number & 0xffffff00) != 0)
4642 && ((inst.reloc.exp.X_add_number & 0xffffff00) != 0xffffff00))
4643 {
4644 inst.error = _("invalid constant: 9 bit expression not in range -2^8..2^8");
4645 }
4646 else
4647 {
4648 inst.reloc.type = BFD_RELOC_SCORE16_BRANCH;
4649 inst.reloc.pc_rel = 1;
4650 inst.instruction |= ((inst.reloc.exp.X_add_number >> 1) & 0xff);
4651 }
4652 }
4653
4654 /* Iterate over the base tables to create the instruction patterns. */
4655 static void
4656 build_score_ops_hsh (void)
4657 {
4658 unsigned int i;
4659 static struct obstack insn_obstack;
4660
4661 obstack_begin (&insn_obstack, 4000);
4662 for (i = 0; i < sizeof (score_insns) / sizeof (struct asm_opcode); i++)
4663 {
4664 const struct asm_opcode *insn = score_insns + i;
4665 unsigned len = strlen (insn->template);
4666 struct asm_opcode *new;
4667 char *template;
4668 new = obstack_alloc (&insn_obstack, sizeof (struct asm_opcode));
4669 template = obstack_alloc (&insn_obstack, len + 1);
4670
4671 strcpy (template, insn->template);
4672 new->template = template;
4673 new->parms = insn->parms;
4674 new->value = insn->value;
4675 new->relax_value = insn->relax_value;
4676 new->type = insn->type;
4677 new->bitmask = insn->bitmask;
4678 hash_insert (score_ops_hsh, new->template, (void *) new);
4679 }
4680 }
4681
4682 static void
4683 build_dependency_insn_hsh (void)
4684 {
4685 unsigned int i;
4686 static struct obstack dependency_obstack;
4687
4688 obstack_begin (&dependency_obstack, 4000);
4689 for (i = 0; i < sizeof (insn_to_dependency_table) / sizeof (insn_to_dependency_table[0]); i++)
4690 {
4691 const struct insn_to_dependency *tmp = insn_to_dependency_table + i;
4692 unsigned len = strlen (tmp->insn_name);
4693 struct insn_to_dependency *new;
4694
4695 new = obstack_alloc (&dependency_obstack, sizeof (struct insn_to_dependency));
4696 new->insn_name = obstack_alloc (&dependency_obstack, len + 1);
4697
4698 strcpy (new->insn_name, tmp->insn_name);
4699 new->type = tmp->type;
4700 hash_insert (dependency_insn_hsh, new->insn_name, (void *) new);
4701 }
4702 }
4703
4704 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
4705 for use in the a.out file, and stores them in the array pointed to by buf.
4706 This knows about the endian-ness of the target machine and does
4707 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
4708 2 (short) and 4 (long) Floating numbers are put out as a series of
4709 LITTLENUMS (shorts, here at least). */
4710
4711 void
4712 md_number_to_chars (char *buf, valueT val, int n)
4713 {
4714 if (target_big_endian)
4715 number_to_chars_bigendian (buf, val, n);
4716 else
4717 number_to_chars_littleendian (buf, val, n);
4718 }
4719
4720 static valueT
4721 md_chars_to_number (char *buf, int n)
4722 {
4723 valueT result = 0;
4724 unsigned char *where = (unsigned char *)buf;
4725
4726 if (target_big_endian)
4727 {
4728 while (n--)
4729 {
4730 result <<= 8;
4731 result |= (*where++ & 255);
4732 }
4733 }
4734 else
4735 {
4736 while (n--)
4737 {
4738 result <<= 8;
4739 result |= (where[n] & 255);
4740 }
4741 }
4742
4743 return result;
4744 }
4745
4746 /* Turn a string in input_line_pointer into a floating point constant
4747 of type TYPE, and store the appropriate bytes in *LITP. The number
4748 of LITTLENUMS emitted is stored in *SIZEP. An error message is
4749 returned, or NULL on OK.
4750
4751 Note that fp constants aren't represent in the normal way on the ARM.
4752 In big endian mode, things are as expected. However, in little endian
4753 mode fp constants are big-endian word-wise, and little-endian byte-wise
4754 within the words. For example, (double) 1.1 in big endian mode is
4755 the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
4756 the byte sequence 99 99 f1 3f 9a 99 99 99. */
4757
4758 char *
4759 md_atof (int type, char *litP, int *sizeP)
4760 {
4761 int prec;
4762 LITTLENUM_TYPE words[MAX_LITTLENUMS];
4763 char *t;
4764 int i;
4765
4766 switch (type)
4767 {
4768 case 'f':
4769 case 'F':
4770 case 's':
4771 case 'S':
4772 prec = 2;
4773 break;
4774 case 'd':
4775 case 'D':
4776 case 'r':
4777 case 'R':
4778 prec = 4;
4779 break;
4780 case 'x':
4781 case 'X':
4782 case 'p':
4783 case 'P':
4784 prec = 6;
4785 break;
4786 default:
4787 *sizeP = 0;
4788 return _("bad call to MD_ATOF()");
4789 }
4790
4791 t = atof_ieee (input_line_pointer, type, words);
4792 if (t)
4793 input_line_pointer = t;
4794 *sizeP = prec * 2;
4795
4796 if (target_big_endian)
4797 {
4798 for (i = 0; i < prec; i++)
4799 {
4800 md_number_to_chars (litP, (valueT) words[i], 2);
4801 litP += 2;
4802 }
4803 }
4804 else
4805 {
4806 for (i = 0; i < prec; i += 2)
4807 {
4808 md_number_to_chars (litP, (valueT) words[i + 1], 2);
4809 md_number_to_chars (litP + 2, (valueT) words[i], 2);
4810 litP += 4;
4811 }
4812 }
4813
4814 return 0;
4815 }
4816
4817 /* Return true if the given symbol should be considered local for PIC. */
4818
4819 static bfd_boolean
4820 pic_need_relax (symbolS *sym, asection *segtype)
4821 {
4822 asection *symsec;
4823 bfd_boolean linkonce;
4824
4825 /* Handle the case of a symbol equated to another symbol. */
4826 while (symbol_equated_reloc_p (sym))
4827 {
4828 symbolS *n;
4829
4830 /* It's possible to get a loop here in a badly written
4831 program. */
4832 n = symbol_get_value_expression (sym)->X_add_symbol;
4833 if (n == sym)
4834 break;
4835 sym = n;
4836 }
4837
4838 symsec = S_GET_SEGMENT (sym);
4839
4840 /* duplicate the test for LINK_ONCE sections as in adjust_reloc_syms */
4841 linkonce = FALSE;
4842 if (symsec != segtype && ! S_IS_LOCAL (sym))
4843 {
4844 if ((bfd_get_section_flags (stdoutput, symsec) & SEC_LINK_ONCE) != 0)
4845 linkonce = TRUE;
4846
4847 /* The GNU toolchain uses an extension for ELF: a section
4848 beginning with the magic string .gnu.linkonce is a linkonce
4849 section. */
4850 if (strncmp (segment_name (symsec), ".gnu.linkonce",
4851 sizeof ".gnu.linkonce" - 1) == 0)
4852 linkonce = TRUE;
4853 }
4854
4855 /* This must duplicate the test in adjust_reloc_syms. */
4856 return (symsec != &bfd_und_section
4857 && symsec != &bfd_abs_section
4858 && ! bfd_is_com_section (symsec)
4859 && !linkonce
4860 #ifdef OBJ_ELF
4861 /* A global or weak symbol is treated as external. */
4862 && (OUTPUT_FLAVOR != bfd_target_elf_flavour
4863 || (! S_IS_WEAK (sym) && ! S_IS_EXTERNAL (sym)))
4864 #endif
4865 );
4866 }
4867
4868 static int
4869 judge_size_before_relax (fragS * fragp, asection *sec)
4870 {
4871 int change = 0;
4872
4873 if (score_pic == NO_PIC)
4874 change = nopic_need_relax (fragp->fr_symbol, 0);
4875 else
4876 change = pic_need_relax (fragp->fr_symbol, sec);
4877
4878 if (change == 1)
4879 {
4880 /* Only at the first time determining whether GP instruction relax should be done,
4881 return the difference between insntruction size and instruction relax size. */
4882 if (fragp->fr_opcode == NULL)
4883 {
4884 fragp->fr_fix = RELAX_NEW (fragp->fr_subtype);
4885 fragp->fr_opcode = fragp->fr_literal + RELAX_RELOC1 (fragp->fr_subtype);
4886 return RELAX_NEW (fragp->fr_subtype) - RELAX_OLD (fragp->fr_subtype);
4887 }
4888 }
4889
4890 return 0;
4891 }
4892
4893 /* In this function, we determine whether GP instruction should do relaxation,
4894 for the label being against was known now.
4895 Doing this here but not in md_relax_frag() can induce iteration times
4896 in stage of doing relax. */
4897 int
4898 md_estimate_size_before_relax (fragS * fragp, asection * sec ATTRIBUTE_UNUSED)
4899 {
4900 if ((RELAX_TYPE (fragp->fr_subtype) == Insn_GP)
4901 || (RELAX_TYPE (fragp->fr_subtype) == Insn_PIC))
4902 return judge_size_before_relax (fragp, sec);
4903
4904 return 0;
4905 }
4906
4907 static int
4908 b32_relax_to_b16 (fragS * fragp)
4909 {
4910 int grows = 0;
4911 int relaxable_p = 0;
4912 int old;
4913 int new;
4914 int frag_addr = fragp->fr_address + fragp->insn_addr;
4915
4916 addressT symbol_address = 0;
4917 symbolS *s;
4918 offsetT offset;
4919 unsigned long value;
4920 unsigned long abs_value;
4921
4922 /* FIXME : here may be able to modify better .
4923 I don't know how to get the fragp's section ,
4924 so in relax stage , it may be wrong to calculate the symbol's offset when the frag's section
4925 is different from the symbol's. */
4926
4927 old = RELAX_OLD (fragp->fr_subtype);
4928 new = RELAX_NEW (fragp->fr_subtype);
4929 relaxable_p = RELAX_OPT (fragp->fr_subtype);
4930
4931 s = fragp->fr_symbol;
4932 /* b/bl immediate */
4933 if (s == NULL)
4934 frag_addr = 0;
4935 else
4936 {
4937 if (s->bsym != 0)
4938 symbol_address = (addressT) s->sy_frag->fr_address;
4939 }
4940
4941 value = md_chars_to_number (fragp->fr_literal, INSN_SIZE);
4942
4943 /* b 32's offset : 20 bit, b 16's tolerate field : 0xff. */
4944 offset = ((value & 0x3ff0000) >> 6) | (value & 0x3fe);
4945 if ((offset & 0x80000) == 0x80000)
4946 offset |= 0xfff00000;
4947
4948 abs_value = offset + symbol_address - frag_addr;
4949 if ((abs_value & 0x80000000) == 0x80000000)
4950 abs_value = 0xffffffff - abs_value + 1;
4951
4952 /* Relax branch 32 to branch 16. */
4953 if (relaxable_p && (s->bsym != NULL) && ((abs_value & 0xffffff00) == 0)
4954 && (S_IS_DEFINED (s) && !S_IS_COMMON (s) && !S_IS_EXTERNAL (s)))
4955 {
4956 /* do nothing. */
4957 }
4958 else
4959 {
4960 /* Branch 32 can not be relaxed to b 16, so clear OPT bit. */
4961 fragp->fr_opcode = NULL;
4962 fragp->fr_subtype = RELAX_OPT_CLEAR (fragp->fr_subtype);
4963 }
4964
4965 return grows;
4966 }
4967
4968 /* Main purpose is to determine whether one frag should do relax.
4969 frag->fr_opcode indicates this point. */
4970
4971 int
4972 score_relax_frag (asection * sec ATTRIBUTE_UNUSED, fragS * fragp, long stretch ATTRIBUTE_UNUSED)
4973 {
4974 int grows = 0;
4975 int insn_size;
4976 int insn_relax_size;
4977 int do_relax_p = 0; /* Indicate doing relaxation for this frag. */
4978 int relaxable_p = 0;
4979 bfd_boolean word_align_p = FALSE;
4980 fragS *next_fragp;
4981
4982 /* If the instruction address is odd, make it half word align first. */
4983 if ((fragp->fr_address) % 2 != 0)
4984 {
4985 if ((fragp->fr_address + fragp->insn_addr) % 2 != 0)
4986 {
4987 fragp->insn_addr = 1;
4988 grows += 1;
4989 }
4990 }
4991
4992 word_align_p = ((fragp->fr_address + fragp->insn_addr) % 4 == 0) ? TRUE : FALSE;
4993
4994 /* Get instruction size and relax size after the last relaxation. */
4995 if (fragp->fr_opcode)
4996 {
4997 insn_size = RELAX_NEW (fragp->fr_subtype);
4998 insn_relax_size = RELAX_OLD (fragp->fr_subtype);
4999 }
5000 else
5001 {
5002 insn_size = RELAX_OLD (fragp->fr_subtype);
5003 insn_relax_size = RELAX_NEW (fragp->fr_subtype);
5004 }
5005
5006 /* Handle specially for GP instruction. for, judge_size_before_relax() has already determine
5007 whether the GP instruction should do relax. */
5008 if ((RELAX_TYPE (fragp->fr_subtype) == Insn_GP)
5009 || (RELAX_TYPE (fragp->fr_subtype) == Insn_PIC))
5010 {
5011 if (!word_align_p)
5012 {
5013 fragp->insn_addr += 2;
5014 grows += 2;
5015 }
5016
5017 if (fragp->fr_opcode)
5018 fragp->fr_fix = RELAX_NEW (fragp->fr_subtype) + fragp->insn_addr;
5019 else
5020 fragp->fr_fix = RELAX_OLD (fragp->fr_subtype) + fragp->insn_addr;
5021 }
5022 else
5023 {
5024 if (RELAX_TYPE (fragp->fr_subtype) == PC_DISP19div2)
5025 b32_relax_to_b16 (fragp);
5026
5027 relaxable_p = RELAX_OPT (fragp->fr_subtype);
5028 next_fragp = fragp->fr_next;
5029 while ((next_fragp) && (next_fragp->fr_type != rs_machine_dependent))
5030 {
5031 next_fragp = next_fragp->fr_next;
5032 }
5033
5034 if (next_fragp)
5035 {
5036 int n_insn_size;
5037 int n_relaxable_p = 0;
5038
5039 if (next_fragp->fr_opcode)
5040 {
5041 n_insn_size = RELAX_NEW (next_fragp->fr_subtype);
5042 }
5043 else
5044 {
5045 n_insn_size = RELAX_OLD (next_fragp->fr_subtype);
5046 }
5047
5048 n_relaxable_p = RELAX_OPT (next_fragp->fr_subtype);
5049
5050 if (word_align_p)
5051 {
5052 if (insn_size == 4)
5053 {
5054 /* 32 -> 16. */
5055 if (relaxable_p && ((n_insn_size == 2) || n_relaxable_p))
5056 {
5057 grows -= 2;
5058 do_relax_p = 1;
5059 }
5060 }
5061 else if (insn_size == 2)
5062 {
5063 /* 16 -> 32. */
5064 if (relaxable_p && ((n_insn_size == 4) && !n_relaxable_p))
5065 {
5066 grows += 2;
5067 do_relax_p = 1;
5068 }
5069 }
5070 else
5071 {
5072 abort ();
5073 }
5074 }
5075 else
5076 {
5077 if (insn_size == 4)
5078 {
5079 /* 32 -> 16. */
5080 if (relaxable_p)
5081 {
5082 grows -= 2;
5083 do_relax_p = 1;
5084 }
5085 /* Make the 32 bit insturction word align. */
5086 else
5087 {
5088 fragp->insn_addr += 2;
5089 grows += 2;
5090 }
5091 }
5092 else if (insn_size == 2)
5093 {
5094 /* Do nothing. */
5095 }
5096 else
5097 {
5098 abort ();
5099 }
5100 }
5101 }
5102 else
5103 {
5104 /* Here, try best to do relax regardless fragp->fr_next->fr_type. */
5105 if (word_align_p == FALSE)
5106 {
5107 if (insn_size % 4 == 0)
5108 {
5109 /* 32 -> 16. */
5110 if (relaxable_p)
5111 {
5112 grows -= 2;
5113 do_relax_p = 1;
5114 }
5115 else
5116 {
5117 fragp->insn_addr += 2;
5118 grows += 2;
5119 }
5120 }
5121 }
5122 else
5123 {
5124 /* Do nothing. */
5125 }
5126 }
5127
5128 /* fragp->fr_opcode indicates whether this frag should be relaxed. */
5129 if (do_relax_p)
5130 {
5131 if (fragp->fr_opcode)
5132 {
5133 fragp->fr_opcode = NULL;
5134 /* Guarantee estimate stage is correct. */
5135 fragp->fr_fix = RELAX_OLD (fragp->fr_subtype);
5136 fragp->fr_fix += fragp->insn_addr;
5137 }
5138 else
5139 {
5140 fragp->fr_opcode = fragp->fr_literal + RELAX_RELOC1 (fragp->fr_subtype);
5141 /* Guarantee estimate stage is correct. */
5142 fragp->fr_fix = RELAX_NEW (fragp->fr_subtype);
5143 fragp->fr_fix += fragp->insn_addr;
5144 }
5145 }
5146 else
5147 {
5148 if (fragp->fr_opcode)
5149 {
5150 /* Guarantee estimate stage is correct. */
5151 fragp->fr_fix = RELAX_NEW (fragp->fr_subtype);
5152 fragp->fr_fix += fragp->insn_addr;
5153 }
5154 else
5155 {
5156 /* Guarantee estimate stage is correct. */
5157 fragp->fr_fix = RELAX_OLD (fragp->fr_subtype);
5158 fragp->fr_fix += fragp->insn_addr;
5159 }
5160 }
5161 }
5162
5163 return grows;
5164 }
5165
5166 void
5167 md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED, segT sec ATTRIBUTE_UNUSED, fragS * fragp)
5168 {
5169 int old;
5170 int new;
5171 char backup[20];
5172 fixS *fixp;
5173
5174 old = RELAX_OLD (fragp->fr_subtype);
5175 new = RELAX_NEW (fragp->fr_subtype);
5176
5177 /* fragp->fr_opcode indicates whether this frag should be relaxed. */
5178 if (fragp->fr_opcode == NULL)
5179 {
5180 memcpy (backup, fragp->fr_literal, old);
5181 fragp->fr_fix = old;
5182 }
5183 else
5184 {
5185 memcpy (backup, fragp->fr_literal + old, new);
5186 fragp->fr_fix = new;
5187 }
5188
5189 fixp = fragp->tc_frag_data.fixp;
5190 while (fixp && fixp->fx_frag == fragp && fixp->fx_where < old)
5191 {
5192 if (fragp->fr_opcode)
5193 fixp->fx_done = 1;
5194 fixp = fixp->fx_next;
5195 }
5196 while (fixp && fixp->fx_frag == fragp)
5197 {
5198 if (fragp->fr_opcode)
5199 fixp->fx_where -= old + fragp->insn_addr;
5200 else
5201 fixp->fx_done = 1;
5202 fixp = fixp->fx_next;
5203 }
5204
5205 if (fragp->insn_addr)
5206 {
5207 md_number_to_chars (fragp->fr_literal, 0x0, fragp->insn_addr);
5208 }
5209 memcpy (fragp->fr_literal + fragp->insn_addr, backup, fragp->fr_fix);
5210 fragp->fr_fix += fragp->insn_addr;
5211 }
5212
5213 /* Implementation of md_frag_check.
5214 Called after md_convert_frag(). */
5215
5216 void
5217 score_frag_check (fragS * fragp ATTRIBUTE_UNUSED)
5218 {
5219 know (fragp->insn_addr <= RELAX_PAD_BYTE);
5220 }
5221
5222 bfd_boolean
5223 score_fix_adjustable (fixS * fixP)
5224 {
5225 if (fixP->fx_addsy == NULL)
5226 {
5227 return 1;
5228 }
5229 else if (OUTPUT_FLAVOR == bfd_target_elf_flavour
5230 && (S_IS_EXTERNAL (fixP->fx_addsy) || S_IS_WEAK (fixP->fx_addsy)))
5231 {
5232 return 0;
5233 }
5234 else if (fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
5235 || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
5236 {
5237 return 0;
5238 }
5239
5240 return 1;
5241 }
5242
5243 /* Implementation of TC_VALIDATE_FIX.
5244 Called before md_apply_fix() and after md_convert_frag(). */
5245 void
5246 score_validate_fix (fixS *fixP)
5247 {
5248 fixP->fx_where += fixP->fx_frag->insn_addr;
5249 }
5250
5251 long
5252 md_pcrel_from (fixS * fixP)
5253 {
5254 long retval = 0;
5255
5256 if (fixP->fx_addsy
5257 && (S_GET_SEGMENT (fixP->fx_addsy) == undefined_section)
5258 && (fixP->fx_subsy == NULL))
5259 {
5260 retval = 0;
5261 }
5262 else
5263 {
5264 retval = fixP->fx_where + fixP->fx_frag->fr_address;
5265 }
5266
5267 return retval;
5268 }
5269
5270 int
5271 score_force_relocation (struct fix *fixp)
5272 {
5273 int retval = 0;
5274
5275 if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
5276 || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY
5277 || fixp->fx_r_type == BFD_RELOC_SCORE_JMP
5278 || fixp->fx_r_type == BFD_RELOC_SCORE_BRANCH
5279 || fixp->fx_r_type == BFD_RELOC_SCORE16_JMP
5280 || fixp->fx_r_type == BFD_RELOC_SCORE16_BRANCH)
5281 {
5282 retval = 1;
5283 }
5284
5285 return retval;
5286 }
5287
5288 /* Round up a section size to the appropriate boundary. */
5289 valueT
5290 md_section_align (segT segment ATTRIBUTE_UNUSED, valueT size)
5291 {
5292 int align = bfd_get_section_alignment (stdoutput, segment);
5293
5294 #ifdef OBJ_ELF
5295 /* We don't need to align ELF sections to the full alignment.
5296 However, Irix 5 may prefer that we align them at least to a 16
5297 byte boundary. We don't bother to align the sections if we are
5298 targeted for an embedded system. */
5299 if (strcmp (TARGET_OS, "elf") == 0)
5300 return size;
5301 if (align > 4)
5302 align = 4;
5303 #endif
5304
5305 return ((size + (1 << align) - 1) & (-1 << align));
5306 }
5307
5308 void
5309 md_apply_fix (fixS *fixP, valueT *valP, segT seg)
5310 {
5311 offsetT value = *valP;
5312 offsetT abs_value = 0;
5313 offsetT newval;
5314 offsetT content;
5315 unsigned short HI, LO;
5316
5317 char *buf = fixP->fx_frag->fr_literal + fixP->fx_where;
5318
5319 assert (fixP->fx_r_type < BFD_RELOC_UNUSED);
5320 if (fixP->fx_addsy == 0 && !fixP->fx_pcrel)
5321 {
5322 if (fixP->fx_r_type != BFD_RELOC_SCORE_DUMMY_HI16)
5323 fixP->fx_done = 1;
5324 }
5325
5326 /* If this symbol is in a different section then we need to leave it for
5327 the linker to deal with. Unfortunately, md_pcrel_from can't tell,
5328 so we have to undo it's effects here. */
5329 if (fixP->fx_pcrel)
5330 {
5331 if (fixP->fx_addsy != NULL
5332 && S_IS_DEFINED (fixP->fx_addsy)
5333 && S_GET_SEGMENT (fixP->fx_addsy) != seg)
5334 value += md_pcrel_from (fixP);
5335 }
5336
5337 /* Remember value for emit_reloc. */
5338 fixP->fx_addnumber = value;
5339
5340 switch (fixP->fx_r_type)
5341 {
5342 case BFD_RELOC_HI16_S:
5343 if (fixP->fx_done)
5344 { /* For la rd, imm32. */
5345 newval = md_chars_to_number (buf, INSN_SIZE);
5346 HI = (value) >> 16; /* mul to 2, then take the hi 16 bit. */
5347 newval |= (HI & 0x3fff) << 1;
5348 newval |= ((HI >> 14) & 0x3) << 16;
5349 md_number_to_chars (buf, newval, INSN_SIZE);
5350 }
5351 break;
5352 case BFD_RELOC_LO16:
5353 if (fixP->fx_done) /* For la rd, imm32. */
5354 {
5355 newval = md_chars_to_number (buf, INSN_SIZE);
5356 LO = (value) & 0xffff;
5357 newval |= (LO & 0x3fff) << 1; /* 16 bit: imm -> 14 bit in lo, 2 bit in hi. */
5358 newval |= ((LO >> 14) & 0x3) << 16;
5359 md_number_to_chars (buf, newval, INSN_SIZE);
5360 }
5361 break;
5362 case BFD_RELOC_SCORE_JMP:
5363 {
5364 content = md_chars_to_number (buf, INSN_SIZE);
5365 value = fixP->fx_offset;
5366 content = (content & ~0x3ff7ffe) | ((value << 1) & 0x3ff0000) | (value & 0x7fff);
5367 md_number_to_chars (buf, content, INSN_SIZE);
5368 }
5369 break;
5370 case BFD_RELOC_SCORE_BRANCH:
5371 if ((S_GET_SEGMENT (fixP->fx_addsy) != seg) || (fixP->fx_addsy != NULL && S_IS_EXTERNAL (fixP->fx_addsy)))
5372 value = fixP->fx_offset;
5373 else
5374 fixP->fx_done = 1;
5375
5376 content = md_chars_to_number (buf, INSN_SIZE);
5377 if ((fixP->fx_frag->fr_opcode != 0) && ((content & 0x80008000) != 0x80008000))
5378 {
5379 if ((value & 0x80000000) == 0x80000000)
5380 abs_value = 0xffffffff - value + 1;
5381 if ((abs_value & 0xffffff00) != 0)
5382 {
5383 as_bad_where (fixP->fx_file, fixP->fx_line,
5384 _(" branch relocation truncate (0x%x) [-2^8 ~ 2^8]"), (unsigned int)value);
5385 return;
5386 }
5387 content = md_chars_to_number (buf, INSN16_SIZE);
5388 content &= 0xff00;
5389 content = (content & 0xff00) | ((value >> 1) & 0xff);
5390 md_number_to_chars (buf, content, INSN16_SIZE);
5391 fixP->fx_r_type = BFD_RELOC_SCORE16_BRANCH;
5392 fixP->fx_size = 2;
5393 }
5394 else
5395 {
5396 if ((value & 0x80000000) == 0x80000000)
5397 abs_value = 0xffffffff - value + 1;
5398 if ((abs_value & 0xfff80000) != 0)
5399 {
5400 as_bad_where (fixP->fx_file, fixP->fx_line,
5401 _(" branch relocation truncate (0x%x) [-2^19 ~ 2^19]"), (unsigned int)value);
5402 return;
5403 }
5404 content = md_chars_to_number (buf, INSN_SIZE);
5405 content &= 0xfc00fc01;
5406 content = (content & 0xfc00fc01) | (value & 0x3fe) | ((value << 6) & 0x3ff0000);
5407 md_number_to_chars (buf, content, INSN_SIZE);
5408 }
5409 break;
5410 case BFD_RELOC_SCORE16_JMP:
5411 content = md_chars_to_number (buf, INSN16_SIZE);
5412 content &= 0xf001;
5413 value = fixP->fx_offset & 0xfff;
5414 content = (content & 0xfc01) | (value & 0xffe);
5415 md_number_to_chars (buf, content, INSN16_SIZE);
5416 break;
5417 case BFD_RELOC_SCORE16_BRANCH:
5418 content = md_chars_to_number (buf, INSN_SIZE);
5419 if ((fixP->fx_frag->fr_opcode != 0) && ((content & 0x80008000) == 0x80008000))
5420 {
5421 if ((S_GET_SEGMENT (fixP->fx_addsy) != seg) ||
5422 (fixP->fx_addsy != NULL && S_IS_EXTERNAL (fixP->fx_addsy)))
5423 value = fixP->fx_offset;
5424 else
5425 fixP->fx_done = 1;
5426 if ((value & 0x80000000) == 0x80000000)
5427 abs_value = 0xffffffff - value + 1;
5428 if ((abs_value & 0xfff80000) != 0)
5429 {
5430 as_bad_where (fixP->fx_file, fixP->fx_line,
5431 _(" branch relocation truncate (0x%x) [-2^19 ~ 2^19]"), (unsigned int)value);
5432 return;
5433 }
5434 content = md_chars_to_number (buf, INSN_SIZE);
5435 content = (content & 0xfc00fc01) | (value & 0x3fe) | ((value << 6) & 0x3ff0000);
5436 md_number_to_chars (buf, content, INSN_SIZE);
5437 fixP->fx_r_type = BFD_RELOC_SCORE_BRANCH;
5438 fixP->fx_size = 4;
5439 break;
5440 }
5441 else
5442 {
5443 /* In differnt section. */
5444 if ((S_GET_SEGMENT (fixP->fx_addsy) != seg) ||
5445 (fixP->fx_addsy != NULL && S_IS_EXTERNAL (fixP->fx_addsy)))
5446 value = fixP->fx_offset;
5447 else
5448 fixP->fx_done = 1;
5449
5450 if ((value & 0x80000000) == 0x80000000)
5451 abs_value = 0xffffffff - value + 1;
5452 if ((abs_value & 0xffffff00) != 0)
5453 {
5454 as_bad_where (fixP->fx_file, fixP->fx_line,
5455 _(" branch relocation truncate (0x%x) [-2^8 ~ 2^8]"), (unsigned int)value);
5456 return;
5457 }
5458 content = md_chars_to_number (buf, INSN16_SIZE);
5459 content = (content & 0xff00) | ((value >> 1) & 0xff);
5460 md_number_to_chars (buf, content, INSN16_SIZE);
5461 break;
5462 }
5463 case BFD_RELOC_8:
5464 if (fixP->fx_done || fixP->fx_pcrel)
5465 md_number_to_chars (buf, value, 1);
5466 #ifdef OBJ_ELF
5467 else
5468 {
5469 value = fixP->fx_offset;
5470 md_number_to_chars (buf, value, 1);
5471 }
5472 #endif
5473 break;
5474
5475 case BFD_RELOC_16:
5476 if (fixP->fx_done || fixP->fx_pcrel)
5477 md_number_to_chars (buf, value, 2);
5478 #ifdef OBJ_ELF
5479 else
5480 {
5481 value = fixP->fx_offset;
5482 md_number_to_chars (buf, value, 2);
5483 }
5484 #endif
5485 break;
5486 case BFD_RELOC_RVA:
5487 case BFD_RELOC_32:
5488 if (fixP->fx_done || fixP->fx_pcrel)
5489 md_number_to_chars (buf, value, 4);
5490 #ifdef OBJ_ELF
5491 else
5492 {
5493 value = fixP->fx_offset;
5494 md_number_to_chars (buf, value, 4);
5495 }
5496 #endif
5497 break;
5498 case BFD_RELOC_VTABLE_INHERIT:
5499 fixP->fx_done = 0;
5500 if (fixP->fx_addsy && !S_IS_DEFINED (fixP->fx_addsy) && !S_IS_WEAK (fixP->fx_addsy))
5501 S_SET_WEAK (fixP->fx_addsy);
5502 break;
5503 case BFD_RELOC_VTABLE_ENTRY:
5504 fixP->fx_done = 0;
5505 break;
5506 case BFD_RELOC_SCORE_GPREL15:
5507 content = md_chars_to_number (buf, INSN_SIZE);
5508 if ((fixP->fx_frag->fr_opcode != 0) && ((content & 0xfc1c8000) != 0x94188000))
5509 fixP->fx_r_type = BFD_RELOC_NONE;
5510 fixP->fx_done = 0;
5511 break;
5512 case BFD_RELOC_SCORE_GOT15:
5513 case BFD_RELOC_SCORE_DUMMY_HI16:
5514 case BFD_RELOC_SCORE_GOT_LO16:
5515 case BFD_RELOC_SCORE_CALL15:
5516 case BFD_RELOC_GPREL32:
5517 break;
5518 case BFD_RELOC_NONE:
5519 default:
5520 as_bad_where (fixP->fx_file, fixP->fx_line, _("bad relocation fixup type (%d)"), fixP->fx_r_type);
5521 }
5522 }
5523
5524 /* Translate internal representation of relocation info to BFD target format. */
5525 arelent **
5526 tc_gen_reloc (asection * section ATTRIBUTE_UNUSED, fixS * fixp)
5527 {
5528 static arelent *retval[MAX_RELOC_EXPANSION + 1]; /* MAX_RELOC_EXPANSION equals 2. */
5529 arelent *reloc;
5530 bfd_reloc_code_real_type code;
5531 char *type;
5532 fragS *f;
5533 symbolS *s;
5534 expressionS e;
5535
5536 reloc = retval[0] = xmalloc (sizeof (arelent));
5537 retval[1] = NULL;
5538
5539 reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
5540 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
5541 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
5542 reloc->addend = fixp->fx_offset;
5543
5544 /* If this is a variant frag, we may need to adjust the existing
5545 reloc and generate a new one. */
5546 if (fixp->fx_frag->fr_opcode != NULL && (fixp->fx_r_type == BFD_RELOC_SCORE_GPREL15))
5547 {
5548 /* Update instruction imm bit. */
5549 offsetT newval;
5550 unsigned short off;
5551 char *buf;
5552
5553 buf = fixp->fx_frag->fr_literal + fixp->fx_frag->insn_addr;
5554 newval = md_chars_to_number (buf, INSN_SIZE);
5555 off = fixp->fx_offset >> 16;
5556 newval |= (off & 0x3fff) << 1;
5557 newval |= ((off >> 14) & 0x3) << 16;
5558 md_number_to_chars (buf, newval, INSN_SIZE);
5559
5560 buf += INSN_SIZE;
5561 newval = md_chars_to_number (buf, INSN_SIZE);
5562 off = fixp->fx_offset & 0xffff;
5563 newval |= ((off & 0x3fff) << 1);
5564 newval |= (((off >> 14) & 0x3) << 16);
5565 md_number_to_chars (buf, newval, INSN_SIZE);
5566
5567 retval[1] = xmalloc (sizeof (arelent));
5568 retval[2] = NULL;
5569 retval[1]->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
5570 *retval[1]->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
5571 retval[1]->address = (reloc->address + RELAX_RELOC2 (fixp->fx_frag->fr_subtype));
5572
5573 f = fixp->fx_frag;
5574 s = f->fr_symbol;
5575 e = s->sy_value;
5576
5577 retval[1]->addend = 0;
5578 retval[1]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_LO16);
5579 assert (retval[1]->howto != NULL);
5580
5581 fixp->fx_r_type = BFD_RELOC_HI16_S;
5582 }
5583
5584 code = fixp->fx_r_type;
5585 switch (fixp->fx_r_type)
5586 {
5587 case BFD_RELOC_32:
5588 if (fixp->fx_pcrel)
5589 {
5590 code = BFD_RELOC_32_PCREL;
5591 break;
5592 }
5593 case BFD_RELOC_HI16_S:
5594 case BFD_RELOC_LO16:
5595 case BFD_RELOC_SCORE_JMP:
5596 case BFD_RELOC_SCORE_BRANCH:
5597 case BFD_RELOC_SCORE16_JMP:
5598 case BFD_RELOC_SCORE16_BRANCH:
5599 case BFD_RELOC_VTABLE_ENTRY:
5600 case BFD_RELOC_VTABLE_INHERIT:
5601 case BFD_RELOC_SCORE_GPREL15:
5602 case BFD_RELOC_SCORE_GOT15:
5603 case BFD_RELOC_SCORE_DUMMY_HI16:
5604 case BFD_RELOC_SCORE_GOT_LO16:
5605 case BFD_RELOC_SCORE_CALL15:
5606 case BFD_RELOC_GPREL32:
5607 case BFD_RELOC_NONE:
5608 code = fixp->fx_r_type;
5609 break;
5610 default:
5611 type = _("<unknown>");
5612 as_bad_where (fixp->fx_file, fixp->fx_line,
5613 _("cannot represent %s relocation in this object file format"), type);
5614 return NULL;
5615 }
5616
5617 reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
5618 if (reloc->howto == NULL)
5619 {
5620 as_bad_where (fixp->fx_file, fixp->fx_line,
5621 _("cannot represent %s relocation in this object file format1"),
5622 bfd_get_reloc_code_name (code));
5623 return NULL;
5624 }
5625 /* HACK: Since arm ELF uses Rel instead of Rela, encode the
5626 vtable entry to be used in the relocation's section offset. */
5627 if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
5628 reloc->address = fixp->fx_offset;
5629
5630 return retval;
5631 }
5632
5633 void
5634 score_elf_final_processing (void)
5635 {
5636 if (fix_data_dependency == 1)
5637 {
5638 elf_elfheader (stdoutput)->e_flags |= EF_SCORE_FIXDEP;
5639 }
5640 if (score_pic == PIC)
5641 {
5642 elf_elfheader (stdoutput)->e_flags |= EF_SCORE_PIC;
5643 }
5644 }
5645
5646 static void
5647 parse_pce_inst (char *insnstr)
5648 {
5649 char c;
5650 char *p;
5651 char first[MAX_LITERAL_POOL_SIZE];
5652 char second[MAX_LITERAL_POOL_SIZE];
5653 struct score_it pec_part_1;
5654
5655 /* Get first part string of PCE. */
5656 p = strstr (insnstr, "||");
5657 c = *p;
5658 *p = '\0';
5659 sprintf (first, "%s", insnstr);
5660
5661 /* Get second part string of PCE. */
5662 *p = c;
5663 p += 2;
5664 sprintf (second, "%s", p);
5665
5666 parse_16_32_inst (first, FALSE);
5667 if (inst.error)
5668 return;
5669
5670 memcpy (&pec_part_1, &inst, sizeof (inst));
5671
5672 parse_16_32_inst (second, FALSE);
5673 if (inst.error)
5674 return;
5675
5676 if ( ((pec_part_1.size == INSN_SIZE) && (inst.size == INSN_SIZE))
5677 || ((pec_part_1.size == INSN_SIZE) && (inst.size == INSN16_SIZE))
5678 || ((pec_part_1.size == INSN16_SIZE) && (inst.size == INSN_SIZE)))
5679 {
5680 inst.error = _("pce instruction error (16 bit || 16 bit)'");
5681 sprintf (inst.str, "%s", insnstr);
5682 return;
5683 }
5684
5685 if (!inst.error)
5686 gen_insn_frag (&pec_part_1, &inst);
5687 }
5688
5689 void
5690 md_assemble (char *str)
5691 {
5692 know (str);
5693 know (strlen (str) < MAX_LITERAL_POOL_SIZE);
5694
5695 memset (&inst, '\0', sizeof (inst));
5696 if (INSN_IS_PCE_P (str))
5697 parse_pce_inst (str);
5698 else
5699 parse_16_32_inst (str, TRUE);
5700
5701 if (inst.error)
5702 as_bad ("%s -- `%s'", inst.error, inst.str);
5703 }
5704
5705 /* We handle all bad expressions here, so that we can report the faulty
5706 instruction in the error message. */
5707 void
5708 md_operand (expressionS * expr)
5709 {
5710 if (in_my_get_expression)
5711 {
5712 expr->X_op = O_illegal;
5713 if (inst.error == NULL)
5714 {
5715 inst.error = _("bad expression");
5716 }
5717 }
5718 }
5719
5720 const char *md_shortopts = "nO::g::G:";
5721
5722 #ifdef SCORE_BI_ENDIAN
5723 #define OPTION_EB (OPTION_MD_BASE + 0)
5724 #define OPTION_EL (OPTION_MD_BASE + 1)
5725 #else
5726 #if TARGET_BYTES_BIG_ENDIAN
5727 #define OPTION_EB (OPTION_MD_BASE + 0)
5728 #else
5729 #define OPTION_EL (OPTION_MD_BASE + 1)
5730 #endif
5731 #endif
5732 #define OPTION_FIXDD (OPTION_MD_BASE + 2)
5733 #define OPTION_NWARN (OPTION_MD_BASE + 3)
5734 #define OPTION_SCORE5 (OPTION_MD_BASE + 4)
5735 #define OPTION_SCORE5U (OPTION_MD_BASE + 5)
5736 #define OPTION_SCORE7 (OPTION_MD_BASE + 6)
5737 #define OPTION_R1 (OPTION_MD_BASE + 7)
5738 #define OPTION_O0 (OPTION_MD_BASE + 8)
5739 #define OPTION_SCORE_VERSION (OPTION_MD_BASE + 9)
5740 #define OPTION_PIC (OPTION_MD_BASE + 10)
5741
5742 struct option md_longopts[] =
5743 {
5744 #ifdef OPTION_EB
5745 {"EB" , no_argument, NULL, OPTION_EB},
5746 #endif
5747 #ifdef OPTION_EL
5748 {"EL" , no_argument, NULL, OPTION_EL},
5749 #endif
5750 {"FIXDD" , no_argument, NULL, OPTION_FIXDD},
5751 {"NWARN" , no_argument, NULL, OPTION_NWARN},
5752 {"SCORE5" , no_argument, NULL, OPTION_SCORE5},
5753 {"SCORE5U", no_argument, NULL, OPTION_SCORE5U},
5754 {"SCORE7" , no_argument, NULL, OPTION_SCORE7},
5755 {"USE_R1" , no_argument, NULL, OPTION_R1},
5756 {"O0" , no_argument, NULL, OPTION_O0},
5757 {"V" , no_argument, NULL, OPTION_SCORE_VERSION},
5758 {"KPIC" , no_argument, NULL, OPTION_PIC},
5759 {NULL , no_argument, NULL, 0}
5760 };
5761
5762 size_t md_longopts_size = sizeof (md_longopts);
5763
5764 int
5765 md_parse_option (int c, char *arg)
5766 {
5767 switch (c)
5768 {
5769 #ifdef OPTION_EB
5770 case OPTION_EB:
5771 target_big_endian = 1;
5772 break;
5773 #endif
5774 #ifdef OPTION_EL
5775 case OPTION_EL:
5776 target_big_endian = 0;
5777 break;
5778 #endif
5779 case OPTION_FIXDD:
5780 fix_data_dependency = 1;
5781 break;
5782 case OPTION_NWARN:
5783 warn_fix_data_dependency = 0;
5784 break;
5785 case OPTION_SCORE5:
5786 score7 = 0;
5787 university_version = 0;
5788 vector_size = SCORE5_PIPELINE;
5789 break;
5790 case OPTION_SCORE5U:
5791 score7 = 0;
5792 university_version = 1;
5793 vector_size = SCORE5_PIPELINE;
5794 break;
5795 case OPTION_SCORE7:
5796 score7 = 1;
5797 university_version = 0;
5798 vector_size = SCORE7_PIPELINE;
5799 break;
5800 case OPTION_R1:
5801 nor1 = 0;
5802 break;
5803 case 'G':
5804 g_switch_value = atoi (arg);
5805 break;
5806 case OPTION_O0:
5807 g_opt = 0;
5808 break;
5809 case OPTION_SCORE_VERSION:
5810 printf (_("Sunplus-v2-0-0-20060510\n"));
5811 break;
5812 case OPTION_PIC:
5813 score_pic = PIC;
5814 g_switch_value = 0; /* Must set -G num as 0 to generate PIC code. */
5815 break;
5816 default:
5817 /* as_bad (_("unrecognized option `-%c%s'"), c, arg ? arg : ""); */
5818 return 0;
5819 }
5820 return 1;
5821 }
5822
5823 void
5824 md_show_usage (FILE * fp)
5825 {
5826 fprintf (fp, _(" Score-specific assembler options:\n"));
5827 #ifdef OPTION_EB
5828 fprintf (fp, _("\
5829 -EB\t\tassemble code for a big-endian cpu\n"));
5830 #endif
5831
5832 #ifdef OPTION_EL
5833 fprintf (fp, _("\
5834 -EL\t\tassemble code for a little-endian cpu\n"));
5835 #endif
5836
5837 fprintf (fp, _("\
5838 -FIXDD\t\tassemble code for fix data dependency\n"));
5839 fprintf (fp, _("\
5840 -NWARN\t\tassemble code for no warning message for fix data dependency\n"));
5841 fprintf (fp, _("\
5842 -SCORE5\t\tassemble code for target is SCORE5\n"));
5843 fprintf (fp, _("\
5844 -SCORE5U\tassemble code for target is SCORE5U\n"));
5845 fprintf (fp, _("\
5846 -SCORE7\t\tassemble code for target is SCORE7, this is default setting\n"));
5847 fprintf (fp, _("\
5848 -USE_R1\t\tassemble code for no warning message when using temp register r1\n"));
5849 fprintf (fp, _("\
5850 -KPIC\t\tassemble code for PIC\n"));
5851 fprintf (fp, _("\
5852 -O0\t\tassembler will not perform any optimizations\n"));
5853 fprintf (fp, _("\
5854 -G gpnum\tassemble code for setting gpsize and default is 8 byte\n"));
5855 fprintf (fp, _("\
5856 -V \t\tSunplus release version \n"));
5857 }
5858
5859
5860 /* Pesudo handling functions. */
5861
5862 /* If we change section we must dump the literal pool first. */
5863 static void
5864 s_score_bss (int ignore ATTRIBUTE_UNUSED)
5865 {
5866 subseg_set (bss_section, (subsegT) get_absolute_expression ());
5867 demand_empty_rest_of_line ();
5868 }
5869
5870 static void
5871 s_score_text (int ignore)
5872 {
5873 obj_elf_text (ignore);
5874 record_alignment (now_seg, 2);
5875 }
5876
5877 static void
5878 score_s_section (int ignore)
5879 {
5880 obj_elf_section (ignore);
5881 if ((bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) != 0)
5882 record_alignment (now_seg, 2);
5883
5884 }
5885
5886 static void
5887 s_change_sec (int sec)
5888 {
5889 segT seg;
5890
5891 #ifdef OBJ_ELF
5892 /* The ELF backend needs to know that we are changing sections, so
5893 that .previous works correctly. We could do something like check
5894 for an obj_section_change_hook macro, but that might be confusing
5895 as it would not be appropriate to use it in the section changing
5896 functions in read.c, since obj-elf.c intercepts those. FIXME:
5897 This should be cleaner, somehow. */
5898 obj_elf_section_change_hook ();
5899 #endif
5900 switch (sec)
5901 {
5902 case 'r':
5903 seg = subseg_new (RDATA_SECTION_NAME, (subsegT) get_absolute_expression ());
5904 bfd_set_section_flags (stdoutput, seg, (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_RELOC | SEC_DATA));
5905 if (strcmp (TARGET_OS, "elf") != 0)
5906 record_alignment (seg, 4);
5907 demand_empty_rest_of_line ();
5908 break;
5909 case 's':
5910 seg = subseg_new (".sdata", (subsegT) get_absolute_expression ());
5911 bfd_set_section_flags (stdoutput, seg, SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA);
5912 if (strcmp (TARGET_OS, "elf") != 0)
5913 record_alignment (seg, 4);
5914 demand_empty_rest_of_line ();
5915 break;
5916 }
5917 }
5918
5919 static void
5920 s_score_mask (int reg_type ATTRIBUTE_UNUSED)
5921 {
5922 long mask, off;
5923
5924 if (cur_proc_ptr == (procS *) NULL)
5925 {
5926 as_warn (_(".mask outside of .ent"));
5927 demand_empty_rest_of_line ();
5928 return;
5929 }
5930 if (get_absolute_expression_and_terminator (&mask) != ',')
5931 {
5932 as_warn (_("Bad .mask directive"));
5933 --input_line_pointer;
5934 demand_empty_rest_of_line ();
5935 return;
5936 }
5937 off = get_absolute_expression ();
5938 cur_proc_ptr->reg_mask = mask;
5939 cur_proc_ptr->reg_offset = off;
5940 demand_empty_rest_of_line ();
5941 }
5942
5943 static symbolS *
5944 get_symbol (void)
5945 {
5946 int c;
5947 char *name;
5948 symbolS *p;
5949
5950 name = input_line_pointer;
5951 c = get_symbol_end ();
5952 p = (symbolS *) symbol_find_or_make (name);
5953 *input_line_pointer = c;
5954 return p;
5955 }
5956
5957 static long
5958 get_number (void)
5959 {
5960 int negative = 0;
5961 long val = 0;
5962
5963 if (*input_line_pointer == '-')
5964 {
5965 ++input_line_pointer;
5966 negative = 1;
5967 }
5968 if (!ISDIGIT (*input_line_pointer))
5969 as_bad (_("expected simple number"));
5970 if (input_line_pointer[0] == '0')
5971 {
5972 if (input_line_pointer[1] == 'x')
5973 {
5974 input_line_pointer += 2;
5975 while (ISXDIGIT (*input_line_pointer))
5976 {
5977 val <<= 4;
5978 val |= hex_value (*input_line_pointer++);
5979 }
5980 return negative ? -val : val;
5981 }
5982 else
5983 {
5984 ++input_line_pointer;
5985 while (ISDIGIT (*input_line_pointer))
5986 {
5987 val <<= 3;
5988 val |= *input_line_pointer++ - '0';
5989 }
5990 return negative ? -val : val;
5991 }
5992 }
5993 if (!ISDIGIT (*input_line_pointer))
5994 {
5995 printf (_(" *input_line_pointer == '%c' 0x%02x\n"), *input_line_pointer, *input_line_pointer);
5996 as_warn (_("invalid number"));
5997 return -1;
5998 }
5999 while (ISDIGIT (*input_line_pointer))
6000 {
6001 val *= 10;
6002 val += *input_line_pointer++ - '0';
6003 }
6004 return negative ? -val : val;
6005 }
6006
6007 /* The .aent and .ent directives. */
6008
6009 static void
6010 s_score_ent (int aent)
6011 {
6012 symbolS *symbolP;
6013 int maybe_text;
6014
6015 symbolP = get_symbol ();
6016 if (*input_line_pointer == ',')
6017 ++input_line_pointer;
6018 SKIP_WHITESPACE ();
6019 if (ISDIGIT (*input_line_pointer) || *input_line_pointer == '-')
6020 get_number ();
6021
6022 #ifdef BFD_ASSEMBLER
6023 if ((bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) != 0)
6024 maybe_text = 1;
6025 else
6026 maybe_text = 0;
6027 #else
6028 if (now_seg != data_section && now_seg != bss_section)
6029 maybe_text = 1;
6030 else
6031 maybe_text = 0;
6032 #endif
6033 if (!maybe_text)
6034 as_warn (_(".ent or .aent not in text section."));
6035 if (!aent && cur_proc_ptr)
6036 as_warn (_("missing .end"));
6037 if (!aent)
6038 {
6039 cur_proc_ptr = &cur_proc;
6040 cur_proc_ptr->reg_mask = 0xdeadbeaf;
6041 cur_proc_ptr->reg_offset = 0xdeadbeaf;
6042 cur_proc_ptr->fpreg_mask = 0xdeafbeaf;
6043 cur_proc_ptr->leaf = 0xdeafbeaf;
6044 cur_proc_ptr->frame_offset = 0xdeafbeaf;
6045 cur_proc_ptr->frame_reg = 0xdeafbeaf;
6046 cur_proc_ptr->pc_reg = 0xdeafbeaf;
6047 cur_proc_ptr->isym = symbolP;
6048 symbol_get_bfdsym (symbolP)->flags |= BSF_FUNCTION;
6049 ++numprocs;
6050 if (debug_type == DEBUG_STABS)
6051 stabs_generate_asm_func (S_GET_NAME (symbolP), S_GET_NAME (symbolP));
6052 }
6053 demand_empty_rest_of_line ();
6054 }
6055
6056 static void
6057 s_score_frame (int ignore ATTRIBUTE_UNUSED)
6058 {
6059 char *backupstr;
6060 char str[30];
6061 long val;
6062 int i = 0;
6063
6064 backupstr = input_line_pointer;
6065
6066 #ifdef OBJ_ELF
6067 if (cur_proc_ptr == (procS *) NULL)
6068 {
6069 as_warn (_(".frame outside of .ent"));
6070 demand_empty_rest_of_line ();
6071 return;
6072 }
6073 cur_proc_ptr->frame_reg = reg_required_here ((&backupstr), 0, REG_TYPE_SCORE);
6074 SKIP_WHITESPACE ();
6075 skip_past_comma (&backupstr);
6076 while (*backupstr != ',')
6077 {
6078 str[i] = *backupstr;
6079 i++;
6080 backupstr++;
6081 }
6082 str[i] = '\0';
6083 val = atoi (str);
6084
6085 SKIP_WHITESPACE ();
6086 skip_past_comma (&backupstr);
6087 cur_proc_ptr->frame_offset = val;
6088 cur_proc_ptr->pc_reg = reg_required_here ((&backupstr), 0, REG_TYPE_SCORE);
6089
6090 SKIP_WHITESPACE ();
6091 skip_past_comma (&backupstr);
6092 i = 0;
6093 while (*backupstr != '\n')
6094 {
6095 str[i] = *backupstr;
6096 i++;
6097 backupstr++;
6098 }
6099 str[i] = '\0';
6100 val = atoi (str);
6101 cur_proc_ptr->leaf = val;
6102 SKIP_WHITESPACE ();
6103 skip_past_comma (&backupstr);
6104
6105 #endif /* OBJ_ELF */
6106 while (input_line_pointer != backupstr)
6107 input_line_pointer++;
6108 }
6109
6110 /* The .end directive. */
6111 static void
6112 s_score_end (int x ATTRIBUTE_UNUSED)
6113 {
6114 symbolS *p;
6115 int maybe_text;
6116
6117 /* Generate a .pdr section. */
6118 segT saved_seg = now_seg;
6119 subsegT saved_subseg = now_subseg;
6120 valueT dot;
6121 expressionS exp;
6122 char *fragp;
6123
6124 if (!is_end_of_line[(unsigned char)*input_line_pointer])
6125 {
6126 p = get_symbol ();
6127 demand_empty_rest_of_line ();
6128 }
6129 else
6130 p = NULL;
6131
6132 #ifdef BFD_ASSEMBLER
6133 if ((bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) != 0)
6134 maybe_text = 1;
6135 else
6136 maybe_text = 0;
6137 #else
6138 if (now_seg != data_section && now_seg != bss_section)
6139 maybe_text = 1;
6140 else
6141 maybe_text = 0;
6142 #endif
6143
6144 if (!maybe_text)
6145 as_warn (_(".end not in text section"));
6146 if (!cur_proc_ptr)
6147 {
6148 as_warn (_(".end directive without a preceding .ent directive."));
6149 demand_empty_rest_of_line ();
6150 return;
6151 }
6152 if (p != NULL)
6153 {
6154 assert (S_GET_NAME (p));
6155 if (strcmp (S_GET_NAME (p), S_GET_NAME (cur_proc_ptr->isym)))
6156 as_warn (_(".end symbol does not match .ent symbol."));
6157 if (debug_type == DEBUG_STABS)
6158 stabs_generate_asm_endfunc (S_GET_NAME (p), S_GET_NAME (p));
6159 }
6160 else
6161 as_warn (_(".end directive missing or unknown symbol"));
6162
6163 if ((cur_proc_ptr->reg_mask == 0xdeadbeaf) ||
6164 (cur_proc_ptr->reg_offset == 0xdeadbeaf) ||
6165 (cur_proc_ptr->leaf == 0xdeafbeaf) ||
6166 (cur_proc_ptr->frame_offset == 0xdeafbeaf) ||
6167 (cur_proc_ptr->frame_reg == 0xdeafbeaf) || (cur_proc_ptr->pc_reg == 0xdeafbeaf));
6168
6169 else
6170 {
6171 dot = frag_now_fix ();
6172 assert (pdr_seg);
6173 subseg_set (pdr_seg, 0);
6174 /* Write the symbol. */
6175 exp.X_op = O_symbol;
6176 exp.X_add_symbol = p;
6177 exp.X_add_number = 0;
6178 emit_expr (&exp, 4);
6179 fragp = frag_more (7 * 4);
6180 md_number_to_chars (fragp, (valueT) cur_proc_ptr->reg_mask, 4);
6181 md_number_to_chars (fragp + 4, (valueT) cur_proc_ptr->reg_offset, 4);
6182 md_number_to_chars (fragp + 8, (valueT) cur_proc_ptr->fpreg_mask, 4);
6183 md_number_to_chars (fragp + 12, (valueT) cur_proc_ptr->leaf, 4);
6184 md_number_to_chars (fragp + 16, (valueT) cur_proc_ptr->frame_offset, 4);
6185 md_number_to_chars (fragp + 20, (valueT) cur_proc_ptr->frame_reg, 4);
6186 md_number_to_chars (fragp + 24, (valueT) cur_proc_ptr->pc_reg, 4);
6187 subseg_set (saved_seg, saved_subseg);
6188
6189 }
6190 cur_proc_ptr = NULL;
6191 }
6192
6193 /* Handle the .set pseudo-op. */
6194 static void
6195 s_score_set (int x ATTRIBUTE_UNUSED)
6196 {
6197 int i = 0;
6198 char name[MAX_LITERAL_POOL_SIZE];
6199 char * orig_ilp = input_line_pointer;
6200
6201 while (!is_end_of_line[(unsigned char)*input_line_pointer])
6202 {
6203 name[i] = (char) * input_line_pointer;
6204 i++;
6205 ++input_line_pointer;
6206 }
6207
6208 name[i] = '\0';
6209
6210 if (strcmp (name, "nwarn") == 0)
6211 {
6212 warn_fix_data_dependency = 0;
6213 }
6214 else if (strcmp (name, "fixdd") == 0)
6215 {
6216 fix_data_dependency = 1;
6217 }
6218 else if (strcmp (name, "nofixdd") == 0)
6219 {
6220 fix_data_dependency = 0;
6221 }
6222 else if (strcmp (name, "r1") == 0)
6223 {
6224 nor1 = 0;
6225 }
6226 else if (strcmp (name, "nor1") == 0)
6227 {
6228 nor1 = 1;
6229 }
6230 else if (strcmp (name, "optimize") == 0)
6231 {
6232 g_opt = 1;
6233 }
6234 else if (strcmp (name, "volatile") == 0)
6235 {
6236 g_opt = 0;
6237 }
6238 else if (strcmp (name, "pic") == 0)
6239 {
6240 score_pic = PIC;
6241 }
6242 else
6243 {
6244 input_line_pointer = orig_ilp;
6245 s_set (0);
6246 }
6247 }
6248
6249 /* Handle the .cpload pseudo-op. This is used when generating PIC code. It sets the
6250 $gp register for the function based on the function address, which is in the register
6251 named in the argument. This uses a relocation against GP_DISP_LABEL, which is handled
6252 specially by the linker. The result is:
6253 ldis gp, %hi(GP_DISP_LABEL)
6254 ori gp, %low(GP_DISP_LABEL)
6255 add gp, gp, .cpload argument
6256 The .cpload argument is normally r29. */
6257
6258 static void
6259 s_score_cpload (int ignore ATTRIBUTE_UNUSED)
6260 {
6261 int reg;
6262 char insn_str[MAX_LITERAL_POOL_SIZE];
6263
6264 /* If we are not generating PIC code, .cpload is ignored. */
6265 if (score_pic == NO_PIC)
6266 {
6267 s_ignore (0);
6268 return;
6269 }
6270
6271 if ((reg = reg_required_here (&input_line_pointer, -1, REG_TYPE_SCORE)) == (int) FAIL)
6272 return;
6273
6274 demand_empty_rest_of_line ();
6275
6276 sprintf (insn_str, "ld_i32hi r%d, %s", GP, GP_DISP_LABEL);
6277 if (append_insn (insn_str, TRUE) == (int) FAIL)
6278 return;
6279
6280 sprintf (insn_str, "ld_i32lo r%d, %s", GP, GP_DISP_LABEL);
6281 if (append_insn (insn_str, TRUE) == (int) FAIL)
6282 return;
6283
6284 sprintf (insn_str, "add r%d, r%d, r%d", GP, GP, reg);
6285 if (append_insn (insn_str, TRUE) == (int) FAIL)
6286 return;
6287 }
6288
6289 /* Handle the .cprestore pseudo-op. This stores $gp into a given
6290 offset from $sp. The offset is remembered, and after making a PIC
6291 call $gp is restored from that location. */
6292
6293 static void
6294 s_score_cprestore (int ignore ATTRIBUTE_UNUSED)
6295 {
6296 #define SCORE_BP_REG 2
6297 int cprestore_offset;
6298 char insn_str[MAX_LITERAL_POOL_SIZE];
6299
6300 /* If we are not generating PIC code, .cprestore is ignored. */
6301 if (score_pic == NO_PIC)
6302 {
6303 s_ignore (0);
6304 return;
6305 }
6306
6307 cprestore_offset = get_absolute_expression ();
6308
6309 sprintf (insn_str, "sw r%d, [r%d, %d]", GP, SCORE_BP_REG, cprestore_offset);
6310 if (append_insn (insn_str, TRUE) == (int) FAIL)
6311 return;
6312 }
6313
6314 /* Handle the .gpword pseudo-op. This is used when generating PIC
6315 code. It generates a 32 bit GP relative reloc. */
6316 static void
6317 s_score_gpword (int ignore ATTRIBUTE_UNUSED)
6318 {
6319 expressionS ex;
6320 char *p;
6321
6322 /* When not generating PIC code, this is treated as .word. */
6323 if (score_pic == NO_PIC)
6324 {
6325 cons (4);
6326 return;
6327 }
6328 expression (&ex);
6329 if (ex.X_op != O_symbol || ex.X_add_number != 0)
6330 {
6331 as_bad (_("Unsupported use of .gpword"));
6332 ignore_rest_of_line ();
6333 }
6334 p = frag_more (4);
6335 md_number_to_chars (p, (valueT) 0, 4);
6336 fix_new_exp (frag_now, p - frag_now->fr_literal, 4, &ex, FALSE, BFD_RELOC_GPREL32);
6337 demand_empty_rest_of_line ();
6338 }
6339
6340 /* Handle the .cpadd pseudo-op. This is used when dealing with switch
6341 tables in PIC code. */
6342
6343 static void
6344 s_score_cpadd (int ignore ATTRIBUTE_UNUSED)
6345 {
6346 int reg;
6347 char insn_str[MAX_LITERAL_POOL_SIZE];
6348
6349 /* If we are not generating PIC code, .cpload is ignored. */
6350 if (score_pic == NO_PIC)
6351 {
6352 s_ignore (0);
6353 return;
6354 }
6355
6356 if ((reg = reg_required_here (&input_line_pointer, -1, REG_TYPE_SCORE)) == (int) FAIL)
6357 {
6358 return;
6359 }
6360 demand_empty_rest_of_line ();
6361
6362 /* Add $gp to the register named as an argument. */
6363 sprintf (insn_str, "add r%d, r%d, r%d", reg, reg, GP);
6364 if (append_insn (insn_str, TRUE) == (int) FAIL)
6365 return;
6366 }
6367
6368 #ifndef TC_IMPLICIT_LCOMM_ALIGNMENT
6369 #define TC_IMPLICIT_LCOMM_ALIGNMENT(SIZE, P2VAR) \
6370 do \
6371 { \
6372 if ((SIZE) >= 8) \
6373 (P2VAR) = 3; \
6374 else if ((SIZE) >= 4) \
6375 (P2VAR) = 2; \
6376 else if ((SIZE) >= 2) \
6377 (P2VAR) = 1; \
6378 else \
6379 (P2VAR) = 0; \
6380 } \
6381 while (0)
6382 #endif
6383
6384 static void
6385 s_score_lcomm (int bytes_p)
6386 {
6387 char *name;
6388 char c;
6389 char *p;
6390 int temp;
6391 symbolS *symbolP;
6392 segT current_seg = now_seg;
6393 subsegT current_subseg = now_subseg;
6394 const int max_alignment = 15;
6395 int align = 0;
6396 segT bss_seg = bss_section;
6397 int needs_align = 0;
6398
6399 name = input_line_pointer;
6400 c = get_symbol_end ();
6401 p = input_line_pointer;
6402 *p = c;
6403
6404 if (name == p)
6405 {
6406 as_bad (_("expected symbol name"));
6407 discard_rest_of_line ();
6408 return;
6409 }
6410
6411 SKIP_WHITESPACE ();
6412
6413 /* Accept an optional comma after the name. The comma used to be
6414 required, but Irix 5 cc does not generate it. */
6415 if (*input_line_pointer == ',')
6416 {
6417 ++input_line_pointer;
6418 SKIP_WHITESPACE ();
6419 }
6420
6421 if (is_end_of_line[(unsigned char)*input_line_pointer])
6422 {
6423 as_bad (_("missing size expression"));
6424 return;
6425 }
6426
6427 if ((temp = get_absolute_expression ()) < 0)
6428 {
6429 as_warn (_("BSS length (%d) < 0 ignored"), temp);
6430 ignore_rest_of_line ();
6431 return;
6432 }
6433
6434 #if defined (TC_SCORE)
6435 if (OUTPUT_FLAVOR == bfd_target_ecoff_flavour || OUTPUT_FLAVOR == bfd_target_elf_flavour)
6436 {
6437 /* For Score and Alpha ECOFF or ELF, small objects are put in .sbss. */
6438 if ((unsigned)temp <= bfd_get_gp_size (stdoutput))
6439 {
6440 bss_seg = subseg_new (".sbss", 1);
6441 seg_info (bss_seg)->bss = 1;
6442 #ifdef BFD_ASSEMBLER
6443 if (!bfd_set_section_flags (stdoutput, bss_seg, SEC_ALLOC))
6444 as_warn (_("error setting flags for \".sbss\": %s"), bfd_errmsg (bfd_get_error ()));
6445 #endif
6446 }
6447 }
6448 #endif
6449
6450 SKIP_WHITESPACE ();
6451 if (*input_line_pointer == ',')
6452 {
6453 ++input_line_pointer;
6454 SKIP_WHITESPACE ();
6455
6456 if (is_end_of_line[(unsigned char)*input_line_pointer])
6457 {
6458 as_bad (_("missing alignment"));
6459 return;
6460 }
6461 else
6462 {
6463 align = get_absolute_expression ();
6464 needs_align = 1;
6465 }
6466 }
6467
6468 if (!needs_align)
6469 {
6470 TC_IMPLICIT_LCOMM_ALIGNMENT (temp, align);
6471
6472 /* Still zero unless TC_IMPLICIT_LCOMM_ALIGNMENT set it. */
6473 if (align)
6474 record_alignment (bss_seg, align);
6475 }
6476
6477 if (needs_align)
6478 {
6479 if (bytes_p)
6480 {
6481 /* Convert to a power of 2. */
6482 if (align != 0)
6483 {
6484 unsigned int i;
6485
6486 for (i = 0; align != 0; align >>= 1, ++i)
6487 ;
6488 align = i - 1;
6489 }
6490 }
6491
6492 if (align > max_alignment)
6493 {
6494 align = max_alignment;
6495 as_warn (_("alignment too large; %d assumed"), align);
6496 }
6497 else if (align < 0)
6498 {
6499 align = 0;
6500 as_warn (_("alignment negative; 0 assumed"));
6501 }
6502
6503 record_alignment (bss_seg, align);
6504 }
6505 else
6506 {
6507 /* Assume some objects may require alignment on some systems. */
6508 #if defined (TC_ALPHA) && ! defined (VMS)
6509 if (temp > 1)
6510 {
6511 align = ffs (temp) - 1;
6512 if (temp % (1 << align))
6513 abort ();
6514 }
6515 #endif
6516 }
6517
6518 *p = 0;
6519 symbolP = symbol_find_or_make (name);
6520 *p = c;
6521
6522 if (
6523 #if (defined (OBJ_AOUT) || defined (OBJ_MAYBE_AOUT) \
6524 || defined (OBJ_BOUT) || defined (OBJ_MAYBE_BOUT))
6525 #ifdef BFD_ASSEMBLER
6526 (OUTPUT_FLAVOR != bfd_target_aout_flavour
6527 || (S_GET_OTHER (symbolP) == 0 && S_GET_DESC (symbolP) == 0)) &&
6528 #else
6529 (S_GET_OTHER (symbolP) == 0 && S_GET_DESC (symbolP) == 0) &&
6530 #endif
6531 #endif
6532 (S_GET_SEGMENT (symbolP) == bss_seg || (!S_IS_DEFINED (symbolP) && S_GET_VALUE (symbolP) == 0)))
6533 {
6534 char *pfrag;
6535
6536 subseg_set (bss_seg, 1);
6537
6538 if (align)
6539 frag_align (align, 0, 0);
6540
6541 /* Detach from old frag. */
6542 if (S_GET_SEGMENT (symbolP) == bss_seg)
6543 symbol_get_frag (symbolP)->fr_symbol = NULL;
6544
6545 symbol_set_frag (symbolP, frag_now);
6546 pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP, (offsetT) temp, NULL);
6547 *pfrag = 0;
6548
6549
6550 S_SET_SEGMENT (symbolP, bss_seg);
6551
6552 #ifdef OBJ_COFF
6553 /* The symbol may already have been created with a preceding
6554 ".globl" directive -- be careful not to step on storage class
6555 in that case. Otherwise, set it to static. */
6556 if (S_GET_STORAGE_CLASS (symbolP) != C_EXT)
6557 {
6558 S_SET_STORAGE_CLASS (symbolP, C_STAT);
6559 }
6560 #endif /* OBJ_COFF */
6561
6562 #ifdef S_SET_SIZE
6563 S_SET_SIZE (symbolP, temp);
6564 #endif
6565 }
6566 else
6567 as_bad (_("symbol `%s' is already defined"), S_GET_NAME (symbolP));
6568
6569 subseg_set (current_seg, current_subseg);
6570
6571 demand_empty_rest_of_line ();
6572 }
6573
6574 static void
6575 insert_reg (const struct reg_entry *r, struct hash_control *htab)
6576 {
6577 int i = 0;
6578 int len = strlen (r->name) + 2;
6579 char *buf = xmalloc (len);
6580 char *buf2 = xmalloc (len);
6581
6582 strcpy (buf + i, r->name);
6583 for (i = 0; buf[i]; i++)
6584 {
6585 buf2[i] = TOUPPER (buf[i]);
6586 }
6587 buf2[i] = '\0';
6588
6589 hash_insert (htab, buf, (void *) r);
6590 hash_insert (htab, buf2, (void *) r);
6591 }
6592
6593 static void
6594 build_reg_hsh (struct reg_map *map)
6595 {
6596 const struct reg_entry *r;
6597
6598 if ((map->htab = hash_new ()) == NULL)
6599 {
6600 as_fatal (_("virtual memory exhausted"));
6601 }
6602 for (r = map->names; r->name != NULL; r++)
6603 {
6604 insert_reg (r, map->htab);
6605 }
6606 }
6607
6608 void
6609 md_begin (void)
6610 {
6611 unsigned int i;
6612 segT seg;
6613 subsegT subseg;
6614
6615 if ((score_ops_hsh = hash_new ()) == NULL)
6616 as_fatal (_("virtual memory exhausted"));
6617
6618 build_score_ops_hsh ();
6619
6620 if ((dependency_insn_hsh = hash_new ()) == NULL)
6621 as_fatal (_("virtual memory exhausted"));
6622
6623 build_dependency_insn_hsh ();
6624
6625 for (i = (int)REG_TYPE_FIRST; i < (int)REG_TYPE_MAX; i++)
6626 build_reg_hsh (all_reg_maps + i);
6627
6628 /* Initialize dependency vector. */
6629 init_dependency_vector ();
6630
6631 bfd_set_arch_mach (stdoutput, TARGET_ARCH, 0);
6632 seg = now_seg;
6633 subseg = now_subseg;
6634 pdr_seg = subseg_new (".pdr", (subsegT) 0);
6635 (void)bfd_set_section_flags (stdoutput, pdr_seg, SEC_READONLY | SEC_RELOC | SEC_DEBUGGING);
6636 (void)bfd_set_section_alignment (stdoutput, pdr_seg, 2);
6637 subseg_set (seg, subseg);
6638
6639 if (USE_GLOBAL_POINTER_OPT)
6640 bfd_set_gp_size (stdoutput, g_switch_value);
6641 }
6642
6643
6644 const pseudo_typeS md_pseudo_table[] =
6645 {
6646 {"bss", s_score_bss, 0},
6647 {"text", s_score_text, 0},
6648 {"word", cons, 4},
6649 {"long", cons, 4},
6650 {"extend", float_cons, 'x'},
6651 {"ldouble", float_cons, 'x'},
6652 {"packed", float_cons, 'p'},
6653 {"end", s_score_end, 0},
6654 {"ent", s_score_ent, 0},
6655 {"frame", s_score_frame, 0},
6656 {"rdata", s_change_sec, 'r'},
6657 {"sdata", s_change_sec, 's'},
6658 {"set", s_score_set, 0},
6659 {"mask", s_score_mask, 'R'},
6660 {"dword", cons, 8},
6661 {"lcomm", s_score_lcomm, 1},
6662 {"section", score_s_section, 0},
6663 {"cpload", s_score_cpload, 0},
6664 {"cprestore", s_score_cprestore, 0},
6665 {"gpword", s_score_gpword, 0},
6666 {"cpadd", s_score_cpadd, 0},
6667 {0, 0, 0}
6668 };
6669
This page took 0.362385 seconds and 5 git commands to generate.