1 /* tc-score.c -- Assembler for Score
2 Copyright 2006, 2007 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 3, 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 /* Used to contain constructed error messages. */
107 static char err_msg
[255];
109 fragS
*score_fragp
= 0;
110 static int fix_data_dependency
= 0;
111 static int warn_fix_data_dependency
= 1;
112 static int score7
= 1;
113 static int university_version
= 0;
115 static int in_my_get_expression
= 0;
117 #define USE_GLOBAL_POINTER_OPT 1
118 #define SCORE_BI_ENDIAN
120 /* Default, pop warning message when using r1. */
123 /* Default will do instruction relax, -O0 will set g_opt = 0. */
124 static unsigned int g_opt
= 1;
126 /* The size of the small data section. */
127 static unsigned int g_switch_value
= 8;
130 /* Pre-defined "_GLOBAL_OFFSET_TABLE_" */
135 enum score_pic_level score_pic
= NO_PIC
;
137 #define INSN_NAME_LEN 16
140 char name
[INSN_NAME_LEN
];
141 unsigned long instruction
;
142 unsigned long relax_inst
;
145 enum score_insn_type type
;
146 char str
[MAX_LITERAL_POOL_SIZE
];
149 char reg
[INSN_NAME_LEN
];
152 bfd_reloc_code_real_type type
;
157 struct score_it inst
;
162 unsigned long reg_mask
;
163 unsigned long reg_offset
;
164 unsigned long fpreg_mask
;
166 unsigned long frame_offset
;
167 unsigned long frame_reg
;
168 unsigned long pc_reg
;
172 static procS cur_proc
;
173 static procS
*cur_proc_ptr
;
176 #define SCORE7_PIPELINE 7
177 #define SCORE5_PIPELINE 5
178 static int vector_size
= SCORE7_PIPELINE
;
179 struct score_it dependency_vector
[SCORE7_PIPELINE
];
181 /* Relax will need some padding for alignment. */
182 #define RELAX_PAD_BYTE 3
184 /* Number of littlenums required to hold an extended precision number. For md_atof. */
185 #define NUM_FLOAT_VALS 8
186 #define MAX_LITTLENUMS 6
187 LITTLENUM_TYPE fp_values
[NUM_FLOAT_VALS
][MAX_LITTLENUMS
];
189 /* Structure for a hash table entry for a register. */
196 static const struct reg_entry score_rn_table
[] =
198 {"r0", 0}, {"r1", 1}, {"r2", 2}, {"r3", 3},
199 {"r4", 4}, {"r5", 5}, {"r6", 6}, {"r7", 7},
200 {"r8", 8}, {"r9", 9}, {"r10", 10}, {"r11", 11},
201 {"r12", 12}, {"r13", 13}, {"r14", 14}, {"r15", 15},
202 {"r16", 16}, {"r17", 17}, {"r18", 18}, {"r19", 19},
203 {"r20", 20}, {"r21", 21}, {"r22", 22}, {"r23", 23},
204 {"r24", 24}, {"r25", 25}, {"r26", 26}, {"r27", 27},
205 {"r28", 28}, {"r29", 29}, {"r30", 30}, {"r31", 31},
209 static const struct reg_entry score_srn_table
[] =
211 {"sr0", 0}, {"sr1", 1}, {"sr2", 2},
215 static const struct reg_entry score_crn_table
[] =
217 {"cr0", 0}, {"cr1", 1}, {"cr2", 2}, {"cr3", 3},
218 {"cr4", 4}, {"cr5", 5}, {"cr6", 6}, {"cr7", 7},
219 {"cr8", 8}, {"cr9", 9}, {"cr10", 10}, {"cr11", 11},
220 {"cr12", 12}, {"cr13", 13}, {"cr14", 14}, {"cr15", 15},
221 {"cr16", 16}, {"cr17", 17}, {"cr18", 18}, {"cr19", 19},
222 {"cr20", 20}, {"cr21", 21}, {"cr22", 22}, {"cr23", 23},
223 {"cr24", 24}, {"cr25", 25}, {"cr26", 26}, {"cr27", 27},
224 {"cr28", 28}, {"cr29", 29}, {"cr30", 30}, {"cr31", 31},
230 const struct reg_entry
*names
;
232 struct hash_control
*htab
;
233 const char *expected
;
236 struct reg_map all_reg_maps
[] =
238 {score_rn_table
, 31, NULL
, N_("S+core register expected")},
239 {score_srn_table
, 2, NULL
, N_("S+core special-register expected")},
240 {score_crn_table
, 31, NULL
, N_("S+core co-processor register expected")},
243 static struct hash_control
*score_ops_hsh
= NULL
;
245 static struct hash_control
*dependency_insn_hsh
= NULL
;
247 /* Enumeration matching entries in table above. */
251 #define REG_TYPE_FIRST REG_TYPE_SCORE
252 REG_TYPE_SCORE_SR
= 1,
253 REG_TYPE_SCORE_CR
= 2,
257 typedef struct literalS
259 struct expressionS exp
;
260 struct score_it
*inst
;
264 literalT literals
[MAX_LITERAL_POOL_SIZE
];
266 static void do_ldst_insn (char *);
267 static void do_crdcrscrsimm5 (char *);
268 static void do_ldst_unalign (char *);
269 static void do_ldst_atomic (char *);
270 static void do_ldst_cop (char *);
271 static void do_macro_li_rdi32 (char *);
272 static void do_macro_la_rdi32 (char *);
273 static void do_macro_rdi32hi (char *);
274 static void do_macro_rdi32lo (char *);
275 static void do_macro_mul_rdrsrs (char *);
276 static void do_macro_ldst_label (char *);
277 static void do_branch (char *);
278 static void do_jump (char *);
279 static void do_empty (char *);
280 static void do_rdrsrs (char *);
281 static void do_rdsi16 (char *);
282 static void do_rdrssi14 (char *);
283 static void do_sub_rdsi16 (char *);
284 static void do_sub_rdrssi14 (char *);
285 static void do_rdrsi5 (char *);
286 static void do_rdrsi14 (char *);
287 static void do_rdi16 (char *);
288 static void do_xrsi5 (char *);
289 static void do_rdrs (char *);
290 static void do_rdxrs (char *);
291 static void do_rsrs (char *);
292 static void do_rdcrs (char *);
293 static void do_rdsrs (char *);
294 static void do_rd (char *);
295 static void do_rs (char *);
296 static void do_i15 (char *);
297 static void do_xi5x (char *);
298 static void do_ceinst (char *);
299 static void do_cache (char *);
300 static void do16_rdrs (char *);
301 static void do16_rs (char *);
302 static void do16_xrs (char *);
303 static void do16_mv_rdrs (char *);
304 static void do16_hrdrs (char *);
305 static void do16_rdhrs (char *);
306 static void do16_rdi4 (char *);
307 static void do16_rdi5 (char *);
308 static void do16_xi5 (char *);
309 static void do16_ldst_insn (char *);
310 static void do16_ldst_imm_insn (char *);
311 static void do16_push_pop (char *);
312 static void do16_branch (char *);
313 static void do16_jump (char *);
314 static void do_rdi16_pic (char *);
315 static void do_addi_s_pic (char *);
316 static void do_addi_u_pic (char *);
317 static void do_lw_pic (char *);
319 static const struct asm_opcode score_ldst_insns
[] =
321 {"lw", 0x20000000, 0x3e000000, 0x2008, Rd_rvalueRs_SI15
, do_ldst_insn
},
322 {"lw", 0x06000000, 0x3e000007, 0x8000, Rd_rvalueRs_preSI12
, do_ldst_insn
},
323 {"lw", 0x0e000000, 0x3e000007, 0x200a, Rd_rvalueRs_postSI12
, do_ldst_insn
},
324 {"lh", 0x22000000, 0x3e000000, 0x2009, Rd_rvalueRs_SI15
, do_ldst_insn
},
325 {"lh", 0x06000001, 0x3e000007, 0x8000, Rd_rvalueRs_preSI12
, do_ldst_insn
},
326 {"lh", 0x0e000001, 0x3e000007, 0x8000, Rd_rvalueRs_postSI12
, do_ldst_insn
},
327 {"lhu", 0x24000000, 0x3e000000, 0x8000, Rd_rvalueRs_SI15
, do_ldst_insn
},
328 {"lhu", 0x06000002, 0x3e000007, 0x8000, Rd_rvalueRs_preSI12
, do_ldst_insn
},
329 {"lhu", 0x0e000002, 0x3e000007, 0x8000, Rd_rvalueRs_postSI12
, do_ldst_insn
},
330 {"lb", 0x26000000, 0x3e000000, 0x8000, Rd_rvalueRs_SI15
, do_ldst_insn
},
331 {"lb", 0x06000003, 0x3e000007, 0x8000, Rd_rvalueRs_preSI12
, do_ldst_insn
},
332 {"lb", 0x0e000003, 0x3e000007, 0x8000, Rd_rvalueRs_postSI12
, do_ldst_insn
},
333 {"sw", 0x28000000, 0x3e000000, 0x200c, Rd_lvalueRs_SI15
, do_ldst_insn
},
334 {"sw", 0x06000004, 0x3e000007, 0x200e, Rd_lvalueRs_preSI12
, do_ldst_insn
},
335 {"sw", 0x0e000004, 0x3e000007, 0x8000, Rd_lvalueRs_postSI12
, do_ldst_insn
},
336 {"sh", 0x2a000000, 0x3e000000, 0x200d, Rd_lvalueRs_SI15
, do_ldst_insn
},
337 {"sh", 0x06000005, 0x3e000007, 0x8000, Rd_lvalueRs_preSI12
, do_ldst_insn
},
338 {"sh", 0x0e000005, 0x3e000007, 0x8000, Rd_lvalueRs_postSI12
, do_ldst_insn
},
339 {"lbu", 0x2c000000, 0x3e000000, 0x200b, Rd_rvalueRs_SI15
, do_ldst_insn
},
340 {"lbu", 0x06000006, 0x3e000007, 0x8000, Rd_rvalueRs_preSI12
, do_ldst_insn
},
341 {"lbu", 0x0e000006, 0x3e000007, 0x8000, Rd_rvalueRs_postSI12
, do_ldst_insn
},
342 {"sb", 0x2e000000, 0x3e000000, 0x200f, Rd_lvalueRs_SI15
, do_ldst_insn
},
343 {"sb", 0x06000007, 0x3e000007, 0x8000, Rd_lvalueRs_preSI12
, do_ldst_insn
},
344 {"sb", 0x0e000007, 0x3e000007, 0x8000, Rd_lvalueRs_postSI12
, do_ldst_insn
},
347 static const struct asm_opcode score_insns
[] =
349 {"abs", 0x3800000a, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
350 {"abs.s", 0x3800004b, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
351 {"add", 0x00000010, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
352 {"add.c", 0x00000011, 0x3e0003ff, 0x2000, Rd_Rs_Rs
, do_rdrsrs
},
353 {"add.s", 0x38000048, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
354 {"addc", 0x00000012, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
355 {"addc.c", 0x00000013, 0x3e0003ff, 0x0009, Rd_Rs_Rs
, do_rdrsrs
},
356 {"addi", 0x02000000, 0x3e0e0001, 0x8000, Rd_SI16
, do_rdsi16
},
357 {"addi.c", 0x02000001, 0x3e0e0001, 0x8000, Rd_SI16
, do_rdsi16
},
358 {"addis", 0x0a000000, 0x3e0e0001, 0x8000, Rd_SI16
, do_rdi16
},
359 {"addis.c", 0x0a000001, 0x3e0e0001, 0x8000, Rd_SI16
, do_rdi16
},
360 {"addri", 0x10000000, 0x3e000001, 0x8000, Rd_Rs_SI14
, do_rdrssi14
},
361 {"addri.c", 0x10000001, 0x3e000001, 0x8000, Rd_Rs_SI14
, do_rdrssi14
},
362 {"addc!", 0x0009, 0x700f, 0x00000013, Rd_Rs
, do16_rdrs
},
363 {"add!", 0x2000, 0x700f, 0x00000011, Rd_Rs
, do16_rdrs
},
364 {"addei!", 0x6000 , 0x7087, 0x02000001, Rd_I4
, do16_rdi4
},
365 {"subi", 0x02000000, 0x3e0e0001, 0x8000, Rd_SI16
, do_sub_rdsi16
},
366 {"subi.c", 0x02000001, 0x3e0e0001, 0x8000, Rd_SI16
, do_sub_rdsi16
},
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
;
798 end_of_line (char *str
)
800 int retval
= SUCCESS
;
802 skip_whitespace (str
);
808 inst
.error
= BAD_GARBAGE
;
815 score_reg_parse (char **ccp
, struct hash_control
*htab
)
820 struct reg_entry
*reg
;
823 if (!ISALPHA (*p
) || !is_name_beginner (*p
))
828 while (ISALPHA (c
) || ISDIGIT (c
) || c
== '_')
832 reg
= (struct reg_entry
*) hash_find (htab
, start
);
843 /* If shift <= 0, only return reg. */
846 reg_required_here (char **str
, int shift
, enum score_reg_type reg_type
)
848 static char buff
[MAX_LITERAL_POOL_SIZE
];
849 int reg
= (int) FAIL
;
852 if ((reg
= score_reg_parse (str
, all_reg_maps
[reg_type
].htab
)) != (int) FAIL
)
854 if (reg_type
== REG_TYPE_SCORE
)
856 if ((reg
== 1) && (nor1
== 1) && (inst
.bwarn
== 0))
858 as_warn (_("Using temp register(r1)"));
864 if (reg_type
== REG_TYPE_SCORE_CR
)
865 strcpy (inst
.reg
, score_crn_table
[reg
].name
);
866 else if (reg_type
== REG_TYPE_SCORE_SR
)
867 strcpy (inst
.reg
, score_srn_table
[reg
].name
);
869 strcpy (inst
.reg
, "");
871 inst
.instruction
|= reg
<< shift
;
877 sprintf (buff
, _("register expected, not '%.100s'"), start
);
885 skip_past_comma (char **str
)
891 while ((c
= *p
) == ' ' || c
== ',')
894 if (c
== ',' && comma
++)
896 inst
.error
= BAD_SKIP_COMMA
;
901 if ((c
== '\0') || (comma
== 0))
903 inst
.error
= BAD_SKIP_COMMA
;
908 return comma
? SUCCESS
: (int) FAIL
;
912 do_rdrsrs (char *str
)
914 skip_whitespace (str
);
916 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) == (int) FAIL
917 || skip_past_comma (&str
) == (int) FAIL
918 || reg_required_here (&str
, 15, REG_TYPE_SCORE
) == (int) FAIL
919 || skip_past_comma (&str
) == (int) FAIL
920 || reg_required_here (&str
, 10, REG_TYPE_SCORE
) == (int) FAIL
921 || end_of_line (str
) == (int) FAIL
)
927 if ((((inst
.instruction
>> 15) & 0x10) == 0)
928 && (((inst
.instruction
>> 10) & 0x10) == 0)
929 && (((inst
.instruction
>> 20) & 0x10) == 0)
930 && (inst
.relax_inst
!= 0x8000)
931 && (((inst
.instruction
>> 20) & 0xf) == ((inst
.instruction
>> 15) & 0xf)))
933 inst
.relax_inst
|= (((inst
.instruction
>> 10) & 0xf) << 4)
934 | (((inst
.instruction
>> 15) & 0xf) << 8);
939 inst
.relax_inst
= 0x8000;
945 walk_no_bignums (symbolS
* sp
)
947 if (symbol_get_value_expression (sp
)->X_op
== O_big
)
950 if (symbol_get_value_expression (sp
)->X_add_symbol
)
951 return (walk_no_bignums (symbol_get_value_expression (sp
)->X_add_symbol
)
952 || (symbol_get_value_expression (sp
)->X_op_symbol
953 && walk_no_bignums (symbol_get_value_expression (sp
)->X_op_symbol
)));
959 my_get_expression (expressionS
* ep
, char **str
)
964 save_in
= input_line_pointer
;
965 input_line_pointer
= *str
;
966 in_my_get_expression
= 1;
967 seg
= expression (ep
);
968 in_my_get_expression
= 0;
970 if (ep
->X_op
== O_illegal
)
972 *str
= input_line_pointer
;
973 input_line_pointer
= save_in
;
974 inst
.error
= _("illegal expression");
977 /* Get rid of any bignums now, so that we don't generate an error for which
978 we can't establish a line number later on. Big numbers are never valid
979 in instructions, which is where this routine is always called. */
980 if (ep
->X_op
== O_big
982 && (walk_no_bignums (ep
->X_add_symbol
)
983 || (ep
->X_op_symbol
&& walk_no_bignums (ep
->X_op_symbol
)))))
985 inst
.error
= _("invalid constant");
986 *str
= input_line_pointer
;
987 input_line_pointer
= save_in
;
991 if ((ep
->X_add_symbol
!= NULL
)
992 && (inst
.type
!= PC_DISP19div2
)
993 && (inst
.type
!= PC_DISP8div2
)
994 && (inst
.type
!= PC_DISP24div2
)
995 && (inst
.type
!= PC_DISP11div2
)
996 && (inst
.type
!= Insn_Type_SYN
)
997 && (inst
.type
!= Rd_rvalueRs_SI15
)
998 && (inst
.type
!= Rd_lvalueRs_SI15
)
999 && (inst
.type
!= Insn_internal
))
1001 inst
.error
= BAD_ARGS
;
1002 *str
= input_line_pointer
;
1003 input_line_pointer
= save_in
;
1007 *str
= input_line_pointer
;
1008 input_line_pointer
= save_in
;
1012 /* Check if an immediate is valid. If so, convert it to the right format. */
1015 validate_immediate (int val
, unsigned int data_type
, int hex_p
)
1021 int val_hi
= ((val
& 0xffff0000) >> 16);
1023 if (score_df_range
[data_type
].range
[0] <= val_hi
1024 && val_hi
<= score_df_range
[data_type
].range
[1])
1031 int val_lo
= (val
& 0xffff);
1033 if (score_df_range
[data_type
].range
[0] <= val_lo
1034 && val_lo
<= score_df_range
[data_type
].range
[1])
1046 if (!(val
>= -0x2000 && val
<= 0x3fff))
1053 if (!(val
>= -8192 && val
<= 8191))
1065 if (!(val
>= -0x7fff && val
<= 0xffff && val
!= 0x8000))
1072 if (!(val
>= -32767 && val
<= 32768))
1083 if (data_type
== _SIMM14_NEG
|| data_type
== _IMM16_NEG
)
1086 if (score_df_range
[data_type
].range
[0] <= val
1087 && val
<= score_df_range
[data_type
].range
[1])
1097 data_op2 (char **str
, int shift
, enum score_data_type data_type
)
1100 char data_exp
[MAX_LITERAL_POOL_SIZE
];
1105 skip_whitespace (*str
);
1109 /* Set hex_p to zero. */
1112 while ((*dataptr
!= '\0') && (*dataptr
!= '|') && (cnt
<= MAX_LITERAL_POOL_SIZE
)) /* 0x7c = ='|' */
1114 data_exp
[cnt
] = *dataptr
;
1119 data_exp
[cnt
] = '\0';
1120 pp
= (char *)&data_exp
;
1122 if (*dataptr
== '|') /* process PCE */
1124 if (my_get_expression (&inst
.reloc
.exp
, &pp
) == (int) FAIL
)
1127 if (inst
.error
!= 0)
1128 return (int) FAIL
; /* to ouptut_inst to printf out the error */
1131 else /* process 16 bit */
1133 if (my_get_expression (&inst
.reloc
.exp
, str
) == (int) FAIL
)
1138 dataptr
= (char *)data_exp
;
1139 for (; *dataptr
!= '\0'; dataptr
++)
1141 *dataptr
= TOLOWER (*dataptr
);
1142 if (*dataptr
== '!' || *dataptr
== ' ')
1145 dataptr
= (char *)data_exp
;
1147 if ((dataptr
!= NULL
)
1148 && (((strstr (dataptr
, "0x")) != NULL
)
1149 || ((strstr (dataptr
, "0X")) != NULL
)))
1152 if ((data_type
!= _SIMM16_LA
)
1153 && (data_type
!= _VALUE_HI16
)
1154 && (data_type
!= _VALUE_LO16
)
1155 && (data_type
!= _IMM16
)
1156 && (data_type
!= _IMM15
)
1157 && (data_type
!= _IMM14
)
1158 && (data_type
!= _IMM4
)
1159 && (data_type
!= _IMM5
)
1160 && (data_type
!= _IMM8
)
1161 && (data_type
!= _IMM5_RSHIFT_1
)
1162 && (data_type
!= _IMM5_RSHIFT_2
)
1163 && (data_type
!= _SIMM14
)
1164 && (data_type
!= _SIMM14_NEG
)
1165 && (data_type
!= _SIMM16_NEG
)
1166 && (data_type
!= _IMM10_RSHIFT_2
)
1167 && (data_type
!= _GP_IMM15
))
1173 if ((inst
.reloc
.exp
.X_add_number
== 0)
1174 && (inst
.type
!= Insn_Type_SYN
)
1175 && (inst
.type
!= Rd_rvalueRs_SI15
)
1176 && (inst
.type
!= Rd_lvalueRs_SI15
)
1177 && (inst
.type
!= Insn_internal
)
1178 && (((*dataptr
>= 'a') && (*dataptr
<= 'z'))
1179 || ((*dataptr
== '0') && (*(dataptr
+ 1) == 'x') && (*(dataptr
+ 2) != '0'))
1180 || ((*dataptr
== '+') && (*(dataptr
+ 1) != '0'))
1181 || ((*dataptr
== '-') && (*(dataptr
+ 1) != '0'))))
1183 inst
.error
= BAD_ARGS
;
1188 if ((inst
.reloc
.exp
.X_add_symbol
)
1189 && ((data_type
== _SIMM16
)
1190 || (data_type
== _SIMM16_NEG
)
1191 || (data_type
== _IMM16_NEG
)
1192 || (data_type
== _SIMM14
)
1193 || (data_type
== _SIMM14_NEG
)
1194 || (data_type
== _IMM5
)
1195 || (data_type
== _IMM14
)
1196 || (data_type
== _IMM20
)
1197 || (data_type
== _IMM16
)
1198 || (data_type
== _IMM15
)
1199 || (data_type
== _IMM4
)))
1201 inst
.error
= BAD_ARGS
;
1205 if (inst
.reloc
.exp
.X_add_symbol
)
1212 inst
.reloc
.type
= BFD_RELOC_HI16_S
;
1213 inst
.reloc
.pc_rel
= 0;
1216 inst
.reloc
.type
= BFD_RELOC_LO16
;
1217 inst
.reloc
.pc_rel
= 0;
1220 inst
.reloc
.type
= BFD_RELOC_SCORE_GPREL15
;
1221 inst
.reloc
.pc_rel
= 0;
1224 case _IMM16_LO16_pic
:
1225 inst
.reloc
.type
= BFD_RELOC_SCORE_GOT_LO16
;
1226 inst
.reloc
.pc_rel
= 0;
1229 inst
.reloc
.type
= BFD_RELOC_32
;
1230 inst
.reloc
.pc_rel
= 0;
1236 if (data_type
== _IMM16_pic
)
1238 inst
.reloc
.type
= BFD_RELOC_SCORE_DUMMY_HI16
;
1239 inst
.reloc
.pc_rel
= 0;
1242 if (data_type
== _SIMM16_LA
&& inst
.reloc
.exp
.X_unsigned
== 1)
1244 value
= validate_immediate (inst
.reloc
.exp
.X_add_number
, _SIMM16_LA_POS
, hex_p
);
1245 if (value
== (int) FAIL
) /* for advance to check if this is ldis */
1246 if ((inst
.reloc
.exp
.X_add_number
& 0xffff) == 0)
1248 inst
.instruction
|= 0x8000000;
1249 inst
.instruction
|= ((inst
.reloc
.exp
.X_add_number
>> 16) << 1) & 0x1fffe;
1255 value
= validate_immediate (inst
.reloc
.exp
.X_add_number
, data_type
, hex_p
);
1258 if (value
== (int) FAIL
)
1260 if ((data_type
!= _SIMM14_NEG
) && (data_type
!= _SIMM16_NEG
) && (data_type
!= _IMM16_NEG
))
1263 _("invalid constant: %d bit expression not in range %d..%d"),
1264 score_df_range
[data_type
].bits
,
1265 score_df_range
[data_type
].range
[0], score_df_range
[data_type
].range
[1]);
1270 _("invalid constant: %d bit expression not in range %d..%d"),
1271 score_df_range
[data_type
].bits
,
1272 -score_df_range
[data_type
].range
[1], -score_df_range
[data_type
].range
[0]);
1275 inst
.error
= err_msg
;
1279 if ((score_df_range
[data_type
].range
[0] != 0) || (data_type
== _IMM5_RANGE_8_31
))
1281 value
&= (1 << score_df_range
[data_type
].bits
) - 1;
1284 inst
.instruction
|= value
<< shift
;
1287 if ((inst
.instruction
& 0xf0000000) == 0x30000000)
1289 if ((((inst
.instruction
>> 20) & 0x1F) != 0)
1290 && (((inst
.instruction
>> 20) & 0x1F) != 1)
1291 && (((inst
.instruction
>> 20) & 0x1F) != 2)
1292 && (((inst
.instruction
>> 20) & 0x1F) != 3)
1293 && (((inst
.instruction
>> 20) & 0x1F) != 4)
1294 && (((inst
.instruction
>> 20) & 0x1F) != 8)
1295 && (((inst
.instruction
>> 20) & 0x1F) != 9)
1296 && (((inst
.instruction
>> 20) & 0x1F) != 0xa)
1297 && (((inst
.instruction
>> 20) & 0x1F) != 0xb)
1298 && (((inst
.instruction
>> 20) & 0x1F) != 0xc)
1299 && (((inst
.instruction
>> 20) & 0x1F) != 0xd)
1300 && (((inst
.instruction
>> 20) & 0x1F) != 0xe)
1301 && (((inst
.instruction
>> 20) & 0x1F) != 0x10)
1302 && (((inst
.instruction
>> 20) & 0x1F) != 0x11)
1303 && (((inst
.instruction
>> 20) & 0x1F) != 0x18)
1304 && (((inst
.instruction
>> 20) & 0x1F) != 0x1A)
1305 && (((inst
.instruction
>> 20) & 0x1F) != 0x1B)
1306 && (((inst
.instruction
>> 20) & 0x1F) != 0x1d)
1307 && (((inst
.instruction
>> 20) & 0x1F) != 0x1e)
1308 && (((inst
.instruction
>> 20) & 0x1F) != 0x1f))
1310 inst
.error
= _("invalid constant: bit expression not defined");
1318 /* Handle addi/addi.c/addis.c/cmpi.c/addis.c/ldi. */
1321 do_rdsi16 (char *str
)
1323 skip_whitespace (str
);
1325 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) == (int) FAIL
1326 || skip_past_comma (&str
) == (int) FAIL
1327 || data_op2 (&str
, 1, _SIMM16
) == (int) FAIL
1328 || end_of_line (str
) == (int) FAIL
)
1332 if ((inst
.instruction
& 0x20c0000) == 0x20c0000)
1334 if ((((inst
.instruction
>> 20) & 0x10) == 0x10) || ((inst
.instruction
& 0x1fe00) != 0))
1336 inst
.relax_inst
= 0x8000;
1340 inst
.relax_inst
|= (inst
.instruction
>> 1) & 0xff;
1341 inst
.relax_inst
|= (((inst
.instruction
>> 20) & 0xf) << 8);
1342 inst
.relax_size
= 2;
1345 else if (((inst
.instruction
>> 20) & 0x10) == 0x10)
1347 inst
.relax_inst
= 0x8000;
1351 /* Handle subi/subi.c. */
1354 do_sub_rdsi16 (char *str
)
1356 skip_whitespace (str
);
1358 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) != (int) FAIL
1359 && skip_past_comma (&str
) != (int) FAIL
1360 && data_op2 (&str
, 1, _SIMM16_NEG
) != (int) FAIL
)
1364 /* Handle addri/addri.c. */
1367 do_rdrssi14 (char *str
) /* -(2^13)~((2^13)-1) */
1369 skip_whitespace (str
);
1371 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) != (int) FAIL
1372 && skip_past_comma (&str
) != (int) FAIL
1373 && reg_required_here (&str
, 15, REG_TYPE_SCORE
) != (int) FAIL
1374 && skip_past_comma (&str
) != (int) FAIL
)
1375 data_op2 (&str
, 1, _SIMM14
);
1378 /* Handle subri.c/subri. */
1380 do_sub_rdrssi14 (char *str
) /* -(2^13)~((2^13)-1) */
1382 skip_whitespace (str
);
1384 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) != (int) FAIL
1385 && skip_past_comma (&str
) != (int) FAIL
1386 && reg_required_here (&str
, 15, REG_TYPE_SCORE
) != (int) FAIL
1387 && skip_past_comma (&str
) != (int) FAIL
1388 && data_op2 (&str
, 1, _SIMM14_NEG
) != (int) FAIL
)
1392 /* Handle bitclr.c/bitset.c/bittgl.c/slli.c/srai.c/srli.c/roli.c/rori.c/rolic.c. */
1394 do_rdrsi5 (char *str
) /* 0~((2^14)-1) */
1396 skip_whitespace (str
);
1398 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) == (int) FAIL
1399 || skip_past_comma (&str
) == (int) FAIL
1400 || reg_required_here (&str
, 15, REG_TYPE_SCORE
) == (int) FAIL
1401 || skip_past_comma (&str
) == (int) FAIL
1402 || data_op2 (&str
, 10, _IMM5
) == (int) FAIL
1403 || end_of_line (str
) == (int) FAIL
)
1406 if ((((inst
.instruction
>> 20) & 0x1f) == ((inst
.instruction
>> 15) & 0x1f))
1407 && (inst
.relax_inst
!= 0x8000) && (((inst
.instruction
>> 15) & 0x10) == 0))
1409 inst
.relax_inst
|= (((inst
.instruction
>> 10) & 0x1f) << 3) | (((inst
.instruction
>> 15) & 0xf) << 8);
1410 inst
.relax_size
= 2;
1413 inst
.relax_inst
= 0x8000;
1416 /* Handle andri/orri/andri.c/orri.c. */
1419 do_rdrsi14 (char *str
) /* 0 ~ ((2^14)-1) */
1421 skip_whitespace (str
);
1423 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) != (int) FAIL
1424 && skip_past_comma (&str
) != (int) FAIL
1425 && reg_required_here (&str
, 15, REG_TYPE_SCORE
) != (int) FAIL
1426 && skip_past_comma (&str
) != (int) FAIL
1427 && data_op2 (&str
, 1, _IMM14
) != (int) FAIL
)
1431 /* Handle bittst.c. */
1433 do_xrsi5 (char *str
)
1435 skip_whitespace (str
);
1437 if (reg_required_here (&str
, 15, REG_TYPE_SCORE
) == (int) FAIL
1438 || skip_past_comma (&str
) == (int) FAIL
1439 || data_op2 (&str
, 10, _IMM5
) == (int) FAIL
1440 || end_of_line (str
) == (int) FAIL
)
1443 if ((inst
.relax_inst
!= 0x8000) && (((inst
.instruction
>> 15) & 0x10) == 0))
1445 inst
.relax_inst
|= (((inst
.instruction
>> 10) & 0x1f) << 3) | (((inst
.instruction
>> 15) & 0xf) << 8);
1446 inst
.relax_size
= 2;
1449 inst
.relax_inst
= 0x8000;
1452 /* Handle addis/andi/ori/andis/oris/ldis. */
1454 do_rdi16 (char *str
)
1456 skip_whitespace (str
);
1458 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) == (int) FAIL
1459 || skip_past_comma (&str
) == (int) FAIL
1460 || data_op2 (&str
, 1, _IMM16
) == (int) FAIL
1461 || end_of_line (str
) == (int) FAIL
)
1464 if (((inst.instruction & 0xa0dfffe) != 0xa0c0000) || ((((inst.instruction >> 20) & 0x1f) & 0x10) == 0x10))
1465 inst.relax_inst = 0x8000;
1467 inst.relax_size = 2;
1472 do_macro_rdi32hi (char *str
)
1474 skip_whitespace (str
);
1476 /* Do not handle end_of_line(). */
1477 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) != (int) FAIL
1478 && skip_past_comma (&str
) != (int) FAIL
)
1479 data_op2 (&str
, 1, _VALUE_HI16
);
1483 do_macro_rdi32lo (char *str
)
1485 skip_whitespace (str
);
1487 /* Do not handle end_of_line(). */
1488 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) != (int) FAIL
1489 && skip_past_comma (&str
) != (int) FAIL
)
1490 data_op2 (&str
, 1, _VALUE_LO16
);
1493 /* Handle ldis_pic. */
1496 do_rdi16_pic (char *str
)
1498 skip_whitespace (str
);
1500 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) != (int) FAIL
1501 && skip_past_comma (&str
) != (int) FAIL
1502 && data_op2 (&str
, 1, _IMM16_pic
) != (int) FAIL
)
1506 /* Handle addi_s_pic to generate R_SCORE_GOT_LO16 . */
1509 do_addi_s_pic (char *str
)
1511 skip_whitespace (str
);
1513 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) != (int) FAIL
1514 && skip_past_comma (&str
) != (int) FAIL
1515 && data_op2 (&str
, 1, _SIMM16_pic
) != (int) FAIL
)
1519 /* Handle addi_u_pic to generate R_SCORE_GOT_LO16 . */
1522 do_addi_u_pic (char *str
)
1524 skip_whitespace (str
);
1526 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) != (int) FAIL
1527 && skip_past_comma (&str
) != (int) FAIL
1528 && data_op2 (&str
, 1, _IMM16_LO16_pic
) != (int) FAIL
)
1532 /* Handle mfceh/mfcel/mtceh/mtchl. */
1537 skip_whitespace (str
);
1539 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) != (int) FAIL
)
1546 skip_whitespace (str
);
1548 if (reg_required_here (&str
, 15, REG_TYPE_SCORE
) == (int) FAIL
1549 || end_of_line (str
) == (int) FAIL
)
1552 if ((inst
.relax_inst
!= 0x8000) && (((inst
.instruction
>> 15) & 0x10) == 0))
1554 inst
.relax_inst
|= (((inst
.instruction
>> 10) & 0xf) << 8) | (((inst
.instruction
>> 15) & 0xf) << 4);
1555 inst
.relax_size
= 2;
1558 inst
.relax_inst
= 0x8000;
1564 skip_whitespace (str
);
1566 if (data_op2 (&str
, 10, _IMM15
) != (int) FAIL
)
1573 skip_whitespace (str
);
1575 if (data_op2 (&str
, 15, _IMM5
) == (int) FAIL
|| end_of_line (str
) == (int) FAIL
)
1578 if (inst
.relax_inst
!= 0x8000)
1580 inst
.relax_inst
|= (((inst
.instruction
>> 15) & 0x1f) << 3);
1581 inst
.relax_size
= 2;
1588 skip_whitespace (str
);
1590 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) == (int) FAIL
1591 || skip_past_comma (&str
) == (int) FAIL
1592 || reg_required_here (&str
, 15, REG_TYPE_SCORE
) == (int) FAIL
1593 || end_of_line (str
) == (int) FAIL
)
1596 if (inst
.relax_inst
!= 0x8000)
1598 if (((inst
.instruction
& 0x7f) == 0x56)) /* adjust mv -> mv! / mlfh! / mhfl! */
1601 if ((((inst
.instruction
>> 15) & 0x10) != 0x0) && (((inst
.instruction
>> 20) & 0x10) == 0))
1603 inst
.relax_inst
= 0x00000001 | (((inst
.instruction
>> 15) & 0xf) << 4)
1604 | (((inst
.instruction
>> 20) & 0xf) << 8);
1605 inst
.relax_size
= 2;
1608 else if ((((inst
.instruction
>> 15) & 0x10) == 0x0) && ((inst
.instruction
>> 20) & 0x10) != 0)
1610 inst
.relax_inst
= 0x00000002 | (((inst
.instruction
>> 15) & 0xf) << 4)
1611 | (((inst
.instruction
>> 20) & 0xf) << 8);
1612 inst
.relax_size
= 2;
1614 else if ((((inst
.instruction
>> 15) & 0x10) == 0x0) && (((inst
.instruction
>> 20) & 0x10) == 0))
1616 inst
.relax_inst
|= (((inst
.instruction
>> 15) & 0xf) << 4)
1617 | (((inst
.instruction
>> 20) & 0xf) << 8);
1618 inst
.relax_size
= 2;
1622 inst
.relax_inst
= 0x8000;
1625 else if ((((inst
.instruction
>> 15) & 0x10) == 0x0) && (((inst
.instruction
>> 20) & 0x10) == 0))
1627 inst
.relax_inst
|= (((inst
.instruction
>> 15) & 0xf) << 4)
1628 | (((inst
.instruction
>> 20) & 0xf) << 8);
1629 inst
.relax_size
= 2;
1633 inst
.relax_inst
= 0x8000;
1638 /* Handle mfcr/mtcr. */
1640 do_rdcrs (char *str
)
1642 skip_whitespace (str
);
1644 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) != (int) FAIL
1645 && skip_past_comma (&str
) != (int) FAIL
1646 && reg_required_here (&str
, 15, REG_TYPE_SCORE_CR
) != (int) FAIL
)
1650 /* Handle mfsr/mtsr. */
1653 do_rdsrs (char *str
)
1655 skip_whitespace (str
);
1658 if ((inst
.instruction
& 0xff) == 0x50)
1660 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) != (int) FAIL
1661 && skip_past_comma (&str
) != (int) FAIL
1662 && reg_required_here (&str
, 10, REG_TYPE_SCORE_SR
) != (int) FAIL
)
1667 if (reg_required_here (&str
, 15, REG_TYPE_SCORE
) != (int) FAIL
1668 && skip_past_comma (&str
) != (int) FAIL
)
1669 reg_required_here (&str
, 10, REG_TYPE_SCORE_SR
);
1676 do_rdxrs (char *str
)
1678 skip_whitespace (str
);
1680 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) == (int) FAIL
1681 || skip_past_comma (&str
) == (int) FAIL
1682 || reg_required_here (&str
, 10, REG_TYPE_SCORE
) == (int) FAIL
1683 || end_of_line (str
) == (int) FAIL
)
1686 if ((inst
.relax_inst
!= 0x8000) && (((inst
.instruction
>> 10) & 0x10) == 0)
1687 && (((inst
.instruction
>> 20) & 0x10) == 0))
1689 inst
.relax_inst
|= (((inst
.instruction
>> 10) & 0xf) << 4) | (((inst
.instruction
>> 20) & 0xf) << 8);
1690 inst
.relax_size
= 2;
1693 inst
.relax_inst
= 0x8000;
1696 /* Handle cmp.c/cmp<cond>. */
1700 skip_whitespace (str
);
1702 if (reg_required_here (&str
, 15, REG_TYPE_SCORE
) == (int) FAIL
1703 || skip_past_comma (&str
) == (int) FAIL
1704 || reg_required_here (&str
, 10, REG_TYPE_SCORE
) == (int) FAIL
1705 || end_of_line (str
) == (int) FAIL
)
1708 if ((inst
.relax_inst
!= 0x8000) && (((inst
.instruction
>> 20) & 0x1f) == 3)
1709 && (((inst
.instruction
>> 10) & 0x10) == 0) && (((inst
.instruction
>> 15) & 0x10) == 0))
1711 inst
.relax_inst
|= (((inst
.instruction
>> 10) & 0xf) << 4) | (((inst
.instruction
>> 15) & 0xf) << 8);
1712 inst
.relax_size
= 2;
1715 inst
.relax_inst
= 0x8000;
1719 do_ceinst (char *str
)
1724 skip_whitespace (str
);
1726 if (data_op2 (&str
, 20, _IMM5
) == (int) FAIL
1727 || skip_past_comma (&str
) == (int) FAIL
1728 || reg_required_here (&str
, 15, REG_TYPE_SCORE
) == (int) FAIL
1729 || skip_past_comma (&str
) == (int) FAIL
1730 || reg_required_here (&str
, 10, REG_TYPE_SCORE
) == (int) FAIL
1731 || skip_past_comma (&str
) == (int) FAIL
1732 || data_op2 (&str
, 5, _IMM5
) == (int) FAIL
1733 || skip_past_comma (&str
) == (int) FAIL
1734 || data_op2 (&str
, 0, _IMM5
) == (int) FAIL
1735 || end_of_line (str
) == (int) FAIL
)
1742 if (data_op2 (&str
, 0, _IMM25
) == (int) FAIL
)
1748 reglow_required_here (char **str
, int shift
)
1750 static char buff
[MAX_LITERAL_POOL_SIZE
];
1754 if ((reg
= score_reg_parse (str
, all_reg_maps
[REG_TYPE_SCORE
].htab
)) != (int) FAIL
)
1756 if ((reg
== 1) && (nor1
== 1) && (inst
.bwarn
== 0))
1758 as_warn (_("Using temp register(r1)"));
1764 inst
.instruction
|= reg
<< shift
;
1770 /* Restore the start point, we may have got a reg of the wrong class. */
1772 sprintf (buff
, _("low register(r0-r15)expected, not '%.100s'"), start
);
1777 /* Handle addc!/add!/and!/cmp!/neg!/not!/or!/sll!/srl!/sra!/xor!/sub!. */
1779 do16_rdrs (char *str
)
1781 skip_whitespace (str
);
1783 if (reglow_required_here (&str
, 8) == (int) FAIL
1784 || skip_past_comma (&str
) == (int) FAIL
1785 || reglow_required_here (&str
, 4) == (int) FAIL
1786 || end_of_line (str
) == (int) FAIL
)
1792 if ((inst
.instruction
& 0x700f) == 0x2003) /* cmp! */
1794 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 15)
1795 | (((inst
.instruction
>> 4) & 0xf) << 10);
1797 else if ((inst
.instruction
& 0x700f) == 0x2006) /* not! */
1799 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 20)
1800 | (((inst
.instruction
>> 4) & 0xf) << 15);
1804 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 20)
1805 | (((inst
.instruction
>> 8) & 0xf) << 15) | (((inst
.instruction
>> 4) & 0xf) << 10);
1807 inst
.relax_size
= 4;
1816 skip_whitespace (str
);
1818 if ((rd
= reglow_required_here (&str
, 4)) == (int) FAIL
1819 || end_of_line (str
) == (int) FAIL
)
1825 inst
.relax_inst
|= rd
<< 20;
1826 inst
.relax_size
= 4;
1830 /* Handle br!/brl!. */
1832 do16_xrs (char *str
)
1834 skip_whitespace (str
);
1836 if (reglow_required_here (&str
, 4) == (int) FAIL
|| end_of_line (str
) == (int) FAIL
)
1842 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 10)
1843 | (((inst
.instruction
>> 4) & 0xf) << 15);
1844 inst
.relax_size
= 4;
1849 reghigh_required_here (char **str
, int shift
)
1851 static char buff
[MAX_LITERAL_POOL_SIZE
];
1855 if ((reg
= score_reg_parse (str
, all_reg_maps
[REG_TYPE_SCORE
].htab
)) != (int) FAIL
)
1857 if (15 < reg
&& reg
< 32)
1860 inst
.instruction
|= (reg
& 0xf) << shift
;
1867 sprintf (buff
, _("high register(r16-r31)expected, not '%.100s'"), start
);
1874 do16_hrdrs (char *str
)
1876 skip_whitespace (str
);
1878 if (reghigh_required_here (&str
, 8) != (int) FAIL
1879 && skip_past_comma (&str
) != (int) FAIL
1880 && reglow_required_here (&str
, 4) != (int) FAIL
1881 && end_of_line (str
) != (int) FAIL
)
1883 inst
.relax_inst
|= ((((inst
.instruction
>> 8) & 0xf) | 0x10) << 20)
1884 | (((inst
.instruction
>> 4) & 0xf) << 15) | (0xf << 10);
1885 inst
.relax_size
= 4;
1891 do16_rdhrs (char *str
)
1893 skip_whitespace (str
);
1895 if (reglow_required_here (&str
, 8) != (int) FAIL
1896 && skip_past_comma (&str
) != (int) FAIL
1897 && reghigh_required_here (&str
, 4) != (int) FAIL
1898 && end_of_line (str
) != (int) FAIL
)
1900 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 20)
1901 | ((((inst
.instruction
>> 4) & 0xf) | 0x10) << 15) | (0xf << 10);
1902 inst
.relax_size
= 4;
1906 /* We need to be able to fix up arbitrary expressions in some statements.
1907 This is so that we can handle symbols that are an arbitrary distance from
1908 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
1909 which returns part of an address in a form which will be valid for
1910 a data instruction. We do this by pushing the expression into a symbol
1911 in the expr_section, and creating a fix for that. */
1913 fix_new_score (fragS
* frag
, int where
, short int size
, expressionS
* exp
, int pc_rel
, int reloc
)
1923 new_fix
= fix_new_exp (frag
, where
, size
, exp
, pc_rel
, reloc
);
1926 new_fix
= fix_new (frag
, where
, size
, make_expr_symbol (exp
), 0, pc_rel
, reloc
);
1933 init_dependency_vector (void)
1937 for (i
= 0; i
< vector_size
; i
++)
1938 memset (&dependency_vector
[i
], '\0', sizeof (dependency_vector
[i
]));
1943 static enum insn_type_for_dependency
1944 dependency_type_from_insn (char *insn_name
)
1946 char name
[INSN_NAME_LEN
];
1947 const struct insn_to_dependency
*tmp
;
1949 strcpy (name
, insn_name
);
1950 tmp
= (const struct insn_to_dependency
*) hash_find (dependency_insn_hsh
, name
);
1959 check_dependency (char *pre_insn
, char *pre_reg
,
1960 char *cur_insn
, char *cur_reg
, int *warn_or_error
)
1964 enum insn_type_for_dependency pre_insn_type
;
1965 enum insn_type_for_dependency cur_insn_type
;
1967 pre_insn_type
= dependency_type_from_insn (pre_insn
);
1968 cur_insn_type
= dependency_type_from_insn (cur_insn
);
1970 for (i
= 0; i
< sizeof (data_dependency_table
) / sizeof (data_dependency_table
[0]); i
++)
1972 if ((pre_insn_type
== data_dependency_table
[i
].pre_insn_type
)
1973 && (D_all_insn
== data_dependency_table
[i
].cur_insn_type
1974 || cur_insn_type
== data_dependency_table
[i
].cur_insn_type
)
1975 && (strcmp (data_dependency_table
[i
].pre_reg
, "") == 0
1976 || strcmp (data_dependency_table
[i
].pre_reg
, pre_reg
) == 0)
1977 && (strcmp (data_dependency_table
[i
].cur_reg
, "") == 0
1978 || strcmp (data_dependency_table
[i
].cur_reg
, cur_reg
) == 0))
1980 bubbles
= (score7
) ? data_dependency_table
[i
].bubblenum_7
: data_dependency_table
[i
].bubblenum_5
;
1981 *warn_or_error
= data_dependency_table
[i
].warn_or_error
;
1990 build_one_frag (struct score_it one_inst
)
1993 int relaxable_p
= g_opt
;
1996 /* Start a new frag if frag_now is not empty. */
1997 if (frag_now_fix () != 0)
1999 if (!frag_now
->tc_frag_data
.is_insn
)
2000 frag_wane (frag_now
);
2006 p
= frag_more (one_inst
.size
);
2007 md_number_to_chars (p
, one_inst
.instruction
, one_inst
.size
);
2010 dwarf2_emit_insn (one_inst
.size
);
2013 relaxable_p
&= (one_inst
.relax_size
!= 0);
2014 relax_size
= relaxable_p
? one_inst
.relax_size
: 0;
2016 p
= frag_var (rs_machine_dependent
, relax_size
+ RELAX_PAD_BYTE
, 0,
2017 RELAX_ENCODE (one_inst
.size
, one_inst
.relax_size
,
2018 one_inst
.type
, 0, 0, relaxable_p
),
2022 md_number_to_chars (p
, one_inst
.relax_inst
, relax_size
);
2026 handle_dependency (struct score_it
*theinst
)
2029 int warn_or_error
= 0; /* warn - 0; error - 1 */
2031 int remainder_bubbles
= 0;
2032 char cur_insn
[INSN_NAME_LEN
];
2033 char pre_insn
[INSN_NAME_LEN
];
2034 struct score_it nop_inst
;
2035 struct score_it pflush_inst
;
2037 nop_inst
.instruction
= 0x0000;
2039 nop_inst
.relax_inst
= 0x80008000;
2040 nop_inst
.relax_size
= 4;
2041 nop_inst
.type
= NO16_OPD
;
2043 pflush_inst
.instruction
= 0x8000800a;
2044 pflush_inst
.size
= 4;
2045 pflush_inst
.relax_inst
= 0x8000;
2046 pflush_inst
.relax_size
= 0;
2047 pflush_inst
.type
= NO_OPD
;
2049 /* pflush will clear all data dependency. */
2050 if (strcmp (theinst
->name
, "pflush") == 0)
2052 init_dependency_vector ();
2056 /* Push current instruction to dependency_vector[0]. */
2057 for (i
= vector_size
- 1; i
> 0; i
--)
2058 memcpy (&dependency_vector
[i
], &dependency_vector
[i
- 1], sizeof (dependency_vector
[i
]));
2060 memcpy (&dependency_vector
[0], theinst
, sizeof (dependency_vector
[i
]));
2062 /* There is no dependency between nop and any instruction. */
2063 if (strcmp (dependency_vector
[0].name
, "nop") == 0
2064 || strcmp (dependency_vector
[0].name
, "nop!") == 0)
2067 /* "pce" is defined in insn_to_dependency_table. */
2068 #define PCE_NAME "pce"
2070 if (dependency_vector
[0].type
== Insn_Type_PCE
)
2071 strcpy (cur_insn
, PCE_NAME
);
2073 strcpy (cur_insn
, dependency_vector
[0].name
);
2075 for (i
= 1; i
< vector_size
; i
++)
2077 /* The element of dependency_vector is NULL. */
2078 if (dependency_vector
[i
].name
[0] == '\0')
2081 if (dependency_vector
[i
].type
== Insn_Type_PCE
)
2082 strcpy (pre_insn
, PCE_NAME
);
2084 strcpy (pre_insn
, dependency_vector
[i
].name
);
2086 bubbles
= check_dependency (pre_insn
, dependency_vector
[i
].reg
,
2087 cur_insn
, dependency_vector
[0].reg
, &warn_or_error
);
2088 remainder_bubbles
= bubbles
- i
+ 1;
2090 if (remainder_bubbles
> 0)
2094 if (fix_data_dependency
== 1)
2096 if (remainder_bubbles
<= 2)
2098 if (warn_fix_data_dependency
)
2099 as_warn (_("Fix data dependency: %s %s -- %s %s (insert %d nop!/%d)"),
2100 dependency_vector
[i
].name
, dependency_vector
[i
].reg
,
2101 dependency_vector
[0].name
, dependency_vector
[0].reg
,
2102 remainder_bubbles
, bubbles
);
2104 for (j
= (vector_size
- 1); (j
- remainder_bubbles
) > 0; j
--)
2105 memcpy (&dependency_vector
[j
], &dependency_vector
[j
- remainder_bubbles
],
2106 sizeof (dependency_vector
[j
]));
2108 for (j
= 1; j
<= remainder_bubbles
; j
++)
2110 memset (&dependency_vector
[j
], '\0', sizeof (dependency_vector
[j
]));
2112 build_one_frag (nop_inst
);
2117 if (warn_fix_data_dependency
)
2118 as_warn (_("Fix data dependency: %s %s -- %s %s (insert 1 pflush/%d)"),
2119 dependency_vector
[i
].name
, dependency_vector
[i
].reg
,
2120 dependency_vector
[0].name
, dependency_vector
[0].reg
,
2123 for (j
= 1; j
< vector_size
; j
++)
2124 memset (&dependency_vector
[j
], '\0', sizeof (dependency_vector
[j
]));
2126 /* Insert pflush. */
2127 build_one_frag (pflush_inst
);
2134 as_bad (_("data dependency: %s %s -- %s %s (%d/%d bubble)"),
2135 dependency_vector
[i
].name
, dependency_vector
[i
].reg
,
2136 dependency_vector
[0].name
, dependency_vector
[0].reg
,
2137 remainder_bubbles
, bubbles
);
2141 as_warn (_("data dependency: %s %s -- %s %s (%d/%d bubble)"),
2142 dependency_vector
[i
].name
, dependency_vector
[i
].reg
,
2143 dependency_vector
[0].name
, dependency_vector
[0].reg
,
2144 remainder_bubbles
, bubbles
);
2151 static enum insn_class
2152 get_insn_class_from_type (enum score_insn_type type
)
2154 enum insn_class retval
= (int) FAIL
;
2160 case Rd_rvalueBP_I5
:
2161 case Rd_lvalueBP_I5
:
2172 retval
= INSN_CLASS_16
;
2181 case Rd_rvalueRs_SI10
:
2182 case Rd_lvalueRs_SI10
:
2183 case Rd_rvalueRs_preSI12
:
2184 case Rd_rvalueRs_postSI12
:
2185 case Rd_lvalueRs_preSI12
:
2186 case Rd_lvalueRs_postSI12
:
2188 case Rd_rvalueRs_SI15
:
2189 case Rd_lvalueRs_SI15
:
2198 case OP5_rvalueRs_SI15
:
2199 case I5_Rs_Rs_I5_OP5
:
2200 case x_rvalueRs_post4
:
2201 case Rd_rvalueRs_post4
:
2203 case Rd_lvalueRs_post4
:
2204 case x_lvalueRs_post4
:
2212 retval
= INSN_CLASS_32
;
2215 retval
= INSN_CLASS_PCE
;
2218 retval
= INSN_CLASS_SYN
;
2227 static unsigned long
2228 adjust_paritybit (unsigned long m_code
, enum insn_class
class)
2230 unsigned long result
= 0;
2231 unsigned long m_code_high
= 0;
2232 unsigned long m_code_low
= 0;
2233 unsigned long pb_high
= 0;
2234 unsigned long pb_low
= 0;
2236 if (class == INSN_CLASS_32
)
2238 pb_high
= 0x80000000;
2239 pb_low
= 0x00008000;
2241 else if (class == INSN_CLASS_16
)
2246 else if (class == INSN_CLASS_PCE
)
2249 pb_low
= 0x00008000;
2251 else if (class == INSN_CLASS_SYN
)
2253 /* FIXME. at this time, INSN_CLASS_SYN must be 32 bit, but, instruction type should
2254 be changed if macro instruction has been expanded. */
2255 pb_high
= 0x80000000;
2256 pb_low
= 0x00008000;
2263 m_code_high
= m_code
& 0x3fff8000;
2264 m_code_low
= m_code
& 0x00007fff;
2265 result
= pb_high
| (m_code_high
<< 1) | pb_low
| m_code_low
;
2271 gen_insn_frag (struct score_it
*part_1
, struct score_it
*part_2
)
2274 bfd_boolean pce_p
= FALSE
;
2275 int relaxable_p
= g_opt
;
2277 struct score_it
*inst1
= part_1
;
2278 struct score_it
*inst2
= part_2
;
2279 struct score_it backup_inst1
;
2281 pce_p
= (inst2
) ? TRUE
: FALSE
;
2282 memcpy (&backup_inst1
, inst1
, sizeof (struct score_it
));
2284 /* Adjust instruction opcode and to be relaxed instruction opcode. */
2287 backup_inst1
.instruction
= ((backup_inst1
.instruction
& 0x7FFF) << 15)
2288 | (inst2
->instruction
& 0x7FFF);
2289 backup_inst1
.instruction
= adjust_paritybit (backup_inst1
.instruction
, INSN_CLASS_PCE
);
2290 backup_inst1
.relax_inst
= 0x8000;
2291 backup_inst1
.size
= INSN_SIZE
;
2292 backup_inst1
.relax_size
= 0;
2293 backup_inst1
.type
= Insn_Type_PCE
;
2297 backup_inst1
.instruction
= adjust_paritybit (backup_inst1
.instruction
,
2298 GET_INSN_CLASS (backup_inst1
.type
));
2301 if (backup_inst1
.relax_size
!= 0)
2303 enum insn_class tmp
;
2305 tmp
= (backup_inst1
.size
== INSN_SIZE
) ? INSN_CLASS_16
: INSN_CLASS_32
;
2306 backup_inst1
.relax_inst
= adjust_paritybit (backup_inst1
.relax_inst
, tmp
);
2309 /* Check data dependency. */
2310 handle_dependency (&backup_inst1
);
2312 /* Start a new frag if frag_now is not empty and is not instruction frag, maybe it contains
2313 data produced by .ascii etc. Doing this is to make one instruction per frag. */
2314 if (frag_now_fix () != 0)
2316 if (!frag_now
->tc_frag_data
.is_insn
)
2317 frag_wane (frag_now
);
2322 /* Here, we must call frag_grow in order to keep the instruction frag type is
2323 rs_machine_dependent.
2324 For, frag_var may change frag_now->fr_type to rs_fill by calling frag_grow which
2325 acturally will call frag_wane.
2326 Calling frag_grow first will create a new frag_now which free size is 20 that is enough
2330 p
= frag_more (backup_inst1
.size
);
2331 md_number_to_chars (p
, backup_inst1
.instruction
, backup_inst1
.size
);
2334 dwarf2_emit_insn (backup_inst1
.size
);
2337 /* Generate fixup structure. */
2340 if (inst1
->reloc
.type
!= BFD_RELOC_NONE
)
2341 fix_new_score (frag_now
, p
- frag_now
->fr_literal
,
2342 inst1
->size
, &inst1
->reloc
.exp
,
2343 inst1
->reloc
.pc_rel
, inst1
->reloc
.type
);
2345 if (inst2
->reloc
.type
!= BFD_RELOC_NONE
)
2346 fix_new_score (frag_now
, p
- frag_now
->fr_literal
+ 2,
2347 inst2
->size
, &inst2
->reloc
.exp
, inst2
->reloc
.pc_rel
, inst2
->reloc
.type
);
2351 if (backup_inst1
.reloc
.type
!= BFD_RELOC_NONE
)
2352 fix_new_score (frag_now
, p
- frag_now
->fr_literal
,
2353 backup_inst1
.size
, &backup_inst1
.reloc
.exp
,
2354 backup_inst1
.reloc
.pc_rel
, backup_inst1
.reloc
.type
);
2357 /* relax_size may be 2, 4, 12 or 0, 0 indicates no relaxation. */
2358 relaxable_p
&= (backup_inst1
.relax_size
!= 0);
2359 relax_size
= relaxable_p
? backup_inst1
.relax_size
: 0;
2361 p
= frag_var (rs_machine_dependent
, relax_size
+ RELAX_PAD_BYTE
, 0,
2362 RELAX_ENCODE (backup_inst1
.size
, backup_inst1
.relax_size
,
2363 backup_inst1
.type
, 0, 0, relaxable_p
),
2364 backup_inst1
.reloc
.exp
.X_add_symbol
, 0, NULL
);
2367 md_number_to_chars (p
, backup_inst1
.relax_inst
, relax_size
);
2369 memcpy (inst1
, &backup_inst1
, sizeof (struct score_it
));
2373 parse_16_32_inst (char *insnstr
, bfd_boolean gen_frag_p
)
2377 char *operator = insnstr
;
2378 const struct asm_opcode
*opcode
;
2380 /* Parse operator and operands. */
2381 skip_whitespace (operator);
2383 for (p
= operator; *p
!= '\0'; p
++)
2384 if ((*p
== ' ') || (*p
== '!'))
2393 opcode
= (const struct asm_opcode
*) hash_find (score_ops_hsh
, operator);
2396 memset (&inst
, '\0', sizeof (inst
));
2397 sprintf (inst
.str
, "%s", insnstr
);
2400 inst
.instruction
= opcode
->value
;
2401 inst
.relax_inst
= opcode
->relax_value
;
2402 inst
.type
= opcode
->type
;
2403 inst
.size
= GET_INSN_SIZE (inst
.type
);
2404 inst
.relax_size
= 0;
2406 sprintf (inst
.name
, "%s", opcode
->template);
2407 strcpy (inst
.reg
, "");
2409 inst
.reloc
.type
= BFD_RELOC_NONE
;
2411 (*opcode
->parms
) (p
);
2413 /* It indicates current instruction is a macro instruction if inst.bwarn equals -1. */
2414 if ((inst
.bwarn
!= -1) && (!inst
.error
) && (gen_frag_p
))
2415 gen_insn_frag (&inst
, NULL
);
2418 inst
.error
= _("unrecognized opcode");
2422 append_insn (char *str
, bfd_boolean gen_frag_p
)
2424 int retval
= SUCCESS
;
2426 parse_16_32_inst (str
, gen_frag_p
);
2430 retval
= (int) FAIL
;
2431 as_bad (_("%s -- `%s'"), inst
.error
, inst
.str
);
2438 /* Handle mv! reg_high, reg_low;
2439 mv! reg_low, reg_high;
2440 mv! reg_low, reg_low; */
2442 do16_mv_rdrs (char *str
)
2446 char *backupstr
= NULL
;
2449 skip_whitespace (str
);
2451 if ((reg_rd
= reg_required_here (&str
, 8, REG_TYPE_SCORE
)) == (int) FAIL
2452 || skip_past_comma (&str
) == (int) FAIL
2453 || (reg_rs
= reg_required_here (&str
, 4, REG_TYPE_SCORE
)) == (int) FAIL
2454 || end_of_line (str
) == (int) FAIL
)
2460 /* Case 1 : mv! or mlfh!. */
2465 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 20)
2466 | (((inst
.instruction
>> 4) & 0xf) << 15) | (0xf << 10);
2467 inst
.relax_size
= 4;
2471 char append_str
[MAX_LITERAL_POOL_SIZE
];
2473 sprintf (append_str
, "mlfh! %s", backupstr
);
2474 if (append_insn (append_str
, TRUE
) == (int) FAIL
)
2476 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
2480 /* Case 2 : mhfl!. */
2485 SET_INSN_ERROR (BAD_ARGS
);
2490 char append_str
[MAX_LITERAL_POOL_SIZE
];
2492 sprintf (append_str
, "mhfl! %s", backupstr
);
2493 if (append_insn (append_str
, TRUE
) == (int) FAIL
)
2496 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
2504 do16_rdi4 (char *str
)
2506 skip_whitespace (str
);
2508 if (reglow_required_here (&str
, 8) == (int) FAIL
2509 || skip_past_comma (&str
) == (int) FAIL
2510 || data_op2 (&str
, 3, _IMM4
) == (int) FAIL
2511 || end_of_line (str
) == (int) FAIL
)
2517 if (((inst
.instruction
>> 3) & 0x10) == 0) /* for judge is addei or subei : bit 5 =0 : addei */
2519 if (((inst
.instruction
>> 3) & 0xf) != 0xf)
2521 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 20)
2522 | ((1 << ((inst
.instruction
>> 3) & 0xf)) << 1);
2523 inst
.relax_size
= 4;
2527 inst
.relax_inst
= 0x8000;
2532 if (((inst
.instruction
>> 3) & 0xf) != 0xf)
2534 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 20)
2535 | (((-(1 << ((inst
.instruction
>> 3) & 0xf))) & 0xffff) << 1);
2536 inst
.relax_size
= 4;
2540 inst
.relax_inst
= 0x8000;
2547 do16_rdi5 (char *str
)
2549 skip_whitespace (str
);
2551 if (reglow_required_here (&str
, 8) == (int) FAIL
2552 || skip_past_comma (&str
) == (int) FAIL
2553 || data_op2 (&str
, 3, _IMM5
) == (int) FAIL
2554 || end_of_line (str
) == (int) FAIL
)
2558 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 20)
2559 | (((inst
.instruction
>> 8) & 0xf) << 15) | (((inst
.instruction
>> 3) & 0x1f) << 10);
2560 inst
.relax_size
= 4;
2566 do16_xi5 (char *str
)
2568 skip_whitespace (str
);
2570 if (data_op2 (&str
, 3, _IMM5
) == (int) FAIL
|| end_of_line (str
) == (int) FAIL
)
2574 inst
.relax_inst
|= (((inst
.instruction
>> 3) & 0x1f) << 15);
2575 inst
.relax_size
= 4;
2579 /* Check that an immediate is word alignment or half word alignment.
2580 If so, convert it to the right format. */
2582 validate_immediate_align (int val
, unsigned int data_type
)
2584 if (data_type
== _IMM5_RSHIFT_1
)
2588 inst
.error
= _("address offset must be half word alignment");
2592 else if ((data_type
== _IMM5_RSHIFT_2
) || (data_type
== _IMM10_RSHIFT_2
))
2596 inst
.error
= _("address offset must be word alignment");
2605 exp_ldst_offset (char **str
, int shift
, unsigned int data_type
)
2611 if ((*dataptr
== '0') && (*(dataptr
+ 1) == 'x')
2612 && (data_type
!= _SIMM16_LA
)
2613 && (data_type
!= _VALUE_HI16
)
2614 && (data_type
!= _VALUE_LO16
)
2615 && (data_type
!= _IMM16
)
2616 && (data_type
!= _IMM15
)
2617 && (data_type
!= _IMM14
)
2618 && (data_type
!= _IMM4
)
2619 && (data_type
!= _IMM5
)
2620 && (data_type
!= _IMM8
)
2621 && (data_type
!= _IMM5_RSHIFT_1
)
2622 && (data_type
!= _IMM5_RSHIFT_2
)
2623 && (data_type
!= _SIMM14_NEG
)
2624 && (data_type
!= _IMM10_RSHIFT_2
))
2629 if (my_get_expression (&inst
.reloc
.exp
, str
) == (int) FAIL
)
2632 if (inst
.reloc
.exp
.X_op
== O_constant
)
2634 /* Need to check the immediate align. */
2635 int value
= validate_immediate_align (inst
.reloc
.exp
.X_add_number
, data_type
);
2637 if (value
== (int) FAIL
)
2640 value
= validate_immediate (inst
.reloc
.exp
.X_add_number
, data_type
, 0);
2641 if (value
== (int) FAIL
)
2645 _("invalid constant: %d bit expression not in range %d..%d"),
2646 score_df_range
[data_type
].bits
,
2647 score_df_range
[data_type
].range
[0], score_df_range
[data_type
].range
[1]);
2650 _("invalid constant: %d bit expression not in range %d..%d"),
2651 score_df_range
[data_type
- 24].bits
,
2652 score_df_range
[data_type
- 24].range
[0], score_df_range
[data_type
- 24].range
[1]);
2653 inst
.error
= err_msg
;
2657 if (data_type
== _IMM5_RSHIFT_1
)
2661 else if ((data_type
== _IMM5_RSHIFT_2
) || (data_type
== _IMM10_RSHIFT_2
))
2666 if (score_df_range
[data_type
].range
[0] != 0)
2668 value
&= (1 << score_df_range
[data_type
].bits
) - 1;
2671 inst
.instruction
|= value
<< shift
;
2675 inst
.reloc
.pc_rel
= 0;
2682 do_ldst_insn (char *str
)
2694 skip_whitespace (str
);
2696 if (((conflict_reg
= reg_required_here (&str
, 20, REG_TYPE_SCORE
)) == (int) FAIL
)
2697 || (skip_past_comma (&str
) == (int) FAIL
))
2700 /* ld/sw rD, [rA, simm15] ld/sw rD, [rA]+, simm12 ld/sw rD, [rA, simm12]+. */
2704 skip_whitespace (str
);
2706 if ((reg
= reg_required_here (&str
, 15, REG_TYPE_SCORE
)) == (int) FAIL
)
2709 /* Conflicts can occur on stores as well as loads. */
2710 conflict_reg
= (conflict_reg
== reg
);
2711 skip_whitespace (str
);
2712 temp
= str
+ 1; /* The latter will process decimal/hex expression. */
2714 /* ld/sw rD, [rA]+, simm12 ld/sw rD, [rA]+. */
2721 /* ld/sw rD, [rA]+, simm12. */
2722 if (skip_past_comma (&str
) == SUCCESS
)
2724 if ((exp_ldst_offset (&str
, 3, _SIMM12
) == (int) FAIL
)
2725 || (end_of_line (str
) == (int) FAIL
))
2730 unsigned int ldst_func
= inst
.instruction
& OPC_PSEUDOLDST_MASK
;
2732 if ((ldst_func
== INSN_LH
)
2733 || (ldst_func
== INSN_LHU
)
2734 || (ldst_func
== INSN_LW
)
2735 || (ldst_func
== INSN_LB
)
2736 || (ldst_func
== INSN_LBU
))
2738 inst
.error
= _("register same as write-back base");
2743 ldst_idx
= inst
.instruction
& OPC_PSEUDOLDST_MASK
;
2744 inst
.instruction
&= ~OPC_PSEUDOLDST_MASK
;
2745 inst
.instruction
|= score_ldst_insns
[ldst_idx
* 3 + LDST_POST
].value
;
2747 /* lw rD, [rA]+, 4 convert to pop rD, [rA]. */
2748 if ((inst
.instruction
& 0x3e000007) == 0x0e000000)
2750 /* rs = r0-r7, offset = 4 */
2751 if ((((inst
.instruction
>> 15) & 0x18) == 0)
2752 && (((inst
.instruction
>> 3) & 0xfff) == 4))
2754 /* Relax to pophi. */
2755 if ((((inst
.instruction
>> 20) & 0x10) == 0x10))
2757 inst
.relax_inst
= 0x0000200a | (((inst
.instruction
>> 20) & 0xf)
2759 (((inst
.instruction
>> 15) & 0x7) << 4);
2764 inst
.relax_inst
= 0x0000200a | (((inst
.instruction
>> 20) & 0xf)
2766 (((inst
.instruction
>> 15) & 0x7) << 4);
2768 inst
.relax_size
= 2;
2773 /* ld/sw rD, [rA]+ convert to ld/sw rD, [rA, 0]+. */
2776 SET_INSN_ERROR (NULL
);
2777 if (end_of_line (str
) == (int) FAIL
)
2783 value
= validate_immediate (inst
.reloc
.exp
.X_add_number
, _SIMM12
, 0);
2784 value
&= (1 << score_df_range
[_SIMM12
].bits
) - 1;
2785 ldst_idx
= inst
.instruction
& OPC_PSEUDOLDST_MASK
;
2786 inst
.instruction
&= ~OPC_PSEUDOLDST_MASK
;
2787 inst
.instruction
|= score_ldst_insns
[ldst_idx
* 3 + pre_inc
].value
;
2788 inst
.instruction
|= value
<< 3;
2789 inst
.relax_inst
= 0x8000;
2793 /* ld/sw rD, [rA] convert to ld/sw rD, [rA, simm15]. */
2796 if (end_of_line (str
) == (int) FAIL
)
2799 ldst_idx
= inst
.instruction
& OPC_PSEUDOLDST_MASK
;
2800 inst
.instruction
&= ~OPC_PSEUDOLDST_MASK
;
2801 inst
.instruction
|= score_ldst_insns
[ldst_idx
* 3 + LDST_NOUPDATE
].value
;
2803 /* lbu rd, [rs] -> lbu! rd, [rs] */
2804 if (ldst_idx
== INSN_LBU
)
2806 inst
.relax_inst
= INSN16_LBU
;
2808 else if (ldst_idx
== INSN_LH
)
2810 inst
.relax_inst
= INSN16_LH
;
2812 else if (ldst_idx
== INSN_LW
)
2814 inst
.relax_inst
= INSN16_LW
;
2816 else if (ldst_idx
== INSN_SB
)
2818 inst
.relax_inst
= INSN16_SB
;
2820 else if (ldst_idx
== INSN_SH
)
2822 inst
.relax_inst
= INSN16_SH
;
2824 else if (ldst_idx
== INSN_SW
)
2826 inst
.relax_inst
= INSN16_SW
;
2830 inst
.relax_inst
= 0x8000;
2833 /* lw/lh/lbu/sw/sh/sb, offset = 0, relax to 16 bit instruction. */
2834 if ((ldst_idx
== INSN_LBU
)
2835 || (ldst_idx
== INSN_LH
)
2836 || (ldst_idx
== INSN_LW
)
2837 || (ldst_idx
== INSN_SB
) || (ldst_idx
== INSN_SH
) || (ldst_idx
== INSN_SW
))
2839 if ((((inst
.instruction
>> 15) & 0x10) == 0) && (((inst
.instruction
>> 20) & 0x10) == 0))
2841 inst
.relax_inst
|= (2 << 12) | (((inst
.instruction
>> 20) & 0xf) << 8) |
2842 (((inst
.instruction
>> 15) & 0xf) << 4);
2843 inst
.relax_size
= 2;
2850 /* ld/sw rD, [rA, simm15] ld/sw rD, [rA, simm12]+. */
2853 if (skip_past_comma (&str
) == (int) FAIL
)
2855 inst
.error
= _("pre-indexed expression expected");
2859 if (my_get_expression (&inst
.reloc
.exp
, &str
) == (int) FAIL
)
2862 skip_whitespace (str
);
2865 inst
.error
= _("missing ]");
2869 skip_whitespace (str
);
2870 /* ld/sw rD, [rA, simm12]+. */
2877 unsigned int ldst_func
= inst
.instruction
& OPC_PSEUDOLDST_MASK
;
2879 if ((ldst_func
== INSN_LH
)
2880 || (ldst_func
== INSN_LHU
)
2881 || (ldst_func
== INSN_LW
)
2882 || (ldst_func
== INSN_LB
)
2883 || (ldst_func
== INSN_LBU
))
2885 inst
.error
= _("register same as write-back base");
2891 if (end_of_line (str
) == (int) FAIL
)
2894 if (inst
.reloc
.exp
.X_op
== O_constant
)
2897 unsigned int data_type
;
2900 data_type
= _SIMM12
;
2902 data_type
= _SIMM15
;
2905 if ((*dataptr
== '0') && (*(dataptr
+ 1) == 'x')
2906 && (data_type
!= _SIMM16_LA
)
2907 && (data_type
!= _VALUE_HI16
)
2908 && (data_type
!= _VALUE_LO16
)
2909 && (data_type
!= _IMM16
)
2910 && (data_type
!= _IMM15
)
2911 && (data_type
!= _IMM14
)
2912 && (data_type
!= _IMM4
)
2913 && (data_type
!= _IMM5
)
2914 && (data_type
!= _IMM8
)
2915 && (data_type
!= _IMM5_RSHIFT_1
)
2916 && (data_type
!= _IMM5_RSHIFT_2
)
2917 && (data_type
!= _SIMM14_NEG
)
2918 && (data_type
!= _IMM10_RSHIFT_2
))
2923 value
= validate_immediate (inst
.reloc
.exp
.X_add_number
, data_type
, 0);
2924 if (value
== (int) FAIL
)
2928 _("invalid constant: %d bit expression not in range %d..%d"),
2929 score_df_range
[data_type
].bits
,
2930 score_df_range
[data_type
].range
[0], score_df_range
[data_type
].range
[1]);
2933 _("invalid constant: %d bit expression not in range %d..%d"),
2934 score_df_range
[data_type
- 24].bits
,
2935 score_df_range
[data_type
- 24].range
[0],
2936 score_df_range
[data_type
- 24].range
[1]);
2937 inst
.error
= err_msg
;
2941 value
&= (1 << score_df_range
[data_type
].bits
) - 1;
2942 ldst_idx
= inst
.instruction
& OPC_PSEUDOLDST_MASK
;
2943 inst
.instruction
&= ~OPC_PSEUDOLDST_MASK
;
2944 inst
.instruction
|= score_ldst_insns
[ldst_idx
* 3 + pre_inc
].value
;
2946 inst
.instruction
|= value
<< 3;
2948 inst
.instruction
|= value
;
2950 /* lw rD, [rA, simm15] */
2951 if ((inst
.instruction
& 0x3e000000) == 0x20000000)
2953 /* Both rD and rA are in [r0 - r15]. */
2954 if ((((inst
.instruction
>> 15) & 0x10) == 0)
2955 && (((inst
.instruction
>> 20) & 0x10) == 0))
2957 /* simm15 = 0, lw -> lw!. */
2958 if ((inst
.instruction
& 0x7fff) == 0)
2960 inst
.relax_inst
|= (((inst
.instruction
>> 15) & 0xf) << 4)
2961 | (((inst
.instruction
>> 20) & 0xf) << 8);
2962 inst
.relax_size
= 2;
2964 /* rA = r2, lw -> lwp!. */
2965 else if ((((inst
.instruction
>> 15) & 0xf) == 2)
2966 && ((inst
.instruction
& 0x3) == 0)
2967 && ((inst
.instruction
& 0x7fff) < 128))
2969 inst
.relax_inst
= 0x7000 | (((inst
.instruction
>> 20) & 0xf) << 8)
2970 | (((inst
.instruction
& 0x7fff) >> 2) << 3);
2971 inst
.relax_size
= 2;
2975 inst
.relax_inst
= 0x8000;
2980 inst
.relax_inst
= 0x8000;
2983 /* sw rD, [rA, simm15] */
2984 else if ((inst
.instruction
& 0x3e000000) == 0x28000000)
2986 /* Both rD and rA are in [r0 - r15]. */
2987 if ((((inst
.instruction
>> 15) & 0x10) == 0) && (((inst
.instruction
>> 20) & 0x10) == 0))
2989 /* simm15 = 0, sw -> sw!. */
2990 if ((inst
.instruction
& 0x7fff) == 0)
2992 inst
.relax_inst
|= (((inst
.instruction
>> 15) & 0xf) << 4)
2993 | (((inst
.instruction
>> 20) & 0xf) << 8);
2994 inst
.relax_size
= 2;
2996 /* rA = r2, sw -> swp!. */
2997 else if ((((inst
.instruction
>> 15) & 0xf) == 2)
2998 && ((inst
.instruction
& 0x3) == 0)
2999 && ((inst
.instruction
& 0x7fff) < 128))
3001 inst
.relax_inst
= 0x7004 | (((inst
.instruction
>> 20) & 0xf) << 8)
3002 | (((inst
.instruction
& 0x7fff) >> 2) << 3);
3003 inst
.relax_size
= 2;
3007 inst
.relax_inst
= 0x8000;
3012 inst
.relax_inst
= 0x8000;
3015 /* sw rD, [rA, simm15]+ sw pre. */
3016 else if ((inst
.instruction
& 0x3e000007) == 0x06000004)
3018 /* rA is in [r0 - r7], and simm15 = -4. */
3019 if ((((inst
.instruction
>> 15) & 0x18) == 0)
3020 && (((inst
.instruction
>> 3) & 0xfff) == 0xffc))
3022 /* sw -> pushhi!. */
3023 if ((((inst
.instruction
>> 20) & 0x10) == 0x10))
3025 inst
.relax_inst
= 0x0000200e | (((inst
.instruction
>> 20) & 0xf) << 8)
3026 | 1 << 7 | (((inst
.instruction
>> 15) & 0x7) << 4);
3027 inst
.relax_size
= 2;
3032 inst
.relax_inst
= 0x0000200e | (((inst
.instruction
>> 20) & 0xf) << 8)
3033 | 0 << 7 | (((inst
.instruction
>> 15) & 0x7) << 4);
3034 inst
.relax_size
= 2;
3039 inst
.relax_inst
= 0x8000;
3042 /* lh rD, [rA, simm15] */
3043 else if ((inst
.instruction
& 0x3e000000) == 0x22000000)
3045 /* Both rD and rA are in [r0 - r15]. */
3046 if ((((inst
.instruction
>> 15) & 0x10) == 0) && (((inst
.instruction
>> 20) & 0x10) == 0))
3048 /* simm15 = 0, lh -> lh!. */
3049 if ((inst
.instruction
& 0x7fff) == 0)
3051 inst
.relax_inst
|= (((inst
.instruction
>> 15) & 0xf) << 4)
3052 | (((inst
.instruction
>> 20) & 0xf) << 8);
3053 inst
.relax_size
= 2;
3055 /* rA = r2, lh -> lhp!. */
3056 else if ((((inst
.instruction
>> 15) & 0xf) == 2)
3057 && ((inst
.instruction
& 0x1) == 0)
3058 && ((inst
.instruction
& 0x7fff) < 64))
3060 inst
.relax_inst
= 0x7001 | (((inst
.instruction
>> 20) & 0xf) << 8)
3061 | (((inst
.instruction
& 0x7fff) >> 1) << 3);
3062 inst
.relax_size
= 2;
3066 inst
.relax_inst
= 0x8000;
3071 inst
.relax_inst
= 0x8000;
3074 /* sh rD, [rA, simm15] */
3075 else if ((inst
.instruction
& 0x3e000000) == 0x2a000000)
3077 /* Both rD and rA are in [r0 - r15]. */
3078 if ((((inst
.instruction
>> 15) & 0x10) == 0) && (((inst
.instruction
>> 20) & 0x10) == 0))
3080 /* simm15 = 0, sh -> sh!. */
3081 if ((inst
.instruction
& 0x7fff) == 0)
3083 inst
.relax_inst
|= (((inst
.instruction
>> 15) & 0xf) << 4)
3084 | (((inst
.instruction
>> 20) & 0xf) << 8);
3085 inst
.relax_size
= 2;
3087 /* rA = r2, sh -> shp!. */
3088 else if ((((inst
.instruction
>> 15) & 0xf) == 2)
3089 && ((inst
.instruction
& 0x1) == 0)
3090 && ((inst
.instruction
& 0x7fff) < 64))
3092 inst
.relax_inst
= 0x7005 | (((inst
.instruction
>> 20) & 0xf) << 8)
3093 | (((inst
.instruction
& 0x7fff) >> 1) << 3);
3094 inst
.relax_size
= 2;
3098 inst
.relax_inst
= 0x8000;
3103 inst
.relax_inst
= 0x8000;
3106 /* lbu rD, [rA, simm15] */
3107 else if ((inst
.instruction
& 0x3e000000) == 0x2c000000)
3109 /* Both rD and rA are in [r0 - r15]. */
3110 if ((((inst
.instruction
>> 15) & 0x10) == 0) && (((inst
.instruction
>> 20) & 0x10) == 0))
3112 /* simm15 = 0, lbu -> lbu!. */
3113 if ((inst
.instruction
& 0x7fff) == 0)
3115 inst
.relax_inst
|= (((inst
.instruction
>> 15) & 0xf) << 4)
3116 | (((inst
.instruction
>> 20) & 0xf) << 8);
3117 inst
.relax_size
= 2;
3119 /* rA = r2, lbu -> lbup!. */
3120 else if ((((inst
.instruction
>> 15) & 0xf) == 2)
3121 && ((inst
.instruction
& 0x7fff) < 32))
3123 inst
.relax_inst
= 0x7003 | (((inst
.instruction
>> 20) & 0xf) << 8)
3124 | ((inst
.instruction
& 0x7fff) << 3);
3125 inst
.relax_size
= 2;
3129 inst
.relax_inst
= 0x8000;
3134 inst
.relax_inst
= 0x8000;
3137 /* sb rD, [rA, simm15] */
3138 else if ((inst
.instruction
& 0x3e000000) == 0x2e000000)
3140 /* Both rD and rA are in [r0 - r15]. */
3141 if ((((inst
.instruction
>> 15) & 0x10) == 0) && (((inst
.instruction
>> 20) & 0x10) == 0))
3143 /* simm15 = 0, sb -> sb!. */
3144 if ((inst
.instruction
& 0x7fff) == 0)
3146 inst
.relax_inst
|= (((inst
.instruction
>> 15) & 0xf) << 4)
3147 | (((inst
.instruction
>> 20) & 0xf) << 8);
3148 inst
.relax_size
= 2;
3150 /* rA = r2, sb -> sb!. */
3151 else if ((((inst
.instruction
>> 15) & 0xf) == 2)
3152 && ((inst
.instruction
& 0x7fff) < 32))
3154 inst
.relax_inst
= 0x7007 | (((inst
.instruction
>> 20) & 0xf) << 8)
3155 | ((inst
.instruction
& 0x7fff) << 3);
3156 inst
.relax_size
= 2;
3160 inst
.relax_inst
= 0x8000;
3165 inst
.relax_inst
= 0x8000;
3170 inst
.relax_inst
= 0x8000;
3177 /* FIXME: may set error, for there is no ld/sw rD, [rA, label] */
3178 inst
.reloc
.pc_rel
= 0;
3184 inst
.error
= BAD_ARGS
;
3191 do_cache (char *str
)
3193 skip_whitespace (str
);
3195 if ((data_op2 (&str
, 20, _IMM5
) == (int) FAIL
) || (skip_past_comma (&str
) == (int) FAIL
))
3203 cache_op
= (inst
.instruction
>> 20) & 0x1F;
3204 sprintf (inst
.name
, "cache %d", cache_op
);
3210 skip_whitespace (str
);
3212 if (reg_required_here (&str
, 15, REG_TYPE_SCORE
) == (int) FAIL
)
3215 skip_whitespace (str
);
3217 /* cache op, [rA] */
3218 if (skip_past_comma (&str
) == (int) FAIL
)
3220 SET_INSN_ERROR (NULL
);
3223 inst
.error
= _("missing ]");
3228 /* cache op, [rA, simm15] */
3231 if (exp_ldst_offset (&str
, 0, _SIMM15
) == (int) FAIL
)
3236 skip_whitespace (str
);
3239 inst
.error
= _("missing ]");
3244 if (end_of_line (str
) == (int) FAIL
)
3249 inst
.error
= BAD_ARGS
;
3254 do_crdcrscrsimm5 (char *str
)
3259 skip_whitespace (str
);
3261 if (reg_required_here (&str
, 20, REG_TYPE_SCORE_CR
) == (int) FAIL
3262 || skip_past_comma (&str
) == (int) FAIL
3263 || reg_required_here (&str
, 15, REG_TYPE_SCORE_CR
) == (int) FAIL
3264 || skip_past_comma (&str
) == (int) FAIL
3265 || reg_required_here (&str
, 10, REG_TYPE_SCORE_CR
) == (int) FAIL
3266 || skip_past_comma (&str
) == (int) FAIL
)
3269 /* cop1 cop_code20. */
3270 if (data_op2 (&str
, 5, _IMM20
) == (int) FAIL
)
3275 if (data_op2 (&str
, 5, _IMM5
) == (int) FAIL
)
3282 /* Handle ldc/stc. */
3284 do_ldst_cop (char *str
)
3286 skip_whitespace (str
);
3288 if ((reg_required_here (&str
, 15, REG_TYPE_SCORE_CR
) == (int) FAIL
)
3289 || (skip_past_comma (&str
) == (int) FAIL
))
3295 skip_whitespace (str
);
3297 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) == (int) FAIL
)
3300 skip_whitespace (str
);
3304 if (exp_ldst_offset (&str
, 5, _IMM10_RSHIFT_2
) == (int) FAIL
)
3307 skip_whitespace (str
);
3310 inst
.error
= _("missing ]");
3318 inst
.error
= BAD_ARGS
;
3322 do16_ldst_insn (char *str
)
3324 skip_whitespace (str
);
3326 if ((reglow_required_here (&str
, 8) == (int) FAIL
) || (skip_past_comma (&str
) == (int) FAIL
))
3334 skip_whitespace (str
);
3336 if ((reg
= reglow_required_here (&str
, 4)) == (int) FAIL
)
3339 skip_whitespace (str
);
3342 if (end_of_line (str
) == (int) FAIL
)
3346 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 20)
3347 | (((inst
.instruction
>> 4) & 0xf) << 15);
3348 inst
.relax_size
= 4;
3353 inst
.error
= _("missing ]");
3358 inst
.error
= BAD_ARGS
;
3362 /* Handle lbup!/lhp!/ldiu!/lwp!/sbp!/shp!/swp!. */
3364 do16_ldst_imm_insn (char *str
)
3366 char data_exp
[MAX_LITERAL_POOL_SIZE
];
3368 char *dataptr
= NULL
, *pp
= NULL
;
3370 int assign_data
= (int) FAIL
;
3371 unsigned int ldst_func
;
3373 skip_whitespace (str
);
3375 if (((reg_rd
= reglow_required_here (&str
, 8)) == (int) FAIL
)
3376 || (skip_past_comma (&str
) == (int) FAIL
))
3379 skip_whitespace (str
);
3382 while ((*dataptr
!= '\0') && (*dataptr
!= '|') && (cnt
<= MAX_LITERAL_POOL_SIZE
))
3384 data_exp
[cnt
] = *dataptr
;
3389 data_exp
[cnt
] = '\0';
3394 ldst_func
= inst
.instruction
& LDST16_RI_MASK
;
3395 if (ldst_func
== N16_LIU
)
3396 assign_data
= exp_ldst_offset (&pp
, 0, _IMM8
);
3397 else if (ldst_func
== N16_LHP
|| ldst_func
== N16_SHP
)
3398 assign_data
= exp_ldst_offset (&pp
, 3, _IMM5_RSHIFT_1
);
3399 else if (ldst_func
== N16_LWP
|| ldst_func
== N16_SWP
)
3400 assign_data
= exp_ldst_offset (&pp
, 3, _IMM5_RSHIFT_2
);
3402 assign_data
= exp_ldst_offset (&pp
, 3, _IMM5
);
3404 if ((assign_data
== (int) FAIL
) || (end_of_line (pp
) == (int) FAIL
))
3408 if ((inst
.instruction
& 0x7000) == N16_LIU
)
3410 inst
.relax_inst
|= ((inst
.instruction
>> 8) & 0xf) << 20
3411 | ((inst
.instruction
& 0xff) << 1);
3413 else if (((inst
.instruction
& 0x7007) == N16_LHP
)
3414 || ((inst
.instruction
& 0x7007) == N16_SHP
))
3416 inst
.relax_inst
|= ((inst
.instruction
>> 8) & 0xf) << 20 | 2 << 15
3417 | (((inst
.instruction
>> 3) & 0x1f) << 1);
3419 else if (((inst
.instruction
& 0x7007) == N16_LWP
)
3420 || ((inst
.instruction
& 0x7007) == N16_SWP
))
3422 inst
.relax_inst
|= ((inst
.instruction
>> 8) & 0xf) << 20 | 2 << 15
3423 | (((inst
.instruction
>> 3) & 0x1f) << 2);
3425 else if (((inst
.instruction
& 0x7007) == N16_LBUP
)
3426 || ((inst
.instruction
& 0x7007) == N16_SBP
))
3428 inst
.relax_inst
|= ((inst
.instruction
>> 8) & 0xf) << 20 | 2 << 15
3429 | (((inst
.instruction
>> 3) & 0x1f));
3432 inst
.relax_size
= 4;
3437 do16_push_pop (char *str
)
3442 skip_whitespace (str
);
3443 if (((reg_rd
= reg_required_here (&str
, 8, REG_TYPE_SCORE
)) == (int) FAIL
)
3444 || (skip_past_comma (&str
) == (int) FAIL
))
3450 /* reg_required_here will change bit 12 of opcode, so we must restore bit 12. */
3451 inst
.instruction
&= ~(1 << 12);
3453 inst
.instruction
|= H_bit_mask
<< 7;
3460 skip_whitespace (str
);
3461 if ((reg
= reg_required_here (&str
, 4, REG_TYPE_SCORE
)) == (int) FAIL
)
3466 inst
.error
= _("base register nums are over 3 bit");
3471 skip_whitespace (str
);
3472 if ((*str
++ != ']') || (end_of_line (str
) == (int) FAIL
))
3475 inst
.error
= _("missing ]");
3481 if ((inst
.instruction
& 0xf) == 0xa)
3485 inst
.relax_inst
|= ((((inst
.instruction
>> 8) & 0xf) | 0x10) << 20)
3486 | (((inst
.instruction
>> 4) & 0x7) << 15) | (4 << 3);
3490 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 20)
3491 | (((inst
.instruction
>> 4) & 0x7) << 15) | (4 << 3);
3499 inst
.relax_inst
|= ((((inst
.instruction
>> 8) & 0xf) | 0x10) << 20)
3500 | (((inst
.instruction
>> 4) & 0x7) << 15) | (((-4) & 0xfff) << 3);
3504 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 20)
3505 | (((inst
.instruction
>> 4) & 0x7) << 15) | (((-4) & 0xfff) << 3);
3508 inst
.relax_size
= 4;
3512 inst
.error
= BAD_ARGS
;
3516 /* Handle lcb/lcw/lce/scb/scw/sce. */
3518 do_ldst_unalign (char *str
)
3522 if (university_version
== 1)
3524 inst
.error
= ERR_FOR_SCORE5U_ATOMIC
;
3528 skip_whitespace (str
);
3530 /* lcb/scb [rA]+. */
3534 skip_whitespace (str
);
3536 if (reg_required_here (&str
, 15, REG_TYPE_SCORE
) == (int) FAIL
)
3543 inst
.error
= _("missing +");
3549 inst
.error
= _("missing ]");
3553 if (end_of_line (str
) == (int) FAIL
)
3556 /* lcw/lce/scb/sce rD, [rA]+. */
3559 if (((conflict_reg
= reg_required_here (&str
, 20, REG_TYPE_SCORE
)) == (int) FAIL
)
3560 || (skip_past_comma (&str
) == (int) FAIL
))
3565 skip_whitespace (str
);
3570 skip_whitespace (str
);
3571 if ((reg
= reg_required_here (&str
, 15, REG_TYPE_SCORE
)) == (int) FAIL
)
3576 /* Conflicts can occur on stores as well as loads. */
3577 conflict_reg
= (conflict_reg
== reg
);
3578 skip_whitespace (str
);
3581 unsigned int ldst_func
= inst
.instruction
& LDST_UNALIGN_MASK
;
3587 as_warn (_("%s register same as write-back base"),
3588 ((ldst_func
& UA_LCE
) || (ldst_func
& UA_LCW
)
3589 ? _("destination") : _("source")));
3594 inst
.error
= _("missing +");
3598 if (end_of_line (str
) == (int) FAIL
)
3603 inst
.error
= _("missing ]");
3609 inst
.error
= BAD_ARGS
;
3615 /* Handle alw/asw. */
3617 do_ldst_atomic (char *str
)
3619 if (university_version
== 1)
3621 inst
.error
= ERR_FOR_SCORE5U_ATOMIC
;
3625 skip_whitespace (str
);
3627 if ((reg_required_here (&str
, 20, REG_TYPE_SCORE
) == (int) FAIL
)
3628 || (skip_past_comma (&str
) == (int) FAIL
))
3635 skip_whitespace (str
);
3640 skip_whitespace (str
);
3641 if ((reg
= reg_required_here (&str
, 15, REG_TYPE_SCORE
)) == (int) FAIL
)
3646 skip_whitespace (str
);
3649 inst
.error
= _("missing ]");
3656 inst
.error
= BAD_ARGS
;
3661 build_relax_frag (struct score_it fix_insts
[RELAX_INST_NUM
], int fix_num ATTRIBUTE_UNUSED
,
3662 struct score_it var_insts
[RELAX_INST_NUM
], int var_num
,
3663 symbolS
*add_symbol
)
3668 fixS
*cur_fixp
= NULL
;
3670 struct score_it inst_main
;
3672 memcpy (&inst_main
, &fix_insts
[0], sizeof (struct score_it
));
3674 /* Adjust instruction opcode and to be relaxed instruction opcode. */
3675 inst_main
.instruction
= adjust_paritybit (inst_main
.instruction
, GET_INSN_CLASS (inst_main
.type
));
3676 inst_main
.type
= Insn_PIC
;
3678 for (i
= 0; i
< var_num
; i
++)
3680 inst_main
.relax_size
+= var_insts
[i
].size
;
3681 var_insts
[i
].instruction
= adjust_paritybit (var_insts
[i
].instruction
,
3682 GET_INSN_CLASS (var_insts
[i
].type
));
3685 /* Check data dependency. */
3686 handle_dependency (&inst_main
);
3688 /* Start a new frag if frag_now is not empty. */
3689 if (frag_now_fix () != 0)
3691 if (!frag_now
->tc_frag_data
.is_insn
)
3693 frag_wane (frag_now
);
3699 /* Write fr_fix part. */
3700 p
= frag_more (inst_main
.size
);
3701 md_number_to_chars (p
, inst_main
.instruction
, inst_main
.size
);
3703 if (inst_main
.reloc
.type
!= BFD_RELOC_NONE
)
3704 fixp
= fix_new_score (frag_now
, p
- frag_now
->fr_literal
, inst_main
.size
,
3705 &inst_main
.reloc
.exp
, inst_main
.reloc
.pc_rel
, inst_main
.reloc
.type
);
3707 frag_now
->tc_frag_data
.fixp
= fixp
;
3708 cur_fixp
= frag_now
->tc_frag_data
.fixp
;
3711 dwarf2_emit_insn (inst_main
.size
);
3714 where
= p
- frag_now
->fr_literal
+ inst_main
.size
;
3715 for (i
= 0; i
< var_num
; i
++)
3718 where
+= var_insts
[i
- 1].size
;
3720 if (var_insts
[i
].reloc
.type
!= BFD_RELOC_NONE
)
3722 fixp
= fix_new_score (frag_now
, where
, var_insts
[i
].size
,
3723 &var_insts
[i
].reloc
.exp
, var_insts
[i
].reloc
.pc_rel
,
3724 var_insts
[i
].reloc
.type
);
3729 cur_fixp
->fx_next
= fixp
;
3730 cur_fixp
= cur_fixp
->fx_next
;
3734 frag_now
->tc_frag_data
.fixp
= fixp
;
3735 cur_fixp
= frag_now
->tc_frag_data
.fixp
;
3741 p
= frag_var (rs_machine_dependent
, inst_main
.relax_size
+ RELAX_PAD_BYTE
, 0,
3742 RELAX_ENCODE (inst_main
.size
, inst_main
.relax_size
, inst_main
.type
,
3743 0, inst_main
.size
, 0), add_symbol
, 0, NULL
);
3745 /* Write fr_var part.
3746 no calling gen_insn_frag, no fixS will be generated. */
3747 for (i
= 0; i
< var_num
; i
++)
3749 md_number_to_chars (p
, var_insts
[i
].instruction
, var_insts
[i
].size
);
3750 p
+= var_insts
[i
].size
;
3752 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
3756 /* Build a relax frag for la instruction when generating PIC,
3757 external symbol first and local symbol second. */
3760 build_la_pic (int reg_rd
, expressionS exp
)
3762 symbolS
*add_symbol
= exp
.X_add_symbol
;
3763 offsetT add_number
= exp
.X_add_number
;
3764 struct score_it fix_insts
[RELAX_INST_NUM
];
3765 struct score_it var_insts
[RELAX_INST_NUM
];
3768 char tmp
[MAX_LITERAL_POOL_SIZE
];
3774 if (add_number
== 0)
3779 /* For an external symbol, only one insn is generated;
3780 For a local symbol, two insns are generated. */
3782 For an external symbol: lw rD, <sym>($gp)
3783 (BFD_RELOC_SCORE_GOT15 or BFD_RELOC_SCORE_CALL15) */
3784 sprintf (tmp
, "lw_pic r%d, %s", reg_rd
, add_symbol
->bsym
->name
);
3785 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
3788 if (reg_rd
== PIC_CALL_REG
)
3789 inst
.reloc
.type
= BFD_RELOC_SCORE_CALL15
;
3790 memcpy (&fix_insts
[0], &inst
, sizeof (struct score_it
));
3793 For a local symbol :
3794 lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15)
3795 addi rD, <sym> (BFD_RELOC_GOT_LO16) */
3796 inst
.reloc
.type
= BFD_RELOC_SCORE_GOT15
;
3797 memcpy (&var_insts
[0], &inst
, sizeof (struct score_it
));
3798 sprintf (tmp
, "addi_s_pic r%d, %s", reg_rd
, add_symbol
->bsym
->name
);
3799 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
3802 memcpy (&var_insts
[1], &inst
, sizeof (struct score_it
));
3803 build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
3805 else if (add_number
>= -0x8000 && add_number
<= 0x7fff)
3807 /* Insn 1: lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15) */
3808 sprintf (tmp
, "lw_pic r%d, %s", reg_rd
, add_symbol
->bsym
->name
);
3809 if (append_insn (tmp
, TRUE
) == (int) FAIL
)
3816 For an external symbol: addi rD, <constant> */
3817 sprintf (tmp
, "addi r%d, %d", reg_rd
, (int)add_number
);
3818 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
3821 memcpy (&fix_insts
[0], &inst
, sizeof (struct score_it
));
3824 For a local symbol: addi rD, <sym>+<constant> (BFD_RELOC_GOT_LO16) */
3825 sprintf (tmp
, "addi_s_pic r%d, %s + %d", reg_rd
, add_symbol
->bsym
->name
, (int)add_number
);
3826 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
3829 memcpy (&var_insts
[0], &inst
, sizeof (struct score_it
));
3830 build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
3834 int hi
= (add_number
>> 16) & 0x0000FFFF;
3835 int lo
= add_number
& 0x0000FFFF;
3837 /* Insn 1: lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15) */
3838 sprintf (tmp
, "lw_pic r%d, %s", reg_rd
, add_symbol
->bsym
->name
);
3839 if (append_insn (tmp
, TRUE
) == (int) FAIL
)
3846 For an external symbol: ldis r1, HI%<constant> */
3847 sprintf (tmp
, "ldis r1, %d", hi
);
3848 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
3851 memcpy (&fix_insts
[0], &inst
, sizeof (struct score_it
));
3854 For a local symbol: ldis r1, HI%<constant>
3855 but, if lo is outof 16 bit, make hi plus 1 */
3856 if ((lo
< -0x8000) || (lo
> 0x7fff))
3860 sprintf (tmp
, "ldis_pic r1, %d", hi
);
3861 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
3864 memcpy (&var_insts
[0], &inst
, sizeof (struct score_it
));
3865 build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
3871 For an external symbol: ori r1, LO%<constant> */
3872 sprintf (tmp
, "ori r1, %d", lo
);
3873 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
3876 memcpy (&fix_insts
[0], &inst
, sizeof (struct score_it
));
3879 For a local symbol: addi r1, <sym>+LO%<constant> (BFD_RELOC_GOT_LO16) */
3880 sprintf (tmp
, "addi_u_pic r1, %s + %d", add_symbol
->bsym
->name
, lo
);
3881 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
3884 memcpy (&var_insts
[0], &inst
, sizeof (struct score_it
));
3885 build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
3887 /* Insn 4: add rD, rD, r1 */
3888 sprintf (tmp
, "add r%d, r%d, r1", reg_rd
, reg_rd
);
3889 if (append_insn (tmp
, TRUE
) == (int) FAIL
)
3892 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
3901 do_macro_la_rdi32 (char *str
)
3905 skip_whitespace (str
);
3906 if ((reg_rd
= reg_required_here (&str
, 20, REG_TYPE_SCORE
)) == (int) FAIL
3907 || skip_past_comma (&str
) == (int) FAIL
)
3913 char append_str
[MAX_LITERAL_POOL_SIZE
];
3914 char *keep_data
= str
;
3916 /* la rd, simm16. */
3917 if (data_op2 (&str
, 1, _SIMM16_LA
) != (int) FAIL
)
3922 /* la rd, imm32 or la rd, label. */
3925 SET_INSN_ERROR (NULL
);
3927 if ((data_op2 (&str
, 1, _VALUE_HI16
) == (int) FAIL
)
3928 || (end_of_line (str
) == (int) FAIL
))
3934 if ((score_pic
== NO_PIC
) || (!inst
.reloc
.exp
.X_add_symbol
))
3936 sprintf (append_str
, "ld_i32hi r%d, %s", reg_rd
, keep_data
);
3937 if (append_insn (append_str
, TRUE
) == (int) FAIL
)
3940 sprintf (append_str
, "ld_i32lo r%d, %s", reg_rd
, keep_data
);
3941 if (append_insn (append_str
, TRUE
) == (int) FAIL
)
3946 assert (inst
.reloc
.exp
.X_add_symbol
);
3947 build_la_pic (reg_rd
, inst
.reloc
.exp
);
3950 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
3959 do_macro_li_rdi32 (char *str
){
3963 skip_whitespace (str
);
3964 if ((reg_rd
= reg_required_here (&str
, 20, REG_TYPE_SCORE
)) == (int) FAIL
3965 || skip_past_comma (&str
) == (int) FAIL
)
3971 char *keep_data
= str
;
3973 /* li rd, simm16. */
3974 if (data_op2 (&str
, 1, _SIMM16_LA
) != (int) FAIL
)
3982 char append_str
[MAX_LITERAL_POOL_SIZE
];
3986 if ((data_op2 (&str
, 1, _VALUE_HI16
) == (int) FAIL
)
3987 || (end_of_line (str
) == (int) FAIL
))
3991 else if (inst
.reloc
.exp
.X_add_symbol
)
3993 inst
.error
= _("li rd label isn't correct instruction form");
3998 sprintf (append_str
, "ld_i32hi r%d, %s", reg_rd
, keep_data
);
4000 if (append_insn (append_str
, TRUE
) == (int) FAIL
)
4004 sprintf (append_str
, "ld_i32lo r%d, %s", reg_rd
, keep_data
);
4005 if (append_insn (append_str
, TRUE
) == (int) FAIL
)
4008 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4016 /* Handle mul/mulu/div/divu/rem/remu. */
4018 do_macro_mul_rdrsrs (char *str
)
4024 char append_str
[MAX_LITERAL_POOL_SIZE
];
4026 if (university_version
== 1)
4027 as_warn ("%s", ERR_FOR_SCORE5U_MUL_DIV
);
4029 strcpy (append_str
, str
);
4030 backupstr
= append_str
;
4031 skip_whitespace (backupstr
);
4032 if (((reg_rd
= reg_required_here (&backupstr
, -1, REG_TYPE_SCORE
)) == (int) FAIL
)
4033 || (skip_past_comma (&backupstr
) == (int) FAIL
)
4034 || ((reg_rs1
= reg_required_here (&backupstr
, -1, REG_TYPE_SCORE
)) == (int) FAIL
))
4036 inst
.error
= BAD_ARGS
;
4040 if (skip_past_comma (&backupstr
) == (int) FAIL
)
4042 /* rem/remu rA, rB is error format. */
4043 if (strcmp (inst
.name
, "rem") == 0 || strcmp (inst
.name
, "remu") == 0)
4045 SET_INSN_ERROR (BAD_ARGS
);
4049 SET_INSN_ERROR (NULL
);
4056 SET_INSN_ERROR (NULL
);
4057 if (((reg_rs2
= reg_required_here (&backupstr
, -1, REG_TYPE_SCORE
)) == (int) FAIL
)
4058 || (end_of_line (backupstr
) == (int) FAIL
))
4064 char append_str1
[MAX_LITERAL_POOL_SIZE
];
4066 if (strcmp (inst
.name
, "rem") == 0)
4068 sprintf (append_str
, "mul r%d, r%d", reg_rs1
, reg_rs2
);
4069 sprintf (append_str1
, "mfceh r%d", reg_rd
);
4071 else if (strcmp (inst
.name
, "remu") == 0)
4073 sprintf (append_str
, "mulu r%d, r%d", reg_rs1
, reg_rs2
);
4074 sprintf (append_str1
, "mfceh r%d", reg_rd
);
4078 sprintf (append_str
, "%s r%d, r%d", inst
.name
, reg_rs1
, reg_rs2
);
4079 sprintf (append_str1
, "mfcel r%d", reg_rd
);
4082 /* Output mul/mulu or div/divu or rem/remu. */
4083 if (append_insn (append_str
, TRUE
) == (int) FAIL
)
4086 /* Output mfcel or mfceh. */
4087 if (append_insn (append_str1
, TRUE
) == (int) FAIL
)
4090 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4097 exp_macro_ldst_abs (char *str
)
4100 char *backupstr
, *tmp
;
4101 char append_str
[MAX_LITERAL_POOL_SIZE
];
4102 char verifystr
[MAX_LITERAL_POOL_SIZE
];
4103 struct score_it inst_backup
;
4108 memcpy (&inst_backup
, &inst
, sizeof (struct score_it
));
4110 strcpy (verifystr
, str
);
4111 backupstr
= verifystr
;
4112 skip_whitespace (backupstr
);
4113 if ((reg_rd
= reg_required_here (&backupstr
, -1, REG_TYPE_SCORE
)) == (int) FAIL
)
4117 if (skip_past_comma (&backupstr
) == (int) FAIL
)
4121 sprintf (append_str
, "li r1 %s", backupstr
);
4122 append_insn (append_str
, TRUE
);
4124 memcpy (&inst
, &inst_backup
, sizeof (struct score_it
));
4125 sprintf (append_str
, " r%d, [r1,0]", reg_rd
);
4126 do_ldst_insn (append_str
);
4132 nopic_need_relax (symbolS
* sym
, int before_relaxing
)
4136 else if (USE_GLOBAL_POINTER_OPT
&& g_switch_value
> 0)
4138 const char *symname
;
4139 const char *segname
;
4141 /* Find out whether this symbol can be referenced off the $gp
4142 register. It can be if it is smaller than the -G size or if
4143 it is in the .sdata or .sbss section. Certain symbols can
4144 not be referenced off the $gp, although it appears as though
4146 symname
= S_GET_NAME (sym
);
4147 if (symname
!= (const char *)NULL
4148 && (strcmp (symname
, "eprol") == 0
4149 || strcmp (symname
, "etext") == 0
4150 || strcmp (symname
, "_gp") == 0
4151 || strcmp (symname
, "edata") == 0
4152 || strcmp (symname
, "_fbss") == 0
4153 || strcmp (symname
, "_fdata") == 0
4154 || strcmp (symname
, "_ftext") == 0
4155 || strcmp (symname
, "end") == 0
4156 || strcmp (symname
, GP_DISP_LABEL
) == 0))
4160 else if ((!S_IS_DEFINED (sym
) || S_IS_COMMON (sym
)) && (0
4161 /* We must defer this decision until after the whole file has been read,
4162 since there might be a .extern after the first use of this symbol. */
4164 && S_GET_VALUE (sym
) == 0)
4165 || (S_GET_VALUE (sym
) != 0
4166 && S_GET_VALUE (sym
) <= g_switch_value
)))
4171 segname
= segment_name (S_GET_SEGMENT (sym
));
4172 return (strcmp (segname
, ".sdata") != 0
4173 && strcmp (segname
, ".sbss") != 0
4174 && strncmp (segname
, ".sdata.", 7) != 0
4175 && strncmp (segname
, ".gnu.linkonce.s.", 16) != 0);
4177 /* We are not optimizing for the $gp register. */
4182 /* Build a relax frag for lw/st instruction when generating PIC,
4183 external symbol first and local symbol second. */
4186 build_lwst_pic (int reg_rd
, expressionS exp
, const char *insn_name
)
4188 symbolS
*add_symbol
= exp
.X_add_symbol
;
4189 int add_number
= exp
.X_add_number
;
4190 struct score_it fix_insts
[RELAX_INST_NUM
];
4191 struct score_it var_insts
[RELAX_INST_NUM
];
4194 char tmp
[MAX_LITERAL_POOL_SIZE
];
4200 if ((add_number
== 0) || (add_number
>= -0x8000 && add_number
<= 0x7fff))
4205 /* For an external symbol, two insns are generated;
4206 For a local symbol, three insns are generated. */
4208 For an external symbol: lw rD, <sym>($gp)
4209 (BFD_RELOC_SCORE_GOT15) */
4210 sprintf (tmp
, "lw_pic r1, %s", add_symbol
->bsym
->name
);
4211 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
4214 memcpy (&fix_insts
[0], &inst
, sizeof (struct score_it
));
4217 For a local symbol :
4218 lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15)
4219 addi rD, <sym> (BFD_RELOC_GOT_LO16) */
4220 inst
.reloc
.type
= BFD_RELOC_SCORE_GOT15
;
4221 memcpy (&var_insts
[0], &inst
, sizeof (struct score_it
));
4222 sprintf (tmp
, "addi_s_pic r1, %s", add_symbol
->bsym
->name
);
4223 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
4226 memcpy (&var_insts
[1], &inst
, sizeof (struct score_it
));
4227 build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
4229 /* Insn 2 or Insn 3: lw/st rD, [r1, constant] */
4230 sprintf (tmp
, "%s r%d, [r1, %d]", insn_name
, reg_rd
, add_number
);
4231 if (append_insn (tmp
, TRUE
) == (int) FAIL
)
4234 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4239 inst
.error
= _("PIC code offset overflow (max 16 signed bits)");
4247 do_macro_ldst_label (char *str
)
4255 char *absolute_value
;
4256 char append_str
[3][MAX_LITERAL_POOL_SIZE
];
4257 char verifystr
[MAX_LITERAL_POOL_SIZE
];
4258 struct score_it inst_backup
;
4259 struct score_it inst_expand
[3];
4260 struct score_it inst_main
;
4262 memcpy (&inst_backup
, &inst
, sizeof (struct score_it
));
4263 strcpy (verifystr
, str
);
4264 backup_str
= verifystr
;
4266 skip_whitespace (backup_str
);
4267 if ((reg_rd
= reg_required_here (&backup_str
, -1, REG_TYPE_SCORE
)) == (int) FAIL
)
4270 if (skip_past_comma (&backup_str
) == (int) FAIL
)
4273 label_str
= backup_str
;
4275 /* Ld/st rD, [rA, imm] ld/st rD, [rA]+, imm ld/st rD, [rA, imm]+. */
4276 if (*backup_str
== '[')
4278 inst
.type
= Rd_rvalueRs_preSI12
;
4283 /* Ld/st rD, imm. */
4284 absolute_value
= backup_str
;
4285 inst
.type
= Rd_rvalueRs_SI15
;
4286 if ((my_get_expression (&inst
.reloc
.exp
, &backup_str
) == (int) FAIL
)
4287 || (validate_immediate (inst
.reloc
.exp
.X_add_number
, _VALUE
, 0) == (int) FAIL
)
4288 || (end_of_line (backup_str
) == (int) FAIL
))
4294 if (inst
.reloc
.exp
.X_add_symbol
== 0)
4296 memcpy (&inst
, &inst_backup
, sizeof (struct score_it
));
4297 exp_macro_ldst_abs (str
);
4302 /* Ld/st rD, label. */
4303 inst
.type
= Rd_rvalueRs_SI15
;
4304 backup_str
= absolute_value
;
4305 if ((data_op2 (&backup_str
, 1, _GP_IMM15
) == (int) FAIL
)
4306 || (end_of_line (backup_str
) == (int) FAIL
))
4312 if (inst
.reloc
.exp
.X_add_symbol
== 0)
4315 inst
.error
= BAD_ARGS
;
4320 if (score_pic
== PIC
)
4323 ldst_idx
= inst
.instruction
& OPC_PSEUDOLDST_MASK
;
4324 build_lwst_pic (reg_rd
, inst
.reloc
.exp
, score_ldst_insns
[ldst_idx
* 3 + 0].template);
4329 if ((inst
.reloc
.exp
.X_add_number
<= 0x3fff)
4330 && (inst
.reloc
.exp
.X_add_number
>= -0x4000)
4331 && (!nopic_need_relax (inst
.reloc
.exp
.X_add_symbol
, 1)))
4335 /* Assign the real opcode. */
4336 ldst_idx
= inst
.instruction
& OPC_PSEUDOLDST_MASK
;
4337 inst
.instruction
&= ~OPC_PSEUDOLDST_MASK
;
4338 inst
.instruction
|= score_ldst_insns
[ldst_idx
* 3 + 0].value
;
4339 inst
.instruction
|= reg_rd
<< 20;
4340 inst
.instruction
|= GP
<< 15;
4341 inst
.relax_inst
= 0x8000;
4342 inst
.relax_size
= 0;
4349 memcpy (&inst_main
, &inst
, sizeof (struct score_it
));
4353 /* Determine which instructions should be output. */
4354 sprintf (append_str
[0], "ld_i32hi r1, %s", label_str
);
4355 sprintf (append_str
[1], "ld_i32lo r1, %s", label_str
);
4356 sprintf (append_str
[2], "%s r%d, [r1, 0]", inst_backup
.name
, reg_rd
);
4358 /* Generate three instructions.
4360 ld/st rd, [r1, 0] */
4361 for (i
= 0; i
< 3; i
++)
4363 if (append_insn (append_str
[i
], FALSE
) == (int) FAIL
)
4366 memcpy (&inst_expand
[i
], &inst
, sizeof (struct score_it
));
4373 /* Adjust instruction opcode and to be relaxed instruction opcode. */
4374 inst_main
.instruction
= adjust_paritybit (inst_main
.instruction
, GET_INSN_CLASS (inst_main
.type
));
4375 inst_main
.relax_size
= inst_expand
[0].size
+ inst_expand
[1].size
+ inst_expand
[2].size
;
4376 inst_main
.type
= Insn_GP
;
4378 for (i
= 0; i
< 3; i
++)
4379 inst_expand
[i
].instruction
= adjust_paritybit (inst_expand
[i
].instruction
4380 , GET_INSN_CLASS (inst_expand
[i
].type
));
4382 /* Check data dependency. */
4383 handle_dependency (&inst_main
);
4385 /* Start a new frag if frag_now is not empty. */
4386 if (frag_now_fix () != 0)
4388 if (!frag_now
->tc_frag_data
.is_insn
)
4389 frag_wane (frag_now
);
4395 /* Write fr_fix part. */
4396 p
= frag_more (inst_main
.size
);
4397 md_number_to_chars (p
, inst_main
.instruction
, inst_main
.size
);
4399 if (inst_main
.reloc
.type
!= BFD_RELOC_NONE
)
4401 fix_new_score (frag_now
, p
- frag_now
->fr_literal
, inst_main
.size
,
4402 &inst_main
.reloc
.exp
, inst_main
.reloc
.pc_rel
, inst_main
.reloc
.type
);
4406 dwarf2_emit_insn (inst_main
.size
);
4409 /* GP instruction can not do optimization, only can do relax between
4410 1 instruction and 3 instructions. */
4411 p
= frag_var (rs_machine_dependent
, inst_main
.relax_size
+ RELAX_PAD_BYTE
, 0,
4412 RELAX_ENCODE (inst_main
.size
, inst_main
.relax_size
, inst_main
.type
, 0, 4, 0),
4413 inst_main
.reloc
.exp
.X_add_symbol
, 0, NULL
);
4415 /* Write fr_var part.
4416 no calling gen_insn_frag, no fixS will be generated. */
4417 md_number_to_chars (p
, inst_expand
[0].instruction
, inst_expand
[0].size
);
4418 p
+= inst_expand
[0].size
;
4419 md_number_to_chars (p
, inst_expand
[1].instruction
, inst_expand
[1].size
);
4420 p
+= inst_expand
[1].size
;
4421 md_number_to_chars (p
, inst_expand
[2].instruction
, inst_expand
[2].size
);
4425 gen_insn_frag (&inst_expand
[0], NULL
);
4426 gen_insn_frag (&inst_expand
[1], NULL
);
4427 gen_insn_frag (&inst_expand
[2], NULL
);
4431 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4436 do_lw_pic (char *str
)
4440 skip_whitespace (str
);
4441 if (((reg_rd
= reg_required_here (&str
, 20, REG_TYPE_SCORE
)) == (int) FAIL
)
4442 || (skip_past_comma (&str
) == (int) FAIL
)
4443 || (my_get_expression (&inst
.reloc
.exp
, &str
) == (int) FAIL
)
4444 || (end_of_line (str
) == (int) FAIL
))
4450 if (inst
.reloc
.exp
.X_add_symbol
== 0)
4453 inst
.error
= BAD_ARGS
;
4458 inst
.instruction
|= GP
<< 15;
4459 inst
.reloc
.type
= BFD_RELOC_SCORE_GOT15
;
4464 do_empty (char *str
)
4467 if (university_version
== 1)
4469 if (((inst
.instruction
& 0x3e0003ff) == 0x0c000004)
4470 || ((inst
.instruction
& 0x3e0003ff) == 0x0c000024)
4471 || ((inst
.instruction
& 0x3e0003ff) == 0x0c000044)
4472 || ((inst
.instruction
& 0x3e0003ff) == 0x0c000064))
4474 inst
.error
= ERR_FOR_SCORE5U_MMU
;
4478 if (end_of_line (str
) == (int) FAIL
)
4481 if (inst
.relax_inst
!= 0x8000)
4483 if (inst
.type
== NO_OPD
)
4485 inst
.relax_size
= 2;
4489 inst
.relax_size
= 4;
4499 skip_whitespace (str
);
4500 if (my_get_expression (&inst
.reloc
.exp
, &str
) == (int) FAIL
4501 || end_of_line (str
) == (int) FAIL
)
4504 if (inst
.reloc
.exp
.X_add_symbol
== 0)
4506 inst
.error
= _("lacking label ");
4510 if (((inst
.reloc
.exp
.X_add_number
& 0xff000000) != 0)
4511 && ((inst
.reloc
.exp
.X_add_number
& 0xff000000) != 0xff000000))
4513 inst
.error
= _("invalid constant: 25 bit expression not in range -2^24..2^24");
4517 save_in
= input_line_pointer
;
4518 input_line_pointer
= str
;
4519 inst
.reloc
.type
= BFD_RELOC_SCORE_JMP
;
4520 inst
.reloc
.pc_rel
= 1;
4521 input_line_pointer
= save_in
;
4525 do16_jump (char *str
)
4527 skip_whitespace (str
);
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
& 0xfffff800) != 0)
4539 && ((inst
.reloc
.exp
.X_add_number
& 0xfffff800) != 0xfffff800))
4541 inst
.error
= _("invalid constant: 12 bit expression not in range -2^11..2^11");
4545 inst
.reloc
.type
= BFD_RELOC_SCORE16_JMP
;
4546 inst
.reloc
.pc_rel
= 1;
4550 do_branch (char *str
)
4552 unsigned long abs_value
= 0;
4554 if (my_get_expression (&inst
.reloc
.exp
, &str
) == (int) FAIL
4555 || end_of_line (str
) == (int) FAIL
)
4559 else if (inst
.reloc
.exp
.X_add_symbol
== 0)
4561 inst
.error
= _("lacking label ");
4564 else if (((inst
.reloc
.exp
.X_add_number
& 0xff000000) != 0)
4565 && ((inst
.reloc
.exp
.X_add_number
& 0xff000000) != 0xff000000))
4567 inst
.error
= _("invalid constant: 20 bit expression not in range -2^19..2^19");
4571 inst
.reloc
.type
= BFD_RELOC_SCORE_BRANCH
;
4572 inst
.reloc
.pc_rel
= 1;
4574 /* Branch 32 offset field : 20 bit, 16 bit branch offset field : 8 bit. */
4575 inst
.instruction
|= (inst
.reloc
.exp
.X_add_number
& 0x3fe) | ((inst
.reloc
.exp
.X_add_number
& 0xffc00) << 5);
4577 /* Compute 16 bit branch instruction. */
4578 if ((inst
.relax_inst
!= 0x8000) && (abs_value
& 0xfffffe00) == 0)
4580 inst
.relax_inst
|= (((inst
.instruction
>> 10) & 0xf) << 8);
4581 inst
.relax_inst
|= ((inst
.reloc
.exp
.X_add_number
>> 1) & 0xff);
4582 inst
.relax_size
= 2;
4586 inst
.relax_inst
= 0x8000;
4591 do16_branch (char *str
)
4593 if ((my_get_expression (&inst
.reloc
.exp
, &str
) == (int) FAIL
4594 || end_of_line (str
) == (int) FAIL
))
4598 else if (inst
.reloc
.exp
.X_add_symbol
== 0)
4600 inst
.error
= _("lacking label");
4602 else if (((inst
.reloc
.exp
.X_add_number
& 0xffffff00) != 0)
4603 && ((inst
.reloc
.exp
.X_add_number
& 0xffffff00) != 0xffffff00))
4605 inst
.error
= _("invalid constant: 9 bit expression not in range -2^8..2^8");
4609 inst
.reloc
.type
= BFD_RELOC_SCORE16_BRANCH
;
4610 inst
.reloc
.pc_rel
= 1;
4611 inst
.instruction
|= ((inst
.reloc
.exp
.X_add_number
>> 1) & 0xff);
4615 /* Iterate over the base tables to create the instruction patterns. */
4617 build_score_ops_hsh (void)
4620 static struct obstack insn_obstack
;
4622 obstack_begin (&insn_obstack
, 4000);
4623 for (i
= 0; i
< sizeof (score_insns
) / sizeof (struct asm_opcode
); i
++)
4625 const struct asm_opcode
*insn
= score_insns
+ i
;
4626 unsigned len
= strlen (insn
->template);
4627 struct asm_opcode
*new;
4629 new = obstack_alloc (&insn_obstack
, sizeof (struct asm_opcode
));
4630 template = obstack_alloc (&insn_obstack
, len
+ 1);
4632 strcpy (template, insn
->template);
4633 new->template = template;
4634 new->parms
= insn
->parms
;
4635 new->value
= insn
->value
;
4636 new->relax_value
= insn
->relax_value
;
4637 new->type
= insn
->type
;
4638 new->bitmask
= insn
->bitmask
;
4639 hash_insert (score_ops_hsh
, new->template, (void *) new);
4644 build_dependency_insn_hsh (void)
4647 static struct obstack dependency_obstack
;
4649 obstack_begin (&dependency_obstack
, 4000);
4650 for (i
= 0; i
< sizeof (insn_to_dependency_table
) / sizeof (insn_to_dependency_table
[0]); i
++)
4652 const struct insn_to_dependency
*tmp
= insn_to_dependency_table
+ i
;
4653 unsigned len
= strlen (tmp
->insn_name
);
4654 struct insn_to_dependency
*new;
4656 new = obstack_alloc (&dependency_obstack
, sizeof (struct insn_to_dependency
));
4657 new->insn_name
= obstack_alloc (&dependency_obstack
, len
+ 1);
4659 strcpy (new->insn_name
, tmp
->insn_name
);
4660 new->type
= tmp
->type
;
4661 hash_insert (dependency_insn_hsh
, new->insn_name
, (void *) new);
4665 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
4666 for use in the a.out file, and stores them in the array pointed to by buf.
4667 This knows about the endian-ness of the target machine and does
4668 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
4669 2 (short) and 4 (long) Floating numbers are put out as a series of
4670 LITTLENUMS (shorts, here at least). */
4673 md_number_to_chars (char *buf
, valueT val
, int n
)
4675 if (target_big_endian
)
4676 number_to_chars_bigendian (buf
, val
, n
);
4678 number_to_chars_littleendian (buf
, val
, n
);
4682 md_chars_to_number (char *buf
, int n
)
4685 unsigned char *where
= (unsigned char *)buf
;
4687 if (target_big_endian
)
4692 result
|= (*where
++ & 255);
4700 result
|= (where
[n
] & 255);
4707 /* Turn a string in input_line_pointer into a floating point constant
4708 of type TYPE, and store the appropriate bytes in *LITP. The number
4709 of LITTLENUMS emitted is stored in *SIZEP. An error message is
4710 returned, or NULL on OK.
4712 Note that fp constants aren't represent in the normal way on the ARM.
4713 In big endian mode, things are as expected. However, in little endian
4714 mode fp constants are big-endian word-wise, and little-endian byte-wise
4715 within the words. For example, (double) 1.1 in big endian mode is
4716 the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
4717 the byte sequence 99 99 f1 3f 9a 99 99 99. */
4720 md_atof (int type
, char *litP
, int *sizeP
)
4723 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
4749 return _("bad call to MD_ATOF()");
4752 t
= atof_ieee (input_line_pointer
, type
, words
);
4754 input_line_pointer
= t
;
4757 if (target_big_endian
)
4759 for (i
= 0; i
< prec
; i
++)
4761 md_number_to_chars (litP
, (valueT
) words
[i
], 2);
4767 for (i
= 0; i
< prec
; i
+= 2)
4769 md_number_to_chars (litP
, (valueT
) words
[i
+ 1], 2);
4770 md_number_to_chars (litP
+ 2, (valueT
) words
[i
], 2);
4778 /* Return true if the given symbol should be considered local for PIC. */
4781 pic_need_relax (symbolS
*sym
, asection
*segtype
)
4784 bfd_boolean linkonce
;
4786 /* Handle the case of a symbol equated to another symbol. */
4787 while (symbol_equated_reloc_p (sym
))
4791 /* It's possible to get a loop here in a badly written
4793 n
= symbol_get_value_expression (sym
)->X_add_symbol
;
4799 symsec
= S_GET_SEGMENT (sym
);
4801 /* duplicate the test for LINK_ONCE sections as in adjust_reloc_syms */
4803 if (symsec
!= segtype
&& ! S_IS_LOCAL (sym
))
4805 if ((bfd_get_section_flags (stdoutput
, symsec
) & SEC_LINK_ONCE
) != 0)
4808 /* The GNU toolchain uses an extension for ELF: a section
4809 beginning with the magic string .gnu.linkonce is a linkonce
4811 if (strncmp (segment_name (symsec
), ".gnu.linkonce",
4812 sizeof ".gnu.linkonce" - 1) == 0)
4816 /* This must duplicate the test in adjust_reloc_syms. */
4817 return (symsec
!= &bfd_und_section
4818 && symsec
!= &bfd_abs_section
4819 && ! bfd_is_com_section (symsec
)
4822 /* A global or weak symbol is treated as external. */
4823 && (OUTPUT_FLAVOR
!= bfd_target_elf_flavour
4824 || (! S_IS_WEAK (sym
) && ! S_IS_EXTERNAL (sym
)))
4830 judge_size_before_relax (fragS
* fragp
, asection
*sec
)
4834 if (score_pic
== NO_PIC
)
4835 change
= nopic_need_relax (fragp
->fr_symbol
, 0);
4837 change
= pic_need_relax (fragp
->fr_symbol
, sec
);
4841 /* Only at the first time determining whether GP instruction relax should be done,
4842 return the difference between insntruction size and instruction relax size. */
4843 if (fragp
->fr_opcode
== NULL
)
4845 fragp
->fr_fix
= RELAX_NEW (fragp
->fr_subtype
);
4846 fragp
->fr_opcode
= fragp
->fr_literal
+ RELAX_RELOC1 (fragp
->fr_subtype
);
4847 return RELAX_NEW (fragp
->fr_subtype
) - RELAX_OLD (fragp
->fr_subtype
);
4854 /* In this function, we determine whether GP instruction should do relaxation,
4855 for the label being against was known now.
4856 Doing this here but not in md_relax_frag() can induce iteration times
4857 in stage of doing relax. */
4859 md_estimate_size_before_relax (fragS
* fragp
, asection
* sec ATTRIBUTE_UNUSED
)
4861 if ((RELAX_TYPE (fragp
->fr_subtype
) == Insn_GP
)
4862 || (RELAX_TYPE (fragp
->fr_subtype
) == Insn_PIC
))
4863 return judge_size_before_relax (fragp
, sec
);
4869 b32_relax_to_b16 (fragS
* fragp
)
4872 int relaxable_p
= 0;
4875 int frag_addr
= fragp
->fr_address
+ fragp
->insn_addr
;
4877 addressT symbol_address
= 0;
4880 unsigned long value
;
4881 unsigned long abs_value
;
4883 /* FIXME : here may be able to modify better .
4884 I don't know how to get the fragp's section ,
4885 so in relax stage , it may be wrong to calculate the symbol's offset when the frag's section
4886 is different from the symbol's. */
4888 old
= RELAX_OLD (fragp
->fr_subtype
);
4889 new = RELAX_NEW (fragp
->fr_subtype
);
4890 relaxable_p
= RELAX_OPT (fragp
->fr_subtype
);
4892 s
= fragp
->fr_symbol
;
4893 /* b/bl immediate */
4899 symbol_address
= (addressT
) s
->sy_frag
->fr_address
;
4902 value
= md_chars_to_number (fragp
->fr_literal
, INSN_SIZE
);
4904 /* b 32's offset : 20 bit, b 16's tolerate field : 0xff. */
4905 offset
= ((value
& 0x3ff0000) >> 6) | (value
& 0x3fe);
4906 if ((offset
& 0x80000) == 0x80000)
4907 offset
|= 0xfff00000;
4909 abs_value
= offset
+ symbol_address
- frag_addr
;
4910 if ((abs_value
& 0x80000000) == 0x80000000)
4911 abs_value
= 0xffffffff - abs_value
+ 1;
4913 /* Relax branch 32 to branch 16. */
4914 if (relaxable_p
&& (s
->bsym
!= NULL
) && ((abs_value
& 0xffffff00) == 0)
4915 && (S_IS_DEFINED (s
) && !S_IS_COMMON (s
) && !S_IS_EXTERNAL (s
)))
4921 /* Branch 32 can not be relaxed to b 16, so clear OPT bit. */
4922 fragp
->fr_opcode
= NULL
;
4923 fragp
->fr_subtype
= RELAX_OPT_CLEAR (fragp
->fr_subtype
);
4929 /* Main purpose is to determine whether one frag should do relax.
4930 frag->fr_opcode indicates this point. */
4933 score_relax_frag (asection
* sec ATTRIBUTE_UNUSED
, fragS
* fragp
, long stretch ATTRIBUTE_UNUSED
)
4937 int insn_relax_size
;
4938 int do_relax_p
= 0; /* Indicate doing relaxation for this frag. */
4939 int relaxable_p
= 0;
4940 bfd_boolean word_align_p
= FALSE
;
4943 /* If the instruction address is odd, make it half word align first. */
4944 if ((fragp
->fr_address
) % 2 != 0)
4946 if ((fragp
->fr_address
+ fragp
->insn_addr
) % 2 != 0)
4948 fragp
->insn_addr
= 1;
4953 word_align_p
= ((fragp
->fr_address
+ fragp
->insn_addr
) % 4 == 0) ? TRUE
: FALSE
;
4955 /* Get instruction size and relax size after the last relaxation. */
4956 if (fragp
->fr_opcode
)
4958 insn_size
= RELAX_NEW (fragp
->fr_subtype
);
4959 insn_relax_size
= RELAX_OLD (fragp
->fr_subtype
);
4963 insn_size
= RELAX_OLD (fragp
->fr_subtype
);
4964 insn_relax_size
= RELAX_NEW (fragp
->fr_subtype
);
4967 /* Handle specially for GP instruction. for, judge_size_before_relax() has already determine
4968 whether the GP instruction should do relax. */
4969 if ((RELAX_TYPE (fragp
->fr_subtype
) == Insn_GP
)
4970 || (RELAX_TYPE (fragp
->fr_subtype
) == Insn_PIC
))
4974 if (fragp
->insn_addr
< 2)
4976 fragp
->insn_addr
+= 2;
4981 fragp
->insn_addr
-= 2;
4986 if (fragp
->fr_opcode
)
4987 fragp
->fr_fix
= RELAX_NEW (fragp
->fr_subtype
) + fragp
->insn_addr
;
4989 fragp
->fr_fix
= RELAX_OLD (fragp
->fr_subtype
) + fragp
->insn_addr
;
4993 if (RELAX_TYPE (fragp
->fr_subtype
) == PC_DISP19div2
)
4994 b32_relax_to_b16 (fragp
);
4996 relaxable_p
= RELAX_OPT (fragp
->fr_subtype
);
4997 next_fragp
= fragp
->fr_next
;
4998 while ((next_fragp
) && (next_fragp
->fr_type
!= rs_machine_dependent
))
5000 next_fragp
= next_fragp
->fr_next
;
5006 int n_relaxable_p
= 0;
5008 if (next_fragp
->fr_opcode
)
5010 n_insn_size
= RELAX_NEW (next_fragp
->fr_subtype
);
5014 n_insn_size
= RELAX_OLD (next_fragp
->fr_subtype
);
5017 if (RELAX_TYPE (next_fragp
->fr_subtype
) == PC_DISP19div2
)
5018 b32_relax_to_b16 (next_fragp
);
5019 n_relaxable_p
= RELAX_OPT (next_fragp
->fr_subtype
);
5026 if (relaxable_p
&& ((n_insn_size
== 2) || n_relaxable_p
))
5032 else if (insn_size
== 2)
5035 if (relaxable_p
&& (((n_insn_size
== 4) && !n_relaxable_p
) || (n_insn_size
> 4)))
5056 /* Make the 32 bit insturction word align. */
5059 fragp
->insn_addr
+= 2;
5063 else if (insn_size
== 2)
5075 /* Here, try best to do relax regardless fragp->fr_next->fr_type. */
5076 if (word_align_p
== FALSE
)
5078 if (insn_size
% 4 == 0)
5088 fragp
->insn_addr
+= 2;
5099 /* fragp->fr_opcode indicates whether this frag should be relaxed. */
5102 if (fragp
->fr_opcode
)
5104 fragp
->fr_opcode
= NULL
;
5105 /* Guarantee estimate stage is correct. */
5106 fragp
->fr_fix
= RELAX_OLD (fragp
->fr_subtype
);
5107 fragp
->fr_fix
+= fragp
->insn_addr
;
5111 fragp
->fr_opcode
= fragp
->fr_literal
+ RELAX_RELOC1 (fragp
->fr_subtype
);
5112 /* Guarantee estimate stage is correct. */
5113 fragp
->fr_fix
= RELAX_NEW (fragp
->fr_subtype
);
5114 fragp
->fr_fix
+= fragp
->insn_addr
;
5119 if (fragp
->fr_opcode
)
5121 /* Guarantee estimate stage is correct. */
5122 fragp
->fr_fix
= RELAX_NEW (fragp
->fr_subtype
);
5123 fragp
->fr_fix
+= fragp
->insn_addr
;
5127 /* Guarantee estimate stage is correct. */
5128 fragp
->fr_fix
= RELAX_OLD (fragp
->fr_subtype
);
5129 fragp
->fr_fix
+= fragp
->insn_addr
;
5138 md_convert_frag (bfd
* abfd ATTRIBUTE_UNUSED
, segT sec ATTRIBUTE_UNUSED
, fragS
* fragp
)
5145 old
= RELAX_OLD (fragp
->fr_subtype
);
5146 new = RELAX_NEW (fragp
->fr_subtype
);
5148 /* fragp->fr_opcode indicates whether this frag should be relaxed. */
5149 if (fragp
->fr_opcode
== NULL
)
5151 memcpy (backup
, fragp
->fr_literal
, old
);
5152 fragp
->fr_fix
= old
;
5156 memcpy (backup
, fragp
->fr_literal
+ old
, new);
5157 fragp
->fr_fix
= new;
5160 fixp
= fragp
->tc_frag_data
.fixp
;
5161 while (fixp
&& fixp
->fx_frag
== fragp
&& fixp
->fx_where
< old
)
5163 if (fragp
->fr_opcode
)
5165 fixp
= fixp
->fx_next
;
5167 while (fixp
&& fixp
->fx_frag
== fragp
)
5169 if (fragp
->fr_opcode
)
5170 fixp
->fx_where
-= old
+ fragp
->insn_addr
;
5173 fixp
= fixp
->fx_next
;
5176 if (fragp
->insn_addr
)
5178 md_number_to_chars (fragp
->fr_literal
, 0x0, fragp
->insn_addr
);
5180 memcpy (fragp
->fr_literal
+ fragp
->insn_addr
, backup
, fragp
->fr_fix
);
5181 fragp
->fr_fix
+= fragp
->insn_addr
;
5184 /* Implementation of md_frag_check.
5185 Called after md_convert_frag(). */
5188 score_frag_check (fragS
* fragp ATTRIBUTE_UNUSED
)
5190 know (fragp
->insn_addr
<= RELAX_PAD_BYTE
);
5194 score_fix_adjustable (fixS
* fixP
)
5196 if (fixP
->fx_addsy
== NULL
)
5200 else if (OUTPUT_FLAVOR
== bfd_target_elf_flavour
5201 && (S_IS_EXTERNAL (fixP
->fx_addsy
) || S_IS_WEAK (fixP
->fx_addsy
)))
5205 else if (fixP
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
5206 || fixP
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
5214 /* Implementation of TC_VALIDATE_FIX.
5215 Called before md_apply_fix() and after md_convert_frag(). */
5217 score_validate_fix (fixS
*fixP
)
5219 fixP
->fx_where
+= fixP
->fx_frag
->insn_addr
;
5223 md_pcrel_from (fixS
* fixP
)
5228 && (S_GET_SEGMENT (fixP
->fx_addsy
) == undefined_section
)
5229 && (fixP
->fx_subsy
== NULL
))
5235 retval
= fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
5242 score_force_relocation (struct fix
*fixp
)
5246 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
5247 || fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
5248 || fixp
->fx_r_type
== BFD_RELOC_SCORE_JMP
5249 || fixp
->fx_r_type
== BFD_RELOC_SCORE_BRANCH
5250 || fixp
->fx_r_type
== BFD_RELOC_SCORE16_JMP
5251 || fixp
->fx_r_type
== BFD_RELOC_SCORE16_BRANCH
)
5259 /* Round up a section size to the appropriate boundary. */
5261 md_section_align (segT segment ATTRIBUTE_UNUSED
, valueT size
)
5263 int align
= bfd_get_section_alignment (stdoutput
, segment
);
5265 return ((size
+ (1 << align
) - 1) & (-1 << align
));
5269 md_apply_fix (fixS
*fixP
, valueT
*valP
, segT seg
)
5271 offsetT value
= *valP
;
5272 offsetT abs_value
= 0;
5275 unsigned short HI
, LO
;
5277 char *buf
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
5279 assert (fixP
->fx_r_type
< BFD_RELOC_UNUSED
);
5280 if (fixP
->fx_addsy
== 0 && !fixP
->fx_pcrel
)
5282 if (fixP
->fx_r_type
!= BFD_RELOC_SCORE_DUMMY_HI16
)
5286 /* If this symbol is in a different section then we need to leave it for
5287 the linker to deal with. Unfortunately, md_pcrel_from can't tell,
5288 so we have to undo it's effects here. */
5291 if (fixP
->fx_addsy
!= NULL
5292 && S_IS_DEFINED (fixP
->fx_addsy
)
5293 && S_GET_SEGMENT (fixP
->fx_addsy
) != seg
)
5294 value
+= md_pcrel_from (fixP
);
5297 /* Remember value for emit_reloc. */
5298 fixP
->fx_addnumber
= value
;
5300 switch (fixP
->fx_r_type
)
5302 case BFD_RELOC_HI16_S
:
5304 { /* For la rd, imm32. */
5305 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5306 HI
= (value
) >> 16; /* mul to 2, then take the hi 16 bit. */
5307 newval
|= (HI
& 0x3fff) << 1;
5308 newval
|= ((HI
>> 14) & 0x3) << 16;
5309 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5312 case BFD_RELOC_LO16
:
5313 if (fixP
->fx_done
) /* For la rd, imm32. */
5315 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5316 LO
= (value
) & 0xffff;
5317 newval
|= (LO
& 0x3fff) << 1; /* 16 bit: imm -> 14 bit in lo, 2 bit in hi. */
5318 newval
|= ((LO
>> 14) & 0x3) << 16;
5319 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5322 case BFD_RELOC_SCORE_JMP
:
5324 content
= md_chars_to_number (buf
, INSN_SIZE
);
5325 value
= fixP
->fx_offset
;
5326 content
= (content
& ~0x3ff7ffe) | ((value
<< 1) & 0x3ff0000) | (value
& 0x7fff);
5327 md_number_to_chars (buf
, content
, INSN_SIZE
);
5330 case BFD_RELOC_SCORE_BRANCH
:
5331 if ((S_GET_SEGMENT (fixP
->fx_addsy
) != seg
) || (fixP
->fx_addsy
!= NULL
&& S_IS_EXTERNAL (fixP
->fx_addsy
)))
5332 value
= fixP
->fx_offset
;
5336 content
= md_chars_to_number (buf
, INSN_SIZE
);
5337 if ((fixP
->fx_frag
->fr_opcode
!= 0) && ((content
& 0x80008000) != 0x80008000))
5339 if ((value
& 0x80000000) == 0x80000000)
5340 abs_value
= 0xffffffff - value
+ 1;
5341 if ((abs_value
& 0xffffff00) != 0)
5343 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5344 _(" branch relocation truncate (0x%x) [-2^8 ~ 2^8]"), (unsigned int)value
);
5347 content
= md_chars_to_number (buf
, INSN16_SIZE
);
5349 content
= (content
& 0xff00) | ((value
>> 1) & 0xff);
5350 md_number_to_chars (buf
, content
, INSN16_SIZE
);
5351 fixP
->fx_r_type
= BFD_RELOC_SCORE16_BRANCH
;
5356 if ((value
& 0x80000000) == 0x80000000)
5357 abs_value
= 0xffffffff - value
+ 1;
5358 if ((abs_value
& 0xfff80000) != 0)
5360 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5361 _(" branch relocation truncate (0x%x) [-2^19 ~ 2^19]"), (unsigned int)value
);
5364 content
= md_chars_to_number (buf
, INSN_SIZE
);
5365 content
&= 0xfc00fc01;
5366 content
= (content
& 0xfc00fc01) | (value
& 0x3fe) | ((value
<< 6) & 0x3ff0000);
5367 md_number_to_chars (buf
, content
, INSN_SIZE
);
5370 case BFD_RELOC_SCORE16_JMP
:
5371 content
= md_chars_to_number (buf
, INSN16_SIZE
);
5373 value
= fixP
->fx_offset
& 0xfff;
5374 content
= (content
& 0xfc01) | (value
& 0xffe);
5375 md_number_to_chars (buf
, content
, INSN16_SIZE
);
5377 case BFD_RELOC_SCORE16_BRANCH
:
5378 content
= md_chars_to_number (buf
, INSN_SIZE
);
5379 if ((fixP
->fx_frag
->fr_opcode
!= 0) && ((content
& 0x80008000) == 0x80008000))
5381 if ((S_GET_SEGMENT (fixP
->fx_addsy
) != seg
) ||
5382 (fixP
->fx_addsy
!= NULL
&& S_IS_EXTERNAL (fixP
->fx_addsy
)))
5383 value
= fixP
->fx_offset
;
5386 if ((value
& 0x80000000) == 0x80000000)
5387 abs_value
= 0xffffffff - value
+ 1;
5388 if ((abs_value
& 0xfff80000) != 0)
5390 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5391 _(" branch relocation truncate (0x%x) [-2^19 ~ 2^19]"), (unsigned int)value
);
5394 content
= md_chars_to_number (buf
, INSN_SIZE
);
5395 content
= (content
& 0xfc00fc01) | (value
& 0x3fe) | ((value
<< 6) & 0x3ff0000);
5396 md_number_to_chars (buf
, content
, INSN_SIZE
);
5397 fixP
->fx_r_type
= BFD_RELOC_SCORE_BRANCH
;
5403 /* In differnt section. */
5404 if ((S_GET_SEGMENT (fixP
->fx_addsy
) != seg
) ||
5405 (fixP
->fx_addsy
!= NULL
&& S_IS_EXTERNAL (fixP
->fx_addsy
)))
5406 value
= fixP
->fx_offset
;
5410 if ((value
& 0x80000000) == 0x80000000)
5411 abs_value
= 0xffffffff - value
+ 1;
5412 if ((abs_value
& 0xffffff00) != 0)
5414 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5415 _(" branch relocation truncate (0x%x) [-2^8 ~ 2^8]"), (unsigned int)value
);
5418 content
= md_chars_to_number (buf
, INSN16_SIZE
);
5419 content
= (content
& 0xff00) | ((value
>> 1) & 0xff);
5420 md_number_to_chars (buf
, content
, INSN16_SIZE
);
5424 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5425 md_number_to_chars (buf
, value
, 1);
5429 value
= fixP
->fx_offset
;
5430 md_number_to_chars (buf
, value
, 1);
5436 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5437 md_number_to_chars (buf
, value
, 2);
5441 value
= fixP
->fx_offset
;
5442 md_number_to_chars (buf
, value
, 2);
5448 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5449 md_number_to_chars (buf
, value
, 4);
5453 value
= fixP
->fx_offset
;
5454 md_number_to_chars (buf
, value
, 4);
5458 case BFD_RELOC_VTABLE_INHERIT
:
5460 if (fixP
->fx_addsy
&& !S_IS_DEFINED (fixP
->fx_addsy
) && !S_IS_WEAK (fixP
->fx_addsy
))
5461 S_SET_WEAK (fixP
->fx_addsy
);
5463 case BFD_RELOC_VTABLE_ENTRY
:
5466 case BFD_RELOC_SCORE_GPREL15
:
5467 content
= md_chars_to_number (buf
, INSN_SIZE
);
5468 if ((fixP
->fx_frag
->fr_opcode
!= 0) && ((content
& 0xfc1c8000) != 0x94188000))
5469 fixP
->fx_r_type
= BFD_RELOC_NONE
;
5472 case BFD_RELOC_SCORE_GOT15
:
5473 case BFD_RELOC_SCORE_DUMMY_HI16
:
5474 case BFD_RELOC_SCORE_GOT_LO16
:
5475 case BFD_RELOC_SCORE_CALL15
:
5476 case BFD_RELOC_GPREL32
:
5478 case BFD_RELOC_NONE
:
5480 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("bad relocation fixup type (%d)"), fixP
->fx_r_type
);
5484 /* Translate internal representation of relocation info to BFD target format. */
5486 tc_gen_reloc (asection
* section ATTRIBUTE_UNUSED
, fixS
* fixp
)
5488 static arelent
*retval
[MAX_RELOC_EXPANSION
+ 1]; /* MAX_RELOC_EXPANSION equals 2. */
5490 bfd_reloc_code_real_type code
;
5496 reloc
= retval
[0] = xmalloc (sizeof (arelent
));
5499 reloc
->sym_ptr_ptr
= xmalloc (sizeof (asymbol
*));
5500 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
5501 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
5502 reloc
->addend
= fixp
->fx_offset
;
5504 /* If this is a variant frag, we may need to adjust the existing
5505 reloc and generate a new one. */
5506 if (fixp
->fx_frag
->fr_opcode
!= NULL
&& (fixp
->fx_r_type
== BFD_RELOC_SCORE_GPREL15
))
5508 /* Update instruction imm bit. */
5513 buf
= fixp
->fx_frag
->fr_literal
+ fixp
->fx_frag
->insn_addr
;
5514 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5515 off
= fixp
->fx_offset
>> 16;
5516 newval
|= (off
& 0x3fff) << 1;
5517 newval
|= ((off
>> 14) & 0x3) << 16;
5518 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5521 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5522 off
= fixp
->fx_offset
& 0xffff;
5523 newval
|= ((off
& 0x3fff) << 1);
5524 newval
|= (((off
>> 14) & 0x3) << 16);
5525 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5527 retval
[1] = xmalloc (sizeof (arelent
));
5529 retval
[1]->sym_ptr_ptr
= xmalloc (sizeof (asymbol
*));
5530 *retval
[1]->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
5531 retval
[1]->address
= (reloc
->address
+ RELAX_RELOC2 (fixp
->fx_frag
->fr_subtype
));
5537 retval
[1]->addend
= 0;
5538 retval
[1]->howto
= bfd_reloc_type_lookup (stdoutput
, BFD_RELOC_LO16
);
5539 assert (retval
[1]->howto
!= NULL
);
5541 fixp
->fx_r_type
= BFD_RELOC_HI16_S
;
5544 code
= fixp
->fx_r_type
;
5545 switch (fixp
->fx_r_type
)
5550 code
= BFD_RELOC_32_PCREL
;
5553 case BFD_RELOC_HI16_S
:
5554 case BFD_RELOC_LO16
:
5555 case BFD_RELOC_SCORE_JMP
:
5556 case BFD_RELOC_SCORE_BRANCH
:
5557 case BFD_RELOC_SCORE16_JMP
:
5558 case BFD_RELOC_SCORE16_BRANCH
:
5559 case BFD_RELOC_VTABLE_ENTRY
:
5560 case BFD_RELOC_VTABLE_INHERIT
:
5561 case BFD_RELOC_SCORE_GPREL15
:
5562 case BFD_RELOC_SCORE_GOT15
:
5563 case BFD_RELOC_SCORE_DUMMY_HI16
:
5564 case BFD_RELOC_SCORE_GOT_LO16
:
5565 case BFD_RELOC_SCORE_CALL15
:
5566 case BFD_RELOC_GPREL32
:
5567 case BFD_RELOC_NONE
:
5568 code
= fixp
->fx_r_type
;
5571 type
= _("<unknown>");
5572 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5573 _("cannot represent %s relocation in this object file format"), type
);
5577 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
5578 if (reloc
->howto
== NULL
)
5580 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5581 _("cannot represent %s relocation in this object file format1"),
5582 bfd_get_reloc_code_name (code
));
5585 /* HACK: Since arm ELF uses Rel instead of Rela, encode the
5586 vtable entry to be used in the relocation's section offset. */
5587 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
5588 reloc
->address
= fixp
->fx_offset
;
5594 score_elf_final_processing (void)
5596 if (fix_data_dependency
== 1)
5598 elf_elfheader (stdoutput
)->e_flags
|= EF_SCORE_FIXDEP
;
5600 if (score_pic
== PIC
)
5602 elf_elfheader (stdoutput
)->e_flags
|= EF_SCORE_PIC
;
5607 parse_pce_inst (char *insnstr
)
5611 char first
[MAX_LITERAL_POOL_SIZE
];
5612 char second
[MAX_LITERAL_POOL_SIZE
];
5613 struct score_it pec_part_1
;
5615 /* Get first part string of PCE. */
5616 p
= strstr (insnstr
, "||");
5619 sprintf (first
, "%s", insnstr
);
5621 /* Get second part string of PCE. */
5624 sprintf (second
, "%s", p
);
5626 parse_16_32_inst (first
, FALSE
);
5630 memcpy (&pec_part_1
, &inst
, sizeof (inst
));
5632 parse_16_32_inst (second
, FALSE
);
5636 if ( ((pec_part_1
.size
== INSN_SIZE
) && (inst
.size
== INSN_SIZE
))
5637 || ((pec_part_1
.size
== INSN_SIZE
) && (inst
.size
== INSN16_SIZE
))
5638 || ((pec_part_1
.size
== INSN16_SIZE
) && (inst
.size
== INSN_SIZE
)))
5640 inst
.error
= _("pce instruction error (16 bit || 16 bit)'");
5641 sprintf (inst
.str
, insnstr
);
5646 gen_insn_frag (&pec_part_1
, &inst
);
5650 md_assemble (char *str
)
5653 know (strlen (str
) < MAX_LITERAL_POOL_SIZE
);
5655 memset (&inst
, '\0', sizeof (inst
));
5656 if (INSN_IS_PCE_P (str
))
5657 parse_pce_inst (str
);
5659 parse_16_32_inst (str
, TRUE
);
5662 as_bad (_("%s -- `%s'"), inst
.error
, inst
.str
);
5665 /* We handle all bad expressions here, so that we can report the faulty
5666 instruction in the error message. */
5668 md_operand (expressionS
* expr
)
5670 if (in_my_get_expression
)
5672 expr
->X_op
= O_illegal
;
5673 if (inst
.error
== NULL
)
5675 inst
.error
= _("bad expression");
5680 const char *md_shortopts
= "nO::g::G:";
5682 #ifdef SCORE_BI_ENDIAN
5683 #define OPTION_EB (OPTION_MD_BASE + 0)
5684 #define OPTION_EL (OPTION_MD_BASE + 1)
5686 #if TARGET_BYTES_BIG_ENDIAN
5687 #define OPTION_EB (OPTION_MD_BASE + 0)
5689 #define OPTION_EL (OPTION_MD_BASE + 1)
5692 #define OPTION_FIXDD (OPTION_MD_BASE + 2)
5693 #define OPTION_NWARN (OPTION_MD_BASE + 3)
5694 #define OPTION_SCORE5 (OPTION_MD_BASE + 4)
5695 #define OPTION_SCORE5U (OPTION_MD_BASE + 5)
5696 #define OPTION_SCORE7 (OPTION_MD_BASE + 6)
5697 #define OPTION_R1 (OPTION_MD_BASE + 7)
5698 #define OPTION_O0 (OPTION_MD_BASE + 8)
5699 #define OPTION_SCORE_VERSION (OPTION_MD_BASE + 9)
5700 #define OPTION_PIC (OPTION_MD_BASE + 10)
5702 struct option md_longopts
[] =
5705 {"EB" , no_argument
, NULL
, OPTION_EB
},
5708 {"EL" , no_argument
, NULL
, OPTION_EL
},
5710 {"FIXDD" , no_argument
, NULL
, OPTION_FIXDD
},
5711 {"NWARN" , no_argument
, NULL
, OPTION_NWARN
},
5712 {"SCORE5" , no_argument
, NULL
, OPTION_SCORE5
},
5713 {"SCORE5U", no_argument
, NULL
, OPTION_SCORE5U
},
5714 {"SCORE7" , no_argument
, NULL
, OPTION_SCORE7
},
5715 {"USE_R1" , no_argument
, NULL
, OPTION_R1
},
5716 {"O0" , no_argument
, NULL
, OPTION_O0
},
5717 {"V" , no_argument
, NULL
, OPTION_SCORE_VERSION
},
5718 {"KPIC" , no_argument
, NULL
, OPTION_PIC
},
5719 {NULL
, no_argument
, NULL
, 0}
5722 size_t md_longopts_size
= sizeof (md_longopts
);
5725 md_parse_option (int c
, char *arg
)
5731 target_big_endian
= 1;
5736 target_big_endian
= 0;
5740 fix_data_dependency
= 1;
5743 warn_fix_data_dependency
= 0;
5747 university_version
= 0;
5748 vector_size
= SCORE5_PIPELINE
;
5750 case OPTION_SCORE5U
:
5752 university_version
= 1;
5753 vector_size
= SCORE5_PIPELINE
;
5757 university_version
= 0;
5758 vector_size
= SCORE7_PIPELINE
;
5764 g_switch_value
= atoi (arg
);
5769 case OPTION_SCORE_VERSION
:
5770 printf (_("Sunplus-v2-0-0-20060510\n"));
5774 g_switch_value
= 0; /* Must set -G num as 0 to generate PIC code. */
5777 /* as_bad (_("unrecognized option `-%c%s'"), c, arg ? arg : ""); */
5784 md_show_usage (FILE * fp
)
5786 fprintf (fp
, _(" Score-specific assembler options:\n"));
5789 -EB\t\tassemble code for a big-endian cpu\n"));
5794 -EL\t\tassemble code for a little-endian cpu\n"));
5798 -FIXDD\t\tassemble code for fix data dependency\n"));
5800 -NWARN\t\tassemble code for no warning message for fix data dependency\n"));
5802 -SCORE5\t\tassemble code for target is SCORE5\n"));
5804 -SCORE5U\tassemble code for target is SCORE5U\n"));
5806 -SCORE7\t\tassemble code for target is SCORE7, this is default setting\n"));
5808 -USE_R1\t\tassemble code for no warning message when using temp register r1\n"));
5810 -KPIC\t\tassemble code for PIC\n"));
5812 -O0\t\tassembler will not perform any optimizations\n"));
5814 -G gpnum\tassemble code for setting gpsize and default is 8 byte\n"));
5816 -V \t\tSunplus release version \n"));
5820 /* Pesudo handling functions. */
5822 /* If we change section we must dump the literal pool first. */
5824 s_score_bss (int ignore ATTRIBUTE_UNUSED
)
5826 subseg_set (bss_section
, (subsegT
) get_absolute_expression ());
5827 demand_empty_rest_of_line ();
5831 s_score_text (int ignore
)
5833 obj_elf_text (ignore
);
5834 record_alignment (now_seg
, 2);
5838 score_s_section (int ignore
)
5840 obj_elf_section (ignore
);
5841 if ((bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
) != 0)
5842 record_alignment (now_seg
, 2);
5847 s_change_sec (int sec
)
5852 /* The ELF backend needs to know that we are changing sections, so
5853 that .previous works correctly. We could do something like check
5854 for an obj_section_change_hook macro, but that might be confusing
5855 as it would not be appropriate to use it in the section changing
5856 functions in read.c, since obj-elf.c intercepts those. FIXME:
5857 This should be cleaner, somehow. */
5858 obj_elf_section_change_hook ();
5863 seg
= subseg_new (RDATA_SECTION_NAME
, (subsegT
) get_absolute_expression ());
5864 bfd_set_section_flags (stdoutput
, seg
, (SEC_ALLOC
| SEC_LOAD
| SEC_READONLY
| SEC_RELOC
| SEC_DATA
));
5865 if (strcmp (TARGET_OS
, "elf") != 0)
5866 record_alignment (seg
, 4);
5867 demand_empty_rest_of_line ();
5870 seg
= subseg_new (".sdata", (subsegT
) get_absolute_expression ());
5871 bfd_set_section_flags (stdoutput
, seg
, SEC_ALLOC
| SEC_LOAD
| SEC_RELOC
| SEC_DATA
);
5872 if (strcmp (TARGET_OS
, "elf") != 0)
5873 record_alignment (seg
, 4);
5874 demand_empty_rest_of_line ();
5880 s_score_mask (int reg_type ATTRIBUTE_UNUSED
)
5884 if (cur_proc_ptr
== (procS
*) NULL
)
5886 as_warn (_(".mask outside of .ent"));
5887 demand_empty_rest_of_line ();
5890 if (get_absolute_expression_and_terminator (&mask
) != ',')
5892 as_warn (_("Bad .mask directive"));
5893 --input_line_pointer
;
5894 demand_empty_rest_of_line ();
5897 off
= get_absolute_expression ();
5898 cur_proc_ptr
->reg_mask
= mask
;
5899 cur_proc_ptr
->reg_offset
= off
;
5900 demand_empty_rest_of_line ();
5910 name
= input_line_pointer
;
5911 c
= get_symbol_end ();
5912 p
= (symbolS
*) symbol_find_or_make (name
);
5913 *input_line_pointer
= c
;
5923 if (*input_line_pointer
== '-')
5925 ++input_line_pointer
;
5928 if (!ISDIGIT (*input_line_pointer
))
5929 as_bad (_("expected simple number"));
5930 if (input_line_pointer
[0] == '0')
5932 if (input_line_pointer
[1] == 'x')
5934 input_line_pointer
+= 2;
5935 while (ISXDIGIT (*input_line_pointer
))
5938 val
|= hex_value (*input_line_pointer
++);
5940 return negative
? -val
: val
;
5944 ++input_line_pointer
;
5945 while (ISDIGIT (*input_line_pointer
))
5948 val
|= *input_line_pointer
++ - '0';
5950 return negative
? -val
: val
;
5953 if (!ISDIGIT (*input_line_pointer
))
5955 printf (_(" *input_line_pointer == '%c' 0x%02x\n"), *input_line_pointer
, *input_line_pointer
);
5956 as_warn (_("invalid number"));
5959 while (ISDIGIT (*input_line_pointer
))
5962 val
+= *input_line_pointer
++ - '0';
5964 return negative
? -val
: val
;
5967 /* The .aent and .ent directives. */
5970 s_score_ent (int aent
)
5975 symbolP
= get_symbol ();
5976 if (*input_line_pointer
== ',')
5977 ++input_line_pointer
;
5979 if (ISDIGIT (*input_line_pointer
) || *input_line_pointer
== '-')
5982 #ifdef BFD_ASSEMBLER
5983 if ((bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
) != 0)
5988 if (now_seg
!= data_section
&& now_seg
!= bss_section
)
5994 as_warn (_(".ent or .aent not in text section."));
5995 if (!aent
&& cur_proc_ptr
)
5996 as_warn (_("missing .end"));
5999 cur_proc_ptr
= &cur_proc
;
6000 cur_proc_ptr
->reg_mask
= 0xdeadbeaf;
6001 cur_proc_ptr
->reg_offset
= 0xdeadbeaf;
6002 cur_proc_ptr
->fpreg_mask
= 0xdeafbeaf;
6003 cur_proc_ptr
->leaf
= 0xdeafbeaf;
6004 cur_proc_ptr
->frame_offset
= 0xdeafbeaf;
6005 cur_proc_ptr
->frame_reg
= 0xdeafbeaf;
6006 cur_proc_ptr
->pc_reg
= 0xdeafbeaf;
6007 cur_proc_ptr
->isym
= symbolP
;
6008 symbol_get_bfdsym (symbolP
)->flags
|= BSF_FUNCTION
;
6010 if (debug_type
== DEBUG_STABS
)
6011 stabs_generate_asm_func (S_GET_NAME (symbolP
), S_GET_NAME (symbolP
));
6013 demand_empty_rest_of_line ();
6017 s_score_frame (int ignore ATTRIBUTE_UNUSED
)
6024 backupstr
= input_line_pointer
;
6027 if (cur_proc_ptr
== (procS
*) NULL
)
6029 as_warn (_(".frame outside of .ent"));
6030 demand_empty_rest_of_line ();
6033 cur_proc_ptr
->frame_reg
= reg_required_here ((&backupstr
), 0, REG_TYPE_SCORE
);
6035 skip_past_comma (&backupstr
);
6036 while (*backupstr
!= ',')
6038 str
[i
] = *backupstr
;
6046 skip_past_comma (&backupstr
);
6047 cur_proc_ptr
->frame_offset
= val
;
6048 cur_proc_ptr
->pc_reg
= reg_required_here ((&backupstr
), 0, REG_TYPE_SCORE
);
6051 skip_past_comma (&backupstr
);
6053 while (*backupstr
!= '\n')
6055 str
[i
] = *backupstr
;
6061 cur_proc_ptr
->leaf
= val
;
6063 skip_past_comma (&backupstr
);
6065 #endif /* OBJ_ELF */
6066 while (input_line_pointer
!= backupstr
)
6067 input_line_pointer
++;
6070 /* The .end directive. */
6072 s_score_end (int x ATTRIBUTE_UNUSED
)
6077 /* Generate a .pdr section. */
6078 segT saved_seg
= now_seg
;
6079 subsegT saved_subseg
= now_subseg
;
6084 if (!is_end_of_line
[(unsigned char)*input_line_pointer
])
6087 demand_empty_rest_of_line ();
6092 #ifdef BFD_ASSEMBLER
6093 if ((bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
) != 0)
6098 if (now_seg
!= data_section
&& now_seg
!= bss_section
)
6105 as_warn (_(".end not in text section"));
6108 as_warn (_(".end directive without a preceding .ent directive."));
6109 demand_empty_rest_of_line ();
6114 assert (S_GET_NAME (p
));
6115 if (strcmp (S_GET_NAME (p
), S_GET_NAME (cur_proc_ptr
->isym
)))
6116 as_warn (_(".end symbol does not match .ent symbol."));
6117 if (debug_type
== DEBUG_STABS
)
6118 stabs_generate_asm_endfunc (S_GET_NAME (p
), S_GET_NAME (p
));
6121 as_warn (_(".end directive missing or unknown symbol"));
6123 if ((cur_proc_ptr
->reg_mask
== 0xdeadbeaf) ||
6124 (cur_proc_ptr
->reg_offset
== 0xdeadbeaf) ||
6125 (cur_proc_ptr
->leaf
== 0xdeafbeaf) ||
6126 (cur_proc_ptr
->frame_offset
== 0xdeafbeaf) ||
6127 (cur_proc_ptr
->frame_reg
== 0xdeafbeaf) || (cur_proc_ptr
->pc_reg
== 0xdeafbeaf));
6131 dot
= frag_now_fix ();
6133 subseg_set (pdr_seg
, 0);
6134 /* Write the symbol. */
6135 exp
.X_op
= O_symbol
;
6136 exp
.X_add_symbol
= p
;
6137 exp
.X_add_number
= 0;
6138 emit_expr (&exp
, 4);
6139 fragp
= frag_more (7 * 4);
6140 md_number_to_chars (fragp
, (valueT
) cur_proc_ptr
->reg_mask
, 4);
6141 md_number_to_chars (fragp
+ 4, (valueT
) cur_proc_ptr
->reg_offset
, 4);
6142 md_number_to_chars (fragp
+ 8, (valueT
) cur_proc_ptr
->fpreg_mask
, 4);
6143 md_number_to_chars (fragp
+ 12, (valueT
) cur_proc_ptr
->leaf
, 4);
6144 md_number_to_chars (fragp
+ 16, (valueT
) cur_proc_ptr
->frame_offset
, 4);
6145 md_number_to_chars (fragp
+ 20, (valueT
) cur_proc_ptr
->frame_reg
, 4);
6146 md_number_to_chars (fragp
+ 24, (valueT
) cur_proc_ptr
->pc_reg
, 4);
6147 subseg_set (saved_seg
, saved_subseg
);
6150 cur_proc_ptr
= NULL
;
6153 /* Handle the .set pseudo-op. */
6155 s_score_set (int x ATTRIBUTE_UNUSED
)
6158 char name
[MAX_LITERAL_POOL_SIZE
];
6159 char * orig_ilp
= input_line_pointer
;
6161 while (!is_end_of_line
[(unsigned char)*input_line_pointer
])
6163 name
[i
] = (char) * input_line_pointer
;
6165 ++input_line_pointer
;
6170 if (strcmp (name
, "nwarn") == 0)
6172 warn_fix_data_dependency
= 0;
6174 else if (strcmp (name
, "fixdd") == 0)
6176 fix_data_dependency
= 1;
6178 else if (strcmp (name
, "nofixdd") == 0)
6180 fix_data_dependency
= 0;
6182 else if (strcmp (name
, "r1") == 0)
6186 else if (strcmp (name
, "nor1") == 0)
6190 else if (strcmp (name
, "optimize") == 0)
6194 else if (strcmp (name
, "volatile") == 0)
6198 else if (strcmp (name
, "pic") == 0)
6204 input_line_pointer
= orig_ilp
;
6209 /* Handle the .cpload pseudo-op. This is used when generating PIC code. It sets the
6210 $gp register for the function based on the function address, which is in the register
6211 named in the argument. This uses a relocation against GP_DISP_LABEL, which is handled
6212 specially by the linker. The result is:
6213 ldis gp, %hi(GP_DISP_LABEL)
6214 ori gp, %low(GP_DISP_LABEL)
6215 add gp, gp, .cpload argument
6216 The .cpload argument is normally r29. */
6219 s_score_cpload (int ignore ATTRIBUTE_UNUSED
)
6222 char insn_str
[MAX_LITERAL_POOL_SIZE
];
6224 /* If we are not generating PIC code, .cpload is ignored. */
6225 if (score_pic
== NO_PIC
)
6231 if ((reg
= reg_required_here (&input_line_pointer
, -1, REG_TYPE_SCORE
)) == (int) FAIL
)
6234 demand_empty_rest_of_line ();
6236 sprintf (insn_str
, "ld_i32hi r%d, %s", GP
, GP_DISP_LABEL
);
6237 if (append_insn (insn_str
, TRUE
) == (int) FAIL
)
6240 sprintf (insn_str
, "ld_i32lo r%d, %s", GP
, GP_DISP_LABEL
);
6241 if (append_insn (insn_str
, TRUE
) == (int) FAIL
)
6244 sprintf (insn_str
, "add r%d, r%d, r%d", GP
, GP
, reg
);
6245 if (append_insn (insn_str
, TRUE
) == (int) FAIL
)
6249 /* Handle the .cprestore pseudo-op. This stores $gp into a given
6250 offset from $sp. The offset is remembered, and after making a PIC
6251 call $gp is restored from that location. */
6254 s_score_cprestore (int ignore ATTRIBUTE_UNUSED
)
6257 int cprestore_offset
;
6258 char insn_str
[MAX_LITERAL_POOL_SIZE
];
6260 /* If we are not generating PIC code, .cprestore is ignored. */
6261 if (score_pic
== NO_PIC
)
6267 if ((reg
= reg_required_here (&input_line_pointer
, -1, REG_TYPE_SCORE
)) == (int) FAIL
6268 || skip_past_comma (&input_line_pointer
) == (int) FAIL
)
6273 cprestore_offset
= get_absolute_expression ();
6275 if (cprestore_offset
<= 0x3fff)
6277 sprintf (insn_str
, "sw r%d, [r%d, %d]", GP
, reg
, cprestore_offset
);
6278 if (append_insn (insn_str
, TRUE
) == (int) FAIL
)
6288 sprintf (insn_str
, "li r1, %d", cprestore_offset
);
6289 if (append_insn (insn_str
, TRUE
) == (int) FAIL
)
6292 sprintf (insn_str
, "add r1, r1, r%d", reg
);
6293 if (append_insn (insn_str
, TRUE
) == (int) FAIL
)
6296 sprintf (insn_str
, "sw r%d, [r1]", GP
);
6297 if (append_insn (insn_str
, TRUE
) == (int) FAIL
)
6303 demand_empty_rest_of_line ();
6306 /* Handle the .gpword pseudo-op. This is used when generating PIC
6307 code. It generates a 32 bit GP relative reloc. */
6309 s_score_gpword (int ignore ATTRIBUTE_UNUSED
)
6314 /* When not generating PIC code, this is treated as .word. */
6315 if (score_pic
== NO_PIC
)
6321 if (ex
.X_op
!= O_symbol
|| ex
.X_add_number
!= 0)
6323 as_bad (_("Unsupported use of .gpword"));
6324 ignore_rest_of_line ();
6327 md_number_to_chars (p
, (valueT
) 0, 4);
6328 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 4, &ex
, FALSE
, BFD_RELOC_GPREL32
);
6329 demand_empty_rest_of_line ();
6332 /* Handle the .cpadd pseudo-op. This is used when dealing with switch
6333 tables in PIC code. */
6336 s_score_cpadd (int ignore ATTRIBUTE_UNUSED
)
6339 char insn_str
[MAX_LITERAL_POOL_SIZE
];
6341 /* If we are not generating PIC code, .cpload is ignored. */
6342 if (score_pic
== NO_PIC
)
6348 if ((reg
= reg_required_here (&input_line_pointer
, -1, REG_TYPE_SCORE
)) == (int) FAIL
)
6352 demand_empty_rest_of_line ();
6354 /* Add $gp to the register named as an argument. */
6355 sprintf (insn_str
, "add r%d, r%d, r%d", reg
, reg
, GP
);
6356 if (append_insn (insn_str
, TRUE
) == (int) FAIL
)
6360 #ifndef TC_IMPLICIT_LCOMM_ALIGNMENT
6361 #define TC_IMPLICIT_LCOMM_ALIGNMENT(SIZE, P2VAR) \
6366 else if ((SIZE) >= 4) \
6368 else if ((SIZE) >= 2) \
6377 s_score_lcomm (int bytes_p
)
6384 segT current_seg
= now_seg
;
6385 subsegT current_subseg
= now_subseg
;
6386 const int max_alignment
= 15;
6388 segT bss_seg
= bss_section
;
6389 int needs_align
= 0;
6391 name
= input_line_pointer
;
6392 c
= get_symbol_end ();
6393 p
= input_line_pointer
;
6398 as_bad (_("expected symbol name"));
6399 discard_rest_of_line ();
6405 /* Accept an optional comma after the name. The comma used to be
6406 required, but Irix 5 cc does not generate it. */
6407 if (*input_line_pointer
== ',')
6409 ++input_line_pointer
;
6413 if (is_end_of_line
[(unsigned char)*input_line_pointer
])
6415 as_bad (_("missing size expression"));
6419 if ((temp
= get_absolute_expression ()) < 0)
6421 as_warn (_("BSS length (%d) < 0 ignored"), temp
);
6422 ignore_rest_of_line ();
6426 #if defined (TC_SCORE)
6427 if (OUTPUT_FLAVOR
== bfd_target_ecoff_flavour
|| OUTPUT_FLAVOR
== bfd_target_elf_flavour
)
6429 /* For Score and Alpha ECOFF or ELF, small objects are put in .sbss. */
6430 if ((unsigned)temp
<= bfd_get_gp_size (stdoutput
))
6432 bss_seg
= subseg_new (".sbss", 1);
6433 seg_info (bss_seg
)->bss
= 1;
6434 #ifdef BFD_ASSEMBLER
6435 if (!bfd_set_section_flags (stdoutput
, bss_seg
, SEC_ALLOC
))
6436 as_warn (_("error setting flags for \".sbss\": %s"), bfd_errmsg (bfd_get_error ()));
6443 if (*input_line_pointer
== ',')
6445 ++input_line_pointer
;
6448 if (is_end_of_line
[(unsigned char)*input_line_pointer
])
6450 as_bad (_("missing alignment"));
6455 align
= get_absolute_expression ();
6462 TC_IMPLICIT_LCOMM_ALIGNMENT (temp
, align
);
6464 /* Still zero unless TC_IMPLICIT_LCOMM_ALIGNMENT set it. */
6466 record_alignment (bss_seg
, align
);
6473 /* Convert to a power of 2. */
6478 for (i
= 0; align
!= 0; align
>>= 1, ++i
)
6484 if (align
> max_alignment
)
6486 align
= max_alignment
;
6487 as_warn (_("alignment too large; %d assumed"), align
);
6492 as_warn (_("alignment negative; 0 assumed"));
6495 record_alignment (bss_seg
, align
);
6499 /* Assume some objects may require alignment on some systems. */
6500 #if defined (TC_ALPHA) && ! defined (VMS)
6503 align
= ffs (temp
) - 1;
6504 if (temp
% (1 << align
))
6511 symbolP
= symbol_find_or_make (name
);
6515 #if (defined (OBJ_AOUT) || defined (OBJ_MAYBE_AOUT) \
6516 || defined (OBJ_BOUT) || defined (OBJ_MAYBE_BOUT))
6517 #ifdef BFD_ASSEMBLER
6518 (OUTPUT_FLAVOR
!= bfd_target_aout_flavour
6519 || (S_GET_OTHER (symbolP
) == 0 && S_GET_DESC (symbolP
) == 0)) &&
6521 (S_GET_OTHER (symbolP
) == 0 && S_GET_DESC (symbolP
) == 0) &&
6524 (S_GET_SEGMENT (symbolP
) == bss_seg
|| (!S_IS_DEFINED (symbolP
) && S_GET_VALUE (symbolP
) == 0)))
6528 subseg_set (bss_seg
, 1);
6531 frag_align (align
, 0, 0);
6533 /* Detach from old frag. */
6534 if (S_GET_SEGMENT (symbolP
) == bss_seg
)
6535 symbol_get_frag (symbolP
)->fr_symbol
= NULL
;
6537 symbol_set_frag (symbolP
, frag_now
);
6538 pfrag
= frag_var (rs_org
, 1, 1, (relax_substateT
) 0, symbolP
, (offsetT
) temp
, NULL
);
6542 S_SET_SEGMENT (symbolP
, bss_seg
);
6545 /* The symbol may already have been created with a preceding
6546 ".globl" directive -- be careful not to step on storage class
6547 in that case. Otherwise, set it to static. */
6548 if (S_GET_STORAGE_CLASS (symbolP
) != C_EXT
)
6550 S_SET_STORAGE_CLASS (symbolP
, C_STAT
);
6552 #endif /* OBJ_COFF */
6555 S_SET_SIZE (symbolP
, temp
);
6559 as_bad (_("symbol `%s' is already defined"), S_GET_NAME (symbolP
));
6561 subseg_set (current_seg
, current_subseg
);
6563 demand_empty_rest_of_line ();
6567 insert_reg (const struct reg_entry
*r
, struct hash_control
*htab
)
6570 int len
= strlen (r
->name
) + 2;
6571 char *buf
= xmalloc (len
);
6572 char *buf2
= xmalloc (len
);
6574 strcpy (buf
+ i
, r
->name
);
6575 for (i
= 0; buf
[i
]; i
++)
6577 buf2
[i
] = TOUPPER (buf
[i
]);
6581 hash_insert (htab
, buf
, (void *) r
);
6582 hash_insert (htab
, buf2
, (void *) r
);
6586 build_reg_hsh (struct reg_map
*map
)
6588 const struct reg_entry
*r
;
6590 if ((map
->htab
= hash_new ()) == NULL
)
6592 as_fatal (_("virtual memory exhausted"));
6594 for (r
= map
->names
; r
->name
!= NULL
; r
++)
6596 insert_reg (r
, map
->htab
);
6607 if ((score_ops_hsh
= hash_new ()) == NULL
)
6608 as_fatal (_("virtual memory exhausted"));
6610 build_score_ops_hsh ();
6612 if ((dependency_insn_hsh
= hash_new ()) == NULL
)
6613 as_fatal (_("virtual memory exhausted"));
6615 build_dependency_insn_hsh ();
6617 for (i
= (int)REG_TYPE_FIRST
; i
< (int)REG_TYPE_MAX
; i
++)
6618 build_reg_hsh (all_reg_maps
+ i
);
6620 /* Initialize dependency vector. */
6621 init_dependency_vector ();
6623 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
, 0);
6625 subseg
= now_subseg
;
6626 pdr_seg
= subseg_new (".pdr", (subsegT
) 0);
6627 (void)bfd_set_section_flags (stdoutput
, pdr_seg
, SEC_READONLY
| SEC_RELOC
| SEC_DEBUGGING
);
6628 (void)bfd_set_section_alignment (stdoutput
, pdr_seg
, 2);
6629 subseg_set (seg
, subseg
);
6631 if (USE_GLOBAL_POINTER_OPT
)
6632 bfd_set_gp_size (stdoutput
, g_switch_value
);
6636 const pseudo_typeS md_pseudo_table
[] =
6638 {"bss", s_score_bss
, 0},
6639 {"text", s_score_text
, 0},
6642 {"extend", float_cons
, 'x'},
6643 {"ldouble", float_cons
, 'x'},
6644 {"packed", float_cons
, 'p'},
6645 {"end", s_score_end
, 0},
6646 {"ent", s_score_ent
, 0},
6647 {"frame", s_score_frame
, 0},
6648 {"rdata", s_change_sec
, 'r'},
6649 {"sdata", s_change_sec
, 's'},
6650 {"set", s_score_set
, 0},
6651 {"mask", s_score_mask
, 'R'},
6653 {"lcomm", s_score_lcomm
, 1},
6654 {"section", score_s_section
, 0},
6655 {"cpload", s_score_cpload
, 0},
6656 {"cprestore", s_score_cprestore
, 0},
6657 {"gpword", s_score_gpword
, 0},
6658 {"cpadd", s_score_cpadd
, 0},