1 /* tc-score.c -- Assembler for Score
2 Copyright 2006 Free Software Foundation, Inc.
4 Mei Ligang (ligang@sunnorth.com.cn)
5 Pei-Lin Tsai (pltsai@sunplus.com)
7 This file is part of GAS, the GNU Assembler.
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)
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.
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
27 #include "safe-ctype.h"
28 #include "opcode/score-inst.h"
29 #include "opcode/score-datadep.h"
30 #include "struc-symbol.h"
33 #include "elf/score.h"
34 #include "dwarf2dbg.h"
38 #define PIC_CALL_REG 29
39 #define MAX_LITERAL_POOL_SIZE 1024
40 #define FAIL 0x80000000
44 #define RELAX_INST_NUM 3
47 /* For score5u : div/mul will pop warning message, mmu/alw/asw will pop error message. */
48 #define BAD_ARGS _("bad arguments to instruction")
49 #define BAD_PC _("r15 not allowed here")
50 #define BAD_COND _("instruction is not conditional")
51 #define ERR_NO_ACCUM _("acc0 expected")
52 #define ERR_FOR_SCORE5U_MUL_DIV _("div / mul are reserved instructions")
53 #define ERR_FOR_SCORE5U_MMU _("This architecture doesn't support mmu")
54 #define ERR_FOR_SCORE5U_ATOMIC _("This architecture doesn't support atomic instruction")
55 #define LONG_LABEL_LEN _("the label length is longer than 1024");
56 #define BAD_SKIP_COMMA BAD_ARGS
57 #define BAD_GARBAGE _("garbage following instruction");
59 #define skip_whitespace(str) while (*(str) == ' ') ++(str)
61 /* The name of the readonly data section. */
62 #define RDATA_SECTION_NAME (OUTPUT_FLAVOR == bfd_target_aout_flavour \
64 : OUTPUT_FLAVOR == bfd_target_ecoff_flavour \
66 : OUTPUT_FLAVOR == bfd_target_coff_flavour \
68 : OUTPUT_FLAVOR == bfd_target_elf_flavour \
72 #define RELAX_ENCODE(old, new, type, reloc1, reloc2, opt) \
81 #define RELAX_OLD(i) (((i) >> 23) & 0x7f)
82 #define RELAX_NEW(i) (((i) >> 16) & 0x7f)
83 #define RELAX_TYPE(i) (((i) >> 9) & 0x7f)
84 #define RELAX_RELOC1(i) ((valueT) ((i) >> 5) & 0xf)
85 #define RELAX_RELOC2(i) ((valueT) ((i) >> 1) & 0xf)
86 #define RELAX_OPT(i) ((i) & 1)
87 #define RELAX_OPT_CLEAR(i) ((i) & ~1)
89 #define SET_INSN_ERROR(s) (inst.error = (s))
90 #define INSN_IS_PCE_P(s) (strstr (str, "||") != NULL)
92 #define GET_INSN_CLASS(type) (get_insn_class_from_type (type))
94 #define GET_INSN_SIZE(type) ((GET_INSN_CLASS (type) == INSN_CLASS_16) \
95 ? INSN16_SIZE : INSN_SIZE)
97 /* This array holds the chars that always start a comment. If the
98 pre-processor is disabled, these aren't very useful. */
99 const char comment_chars
[] = "#";
100 const char line_comment_chars
[] = "#";
101 const char line_separator_chars
[] = ";";
103 /* Chars that can be used to separate mant from exp in floating point numbers. */
104 const char EXP_CHARS
[] = "eE";
105 const char FLT_CHARS
[] = "rRsSfFdDxXeEpP";
107 fragS
*score_fragp
= 0;
108 static int fix_data_dependency
= 0;
109 static int warn_fix_data_dependency
= 1;
110 static int score7
= 1;
111 static int university_version
= 0;
113 static int in_my_get_expression
= 0;
115 #define USE_GLOBAL_POINTER_OPT 1
116 #define SCORE_BI_ENDIAN
118 /* Default, pop warning message when using r1. */
121 /* Default will do instruction relax, -O0 will set g_opt = 0. */
122 static unsigned int g_opt
= 1;
124 /* The size of the small data section. */
125 static unsigned int g_switch_value
= 8;
128 /* Pre-defined "_GLOBAL_OFFSET_TABLE_" */
133 enum score_pic_level score_pic
= NO_PIC
;
135 #define INSN_NAME_LEN 16
138 char name
[INSN_NAME_LEN
];
139 unsigned long instruction
;
140 unsigned long relax_inst
;
143 enum score_insn_type type
;
144 char str
[MAX_LITERAL_POOL_SIZE
];
147 char reg
[INSN_NAME_LEN
];
150 bfd_reloc_code_real_type type
;
155 struct score_it inst
;
160 unsigned long reg_mask
;
161 unsigned long reg_offset
;
162 unsigned long fpreg_mask
;
164 unsigned long frame_offset
;
165 unsigned long frame_reg
;
166 unsigned long pc_reg
;
170 static procS cur_proc
;
171 static procS
*cur_proc_ptr
;
174 #define SCORE7_PIPELINE 7
175 #define SCORE5_PIPELINE 5
176 static int vector_size
= SCORE7_PIPELINE
;
177 struct score_it dependency_vector
[SCORE7_PIPELINE
];
179 /* Relax will need some padding for alignment. */
180 #define RELAX_PAD_BYTE 3
182 /* Number of littlenums required to hold an extended precision number. For md_atof. */
183 #define NUM_FLOAT_VALS 8
184 #define MAX_LITTLENUMS 6
185 LITTLENUM_TYPE fp_values
[NUM_FLOAT_VALS
][MAX_LITTLENUMS
];
187 /* Structure for a hash table entry for a register. */
194 static const struct reg_entry score_rn_table
[] =
196 {"r0", 0}, {"r1", 1}, {"r2", 2}, {"r3", 3},
197 {"r4", 4}, {"r5", 5}, {"r6", 6}, {"r7", 7},
198 {"r8", 8}, {"r9", 9}, {"r10", 10}, {"r11", 11},
199 {"r12", 12}, {"r13", 13}, {"r14", 14}, {"r15", 15},
200 {"r16", 16}, {"r17", 17}, {"r18", 18}, {"r19", 19},
201 {"r20", 20}, {"r21", 21}, {"r22", 22}, {"r23", 23},
202 {"r24", 24}, {"r25", 25}, {"r26", 26}, {"r27", 27},
203 {"r28", 28}, {"r29", 29}, {"r30", 30}, {"r31", 31},
207 static const struct reg_entry score_srn_table
[] =
209 {"sr0", 0}, {"sr1", 1}, {"sr2", 2},
213 static const struct reg_entry score_crn_table
[] =
215 {"cr0", 0}, {"cr1", 1}, {"cr2", 2}, {"cr3", 3},
216 {"cr4", 4}, {"cr5", 5}, {"cr6", 6}, {"cr7", 7},
217 {"cr8", 8}, {"cr9", 9}, {"cr10", 10}, {"cr11", 11},
218 {"cr12", 12}, {"cr13", 13}, {"cr14", 14}, {"cr15", 15},
219 {"cr16", 16}, {"cr17", 17}, {"cr18", 18}, {"cr19", 19},
220 {"cr20", 20}, {"cr21", 21}, {"cr22", 22}, {"cr23", 23},
221 {"cr24", 24}, {"cr25", 25}, {"cr26", 26}, {"cr27", 27},
222 {"cr28", 28}, {"cr29", 29}, {"cr30", 30}, {"cr31", 31},
228 const struct reg_entry
*names
;
230 struct hash_control
*htab
;
231 const char *expected
;
234 struct reg_map all_reg_maps
[] =
236 {score_rn_table
, 31, NULL
, N_("S+core register expected")},
237 {score_srn_table
, 2, NULL
, N_("S+core special-register expected")},
238 {score_crn_table
, 31, NULL
, N_("S+core co-processor register expected")},
241 static struct hash_control
*score_ops_hsh
= NULL
;
243 static struct hash_control
*dependency_insn_hsh
= NULL
;
245 /* Enumeration matching entries in table above. */
249 #define REG_TYPE_FIRST REG_TYPE_SCORE
250 REG_TYPE_SCORE_SR
= 1,
251 REG_TYPE_SCORE_CR
= 2,
255 typedef struct literalS
257 struct expressionS exp
;
258 struct score_it
*inst
;
262 literalT literals
[MAX_LITERAL_POOL_SIZE
];
264 static void do_ldst_insn (char *);
265 static void do_crdcrscrsimm5 (char *);
266 static void do_ldst_unalign (char *);
267 static void do_ldst_atomic (char *);
268 static void do_ldst_cop (char *);
269 static void do_macro_li_rdi32 (char *);
270 static void do_macro_la_rdi32 (char *);
271 static void do_macro_rdi32hi (char *);
272 static void do_macro_rdi32lo (char *);
273 static void do_macro_mul_rdrsrs (char *);
274 static void do_macro_ldst_label (char *);
275 static void do_branch (char *);
276 static void do_jump (char *);
277 static void do_empty (char *);
278 static void do_rdrsrs (char *);
279 static void do_rdsi16 (char *);
280 static void do_rdrssi14 (char *);
281 static void do_sub_rdsi16 (char *);
282 static void do_sub_rdi16 (char *);
283 static void do_sub_rdrssi14 (char *);
284 static void do_rdrsi5 (char *);
285 static void do_rdrsi14 (char *);
286 static void do_rdi16 (char *);
287 static void do_xrsi5 (char *);
288 static void do_rdrs (char *);
289 static void do_rdxrs (char *);
290 static void do_rsrs (char *);
291 static void do_rdcrs (char *);
292 static void do_rdsrs (char *);
293 static void do_rd (char *);
294 static void do_rs (char *);
295 static void do_i15 (char *);
296 static void do_xi5x (char *);
297 static void do_ceinst (char *);
298 static void do_cache (char *);
299 static void do16_rdrs (char *);
300 static void do16_rs (char *);
301 static void do16_xrs (char *);
302 static void do16_mv_rdrs (char *);
303 static void do16_hrdrs (char *);
304 static void do16_rdhrs (char *);
305 static void do16_rdi4 (char *);
306 static void do16_rdi5 (char *);
307 static void do16_xi5 (char *);
308 static void do16_ldst_insn (char *);
309 static void do16_ldst_imm_insn (char *);
310 static void do16_push_pop (char *);
311 static void do16_branch (char *);
312 static void do16_jump (char *);
313 static void do_rdi16_pic (char *);
314 static void do_addi_s_pic (char *);
315 static void do_addi_u_pic (char *);
316 static void do_lw_pic (char *);
318 static const struct asm_opcode score_ldst_insns
[] =
320 {"lw", 0x20000000, 0x3e000000, 0x2008, Rd_rvalueRs_SI15
, do_ldst_insn
},
321 {"lw", 0x06000000, 0x3e000007, 0x8000, Rd_rvalueRs_preSI12
, do_ldst_insn
},
322 {"lw", 0x0e000000, 0x3e000007, 0x200a, Rd_rvalueRs_postSI12
, do_ldst_insn
},
323 {"lh", 0x22000000, 0x3e000000, 0x2009, Rd_rvalueRs_SI15
, do_ldst_insn
},
324 {"lh", 0x06000001, 0x3e000007, 0x8000, Rd_rvalueRs_preSI12
, do_ldst_insn
},
325 {"lh", 0x0e000001, 0x3e000007, 0x8000, Rd_rvalueRs_postSI12
, do_ldst_insn
},
326 {"lhu", 0x24000000, 0x3e000000, 0x8000, Rd_rvalueRs_SI15
, do_ldst_insn
},
327 {"lhu", 0x06000002, 0x3e000007, 0x8000, Rd_rvalueRs_preSI12
, do_ldst_insn
},
328 {"lhu", 0x0e000002, 0x3e000007, 0x8000, Rd_rvalueRs_postSI12
, do_ldst_insn
},
329 {"lb", 0x26000000, 0x3e000000, 0x8000, Rd_rvalueRs_SI15
, do_ldst_insn
},
330 {"lb", 0x06000003, 0x3e000007, 0x8000, Rd_rvalueRs_preSI12
, do_ldst_insn
},
331 {"lb", 0x0e000003, 0x3e000007, 0x8000, Rd_rvalueRs_postSI12
, do_ldst_insn
},
332 {"sw", 0x28000000, 0x3e000000, 0x200c, Rd_lvalueRs_SI15
, do_ldst_insn
},
333 {"sw", 0x06000004, 0x3e000007, 0x200e, Rd_lvalueRs_preSI12
, do_ldst_insn
},
334 {"sw", 0x0e000004, 0x3e000007, 0x8000, Rd_lvalueRs_postSI12
, do_ldst_insn
},
335 {"sh", 0x2a000000, 0x3e000000, 0x200d, Rd_lvalueRs_SI15
, do_ldst_insn
},
336 {"sh", 0x06000005, 0x3e000007, 0x8000, Rd_lvalueRs_preSI12
, do_ldst_insn
},
337 {"sh", 0x0e000005, 0x3e000007, 0x8000, Rd_lvalueRs_postSI12
, do_ldst_insn
},
338 {"lbu", 0x2c000000, 0x3e000000, 0x200b, Rd_rvalueRs_SI15
, do_ldst_insn
},
339 {"lbu", 0x06000006, 0x3e000007, 0x8000, Rd_rvalueRs_preSI12
, do_ldst_insn
},
340 {"lbu", 0x0e000006, 0x3e000007, 0x8000, Rd_rvalueRs_postSI12
, do_ldst_insn
},
341 {"sb", 0x2e000000, 0x3e000000, 0x200f, Rd_lvalueRs_SI15
, do_ldst_insn
},
342 {"sb", 0x06000007, 0x3e000007, 0x8000, Rd_lvalueRs_preSI12
, do_ldst_insn
},
343 {"sb", 0x0e000007, 0x3e000007, 0x8000, Rd_lvalueRs_postSI12
, do_ldst_insn
},
346 static const struct asm_opcode score_insns
[] =
348 {"abs", 0x3800000a, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
349 {"abs.s", 0x3800004b, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
350 {"add", 0x00000010, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
351 {"add.c", 0x00000011, 0x3e0003ff, 0x2000, Rd_Rs_Rs
, do_rdrsrs
},
352 {"add.s", 0x38000048, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
353 {"addc", 0x00000012, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
354 {"addc.c", 0x00000013, 0x3e0003ff, 0x0009, Rd_Rs_Rs
, do_rdrsrs
},
355 {"addi", 0x02000000, 0x3e0e0001, 0x8000, Rd_SI16
, do_rdsi16
},
356 {"addi.c", 0x02000001, 0x3e0e0001, 0x8000, Rd_SI16
, do_rdsi16
},
357 {"addis", 0x0a000000, 0x3e0e0001, 0x8000, Rd_SI16
, do_rdi16
},
358 {"addis.c", 0x0a000001, 0x3e0e0001, 0x8000, Rd_SI16
, do_rdi16
},
359 {"addri", 0x10000000, 0x3e000001, 0x8000, Rd_Rs_SI14
, do_rdrssi14
},
360 {"addri.c", 0x10000001, 0x3e000001, 0x8000, Rd_Rs_SI14
, do_rdrssi14
},
361 {"addc!", 0x0009, 0x700f, 0x00000013, Rd_Rs
, do16_rdrs
},
362 {"add!", 0x2000, 0x700f, 0x00000011, Rd_Rs
, do16_rdrs
},
363 {"addei!", 0x6000 , 0x7087, 0x02000001, Rd_I4
, do16_rdi4
},
364 {"subi", 0x02000000, 0x3e0e0001, 0x8000, Rd_SI16
, do_sub_rdsi16
},
365 {"subi.c", 0x02000001, 0x3e0e0001, 0x8000, Rd_SI16
, do_sub_rdsi16
},
366 {"subis", 0x0a000000, 0x3e0e0001, 0x8000, Rd_SI16
, do_sub_rdi16
},
367 {"subis.c", 0x0a000001, 0x3e0e0001, 0x8000, Rd_SI16
, do_sub_rdi16
},
368 {"subri", 0x10000000, 0x3e000001, 0x8000, Rd_Rs_SI14
, do_sub_rdrssi14
},
369 {"subri.c", 0x10000001, 0x3e000001, 0x8000, Rd_Rs_SI14
, do_sub_rdrssi14
},
370 {"and", 0x00000020, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
371 {"and.c", 0x00000021, 0x3e0003ff, 0x2004, Rd_Rs_Rs
, do_rdrsrs
},
372 {"andi", 0x02080000, 0x3e0e0001, 0x8000, Rd_I16
, do_rdi16
},
373 {"andi.c", 0x02080001, 0x3e0e0001, 0x8000, Rd_I16
, do_rdi16
},
374 {"andis", 0x0a080000, 0x3e0e0001, 0x8000, Rd_I16
, do_rdi16
},
375 {"andis.c", 0x0a080001, 0x3e0e0001, 0x8000, Rd_I16
, do_rdi16
},
376 {"andri", 0x18000000, 0x3e000001, 0x8000, Rd_Rs_I14
, do_rdrsi14
},
377 {"andri.c", 0x18000001, 0x3e000001, 0x8000, Rd_Rs_I14
, do_rdrsi14
},
378 {"and!", 0x2004, 0x700f, 0x00000021, Rd_Rs
, do16_rdrs
},
379 {"bcs", 0x08000000, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
380 {"bcc", 0x08000400, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
381 {"bcnz", 0x08003800, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
382 {"bcsl", 0x08000001, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
383 {"bccl", 0x08000401, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
384 {"bcnzl", 0x08003801, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
385 {"bcs!", 0x4000, 0x7f00, 0x08000000, PC_DISP8div2
, do16_branch
},
386 {"bcc!", 0x4100, 0x7f00, 0x08000400, PC_DISP8div2
, do16_branch
},
387 {"bcnz!", 0x4e00, 0x7f00, 0x08003800, PC_DISP8div2
, do16_branch
},
388 {"beq", 0x08001000, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
389 {"beql", 0x08001001, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
390 {"beq!", 0x4400, 0x7f00, 0x08001000, PC_DISP8div2
, do16_branch
},
391 {"bgtu", 0x08000800, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
392 {"bgt", 0x08001800, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
393 {"bge", 0x08002000, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
394 {"bgtul", 0x08000801, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
395 {"bgtl", 0x08001801, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
396 {"bgel", 0x08002001, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
397 {"bgtu!", 0x4200, 0x7f00, 0x08000800, PC_DISP8div2
, do16_branch
},
398 {"bgt!", 0x4600, 0x7f00, 0x08001800, PC_DISP8div2
, do16_branch
},
399 {"bge!", 0x4800, 0x7f00, 0x08002000, PC_DISP8div2
, do16_branch
},
400 {"bitclr.c", 0x00000029, 0x3e0003ff, 0x6004, Rd_Rs_I5
, do_rdrsi5
},
401 {"bitrev", 0x3800000c, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
402 {"bitset.c", 0x0000002b, 0x3e0003ff, 0x6005, Rd_Rs_I5
, do_rdrsi5
},
403 {"bittst.c", 0x0000002d, 0x3e0003ff, 0x6006, x_Rs_I5
, do_xrsi5
},
404 {"bittgl.c", 0x0000002f, 0x3e0003ff, 0x6007, Rd_Rs_I5
, do_rdrsi5
},
405 {"bitclr!", 0x6004, 0x7007, 0x00000029, Rd_I5
, do16_rdi5
},
406 {"bitset!", 0x6005, 0x7007, 0x0000002b, Rd_I5
, do16_rdi5
},
407 {"bittst!", 0x6006, 0x7007, 0x0000002d, Rd_I5
, do16_rdi5
},
408 {"bittgl!", 0x6007, 0x7007, 0x0000002f, Rd_I5
, do16_rdi5
},
409 {"bleu", 0x08000c00, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
410 {"ble", 0x08001c00, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
411 {"blt", 0x08002400, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
412 {"bleul", 0x08000c01, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
413 {"blel", 0x08001c01, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
414 {"bltl", 0x08002401, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
415 {"bl", 0x08003c01, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
416 {"bleu!", 0x4300, 0x7f00, 0x08000c00, PC_DISP8div2
, do16_branch
},
417 {"ble!", 0x4700, 0x7f00, 0x08001c00, PC_DISP8div2
, do16_branch
},
418 {"blt!", 0x4900, 0x7f00, 0x08002400, PC_DISP8div2
, do16_branch
},
419 {"bmi", 0x08002800, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
420 {"bmil", 0x08002801, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
421 {"bmi!", 0x00004a00, 0x00007f00, 0x08002800, PC_DISP8div2
, do16_branch
},
422 {"bne", 0x08001400, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
423 {"bnel", 0x08001401, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
424 {"bne!", 0x4500, 0x7f00, 0x08001400, PC_DISP8div2
, do16_branch
},
425 {"bpl", 0x08002c00, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
426 {"bpll", 0x08002c01, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
427 {"bpl!", 0x4b00, 0x7f00, 0x08002c00, PC_DISP8div2
, do16_branch
},
428 {"brcs", 0x00000008, 0x3e007fff, 0x0004, x_Rs_x
, do_rs
},
429 {"brcc", 0x00000408, 0x3e007fff, 0x0104, x_Rs_x
, do_rs
},
430 {"brgtu", 0x00000808, 0x3e007fff, 0x0204, x_Rs_x
, do_rs
},
431 {"brleu", 0x00000c08, 0x3e007fff, 0x0304, x_Rs_x
, do_rs
},
432 {"breq", 0x00001008, 0x3e007fff, 0x0404, x_Rs_x
, do_rs
},
433 {"brne", 0x00001408, 0x3e007fff, 0x0504, x_Rs_x
, do_rs
},
434 {"brgt", 0x00001808, 0x3e007fff, 0x0604, x_Rs_x
, do_rs
},
435 {"brle", 0x00001c08, 0x3e007fff, 0x0704, x_Rs_x
, do_rs
},
436 {"brge", 0x00002008, 0x3e007fff, 0x0804, x_Rs_x
, do_rs
},
437 {"brlt", 0x00002408, 0x3e007fff, 0x0904, x_Rs_x
, do_rs
},
438 {"brmi", 0x00002808, 0x3e007fff, 0x0a04, x_Rs_x
, do_rs
},
439 {"brpl", 0x00002c08, 0x3e007fff, 0x0b04, x_Rs_x
, do_rs
},
440 {"brvs", 0x00003008, 0x3e007fff, 0x0c04, x_Rs_x
, do_rs
},
441 {"brvc", 0x00003408, 0x3e007fff, 0x0d04, x_Rs_x
, do_rs
},
442 {"brcnz", 0x00003808, 0x3e007fff, 0x0e04, x_Rs_x
, do_rs
},
443 {"br", 0x00003c08, 0x3e007fff, 0x0f04, x_Rs_x
, do_rs
},
444 {"brcsl", 0x00000009, 0x3e007fff, 0x000c, x_Rs_x
, do_rs
},
445 {"brccl", 0x00000409, 0x3e007fff, 0x010c, x_Rs_x
, do_rs
},
446 {"brgtul", 0x00000809, 0x3e007fff, 0x020c, x_Rs_x
, do_rs
},
447 {"brleul", 0x00000c09, 0x3e007fff, 0x030c, x_Rs_x
, do_rs
},
448 {"breql", 0x00001009, 0x3e007fff, 0x040c, x_Rs_x
, do_rs
},
449 {"brnel", 0x00001409, 0x3e007fff, 0x050c, x_Rs_x
, do_rs
},
450 {"brgtl", 0x00001809, 0x3e007fff, 0x060c, x_Rs_x
, do_rs
},
451 {"brlel", 0x00001c09, 0x3e007fff, 0x070c, x_Rs_x
, do_rs
},
452 {"brgel", 0x00002009, 0x3e007fff, 0x080c, x_Rs_x
, do_rs
},
453 {"brltl", 0x00002409, 0x3e007fff, 0x090c, x_Rs_x
, do_rs
},
454 {"brmil", 0x00002809, 0x3e007fff, 0x0a0c, x_Rs_x
, do_rs
},
455 {"brpll", 0x00002c09, 0x3e007fff, 0x0b0c, x_Rs_x
, do_rs
},
456 {"brvsl", 0x00003009, 0x3e007fff, 0x0c0c, x_Rs_x
, do_rs
},
457 {"brvcl", 0x00003409, 0x3e007fff, 0x0d0c, x_Rs_x
, do_rs
},
458 {"brcnzl", 0x00003809, 0x3e007fff, 0x0e0c, x_Rs_x
, do_rs
},
459 {"brl", 0x00003c09, 0x3e007fff, 0x0f0c, x_Rs_x
, do_rs
},
460 {"brcs!", 0x0004, 0x7f0f, 0x00000008, x_Rs
, do16_xrs
},
461 {"brcc!", 0x0104, 0x7f0f, 0x00000408, x_Rs
, do16_xrs
},
462 {"brgtu!", 0x0204, 0x7f0f, 0x00000808, x_Rs
, do16_xrs
},
463 {"brleu!", 0x0304, 0x7f0f, 0x00000c08, x_Rs
, do16_xrs
},
464 {"breq!", 0x0404, 0x7f0f, 0x00001008, x_Rs
, do16_xrs
},
465 {"brne!", 0x0504, 0x7f0f, 0x00001408, x_Rs
, do16_xrs
},
466 {"brgt!", 0x0604, 0x7f0f, 0x00001808, x_Rs
, do16_xrs
},
467 {"brle!", 0x0704, 0x7f0f, 0x00001c08, x_Rs
, do16_xrs
},
468 {"brge!", 0x0804, 0x7f0f, 0x00002008, x_Rs
, do16_xrs
},
469 {"brlt!", 0x0904, 0x7f0f, 0x00002408, x_Rs
, do16_xrs
},
470 {"brmi!", 0x0a04, 0x7f0f, 0x00002808, x_Rs
, do16_xrs
},
471 {"brpl!", 0x0b04, 0x7f0f, 0x00002c08, x_Rs
, do16_xrs
},
472 {"brvs!", 0x0c04, 0x7f0f, 0x00003008, x_Rs
, do16_xrs
},
473 {"brvc!", 0x0d04, 0x7f0f, 0x00003408, x_Rs
, do16_xrs
},
474 {"brcnz!", 0x0e04, 0x7f0f, 0x00003808, x_Rs
, do16_xrs
},
475 {"br!", 0x0f04, 0x7f0f, 0x00003c08, x_Rs
, do16_xrs
},
476 {"brcsl!", 0x000c, 0x7f0f, 0x00000009, x_Rs
, do16_xrs
},
477 {"brccl!", 0x010c, 0x7f0f, 0x00000409, x_Rs
, do16_xrs
},
478 {"brgtul!", 0x020c, 0x7f0f, 0x00000809, x_Rs
, do16_xrs
},
479 {"brleul!", 0x030c, 0x7f0f, 0x00000c09, x_Rs
, do16_xrs
},
480 {"breql!", 0x040c, 0x7f0f, 0x00001009, x_Rs
, do16_xrs
},
481 {"brnel!", 0x050c, 0x7f0f, 0x00001409, x_Rs
, do16_xrs
},
482 {"brgtl!", 0x060c, 0x7f0f, 0x00001809, x_Rs
, do16_xrs
},
483 {"brlel!", 0x070c, 0x7f0f, 0x00001c09, x_Rs
, do16_xrs
},
484 {"brgel!", 0x080c, 0x7f0f, 0x00002009, x_Rs
, do16_xrs
},
485 {"brltl!", 0x090c, 0x7f0f, 0x00002409, x_Rs
, do16_xrs
},
486 {"brmil!", 0x0a0c, 0x7f0f, 0x00002809, x_Rs
, do16_xrs
},
487 {"brpll!", 0x0b0c, 0x7f0f, 0x00002c09, x_Rs
, do16_xrs
},
488 {"brvsl!", 0x0c0c, 0x7f0f, 0x00003009, x_Rs
, do16_xrs
},
489 {"brvcl!", 0x0d0c, 0x7f0f, 0x00003409, x_Rs
, do16_xrs
},
490 {"brcnzl!", 0x0e0c, 0x7f0f, 0x00003809, x_Rs
, do16_xrs
},
491 {"brl!", 0x0f0c, 0x7f0f, 0x00003c09, x_Rs
, do16_xrs
},
492 {"bvs", 0x08003000, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
493 {"bvc", 0x08003400, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
494 {"bvsl", 0x08003001, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
495 {"bvcl", 0x08003401, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
496 {"bvs!", 0x4c00, 0x7f00, 0x08003000, PC_DISP8div2
, do16_branch
},
497 {"bvc!", 0x4d00, 0x7f00, 0x08003400, PC_DISP8div2
, do16_branch
},
498 {"b!", 0x4f00, 0x7f00, 0x08003c00, PC_DISP8div2
, do16_branch
},
499 {"b", 0x08003c00, 0x3e007c01, 0x08003c00, PC_DISP19div2
, do_branch
},
500 {"cache", 0x30000000, 0x3ff00000, 0x8000, OP5_rvalueRs_SI15
, do_cache
},
501 {"ceinst", 0x38000000, 0x3e000000, 0x8000, I5_Rs_Rs_I5_OP5
, do_ceinst
},
502 {"clz", 0x3800000d, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
503 {"cmpteq.c", 0x00000019, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
504 {"cmptmi.c", 0x00100019, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
505 {"cmp.c", 0x00300019, 0x3ff003ff, 0x2003, x_Rs_Rs
, do_rsrs
},
506 {"cmpzteq.c", 0x0000001b, 0x3ff07fff, 0x8000, x_Rs_x
, do_rs
},
507 {"cmpztmi.c", 0x0010001b, 0x3ff07fff, 0x8000, x_Rs_x
, do_rs
},
508 {"cmpz.c", 0x0030001b, 0x3ff07fff, 0x8000, x_Rs_x
, do_rs
},
509 {"cmpi.c", 0x02040001, 0x3e0e0001, 0x8000, Rd_SI16
, do_rdsi16
},
510 {"cmp!", 0x2003, 0x700f, 0x00300019, Rd_Rs
, do16_rdrs
},
511 {"cop1", 0x0c00000c, 0x3e00001f, 0x8000, Rd_Rs_Rs_imm
, do_crdcrscrsimm5
},
512 {"cop2", 0x0c000014, 0x3e00001f, 0x8000, Rd_Rs_Rs_imm
, do_crdcrscrsimm5
},
513 {"cop3", 0x0c00001c, 0x3e00001f, 0x8000, Rd_Rs_Rs_imm
, do_crdcrscrsimm5
},
514 {"drte", 0x0c0000a4, 0x3e0003ff, 0x8000, NO_OPD
, do_empty
},
515 {"extsb", 0x00000058, 0x3e0003ff, 0x8000, Rd_Rs_x
, do_rdrs
},
516 {"extsb.c", 0x00000059, 0x3e0003ff, 0x8000, Rd_Rs_x
, do_rdrs
},
517 {"extsh", 0x0000005a, 0x3e0003ff, 0x8000, Rd_Rs_x
, do_rdrs
},
518 {"extsh.c", 0x0000005b, 0x3e0003ff, 0x8000, Rd_Rs_x
, do_rdrs
},
519 {"extzb", 0x0000005c, 0x3e0003ff, 0x8000, Rd_Rs_x
, do_rdrs
},
520 {"extzb.c", 0x0000005d, 0x3e0003ff, 0x8000, Rd_Rs_x
, do_rdrs
},
521 {"extzh", 0x0000005e, 0x3e0003ff, 0x8000, Rd_Rs_x
, do_rdrs
},
522 {"extzh.c", 0x0000005f, 0x3e0003ff, 0x8000, Rd_Rs_x
, do_rdrs
},
523 {"jl", 0x04000001, 0x3e000001, 0x8000, PC_DISP24div2
, do_jump
},
524 {"jl!", 0x3001, 0x7001, 0x04000001, PC_DISP11div2
, do16_jump
},
525 {"j!", 0x3000, 0x7001, 0x04000000, PC_DISP11div2
, do16_jump
},
526 {"j", 0x04000000, 0x3e000001, 0x8000, PC_DISP24div2
, do_jump
},
527 {"lbu!", 0x200b, 0x0000700f, 0x2c000000, Rd_rvalueRs
, do16_ldst_insn
},
528 {"lbup!", 0x7003, 0x7007, 0x2c000000, Rd_rvalueBP_I5
, do16_ldst_imm_insn
},
529 {"alw", 0x0000000c, 0x3e0003ff, 0x8000, Rd_rvalue32Rs
, do_ldst_atomic
},
530 {"lcb", 0x00000060, 0x3e0003ff, 0x8000, x_rvalueRs_post4
, do_ldst_unalign
},
531 {"lcw", 0x00000062, 0x3e0003ff, 0x8000, Rd_rvalueRs_post4
, do_ldst_unalign
},
532 {"lce", 0x00000066, 0x3e0003ff, 0x8000, Rd_rvalueRs_post4
, do_ldst_unalign
},
533 {"ldc1", 0x0c00000a, 0x3e00001f, 0x8000, Rd_rvalueRs_SI10
, do_ldst_cop
},
534 {"ldc2", 0x0c000012, 0x3e00001f, 0x8000, Rd_rvalueRs_SI10
, do_ldst_cop
},
535 {"ldc3", 0x0c00001a, 0x3e00001f, 0x8000, Rd_rvalueRs_SI10
, do_ldst_cop
},
536 {"lh!", 0x2009, 0x700f, 0x22000000, Rd_rvalueRs
, do16_ldst_insn
},
537 {"lhp!", 0x7001, 0x7007, 0x22000000, Rd_rvalueBP_I5
, do16_ldst_imm_insn
},
538 {"ldi", 0x020c0000, 0x3e0e0000, 0x5000, Rd_SI16
, do_rdsi16
},
539 {"ldis", 0x0a0c0000, 0x3e0e0000, 0x5000, Rd_I16
, do_rdi16
},
540 {"ldiu!", 0x5000, 0x7000, 0x020c0000, Rd_I8
, do16_ldst_imm_insn
},
541 {"lw!", 0x2008, 0x700f, 0x20000000, Rd_rvalueRs
, do16_ldst_insn
},
542 {"lwp!", 0x7000, 0x7007, 0x20000000, Rd_rvalueBP_I5
, do16_ldst_imm_insn
},
543 {"mfcel", 0x00000448, 0x3e007fff, 0x8000, Rd_x_x
, do_rd
},
544 {"mfcel!", 0x1001, 0x7f0f, 0x00000448, x_Rs
, do16_rs
},
545 {"mad", 0x38000000, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
546 {"mad.f!", 0x1004, 0x700f, 0x38000080, Rd_Rs
, do16_rdrs
},
547 {"madh", 0x38000203, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
548 {"madh.fs", 0x380002c3, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
549 {"madh.fs!", 0x100b, 0x700f, 0x380002c3, Rd_Rs
, do16_rdrs
},
550 {"madl", 0x38000002, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
551 {"madl.fs", 0x380000c2, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
552 {"madl.fs!", 0x100a, 0x700f, 0x380000c2, Rd_Rs
, do16_rdrs
},
553 {"madu", 0x38000020, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
554 {"madu!", 0x1005, 0x700f, 0x38000020, Rd_Rs
, do16_rdrs
},
555 {"mad.f", 0x38000080, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
556 {"max", 0x38000007, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
557 {"mazh", 0x38000303, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
558 {"mazh.f", 0x38000383, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
559 {"mazh.f!", 0x1009, 0x700f, 0x3800038c, Rd_Rs
, do16_rdrs
},
560 {"mazl", 0x38000102, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
561 {"mazl.f", 0x38000182, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
562 {"mazl.f!", 0x1008, 0x700f, 0x38000182, Rd_Rs
, do16_rdrs
},
563 {"mfceh", 0x00000848, 0x3e007fff, 0x8000, Rd_x_x
, do_rd
},
564 {"mfceh!", 0x1101, 0x7f0f, 0x00000848, x_Rs
, do16_rs
},
565 {"mfcehl", 0x00000c48, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
566 {"mfsr", 0x00000050, 0x3e0003ff, 0x8000, Rd_x_I5
, do_rdsrs
},
567 {"mfcr", 0x0c000001, 0x3e00001f, 0x8000, Rd_Rs_x
, do_rdcrs
},
568 {"mfc1", 0x0c000009, 0x3e00001f, 0x8000, Rd_Rs_x
, do_rdcrs
},
569 {"mfc2", 0x0c000011, 0x3e00001f, 0x8000, Rd_Rs_x
, do_rdcrs
},
570 {"mfc3", 0x0c000019, 0x3e00001f, 0x8000, Rd_Rs_x
, do_rdcrs
},
571 {"mfcc1", 0x0c00000f, 0x3e00001f, 0x8000, Rd_Rs_x
, do_rdcrs
},
572 {"mfcc2", 0x0c000017, 0x3e00001f, 0x8000, Rd_Rs_x
, do_rdcrs
},
573 {"mfcc3", 0x0c00001f, 0x3e00001f, 0x8000, Rd_Rs_x
, do_rdcrs
},
574 {"mhfl!", 0x0002, 0x700f, 0x00003c56, Rd_LowRs
, do16_hrdrs
},
575 {"min", 0x38000006, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
576 {"mlfh!", 0x0001, 0x700f, 0x00003c56, Rd_HighRs
, do16_rdhrs
},
577 {"msb", 0x38000001, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
578 {"msb.f!", 0x1006, 0x700f, 0x38000081, Rd_Rs
, do16_rdrs
},
579 {"msbh", 0x38000205, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
580 {"msbh.fs", 0x380002c5, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
581 {"msbh.fs!", 0x100f, 0x700f, 0x380002c5, Rd_Rs
, do16_rdrs
},
582 {"msbl", 0x38000004, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
583 {"msbl.fs", 0x380000c4, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
584 {"msbl.fs!", 0x100e, 0x700f, 0x380000c4, Rd_Rs
, do16_rdrs
},
585 {"msbu", 0x38000021, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
586 {"msbu!", 0x1007, 0x700f, 0x38000021, Rd_Rs
, do16_rdrs
},
587 {"msb.f", 0x38000081, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
588 {"mszh", 0x38000305, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
589 {"mszh.f", 0x38000385, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
590 {"mszh.f!", 0x100d, 0x700f, 0x38000385, Rd_Rs
, do16_rdrs
},
591 {"mszl", 0x38000104, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
592 {"mszl.f", 0x38000184, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
593 {"mszl.f!", 0x100c, 0x700f, 0x38000184, Rd_Rs
, do16_rdrs
},
594 {"mtcel!", 0x1000, 0x7f0f, 0x0000044a, x_Rs
, do16_rs
},
595 {"mtcel", 0x0000044a, 0x3e007fff, 0x8000, Rd_x_x
, do_rd
},
596 {"mtceh", 0x0000084a, 0x3e007fff, 0x8000, Rd_x_x
, do_rd
},
597 {"mtceh!", 0x1100, 0x7f0f, 0x0000084a, x_Rs
, do16_rs
},
598 {"mtcehl", 0x00000c4a, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
599 {"mtsr", 0x00000052, 0x3e0003ff, 0x8000, x_Rs_I5
, do_rdsrs
},
600 {"mtcr", 0x0c000000, 0x3e00001f, 0x8000, Rd_Rs_x
, do_rdcrs
},
601 {"mtc1", 0x0c000008, 0x3e00001f, 0x8000, Rd_Rs_x
, do_rdcrs
},
602 {"mtc2", 0x0c000010, 0x3e00001f, 0x8000, Rd_Rs_x
, do_rdcrs
},
603 {"mtc3", 0x0c000018, 0x3e00001f, 0x8000, Rd_Rs_x
, do_rdcrs
},
604 {"mtcc1", 0x0c00000e, 0x3e00001f, 0x8000, Rd_Rs_x
, do_rdcrs
},
605 {"mtcc2", 0x0c000016, 0x3e00001f, 0x8000, Rd_Rs_x
, do_rdcrs
},
606 {"mtcc3", 0x0c00001e, 0x3e00001f, 0x8000, Rd_Rs_x
, do_rdcrs
},
607 {"mul.f!", 0x1002, 0x700f, 0x00000041, Rd_Rs
, do16_rdrs
},
608 {"mulu!", 0x1003, 0x700f, 0x00000042, Rd_Rs
, do16_rdrs
},
609 {"mvcs", 0x00000056, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
610 {"mvcc", 0x00000456, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
611 {"mvgtu", 0x00000856, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
612 {"mvleu", 0x00000c56, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
613 {"mveq", 0x00001056, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
614 {"mvne", 0x00001456, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
615 {"mvgt", 0x00001856, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
616 {"mvle", 0x00001c56, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
617 {"mvge", 0x00002056, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
618 {"mvlt", 0x00002456, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
619 {"mvmi", 0x00002856, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
620 {"mvpl", 0x00002c56, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
621 {"mvvs", 0x00003056, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
622 {"mvvc", 0x00003456, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
623 {"mv", 0x00003c56, 0x3e007fff, 0x0003, Rd_Rs_x
, do_rdrs
},
624 {"mv!", 0x0003, 0x700f, 0x00003c56, Rd_Rs
, do16_mv_rdrs
},
625 {"neg", 0x0000001e, 0x3e0003ff, 0x8000, Rd_x_Rs
, do_rdxrs
},
626 {"neg.c", 0x0000001f, 0x3e0003ff, 0x2002, Rd_x_Rs
, do_rdxrs
},
627 {"neg!", 0x2002, 0x700f, 0x0000001f, Rd_Rs
, do16_rdrs
},
628 {"nop", 0x00000000, 0x3e0003ff, 0x0000, NO_OPD
, do_empty
},
629 {"not", 0x00000024, 0x3e0003ff, 0x8000, Rd_Rs_x
, do_rdrs
},
630 {"not.c", 0x00000025, 0x3e0003ff, 0x2006, Rd_Rs_x
, do_rdrs
},
631 {"nop!", 0x0000, 0x700f, 0x00000000, NO16_OPD
, do_empty
},
632 {"not!", 0x2006, 0x700f, 0x00000025, Rd_Rs
, do16_rdrs
},
633 {"or", 0x00000022, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
634 {"or.c", 0x00000023, 0x3e0003ff, 0x2005, Rd_Rs_Rs
, do_rdrsrs
},
635 {"ori", 0x020a0000, 0x3e0e0001, 0x8000, Rd_I16
, do_rdi16
},
636 {"ori.c", 0x020a0001, 0x3e0e0001, 0x8000, Rd_I16
, do_rdi16
},
637 {"oris", 0x0a0a0000, 0x3e0e0001, 0x8000, Rd_I16
, do_rdi16
},
638 {"oris.c", 0x0a0a0001, 0x3e0e0001, 0x8000, Rd_I16
, do_rdi16
},
639 {"orri", 0x1a000000, 0x3e000001, 0x8000, Rd_Rs_I14
, do_rdrsi14
},
640 {"orri.c", 0x1a000001, 0x3e000001, 0x8000, Rd_Rs_I14
, do_rdrsi14
},
641 {"or!", 0x2005, 0x700f, 0x00000023, Rd_Rs
, do16_rdrs
},
642 {"pflush", 0x0000000a, 0x3e0003ff, 0x8000, NO_OPD
, do_empty
},
643 {"pop!", 0x200a, 0x700f, 0x0e000000, Rd_rvalueRs
, do16_push_pop
},
644 {"push!", 0x200e, 0x700f, 0x06000004, Rd_lvalueRs
, do16_push_pop
},
645 {"ror", 0x00000038, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
646 {"ror.c", 0x00000039, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
647 {"rorc.c", 0x0000003b, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
648 {"rol", 0x0000003c, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
649 {"rol.c", 0x0000003d, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
650 {"rolc.c", 0x0000003f, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
651 {"rori", 0x00000078, 0x3e0003ff, 0x8000, Rd_Rs_I5
, do_rdrsi5
},
652 {"rori.c", 0x00000079, 0x3e0003ff, 0x8000, Rd_Rs_I5
, do_rdrsi5
},
653 {"roric.c", 0x0000007b, 0x3e0003ff, 0x8000, Rd_Rs_I5
, do_rdrsi5
},
654 {"roli", 0x0000007c, 0x3e0003ff, 0x8000, Rd_Rs_I5
, do_rdrsi5
},
655 {"roli.c", 0x0000007d, 0x3e0003ff, 0x8000, Rd_Rs_I5
, do_rdrsi5
},
656 {"rolic.c", 0x0000007f, 0x3e0003ff, 0x8000, Rd_Rs_I5
, do_rdrsi5
},
657 {"rte", 0x0c000084, 0x3e0003ff, 0x8000, NO_OPD
, do_empty
},
658 {"sb!", 0x200f, 0x700f, 0x2e000000, Rd_lvalueRs
, do16_ldst_insn
},
659 {"sbp!", 0x7007, 0x7007, 0x2e000000, Rd_lvalueBP_I5
, do16_ldst_imm_insn
},
660 {"asw", 0x0000000e, 0x3e0003ff, 0x8000, Rd_lvalue32Rs
, do_ldst_atomic
},
661 {"scb", 0x00000068, 0x3e0003ff, 0x8000, Rd_lvalueRs_post4
, do_ldst_unalign
},
662 {"scw", 0x0000006a, 0x3e0003ff, 0x8000, Rd_lvalueRs_post4
, do_ldst_unalign
},
663 {"sce", 0x0000006e, 0x3e0003ff, 0x8000, x_lvalueRs_post4
, do_ldst_unalign
},
664 {"sdbbp", 0x00000006, 0x3e0003ff, 0x6002, x_I5_x
, do_xi5x
},
665 {"sdbbp!", 0x6002, 0x7007, 0x00000006, Rd_I5
, do16_xi5
},
666 {"sh!", 0x200d, 0x700f, 0x2a000000, Rd_lvalueRs
, do16_ldst_insn
},
667 {"shp!", 0x7005, 0x7007, 0x2a000000, Rd_lvalueBP_I5
, do16_ldst_imm_insn
},
668 {"sleep", 0x0c0000c4, 0x3e0003ff, 0x8000, NO_OPD
, do_empty
},
669 {"sll", 0x00000030, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
670 {"sll.c", 0x00000031, 0x3e0003ff, 0x0008, Rd_Rs_Rs
, do_rdrsrs
},
671 {"sll.s", 0x3800004e, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
672 {"slli", 0x00000070, 0x3e0003ff, 0x8000, Rd_Rs_I5
, do_rdrsi5
},
673 {"slli.c", 0x00000071, 0x3e0003ff, 0x6001, Rd_Rs_I5
, do_rdrsi5
},
674 {"sll!", 0x0008, 0x700f, 0x00000031, Rd_Rs
, do16_rdrs
},
675 {"slli!", 0x6001, 0x7007, 0x00000071, Rd_I5
, do16_rdi5
},
676 {"srl", 0x00000034, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
677 {"srl.c", 0x00000035, 0x3e0003ff, 0x000a, Rd_Rs_Rs
, do_rdrsrs
},
678 {"sra", 0x00000036, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
679 {"sra.c", 0x00000037, 0x3e0003ff, 0x000b, Rd_Rs_Rs
, do_rdrsrs
},
680 {"srli", 0x00000074, 0x3e0003ff, 0x8000, Rd_Rs_I5
, do_rdrsi5
},
681 {"srli.c", 0x00000075, 0x3e0003ff, 0x6003, Rd_Rs_I5
, do_rdrsi5
},
682 {"srai", 0x00000076, 0x3e0003ff, 0x8000, Rd_Rs_I5
, do_rdrsi5
},
683 {"srai.c", 0x00000077, 0x3e0003ff, 0x8000, Rd_Rs_I5
, do_rdrsi5
},
684 {"srl!", 0x000a, 0x700f, 0x00000035, Rd_Rs
, do16_rdrs
},
685 {"sra!", 0x000b, 0x700f, 0x00000037, Rd_Rs
, do16_rdrs
},
686 {"srli!", 0x6003, 0x7007, 0x00000075, Rd_Rs
, do16_rdi5
},
687 {"stc1", 0x0c00000b, 0x3e00001f, 0x8000, Rd_lvalueRs_SI10
, do_ldst_cop
},
688 {"stc2", 0x0c000013, 0x3e00001f, 0x8000, Rd_lvalueRs_SI10
, do_ldst_cop
},
689 {"stc3", 0x0c00001b, 0x3e00001f, 0x8000, Rd_lvalueRs_SI10
, do_ldst_cop
},
690 {"sub", 0x00000014, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
691 {"sub.c", 0x00000015, 0x3e0003ff, 0x2001, Rd_Rs_Rs
, do_rdrsrs
},
692 {"sub.s", 0x38000049, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
693 {"subc", 0x00000016, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
694 {"subc.c", 0x00000017, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
695 {"sub!", 0x2001, 0x700f, 0x00000015, Rd_Rs
, do16_rdrs
},
696 {"subei!", 0x6080, 0x7087, 0x02000001, Rd_I4
, do16_rdi4
},
697 {"sw!", 0x200c, 0x700f, 0x28000000, Rd_lvalueRs
, do16_ldst_insn
},
698 {"swp!", 0x7004, 0x7007, 0x28000000, Rd_lvalueBP_I5
, do16_ldst_imm_insn
},
699 {"syscall", 0x00000002, 0x3e0003ff, 0x8000, I15
, do_i15
},
700 {"tcs", 0x00000054, 0x3e007fff, 0x0005, NO_OPD
, do_empty
},
701 {"tcc", 0x00000454, 0x3e007fff, 0x0105, NO_OPD
, do_empty
},
702 {"tcnz", 0x00003854, 0x3e007fff, 0x0e05, NO_OPD
, do_empty
},
703 {"tcs!", 0x0005, 0x7f0f, 0x00000054, NO16_OPD
, do_empty
},
704 {"tcc!", 0x0105, 0x7f0f, 0x00000454, NO16_OPD
, do_empty
},
705 {"tcnz!", 0x0e05, 0x7f0f, 0x00003854, NO16_OPD
, do_empty
},
706 {"teq", 0x00001054, 0x3e007fff, 0x0405, NO_OPD
, do_empty
},
707 {"teq!", 0x0405, 0x7f0f, 0x00001054, NO16_OPD
, do_empty
},
708 {"tgtu", 0x00000854, 0x3e007fff, 0x0205, NO_OPD
, do_empty
},
709 {"tgt", 0x00001854, 0x3e007fff, 0x0605, NO_OPD
, do_empty
},
710 {"tge", 0x00002054, 0x3e007fff, 0x0805, NO_OPD
, do_empty
},
711 {"tgtu!", 0x0205, 0x7f0f, 0x00000854, NO16_OPD
, do_empty
},
712 {"tgt!", 0x0605, 0x7f0f, 0x00001854, NO16_OPD
, do_empty
},
713 {"tge!", 0x0805, 0x7f0f, 0x00002054, NO16_OPD
, do_empty
},
714 {"tleu", 0x00000c54, 0x3e007fff, 0x0305, NO_OPD
, do_empty
},
715 {"tle", 0x00001c54, 0x3e007fff, 0x0705, NO_OPD
, do_empty
},
716 {"tlt", 0x00002454, 0x3e007fff, 0x0905, NO_OPD
, do_empty
},
717 {"stlb", 0x0c000004, 0x3e0003ff, 0x8000, NO_OPD
, do_empty
},
718 {"mftlb", 0x0c000024, 0x3e0003ff, 0x8000, NO_OPD
, do_empty
},
719 {"mtptlb", 0x0c000044, 0x3e0003ff, 0x8000, NO_OPD
, do_empty
},
720 {"mtrtlb", 0x0c000064, 0x3e0003ff, 0x8000, NO_OPD
, do_empty
},
721 {"tleu!", 0x0305, 0x7f0f, 0x00000c54, NO16_OPD
, do_empty
},
722 {"tle!", 0x0705, 0x7f0f, 0x00001c54, NO16_OPD
, do_empty
},
723 {"tlt!", 0x0905, 0x7f0f, 0x00002454, NO16_OPD
, do_empty
},
724 {"tmi", 0x00002854, 0x3e007fff, 0x0a05, NO_OPD
, do_empty
},
725 {"tmi!", 0x0a05, 0x7f0f, 0x00002854, NO16_OPD
, do_empty
},
726 {"tne", 0x00001454, 0x3e007fff, 0x0505, NO_OPD
, do_empty
},
727 {"tne!", 0x0505, 0x7f0f, 0x00001454, NO16_OPD
, do_empty
},
728 {"tpl", 0x00002c54, 0x3e007fff, 0x0b05, NO_OPD
, do_empty
},
729 {"tpl!", 0x0b05, 0x7f0f, 0x00002c54, NO16_OPD
, do_empty
},
730 {"trapcs", 0x00000004, 0x3e007fff, 0x8000, x_I5_x
, do_xi5x
},
731 {"trapcc", 0x00000404, 0x3e007fff, 0x8000, x_I5_x
, do_xi5x
},
732 {"trapgtu", 0x00000804, 0x3e007fff, 0x8000, x_I5_x
, do_xi5x
},
733 {"trapleu", 0x00000c04, 0x3e007fff, 0x8000, x_I5_x
, do_xi5x
},
734 {"trapeq", 0x00001004, 0x3e007fff, 0x8000, x_I5_x
, do_xi5x
},
735 {"trapne", 0x00001404, 0x3e007fff, 0x8000, x_I5_x
, do_xi5x
},
736 {"trapgt", 0x00001804, 0x3e007fff, 0x8000, x_I5_x
, do_xi5x
},
737 {"traple", 0x00001c04, 0x3e007fff, 0x8000, x_I5_x
, do_xi5x
},
738 {"trapge", 0x00002004, 0x3e007fff, 0x8000, x_I5_x
, do_xi5x
},
739 {"traplt", 0x00002404, 0x3e007fff, 0x8000, x_I5_x
, do_xi5x
},
740 {"trapmi", 0x00002804, 0x3e007fff, 0x8000, x_I5_x
, do_xi5x
},
741 {"trappl", 0x00002c04, 0x3e007fff, 0x8000, x_I5_x
, do_xi5x
},
742 {"trapvs", 0x00003004, 0x3e007fff, 0x8000, x_I5_x
, do_xi5x
},
743 {"trapvc", 0x00003404, 0x3e007fff, 0x8000, x_I5_x
, do_xi5x
},
744 {"trap", 0x00003c04, 0x3e007fff, 0x8000, x_I5_x
, do_xi5x
},
745 {"tset", 0x00003c54, 0x3e007fff, 0x0f05, NO_OPD
, do_empty
},
746 {"tset!", 0x0f05, 0x00007f0f, 0x00003c54, NO16_OPD
, do_empty
},
747 {"tvs", 0x00003054, 0x3e007fff, 0x0c05, NO_OPD
, do_empty
},
748 {"tvc", 0x00003454, 0x3e007fff, 0x0d05, NO_OPD
, do_empty
},
749 {"tvs!", 0x0c05, 0x7f0f, 0x00003054, NO16_OPD
, do_empty
},
750 {"tvc!", 0x0d05, 0x7f0f, 0x00003454, NO16_OPD
, do_empty
},
751 {"xor", 0x00000026, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
752 {"xor.c", 0x00000027, 0x3e0003ff, 0x2007, Rd_Rs_Rs
, do_rdrsrs
},
753 {"xor!", 0x2007, 0x700f, 0x00000027, Rd_Rs
, do16_rdrs
},
754 /* Macro instruction. */
755 {"li", 0x020c0000, 0x3e0e0000, 0x8000, Insn_Type_SYN
, do_macro_li_rdi32
},
756 /* la reg, imm32 -->(1) ldi reg, simm16
757 (2) ldis reg, %HI(imm32)
760 la reg, symbol -->(1) lis reg, %HI(imm32)
761 ori reg, %LO(imm32) */
762 {"la", 0x020c0000, 0x3e0e0000, 0x8000, Insn_Type_SYN
, do_macro_la_rdi32
},
763 {"div", 0x00000044, 0x3e0003ff, 0x8000, Insn_Type_SYN
, do_macro_mul_rdrsrs
},
764 {"divu", 0x00000046, 0x3e0003ff, 0x8000, Insn_Type_SYN
, do_macro_mul_rdrsrs
},
765 {"rem", 0x00000044, 0x3e0003ff, 0x8000, Insn_Type_SYN
, do_macro_mul_rdrsrs
},
766 {"remu", 0x00000046, 0x3e0003ff, 0x8000, Insn_Type_SYN
, do_macro_mul_rdrsrs
},
767 {"mul", 0x00000040, 0x3e0003ff, 0x8000, Insn_Type_SYN
, do_macro_mul_rdrsrs
},
768 {"mulu", 0x00000042, 0x3e0003ff, 0x8000, Insn_Type_SYN
, do_macro_mul_rdrsrs
},
769 {"maz", 0x00000040, 0x3e0003ff, 0x8000, Insn_Type_SYN
, do_macro_mul_rdrsrs
},
770 {"mazu", 0x00000042, 0x3e0003ff, 0x8000, Insn_Type_SYN
, do_macro_mul_rdrsrs
},
771 {"mul.f", 0x00000041, 0x3e0003ff, 0x8000, Insn_Type_SYN
, do_macro_mul_rdrsrs
},
772 {"maz.f", 0x00000041, 0x3e0003ff, 0x8000, Insn_Type_SYN
, do_macro_mul_rdrsrs
},
773 {"lb", INSN_LB
, 0x00000000, 0x8000, Insn_Type_SYN
, do_macro_ldst_label
},
774 {"lbu", INSN_LBU
, 0x00000000, 0x200b, Insn_Type_SYN
, do_macro_ldst_label
},
775 {"lh", INSN_LH
, 0x00000000, 0x2009, Insn_Type_SYN
, do_macro_ldst_label
},
776 {"lhu", INSN_LHU
, 0x00000000, 0x8000, Insn_Type_SYN
, do_macro_ldst_label
},
777 {"lw", INSN_LW
, 0x00000000, 0x2008, Insn_Type_SYN
, do_macro_ldst_label
},
778 {"sb", INSN_SB
, 0x00000000, 0x200f, Insn_Type_SYN
, do_macro_ldst_label
},
779 {"sh", INSN_SH
, 0x00000000, 0x200d, Insn_Type_SYN
, do_macro_ldst_label
},
780 {"sw", INSN_SW
, 0x00000000, 0x200c, Insn_Type_SYN
, do_macro_ldst_label
},
781 /* Assembler use internal. */
782 {"ld_i32hi", 0x0a0c0000, 0x3e0e0000, 0x8000, Rd_I16
, do_macro_rdi32hi
},
783 {"ld_i32lo", 0x020a0000, 0x3e0e0001, 0x8000, Rd_I16
, do_macro_rdi32lo
},
784 {"ldis_pic", 0x0a0c0000, 0x3e0e0000, 0x5000, Rd_I16
, do_rdi16_pic
},
785 {"addi_s_pic",0x02000000, 0x3e0e0001, 0x8000, Rd_SI16
, do_addi_s_pic
},
786 {"addi_u_pic",0x02000000, 0x3e0e0001, 0x8000, Rd_SI16
, do_addi_u_pic
},
787 {"lw_pic", 0x20000000, 0x3e000000, 0x2008, Rd_rvalueRs_SI15
, do_lw_pic
},
790 /* Next free entry in the pool. */
791 int next_literal_pool_place
= 0;
793 /* Next literal pool number. */
794 int lit_pool_num
= 1;
795 symbolS
*current_poolP
= NULL
;
798 end_of_line (char *str
)
800 int retval
= SUCCESS
;
802 skip_whitespace (str
);
809 inst
.error
= BAD_GARBAGE
}
816 score_reg_parse (char **ccp
, struct hash_control
*htab
)
821 struct reg_entry
*reg
;
824 if (!ISALPHA (*p
) || !is_name_beginner (*p
))
829 while (ISALPHA (c
) || ISDIGIT (c
) || c
== '_')
833 reg
= (struct reg_entry
*) hash_find (htab
, start
);
844 /* If shift <= 0, only return reg. */
847 reg_required_here (char **str
, int shift
, enum score_reg_type reg_type
)
849 static char buff
[MAX_LITERAL_POOL_SIZE
];
850 int reg
= (int) FAIL
;
853 if ((reg
= score_reg_parse (str
, all_reg_maps
[reg_type
].htab
)) != (int) FAIL
)
855 if (reg_type
== REG_TYPE_SCORE
)
857 if ((reg
== 1) && (nor1
== 1) && (inst
.bwarn
== 0))
859 as_warn ("Using temp register(r1)");
865 if (reg_type
== REG_TYPE_SCORE_CR
)
866 strcpy (inst
.reg
, score_crn_table
[reg
].name
);
867 else if (reg_type
== REG_TYPE_SCORE_SR
)
868 strcpy (inst
.reg
, score_srn_table
[reg
].name
);
870 strcpy (inst
.reg
, "");
872 inst
.instruction
|= reg
<< shift
;
878 sprintf (buff
, _("register expected, not '%.100s'"), start
);
886 skip_past_comma (char **str
)
892 while ((c
= *p
) == ' ' || c
== ',')
895 if (c
== ',' && comma
++)
897 inst
.error
= BAD_SKIP_COMMA
;
902 if ((c
== '\0') || (comma
== 0))
904 inst
.error
= BAD_SKIP_COMMA
;
909 return comma
? SUCCESS
: (int) FAIL
;
913 do_rdrsrs (char *str
)
915 skip_whitespace (str
);
917 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) == (int) FAIL
918 || skip_past_comma (&str
) == (int) FAIL
919 || reg_required_here (&str
, 15, REG_TYPE_SCORE
) == (int) FAIL
920 || skip_past_comma (&str
) == (int) FAIL
921 || reg_required_here (&str
, 10, REG_TYPE_SCORE
) == (int) FAIL
922 || end_of_line (str
) == (int) FAIL
)
928 if ((((inst
.instruction
>> 15) & 0x10) == 0)
929 && (((inst
.instruction
>> 10) & 0x10) == 0)
930 && (((inst
.instruction
>> 20) & 0x10) == 0)
931 && (inst
.relax_inst
!= 0x8000)
932 && (((inst
.instruction
>> 20) & 0xf) == ((inst
.instruction
>> 15) & 0xf)))
934 inst
.relax_inst
|= (((inst
.instruction
>> 10) & 0xf) << 4)
935 | (((inst
.instruction
>> 15) & 0xf) << 8);
940 inst
.relax_inst
= 0x8000;
946 walk_no_bignums (symbolS
* sp
)
948 if (symbol_get_value_expression (sp
)->X_op
== O_big
)
951 if (symbol_get_value_expression (sp
)->X_add_symbol
)
952 return (walk_no_bignums (symbol_get_value_expression (sp
)->X_add_symbol
)
953 || (symbol_get_value_expression (sp
)->X_op_symbol
954 && walk_no_bignums (symbol_get_value_expression (sp
)->X_op_symbol
)));
960 my_get_expression (expressionS
* ep
, char **str
)
965 save_in
= input_line_pointer
;
966 input_line_pointer
= *str
;
967 in_my_get_expression
= 1;
968 seg
= expression (ep
);
969 in_my_get_expression
= 0;
971 if (ep
->X_op
== O_illegal
)
973 *str
= input_line_pointer
;
974 input_line_pointer
= save_in
;
975 inst
.error
= _("illegal expression");
978 /* Get rid of any bignums now, so that we don't generate an error for which
979 we can't establish a line number later on. Big numbers are never valid
980 in instructions, which is where this routine is always called. */
981 if (ep
->X_op
== O_big
983 && (walk_no_bignums (ep
->X_add_symbol
)
984 || (ep
->X_op_symbol
&& walk_no_bignums (ep
->X_op_symbol
)))))
986 inst
.error
= _("invalid constant");
987 *str
= input_line_pointer
;
988 input_line_pointer
= save_in
;
992 *str
= input_line_pointer
;
993 input_line_pointer
= save_in
;
997 /* Check if an immediate is valid. If so, convert it to the right format. */
1000 validate_immediate (int val
, unsigned int data_type
)
1006 int val_hi
= ((val
& 0xffff0000) >> 16);
1008 if (score_df_range
[data_type
].range
[0] <= val_hi
1009 && val_hi
<= score_df_range
[data_type
].range
[1])
1016 int val_lo
= (val
& 0xffff);
1018 if (score_df_range
[data_type
].range
[0] <= val_lo
1019 && val_lo
<= score_df_range
[data_type
].range
[1])
1029 if (data_type
== _SIMM14_NEG
|| data_type
== _SIMM16_NEG
|| data_type
== _IMM16_NEG
)
1032 if (score_df_range
[data_type
].range
[0] <= val
1033 && val
<= score_df_range
[data_type
].range
[1])
1043 data_op2 (char **str
, int shift
, enum score_data_type data_type
)
1046 char data_exp
[MAX_LITERAL_POOL_SIZE
];
1051 skip_whitespace (*str
);
1055 while ((*dataptr
!= '\0') && (*dataptr
!= '|') && (cnt
<= MAX_LITERAL_POOL_SIZE
)) /* 0x7c = ='|' */
1057 data_exp
[cnt
] = *dataptr
;
1062 data_exp
[cnt
] = '\0';
1063 pp
= (char *)&data_exp
;
1065 if (*dataptr
== '|') /* process PCE */
1067 if (my_get_expression (&inst
.reloc
.exp
, &pp
) == (int) FAIL
)
1070 if (inst
.error
!= 0)
1071 return (int) FAIL
; /* to ouptut_inst to printf out the error */
1074 else /* process 16 bit */
1076 if (my_get_expression (&inst
.reloc
.exp
, str
) == (int) FAIL
)
1081 dataptr
= (char *)data_exp
;
1082 for (; *dataptr
!= '\0'; dataptr
++)
1084 *dataptr
= TOLOWER (*dataptr
);
1085 if (*dataptr
== '!' || *dataptr
== ' ')
1088 dataptr
= (char *)data_exp
;
1090 if ((*dataptr
== '0') && (*(dataptr
+ 1) == 'x')
1091 && (data_type
!= _SIMM16_LA
)
1092 && (data_type
!= _VALUE_HI16
)
1093 && (data_type
!= _VALUE_LO16
)
1094 && (data_type
!= _IMM16
)
1095 && (data_type
!= _IMM15
)
1096 && (data_type
!= _IMM14
)
1097 && (data_type
!= _IMM4
)
1098 && (data_type
!= _IMM5
)
1099 && (data_type
!= _IMM8
)
1100 && (data_type
!= _IMM5_RSHIFT_1
)
1101 && (data_type
!= _IMM5_RSHIFT_2
)
1102 && (data_type
!= _SIMM14_NEG
)
1103 && (data_type
!= _IMM10_RSHIFT_2
)
1104 && (data_type
!= _GP_IMM15
))
1110 if ((inst
.reloc
.exp
.X_add_symbol
)
1111 && ((data_type
== _SIMM16
)
1112 || (data_type
== _SIMM16_NEG
)
1113 || (data_type
== _IMM16_NEG
)
1114 || (data_type
== _SIMM14
)
1115 || (data_type
== _SIMM14_NEG
)
1116 || (data_type
== _IMM5
)
1117 || (data_type
== _IMM14
)
1118 || (data_type
== _IMM20
)
1119 || (data_type
== _IMM16
)
1120 || (data_type
== _IMM15
)
1121 || (data_type
== _IMM4
)))
1123 inst
.error
= BAD_ARGS
;
1127 if (inst
.reloc
.exp
.X_add_symbol
)
1134 inst
.reloc
.type
= BFD_RELOC_HI16_S
;
1135 inst
.reloc
.pc_rel
= 0;
1138 inst
.reloc
.type
= BFD_RELOC_LO16
;
1139 inst
.reloc
.pc_rel
= 0;
1142 inst
.reloc
.type
= BFD_RELOC_SCORE_GPREL15
;
1143 inst
.reloc
.pc_rel
= 0;
1146 case _IMM16_LO16_pic
:
1147 inst
.reloc
.type
= BFD_RELOC_SCORE_GOT_LO16
;
1148 inst
.reloc
.pc_rel
= 0;
1151 inst
.reloc
.type
= BFD_RELOC_32
;
1152 inst
.reloc
.pc_rel
= 0;
1158 if (data_type
== _IMM16_pic
)
1160 inst
.reloc
.type
= BFD_RELOC_SCORE_DUMMY_HI16
;
1161 inst
.reloc
.pc_rel
= 0;
1164 if (data_type
== _SIMM16_LA
&& inst
.reloc
.exp
.X_unsigned
== 1)
1166 value
= validate_immediate (inst
.reloc
.exp
.X_add_number
, _SIMM16_LA_POS
);
1167 if (value
== (int) FAIL
) /* for advance to check if this is ldis */
1168 if ((inst
.reloc
.exp
.X_add_number
& 0xffff) == 0)
1170 inst
.instruction
|= 0x8000000;
1171 inst
.instruction
|= ((inst
.reloc
.exp
.X_add_number
>> 16) << 1) & 0x1fffe;
1177 value
= validate_immediate (inst
.reloc
.exp
.X_add_number
, data_type
);
1180 if (value
== (int) FAIL
)
1184 if ((data_type
!= _SIMM14_NEG
) && (data_type
!= _SIMM16_NEG
) && (data_type
!= _IMM16_NEG
))
1187 "invalid constant: %d bit expression not in range %d..%d",
1188 score_df_range
[data_type
].bits
,
1189 score_df_range
[data_type
].range
[0], score_df_range
[data_type
].range
[1]);
1194 "invalid constant: %d bit expression not in range %d..%d",
1195 score_df_range
[data_type
].bits
,
1196 -score_df_range
[data_type
].range
[1], -score_df_range
[data_type
].range
[0]);
1199 inst
.error
= _(err_msg
);
1203 if ((score_df_range
[data_type
].range
[0] != 0) || (data_type
== _IMM5_RANGE_8_31
))
1205 value
&= (1 << score_df_range
[data_type
].bits
) - 1;
1208 inst
.instruction
|= value
<< shift
;
1211 if ((inst
.instruction
& 0xf0000000) == 0x30000000)
1213 if ((((inst
.instruction
>> 20) & 0x1F) != 0)
1214 && (((inst
.instruction
>> 20) & 0x1F) != 1)
1215 && (((inst
.instruction
>> 20) & 0x1F) != 2)
1216 && (((inst
.instruction
>> 20) & 0x1F) != 3)
1217 && (((inst
.instruction
>> 20) & 0x1F) != 4)
1218 && (((inst
.instruction
>> 20) & 0x1F) != 8)
1219 && (((inst
.instruction
>> 20) & 0x1F) != 9)
1220 && (((inst
.instruction
>> 20) & 0x1F) != 0xa)
1221 && (((inst
.instruction
>> 20) & 0x1F) != 0xb)
1222 && (((inst
.instruction
>> 20) & 0x1F) != 0xc)
1223 && (((inst
.instruction
>> 20) & 0x1F) != 0xd)
1224 && (((inst
.instruction
>> 20) & 0x1F) != 0xe)
1225 && (((inst
.instruction
>> 20) & 0x1F) != 0x10)
1226 && (((inst
.instruction
>> 20) & 0x1F) != 0x11)
1227 && (((inst
.instruction
>> 20) & 0x1F) != 0x18)
1228 && (((inst
.instruction
>> 20) & 0x1F) != 0x1A)
1229 && (((inst
.instruction
>> 20) & 0x1F) != 0x1B)
1230 && (((inst
.instruction
>> 20) & 0x1F) != 0x1d)
1231 && (((inst
.instruction
>> 20) & 0x1F) != 0x1e)
1232 && (((inst
.instruction
>> 20) & 0x1F) != 0x1f))
1236 sprintf (err_msg
, "invalid constant: bit expression not defined");
1237 inst
.error
= _(err_msg
);
1245 /* Handle addi/addi.c/addis.c/cmpi.c/addis.c/ldi. */
1248 do_rdsi16 (char *str
)
1250 skip_whitespace (str
);
1252 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) == (int) FAIL
1253 || skip_past_comma (&str
) == (int) FAIL
1254 || data_op2 (&str
, 1, _SIMM16
) == (int) FAIL
1255 || end_of_line (str
) == (int) FAIL
)
1259 if ((inst
.instruction
& 0x20c0000) == 0x20c0000)
1261 if ((((inst
.instruction
>> 20) & 0x10) == 0x10) || ((inst
.instruction
& 0x1fe00) != 0))
1263 inst
.relax_inst
= 0x8000;
1267 inst
.relax_inst
|= (inst
.instruction
>> 1) & 0xff;
1268 inst
.relax_inst
|= (((inst
.instruction
>> 20) & 0xf) << 8);
1269 inst
.relax_size
= 2;
1272 else if (((inst
.instruction
>> 20) & 0x10) == 0x10)
1274 inst
.relax_inst
= 0x8000;
1278 /* Handle subi/subi.c. */
1281 do_sub_rdsi16 (char *str
)
1283 skip_whitespace (str
);
1285 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) != (int) FAIL
1286 && skip_past_comma (&str
) != (int) FAIL
1287 && data_op2 (&str
, 1, _SIMM16_NEG
) != (int) FAIL
)
1291 /* Handle subis/subis.c. */
1294 do_sub_rdi16 (char *str
)
1296 skip_whitespace (str
);
1298 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) != (int) FAIL
1299 && skip_past_comma (&str
) != (int) FAIL
1300 && data_op2 (&str
, 1, _IMM16_NEG
) != (int) FAIL
)
1304 /* Handle addri/addri.c. */
1307 do_rdrssi14 (char *str
) /* -(2^13)~((2^13)-1) */
1309 skip_whitespace (str
);
1311 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) != (int) FAIL
1312 && skip_past_comma (&str
) != (int) FAIL
1313 && reg_required_here (&str
, 15, REG_TYPE_SCORE
) != (int) FAIL
1314 && skip_past_comma (&str
) != (int) FAIL
)
1315 data_op2 (&str
, 1, _SIMM14
);
1318 /* Handle subri.c/subri. */
1320 do_sub_rdrssi14 (char *str
) /* -(2^13)~((2^13)-1) */
1322 skip_whitespace (str
);
1324 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) != (int) FAIL
1325 && skip_past_comma (&str
) != (int) FAIL
1326 && reg_required_here (&str
, 15, REG_TYPE_SCORE
) != (int) FAIL
1327 && skip_past_comma (&str
) != (int) FAIL
1328 && data_op2 (&str
, 1, _SIMM14_NEG
) != (int) FAIL
)
1332 /* Handle bitclr.c/bitset.c/bittgl.c/slli.c/srai.c/srli.c/roli.c/rori.c/rolic.c. */
1334 do_rdrsi5 (char *str
) /* 0~((2^14)-1) */
1336 skip_whitespace (str
);
1338 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) == (int) FAIL
1339 || skip_past_comma (&str
) == (int) FAIL
1340 || reg_required_here (&str
, 15, REG_TYPE_SCORE
) == (int) FAIL
1341 || skip_past_comma (&str
) == (int) FAIL
1342 || data_op2 (&str
, 10, _IMM5
) == (int) FAIL
1343 || end_of_line (str
) == (int) FAIL
)
1346 if ((((inst
.instruction
>> 20) & 0x1f) == ((inst
.instruction
>> 15) & 0x1f))
1347 && (inst
.relax_inst
!= 0x8000) && (((inst
.instruction
>> 15) & 0x10) == 0))
1349 inst
.relax_inst
|= (((inst
.instruction
>> 10) & 0x1f) << 3) | (((inst
.instruction
>> 15) & 0xf) << 8);
1350 inst
.relax_size
= 2;
1353 inst
.relax_inst
= 0x8000;
1356 /* Handle andri/orri/andri.c/orri.c. */
1359 do_rdrsi14 (char *str
) /* 0 ~ ((2^14)-1) */
1361 skip_whitespace (str
);
1363 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) != (int) FAIL
1364 && skip_past_comma (&str
) != (int) FAIL
1365 && reg_required_here (&str
, 15, REG_TYPE_SCORE
) != (int) FAIL
1366 && skip_past_comma (&str
) != (int) FAIL
1367 && data_op2 (&str
, 1, _IMM14
) != (int) FAIL
)
1371 /* Handle bittst.c. */
1373 do_xrsi5 (char *str
)
1375 skip_whitespace (str
);
1377 if (reg_required_here (&str
, 15, REG_TYPE_SCORE
) == (int) FAIL
1378 || skip_past_comma (&str
) == (int) FAIL
1379 || data_op2 (&str
, 10, _IMM5
) == (int) FAIL
1380 || end_of_line (str
) == (int) FAIL
)
1383 if ((inst
.relax_inst
!= 0x8000) && (((inst
.instruction
>> 15) & 0x10) == 0))
1385 inst
.relax_inst
|= (((inst
.instruction
>> 10) & 0x1f) << 3) | (((inst
.instruction
>> 15) & 0xf) << 8);
1386 inst
.relax_size
= 2;
1389 inst
.relax_inst
= 0x8000;
1392 /* Handle andi/ori/andis/oris/ldis. */
1394 do_rdi16 (char *str
)
1396 skip_whitespace (str
);
1398 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) == (int) FAIL
1399 || skip_past_comma (&str
) == (int) FAIL
1400 || data_op2 (&str
, 1, _IMM16
) == (int) FAIL
1401 || end_of_line (str
) == (int) FAIL
)
1404 if (((inst
.instruction
& 0xa0dfffe) != 0xa0c0000) || ((((inst
.instruction
>> 20) & 0x1f) & 0x10) == 0x10))
1405 inst
.relax_inst
= 0x8000;
1407 inst
.relax_size
= 2;
1411 do_macro_rdi32hi (char *str
)
1413 skip_whitespace (str
);
1415 /* Do not handle end_of_line(). */
1416 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) != (int) FAIL
1417 && skip_past_comma (&str
) != (int) FAIL
)
1418 data_op2 (&str
, 1, _VALUE_HI16
);
1422 do_macro_rdi32lo (char *str
)
1424 skip_whitespace (str
);
1426 /* Do not handle end_of_line(). */
1427 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) != (int) FAIL
1428 && skip_past_comma (&str
) != (int) FAIL
)
1429 data_op2 (&str
, 1, _VALUE_LO16
);
1432 /* Handle ldis_pic. */
1435 do_rdi16_pic (char *str
)
1437 skip_whitespace (str
);
1439 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) != (int) FAIL
1440 && skip_past_comma (&str
) != (int) FAIL
1441 && data_op2 (&str
, 1, _IMM16_pic
) != (int) FAIL
)
1445 /* Handle addi_s_pic to generate R_SCORE_GOT_LO16 . */
1448 do_addi_s_pic (char *str
)
1450 skip_whitespace (str
);
1452 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) != (int) FAIL
1453 && skip_past_comma (&str
) != (int) FAIL
1454 && data_op2 (&str
, 1, _SIMM16_pic
) != (int) FAIL
)
1458 /* Handle addi_u_pic to generate R_SCORE_GOT_LO16 . */
1461 do_addi_u_pic (char *str
)
1463 skip_whitespace (str
);
1465 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) != (int) FAIL
1466 && skip_past_comma (&str
) != (int) FAIL
1467 && data_op2 (&str
, 1, _IMM16_LO16_pic
) != (int) FAIL
)
1471 /* Handle mfceh/mfcel/mtceh/mtchl. */
1476 skip_whitespace (str
);
1478 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) != (int) FAIL
)
1485 skip_whitespace (str
);
1487 if (reg_required_here (&str
, 15, REG_TYPE_SCORE
) == (int) FAIL
1488 || end_of_line (str
) == (int) FAIL
)
1491 if ((inst
.relax_inst
!= 0x8000) && (((inst
.instruction
>> 15) & 0x10) == 0))
1493 inst
.relax_inst
|= (((inst
.instruction
>> 10) & 0xf) << 8) | (((inst
.instruction
>> 15) & 0xf) << 4);
1494 inst
.relax_size
= 2;
1497 inst
.relax_inst
= 0x8000;
1503 skip_whitespace (str
);
1505 if (data_op2 (&str
, 10, _IMM15
) != (int) FAIL
)
1512 skip_whitespace (str
);
1514 if (data_op2 (&str
, 15, _IMM5
) == (int) FAIL
|| end_of_line (str
) == (int) FAIL
)
1517 if (inst
.relax_inst
!= 0x8000)
1519 inst
.relax_inst
|= (((inst
.instruction
>> 15) & 0x1f) << 3);
1520 inst
.relax_size
= 2;
1527 skip_whitespace (str
);
1529 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) == (int) FAIL
1530 || skip_past_comma (&str
) == (int) FAIL
1531 || reg_required_here (&str
, 15, REG_TYPE_SCORE
) == (int) FAIL
1532 || end_of_line (str
) == (int) FAIL
)
1535 if (inst
.relax_inst
!= 0x8000)
1537 if (((inst
.instruction
& 0x7f) == 0x56)) /* adjust mv -> mv! / mlfh! / mhfl! */
1540 if ((((inst
.instruction
>> 15) & 0x10) != 0x0) && (((inst
.instruction
>> 20) & 0x10) == 0))
1542 inst
.relax_inst
= 0x00000001 | (((inst
.instruction
>> 15) & 0xf) << 4)
1543 | (((inst
.instruction
>> 20) & 0xf) << 8);
1544 inst
.relax_size
= 2;
1547 else if ((((inst
.instruction
>> 15) & 0x10) == 0x0) && ((inst
.instruction
>> 20) & 0x10) != 0)
1549 inst
.relax_inst
= 0x00000002 | (((inst
.instruction
>> 15) & 0xf) << 4)
1550 | (((inst
.instruction
>> 20) & 0xf) << 8);
1551 inst
.relax_size
= 2;
1553 else if ((((inst
.instruction
>> 15) & 0x10) == 0x0) && (((inst
.instruction
>> 20) & 0x10) == 0))
1555 inst
.relax_inst
|= (((inst
.instruction
>> 15) & 0xf) << 4)
1556 | (((inst
.instruction
>> 20) & 0xf) << 8);
1557 inst
.relax_size
= 2;
1561 inst
.relax_inst
= 0x8000;
1564 else if ((((inst
.instruction
>> 15) & 0x10) == 0x0) && (((inst
.instruction
>> 20) & 0x10) == 0))
1566 inst
.relax_inst
|= (((inst
.instruction
>> 15) & 0xf) << 4)
1567 | (((inst
.instruction
>> 20) & 0xf) << 8);
1568 inst
.relax_size
= 2;
1572 inst
.relax_inst
= 0x8000;
1577 /* Handle mfcr/mtcr. */
1579 do_rdcrs (char *str
)
1581 skip_whitespace (str
);
1583 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) != (int) FAIL
1584 && skip_past_comma (&str
) != (int) FAIL
1585 && reg_required_here (&str
, 15, REG_TYPE_SCORE_CR
) != (int) FAIL
)
1589 /* Handle mfsr/mtsr. */
1592 do_rdsrs (char *str
)
1594 skip_whitespace (str
);
1597 if ((inst
.instruction
& 0xff) == 0x50)
1599 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) != (int) FAIL
1600 && skip_past_comma (&str
) != (int) FAIL
1601 && reg_required_here (&str
, 10, REG_TYPE_SCORE_SR
) != (int) FAIL
)
1606 if (reg_required_here (&str
, 15, REG_TYPE_SCORE
) != (int) FAIL
1607 && skip_past_comma (&str
) != (int) FAIL
)
1608 reg_required_here (&str
, 10, REG_TYPE_SCORE_SR
);
1615 do_rdxrs (char *str
)
1617 skip_whitespace (str
);
1619 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) == (int) FAIL
1620 || skip_past_comma (&str
) == (int) FAIL
1621 || reg_required_here (&str
, 10, REG_TYPE_SCORE
) == (int) FAIL
1622 || end_of_line (str
) == (int) FAIL
)
1625 if ((inst
.relax_inst
!= 0x8000) && (((inst
.instruction
>> 10) & 0x10) == 0)
1626 && (((inst
.instruction
>> 20) & 0x10) == 0))
1628 inst
.relax_inst
|= (((inst
.instruction
>> 10) & 0xf) << 4) | (((inst
.instruction
>> 20) & 0xf) << 8);
1629 inst
.relax_size
= 2;
1632 inst
.relax_inst
= 0x8000;
1635 /* Handle cmp.c/cmp<cond>. */
1639 skip_whitespace (str
);
1641 if (reg_required_here (&str
, 15, REG_TYPE_SCORE
) == (int) FAIL
1642 || skip_past_comma (&str
) == (int) FAIL
1643 || reg_required_here (&str
, 10, REG_TYPE_SCORE
) == (int) FAIL
1644 || end_of_line (str
) == (int) FAIL
)
1647 if ((inst
.relax_inst
!= 0x8000) && (((inst
.instruction
>> 20) & 0x1f) == 3)
1648 && (((inst
.instruction
>> 10) & 0x10) == 0) && (((inst
.instruction
>> 15) & 0x10) == 0))
1650 inst
.relax_inst
|= (((inst
.instruction
>> 10) & 0xf) << 4) | (((inst
.instruction
>> 15) & 0xf) << 8);
1651 inst
.relax_size
= 2;
1654 inst
.relax_inst
= 0x8000;
1658 do_ceinst (char *str
)
1663 skip_whitespace (str
);
1665 if (data_op2 (&str
, 20, _IMM5
) == (int) FAIL
1666 || skip_past_comma (&str
) == (int) FAIL
1667 || reg_required_here (&str
, 15, REG_TYPE_SCORE
) == (int) FAIL
1668 || skip_past_comma (&str
) == (int) FAIL
1669 || reg_required_here (&str
, 10, REG_TYPE_SCORE
) == (int) FAIL
1670 || skip_past_comma (&str
) == (int) FAIL
1671 || data_op2 (&str
, 5, _IMM5
) == (int) FAIL
1672 || skip_past_comma (&str
) == (int) FAIL
1673 || data_op2 (&str
, 0, _IMM5
) == (int) FAIL
1674 || end_of_line (str
) == (int) FAIL
)
1681 if (data_op2 (&str
, 0, _IMM25
) == (int) FAIL
)
1687 reglow_required_here (char **str
, int shift
)
1689 static char buff
[MAX_LITERAL_POOL_SIZE
];
1693 if ((reg
= score_reg_parse (str
, all_reg_maps
[REG_TYPE_SCORE
].htab
)) != (int) FAIL
)
1695 if ((reg
== 1) && (nor1
== 1) && (inst
.bwarn
== 0))
1697 as_warn ("Using temp register(r1)");
1703 inst
.instruction
|= reg
<< shift
;
1709 /* Restore the start point, we may have got a reg of the wrong class. */
1711 sprintf (buff
, _("low register(r0-r15)expected, not '%.100s'"), start
);
1716 /* Handle addc!/add!/and!/cmp!/neg!/not!/or!/sll!/srl!/sra!/xor!/sub!. */
1718 do16_rdrs (char *str
)
1720 skip_whitespace (str
);
1722 if (reglow_required_here (&str
, 8) == (int) FAIL
1723 || skip_past_comma (&str
) == (int) FAIL
1724 || reglow_required_here (&str
, 4) == (int) FAIL
1725 || end_of_line (str
) == (int) FAIL
)
1731 if ((inst
.instruction
& 0x700f) == 0x2003) /* cmp! */
1733 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 15)
1734 | (((inst
.instruction
>> 4) & 0xf) << 10);
1738 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 20)
1739 | (((inst
.instruction
>> 8) & 0xf) << 15) | (((inst
.instruction
>> 4) & 0xf) << 10);
1741 inst
.relax_size
= 4;
1750 skip_whitespace (str
);
1752 if ((rd
= reglow_required_here (&str
, 4)) == (int) FAIL
1753 || end_of_line (str
) == (int) FAIL
)
1759 inst
.relax_inst
|= rd
<< 20;
1760 inst
.relax_size
= 4;
1764 /* Handle br!/brl!. */
1766 do16_xrs (char *str
)
1768 skip_whitespace (str
);
1770 if (reglow_required_here (&str
, 4) == (int) FAIL
|| end_of_line (str
) == (int) FAIL
)
1776 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 10)
1777 | (((inst
.instruction
>> 4) & 0xf) << 15);
1778 inst
.relax_size
= 4;
1783 reghigh_required_here (char **str
, int shift
)
1785 static char buff
[MAX_LITERAL_POOL_SIZE
];
1789 if ((reg
= score_reg_parse (str
, all_reg_maps
[REG_TYPE_SCORE
].htab
)) != (int) FAIL
)
1791 if (15 < reg
&& reg
< 32)
1794 inst
.instruction
|= (reg
& 0xf) << shift
;
1801 sprintf (buff
, _("high register(r16-r31)expected, not '%.100s'"), start
);
1808 do16_hrdrs (char *str
)
1810 skip_whitespace (str
);
1812 if (reghigh_required_here (&str
, 8) != (int) FAIL
1813 && skip_past_comma (&str
) != (int) FAIL
1814 && reglow_required_here (&str
, 4) != (int) FAIL
1815 && end_of_line (str
) != (int) FAIL
)
1817 inst
.relax_inst
|= ((((inst
.instruction
>> 8) & 0xf) | 0x10) << 20)
1818 | (((inst
.instruction
>> 4) & 0xf) << 15) | (0xf << 10);
1819 inst
.relax_size
= 4;
1825 do16_rdhrs (char *str
)
1827 skip_whitespace (str
);
1829 if (reglow_required_here (&str
, 8) != (int) FAIL
1830 && skip_past_comma (&str
) != (int) FAIL
1831 && reghigh_required_here (&str
, 4) != (int) FAIL
1832 && end_of_line (str
) != (int) FAIL
)
1834 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 20)
1835 | ((((inst
.instruction
>> 4) & 0xf) | 0x10) << 15) | (0xf << 10);
1836 inst
.relax_size
= 4;
1840 /* We need to be able to fix up arbitrary expressions in some statements.
1841 This is so that we can handle symbols that are an arbitrary distance from
1842 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
1843 which returns part of an address in a form which will be valid for
1844 a data instruction. We do this by pushing the expression into a symbol
1845 in the expr_section, and creating a fix for that. */
1847 fix_new_score (fragS
* frag
, int where
, short int size
, expressionS
* exp
, int pc_rel
, int reloc
)
1857 new_fix
= fix_new_exp (frag
, where
, size
, exp
, pc_rel
, reloc
);
1860 new_fix
= fix_new (frag
, where
, size
, make_expr_symbol (exp
), 0, pc_rel
, reloc
);
1867 init_dependency_vector (void)
1871 for (i
= 0; i
< vector_size
; i
++)
1872 memset (&dependency_vector
[i
], '\0', sizeof (dependency_vector
[i
]));
1877 static enum insn_type_for_dependency
1878 dependency_type_from_insn (char *insn_name
)
1880 char name
[INSN_NAME_LEN
];
1881 const struct insn_to_dependency
*tmp
;
1883 strcpy (name
, insn_name
);
1884 tmp
= (const struct insn_to_dependency
*) hash_find (dependency_insn_hsh
, name
);
1893 check_dependency (char *pre_insn
, char *pre_reg
,
1894 char *cur_insn
, char *cur_reg
, int *warn_or_error
)
1898 enum insn_type_for_dependency pre_insn_type
;
1899 enum insn_type_for_dependency cur_insn_type
;
1901 pre_insn_type
= dependency_type_from_insn (pre_insn
);
1902 cur_insn_type
= dependency_type_from_insn (cur_insn
);
1904 for (i
= 0; i
< sizeof (data_dependency_table
) / sizeof (data_dependency_table
[0]); i
++)
1906 if ((pre_insn_type
== data_dependency_table
[i
].pre_insn_type
)
1907 && (D_all_insn
== data_dependency_table
[i
].cur_insn_type
1908 || cur_insn_type
== data_dependency_table
[i
].cur_insn_type
)
1909 && (strcmp (data_dependency_table
[i
].pre_reg
, "") == 0
1910 || strcmp (data_dependency_table
[i
].pre_reg
, pre_reg
) == 0)
1911 && (strcmp (data_dependency_table
[i
].cur_reg
, "") == 0
1912 || strcmp (data_dependency_table
[i
].cur_reg
, cur_reg
) == 0))
1914 bubbles
= (score7
) ? data_dependency_table
[i
].bubblenum_7
: data_dependency_table
[i
].bubblenum_5
;
1915 *warn_or_error
= data_dependency_table
[i
].warn_or_error
;
1924 build_one_frag (struct score_it one_inst
)
1927 int relaxable_p
= g_opt
;
1930 /* Start a new frag if frag_now is not empty. */
1931 if (frag_now_fix () != 0)
1933 if (!frag_now
->tc_frag_data
.is_insn
)
1934 frag_wane (frag_now
);
1940 p
= frag_more (one_inst
.size
);
1941 md_number_to_chars (p
, one_inst
.instruction
, one_inst
.size
);
1944 dwarf2_emit_insn (one_inst
.size
);
1947 relaxable_p
&= (one_inst
.relax_size
!= 0);
1948 relax_size
= relaxable_p
? one_inst
.relax_size
: 0;
1950 p
= frag_var (rs_machine_dependent
, relax_size
+ RELAX_PAD_BYTE
, 0,
1951 RELAX_ENCODE (one_inst
.size
, one_inst
.relax_size
,
1952 one_inst
.type
, 0, 0, relaxable_p
),
1956 md_number_to_chars (p
, one_inst
.relax_inst
, relax_size
);
1960 handle_dependency (struct score_it
*theinst
)
1963 int warn_or_error
= 0; /* warn - 0; error - 1 */
1965 int remainder_bubbles
= 0;
1966 char cur_insn
[INSN_NAME_LEN
];
1967 char pre_insn
[INSN_NAME_LEN
];
1968 struct score_it nop_inst
;
1969 struct score_it pflush_inst
;
1971 nop_inst
.instruction
= 0x0000;
1973 nop_inst
.relax_inst
= 0x80008000;
1974 nop_inst
.relax_size
= 4;
1975 nop_inst
.type
= NO16_OPD
;
1977 pflush_inst
.instruction
= 0x8000800a;
1978 pflush_inst
.size
= 4;
1979 pflush_inst
.relax_inst
= 0x8000;
1980 pflush_inst
.relax_size
= 0;
1981 pflush_inst
.type
= NO_OPD
;
1983 /* pflush will clear all data dependency. */
1984 if (strcmp (theinst
->name
, "pflush") == 0)
1986 init_dependency_vector ();
1990 /* Push current instruction to dependency_vector[0]. */
1991 for (i
= vector_size
- 1; i
> 0; i
--)
1992 memcpy (&dependency_vector
[i
], &dependency_vector
[i
- 1], sizeof (dependency_vector
[i
]));
1994 memcpy (&dependency_vector
[0], theinst
, sizeof (dependency_vector
[i
]));
1996 /* There is no dependency between nop and any instruction. */
1997 if (strcmp (dependency_vector
[0].name
, "nop") == 0
1998 || strcmp (dependency_vector
[0].name
, "nop!") == 0)
2001 /* "pce" is defined in insn_to_dependency_table. */
2002 #define PCE_NAME "pce"
2004 if (dependency_vector
[0].type
== Insn_Type_PCE
)
2005 strcpy (cur_insn
, PCE_NAME
);
2007 strcpy (cur_insn
, dependency_vector
[0].name
);
2009 for (i
= 1; i
< vector_size
; i
++)
2011 /* The element of dependency_vector is NULL. */
2012 if (dependency_vector
[i
].name
[0] == '\0')
2015 if (dependency_vector
[i
].type
== Insn_Type_PCE
)
2016 strcpy (pre_insn
, PCE_NAME
);
2018 strcpy (pre_insn
, dependency_vector
[i
].name
);
2020 bubbles
= check_dependency (pre_insn
, dependency_vector
[i
].reg
,
2021 cur_insn
, dependency_vector
[0].reg
, &warn_or_error
);
2022 remainder_bubbles
= bubbles
- i
+ 1;
2024 if (remainder_bubbles
> 0)
2028 if (fix_data_dependency
== 1)
2030 if (remainder_bubbles
<= 2)
2032 if (warn_fix_data_dependency
)
2033 as_warn ("Fix data dependency: %s %s -- %s %s (insert %d nop!/%d)",
2034 dependency_vector
[i
].name
, dependency_vector
[i
].reg
,
2035 dependency_vector
[0].name
, dependency_vector
[0].reg
,
2036 remainder_bubbles
, bubbles
);
2038 for (j
= (vector_size
- 1); (j
- remainder_bubbles
) > 0; j
--)
2039 memcpy (&dependency_vector
[j
], &dependency_vector
[j
- remainder_bubbles
],
2040 sizeof (dependency_vector
[j
]));
2042 for (j
= 1; j
<= remainder_bubbles
; j
++)
2044 memset (&dependency_vector
[j
], '\0', sizeof (dependency_vector
[j
]));
2046 build_one_frag (nop_inst
);
2051 if (warn_fix_data_dependency
)
2052 as_warn ("Fix data dependency: %s %s -- %s %s (insert 1 pflush/%d)",
2053 dependency_vector
[i
].name
, dependency_vector
[i
].reg
,
2054 dependency_vector
[0].name
, dependency_vector
[0].reg
,
2057 for (j
= 1; j
< vector_size
; j
++)
2058 memset (&dependency_vector
[j
], '\0', sizeof (dependency_vector
[j
]));
2060 /* Insert pflush. */
2061 build_one_frag (pflush_inst
);
2068 as_bad ("data dependency: %s %s -- %s %s (%d/%d bubble)",
2069 dependency_vector
[i
].name
, dependency_vector
[i
].reg
,
2070 dependency_vector
[0].name
, dependency_vector
[0].reg
,
2071 remainder_bubbles
, bubbles
);
2075 as_warn ("data dependency: %s %s -- %s %s (%d/%d bubble)",
2076 dependency_vector
[i
].name
, dependency_vector
[i
].reg
,
2077 dependency_vector
[0].name
, dependency_vector
[0].reg
,
2078 remainder_bubbles
, bubbles
);
2085 static enum insn_class
2086 get_insn_class_from_type (enum score_insn_type type
)
2088 enum insn_class retval
= (int) FAIL
;
2094 case Rd_rvalueBP_I5
:
2095 case Rd_lvalueBP_I5
:
2106 retval
= INSN_CLASS_16
;
2115 case Rd_rvalueRs_SI10
:
2116 case Rd_lvalueRs_SI10
:
2117 case Rd_rvalueRs_preSI12
:
2118 case Rd_rvalueRs_postSI12
:
2119 case Rd_lvalueRs_preSI12
:
2120 case Rd_lvalueRs_postSI12
:
2122 case Rd_rvalueRs_SI15
:
2123 case Rd_lvalueRs_SI15
:
2132 case OP5_rvalueRs_SI15
:
2133 case I5_Rs_Rs_I5_OP5
:
2134 case x_rvalueRs_post4
:
2135 case Rd_rvalueRs_post4
:
2137 case Rd_lvalueRs_post4
:
2138 case x_lvalueRs_post4
:
2145 retval
= INSN_CLASS_32
;
2148 retval
= INSN_CLASS_PCE
;
2151 retval
= INSN_CLASS_SYN
;
2160 static unsigned long
2161 adjust_paritybit (unsigned long m_code
, enum insn_class
class)
2163 unsigned long result
= 0;
2164 unsigned long m_code_high
= 0;
2165 unsigned long m_code_low
= 0;
2166 unsigned long pb_high
= 0;
2167 unsigned long pb_low
= 0;
2169 if (class == INSN_CLASS_32
)
2171 pb_high
= 0x80000000;
2172 pb_low
= 0x00008000;
2174 else if (class == INSN_CLASS_16
)
2179 else if (class == INSN_CLASS_PCE
)
2182 pb_low
= 0x00008000;
2184 else if (class == INSN_CLASS_SYN
)
2186 /* FIXME. at this time, INSN_CLASS_SYN must be 32 bit, but, instruction type should
2187 be changed if macro instruction has been expanded. */
2188 pb_high
= 0x80000000;
2189 pb_low
= 0x00008000;
2196 m_code_high
= m_code
& 0x3fff8000;
2197 m_code_low
= m_code
& 0x00007fff;
2198 result
= pb_high
| (m_code_high
<< 1) | pb_low
| m_code_low
;
2204 gen_insn_frag (struct score_it
*part_1
, struct score_it
*part_2
)
2207 bfd_boolean pce_p
= FALSE
;
2208 int relaxable_p
= g_opt
;
2210 struct score_it
*inst1
= part_1
;
2211 struct score_it
*inst2
= part_2
;
2212 struct score_it backup_inst1
;
2214 pce_p
= (inst2
) ? TRUE
: FALSE
;
2215 memcpy (&backup_inst1
, inst1
, sizeof (struct score_it
));
2217 /* Adjust instruction opcode and to be relaxed instruction opcode. */
2220 backup_inst1
.instruction
= ((backup_inst1
.instruction
& 0x7FFF) << 15)
2221 | (inst2
->instruction
& 0x7FFF);
2222 backup_inst1
.instruction
= adjust_paritybit (backup_inst1
.instruction
, INSN_CLASS_PCE
);
2223 backup_inst1
.relax_inst
= 0x8000;
2224 backup_inst1
.size
= INSN_SIZE
;
2225 backup_inst1
.relax_size
= 0;
2226 backup_inst1
.type
= Insn_Type_PCE
;
2230 backup_inst1
.instruction
= adjust_paritybit (backup_inst1
.instruction
,
2231 GET_INSN_CLASS (backup_inst1
.type
));
2234 if (backup_inst1
.relax_size
!= 0)
2236 enum insn_class tmp
;
2238 tmp
= (backup_inst1
.size
== INSN_SIZE
) ? INSN_CLASS_16
: INSN_CLASS_32
;
2239 backup_inst1
.relax_inst
= adjust_paritybit (backup_inst1
.relax_inst
, tmp
);
2242 /* Check data dependency. */
2243 handle_dependency (&backup_inst1
);
2245 /* Start a new frag if frag_now is not empty and is not instruction frag, maybe it contains
2246 data produced by .ascii etc. Doing this is to make one instruction per frag. */
2247 if (frag_now_fix () != 0)
2249 if (!frag_now
->tc_frag_data
.is_insn
)
2250 frag_wane (frag_now
);
2255 /* Here, we must call frag_grow in order to keep the instruction frag type is
2256 rs_machine_dependent.
2257 For, frag_var may change frag_now->fr_type to rs_fill by calling frag_grow which
2258 acturally will call frag_wane.
2259 Calling frag_grow first will create a new frag_now which free size is 20 that is enough
2263 p
= frag_more (backup_inst1
.size
);
2264 md_number_to_chars (p
, backup_inst1
.instruction
, backup_inst1
.size
);
2267 dwarf2_emit_insn (backup_inst1
.size
);
2270 /* Generate fixup structure. */
2273 if (inst1
->reloc
.type
!= BFD_RELOC_NONE
)
2274 fix_new_score (frag_now
, p
- frag_now
->fr_literal
,
2275 inst1
->size
, &inst1
->reloc
.exp
,
2276 inst1
->reloc
.pc_rel
, inst1
->reloc
.type
);
2278 if (inst2
->reloc
.type
!= BFD_RELOC_NONE
)
2279 fix_new_score (frag_now
, p
- frag_now
->fr_literal
+ 2,
2280 inst2
->size
, &inst2
->reloc
.exp
, inst2
->reloc
.pc_rel
, inst2
->reloc
.type
);
2284 if (backup_inst1
.reloc
.type
!= BFD_RELOC_NONE
)
2285 fix_new_score (frag_now
, p
- frag_now
->fr_literal
,
2286 backup_inst1
.size
, &backup_inst1
.reloc
.exp
,
2287 backup_inst1
.reloc
.pc_rel
, backup_inst1
.reloc
.type
);
2290 /* relax_size may be 2, 4, 12 or 0, 0 indicates no relaxation. */
2291 relaxable_p
&= (backup_inst1
.relax_size
!= 0);
2292 relax_size
= relaxable_p
? backup_inst1
.relax_size
: 0;
2294 p
= frag_var (rs_machine_dependent
, relax_size
+ RELAX_PAD_BYTE
, 0,
2295 RELAX_ENCODE (backup_inst1
.size
, backup_inst1
.relax_size
,
2296 backup_inst1
.type
, 0, 0, relaxable_p
),
2297 backup_inst1
.reloc
.exp
.X_add_symbol
, 0, NULL
);
2300 md_number_to_chars (p
, backup_inst1
.relax_inst
, relax_size
);
2302 memcpy (inst1
, &backup_inst1
, sizeof (struct score_it
));
2306 parse_16_32_inst (char *insnstr
, bfd_boolean gen_frag_p
)
2310 char *operator = insnstr
;
2311 const struct asm_opcode
*opcode
;
2313 /* Parse operator and operands. */
2314 skip_whitespace (operator);
2316 for (p
= operator; *p
!= '\0'; p
++)
2317 if ((*p
== ' ') || (*p
== '!'))
2326 opcode
= (const struct asm_opcode
*) hash_find (score_ops_hsh
, operator);
2329 memset (&inst
, '\0', sizeof (inst
));
2330 sprintf (inst
.str
, "%s", insnstr
);
2333 inst
.instruction
= opcode
->value
;
2334 inst
.relax_inst
= opcode
->relax_value
;
2335 inst
.type
= opcode
->type
;
2336 inst
.size
= GET_INSN_SIZE (inst
.type
);
2337 inst
.relax_size
= 0;
2339 sprintf (inst
.name
, "%s", opcode
->template);
2340 strcpy (inst
.reg
, "");
2342 inst
.reloc
.type
= BFD_RELOC_NONE
;
2344 (*opcode
->parms
) (p
);
2346 /* It indicates current instruction is a macro instruction if inst.bwarn equals -1. */
2347 if ((inst
.bwarn
!= -1) && (!inst
.error
) && (gen_frag_p
))
2348 gen_insn_frag (&inst
, NULL
);
2351 inst
.error
= _("unrecognized opcode");
2355 append_insn (char *str
, bfd_boolean gen_frag_p
)
2357 int retval
= SUCCESS
;
2359 parse_16_32_inst (str
, gen_frag_p
);
2363 retval
= (int) FAIL
;
2364 as_bad ("%s -- `%s'", inst
.error
, inst
.str
);
2371 /* Handle mv! reg_high, reg_low;
2372 mv! reg_low, reg_high;
2373 mv! reg_low, reg_low; */
2375 do16_mv_rdrs (char *str
)
2379 char *backupstr
= NULL
;
2382 skip_whitespace (str
);
2384 if ((reg_rd
= reg_required_here (&str
, 8, REG_TYPE_SCORE
)) == (int) FAIL
2385 || skip_past_comma (&str
) == (int) FAIL
2386 || (reg_rs
= reg_required_here (&str
, 4, REG_TYPE_SCORE
)) == (int) FAIL
2387 || end_of_line (str
) == (int) FAIL
)
2393 /* Case 1 : mv! or mlfh!. */
2398 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 20)
2399 | (((inst
.instruction
>> 4) & 0xf) << 15) | (0xf << 10);
2400 inst
.relax_size
= 4;
2404 char append_str
[MAX_LITERAL_POOL_SIZE
];
2406 sprintf (append_str
, "mlfh! %s", backupstr
);
2407 if (append_insn (append_str
, TRUE
) == (int) FAIL
)
2409 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
2413 /* Case 2 : mhfl!. */
2418 SET_INSN_ERROR (BAD_ARGS
);
2423 char append_str
[MAX_LITERAL_POOL_SIZE
];
2425 sprintf (append_str
, "mhfl! %s", backupstr
);
2426 if (append_insn (append_str
, TRUE
) == (int) FAIL
)
2429 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
2437 do16_rdi4 (char *str
)
2439 skip_whitespace (str
);
2441 if (reglow_required_here (&str
, 8) == (int) FAIL
2442 || skip_past_comma (&str
) == (int) FAIL
2443 || data_op2 (&str
, 3, _IMM4
) == (int) FAIL
2444 || end_of_line (str
) == (int) FAIL
)
2450 if (((inst
.instruction
>> 3) & 0x10) == 0) /* for judge is addei or subei : bit 5 =0 : addei */
2452 if (((inst
.instruction
>> 3) & 0xf) != 0xf)
2454 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 20)
2455 | ((1 << ((inst
.instruction
>> 3) & 0xf)) << 1);
2456 inst
.relax_size
= 4;
2460 inst
.relax_inst
= 0x8000;
2465 if (((inst
.instruction
>> 3) & 0xf) != 0xf)
2467 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 20)
2468 | (((-(1 << ((inst
.instruction
>> 3) & 0xf))) & 0xffff) << 1);
2469 inst
.relax_size
= 4;
2473 inst
.relax_inst
= 0x8000;
2480 do16_rdi5 (char *str
)
2482 skip_whitespace (str
);
2484 if (reglow_required_here (&str
, 8) == (int) FAIL
2485 || skip_past_comma (&str
) == (int) FAIL
2486 || data_op2 (&str
, 3, _IMM5
) == (int) FAIL
2487 || end_of_line (str
) == (int) FAIL
)
2491 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 20)
2492 | (((inst
.instruction
>> 8) & 0xf) << 15) | (((inst
.instruction
>> 3) & 0x1f) << 10);
2493 inst
.relax_size
= 4;
2499 do16_xi5 (char *str
)
2501 skip_whitespace (str
);
2503 if (data_op2 (&str
, 3, _IMM5
) == (int) FAIL
|| end_of_line (str
) == (int) FAIL
)
2507 inst
.relax_inst
|= (((inst
.instruction
>> 3) & 0x1f) << 15);
2508 inst
.relax_size
= 4;
2512 /* Check that an immediate is word alignment or half word alignment.
2513 If so, convert it to the right format. */
2515 validate_immediate_align (int val
, unsigned int data_type
)
2517 if (data_type
== _IMM5_RSHIFT_1
)
2521 inst
.error
= _("address offset must be half word alignment");
2525 else if ((data_type
== _IMM5_RSHIFT_2
) || (data_type
== _IMM10_RSHIFT_2
))
2529 inst
.error
= _("address offset must be word alignment");
2538 exp_ldst_offset (char **str
, int shift
, unsigned int data_type
)
2544 if ((*dataptr
== '0') && (*(dataptr
+ 1) == 'x')
2545 && (data_type
!= _SIMM16_LA
)
2546 && (data_type
!= _VALUE_HI16
)
2547 && (data_type
!= _VALUE_LO16
)
2548 && (data_type
!= _IMM16
)
2549 && (data_type
!= _IMM15
)
2550 && (data_type
!= _IMM14
)
2551 && (data_type
!= _IMM4
)
2552 && (data_type
!= _IMM5
)
2553 && (data_type
!= _IMM8
)
2554 && (data_type
!= _IMM5_RSHIFT_1
)
2555 && (data_type
!= _IMM5_RSHIFT_2
)
2556 && (data_type
!= _SIMM14_NEG
)
2557 && (data_type
!= _IMM10_RSHIFT_2
))
2562 if (my_get_expression (&inst
.reloc
.exp
, str
) == (int) FAIL
)
2565 if (inst
.reloc
.exp
.X_op
== O_constant
)
2567 /* Need to check the immediate align. */
2568 int value
= validate_immediate_align (inst
.reloc
.exp
.X_add_number
, data_type
);
2570 if (value
== (int) FAIL
)
2573 value
= validate_immediate (inst
.reloc
.exp
.X_add_number
, data_type
);
2574 if (value
== (int) FAIL
)
2580 "invalid constant: %d bit expression not in range %d..%d",
2581 score_df_range
[data_type
].bits
,
2582 score_df_range
[data_type
].range
[0], score_df_range
[data_type
].range
[1]);
2585 "invalid constant: %d bit expression not in range %d..%d",
2586 score_df_range
[data_type
- 24].bits
,
2587 score_df_range
[data_type
- 24].range
[0], score_df_range
[data_type
- 24].range
[1]);
2588 inst
.error
= _(err_msg
);
2592 if (data_type
== _IMM5_RSHIFT_1
)
2596 else if ((data_type
== _IMM5_RSHIFT_2
) || (data_type
== _IMM10_RSHIFT_2
))
2601 if (score_df_range
[data_type
].range
[0] != 0)
2603 value
&= (1 << score_df_range
[data_type
].bits
) - 1;
2606 inst
.instruction
|= value
<< shift
;
2610 inst
.reloc
.pc_rel
= 0;
2617 do_ldst_insn (char *str
)
2629 skip_whitespace (str
);
2631 if (((conflict_reg
= reg_required_here (&str
, 20, REG_TYPE_SCORE
)) == (int) FAIL
)
2632 || (skip_past_comma (&str
) == (int) FAIL
))
2635 /* ld/sw rD, [rA, simm15] ld/sw rD, [rA]+, simm12 ld/sw rD, [rA, simm12]+. */
2639 skip_whitespace (str
);
2641 if ((reg
= reg_required_here (&str
, 15, REG_TYPE_SCORE
)) == (int) FAIL
)
2644 /* Conflicts can occur on stores as well as loads. */
2645 conflict_reg
= (conflict_reg
== reg
);
2646 skip_whitespace (str
);
2647 temp
= str
+ 1; /* The latter will process decimal/hex expression. */
2649 /* ld/sw rD, [rA]+, simm12 ld/sw rD, [rA]+. */
2656 /* ld/sw rD, [rA]+, simm12. */
2657 if (skip_past_comma (&str
) == SUCCESS
)
2659 if ((exp_ldst_offset (&str
, 3, _SIMM12
) == (int) FAIL
)
2660 || (end_of_line (str
) == (int) FAIL
))
2665 unsigned int ldst_func
= inst
.instruction
& OPC_PSEUDOLDST_MASK
;
2667 if ((ldst_func
== INSN_LH
)
2668 || (ldst_func
== INSN_LHU
)
2669 || (ldst_func
== INSN_LW
)
2670 || (ldst_func
== INSN_LB
)
2671 || (ldst_func
== INSN_LBU
))
2673 inst
.error
= _("register same as write-back base");
2678 ldst_idx
= inst
.instruction
& OPC_PSEUDOLDST_MASK
;
2679 inst
.instruction
&= ~OPC_PSEUDOLDST_MASK
;
2680 inst
.instruction
|= score_ldst_insns
[ldst_idx
* 3 + LDST_POST
].value
;
2682 /* lw rD, [rA]+, 4 convert to pop rD, [rA]. */
2683 if ((inst
.instruction
& 0x3e000007) == 0x0e000000)
2685 /* rs = r0-r7, offset = 4 */
2686 if ((((inst
.instruction
>> 15) & 0x18) == 0)
2687 && (((inst
.instruction
>> 3) & 0xfff) == 4))
2689 /* Relax to pophi. */
2690 if ((((inst
.instruction
>> 20) & 0x10) == 0x10))
2692 inst
.relax_inst
= 0x0000200a | (((inst
.instruction
>> 20) & 0xf)
2694 (((inst
.instruction
>> 15) & 0x7) << 4);
2699 inst
.relax_inst
= 0x0000200a | (((inst
.instruction
>> 20) & 0xf)
2701 (((inst
.instruction
>> 15) & 0x7) << 4);
2703 inst
.relax_size
= 2;
2708 /* ld/sw rD, [rA]+ convert to ld/sw rD, [rA, 0]+. */
2711 SET_INSN_ERROR (NULL
);
2712 if (end_of_line (str
) == (int) FAIL
)
2718 value
= validate_immediate (inst
.reloc
.exp
.X_add_number
, _SIMM12
);
2719 value
&= (1 << score_df_range
[_SIMM12
].bits
) - 1;
2720 ldst_idx
= inst
.instruction
& OPC_PSEUDOLDST_MASK
;
2721 inst
.instruction
&= ~OPC_PSEUDOLDST_MASK
;
2722 inst
.instruction
|= score_ldst_insns
[ldst_idx
* 3 + pre_inc
].value
;
2723 inst
.instruction
|= value
<< 3;
2724 inst
.relax_inst
= 0x8000;
2728 /* ld/sw rD, [rA] convert to ld/sw rD, [rA, simm15]. */
2731 if (end_of_line (str
) == (int) FAIL
)
2734 ldst_idx
= inst
.instruction
& OPC_PSEUDOLDST_MASK
;
2735 inst
.instruction
&= ~OPC_PSEUDOLDST_MASK
;
2736 inst
.instruction
|= score_ldst_insns
[ldst_idx
* 3 + LDST_NOUPDATE
].value
;
2738 /* lbu rd, [rs] -> lbu! rd, [rs] */
2739 if (ldst_idx
== INSN_LBU
)
2741 inst
.relax_inst
= INSN16_LBU
;
2743 else if (ldst_idx
== INSN_LH
)
2745 inst
.relax_inst
= INSN16_LH
;
2747 else if (ldst_idx
== INSN_LW
)
2749 inst
.relax_inst
= INSN16_LW
;
2751 else if (ldst_idx
== INSN_SB
)
2753 inst
.relax_inst
= INSN16_SB
;
2755 else if (ldst_idx
== INSN_SH
)
2757 inst
.relax_inst
= INSN16_SH
;
2759 else if (ldst_idx
== INSN_SW
)
2761 inst
.relax_inst
= INSN16_SW
;
2765 inst
.relax_inst
= 0x8000;
2768 /* lw/lh/lbu/sw/sh/sb, offset = 0, relax to 16 bit instruction. */
2769 if ((ldst_idx
== INSN_LBU
)
2770 || (ldst_idx
== INSN_LH
)
2771 || (ldst_idx
== INSN_LW
)
2772 || (ldst_idx
== INSN_SB
) || (ldst_idx
== INSN_SH
) || (ldst_idx
== INSN_SW
))
2774 if ((((inst
.instruction
>> 15) & 0x10) == 0) && (((inst
.instruction
>> 20) & 0x10) == 0))
2776 inst
.relax_inst
|= (2 << 12) | (((inst
.instruction
>> 20) & 0xf) << 8) |
2777 (((inst
.instruction
>> 15) & 0xf) << 4);
2778 inst
.relax_size
= 2;
2785 /* ld/sw rD, [rA, simm15] ld/sw rD, [rA, simm12]+. */
2788 if (skip_past_comma (&str
) == (int) FAIL
)
2790 inst
.error
= _("pre-indexed expression expected");
2794 if (my_get_expression (&inst
.reloc
.exp
, &str
) == (int) FAIL
)
2797 skip_whitespace (str
);
2800 inst
.error
= _("missing ]");
2804 skip_whitespace (str
);
2805 /* ld/sw rD, [rA, simm12]+. */
2812 unsigned int ldst_func
= inst
.instruction
& OPC_PSEUDOLDST_MASK
;
2814 if ((ldst_func
== INSN_LH
)
2815 || (ldst_func
== INSN_LHU
)
2816 || (ldst_func
== INSN_LW
)
2817 || (ldst_func
== INSN_LB
)
2818 || (ldst_func
== INSN_LBU
))
2820 inst
.error
= _("register same as write-back base");
2826 if (end_of_line (str
) == (int) FAIL
)
2829 if (inst
.reloc
.exp
.X_op
== O_constant
)
2832 unsigned int data_type
;
2835 data_type
= _SIMM12
;
2837 data_type
= _SIMM15
;
2840 if ((*dataptr
== '0') && (*(dataptr
+ 1) == 'x')
2841 && (data_type
!= _SIMM16_LA
)
2842 && (data_type
!= _VALUE_HI16
)
2843 && (data_type
!= _VALUE_LO16
)
2844 && (data_type
!= _IMM16
)
2845 && (data_type
!= _IMM15
)
2846 && (data_type
!= _IMM14
)
2847 && (data_type
!= _IMM4
)
2848 && (data_type
!= _IMM5
)
2849 && (data_type
!= _IMM8
)
2850 && (data_type
!= _IMM5_RSHIFT_1
)
2851 && (data_type
!= _IMM5_RSHIFT_2
)
2852 && (data_type
!= _SIMM14_NEG
)
2853 && (data_type
!= _IMM10_RSHIFT_2
))
2858 value
= validate_immediate (inst
.reloc
.exp
.X_add_number
, data_type
);
2859 if (value
== (int) FAIL
)
2865 "invalid constant: %d bit expression not in range %d..%d",
2866 score_df_range
[data_type
].bits
,
2867 score_df_range
[data_type
].range
[0], score_df_range
[data_type
].range
[1]);
2870 "invalid constant: %d bit expression not in range %d..%d",
2871 score_df_range
[data_type
- 21].bits
,
2872 score_df_range
[data_type
- 21].range
[0],
2873 score_df_range
[data_type
- 21].range
[1]);
2874 inst
.error
= _(err_msg
);
2878 value
&= (1 << score_df_range
[data_type
].bits
) - 1;
2879 ldst_idx
= inst
.instruction
& OPC_PSEUDOLDST_MASK
;
2880 inst
.instruction
&= ~OPC_PSEUDOLDST_MASK
;
2881 inst
.instruction
|= score_ldst_insns
[ldst_idx
* 3 + pre_inc
].value
;
2883 inst
.instruction
|= value
<< 3;
2885 inst
.instruction
|= value
;
2887 /* lw rD, [rA, simm15] */
2888 if ((inst
.instruction
& 0x3e000000) == 0x20000000)
2890 /* Both rD and rA are in [r0 - r15]. */
2891 if ((((inst
.instruction
>> 15) & 0x10) == 0)
2892 && (((inst
.instruction
>> 20) & 0x10) == 0))
2894 /* simm15 = 0, lw -> lw!. */
2895 if ((inst
.instruction
& 0x7fff) == 0)
2897 inst
.relax_inst
|= (((inst
.instruction
>> 15) & 0xf) << 4)
2898 | (((inst
.instruction
>> 20) & 0xf) << 8);
2899 inst
.relax_size
= 2;
2901 /* rA = r2, lw -> lwp!. */
2902 else if ((((inst
.instruction
>> 15) & 0xf) == 2)
2903 && ((inst
.instruction
& 0x3) == 0)
2904 && ((inst
.instruction
& 0x7fff) < 128))
2906 inst
.relax_inst
= 0x7000 | (((inst
.instruction
>> 20) & 0xf) << 8)
2907 | (((inst
.instruction
& 0x7fff) >> 2) << 3);
2908 inst
.relax_size
= 2;
2912 inst
.relax_inst
= 0x8000;
2917 inst
.relax_inst
= 0x8000;
2920 /* sw rD, [rA, simm15] */
2921 else if ((inst
.instruction
& 0x3e000000) == 0x28000000)
2923 /* Both rD and rA are in [r0 - r15]. */
2924 if ((((inst
.instruction
>> 15) & 0x10) == 0) && (((inst
.instruction
>> 20) & 0x10) == 0))
2926 /* simm15 = 0, sw -> sw!. */
2927 if ((inst
.instruction
& 0x7fff) == 0)
2929 inst
.relax_inst
|= (((inst
.instruction
>> 15) & 0xf) << 4)
2930 | (((inst
.instruction
>> 20) & 0xf) << 8);
2931 inst
.relax_size
= 2;
2933 /* rA = r2, sw -> swp!. */
2934 else if ((((inst
.instruction
>> 15) & 0xf) == 2)
2935 && ((inst
.instruction
& 0x3) == 0)
2936 && ((inst
.instruction
& 0x7fff) < 128))
2938 inst
.relax_inst
= 0x7004 | (((inst
.instruction
>> 20) & 0xf) << 8)
2939 | (((inst
.instruction
& 0x7fff) >> 2) << 3);
2940 inst
.relax_size
= 2;
2944 inst
.relax_inst
= 0x8000;
2949 inst
.relax_inst
= 0x8000;
2952 /* sw rD, [rA, simm15]+ sw pre. */
2953 else if ((inst
.instruction
& 0x3e000007) == 0x06000004)
2955 /* rA is in [r0 - r7], and simm15 = -4. */
2956 if ((((inst
.instruction
>> 15) & 0x18) == 0)
2957 && (((inst
.instruction
>> 3) & 0xfff) == 0xffc))
2959 /* sw -> pushhi!. */
2960 if ((((inst
.instruction
>> 20) & 0x10) == 0x10))
2962 inst
.relax_inst
= 0x0000200e | (((inst
.instruction
>> 20) & 0xf) << 8)
2963 | 1 << 7 | (((inst
.instruction
>> 15) & 0x7) << 4);
2964 inst
.relax_size
= 2;
2969 inst
.relax_inst
= 0x0000200e | (((inst
.instruction
>> 20) & 0xf) << 8)
2970 | 0 << 7 | (((inst
.instruction
>> 15) & 0x7) << 4);
2971 inst
.relax_size
= 2;
2976 inst
.relax_inst
= 0x8000;
2979 /* lh rD, [rA, simm15] */
2980 else if ((inst
.instruction
& 0x3e000000) == 0x22000000)
2982 /* Both rD and rA are in [r0 - r15]. */
2983 if ((((inst
.instruction
>> 15) & 0x10) == 0) && (((inst
.instruction
>> 20) & 0x10) == 0))
2985 /* simm15 = 0, lh -> lh!. */
2986 if ((inst
.instruction
& 0x7fff) == 0)
2988 inst
.relax_inst
|= (((inst
.instruction
>> 15) & 0xf) << 4)
2989 | (((inst
.instruction
>> 20) & 0xf) << 8);
2990 inst
.relax_size
= 2;
2992 /* rA = r2, lh -> lhp!. */
2993 else if ((((inst
.instruction
>> 15) & 0xf) == 2)
2994 && ((inst
.instruction
& 0x1) == 0)
2995 && ((inst
.instruction
& 0x7fff) < 64))
2997 inst
.relax_inst
= 0x7001 | (((inst
.instruction
>> 20) & 0xf) << 8)
2998 | (((inst
.instruction
& 0x7fff) >> 1) << 3);
2999 inst
.relax_size
= 2;
3003 inst
.relax_inst
= 0x8000;
3008 inst
.relax_inst
= 0x8000;
3011 /* sh rD, [rA, simm15] */
3012 else if ((inst
.instruction
& 0x3e000000) == 0x2a000000)
3014 /* Both rD and rA are in [r0 - r15]. */
3015 if ((((inst
.instruction
>> 15) & 0x10) == 0) && (((inst
.instruction
>> 20) & 0x10) == 0))
3017 /* simm15 = 0, sh -> sh!. */
3018 if ((inst
.instruction
& 0x7fff) == 0)
3020 inst
.relax_inst
|= (((inst
.instruction
>> 15) & 0xf) << 4)
3021 | (((inst
.instruction
>> 20) & 0xf) << 8);
3022 inst
.relax_size
= 2;
3024 /* rA = r2, sh -> shp!. */
3025 else if ((((inst
.instruction
>> 15) & 0xf) == 2)
3026 && ((inst
.instruction
& 0x1) == 0)
3027 && ((inst
.instruction
& 0x7fff) < 64))
3029 inst
.relax_inst
= 0x7005 | (((inst
.instruction
>> 20) & 0xf) << 8)
3030 | (((inst
.instruction
& 0x7fff) >> 1) << 3);
3031 inst
.relax_size
= 2;
3035 inst
.relax_inst
= 0x8000;
3040 inst
.relax_inst
= 0x8000;
3043 /* lbu rD, [rA, simm15] */
3044 else if ((inst
.instruction
& 0x3e000000) == 0x2c000000)
3046 /* Both rD and rA are in [r0 - r15]. */
3047 if ((((inst
.instruction
>> 15) & 0x10) == 0) && (((inst
.instruction
>> 20) & 0x10) == 0))
3049 /* simm15 = 0, lbu -> lbu!. */
3050 if ((inst
.instruction
& 0x7fff) == 0)
3052 inst
.relax_inst
|= (((inst
.instruction
>> 15) & 0xf) << 4)
3053 | (((inst
.instruction
>> 20) & 0xf) << 8);
3054 inst
.relax_size
= 2;
3056 /* rA = r2, lbu -> lbup!. */
3057 else if ((((inst
.instruction
>> 15) & 0xf) == 2)
3058 && ((inst
.instruction
& 0x7fff) < 32))
3060 inst
.relax_inst
= 0x7003 | (((inst
.instruction
>> 20) & 0xf) << 8)
3061 | ((inst
.instruction
& 0x7fff) << 3);
3062 inst
.relax_size
= 2;
3066 inst
.relax_inst
= 0x8000;
3071 inst
.relax_inst
= 0x8000;
3074 /* sb rD, [rA, simm15] */
3075 else if ((inst
.instruction
& 0x3e000000) == 0x2e000000)
3077 /* Both rD and rA are in [r0 - r15]. */
3078 if ((((inst
.instruction
>> 15) & 0x10) == 0) && (((inst
.instruction
>> 20) & 0x10) == 0))
3080 /* simm15 = 0, sb -> sb!. */
3081 if ((inst
.instruction
& 0x7fff) == 0)
3083 inst
.relax_inst
|= (((inst
.instruction
>> 15) & 0xf) << 4)
3084 | (((inst
.instruction
>> 20) & 0xf) << 8);
3085 inst
.relax_size
= 2;
3087 /* rA = r2, sb -> sb!. */
3088 else if ((((inst
.instruction
>> 15) & 0xf) == 2)
3089 && ((inst
.instruction
& 0x7fff) < 32))
3091 inst
.relax_inst
= 0x7007 | (((inst
.instruction
>> 20) & 0xf) << 8)
3092 | ((inst
.instruction
& 0x7fff) << 3);
3093 inst
.relax_size
= 2;
3097 inst
.relax_inst
= 0x8000;
3102 inst
.relax_inst
= 0x8000;
3107 inst
.relax_inst
= 0x8000;
3114 /* FIXME: may set error, for there is no ld/sw rD, [rA, label] */
3115 inst
.reloc
.pc_rel
= 0;
3121 inst
.error
= BAD_ARGS
;
3128 do_cache (char *str
)
3130 skip_whitespace (str
);
3132 if ((data_op2 (&str
, 20, _IMM5
) == (int) FAIL
) || (skip_past_comma (&str
) == (int) FAIL
))
3140 cache_op
= (inst
.instruction
>> 20) & 0x1F;
3141 sprintf (inst
.name
, "cache %d", cache_op
);
3147 skip_whitespace (str
);
3149 if (reg_required_here (&str
, 15, REG_TYPE_SCORE
) == (int) FAIL
)
3152 skip_whitespace (str
);
3154 /* cache op, [rA] */
3155 if (skip_past_comma (&str
) == (int) FAIL
)
3157 SET_INSN_ERROR (NULL
);
3160 inst
.error
= _("missing ]");
3165 /* cache op, [rA, simm15] */
3168 if (exp_ldst_offset (&str
, 0, _SIMM15
) == (int) FAIL
)
3173 skip_whitespace (str
);
3176 inst
.error
= _("missing ]");
3181 if (end_of_line (str
) == (int) FAIL
)
3186 inst
.error
= BAD_ARGS
;
3191 do_crdcrscrsimm5 (char *str
)
3196 skip_whitespace (str
);
3198 if (reg_required_here (&str
, 20, REG_TYPE_SCORE_CR
) == (int) FAIL
3199 || skip_past_comma (&str
) == (int) FAIL
3200 || reg_required_here (&str
, 15, REG_TYPE_SCORE_CR
) == (int) FAIL
3201 || skip_past_comma (&str
) == (int) FAIL
3202 || reg_required_here (&str
, 10, REG_TYPE_SCORE_CR
) == (int) FAIL
3203 || skip_past_comma (&str
) == (int) FAIL
)
3206 /* cop1 cop_code20. */
3207 if (data_op2 (&str
, 5, _IMM20
) == (int) FAIL
)
3212 if (data_op2 (&str
, 5, _IMM5
) == (int) FAIL
)
3219 /* Handle ldc/stc. */
3221 do_ldst_cop (char *str
)
3223 skip_whitespace (str
);
3225 if ((reg_required_here (&str
, 15, REG_TYPE_SCORE_CR
) == (int) FAIL
)
3226 || (skip_past_comma (&str
) == (int) FAIL
))
3232 skip_whitespace (str
);
3234 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) == (int) FAIL
)
3237 skip_whitespace (str
);
3241 if (exp_ldst_offset (&str
, 5, _IMM10_RSHIFT_2
) == (int) FAIL
)
3244 skip_whitespace (str
);
3247 inst
.error
= _("missing ]");
3255 inst
.error
= BAD_ARGS
;
3259 do16_ldst_insn (char *str
)
3261 skip_whitespace (str
);
3263 if ((reglow_required_here (&str
, 8) == (int) FAIL
) || (skip_past_comma (&str
) == (int) FAIL
))
3271 skip_whitespace (str
);
3273 if ((reg
= reglow_required_here (&str
, 4)) == (int) FAIL
)
3276 skip_whitespace (str
);
3279 if (end_of_line (str
) == (int) FAIL
)
3283 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 20)
3284 | (((inst
.instruction
>> 4) & 0xf) << 15);
3285 inst
.relax_size
= 4;
3290 inst
.error
= _("missing ]");
3295 inst
.error
= BAD_ARGS
;
3299 /* Handle lbup!/lhp!/ldiu!/lwp!/sbp!/shp!/swp!. */
3301 do16_ldst_imm_insn (char *str
)
3303 char data_exp
[MAX_LITERAL_POOL_SIZE
];
3305 char *dataptr
= NULL
, *pp
= NULL
;
3307 int assign_data
= (int) FAIL
;
3308 unsigned int ldst_func
;
3310 skip_whitespace (str
);
3312 if (((reg_rd
= reglow_required_here (&str
, 8)) == (int) FAIL
)
3313 || (skip_past_comma (&str
) == (int) FAIL
))
3316 skip_whitespace (str
);
3319 while ((*dataptr
!= '\0') && (*dataptr
!= '|') && (cnt
<= MAX_LITERAL_POOL_SIZE
))
3321 data_exp
[cnt
] = *dataptr
;
3326 data_exp
[cnt
] = '\0';
3331 ldst_func
= inst
.instruction
& LDST16_RI_MASK
;
3332 if (ldst_func
== N16_LIU
)
3333 assign_data
= exp_ldst_offset (&pp
, 0, _IMM8
);
3334 else if (ldst_func
== N16_LHP
|| ldst_func
== N16_SHP
)
3335 assign_data
= exp_ldst_offset (&pp
, 3, _IMM5_RSHIFT_1
);
3336 else if (ldst_func
== N16_LWP
|| ldst_func
== N16_SWP
)
3337 assign_data
= exp_ldst_offset (&pp
, 3, _IMM5_RSHIFT_2
);
3339 assign_data
= exp_ldst_offset (&pp
, 3, _IMM5
);
3341 if ((assign_data
== (int) FAIL
) || (end_of_line (pp
) == (int) FAIL
))
3345 if ((inst
.instruction
& 0x7000) == N16_LIU
)
3347 inst
.relax_inst
|= ((inst
.instruction
>> 8) & 0xf) << 20
3348 | ((inst
.instruction
& 0xff) << 1);
3350 else if (((inst
.instruction
& 0x7007) == N16_LHP
)
3351 || ((inst
.instruction
& 0x7007) == N16_SHP
))
3353 inst
.relax_inst
|= ((inst
.instruction
>> 8) & 0xf) << 20 | 2 << 15
3354 | (((inst
.instruction
>> 3) & 0x1f) << 1);
3356 else if (((inst
.instruction
& 0x7007) == N16_LWP
)
3357 || ((inst
.instruction
& 0x7007) == N16_SWP
))
3359 inst
.relax_inst
|= ((inst
.instruction
>> 8) & 0xf) << 20 | 2 << 15
3360 | (((inst
.instruction
>> 3) & 0x1f) << 2);
3362 else if (((inst
.instruction
& 0x7007) == N16_LBUP
)
3363 || ((inst
.instruction
& 0x7007) == N16_SBP
))
3365 inst
.relax_inst
|= ((inst
.instruction
>> 8) & 0xf) << 20 | 2 << 15
3366 | (((inst
.instruction
>> 3) & 0x1f));
3369 inst
.relax_size
= 4;
3374 do16_push_pop (char *str
)
3379 skip_whitespace (str
);
3380 if (((reg_rd
= reg_required_here (&str
, 8, REG_TYPE_SCORE
)) == (int) FAIL
)
3381 || (skip_past_comma (&str
) == (int) FAIL
))
3387 /* reg_required_here will change bit 12 of opcode, so we must restore bit 12. */
3388 inst
.instruction
&= ~(1 << 12);
3390 inst
.instruction
|= H_bit_mask
<< 7;
3397 skip_whitespace (str
);
3398 if ((reg
= reg_required_here (&str
, 4, REG_TYPE_SCORE
)) == (int) FAIL
)
3403 inst
.error
= _("base register nums are over 3 bit");
3408 skip_whitespace (str
);
3409 if ((*str
++ != ']') || (end_of_line (str
) == (int) FAIL
))
3412 inst
.error
= _("missing ]");
3418 if ((inst
.instruction
& 0xf) == 0xa)
3422 inst
.relax_inst
|= ((((inst
.instruction
>> 8) & 0xf) | 0x10) << 20)
3423 | (((inst
.instruction
>> 4) & 0x7) << 15) | (4 << 3);
3427 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 20)
3428 | (((inst
.instruction
>> 4) & 0x7) << 15) | (4 << 3);
3436 inst
.relax_inst
|= ((((inst
.instruction
>> 8) & 0xf) | 0x10) << 20)
3437 | (((inst
.instruction
>> 4) & 0x7) << 15) | (((-4) & 0xfff) << 3);
3441 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 20)
3442 | (((inst
.instruction
>> 4) & 0x7) << 15) | (((-4) & 0xfff) << 3);
3445 inst
.relax_size
= 4;
3449 inst
.error
= BAD_ARGS
;
3453 /* Handle lcb/lcw/lce/scb/scw/sce. */
3455 do_ldst_unalign (char *str
)
3459 if (university_version
== 1)
3461 inst
.error
= ERR_FOR_SCORE5U_ATOMIC
;
3465 skip_whitespace (str
);
3467 /* lcb/scb [rA]+. */
3471 skip_whitespace (str
);
3473 if (reg_required_here (&str
, 15, REG_TYPE_SCORE
) == (int) FAIL
)
3480 inst
.error
= _("missing +");
3486 inst
.error
= _("missing ]");
3490 if (end_of_line (str
) == (int) FAIL
)
3493 /* lcw/lce/scb/sce rD, [rA]+. */
3496 if (((conflict_reg
= reg_required_here (&str
, 20, REG_TYPE_SCORE
)) == (int) FAIL
)
3497 || (skip_past_comma (&str
) == (int) FAIL
))
3502 skip_whitespace (str
);
3507 skip_whitespace (str
);
3508 if ((reg
= reg_required_here (&str
, 15, REG_TYPE_SCORE
)) == (int) FAIL
)
3513 /* Conflicts can occur on stores as well as loads. */
3514 conflict_reg
= (conflict_reg
== reg
);
3515 skip_whitespace (str
);
3518 unsigned int ldst_func
= inst
.instruction
& LDST_UNALIGN_MASK
;
3524 as_warn (_("%s register same as write-back base"),
3525 ((ldst_func
& UA_LCE
) || (ldst_func
& UA_LCW
)
3526 ? _("destination") : _("source")));
3531 inst
.error
= _("missing +");
3535 if (end_of_line (str
) == (int) FAIL
)
3540 inst
.error
= _("missing ]");
3546 inst
.error
= BAD_ARGS
;
3552 /* Handle alw/asw. */
3554 do_ldst_atomic (char *str
)
3556 if (university_version
== 1)
3558 inst
.error
= ERR_FOR_SCORE5U_ATOMIC
;
3562 skip_whitespace (str
);
3564 if ((reg_required_here (&str
, 20, REG_TYPE_SCORE
) == (int) FAIL
)
3565 || (skip_past_comma (&str
) == (int) FAIL
))
3572 skip_whitespace (str
);
3577 skip_whitespace (str
);
3578 if ((reg
= reg_required_here (&str
, 15, REG_TYPE_SCORE
)) == (int) FAIL
)
3583 skip_whitespace (str
);
3586 inst
.error
= _("missing ]");
3593 inst
.error
= BAD_ARGS
;
3598 build_relax_frag (struct score_it fix_insts
[RELAX_INST_NUM
], int fix_num ATTRIBUTE_UNUSED
,
3599 struct score_it var_insts
[RELAX_INST_NUM
], int var_num
,
3600 symbolS
*add_symbol
)
3605 fixS
*head_fixp
= NULL
;
3607 struct score_it inst_main
;
3609 memcpy (&inst_main
, &fix_insts
[0], sizeof (struct score_it
));
3611 /* Adjust instruction opcode and to be relaxed instruction opcode. */
3612 inst_main
.instruction
= adjust_paritybit (inst_main
.instruction
, GET_INSN_CLASS (inst_main
.type
));
3613 inst_main
.type
= Insn_PIC
;
3615 for (i
= 0; i
< var_num
; i
++)
3617 inst_main
.relax_size
+= var_insts
[i
].size
;
3618 var_insts
[i
].instruction
= adjust_paritybit (var_insts
[i
].instruction
,
3619 GET_INSN_CLASS (var_insts
[i
].type
));
3622 /* Check data dependency. */
3623 handle_dependency (&inst_main
);
3625 /* Start a new frag if frag_now is not empty. */
3626 if (frag_now_fix () != 0)
3628 if (!frag_now
->tc_frag_data
.is_insn
)
3630 frag_wane (frag_now
);
3636 /* Write fr_fix part. */
3637 p
= frag_more (inst_main
.size
);
3638 md_number_to_chars (p
, inst_main
.instruction
, inst_main
.size
);
3640 if (inst_main
.reloc
.type
!= BFD_RELOC_NONE
)
3642 fixp
= fix_new_score (frag_now
, p
- frag_now
->fr_literal
, inst_main
.size
,
3643 &inst_main
.reloc
.exp
, inst_main
.reloc
.pc_rel
, inst_main
.reloc
.type
);
3646 head_fixp
= xmalloc (sizeof (fixS
*));
3647 frag_now
->tc_frag_data
.fixp
= head_fixp
;
3651 head_fixp
->fx_next
= fixp
;
3652 head_fixp
= head_fixp
->fx_next
;
3656 dwarf2_emit_insn (inst_main
.size
);
3659 where
= p
- frag_now
->fr_literal
+ inst_main
.size
;
3660 for (i
= 0; i
< var_num
; i
++)
3663 where
+= var_insts
[i
- 1].size
;
3665 if (var_insts
[i
].reloc
.type
!= BFD_RELOC_NONE
)
3667 fixp
= fix_new_score (frag_now
, where
, var_insts
[i
].size
,
3668 &var_insts
[i
].reloc
.exp
, var_insts
[i
].reloc
.pc_rel
,
3669 var_insts
[i
].reloc
.type
);
3672 head_fixp
->fx_next
= fixp
;
3673 head_fixp
= head_fixp
->fx_next
;
3678 head_fixp
= frag_now
->tc_frag_data
.fixp
;
3679 frag_now
->tc_frag_data
.fixp
= head_fixp
->fx_next
;
3682 p
= frag_var (rs_machine_dependent
, inst_main
.relax_size
+ RELAX_PAD_BYTE
, 0,
3683 RELAX_ENCODE (inst_main
.size
, inst_main
.relax_size
, inst_main
.type
,
3684 0, inst_main
.size
, 0), add_symbol
, 0, NULL
);
3686 /* Write fr_var part.
3687 no calling gen_insn_frag, no fixS will be generated. */
3688 for (i
= 0; i
< var_num
; i
++)
3690 md_number_to_chars (p
, var_insts
[i
].instruction
, var_insts
[i
].size
);
3691 p
+= var_insts
[i
].size
;
3693 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
3697 /* Build a relax frag for la instruction when generating PIC,
3698 external symbol first and local symbol second. */
3701 build_la_pic (int reg_rd
, expressionS exp
)
3703 symbolS
*add_symbol
= exp
.X_add_symbol
;
3704 offsetT add_number
= exp
.X_add_number
;
3705 struct score_it fix_insts
[RELAX_INST_NUM
];
3706 struct score_it var_insts
[RELAX_INST_NUM
];
3709 char tmp
[MAX_LITERAL_POOL_SIZE
];
3715 if (add_number
== 0)
3720 /* Insn 1 and Insn 2 */
3722 For an external symbol: lw rD, <sym>($gp)
3723 (BFD_RELOC_SCORE_GOT15 or BFD_RELOC_SCORE_CALL15) */
3724 sprintf (tmp
, "lw_pic r%d, %s", reg_rd
, add_symbol
->bsym
->name
);
3725 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
3728 if (reg_rd
== PIC_CALL_REG
)
3729 inst
.reloc
.type
= BFD_RELOC_SCORE_CALL15
;
3730 memcpy (&fix_insts
[0], &inst
, sizeof (struct score_it
));
3733 For a local symbol :
3734 lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15)
3735 addi rD, <sym> (BFD_RELOC_GOT_LO16) */
3736 inst
.reloc
.type
= BFD_RELOC_SCORE_GOT15
;
3737 memcpy (&var_insts
[0], &inst
, sizeof (struct score_it
));
3738 sprintf (tmp
, "addi_s_pic r%d, %s", reg_rd
, add_symbol
->bsym
->name
);
3739 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
3742 memcpy (&var_insts
[1], &inst
, sizeof (struct score_it
));
3743 build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
3745 else if (add_number
>= -0x8000 && add_number
<= 0x7fff)
3747 /* Insn 1: lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15) */
3748 sprintf (tmp
, "lw_pic r%d, %s", reg_rd
, add_symbol
->bsym
->name
);
3749 if (append_insn (tmp
, TRUE
) == (int) FAIL
)
3756 For an external symbol: addi rD, <constant> */
3757 sprintf (tmp
, "addi r%d, %d", reg_rd
, (int)add_number
);
3758 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
3761 memcpy (&fix_insts
[0], &inst
, sizeof (struct score_it
));
3764 For a local symbol: addi rD, <sym>+<constant> (BFD_RELOC_GOT_LO16) */
3765 sprintf (tmp
, "addi_s_pic r%d, %s + %d", reg_rd
, add_symbol
->bsym
->name
, (int)add_number
);
3766 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
3769 memcpy (&var_insts
[0], &inst
, sizeof (struct score_it
));
3770 build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
3774 int hi
= (add_number
>> 16) & 0x0000FFFF;
3775 int lo
= add_number
& 0x0000FFFF;
3777 /* Insn 1: lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15) */
3778 sprintf (tmp
, "lw_pic r%d, %s", reg_rd
, add_symbol
->bsym
->name
);
3779 if (append_insn (tmp
, TRUE
) == (int) FAIL
)
3786 For an external symbol: ldis r1, HI%<constant> */
3787 sprintf (tmp
, "ldis %s, %d", "r1", hi
);
3788 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
3791 memcpy (&fix_insts
[0], &inst
, sizeof (struct score_it
));
3794 For a local symbol: ldis r1, HI%<constant>
3795 but, if lo is outof 16 bit, make hi plus 1 */
3796 if ((lo
< -0x8000) || (lo
> 0x7fff))
3800 sprintf (tmp
, "ldis_pic %s, %d", "r1", hi
);
3801 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
3804 memcpy (&var_insts
[0], &inst
, sizeof (struct score_it
));
3805 build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
3811 For an external symbol: ori r1, LO%<constant> */
3812 sprintf (tmp
, "ori %s, %d", "r1", lo
);
3813 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
3816 memcpy (&fix_insts
[0], &inst
, sizeof (struct score_it
));
3819 For a local symbol: addi r1, <sym>+LO%<constant> (BFD_RELOC_GOT_LO16) */
3820 sprintf (tmp
, "addi_u_pic %s, %s + %d", "r1", add_symbol
->bsym
->name
, lo
);
3821 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
3824 memcpy (&var_insts
[0], &inst
, sizeof (struct score_it
));
3825 build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
3827 /* Insn 4: add rD, rD, r1 */
3828 sprintf (tmp
, "add r%d, r%d, %s", reg_rd
, reg_rd
, "r1");
3829 if (append_insn (tmp
, TRUE
) == (int) FAIL
)
3832 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
3841 do_macro_la_rdi32 (char *str
)
3845 skip_whitespace (str
);
3846 if ((reg_rd
= reg_required_here (&str
, 20, REG_TYPE_SCORE
)) == (int) FAIL
3847 || skip_past_comma (&str
) == (int) FAIL
)
3853 char append_str
[MAX_LITERAL_POOL_SIZE
];
3854 char *keep_data
= str
;
3856 /* la rd, simm16. */
3857 if (data_op2 (&str
, 1, _SIMM16_LA
) != (int) FAIL
)
3862 /* la rd, imm32 or la rd, label. */
3865 SET_INSN_ERROR (NULL
);
3867 if ((data_op2 (&str
, 1, _VALUE_HI16
) == (int) FAIL
)
3868 || (end_of_line (str
) == (int) FAIL
))
3874 if ((score_pic
== NO_PIC
) || (!inst
.reloc
.exp
.X_add_symbol
))
3876 sprintf (append_str
, "ld_i32hi r%d, %s", reg_rd
, keep_data
);
3877 if (append_insn (append_str
, TRUE
) == (int) FAIL
)
3880 sprintf (append_str
, "ld_i32lo r%d, %s", reg_rd
, keep_data
);
3881 if (append_insn (append_str
, TRUE
) == (int) FAIL
)
3886 assert (inst
.reloc
.exp
.X_add_symbol
);
3887 build_la_pic (reg_rd
, inst
.reloc
.exp
);
3890 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
3899 do_macro_li_rdi32 (char *str
){
3903 skip_whitespace (str
);
3904 if ((reg_rd
= reg_required_here (&str
, 20, REG_TYPE_SCORE
)) == (int) FAIL
3905 || skip_past_comma (&str
) == (int) FAIL
)
3911 char *keep_data
= str
;
3913 /* li rd, simm16. */
3914 if (data_op2 (&str
, 1, _SIMM16_LA
) != (int) FAIL
)
3922 char append_str
[MAX_LITERAL_POOL_SIZE
];
3926 if ((data_op2 (&str
, 1, _VALUE_HI16
) == (int) FAIL
)
3927 || (end_of_line (str
) == (int) FAIL
))
3931 else if (inst
.reloc
.exp
.X_add_symbol
)
3933 inst
.error
= _("li rd label isn't correct instruction form");
3938 sprintf (append_str
, "ld_i32hi r%d, %s", reg_rd
, keep_data
);
3940 if (append_insn (append_str
, TRUE
) == (int) FAIL
)
3944 sprintf (append_str
, "ld_i32lo r%d, %s", reg_rd
, keep_data
);
3945 if (append_insn (append_str
, TRUE
) == (int) FAIL
)
3948 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
3956 /* Handle mul/mulu/div/divu/rem/remu. */
3958 do_macro_mul_rdrsrs (char *str
)
3964 char append_str
[MAX_LITERAL_POOL_SIZE
];
3966 if (university_version
== 1)
3967 as_warn ("%s", ERR_FOR_SCORE5U_MUL_DIV
);
3969 strcpy (append_str
, str
);
3970 backupstr
= append_str
;
3971 skip_whitespace (backupstr
);
3972 if (((reg_rd
= reg_required_here (&backupstr
, -1, REG_TYPE_SCORE
)) == (int) FAIL
)
3973 || (skip_past_comma (&backupstr
) == (int) FAIL
)
3974 || ((reg_rs1
= reg_required_here (&backupstr
, -1, REG_TYPE_SCORE
)) == (int) FAIL
))
3976 inst
.error
= BAD_ARGS
;
3980 if (skip_past_comma (&backupstr
) == (int) FAIL
)
3982 /* rem/remu rA, rB is error format. */
3983 if (strcmp (inst
.name
, "rem") == 0 || strcmp (inst
.name
, "remu") == 0)
3985 SET_INSN_ERROR (BAD_ARGS
);
3989 SET_INSN_ERROR (NULL
);
3996 SET_INSN_ERROR (NULL
);
3997 if (((reg_rs2
= reg_required_here (&backupstr
, -1, REG_TYPE_SCORE
)) == (int) FAIL
)
3998 || (end_of_line (backupstr
) == (int) FAIL
))
4004 char append_str1
[MAX_LITERAL_POOL_SIZE
];
4006 if (strcmp (inst
.name
, "rem") == 0)
4008 sprintf (append_str
, "%s r%d, r%d", "mul", reg_rs1
, reg_rs2
);
4009 sprintf (append_str1
, "mfceh r%d", reg_rd
);
4011 else if (strcmp (inst
.name
, "remu") == 0)
4013 sprintf (append_str
, "%s r%d, r%d", "mulu", reg_rs1
, reg_rs2
);
4014 sprintf (append_str1
, "mfceh r%d", reg_rd
);
4018 sprintf (append_str
, "%s r%d, r%d", inst
.name
, reg_rs1
, reg_rs2
);
4019 sprintf (append_str1
, "mfcel r%d", reg_rd
);
4022 /* Output mul/mulu or div/divu or rem/remu. */
4023 if (append_insn (append_str
, TRUE
) == (int) FAIL
)
4026 /* Output mfcel or mfceh. */
4027 if (append_insn (append_str1
, TRUE
) == (int) FAIL
)
4030 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4037 exp_macro_ldst_abs (char *str
)
4040 char *backupstr
, *tmp
;
4041 char append_str
[MAX_LITERAL_POOL_SIZE
];
4042 char verifystr
[MAX_LITERAL_POOL_SIZE
];
4043 struct score_it inst_backup
;
4048 memcpy (&inst_backup
, &inst
, sizeof (struct score_it
));
4050 strcpy (verifystr
, str
);
4051 backupstr
= verifystr
;
4052 skip_whitespace (backupstr
);
4053 if ((reg_rd
= reg_required_here (&backupstr
, -1, REG_TYPE_SCORE
)) == (int) FAIL
)
4057 if (skip_past_comma (&backupstr
) == (int) FAIL
)
4061 sprintf (append_str
, "li r1 %s", backupstr
);
4062 append_insn (append_str
, TRUE
);
4064 memcpy (&inst
, &inst_backup
, sizeof (struct score_it
));
4065 sprintf (append_str
, " r%d, [r1,0]", reg_rd
);
4066 do_ldst_insn (append_str
);
4072 nopic_need_relax (symbolS
* sym
, int before_relaxing
)
4076 else if (USE_GLOBAL_POINTER_OPT
&& g_switch_value
> 0)
4078 const char *symname
;
4079 const char *segname
;
4081 /* Find out whether this symbol can be referenced off the $gp
4082 register. It can be if it is smaller than the -G size or if
4083 it is in the .sdata or .sbss section. Certain symbols can
4084 not be referenced off the $gp, although it appears as though
4086 symname
= S_GET_NAME (sym
);
4087 if (symname
!= (const char *)NULL
4088 && (strcmp (symname
, "eprol") == 0
4089 || strcmp (symname
, "etext") == 0
4090 || strcmp (symname
, "_gp") == 0
4091 || strcmp (symname
, "edata") == 0
4092 || strcmp (symname
, "_fbss") == 0
4093 || strcmp (symname
, "_fdata") == 0
4094 || strcmp (symname
, "_ftext") == 0
4095 || strcmp (symname
, "end") == 0
4096 || strcmp (symname
, GP_DISP_LABEL
) == 0))
4100 else if ((!S_IS_DEFINED (sym
) || S_IS_COMMON (sym
)) && (0
4101 /* We must defer this decision until after the whole file has been read,
4102 since there might be a .extern after the first use of this symbol. */
4104 && S_GET_VALUE (sym
) == 0)
4105 || (S_GET_VALUE (sym
) != 0
4106 && S_GET_VALUE (sym
) <= g_switch_value
)))
4111 segname
= segment_name (S_GET_SEGMENT (sym
));
4112 return (strcmp (segname
, ".sdata") != 0
4113 && strcmp (segname
, ".sbss") != 0
4114 && strncmp (segname
, ".sdata.", 7) != 0
4115 && strncmp (segname
, ".gnu.linkonce.s.", 16) != 0);
4117 /* We are not optimizing for the $gp register. */
4122 /* Build a relax frag for lw instruction when generating PIC,
4123 external symbol first and local symbol second. */
4126 build_lw_pic (int reg_rd
, expressionS exp
)
4128 symbolS
*add_symbol
= exp
.X_add_symbol
;
4129 int add_number
= exp
.X_add_number
;
4130 struct score_it fix_insts
[RELAX_INST_NUM
];
4131 struct score_it var_insts
[RELAX_INST_NUM
];
4134 char tmp
[MAX_LITERAL_POOL_SIZE
];
4140 if ((add_number
== 0) || (add_number
>= -0x8000 && add_number
<= 0x7fff))
4145 /* Insn 1 and Insn 2 */
4147 For an external symbol: lw rD, <sym>($gp)
4148 (BFD_RELOC_SCORE_GOT15) */
4149 sprintf (tmp
, "lw_pic r%d, %s", reg_rd
, add_symbol
->bsym
->name
);
4150 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
4153 memcpy (&fix_insts
[0], &inst
, sizeof (struct score_it
));
4156 For a local symbol :
4157 lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15)
4158 addi rD, <sym> (BFD_RELOC_GOT_LO16) */
4159 inst
.reloc
.type
= BFD_RELOC_SCORE_GOT15
;
4160 memcpy (&var_insts
[0], &inst
, sizeof (struct score_it
));
4161 sprintf (tmp
, "addi_s_pic r%d, %s", reg_rd
, add_symbol
->bsym
->name
);
4162 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
4165 memcpy (&var_insts
[1], &inst
, sizeof (struct score_it
));
4166 build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
4168 /* Insn 2: lw rD, [rD, constant] */
4169 sprintf (tmp
, "lw r%d, [r%d, %d]", reg_rd
, reg_rd
, add_number
);
4170 if (append_insn (tmp
, TRUE
) == (int) FAIL
)
4173 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4178 int hi
= (add_number
>> 16) & 0x0000FFFF;
4179 int lo
= add_number
& 0x0000FFFF;
4181 /* Insn 1: lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15) */
4182 sprintf (tmp
, "lw_pic r%d, %s", reg_rd
, add_symbol
->bsym
->name
);
4183 if (append_insn (tmp
, TRUE
) == (int) FAIL
)
4190 For an external symbol: ldis r1, HI%<constant> */
4191 sprintf (tmp
, "ldis %s, %d", "r1", hi
);
4192 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
4195 memcpy (&fix_insts
[0], &inst
, sizeof (struct score_it
));
4198 For a local symbol: ldis r1, HI%<constant>
4199 but, if lo is outof 16 bit, make hi plus 1 */
4200 if ((lo
< -0x8000) || (lo
> 0x7fff))
4204 sprintf (tmp
, "ldis_pic %s, %d", "r1", hi
);
4205 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
4208 memcpy (&var_insts
[0], &inst
, sizeof (struct score_it
));
4209 build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
4215 For an external symbol: ori r1, LO%<constant> */
4216 sprintf (tmp
, "ori %s, %d", "r1", lo
);
4217 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
4220 memcpy (&fix_insts
[0], &inst
, sizeof (struct score_it
));
4223 For a local symbol: addi r1, <sym>+LO%<constant> (BFD_RELOC_GOT_LO16) */
4224 sprintf (tmp
, "addi_u_pic %s, %s + %d", "r1", add_symbol
->bsym
->name
, lo
);
4225 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
4228 memcpy (&var_insts
[0], &inst
, sizeof (struct score_it
));
4229 build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
4231 /* Insn 4: add rD, rD, r1 */
4232 sprintf (tmp
, "add r%d, r%d, %s", reg_rd
, reg_rd
, "r1");
4233 if (append_insn (tmp
, TRUE
) == (int) FAIL
)
4236 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4239 /* Insn 5: lw rD, [rD, 0] */
4240 sprintf (tmp
, "lw r%d, [r%d, 0]", reg_rd
, reg_rd
);
4241 if (append_insn (tmp
, TRUE
) == (int) FAIL
)
4244 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4252 do_macro_ldst_label (char *str
)
4260 char *absolute_value
;
4261 char append_str
[3][MAX_LITERAL_POOL_SIZE
];
4262 char verifystr
[MAX_LITERAL_POOL_SIZE
];
4263 struct score_it inst_backup
;
4264 struct score_it inst_expand
[3];
4265 struct score_it inst_main
;
4267 memcpy (&inst_backup
, &inst
, sizeof (struct score_it
));
4268 strcpy (verifystr
, str
);
4269 backup_str
= verifystr
;
4271 skip_whitespace (backup_str
);
4272 if ((reg_rd
= reg_required_here (&backup_str
, -1, REG_TYPE_SCORE
)) == (int) FAIL
)
4275 if (skip_past_comma (&backup_str
) == (int) FAIL
)
4278 label_str
= backup_str
;
4280 /* Ld/st rD, [rA, imm] ld/st rD, [rA]+, imm ld/st rD, [rA, imm]+. */
4281 if (*backup_str
== '[')
4287 /* Ld/st rD, imm. */
4288 absolute_value
= backup_str
;
4289 if ((my_get_expression (&inst
.reloc
.exp
, &backup_str
) == (int) FAIL
)
4290 || (validate_immediate (inst
.reloc
.exp
.X_add_number
, _VALUE
) == (int) FAIL
)
4291 || (end_of_line (backup_str
) == (int) FAIL
))
4297 if (inst
.reloc
.exp
.X_add_symbol
== 0)
4299 memcpy (&inst
, &inst_backup
, sizeof (struct score_it
));
4300 exp_macro_ldst_abs (str
);
4305 /* Ld/st rD, label. */
4306 backup_str
= absolute_value
;
4307 if ((data_op2 (&backup_str
, 1, _GP_IMM15
) == (int) FAIL
)
4308 || (end_of_line (backup_str
) == (int) FAIL
))
4314 if (inst
.reloc
.exp
.X_add_symbol
== 0)
4317 inst
.error
= BAD_ARGS
;
4322 if (score_pic
== PIC
)
4324 build_lw_pic (reg_rd
, inst
.reloc
.exp
);
4329 if ((inst
.reloc
.exp
.X_add_number
<= 0x3fff)
4330 && (inst
.reloc
.exp
.X_add_number
>= -0x4000)
4331 && (!nopic_need_relax (inst
.reloc
.exp
.X_add_symbol
, 1)))
4335 /* Assign the real opcode. */
4336 ldst_idx
= inst
.instruction
& OPC_PSEUDOLDST_MASK
;
4337 inst
.instruction
&= ~OPC_PSEUDOLDST_MASK
;
4338 inst
.instruction
|= score_ldst_insns
[ldst_idx
* 3 + 0].value
;
4339 inst
.instruction
|= reg_rd
<< 20;
4340 inst
.instruction
|= GP
<< 15;
4341 inst
.relax_inst
= 0x8000;
4342 inst
.relax_size
= 0;
4349 memcpy (&inst_main
, &inst
, sizeof (struct score_it
));
4353 /* Determine which instructions should be output. */
4354 sprintf (append_str
[0], "ld_i32hi r1, %s", label_str
);
4355 sprintf (append_str
[1], "ld_i32lo r1, %s", label_str
);
4356 sprintf (append_str
[2], "%s r%d, [r1, 0]", inst_backup
.name
, reg_rd
);
4358 /* Generate three instructions.
4360 ld/st rd, [r1, 0] */
4361 for (i
= 0; i
< 3; i
++)
4363 if (append_insn (append_str
[i
], FALSE
) == (int) FAIL
)
4366 memcpy (&inst_expand
[i
], &inst
, sizeof (struct score_it
));
4373 /* Adjust instruction opcode and to be relaxed instruction opcode. */
4374 inst_main
.instruction
= adjust_paritybit (inst_main
.instruction
, GET_INSN_CLASS (inst_main
.type
));
4375 inst_main
.relax_size
= inst_expand
[0].size
+ inst_expand
[1].size
+ inst_expand
[2].size
;
4376 inst_main
.type
= Insn_GP
;
4378 for (i
= 0; i
< 3; i
++)
4379 inst_expand
[i
].instruction
= adjust_paritybit (inst_expand
[i
].instruction
4380 , GET_INSN_CLASS (inst_expand
[i
].type
));
4382 /* Check data dependency. */
4383 handle_dependency (&inst_main
);
4385 /* Start a new frag if frag_now is not empty. */
4386 if (frag_now_fix () != 0)
4388 if (!frag_now
->tc_frag_data
.is_insn
)
4389 frag_wane (frag_now
);
4395 /* Write fr_fix part. */
4396 p
= frag_more (inst_main
.size
);
4397 md_number_to_chars (p
, inst_main
.instruction
, inst_main
.size
);
4399 if (inst_main
.reloc
.type
!= BFD_RELOC_NONE
)
4401 fix_new_score (frag_now
, p
- frag_now
->fr_literal
, inst_main
.size
,
4402 &inst_main
.reloc
.exp
, inst_main
.reloc
.pc_rel
, inst_main
.reloc
.type
);
4406 dwarf2_emit_insn (inst_main
.size
);
4409 /* GP instruction can not do optimization, only can do relax between
4410 1 instruction and 3 instructions. */
4411 p
= frag_var (rs_machine_dependent
, inst_main
.relax_size
+ RELAX_PAD_BYTE
, 0,
4412 RELAX_ENCODE (inst_main
.size
, inst_main
.relax_size
, inst_main
.type
, 0, 4, 0),
4413 inst_main
.reloc
.exp
.X_add_symbol
, 0, NULL
);
4415 /* Write fr_var part.
4416 no calling gen_insn_frag, no fixS will be generated. */
4417 md_number_to_chars (p
, inst_expand
[0].instruction
, inst_expand
[0].size
);
4418 p
+= inst_expand
[0].size
;
4419 md_number_to_chars (p
, inst_expand
[1].instruction
, inst_expand
[1].size
);
4420 p
+= inst_expand
[1].size
;
4421 md_number_to_chars (p
, inst_expand
[2].instruction
, inst_expand
[2].size
);
4425 gen_insn_frag (&inst_expand
[0], NULL
);
4426 gen_insn_frag (&inst_expand
[1], NULL
);
4427 gen_insn_frag (&inst_expand
[2], NULL
);
4431 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4436 do_lw_pic (char *str
)
4440 skip_whitespace (str
);
4441 if (((reg_rd
= reg_required_here (&str
, 20, REG_TYPE_SCORE
)) == (int) FAIL
)
4442 || (skip_past_comma (&str
) == (int) FAIL
)
4443 || (my_get_expression (&inst
.reloc
.exp
, &str
) == (int) FAIL
)
4444 || (end_of_line (str
) == (int) FAIL
))
4450 if (inst
.reloc
.exp
.X_add_symbol
== 0)
4453 inst
.error
= BAD_ARGS
;
4458 inst
.instruction
|= GP
<< 15;
4459 inst
.reloc
.type
= BFD_RELOC_SCORE_GOT15
;
4464 do_empty (char *str
)
4467 if (university_version
== 1)
4469 if (((inst
.instruction
& 0x3e0003ff) == 0x0c000004)
4470 || ((inst
.instruction
& 0x3e0003ff) == 0x0c000024)
4471 || ((inst
.instruction
& 0x3e0003ff) == 0x0c000044)
4472 || ((inst
.instruction
& 0x3e0003ff) == 0x0c000064))
4474 inst
.error
= ERR_FOR_SCORE5U_MMU
;
4478 if (end_of_line (str
) == (int) FAIL
)
4481 if (inst
.relax_inst
!= 0x8000)
4483 if (inst
.type
== NO_OPD
)
4485 inst
.relax_size
= 2;
4489 inst
.relax_size
= 4;
4500 skip_whitespace (str
);
4501 if (my_get_expression (&inst
.reloc
.exp
, &str
) == (int) FAIL
4502 || end_of_line (str
) == (int) FAIL
)
4505 if (inst
.reloc
.exp
.X_add_symbol
== 0)
4507 inst
.error
= _("lacking label ");
4511 if (((inst
.reloc
.exp
.X_add_number
& 0xff000000) != 0)
4512 && ((inst
.reloc
.exp
.X_add_number
& 0xff000000) != 0xff000000))
4514 sprintf (err_msg
, "invalid constant: 25 bit expression not in range -2^24..2^24");
4515 inst
.error
= _(err_msg
);
4519 save_in
= input_line_pointer
;
4520 input_line_pointer
= str
;
4521 inst
.reloc
.type
= BFD_RELOC_SCORE_JMP
;
4522 inst
.reloc
.pc_rel
= 1;
4523 input_line_pointer
= save_in
;
4527 do16_jump (char *str
)
4529 skip_whitespace (str
);
4530 if (my_get_expression (&inst
.reloc
.exp
, &str
) == (int) FAIL
4531 || end_of_line (str
) == (int) FAIL
)
4535 else if (inst
.reloc
.exp
.X_add_symbol
== 0)
4537 inst
.error
= _("lacking label ");
4540 else if (((inst
.reloc
.exp
.X_add_number
& 0xfffff800) != 0)
4541 && ((inst
.reloc
.exp
.X_add_number
& 0xfffff800) != 0xfffff800))
4543 inst
.error
= _("invalid constant: 12 bit expression not in range -2^11..2^11");
4547 inst
.reloc
.type
= BFD_RELOC_SCORE16_JMP
;
4548 inst
.reloc
.pc_rel
= 1;
4552 do_branch (char *str
)
4554 unsigned long abs_value
= 0;
4556 if (my_get_expression (&inst
.reloc
.exp
, &str
) == (int) FAIL
4557 || end_of_line (str
) == (int) FAIL
)
4561 else if (inst
.reloc
.exp
.X_add_symbol
== 0)
4563 inst
.error
= _("lacking label ");
4566 else if (((inst
.reloc
.exp
.X_add_number
& 0xff000000) != 0)
4567 && ((inst
.reloc
.exp
.X_add_number
& 0xff000000) != 0xff000000))
4569 inst
.error
= "invalid constant: 20 bit expression not in range -2^19..2^19";
4573 inst
.reloc
.type
= BFD_RELOC_SCORE_BRANCH
;
4574 inst
.reloc
.pc_rel
= 1;
4576 /* Branch 32 offset field : 20 bit, 16 bit branch offset field : 8 bit. */
4577 inst
.instruction
|= (inst
.reloc
.exp
.X_add_number
& 0x3fe) | ((inst
.reloc
.exp
.X_add_number
& 0xffc00) << 5);
4579 /* Take the branch condition code. */
4580 inst
.relax_inst
= 0x4000 | (((inst
.instruction
>> 10) & 0xf) << 8);
4582 if ((abs_value
& 0xfffffe00) == 0)
4584 inst
.relax_inst
|= ((inst
.reloc
.exp
.X_add_number
>> 1) & 0xff);
4585 inst
.relax_size
= 2;
4589 inst
.relax_inst
= 0x8000;
4592 if (inst
.instruction
& 1)
4593 inst
.relax_inst
= 0x8000;
4597 do16_branch (char *str
)
4599 if ((my_get_expression (&inst
.reloc
.exp
, &str
) == (int) FAIL
4600 || end_of_line (str
) == (int) FAIL
))
4604 else if (inst
.reloc
.exp
.X_add_symbol
== 0)
4606 inst
.error
= _("lacking label");
4608 else if (((inst
.reloc
.exp
.X_add_number
& 0xffffff00) != 0)
4609 && ((inst
.reloc
.exp
.X_add_number
& 0xffffff00) != 0xffffff00))
4611 inst
.error
= _("invalid constant: 9 bit expression not in range -2^8..2^8");
4615 inst
.reloc
.type
= BFD_RELOC_SCORE16_BRANCH
;
4616 inst
.reloc
.pc_rel
= 1;
4617 inst
.instruction
|= ((inst
.reloc
.exp
.X_add_number
>> 1) & 0xff);
4621 /* Iterate over the base tables to create the instruction patterns. */
4623 build_score_ops_hsh (void)
4626 static struct obstack insn_obstack
;
4628 obstack_begin (&insn_obstack
, 4000);
4629 for (i
= 0; i
< sizeof (score_insns
) / sizeof (struct asm_opcode
); i
++)
4631 const struct asm_opcode
*insn
= score_insns
+ i
;
4632 unsigned len
= strlen (insn
->template);
4633 struct asm_opcode
*new;
4635 new = obstack_alloc (&insn_obstack
, sizeof (struct asm_opcode
));
4636 template = obstack_alloc (&insn_obstack
, len
+ 1);
4638 strcpy (template, insn
->template);
4639 new->template = template;
4640 new->parms
= insn
->parms
;
4641 new->value
= insn
->value
;
4642 new->relax_value
= insn
->relax_value
;
4643 new->type
= insn
->type
;
4644 new->bitmask
= insn
->bitmask
;
4645 hash_insert (score_ops_hsh
, new->template, (void *) new);
4650 build_dependency_insn_hsh (void)
4653 static struct obstack dependency_obstack
;
4655 obstack_begin (&dependency_obstack
, 4000);
4656 for (i
= 0; i
< sizeof (insn_to_dependency_table
) / sizeof (insn_to_dependency_table
[0]); i
++)
4658 const struct insn_to_dependency
*tmp
= insn_to_dependency_table
+ i
;
4659 unsigned len
= strlen (tmp
->insn_name
);
4660 struct insn_to_dependency
*new;
4662 new = obstack_alloc (&dependency_obstack
, sizeof (struct insn_to_dependency
));
4663 new->insn_name
= obstack_alloc (&dependency_obstack
, len
+ 1);
4665 strcpy (new->insn_name
, tmp
->insn_name
);
4666 new->type
= tmp
->type
;
4667 hash_insert (dependency_insn_hsh
, new->insn_name
, (void *) new);
4671 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
4672 for use in the a.out file, and stores them in the array pointed to by buf.
4673 This knows about the endian-ness of the target machine and does
4674 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
4675 2 (short) and 4 (long) Floating numbers are put out as a series of
4676 LITTLENUMS (shorts, here at least). */
4679 md_number_to_chars (char *buf
, valueT val
, int n
)
4681 if (target_big_endian
)
4682 number_to_chars_bigendian (buf
, val
, n
);
4684 number_to_chars_littleendian (buf
, val
, n
);
4688 md_chars_to_number (char *buf
, int n
)
4691 unsigned char *where
= (unsigned char *)buf
;
4693 if (target_big_endian
)
4698 result
|= (*where
++ & 255);
4706 result
|= (where
[n
] & 255);
4713 /* Turn a string in input_line_pointer into a floating point constant
4714 of type TYPE, and store the appropriate bytes in *LITP. The number
4715 of LITTLENUMS emitted is stored in *SIZEP. An error message is
4716 returned, or NULL on OK.
4718 Note that fp constants aren't represent in the normal way on the ARM.
4719 In big endian mode, things are as expected. However, in little endian
4720 mode fp constants are big-endian word-wise, and little-endian byte-wise
4721 within the words. For example, (double) 1.1 in big endian mode is
4722 the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
4723 the byte sequence 99 99 f1 3f 9a 99 99 99. */
4726 md_atof (int type
, char *litP
, int *sizeP
)
4729 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
4755 return _("bad call to MD_ATOF()");
4758 t
= atof_ieee (input_line_pointer
, type
, words
);
4760 input_line_pointer
= t
;
4763 if (target_big_endian
)
4765 for (i
= 0; i
< prec
; i
++)
4767 md_number_to_chars (litP
, (valueT
) words
[i
], 2);
4773 for (i
= 0; i
< prec
; i
+= 2)
4775 md_number_to_chars (litP
, (valueT
) words
[i
+ 1], 2);
4776 md_number_to_chars (litP
+ 2, (valueT
) words
[i
], 2);
4784 /* Return true if the given symbol should be considered local for PIC. */
4787 pic_need_relax (symbolS
*sym
, asection
*segtype
)
4790 bfd_boolean linkonce
;
4792 /* Handle the case of a symbol equated to another symbol. */
4793 while (symbol_equated_reloc_p (sym
))
4797 /* It's possible to get a loop here in a badly written
4799 n
= symbol_get_value_expression (sym
)->X_add_symbol
;
4805 symsec
= S_GET_SEGMENT (sym
);
4807 /* duplicate the test for LINK_ONCE sections as in adjust_reloc_syms */
4809 if (symsec
!= segtype
&& ! S_IS_LOCAL (sym
))
4811 if ((bfd_get_section_flags (stdoutput
, symsec
) & SEC_LINK_ONCE
) != 0)
4814 /* The GNU toolchain uses an extension for ELF: a section
4815 beginning with the magic string .gnu.linkonce is a linkonce
4817 if (strncmp (segment_name (symsec
), ".gnu.linkonce",
4818 sizeof ".gnu.linkonce" - 1) == 0)
4822 /* This must duplicate the test in adjust_reloc_syms. */
4823 return (symsec
!= &bfd_und_section
4824 && symsec
!= &bfd_abs_section
4825 && ! bfd_is_com_section (symsec
)
4828 /* A global or weak symbol is treated as external. */
4829 && (OUTPUT_FLAVOR
!= bfd_target_elf_flavour
4830 || (! S_IS_WEAK (sym
) && ! S_IS_EXTERNAL (sym
)))
4836 judge_size_before_relax (fragS
* fragp
, asection
*sec
)
4840 if (score_pic
== NO_PIC
)
4841 change
= nopic_need_relax (fragp
->fr_symbol
, 0);
4843 change
= pic_need_relax (fragp
->fr_symbol
, sec
);
4847 /* Only at the first time determining whether GP instruction relax should be done,
4848 return the difference between insntruction size and instruction relax size. */
4849 if (fragp
->fr_opcode
== NULL
)
4851 fragp
->fr_fix
= RELAX_NEW (fragp
->fr_subtype
);
4852 fragp
->fr_opcode
= fragp
->fr_literal
+ RELAX_RELOC1 (fragp
->fr_subtype
);
4853 return RELAX_NEW (fragp
->fr_subtype
) - RELAX_OLD (fragp
->fr_subtype
);
4860 /* In this function, we determine whether GP instruction should do relaxation,
4861 for the label being against was known now.
4862 Doing this here but not in md_relax_frag() can induce iteration times
4863 in stage of doing relax. */
4865 md_estimate_size_before_relax (fragS
* fragp
, asection
* sec ATTRIBUTE_UNUSED
)
4867 if ((RELAX_TYPE (fragp
->fr_subtype
) == Insn_GP
)
4868 || (RELAX_TYPE (fragp
->fr_subtype
) == Insn_PIC
))
4869 return judge_size_before_relax (fragp
, sec
);
4875 b32_relax_to_b16 (fragS
* fragp
)
4878 int relaxable_p
= 0;
4881 int frag_addr
= fragp
->fr_address
+ fragp
->insn_addr
;
4883 addressT symbol_address
= 0;
4886 unsigned long value
;
4887 unsigned long abs_value
;
4889 /* FIXME : here may be able to modify better .
4890 I don't know how to get the fragp's section ,
4891 so in relax stage , it may be wrong to calculate the symbol's offset when the frag's section
4892 is different from the symbol's. */
4894 old
= RELAX_OLD (fragp
->fr_subtype
);
4895 new = RELAX_NEW (fragp
->fr_subtype
);
4896 relaxable_p
= RELAX_OPT (fragp
->fr_subtype
);
4898 s
= fragp
->fr_symbol
;
4899 /* b/bl immediate */
4905 symbol_address
= (addressT
) s
->sy_frag
->fr_address
;
4908 value
= md_chars_to_number (fragp
->fr_literal
, INSN_SIZE
);
4910 /* b 32's offset : 20 bit, b 16's tolerate field : 0xff. */
4911 offset
= ((value
& 0x3ff0000) >> 6) | (value
& 0x3fe);
4912 if ((offset
& 0x80000) == 0x80000)
4913 offset
|= 0xfff00000;
4915 abs_value
= offset
+ symbol_address
- frag_addr
;
4916 if ((abs_value
& 0x80000000) == 0x80000000)
4917 abs_value
= 0xffffffff - abs_value
+ 1;
4919 /* Relax branch 32 to branch 16. */
4920 if (relaxable_p
&& (s
->bsym
!= NULL
) && ((abs_value
& 0xffffff00) == 0)
4921 && (S_IS_DEFINED (s
) && !S_IS_COMMON (s
) && !S_IS_EXTERNAL (s
)))
4927 /* Branch 32 can not be relaxed to b 16, so clear OPT bit. */
4928 fragp
->fr_opcode
= NULL
;
4929 fragp
->fr_subtype
= RELAX_OPT_CLEAR (fragp
->fr_subtype
);
4935 /* Main purpose is to determine whether one frag should do relax.
4936 frag->fr_opcode indicates this point. */
4939 score_relax_frag (asection
* sec ATTRIBUTE_UNUSED
, fragS
* fragp
, long stretch ATTRIBUTE_UNUSED
)
4943 int insn_relax_size
;
4944 int do_relax_p
= 0; /* Indicate doing relaxation for this frag. */
4945 int relaxable_p
= 0;
4946 bfd_boolean word_align_p
= FALSE
;
4949 /* If the instruction address is odd, make it half word align first. */
4950 if ((fragp
->fr_address
) % 2 != 0)
4952 if ((fragp
->fr_address
+ fragp
->insn_addr
) % 2 != 0)
4954 fragp
->insn_addr
= 1;
4959 word_align_p
= ((fragp
->fr_address
+ fragp
->insn_addr
) % 4 == 0) ? TRUE
: FALSE
;
4961 /* Get instruction size and relax size after the last relaxation. */
4962 if (fragp
->fr_opcode
)
4964 insn_size
= RELAX_NEW (fragp
->fr_subtype
);
4965 insn_relax_size
= RELAX_OLD (fragp
->fr_subtype
);
4969 insn_size
= RELAX_OLD (fragp
->fr_subtype
);
4970 insn_relax_size
= RELAX_NEW (fragp
->fr_subtype
);
4973 /* Handle specially for GP instruction. for, judge_size_before_relax() has already determine
4974 whether the GP instruction should do relax. */
4975 if ((RELAX_TYPE (fragp
->fr_subtype
) == Insn_GP
)
4976 || (RELAX_TYPE (fragp
->fr_subtype
) == Insn_PIC
))
4980 fragp
->insn_addr
+= 2;
4984 if (fragp
->fr_opcode
)
4985 fragp
->fr_fix
= RELAX_NEW (fragp
->fr_subtype
) + fragp
->insn_addr
;
4987 fragp
->fr_fix
= RELAX_OLD (fragp
->fr_subtype
) + fragp
->insn_addr
;
4991 if (RELAX_TYPE (fragp
->fr_subtype
) == PC_DISP19div2
)
4992 b32_relax_to_b16 (fragp
);
4994 relaxable_p
= RELAX_OPT (fragp
->fr_subtype
);
4995 next_fragp
= fragp
->fr_next
;
4996 while ((next_fragp
) && (next_fragp
->fr_type
!= rs_machine_dependent
))
4998 next_fragp
= next_fragp
->fr_next
;
5004 int n_relaxable_p
= 0;
5006 if (next_fragp
->fr_opcode
)
5008 n_insn_size
= RELAX_NEW (next_fragp
->fr_subtype
);
5012 n_insn_size
= RELAX_OLD (next_fragp
->fr_subtype
);
5015 n_relaxable_p
= RELAX_OPT (next_fragp
->fr_subtype
);
5022 if (relaxable_p
&& ((n_insn_size
== 2) || n_relaxable_p
))
5028 else if (insn_size
== 2)
5031 if (relaxable_p
&& ((n_insn_size
== 4) && !n_relaxable_p
))
5052 /* Make the 32 bit insturction word align. */
5055 fragp
->insn_addr
+= 2;
5059 else if (insn_size
== 2)
5071 /* Here, try best to do relax regardless fragp->fr_next->fr_type. */
5072 if (word_align_p
== FALSE
)
5074 if (insn_size
% 4 == 0)
5084 fragp
->insn_addr
+= 2;
5095 /* fragp->fr_opcode indicates whether this frag should be relaxed. */
5098 if (fragp
->fr_opcode
)
5100 fragp
->fr_opcode
= NULL
;
5101 /* Guarantee estimate stage is correct. */
5102 fragp
->fr_fix
= RELAX_OLD (fragp
->fr_subtype
);
5103 fragp
->fr_fix
+= fragp
->insn_addr
;
5107 fragp
->fr_opcode
= fragp
->fr_literal
+ RELAX_RELOC1 (fragp
->fr_subtype
);
5108 /* Guarantee estimate stage is correct. */
5109 fragp
->fr_fix
= RELAX_NEW (fragp
->fr_subtype
);
5110 fragp
->fr_fix
+= fragp
->insn_addr
;
5115 if (fragp
->fr_opcode
)
5117 /* Guarantee estimate stage is correct. */
5118 fragp
->fr_fix
= RELAX_NEW (fragp
->fr_subtype
);
5119 fragp
->fr_fix
+= fragp
->insn_addr
;
5123 /* Guarantee estimate stage is correct. */
5124 fragp
->fr_fix
= RELAX_OLD (fragp
->fr_subtype
);
5125 fragp
->fr_fix
+= fragp
->insn_addr
;
5134 md_convert_frag (bfd
* abfd ATTRIBUTE_UNUSED
, segT sec ATTRIBUTE_UNUSED
, fragS
* fragp
)
5141 old
= RELAX_OLD (fragp
->fr_subtype
);
5142 new = RELAX_NEW (fragp
->fr_subtype
);
5144 /* fragp->fr_opcode indicates whether this frag should be relaxed. */
5145 if (fragp
->fr_opcode
== NULL
)
5147 memcpy (backup
, fragp
->fr_literal
, old
);
5148 fragp
->fr_fix
= old
;
5152 memcpy (backup
, fragp
->fr_literal
+ old
, new);
5153 fragp
->fr_fix
= new;
5156 fixp
= fragp
->tc_frag_data
.fixp
;
5157 while (fixp
&& fixp
->fx_frag
== fragp
&& fixp
->fx_where
< old
)
5159 if (fragp
->fr_opcode
)
5161 fixp
= fixp
->fx_next
;
5163 while (fixp
&& fixp
->fx_frag
== fragp
)
5165 if (fragp
->fr_opcode
)
5166 fixp
->fx_where
-= old
+ fragp
->insn_addr
;
5169 fixp
= fixp
->fx_next
;
5172 if (fragp
->insn_addr
)
5174 md_number_to_chars (fragp
->fr_literal
, 0x0, fragp
->insn_addr
);
5176 memcpy (fragp
->fr_literal
+ fragp
->insn_addr
, backup
, fragp
->fr_fix
);
5177 fragp
->fr_fix
+= fragp
->insn_addr
;
5180 /* Implementation of md_frag_check.
5181 Called after md_convert_frag(). */
5184 score_frag_check (fragS
* fragp ATTRIBUTE_UNUSED
)
5186 know (fragp
->insn_addr
<= RELAX_PAD_BYTE
);
5190 score_fix_adjustable (fixS
* fixP
)
5192 if (fixP
->fx_addsy
== NULL
)
5196 else if (OUTPUT_FLAVOR
== bfd_target_elf_flavour
5197 && (S_IS_EXTERNAL (fixP
->fx_addsy
) || S_IS_WEAK (fixP
->fx_addsy
)))
5201 else if (fixP
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
5202 || fixP
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
5210 /* Implementation of TC_VALIDATE_FIX.
5211 Called before md_apply_fix() and after md_convert_frag(). */
5213 score_validate_fix (fixS
*fixP
)
5215 fixP
->fx_where
+= fixP
->fx_frag
->insn_addr
;
5219 md_pcrel_from (fixS
* fixP
)
5224 && (S_GET_SEGMENT (fixP
->fx_addsy
) == undefined_section
)
5225 && (fixP
->fx_subsy
== NULL
))
5231 retval
= fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
5238 score_force_relocation (struct fix
*fixp
)
5242 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
5243 || fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
5244 || fixp
->fx_r_type
== BFD_RELOC_SCORE_JMP
5245 || fixp
->fx_r_type
== BFD_RELOC_SCORE_BRANCH
5246 || fixp
->fx_r_type
== BFD_RELOC_SCORE16_JMP
5247 || fixp
->fx_r_type
== BFD_RELOC_SCORE16_BRANCH
)
5255 /* Round up a section size to the appropriate boundary. */
5257 md_section_align (segT segment ATTRIBUTE_UNUSED
, valueT size
)
5259 int align
= bfd_get_section_alignment (stdoutput
, segment
);
5262 /* We don't need to align ELF sections to the full alignment.
5263 However, Irix 5 may prefer that we align them at least to a 16
5264 byte boundary. We don't bother to align the sections if we are
5265 targeted for an embedded system. */
5266 if (strcmp (TARGET_OS
, "elf") == 0)
5272 return ((size
+ (1 << align
) - 1) & (-1 << align
));
5276 md_apply_fix (fixS
*fixP
, valueT
*valP
, segT seg
)
5278 offsetT value
= *valP
;
5279 offsetT abs_value
= 0;
5282 unsigned short HI
, LO
;
5284 char *buf
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
5286 assert (fixP
->fx_r_type
< BFD_RELOC_UNUSED
);
5287 if (fixP
->fx_addsy
== 0 && !fixP
->fx_pcrel
)
5289 if (fixP
->fx_r_type
!= BFD_RELOC_SCORE_DUMMY_HI16
)
5293 /* If this symbol is in a different section then we need to leave it for
5294 the linker to deal with. Unfortunately, md_pcrel_from can't tell,
5295 so we have to undo it's effects here. */
5298 if (fixP
->fx_addsy
!= NULL
5299 && S_IS_DEFINED (fixP
->fx_addsy
)
5300 && S_GET_SEGMENT (fixP
->fx_addsy
) != seg
)
5301 value
+= md_pcrel_from (fixP
);
5304 /* Remember value for emit_reloc. */
5305 fixP
->fx_addnumber
= value
;
5307 switch (fixP
->fx_r_type
)
5309 case BFD_RELOC_HI16_S
:
5311 { /* For la rd, imm32. */
5312 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5313 HI
= (value
) >> 16; /* mul to 2, then take the hi 16 bit. */
5314 newval
|= (HI
& 0x3fff) << 1;
5315 newval
|= ((HI
>> 14) & 0x3) << 16;
5316 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5319 case BFD_RELOC_LO16
:
5320 if (fixP
->fx_done
) /* For la rd, imm32. */
5322 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5323 LO
= (value
) & 0xffff;
5324 newval
|= (LO
& 0x3fff) << 1; /* 16 bit: imm -> 14 bit in lo, 2 bit in hi. */
5325 newval
|= ((LO
>> 14) & 0x3) << 16;
5326 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5329 case BFD_RELOC_SCORE_JMP
:
5331 content
= md_chars_to_number (buf
, INSN_SIZE
);
5332 value
= fixP
->fx_offset
;
5333 content
= (content
& ~0x3ff7ffe) | ((value
<< 1) & 0x3ff0000) | (value
& 0x7fff);
5334 md_number_to_chars (buf
, content
, INSN_SIZE
);
5337 case BFD_RELOC_SCORE_BRANCH
:
5338 if ((S_GET_SEGMENT (fixP
->fx_addsy
) != seg
) || (fixP
->fx_addsy
!= NULL
&& S_IS_EXTERNAL (fixP
->fx_addsy
)))
5339 value
= fixP
->fx_offset
;
5343 content
= md_chars_to_number (buf
, INSN_SIZE
);
5344 if ((fixP
->fx_frag
->fr_opcode
!= 0) && ((content
& 0x80008000) != 0x80008000))
5346 if ((value
& 0x80000000) == 0x80000000)
5347 abs_value
= 0xffffffff - value
+ 1;
5348 if ((abs_value
& 0xffffff00) != 0)
5350 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5351 _(" branch relocation truncate (0x%x) [-2^8 ~ 2^8]"), (unsigned int)value
);
5354 content
= md_chars_to_number (buf
, INSN16_SIZE
);
5356 content
= (content
& 0xff00) | ((value
>> 1) & 0xff);
5357 md_number_to_chars (buf
, content
, INSN16_SIZE
);
5358 fixP
->fx_r_type
= BFD_RELOC_SCORE16_BRANCH
;
5363 if ((value
& 0x80000000) == 0x80000000)
5364 abs_value
= 0xffffffff - value
+ 1;
5365 if ((abs_value
& 0xfff80000) != 0)
5367 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5368 _(" branch relocation truncate (0x%x) [-2^19 ~ 2^19]"), (unsigned int)value
);
5371 content
= md_chars_to_number (buf
, INSN_SIZE
);
5372 content
&= 0xfc00fc01;
5373 content
= (content
& 0xfc00fc01) | (value
& 0x3fe) | ((value
<< 6) & 0x3ff0000);
5374 md_number_to_chars (buf
, content
, INSN_SIZE
);
5377 case BFD_RELOC_SCORE16_JMP
:
5378 content
= md_chars_to_number (buf
, INSN16_SIZE
);
5380 value
= fixP
->fx_offset
& 0xfff;
5381 content
= (content
& 0xfc01) | (value
& 0xffe);
5382 md_number_to_chars (buf
, content
, INSN16_SIZE
);
5384 case BFD_RELOC_SCORE16_BRANCH
:
5385 content
= md_chars_to_number (buf
, INSN_SIZE
);
5386 if ((fixP
->fx_frag
->fr_opcode
!= 0) && ((content
& 0x80008000) == 0x80008000))
5388 if ((S_GET_SEGMENT (fixP
->fx_addsy
) != seg
) ||
5389 (fixP
->fx_addsy
!= NULL
&& S_IS_EXTERNAL (fixP
->fx_addsy
)))
5390 value
= fixP
->fx_offset
;
5393 if ((value
& 0x80000000) == 0x80000000)
5394 abs_value
= 0xffffffff - value
+ 1;
5395 if ((abs_value
& 0xfff80000) != 0)
5397 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5398 _(" branch relocation truncate (0x%x) [-2^19 ~ 2^19]"), (unsigned int)value
);
5401 content
= md_chars_to_number (buf
, INSN_SIZE
);
5402 content
= (content
& 0xfc00fc01) | (value
& 0x3fe) | ((value
<< 6) & 0x3ff0000);
5403 md_number_to_chars (buf
, content
, INSN_SIZE
);
5404 fixP
->fx_r_type
= BFD_RELOC_SCORE_BRANCH
;
5410 /* In differnt section. */
5411 if ((S_GET_SEGMENT (fixP
->fx_addsy
) != seg
) ||
5412 (fixP
->fx_addsy
!= NULL
&& S_IS_EXTERNAL (fixP
->fx_addsy
)))
5413 value
= fixP
->fx_offset
;
5417 if ((value
& 0x80000000) == 0x80000000)
5418 abs_value
= 0xffffffff - value
+ 1;
5419 if ((abs_value
& 0xffffff00) != 0)
5421 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5422 _(" branch relocation truncate (0x%x) [-2^8 ~ 2^8]"), (unsigned int)value
);
5425 content
= md_chars_to_number (buf
, INSN16_SIZE
);
5426 content
= (content
& 0xff00) | ((value
>> 1) & 0xff);
5427 md_number_to_chars (buf
, content
, INSN16_SIZE
);
5431 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5432 md_number_to_chars (buf
, value
, 1);
5436 value
= fixP
->fx_offset
;
5437 md_number_to_chars (buf
, value
, 1);
5443 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5444 md_number_to_chars (buf
, value
, 2);
5448 value
= fixP
->fx_offset
;
5449 md_number_to_chars (buf
, value
, 2);
5455 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5456 md_number_to_chars (buf
, value
, 4);
5460 value
= fixP
->fx_offset
;
5461 md_number_to_chars (buf
, value
, 4);
5465 case BFD_RELOC_VTABLE_INHERIT
:
5467 if (fixP
->fx_addsy
&& !S_IS_DEFINED (fixP
->fx_addsy
) && !S_IS_WEAK (fixP
->fx_addsy
))
5468 S_SET_WEAK (fixP
->fx_addsy
);
5470 case BFD_RELOC_VTABLE_ENTRY
:
5473 case BFD_RELOC_SCORE_GPREL15
:
5474 content
= md_chars_to_number (buf
, INSN_SIZE
);
5475 if ((fixP
->fx_frag
->fr_opcode
!= 0) && ((content
& 0xfc1c8000) != 0x94188000))
5476 fixP
->fx_r_type
= BFD_RELOC_NONE
;
5479 case BFD_RELOC_SCORE_GOT15
:
5480 case BFD_RELOC_SCORE_DUMMY_HI16
:
5481 case BFD_RELOC_SCORE_GOT_LO16
:
5482 case BFD_RELOC_SCORE_CALL15
:
5483 case BFD_RELOC_GPREL32
:
5485 case BFD_RELOC_NONE
:
5487 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("bad relocation fixup type (%d)"), fixP
->fx_r_type
);
5491 /* Translate internal representation of relocation info to BFD target format. */
5493 tc_gen_reloc (asection
* section ATTRIBUTE_UNUSED
, fixS
* fixp
)
5495 static arelent
*retval
[MAX_RELOC_EXPANSION
+ 1]; /* MAX_RELOC_EXPANSION equals 2. */
5497 bfd_reloc_code_real_type code
;
5503 reloc
= retval
[0] = xmalloc (sizeof (arelent
));
5506 reloc
->sym_ptr_ptr
= xmalloc (sizeof (asymbol
*));
5507 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
5508 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
5509 reloc
->addend
= fixp
->fx_offset
;
5511 /* If this is a variant frag, we may need to adjust the existing
5512 reloc and generate a new one. */
5513 if (fixp
->fx_frag
->fr_opcode
!= NULL
&& (fixp
->fx_r_type
== BFD_RELOC_SCORE_GPREL15
))
5515 /* Update instruction imm bit. */
5520 buf
= fixp
->fx_frag
->fr_literal
+ fixp
->fx_frag
->insn_addr
;
5521 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5522 off
= fixp
->fx_offset
>> 16;
5523 newval
|= (off
& 0x3fff) << 1;
5524 newval
|= ((off
>> 14) & 0x3) << 16;
5525 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5528 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5529 off
= fixp
->fx_offset
& 0xffff;
5530 newval
|= ((off
& 0x3fff) << 1);
5531 newval
|= (((off
>> 14) & 0x3) << 16);
5532 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5534 retval
[1] = xmalloc (sizeof (arelent
));
5536 retval
[1]->sym_ptr_ptr
= xmalloc (sizeof (asymbol
*));
5537 *retval
[1]->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
5538 retval
[1]->address
= (reloc
->address
+ RELAX_RELOC2 (fixp
->fx_frag
->fr_subtype
));
5544 retval
[1]->addend
= 0;
5545 retval
[1]->howto
= bfd_reloc_type_lookup (stdoutput
, BFD_RELOC_LO16
);
5546 assert (retval
[1]->howto
!= NULL
);
5548 fixp
->fx_r_type
= BFD_RELOC_HI16_S
;
5551 code
= fixp
->fx_r_type
;
5552 switch (fixp
->fx_r_type
)
5557 code
= BFD_RELOC_32_PCREL
;
5560 case BFD_RELOC_HI16_S
:
5561 case BFD_RELOC_LO16
:
5562 case BFD_RELOC_SCORE_JMP
:
5563 case BFD_RELOC_SCORE_BRANCH
:
5564 case BFD_RELOC_SCORE16_JMP
:
5565 case BFD_RELOC_SCORE16_BRANCH
:
5566 case BFD_RELOC_VTABLE_ENTRY
:
5567 case BFD_RELOC_VTABLE_INHERIT
:
5568 case BFD_RELOC_SCORE_GPREL15
:
5569 case BFD_RELOC_SCORE_GOT15
:
5570 case BFD_RELOC_SCORE_DUMMY_HI16
:
5571 case BFD_RELOC_SCORE_GOT_LO16
:
5572 case BFD_RELOC_SCORE_CALL15
:
5573 case BFD_RELOC_GPREL32
:
5574 case BFD_RELOC_NONE
:
5575 code
= fixp
->fx_r_type
;
5578 type
= _("<unknown>");
5579 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5580 _("cannot represent %s relocation in this object file format"), type
);
5584 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
5585 if (reloc
->howto
== NULL
)
5587 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5588 _("cannot represent %s relocation in this object file format1"),
5589 bfd_get_reloc_code_name (code
));
5592 /* HACK: Since arm ELF uses Rel instead of Rela, encode the
5593 vtable entry to be used in the relocation's section offset. */
5594 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
5595 reloc
->address
= fixp
->fx_offset
;
5601 score_elf_final_processing (void)
5603 if (fix_data_dependency
== 1)
5605 elf_elfheader (stdoutput
)->e_flags
|= EF_SCORE_FIXDEP
;
5607 if (score_pic
== PIC
)
5609 elf_elfheader (stdoutput
)->e_flags
|= EF_SCORE_PIC
;
5614 parse_pce_inst (char *insnstr
)
5618 char first
[MAX_LITERAL_POOL_SIZE
];
5619 char second
[MAX_LITERAL_POOL_SIZE
];
5620 struct score_it pec_part_1
;
5622 /* Get first part string of PCE. */
5623 p
= strstr (insnstr
, "||");
5626 sprintf (first
, "%s", insnstr
);
5628 /* Get second part string of PCE. */
5631 sprintf (second
, "%s", p
);
5633 parse_16_32_inst (first
, FALSE
);
5637 memcpy (&pec_part_1
, &inst
, sizeof (inst
));
5639 parse_16_32_inst (second
, FALSE
);
5643 if ( ((pec_part_1
.size
== INSN_SIZE
) && (inst
.size
== INSN_SIZE
))
5644 || ((pec_part_1
.size
== INSN_SIZE
) && (inst
.size
== INSN16_SIZE
))
5645 || ((pec_part_1
.size
== INSN16_SIZE
) && (inst
.size
== INSN_SIZE
)))
5647 inst
.error
= _("pce instruction error (16 bit || 16 bit)'");
5648 sprintf (inst
.str
, "%s", insnstr
);
5653 gen_insn_frag (&pec_part_1
, &inst
);
5657 md_assemble (char *str
)
5660 know (strlen (str
) < MAX_LITERAL_POOL_SIZE
);
5662 memset (&inst
, '\0', sizeof (inst
));
5663 if (INSN_IS_PCE_P (str
))
5664 parse_pce_inst (str
);
5666 parse_16_32_inst (str
, TRUE
);
5669 as_bad ("%s -- `%s'", inst
.error
, inst
.str
);
5672 /* We handle all bad expressions here, so that we can report the faulty
5673 instruction in the error message. */
5675 md_operand (expressionS
* expr
)
5677 if (in_my_get_expression
)
5679 expr
->X_op
= O_illegal
;
5680 if (inst
.error
== NULL
)
5682 inst
.error
= _("bad expression");
5687 const char *md_shortopts
= "nO::g::G:";
5689 #ifdef SCORE_BI_ENDIAN
5690 #define OPTION_EB (OPTION_MD_BASE + 0)
5691 #define OPTION_EL (OPTION_MD_BASE + 1)
5693 #if TARGET_BYTES_BIG_ENDIAN
5694 #define OPTION_EB (OPTION_MD_BASE + 0)
5696 #define OPTION_EL (OPTION_MD_BASE + 1)
5699 #define OPTION_FIXDD (OPTION_MD_BASE + 2)
5700 #define OPTION_NWARN (OPTION_MD_BASE + 3)
5701 #define OPTION_SCORE5 (OPTION_MD_BASE + 4)
5702 #define OPTION_SCORE5U (OPTION_MD_BASE + 5)
5703 #define OPTION_SCORE7 (OPTION_MD_BASE + 6)
5704 #define OPTION_R1 (OPTION_MD_BASE + 7)
5705 #define OPTION_O0 (OPTION_MD_BASE + 8)
5706 #define OPTION_SCORE_VERSION (OPTION_MD_BASE + 9)
5707 #define OPTION_PIC (OPTION_MD_BASE + 10)
5709 struct option md_longopts
[] =
5712 {"EB" , no_argument
, NULL
, OPTION_EB
},
5715 {"EL" , no_argument
, NULL
, OPTION_EL
},
5717 {"FIXDD" , no_argument
, NULL
, OPTION_FIXDD
},
5718 {"NWARN" , no_argument
, NULL
, OPTION_NWARN
},
5719 {"SCORE5" , no_argument
, NULL
, OPTION_SCORE5
},
5720 {"SCORE5U", no_argument
, NULL
, OPTION_SCORE5U
},
5721 {"SCORE7" , no_argument
, NULL
, OPTION_SCORE7
},
5722 {"USE_R1" , no_argument
, NULL
, OPTION_R1
},
5723 {"O0" , no_argument
, NULL
, OPTION_O0
},
5724 {"V" , no_argument
, NULL
, OPTION_SCORE_VERSION
},
5725 {"KPIC" , no_argument
, NULL
, OPTION_PIC
},
5726 {NULL
, no_argument
, NULL
, 0}
5729 size_t md_longopts_size
= sizeof (md_longopts
);
5732 md_parse_option (int c
, char *arg
)
5738 target_big_endian
= 1;
5743 target_big_endian
= 0;
5747 fix_data_dependency
= 1;
5750 warn_fix_data_dependency
= 0;
5754 university_version
= 0;
5755 vector_size
= SCORE5_PIPELINE
;
5757 case OPTION_SCORE5U
:
5759 university_version
= 1;
5760 vector_size
= SCORE5_PIPELINE
;
5764 university_version
= 0;
5765 vector_size
= SCORE7_PIPELINE
;
5771 g_switch_value
= atoi (arg
);
5776 case OPTION_SCORE_VERSION
:
5777 printf (_("Sunplus-v2-0-0-20060510\n"));
5781 g_switch_value
= 0; /* Must set -G num as 0 to generate PIC code. */
5784 /* as_bad (_("unrecognized option `-%c%s'"), c, arg ? arg : ""); */
5791 md_show_usage (FILE * fp
)
5793 fprintf (fp
, _(" Score-specific assembler options:\n"));
5796 -EB\t\tassemble code for a big-endian cpu\n"));
5801 -EL\t\tassemble code for a little-endian cpu\n"));
5805 -FIXDD\t\tassemble code for fix data dependency\n"));
5807 -NWARN\t\tassemble code for no warning message for fix data dependency\n"));
5809 -SCORE5\t\tassemble code for target is SCORE5\n"));
5811 -SCORE5U\tassemble code for target is SCORE5U\n"));
5813 -SCORE7\t\tassemble code for target is SCORE7, this is default setting\n"));
5815 -USE_R1\t\tassemble code for no warning message when using temp register r1\n"));
5817 -KPIC\t\tassemble code for PIC\n"));
5819 -O0\t\tassembler will not perform any optimizations\n"));
5821 -G gpnum\tassemble code for setting gpsize and default is 8 byte\n"));
5823 -V \t\tSunplus release version \n"));
5827 /* Pesudo handling functions. */
5829 /* If we change section we must dump the literal pool first. */
5831 s_score_bss (int ignore ATTRIBUTE_UNUSED
)
5833 subseg_set (bss_section
, (subsegT
) get_absolute_expression ());
5834 demand_empty_rest_of_line ();
5838 s_score_text (int ignore
)
5840 obj_elf_text (ignore
);
5841 record_alignment (now_seg
, 2);
5845 score_s_section (int ignore
)
5847 obj_elf_section (ignore
);
5848 if ((bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
) != 0)
5849 record_alignment (now_seg
, 2);
5854 s_change_sec (int sec
)
5859 /* The ELF backend needs to know that we are changing sections, so
5860 that .previous works correctly. We could do something like check
5861 for an obj_section_change_hook macro, but that might be confusing
5862 as it would not be appropriate to use it in the section changing
5863 functions in read.c, since obj-elf.c intercepts those. FIXME:
5864 This should be cleaner, somehow. */
5865 obj_elf_section_change_hook ();
5870 seg
= subseg_new (RDATA_SECTION_NAME
, (subsegT
) get_absolute_expression ());
5871 bfd_set_section_flags (stdoutput
, seg
, (SEC_ALLOC
| SEC_LOAD
| SEC_READONLY
| SEC_RELOC
| SEC_DATA
));
5872 if (strcmp (TARGET_OS
, "elf") != 0)
5873 record_alignment (seg
, 4);
5874 demand_empty_rest_of_line ();
5877 seg
= subseg_new (".sdata", (subsegT
) get_absolute_expression ());
5878 bfd_set_section_flags (stdoutput
, seg
, SEC_ALLOC
| SEC_LOAD
| SEC_RELOC
| SEC_DATA
);
5879 if (strcmp (TARGET_OS
, "elf") != 0)
5880 record_alignment (seg
, 4);
5881 demand_empty_rest_of_line ();
5887 s_score_mask (int reg_type ATTRIBUTE_UNUSED
)
5891 if (cur_proc_ptr
== (procS
*) NULL
)
5893 as_warn (_(".mask outside of .ent"));
5894 demand_empty_rest_of_line ();
5897 if (get_absolute_expression_and_terminator (&mask
) != ',')
5899 as_warn (_("Bad .mask directive"));
5900 --input_line_pointer
;
5901 demand_empty_rest_of_line ();
5904 off
= get_absolute_expression ();
5905 cur_proc_ptr
->reg_mask
= mask
;
5906 cur_proc_ptr
->reg_offset
= off
;
5907 demand_empty_rest_of_line ();
5917 name
= input_line_pointer
;
5918 c
= get_symbol_end ();
5919 p
= (symbolS
*) symbol_find_or_make (name
);
5920 *input_line_pointer
= c
;
5930 if (*input_line_pointer
== '-')
5932 ++input_line_pointer
;
5935 if (!ISDIGIT (*input_line_pointer
))
5936 as_bad (_("expected simple number"));
5937 if (input_line_pointer
[0] == '0')
5939 if (input_line_pointer
[1] == 'x')
5941 input_line_pointer
+= 2;
5942 while (ISXDIGIT (*input_line_pointer
))
5945 val
|= hex_value (*input_line_pointer
++);
5947 return negative
? -val
: val
;
5951 ++input_line_pointer
;
5952 while (ISDIGIT (*input_line_pointer
))
5955 val
|= *input_line_pointer
++ - '0';
5957 return negative
? -val
: val
;
5960 if (!ISDIGIT (*input_line_pointer
))
5962 printf (_(" *input_line_pointer == '%c' 0x%02x\n"), *input_line_pointer
, *input_line_pointer
);
5963 as_warn (_("invalid number"));
5966 while (ISDIGIT (*input_line_pointer
))
5969 val
+= *input_line_pointer
++ - '0';
5971 return negative
? -val
: val
;
5974 /* The .aent and .ent directives. */
5977 s_score_ent (int aent
)
5982 symbolP
= get_symbol ();
5983 if (*input_line_pointer
== ',')
5984 ++input_line_pointer
;
5986 if (ISDIGIT (*input_line_pointer
) || *input_line_pointer
== '-')
5989 #ifdef BFD_ASSEMBLER
5990 if ((bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
) != 0)
5995 if (now_seg
!= data_section
&& now_seg
!= bss_section
)
6001 as_warn (_(".ent or .aent not in text section."));
6002 if (!aent
&& cur_proc_ptr
)
6003 as_warn (_("missing .end"));
6006 cur_proc_ptr
= &cur_proc
;
6007 cur_proc_ptr
->reg_mask
= 0xdeadbeaf;
6008 cur_proc_ptr
->reg_offset
= 0xdeadbeaf;
6009 cur_proc_ptr
->fpreg_mask
= 0xdeafbeaf;
6010 cur_proc_ptr
->leaf
= 0xdeafbeaf;
6011 cur_proc_ptr
->frame_offset
= 0xdeafbeaf;
6012 cur_proc_ptr
->frame_reg
= 0xdeafbeaf;
6013 cur_proc_ptr
->pc_reg
= 0xdeafbeaf;
6014 cur_proc_ptr
->isym
= symbolP
;
6015 symbol_get_bfdsym (symbolP
)->flags
|= BSF_FUNCTION
;
6017 if (debug_type
== DEBUG_STABS
)
6018 stabs_generate_asm_func (S_GET_NAME (symbolP
), S_GET_NAME (symbolP
));
6020 demand_empty_rest_of_line ();
6024 s_score_frame (int ignore ATTRIBUTE_UNUSED
)
6031 backupstr
= input_line_pointer
;
6034 if (cur_proc_ptr
== (procS
*) NULL
)
6036 as_warn (_(".frame outside of .ent"));
6037 demand_empty_rest_of_line ();
6040 cur_proc_ptr
->frame_reg
= reg_required_here ((&backupstr
), 0, REG_TYPE_SCORE
);
6042 skip_past_comma (&backupstr
);
6043 while (*backupstr
!= ',')
6045 str
[i
] = *backupstr
;
6053 skip_past_comma (&backupstr
);
6054 cur_proc_ptr
->frame_offset
= val
;
6055 cur_proc_ptr
->pc_reg
= reg_required_here ((&backupstr
), 0, REG_TYPE_SCORE
);
6058 skip_past_comma (&backupstr
);
6060 while (*backupstr
!= '\n')
6062 str
[i
] = *backupstr
;
6068 cur_proc_ptr
->leaf
= val
;
6070 skip_past_comma (&backupstr
);
6072 #endif /* OBJ_ELF */
6073 while (input_line_pointer
!= backupstr
)
6074 input_line_pointer
++;
6077 /* The .end directive. */
6079 s_score_end (int x ATTRIBUTE_UNUSED
)
6084 /* Generate a .pdr section. */
6085 segT saved_seg
= now_seg
;
6086 subsegT saved_subseg
= now_subseg
;
6091 if (!is_end_of_line
[(unsigned char)*input_line_pointer
])
6094 demand_empty_rest_of_line ();
6099 #ifdef BFD_ASSEMBLER
6100 if ((bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
) != 0)
6105 if (now_seg
!= data_section
&& now_seg
!= bss_section
)
6112 as_warn (_(".end not in text section"));
6115 as_warn (_(".end directive without a preceding .ent directive."));
6116 demand_empty_rest_of_line ();
6121 assert (S_GET_NAME (p
));
6122 if (strcmp (S_GET_NAME (p
), S_GET_NAME (cur_proc_ptr
->isym
)))
6123 as_warn (_(".end symbol does not match .ent symbol."));
6124 if (debug_type
== DEBUG_STABS
)
6125 stabs_generate_asm_endfunc (S_GET_NAME (p
), S_GET_NAME (p
));
6128 as_warn (_(".end directive missing or unknown symbol"));
6130 if ((cur_proc_ptr
->reg_mask
== 0xdeadbeaf) ||
6131 (cur_proc_ptr
->reg_offset
== 0xdeadbeaf) ||
6132 (cur_proc_ptr
->leaf
== 0xdeafbeaf) ||
6133 (cur_proc_ptr
->frame_offset
== 0xdeafbeaf) ||
6134 (cur_proc_ptr
->frame_reg
== 0xdeafbeaf) || (cur_proc_ptr
->pc_reg
== 0xdeafbeaf));
6138 dot
= frag_now_fix ();
6140 subseg_set (pdr_seg
, 0);
6141 /* Write the symbol. */
6142 exp
.X_op
= O_symbol
;
6143 exp
.X_add_symbol
= p
;
6144 exp
.X_add_number
= 0;
6145 emit_expr (&exp
, 4);
6146 fragp
= frag_more (7 * 4);
6147 md_number_to_chars (fragp
, (valueT
) cur_proc_ptr
->reg_mask
, 4);
6148 md_number_to_chars (fragp
+ 4, (valueT
) cur_proc_ptr
->reg_offset
, 4);
6149 md_number_to_chars (fragp
+ 8, (valueT
) cur_proc_ptr
->fpreg_mask
, 4);
6150 md_number_to_chars (fragp
+ 12, (valueT
) cur_proc_ptr
->leaf
, 4);
6151 md_number_to_chars (fragp
+ 16, (valueT
) cur_proc_ptr
->frame_offset
, 4);
6152 md_number_to_chars (fragp
+ 20, (valueT
) cur_proc_ptr
->frame_reg
, 4);
6153 md_number_to_chars (fragp
+ 24, (valueT
) cur_proc_ptr
->pc_reg
, 4);
6154 subseg_set (saved_seg
, saved_subseg
);
6157 cur_proc_ptr
= NULL
;
6160 /* Handle the .set pseudo-op. */
6162 s_score_set (int x ATTRIBUTE_UNUSED
)
6165 char name
[MAX_LITERAL_POOL_SIZE
];
6166 char * orig_ilp
= input_line_pointer
;
6168 while (!is_end_of_line
[(unsigned char)*input_line_pointer
])
6170 name
[i
] = (char) * input_line_pointer
;
6172 ++input_line_pointer
;
6177 if (strcmp (name
, "nwarn") == 0)
6179 warn_fix_data_dependency
= 0;
6181 else if (strcmp (name
, "fixdd") == 0)
6183 fix_data_dependency
= 1;
6185 else if (strcmp (name
, "nofixdd") == 0)
6187 fix_data_dependency
= 0;
6189 else if (strcmp (name
, "r1") == 0)
6193 else if (strcmp (name
, "nor1") == 0)
6197 else if (strcmp (name
, "optimize") == 0)
6201 else if (strcmp (name
, "volatile") == 0)
6205 else if (strcmp (name
, "pic") == 0)
6211 input_line_pointer
= orig_ilp
;
6216 /* Handle the .cpload pseudo-op. This is used when generating PIC code. It sets the
6217 $gp register for the function based on the function address, which is in the register
6218 named in the argument. This uses a relocation against GP_DISP_LABEL, which is handled
6219 specially by the linker. The result is:
6220 ldis gp, %hi(GP_DISP_LABEL)
6221 ori gp, %low(GP_DISP_LABEL)
6222 add gp, gp, .cpload argument
6223 The .cpload argument is normally r29. */
6226 s_score_cpload (int ignore ATTRIBUTE_UNUSED
)
6229 char insn_str
[MAX_LITERAL_POOL_SIZE
];
6231 /* If we are not generating PIC code, .cpload is ignored. */
6232 if (score_pic
== NO_PIC
)
6238 if ((reg
= reg_required_here (&input_line_pointer
, -1, REG_TYPE_SCORE
)) == (int) FAIL
)
6241 demand_empty_rest_of_line ();
6243 sprintf (insn_str
, "ld_i32hi r%d, %s", GP
, GP_DISP_LABEL
);
6244 if (append_insn (insn_str
, TRUE
) == (int) FAIL
)
6247 sprintf (insn_str
, "ld_i32lo r%d, %s", GP
, GP_DISP_LABEL
);
6248 if (append_insn (insn_str
, TRUE
) == (int) FAIL
)
6251 sprintf (insn_str
, "add r%d, r%d, r%d", GP
, GP
, reg
);
6252 if (append_insn (insn_str
, TRUE
) == (int) FAIL
)
6256 /* Handle the .cprestore pseudo-op. This stores $gp into a given
6257 offset from $sp. The offset is remembered, and after making a PIC
6258 call $gp is restored from that location. */
6261 s_score_cprestore (int ignore ATTRIBUTE_UNUSED
)
6263 #define SCORE_BP_REG 2
6264 int cprestore_offset
;
6265 char insn_str
[MAX_LITERAL_POOL_SIZE
];
6267 /* If we are not generating PIC code, .cprestore is ignored. */
6268 if (score_pic
== NO_PIC
)
6274 cprestore_offset
= get_absolute_expression ();
6276 sprintf (insn_str
, "sw r%d, [r%d, %d]", GP
, SCORE_BP_REG
, cprestore_offset
);
6277 if (append_insn (insn_str
, TRUE
) == (int) FAIL
)
6281 /* Handle the .gpword pseudo-op. This is used when generating PIC
6282 code. It generates a 32 bit GP relative reloc. */
6284 s_score_gpword (int ignore ATTRIBUTE_UNUSED
)
6289 /* When not generating PIC code, this is treated as .word. */
6290 if (score_pic
== NO_PIC
)
6296 if (ex
.X_op
!= O_symbol
|| ex
.X_add_number
!= 0)
6298 as_bad (_("Unsupported use of .gpword"));
6299 ignore_rest_of_line ();
6302 md_number_to_chars (p
, (valueT
) 0, 4);
6303 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 4, &ex
, FALSE
, BFD_RELOC_GPREL32
);
6304 demand_empty_rest_of_line ();
6307 /* Handle the .cpadd pseudo-op. This is used when dealing with switch
6308 tables in PIC code. */
6311 s_score_cpadd (int ignore ATTRIBUTE_UNUSED
)
6314 char insn_str
[MAX_LITERAL_POOL_SIZE
];
6316 /* If we are not generating PIC code, .cpload is ignored. */
6317 if (score_pic
== NO_PIC
)
6323 if ((reg
= reg_required_here (&input_line_pointer
, -1, REG_TYPE_SCORE
)) == (int) FAIL
)
6327 demand_empty_rest_of_line ();
6329 /* Add $gp to the register named as an argument. */
6330 sprintf (insn_str
, "add r%d, r%d, r%d", reg
, reg
, GP
);
6331 if (append_insn (insn_str
, TRUE
) == (int) FAIL
)
6335 #ifndef TC_IMPLICIT_LCOMM_ALIGNMENT
6336 #define TC_IMPLICIT_LCOMM_ALIGNMENT(SIZE, P2VAR) \
6341 else if ((SIZE) >= 4) \
6343 else if ((SIZE) >= 2) \
6352 s_score_lcomm (int bytes_p
)
6359 segT current_seg
= now_seg
;
6360 subsegT current_subseg
= now_subseg
;
6361 const int max_alignment
= 15;
6363 segT bss_seg
= bss_section
;
6364 int needs_align
= 0;
6366 name
= input_line_pointer
;
6367 c
= get_symbol_end ();
6368 p
= input_line_pointer
;
6373 as_bad (_("expected symbol name"));
6374 discard_rest_of_line ();
6380 /* Accept an optional comma after the name. The comma used to be
6381 required, but Irix 5 cc does not generate it. */
6382 if (*input_line_pointer
== ',')
6384 ++input_line_pointer
;
6388 if (is_end_of_line
[(unsigned char)*input_line_pointer
])
6390 as_bad (_("missing size expression"));
6394 if ((temp
= get_absolute_expression ()) < 0)
6396 as_warn (_("BSS length (%d) < 0 ignored"), temp
);
6397 ignore_rest_of_line ();
6401 #if defined (TC_SCORE)
6402 if (OUTPUT_FLAVOR
== bfd_target_ecoff_flavour
|| OUTPUT_FLAVOR
== bfd_target_elf_flavour
)
6404 /* For Score and Alpha ECOFF or ELF, small objects are put in .sbss. */
6405 if ((unsigned)temp
<= bfd_get_gp_size (stdoutput
))
6407 bss_seg
= subseg_new (".sbss", 1);
6408 seg_info (bss_seg
)->bss
= 1;
6409 #ifdef BFD_ASSEMBLER
6410 if (!bfd_set_section_flags (stdoutput
, bss_seg
, SEC_ALLOC
))
6411 as_warn (_("error setting flags for \".sbss\": %s"), bfd_errmsg (bfd_get_error ()));
6418 if (*input_line_pointer
== ',')
6420 ++input_line_pointer
;
6423 if (is_end_of_line
[(unsigned char)*input_line_pointer
])
6425 as_bad (_("missing alignment"));
6430 align
= get_absolute_expression ();
6437 TC_IMPLICIT_LCOMM_ALIGNMENT (temp
, align
);
6439 /* Still zero unless TC_IMPLICIT_LCOMM_ALIGNMENT set it. */
6441 record_alignment (bss_seg
, align
);
6448 /* Convert to a power of 2. */
6453 for (i
= 0; align
!= 0; align
>>= 1, ++i
)
6459 if (align
> max_alignment
)
6461 align
= max_alignment
;
6462 as_warn (_("alignment too large; %d assumed"), align
);
6467 as_warn (_("alignment negative; 0 assumed"));
6470 record_alignment (bss_seg
, align
);
6474 /* Assume some objects may require alignment on some systems. */
6475 #if defined (TC_ALPHA) && ! defined (VMS)
6478 align
= ffs (temp
) - 1;
6479 if (temp
% (1 << align
))
6486 symbolP
= symbol_find_or_make (name
);
6490 #if (defined (OBJ_AOUT) || defined (OBJ_MAYBE_AOUT) \
6491 || defined (OBJ_BOUT) || defined (OBJ_MAYBE_BOUT))
6492 #ifdef BFD_ASSEMBLER
6493 (OUTPUT_FLAVOR
!= bfd_target_aout_flavour
6494 || (S_GET_OTHER (symbolP
) == 0 && S_GET_DESC (symbolP
) == 0)) &&
6496 (S_GET_OTHER (symbolP
) == 0 && S_GET_DESC (symbolP
) == 0) &&
6499 (S_GET_SEGMENT (symbolP
) == bss_seg
|| (!S_IS_DEFINED (symbolP
) && S_GET_VALUE (symbolP
) == 0)))
6503 subseg_set (bss_seg
, 1);
6506 frag_align (align
, 0, 0);
6508 /* Detach from old frag. */
6509 if (S_GET_SEGMENT (symbolP
) == bss_seg
)
6510 symbol_get_frag (symbolP
)->fr_symbol
= NULL
;
6512 symbol_set_frag (symbolP
, frag_now
);
6513 pfrag
= frag_var (rs_org
, 1, 1, (relax_substateT
) 0, symbolP
, (offsetT
) temp
, NULL
);
6517 S_SET_SEGMENT (symbolP
, bss_seg
);
6520 /* The symbol may already have been created with a preceding
6521 ".globl" directive -- be careful not to step on storage class
6522 in that case. Otherwise, set it to static. */
6523 if (S_GET_STORAGE_CLASS (symbolP
) != C_EXT
)
6525 S_SET_STORAGE_CLASS (symbolP
, C_STAT
);
6527 #endif /* OBJ_COFF */
6530 S_SET_SIZE (symbolP
, temp
);
6534 as_bad (_("symbol `%s' is already defined"), S_GET_NAME (symbolP
));
6536 subseg_set (current_seg
, current_subseg
);
6538 demand_empty_rest_of_line ();
6542 insert_reg (const struct reg_entry
*r
, struct hash_control
*htab
)
6545 int len
= strlen (r
->name
) + 2;
6546 char *buf
= xmalloc (len
);
6547 char *buf2
= xmalloc (len
);
6549 strcpy (buf
+ i
, r
->name
);
6550 for (i
= 0; buf
[i
]; i
++)
6552 buf2
[i
] = TOUPPER (buf
[i
]);
6556 hash_insert (htab
, buf
, (void *) r
);
6557 hash_insert (htab
, buf2
, (void *) r
);
6561 build_reg_hsh (struct reg_map
*map
)
6563 const struct reg_entry
*r
;
6565 if ((map
->htab
= hash_new ()) == NULL
)
6567 as_fatal (_("virtual memory exhausted"));
6569 for (r
= map
->names
; r
->name
!= NULL
; r
++)
6571 insert_reg (r
, map
->htab
);
6582 if ((score_ops_hsh
= hash_new ()) == NULL
)
6583 as_fatal (_("virtual memory exhausted"));
6585 build_score_ops_hsh ();
6587 if ((dependency_insn_hsh
= hash_new ()) == NULL
)
6588 as_fatal (_("virtual memory exhausted"));
6590 build_dependency_insn_hsh ();
6592 for (i
= (int)REG_TYPE_FIRST
; i
< (int)REG_TYPE_MAX
; i
++)
6593 build_reg_hsh (all_reg_maps
+ i
);
6595 /* Initialize dependency vector. */
6596 init_dependency_vector ();
6598 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
, 0);
6600 subseg
= now_subseg
;
6601 pdr_seg
= subseg_new (".pdr", (subsegT
) 0);
6602 (void)bfd_set_section_flags (stdoutput
, pdr_seg
, SEC_READONLY
| SEC_RELOC
| SEC_DEBUGGING
);
6603 (void)bfd_set_section_alignment (stdoutput
, pdr_seg
, 2);
6604 subseg_set (seg
, subseg
);
6606 if (USE_GLOBAL_POINTER_OPT
)
6607 bfd_set_gp_size (stdoutput
, g_switch_value
);
6611 const pseudo_typeS md_pseudo_table
[] =
6613 {"bss", s_score_bss
, 0},
6614 {"text", s_score_text
, 0},
6617 {"extend", float_cons
, 'x'},
6618 {"ldouble", float_cons
, 'x'},
6619 {"packed", float_cons
, 'p'},
6620 {"end", s_score_end
, 0},
6621 {"ent", s_score_ent
, 0},
6622 {"frame", s_score_frame
, 0},
6623 {"rdata", s_change_sec
, 'r'},
6624 {"sdata", s_change_sec
, 's'},
6625 {"set", s_score_set
, 0},
6626 {"mask", s_score_mask
, 'R'},
6628 {"lcomm", s_score_lcomm
, 1},
6629 {"section", score_s_section
, 0},
6630 {"cpload", s_score_cpload
, 0},
6631 {"cprestore", s_score_cprestore
, 0},
6632 {"gpword", s_score_gpword
, 0},
6633 {"cpadd", s_score_cpadd
, 0},