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
46 /* For score5u : div/mul will pop warning message, mmu/alw/asw will pop error message. */
47 #define BAD_ARGS _("bad arguments to instruction")
48 #define BAD_PC _("r15 not allowed here")
49 #define BAD_COND _("instruction is not conditional")
50 #define ERR_NO_ACCUM _("acc0 expected")
51 #define ERR_FOR_SCORE5U_MUL_DIV _("div / mul are reserved instructions")
52 #define ERR_FOR_SCORE5U_MMU _("This architecture doesn't support mmu")
53 #define ERR_FOR_SCORE5U_ATOMIC _("This architecture doesn't support atomic instruction")
54 #define LONG_LABEL_LEN _("the label length is longer than 1024");
55 #define BAD_SKIP_COMMA BAD_ARGS
56 #define BAD_GARBAGE _("garbage following instruction");
58 #define skip_whitespace(str) while (*(str) == ' ') ++(str)
60 /* The name of the readonly data section. */
61 #define RDATA_SECTION_NAME (OUTPUT_FLAVOR == bfd_target_aout_flavour \
63 : OUTPUT_FLAVOR == bfd_target_ecoff_flavour \
65 : OUTPUT_FLAVOR == bfd_target_coff_flavour \
67 : OUTPUT_FLAVOR == bfd_target_elf_flavour \
71 #define RELAX_ENCODE(old, new, type, reloc1, reloc2, opt) \
80 #define RELAX_OLD(i) (((i) >> 23) & 0x7f)
81 #define RELAX_NEW(i) (((i) >> 16) & 0x7f)
82 #define RELAX_TYPE(i) (((i) >> 9) & 0x7f)
83 #define RELAX_RELOC1(i) ((valueT) ((i) >> 5) & 0xf)
84 #define RELAX_RELOC2(i) ((valueT) ((i) >> 1) & 0xf)
85 #define RELAX_OPT(i) ((i) & 1)
86 #define RELAX_OPT_CLEAR(i) ((i) & ~1)
88 #define SET_INSN_ERROR(s) (inst.error = (s))
89 #define INSN_IS_PCE_P(s) (strstr (str, "||") != NULL)
91 #define GET_INSN_CLASS(type) (get_insn_class_from_type (type))
93 #define GET_INSN_SIZE(type) ((GET_INSN_CLASS (type) == INSN_CLASS_16) \
94 ? INSN16_SIZE : INSN_SIZE)
96 /* This array holds the chars that always start a comment. If the
97 pre-processor is disabled, these aren't very useful. */
98 const char comment_chars
[] = "#";
99 const char line_comment_chars
[] = "#";
100 const char line_separator_chars
[] = ";";
102 /* Chars that can be used to separate mant from exp in floating point numbers. */
103 const char EXP_CHARS
[] = "eE";
104 const char FLT_CHARS
[] = "rRsSfFdDxXeEpP";
106 fragS
*score_fragp
= 0;
107 static int fix_data_dependency
= 0;
108 static int warn_fix_data_dependency
= 1;
109 static int score7
= 1;
110 static int university_version
= 0;
112 static int in_my_get_expression
= 0;
114 #define USE_GLOBAL_POINTER_OPT 1
115 #define SCORE_BI_ENDIAN
117 /* Default, pop warning message when using r1. */
120 /* Default will do instruction relax, -O0 will set g_opt = 0. */
121 static unsigned int g_opt
= 1;
123 /* The size of the small data section. */
124 static unsigned int g_switch_value
= 8;
127 /* Pre-defined "_GLOBAL_OFFSET_TABLE_" */
132 enum score_pic_level score_pic
= NO_PIC
;
134 #define INSN_NAME_LEN 16
137 char name
[INSN_NAME_LEN
];
138 unsigned long instruction
;
139 unsigned long relax_inst
;
142 enum score_insn_type type
;
143 char str
[MAX_LITERAL_POOL_SIZE
];
146 char reg
[INSN_NAME_LEN
];
149 bfd_reloc_code_real_type type
;
154 struct score_it inst
;
159 unsigned long reg_mask
;
160 unsigned long reg_offset
;
161 unsigned long fpreg_mask
;
163 unsigned long frame_offset
;
164 unsigned long frame_reg
;
165 unsigned long pc_reg
;
169 static procS cur_proc
;
170 static procS
*cur_proc_ptr
;
173 #define SCORE7_PIPELINE 7
174 #define SCORE5_PIPELINE 5
175 static int vector_size
= SCORE7_PIPELINE
;
176 struct score_it dependency_vector
[SCORE7_PIPELINE
];
178 /* Relax will need some padding for alignment. */
179 #define RELAX_PAD_BYTE 3
181 /* Number of littlenums required to hold an extended precision number. For md_atof. */
182 #define NUM_FLOAT_VALS 8
183 #define MAX_LITTLENUMS 6
184 LITTLENUM_TYPE fp_values
[NUM_FLOAT_VALS
][MAX_LITTLENUMS
];
186 /* Structure for a hash table entry for a register. */
193 static const struct reg_entry score_rn_table
[] =
195 {"r0", 0}, {"r1", 1}, {"r2", 2}, {"r3", 3},
196 {"r4", 4}, {"r5", 5}, {"r6", 6}, {"r7", 7},
197 {"r8", 8}, {"r9", 9}, {"r10", 10}, {"r11", 11},
198 {"r12", 12}, {"r13", 13}, {"r14", 14}, {"r15", 15},
199 {"r16", 16}, {"r17", 17}, {"r18", 18}, {"r19", 19},
200 {"r20", 20}, {"r21", 21}, {"r22", 22}, {"r23", 23},
201 {"r24", 24}, {"r25", 25}, {"r26", 26}, {"r27", 27},
202 {"r28", 28}, {"r29", 29}, {"r30", 30}, {"r31", 31},
206 static const struct reg_entry score_srn_table
[] =
208 {"sr0", 0}, {"sr1", 1}, {"sr2", 2},
212 static const struct reg_entry score_crn_table
[] =
214 {"cr0", 0}, {"cr1", 1}, {"cr2", 2}, {"cr3", 3},
215 {"cr4", 4}, {"cr5", 5}, {"cr6", 6}, {"cr7", 7},
216 {"cr8", 8}, {"cr9", 9}, {"cr10", 10}, {"cr11", 11},
217 {"cr12", 12}, {"cr13", 13}, {"cr14", 14}, {"cr15", 15},
218 {"cr16", 16}, {"cr17", 17}, {"cr18", 18}, {"cr19", 19},
219 {"cr20", 20}, {"cr21", 21}, {"cr22", 22}, {"cr23", 23},
220 {"cr24", 24}, {"cr25", 25}, {"cr26", 26}, {"cr27", 27},
221 {"cr28", 28}, {"cr29", 29}, {"cr30", 30}, {"cr31", 31},
227 const struct reg_entry
*names
;
229 struct hash_control
*htab
;
230 const char *expected
;
233 struct reg_map all_reg_maps
[] =
235 {score_rn_table
, 31, NULL
, N_("S+core register expected")},
236 {score_srn_table
, 2, NULL
, N_("S+core special-register expected")},
237 {score_crn_table
, 31, NULL
, N_("S+core co-processor register expected")},
240 static struct hash_control
*score_ops_hsh
= NULL
;
242 static struct hash_control
*dependency_insn_hsh
= NULL
;
244 /* Enumeration matching entries in table above. */
248 #define REG_TYPE_FIRST REG_TYPE_SCORE
249 REG_TYPE_SCORE_SR
= 1,
250 REG_TYPE_SCORE_CR
= 2,
254 typedef struct literalS
256 struct expressionS exp
;
257 struct score_it
*inst
;
261 literalT literals
[MAX_LITERAL_POOL_SIZE
];
263 static void do_ldst_insn (char *);
264 static void do_crdcrscrsimm5 (char *);
265 static void do_ldst_unalign (char *);
266 static void do_ldst_atomic (char *);
267 static void do_ldst_cop (char *);
268 static void do_macro_li_rdi32 (char *);
269 static void do_macro_la_rdi32 (char *);
270 static void do_macro_rdi32hi (char *);
271 static void do_macro_rdi32lo (char *);
272 static void do_macro_mul_rdrsrs (char *);
273 static void do_macro_ldst_label (char *);
274 static void do_branch (char *);
275 static void do_jump (char *);
276 static void do_empty (char *);
277 static void do_rdrsrs (char *);
278 static void do_rdsi16 (char *);
279 static void do_rdrssi14 (char *);
280 static void do_sub_rdsi16 (char *);
281 static void do_sub_rdi16 (char *);
282 static void do_sub_rdrssi14 (char *);
283 static void do_rdrsi5 (char *);
284 static void do_rdrsi14 (char *);
285 static void do_rdi16 (char *);
286 static void do_xrsi5 (char *);
287 static void do_rdrs (char *);
288 static void do_rdxrs (char *);
289 static void do_rsrs (char *);
290 static void do_rdcrs (char *);
291 static void do_rdsrs (char *);
292 static void do_rd (char *);
293 static void do_rs (char *);
294 static void do_i15 (char *);
295 static void do_xi5x (char *);
296 static void do_ceinst (char *);
297 static void do_cache (char *);
298 static void do16_rdrs (char *);
299 static void do16_rs (char *);
300 static void do16_xrs (char *);
301 static void do16_mv_rdrs (char *);
302 static void do16_hrdrs (char *);
303 static void do16_rdhrs (char *);
304 static void do16_rdi4 (char *);
305 static void do16_rdi5 (char *);
306 static void do16_xi5 (char *);
307 static void do16_ldst_insn (char *);
308 static void do16_ldst_imm_insn (char *);
309 static void do16_push_pop (char *);
310 static void do16_branch (char *);
311 static void do16_jump (char *);
312 static void do_rdi16_pic (char *);
313 static void do_addi_s_pic (char *);
314 static void do_addi_u_pic (char *);
315 static void do_lw_pic (char *);
317 static const struct asm_opcode score_ldst_insns
[] =
319 {"lw", 0x20000000, 0x3e000000, 0x2008, Rd_rvalueRs_SI15
, do_ldst_insn
},
320 {"lw", 0x06000000, 0x3e000007, 0x8000, Rd_rvalueRs_preSI12
, do_ldst_insn
},
321 {"lw", 0x0e000000, 0x3e000007, 0x200a, Rd_rvalueRs_postSI12
, do_ldst_insn
},
322 {"lh", 0x22000000, 0x3e000000, 0x2009, Rd_rvalueRs_SI15
, do_ldst_insn
},
323 {"lh", 0x06000001, 0x3e000007, 0x8000, Rd_rvalueRs_preSI12
, do_ldst_insn
},
324 {"lh", 0x0e000001, 0x3e000007, 0x8000, Rd_rvalueRs_postSI12
, do_ldst_insn
},
325 {"lhu", 0x24000000, 0x3e000000, 0x8000, Rd_rvalueRs_SI15
, do_ldst_insn
},
326 {"lhu", 0x06000002, 0x3e000007, 0x8000, Rd_rvalueRs_preSI12
, do_ldst_insn
},
327 {"lhu", 0x0e000002, 0x3e000007, 0x8000, Rd_rvalueRs_postSI12
, do_ldst_insn
},
328 {"lb", 0x26000000, 0x3e000000, 0x8000, Rd_rvalueRs_SI15
, do_ldst_insn
},
329 {"lb", 0x06000003, 0x3e000007, 0x8000, Rd_rvalueRs_preSI12
, do_ldst_insn
},
330 {"lb", 0x0e000003, 0x3e000007, 0x8000, Rd_rvalueRs_postSI12
, do_ldst_insn
},
331 {"sw", 0x28000000, 0x3e000000, 0x200c, Rd_lvalueRs_SI15
, do_ldst_insn
},
332 {"sw", 0x06000004, 0x3e000007, 0x200e, Rd_lvalueRs_preSI12
, do_ldst_insn
},
333 {"sw", 0x0e000004, 0x3e000007, 0x8000, Rd_lvalueRs_postSI12
, do_ldst_insn
},
334 {"sh", 0x2a000000, 0x3e000000, 0x200d, Rd_lvalueRs_SI15
, do_ldst_insn
},
335 {"sh", 0x06000005, 0x3e000007, 0x8000, Rd_lvalueRs_preSI12
, do_ldst_insn
},
336 {"sh", 0x0e000005, 0x3e000007, 0x8000, Rd_lvalueRs_postSI12
, do_ldst_insn
},
337 {"lbu", 0x2c000000, 0x3e000000, 0x200b, Rd_rvalueRs_SI15
, do_ldst_insn
},
338 {"lbu", 0x06000006, 0x3e000007, 0x8000, Rd_rvalueRs_preSI12
, do_ldst_insn
},
339 {"lbu", 0x0e000006, 0x3e000007, 0x8000, Rd_rvalueRs_postSI12
, do_ldst_insn
},
340 {"sb", 0x2e000000, 0x3e000000, 0x200f, Rd_lvalueRs_SI15
, do_ldst_insn
},
341 {"sb", 0x06000007, 0x3e000007, 0x8000, Rd_lvalueRs_preSI12
, do_ldst_insn
},
342 {"sb", 0x0e000007, 0x3e000007, 0x8000, Rd_lvalueRs_postSI12
, do_ldst_insn
},
345 static const struct asm_opcode score_insns
[] =
347 {"abs", 0x3800000a, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
348 {"abs.s", 0x3800004b, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
349 {"add", 0x00000010, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
350 {"add.c", 0x00000011, 0x3e0003ff, 0x2000, Rd_Rs_Rs
, do_rdrsrs
},
351 {"add.s", 0x38000048, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
352 {"addc", 0x00000012, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
353 {"addc.c", 0x00000013, 0x3e0003ff, 0x0009, Rd_Rs_Rs
, do_rdrsrs
},
354 {"addi", 0x02000000, 0x3e0e0001, 0x8000, Rd_SI16
, do_rdsi16
},
355 {"addi.c", 0x02000001, 0x3e0e0001, 0x8000, Rd_SI16
, do_rdsi16
},
356 {"addis", 0x0a000000, 0x3e0e0001, 0x8000, Rd_SI16
, do_rdi16
},
357 {"addis.c", 0x0a000001, 0x3e0e0001, 0x8000, Rd_SI16
, do_rdi16
},
358 {"addri", 0x10000000, 0x3e000001, 0x8000, Rd_Rs_SI14
, do_rdrssi14
},
359 {"addri.c", 0x10000001, 0x3e000001, 0x8000, Rd_Rs_SI14
, do_rdrssi14
},
360 {"addc!", 0x0009, 0x700f, 0x00000013, Rd_Rs
, do16_rdrs
},
361 {"add!", 0x2000, 0x700f, 0x00000011, Rd_Rs
, do16_rdrs
},
362 {"addei!", 0x6000 , 0x7087, 0x02000001, Rd_I4
, do16_rdi4
},
363 {"subi", 0x02000000, 0x3e0e0001, 0x8000, Rd_SI16
, do_sub_rdsi16
},
364 {"subi.c", 0x02000001, 0x3e0e0001, 0x8000, Rd_SI16
, do_sub_rdsi16
},
365 {"subis", 0x0a000000, 0x3e0e0001, 0x8000, Rd_SI16
, do_sub_rdi16
},
366 {"subis.c", 0x0a000001, 0x3e0e0001, 0x8000, Rd_SI16
, do_sub_rdi16
},
367 {"subri", 0x10000000, 0x3e000001, 0x8000, Rd_Rs_SI14
, do_sub_rdrssi14
},
368 {"subri.c", 0x10000001, 0x3e000001, 0x8000, Rd_Rs_SI14
, do_sub_rdrssi14
},
369 {"and", 0x00000020, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
370 {"and.c", 0x00000021, 0x3e0003ff, 0x2004, Rd_Rs_Rs
, do_rdrsrs
},
371 {"andi", 0x02080000, 0x3e0e0001, 0x8000, Rd_I16
, do_rdi16
},
372 {"andi.c", 0x02080001, 0x3e0e0001, 0x8000, Rd_I16
, do_rdi16
},
373 {"andis", 0x0a080000, 0x3e0e0001, 0x8000, Rd_I16
, do_rdi16
},
374 {"andis.c", 0x0a080001, 0x3e0e0001, 0x8000, Rd_I16
, do_rdi16
},
375 {"andri", 0x18000000, 0x3e000001, 0x8000, Rd_Rs_I14
, do_rdrsi14
},
376 {"andri.c", 0x18000001, 0x3e000001, 0x8000, Rd_Rs_I14
, do_rdrsi14
},
377 {"and!", 0x2004, 0x700f, 0x00000021, Rd_Rs
, do16_rdrs
},
378 {"bcs", 0x08000000, 0x3e007c01, 0x4000, PC_DISP19div2
, do_branch
},
379 {"bcc", 0x08000400, 0x3e007c01, 0x4000, PC_DISP19div2
, do_branch
},
380 {"bcnz", 0x08003800, 0x3e007c01, 0x4000, PC_DISP19div2
, do_branch
},
381 {"bcsl", 0x08000001, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
382 {"bccl", 0x08000401, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
383 {"bcnzl", 0x08003801, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
384 {"bcs!", 0x4000, 0x7f00, 0x08000000, PC_DISP8div2
, do16_branch
},
385 {"bcc!", 0x4100, 0x7f00, 0x08000400, PC_DISP8div2
, do16_branch
},
386 {"bcnz!", 0x4e00, 0x7f00, 0x08003800, PC_DISP8div2
, do16_branch
},
387 {"beq", 0x08001000, 0x3e007c01, 0x4000, PC_DISP19div2
, do_branch
},
388 {"beql", 0x08001001, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
389 {"beq!", 0x4400, 0x7f00, 0x08001000, PC_DISP8div2
, do16_branch
},
390 {"bgtu", 0x08000800, 0x3e007c01, 0x4000, PC_DISP19div2
, do_branch
},
391 {"bgt", 0x08001800, 0x3e007c01, 0x4000, PC_DISP19div2
, do_branch
},
392 {"bge", 0x08002000, 0x3e007c01, 0x4000, PC_DISP19div2
, do_branch
},
393 {"bgtul", 0x08000801, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
394 {"bgtl", 0x08001801, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
395 {"bgel", 0x08002001, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
396 {"bgtu!", 0x4200, 0x7f00, 0x08000800, PC_DISP8div2
, do16_branch
},
397 {"bgt!", 0x4600, 0x7f00, 0x08001800, PC_DISP8div2
, do16_branch
},
398 {"bge!", 0x4800, 0x7f00, 0x08002000, PC_DISP8div2
, do16_branch
},
399 {"bitclr.c", 0x00000029, 0x3e0003ff, 0x6004, Rd_Rs_I5
, do_rdrsi5
},
400 {"bitrev", 0x3800000c, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
401 {"bitset.c", 0x0000002b, 0x3e0003ff, 0x6005, Rd_Rs_I5
, do_rdrsi5
},
402 {"bittst.c", 0x0000002d, 0x3e0003ff, 0x6006, x_Rs_I5
, do_xrsi5
},
403 {"bittgl.c", 0x0000002f, 0x3e0003ff, 0x6007, Rd_Rs_I5
, do_rdrsi5
},
404 {"bitclr!", 0x6004, 0x7007, 0x00000029, Rd_I5
, do16_rdi5
},
405 {"bitset!", 0x6005, 0x7007, 0x0000002b, Rd_I5
, do16_rdi5
},
406 {"bittst!", 0x6006, 0x7007, 0x0000002d, Rd_I5
, do16_rdi5
},
407 {"bittgl!", 0x6007, 0x7007, 0x0000002f, Rd_I5
, do16_rdi5
},
408 {"bleu", 0x08000c00, 0x3e007c01, 0x4000, PC_DISP19div2
, do_branch
},
409 {"ble", 0x08001c00, 0x3e007c01, 0x4000, PC_DISP19div2
, do_branch
},
410 {"blt", 0x08002400, 0x3e007c01, 0x4000, PC_DISP19div2
, do_branch
},
411 {"bleul", 0x08000c01, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
412 {"blel", 0x08001c01, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
413 {"bltl", 0x08002401, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
414 {"bl", 0x08003c01, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
415 {"bleu!", 0x4300, 0x7f00, 0x08000c00, PC_DISP8div2
, do16_branch
},
416 {"ble!", 0x4700, 0x7f00, 0x08001c00, PC_DISP8div2
, do16_branch
},
417 {"blt!", 0x4900, 0x7f00, 0x08002400, PC_DISP8div2
, do16_branch
},
418 {"bmi", 0x08002800, 0x3e007c01, 0x4000, PC_DISP19div2
, do_branch
},
419 {"bmil", 0x08002801, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
420 {"bmi!", 0x00004a00, 0x00007f00, 0x08002800, PC_DISP8div2
, do16_branch
},
421 {"bne", 0x08001400, 0x3e007c01, 0x4000, PC_DISP19div2
, do_branch
},
422 {"bnel", 0x08001401, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
423 {"bne!", 0x4500, 0x7f00, 0x08001400, PC_DISP8div2
, do16_branch
},
424 {"bpl", 0x08002c00, 0x3e007c01, 0x4000, PC_DISP19div2
, do_branch
},
425 {"bpll", 0x08002c01, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
426 {"bpl!", 0x4b00, 0x7f00, 0x08002c00, PC_DISP8div2
, do16_branch
},
427 {"brcs", 0x00000008, 0x3e007fff, 0x0004, x_Rs_x
, do_rs
},
428 {"brcc", 0x00000408, 0x3e007fff, 0x0104, x_Rs_x
, do_rs
},
429 {"brgtu", 0x00000808, 0x3e007fff, 0x0204, x_Rs_x
, do_rs
},
430 {"brleu", 0x00000c08, 0x3e007fff, 0x0304, x_Rs_x
, do_rs
},
431 {"breq", 0x00001008, 0x3e007fff, 0x0404, x_Rs_x
, do_rs
},
432 {"brne", 0x00001408, 0x3e007fff, 0x0504, x_Rs_x
, do_rs
},
433 {"brgt", 0x00001808, 0x3e007fff, 0x0604, x_Rs_x
, do_rs
},
434 {"brle", 0x00001c08, 0x3e007fff, 0x0704, x_Rs_x
, do_rs
},
435 {"brge", 0x00002008, 0x3e007fff, 0x0804, x_Rs_x
, do_rs
},
436 {"brlt", 0x00002408, 0x3e007fff, 0x0904, x_Rs_x
, do_rs
},
437 {"brmi", 0x00002808, 0x3e007fff, 0x0a04, x_Rs_x
, do_rs
},
438 {"brpl", 0x00002c08, 0x3e007fff, 0x0b04, x_Rs_x
, do_rs
},
439 {"brvs", 0x00003008, 0x3e007fff, 0x0c04, x_Rs_x
, do_rs
},
440 {"brvc", 0x00003408, 0x3e007fff, 0x0d04, x_Rs_x
, do_rs
},
441 {"brcnz", 0x00003808, 0x3e007fff, 0x0e04, x_Rs_x
, do_rs
},
442 {"br", 0x00003c08, 0x3e007fff, 0x0f04, x_Rs_x
, do_rs
},
443 {"brcsl", 0x00000009, 0x3e007fff, 0x000c, x_Rs_x
, do_rs
},
444 {"brccl", 0x00000409, 0x3e007fff, 0x010c, x_Rs_x
, do_rs
},
445 {"brgtul", 0x00000809, 0x3e007fff, 0x020c, x_Rs_x
, do_rs
},
446 {"brleul", 0x00000c09, 0x3e007fff, 0x030c, x_Rs_x
, do_rs
},
447 {"breql", 0x00001009, 0x3e007fff, 0x040c, x_Rs_x
, do_rs
},
448 {"brnel", 0x00001409, 0x3e007fff, 0x050c, x_Rs_x
, do_rs
},
449 {"brgtl", 0x00001809, 0x3e007fff, 0x060c, x_Rs_x
, do_rs
},
450 {"brlel", 0x00001c09, 0x3e007fff, 0x070c, x_Rs_x
, do_rs
},
451 {"brgel", 0x00002009, 0x3e007fff, 0x080c, x_Rs_x
, do_rs
},
452 {"brltl", 0x00002409, 0x3e007fff, 0x090c, x_Rs_x
, do_rs
},
453 {"brmil", 0x00002809, 0x3e007fff, 0x0a0c, x_Rs_x
, do_rs
},
454 {"brpll", 0x00002c09, 0x3e007fff, 0x0b0c, x_Rs_x
, do_rs
},
455 {"brvsl", 0x00003009, 0x3e007fff, 0x0c0c, x_Rs_x
, do_rs
},
456 {"brvcl", 0x00003409, 0x3e007fff, 0x0d0c, x_Rs_x
, do_rs
},
457 {"brcnzl", 0x00003809, 0x3e007fff, 0x0e0c, x_Rs_x
, do_rs
},
458 {"brl", 0x00003c09, 0x3e007fff, 0x0f0c, x_Rs_x
, do_rs
},
459 {"brcs!", 0x0004, 0x7f0f, 0x00000008, x_Rs
, do16_xrs
},
460 {"brcc!", 0x0104, 0x7f0f, 0x00000408, x_Rs
, do16_xrs
},
461 {"brgtu!", 0x0204, 0x7f0f, 0x00000808, x_Rs
, do16_xrs
},
462 {"brleu!", 0x0304, 0x7f0f, 0x00000c08, x_Rs
, do16_xrs
},
463 {"breq!", 0x0404, 0x7f0f, 0x00001008, x_Rs
, do16_xrs
},
464 {"brne!", 0x0504, 0x7f0f, 0x00001408, x_Rs
, do16_xrs
},
465 {"brgt!", 0x0604, 0x7f0f, 0x00001808, x_Rs
, do16_xrs
},
466 {"brle!", 0x0704, 0x7f0f, 0x00001c08, x_Rs
, do16_xrs
},
467 {"brge!", 0x0804, 0x7f0f, 0x00002008, x_Rs
, do16_xrs
},
468 {"brlt!", 0x0904, 0x7f0f, 0x00002408, x_Rs
, do16_xrs
},
469 {"brmi!", 0x0a04, 0x7f0f, 0x00002808, x_Rs
, do16_xrs
},
470 {"brpl!", 0x0b04, 0x7f0f, 0x00002c08, x_Rs
, do16_xrs
},
471 {"brvs!", 0x0c04, 0x7f0f, 0x00003008, x_Rs
, do16_xrs
},
472 {"brvc!", 0x0d04, 0x7f0f, 0x00003408, x_Rs
, do16_xrs
},
473 {"brcnz!", 0x0e04, 0x7f0f, 0x00003808, x_Rs
, do16_xrs
},
474 {"br!", 0x0f04, 0x7f0f, 0x00003c08, x_Rs
, do16_xrs
},
475 {"brcsl!", 0x000c, 0x7f0f, 0x00000009, x_Rs
, do16_xrs
},
476 {"brccl!", 0x010c, 0x7f0f, 0x00000409, x_Rs
, do16_xrs
},
477 {"brgtul!", 0x020c, 0x7f0f, 0x00000809, x_Rs
, do16_xrs
},
478 {"brleul!", 0x030c, 0x7f0f, 0x00000c09, x_Rs
, do16_xrs
},
479 {"breql!", 0x040c, 0x7f0f, 0x00001009, x_Rs
, do16_xrs
},
480 {"brnel!", 0x050c, 0x7f0f, 0x00001409, x_Rs
, do16_xrs
},
481 {"brgtl!", 0x060c, 0x7f0f, 0x00001809, x_Rs
, do16_xrs
},
482 {"brlel!", 0x070c, 0x7f0f, 0x00001c09, x_Rs
, do16_xrs
},
483 {"brgel!", 0x080c, 0x7f0f, 0x00002009, x_Rs
, do16_xrs
},
484 {"brltl!", 0x090c, 0x7f0f, 0x00002409, x_Rs
, do16_xrs
},
485 {"brmil!", 0x0a0c, 0x7f0f, 0x00002809, x_Rs
, do16_xrs
},
486 {"brpll!", 0x0b0c, 0x7f0f, 0x00002c09, x_Rs
, do16_xrs
},
487 {"brvsl!", 0x0c0c, 0x7f0f, 0x00003009, x_Rs
, do16_xrs
},
488 {"brvcl!", 0x0d0c, 0x7f0f, 0x00003409, x_Rs
, do16_xrs
},
489 {"brcnzl!", 0x0e0c, 0x7f0f, 0x00003809, x_Rs
, do16_xrs
},
490 {"brl!", 0x0f0c, 0x7f0f, 0x00003c09, x_Rs
, do16_xrs
},
491 {"bvs", 0x08003000, 0x3e007c01, 0x4000, PC_DISP19div2
, do_branch
},
492 {"bvc", 0x08003400, 0x3e007c01, 0x4000, PC_DISP19div2
, do_branch
},
493 {"bvsl", 0x08003001, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
494 {"bvcl", 0x08003401, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
495 {"bvs!", 0x4c00, 0x7f00, 0x08003000, PC_DISP8div2
, do16_branch
},
496 {"bvc!", 0x4d00, 0x7f00, 0x08003400, PC_DISP8div2
, do16_branch
},
497 {"b!", 0x4f00, 0x7f00, 0x08003c00, PC_DISP8div2
, do16_branch
},
498 {"b", 0x08003c00, 0x3e007c01, 0x4000, PC_DISP19div2
, do_branch
},
499 {"cache", 0x30000000, 0x3ff00000, 0x8000, OP5_rvalueRs_SI15
, do_cache
},
500 {"ceinst", 0x38000000, 0x3e000000, 0x8000, I5_Rs_Rs_I5_OP5
, do_ceinst
},
501 {"clz", 0x3800000d, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
502 {"cmpteq.c", 0x00000019, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
503 {"cmptmi.c", 0x00100019, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
504 {"cmp.c", 0x00300019, 0x3ff003ff, 0x2003, x_Rs_Rs
, do_rsrs
},
505 {"cmpzteq.c", 0x0000001b, 0x3ff07fff, 0x8000, x_Rs_x
, do_rs
},
506 {"cmpztmi.c", 0x0010001b, 0x3ff07fff, 0x8000, x_Rs_x
, do_rs
},
507 {"cmpz.c", 0x0030001b, 0x3ff07fff, 0x8000, x_Rs_x
, do_rs
},
508 {"cmpi.c", 0x02040001, 0x3e0e0001, 0x8000, Rd_SI16
, do_rdsi16
},
509 {"cmp!", 0x2003, 0x700f, 0x00300019, Rd_Rs
, do16_rdrs
},
510 {"cop1", 0x0c00000c, 0x3e00001f, 0x8000, Rd_Rs_Rs_imm
, do_crdcrscrsimm5
},
511 {"cop2", 0x0c000014, 0x3e00001f, 0x8000, Rd_Rs_Rs_imm
, do_crdcrscrsimm5
},
512 {"cop3", 0x0c00001c, 0x3e00001f, 0x8000, Rd_Rs_Rs_imm
, do_crdcrscrsimm5
},
513 {"drte", 0x0c0000a4, 0x3e0003ff, 0x8000, NO_OPD
, do_empty
},
514 {"extsb", 0x00000058, 0x3e0003ff, 0x8000, Rd_Rs_x
, do_rdrs
},
515 {"extsb.c", 0x00000059, 0x3e0003ff, 0x8000, Rd_Rs_x
, do_rdrs
},
516 {"extsh", 0x0000005a, 0x3e0003ff, 0x8000, Rd_Rs_x
, do_rdrs
},
517 {"extsh.c", 0x0000005b, 0x3e0003ff, 0x8000, Rd_Rs_x
, do_rdrs
},
518 {"extzb", 0x0000005c, 0x3e0003ff, 0x8000, Rd_Rs_x
, do_rdrs
},
519 {"extzb.c", 0x0000005d, 0x3e0003ff, 0x8000, Rd_Rs_x
, do_rdrs
},
520 {"extzh", 0x0000005e, 0x3e0003ff, 0x8000, Rd_Rs_x
, do_rdrs
},
521 {"extzh.c", 0x0000005f, 0x3e0003ff, 0x8000, Rd_Rs_x
, do_rdrs
},
522 {"jl", 0x04000001, 0x3e000001, 0x8000, PC_DISP24div2
, do_jump
},
523 {"jl!", 0x3001, 0x7001, 0x04000001, PC_DISP11div2
, do16_jump
},
524 {"j!", 0x3000, 0x7001, 0x04000000, PC_DISP11div2
, do16_jump
},
525 {"j", 0x04000000, 0x3e000001, 0x8000, PC_DISP24div2
, do_jump
},
526 {"lbu!", 0x200b, 0x0000700f, 0x2c000000, Rd_rvalueRs
, do16_ldst_insn
},
527 {"lbup!", 0x7003, 0x7007, 0x2c000000, Rd_rvalueBP_I5
, do16_ldst_imm_insn
},
528 {"alw", 0x0000000c, 0x3e0003ff, 0x8000, Rd_rvalue32Rs
, do_ldst_atomic
},
529 {"lcb", 0x00000060, 0x3e0003ff, 0x8000, x_rvalueRs_post4
, do_ldst_unalign
},
530 {"lcw", 0x00000062, 0x3e0003ff, 0x8000, Rd_rvalueRs_post4
, do_ldst_unalign
},
531 {"lce", 0x00000066, 0x3e0003ff, 0x8000, Rd_rvalueRs_post4
, do_ldst_unalign
},
532 {"ldc1", 0x0c00000a, 0x3e00001f, 0x8000, Rd_rvalueRs_SI10
, do_ldst_cop
},
533 {"ldc2", 0x0c000012, 0x3e00001f, 0x8000, Rd_rvalueRs_SI10
, do_ldst_cop
},
534 {"ldc3", 0x0c00001a, 0x3e00001f, 0x8000, Rd_rvalueRs_SI10
, do_ldst_cop
},
535 {"lh!", 0x2009, 0x700f, 0x22000000, Rd_rvalueRs
, do16_ldst_insn
},
536 {"lhp!", 0x7001, 0x7007, 0x22000000, Rd_rvalueBP_I5
, do16_ldst_imm_insn
},
537 {"ldi", 0x020c0000, 0x3e0e0000, 0x5000, Rd_SI16
, do_rdsi16
},
538 {"ldis", 0x0a0c0000, 0x3e0e0000, 0x5000, Rd_I16
, do_rdi16
},
539 {"ldiu!", 0x5000, 0x7000, 0x020c0000, Rd_I8
, do16_ldst_imm_insn
},
540 {"lw!", 0x2008, 0x700f, 0x20000000, Rd_rvalueRs
, do16_ldst_insn
},
541 {"lwp!", 0x7000, 0x7007, 0x20000000, Rd_rvalueBP_I5
, do16_ldst_imm_insn
},
542 {"mfcel", 0x00000448, 0x3e007fff, 0x8000, Rd_x_x
, do_rd
},
543 {"mfcel!", 0x1001, 0x7f0f, 0x00000448, x_Rs
, do16_rs
},
544 {"mad", 0x38000000, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
545 {"mad.f!", 0x1004, 0x700f, 0x38000080, Rd_Rs
, do16_rdrs
},
546 {"madh", 0x38000203, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
547 {"madh.fs", 0x380002c3, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
548 {"madh.fs!", 0x100b, 0x700f, 0x380002c3, Rd_Rs
, do16_rdrs
},
549 {"madl", 0x38000002, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
550 {"madl.fs", 0x380000c2, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
551 {"madl.fs!", 0x100a, 0x700f, 0x380000c2, Rd_Rs
, do16_rdrs
},
552 {"madu", 0x38000020, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
553 {"madu!", 0x1005, 0x700f, 0x38000020, Rd_Rs
, do16_rdrs
},
554 {"mad.f", 0x38000080, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
555 {"max", 0x38000007, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
556 {"mazh", 0x38000303, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
557 {"mazh.f", 0x38000383, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
558 {"mazh.f!", 0x1009, 0x700f, 0x3800038c, Rd_Rs
, do16_rdrs
},
559 {"mazl", 0x38000102, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
560 {"mazl.f", 0x38000182, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
561 {"mazl.f!", 0x1008, 0x700f, 0x38000182, Rd_Rs
, do16_rdrs
},
562 {"mfceh", 0x00000848, 0x3e007fff, 0x8000, Rd_x_x
, do_rd
},
563 {"mfceh!", 0x1101, 0x7f0f, 0x00000848, x_Rs
, do16_rs
},
564 {"mfcehl", 0x00000c48, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
565 {"mfsr", 0x00000050, 0x3e0003ff, 0x8000, Rd_x_I5
, do_rdsrs
},
566 {"mfcr", 0x0c000001, 0x3e00001f, 0x8000, Rd_Rs_x
, do_rdcrs
},
567 {"mfc1", 0x0c000009, 0x3e00001f, 0x8000, Rd_Rs_x
, do_rdcrs
},
568 {"mfc2", 0x0c000011, 0x3e00001f, 0x8000, Rd_Rs_x
, do_rdcrs
},
569 {"mfc3", 0x0c000019, 0x3e00001f, 0x8000, Rd_Rs_x
, do_rdcrs
},
570 {"mfcc1", 0x0c00000f, 0x3e00001f, 0x8000, Rd_Rs_x
, do_rdcrs
},
571 {"mfcc2", 0x0c000017, 0x3e00001f, 0x8000, Rd_Rs_x
, do_rdcrs
},
572 {"mfcc3", 0x0c00001f, 0x3e00001f, 0x8000, Rd_Rs_x
, do_rdcrs
},
573 {"mhfl!", 0x0002, 0x700f, 0x00003c56, Rd_LowRs
, do16_hrdrs
},
574 {"min", 0x38000006, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
575 {"mlfh!", 0x0001, 0x700f, 0x00003c56, Rd_HighRs
, do16_rdhrs
},
576 {"msb", 0x38000001, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
577 {"msb.f!", 0x1006, 0x700f, 0x38000081, Rd_Rs
, do16_rdrs
},
578 {"msbh", 0x38000205, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
579 {"msbh.fs", 0x380002c5, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
580 {"msbh.fs!", 0x100f, 0x700f, 0x380002c5, Rd_Rs
, do16_rdrs
},
581 {"msbl", 0x38000004, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
582 {"msbl.fs", 0x380000c4, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
583 {"msbl.fs!", 0x100e, 0x700f, 0x380000c4, Rd_Rs
, do16_rdrs
},
584 {"msbu", 0x38000021, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
585 {"msbu!", 0x1007, 0x700f, 0x38000021, Rd_Rs
, do16_rdrs
},
586 {"msb.f", 0x38000081, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
587 {"mszh", 0x38000305, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
588 {"mszh.f", 0x38000385, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
589 {"mszh.f!", 0x100d, 0x700f, 0x38000385, Rd_Rs
, do16_rdrs
},
590 {"mszl", 0x38000104, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
591 {"mszl.f", 0x38000184, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
592 {"mszl.f!", 0x100c, 0x700f, 0x38000184, Rd_Rs
, do16_rdrs
},
593 {"mtcel!", 0x1000, 0x7f0f, 0x0000044a, x_Rs
, do16_rs
},
594 {"mtcel", 0x0000044a, 0x3e007fff, 0x8000, Rd_x_x
, do_rd
},
595 {"mtceh", 0x0000084a, 0x3e007fff, 0x8000, Rd_x_x
, do_rd
},
596 {"mtceh!", 0x1100, 0x7f0f, 0x0000084a, x_Rs
, do16_rs
},
597 {"mtcehl", 0x00000c4a, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
598 {"mtsr", 0x00000052, 0x3e0003ff, 0x8000, x_Rs_I5
, do_rdsrs
},
599 {"mtcr", 0x0c000000, 0x3e00001f, 0x8000, Rd_Rs_x
, do_rdcrs
},
600 {"mtc1", 0x0c000008, 0x3e00001f, 0x8000, Rd_Rs_x
, do_rdcrs
},
601 {"mtc2", 0x0c000010, 0x3e00001f, 0x8000, Rd_Rs_x
, do_rdcrs
},
602 {"mtc3", 0x0c000018, 0x3e00001f, 0x8000, Rd_Rs_x
, do_rdcrs
},
603 {"mtcc1", 0x0c00000e, 0x3e00001f, 0x8000, Rd_Rs_x
, do_rdcrs
},
604 {"mtcc2", 0x0c000016, 0x3e00001f, 0x8000, Rd_Rs_x
, do_rdcrs
},
605 {"mtcc3", 0x0c00001e, 0x3e00001f, 0x8000, Rd_Rs_x
, do_rdcrs
},
606 {"mul.f!", 0x1002, 0x700f, 0x00000041, Rd_Rs
, do16_rdrs
},
607 {"mulu!", 0x1003, 0x700f, 0x00000042, Rd_Rs
, do16_rdrs
},
608 {"mvcs", 0x00000056, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
609 {"mvcc", 0x00000456, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
610 {"mvgtu", 0x00000856, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
611 {"mvleu", 0x00000c56, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
612 {"mveq", 0x00001056, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
613 {"mvne", 0x00001456, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
614 {"mvgt", 0x00001856, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
615 {"mvle", 0x00001c56, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
616 {"mvge", 0x00002056, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
617 {"mvlt", 0x00002456, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
618 {"mvmi", 0x00002856, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
619 {"mvpl", 0x00002c56, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
620 {"mvvs", 0x00003056, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
621 {"mvvc", 0x00003456, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
622 {"mv", 0x00003c56, 0x3e007fff, 0x0003, Rd_Rs_x
, do_rdrs
},
623 {"mv!", 0x0003, 0x700f, 0x00003c56, Rd_Rs
, do16_mv_rdrs
},
624 {"neg", 0x0000001e, 0x3e0003ff, 0x8000, Rd_x_Rs
, do_rdxrs
},
625 {"neg.c", 0x0000001f, 0x3e0003ff, 0x2002, Rd_x_Rs
, do_rdxrs
},
626 {"neg!", 0x2002, 0x700f, 0x0000001f, Rd_Rs
, do16_rdrs
},
627 {"nop", 0x00000000, 0x3e0003ff, 0x0000, NO_OPD
, do_empty
},
628 {"not", 0x00000024, 0x3e0003ff, 0x8000, Rd_Rs_x
, do_rdrs
},
629 {"not.c", 0x00000025, 0x3e0003ff, 0x2006, Rd_Rs_x
, do_rdrs
},
630 {"nop!", 0x0000, 0x700f, 0x00000000, NO16_OPD
, do_empty
},
631 {"not!", 0x2006, 0x700f, 0x00000025, Rd_Rs
, do16_rdrs
},
632 {"or", 0x00000022, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
633 {"or.c", 0x00000023, 0x3e0003ff, 0x2005, Rd_Rs_Rs
, do_rdrsrs
},
634 {"ori", 0x020a0000, 0x3e0e0001, 0x8000, Rd_I16
, do_rdi16
},
635 {"ori.c", 0x020a0001, 0x3e0e0001, 0x8000, Rd_I16
, do_rdi16
},
636 {"oris", 0x0a0a0000, 0x3e0e0001, 0x8000, Rd_I16
, do_rdi16
},
637 {"oris.c", 0x0a0a0001, 0x3e0e0001, 0x8000, Rd_I16
, do_rdi16
},
638 {"orri", 0x1a000000, 0x3e000001, 0x8000, Rd_Rs_I14
, do_rdrsi14
},
639 {"orri.c", 0x1a000001, 0x3e000001, 0x8000, Rd_Rs_I14
, do_rdrsi14
},
640 {"or!", 0x2005, 0x700f, 0x00000023, Rd_Rs
, do16_rdrs
},
641 {"pflush", 0x0000000a, 0x3e0003ff, 0x8000, NO_OPD
, do_empty
},
642 {"pop!", 0x200a, 0x700f, 0x0e000000, Rd_rvalueRs
, do16_push_pop
},
643 {"push!", 0x200e, 0x700f, 0x06000004, Rd_lvalueRs
, do16_push_pop
},
644 {"ror", 0x00000038, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
645 {"ror.c", 0x00000039, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
646 {"rorc.c", 0x0000003b, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
647 {"rol", 0x0000003c, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
648 {"rol.c", 0x0000003d, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
649 {"rolc.c", 0x0000003f, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
650 {"rori", 0x00000078, 0x3e0003ff, 0x8000, Rd_Rs_I5
, do_rdrsi5
},
651 {"rori.c", 0x00000079, 0x3e0003ff, 0x8000, Rd_Rs_I5
, do_rdrsi5
},
652 {"roric.c", 0x0000007b, 0x3e0003ff, 0x8000, Rd_Rs_I5
, do_rdrsi5
},
653 {"roli", 0x0000007c, 0x3e0003ff, 0x8000, Rd_Rs_I5
, do_rdrsi5
},
654 {"roli.c", 0x0000007d, 0x3e0003ff, 0x8000, Rd_Rs_I5
, do_rdrsi5
},
655 {"rolic.c", 0x0000007f, 0x3e0003ff, 0x8000, Rd_Rs_I5
, do_rdrsi5
},
656 {"rte", 0x0c000084, 0x3e0003ff, 0x8000, NO_OPD
, do_empty
},
657 {"sb!", 0x200f, 0x700f, 0x2e000000, Rd_lvalueRs
, do16_ldst_insn
},
658 {"sbp!", 0x7007, 0x7007, 0x2e000000, Rd_lvalueBP_I5
, do16_ldst_imm_insn
},
659 {"asw", 0x0000000e, 0x3e0003ff, 0x8000, Rd_lvalue32Rs
, do_ldst_atomic
},
660 {"scb", 0x00000068, 0x3e0003ff, 0x8000, Rd_lvalueRs_post4
, do_ldst_unalign
},
661 {"scw", 0x0000006a, 0x3e0003ff, 0x8000, Rd_lvalueRs_post4
, do_ldst_unalign
},
662 {"sce", 0x0000006e, 0x3e0003ff, 0x8000, x_lvalueRs_post4
, do_ldst_unalign
},
663 {"sdbbp", 0x00000006, 0x3e0003ff, 0x6002, x_I5_x
, do_xi5x
},
664 {"sdbbp!", 0x6002, 0x7007, 0x00000006, Rd_I5
, do16_xi5
},
665 {"sh!", 0x200d, 0x700f, 0x2a000000, Rd_lvalueRs
, do16_ldst_insn
},
666 {"shp!", 0x7005, 0x7007, 0x2a000000, Rd_lvalueBP_I5
, do16_ldst_imm_insn
},
667 {"sleep", 0x0c0000c4, 0x3e0003ff, 0x8000, NO_OPD
, do_empty
},
668 {"sll", 0x00000030, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
669 {"sll.c", 0x00000031, 0x3e0003ff, 0x0008, Rd_Rs_Rs
, do_rdrsrs
},
670 {"sll.s", 0x3800004e, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
671 {"slli", 0x00000070, 0x3e0003ff, 0x8000, Rd_Rs_I5
, do_rdrsi5
},
672 {"slli.c", 0x00000071, 0x3e0003ff, 0x6001, Rd_Rs_I5
, do_rdrsi5
},
673 {"sll!", 0x0008, 0x700f, 0x00000031, Rd_Rs
, do16_rdrs
},
674 {"slli!", 0x6001, 0x7007, 0x00000071, Rd_I5
, do16_rdi5
},
675 {"srl", 0x00000034, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
676 {"srl.c", 0x00000035, 0x3e0003ff, 0x000a, Rd_Rs_Rs
, do_rdrsrs
},
677 {"sra", 0x00000036, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
678 {"sra.c", 0x00000037, 0x3e0003ff, 0x000b, Rd_Rs_Rs
, do_rdrsrs
},
679 {"srli", 0x00000074, 0x3e0003ff, 0x8000, Rd_Rs_I5
, do_rdrsi5
},
680 {"srli.c", 0x00000075, 0x3e0003ff, 0x6003, Rd_Rs_I5
, do_rdrsi5
},
681 {"srai", 0x00000076, 0x3e0003ff, 0x8000, Rd_Rs_I5
, do_rdrsi5
},
682 {"srai.c", 0x00000077, 0x3e0003ff, 0x8000, Rd_Rs_I5
, do_rdrsi5
},
683 {"srl!", 0x000a, 0x700f, 0x00000035, Rd_Rs
, do16_rdrs
},
684 {"sra!", 0x000b, 0x700f, 0x00000037, Rd_Rs
, do16_rdrs
},
685 {"srli!", 0x6003, 0x7007, 0x00000075, Rd_Rs
, do16_rdi5
},
686 {"stc1", 0x0c00000b, 0x3e00001f, 0x8000, Rd_lvalueRs_SI10
, do_ldst_cop
},
687 {"stc2", 0x0c000013, 0x3e00001f, 0x8000, Rd_lvalueRs_SI10
, do_ldst_cop
},
688 {"stc3", 0x0c00001b, 0x3e00001f, 0x8000, Rd_lvalueRs_SI10
, do_ldst_cop
},
689 {"sub", 0x00000014, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
690 {"sub.c", 0x00000015, 0x3e0003ff, 0x2001, Rd_Rs_Rs
, do_rdrsrs
},
691 {"sub.s", 0x38000049, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
692 {"subc", 0x00000016, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
693 {"subc.c", 0x00000017, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
694 {"sub!", 0x2001, 0x700f, 0x00000015, Rd_Rs
, do16_rdrs
},
695 {"subei!", 0x6080, 0x7087, 0x02000001, Rd_I4
, do16_rdi4
},
696 {"sw!", 0x200c, 0x700f, 0x28000000, Rd_lvalueRs
, do16_ldst_insn
},
697 {"swp!", 0x7004, 0x7007, 0x28000000, Rd_lvalueBP_I5
, do16_ldst_imm_insn
},
698 {"syscall", 0x00000002, 0x3e0003ff, 0x8000, I15
, do_i15
},
699 {"tcs", 0x00000054, 0x3e007fff, 0x0005, NO_OPD
, do_empty
},
700 {"tcc", 0x00000454, 0x3e007fff, 0x0105, NO_OPD
, do_empty
},
701 {"tcnz", 0x00003854, 0x3e007fff, 0x0e05, NO_OPD
, do_empty
},
702 {"tcs!", 0x0005, 0x7f0f, 0x00000054, NO16_OPD
, do_empty
},
703 {"tcc!", 0x0105, 0x7f0f, 0x00000454, NO16_OPD
, do_empty
},
704 {"tcnz!", 0x0e05, 0x7f0f, 0x00003854, NO16_OPD
, do_empty
},
705 {"teq", 0x00001054, 0x3e007fff, 0x0405, NO_OPD
, do_empty
},
706 {"teq!", 0x0405, 0x7f0f, 0x00001054, NO16_OPD
, do_empty
},
707 {"tgtu", 0x00000854, 0x3e007fff, 0x0205, NO_OPD
, do_empty
},
708 {"tgt", 0x00001854, 0x3e007fff, 0x0605, NO_OPD
, do_empty
},
709 {"tge", 0x00002054, 0x3e007fff, 0x0805, NO_OPD
, do_empty
},
710 {"tgtu!", 0x0205, 0x7f0f, 0x00000854, NO16_OPD
, do_empty
},
711 {"tgt!", 0x0605, 0x7f0f, 0x00001854, NO16_OPD
, do_empty
},
712 {"tge!", 0x0805, 0x7f0f, 0x00002054, NO16_OPD
, do_empty
},
713 {"tleu", 0x00000c54, 0x3e007fff, 0x0305, NO_OPD
, do_empty
},
714 {"tle", 0x00001c54, 0x3e007fff, 0x0705, NO_OPD
, do_empty
},
715 {"tlt", 0x00002454, 0x3e007fff, 0x0905, NO_OPD
, do_empty
},
716 {"stlb", 0x0c000004, 0x3e0003ff, 0x8000, NO_OPD
, do_empty
},
717 {"mftlb", 0x0c000024, 0x3e0003ff, 0x8000, NO_OPD
, do_empty
},
718 {"mtptlb", 0x0c000044, 0x3e0003ff, 0x8000, NO_OPD
, do_empty
},
719 {"mtrtlb", 0x0c000064, 0x3e0003ff, 0x8000, NO_OPD
, do_empty
},
720 {"tleu!", 0x0305, 0x7f0f, 0x00000c54, NO16_OPD
, do_empty
},
721 {"tle!", 0x0705, 0x7f0f, 0x00001c54, NO16_OPD
, do_empty
},
722 {"tlt!", 0x0905, 0x7f0f, 0x00002454, NO16_OPD
, do_empty
},
723 {"tmi", 0x00002854, 0x3e007fff, 0x0a05, NO_OPD
, do_empty
},
724 {"tmi!", 0x0a05, 0x7f0f, 0x00002854, NO16_OPD
, do_empty
},
725 {"tne", 0x00001454, 0x3e007fff, 0x0505, NO_OPD
, do_empty
},
726 {"tne!", 0x0505, 0x7f0f, 0x00001454, NO16_OPD
, do_empty
},
727 {"tpl", 0x00002c54, 0x3e007fff, 0x0b05, NO_OPD
, do_empty
},
728 {"tpl!", 0x0b05, 0x7f0f, 0x00002c54, NO16_OPD
, do_empty
},
729 {"trapcs", 0x00000004, 0x3e007fff, 0x8000, x_I5_x
, do_xi5x
},
730 {"trapcc", 0x00000404, 0x3e007fff, 0x8000, x_I5_x
, do_xi5x
},
731 {"trapgtu", 0x00000804, 0x3e007fff, 0x8000, x_I5_x
, do_xi5x
},
732 {"trapleu", 0x00000c04, 0x3e007fff, 0x8000, x_I5_x
, do_xi5x
},
733 {"trapeq", 0x00001004, 0x3e007fff, 0x8000, x_I5_x
, do_xi5x
},
734 {"trapne", 0x00001404, 0x3e007fff, 0x8000, x_I5_x
, do_xi5x
},
735 {"trapgt", 0x00001804, 0x3e007fff, 0x8000, x_I5_x
, do_xi5x
},
736 {"traple", 0x00001c04, 0x3e007fff, 0x8000, x_I5_x
, do_xi5x
},
737 {"trapge", 0x00002004, 0x3e007fff, 0x8000, x_I5_x
, do_xi5x
},
738 {"traplt", 0x00002404, 0x3e007fff, 0x8000, x_I5_x
, do_xi5x
},
739 {"trapmi", 0x00002804, 0x3e007fff, 0x8000, x_I5_x
, do_xi5x
},
740 {"trappl", 0x00002c04, 0x3e007fff, 0x8000, x_I5_x
, do_xi5x
},
741 {"trapvs", 0x00003004, 0x3e007fff, 0x8000, x_I5_x
, do_xi5x
},
742 {"trapvc", 0x00003404, 0x3e007fff, 0x8000, x_I5_x
, do_xi5x
},
743 {"trap", 0x00003c04, 0x3e007fff, 0x8000, x_I5_x
, do_xi5x
},
744 {"tset", 0x00003c54, 0x3e007fff, 0x0f05, NO_OPD
, do_empty
},
745 {"tset!", 0x0f05, 0x00007f0f, 0x00003c54, NO16_OPD
, do_empty
},
746 {"tvs", 0x00003054, 0x3e007fff, 0x0c05, NO_OPD
, do_empty
},
747 {"tvc", 0x00003454, 0x3e007fff, 0x0d05, NO_OPD
, do_empty
},
748 {"tvs!", 0x0c05, 0x7f0f, 0x00003054, NO16_OPD
, do_empty
},
749 {"tvc!", 0x0d05, 0x7f0f, 0x00003454, NO16_OPD
, do_empty
},
750 {"xor", 0x00000026, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
751 {"xor.c", 0x00000027, 0x3e0003ff, 0x2007, Rd_Rs_Rs
, do_rdrsrs
},
752 {"xor!", 0x2007, 0x700f, 0x00000027, Rd_Rs
, do16_rdrs
},
753 /* Macro instruction. */
754 {"li", 0x020c0000, 0x3e0e0000, 0x8000, Insn_Type_SYN
, do_macro_li_rdi32
},
755 /* la reg, imm32 -->(1) ldi reg, simm16
756 (2) ldis reg, %HI(imm32)
759 la reg, symbol -->(1) lis reg, %HI(imm32)
760 ori reg, %LO(imm32) */
761 {"la", 0x020c0000, 0x3e0e0000, 0x8000, Insn_Type_SYN
, do_macro_la_rdi32
},
762 {"div", 0x00000044, 0x3e0003ff, 0x8000, Insn_Type_SYN
, do_macro_mul_rdrsrs
},
763 {"divu", 0x00000046, 0x3e0003ff, 0x8000, Insn_Type_SYN
, do_macro_mul_rdrsrs
},
764 {"rem", 0x00000044, 0x3e0003ff, 0x8000, Insn_Type_SYN
, do_macro_mul_rdrsrs
},
765 {"remu", 0x00000046, 0x3e0003ff, 0x8000, Insn_Type_SYN
, do_macro_mul_rdrsrs
},
766 {"mul", 0x00000040, 0x3e0003ff, 0x8000, Insn_Type_SYN
, do_macro_mul_rdrsrs
},
767 {"mulu", 0x00000042, 0x3e0003ff, 0x8000, Insn_Type_SYN
, do_macro_mul_rdrsrs
},
768 {"maz", 0x00000040, 0x3e0003ff, 0x8000, Insn_Type_SYN
, do_macro_mul_rdrsrs
},
769 {"mazu", 0x00000042, 0x3e0003ff, 0x8000, Insn_Type_SYN
, do_macro_mul_rdrsrs
},
770 {"mul.f", 0x00000041, 0x3e0003ff, 0x8000, Insn_Type_SYN
, do_macro_mul_rdrsrs
},
771 {"maz.f", 0x00000041, 0x3e0003ff, 0x8000, Insn_Type_SYN
, do_macro_mul_rdrsrs
},
772 {"lb", INSN_LB
, 0x00000000, 0x8000, Insn_Type_SYN
, do_macro_ldst_label
},
773 {"lbu", INSN_LBU
, 0x00000000, 0x200b, Insn_Type_SYN
, do_macro_ldst_label
},
774 {"lh", INSN_LH
, 0x00000000, 0x2009, Insn_Type_SYN
, do_macro_ldst_label
},
775 {"lhu", INSN_LHU
, 0x00000000, 0x8000, Insn_Type_SYN
, do_macro_ldst_label
},
776 {"lw", INSN_LW
, 0x00000000, 0x2008, Insn_Type_SYN
, do_macro_ldst_label
},
777 {"sb", INSN_SB
, 0x00000000, 0x200f, Insn_Type_SYN
, do_macro_ldst_label
},
778 {"sh", INSN_SH
, 0x00000000, 0x200d, Insn_Type_SYN
, do_macro_ldst_label
},
779 {"sw", INSN_SW
, 0x00000000, 0x200c, Insn_Type_SYN
, do_macro_ldst_label
},
780 /* Assembler use internal. */
781 {"ld_i32hi", 0x0a0c0000, 0x3e0e0000, 0x8000, Insn_internal
, do_macro_rdi32hi
},
782 {"ld_i32lo", 0x020a0000, 0x3e0e0001, 0x8000, Insn_internal
, do_macro_rdi32lo
},
783 {"ldis_pic", 0x0a0c0000, 0x3e0e0000, 0x5000, Insn_internal
, do_rdi16_pic
},
784 {"addi_s_pic",0x02000000, 0x3e0e0001, 0x8000, Insn_internal
, do_addi_s_pic
},
785 {"addi_u_pic",0x02000000, 0x3e0e0001, 0x8000, Insn_internal
, do_addi_u_pic
},
786 {"lw_pic", 0x20000000, 0x3e000000, 0x2008, Insn_internal
, do_lw_pic
},
789 /* Next free entry in the pool. */
790 int next_literal_pool_place
= 0;
792 /* Next literal pool number. */
793 int lit_pool_num
= 1;
794 symbolS
*current_poolP
= NULL
;
797 end_of_line (char *str
)
799 int retval
= SUCCESS
;
801 skip_whitespace (str
);
807 inst
.error
= BAD_GARBAGE
;
814 score_reg_parse (char **ccp
, struct hash_control
*htab
)
819 struct reg_entry
*reg
;
822 if (!ISALPHA (*p
) || !is_name_beginner (*p
))
827 while (ISALPHA (c
) || ISDIGIT (c
) || c
== '_')
831 reg
= (struct reg_entry
*) hash_find (htab
, start
);
842 /* If shift <= 0, only return reg. */
845 reg_required_here (char **str
, int shift
, enum score_reg_type reg_type
)
847 static char buff
[MAX_LITERAL_POOL_SIZE
];
848 int reg
= (int) FAIL
;
851 if ((reg
= score_reg_parse (str
, all_reg_maps
[reg_type
].htab
)) != (int) FAIL
)
853 if (reg_type
== REG_TYPE_SCORE
)
855 if ((reg
== 1) && (nor1
== 1) && (inst
.bwarn
== 0))
857 as_warn ("Using temp register(r1)");
863 if (reg_type
== REG_TYPE_SCORE_CR
)
864 strcpy (inst
.reg
, score_crn_table
[reg
].name
);
865 else if (reg_type
== REG_TYPE_SCORE_SR
)
866 strcpy (inst
.reg
, score_srn_table
[reg
].name
);
868 strcpy (inst
.reg
, "");
870 inst
.instruction
|= reg
<< shift
;
876 sprintf (buff
, _("register expected, not '%.100s'"), start
);
884 skip_past_comma (char **str
)
890 while ((c
= *p
) == ' ' || c
== ',')
893 if (c
== ',' && comma
++)
895 inst
.error
= BAD_SKIP_COMMA
;
900 if ((c
== '\0') || (comma
== 0))
902 inst
.error
= BAD_SKIP_COMMA
;
907 return comma
? SUCCESS
: (int) FAIL
;
911 do_rdrsrs (char *str
)
913 skip_whitespace (str
);
915 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) == (int) FAIL
916 || skip_past_comma (&str
) == (int) FAIL
917 || reg_required_here (&str
, 15, REG_TYPE_SCORE
) == (int) FAIL
918 || skip_past_comma (&str
) == (int) FAIL
919 || reg_required_here (&str
, 10, REG_TYPE_SCORE
) == (int) FAIL
920 || end_of_line (str
) == (int) FAIL
)
926 if ((((inst
.instruction
>> 15) & 0x10) == 0)
927 && (((inst
.instruction
>> 10) & 0x10) == 0)
928 && (((inst
.instruction
>> 20) & 0x10) == 0)
929 && (inst
.relax_inst
!= 0x8000)
930 && (((inst
.instruction
>> 20) & 0xf) == ((inst
.instruction
>> 15) & 0xf)))
932 inst
.relax_inst
|= (((inst
.instruction
>> 10) & 0xf) << 4)
933 | (((inst
.instruction
>> 15) & 0xf) << 8);
938 inst
.relax_inst
= 0x8000;
944 walk_no_bignums (symbolS
* sp
)
946 if (symbol_get_value_expression (sp
)->X_op
== O_big
)
949 if (symbol_get_value_expression (sp
)->X_add_symbol
)
950 return (walk_no_bignums (symbol_get_value_expression (sp
)->X_add_symbol
)
951 || (symbol_get_value_expression (sp
)->X_op_symbol
952 && walk_no_bignums (symbol_get_value_expression (sp
)->X_op_symbol
)));
958 my_get_expression (expressionS
* ep
, char **str
)
963 save_in
= input_line_pointer
;
964 input_line_pointer
= *str
;
965 in_my_get_expression
= 1;
966 seg
= expression (ep
);
967 in_my_get_expression
= 0;
969 if (ep
->X_op
== O_illegal
)
971 *str
= input_line_pointer
;
972 input_line_pointer
= save_in
;
973 inst
.error
= _("illegal expression");
976 /* Get rid of any bignums now, so that we don't generate an error for which
977 we can't establish a line number later on. Big numbers are never valid
978 in instructions, which is where this routine is always called. */
979 if (ep
->X_op
== O_big
981 && (walk_no_bignums (ep
->X_add_symbol
)
982 || (ep
->X_op_symbol
&& walk_no_bignums (ep
->X_op_symbol
)))))
984 inst
.error
= _("invalid constant");
985 *str
= input_line_pointer
;
986 input_line_pointer
= save_in
;
990 if ((ep
->X_add_symbol
!= NULL
)
991 && (inst
.type
!= PC_DISP19div2
)
992 && (inst
.type
!= PC_DISP8div2
)
993 && (inst
.type
!= PC_DISP24div2
)
994 && (inst
.type
!= PC_DISP11div2
)
995 && (inst
.type
!= Insn_Type_SYN
)
996 && (inst
.type
!= Rd_rvalueRs_SI15
)
997 && (inst
.type
!= Rd_lvalueRs_SI15
)
998 && (inst
.type
!= Insn_internal
))
1000 inst
.error
= BAD_ARGS
;
1001 *str
= input_line_pointer
;
1002 input_line_pointer
= save_in
;
1006 *str
= input_line_pointer
;
1007 input_line_pointer
= save_in
;
1011 /* Check if an immediate is valid. If so, convert it to the right format. */
1014 validate_immediate (int val
, unsigned int data_type
)
1020 int val_hi
= ((val
& 0xffff0000) >> 16);
1022 if (score_df_range
[data_type
].range
[0] <= val_hi
1023 && val_hi
<= score_df_range
[data_type
].range
[1])
1030 int val_lo
= (val
& 0xffff);
1032 if (score_df_range
[data_type
].range
[0] <= val_lo
1033 && val_lo
<= score_df_range
[data_type
].range
[1])
1043 if (data_type
== _SIMM14_NEG
|| data_type
== _SIMM16_NEG
|| data_type
== _IMM16_NEG
)
1046 if (score_df_range
[data_type
].range
[0] <= val
1047 && val
<= score_df_range
[data_type
].range
[1])
1057 data_op2 (char **str
, int shift
, enum score_data_type data_type
)
1060 char data_exp
[MAX_LITERAL_POOL_SIZE
];
1065 skip_whitespace (*str
);
1069 while ((*dataptr
!= '\0') && (*dataptr
!= '|') && (cnt
<= MAX_LITERAL_POOL_SIZE
)) /* 0x7c = ='|' */
1071 data_exp
[cnt
] = *dataptr
;
1076 data_exp
[cnt
] = '\0';
1077 pp
= (char *)&data_exp
;
1079 if (*dataptr
== '|') /* process PCE */
1081 if (my_get_expression (&inst
.reloc
.exp
, &pp
) == (int) FAIL
)
1084 if (inst
.error
!= 0)
1085 return (int) FAIL
; /* to ouptut_inst to printf out the error */
1088 else /* process 16 bit */
1090 if (my_get_expression (&inst
.reloc
.exp
, str
) == (int) FAIL
)
1095 dataptr
= (char *)data_exp
;
1096 for (; *dataptr
!= '\0'; dataptr
++)
1098 *dataptr
= TOLOWER (*dataptr
);
1099 if (*dataptr
== '!' || *dataptr
== ' ')
1102 dataptr
= (char *)data_exp
;
1104 if ((*dataptr
== '0') && (*(dataptr
+ 1) == 'x')
1105 && (data_type
!= _SIMM16_LA
)
1106 && (data_type
!= _VALUE_HI16
)
1107 && (data_type
!= _VALUE_LO16
)
1108 && (data_type
!= _IMM16
)
1109 && (data_type
!= _IMM15
)
1110 && (data_type
!= _IMM14
)
1111 && (data_type
!= _IMM4
)
1112 && (data_type
!= _IMM5
)
1113 && (data_type
!= _IMM8
)
1114 && (data_type
!= _IMM5_RSHIFT_1
)
1115 && (data_type
!= _IMM5_RSHIFT_2
)
1116 && (data_type
!= _SIMM14_NEG
)
1117 && (data_type
!= _IMM10_RSHIFT_2
)
1118 && (data_type
!= _GP_IMM15
))
1123 if ((inst
.reloc
.exp
.X_add_number
== 0)
1124 && (inst
.type
!= Insn_Type_SYN
)
1125 && (inst
.type
!= Rd_rvalueRs_SI15
)
1126 && (inst
.type
!= Rd_lvalueRs_SI15
)
1127 && (inst
.type
!= Insn_internal
)
1128 && (((*dataptr
>= 'a') && (*dataptr
<= 'z'))
1129 || ((*dataptr
== '0') && (*(dataptr
+ 1) == 'x') && (*(dataptr
+ 2) != '0'))
1130 || ((*dataptr
== '+') && (*(dataptr
+ 1) != '0'))
1131 || ((*dataptr
== '-') && (*(dataptr
+ 1) != '0'))))
1133 inst
.error
= BAD_ARGS
;
1138 if ((inst
.reloc
.exp
.X_add_symbol
)
1139 && ((data_type
== _SIMM16
)
1140 || (data_type
== _SIMM16_NEG
)
1141 || (data_type
== _IMM16_NEG
)
1142 || (data_type
== _SIMM14
)
1143 || (data_type
== _SIMM14_NEG
)
1144 || (data_type
== _IMM5
)
1145 || (data_type
== _IMM14
)
1146 || (data_type
== _IMM20
)
1147 || (data_type
== _IMM16
)
1148 || (data_type
== _IMM15
)
1149 || (data_type
== _IMM4
)))
1151 inst
.error
= BAD_ARGS
;
1155 if (inst
.reloc
.exp
.X_add_symbol
)
1162 inst
.reloc
.type
= BFD_RELOC_HI16_S
;
1163 inst
.reloc
.pc_rel
= 0;
1166 inst
.reloc
.type
= BFD_RELOC_LO16
;
1167 inst
.reloc
.pc_rel
= 0;
1170 inst
.reloc
.type
= BFD_RELOC_SCORE_GPREL15
;
1171 inst
.reloc
.pc_rel
= 0;
1174 case _IMM16_LO16_pic
:
1175 inst
.reloc
.type
= BFD_RELOC_SCORE_GOT_LO16
;
1176 inst
.reloc
.pc_rel
= 0;
1179 inst
.reloc
.type
= BFD_RELOC_32
;
1180 inst
.reloc
.pc_rel
= 0;
1186 if (data_type
== _IMM16_pic
)
1188 inst
.reloc
.type
= BFD_RELOC_SCORE_DUMMY_HI16
;
1189 inst
.reloc
.pc_rel
= 0;
1192 if (data_type
== _SIMM16_LA
&& inst
.reloc
.exp
.X_unsigned
== 1)
1194 value
= validate_immediate (inst
.reloc
.exp
.X_add_number
, _SIMM16_LA_POS
);
1195 if (value
== (int) FAIL
) /* for advance to check if this is ldis */
1196 if ((inst
.reloc
.exp
.X_add_number
& 0xffff) == 0)
1198 inst
.instruction
|= 0x8000000;
1199 inst
.instruction
|= ((inst
.reloc
.exp
.X_add_number
>> 16) << 1) & 0x1fffe;
1205 value
= validate_immediate (inst
.reloc
.exp
.X_add_number
, data_type
);
1208 if (value
== (int) FAIL
)
1212 if ((data_type
!= _SIMM14_NEG
) && (data_type
!= _SIMM16_NEG
) && (data_type
!= _IMM16_NEG
))
1215 "invalid constant: %d bit expression not in range %d..%d",
1216 score_df_range
[data_type
].bits
,
1217 score_df_range
[data_type
].range
[0], score_df_range
[data_type
].range
[1]);
1222 "invalid constant: %d bit expression not in range %d..%d",
1223 score_df_range
[data_type
].bits
,
1224 -score_df_range
[data_type
].range
[1], -score_df_range
[data_type
].range
[0]);
1227 inst
.error
= _(err_msg
);
1231 if ((score_df_range
[data_type
].range
[0] != 0) || (data_type
== _IMM5_RANGE_8_31
))
1233 value
&= (1 << score_df_range
[data_type
].bits
) - 1;
1236 inst
.instruction
|= value
<< shift
;
1239 if ((inst
.instruction
& 0xf0000000) == 0x30000000)
1241 if ((((inst
.instruction
>> 20) & 0x1F) != 0)
1242 && (((inst
.instruction
>> 20) & 0x1F) != 1)
1243 && (((inst
.instruction
>> 20) & 0x1F) != 2)
1244 && (((inst
.instruction
>> 20) & 0x1F) != 3)
1245 && (((inst
.instruction
>> 20) & 0x1F) != 4)
1246 && (((inst
.instruction
>> 20) & 0x1F) != 8)
1247 && (((inst
.instruction
>> 20) & 0x1F) != 9)
1248 && (((inst
.instruction
>> 20) & 0x1F) != 0xa)
1249 && (((inst
.instruction
>> 20) & 0x1F) != 0xb)
1250 && (((inst
.instruction
>> 20) & 0x1F) != 0xc)
1251 && (((inst
.instruction
>> 20) & 0x1F) != 0xd)
1252 && (((inst
.instruction
>> 20) & 0x1F) != 0xe)
1253 && (((inst
.instruction
>> 20) & 0x1F) != 0x10)
1254 && (((inst
.instruction
>> 20) & 0x1F) != 0x11)
1255 && (((inst
.instruction
>> 20) & 0x1F) != 0x18)
1256 && (((inst
.instruction
>> 20) & 0x1F) != 0x1A)
1257 && (((inst
.instruction
>> 20) & 0x1F) != 0x1B)
1258 && (((inst
.instruction
>> 20) & 0x1F) != 0x1d)
1259 && (((inst
.instruction
>> 20) & 0x1F) != 0x1e)
1260 && (((inst
.instruction
>> 20) & 0x1F) != 0x1f))
1264 sprintf (err_msg
, "invalid constant: bit expression not defined");
1265 inst
.error
= _(err_msg
);
1273 /* Handle addi/addi.c/addis.c/cmpi.c/addis.c/ldi. */
1276 do_rdsi16 (char *str
)
1278 skip_whitespace (str
);
1280 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) == (int) FAIL
1281 || skip_past_comma (&str
) == (int) FAIL
1282 || data_op2 (&str
, 1, _SIMM16
) == (int) FAIL
1283 || end_of_line (str
) == (int) FAIL
)
1287 if ((inst
.instruction
& 0x20c0000) == 0x20c0000)
1289 if ((((inst
.instruction
>> 20) & 0x10) == 0x10) || ((inst
.instruction
& 0x1fe00) != 0))
1291 inst
.relax_inst
= 0x8000;
1295 inst
.relax_inst
|= (inst
.instruction
>> 1) & 0xff;
1296 inst
.relax_inst
|= (((inst
.instruction
>> 20) & 0xf) << 8);
1297 inst
.relax_size
= 2;
1300 else if (((inst
.instruction
>> 20) & 0x10) == 0x10)
1302 inst
.relax_inst
= 0x8000;
1306 /* Handle subi/subi.c. */
1309 do_sub_rdsi16 (char *str
)
1311 skip_whitespace (str
);
1313 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) != (int) FAIL
1314 && skip_past_comma (&str
) != (int) FAIL
1315 && data_op2 (&str
, 1, _SIMM16_NEG
) != (int) FAIL
)
1319 /* Handle subis/subis.c. */
1322 do_sub_rdi16 (char *str
)
1324 skip_whitespace (str
);
1326 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) != (int) FAIL
1327 && skip_past_comma (&str
) != (int) FAIL
1328 && data_op2 (&str
, 1, _IMM16_NEG
) != (int) FAIL
)
1332 /* Handle addri/addri.c. */
1335 do_rdrssi14 (char *str
) /* -(2^13)~((2^13)-1) */
1337 skip_whitespace (str
);
1339 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) != (int) FAIL
1340 && skip_past_comma (&str
) != (int) FAIL
1341 && reg_required_here (&str
, 15, REG_TYPE_SCORE
) != (int) FAIL
1342 && skip_past_comma (&str
) != (int) FAIL
)
1343 data_op2 (&str
, 1, _SIMM14
);
1346 /* Handle subri.c/subri. */
1348 do_sub_rdrssi14 (char *str
) /* -(2^13)~((2^13)-1) */
1350 skip_whitespace (str
);
1352 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) != (int) FAIL
1353 && skip_past_comma (&str
) != (int) FAIL
1354 && reg_required_here (&str
, 15, REG_TYPE_SCORE
) != (int) FAIL
1355 && skip_past_comma (&str
) != (int) FAIL
1356 && data_op2 (&str
, 1, _SIMM14_NEG
) != (int) FAIL
)
1360 /* Handle bitclr.c/bitset.c/bittgl.c/slli.c/srai.c/srli.c/roli.c/rori.c/rolic.c. */
1362 do_rdrsi5 (char *str
) /* 0~((2^14)-1) */
1364 skip_whitespace (str
);
1366 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) == (int) FAIL
1367 || skip_past_comma (&str
) == (int) FAIL
1368 || reg_required_here (&str
, 15, REG_TYPE_SCORE
) == (int) FAIL
1369 || skip_past_comma (&str
) == (int) FAIL
1370 || data_op2 (&str
, 10, _IMM5
) == (int) FAIL
1371 || end_of_line (str
) == (int) FAIL
)
1374 if ((((inst
.instruction
>> 20) & 0x1f) == ((inst
.instruction
>> 15) & 0x1f))
1375 && (inst
.relax_inst
!= 0x8000) && (((inst
.instruction
>> 15) & 0x10) == 0))
1377 inst
.relax_inst
|= (((inst
.instruction
>> 10) & 0x1f) << 3) | (((inst
.instruction
>> 15) & 0xf) << 8);
1378 inst
.relax_size
= 2;
1381 inst
.relax_inst
= 0x8000;
1384 /* Handle andri/orri/andri.c/orri.c. */
1387 do_rdrsi14 (char *str
) /* 0 ~ ((2^14)-1) */
1389 skip_whitespace (str
);
1391 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) != (int) FAIL
1392 && skip_past_comma (&str
) != (int) FAIL
1393 && reg_required_here (&str
, 15, REG_TYPE_SCORE
) != (int) FAIL
1394 && skip_past_comma (&str
) != (int) FAIL
1395 && data_op2 (&str
, 1, _IMM14
) != (int) FAIL
)
1399 /* Handle bittst.c. */
1401 do_xrsi5 (char *str
)
1403 skip_whitespace (str
);
1405 if (reg_required_here (&str
, 15, REG_TYPE_SCORE
) == (int) FAIL
1406 || skip_past_comma (&str
) == (int) FAIL
1407 || data_op2 (&str
, 10, _IMM5
) == (int) FAIL
1408 || end_of_line (str
) == (int) FAIL
)
1411 if ((inst
.relax_inst
!= 0x8000) && (((inst
.instruction
>> 15) & 0x10) == 0))
1413 inst
.relax_inst
|= (((inst
.instruction
>> 10) & 0x1f) << 3) | (((inst
.instruction
>> 15) & 0xf) << 8);
1414 inst
.relax_size
= 2;
1417 inst
.relax_inst
= 0x8000;
1420 /* Handle andi/ori/andis/oris/ldis. */
1422 do_rdi16 (char *str
)
1424 skip_whitespace (str
);
1426 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) == (int) FAIL
1427 || skip_past_comma (&str
) == (int) FAIL
1428 || data_op2 (&str
, 1, _IMM16
) == (int) FAIL
1429 || end_of_line (str
) == (int) FAIL
)
1432 if (((inst
.instruction
& 0xa0dfffe) != 0xa0c0000) || ((((inst
.instruction
>> 20) & 0x1f) & 0x10) == 0x10))
1433 inst
.relax_inst
= 0x8000;
1435 inst
.relax_size
= 2;
1439 do_macro_rdi32hi (char *str
)
1441 skip_whitespace (str
);
1443 /* Do not handle end_of_line(). */
1444 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) != (int) FAIL
1445 && skip_past_comma (&str
) != (int) FAIL
)
1446 data_op2 (&str
, 1, _VALUE_HI16
);
1450 do_macro_rdi32lo (char *str
)
1452 skip_whitespace (str
);
1454 /* Do not handle end_of_line(). */
1455 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) != (int) FAIL
1456 && skip_past_comma (&str
) != (int) FAIL
)
1457 data_op2 (&str
, 1, _VALUE_LO16
);
1460 /* Handle ldis_pic. */
1463 do_rdi16_pic (char *str
)
1465 skip_whitespace (str
);
1467 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) != (int) FAIL
1468 && skip_past_comma (&str
) != (int) FAIL
1469 && data_op2 (&str
, 1, _IMM16_pic
) != (int) FAIL
)
1473 /* Handle addi_s_pic to generate R_SCORE_GOT_LO16 . */
1476 do_addi_s_pic (char *str
)
1478 skip_whitespace (str
);
1480 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) != (int) FAIL
1481 && skip_past_comma (&str
) != (int) FAIL
1482 && data_op2 (&str
, 1, _SIMM16_pic
) != (int) FAIL
)
1486 /* Handle addi_u_pic to generate R_SCORE_GOT_LO16 . */
1489 do_addi_u_pic (char *str
)
1491 skip_whitespace (str
);
1493 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) != (int) FAIL
1494 && skip_past_comma (&str
) != (int) FAIL
1495 && data_op2 (&str
, 1, _IMM16_LO16_pic
) != (int) FAIL
)
1499 /* Handle mfceh/mfcel/mtceh/mtchl. */
1504 skip_whitespace (str
);
1506 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) != (int) FAIL
)
1513 skip_whitespace (str
);
1515 if (reg_required_here (&str
, 15, REG_TYPE_SCORE
) == (int) FAIL
1516 || end_of_line (str
) == (int) FAIL
)
1519 if ((inst
.relax_inst
!= 0x8000) && (((inst
.instruction
>> 15) & 0x10) == 0))
1521 inst
.relax_inst
|= (((inst
.instruction
>> 10) & 0xf) << 8) | (((inst
.instruction
>> 15) & 0xf) << 4);
1522 inst
.relax_size
= 2;
1525 inst
.relax_inst
= 0x8000;
1531 skip_whitespace (str
);
1533 if (data_op2 (&str
, 10, _IMM15
) != (int) FAIL
)
1540 skip_whitespace (str
);
1542 if (data_op2 (&str
, 15, _IMM5
) == (int) FAIL
|| end_of_line (str
) == (int) FAIL
)
1545 if (inst
.relax_inst
!= 0x8000)
1547 inst
.relax_inst
|= (((inst
.instruction
>> 15) & 0x1f) << 3);
1548 inst
.relax_size
= 2;
1555 skip_whitespace (str
);
1557 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) == (int) FAIL
1558 || skip_past_comma (&str
) == (int) FAIL
1559 || reg_required_here (&str
, 15, REG_TYPE_SCORE
) == (int) FAIL
1560 || end_of_line (str
) == (int) FAIL
)
1563 if (inst
.relax_inst
!= 0x8000)
1565 if (((inst
.instruction
& 0x7f) == 0x56)) /* adjust mv -> mv! / mlfh! / mhfl! */
1568 if ((((inst
.instruction
>> 15) & 0x10) != 0x0) && (((inst
.instruction
>> 20) & 0x10) == 0))
1570 inst
.relax_inst
= 0x00000001 | (((inst
.instruction
>> 15) & 0xf) << 4)
1571 | (((inst
.instruction
>> 20) & 0xf) << 8);
1572 inst
.relax_size
= 2;
1575 else if ((((inst
.instruction
>> 15) & 0x10) == 0x0) && ((inst
.instruction
>> 20) & 0x10) != 0)
1577 inst
.relax_inst
= 0x00000002 | (((inst
.instruction
>> 15) & 0xf) << 4)
1578 | (((inst
.instruction
>> 20) & 0xf) << 8);
1579 inst
.relax_size
= 2;
1581 else if ((((inst
.instruction
>> 15) & 0x10) == 0x0) && (((inst
.instruction
>> 20) & 0x10) == 0))
1583 inst
.relax_inst
|= (((inst
.instruction
>> 15) & 0xf) << 4)
1584 | (((inst
.instruction
>> 20) & 0xf) << 8);
1585 inst
.relax_size
= 2;
1589 inst
.relax_inst
= 0x8000;
1592 else if ((((inst
.instruction
>> 15) & 0x10) == 0x0) && (((inst
.instruction
>> 20) & 0x10) == 0))
1594 inst
.relax_inst
|= (((inst
.instruction
>> 15) & 0xf) << 4)
1595 | (((inst
.instruction
>> 20) & 0xf) << 8);
1596 inst
.relax_size
= 2;
1600 inst
.relax_inst
= 0x8000;
1605 /* Handle mfcr/mtcr. */
1607 do_rdcrs (char *str
)
1609 skip_whitespace (str
);
1611 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) != (int) FAIL
1612 && skip_past_comma (&str
) != (int) FAIL
1613 && reg_required_here (&str
, 15, REG_TYPE_SCORE_CR
) != (int) FAIL
)
1617 /* Handle mfsr/mtsr. */
1620 do_rdsrs (char *str
)
1622 skip_whitespace (str
);
1625 if ((inst
.instruction
& 0xff) == 0x50)
1627 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) != (int) FAIL
1628 && skip_past_comma (&str
) != (int) FAIL
1629 && reg_required_here (&str
, 10, REG_TYPE_SCORE_SR
) != (int) FAIL
)
1634 if (reg_required_here (&str
, 15, REG_TYPE_SCORE
) != (int) FAIL
1635 && skip_past_comma (&str
) != (int) FAIL
)
1636 reg_required_here (&str
, 10, REG_TYPE_SCORE_SR
);
1643 do_rdxrs (char *str
)
1645 skip_whitespace (str
);
1647 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) == (int) FAIL
1648 || skip_past_comma (&str
) == (int) FAIL
1649 || reg_required_here (&str
, 10, REG_TYPE_SCORE
) == (int) FAIL
1650 || end_of_line (str
) == (int) FAIL
)
1653 if ((inst
.relax_inst
!= 0x8000) && (((inst
.instruction
>> 10) & 0x10) == 0)
1654 && (((inst
.instruction
>> 20) & 0x10) == 0))
1656 inst
.relax_inst
|= (((inst
.instruction
>> 10) & 0xf) << 4) | (((inst
.instruction
>> 20) & 0xf) << 8);
1657 inst
.relax_size
= 2;
1660 inst
.relax_inst
= 0x8000;
1663 /* Handle cmp.c/cmp<cond>. */
1667 skip_whitespace (str
);
1669 if (reg_required_here (&str
, 15, REG_TYPE_SCORE
) == (int) FAIL
1670 || skip_past_comma (&str
) == (int) FAIL
1671 || reg_required_here (&str
, 10, REG_TYPE_SCORE
) == (int) FAIL
1672 || end_of_line (str
) == (int) FAIL
)
1675 if ((inst
.relax_inst
!= 0x8000) && (((inst
.instruction
>> 20) & 0x1f) == 3)
1676 && (((inst
.instruction
>> 10) & 0x10) == 0) && (((inst
.instruction
>> 15) & 0x10) == 0))
1678 inst
.relax_inst
|= (((inst
.instruction
>> 10) & 0xf) << 4) | (((inst
.instruction
>> 15) & 0xf) << 8);
1679 inst
.relax_size
= 2;
1682 inst
.relax_inst
= 0x8000;
1686 do_ceinst (char *str
)
1691 skip_whitespace (str
);
1693 if (data_op2 (&str
, 20, _IMM5
) == (int) FAIL
1694 || skip_past_comma (&str
) == (int) FAIL
1695 || reg_required_here (&str
, 15, REG_TYPE_SCORE
) == (int) FAIL
1696 || skip_past_comma (&str
) == (int) FAIL
1697 || reg_required_here (&str
, 10, REG_TYPE_SCORE
) == (int) FAIL
1698 || skip_past_comma (&str
) == (int) FAIL
1699 || data_op2 (&str
, 5, _IMM5
) == (int) FAIL
1700 || skip_past_comma (&str
) == (int) FAIL
1701 || data_op2 (&str
, 0, _IMM5
) == (int) FAIL
1702 || end_of_line (str
) == (int) FAIL
)
1709 if (data_op2 (&str
, 0, _IMM25
) == (int) FAIL
)
1715 reglow_required_here (char **str
, int shift
)
1717 static char buff
[MAX_LITERAL_POOL_SIZE
];
1721 if ((reg
= score_reg_parse (str
, all_reg_maps
[REG_TYPE_SCORE
].htab
)) != (int) FAIL
)
1723 if ((reg
== 1) && (nor1
== 1) && (inst
.bwarn
== 0))
1725 as_warn ("Using temp register(r1)");
1731 inst
.instruction
|= reg
<< shift
;
1737 /* Restore the start point, we may have got a reg of the wrong class. */
1739 sprintf (buff
, _("low register(r0-r15)expected, not '%.100s'"), start
);
1744 /* Handle addc!/add!/and!/cmp!/neg!/not!/or!/sll!/srl!/sra!/xor!/sub!. */
1746 do16_rdrs (char *str
)
1748 skip_whitespace (str
);
1750 if (reglow_required_here (&str
, 8) == (int) FAIL
1751 || skip_past_comma (&str
) == (int) FAIL
1752 || reglow_required_here (&str
, 4) == (int) FAIL
1753 || end_of_line (str
) == (int) FAIL
)
1759 if ((inst
.instruction
& 0x700f) == 0x2003) /* cmp! */
1761 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 15)
1762 | (((inst
.instruction
>> 4) & 0xf) << 10);
1764 else if ((inst
.instruction
& 0x700f) == 0x2006) /* not! */
1766 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 20)
1767 | (((inst
.instruction
>> 4) & 0xf) << 15);
1771 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 20)
1772 | (((inst
.instruction
>> 8) & 0xf) << 15) | (((inst
.instruction
>> 4) & 0xf) << 10);
1774 inst
.relax_size
= 4;
1783 skip_whitespace (str
);
1785 if ((rd
= reglow_required_here (&str
, 4)) == (int) FAIL
1786 || end_of_line (str
) == (int) FAIL
)
1792 inst
.relax_inst
|= rd
<< 20;
1793 inst
.relax_size
= 4;
1797 /* Handle br!/brl!. */
1799 do16_xrs (char *str
)
1801 skip_whitespace (str
);
1803 if (reglow_required_here (&str
, 4) == (int) FAIL
|| end_of_line (str
) == (int) FAIL
)
1809 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 10)
1810 | (((inst
.instruction
>> 4) & 0xf) << 15);
1811 inst
.relax_size
= 4;
1816 reghigh_required_here (char **str
, int shift
)
1818 static char buff
[MAX_LITERAL_POOL_SIZE
];
1822 if ((reg
= score_reg_parse (str
, all_reg_maps
[REG_TYPE_SCORE
].htab
)) != (int) FAIL
)
1824 if (15 < reg
&& reg
< 32)
1827 inst
.instruction
|= (reg
& 0xf) << shift
;
1834 sprintf (buff
, _("high register(r16-r31)expected, not '%.100s'"), start
);
1841 do16_hrdrs (char *str
)
1843 skip_whitespace (str
);
1845 if (reghigh_required_here (&str
, 8) != (int) FAIL
1846 && skip_past_comma (&str
) != (int) FAIL
1847 && reglow_required_here (&str
, 4) != (int) FAIL
1848 && end_of_line (str
) != (int) FAIL
)
1850 inst
.relax_inst
|= ((((inst
.instruction
>> 8) & 0xf) | 0x10) << 20)
1851 | (((inst
.instruction
>> 4) & 0xf) << 15) | (0xf << 10);
1852 inst
.relax_size
= 4;
1858 do16_rdhrs (char *str
)
1860 skip_whitespace (str
);
1862 if (reglow_required_here (&str
, 8) != (int) FAIL
1863 && skip_past_comma (&str
) != (int) FAIL
1864 && reghigh_required_here (&str
, 4) != (int) FAIL
1865 && end_of_line (str
) != (int) FAIL
)
1867 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 20)
1868 | ((((inst
.instruction
>> 4) & 0xf) | 0x10) << 15) | (0xf << 10);
1869 inst
.relax_size
= 4;
1873 /* We need to be able to fix up arbitrary expressions in some statements.
1874 This is so that we can handle symbols that are an arbitrary distance from
1875 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
1876 which returns part of an address in a form which will be valid for
1877 a data instruction. We do this by pushing the expression into a symbol
1878 in the expr_section, and creating a fix for that. */
1880 fix_new_score (fragS
* frag
, int where
, short int size
, expressionS
* exp
, int pc_rel
, int reloc
)
1890 new_fix
= fix_new_exp (frag
, where
, size
, exp
, pc_rel
, reloc
);
1893 new_fix
= fix_new (frag
, where
, size
, make_expr_symbol (exp
), 0, pc_rel
, reloc
);
1900 init_dependency_vector (void)
1904 for (i
= 0; i
< vector_size
; i
++)
1905 memset (&dependency_vector
[i
], '\0', sizeof (dependency_vector
[i
]));
1910 static enum insn_type_for_dependency
1911 dependency_type_from_insn (char *insn_name
)
1913 char name
[INSN_NAME_LEN
];
1914 const struct insn_to_dependency
*tmp
;
1916 strcpy (name
, insn_name
);
1917 tmp
= (const struct insn_to_dependency
*) hash_find (dependency_insn_hsh
, name
);
1926 check_dependency (char *pre_insn
, char *pre_reg
,
1927 char *cur_insn
, char *cur_reg
, int *warn_or_error
)
1931 enum insn_type_for_dependency pre_insn_type
;
1932 enum insn_type_for_dependency cur_insn_type
;
1934 pre_insn_type
= dependency_type_from_insn (pre_insn
);
1935 cur_insn_type
= dependency_type_from_insn (cur_insn
);
1937 for (i
= 0; i
< sizeof (data_dependency_table
) / sizeof (data_dependency_table
[0]); i
++)
1939 if ((pre_insn_type
== data_dependency_table
[i
].pre_insn_type
)
1940 && (D_all_insn
== data_dependency_table
[i
].cur_insn_type
1941 || cur_insn_type
== data_dependency_table
[i
].cur_insn_type
)
1942 && (strcmp (data_dependency_table
[i
].pre_reg
, "") == 0
1943 || strcmp (data_dependency_table
[i
].pre_reg
, pre_reg
) == 0)
1944 && (strcmp (data_dependency_table
[i
].cur_reg
, "") == 0
1945 || strcmp (data_dependency_table
[i
].cur_reg
, cur_reg
) == 0))
1947 bubbles
= (score7
) ? data_dependency_table
[i
].bubblenum_7
: data_dependency_table
[i
].bubblenum_5
;
1948 *warn_or_error
= data_dependency_table
[i
].warn_or_error
;
1957 build_one_frag (struct score_it one_inst
)
1960 int relaxable_p
= g_opt
;
1963 /* Start a new frag if frag_now is not empty. */
1964 if (frag_now_fix () != 0)
1966 if (!frag_now
->tc_frag_data
.is_insn
)
1967 frag_wane (frag_now
);
1973 p
= frag_more (one_inst
.size
);
1974 md_number_to_chars (p
, one_inst
.instruction
, one_inst
.size
);
1977 dwarf2_emit_insn (one_inst
.size
);
1980 relaxable_p
&= (one_inst
.relax_size
!= 0);
1981 relax_size
= relaxable_p
? one_inst
.relax_size
: 0;
1983 p
= frag_var (rs_machine_dependent
, relax_size
+ RELAX_PAD_BYTE
, 0,
1984 RELAX_ENCODE (one_inst
.size
, one_inst
.relax_size
,
1985 one_inst
.type
, 0, 0, relaxable_p
),
1989 md_number_to_chars (p
, one_inst
.relax_inst
, relax_size
);
1993 handle_dependency (struct score_it
*theinst
)
1996 int warn_or_error
= 0; /* warn - 0; error - 1 */
1998 int remainder_bubbles
= 0;
1999 char cur_insn
[INSN_NAME_LEN
];
2000 char pre_insn
[INSN_NAME_LEN
];
2001 struct score_it nop_inst
;
2002 struct score_it pflush_inst
;
2004 nop_inst
.instruction
= 0x0000;
2006 nop_inst
.relax_inst
= 0x80008000;
2007 nop_inst
.relax_size
= 4;
2008 nop_inst
.type
= NO16_OPD
;
2010 pflush_inst
.instruction
= 0x8000800a;
2011 pflush_inst
.size
= 4;
2012 pflush_inst
.relax_inst
= 0x8000;
2013 pflush_inst
.relax_size
= 0;
2014 pflush_inst
.type
= NO_OPD
;
2016 /* pflush will clear all data dependency. */
2017 if (strcmp (theinst
->name
, "pflush") == 0)
2019 init_dependency_vector ();
2023 /* Push current instruction to dependency_vector[0]. */
2024 for (i
= vector_size
- 1; i
> 0; i
--)
2025 memcpy (&dependency_vector
[i
], &dependency_vector
[i
- 1], sizeof (dependency_vector
[i
]));
2027 memcpy (&dependency_vector
[0], theinst
, sizeof (dependency_vector
[i
]));
2029 /* There is no dependency between nop and any instruction. */
2030 if (strcmp (dependency_vector
[0].name
, "nop") == 0
2031 || strcmp (dependency_vector
[0].name
, "nop!") == 0)
2034 /* "pce" is defined in insn_to_dependency_table. */
2035 #define PCE_NAME "pce"
2037 if (dependency_vector
[0].type
== Insn_Type_PCE
)
2038 strcpy (cur_insn
, PCE_NAME
);
2040 strcpy (cur_insn
, dependency_vector
[0].name
);
2042 for (i
= 1; i
< vector_size
; i
++)
2044 /* The element of dependency_vector is NULL. */
2045 if (dependency_vector
[i
].name
[0] == '\0')
2048 if (dependency_vector
[i
].type
== Insn_Type_PCE
)
2049 strcpy (pre_insn
, PCE_NAME
);
2051 strcpy (pre_insn
, dependency_vector
[i
].name
);
2053 bubbles
= check_dependency (pre_insn
, dependency_vector
[i
].reg
,
2054 cur_insn
, dependency_vector
[0].reg
, &warn_or_error
);
2055 remainder_bubbles
= bubbles
- i
+ 1;
2057 if (remainder_bubbles
> 0)
2061 if (fix_data_dependency
== 1)
2063 if (remainder_bubbles
<= 2)
2065 if (warn_fix_data_dependency
)
2066 as_warn ("Fix data dependency: %s %s -- %s %s (insert %d nop!/%d)",
2067 dependency_vector
[i
].name
, dependency_vector
[i
].reg
,
2068 dependency_vector
[0].name
, dependency_vector
[0].reg
,
2069 remainder_bubbles
, bubbles
);
2071 for (j
= (vector_size
- 1); (j
- remainder_bubbles
) > 0; j
--)
2072 memcpy (&dependency_vector
[j
], &dependency_vector
[j
- remainder_bubbles
],
2073 sizeof (dependency_vector
[j
]));
2075 for (j
= 1; j
<= remainder_bubbles
; j
++)
2077 memset (&dependency_vector
[j
], '\0', sizeof (dependency_vector
[j
]));
2079 build_one_frag (nop_inst
);
2084 if (warn_fix_data_dependency
)
2085 as_warn ("Fix data dependency: %s %s -- %s %s (insert 1 pflush/%d)",
2086 dependency_vector
[i
].name
, dependency_vector
[i
].reg
,
2087 dependency_vector
[0].name
, dependency_vector
[0].reg
,
2090 for (j
= 1; j
< vector_size
; j
++)
2091 memset (&dependency_vector
[j
], '\0', sizeof (dependency_vector
[j
]));
2093 /* Insert pflush. */
2094 build_one_frag (pflush_inst
);
2101 as_bad ("data dependency: %s %s -- %s %s (%d/%d bubble)",
2102 dependency_vector
[i
].name
, dependency_vector
[i
].reg
,
2103 dependency_vector
[0].name
, dependency_vector
[0].reg
,
2104 remainder_bubbles
, bubbles
);
2108 as_warn ("data dependency: %s %s -- %s %s (%d/%d bubble)",
2109 dependency_vector
[i
].name
, dependency_vector
[i
].reg
,
2110 dependency_vector
[0].name
, dependency_vector
[0].reg
,
2111 remainder_bubbles
, bubbles
);
2118 static enum insn_class
2119 get_insn_class_from_type (enum score_insn_type type
)
2121 enum insn_class retval
= (int) FAIL
;
2127 case Rd_rvalueBP_I5
:
2128 case Rd_lvalueBP_I5
:
2139 retval
= INSN_CLASS_16
;
2148 case Rd_rvalueRs_SI10
:
2149 case Rd_lvalueRs_SI10
:
2150 case Rd_rvalueRs_preSI12
:
2151 case Rd_rvalueRs_postSI12
:
2152 case Rd_lvalueRs_preSI12
:
2153 case Rd_lvalueRs_postSI12
:
2155 case Rd_rvalueRs_SI15
:
2156 case Rd_lvalueRs_SI15
:
2165 case OP5_rvalueRs_SI15
:
2166 case I5_Rs_Rs_I5_OP5
:
2167 case x_rvalueRs_post4
:
2168 case Rd_rvalueRs_post4
:
2170 case Rd_lvalueRs_post4
:
2171 case x_lvalueRs_post4
:
2179 retval
= INSN_CLASS_32
;
2182 retval
= INSN_CLASS_PCE
;
2185 retval
= INSN_CLASS_SYN
;
2194 static unsigned long
2195 adjust_paritybit (unsigned long m_code
, enum insn_class
class)
2197 unsigned long result
= 0;
2198 unsigned long m_code_high
= 0;
2199 unsigned long m_code_low
= 0;
2200 unsigned long pb_high
= 0;
2201 unsigned long pb_low
= 0;
2203 if (class == INSN_CLASS_32
)
2205 pb_high
= 0x80000000;
2206 pb_low
= 0x00008000;
2208 else if (class == INSN_CLASS_16
)
2213 else if (class == INSN_CLASS_PCE
)
2216 pb_low
= 0x00008000;
2218 else if (class == INSN_CLASS_SYN
)
2220 /* FIXME. at this time, INSN_CLASS_SYN must be 32 bit, but, instruction type should
2221 be changed if macro instruction has been expanded. */
2222 pb_high
= 0x80000000;
2223 pb_low
= 0x00008000;
2230 m_code_high
= m_code
& 0x3fff8000;
2231 m_code_low
= m_code
& 0x00007fff;
2232 result
= pb_high
| (m_code_high
<< 1) | pb_low
| m_code_low
;
2238 gen_insn_frag (struct score_it
*part_1
, struct score_it
*part_2
)
2241 bfd_boolean pce_p
= FALSE
;
2242 int relaxable_p
= g_opt
;
2244 struct score_it
*inst1
= part_1
;
2245 struct score_it
*inst2
= part_2
;
2246 struct score_it backup_inst1
;
2248 pce_p
= (inst2
) ? TRUE
: FALSE
;
2249 memcpy (&backup_inst1
, inst1
, sizeof (struct score_it
));
2251 /* Adjust instruction opcode and to be relaxed instruction opcode. */
2254 backup_inst1
.instruction
= ((backup_inst1
.instruction
& 0x7FFF) << 15)
2255 | (inst2
->instruction
& 0x7FFF);
2256 backup_inst1
.instruction
= adjust_paritybit (backup_inst1
.instruction
, INSN_CLASS_PCE
);
2257 backup_inst1
.relax_inst
= 0x8000;
2258 backup_inst1
.size
= INSN_SIZE
;
2259 backup_inst1
.relax_size
= 0;
2260 backup_inst1
.type
= Insn_Type_PCE
;
2264 backup_inst1
.instruction
= adjust_paritybit (backup_inst1
.instruction
,
2265 GET_INSN_CLASS (backup_inst1
.type
));
2268 if (backup_inst1
.relax_size
!= 0)
2270 enum insn_class tmp
;
2272 tmp
= (backup_inst1
.size
== INSN_SIZE
) ? INSN_CLASS_16
: INSN_CLASS_32
;
2273 backup_inst1
.relax_inst
= adjust_paritybit (backup_inst1
.relax_inst
, tmp
);
2276 /* Check data dependency. */
2277 handle_dependency (&backup_inst1
);
2279 /* Start a new frag if frag_now is not empty and is not instruction frag, maybe it contains
2280 data produced by .ascii etc. Doing this is to make one instruction per frag. */
2281 if (frag_now_fix () != 0)
2283 if (!frag_now
->tc_frag_data
.is_insn
)
2284 frag_wane (frag_now
);
2289 /* Here, we must call frag_grow in order to keep the instruction frag type is
2290 rs_machine_dependent.
2291 For, frag_var may change frag_now->fr_type to rs_fill by calling frag_grow which
2292 acturally will call frag_wane.
2293 Calling frag_grow first will create a new frag_now which free size is 20 that is enough
2297 p
= frag_more (backup_inst1
.size
);
2298 md_number_to_chars (p
, backup_inst1
.instruction
, backup_inst1
.size
);
2301 dwarf2_emit_insn (backup_inst1
.size
);
2304 /* Generate fixup structure. */
2307 if (inst1
->reloc
.type
!= BFD_RELOC_NONE
)
2308 fix_new_score (frag_now
, p
- frag_now
->fr_literal
,
2309 inst1
->size
, &inst1
->reloc
.exp
,
2310 inst1
->reloc
.pc_rel
, inst1
->reloc
.type
);
2312 if (inst2
->reloc
.type
!= BFD_RELOC_NONE
)
2313 fix_new_score (frag_now
, p
- frag_now
->fr_literal
+ 2,
2314 inst2
->size
, &inst2
->reloc
.exp
, inst2
->reloc
.pc_rel
, inst2
->reloc
.type
);
2318 if (backup_inst1
.reloc
.type
!= BFD_RELOC_NONE
)
2319 fix_new_score (frag_now
, p
- frag_now
->fr_literal
,
2320 backup_inst1
.size
, &backup_inst1
.reloc
.exp
,
2321 backup_inst1
.reloc
.pc_rel
, backup_inst1
.reloc
.type
);
2324 /* relax_size may be 2, 4, 12 or 0, 0 indicates no relaxation. */
2325 relaxable_p
&= (backup_inst1
.relax_size
!= 0);
2326 relax_size
= relaxable_p
? backup_inst1
.relax_size
: 0;
2328 p
= frag_var (rs_machine_dependent
, relax_size
+ RELAX_PAD_BYTE
, 0,
2329 RELAX_ENCODE (backup_inst1
.size
, backup_inst1
.relax_size
,
2330 backup_inst1
.type
, 0, 0, relaxable_p
),
2331 backup_inst1
.reloc
.exp
.X_add_symbol
, 0, NULL
);
2334 md_number_to_chars (p
, backup_inst1
.relax_inst
, relax_size
);
2336 memcpy (inst1
, &backup_inst1
, sizeof (struct score_it
));
2340 parse_16_32_inst (char *insnstr
, bfd_boolean gen_frag_p
)
2344 char *operator = insnstr
;
2345 const struct asm_opcode
*opcode
;
2347 /* Parse operator and operands. */
2348 skip_whitespace (operator);
2350 for (p
= operator; *p
!= '\0'; p
++)
2351 if ((*p
== ' ') || (*p
== '!'))
2360 opcode
= (const struct asm_opcode
*) hash_find (score_ops_hsh
, operator);
2363 memset (&inst
, '\0', sizeof (inst
));
2364 sprintf (inst
.str
, "%s", insnstr
);
2367 inst
.instruction
= opcode
->value
;
2368 inst
.relax_inst
= opcode
->relax_value
;
2369 inst
.type
= opcode
->type
;
2370 inst
.size
= GET_INSN_SIZE (inst
.type
);
2371 inst
.relax_size
= 0;
2373 sprintf (inst
.name
, "%s", opcode
->template);
2374 strcpy (inst
.reg
, "");
2376 inst
.reloc
.type
= BFD_RELOC_NONE
;
2378 (*opcode
->parms
) (p
);
2380 /* It indicates current instruction is a macro instruction if inst.bwarn equals -1. */
2381 if ((inst
.bwarn
!= -1) && (!inst
.error
) && (gen_frag_p
))
2382 gen_insn_frag (&inst
, NULL
);
2385 inst
.error
= _("unrecognized opcode");
2389 append_insn (char *str
, bfd_boolean gen_frag_p
)
2391 int retval
= SUCCESS
;
2393 parse_16_32_inst (str
, gen_frag_p
);
2397 retval
= (int) FAIL
;
2398 as_bad ("%s -- `%s'", inst
.error
, inst
.str
);
2405 /* Handle mv! reg_high, reg_low;
2406 mv! reg_low, reg_high;
2407 mv! reg_low, reg_low; */
2409 do16_mv_rdrs (char *str
)
2413 char *backupstr
= NULL
;
2416 skip_whitespace (str
);
2418 if ((reg_rd
= reg_required_here (&str
, 8, REG_TYPE_SCORE
)) == (int) FAIL
2419 || skip_past_comma (&str
) == (int) FAIL
2420 || (reg_rs
= reg_required_here (&str
, 4, REG_TYPE_SCORE
)) == (int) FAIL
2421 || end_of_line (str
) == (int) FAIL
)
2427 /* Case 1 : mv! or mlfh!. */
2432 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 20)
2433 | (((inst
.instruction
>> 4) & 0xf) << 15) | (0xf << 10);
2434 inst
.relax_size
= 4;
2438 char append_str
[MAX_LITERAL_POOL_SIZE
];
2440 sprintf (append_str
, "mlfh! %s", backupstr
);
2441 if (append_insn (append_str
, TRUE
) == (int) FAIL
)
2443 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
2447 /* Case 2 : mhfl!. */
2452 SET_INSN_ERROR (BAD_ARGS
);
2457 char append_str
[MAX_LITERAL_POOL_SIZE
];
2459 sprintf (append_str
, "mhfl! %s", backupstr
);
2460 if (append_insn (append_str
, TRUE
) == (int) FAIL
)
2463 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
2471 do16_rdi4 (char *str
)
2473 skip_whitespace (str
);
2475 if (reglow_required_here (&str
, 8) == (int) FAIL
2476 || skip_past_comma (&str
) == (int) FAIL
2477 || data_op2 (&str
, 3, _IMM4
) == (int) FAIL
2478 || end_of_line (str
) == (int) FAIL
)
2484 if (((inst
.instruction
>> 3) & 0x10) == 0) /* for judge is addei or subei : bit 5 =0 : addei */
2486 if (((inst
.instruction
>> 3) & 0xf) != 0xf)
2488 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 20)
2489 | ((1 << ((inst
.instruction
>> 3) & 0xf)) << 1);
2490 inst
.relax_size
= 4;
2494 inst
.relax_inst
= 0x8000;
2499 if (((inst
.instruction
>> 3) & 0xf) != 0xf)
2501 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 20)
2502 | (((-(1 << ((inst
.instruction
>> 3) & 0xf))) & 0xffff) << 1);
2503 inst
.relax_size
= 4;
2507 inst
.relax_inst
= 0x8000;
2514 do16_rdi5 (char *str
)
2516 skip_whitespace (str
);
2518 if (reglow_required_here (&str
, 8) == (int) FAIL
2519 || skip_past_comma (&str
) == (int) FAIL
2520 || data_op2 (&str
, 3, _IMM5
) == (int) FAIL
2521 || end_of_line (str
) == (int) FAIL
)
2525 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 20)
2526 | (((inst
.instruction
>> 8) & 0xf) << 15) | (((inst
.instruction
>> 3) & 0x1f) << 10);
2527 inst
.relax_size
= 4;
2533 do16_xi5 (char *str
)
2535 skip_whitespace (str
);
2537 if (data_op2 (&str
, 3, _IMM5
) == (int) FAIL
|| end_of_line (str
) == (int) FAIL
)
2541 inst
.relax_inst
|= (((inst
.instruction
>> 3) & 0x1f) << 15);
2542 inst
.relax_size
= 4;
2546 /* Check that an immediate is word alignment or half word alignment.
2547 If so, convert it to the right format. */
2549 validate_immediate_align (int val
, unsigned int data_type
)
2551 if (data_type
== _IMM5_RSHIFT_1
)
2555 inst
.error
= _("address offset must be half word alignment");
2559 else if ((data_type
== _IMM5_RSHIFT_2
) || (data_type
== _IMM10_RSHIFT_2
))
2563 inst
.error
= _("address offset must be word alignment");
2572 exp_ldst_offset (char **str
, int shift
, unsigned int data_type
)
2578 if ((*dataptr
== '0') && (*(dataptr
+ 1) == 'x')
2579 && (data_type
!= _SIMM16_LA
)
2580 && (data_type
!= _VALUE_HI16
)
2581 && (data_type
!= _VALUE_LO16
)
2582 && (data_type
!= _IMM16
)
2583 && (data_type
!= _IMM15
)
2584 && (data_type
!= _IMM14
)
2585 && (data_type
!= _IMM4
)
2586 && (data_type
!= _IMM5
)
2587 && (data_type
!= _IMM8
)
2588 && (data_type
!= _IMM5_RSHIFT_1
)
2589 && (data_type
!= _IMM5_RSHIFT_2
)
2590 && (data_type
!= _SIMM14_NEG
)
2591 && (data_type
!= _IMM10_RSHIFT_2
))
2596 if (my_get_expression (&inst
.reloc
.exp
, str
) == (int) FAIL
)
2599 if (inst
.reloc
.exp
.X_op
== O_constant
)
2601 /* Need to check the immediate align. */
2602 int value
= validate_immediate_align (inst
.reloc
.exp
.X_add_number
, data_type
);
2604 if (value
== (int) FAIL
)
2607 value
= validate_immediate (inst
.reloc
.exp
.X_add_number
, data_type
);
2608 if (value
== (int) FAIL
)
2614 "invalid constant: %d bit expression not in range %d..%d",
2615 score_df_range
[data_type
].bits
,
2616 score_df_range
[data_type
].range
[0], score_df_range
[data_type
].range
[1]);
2619 "invalid constant: %d bit expression not in range %d..%d",
2620 score_df_range
[data_type
- 24].bits
,
2621 score_df_range
[data_type
- 24].range
[0], score_df_range
[data_type
- 24].range
[1]);
2622 inst
.error
= _(err_msg
);
2626 if (data_type
== _IMM5_RSHIFT_1
)
2630 else if ((data_type
== _IMM5_RSHIFT_2
) || (data_type
== _IMM10_RSHIFT_2
))
2635 if (score_df_range
[data_type
].range
[0] != 0)
2637 value
&= (1 << score_df_range
[data_type
].bits
) - 1;
2640 inst
.instruction
|= value
<< shift
;
2644 inst
.reloc
.pc_rel
= 0;
2651 do_ldst_insn (char *str
)
2663 skip_whitespace (str
);
2665 if (((conflict_reg
= reg_required_here (&str
, 20, REG_TYPE_SCORE
)) == (int) FAIL
)
2666 || (skip_past_comma (&str
) == (int) FAIL
))
2669 /* ld/sw rD, [rA, simm15] ld/sw rD, [rA]+, simm12 ld/sw rD, [rA, simm12]+. */
2673 skip_whitespace (str
);
2675 if ((reg
= reg_required_here (&str
, 15, REG_TYPE_SCORE
)) == (int) FAIL
)
2678 /* Conflicts can occur on stores as well as loads. */
2679 conflict_reg
= (conflict_reg
== reg
);
2680 skip_whitespace (str
);
2681 temp
= str
+ 1; /* The latter will process decimal/hex expression. */
2683 /* ld/sw rD, [rA]+, simm12 ld/sw rD, [rA]+. */
2690 /* ld/sw rD, [rA]+, simm12. */
2691 if (skip_past_comma (&str
) == SUCCESS
)
2693 if ((exp_ldst_offset (&str
, 3, _SIMM12
) == (int) FAIL
)
2694 || (end_of_line (str
) == (int) FAIL
))
2699 unsigned int ldst_func
= inst
.instruction
& OPC_PSEUDOLDST_MASK
;
2701 if ((ldst_func
== INSN_LH
)
2702 || (ldst_func
== INSN_LHU
)
2703 || (ldst_func
== INSN_LW
)
2704 || (ldst_func
== INSN_LB
)
2705 || (ldst_func
== INSN_LBU
))
2707 inst
.error
= _("register same as write-back base");
2712 ldst_idx
= inst
.instruction
& OPC_PSEUDOLDST_MASK
;
2713 inst
.instruction
&= ~OPC_PSEUDOLDST_MASK
;
2714 inst
.instruction
|= score_ldst_insns
[ldst_idx
* 3 + LDST_POST
].value
;
2716 /* lw rD, [rA]+, 4 convert to pop rD, [rA]. */
2717 if ((inst
.instruction
& 0x3e000007) == 0x0e000000)
2719 /* rs = r0-r7, offset = 4 */
2720 if ((((inst
.instruction
>> 15) & 0x18) == 0)
2721 && (((inst
.instruction
>> 3) & 0xfff) == 4))
2723 /* Relax to pophi. */
2724 if ((((inst
.instruction
>> 20) & 0x10) == 0x10))
2726 inst
.relax_inst
= 0x0000200a | (((inst
.instruction
>> 20) & 0xf)
2728 (((inst
.instruction
>> 15) & 0x7) << 4);
2733 inst
.relax_inst
= 0x0000200a | (((inst
.instruction
>> 20) & 0xf)
2735 (((inst
.instruction
>> 15) & 0x7) << 4);
2737 inst
.relax_size
= 2;
2742 /* ld/sw rD, [rA]+ convert to ld/sw rD, [rA, 0]+. */
2745 SET_INSN_ERROR (NULL
);
2746 if (end_of_line (str
) == (int) FAIL
)
2752 value
= validate_immediate (inst
.reloc
.exp
.X_add_number
, _SIMM12
);
2753 value
&= (1 << score_df_range
[_SIMM12
].bits
) - 1;
2754 ldst_idx
= inst
.instruction
& OPC_PSEUDOLDST_MASK
;
2755 inst
.instruction
&= ~OPC_PSEUDOLDST_MASK
;
2756 inst
.instruction
|= score_ldst_insns
[ldst_idx
* 3 + pre_inc
].value
;
2757 inst
.instruction
|= value
<< 3;
2758 inst
.relax_inst
= 0x8000;
2762 /* ld/sw rD, [rA] convert to ld/sw rD, [rA, simm15]. */
2765 if (end_of_line (str
) == (int) FAIL
)
2768 ldst_idx
= inst
.instruction
& OPC_PSEUDOLDST_MASK
;
2769 inst
.instruction
&= ~OPC_PSEUDOLDST_MASK
;
2770 inst
.instruction
|= score_ldst_insns
[ldst_idx
* 3 + LDST_NOUPDATE
].value
;
2772 /* lbu rd, [rs] -> lbu! rd, [rs] */
2773 if (ldst_idx
== INSN_LBU
)
2775 inst
.relax_inst
= INSN16_LBU
;
2777 else if (ldst_idx
== INSN_LH
)
2779 inst
.relax_inst
= INSN16_LH
;
2781 else if (ldst_idx
== INSN_LW
)
2783 inst
.relax_inst
= INSN16_LW
;
2785 else if (ldst_idx
== INSN_SB
)
2787 inst
.relax_inst
= INSN16_SB
;
2789 else if (ldst_idx
== INSN_SH
)
2791 inst
.relax_inst
= INSN16_SH
;
2793 else if (ldst_idx
== INSN_SW
)
2795 inst
.relax_inst
= INSN16_SW
;
2799 inst
.relax_inst
= 0x8000;
2802 /* lw/lh/lbu/sw/sh/sb, offset = 0, relax to 16 bit instruction. */
2803 if ((ldst_idx
== INSN_LBU
)
2804 || (ldst_idx
== INSN_LH
)
2805 || (ldst_idx
== INSN_LW
)
2806 || (ldst_idx
== INSN_SB
) || (ldst_idx
== INSN_SH
) || (ldst_idx
== INSN_SW
))
2808 if ((((inst
.instruction
>> 15) & 0x10) == 0) && (((inst
.instruction
>> 20) & 0x10) == 0))
2810 inst
.relax_inst
|= (2 << 12) | (((inst
.instruction
>> 20) & 0xf) << 8) |
2811 (((inst
.instruction
>> 15) & 0xf) << 4);
2812 inst
.relax_size
= 2;
2819 /* ld/sw rD, [rA, simm15] ld/sw rD, [rA, simm12]+. */
2822 if (skip_past_comma (&str
) == (int) FAIL
)
2824 inst
.error
= _("pre-indexed expression expected");
2828 if (my_get_expression (&inst
.reloc
.exp
, &str
) == (int) FAIL
)
2831 skip_whitespace (str
);
2834 inst
.error
= _("missing ]");
2838 skip_whitespace (str
);
2839 /* ld/sw rD, [rA, simm12]+. */
2846 unsigned int ldst_func
= inst
.instruction
& OPC_PSEUDOLDST_MASK
;
2848 if ((ldst_func
== INSN_LH
)
2849 || (ldst_func
== INSN_LHU
)
2850 || (ldst_func
== INSN_LW
)
2851 || (ldst_func
== INSN_LB
)
2852 || (ldst_func
== INSN_LBU
))
2854 inst
.error
= _("register same as write-back base");
2860 if (end_of_line (str
) == (int) FAIL
)
2863 if (inst
.reloc
.exp
.X_op
== O_constant
)
2866 unsigned int data_type
;
2869 data_type
= _SIMM12
;
2871 data_type
= _SIMM15
;
2874 if ((*dataptr
== '0') && (*(dataptr
+ 1) == 'x')
2875 && (data_type
!= _SIMM16_LA
)
2876 && (data_type
!= _VALUE_HI16
)
2877 && (data_type
!= _VALUE_LO16
)
2878 && (data_type
!= _IMM16
)
2879 && (data_type
!= _IMM15
)
2880 && (data_type
!= _IMM14
)
2881 && (data_type
!= _IMM4
)
2882 && (data_type
!= _IMM5
)
2883 && (data_type
!= _IMM8
)
2884 && (data_type
!= _IMM5_RSHIFT_1
)
2885 && (data_type
!= _IMM5_RSHIFT_2
)
2886 && (data_type
!= _SIMM14_NEG
)
2887 && (data_type
!= _IMM10_RSHIFT_2
))
2892 value
= validate_immediate (inst
.reloc
.exp
.X_add_number
, data_type
);
2893 if (value
== (int) FAIL
)
2899 "invalid constant: %d bit expression not in range %d..%d",
2900 score_df_range
[data_type
].bits
,
2901 score_df_range
[data_type
].range
[0], score_df_range
[data_type
].range
[1]);
2904 "invalid constant: %d bit expression not in range %d..%d",
2905 score_df_range
[data_type
- 24].bits
,
2906 score_df_range
[data_type
- 24].range
[0],
2907 score_df_range
[data_type
- 24].range
[1]);
2908 inst
.error
= _(err_msg
);
2912 value
&= (1 << score_df_range
[data_type
].bits
) - 1;
2913 ldst_idx
= inst
.instruction
& OPC_PSEUDOLDST_MASK
;
2914 inst
.instruction
&= ~OPC_PSEUDOLDST_MASK
;
2915 inst
.instruction
|= score_ldst_insns
[ldst_idx
* 3 + pre_inc
].value
;
2917 inst
.instruction
|= value
<< 3;
2919 inst
.instruction
|= value
;
2921 /* lw rD, [rA, simm15] */
2922 if ((inst
.instruction
& 0x3e000000) == 0x20000000)
2924 /* Both rD and rA are in [r0 - r15]. */
2925 if ((((inst
.instruction
>> 15) & 0x10) == 0)
2926 && (((inst
.instruction
>> 20) & 0x10) == 0))
2928 /* simm15 = 0, lw -> lw!. */
2929 if ((inst
.instruction
& 0x7fff) == 0)
2931 inst
.relax_inst
|= (((inst
.instruction
>> 15) & 0xf) << 4)
2932 | (((inst
.instruction
>> 20) & 0xf) << 8);
2933 inst
.relax_size
= 2;
2935 /* rA = r2, lw -> lwp!. */
2936 else if ((((inst
.instruction
>> 15) & 0xf) == 2)
2937 && ((inst
.instruction
& 0x3) == 0)
2938 && ((inst
.instruction
& 0x7fff) < 128))
2940 inst
.relax_inst
= 0x7000 | (((inst
.instruction
>> 20) & 0xf) << 8)
2941 | (((inst
.instruction
& 0x7fff) >> 2) << 3);
2942 inst
.relax_size
= 2;
2946 inst
.relax_inst
= 0x8000;
2951 inst
.relax_inst
= 0x8000;
2954 /* sw rD, [rA, simm15] */
2955 else if ((inst
.instruction
& 0x3e000000) == 0x28000000)
2957 /* Both rD and rA are in [r0 - r15]. */
2958 if ((((inst
.instruction
>> 15) & 0x10) == 0) && (((inst
.instruction
>> 20) & 0x10) == 0))
2960 /* simm15 = 0, sw -> sw!. */
2961 if ((inst
.instruction
& 0x7fff) == 0)
2963 inst
.relax_inst
|= (((inst
.instruction
>> 15) & 0xf) << 4)
2964 | (((inst
.instruction
>> 20) & 0xf) << 8);
2965 inst
.relax_size
= 2;
2967 /* rA = r2, sw -> swp!. */
2968 else if ((((inst
.instruction
>> 15) & 0xf) == 2)
2969 && ((inst
.instruction
& 0x3) == 0)
2970 && ((inst
.instruction
& 0x7fff) < 128))
2972 inst
.relax_inst
= 0x7004 | (((inst
.instruction
>> 20) & 0xf) << 8)
2973 | (((inst
.instruction
& 0x7fff) >> 2) << 3);
2974 inst
.relax_size
= 2;
2978 inst
.relax_inst
= 0x8000;
2983 inst
.relax_inst
= 0x8000;
2986 /* sw rD, [rA, simm15]+ sw pre. */
2987 else if ((inst
.instruction
& 0x3e000007) == 0x06000004)
2989 /* rA is in [r0 - r7], and simm15 = -4. */
2990 if ((((inst
.instruction
>> 15) & 0x18) == 0)
2991 && (((inst
.instruction
>> 3) & 0xfff) == 0xffc))
2993 /* sw -> pushhi!. */
2994 if ((((inst
.instruction
>> 20) & 0x10) == 0x10))
2996 inst
.relax_inst
= 0x0000200e | (((inst
.instruction
>> 20) & 0xf) << 8)
2997 | 1 << 7 | (((inst
.instruction
>> 15) & 0x7) << 4);
2998 inst
.relax_size
= 2;
3003 inst
.relax_inst
= 0x0000200e | (((inst
.instruction
>> 20) & 0xf) << 8)
3004 | 0 << 7 | (((inst
.instruction
>> 15) & 0x7) << 4);
3005 inst
.relax_size
= 2;
3010 inst
.relax_inst
= 0x8000;
3013 /* lh rD, [rA, simm15] */
3014 else if ((inst
.instruction
& 0x3e000000) == 0x22000000)
3016 /* Both rD and rA are in [r0 - r15]. */
3017 if ((((inst
.instruction
>> 15) & 0x10) == 0) && (((inst
.instruction
>> 20) & 0x10) == 0))
3019 /* simm15 = 0, lh -> lh!. */
3020 if ((inst
.instruction
& 0x7fff) == 0)
3022 inst
.relax_inst
|= (((inst
.instruction
>> 15) & 0xf) << 4)
3023 | (((inst
.instruction
>> 20) & 0xf) << 8);
3024 inst
.relax_size
= 2;
3026 /* rA = r2, lh -> lhp!. */
3027 else if ((((inst
.instruction
>> 15) & 0xf) == 2)
3028 && ((inst
.instruction
& 0x1) == 0)
3029 && ((inst
.instruction
& 0x7fff) < 64))
3031 inst
.relax_inst
= 0x7001 | (((inst
.instruction
>> 20) & 0xf) << 8)
3032 | (((inst
.instruction
& 0x7fff) >> 1) << 3);
3033 inst
.relax_size
= 2;
3037 inst
.relax_inst
= 0x8000;
3042 inst
.relax_inst
= 0x8000;
3045 /* sh rD, [rA, simm15] */
3046 else if ((inst
.instruction
& 0x3e000000) == 0x2a000000)
3048 /* Both rD and rA are in [r0 - r15]. */
3049 if ((((inst
.instruction
>> 15) & 0x10) == 0) && (((inst
.instruction
>> 20) & 0x10) == 0))
3051 /* simm15 = 0, sh -> sh!. */
3052 if ((inst
.instruction
& 0x7fff) == 0)
3054 inst
.relax_inst
|= (((inst
.instruction
>> 15) & 0xf) << 4)
3055 | (((inst
.instruction
>> 20) & 0xf) << 8);
3056 inst
.relax_size
= 2;
3058 /* rA = r2, sh -> shp!. */
3059 else if ((((inst
.instruction
>> 15) & 0xf) == 2)
3060 && ((inst
.instruction
& 0x1) == 0)
3061 && ((inst
.instruction
& 0x7fff) < 64))
3063 inst
.relax_inst
= 0x7005 | (((inst
.instruction
>> 20) & 0xf) << 8)
3064 | (((inst
.instruction
& 0x7fff) >> 1) << 3);
3065 inst
.relax_size
= 2;
3069 inst
.relax_inst
= 0x8000;
3074 inst
.relax_inst
= 0x8000;
3077 /* lbu rD, [rA, simm15] */
3078 else if ((inst
.instruction
& 0x3e000000) == 0x2c000000)
3080 /* Both rD and rA are in [r0 - r15]. */
3081 if ((((inst
.instruction
>> 15) & 0x10) == 0) && (((inst
.instruction
>> 20) & 0x10) == 0))
3083 /* simm15 = 0, lbu -> lbu!. */
3084 if ((inst
.instruction
& 0x7fff) == 0)
3086 inst
.relax_inst
|= (((inst
.instruction
>> 15) & 0xf) << 4)
3087 | (((inst
.instruction
>> 20) & 0xf) << 8);
3088 inst
.relax_size
= 2;
3090 /* rA = r2, lbu -> lbup!. */
3091 else if ((((inst
.instruction
>> 15) & 0xf) == 2)
3092 && ((inst
.instruction
& 0x7fff) < 32))
3094 inst
.relax_inst
= 0x7003 | (((inst
.instruction
>> 20) & 0xf) << 8)
3095 | ((inst
.instruction
& 0x7fff) << 3);
3096 inst
.relax_size
= 2;
3100 inst
.relax_inst
= 0x8000;
3105 inst
.relax_inst
= 0x8000;
3108 /* sb rD, [rA, simm15] */
3109 else if ((inst
.instruction
& 0x3e000000) == 0x2e000000)
3111 /* Both rD and rA are in [r0 - r15]. */
3112 if ((((inst
.instruction
>> 15) & 0x10) == 0) && (((inst
.instruction
>> 20) & 0x10) == 0))
3114 /* simm15 = 0, sb -> sb!. */
3115 if ((inst
.instruction
& 0x7fff) == 0)
3117 inst
.relax_inst
|= (((inst
.instruction
>> 15) & 0xf) << 4)
3118 | (((inst
.instruction
>> 20) & 0xf) << 8);
3119 inst
.relax_size
= 2;
3121 /* rA = r2, sb -> sb!. */
3122 else if ((((inst
.instruction
>> 15) & 0xf) == 2)
3123 && ((inst
.instruction
& 0x7fff) < 32))
3125 inst
.relax_inst
= 0x7007 | (((inst
.instruction
>> 20) & 0xf) << 8)
3126 | ((inst
.instruction
& 0x7fff) << 3);
3127 inst
.relax_size
= 2;
3131 inst
.relax_inst
= 0x8000;
3136 inst
.relax_inst
= 0x8000;
3141 inst
.relax_inst
= 0x8000;
3148 /* FIXME: may set error, for there is no ld/sw rD, [rA, label] */
3149 inst
.reloc
.pc_rel
= 0;
3155 inst
.error
= BAD_ARGS
;
3162 do_cache (char *str
)
3164 skip_whitespace (str
);
3166 if ((data_op2 (&str
, 20, _IMM5
) == (int) FAIL
) || (skip_past_comma (&str
) == (int) FAIL
))
3174 cache_op
= (inst
.instruction
>> 20) & 0x1F;
3175 sprintf (inst
.name
, "cache %d", cache_op
);
3181 skip_whitespace (str
);
3183 if (reg_required_here (&str
, 15, REG_TYPE_SCORE
) == (int) FAIL
)
3186 skip_whitespace (str
);
3188 /* cache op, [rA] */
3189 if (skip_past_comma (&str
) == (int) FAIL
)
3191 SET_INSN_ERROR (NULL
);
3194 inst
.error
= _("missing ]");
3199 /* cache op, [rA, simm15] */
3202 if (exp_ldst_offset (&str
, 0, _SIMM15
) == (int) FAIL
)
3207 skip_whitespace (str
);
3210 inst
.error
= _("missing ]");
3215 if (end_of_line (str
) == (int) FAIL
)
3220 inst
.error
= BAD_ARGS
;
3225 do_crdcrscrsimm5 (char *str
)
3230 skip_whitespace (str
);
3232 if (reg_required_here (&str
, 20, REG_TYPE_SCORE_CR
) == (int) FAIL
3233 || skip_past_comma (&str
) == (int) FAIL
3234 || reg_required_here (&str
, 15, REG_TYPE_SCORE_CR
) == (int) FAIL
3235 || skip_past_comma (&str
) == (int) FAIL
3236 || reg_required_here (&str
, 10, REG_TYPE_SCORE_CR
) == (int) FAIL
3237 || skip_past_comma (&str
) == (int) FAIL
)
3240 /* cop1 cop_code20. */
3241 if (data_op2 (&str
, 5, _IMM20
) == (int) FAIL
)
3246 if (data_op2 (&str
, 5, _IMM5
) == (int) FAIL
)
3253 /* Handle ldc/stc. */
3255 do_ldst_cop (char *str
)
3257 skip_whitespace (str
);
3259 if ((reg_required_here (&str
, 15, REG_TYPE_SCORE_CR
) == (int) FAIL
)
3260 || (skip_past_comma (&str
) == (int) FAIL
))
3266 skip_whitespace (str
);
3268 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) == (int) FAIL
)
3271 skip_whitespace (str
);
3275 if (exp_ldst_offset (&str
, 5, _IMM10_RSHIFT_2
) == (int) FAIL
)
3278 skip_whitespace (str
);
3281 inst
.error
= _("missing ]");
3289 inst
.error
= BAD_ARGS
;
3293 do16_ldst_insn (char *str
)
3295 skip_whitespace (str
);
3297 if ((reglow_required_here (&str
, 8) == (int) FAIL
) || (skip_past_comma (&str
) == (int) FAIL
))
3305 skip_whitespace (str
);
3307 if ((reg
= reglow_required_here (&str
, 4)) == (int) FAIL
)
3310 skip_whitespace (str
);
3313 if (end_of_line (str
) == (int) FAIL
)
3317 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 20)
3318 | (((inst
.instruction
>> 4) & 0xf) << 15);
3319 inst
.relax_size
= 4;
3324 inst
.error
= _("missing ]");
3329 inst
.error
= BAD_ARGS
;
3333 /* Handle lbup!/lhp!/ldiu!/lwp!/sbp!/shp!/swp!. */
3335 do16_ldst_imm_insn (char *str
)
3337 char data_exp
[MAX_LITERAL_POOL_SIZE
];
3339 char *dataptr
= NULL
, *pp
= NULL
;
3341 int assign_data
= (int) FAIL
;
3342 unsigned int ldst_func
;
3344 skip_whitespace (str
);
3346 if (((reg_rd
= reglow_required_here (&str
, 8)) == (int) FAIL
)
3347 || (skip_past_comma (&str
) == (int) FAIL
))
3350 skip_whitespace (str
);
3353 while ((*dataptr
!= '\0') && (*dataptr
!= '|') && (cnt
<= MAX_LITERAL_POOL_SIZE
))
3355 data_exp
[cnt
] = *dataptr
;
3360 data_exp
[cnt
] = '\0';
3365 ldst_func
= inst
.instruction
& LDST16_RI_MASK
;
3366 if (ldst_func
== N16_LIU
)
3367 assign_data
= exp_ldst_offset (&pp
, 0, _IMM8
);
3368 else if (ldst_func
== N16_LHP
|| ldst_func
== N16_SHP
)
3369 assign_data
= exp_ldst_offset (&pp
, 3, _IMM5_RSHIFT_1
);
3370 else if (ldst_func
== N16_LWP
|| ldst_func
== N16_SWP
)
3371 assign_data
= exp_ldst_offset (&pp
, 3, _IMM5_RSHIFT_2
);
3373 assign_data
= exp_ldst_offset (&pp
, 3, _IMM5
);
3375 if ((assign_data
== (int) FAIL
) || (end_of_line (pp
) == (int) FAIL
))
3379 if ((inst
.instruction
& 0x7000) == N16_LIU
)
3381 inst
.relax_inst
|= ((inst
.instruction
>> 8) & 0xf) << 20
3382 | ((inst
.instruction
& 0xff) << 1);
3384 else if (((inst
.instruction
& 0x7007) == N16_LHP
)
3385 || ((inst
.instruction
& 0x7007) == N16_SHP
))
3387 inst
.relax_inst
|= ((inst
.instruction
>> 8) & 0xf) << 20 | 2 << 15
3388 | (((inst
.instruction
>> 3) & 0x1f) << 1);
3390 else if (((inst
.instruction
& 0x7007) == N16_LWP
)
3391 || ((inst
.instruction
& 0x7007) == N16_SWP
))
3393 inst
.relax_inst
|= ((inst
.instruction
>> 8) & 0xf) << 20 | 2 << 15
3394 | (((inst
.instruction
>> 3) & 0x1f) << 2);
3396 else if (((inst
.instruction
& 0x7007) == N16_LBUP
)
3397 || ((inst
.instruction
& 0x7007) == N16_SBP
))
3399 inst
.relax_inst
|= ((inst
.instruction
>> 8) & 0xf) << 20 | 2 << 15
3400 | (((inst
.instruction
>> 3) & 0x1f));
3403 inst
.relax_size
= 4;
3408 do16_push_pop (char *str
)
3413 skip_whitespace (str
);
3414 if (((reg_rd
= reg_required_here (&str
, 8, REG_TYPE_SCORE
)) == (int) FAIL
)
3415 || (skip_past_comma (&str
) == (int) FAIL
))
3421 /* reg_required_here will change bit 12 of opcode, so we must restore bit 12. */
3422 inst
.instruction
&= ~(1 << 12);
3424 inst
.instruction
|= H_bit_mask
<< 7;
3431 skip_whitespace (str
);
3432 if ((reg
= reg_required_here (&str
, 4, REG_TYPE_SCORE
)) == (int) FAIL
)
3437 inst
.error
= _("base register nums are over 3 bit");
3442 skip_whitespace (str
);
3443 if ((*str
++ != ']') || (end_of_line (str
) == (int) FAIL
))
3446 inst
.error
= _("missing ]");
3452 if ((inst
.instruction
& 0xf) == 0xa)
3456 inst
.relax_inst
|= ((((inst
.instruction
>> 8) & 0xf) | 0x10) << 20)
3457 | (((inst
.instruction
>> 4) & 0x7) << 15) | (4 << 3);
3461 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 20)
3462 | (((inst
.instruction
>> 4) & 0x7) << 15) | (4 << 3);
3470 inst
.relax_inst
|= ((((inst
.instruction
>> 8) & 0xf) | 0x10) << 20)
3471 | (((inst
.instruction
>> 4) & 0x7) << 15) | (((-4) & 0xfff) << 3);
3475 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 20)
3476 | (((inst
.instruction
>> 4) & 0x7) << 15) | (((-4) & 0xfff) << 3);
3479 inst
.relax_size
= 4;
3483 inst
.error
= BAD_ARGS
;
3487 /* Handle lcb/lcw/lce/scb/scw/sce. */
3489 do_ldst_unalign (char *str
)
3493 if (university_version
== 1)
3495 inst
.error
= ERR_FOR_SCORE5U_ATOMIC
;
3499 skip_whitespace (str
);
3501 /* lcb/scb [rA]+. */
3505 skip_whitespace (str
);
3507 if (reg_required_here (&str
, 15, REG_TYPE_SCORE
) == (int) FAIL
)
3514 inst
.error
= _("missing +");
3520 inst
.error
= _("missing ]");
3524 if (end_of_line (str
) == (int) FAIL
)
3527 /* lcw/lce/scb/sce rD, [rA]+. */
3530 if (((conflict_reg
= reg_required_here (&str
, 20, REG_TYPE_SCORE
)) == (int) FAIL
)
3531 || (skip_past_comma (&str
) == (int) FAIL
))
3536 skip_whitespace (str
);
3541 skip_whitespace (str
);
3542 if ((reg
= reg_required_here (&str
, 15, REG_TYPE_SCORE
)) == (int) FAIL
)
3547 /* Conflicts can occur on stores as well as loads. */
3548 conflict_reg
= (conflict_reg
== reg
);
3549 skip_whitespace (str
);
3552 unsigned int ldst_func
= inst
.instruction
& LDST_UNALIGN_MASK
;
3558 as_warn (_("%s register same as write-back base"),
3559 ((ldst_func
& UA_LCE
) || (ldst_func
& UA_LCW
)
3560 ? _("destination") : _("source")));
3565 inst
.error
= _("missing +");
3569 if (end_of_line (str
) == (int) FAIL
)
3574 inst
.error
= _("missing ]");
3580 inst
.error
= BAD_ARGS
;
3586 /* Handle alw/asw. */
3588 do_ldst_atomic (char *str
)
3590 if (university_version
== 1)
3592 inst
.error
= ERR_FOR_SCORE5U_ATOMIC
;
3596 skip_whitespace (str
);
3598 if ((reg_required_here (&str
, 20, REG_TYPE_SCORE
) == (int) FAIL
)
3599 || (skip_past_comma (&str
) == (int) FAIL
))
3606 skip_whitespace (str
);
3611 skip_whitespace (str
);
3612 if ((reg
= reg_required_here (&str
, 15, REG_TYPE_SCORE
)) == (int) FAIL
)
3617 skip_whitespace (str
);
3620 inst
.error
= _("missing ]");
3627 inst
.error
= BAD_ARGS
;
3632 build_relax_frag (struct score_it fix_insts
[RELAX_INST_NUM
], int fix_num ATTRIBUTE_UNUSED
,
3633 struct score_it var_insts
[RELAX_INST_NUM
], int var_num
,
3634 symbolS
*add_symbol
)
3639 fixS
*cur_fixp
= NULL
;
3641 struct score_it inst_main
;
3643 memcpy (&inst_main
, &fix_insts
[0], sizeof (struct score_it
));
3645 /* Adjust instruction opcode and to be relaxed instruction opcode. */
3646 inst_main
.instruction
= adjust_paritybit (inst_main
.instruction
, GET_INSN_CLASS (inst_main
.type
));
3647 inst_main
.type
= Insn_PIC
;
3649 for (i
= 0; i
< var_num
; i
++)
3651 inst_main
.relax_size
+= var_insts
[i
].size
;
3652 var_insts
[i
].instruction
= adjust_paritybit (var_insts
[i
].instruction
,
3653 GET_INSN_CLASS (var_insts
[i
].type
));
3656 /* Check data dependency. */
3657 handle_dependency (&inst_main
);
3659 /* Start a new frag if frag_now is not empty. */
3660 if (frag_now_fix () != 0)
3662 if (!frag_now
->tc_frag_data
.is_insn
)
3664 frag_wane (frag_now
);
3670 /* Write fr_fix part. */
3671 p
= frag_more (inst_main
.size
);
3672 md_number_to_chars (p
, inst_main
.instruction
, inst_main
.size
);
3674 if (inst_main
.reloc
.type
!= BFD_RELOC_NONE
)
3675 fixp
= fix_new_score (frag_now
, p
- frag_now
->fr_literal
, inst_main
.size
,
3676 &inst_main
.reloc
.exp
, inst_main
.reloc
.pc_rel
, inst_main
.reloc
.type
);
3678 frag_now
->tc_frag_data
.fixp
= fixp
;
3679 cur_fixp
= frag_now
->tc_frag_data
.fixp
;
3682 dwarf2_emit_insn (inst_main
.size
);
3685 where
= p
- frag_now
->fr_literal
+ inst_main
.size
;
3686 for (i
= 0; i
< var_num
; i
++)
3689 where
+= var_insts
[i
- 1].size
;
3691 if (var_insts
[i
].reloc
.type
!= BFD_RELOC_NONE
)
3693 fixp
= fix_new_score (frag_now
, where
, var_insts
[i
].size
,
3694 &var_insts
[i
].reloc
.exp
, var_insts
[i
].reloc
.pc_rel
,
3695 var_insts
[i
].reloc
.type
);
3700 cur_fixp
->fx_next
= fixp
;
3701 cur_fixp
= cur_fixp
->fx_next
;
3705 frag_now
->tc_frag_data
.fixp
= fixp
;
3706 cur_fixp
= frag_now
->tc_frag_data
.fixp
;
3712 p
= frag_var (rs_machine_dependent
, inst_main
.relax_size
+ RELAX_PAD_BYTE
, 0,
3713 RELAX_ENCODE (inst_main
.size
, inst_main
.relax_size
, inst_main
.type
,
3714 0, inst_main
.size
, 0), add_symbol
, 0, NULL
);
3716 /* Write fr_var part.
3717 no calling gen_insn_frag, no fixS will be generated. */
3718 for (i
= 0; i
< var_num
; i
++)
3720 md_number_to_chars (p
, var_insts
[i
].instruction
, var_insts
[i
].size
);
3721 p
+= var_insts
[i
].size
;
3723 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
3727 /* Build a relax frag for la instruction when generating PIC,
3728 external symbol first and local symbol second. */
3731 build_la_pic (int reg_rd
, expressionS exp
)
3733 symbolS
*add_symbol
= exp
.X_add_symbol
;
3734 offsetT add_number
= exp
.X_add_number
;
3735 struct score_it fix_insts
[RELAX_INST_NUM
];
3736 struct score_it var_insts
[RELAX_INST_NUM
];
3739 char tmp
[MAX_LITERAL_POOL_SIZE
];
3745 if (add_number
== 0)
3750 /* Insn 1 and Insn 2 */
3752 For an external symbol: lw rD, <sym>($gp)
3753 (BFD_RELOC_SCORE_GOT15 or BFD_RELOC_SCORE_CALL15) */
3754 sprintf (tmp
, "lw_pic r%d, %s", reg_rd
, add_symbol
->bsym
->name
);
3755 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
3758 if (reg_rd
== PIC_CALL_REG
)
3759 inst
.reloc
.type
= BFD_RELOC_SCORE_CALL15
;
3760 memcpy (&fix_insts
[0], &inst
, sizeof (struct score_it
));
3763 For a local symbol :
3764 lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15)
3765 addi rD, <sym> (BFD_RELOC_GOT_LO16) */
3766 inst
.reloc
.type
= BFD_RELOC_SCORE_GOT15
;
3767 memcpy (&var_insts
[0], &inst
, sizeof (struct score_it
));
3768 sprintf (tmp
, "addi_s_pic r%d, %s", reg_rd
, add_symbol
->bsym
->name
);
3769 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
3772 memcpy (&var_insts
[1], &inst
, sizeof (struct score_it
));
3773 build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
3775 else if (add_number
>= -0x8000 && add_number
<= 0x7fff)
3777 /* Insn 1: lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15) */
3778 sprintf (tmp
, "lw_pic r%d, %s", reg_rd
, add_symbol
->bsym
->name
);
3779 if (append_insn (tmp
, TRUE
) == (int) FAIL
)
3786 For an external symbol: addi rD, <constant> */
3787 sprintf (tmp
, "addi r%d, %d", reg_rd
, (int)add_number
);
3788 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
3791 memcpy (&fix_insts
[0], &inst
, sizeof (struct score_it
));
3794 For a local symbol: addi rD, <sym>+<constant> (BFD_RELOC_GOT_LO16) */
3795 sprintf (tmp
, "addi_s_pic r%d, %s + %d", reg_rd
, add_symbol
->bsym
->name
, (int)add_number
);
3796 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
3799 memcpy (&var_insts
[0], &inst
, sizeof (struct score_it
));
3800 build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
3804 int hi
= (add_number
>> 16) & 0x0000FFFF;
3805 int lo
= add_number
& 0x0000FFFF;
3807 /* Insn 1: lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15) */
3808 sprintf (tmp
, "lw_pic r%d, %s", reg_rd
, add_symbol
->bsym
->name
);
3809 if (append_insn (tmp
, TRUE
) == (int) FAIL
)
3816 For an external symbol: ldis r1, HI%<constant> */
3817 sprintf (tmp
, "ldis %s, %d", "r1", hi
);
3818 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
3821 memcpy (&fix_insts
[0], &inst
, sizeof (struct score_it
));
3824 For a local symbol: ldis r1, HI%<constant>
3825 but, if lo is outof 16 bit, make hi plus 1 */
3826 if ((lo
< -0x8000) || (lo
> 0x7fff))
3830 sprintf (tmp
, "ldis_pic %s, %d", "r1", hi
);
3831 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
3834 memcpy (&var_insts
[0], &inst
, sizeof (struct score_it
));
3835 build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
3841 For an external symbol: ori r1, LO%<constant> */
3842 sprintf (tmp
, "ori %s, %d", "r1", lo
);
3843 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
3846 memcpy (&fix_insts
[0], &inst
, sizeof (struct score_it
));
3849 For a local symbol: addi r1, <sym>+LO%<constant> (BFD_RELOC_GOT_LO16) */
3850 sprintf (tmp
, "addi_u_pic %s, %s + %d", "r1", add_symbol
->bsym
->name
, lo
);
3851 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
3854 memcpy (&var_insts
[0], &inst
, sizeof (struct score_it
));
3855 build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
3857 /* Insn 4: add rD, rD, r1 */
3858 sprintf (tmp
, "add r%d, r%d, %s", reg_rd
, reg_rd
, "r1");
3859 if (append_insn (tmp
, TRUE
) == (int) FAIL
)
3862 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
3871 do_macro_la_rdi32 (char *str
)
3875 skip_whitespace (str
);
3876 if ((reg_rd
= reg_required_here (&str
, 20, REG_TYPE_SCORE
)) == (int) FAIL
3877 || skip_past_comma (&str
) == (int) FAIL
)
3883 char append_str
[MAX_LITERAL_POOL_SIZE
];
3884 char *keep_data
= str
;
3886 /* la rd, simm16. */
3887 if (data_op2 (&str
, 1, _SIMM16_LA
) != (int) FAIL
)
3892 /* la rd, imm32 or la rd, label. */
3895 SET_INSN_ERROR (NULL
);
3897 if ((data_op2 (&str
, 1, _VALUE_HI16
) == (int) FAIL
)
3898 || (end_of_line (str
) == (int) FAIL
))
3904 if ((score_pic
== NO_PIC
) || (!inst
.reloc
.exp
.X_add_symbol
))
3906 sprintf (append_str
, "ld_i32hi r%d, %s", reg_rd
, keep_data
);
3907 if (append_insn (append_str
, TRUE
) == (int) FAIL
)
3910 sprintf (append_str
, "ld_i32lo r%d, %s", reg_rd
, keep_data
);
3911 if (append_insn (append_str
, TRUE
) == (int) FAIL
)
3916 assert (inst
.reloc
.exp
.X_add_symbol
);
3917 build_la_pic (reg_rd
, inst
.reloc
.exp
);
3920 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
3929 do_macro_li_rdi32 (char *str
){
3933 skip_whitespace (str
);
3934 if ((reg_rd
= reg_required_here (&str
, 20, REG_TYPE_SCORE
)) == (int) FAIL
3935 || skip_past_comma (&str
) == (int) FAIL
)
3941 char *keep_data
= str
;
3943 /* li rd, simm16. */
3944 if (data_op2 (&str
, 1, _SIMM16_LA
) != (int) FAIL
)
3952 char append_str
[MAX_LITERAL_POOL_SIZE
];
3956 if ((data_op2 (&str
, 1, _VALUE_HI16
) == (int) FAIL
)
3957 || (end_of_line (str
) == (int) FAIL
))
3961 else if (inst
.reloc
.exp
.X_add_symbol
)
3963 inst
.error
= _("li rd label isn't correct instruction form");
3968 sprintf (append_str
, "ld_i32hi r%d, %s", reg_rd
, keep_data
);
3970 if (append_insn (append_str
, TRUE
) == (int) FAIL
)
3974 sprintf (append_str
, "ld_i32lo r%d, %s", reg_rd
, keep_data
);
3975 if (append_insn (append_str
, TRUE
) == (int) FAIL
)
3978 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
3986 /* Handle mul/mulu/div/divu/rem/remu. */
3988 do_macro_mul_rdrsrs (char *str
)
3994 char append_str
[MAX_LITERAL_POOL_SIZE
];
3996 if (university_version
== 1)
3997 as_warn ("%s", ERR_FOR_SCORE5U_MUL_DIV
);
3999 strcpy (append_str
, str
);
4000 backupstr
= append_str
;
4001 skip_whitespace (backupstr
);
4002 if (((reg_rd
= reg_required_here (&backupstr
, -1, REG_TYPE_SCORE
)) == (int) FAIL
)
4003 || (skip_past_comma (&backupstr
) == (int) FAIL
)
4004 || ((reg_rs1
= reg_required_here (&backupstr
, -1, REG_TYPE_SCORE
)) == (int) FAIL
))
4006 inst
.error
= BAD_ARGS
;
4010 if (skip_past_comma (&backupstr
) == (int) FAIL
)
4012 /* rem/remu rA, rB is error format. */
4013 if (strcmp (inst
.name
, "rem") == 0 || strcmp (inst
.name
, "remu") == 0)
4015 SET_INSN_ERROR (BAD_ARGS
);
4019 SET_INSN_ERROR (NULL
);
4026 SET_INSN_ERROR (NULL
);
4027 if (((reg_rs2
= reg_required_here (&backupstr
, -1, REG_TYPE_SCORE
)) == (int) FAIL
)
4028 || (end_of_line (backupstr
) == (int) FAIL
))
4034 char append_str1
[MAX_LITERAL_POOL_SIZE
];
4036 if (strcmp (inst
.name
, "rem") == 0)
4038 sprintf (append_str
, "%s r%d, r%d", "mul", reg_rs1
, reg_rs2
);
4039 sprintf (append_str1
, "mfceh r%d", reg_rd
);
4041 else if (strcmp (inst
.name
, "remu") == 0)
4043 sprintf (append_str
, "%s r%d, r%d", "mulu", reg_rs1
, reg_rs2
);
4044 sprintf (append_str1
, "mfceh r%d", reg_rd
);
4048 sprintf (append_str
, "%s r%d, r%d", inst
.name
, reg_rs1
, reg_rs2
);
4049 sprintf (append_str1
, "mfcel r%d", reg_rd
);
4052 /* Output mul/mulu or div/divu or rem/remu. */
4053 if (append_insn (append_str
, TRUE
) == (int) FAIL
)
4056 /* Output mfcel or mfceh. */
4057 if (append_insn (append_str1
, TRUE
) == (int) FAIL
)
4060 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4067 exp_macro_ldst_abs (char *str
)
4070 char *backupstr
, *tmp
;
4071 char append_str
[MAX_LITERAL_POOL_SIZE
];
4072 char verifystr
[MAX_LITERAL_POOL_SIZE
];
4073 struct score_it inst_backup
;
4078 memcpy (&inst_backup
, &inst
, sizeof (struct score_it
));
4080 strcpy (verifystr
, str
);
4081 backupstr
= verifystr
;
4082 skip_whitespace (backupstr
);
4083 if ((reg_rd
= reg_required_here (&backupstr
, -1, REG_TYPE_SCORE
)) == (int) FAIL
)
4087 if (skip_past_comma (&backupstr
) == (int) FAIL
)
4091 sprintf (append_str
, "li r1 %s", backupstr
);
4092 append_insn (append_str
, TRUE
);
4094 memcpy (&inst
, &inst_backup
, sizeof (struct score_it
));
4095 sprintf (append_str
, " r%d, [r1,0]", reg_rd
);
4096 do_ldst_insn (append_str
);
4102 nopic_need_relax (symbolS
* sym
, int before_relaxing
)
4106 else if (USE_GLOBAL_POINTER_OPT
&& g_switch_value
> 0)
4108 const char *symname
;
4109 const char *segname
;
4111 /* Find out whether this symbol can be referenced off the $gp
4112 register. It can be if it is smaller than the -G size or if
4113 it is in the .sdata or .sbss section. Certain symbols can
4114 not be referenced off the $gp, although it appears as though
4116 symname
= S_GET_NAME (sym
);
4117 if (symname
!= (const char *)NULL
4118 && (strcmp (symname
, "eprol") == 0
4119 || strcmp (symname
, "etext") == 0
4120 || strcmp (symname
, "_gp") == 0
4121 || strcmp (symname
, "edata") == 0
4122 || strcmp (symname
, "_fbss") == 0
4123 || strcmp (symname
, "_fdata") == 0
4124 || strcmp (symname
, "_ftext") == 0
4125 || strcmp (symname
, "end") == 0
4126 || strcmp (symname
, GP_DISP_LABEL
) == 0))
4130 else if ((!S_IS_DEFINED (sym
) || S_IS_COMMON (sym
)) && (0
4131 /* We must defer this decision until after the whole file has been read,
4132 since there might be a .extern after the first use of this symbol. */
4134 && S_GET_VALUE (sym
) == 0)
4135 || (S_GET_VALUE (sym
) != 0
4136 && S_GET_VALUE (sym
) <= g_switch_value
)))
4141 segname
= segment_name (S_GET_SEGMENT (sym
));
4142 return (strcmp (segname
, ".sdata") != 0
4143 && strcmp (segname
, ".sbss") != 0
4144 && strncmp (segname
, ".sdata.", 7) != 0
4145 && strncmp (segname
, ".gnu.linkonce.s.", 16) != 0);
4147 /* We are not optimizing for the $gp register. */
4152 /* Build a relax frag for lw instruction when generating PIC,
4153 external symbol first and local symbol second. */
4156 build_lw_pic (int reg_rd
, expressionS exp
)
4158 symbolS
*add_symbol
= exp
.X_add_symbol
;
4159 int add_number
= exp
.X_add_number
;
4160 struct score_it fix_insts
[RELAX_INST_NUM
];
4161 struct score_it var_insts
[RELAX_INST_NUM
];
4164 char tmp
[MAX_LITERAL_POOL_SIZE
];
4170 if ((add_number
== 0) || (add_number
>= -0x8000 && add_number
<= 0x7fff))
4175 /* Insn 1 and Insn 2 */
4177 For an external symbol: lw rD, <sym>($gp)
4178 (BFD_RELOC_SCORE_GOT15) */
4179 sprintf (tmp
, "lw_pic r%d, %s", reg_rd
, add_symbol
->bsym
->name
);
4180 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
4183 memcpy (&fix_insts
[0], &inst
, sizeof (struct score_it
));
4186 For a local symbol :
4187 lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15)
4188 addi rD, <sym> (BFD_RELOC_GOT_LO16) */
4189 inst
.reloc
.type
= BFD_RELOC_SCORE_GOT15
;
4190 memcpy (&var_insts
[0], &inst
, sizeof (struct score_it
));
4191 sprintf (tmp
, "addi_s_pic r%d, %s", reg_rd
, add_symbol
->bsym
->name
);
4192 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
4195 memcpy (&var_insts
[1], &inst
, sizeof (struct score_it
));
4196 build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
4198 /* Insn 2: lw rD, [rD, constant] */
4199 sprintf (tmp
, "lw r%d, [r%d, %d]", reg_rd
, reg_rd
, add_number
);
4200 if (append_insn (tmp
, TRUE
) == (int) FAIL
)
4203 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4208 int hi
= (add_number
>> 16) & 0x0000FFFF;
4209 int lo
= add_number
& 0x0000FFFF;
4211 /* Insn 1: lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15) */
4212 sprintf (tmp
, "lw_pic r%d, %s", reg_rd
, add_symbol
->bsym
->name
);
4213 if (append_insn (tmp
, TRUE
) == (int) FAIL
)
4220 For an external symbol: ldis r1, HI%<constant> */
4221 sprintf (tmp
, "ldis %s, %d", "r1", hi
);
4222 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
4225 memcpy (&fix_insts
[0], &inst
, sizeof (struct score_it
));
4228 For a local symbol: ldis r1, HI%<constant>
4229 but, if lo is outof 16 bit, make hi plus 1 */
4230 if ((lo
< -0x8000) || (lo
> 0x7fff))
4234 sprintf (tmp
, "ldis_pic %s, %d", "r1", hi
);
4235 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
4238 memcpy (&var_insts
[0], &inst
, sizeof (struct score_it
));
4239 build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
4245 For an external symbol: ori r1, LO%<constant> */
4246 sprintf (tmp
, "ori %s, %d", "r1", lo
);
4247 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
4250 memcpy (&fix_insts
[0], &inst
, sizeof (struct score_it
));
4253 For a local symbol: addi r1, <sym>+LO%<constant> (BFD_RELOC_GOT_LO16) */
4254 sprintf (tmp
, "addi_u_pic %s, %s + %d", "r1", add_symbol
->bsym
->name
, lo
);
4255 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
4258 memcpy (&var_insts
[0], &inst
, sizeof (struct score_it
));
4259 build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
4261 /* Insn 4: add rD, rD, r1 */
4262 sprintf (tmp
, "add r%d, r%d, %s", reg_rd
, reg_rd
, "r1");
4263 if (append_insn (tmp
, TRUE
) == (int) FAIL
)
4266 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4269 /* Insn 5: lw rD, [rD, 0] */
4270 sprintf (tmp
, "lw r%d, [r%d, 0]", reg_rd
, reg_rd
);
4271 if (append_insn (tmp
, TRUE
) == (int) FAIL
)
4274 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4282 do_macro_ldst_label (char *str
)
4290 char *absolute_value
;
4291 char append_str
[3][MAX_LITERAL_POOL_SIZE
];
4292 char verifystr
[MAX_LITERAL_POOL_SIZE
];
4293 struct score_it inst_backup
;
4294 struct score_it inst_expand
[3];
4295 struct score_it inst_main
;
4297 memcpy (&inst_backup
, &inst
, sizeof (struct score_it
));
4298 strcpy (verifystr
, str
);
4299 backup_str
= verifystr
;
4301 skip_whitespace (backup_str
);
4302 if ((reg_rd
= reg_required_here (&backup_str
, -1, REG_TYPE_SCORE
)) == (int) FAIL
)
4305 if (skip_past_comma (&backup_str
) == (int) FAIL
)
4308 label_str
= backup_str
;
4310 /* Ld/st rD, [rA, imm] ld/st rD, [rA]+, imm ld/st rD, [rA, imm]+. */
4311 if (*backup_str
== '[')
4313 inst
.type
= Rd_rvalueRs_preSI12
;
4318 /* Ld/st rD, imm. */
4319 absolute_value
= backup_str
;
4320 inst
.type
= Rd_rvalueRs_SI15
;
4321 if ((my_get_expression (&inst
.reloc
.exp
, &backup_str
) == (int) FAIL
)
4322 || (validate_immediate (inst
.reloc
.exp
.X_add_number
, _VALUE
) == (int) FAIL
)
4323 || (end_of_line (backup_str
) == (int) FAIL
))
4329 if (inst
.reloc
.exp
.X_add_symbol
== 0)
4331 memcpy (&inst
, &inst_backup
, sizeof (struct score_it
));
4332 exp_macro_ldst_abs (str
);
4337 /* Ld/st rD, label. */
4338 inst
.type
= Rd_rvalueRs_SI15
;
4339 backup_str
= absolute_value
;
4340 if ((data_op2 (&backup_str
, 1, _GP_IMM15
) == (int) FAIL
)
4341 || (end_of_line (backup_str
) == (int) FAIL
))
4347 if (inst
.reloc
.exp
.X_add_symbol
== 0)
4350 inst
.error
= BAD_ARGS
;
4355 if (score_pic
== PIC
)
4357 build_lw_pic (reg_rd
, inst
.reloc
.exp
);
4362 if ((inst
.reloc
.exp
.X_add_number
<= 0x3fff)
4363 && (inst
.reloc
.exp
.X_add_number
>= -0x4000)
4364 && (!nopic_need_relax (inst
.reloc
.exp
.X_add_symbol
, 1)))
4368 /* Assign the real opcode. */
4369 ldst_idx
= inst
.instruction
& OPC_PSEUDOLDST_MASK
;
4370 inst
.instruction
&= ~OPC_PSEUDOLDST_MASK
;
4371 inst
.instruction
|= score_ldst_insns
[ldst_idx
* 3 + 0].value
;
4372 inst
.instruction
|= reg_rd
<< 20;
4373 inst
.instruction
|= GP
<< 15;
4374 inst
.relax_inst
= 0x8000;
4375 inst
.relax_size
= 0;
4382 memcpy (&inst_main
, &inst
, sizeof (struct score_it
));
4386 /* Determine which instructions should be output. */
4387 sprintf (append_str
[0], "ld_i32hi r1, %s", label_str
);
4388 sprintf (append_str
[1], "ld_i32lo r1, %s", label_str
);
4389 sprintf (append_str
[2], "%s r%d, [r1, 0]", inst_backup
.name
, reg_rd
);
4391 /* Generate three instructions.
4393 ld/st rd, [r1, 0] */
4394 for (i
= 0; i
< 3; i
++)
4396 if (append_insn (append_str
[i
], FALSE
) == (int) FAIL
)
4399 memcpy (&inst_expand
[i
], &inst
, sizeof (struct score_it
));
4406 /* Adjust instruction opcode and to be relaxed instruction opcode. */
4407 inst_main
.instruction
= adjust_paritybit (inst_main
.instruction
, GET_INSN_CLASS (inst_main
.type
));
4408 inst_main
.relax_size
= inst_expand
[0].size
+ inst_expand
[1].size
+ inst_expand
[2].size
;
4409 inst_main
.type
= Insn_GP
;
4411 for (i
= 0; i
< 3; i
++)
4412 inst_expand
[i
].instruction
= adjust_paritybit (inst_expand
[i
].instruction
4413 , GET_INSN_CLASS (inst_expand
[i
].type
));
4415 /* Check data dependency. */
4416 handle_dependency (&inst_main
);
4418 /* Start a new frag if frag_now is not empty. */
4419 if (frag_now_fix () != 0)
4421 if (!frag_now
->tc_frag_data
.is_insn
)
4422 frag_wane (frag_now
);
4428 /* Write fr_fix part. */
4429 p
= frag_more (inst_main
.size
);
4430 md_number_to_chars (p
, inst_main
.instruction
, inst_main
.size
);
4432 if (inst_main
.reloc
.type
!= BFD_RELOC_NONE
)
4434 fix_new_score (frag_now
, p
- frag_now
->fr_literal
, inst_main
.size
,
4435 &inst_main
.reloc
.exp
, inst_main
.reloc
.pc_rel
, inst_main
.reloc
.type
);
4439 dwarf2_emit_insn (inst_main
.size
);
4442 /* GP instruction can not do optimization, only can do relax between
4443 1 instruction and 3 instructions. */
4444 p
= frag_var (rs_machine_dependent
, inst_main
.relax_size
+ RELAX_PAD_BYTE
, 0,
4445 RELAX_ENCODE (inst_main
.size
, inst_main
.relax_size
, inst_main
.type
, 0, 4, 0),
4446 inst_main
.reloc
.exp
.X_add_symbol
, 0, NULL
);
4448 /* Write fr_var part.
4449 no calling gen_insn_frag, no fixS will be generated. */
4450 md_number_to_chars (p
, inst_expand
[0].instruction
, inst_expand
[0].size
);
4451 p
+= inst_expand
[0].size
;
4452 md_number_to_chars (p
, inst_expand
[1].instruction
, inst_expand
[1].size
);
4453 p
+= inst_expand
[1].size
;
4454 md_number_to_chars (p
, inst_expand
[2].instruction
, inst_expand
[2].size
);
4458 gen_insn_frag (&inst_expand
[0], NULL
);
4459 gen_insn_frag (&inst_expand
[1], NULL
);
4460 gen_insn_frag (&inst_expand
[2], NULL
);
4464 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4469 do_lw_pic (char *str
)
4473 skip_whitespace (str
);
4474 if (((reg_rd
= reg_required_here (&str
, 20, REG_TYPE_SCORE
)) == (int) FAIL
)
4475 || (skip_past_comma (&str
) == (int) FAIL
)
4476 || (my_get_expression (&inst
.reloc
.exp
, &str
) == (int) FAIL
)
4477 || (end_of_line (str
) == (int) FAIL
))
4483 if (inst
.reloc
.exp
.X_add_symbol
== 0)
4486 inst
.error
= BAD_ARGS
;
4491 inst
.instruction
|= GP
<< 15;
4492 inst
.reloc
.type
= BFD_RELOC_SCORE_GOT15
;
4497 do_empty (char *str
)
4500 if (university_version
== 1)
4502 if (((inst
.instruction
& 0x3e0003ff) == 0x0c000004)
4503 || ((inst
.instruction
& 0x3e0003ff) == 0x0c000024)
4504 || ((inst
.instruction
& 0x3e0003ff) == 0x0c000044)
4505 || ((inst
.instruction
& 0x3e0003ff) == 0x0c000064))
4507 inst
.error
= ERR_FOR_SCORE5U_MMU
;
4511 if (end_of_line (str
) == (int) FAIL
)
4514 if (inst
.relax_inst
!= 0x8000)
4516 if (inst
.type
== NO_OPD
)
4518 inst
.relax_size
= 2;
4522 inst
.relax_size
= 4;
4533 skip_whitespace (str
);
4534 if (my_get_expression (&inst
.reloc
.exp
, &str
) == (int) FAIL
4535 || end_of_line (str
) == (int) FAIL
)
4538 if (inst
.reloc
.exp
.X_add_symbol
== 0)
4540 inst
.error
= _("lacking label ");
4544 if (((inst
.reloc
.exp
.X_add_number
& 0xff000000) != 0)
4545 && ((inst
.reloc
.exp
.X_add_number
& 0xff000000) != 0xff000000))
4547 sprintf (err_msg
, "invalid constant: 25 bit expression not in range -2^24..2^24");
4548 inst
.error
= _(err_msg
);
4552 save_in
= input_line_pointer
;
4553 input_line_pointer
= str
;
4554 inst
.reloc
.type
= BFD_RELOC_SCORE_JMP
;
4555 inst
.reloc
.pc_rel
= 1;
4556 input_line_pointer
= save_in
;
4560 do16_jump (char *str
)
4562 skip_whitespace (str
);
4563 if (my_get_expression (&inst
.reloc
.exp
, &str
) == (int) FAIL
4564 || end_of_line (str
) == (int) FAIL
)
4568 else if (inst
.reloc
.exp
.X_add_symbol
== 0)
4570 inst
.error
= _("lacking label ");
4573 else if (((inst
.reloc
.exp
.X_add_number
& 0xfffff800) != 0)
4574 && ((inst
.reloc
.exp
.X_add_number
& 0xfffff800) != 0xfffff800))
4576 inst
.error
= _("invalid constant: 12 bit expression not in range -2^11..2^11");
4580 inst
.reloc
.type
= BFD_RELOC_SCORE16_JMP
;
4581 inst
.reloc
.pc_rel
= 1;
4585 do_branch (char *str
)
4587 unsigned long abs_value
= 0;
4589 if (my_get_expression (&inst
.reloc
.exp
, &str
) == (int) FAIL
4590 || end_of_line (str
) == (int) FAIL
)
4594 else if (inst
.reloc
.exp
.X_add_symbol
== 0)
4596 inst
.error
= _("lacking label ");
4599 else if (((inst
.reloc
.exp
.X_add_number
& 0xff000000) != 0)
4600 && ((inst
.reloc
.exp
.X_add_number
& 0xff000000) != 0xff000000))
4602 inst
.error
= "invalid constant: 20 bit expression not in range -2^19..2^19";
4606 inst
.reloc
.type
= BFD_RELOC_SCORE_BRANCH
;
4607 inst
.reloc
.pc_rel
= 1;
4609 /* Branch 32 offset field : 20 bit, 16 bit branch offset field : 8 bit. */
4610 inst
.instruction
|= (inst
.reloc
.exp
.X_add_number
& 0x3fe) | ((inst
.reloc
.exp
.X_add_number
& 0xffc00) << 5);
4612 /* Compute 16 bit branch instruction. */
4613 if ((inst
.relax_inst
!= 0x8000) && (abs_value
& 0xfffffe00) == 0)
4615 inst
.relax_inst
|= (((inst
.instruction
>> 10) & 0xf) << 8);
4616 inst
.relax_inst
|= ((inst
.reloc
.exp
.X_add_number
>> 1) & 0xff);
4617 inst
.relax_size
= 2;
4621 inst
.relax_inst
= 0x8000;
4626 do16_branch (char *str
)
4628 if ((my_get_expression (&inst
.reloc
.exp
, &str
) == (int) FAIL
4629 || end_of_line (str
) == (int) FAIL
))
4633 else if (inst
.reloc
.exp
.X_add_symbol
== 0)
4635 inst
.error
= _("lacking label");
4637 else if (((inst
.reloc
.exp
.X_add_number
& 0xffffff00) != 0)
4638 && ((inst
.reloc
.exp
.X_add_number
& 0xffffff00) != 0xffffff00))
4640 inst
.error
= _("invalid constant: 9 bit expression not in range -2^8..2^8");
4644 inst
.reloc
.type
= BFD_RELOC_SCORE16_BRANCH
;
4645 inst
.reloc
.pc_rel
= 1;
4646 inst
.instruction
|= ((inst
.reloc
.exp
.X_add_number
>> 1) & 0xff);
4650 /* Iterate over the base tables to create the instruction patterns. */
4652 build_score_ops_hsh (void)
4655 static struct obstack insn_obstack
;
4657 obstack_begin (&insn_obstack
, 4000);
4658 for (i
= 0; i
< sizeof (score_insns
) / sizeof (struct asm_opcode
); i
++)
4660 const struct asm_opcode
*insn
= score_insns
+ i
;
4661 unsigned len
= strlen (insn
->template);
4662 struct asm_opcode
*new;
4664 new = obstack_alloc (&insn_obstack
, sizeof (struct asm_opcode
));
4665 template = obstack_alloc (&insn_obstack
, len
+ 1);
4667 strcpy (template, insn
->template);
4668 new->template = template;
4669 new->parms
= insn
->parms
;
4670 new->value
= insn
->value
;
4671 new->relax_value
= insn
->relax_value
;
4672 new->type
= insn
->type
;
4673 new->bitmask
= insn
->bitmask
;
4674 hash_insert (score_ops_hsh
, new->template, (void *) new);
4679 build_dependency_insn_hsh (void)
4682 static struct obstack dependency_obstack
;
4684 obstack_begin (&dependency_obstack
, 4000);
4685 for (i
= 0; i
< sizeof (insn_to_dependency_table
) / sizeof (insn_to_dependency_table
[0]); i
++)
4687 const struct insn_to_dependency
*tmp
= insn_to_dependency_table
+ i
;
4688 unsigned len
= strlen (tmp
->insn_name
);
4689 struct insn_to_dependency
*new;
4691 new = obstack_alloc (&dependency_obstack
, sizeof (struct insn_to_dependency
));
4692 new->insn_name
= obstack_alloc (&dependency_obstack
, len
+ 1);
4694 strcpy (new->insn_name
, tmp
->insn_name
);
4695 new->type
= tmp
->type
;
4696 hash_insert (dependency_insn_hsh
, new->insn_name
, (void *) new);
4700 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
4701 for use in the a.out file, and stores them in the array pointed to by buf.
4702 This knows about the endian-ness of the target machine and does
4703 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
4704 2 (short) and 4 (long) Floating numbers are put out as a series of
4705 LITTLENUMS (shorts, here at least). */
4708 md_number_to_chars (char *buf
, valueT val
, int n
)
4710 if (target_big_endian
)
4711 number_to_chars_bigendian (buf
, val
, n
);
4713 number_to_chars_littleendian (buf
, val
, n
);
4717 md_chars_to_number (char *buf
, int n
)
4720 unsigned char *where
= (unsigned char *)buf
;
4722 if (target_big_endian
)
4727 result
|= (*where
++ & 255);
4735 result
|= (where
[n
] & 255);
4742 /* Turn a string in input_line_pointer into a floating point constant
4743 of type TYPE, and store the appropriate bytes in *LITP. The number
4744 of LITTLENUMS emitted is stored in *SIZEP. An error message is
4745 returned, or NULL on OK.
4747 Note that fp constants aren't represent in the normal way on the ARM.
4748 In big endian mode, things are as expected. However, in little endian
4749 mode fp constants are big-endian word-wise, and little-endian byte-wise
4750 within the words. For example, (double) 1.1 in big endian mode is
4751 the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
4752 the byte sequence 99 99 f1 3f 9a 99 99 99. */
4755 md_atof (int type
, char *litP
, int *sizeP
)
4758 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
4784 return _("bad call to MD_ATOF()");
4787 t
= atof_ieee (input_line_pointer
, type
, words
);
4789 input_line_pointer
= t
;
4792 if (target_big_endian
)
4794 for (i
= 0; i
< prec
; i
++)
4796 md_number_to_chars (litP
, (valueT
) words
[i
], 2);
4802 for (i
= 0; i
< prec
; i
+= 2)
4804 md_number_to_chars (litP
, (valueT
) words
[i
+ 1], 2);
4805 md_number_to_chars (litP
+ 2, (valueT
) words
[i
], 2);
4813 /* Return true if the given symbol should be considered local for PIC. */
4816 pic_need_relax (symbolS
*sym
, asection
*segtype
)
4819 bfd_boolean linkonce
;
4821 /* Handle the case of a symbol equated to another symbol. */
4822 while (symbol_equated_reloc_p (sym
))
4826 /* It's possible to get a loop here in a badly written
4828 n
= symbol_get_value_expression (sym
)->X_add_symbol
;
4834 symsec
= S_GET_SEGMENT (sym
);
4836 /* duplicate the test for LINK_ONCE sections as in adjust_reloc_syms */
4838 if (symsec
!= segtype
&& ! S_IS_LOCAL (sym
))
4840 if ((bfd_get_section_flags (stdoutput
, symsec
) & SEC_LINK_ONCE
) != 0)
4843 /* The GNU toolchain uses an extension for ELF: a section
4844 beginning with the magic string .gnu.linkonce is a linkonce
4846 if (strncmp (segment_name (symsec
), ".gnu.linkonce",
4847 sizeof ".gnu.linkonce" - 1) == 0)
4851 /* This must duplicate the test in adjust_reloc_syms. */
4852 return (symsec
!= &bfd_und_section
4853 && symsec
!= &bfd_abs_section
4854 && ! bfd_is_com_section (symsec
)
4857 /* A global or weak symbol is treated as external. */
4858 && (OUTPUT_FLAVOR
!= bfd_target_elf_flavour
4859 || (! S_IS_WEAK (sym
) && ! S_IS_EXTERNAL (sym
)))
4865 judge_size_before_relax (fragS
* fragp
, asection
*sec
)
4869 if (score_pic
== NO_PIC
)
4870 change
= nopic_need_relax (fragp
->fr_symbol
, 0);
4872 change
= pic_need_relax (fragp
->fr_symbol
, sec
);
4876 /* Only at the first time determining whether GP instruction relax should be done,
4877 return the difference between insntruction size and instruction relax size. */
4878 if (fragp
->fr_opcode
== NULL
)
4880 fragp
->fr_fix
= RELAX_NEW (fragp
->fr_subtype
);
4881 fragp
->fr_opcode
= fragp
->fr_literal
+ RELAX_RELOC1 (fragp
->fr_subtype
);
4882 return RELAX_NEW (fragp
->fr_subtype
) - RELAX_OLD (fragp
->fr_subtype
);
4889 /* In this function, we determine whether GP instruction should do relaxation,
4890 for the label being against was known now.
4891 Doing this here but not in md_relax_frag() can induce iteration times
4892 in stage of doing relax. */
4894 md_estimate_size_before_relax (fragS
* fragp
, asection
* sec ATTRIBUTE_UNUSED
)
4896 if ((RELAX_TYPE (fragp
->fr_subtype
) == Insn_GP
)
4897 || (RELAX_TYPE (fragp
->fr_subtype
) == Insn_PIC
))
4898 return judge_size_before_relax (fragp
, sec
);
4904 b32_relax_to_b16 (fragS
* fragp
)
4907 int relaxable_p
= 0;
4910 int frag_addr
= fragp
->fr_address
+ fragp
->insn_addr
;
4912 addressT symbol_address
= 0;
4915 unsigned long value
;
4916 unsigned long abs_value
;
4918 /* FIXME : here may be able to modify better .
4919 I don't know how to get the fragp's section ,
4920 so in relax stage , it may be wrong to calculate the symbol's offset when the frag's section
4921 is different from the symbol's. */
4923 old
= RELAX_OLD (fragp
->fr_subtype
);
4924 new = RELAX_NEW (fragp
->fr_subtype
);
4925 relaxable_p
= RELAX_OPT (fragp
->fr_subtype
);
4927 s
= fragp
->fr_symbol
;
4928 /* b/bl immediate */
4934 symbol_address
= (addressT
) s
->sy_frag
->fr_address
;
4937 value
= md_chars_to_number (fragp
->fr_literal
, INSN_SIZE
);
4939 /* b 32's offset : 20 bit, b 16's tolerate field : 0xff. */
4940 offset
= ((value
& 0x3ff0000) >> 6) | (value
& 0x3fe);
4941 if ((offset
& 0x80000) == 0x80000)
4942 offset
|= 0xfff00000;
4944 abs_value
= offset
+ symbol_address
- frag_addr
;
4945 if ((abs_value
& 0x80000000) == 0x80000000)
4946 abs_value
= 0xffffffff - abs_value
+ 1;
4948 /* Relax branch 32 to branch 16. */
4949 if (relaxable_p
&& (s
->bsym
!= NULL
) && ((abs_value
& 0xffffff00) == 0)
4950 && (S_IS_DEFINED (s
) && !S_IS_COMMON (s
) && !S_IS_EXTERNAL (s
)))
4956 /* Branch 32 can not be relaxed to b 16, so clear OPT bit. */
4957 fragp
->fr_opcode
= NULL
;
4958 fragp
->fr_subtype
= RELAX_OPT_CLEAR (fragp
->fr_subtype
);
4964 /* Main purpose is to determine whether one frag should do relax.
4965 frag->fr_opcode indicates this point. */
4968 score_relax_frag (asection
* sec ATTRIBUTE_UNUSED
, fragS
* fragp
, long stretch ATTRIBUTE_UNUSED
)
4972 int insn_relax_size
;
4973 int do_relax_p
= 0; /* Indicate doing relaxation for this frag. */
4974 int relaxable_p
= 0;
4975 bfd_boolean word_align_p
= FALSE
;
4978 /* If the instruction address is odd, make it half word align first. */
4979 if ((fragp
->fr_address
) % 2 != 0)
4981 if ((fragp
->fr_address
+ fragp
->insn_addr
) % 2 != 0)
4983 fragp
->insn_addr
= 1;
4988 word_align_p
= ((fragp
->fr_address
+ fragp
->insn_addr
) % 4 == 0) ? TRUE
: FALSE
;
4990 /* Get instruction size and relax size after the last relaxation. */
4991 if (fragp
->fr_opcode
)
4993 insn_size
= RELAX_NEW (fragp
->fr_subtype
);
4994 insn_relax_size
= RELAX_OLD (fragp
->fr_subtype
);
4998 insn_size
= RELAX_OLD (fragp
->fr_subtype
);
4999 insn_relax_size
= RELAX_NEW (fragp
->fr_subtype
);
5002 /* Handle specially for GP instruction. for, judge_size_before_relax() has already determine
5003 whether the GP instruction should do relax. */
5004 if ((RELAX_TYPE (fragp
->fr_subtype
) == Insn_GP
)
5005 || (RELAX_TYPE (fragp
->fr_subtype
) == Insn_PIC
))
5009 fragp
->insn_addr
+= 2;
5013 if (fragp
->fr_opcode
)
5014 fragp
->fr_fix
= RELAX_NEW (fragp
->fr_subtype
) + fragp
->insn_addr
;
5016 fragp
->fr_fix
= RELAX_OLD (fragp
->fr_subtype
) + fragp
->insn_addr
;
5020 if (RELAX_TYPE (fragp
->fr_subtype
) == PC_DISP19div2
)
5021 b32_relax_to_b16 (fragp
);
5023 relaxable_p
= RELAX_OPT (fragp
->fr_subtype
);
5024 next_fragp
= fragp
->fr_next
;
5025 while ((next_fragp
) && (next_fragp
->fr_type
!= rs_machine_dependent
))
5027 next_fragp
= next_fragp
->fr_next
;
5033 int n_relaxable_p
= 0;
5035 if (next_fragp
->fr_opcode
)
5037 n_insn_size
= RELAX_NEW (next_fragp
->fr_subtype
);
5041 n_insn_size
= RELAX_OLD (next_fragp
->fr_subtype
);
5044 if (RELAX_TYPE (next_fragp
->fr_subtype
) == PC_DISP19div2
)
5045 b32_relax_to_b16 (next_fragp
);
5046 n_relaxable_p
= RELAX_OPT (next_fragp
->fr_subtype
);
5053 if (relaxable_p
&& ((n_insn_size
== 2) || n_relaxable_p
))
5059 else if (insn_size
== 2)
5062 if (relaxable_p
&& (((n_insn_size
== 4) && !n_relaxable_p
) || (n_insn_size
> 4)))
5083 /* Make the 32 bit insturction word align. */
5086 fragp
->insn_addr
+= 2;
5090 else if (insn_size
== 2)
5102 /* Here, try best to do relax regardless fragp->fr_next->fr_type. */
5103 if (word_align_p
== FALSE
)
5105 if (insn_size
% 4 == 0)
5115 fragp
->insn_addr
+= 2;
5126 /* fragp->fr_opcode indicates whether this frag should be relaxed. */
5129 if (fragp
->fr_opcode
)
5131 fragp
->fr_opcode
= NULL
;
5132 /* Guarantee estimate stage is correct. */
5133 fragp
->fr_fix
= RELAX_OLD (fragp
->fr_subtype
);
5134 fragp
->fr_fix
+= fragp
->insn_addr
;
5138 fragp
->fr_opcode
= fragp
->fr_literal
+ RELAX_RELOC1 (fragp
->fr_subtype
);
5139 /* Guarantee estimate stage is correct. */
5140 fragp
->fr_fix
= RELAX_NEW (fragp
->fr_subtype
);
5141 fragp
->fr_fix
+= fragp
->insn_addr
;
5146 if (fragp
->fr_opcode
)
5148 /* Guarantee estimate stage is correct. */
5149 fragp
->fr_fix
= RELAX_NEW (fragp
->fr_subtype
);
5150 fragp
->fr_fix
+= fragp
->insn_addr
;
5154 /* Guarantee estimate stage is correct. */
5155 fragp
->fr_fix
= RELAX_OLD (fragp
->fr_subtype
);
5156 fragp
->fr_fix
+= fragp
->insn_addr
;
5165 md_convert_frag (bfd
* abfd ATTRIBUTE_UNUSED
, segT sec ATTRIBUTE_UNUSED
, fragS
* fragp
)
5172 old
= RELAX_OLD (fragp
->fr_subtype
);
5173 new = RELAX_NEW (fragp
->fr_subtype
);
5175 /* fragp->fr_opcode indicates whether this frag should be relaxed. */
5176 if (fragp
->fr_opcode
== NULL
)
5178 memcpy (backup
, fragp
->fr_literal
, old
);
5179 fragp
->fr_fix
= old
;
5183 memcpy (backup
, fragp
->fr_literal
+ old
, new);
5184 fragp
->fr_fix
= new;
5187 fixp
= fragp
->tc_frag_data
.fixp
;
5188 while (fixp
&& fixp
->fx_frag
== fragp
&& fixp
->fx_where
< old
)
5190 if (fragp
->fr_opcode
)
5192 fixp
= fixp
->fx_next
;
5194 while (fixp
&& fixp
->fx_frag
== fragp
)
5196 if (fragp
->fr_opcode
)
5197 fixp
->fx_where
-= old
+ fragp
->insn_addr
;
5200 fixp
= fixp
->fx_next
;
5203 if (fragp
->insn_addr
)
5205 md_number_to_chars (fragp
->fr_literal
, 0x0, fragp
->insn_addr
);
5207 memcpy (fragp
->fr_literal
+ fragp
->insn_addr
, backup
, fragp
->fr_fix
);
5208 fragp
->fr_fix
+= fragp
->insn_addr
;
5211 /* Implementation of md_frag_check.
5212 Called after md_convert_frag(). */
5215 score_frag_check (fragS
* fragp ATTRIBUTE_UNUSED
)
5217 know (fragp
->insn_addr
<= RELAX_PAD_BYTE
);
5221 score_fix_adjustable (fixS
* fixP
)
5223 if (fixP
->fx_addsy
== NULL
)
5227 else if (OUTPUT_FLAVOR
== bfd_target_elf_flavour
5228 && (S_IS_EXTERNAL (fixP
->fx_addsy
) || S_IS_WEAK (fixP
->fx_addsy
)))
5232 else if (fixP
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
5233 || fixP
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
5241 /* Implementation of TC_VALIDATE_FIX.
5242 Called before md_apply_fix() and after md_convert_frag(). */
5244 score_validate_fix (fixS
*fixP
)
5246 fixP
->fx_where
+= fixP
->fx_frag
->insn_addr
;
5250 md_pcrel_from (fixS
* fixP
)
5255 && (S_GET_SEGMENT (fixP
->fx_addsy
) == undefined_section
)
5256 && (fixP
->fx_subsy
== NULL
))
5262 retval
= fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
5269 score_force_relocation (struct fix
*fixp
)
5273 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
5274 || fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
5275 || fixp
->fx_r_type
== BFD_RELOC_SCORE_JMP
5276 || fixp
->fx_r_type
== BFD_RELOC_SCORE_BRANCH
5277 || fixp
->fx_r_type
== BFD_RELOC_SCORE16_JMP
5278 || fixp
->fx_r_type
== BFD_RELOC_SCORE16_BRANCH
)
5286 /* Round up a section size to the appropriate boundary. */
5288 md_section_align (segT segment ATTRIBUTE_UNUSED
, valueT size
)
5290 int align
= bfd_get_section_alignment (stdoutput
, segment
);
5293 /* We don't need to align ELF sections to the full alignment.
5294 However, Irix 5 may prefer that we align them at least to a 16
5295 byte boundary. We don't bother to align the sections if we are
5296 targeted for an embedded system. */
5297 if (strcmp (TARGET_OS
, "elf") == 0)
5303 return ((size
+ (1 << align
) - 1) & (-1 << align
));
5307 md_apply_fix (fixS
*fixP
, valueT
*valP
, segT seg
)
5309 offsetT value
= *valP
;
5310 offsetT abs_value
= 0;
5313 unsigned short HI
, LO
;
5315 char *buf
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
5317 assert (fixP
->fx_r_type
< BFD_RELOC_UNUSED
);
5318 if (fixP
->fx_addsy
== 0 && !fixP
->fx_pcrel
)
5320 if (fixP
->fx_r_type
!= BFD_RELOC_SCORE_DUMMY_HI16
)
5324 /* If this symbol is in a different section then we need to leave it for
5325 the linker to deal with. Unfortunately, md_pcrel_from can't tell,
5326 so we have to undo it's effects here. */
5329 if (fixP
->fx_addsy
!= NULL
5330 && S_IS_DEFINED (fixP
->fx_addsy
)
5331 && S_GET_SEGMENT (fixP
->fx_addsy
) != seg
)
5332 value
+= md_pcrel_from (fixP
);
5335 /* Remember value for emit_reloc. */
5336 fixP
->fx_addnumber
= value
;
5338 switch (fixP
->fx_r_type
)
5340 case BFD_RELOC_HI16_S
:
5342 { /* For la rd, imm32. */
5343 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5344 HI
= (value
) >> 16; /* mul to 2, then take the hi 16 bit. */
5345 newval
|= (HI
& 0x3fff) << 1;
5346 newval
|= ((HI
>> 14) & 0x3) << 16;
5347 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5350 case BFD_RELOC_LO16
:
5351 if (fixP
->fx_done
) /* For la rd, imm32. */
5353 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5354 LO
= (value
) & 0xffff;
5355 newval
|= (LO
& 0x3fff) << 1; /* 16 bit: imm -> 14 bit in lo, 2 bit in hi. */
5356 newval
|= ((LO
>> 14) & 0x3) << 16;
5357 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5360 case BFD_RELOC_SCORE_JMP
:
5362 content
= md_chars_to_number (buf
, INSN_SIZE
);
5363 value
= fixP
->fx_offset
;
5364 content
= (content
& ~0x3ff7ffe) | ((value
<< 1) & 0x3ff0000) | (value
& 0x7fff);
5365 md_number_to_chars (buf
, content
, INSN_SIZE
);
5368 case BFD_RELOC_SCORE_BRANCH
:
5369 if ((S_GET_SEGMENT (fixP
->fx_addsy
) != seg
) || (fixP
->fx_addsy
!= NULL
&& S_IS_EXTERNAL (fixP
->fx_addsy
)))
5370 value
= fixP
->fx_offset
;
5374 content
= md_chars_to_number (buf
, INSN_SIZE
);
5375 if ((fixP
->fx_frag
->fr_opcode
!= 0) && ((content
& 0x80008000) != 0x80008000))
5377 if ((value
& 0x80000000) == 0x80000000)
5378 abs_value
= 0xffffffff - value
+ 1;
5379 if ((abs_value
& 0xffffff00) != 0)
5381 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5382 _(" branch relocation truncate (0x%x) [-2^8 ~ 2^8]"), (unsigned int)value
);
5385 content
= md_chars_to_number (buf
, INSN16_SIZE
);
5387 content
= (content
& 0xff00) | ((value
>> 1) & 0xff);
5388 md_number_to_chars (buf
, content
, INSN16_SIZE
);
5389 fixP
->fx_r_type
= BFD_RELOC_SCORE16_BRANCH
;
5394 if ((value
& 0x80000000) == 0x80000000)
5395 abs_value
= 0xffffffff - value
+ 1;
5396 if ((abs_value
& 0xfff80000) != 0)
5398 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5399 _(" branch relocation truncate (0x%x) [-2^19 ~ 2^19]"), (unsigned int)value
);
5402 content
= md_chars_to_number (buf
, INSN_SIZE
);
5403 content
&= 0xfc00fc01;
5404 content
= (content
& 0xfc00fc01) | (value
& 0x3fe) | ((value
<< 6) & 0x3ff0000);
5405 md_number_to_chars (buf
, content
, INSN_SIZE
);
5408 case BFD_RELOC_SCORE16_JMP
:
5409 content
= md_chars_to_number (buf
, INSN16_SIZE
);
5411 value
= fixP
->fx_offset
& 0xfff;
5412 content
= (content
& 0xfc01) | (value
& 0xffe);
5413 md_number_to_chars (buf
, content
, INSN16_SIZE
);
5415 case BFD_RELOC_SCORE16_BRANCH
:
5416 content
= md_chars_to_number (buf
, INSN_SIZE
);
5417 if ((fixP
->fx_frag
->fr_opcode
!= 0) && ((content
& 0x80008000) == 0x80008000))
5419 if ((S_GET_SEGMENT (fixP
->fx_addsy
) != seg
) ||
5420 (fixP
->fx_addsy
!= NULL
&& S_IS_EXTERNAL (fixP
->fx_addsy
)))
5421 value
= fixP
->fx_offset
;
5424 if ((value
& 0x80000000) == 0x80000000)
5425 abs_value
= 0xffffffff - value
+ 1;
5426 if ((abs_value
& 0xfff80000) != 0)
5428 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5429 _(" branch relocation truncate (0x%x) [-2^19 ~ 2^19]"), (unsigned int)value
);
5432 content
= md_chars_to_number (buf
, INSN_SIZE
);
5433 content
= (content
& 0xfc00fc01) | (value
& 0x3fe) | ((value
<< 6) & 0x3ff0000);
5434 md_number_to_chars (buf
, content
, INSN_SIZE
);
5435 fixP
->fx_r_type
= BFD_RELOC_SCORE_BRANCH
;
5441 /* In differnt section. */
5442 if ((S_GET_SEGMENT (fixP
->fx_addsy
) != seg
) ||
5443 (fixP
->fx_addsy
!= NULL
&& S_IS_EXTERNAL (fixP
->fx_addsy
)))
5444 value
= fixP
->fx_offset
;
5448 if ((value
& 0x80000000) == 0x80000000)
5449 abs_value
= 0xffffffff - value
+ 1;
5450 if ((abs_value
& 0xffffff00) != 0)
5452 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5453 _(" branch relocation truncate (0x%x) [-2^8 ~ 2^8]"), (unsigned int)value
);
5456 content
= md_chars_to_number (buf
, INSN16_SIZE
);
5457 content
= (content
& 0xff00) | ((value
>> 1) & 0xff);
5458 md_number_to_chars (buf
, content
, INSN16_SIZE
);
5462 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5463 md_number_to_chars (buf
, value
, 1);
5467 value
= fixP
->fx_offset
;
5468 md_number_to_chars (buf
, value
, 1);
5474 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5475 md_number_to_chars (buf
, value
, 2);
5479 value
= fixP
->fx_offset
;
5480 md_number_to_chars (buf
, value
, 2);
5486 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5487 md_number_to_chars (buf
, value
, 4);
5491 value
= fixP
->fx_offset
;
5492 md_number_to_chars (buf
, value
, 4);
5496 case BFD_RELOC_VTABLE_INHERIT
:
5498 if (fixP
->fx_addsy
&& !S_IS_DEFINED (fixP
->fx_addsy
) && !S_IS_WEAK (fixP
->fx_addsy
))
5499 S_SET_WEAK (fixP
->fx_addsy
);
5501 case BFD_RELOC_VTABLE_ENTRY
:
5504 case BFD_RELOC_SCORE_GPREL15
:
5505 content
= md_chars_to_number (buf
, INSN_SIZE
);
5506 if ((fixP
->fx_frag
->fr_opcode
!= 0) && ((content
& 0xfc1c8000) != 0x94188000))
5507 fixP
->fx_r_type
= BFD_RELOC_NONE
;
5510 case BFD_RELOC_SCORE_GOT15
:
5511 case BFD_RELOC_SCORE_DUMMY_HI16
:
5512 case BFD_RELOC_SCORE_GOT_LO16
:
5513 case BFD_RELOC_SCORE_CALL15
:
5514 case BFD_RELOC_GPREL32
:
5516 case BFD_RELOC_NONE
:
5518 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("bad relocation fixup type (%d)"), fixP
->fx_r_type
);
5522 /* Translate internal representation of relocation info to BFD target format. */
5524 tc_gen_reloc (asection
* section ATTRIBUTE_UNUSED
, fixS
* fixp
)
5526 static arelent
*retval
[MAX_RELOC_EXPANSION
+ 1]; /* MAX_RELOC_EXPANSION equals 2. */
5528 bfd_reloc_code_real_type code
;
5534 reloc
= retval
[0] = xmalloc (sizeof (arelent
));
5537 reloc
->sym_ptr_ptr
= xmalloc (sizeof (asymbol
*));
5538 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
5539 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
5540 reloc
->addend
= fixp
->fx_offset
;
5542 /* If this is a variant frag, we may need to adjust the existing
5543 reloc and generate a new one. */
5544 if (fixp
->fx_frag
->fr_opcode
!= NULL
&& (fixp
->fx_r_type
== BFD_RELOC_SCORE_GPREL15
))
5546 /* Update instruction imm bit. */
5551 buf
= fixp
->fx_frag
->fr_literal
+ fixp
->fx_frag
->insn_addr
;
5552 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5553 off
= fixp
->fx_offset
>> 16;
5554 newval
|= (off
& 0x3fff) << 1;
5555 newval
|= ((off
>> 14) & 0x3) << 16;
5556 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5559 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5560 off
= fixp
->fx_offset
& 0xffff;
5561 newval
|= ((off
& 0x3fff) << 1);
5562 newval
|= (((off
>> 14) & 0x3) << 16);
5563 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5565 retval
[1] = xmalloc (sizeof (arelent
));
5567 retval
[1]->sym_ptr_ptr
= xmalloc (sizeof (asymbol
*));
5568 *retval
[1]->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
5569 retval
[1]->address
= (reloc
->address
+ RELAX_RELOC2 (fixp
->fx_frag
->fr_subtype
));
5575 retval
[1]->addend
= 0;
5576 retval
[1]->howto
= bfd_reloc_type_lookup (stdoutput
, BFD_RELOC_LO16
);
5577 assert (retval
[1]->howto
!= NULL
);
5579 fixp
->fx_r_type
= BFD_RELOC_HI16_S
;
5582 code
= fixp
->fx_r_type
;
5583 switch (fixp
->fx_r_type
)
5588 code
= BFD_RELOC_32_PCREL
;
5591 case BFD_RELOC_HI16_S
:
5592 case BFD_RELOC_LO16
:
5593 case BFD_RELOC_SCORE_JMP
:
5594 case BFD_RELOC_SCORE_BRANCH
:
5595 case BFD_RELOC_SCORE16_JMP
:
5596 case BFD_RELOC_SCORE16_BRANCH
:
5597 case BFD_RELOC_VTABLE_ENTRY
:
5598 case BFD_RELOC_VTABLE_INHERIT
:
5599 case BFD_RELOC_SCORE_GPREL15
:
5600 case BFD_RELOC_SCORE_GOT15
:
5601 case BFD_RELOC_SCORE_DUMMY_HI16
:
5602 case BFD_RELOC_SCORE_GOT_LO16
:
5603 case BFD_RELOC_SCORE_CALL15
:
5604 case BFD_RELOC_GPREL32
:
5605 case BFD_RELOC_NONE
:
5606 code
= fixp
->fx_r_type
;
5609 type
= _("<unknown>");
5610 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5611 _("cannot represent %s relocation in this object file format"), type
);
5615 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
5616 if (reloc
->howto
== NULL
)
5618 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5619 _("cannot represent %s relocation in this object file format1"),
5620 bfd_get_reloc_code_name (code
));
5623 /* HACK: Since arm ELF uses Rel instead of Rela, encode the
5624 vtable entry to be used in the relocation's section offset. */
5625 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
5626 reloc
->address
= fixp
->fx_offset
;
5632 score_elf_final_processing (void)
5634 if (fix_data_dependency
== 1)
5636 elf_elfheader (stdoutput
)->e_flags
|= EF_SCORE_FIXDEP
;
5638 if (score_pic
== PIC
)
5640 elf_elfheader (stdoutput
)->e_flags
|= EF_SCORE_PIC
;
5645 parse_pce_inst (char *insnstr
)
5649 char first
[MAX_LITERAL_POOL_SIZE
];
5650 char second
[MAX_LITERAL_POOL_SIZE
];
5651 struct score_it pec_part_1
;
5653 /* Get first part string of PCE. */
5654 p
= strstr (insnstr
, "||");
5657 sprintf (first
, "%s", insnstr
);
5659 /* Get second part string of PCE. */
5662 sprintf (second
, "%s", p
);
5664 parse_16_32_inst (first
, FALSE
);
5668 memcpy (&pec_part_1
, &inst
, sizeof (inst
));
5670 parse_16_32_inst (second
, FALSE
);
5674 if ( ((pec_part_1
.size
== INSN_SIZE
) && (inst
.size
== INSN_SIZE
))
5675 || ((pec_part_1
.size
== INSN_SIZE
) && (inst
.size
== INSN16_SIZE
))
5676 || ((pec_part_1
.size
== INSN16_SIZE
) && (inst
.size
== INSN_SIZE
)))
5678 inst
.error
= _("pce instruction error (16 bit || 16 bit)'");
5679 sprintf (inst
.str
, "%s", insnstr
);
5684 gen_insn_frag (&pec_part_1
, &inst
);
5688 md_assemble (char *str
)
5691 know (strlen (str
) < MAX_LITERAL_POOL_SIZE
);
5693 memset (&inst
, '\0', sizeof (inst
));
5694 if (INSN_IS_PCE_P (str
))
5695 parse_pce_inst (str
);
5697 parse_16_32_inst (str
, TRUE
);
5700 as_bad ("%s -- `%s'", inst
.error
, inst
.str
);
5703 /* We handle all bad expressions here, so that we can report the faulty
5704 instruction in the error message. */
5706 md_operand (expressionS
* expr
)
5708 if (in_my_get_expression
)
5710 expr
->X_op
= O_illegal
;
5711 if (inst
.error
== NULL
)
5713 inst
.error
= _("bad expression");
5718 const char *md_shortopts
= "nO::g::G:";
5720 #ifdef SCORE_BI_ENDIAN
5721 #define OPTION_EB (OPTION_MD_BASE + 0)
5722 #define OPTION_EL (OPTION_MD_BASE + 1)
5724 #if TARGET_BYTES_BIG_ENDIAN
5725 #define OPTION_EB (OPTION_MD_BASE + 0)
5727 #define OPTION_EL (OPTION_MD_BASE + 1)
5730 #define OPTION_FIXDD (OPTION_MD_BASE + 2)
5731 #define OPTION_NWARN (OPTION_MD_BASE + 3)
5732 #define OPTION_SCORE5 (OPTION_MD_BASE + 4)
5733 #define OPTION_SCORE5U (OPTION_MD_BASE + 5)
5734 #define OPTION_SCORE7 (OPTION_MD_BASE + 6)
5735 #define OPTION_R1 (OPTION_MD_BASE + 7)
5736 #define OPTION_O0 (OPTION_MD_BASE + 8)
5737 #define OPTION_SCORE_VERSION (OPTION_MD_BASE + 9)
5738 #define OPTION_PIC (OPTION_MD_BASE + 10)
5740 struct option md_longopts
[] =
5743 {"EB" , no_argument
, NULL
, OPTION_EB
},
5746 {"EL" , no_argument
, NULL
, OPTION_EL
},
5748 {"FIXDD" , no_argument
, NULL
, OPTION_FIXDD
},
5749 {"NWARN" , no_argument
, NULL
, OPTION_NWARN
},
5750 {"SCORE5" , no_argument
, NULL
, OPTION_SCORE5
},
5751 {"SCORE5U", no_argument
, NULL
, OPTION_SCORE5U
},
5752 {"SCORE7" , no_argument
, NULL
, OPTION_SCORE7
},
5753 {"USE_R1" , no_argument
, NULL
, OPTION_R1
},
5754 {"O0" , no_argument
, NULL
, OPTION_O0
},
5755 {"V" , no_argument
, NULL
, OPTION_SCORE_VERSION
},
5756 {"KPIC" , no_argument
, NULL
, OPTION_PIC
},
5757 {NULL
, no_argument
, NULL
, 0}
5760 size_t md_longopts_size
= sizeof (md_longopts
);
5763 md_parse_option (int c
, char *arg
)
5769 target_big_endian
= 1;
5774 target_big_endian
= 0;
5778 fix_data_dependency
= 1;
5781 warn_fix_data_dependency
= 0;
5785 university_version
= 0;
5786 vector_size
= SCORE5_PIPELINE
;
5788 case OPTION_SCORE5U
:
5790 university_version
= 1;
5791 vector_size
= SCORE5_PIPELINE
;
5795 university_version
= 0;
5796 vector_size
= SCORE7_PIPELINE
;
5802 g_switch_value
= atoi (arg
);
5807 case OPTION_SCORE_VERSION
:
5808 printf (_("Sunplus-v2-0-0-20060510\n"));
5812 g_switch_value
= 0; /* Must set -G num as 0 to generate PIC code. */
5815 /* as_bad (_("unrecognized option `-%c%s'"), c, arg ? arg : ""); */
5822 md_show_usage (FILE * fp
)
5824 fprintf (fp
, _(" Score-specific assembler options:\n"));
5827 -EB\t\tassemble code for a big-endian cpu\n"));
5832 -EL\t\tassemble code for a little-endian cpu\n"));
5836 -FIXDD\t\tassemble code for fix data dependency\n"));
5838 -NWARN\t\tassemble code for no warning message for fix data dependency\n"));
5840 -SCORE5\t\tassemble code for target is SCORE5\n"));
5842 -SCORE5U\tassemble code for target is SCORE5U\n"));
5844 -SCORE7\t\tassemble code for target is SCORE7, this is default setting\n"));
5846 -USE_R1\t\tassemble code for no warning message when using temp register r1\n"));
5848 -KPIC\t\tassemble code for PIC\n"));
5850 -O0\t\tassembler will not perform any optimizations\n"));
5852 -G gpnum\tassemble code for setting gpsize and default is 8 byte\n"));
5854 -V \t\tSunplus release version \n"));
5858 /* Pesudo handling functions. */
5860 /* If we change section we must dump the literal pool first. */
5862 s_score_bss (int ignore ATTRIBUTE_UNUSED
)
5864 subseg_set (bss_section
, (subsegT
) get_absolute_expression ());
5865 demand_empty_rest_of_line ();
5869 s_score_text (int ignore
)
5871 obj_elf_text (ignore
);
5872 record_alignment (now_seg
, 2);
5876 score_s_section (int ignore
)
5878 obj_elf_section (ignore
);
5879 if ((bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
) != 0)
5880 record_alignment (now_seg
, 2);
5885 s_change_sec (int sec
)
5890 /* The ELF backend needs to know that we are changing sections, so
5891 that .previous works correctly. We could do something like check
5892 for an obj_section_change_hook macro, but that might be confusing
5893 as it would not be appropriate to use it in the section changing
5894 functions in read.c, since obj-elf.c intercepts those. FIXME:
5895 This should be cleaner, somehow. */
5896 obj_elf_section_change_hook ();
5901 seg
= subseg_new (RDATA_SECTION_NAME
, (subsegT
) get_absolute_expression ());
5902 bfd_set_section_flags (stdoutput
, seg
, (SEC_ALLOC
| SEC_LOAD
| SEC_READONLY
| SEC_RELOC
| SEC_DATA
));
5903 if (strcmp (TARGET_OS
, "elf") != 0)
5904 record_alignment (seg
, 4);
5905 demand_empty_rest_of_line ();
5908 seg
= subseg_new (".sdata", (subsegT
) get_absolute_expression ());
5909 bfd_set_section_flags (stdoutput
, seg
, SEC_ALLOC
| SEC_LOAD
| SEC_RELOC
| SEC_DATA
);
5910 if (strcmp (TARGET_OS
, "elf") != 0)
5911 record_alignment (seg
, 4);
5912 demand_empty_rest_of_line ();
5918 s_score_mask (int reg_type ATTRIBUTE_UNUSED
)
5922 if (cur_proc_ptr
== (procS
*) NULL
)
5924 as_warn (_(".mask outside of .ent"));
5925 demand_empty_rest_of_line ();
5928 if (get_absolute_expression_and_terminator (&mask
) != ',')
5930 as_warn (_("Bad .mask directive"));
5931 --input_line_pointer
;
5932 demand_empty_rest_of_line ();
5935 off
= get_absolute_expression ();
5936 cur_proc_ptr
->reg_mask
= mask
;
5937 cur_proc_ptr
->reg_offset
= off
;
5938 demand_empty_rest_of_line ();
5948 name
= input_line_pointer
;
5949 c
= get_symbol_end ();
5950 p
= (symbolS
*) symbol_find_or_make (name
);
5951 *input_line_pointer
= c
;
5961 if (*input_line_pointer
== '-')
5963 ++input_line_pointer
;
5966 if (!ISDIGIT (*input_line_pointer
))
5967 as_bad (_("expected simple number"));
5968 if (input_line_pointer
[0] == '0')
5970 if (input_line_pointer
[1] == 'x')
5972 input_line_pointer
+= 2;
5973 while (ISXDIGIT (*input_line_pointer
))
5976 val
|= hex_value (*input_line_pointer
++);
5978 return negative
? -val
: val
;
5982 ++input_line_pointer
;
5983 while (ISDIGIT (*input_line_pointer
))
5986 val
|= *input_line_pointer
++ - '0';
5988 return negative
? -val
: val
;
5991 if (!ISDIGIT (*input_line_pointer
))
5993 printf (_(" *input_line_pointer == '%c' 0x%02x\n"), *input_line_pointer
, *input_line_pointer
);
5994 as_warn (_("invalid number"));
5997 while (ISDIGIT (*input_line_pointer
))
6000 val
+= *input_line_pointer
++ - '0';
6002 return negative
? -val
: val
;
6005 /* The .aent and .ent directives. */
6008 s_score_ent (int aent
)
6013 symbolP
= get_symbol ();
6014 if (*input_line_pointer
== ',')
6015 ++input_line_pointer
;
6017 if (ISDIGIT (*input_line_pointer
) || *input_line_pointer
== '-')
6020 #ifdef BFD_ASSEMBLER
6021 if ((bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
) != 0)
6026 if (now_seg
!= data_section
&& now_seg
!= bss_section
)
6032 as_warn (_(".ent or .aent not in text section."));
6033 if (!aent
&& cur_proc_ptr
)
6034 as_warn (_("missing .end"));
6037 cur_proc_ptr
= &cur_proc
;
6038 cur_proc_ptr
->reg_mask
= 0xdeadbeaf;
6039 cur_proc_ptr
->reg_offset
= 0xdeadbeaf;
6040 cur_proc_ptr
->fpreg_mask
= 0xdeafbeaf;
6041 cur_proc_ptr
->leaf
= 0xdeafbeaf;
6042 cur_proc_ptr
->frame_offset
= 0xdeafbeaf;
6043 cur_proc_ptr
->frame_reg
= 0xdeafbeaf;
6044 cur_proc_ptr
->pc_reg
= 0xdeafbeaf;
6045 cur_proc_ptr
->isym
= symbolP
;
6046 symbol_get_bfdsym (symbolP
)->flags
|= BSF_FUNCTION
;
6048 if (debug_type
== DEBUG_STABS
)
6049 stabs_generate_asm_func (S_GET_NAME (symbolP
), S_GET_NAME (symbolP
));
6051 demand_empty_rest_of_line ();
6055 s_score_frame (int ignore ATTRIBUTE_UNUSED
)
6062 backupstr
= input_line_pointer
;
6065 if (cur_proc_ptr
== (procS
*) NULL
)
6067 as_warn (_(".frame outside of .ent"));
6068 demand_empty_rest_of_line ();
6071 cur_proc_ptr
->frame_reg
= reg_required_here ((&backupstr
), 0, REG_TYPE_SCORE
);
6073 skip_past_comma (&backupstr
);
6074 while (*backupstr
!= ',')
6076 str
[i
] = *backupstr
;
6084 skip_past_comma (&backupstr
);
6085 cur_proc_ptr
->frame_offset
= val
;
6086 cur_proc_ptr
->pc_reg
= reg_required_here ((&backupstr
), 0, REG_TYPE_SCORE
);
6089 skip_past_comma (&backupstr
);
6091 while (*backupstr
!= '\n')
6093 str
[i
] = *backupstr
;
6099 cur_proc_ptr
->leaf
= val
;
6101 skip_past_comma (&backupstr
);
6103 #endif /* OBJ_ELF */
6104 while (input_line_pointer
!= backupstr
)
6105 input_line_pointer
++;
6108 /* The .end directive. */
6110 s_score_end (int x ATTRIBUTE_UNUSED
)
6115 /* Generate a .pdr section. */
6116 segT saved_seg
= now_seg
;
6117 subsegT saved_subseg
= now_subseg
;
6122 if (!is_end_of_line
[(unsigned char)*input_line_pointer
])
6125 demand_empty_rest_of_line ();
6130 #ifdef BFD_ASSEMBLER
6131 if ((bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
) != 0)
6136 if (now_seg
!= data_section
&& now_seg
!= bss_section
)
6143 as_warn (_(".end not in text section"));
6146 as_warn (_(".end directive without a preceding .ent directive."));
6147 demand_empty_rest_of_line ();
6152 assert (S_GET_NAME (p
));
6153 if (strcmp (S_GET_NAME (p
), S_GET_NAME (cur_proc_ptr
->isym
)))
6154 as_warn (_(".end symbol does not match .ent symbol."));
6155 if (debug_type
== DEBUG_STABS
)
6156 stabs_generate_asm_endfunc (S_GET_NAME (p
), S_GET_NAME (p
));
6159 as_warn (_(".end directive missing or unknown symbol"));
6161 if ((cur_proc_ptr
->reg_mask
== 0xdeadbeaf) ||
6162 (cur_proc_ptr
->reg_offset
== 0xdeadbeaf) ||
6163 (cur_proc_ptr
->leaf
== 0xdeafbeaf) ||
6164 (cur_proc_ptr
->frame_offset
== 0xdeafbeaf) ||
6165 (cur_proc_ptr
->frame_reg
== 0xdeafbeaf) || (cur_proc_ptr
->pc_reg
== 0xdeafbeaf));
6169 dot
= frag_now_fix ();
6171 subseg_set (pdr_seg
, 0);
6172 /* Write the symbol. */
6173 exp
.X_op
= O_symbol
;
6174 exp
.X_add_symbol
= p
;
6175 exp
.X_add_number
= 0;
6176 emit_expr (&exp
, 4);
6177 fragp
= frag_more (7 * 4);
6178 md_number_to_chars (fragp
, (valueT
) cur_proc_ptr
->reg_mask
, 4);
6179 md_number_to_chars (fragp
+ 4, (valueT
) cur_proc_ptr
->reg_offset
, 4);
6180 md_number_to_chars (fragp
+ 8, (valueT
) cur_proc_ptr
->fpreg_mask
, 4);
6181 md_number_to_chars (fragp
+ 12, (valueT
) cur_proc_ptr
->leaf
, 4);
6182 md_number_to_chars (fragp
+ 16, (valueT
) cur_proc_ptr
->frame_offset
, 4);
6183 md_number_to_chars (fragp
+ 20, (valueT
) cur_proc_ptr
->frame_reg
, 4);
6184 md_number_to_chars (fragp
+ 24, (valueT
) cur_proc_ptr
->pc_reg
, 4);
6185 subseg_set (saved_seg
, saved_subseg
);
6188 cur_proc_ptr
= NULL
;
6191 /* Handle the .set pseudo-op. */
6193 s_score_set (int x ATTRIBUTE_UNUSED
)
6196 char name
[MAX_LITERAL_POOL_SIZE
];
6197 char * orig_ilp
= input_line_pointer
;
6199 while (!is_end_of_line
[(unsigned char)*input_line_pointer
])
6201 name
[i
] = (char) * input_line_pointer
;
6203 ++input_line_pointer
;
6208 if (strcmp (name
, "nwarn") == 0)
6210 warn_fix_data_dependency
= 0;
6212 else if (strcmp (name
, "fixdd") == 0)
6214 fix_data_dependency
= 1;
6216 else if (strcmp (name
, "nofixdd") == 0)
6218 fix_data_dependency
= 0;
6220 else if (strcmp (name
, "r1") == 0)
6224 else if (strcmp (name
, "nor1") == 0)
6228 else if (strcmp (name
, "optimize") == 0)
6232 else if (strcmp (name
, "volatile") == 0)
6236 else if (strcmp (name
, "pic") == 0)
6242 input_line_pointer
= orig_ilp
;
6247 /* Handle the .cpload pseudo-op. This is used when generating PIC code. It sets the
6248 $gp register for the function based on the function address, which is in the register
6249 named in the argument. This uses a relocation against GP_DISP_LABEL, which is handled
6250 specially by the linker. The result is:
6251 ldis gp, %hi(GP_DISP_LABEL)
6252 ori gp, %low(GP_DISP_LABEL)
6253 add gp, gp, .cpload argument
6254 The .cpload argument is normally r29. */
6257 s_score_cpload (int ignore ATTRIBUTE_UNUSED
)
6260 char insn_str
[MAX_LITERAL_POOL_SIZE
];
6262 /* If we are not generating PIC code, .cpload is ignored. */
6263 if (score_pic
== NO_PIC
)
6269 if ((reg
= reg_required_here (&input_line_pointer
, -1, REG_TYPE_SCORE
)) == (int) FAIL
)
6272 demand_empty_rest_of_line ();
6274 sprintf (insn_str
, "ld_i32hi r%d, %s", GP
, GP_DISP_LABEL
);
6275 if (append_insn (insn_str
, TRUE
) == (int) FAIL
)
6278 sprintf (insn_str
, "ld_i32lo r%d, %s", GP
, GP_DISP_LABEL
);
6279 if (append_insn (insn_str
, TRUE
) == (int) FAIL
)
6282 sprintf (insn_str
, "add r%d, r%d, r%d", GP
, GP
, reg
);
6283 if (append_insn (insn_str
, TRUE
) == (int) FAIL
)
6287 /* Handle the .cprestore pseudo-op. This stores $gp into a given
6288 offset from $sp. The offset is remembered, and after making a PIC
6289 call $gp is restored from that location. */
6292 s_score_cprestore (int ignore ATTRIBUTE_UNUSED
)
6294 #define SCORE_BP_REG 2
6295 int cprestore_offset
;
6296 char insn_str
[MAX_LITERAL_POOL_SIZE
];
6298 /* If we are not generating PIC code, .cprestore is ignored. */
6299 if (score_pic
== NO_PIC
)
6305 cprestore_offset
= get_absolute_expression ();
6307 sprintf (insn_str
, "sw r%d, [r%d, %d]", GP
, SCORE_BP_REG
, cprestore_offset
);
6308 if (append_insn (insn_str
, TRUE
) == (int) FAIL
)
6312 /* Handle the .gpword pseudo-op. This is used when generating PIC
6313 code. It generates a 32 bit GP relative reloc. */
6315 s_score_gpword (int ignore ATTRIBUTE_UNUSED
)
6320 /* When not generating PIC code, this is treated as .word. */
6321 if (score_pic
== NO_PIC
)
6327 if (ex
.X_op
!= O_symbol
|| ex
.X_add_number
!= 0)
6329 as_bad (_("Unsupported use of .gpword"));
6330 ignore_rest_of_line ();
6333 md_number_to_chars (p
, (valueT
) 0, 4);
6334 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 4, &ex
, FALSE
, BFD_RELOC_GPREL32
);
6335 demand_empty_rest_of_line ();
6338 /* Handle the .cpadd pseudo-op. This is used when dealing with switch
6339 tables in PIC code. */
6342 s_score_cpadd (int ignore ATTRIBUTE_UNUSED
)
6345 char insn_str
[MAX_LITERAL_POOL_SIZE
];
6347 /* If we are not generating PIC code, .cpload is ignored. */
6348 if (score_pic
== NO_PIC
)
6354 if ((reg
= reg_required_here (&input_line_pointer
, -1, REG_TYPE_SCORE
)) == (int) FAIL
)
6358 demand_empty_rest_of_line ();
6360 /* Add $gp to the register named as an argument. */
6361 sprintf (insn_str
, "add r%d, r%d, r%d", reg
, reg
, GP
);
6362 if (append_insn (insn_str
, TRUE
) == (int) FAIL
)
6366 #ifndef TC_IMPLICIT_LCOMM_ALIGNMENT
6367 #define TC_IMPLICIT_LCOMM_ALIGNMENT(SIZE, P2VAR) \
6372 else if ((SIZE) >= 4) \
6374 else if ((SIZE) >= 2) \
6383 s_score_lcomm (int bytes_p
)
6390 segT current_seg
= now_seg
;
6391 subsegT current_subseg
= now_subseg
;
6392 const int max_alignment
= 15;
6394 segT bss_seg
= bss_section
;
6395 int needs_align
= 0;
6397 name
= input_line_pointer
;
6398 c
= get_symbol_end ();
6399 p
= input_line_pointer
;
6404 as_bad (_("expected symbol name"));
6405 discard_rest_of_line ();
6411 /* Accept an optional comma after the name. The comma used to be
6412 required, but Irix 5 cc does not generate it. */
6413 if (*input_line_pointer
== ',')
6415 ++input_line_pointer
;
6419 if (is_end_of_line
[(unsigned char)*input_line_pointer
])
6421 as_bad (_("missing size expression"));
6425 if ((temp
= get_absolute_expression ()) < 0)
6427 as_warn (_("BSS length (%d) < 0 ignored"), temp
);
6428 ignore_rest_of_line ();
6432 #if defined (TC_SCORE)
6433 if (OUTPUT_FLAVOR
== bfd_target_ecoff_flavour
|| OUTPUT_FLAVOR
== bfd_target_elf_flavour
)
6435 /* For Score and Alpha ECOFF or ELF, small objects are put in .sbss. */
6436 if ((unsigned)temp
<= bfd_get_gp_size (stdoutput
))
6438 bss_seg
= subseg_new (".sbss", 1);
6439 seg_info (bss_seg
)->bss
= 1;
6440 #ifdef BFD_ASSEMBLER
6441 if (!bfd_set_section_flags (stdoutput
, bss_seg
, SEC_ALLOC
))
6442 as_warn (_("error setting flags for \".sbss\": %s"), bfd_errmsg (bfd_get_error ()));
6449 if (*input_line_pointer
== ',')
6451 ++input_line_pointer
;
6454 if (is_end_of_line
[(unsigned char)*input_line_pointer
])
6456 as_bad (_("missing alignment"));
6461 align
= get_absolute_expression ();
6468 TC_IMPLICIT_LCOMM_ALIGNMENT (temp
, align
);
6470 /* Still zero unless TC_IMPLICIT_LCOMM_ALIGNMENT set it. */
6472 record_alignment (bss_seg
, align
);
6479 /* Convert to a power of 2. */
6484 for (i
= 0; align
!= 0; align
>>= 1, ++i
)
6490 if (align
> max_alignment
)
6492 align
= max_alignment
;
6493 as_warn (_("alignment too large; %d assumed"), align
);
6498 as_warn (_("alignment negative; 0 assumed"));
6501 record_alignment (bss_seg
, align
);
6505 /* Assume some objects may require alignment on some systems. */
6506 #if defined (TC_ALPHA) && ! defined (VMS)
6509 align
= ffs (temp
) - 1;
6510 if (temp
% (1 << align
))
6517 symbolP
= symbol_find_or_make (name
);
6521 #if (defined (OBJ_AOUT) || defined (OBJ_MAYBE_AOUT) \
6522 || defined (OBJ_BOUT) || defined (OBJ_MAYBE_BOUT))
6523 #ifdef BFD_ASSEMBLER
6524 (OUTPUT_FLAVOR
!= bfd_target_aout_flavour
6525 || (S_GET_OTHER (symbolP
) == 0 && S_GET_DESC (symbolP
) == 0)) &&
6527 (S_GET_OTHER (symbolP
) == 0 && S_GET_DESC (symbolP
) == 0) &&
6530 (S_GET_SEGMENT (symbolP
) == bss_seg
|| (!S_IS_DEFINED (symbolP
) && S_GET_VALUE (symbolP
) == 0)))
6534 subseg_set (bss_seg
, 1);
6537 frag_align (align
, 0, 0);
6539 /* Detach from old frag. */
6540 if (S_GET_SEGMENT (symbolP
) == bss_seg
)
6541 symbol_get_frag (symbolP
)->fr_symbol
= NULL
;
6543 symbol_set_frag (symbolP
, frag_now
);
6544 pfrag
= frag_var (rs_org
, 1, 1, (relax_substateT
) 0, symbolP
, (offsetT
) temp
, NULL
);
6548 S_SET_SEGMENT (symbolP
, bss_seg
);
6551 /* The symbol may already have been created with a preceding
6552 ".globl" directive -- be careful not to step on storage class
6553 in that case. Otherwise, set it to static. */
6554 if (S_GET_STORAGE_CLASS (symbolP
) != C_EXT
)
6556 S_SET_STORAGE_CLASS (symbolP
, C_STAT
);
6558 #endif /* OBJ_COFF */
6561 S_SET_SIZE (symbolP
, temp
);
6565 as_bad (_("symbol `%s' is already defined"), S_GET_NAME (symbolP
));
6567 subseg_set (current_seg
, current_subseg
);
6569 demand_empty_rest_of_line ();
6573 insert_reg (const struct reg_entry
*r
, struct hash_control
*htab
)
6576 int len
= strlen (r
->name
) + 2;
6577 char *buf
= xmalloc (len
);
6578 char *buf2
= xmalloc (len
);
6580 strcpy (buf
+ i
, r
->name
);
6581 for (i
= 0; buf
[i
]; i
++)
6583 buf2
[i
] = TOUPPER (buf
[i
]);
6587 hash_insert (htab
, buf
, (void *) r
);
6588 hash_insert (htab
, buf2
, (void *) r
);
6592 build_reg_hsh (struct reg_map
*map
)
6594 const struct reg_entry
*r
;
6596 if ((map
->htab
= hash_new ()) == NULL
)
6598 as_fatal (_("virtual memory exhausted"));
6600 for (r
= map
->names
; r
->name
!= NULL
; r
++)
6602 insert_reg (r
, map
->htab
);
6613 if ((score_ops_hsh
= hash_new ()) == NULL
)
6614 as_fatal (_("virtual memory exhausted"));
6616 build_score_ops_hsh ();
6618 if ((dependency_insn_hsh
= hash_new ()) == NULL
)
6619 as_fatal (_("virtual memory exhausted"));
6621 build_dependency_insn_hsh ();
6623 for (i
= (int)REG_TYPE_FIRST
; i
< (int)REG_TYPE_MAX
; i
++)
6624 build_reg_hsh (all_reg_maps
+ i
);
6626 /* Initialize dependency vector. */
6627 init_dependency_vector ();
6629 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
, 0);
6631 subseg
= now_subseg
;
6632 pdr_seg
= subseg_new (".pdr", (subsegT
) 0);
6633 (void)bfd_set_section_flags (stdoutput
, pdr_seg
, SEC_READONLY
| SEC_RELOC
| SEC_DEBUGGING
);
6634 (void)bfd_set_section_alignment (stdoutput
, pdr_seg
, 2);
6635 subseg_set (seg
, subseg
);
6637 if (USE_GLOBAL_POINTER_OPT
)
6638 bfd_set_gp_size (stdoutput
, g_switch_value
);
6642 const pseudo_typeS md_pseudo_table
[] =
6644 {"bss", s_score_bss
, 0},
6645 {"text", s_score_text
, 0},
6648 {"extend", float_cons
, 'x'},
6649 {"ldouble", float_cons
, 'x'},
6650 {"packed", float_cons
, 'p'},
6651 {"end", s_score_end
, 0},
6652 {"ent", s_score_ent
, 0},
6653 {"frame", s_score_frame
, 0},
6654 {"rdata", s_change_sec
, 'r'},
6655 {"sdata", s_change_sec
, 's'},
6656 {"set", s_score_set
, 0},
6657 {"mask", s_score_mask
, 'R'},
6659 {"lcomm", s_score_lcomm
, 1},
6660 {"section", score_s_section
, 0},
6661 {"cpload", s_score_cpload
, 0},
6662 {"cprestore", s_score_cprestore
, 0},
6663 {"gpword", s_score_gpword
, 0},
6664 {"cpadd", s_score_cpadd
, 0},