1 /* tc-score.c -- Assembler for Score
2 Copyright 2006 Free Software Foundation, Inc.
4 Mei Ligang (ligang@sunnorth.com.cn)
5 Pei-Lin Tsai (pltsai@sunplus.com)
7 This file is part of GAS, the GNU Assembler.
9 GAS is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2, or (at your option)
14 GAS is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with GAS; see the file COPYING. If not, write to the Free
21 Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
27 #include "safe-ctype.h"
28 #include "opcode/score-inst.h"
29 #include "opcode/score-datadep.h"
30 #include "struc-symbol.h"
33 #include "elf/score.h"
34 #include "dwarf2dbg.h"
38 #define PIC_CALL_REG 29
39 #define MAX_LITERAL_POOL_SIZE 1024
40 #define FAIL 0x80000000
44 #define RELAX_INST_NUM 3
46 /* For score5u : div/mul will pop warning message, mmu/alw/asw will pop error message. */
47 #define BAD_ARGS _("bad arguments to instruction")
48 #define BAD_PC _("r15 not allowed here")
49 #define BAD_COND _("instruction is not conditional")
50 #define ERR_NO_ACCUM _("acc0 expected")
51 #define ERR_FOR_SCORE5U_MUL_DIV _("div / mul are reserved instructions")
52 #define ERR_FOR_SCORE5U_MMU _("This architecture doesn't support mmu")
53 #define ERR_FOR_SCORE5U_ATOMIC _("This architecture doesn't support atomic instruction")
54 #define LONG_LABEL_LEN _("the label length is longer than 1024");
55 #define BAD_SKIP_COMMA BAD_ARGS
56 #define BAD_GARBAGE _("garbage following instruction");
58 #define skip_whitespace(str) while (*(str) == ' ') ++(str)
60 /* The name of the readonly data section. */
61 #define RDATA_SECTION_NAME (OUTPUT_FLAVOR == bfd_target_aout_flavour \
63 : OUTPUT_FLAVOR == bfd_target_ecoff_flavour \
65 : OUTPUT_FLAVOR == bfd_target_coff_flavour \
67 : OUTPUT_FLAVOR == bfd_target_elf_flavour \
71 #define RELAX_ENCODE(old, new, type, reloc1, reloc2, opt) \
80 #define RELAX_OLD(i) (((i) >> 23) & 0x7f)
81 #define RELAX_NEW(i) (((i) >> 16) & 0x7f)
82 #define RELAX_TYPE(i) (((i) >> 9) & 0x7f)
83 #define RELAX_RELOC1(i) ((valueT) ((i) >> 5) & 0xf)
84 #define RELAX_RELOC2(i) ((valueT) ((i) >> 1) & 0xf)
85 #define RELAX_OPT(i) ((i) & 1)
86 #define RELAX_OPT_CLEAR(i) ((i) & ~1)
88 #define SET_INSN_ERROR(s) (inst.error = (s))
89 #define INSN_IS_PCE_P(s) (strstr (str, "||") != NULL)
91 #define GET_INSN_CLASS(type) (get_insn_class_from_type (type))
93 #define GET_INSN_SIZE(type) ((GET_INSN_CLASS (type) == INSN_CLASS_16) \
94 ? INSN16_SIZE : INSN_SIZE)
96 /* This array holds the chars that always start a comment. If the
97 pre-processor is disabled, these aren't very useful. */
98 const char comment_chars
[] = "#";
99 const char line_comment_chars
[] = "#";
100 const char line_separator_chars
[] = ";";
102 /* Chars that can be used to separate mant from exp in floating point numbers. */
103 const char EXP_CHARS
[] = "eE";
104 const char FLT_CHARS
[] = "rRsSfFdDxXeEpP";
106 fragS
*score_fragp
= 0;
107 static int fix_data_dependency
= 0;
108 static int warn_fix_data_dependency
= 1;
109 static int score7
= 1;
110 static int university_version
= 0;
112 static int in_my_get_expression
= 0;
114 #define USE_GLOBAL_POINTER_OPT 1
115 #define SCORE_BI_ENDIAN
117 /* Default, pop warning message when using r1. */
120 /* Default will do instruction relax, -O0 will set g_opt = 0. */
121 static unsigned int g_opt
= 1;
123 /* The size of the small data section. */
124 static unsigned int g_switch_value
= 8;
127 /* Pre-defined "_GLOBAL_OFFSET_TABLE_" */
132 enum score_pic_level score_pic
= NO_PIC
;
134 #define INSN_NAME_LEN 16
137 char name
[INSN_NAME_LEN
];
138 unsigned long instruction
;
139 unsigned long relax_inst
;
142 enum score_insn_type type
;
143 char str
[MAX_LITERAL_POOL_SIZE
];
146 char reg
[INSN_NAME_LEN
];
149 bfd_reloc_code_real_type type
;
154 struct score_it inst
;
159 unsigned long reg_mask
;
160 unsigned long reg_offset
;
161 unsigned long fpreg_mask
;
163 unsigned long frame_offset
;
164 unsigned long frame_reg
;
165 unsigned long pc_reg
;
169 static procS cur_proc
;
170 static procS
*cur_proc_ptr
;
173 #define SCORE7_PIPELINE 7
174 #define SCORE5_PIPELINE 5
175 static int vector_size
= SCORE7_PIPELINE
;
176 struct score_it dependency_vector
[SCORE7_PIPELINE
];
178 /* Relax will need some padding for alignment. */
179 #define RELAX_PAD_BYTE 3
181 /* Number of littlenums required to hold an extended precision number. For md_atof. */
182 #define NUM_FLOAT_VALS 8
183 #define MAX_LITTLENUMS 6
184 LITTLENUM_TYPE fp_values
[NUM_FLOAT_VALS
][MAX_LITTLENUMS
];
186 /* Structure for a hash table entry for a register. */
193 static const struct reg_entry score_rn_table
[] =
195 {"r0", 0}, {"r1", 1}, {"r2", 2}, {"r3", 3},
196 {"r4", 4}, {"r5", 5}, {"r6", 6}, {"r7", 7},
197 {"r8", 8}, {"r9", 9}, {"r10", 10}, {"r11", 11},
198 {"r12", 12}, {"r13", 13}, {"r14", 14}, {"r15", 15},
199 {"r16", 16}, {"r17", 17}, {"r18", 18}, {"r19", 19},
200 {"r20", 20}, {"r21", 21}, {"r22", 22}, {"r23", 23},
201 {"r24", 24}, {"r25", 25}, {"r26", 26}, {"r27", 27},
202 {"r28", 28}, {"r29", 29}, {"r30", 30}, {"r31", 31},
206 static const struct reg_entry score_srn_table
[] =
208 {"sr0", 0}, {"sr1", 1}, {"sr2", 2},
212 static const struct reg_entry score_crn_table
[] =
214 {"cr0", 0}, {"cr1", 1}, {"cr2", 2}, {"cr3", 3},
215 {"cr4", 4}, {"cr5", 5}, {"cr6", 6}, {"cr7", 7},
216 {"cr8", 8}, {"cr9", 9}, {"cr10", 10}, {"cr11", 11},
217 {"cr12", 12}, {"cr13", 13}, {"cr14", 14}, {"cr15", 15},
218 {"cr16", 16}, {"cr17", 17}, {"cr18", 18}, {"cr19", 19},
219 {"cr20", 20}, {"cr21", 21}, {"cr22", 22}, {"cr23", 23},
220 {"cr24", 24}, {"cr25", 25}, {"cr26", 26}, {"cr27", 27},
221 {"cr28", 28}, {"cr29", 29}, {"cr30", 30}, {"cr31", 31},
227 const struct reg_entry
*names
;
229 struct hash_control
*htab
;
230 const char *expected
;
233 struct reg_map all_reg_maps
[] =
235 {score_rn_table
, 31, NULL
, N_("S+core register expected")},
236 {score_srn_table
, 2, NULL
, N_("S+core special-register expected")},
237 {score_crn_table
, 31, NULL
, N_("S+core co-processor register expected")},
240 static struct hash_control
*score_ops_hsh
= NULL
;
242 static struct hash_control
*dependency_insn_hsh
= NULL
;
244 /* Enumeration matching entries in table above. */
248 #define REG_TYPE_FIRST REG_TYPE_SCORE
249 REG_TYPE_SCORE_SR
= 1,
250 REG_TYPE_SCORE_CR
= 2,
254 typedef struct literalS
256 struct expressionS exp
;
257 struct score_it
*inst
;
261 literalT literals
[MAX_LITERAL_POOL_SIZE
];
263 static void do_ldst_insn (char *);
264 static void do_crdcrscrsimm5 (char *);
265 static void do_ldst_unalign (char *);
266 static void do_ldst_atomic (char *);
267 static void do_ldst_cop (char *);
268 static void do_macro_li_rdi32 (char *);
269 static void do_macro_la_rdi32 (char *);
270 static void do_macro_rdi32hi (char *);
271 static void do_macro_rdi32lo (char *);
272 static void do_macro_mul_rdrsrs (char *);
273 static void do_macro_ldst_label (char *);
274 static void do_branch (char *);
275 static void do_jump (char *);
276 static void do_empty (char *);
277 static void do_rdrsrs (char *);
278 static void do_rdsi16 (char *);
279 static void do_rdrssi14 (char *);
280 static void do_sub_rdsi16 (char *);
281 static void do_sub_rdi16 (char *);
282 static void do_sub_rdrssi14 (char *);
283 static void do_rdrsi5 (char *);
284 static void do_rdrsi14 (char *);
285 static void do_rdi16 (char *);
286 static void do_xrsi5 (char *);
287 static void do_rdrs (char *);
288 static void do_rdxrs (char *);
289 static void do_rsrs (char *);
290 static void do_rdcrs (char *);
291 static void do_rdsrs (char *);
292 static void do_rd (char *);
293 static void do_rs (char *);
294 static void do_i15 (char *);
295 static void do_xi5x (char *);
296 static void do_ceinst (char *);
297 static void do_cache (char *);
298 static void do16_rdrs (char *);
299 static void do16_rs (char *);
300 static void do16_xrs (char *);
301 static void do16_mv_rdrs (char *);
302 static void do16_hrdrs (char *);
303 static void do16_rdhrs (char *);
304 static void do16_rdi4 (char *);
305 static void do16_rdi5 (char *);
306 static void do16_xi5 (char *);
307 static void do16_ldst_insn (char *);
308 static void do16_ldst_imm_insn (char *);
309 static void do16_push_pop (char *);
310 static void do16_branch (char *);
311 static void do16_jump (char *);
312 static void do_rdi16_pic (char *);
313 static void do_addi_s_pic (char *);
314 static void do_addi_u_pic (char *);
315 static void do_lw_pic (char *);
317 static const struct asm_opcode score_ldst_insns
[] =
319 {"lw", 0x20000000, 0x3e000000, 0x2008, Rd_rvalueRs_SI15
, do_ldst_insn
},
320 {"lw", 0x06000000, 0x3e000007, 0x8000, Rd_rvalueRs_preSI12
, do_ldst_insn
},
321 {"lw", 0x0e000000, 0x3e000007, 0x200a, Rd_rvalueRs_postSI12
, do_ldst_insn
},
322 {"lh", 0x22000000, 0x3e000000, 0x2009, Rd_rvalueRs_SI15
, do_ldst_insn
},
323 {"lh", 0x06000001, 0x3e000007, 0x8000, Rd_rvalueRs_preSI12
, do_ldst_insn
},
324 {"lh", 0x0e000001, 0x3e000007, 0x8000, Rd_rvalueRs_postSI12
, do_ldst_insn
},
325 {"lhu", 0x24000000, 0x3e000000, 0x8000, Rd_rvalueRs_SI15
, do_ldst_insn
},
326 {"lhu", 0x06000002, 0x3e000007, 0x8000, Rd_rvalueRs_preSI12
, do_ldst_insn
},
327 {"lhu", 0x0e000002, 0x3e000007, 0x8000, Rd_rvalueRs_postSI12
, do_ldst_insn
},
328 {"lb", 0x26000000, 0x3e000000, 0x8000, Rd_rvalueRs_SI15
, do_ldst_insn
},
329 {"lb", 0x06000003, 0x3e000007, 0x8000, Rd_rvalueRs_preSI12
, do_ldst_insn
},
330 {"lb", 0x0e000003, 0x3e000007, 0x8000, Rd_rvalueRs_postSI12
, do_ldst_insn
},
331 {"sw", 0x28000000, 0x3e000000, 0x200c, Rd_lvalueRs_SI15
, do_ldst_insn
},
332 {"sw", 0x06000004, 0x3e000007, 0x200e, Rd_lvalueRs_preSI12
, do_ldst_insn
},
333 {"sw", 0x0e000004, 0x3e000007, 0x8000, Rd_lvalueRs_postSI12
, do_ldst_insn
},
334 {"sh", 0x2a000000, 0x3e000000, 0x200d, Rd_lvalueRs_SI15
, do_ldst_insn
},
335 {"sh", 0x06000005, 0x3e000007, 0x8000, Rd_lvalueRs_preSI12
, do_ldst_insn
},
336 {"sh", 0x0e000005, 0x3e000007, 0x8000, Rd_lvalueRs_postSI12
, do_ldst_insn
},
337 {"lbu", 0x2c000000, 0x3e000000, 0x200b, Rd_rvalueRs_SI15
, do_ldst_insn
},
338 {"lbu", 0x06000006, 0x3e000007, 0x8000, Rd_rvalueRs_preSI12
, do_ldst_insn
},
339 {"lbu", 0x0e000006, 0x3e000007, 0x8000, Rd_rvalueRs_postSI12
, do_ldst_insn
},
340 {"sb", 0x2e000000, 0x3e000000, 0x200f, Rd_lvalueRs_SI15
, do_ldst_insn
},
341 {"sb", 0x06000007, 0x3e000007, 0x8000, Rd_lvalueRs_preSI12
, do_ldst_insn
},
342 {"sb", 0x0e000007, 0x3e000007, 0x8000, Rd_lvalueRs_postSI12
, do_ldst_insn
},
345 static const struct asm_opcode score_insns
[] =
347 {"abs", 0x3800000a, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
348 {"abs.s", 0x3800004b, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
349 {"add", 0x00000010, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
350 {"add.c", 0x00000011, 0x3e0003ff, 0x2000, Rd_Rs_Rs
, do_rdrsrs
},
351 {"add.s", 0x38000048, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
352 {"addc", 0x00000012, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
353 {"addc.c", 0x00000013, 0x3e0003ff, 0x0009, Rd_Rs_Rs
, do_rdrsrs
},
354 {"addi", 0x02000000, 0x3e0e0001, 0x8000, Rd_SI16
, do_rdsi16
},
355 {"addi.c", 0x02000001, 0x3e0e0001, 0x8000, Rd_SI16
, do_rdsi16
},
356 {"addis", 0x0a000000, 0x3e0e0001, 0x8000, Rd_SI16
, do_rdi16
},
357 {"addis.c", 0x0a000001, 0x3e0e0001, 0x8000, Rd_SI16
, do_rdi16
},
358 {"addri", 0x10000000, 0x3e000001, 0x8000, Rd_Rs_SI14
, do_rdrssi14
},
359 {"addri.c", 0x10000001, 0x3e000001, 0x8000, Rd_Rs_SI14
, do_rdrssi14
},
360 {"addc!", 0x0009, 0x700f, 0x00000013, Rd_Rs
, do16_rdrs
},
361 {"add!", 0x2000, 0x700f, 0x00000011, Rd_Rs
, do16_rdrs
},
362 {"addei!", 0x6000 , 0x7087, 0x02000001, Rd_I4
, do16_rdi4
},
363 {"subi", 0x02000000, 0x3e0e0001, 0x8000, Rd_SI16
, do_sub_rdsi16
},
364 {"subi.c", 0x02000001, 0x3e0e0001, 0x8000, Rd_SI16
, do_sub_rdsi16
},
365 {"subis", 0x0a000000, 0x3e0e0001, 0x8000, Rd_SI16
, do_sub_rdi16
},
366 {"subis.c", 0x0a000001, 0x3e0e0001, 0x8000, Rd_SI16
, do_sub_rdi16
},
367 {"subri", 0x10000000, 0x3e000001, 0x8000, Rd_Rs_SI14
, do_sub_rdrssi14
},
368 {"subri.c", 0x10000001, 0x3e000001, 0x8000, Rd_Rs_SI14
, do_sub_rdrssi14
},
369 {"and", 0x00000020, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
370 {"and.c", 0x00000021, 0x3e0003ff, 0x2004, Rd_Rs_Rs
, do_rdrsrs
},
371 {"andi", 0x02080000, 0x3e0e0001, 0x8000, Rd_I16
, do_rdi16
},
372 {"andi.c", 0x02080001, 0x3e0e0001, 0x8000, Rd_I16
, do_rdi16
},
373 {"andis", 0x0a080000, 0x3e0e0001, 0x8000, Rd_I16
, do_rdi16
},
374 {"andis.c", 0x0a080001, 0x3e0e0001, 0x8000, Rd_I16
, do_rdi16
},
375 {"andri", 0x18000000, 0x3e000001, 0x8000, Rd_Rs_I14
, do_rdrsi14
},
376 {"andri.c", 0x18000001, 0x3e000001, 0x8000, Rd_Rs_I14
, do_rdrsi14
},
377 {"and!", 0x2004, 0x700f, 0x00000021, Rd_Rs
, do16_rdrs
},
378 {"bcs", 0x08000000, 0x3e007c01, 0x4000, PC_DISP19div2
, do_branch
},
379 {"bcc", 0x08000400, 0x3e007c01, 0x4000, PC_DISP19div2
, do_branch
},
380 {"bcnz", 0x08003800, 0x3e007c01, 0x4000, PC_DISP19div2
, do_branch
},
381 {"bcsl", 0x08000001, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
382 {"bccl", 0x08000401, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
383 {"bcnzl", 0x08003801, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
384 {"bcs!", 0x4000, 0x7f00, 0x08000000, PC_DISP8div2
, do16_branch
},
385 {"bcc!", 0x4100, 0x7f00, 0x08000400, PC_DISP8div2
, do16_branch
},
386 {"bcnz!", 0x4e00, 0x7f00, 0x08003800, PC_DISP8div2
, do16_branch
},
387 {"beq", 0x08001000, 0x3e007c01, 0x4000, PC_DISP19div2
, do_branch
},
388 {"beql", 0x08001001, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
389 {"beq!", 0x4400, 0x7f00, 0x08001000, PC_DISP8div2
, do16_branch
},
390 {"bgtu", 0x08000800, 0x3e007c01, 0x4000, PC_DISP19div2
, do_branch
},
391 {"bgt", 0x08001800, 0x3e007c01, 0x4000, PC_DISP19div2
, do_branch
},
392 {"bge", 0x08002000, 0x3e007c01, 0x4000, PC_DISP19div2
, do_branch
},
393 {"bgtul", 0x08000801, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
394 {"bgtl", 0x08001801, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
395 {"bgel", 0x08002001, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
396 {"bgtu!", 0x4200, 0x7f00, 0x08000800, PC_DISP8div2
, do16_branch
},
397 {"bgt!", 0x4600, 0x7f00, 0x08001800, PC_DISP8div2
, do16_branch
},
398 {"bge!", 0x4800, 0x7f00, 0x08002000, PC_DISP8div2
, do16_branch
},
399 {"bitclr.c", 0x00000029, 0x3e0003ff, 0x6004, Rd_Rs_I5
, do_rdrsi5
},
400 {"bitrev", 0x3800000c, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
401 {"bitset.c", 0x0000002b, 0x3e0003ff, 0x6005, Rd_Rs_I5
, do_rdrsi5
},
402 {"bittst.c", 0x0000002d, 0x3e0003ff, 0x6006, x_Rs_I5
, do_xrsi5
},
403 {"bittgl.c", 0x0000002f, 0x3e0003ff, 0x6007, Rd_Rs_I5
, do_rdrsi5
},
404 {"bitclr!", 0x6004, 0x7007, 0x00000029, Rd_I5
, do16_rdi5
},
405 {"bitset!", 0x6005, 0x7007, 0x0000002b, Rd_I5
, do16_rdi5
},
406 {"bittst!", 0x6006, 0x7007, 0x0000002d, Rd_I5
, do16_rdi5
},
407 {"bittgl!", 0x6007, 0x7007, 0x0000002f, Rd_I5
, do16_rdi5
},
408 {"bleu", 0x08000c00, 0x3e007c01, 0x4000, PC_DISP19div2
, do_branch
},
409 {"ble", 0x08001c00, 0x3e007c01, 0x4000, PC_DISP19div2
, do_branch
},
410 {"blt", 0x08002400, 0x3e007c01, 0x4000, PC_DISP19div2
, do_branch
},
411 {"bleul", 0x08000c01, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
412 {"blel", 0x08001c01, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
413 {"bltl", 0x08002401, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
414 {"bl", 0x08003c01, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
415 {"bleu!", 0x4300, 0x7f00, 0x08000c00, PC_DISP8div2
, do16_branch
},
416 {"ble!", 0x4700, 0x7f00, 0x08001c00, PC_DISP8div2
, do16_branch
},
417 {"blt!", 0x4900, 0x7f00, 0x08002400, PC_DISP8div2
, do16_branch
},
418 {"bmi", 0x08002800, 0x3e007c01, 0x4000, PC_DISP19div2
, do_branch
},
419 {"bmil", 0x08002801, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
420 {"bmi!", 0x00004a00, 0x00007f00, 0x08002800, PC_DISP8div2
, do16_branch
},
421 {"bne", 0x08001400, 0x3e007c01, 0x4000, PC_DISP19div2
, do_branch
},
422 {"bnel", 0x08001401, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
423 {"bne!", 0x4500, 0x7f00, 0x08001400, PC_DISP8div2
, do16_branch
},
424 {"bpl", 0x08002c00, 0x3e007c01, 0x4000, PC_DISP19div2
, do_branch
},
425 {"bpll", 0x08002c01, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
426 {"bpl!", 0x4b00, 0x7f00, 0x08002c00, PC_DISP8div2
, do16_branch
},
427 {"brcs", 0x00000008, 0x3e007fff, 0x0004, x_Rs_x
, do_rs
},
428 {"brcc", 0x00000408, 0x3e007fff, 0x0104, x_Rs_x
, do_rs
},
429 {"brgtu", 0x00000808, 0x3e007fff, 0x0204, x_Rs_x
, do_rs
},
430 {"brleu", 0x00000c08, 0x3e007fff, 0x0304, x_Rs_x
, do_rs
},
431 {"breq", 0x00001008, 0x3e007fff, 0x0404, x_Rs_x
, do_rs
},
432 {"brne", 0x00001408, 0x3e007fff, 0x0504, x_Rs_x
, do_rs
},
433 {"brgt", 0x00001808, 0x3e007fff, 0x0604, x_Rs_x
, do_rs
},
434 {"brle", 0x00001c08, 0x3e007fff, 0x0704, x_Rs_x
, do_rs
},
435 {"brge", 0x00002008, 0x3e007fff, 0x0804, x_Rs_x
, do_rs
},
436 {"brlt", 0x00002408, 0x3e007fff, 0x0904, x_Rs_x
, do_rs
},
437 {"brmi", 0x00002808, 0x3e007fff, 0x0a04, x_Rs_x
, do_rs
},
438 {"brpl", 0x00002c08, 0x3e007fff, 0x0b04, x_Rs_x
, do_rs
},
439 {"brvs", 0x00003008, 0x3e007fff, 0x0c04, x_Rs_x
, do_rs
},
440 {"brvc", 0x00003408, 0x3e007fff, 0x0d04, x_Rs_x
, do_rs
},
441 {"brcnz", 0x00003808, 0x3e007fff, 0x0e04, x_Rs_x
, do_rs
},
442 {"br", 0x00003c08, 0x3e007fff, 0x0f04, x_Rs_x
, do_rs
},
443 {"brcsl", 0x00000009, 0x3e007fff, 0x000c, x_Rs_x
, do_rs
},
444 {"brccl", 0x00000409, 0x3e007fff, 0x010c, x_Rs_x
, do_rs
},
445 {"brgtul", 0x00000809, 0x3e007fff, 0x020c, x_Rs_x
, do_rs
},
446 {"brleul", 0x00000c09, 0x3e007fff, 0x030c, x_Rs_x
, do_rs
},
447 {"breql", 0x00001009, 0x3e007fff, 0x040c, x_Rs_x
, do_rs
},
448 {"brnel", 0x00001409, 0x3e007fff, 0x050c, x_Rs_x
, do_rs
},
449 {"brgtl", 0x00001809, 0x3e007fff, 0x060c, x_Rs_x
, do_rs
},
450 {"brlel", 0x00001c09, 0x3e007fff, 0x070c, x_Rs_x
, do_rs
},
451 {"brgel", 0x00002009, 0x3e007fff, 0x080c, x_Rs_x
, do_rs
},
452 {"brltl", 0x00002409, 0x3e007fff, 0x090c, x_Rs_x
, do_rs
},
453 {"brmil", 0x00002809, 0x3e007fff, 0x0a0c, x_Rs_x
, do_rs
},
454 {"brpll", 0x00002c09, 0x3e007fff, 0x0b0c, x_Rs_x
, do_rs
},
455 {"brvsl", 0x00003009, 0x3e007fff, 0x0c0c, x_Rs_x
, do_rs
},
456 {"brvcl", 0x00003409, 0x3e007fff, 0x0d0c, x_Rs_x
, do_rs
},
457 {"brcnzl", 0x00003809, 0x3e007fff, 0x0e0c, x_Rs_x
, do_rs
},
458 {"brl", 0x00003c09, 0x3e007fff, 0x0f0c, x_Rs_x
, do_rs
},
459 {"brcs!", 0x0004, 0x7f0f, 0x00000008, x_Rs
, do16_xrs
},
460 {"brcc!", 0x0104, 0x7f0f, 0x00000408, x_Rs
, do16_xrs
},
461 {"brgtu!", 0x0204, 0x7f0f, 0x00000808, x_Rs
, do16_xrs
},
462 {"brleu!", 0x0304, 0x7f0f, 0x00000c08, x_Rs
, do16_xrs
},
463 {"breq!", 0x0404, 0x7f0f, 0x00001008, x_Rs
, do16_xrs
},
464 {"brne!", 0x0504, 0x7f0f, 0x00001408, x_Rs
, do16_xrs
},
465 {"brgt!", 0x0604, 0x7f0f, 0x00001808, x_Rs
, do16_xrs
},
466 {"brle!", 0x0704, 0x7f0f, 0x00001c08, x_Rs
, do16_xrs
},
467 {"brge!", 0x0804, 0x7f0f, 0x00002008, x_Rs
, do16_xrs
},
468 {"brlt!", 0x0904, 0x7f0f, 0x00002408, x_Rs
, do16_xrs
},
469 {"brmi!", 0x0a04, 0x7f0f, 0x00002808, x_Rs
, do16_xrs
},
470 {"brpl!", 0x0b04, 0x7f0f, 0x00002c08, x_Rs
, do16_xrs
},
471 {"brvs!", 0x0c04, 0x7f0f, 0x00003008, x_Rs
, do16_xrs
},
472 {"brvc!", 0x0d04, 0x7f0f, 0x00003408, x_Rs
, do16_xrs
},
473 {"brcnz!", 0x0e04, 0x7f0f, 0x00003808, x_Rs
, do16_xrs
},
474 {"br!", 0x0f04, 0x7f0f, 0x00003c08, x_Rs
, do16_xrs
},
475 {"brcsl!", 0x000c, 0x7f0f, 0x00000009, x_Rs
, do16_xrs
},
476 {"brccl!", 0x010c, 0x7f0f, 0x00000409, x_Rs
, do16_xrs
},
477 {"brgtul!", 0x020c, 0x7f0f, 0x00000809, x_Rs
, do16_xrs
},
478 {"brleul!", 0x030c, 0x7f0f, 0x00000c09, x_Rs
, do16_xrs
},
479 {"breql!", 0x040c, 0x7f0f, 0x00001009, x_Rs
, do16_xrs
},
480 {"brnel!", 0x050c, 0x7f0f, 0x00001409, x_Rs
, do16_xrs
},
481 {"brgtl!", 0x060c, 0x7f0f, 0x00001809, x_Rs
, do16_xrs
},
482 {"brlel!", 0x070c, 0x7f0f, 0x00001c09, x_Rs
, do16_xrs
},
483 {"brgel!", 0x080c, 0x7f0f, 0x00002009, x_Rs
, do16_xrs
},
484 {"brltl!", 0x090c, 0x7f0f, 0x00002409, x_Rs
, do16_xrs
},
485 {"brmil!", 0x0a0c, 0x7f0f, 0x00002809, x_Rs
, do16_xrs
},
486 {"brpll!", 0x0b0c, 0x7f0f, 0x00002c09, x_Rs
, do16_xrs
},
487 {"brvsl!", 0x0c0c, 0x7f0f, 0x00003009, x_Rs
, do16_xrs
},
488 {"brvcl!", 0x0d0c, 0x7f0f, 0x00003409, x_Rs
, do16_xrs
},
489 {"brcnzl!", 0x0e0c, 0x7f0f, 0x00003809, x_Rs
, do16_xrs
},
490 {"brl!", 0x0f0c, 0x7f0f, 0x00003c09, x_Rs
, do16_xrs
},
491 {"bvs", 0x08003000, 0x3e007c01, 0x4000, PC_DISP19div2
, do_branch
},
492 {"bvc", 0x08003400, 0x3e007c01, 0x4000, PC_DISP19div2
, do_branch
},
493 {"bvsl", 0x08003001, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
494 {"bvcl", 0x08003401, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
495 {"bvs!", 0x4c00, 0x7f00, 0x08003000, PC_DISP8div2
, do16_branch
},
496 {"bvc!", 0x4d00, 0x7f00, 0x08003400, PC_DISP8div2
, do16_branch
},
497 {"b!", 0x4f00, 0x7f00, 0x08003c00, PC_DISP8div2
, do16_branch
},
498 {"b", 0x08003c00, 0x3e007c01, 0x4000, PC_DISP19div2
, do_branch
},
499 {"cache", 0x30000000, 0x3ff00000, 0x8000, OP5_rvalueRs_SI15
, do_cache
},
500 {"ceinst", 0x38000000, 0x3e000000, 0x8000, I5_Rs_Rs_I5_OP5
, do_ceinst
},
501 {"clz", 0x3800000d, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
502 {"cmpteq.c", 0x00000019, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
503 {"cmptmi.c", 0x00100019, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
504 {"cmp.c", 0x00300019, 0x3ff003ff, 0x2003, x_Rs_Rs
, do_rsrs
},
505 {"cmpzteq.c", 0x0000001b, 0x3ff07fff, 0x8000, x_Rs_x
, do_rs
},
506 {"cmpztmi.c", 0x0010001b, 0x3ff07fff, 0x8000, x_Rs_x
, do_rs
},
507 {"cmpz.c", 0x0030001b, 0x3ff07fff, 0x8000, x_Rs_x
, do_rs
},
508 {"cmpi.c", 0x02040001, 0x3e0e0001, 0x8000, Rd_SI16
, do_rdsi16
},
509 {"cmp!", 0x2003, 0x700f, 0x00300019, Rd_Rs
, do16_rdrs
},
510 {"cop1", 0x0c00000c, 0x3e00001f, 0x8000, Rd_Rs_Rs_imm
, do_crdcrscrsimm5
},
511 {"cop2", 0x0c000014, 0x3e00001f, 0x8000, Rd_Rs_Rs_imm
, do_crdcrscrsimm5
},
512 {"cop3", 0x0c00001c, 0x3e00001f, 0x8000, Rd_Rs_Rs_imm
, do_crdcrscrsimm5
},
513 {"drte", 0x0c0000a4, 0x3e0003ff, 0x8000, NO_OPD
, do_empty
},
514 {"extsb", 0x00000058, 0x3e0003ff, 0x8000, Rd_Rs_x
, do_rdrs
},
515 {"extsb.c", 0x00000059, 0x3e0003ff, 0x8000, Rd_Rs_x
, do_rdrs
},
516 {"extsh", 0x0000005a, 0x3e0003ff, 0x8000, Rd_Rs_x
, do_rdrs
},
517 {"extsh.c", 0x0000005b, 0x3e0003ff, 0x8000, Rd_Rs_x
, do_rdrs
},
518 {"extzb", 0x0000005c, 0x3e0003ff, 0x8000, Rd_Rs_x
, do_rdrs
},
519 {"extzb.c", 0x0000005d, 0x3e0003ff, 0x8000, Rd_Rs_x
, do_rdrs
},
520 {"extzh", 0x0000005e, 0x3e0003ff, 0x8000, Rd_Rs_x
, do_rdrs
},
521 {"extzh.c", 0x0000005f, 0x3e0003ff, 0x8000, Rd_Rs_x
, do_rdrs
},
522 {"jl", 0x04000001, 0x3e000001, 0x8000, PC_DISP24div2
, do_jump
},
523 {"jl!", 0x3001, 0x7001, 0x04000001, PC_DISP11div2
, do16_jump
},
524 {"j!", 0x3000, 0x7001, 0x04000000, PC_DISP11div2
, do16_jump
},
525 {"j", 0x04000000, 0x3e000001, 0x8000, PC_DISP24div2
, do_jump
},
526 {"lbu!", 0x200b, 0x0000700f, 0x2c000000, Rd_rvalueRs
, do16_ldst_insn
},
527 {"lbup!", 0x7003, 0x7007, 0x2c000000, Rd_rvalueBP_I5
, do16_ldst_imm_insn
},
528 {"alw", 0x0000000c, 0x3e0003ff, 0x8000, Rd_rvalue32Rs
, do_ldst_atomic
},
529 {"lcb", 0x00000060, 0x3e0003ff, 0x8000, x_rvalueRs_post4
, do_ldst_unalign
},
530 {"lcw", 0x00000062, 0x3e0003ff, 0x8000, Rd_rvalueRs_post4
, do_ldst_unalign
},
531 {"lce", 0x00000066, 0x3e0003ff, 0x8000, Rd_rvalueRs_post4
, do_ldst_unalign
},
532 {"ldc1", 0x0c00000a, 0x3e00001f, 0x8000, Rd_rvalueRs_SI10
, do_ldst_cop
},
533 {"ldc2", 0x0c000012, 0x3e00001f, 0x8000, Rd_rvalueRs_SI10
, do_ldst_cop
},
534 {"ldc3", 0x0c00001a, 0x3e00001f, 0x8000, Rd_rvalueRs_SI10
, do_ldst_cop
},
535 {"lh!", 0x2009, 0x700f, 0x22000000, Rd_rvalueRs
, do16_ldst_insn
},
536 {"lhp!", 0x7001, 0x7007, 0x22000000, Rd_rvalueBP_I5
, do16_ldst_imm_insn
},
537 {"ldi", 0x020c0000, 0x3e0e0000, 0x5000, Rd_SI16
, do_rdsi16
},
538 {"ldis", 0x0a0c0000, 0x3e0e0000, 0x5000, Rd_I16
, do_rdi16
},
539 {"ldiu!", 0x5000, 0x7000, 0x020c0000, Rd_I8
, do16_ldst_imm_insn
},
540 {"lw!", 0x2008, 0x700f, 0x20000000, Rd_rvalueRs
, do16_ldst_insn
},
541 {"lwp!", 0x7000, 0x7007, 0x20000000, Rd_rvalueBP_I5
, do16_ldst_imm_insn
},
542 {"mfcel", 0x00000448, 0x3e007fff, 0x8000, Rd_x_x
, do_rd
},
543 {"mfcel!", 0x1001, 0x7f0f, 0x00000448, x_Rs
, do16_rs
},
544 {"mad", 0x38000000, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
545 {"mad.f!", 0x1004, 0x700f, 0x38000080, Rd_Rs
, do16_rdrs
},
546 {"madh", 0x38000203, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
547 {"madh.fs", 0x380002c3, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
548 {"madh.fs!", 0x100b, 0x700f, 0x380002c3, Rd_Rs
, do16_rdrs
},
549 {"madl", 0x38000002, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
550 {"madl.fs", 0x380000c2, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
551 {"madl.fs!", 0x100a, 0x700f, 0x380000c2, Rd_Rs
, do16_rdrs
},
552 {"madu", 0x38000020, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
553 {"madu!", 0x1005, 0x700f, 0x38000020, Rd_Rs
, do16_rdrs
},
554 {"mad.f", 0x38000080, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
555 {"max", 0x38000007, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
556 {"mazh", 0x38000303, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
557 {"mazh.f", 0x38000383, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
558 {"mazh.f!", 0x1009, 0x700f, 0x3800038c, Rd_Rs
, do16_rdrs
},
559 {"mazl", 0x38000102, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
560 {"mazl.f", 0x38000182, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
561 {"mazl.f!", 0x1008, 0x700f, 0x38000182, Rd_Rs
, do16_rdrs
},
562 {"mfceh", 0x00000848, 0x3e007fff, 0x8000, Rd_x_x
, do_rd
},
563 {"mfceh!", 0x1101, 0x7f0f, 0x00000848, x_Rs
, do16_rs
},
564 {"mfcehl", 0x00000c48, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
565 {"mfsr", 0x00000050, 0x3e0003ff, 0x8000, Rd_x_I5
, do_rdsrs
},
566 {"mfcr", 0x0c000001, 0x3e00001f, 0x8000, Rd_Rs_x
, do_rdcrs
},
567 {"mfc1", 0x0c000009, 0x3e00001f, 0x8000, Rd_Rs_x
, do_rdcrs
},
568 {"mfc2", 0x0c000011, 0x3e00001f, 0x8000, Rd_Rs_x
, do_rdcrs
},
569 {"mfc3", 0x0c000019, 0x3e00001f, 0x8000, Rd_Rs_x
, do_rdcrs
},
570 {"mfcc1", 0x0c00000f, 0x3e00001f, 0x8000, Rd_Rs_x
, do_rdcrs
},
571 {"mfcc2", 0x0c000017, 0x3e00001f, 0x8000, Rd_Rs_x
, do_rdcrs
},
572 {"mfcc3", 0x0c00001f, 0x3e00001f, 0x8000, Rd_Rs_x
, do_rdcrs
},
573 {"mhfl!", 0x0002, 0x700f, 0x00003c56, Rd_LowRs
, do16_hrdrs
},
574 {"min", 0x38000006, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
575 {"mlfh!", 0x0001, 0x700f, 0x00003c56, Rd_HighRs
, do16_rdhrs
},
576 {"msb", 0x38000001, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
577 {"msb.f!", 0x1006, 0x700f, 0x38000081, Rd_Rs
, do16_rdrs
},
578 {"msbh", 0x38000205, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
579 {"msbh.fs", 0x380002c5, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
580 {"msbh.fs!", 0x100f, 0x700f, 0x380002c5, Rd_Rs
, do16_rdrs
},
581 {"msbl", 0x38000004, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
582 {"msbl.fs", 0x380000c4, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
583 {"msbl.fs!", 0x100e, 0x700f, 0x380000c4, Rd_Rs
, do16_rdrs
},
584 {"msbu", 0x38000021, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
585 {"msbu!", 0x1007, 0x700f, 0x38000021, Rd_Rs
, do16_rdrs
},
586 {"msb.f", 0x38000081, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
587 {"mszh", 0x38000305, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
588 {"mszh.f", 0x38000385, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
589 {"mszh.f!", 0x100d, 0x700f, 0x38000385, Rd_Rs
, do16_rdrs
},
590 {"mszl", 0x38000104, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
591 {"mszl.f", 0x38000184, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
592 {"mszl.f!", 0x100c, 0x700f, 0x38000184, Rd_Rs
, do16_rdrs
},
593 {"mtcel!", 0x1000, 0x7f0f, 0x0000044a, x_Rs
, do16_rs
},
594 {"mtcel", 0x0000044a, 0x3e007fff, 0x8000, Rd_x_x
, do_rd
},
595 {"mtceh", 0x0000084a, 0x3e007fff, 0x8000, Rd_x_x
, do_rd
},
596 {"mtceh!", 0x1100, 0x7f0f, 0x0000084a, x_Rs
, do16_rs
},
597 {"mtcehl", 0x00000c4a, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
598 {"mtsr", 0x00000052, 0x3e0003ff, 0x8000, x_Rs_I5
, do_rdsrs
},
599 {"mtcr", 0x0c000000, 0x3e00001f, 0x8000, Rd_Rs_x
, do_rdcrs
},
600 {"mtc1", 0x0c000008, 0x3e00001f, 0x8000, Rd_Rs_x
, do_rdcrs
},
601 {"mtc2", 0x0c000010, 0x3e00001f, 0x8000, Rd_Rs_x
, do_rdcrs
},
602 {"mtc3", 0x0c000018, 0x3e00001f, 0x8000, Rd_Rs_x
, do_rdcrs
},
603 {"mtcc1", 0x0c00000e, 0x3e00001f, 0x8000, Rd_Rs_x
, do_rdcrs
},
604 {"mtcc2", 0x0c000016, 0x3e00001f, 0x8000, Rd_Rs_x
, do_rdcrs
},
605 {"mtcc3", 0x0c00001e, 0x3e00001f, 0x8000, Rd_Rs_x
, do_rdcrs
},
606 {"mul.f!", 0x1002, 0x700f, 0x00000041, Rd_Rs
, do16_rdrs
},
607 {"mulu!", 0x1003, 0x700f, 0x00000042, Rd_Rs
, do16_rdrs
},
608 {"mvcs", 0x00000056, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
609 {"mvcc", 0x00000456, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
610 {"mvgtu", 0x00000856, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
611 {"mvleu", 0x00000c56, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
612 {"mveq", 0x00001056, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
613 {"mvne", 0x00001456, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
614 {"mvgt", 0x00001856, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
615 {"mvle", 0x00001c56, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
616 {"mvge", 0x00002056, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
617 {"mvlt", 0x00002456, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
618 {"mvmi", 0x00002856, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
619 {"mvpl", 0x00002c56, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
620 {"mvvs", 0x00003056, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
621 {"mvvc", 0x00003456, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
622 {"mv", 0x00003c56, 0x3e007fff, 0x0003, Rd_Rs_x
, do_rdrs
},
623 {"mv!", 0x0003, 0x700f, 0x00003c56, Rd_Rs
, do16_mv_rdrs
},
624 {"neg", 0x0000001e, 0x3e0003ff, 0x8000, Rd_x_Rs
, do_rdxrs
},
625 {"neg.c", 0x0000001f, 0x3e0003ff, 0x2002, Rd_x_Rs
, do_rdxrs
},
626 {"neg!", 0x2002, 0x700f, 0x0000001f, Rd_Rs
, do16_rdrs
},
627 {"nop", 0x00000000, 0x3e0003ff, 0x0000, NO_OPD
, do_empty
},
628 {"not", 0x00000024, 0x3e0003ff, 0x8000, Rd_Rs_x
, do_rdrs
},
629 {"not.c", 0x00000025, 0x3e0003ff, 0x2006, Rd_Rs_x
, do_rdrs
},
630 {"nop!", 0x0000, 0x700f, 0x00000000, NO16_OPD
, do_empty
},
631 {"not!", 0x2006, 0x700f, 0x00000025, Rd_Rs
, do16_rdrs
},
632 {"or", 0x00000022, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
633 {"or.c", 0x00000023, 0x3e0003ff, 0x2005, Rd_Rs_Rs
, do_rdrsrs
},
634 {"ori", 0x020a0000, 0x3e0e0001, 0x8000, Rd_I16
, do_rdi16
},
635 {"ori.c", 0x020a0001, 0x3e0e0001, 0x8000, Rd_I16
, do_rdi16
},
636 {"oris", 0x0a0a0000, 0x3e0e0001, 0x8000, Rd_I16
, do_rdi16
},
637 {"oris.c", 0x0a0a0001, 0x3e0e0001, 0x8000, Rd_I16
, do_rdi16
},
638 {"orri", 0x1a000000, 0x3e000001, 0x8000, Rd_Rs_I14
, do_rdrsi14
},
639 {"orri.c", 0x1a000001, 0x3e000001, 0x8000, Rd_Rs_I14
, do_rdrsi14
},
640 {"or!", 0x2005, 0x700f, 0x00000023, Rd_Rs
, do16_rdrs
},
641 {"pflush", 0x0000000a, 0x3e0003ff, 0x8000, NO_OPD
, do_empty
},
642 {"pop!", 0x200a, 0x700f, 0x0e000000, Rd_rvalueRs
, do16_push_pop
},
643 {"push!", 0x200e, 0x700f, 0x06000004, Rd_lvalueRs
, do16_push_pop
},
644 {"ror", 0x00000038, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
645 {"ror.c", 0x00000039, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
646 {"rorc.c", 0x0000003b, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
647 {"rol", 0x0000003c, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
648 {"rol.c", 0x0000003d, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
649 {"rolc.c", 0x0000003f, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
650 {"rori", 0x00000078, 0x3e0003ff, 0x8000, Rd_Rs_I5
, do_rdrsi5
},
651 {"rori.c", 0x00000079, 0x3e0003ff, 0x8000, Rd_Rs_I5
, do_rdrsi5
},
652 {"roric.c", 0x0000007b, 0x3e0003ff, 0x8000, Rd_Rs_I5
, do_rdrsi5
},
653 {"roli", 0x0000007c, 0x3e0003ff, 0x8000, Rd_Rs_I5
, do_rdrsi5
},
654 {"roli.c", 0x0000007d, 0x3e0003ff, 0x8000, Rd_Rs_I5
, do_rdrsi5
},
655 {"rolic.c", 0x0000007f, 0x3e0003ff, 0x8000, Rd_Rs_I5
, do_rdrsi5
},
656 {"rte", 0x0c000084, 0x3e0003ff, 0x8000, NO_OPD
, do_empty
},
657 {"sb!", 0x200f, 0x700f, 0x2e000000, Rd_lvalueRs
, do16_ldst_insn
},
658 {"sbp!", 0x7007, 0x7007, 0x2e000000, Rd_lvalueBP_I5
, do16_ldst_imm_insn
},
659 {"asw", 0x0000000e, 0x3e0003ff, 0x8000, Rd_lvalue32Rs
, do_ldst_atomic
},
660 {"scb", 0x00000068, 0x3e0003ff, 0x8000, Rd_lvalueRs_post4
, do_ldst_unalign
},
661 {"scw", 0x0000006a, 0x3e0003ff, 0x8000, Rd_lvalueRs_post4
, do_ldst_unalign
},
662 {"sce", 0x0000006e, 0x3e0003ff, 0x8000, x_lvalueRs_post4
, do_ldst_unalign
},
663 {"sdbbp", 0x00000006, 0x3e0003ff, 0x6002, x_I5_x
, do_xi5x
},
664 {"sdbbp!", 0x6002, 0x7007, 0x00000006, Rd_I5
, do16_xi5
},
665 {"sh!", 0x200d, 0x700f, 0x2a000000, Rd_lvalueRs
, do16_ldst_insn
},
666 {"shp!", 0x7005, 0x7007, 0x2a000000, Rd_lvalueBP_I5
, do16_ldst_imm_insn
},
667 {"sleep", 0x0c0000c4, 0x3e0003ff, 0x8000, NO_OPD
, do_empty
},
668 {"sll", 0x00000030, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
669 {"sll.c", 0x00000031, 0x3e0003ff, 0x0008, Rd_Rs_Rs
, do_rdrsrs
},
670 {"sll.s", 0x3800004e, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
671 {"slli", 0x00000070, 0x3e0003ff, 0x8000, Rd_Rs_I5
, do_rdrsi5
},
672 {"slli.c", 0x00000071, 0x3e0003ff, 0x6001, Rd_Rs_I5
, do_rdrsi5
},
673 {"sll!", 0x0008, 0x700f, 0x00000031, Rd_Rs
, do16_rdrs
},
674 {"slli!", 0x6001, 0x7007, 0x00000071, Rd_I5
, do16_rdi5
},
675 {"srl", 0x00000034, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
676 {"srl.c", 0x00000035, 0x3e0003ff, 0x000a, Rd_Rs_Rs
, do_rdrsrs
},
677 {"sra", 0x00000036, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
678 {"sra.c", 0x00000037, 0x3e0003ff, 0x000b, Rd_Rs_Rs
, do_rdrsrs
},
679 {"srli", 0x00000074, 0x3e0003ff, 0x8000, Rd_Rs_I5
, do_rdrsi5
},
680 {"srli.c", 0x00000075, 0x3e0003ff, 0x6003, Rd_Rs_I5
, do_rdrsi5
},
681 {"srai", 0x00000076, 0x3e0003ff, 0x8000, Rd_Rs_I5
, do_rdrsi5
},
682 {"srai.c", 0x00000077, 0x3e0003ff, 0x8000, Rd_Rs_I5
, do_rdrsi5
},
683 {"srl!", 0x000a, 0x700f, 0x00000035, Rd_Rs
, do16_rdrs
},
684 {"sra!", 0x000b, 0x700f, 0x00000037, Rd_Rs
, do16_rdrs
},
685 {"srli!", 0x6003, 0x7007, 0x00000075, Rd_Rs
, do16_rdi5
},
686 {"stc1", 0x0c00000b, 0x3e00001f, 0x8000, Rd_lvalueRs_SI10
, do_ldst_cop
},
687 {"stc2", 0x0c000013, 0x3e00001f, 0x8000, Rd_lvalueRs_SI10
, do_ldst_cop
},
688 {"stc3", 0x0c00001b, 0x3e00001f, 0x8000, Rd_lvalueRs_SI10
, do_ldst_cop
},
689 {"sub", 0x00000014, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
690 {"sub.c", 0x00000015, 0x3e0003ff, 0x2001, Rd_Rs_Rs
, do_rdrsrs
},
691 {"sub.s", 0x38000049, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
692 {"subc", 0x00000016, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
693 {"subc.c", 0x00000017, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
694 {"sub!", 0x2001, 0x700f, 0x00000015, Rd_Rs
, do16_rdrs
},
695 {"subei!", 0x6080, 0x7087, 0x02000001, Rd_I4
, do16_rdi4
},
696 {"sw!", 0x200c, 0x700f, 0x28000000, Rd_lvalueRs
, do16_ldst_insn
},
697 {"swp!", 0x7004, 0x7007, 0x28000000, Rd_lvalueBP_I5
, do16_ldst_imm_insn
},
698 {"syscall", 0x00000002, 0x3e0003ff, 0x8000, I15
, do_i15
},
699 {"tcs", 0x00000054, 0x3e007fff, 0x0005, NO_OPD
, do_empty
},
700 {"tcc", 0x00000454, 0x3e007fff, 0x0105, NO_OPD
, do_empty
},
701 {"tcnz", 0x00003854, 0x3e007fff, 0x0e05, NO_OPD
, do_empty
},
702 {"tcs!", 0x0005, 0x7f0f, 0x00000054, NO16_OPD
, do_empty
},
703 {"tcc!", 0x0105, 0x7f0f, 0x00000454, NO16_OPD
, do_empty
},
704 {"tcnz!", 0x0e05, 0x7f0f, 0x00003854, NO16_OPD
, do_empty
},
705 {"teq", 0x00001054, 0x3e007fff, 0x0405, NO_OPD
, do_empty
},
706 {"teq!", 0x0405, 0x7f0f, 0x00001054, NO16_OPD
, do_empty
},
707 {"tgtu", 0x00000854, 0x3e007fff, 0x0205, NO_OPD
, do_empty
},
708 {"tgt", 0x00001854, 0x3e007fff, 0x0605, NO_OPD
, do_empty
},
709 {"tge", 0x00002054, 0x3e007fff, 0x0805, NO_OPD
, do_empty
},
710 {"tgtu!", 0x0205, 0x7f0f, 0x00000854, NO16_OPD
, do_empty
},
711 {"tgt!", 0x0605, 0x7f0f, 0x00001854, NO16_OPD
, do_empty
},
712 {"tge!", 0x0805, 0x7f0f, 0x00002054, NO16_OPD
, do_empty
},
713 {"tleu", 0x00000c54, 0x3e007fff, 0x0305, NO_OPD
, do_empty
},
714 {"tle", 0x00001c54, 0x3e007fff, 0x0705, NO_OPD
, do_empty
},
715 {"tlt", 0x00002454, 0x3e007fff, 0x0905, NO_OPD
, do_empty
},
716 {"stlb", 0x0c000004, 0x3e0003ff, 0x8000, NO_OPD
, do_empty
},
717 {"mftlb", 0x0c000024, 0x3e0003ff, 0x8000, NO_OPD
, do_empty
},
718 {"mtptlb", 0x0c000044, 0x3e0003ff, 0x8000, NO_OPD
, do_empty
},
719 {"mtrtlb", 0x0c000064, 0x3e0003ff, 0x8000, NO_OPD
, do_empty
},
720 {"tleu!", 0x0305, 0x7f0f, 0x00000c54, NO16_OPD
, do_empty
},
721 {"tle!", 0x0705, 0x7f0f, 0x00001c54, NO16_OPD
, do_empty
},
722 {"tlt!", 0x0905, 0x7f0f, 0x00002454, NO16_OPD
, do_empty
},
723 {"tmi", 0x00002854, 0x3e007fff, 0x0a05, NO_OPD
, do_empty
},
724 {"tmi!", 0x0a05, 0x7f0f, 0x00002854, NO16_OPD
, do_empty
},
725 {"tne", 0x00001454, 0x3e007fff, 0x0505, NO_OPD
, do_empty
},
726 {"tne!", 0x0505, 0x7f0f, 0x00001454, NO16_OPD
, do_empty
},
727 {"tpl", 0x00002c54, 0x3e007fff, 0x0b05, NO_OPD
, do_empty
},
728 {"tpl!", 0x0b05, 0x7f0f, 0x00002c54, NO16_OPD
, do_empty
},
729 {"trapcs", 0x00000004, 0x3e007fff, 0x8000, x_I5_x
, do_xi5x
},
730 {"trapcc", 0x00000404, 0x3e007fff, 0x8000, x_I5_x
, do_xi5x
},
731 {"trapgtu", 0x00000804, 0x3e007fff, 0x8000, x_I5_x
, do_xi5x
},
732 {"trapleu", 0x00000c04, 0x3e007fff, 0x8000, x_I5_x
, do_xi5x
},
733 {"trapeq", 0x00001004, 0x3e007fff, 0x8000, x_I5_x
, do_xi5x
},
734 {"trapne", 0x00001404, 0x3e007fff, 0x8000, x_I5_x
, do_xi5x
},
735 {"trapgt", 0x00001804, 0x3e007fff, 0x8000, x_I5_x
, do_xi5x
},
736 {"traple", 0x00001c04, 0x3e007fff, 0x8000, x_I5_x
, do_xi5x
},
737 {"trapge", 0x00002004, 0x3e007fff, 0x8000, x_I5_x
, do_xi5x
},
738 {"traplt", 0x00002404, 0x3e007fff, 0x8000, x_I5_x
, do_xi5x
},
739 {"trapmi", 0x00002804, 0x3e007fff, 0x8000, x_I5_x
, do_xi5x
},
740 {"trappl", 0x00002c04, 0x3e007fff, 0x8000, x_I5_x
, do_xi5x
},
741 {"trapvs", 0x00003004, 0x3e007fff, 0x8000, x_I5_x
, do_xi5x
},
742 {"trapvc", 0x00003404, 0x3e007fff, 0x8000, x_I5_x
, do_xi5x
},
743 {"trap", 0x00003c04, 0x3e007fff, 0x8000, x_I5_x
, do_xi5x
},
744 {"tset", 0x00003c54, 0x3e007fff, 0x0f05, NO_OPD
, do_empty
},
745 {"tset!", 0x0f05, 0x00007f0f, 0x00003c54, NO16_OPD
, do_empty
},
746 {"tvs", 0x00003054, 0x3e007fff, 0x0c05, NO_OPD
, do_empty
},
747 {"tvc", 0x00003454, 0x3e007fff, 0x0d05, NO_OPD
, do_empty
},
748 {"tvs!", 0x0c05, 0x7f0f, 0x00003054, NO16_OPD
, do_empty
},
749 {"tvc!", 0x0d05, 0x7f0f, 0x00003454, NO16_OPD
, do_empty
},
750 {"xor", 0x00000026, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
751 {"xor.c", 0x00000027, 0x3e0003ff, 0x2007, Rd_Rs_Rs
, do_rdrsrs
},
752 {"xor!", 0x2007, 0x700f, 0x00000027, Rd_Rs
, do16_rdrs
},
753 /* Macro instruction. */
754 {"li", 0x020c0000, 0x3e0e0000, 0x8000, Insn_Type_SYN
, do_macro_li_rdi32
},
755 /* la reg, imm32 -->(1) ldi reg, simm16
756 (2) ldis reg, %HI(imm32)
759 la reg, symbol -->(1) lis reg, %HI(imm32)
760 ori reg, %LO(imm32) */
761 {"la", 0x020c0000, 0x3e0e0000, 0x8000, Insn_Type_SYN
, do_macro_la_rdi32
},
762 {"div", 0x00000044, 0x3e0003ff, 0x8000, Insn_Type_SYN
, do_macro_mul_rdrsrs
},
763 {"divu", 0x00000046, 0x3e0003ff, 0x8000, Insn_Type_SYN
, do_macro_mul_rdrsrs
},
764 {"rem", 0x00000044, 0x3e0003ff, 0x8000, Insn_Type_SYN
, do_macro_mul_rdrsrs
},
765 {"remu", 0x00000046, 0x3e0003ff, 0x8000, Insn_Type_SYN
, do_macro_mul_rdrsrs
},
766 {"mul", 0x00000040, 0x3e0003ff, 0x8000, Insn_Type_SYN
, do_macro_mul_rdrsrs
},
767 {"mulu", 0x00000042, 0x3e0003ff, 0x8000, Insn_Type_SYN
, do_macro_mul_rdrsrs
},
768 {"maz", 0x00000040, 0x3e0003ff, 0x8000, Insn_Type_SYN
, do_macro_mul_rdrsrs
},
769 {"mazu", 0x00000042, 0x3e0003ff, 0x8000, Insn_Type_SYN
, do_macro_mul_rdrsrs
},
770 {"mul.f", 0x00000041, 0x3e0003ff, 0x8000, Insn_Type_SYN
, do_macro_mul_rdrsrs
},
771 {"maz.f", 0x00000041, 0x3e0003ff, 0x8000, Insn_Type_SYN
, do_macro_mul_rdrsrs
},
772 {"lb", INSN_LB
, 0x00000000, 0x8000, Insn_Type_SYN
, do_macro_ldst_label
},
773 {"lbu", INSN_LBU
, 0x00000000, 0x200b, Insn_Type_SYN
, do_macro_ldst_label
},
774 {"lh", INSN_LH
, 0x00000000, 0x2009, Insn_Type_SYN
, do_macro_ldst_label
},
775 {"lhu", INSN_LHU
, 0x00000000, 0x8000, Insn_Type_SYN
, do_macro_ldst_label
},
776 {"lw", INSN_LW
, 0x00000000, 0x2008, Insn_Type_SYN
, do_macro_ldst_label
},
777 {"sb", INSN_SB
, 0x00000000, 0x200f, Insn_Type_SYN
, do_macro_ldst_label
},
778 {"sh", INSN_SH
, 0x00000000, 0x200d, Insn_Type_SYN
, do_macro_ldst_label
},
779 {"sw", INSN_SW
, 0x00000000, 0x200c, Insn_Type_SYN
, do_macro_ldst_label
},
780 /* Assembler use internal. */
781 {"ld_i32hi", 0x0a0c0000, 0x3e0e0000, 0x8000, Insn_internal
, do_macro_rdi32hi
},
782 {"ld_i32lo", 0x020a0000, 0x3e0e0001, 0x8000, Insn_internal
, do_macro_rdi32lo
},
783 {"ldis_pic", 0x0a0c0000, 0x3e0e0000, 0x5000, Insn_internal
, do_rdi16_pic
},
784 {"addi_s_pic",0x02000000, 0x3e0e0001, 0x8000, Insn_internal
, do_addi_s_pic
},
785 {"addi_u_pic",0x02000000, 0x3e0e0001, 0x8000, Insn_internal
, do_addi_u_pic
},
786 {"lw_pic", 0x20000000, 0x3e000000, 0x8000, Insn_internal
, do_lw_pic
},
789 /* Next free entry in the pool. */
790 int next_literal_pool_place
= 0;
792 /* Next literal pool number. */
793 int lit_pool_num
= 1;
794 symbolS
*current_poolP
= NULL
;
797 end_of_line (char *str
)
799 int retval
= SUCCESS
;
801 skip_whitespace (str
);
807 inst
.error
= BAD_GARBAGE
;
814 score_reg_parse (char **ccp
, struct hash_control
*htab
)
819 struct reg_entry
*reg
;
822 if (!ISALPHA (*p
) || !is_name_beginner (*p
))
827 while (ISALPHA (c
) || ISDIGIT (c
) || c
== '_')
831 reg
= (struct reg_entry
*) hash_find (htab
, start
);
842 /* If shift <= 0, only return reg. */
845 reg_required_here (char **str
, int shift
, enum score_reg_type reg_type
)
847 static char buff
[MAX_LITERAL_POOL_SIZE
];
848 int reg
= (int) FAIL
;
851 if ((reg
= score_reg_parse (str
, all_reg_maps
[reg_type
].htab
)) != (int) FAIL
)
853 if (reg_type
== REG_TYPE_SCORE
)
855 if ((reg
== 1) && (nor1
== 1) && (inst
.bwarn
== 0))
857 as_warn ("Using temp register(r1)");
863 if (reg_type
== REG_TYPE_SCORE_CR
)
864 strcpy (inst
.reg
, score_crn_table
[reg
].name
);
865 else if (reg_type
== REG_TYPE_SCORE_SR
)
866 strcpy (inst
.reg
, score_srn_table
[reg
].name
);
868 strcpy (inst
.reg
, "");
870 inst
.instruction
|= reg
<< shift
;
876 sprintf (buff
, _("register expected, not '%.100s'"), start
);
884 skip_past_comma (char **str
)
890 while ((c
= *p
) == ' ' || c
== ',')
893 if (c
== ',' && comma
++)
895 inst
.error
= BAD_SKIP_COMMA
;
900 if ((c
== '\0') || (comma
== 0))
902 inst
.error
= BAD_SKIP_COMMA
;
907 return comma
? SUCCESS
: (int) FAIL
;
911 do_rdrsrs (char *str
)
913 skip_whitespace (str
);
915 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) == (int) FAIL
916 || skip_past_comma (&str
) == (int) FAIL
917 || reg_required_here (&str
, 15, REG_TYPE_SCORE
) == (int) FAIL
918 || skip_past_comma (&str
) == (int) FAIL
919 || reg_required_here (&str
, 10, REG_TYPE_SCORE
) == (int) FAIL
920 || end_of_line (str
) == (int) FAIL
)
926 if ((((inst
.instruction
>> 15) & 0x10) == 0)
927 && (((inst
.instruction
>> 10) & 0x10) == 0)
928 && (((inst
.instruction
>> 20) & 0x10) == 0)
929 && (inst
.relax_inst
!= 0x8000)
930 && (((inst
.instruction
>> 20) & 0xf) == ((inst
.instruction
>> 15) & 0xf)))
932 inst
.relax_inst
|= (((inst
.instruction
>> 10) & 0xf) << 4)
933 | (((inst
.instruction
>> 15) & 0xf) << 8);
938 inst
.relax_inst
= 0x8000;
944 walk_no_bignums (symbolS
* sp
)
946 if (symbol_get_value_expression (sp
)->X_op
== O_big
)
949 if (symbol_get_value_expression (sp
)->X_add_symbol
)
950 return (walk_no_bignums (symbol_get_value_expression (sp
)->X_add_symbol
)
951 || (symbol_get_value_expression (sp
)->X_op_symbol
952 && walk_no_bignums (symbol_get_value_expression (sp
)->X_op_symbol
)));
958 my_get_expression (expressionS
* ep
, char **str
)
963 save_in
= input_line_pointer
;
964 input_line_pointer
= *str
;
965 in_my_get_expression
= 1;
966 seg
= expression (ep
);
967 in_my_get_expression
= 0;
969 if (ep
->X_op
== O_illegal
)
971 *str
= input_line_pointer
;
972 input_line_pointer
= save_in
;
973 inst
.error
= _("illegal expression");
976 /* Get rid of any bignums now, so that we don't generate an error for which
977 we can't establish a line number later on. Big numbers are never valid
978 in instructions, which is where this routine is always called. */
979 if (ep
->X_op
== O_big
981 && (walk_no_bignums (ep
->X_add_symbol
)
982 || (ep
->X_op_symbol
&& walk_no_bignums (ep
->X_op_symbol
)))))
984 inst
.error
= _("invalid constant");
985 *str
= input_line_pointer
;
986 input_line_pointer
= save_in
;
990 if ((ep
->X_add_symbol
!= NULL
)
991 && (inst
.type
!= PC_DISP19div2
)
992 && (inst
.type
!= PC_DISP8div2
)
993 && (inst
.type
!= PC_DISP24div2
)
994 && (inst
.type
!= PC_DISP11div2
)
995 && (inst
.type
!= Insn_Type_SYN
)
996 && (inst
.type
!= Rd_rvalueRs_SI15
)
997 && (inst
.type
!= Rd_lvalueRs_SI15
)
998 && (inst
.type
!= Insn_internal
))
1000 inst
.error
= BAD_ARGS
;
1001 *str
= input_line_pointer
;
1002 input_line_pointer
= save_in
;
1006 *str
= input_line_pointer
;
1007 input_line_pointer
= save_in
;
1011 /* Check if an immediate is valid. If so, convert it to the right format. */
1014 validate_immediate (int val
, unsigned int data_type
)
1020 int val_hi
= ((val
& 0xffff0000) >> 16);
1022 if (score_df_range
[data_type
].range
[0] <= val_hi
1023 && val_hi
<= score_df_range
[data_type
].range
[1])
1030 int val_lo
= (val
& 0xffff);
1032 if (score_df_range
[data_type
].range
[0] <= val_lo
1033 && val_lo
<= score_df_range
[data_type
].range
[1])
1043 if (data_type
== _SIMM14_NEG
|| data_type
== _SIMM16_NEG
|| data_type
== _IMM16_NEG
)
1046 if (score_df_range
[data_type
].range
[0] <= val
1047 && val
<= score_df_range
[data_type
].range
[1])
1057 data_op2 (char **str
, int shift
, enum score_data_type data_type
)
1060 char data_exp
[MAX_LITERAL_POOL_SIZE
];
1065 skip_whitespace (*str
);
1069 while ((*dataptr
!= '\0') && (*dataptr
!= '|') && (cnt
<= MAX_LITERAL_POOL_SIZE
)) /* 0x7c = ='|' */
1071 data_exp
[cnt
] = *dataptr
;
1076 data_exp
[cnt
] = '\0';
1077 pp
= (char *)&data_exp
;
1079 if (*dataptr
== '|') /* process PCE */
1081 if (my_get_expression (&inst
.reloc
.exp
, &pp
) == (int) FAIL
)
1084 if (inst
.error
!= 0)
1085 return (int) FAIL
; /* to ouptut_inst to printf out the error */
1088 else /* process 16 bit */
1090 if (my_get_expression (&inst
.reloc
.exp
, str
) == (int) FAIL
)
1095 dataptr
= (char *)data_exp
;
1096 for (; *dataptr
!= '\0'; dataptr
++)
1098 *dataptr
= TOLOWER (*dataptr
);
1099 if (*dataptr
== '!' || *dataptr
== ' ')
1102 dataptr
= (char *)data_exp
;
1104 if ((*dataptr
== '0') && (*(dataptr
+ 1) == 'x')
1105 && (data_type
!= _SIMM16_LA
)
1106 && (data_type
!= _VALUE_HI16
)
1107 && (data_type
!= _VALUE_LO16
)
1108 && (data_type
!= _IMM16
)
1109 && (data_type
!= _IMM15
)
1110 && (data_type
!= _IMM14
)
1111 && (data_type
!= _IMM4
)
1112 && (data_type
!= _IMM5
)
1113 && (data_type
!= _IMM8
)
1114 && (data_type
!= _IMM5_RSHIFT_1
)
1115 && (data_type
!= _IMM5_RSHIFT_2
)
1116 && (data_type
!= _SIMM14_NEG
)
1117 && (data_type
!= _IMM10_RSHIFT_2
)
1118 && (data_type
!= _GP_IMM15
))
1123 if ((inst
.reloc
.exp
.X_add_number
== 0)
1124 && (inst
.type
!= Insn_Type_SYN
)
1125 && (inst
.type
!= Rd_rvalueRs_SI15
)
1126 && (inst
.type
!= Rd_lvalueRs_SI15
)
1127 && (inst
.type
!= Insn_internal
)
1128 && (((*dataptr
>= 'a') && (*dataptr
<= 'z'))
1129 || ((*dataptr
== '0') && (*(dataptr
+ 1) == 'x') && (*(dataptr
+ 2) != '0'))
1130 || ((*dataptr
== '+') && (*(dataptr
+ 1) != '0'))
1131 || ((*dataptr
== '-') && (*(dataptr
+ 1) != '0'))))
1133 inst
.error
= BAD_ARGS
;
1138 if ((inst
.reloc
.exp
.X_add_symbol
)
1139 && ((data_type
== _SIMM16
)
1140 || (data_type
== _SIMM16_NEG
)
1141 || (data_type
== _IMM16_NEG
)
1142 || (data_type
== _SIMM14
)
1143 || (data_type
== _SIMM14_NEG
)
1144 || (data_type
== _IMM5
)
1145 || (data_type
== _IMM14
)
1146 || (data_type
== _IMM20
)
1147 || (data_type
== _IMM16
)
1148 || (data_type
== _IMM15
)
1149 || (data_type
== _IMM4
)))
1151 inst
.error
= BAD_ARGS
;
1155 if (inst
.reloc
.exp
.X_add_symbol
)
1162 inst
.reloc
.type
= BFD_RELOC_HI16_S
;
1163 inst
.reloc
.pc_rel
= 0;
1166 inst
.reloc
.type
= BFD_RELOC_LO16
;
1167 inst
.reloc
.pc_rel
= 0;
1170 inst
.reloc
.type
= BFD_RELOC_SCORE_GPREL15
;
1171 inst
.reloc
.pc_rel
= 0;
1174 case _IMM16_LO16_pic
:
1175 inst
.reloc
.type
= BFD_RELOC_SCORE_GOT_LO16
;
1176 inst
.reloc
.pc_rel
= 0;
1179 inst
.reloc
.type
= BFD_RELOC_32
;
1180 inst
.reloc
.pc_rel
= 0;
1186 if (data_type
== _IMM16_pic
)
1188 inst
.reloc
.type
= BFD_RELOC_SCORE_DUMMY_HI16
;
1189 inst
.reloc
.pc_rel
= 0;
1192 if (data_type
== _SIMM16_LA
&& inst
.reloc
.exp
.X_unsigned
== 1)
1194 value
= validate_immediate (inst
.reloc
.exp
.X_add_number
, _SIMM16_LA_POS
);
1195 if (value
== (int) FAIL
) /* for advance to check if this is ldis */
1196 if ((inst
.reloc
.exp
.X_add_number
& 0xffff) == 0)
1198 inst
.instruction
|= 0x8000000;
1199 inst
.instruction
|= ((inst
.reloc
.exp
.X_add_number
>> 16) << 1) & 0x1fffe;
1205 value
= validate_immediate (inst
.reloc
.exp
.X_add_number
, data_type
);
1208 if (value
== (int) FAIL
)
1212 if ((data_type
!= _SIMM14_NEG
) && (data_type
!= _SIMM16_NEG
) && (data_type
!= _IMM16_NEG
))
1215 "invalid constant: %d bit expression not in range %d..%d",
1216 score_df_range
[data_type
].bits
,
1217 score_df_range
[data_type
].range
[0], score_df_range
[data_type
].range
[1]);
1222 "invalid constant: %d bit expression not in range %d..%d",
1223 score_df_range
[data_type
].bits
,
1224 -score_df_range
[data_type
].range
[1], -score_df_range
[data_type
].range
[0]);
1227 inst
.error
= _(err_msg
);
1231 if ((score_df_range
[data_type
].range
[0] != 0) || (data_type
== _IMM5_RANGE_8_31
))
1233 value
&= (1 << score_df_range
[data_type
].bits
) - 1;
1236 inst
.instruction
|= value
<< shift
;
1239 if ((inst
.instruction
& 0xf0000000) == 0x30000000)
1241 if ((((inst
.instruction
>> 20) & 0x1F) != 0)
1242 && (((inst
.instruction
>> 20) & 0x1F) != 1)
1243 && (((inst
.instruction
>> 20) & 0x1F) != 2)
1244 && (((inst
.instruction
>> 20) & 0x1F) != 3)
1245 && (((inst
.instruction
>> 20) & 0x1F) != 4)
1246 && (((inst
.instruction
>> 20) & 0x1F) != 8)
1247 && (((inst
.instruction
>> 20) & 0x1F) != 9)
1248 && (((inst
.instruction
>> 20) & 0x1F) != 0xa)
1249 && (((inst
.instruction
>> 20) & 0x1F) != 0xb)
1250 && (((inst
.instruction
>> 20) & 0x1F) != 0xc)
1251 && (((inst
.instruction
>> 20) & 0x1F) != 0xd)
1252 && (((inst
.instruction
>> 20) & 0x1F) != 0xe)
1253 && (((inst
.instruction
>> 20) & 0x1F) != 0x10)
1254 && (((inst
.instruction
>> 20) & 0x1F) != 0x11)
1255 && (((inst
.instruction
>> 20) & 0x1F) != 0x18)
1256 && (((inst
.instruction
>> 20) & 0x1F) != 0x1A)
1257 && (((inst
.instruction
>> 20) & 0x1F) != 0x1B)
1258 && (((inst
.instruction
>> 20) & 0x1F) != 0x1d)
1259 && (((inst
.instruction
>> 20) & 0x1F) != 0x1e)
1260 && (((inst
.instruction
>> 20) & 0x1F) != 0x1f))
1264 sprintf (err_msg
, "invalid constant: bit expression not defined");
1265 inst
.error
= _(err_msg
);
1273 /* Handle addi/addi.c/addis.c/cmpi.c/addis.c/ldi. */
1276 do_rdsi16 (char *str
)
1278 skip_whitespace (str
);
1280 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) == (int) FAIL
1281 || skip_past_comma (&str
) == (int) FAIL
1282 || data_op2 (&str
, 1, _SIMM16
) == (int) FAIL
1283 || end_of_line (str
) == (int) FAIL
)
1287 if ((inst
.instruction
& 0x20c0000) == 0x20c0000)
1289 if ((((inst
.instruction
>> 20) & 0x10) == 0x10) || ((inst
.instruction
& 0x1fe00) != 0))
1291 inst
.relax_inst
= 0x8000;
1295 inst
.relax_inst
|= (inst
.instruction
>> 1) & 0xff;
1296 inst
.relax_inst
|= (((inst
.instruction
>> 20) & 0xf) << 8);
1297 inst
.relax_size
= 2;
1300 else if (((inst
.instruction
>> 20) & 0x10) == 0x10)
1302 inst
.relax_inst
= 0x8000;
1306 /* Handle subi/subi.c. */
1309 do_sub_rdsi16 (char *str
)
1311 skip_whitespace (str
);
1313 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) != (int) FAIL
1314 && skip_past_comma (&str
) != (int) FAIL
1315 && data_op2 (&str
, 1, _SIMM16_NEG
) != (int) FAIL
)
1319 /* Handle subis/subis.c. */
1322 do_sub_rdi16 (char *str
)
1324 skip_whitespace (str
);
1326 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) != (int) FAIL
1327 && skip_past_comma (&str
) != (int) FAIL
1328 && data_op2 (&str
, 1, _IMM16_NEG
) != (int) FAIL
)
1332 /* Handle addri/addri.c. */
1335 do_rdrssi14 (char *str
) /* -(2^13)~((2^13)-1) */
1337 skip_whitespace (str
);
1339 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) != (int) FAIL
1340 && skip_past_comma (&str
) != (int) FAIL
1341 && reg_required_here (&str
, 15, REG_TYPE_SCORE
) != (int) FAIL
1342 && skip_past_comma (&str
) != (int) FAIL
)
1343 data_op2 (&str
, 1, _SIMM14
);
1346 /* Handle subri.c/subri. */
1348 do_sub_rdrssi14 (char *str
) /* -(2^13)~((2^13)-1) */
1350 skip_whitespace (str
);
1352 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) != (int) FAIL
1353 && skip_past_comma (&str
) != (int) FAIL
1354 && reg_required_here (&str
, 15, REG_TYPE_SCORE
) != (int) FAIL
1355 && skip_past_comma (&str
) != (int) FAIL
1356 && data_op2 (&str
, 1, _SIMM14_NEG
) != (int) FAIL
)
1360 /* Handle bitclr.c/bitset.c/bittgl.c/slli.c/srai.c/srli.c/roli.c/rori.c/rolic.c. */
1362 do_rdrsi5 (char *str
) /* 0~((2^14)-1) */
1364 skip_whitespace (str
);
1366 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) == (int) FAIL
1367 || skip_past_comma (&str
) == (int) FAIL
1368 || reg_required_here (&str
, 15, REG_TYPE_SCORE
) == (int) FAIL
1369 || skip_past_comma (&str
) == (int) FAIL
1370 || data_op2 (&str
, 10, _IMM5
) == (int) FAIL
1371 || end_of_line (str
) == (int) FAIL
)
1374 if ((((inst
.instruction
>> 20) & 0x1f) == ((inst
.instruction
>> 15) & 0x1f))
1375 && (inst
.relax_inst
!= 0x8000) && (((inst
.instruction
>> 15) & 0x10) == 0))
1377 inst
.relax_inst
|= (((inst
.instruction
>> 10) & 0x1f) << 3) | (((inst
.instruction
>> 15) & 0xf) << 8);
1378 inst
.relax_size
= 2;
1381 inst
.relax_inst
= 0x8000;
1384 /* Handle andri/orri/andri.c/orri.c. */
1387 do_rdrsi14 (char *str
) /* 0 ~ ((2^14)-1) */
1389 skip_whitespace (str
);
1391 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) != (int) FAIL
1392 && skip_past_comma (&str
) != (int) FAIL
1393 && reg_required_here (&str
, 15, REG_TYPE_SCORE
) != (int) FAIL
1394 && skip_past_comma (&str
) != (int) FAIL
1395 && data_op2 (&str
, 1, _IMM14
) != (int) FAIL
)
1399 /* Handle bittst.c. */
1401 do_xrsi5 (char *str
)
1403 skip_whitespace (str
);
1405 if (reg_required_here (&str
, 15, REG_TYPE_SCORE
) == (int) FAIL
1406 || skip_past_comma (&str
) == (int) FAIL
1407 || data_op2 (&str
, 10, _IMM5
) == (int) FAIL
1408 || end_of_line (str
) == (int) FAIL
)
1411 if ((inst
.relax_inst
!= 0x8000) && (((inst
.instruction
>> 15) & 0x10) == 0))
1413 inst
.relax_inst
|= (((inst
.instruction
>> 10) & 0x1f) << 3) | (((inst
.instruction
>> 15) & 0xf) << 8);
1414 inst
.relax_size
= 2;
1417 inst
.relax_inst
= 0x8000;
1420 /* Handle andi/ori/andis/oris/ldis. */
1422 do_rdi16 (char *str
)
1424 skip_whitespace (str
);
1426 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) == (int) FAIL
1427 || skip_past_comma (&str
) == (int) FAIL
1428 || data_op2 (&str
, 1, _IMM16
) == (int) FAIL
1429 || end_of_line (str
) == (int) FAIL
)
1432 if (((inst
.instruction
& 0xa0dfffe) != 0xa0c0000) || ((((inst
.instruction
>> 20) & 0x1f) & 0x10) == 0x10))
1433 inst
.relax_inst
= 0x8000;
1435 inst
.relax_size
= 2;
1439 do_macro_rdi32hi (char *str
)
1441 skip_whitespace (str
);
1443 /* Do not handle end_of_line(). */
1444 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) != (int) FAIL
1445 && skip_past_comma (&str
) != (int) FAIL
)
1446 data_op2 (&str
, 1, _VALUE_HI16
);
1450 do_macro_rdi32lo (char *str
)
1452 skip_whitespace (str
);
1454 /* Do not handle end_of_line(). */
1455 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) != (int) FAIL
1456 && skip_past_comma (&str
) != (int) FAIL
)
1457 data_op2 (&str
, 1, _VALUE_LO16
);
1460 /* Handle ldis_pic. */
1463 do_rdi16_pic (char *str
)
1465 skip_whitespace (str
);
1467 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) != (int) FAIL
1468 && skip_past_comma (&str
) != (int) FAIL
1469 && data_op2 (&str
, 1, _IMM16_pic
) != (int) FAIL
)
1473 /* Handle addi_s_pic to generate R_SCORE_GOT_LO16 . */
1476 do_addi_s_pic (char *str
)
1478 skip_whitespace (str
);
1480 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) != (int) FAIL
1481 && skip_past_comma (&str
) != (int) FAIL
1482 && data_op2 (&str
, 1, _SIMM16_pic
) != (int) FAIL
)
1486 /* Handle addi_u_pic to generate R_SCORE_GOT_LO16 . */
1489 do_addi_u_pic (char *str
)
1491 skip_whitespace (str
);
1493 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) != (int) FAIL
1494 && skip_past_comma (&str
) != (int) FAIL
1495 && data_op2 (&str
, 1, _IMM16_LO16_pic
) != (int) FAIL
)
1499 /* Handle mfceh/mfcel/mtceh/mtchl. */
1504 skip_whitespace (str
);
1506 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) != (int) FAIL
)
1513 skip_whitespace (str
);
1515 if (reg_required_here (&str
, 15, REG_TYPE_SCORE
) == (int) FAIL
1516 || end_of_line (str
) == (int) FAIL
)
1519 if ((inst
.relax_inst
!= 0x8000) && (((inst
.instruction
>> 15) & 0x10) == 0))
1521 inst
.relax_inst
|= (((inst
.instruction
>> 10) & 0xf) << 8) | (((inst
.instruction
>> 15) & 0xf) << 4);
1522 inst
.relax_size
= 2;
1525 inst
.relax_inst
= 0x8000;
1531 skip_whitespace (str
);
1533 if (data_op2 (&str
, 10, _IMM15
) != (int) FAIL
)
1540 skip_whitespace (str
);
1542 if (data_op2 (&str
, 15, _IMM5
) == (int) FAIL
|| end_of_line (str
) == (int) FAIL
)
1545 if (inst
.relax_inst
!= 0x8000)
1547 inst
.relax_inst
|= (((inst
.instruction
>> 15) & 0x1f) << 3);
1548 inst
.relax_size
= 2;
1555 skip_whitespace (str
);
1557 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) == (int) FAIL
1558 || skip_past_comma (&str
) == (int) FAIL
1559 || reg_required_here (&str
, 15, REG_TYPE_SCORE
) == (int) FAIL
1560 || end_of_line (str
) == (int) FAIL
)
1563 if (inst
.relax_inst
!= 0x8000)
1565 if (((inst
.instruction
& 0x7f) == 0x56)) /* adjust mv -> mv! / mlfh! / mhfl! */
1568 if ((((inst
.instruction
>> 15) & 0x10) != 0x0) && (((inst
.instruction
>> 20) & 0x10) == 0))
1570 inst
.relax_inst
= 0x00000001 | (((inst
.instruction
>> 15) & 0xf) << 4)
1571 | (((inst
.instruction
>> 20) & 0xf) << 8);
1572 inst
.relax_size
= 2;
1575 else if ((((inst
.instruction
>> 15) & 0x10) == 0x0) && ((inst
.instruction
>> 20) & 0x10) != 0)
1577 inst
.relax_inst
= 0x00000002 | (((inst
.instruction
>> 15) & 0xf) << 4)
1578 | (((inst
.instruction
>> 20) & 0xf) << 8);
1579 inst
.relax_size
= 2;
1581 else if ((((inst
.instruction
>> 15) & 0x10) == 0x0) && (((inst
.instruction
>> 20) & 0x10) == 0))
1583 inst
.relax_inst
|= (((inst
.instruction
>> 15) & 0xf) << 4)
1584 | (((inst
.instruction
>> 20) & 0xf) << 8);
1585 inst
.relax_size
= 2;
1589 inst
.relax_inst
= 0x8000;
1592 else if ((((inst
.instruction
>> 15) & 0x10) == 0x0) && (((inst
.instruction
>> 20) & 0x10) == 0))
1594 inst
.relax_inst
|= (((inst
.instruction
>> 15) & 0xf) << 4)
1595 | (((inst
.instruction
>> 20) & 0xf) << 8);
1596 inst
.relax_size
= 2;
1600 inst
.relax_inst
= 0x8000;
1605 /* Handle mfcr/mtcr. */
1607 do_rdcrs (char *str
)
1609 skip_whitespace (str
);
1611 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) != (int) FAIL
1612 && skip_past_comma (&str
) != (int) FAIL
1613 && reg_required_here (&str
, 15, REG_TYPE_SCORE_CR
) != (int) FAIL
)
1617 /* Handle mfsr/mtsr. */
1620 do_rdsrs (char *str
)
1622 skip_whitespace (str
);
1625 if ((inst
.instruction
& 0xff) == 0x50)
1627 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) != (int) FAIL
1628 && skip_past_comma (&str
) != (int) FAIL
1629 && reg_required_here (&str
, 10, REG_TYPE_SCORE_SR
) != (int) FAIL
)
1634 if (reg_required_here (&str
, 15, REG_TYPE_SCORE
) != (int) FAIL
1635 && skip_past_comma (&str
) != (int) FAIL
)
1636 reg_required_here (&str
, 10, REG_TYPE_SCORE_SR
);
1643 do_rdxrs (char *str
)
1645 skip_whitespace (str
);
1647 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) == (int) FAIL
1648 || skip_past_comma (&str
) == (int) FAIL
1649 || reg_required_here (&str
, 10, REG_TYPE_SCORE
) == (int) FAIL
1650 || end_of_line (str
) == (int) FAIL
)
1653 if ((inst
.relax_inst
!= 0x8000) && (((inst
.instruction
>> 10) & 0x10) == 0)
1654 && (((inst
.instruction
>> 20) & 0x10) == 0))
1656 inst
.relax_inst
|= (((inst
.instruction
>> 10) & 0xf) << 4) | (((inst
.instruction
>> 20) & 0xf) << 8);
1657 inst
.relax_size
= 2;
1660 inst
.relax_inst
= 0x8000;
1663 /* Handle cmp.c/cmp<cond>. */
1667 skip_whitespace (str
);
1669 if (reg_required_here (&str
, 15, REG_TYPE_SCORE
) == (int) FAIL
1670 || skip_past_comma (&str
) == (int) FAIL
1671 || reg_required_here (&str
, 10, REG_TYPE_SCORE
) == (int) FAIL
1672 || end_of_line (str
) == (int) FAIL
)
1675 if ((inst
.relax_inst
!= 0x8000) && (((inst
.instruction
>> 20) & 0x1f) == 3)
1676 && (((inst
.instruction
>> 10) & 0x10) == 0) && (((inst
.instruction
>> 15) & 0x10) == 0))
1678 inst
.relax_inst
|= (((inst
.instruction
>> 10) & 0xf) << 4) | (((inst
.instruction
>> 15) & 0xf) << 8);
1679 inst
.relax_size
= 2;
1682 inst
.relax_inst
= 0x8000;
1686 do_ceinst (char *str
)
1691 skip_whitespace (str
);
1693 if (data_op2 (&str
, 20, _IMM5
) == (int) FAIL
1694 || skip_past_comma (&str
) == (int) FAIL
1695 || reg_required_here (&str
, 15, REG_TYPE_SCORE
) == (int) FAIL
1696 || skip_past_comma (&str
) == (int) FAIL
1697 || reg_required_here (&str
, 10, REG_TYPE_SCORE
) == (int) FAIL
1698 || skip_past_comma (&str
) == (int) FAIL
1699 || data_op2 (&str
, 5, _IMM5
) == (int) FAIL
1700 || skip_past_comma (&str
) == (int) FAIL
1701 || data_op2 (&str
, 0, _IMM5
) == (int) FAIL
1702 || end_of_line (str
) == (int) FAIL
)
1709 if (data_op2 (&str
, 0, _IMM25
) == (int) FAIL
)
1715 reglow_required_here (char **str
, int shift
)
1717 static char buff
[MAX_LITERAL_POOL_SIZE
];
1721 if ((reg
= score_reg_parse (str
, all_reg_maps
[REG_TYPE_SCORE
].htab
)) != (int) FAIL
)
1723 if ((reg
== 1) && (nor1
== 1) && (inst
.bwarn
== 0))
1725 as_warn ("Using temp register(r1)");
1731 inst
.instruction
|= reg
<< shift
;
1737 /* Restore the start point, we may have got a reg of the wrong class. */
1739 sprintf (buff
, _("low register(r0-r15)expected, not '%.100s'"), start
);
1744 /* Handle addc!/add!/and!/cmp!/neg!/not!/or!/sll!/srl!/sra!/xor!/sub!. */
1746 do16_rdrs (char *str
)
1748 skip_whitespace (str
);
1750 if (reglow_required_here (&str
, 8) == (int) FAIL
1751 || skip_past_comma (&str
) == (int) FAIL
1752 || reglow_required_here (&str
, 4) == (int) FAIL
1753 || end_of_line (str
) == (int) FAIL
)
1759 if ((inst
.instruction
& 0x700f) == 0x2003) /* cmp! */
1761 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 15)
1762 | (((inst
.instruction
>> 4) & 0xf) << 10);
1764 else if ((inst
.instruction
& 0x700f) == 0x2006) /* not! */
1766 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 20)
1767 | (((inst
.instruction
>> 4) & 0xf) << 15);
1771 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 20)
1772 | (((inst
.instruction
>> 8) & 0xf) << 15) | (((inst
.instruction
>> 4) & 0xf) << 10);
1774 inst
.relax_size
= 4;
1783 skip_whitespace (str
);
1785 if ((rd
= reglow_required_here (&str
, 4)) == (int) FAIL
1786 || end_of_line (str
) == (int) FAIL
)
1792 inst
.relax_inst
|= rd
<< 20;
1793 inst
.relax_size
= 4;
1797 /* Handle br!/brl!. */
1799 do16_xrs (char *str
)
1801 skip_whitespace (str
);
1803 if (reglow_required_here (&str
, 4) == (int) FAIL
|| end_of_line (str
) == (int) FAIL
)
1809 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 10)
1810 | (((inst
.instruction
>> 4) & 0xf) << 15);
1811 inst
.relax_size
= 4;
1816 reghigh_required_here (char **str
, int shift
)
1818 static char buff
[MAX_LITERAL_POOL_SIZE
];
1822 if ((reg
= score_reg_parse (str
, all_reg_maps
[REG_TYPE_SCORE
].htab
)) != (int) FAIL
)
1824 if (15 < reg
&& reg
< 32)
1827 inst
.instruction
|= (reg
& 0xf) << shift
;
1834 sprintf (buff
, _("high register(r16-r31)expected, not '%.100s'"), start
);
1841 do16_hrdrs (char *str
)
1843 skip_whitespace (str
);
1845 if (reghigh_required_here (&str
, 8) != (int) FAIL
1846 && skip_past_comma (&str
) != (int) FAIL
1847 && reglow_required_here (&str
, 4) != (int) FAIL
1848 && end_of_line (str
) != (int) FAIL
)
1850 inst
.relax_inst
|= ((((inst
.instruction
>> 8) & 0xf) | 0x10) << 20)
1851 | (((inst
.instruction
>> 4) & 0xf) << 15) | (0xf << 10);
1852 inst
.relax_size
= 4;
1858 do16_rdhrs (char *str
)
1860 skip_whitespace (str
);
1862 if (reglow_required_here (&str
, 8) != (int) FAIL
1863 && skip_past_comma (&str
) != (int) FAIL
1864 && reghigh_required_here (&str
, 4) != (int) FAIL
1865 && end_of_line (str
) != (int) FAIL
)
1867 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 20)
1868 | ((((inst
.instruction
>> 4) & 0xf) | 0x10) << 15) | (0xf << 10);
1869 inst
.relax_size
= 4;
1873 /* We need to be able to fix up arbitrary expressions in some statements.
1874 This is so that we can handle symbols that are an arbitrary distance from
1875 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
1876 which returns part of an address in a form which will be valid for
1877 a data instruction. We do this by pushing the expression into a symbol
1878 in the expr_section, and creating a fix for that. */
1880 fix_new_score (fragS
* frag
, int where
, short int size
, expressionS
* exp
, int pc_rel
, int reloc
)
1890 new_fix
= fix_new_exp (frag
, where
, size
, exp
, pc_rel
, reloc
);
1893 new_fix
= fix_new (frag
, where
, size
, make_expr_symbol (exp
), 0, pc_rel
, reloc
);
1900 init_dependency_vector (void)
1904 for (i
= 0; i
< vector_size
; i
++)
1905 memset (&dependency_vector
[i
], '\0', sizeof (dependency_vector
[i
]));
1910 static enum insn_type_for_dependency
1911 dependency_type_from_insn (char *insn_name
)
1913 char name
[INSN_NAME_LEN
];
1914 const struct insn_to_dependency
*tmp
;
1916 strcpy (name
, insn_name
);
1917 tmp
= (const struct insn_to_dependency
*) hash_find (dependency_insn_hsh
, name
);
1926 check_dependency (char *pre_insn
, char *pre_reg
,
1927 char *cur_insn
, char *cur_reg
, int *warn_or_error
)
1931 enum insn_type_for_dependency pre_insn_type
;
1932 enum insn_type_for_dependency cur_insn_type
;
1934 pre_insn_type
= dependency_type_from_insn (pre_insn
);
1935 cur_insn_type
= dependency_type_from_insn (cur_insn
);
1937 for (i
= 0; i
< sizeof (data_dependency_table
) / sizeof (data_dependency_table
[0]); i
++)
1939 if ((pre_insn_type
== data_dependency_table
[i
].pre_insn_type
)
1940 && (D_all_insn
== data_dependency_table
[i
].cur_insn_type
1941 || cur_insn_type
== data_dependency_table
[i
].cur_insn_type
)
1942 && (strcmp (data_dependency_table
[i
].pre_reg
, "") == 0
1943 || strcmp (data_dependency_table
[i
].pre_reg
, pre_reg
) == 0)
1944 && (strcmp (data_dependency_table
[i
].cur_reg
, "") == 0
1945 || strcmp (data_dependency_table
[i
].cur_reg
, cur_reg
) == 0))
1947 bubbles
= (score7
) ? data_dependency_table
[i
].bubblenum_7
: data_dependency_table
[i
].bubblenum_5
;
1948 *warn_or_error
= data_dependency_table
[i
].warn_or_error
;
1957 build_one_frag (struct score_it one_inst
)
1960 int relaxable_p
= g_opt
;
1963 /* Start a new frag if frag_now is not empty. */
1964 if (frag_now_fix () != 0)
1966 if (!frag_now
->tc_frag_data
.is_insn
)
1967 frag_wane (frag_now
);
1973 p
= frag_more (one_inst
.size
);
1974 md_number_to_chars (p
, one_inst
.instruction
, one_inst
.size
);
1977 dwarf2_emit_insn (one_inst
.size
);
1980 relaxable_p
&= (one_inst
.relax_size
!= 0);
1981 relax_size
= relaxable_p
? one_inst
.relax_size
: 0;
1983 p
= frag_var (rs_machine_dependent
, relax_size
+ RELAX_PAD_BYTE
, 0,
1984 RELAX_ENCODE (one_inst
.size
, one_inst
.relax_size
,
1985 one_inst
.type
, 0, 0, relaxable_p
),
1989 md_number_to_chars (p
, one_inst
.relax_inst
, relax_size
);
1993 handle_dependency (struct score_it
*theinst
)
1996 int warn_or_error
= 0; /* warn - 0; error - 1 */
1998 int remainder_bubbles
= 0;
1999 char cur_insn
[INSN_NAME_LEN
];
2000 char pre_insn
[INSN_NAME_LEN
];
2001 struct score_it nop_inst
;
2002 struct score_it pflush_inst
;
2004 nop_inst
.instruction
= 0x0000;
2006 nop_inst
.relax_inst
= 0x80008000;
2007 nop_inst
.relax_size
= 4;
2008 nop_inst
.type
= NO16_OPD
;
2010 pflush_inst
.instruction
= 0x8000800a;
2011 pflush_inst
.size
= 4;
2012 pflush_inst
.relax_inst
= 0x8000;
2013 pflush_inst
.relax_size
= 0;
2014 pflush_inst
.type
= NO_OPD
;
2016 /* pflush will clear all data dependency. */
2017 if (strcmp (theinst
->name
, "pflush") == 0)
2019 init_dependency_vector ();
2023 /* Push current instruction to dependency_vector[0]. */
2024 for (i
= vector_size
- 1; i
> 0; i
--)
2025 memcpy (&dependency_vector
[i
], &dependency_vector
[i
- 1], sizeof (dependency_vector
[i
]));
2027 memcpy (&dependency_vector
[0], theinst
, sizeof (dependency_vector
[i
]));
2029 /* There is no dependency between nop and any instruction. */
2030 if (strcmp (dependency_vector
[0].name
, "nop") == 0
2031 || strcmp (dependency_vector
[0].name
, "nop!") == 0)
2034 /* "pce" is defined in insn_to_dependency_table. */
2035 #define PCE_NAME "pce"
2037 if (dependency_vector
[0].type
== Insn_Type_PCE
)
2038 strcpy (cur_insn
, PCE_NAME
);
2040 strcpy (cur_insn
, dependency_vector
[0].name
);
2042 for (i
= 1; i
< vector_size
; i
++)
2044 /* The element of dependency_vector is NULL. */
2045 if (dependency_vector
[i
].name
[0] == '\0')
2048 if (dependency_vector
[i
].type
== Insn_Type_PCE
)
2049 strcpy (pre_insn
, PCE_NAME
);
2051 strcpy (pre_insn
, dependency_vector
[i
].name
);
2053 bubbles
= check_dependency (pre_insn
, dependency_vector
[i
].reg
,
2054 cur_insn
, dependency_vector
[0].reg
, &warn_or_error
);
2055 remainder_bubbles
= bubbles
- i
+ 1;
2057 if (remainder_bubbles
> 0)
2061 if (fix_data_dependency
== 1)
2063 if (remainder_bubbles
<= 2)
2065 if (warn_fix_data_dependency
)
2066 as_warn ("Fix data dependency: %s %s -- %s %s (insert %d nop!/%d)",
2067 dependency_vector
[i
].name
, dependency_vector
[i
].reg
,
2068 dependency_vector
[0].name
, dependency_vector
[0].reg
,
2069 remainder_bubbles
, bubbles
);
2071 for (j
= (vector_size
- 1); (j
- remainder_bubbles
) > 0; j
--)
2072 memcpy (&dependency_vector
[j
], &dependency_vector
[j
- remainder_bubbles
],
2073 sizeof (dependency_vector
[j
]));
2075 for (j
= 1; j
<= remainder_bubbles
; j
++)
2077 memset (&dependency_vector
[j
], '\0', sizeof (dependency_vector
[j
]));
2079 build_one_frag (nop_inst
);
2084 if (warn_fix_data_dependency
)
2085 as_warn ("Fix data dependency: %s %s -- %s %s (insert 1 pflush/%d)",
2086 dependency_vector
[i
].name
, dependency_vector
[i
].reg
,
2087 dependency_vector
[0].name
, dependency_vector
[0].reg
,
2090 for (j
= 1; j
< vector_size
; j
++)
2091 memset (&dependency_vector
[j
], '\0', sizeof (dependency_vector
[j
]));
2093 /* Insert pflush. */
2094 build_one_frag (pflush_inst
);
2101 as_bad ("data dependency: %s %s -- %s %s (%d/%d bubble)",
2102 dependency_vector
[i
].name
, dependency_vector
[i
].reg
,
2103 dependency_vector
[0].name
, dependency_vector
[0].reg
,
2104 remainder_bubbles
, bubbles
);
2108 as_warn ("data dependency: %s %s -- %s %s (%d/%d bubble)",
2109 dependency_vector
[i
].name
, dependency_vector
[i
].reg
,
2110 dependency_vector
[0].name
, dependency_vector
[0].reg
,
2111 remainder_bubbles
, bubbles
);
2118 static enum insn_class
2119 get_insn_class_from_type (enum score_insn_type type
)
2121 enum insn_class retval
= (int) FAIL
;
2127 case Rd_rvalueBP_I5
:
2128 case Rd_lvalueBP_I5
:
2139 retval
= INSN_CLASS_16
;
2148 case Rd_rvalueRs_SI10
:
2149 case Rd_lvalueRs_SI10
:
2150 case Rd_rvalueRs_preSI12
:
2151 case Rd_rvalueRs_postSI12
:
2152 case Rd_lvalueRs_preSI12
:
2153 case Rd_lvalueRs_postSI12
:
2155 case Rd_rvalueRs_SI15
:
2156 case Rd_lvalueRs_SI15
:
2165 case OP5_rvalueRs_SI15
:
2166 case I5_Rs_Rs_I5_OP5
:
2167 case x_rvalueRs_post4
:
2168 case Rd_rvalueRs_post4
:
2170 case Rd_lvalueRs_post4
:
2171 case x_lvalueRs_post4
:
2179 retval
= INSN_CLASS_32
;
2182 retval
= INSN_CLASS_PCE
;
2185 retval
= INSN_CLASS_SYN
;
2194 static unsigned long
2195 adjust_paritybit (unsigned long m_code
, enum insn_class
class)
2197 unsigned long result
= 0;
2198 unsigned long m_code_high
= 0;
2199 unsigned long m_code_low
= 0;
2200 unsigned long pb_high
= 0;
2201 unsigned long pb_low
= 0;
2203 if (class == INSN_CLASS_32
)
2205 pb_high
= 0x80000000;
2206 pb_low
= 0x00008000;
2208 else if (class == INSN_CLASS_16
)
2213 else if (class == INSN_CLASS_PCE
)
2216 pb_low
= 0x00008000;
2218 else if (class == INSN_CLASS_SYN
)
2220 /* FIXME. at this time, INSN_CLASS_SYN must be 32 bit, but, instruction type should
2221 be changed if macro instruction has been expanded. */
2222 pb_high
= 0x80000000;
2223 pb_low
= 0x00008000;
2230 m_code_high
= m_code
& 0x3fff8000;
2231 m_code_low
= m_code
& 0x00007fff;
2232 result
= pb_high
| (m_code_high
<< 1) | pb_low
| m_code_low
;
2238 gen_insn_frag (struct score_it
*part_1
, struct score_it
*part_2
)
2241 bfd_boolean pce_p
= FALSE
;
2242 int relaxable_p
= g_opt
;
2244 struct score_it
*inst1
= part_1
;
2245 struct score_it
*inst2
= part_2
;
2246 struct score_it backup_inst1
;
2248 pce_p
= (inst2
) ? TRUE
: FALSE
;
2249 memcpy (&backup_inst1
, inst1
, sizeof (struct score_it
));
2251 /* Adjust instruction opcode and to be relaxed instruction opcode. */
2254 backup_inst1
.instruction
= ((backup_inst1
.instruction
& 0x7FFF) << 15)
2255 | (inst2
->instruction
& 0x7FFF);
2256 backup_inst1
.instruction
= adjust_paritybit (backup_inst1
.instruction
, INSN_CLASS_PCE
);
2257 backup_inst1
.relax_inst
= 0x8000;
2258 backup_inst1
.size
= INSN_SIZE
;
2259 backup_inst1
.relax_size
= 0;
2260 backup_inst1
.type
= Insn_Type_PCE
;
2264 backup_inst1
.instruction
= adjust_paritybit (backup_inst1
.instruction
,
2265 GET_INSN_CLASS (backup_inst1
.type
));
2268 if (backup_inst1
.relax_size
!= 0)
2270 enum insn_class tmp
;
2272 tmp
= (backup_inst1
.size
== INSN_SIZE
) ? INSN_CLASS_16
: INSN_CLASS_32
;
2273 backup_inst1
.relax_inst
= adjust_paritybit (backup_inst1
.relax_inst
, tmp
);
2276 /* Check data dependency. */
2277 handle_dependency (&backup_inst1
);
2279 /* Start a new frag if frag_now is not empty and is not instruction frag, maybe it contains
2280 data produced by .ascii etc. Doing this is to make one instruction per frag. */
2281 if (frag_now_fix () != 0)
2283 if (!frag_now
->tc_frag_data
.is_insn
)
2284 frag_wane (frag_now
);
2289 /* Here, we must call frag_grow in order to keep the instruction frag type is
2290 rs_machine_dependent.
2291 For, frag_var may change frag_now->fr_type to rs_fill by calling frag_grow which
2292 acturally will call frag_wane.
2293 Calling frag_grow first will create a new frag_now which free size is 20 that is enough
2297 p
= frag_more (backup_inst1
.size
);
2298 md_number_to_chars (p
, backup_inst1
.instruction
, backup_inst1
.size
);
2301 dwarf2_emit_insn (backup_inst1
.size
);
2304 /* Generate fixup structure. */
2307 if (inst1
->reloc
.type
!= BFD_RELOC_NONE
)
2308 fix_new_score (frag_now
, p
- frag_now
->fr_literal
,
2309 inst1
->size
, &inst1
->reloc
.exp
,
2310 inst1
->reloc
.pc_rel
, inst1
->reloc
.type
);
2312 if (inst2
->reloc
.type
!= BFD_RELOC_NONE
)
2313 fix_new_score (frag_now
, p
- frag_now
->fr_literal
+ 2,
2314 inst2
->size
, &inst2
->reloc
.exp
, inst2
->reloc
.pc_rel
, inst2
->reloc
.type
);
2318 if (backup_inst1
.reloc
.type
!= BFD_RELOC_NONE
)
2319 fix_new_score (frag_now
, p
- frag_now
->fr_literal
,
2320 backup_inst1
.size
, &backup_inst1
.reloc
.exp
,
2321 backup_inst1
.reloc
.pc_rel
, backup_inst1
.reloc
.type
);
2324 /* relax_size may be 2, 4, 12 or 0, 0 indicates no relaxation. */
2325 relaxable_p
&= (backup_inst1
.relax_size
!= 0);
2326 relax_size
= relaxable_p
? backup_inst1
.relax_size
: 0;
2328 p
= frag_var (rs_machine_dependent
, relax_size
+ RELAX_PAD_BYTE
, 0,
2329 RELAX_ENCODE (backup_inst1
.size
, backup_inst1
.relax_size
,
2330 backup_inst1
.type
, 0, 0, relaxable_p
),
2331 backup_inst1
.reloc
.exp
.X_add_symbol
, 0, NULL
);
2334 md_number_to_chars (p
, backup_inst1
.relax_inst
, relax_size
);
2336 memcpy (inst1
, &backup_inst1
, sizeof (struct score_it
));
2340 parse_16_32_inst (char *insnstr
, bfd_boolean gen_frag_p
)
2344 char *operator = insnstr
;
2345 const struct asm_opcode
*opcode
;
2347 /* Parse operator and operands. */
2348 skip_whitespace (operator);
2350 for (p
= operator; *p
!= '\0'; p
++)
2351 if ((*p
== ' ') || (*p
== '!'))
2360 opcode
= (const struct asm_opcode
*) hash_find (score_ops_hsh
, operator);
2363 memset (&inst
, '\0', sizeof (inst
));
2364 sprintf (inst
.str
, "%s", insnstr
);
2367 inst
.instruction
= opcode
->value
;
2368 inst
.relax_inst
= opcode
->relax_value
;
2369 inst
.type
= opcode
->type
;
2370 inst
.size
= GET_INSN_SIZE (inst
.type
);
2371 inst
.relax_size
= 0;
2373 sprintf (inst
.name
, "%s", opcode
->template);
2374 strcpy (inst
.reg
, "");
2376 inst
.reloc
.type
= BFD_RELOC_NONE
;
2378 (*opcode
->parms
) (p
);
2380 /* It indicates current instruction is a macro instruction if inst.bwarn equals -1. */
2381 if ((inst
.bwarn
!= -1) && (!inst
.error
) && (gen_frag_p
))
2382 gen_insn_frag (&inst
, NULL
);
2385 inst
.error
= _("unrecognized opcode");
2389 append_insn (char *str
, bfd_boolean gen_frag_p
)
2391 int retval
= SUCCESS
;
2393 parse_16_32_inst (str
, gen_frag_p
);
2397 retval
= (int) FAIL
;
2398 as_bad ("%s -- `%s'", inst
.error
, inst
.str
);
2405 /* Handle mv! reg_high, reg_low;
2406 mv! reg_low, reg_high;
2407 mv! reg_low, reg_low; */
2409 do16_mv_rdrs (char *str
)
2413 char *backupstr
= NULL
;
2416 skip_whitespace (str
);
2418 if ((reg_rd
= reg_required_here (&str
, 8, REG_TYPE_SCORE
)) == (int) FAIL
2419 || skip_past_comma (&str
) == (int) FAIL
2420 || (reg_rs
= reg_required_here (&str
, 4, REG_TYPE_SCORE
)) == (int) FAIL
2421 || end_of_line (str
) == (int) FAIL
)
2427 /* Case 1 : mv! or mlfh!. */
2432 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 20)
2433 | (((inst
.instruction
>> 4) & 0xf) << 15) | (0xf << 10);
2434 inst
.relax_size
= 4;
2438 char append_str
[MAX_LITERAL_POOL_SIZE
];
2440 sprintf (append_str
, "mlfh! %s", backupstr
);
2441 if (append_insn (append_str
, TRUE
) == (int) FAIL
)
2443 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
2447 /* Case 2 : mhfl!. */
2452 SET_INSN_ERROR (BAD_ARGS
);
2457 char append_str
[MAX_LITERAL_POOL_SIZE
];
2459 sprintf (append_str
, "mhfl! %s", backupstr
);
2460 if (append_insn (append_str
, TRUE
) == (int) FAIL
)
2463 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
2471 do16_rdi4 (char *str
)
2473 skip_whitespace (str
);
2475 if (reglow_required_here (&str
, 8) == (int) FAIL
2476 || skip_past_comma (&str
) == (int) FAIL
2477 || data_op2 (&str
, 3, _IMM4
) == (int) FAIL
2478 || end_of_line (str
) == (int) FAIL
)
2484 if (((inst
.instruction
>> 3) & 0x10) == 0) /* for judge is addei or subei : bit 5 =0 : addei */
2486 if (((inst
.instruction
>> 3) & 0xf) != 0xf)
2488 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 20)
2489 | ((1 << ((inst
.instruction
>> 3) & 0xf)) << 1);
2490 inst
.relax_size
= 4;
2494 inst
.relax_inst
= 0x8000;
2499 if (((inst
.instruction
>> 3) & 0xf) != 0xf)
2501 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 20)
2502 | (((-(1 << ((inst
.instruction
>> 3) & 0xf))) & 0xffff) << 1);
2503 inst
.relax_size
= 4;
2507 inst
.relax_inst
= 0x8000;
2514 do16_rdi5 (char *str
)
2516 skip_whitespace (str
);
2518 if (reglow_required_here (&str
, 8) == (int) FAIL
2519 || skip_past_comma (&str
) == (int) FAIL
2520 || data_op2 (&str
, 3, _IMM5
) == (int) FAIL
2521 || end_of_line (str
) == (int) FAIL
)
2525 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 20)
2526 | (((inst
.instruction
>> 8) & 0xf) << 15) | (((inst
.instruction
>> 3) & 0x1f) << 10);
2527 inst
.relax_size
= 4;
2533 do16_xi5 (char *str
)
2535 skip_whitespace (str
);
2537 if (data_op2 (&str
, 3, _IMM5
) == (int) FAIL
|| end_of_line (str
) == (int) FAIL
)
2541 inst
.relax_inst
|= (((inst
.instruction
>> 3) & 0x1f) << 15);
2542 inst
.relax_size
= 4;
2546 /* Check that an immediate is word alignment or half word alignment.
2547 If so, convert it to the right format. */
2549 validate_immediate_align (int val
, unsigned int data_type
)
2551 if (data_type
== _IMM5_RSHIFT_1
)
2555 inst
.error
= _("address offset must be half word alignment");
2559 else if ((data_type
== _IMM5_RSHIFT_2
) || (data_type
== _IMM10_RSHIFT_2
))
2563 inst
.error
= _("address offset must be word alignment");
2572 exp_ldst_offset (char **str
, int shift
, unsigned int data_type
)
2578 if ((*dataptr
== '0') && (*(dataptr
+ 1) == 'x')
2579 && (data_type
!= _SIMM16_LA
)
2580 && (data_type
!= _VALUE_HI16
)
2581 && (data_type
!= _VALUE_LO16
)
2582 && (data_type
!= _IMM16
)
2583 && (data_type
!= _IMM15
)
2584 && (data_type
!= _IMM14
)
2585 && (data_type
!= _IMM4
)
2586 && (data_type
!= _IMM5
)
2587 && (data_type
!= _IMM8
)
2588 && (data_type
!= _IMM5_RSHIFT_1
)
2589 && (data_type
!= _IMM5_RSHIFT_2
)
2590 && (data_type
!= _SIMM14_NEG
)
2591 && (data_type
!= _IMM10_RSHIFT_2
))
2596 if (my_get_expression (&inst
.reloc
.exp
, str
) == (int) FAIL
)
2599 if (inst
.reloc
.exp
.X_op
== O_constant
)
2601 /* Need to check the immediate align. */
2602 int value
= validate_immediate_align (inst
.reloc
.exp
.X_add_number
, data_type
);
2604 if (value
== (int) FAIL
)
2607 value
= validate_immediate (inst
.reloc
.exp
.X_add_number
, data_type
);
2608 if (value
== (int) FAIL
)
2614 "invalid constant: %d bit expression not in range %d..%d",
2615 score_df_range
[data_type
].bits
,
2616 score_df_range
[data_type
].range
[0], score_df_range
[data_type
].range
[1]);
2619 "invalid constant: %d bit expression not in range %d..%d",
2620 score_df_range
[data_type
- 24].bits
,
2621 score_df_range
[data_type
- 24].range
[0], score_df_range
[data_type
- 24].range
[1]);
2622 inst
.error
= _(err_msg
);
2626 if (data_type
== _IMM5_RSHIFT_1
)
2630 else if ((data_type
== _IMM5_RSHIFT_2
) || (data_type
== _IMM10_RSHIFT_2
))
2635 if (score_df_range
[data_type
].range
[0] != 0)
2637 value
&= (1 << score_df_range
[data_type
].bits
) - 1;
2640 inst
.instruction
|= value
<< shift
;
2644 inst
.reloc
.pc_rel
= 0;
2651 do_ldst_insn (char *str
)
2663 skip_whitespace (str
);
2665 if (((conflict_reg
= reg_required_here (&str
, 20, REG_TYPE_SCORE
)) == (int) FAIL
)
2666 || (skip_past_comma (&str
) == (int) FAIL
))
2669 /* ld/sw rD, [rA, simm15] ld/sw rD, [rA]+, simm12 ld/sw rD, [rA, simm12]+. */
2673 skip_whitespace (str
);
2675 if ((reg
= reg_required_here (&str
, 15, REG_TYPE_SCORE
)) == (int) FAIL
)
2678 /* Conflicts can occur on stores as well as loads. */
2679 conflict_reg
= (conflict_reg
== reg
);
2680 skip_whitespace (str
);
2681 temp
= str
+ 1; /* The latter will process decimal/hex expression. */
2683 /* ld/sw rD, [rA]+, simm12 ld/sw rD, [rA]+. */
2690 /* ld/sw rD, [rA]+, simm12. */
2691 if (skip_past_comma (&str
) == SUCCESS
)
2693 if ((exp_ldst_offset (&str
, 3, _SIMM12
) == (int) FAIL
)
2694 || (end_of_line (str
) == (int) FAIL
))
2699 unsigned int ldst_func
= inst
.instruction
& OPC_PSEUDOLDST_MASK
;
2701 if ((ldst_func
== INSN_LH
)
2702 || (ldst_func
== INSN_LHU
)
2703 || (ldst_func
== INSN_LW
)
2704 || (ldst_func
== INSN_LB
)
2705 || (ldst_func
== INSN_LBU
))
2707 inst
.error
= _("register same as write-back base");
2712 ldst_idx
= inst
.instruction
& OPC_PSEUDOLDST_MASK
;
2713 inst
.instruction
&= ~OPC_PSEUDOLDST_MASK
;
2714 inst
.instruction
|= score_ldst_insns
[ldst_idx
* 3 + LDST_POST
].value
;
2716 /* lw rD, [rA]+, 4 convert to pop rD, [rA]. */
2717 if ((inst
.instruction
& 0x3e000007) == 0x0e000000)
2719 /* rs = r0-r7, offset = 4 */
2720 if ((((inst
.instruction
>> 15) & 0x18) == 0)
2721 && (((inst
.instruction
>> 3) & 0xfff) == 4))
2723 /* Relax to pophi. */
2724 if ((((inst
.instruction
>> 20) & 0x10) == 0x10))
2726 inst
.relax_inst
= 0x0000200a | (((inst
.instruction
>> 20) & 0xf)
2728 (((inst
.instruction
>> 15) & 0x7) << 4);
2733 inst
.relax_inst
= 0x0000200a | (((inst
.instruction
>> 20) & 0xf)
2735 (((inst
.instruction
>> 15) & 0x7) << 4);
2737 inst
.relax_size
= 2;
2742 /* ld/sw rD, [rA]+ convert to ld/sw rD, [rA, 0]+. */
2745 SET_INSN_ERROR (NULL
);
2746 if (end_of_line (str
) == (int) FAIL
)
2752 value
= validate_immediate (inst
.reloc
.exp
.X_add_number
, _SIMM12
);
2753 value
&= (1 << score_df_range
[_SIMM12
].bits
) - 1;
2754 ldst_idx
= inst
.instruction
& OPC_PSEUDOLDST_MASK
;
2755 inst
.instruction
&= ~OPC_PSEUDOLDST_MASK
;
2756 inst
.instruction
|= score_ldst_insns
[ldst_idx
* 3 + pre_inc
].value
;
2757 inst
.instruction
|= value
<< 3;
2758 inst
.relax_inst
= 0x8000;
2762 /* ld/sw rD, [rA] convert to ld/sw rD, [rA, simm15]. */
2765 if (end_of_line (str
) == (int) FAIL
)
2768 ldst_idx
= inst
.instruction
& OPC_PSEUDOLDST_MASK
;
2769 inst
.instruction
&= ~OPC_PSEUDOLDST_MASK
;
2770 inst
.instruction
|= score_ldst_insns
[ldst_idx
* 3 + LDST_NOUPDATE
].value
;
2772 /* lbu rd, [rs] -> lbu! rd, [rs] */
2773 if (ldst_idx
== INSN_LBU
)
2775 inst
.relax_inst
= INSN16_LBU
;
2777 else if (ldst_idx
== INSN_LH
)
2779 inst
.relax_inst
= INSN16_LH
;
2781 else if (ldst_idx
== INSN_LW
)
2783 inst
.relax_inst
= INSN16_LW
;
2785 else if (ldst_idx
== INSN_SB
)
2787 inst
.relax_inst
= INSN16_SB
;
2789 else if (ldst_idx
== INSN_SH
)
2791 inst
.relax_inst
= INSN16_SH
;
2793 else if (ldst_idx
== INSN_SW
)
2795 inst
.relax_inst
= INSN16_SW
;
2799 inst
.relax_inst
= 0x8000;
2802 /* lw/lh/lbu/sw/sh/sb, offset = 0, relax to 16 bit instruction. */
2803 if ((ldst_idx
== INSN_LBU
)
2804 || (ldst_idx
== INSN_LH
)
2805 || (ldst_idx
== INSN_LW
)
2806 || (ldst_idx
== INSN_SB
) || (ldst_idx
== INSN_SH
) || (ldst_idx
== INSN_SW
))
2808 if ((((inst
.instruction
>> 15) & 0x10) == 0) && (((inst
.instruction
>> 20) & 0x10) == 0))
2810 inst
.relax_inst
|= (2 << 12) | (((inst
.instruction
>> 20) & 0xf) << 8) |
2811 (((inst
.instruction
>> 15) & 0xf) << 4);
2812 inst
.relax_size
= 2;
2819 /* ld/sw rD, [rA, simm15] ld/sw rD, [rA, simm12]+. */
2822 if (skip_past_comma (&str
) == (int) FAIL
)
2824 inst
.error
= _("pre-indexed expression expected");
2828 if (my_get_expression (&inst
.reloc
.exp
, &str
) == (int) FAIL
)
2831 skip_whitespace (str
);
2834 inst
.error
= _("missing ]");
2838 skip_whitespace (str
);
2839 /* ld/sw rD, [rA, simm12]+. */
2846 unsigned int ldst_func
= inst
.instruction
& OPC_PSEUDOLDST_MASK
;
2848 if ((ldst_func
== INSN_LH
)
2849 || (ldst_func
== INSN_LHU
)
2850 || (ldst_func
== INSN_LW
)
2851 || (ldst_func
== INSN_LB
)
2852 || (ldst_func
== INSN_LBU
))
2854 inst
.error
= _("register same as write-back base");
2860 if (end_of_line (str
) == (int) FAIL
)
2863 if (inst
.reloc
.exp
.X_op
== O_constant
)
2866 unsigned int data_type
;
2869 data_type
= _SIMM12
;
2871 data_type
= _SIMM15
;
2874 if ((*dataptr
== '0') && (*(dataptr
+ 1) == 'x')
2875 && (data_type
!= _SIMM16_LA
)
2876 && (data_type
!= _VALUE_HI16
)
2877 && (data_type
!= _VALUE_LO16
)
2878 && (data_type
!= _IMM16
)
2879 && (data_type
!= _IMM15
)
2880 && (data_type
!= _IMM14
)
2881 && (data_type
!= _IMM4
)
2882 && (data_type
!= _IMM5
)
2883 && (data_type
!= _IMM8
)
2884 && (data_type
!= _IMM5_RSHIFT_1
)
2885 && (data_type
!= _IMM5_RSHIFT_2
)
2886 && (data_type
!= _SIMM14_NEG
)
2887 && (data_type
!= _IMM10_RSHIFT_2
))
2892 value
= validate_immediate (inst
.reloc
.exp
.X_add_number
, data_type
);
2893 if (value
== (int) FAIL
)
2899 "invalid constant: %d bit expression not in range %d..%d",
2900 score_df_range
[data_type
].bits
,
2901 score_df_range
[data_type
].range
[0], score_df_range
[data_type
].range
[1]);
2904 "invalid constant: %d bit expression not in range %d..%d",
2905 score_df_range
[data_type
- 24].bits
,
2906 score_df_range
[data_type
- 24].range
[0],
2907 score_df_range
[data_type
- 24].range
[1]);
2908 inst
.error
= _(err_msg
);
2912 value
&= (1 << score_df_range
[data_type
].bits
) - 1;
2913 ldst_idx
= inst
.instruction
& OPC_PSEUDOLDST_MASK
;
2914 inst
.instruction
&= ~OPC_PSEUDOLDST_MASK
;
2915 inst
.instruction
|= score_ldst_insns
[ldst_idx
* 3 + pre_inc
].value
;
2917 inst
.instruction
|= value
<< 3;
2919 inst
.instruction
|= value
;
2921 /* lw rD, [rA, simm15] */
2922 if ((inst
.instruction
& 0x3e000000) == 0x20000000)
2924 /* Both rD and rA are in [r0 - r15]. */
2925 if ((((inst
.instruction
>> 15) & 0x10) == 0)
2926 && (((inst
.instruction
>> 20) & 0x10) == 0))
2928 /* simm15 = 0, lw -> lw!. */
2929 if ((inst
.instruction
& 0x7fff) == 0)
2931 inst
.relax_inst
|= (((inst
.instruction
>> 15) & 0xf) << 4)
2932 | (((inst
.instruction
>> 20) & 0xf) << 8);
2933 inst
.relax_size
= 2;
2935 /* rA = r2, lw -> lwp!. */
2936 else if ((((inst
.instruction
>> 15) & 0xf) == 2)
2937 && ((inst
.instruction
& 0x3) == 0)
2938 && ((inst
.instruction
& 0x7fff) < 128))
2940 inst
.relax_inst
= 0x7000 | (((inst
.instruction
>> 20) & 0xf) << 8)
2941 | (((inst
.instruction
& 0x7fff) >> 2) << 3);
2942 inst
.relax_size
= 2;
2946 inst
.relax_inst
= 0x8000;
2951 inst
.relax_inst
= 0x8000;
2954 /* sw rD, [rA, simm15] */
2955 else if ((inst
.instruction
& 0x3e000000) == 0x28000000)
2957 /* Both rD and rA are in [r0 - r15]. */
2958 if ((((inst
.instruction
>> 15) & 0x10) == 0) && (((inst
.instruction
>> 20) & 0x10) == 0))
2960 /* simm15 = 0, sw -> sw!. */
2961 if ((inst
.instruction
& 0x7fff) == 0)
2963 inst
.relax_inst
|= (((inst
.instruction
>> 15) & 0xf) << 4)
2964 | (((inst
.instruction
>> 20) & 0xf) << 8);
2965 inst
.relax_size
= 2;
2967 /* rA = r2, sw -> swp!. */
2968 else if ((((inst
.instruction
>> 15) & 0xf) == 2)
2969 && ((inst
.instruction
& 0x3) == 0)
2970 && ((inst
.instruction
& 0x7fff) < 128))
2972 inst
.relax_inst
= 0x7004 | (((inst
.instruction
>> 20) & 0xf) << 8)
2973 | (((inst
.instruction
& 0x7fff) >> 2) << 3);
2974 inst
.relax_size
= 2;
2978 inst
.relax_inst
= 0x8000;
2983 inst
.relax_inst
= 0x8000;
2986 /* sw rD, [rA, simm15]+ sw pre. */
2987 else if ((inst
.instruction
& 0x3e000007) == 0x06000004)
2989 /* rA is in [r0 - r7], and simm15 = -4. */
2990 if ((((inst
.instruction
>> 15) & 0x18) == 0)
2991 && (((inst
.instruction
>> 3) & 0xfff) == 0xffc))
2993 /* sw -> pushhi!. */
2994 if ((((inst
.instruction
>> 20) & 0x10) == 0x10))
2996 inst
.relax_inst
= 0x0000200e | (((inst
.instruction
>> 20) & 0xf) << 8)
2997 | 1 << 7 | (((inst
.instruction
>> 15) & 0x7) << 4);
2998 inst
.relax_size
= 2;
3003 inst
.relax_inst
= 0x0000200e | (((inst
.instruction
>> 20) & 0xf) << 8)
3004 | 0 << 7 | (((inst
.instruction
>> 15) & 0x7) << 4);
3005 inst
.relax_size
= 2;
3010 inst
.relax_inst
= 0x8000;
3013 /* lh rD, [rA, simm15] */
3014 else if ((inst
.instruction
& 0x3e000000) == 0x22000000)
3016 /* Both rD and rA are in [r0 - r15]. */
3017 if ((((inst
.instruction
>> 15) & 0x10) == 0) && (((inst
.instruction
>> 20) & 0x10) == 0))
3019 /* simm15 = 0, lh -> lh!. */
3020 if ((inst
.instruction
& 0x7fff) == 0)
3022 inst
.relax_inst
|= (((inst
.instruction
>> 15) & 0xf) << 4)
3023 | (((inst
.instruction
>> 20) & 0xf) << 8);
3024 inst
.relax_size
= 2;
3026 /* rA = r2, lh -> lhp!. */
3027 else if ((((inst
.instruction
>> 15) & 0xf) == 2)
3028 && ((inst
.instruction
& 0x1) == 0)
3029 && ((inst
.instruction
& 0x7fff) < 64))
3031 inst
.relax_inst
= 0x7001 | (((inst
.instruction
>> 20) & 0xf) << 8)
3032 | (((inst
.instruction
& 0x7fff) >> 1) << 3);
3033 inst
.relax_size
= 2;
3037 inst
.relax_inst
= 0x8000;
3042 inst
.relax_inst
= 0x8000;
3045 /* sh rD, [rA, simm15] */
3046 else if ((inst
.instruction
& 0x3e000000) == 0x2a000000)
3048 /* Both rD and rA are in [r0 - r15]. */
3049 if ((((inst
.instruction
>> 15) & 0x10) == 0) && (((inst
.instruction
>> 20) & 0x10) == 0))
3051 /* simm15 = 0, sh -> sh!. */
3052 if ((inst
.instruction
& 0x7fff) == 0)
3054 inst
.relax_inst
|= (((inst
.instruction
>> 15) & 0xf) << 4)
3055 | (((inst
.instruction
>> 20) & 0xf) << 8);
3056 inst
.relax_size
= 2;
3058 /* rA = r2, sh -> shp!. */
3059 else if ((((inst
.instruction
>> 15) & 0xf) == 2)
3060 && ((inst
.instruction
& 0x1) == 0)
3061 && ((inst
.instruction
& 0x7fff) < 64))
3063 inst
.relax_inst
= 0x7005 | (((inst
.instruction
>> 20) & 0xf) << 8)
3064 | (((inst
.instruction
& 0x7fff) >> 1) << 3);
3065 inst
.relax_size
= 2;
3069 inst
.relax_inst
= 0x8000;
3074 inst
.relax_inst
= 0x8000;
3077 /* lbu rD, [rA, simm15] */
3078 else if ((inst
.instruction
& 0x3e000000) == 0x2c000000)
3080 /* Both rD and rA are in [r0 - r15]. */
3081 if ((((inst
.instruction
>> 15) & 0x10) == 0) && (((inst
.instruction
>> 20) & 0x10) == 0))
3083 /* simm15 = 0, lbu -> lbu!. */
3084 if ((inst
.instruction
& 0x7fff) == 0)
3086 inst
.relax_inst
|= (((inst
.instruction
>> 15) & 0xf) << 4)
3087 | (((inst
.instruction
>> 20) & 0xf) << 8);
3088 inst
.relax_size
= 2;
3090 /* rA = r2, lbu -> lbup!. */
3091 else if ((((inst
.instruction
>> 15) & 0xf) == 2)
3092 && ((inst
.instruction
& 0x7fff) < 32))
3094 inst
.relax_inst
= 0x7003 | (((inst
.instruction
>> 20) & 0xf) << 8)
3095 | ((inst
.instruction
& 0x7fff) << 3);
3096 inst
.relax_size
= 2;
3100 inst
.relax_inst
= 0x8000;
3105 inst
.relax_inst
= 0x8000;
3108 /* sb rD, [rA, simm15] */
3109 else if ((inst
.instruction
& 0x3e000000) == 0x2e000000)
3111 /* Both rD and rA are in [r0 - r15]. */
3112 if ((((inst
.instruction
>> 15) & 0x10) == 0) && (((inst
.instruction
>> 20) & 0x10) == 0))
3114 /* simm15 = 0, sb -> sb!. */
3115 if ((inst
.instruction
& 0x7fff) == 0)
3117 inst
.relax_inst
|= (((inst
.instruction
>> 15) & 0xf) << 4)
3118 | (((inst
.instruction
>> 20) & 0xf) << 8);
3119 inst
.relax_size
= 2;
3121 /* rA = r2, sb -> sb!. */
3122 else if ((((inst
.instruction
>> 15) & 0xf) == 2)
3123 && ((inst
.instruction
& 0x7fff) < 32))
3125 inst
.relax_inst
= 0x7007 | (((inst
.instruction
>> 20) & 0xf) << 8)
3126 | ((inst
.instruction
& 0x7fff) << 3);
3127 inst
.relax_size
= 2;
3131 inst
.relax_inst
= 0x8000;
3136 inst
.relax_inst
= 0x8000;
3141 inst
.relax_inst
= 0x8000;
3148 /* FIXME: may set error, for there is no ld/sw rD, [rA, label] */
3149 inst
.reloc
.pc_rel
= 0;
3155 inst
.error
= BAD_ARGS
;
3162 do_cache (char *str
)
3164 skip_whitespace (str
);
3166 if ((data_op2 (&str
, 20, _IMM5
) == (int) FAIL
) || (skip_past_comma (&str
) == (int) FAIL
))
3174 cache_op
= (inst
.instruction
>> 20) & 0x1F;
3175 sprintf (inst
.name
, "cache %d", cache_op
);
3181 skip_whitespace (str
);
3183 if (reg_required_here (&str
, 15, REG_TYPE_SCORE
) == (int) FAIL
)
3186 skip_whitespace (str
);
3188 /* cache op, [rA] */
3189 if (skip_past_comma (&str
) == (int) FAIL
)
3191 SET_INSN_ERROR (NULL
);
3194 inst
.error
= _("missing ]");
3199 /* cache op, [rA, simm15] */
3202 if (exp_ldst_offset (&str
, 0, _SIMM15
) == (int) FAIL
)
3207 skip_whitespace (str
);
3210 inst
.error
= _("missing ]");
3215 if (end_of_line (str
) == (int) FAIL
)
3220 inst
.error
= BAD_ARGS
;
3225 do_crdcrscrsimm5 (char *str
)
3230 skip_whitespace (str
);
3232 if (reg_required_here (&str
, 20, REG_TYPE_SCORE_CR
) == (int) FAIL
3233 || skip_past_comma (&str
) == (int) FAIL
3234 || reg_required_here (&str
, 15, REG_TYPE_SCORE_CR
) == (int) FAIL
3235 || skip_past_comma (&str
) == (int) FAIL
3236 || reg_required_here (&str
, 10, REG_TYPE_SCORE_CR
) == (int) FAIL
3237 || skip_past_comma (&str
) == (int) FAIL
)
3240 /* cop1 cop_code20. */
3241 if (data_op2 (&str
, 5, _IMM20
) == (int) FAIL
)
3246 if (data_op2 (&str
, 5, _IMM5
) == (int) FAIL
)
3253 /* Handle ldc/stc. */
3255 do_ldst_cop (char *str
)
3257 skip_whitespace (str
);
3259 if ((reg_required_here (&str
, 15, REG_TYPE_SCORE_CR
) == (int) FAIL
)
3260 || (skip_past_comma (&str
) == (int) FAIL
))
3266 skip_whitespace (str
);
3268 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) == (int) FAIL
)
3271 skip_whitespace (str
);
3275 if (exp_ldst_offset (&str
, 5, _IMM10_RSHIFT_2
) == (int) FAIL
)
3278 skip_whitespace (str
);
3281 inst
.error
= _("missing ]");
3289 inst
.error
= BAD_ARGS
;
3293 do16_ldst_insn (char *str
)
3295 skip_whitespace (str
);
3297 if ((reglow_required_here (&str
, 8) == (int) FAIL
) || (skip_past_comma (&str
) == (int) FAIL
))
3305 skip_whitespace (str
);
3307 if ((reg
= reglow_required_here (&str
, 4)) == (int) FAIL
)
3310 skip_whitespace (str
);
3313 if (end_of_line (str
) == (int) FAIL
)
3317 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 20)
3318 | (((inst
.instruction
>> 4) & 0xf) << 15);
3319 inst
.relax_size
= 4;
3324 inst
.error
= _("missing ]");
3329 inst
.error
= BAD_ARGS
;
3333 /* Handle lbup!/lhp!/ldiu!/lwp!/sbp!/shp!/swp!. */
3335 do16_ldst_imm_insn (char *str
)
3337 char data_exp
[MAX_LITERAL_POOL_SIZE
];
3339 char *dataptr
= NULL
, *pp
= NULL
;
3341 int assign_data
= (int) FAIL
;
3342 unsigned int ldst_func
;
3344 skip_whitespace (str
);
3346 if (((reg_rd
= reglow_required_here (&str
, 8)) == (int) FAIL
)
3347 || (skip_past_comma (&str
) == (int) FAIL
))
3350 skip_whitespace (str
);
3353 while ((*dataptr
!= '\0') && (*dataptr
!= '|') && (cnt
<= MAX_LITERAL_POOL_SIZE
))
3355 data_exp
[cnt
] = *dataptr
;
3360 data_exp
[cnt
] = '\0';
3365 ldst_func
= inst
.instruction
& LDST16_RI_MASK
;
3366 if (ldst_func
== N16_LIU
)
3367 assign_data
= exp_ldst_offset (&pp
, 0, _IMM8
);
3368 else if (ldst_func
== N16_LHP
|| ldst_func
== N16_SHP
)
3369 assign_data
= exp_ldst_offset (&pp
, 3, _IMM5_RSHIFT_1
);
3370 else if (ldst_func
== N16_LWP
|| ldst_func
== N16_SWP
)
3371 assign_data
= exp_ldst_offset (&pp
, 3, _IMM5_RSHIFT_2
);
3373 assign_data
= exp_ldst_offset (&pp
, 3, _IMM5
);
3375 if ((assign_data
== (int) FAIL
) || (end_of_line (pp
) == (int) FAIL
))
3379 if ((inst
.instruction
& 0x7000) == N16_LIU
)
3381 inst
.relax_inst
|= ((inst
.instruction
>> 8) & 0xf) << 20
3382 | ((inst
.instruction
& 0xff) << 1);
3384 else if (((inst
.instruction
& 0x7007) == N16_LHP
)
3385 || ((inst
.instruction
& 0x7007) == N16_SHP
))
3387 inst
.relax_inst
|= ((inst
.instruction
>> 8) & 0xf) << 20 | 2 << 15
3388 | (((inst
.instruction
>> 3) & 0x1f) << 1);
3390 else if (((inst
.instruction
& 0x7007) == N16_LWP
)
3391 || ((inst
.instruction
& 0x7007) == N16_SWP
))
3393 inst
.relax_inst
|= ((inst
.instruction
>> 8) & 0xf) << 20 | 2 << 15
3394 | (((inst
.instruction
>> 3) & 0x1f) << 2);
3396 else if (((inst
.instruction
& 0x7007) == N16_LBUP
)
3397 || ((inst
.instruction
& 0x7007) == N16_SBP
))
3399 inst
.relax_inst
|= ((inst
.instruction
>> 8) & 0xf) << 20 | 2 << 15
3400 | (((inst
.instruction
>> 3) & 0x1f));
3403 inst
.relax_size
= 4;
3408 do16_push_pop (char *str
)
3413 skip_whitespace (str
);
3414 if (((reg_rd
= reg_required_here (&str
, 8, REG_TYPE_SCORE
)) == (int) FAIL
)
3415 || (skip_past_comma (&str
) == (int) FAIL
))
3421 /* reg_required_here will change bit 12 of opcode, so we must restore bit 12. */
3422 inst
.instruction
&= ~(1 << 12);
3424 inst
.instruction
|= H_bit_mask
<< 7;
3431 skip_whitespace (str
);
3432 if ((reg
= reg_required_here (&str
, 4, REG_TYPE_SCORE
)) == (int) FAIL
)
3437 inst
.error
= _("base register nums are over 3 bit");
3442 skip_whitespace (str
);
3443 if ((*str
++ != ']') || (end_of_line (str
) == (int) FAIL
))
3446 inst
.error
= _("missing ]");
3452 if ((inst
.instruction
& 0xf) == 0xa)
3456 inst
.relax_inst
|= ((((inst
.instruction
>> 8) & 0xf) | 0x10) << 20)
3457 | (((inst
.instruction
>> 4) & 0x7) << 15) | (4 << 3);
3461 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 20)
3462 | (((inst
.instruction
>> 4) & 0x7) << 15) | (4 << 3);
3470 inst
.relax_inst
|= ((((inst
.instruction
>> 8) & 0xf) | 0x10) << 20)
3471 | (((inst
.instruction
>> 4) & 0x7) << 15) | (((-4) & 0xfff) << 3);
3475 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 20)
3476 | (((inst
.instruction
>> 4) & 0x7) << 15) | (((-4) & 0xfff) << 3);
3479 inst
.relax_size
= 4;
3483 inst
.error
= BAD_ARGS
;
3487 /* Handle lcb/lcw/lce/scb/scw/sce. */
3489 do_ldst_unalign (char *str
)
3493 if (university_version
== 1)
3495 inst
.error
= ERR_FOR_SCORE5U_ATOMIC
;
3499 skip_whitespace (str
);
3501 /* lcb/scb [rA]+. */
3505 skip_whitespace (str
);
3507 if (reg_required_here (&str
, 15, REG_TYPE_SCORE
) == (int) FAIL
)
3514 inst
.error
= _("missing +");
3520 inst
.error
= _("missing ]");
3524 if (end_of_line (str
) == (int) FAIL
)
3527 /* lcw/lce/scb/sce rD, [rA]+. */
3530 if (((conflict_reg
= reg_required_here (&str
, 20, REG_TYPE_SCORE
)) == (int) FAIL
)
3531 || (skip_past_comma (&str
) == (int) FAIL
))
3536 skip_whitespace (str
);
3541 skip_whitespace (str
);
3542 if ((reg
= reg_required_here (&str
, 15, REG_TYPE_SCORE
)) == (int) FAIL
)
3547 /* Conflicts can occur on stores as well as loads. */
3548 conflict_reg
= (conflict_reg
== reg
);
3549 skip_whitespace (str
);
3552 unsigned int ldst_func
= inst
.instruction
& LDST_UNALIGN_MASK
;
3558 as_warn (_("%s register same as write-back base"),
3559 ((ldst_func
& UA_LCE
) || (ldst_func
& UA_LCW
)
3560 ? _("destination") : _("source")));
3565 inst
.error
= _("missing +");
3569 if (end_of_line (str
) == (int) FAIL
)
3574 inst
.error
= _("missing ]");
3580 inst
.error
= BAD_ARGS
;
3586 /* Handle alw/asw. */
3588 do_ldst_atomic (char *str
)
3590 if (university_version
== 1)
3592 inst
.error
= ERR_FOR_SCORE5U_ATOMIC
;
3596 skip_whitespace (str
);
3598 if ((reg_required_here (&str
, 20, REG_TYPE_SCORE
) == (int) FAIL
)
3599 || (skip_past_comma (&str
) == (int) FAIL
))
3606 skip_whitespace (str
);
3611 skip_whitespace (str
);
3612 if ((reg
= reg_required_here (&str
, 15, REG_TYPE_SCORE
)) == (int) FAIL
)
3617 skip_whitespace (str
);
3620 inst
.error
= _("missing ]");
3627 inst
.error
= BAD_ARGS
;
3632 build_relax_frag (struct score_it fix_insts
[RELAX_INST_NUM
], int fix_num ATTRIBUTE_UNUSED
,
3633 struct score_it var_insts
[RELAX_INST_NUM
], int var_num
,
3634 symbolS
*add_symbol
)
3639 fixS
*cur_fixp
= NULL
;
3641 struct score_it inst_main
;
3643 memcpy (&inst_main
, &fix_insts
[0], sizeof (struct score_it
));
3645 /* Adjust instruction opcode and to be relaxed instruction opcode. */
3646 inst_main
.instruction
= adjust_paritybit (inst_main
.instruction
, GET_INSN_CLASS (inst_main
.type
));
3647 inst_main
.type
= Insn_PIC
;
3649 for (i
= 0; i
< var_num
; i
++)
3651 inst_main
.relax_size
+= var_insts
[i
].size
;
3652 var_insts
[i
].instruction
= adjust_paritybit (var_insts
[i
].instruction
,
3653 GET_INSN_CLASS (var_insts
[i
].type
));
3656 /* Check data dependency. */
3657 handle_dependency (&inst_main
);
3659 /* Start a new frag if frag_now is not empty. */
3660 if (frag_now_fix () != 0)
3662 if (!frag_now
->tc_frag_data
.is_insn
)
3664 frag_wane (frag_now
);
3670 /* Write fr_fix part. */
3671 p
= frag_more (inst_main
.size
);
3672 md_number_to_chars (p
, inst_main
.instruction
, inst_main
.size
);
3674 if (inst_main
.reloc
.type
!= BFD_RELOC_NONE
)
3675 fixp
= fix_new_score (frag_now
, p
- frag_now
->fr_literal
, inst_main
.size
,
3676 &inst_main
.reloc
.exp
, inst_main
.reloc
.pc_rel
, inst_main
.reloc
.type
);
3678 frag_now
->tc_frag_data
.fixp
= fixp
;
3679 cur_fixp
= frag_now
->tc_frag_data
.fixp
;
3682 dwarf2_emit_insn (inst_main
.size
);
3685 where
= p
- frag_now
->fr_literal
+ inst_main
.size
;
3686 for (i
= 0; i
< var_num
; i
++)
3689 where
+= var_insts
[i
- 1].size
;
3691 if (var_insts
[i
].reloc
.type
!= BFD_RELOC_NONE
)
3693 fixp
= fix_new_score (frag_now
, where
, var_insts
[i
].size
,
3694 &var_insts
[i
].reloc
.exp
, var_insts
[i
].reloc
.pc_rel
,
3695 var_insts
[i
].reloc
.type
);
3700 cur_fixp
->fx_next
= fixp
;
3701 cur_fixp
= cur_fixp
->fx_next
;
3705 frag_now
->tc_frag_data
.fixp
= fixp
;
3706 cur_fixp
= frag_now
->tc_frag_data
.fixp
;
3712 p
= frag_var (rs_machine_dependent
, inst_main
.relax_size
+ RELAX_PAD_BYTE
, 0,
3713 RELAX_ENCODE (inst_main
.size
, inst_main
.relax_size
, inst_main
.type
,
3714 0, inst_main
.size
, 0), add_symbol
, 0, NULL
);
3716 /* Write fr_var part.
3717 no calling gen_insn_frag, no fixS will be generated. */
3718 for (i
= 0; i
< var_num
; i
++)
3720 md_number_to_chars (p
, var_insts
[i
].instruction
, var_insts
[i
].size
);
3721 p
+= var_insts
[i
].size
;
3723 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
3727 /* Build a relax frag for la instruction when generating PIC,
3728 external symbol first and local symbol second. */
3731 build_la_pic (int reg_rd
, expressionS exp
)
3733 symbolS
*add_symbol
= exp
.X_add_symbol
;
3734 offsetT add_number
= exp
.X_add_number
;
3735 struct score_it fix_insts
[RELAX_INST_NUM
];
3736 struct score_it var_insts
[RELAX_INST_NUM
];
3739 char tmp
[MAX_LITERAL_POOL_SIZE
];
3745 if (add_number
== 0)
3750 /* For an external symbol, only one insn is generated;
3751 For a local symbol, two insns are generated. */
3753 For an external symbol: lw rD, <sym>($gp)
3754 (BFD_RELOC_SCORE_GOT15 or BFD_RELOC_SCORE_CALL15) */
3755 sprintf (tmp
, "lw_pic r%d, %s", reg_rd
, add_symbol
->bsym
->name
);
3756 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
3759 if (reg_rd
== PIC_CALL_REG
)
3760 inst
.reloc
.type
= BFD_RELOC_SCORE_CALL15
;
3761 memcpy (&fix_insts
[0], &inst
, sizeof (struct score_it
));
3764 For a local symbol :
3765 lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15)
3766 addi rD, <sym> (BFD_RELOC_GOT_LO16) */
3767 inst
.reloc
.type
= BFD_RELOC_SCORE_GOT15
;
3768 memcpy (&var_insts
[0], &inst
, sizeof (struct score_it
));
3769 sprintf (tmp
, "addi_s_pic r%d, %s", reg_rd
, add_symbol
->bsym
->name
);
3770 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
3773 memcpy (&var_insts
[1], &inst
, sizeof (struct score_it
));
3774 build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
3776 else if (add_number
>= -0x8000 && add_number
<= 0x7fff)
3778 /* Insn 1: lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15) */
3779 sprintf (tmp
, "lw_pic r%d, %s", reg_rd
, add_symbol
->bsym
->name
);
3780 if (append_insn (tmp
, TRUE
) == (int) FAIL
)
3787 For an external symbol: addi rD, <constant> */
3788 sprintf (tmp
, "addi r%d, %d", reg_rd
, (int)add_number
);
3789 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
3792 memcpy (&fix_insts
[0], &inst
, sizeof (struct score_it
));
3795 For a local symbol: addi rD, <sym>+<constant> (BFD_RELOC_GOT_LO16) */
3796 sprintf (tmp
, "addi_s_pic r%d, %s + %d", reg_rd
, add_symbol
->bsym
->name
, (int)add_number
);
3797 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
3800 memcpy (&var_insts
[0], &inst
, sizeof (struct score_it
));
3801 build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
3805 int hi
= (add_number
>> 16) & 0x0000FFFF;
3806 int lo
= add_number
& 0x0000FFFF;
3808 /* Insn 1: lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15) */
3809 sprintf (tmp
, "lw_pic r%d, %s", reg_rd
, add_symbol
->bsym
->name
);
3810 if (append_insn (tmp
, TRUE
) == (int) FAIL
)
3817 For an external symbol: ldis r1, HI%<constant> */
3818 sprintf (tmp
, "ldis %s, %d", "r1", hi
);
3819 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
3822 memcpy (&fix_insts
[0], &inst
, sizeof (struct score_it
));
3825 For a local symbol: ldis r1, HI%<constant>
3826 but, if lo is outof 16 bit, make hi plus 1 */
3827 if ((lo
< -0x8000) || (lo
> 0x7fff))
3831 sprintf (tmp
, "ldis_pic %s, %d", "r1", hi
);
3832 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
3835 memcpy (&var_insts
[0], &inst
, sizeof (struct score_it
));
3836 build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
3842 For an external symbol: ori r1, LO%<constant> */
3843 sprintf (tmp
, "ori %s, %d", "r1", lo
);
3844 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
3847 memcpy (&fix_insts
[0], &inst
, sizeof (struct score_it
));
3850 For a local symbol: addi r1, <sym>+LO%<constant> (BFD_RELOC_GOT_LO16) */
3851 sprintf (tmp
, "addi_u_pic %s, %s + %d", "r1", add_symbol
->bsym
->name
, lo
);
3852 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
3855 memcpy (&var_insts
[0], &inst
, sizeof (struct score_it
));
3856 build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
3858 /* Insn 4: add rD, rD, r1 */
3859 sprintf (tmp
, "add r%d, r%d, %s", reg_rd
, reg_rd
, "r1");
3860 if (append_insn (tmp
, TRUE
) == (int) FAIL
)
3863 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
3872 do_macro_la_rdi32 (char *str
)
3876 skip_whitespace (str
);
3877 if ((reg_rd
= reg_required_here (&str
, 20, REG_TYPE_SCORE
)) == (int) FAIL
3878 || skip_past_comma (&str
) == (int) FAIL
)
3884 char append_str
[MAX_LITERAL_POOL_SIZE
];
3885 char *keep_data
= str
;
3887 /* la rd, simm16. */
3888 if (data_op2 (&str
, 1, _SIMM16_LA
) != (int) FAIL
)
3893 /* la rd, imm32 or la rd, label. */
3896 SET_INSN_ERROR (NULL
);
3898 if ((data_op2 (&str
, 1, _VALUE_HI16
) == (int) FAIL
)
3899 || (end_of_line (str
) == (int) FAIL
))
3905 if ((score_pic
== NO_PIC
) || (!inst
.reloc
.exp
.X_add_symbol
))
3907 sprintf (append_str
, "ld_i32hi r%d, %s", reg_rd
, keep_data
);
3908 if (append_insn (append_str
, TRUE
) == (int) FAIL
)
3911 sprintf (append_str
, "ld_i32lo r%d, %s", reg_rd
, keep_data
);
3912 if (append_insn (append_str
, TRUE
) == (int) FAIL
)
3917 assert (inst
.reloc
.exp
.X_add_symbol
);
3918 build_la_pic (reg_rd
, inst
.reloc
.exp
);
3921 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
3930 do_macro_li_rdi32 (char *str
){
3934 skip_whitespace (str
);
3935 if ((reg_rd
= reg_required_here (&str
, 20, REG_TYPE_SCORE
)) == (int) FAIL
3936 || skip_past_comma (&str
) == (int) FAIL
)
3942 char *keep_data
= str
;
3944 /* li rd, simm16. */
3945 if (data_op2 (&str
, 1, _SIMM16_LA
) != (int) FAIL
)
3953 char append_str
[MAX_LITERAL_POOL_SIZE
];
3957 if ((data_op2 (&str
, 1, _VALUE_HI16
) == (int) FAIL
)
3958 || (end_of_line (str
) == (int) FAIL
))
3962 else if (inst
.reloc
.exp
.X_add_symbol
)
3964 inst
.error
= _("li rd label isn't correct instruction form");
3969 sprintf (append_str
, "ld_i32hi r%d, %s", reg_rd
, keep_data
);
3971 if (append_insn (append_str
, TRUE
) == (int) FAIL
)
3975 sprintf (append_str
, "ld_i32lo r%d, %s", reg_rd
, keep_data
);
3976 if (append_insn (append_str
, TRUE
) == (int) FAIL
)
3979 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
3987 /* Handle mul/mulu/div/divu/rem/remu. */
3989 do_macro_mul_rdrsrs (char *str
)
3995 char append_str
[MAX_LITERAL_POOL_SIZE
];
3997 if (university_version
== 1)
3998 as_warn ("%s", ERR_FOR_SCORE5U_MUL_DIV
);
4000 strcpy (append_str
, str
);
4001 backupstr
= append_str
;
4002 skip_whitespace (backupstr
);
4003 if (((reg_rd
= reg_required_here (&backupstr
, -1, REG_TYPE_SCORE
)) == (int) FAIL
)
4004 || (skip_past_comma (&backupstr
) == (int) FAIL
)
4005 || ((reg_rs1
= reg_required_here (&backupstr
, -1, REG_TYPE_SCORE
)) == (int) FAIL
))
4007 inst
.error
= BAD_ARGS
;
4011 if (skip_past_comma (&backupstr
) == (int) FAIL
)
4013 /* rem/remu rA, rB is error format. */
4014 if (strcmp (inst
.name
, "rem") == 0 || strcmp (inst
.name
, "remu") == 0)
4016 SET_INSN_ERROR (BAD_ARGS
);
4020 SET_INSN_ERROR (NULL
);
4027 SET_INSN_ERROR (NULL
);
4028 if (((reg_rs2
= reg_required_here (&backupstr
, -1, REG_TYPE_SCORE
)) == (int) FAIL
)
4029 || (end_of_line (backupstr
) == (int) FAIL
))
4035 char append_str1
[MAX_LITERAL_POOL_SIZE
];
4037 if (strcmp (inst
.name
, "rem") == 0)
4039 sprintf (append_str
, "%s r%d, r%d", "mul", reg_rs1
, reg_rs2
);
4040 sprintf (append_str1
, "mfceh r%d", reg_rd
);
4042 else if (strcmp (inst
.name
, "remu") == 0)
4044 sprintf (append_str
, "%s r%d, r%d", "mulu", reg_rs1
, reg_rs2
);
4045 sprintf (append_str1
, "mfceh r%d", reg_rd
);
4049 sprintf (append_str
, "%s r%d, r%d", inst
.name
, reg_rs1
, reg_rs2
);
4050 sprintf (append_str1
, "mfcel r%d", reg_rd
);
4053 /* Output mul/mulu or div/divu or rem/remu. */
4054 if (append_insn (append_str
, TRUE
) == (int) FAIL
)
4057 /* Output mfcel or mfceh. */
4058 if (append_insn (append_str1
, TRUE
) == (int) FAIL
)
4061 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4068 exp_macro_ldst_abs (char *str
)
4071 char *backupstr
, *tmp
;
4072 char append_str
[MAX_LITERAL_POOL_SIZE
];
4073 char verifystr
[MAX_LITERAL_POOL_SIZE
];
4074 struct score_it inst_backup
;
4079 memcpy (&inst_backup
, &inst
, sizeof (struct score_it
));
4081 strcpy (verifystr
, str
);
4082 backupstr
= verifystr
;
4083 skip_whitespace (backupstr
);
4084 if ((reg_rd
= reg_required_here (&backupstr
, -1, REG_TYPE_SCORE
)) == (int) FAIL
)
4088 if (skip_past_comma (&backupstr
) == (int) FAIL
)
4092 sprintf (append_str
, "li r1 %s", backupstr
);
4093 append_insn (append_str
, TRUE
);
4095 memcpy (&inst
, &inst_backup
, sizeof (struct score_it
));
4096 sprintf (append_str
, " r%d, [r1,0]", reg_rd
);
4097 do_ldst_insn (append_str
);
4103 nopic_need_relax (symbolS
* sym
, int before_relaxing
)
4107 else if (USE_GLOBAL_POINTER_OPT
&& g_switch_value
> 0)
4109 const char *symname
;
4110 const char *segname
;
4112 /* Find out whether this symbol can be referenced off the $gp
4113 register. It can be if it is smaller than the -G size or if
4114 it is in the .sdata or .sbss section. Certain symbols can
4115 not be referenced off the $gp, although it appears as though
4117 symname
= S_GET_NAME (sym
);
4118 if (symname
!= (const char *)NULL
4119 && (strcmp (symname
, "eprol") == 0
4120 || strcmp (symname
, "etext") == 0
4121 || strcmp (symname
, "_gp") == 0
4122 || strcmp (symname
, "edata") == 0
4123 || strcmp (symname
, "_fbss") == 0
4124 || strcmp (symname
, "_fdata") == 0
4125 || strcmp (symname
, "_ftext") == 0
4126 || strcmp (symname
, "end") == 0
4127 || strcmp (symname
, GP_DISP_LABEL
) == 0))
4131 else if ((!S_IS_DEFINED (sym
) || S_IS_COMMON (sym
)) && (0
4132 /* We must defer this decision until after the whole file has been read,
4133 since there might be a .extern after the first use of this symbol. */
4135 && S_GET_VALUE (sym
) == 0)
4136 || (S_GET_VALUE (sym
) != 0
4137 && S_GET_VALUE (sym
) <= g_switch_value
)))
4142 segname
= segment_name (S_GET_SEGMENT (sym
));
4143 return (strcmp (segname
, ".sdata") != 0
4144 && strcmp (segname
, ".sbss") != 0
4145 && strncmp (segname
, ".sdata.", 7) != 0
4146 && strncmp (segname
, ".gnu.linkonce.s.", 16) != 0);
4148 /* We are not optimizing for the $gp register. */
4153 /* Build a relax frag for lw/st instruction when generating PIC,
4154 external symbol first and local symbol second. */
4157 build_lwst_pic (int reg_rd
, expressionS exp
, const char *insn_name
)
4159 symbolS
*add_symbol
= exp
.X_add_symbol
;
4160 int add_number
= exp
.X_add_number
;
4161 struct score_it fix_insts
[RELAX_INST_NUM
];
4162 struct score_it var_insts
[RELAX_INST_NUM
];
4165 char tmp
[MAX_LITERAL_POOL_SIZE
];
4171 if ((add_number
== 0) || (add_number
>= -0x8000 && add_number
<= 0x7fff))
4176 /* For an external symbol, two insns are generated;
4177 For a local symbol, three insns are generated. */
4179 For an external symbol: lw rD, <sym>($gp)
4180 (BFD_RELOC_SCORE_GOT15) */
4181 sprintf (tmp
, "lw_pic %s, %s", "r1", add_symbol
->bsym
->name
);
4182 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
4185 memcpy (&fix_insts
[0], &inst
, sizeof (struct score_it
));
4188 For a local symbol :
4189 lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15)
4190 addi rD, <sym> (BFD_RELOC_GOT_LO16) */
4191 inst
.reloc
.type
= BFD_RELOC_SCORE_GOT15
;
4192 memcpy (&var_insts
[0], &inst
, sizeof (struct score_it
));
4193 sprintf (tmp
, "addi_s_pic %s, %s", "r1", add_symbol
->bsym
->name
);
4194 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
4197 memcpy (&var_insts
[1], &inst
, sizeof (struct score_it
));
4198 build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
4200 /* Insn 2 or Insn 3: lw/st rD, [r1, constant] */
4201 sprintf (tmp
, "%s r%d, [%s, %d]", insn_name
, reg_rd
, "r1", add_number
);
4202 if (append_insn (tmp
, TRUE
) == (int) FAIL
)
4205 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4210 inst
.error
= _("PIC code offset overflow (max 16 signed bits)");
4218 do_macro_ldst_label (char *str
)
4226 char *absolute_value
;
4227 char append_str
[3][MAX_LITERAL_POOL_SIZE
];
4228 char verifystr
[MAX_LITERAL_POOL_SIZE
];
4229 struct score_it inst_backup
;
4230 struct score_it inst_expand
[3];
4231 struct score_it inst_main
;
4233 memcpy (&inst_backup
, &inst
, sizeof (struct score_it
));
4234 strcpy (verifystr
, str
);
4235 backup_str
= verifystr
;
4237 skip_whitespace (backup_str
);
4238 if ((reg_rd
= reg_required_here (&backup_str
, -1, REG_TYPE_SCORE
)) == (int) FAIL
)
4241 if (skip_past_comma (&backup_str
) == (int) FAIL
)
4244 label_str
= backup_str
;
4246 /* Ld/st rD, [rA, imm] ld/st rD, [rA]+, imm ld/st rD, [rA, imm]+. */
4247 if (*backup_str
== '[')
4249 inst
.type
= Rd_rvalueRs_preSI12
;
4254 /* Ld/st rD, imm. */
4255 absolute_value
= backup_str
;
4256 inst
.type
= Rd_rvalueRs_SI15
;
4257 if ((my_get_expression (&inst
.reloc
.exp
, &backup_str
) == (int) FAIL
)
4258 || (validate_immediate (inst
.reloc
.exp
.X_add_number
, _VALUE
) == (int) FAIL
)
4259 || (end_of_line (backup_str
) == (int) FAIL
))
4265 if (inst
.reloc
.exp
.X_add_symbol
== 0)
4267 memcpy (&inst
, &inst_backup
, sizeof (struct score_it
));
4268 exp_macro_ldst_abs (str
);
4273 /* Ld/st rD, label. */
4274 inst
.type
= Rd_rvalueRs_SI15
;
4275 backup_str
= absolute_value
;
4276 if ((data_op2 (&backup_str
, 1, _GP_IMM15
) == (int) FAIL
)
4277 || (end_of_line (backup_str
) == (int) FAIL
))
4283 if (inst
.reloc
.exp
.X_add_symbol
== 0)
4286 inst
.error
= BAD_ARGS
;
4291 if (score_pic
== PIC
)
4294 ldst_idx
= inst
.instruction
& OPC_PSEUDOLDST_MASK
;
4295 build_lwst_pic (reg_rd
, inst
.reloc
.exp
, score_ldst_insns
[ldst_idx
* 3 + 0].template);
4300 if ((inst
.reloc
.exp
.X_add_number
<= 0x3fff)
4301 && (inst
.reloc
.exp
.X_add_number
>= -0x4000)
4302 && (!nopic_need_relax (inst
.reloc
.exp
.X_add_symbol
, 1)))
4306 /* Assign the real opcode. */
4307 ldst_idx
= inst
.instruction
& OPC_PSEUDOLDST_MASK
;
4308 inst
.instruction
&= ~OPC_PSEUDOLDST_MASK
;
4309 inst
.instruction
|= score_ldst_insns
[ldst_idx
* 3 + 0].value
;
4310 inst
.instruction
|= reg_rd
<< 20;
4311 inst
.instruction
|= GP
<< 15;
4312 inst
.relax_inst
= 0x8000;
4313 inst
.relax_size
= 0;
4320 memcpy (&inst_main
, &inst
, sizeof (struct score_it
));
4324 /* Determine which instructions should be output. */
4325 sprintf (append_str
[0], "ld_i32hi r1, %s", label_str
);
4326 sprintf (append_str
[1], "ld_i32lo r1, %s", label_str
);
4327 sprintf (append_str
[2], "%s r%d, [r1, 0]", inst_backup
.name
, reg_rd
);
4329 /* Generate three instructions.
4331 ld/st rd, [r1, 0] */
4332 for (i
= 0; i
< 3; i
++)
4334 if (append_insn (append_str
[i
], FALSE
) == (int) FAIL
)
4337 memcpy (&inst_expand
[i
], &inst
, sizeof (struct score_it
));
4344 /* Adjust instruction opcode and to be relaxed instruction opcode. */
4345 inst_main
.instruction
= adjust_paritybit (inst_main
.instruction
, GET_INSN_CLASS (inst_main
.type
));
4346 inst_main
.relax_size
= inst_expand
[0].size
+ inst_expand
[1].size
+ inst_expand
[2].size
;
4347 inst_main
.type
= Insn_GP
;
4349 for (i
= 0; i
< 3; i
++)
4350 inst_expand
[i
].instruction
= adjust_paritybit (inst_expand
[i
].instruction
4351 , GET_INSN_CLASS (inst_expand
[i
].type
));
4353 /* Check data dependency. */
4354 handle_dependency (&inst_main
);
4356 /* Start a new frag if frag_now is not empty. */
4357 if (frag_now_fix () != 0)
4359 if (!frag_now
->tc_frag_data
.is_insn
)
4360 frag_wane (frag_now
);
4366 /* Write fr_fix part. */
4367 p
= frag_more (inst_main
.size
);
4368 md_number_to_chars (p
, inst_main
.instruction
, inst_main
.size
);
4370 if (inst_main
.reloc
.type
!= BFD_RELOC_NONE
)
4372 fix_new_score (frag_now
, p
- frag_now
->fr_literal
, inst_main
.size
,
4373 &inst_main
.reloc
.exp
, inst_main
.reloc
.pc_rel
, inst_main
.reloc
.type
);
4377 dwarf2_emit_insn (inst_main
.size
);
4380 /* GP instruction can not do optimization, only can do relax between
4381 1 instruction and 3 instructions. */
4382 p
= frag_var (rs_machine_dependent
, inst_main
.relax_size
+ RELAX_PAD_BYTE
, 0,
4383 RELAX_ENCODE (inst_main
.size
, inst_main
.relax_size
, inst_main
.type
, 0, 4, 0),
4384 inst_main
.reloc
.exp
.X_add_symbol
, 0, NULL
);
4386 /* Write fr_var part.
4387 no calling gen_insn_frag, no fixS will be generated. */
4388 md_number_to_chars (p
, inst_expand
[0].instruction
, inst_expand
[0].size
);
4389 p
+= inst_expand
[0].size
;
4390 md_number_to_chars (p
, inst_expand
[1].instruction
, inst_expand
[1].size
);
4391 p
+= inst_expand
[1].size
;
4392 md_number_to_chars (p
, inst_expand
[2].instruction
, inst_expand
[2].size
);
4396 gen_insn_frag (&inst_expand
[0], NULL
);
4397 gen_insn_frag (&inst_expand
[1], NULL
);
4398 gen_insn_frag (&inst_expand
[2], NULL
);
4402 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4407 do_lw_pic (char *str
)
4411 skip_whitespace (str
);
4412 if (((reg_rd
= reg_required_here (&str
, 20, REG_TYPE_SCORE
)) == (int) FAIL
)
4413 || (skip_past_comma (&str
) == (int) FAIL
)
4414 || (my_get_expression (&inst
.reloc
.exp
, &str
) == (int) FAIL
)
4415 || (end_of_line (str
) == (int) FAIL
))
4421 if (inst
.reloc
.exp
.X_add_symbol
== 0)
4424 inst
.error
= BAD_ARGS
;
4429 inst
.instruction
|= GP
<< 15;
4430 inst
.reloc
.type
= BFD_RELOC_SCORE_GOT15
;
4435 do_empty (char *str
)
4438 if (university_version
== 1)
4440 if (((inst
.instruction
& 0x3e0003ff) == 0x0c000004)
4441 || ((inst
.instruction
& 0x3e0003ff) == 0x0c000024)
4442 || ((inst
.instruction
& 0x3e0003ff) == 0x0c000044)
4443 || ((inst
.instruction
& 0x3e0003ff) == 0x0c000064))
4445 inst
.error
= ERR_FOR_SCORE5U_MMU
;
4449 if (end_of_line (str
) == (int) FAIL
)
4452 if (inst
.relax_inst
!= 0x8000)
4454 if (inst
.type
== NO_OPD
)
4456 inst
.relax_size
= 2;
4460 inst
.relax_size
= 4;
4471 skip_whitespace (str
);
4472 if (my_get_expression (&inst
.reloc
.exp
, &str
) == (int) FAIL
4473 || end_of_line (str
) == (int) FAIL
)
4476 if (inst
.reloc
.exp
.X_add_symbol
== 0)
4478 inst
.error
= _("lacking label ");
4482 if (((inst
.reloc
.exp
.X_add_number
& 0xff000000) != 0)
4483 && ((inst
.reloc
.exp
.X_add_number
& 0xff000000) != 0xff000000))
4485 sprintf (err_msg
, "invalid constant: 25 bit expression not in range -2^24..2^24");
4486 inst
.error
= _(err_msg
);
4490 save_in
= input_line_pointer
;
4491 input_line_pointer
= str
;
4492 inst
.reloc
.type
= BFD_RELOC_SCORE_JMP
;
4493 inst
.reloc
.pc_rel
= 1;
4494 input_line_pointer
= save_in
;
4498 do16_jump (char *str
)
4500 skip_whitespace (str
);
4501 if (my_get_expression (&inst
.reloc
.exp
, &str
) == (int) FAIL
4502 || end_of_line (str
) == (int) FAIL
)
4506 else if (inst
.reloc
.exp
.X_add_symbol
== 0)
4508 inst
.error
= _("lacking label ");
4511 else if (((inst
.reloc
.exp
.X_add_number
& 0xfffff800) != 0)
4512 && ((inst
.reloc
.exp
.X_add_number
& 0xfffff800) != 0xfffff800))
4514 inst
.error
= _("invalid constant: 12 bit expression not in range -2^11..2^11");
4518 inst
.reloc
.type
= BFD_RELOC_SCORE16_JMP
;
4519 inst
.reloc
.pc_rel
= 1;
4523 do_branch (char *str
)
4525 unsigned long abs_value
= 0;
4527 if (my_get_expression (&inst
.reloc
.exp
, &str
) == (int) FAIL
4528 || end_of_line (str
) == (int) FAIL
)
4532 else if (inst
.reloc
.exp
.X_add_symbol
== 0)
4534 inst
.error
= _("lacking label ");
4537 else if (((inst
.reloc
.exp
.X_add_number
& 0xff000000) != 0)
4538 && ((inst
.reloc
.exp
.X_add_number
& 0xff000000) != 0xff000000))
4540 inst
.error
= "invalid constant: 20 bit expression not in range -2^19..2^19";
4544 inst
.reloc
.type
= BFD_RELOC_SCORE_BRANCH
;
4545 inst
.reloc
.pc_rel
= 1;
4547 /* Branch 32 offset field : 20 bit, 16 bit branch offset field : 8 bit. */
4548 inst
.instruction
|= (inst
.reloc
.exp
.X_add_number
& 0x3fe) | ((inst
.reloc
.exp
.X_add_number
& 0xffc00) << 5);
4550 /* Compute 16 bit branch instruction. */
4551 if ((inst
.relax_inst
!= 0x8000) && (abs_value
& 0xfffffe00) == 0)
4553 inst
.relax_inst
|= (((inst
.instruction
>> 10) & 0xf) << 8);
4554 inst
.relax_inst
|= ((inst
.reloc
.exp
.X_add_number
>> 1) & 0xff);
4555 inst
.relax_size
= 2;
4559 inst
.relax_inst
= 0x8000;
4564 do16_branch (char *str
)
4566 if ((my_get_expression (&inst
.reloc
.exp
, &str
) == (int) FAIL
4567 || end_of_line (str
) == (int) FAIL
))
4571 else if (inst
.reloc
.exp
.X_add_symbol
== 0)
4573 inst
.error
= _("lacking label");
4575 else if (((inst
.reloc
.exp
.X_add_number
& 0xffffff00) != 0)
4576 && ((inst
.reloc
.exp
.X_add_number
& 0xffffff00) != 0xffffff00))
4578 inst
.error
= _("invalid constant: 9 bit expression not in range -2^8..2^8");
4582 inst
.reloc
.type
= BFD_RELOC_SCORE16_BRANCH
;
4583 inst
.reloc
.pc_rel
= 1;
4584 inst
.instruction
|= ((inst
.reloc
.exp
.X_add_number
>> 1) & 0xff);
4588 /* Iterate over the base tables to create the instruction patterns. */
4590 build_score_ops_hsh (void)
4593 static struct obstack insn_obstack
;
4595 obstack_begin (&insn_obstack
, 4000);
4596 for (i
= 0; i
< sizeof (score_insns
) / sizeof (struct asm_opcode
); i
++)
4598 const struct asm_opcode
*insn
= score_insns
+ i
;
4599 unsigned len
= strlen (insn
->template);
4600 struct asm_opcode
*new;
4602 new = obstack_alloc (&insn_obstack
, sizeof (struct asm_opcode
));
4603 template = obstack_alloc (&insn_obstack
, len
+ 1);
4605 strcpy (template, insn
->template);
4606 new->template = template;
4607 new->parms
= insn
->parms
;
4608 new->value
= insn
->value
;
4609 new->relax_value
= insn
->relax_value
;
4610 new->type
= insn
->type
;
4611 new->bitmask
= insn
->bitmask
;
4612 hash_insert (score_ops_hsh
, new->template, (void *) new);
4617 build_dependency_insn_hsh (void)
4620 static struct obstack dependency_obstack
;
4622 obstack_begin (&dependency_obstack
, 4000);
4623 for (i
= 0; i
< sizeof (insn_to_dependency_table
) / sizeof (insn_to_dependency_table
[0]); i
++)
4625 const struct insn_to_dependency
*tmp
= insn_to_dependency_table
+ i
;
4626 unsigned len
= strlen (tmp
->insn_name
);
4627 struct insn_to_dependency
*new;
4629 new = obstack_alloc (&dependency_obstack
, sizeof (struct insn_to_dependency
));
4630 new->insn_name
= obstack_alloc (&dependency_obstack
, len
+ 1);
4632 strcpy (new->insn_name
, tmp
->insn_name
);
4633 new->type
= tmp
->type
;
4634 hash_insert (dependency_insn_hsh
, new->insn_name
, (void *) new);
4638 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
4639 for use in the a.out file, and stores them in the array pointed to by buf.
4640 This knows about the endian-ness of the target machine and does
4641 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
4642 2 (short) and 4 (long) Floating numbers are put out as a series of
4643 LITTLENUMS (shorts, here at least). */
4646 md_number_to_chars (char *buf
, valueT val
, int n
)
4648 if (target_big_endian
)
4649 number_to_chars_bigendian (buf
, val
, n
);
4651 number_to_chars_littleendian (buf
, val
, n
);
4655 md_chars_to_number (char *buf
, int n
)
4658 unsigned char *where
= (unsigned char *)buf
;
4660 if (target_big_endian
)
4665 result
|= (*where
++ & 255);
4673 result
|= (where
[n
] & 255);
4680 /* Turn a string in input_line_pointer into a floating point constant
4681 of type TYPE, and store the appropriate bytes in *LITP. The number
4682 of LITTLENUMS emitted is stored in *SIZEP. An error message is
4683 returned, or NULL on OK.
4685 Note that fp constants aren't represent in the normal way on the ARM.
4686 In big endian mode, things are as expected. However, in little endian
4687 mode fp constants are big-endian word-wise, and little-endian byte-wise
4688 within the words. For example, (double) 1.1 in big endian mode is
4689 the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
4690 the byte sequence 99 99 f1 3f 9a 99 99 99. */
4693 md_atof (int type
, char *litP
, int *sizeP
)
4696 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
4722 return _("bad call to MD_ATOF()");
4725 t
= atof_ieee (input_line_pointer
, type
, words
);
4727 input_line_pointer
= t
;
4730 if (target_big_endian
)
4732 for (i
= 0; i
< prec
; i
++)
4734 md_number_to_chars (litP
, (valueT
) words
[i
], 2);
4740 for (i
= 0; i
< prec
; i
+= 2)
4742 md_number_to_chars (litP
, (valueT
) words
[i
+ 1], 2);
4743 md_number_to_chars (litP
+ 2, (valueT
) words
[i
], 2);
4751 /* Return true if the given symbol should be considered local for PIC. */
4754 pic_need_relax (symbolS
*sym
, asection
*segtype
)
4757 bfd_boolean linkonce
;
4759 /* Handle the case of a symbol equated to another symbol. */
4760 while (symbol_equated_reloc_p (sym
))
4764 /* It's possible to get a loop here in a badly written
4766 n
= symbol_get_value_expression (sym
)->X_add_symbol
;
4772 symsec
= S_GET_SEGMENT (sym
);
4774 /* duplicate the test for LINK_ONCE sections as in adjust_reloc_syms */
4776 if (symsec
!= segtype
&& ! S_IS_LOCAL (sym
))
4778 if ((bfd_get_section_flags (stdoutput
, symsec
) & SEC_LINK_ONCE
) != 0)
4781 /* The GNU toolchain uses an extension for ELF: a section
4782 beginning with the magic string .gnu.linkonce is a linkonce
4784 if (strncmp (segment_name (symsec
), ".gnu.linkonce",
4785 sizeof ".gnu.linkonce" - 1) == 0)
4789 /* This must duplicate the test in adjust_reloc_syms. */
4790 return (symsec
!= &bfd_und_section
4791 && symsec
!= &bfd_abs_section
4792 && ! bfd_is_com_section (symsec
)
4795 /* A global or weak symbol is treated as external. */
4796 && (OUTPUT_FLAVOR
!= bfd_target_elf_flavour
4797 || (! S_IS_WEAK (sym
) && ! S_IS_EXTERNAL (sym
)))
4803 judge_size_before_relax (fragS
* fragp
, asection
*sec
)
4807 if (score_pic
== NO_PIC
)
4808 change
= nopic_need_relax (fragp
->fr_symbol
, 0);
4810 change
= pic_need_relax (fragp
->fr_symbol
, sec
);
4814 /* Only at the first time determining whether GP instruction relax should be done,
4815 return the difference between insntruction size and instruction relax size. */
4816 if (fragp
->fr_opcode
== NULL
)
4818 fragp
->fr_fix
= RELAX_NEW (fragp
->fr_subtype
);
4819 fragp
->fr_opcode
= fragp
->fr_literal
+ RELAX_RELOC1 (fragp
->fr_subtype
);
4820 return RELAX_NEW (fragp
->fr_subtype
) - RELAX_OLD (fragp
->fr_subtype
);
4827 /* In this function, we determine whether GP instruction should do relaxation,
4828 for the label being against was known now.
4829 Doing this here but not in md_relax_frag() can induce iteration times
4830 in stage of doing relax. */
4832 md_estimate_size_before_relax (fragS
* fragp
, asection
* sec ATTRIBUTE_UNUSED
)
4834 if ((RELAX_TYPE (fragp
->fr_subtype
) == Insn_GP
)
4835 || (RELAX_TYPE (fragp
->fr_subtype
) == Insn_PIC
))
4836 return judge_size_before_relax (fragp
, sec
);
4842 b32_relax_to_b16 (fragS
* fragp
)
4845 int relaxable_p
= 0;
4848 int frag_addr
= fragp
->fr_address
+ fragp
->insn_addr
;
4850 addressT symbol_address
= 0;
4853 unsigned long value
;
4854 unsigned long abs_value
;
4856 /* FIXME : here may be able to modify better .
4857 I don't know how to get the fragp's section ,
4858 so in relax stage , it may be wrong to calculate the symbol's offset when the frag's section
4859 is different from the symbol's. */
4861 old
= RELAX_OLD (fragp
->fr_subtype
);
4862 new = RELAX_NEW (fragp
->fr_subtype
);
4863 relaxable_p
= RELAX_OPT (fragp
->fr_subtype
);
4865 s
= fragp
->fr_symbol
;
4866 /* b/bl immediate */
4872 symbol_address
= (addressT
) s
->sy_frag
->fr_address
;
4875 value
= md_chars_to_number (fragp
->fr_literal
, INSN_SIZE
);
4877 /* b 32's offset : 20 bit, b 16's tolerate field : 0xff. */
4878 offset
= ((value
& 0x3ff0000) >> 6) | (value
& 0x3fe);
4879 if ((offset
& 0x80000) == 0x80000)
4880 offset
|= 0xfff00000;
4882 abs_value
= offset
+ symbol_address
- frag_addr
;
4883 if ((abs_value
& 0x80000000) == 0x80000000)
4884 abs_value
= 0xffffffff - abs_value
+ 1;
4886 /* Relax branch 32 to branch 16. */
4887 if (relaxable_p
&& (s
->bsym
!= NULL
) && ((abs_value
& 0xffffff00) == 0)
4888 && (S_IS_DEFINED (s
) && !S_IS_COMMON (s
) && !S_IS_EXTERNAL (s
)))
4894 /* Branch 32 can not be relaxed to b 16, so clear OPT bit. */
4895 fragp
->fr_opcode
= NULL
;
4896 fragp
->fr_subtype
= RELAX_OPT_CLEAR (fragp
->fr_subtype
);
4902 /* Main purpose is to determine whether one frag should do relax.
4903 frag->fr_opcode indicates this point. */
4906 score_relax_frag (asection
* sec ATTRIBUTE_UNUSED
, fragS
* fragp
, long stretch ATTRIBUTE_UNUSED
)
4910 int insn_relax_size
;
4911 int do_relax_p
= 0; /* Indicate doing relaxation for this frag. */
4912 int relaxable_p
= 0;
4913 bfd_boolean word_align_p
= FALSE
;
4916 /* If the instruction address is odd, make it half word align first. */
4917 if ((fragp
->fr_address
) % 2 != 0)
4919 if ((fragp
->fr_address
+ fragp
->insn_addr
) % 2 != 0)
4921 fragp
->insn_addr
= 1;
4926 word_align_p
= ((fragp
->fr_address
+ fragp
->insn_addr
) % 4 == 0) ? TRUE
: FALSE
;
4928 /* Get instruction size and relax size after the last relaxation. */
4929 if (fragp
->fr_opcode
)
4931 insn_size
= RELAX_NEW (fragp
->fr_subtype
);
4932 insn_relax_size
= RELAX_OLD (fragp
->fr_subtype
);
4936 insn_size
= RELAX_OLD (fragp
->fr_subtype
);
4937 insn_relax_size
= RELAX_NEW (fragp
->fr_subtype
);
4940 /* Handle specially for GP instruction. for, judge_size_before_relax() has already determine
4941 whether the GP instruction should do relax. */
4942 if ((RELAX_TYPE (fragp
->fr_subtype
) == Insn_GP
)
4943 || (RELAX_TYPE (fragp
->fr_subtype
) == Insn_PIC
))
4947 if (fragp
->insn_addr
< 2)
4949 fragp
->insn_addr
+= 2;
4954 fragp
->insn_addr
-= 2;
4959 if (fragp
->fr_opcode
)
4960 fragp
->fr_fix
= RELAX_NEW (fragp
->fr_subtype
) + fragp
->insn_addr
;
4962 fragp
->fr_fix
= RELAX_OLD (fragp
->fr_subtype
) + fragp
->insn_addr
;
4966 if (RELAX_TYPE (fragp
->fr_subtype
) == PC_DISP19div2
)
4967 b32_relax_to_b16 (fragp
);
4969 relaxable_p
= RELAX_OPT (fragp
->fr_subtype
);
4970 next_fragp
= fragp
->fr_next
;
4971 while ((next_fragp
) && (next_fragp
->fr_type
!= rs_machine_dependent
))
4973 next_fragp
= next_fragp
->fr_next
;
4979 int n_relaxable_p
= 0;
4981 if (next_fragp
->fr_opcode
)
4983 n_insn_size
= RELAX_NEW (next_fragp
->fr_subtype
);
4987 n_insn_size
= RELAX_OLD (next_fragp
->fr_subtype
);
4990 if (RELAX_TYPE (next_fragp
->fr_subtype
) == PC_DISP19div2
)
4991 b32_relax_to_b16 (next_fragp
);
4992 n_relaxable_p
= RELAX_OPT (next_fragp
->fr_subtype
);
4999 if (relaxable_p
&& ((n_insn_size
== 2) || n_relaxable_p
))
5005 else if (insn_size
== 2)
5008 if (relaxable_p
&& (((n_insn_size
== 4) && !n_relaxable_p
) || (n_insn_size
> 4)))
5029 /* Make the 32 bit insturction word align. */
5032 fragp
->insn_addr
+= 2;
5036 else if (insn_size
== 2)
5048 /* Here, try best to do relax regardless fragp->fr_next->fr_type. */
5049 if (word_align_p
== FALSE
)
5051 if (insn_size
% 4 == 0)
5061 fragp
->insn_addr
+= 2;
5072 /* fragp->fr_opcode indicates whether this frag should be relaxed. */
5075 if (fragp
->fr_opcode
)
5077 fragp
->fr_opcode
= NULL
;
5078 /* Guarantee estimate stage is correct. */
5079 fragp
->fr_fix
= RELAX_OLD (fragp
->fr_subtype
);
5080 fragp
->fr_fix
+= fragp
->insn_addr
;
5084 fragp
->fr_opcode
= fragp
->fr_literal
+ RELAX_RELOC1 (fragp
->fr_subtype
);
5085 /* Guarantee estimate stage is correct. */
5086 fragp
->fr_fix
= RELAX_NEW (fragp
->fr_subtype
);
5087 fragp
->fr_fix
+= fragp
->insn_addr
;
5092 if (fragp
->fr_opcode
)
5094 /* Guarantee estimate stage is correct. */
5095 fragp
->fr_fix
= RELAX_NEW (fragp
->fr_subtype
);
5096 fragp
->fr_fix
+= fragp
->insn_addr
;
5100 /* Guarantee estimate stage is correct. */
5101 fragp
->fr_fix
= RELAX_OLD (fragp
->fr_subtype
);
5102 fragp
->fr_fix
+= fragp
->insn_addr
;
5111 md_convert_frag (bfd
* abfd ATTRIBUTE_UNUSED
, segT sec ATTRIBUTE_UNUSED
, fragS
* fragp
)
5118 old
= RELAX_OLD (fragp
->fr_subtype
);
5119 new = RELAX_NEW (fragp
->fr_subtype
);
5121 /* fragp->fr_opcode indicates whether this frag should be relaxed. */
5122 if (fragp
->fr_opcode
== NULL
)
5124 memcpy (backup
, fragp
->fr_literal
, old
);
5125 fragp
->fr_fix
= old
;
5129 memcpy (backup
, fragp
->fr_literal
+ old
, new);
5130 fragp
->fr_fix
= new;
5133 fixp
= fragp
->tc_frag_data
.fixp
;
5134 while (fixp
&& fixp
->fx_frag
== fragp
&& fixp
->fx_where
< old
)
5136 if (fragp
->fr_opcode
)
5138 fixp
= fixp
->fx_next
;
5140 while (fixp
&& fixp
->fx_frag
== fragp
)
5142 if (fragp
->fr_opcode
)
5143 fixp
->fx_where
-= old
+ fragp
->insn_addr
;
5146 fixp
= fixp
->fx_next
;
5149 if (fragp
->insn_addr
)
5151 md_number_to_chars (fragp
->fr_literal
, 0x0, fragp
->insn_addr
);
5153 memcpy (fragp
->fr_literal
+ fragp
->insn_addr
, backup
, fragp
->fr_fix
);
5154 fragp
->fr_fix
+= fragp
->insn_addr
;
5157 /* Implementation of md_frag_check.
5158 Called after md_convert_frag(). */
5161 score_frag_check (fragS
* fragp ATTRIBUTE_UNUSED
)
5163 know (fragp
->insn_addr
<= RELAX_PAD_BYTE
);
5167 score_fix_adjustable (fixS
* fixP
)
5169 if (fixP
->fx_addsy
== NULL
)
5173 else if (OUTPUT_FLAVOR
== bfd_target_elf_flavour
5174 && (S_IS_EXTERNAL (fixP
->fx_addsy
) || S_IS_WEAK (fixP
->fx_addsy
)))
5178 else if (fixP
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
5179 || fixP
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
5187 /* Implementation of TC_VALIDATE_FIX.
5188 Called before md_apply_fix() and after md_convert_frag(). */
5190 score_validate_fix (fixS
*fixP
)
5192 fixP
->fx_where
+= fixP
->fx_frag
->insn_addr
;
5196 md_pcrel_from (fixS
* fixP
)
5201 && (S_GET_SEGMENT (fixP
->fx_addsy
) == undefined_section
)
5202 && (fixP
->fx_subsy
== NULL
))
5208 retval
= fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
5215 score_force_relocation (struct fix
*fixp
)
5219 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
5220 || fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
5221 || fixp
->fx_r_type
== BFD_RELOC_SCORE_JMP
5222 || fixp
->fx_r_type
== BFD_RELOC_SCORE_BRANCH
5223 || fixp
->fx_r_type
== BFD_RELOC_SCORE16_JMP
5224 || fixp
->fx_r_type
== BFD_RELOC_SCORE16_BRANCH
)
5232 /* Round up a section size to the appropriate boundary. */
5234 md_section_align (segT segment ATTRIBUTE_UNUSED
, valueT size
)
5236 int align
= bfd_get_section_alignment (stdoutput
, segment
);
5239 /* We don't need to align ELF sections to the full alignment.
5240 However, Irix 5 may prefer that we align them at least to a 16
5241 byte boundary. We don't bother to align the sections if we are
5242 targeted for an embedded system. */
5243 if (strcmp (TARGET_OS
, "elf") == 0)
5249 return ((size
+ (1 << align
) - 1) & (-1 << align
));
5253 md_apply_fix (fixS
*fixP
, valueT
*valP
, segT seg
)
5255 offsetT value
= *valP
;
5256 offsetT abs_value
= 0;
5259 unsigned short HI
, LO
;
5261 char *buf
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
5263 assert (fixP
->fx_r_type
< BFD_RELOC_UNUSED
);
5264 if (fixP
->fx_addsy
== 0 && !fixP
->fx_pcrel
)
5266 if (fixP
->fx_r_type
!= BFD_RELOC_SCORE_DUMMY_HI16
)
5270 /* If this symbol is in a different section then we need to leave it for
5271 the linker to deal with. Unfortunately, md_pcrel_from can't tell,
5272 so we have to undo it's effects here. */
5275 if (fixP
->fx_addsy
!= NULL
5276 && S_IS_DEFINED (fixP
->fx_addsy
)
5277 && S_GET_SEGMENT (fixP
->fx_addsy
) != seg
)
5278 value
+= md_pcrel_from (fixP
);
5281 /* Remember value for emit_reloc. */
5282 fixP
->fx_addnumber
= value
;
5284 switch (fixP
->fx_r_type
)
5286 case BFD_RELOC_HI16_S
:
5288 { /* For la rd, imm32. */
5289 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5290 HI
= (value
) >> 16; /* mul to 2, then take the hi 16 bit. */
5291 newval
|= (HI
& 0x3fff) << 1;
5292 newval
|= ((HI
>> 14) & 0x3) << 16;
5293 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5296 case BFD_RELOC_LO16
:
5297 if (fixP
->fx_done
) /* For la rd, imm32. */
5299 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5300 LO
= (value
) & 0xffff;
5301 newval
|= (LO
& 0x3fff) << 1; /* 16 bit: imm -> 14 bit in lo, 2 bit in hi. */
5302 newval
|= ((LO
>> 14) & 0x3) << 16;
5303 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5306 case BFD_RELOC_SCORE_JMP
:
5308 content
= md_chars_to_number (buf
, INSN_SIZE
);
5309 value
= fixP
->fx_offset
;
5310 content
= (content
& ~0x3ff7ffe) | ((value
<< 1) & 0x3ff0000) | (value
& 0x7fff);
5311 md_number_to_chars (buf
, content
, INSN_SIZE
);
5314 case BFD_RELOC_SCORE_BRANCH
:
5315 if ((S_GET_SEGMENT (fixP
->fx_addsy
) != seg
) || (fixP
->fx_addsy
!= NULL
&& S_IS_EXTERNAL (fixP
->fx_addsy
)))
5316 value
= fixP
->fx_offset
;
5320 content
= md_chars_to_number (buf
, INSN_SIZE
);
5321 if ((fixP
->fx_frag
->fr_opcode
!= 0) && ((content
& 0x80008000) != 0x80008000))
5323 if ((value
& 0x80000000) == 0x80000000)
5324 abs_value
= 0xffffffff - value
+ 1;
5325 if ((abs_value
& 0xffffff00) != 0)
5327 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5328 _(" branch relocation truncate (0x%x) [-2^8 ~ 2^8]"), (unsigned int)value
);
5331 content
= md_chars_to_number (buf
, INSN16_SIZE
);
5333 content
= (content
& 0xff00) | ((value
>> 1) & 0xff);
5334 md_number_to_chars (buf
, content
, INSN16_SIZE
);
5335 fixP
->fx_r_type
= BFD_RELOC_SCORE16_BRANCH
;
5340 if ((value
& 0x80000000) == 0x80000000)
5341 abs_value
= 0xffffffff - value
+ 1;
5342 if ((abs_value
& 0xfff80000) != 0)
5344 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5345 _(" branch relocation truncate (0x%x) [-2^19 ~ 2^19]"), (unsigned int)value
);
5348 content
= md_chars_to_number (buf
, INSN_SIZE
);
5349 content
&= 0xfc00fc01;
5350 content
= (content
& 0xfc00fc01) | (value
& 0x3fe) | ((value
<< 6) & 0x3ff0000);
5351 md_number_to_chars (buf
, content
, INSN_SIZE
);
5354 case BFD_RELOC_SCORE16_JMP
:
5355 content
= md_chars_to_number (buf
, INSN16_SIZE
);
5357 value
= fixP
->fx_offset
& 0xfff;
5358 content
= (content
& 0xfc01) | (value
& 0xffe);
5359 md_number_to_chars (buf
, content
, INSN16_SIZE
);
5361 case BFD_RELOC_SCORE16_BRANCH
:
5362 content
= md_chars_to_number (buf
, INSN_SIZE
);
5363 if ((fixP
->fx_frag
->fr_opcode
!= 0) && ((content
& 0x80008000) == 0x80008000))
5365 if ((S_GET_SEGMENT (fixP
->fx_addsy
) != seg
) ||
5366 (fixP
->fx_addsy
!= NULL
&& S_IS_EXTERNAL (fixP
->fx_addsy
)))
5367 value
= fixP
->fx_offset
;
5370 if ((value
& 0x80000000) == 0x80000000)
5371 abs_value
= 0xffffffff - value
+ 1;
5372 if ((abs_value
& 0xfff80000) != 0)
5374 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5375 _(" branch relocation truncate (0x%x) [-2^19 ~ 2^19]"), (unsigned int)value
);
5378 content
= md_chars_to_number (buf
, INSN_SIZE
);
5379 content
= (content
& 0xfc00fc01) | (value
& 0x3fe) | ((value
<< 6) & 0x3ff0000);
5380 md_number_to_chars (buf
, content
, INSN_SIZE
);
5381 fixP
->fx_r_type
= BFD_RELOC_SCORE_BRANCH
;
5387 /* In differnt section. */
5388 if ((S_GET_SEGMENT (fixP
->fx_addsy
) != seg
) ||
5389 (fixP
->fx_addsy
!= NULL
&& S_IS_EXTERNAL (fixP
->fx_addsy
)))
5390 value
= fixP
->fx_offset
;
5394 if ((value
& 0x80000000) == 0x80000000)
5395 abs_value
= 0xffffffff - value
+ 1;
5396 if ((abs_value
& 0xffffff00) != 0)
5398 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5399 _(" branch relocation truncate (0x%x) [-2^8 ~ 2^8]"), (unsigned int)value
);
5402 content
= md_chars_to_number (buf
, INSN16_SIZE
);
5403 content
= (content
& 0xff00) | ((value
>> 1) & 0xff);
5404 md_number_to_chars (buf
, content
, INSN16_SIZE
);
5408 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5409 md_number_to_chars (buf
, value
, 1);
5413 value
= fixP
->fx_offset
;
5414 md_number_to_chars (buf
, value
, 1);
5420 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5421 md_number_to_chars (buf
, value
, 2);
5425 value
= fixP
->fx_offset
;
5426 md_number_to_chars (buf
, value
, 2);
5432 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5433 md_number_to_chars (buf
, value
, 4);
5437 value
= fixP
->fx_offset
;
5438 md_number_to_chars (buf
, value
, 4);
5442 case BFD_RELOC_VTABLE_INHERIT
:
5444 if (fixP
->fx_addsy
&& !S_IS_DEFINED (fixP
->fx_addsy
) && !S_IS_WEAK (fixP
->fx_addsy
))
5445 S_SET_WEAK (fixP
->fx_addsy
);
5447 case BFD_RELOC_VTABLE_ENTRY
:
5450 case BFD_RELOC_SCORE_GPREL15
:
5451 content
= md_chars_to_number (buf
, INSN_SIZE
);
5452 if ((fixP
->fx_frag
->fr_opcode
!= 0) && ((content
& 0xfc1c8000) != 0x94188000))
5453 fixP
->fx_r_type
= BFD_RELOC_NONE
;
5456 case BFD_RELOC_SCORE_GOT15
:
5457 case BFD_RELOC_SCORE_DUMMY_HI16
:
5458 case BFD_RELOC_SCORE_GOT_LO16
:
5459 case BFD_RELOC_SCORE_CALL15
:
5460 case BFD_RELOC_GPREL32
:
5462 case BFD_RELOC_NONE
:
5464 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("bad relocation fixup type (%d)"), fixP
->fx_r_type
);
5468 /* Translate internal representation of relocation info to BFD target format. */
5470 tc_gen_reloc (asection
* section ATTRIBUTE_UNUSED
, fixS
* fixp
)
5472 static arelent
*retval
[MAX_RELOC_EXPANSION
+ 1]; /* MAX_RELOC_EXPANSION equals 2. */
5474 bfd_reloc_code_real_type code
;
5480 reloc
= retval
[0] = xmalloc (sizeof (arelent
));
5483 reloc
->sym_ptr_ptr
= xmalloc (sizeof (asymbol
*));
5484 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
5485 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
5486 reloc
->addend
= fixp
->fx_offset
;
5488 /* If this is a variant frag, we may need to adjust the existing
5489 reloc and generate a new one. */
5490 if (fixp
->fx_frag
->fr_opcode
!= NULL
&& (fixp
->fx_r_type
== BFD_RELOC_SCORE_GPREL15
))
5492 /* Update instruction imm bit. */
5497 buf
= fixp
->fx_frag
->fr_literal
+ fixp
->fx_frag
->insn_addr
;
5498 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5499 off
= fixp
->fx_offset
>> 16;
5500 newval
|= (off
& 0x3fff) << 1;
5501 newval
|= ((off
>> 14) & 0x3) << 16;
5502 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5505 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5506 off
= fixp
->fx_offset
& 0xffff;
5507 newval
|= ((off
& 0x3fff) << 1);
5508 newval
|= (((off
>> 14) & 0x3) << 16);
5509 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5511 retval
[1] = xmalloc (sizeof (arelent
));
5513 retval
[1]->sym_ptr_ptr
= xmalloc (sizeof (asymbol
*));
5514 *retval
[1]->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
5515 retval
[1]->address
= (reloc
->address
+ RELAX_RELOC2 (fixp
->fx_frag
->fr_subtype
));
5521 retval
[1]->addend
= 0;
5522 retval
[1]->howto
= bfd_reloc_type_lookup (stdoutput
, BFD_RELOC_LO16
);
5523 assert (retval
[1]->howto
!= NULL
);
5525 fixp
->fx_r_type
= BFD_RELOC_HI16_S
;
5528 code
= fixp
->fx_r_type
;
5529 switch (fixp
->fx_r_type
)
5534 code
= BFD_RELOC_32_PCREL
;
5537 case BFD_RELOC_HI16_S
:
5538 case BFD_RELOC_LO16
:
5539 case BFD_RELOC_SCORE_JMP
:
5540 case BFD_RELOC_SCORE_BRANCH
:
5541 case BFD_RELOC_SCORE16_JMP
:
5542 case BFD_RELOC_SCORE16_BRANCH
:
5543 case BFD_RELOC_VTABLE_ENTRY
:
5544 case BFD_RELOC_VTABLE_INHERIT
:
5545 case BFD_RELOC_SCORE_GPREL15
:
5546 case BFD_RELOC_SCORE_GOT15
:
5547 case BFD_RELOC_SCORE_DUMMY_HI16
:
5548 case BFD_RELOC_SCORE_GOT_LO16
:
5549 case BFD_RELOC_SCORE_CALL15
:
5550 case BFD_RELOC_GPREL32
:
5551 case BFD_RELOC_NONE
:
5552 code
= fixp
->fx_r_type
;
5555 type
= _("<unknown>");
5556 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5557 _("cannot represent %s relocation in this object file format"), type
);
5561 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
5562 if (reloc
->howto
== NULL
)
5564 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5565 _("cannot represent %s relocation in this object file format1"),
5566 bfd_get_reloc_code_name (code
));
5569 /* HACK: Since arm ELF uses Rel instead of Rela, encode the
5570 vtable entry to be used in the relocation's section offset. */
5571 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
5572 reloc
->address
= fixp
->fx_offset
;
5578 score_elf_final_processing (void)
5580 if (fix_data_dependency
== 1)
5582 elf_elfheader (stdoutput
)->e_flags
|= EF_SCORE_FIXDEP
;
5584 if (score_pic
== PIC
)
5586 elf_elfheader (stdoutput
)->e_flags
|= EF_SCORE_PIC
;
5591 parse_pce_inst (char *insnstr
)
5595 char first
[MAX_LITERAL_POOL_SIZE
];
5596 char second
[MAX_LITERAL_POOL_SIZE
];
5597 struct score_it pec_part_1
;
5599 /* Get first part string of PCE. */
5600 p
= strstr (insnstr
, "||");
5603 sprintf (first
, "%s", insnstr
);
5605 /* Get second part string of PCE. */
5608 sprintf (second
, "%s", p
);
5610 parse_16_32_inst (first
, FALSE
);
5614 memcpy (&pec_part_1
, &inst
, sizeof (inst
));
5616 parse_16_32_inst (second
, FALSE
);
5620 if ( ((pec_part_1
.size
== INSN_SIZE
) && (inst
.size
== INSN_SIZE
))
5621 || ((pec_part_1
.size
== INSN_SIZE
) && (inst
.size
== INSN16_SIZE
))
5622 || ((pec_part_1
.size
== INSN16_SIZE
) && (inst
.size
== INSN_SIZE
)))
5624 inst
.error
= _("pce instruction error (16 bit || 16 bit)'");
5625 sprintf (inst
.str
, "%s", insnstr
);
5630 gen_insn_frag (&pec_part_1
, &inst
);
5634 md_assemble (char *str
)
5637 know (strlen (str
) < MAX_LITERAL_POOL_SIZE
);
5639 memset (&inst
, '\0', sizeof (inst
));
5640 if (INSN_IS_PCE_P (str
))
5641 parse_pce_inst (str
);
5643 parse_16_32_inst (str
, TRUE
);
5646 as_bad ("%s -- `%s'", inst
.error
, inst
.str
);
5649 /* We handle all bad expressions here, so that we can report the faulty
5650 instruction in the error message. */
5652 md_operand (expressionS
* expr
)
5654 if (in_my_get_expression
)
5656 expr
->X_op
= O_illegal
;
5657 if (inst
.error
== NULL
)
5659 inst
.error
= _("bad expression");
5664 const char *md_shortopts
= "nO::g::G:";
5666 #ifdef SCORE_BI_ENDIAN
5667 #define OPTION_EB (OPTION_MD_BASE + 0)
5668 #define OPTION_EL (OPTION_MD_BASE + 1)
5670 #if TARGET_BYTES_BIG_ENDIAN
5671 #define OPTION_EB (OPTION_MD_BASE + 0)
5673 #define OPTION_EL (OPTION_MD_BASE + 1)
5676 #define OPTION_FIXDD (OPTION_MD_BASE + 2)
5677 #define OPTION_NWARN (OPTION_MD_BASE + 3)
5678 #define OPTION_SCORE5 (OPTION_MD_BASE + 4)
5679 #define OPTION_SCORE5U (OPTION_MD_BASE + 5)
5680 #define OPTION_SCORE7 (OPTION_MD_BASE + 6)
5681 #define OPTION_R1 (OPTION_MD_BASE + 7)
5682 #define OPTION_O0 (OPTION_MD_BASE + 8)
5683 #define OPTION_SCORE_VERSION (OPTION_MD_BASE + 9)
5684 #define OPTION_PIC (OPTION_MD_BASE + 10)
5686 struct option md_longopts
[] =
5689 {"EB" , no_argument
, NULL
, OPTION_EB
},
5692 {"EL" , no_argument
, NULL
, OPTION_EL
},
5694 {"FIXDD" , no_argument
, NULL
, OPTION_FIXDD
},
5695 {"NWARN" , no_argument
, NULL
, OPTION_NWARN
},
5696 {"SCORE5" , no_argument
, NULL
, OPTION_SCORE5
},
5697 {"SCORE5U", no_argument
, NULL
, OPTION_SCORE5U
},
5698 {"SCORE7" , no_argument
, NULL
, OPTION_SCORE7
},
5699 {"USE_R1" , no_argument
, NULL
, OPTION_R1
},
5700 {"O0" , no_argument
, NULL
, OPTION_O0
},
5701 {"V" , no_argument
, NULL
, OPTION_SCORE_VERSION
},
5702 {"KPIC" , no_argument
, NULL
, OPTION_PIC
},
5703 {NULL
, no_argument
, NULL
, 0}
5706 size_t md_longopts_size
= sizeof (md_longopts
);
5709 md_parse_option (int c
, char *arg
)
5715 target_big_endian
= 1;
5720 target_big_endian
= 0;
5724 fix_data_dependency
= 1;
5727 warn_fix_data_dependency
= 0;
5731 university_version
= 0;
5732 vector_size
= SCORE5_PIPELINE
;
5734 case OPTION_SCORE5U
:
5736 university_version
= 1;
5737 vector_size
= SCORE5_PIPELINE
;
5741 university_version
= 0;
5742 vector_size
= SCORE7_PIPELINE
;
5748 g_switch_value
= atoi (arg
);
5753 case OPTION_SCORE_VERSION
:
5754 printf (_("Sunplus-v2-0-0-20060510\n"));
5758 g_switch_value
= 0; /* Must set -G num as 0 to generate PIC code. */
5761 /* as_bad (_("unrecognized option `-%c%s'"), c, arg ? arg : ""); */
5768 md_show_usage (FILE * fp
)
5770 fprintf (fp
, _(" Score-specific assembler options:\n"));
5773 -EB\t\tassemble code for a big-endian cpu\n"));
5778 -EL\t\tassemble code for a little-endian cpu\n"));
5782 -FIXDD\t\tassemble code for fix data dependency\n"));
5784 -NWARN\t\tassemble code for no warning message for fix data dependency\n"));
5786 -SCORE5\t\tassemble code for target is SCORE5\n"));
5788 -SCORE5U\tassemble code for target is SCORE5U\n"));
5790 -SCORE7\t\tassemble code for target is SCORE7, this is default setting\n"));
5792 -USE_R1\t\tassemble code for no warning message when using temp register r1\n"));
5794 -KPIC\t\tassemble code for PIC\n"));
5796 -O0\t\tassembler will not perform any optimizations\n"));
5798 -G gpnum\tassemble code for setting gpsize and default is 8 byte\n"));
5800 -V \t\tSunplus release version \n"));
5804 /* Pesudo handling functions. */
5806 /* If we change section we must dump the literal pool first. */
5808 s_score_bss (int ignore ATTRIBUTE_UNUSED
)
5810 subseg_set (bss_section
, (subsegT
) get_absolute_expression ());
5811 demand_empty_rest_of_line ();
5815 s_score_text (int ignore
)
5817 obj_elf_text (ignore
);
5818 record_alignment (now_seg
, 2);
5822 score_s_section (int ignore
)
5824 obj_elf_section (ignore
);
5825 if ((bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
) != 0)
5826 record_alignment (now_seg
, 2);
5831 s_change_sec (int sec
)
5836 /* The ELF backend needs to know that we are changing sections, so
5837 that .previous works correctly. We could do something like check
5838 for an obj_section_change_hook macro, but that might be confusing
5839 as it would not be appropriate to use it in the section changing
5840 functions in read.c, since obj-elf.c intercepts those. FIXME:
5841 This should be cleaner, somehow. */
5842 obj_elf_section_change_hook ();
5847 seg
= subseg_new (RDATA_SECTION_NAME
, (subsegT
) get_absolute_expression ());
5848 bfd_set_section_flags (stdoutput
, seg
, (SEC_ALLOC
| SEC_LOAD
| SEC_READONLY
| SEC_RELOC
| SEC_DATA
));
5849 if (strcmp (TARGET_OS
, "elf") != 0)
5850 record_alignment (seg
, 4);
5851 demand_empty_rest_of_line ();
5854 seg
= subseg_new (".sdata", (subsegT
) get_absolute_expression ());
5855 bfd_set_section_flags (stdoutput
, seg
, SEC_ALLOC
| SEC_LOAD
| SEC_RELOC
| SEC_DATA
);
5856 if (strcmp (TARGET_OS
, "elf") != 0)
5857 record_alignment (seg
, 4);
5858 demand_empty_rest_of_line ();
5864 s_score_mask (int reg_type ATTRIBUTE_UNUSED
)
5868 if (cur_proc_ptr
== (procS
*) NULL
)
5870 as_warn (_(".mask outside of .ent"));
5871 demand_empty_rest_of_line ();
5874 if (get_absolute_expression_and_terminator (&mask
) != ',')
5876 as_warn (_("Bad .mask directive"));
5877 --input_line_pointer
;
5878 demand_empty_rest_of_line ();
5881 off
= get_absolute_expression ();
5882 cur_proc_ptr
->reg_mask
= mask
;
5883 cur_proc_ptr
->reg_offset
= off
;
5884 demand_empty_rest_of_line ();
5894 name
= input_line_pointer
;
5895 c
= get_symbol_end ();
5896 p
= (symbolS
*) symbol_find_or_make (name
);
5897 *input_line_pointer
= c
;
5907 if (*input_line_pointer
== '-')
5909 ++input_line_pointer
;
5912 if (!ISDIGIT (*input_line_pointer
))
5913 as_bad (_("expected simple number"));
5914 if (input_line_pointer
[0] == '0')
5916 if (input_line_pointer
[1] == 'x')
5918 input_line_pointer
+= 2;
5919 while (ISXDIGIT (*input_line_pointer
))
5922 val
|= hex_value (*input_line_pointer
++);
5924 return negative
? -val
: val
;
5928 ++input_line_pointer
;
5929 while (ISDIGIT (*input_line_pointer
))
5932 val
|= *input_line_pointer
++ - '0';
5934 return negative
? -val
: val
;
5937 if (!ISDIGIT (*input_line_pointer
))
5939 printf (_(" *input_line_pointer == '%c' 0x%02x\n"), *input_line_pointer
, *input_line_pointer
);
5940 as_warn (_("invalid number"));
5943 while (ISDIGIT (*input_line_pointer
))
5946 val
+= *input_line_pointer
++ - '0';
5948 return negative
? -val
: val
;
5951 /* The .aent and .ent directives. */
5954 s_score_ent (int aent
)
5959 symbolP
= get_symbol ();
5960 if (*input_line_pointer
== ',')
5961 ++input_line_pointer
;
5963 if (ISDIGIT (*input_line_pointer
) || *input_line_pointer
== '-')
5966 #ifdef BFD_ASSEMBLER
5967 if ((bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
) != 0)
5972 if (now_seg
!= data_section
&& now_seg
!= bss_section
)
5978 as_warn (_(".ent or .aent not in text section."));
5979 if (!aent
&& cur_proc_ptr
)
5980 as_warn (_("missing .end"));
5983 cur_proc_ptr
= &cur_proc
;
5984 cur_proc_ptr
->reg_mask
= 0xdeadbeaf;
5985 cur_proc_ptr
->reg_offset
= 0xdeadbeaf;
5986 cur_proc_ptr
->fpreg_mask
= 0xdeafbeaf;
5987 cur_proc_ptr
->leaf
= 0xdeafbeaf;
5988 cur_proc_ptr
->frame_offset
= 0xdeafbeaf;
5989 cur_proc_ptr
->frame_reg
= 0xdeafbeaf;
5990 cur_proc_ptr
->pc_reg
= 0xdeafbeaf;
5991 cur_proc_ptr
->isym
= symbolP
;
5992 symbol_get_bfdsym (symbolP
)->flags
|= BSF_FUNCTION
;
5994 if (debug_type
== DEBUG_STABS
)
5995 stabs_generate_asm_func (S_GET_NAME (symbolP
), S_GET_NAME (symbolP
));
5997 demand_empty_rest_of_line ();
6001 s_score_frame (int ignore ATTRIBUTE_UNUSED
)
6008 backupstr
= input_line_pointer
;
6011 if (cur_proc_ptr
== (procS
*) NULL
)
6013 as_warn (_(".frame outside of .ent"));
6014 demand_empty_rest_of_line ();
6017 cur_proc_ptr
->frame_reg
= reg_required_here ((&backupstr
), 0, REG_TYPE_SCORE
);
6019 skip_past_comma (&backupstr
);
6020 while (*backupstr
!= ',')
6022 str
[i
] = *backupstr
;
6030 skip_past_comma (&backupstr
);
6031 cur_proc_ptr
->frame_offset
= val
;
6032 cur_proc_ptr
->pc_reg
= reg_required_here ((&backupstr
), 0, REG_TYPE_SCORE
);
6035 skip_past_comma (&backupstr
);
6037 while (*backupstr
!= '\n')
6039 str
[i
] = *backupstr
;
6045 cur_proc_ptr
->leaf
= val
;
6047 skip_past_comma (&backupstr
);
6049 #endif /* OBJ_ELF */
6050 while (input_line_pointer
!= backupstr
)
6051 input_line_pointer
++;
6054 /* The .end directive. */
6056 s_score_end (int x ATTRIBUTE_UNUSED
)
6061 /* Generate a .pdr section. */
6062 segT saved_seg
= now_seg
;
6063 subsegT saved_subseg
= now_subseg
;
6068 if (!is_end_of_line
[(unsigned char)*input_line_pointer
])
6071 demand_empty_rest_of_line ();
6076 #ifdef BFD_ASSEMBLER
6077 if ((bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
) != 0)
6082 if (now_seg
!= data_section
&& now_seg
!= bss_section
)
6089 as_warn (_(".end not in text section"));
6092 as_warn (_(".end directive without a preceding .ent directive."));
6093 demand_empty_rest_of_line ();
6098 assert (S_GET_NAME (p
));
6099 if (strcmp (S_GET_NAME (p
), S_GET_NAME (cur_proc_ptr
->isym
)))
6100 as_warn (_(".end symbol does not match .ent symbol."));
6101 if (debug_type
== DEBUG_STABS
)
6102 stabs_generate_asm_endfunc (S_GET_NAME (p
), S_GET_NAME (p
));
6105 as_warn (_(".end directive missing or unknown symbol"));
6107 if ((cur_proc_ptr
->reg_mask
== 0xdeadbeaf) ||
6108 (cur_proc_ptr
->reg_offset
== 0xdeadbeaf) ||
6109 (cur_proc_ptr
->leaf
== 0xdeafbeaf) ||
6110 (cur_proc_ptr
->frame_offset
== 0xdeafbeaf) ||
6111 (cur_proc_ptr
->frame_reg
== 0xdeafbeaf) || (cur_proc_ptr
->pc_reg
== 0xdeafbeaf));
6115 dot
= frag_now_fix ();
6117 subseg_set (pdr_seg
, 0);
6118 /* Write the symbol. */
6119 exp
.X_op
= O_symbol
;
6120 exp
.X_add_symbol
= p
;
6121 exp
.X_add_number
= 0;
6122 emit_expr (&exp
, 4);
6123 fragp
= frag_more (7 * 4);
6124 md_number_to_chars (fragp
, (valueT
) cur_proc_ptr
->reg_mask
, 4);
6125 md_number_to_chars (fragp
+ 4, (valueT
) cur_proc_ptr
->reg_offset
, 4);
6126 md_number_to_chars (fragp
+ 8, (valueT
) cur_proc_ptr
->fpreg_mask
, 4);
6127 md_number_to_chars (fragp
+ 12, (valueT
) cur_proc_ptr
->leaf
, 4);
6128 md_number_to_chars (fragp
+ 16, (valueT
) cur_proc_ptr
->frame_offset
, 4);
6129 md_number_to_chars (fragp
+ 20, (valueT
) cur_proc_ptr
->frame_reg
, 4);
6130 md_number_to_chars (fragp
+ 24, (valueT
) cur_proc_ptr
->pc_reg
, 4);
6131 subseg_set (saved_seg
, saved_subseg
);
6134 cur_proc_ptr
= NULL
;
6137 /* Handle the .set pseudo-op. */
6139 s_score_set (int x ATTRIBUTE_UNUSED
)
6142 char name
[MAX_LITERAL_POOL_SIZE
];
6143 char * orig_ilp
= input_line_pointer
;
6145 while (!is_end_of_line
[(unsigned char)*input_line_pointer
])
6147 name
[i
] = (char) * input_line_pointer
;
6149 ++input_line_pointer
;
6154 if (strcmp (name
, "nwarn") == 0)
6156 warn_fix_data_dependency
= 0;
6158 else if (strcmp (name
, "fixdd") == 0)
6160 fix_data_dependency
= 1;
6162 else if (strcmp (name
, "nofixdd") == 0)
6164 fix_data_dependency
= 0;
6166 else if (strcmp (name
, "r1") == 0)
6170 else if (strcmp (name
, "nor1") == 0)
6174 else if (strcmp (name
, "optimize") == 0)
6178 else if (strcmp (name
, "volatile") == 0)
6182 else if (strcmp (name
, "pic") == 0)
6188 input_line_pointer
= orig_ilp
;
6193 /* Handle the .cpload pseudo-op. This is used when generating PIC code. It sets the
6194 $gp register for the function based on the function address, which is in the register
6195 named in the argument. This uses a relocation against GP_DISP_LABEL, which is handled
6196 specially by the linker. The result is:
6197 ldis gp, %hi(GP_DISP_LABEL)
6198 ori gp, %low(GP_DISP_LABEL)
6199 add gp, gp, .cpload argument
6200 The .cpload argument is normally r29. */
6203 s_score_cpload (int ignore ATTRIBUTE_UNUSED
)
6206 char insn_str
[MAX_LITERAL_POOL_SIZE
];
6208 /* If we are not generating PIC code, .cpload is ignored. */
6209 if (score_pic
== NO_PIC
)
6215 if ((reg
= reg_required_here (&input_line_pointer
, -1, REG_TYPE_SCORE
)) == (int) FAIL
)
6218 demand_empty_rest_of_line ();
6220 sprintf (insn_str
, "ld_i32hi r%d, %s", GP
, GP_DISP_LABEL
);
6221 if (append_insn (insn_str
, TRUE
) == (int) FAIL
)
6224 sprintf (insn_str
, "ld_i32lo r%d, %s", GP
, GP_DISP_LABEL
);
6225 if (append_insn (insn_str
, TRUE
) == (int) FAIL
)
6228 sprintf (insn_str
, "add r%d, r%d, r%d", GP
, GP
, reg
);
6229 if (append_insn (insn_str
, TRUE
) == (int) FAIL
)
6233 /* Handle the .cprestore pseudo-op. This stores $gp into a given
6234 offset from $sp. The offset is remembered, and after making a PIC
6235 call $gp is restored from that location. */
6238 s_score_cprestore (int ignore ATTRIBUTE_UNUSED
)
6241 int cprestore_offset
;
6242 char insn_str
[MAX_LITERAL_POOL_SIZE
];
6244 /* If we are not generating PIC code, .cprestore is ignored. */
6245 if (score_pic
== NO_PIC
)
6251 if ((reg
= reg_required_here (&input_line_pointer
, -1, REG_TYPE_SCORE
)) == (int) FAIL
6252 || skip_past_comma (&input_line_pointer
) == (int) FAIL
)
6257 cprestore_offset
= get_absolute_expression ();
6259 if (cprestore_offset
<= 0x3fff)
6261 sprintf (insn_str
, "sw r%d, [r%d, %d]", GP
, reg
, cprestore_offset
);
6262 if (append_insn (insn_str
, TRUE
) == (int) FAIL
)
6272 sprintf (insn_str
, "li r1, %d", cprestore_offset
);
6273 if (append_insn (insn_str
, TRUE
) == (int) FAIL
)
6276 sprintf (insn_str
, "add r1, r1, r%d", reg
);
6277 if (append_insn (insn_str
, TRUE
) == (int) FAIL
)
6280 sprintf (insn_str
, "sw r%d, [r1]", GP
);
6281 if (append_insn (insn_str
, TRUE
) == (int) FAIL
)
6287 demand_empty_rest_of_line ();
6290 /* Handle the .gpword pseudo-op. This is used when generating PIC
6291 code. It generates a 32 bit GP relative reloc. */
6293 s_score_gpword (int ignore ATTRIBUTE_UNUSED
)
6298 /* When not generating PIC code, this is treated as .word. */
6299 if (score_pic
== NO_PIC
)
6305 if (ex
.X_op
!= O_symbol
|| ex
.X_add_number
!= 0)
6307 as_bad (_("Unsupported use of .gpword"));
6308 ignore_rest_of_line ();
6311 md_number_to_chars (p
, (valueT
) 0, 4);
6312 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 4, &ex
, FALSE
, BFD_RELOC_GPREL32
);
6313 demand_empty_rest_of_line ();
6316 /* Handle the .cpadd pseudo-op. This is used when dealing with switch
6317 tables in PIC code. */
6320 s_score_cpadd (int ignore ATTRIBUTE_UNUSED
)
6323 char insn_str
[MAX_LITERAL_POOL_SIZE
];
6325 /* If we are not generating PIC code, .cpload is ignored. */
6326 if (score_pic
== NO_PIC
)
6332 if ((reg
= reg_required_here (&input_line_pointer
, -1, REG_TYPE_SCORE
)) == (int) FAIL
)
6336 demand_empty_rest_of_line ();
6338 /* Add $gp to the register named as an argument. */
6339 sprintf (insn_str
, "add r%d, r%d, r%d", reg
, reg
, GP
);
6340 if (append_insn (insn_str
, TRUE
) == (int) FAIL
)
6344 #ifndef TC_IMPLICIT_LCOMM_ALIGNMENT
6345 #define TC_IMPLICIT_LCOMM_ALIGNMENT(SIZE, P2VAR) \
6350 else if ((SIZE) >= 4) \
6352 else if ((SIZE) >= 2) \
6361 s_score_lcomm (int bytes_p
)
6368 segT current_seg
= now_seg
;
6369 subsegT current_subseg
= now_subseg
;
6370 const int max_alignment
= 15;
6372 segT bss_seg
= bss_section
;
6373 int needs_align
= 0;
6375 name
= input_line_pointer
;
6376 c
= get_symbol_end ();
6377 p
= input_line_pointer
;
6382 as_bad (_("expected symbol name"));
6383 discard_rest_of_line ();
6389 /* Accept an optional comma after the name. The comma used to be
6390 required, but Irix 5 cc does not generate it. */
6391 if (*input_line_pointer
== ',')
6393 ++input_line_pointer
;
6397 if (is_end_of_line
[(unsigned char)*input_line_pointer
])
6399 as_bad (_("missing size expression"));
6403 if ((temp
= get_absolute_expression ()) < 0)
6405 as_warn (_("BSS length (%d) < 0 ignored"), temp
);
6406 ignore_rest_of_line ();
6410 #if defined (TC_SCORE)
6411 if (OUTPUT_FLAVOR
== bfd_target_ecoff_flavour
|| OUTPUT_FLAVOR
== bfd_target_elf_flavour
)
6413 /* For Score and Alpha ECOFF or ELF, small objects are put in .sbss. */
6414 if ((unsigned)temp
<= bfd_get_gp_size (stdoutput
))
6416 bss_seg
= subseg_new (".sbss", 1);
6417 seg_info (bss_seg
)->bss
= 1;
6418 #ifdef BFD_ASSEMBLER
6419 if (!bfd_set_section_flags (stdoutput
, bss_seg
, SEC_ALLOC
))
6420 as_warn (_("error setting flags for \".sbss\": %s"), bfd_errmsg (bfd_get_error ()));
6427 if (*input_line_pointer
== ',')
6429 ++input_line_pointer
;
6432 if (is_end_of_line
[(unsigned char)*input_line_pointer
])
6434 as_bad (_("missing alignment"));
6439 align
= get_absolute_expression ();
6446 TC_IMPLICIT_LCOMM_ALIGNMENT (temp
, align
);
6448 /* Still zero unless TC_IMPLICIT_LCOMM_ALIGNMENT set it. */
6450 record_alignment (bss_seg
, align
);
6457 /* Convert to a power of 2. */
6462 for (i
= 0; align
!= 0; align
>>= 1, ++i
)
6468 if (align
> max_alignment
)
6470 align
= max_alignment
;
6471 as_warn (_("alignment too large; %d assumed"), align
);
6476 as_warn (_("alignment negative; 0 assumed"));
6479 record_alignment (bss_seg
, align
);
6483 /* Assume some objects may require alignment on some systems. */
6484 #if defined (TC_ALPHA) && ! defined (VMS)
6487 align
= ffs (temp
) - 1;
6488 if (temp
% (1 << align
))
6495 symbolP
= symbol_find_or_make (name
);
6499 #if (defined (OBJ_AOUT) || defined (OBJ_MAYBE_AOUT) \
6500 || defined (OBJ_BOUT) || defined (OBJ_MAYBE_BOUT))
6501 #ifdef BFD_ASSEMBLER
6502 (OUTPUT_FLAVOR
!= bfd_target_aout_flavour
6503 || (S_GET_OTHER (symbolP
) == 0 && S_GET_DESC (symbolP
) == 0)) &&
6505 (S_GET_OTHER (symbolP
) == 0 && S_GET_DESC (symbolP
) == 0) &&
6508 (S_GET_SEGMENT (symbolP
) == bss_seg
|| (!S_IS_DEFINED (symbolP
) && S_GET_VALUE (symbolP
) == 0)))
6512 subseg_set (bss_seg
, 1);
6515 frag_align (align
, 0, 0);
6517 /* Detach from old frag. */
6518 if (S_GET_SEGMENT (symbolP
) == bss_seg
)
6519 symbol_get_frag (symbolP
)->fr_symbol
= NULL
;
6521 symbol_set_frag (symbolP
, frag_now
);
6522 pfrag
= frag_var (rs_org
, 1, 1, (relax_substateT
) 0, symbolP
, (offsetT
) temp
, NULL
);
6526 S_SET_SEGMENT (symbolP
, bss_seg
);
6529 /* The symbol may already have been created with a preceding
6530 ".globl" directive -- be careful not to step on storage class
6531 in that case. Otherwise, set it to static. */
6532 if (S_GET_STORAGE_CLASS (symbolP
) != C_EXT
)
6534 S_SET_STORAGE_CLASS (symbolP
, C_STAT
);
6536 #endif /* OBJ_COFF */
6539 S_SET_SIZE (symbolP
, temp
);
6543 as_bad (_("symbol `%s' is already defined"), S_GET_NAME (symbolP
));
6545 subseg_set (current_seg
, current_subseg
);
6547 demand_empty_rest_of_line ();
6551 insert_reg (const struct reg_entry
*r
, struct hash_control
*htab
)
6554 int len
= strlen (r
->name
) + 2;
6555 char *buf
= xmalloc (len
);
6556 char *buf2
= xmalloc (len
);
6558 strcpy (buf
+ i
, r
->name
);
6559 for (i
= 0; buf
[i
]; i
++)
6561 buf2
[i
] = TOUPPER (buf
[i
]);
6565 hash_insert (htab
, buf
, (void *) r
);
6566 hash_insert (htab
, buf2
, (void *) r
);
6570 build_reg_hsh (struct reg_map
*map
)
6572 const struct reg_entry
*r
;
6574 if ((map
->htab
= hash_new ()) == NULL
)
6576 as_fatal (_("virtual memory exhausted"));
6578 for (r
= map
->names
; r
->name
!= NULL
; r
++)
6580 insert_reg (r
, map
->htab
);
6591 if ((score_ops_hsh
= hash_new ()) == NULL
)
6592 as_fatal (_("virtual memory exhausted"));
6594 build_score_ops_hsh ();
6596 if ((dependency_insn_hsh
= hash_new ()) == NULL
)
6597 as_fatal (_("virtual memory exhausted"));
6599 build_dependency_insn_hsh ();
6601 for (i
= (int)REG_TYPE_FIRST
; i
< (int)REG_TYPE_MAX
; i
++)
6602 build_reg_hsh (all_reg_maps
+ i
);
6604 /* Initialize dependency vector. */
6605 init_dependency_vector ();
6607 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
, 0);
6609 subseg
= now_subseg
;
6610 pdr_seg
= subseg_new (".pdr", (subsegT
) 0);
6611 (void)bfd_set_section_flags (stdoutput
, pdr_seg
, SEC_READONLY
| SEC_RELOC
| SEC_DEBUGGING
);
6612 (void)bfd_set_section_alignment (stdoutput
, pdr_seg
, 2);
6613 subseg_set (seg
, subseg
);
6615 if (USE_GLOBAL_POINTER_OPT
)
6616 bfd_set_gp_size (stdoutput
, g_switch_value
);
6620 const pseudo_typeS md_pseudo_table
[] =
6622 {"bss", s_score_bss
, 0},
6623 {"text", s_score_text
, 0},
6626 {"extend", float_cons
, 'x'},
6627 {"ldouble", float_cons
, 'x'},
6628 {"packed", float_cons
, 'p'},
6629 {"end", s_score_end
, 0},
6630 {"ent", s_score_ent
, 0},
6631 {"frame", s_score_frame
, 0},
6632 {"rdata", s_change_sec
, 'r'},
6633 {"sdata", s_change_sec
, 's'},
6634 {"set", s_score_set
, 0},
6635 {"mask", s_score_mask
, 'R'},
6637 {"lcomm", s_score_lcomm
, 1},
6638 {"section", score_s_section
, 0},
6639 {"cpload", s_score_cpload
, 0},
6640 {"cprestore", s_score_cprestore
, 0},
6641 {"gpword", s_score_gpword
, 0},
6642 {"cpadd", s_score_cpadd
, 0},