1 /* tc-score.c -- Assembler for Score
2 Copyright 2006 Free Software Foundation, Inc.
4 Mei Ligang (ligang@sunnorth.com.cn)
5 Pei-Lin Tsai (pltsai@sunplus.com)
7 This file is part of GAS, the GNU Assembler.
9 GAS is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2, or (at your option)
14 GAS is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with GAS; see the file COPYING. If not, write to the Free
21 Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
27 #include "safe-ctype.h"
28 #include "opcode/score-inst.h"
29 #include "opcode/score-datadep.h"
30 #include "struc-symbol.h"
33 #include "elf/score.h"
34 #include "dwarf2dbg.h"
38 #define PIC_CALL_REG 29
39 #define MAX_LITERAL_POOL_SIZE 1024
40 #define FAIL 0x80000000
44 #define RELAX_INST_NUM 3
46 /* For score5u : div/mul will pop warning message, mmu/alw/asw will pop error message. */
47 #define BAD_ARGS _("bad arguments to instruction")
48 #define BAD_PC _("r15 not allowed here")
49 #define BAD_COND _("instruction is not conditional")
50 #define ERR_NO_ACCUM _("acc0 expected")
51 #define ERR_FOR_SCORE5U_MUL_DIV _("div / mul are reserved instructions")
52 #define ERR_FOR_SCORE5U_MMU _("This architecture doesn't support mmu")
53 #define ERR_FOR_SCORE5U_ATOMIC _("This architecture doesn't support atomic instruction")
54 #define LONG_LABEL_LEN _("the label length is longer than 1024");
55 #define BAD_SKIP_COMMA BAD_ARGS
56 #define BAD_GARBAGE _("garbage following instruction");
58 #define skip_whitespace(str) while (*(str) == ' ') ++(str)
60 /* The name of the readonly data section. */
61 #define RDATA_SECTION_NAME (OUTPUT_FLAVOR == bfd_target_aout_flavour \
63 : OUTPUT_FLAVOR == bfd_target_ecoff_flavour \
65 : OUTPUT_FLAVOR == bfd_target_coff_flavour \
67 : OUTPUT_FLAVOR == bfd_target_elf_flavour \
71 #define RELAX_ENCODE(old, new, type, reloc1, reloc2, opt) \
80 #define RELAX_OLD(i) (((i) >> 23) & 0x7f)
81 #define RELAX_NEW(i) (((i) >> 16) & 0x7f)
82 #define RELAX_TYPE(i) (((i) >> 9) & 0x7f)
83 #define RELAX_RELOC1(i) ((valueT) ((i) >> 5) & 0xf)
84 #define RELAX_RELOC2(i) ((valueT) ((i) >> 1) & 0xf)
85 #define RELAX_OPT(i) ((i) & 1)
86 #define RELAX_OPT_CLEAR(i) ((i) & ~1)
88 #define SET_INSN_ERROR(s) (inst.error = (s))
89 #define INSN_IS_PCE_P(s) (strstr (str, "||") != NULL)
91 #define GET_INSN_CLASS(type) (get_insn_class_from_type (type))
93 #define GET_INSN_SIZE(type) ((GET_INSN_CLASS (type) == INSN_CLASS_16) \
94 ? INSN16_SIZE : INSN_SIZE)
96 /* This array holds the chars that always start a comment. If the
97 pre-processor is disabled, these aren't very useful. */
98 const char comment_chars
[] = "#";
99 const char line_comment_chars
[] = "#";
100 const char line_separator_chars
[] = ";";
102 /* Chars that can be used to separate mant from exp in floating point numbers. */
103 const char EXP_CHARS
[] = "eE";
104 const char FLT_CHARS
[] = "rRsSfFdDxXeEpP";
106 fragS
*score_fragp
= 0;
107 static int fix_data_dependency
= 0;
108 static int warn_fix_data_dependency
= 1;
109 static int score7
= 1;
110 static int university_version
= 0;
112 static int in_my_get_expression
= 0;
114 #define USE_GLOBAL_POINTER_OPT 1
115 #define SCORE_BI_ENDIAN
117 /* Default, pop warning message when using r1. */
120 /* Default will do instruction relax, -O0 will set g_opt = 0. */
121 static unsigned int g_opt
= 1;
123 /* The size of the small data section. */
124 static unsigned int g_switch_value
= 8;
127 /* Pre-defined "_GLOBAL_OFFSET_TABLE_" */
132 enum score_pic_level score_pic
= NO_PIC
;
134 #define INSN_NAME_LEN 16
137 char name
[INSN_NAME_LEN
];
138 unsigned long instruction
;
139 unsigned long relax_inst
;
142 enum score_insn_type type
;
143 char str
[MAX_LITERAL_POOL_SIZE
];
146 char reg
[INSN_NAME_LEN
];
149 bfd_reloc_code_real_type type
;
154 struct score_it inst
;
159 unsigned long reg_mask
;
160 unsigned long reg_offset
;
161 unsigned long fpreg_mask
;
163 unsigned long frame_offset
;
164 unsigned long frame_reg
;
165 unsigned long pc_reg
;
169 static procS cur_proc
;
170 static procS
*cur_proc_ptr
;
173 #define SCORE7_PIPELINE 7
174 #define SCORE5_PIPELINE 5
175 static int vector_size
= SCORE7_PIPELINE
;
176 struct score_it dependency_vector
[SCORE7_PIPELINE
];
178 /* Relax will need some padding for alignment. */
179 #define RELAX_PAD_BYTE 3
181 /* Number of littlenums required to hold an extended precision number. For md_atof. */
182 #define NUM_FLOAT_VALS 8
183 #define MAX_LITTLENUMS 6
184 LITTLENUM_TYPE fp_values
[NUM_FLOAT_VALS
][MAX_LITTLENUMS
];
186 /* Structure for a hash table entry for a register. */
193 static const struct reg_entry score_rn_table
[] =
195 {"r0", 0}, {"r1", 1}, {"r2", 2}, {"r3", 3},
196 {"r4", 4}, {"r5", 5}, {"r6", 6}, {"r7", 7},
197 {"r8", 8}, {"r9", 9}, {"r10", 10}, {"r11", 11},
198 {"r12", 12}, {"r13", 13}, {"r14", 14}, {"r15", 15},
199 {"r16", 16}, {"r17", 17}, {"r18", 18}, {"r19", 19},
200 {"r20", 20}, {"r21", 21}, {"r22", 22}, {"r23", 23},
201 {"r24", 24}, {"r25", 25}, {"r26", 26}, {"r27", 27},
202 {"r28", 28}, {"r29", 29}, {"r30", 30}, {"r31", 31},
206 static const struct reg_entry score_srn_table
[] =
208 {"sr0", 0}, {"sr1", 1}, {"sr2", 2},
212 static const struct reg_entry score_crn_table
[] =
214 {"cr0", 0}, {"cr1", 1}, {"cr2", 2}, {"cr3", 3},
215 {"cr4", 4}, {"cr5", 5}, {"cr6", 6}, {"cr7", 7},
216 {"cr8", 8}, {"cr9", 9}, {"cr10", 10}, {"cr11", 11},
217 {"cr12", 12}, {"cr13", 13}, {"cr14", 14}, {"cr15", 15},
218 {"cr16", 16}, {"cr17", 17}, {"cr18", 18}, {"cr19", 19},
219 {"cr20", 20}, {"cr21", 21}, {"cr22", 22}, {"cr23", 23},
220 {"cr24", 24}, {"cr25", 25}, {"cr26", 26}, {"cr27", 27},
221 {"cr28", 28}, {"cr29", 29}, {"cr30", 30}, {"cr31", 31},
227 const struct reg_entry
*names
;
229 struct hash_control
*htab
;
230 const char *expected
;
233 struct reg_map all_reg_maps
[] =
235 {score_rn_table
, 31, NULL
, N_("S+core register expected")},
236 {score_srn_table
, 2, NULL
, N_("S+core special-register expected")},
237 {score_crn_table
, 31, NULL
, N_("S+core co-processor register expected")},
240 static struct hash_control
*score_ops_hsh
= NULL
;
242 static struct hash_control
*dependency_insn_hsh
= NULL
;
244 /* Enumeration matching entries in table above. */
248 #define REG_TYPE_FIRST REG_TYPE_SCORE
249 REG_TYPE_SCORE_SR
= 1,
250 REG_TYPE_SCORE_CR
= 2,
254 typedef struct literalS
256 struct expressionS exp
;
257 struct score_it
*inst
;
261 literalT literals
[MAX_LITERAL_POOL_SIZE
];
263 static void do_ldst_insn (char *);
264 static void do_crdcrscrsimm5 (char *);
265 static void do_ldst_unalign (char *);
266 static void do_ldst_atomic (char *);
267 static void do_ldst_cop (char *);
268 static void do_macro_li_rdi32 (char *);
269 static void do_macro_la_rdi32 (char *);
270 static void do_macro_rdi32hi (char *);
271 static void do_macro_rdi32lo (char *);
272 static void do_macro_mul_rdrsrs (char *);
273 static void do_macro_ldst_label (char *);
274 static void do_branch (char *);
275 static void do_jump (char *);
276 static void do_empty (char *);
277 static void do_rdrsrs (char *);
278 static void do_rdsi16 (char *);
279 static void do_rdrssi14 (char *);
280 static void do_sub_rdsi16 (char *);
281 static void do_sub_rdi16 (char *);
282 static void do_sub_rdrssi14 (char *);
283 static void do_rdrsi5 (char *);
284 static void do_rdrsi14 (char *);
285 static void do_rdi16 (char *);
286 static void do_xrsi5 (char *);
287 static void do_rdrs (char *);
288 static void do_rdxrs (char *);
289 static void do_rsrs (char *);
290 static void do_rdcrs (char *);
291 static void do_rdsrs (char *);
292 static void do_rd (char *);
293 static void do_rs (char *);
294 static void do_i15 (char *);
295 static void do_xi5x (char *);
296 static void do_ceinst (char *);
297 static void do_cache (char *);
298 static void do16_rdrs (char *);
299 static void do16_rs (char *);
300 static void do16_xrs (char *);
301 static void do16_mv_rdrs (char *);
302 static void do16_hrdrs (char *);
303 static void do16_rdhrs (char *);
304 static void do16_rdi4 (char *);
305 static void do16_rdi5 (char *);
306 static void do16_xi5 (char *);
307 static void do16_ldst_insn (char *);
308 static void do16_ldst_imm_insn (char *);
309 static void do16_push_pop (char *);
310 static void do16_branch (char *);
311 static void do16_jump (char *);
312 static void do_rdi16_pic (char *);
313 static void do_addi_s_pic (char *);
314 static void do_addi_u_pic (char *);
315 static void do_lw_pic (char *);
317 static const struct asm_opcode score_ldst_insns
[] =
319 {"lw", 0x20000000, 0x3e000000, 0x2008, Rd_rvalueRs_SI15
, do_ldst_insn
},
320 {"lw", 0x06000000, 0x3e000007, 0x8000, Rd_rvalueRs_preSI12
, do_ldst_insn
},
321 {"lw", 0x0e000000, 0x3e000007, 0x200a, Rd_rvalueRs_postSI12
, do_ldst_insn
},
322 {"lh", 0x22000000, 0x3e000000, 0x2009, Rd_rvalueRs_SI15
, do_ldst_insn
},
323 {"lh", 0x06000001, 0x3e000007, 0x8000, Rd_rvalueRs_preSI12
, do_ldst_insn
},
324 {"lh", 0x0e000001, 0x3e000007, 0x8000, Rd_rvalueRs_postSI12
, do_ldst_insn
},
325 {"lhu", 0x24000000, 0x3e000000, 0x8000, Rd_rvalueRs_SI15
, do_ldst_insn
},
326 {"lhu", 0x06000002, 0x3e000007, 0x8000, Rd_rvalueRs_preSI12
, do_ldst_insn
},
327 {"lhu", 0x0e000002, 0x3e000007, 0x8000, Rd_rvalueRs_postSI12
, do_ldst_insn
},
328 {"lb", 0x26000000, 0x3e000000, 0x8000, Rd_rvalueRs_SI15
, do_ldst_insn
},
329 {"lb", 0x06000003, 0x3e000007, 0x8000, Rd_rvalueRs_preSI12
, do_ldst_insn
},
330 {"lb", 0x0e000003, 0x3e000007, 0x8000, Rd_rvalueRs_postSI12
, do_ldst_insn
},
331 {"sw", 0x28000000, 0x3e000000, 0x200c, Rd_lvalueRs_SI15
, do_ldst_insn
},
332 {"sw", 0x06000004, 0x3e000007, 0x200e, Rd_lvalueRs_preSI12
, do_ldst_insn
},
333 {"sw", 0x0e000004, 0x3e000007, 0x8000, Rd_lvalueRs_postSI12
, do_ldst_insn
},
334 {"sh", 0x2a000000, 0x3e000000, 0x200d, Rd_lvalueRs_SI15
, do_ldst_insn
},
335 {"sh", 0x06000005, 0x3e000007, 0x8000, Rd_lvalueRs_preSI12
, do_ldst_insn
},
336 {"sh", 0x0e000005, 0x3e000007, 0x8000, Rd_lvalueRs_postSI12
, do_ldst_insn
},
337 {"lbu", 0x2c000000, 0x3e000000, 0x200b, Rd_rvalueRs_SI15
, do_ldst_insn
},
338 {"lbu", 0x06000006, 0x3e000007, 0x8000, Rd_rvalueRs_preSI12
, do_ldst_insn
},
339 {"lbu", 0x0e000006, 0x3e000007, 0x8000, Rd_rvalueRs_postSI12
, do_ldst_insn
},
340 {"sb", 0x2e000000, 0x3e000000, 0x200f, Rd_lvalueRs_SI15
, do_ldst_insn
},
341 {"sb", 0x06000007, 0x3e000007, 0x8000, Rd_lvalueRs_preSI12
, do_ldst_insn
},
342 {"sb", 0x0e000007, 0x3e000007, 0x8000, Rd_lvalueRs_postSI12
, do_ldst_insn
},
345 static const struct asm_opcode score_insns
[] =
347 {"abs", 0x3800000a, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
348 {"abs.s", 0x3800004b, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
349 {"add", 0x00000010, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
350 {"add.c", 0x00000011, 0x3e0003ff, 0x2000, Rd_Rs_Rs
, do_rdrsrs
},
351 {"add.s", 0x38000048, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
352 {"addc", 0x00000012, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
353 {"addc.c", 0x00000013, 0x3e0003ff, 0x0009, Rd_Rs_Rs
, do_rdrsrs
},
354 {"addi", 0x02000000, 0x3e0e0001, 0x8000, Rd_SI16
, do_rdsi16
},
355 {"addi.c", 0x02000001, 0x3e0e0001, 0x8000, Rd_SI16
, do_rdsi16
},
356 {"addis", 0x0a000000, 0x3e0e0001, 0x8000, Rd_SI16
, do_rdi16
},
357 {"addis.c", 0x0a000001, 0x3e0e0001, 0x8000, Rd_SI16
, do_rdi16
},
358 {"addri", 0x10000000, 0x3e000001, 0x8000, Rd_Rs_SI14
, do_rdrssi14
},
359 {"addri.c", 0x10000001, 0x3e000001, 0x8000, Rd_Rs_SI14
, do_rdrssi14
},
360 {"addc!", 0x0009, 0x700f, 0x00000013, Rd_Rs
, do16_rdrs
},
361 {"add!", 0x2000, 0x700f, 0x00000011, Rd_Rs
, do16_rdrs
},
362 {"addei!", 0x6000 , 0x7087, 0x02000001, Rd_I4
, do16_rdi4
},
363 {"subi", 0x02000000, 0x3e0e0001, 0x8000, Rd_SI16
, do_sub_rdsi16
},
364 {"subi.c", 0x02000001, 0x3e0e0001, 0x8000, Rd_SI16
, do_sub_rdsi16
},
365 {"subis", 0x0a000000, 0x3e0e0001, 0x8000, Rd_SI16
, do_sub_rdi16
},
366 {"subis.c", 0x0a000001, 0x3e0e0001, 0x8000, Rd_SI16
, do_sub_rdi16
},
367 {"subri", 0x10000000, 0x3e000001, 0x8000, Rd_Rs_SI14
, do_sub_rdrssi14
},
368 {"subri.c", 0x10000001, 0x3e000001, 0x8000, Rd_Rs_SI14
, do_sub_rdrssi14
},
369 {"and", 0x00000020, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
370 {"and.c", 0x00000021, 0x3e0003ff, 0x2004, Rd_Rs_Rs
, do_rdrsrs
},
371 {"andi", 0x02080000, 0x3e0e0001, 0x8000, Rd_I16
, do_rdi16
},
372 {"andi.c", 0x02080001, 0x3e0e0001, 0x8000, Rd_I16
, do_rdi16
},
373 {"andis", 0x0a080000, 0x3e0e0001, 0x8000, Rd_I16
, do_rdi16
},
374 {"andis.c", 0x0a080001, 0x3e0e0001, 0x8000, Rd_I16
, do_rdi16
},
375 {"andri", 0x18000000, 0x3e000001, 0x8000, Rd_Rs_I14
, do_rdrsi14
},
376 {"andri.c", 0x18000001, 0x3e000001, 0x8000, Rd_Rs_I14
, do_rdrsi14
},
377 {"and!", 0x2004, 0x700f, 0x00000021, Rd_Rs
, do16_rdrs
},
378 {"bcs", 0x08000000, 0x3e007c01, 0x4000, PC_DISP19div2
, do_branch
},
379 {"bcc", 0x08000400, 0x3e007c01, 0x4000, PC_DISP19div2
, do_branch
},
380 {"bcnz", 0x08003800, 0x3e007c01, 0x4000, PC_DISP19div2
, do_branch
},
381 {"bcsl", 0x08000001, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
382 {"bccl", 0x08000401, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
383 {"bcnzl", 0x08003801, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
384 {"bcs!", 0x4000, 0x7f00, 0x08000000, PC_DISP8div2
, do16_branch
},
385 {"bcc!", 0x4100, 0x7f00, 0x08000400, PC_DISP8div2
, do16_branch
},
386 {"bcnz!", 0x4e00, 0x7f00, 0x08003800, PC_DISP8div2
, do16_branch
},
387 {"beq", 0x08001000, 0x3e007c01, 0x4000, PC_DISP19div2
, do_branch
},
388 {"beql", 0x08001001, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
389 {"beq!", 0x4400, 0x7f00, 0x08001000, PC_DISP8div2
, do16_branch
},
390 {"bgtu", 0x08000800, 0x3e007c01, 0x4000, PC_DISP19div2
, do_branch
},
391 {"bgt", 0x08001800, 0x3e007c01, 0x4000, PC_DISP19div2
, do_branch
},
392 {"bge", 0x08002000, 0x3e007c01, 0x4000, PC_DISP19div2
, do_branch
},
393 {"bgtul", 0x08000801, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
394 {"bgtl", 0x08001801, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
395 {"bgel", 0x08002001, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
396 {"bgtu!", 0x4200, 0x7f00, 0x08000800, PC_DISP8div2
, do16_branch
},
397 {"bgt!", 0x4600, 0x7f00, 0x08001800, PC_DISP8div2
, do16_branch
},
398 {"bge!", 0x4800, 0x7f00, 0x08002000, PC_DISP8div2
, do16_branch
},
399 {"bitclr.c", 0x00000029, 0x3e0003ff, 0x6004, Rd_Rs_I5
, do_rdrsi5
},
400 {"bitrev", 0x3800000c, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
401 {"bitset.c", 0x0000002b, 0x3e0003ff, 0x6005, Rd_Rs_I5
, do_rdrsi5
},
402 {"bittst.c", 0x0000002d, 0x3e0003ff, 0x6006, x_Rs_I5
, do_xrsi5
},
403 {"bittgl.c", 0x0000002f, 0x3e0003ff, 0x6007, Rd_Rs_I5
, do_rdrsi5
},
404 {"bitclr!", 0x6004, 0x7007, 0x00000029, Rd_I5
, do16_rdi5
},
405 {"bitset!", 0x6005, 0x7007, 0x0000002b, Rd_I5
, do16_rdi5
},
406 {"bittst!", 0x6006, 0x7007, 0x0000002d, Rd_I5
, do16_rdi5
},
407 {"bittgl!", 0x6007, 0x7007, 0x0000002f, Rd_I5
, do16_rdi5
},
408 {"bleu", 0x08000c00, 0x3e007c01, 0x4000, PC_DISP19div2
, do_branch
},
409 {"ble", 0x08001c00, 0x3e007c01, 0x4000, PC_DISP19div2
, do_branch
},
410 {"blt", 0x08002400, 0x3e007c01, 0x4000, PC_DISP19div2
, do_branch
},
411 {"bleul", 0x08000c01, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
412 {"blel", 0x08001c01, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
413 {"bltl", 0x08002401, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
414 {"bl", 0x08003c01, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
415 {"bleu!", 0x4300, 0x7f00, 0x08000c00, PC_DISP8div2
, do16_branch
},
416 {"ble!", 0x4700, 0x7f00, 0x08001c00, PC_DISP8div2
, do16_branch
},
417 {"blt!", 0x4900, 0x7f00, 0x08002400, PC_DISP8div2
, do16_branch
},
418 {"bmi", 0x08002800, 0x3e007c01, 0x4000, PC_DISP19div2
, do_branch
},
419 {"bmil", 0x08002801, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
420 {"bmi!", 0x00004a00, 0x00007f00, 0x08002800, PC_DISP8div2
, do16_branch
},
421 {"bne", 0x08001400, 0x3e007c01, 0x4000, PC_DISP19div2
, do_branch
},
422 {"bnel", 0x08001401, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
423 {"bne!", 0x4500, 0x7f00, 0x08001400, PC_DISP8div2
, do16_branch
},
424 {"bpl", 0x08002c00, 0x3e007c01, 0x4000, PC_DISP19div2
, do_branch
},
425 {"bpll", 0x08002c01, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
426 {"bpl!", 0x4b00, 0x7f00, 0x08002c00, PC_DISP8div2
, do16_branch
},
427 {"brcs", 0x00000008, 0x3e007fff, 0x0004, x_Rs_x
, do_rs
},
428 {"brcc", 0x00000408, 0x3e007fff, 0x0104, x_Rs_x
, do_rs
},
429 {"brgtu", 0x00000808, 0x3e007fff, 0x0204, x_Rs_x
, do_rs
},
430 {"brleu", 0x00000c08, 0x3e007fff, 0x0304, x_Rs_x
, do_rs
},
431 {"breq", 0x00001008, 0x3e007fff, 0x0404, x_Rs_x
, do_rs
},
432 {"brne", 0x00001408, 0x3e007fff, 0x0504, x_Rs_x
, do_rs
},
433 {"brgt", 0x00001808, 0x3e007fff, 0x0604, x_Rs_x
, do_rs
},
434 {"brle", 0x00001c08, 0x3e007fff, 0x0704, x_Rs_x
, do_rs
},
435 {"brge", 0x00002008, 0x3e007fff, 0x0804, x_Rs_x
, do_rs
},
436 {"brlt", 0x00002408, 0x3e007fff, 0x0904, x_Rs_x
, do_rs
},
437 {"brmi", 0x00002808, 0x3e007fff, 0x0a04, x_Rs_x
, do_rs
},
438 {"brpl", 0x00002c08, 0x3e007fff, 0x0b04, x_Rs_x
, do_rs
},
439 {"brvs", 0x00003008, 0x3e007fff, 0x0c04, x_Rs_x
, do_rs
},
440 {"brvc", 0x00003408, 0x3e007fff, 0x0d04, x_Rs_x
, do_rs
},
441 {"brcnz", 0x00003808, 0x3e007fff, 0x0e04, x_Rs_x
, do_rs
},
442 {"br", 0x00003c08, 0x3e007fff, 0x0f04, x_Rs_x
, do_rs
},
443 {"brcsl", 0x00000009, 0x3e007fff, 0x000c, x_Rs_x
, do_rs
},
444 {"brccl", 0x00000409, 0x3e007fff, 0x010c, x_Rs_x
, do_rs
},
445 {"brgtul", 0x00000809, 0x3e007fff, 0x020c, x_Rs_x
, do_rs
},
446 {"brleul", 0x00000c09, 0x3e007fff, 0x030c, x_Rs_x
, do_rs
},
447 {"breql", 0x00001009, 0x3e007fff, 0x040c, x_Rs_x
, do_rs
},
448 {"brnel", 0x00001409, 0x3e007fff, 0x050c, x_Rs_x
, do_rs
},
449 {"brgtl", 0x00001809, 0x3e007fff, 0x060c, x_Rs_x
, do_rs
},
450 {"brlel", 0x00001c09, 0x3e007fff, 0x070c, x_Rs_x
, do_rs
},
451 {"brgel", 0x00002009, 0x3e007fff, 0x080c, x_Rs_x
, do_rs
},
452 {"brltl", 0x00002409, 0x3e007fff, 0x090c, x_Rs_x
, do_rs
},
453 {"brmil", 0x00002809, 0x3e007fff, 0x0a0c, x_Rs_x
, do_rs
},
454 {"brpll", 0x00002c09, 0x3e007fff, 0x0b0c, x_Rs_x
, do_rs
},
455 {"brvsl", 0x00003009, 0x3e007fff, 0x0c0c, x_Rs_x
, do_rs
},
456 {"brvcl", 0x00003409, 0x3e007fff, 0x0d0c, x_Rs_x
, do_rs
},
457 {"brcnzl", 0x00003809, 0x3e007fff, 0x0e0c, x_Rs_x
, do_rs
},
458 {"brl", 0x00003c09, 0x3e007fff, 0x0f0c, x_Rs_x
, do_rs
},
459 {"brcs!", 0x0004, 0x7f0f, 0x00000008, x_Rs
, do16_xrs
},
460 {"brcc!", 0x0104, 0x7f0f, 0x00000408, x_Rs
, do16_xrs
},
461 {"brgtu!", 0x0204, 0x7f0f, 0x00000808, x_Rs
, do16_xrs
},
462 {"brleu!", 0x0304, 0x7f0f, 0x00000c08, x_Rs
, do16_xrs
},
463 {"breq!", 0x0404, 0x7f0f, 0x00001008, x_Rs
, do16_xrs
},
464 {"brne!", 0x0504, 0x7f0f, 0x00001408, x_Rs
, do16_xrs
},
465 {"brgt!", 0x0604, 0x7f0f, 0x00001808, x_Rs
, do16_xrs
},
466 {"brle!", 0x0704, 0x7f0f, 0x00001c08, x_Rs
, do16_xrs
},
467 {"brge!", 0x0804, 0x7f0f, 0x00002008, x_Rs
, do16_xrs
},
468 {"brlt!", 0x0904, 0x7f0f, 0x00002408, x_Rs
, do16_xrs
},
469 {"brmi!", 0x0a04, 0x7f0f, 0x00002808, x_Rs
, do16_xrs
},
470 {"brpl!", 0x0b04, 0x7f0f, 0x00002c08, x_Rs
, do16_xrs
},
471 {"brvs!", 0x0c04, 0x7f0f, 0x00003008, x_Rs
, do16_xrs
},
472 {"brvc!", 0x0d04, 0x7f0f, 0x00003408, x_Rs
, do16_xrs
},
473 {"brcnz!", 0x0e04, 0x7f0f, 0x00003808, x_Rs
, do16_xrs
},
474 {"br!", 0x0f04, 0x7f0f, 0x00003c08, x_Rs
, do16_xrs
},
475 {"brcsl!", 0x000c, 0x7f0f, 0x00000009, x_Rs
, do16_xrs
},
476 {"brccl!", 0x010c, 0x7f0f, 0x00000409, x_Rs
, do16_xrs
},
477 {"brgtul!", 0x020c, 0x7f0f, 0x00000809, x_Rs
, do16_xrs
},
478 {"brleul!", 0x030c, 0x7f0f, 0x00000c09, x_Rs
, do16_xrs
},
479 {"breql!", 0x040c, 0x7f0f, 0x00001009, x_Rs
, do16_xrs
},
480 {"brnel!", 0x050c, 0x7f0f, 0x00001409, x_Rs
, do16_xrs
},
481 {"brgtl!", 0x060c, 0x7f0f, 0x00001809, x_Rs
, do16_xrs
},
482 {"brlel!", 0x070c, 0x7f0f, 0x00001c09, x_Rs
, do16_xrs
},
483 {"brgel!", 0x080c, 0x7f0f, 0x00002009, x_Rs
, do16_xrs
},
484 {"brltl!", 0x090c, 0x7f0f, 0x00002409, x_Rs
, do16_xrs
},
485 {"brmil!", 0x0a0c, 0x7f0f, 0x00002809, x_Rs
, do16_xrs
},
486 {"brpll!", 0x0b0c, 0x7f0f, 0x00002c09, x_Rs
, do16_xrs
},
487 {"brvsl!", 0x0c0c, 0x7f0f, 0x00003009, x_Rs
, do16_xrs
},
488 {"brvcl!", 0x0d0c, 0x7f0f, 0x00003409, x_Rs
, do16_xrs
},
489 {"brcnzl!", 0x0e0c, 0x7f0f, 0x00003809, x_Rs
, do16_xrs
},
490 {"brl!", 0x0f0c, 0x7f0f, 0x00003c09, x_Rs
, do16_xrs
},
491 {"bvs", 0x08003000, 0x3e007c01, 0x4000, PC_DISP19div2
, do_branch
},
492 {"bvc", 0x08003400, 0x3e007c01, 0x4000, PC_DISP19div2
, do_branch
},
493 {"bvsl", 0x08003001, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
494 {"bvcl", 0x08003401, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
495 {"bvs!", 0x4c00, 0x7f00, 0x08003000, PC_DISP8div2
, do16_branch
},
496 {"bvc!", 0x4d00, 0x7f00, 0x08003400, PC_DISP8div2
, do16_branch
},
497 {"b!", 0x4f00, 0x7f00, 0x08003c00, PC_DISP8div2
, do16_branch
},
498 {"b", 0x08003c00, 0x3e007c01, 0x4000, PC_DISP19div2
, do_branch
},
499 {"cache", 0x30000000, 0x3ff00000, 0x8000, OP5_rvalueRs_SI15
, do_cache
},
500 {"ceinst", 0x38000000, 0x3e000000, 0x8000, I5_Rs_Rs_I5_OP5
, do_ceinst
},
501 {"clz", 0x3800000d, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
502 {"cmpteq.c", 0x00000019, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
503 {"cmptmi.c", 0x00100019, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
504 {"cmp.c", 0x00300019, 0x3ff003ff, 0x2003, x_Rs_Rs
, do_rsrs
},
505 {"cmpzteq.c", 0x0000001b, 0x3ff07fff, 0x8000, x_Rs_x
, do_rs
},
506 {"cmpztmi.c", 0x0010001b, 0x3ff07fff, 0x8000, x_Rs_x
, do_rs
},
507 {"cmpz.c", 0x0030001b, 0x3ff07fff, 0x8000, x_Rs_x
, do_rs
},
508 {"cmpi.c", 0x02040001, 0x3e0e0001, 0x8000, Rd_SI16
, do_rdsi16
},
509 {"cmp!", 0x2003, 0x700f, 0x00300019, Rd_Rs
, do16_rdrs
},
510 {"cop1", 0x0c00000c, 0x3e00001f, 0x8000, Rd_Rs_Rs_imm
, do_crdcrscrsimm5
},
511 {"cop2", 0x0c000014, 0x3e00001f, 0x8000, Rd_Rs_Rs_imm
, do_crdcrscrsimm5
},
512 {"cop3", 0x0c00001c, 0x3e00001f, 0x8000, Rd_Rs_Rs_imm
, do_crdcrscrsimm5
},
513 {"drte", 0x0c0000a4, 0x3e0003ff, 0x8000, NO_OPD
, do_empty
},
514 {"extsb", 0x00000058, 0x3e0003ff, 0x8000, Rd_Rs_x
, do_rdrs
},
515 {"extsb.c", 0x00000059, 0x3e0003ff, 0x8000, Rd_Rs_x
, do_rdrs
},
516 {"extsh", 0x0000005a, 0x3e0003ff, 0x8000, Rd_Rs_x
, do_rdrs
},
517 {"extsh.c", 0x0000005b, 0x3e0003ff, 0x8000, Rd_Rs_x
, do_rdrs
},
518 {"extzb", 0x0000005c, 0x3e0003ff, 0x8000, Rd_Rs_x
, do_rdrs
},
519 {"extzb.c", 0x0000005d, 0x3e0003ff, 0x8000, Rd_Rs_x
, do_rdrs
},
520 {"extzh", 0x0000005e, 0x3e0003ff, 0x8000, Rd_Rs_x
, do_rdrs
},
521 {"extzh.c", 0x0000005f, 0x3e0003ff, 0x8000, Rd_Rs_x
, do_rdrs
},
522 {"jl", 0x04000001, 0x3e000001, 0x8000, PC_DISP24div2
, do_jump
},
523 {"jl!", 0x3001, 0x7001, 0x04000001, PC_DISP11div2
, do16_jump
},
524 {"j!", 0x3000, 0x7001, 0x04000000, PC_DISP11div2
, do16_jump
},
525 {"j", 0x04000000, 0x3e000001, 0x8000, PC_DISP24div2
, do_jump
},
526 {"lbu!", 0x200b, 0x0000700f, 0x2c000000, Rd_rvalueRs
, do16_ldst_insn
},
527 {"lbup!", 0x7003, 0x7007, 0x2c000000, Rd_rvalueBP_I5
, do16_ldst_imm_insn
},
528 {"alw", 0x0000000c, 0x3e0003ff, 0x8000, Rd_rvalue32Rs
, do_ldst_atomic
},
529 {"lcb", 0x00000060, 0x3e0003ff, 0x8000, x_rvalueRs_post4
, do_ldst_unalign
},
530 {"lcw", 0x00000062, 0x3e0003ff, 0x8000, Rd_rvalueRs_post4
, do_ldst_unalign
},
531 {"lce", 0x00000066, 0x3e0003ff, 0x8000, Rd_rvalueRs_post4
, do_ldst_unalign
},
532 {"ldc1", 0x0c00000a, 0x3e00001f, 0x8000, Rd_rvalueRs_SI10
, do_ldst_cop
},
533 {"ldc2", 0x0c000012, 0x3e00001f, 0x8000, Rd_rvalueRs_SI10
, do_ldst_cop
},
534 {"ldc3", 0x0c00001a, 0x3e00001f, 0x8000, Rd_rvalueRs_SI10
, do_ldst_cop
},
535 {"lh!", 0x2009, 0x700f, 0x22000000, Rd_rvalueRs
, do16_ldst_insn
},
536 {"lhp!", 0x7001, 0x7007, 0x22000000, Rd_rvalueBP_I5
, do16_ldst_imm_insn
},
537 {"ldi", 0x020c0000, 0x3e0e0000, 0x5000, Rd_SI16
, do_rdsi16
},
538 {"ldis", 0x0a0c0000, 0x3e0e0000, 0x8000, 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, 0x8000, 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
)
1210 static char err_msg
[100];
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))
1262 static char err_msg
[100];
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 addis/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;
1440 do_macro_rdi32hi (char *str
)
1442 skip_whitespace (str
);
1444 /* Do not handle end_of_line(). */
1445 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) != (int) FAIL
1446 && skip_past_comma (&str
) != (int) FAIL
)
1447 data_op2 (&str
, 1, _VALUE_HI16
);
1451 do_macro_rdi32lo (char *str
)
1453 skip_whitespace (str
);
1455 /* Do not handle end_of_line(). */
1456 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) != (int) FAIL
1457 && skip_past_comma (&str
) != (int) FAIL
)
1458 data_op2 (&str
, 1, _VALUE_LO16
);
1461 /* Handle ldis_pic. */
1464 do_rdi16_pic (char *str
)
1466 skip_whitespace (str
);
1468 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) != (int) FAIL
1469 && skip_past_comma (&str
) != (int) FAIL
1470 && data_op2 (&str
, 1, _IMM16_pic
) != (int) FAIL
)
1474 /* Handle addi_s_pic to generate R_SCORE_GOT_LO16 . */
1477 do_addi_s_pic (char *str
)
1479 skip_whitespace (str
);
1481 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) != (int) FAIL
1482 && skip_past_comma (&str
) != (int) FAIL
1483 && data_op2 (&str
, 1, _SIMM16_pic
) != (int) FAIL
)
1487 /* Handle addi_u_pic to generate R_SCORE_GOT_LO16 . */
1490 do_addi_u_pic (char *str
)
1492 skip_whitespace (str
);
1494 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) != (int) FAIL
1495 && skip_past_comma (&str
) != (int) FAIL
1496 && data_op2 (&str
, 1, _IMM16_LO16_pic
) != (int) FAIL
)
1500 /* Handle mfceh/mfcel/mtceh/mtchl. */
1505 skip_whitespace (str
);
1507 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) != (int) FAIL
)
1514 skip_whitespace (str
);
1516 if (reg_required_here (&str
, 15, REG_TYPE_SCORE
) == (int) FAIL
1517 || end_of_line (str
) == (int) FAIL
)
1520 if ((inst
.relax_inst
!= 0x8000) && (((inst
.instruction
>> 15) & 0x10) == 0))
1522 inst
.relax_inst
|= (((inst
.instruction
>> 10) & 0xf) << 8) | (((inst
.instruction
>> 15) & 0xf) << 4);
1523 inst
.relax_size
= 2;
1526 inst
.relax_inst
= 0x8000;
1532 skip_whitespace (str
);
1534 if (data_op2 (&str
, 10, _IMM15
) != (int) FAIL
)
1541 skip_whitespace (str
);
1543 if (data_op2 (&str
, 15, _IMM5
) == (int) FAIL
|| end_of_line (str
) == (int) FAIL
)
1546 if (inst
.relax_inst
!= 0x8000)
1548 inst
.relax_inst
|= (((inst
.instruction
>> 15) & 0x1f) << 3);
1549 inst
.relax_size
= 2;
1556 skip_whitespace (str
);
1558 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) == (int) FAIL
1559 || skip_past_comma (&str
) == (int) FAIL
1560 || reg_required_here (&str
, 15, REG_TYPE_SCORE
) == (int) FAIL
1561 || end_of_line (str
) == (int) FAIL
)
1564 if (inst
.relax_inst
!= 0x8000)
1566 if (((inst
.instruction
& 0x7f) == 0x56)) /* adjust mv -> mv! / mlfh! / mhfl! */
1569 if ((((inst
.instruction
>> 15) & 0x10) != 0x0) && (((inst
.instruction
>> 20) & 0x10) == 0))
1571 inst
.relax_inst
= 0x00000001 | (((inst
.instruction
>> 15) & 0xf) << 4)
1572 | (((inst
.instruction
>> 20) & 0xf) << 8);
1573 inst
.relax_size
= 2;
1576 else if ((((inst
.instruction
>> 15) & 0x10) == 0x0) && ((inst
.instruction
>> 20) & 0x10) != 0)
1578 inst
.relax_inst
= 0x00000002 | (((inst
.instruction
>> 15) & 0xf) << 4)
1579 | (((inst
.instruction
>> 20) & 0xf) << 8);
1580 inst
.relax_size
= 2;
1582 else if ((((inst
.instruction
>> 15) & 0x10) == 0x0) && (((inst
.instruction
>> 20) & 0x10) == 0))
1584 inst
.relax_inst
|= (((inst
.instruction
>> 15) & 0xf) << 4)
1585 | (((inst
.instruction
>> 20) & 0xf) << 8);
1586 inst
.relax_size
= 2;
1590 inst
.relax_inst
= 0x8000;
1593 else if ((((inst
.instruction
>> 15) & 0x10) == 0x0) && (((inst
.instruction
>> 20) & 0x10) == 0))
1595 inst
.relax_inst
|= (((inst
.instruction
>> 15) & 0xf) << 4)
1596 | (((inst
.instruction
>> 20) & 0xf) << 8);
1597 inst
.relax_size
= 2;
1601 inst
.relax_inst
= 0x8000;
1606 /* Handle mfcr/mtcr. */
1608 do_rdcrs (char *str
)
1610 skip_whitespace (str
);
1612 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) != (int) FAIL
1613 && skip_past_comma (&str
) != (int) FAIL
1614 && reg_required_here (&str
, 15, REG_TYPE_SCORE_CR
) != (int) FAIL
)
1618 /* Handle mfsr/mtsr. */
1621 do_rdsrs (char *str
)
1623 skip_whitespace (str
);
1626 if ((inst
.instruction
& 0xff) == 0x50)
1628 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) != (int) FAIL
1629 && skip_past_comma (&str
) != (int) FAIL
1630 && reg_required_here (&str
, 10, REG_TYPE_SCORE_SR
) != (int) FAIL
)
1635 if (reg_required_here (&str
, 15, REG_TYPE_SCORE
) != (int) FAIL
1636 && skip_past_comma (&str
) != (int) FAIL
)
1637 reg_required_here (&str
, 10, REG_TYPE_SCORE_SR
);
1644 do_rdxrs (char *str
)
1646 skip_whitespace (str
);
1648 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) == (int) FAIL
1649 || skip_past_comma (&str
) == (int) FAIL
1650 || reg_required_here (&str
, 10, REG_TYPE_SCORE
) == (int) FAIL
1651 || end_of_line (str
) == (int) FAIL
)
1654 if ((inst
.relax_inst
!= 0x8000) && (((inst
.instruction
>> 10) & 0x10) == 0)
1655 && (((inst
.instruction
>> 20) & 0x10) == 0))
1657 inst
.relax_inst
|= (((inst
.instruction
>> 10) & 0xf) << 4) | (((inst
.instruction
>> 20) & 0xf) << 8);
1658 inst
.relax_size
= 2;
1661 inst
.relax_inst
= 0x8000;
1664 /* Handle cmp.c/cmp<cond>. */
1668 skip_whitespace (str
);
1670 if (reg_required_here (&str
, 15, REG_TYPE_SCORE
) == (int) FAIL
1671 || skip_past_comma (&str
) == (int) FAIL
1672 || reg_required_here (&str
, 10, REG_TYPE_SCORE
) == (int) FAIL
1673 || end_of_line (str
) == (int) FAIL
)
1676 if ((inst
.relax_inst
!= 0x8000) && (((inst
.instruction
>> 20) & 0x1f) == 3)
1677 && (((inst
.instruction
>> 10) & 0x10) == 0) && (((inst
.instruction
>> 15) & 0x10) == 0))
1679 inst
.relax_inst
|= (((inst
.instruction
>> 10) & 0xf) << 4) | (((inst
.instruction
>> 15) & 0xf) << 8);
1680 inst
.relax_size
= 2;
1683 inst
.relax_inst
= 0x8000;
1687 do_ceinst (char *str
)
1692 skip_whitespace (str
);
1694 if (data_op2 (&str
, 20, _IMM5
) == (int) FAIL
1695 || skip_past_comma (&str
) == (int) FAIL
1696 || reg_required_here (&str
, 15, REG_TYPE_SCORE
) == (int) FAIL
1697 || skip_past_comma (&str
) == (int) FAIL
1698 || reg_required_here (&str
, 10, REG_TYPE_SCORE
) == (int) FAIL
1699 || skip_past_comma (&str
) == (int) FAIL
1700 || data_op2 (&str
, 5, _IMM5
) == (int) FAIL
1701 || skip_past_comma (&str
) == (int) FAIL
1702 || data_op2 (&str
, 0, _IMM5
) == (int) FAIL
1703 || end_of_line (str
) == (int) FAIL
)
1710 if (data_op2 (&str
, 0, _IMM25
) == (int) FAIL
)
1716 reglow_required_here (char **str
, int shift
)
1718 static char buff
[MAX_LITERAL_POOL_SIZE
];
1722 if ((reg
= score_reg_parse (str
, all_reg_maps
[REG_TYPE_SCORE
].htab
)) != (int) FAIL
)
1724 if ((reg
== 1) && (nor1
== 1) && (inst
.bwarn
== 0))
1726 as_warn (_("Using temp register(r1)"));
1732 inst
.instruction
|= reg
<< shift
;
1738 /* Restore the start point, we may have got a reg of the wrong class. */
1740 sprintf (buff
, _("low register(r0-r15)expected, not '%.100s'"), start
);
1745 /* Handle addc!/add!/and!/cmp!/neg!/not!/or!/sll!/srl!/sra!/xor!/sub!. */
1747 do16_rdrs (char *str
)
1749 skip_whitespace (str
);
1751 if (reglow_required_here (&str
, 8) == (int) FAIL
1752 || skip_past_comma (&str
) == (int) FAIL
1753 || reglow_required_here (&str
, 4) == (int) FAIL
1754 || end_of_line (str
) == (int) FAIL
)
1760 if ((inst
.instruction
& 0x700f) == 0x2003) /* cmp! */
1762 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 15)
1763 | (((inst
.instruction
>> 4) & 0xf) << 10);
1765 else if ((inst
.instruction
& 0x700f) == 0x2006) /* not! */
1767 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 20)
1768 | (((inst
.instruction
>> 4) & 0xf) << 15);
1772 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 20)
1773 | (((inst
.instruction
>> 8) & 0xf) << 15) | (((inst
.instruction
>> 4) & 0xf) << 10);
1775 inst
.relax_size
= 4;
1784 skip_whitespace (str
);
1786 if ((rd
= reglow_required_here (&str
, 4)) == (int) FAIL
1787 || end_of_line (str
) == (int) FAIL
)
1793 inst
.relax_inst
|= rd
<< 20;
1794 inst
.relax_size
= 4;
1798 /* Handle br!/brl!. */
1800 do16_xrs (char *str
)
1802 skip_whitespace (str
);
1804 if (reglow_required_here (&str
, 4) == (int) FAIL
|| end_of_line (str
) == (int) FAIL
)
1810 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 10)
1811 | (((inst
.instruction
>> 4) & 0xf) << 15);
1812 inst
.relax_size
= 4;
1817 reghigh_required_here (char **str
, int shift
)
1819 static char buff
[MAX_LITERAL_POOL_SIZE
];
1823 if ((reg
= score_reg_parse (str
, all_reg_maps
[REG_TYPE_SCORE
].htab
)) != (int) FAIL
)
1825 if (15 < reg
&& reg
< 32)
1828 inst
.instruction
|= (reg
& 0xf) << shift
;
1835 sprintf (buff
, _("high register(r16-r31)expected, not '%.100s'"), start
);
1842 do16_hrdrs (char *str
)
1844 skip_whitespace (str
);
1846 if (reghigh_required_here (&str
, 8) != (int) FAIL
1847 && skip_past_comma (&str
) != (int) FAIL
1848 && reglow_required_here (&str
, 4) != (int) FAIL
1849 && end_of_line (str
) != (int) FAIL
)
1851 inst
.relax_inst
|= ((((inst
.instruction
>> 8) & 0xf) | 0x10) << 20)
1852 | (((inst
.instruction
>> 4) & 0xf) << 15) | (0xf << 10);
1853 inst
.relax_size
= 4;
1859 do16_rdhrs (char *str
)
1861 skip_whitespace (str
);
1863 if (reglow_required_here (&str
, 8) != (int) FAIL
1864 && skip_past_comma (&str
) != (int) FAIL
1865 && reghigh_required_here (&str
, 4) != (int) FAIL
1866 && end_of_line (str
) != (int) FAIL
)
1868 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 20)
1869 | ((((inst
.instruction
>> 4) & 0xf) | 0x10) << 15) | (0xf << 10);
1870 inst
.relax_size
= 4;
1874 /* We need to be able to fix up arbitrary expressions in some statements.
1875 This is so that we can handle symbols that are an arbitrary distance from
1876 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
1877 which returns part of an address in a form which will be valid for
1878 a data instruction. We do this by pushing the expression into a symbol
1879 in the expr_section, and creating a fix for that. */
1881 fix_new_score (fragS
* frag
, int where
, short int size
, expressionS
* exp
, int pc_rel
, int reloc
)
1891 new_fix
= fix_new_exp (frag
, where
, size
, exp
, pc_rel
, reloc
);
1894 new_fix
= fix_new (frag
, where
, size
, make_expr_symbol (exp
), 0, pc_rel
, reloc
);
1901 init_dependency_vector (void)
1905 for (i
= 0; i
< vector_size
; i
++)
1906 memset (&dependency_vector
[i
], '\0', sizeof (dependency_vector
[i
]));
1911 static enum insn_type_for_dependency
1912 dependency_type_from_insn (char *insn_name
)
1914 char name
[INSN_NAME_LEN
];
1915 const struct insn_to_dependency
*tmp
;
1917 strcpy (name
, insn_name
);
1918 tmp
= (const struct insn_to_dependency
*) hash_find (dependency_insn_hsh
, name
);
1927 check_dependency (char *pre_insn
, char *pre_reg
,
1928 char *cur_insn
, char *cur_reg
, int *warn_or_error
)
1932 enum insn_type_for_dependency pre_insn_type
;
1933 enum insn_type_for_dependency cur_insn_type
;
1935 pre_insn_type
= dependency_type_from_insn (pre_insn
);
1936 cur_insn_type
= dependency_type_from_insn (cur_insn
);
1938 for (i
= 0; i
< sizeof (data_dependency_table
) / sizeof (data_dependency_table
[0]); i
++)
1940 if ((pre_insn_type
== data_dependency_table
[i
].pre_insn_type
)
1941 && (D_all_insn
== data_dependency_table
[i
].cur_insn_type
1942 || cur_insn_type
== data_dependency_table
[i
].cur_insn_type
)
1943 && (strcmp (data_dependency_table
[i
].pre_reg
, "") == 0
1944 || strcmp (data_dependency_table
[i
].pre_reg
, pre_reg
) == 0)
1945 && (strcmp (data_dependency_table
[i
].cur_reg
, "") == 0
1946 || strcmp (data_dependency_table
[i
].cur_reg
, cur_reg
) == 0))
1948 bubbles
= (score7
) ? data_dependency_table
[i
].bubblenum_7
: data_dependency_table
[i
].bubblenum_5
;
1949 *warn_or_error
= data_dependency_table
[i
].warn_or_error
;
1958 build_one_frag (struct score_it one_inst
)
1961 int relaxable_p
= g_opt
;
1964 /* Start a new frag if frag_now is not empty. */
1965 if (frag_now_fix () != 0)
1967 if (!frag_now
->tc_frag_data
.is_insn
)
1968 frag_wane (frag_now
);
1974 p
= frag_more (one_inst
.size
);
1975 md_number_to_chars (p
, one_inst
.instruction
, one_inst
.size
);
1978 dwarf2_emit_insn (one_inst
.size
);
1981 relaxable_p
&= (one_inst
.relax_size
!= 0);
1982 relax_size
= relaxable_p
? one_inst
.relax_size
: 0;
1984 p
= frag_var (rs_machine_dependent
, relax_size
+ RELAX_PAD_BYTE
, 0,
1985 RELAX_ENCODE (one_inst
.size
, one_inst
.relax_size
,
1986 one_inst
.type
, 0, 0, relaxable_p
),
1990 md_number_to_chars (p
, one_inst
.relax_inst
, relax_size
);
1994 handle_dependency (struct score_it
*theinst
)
1997 int warn_or_error
= 0; /* warn - 0; error - 1 */
1999 int remainder_bubbles
= 0;
2000 char cur_insn
[INSN_NAME_LEN
];
2001 char pre_insn
[INSN_NAME_LEN
];
2002 struct score_it nop_inst
;
2003 struct score_it pflush_inst
;
2005 nop_inst
.instruction
= 0x0000;
2007 nop_inst
.relax_inst
= 0x80008000;
2008 nop_inst
.relax_size
= 4;
2009 nop_inst
.type
= NO16_OPD
;
2011 pflush_inst
.instruction
= 0x8000800a;
2012 pflush_inst
.size
= 4;
2013 pflush_inst
.relax_inst
= 0x8000;
2014 pflush_inst
.relax_size
= 0;
2015 pflush_inst
.type
= NO_OPD
;
2017 /* pflush will clear all data dependency. */
2018 if (strcmp (theinst
->name
, "pflush") == 0)
2020 init_dependency_vector ();
2024 /* Push current instruction to dependency_vector[0]. */
2025 for (i
= vector_size
- 1; i
> 0; i
--)
2026 memcpy (&dependency_vector
[i
], &dependency_vector
[i
- 1], sizeof (dependency_vector
[i
]));
2028 memcpy (&dependency_vector
[0], theinst
, sizeof (dependency_vector
[i
]));
2030 /* There is no dependency between nop and any instruction. */
2031 if (strcmp (dependency_vector
[0].name
, "nop") == 0
2032 || strcmp (dependency_vector
[0].name
, "nop!") == 0)
2035 /* "pce" is defined in insn_to_dependency_table. */
2036 #define PCE_NAME "pce"
2038 if (dependency_vector
[0].type
== Insn_Type_PCE
)
2039 strcpy (cur_insn
, PCE_NAME
);
2041 strcpy (cur_insn
, dependency_vector
[0].name
);
2043 for (i
= 1; i
< vector_size
; i
++)
2045 /* The element of dependency_vector is NULL. */
2046 if (dependency_vector
[i
].name
[0] == '\0')
2049 if (dependency_vector
[i
].type
== Insn_Type_PCE
)
2050 strcpy (pre_insn
, PCE_NAME
);
2052 strcpy (pre_insn
, dependency_vector
[i
].name
);
2054 bubbles
= check_dependency (pre_insn
, dependency_vector
[i
].reg
,
2055 cur_insn
, dependency_vector
[0].reg
, &warn_or_error
);
2056 remainder_bubbles
= bubbles
- i
+ 1;
2058 if (remainder_bubbles
> 0)
2062 if (fix_data_dependency
== 1)
2064 if (remainder_bubbles
<= 2)
2066 if (warn_fix_data_dependency
)
2067 as_warn (_("Fix data dependency: %s %s -- %s %s (insert %d nop!/%d)"),
2068 dependency_vector
[i
].name
, dependency_vector
[i
].reg
,
2069 dependency_vector
[0].name
, dependency_vector
[0].reg
,
2070 remainder_bubbles
, bubbles
);
2072 for (j
= (vector_size
- 1); (j
- remainder_bubbles
) > 0; j
--)
2073 memcpy (&dependency_vector
[j
], &dependency_vector
[j
- remainder_bubbles
],
2074 sizeof (dependency_vector
[j
]));
2076 for (j
= 1; j
<= remainder_bubbles
; j
++)
2078 memset (&dependency_vector
[j
], '\0', sizeof (dependency_vector
[j
]));
2080 build_one_frag (nop_inst
);
2085 if (warn_fix_data_dependency
)
2086 as_warn (_("Fix data dependency: %s %s -- %s %s (insert 1 pflush/%d)"),
2087 dependency_vector
[i
].name
, dependency_vector
[i
].reg
,
2088 dependency_vector
[0].name
, dependency_vector
[0].reg
,
2091 for (j
= 1; j
< vector_size
; j
++)
2092 memset (&dependency_vector
[j
], '\0', sizeof (dependency_vector
[j
]));
2094 /* Insert pflush. */
2095 build_one_frag (pflush_inst
);
2102 as_bad (_("data dependency: %s %s -- %s %s (%d/%d bubble)"),
2103 dependency_vector
[i
].name
, dependency_vector
[i
].reg
,
2104 dependency_vector
[0].name
, dependency_vector
[0].reg
,
2105 remainder_bubbles
, bubbles
);
2109 as_warn (_("data dependency: %s %s -- %s %s (%d/%d bubble)"),
2110 dependency_vector
[i
].name
, dependency_vector
[i
].reg
,
2111 dependency_vector
[0].name
, dependency_vector
[0].reg
,
2112 remainder_bubbles
, bubbles
);
2119 static enum insn_class
2120 get_insn_class_from_type (enum score_insn_type type
)
2122 enum insn_class retval
= (int) FAIL
;
2128 case Rd_rvalueBP_I5
:
2129 case Rd_lvalueBP_I5
:
2140 retval
= INSN_CLASS_16
;
2149 case Rd_rvalueRs_SI10
:
2150 case Rd_lvalueRs_SI10
:
2151 case Rd_rvalueRs_preSI12
:
2152 case Rd_rvalueRs_postSI12
:
2153 case Rd_lvalueRs_preSI12
:
2154 case Rd_lvalueRs_postSI12
:
2156 case Rd_rvalueRs_SI15
:
2157 case Rd_lvalueRs_SI15
:
2166 case OP5_rvalueRs_SI15
:
2167 case I5_Rs_Rs_I5_OP5
:
2168 case x_rvalueRs_post4
:
2169 case Rd_rvalueRs_post4
:
2171 case Rd_lvalueRs_post4
:
2172 case x_lvalueRs_post4
:
2180 retval
= INSN_CLASS_32
;
2183 retval
= INSN_CLASS_PCE
;
2186 retval
= INSN_CLASS_SYN
;
2195 static unsigned long
2196 adjust_paritybit (unsigned long m_code
, enum insn_class
class)
2198 unsigned long result
= 0;
2199 unsigned long m_code_high
= 0;
2200 unsigned long m_code_low
= 0;
2201 unsigned long pb_high
= 0;
2202 unsigned long pb_low
= 0;
2204 if (class == INSN_CLASS_32
)
2206 pb_high
= 0x80000000;
2207 pb_low
= 0x00008000;
2209 else if (class == INSN_CLASS_16
)
2214 else if (class == INSN_CLASS_PCE
)
2217 pb_low
= 0x00008000;
2219 else if (class == INSN_CLASS_SYN
)
2221 /* FIXME. at this time, INSN_CLASS_SYN must be 32 bit, but, instruction type should
2222 be changed if macro instruction has been expanded. */
2223 pb_high
= 0x80000000;
2224 pb_low
= 0x00008000;
2231 m_code_high
= m_code
& 0x3fff8000;
2232 m_code_low
= m_code
& 0x00007fff;
2233 result
= pb_high
| (m_code_high
<< 1) | pb_low
| m_code_low
;
2239 gen_insn_frag (struct score_it
*part_1
, struct score_it
*part_2
)
2242 bfd_boolean pce_p
= FALSE
;
2243 int relaxable_p
= g_opt
;
2245 struct score_it
*inst1
= part_1
;
2246 struct score_it
*inst2
= part_2
;
2247 struct score_it backup_inst1
;
2249 pce_p
= (inst2
) ? TRUE
: FALSE
;
2250 memcpy (&backup_inst1
, inst1
, sizeof (struct score_it
));
2252 /* Adjust instruction opcode and to be relaxed instruction opcode. */
2255 backup_inst1
.instruction
= ((backup_inst1
.instruction
& 0x7FFF) << 15)
2256 | (inst2
->instruction
& 0x7FFF);
2257 backup_inst1
.instruction
= adjust_paritybit (backup_inst1
.instruction
, INSN_CLASS_PCE
);
2258 backup_inst1
.relax_inst
= 0x8000;
2259 backup_inst1
.size
= INSN_SIZE
;
2260 backup_inst1
.relax_size
= 0;
2261 backup_inst1
.type
= Insn_Type_PCE
;
2265 backup_inst1
.instruction
= adjust_paritybit (backup_inst1
.instruction
,
2266 GET_INSN_CLASS (backup_inst1
.type
));
2269 if (backup_inst1
.relax_size
!= 0)
2271 enum insn_class tmp
;
2273 tmp
= (backup_inst1
.size
== INSN_SIZE
) ? INSN_CLASS_16
: INSN_CLASS_32
;
2274 backup_inst1
.relax_inst
= adjust_paritybit (backup_inst1
.relax_inst
, tmp
);
2277 /* Check data dependency. */
2278 handle_dependency (&backup_inst1
);
2280 /* Start a new frag if frag_now is not empty and is not instruction frag, maybe it contains
2281 data produced by .ascii etc. Doing this is to make one instruction per frag. */
2282 if (frag_now_fix () != 0)
2284 if (!frag_now
->tc_frag_data
.is_insn
)
2285 frag_wane (frag_now
);
2290 /* Here, we must call frag_grow in order to keep the instruction frag type is
2291 rs_machine_dependent.
2292 For, frag_var may change frag_now->fr_type to rs_fill by calling frag_grow which
2293 acturally will call frag_wane.
2294 Calling frag_grow first will create a new frag_now which free size is 20 that is enough
2298 p
= frag_more (backup_inst1
.size
);
2299 md_number_to_chars (p
, backup_inst1
.instruction
, backup_inst1
.size
);
2302 dwarf2_emit_insn (backup_inst1
.size
);
2305 /* Generate fixup structure. */
2308 if (inst1
->reloc
.type
!= BFD_RELOC_NONE
)
2309 fix_new_score (frag_now
, p
- frag_now
->fr_literal
,
2310 inst1
->size
, &inst1
->reloc
.exp
,
2311 inst1
->reloc
.pc_rel
, inst1
->reloc
.type
);
2313 if (inst2
->reloc
.type
!= BFD_RELOC_NONE
)
2314 fix_new_score (frag_now
, p
- frag_now
->fr_literal
+ 2,
2315 inst2
->size
, &inst2
->reloc
.exp
, inst2
->reloc
.pc_rel
, inst2
->reloc
.type
);
2319 if (backup_inst1
.reloc
.type
!= BFD_RELOC_NONE
)
2320 fix_new_score (frag_now
, p
- frag_now
->fr_literal
,
2321 backup_inst1
.size
, &backup_inst1
.reloc
.exp
,
2322 backup_inst1
.reloc
.pc_rel
, backup_inst1
.reloc
.type
);
2325 /* relax_size may be 2, 4, 12 or 0, 0 indicates no relaxation. */
2326 relaxable_p
&= (backup_inst1
.relax_size
!= 0);
2327 relax_size
= relaxable_p
? backup_inst1
.relax_size
: 0;
2329 p
= frag_var (rs_machine_dependent
, relax_size
+ RELAX_PAD_BYTE
, 0,
2330 RELAX_ENCODE (backup_inst1
.size
, backup_inst1
.relax_size
,
2331 backup_inst1
.type
, 0, 0, relaxable_p
),
2332 backup_inst1
.reloc
.exp
.X_add_symbol
, 0, NULL
);
2335 md_number_to_chars (p
, backup_inst1
.relax_inst
, relax_size
);
2337 memcpy (inst1
, &backup_inst1
, sizeof (struct score_it
));
2341 parse_16_32_inst (char *insnstr
, bfd_boolean gen_frag_p
)
2345 char *operator = insnstr
;
2346 const struct asm_opcode
*opcode
;
2348 /* Parse operator and operands. */
2349 skip_whitespace (operator);
2351 for (p
= operator; *p
!= '\0'; p
++)
2352 if ((*p
== ' ') || (*p
== '!'))
2361 opcode
= (const struct asm_opcode
*) hash_find (score_ops_hsh
, operator);
2364 memset (&inst
, '\0', sizeof (inst
));
2365 sprintf (inst
.str
, "%s", insnstr
);
2368 inst
.instruction
= opcode
->value
;
2369 inst
.relax_inst
= opcode
->relax_value
;
2370 inst
.type
= opcode
->type
;
2371 inst
.size
= GET_INSN_SIZE (inst
.type
);
2372 inst
.relax_size
= 0;
2374 sprintf (inst
.name
, "%s", opcode
->template);
2375 strcpy (inst
.reg
, "");
2377 inst
.reloc
.type
= BFD_RELOC_NONE
;
2379 (*opcode
->parms
) (p
);
2381 /* It indicates current instruction is a macro instruction if inst.bwarn equals -1. */
2382 if ((inst
.bwarn
!= -1) && (!inst
.error
) && (gen_frag_p
))
2383 gen_insn_frag (&inst
, NULL
);
2386 inst
.error
= _("unrecognized opcode");
2390 append_insn (char *str
, bfd_boolean gen_frag_p
)
2392 int retval
= SUCCESS
;
2394 parse_16_32_inst (str
, gen_frag_p
);
2398 retval
= (int) FAIL
;
2399 as_bad (_("%s -- `%s'"), inst
.error
, inst
.str
);
2406 /* Handle mv! reg_high, reg_low;
2407 mv! reg_low, reg_high;
2408 mv! reg_low, reg_low; */
2410 do16_mv_rdrs (char *str
)
2414 char *backupstr
= NULL
;
2417 skip_whitespace (str
);
2419 if ((reg_rd
= reg_required_here (&str
, 8, REG_TYPE_SCORE
)) == (int) FAIL
2420 || skip_past_comma (&str
) == (int) FAIL
2421 || (reg_rs
= reg_required_here (&str
, 4, REG_TYPE_SCORE
)) == (int) FAIL
2422 || end_of_line (str
) == (int) FAIL
)
2428 /* Case 1 : mv! or mlfh!. */
2433 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 20)
2434 | (((inst
.instruction
>> 4) & 0xf) << 15) | (0xf << 10);
2435 inst
.relax_size
= 4;
2439 char append_str
[MAX_LITERAL_POOL_SIZE
];
2441 sprintf (append_str
, _("mlfh! %s"), backupstr
);
2442 if (append_insn (append_str
, TRUE
) == (int) FAIL
)
2444 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
2448 /* Case 2 : mhfl!. */
2453 SET_INSN_ERROR (BAD_ARGS
);
2458 char append_str
[MAX_LITERAL_POOL_SIZE
];
2460 sprintf (append_str
, _("mhfl! %s"), backupstr
);
2461 if (append_insn (append_str
, TRUE
) == (int) FAIL
)
2464 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
2472 do16_rdi4 (char *str
)
2474 skip_whitespace (str
);
2476 if (reglow_required_here (&str
, 8) == (int) FAIL
2477 || skip_past_comma (&str
) == (int) FAIL
2478 || data_op2 (&str
, 3, _IMM4
) == (int) FAIL
2479 || end_of_line (str
) == (int) FAIL
)
2485 if (((inst
.instruction
>> 3) & 0x10) == 0) /* for judge is addei or subei : bit 5 =0 : addei */
2487 if (((inst
.instruction
>> 3) & 0xf) != 0xf)
2489 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 20)
2490 | ((1 << ((inst
.instruction
>> 3) & 0xf)) << 1);
2491 inst
.relax_size
= 4;
2495 inst
.relax_inst
= 0x8000;
2500 if (((inst
.instruction
>> 3) & 0xf) != 0xf)
2502 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 20)
2503 | (((-(1 << ((inst
.instruction
>> 3) & 0xf))) & 0xffff) << 1);
2504 inst
.relax_size
= 4;
2508 inst
.relax_inst
= 0x8000;
2515 do16_rdi5 (char *str
)
2517 skip_whitespace (str
);
2519 if (reglow_required_here (&str
, 8) == (int) FAIL
2520 || skip_past_comma (&str
) == (int) FAIL
2521 || data_op2 (&str
, 3, _IMM5
) == (int) FAIL
2522 || end_of_line (str
) == (int) FAIL
)
2526 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 20)
2527 | (((inst
.instruction
>> 8) & 0xf) << 15) | (((inst
.instruction
>> 3) & 0x1f) << 10);
2528 inst
.relax_size
= 4;
2534 do16_xi5 (char *str
)
2536 skip_whitespace (str
);
2538 if (data_op2 (&str
, 3, _IMM5
) == (int) FAIL
|| end_of_line (str
) == (int) FAIL
)
2542 inst
.relax_inst
|= (((inst
.instruction
>> 3) & 0x1f) << 15);
2543 inst
.relax_size
= 4;
2547 /* Check that an immediate is word alignment or half word alignment.
2548 If so, convert it to the right format. */
2550 validate_immediate_align (int val
, unsigned int data_type
)
2552 if (data_type
== _IMM5_RSHIFT_1
)
2556 inst
.error
= _("address offset must be half word alignment");
2560 else if ((data_type
== _IMM5_RSHIFT_2
) || (data_type
== _IMM10_RSHIFT_2
))
2564 inst
.error
= _("address offset must be word alignment");
2573 exp_ldst_offset (char **str
, int shift
, unsigned int data_type
)
2579 if ((*dataptr
== '0') && (*(dataptr
+ 1) == 'x')
2580 && (data_type
!= _SIMM16_LA
)
2581 && (data_type
!= _VALUE_HI16
)
2582 && (data_type
!= _VALUE_LO16
)
2583 && (data_type
!= _IMM16
)
2584 && (data_type
!= _IMM15
)
2585 && (data_type
!= _IMM14
)
2586 && (data_type
!= _IMM4
)
2587 && (data_type
!= _IMM5
)
2588 && (data_type
!= _IMM8
)
2589 && (data_type
!= _IMM5_RSHIFT_1
)
2590 && (data_type
!= _IMM5_RSHIFT_2
)
2591 && (data_type
!= _SIMM14_NEG
)
2592 && (data_type
!= _IMM10_RSHIFT_2
))
2597 if (my_get_expression (&inst
.reloc
.exp
, str
) == (int) FAIL
)
2600 if (inst
.reloc
.exp
.X_op
== O_constant
)
2602 /* Need to check the immediate align. */
2603 int value
= validate_immediate_align (inst
.reloc
.exp
.X_add_number
, data_type
);
2605 if (value
== (int) FAIL
)
2608 value
= validate_immediate (inst
.reloc
.exp
.X_add_number
, data_type
);
2609 if (value
== (int) FAIL
)
2611 static char err_msg
[255];
2615 _("invalid constant: %d bit expression not in range %d..%d"),
2616 score_df_range
[data_type
].bits
,
2617 score_df_range
[data_type
].range
[0], score_df_range
[data_type
].range
[1]);
2620 _("invalid constant: %d bit expression not in range %d..%d"),
2621 score_df_range
[data_type
- 24].bits
,
2622 score_df_range
[data_type
- 24].range
[0], score_df_range
[data_type
- 24].range
[1]);
2623 inst
.error
= _(err_msg
);
2627 if (data_type
== _IMM5_RSHIFT_1
)
2631 else if ((data_type
== _IMM5_RSHIFT_2
) || (data_type
== _IMM10_RSHIFT_2
))
2636 if (score_df_range
[data_type
].range
[0] != 0)
2638 value
&= (1 << score_df_range
[data_type
].bits
) - 1;
2641 inst
.instruction
|= value
<< shift
;
2645 inst
.reloc
.pc_rel
= 0;
2652 do_ldst_insn (char *str
)
2664 skip_whitespace (str
);
2666 if (((conflict_reg
= reg_required_here (&str
, 20, REG_TYPE_SCORE
)) == (int) FAIL
)
2667 || (skip_past_comma (&str
) == (int) FAIL
))
2670 /* ld/sw rD, [rA, simm15] ld/sw rD, [rA]+, simm12 ld/sw rD, [rA, simm12]+. */
2674 skip_whitespace (str
);
2676 if ((reg
= reg_required_here (&str
, 15, REG_TYPE_SCORE
)) == (int) FAIL
)
2679 /* Conflicts can occur on stores as well as loads. */
2680 conflict_reg
= (conflict_reg
== reg
);
2681 skip_whitespace (str
);
2682 temp
= str
+ 1; /* The latter will process decimal/hex expression. */
2684 /* ld/sw rD, [rA]+, simm12 ld/sw rD, [rA]+. */
2691 /* ld/sw rD, [rA]+, simm12. */
2692 if (skip_past_comma (&str
) == SUCCESS
)
2694 if ((exp_ldst_offset (&str
, 3, _SIMM12
) == (int) FAIL
)
2695 || (end_of_line (str
) == (int) FAIL
))
2700 unsigned int ldst_func
= inst
.instruction
& OPC_PSEUDOLDST_MASK
;
2702 if ((ldst_func
== INSN_LH
)
2703 || (ldst_func
== INSN_LHU
)
2704 || (ldst_func
== INSN_LW
)
2705 || (ldst_func
== INSN_LB
)
2706 || (ldst_func
== INSN_LBU
))
2708 inst
.error
= _("register same as write-back base");
2713 ldst_idx
= inst
.instruction
& OPC_PSEUDOLDST_MASK
;
2714 inst
.instruction
&= ~OPC_PSEUDOLDST_MASK
;
2715 inst
.instruction
|= score_ldst_insns
[ldst_idx
* 3 + LDST_POST
].value
;
2717 /* lw rD, [rA]+, 4 convert to pop rD, [rA]. */
2718 if ((inst
.instruction
& 0x3e000007) == 0x0e000000)
2720 /* rs = r0-r7, offset = 4 */
2721 if ((((inst
.instruction
>> 15) & 0x18) == 0)
2722 && (((inst
.instruction
>> 3) & 0xfff) == 4))
2724 /* Relax to pophi. */
2725 if ((((inst
.instruction
>> 20) & 0x10) == 0x10))
2727 inst
.relax_inst
= 0x0000200a | (((inst
.instruction
>> 20) & 0xf)
2729 (((inst
.instruction
>> 15) & 0x7) << 4);
2734 inst
.relax_inst
= 0x0000200a | (((inst
.instruction
>> 20) & 0xf)
2736 (((inst
.instruction
>> 15) & 0x7) << 4);
2738 inst
.relax_size
= 2;
2743 /* ld/sw rD, [rA]+ convert to ld/sw rD, [rA, 0]+. */
2746 SET_INSN_ERROR (NULL
);
2747 if (end_of_line (str
) == (int) FAIL
)
2753 value
= validate_immediate (inst
.reloc
.exp
.X_add_number
, _SIMM12
);
2754 value
&= (1 << score_df_range
[_SIMM12
].bits
) - 1;
2755 ldst_idx
= inst
.instruction
& OPC_PSEUDOLDST_MASK
;
2756 inst
.instruction
&= ~OPC_PSEUDOLDST_MASK
;
2757 inst
.instruction
|= score_ldst_insns
[ldst_idx
* 3 + pre_inc
].value
;
2758 inst
.instruction
|= value
<< 3;
2759 inst
.relax_inst
= 0x8000;
2763 /* ld/sw rD, [rA] convert to ld/sw rD, [rA, simm15]. */
2766 if (end_of_line (str
) == (int) FAIL
)
2769 ldst_idx
= inst
.instruction
& OPC_PSEUDOLDST_MASK
;
2770 inst
.instruction
&= ~OPC_PSEUDOLDST_MASK
;
2771 inst
.instruction
|= score_ldst_insns
[ldst_idx
* 3 + LDST_NOUPDATE
].value
;
2773 /* lbu rd, [rs] -> lbu! rd, [rs] */
2774 if (ldst_idx
== INSN_LBU
)
2776 inst
.relax_inst
= INSN16_LBU
;
2778 else if (ldst_idx
== INSN_LH
)
2780 inst
.relax_inst
= INSN16_LH
;
2782 else if (ldst_idx
== INSN_LW
)
2784 inst
.relax_inst
= INSN16_LW
;
2786 else if (ldst_idx
== INSN_SB
)
2788 inst
.relax_inst
= INSN16_SB
;
2790 else if (ldst_idx
== INSN_SH
)
2792 inst
.relax_inst
= INSN16_SH
;
2794 else if (ldst_idx
== INSN_SW
)
2796 inst
.relax_inst
= INSN16_SW
;
2800 inst
.relax_inst
= 0x8000;
2803 /* lw/lh/lbu/sw/sh/sb, offset = 0, relax to 16 bit instruction. */
2804 if ((ldst_idx
== INSN_LBU
)
2805 || (ldst_idx
== INSN_LH
)
2806 || (ldst_idx
== INSN_LW
)
2807 || (ldst_idx
== INSN_SB
) || (ldst_idx
== INSN_SH
) || (ldst_idx
== INSN_SW
))
2809 if ((((inst
.instruction
>> 15) & 0x10) == 0) && (((inst
.instruction
>> 20) & 0x10) == 0))
2811 inst
.relax_inst
|= (2 << 12) | (((inst
.instruction
>> 20) & 0xf) << 8) |
2812 (((inst
.instruction
>> 15) & 0xf) << 4);
2813 inst
.relax_size
= 2;
2820 /* ld/sw rD, [rA, simm15] ld/sw rD, [rA, simm12]+. */
2823 if (skip_past_comma (&str
) == (int) FAIL
)
2825 inst
.error
= _("pre-indexed expression expected");
2829 if (my_get_expression (&inst
.reloc
.exp
, &str
) == (int) FAIL
)
2832 skip_whitespace (str
);
2835 inst
.error
= _("missing ]");
2839 skip_whitespace (str
);
2840 /* ld/sw rD, [rA, simm12]+. */
2847 unsigned int ldst_func
= inst
.instruction
& OPC_PSEUDOLDST_MASK
;
2849 if ((ldst_func
== INSN_LH
)
2850 || (ldst_func
== INSN_LHU
)
2851 || (ldst_func
== INSN_LW
)
2852 || (ldst_func
== INSN_LB
)
2853 || (ldst_func
== INSN_LBU
))
2855 inst
.error
= _("register same as write-back base");
2861 if (end_of_line (str
) == (int) FAIL
)
2864 if (inst
.reloc
.exp
.X_op
== O_constant
)
2867 unsigned int data_type
;
2870 data_type
= _SIMM12
;
2872 data_type
= _SIMM15
;
2875 if ((*dataptr
== '0') && (*(dataptr
+ 1) == 'x')
2876 && (data_type
!= _SIMM16_LA
)
2877 && (data_type
!= _VALUE_HI16
)
2878 && (data_type
!= _VALUE_LO16
)
2879 && (data_type
!= _IMM16
)
2880 && (data_type
!= _IMM15
)
2881 && (data_type
!= _IMM14
)
2882 && (data_type
!= _IMM4
)
2883 && (data_type
!= _IMM5
)
2884 && (data_type
!= _IMM8
)
2885 && (data_type
!= _IMM5_RSHIFT_1
)
2886 && (data_type
!= _IMM5_RSHIFT_2
)
2887 && (data_type
!= _SIMM14_NEG
)
2888 && (data_type
!= _IMM10_RSHIFT_2
))
2893 value
= validate_immediate (inst
.reloc
.exp
.X_add_number
, data_type
);
2894 if (value
== (int) FAIL
)
2896 static char err_msg
[255];
2900 _("invalid constant: %d bit expression not in range %d..%d"),
2901 score_df_range
[data_type
].bits
,
2902 score_df_range
[data_type
].range
[0], score_df_range
[data_type
].range
[1]);
2905 _("invalid constant: %d bit expression not in range %d..%d"),
2906 score_df_range
[data_type
- 24].bits
,
2907 score_df_range
[data_type
- 24].range
[0],
2908 score_df_range
[data_type
- 24].range
[1]);
2909 inst
.error
= _(err_msg
);
2913 value
&= (1 << score_df_range
[data_type
].bits
) - 1;
2914 ldst_idx
= inst
.instruction
& OPC_PSEUDOLDST_MASK
;
2915 inst
.instruction
&= ~OPC_PSEUDOLDST_MASK
;
2916 inst
.instruction
|= score_ldst_insns
[ldst_idx
* 3 + pre_inc
].value
;
2918 inst
.instruction
|= value
<< 3;
2920 inst
.instruction
|= value
;
2922 /* lw rD, [rA, simm15] */
2923 if ((inst
.instruction
& 0x3e000000) == 0x20000000)
2925 /* Both rD and rA are in [r0 - r15]. */
2926 if ((((inst
.instruction
>> 15) & 0x10) == 0)
2927 && (((inst
.instruction
>> 20) & 0x10) == 0))
2929 /* simm15 = 0, lw -> lw!. */
2930 if ((inst
.instruction
& 0x7fff) == 0)
2932 inst
.relax_inst
|= (((inst
.instruction
>> 15) & 0xf) << 4)
2933 | (((inst
.instruction
>> 20) & 0xf) << 8);
2934 inst
.relax_size
= 2;
2936 /* rA = r2, lw -> lwp!. */
2937 else if ((((inst
.instruction
>> 15) & 0xf) == 2)
2938 && ((inst
.instruction
& 0x3) == 0)
2939 && ((inst
.instruction
& 0x7fff) < 128))
2941 inst
.relax_inst
= 0x7000 | (((inst
.instruction
>> 20) & 0xf) << 8)
2942 | (((inst
.instruction
& 0x7fff) >> 2) << 3);
2943 inst
.relax_size
= 2;
2947 inst
.relax_inst
= 0x8000;
2952 inst
.relax_inst
= 0x8000;
2955 /* sw rD, [rA, simm15] */
2956 else if ((inst
.instruction
& 0x3e000000) == 0x28000000)
2958 /* Both rD and rA are in [r0 - r15]. */
2959 if ((((inst
.instruction
>> 15) & 0x10) == 0) && (((inst
.instruction
>> 20) & 0x10) == 0))
2961 /* simm15 = 0, sw -> sw!. */
2962 if ((inst
.instruction
& 0x7fff) == 0)
2964 inst
.relax_inst
|= (((inst
.instruction
>> 15) & 0xf) << 4)
2965 | (((inst
.instruction
>> 20) & 0xf) << 8);
2966 inst
.relax_size
= 2;
2968 /* rA = r2, sw -> swp!. */
2969 else if ((((inst
.instruction
>> 15) & 0xf) == 2)
2970 && ((inst
.instruction
& 0x3) == 0)
2971 && ((inst
.instruction
& 0x7fff) < 128))
2973 inst
.relax_inst
= 0x7004 | (((inst
.instruction
>> 20) & 0xf) << 8)
2974 | (((inst
.instruction
& 0x7fff) >> 2) << 3);
2975 inst
.relax_size
= 2;
2979 inst
.relax_inst
= 0x8000;
2984 inst
.relax_inst
= 0x8000;
2987 /* sw rD, [rA, simm15]+ sw pre. */
2988 else if ((inst
.instruction
& 0x3e000007) == 0x06000004)
2990 /* rA is in [r0 - r7], and simm15 = -4. */
2991 if ((((inst
.instruction
>> 15) & 0x18) == 0)
2992 && (((inst
.instruction
>> 3) & 0xfff) == 0xffc))
2994 /* sw -> pushhi!. */
2995 if ((((inst
.instruction
>> 20) & 0x10) == 0x10))
2997 inst
.relax_inst
= 0x0000200e | (((inst
.instruction
>> 20) & 0xf) << 8)
2998 | 1 << 7 | (((inst
.instruction
>> 15) & 0x7) << 4);
2999 inst
.relax_size
= 2;
3004 inst
.relax_inst
= 0x0000200e | (((inst
.instruction
>> 20) & 0xf) << 8)
3005 | 0 << 7 | (((inst
.instruction
>> 15) & 0x7) << 4);
3006 inst
.relax_size
= 2;
3011 inst
.relax_inst
= 0x8000;
3014 /* lh rD, [rA, simm15] */
3015 else if ((inst
.instruction
& 0x3e000000) == 0x22000000)
3017 /* Both rD and rA are in [r0 - r15]. */
3018 if ((((inst
.instruction
>> 15) & 0x10) == 0) && (((inst
.instruction
>> 20) & 0x10) == 0))
3020 /* simm15 = 0, lh -> lh!. */
3021 if ((inst
.instruction
& 0x7fff) == 0)
3023 inst
.relax_inst
|= (((inst
.instruction
>> 15) & 0xf) << 4)
3024 | (((inst
.instruction
>> 20) & 0xf) << 8);
3025 inst
.relax_size
= 2;
3027 /* rA = r2, lh -> lhp!. */
3028 else if ((((inst
.instruction
>> 15) & 0xf) == 2)
3029 && ((inst
.instruction
& 0x1) == 0)
3030 && ((inst
.instruction
& 0x7fff) < 64))
3032 inst
.relax_inst
= 0x7001 | (((inst
.instruction
>> 20) & 0xf) << 8)
3033 | (((inst
.instruction
& 0x7fff) >> 1) << 3);
3034 inst
.relax_size
= 2;
3038 inst
.relax_inst
= 0x8000;
3043 inst
.relax_inst
= 0x8000;
3046 /* sh rD, [rA, simm15] */
3047 else if ((inst
.instruction
& 0x3e000000) == 0x2a000000)
3049 /* Both rD and rA are in [r0 - r15]. */
3050 if ((((inst
.instruction
>> 15) & 0x10) == 0) && (((inst
.instruction
>> 20) & 0x10) == 0))
3052 /* simm15 = 0, sh -> sh!. */
3053 if ((inst
.instruction
& 0x7fff) == 0)
3055 inst
.relax_inst
|= (((inst
.instruction
>> 15) & 0xf) << 4)
3056 | (((inst
.instruction
>> 20) & 0xf) << 8);
3057 inst
.relax_size
= 2;
3059 /* rA = r2, sh -> shp!. */
3060 else if ((((inst
.instruction
>> 15) & 0xf) == 2)
3061 && ((inst
.instruction
& 0x1) == 0)
3062 && ((inst
.instruction
& 0x7fff) < 64))
3064 inst
.relax_inst
= 0x7005 | (((inst
.instruction
>> 20) & 0xf) << 8)
3065 | (((inst
.instruction
& 0x7fff) >> 1) << 3);
3066 inst
.relax_size
= 2;
3070 inst
.relax_inst
= 0x8000;
3075 inst
.relax_inst
= 0x8000;
3078 /* lbu rD, [rA, simm15] */
3079 else if ((inst
.instruction
& 0x3e000000) == 0x2c000000)
3081 /* Both rD and rA are in [r0 - r15]. */
3082 if ((((inst
.instruction
>> 15) & 0x10) == 0) && (((inst
.instruction
>> 20) & 0x10) == 0))
3084 /* simm15 = 0, lbu -> lbu!. */
3085 if ((inst
.instruction
& 0x7fff) == 0)
3087 inst
.relax_inst
|= (((inst
.instruction
>> 15) & 0xf) << 4)
3088 | (((inst
.instruction
>> 20) & 0xf) << 8);
3089 inst
.relax_size
= 2;
3091 /* rA = r2, lbu -> lbup!. */
3092 else if ((((inst
.instruction
>> 15) & 0xf) == 2)
3093 && ((inst
.instruction
& 0x7fff) < 32))
3095 inst
.relax_inst
= 0x7003 | (((inst
.instruction
>> 20) & 0xf) << 8)
3096 | ((inst
.instruction
& 0x7fff) << 3);
3097 inst
.relax_size
= 2;
3101 inst
.relax_inst
= 0x8000;
3106 inst
.relax_inst
= 0x8000;
3109 /* sb rD, [rA, simm15] */
3110 else if ((inst
.instruction
& 0x3e000000) == 0x2e000000)
3112 /* Both rD and rA are in [r0 - r15]. */
3113 if ((((inst
.instruction
>> 15) & 0x10) == 0) && (((inst
.instruction
>> 20) & 0x10) == 0))
3115 /* simm15 = 0, sb -> sb!. */
3116 if ((inst
.instruction
& 0x7fff) == 0)
3118 inst
.relax_inst
|= (((inst
.instruction
>> 15) & 0xf) << 4)
3119 | (((inst
.instruction
>> 20) & 0xf) << 8);
3120 inst
.relax_size
= 2;
3122 /* rA = r2, sb -> sb!. */
3123 else if ((((inst
.instruction
>> 15) & 0xf) == 2)
3124 && ((inst
.instruction
& 0x7fff) < 32))
3126 inst
.relax_inst
= 0x7007 | (((inst
.instruction
>> 20) & 0xf) << 8)
3127 | ((inst
.instruction
& 0x7fff) << 3);
3128 inst
.relax_size
= 2;
3132 inst
.relax_inst
= 0x8000;
3137 inst
.relax_inst
= 0x8000;
3142 inst
.relax_inst
= 0x8000;
3149 /* FIXME: may set error, for there is no ld/sw rD, [rA, label] */
3150 inst
.reloc
.pc_rel
= 0;
3156 inst
.error
= BAD_ARGS
;
3163 do_cache (char *str
)
3165 skip_whitespace (str
);
3167 if ((data_op2 (&str
, 20, _IMM5
) == (int) FAIL
) || (skip_past_comma (&str
) == (int) FAIL
))
3175 cache_op
= (inst
.instruction
>> 20) & 0x1F;
3176 sprintf (inst
.name
, _("cache %d"), cache_op
);
3182 skip_whitespace (str
);
3184 if (reg_required_here (&str
, 15, REG_TYPE_SCORE
) == (int) FAIL
)
3187 skip_whitespace (str
);
3189 /* cache op, [rA] */
3190 if (skip_past_comma (&str
) == (int) FAIL
)
3192 SET_INSN_ERROR (NULL
);
3195 inst
.error
= _("missing ]");
3200 /* cache op, [rA, simm15] */
3203 if (exp_ldst_offset (&str
, 0, _SIMM15
) == (int) FAIL
)
3208 skip_whitespace (str
);
3211 inst
.error
= _("missing ]");
3216 if (end_of_line (str
) == (int) FAIL
)
3221 inst
.error
= BAD_ARGS
;
3226 do_crdcrscrsimm5 (char *str
)
3231 skip_whitespace (str
);
3233 if (reg_required_here (&str
, 20, REG_TYPE_SCORE_CR
) == (int) FAIL
3234 || skip_past_comma (&str
) == (int) FAIL
3235 || reg_required_here (&str
, 15, REG_TYPE_SCORE_CR
) == (int) FAIL
3236 || skip_past_comma (&str
) == (int) FAIL
3237 || reg_required_here (&str
, 10, REG_TYPE_SCORE_CR
) == (int) FAIL
3238 || skip_past_comma (&str
) == (int) FAIL
)
3241 /* cop1 cop_code20. */
3242 if (data_op2 (&str
, 5, _IMM20
) == (int) FAIL
)
3247 if (data_op2 (&str
, 5, _IMM5
) == (int) FAIL
)
3254 /* Handle ldc/stc. */
3256 do_ldst_cop (char *str
)
3258 skip_whitespace (str
);
3260 if ((reg_required_here (&str
, 15, REG_TYPE_SCORE_CR
) == (int) FAIL
)
3261 || (skip_past_comma (&str
) == (int) FAIL
))
3267 skip_whitespace (str
);
3269 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) == (int) FAIL
)
3272 skip_whitespace (str
);
3276 if (exp_ldst_offset (&str
, 5, _IMM10_RSHIFT_2
) == (int) FAIL
)
3279 skip_whitespace (str
);
3282 inst
.error
= _("missing ]");
3290 inst
.error
= BAD_ARGS
;
3294 do16_ldst_insn (char *str
)
3296 skip_whitespace (str
);
3298 if ((reglow_required_here (&str
, 8) == (int) FAIL
) || (skip_past_comma (&str
) == (int) FAIL
))
3306 skip_whitespace (str
);
3308 if ((reg
= reglow_required_here (&str
, 4)) == (int) FAIL
)
3311 skip_whitespace (str
);
3314 if (end_of_line (str
) == (int) FAIL
)
3318 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 20)
3319 | (((inst
.instruction
>> 4) & 0xf) << 15);
3320 inst
.relax_size
= 4;
3325 inst
.error
= _("missing ]");
3330 inst
.error
= BAD_ARGS
;
3334 /* Handle lbup!/lhp!/ldiu!/lwp!/sbp!/shp!/swp!. */
3336 do16_ldst_imm_insn (char *str
)
3338 char data_exp
[MAX_LITERAL_POOL_SIZE
];
3340 char *dataptr
= NULL
, *pp
= NULL
;
3342 int assign_data
= (int) FAIL
;
3343 unsigned int ldst_func
;
3345 skip_whitespace (str
);
3347 if (((reg_rd
= reglow_required_here (&str
, 8)) == (int) FAIL
)
3348 || (skip_past_comma (&str
) == (int) FAIL
))
3351 skip_whitespace (str
);
3354 while ((*dataptr
!= '\0') && (*dataptr
!= '|') && (cnt
<= MAX_LITERAL_POOL_SIZE
))
3356 data_exp
[cnt
] = *dataptr
;
3361 data_exp
[cnt
] = '\0';
3366 ldst_func
= inst
.instruction
& LDST16_RI_MASK
;
3367 if (ldst_func
== N16_LIU
)
3368 assign_data
= exp_ldst_offset (&pp
, 0, _IMM8
);
3369 else if (ldst_func
== N16_LHP
|| ldst_func
== N16_SHP
)
3370 assign_data
= exp_ldst_offset (&pp
, 3, _IMM5_RSHIFT_1
);
3371 else if (ldst_func
== N16_LWP
|| ldst_func
== N16_SWP
)
3372 assign_data
= exp_ldst_offset (&pp
, 3, _IMM5_RSHIFT_2
);
3374 assign_data
= exp_ldst_offset (&pp
, 3, _IMM5
);
3376 if ((assign_data
== (int) FAIL
) || (end_of_line (pp
) == (int) FAIL
))
3380 if ((inst
.instruction
& 0x7000) == N16_LIU
)
3382 inst
.relax_inst
|= ((inst
.instruction
>> 8) & 0xf) << 20
3383 | ((inst
.instruction
& 0xff) << 1);
3385 else if (((inst
.instruction
& 0x7007) == N16_LHP
)
3386 || ((inst
.instruction
& 0x7007) == N16_SHP
))
3388 inst
.relax_inst
|= ((inst
.instruction
>> 8) & 0xf) << 20 | 2 << 15
3389 | (((inst
.instruction
>> 3) & 0x1f) << 1);
3391 else if (((inst
.instruction
& 0x7007) == N16_LWP
)
3392 || ((inst
.instruction
& 0x7007) == N16_SWP
))
3394 inst
.relax_inst
|= ((inst
.instruction
>> 8) & 0xf) << 20 | 2 << 15
3395 | (((inst
.instruction
>> 3) & 0x1f) << 2);
3397 else if (((inst
.instruction
& 0x7007) == N16_LBUP
)
3398 || ((inst
.instruction
& 0x7007) == N16_SBP
))
3400 inst
.relax_inst
|= ((inst
.instruction
>> 8) & 0xf) << 20 | 2 << 15
3401 | (((inst
.instruction
>> 3) & 0x1f));
3404 inst
.relax_size
= 4;
3409 do16_push_pop (char *str
)
3414 skip_whitespace (str
);
3415 if (((reg_rd
= reg_required_here (&str
, 8, REG_TYPE_SCORE
)) == (int) FAIL
)
3416 || (skip_past_comma (&str
) == (int) FAIL
))
3422 /* reg_required_here will change bit 12 of opcode, so we must restore bit 12. */
3423 inst
.instruction
&= ~(1 << 12);
3425 inst
.instruction
|= H_bit_mask
<< 7;
3432 skip_whitespace (str
);
3433 if ((reg
= reg_required_here (&str
, 4, REG_TYPE_SCORE
)) == (int) FAIL
)
3438 inst
.error
= _("base register nums are over 3 bit");
3443 skip_whitespace (str
);
3444 if ((*str
++ != ']') || (end_of_line (str
) == (int) FAIL
))
3447 inst
.error
= _("missing ]");
3453 if ((inst
.instruction
& 0xf) == 0xa)
3457 inst
.relax_inst
|= ((((inst
.instruction
>> 8) & 0xf) | 0x10) << 20)
3458 | (((inst
.instruction
>> 4) & 0x7) << 15) | (4 << 3);
3462 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 20)
3463 | (((inst
.instruction
>> 4) & 0x7) << 15) | (4 << 3);
3471 inst
.relax_inst
|= ((((inst
.instruction
>> 8) & 0xf) | 0x10) << 20)
3472 | (((inst
.instruction
>> 4) & 0x7) << 15) | (((-4) & 0xfff) << 3);
3476 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 20)
3477 | (((inst
.instruction
>> 4) & 0x7) << 15) | (((-4) & 0xfff) << 3);
3480 inst
.relax_size
= 4;
3484 inst
.error
= BAD_ARGS
;
3488 /* Handle lcb/lcw/lce/scb/scw/sce. */
3490 do_ldst_unalign (char *str
)
3494 if (university_version
== 1)
3496 inst
.error
= ERR_FOR_SCORE5U_ATOMIC
;
3500 skip_whitespace (str
);
3502 /* lcb/scb [rA]+. */
3506 skip_whitespace (str
);
3508 if (reg_required_here (&str
, 15, REG_TYPE_SCORE
) == (int) FAIL
)
3515 inst
.error
= _("missing +");
3521 inst
.error
= _("missing ]");
3525 if (end_of_line (str
) == (int) FAIL
)
3528 /* lcw/lce/scb/sce rD, [rA]+. */
3531 if (((conflict_reg
= reg_required_here (&str
, 20, REG_TYPE_SCORE
)) == (int) FAIL
)
3532 || (skip_past_comma (&str
) == (int) FAIL
))
3537 skip_whitespace (str
);
3542 skip_whitespace (str
);
3543 if ((reg
= reg_required_here (&str
, 15, REG_TYPE_SCORE
)) == (int) FAIL
)
3548 /* Conflicts can occur on stores as well as loads. */
3549 conflict_reg
= (conflict_reg
== reg
);
3550 skip_whitespace (str
);
3553 unsigned int ldst_func
= inst
.instruction
& LDST_UNALIGN_MASK
;
3559 as_warn (_("%s register same as write-back base"),
3560 ((ldst_func
& UA_LCE
) || (ldst_func
& UA_LCW
)
3561 ? _("destination") : _("source")));
3566 inst
.error
= _("missing +");
3570 if (end_of_line (str
) == (int) FAIL
)
3575 inst
.error
= _("missing ]");
3581 inst
.error
= BAD_ARGS
;
3587 /* Handle alw/asw. */
3589 do_ldst_atomic (char *str
)
3591 if (university_version
== 1)
3593 inst
.error
= ERR_FOR_SCORE5U_ATOMIC
;
3597 skip_whitespace (str
);
3599 if ((reg_required_here (&str
, 20, REG_TYPE_SCORE
) == (int) FAIL
)
3600 || (skip_past_comma (&str
) == (int) FAIL
))
3607 skip_whitespace (str
);
3612 skip_whitespace (str
);
3613 if ((reg
= reg_required_here (&str
, 15, REG_TYPE_SCORE
)) == (int) FAIL
)
3618 skip_whitespace (str
);
3621 inst
.error
= _("missing ]");
3628 inst
.error
= BAD_ARGS
;
3633 build_relax_frag (struct score_it fix_insts
[RELAX_INST_NUM
], int fix_num ATTRIBUTE_UNUSED
,
3634 struct score_it var_insts
[RELAX_INST_NUM
], int var_num
,
3635 symbolS
*add_symbol
)
3640 fixS
*cur_fixp
= NULL
;
3642 struct score_it inst_main
;
3644 memcpy (&inst_main
, &fix_insts
[0], sizeof (struct score_it
));
3646 /* Adjust instruction opcode and to be relaxed instruction opcode. */
3647 inst_main
.instruction
= adjust_paritybit (inst_main
.instruction
, GET_INSN_CLASS (inst_main
.type
));
3648 inst_main
.type
= Insn_PIC
;
3650 for (i
= 0; i
< var_num
; i
++)
3652 inst_main
.relax_size
+= var_insts
[i
].size
;
3653 var_insts
[i
].instruction
= adjust_paritybit (var_insts
[i
].instruction
,
3654 GET_INSN_CLASS (var_insts
[i
].type
));
3657 /* Check data dependency. */
3658 handle_dependency (&inst_main
);
3660 /* Start a new frag if frag_now is not empty. */
3661 if (frag_now_fix () != 0)
3663 if (!frag_now
->tc_frag_data
.is_insn
)
3665 frag_wane (frag_now
);
3671 /* Write fr_fix part. */
3672 p
= frag_more (inst_main
.size
);
3673 md_number_to_chars (p
, inst_main
.instruction
, inst_main
.size
);
3675 if (inst_main
.reloc
.type
!= BFD_RELOC_NONE
)
3676 fixp
= fix_new_score (frag_now
, p
- frag_now
->fr_literal
, inst_main
.size
,
3677 &inst_main
.reloc
.exp
, inst_main
.reloc
.pc_rel
, inst_main
.reloc
.type
);
3679 frag_now
->tc_frag_data
.fixp
= fixp
;
3680 cur_fixp
= frag_now
->tc_frag_data
.fixp
;
3683 dwarf2_emit_insn (inst_main
.size
);
3686 where
= p
- frag_now
->fr_literal
+ inst_main
.size
;
3687 for (i
= 0; i
< var_num
; i
++)
3690 where
+= var_insts
[i
- 1].size
;
3692 if (var_insts
[i
].reloc
.type
!= BFD_RELOC_NONE
)
3694 fixp
= fix_new_score (frag_now
, where
, var_insts
[i
].size
,
3695 &var_insts
[i
].reloc
.exp
, var_insts
[i
].reloc
.pc_rel
,
3696 var_insts
[i
].reloc
.type
);
3701 cur_fixp
->fx_next
= fixp
;
3702 cur_fixp
= cur_fixp
->fx_next
;
3706 frag_now
->tc_frag_data
.fixp
= fixp
;
3707 cur_fixp
= frag_now
->tc_frag_data
.fixp
;
3713 p
= frag_var (rs_machine_dependent
, inst_main
.relax_size
+ RELAX_PAD_BYTE
, 0,
3714 RELAX_ENCODE (inst_main
.size
, inst_main
.relax_size
, inst_main
.type
,
3715 0, inst_main
.size
, 0), add_symbol
, 0, NULL
);
3717 /* Write fr_var part.
3718 no calling gen_insn_frag, no fixS will be generated. */
3719 for (i
= 0; i
< var_num
; i
++)
3721 md_number_to_chars (p
, var_insts
[i
].instruction
, var_insts
[i
].size
);
3722 p
+= var_insts
[i
].size
;
3724 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
3728 /* Build a relax frag for la instruction when generating PIC,
3729 external symbol first and local symbol second. */
3732 build_la_pic (int reg_rd
, expressionS exp
)
3734 symbolS
*add_symbol
= exp
.X_add_symbol
;
3735 offsetT add_number
= exp
.X_add_number
;
3736 struct score_it fix_insts
[RELAX_INST_NUM
];
3737 struct score_it var_insts
[RELAX_INST_NUM
];
3740 char tmp
[MAX_LITERAL_POOL_SIZE
];
3746 if (add_number
== 0)
3751 /* For an external symbol, only one insn is generated;
3752 For a local symbol, two insns are generated. */
3754 For an external symbol: lw rD, <sym>($gp)
3755 (BFD_RELOC_SCORE_GOT15 or BFD_RELOC_SCORE_CALL15) */
3756 sprintf (tmp
, _("lw_pic r%d, %s"), reg_rd
, add_symbol
->bsym
->name
);
3757 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
3760 if (reg_rd
== PIC_CALL_REG
)
3761 inst
.reloc
.type
= BFD_RELOC_SCORE_CALL15
;
3762 memcpy (&fix_insts
[0], &inst
, sizeof (struct score_it
));
3765 For a local symbol :
3766 lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15)
3767 addi rD, <sym> (BFD_RELOC_GOT_LO16) */
3768 inst
.reloc
.type
= BFD_RELOC_SCORE_GOT15
;
3769 memcpy (&var_insts
[0], &inst
, sizeof (struct score_it
));
3770 sprintf (tmp
, _("addi_s_pic r%d, %s"), reg_rd
, add_symbol
->bsym
->name
);
3771 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
3774 memcpy (&var_insts
[1], &inst
, sizeof (struct score_it
));
3775 build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
3777 else if (add_number
>= -0x8000 && add_number
<= 0x7fff)
3779 /* Insn 1: lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15) */
3780 sprintf (tmp
, _("lw_pic r%d, %s"), reg_rd
, add_symbol
->bsym
->name
);
3781 if (append_insn (tmp
, TRUE
) == (int) FAIL
)
3788 For an external symbol: addi rD, <constant> */
3789 sprintf (tmp
, _("addi r%d, %d"), reg_rd
, (int)add_number
);
3790 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
3793 memcpy (&fix_insts
[0], &inst
, sizeof (struct score_it
));
3796 For a local symbol: addi rD, <sym>+<constant> (BFD_RELOC_GOT_LO16) */
3797 sprintf (tmp
, _("addi_s_pic r%d, %s + %d"), reg_rd
, add_symbol
->bsym
->name
, (int)add_number
);
3798 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
3801 memcpy (&var_insts
[0], &inst
, sizeof (struct score_it
));
3802 build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
3806 int hi
= (add_number
>> 16) & 0x0000FFFF;
3807 int lo
= add_number
& 0x0000FFFF;
3809 /* Insn 1: lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15) */
3810 sprintf (tmp
, _("lw_pic r%d, %s"), reg_rd
, add_symbol
->bsym
->name
);
3811 if (append_insn (tmp
, TRUE
) == (int) FAIL
)
3818 For an external symbol: ldis r1, HI%<constant> */
3819 sprintf (tmp
, _("ldis %s, %d"), _("r1"), hi
);
3820 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
3823 memcpy (&fix_insts
[0], &inst
, sizeof (struct score_it
));
3826 For a local symbol: ldis r1, HI%<constant>
3827 but, if lo is outof 16 bit, make hi plus 1 */
3828 if ((lo
< -0x8000) || (lo
> 0x7fff))
3832 sprintf (tmp
, _("ldis_pic %s, %d"), _("r1"), hi
);
3833 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
3836 memcpy (&var_insts
[0], &inst
, sizeof (struct score_it
));
3837 build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
3843 For an external symbol: ori r1, LO%<constant> */
3844 sprintf (tmp
, _("ori %s, %d"), _("r1"), lo
);
3845 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
3848 memcpy (&fix_insts
[0], &inst
, sizeof (struct score_it
));
3851 For a local symbol: addi r1, <sym>+LO%<constant> (BFD_RELOC_GOT_LO16) */
3852 sprintf (tmp
, _("addi_u_pic %s, %s + %d"), _("r1"), add_symbol
->bsym
->name
, lo
);
3853 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
3856 memcpy (&var_insts
[0], &inst
, sizeof (struct score_it
));
3857 build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
3859 /* Insn 4: add rD, rD, r1 */
3860 sprintf (tmp
, _("add r%d, r%d, %s"), reg_rd
, reg_rd
, _("r1"));
3861 if (append_insn (tmp
, TRUE
) == (int) FAIL
)
3864 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
3873 do_macro_la_rdi32 (char *str
)
3877 skip_whitespace (str
);
3878 if ((reg_rd
= reg_required_here (&str
, 20, REG_TYPE_SCORE
)) == (int) FAIL
3879 || skip_past_comma (&str
) == (int) FAIL
)
3885 char append_str
[MAX_LITERAL_POOL_SIZE
];
3886 char *keep_data
= str
;
3888 /* la rd, simm16. */
3889 if (data_op2 (&str
, 1, _SIMM16_LA
) != (int) FAIL
)
3894 /* la rd, imm32 or la rd, label. */
3897 SET_INSN_ERROR (NULL
);
3899 if ((data_op2 (&str
, 1, _VALUE_HI16
) == (int) FAIL
)
3900 || (end_of_line (str
) == (int) FAIL
))
3906 if ((score_pic
== NO_PIC
) || (!inst
.reloc
.exp
.X_add_symbol
))
3908 sprintf (append_str
, _("ld_i32hi r%d, %s"), reg_rd
, keep_data
);
3909 if (append_insn (append_str
, TRUE
) == (int) FAIL
)
3912 sprintf (append_str
, _("ld_i32lo r%d, %s"), reg_rd
, keep_data
);
3913 if (append_insn (append_str
, TRUE
) == (int) FAIL
)
3918 assert (inst
.reloc
.exp
.X_add_symbol
);
3919 build_la_pic (reg_rd
, inst
.reloc
.exp
);
3922 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
3931 do_macro_li_rdi32 (char *str
){
3935 skip_whitespace (str
);
3936 if ((reg_rd
= reg_required_here (&str
, 20, REG_TYPE_SCORE
)) == (int) FAIL
3937 || skip_past_comma (&str
) == (int) FAIL
)
3943 char *keep_data
= str
;
3945 /* li rd, simm16. */
3946 if (data_op2 (&str
, 1, _SIMM16_LA
) != (int) FAIL
)
3954 char append_str
[MAX_LITERAL_POOL_SIZE
];
3958 if ((data_op2 (&str
, 1, _VALUE_HI16
) == (int) FAIL
)
3959 || (end_of_line (str
) == (int) FAIL
))
3963 else if (inst
.reloc
.exp
.X_add_symbol
)
3965 inst
.error
= _("li rd label isn't correct instruction form");
3970 sprintf (append_str
, _("ld_i32hi r%d, %s"), reg_rd
, keep_data
);
3972 if (append_insn (append_str
, TRUE
) == (int) FAIL
)
3976 sprintf (append_str
, _("ld_i32lo r%d, %s"), reg_rd
, keep_data
);
3977 if (append_insn (append_str
, TRUE
) == (int) FAIL
)
3980 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
3988 /* Handle mul/mulu/div/divu/rem/remu. */
3990 do_macro_mul_rdrsrs (char *str
)
3996 char append_str
[MAX_LITERAL_POOL_SIZE
];
3998 if (university_version
== 1)
3999 as_warn ("%s", ERR_FOR_SCORE5U_MUL_DIV
);
4001 strcpy (append_str
, str
);
4002 backupstr
= append_str
;
4003 skip_whitespace (backupstr
);
4004 if (((reg_rd
= reg_required_here (&backupstr
, -1, REG_TYPE_SCORE
)) == (int) FAIL
)
4005 || (skip_past_comma (&backupstr
) == (int) FAIL
)
4006 || ((reg_rs1
= reg_required_here (&backupstr
, -1, REG_TYPE_SCORE
)) == (int) FAIL
))
4008 inst
.error
= BAD_ARGS
;
4012 if (skip_past_comma (&backupstr
) == (int) FAIL
)
4014 /* rem/remu rA, rB is error format. */
4015 if (strcmp (inst
.name
, "rem") == 0 || strcmp (inst
.name
, "remu") == 0)
4017 SET_INSN_ERROR (BAD_ARGS
);
4021 SET_INSN_ERROR (NULL
);
4028 SET_INSN_ERROR (NULL
);
4029 if (((reg_rs2
= reg_required_here (&backupstr
, -1, REG_TYPE_SCORE
)) == (int) FAIL
)
4030 || (end_of_line (backupstr
) == (int) FAIL
))
4036 char append_str1
[MAX_LITERAL_POOL_SIZE
];
4038 if (strcmp (inst
.name
, "rem") == 0)
4040 sprintf (append_str
, _("%s r%d, r%d"), _("mul"), reg_rs1
, reg_rs2
);
4041 sprintf (append_str1
, _("mfceh r%d"), reg_rd
);
4043 else if (strcmp (inst
.name
, "remu") == 0)
4045 sprintf (append_str
, _("%s r%d, r%d"), _("mulu"), reg_rs1
, reg_rs2
);
4046 sprintf (append_str1
, _("mfceh r%d"), reg_rd
);
4050 sprintf (append_str
, _("%s r%d, r%d"), inst
.name
, reg_rs1
, reg_rs2
);
4051 sprintf (append_str1
, _("mfcel r%d"), reg_rd
);
4054 /* Output mul/mulu or div/divu or rem/remu. */
4055 if (append_insn (append_str
, TRUE
) == (int) FAIL
)
4058 /* Output mfcel or mfceh. */
4059 if (append_insn (append_str1
, TRUE
) == (int) FAIL
)
4062 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4069 exp_macro_ldst_abs (char *str
)
4072 char *backupstr
, *tmp
;
4073 char append_str
[MAX_LITERAL_POOL_SIZE
];
4074 char verifystr
[MAX_LITERAL_POOL_SIZE
];
4075 struct score_it inst_backup
;
4080 memcpy (&inst_backup
, &inst
, sizeof (struct score_it
));
4082 strcpy (verifystr
, str
);
4083 backupstr
= verifystr
;
4084 skip_whitespace (backupstr
);
4085 if ((reg_rd
= reg_required_here (&backupstr
, -1, REG_TYPE_SCORE
)) == (int) FAIL
)
4089 if (skip_past_comma (&backupstr
) == (int) FAIL
)
4093 sprintf (append_str
, _("li r1 %s"), backupstr
);
4094 append_insn (append_str
, TRUE
);
4096 memcpy (&inst
, &inst_backup
, sizeof (struct score_it
));
4097 sprintf (append_str
, _(" r%d, [r1,0]"), reg_rd
);
4098 do_ldst_insn (append_str
);
4104 nopic_need_relax (symbolS
* sym
, int before_relaxing
)
4108 else if (USE_GLOBAL_POINTER_OPT
&& g_switch_value
> 0)
4110 const char *symname
;
4111 const char *segname
;
4113 /* Find out whether this symbol can be referenced off the $gp
4114 register. It can be if it is smaller than the -G size or if
4115 it is in the .sdata or .sbss section. Certain symbols can
4116 not be referenced off the $gp, although it appears as though
4118 symname
= S_GET_NAME (sym
);
4119 if (symname
!= (const char *)NULL
4120 && (strcmp (symname
, "eprol") == 0
4121 || strcmp (symname
, "etext") == 0
4122 || strcmp (symname
, "_gp") == 0
4123 || strcmp (symname
, "edata") == 0
4124 || strcmp (symname
, "_fbss") == 0
4125 || strcmp (symname
, "_fdata") == 0
4126 || strcmp (symname
, "_ftext") == 0
4127 || strcmp (symname
, "end") == 0
4128 || strcmp (symname
, GP_DISP_LABEL
) == 0))
4132 else if ((!S_IS_DEFINED (sym
) || S_IS_COMMON (sym
)) && (0
4133 /* We must defer this decision until after the whole file has been read,
4134 since there might be a .extern after the first use of this symbol. */
4136 && S_GET_VALUE (sym
) == 0)
4137 || (S_GET_VALUE (sym
) != 0
4138 && S_GET_VALUE (sym
) <= g_switch_value
)))
4143 segname
= segment_name (S_GET_SEGMENT (sym
));
4144 return (strcmp (segname
, ".sdata") != 0
4145 && strcmp (segname
, ".sbss") != 0
4146 && strncmp (segname
, ".sdata.", 7) != 0
4147 && strncmp (segname
, ".gnu.linkonce.s.", 16) != 0);
4149 /* We are not optimizing for the $gp register. */
4154 /* Build a relax frag for lw/st instruction when generating PIC,
4155 external symbol first and local symbol second. */
4158 build_lwst_pic (int reg_rd
, expressionS exp
, const char *insn_name
)
4160 symbolS
*add_symbol
= exp
.X_add_symbol
;
4161 int add_number
= exp
.X_add_number
;
4162 struct score_it fix_insts
[RELAX_INST_NUM
];
4163 struct score_it var_insts
[RELAX_INST_NUM
];
4166 char tmp
[MAX_LITERAL_POOL_SIZE
];
4172 if ((add_number
== 0) || (add_number
>= -0x8000 && add_number
<= 0x7fff))
4177 /* For an external symbol, two insns are generated;
4178 For a local symbol, three insns are generated. */
4180 For an external symbol: lw rD, <sym>($gp)
4181 (BFD_RELOC_SCORE_GOT15) */
4182 sprintf (tmp
, _("lw_pic %s, %s"), _("r1"), add_symbol
->bsym
->name
);
4183 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
4186 memcpy (&fix_insts
[0], &inst
, sizeof (struct score_it
));
4189 For a local symbol :
4190 lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15)
4191 addi rD, <sym> (BFD_RELOC_GOT_LO16) */
4192 inst
.reloc
.type
= BFD_RELOC_SCORE_GOT15
;
4193 memcpy (&var_insts
[0], &inst
, sizeof (struct score_it
));
4194 sprintf (tmp
, _("addi_s_pic %s, %s"), _("r1"), add_symbol
->bsym
->name
);
4195 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
4198 memcpy (&var_insts
[1], &inst
, sizeof (struct score_it
));
4199 build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
4201 /* Insn 2 or Insn 3: lw/st rD, [r1, constant] */
4202 sprintf (tmp
, _("%s r%d, [%s, %d]"), insn_name
, reg_rd
, _("r1"), add_number
);
4203 if (append_insn (tmp
, TRUE
) == (int) FAIL
)
4206 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4211 inst
.error
= _("PIC code offset overflow (max 16 signed bits)");
4219 do_macro_ldst_label (char *str
)
4227 char *absolute_value
;
4228 char append_str
[3][MAX_LITERAL_POOL_SIZE
];
4229 char verifystr
[MAX_LITERAL_POOL_SIZE
];
4230 struct score_it inst_backup
;
4231 struct score_it inst_expand
[3];
4232 struct score_it inst_main
;
4234 memcpy (&inst_backup
, &inst
, sizeof (struct score_it
));
4235 strcpy (verifystr
, str
);
4236 backup_str
= verifystr
;
4238 skip_whitespace (backup_str
);
4239 if ((reg_rd
= reg_required_here (&backup_str
, -1, REG_TYPE_SCORE
)) == (int) FAIL
)
4242 if (skip_past_comma (&backup_str
) == (int) FAIL
)
4245 label_str
= backup_str
;
4247 /* Ld/st rD, [rA, imm] ld/st rD, [rA]+, imm ld/st rD, [rA, imm]+. */
4248 if (*backup_str
== '[')
4250 inst
.type
= Rd_rvalueRs_preSI12
;
4255 /* Ld/st rD, imm. */
4256 absolute_value
= backup_str
;
4257 inst
.type
= Rd_rvalueRs_SI15
;
4258 if ((my_get_expression (&inst
.reloc
.exp
, &backup_str
) == (int) FAIL
)
4259 || (validate_immediate (inst
.reloc
.exp
.X_add_number
, _VALUE
) == (int) FAIL
)
4260 || (end_of_line (backup_str
) == (int) FAIL
))
4266 if (inst
.reloc
.exp
.X_add_symbol
== 0)
4268 memcpy (&inst
, &inst_backup
, sizeof (struct score_it
));
4269 exp_macro_ldst_abs (str
);
4274 /* Ld/st rD, label. */
4275 inst
.type
= Rd_rvalueRs_SI15
;
4276 backup_str
= absolute_value
;
4277 if ((data_op2 (&backup_str
, 1, _GP_IMM15
) == (int) FAIL
)
4278 || (end_of_line (backup_str
) == (int) FAIL
))
4284 if (inst
.reloc
.exp
.X_add_symbol
== 0)
4287 inst
.error
= BAD_ARGS
;
4292 if (score_pic
== PIC
)
4295 ldst_idx
= inst
.instruction
& OPC_PSEUDOLDST_MASK
;
4296 build_lwst_pic (reg_rd
, inst
.reloc
.exp
, score_ldst_insns
[ldst_idx
* 3 + 0].template);
4301 if ((inst
.reloc
.exp
.X_add_number
<= 0x3fff)
4302 && (inst
.reloc
.exp
.X_add_number
>= -0x4000)
4303 && (!nopic_need_relax (inst
.reloc
.exp
.X_add_symbol
, 1)))
4307 /* Assign the real opcode. */
4308 ldst_idx
= inst
.instruction
& OPC_PSEUDOLDST_MASK
;
4309 inst
.instruction
&= ~OPC_PSEUDOLDST_MASK
;
4310 inst
.instruction
|= score_ldst_insns
[ldst_idx
* 3 + 0].value
;
4311 inst
.instruction
|= reg_rd
<< 20;
4312 inst
.instruction
|= GP
<< 15;
4313 inst
.relax_inst
= 0x8000;
4314 inst
.relax_size
= 0;
4321 memcpy (&inst_main
, &inst
, sizeof (struct score_it
));
4325 /* Determine which instructions should be output. */
4326 sprintf (append_str
[0], _("ld_i32hi r1, %s"), label_str
);
4327 sprintf (append_str
[1], _("ld_i32lo r1, %s"), label_str
);
4328 sprintf (append_str
[2], _("%s r%d, [r1, 0]"), inst_backup
.name
, reg_rd
);
4330 /* Generate three instructions.
4332 ld/st rd, [r1, 0] */
4333 for (i
= 0; i
< 3; i
++)
4335 if (append_insn (append_str
[i
], FALSE
) == (int) FAIL
)
4338 memcpy (&inst_expand
[i
], &inst
, sizeof (struct score_it
));
4345 /* Adjust instruction opcode and to be relaxed instruction opcode. */
4346 inst_main
.instruction
= adjust_paritybit (inst_main
.instruction
, GET_INSN_CLASS (inst_main
.type
));
4347 inst_main
.relax_size
= inst_expand
[0].size
+ inst_expand
[1].size
+ inst_expand
[2].size
;
4348 inst_main
.type
= Insn_GP
;
4350 for (i
= 0; i
< 3; i
++)
4351 inst_expand
[i
].instruction
= adjust_paritybit (inst_expand
[i
].instruction
4352 , GET_INSN_CLASS (inst_expand
[i
].type
));
4354 /* Check data dependency. */
4355 handle_dependency (&inst_main
);
4357 /* Start a new frag if frag_now is not empty. */
4358 if (frag_now_fix () != 0)
4360 if (!frag_now
->tc_frag_data
.is_insn
)
4361 frag_wane (frag_now
);
4367 /* Write fr_fix part. */
4368 p
= frag_more (inst_main
.size
);
4369 md_number_to_chars (p
, inst_main
.instruction
, inst_main
.size
);
4371 if (inst_main
.reloc
.type
!= BFD_RELOC_NONE
)
4373 fix_new_score (frag_now
, p
- frag_now
->fr_literal
, inst_main
.size
,
4374 &inst_main
.reloc
.exp
, inst_main
.reloc
.pc_rel
, inst_main
.reloc
.type
);
4378 dwarf2_emit_insn (inst_main
.size
);
4381 /* GP instruction can not do optimization, only can do relax between
4382 1 instruction and 3 instructions. */
4383 p
= frag_var (rs_machine_dependent
, inst_main
.relax_size
+ RELAX_PAD_BYTE
, 0,
4384 RELAX_ENCODE (inst_main
.size
, inst_main
.relax_size
, inst_main
.type
, 0, 4, 0),
4385 inst_main
.reloc
.exp
.X_add_symbol
, 0, NULL
);
4387 /* Write fr_var part.
4388 no calling gen_insn_frag, no fixS will be generated. */
4389 md_number_to_chars (p
, inst_expand
[0].instruction
, inst_expand
[0].size
);
4390 p
+= inst_expand
[0].size
;
4391 md_number_to_chars (p
, inst_expand
[1].instruction
, inst_expand
[1].size
);
4392 p
+= inst_expand
[1].size
;
4393 md_number_to_chars (p
, inst_expand
[2].instruction
, inst_expand
[2].size
);
4397 gen_insn_frag (&inst_expand
[0], NULL
);
4398 gen_insn_frag (&inst_expand
[1], NULL
);
4399 gen_insn_frag (&inst_expand
[2], NULL
);
4403 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4408 do_lw_pic (char *str
)
4412 skip_whitespace (str
);
4413 if (((reg_rd
= reg_required_here (&str
, 20, REG_TYPE_SCORE
)) == (int) FAIL
)
4414 || (skip_past_comma (&str
) == (int) FAIL
)
4415 || (my_get_expression (&inst
.reloc
.exp
, &str
) == (int) FAIL
)
4416 || (end_of_line (str
) == (int) FAIL
))
4422 if (inst
.reloc
.exp
.X_add_symbol
== 0)
4425 inst
.error
= BAD_ARGS
;
4430 inst
.instruction
|= GP
<< 15;
4431 inst
.reloc
.type
= BFD_RELOC_SCORE_GOT15
;
4436 do_empty (char *str
)
4439 if (university_version
== 1)
4441 if (((inst
.instruction
& 0x3e0003ff) == 0x0c000004)
4442 || ((inst
.instruction
& 0x3e0003ff) == 0x0c000024)
4443 || ((inst
.instruction
& 0x3e0003ff) == 0x0c000044)
4444 || ((inst
.instruction
& 0x3e0003ff) == 0x0c000064))
4446 inst
.error
= ERR_FOR_SCORE5U_MMU
;
4450 if (end_of_line (str
) == (int) FAIL
)
4453 if (inst
.relax_inst
!= 0x8000)
4455 if (inst
.type
== NO_OPD
)
4457 inst
.relax_size
= 2;
4461 inst
.relax_size
= 4;
4470 static char err_msg
[100];
4472 skip_whitespace (str
);
4473 if (my_get_expression (&inst
.reloc
.exp
, &str
) == (int) FAIL
4474 || end_of_line (str
) == (int) FAIL
)
4477 if (inst
.reloc
.exp
.X_add_symbol
== 0)
4479 inst
.error
= _("lacking label ");
4483 if (((inst
.reloc
.exp
.X_add_number
& 0xff000000) != 0)
4484 && ((inst
.reloc
.exp
.X_add_number
& 0xff000000) != 0xff000000))
4486 sprintf (err_msg
, _("invalid constant: 25 bit expression not in range -2^24..2^24"));
4487 inst
.error
= _(err_msg
);
4491 save_in
= input_line_pointer
;
4492 input_line_pointer
= str
;
4493 inst
.reloc
.type
= BFD_RELOC_SCORE_JMP
;
4494 inst
.reloc
.pc_rel
= 1;
4495 input_line_pointer
= save_in
;
4499 do16_jump (char *str
)
4501 skip_whitespace (str
);
4502 if (my_get_expression (&inst
.reloc
.exp
, &str
) == (int) FAIL
4503 || end_of_line (str
) == (int) FAIL
)
4507 else if (inst
.reloc
.exp
.X_add_symbol
== 0)
4509 inst
.error
= _("lacking label ");
4512 else if (((inst
.reloc
.exp
.X_add_number
& 0xfffff800) != 0)
4513 && ((inst
.reloc
.exp
.X_add_number
& 0xfffff800) != 0xfffff800))
4515 inst
.error
= _("invalid constant: 12 bit expression not in range -2^11..2^11");
4519 inst
.reloc
.type
= BFD_RELOC_SCORE16_JMP
;
4520 inst
.reloc
.pc_rel
= 1;
4524 do_branch (char *str
)
4526 unsigned long abs_value
= 0;
4528 if (my_get_expression (&inst
.reloc
.exp
, &str
) == (int) FAIL
4529 || end_of_line (str
) == (int) FAIL
)
4533 else if (inst
.reloc
.exp
.X_add_symbol
== 0)
4535 inst
.error
= _("lacking label ");
4538 else if (((inst
.reloc
.exp
.X_add_number
& 0xff000000) != 0)
4539 && ((inst
.reloc
.exp
.X_add_number
& 0xff000000) != 0xff000000))
4541 inst
.error
= _("invalid constant: 20 bit expression not in range -2^19..2^19");
4545 inst
.reloc
.type
= BFD_RELOC_SCORE_BRANCH
;
4546 inst
.reloc
.pc_rel
= 1;
4548 /* Branch 32 offset field : 20 bit, 16 bit branch offset field : 8 bit. */
4549 inst
.instruction
|= (inst
.reloc
.exp
.X_add_number
& 0x3fe) | ((inst
.reloc
.exp
.X_add_number
& 0xffc00) << 5);
4551 /* Compute 16 bit branch instruction. */
4552 if ((inst
.relax_inst
!= 0x8000) && (abs_value
& 0xfffffe00) == 0)
4554 inst
.relax_inst
|= (((inst
.instruction
>> 10) & 0xf) << 8);
4555 inst
.relax_inst
|= ((inst
.reloc
.exp
.X_add_number
>> 1) & 0xff);
4556 inst
.relax_size
= 2;
4560 inst
.relax_inst
= 0x8000;
4565 do16_branch (char *str
)
4567 if ((my_get_expression (&inst
.reloc
.exp
, &str
) == (int) FAIL
4568 || end_of_line (str
) == (int) FAIL
))
4572 else if (inst
.reloc
.exp
.X_add_symbol
== 0)
4574 inst
.error
= _("lacking label");
4576 else if (((inst
.reloc
.exp
.X_add_number
& 0xffffff00) != 0)
4577 && ((inst
.reloc
.exp
.X_add_number
& 0xffffff00) != 0xffffff00))
4579 inst
.error
= _("invalid constant: 9 bit expression not in range -2^8..2^8");
4583 inst
.reloc
.type
= BFD_RELOC_SCORE16_BRANCH
;
4584 inst
.reloc
.pc_rel
= 1;
4585 inst
.instruction
|= ((inst
.reloc
.exp
.X_add_number
>> 1) & 0xff);
4589 /* Iterate over the base tables to create the instruction patterns. */
4591 build_score_ops_hsh (void)
4594 static struct obstack insn_obstack
;
4596 obstack_begin (&insn_obstack
, 4000);
4597 for (i
= 0; i
< sizeof (score_insns
) / sizeof (struct asm_opcode
); i
++)
4599 const struct asm_opcode
*insn
= score_insns
+ i
;
4600 unsigned len
= strlen (insn
->template);
4601 struct asm_opcode
*new;
4603 new = obstack_alloc (&insn_obstack
, sizeof (struct asm_opcode
));
4604 template = obstack_alloc (&insn_obstack
, len
+ 1);
4606 strcpy (template, insn
->template);
4607 new->template = template;
4608 new->parms
= insn
->parms
;
4609 new->value
= insn
->value
;
4610 new->relax_value
= insn
->relax_value
;
4611 new->type
= insn
->type
;
4612 new->bitmask
= insn
->bitmask
;
4613 hash_insert (score_ops_hsh
, new->template, (void *) new);
4618 build_dependency_insn_hsh (void)
4621 static struct obstack dependency_obstack
;
4623 obstack_begin (&dependency_obstack
, 4000);
4624 for (i
= 0; i
< sizeof (insn_to_dependency_table
) / sizeof (insn_to_dependency_table
[0]); i
++)
4626 const struct insn_to_dependency
*tmp
= insn_to_dependency_table
+ i
;
4627 unsigned len
= strlen (tmp
->insn_name
);
4628 struct insn_to_dependency
*new;
4630 new = obstack_alloc (&dependency_obstack
, sizeof (struct insn_to_dependency
));
4631 new->insn_name
= obstack_alloc (&dependency_obstack
, len
+ 1);
4633 strcpy (new->insn_name
, tmp
->insn_name
);
4634 new->type
= tmp
->type
;
4635 hash_insert (dependency_insn_hsh
, new->insn_name
, (void *) new);
4639 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
4640 for use in the a.out file, and stores them in the array pointed to by buf.
4641 This knows about the endian-ness of the target machine and does
4642 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
4643 2 (short) and 4 (long) Floating numbers are put out as a series of
4644 LITTLENUMS (shorts, here at least). */
4647 md_number_to_chars (char *buf
, valueT val
, int n
)
4649 if (target_big_endian
)
4650 number_to_chars_bigendian (buf
, val
, n
);
4652 number_to_chars_littleendian (buf
, val
, n
);
4656 md_chars_to_number (char *buf
, int n
)
4659 unsigned char *where
= (unsigned char *)buf
;
4661 if (target_big_endian
)
4666 result
|= (*where
++ & 255);
4674 result
|= (where
[n
] & 255);
4681 /* Turn a string in input_line_pointer into a floating point constant
4682 of type TYPE, and store the appropriate bytes in *LITP. The number
4683 of LITTLENUMS emitted is stored in *SIZEP. An error message is
4684 returned, or NULL on OK.
4686 Note that fp constants aren't represent in the normal way on the ARM.
4687 In big endian mode, things are as expected. However, in little endian
4688 mode fp constants are big-endian word-wise, and little-endian byte-wise
4689 within the words. For example, (double) 1.1 in big endian mode is
4690 the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
4691 the byte sequence 99 99 f1 3f 9a 99 99 99. */
4694 md_atof (int type
, char *litP
, int *sizeP
)
4697 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
4723 return _("bad call to MD_ATOF()");
4726 t
= atof_ieee (input_line_pointer
, type
, words
);
4728 input_line_pointer
= t
;
4731 if (target_big_endian
)
4733 for (i
= 0; i
< prec
; i
++)
4735 md_number_to_chars (litP
, (valueT
) words
[i
], 2);
4741 for (i
= 0; i
< prec
; i
+= 2)
4743 md_number_to_chars (litP
, (valueT
) words
[i
+ 1], 2);
4744 md_number_to_chars (litP
+ 2, (valueT
) words
[i
], 2);
4752 /* Return true if the given symbol should be considered local for PIC. */
4755 pic_need_relax (symbolS
*sym
, asection
*segtype
)
4758 bfd_boolean linkonce
;
4760 /* Handle the case of a symbol equated to another symbol. */
4761 while (symbol_equated_reloc_p (sym
))
4765 /* It's possible to get a loop here in a badly written
4767 n
= symbol_get_value_expression (sym
)->X_add_symbol
;
4773 symsec
= S_GET_SEGMENT (sym
);
4775 /* duplicate the test for LINK_ONCE sections as in adjust_reloc_syms */
4777 if (symsec
!= segtype
&& ! S_IS_LOCAL (sym
))
4779 if ((bfd_get_section_flags (stdoutput
, symsec
) & SEC_LINK_ONCE
) != 0)
4782 /* The GNU toolchain uses an extension for ELF: a section
4783 beginning with the magic string .gnu.linkonce is a linkonce
4785 if (strncmp (segment_name (symsec
), ".gnu.linkonce",
4786 sizeof ".gnu.linkonce" - 1) == 0)
4790 /* This must duplicate the test in adjust_reloc_syms. */
4791 return (symsec
!= &bfd_und_section
4792 && symsec
!= &bfd_abs_section
4793 && ! bfd_is_com_section (symsec
)
4796 /* A global or weak symbol is treated as external. */
4797 && (OUTPUT_FLAVOR
!= bfd_target_elf_flavour
4798 || (! S_IS_WEAK (sym
) && ! S_IS_EXTERNAL (sym
)))
4804 judge_size_before_relax (fragS
* fragp
, asection
*sec
)
4808 if (score_pic
== NO_PIC
)
4809 change
= nopic_need_relax (fragp
->fr_symbol
, 0);
4811 change
= pic_need_relax (fragp
->fr_symbol
, sec
);
4815 /* Only at the first time determining whether GP instruction relax should be done,
4816 return the difference between insntruction size and instruction relax size. */
4817 if (fragp
->fr_opcode
== NULL
)
4819 fragp
->fr_fix
= RELAX_NEW (fragp
->fr_subtype
);
4820 fragp
->fr_opcode
= fragp
->fr_literal
+ RELAX_RELOC1 (fragp
->fr_subtype
);
4821 return RELAX_NEW (fragp
->fr_subtype
) - RELAX_OLD (fragp
->fr_subtype
);
4828 /* In this function, we determine whether GP instruction should do relaxation,
4829 for the label being against was known now.
4830 Doing this here but not in md_relax_frag() can induce iteration times
4831 in stage of doing relax. */
4833 md_estimate_size_before_relax (fragS
* fragp
, asection
* sec ATTRIBUTE_UNUSED
)
4835 if ((RELAX_TYPE (fragp
->fr_subtype
) == Insn_GP
)
4836 || (RELAX_TYPE (fragp
->fr_subtype
) == Insn_PIC
))
4837 return judge_size_before_relax (fragp
, sec
);
4843 b32_relax_to_b16 (fragS
* fragp
)
4846 int relaxable_p
= 0;
4849 int frag_addr
= fragp
->fr_address
+ fragp
->insn_addr
;
4851 addressT symbol_address
= 0;
4854 unsigned long value
;
4855 unsigned long abs_value
;
4857 /* FIXME : here may be able to modify better .
4858 I don't know how to get the fragp's section ,
4859 so in relax stage , it may be wrong to calculate the symbol's offset when the frag's section
4860 is different from the symbol's. */
4862 old
= RELAX_OLD (fragp
->fr_subtype
);
4863 new = RELAX_NEW (fragp
->fr_subtype
);
4864 relaxable_p
= RELAX_OPT (fragp
->fr_subtype
);
4866 s
= fragp
->fr_symbol
;
4867 /* b/bl immediate */
4873 symbol_address
= (addressT
) s
->sy_frag
->fr_address
;
4876 value
= md_chars_to_number (fragp
->fr_literal
, INSN_SIZE
);
4878 /* b 32's offset : 20 bit, b 16's tolerate field : 0xff. */
4879 offset
= ((value
& 0x3ff0000) >> 6) | (value
& 0x3fe);
4880 if ((offset
& 0x80000) == 0x80000)
4881 offset
|= 0xfff00000;
4883 abs_value
= offset
+ symbol_address
- frag_addr
;
4884 if ((abs_value
& 0x80000000) == 0x80000000)
4885 abs_value
= 0xffffffff - abs_value
+ 1;
4887 /* Relax branch 32 to branch 16. */
4888 if (relaxable_p
&& (s
->bsym
!= NULL
) && ((abs_value
& 0xffffff00) == 0)
4889 && (S_IS_DEFINED (s
) && !S_IS_COMMON (s
) && !S_IS_EXTERNAL (s
)))
4895 /* Branch 32 can not be relaxed to b 16, so clear OPT bit. */
4896 fragp
->fr_opcode
= NULL
;
4897 fragp
->fr_subtype
= RELAX_OPT_CLEAR (fragp
->fr_subtype
);
4903 /* Main purpose is to determine whether one frag should do relax.
4904 frag->fr_opcode indicates this point. */
4907 score_relax_frag (asection
* sec ATTRIBUTE_UNUSED
, fragS
* fragp
, long stretch ATTRIBUTE_UNUSED
)
4911 int insn_relax_size
;
4912 int do_relax_p
= 0; /* Indicate doing relaxation for this frag. */
4913 int relaxable_p
= 0;
4914 bfd_boolean word_align_p
= FALSE
;
4917 /* If the instruction address is odd, make it half word align first. */
4918 if ((fragp
->fr_address
) % 2 != 0)
4920 if ((fragp
->fr_address
+ fragp
->insn_addr
) % 2 != 0)
4922 fragp
->insn_addr
= 1;
4927 word_align_p
= ((fragp
->fr_address
+ fragp
->insn_addr
) % 4 == 0) ? TRUE
: FALSE
;
4929 /* Get instruction size and relax size after the last relaxation. */
4930 if (fragp
->fr_opcode
)
4932 insn_size
= RELAX_NEW (fragp
->fr_subtype
);
4933 insn_relax_size
= RELAX_OLD (fragp
->fr_subtype
);
4937 insn_size
= RELAX_OLD (fragp
->fr_subtype
);
4938 insn_relax_size
= RELAX_NEW (fragp
->fr_subtype
);
4941 /* Handle specially for GP instruction. for, judge_size_before_relax() has already determine
4942 whether the GP instruction should do relax. */
4943 if ((RELAX_TYPE (fragp
->fr_subtype
) == Insn_GP
)
4944 || (RELAX_TYPE (fragp
->fr_subtype
) == Insn_PIC
))
4948 if (fragp
->insn_addr
< 2)
4950 fragp
->insn_addr
+= 2;
4955 fragp
->insn_addr
-= 2;
4960 if (fragp
->fr_opcode
)
4961 fragp
->fr_fix
= RELAX_NEW (fragp
->fr_subtype
) + fragp
->insn_addr
;
4963 fragp
->fr_fix
= RELAX_OLD (fragp
->fr_subtype
) + fragp
->insn_addr
;
4967 if (RELAX_TYPE (fragp
->fr_subtype
) == PC_DISP19div2
)
4968 b32_relax_to_b16 (fragp
);
4970 relaxable_p
= RELAX_OPT (fragp
->fr_subtype
);
4971 next_fragp
= fragp
->fr_next
;
4972 while ((next_fragp
) && (next_fragp
->fr_type
!= rs_machine_dependent
))
4974 next_fragp
= next_fragp
->fr_next
;
4980 int n_relaxable_p
= 0;
4982 if (next_fragp
->fr_opcode
)
4984 n_insn_size
= RELAX_NEW (next_fragp
->fr_subtype
);
4988 n_insn_size
= RELAX_OLD (next_fragp
->fr_subtype
);
4991 if (RELAX_TYPE (next_fragp
->fr_subtype
) == PC_DISP19div2
)
4992 b32_relax_to_b16 (next_fragp
);
4993 n_relaxable_p
= RELAX_OPT (next_fragp
->fr_subtype
);
5000 if (relaxable_p
&& ((n_insn_size
== 2) || n_relaxable_p
))
5006 else if (insn_size
== 2)
5009 if (relaxable_p
&& (((n_insn_size
== 4) && !n_relaxable_p
) || (n_insn_size
> 4)))
5030 /* Make the 32 bit insturction word align. */
5033 fragp
->insn_addr
+= 2;
5037 else if (insn_size
== 2)
5049 /* Here, try best to do relax regardless fragp->fr_next->fr_type. */
5050 if (word_align_p
== FALSE
)
5052 if (insn_size
% 4 == 0)
5062 fragp
->insn_addr
+= 2;
5073 /* fragp->fr_opcode indicates whether this frag should be relaxed. */
5076 if (fragp
->fr_opcode
)
5078 fragp
->fr_opcode
= NULL
;
5079 /* Guarantee estimate stage is correct. */
5080 fragp
->fr_fix
= RELAX_OLD (fragp
->fr_subtype
);
5081 fragp
->fr_fix
+= fragp
->insn_addr
;
5085 fragp
->fr_opcode
= fragp
->fr_literal
+ RELAX_RELOC1 (fragp
->fr_subtype
);
5086 /* Guarantee estimate stage is correct. */
5087 fragp
->fr_fix
= RELAX_NEW (fragp
->fr_subtype
);
5088 fragp
->fr_fix
+= fragp
->insn_addr
;
5093 if (fragp
->fr_opcode
)
5095 /* Guarantee estimate stage is correct. */
5096 fragp
->fr_fix
= RELAX_NEW (fragp
->fr_subtype
);
5097 fragp
->fr_fix
+= fragp
->insn_addr
;
5101 /* Guarantee estimate stage is correct. */
5102 fragp
->fr_fix
= RELAX_OLD (fragp
->fr_subtype
);
5103 fragp
->fr_fix
+= fragp
->insn_addr
;
5112 md_convert_frag (bfd
* abfd ATTRIBUTE_UNUSED
, segT sec ATTRIBUTE_UNUSED
, fragS
* fragp
)
5119 old
= RELAX_OLD (fragp
->fr_subtype
);
5120 new = RELAX_NEW (fragp
->fr_subtype
);
5122 /* fragp->fr_opcode indicates whether this frag should be relaxed. */
5123 if (fragp
->fr_opcode
== NULL
)
5125 memcpy (backup
, fragp
->fr_literal
, old
);
5126 fragp
->fr_fix
= old
;
5130 memcpy (backup
, fragp
->fr_literal
+ old
, new);
5131 fragp
->fr_fix
= new;
5134 fixp
= fragp
->tc_frag_data
.fixp
;
5135 while (fixp
&& fixp
->fx_frag
== fragp
&& fixp
->fx_where
< old
)
5137 if (fragp
->fr_opcode
)
5139 fixp
= fixp
->fx_next
;
5141 while (fixp
&& fixp
->fx_frag
== fragp
)
5143 if (fragp
->fr_opcode
)
5144 fixp
->fx_where
-= old
+ fragp
->insn_addr
;
5147 fixp
= fixp
->fx_next
;
5150 if (fragp
->insn_addr
)
5152 md_number_to_chars (fragp
->fr_literal
, 0x0, fragp
->insn_addr
);
5154 memcpy (fragp
->fr_literal
+ fragp
->insn_addr
, backup
, fragp
->fr_fix
);
5155 fragp
->fr_fix
+= fragp
->insn_addr
;
5158 /* Implementation of md_frag_check.
5159 Called after md_convert_frag(). */
5162 score_frag_check (fragS
* fragp ATTRIBUTE_UNUSED
)
5164 know (fragp
->insn_addr
<= RELAX_PAD_BYTE
);
5168 score_fix_adjustable (fixS
* fixP
)
5170 if (fixP
->fx_addsy
== NULL
)
5174 else if (OUTPUT_FLAVOR
== bfd_target_elf_flavour
5175 && (S_IS_EXTERNAL (fixP
->fx_addsy
) || S_IS_WEAK (fixP
->fx_addsy
)))
5179 else if (fixP
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
5180 || fixP
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
5188 /* Implementation of TC_VALIDATE_FIX.
5189 Called before md_apply_fix() and after md_convert_frag(). */
5191 score_validate_fix (fixS
*fixP
)
5193 fixP
->fx_where
+= fixP
->fx_frag
->insn_addr
;
5197 md_pcrel_from (fixS
* fixP
)
5202 && (S_GET_SEGMENT (fixP
->fx_addsy
) == undefined_section
)
5203 && (fixP
->fx_subsy
== NULL
))
5209 retval
= fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
5216 score_force_relocation (struct fix
*fixp
)
5220 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
5221 || fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
5222 || fixp
->fx_r_type
== BFD_RELOC_SCORE_JMP
5223 || fixp
->fx_r_type
== BFD_RELOC_SCORE_BRANCH
5224 || fixp
->fx_r_type
== BFD_RELOC_SCORE16_JMP
5225 || fixp
->fx_r_type
== BFD_RELOC_SCORE16_BRANCH
)
5233 /* Round up a section size to the appropriate boundary. */
5235 md_section_align (segT segment ATTRIBUTE_UNUSED
, valueT size
)
5237 int align
= bfd_get_section_alignment (stdoutput
, segment
);
5239 return ((size
+ (1 << align
) - 1) & (-1 << align
));
5243 md_apply_fix (fixS
*fixP
, valueT
*valP
, segT seg
)
5245 offsetT value
= *valP
;
5246 offsetT abs_value
= 0;
5249 unsigned short HI
, LO
;
5251 char *buf
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
5253 assert (fixP
->fx_r_type
< BFD_RELOC_UNUSED
);
5254 if (fixP
->fx_addsy
== 0 && !fixP
->fx_pcrel
)
5256 if (fixP
->fx_r_type
!= BFD_RELOC_SCORE_DUMMY_HI16
)
5260 /* If this symbol is in a different section then we need to leave it for
5261 the linker to deal with. Unfortunately, md_pcrel_from can't tell,
5262 so we have to undo it's effects here. */
5265 if (fixP
->fx_addsy
!= NULL
5266 && S_IS_DEFINED (fixP
->fx_addsy
)
5267 && S_GET_SEGMENT (fixP
->fx_addsy
) != seg
)
5268 value
+= md_pcrel_from (fixP
);
5271 /* Remember value for emit_reloc. */
5272 fixP
->fx_addnumber
= value
;
5274 switch (fixP
->fx_r_type
)
5276 case BFD_RELOC_HI16_S
:
5278 { /* For la rd, imm32. */
5279 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5280 HI
= (value
) >> 16; /* mul to 2, then take the hi 16 bit. */
5281 newval
|= (HI
& 0x3fff) << 1;
5282 newval
|= ((HI
>> 14) & 0x3) << 16;
5283 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5286 case BFD_RELOC_LO16
:
5287 if (fixP
->fx_done
) /* For la rd, imm32. */
5289 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5290 LO
= (value
) & 0xffff;
5291 newval
|= (LO
& 0x3fff) << 1; /* 16 bit: imm -> 14 bit in lo, 2 bit in hi. */
5292 newval
|= ((LO
>> 14) & 0x3) << 16;
5293 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5296 case BFD_RELOC_SCORE_JMP
:
5298 content
= md_chars_to_number (buf
, INSN_SIZE
);
5299 value
= fixP
->fx_offset
;
5300 content
= (content
& ~0x3ff7ffe) | ((value
<< 1) & 0x3ff0000) | (value
& 0x7fff);
5301 md_number_to_chars (buf
, content
, INSN_SIZE
);
5304 case BFD_RELOC_SCORE_BRANCH
:
5305 if ((S_GET_SEGMENT (fixP
->fx_addsy
) != seg
) || (fixP
->fx_addsy
!= NULL
&& S_IS_EXTERNAL (fixP
->fx_addsy
)))
5306 value
= fixP
->fx_offset
;
5310 content
= md_chars_to_number (buf
, INSN_SIZE
);
5311 if ((fixP
->fx_frag
->fr_opcode
!= 0) && ((content
& 0x80008000) != 0x80008000))
5313 if ((value
& 0x80000000) == 0x80000000)
5314 abs_value
= 0xffffffff - value
+ 1;
5315 if ((abs_value
& 0xffffff00) != 0)
5317 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5318 _(" branch relocation truncate (0x%x) [-2^8 ~ 2^8]"), (unsigned int)value
);
5321 content
= md_chars_to_number (buf
, INSN16_SIZE
);
5323 content
= (content
& 0xff00) | ((value
>> 1) & 0xff);
5324 md_number_to_chars (buf
, content
, INSN16_SIZE
);
5325 fixP
->fx_r_type
= BFD_RELOC_SCORE16_BRANCH
;
5330 if ((value
& 0x80000000) == 0x80000000)
5331 abs_value
= 0xffffffff - value
+ 1;
5332 if ((abs_value
& 0xfff80000) != 0)
5334 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5335 _(" branch relocation truncate (0x%x) [-2^19 ~ 2^19]"), (unsigned int)value
);
5338 content
= md_chars_to_number (buf
, INSN_SIZE
);
5339 content
&= 0xfc00fc01;
5340 content
= (content
& 0xfc00fc01) | (value
& 0x3fe) | ((value
<< 6) & 0x3ff0000);
5341 md_number_to_chars (buf
, content
, INSN_SIZE
);
5344 case BFD_RELOC_SCORE16_JMP
:
5345 content
= md_chars_to_number (buf
, INSN16_SIZE
);
5347 value
= fixP
->fx_offset
& 0xfff;
5348 content
= (content
& 0xfc01) | (value
& 0xffe);
5349 md_number_to_chars (buf
, content
, INSN16_SIZE
);
5351 case BFD_RELOC_SCORE16_BRANCH
:
5352 content
= md_chars_to_number (buf
, INSN_SIZE
);
5353 if ((fixP
->fx_frag
->fr_opcode
!= 0) && ((content
& 0x80008000) == 0x80008000))
5355 if ((S_GET_SEGMENT (fixP
->fx_addsy
) != seg
) ||
5356 (fixP
->fx_addsy
!= NULL
&& S_IS_EXTERNAL (fixP
->fx_addsy
)))
5357 value
= fixP
->fx_offset
;
5360 if ((value
& 0x80000000) == 0x80000000)
5361 abs_value
= 0xffffffff - value
+ 1;
5362 if ((abs_value
& 0xfff80000) != 0)
5364 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5365 _(" branch relocation truncate (0x%x) [-2^19 ~ 2^19]"), (unsigned int)value
);
5368 content
= md_chars_to_number (buf
, INSN_SIZE
);
5369 content
= (content
& 0xfc00fc01) | (value
& 0x3fe) | ((value
<< 6) & 0x3ff0000);
5370 md_number_to_chars (buf
, content
, INSN_SIZE
);
5371 fixP
->fx_r_type
= BFD_RELOC_SCORE_BRANCH
;
5377 /* In differnt section. */
5378 if ((S_GET_SEGMENT (fixP
->fx_addsy
) != seg
) ||
5379 (fixP
->fx_addsy
!= NULL
&& S_IS_EXTERNAL (fixP
->fx_addsy
)))
5380 value
= fixP
->fx_offset
;
5384 if ((value
& 0x80000000) == 0x80000000)
5385 abs_value
= 0xffffffff - value
+ 1;
5386 if ((abs_value
& 0xffffff00) != 0)
5388 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5389 _(" branch relocation truncate (0x%x) [-2^8 ~ 2^8]"), (unsigned int)value
);
5392 content
= md_chars_to_number (buf
, INSN16_SIZE
);
5393 content
= (content
& 0xff00) | ((value
>> 1) & 0xff);
5394 md_number_to_chars (buf
, content
, INSN16_SIZE
);
5398 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5399 md_number_to_chars (buf
, value
, 1);
5403 value
= fixP
->fx_offset
;
5404 md_number_to_chars (buf
, value
, 1);
5410 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5411 md_number_to_chars (buf
, value
, 2);
5415 value
= fixP
->fx_offset
;
5416 md_number_to_chars (buf
, value
, 2);
5422 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5423 md_number_to_chars (buf
, value
, 4);
5427 value
= fixP
->fx_offset
;
5428 md_number_to_chars (buf
, value
, 4);
5432 case BFD_RELOC_VTABLE_INHERIT
:
5434 if (fixP
->fx_addsy
&& !S_IS_DEFINED (fixP
->fx_addsy
) && !S_IS_WEAK (fixP
->fx_addsy
))
5435 S_SET_WEAK (fixP
->fx_addsy
);
5437 case BFD_RELOC_VTABLE_ENTRY
:
5440 case BFD_RELOC_SCORE_GPREL15
:
5441 content
= md_chars_to_number (buf
, INSN_SIZE
);
5442 if ((fixP
->fx_frag
->fr_opcode
!= 0) && ((content
& 0xfc1c8000) != 0x94188000))
5443 fixP
->fx_r_type
= BFD_RELOC_NONE
;
5446 case BFD_RELOC_SCORE_GOT15
:
5447 case BFD_RELOC_SCORE_DUMMY_HI16
:
5448 case BFD_RELOC_SCORE_GOT_LO16
:
5449 case BFD_RELOC_SCORE_CALL15
:
5450 case BFD_RELOC_GPREL32
:
5452 case BFD_RELOC_NONE
:
5454 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("bad relocation fixup type (%d)"), fixP
->fx_r_type
);
5458 /* Translate internal representation of relocation info to BFD target format. */
5460 tc_gen_reloc (asection
* section ATTRIBUTE_UNUSED
, fixS
* fixp
)
5462 static arelent
*retval
[MAX_RELOC_EXPANSION
+ 1]; /* MAX_RELOC_EXPANSION equals 2. */
5464 bfd_reloc_code_real_type code
;
5470 reloc
= retval
[0] = xmalloc (sizeof (arelent
));
5473 reloc
->sym_ptr_ptr
= xmalloc (sizeof (asymbol
*));
5474 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
5475 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
5476 reloc
->addend
= fixp
->fx_offset
;
5478 /* If this is a variant frag, we may need to adjust the existing
5479 reloc and generate a new one. */
5480 if (fixp
->fx_frag
->fr_opcode
!= NULL
&& (fixp
->fx_r_type
== BFD_RELOC_SCORE_GPREL15
))
5482 /* Update instruction imm bit. */
5487 buf
= fixp
->fx_frag
->fr_literal
+ fixp
->fx_frag
->insn_addr
;
5488 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5489 off
= fixp
->fx_offset
>> 16;
5490 newval
|= (off
& 0x3fff) << 1;
5491 newval
|= ((off
>> 14) & 0x3) << 16;
5492 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5495 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5496 off
= fixp
->fx_offset
& 0xffff;
5497 newval
|= ((off
& 0x3fff) << 1);
5498 newval
|= (((off
>> 14) & 0x3) << 16);
5499 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5501 retval
[1] = xmalloc (sizeof (arelent
));
5503 retval
[1]->sym_ptr_ptr
= xmalloc (sizeof (asymbol
*));
5504 *retval
[1]->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
5505 retval
[1]->address
= (reloc
->address
+ RELAX_RELOC2 (fixp
->fx_frag
->fr_subtype
));
5511 retval
[1]->addend
= 0;
5512 retval
[1]->howto
= bfd_reloc_type_lookup (stdoutput
, BFD_RELOC_LO16
);
5513 assert (retval
[1]->howto
!= NULL
);
5515 fixp
->fx_r_type
= BFD_RELOC_HI16_S
;
5518 code
= fixp
->fx_r_type
;
5519 switch (fixp
->fx_r_type
)
5524 code
= BFD_RELOC_32_PCREL
;
5527 case BFD_RELOC_HI16_S
:
5528 case BFD_RELOC_LO16
:
5529 case BFD_RELOC_SCORE_JMP
:
5530 case BFD_RELOC_SCORE_BRANCH
:
5531 case BFD_RELOC_SCORE16_JMP
:
5532 case BFD_RELOC_SCORE16_BRANCH
:
5533 case BFD_RELOC_VTABLE_ENTRY
:
5534 case BFD_RELOC_VTABLE_INHERIT
:
5535 case BFD_RELOC_SCORE_GPREL15
:
5536 case BFD_RELOC_SCORE_GOT15
:
5537 case BFD_RELOC_SCORE_DUMMY_HI16
:
5538 case BFD_RELOC_SCORE_GOT_LO16
:
5539 case BFD_RELOC_SCORE_CALL15
:
5540 case BFD_RELOC_GPREL32
:
5541 case BFD_RELOC_NONE
:
5542 code
= fixp
->fx_r_type
;
5545 type
= _("<unknown>");
5546 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5547 _("cannot represent %s relocation in this object file format"), type
);
5551 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
5552 if (reloc
->howto
== NULL
)
5554 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5555 _("cannot represent %s relocation in this object file format1"),
5556 bfd_get_reloc_code_name (code
));
5559 /* HACK: Since arm ELF uses Rel instead of Rela, encode the
5560 vtable entry to be used in the relocation's section offset. */
5561 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
5562 reloc
->address
= fixp
->fx_offset
;
5568 score_elf_final_processing (void)
5570 if (fix_data_dependency
== 1)
5572 elf_elfheader (stdoutput
)->e_flags
|= EF_SCORE_FIXDEP
;
5574 if (score_pic
== PIC
)
5576 elf_elfheader (stdoutput
)->e_flags
|= EF_SCORE_PIC
;
5581 parse_pce_inst (char *insnstr
)
5585 char first
[MAX_LITERAL_POOL_SIZE
];
5586 char second
[MAX_LITERAL_POOL_SIZE
];
5587 struct score_it pec_part_1
;
5589 /* Get first part string of PCE. */
5590 p
= strstr (insnstr
, "||");
5593 sprintf (first
, "%s", insnstr
);
5595 /* Get second part string of PCE. */
5598 sprintf (second
, "%s", p
);
5600 parse_16_32_inst (first
, FALSE
);
5604 memcpy (&pec_part_1
, &inst
, sizeof (inst
));
5606 parse_16_32_inst (second
, FALSE
);
5610 if ( ((pec_part_1
.size
== INSN_SIZE
) && (inst
.size
== INSN_SIZE
))
5611 || ((pec_part_1
.size
== INSN_SIZE
) && (inst
.size
== INSN16_SIZE
))
5612 || ((pec_part_1
.size
== INSN16_SIZE
) && (inst
.size
== INSN_SIZE
)))
5614 inst
.error
= _("pce instruction error (16 bit || 16 bit)'");
5615 sprintf (inst
.str
, "%s", insnstr
);
5620 gen_insn_frag (&pec_part_1
, &inst
);
5624 md_assemble (char *str
)
5627 know (strlen (str
) < MAX_LITERAL_POOL_SIZE
);
5629 memset (&inst
, '\0', sizeof (inst
));
5630 if (INSN_IS_PCE_P (str
))
5631 parse_pce_inst (str
);
5633 parse_16_32_inst (str
, TRUE
);
5636 as_bad (_("%s -- `%s'"), inst
.error
, inst
.str
);
5639 /* We handle all bad expressions here, so that we can report the faulty
5640 instruction in the error message. */
5642 md_operand (expressionS
* expr
)
5644 if (in_my_get_expression
)
5646 expr
->X_op
= O_illegal
;
5647 if (inst
.error
== NULL
)
5649 inst
.error
= _("bad expression");
5654 const char *md_shortopts
= "nO::g::G:";
5656 #ifdef SCORE_BI_ENDIAN
5657 #define OPTION_EB (OPTION_MD_BASE + 0)
5658 #define OPTION_EL (OPTION_MD_BASE + 1)
5660 #if TARGET_BYTES_BIG_ENDIAN
5661 #define OPTION_EB (OPTION_MD_BASE + 0)
5663 #define OPTION_EL (OPTION_MD_BASE + 1)
5666 #define OPTION_FIXDD (OPTION_MD_BASE + 2)
5667 #define OPTION_NWARN (OPTION_MD_BASE + 3)
5668 #define OPTION_SCORE5 (OPTION_MD_BASE + 4)
5669 #define OPTION_SCORE5U (OPTION_MD_BASE + 5)
5670 #define OPTION_SCORE7 (OPTION_MD_BASE + 6)
5671 #define OPTION_R1 (OPTION_MD_BASE + 7)
5672 #define OPTION_O0 (OPTION_MD_BASE + 8)
5673 #define OPTION_SCORE_VERSION (OPTION_MD_BASE + 9)
5674 #define OPTION_PIC (OPTION_MD_BASE + 10)
5676 struct option md_longopts
[] =
5679 {"EB" , no_argument
, NULL
, OPTION_EB
},
5682 {"EL" , no_argument
, NULL
, OPTION_EL
},
5684 {"FIXDD" , no_argument
, NULL
, OPTION_FIXDD
},
5685 {"NWARN" , no_argument
, NULL
, OPTION_NWARN
},
5686 {"SCORE5" , no_argument
, NULL
, OPTION_SCORE5
},
5687 {"SCORE5U", no_argument
, NULL
, OPTION_SCORE5U
},
5688 {"SCORE7" , no_argument
, NULL
, OPTION_SCORE7
},
5689 {"USE_R1" , no_argument
, NULL
, OPTION_R1
},
5690 {"O0" , no_argument
, NULL
, OPTION_O0
},
5691 {"V" , no_argument
, NULL
, OPTION_SCORE_VERSION
},
5692 {"KPIC" , no_argument
, NULL
, OPTION_PIC
},
5693 {NULL
, no_argument
, NULL
, 0}
5696 size_t md_longopts_size
= sizeof (md_longopts
);
5699 md_parse_option (int c
, char *arg
)
5705 target_big_endian
= 1;
5710 target_big_endian
= 0;
5714 fix_data_dependency
= 1;
5717 warn_fix_data_dependency
= 0;
5721 university_version
= 0;
5722 vector_size
= SCORE5_PIPELINE
;
5724 case OPTION_SCORE5U
:
5726 university_version
= 1;
5727 vector_size
= SCORE5_PIPELINE
;
5731 university_version
= 0;
5732 vector_size
= SCORE7_PIPELINE
;
5738 g_switch_value
= atoi (arg
);
5743 case OPTION_SCORE_VERSION
:
5744 printf (_("Sunplus-v2-0-0-20060510\n"));
5748 g_switch_value
= 0; /* Must set -G num as 0 to generate PIC code. */
5751 /* as_bad (_("unrecognized option `-%c%s'"), c, arg ? arg : ""); */
5758 md_show_usage (FILE * fp
)
5760 fprintf (fp
, _(" Score-specific assembler options:\n"));
5763 -EB\t\tassemble code for a big-endian cpu\n"));
5768 -EL\t\tassemble code for a little-endian cpu\n"));
5772 -FIXDD\t\tassemble code for fix data dependency\n"));
5774 -NWARN\t\tassemble code for no warning message for fix data dependency\n"));
5776 -SCORE5\t\tassemble code for target is SCORE5\n"));
5778 -SCORE5U\tassemble code for target is SCORE5U\n"));
5780 -SCORE7\t\tassemble code for target is SCORE7, this is default setting\n"));
5782 -USE_R1\t\tassemble code for no warning message when using temp register r1\n"));
5784 -KPIC\t\tassemble code for PIC\n"));
5786 -O0\t\tassembler will not perform any optimizations\n"));
5788 -G gpnum\tassemble code for setting gpsize and default is 8 byte\n"));
5790 -V \t\tSunplus release version \n"));
5794 /* Pesudo handling functions. */
5796 /* If we change section we must dump the literal pool first. */
5798 s_score_bss (int ignore ATTRIBUTE_UNUSED
)
5800 subseg_set (bss_section
, (subsegT
) get_absolute_expression ());
5801 demand_empty_rest_of_line ();
5805 s_score_text (int ignore
)
5807 obj_elf_text (ignore
);
5808 record_alignment (now_seg
, 2);
5812 score_s_section (int ignore
)
5814 obj_elf_section (ignore
);
5815 if ((bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
) != 0)
5816 record_alignment (now_seg
, 2);
5821 s_change_sec (int sec
)
5826 /* The ELF backend needs to know that we are changing sections, so
5827 that .previous works correctly. We could do something like check
5828 for an obj_section_change_hook macro, but that might be confusing
5829 as it would not be appropriate to use it in the section changing
5830 functions in read.c, since obj-elf.c intercepts those. FIXME:
5831 This should be cleaner, somehow. */
5832 obj_elf_section_change_hook ();
5837 seg
= subseg_new (RDATA_SECTION_NAME
, (subsegT
) get_absolute_expression ());
5838 bfd_set_section_flags (stdoutput
, seg
, (SEC_ALLOC
| SEC_LOAD
| SEC_READONLY
| SEC_RELOC
| SEC_DATA
));
5839 if (strcmp (TARGET_OS
, "elf") != 0)
5840 record_alignment (seg
, 4);
5841 demand_empty_rest_of_line ();
5844 seg
= subseg_new (".sdata", (subsegT
) get_absolute_expression ());
5845 bfd_set_section_flags (stdoutput
, seg
, SEC_ALLOC
| SEC_LOAD
| SEC_RELOC
| SEC_DATA
);
5846 if (strcmp (TARGET_OS
, "elf") != 0)
5847 record_alignment (seg
, 4);
5848 demand_empty_rest_of_line ();
5854 s_score_mask (int reg_type ATTRIBUTE_UNUSED
)
5858 if (cur_proc_ptr
== (procS
*) NULL
)
5860 as_warn (_(".mask outside of .ent"));
5861 demand_empty_rest_of_line ();
5864 if (get_absolute_expression_and_terminator (&mask
) != ',')
5866 as_warn (_("Bad .mask directive"));
5867 --input_line_pointer
;
5868 demand_empty_rest_of_line ();
5871 off
= get_absolute_expression ();
5872 cur_proc_ptr
->reg_mask
= mask
;
5873 cur_proc_ptr
->reg_offset
= off
;
5874 demand_empty_rest_of_line ();
5884 name
= input_line_pointer
;
5885 c
= get_symbol_end ();
5886 p
= (symbolS
*) symbol_find_or_make (name
);
5887 *input_line_pointer
= c
;
5897 if (*input_line_pointer
== '-')
5899 ++input_line_pointer
;
5902 if (!ISDIGIT (*input_line_pointer
))
5903 as_bad (_("expected simple number"));
5904 if (input_line_pointer
[0] == '0')
5906 if (input_line_pointer
[1] == 'x')
5908 input_line_pointer
+= 2;
5909 while (ISXDIGIT (*input_line_pointer
))
5912 val
|= hex_value (*input_line_pointer
++);
5914 return negative
? -val
: val
;
5918 ++input_line_pointer
;
5919 while (ISDIGIT (*input_line_pointer
))
5922 val
|= *input_line_pointer
++ - '0';
5924 return negative
? -val
: val
;
5927 if (!ISDIGIT (*input_line_pointer
))
5929 printf (_(" *input_line_pointer == '%c' 0x%02x\n"), *input_line_pointer
, *input_line_pointer
);
5930 as_warn (_("invalid number"));
5933 while (ISDIGIT (*input_line_pointer
))
5936 val
+= *input_line_pointer
++ - '0';
5938 return negative
? -val
: val
;
5941 /* The .aent and .ent directives. */
5944 s_score_ent (int aent
)
5949 symbolP
= get_symbol ();
5950 if (*input_line_pointer
== ',')
5951 ++input_line_pointer
;
5953 if (ISDIGIT (*input_line_pointer
) || *input_line_pointer
== '-')
5956 #ifdef BFD_ASSEMBLER
5957 if ((bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
) != 0)
5962 if (now_seg
!= data_section
&& now_seg
!= bss_section
)
5968 as_warn (_(".ent or .aent not in text section."));
5969 if (!aent
&& cur_proc_ptr
)
5970 as_warn (_("missing .end"));
5973 cur_proc_ptr
= &cur_proc
;
5974 cur_proc_ptr
->reg_mask
= 0xdeadbeaf;
5975 cur_proc_ptr
->reg_offset
= 0xdeadbeaf;
5976 cur_proc_ptr
->fpreg_mask
= 0xdeafbeaf;
5977 cur_proc_ptr
->leaf
= 0xdeafbeaf;
5978 cur_proc_ptr
->frame_offset
= 0xdeafbeaf;
5979 cur_proc_ptr
->frame_reg
= 0xdeafbeaf;
5980 cur_proc_ptr
->pc_reg
= 0xdeafbeaf;
5981 cur_proc_ptr
->isym
= symbolP
;
5982 symbol_get_bfdsym (symbolP
)->flags
|= BSF_FUNCTION
;
5984 if (debug_type
== DEBUG_STABS
)
5985 stabs_generate_asm_func (S_GET_NAME (symbolP
), S_GET_NAME (symbolP
));
5987 demand_empty_rest_of_line ();
5991 s_score_frame (int ignore ATTRIBUTE_UNUSED
)
5998 backupstr
= input_line_pointer
;
6001 if (cur_proc_ptr
== (procS
*) NULL
)
6003 as_warn (_(".frame outside of .ent"));
6004 demand_empty_rest_of_line ();
6007 cur_proc_ptr
->frame_reg
= reg_required_here ((&backupstr
), 0, REG_TYPE_SCORE
);
6009 skip_past_comma (&backupstr
);
6010 while (*backupstr
!= ',')
6012 str
[i
] = *backupstr
;
6020 skip_past_comma (&backupstr
);
6021 cur_proc_ptr
->frame_offset
= val
;
6022 cur_proc_ptr
->pc_reg
= reg_required_here ((&backupstr
), 0, REG_TYPE_SCORE
);
6025 skip_past_comma (&backupstr
);
6027 while (*backupstr
!= '\n')
6029 str
[i
] = *backupstr
;
6035 cur_proc_ptr
->leaf
= val
;
6037 skip_past_comma (&backupstr
);
6039 #endif /* OBJ_ELF */
6040 while (input_line_pointer
!= backupstr
)
6041 input_line_pointer
++;
6044 /* The .end directive. */
6046 s_score_end (int x ATTRIBUTE_UNUSED
)
6051 /* Generate a .pdr section. */
6052 segT saved_seg
= now_seg
;
6053 subsegT saved_subseg
= now_subseg
;
6058 if (!is_end_of_line
[(unsigned char)*input_line_pointer
])
6061 demand_empty_rest_of_line ();
6066 #ifdef BFD_ASSEMBLER
6067 if ((bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
) != 0)
6072 if (now_seg
!= data_section
&& now_seg
!= bss_section
)
6079 as_warn (_(".end not in text section"));
6082 as_warn (_(".end directive without a preceding .ent directive."));
6083 demand_empty_rest_of_line ();
6088 assert (S_GET_NAME (p
));
6089 if (strcmp (S_GET_NAME (p
), S_GET_NAME (cur_proc_ptr
->isym
)))
6090 as_warn (_(".end symbol does not match .ent symbol."));
6091 if (debug_type
== DEBUG_STABS
)
6092 stabs_generate_asm_endfunc (S_GET_NAME (p
), S_GET_NAME (p
));
6095 as_warn (_(".end directive missing or unknown symbol"));
6097 if ((cur_proc_ptr
->reg_mask
== 0xdeadbeaf) ||
6098 (cur_proc_ptr
->reg_offset
== 0xdeadbeaf) ||
6099 (cur_proc_ptr
->leaf
== 0xdeafbeaf) ||
6100 (cur_proc_ptr
->frame_offset
== 0xdeafbeaf) ||
6101 (cur_proc_ptr
->frame_reg
== 0xdeafbeaf) || (cur_proc_ptr
->pc_reg
== 0xdeafbeaf));
6105 dot
= frag_now_fix ();
6107 subseg_set (pdr_seg
, 0);
6108 /* Write the symbol. */
6109 exp
.X_op
= O_symbol
;
6110 exp
.X_add_symbol
= p
;
6111 exp
.X_add_number
= 0;
6112 emit_expr (&exp
, 4);
6113 fragp
= frag_more (7 * 4);
6114 md_number_to_chars (fragp
, (valueT
) cur_proc_ptr
->reg_mask
, 4);
6115 md_number_to_chars (fragp
+ 4, (valueT
) cur_proc_ptr
->reg_offset
, 4);
6116 md_number_to_chars (fragp
+ 8, (valueT
) cur_proc_ptr
->fpreg_mask
, 4);
6117 md_number_to_chars (fragp
+ 12, (valueT
) cur_proc_ptr
->leaf
, 4);
6118 md_number_to_chars (fragp
+ 16, (valueT
) cur_proc_ptr
->frame_offset
, 4);
6119 md_number_to_chars (fragp
+ 20, (valueT
) cur_proc_ptr
->frame_reg
, 4);
6120 md_number_to_chars (fragp
+ 24, (valueT
) cur_proc_ptr
->pc_reg
, 4);
6121 subseg_set (saved_seg
, saved_subseg
);
6124 cur_proc_ptr
= NULL
;
6127 /* Handle the .set pseudo-op. */
6129 s_score_set (int x ATTRIBUTE_UNUSED
)
6132 char name
[MAX_LITERAL_POOL_SIZE
];
6133 char * orig_ilp
= input_line_pointer
;
6135 while (!is_end_of_line
[(unsigned char)*input_line_pointer
])
6137 name
[i
] = (char) * input_line_pointer
;
6139 ++input_line_pointer
;
6144 if (strcmp (name
, "nwarn") == 0)
6146 warn_fix_data_dependency
= 0;
6148 else if (strcmp (name
, "fixdd") == 0)
6150 fix_data_dependency
= 1;
6152 else if (strcmp (name
, "nofixdd") == 0)
6154 fix_data_dependency
= 0;
6156 else if (strcmp (name
, "r1") == 0)
6160 else if (strcmp (name
, "nor1") == 0)
6164 else if (strcmp (name
, "optimize") == 0)
6168 else if (strcmp (name
, "volatile") == 0)
6172 else if (strcmp (name
, "pic") == 0)
6178 input_line_pointer
= orig_ilp
;
6183 /* Handle the .cpload pseudo-op. This is used when generating PIC code. It sets the
6184 $gp register for the function based on the function address, which is in the register
6185 named in the argument. This uses a relocation against GP_DISP_LABEL, which is handled
6186 specially by the linker. The result is:
6187 ldis gp, %hi(GP_DISP_LABEL)
6188 ori gp, %low(GP_DISP_LABEL)
6189 add gp, gp, .cpload argument
6190 The .cpload argument is normally r29. */
6193 s_score_cpload (int ignore ATTRIBUTE_UNUSED
)
6196 char insn_str
[MAX_LITERAL_POOL_SIZE
];
6198 /* If we are not generating PIC code, .cpload is ignored. */
6199 if (score_pic
== NO_PIC
)
6205 if ((reg
= reg_required_here (&input_line_pointer
, -1, REG_TYPE_SCORE
)) == (int) FAIL
)
6208 demand_empty_rest_of_line ();
6210 sprintf (insn_str
, _("ld_i32hi r%d, %s"), GP
, GP_DISP_LABEL
);
6211 if (append_insn (insn_str
, TRUE
) == (int) FAIL
)
6214 sprintf (insn_str
, _("ld_i32lo r%d, %s"), GP
, GP_DISP_LABEL
);
6215 if (append_insn (insn_str
, TRUE
) == (int) FAIL
)
6218 sprintf (insn_str
, _("add r%d, r%d, r%d"), GP
, GP
, reg
);
6219 if (append_insn (insn_str
, TRUE
) == (int) FAIL
)
6223 /* Handle the .cprestore pseudo-op. This stores $gp into a given
6224 offset from $sp. The offset is remembered, and after making a PIC
6225 call $gp is restored from that location. */
6228 s_score_cprestore (int ignore ATTRIBUTE_UNUSED
)
6231 int cprestore_offset
;
6232 char insn_str
[MAX_LITERAL_POOL_SIZE
];
6234 /* If we are not generating PIC code, .cprestore is ignored. */
6235 if (score_pic
== NO_PIC
)
6241 if ((reg
= reg_required_here (&input_line_pointer
, -1, REG_TYPE_SCORE
)) == (int) FAIL
6242 || skip_past_comma (&input_line_pointer
) == (int) FAIL
)
6247 cprestore_offset
= get_absolute_expression ();
6249 if (cprestore_offset
<= 0x3fff)
6251 sprintf (insn_str
, _("sw r%d, [r%d, %d]"), GP
, reg
, cprestore_offset
);
6252 if (append_insn (insn_str
, TRUE
) == (int) FAIL
)
6262 sprintf (insn_str
, _("li r1, %d"), cprestore_offset
);
6263 if (append_insn (insn_str
, TRUE
) == (int) FAIL
)
6266 sprintf (insn_str
, _("add r1, r1, r%d"), reg
);
6267 if (append_insn (insn_str
, TRUE
) == (int) FAIL
)
6270 sprintf (insn_str
, _("sw r%d, [r1]"), GP
);
6271 if (append_insn (insn_str
, TRUE
) == (int) FAIL
)
6277 demand_empty_rest_of_line ();
6280 /* Handle the .gpword pseudo-op. This is used when generating PIC
6281 code. It generates a 32 bit GP relative reloc. */
6283 s_score_gpword (int ignore ATTRIBUTE_UNUSED
)
6288 /* When not generating PIC code, this is treated as .word. */
6289 if (score_pic
== NO_PIC
)
6295 if (ex
.X_op
!= O_symbol
|| ex
.X_add_number
!= 0)
6297 as_bad (_("Unsupported use of .gpword"));
6298 ignore_rest_of_line ();
6301 md_number_to_chars (p
, (valueT
) 0, 4);
6302 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 4, &ex
, FALSE
, BFD_RELOC_GPREL32
);
6303 demand_empty_rest_of_line ();
6306 /* Handle the .cpadd pseudo-op. This is used when dealing with switch
6307 tables in PIC code. */
6310 s_score_cpadd (int ignore ATTRIBUTE_UNUSED
)
6313 char insn_str
[MAX_LITERAL_POOL_SIZE
];
6315 /* If we are not generating PIC code, .cpload is ignored. */
6316 if (score_pic
== NO_PIC
)
6322 if ((reg
= reg_required_here (&input_line_pointer
, -1, REG_TYPE_SCORE
)) == (int) FAIL
)
6326 demand_empty_rest_of_line ();
6328 /* Add $gp to the register named as an argument. */
6329 sprintf (insn_str
, _("add r%d, r%d, r%d"), reg
, reg
, GP
);
6330 if (append_insn (insn_str
, TRUE
) == (int) FAIL
)
6334 #ifndef TC_IMPLICIT_LCOMM_ALIGNMENT
6335 #define TC_IMPLICIT_LCOMM_ALIGNMENT(SIZE, P2VAR) \
6340 else if ((SIZE) >= 4) \
6342 else if ((SIZE) >= 2) \
6351 s_score_lcomm (int bytes_p
)
6358 segT current_seg
= now_seg
;
6359 subsegT current_subseg
= now_subseg
;
6360 const int max_alignment
= 15;
6362 segT bss_seg
= bss_section
;
6363 int needs_align
= 0;
6365 name
= input_line_pointer
;
6366 c
= get_symbol_end ();
6367 p
= input_line_pointer
;
6372 as_bad (_("expected symbol name"));
6373 discard_rest_of_line ();
6379 /* Accept an optional comma after the name. The comma used to be
6380 required, but Irix 5 cc does not generate it. */
6381 if (*input_line_pointer
== ',')
6383 ++input_line_pointer
;
6387 if (is_end_of_line
[(unsigned char)*input_line_pointer
])
6389 as_bad (_("missing size expression"));
6393 if ((temp
= get_absolute_expression ()) < 0)
6395 as_warn (_("BSS length (%d) < 0 ignored"), temp
);
6396 ignore_rest_of_line ();
6400 #if defined (TC_SCORE)
6401 if (OUTPUT_FLAVOR
== bfd_target_ecoff_flavour
|| OUTPUT_FLAVOR
== bfd_target_elf_flavour
)
6403 /* For Score and Alpha ECOFF or ELF, small objects are put in .sbss. */
6404 if ((unsigned)temp
<= bfd_get_gp_size (stdoutput
))
6406 bss_seg
= subseg_new (".sbss", 1);
6407 seg_info (bss_seg
)->bss
= 1;
6408 #ifdef BFD_ASSEMBLER
6409 if (!bfd_set_section_flags (stdoutput
, bss_seg
, SEC_ALLOC
))
6410 as_warn (_("error setting flags for \".sbss\": %s"), bfd_errmsg (bfd_get_error ()));
6417 if (*input_line_pointer
== ',')
6419 ++input_line_pointer
;
6422 if (is_end_of_line
[(unsigned char)*input_line_pointer
])
6424 as_bad (_("missing alignment"));
6429 align
= get_absolute_expression ();
6436 TC_IMPLICIT_LCOMM_ALIGNMENT (temp
, align
);
6438 /* Still zero unless TC_IMPLICIT_LCOMM_ALIGNMENT set it. */
6440 record_alignment (bss_seg
, align
);
6447 /* Convert to a power of 2. */
6452 for (i
= 0; align
!= 0; align
>>= 1, ++i
)
6458 if (align
> max_alignment
)
6460 align
= max_alignment
;
6461 as_warn (_("alignment too large; %d assumed"), align
);
6466 as_warn (_("alignment negative; 0 assumed"));
6469 record_alignment (bss_seg
, align
);
6473 /* Assume some objects may require alignment on some systems. */
6474 #if defined (TC_ALPHA) && ! defined (VMS)
6477 align
= ffs (temp
) - 1;
6478 if (temp
% (1 << align
))
6485 symbolP
= symbol_find_or_make (name
);
6489 #if (defined (OBJ_AOUT) || defined (OBJ_MAYBE_AOUT) \
6490 || defined (OBJ_BOUT) || defined (OBJ_MAYBE_BOUT))
6491 #ifdef BFD_ASSEMBLER
6492 (OUTPUT_FLAVOR
!= bfd_target_aout_flavour
6493 || (S_GET_OTHER (symbolP
) == 0 && S_GET_DESC (symbolP
) == 0)) &&
6495 (S_GET_OTHER (symbolP
) == 0 && S_GET_DESC (symbolP
) == 0) &&
6498 (S_GET_SEGMENT (symbolP
) == bss_seg
|| (!S_IS_DEFINED (symbolP
) && S_GET_VALUE (symbolP
) == 0)))
6502 subseg_set (bss_seg
, 1);
6505 frag_align (align
, 0, 0);
6507 /* Detach from old frag. */
6508 if (S_GET_SEGMENT (symbolP
) == bss_seg
)
6509 symbol_get_frag (symbolP
)->fr_symbol
= NULL
;
6511 symbol_set_frag (symbolP
, frag_now
);
6512 pfrag
= frag_var (rs_org
, 1, 1, (relax_substateT
) 0, symbolP
, (offsetT
) temp
, NULL
);
6516 S_SET_SEGMENT (symbolP
, bss_seg
);
6519 /* The symbol may already have been created with a preceding
6520 ".globl" directive -- be careful not to step on storage class
6521 in that case. Otherwise, set it to static. */
6522 if (S_GET_STORAGE_CLASS (symbolP
) != C_EXT
)
6524 S_SET_STORAGE_CLASS (symbolP
, C_STAT
);
6526 #endif /* OBJ_COFF */
6529 S_SET_SIZE (symbolP
, temp
);
6533 as_bad (_("symbol `%s' is already defined"), S_GET_NAME (symbolP
));
6535 subseg_set (current_seg
, current_subseg
);
6537 demand_empty_rest_of_line ();
6541 insert_reg (const struct reg_entry
*r
, struct hash_control
*htab
)
6544 int len
= strlen (r
->name
) + 2;
6545 char *buf
= xmalloc (len
);
6546 char *buf2
= xmalloc (len
);
6548 strcpy (buf
+ i
, r
->name
);
6549 for (i
= 0; buf
[i
]; i
++)
6551 buf2
[i
] = TOUPPER (buf
[i
]);
6555 hash_insert (htab
, buf
, (void *) r
);
6556 hash_insert (htab
, buf2
, (void *) r
);
6560 build_reg_hsh (struct reg_map
*map
)
6562 const struct reg_entry
*r
;
6564 if ((map
->htab
= hash_new ()) == NULL
)
6566 as_fatal (_("virtual memory exhausted"));
6568 for (r
= map
->names
; r
->name
!= NULL
; r
++)
6570 insert_reg (r
, map
->htab
);
6581 if ((score_ops_hsh
= hash_new ()) == NULL
)
6582 as_fatal (_("virtual memory exhausted"));
6584 build_score_ops_hsh ();
6586 if ((dependency_insn_hsh
= hash_new ()) == NULL
)
6587 as_fatal (_("virtual memory exhausted"));
6589 build_dependency_insn_hsh ();
6591 for (i
= (int)REG_TYPE_FIRST
; i
< (int)REG_TYPE_MAX
; i
++)
6592 build_reg_hsh (all_reg_maps
+ i
);
6594 /* Initialize dependency vector. */
6595 init_dependency_vector ();
6597 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
, 0);
6599 subseg
= now_subseg
;
6600 pdr_seg
= subseg_new (".pdr", (subsegT
) 0);
6601 (void)bfd_set_section_flags (stdoutput
, pdr_seg
, SEC_READONLY
| SEC_RELOC
| SEC_DEBUGGING
);
6602 (void)bfd_set_section_alignment (stdoutput
, pdr_seg
, 2);
6603 subseg_set (seg
, subseg
);
6605 if (USE_GLOBAL_POINTER_OPT
)
6606 bfd_set_gp_size (stdoutput
, g_switch_value
);
6610 const pseudo_typeS md_pseudo_table
[] =
6612 {"bss", s_score_bss
, 0},
6613 {"text", s_score_text
, 0},
6616 {"extend", float_cons
, 'x'},
6617 {"ldouble", float_cons
, 'x'},
6618 {"packed", float_cons
, 'p'},
6619 {"end", s_score_end
, 0},
6620 {"ent", s_score_ent
, 0},
6621 {"frame", s_score_frame
, 0},
6622 {"rdata", s_change_sec
, 'r'},
6623 {"sdata", s_change_sec
, 's'},
6624 {"set", s_score_set
, 0},
6625 {"mask", s_score_mask
, 'R'},
6627 {"lcomm", s_score_lcomm
, 1},
6628 {"section", score_s_section
, 0},
6629 {"cpload", s_score_cpload
, 0},
6630 {"cprestore", s_score_cprestore
, 0},
6631 {"gpword", s_score_gpword
, 0},
6632 {"cpadd", s_score_cpadd
, 0},