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, 0x8000, PC_DISP19div2
, do_branch
},
379 {"bcc", 0x08000400, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
380 {"bcnz", 0x08003800, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
381 {"bcsl", 0x08000001, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
382 {"bccl", 0x08000401, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
383 {"bcnzl", 0x08003801, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
384 {"bcs!", 0x4000, 0x7f00, 0x08000000, PC_DISP8div2
, do16_branch
},
385 {"bcc!", 0x4100, 0x7f00, 0x08000400, PC_DISP8div2
, do16_branch
},
386 {"bcnz!", 0x4e00, 0x7f00, 0x08003800, PC_DISP8div2
, do16_branch
},
387 {"beq", 0x08001000, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
388 {"beql", 0x08001001, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
389 {"beq!", 0x4400, 0x7f00, 0x08001000, PC_DISP8div2
, do16_branch
},
390 {"bgtu", 0x08000800, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
391 {"bgt", 0x08001800, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
392 {"bge", 0x08002000, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
393 {"bgtul", 0x08000801, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
394 {"bgtl", 0x08001801, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
395 {"bgel", 0x08002001, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
396 {"bgtu!", 0x4200, 0x7f00, 0x08000800, PC_DISP8div2
, do16_branch
},
397 {"bgt!", 0x4600, 0x7f00, 0x08001800, PC_DISP8div2
, do16_branch
},
398 {"bge!", 0x4800, 0x7f00, 0x08002000, PC_DISP8div2
, do16_branch
},
399 {"bitclr.c", 0x00000029, 0x3e0003ff, 0x6004, Rd_Rs_I5
, do_rdrsi5
},
400 {"bitrev", 0x3800000c, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
401 {"bitset.c", 0x0000002b, 0x3e0003ff, 0x6005, Rd_Rs_I5
, do_rdrsi5
},
402 {"bittst.c", 0x0000002d, 0x3e0003ff, 0x6006, x_Rs_I5
, do_xrsi5
},
403 {"bittgl.c", 0x0000002f, 0x3e0003ff, 0x6007, Rd_Rs_I5
, do_rdrsi5
},
404 {"bitclr!", 0x6004, 0x7007, 0x00000029, Rd_I5
, do16_rdi5
},
405 {"bitset!", 0x6005, 0x7007, 0x0000002b, Rd_I5
, do16_rdi5
},
406 {"bittst!", 0x6006, 0x7007, 0x0000002d, Rd_I5
, do16_rdi5
},
407 {"bittgl!", 0x6007, 0x7007, 0x0000002f, Rd_I5
, do16_rdi5
},
408 {"bleu", 0x08000c00, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
409 {"ble", 0x08001c00, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
410 {"blt", 0x08002400, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
411 {"bleul", 0x08000c01, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
412 {"blel", 0x08001c01, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
413 {"bltl", 0x08002401, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
414 {"bl", 0x08003c01, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
415 {"bleu!", 0x4300, 0x7f00, 0x08000c00, PC_DISP8div2
, do16_branch
},
416 {"ble!", 0x4700, 0x7f00, 0x08001c00, PC_DISP8div2
, do16_branch
},
417 {"blt!", 0x4900, 0x7f00, 0x08002400, PC_DISP8div2
, do16_branch
},
418 {"bmi", 0x08002800, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
419 {"bmil", 0x08002801, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
420 {"bmi!", 0x00004a00, 0x00007f00, 0x08002800, PC_DISP8div2
, do16_branch
},
421 {"bne", 0x08001400, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
422 {"bnel", 0x08001401, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
423 {"bne!", 0x4500, 0x7f00, 0x08001400, PC_DISP8div2
, do16_branch
},
424 {"bpl", 0x08002c00, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
425 {"bpll", 0x08002c01, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
426 {"bpl!", 0x4b00, 0x7f00, 0x08002c00, PC_DISP8div2
, do16_branch
},
427 {"brcs", 0x00000008, 0x3e007fff, 0x0004, x_Rs_x
, do_rs
},
428 {"brcc", 0x00000408, 0x3e007fff, 0x0104, x_Rs_x
, do_rs
},
429 {"brgtu", 0x00000808, 0x3e007fff, 0x0204, x_Rs_x
, do_rs
},
430 {"brleu", 0x00000c08, 0x3e007fff, 0x0304, x_Rs_x
, do_rs
},
431 {"breq", 0x00001008, 0x3e007fff, 0x0404, x_Rs_x
, do_rs
},
432 {"brne", 0x00001408, 0x3e007fff, 0x0504, x_Rs_x
, do_rs
},
433 {"brgt", 0x00001808, 0x3e007fff, 0x0604, x_Rs_x
, do_rs
},
434 {"brle", 0x00001c08, 0x3e007fff, 0x0704, x_Rs_x
, do_rs
},
435 {"brge", 0x00002008, 0x3e007fff, 0x0804, x_Rs_x
, do_rs
},
436 {"brlt", 0x00002408, 0x3e007fff, 0x0904, x_Rs_x
, do_rs
},
437 {"brmi", 0x00002808, 0x3e007fff, 0x0a04, x_Rs_x
, do_rs
},
438 {"brpl", 0x00002c08, 0x3e007fff, 0x0b04, x_Rs_x
, do_rs
},
439 {"brvs", 0x00003008, 0x3e007fff, 0x0c04, x_Rs_x
, do_rs
},
440 {"brvc", 0x00003408, 0x3e007fff, 0x0d04, x_Rs_x
, do_rs
},
441 {"brcnz", 0x00003808, 0x3e007fff, 0x0e04, x_Rs_x
, do_rs
},
442 {"br", 0x00003c08, 0x3e007fff, 0x0f04, x_Rs_x
, do_rs
},
443 {"brcsl", 0x00000009, 0x3e007fff, 0x000c, x_Rs_x
, do_rs
},
444 {"brccl", 0x00000409, 0x3e007fff, 0x010c, x_Rs_x
, do_rs
},
445 {"brgtul", 0x00000809, 0x3e007fff, 0x020c, x_Rs_x
, do_rs
},
446 {"brleul", 0x00000c09, 0x3e007fff, 0x030c, x_Rs_x
, do_rs
},
447 {"breql", 0x00001009, 0x3e007fff, 0x040c, x_Rs_x
, do_rs
},
448 {"brnel", 0x00001409, 0x3e007fff, 0x050c, x_Rs_x
, do_rs
},
449 {"brgtl", 0x00001809, 0x3e007fff, 0x060c, x_Rs_x
, do_rs
},
450 {"brlel", 0x00001c09, 0x3e007fff, 0x070c, x_Rs_x
, do_rs
},
451 {"brgel", 0x00002009, 0x3e007fff, 0x080c, x_Rs_x
, do_rs
},
452 {"brltl", 0x00002409, 0x3e007fff, 0x090c, x_Rs_x
, do_rs
},
453 {"brmil", 0x00002809, 0x3e007fff, 0x0a0c, x_Rs_x
, do_rs
},
454 {"brpll", 0x00002c09, 0x3e007fff, 0x0b0c, x_Rs_x
, do_rs
},
455 {"brvsl", 0x00003009, 0x3e007fff, 0x0c0c, x_Rs_x
, do_rs
},
456 {"brvcl", 0x00003409, 0x3e007fff, 0x0d0c, x_Rs_x
, do_rs
},
457 {"brcnzl", 0x00003809, 0x3e007fff, 0x0e0c, x_Rs_x
, do_rs
},
458 {"brl", 0x00003c09, 0x3e007fff, 0x0f0c, x_Rs_x
, do_rs
},
459 {"brcs!", 0x0004, 0x7f0f, 0x00000008, x_Rs
, do16_xrs
},
460 {"brcc!", 0x0104, 0x7f0f, 0x00000408, x_Rs
, do16_xrs
},
461 {"brgtu!", 0x0204, 0x7f0f, 0x00000808, x_Rs
, do16_xrs
},
462 {"brleu!", 0x0304, 0x7f0f, 0x00000c08, x_Rs
, do16_xrs
},
463 {"breq!", 0x0404, 0x7f0f, 0x00001008, x_Rs
, do16_xrs
},
464 {"brne!", 0x0504, 0x7f0f, 0x00001408, x_Rs
, do16_xrs
},
465 {"brgt!", 0x0604, 0x7f0f, 0x00001808, x_Rs
, do16_xrs
},
466 {"brle!", 0x0704, 0x7f0f, 0x00001c08, x_Rs
, do16_xrs
},
467 {"brge!", 0x0804, 0x7f0f, 0x00002008, x_Rs
, do16_xrs
},
468 {"brlt!", 0x0904, 0x7f0f, 0x00002408, x_Rs
, do16_xrs
},
469 {"brmi!", 0x0a04, 0x7f0f, 0x00002808, x_Rs
, do16_xrs
},
470 {"brpl!", 0x0b04, 0x7f0f, 0x00002c08, x_Rs
, do16_xrs
},
471 {"brvs!", 0x0c04, 0x7f0f, 0x00003008, x_Rs
, do16_xrs
},
472 {"brvc!", 0x0d04, 0x7f0f, 0x00003408, x_Rs
, do16_xrs
},
473 {"brcnz!", 0x0e04, 0x7f0f, 0x00003808, x_Rs
, do16_xrs
},
474 {"br!", 0x0f04, 0x7f0f, 0x00003c08, x_Rs
, do16_xrs
},
475 {"brcsl!", 0x000c, 0x7f0f, 0x00000009, x_Rs
, do16_xrs
},
476 {"brccl!", 0x010c, 0x7f0f, 0x00000409, x_Rs
, do16_xrs
},
477 {"brgtul!", 0x020c, 0x7f0f, 0x00000809, x_Rs
, do16_xrs
},
478 {"brleul!", 0x030c, 0x7f0f, 0x00000c09, x_Rs
, do16_xrs
},
479 {"breql!", 0x040c, 0x7f0f, 0x00001009, x_Rs
, do16_xrs
},
480 {"brnel!", 0x050c, 0x7f0f, 0x00001409, x_Rs
, do16_xrs
},
481 {"brgtl!", 0x060c, 0x7f0f, 0x00001809, x_Rs
, do16_xrs
},
482 {"brlel!", 0x070c, 0x7f0f, 0x00001c09, x_Rs
, do16_xrs
},
483 {"brgel!", 0x080c, 0x7f0f, 0x00002009, x_Rs
, do16_xrs
},
484 {"brltl!", 0x090c, 0x7f0f, 0x00002409, x_Rs
, do16_xrs
},
485 {"brmil!", 0x0a0c, 0x7f0f, 0x00002809, x_Rs
, do16_xrs
},
486 {"brpll!", 0x0b0c, 0x7f0f, 0x00002c09, x_Rs
, do16_xrs
},
487 {"brvsl!", 0x0c0c, 0x7f0f, 0x00003009, x_Rs
, do16_xrs
},
488 {"brvcl!", 0x0d0c, 0x7f0f, 0x00003409, x_Rs
, do16_xrs
},
489 {"brcnzl!", 0x0e0c, 0x7f0f, 0x00003809, x_Rs
, do16_xrs
},
490 {"brl!", 0x0f0c, 0x7f0f, 0x00003c09, x_Rs
, do16_xrs
},
491 {"bvs", 0x08003000, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
492 {"bvc", 0x08003400, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
493 {"bvsl", 0x08003001, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
494 {"bvcl", 0x08003401, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
495 {"bvs!", 0x4c00, 0x7f00, 0x08003000, PC_DISP8div2
, do16_branch
},
496 {"bvc!", 0x4d00, 0x7f00, 0x08003400, PC_DISP8div2
, do16_branch
},
497 {"b!", 0x4f00, 0x7f00, 0x08003c00, PC_DISP8div2
, do16_branch
},
498 {"b", 0x08003c00, 0x3e007c01, 0x08003c00, PC_DISP19div2
, do_branch
},
499 {"cache", 0x30000000, 0x3ff00000, 0x8000, OP5_rvalueRs_SI15
, do_cache
},
500 {"ceinst", 0x38000000, 0x3e000000, 0x8000, I5_Rs_Rs_I5_OP5
, do_ceinst
},
501 {"clz", 0x3800000d, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
502 {"cmpteq.c", 0x00000019, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
503 {"cmptmi.c", 0x00100019, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
504 {"cmp.c", 0x00300019, 0x3ff003ff, 0x2003, x_Rs_Rs
, do_rsrs
},
505 {"cmpzteq.c", 0x0000001b, 0x3ff07fff, 0x8000, x_Rs_x
, do_rs
},
506 {"cmpztmi.c", 0x0010001b, 0x3ff07fff, 0x8000, x_Rs_x
, do_rs
},
507 {"cmpz.c", 0x0030001b, 0x3ff07fff, 0x8000, x_Rs_x
, do_rs
},
508 {"cmpi.c", 0x02040001, 0x3e0e0001, 0x8000, Rd_SI16
, do_rdsi16
},
509 {"cmp!", 0x2003, 0x700f, 0x00300019, Rd_Rs
, do16_rdrs
},
510 {"cop1", 0x0c00000c, 0x3e00001f, 0x8000, Rd_Rs_Rs_imm
, do_crdcrscrsimm5
},
511 {"cop2", 0x0c000014, 0x3e00001f, 0x8000, Rd_Rs_Rs_imm
, do_crdcrscrsimm5
},
512 {"cop3", 0x0c00001c, 0x3e00001f, 0x8000, Rd_Rs_Rs_imm
, do_crdcrscrsimm5
},
513 {"drte", 0x0c0000a4, 0x3e0003ff, 0x8000, NO_OPD
, do_empty
},
514 {"extsb", 0x00000058, 0x3e0003ff, 0x8000, Rd_Rs_x
, do_rdrs
},
515 {"extsb.c", 0x00000059, 0x3e0003ff, 0x8000, Rd_Rs_x
, do_rdrs
},
516 {"extsh", 0x0000005a, 0x3e0003ff, 0x8000, Rd_Rs_x
, do_rdrs
},
517 {"extsh.c", 0x0000005b, 0x3e0003ff, 0x8000, Rd_Rs_x
, do_rdrs
},
518 {"extzb", 0x0000005c, 0x3e0003ff, 0x8000, Rd_Rs_x
, do_rdrs
},
519 {"extzb.c", 0x0000005d, 0x3e0003ff, 0x8000, Rd_Rs_x
, do_rdrs
},
520 {"extzh", 0x0000005e, 0x3e0003ff, 0x8000, Rd_Rs_x
, do_rdrs
},
521 {"extzh.c", 0x0000005f, 0x3e0003ff, 0x8000, Rd_Rs_x
, do_rdrs
},
522 {"jl", 0x04000001, 0x3e000001, 0x8000, PC_DISP24div2
, do_jump
},
523 {"jl!", 0x3001, 0x7001, 0x04000001, PC_DISP11div2
, do16_jump
},
524 {"j!", 0x3000, 0x7001, 0x04000000, PC_DISP11div2
, do16_jump
},
525 {"j", 0x04000000, 0x3e000001, 0x8000, PC_DISP24div2
, do_jump
},
526 {"lbu!", 0x200b, 0x0000700f, 0x2c000000, Rd_rvalueRs
, do16_ldst_insn
},
527 {"lbup!", 0x7003, 0x7007, 0x2c000000, Rd_rvalueBP_I5
, do16_ldst_imm_insn
},
528 {"alw", 0x0000000c, 0x3e0003ff, 0x8000, Rd_rvalue32Rs
, do_ldst_atomic
},
529 {"lcb", 0x00000060, 0x3e0003ff, 0x8000, x_rvalueRs_post4
, do_ldst_unalign
},
530 {"lcw", 0x00000062, 0x3e0003ff, 0x8000, Rd_rvalueRs_post4
, do_ldst_unalign
},
531 {"lce", 0x00000066, 0x3e0003ff, 0x8000, Rd_rvalueRs_post4
, do_ldst_unalign
},
532 {"ldc1", 0x0c00000a, 0x3e00001f, 0x8000, Rd_rvalueRs_SI10
, do_ldst_cop
},
533 {"ldc2", 0x0c000012, 0x3e00001f, 0x8000, Rd_rvalueRs_SI10
, do_ldst_cop
},
534 {"ldc3", 0x0c00001a, 0x3e00001f, 0x8000, Rd_rvalueRs_SI10
, do_ldst_cop
},
535 {"lh!", 0x2009, 0x700f, 0x22000000, Rd_rvalueRs
, do16_ldst_insn
},
536 {"lhp!", 0x7001, 0x7007, 0x22000000, Rd_rvalueBP_I5
, do16_ldst_imm_insn
},
537 {"ldi", 0x020c0000, 0x3e0e0000, 0x5000, Rd_SI16
, do_rdsi16
},
538 {"ldis", 0x0a0c0000, 0x3e0e0000, 0x5000, Rd_I16
, do_rdi16
},
539 {"ldiu!", 0x5000, 0x7000, 0x020c0000, Rd_I8
, do16_ldst_imm_insn
},
540 {"lw!", 0x2008, 0x700f, 0x20000000, Rd_rvalueRs
, do16_ldst_insn
},
541 {"lwp!", 0x7000, 0x7007, 0x20000000, Rd_rvalueBP_I5
, do16_ldst_imm_insn
},
542 {"mfcel", 0x00000448, 0x3e007fff, 0x8000, Rd_x_x
, do_rd
},
543 {"mfcel!", 0x1001, 0x7f0f, 0x00000448, x_Rs
, do16_rs
},
544 {"mad", 0x38000000, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
545 {"mad.f!", 0x1004, 0x700f, 0x38000080, Rd_Rs
, do16_rdrs
},
546 {"madh", 0x38000203, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
547 {"madh.fs", 0x380002c3, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
548 {"madh.fs!", 0x100b, 0x700f, 0x380002c3, Rd_Rs
, do16_rdrs
},
549 {"madl", 0x38000002, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
550 {"madl.fs", 0x380000c2, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
551 {"madl.fs!", 0x100a, 0x700f, 0x380000c2, Rd_Rs
, do16_rdrs
},
552 {"madu", 0x38000020, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
553 {"madu!", 0x1005, 0x700f, 0x38000020, Rd_Rs
, do16_rdrs
},
554 {"mad.f", 0x38000080, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
555 {"max", 0x38000007, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
556 {"mazh", 0x38000303, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
557 {"mazh.f", 0x38000383, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
558 {"mazh.f!", 0x1009, 0x700f, 0x3800038c, Rd_Rs
, do16_rdrs
},
559 {"mazl", 0x38000102, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
560 {"mazl.f", 0x38000182, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
561 {"mazl.f!", 0x1008, 0x700f, 0x38000182, Rd_Rs
, do16_rdrs
},
562 {"mfceh", 0x00000848, 0x3e007fff, 0x8000, Rd_x_x
, do_rd
},
563 {"mfceh!", 0x1101, 0x7f0f, 0x00000848, x_Rs
, do16_rs
},
564 {"mfcehl", 0x00000c48, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
565 {"mfsr", 0x00000050, 0x3e0003ff, 0x8000, Rd_x_I5
, do_rdsrs
},
566 {"mfcr", 0x0c000001, 0x3e00001f, 0x8000, Rd_Rs_x
, do_rdcrs
},
567 {"mfc1", 0x0c000009, 0x3e00001f, 0x8000, Rd_Rs_x
, do_rdcrs
},
568 {"mfc2", 0x0c000011, 0x3e00001f, 0x8000, Rd_Rs_x
, do_rdcrs
},
569 {"mfc3", 0x0c000019, 0x3e00001f, 0x8000, Rd_Rs_x
, do_rdcrs
},
570 {"mfcc1", 0x0c00000f, 0x3e00001f, 0x8000, Rd_Rs_x
, do_rdcrs
},
571 {"mfcc2", 0x0c000017, 0x3e00001f, 0x8000, Rd_Rs_x
, do_rdcrs
},
572 {"mfcc3", 0x0c00001f, 0x3e00001f, 0x8000, Rd_Rs_x
, do_rdcrs
},
573 {"mhfl!", 0x0002, 0x700f, 0x00003c56, Rd_LowRs
, do16_hrdrs
},
574 {"min", 0x38000006, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
575 {"mlfh!", 0x0001, 0x700f, 0x00003c56, Rd_HighRs
, do16_rdhrs
},
576 {"msb", 0x38000001, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
577 {"msb.f!", 0x1006, 0x700f, 0x38000081, Rd_Rs
, do16_rdrs
},
578 {"msbh", 0x38000205, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
579 {"msbh.fs", 0x380002c5, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
580 {"msbh.fs!", 0x100f, 0x700f, 0x380002c5, Rd_Rs
, do16_rdrs
},
581 {"msbl", 0x38000004, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
582 {"msbl.fs", 0x380000c4, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
583 {"msbl.fs!", 0x100e, 0x700f, 0x380000c4, Rd_Rs
, do16_rdrs
},
584 {"msbu", 0x38000021, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
585 {"msbu!", 0x1007, 0x700f, 0x38000021, Rd_Rs
, do16_rdrs
},
586 {"msb.f", 0x38000081, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
587 {"mszh", 0x38000305, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
588 {"mszh.f", 0x38000385, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
589 {"mszh.f!", 0x100d, 0x700f, 0x38000385, Rd_Rs
, do16_rdrs
},
590 {"mszl", 0x38000104, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
591 {"mszl.f", 0x38000184, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
592 {"mszl.f!", 0x100c, 0x700f, 0x38000184, Rd_Rs
, do16_rdrs
},
593 {"mtcel!", 0x1000, 0x7f0f, 0x0000044a, x_Rs
, do16_rs
},
594 {"mtcel", 0x0000044a, 0x3e007fff, 0x8000, Rd_x_x
, do_rd
},
595 {"mtceh", 0x0000084a, 0x3e007fff, 0x8000, Rd_x_x
, do_rd
},
596 {"mtceh!", 0x1100, 0x7f0f, 0x0000084a, x_Rs
, do16_rs
},
597 {"mtcehl", 0x00000c4a, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
598 {"mtsr", 0x00000052, 0x3e0003ff, 0x8000, x_Rs_I5
, do_rdsrs
},
599 {"mtcr", 0x0c000000, 0x3e00001f, 0x8000, Rd_Rs_x
, do_rdcrs
},
600 {"mtc1", 0x0c000008, 0x3e00001f, 0x8000, Rd_Rs_x
, do_rdcrs
},
601 {"mtc2", 0x0c000010, 0x3e00001f, 0x8000, Rd_Rs_x
, do_rdcrs
},
602 {"mtc3", 0x0c000018, 0x3e00001f, 0x8000, Rd_Rs_x
, do_rdcrs
},
603 {"mtcc1", 0x0c00000e, 0x3e00001f, 0x8000, Rd_Rs_x
, do_rdcrs
},
604 {"mtcc2", 0x0c000016, 0x3e00001f, 0x8000, Rd_Rs_x
, do_rdcrs
},
605 {"mtcc3", 0x0c00001e, 0x3e00001f, 0x8000, Rd_Rs_x
, do_rdcrs
},
606 {"mul.f!", 0x1002, 0x700f, 0x00000041, Rd_Rs
, do16_rdrs
},
607 {"mulu!", 0x1003, 0x700f, 0x00000042, Rd_Rs
, do16_rdrs
},
608 {"mvcs", 0x00000056, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
609 {"mvcc", 0x00000456, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
610 {"mvgtu", 0x00000856, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
611 {"mvleu", 0x00000c56, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
612 {"mveq", 0x00001056, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
613 {"mvne", 0x00001456, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
614 {"mvgt", 0x00001856, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
615 {"mvle", 0x00001c56, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
616 {"mvge", 0x00002056, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
617 {"mvlt", 0x00002456, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
618 {"mvmi", 0x00002856, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
619 {"mvpl", 0x00002c56, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
620 {"mvvs", 0x00003056, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
621 {"mvvc", 0x00003456, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
622 {"mv", 0x00003c56, 0x3e007fff, 0x0003, Rd_Rs_x
, do_rdrs
},
623 {"mv!", 0x0003, 0x700f, 0x00003c56, Rd_Rs
, do16_mv_rdrs
},
624 {"neg", 0x0000001e, 0x3e0003ff, 0x8000, Rd_x_Rs
, do_rdxrs
},
625 {"neg.c", 0x0000001f, 0x3e0003ff, 0x2002, Rd_x_Rs
, do_rdxrs
},
626 {"neg!", 0x2002, 0x700f, 0x0000001f, Rd_Rs
, do16_rdrs
},
627 {"nop", 0x00000000, 0x3e0003ff, 0x0000, NO_OPD
, do_empty
},
628 {"not", 0x00000024, 0x3e0003ff, 0x8000, Rd_Rs_x
, do_rdrs
},
629 {"not.c", 0x00000025, 0x3e0003ff, 0x2006, Rd_Rs_x
, do_rdrs
},
630 {"nop!", 0x0000, 0x700f, 0x00000000, NO16_OPD
, do_empty
},
631 {"not!", 0x2006, 0x700f, 0x00000025, Rd_Rs
, do16_rdrs
},
632 {"or", 0x00000022, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
633 {"or.c", 0x00000023, 0x3e0003ff, 0x2005, Rd_Rs_Rs
, do_rdrsrs
},
634 {"ori", 0x020a0000, 0x3e0e0001, 0x8000, Rd_I16
, do_rdi16
},
635 {"ori.c", 0x020a0001, 0x3e0e0001, 0x8000, Rd_I16
, do_rdi16
},
636 {"oris", 0x0a0a0000, 0x3e0e0001, 0x8000, Rd_I16
, do_rdi16
},
637 {"oris.c", 0x0a0a0001, 0x3e0e0001, 0x8000, Rd_I16
, do_rdi16
},
638 {"orri", 0x1a000000, 0x3e000001, 0x8000, Rd_Rs_I14
, do_rdrsi14
},
639 {"orri.c", 0x1a000001, 0x3e000001, 0x8000, Rd_Rs_I14
, do_rdrsi14
},
640 {"or!", 0x2005, 0x700f, 0x00000023, Rd_Rs
, do16_rdrs
},
641 {"pflush", 0x0000000a, 0x3e0003ff, 0x8000, NO_OPD
, do_empty
},
642 {"pop!", 0x200a, 0x700f, 0x0e000000, Rd_rvalueRs
, do16_push_pop
},
643 {"push!", 0x200e, 0x700f, 0x06000004, Rd_lvalueRs
, do16_push_pop
},
644 {"ror", 0x00000038, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
645 {"ror.c", 0x00000039, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
646 {"rorc.c", 0x0000003b, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
647 {"rol", 0x0000003c, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
648 {"rol.c", 0x0000003d, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
649 {"rolc.c", 0x0000003f, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
650 {"rori", 0x00000078, 0x3e0003ff, 0x8000, Rd_Rs_I5
, do_rdrsi5
},
651 {"rori.c", 0x00000079, 0x3e0003ff, 0x8000, Rd_Rs_I5
, do_rdrsi5
},
652 {"roric.c", 0x0000007b, 0x3e0003ff, 0x8000, Rd_Rs_I5
, do_rdrsi5
},
653 {"roli", 0x0000007c, 0x3e0003ff, 0x8000, Rd_Rs_I5
, do_rdrsi5
},
654 {"roli.c", 0x0000007d, 0x3e0003ff, 0x8000, Rd_Rs_I5
, do_rdrsi5
},
655 {"rolic.c", 0x0000007f, 0x3e0003ff, 0x8000, Rd_Rs_I5
, do_rdrsi5
},
656 {"rte", 0x0c000084, 0x3e0003ff, 0x8000, NO_OPD
, do_empty
},
657 {"sb!", 0x200f, 0x700f, 0x2e000000, Rd_lvalueRs
, do16_ldst_insn
},
658 {"sbp!", 0x7007, 0x7007, 0x2e000000, Rd_lvalueBP_I5
, do16_ldst_imm_insn
},
659 {"asw", 0x0000000e, 0x3e0003ff, 0x8000, Rd_lvalue32Rs
, do_ldst_atomic
},
660 {"scb", 0x00000068, 0x3e0003ff, 0x8000, Rd_lvalueRs_post4
, do_ldst_unalign
},
661 {"scw", 0x0000006a, 0x3e0003ff, 0x8000, Rd_lvalueRs_post4
, do_ldst_unalign
},
662 {"sce", 0x0000006e, 0x3e0003ff, 0x8000, x_lvalueRs_post4
, do_ldst_unalign
},
663 {"sdbbp", 0x00000006, 0x3e0003ff, 0x6002, x_I5_x
, do_xi5x
},
664 {"sdbbp!", 0x6002, 0x7007, 0x00000006, Rd_I5
, do16_xi5
},
665 {"sh!", 0x200d, 0x700f, 0x2a000000, Rd_lvalueRs
, do16_ldst_insn
},
666 {"shp!", 0x7005, 0x7007, 0x2a000000, Rd_lvalueBP_I5
, do16_ldst_imm_insn
},
667 {"sleep", 0x0c0000c4, 0x3e0003ff, 0x8000, NO_OPD
, do_empty
},
668 {"sll", 0x00000030, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
669 {"sll.c", 0x00000031, 0x3e0003ff, 0x0008, Rd_Rs_Rs
, do_rdrsrs
},
670 {"sll.s", 0x3800004e, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
671 {"slli", 0x00000070, 0x3e0003ff, 0x8000, Rd_Rs_I5
, do_rdrsi5
},
672 {"slli.c", 0x00000071, 0x3e0003ff, 0x6001, Rd_Rs_I5
, do_rdrsi5
},
673 {"sll!", 0x0008, 0x700f, 0x00000031, Rd_Rs
, do16_rdrs
},
674 {"slli!", 0x6001, 0x7007, 0x00000071, Rd_I5
, do16_rdi5
},
675 {"srl", 0x00000034, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
676 {"srl.c", 0x00000035, 0x3e0003ff, 0x000a, Rd_Rs_Rs
, do_rdrsrs
},
677 {"sra", 0x00000036, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
678 {"sra.c", 0x00000037, 0x3e0003ff, 0x000b, Rd_Rs_Rs
, do_rdrsrs
},
679 {"srli", 0x00000074, 0x3e0003ff, 0x8000, Rd_Rs_I5
, do_rdrsi5
},
680 {"srli.c", 0x00000075, 0x3e0003ff, 0x6003, Rd_Rs_I5
, do_rdrsi5
},
681 {"srai", 0x00000076, 0x3e0003ff, 0x8000, Rd_Rs_I5
, do_rdrsi5
},
682 {"srai.c", 0x00000077, 0x3e0003ff, 0x8000, Rd_Rs_I5
, do_rdrsi5
},
683 {"srl!", 0x000a, 0x700f, 0x00000035, Rd_Rs
, do16_rdrs
},
684 {"sra!", 0x000b, 0x700f, 0x00000037, Rd_Rs
, do16_rdrs
},
685 {"srli!", 0x6003, 0x7007, 0x00000075, Rd_Rs
, do16_rdi5
},
686 {"stc1", 0x0c00000b, 0x3e00001f, 0x8000, Rd_lvalueRs_SI10
, do_ldst_cop
},
687 {"stc2", 0x0c000013, 0x3e00001f, 0x8000, Rd_lvalueRs_SI10
, do_ldst_cop
},
688 {"stc3", 0x0c00001b, 0x3e00001f, 0x8000, Rd_lvalueRs_SI10
, do_ldst_cop
},
689 {"sub", 0x00000014, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
690 {"sub.c", 0x00000015, 0x3e0003ff, 0x2001, Rd_Rs_Rs
, do_rdrsrs
},
691 {"sub.s", 0x38000049, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
692 {"subc", 0x00000016, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
693 {"subc.c", 0x00000017, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
694 {"sub!", 0x2001, 0x700f, 0x00000015, Rd_Rs
, do16_rdrs
},
695 {"subei!", 0x6080, 0x7087, 0x02000001, Rd_I4
, do16_rdi4
},
696 {"sw!", 0x200c, 0x700f, 0x28000000, Rd_lvalueRs
, do16_ldst_insn
},
697 {"swp!", 0x7004, 0x7007, 0x28000000, Rd_lvalueBP_I5
, do16_ldst_imm_insn
},
698 {"syscall", 0x00000002, 0x3e0003ff, 0x8000, I15
, do_i15
},
699 {"tcs", 0x00000054, 0x3e007fff, 0x0005, NO_OPD
, do_empty
},
700 {"tcc", 0x00000454, 0x3e007fff, 0x0105, NO_OPD
, do_empty
},
701 {"tcnz", 0x00003854, 0x3e007fff, 0x0e05, NO_OPD
, do_empty
},
702 {"tcs!", 0x0005, 0x7f0f, 0x00000054, NO16_OPD
, do_empty
},
703 {"tcc!", 0x0105, 0x7f0f, 0x00000454, NO16_OPD
, do_empty
},
704 {"tcnz!", 0x0e05, 0x7f0f, 0x00003854, NO16_OPD
, do_empty
},
705 {"teq", 0x00001054, 0x3e007fff, 0x0405, NO_OPD
, do_empty
},
706 {"teq!", 0x0405, 0x7f0f, 0x00001054, NO16_OPD
, do_empty
},
707 {"tgtu", 0x00000854, 0x3e007fff, 0x0205, NO_OPD
, do_empty
},
708 {"tgt", 0x00001854, 0x3e007fff, 0x0605, NO_OPD
, do_empty
},
709 {"tge", 0x00002054, 0x3e007fff, 0x0805, NO_OPD
, do_empty
},
710 {"tgtu!", 0x0205, 0x7f0f, 0x00000854, NO16_OPD
, do_empty
},
711 {"tgt!", 0x0605, 0x7f0f, 0x00001854, NO16_OPD
, do_empty
},
712 {"tge!", 0x0805, 0x7f0f, 0x00002054, NO16_OPD
, do_empty
},
713 {"tleu", 0x00000c54, 0x3e007fff, 0x0305, NO_OPD
, do_empty
},
714 {"tle", 0x00001c54, 0x3e007fff, 0x0705, NO_OPD
, do_empty
},
715 {"tlt", 0x00002454, 0x3e007fff, 0x0905, NO_OPD
, do_empty
},
716 {"stlb", 0x0c000004, 0x3e0003ff, 0x8000, NO_OPD
, do_empty
},
717 {"mftlb", 0x0c000024, 0x3e0003ff, 0x8000, NO_OPD
, do_empty
},
718 {"mtptlb", 0x0c000044, 0x3e0003ff, 0x8000, NO_OPD
, do_empty
},
719 {"mtrtlb", 0x0c000064, 0x3e0003ff, 0x8000, NO_OPD
, do_empty
},
720 {"tleu!", 0x0305, 0x7f0f, 0x00000c54, NO16_OPD
, do_empty
},
721 {"tle!", 0x0705, 0x7f0f, 0x00001c54, NO16_OPD
, do_empty
},
722 {"tlt!", 0x0905, 0x7f0f, 0x00002454, NO16_OPD
, do_empty
},
723 {"tmi", 0x00002854, 0x3e007fff, 0x0a05, NO_OPD
, do_empty
},
724 {"tmi!", 0x0a05, 0x7f0f, 0x00002854, NO16_OPD
, do_empty
},
725 {"tne", 0x00001454, 0x3e007fff, 0x0505, NO_OPD
, do_empty
},
726 {"tne!", 0x0505, 0x7f0f, 0x00001454, NO16_OPD
, do_empty
},
727 {"tpl", 0x00002c54, 0x3e007fff, 0x0b05, NO_OPD
, do_empty
},
728 {"tpl!", 0x0b05, 0x7f0f, 0x00002c54, NO16_OPD
, do_empty
},
729 {"trapcs", 0x00000004, 0x3e007fff, 0x8000, x_I5_x
, do_xi5x
},
730 {"trapcc", 0x00000404, 0x3e007fff, 0x8000, x_I5_x
, do_xi5x
},
731 {"trapgtu", 0x00000804, 0x3e007fff, 0x8000, x_I5_x
, do_xi5x
},
732 {"trapleu", 0x00000c04, 0x3e007fff, 0x8000, x_I5_x
, do_xi5x
},
733 {"trapeq", 0x00001004, 0x3e007fff, 0x8000, x_I5_x
, do_xi5x
},
734 {"trapne", 0x00001404, 0x3e007fff, 0x8000, x_I5_x
, do_xi5x
},
735 {"trapgt", 0x00001804, 0x3e007fff, 0x8000, x_I5_x
, do_xi5x
},
736 {"traple", 0x00001c04, 0x3e007fff, 0x8000, x_I5_x
, do_xi5x
},
737 {"trapge", 0x00002004, 0x3e007fff, 0x8000, x_I5_x
, do_xi5x
},
738 {"traplt", 0x00002404, 0x3e007fff, 0x8000, x_I5_x
, do_xi5x
},
739 {"trapmi", 0x00002804, 0x3e007fff, 0x8000, x_I5_x
, do_xi5x
},
740 {"trappl", 0x00002c04, 0x3e007fff, 0x8000, x_I5_x
, do_xi5x
},
741 {"trapvs", 0x00003004, 0x3e007fff, 0x8000, x_I5_x
, do_xi5x
},
742 {"trapvc", 0x00003404, 0x3e007fff, 0x8000, x_I5_x
, do_xi5x
},
743 {"trap", 0x00003c04, 0x3e007fff, 0x8000, x_I5_x
, do_xi5x
},
744 {"tset", 0x00003c54, 0x3e007fff, 0x0f05, NO_OPD
, do_empty
},
745 {"tset!", 0x0f05, 0x00007f0f, 0x00003c54, NO16_OPD
, do_empty
},
746 {"tvs", 0x00003054, 0x3e007fff, 0x0c05, NO_OPD
, do_empty
},
747 {"tvc", 0x00003454, 0x3e007fff, 0x0d05, NO_OPD
, do_empty
},
748 {"tvs!", 0x0c05, 0x7f0f, 0x00003054, NO16_OPD
, do_empty
},
749 {"tvc!", 0x0d05, 0x7f0f, 0x00003454, NO16_OPD
, do_empty
},
750 {"xor", 0x00000026, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
751 {"xor.c", 0x00000027, 0x3e0003ff, 0x2007, Rd_Rs_Rs
, do_rdrsrs
},
752 {"xor!", 0x2007, 0x700f, 0x00000027, Rd_Rs
, do16_rdrs
},
753 /* Macro instruction. */
754 {"li", 0x020c0000, 0x3e0e0000, 0x8000, Insn_Type_SYN
, do_macro_li_rdi32
},
755 /* la reg, imm32 -->(1) ldi reg, simm16
756 (2) ldis reg, %HI(imm32)
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);
1766 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 20)
1767 | (((inst
.instruction
>> 8) & 0xf) << 15) | (((inst
.instruction
>> 4) & 0xf) << 10);
1769 inst
.relax_size
= 4;
1778 skip_whitespace (str
);
1780 if ((rd
= reglow_required_here (&str
, 4)) == (int) FAIL
1781 || end_of_line (str
) == (int) FAIL
)
1787 inst
.relax_inst
|= rd
<< 20;
1788 inst
.relax_size
= 4;
1792 /* Handle br!/brl!. */
1794 do16_xrs (char *str
)
1796 skip_whitespace (str
);
1798 if (reglow_required_here (&str
, 4) == (int) FAIL
|| end_of_line (str
) == (int) FAIL
)
1804 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 10)
1805 | (((inst
.instruction
>> 4) & 0xf) << 15);
1806 inst
.relax_size
= 4;
1811 reghigh_required_here (char **str
, int shift
)
1813 static char buff
[MAX_LITERAL_POOL_SIZE
];
1817 if ((reg
= score_reg_parse (str
, all_reg_maps
[REG_TYPE_SCORE
].htab
)) != (int) FAIL
)
1819 if (15 < reg
&& reg
< 32)
1822 inst
.instruction
|= (reg
& 0xf) << shift
;
1829 sprintf (buff
, _("high register(r16-r31)expected, not '%.100s'"), start
);
1836 do16_hrdrs (char *str
)
1838 skip_whitespace (str
);
1840 if (reghigh_required_here (&str
, 8) != (int) FAIL
1841 && skip_past_comma (&str
) != (int) FAIL
1842 && reglow_required_here (&str
, 4) != (int) FAIL
1843 && end_of_line (str
) != (int) FAIL
)
1845 inst
.relax_inst
|= ((((inst
.instruction
>> 8) & 0xf) | 0x10) << 20)
1846 | (((inst
.instruction
>> 4) & 0xf) << 15) | (0xf << 10);
1847 inst
.relax_size
= 4;
1853 do16_rdhrs (char *str
)
1855 skip_whitespace (str
);
1857 if (reglow_required_here (&str
, 8) != (int) FAIL
1858 && skip_past_comma (&str
) != (int) FAIL
1859 && reghigh_required_here (&str
, 4) != (int) FAIL
1860 && end_of_line (str
) != (int) FAIL
)
1862 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 20)
1863 | ((((inst
.instruction
>> 4) & 0xf) | 0x10) << 15) | (0xf << 10);
1864 inst
.relax_size
= 4;
1868 /* We need to be able to fix up arbitrary expressions in some statements.
1869 This is so that we can handle symbols that are an arbitrary distance from
1870 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
1871 which returns part of an address in a form which will be valid for
1872 a data instruction. We do this by pushing the expression into a symbol
1873 in the expr_section, and creating a fix for that. */
1875 fix_new_score (fragS
* frag
, int where
, short int size
, expressionS
* exp
, int pc_rel
, int reloc
)
1885 new_fix
= fix_new_exp (frag
, where
, size
, exp
, pc_rel
, reloc
);
1888 new_fix
= fix_new (frag
, where
, size
, make_expr_symbol (exp
), 0, pc_rel
, reloc
);
1895 init_dependency_vector (void)
1899 for (i
= 0; i
< vector_size
; i
++)
1900 memset (&dependency_vector
[i
], '\0', sizeof (dependency_vector
[i
]));
1905 static enum insn_type_for_dependency
1906 dependency_type_from_insn (char *insn_name
)
1908 char name
[INSN_NAME_LEN
];
1909 const struct insn_to_dependency
*tmp
;
1911 strcpy (name
, insn_name
);
1912 tmp
= (const struct insn_to_dependency
*) hash_find (dependency_insn_hsh
, name
);
1921 check_dependency (char *pre_insn
, char *pre_reg
,
1922 char *cur_insn
, char *cur_reg
, int *warn_or_error
)
1926 enum insn_type_for_dependency pre_insn_type
;
1927 enum insn_type_for_dependency cur_insn_type
;
1929 pre_insn_type
= dependency_type_from_insn (pre_insn
);
1930 cur_insn_type
= dependency_type_from_insn (cur_insn
);
1932 for (i
= 0; i
< sizeof (data_dependency_table
) / sizeof (data_dependency_table
[0]); i
++)
1934 if ((pre_insn_type
== data_dependency_table
[i
].pre_insn_type
)
1935 && (D_all_insn
== data_dependency_table
[i
].cur_insn_type
1936 || cur_insn_type
== data_dependency_table
[i
].cur_insn_type
)
1937 && (strcmp (data_dependency_table
[i
].pre_reg
, "") == 0
1938 || strcmp (data_dependency_table
[i
].pre_reg
, pre_reg
) == 0)
1939 && (strcmp (data_dependency_table
[i
].cur_reg
, "") == 0
1940 || strcmp (data_dependency_table
[i
].cur_reg
, cur_reg
) == 0))
1942 bubbles
= (score7
) ? data_dependency_table
[i
].bubblenum_7
: data_dependency_table
[i
].bubblenum_5
;
1943 *warn_or_error
= data_dependency_table
[i
].warn_or_error
;
1952 build_one_frag (struct score_it one_inst
)
1955 int relaxable_p
= g_opt
;
1958 /* Start a new frag if frag_now is not empty. */
1959 if (frag_now_fix () != 0)
1961 if (!frag_now
->tc_frag_data
.is_insn
)
1962 frag_wane (frag_now
);
1968 p
= frag_more (one_inst
.size
);
1969 md_number_to_chars (p
, one_inst
.instruction
, one_inst
.size
);
1972 dwarf2_emit_insn (one_inst
.size
);
1975 relaxable_p
&= (one_inst
.relax_size
!= 0);
1976 relax_size
= relaxable_p
? one_inst
.relax_size
: 0;
1978 p
= frag_var (rs_machine_dependent
, relax_size
+ RELAX_PAD_BYTE
, 0,
1979 RELAX_ENCODE (one_inst
.size
, one_inst
.relax_size
,
1980 one_inst
.type
, 0, 0, relaxable_p
),
1984 md_number_to_chars (p
, one_inst
.relax_inst
, relax_size
);
1988 handle_dependency (struct score_it
*theinst
)
1991 int warn_or_error
= 0; /* warn - 0; error - 1 */
1993 int remainder_bubbles
= 0;
1994 char cur_insn
[INSN_NAME_LEN
];
1995 char pre_insn
[INSN_NAME_LEN
];
1996 struct score_it nop_inst
;
1997 struct score_it pflush_inst
;
1999 nop_inst
.instruction
= 0x0000;
2001 nop_inst
.relax_inst
= 0x80008000;
2002 nop_inst
.relax_size
= 4;
2003 nop_inst
.type
= NO16_OPD
;
2005 pflush_inst
.instruction
= 0x8000800a;
2006 pflush_inst
.size
= 4;
2007 pflush_inst
.relax_inst
= 0x8000;
2008 pflush_inst
.relax_size
= 0;
2009 pflush_inst
.type
= NO_OPD
;
2011 /* pflush will clear all data dependency. */
2012 if (strcmp (theinst
->name
, "pflush") == 0)
2014 init_dependency_vector ();
2018 /* Push current instruction to dependency_vector[0]. */
2019 for (i
= vector_size
- 1; i
> 0; i
--)
2020 memcpy (&dependency_vector
[i
], &dependency_vector
[i
- 1], sizeof (dependency_vector
[i
]));
2022 memcpy (&dependency_vector
[0], theinst
, sizeof (dependency_vector
[i
]));
2024 /* There is no dependency between nop and any instruction. */
2025 if (strcmp (dependency_vector
[0].name
, "nop") == 0
2026 || strcmp (dependency_vector
[0].name
, "nop!") == 0)
2029 /* "pce" is defined in insn_to_dependency_table. */
2030 #define PCE_NAME "pce"
2032 if (dependency_vector
[0].type
== Insn_Type_PCE
)
2033 strcpy (cur_insn
, PCE_NAME
);
2035 strcpy (cur_insn
, dependency_vector
[0].name
);
2037 for (i
= 1; i
< vector_size
; i
++)
2039 /* The element of dependency_vector is NULL. */
2040 if (dependency_vector
[i
].name
[0] == '\0')
2043 if (dependency_vector
[i
].type
== Insn_Type_PCE
)
2044 strcpy (pre_insn
, PCE_NAME
);
2046 strcpy (pre_insn
, dependency_vector
[i
].name
);
2048 bubbles
= check_dependency (pre_insn
, dependency_vector
[i
].reg
,
2049 cur_insn
, dependency_vector
[0].reg
, &warn_or_error
);
2050 remainder_bubbles
= bubbles
- i
+ 1;
2052 if (remainder_bubbles
> 0)
2056 if (fix_data_dependency
== 1)
2058 if (remainder_bubbles
<= 2)
2060 if (warn_fix_data_dependency
)
2061 as_warn ("Fix data dependency: %s %s -- %s %s (insert %d nop!/%d)",
2062 dependency_vector
[i
].name
, dependency_vector
[i
].reg
,
2063 dependency_vector
[0].name
, dependency_vector
[0].reg
,
2064 remainder_bubbles
, bubbles
);
2066 for (j
= (vector_size
- 1); (j
- remainder_bubbles
) > 0; j
--)
2067 memcpy (&dependency_vector
[j
], &dependency_vector
[j
- remainder_bubbles
],
2068 sizeof (dependency_vector
[j
]));
2070 for (j
= 1; j
<= remainder_bubbles
; j
++)
2072 memset (&dependency_vector
[j
], '\0', sizeof (dependency_vector
[j
]));
2074 build_one_frag (nop_inst
);
2079 if (warn_fix_data_dependency
)
2080 as_warn ("Fix data dependency: %s %s -- %s %s (insert 1 pflush/%d)",
2081 dependency_vector
[i
].name
, dependency_vector
[i
].reg
,
2082 dependency_vector
[0].name
, dependency_vector
[0].reg
,
2085 for (j
= 1; j
< vector_size
; j
++)
2086 memset (&dependency_vector
[j
], '\0', sizeof (dependency_vector
[j
]));
2088 /* Insert pflush. */
2089 build_one_frag (pflush_inst
);
2096 as_bad ("data dependency: %s %s -- %s %s (%d/%d bubble)",
2097 dependency_vector
[i
].name
, dependency_vector
[i
].reg
,
2098 dependency_vector
[0].name
, dependency_vector
[0].reg
,
2099 remainder_bubbles
, bubbles
);
2103 as_warn ("data dependency: %s %s -- %s %s (%d/%d bubble)",
2104 dependency_vector
[i
].name
, dependency_vector
[i
].reg
,
2105 dependency_vector
[0].name
, dependency_vector
[0].reg
,
2106 remainder_bubbles
, bubbles
);
2113 static enum insn_class
2114 get_insn_class_from_type (enum score_insn_type type
)
2116 enum insn_class retval
= (int) FAIL
;
2122 case Rd_rvalueBP_I5
:
2123 case Rd_lvalueBP_I5
:
2134 retval
= INSN_CLASS_16
;
2143 case Rd_rvalueRs_SI10
:
2144 case Rd_lvalueRs_SI10
:
2145 case Rd_rvalueRs_preSI12
:
2146 case Rd_rvalueRs_postSI12
:
2147 case Rd_lvalueRs_preSI12
:
2148 case Rd_lvalueRs_postSI12
:
2150 case Rd_rvalueRs_SI15
:
2151 case Rd_lvalueRs_SI15
:
2160 case OP5_rvalueRs_SI15
:
2161 case I5_Rs_Rs_I5_OP5
:
2162 case x_rvalueRs_post4
:
2163 case Rd_rvalueRs_post4
:
2165 case Rd_lvalueRs_post4
:
2166 case x_lvalueRs_post4
:
2174 retval
= INSN_CLASS_32
;
2177 retval
= INSN_CLASS_PCE
;
2180 retval
= INSN_CLASS_SYN
;
2189 static unsigned long
2190 adjust_paritybit (unsigned long m_code
, enum insn_class
class)
2192 unsigned long result
= 0;
2193 unsigned long m_code_high
= 0;
2194 unsigned long m_code_low
= 0;
2195 unsigned long pb_high
= 0;
2196 unsigned long pb_low
= 0;
2198 if (class == INSN_CLASS_32
)
2200 pb_high
= 0x80000000;
2201 pb_low
= 0x00008000;
2203 else if (class == INSN_CLASS_16
)
2208 else if (class == INSN_CLASS_PCE
)
2211 pb_low
= 0x00008000;
2213 else if (class == INSN_CLASS_SYN
)
2215 /* FIXME. at this time, INSN_CLASS_SYN must be 32 bit, but, instruction type should
2216 be changed if macro instruction has been expanded. */
2217 pb_high
= 0x80000000;
2218 pb_low
= 0x00008000;
2225 m_code_high
= m_code
& 0x3fff8000;
2226 m_code_low
= m_code
& 0x00007fff;
2227 result
= pb_high
| (m_code_high
<< 1) | pb_low
| m_code_low
;
2233 gen_insn_frag (struct score_it
*part_1
, struct score_it
*part_2
)
2236 bfd_boolean pce_p
= FALSE
;
2237 int relaxable_p
= g_opt
;
2239 struct score_it
*inst1
= part_1
;
2240 struct score_it
*inst2
= part_2
;
2241 struct score_it backup_inst1
;
2243 pce_p
= (inst2
) ? TRUE
: FALSE
;
2244 memcpy (&backup_inst1
, inst1
, sizeof (struct score_it
));
2246 /* Adjust instruction opcode and to be relaxed instruction opcode. */
2249 backup_inst1
.instruction
= ((backup_inst1
.instruction
& 0x7FFF) << 15)
2250 | (inst2
->instruction
& 0x7FFF);
2251 backup_inst1
.instruction
= adjust_paritybit (backup_inst1
.instruction
, INSN_CLASS_PCE
);
2252 backup_inst1
.relax_inst
= 0x8000;
2253 backup_inst1
.size
= INSN_SIZE
;
2254 backup_inst1
.relax_size
= 0;
2255 backup_inst1
.type
= Insn_Type_PCE
;
2259 backup_inst1
.instruction
= adjust_paritybit (backup_inst1
.instruction
,
2260 GET_INSN_CLASS (backup_inst1
.type
));
2263 if (backup_inst1
.relax_size
!= 0)
2265 enum insn_class tmp
;
2267 tmp
= (backup_inst1
.size
== INSN_SIZE
) ? INSN_CLASS_16
: INSN_CLASS_32
;
2268 backup_inst1
.relax_inst
= adjust_paritybit (backup_inst1
.relax_inst
, tmp
);
2271 /* Check data dependency. */
2272 handle_dependency (&backup_inst1
);
2274 /* Start a new frag if frag_now is not empty and is not instruction frag, maybe it contains
2275 data produced by .ascii etc. Doing this is to make one instruction per frag. */
2276 if (frag_now_fix () != 0)
2278 if (!frag_now
->tc_frag_data
.is_insn
)
2279 frag_wane (frag_now
);
2284 /* Here, we must call frag_grow in order to keep the instruction frag type is
2285 rs_machine_dependent.
2286 For, frag_var may change frag_now->fr_type to rs_fill by calling frag_grow which
2287 acturally will call frag_wane.
2288 Calling frag_grow first will create a new frag_now which free size is 20 that is enough
2292 p
= frag_more (backup_inst1
.size
);
2293 md_number_to_chars (p
, backup_inst1
.instruction
, backup_inst1
.size
);
2296 dwarf2_emit_insn (backup_inst1
.size
);
2299 /* Generate fixup structure. */
2302 if (inst1
->reloc
.type
!= BFD_RELOC_NONE
)
2303 fix_new_score (frag_now
, p
- frag_now
->fr_literal
,
2304 inst1
->size
, &inst1
->reloc
.exp
,
2305 inst1
->reloc
.pc_rel
, inst1
->reloc
.type
);
2307 if (inst2
->reloc
.type
!= BFD_RELOC_NONE
)
2308 fix_new_score (frag_now
, p
- frag_now
->fr_literal
+ 2,
2309 inst2
->size
, &inst2
->reloc
.exp
, inst2
->reloc
.pc_rel
, inst2
->reloc
.type
);
2313 if (backup_inst1
.reloc
.type
!= BFD_RELOC_NONE
)
2314 fix_new_score (frag_now
, p
- frag_now
->fr_literal
,
2315 backup_inst1
.size
, &backup_inst1
.reloc
.exp
,
2316 backup_inst1
.reloc
.pc_rel
, backup_inst1
.reloc
.type
);
2319 /* relax_size may be 2, 4, 12 or 0, 0 indicates no relaxation. */
2320 relaxable_p
&= (backup_inst1
.relax_size
!= 0);
2321 relax_size
= relaxable_p
? backup_inst1
.relax_size
: 0;
2323 p
= frag_var (rs_machine_dependent
, relax_size
+ RELAX_PAD_BYTE
, 0,
2324 RELAX_ENCODE (backup_inst1
.size
, backup_inst1
.relax_size
,
2325 backup_inst1
.type
, 0, 0, relaxable_p
),
2326 backup_inst1
.reloc
.exp
.X_add_symbol
, 0, NULL
);
2329 md_number_to_chars (p
, backup_inst1
.relax_inst
, relax_size
);
2331 memcpy (inst1
, &backup_inst1
, sizeof (struct score_it
));
2335 parse_16_32_inst (char *insnstr
, bfd_boolean gen_frag_p
)
2339 char *operator = insnstr
;
2340 const struct asm_opcode
*opcode
;
2342 /* Parse operator and operands. */
2343 skip_whitespace (operator);
2345 for (p
= operator; *p
!= '\0'; p
++)
2346 if ((*p
== ' ') || (*p
== '!'))
2355 opcode
= (const struct asm_opcode
*) hash_find (score_ops_hsh
, operator);
2358 memset (&inst
, '\0', sizeof (inst
));
2359 sprintf (inst
.str
, "%s", insnstr
);
2362 inst
.instruction
= opcode
->value
;
2363 inst
.relax_inst
= opcode
->relax_value
;
2364 inst
.type
= opcode
->type
;
2365 inst
.size
= GET_INSN_SIZE (inst
.type
);
2366 inst
.relax_size
= 0;
2368 sprintf (inst
.name
, "%s", opcode
->template);
2369 strcpy (inst
.reg
, "");
2371 inst
.reloc
.type
= BFD_RELOC_NONE
;
2373 (*opcode
->parms
) (p
);
2375 /* It indicates current instruction is a macro instruction if inst.bwarn equals -1. */
2376 if ((inst
.bwarn
!= -1) && (!inst
.error
) && (gen_frag_p
))
2377 gen_insn_frag (&inst
, NULL
);
2380 inst
.error
= _("unrecognized opcode");
2384 append_insn (char *str
, bfd_boolean gen_frag_p
)
2386 int retval
= SUCCESS
;
2388 parse_16_32_inst (str
, gen_frag_p
);
2392 retval
= (int) FAIL
;
2393 as_bad ("%s -- `%s'", inst
.error
, inst
.str
);
2400 /* Handle mv! reg_high, reg_low;
2401 mv! reg_low, reg_high;
2402 mv! reg_low, reg_low; */
2404 do16_mv_rdrs (char *str
)
2408 char *backupstr
= NULL
;
2411 skip_whitespace (str
);
2413 if ((reg_rd
= reg_required_here (&str
, 8, REG_TYPE_SCORE
)) == (int) FAIL
2414 || skip_past_comma (&str
) == (int) FAIL
2415 || (reg_rs
= reg_required_here (&str
, 4, REG_TYPE_SCORE
)) == (int) FAIL
2416 || end_of_line (str
) == (int) FAIL
)
2422 /* Case 1 : mv! or mlfh!. */
2427 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 20)
2428 | (((inst
.instruction
>> 4) & 0xf) << 15) | (0xf << 10);
2429 inst
.relax_size
= 4;
2433 char append_str
[MAX_LITERAL_POOL_SIZE
];
2435 sprintf (append_str
, "mlfh! %s", backupstr
);
2436 if (append_insn (append_str
, TRUE
) == (int) FAIL
)
2438 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
2442 /* Case 2 : mhfl!. */
2447 SET_INSN_ERROR (BAD_ARGS
);
2452 char append_str
[MAX_LITERAL_POOL_SIZE
];
2454 sprintf (append_str
, "mhfl! %s", backupstr
);
2455 if (append_insn (append_str
, TRUE
) == (int) FAIL
)
2458 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
2466 do16_rdi4 (char *str
)
2468 skip_whitespace (str
);
2470 if (reglow_required_here (&str
, 8) == (int) FAIL
2471 || skip_past_comma (&str
) == (int) FAIL
2472 || data_op2 (&str
, 3, _IMM4
) == (int) FAIL
2473 || end_of_line (str
) == (int) FAIL
)
2479 if (((inst
.instruction
>> 3) & 0x10) == 0) /* for judge is addei or subei : bit 5 =0 : addei */
2481 if (((inst
.instruction
>> 3) & 0xf) != 0xf)
2483 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 20)
2484 | ((1 << ((inst
.instruction
>> 3) & 0xf)) << 1);
2485 inst
.relax_size
= 4;
2489 inst
.relax_inst
= 0x8000;
2494 if (((inst
.instruction
>> 3) & 0xf) != 0xf)
2496 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 20)
2497 | (((-(1 << ((inst
.instruction
>> 3) & 0xf))) & 0xffff) << 1);
2498 inst
.relax_size
= 4;
2502 inst
.relax_inst
= 0x8000;
2509 do16_rdi5 (char *str
)
2511 skip_whitespace (str
);
2513 if (reglow_required_here (&str
, 8) == (int) FAIL
2514 || skip_past_comma (&str
) == (int) FAIL
2515 || data_op2 (&str
, 3, _IMM5
) == (int) FAIL
2516 || end_of_line (str
) == (int) FAIL
)
2520 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 20)
2521 | (((inst
.instruction
>> 8) & 0xf) << 15) | (((inst
.instruction
>> 3) & 0x1f) << 10);
2522 inst
.relax_size
= 4;
2528 do16_xi5 (char *str
)
2530 skip_whitespace (str
);
2532 if (data_op2 (&str
, 3, _IMM5
) == (int) FAIL
|| end_of_line (str
) == (int) FAIL
)
2536 inst
.relax_inst
|= (((inst
.instruction
>> 3) & 0x1f) << 15);
2537 inst
.relax_size
= 4;
2541 /* Check that an immediate is word alignment or half word alignment.
2542 If so, convert it to the right format. */
2544 validate_immediate_align (int val
, unsigned int data_type
)
2546 if (data_type
== _IMM5_RSHIFT_1
)
2550 inst
.error
= _("address offset must be half word alignment");
2554 else if ((data_type
== _IMM5_RSHIFT_2
) || (data_type
== _IMM10_RSHIFT_2
))
2558 inst
.error
= _("address offset must be word alignment");
2567 exp_ldst_offset (char **str
, int shift
, unsigned int data_type
)
2573 if ((*dataptr
== '0') && (*(dataptr
+ 1) == 'x')
2574 && (data_type
!= _SIMM16_LA
)
2575 && (data_type
!= _VALUE_HI16
)
2576 && (data_type
!= _VALUE_LO16
)
2577 && (data_type
!= _IMM16
)
2578 && (data_type
!= _IMM15
)
2579 && (data_type
!= _IMM14
)
2580 && (data_type
!= _IMM4
)
2581 && (data_type
!= _IMM5
)
2582 && (data_type
!= _IMM8
)
2583 && (data_type
!= _IMM5_RSHIFT_1
)
2584 && (data_type
!= _IMM5_RSHIFT_2
)
2585 && (data_type
!= _SIMM14_NEG
)
2586 && (data_type
!= _IMM10_RSHIFT_2
))
2591 if (my_get_expression (&inst
.reloc
.exp
, str
) == (int) FAIL
)
2594 if (inst
.reloc
.exp
.X_op
== O_constant
)
2596 /* Need to check the immediate align. */
2597 int value
= validate_immediate_align (inst
.reloc
.exp
.X_add_number
, data_type
);
2599 if (value
== (int) FAIL
)
2602 value
= validate_immediate (inst
.reloc
.exp
.X_add_number
, data_type
);
2603 if (value
== (int) FAIL
)
2609 "invalid constant: %d bit expression not in range %d..%d",
2610 score_df_range
[data_type
].bits
,
2611 score_df_range
[data_type
].range
[0], score_df_range
[data_type
].range
[1]);
2614 "invalid constant: %d bit expression not in range %d..%d",
2615 score_df_range
[data_type
- 24].bits
,
2616 score_df_range
[data_type
- 24].range
[0], score_df_range
[data_type
- 24].range
[1]);
2617 inst
.error
= _(err_msg
);
2621 if (data_type
== _IMM5_RSHIFT_1
)
2625 else if ((data_type
== _IMM5_RSHIFT_2
) || (data_type
== _IMM10_RSHIFT_2
))
2630 if (score_df_range
[data_type
].range
[0] != 0)
2632 value
&= (1 << score_df_range
[data_type
].bits
) - 1;
2635 inst
.instruction
|= value
<< shift
;
2639 inst
.reloc
.pc_rel
= 0;
2646 do_ldst_insn (char *str
)
2658 skip_whitespace (str
);
2660 if (((conflict_reg
= reg_required_here (&str
, 20, REG_TYPE_SCORE
)) == (int) FAIL
)
2661 || (skip_past_comma (&str
) == (int) FAIL
))
2664 /* ld/sw rD, [rA, simm15] ld/sw rD, [rA]+, simm12 ld/sw rD, [rA, simm12]+. */
2668 skip_whitespace (str
);
2670 if ((reg
= reg_required_here (&str
, 15, REG_TYPE_SCORE
)) == (int) FAIL
)
2673 /* Conflicts can occur on stores as well as loads. */
2674 conflict_reg
= (conflict_reg
== reg
);
2675 skip_whitespace (str
);
2676 temp
= str
+ 1; /* The latter will process decimal/hex expression. */
2678 /* ld/sw rD, [rA]+, simm12 ld/sw rD, [rA]+. */
2685 /* ld/sw rD, [rA]+, simm12. */
2686 if (skip_past_comma (&str
) == SUCCESS
)
2688 if ((exp_ldst_offset (&str
, 3, _SIMM12
) == (int) FAIL
)
2689 || (end_of_line (str
) == (int) FAIL
))
2694 unsigned int ldst_func
= inst
.instruction
& OPC_PSEUDOLDST_MASK
;
2696 if ((ldst_func
== INSN_LH
)
2697 || (ldst_func
== INSN_LHU
)
2698 || (ldst_func
== INSN_LW
)
2699 || (ldst_func
== INSN_LB
)
2700 || (ldst_func
== INSN_LBU
))
2702 inst
.error
= _("register same as write-back base");
2707 ldst_idx
= inst
.instruction
& OPC_PSEUDOLDST_MASK
;
2708 inst
.instruction
&= ~OPC_PSEUDOLDST_MASK
;
2709 inst
.instruction
|= score_ldst_insns
[ldst_idx
* 3 + LDST_POST
].value
;
2711 /* lw rD, [rA]+, 4 convert to pop rD, [rA]. */
2712 if ((inst
.instruction
& 0x3e000007) == 0x0e000000)
2714 /* rs = r0-r7, offset = 4 */
2715 if ((((inst
.instruction
>> 15) & 0x18) == 0)
2716 && (((inst
.instruction
>> 3) & 0xfff) == 4))
2718 /* Relax to pophi. */
2719 if ((((inst
.instruction
>> 20) & 0x10) == 0x10))
2721 inst
.relax_inst
= 0x0000200a | (((inst
.instruction
>> 20) & 0xf)
2723 (((inst
.instruction
>> 15) & 0x7) << 4);
2728 inst
.relax_inst
= 0x0000200a | (((inst
.instruction
>> 20) & 0xf)
2730 (((inst
.instruction
>> 15) & 0x7) << 4);
2732 inst
.relax_size
= 2;
2737 /* ld/sw rD, [rA]+ convert to ld/sw rD, [rA, 0]+. */
2740 SET_INSN_ERROR (NULL
);
2741 if (end_of_line (str
) == (int) FAIL
)
2747 value
= validate_immediate (inst
.reloc
.exp
.X_add_number
, _SIMM12
);
2748 value
&= (1 << score_df_range
[_SIMM12
].bits
) - 1;
2749 ldst_idx
= inst
.instruction
& OPC_PSEUDOLDST_MASK
;
2750 inst
.instruction
&= ~OPC_PSEUDOLDST_MASK
;
2751 inst
.instruction
|= score_ldst_insns
[ldst_idx
* 3 + pre_inc
].value
;
2752 inst
.instruction
|= value
<< 3;
2753 inst
.relax_inst
= 0x8000;
2757 /* ld/sw rD, [rA] convert to ld/sw rD, [rA, simm15]. */
2760 if (end_of_line (str
) == (int) FAIL
)
2763 ldst_idx
= inst
.instruction
& OPC_PSEUDOLDST_MASK
;
2764 inst
.instruction
&= ~OPC_PSEUDOLDST_MASK
;
2765 inst
.instruction
|= score_ldst_insns
[ldst_idx
* 3 + LDST_NOUPDATE
].value
;
2767 /* lbu rd, [rs] -> lbu! rd, [rs] */
2768 if (ldst_idx
== INSN_LBU
)
2770 inst
.relax_inst
= INSN16_LBU
;
2772 else if (ldst_idx
== INSN_LH
)
2774 inst
.relax_inst
= INSN16_LH
;
2776 else if (ldst_idx
== INSN_LW
)
2778 inst
.relax_inst
= INSN16_LW
;
2780 else if (ldst_idx
== INSN_SB
)
2782 inst
.relax_inst
= INSN16_SB
;
2784 else if (ldst_idx
== INSN_SH
)
2786 inst
.relax_inst
= INSN16_SH
;
2788 else if (ldst_idx
== INSN_SW
)
2790 inst
.relax_inst
= INSN16_SW
;
2794 inst
.relax_inst
= 0x8000;
2797 /* lw/lh/lbu/sw/sh/sb, offset = 0, relax to 16 bit instruction. */
2798 if ((ldst_idx
== INSN_LBU
)
2799 || (ldst_idx
== INSN_LH
)
2800 || (ldst_idx
== INSN_LW
)
2801 || (ldst_idx
== INSN_SB
) || (ldst_idx
== INSN_SH
) || (ldst_idx
== INSN_SW
))
2803 if ((((inst
.instruction
>> 15) & 0x10) == 0) && (((inst
.instruction
>> 20) & 0x10) == 0))
2805 inst
.relax_inst
|= (2 << 12) | (((inst
.instruction
>> 20) & 0xf) << 8) |
2806 (((inst
.instruction
>> 15) & 0xf) << 4);
2807 inst
.relax_size
= 2;
2814 /* ld/sw rD, [rA, simm15] ld/sw rD, [rA, simm12]+. */
2817 if (skip_past_comma (&str
) == (int) FAIL
)
2819 inst
.error
= _("pre-indexed expression expected");
2823 if (my_get_expression (&inst
.reloc
.exp
, &str
) == (int) FAIL
)
2826 skip_whitespace (str
);
2829 inst
.error
= _("missing ]");
2833 skip_whitespace (str
);
2834 /* ld/sw rD, [rA, simm12]+. */
2841 unsigned int ldst_func
= inst
.instruction
& OPC_PSEUDOLDST_MASK
;
2843 if ((ldst_func
== INSN_LH
)
2844 || (ldst_func
== INSN_LHU
)
2845 || (ldst_func
== INSN_LW
)
2846 || (ldst_func
== INSN_LB
)
2847 || (ldst_func
== INSN_LBU
))
2849 inst
.error
= _("register same as write-back base");
2855 if (end_of_line (str
) == (int) FAIL
)
2858 if (inst
.reloc
.exp
.X_op
== O_constant
)
2861 unsigned int data_type
;
2864 data_type
= _SIMM12
;
2866 data_type
= _SIMM15
;
2869 if ((*dataptr
== '0') && (*(dataptr
+ 1) == 'x')
2870 && (data_type
!= _SIMM16_LA
)
2871 && (data_type
!= _VALUE_HI16
)
2872 && (data_type
!= _VALUE_LO16
)
2873 && (data_type
!= _IMM16
)
2874 && (data_type
!= _IMM15
)
2875 && (data_type
!= _IMM14
)
2876 && (data_type
!= _IMM4
)
2877 && (data_type
!= _IMM5
)
2878 && (data_type
!= _IMM8
)
2879 && (data_type
!= _IMM5_RSHIFT_1
)
2880 && (data_type
!= _IMM5_RSHIFT_2
)
2881 && (data_type
!= _SIMM14_NEG
)
2882 && (data_type
!= _IMM10_RSHIFT_2
))
2887 value
= validate_immediate (inst
.reloc
.exp
.X_add_number
, data_type
);
2888 if (value
== (int) FAIL
)
2894 "invalid constant: %d bit expression not in range %d..%d",
2895 score_df_range
[data_type
].bits
,
2896 score_df_range
[data_type
].range
[0], score_df_range
[data_type
].range
[1]);
2899 "invalid constant: %d bit expression not in range %d..%d",
2900 score_df_range
[data_type
- 24].bits
,
2901 score_df_range
[data_type
- 24].range
[0],
2902 score_df_range
[data_type
- 24].range
[1]);
2903 inst
.error
= _(err_msg
);
2907 value
&= (1 << score_df_range
[data_type
].bits
) - 1;
2908 ldst_idx
= inst
.instruction
& OPC_PSEUDOLDST_MASK
;
2909 inst
.instruction
&= ~OPC_PSEUDOLDST_MASK
;
2910 inst
.instruction
|= score_ldst_insns
[ldst_idx
* 3 + pre_inc
].value
;
2912 inst
.instruction
|= value
<< 3;
2914 inst
.instruction
|= value
;
2916 /* lw rD, [rA, simm15] */
2917 if ((inst
.instruction
& 0x3e000000) == 0x20000000)
2919 /* Both rD and rA are in [r0 - r15]. */
2920 if ((((inst
.instruction
>> 15) & 0x10) == 0)
2921 && (((inst
.instruction
>> 20) & 0x10) == 0))
2923 /* simm15 = 0, lw -> lw!. */
2924 if ((inst
.instruction
& 0x7fff) == 0)
2926 inst
.relax_inst
|= (((inst
.instruction
>> 15) & 0xf) << 4)
2927 | (((inst
.instruction
>> 20) & 0xf) << 8);
2928 inst
.relax_size
= 2;
2930 /* rA = r2, lw -> lwp!. */
2931 else if ((((inst
.instruction
>> 15) & 0xf) == 2)
2932 && ((inst
.instruction
& 0x3) == 0)
2933 && ((inst
.instruction
& 0x7fff) < 128))
2935 inst
.relax_inst
= 0x7000 | (((inst
.instruction
>> 20) & 0xf) << 8)
2936 | (((inst
.instruction
& 0x7fff) >> 2) << 3);
2937 inst
.relax_size
= 2;
2941 inst
.relax_inst
= 0x8000;
2946 inst
.relax_inst
= 0x8000;
2949 /* sw rD, [rA, simm15] */
2950 else if ((inst
.instruction
& 0x3e000000) == 0x28000000)
2952 /* Both rD and rA are in [r0 - r15]. */
2953 if ((((inst
.instruction
>> 15) & 0x10) == 0) && (((inst
.instruction
>> 20) & 0x10) == 0))
2955 /* simm15 = 0, sw -> sw!. */
2956 if ((inst
.instruction
& 0x7fff) == 0)
2958 inst
.relax_inst
|= (((inst
.instruction
>> 15) & 0xf) << 4)
2959 | (((inst
.instruction
>> 20) & 0xf) << 8);
2960 inst
.relax_size
= 2;
2962 /* rA = r2, sw -> swp!. */
2963 else if ((((inst
.instruction
>> 15) & 0xf) == 2)
2964 && ((inst
.instruction
& 0x3) == 0)
2965 && ((inst
.instruction
& 0x7fff) < 128))
2967 inst
.relax_inst
= 0x7004 | (((inst
.instruction
>> 20) & 0xf) << 8)
2968 | (((inst
.instruction
& 0x7fff) >> 2) << 3);
2969 inst
.relax_size
= 2;
2973 inst
.relax_inst
= 0x8000;
2978 inst
.relax_inst
= 0x8000;
2981 /* sw rD, [rA, simm15]+ sw pre. */
2982 else if ((inst
.instruction
& 0x3e000007) == 0x06000004)
2984 /* rA is in [r0 - r7], and simm15 = -4. */
2985 if ((((inst
.instruction
>> 15) & 0x18) == 0)
2986 && (((inst
.instruction
>> 3) & 0xfff) == 0xffc))
2988 /* sw -> pushhi!. */
2989 if ((((inst
.instruction
>> 20) & 0x10) == 0x10))
2991 inst
.relax_inst
= 0x0000200e | (((inst
.instruction
>> 20) & 0xf) << 8)
2992 | 1 << 7 | (((inst
.instruction
>> 15) & 0x7) << 4);
2993 inst
.relax_size
= 2;
2998 inst
.relax_inst
= 0x0000200e | (((inst
.instruction
>> 20) & 0xf) << 8)
2999 | 0 << 7 | (((inst
.instruction
>> 15) & 0x7) << 4);
3000 inst
.relax_size
= 2;
3005 inst
.relax_inst
= 0x8000;
3008 /* lh rD, [rA, simm15] */
3009 else if ((inst
.instruction
& 0x3e000000) == 0x22000000)
3011 /* Both rD and rA are in [r0 - r15]. */
3012 if ((((inst
.instruction
>> 15) & 0x10) == 0) && (((inst
.instruction
>> 20) & 0x10) == 0))
3014 /* simm15 = 0, lh -> lh!. */
3015 if ((inst
.instruction
& 0x7fff) == 0)
3017 inst
.relax_inst
|= (((inst
.instruction
>> 15) & 0xf) << 4)
3018 | (((inst
.instruction
>> 20) & 0xf) << 8);
3019 inst
.relax_size
= 2;
3021 /* rA = r2, lh -> lhp!. */
3022 else if ((((inst
.instruction
>> 15) & 0xf) == 2)
3023 && ((inst
.instruction
& 0x1) == 0)
3024 && ((inst
.instruction
& 0x7fff) < 64))
3026 inst
.relax_inst
= 0x7001 | (((inst
.instruction
>> 20) & 0xf) << 8)
3027 | (((inst
.instruction
& 0x7fff) >> 1) << 3);
3028 inst
.relax_size
= 2;
3032 inst
.relax_inst
= 0x8000;
3037 inst
.relax_inst
= 0x8000;
3040 /* sh rD, [rA, simm15] */
3041 else if ((inst
.instruction
& 0x3e000000) == 0x2a000000)
3043 /* Both rD and rA are in [r0 - r15]. */
3044 if ((((inst
.instruction
>> 15) & 0x10) == 0) && (((inst
.instruction
>> 20) & 0x10) == 0))
3046 /* simm15 = 0, sh -> sh!. */
3047 if ((inst
.instruction
& 0x7fff) == 0)
3049 inst
.relax_inst
|= (((inst
.instruction
>> 15) & 0xf) << 4)
3050 | (((inst
.instruction
>> 20) & 0xf) << 8);
3051 inst
.relax_size
= 2;
3053 /* rA = r2, sh -> shp!. */
3054 else if ((((inst
.instruction
>> 15) & 0xf) == 2)
3055 && ((inst
.instruction
& 0x1) == 0)
3056 && ((inst
.instruction
& 0x7fff) < 64))
3058 inst
.relax_inst
= 0x7005 | (((inst
.instruction
>> 20) & 0xf) << 8)
3059 | (((inst
.instruction
& 0x7fff) >> 1) << 3);
3060 inst
.relax_size
= 2;
3064 inst
.relax_inst
= 0x8000;
3069 inst
.relax_inst
= 0x8000;
3072 /* lbu rD, [rA, simm15] */
3073 else if ((inst
.instruction
& 0x3e000000) == 0x2c000000)
3075 /* Both rD and rA are in [r0 - r15]. */
3076 if ((((inst
.instruction
>> 15) & 0x10) == 0) && (((inst
.instruction
>> 20) & 0x10) == 0))
3078 /* simm15 = 0, lbu -> lbu!. */
3079 if ((inst
.instruction
& 0x7fff) == 0)
3081 inst
.relax_inst
|= (((inst
.instruction
>> 15) & 0xf) << 4)
3082 | (((inst
.instruction
>> 20) & 0xf) << 8);
3083 inst
.relax_size
= 2;
3085 /* rA = r2, lbu -> lbup!. */
3086 else if ((((inst
.instruction
>> 15) & 0xf) == 2)
3087 && ((inst
.instruction
& 0x7fff) < 32))
3089 inst
.relax_inst
= 0x7003 | (((inst
.instruction
>> 20) & 0xf) << 8)
3090 | ((inst
.instruction
& 0x7fff) << 3);
3091 inst
.relax_size
= 2;
3095 inst
.relax_inst
= 0x8000;
3100 inst
.relax_inst
= 0x8000;
3103 /* sb rD, [rA, simm15] */
3104 else if ((inst
.instruction
& 0x3e000000) == 0x2e000000)
3106 /* Both rD and rA are in [r0 - r15]. */
3107 if ((((inst
.instruction
>> 15) & 0x10) == 0) && (((inst
.instruction
>> 20) & 0x10) == 0))
3109 /* simm15 = 0, sb -> sb!. */
3110 if ((inst
.instruction
& 0x7fff) == 0)
3112 inst
.relax_inst
|= (((inst
.instruction
>> 15) & 0xf) << 4)
3113 | (((inst
.instruction
>> 20) & 0xf) << 8);
3114 inst
.relax_size
= 2;
3116 /* rA = r2, sb -> sb!. */
3117 else if ((((inst
.instruction
>> 15) & 0xf) == 2)
3118 && ((inst
.instruction
& 0x7fff) < 32))
3120 inst
.relax_inst
= 0x7007 | (((inst
.instruction
>> 20) & 0xf) << 8)
3121 | ((inst
.instruction
& 0x7fff) << 3);
3122 inst
.relax_size
= 2;
3126 inst
.relax_inst
= 0x8000;
3131 inst
.relax_inst
= 0x8000;
3136 inst
.relax_inst
= 0x8000;
3143 /* FIXME: may set error, for there is no ld/sw rD, [rA, label] */
3144 inst
.reloc
.pc_rel
= 0;
3150 inst
.error
= BAD_ARGS
;
3157 do_cache (char *str
)
3159 skip_whitespace (str
);
3161 if ((data_op2 (&str
, 20, _IMM5
) == (int) FAIL
) || (skip_past_comma (&str
) == (int) FAIL
))
3169 cache_op
= (inst
.instruction
>> 20) & 0x1F;
3170 sprintf (inst
.name
, "cache %d", cache_op
);
3176 skip_whitespace (str
);
3178 if (reg_required_here (&str
, 15, REG_TYPE_SCORE
) == (int) FAIL
)
3181 skip_whitespace (str
);
3183 /* cache op, [rA] */
3184 if (skip_past_comma (&str
) == (int) FAIL
)
3186 SET_INSN_ERROR (NULL
);
3189 inst
.error
= _("missing ]");
3194 /* cache op, [rA, simm15] */
3197 if (exp_ldst_offset (&str
, 0, _SIMM15
) == (int) FAIL
)
3202 skip_whitespace (str
);
3205 inst
.error
= _("missing ]");
3210 if (end_of_line (str
) == (int) FAIL
)
3215 inst
.error
= BAD_ARGS
;
3220 do_crdcrscrsimm5 (char *str
)
3225 skip_whitespace (str
);
3227 if (reg_required_here (&str
, 20, REG_TYPE_SCORE_CR
) == (int) FAIL
3228 || skip_past_comma (&str
) == (int) FAIL
3229 || reg_required_here (&str
, 15, REG_TYPE_SCORE_CR
) == (int) FAIL
3230 || skip_past_comma (&str
) == (int) FAIL
3231 || reg_required_here (&str
, 10, REG_TYPE_SCORE_CR
) == (int) FAIL
3232 || skip_past_comma (&str
) == (int) FAIL
)
3235 /* cop1 cop_code20. */
3236 if (data_op2 (&str
, 5, _IMM20
) == (int) FAIL
)
3241 if (data_op2 (&str
, 5, _IMM5
) == (int) FAIL
)
3248 /* Handle ldc/stc. */
3250 do_ldst_cop (char *str
)
3252 skip_whitespace (str
);
3254 if ((reg_required_here (&str
, 15, REG_TYPE_SCORE_CR
) == (int) FAIL
)
3255 || (skip_past_comma (&str
) == (int) FAIL
))
3261 skip_whitespace (str
);
3263 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) == (int) FAIL
)
3266 skip_whitespace (str
);
3270 if (exp_ldst_offset (&str
, 5, _IMM10_RSHIFT_2
) == (int) FAIL
)
3273 skip_whitespace (str
);
3276 inst
.error
= _("missing ]");
3284 inst
.error
= BAD_ARGS
;
3288 do16_ldst_insn (char *str
)
3290 skip_whitespace (str
);
3292 if ((reglow_required_here (&str
, 8) == (int) FAIL
) || (skip_past_comma (&str
) == (int) FAIL
))
3300 skip_whitespace (str
);
3302 if ((reg
= reglow_required_here (&str
, 4)) == (int) FAIL
)
3305 skip_whitespace (str
);
3308 if (end_of_line (str
) == (int) FAIL
)
3312 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 20)
3313 | (((inst
.instruction
>> 4) & 0xf) << 15);
3314 inst
.relax_size
= 4;
3319 inst
.error
= _("missing ]");
3324 inst
.error
= BAD_ARGS
;
3328 /* Handle lbup!/lhp!/ldiu!/lwp!/sbp!/shp!/swp!. */
3330 do16_ldst_imm_insn (char *str
)
3332 char data_exp
[MAX_LITERAL_POOL_SIZE
];
3334 char *dataptr
= NULL
, *pp
= NULL
;
3336 int assign_data
= (int) FAIL
;
3337 unsigned int ldst_func
;
3339 skip_whitespace (str
);
3341 if (((reg_rd
= reglow_required_here (&str
, 8)) == (int) FAIL
)
3342 || (skip_past_comma (&str
) == (int) FAIL
))
3345 skip_whitespace (str
);
3348 while ((*dataptr
!= '\0') && (*dataptr
!= '|') && (cnt
<= MAX_LITERAL_POOL_SIZE
))
3350 data_exp
[cnt
] = *dataptr
;
3355 data_exp
[cnt
] = '\0';
3360 ldst_func
= inst
.instruction
& LDST16_RI_MASK
;
3361 if (ldst_func
== N16_LIU
)
3362 assign_data
= exp_ldst_offset (&pp
, 0, _IMM8
);
3363 else if (ldst_func
== N16_LHP
|| ldst_func
== N16_SHP
)
3364 assign_data
= exp_ldst_offset (&pp
, 3, _IMM5_RSHIFT_1
);
3365 else if (ldst_func
== N16_LWP
|| ldst_func
== N16_SWP
)
3366 assign_data
= exp_ldst_offset (&pp
, 3, _IMM5_RSHIFT_2
);
3368 assign_data
= exp_ldst_offset (&pp
, 3, _IMM5
);
3370 if ((assign_data
== (int) FAIL
) || (end_of_line (pp
) == (int) FAIL
))
3374 if ((inst
.instruction
& 0x7000) == N16_LIU
)
3376 inst
.relax_inst
|= ((inst
.instruction
>> 8) & 0xf) << 20
3377 | ((inst
.instruction
& 0xff) << 1);
3379 else if (((inst
.instruction
& 0x7007) == N16_LHP
)
3380 || ((inst
.instruction
& 0x7007) == N16_SHP
))
3382 inst
.relax_inst
|= ((inst
.instruction
>> 8) & 0xf) << 20 | 2 << 15
3383 | (((inst
.instruction
>> 3) & 0x1f) << 1);
3385 else if (((inst
.instruction
& 0x7007) == N16_LWP
)
3386 || ((inst
.instruction
& 0x7007) == N16_SWP
))
3388 inst
.relax_inst
|= ((inst
.instruction
>> 8) & 0xf) << 20 | 2 << 15
3389 | (((inst
.instruction
>> 3) & 0x1f) << 2);
3391 else if (((inst
.instruction
& 0x7007) == N16_LBUP
)
3392 || ((inst
.instruction
& 0x7007) == N16_SBP
))
3394 inst
.relax_inst
|= ((inst
.instruction
>> 8) & 0xf) << 20 | 2 << 15
3395 | (((inst
.instruction
>> 3) & 0x1f));
3398 inst
.relax_size
= 4;
3403 do16_push_pop (char *str
)
3408 skip_whitespace (str
);
3409 if (((reg_rd
= reg_required_here (&str
, 8, REG_TYPE_SCORE
)) == (int) FAIL
)
3410 || (skip_past_comma (&str
) == (int) FAIL
))
3416 /* reg_required_here will change bit 12 of opcode, so we must restore bit 12. */
3417 inst
.instruction
&= ~(1 << 12);
3419 inst
.instruction
|= H_bit_mask
<< 7;
3426 skip_whitespace (str
);
3427 if ((reg
= reg_required_here (&str
, 4, REG_TYPE_SCORE
)) == (int) FAIL
)
3432 inst
.error
= _("base register nums are over 3 bit");
3437 skip_whitespace (str
);
3438 if ((*str
++ != ']') || (end_of_line (str
) == (int) FAIL
))
3441 inst
.error
= _("missing ]");
3447 if ((inst
.instruction
& 0xf) == 0xa)
3451 inst
.relax_inst
|= ((((inst
.instruction
>> 8) & 0xf) | 0x10) << 20)
3452 | (((inst
.instruction
>> 4) & 0x7) << 15) | (4 << 3);
3456 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 20)
3457 | (((inst
.instruction
>> 4) & 0x7) << 15) | (4 << 3);
3465 inst
.relax_inst
|= ((((inst
.instruction
>> 8) & 0xf) | 0x10) << 20)
3466 | (((inst
.instruction
>> 4) & 0x7) << 15) | (((-4) & 0xfff) << 3);
3470 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 20)
3471 | (((inst
.instruction
>> 4) & 0x7) << 15) | (((-4) & 0xfff) << 3);
3474 inst
.relax_size
= 4;
3478 inst
.error
= BAD_ARGS
;
3482 /* Handle lcb/lcw/lce/scb/scw/sce. */
3484 do_ldst_unalign (char *str
)
3488 if (university_version
== 1)
3490 inst
.error
= ERR_FOR_SCORE5U_ATOMIC
;
3494 skip_whitespace (str
);
3496 /* lcb/scb [rA]+. */
3500 skip_whitespace (str
);
3502 if (reg_required_here (&str
, 15, REG_TYPE_SCORE
) == (int) FAIL
)
3509 inst
.error
= _("missing +");
3515 inst
.error
= _("missing ]");
3519 if (end_of_line (str
) == (int) FAIL
)
3522 /* lcw/lce/scb/sce rD, [rA]+. */
3525 if (((conflict_reg
= reg_required_here (&str
, 20, REG_TYPE_SCORE
)) == (int) FAIL
)
3526 || (skip_past_comma (&str
) == (int) FAIL
))
3531 skip_whitespace (str
);
3536 skip_whitespace (str
);
3537 if ((reg
= reg_required_here (&str
, 15, REG_TYPE_SCORE
)) == (int) FAIL
)
3542 /* Conflicts can occur on stores as well as loads. */
3543 conflict_reg
= (conflict_reg
== reg
);
3544 skip_whitespace (str
);
3547 unsigned int ldst_func
= inst
.instruction
& LDST_UNALIGN_MASK
;
3553 as_warn (_("%s register same as write-back base"),
3554 ((ldst_func
& UA_LCE
) || (ldst_func
& UA_LCW
)
3555 ? _("destination") : _("source")));
3560 inst
.error
= _("missing +");
3564 if (end_of_line (str
) == (int) FAIL
)
3569 inst
.error
= _("missing ]");
3575 inst
.error
= BAD_ARGS
;
3581 /* Handle alw/asw. */
3583 do_ldst_atomic (char *str
)
3585 if (university_version
== 1)
3587 inst
.error
= ERR_FOR_SCORE5U_ATOMIC
;
3591 skip_whitespace (str
);
3593 if ((reg_required_here (&str
, 20, REG_TYPE_SCORE
) == (int) FAIL
)
3594 || (skip_past_comma (&str
) == (int) FAIL
))
3601 skip_whitespace (str
);
3606 skip_whitespace (str
);
3607 if ((reg
= reg_required_here (&str
, 15, REG_TYPE_SCORE
)) == (int) FAIL
)
3612 skip_whitespace (str
);
3615 inst
.error
= _("missing ]");
3622 inst
.error
= BAD_ARGS
;
3627 build_relax_frag (struct score_it fix_insts
[RELAX_INST_NUM
], int fix_num ATTRIBUTE_UNUSED
,
3628 struct score_it var_insts
[RELAX_INST_NUM
], int var_num
,
3629 symbolS
*add_symbol
)
3634 fixS
*cur_fixp
= NULL
;
3636 struct score_it inst_main
;
3638 memcpy (&inst_main
, &fix_insts
[0], sizeof (struct score_it
));
3640 /* Adjust instruction opcode and to be relaxed instruction opcode. */
3641 inst_main
.instruction
= adjust_paritybit (inst_main
.instruction
, GET_INSN_CLASS (inst_main
.type
));
3642 inst_main
.type
= Insn_PIC
;
3644 for (i
= 0; i
< var_num
; i
++)
3646 inst_main
.relax_size
+= var_insts
[i
].size
;
3647 var_insts
[i
].instruction
= adjust_paritybit (var_insts
[i
].instruction
,
3648 GET_INSN_CLASS (var_insts
[i
].type
));
3651 /* Check data dependency. */
3652 handle_dependency (&inst_main
);
3654 /* Start a new frag if frag_now is not empty. */
3655 if (frag_now_fix () != 0)
3657 if (!frag_now
->tc_frag_data
.is_insn
)
3659 frag_wane (frag_now
);
3665 /* Write fr_fix part. */
3666 p
= frag_more (inst_main
.size
);
3667 md_number_to_chars (p
, inst_main
.instruction
, inst_main
.size
);
3669 if (inst_main
.reloc
.type
!= BFD_RELOC_NONE
)
3670 fixp
= fix_new_score (frag_now
, p
- frag_now
->fr_literal
, inst_main
.size
,
3671 &inst_main
.reloc
.exp
, inst_main
.reloc
.pc_rel
, inst_main
.reloc
.type
);
3673 frag_now
->tc_frag_data
.fixp
= fixp
;
3674 cur_fixp
= frag_now
->tc_frag_data
.fixp
;
3677 dwarf2_emit_insn (inst_main
.size
);
3680 where
= p
- frag_now
->fr_literal
+ inst_main
.size
;
3681 for (i
= 0; i
< var_num
; i
++)
3684 where
+= var_insts
[i
- 1].size
;
3686 if (var_insts
[i
].reloc
.type
!= BFD_RELOC_NONE
)
3688 fixp
= fix_new_score (frag_now
, where
, var_insts
[i
].size
,
3689 &var_insts
[i
].reloc
.exp
, var_insts
[i
].reloc
.pc_rel
,
3690 var_insts
[i
].reloc
.type
);
3695 cur_fixp
->fx_next
= fixp
;
3696 cur_fixp
= cur_fixp
->fx_next
;
3700 frag_now
->tc_frag_data
.fixp
= fixp
;
3701 cur_fixp
= frag_now
->tc_frag_data
.fixp
;
3707 p
= frag_var (rs_machine_dependent
, inst_main
.relax_size
+ RELAX_PAD_BYTE
, 0,
3708 RELAX_ENCODE (inst_main
.size
, inst_main
.relax_size
, inst_main
.type
,
3709 0, inst_main
.size
, 0), add_symbol
, 0, NULL
);
3711 /* Write fr_var part.
3712 no calling gen_insn_frag, no fixS will be generated. */
3713 for (i
= 0; i
< var_num
; i
++)
3715 md_number_to_chars (p
, var_insts
[i
].instruction
, var_insts
[i
].size
);
3716 p
+= var_insts
[i
].size
;
3718 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
3722 /* Build a relax frag for la instruction when generating PIC,
3723 external symbol first and local symbol second. */
3726 build_la_pic (int reg_rd
, expressionS exp
)
3728 symbolS
*add_symbol
= exp
.X_add_symbol
;
3729 offsetT add_number
= exp
.X_add_number
;
3730 struct score_it fix_insts
[RELAX_INST_NUM
];
3731 struct score_it var_insts
[RELAX_INST_NUM
];
3734 char tmp
[MAX_LITERAL_POOL_SIZE
];
3740 if (add_number
== 0)
3745 /* Insn 1 and Insn 2 */
3747 For an external symbol: lw rD, <sym>($gp)
3748 (BFD_RELOC_SCORE_GOT15 or BFD_RELOC_SCORE_CALL15) */
3749 sprintf (tmp
, "lw_pic r%d, %s", reg_rd
, add_symbol
->bsym
->name
);
3750 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
3753 if (reg_rd
== PIC_CALL_REG
)
3754 inst
.reloc
.type
= BFD_RELOC_SCORE_CALL15
;
3755 memcpy (&fix_insts
[0], &inst
, sizeof (struct score_it
));
3758 For a local symbol :
3759 lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15)
3760 addi rD, <sym> (BFD_RELOC_GOT_LO16) */
3761 inst
.reloc
.type
= BFD_RELOC_SCORE_GOT15
;
3762 memcpy (&var_insts
[0], &inst
, sizeof (struct score_it
));
3763 sprintf (tmp
, "addi_s_pic r%d, %s", reg_rd
, add_symbol
->bsym
->name
);
3764 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
3767 memcpy (&var_insts
[1], &inst
, sizeof (struct score_it
));
3768 build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
3770 else if (add_number
>= -0x8000 && add_number
<= 0x7fff)
3772 /* Insn 1: lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15) */
3773 sprintf (tmp
, "lw_pic r%d, %s", reg_rd
, add_symbol
->bsym
->name
);
3774 if (append_insn (tmp
, TRUE
) == (int) FAIL
)
3781 For an external symbol: addi rD, <constant> */
3782 sprintf (tmp
, "addi r%d, %d", reg_rd
, (int)add_number
);
3783 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
3786 memcpy (&fix_insts
[0], &inst
, sizeof (struct score_it
));
3789 For a local symbol: addi rD, <sym>+<constant> (BFD_RELOC_GOT_LO16) */
3790 sprintf (tmp
, "addi_s_pic r%d, %s + %d", reg_rd
, add_symbol
->bsym
->name
, (int)add_number
);
3791 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
3794 memcpy (&var_insts
[0], &inst
, sizeof (struct score_it
));
3795 build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
3799 int hi
= (add_number
>> 16) & 0x0000FFFF;
3800 int lo
= add_number
& 0x0000FFFF;
3802 /* Insn 1: lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15) */
3803 sprintf (tmp
, "lw_pic r%d, %s", reg_rd
, add_symbol
->bsym
->name
);
3804 if (append_insn (tmp
, TRUE
) == (int) FAIL
)
3811 For an external symbol: ldis r1, HI%<constant> */
3812 sprintf (tmp
, "ldis %s, %d", "r1", hi
);
3813 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
3816 memcpy (&fix_insts
[0], &inst
, sizeof (struct score_it
));
3819 For a local symbol: ldis r1, HI%<constant>
3820 but, if lo is outof 16 bit, make hi plus 1 */
3821 if ((lo
< -0x8000) || (lo
> 0x7fff))
3825 sprintf (tmp
, "ldis_pic %s, %d", "r1", hi
);
3826 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
3829 memcpy (&var_insts
[0], &inst
, sizeof (struct score_it
));
3830 build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
3836 For an external symbol: ori r1, LO%<constant> */
3837 sprintf (tmp
, "ori %s, %d", "r1", lo
);
3838 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
3841 memcpy (&fix_insts
[0], &inst
, sizeof (struct score_it
));
3844 For a local symbol: addi r1, <sym>+LO%<constant> (BFD_RELOC_GOT_LO16) */
3845 sprintf (tmp
, "addi_u_pic %s, %s + %d", "r1", add_symbol
->bsym
->name
, lo
);
3846 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
3849 memcpy (&var_insts
[0], &inst
, sizeof (struct score_it
));
3850 build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
3852 /* Insn 4: add rD, rD, r1 */
3853 sprintf (tmp
, "add r%d, r%d, %s", reg_rd
, reg_rd
, "r1");
3854 if (append_insn (tmp
, TRUE
) == (int) FAIL
)
3857 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
3866 do_macro_la_rdi32 (char *str
)
3870 skip_whitespace (str
);
3871 if ((reg_rd
= reg_required_here (&str
, 20, REG_TYPE_SCORE
)) == (int) FAIL
3872 || skip_past_comma (&str
) == (int) FAIL
)
3878 char append_str
[MAX_LITERAL_POOL_SIZE
];
3879 char *keep_data
= str
;
3881 /* la rd, simm16. */
3882 if (data_op2 (&str
, 1, _SIMM16_LA
) != (int) FAIL
)
3887 /* la rd, imm32 or la rd, label. */
3890 SET_INSN_ERROR (NULL
);
3892 if ((data_op2 (&str
, 1, _VALUE_HI16
) == (int) FAIL
)
3893 || (end_of_line (str
) == (int) FAIL
))
3899 if ((score_pic
== NO_PIC
) || (!inst
.reloc
.exp
.X_add_symbol
))
3901 sprintf (append_str
, "ld_i32hi r%d, %s", reg_rd
, keep_data
);
3902 if (append_insn (append_str
, TRUE
) == (int) FAIL
)
3905 sprintf (append_str
, "ld_i32lo r%d, %s", reg_rd
, keep_data
);
3906 if (append_insn (append_str
, TRUE
) == (int) FAIL
)
3911 assert (inst
.reloc
.exp
.X_add_symbol
);
3912 build_la_pic (reg_rd
, inst
.reloc
.exp
);
3915 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
3924 do_macro_li_rdi32 (char *str
){
3928 skip_whitespace (str
);
3929 if ((reg_rd
= reg_required_here (&str
, 20, REG_TYPE_SCORE
)) == (int) FAIL
3930 || skip_past_comma (&str
) == (int) FAIL
)
3936 char *keep_data
= str
;
3938 /* li rd, simm16. */
3939 if (data_op2 (&str
, 1, _SIMM16_LA
) != (int) FAIL
)
3947 char append_str
[MAX_LITERAL_POOL_SIZE
];
3951 if ((data_op2 (&str
, 1, _VALUE_HI16
) == (int) FAIL
)
3952 || (end_of_line (str
) == (int) FAIL
))
3956 else if (inst
.reloc
.exp
.X_add_symbol
)
3958 inst
.error
= _("li rd label isn't correct instruction form");
3963 sprintf (append_str
, "ld_i32hi r%d, %s", reg_rd
, keep_data
);
3965 if (append_insn (append_str
, TRUE
) == (int) FAIL
)
3969 sprintf (append_str
, "ld_i32lo r%d, %s", reg_rd
, keep_data
);
3970 if (append_insn (append_str
, TRUE
) == (int) FAIL
)
3973 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
3981 /* Handle mul/mulu/div/divu/rem/remu. */
3983 do_macro_mul_rdrsrs (char *str
)
3989 char append_str
[MAX_LITERAL_POOL_SIZE
];
3991 if (university_version
== 1)
3992 as_warn ("%s", ERR_FOR_SCORE5U_MUL_DIV
);
3994 strcpy (append_str
, str
);
3995 backupstr
= append_str
;
3996 skip_whitespace (backupstr
);
3997 if (((reg_rd
= reg_required_here (&backupstr
, -1, REG_TYPE_SCORE
)) == (int) FAIL
)
3998 || (skip_past_comma (&backupstr
) == (int) FAIL
)
3999 || ((reg_rs1
= reg_required_here (&backupstr
, -1, REG_TYPE_SCORE
)) == (int) FAIL
))
4001 inst
.error
= BAD_ARGS
;
4005 if (skip_past_comma (&backupstr
) == (int) FAIL
)
4007 /* rem/remu rA, rB is error format. */
4008 if (strcmp (inst
.name
, "rem") == 0 || strcmp (inst
.name
, "remu") == 0)
4010 SET_INSN_ERROR (BAD_ARGS
);
4014 SET_INSN_ERROR (NULL
);
4021 SET_INSN_ERROR (NULL
);
4022 if (((reg_rs2
= reg_required_here (&backupstr
, -1, REG_TYPE_SCORE
)) == (int) FAIL
)
4023 || (end_of_line (backupstr
) == (int) FAIL
))
4029 char append_str1
[MAX_LITERAL_POOL_SIZE
];
4031 if (strcmp (inst
.name
, "rem") == 0)
4033 sprintf (append_str
, "%s r%d, r%d", "mul", reg_rs1
, reg_rs2
);
4034 sprintf (append_str1
, "mfceh r%d", reg_rd
);
4036 else if (strcmp (inst
.name
, "remu") == 0)
4038 sprintf (append_str
, "%s r%d, r%d", "mulu", reg_rs1
, reg_rs2
);
4039 sprintf (append_str1
, "mfceh r%d", reg_rd
);
4043 sprintf (append_str
, "%s r%d, r%d", inst
.name
, reg_rs1
, reg_rs2
);
4044 sprintf (append_str1
, "mfcel r%d", reg_rd
);
4047 /* Output mul/mulu or div/divu or rem/remu. */
4048 if (append_insn (append_str
, TRUE
) == (int) FAIL
)
4051 /* Output mfcel or mfceh. */
4052 if (append_insn (append_str1
, TRUE
) == (int) FAIL
)
4055 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4062 exp_macro_ldst_abs (char *str
)
4065 char *backupstr
, *tmp
;
4066 char append_str
[MAX_LITERAL_POOL_SIZE
];
4067 char verifystr
[MAX_LITERAL_POOL_SIZE
];
4068 struct score_it inst_backup
;
4073 memcpy (&inst_backup
, &inst
, sizeof (struct score_it
));
4075 strcpy (verifystr
, str
);
4076 backupstr
= verifystr
;
4077 skip_whitespace (backupstr
);
4078 if ((reg_rd
= reg_required_here (&backupstr
, -1, REG_TYPE_SCORE
)) == (int) FAIL
)
4082 if (skip_past_comma (&backupstr
) == (int) FAIL
)
4086 sprintf (append_str
, "li r1 %s", backupstr
);
4087 append_insn (append_str
, TRUE
);
4089 memcpy (&inst
, &inst_backup
, sizeof (struct score_it
));
4090 sprintf (append_str
, " r%d, [r1,0]", reg_rd
);
4091 do_ldst_insn (append_str
);
4097 nopic_need_relax (symbolS
* sym
, int before_relaxing
)
4101 else if (USE_GLOBAL_POINTER_OPT
&& g_switch_value
> 0)
4103 const char *symname
;
4104 const char *segname
;
4106 /* Find out whether this symbol can be referenced off the $gp
4107 register. It can be if it is smaller than the -G size or if
4108 it is in the .sdata or .sbss section. Certain symbols can
4109 not be referenced off the $gp, although it appears as though
4111 symname
= S_GET_NAME (sym
);
4112 if (symname
!= (const char *)NULL
4113 && (strcmp (symname
, "eprol") == 0
4114 || strcmp (symname
, "etext") == 0
4115 || strcmp (symname
, "_gp") == 0
4116 || strcmp (symname
, "edata") == 0
4117 || strcmp (symname
, "_fbss") == 0
4118 || strcmp (symname
, "_fdata") == 0
4119 || strcmp (symname
, "_ftext") == 0
4120 || strcmp (symname
, "end") == 0
4121 || strcmp (symname
, GP_DISP_LABEL
) == 0))
4125 else if ((!S_IS_DEFINED (sym
) || S_IS_COMMON (sym
)) && (0
4126 /* We must defer this decision until after the whole file has been read,
4127 since there might be a .extern after the first use of this symbol. */
4129 && S_GET_VALUE (sym
) == 0)
4130 || (S_GET_VALUE (sym
) != 0
4131 && S_GET_VALUE (sym
) <= g_switch_value
)))
4136 segname
= segment_name (S_GET_SEGMENT (sym
));
4137 return (strcmp (segname
, ".sdata") != 0
4138 && strcmp (segname
, ".sbss") != 0
4139 && strncmp (segname
, ".sdata.", 7) != 0
4140 && strncmp (segname
, ".gnu.linkonce.s.", 16) != 0);
4142 /* We are not optimizing for the $gp register. */
4147 /* Build a relax frag for lw instruction when generating PIC,
4148 external symbol first and local symbol second. */
4151 build_lw_pic (int reg_rd
, expressionS exp
)
4153 symbolS
*add_symbol
= exp
.X_add_symbol
;
4154 int add_number
= exp
.X_add_number
;
4155 struct score_it fix_insts
[RELAX_INST_NUM
];
4156 struct score_it var_insts
[RELAX_INST_NUM
];
4159 char tmp
[MAX_LITERAL_POOL_SIZE
];
4165 if ((add_number
== 0) || (add_number
>= -0x8000 && add_number
<= 0x7fff))
4170 /* Insn 1 and Insn 2 */
4172 For an external symbol: lw rD, <sym>($gp)
4173 (BFD_RELOC_SCORE_GOT15) */
4174 sprintf (tmp
, "lw_pic r%d, %s", reg_rd
, add_symbol
->bsym
->name
);
4175 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
4178 memcpy (&fix_insts
[0], &inst
, sizeof (struct score_it
));
4181 For a local symbol :
4182 lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15)
4183 addi rD, <sym> (BFD_RELOC_GOT_LO16) */
4184 inst
.reloc
.type
= BFD_RELOC_SCORE_GOT15
;
4185 memcpy (&var_insts
[0], &inst
, sizeof (struct score_it
));
4186 sprintf (tmp
, "addi_s_pic r%d, %s", reg_rd
, add_symbol
->bsym
->name
);
4187 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
4190 memcpy (&var_insts
[1], &inst
, sizeof (struct score_it
));
4191 build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
4193 /* Insn 2: lw rD, [rD, constant] */
4194 sprintf (tmp
, "lw r%d, [r%d, %d]", reg_rd
, reg_rd
, add_number
);
4195 if (append_insn (tmp
, TRUE
) == (int) FAIL
)
4198 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4203 int hi
= (add_number
>> 16) & 0x0000FFFF;
4204 int lo
= add_number
& 0x0000FFFF;
4206 /* Insn 1: lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15) */
4207 sprintf (tmp
, "lw_pic r%d, %s", reg_rd
, add_symbol
->bsym
->name
);
4208 if (append_insn (tmp
, TRUE
) == (int) FAIL
)
4215 For an external symbol: ldis r1, HI%<constant> */
4216 sprintf (tmp
, "ldis %s, %d", "r1", hi
);
4217 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
4220 memcpy (&fix_insts
[0], &inst
, sizeof (struct score_it
));
4223 For a local symbol: ldis r1, HI%<constant>
4224 but, if lo is outof 16 bit, make hi plus 1 */
4225 if ((lo
< -0x8000) || (lo
> 0x7fff))
4229 sprintf (tmp
, "ldis_pic %s, %d", "r1", hi
);
4230 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
4233 memcpy (&var_insts
[0], &inst
, sizeof (struct score_it
));
4234 build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
4240 For an external symbol: ori r1, LO%<constant> */
4241 sprintf (tmp
, "ori %s, %d", "r1", lo
);
4242 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
4245 memcpy (&fix_insts
[0], &inst
, sizeof (struct score_it
));
4248 For a local symbol: addi r1, <sym>+LO%<constant> (BFD_RELOC_GOT_LO16) */
4249 sprintf (tmp
, "addi_u_pic %s, %s + %d", "r1", add_symbol
->bsym
->name
, lo
);
4250 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
4253 memcpy (&var_insts
[0], &inst
, sizeof (struct score_it
));
4254 build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
4256 /* Insn 4: add rD, rD, r1 */
4257 sprintf (tmp
, "add r%d, r%d, %s", reg_rd
, reg_rd
, "r1");
4258 if (append_insn (tmp
, TRUE
) == (int) FAIL
)
4261 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4264 /* Insn 5: lw rD, [rD, 0] */
4265 sprintf (tmp
, "lw r%d, [r%d, 0]", reg_rd
, reg_rd
);
4266 if (append_insn (tmp
, TRUE
) == (int) FAIL
)
4269 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4277 do_macro_ldst_label (char *str
)
4285 char *absolute_value
;
4286 char append_str
[3][MAX_LITERAL_POOL_SIZE
];
4287 char verifystr
[MAX_LITERAL_POOL_SIZE
];
4288 struct score_it inst_backup
;
4289 struct score_it inst_expand
[3];
4290 struct score_it inst_main
;
4292 memcpy (&inst_backup
, &inst
, sizeof (struct score_it
));
4293 strcpy (verifystr
, str
);
4294 backup_str
= verifystr
;
4296 skip_whitespace (backup_str
);
4297 if ((reg_rd
= reg_required_here (&backup_str
, -1, REG_TYPE_SCORE
)) == (int) FAIL
)
4300 if (skip_past_comma (&backup_str
) == (int) FAIL
)
4303 label_str
= backup_str
;
4305 /* Ld/st rD, [rA, imm] ld/st rD, [rA]+, imm ld/st rD, [rA, imm]+. */
4306 if (*backup_str
== '[')
4308 inst
.type
= Rd_rvalueRs_preSI12
;
4313 /* Ld/st rD, imm. */
4314 absolute_value
= backup_str
;
4315 inst
.type
= Rd_rvalueRs_SI15
;
4316 if ((my_get_expression (&inst
.reloc
.exp
, &backup_str
) == (int) FAIL
)
4317 || (validate_immediate (inst
.reloc
.exp
.X_add_number
, _VALUE
) == (int) FAIL
)
4318 || (end_of_line (backup_str
) == (int) FAIL
))
4324 if (inst
.reloc
.exp
.X_add_symbol
== 0)
4326 memcpy (&inst
, &inst_backup
, sizeof (struct score_it
));
4327 exp_macro_ldst_abs (str
);
4332 /* Ld/st rD, label. */
4333 inst
.type
= Rd_rvalueRs_SI15
;
4334 backup_str
= absolute_value
;
4335 if ((data_op2 (&backup_str
, 1, _GP_IMM15
) == (int) FAIL
)
4336 || (end_of_line (backup_str
) == (int) FAIL
))
4342 if (inst
.reloc
.exp
.X_add_symbol
== 0)
4345 inst
.error
= BAD_ARGS
;
4350 if (score_pic
== PIC
)
4352 build_lw_pic (reg_rd
, inst
.reloc
.exp
);
4357 if ((inst
.reloc
.exp
.X_add_number
<= 0x3fff)
4358 && (inst
.reloc
.exp
.X_add_number
>= -0x4000)
4359 && (!nopic_need_relax (inst
.reloc
.exp
.X_add_symbol
, 1)))
4363 /* Assign the real opcode. */
4364 ldst_idx
= inst
.instruction
& OPC_PSEUDOLDST_MASK
;
4365 inst
.instruction
&= ~OPC_PSEUDOLDST_MASK
;
4366 inst
.instruction
|= score_ldst_insns
[ldst_idx
* 3 + 0].value
;
4367 inst
.instruction
|= reg_rd
<< 20;
4368 inst
.instruction
|= GP
<< 15;
4369 inst
.relax_inst
= 0x8000;
4370 inst
.relax_size
= 0;
4377 memcpy (&inst_main
, &inst
, sizeof (struct score_it
));
4381 /* Determine which instructions should be output. */
4382 sprintf (append_str
[0], "ld_i32hi r1, %s", label_str
);
4383 sprintf (append_str
[1], "ld_i32lo r1, %s", label_str
);
4384 sprintf (append_str
[2], "%s r%d, [r1, 0]", inst_backup
.name
, reg_rd
);
4386 /* Generate three instructions.
4388 ld/st rd, [r1, 0] */
4389 for (i
= 0; i
< 3; i
++)
4391 if (append_insn (append_str
[i
], FALSE
) == (int) FAIL
)
4394 memcpy (&inst_expand
[i
], &inst
, sizeof (struct score_it
));
4401 /* Adjust instruction opcode and to be relaxed instruction opcode. */
4402 inst_main
.instruction
= adjust_paritybit (inst_main
.instruction
, GET_INSN_CLASS (inst_main
.type
));
4403 inst_main
.relax_size
= inst_expand
[0].size
+ inst_expand
[1].size
+ inst_expand
[2].size
;
4404 inst_main
.type
= Insn_GP
;
4406 for (i
= 0; i
< 3; i
++)
4407 inst_expand
[i
].instruction
= adjust_paritybit (inst_expand
[i
].instruction
4408 , GET_INSN_CLASS (inst_expand
[i
].type
));
4410 /* Check data dependency. */
4411 handle_dependency (&inst_main
);
4413 /* Start a new frag if frag_now is not empty. */
4414 if (frag_now_fix () != 0)
4416 if (!frag_now
->tc_frag_data
.is_insn
)
4417 frag_wane (frag_now
);
4423 /* Write fr_fix part. */
4424 p
= frag_more (inst_main
.size
);
4425 md_number_to_chars (p
, inst_main
.instruction
, inst_main
.size
);
4427 if (inst_main
.reloc
.type
!= BFD_RELOC_NONE
)
4429 fix_new_score (frag_now
, p
- frag_now
->fr_literal
, inst_main
.size
,
4430 &inst_main
.reloc
.exp
, inst_main
.reloc
.pc_rel
, inst_main
.reloc
.type
);
4434 dwarf2_emit_insn (inst_main
.size
);
4437 /* GP instruction can not do optimization, only can do relax between
4438 1 instruction and 3 instructions. */
4439 p
= frag_var (rs_machine_dependent
, inst_main
.relax_size
+ RELAX_PAD_BYTE
, 0,
4440 RELAX_ENCODE (inst_main
.size
, inst_main
.relax_size
, inst_main
.type
, 0, 4, 0),
4441 inst_main
.reloc
.exp
.X_add_symbol
, 0, NULL
);
4443 /* Write fr_var part.
4444 no calling gen_insn_frag, no fixS will be generated. */
4445 md_number_to_chars (p
, inst_expand
[0].instruction
, inst_expand
[0].size
);
4446 p
+= inst_expand
[0].size
;
4447 md_number_to_chars (p
, inst_expand
[1].instruction
, inst_expand
[1].size
);
4448 p
+= inst_expand
[1].size
;
4449 md_number_to_chars (p
, inst_expand
[2].instruction
, inst_expand
[2].size
);
4453 gen_insn_frag (&inst_expand
[0], NULL
);
4454 gen_insn_frag (&inst_expand
[1], NULL
);
4455 gen_insn_frag (&inst_expand
[2], NULL
);
4459 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4464 do_lw_pic (char *str
)
4468 skip_whitespace (str
);
4469 if (((reg_rd
= reg_required_here (&str
, 20, REG_TYPE_SCORE
)) == (int) FAIL
)
4470 || (skip_past_comma (&str
) == (int) FAIL
)
4471 || (my_get_expression (&inst
.reloc
.exp
, &str
) == (int) FAIL
)
4472 || (end_of_line (str
) == (int) FAIL
))
4478 if (inst
.reloc
.exp
.X_add_symbol
== 0)
4481 inst
.error
= BAD_ARGS
;
4486 inst
.instruction
|= GP
<< 15;
4487 inst
.reloc
.type
= BFD_RELOC_SCORE_GOT15
;
4492 do_empty (char *str
)
4495 if (university_version
== 1)
4497 if (((inst
.instruction
& 0x3e0003ff) == 0x0c000004)
4498 || ((inst
.instruction
& 0x3e0003ff) == 0x0c000024)
4499 || ((inst
.instruction
& 0x3e0003ff) == 0x0c000044)
4500 || ((inst
.instruction
& 0x3e0003ff) == 0x0c000064))
4502 inst
.error
= ERR_FOR_SCORE5U_MMU
;
4506 if (end_of_line (str
) == (int) FAIL
)
4509 if (inst
.relax_inst
!= 0x8000)
4511 if (inst
.type
== NO_OPD
)
4513 inst
.relax_size
= 2;
4517 inst
.relax_size
= 4;
4528 skip_whitespace (str
);
4529 if (my_get_expression (&inst
.reloc
.exp
, &str
) == (int) FAIL
4530 || end_of_line (str
) == (int) FAIL
)
4533 if (inst
.reloc
.exp
.X_add_symbol
== 0)
4535 inst
.error
= _("lacking label ");
4539 if (((inst
.reloc
.exp
.X_add_number
& 0xff000000) != 0)
4540 && ((inst
.reloc
.exp
.X_add_number
& 0xff000000) != 0xff000000))
4542 sprintf (err_msg
, "invalid constant: 25 bit expression not in range -2^24..2^24");
4543 inst
.error
= _(err_msg
);
4547 save_in
= input_line_pointer
;
4548 input_line_pointer
= str
;
4549 inst
.reloc
.type
= BFD_RELOC_SCORE_JMP
;
4550 inst
.reloc
.pc_rel
= 1;
4551 input_line_pointer
= save_in
;
4555 do16_jump (char *str
)
4557 skip_whitespace (str
);
4558 if (my_get_expression (&inst
.reloc
.exp
, &str
) == (int) FAIL
4559 || end_of_line (str
) == (int) FAIL
)
4563 else if (inst
.reloc
.exp
.X_add_symbol
== 0)
4565 inst
.error
= _("lacking label ");
4568 else if (((inst
.reloc
.exp
.X_add_number
& 0xfffff800) != 0)
4569 && ((inst
.reloc
.exp
.X_add_number
& 0xfffff800) != 0xfffff800))
4571 inst
.error
= _("invalid constant: 12 bit expression not in range -2^11..2^11");
4575 inst
.reloc
.type
= BFD_RELOC_SCORE16_JMP
;
4576 inst
.reloc
.pc_rel
= 1;
4580 do_branch (char *str
)
4582 unsigned long abs_value
= 0;
4584 if (my_get_expression (&inst
.reloc
.exp
, &str
) == (int) FAIL
4585 || end_of_line (str
) == (int) FAIL
)
4589 else if (inst
.reloc
.exp
.X_add_symbol
== 0)
4591 inst
.error
= _("lacking label ");
4594 else if (((inst
.reloc
.exp
.X_add_number
& 0xff000000) != 0)
4595 && ((inst
.reloc
.exp
.X_add_number
& 0xff000000) != 0xff000000))
4597 inst
.error
= "invalid constant: 20 bit expression not in range -2^19..2^19";
4601 inst
.reloc
.type
= BFD_RELOC_SCORE_BRANCH
;
4602 inst
.reloc
.pc_rel
= 1;
4604 /* Branch 32 offset field : 20 bit, 16 bit branch offset field : 8 bit. */
4605 inst
.instruction
|= (inst
.reloc
.exp
.X_add_number
& 0x3fe) | ((inst
.reloc
.exp
.X_add_number
& 0xffc00) << 5);
4607 /* Take the branch condition code. */
4608 inst
.relax_inst
= 0x4000 | (((inst
.instruction
>> 10) & 0xf) << 8);
4610 if ((abs_value
& 0xfffffe00) == 0)
4612 inst
.relax_inst
|= ((inst
.reloc
.exp
.X_add_number
>> 1) & 0xff);
4613 inst
.relax_size
= 2;
4617 inst
.relax_inst
= 0x8000;
4620 if (inst
.instruction
& 1)
4621 inst
.relax_inst
= 0x8000;
4625 do16_branch (char *str
)
4627 if ((my_get_expression (&inst
.reloc
.exp
, &str
) == (int) FAIL
4628 || end_of_line (str
) == (int) FAIL
))
4632 else if (inst
.reloc
.exp
.X_add_symbol
== 0)
4634 inst
.error
= _("lacking label");
4636 else if (((inst
.reloc
.exp
.X_add_number
& 0xffffff00) != 0)
4637 && ((inst
.reloc
.exp
.X_add_number
& 0xffffff00) != 0xffffff00))
4639 inst
.error
= _("invalid constant: 9 bit expression not in range -2^8..2^8");
4643 inst
.reloc
.type
= BFD_RELOC_SCORE16_BRANCH
;
4644 inst
.reloc
.pc_rel
= 1;
4645 inst
.instruction
|= ((inst
.reloc
.exp
.X_add_number
>> 1) & 0xff);
4649 /* Iterate over the base tables to create the instruction patterns. */
4651 build_score_ops_hsh (void)
4654 static struct obstack insn_obstack
;
4656 obstack_begin (&insn_obstack
, 4000);
4657 for (i
= 0; i
< sizeof (score_insns
) / sizeof (struct asm_opcode
); i
++)
4659 const struct asm_opcode
*insn
= score_insns
+ i
;
4660 unsigned len
= strlen (insn
->template);
4661 struct asm_opcode
*new;
4663 new = obstack_alloc (&insn_obstack
, sizeof (struct asm_opcode
));
4664 template = obstack_alloc (&insn_obstack
, len
+ 1);
4666 strcpy (template, insn
->template);
4667 new->template = template;
4668 new->parms
= insn
->parms
;
4669 new->value
= insn
->value
;
4670 new->relax_value
= insn
->relax_value
;
4671 new->type
= insn
->type
;
4672 new->bitmask
= insn
->bitmask
;
4673 hash_insert (score_ops_hsh
, new->template, (void *) new);
4678 build_dependency_insn_hsh (void)
4681 static struct obstack dependency_obstack
;
4683 obstack_begin (&dependency_obstack
, 4000);
4684 for (i
= 0; i
< sizeof (insn_to_dependency_table
) / sizeof (insn_to_dependency_table
[0]); i
++)
4686 const struct insn_to_dependency
*tmp
= insn_to_dependency_table
+ i
;
4687 unsigned len
= strlen (tmp
->insn_name
);
4688 struct insn_to_dependency
*new;
4690 new = obstack_alloc (&dependency_obstack
, sizeof (struct insn_to_dependency
));
4691 new->insn_name
= obstack_alloc (&dependency_obstack
, len
+ 1);
4693 strcpy (new->insn_name
, tmp
->insn_name
);
4694 new->type
= tmp
->type
;
4695 hash_insert (dependency_insn_hsh
, new->insn_name
, (void *) new);
4699 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
4700 for use in the a.out file, and stores them in the array pointed to by buf.
4701 This knows about the endian-ness of the target machine and does
4702 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
4703 2 (short) and 4 (long) Floating numbers are put out as a series of
4704 LITTLENUMS (shorts, here at least). */
4707 md_number_to_chars (char *buf
, valueT val
, int n
)
4709 if (target_big_endian
)
4710 number_to_chars_bigendian (buf
, val
, n
);
4712 number_to_chars_littleendian (buf
, val
, n
);
4716 md_chars_to_number (char *buf
, int n
)
4719 unsigned char *where
= (unsigned char *)buf
;
4721 if (target_big_endian
)
4726 result
|= (*where
++ & 255);
4734 result
|= (where
[n
] & 255);
4741 /* Turn a string in input_line_pointer into a floating point constant
4742 of type TYPE, and store the appropriate bytes in *LITP. The number
4743 of LITTLENUMS emitted is stored in *SIZEP. An error message is
4744 returned, or NULL on OK.
4746 Note that fp constants aren't represent in the normal way on the ARM.
4747 In big endian mode, things are as expected. However, in little endian
4748 mode fp constants are big-endian word-wise, and little-endian byte-wise
4749 within the words. For example, (double) 1.1 in big endian mode is
4750 the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
4751 the byte sequence 99 99 f1 3f 9a 99 99 99. */
4754 md_atof (int type
, char *litP
, int *sizeP
)
4757 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
4783 return _("bad call to MD_ATOF()");
4786 t
= atof_ieee (input_line_pointer
, type
, words
);
4788 input_line_pointer
= t
;
4791 if (target_big_endian
)
4793 for (i
= 0; i
< prec
; i
++)
4795 md_number_to_chars (litP
, (valueT
) words
[i
], 2);
4801 for (i
= 0; i
< prec
; i
+= 2)
4803 md_number_to_chars (litP
, (valueT
) words
[i
+ 1], 2);
4804 md_number_to_chars (litP
+ 2, (valueT
) words
[i
], 2);
4812 /* Return true if the given symbol should be considered local for PIC. */
4815 pic_need_relax (symbolS
*sym
, asection
*segtype
)
4818 bfd_boolean linkonce
;
4820 /* Handle the case of a symbol equated to another symbol. */
4821 while (symbol_equated_reloc_p (sym
))
4825 /* It's possible to get a loop here in a badly written
4827 n
= symbol_get_value_expression (sym
)->X_add_symbol
;
4833 symsec
= S_GET_SEGMENT (sym
);
4835 /* duplicate the test for LINK_ONCE sections as in adjust_reloc_syms */
4837 if (symsec
!= segtype
&& ! S_IS_LOCAL (sym
))
4839 if ((bfd_get_section_flags (stdoutput
, symsec
) & SEC_LINK_ONCE
) != 0)
4842 /* The GNU toolchain uses an extension for ELF: a section
4843 beginning with the magic string .gnu.linkonce is a linkonce
4845 if (strncmp (segment_name (symsec
), ".gnu.linkonce",
4846 sizeof ".gnu.linkonce" - 1) == 0)
4850 /* This must duplicate the test in adjust_reloc_syms. */
4851 return (symsec
!= &bfd_und_section
4852 && symsec
!= &bfd_abs_section
4853 && ! bfd_is_com_section (symsec
)
4856 /* A global or weak symbol is treated as external. */
4857 && (OUTPUT_FLAVOR
!= bfd_target_elf_flavour
4858 || (! S_IS_WEAK (sym
) && ! S_IS_EXTERNAL (sym
)))
4864 judge_size_before_relax (fragS
* fragp
, asection
*sec
)
4868 if (score_pic
== NO_PIC
)
4869 change
= nopic_need_relax (fragp
->fr_symbol
, 0);
4871 change
= pic_need_relax (fragp
->fr_symbol
, sec
);
4875 /* Only at the first time determining whether GP instruction relax should be done,
4876 return the difference between insntruction size and instruction relax size. */
4877 if (fragp
->fr_opcode
== NULL
)
4879 fragp
->fr_fix
= RELAX_NEW (fragp
->fr_subtype
);
4880 fragp
->fr_opcode
= fragp
->fr_literal
+ RELAX_RELOC1 (fragp
->fr_subtype
);
4881 return RELAX_NEW (fragp
->fr_subtype
) - RELAX_OLD (fragp
->fr_subtype
);
4888 /* In this function, we determine whether GP instruction should do relaxation,
4889 for the label being against was known now.
4890 Doing this here but not in md_relax_frag() can induce iteration times
4891 in stage of doing relax. */
4893 md_estimate_size_before_relax (fragS
* fragp
, asection
* sec ATTRIBUTE_UNUSED
)
4895 if ((RELAX_TYPE (fragp
->fr_subtype
) == Insn_GP
)
4896 || (RELAX_TYPE (fragp
->fr_subtype
) == Insn_PIC
))
4897 return judge_size_before_relax (fragp
, sec
);
4903 b32_relax_to_b16 (fragS
* fragp
)
4906 int relaxable_p
= 0;
4909 int frag_addr
= fragp
->fr_address
+ fragp
->insn_addr
;
4911 addressT symbol_address
= 0;
4914 unsigned long value
;
4915 unsigned long abs_value
;
4917 /* FIXME : here may be able to modify better .
4918 I don't know how to get the fragp's section ,
4919 so in relax stage , it may be wrong to calculate the symbol's offset when the frag's section
4920 is different from the symbol's. */
4922 old
= RELAX_OLD (fragp
->fr_subtype
);
4923 new = RELAX_NEW (fragp
->fr_subtype
);
4924 relaxable_p
= RELAX_OPT (fragp
->fr_subtype
);
4926 s
= fragp
->fr_symbol
;
4927 /* b/bl immediate */
4933 symbol_address
= (addressT
) s
->sy_frag
->fr_address
;
4936 value
= md_chars_to_number (fragp
->fr_literal
, INSN_SIZE
);
4938 /* b 32's offset : 20 bit, b 16's tolerate field : 0xff. */
4939 offset
= ((value
& 0x3ff0000) >> 6) | (value
& 0x3fe);
4940 if ((offset
& 0x80000) == 0x80000)
4941 offset
|= 0xfff00000;
4943 abs_value
= offset
+ symbol_address
- frag_addr
;
4944 if ((abs_value
& 0x80000000) == 0x80000000)
4945 abs_value
= 0xffffffff - abs_value
+ 1;
4947 /* Relax branch 32 to branch 16. */
4948 if (relaxable_p
&& (s
->bsym
!= NULL
) && ((abs_value
& 0xffffff00) == 0)
4949 && (S_IS_DEFINED (s
) && !S_IS_COMMON (s
) && !S_IS_EXTERNAL (s
)))
4955 /* Branch 32 can not be relaxed to b 16, so clear OPT bit. */
4956 fragp
->fr_opcode
= NULL
;
4957 fragp
->fr_subtype
= RELAX_OPT_CLEAR (fragp
->fr_subtype
);
4963 /* Main purpose is to determine whether one frag should do relax.
4964 frag->fr_opcode indicates this point. */
4967 score_relax_frag (asection
* sec ATTRIBUTE_UNUSED
, fragS
* fragp
, long stretch ATTRIBUTE_UNUSED
)
4971 int insn_relax_size
;
4972 int do_relax_p
= 0; /* Indicate doing relaxation for this frag. */
4973 int relaxable_p
= 0;
4974 bfd_boolean word_align_p
= FALSE
;
4977 /* If the instruction address is odd, make it half word align first. */
4978 if ((fragp
->fr_address
) % 2 != 0)
4980 if ((fragp
->fr_address
+ fragp
->insn_addr
) % 2 != 0)
4982 fragp
->insn_addr
= 1;
4987 word_align_p
= ((fragp
->fr_address
+ fragp
->insn_addr
) % 4 == 0) ? TRUE
: FALSE
;
4989 /* Get instruction size and relax size after the last relaxation. */
4990 if (fragp
->fr_opcode
)
4992 insn_size
= RELAX_NEW (fragp
->fr_subtype
);
4993 insn_relax_size
= RELAX_OLD (fragp
->fr_subtype
);
4997 insn_size
= RELAX_OLD (fragp
->fr_subtype
);
4998 insn_relax_size
= RELAX_NEW (fragp
->fr_subtype
);
5001 /* Handle specially for GP instruction. for, judge_size_before_relax() has already determine
5002 whether the GP instruction should do relax. */
5003 if ((RELAX_TYPE (fragp
->fr_subtype
) == Insn_GP
)
5004 || (RELAX_TYPE (fragp
->fr_subtype
) == Insn_PIC
))
5008 fragp
->insn_addr
+= 2;
5012 if (fragp
->fr_opcode
)
5013 fragp
->fr_fix
= RELAX_NEW (fragp
->fr_subtype
) + fragp
->insn_addr
;
5015 fragp
->fr_fix
= RELAX_OLD (fragp
->fr_subtype
) + fragp
->insn_addr
;
5019 if (RELAX_TYPE (fragp
->fr_subtype
) == PC_DISP19div2
)
5020 b32_relax_to_b16 (fragp
);
5022 relaxable_p
= RELAX_OPT (fragp
->fr_subtype
);
5023 next_fragp
= fragp
->fr_next
;
5024 while ((next_fragp
) && (next_fragp
->fr_type
!= rs_machine_dependent
))
5026 next_fragp
= next_fragp
->fr_next
;
5032 int n_relaxable_p
= 0;
5034 if (next_fragp
->fr_opcode
)
5036 n_insn_size
= RELAX_NEW (next_fragp
->fr_subtype
);
5040 n_insn_size
= RELAX_OLD (next_fragp
->fr_subtype
);
5043 n_relaxable_p
= RELAX_OPT (next_fragp
->fr_subtype
);
5050 if (relaxable_p
&& ((n_insn_size
== 2) || n_relaxable_p
))
5056 else if (insn_size
== 2)
5059 if (relaxable_p
&& ((n_insn_size
== 4) && !n_relaxable_p
))
5080 /* Make the 32 bit insturction word align. */
5083 fragp
->insn_addr
+= 2;
5087 else if (insn_size
== 2)
5099 /* Here, try best to do relax regardless fragp->fr_next->fr_type. */
5100 if (word_align_p
== FALSE
)
5102 if (insn_size
% 4 == 0)
5112 fragp
->insn_addr
+= 2;
5123 /* fragp->fr_opcode indicates whether this frag should be relaxed. */
5126 if (fragp
->fr_opcode
)
5128 fragp
->fr_opcode
= NULL
;
5129 /* Guarantee estimate stage is correct. */
5130 fragp
->fr_fix
= RELAX_OLD (fragp
->fr_subtype
);
5131 fragp
->fr_fix
+= fragp
->insn_addr
;
5135 fragp
->fr_opcode
= fragp
->fr_literal
+ RELAX_RELOC1 (fragp
->fr_subtype
);
5136 /* Guarantee estimate stage is correct. */
5137 fragp
->fr_fix
= RELAX_NEW (fragp
->fr_subtype
);
5138 fragp
->fr_fix
+= fragp
->insn_addr
;
5143 if (fragp
->fr_opcode
)
5145 /* Guarantee estimate stage is correct. */
5146 fragp
->fr_fix
= RELAX_NEW (fragp
->fr_subtype
);
5147 fragp
->fr_fix
+= fragp
->insn_addr
;
5151 /* Guarantee estimate stage is correct. */
5152 fragp
->fr_fix
= RELAX_OLD (fragp
->fr_subtype
);
5153 fragp
->fr_fix
+= fragp
->insn_addr
;
5162 md_convert_frag (bfd
* abfd ATTRIBUTE_UNUSED
, segT sec ATTRIBUTE_UNUSED
, fragS
* fragp
)
5169 old
= RELAX_OLD (fragp
->fr_subtype
);
5170 new = RELAX_NEW (fragp
->fr_subtype
);
5172 /* fragp->fr_opcode indicates whether this frag should be relaxed. */
5173 if (fragp
->fr_opcode
== NULL
)
5175 memcpy (backup
, fragp
->fr_literal
, old
);
5176 fragp
->fr_fix
= old
;
5180 memcpy (backup
, fragp
->fr_literal
+ old
, new);
5181 fragp
->fr_fix
= new;
5184 fixp
= fragp
->tc_frag_data
.fixp
;
5185 while (fixp
&& fixp
->fx_frag
== fragp
&& fixp
->fx_where
< old
)
5187 if (fragp
->fr_opcode
)
5189 fixp
= fixp
->fx_next
;
5191 while (fixp
&& fixp
->fx_frag
== fragp
)
5193 if (fragp
->fr_opcode
)
5194 fixp
->fx_where
-= old
+ fragp
->insn_addr
;
5197 fixp
= fixp
->fx_next
;
5200 if (fragp
->insn_addr
)
5202 md_number_to_chars (fragp
->fr_literal
, 0x0, fragp
->insn_addr
);
5204 memcpy (fragp
->fr_literal
+ fragp
->insn_addr
, backup
, fragp
->fr_fix
);
5205 fragp
->fr_fix
+= fragp
->insn_addr
;
5208 /* Implementation of md_frag_check.
5209 Called after md_convert_frag(). */
5212 score_frag_check (fragS
* fragp ATTRIBUTE_UNUSED
)
5214 know (fragp
->insn_addr
<= RELAX_PAD_BYTE
);
5218 score_fix_adjustable (fixS
* fixP
)
5220 if (fixP
->fx_addsy
== NULL
)
5224 else if (OUTPUT_FLAVOR
== bfd_target_elf_flavour
5225 && (S_IS_EXTERNAL (fixP
->fx_addsy
) || S_IS_WEAK (fixP
->fx_addsy
)))
5229 else if (fixP
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
5230 || fixP
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
5238 /* Implementation of TC_VALIDATE_FIX.
5239 Called before md_apply_fix() and after md_convert_frag(). */
5241 score_validate_fix (fixS
*fixP
)
5243 fixP
->fx_where
+= fixP
->fx_frag
->insn_addr
;
5247 md_pcrel_from (fixS
* fixP
)
5252 && (S_GET_SEGMENT (fixP
->fx_addsy
) == undefined_section
)
5253 && (fixP
->fx_subsy
== NULL
))
5259 retval
= fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
5266 score_force_relocation (struct fix
*fixp
)
5270 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
5271 || fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
5272 || fixp
->fx_r_type
== BFD_RELOC_SCORE_JMP
5273 || fixp
->fx_r_type
== BFD_RELOC_SCORE_BRANCH
5274 || fixp
->fx_r_type
== BFD_RELOC_SCORE16_JMP
5275 || fixp
->fx_r_type
== BFD_RELOC_SCORE16_BRANCH
)
5283 /* Round up a section size to the appropriate boundary. */
5285 md_section_align (segT segment ATTRIBUTE_UNUSED
, valueT size
)
5287 int align
= bfd_get_section_alignment (stdoutput
, segment
);
5290 /* We don't need to align ELF sections to the full alignment.
5291 However, Irix 5 may prefer that we align them at least to a 16
5292 byte boundary. We don't bother to align the sections if we are
5293 targeted for an embedded system. */
5294 if (strcmp (TARGET_OS
, "elf") == 0)
5300 return ((size
+ (1 << align
) - 1) & (-1 << align
));
5304 md_apply_fix (fixS
*fixP
, valueT
*valP
, segT seg
)
5306 offsetT value
= *valP
;
5307 offsetT abs_value
= 0;
5310 unsigned short HI
, LO
;
5312 char *buf
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
5314 assert (fixP
->fx_r_type
< BFD_RELOC_UNUSED
);
5315 if (fixP
->fx_addsy
== 0 && !fixP
->fx_pcrel
)
5317 if (fixP
->fx_r_type
!= BFD_RELOC_SCORE_DUMMY_HI16
)
5321 /* If this symbol is in a different section then we need to leave it for
5322 the linker to deal with. Unfortunately, md_pcrel_from can't tell,
5323 so we have to undo it's effects here. */
5326 if (fixP
->fx_addsy
!= NULL
5327 && S_IS_DEFINED (fixP
->fx_addsy
)
5328 && S_GET_SEGMENT (fixP
->fx_addsy
) != seg
)
5329 value
+= md_pcrel_from (fixP
);
5332 /* Remember value for emit_reloc. */
5333 fixP
->fx_addnumber
= value
;
5335 switch (fixP
->fx_r_type
)
5337 case BFD_RELOC_HI16_S
:
5339 { /* For la rd, imm32. */
5340 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5341 HI
= (value
) >> 16; /* mul to 2, then take the hi 16 bit. */
5342 newval
|= (HI
& 0x3fff) << 1;
5343 newval
|= ((HI
>> 14) & 0x3) << 16;
5344 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5347 case BFD_RELOC_LO16
:
5348 if (fixP
->fx_done
) /* For la rd, imm32. */
5350 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5351 LO
= (value
) & 0xffff;
5352 newval
|= (LO
& 0x3fff) << 1; /* 16 bit: imm -> 14 bit in lo, 2 bit in hi. */
5353 newval
|= ((LO
>> 14) & 0x3) << 16;
5354 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5357 case BFD_RELOC_SCORE_JMP
:
5359 content
= md_chars_to_number (buf
, INSN_SIZE
);
5360 value
= fixP
->fx_offset
;
5361 content
= (content
& ~0x3ff7ffe) | ((value
<< 1) & 0x3ff0000) | (value
& 0x7fff);
5362 md_number_to_chars (buf
, content
, INSN_SIZE
);
5365 case BFD_RELOC_SCORE_BRANCH
:
5366 if ((S_GET_SEGMENT (fixP
->fx_addsy
) != seg
) || (fixP
->fx_addsy
!= NULL
&& S_IS_EXTERNAL (fixP
->fx_addsy
)))
5367 value
= fixP
->fx_offset
;
5371 content
= md_chars_to_number (buf
, INSN_SIZE
);
5372 if ((fixP
->fx_frag
->fr_opcode
!= 0) && ((content
& 0x80008000) != 0x80008000))
5374 if ((value
& 0x80000000) == 0x80000000)
5375 abs_value
= 0xffffffff - value
+ 1;
5376 if ((abs_value
& 0xffffff00) != 0)
5378 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5379 _(" branch relocation truncate (0x%x) [-2^8 ~ 2^8]"), (unsigned int)value
);
5382 content
= md_chars_to_number (buf
, INSN16_SIZE
);
5384 content
= (content
& 0xff00) | ((value
>> 1) & 0xff);
5385 md_number_to_chars (buf
, content
, INSN16_SIZE
);
5386 fixP
->fx_r_type
= BFD_RELOC_SCORE16_BRANCH
;
5391 if ((value
& 0x80000000) == 0x80000000)
5392 abs_value
= 0xffffffff - value
+ 1;
5393 if ((abs_value
& 0xfff80000) != 0)
5395 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5396 _(" branch relocation truncate (0x%x) [-2^19 ~ 2^19]"), (unsigned int)value
);
5399 content
= md_chars_to_number (buf
, INSN_SIZE
);
5400 content
&= 0xfc00fc01;
5401 content
= (content
& 0xfc00fc01) | (value
& 0x3fe) | ((value
<< 6) & 0x3ff0000);
5402 md_number_to_chars (buf
, content
, INSN_SIZE
);
5405 case BFD_RELOC_SCORE16_JMP
:
5406 content
= md_chars_to_number (buf
, INSN16_SIZE
);
5408 value
= fixP
->fx_offset
& 0xfff;
5409 content
= (content
& 0xfc01) | (value
& 0xffe);
5410 md_number_to_chars (buf
, content
, INSN16_SIZE
);
5412 case BFD_RELOC_SCORE16_BRANCH
:
5413 content
= md_chars_to_number (buf
, INSN_SIZE
);
5414 if ((fixP
->fx_frag
->fr_opcode
!= 0) && ((content
& 0x80008000) == 0x80008000))
5416 if ((S_GET_SEGMENT (fixP
->fx_addsy
) != seg
) ||
5417 (fixP
->fx_addsy
!= NULL
&& S_IS_EXTERNAL (fixP
->fx_addsy
)))
5418 value
= fixP
->fx_offset
;
5421 if ((value
& 0x80000000) == 0x80000000)
5422 abs_value
= 0xffffffff - value
+ 1;
5423 if ((abs_value
& 0xfff80000) != 0)
5425 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5426 _(" branch relocation truncate (0x%x) [-2^19 ~ 2^19]"), (unsigned int)value
);
5429 content
= md_chars_to_number (buf
, INSN_SIZE
);
5430 content
= (content
& 0xfc00fc01) | (value
& 0x3fe) | ((value
<< 6) & 0x3ff0000);
5431 md_number_to_chars (buf
, content
, INSN_SIZE
);
5432 fixP
->fx_r_type
= BFD_RELOC_SCORE_BRANCH
;
5438 /* In differnt section. */
5439 if ((S_GET_SEGMENT (fixP
->fx_addsy
) != seg
) ||
5440 (fixP
->fx_addsy
!= NULL
&& S_IS_EXTERNAL (fixP
->fx_addsy
)))
5441 value
= fixP
->fx_offset
;
5445 if ((value
& 0x80000000) == 0x80000000)
5446 abs_value
= 0xffffffff - value
+ 1;
5447 if ((abs_value
& 0xffffff00) != 0)
5449 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5450 _(" branch relocation truncate (0x%x) [-2^8 ~ 2^8]"), (unsigned int)value
);
5453 content
= md_chars_to_number (buf
, INSN16_SIZE
);
5454 content
= (content
& 0xff00) | ((value
>> 1) & 0xff);
5455 md_number_to_chars (buf
, content
, INSN16_SIZE
);
5459 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5460 md_number_to_chars (buf
, value
, 1);
5464 value
= fixP
->fx_offset
;
5465 md_number_to_chars (buf
, value
, 1);
5471 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5472 md_number_to_chars (buf
, value
, 2);
5476 value
= fixP
->fx_offset
;
5477 md_number_to_chars (buf
, value
, 2);
5483 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5484 md_number_to_chars (buf
, value
, 4);
5488 value
= fixP
->fx_offset
;
5489 md_number_to_chars (buf
, value
, 4);
5493 case BFD_RELOC_VTABLE_INHERIT
:
5495 if (fixP
->fx_addsy
&& !S_IS_DEFINED (fixP
->fx_addsy
) && !S_IS_WEAK (fixP
->fx_addsy
))
5496 S_SET_WEAK (fixP
->fx_addsy
);
5498 case BFD_RELOC_VTABLE_ENTRY
:
5501 case BFD_RELOC_SCORE_GPREL15
:
5502 content
= md_chars_to_number (buf
, INSN_SIZE
);
5503 if ((fixP
->fx_frag
->fr_opcode
!= 0) && ((content
& 0xfc1c8000) != 0x94188000))
5504 fixP
->fx_r_type
= BFD_RELOC_NONE
;
5507 case BFD_RELOC_SCORE_GOT15
:
5508 case BFD_RELOC_SCORE_DUMMY_HI16
:
5509 case BFD_RELOC_SCORE_GOT_LO16
:
5510 case BFD_RELOC_SCORE_CALL15
:
5511 case BFD_RELOC_GPREL32
:
5513 case BFD_RELOC_NONE
:
5515 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("bad relocation fixup type (%d)"), fixP
->fx_r_type
);
5519 /* Translate internal representation of relocation info to BFD target format. */
5521 tc_gen_reloc (asection
* section ATTRIBUTE_UNUSED
, fixS
* fixp
)
5523 static arelent
*retval
[MAX_RELOC_EXPANSION
+ 1]; /* MAX_RELOC_EXPANSION equals 2. */
5525 bfd_reloc_code_real_type code
;
5531 reloc
= retval
[0] = xmalloc (sizeof (arelent
));
5534 reloc
->sym_ptr_ptr
= xmalloc (sizeof (asymbol
*));
5535 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
5536 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
5537 reloc
->addend
= fixp
->fx_offset
;
5539 /* If this is a variant frag, we may need to adjust the existing
5540 reloc and generate a new one. */
5541 if (fixp
->fx_frag
->fr_opcode
!= NULL
&& (fixp
->fx_r_type
== BFD_RELOC_SCORE_GPREL15
))
5543 /* Update instruction imm bit. */
5548 buf
= fixp
->fx_frag
->fr_literal
+ fixp
->fx_frag
->insn_addr
;
5549 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5550 off
= fixp
->fx_offset
>> 16;
5551 newval
|= (off
& 0x3fff) << 1;
5552 newval
|= ((off
>> 14) & 0x3) << 16;
5553 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5556 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5557 off
= fixp
->fx_offset
& 0xffff;
5558 newval
|= ((off
& 0x3fff) << 1);
5559 newval
|= (((off
>> 14) & 0x3) << 16);
5560 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5562 retval
[1] = xmalloc (sizeof (arelent
));
5564 retval
[1]->sym_ptr_ptr
= xmalloc (sizeof (asymbol
*));
5565 *retval
[1]->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
5566 retval
[1]->address
= (reloc
->address
+ RELAX_RELOC2 (fixp
->fx_frag
->fr_subtype
));
5572 retval
[1]->addend
= 0;
5573 retval
[1]->howto
= bfd_reloc_type_lookup (stdoutput
, BFD_RELOC_LO16
);
5574 assert (retval
[1]->howto
!= NULL
);
5576 fixp
->fx_r_type
= BFD_RELOC_HI16_S
;
5579 code
= fixp
->fx_r_type
;
5580 switch (fixp
->fx_r_type
)
5585 code
= BFD_RELOC_32_PCREL
;
5588 case BFD_RELOC_HI16_S
:
5589 case BFD_RELOC_LO16
:
5590 case BFD_RELOC_SCORE_JMP
:
5591 case BFD_RELOC_SCORE_BRANCH
:
5592 case BFD_RELOC_SCORE16_JMP
:
5593 case BFD_RELOC_SCORE16_BRANCH
:
5594 case BFD_RELOC_VTABLE_ENTRY
:
5595 case BFD_RELOC_VTABLE_INHERIT
:
5596 case BFD_RELOC_SCORE_GPREL15
:
5597 case BFD_RELOC_SCORE_GOT15
:
5598 case BFD_RELOC_SCORE_DUMMY_HI16
:
5599 case BFD_RELOC_SCORE_GOT_LO16
:
5600 case BFD_RELOC_SCORE_CALL15
:
5601 case BFD_RELOC_GPREL32
:
5602 case BFD_RELOC_NONE
:
5603 code
= fixp
->fx_r_type
;
5606 type
= _("<unknown>");
5607 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5608 _("cannot represent %s relocation in this object file format"), type
);
5612 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
5613 if (reloc
->howto
== NULL
)
5615 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5616 _("cannot represent %s relocation in this object file format1"),
5617 bfd_get_reloc_code_name (code
));
5620 /* HACK: Since arm ELF uses Rel instead of Rela, encode the
5621 vtable entry to be used in the relocation's section offset. */
5622 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
5623 reloc
->address
= fixp
->fx_offset
;
5629 score_elf_final_processing (void)
5631 if (fix_data_dependency
== 1)
5633 elf_elfheader (stdoutput
)->e_flags
|= EF_SCORE_FIXDEP
;
5635 if (score_pic
== PIC
)
5637 elf_elfheader (stdoutput
)->e_flags
|= EF_SCORE_PIC
;
5642 parse_pce_inst (char *insnstr
)
5646 char first
[MAX_LITERAL_POOL_SIZE
];
5647 char second
[MAX_LITERAL_POOL_SIZE
];
5648 struct score_it pec_part_1
;
5650 /* Get first part string of PCE. */
5651 p
= strstr (insnstr
, "||");
5654 sprintf (first
, "%s", insnstr
);
5656 /* Get second part string of PCE. */
5659 sprintf (second
, "%s", p
);
5661 parse_16_32_inst (first
, FALSE
);
5665 memcpy (&pec_part_1
, &inst
, sizeof (inst
));
5667 parse_16_32_inst (second
, FALSE
);
5671 if ( ((pec_part_1
.size
== INSN_SIZE
) && (inst
.size
== INSN_SIZE
))
5672 || ((pec_part_1
.size
== INSN_SIZE
) && (inst
.size
== INSN16_SIZE
))
5673 || ((pec_part_1
.size
== INSN16_SIZE
) && (inst
.size
== INSN_SIZE
)))
5675 inst
.error
= _("pce instruction error (16 bit || 16 bit)'");
5676 sprintf (inst
.str
, "%s", insnstr
);
5681 gen_insn_frag (&pec_part_1
, &inst
);
5685 md_assemble (char *str
)
5688 know (strlen (str
) < MAX_LITERAL_POOL_SIZE
);
5690 memset (&inst
, '\0', sizeof (inst
));
5691 if (INSN_IS_PCE_P (str
))
5692 parse_pce_inst (str
);
5694 parse_16_32_inst (str
, TRUE
);
5697 as_bad ("%s -- `%s'", inst
.error
, inst
.str
);
5700 /* We handle all bad expressions here, so that we can report the faulty
5701 instruction in the error message. */
5703 md_operand (expressionS
* expr
)
5705 if (in_my_get_expression
)
5707 expr
->X_op
= O_illegal
;
5708 if (inst
.error
== NULL
)
5710 inst
.error
= _("bad expression");
5715 const char *md_shortopts
= "nO::g::G:";
5717 #ifdef SCORE_BI_ENDIAN
5718 #define OPTION_EB (OPTION_MD_BASE + 0)
5719 #define OPTION_EL (OPTION_MD_BASE + 1)
5721 #if TARGET_BYTES_BIG_ENDIAN
5722 #define OPTION_EB (OPTION_MD_BASE + 0)
5724 #define OPTION_EL (OPTION_MD_BASE + 1)
5727 #define OPTION_FIXDD (OPTION_MD_BASE + 2)
5728 #define OPTION_NWARN (OPTION_MD_BASE + 3)
5729 #define OPTION_SCORE5 (OPTION_MD_BASE + 4)
5730 #define OPTION_SCORE5U (OPTION_MD_BASE + 5)
5731 #define OPTION_SCORE7 (OPTION_MD_BASE + 6)
5732 #define OPTION_R1 (OPTION_MD_BASE + 7)
5733 #define OPTION_O0 (OPTION_MD_BASE + 8)
5734 #define OPTION_SCORE_VERSION (OPTION_MD_BASE + 9)
5735 #define OPTION_PIC (OPTION_MD_BASE + 10)
5737 struct option md_longopts
[] =
5740 {"EB" , no_argument
, NULL
, OPTION_EB
},
5743 {"EL" , no_argument
, NULL
, OPTION_EL
},
5745 {"FIXDD" , no_argument
, NULL
, OPTION_FIXDD
},
5746 {"NWARN" , no_argument
, NULL
, OPTION_NWARN
},
5747 {"SCORE5" , no_argument
, NULL
, OPTION_SCORE5
},
5748 {"SCORE5U", no_argument
, NULL
, OPTION_SCORE5U
},
5749 {"SCORE7" , no_argument
, NULL
, OPTION_SCORE7
},
5750 {"USE_R1" , no_argument
, NULL
, OPTION_R1
},
5751 {"O0" , no_argument
, NULL
, OPTION_O0
},
5752 {"V" , no_argument
, NULL
, OPTION_SCORE_VERSION
},
5753 {"KPIC" , no_argument
, NULL
, OPTION_PIC
},
5754 {NULL
, no_argument
, NULL
, 0}
5757 size_t md_longopts_size
= sizeof (md_longopts
);
5760 md_parse_option (int c
, char *arg
)
5766 target_big_endian
= 1;
5771 target_big_endian
= 0;
5775 fix_data_dependency
= 1;
5778 warn_fix_data_dependency
= 0;
5782 university_version
= 0;
5783 vector_size
= SCORE5_PIPELINE
;
5785 case OPTION_SCORE5U
:
5787 university_version
= 1;
5788 vector_size
= SCORE5_PIPELINE
;
5792 university_version
= 0;
5793 vector_size
= SCORE7_PIPELINE
;
5799 g_switch_value
= atoi (arg
);
5804 case OPTION_SCORE_VERSION
:
5805 printf (_("Sunplus-v2-0-0-20060510\n"));
5809 g_switch_value
= 0; /* Must set -G num as 0 to generate PIC code. */
5812 /* as_bad (_("unrecognized option `-%c%s'"), c, arg ? arg : ""); */
5819 md_show_usage (FILE * fp
)
5821 fprintf (fp
, _(" Score-specific assembler options:\n"));
5824 -EB\t\tassemble code for a big-endian cpu\n"));
5829 -EL\t\tassemble code for a little-endian cpu\n"));
5833 -FIXDD\t\tassemble code for fix data dependency\n"));
5835 -NWARN\t\tassemble code for no warning message for fix data dependency\n"));
5837 -SCORE5\t\tassemble code for target is SCORE5\n"));
5839 -SCORE5U\tassemble code for target is SCORE5U\n"));
5841 -SCORE7\t\tassemble code for target is SCORE7, this is default setting\n"));
5843 -USE_R1\t\tassemble code for no warning message when using temp register r1\n"));
5845 -KPIC\t\tassemble code for PIC\n"));
5847 -O0\t\tassembler will not perform any optimizations\n"));
5849 -G gpnum\tassemble code for setting gpsize and default is 8 byte\n"));
5851 -V \t\tSunplus release version \n"));
5855 /* Pesudo handling functions. */
5857 /* If we change section we must dump the literal pool first. */
5859 s_score_bss (int ignore ATTRIBUTE_UNUSED
)
5861 subseg_set (bss_section
, (subsegT
) get_absolute_expression ());
5862 demand_empty_rest_of_line ();
5866 s_score_text (int ignore
)
5868 obj_elf_text (ignore
);
5869 record_alignment (now_seg
, 2);
5873 score_s_section (int ignore
)
5875 obj_elf_section (ignore
);
5876 if ((bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
) != 0)
5877 record_alignment (now_seg
, 2);
5882 s_change_sec (int sec
)
5887 /* The ELF backend needs to know that we are changing sections, so
5888 that .previous works correctly. We could do something like check
5889 for an obj_section_change_hook macro, but that might be confusing
5890 as it would not be appropriate to use it in the section changing
5891 functions in read.c, since obj-elf.c intercepts those. FIXME:
5892 This should be cleaner, somehow. */
5893 obj_elf_section_change_hook ();
5898 seg
= subseg_new (RDATA_SECTION_NAME
, (subsegT
) get_absolute_expression ());
5899 bfd_set_section_flags (stdoutput
, seg
, (SEC_ALLOC
| SEC_LOAD
| SEC_READONLY
| SEC_RELOC
| SEC_DATA
));
5900 if (strcmp (TARGET_OS
, "elf") != 0)
5901 record_alignment (seg
, 4);
5902 demand_empty_rest_of_line ();
5905 seg
= subseg_new (".sdata", (subsegT
) get_absolute_expression ());
5906 bfd_set_section_flags (stdoutput
, seg
, SEC_ALLOC
| SEC_LOAD
| SEC_RELOC
| SEC_DATA
);
5907 if (strcmp (TARGET_OS
, "elf") != 0)
5908 record_alignment (seg
, 4);
5909 demand_empty_rest_of_line ();
5915 s_score_mask (int reg_type ATTRIBUTE_UNUSED
)
5919 if (cur_proc_ptr
== (procS
*) NULL
)
5921 as_warn (_(".mask outside of .ent"));
5922 demand_empty_rest_of_line ();
5925 if (get_absolute_expression_and_terminator (&mask
) != ',')
5927 as_warn (_("Bad .mask directive"));
5928 --input_line_pointer
;
5929 demand_empty_rest_of_line ();
5932 off
= get_absolute_expression ();
5933 cur_proc_ptr
->reg_mask
= mask
;
5934 cur_proc_ptr
->reg_offset
= off
;
5935 demand_empty_rest_of_line ();
5945 name
= input_line_pointer
;
5946 c
= get_symbol_end ();
5947 p
= (symbolS
*) symbol_find_or_make (name
);
5948 *input_line_pointer
= c
;
5958 if (*input_line_pointer
== '-')
5960 ++input_line_pointer
;
5963 if (!ISDIGIT (*input_line_pointer
))
5964 as_bad (_("expected simple number"));
5965 if (input_line_pointer
[0] == '0')
5967 if (input_line_pointer
[1] == 'x')
5969 input_line_pointer
+= 2;
5970 while (ISXDIGIT (*input_line_pointer
))
5973 val
|= hex_value (*input_line_pointer
++);
5975 return negative
? -val
: val
;
5979 ++input_line_pointer
;
5980 while (ISDIGIT (*input_line_pointer
))
5983 val
|= *input_line_pointer
++ - '0';
5985 return negative
? -val
: val
;
5988 if (!ISDIGIT (*input_line_pointer
))
5990 printf (_(" *input_line_pointer == '%c' 0x%02x\n"), *input_line_pointer
, *input_line_pointer
);
5991 as_warn (_("invalid number"));
5994 while (ISDIGIT (*input_line_pointer
))
5997 val
+= *input_line_pointer
++ - '0';
5999 return negative
? -val
: val
;
6002 /* The .aent and .ent directives. */
6005 s_score_ent (int aent
)
6010 symbolP
= get_symbol ();
6011 if (*input_line_pointer
== ',')
6012 ++input_line_pointer
;
6014 if (ISDIGIT (*input_line_pointer
) || *input_line_pointer
== '-')
6017 #ifdef BFD_ASSEMBLER
6018 if ((bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
) != 0)
6023 if (now_seg
!= data_section
&& now_seg
!= bss_section
)
6029 as_warn (_(".ent or .aent not in text section."));
6030 if (!aent
&& cur_proc_ptr
)
6031 as_warn (_("missing .end"));
6034 cur_proc_ptr
= &cur_proc
;
6035 cur_proc_ptr
->reg_mask
= 0xdeadbeaf;
6036 cur_proc_ptr
->reg_offset
= 0xdeadbeaf;
6037 cur_proc_ptr
->fpreg_mask
= 0xdeafbeaf;
6038 cur_proc_ptr
->leaf
= 0xdeafbeaf;
6039 cur_proc_ptr
->frame_offset
= 0xdeafbeaf;
6040 cur_proc_ptr
->frame_reg
= 0xdeafbeaf;
6041 cur_proc_ptr
->pc_reg
= 0xdeafbeaf;
6042 cur_proc_ptr
->isym
= symbolP
;
6043 symbol_get_bfdsym (symbolP
)->flags
|= BSF_FUNCTION
;
6045 if (debug_type
== DEBUG_STABS
)
6046 stabs_generate_asm_func (S_GET_NAME (symbolP
), S_GET_NAME (symbolP
));
6048 demand_empty_rest_of_line ();
6052 s_score_frame (int ignore ATTRIBUTE_UNUSED
)
6059 backupstr
= input_line_pointer
;
6062 if (cur_proc_ptr
== (procS
*) NULL
)
6064 as_warn (_(".frame outside of .ent"));
6065 demand_empty_rest_of_line ();
6068 cur_proc_ptr
->frame_reg
= reg_required_here ((&backupstr
), 0, REG_TYPE_SCORE
);
6070 skip_past_comma (&backupstr
);
6071 while (*backupstr
!= ',')
6073 str
[i
] = *backupstr
;
6081 skip_past_comma (&backupstr
);
6082 cur_proc_ptr
->frame_offset
= val
;
6083 cur_proc_ptr
->pc_reg
= reg_required_here ((&backupstr
), 0, REG_TYPE_SCORE
);
6086 skip_past_comma (&backupstr
);
6088 while (*backupstr
!= '\n')
6090 str
[i
] = *backupstr
;
6096 cur_proc_ptr
->leaf
= val
;
6098 skip_past_comma (&backupstr
);
6100 #endif /* OBJ_ELF */
6101 while (input_line_pointer
!= backupstr
)
6102 input_line_pointer
++;
6105 /* The .end directive. */
6107 s_score_end (int x ATTRIBUTE_UNUSED
)
6112 /* Generate a .pdr section. */
6113 segT saved_seg
= now_seg
;
6114 subsegT saved_subseg
= now_subseg
;
6119 if (!is_end_of_line
[(unsigned char)*input_line_pointer
])
6122 demand_empty_rest_of_line ();
6127 #ifdef BFD_ASSEMBLER
6128 if ((bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
) != 0)
6133 if (now_seg
!= data_section
&& now_seg
!= bss_section
)
6140 as_warn (_(".end not in text section"));
6143 as_warn (_(".end directive without a preceding .ent directive."));
6144 demand_empty_rest_of_line ();
6149 assert (S_GET_NAME (p
));
6150 if (strcmp (S_GET_NAME (p
), S_GET_NAME (cur_proc_ptr
->isym
)))
6151 as_warn (_(".end symbol does not match .ent symbol."));
6152 if (debug_type
== DEBUG_STABS
)
6153 stabs_generate_asm_endfunc (S_GET_NAME (p
), S_GET_NAME (p
));
6156 as_warn (_(".end directive missing or unknown symbol"));
6158 if ((cur_proc_ptr
->reg_mask
== 0xdeadbeaf) ||
6159 (cur_proc_ptr
->reg_offset
== 0xdeadbeaf) ||
6160 (cur_proc_ptr
->leaf
== 0xdeafbeaf) ||
6161 (cur_proc_ptr
->frame_offset
== 0xdeafbeaf) ||
6162 (cur_proc_ptr
->frame_reg
== 0xdeafbeaf) || (cur_proc_ptr
->pc_reg
== 0xdeafbeaf));
6166 dot
= frag_now_fix ();
6168 subseg_set (pdr_seg
, 0);
6169 /* Write the symbol. */
6170 exp
.X_op
= O_symbol
;
6171 exp
.X_add_symbol
= p
;
6172 exp
.X_add_number
= 0;
6173 emit_expr (&exp
, 4);
6174 fragp
= frag_more (7 * 4);
6175 md_number_to_chars (fragp
, (valueT
) cur_proc_ptr
->reg_mask
, 4);
6176 md_number_to_chars (fragp
+ 4, (valueT
) cur_proc_ptr
->reg_offset
, 4);
6177 md_number_to_chars (fragp
+ 8, (valueT
) cur_proc_ptr
->fpreg_mask
, 4);
6178 md_number_to_chars (fragp
+ 12, (valueT
) cur_proc_ptr
->leaf
, 4);
6179 md_number_to_chars (fragp
+ 16, (valueT
) cur_proc_ptr
->frame_offset
, 4);
6180 md_number_to_chars (fragp
+ 20, (valueT
) cur_proc_ptr
->frame_reg
, 4);
6181 md_number_to_chars (fragp
+ 24, (valueT
) cur_proc_ptr
->pc_reg
, 4);
6182 subseg_set (saved_seg
, saved_subseg
);
6185 cur_proc_ptr
= NULL
;
6188 /* Handle the .set pseudo-op. */
6190 s_score_set (int x ATTRIBUTE_UNUSED
)
6193 char name
[MAX_LITERAL_POOL_SIZE
];
6194 char * orig_ilp
= input_line_pointer
;
6196 while (!is_end_of_line
[(unsigned char)*input_line_pointer
])
6198 name
[i
] = (char) * input_line_pointer
;
6200 ++input_line_pointer
;
6205 if (strcmp (name
, "nwarn") == 0)
6207 warn_fix_data_dependency
= 0;
6209 else if (strcmp (name
, "fixdd") == 0)
6211 fix_data_dependency
= 1;
6213 else if (strcmp (name
, "nofixdd") == 0)
6215 fix_data_dependency
= 0;
6217 else if (strcmp (name
, "r1") == 0)
6221 else if (strcmp (name
, "nor1") == 0)
6225 else if (strcmp (name
, "optimize") == 0)
6229 else if (strcmp (name
, "volatile") == 0)
6233 else if (strcmp (name
, "pic") == 0)
6239 input_line_pointer
= orig_ilp
;
6244 /* Handle the .cpload pseudo-op. This is used when generating PIC code. It sets the
6245 $gp register for the function based on the function address, which is in the register
6246 named in the argument. This uses a relocation against GP_DISP_LABEL, which is handled
6247 specially by the linker. The result is:
6248 ldis gp, %hi(GP_DISP_LABEL)
6249 ori gp, %low(GP_DISP_LABEL)
6250 add gp, gp, .cpload argument
6251 The .cpload argument is normally r29. */
6254 s_score_cpload (int ignore ATTRIBUTE_UNUSED
)
6257 char insn_str
[MAX_LITERAL_POOL_SIZE
];
6259 /* If we are not generating PIC code, .cpload is ignored. */
6260 if (score_pic
== NO_PIC
)
6266 if ((reg
= reg_required_here (&input_line_pointer
, -1, REG_TYPE_SCORE
)) == (int) FAIL
)
6269 demand_empty_rest_of_line ();
6271 sprintf (insn_str
, "ld_i32hi r%d, %s", GP
, GP_DISP_LABEL
);
6272 if (append_insn (insn_str
, TRUE
) == (int) FAIL
)
6275 sprintf (insn_str
, "ld_i32lo r%d, %s", GP
, GP_DISP_LABEL
);
6276 if (append_insn (insn_str
, TRUE
) == (int) FAIL
)
6279 sprintf (insn_str
, "add r%d, r%d, r%d", GP
, GP
, reg
);
6280 if (append_insn (insn_str
, TRUE
) == (int) FAIL
)
6284 /* Handle the .cprestore pseudo-op. This stores $gp into a given
6285 offset from $sp. The offset is remembered, and after making a PIC
6286 call $gp is restored from that location. */
6289 s_score_cprestore (int ignore ATTRIBUTE_UNUSED
)
6291 #define SCORE_BP_REG 2
6292 int cprestore_offset
;
6293 char insn_str
[MAX_LITERAL_POOL_SIZE
];
6295 /* If we are not generating PIC code, .cprestore is ignored. */
6296 if (score_pic
== NO_PIC
)
6302 cprestore_offset
= get_absolute_expression ();
6304 sprintf (insn_str
, "sw r%d, [r%d, %d]", GP
, SCORE_BP_REG
, cprestore_offset
);
6305 if (append_insn (insn_str
, TRUE
) == (int) FAIL
)
6309 /* Handle the .gpword pseudo-op. This is used when generating PIC
6310 code. It generates a 32 bit GP relative reloc. */
6312 s_score_gpword (int ignore ATTRIBUTE_UNUSED
)
6317 /* When not generating PIC code, this is treated as .word. */
6318 if (score_pic
== NO_PIC
)
6324 if (ex
.X_op
!= O_symbol
|| ex
.X_add_number
!= 0)
6326 as_bad (_("Unsupported use of .gpword"));
6327 ignore_rest_of_line ();
6330 md_number_to_chars (p
, (valueT
) 0, 4);
6331 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 4, &ex
, FALSE
, BFD_RELOC_GPREL32
);
6332 demand_empty_rest_of_line ();
6335 /* Handle the .cpadd pseudo-op. This is used when dealing with switch
6336 tables in PIC code. */
6339 s_score_cpadd (int ignore ATTRIBUTE_UNUSED
)
6342 char insn_str
[MAX_LITERAL_POOL_SIZE
];
6344 /* If we are not generating PIC code, .cpload is ignored. */
6345 if (score_pic
== NO_PIC
)
6351 if ((reg
= reg_required_here (&input_line_pointer
, -1, REG_TYPE_SCORE
)) == (int) FAIL
)
6355 demand_empty_rest_of_line ();
6357 /* Add $gp to the register named as an argument. */
6358 sprintf (insn_str
, "add r%d, r%d, r%d", reg
, reg
, GP
);
6359 if (append_insn (insn_str
, TRUE
) == (int) FAIL
)
6363 #ifndef TC_IMPLICIT_LCOMM_ALIGNMENT
6364 #define TC_IMPLICIT_LCOMM_ALIGNMENT(SIZE, P2VAR) \
6369 else if ((SIZE) >= 4) \
6371 else if ((SIZE) >= 2) \
6380 s_score_lcomm (int bytes_p
)
6387 segT current_seg
= now_seg
;
6388 subsegT current_subseg
= now_subseg
;
6389 const int max_alignment
= 15;
6391 segT bss_seg
= bss_section
;
6392 int needs_align
= 0;
6394 name
= input_line_pointer
;
6395 c
= get_symbol_end ();
6396 p
= input_line_pointer
;
6401 as_bad (_("expected symbol name"));
6402 discard_rest_of_line ();
6408 /* Accept an optional comma after the name. The comma used to be
6409 required, but Irix 5 cc does not generate it. */
6410 if (*input_line_pointer
== ',')
6412 ++input_line_pointer
;
6416 if (is_end_of_line
[(unsigned char)*input_line_pointer
])
6418 as_bad (_("missing size expression"));
6422 if ((temp
= get_absolute_expression ()) < 0)
6424 as_warn (_("BSS length (%d) < 0 ignored"), temp
);
6425 ignore_rest_of_line ();
6429 #if defined (TC_SCORE)
6430 if (OUTPUT_FLAVOR
== bfd_target_ecoff_flavour
|| OUTPUT_FLAVOR
== bfd_target_elf_flavour
)
6432 /* For Score and Alpha ECOFF or ELF, small objects are put in .sbss. */
6433 if ((unsigned)temp
<= bfd_get_gp_size (stdoutput
))
6435 bss_seg
= subseg_new (".sbss", 1);
6436 seg_info (bss_seg
)->bss
= 1;
6437 #ifdef BFD_ASSEMBLER
6438 if (!bfd_set_section_flags (stdoutput
, bss_seg
, SEC_ALLOC
))
6439 as_warn (_("error setting flags for \".sbss\": %s"), bfd_errmsg (bfd_get_error ()));
6446 if (*input_line_pointer
== ',')
6448 ++input_line_pointer
;
6451 if (is_end_of_line
[(unsigned char)*input_line_pointer
])
6453 as_bad (_("missing alignment"));
6458 align
= get_absolute_expression ();
6465 TC_IMPLICIT_LCOMM_ALIGNMENT (temp
, align
);
6467 /* Still zero unless TC_IMPLICIT_LCOMM_ALIGNMENT set it. */
6469 record_alignment (bss_seg
, align
);
6476 /* Convert to a power of 2. */
6481 for (i
= 0; align
!= 0; align
>>= 1, ++i
)
6487 if (align
> max_alignment
)
6489 align
= max_alignment
;
6490 as_warn (_("alignment too large; %d assumed"), align
);
6495 as_warn (_("alignment negative; 0 assumed"));
6498 record_alignment (bss_seg
, align
);
6502 /* Assume some objects may require alignment on some systems. */
6503 #if defined (TC_ALPHA) && ! defined (VMS)
6506 align
= ffs (temp
) - 1;
6507 if (temp
% (1 << align
))
6514 symbolP
= symbol_find_or_make (name
);
6518 #if (defined (OBJ_AOUT) || defined (OBJ_MAYBE_AOUT) \
6519 || defined (OBJ_BOUT) || defined (OBJ_MAYBE_BOUT))
6520 #ifdef BFD_ASSEMBLER
6521 (OUTPUT_FLAVOR
!= bfd_target_aout_flavour
6522 || (S_GET_OTHER (symbolP
) == 0 && S_GET_DESC (symbolP
) == 0)) &&
6524 (S_GET_OTHER (symbolP
) == 0 && S_GET_DESC (symbolP
) == 0) &&
6527 (S_GET_SEGMENT (symbolP
) == bss_seg
|| (!S_IS_DEFINED (symbolP
) && S_GET_VALUE (symbolP
) == 0)))
6531 subseg_set (bss_seg
, 1);
6534 frag_align (align
, 0, 0);
6536 /* Detach from old frag. */
6537 if (S_GET_SEGMENT (symbolP
) == bss_seg
)
6538 symbol_get_frag (symbolP
)->fr_symbol
= NULL
;
6540 symbol_set_frag (symbolP
, frag_now
);
6541 pfrag
= frag_var (rs_org
, 1, 1, (relax_substateT
) 0, symbolP
, (offsetT
) temp
, NULL
);
6545 S_SET_SEGMENT (symbolP
, bss_seg
);
6548 /* The symbol may already have been created with a preceding
6549 ".globl" directive -- be careful not to step on storage class
6550 in that case. Otherwise, set it to static. */
6551 if (S_GET_STORAGE_CLASS (symbolP
) != C_EXT
)
6553 S_SET_STORAGE_CLASS (symbolP
, C_STAT
);
6555 #endif /* OBJ_COFF */
6558 S_SET_SIZE (symbolP
, temp
);
6562 as_bad (_("symbol `%s' is already defined"), S_GET_NAME (symbolP
));
6564 subseg_set (current_seg
, current_subseg
);
6566 demand_empty_rest_of_line ();
6570 insert_reg (const struct reg_entry
*r
, struct hash_control
*htab
)
6573 int len
= strlen (r
->name
) + 2;
6574 char *buf
= xmalloc (len
);
6575 char *buf2
= xmalloc (len
);
6577 strcpy (buf
+ i
, r
->name
);
6578 for (i
= 0; buf
[i
]; i
++)
6580 buf2
[i
] = TOUPPER (buf
[i
]);
6584 hash_insert (htab
, buf
, (void *) r
);
6585 hash_insert (htab
, buf2
, (void *) r
);
6589 build_reg_hsh (struct reg_map
*map
)
6591 const struct reg_entry
*r
;
6593 if ((map
->htab
= hash_new ()) == NULL
)
6595 as_fatal (_("virtual memory exhausted"));
6597 for (r
= map
->names
; r
->name
!= NULL
; r
++)
6599 insert_reg (r
, map
->htab
);
6610 if ((score_ops_hsh
= hash_new ()) == NULL
)
6611 as_fatal (_("virtual memory exhausted"));
6613 build_score_ops_hsh ();
6615 if ((dependency_insn_hsh
= hash_new ()) == NULL
)
6616 as_fatal (_("virtual memory exhausted"));
6618 build_dependency_insn_hsh ();
6620 for (i
= (int)REG_TYPE_FIRST
; i
< (int)REG_TYPE_MAX
; i
++)
6621 build_reg_hsh (all_reg_maps
+ i
);
6623 /* Initialize dependency vector. */
6624 init_dependency_vector ();
6626 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
, 0);
6628 subseg
= now_subseg
;
6629 pdr_seg
= subseg_new (".pdr", (subsegT
) 0);
6630 (void)bfd_set_section_flags (stdoutput
, pdr_seg
, SEC_READONLY
| SEC_RELOC
| SEC_DEBUGGING
);
6631 (void)bfd_set_section_alignment (stdoutput
, pdr_seg
, 2);
6632 subseg_set (seg
, subseg
);
6634 if (USE_GLOBAL_POINTER_OPT
)
6635 bfd_set_gp_size (stdoutput
, g_switch_value
);
6639 const pseudo_typeS md_pseudo_table
[] =
6641 {"bss", s_score_bss
, 0},
6642 {"text", s_score_text
, 0},
6645 {"extend", float_cons
, 'x'},
6646 {"ldouble", float_cons
, 'x'},
6647 {"packed", float_cons
, 'p'},
6648 {"end", s_score_end
, 0},
6649 {"ent", s_score_ent
, 0},
6650 {"frame", s_score_frame
, 0},
6651 {"rdata", s_change_sec
, 'r'},
6652 {"sdata", s_change_sec
, 's'},
6653 {"set", s_score_set
, 0},
6654 {"mask", s_score_mask
, 'R'},
6656 {"lcomm", s_score_lcomm
, 1},
6657 {"section", score_s_section
, 0},
6658 {"cpload", s_score_cpload
, 0},
6659 {"cprestore", s_score_cprestore
, 0},
6660 {"gpword", s_score_gpword
, 0},
6661 {"cpadd", s_score_cpadd
, 0},