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