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
*cur_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
)
3641 fixp
= fix_new_score (frag_now
, p
- frag_now
->fr_literal
, inst_main
.size
,
3642 &inst_main
.reloc
.exp
, inst_main
.reloc
.pc_rel
, inst_main
.reloc
.type
);
3644 frag_now
->tc_frag_data
.fixp
= fixp
;
3645 cur_fixp
= frag_now
->tc_frag_data
.fixp
;
3648 dwarf2_emit_insn (inst_main
.size
);
3651 where
= p
- frag_now
->fr_literal
+ inst_main
.size
;
3652 for (i
= 0; i
< var_num
; i
++)
3655 where
+= var_insts
[i
- 1].size
;
3657 if (var_insts
[i
].reloc
.type
!= BFD_RELOC_NONE
)
3659 fixp
= fix_new_score (frag_now
, where
, var_insts
[i
].size
,
3660 &var_insts
[i
].reloc
.exp
, var_insts
[i
].reloc
.pc_rel
,
3661 var_insts
[i
].reloc
.type
);
3666 cur_fixp
->fx_next
= fixp
;
3667 cur_fixp
= cur_fixp
->fx_next
;
3671 frag_now
->tc_frag_data
.fixp
= fixp
;
3672 cur_fixp
= frag_now
->tc_frag_data
.fixp
;
3678 p
= frag_var (rs_machine_dependent
, inst_main
.relax_size
+ RELAX_PAD_BYTE
, 0,
3679 RELAX_ENCODE (inst_main
.size
, inst_main
.relax_size
, inst_main
.type
,
3680 0, inst_main
.size
, 0), add_symbol
, 0, NULL
);
3682 /* Write fr_var part.
3683 no calling gen_insn_frag, no fixS will be generated. */
3684 for (i
= 0; i
< var_num
; i
++)
3686 md_number_to_chars (p
, var_insts
[i
].instruction
, var_insts
[i
].size
);
3687 p
+= var_insts
[i
].size
;
3689 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
3693 /* Build a relax frag for la instruction when generating PIC,
3694 external symbol first and local symbol second. */
3697 build_la_pic (int reg_rd
, expressionS exp
)
3699 symbolS
*add_symbol
= exp
.X_add_symbol
;
3700 offsetT add_number
= exp
.X_add_number
;
3701 struct score_it fix_insts
[RELAX_INST_NUM
];
3702 struct score_it var_insts
[RELAX_INST_NUM
];
3705 char tmp
[MAX_LITERAL_POOL_SIZE
];
3711 if (add_number
== 0)
3716 /* Insn 1 and Insn 2 */
3718 For an external symbol: lw rD, <sym>($gp)
3719 (BFD_RELOC_SCORE_GOT15 or BFD_RELOC_SCORE_CALL15) */
3720 sprintf (tmp
, "lw_pic r%d, %s", reg_rd
, add_symbol
->bsym
->name
);
3721 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
3724 if (reg_rd
== PIC_CALL_REG
)
3725 inst
.reloc
.type
= BFD_RELOC_SCORE_CALL15
;
3726 memcpy (&fix_insts
[0], &inst
, sizeof (struct score_it
));
3729 For a local symbol :
3730 lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15)
3731 addi rD, <sym> (BFD_RELOC_GOT_LO16) */
3732 inst
.reloc
.type
= BFD_RELOC_SCORE_GOT15
;
3733 memcpy (&var_insts
[0], &inst
, sizeof (struct score_it
));
3734 sprintf (tmp
, "addi_s_pic r%d, %s", reg_rd
, add_symbol
->bsym
->name
);
3735 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
3738 memcpy (&var_insts
[1], &inst
, sizeof (struct score_it
));
3739 build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
3741 else if (add_number
>= -0x8000 && add_number
<= 0x7fff)
3743 /* Insn 1: lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15) */
3744 sprintf (tmp
, "lw_pic r%d, %s", reg_rd
, add_symbol
->bsym
->name
);
3745 if (append_insn (tmp
, TRUE
) == (int) FAIL
)
3752 For an external symbol: addi rD, <constant> */
3753 sprintf (tmp
, "addi r%d, %d", reg_rd
, (int)add_number
);
3754 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
3757 memcpy (&fix_insts
[0], &inst
, sizeof (struct score_it
));
3760 For a local symbol: addi rD, <sym>+<constant> (BFD_RELOC_GOT_LO16) */
3761 sprintf (tmp
, "addi_s_pic r%d, %s + %d", reg_rd
, add_symbol
->bsym
->name
, (int)add_number
);
3762 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
3765 memcpy (&var_insts
[0], &inst
, sizeof (struct score_it
));
3766 build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
3770 int hi
= (add_number
>> 16) & 0x0000FFFF;
3771 int lo
= add_number
& 0x0000FFFF;
3773 /* Insn 1: lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15) */
3774 sprintf (tmp
, "lw_pic r%d, %s", reg_rd
, add_symbol
->bsym
->name
);
3775 if (append_insn (tmp
, TRUE
) == (int) FAIL
)
3782 For an external symbol: ldis r1, HI%<constant> */
3783 sprintf (tmp
, "ldis %s, %d", "r1", hi
);
3784 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
3787 memcpy (&fix_insts
[0], &inst
, sizeof (struct score_it
));
3790 For a local symbol: ldis r1, HI%<constant>
3791 but, if lo is outof 16 bit, make hi plus 1 */
3792 if ((lo
< -0x8000) || (lo
> 0x7fff))
3796 sprintf (tmp
, "ldis_pic %s, %d", "r1", hi
);
3797 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
3800 memcpy (&var_insts
[0], &inst
, sizeof (struct score_it
));
3801 build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
3807 For an external symbol: ori r1, LO%<constant> */
3808 sprintf (tmp
, "ori %s, %d", "r1", lo
);
3809 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
3812 memcpy (&fix_insts
[0], &inst
, sizeof (struct score_it
));
3815 For a local symbol: addi r1, <sym>+LO%<constant> (BFD_RELOC_GOT_LO16) */
3816 sprintf (tmp
, "addi_u_pic %s, %s + %d", "r1", add_symbol
->bsym
->name
, lo
);
3817 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
3820 memcpy (&var_insts
[0], &inst
, sizeof (struct score_it
));
3821 build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
3823 /* Insn 4: add rD, rD, r1 */
3824 sprintf (tmp
, "add r%d, r%d, %s", reg_rd
, reg_rd
, "r1");
3825 if (append_insn (tmp
, TRUE
) == (int) FAIL
)
3828 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
3837 do_macro_la_rdi32 (char *str
)
3841 skip_whitespace (str
);
3842 if ((reg_rd
= reg_required_here (&str
, 20, REG_TYPE_SCORE
)) == (int) FAIL
3843 || skip_past_comma (&str
) == (int) FAIL
)
3849 char append_str
[MAX_LITERAL_POOL_SIZE
];
3850 char *keep_data
= str
;
3852 /* la rd, simm16. */
3853 if (data_op2 (&str
, 1, _SIMM16_LA
) != (int) FAIL
)
3858 /* la rd, imm32 or la rd, label. */
3861 SET_INSN_ERROR (NULL
);
3863 if ((data_op2 (&str
, 1, _VALUE_HI16
) == (int) FAIL
)
3864 || (end_of_line (str
) == (int) FAIL
))
3870 if ((score_pic
== NO_PIC
) || (!inst
.reloc
.exp
.X_add_symbol
))
3872 sprintf (append_str
, "ld_i32hi r%d, %s", reg_rd
, keep_data
);
3873 if (append_insn (append_str
, TRUE
) == (int) FAIL
)
3876 sprintf (append_str
, "ld_i32lo r%d, %s", reg_rd
, keep_data
);
3877 if (append_insn (append_str
, TRUE
) == (int) FAIL
)
3882 assert (inst
.reloc
.exp
.X_add_symbol
);
3883 build_la_pic (reg_rd
, inst
.reloc
.exp
);
3886 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
3895 do_macro_li_rdi32 (char *str
){
3899 skip_whitespace (str
);
3900 if ((reg_rd
= reg_required_here (&str
, 20, REG_TYPE_SCORE
)) == (int) FAIL
3901 || skip_past_comma (&str
) == (int) FAIL
)
3907 char *keep_data
= str
;
3909 /* li rd, simm16. */
3910 if (data_op2 (&str
, 1, _SIMM16_LA
) != (int) FAIL
)
3918 char append_str
[MAX_LITERAL_POOL_SIZE
];
3922 if ((data_op2 (&str
, 1, _VALUE_HI16
) == (int) FAIL
)
3923 || (end_of_line (str
) == (int) FAIL
))
3927 else if (inst
.reloc
.exp
.X_add_symbol
)
3929 inst
.error
= _("li rd label isn't correct instruction form");
3934 sprintf (append_str
, "ld_i32hi r%d, %s", reg_rd
, keep_data
);
3936 if (append_insn (append_str
, TRUE
) == (int) FAIL
)
3940 sprintf (append_str
, "ld_i32lo r%d, %s", reg_rd
, keep_data
);
3941 if (append_insn (append_str
, TRUE
) == (int) FAIL
)
3944 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
3952 /* Handle mul/mulu/div/divu/rem/remu. */
3954 do_macro_mul_rdrsrs (char *str
)
3960 char append_str
[MAX_LITERAL_POOL_SIZE
];
3962 if (university_version
== 1)
3963 as_warn ("%s", ERR_FOR_SCORE5U_MUL_DIV
);
3965 strcpy (append_str
, str
);
3966 backupstr
= append_str
;
3967 skip_whitespace (backupstr
);
3968 if (((reg_rd
= reg_required_here (&backupstr
, -1, REG_TYPE_SCORE
)) == (int) FAIL
)
3969 || (skip_past_comma (&backupstr
) == (int) FAIL
)
3970 || ((reg_rs1
= reg_required_here (&backupstr
, -1, REG_TYPE_SCORE
)) == (int) FAIL
))
3972 inst
.error
= BAD_ARGS
;
3976 if (skip_past_comma (&backupstr
) == (int) FAIL
)
3978 /* rem/remu rA, rB is error format. */
3979 if (strcmp (inst
.name
, "rem") == 0 || strcmp (inst
.name
, "remu") == 0)
3981 SET_INSN_ERROR (BAD_ARGS
);
3985 SET_INSN_ERROR (NULL
);
3992 SET_INSN_ERROR (NULL
);
3993 if (((reg_rs2
= reg_required_here (&backupstr
, -1, REG_TYPE_SCORE
)) == (int) FAIL
)
3994 || (end_of_line (backupstr
) == (int) FAIL
))
4000 char append_str1
[MAX_LITERAL_POOL_SIZE
];
4002 if (strcmp (inst
.name
, "rem") == 0)
4004 sprintf (append_str
, "%s r%d, r%d", "mul", reg_rs1
, reg_rs2
);
4005 sprintf (append_str1
, "mfceh r%d", reg_rd
);
4007 else if (strcmp (inst
.name
, "remu") == 0)
4009 sprintf (append_str
, "%s r%d, r%d", "mulu", reg_rs1
, reg_rs2
);
4010 sprintf (append_str1
, "mfceh r%d", reg_rd
);
4014 sprintf (append_str
, "%s r%d, r%d", inst
.name
, reg_rs1
, reg_rs2
);
4015 sprintf (append_str1
, "mfcel r%d", reg_rd
);
4018 /* Output mul/mulu or div/divu or rem/remu. */
4019 if (append_insn (append_str
, TRUE
) == (int) FAIL
)
4022 /* Output mfcel or mfceh. */
4023 if (append_insn (append_str1
, TRUE
) == (int) FAIL
)
4026 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4033 exp_macro_ldst_abs (char *str
)
4036 char *backupstr
, *tmp
;
4037 char append_str
[MAX_LITERAL_POOL_SIZE
];
4038 char verifystr
[MAX_LITERAL_POOL_SIZE
];
4039 struct score_it inst_backup
;
4044 memcpy (&inst_backup
, &inst
, sizeof (struct score_it
));
4046 strcpy (verifystr
, str
);
4047 backupstr
= verifystr
;
4048 skip_whitespace (backupstr
);
4049 if ((reg_rd
= reg_required_here (&backupstr
, -1, REG_TYPE_SCORE
)) == (int) FAIL
)
4053 if (skip_past_comma (&backupstr
) == (int) FAIL
)
4057 sprintf (append_str
, "li r1 %s", backupstr
);
4058 append_insn (append_str
, TRUE
);
4060 memcpy (&inst
, &inst_backup
, sizeof (struct score_it
));
4061 sprintf (append_str
, " r%d, [r1,0]", reg_rd
);
4062 do_ldst_insn (append_str
);
4068 nopic_need_relax (symbolS
* sym
, int before_relaxing
)
4072 else if (USE_GLOBAL_POINTER_OPT
&& g_switch_value
> 0)
4074 const char *symname
;
4075 const char *segname
;
4077 /* Find out whether this symbol can be referenced off the $gp
4078 register. It can be if it is smaller than the -G size or if
4079 it is in the .sdata or .sbss section. Certain symbols can
4080 not be referenced off the $gp, although it appears as though
4082 symname
= S_GET_NAME (sym
);
4083 if (symname
!= (const char *)NULL
4084 && (strcmp (symname
, "eprol") == 0
4085 || strcmp (symname
, "etext") == 0
4086 || strcmp (symname
, "_gp") == 0
4087 || strcmp (symname
, "edata") == 0
4088 || strcmp (symname
, "_fbss") == 0
4089 || strcmp (symname
, "_fdata") == 0
4090 || strcmp (symname
, "_ftext") == 0
4091 || strcmp (symname
, "end") == 0
4092 || strcmp (symname
, GP_DISP_LABEL
) == 0))
4096 else if ((!S_IS_DEFINED (sym
) || S_IS_COMMON (sym
)) && (0
4097 /* We must defer this decision until after the whole file has been read,
4098 since there might be a .extern after the first use of this symbol. */
4100 && S_GET_VALUE (sym
) == 0)
4101 || (S_GET_VALUE (sym
) != 0
4102 && S_GET_VALUE (sym
) <= g_switch_value
)))
4107 segname
= segment_name (S_GET_SEGMENT (sym
));
4108 return (strcmp (segname
, ".sdata") != 0
4109 && strcmp (segname
, ".sbss") != 0
4110 && strncmp (segname
, ".sdata.", 7) != 0
4111 && strncmp (segname
, ".gnu.linkonce.s.", 16) != 0);
4113 /* We are not optimizing for the $gp register. */
4118 /* Build a relax frag for lw instruction when generating PIC,
4119 external symbol first and local symbol second. */
4122 build_lw_pic (int reg_rd
, expressionS exp
)
4124 symbolS
*add_symbol
= exp
.X_add_symbol
;
4125 int add_number
= exp
.X_add_number
;
4126 struct score_it fix_insts
[RELAX_INST_NUM
];
4127 struct score_it var_insts
[RELAX_INST_NUM
];
4130 char tmp
[MAX_LITERAL_POOL_SIZE
];
4136 if ((add_number
== 0) || (add_number
>= -0x8000 && add_number
<= 0x7fff))
4141 /* Insn 1 and Insn 2 */
4143 For an external symbol: lw rD, <sym>($gp)
4144 (BFD_RELOC_SCORE_GOT15) */
4145 sprintf (tmp
, "lw_pic r%d, %s", reg_rd
, add_symbol
->bsym
->name
);
4146 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
4149 memcpy (&fix_insts
[0], &inst
, sizeof (struct score_it
));
4152 For a local symbol :
4153 lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15)
4154 addi rD, <sym> (BFD_RELOC_GOT_LO16) */
4155 inst
.reloc
.type
= BFD_RELOC_SCORE_GOT15
;
4156 memcpy (&var_insts
[0], &inst
, sizeof (struct score_it
));
4157 sprintf (tmp
, "addi_s_pic r%d, %s", reg_rd
, add_symbol
->bsym
->name
);
4158 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
4161 memcpy (&var_insts
[1], &inst
, sizeof (struct score_it
));
4162 build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
4164 /* Insn 2: lw rD, [rD, constant] */
4165 sprintf (tmp
, "lw r%d, [r%d, %d]", reg_rd
, reg_rd
, add_number
);
4166 if (append_insn (tmp
, TRUE
) == (int) FAIL
)
4169 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4174 int hi
= (add_number
>> 16) & 0x0000FFFF;
4175 int lo
= add_number
& 0x0000FFFF;
4177 /* Insn 1: lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15) */
4178 sprintf (tmp
, "lw_pic r%d, %s", reg_rd
, add_symbol
->bsym
->name
);
4179 if (append_insn (tmp
, TRUE
) == (int) FAIL
)
4186 For an external symbol: ldis r1, HI%<constant> */
4187 sprintf (tmp
, "ldis %s, %d", "r1", hi
);
4188 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
4191 memcpy (&fix_insts
[0], &inst
, sizeof (struct score_it
));
4194 For a local symbol: ldis r1, HI%<constant>
4195 but, if lo is outof 16 bit, make hi plus 1 */
4196 if ((lo
< -0x8000) || (lo
> 0x7fff))
4200 sprintf (tmp
, "ldis_pic %s, %d", "r1", hi
);
4201 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
4204 memcpy (&var_insts
[0], &inst
, sizeof (struct score_it
));
4205 build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
4211 For an external symbol: ori r1, LO%<constant> */
4212 sprintf (tmp
, "ori %s, %d", "r1", lo
);
4213 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
4216 memcpy (&fix_insts
[0], &inst
, sizeof (struct score_it
));
4219 For a local symbol: addi r1, <sym>+LO%<constant> (BFD_RELOC_GOT_LO16) */
4220 sprintf (tmp
, "addi_u_pic %s, %s + %d", "r1", add_symbol
->bsym
->name
, lo
);
4221 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
4224 memcpy (&var_insts
[0], &inst
, sizeof (struct score_it
));
4225 build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
4227 /* Insn 4: add rD, rD, r1 */
4228 sprintf (tmp
, "add r%d, r%d, %s", reg_rd
, reg_rd
, "r1");
4229 if (append_insn (tmp
, TRUE
) == (int) FAIL
)
4232 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4235 /* Insn 5: lw rD, [rD, 0] */
4236 sprintf (tmp
, "lw r%d, [r%d, 0]", reg_rd
, reg_rd
);
4237 if (append_insn (tmp
, TRUE
) == (int) FAIL
)
4240 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4248 do_macro_ldst_label (char *str
)
4256 char *absolute_value
;
4257 char append_str
[3][MAX_LITERAL_POOL_SIZE
];
4258 char verifystr
[MAX_LITERAL_POOL_SIZE
];
4259 struct score_it inst_backup
;
4260 struct score_it inst_expand
[3];
4261 struct score_it inst_main
;
4263 memcpy (&inst_backup
, &inst
, sizeof (struct score_it
));
4264 strcpy (verifystr
, str
);
4265 backup_str
= verifystr
;
4267 skip_whitespace (backup_str
);
4268 if ((reg_rd
= reg_required_here (&backup_str
, -1, REG_TYPE_SCORE
)) == (int) FAIL
)
4271 if (skip_past_comma (&backup_str
) == (int) FAIL
)
4274 label_str
= backup_str
;
4276 /* Ld/st rD, [rA, imm] ld/st rD, [rA]+, imm ld/st rD, [rA, imm]+. */
4277 if (*backup_str
== '[')
4283 /* Ld/st rD, imm. */
4284 absolute_value
= backup_str
;
4285 if ((my_get_expression (&inst
.reloc
.exp
, &backup_str
) == (int) FAIL
)
4286 || (validate_immediate (inst
.reloc
.exp
.X_add_number
, _VALUE
) == (int) FAIL
)
4287 || (end_of_line (backup_str
) == (int) FAIL
))
4293 if (inst
.reloc
.exp
.X_add_symbol
== 0)
4295 memcpy (&inst
, &inst_backup
, sizeof (struct score_it
));
4296 exp_macro_ldst_abs (str
);
4301 /* Ld/st rD, label. */
4302 backup_str
= absolute_value
;
4303 if ((data_op2 (&backup_str
, 1, _GP_IMM15
) == (int) FAIL
)
4304 || (end_of_line (backup_str
) == (int) FAIL
))
4310 if (inst
.reloc
.exp
.X_add_symbol
== 0)
4313 inst
.error
= BAD_ARGS
;
4318 if (score_pic
== PIC
)
4320 build_lw_pic (reg_rd
, inst
.reloc
.exp
);
4325 if ((inst
.reloc
.exp
.X_add_number
<= 0x3fff)
4326 && (inst
.reloc
.exp
.X_add_number
>= -0x4000)
4327 && (!nopic_need_relax (inst
.reloc
.exp
.X_add_symbol
, 1)))
4331 /* Assign the real opcode. */
4332 ldst_idx
= inst
.instruction
& OPC_PSEUDOLDST_MASK
;
4333 inst
.instruction
&= ~OPC_PSEUDOLDST_MASK
;
4334 inst
.instruction
|= score_ldst_insns
[ldst_idx
* 3 + 0].value
;
4335 inst
.instruction
|= reg_rd
<< 20;
4336 inst
.instruction
|= GP
<< 15;
4337 inst
.relax_inst
= 0x8000;
4338 inst
.relax_size
= 0;
4345 memcpy (&inst_main
, &inst
, sizeof (struct score_it
));
4349 /* Determine which instructions should be output. */
4350 sprintf (append_str
[0], "ld_i32hi r1, %s", label_str
);
4351 sprintf (append_str
[1], "ld_i32lo r1, %s", label_str
);
4352 sprintf (append_str
[2], "%s r%d, [r1, 0]", inst_backup
.name
, reg_rd
);
4354 /* Generate three instructions.
4356 ld/st rd, [r1, 0] */
4357 for (i
= 0; i
< 3; i
++)
4359 if (append_insn (append_str
[i
], FALSE
) == (int) FAIL
)
4362 memcpy (&inst_expand
[i
], &inst
, sizeof (struct score_it
));
4369 /* Adjust instruction opcode and to be relaxed instruction opcode. */
4370 inst_main
.instruction
= adjust_paritybit (inst_main
.instruction
, GET_INSN_CLASS (inst_main
.type
));
4371 inst_main
.relax_size
= inst_expand
[0].size
+ inst_expand
[1].size
+ inst_expand
[2].size
;
4372 inst_main
.type
= Insn_GP
;
4374 for (i
= 0; i
< 3; i
++)
4375 inst_expand
[i
].instruction
= adjust_paritybit (inst_expand
[i
].instruction
4376 , GET_INSN_CLASS (inst_expand
[i
].type
));
4378 /* Check data dependency. */
4379 handle_dependency (&inst_main
);
4381 /* Start a new frag if frag_now is not empty. */
4382 if (frag_now_fix () != 0)
4384 if (!frag_now
->tc_frag_data
.is_insn
)
4385 frag_wane (frag_now
);
4391 /* Write fr_fix part. */
4392 p
= frag_more (inst_main
.size
);
4393 md_number_to_chars (p
, inst_main
.instruction
, inst_main
.size
);
4395 if (inst_main
.reloc
.type
!= BFD_RELOC_NONE
)
4397 fix_new_score (frag_now
, p
- frag_now
->fr_literal
, inst_main
.size
,
4398 &inst_main
.reloc
.exp
, inst_main
.reloc
.pc_rel
, inst_main
.reloc
.type
);
4402 dwarf2_emit_insn (inst_main
.size
);
4405 /* GP instruction can not do optimization, only can do relax between
4406 1 instruction and 3 instructions. */
4407 p
= frag_var (rs_machine_dependent
, inst_main
.relax_size
+ RELAX_PAD_BYTE
, 0,
4408 RELAX_ENCODE (inst_main
.size
, inst_main
.relax_size
, inst_main
.type
, 0, 4, 0),
4409 inst_main
.reloc
.exp
.X_add_symbol
, 0, NULL
);
4411 /* Write fr_var part.
4412 no calling gen_insn_frag, no fixS will be generated. */
4413 md_number_to_chars (p
, inst_expand
[0].instruction
, inst_expand
[0].size
);
4414 p
+= inst_expand
[0].size
;
4415 md_number_to_chars (p
, inst_expand
[1].instruction
, inst_expand
[1].size
);
4416 p
+= inst_expand
[1].size
;
4417 md_number_to_chars (p
, inst_expand
[2].instruction
, inst_expand
[2].size
);
4421 gen_insn_frag (&inst_expand
[0], NULL
);
4422 gen_insn_frag (&inst_expand
[1], NULL
);
4423 gen_insn_frag (&inst_expand
[2], NULL
);
4427 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4432 do_lw_pic (char *str
)
4436 skip_whitespace (str
);
4437 if (((reg_rd
= reg_required_here (&str
, 20, REG_TYPE_SCORE
)) == (int) FAIL
)
4438 || (skip_past_comma (&str
) == (int) FAIL
)
4439 || (my_get_expression (&inst
.reloc
.exp
, &str
) == (int) FAIL
)
4440 || (end_of_line (str
) == (int) FAIL
))
4446 if (inst
.reloc
.exp
.X_add_symbol
== 0)
4449 inst
.error
= BAD_ARGS
;
4454 inst
.instruction
|= GP
<< 15;
4455 inst
.reloc
.type
= BFD_RELOC_SCORE_GOT15
;
4460 do_empty (char *str
)
4463 if (university_version
== 1)
4465 if (((inst
.instruction
& 0x3e0003ff) == 0x0c000004)
4466 || ((inst
.instruction
& 0x3e0003ff) == 0x0c000024)
4467 || ((inst
.instruction
& 0x3e0003ff) == 0x0c000044)
4468 || ((inst
.instruction
& 0x3e0003ff) == 0x0c000064))
4470 inst
.error
= ERR_FOR_SCORE5U_MMU
;
4474 if (end_of_line (str
) == (int) FAIL
)
4477 if (inst
.relax_inst
!= 0x8000)
4479 if (inst
.type
== NO_OPD
)
4481 inst
.relax_size
= 2;
4485 inst
.relax_size
= 4;
4496 skip_whitespace (str
);
4497 if (my_get_expression (&inst
.reloc
.exp
, &str
) == (int) FAIL
4498 || end_of_line (str
) == (int) FAIL
)
4501 if (inst
.reloc
.exp
.X_add_symbol
== 0)
4503 inst
.error
= _("lacking label ");
4507 if (((inst
.reloc
.exp
.X_add_number
& 0xff000000) != 0)
4508 && ((inst
.reloc
.exp
.X_add_number
& 0xff000000) != 0xff000000))
4510 sprintf (err_msg
, "invalid constant: 25 bit expression not in range -2^24..2^24");
4511 inst
.error
= _(err_msg
);
4515 save_in
= input_line_pointer
;
4516 input_line_pointer
= str
;
4517 inst
.reloc
.type
= BFD_RELOC_SCORE_JMP
;
4518 inst
.reloc
.pc_rel
= 1;
4519 input_line_pointer
= save_in
;
4523 do16_jump (char *str
)
4525 skip_whitespace (str
);
4526 if (my_get_expression (&inst
.reloc
.exp
, &str
) == (int) FAIL
4527 || end_of_line (str
) == (int) FAIL
)
4531 else if (inst
.reloc
.exp
.X_add_symbol
== 0)
4533 inst
.error
= _("lacking label ");
4536 else if (((inst
.reloc
.exp
.X_add_number
& 0xfffff800) != 0)
4537 && ((inst
.reloc
.exp
.X_add_number
& 0xfffff800) != 0xfffff800))
4539 inst
.error
= _("invalid constant: 12 bit expression not in range -2^11..2^11");
4543 inst
.reloc
.type
= BFD_RELOC_SCORE16_JMP
;
4544 inst
.reloc
.pc_rel
= 1;
4548 do_branch (char *str
)
4550 unsigned long abs_value
= 0;
4552 if (my_get_expression (&inst
.reloc
.exp
, &str
) == (int) FAIL
4553 || end_of_line (str
) == (int) FAIL
)
4557 else if (inst
.reloc
.exp
.X_add_symbol
== 0)
4559 inst
.error
= _("lacking label ");
4562 else if (((inst
.reloc
.exp
.X_add_number
& 0xff000000) != 0)
4563 && ((inst
.reloc
.exp
.X_add_number
& 0xff000000) != 0xff000000))
4565 inst
.error
= "invalid constant: 20 bit expression not in range -2^19..2^19";
4569 inst
.reloc
.type
= BFD_RELOC_SCORE_BRANCH
;
4570 inst
.reloc
.pc_rel
= 1;
4572 /* Branch 32 offset field : 20 bit, 16 bit branch offset field : 8 bit. */
4573 inst
.instruction
|= (inst
.reloc
.exp
.X_add_number
& 0x3fe) | ((inst
.reloc
.exp
.X_add_number
& 0xffc00) << 5);
4575 /* Take the branch condition code. */
4576 inst
.relax_inst
= 0x4000 | (((inst
.instruction
>> 10) & 0xf) << 8);
4578 if ((abs_value
& 0xfffffe00) == 0)
4580 inst
.relax_inst
|= ((inst
.reloc
.exp
.X_add_number
>> 1) & 0xff);
4581 inst
.relax_size
= 2;
4585 inst
.relax_inst
= 0x8000;
4588 if (inst
.instruction
& 1)
4589 inst
.relax_inst
= 0x8000;
4593 do16_branch (char *str
)
4595 if ((my_get_expression (&inst
.reloc
.exp
, &str
) == (int) FAIL
4596 || end_of_line (str
) == (int) FAIL
))
4600 else if (inst
.reloc
.exp
.X_add_symbol
== 0)
4602 inst
.error
= _("lacking label");
4604 else if (((inst
.reloc
.exp
.X_add_number
& 0xffffff00) != 0)
4605 && ((inst
.reloc
.exp
.X_add_number
& 0xffffff00) != 0xffffff00))
4607 inst
.error
= _("invalid constant: 9 bit expression not in range -2^8..2^8");
4611 inst
.reloc
.type
= BFD_RELOC_SCORE16_BRANCH
;
4612 inst
.reloc
.pc_rel
= 1;
4613 inst
.instruction
|= ((inst
.reloc
.exp
.X_add_number
>> 1) & 0xff);
4617 /* Iterate over the base tables to create the instruction patterns. */
4619 build_score_ops_hsh (void)
4622 static struct obstack insn_obstack
;
4624 obstack_begin (&insn_obstack
, 4000);
4625 for (i
= 0; i
< sizeof (score_insns
) / sizeof (struct asm_opcode
); i
++)
4627 const struct asm_opcode
*insn
= score_insns
+ i
;
4628 unsigned len
= strlen (insn
->template);
4629 struct asm_opcode
*new;
4631 new = obstack_alloc (&insn_obstack
, sizeof (struct asm_opcode
));
4632 template = obstack_alloc (&insn_obstack
, len
+ 1);
4634 strcpy (template, insn
->template);
4635 new->template = template;
4636 new->parms
= insn
->parms
;
4637 new->value
= insn
->value
;
4638 new->relax_value
= insn
->relax_value
;
4639 new->type
= insn
->type
;
4640 new->bitmask
= insn
->bitmask
;
4641 hash_insert (score_ops_hsh
, new->template, (void *) new);
4646 build_dependency_insn_hsh (void)
4649 static struct obstack dependency_obstack
;
4651 obstack_begin (&dependency_obstack
, 4000);
4652 for (i
= 0; i
< sizeof (insn_to_dependency_table
) / sizeof (insn_to_dependency_table
[0]); i
++)
4654 const struct insn_to_dependency
*tmp
= insn_to_dependency_table
+ i
;
4655 unsigned len
= strlen (tmp
->insn_name
);
4656 struct insn_to_dependency
*new;
4658 new = obstack_alloc (&dependency_obstack
, sizeof (struct insn_to_dependency
));
4659 new->insn_name
= obstack_alloc (&dependency_obstack
, len
+ 1);
4661 strcpy (new->insn_name
, tmp
->insn_name
);
4662 new->type
= tmp
->type
;
4663 hash_insert (dependency_insn_hsh
, new->insn_name
, (void *) new);
4667 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
4668 for use in the a.out file, and stores them in the array pointed to by buf.
4669 This knows about the endian-ness of the target machine and does
4670 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
4671 2 (short) and 4 (long) Floating numbers are put out as a series of
4672 LITTLENUMS (shorts, here at least). */
4675 md_number_to_chars (char *buf
, valueT val
, int n
)
4677 if (target_big_endian
)
4678 number_to_chars_bigendian (buf
, val
, n
);
4680 number_to_chars_littleendian (buf
, val
, n
);
4684 md_chars_to_number (char *buf
, int n
)
4687 unsigned char *where
= (unsigned char *)buf
;
4689 if (target_big_endian
)
4694 result
|= (*where
++ & 255);
4702 result
|= (where
[n
] & 255);
4709 /* Turn a string in input_line_pointer into a floating point constant
4710 of type TYPE, and store the appropriate bytes in *LITP. The number
4711 of LITTLENUMS emitted is stored in *SIZEP. An error message is
4712 returned, or NULL on OK.
4714 Note that fp constants aren't represent in the normal way on the ARM.
4715 In big endian mode, things are as expected. However, in little endian
4716 mode fp constants are big-endian word-wise, and little-endian byte-wise
4717 within the words. For example, (double) 1.1 in big endian mode is
4718 the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
4719 the byte sequence 99 99 f1 3f 9a 99 99 99. */
4722 md_atof (int type
, char *litP
, int *sizeP
)
4725 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
4751 return _("bad call to MD_ATOF()");
4754 t
= atof_ieee (input_line_pointer
, type
, words
);
4756 input_line_pointer
= t
;
4759 if (target_big_endian
)
4761 for (i
= 0; i
< prec
; i
++)
4763 md_number_to_chars (litP
, (valueT
) words
[i
], 2);
4769 for (i
= 0; i
< prec
; i
+= 2)
4771 md_number_to_chars (litP
, (valueT
) words
[i
+ 1], 2);
4772 md_number_to_chars (litP
+ 2, (valueT
) words
[i
], 2);
4780 /* Return true if the given symbol should be considered local for PIC. */
4783 pic_need_relax (symbolS
*sym
, asection
*segtype
)
4786 bfd_boolean linkonce
;
4788 /* Handle the case of a symbol equated to another symbol. */
4789 while (symbol_equated_reloc_p (sym
))
4793 /* It's possible to get a loop here in a badly written
4795 n
= symbol_get_value_expression (sym
)->X_add_symbol
;
4801 symsec
= S_GET_SEGMENT (sym
);
4803 /* duplicate the test for LINK_ONCE sections as in adjust_reloc_syms */
4805 if (symsec
!= segtype
&& ! S_IS_LOCAL (sym
))
4807 if ((bfd_get_section_flags (stdoutput
, symsec
) & SEC_LINK_ONCE
) != 0)
4810 /* The GNU toolchain uses an extension for ELF: a section
4811 beginning with the magic string .gnu.linkonce is a linkonce
4813 if (strncmp (segment_name (symsec
), ".gnu.linkonce",
4814 sizeof ".gnu.linkonce" - 1) == 0)
4818 /* This must duplicate the test in adjust_reloc_syms. */
4819 return (symsec
!= &bfd_und_section
4820 && symsec
!= &bfd_abs_section
4821 && ! bfd_is_com_section (symsec
)
4824 /* A global or weak symbol is treated as external. */
4825 && (OUTPUT_FLAVOR
!= bfd_target_elf_flavour
4826 || (! S_IS_WEAK (sym
) && ! S_IS_EXTERNAL (sym
)))
4832 judge_size_before_relax (fragS
* fragp
, asection
*sec
)
4836 if (score_pic
== NO_PIC
)
4837 change
= nopic_need_relax (fragp
->fr_symbol
, 0);
4839 change
= pic_need_relax (fragp
->fr_symbol
, sec
);
4843 /* Only at the first time determining whether GP instruction relax should be done,
4844 return the difference between insntruction size and instruction relax size. */
4845 if (fragp
->fr_opcode
== NULL
)
4847 fragp
->fr_fix
= RELAX_NEW (fragp
->fr_subtype
);
4848 fragp
->fr_opcode
= fragp
->fr_literal
+ RELAX_RELOC1 (fragp
->fr_subtype
);
4849 return RELAX_NEW (fragp
->fr_subtype
) - RELAX_OLD (fragp
->fr_subtype
);
4856 /* In this function, we determine whether GP instruction should do relaxation,
4857 for the label being against was known now.
4858 Doing this here but not in md_relax_frag() can induce iteration times
4859 in stage of doing relax. */
4861 md_estimate_size_before_relax (fragS
* fragp
, asection
* sec ATTRIBUTE_UNUSED
)
4863 if ((RELAX_TYPE (fragp
->fr_subtype
) == Insn_GP
)
4864 || (RELAX_TYPE (fragp
->fr_subtype
) == Insn_PIC
))
4865 return judge_size_before_relax (fragp
, sec
);
4871 b32_relax_to_b16 (fragS
* fragp
)
4874 int relaxable_p
= 0;
4877 int frag_addr
= fragp
->fr_address
+ fragp
->insn_addr
;
4879 addressT symbol_address
= 0;
4882 unsigned long value
;
4883 unsigned long abs_value
;
4885 /* FIXME : here may be able to modify better .
4886 I don't know how to get the fragp's section ,
4887 so in relax stage , it may be wrong to calculate the symbol's offset when the frag's section
4888 is different from the symbol's. */
4890 old
= RELAX_OLD (fragp
->fr_subtype
);
4891 new = RELAX_NEW (fragp
->fr_subtype
);
4892 relaxable_p
= RELAX_OPT (fragp
->fr_subtype
);
4894 s
= fragp
->fr_symbol
;
4895 /* b/bl immediate */
4901 symbol_address
= (addressT
) s
->sy_frag
->fr_address
;
4904 value
= md_chars_to_number (fragp
->fr_literal
, INSN_SIZE
);
4906 /* b 32's offset : 20 bit, b 16's tolerate field : 0xff. */
4907 offset
= ((value
& 0x3ff0000) >> 6) | (value
& 0x3fe);
4908 if ((offset
& 0x80000) == 0x80000)
4909 offset
|= 0xfff00000;
4911 abs_value
= offset
+ symbol_address
- frag_addr
;
4912 if ((abs_value
& 0x80000000) == 0x80000000)
4913 abs_value
= 0xffffffff - abs_value
+ 1;
4915 /* Relax branch 32 to branch 16. */
4916 if (relaxable_p
&& (s
->bsym
!= NULL
) && ((abs_value
& 0xffffff00) == 0)
4917 && (S_IS_DEFINED (s
) && !S_IS_COMMON (s
) && !S_IS_EXTERNAL (s
)))
4923 /* Branch 32 can not be relaxed to b 16, so clear OPT bit. */
4924 fragp
->fr_opcode
= NULL
;
4925 fragp
->fr_subtype
= RELAX_OPT_CLEAR (fragp
->fr_subtype
);
4931 /* Main purpose is to determine whether one frag should do relax.
4932 frag->fr_opcode indicates this point. */
4935 score_relax_frag (asection
* sec ATTRIBUTE_UNUSED
, fragS
* fragp
, long stretch ATTRIBUTE_UNUSED
)
4939 int insn_relax_size
;
4940 int do_relax_p
= 0; /* Indicate doing relaxation for this frag. */
4941 int relaxable_p
= 0;
4942 bfd_boolean word_align_p
= FALSE
;
4945 /* If the instruction address is odd, make it half word align first. */
4946 if ((fragp
->fr_address
) % 2 != 0)
4948 if ((fragp
->fr_address
+ fragp
->insn_addr
) % 2 != 0)
4950 fragp
->insn_addr
= 1;
4955 word_align_p
= ((fragp
->fr_address
+ fragp
->insn_addr
) % 4 == 0) ? TRUE
: FALSE
;
4957 /* Get instruction size and relax size after the last relaxation. */
4958 if (fragp
->fr_opcode
)
4960 insn_size
= RELAX_NEW (fragp
->fr_subtype
);
4961 insn_relax_size
= RELAX_OLD (fragp
->fr_subtype
);
4965 insn_size
= RELAX_OLD (fragp
->fr_subtype
);
4966 insn_relax_size
= RELAX_NEW (fragp
->fr_subtype
);
4969 /* Handle specially for GP instruction. for, judge_size_before_relax() has already determine
4970 whether the GP instruction should do relax. */
4971 if ((RELAX_TYPE (fragp
->fr_subtype
) == Insn_GP
)
4972 || (RELAX_TYPE (fragp
->fr_subtype
) == Insn_PIC
))
4976 fragp
->insn_addr
+= 2;
4980 if (fragp
->fr_opcode
)
4981 fragp
->fr_fix
= RELAX_NEW (fragp
->fr_subtype
) + fragp
->insn_addr
;
4983 fragp
->fr_fix
= RELAX_OLD (fragp
->fr_subtype
) + fragp
->insn_addr
;
4987 if (RELAX_TYPE (fragp
->fr_subtype
) == PC_DISP19div2
)
4988 b32_relax_to_b16 (fragp
);
4990 relaxable_p
= RELAX_OPT (fragp
->fr_subtype
);
4991 next_fragp
= fragp
->fr_next
;
4992 while ((next_fragp
) && (next_fragp
->fr_type
!= rs_machine_dependent
))
4994 next_fragp
= next_fragp
->fr_next
;
5000 int n_relaxable_p
= 0;
5002 if (next_fragp
->fr_opcode
)
5004 n_insn_size
= RELAX_NEW (next_fragp
->fr_subtype
);
5008 n_insn_size
= RELAX_OLD (next_fragp
->fr_subtype
);
5011 n_relaxable_p
= RELAX_OPT (next_fragp
->fr_subtype
);
5018 if (relaxable_p
&& ((n_insn_size
== 2) || n_relaxable_p
))
5024 else if (insn_size
== 2)
5027 if (relaxable_p
&& ((n_insn_size
== 4) && !n_relaxable_p
))
5048 /* Make the 32 bit insturction word align. */
5051 fragp
->insn_addr
+= 2;
5055 else if (insn_size
== 2)
5067 /* Here, try best to do relax regardless fragp->fr_next->fr_type. */
5068 if (word_align_p
== FALSE
)
5070 if (insn_size
% 4 == 0)
5080 fragp
->insn_addr
+= 2;
5091 /* fragp->fr_opcode indicates whether this frag should be relaxed. */
5094 if (fragp
->fr_opcode
)
5096 fragp
->fr_opcode
= NULL
;
5097 /* Guarantee estimate stage is correct. */
5098 fragp
->fr_fix
= RELAX_OLD (fragp
->fr_subtype
);
5099 fragp
->fr_fix
+= fragp
->insn_addr
;
5103 fragp
->fr_opcode
= fragp
->fr_literal
+ RELAX_RELOC1 (fragp
->fr_subtype
);
5104 /* Guarantee estimate stage is correct. */
5105 fragp
->fr_fix
= RELAX_NEW (fragp
->fr_subtype
);
5106 fragp
->fr_fix
+= fragp
->insn_addr
;
5111 if (fragp
->fr_opcode
)
5113 /* Guarantee estimate stage is correct. */
5114 fragp
->fr_fix
= RELAX_NEW (fragp
->fr_subtype
);
5115 fragp
->fr_fix
+= fragp
->insn_addr
;
5119 /* Guarantee estimate stage is correct. */
5120 fragp
->fr_fix
= RELAX_OLD (fragp
->fr_subtype
);
5121 fragp
->fr_fix
+= fragp
->insn_addr
;
5130 md_convert_frag (bfd
* abfd ATTRIBUTE_UNUSED
, segT sec ATTRIBUTE_UNUSED
, fragS
* fragp
)
5137 old
= RELAX_OLD (fragp
->fr_subtype
);
5138 new = RELAX_NEW (fragp
->fr_subtype
);
5140 /* fragp->fr_opcode indicates whether this frag should be relaxed. */
5141 if (fragp
->fr_opcode
== NULL
)
5143 memcpy (backup
, fragp
->fr_literal
, old
);
5144 fragp
->fr_fix
= old
;
5148 memcpy (backup
, fragp
->fr_literal
+ old
, new);
5149 fragp
->fr_fix
= new;
5152 fixp
= fragp
->tc_frag_data
.fixp
;
5153 while (fixp
&& fixp
->fx_frag
== fragp
&& fixp
->fx_where
< old
)
5155 if (fragp
->fr_opcode
)
5157 fixp
= fixp
->fx_next
;
5159 while (fixp
&& fixp
->fx_frag
== fragp
)
5161 if (fragp
->fr_opcode
)
5162 fixp
->fx_where
-= old
+ fragp
->insn_addr
;
5165 fixp
= fixp
->fx_next
;
5168 if (fragp
->insn_addr
)
5170 md_number_to_chars (fragp
->fr_literal
, 0x0, fragp
->insn_addr
);
5172 memcpy (fragp
->fr_literal
+ fragp
->insn_addr
, backup
, fragp
->fr_fix
);
5173 fragp
->fr_fix
+= fragp
->insn_addr
;
5176 /* Implementation of md_frag_check.
5177 Called after md_convert_frag(). */
5180 score_frag_check (fragS
* fragp ATTRIBUTE_UNUSED
)
5182 know (fragp
->insn_addr
<= RELAX_PAD_BYTE
);
5186 score_fix_adjustable (fixS
* fixP
)
5188 if (fixP
->fx_addsy
== NULL
)
5192 else if (OUTPUT_FLAVOR
== bfd_target_elf_flavour
5193 && (S_IS_EXTERNAL (fixP
->fx_addsy
) || S_IS_WEAK (fixP
->fx_addsy
)))
5197 else if (fixP
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
5198 || fixP
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
5206 /* Implementation of TC_VALIDATE_FIX.
5207 Called before md_apply_fix() and after md_convert_frag(). */
5209 score_validate_fix (fixS
*fixP
)
5211 fixP
->fx_where
+= fixP
->fx_frag
->insn_addr
;
5215 md_pcrel_from (fixS
* fixP
)
5220 && (S_GET_SEGMENT (fixP
->fx_addsy
) == undefined_section
)
5221 && (fixP
->fx_subsy
== NULL
))
5227 retval
= fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
5234 score_force_relocation (struct fix
*fixp
)
5238 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
5239 || fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
5240 || fixp
->fx_r_type
== BFD_RELOC_SCORE_JMP
5241 || fixp
->fx_r_type
== BFD_RELOC_SCORE_BRANCH
5242 || fixp
->fx_r_type
== BFD_RELOC_SCORE16_JMP
5243 || fixp
->fx_r_type
== BFD_RELOC_SCORE16_BRANCH
)
5251 /* Round up a section size to the appropriate boundary. */
5253 md_section_align (segT segment ATTRIBUTE_UNUSED
, valueT size
)
5255 int align
= bfd_get_section_alignment (stdoutput
, segment
);
5258 /* We don't need to align ELF sections to the full alignment.
5259 However, Irix 5 may prefer that we align them at least to a 16
5260 byte boundary. We don't bother to align the sections if we are
5261 targeted for an embedded system. */
5262 if (strcmp (TARGET_OS
, "elf") == 0)
5268 return ((size
+ (1 << align
) - 1) & (-1 << align
));
5272 md_apply_fix (fixS
*fixP
, valueT
*valP
, segT seg
)
5274 offsetT value
= *valP
;
5275 offsetT abs_value
= 0;
5278 unsigned short HI
, LO
;
5280 char *buf
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
5282 assert (fixP
->fx_r_type
< BFD_RELOC_UNUSED
);
5283 if (fixP
->fx_addsy
== 0 && !fixP
->fx_pcrel
)
5285 if (fixP
->fx_r_type
!= BFD_RELOC_SCORE_DUMMY_HI16
)
5289 /* If this symbol is in a different section then we need to leave it for
5290 the linker to deal with. Unfortunately, md_pcrel_from can't tell,
5291 so we have to undo it's effects here. */
5294 if (fixP
->fx_addsy
!= NULL
5295 && S_IS_DEFINED (fixP
->fx_addsy
)
5296 && S_GET_SEGMENT (fixP
->fx_addsy
) != seg
)
5297 value
+= md_pcrel_from (fixP
);
5300 /* Remember value for emit_reloc. */
5301 fixP
->fx_addnumber
= value
;
5303 switch (fixP
->fx_r_type
)
5305 case BFD_RELOC_HI16_S
:
5307 { /* For la rd, imm32. */
5308 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5309 HI
= (value
) >> 16; /* mul to 2, then take the hi 16 bit. */
5310 newval
|= (HI
& 0x3fff) << 1;
5311 newval
|= ((HI
>> 14) & 0x3) << 16;
5312 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5315 case BFD_RELOC_LO16
:
5316 if (fixP
->fx_done
) /* For la rd, imm32. */
5318 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5319 LO
= (value
) & 0xffff;
5320 newval
|= (LO
& 0x3fff) << 1; /* 16 bit: imm -> 14 bit in lo, 2 bit in hi. */
5321 newval
|= ((LO
>> 14) & 0x3) << 16;
5322 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5325 case BFD_RELOC_SCORE_JMP
:
5327 content
= md_chars_to_number (buf
, INSN_SIZE
);
5328 value
= fixP
->fx_offset
;
5329 content
= (content
& ~0x3ff7ffe) | ((value
<< 1) & 0x3ff0000) | (value
& 0x7fff);
5330 md_number_to_chars (buf
, content
, INSN_SIZE
);
5333 case BFD_RELOC_SCORE_BRANCH
:
5334 if ((S_GET_SEGMENT (fixP
->fx_addsy
) != seg
) || (fixP
->fx_addsy
!= NULL
&& S_IS_EXTERNAL (fixP
->fx_addsy
)))
5335 value
= fixP
->fx_offset
;
5339 content
= md_chars_to_number (buf
, INSN_SIZE
);
5340 if ((fixP
->fx_frag
->fr_opcode
!= 0) && ((content
& 0x80008000) != 0x80008000))
5342 if ((value
& 0x80000000) == 0x80000000)
5343 abs_value
= 0xffffffff - value
+ 1;
5344 if ((abs_value
& 0xffffff00) != 0)
5346 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5347 _(" branch relocation truncate (0x%x) [-2^8 ~ 2^8]"), (unsigned int)value
);
5350 content
= md_chars_to_number (buf
, INSN16_SIZE
);
5352 content
= (content
& 0xff00) | ((value
>> 1) & 0xff);
5353 md_number_to_chars (buf
, content
, INSN16_SIZE
);
5354 fixP
->fx_r_type
= BFD_RELOC_SCORE16_BRANCH
;
5359 if ((value
& 0x80000000) == 0x80000000)
5360 abs_value
= 0xffffffff - value
+ 1;
5361 if ((abs_value
& 0xfff80000) != 0)
5363 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5364 _(" branch relocation truncate (0x%x) [-2^19 ~ 2^19]"), (unsigned int)value
);
5367 content
= md_chars_to_number (buf
, INSN_SIZE
);
5368 content
&= 0xfc00fc01;
5369 content
= (content
& 0xfc00fc01) | (value
& 0x3fe) | ((value
<< 6) & 0x3ff0000);
5370 md_number_to_chars (buf
, content
, INSN_SIZE
);
5373 case BFD_RELOC_SCORE16_JMP
:
5374 content
= md_chars_to_number (buf
, INSN16_SIZE
);
5376 value
= fixP
->fx_offset
& 0xfff;
5377 content
= (content
& 0xfc01) | (value
& 0xffe);
5378 md_number_to_chars (buf
, content
, INSN16_SIZE
);
5380 case BFD_RELOC_SCORE16_BRANCH
:
5381 content
= md_chars_to_number (buf
, INSN_SIZE
);
5382 if ((fixP
->fx_frag
->fr_opcode
!= 0) && ((content
& 0x80008000) == 0x80008000))
5384 if ((S_GET_SEGMENT (fixP
->fx_addsy
) != seg
) ||
5385 (fixP
->fx_addsy
!= NULL
&& S_IS_EXTERNAL (fixP
->fx_addsy
)))
5386 value
= fixP
->fx_offset
;
5389 if ((value
& 0x80000000) == 0x80000000)
5390 abs_value
= 0xffffffff - value
+ 1;
5391 if ((abs_value
& 0xfff80000) != 0)
5393 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5394 _(" branch relocation truncate (0x%x) [-2^19 ~ 2^19]"), (unsigned int)value
);
5397 content
= md_chars_to_number (buf
, INSN_SIZE
);
5398 content
= (content
& 0xfc00fc01) | (value
& 0x3fe) | ((value
<< 6) & 0x3ff0000);
5399 md_number_to_chars (buf
, content
, INSN_SIZE
);
5400 fixP
->fx_r_type
= BFD_RELOC_SCORE_BRANCH
;
5406 /* In differnt section. */
5407 if ((S_GET_SEGMENT (fixP
->fx_addsy
) != seg
) ||
5408 (fixP
->fx_addsy
!= NULL
&& S_IS_EXTERNAL (fixP
->fx_addsy
)))
5409 value
= fixP
->fx_offset
;
5413 if ((value
& 0x80000000) == 0x80000000)
5414 abs_value
= 0xffffffff - value
+ 1;
5415 if ((abs_value
& 0xffffff00) != 0)
5417 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5418 _(" branch relocation truncate (0x%x) [-2^8 ~ 2^8]"), (unsigned int)value
);
5421 content
= md_chars_to_number (buf
, INSN16_SIZE
);
5422 content
= (content
& 0xff00) | ((value
>> 1) & 0xff);
5423 md_number_to_chars (buf
, content
, INSN16_SIZE
);
5427 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5428 md_number_to_chars (buf
, value
, 1);
5432 value
= fixP
->fx_offset
;
5433 md_number_to_chars (buf
, value
, 1);
5439 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5440 md_number_to_chars (buf
, value
, 2);
5444 value
= fixP
->fx_offset
;
5445 md_number_to_chars (buf
, value
, 2);
5451 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5452 md_number_to_chars (buf
, value
, 4);
5456 value
= fixP
->fx_offset
;
5457 md_number_to_chars (buf
, value
, 4);
5461 case BFD_RELOC_VTABLE_INHERIT
:
5463 if (fixP
->fx_addsy
&& !S_IS_DEFINED (fixP
->fx_addsy
) && !S_IS_WEAK (fixP
->fx_addsy
))
5464 S_SET_WEAK (fixP
->fx_addsy
);
5466 case BFD_RELOC_VTABLE_ENTRY
:
5469 case BFD_RELOC_SCORE_GPREL15
:
5470 content
= md_chars_to_number (buf
, INSN_SIZE
);
5471 if ((fixP
->fx_frag
->fr_opcode
!= 0) && ((content
& 0xfc1c8000) != 0x94188000))
5472 fixP
->fx_r_type
= BFD_RELOC_NONE
;
5475 case BFD_RELOC_SCORE_GOT15
:
5476 case BFD_RELOC_SCORE_DUMMY_HI16
:
5477 case BFD_RELOC_SCORE_GOT_LO16
:
5478 case BFD_RELOC_SCORE_CALL15
:
5479 case BFD_RELOC_GPREL32
:
5481 case BFD_RELOC_NONE
:
5483 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("bad relocation fixup type (%d)"), fixP
->fx_r_type
);
5487 /* Translate internal representation of relocation info to BFD target format. */
5489 tc_gen_reloc (asection
* section ATTRIBUTE_UNUSED
, fixS
* fixp
)
5491 static arelent
*retval
[MAX_RELOC_EXPANSION
+ 1]; /* MAX_RELOC_EXPANSION equals 2. */
5493 bfd_reloc_code_real_type code
;
5499 reloc
= retval
[0] = xmalloc (sizeof (arelent
));
5502 reloc
->sym_ptr_ptr
= xmalloc (sizeof (asymbol
*));
5503 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
5504 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
5505 reloc
->addend
= fixp
->fx_offset
;
5507 /* If this is a variant frag, we may need to adjust the existing
5508 reloc and generate a new one. */
5509 if (fixp
->fx_frag
->fr_opcode
!= NULL
&& (fixp
->fx_r_type
== BFD_RELOC_SCORE_GPREL15
))
5511 /* Update instruction imm bit. */
5516 buf
= fixp
->fx_frag
->fr_literal
+ fixp
->fx_frag
->insn_addr
;
5517 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5518 off
= fixp
->fx_offset
>> 16;
5519 newval
|= (off
& 0x3fff) << 1;
5520 newval
|= ((off
>> 14) & 0x3) << 16;
5521 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5524 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5525 off
= fixp
->fx_offset
& 0xffff;
5526 newval
|= ((off
& 0x3fff) << 1);
5527 newval
|= (((off
>> 14) & 0x3) << 16);
5528 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5530 retval
[1] = xmalloc (sizeof (arelent
));
5532 retval
[1]->sym_ptr_ptr
= xmalloc (sizeof (asymbol
*));
5533 *retval
[1]->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
5534 retval
[1]->address
= (reloc
->address
+ RELAX_RELOC2 (fixp
->fx_frag
->fr_subtype
));
5540 retval
[1]->addend
= 0;
5541 retval
[1]->howto
= bfd_reloc_type_lookup (stdoutput
, BFD_RELOC_LO16
);
5542 assert (retval
[1]->howto
!= NULL
);
5544 fixp
->fx_r_type
= BFD_RELOC_HI16_S
;
5547 code
= fixp
->fx_r_type
;
5548 switch (fixp
->fx_r_type
)
5553 code
= BFD_RELOC_32_PCREL
;
5556 case BFD_RELOC_HI16_S
:
5557 case BFD_RELOC_LO16
:
5558 case BFD_RELOC_SCORE_JMP
:
5559 case BFD_RELOC_SCORE_BRANCH
:
5560 case BFD_RELOC_SCORE16_JMP
:
5561 case BFD_RELOC_SCORE16_BRANCH
:
5562 case BFD_RELOC_VTABLE_ENTRY
:
5563 case BFD_RELOC_VTABLE_INHERIT
:
5564 case BFD_RELOC_SCORE_GPREL15
:
5565 case BFD_RELOC_SCORE_GOT15
:
5566 case BFD_RELOC_SCORE_DUMMY_HI16
:
5567 case BFD_RELOC_SCORE_GOT_LO16
:
5568 case BFD_RELOC_SCORE_CALL15
:
5569 case BFD_RELOC_GPREL32
:
5570 case BFD_RELOC_NONE
:
5571 code
= fixp
->fx_r_type
;
5574 type
= _("<unknown>");
5575 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5576 _("cannot represent %s relocation in this object file format"), type
);
5580 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
5581 if (reloc
->howto
== NULL
)
5583 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5584 _("cannot represent %s relocation in this object file format1"),
5585 bfd_get_reloc_code_name (code
));
5588 /* HACK: Since arm ELF uses Rel instead of Rela, encode the
5589 vtable entry to be used in the relocation's section offset. */
5590 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
5591 reloc
->address
= fixp
->fx_offset
;
5597 score_elf_final_processing (void)
5599 if (fix_data_dependency
== 1)
5601 elf_elfheader (stdoutput
)->e_flags
|= EF_SCORE_FIXDEP
;
5603 if (score_pic
== PIC
)
5605 elf_elfheader (stdoutput
)->e_flags
|= EF_SCORE_PIC
;
5610 parse_pce_inst (char *insnstr
)
5614 char first
[MAX_LITERAL_POOL_SIZE
];
5615 char second
[MAX_LITERAL_POOL_SIZE
];
5616 struct score_it pec_part_1
;
5618 /* Get first part string of PCE. */
5619 p
= strstr (insnstr
, "||");
5622 sprintf (first
, "%s", insnstr
);
5624 /* Get second part string of PCE. */
5627 sprintf (second
, "%s", p
);
5629 parse_16_32_inst (first
, FALSE
);
5633 memcpy (&pec_part_1
, &inst
, sizeof (inst
));
5635 parse_16_32_inst (second
, FALSE
);
5639 if ( ((pec_part_1
.size
== INSN_SIZE
) && (inst
.size
== INSN_SIZE
))
5640 || ((pec_part_1
.size
== INSN_SIZE
) && (inst
.size
== INSN16_SIZE
))
5641 || ((pec_part_1
.size
== INSN16_SIZE
) && (inst
.size
== INSN_SIZE
)))
5643 inst
.error
= _("pce instruction error (16 bit || 16 bit)'");
5644 sprintf (inst
.str
, "%s", insnstr
);
5649 gen_insn_frag (&pec_part_1
, &inst
);
5653 md_assemble (char *str
)
5656 know (strlen (str
) < MAX_LITERAL_POOL_SIZE
);
5658 memset (&inst
, '\0', sizeof (inst
));
5659 if (INSN_IS_PCE_P (str
))
5660 parse_pce_inst (str
);
5662 parse_16_32_inst (str
, TRUE
);
5665 as_bad ("%s -- `%s'", inst
.error
, inst
.str
);
5668 /* We handle all bad expressions here, so that we can report the faulty
5669 instruction in the error message. */
5671 md_operand (expressionS
* expr
)
5673 if (in_my_get_expression
)
5675 expr
->X_op
= O_illegal
;
5676 if (inst
.error
== NULL
)
5678 inst
.error
= _("bad expression");
5683 const char *md_shortopts
= "nO::g::G:";
5685 #ifdef SCORE_BI_ENDIAN
5686 #define OPTION_EB (OPTION_MD_BASE + 0)
5687 #define OPTION_EL (OPTION_MD_BASE + 1)
5689 #if TARGET_BYTES_BIG_ENDIAN
5690 #define OPTION_EB (OPTION_MD_BASE + 0)
5692 #define OPTION_EL (OPTION_MD_BASE + 1)
5695 #define OPTION_FIXDD (OPTION_MD_BASE + 2)
5696 #define OPTION_NWARN (OPTION_MD_BASE + 3)
5697 #define OPTION_SCORE5 (OPTION_MD_BASE + 4)
5698 #define OPTION_SCORE5U (OPTION_MD_BASE + 5)
5699 #define OPTION_SCORE7 (OPTION_MD_BASE + 6)
5700 #define OPTION_R1 (OPTION_MD_BASE + 7)
5701 #define OPTION_O0 (OPTION_MD_BASE + 8)
5702 #define OPTION_SCORE_VERSION (OPTION_MD_BASE + 9)
5703 #define OPTION_PIC (OPTION_MD_BASE + 10)
5705 struct option md_longopts
[] =
5708 {"EB" , no_argument
, NULL
, OPTION_EB
},
5711 {"EL" , no_argument
, NULL
, OPTION_EL
},
5713 {"FIXDD" , no_argument
, NULL
, OPTION_FIXDD
},
5714 {"NWARN" , no_argument
, NULL
, OPTION_NWARN
},
5715 {"SCORE5" , no_argument
, NULL
, OPTION_SCORE5
},
5716 {"SCORE5U", no_argument
, NULL
, OPTION_SCORE5U
},
5717 {"SCORE7" , no_argument
, NULL
, OPTION_SCORE7
},
5718 {"USE_R1" , no_argument
, NULL
, OPTION_R1
},
5719 {"O0" , no_argument
, NULL
, OPTION_O0
},
5720 {"V" , no_argument
, NULL
, OPTION_SCORE_VERSION
},
5721 {"KPIC" , no_argument
, NULL
, OPTION_PIC
},
5722 {NULL
, no_argument
, NULL
, 0}
5725 size_t md_longopts_size
= sizeof (md_longopts
);
5728 md_parse_option (int c
, char *arg
)
5734 target_big_endian
= 1;
5739 target_big_endian
= 0;
5743 fix_data_dependency
= 1;
5746 warn_fix_data_dependency
= 0;
5750 university_version
= 0;
5751 vector_size
= SCORE5_PIPELINE
;
5753 case OPTION_SCORE5U
:
5755 university_version
= 1;
5756 vector_size
= SCORE5_PIPELINE
;
5760 university_version
= 0;
5761 vector_size
= SCORE7_PIPELINE
;
5767 g_switch_value
= atoi (arg
);
5772 case OPTION_SCORE_VERSION
:
5773 printf (_("Sunplus-v2-0-0-20060510\n"));
5777 g_switch_value
= 0; /* Must set -G num as 0 to generate PIC code. */
5780 /* as_bad (_("unrecognized option `-%c%s'"), c, arg ? arg : ""); */
5787 md_show_usage (FILE * fp
)
5789 fprintf (fp
, _(" Score-specific assembler options:\n"));
5792 -EB\t\tassemble code for a big-endian cpu\n"));
5797 -EL\t\tassemble code for a little-endian cpu\n"));
5801 -FIXDD\t\tassemble code for fix data dependency\n"));
5803 -NWARN\t\tassemble code for no warning message for fix data dependency\n"));
5805 -SCORE5\t\tassemble code for target is SCORE5\n"));
5807 -SCORE5U\tassemble code for target is SCORE5U\n"));
5809 -SCORE7\t\tassemble code for target is SCORE7, this is default setting\n"));
5811 -USE_R1\t\tassemble code for no warning message when using temp register r1\n"));
5813 -KPIC\t\tassemble code for PIC\n"));
5815 -O0\t\tassembler will not perform any optimizations\n"));
5817 -G gpnum\tassemble code for setting gpsize and default is 8 byte\n"));
5819 -V \t\tSunplus release version \n"));
5823 /* Pesudo handling functions. */
5825 /* If we change section we must dump the literal pool first. */
5827 s_score_bss (int ignore ATTRIBUTE_UNUSED
)
5829 subseg_set (bss_section
, (subsegT
) get_absolute_expression ());
5830 demand_empty_rest_of_line ();
5834 s_score_text (int ignore
)
5836 obj_elf_text (ignore
);
5837 record_alignment (now_seg
, 2);
5841 score_s_section (int ignore
)
5843 obj_elf_section (ignore
);
5844 if ((bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
) != 0)
5845 record_alignment (now_seg
, 2);
5850 s_change_sec (int sec
)
5855 /* The ELF backend needs to know that we are changing sections, so
5856 that .previous works correctly. We could do something like check
5857 for an obj_section_change_hook macro, but that might be confusing
5858 as it would not be appropriate to use it in the section changing
5859 functions in read.c, since obj-elf.c intercepts those. FIXME:
5860 This should be cleaner, somehow. */
5861 obj_elf_section_change_hook ();
5866 seg
= subseg_new (RDATA_SECTION_NAME
, (subsegT
) get_absolute_expression ());
5867 bfd_set_section_flags (stdoutput
, seg
, (SEC_ALLOC
| SEC_LOAD
| SEC_READONLY
| SEC_RELOC
| SEC_DATA
));
5868 if (strcmp (TARGET_OS
, "elf") != 0)
5869 record_alignment (seg
, 4);
5870 demand_empty_rest_of_line ();
5873 seg
= subseg_new (".sdata", (subsegT
) get_absolute_expression ());
5874 bfd_set_section_flags (stdoutput
, seg
, SEC_ALLOC
| SEC_LOAD
| SEC_RELOC
| SEC_DATA
);
5875 if (strcmp (TARGET_OS
, "elf") != 0)
5876 record_alignment (seg
, 4);
5877 demand_empty_rest_of_line ();
5883 s_score_mask (int reg_type ATTRIBUTE_UNUSED
)
5887 if (cur_proc_ptr
== (procS
*) NULL
)
5889 as_warn (_(".mask outside of .ent"));
5890 demand_empty_rest_of_line ();
5893 if (get_absolute_expression_and_terminator (&mask
) != ',')
5895 as_warn (_("Bad .mask directive"));
5896 --input_line_pointer
;
5897 demand_empty_rest_of_line ();
5900 off
= get_absolute_expression ();
5901 cur_proc_ptr
->reg_mask
= mask
;
5902 cur_proc_ptr
->reg_offset
= off
;
5903 demand_empty_rest_of_line ();
5913 name
= input_line_pointer
;
5914 c
= get_symbol_end ();
5915 p
= (symbolS
*) symbol_find_or_make (name
);
5916 *input_line_pointer
= c
;
5926 if (*input_line_pointer
== '-')
5928 ++input_line_pointer
;
5931 if (!ISDIGIT (*input_line_pointer
))
5932 as_bad (_("expected simple number"));
5933 if (input_line_pointer
[0] == '0')
5935 if (input_line_pointer
[1] == 'x')
5937 input_line_pointer
+= 2;
5938 while (ISXDIGIT (*input_line_pointer
))
5941 val
|= hex_value (*input_line_pointer
++);
5943 return negative
? -val
: val
;
5947 ++input_line_pointer
;
5948 while (ISDIGIT (*input_line_pointer
))
5951 val
|= *input_line_pointer
++ - '0';
5953 return negative
? -val
: val
;
5956 if (!ISDIGIT (*input_line_pointer
))
5958 printf (_(" *input_line_pointer == '%c' 0x%02x\n"), *input_line_pointer
, *input_line_pointer
);
5959 as_warn (_("invalid number"));
5962 while (ISDIGIT (*input_line_pointer
))
5965 val
+= *input_line_pointer
++ - '0';
5967 return negative
? -val
: val
;
5970 /* The .aent and .ent directives. */
5973 s_score_ent (int aent
)
5978 symbolP
= get_symbol ();
5979 if (*input_line_pointer
== ',')
5980 ++input_line_pointer
;
5982 if (ISDIGIT (*input_line_pointer
) || *input_line_pointer
== '-')
5985 #ifdef BFD_ASSEMBLER
5986 if ((bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
) != 0)
5991 if (now_seg
!= data_section
&& now_seg
!= bss_section
)
5997 as_warn (_(".ent or .aent not in text section."));
5998 if (!aent
&& cur_proc_ptr
)
5999 as_warn (_("missing .end"));
6002 cur_proc_ptr
= &cur_proc
;
6003 cur_proc_ptr
->reg_mask
= 0xdeadbeaf;
6004 cur_proc_ptr
->reg_offset
= 0xdeadbeaf;
6005 cur_proc_ptr
->fpreg_mask
= 0xdeafbeaf;
6006 cur_proc_ptr
->leaf
= 0xdeafbeaf;
6007 cur_proc_ptr
->frame_offset
= 0xdeafbeaf;
6008 cur_proc_ptr
->frame_reg
= 0xdeafbeaf;
6009 cur_proc_ptr
->pc_reg
= 0xdeafbeaf;
6010 cur_proc_ptr
->isym
= symbolP
;
6011 symbol_get_bfdsym (symbolP
)->flags
|= BSF_FUNCTION
;
6013 if (debug_type
== DEBUG_STABS
)
6014 stabs_generate_asm_func (S_GET_NAME (symbolP
), S_GET_NAME (symbolP
));
6016 demand_empty_rest_of_line ();
6020 s_score_frame (int ignore ATTRIBUTE_UNUSED
)
6027 backupstr
= input_line_pointer
;
6030 if (cur_proc_ptr
== (procS
*) NULL
)
6032 as_warn (_(".frame outside of .ent"));
6033 demand_empty_rest_of_line ();
6036 cur_proc_ptr
->frame_reg
= reg_required_here ((&backupstr
), 0, REG_TYPE_SCORE
);
6038 skip_past_comma (&backupstr
);
6039 while (*backupstr
!= ',')
6041 str
[i
] = *backupstr
;
6049 skip_past_comma (&backupstr
);
6050 cur_proc_ptr
->frame_offset
= val
;
6051 cur_proc_ptr
->pc_reg
= reg_required_here ((&backupstr
), 0, REG_TYPE_SCORE
);
6054 skip_past_comma (&backupstr
);
6056 while (*backupstr
!= '\n')
6058 str
[i
] = *backupstr
;
6064 cur_proc_ptr
->leaf
= val
;
6066 skip_past_comma (&backupstr
);
6068 #endif /* OBJ_ELF */
6069 while (input_line_pointer
!= backupstr
)
6070 input_line_pointer
++;
6073 /* The .end directive. */
6075 s_score_end (int x ATTRIBUTE_UNUSED
)
6080 /* Generate a .pdr section. */
6081 segT saved_seg
= now_seg
;
6082 subsegT saved_subseg
= now_subseg
;
6087 if (!is_end_of_line
[(unsigned char)*input_line_pointer
])
6090 demand_empty_rest_of_line ();
6095 #ifdef BFD_ASSEMBLER
6096 if ((bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
) != 0)
6101 if (now_seg
!= data_section
&& now_seg
!= bss_section
)
6108 as_warn (_(".end not in text section"));
6111 as_warn (_(".end directive without a preceding .ent directive."));
6112 demand_empty_rest_of_line ();
6117 assert (S_GET_NAME (p
));
6118 if (strcmp (S_GET_NAME (p
), S_GET_NAME (cur_proc_ptr
->isym
)))
6119 as_warn (_(".end symbol does not match .ent symbol."));
6120 if (debug_type
== DEBUG_STABS
)
6121 stabs_generate_asm_endfunc (S_GET_NAME (p
), S_GET_NAME (p
));
6124 as_warn (_(".end directive missing or unknown symbol"));
6126 if ((cur_proc_ptr
->reg_mask
== 0xdeadbeaf) ||
6127 (cur_proc_ptr
->reg_offset
== 0xdeadbeaf) ||
6128 (cur_proc_ptr
->leaf
== 0xdeafbeaf) ||
6129 (cur_proc_ptr
->frame_offset
== 0xdeafbeaf) ||
6130 (cur_proc_ptr
->frame_reg
== 0xdeafbeaf) || (cur_proc_ptr
->pc_reg
== 0xdeafbeaf));
6134 dot
= frag_now_fix ();
6136 subseg_set (pdr_seg
, 0);
6137 /* Write the symbol. */
6138 exp
.X_op
= O_symbol
;
6139 exp
.X_add_symbol
= p
;
6140 exp
.X_add_number
= 0;
6141 emit_expr (&exp
, 4);
6142 fragp
= frag_more (7 * 4);
6143 md_number_to_chars (fragp
, (valueT
) cur_proc_ptr
->reg_mask
, 4);
6144 md_number_to_chars (fragp
+ 4, (valueT
) cur_proc_ptr
->reg_offset
, 4);
6145 md_number_to_chars (fragp
+ 8, (valueT
) cur_proc_ptr
->fpreg_mask
, 4);
6146 md_number_to_chars (fragp
+ 12, (valueT
) cur_proc_ptr
->leaf
, 4);
6147 md_number_to_chars (fragp
+ 16, (valueT
) cur_proc_ptr
->frame_offset
, 4);
6148 md_number_to_chars (fragp
+ 20, (valueT
) cur_proc_ptr
->frame_reg
, 4);
6149 md_number_to_chars (fragp
+ 24, (valueT
) cur_proc_ptr
->pc_reg
, 4);
6150 subseg_set (saved_seg
, saved_subseg
);
6153 cur_proc_ptr
= NULL
;
6156 /* Handle the .set pseudo-op. */
6158 s_score_set (int x ATTRIBUTE_UNUSED
)
6161 char name
[MAX_LITERAL_POOL_SIZE
];
6162 char * orig_ilp
= input_line_pointer
;
6164 while (!is_end_of_line
[(unsigned char)*input_line_pointer
])
6166 name
[i
] = (char) * input_line_pointer
;
6168 ++input_line_pointer
;
6173 if (strcmp (name
, "nwarn") == 0)
6175 warn_fix_data_dependency
= 0;
6177 else if (strcmp (name
, "fixdd") == 0)
6179 fix_data_dependency
= 1;
6181 else if (strcmp (name
, "nofixdd") == 0)
6183 fix_data_dependency
= 0;
6185 else if (strcmp (name
, "r1") == 0)
6189 else if (strcmp (name
, "nor1") == 0)
6193 else if (strcmp (name
, "optimize") == 0)
6197 else if (strcmp (name
, "volatile") == 0)
6201 else if (strcmp (name
, "pic") == 0)
6207 input_line_pointer
= orig_ilp
;
6212 /* Handle the .cpload pseudo-op. This is used when generating PIC code. It sets the
6213 $gp register for the function based on the function address, which is in the register
6214 named in the argument. This uses a relocation against GP_DISP_LABEL, which is handled
6215 specially by the linker. The result is:
6216 ldis gp, %hi(GP_DISP_LABEL)
6217 ori gp, %low(GP_DISP_LABEL)
6218 add gp, gp, .cpload argument
6219 The .cpload argument is normally r29. */
6222 s_score_cpload (int ignore ATTRIBUTE_UNUSED
)
6225 char insn_str
[MAX_LITERAL_POOL_SIZE
];
6227 /* If we are not generating PIC code, .cpload is ignored. */
6228 if (score_pic
== NO_PIC
)
6234 if ((reg
= reg_required_here (&input_line_pointer
, -1, REG_TYPE_SCORE
)) == (int) FAIL
)
6237 demand_empty_rest_of_line ();
6239 sprintf (insn_str
, "ld_i32hi r%d, %s", GP
, GP_DISP_LABEL
);
6240 if (append_insn (insn_str
, TRUE
) == (int) FAIL
)
6243 sprintf (insn_str
, "ld_i32lo r%d, %s", GP
, GP_DISP_LABEL
);
6244 if (append_insn (insn_str
, TRUE
) == (int) FAIL
)
6247 sprintf (insn_str
, "add r%d, r%d, r%d", GP
, GP
, reg
);
6248 if (append_insn (insn_str
, TRUE
) == (int) FAIL
)
6252 /* Handle the .cprestore pseudo-op. This stores $gp into a given
6253 offset from $sp. The offset is remembered, and after making a PIC
6254 call $gp is restored from that location. */
6257 s_score_cprestore (int ignore ATTRIBUTE_UNUSED
)
6259 #define SCORE_BP_REG 2
6260 int cprestore_offset
;
6261 char insn_str
[MAX_LITERAL_POOL_SIZE
];
6263 /* If we are not generating PIC code, .cprestore is ignored. */
6264 if (score_pic
== NO_PIC
)
6270 cprestore_offset
= get_absolute_expression ();
6272 sprintf (insn_str
, "sw r%d, [r%d, %d]", GP
, SCORE_BP_REG
, cprestore_offset
);
6273 if (append_insn (insn_str
, TRUE
) == (int) FAIL
)
6277 /* Handle the .gpword pseudo-op. This is used when generating PIC
6278 code. It generates a 32 bit GP relative reloc. */
6280 s_score_gpword (int ignore ATTRIBUTE_UNUSED
)
6285 /* When not generating PIC code, this is treated as .word. */
6286 if (score_pic
== NO_PIC
)
6292 if (ex
.X_op
!= O_symbol
|| ex
.X_add_number
!= 0)
6294 as_bad (_("Unsupported use of .gpword"));
6295 ignore_rest_of_line ();
6298 md_number_to_chars (p
, (valueT
) 0, 4);
6299 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 4, &ex
, FALSE
, BFD_RELOC_GPREL32
);
6300 demand_empty_rest_of_line ();
6303 /* Handle the .cpadd pseudo-op. This is used when dealing with switch
6304 tables in PIC code. */
6307 s_score_cpadd (int ignore ATTRIBUTE_UNUSED
)
6310 char insn_str
[MAX_LITERAL_POOL_SIZE
];
6312 /* If we are not generating PIC code, .cpload is ignored. */
6313 if (score_pic
== NO_PIC
)
6319 if ((reg
= reg_required_here (&input_line_pointer
, -1, REG_TYPE_SCORE
)) == (int) FAIL
)
6323 demand_empty_rest_of_line ();
6325 /* Add $gp to the register named as an argument. */
6326 sprintf (insn_str
, "add r%d, r%d, r%d", reg
, reg
, GP
);
6327 if (append_insn (insn_str
, TRUE
) == (int) FAIL
)
6331 #ifndef TC_IMPLICIT_LCOMM_ALIGNMENT
6332 #define TC_IMPLICIT_LCOMM_ALIGNMENT(SIZE, P2VAR) \
6337 else if ((SIZE) >= 4) \
6339 else if ((SIZE) >= 2) \
6348 s_score_lcomm (int bytes_p
)
6355 segT current_seg
= now_seg
;
6356 subsegT current_subseg
= now_subseg
;
6357 const int max_alignment
= 15;
6359 segT bss_seg
= bss_section
;
6360 int needs_align
= 0;
6362 name
= input_line_pointer
;
6363 c
= get_symbol_end ();
6364 p
= input_line_pointer
;
6369 as_bad (_("expected symbol name"));
6370 discard_rest_of_line ();
6376 /* Accept an optional comma after the name. The comma used to be
6377 required, but Irix 5 cc does not generate it. */
6378 if (*input_line_pointer
== ',')
6380 ++input_line_pointer
;
6384 if (is_end_of_line
[(unsigned char)*input_line_pointer
])
6386 as_bad (_("missing size expression"));
6390 if ((temp
= get_absolute_expression ()) < 0)
6392 as_warn (_("BSS length (%d) < 0 ignored"), temp
);
6393 ignore_rest_of_line ();
6397 #if defined (TC_SCORE)
6398 if (OUTPUT_FLAVOR
== bfd_target_ecoff_flavour
|| OUTPUT_FLAVOR
== bfd_target_elf_flavour
)
6400 /* For Score and Alpha ECOFF or ELF, small objects are put in .sbss. */
6401 if ((unsigned)temp
<= bfd_get_gp_size (stdoutput
))
6403 bss_seg
= subseg_new (".sbss", 1);
6404 seg_info (bss_seg
)->bss
= 1;
6405 #ifdef BFD_ASSEMBLER
6406 if (!bfd_set_section_flags (stdoutput
, bss_seg
, SEC_ALLOC
))
6407 as_warn (_("error setting flags for \".sbss\": %s"), bfd_errmsg (bfd_get_error ()));
6414 if (*input_line_pointer
== ',')
6416 ++input_line_pointer
;
6419 if (is_end_of_line
[(unsigned char)*input_line_pointer
])
6421 as_bad (_("missing alignment"));
6426 align
= get_absolute_expression ();
6433 TC_IMPLICIT_LCOMM_ALIGNMENT (temp
, align
);
6435 /* Still zero unless TC_IMPLICIT_LCOMM_ALIGNMENT set it. */
6437 record_alignment (bss_seg
, align
);
6444 /* Convert to a power of 2. */
6449 for (i
= 0; align
!= 0; align
>>= 1, ++i
)
6455 if (align
> max_alignment
)
6457 align
= max_alignment
;
6458 as_warn (_("alignment too large; %d assumed"), align
);
6463 as_warn (_("alignment negative; 0 assumed"));
6466 record_alignment (bss_seg
, align
);
6470 /* Assume some objects may require alignment on some systems. */
6471 #if defined (TC_ALPHA) && ! defined (VMS)
6474 align
= ffs (temp
) - 1;
6475 if (temp
% (1 << align
))
6482 symbolP
= symbol_find_or_make (name
);
6486 #if (defined (OBJ_AOUT) || defined (OBJ_MAYBE_AOUT) \
6487 || defined (OBJ_BOUT) || defined (OBJ_MAYBE_BOUT))
6488 #ifdef BFD_ASSEMBLER
6489 (OUTPUT_FLAVOR
!= bfd_target_aout_flavour
6490 || (S_GET_OTHER (symbolP
) == 0 && S_GET_DESC (symbolP
) == 0)) &&
6492 (S_GET_OTHER (symbolP
) == 0 && S_GET_DESC (symbolP
) == 0) &&
6495 (S_GET_SEGMENT (symbolP
) == bss_seg
|| (!S_IS_DEFINED (symbolP
) && S_GET_VALUE (symbolP
) == 0)))
6499 subseg_set (bss_seg
, 1);
6502 frag_align (align
, 0, 0);
6504 /* Detach from old frag. */
6505 if (S_GET_SEGMENT (symbolP
) == bss_seg
)
6506 symbol_get_frag (symbolP
)->fr_symbol
= NULL
;
6508 symbol_set_frag (symbolP
, frag_now
);
6509 pfrag
= frag_var (rs_org
, 1, 1, (relax_substateT
) 0, symbolP
, (offsetT
) temp
, NULL
);
6513 S_SET_SEGMENT (symbolP
, bss_seg
);
6516 /* The symbol may already have been created with a preceding
6517 ".globl" directive -- be careful not to step on storage class
6518 in that case. Otherwise, set it to static. */
6519 if (S_GET_STORAGE_CLASS (symbolP
) != C_EXT
)
6521 S_SET_STORAGE_CLASS (symbolP
, C_STAT
);
6523 #endif /* OBJ_COFF */
6526 S_SET_SIZE (symbolP
, temp
);
6530 as_bad (_("symbol `%s' is already defined"), S_GET_NAME (symbolP
));
6532 subseg_set (current_seg
, current_subseg
);
6534 demand_empty_rest_of_line ();
6538 insert_reg (const struct reg_entry
*r
, struct hash_control
*htab
)
6541 int len
= strlen (r
->name
) + 2;
6542 char *buf
= xmalloc (len
);
6543 char *buf2
= xmalloc (len
);
6545 strcpy (buf
+ i
, r
->name
);
6546 for (i
= 0; buf
[i
]; i
++)
6548 buf2
[i
] = TOUPPER (buf
[i
]);
6552 hash_insert (htab
, buf
, (void *) r
);
6553 hash_insert (htab
, buf2
, (void *) r
);
6557 build_reg_hsh (struct reg_map
*map
)
6559 const struct reg_entry
*r
;
6561 if ((map
->htab
= hash_new ()) == NULL
)
6563 as_fatal (_("virtual memory exhausted"));
6565 for (r
= map
->names
; r
->name
!= NULL
; r
++)
6567 insert_reg (r
, map
->htab
);
6578 if ((score_ops_hsh
= hash_new ()) == NULL
)
6579 as_fatal (_("virtual memory exhausted"));
6581 build_score_ops_hsh ();
6583 if ((dependency_insn_hsh
= hash_new ()) == NULL
)
6584 as_fatal (_("virtual memory exhausted"));
6586 build_dependency_insn_hsh ();
6588 for (i
= (int)REG_TYPE_FIRST
; i
< (int)REG_TYPE_MAX
; i
++)
6589 build_reg_hsh (all_reg_maps
+ i
);
6591 /* Initialize dependency vector. */
6592 init_dependency_vector ();
6594 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
, 0);
6596 subseg
= now_subseg
;
6597 pdr_seg
= subseg_new (".pdr", (subsegT
) 0);
6598 (void)bfd_set_section_flags (stdoutput
, pdr_seg
, SEC_READONLY
| SEC_RELOC
| SEC_DEBUGGING
);
6599 (void)bfd_set_section_alignment (stdoutput
, pdr_seg
, 2);
6600 subseg_set (seg
, subseg
);
6602 if (USE_GLOBAL_POINTER_OPT
)
6603 bfd_set_gp_size (stdoutput
, g_switch_value
);
6607 const pseudo_typeS md_pseudo_table
[] =
6609 {"bss", s_score_bss
, 0},
6610 {"text", s_score_text
, 0},
6613 {"extend", float_cons
, 'x'},
6614 {"ldouble", float_cons
, 'x'},
6615 {"packed", float_cons
, 'p'},
6616 {"end", s_score_end
, 0},
6617 {"ent", s_score_ent
, 0},
6618 {"frame", s_score_frame
, 0},
6619 {"rdata", s_change_sec
, 'r'},
6620 {"sdata", s_change_sec
, 's'},
6621 {"set", s_score_set
, 0},
6622 {"mask", s_score_mask
, 'R'},
6624 {"lcomm", s_score_lcomm
, 1},
6625 {"section", score_s_section
, 0},
6626 {"cpload", s_score_cpload
, 0},
6627 {"cprestore", s_score_cprestore
, 0},
6628 {"gpword", s_score_gpword
, 0},
6629 {"cpadd", s_score_cpadd
, 0},