1 /* tc-score.c -- Assembler for Score
2 Copyright 2006, 2007 Free Software Foundation, Inc.
4 Mei Ligang (ligang@sunnorth.com.cn)
5 Pei-Lin Tsai (pltsai@sunplus.com)
7 This file is part of GAS, the GNU Assembler.
9 GAS is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3, or (at your option)
14 GAS is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with GAS; see the file COPYING. If not, write to the Free
21 Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
27 #include "safe-ctype.h"
28 #include "opcode/score-inst.h"
29 #include "opcode/score-datadep.h"
30 #include "struc-symbol.h"
33 #include "elf/score.h"
34 #include "dwarf2dbg.h"
38 #define PIC_CALL_REG 29
39 #define MAX_LITERAL_POOL_SIZE 1024
40 #define FAIL 0x80000000
44 #define RELAX_INST_NUM 3
46 /* For score5u : div/mul will pop warning message, mmu/alw/asw will pop error message. */
47 #define BAD_ARGS _("bad arguments to instruction")
48 #define BAD_PC _("r15 not allowed here")
49 #define BAD_COND _("instruction is not conditional")
50 #define ERR_NO_ACCUM _("acc0 expected")
51 #define ERR_FOR_SCORE5U_MUL_DIV _("div / mul are reserved instructions")
52 #define ERR_FOR_SCORE5U_MMU _("This architecture doesn't support mmu")
53 #define ERR_FOR_SCORE5U_ATOMIC _("This architecture doesn't support atomic instruction")
54 #define LONG_LABEL_LEN _("the label length is longer than 1024");
55 #define BAD_SKIP_COMMA BAD_ARGS
56 #define BAD_GARBAGE _("garbage following instruction");
58 #define skip_whitespace(str) while (*(str) == ' ') ++(str)
60 /* The name of the readonly data section. */
61 #define RDATA_SECTION_NAME (OUTPUT_FLAVOR == bfd_target_aout_flavour \
63 : OUTPUT_FLAVOR == bfd_target_ecoff_flavour \
65 : OUTPUT_FLAVOR == bfd_target_coff_flavour \
67 : OUTPUT_FLAVOR == bfd_target_elf_flavour \
71 #define RELAX_ENCODE(old, new, type, reloc1, reloc2, opt) \
80 #define RELAX_OLD(i) (((i) >> 23) & 0x7f)
81 #define RELAX_NEW(i) (((i) >> 16) & 0x7f)
82 #define RELAX_TYPE(i) (((i) >> 9) & 0x7f)
83 #define RELAX_RELOC1(i) ((valueT) ((i) >> 5) & 0xf)
84 #define RELAX_RELOC2(i) ((valueT) ((i) >> 1) & 0xf)
85 #define RELAX_OPT(i) ((i) & 1)
86 #define RELAX_OPT_CLEAR(i) ((i) & ~1)
88 #define SET_INSN_ERROR(s) (inst.error = (s))
89 #define INSN_IS_PCE_P(s) (strstr (str, "||") != NULL)
91 #define GET_INSN_CLASS(type) (get_insn_class_from_type (type))
93 #define GET_INSN_SIZE(type) ((GET_INSN_CLASS (type) == INSN_CLASS_16) \
94 ? INSN16_SIZE : INSN_SIZE)
96 /* This array holds the chars that always start a comment. If the
97 pre-processor is disabled, these aren't very useful. */
98 const char comment_chars
[] = "#";
99 const char line_comment_chars
[] = "#";
100 const char line_separator_chars
[] = ";";
102 /* Chars that can be used to separate mant from exp in floating point numbers. */
103 const char EXP_CHARS
[] = "eE";
104 const char FLT_CHARS
[] = "rRsSfFdDxXeEpP";
106 /* Used to contain constructed error messages. */
107 static char err_msg
[255];
109 fragS
*score_fragp
= 0;
110 static int fix_data_dependency
= 0;
111 static int warn_fix_data_dependency
= 1;
112 static int score7
= 1;
113 static int university_version
= 0;
115 static int in_my_get_expression
= 0;
117 #define USE_GLOBAL_POINTER_OPT 1
118 #define SCORE_BI_ENDIAN
120 /* Default, pop warning message when using r1. */
123 /* Default will do instruction relax, -O0 will set g_opt = 0. */
124 static unsigned int g_opt
= 1;
126 /* The size of the small data section. */
127 static unsigned int g_switch_value
= 8;
130 /* Pre-defined "_GLOBAL_OFFSET_TABLE_" */
135 enum score_pic_level score_pic
= NO_PIC
;
137 #define INSN_NAME_LEN 16
140 char name
[INSN_NAME_LEN
];
141 unsigned long instruction
;
142 unsigned long relax_inst
;
145 enum score_insn_type type
;
146 char str
[MAX_LITERAL_POOL_SIZE
];
149 char reg
[INSN_NAME_LEN
];
152 bfd_reloc_code_real_type type
;
157 struct score_it inst
;
162 unsigned long reg_mask
;
163 unsigned long reg_offset
;
164 unsigned long fpreg_mask
;
166 unsigned long frame_offset
;
167 unsigned long frame_reg
;
168 unsigned long pc_reg
;
172 static procS cur_proc
;
173 static procS
*cur_proc_ptr
;
176 #define SCORE7_PIPELINE 7
177 #define SCORE5_PIPELINE 5
178 static int vector_size
= SCORE7_PIPELINE
;
179 struct score_it dependency_vector
[SCORE7_PIPELINE
];
181 /* Relax will need some padding for alignment. */
182 #define RELAX_PAD_BYTE 3
184 /* Structure for a hash table entry for a register. */
191 static const struct reg_entry score_rn_table
[] =
193 {"r0", 0}, {"r1", 1}, {"r2", 2}, {"r3", 3},
194 {"r4", 4}, {"r5", 5}, {"r6", 6}, {"r7", 7},
195 {"r8", 8}, {"r9", 9}, {"r10", 10}, {"r11", 11},
196 {"r12", 12}, {"r13", 13}, {"r14", 14}, {"r15", 15},
197 {"r16", 16}, {"r17", 17}, {"r18", 18}, {"r19", 19},
198 {"r20", 20}, {"r21", 21}, {"r22", 22}, {"r23", 23},
199 {"r24", 24}, {"r25", 25}, {"r26", 26}, {"r27", 27},
200 {"r28", 28}, {"r29", 29}, {"r30", 30}, {"r31", 31},
204 static const struct reg_entry score_srn_table
[] =
206 {"sr0", 0}, {"sr1", 1}, {"sr2", 2},
210 static const struct reg_entry score_crn_table
[] =
212 {"cr0", 0}, {"cr1", 1}, {"cr2", 2}, {"cr3", 3},
213 {"cr4", 4}, {"cr5", 5}, {"cr6", 6}, {"cr7", 7},
214 {"cr8", 8}, {"cr9", 9}, {"cr10", 10}, {"cr11", 11},
215 {"cr12", 12}, {"cr13", 13}, {"cr14", 14}, {"cr15", 15},
216 {"cr16", 16}, {"cr17", 17}, {"cr18", 18}, {"cr19", 19},
217 {"cr20", 20}, {"cr21", 21}, {"cr22", 22}, {"cr23", 23},
218 {"cr24", 24}, {"cr25", 25}, {"cr26", 26}, {"cr27", 27},
219 {"cr28", 28}, {"cr29", 29}, {"cr30", 30}, {"cr31", 31},
225 const struct reg_entry
*names
;
227 struct hash_control
*htab
;
228 const char *expected
;
231 struct reg_map all_reg_maps
[] =
233 {score_rn_table
, 31, NULL
, N_("S+core register expected")},
234 {score_srn_table
, 2, NULL
, N_("S+core special-register expected")},
235 {score_crn_table
, 31, NULL
, N_("S+core co-processor register expected")},
238 static struct hash_control
*score_ops_hsh
= NULL
;
240 static struct hash_control
*dependency_insn_hsh
= NULL
;
242 /* Enumeration matching entries in table above. */
246 #define REG_TYPE_FIRST REG_TYPE_SCORE
247 REG_TYPE_SCORE_SR
= 1,
248 REG_TYPE_SCORE_CR
= 2,
252 typedef struct literalS
254 struct expressionS exp
;
255 struct score_it
*inst
;
259 literalT literals
[MAX_LITERAL_POOL_SIZE
];
261 static void do_ldst_insn (char *);
262 static void do_crdcrscrsimm5 (char *);
263 static void do_ldst_unalign (char *);
264 static void do_ldst_atomic (char *);
265 static void do_ldst_cop (char *);
266 static void do_macro_li_rdi32 (char *);
267 static void do_macro_la_rdi32 (char *);
268 static void do_macro_rdi32hi (char *);
269 static void do_macro_rdi32lo (char *);
270 static void do_macro_mul_rdrsrs (char *);
271 static void do_macro_ldst_label (char *);
272 static void do_branch (char *);
273 static void do_jump (char *);
274 static void do_empty (char *);
275 static void do_rdrsrs (char *);
276 static void do_rdsi16 (char *);
277 static void do_rdrssi14 (char *);
278 static void do_sub_rdsi16 (char *);
279 static void do_sub_rdrssi14 (char *);
280 static void do_rdrsi5 (char *);
281 static void do_rdrsi14 (char *);
282 static void do_rdi16 (char *);
283 static void do_xrsi5 (char *);
284 static void do_rdrs (char *);
285 static void do_rdxrs (char *);
286 static void do_rsrs (char *);
287 static void do_rdcrs (char *);
288 static void do_rdsrs (char *);
289 static void do_rd (char *);
290 static void do_rs (char *);
291 static void do_i15 (char *);
292 static void do_xi5x (char *);
293 static void do_ceinst (char *);
294 static void do_cache (char *);
295 static void do16_rdrs (char *);
296 static void do16_rs (char *);
297 static void do16_xrs (char *);
298 static void do16_mv_rdrs (char *);
299 static void do16_hrdrs (char *);
300 static void do16_rdhrs (char *);
301 static void do16_rdi4 (char *);
302 static void do16_rdi5 (char *);
303 static void do16_xi5 (char *);
304 static void do16_ldst_insn (char *);
305 static void do16_ldst_imm_insn (char *);
306 static void do16_push_pop (char *);
307 static void do16_branch (char *);
308 static void do16_jump (char *);
309 static void do_rdi16_pic (char *);
310 static void do_addi_s_pic (char *);
311 static void do_addi_u_pic (char *);
312 static void do_lw_pic (char *);
314 static const struct asm_opcode score_ldst_insns
[] =
316 {"lw", 0x20000000, 0x3e000000, 0x2008, Rd_rvalueRs_SI15
, do_ldst_insn
},
317 {"lw", 0x06000000, 0x3e000007, 0x8000, Rd_rvalueRs_preSI12
, do_ldst_insn
},
318 {"lw", 0x0e000000, 0x3e000007, 0x200a, Rd_rvalueRs_postSI12
, do_ldst_insn
},
319 {"lh", 0x22000000, 0x3e000000, 0x2009, Rd_rvalueRs_SI15
, do_ldst_insn
},
320 {"lh", 0x06000001, 0x3e000007, 0x8000, Rd_rvalueRs_preSI12
, do_ldst_insn
},
321 {"lh", 0x0e000001, 0x3e000007, 0x8000, Rd_rvalueRs_postSI12
, do_ldst_insn
},
322 {"lhu", 0x24000000, 0x3e000000, 0x8000, Rd_rvalueRs_SI15
, do_ldst_insn
},
323 {"lhu", 0x06000002, 0x3e000007, 0x8000, Rd_rvalueRs_preSI12
, do_ldst_insn
},
324 {"lhu", 0x0e000002, 0x3e000007, 0x8000, Rd_rvalueRs_postSI12
, do_ldst_insn
},
325 {"lb", 0x26000000, 0x3e000000, 0x8000, Rd_rvalueRs_SI15
, do_ldst_insn
},
326 {"lb", 0x06000003, 0x3e000007, 0x8000, Rd_rvalueRs_preSI12
, do_ldst_insn
},
327 {"lb", 0x0e000003, 0x3e000007, 0x8000, Rd_rvalueRs_postSI12
, do_ldst_insn
},
328 {"sw", 0x28000000, 0x3e000000, 0x200c, Rd_lvalueRs_SI15
, do_ldst_insn
},
329 {"sw", 0x06000004, 0x3e000007, 0x200e, Rd_lvalueRs_preSI12
, do_ldst_insn
},
330 {"sw", 0x0e000004, 0x3e000007, 0x8000, Rd_lvalueRs_postSI12
, do_ldst_insn
},
331 {"sh", 0x2a000000, 0x3e000000, 0x200d, Rd_lvalueRs_SI15
, do_ldst_insn
},
332 {"sh", 0x06000005, 0x3e000007, 0x8000, Rd_lvalueRs_preSI12
, do_ldst_insn
},
333 {"sh", 0x0e000005, 0x3e000007, 0x8000, Rd_lvalueRs_postSI12
, do_ldst_insn
},
334 {"lbu", 0x2c000000, 0x3e000000, 0x200b, Rd_rvalueRs_SI15
, do_ldst_insn
},
335 {"lbu", 0x06000006, 0x3e000007, 0x8000, Rd_rvalueRs_preSI12
, do_ldst_insn
},
336 {"lbu", 0x0e000006, 0x3e000007, 0x8000, Rd_rvalueRs_postSI12
, do_ldst_insn
},
337 {"sb", 0x2e000000, 0x3e000000, 0x200f, Rd_lvalueRs_SI15
, do_ldst_insn
},
338 {"sb", 0x06000007, 0x3e000007, 0x8000, Rd_lvalueRs_preSI12
, do_ldst_insn
},
339 {"sb", 0x0e000007, 0x3e000007, 0x8000, Rd_lvalueRs_postSI12
, do_ldst_insn
},
342 static const struct asm_opcode score_insns
[] =
344 {"abs", 0x3800000a, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
345 {"abs.s", 0x3800004b, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
346 {"add", 0x00000010, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
347 {"add.c", 0x00000011, 0x3e0003ff, 0x2000, Rd_Rs_Rs
, do_rdrsrs
},
348 {"add.s", 0x38000048, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
349 {"addc", 0x00000012, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
350 {"addc.c", 0x00000013, 0x3e0003ff, 0x0009, Rd_Rs_Rs
, do_rdrsrs
},
351 {"addi", 0x02000000, 0x3e0e0001, 0x8000, Rd_SI16
, do_rdsi16
},
352 {"addi.c", 0x02000001, 0x3e0e0001, 0x8000, Rd_SI16
, do_rdsi16
},
353 {"addis", 0x0a000000, 0x3e0e0001, 0x8000, Rd_SI16
, do_rdi16
},
354 {"addis.c", 0x0a000001, 0x3e0e0001, 0x8000, Rd_SI16
, do_rdi16
},
355 {"addri", 0x10000000, 0x3e000001, 0x8000, Rd_Rs_SI14
, do_rdrssi14
},
356 {"addri.c", 0x10000001, 0x3e000001, 0x8000, Rd_Rs_SI14
, do_rdrssi14
},
357 {"addc!", 0x0009, 0x700f, 0x00000013, Rd_Rs
, do16_rdrs
},
358 {"add!", 0x2000, 0x700f, 0x00000011, Rd_Rs
, do16_rdrs
},
359 {"addei!", 0x6000 , 0x7087, 0x02000001, Rd_I4
, do16_rdi4
},
360 {"subi", 0x02000000, 0x3e0e0001, 0x8000, Rd_SI16
, do_sub_rdsi16
},
361 {"subi.c", 0x02000001, 0x3e0e0001, 0x8000, Rd_SI16
, do_sub_rdsi16
},
362 {"subri", 0x10000000, 0x3e000001, 0x8000, Rd_Rs_SI14
, do_sub_rdrssi14
},
363 {"subri.c", 0x10000001, 0x3e000001, 0x8000, Rd_Rs_SI14
, do_sub_rdrssi14
},
364 {"and", 0x00000020, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
365 {"and.c", 0x00000021, 0x3e0003ff, 0x2004, Rd_Rs_Rs
, do_rdrsrs
},
366 {"andi", 0x02080000, 0x3e0e0001, 0x8000, Rd_I16
, do_rdi16
},
367 {"andi.c", 0x02080001, 0x3e0e0001, 0x8000, Rd_I16
, do_rdi16
},
368 {"andis", 0x0a080000, 0x3e0e0001, 0x8000, Rd_I16
, do_rdi16
},
369 {"andis.c", 0x0a080001, 0x3e0e0001, 0x8000, Rd_I16
, do_rdi16
},
370 {"andri", 0x18000000, 0x3e000001, 0x8000, Rd_Rs_I14
, do_rdrsi14
},
371 {"andri.c", 0x18000001, 0x3e000001, 0x8000, Rd_Rs_I14
, do_rdrsi14
},
372 {"and!", 0x2004, 0x700f, 0x00000021, Rd_Rs
, do16_rdrs
},
373 {"bcs", 0x08000000, 0x3e007c01, 0x4000, PC_DISP19div2
, do_branch
},
374 {"bcc", 0x08000400, 0x3e007c01, 0x4000, PC_DISP19div2
, do_branch
},
375 {"bcnz", 0x08003800, 0x3e007c01, 0x4000, PC_DISP19div2
, do_branch
},
376 {"bcsl", 0x08000001, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
377 {"bccl", 0x08000401, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
378 {"bcnzl", 0x08003801, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
379 {"bcs!", 0x4000, 0x7f00, 0x08000000, PC_DISP8div2
, do16_branch
},
380 {"bcc!", 0x4100, 0x7f00, 0x08000400, PC_DISP8div2
, do16_branch
},
381 {"bcnz!", 0x4e00, 0x7f00, 0x08003800, PC_DISP8div2
, do16_branch
},
382 {"beq", 0x08001000, 0x3e007c01, 0x4000, PC_DISP19div2
, do_branch
},
383 {"beql", 0x08001001, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
384 {"beq!", 0x4400, 0x7f00, 0x08001000, PC_DISP8div2
, do16_branch
},
385 {"bgtu", 0x08000800, 0x3e007c01, 0x4000, PC_DISP19div2
, do_branch
},
386 {"bgt", 0x08001800, 0x3e007c01, 0x4000, PC_DISP19div2
, do_branch
},
387 {"bge", 0x08002000, 0x3e007c01, 0x4000, PC_DISP19div2
, do_branch
},
388 {"bgtul", 0x08000801, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
389 {"bgtl", 0x08001801, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
390 {"bgel", 0x08002001, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
391 {"bgtu!", 0x4200, 0x7f00, 0x08000800, PC_DISP8div2
, do16_branch
},
392 {"bgt!", 0x4600, 0x7f00, 0x08001800, PC_DISP8div2
, do16_branch
},
393 {"bge!", 0x4800, 0x7f00, 0x08002000, PC_DISP8div2
, do16_branch
},
394 {"bitclr.c", 0x00000029, 0x3e0003ff, 0x6004, Rd_Rs_I5
, do_rdrsi5
},
395 {"bitrev", 0x3800000c, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
396 {"bitset.c", 0x0000002b, 0x3e0003ff, 0x6005, Rd_Rs_I5
, do_rdrsi5
},
397 {"bittst.c", 0x0000002d, 0x3e0003ff, 0x6006, x_Rs_I5
, do_xrsi5
},
398 {"bittgl.c", 0x0000002f, 0x3e0003ff, 0x6007, Rd_Rs_I5
, do_rdrsi5
},
399 {"bitclr!", 0x6004, 0x7007, 0x00000029, Rd_I5
, do16_rdi5
},
400 {"bitset!", 0x6005, 0x7007, 0x0000002b, Rd_I5
, do16_rdi5
},
401 {"bittst!", 0x6006, 0x7007, 0x0000002d, Rd_I5
, do16_rdi5
},
402 {"bittgl!", 0x6007, 0x7007, 0x0000002f, Rd_I5
, do16_rdi5
},
403 {"bleu", 0x08000c00, 0x3e007c01, 0x4000, PC_DISP19div2
, do_branch
},
404 {"ble", 0x08001c00, 0x3e007c01, 0x4000, PC_DISP19div2
, do_branch
},
405 {"blt", 0x08002400, 0x3e007c01, 0x4000, PC_DISP19div2
, do_branch
},
406 {"bleul", 0x08000c01, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
407 {"blel", 0x08001c01, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
408 {"bltl", 0x08002401, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
409 {"bl", 0x08003c01, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
410 {"bleu!", 0x4300, 0x7f00, 0x08000c00, PC_DISP8div2
, do16_branch
},
411 {"ble!", 0x4700, 0x7f00, 0x08001c00, PC_DISP8div2
, do16_branch
},
412 {"blt!", 0x4900, 0x7f00, 0x08002400, PC_DISP8div2
, do16_branch
},
413 {"bmi", 0x08002800, 0x3e007c01, 0x4000, PC_DISP19div2
, do_branch
},
414 {"bmil", 0x08002801, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
415 {"bmi!", 0x00004a00, 0x00007f00, 0x08002800, PC_DISP8div2
, do16_branch
},
416 {"bne", 0x08001400, 0x3e007c01, 0x4000, PC_DISP19div2
, do_branch
},
417 {"bnel", 0x08001401, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
418 {"bne!", 0x4500, 0x7f00, 0x08001400, PC_DISP8div2
, do16_branch
},
419 {"bpl", 0x08002c00, 0x3e007c01, 0x4000, PC_DISP19div2
, do_branch
},
420 {"bpll", 0x08002c01, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
421 {"bpl!", 0x4b00, 0x7f00, 0x08002c00, PC_DISP8div2
, do16_branch
},
422 {"brcs", 0x00000008, 0x3e007fff, 0x0004, x_Rs_x
, do_rs
},
423 {"brcc", 0x00000408, 0x3e007fff, 0x0104, x_Rs_x
, do_rs
},
424 {"brgtu", 0x00000808, 0x3e007fff, 0x0204, x_Rs_x
, do_rs
},
425 {"brleu", 0x00000c08, 0x3e007fff, 0x0304, x_Rs_x
, do_rs
},
426 {"breq", 0x00001008, 0x3e007fff, 0x0404, x_Rs_x
, do_rs
},
427 {"brne", 0x00001408, 0x3e007fff, 0x0504, x_Rs_x
, do_rs
},
428 {"brgt", 0x00001808, 0x3e007fff, 0x0604, x_Rs_x
, do_rs
},
429 {"brle", 0x00001c08, 0x3e007fff, 0x0704, x_Rs_x
, do_rs
},
430 {"brge", 0x00002008, 0x3e007fff, 0x0804, x_Rs_x
, do_rs
},
431 {"brlt", 0x00002408, 0x3e007fff, 0x0904, x_Rs_x
, do_rs
},
432 {"brmi", 0x00002808, 0x3e007fff, 0x0a04, x_Rs_x
, do_rs
},
433 {"brpl", 0x00002c08, 0x3e007fff, 0x0b04, x_Rs_x
, do_rs
},
434 {"brvs", 0x00003008, 0x3e007fff, 0x0c04, x_Rs_x
, do_rs
},
435 {"brvc", 0x00003408, 0x3e007fff, 0x0d04, x_Rs_x
, do_rs
},
436 {"brcnz", 0x00003808, 0x3e007fff, 0x0e04, x_Rs_x
, do_rs
},
437 {"br", 0x00003c08, 0x3e007fff, 0x0f04, x_Rs_x
, do_rs
},
438 {"brcsl", 0x00000009, 0x3e007fff, 0x000c, x_Rs_x
, do_rs
},
439 {"brccl", 0x00000409, 0x3e007fff, 0x010c, x_Rs_x
, do_rs
},
440 {"brgtul", 0x00000809, 0x3e007fff, 0x020c, x_Rs_x
, do_rs
},
441 {"brleul", 0x00000c09, 0x3e007fff, 0x030c, x_Rs_x
, do_rs
},
442 {"breql", 0x00001009, 0x3e007fff, 0x040c, x_Rs_x
, do_rs
},
443 {"brnel", 0x00001409, 0x3e007fff, 0x050c, x_Rs_x
, do_rs
},
444 {"brgtl", 0x00001809, 0x3e007fff, 0x060c, x_Rs_x
, do_rs
},
445 {"brlel", 0x00001c09, 0x3e007fff, 0x070c, x_Rs_x
, do_rs
},
446 {"brgel", 0x00002009, 0x3e007fff, 0x080c, x_Rs_x
, do_rs
},
447 {"brltl", 0x00002409, 0x3e007fff, 0x090c, x_Rs_x
, do_rs
},
448 {"brmil", 0x00002809, 0x3e007fff, 0x0a0c, x_Rs_x
, do_rs
},
449 {"brpll", 0x00002c09, 0x3e007fff, 0x0b0c, x_Rs_x
, do_rs
},
450 {"brvsl", 0x00003009, 0x3e007fff, 0x0c0c, x_Rs_x
, do_rs
},
451 {"brvcl", 0x00003409, 0x3e007fff, 0x0d0c, x_Rs_x
, do_rs
},
452 {"brcnzl", 0x00003809, 0x3e007fff, 0x0e0c, x_Rs_x
, do_rs
},
453 {"brl", 0x00003c09, 0x3e007fff, 0x0f0c, x_Rs_x
, do_rs
},
454 {"brcs!", 0x0004, 0x7f0f, 0x00000008, x_Rs
, do16_xrs
},
455 {"brcc!", 0x0104, 0x7f0f, 0x00000408, x_Rs
, do16_xrs
},
456 {"brgtu!", 0x0204, 0x7f0f, 0x00000808, x_Rs
, do16_xrs
},
457 {"brleu!", 0x0304, 0x7f0f, 0x00000c08, x_Rs
, do16_xrs
},
458 {"breq!", 0x0404, 0x7f0f, 0x00001008, x_Rs
, do16_xrs
},
459 {"brne!", 0x0504, 0x7f0f, 0x00001408, x_Rs
, do16_xrs
},
460 {"brgt!", 0x0604, 0x7f0f, 0x00001808, x_Rs
, do16_xrs
},
461 {"brle!", 0x0704, 0x7f0f, 0x00001c08, x_Rs
, do16_xrs
},
462 {"brge!", 0x0804, 0x7f0f, 0x00002008, x_Rs
, do16_xrs
},
463 {"brlt!", 0x0904, 0x7f0f, 0x00002408, x_Rs
, do16_xrs
},
464 {"brmi!", 0x0a04, 0x7f0f, 0x00002808, x_Rs
, do16_xrs
},
465 {"brpl!", 0x0b04, 0x7f0f, 0x00002c08, x_Rs
, do16_xrs
},
466 {"brvs!", 0x0c04, 0x7f0f, 0x00003008, x_Rs
, do16_xrs
},
467 {"brvc!", 0x0d04, 0x7f0f, 0x00003408, x_Rs
, do16_xrs
},
468 {"brcnz!", 0x0e04, 0x7f0f, 0x00003808, x_Rs
, do16_xrs
},
469 {"br!", 0x0f04, 0x7f0f, 0x00003c08, x_Rs
, do16_xrs
},
470 {"brcsl!", 0x000c, 0x7f0f, 0x00000009, x_Rs
, do16_xrs
},
471 {"brccl!", 0x010c, 0x7f0f, 0x00000409, x_Rs
, do16_xrs
},
472 {"brgtul!", 0x020c, 0x7f0f, 0x00000809, x_Rs
, do16_xrs
},
473 {"brleul!", 0x030c, 0x7f0f, 0x00000c09, x_Rs
, do16_xrs
},
474 {"breql!", 0x040c, 0x7f0f, 0x00001009, x_Rs
, do16_xrs
},
475 {"brnel!", 0x050c, 0x7f0f, 0x00001409, x_Rs
, do16_xrs
},
476 {"brgtl!", 0x060c, 0x7f0f, 0x00001809, x_Rs
, do16_xrs
},
477 {"brlel!", 0x070c, 0x7f0f, 0x00001c09, x_Rs
, do16_xrs
},
478 {"brgel!", 0x080c, 0x7f0f, 0x00002009, x_Rs
, do16_xrs
},
479 {"brltl!", 0x090c, 0x7f0f, 0x00002409, x_Rs
, do16_xrs
},
480 {"brmil!", 0x0a0c, 0x7f0f, 0x00002809, x_Rs
, do16_xrs
},
481 {"brpll!", 0x0b0c, 0x7f0f, 0x00002c09, x_Rs
, do16_xrs
},
482 {"brvsl!", 0x0c0c, 0x7f0f, 0x00003009, x_Rs
, do16_xrs
},
483 {"brvcl!", 0x0d0c, 0x7f0f, 0x00003409, x_Rs
, do16_xrs
},
484 {"brcnzl!", 0x0e0c, 0x7f0f, 0x00003809, x_Rs
, do16_xrs
},
485 {"brl!", 0x0f0c, 0x7f0f, 0x00003c09, x_Rs
, do16_xrs
},
486 {"bvs", 0x08003000, 0x3e007c01, 0x4000, PC_DISP19div2
, do_branch
},
487 {"bvc", 0x08003400, 0x3e007c01, 0x4000, PC_DISP19div2
, do_branch
},
488 {"bvsl", 0x08003001, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
489 {"bvcl", 0x08003401, 0x3e007c01, 0x8000, PC_DISP19div2
, do_branch
},
490 {"bvs!", 0x4c00, 0x7f00, 0x08003000, PC_DISP8div2
, do16_branch
},
491 {"bvc!", 0x4d00, 0x7f00, 0x08003400, PC_DISP8div2
, do16_branch
},
492 {"b!", 0x4f00, 0x7f00, 0x08003c00, PC_DISP8div2
, do16_branch
},
493 {"b", 0x08003c00, 0x3e007c01, 0x4000, PC_DISP19div2
, do_branch
},
494 {"cache", 0x30000000, 0x3ff00000, 0x8000, OP5_rvalueRs_SI15
, do_cache
},
495 {"ceinst", 0x38000000, 0x3e000000, 0x8000, I5_Rs_Rs_I5_OP5
, do_ceinst
},
496 {"clz", 0x3800000d, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
497 {"cmpteq.c", 0x00000019, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
498 {"cmptmi.c", 0x00100019, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
499 {"cmp.c", 0x00300019, 0x3ff003ff, 0x2003, x_Rs_Rs
, do_rsrs
},
500 {"cmpzteq.c", 0x0000001b, 0x3ff07fff, 0x8000, x_Rs_x
, do_rs
},
501 {"cmpztmi.c", 0x0010001b, 0x3ff07fff, 0x8000, x_Rs_x
, do_rs
},
502 {"cmpz.c", 0x0030001b, 0x3ff07fff, 0x8000, x_Rs_x
, do_rs
},
503 {"cmpi.c", 0x02040001, 0x3e0e0001, 0x8000, Rd_SI16
, do_rdsi16
},
504 {"cmp!", 0x2003, 0x700f, 0x00300019, Rd_Rs
, do16_rdrs
},
505 {"cop1", 0x0c00000c, 0x3e00001f, 0x8000, Rd_Rs_Rs_imm
, do_crdcrscrsimm5
},
506 {"cop2", 0x0c000014, 0x3e00001f, 0x8000, Rd_Rs_Rs_imm
, do_crdcrscrsimm5
},
507 {"cop3", 0x0c00001c, 0x3e00001f, 0x8000, Rd_Rs_Rs_imm
, do_crdcrscrsimm5
},
508 {"drte", 0x0c0000a4, 0x3e0003ff, 0x8000, NO_OPD
, do_empty
},
509 {"extsb", 0x00000058, 0x3e0003ff, 0x8000, Rd_Rs_x
, do_rdrs
},
510 {"extsb.c", 0x00000059, 0x3e0003ff, 0x8000, Rd_Rs_x
, do_rdrs
},
511 {"extsh", 0x0000005a, 0x3e0003ff, 0x8000, Rd_Rs_x
, do_rdrs
},
512 {"extsh.c", 0x0000005b, 0x3e0003ff, 0x8000, Rd_Rs_x
, do_rdrs
},
513 {"extzb", 0x0000005c, 0x3e0003ff, 0x8000, Rd_Rs_x
, do_rdrs
},
514 {"extzb.c", 0x0000005d, 0x3e0003ff, 0x8000, Rd_Rs_x
, do_rdrs
},
515 {"extzh", 0x0000005e, 0x3e0003ff, 0x8000, Rd_Rs_x
, do_rdrs
},
516 {"extzh.c", 0x0000005f, 0x3e0003ff, 0x8000, Rd_Rs_x
, do_rdrs
},
517 {"jl", 0x04000001, 0x3e000001, 0x8000, PC_DISP24div2
, do_jump
},
518 {"jl!", 0x3001, 0x7001, 0x04000001, PC_DISP11div2
, do16_jump
},
519 {"j!", 0x3000, 0x7001, 0x04000000, PC_DISP11div2
, do16_jump
},
520 {"j", 0x04000000, 0x3e000001, 0x8000, PC_DISP24div2
, do_jump
},
521 {"lbu!", 0x200b, 0x0000700f, 0x2c000000, Rd_rvalueRs
, do16_ldst_insn
},
522 {"lbup!", 0x7003, 0x7007, 0x2c000000, Rd_rvalueBP_I5
, do16_ldst_imm_insn
},
523 {"alw", 0x0000000c, 0x3e0003ff, 0x8000, Rd_rvalue32Rs
, do_ldst_atomic
},
524 {"lcb", 0x00000060, 0x3e0003ff, 0x8000, x_rvalueRs_post4
, do_ldst_unalign
},
525 {"lcw", 0x00000062, 0x3e0003ff, 0x8000, Rd_rvalueRs_post4
, do_ldst_unalign
},
526 {"lce", 0x00000066, 0x3e0003ff, 0x8000, Rd_rvalueRs_post4
, do_ldst_unalign
},
527 {"ldc1", 0x0c00000a, 0x3e00001f, 0x8000, Rd_rvalueRs_SI10
, do_ldst_cop
},
528 {"ldc2", 0x0c000012, 0x3e00001f, 0x8000, Rd_rvalueRs_SI10
, do_ldst_cop
},
529 {"ldc3", 0x0c00001a, 0x3e00001f, 0x8000, Rd_rvalueRs_SI10
, do_ldst_cop
},
530 {"lh!", 0x2009, 0x700f, 0x22000000, Rd_rvalueRs
, do16_ldst_insn
},
531 {"lhp!", 0x7001, 0x7007, 0x22000000, Rd_rvalueBP_I5
, do16_ldst_imm_insn
},
532 {"ldi", 0x020c0000, 0x3e0e0000, 0x5000, Rd_SI16
, do_rdsi16
},
533 {"ldis", 0x0a0c0000, 0x3e0e0000, 0x8000, Rd_I16
, do_rdi16
},
534 {"ldiu!", 0x5000, 0x7000, 0x020c0000, Rd_I8
, do16_ldst_imm_insn
},
535 {"lw!", 0x2008, 0x700f, 0x20000000, Rd_rvalueRs
, do16_ldst_insn
},
536 {"lwp!", 0x7000, 0x7007, 0x20000000, Rd_rvalueBP_I5
, do16_ldst_imm_insn
},
537 {"mfcel", 0x00000448, 0x3e007fff, 0x8000, Rd_x_x
, do_rd
},
538 {"mfcel!", 0x1001, 0x7f0f, 0x00000448, x_Rs
, do16_rs
},
539 {"mad", 0x38000000, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
540 {"mad.f!", 0x1004, 0x700f, 0x38000080, Rd_Rs
, do16_rdrs
},
541 {"madh", 0x38000203, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
542 {"madh.fs", 0x380002c3, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
543 {"madh.fs!", 0x100b, 0x700f, 0x380002c3, Rd_Rs
, do16_rdrs
},
544 {"madl", 0x38000002, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
545 {"madl.fs", 0x380000c2, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
546 {"madl.fs!", 0x100a, 0x700f, 0x380000c2, Rd_Rs
, do16_rdrs
},
547 {"madu", 0x38000020, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
548 {"madu!", 0x1005, 0x700f, 0x38000020, Rd_Rs
, do16_rdrs
},
549 {"mad.f", 0x38000080, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
550 {"max", 0x38000007, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
551 {"mazh", 0x38000303, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
552 {"mazh.f", 0x38000383, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
553 {"mazh.f!", 0x1009, 0x700f, 0x3800038c, Rd_Rs
, do16_rdrs
},
554 {"mazl", 0x38000102, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
555 {"mazl.f", 0x38000182, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
556 {"mazl.f!", 0x1008, 0x700f, 0x38000182, Rd_Rs
, do16_rdrs
},
557 {"mfceh", 0x00000848, 0x3e007fff, 0x8000, Rd_x_x
, do_rd
},
558 {"mfceh!", 0x1101, 0x7f0f, 0x00000848, x_Rs
, do16_rs
},
559 {"mfcehl", 0x00000c48, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
560 {"mfsr", 0x00000050, 0x3e0003ff, 0x8000, Rd_x_I5
, do_rdsrs
},
561 {"mfcr", 0x0c000001, 0x3e00001f, 0x8000, Rd_Rs_x
, do_rdcrs
},
562 {"mfc1", 0x0c000009, 0x3e00001f, 0x8000, Rd_Rs_x
, do_rdcrs
},
563 {"mfc2", 0x0c000011, 0x3e00001f, 0x8000, Rd_Rs_x
, do_rdcrs
},
564 {"mfc3", 0x0c000019, 0x3e00001f, 0x8000, Rd_Rs_x
, do_rdcrs
},
565 {"mfcc1", 0x0c00000f, 0x3e00001f, 0x8000, Rd_Rs_x
, do_rdcrs
},
566 {"mfcc2", 0x0c000017, 0x3e00001f, 0x8000, Rd_Rs_x
, do_rdcrs
},
567 {"mfcc3", 0x0c00001f, 0x3e00001f, 0x8000, Rd_Rs_x
, do_rdcrs
},
568 {"mhfl!", 0x0002, 0x700f, 0x00003c56, Rd_LowRs
, do16_hrdrs
},
569 {"min", 0x38000006, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
570 {"mlfh!", 0x0001, 0x700f, 0x00003c56, Rd_HighRs
, do16_rdhrs
},
571 {"msb", 0x38000001, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
572 {"msb.f!", 0x1006, 0x700f, 0x38000081, Rd_Rs
, do16_rdrs
},
573 {"msbh", 0x38000205, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
574 {"msbh.fs", 0x380002c5, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
575 {"msbh.fs!", 0x100f, 0x700f, 0x380002c5, Rd_Rs
, do16_rdrs
},
576 {"msbl", 0x38000004, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
577 {"msbl.fs", 0x380000c4, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
578 {"msbl.fs!", 0x100e, 0x700f, 0x380000c4, Rd_Rs
, do16_rdrs
},
579 {"msbu", 0x38000021, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
580 {"msbu!", 0x1007, 0x700f, 0x38000021, Rd_Rs
, do16_rdrs
},
581 {"msb.f", 0x38000081, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
582 {"mszh", 0x38000305, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
583 {"mszh.f", 0x38000385, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
584 {"mszh.f!", 0x100d, 0x700f, 0x38000385, Rd_Rs
, do16_rdrs
},
585 {"mszl", 0x38000104, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
586 {"mszl.f", 0x38000184, 0x3ff003ff, 0x8000, x_Rs_Rs
, do_rsrs
},
587 {"mszl.f!", 0x100c, 0x700f, 0x38000184, Rd_Rs
, do16_rdrs
},
588 {"mtcel!", 0x1000, 0x7f0f, 0x0000044a, x_Rs
, do16_rs
},
589 {"mtcel", 0x0000044a, 0x3e007fff, 0x8000, Rd_x_x
, do_rd
},
590 {"mtceh", 0x0000084a, 0x3e007fff, 0x8000, Rd_x_x
, do_rd
},
591 {"mtceh!", 0x1100, 0x7f0f, 0x0000084a, x_Rs
, do16_rs
},
592 {"mtcehl", 0x00000c4a, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
593 {"mtsr", 0x00000052, 0x3e0003ff, 0x8000, x_Rs_I5
, do_rdsrs
},
594 {"mtcr", 0x0c000000, 0x3e00001f, 0x8000, Rd_Rs_x
, do_rdcrs
},
595 {"mtc1", 0x0c000008, 0x3e00001f, 0x8000, Rd_Rs_x
, do_rdcrs
},
596 {"mtc2", 0x0c000010, 0x3e00001f, 0x8000, Rd_Rs_x
, do_rdcrs
},
597 {"mtc3", 0x0c000018, 0x3e00001f, 0x8000, Rd_Rs_x
, do_rdcrs
},
598 {"mtcc1", 0x0c00000e, 0x3e00001f, 0x8000, Rd_Rs_x
, do_rdcrs
},
599 {"mtcc2", 0x0c000016, 0x3e00001f, 0x8000, Rd_Rs_x
, do_rdcrs
},
600 {"mtcc3", 0x0c00001e, 0x3e00001f, 0x8000, Rd_Rs_x
, do_rdcrs
},
601 {"mul.f!", 0x1002, 0x700f, 0x00000041, Rd_Rs
, do16_rdrs
},
602 {"mulu!", 0x1003, 0x700f, 0x00000042, Rd_Rs
, do16_rdrs
},
603 {"mvcs", 0x00000056, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
604 {"mvcc", 0x00000456, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
605 {"mvgtu", 0x00000856, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
606 {"mvleu", 0x00000c56, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
607 {"mveq", 0x00001056, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
608 {"mvne", 0x00001456, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
609 {"mvgt", 0x00001856, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
610 {"mvle", 0x00001c56, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
611 {"mvge", 0x00002056, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
612 {"mvlt", 0x00002456, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
613 {"mvmi", 0x00002856, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
614 {"mvpl", 0x00002c56, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
615 {"mvvs", 0x00003056, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
616 {"mvvc", 0x00003456, 0x3e007fff, 0x8000, Rd_Rs_x
, do_rdrs
},
617 {"mv", 0x00003c56, 0x3e007fff, 0x0003, Rd_Rs_x
, do_rdrs
},
618 {"mv!", 0x0003, 0x700f, 0x00003c56, Rd_Rs
, do16_mv_rdrs
},
619 {"neg", 0x0000001e, 0x3e0003ff, 0x8000, Rd_x_Rs
, do_rdxrs
},
620 {"neg.c", 0x0000001f, 0x3e0003ff, 0x2002, Rd_x_Rs
, do_rdxrs
},
621 {"neg!", 0x2002, 0x700f, 0x0000001f, Rd_Rs
, do16_rdrs
},
622 {"nop", 0x00000000, 0x3e0003ff, 0x0000, NO_OPD
, do_empty
},
623 {"not", 0x00000024, 0x3e0003ff, 0x8000, Rd_Rs_x
, do_rdrs
},
624 {"not.c", 0x00000025, 0x3e0003ff, 0x2006, Rd_Rs_x
, do_rdrs
},
625 {"nop!", 0x0000, 0x700f, 0x00000000, NO16_OPD
, do_empty
},
626 {"not!", 0x2006, 0x700f, 0x00000025, Rd_Rs
, do16_rdrs
},
627 {"or", 0x00000022, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
628 {"or.c", 0x00000023, 0x3e0003ff, 0x2005, Rd_Rs_Rs
, do_rdrsrs
},
629 {"ori", 0x020a0000, 0x3e0e0001, 0x8000, Rd_I16
, do_rdi16
},
630 {"ori.c", 0x020a0001, 0x3e0e0001, 0x8000, Rd_I16
, do_rdi16
},
631 {"oris", 0x0a0a0000, 0x3e0e0001, 0x8000, Rd_I16
, do_rdi16
},
632 {"oris.c", 0x0a0a0001, 0x3e0e0001, 0x8000, Rd_I16
, do_rdi16
},
633 {"orri", 0x1a000000, 0x3e000001, 0x8000, Rd_Rs_I14
, do_rdrsi14
},
634 {"orri.c", 0x1a000001, 0x3e000001, 0x8000, Rd_Rs_I14
, do_rdrsi14
},
635 {"or!", 0x2005, 0x700f, 0x00000023, Rd_Rs
, do16_rdrs
},
636 {"pflush", 0x0000000a, 0x3e0003ff, 0x8000, NO_OPD
, do_empty
},
637 {"pop!", 0x200a, 0x700f, 0x0e000000, Rd_rvalueRs
, do16_push_pop
},
638 {"push!", 0x200e, 0x700f, 0x06000004, Rd_lvalueRs
, do16_push_pop
},
639 {"ror", 0x00000038, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
640 {"ror.c", 0x00000039, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
641 {"rorc.c", 0x0000003b, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
642 {"rol", 0x0000003c, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
643 {"rol.c", 0x0000003d, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
644 {"rolc.c", 0x0000003f, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
645 {"rori", 0x00000078, 0x3e0003ff, 0x8000, Rd_Rs_I5
, do_rdrsi5
},
646 {"rori.c", 0x00000079, 0x3e0003ff, 0x8000, Rd_Rs_I5
, do_rdrsi5
},
647 {"roric.c", 0x0000007b, 0x3e0003ff, 0x8000, Rd_Rs_I5
, do_rdrsi5
},
648 {"roli", 0x0000007c, 0x3e0003ff, 0x8000, Rd_Rs_I5
, do_rdrsi5
},
649 {"roli.c", 0x0000007d, 0x3e0003ff, 0x8000, Rd_Rs_I5
, do_rdrsi5
},
650 {"rolic.c", 0x0000007f, 0x3e0003ff, 0x8000, Rd_Rs_I5
, do_rdrsi5
},
651 {"rte", 0x0c000084, 0x3e0003ff, 0x8000, NO_OPD
, do_empty
},
652 {"sb!", 0x200f, 0x700f, 0x2e000000, Rd_lvalueRs
, do16_ldst_insn
},
653 {"sbp!", 0x7007, 0x7007, 0x2e000000, Rd_lvalueBP_I5
, do16_ldst_imm_insn
},
654 {"asw", 0x0000000e, 0x3e0003ff, 0x8000, Rd_lvalue32Rs
, do_ldst_atomic
},
655 {"scb", 0x00000068, 0x3e0003ff, 0x8000, Rd_lvalueRs_post4
, do_ldst_unalign
},
656 {"scw", 0x0000006a, 0x3e0003ff, 0x8000, Rd_lvalueRs_post4
, do_ldst_unalign
},
657 {"sce", 0x0000006e, 0x3e0003ff, 0x8000, x_lvalueRs_post4
, do_ldst_unalign
},
658 {"sdbbp", 0x00000006, 0x3e0003ff, 0x6002, x_I5_x
, do_xi5x
},
659 {"sdbbp!", 0x6002, 0x7007, 0x00000006, Rd_I5
, do16_xi5
},
660 {"sh!", 0x200d, 0x700f, 0x2a000000, Rd_lvalueRs
, do16_ldst_insn
},
661 {"shp!", 0x7005, 0x7007, 0x2a000000, Rd_lvalueBP_I5
, do16_ldst_imm_insn
},
662 {"sleep", 0x0c0000c4, 0x3e0003ff, 0x8000, NO_OPD
, do_empty
},
663 {"sll", 0x00000030, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
664 {"sll.c", 0x00000031, 0x3e0003ff, 0x0008, Rd_Rs_Rs
, do_rdrsrs
},
665 {"sll.s", 0x3800004e, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
666 {"slli", 0x00000070, 0x3e0003ff, 0x8000, Rd_Rs_I5
, do_rdrsi5
},
667 {"slli.c", 0x00000071, 0x3e0003ff, 0x6001, Rd_Rs_I5
, do_rdrsi5
},
668 {"sll!", 0x0008, 0x700f, 0x00000031, Rd_Rs
, do16_rdrs
},
669 {"slli!", 0x6001, 0x7007, 0x00000071, Rd_I5
, do16_rdi5
},
670 {"srl", 0x00000034, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
671 {"srl.c", 0x00000035, 0x3e0003ff, 0x000a, Rd_Rs_Rs
, do_rdrsrs
},
672 {"sra", 0x00000036, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
673 {"sra.c", 0x00000037, 0x3e0003ff, 0x000b, Rd_Rs_Rs
, do_rdrsrs
},
674 {"srli", 0x00000074, 0x3e0003ff, 0x8000, Rd_Rs_I5
, do_rdrsi5
},
675 {"srli.c", 0x00000075, 0x3e0003ff, 0x6003, Rd_Rs_I5
, do_rdrsi5
},
676 {"srai", 0x00000076, 0x3e0003ff, 0x8000, Rd_Rs_I5
, do_rdrsi5
},
677 {"srai.c", 0x00000077, 0x3e0003ff, 0x8000, Rd_Rs_I5
, do_rdrsi5
},
678 {"srl!", 0x000a, 0x700f, 0x00000035, Rd_Rs
, do16_rdrs
},
679 {"sra!", 0x000b, 0x700f, 0x00000037, Rd_Rs
, do16_rdrs
},
680 {"srli!", 0x6003, 0x7007, 0x00000075, Rd_Rs
, do16_rdi5
},
681 {"stc1", 0x0c00000b, 0x3e00001f, 0x8000, Rd_lvalueRs_SI10
, do_ldst_cop
},
682 {"stc2", 0x0c000013, 0x3e00001f, 0x8000, Rd_lvalueRs_SI10
, do_ldst_cop
},
683 {"stc3", 0x0c00001b, 0x3e00001f, 0x8000, Rd_lvalueRs_SI10
, do_ldst_cop
},
684 {"sub", 0x00000014, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
685 {"sub.c", 0x00000015, 0x3e0003ff, 0x2001, Rd_Rs_Rs
, do_rdrsrs
},
686 {"sub.s", 0x38000049, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
687 {"subc", 0x00000016, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
688 {"subc.c", 0x00000017, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
689 {"sub!", 0x2001, 0x700f, 0x00000015, Rd_Rs
, do16_rdrs
},
690 {"subei!", 0x6080, 0x7087, 0x02000001, Rd_I4
, do16_rdi4
},
691 {"sw!", 0x200c, 0x700f, 0x28000000, Rd_lvalueRs
, do16_ldst_insn
},
692 {"swp!", 0x7004, 0x7007, 0x28000000, Rd_lvalueBP_I5
, do16_ldst_imm_insn
},
693 {"syscall", 0x00000002, 0x3e0003ff, 0x8000, I15
, do_i15
},
694 {"tcs", 0x00000054, 0x3e007fff, 0x0005, NO_OPD
, do_empty
},
695 {"tcc", 0x00000454, 0x3e007fff, 0x0105, NO_OPD
, do_empty
},
696 {"tcnz", 0x00003854, 0x3e007fff, 0x0e05, NO_OPD
, do_empty
},
697 {"tcs!", 0x0005, 0x7f0f, 0x00000054, NO16_OPD
, do_empty
},
698 {"tcc!", 0x0105, 0x7f0f, 0x00000454, NO16_OPD
, do_empty
},
699 {"tcnz!", 0x0e05, 0x7f0f, 0x00003854, NO16_OPD
, do_empty
},
700 {"teq", 0x00001054, 0x3e007fff, 0x0405, NO_OPD
, do_empty
},
701 {"teq!", 0x0405, 0x7f0f, 0x00001054, NO16_OPD
, do_empty
},
702 {"tgtu", 0x00000854, 0x3e007fff, 0x0205, NO_OPD
, do_empty
},
703 {"tgt", 0x00001854, 0x3e007fff, 0x0605, NO_OPD
, do_empty
},
704 {"tge", 0x00002054, 0x3e007fff, 0x0805, NO_OPD
, do_empty
},
705 {"tgtu!", 0x0205, 0x7f0f, 0x00000854, NO16_OPD
, do_empty
},
706 {"tgt!", 0x0605, 0x7f0f, 0x00001854, NO16_OPD
, do_empty
},
707 {"tge!", 0x0805, 0x7f0f, 0x00002054, NO16_OPD
, do_empty
},
708 {"tleu", 0x00000c54, 0x3e007fff, 0x0305, NO_OPD
, do_empty
},
709 {"tle", 0x00001c54, 0x3e007fff, 0x0705, NO_OPD
, do_empty
},
710 {"tlt", 0x00002454, 0x3e007fff, 0x0905, NO_OPD
, do_empty
},
711 {"stlb", 0x0c000004, 0x3e0003ff, 0x8000, NO_OPD
, do_empty
},
712 {"mftlb", 0x0c000024, 0x3e0003ff, 0x8000, NO_OPD
, do_empty
},
713 {"mtptlb", 0x0c000044, 0x3e0003ff, 0x8000, NO_OPD
, do_empty
},
714 {"mtrtlb", 0x0c000064, 0x3e0003ff, 0x8000, NO_OPD
, do_empty
},
715 {"tleu!", 0x0305, 0x7f0f, 0x00000c54, NO16_OPD
, do_empty
},
716 {"tle!", 0x0705, 0x7f0f, 0x00001c54, NO16_OPD
, do_empty
},
717 {"tlt!", 0x0905, 0x7f0f, 0x00002454, NO16_OPD
, do_empty
},
718 {"tmi", 0x00002854, 0x3e007fff, 0x0a05, NO_OPD
, do_empty
},
719 {"tmi!", 0x0a05, 0x7f0f, 0x00002854, NO16_OPD
, do_empty
},
720 {"tne", 0x00001454, 0x3e007fff, 0x0505, NO_OPD
, do_empty
},
721 {"tne!", 0x0505, 0x7f0f, 0x00001454, NO16_OPD
, do_empty
},
722 {"tpl", 0x00002c54, 0x3e007fff, 0x0b05, NO_OPD
, do_empty
},
723 {"tpl!", 0x0b05, 0x7f0f, 0x00002c54, NO16_OPD
, do_empty
},
724 {"trapcs", 0x00000004, 0x3e007fff, 0x8000, x_I5_x
, do_xi5x
},
725 {"trapcc", 0x00000404, 0x3e007fff, 0x8000, x_I5_x
, do_xi5x
},
726 {"trapgtu", 0x00000804, 0x3e007fff, 0x8000, x_I5_x
, do_xi5x
},
727 {"trapleu", 0x00000c04, 0x3e007fff, 0x8000, x_I5_x
, do_xi5x
},
728 {"trapeq", 0x00001004, 0x3e007fff, 0x8000, x_I5_x
, do_xi5x
},
729 {"trapne", 0x00001404, 0x3e007fff, 0x8000, x_I5_x
, do_xi5x
},
730 {"trapgt", 0x00001804, 0x3e007fff, 0x8000, x_I5_x
, do_xi5x
},
731 {"traple", 0x00001c04, 0x3e007fff, 0x8000, x_I5_x
, do_xi5x
},
732 {"trapge", 0x00002004, 0x3e007fff, 0x8000, x_I5_x
, do_xi5x
},
733 {"traplt", 0x00002404, 0x3e007fff, 0x8000, x_I5_x
, do_xi5x
},
734 {"trapmi", 0x00002804, 0x3e007fff, 0x8000, x_I5_x
, do_xi5x
},
735 {"trappl", 0x00002c04, 0x3e007fff, 0x8000, x_I5_x
, do_xi5x
},
736 {"trapvs", 0x00003004, 0x3e007fff, 0x8000, x_I5_x
, do_xi5x
},
737 {"trapvc", 0x00003404, 0x3e007fff, 0x8000, x_I5_x
, do_xi5x
},
738 {"trap", 0x00003c04, 0x3e007fff, 0x8000, x_I5_x
, do_xi5x
},
739 {"tset", 0x00003c54, 0x3e007fff, 0x0f05, NO_OPD
, do_empty
},
740 {"tset!", 0x0f05, 0x00007f0f, 0x00003c54, NO16_OPD
, do_empty
},
741 {"tvs", 0x00003054, 0x3e007fff, 0x0c05, NO_OPD
, do_empty
},
742 {"tvc", 0x00003454, 0x3e007fff, 0x0d05, NO_OPD
, do_empty
},
743 {"tvs!", 0x0c05, 0x7f0f, 0x00003054, NO16_OPD
, do_empty
},
744 {"tvc!", 0x0d05, 0x7f0f, 0x00003454, NO16_OPD
, do_empty
},
745 {"xor", 0x00000026, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, do_rdrsrs
},
746 {"xor.c", 0x00000027, 0x3e0003ff, 0x2007, Rd_Rs_Rs
, do_rdrsrs
},
747 {"xor!", 0x2007, 0x700f, 0x00000027, Rd_Rs
, do16_rdrs
},
748 /* Macro instruction. */
749 {"li", 0x020c0000, 0x3e0e0000, 0x8000, Insn_Type_SYN
, do_macro_li_rdi32
},
750 /* la reg, imm32 -->(1) ldi reg, simm16
751 (2) ldis reg, %HI(imm32)
754 la reg, symbol -->(1) lis reg, %HI(imm32)
755 ori reg, %LO(imm32) */
756 {"la", 0x020c0000, 0x3e0e0000, 0x8000, Insn_Type_SYN
, do_macro_la_rdi32
},
757 {"div", 0x00000044, 0x3e0003ff, 0x8000, Insn_Type_SYN
, do_macro_mul_rdrsrs
},
758 {"divu", 0x00000046, 0x3e0003ff, 0x8000, Insn_Type_SYN
, do_macro_mul_rdrsrs
},
759 {"rem", 0x00000044, 0x3e0003ff, 0x8000, Insn_Type_SYN
, do_macro_mul_rdrsrs
},
760 {"remu", 0x00000046, 0x3e0003ff, 0x8000, Insn_Type_SYN
, do_macro_mul_rdrsrs
},
761 {"mul", 0x00000040, 0x3e0003ff, 0x8000, Insn_Type_SYN
, do_macro_mul_rdrsrs
},
762 {"mulu", 0x00000042, 0x3e0003ff, 0x8000, Insn_Type_SYN
, do_macro_mul_rdrsrs
},
763 {"maz", 0x00000040, 0x3e0003ff, 0x8000, Insn_Type_SYN
, do_macro_mul_rdrsrs
},
764 {"mazu", 0x00000042, 0x3e0003ff, 0x8000, Insn_Type_SYN
, do_macro_mul_rdrsrs
},
765 {"mul.f", 0x00000041, 0x3e0003ff, 0x8000, Insn_Type_SYN
, do_macro_mul_rdrsrs
},
766 {"maz.f", 0x00000041, 0x3e0003ff, 0x8000, Insn_Type_SYN
, do_macro_mul_rdrsrs
},
767 {"lb", INSN_LB
, 0x00000000, 0x8000, Insn_Type_SYN
, do_macro_ldst_label
},
768 {"lbu", INSN_LBU
, 0x00000000, 0x200b, Insn_Type_SYN
, do_macro_ldst_label
},
769 {"lh", INSN_LH
, 0x00000000, 0x2009, Insn_Type_SYN
, do_macro_ldst_label
},
770 {"lhu", INSN_LHU
, 0x00000000, 0x8000, Insn_Type_SYN
, do_macro_ldst_label
},
771 {"lw", INSN_LW
, 0x00000000, 0x2008, Insn_Type_SYN
, do_macro_ldst_label
},
772 {"sb", INSN_SB
, 0x00000000, 0x200f, Insn_Type_SYN
, do_macro_ldst_label
},
773 {"sh", INSN_SH
, 0x00000000, 0x200d, Insn_Type_SYN
, do_macro_ldst_label
},
774 {"sw", INSN_SW
, 0x00000000, 0x200c, Insn_Type_SYN
, do_macro_ldst_label
},
775 /* Assembler use internal. */
776 {"ld_i32hi", 0x0a0c0000, 0x3e0e0000, 0x8000, Insn_internal
, do_macro_rdi32hi
},
777 {"ld_i32lo", 0x020a0000, 0x3e0e0001, 0x8000, Insn_internal
, do_macro_rdi32lo
},
778 {"ldis_pic", 0x0a0c0000, 0x3e0e0000, 0x5000, Insn_internal
, do_rdi16_pic
},
779 {"addi_s_pic",0x02000000, 0x3e0e0001, 0x8000, Insn_internal
, do_addi_s_pic
},
780 {"addi_u_pic",0x02000000, 0x3e0e0001, 0x8000, Insn_internal
, do_addi_u_pic
},
781 {"lw_pic", 0x20000000, 0x3e000000, 0x8000, Insn_internal
, do_lw_pic
},
784 /* Next free entry in the pool. */
785 int next_literal_pool_place
= 0;
787 /* Next literal pool number. */
788 int lit_pool_num
= 1;
789 symbolS
*current_poolP
= NULL
;
793 end_of_line (char *str
)
795 int retval
= SUCCESS
;
797 skip_whitespace (str
);
803 inst
.error
= BAD_GARBAGE
;
810 score_reg_parse (char **ccp
, struct hash_control
*htab
)
815 struct reg_entry
*reg
;
818 if (!ISALPHA (*p
) || !is_name_beginner (*p
))
823 while (ISALPHA (c
) || ISDIGIT (c
) || c
== '_')
827 reg
= (struct reg_entry
*) hash_find (htab
, start
);
838 /* If shift <= 0, only return reg. */
841 reg_required_here (char **str
, int shift
, enum score_reg_type reg_type
)
843 static char buff
[MAX_LITERAL_POOL_SIZE
];
844 int reg
= (int) FAIL
;
847 if ((reg
= score_reg_parse (str
, all_reg_maps
[reg_type
].htab
)) != (int) FAIL
)
849 if (reg_type
== REG_TYPE_SCORE
)
851 if ((reg
== 1) && (nor1
== 1) && (inst
.bwarn
== 0))
853 as_warn (_("Using temp register(r1)"));
859 if (reg_type
== REG_TYPE_SCORE_CR
)
860 strcpy (inst
.reg
, score_crn_table
[reg
].name
);
861 else if (reg_type
== REG_TYPE_SCORE_SR
)
862 strcpy (inst
.reg
, score_srn_table
[reg
].name
);
864 strcpy (inst
.reg
, "");
866 inst
.instruction
|= reg
<< shift
;
872 sprintf (buff
, _("register expected, not '%.100s'"), start
);
880 skip_past_comma (char **str
)
886 while ((c
= *p
) == ' ' || c
== ',')
889 if (c
== ',' && comma
++)
891 inst
.error
= BAD_SKIP_COMMA
;
896 if ((c
== '\0') || (comma
== 0))
898 inst
.error
= BAD_SKIP_COMMA
;
903 return comma
? SUCCESS
: (int) FAIL
;
907 do_rdrsrs (char *str
)
909 skip_whitespace (str
);
911 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) == (int) FAIL
912 || skip_past_comma (&str
) == (int) FAIL
913 || reg_required_here (&str
, 15, REG_TYPE_SCORE
) == (int) FAIL
914 || skip_past_comma (&str
) == (int) FAIL
915 || reg_required_here (&str
, 10, REG_TYPE_SCORE
) == (int) FAIL
916 || end_of_line (str
) == (int) FAIL
)
922 if ((((inst
.instruction
>> 15) & 0x10) == 0)
923 && (((inst
.instruction
>> 10) & 0x10) == 0)
924 && (((inst
.instruction
>> 20) & 0x10) == 0)
925 && (inst
.relax_inst
!= 0x8000)
926 && (((inst
.instruction
>> 20) & 0xf) == ((inst
.instruction
>> 15) & 0xf)))
928 inst
.relax_inst
|= (((inst
.instruction
>> 10) & 0xf) << 4)
929 | (((inst
.instruction
>> 15) & 0xf) << 8);
934 inst
.relax_inst
= 0x8000;
940 walk_no_bignums (symbolS
* sp
)
942 if (symbol_get_value_expression (sp
)->X_op
== O_big
)
945 if (symbol_get_value_expression (sp
)->X_add_symbol
)
946 return (walk_no_bignums (symbol_get_value_expression (sp
)->X_add_symbol
)
947 || (symbol_get_value_expression (sp
)->X_op_symbol
948 && walk_no_bignums (symbol_get_value_expression (sp
)->X_op_symbol
)));
954 my_get_expression (expressionS
* ep
, char **str
)
959 save_in
= input_line_pointer
;
960 input_line_pointer
= *str
;
961 in_my_get_expression
= 1;
962 seg
= expression (ep
);
963 in_my_get_expression
= 0;
965 if (ep
->X_op
== O_illegal
)
967 *str
= input_line_pointer
;
968 input_line_pointer
= save_in
;
969 inst
.error
= _("illegal expression");
972 /* Get rid of any bignums now, so that we don't generate an error for which
973 we can't establish a line number later on. Big numbers are never valid
974 in instructions, which is where this routine is always called. */
975 if (ep
->X_op
== O_big
977 && (walk_no_bignums (ep
->X_add_symbol
)
978 || (ep
->X_op_symbol
&& walk_no_bignums (ep
->X_op_symbol
)))))
980 inst
.error
= _("invalid constant");
981 *str
= input_line_pointer
;
982 input_line_pointer
= save_in
;
986 if ((ep
->X_add_symbol
!= NULL
)
987 && (inst
.type
!= PC_DISP19div2
)
988 && (inst
.type
!= PC_DISP8div2
)
989 && (inst
.type
!= PC_DISP24div2
)
990 && (inst
.type
!= PC_DISP11div2
)
991 && (inst
.type
!= Insn_Type_SYN
)
992 && (inst
.type
!= Rd_rvalueRs_SI15
)
993 && (inst
.type
!= Rd_lvalueRs_SI15
)
994 && (inst
.type
!= Insn_internal
))
996 inst
.error
= BAD_ARGS
;
997 *str
= input_line_pointer
;
998 input_line_pointer
= save_in
;
1002 *str
= input_line_pointer
;
1003 input_line_pointer
= save_in
;
1007 /* Check if an immediate is valid. If so, convert it to the right format. */
1010 validate_immediate (int val
, unsigned int data_type
, int hex_p
)
1016 int val_hi
= ((val
& 0xffff0000) >> 16);
1018 if (score_df_range
[data_type
].range
[0] <= val_hi
1019 && val_hi
<= score_df_range
[data_type
].range
[1])
1026 int val_lo
= (val
& 0xffff);
1028 if (score_df_range
[data_type
].range
[0] <= val_lo
1029 && val_lo
<= score_df_range
[data_type
].range
[1])
1041 if (!(val
>= -0x2000 && val
<= 0x3fff))
1048 if (!(val
>= -8192 && val
<= 8191))
1060 if (!(val
>= -0x7fff && val
<= 0xffff && val
!= 0x8000))
1067 if (!(val
>= -32767 && val
<= 32768))
1078 if (data_type
== _SIMM14_NEG
|| data_type
== _IMM16_NEG
)
1081 if (score_df_range
[data_type
].range
[0] <= val
1082 && val
<= score_df_range
[data_type
].range
[1])
1092 data_op2 (char **str
, int shift
, enum score_data_type data_type
)
1095 char data_exp
[MAX_LITERAL_POOL_SIZE
];
1100 skip_whitespace (*str
);
1104 /* Set hex_p to zero. */
1107 while ((*dataptr
!= '\0') && (*dataptr
!= '|') && (cnt
<= MAX_LITERAL_POOL_SIZE
)) /* 0x7c = ='|' */
1109 data_exp
[cnt
] = *dataptr
;
1114 data_exp
[cnt
] = '\0';
1115 pp
= (char *)&data_exp
;
1117 if (*dataptr
== '|') /* process PCE */
1119 if (my_get_expression (&inst
.reloc
.exp
, &pp
) == (int) FAIL
)
1122 if (inst
.error
!= 0)
1123 return (int) FAIL
; /* to ouptut_inst to printf out the error */
1126 else /* process 16 bit */
1128 if (my_get_expression (&inst
.reloc
.exp
, str
) == (int) FAIL
)
1133 dataptr
= (char *)data_exp
;
1134 for (; *dataptr
!= '\0'; dataptr
++)
1136 *dataptr
= TOLOWER (*dataptr
);
1137 if (*dataptr
== '!' || *dataptr
== ' ')
1140 dataptr
= (char *)data_exp
;
1142 if ((dataptr
!= NULL
)
1143 && (((strstr (dataptr
, "0x")) != NULL
)
1144 || ((strstr (dataptr
, "0X")) != NULL
)))
1147 if ((data_type
!= _SIMM16_LA
)
1148 && (data_type
!= _VALUE_HI16
)
1149 && (data_type
!= _VALUE_LO16
)
1150 && (data_type
!= _IMM16
)
1151 && (data_type
!= _IMM15
)
1152 && (data_type
!= _IMM14
)
1153 && (data_type
!= _IMM4
)
1154 && (data_type
!= _IMM5
)
1155 && (data_type
!= _IMM8
)
1156 && (data_type
!= _IMM5_RSHIFT_1
)
1157 && (data_type
!= _IMM5_RSHIFT_2
)
1158 && (data_type
!= _SIMM14
)
1159 && (data_type
!= _SIMM14_NEG
)
1160 && (data_type
!= _SIMM16_NEG
)
1161 && (data_type
!= _IMM10_RSHIFT_2
)
1162 && (data_type
!= _GP_IMM15
))
1168 if ((inst
.reloc
.exp
.X_add_number
== 0)
1169 && (inst
.type
!= Insn_Type_SYN
)
1170 && (inst
.type
!= Rd_rvalueRs_SI15
)
1171 && (inst
.type
!= Rd_lvalueRs_SI15
)
1172 && (inst
.type
!= Insn_internal
)
1173 && (((*dataptr
>= 'a') && (*dataptr
<= 'z'))
1174 || ((*dataptr
== '0') && (*(dataptr
+ 1) == 'x') && (*(dataptr
+ 2) != '0'))
1175 || ((*dataptr
== '+') && (*(dataptr
+ 1) != '0'))
1176 || ((*dataptr
== '-') && (*(dataptr
+ 1) != '0'))))
1178 inst
.error
= BAD_ARGS
;
1183 if ((inst
.reloc
.exp
.X_add_symbol
)
1184 && ((data_type
== _SIMM16
)
1185 || (data_type
== _SIMM16_NEG
)
1186 || (data_type
== _IMM16_NEG
)
1187 || (data_type
== _SIMM14
)
1188 || (data_type
== _SIMM14_NEG
)
1189 || (data_type
== _IMM5
)
1190 || (data_type
== _IMM14
)
1191 || (data_type
== _IMM20
)
1192 || (data_type
== _IMM16
)
1193 || (data_type
== _IMM15
)
1194 || (data_type
== _IMM4
)))
1196 inst
.error
= BAD_ARGS
;
1200 if (inst
.reloc
.exp
.X_add_symbol
)
1207 inst
.reloc
.type
= BFD_RELOC_HI16_S
;
1208 inst
.reloc
.pc_rel
= 0;
1211 inst
.reloc
.type
= BFD_RELOC_LO16
;
1212 inst
.reloc
.pc_rel
= 0;
1215 inst
.reloc
.type
= BFD_RELOC_SCORE_GPREL15
;
1216 inst
.reloc
.pc_rel
= 0;
1219 case _IMM16_LO16_pic
:
1220 inst
.reloc
.type
= BFD_RELOC_SCORE_GOT_LO16
;
1221 inst
.reloc
.pc_rel
= 0;
1224 inst
.reloc
.type
= BFD_RELOC_32
;
1225 inst
.reloc
.pc_rel
= 0;
1231 if (data_type
== _IMM16_pic
)
1233 inst
.reloc
.type
= BFD_RELOC_SCORE_DUMMY_HI16
;
1234 inst
.reloc
.pc_rel
= 0;
1237 if (data_type
== _SIMM16_LA
&& inst
.reloc
.exp
.X_unsigned
== 1)
1239 value
= validate_immediate (inst
.reloc
.exp
.X_add_number
, _SIMM16_LA_POS
, hex_p
);
1240 if (value
== (int) FAIL
) /* for advance to check if this is ldis */
1241 if ((inst
.reloc
.exp
.X_add_number
& 0xffff) == 0)
1243 inst
.instruction
|= 0x8000000;
1244 inst
.instruction
|= ((inst
.reloc
.exp
.X_add_number
>> 16) << 1) & 0x1fffe;
1250 value
= validate_immediate (inst
.reloc
.exp
.X_add_number
, data_type
, hex_p
);
1253 if (value
== (int) FAIL
)
1255 if ((data_type
!= _SIMM14_NEG
) && (data_type
!= _SIMM16_NEG
) && (data_type
!= _IMM16_NEG
))
1258 _("invalid constant: %d bit expression not in range %d..%d"),
1259 score_df_range
[data_type
].bits
,
1260 score_df_range
[data_type
].range
[0], score_df_range
[data_type
].range
[1]);
1265 _("invalid constant: %d bit expression not in range %d..%d"),
1266 score_df_range
[data_type
].bits
,
1267 -score_df_range
[data_type
].range
[1], -score_df_range
[data_type
].range
[0]);
1270 inst
.error
= err_msg
;
1274 if ((score_df_range
[data_type
].range
[0] != 0) || (data_type
== _IMM5_RANGE_8_31
))
1276 value
&= (1 << score_df_range
[data_type
].bits
) - 1;
1279 inst
.instruction
|= value
<< shift
;
1282 if ((inst
.instruction
& 0xf0000000) == 0x30000000)
1284 if ((((inst
.instruction
>> 20) & 0x1F) != 0)
1285 && (((inst
.instruction
>> 20) & 0x1F) != 1)
1286 && (((inst
.instruction
>> 20) & 0x1F) != 2)
1287 && (((inst
.instruction
>> 20) & 0x1F) != 3)
1288 && (((inst
.instruction
>> 20) & 0x1F) != 4)
1289 && (((inst
.instruction
>> 20) & 0x1F) != 8)
1290 && (((inst
.instruction
>> 20) & 0x1F) != 9)
1291 && (((inst
.instruction
>> 20) & 0x1F) != 0xa)
1292 && (((inst
.instruction
>> 20) & 0x1F) != 0xb)
1293 && (((inst
.instruction
>> 20) & 0x1F) != 0xc)
1294 && (((inst
.instruction
>> 20) & 0x1F) != 0xd)
1295 && (((inst
.instruction
>> 20) & 0x1F) != 0xe)
1296 && (((inst
.instruction
>> 20) & 0x1F) != 0x10)
1297 && (((inst
.instruction
>> 20) & 0x1F) != 0x11)
1298 && (((inst
.instruction
>> 20) & 0x1F) != 0x18)
1299 && (((inst
.instruction
>> 20) & 0x1F) != 0x1A)
1300 && (((inst
.instruction
>> 20) & 0x1F) != 0x1B)
1301 && (((inst
.instruction
>> 20) & 0x1F) != 0x1d)
1302 && (((inst
.instruction
>> 20) & 0x1F) != 0x1e)
1303 && (((inst
.instruction
>> 20) & 0x1F) != 0x1f))
1305 inst
.error
= _("invalid constant: bit expression not defined");
1313 /* Handle addi/addi.c/addis.c/cmpi.c/addis.c/ldi. */
1316 do_rdsi16 (char *str
)
1318 skip_whitespace (str
);
1320 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) == (int) FAIL
1321 || skip_past_comma (&str
) == (int) FAIL
1322 || data_op2 (&str
, 1, _SIMM16
) == (int) FAIL
1323 || end_of_line (str
) == (int) FAIL
)
1327 if ((inst
.instruction
& 0x20c0000) == 0x20c0000)
1329 if ((((inst
.instruction
>> 20) & 0x10) == 0x10) || ((inst
.instruction
& 0x1fe00) != 0))
1331 inst
.relax_inst
= 0x8000;
1335 inst
.relax_inst
|= (inst
.instruction
>> 1) & 0xff;
1336 inst
.relax_inst
|= (((inst
.instruction
>> 20) & 0xf) << 8);
1337 inst
.relax_size
= 2;
1340 else if (((inst
.instruction
>> 20) & 0x10) == 0x10)
1342 inst
.relax_inst
= 0x8000;
1346 /* Handle subi/subi.c. */
1349 do_sub_rdsi16 (char *str
)
1351 skip_whitespace (str
);
1353 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) != (int) FAIL
1354 && skip_past_comma (&str
) != (int) FAIL
1355 && data_op2 (&str
, 1, _SIMM16_NEG
) != (int) FAIL
)
1359 /* Handle addri/addri.c. */
1362 do_rdrssi14 (char *str
) /* -(2^13)~((2^13)-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
, 1, _SIMM14
);
1373 /* Handle subri.c/subri. */
1375 do_sub_rdrssi14 (char *str
) /* -(2^13)~((2^13)-1) */
1377 skip_whitespace (str
);
1379 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) != (int) FAIL
1380 && skip_past_comma (&str
) != (int) FAIL
1381 && reg_required_here (&str
, 15, REG_TYPE_SCORE
) != (int) FAIL
1382 && skip_past_comma (&str
) != (int) FAIL
1383 && data_op2 (&str
, 1, _SIMM14_NEG
) != (int) FAIL
)
1387 /* Handle bitclr.c/bitset.c/bittgl.c/slli.c/srai.c/srli.c/roli.c/rori.c/rolic.c. */
1389 do_rdrsi5 (char *str
) /* 0~((2^14)-1) */
1391 skip_whitespace (str
);
1393 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) == (int) FAIL
1394 || skip_past_comma (&str
) == (int) FAIL
1395 || reg_required_here (&str
, 15, REG_TYPE_SCORE
) == (int) FAIL
1396 || skip_past_comma (&str
) == (int) FAIL
1397 || data_op2 (&str
, 10, _IMM5
) == (int) FAIL
1398 || end_of_line (str
) == (int) FAIL
)
1401 if ((((inst
.instruction
>> 20) & 0x1f) == ((inst
.instruction
>> 15) & 0x1f))
1402 && (inst
.relax_inst
!= 0x8000) && (((inst
.instruction
>> 15) & 0x10) == 0))
1404 inst
.relax_inst
|= (((inst
.instruction
>> 10) & 0x1f) << 3) | (((inst
.instruction
>> 15) & 0xf) << 8);
1405 inst
.relax_size
= 2;
1408 inst
.relax_inst
= 0x8000;
1411 /* Handle andri/orri/andri.c/orri.c. */
1414 do_rdrsi14 (char *str
) /* 0 ~ ((2^14)-1) */
1416 skip_whitespace (str
);
1418 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) != (int) FAIL
1419 && skip_past_comma (&str
) != (int) FAIL
1420 && reg_required_here (&str
, 15, REG_TYPE_SCORE
) != (int) FAIL
1421 && skip_past_comma (&str
) != (int) FAIL
1422 && data_op2 (&str
, 1, _IMM14
) != (int) FAIL
)
1426 /* Handle bittst.c. */
1428 do_xrsi5 (char *str
)
1430 skip_whitespace (str
);
1432 if (reg_required_here (&str
, 15, REG_TYPE_SCORE
) == (int) FAIL
1433 || skip_past_comma (&str
) == (int) FAIL
1434 || data_op2 (&str
, 10, _IMM5
) == (int) FAIL
1435 || end_of_line (str
) == (int) FAIL
)
1438 if ((inst
.relax_inst
!= 0x8000) && (((inst
.instruction
>> 15) & 0x10) == 0))
1440 inst
.relax_inst
|= (((inst
.instruction
>> 10) & 0x1f) << 3) | (((inst
.instruction
>> 15) & 0xf) << 8);
1441 inst
.relax_size
= 2;
1444 inst
.relax_inst
= 0x8000;
1447 /* Handle addis/andi/ori/andis/oris/ldis. */
1449 do_rdi16 (char *str
)
1451 skip_whitespace (str
);
1453 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) == (int) FAIL
1454 || skip_past_comma (&str
) == (int) FAIL
1455 || data_op2 (&str
, 1, _IMM16
) == (int) FAIL
1456 || end_of_line (str
) == (int) FAIL
)
1459 if (((inst.instruction & 0xa0dfffe) != 0xa0c0000) || ((((inst.instruction >> 20) & 0x1f) & 0x10) == 0x10))
1460 inst.relax_inst = 0x8000;
1462 inst.relax_size = 2;
1467 do_macro_rdi32hi (char *str
)
1469 skip_whitespace (str
);
1471 /* Do not handle end_of_line(). */
1472 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) != (int) FAIL
1473 && skip_past_comma (&str
) != (int) FAIL
)
1474 data_op2 (&str
, 1, _VALUE_HI16
);
1478 do_macro_rdi32lo (char *str
)
1480 skip_whitespace (str
);
1482 /* Do not handle end_of_line(). */
1483 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) != (int) FAIL
1484 && skip_past_comma (&str
) != (int) FAIL
)
1485 data_op2 (&str
, 1, _VALUE_LO16
);
1488 /* Handle ldis_pic. */
1491 do_rdi16_pic (char *str
)
1493 skip_whitespace (str
);
1495 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) != (int) FAIL
1496 && skip_past_comma (&str
) != (int) FAIL
1497 && data_op2 (&str
, 1, _IMM16_pic
) != (int) FAIL
)
1501 /* Handle addi_s_pic to generate R_SCORE_GOT_LO16 . */
1504 do_addi_s_pic (char *str
)
1506 skip_whitespace (str
);
1508 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) != (int) FAIL
1509 && skip_past_comma (&str
) != (int) FAIL
1510 && data_op2 (&str
, 1, _SIMM16_pic
) != (int) FAIL
)
1514 /* Handle addi_u_pic to generate R_SCORE_GOT_LO16 . */
1517 do_addi_u_pic (char *str
)
1519 skip_whitespace (str
);
1521 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) != (int) FAIL
1522 && skip_past_comma (&str
) != (int) FAIL
1523 && data_op2 (&str
, 1, _IMM16_LO16_pic
) != (int) FAIL
)
1527 /* Handle mfceh/mfcel/mtceh/mtchl. */
1532 skip_whitespace (str
);
1534 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) != (int) FAIL
)
1541 skip_whitespace (str
);
1543 if (reg_required_here (&str
, 15, REG_TYPE_SCORE
) == (int) FAIL
1544 || end_of_line (str
) == (int) FAIL
)
1547 if ((inst
.relax_inst
!= 0x8000) && (((inst
.instruction
>> 15) & 0x10) == 0))
1549 inst
.relax_inst
|= (((inst
.instruction
>> 10) & 0xf) << 8) | (((inst
.instruction
>> 15) & 0xf) << 4);
1550 inst
.relax_size
= 2;
1553 inst
.relax_inst
= 0x8000;
1559 skip_whitespace (str
);
1561 if (data_op2 (&str
, 10, _IMM15
) != (int) FAIL
)
1568 skip_whitespace (str
);
1570 if (data_op2 (&str
, 15, _IMM5
) == (int) FAIL
|| end_of_line (str
) == (int) FAIL
)
1573 if (inst
.relax_inst
!= 0x8000)
1575 inst
.relax_inst
|= (((inst
.instruction
>> 15) & 0x1f) << 3);
1576 inst
.relax_size
= 2;
1583 skip_whitespace (str
);
1585 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) == (int) FAIL
1586 || skip_past_comma (&str
) == (int) FAIL
1587 || reg_required_here (&str
, 15, REG_TYPE_SCORE
) == (int) FAIL
1588 || end_of_line (str
) == (int) FAIL
)
1591 if (inst
.relax_inst
!= 0x8000)
1593 if (((inst
.instruction
& 0x7f) == 0x56)) /* adjust mv -> mv! / mlfh! / mhfl! */
1596 if ((((inst
.instruction
>> 15) & 0x10) != 0x0) && (((inst
.instruction
>> 20) & 0x10) == 0))
1598 inst
.relax_inst
= 0x00000001 | (((inst
.instruction
>> 15) & 0xf) << 4)
1599 | (((inst
.instruction
>> 20) & 0xf) << 8);
1600 inst
.relax_size
= 2;
1603 else if ((((inst
.instruction
>> 15) & 0x10) == 0x0) && ((inst
.instruction
>> 20) & 0x10) != 0)
1605 inst
.relax_inst
= 0x00000002 | (((inst
.instruction
>> 15) & 0xf) << 4)
1606 | (((inst
.instruction
>> 20) & 0xf) << 8);
1607 inst
.relax_size
= 2;
1609 else if ((((inst
.instruction
>> 15) & 0x10) == 0x0) && (((inst
.instruction
>> 20) & 0x10) == 0))
1611 inst
.relax_inst
|= (((inst
.instruction
>> 15) & 0xf) << 4)
1612 | (((inst
.instruction
>> 20) & 0xf) << 8);
1613 inst
.relax_size
= 2;
1617 inst
.relax_inst
= 0x8000;
1620 else if ((((inst
.instruction
>> 15) & 0x10) == 0x0) && (((inst
.instruction
>> 20) & 0x10) == 0))
1622 inst
.relax_inst
|= (((inst
.instruction
>> 15) & 0xf) << 4)
1623 | (((inst
.instruction
>> 20) & 0xf) << 8);
1624 inst
.relax_size
= 2;
1628 inst
.relax_inst
= 0x8000;
1633 /* Handle mfcr/mtcr. */
1635 do_rdcrs (char *str
)
1637 skip_whitespace (str
);
1639 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) != (int) FAIL
1640 && skip_past_comma (&str
) != (int) FAIL
1641 && reg_required_here (&str
, 15, REG_TYPE_SCORE_CR
) != (int) FAIL
)
1645 /* Handle mfsr/mtsr. */
1648 do_rdsrs (char *str
)
1650 skip_whitespace (str
);
1653 if ((inst
.instruction
& 0xff) == 0x50)
1655 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) != (int) FAIL
1656 && skip_past_comma (&str
) != (int) FAIL
1657 && reg_required_here (&str
, 10, REG_TYPE_SCORE_SR
) != (int) FAIL
)
1662 if (reg_required_here (&str
, 15, REG_TYPE_SCORE
) != (int) FAIL
1663 && skip_past_comma (&str
) != (int) FAIL
)
1664 reg_required_here (&str
, 10, REG_TYPE_SCORE_SR
);
1671 do_rdxrs (char *str
)
1673 skip_whitespace (str
);
1675 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) == (int) FAIL
1676 || skip_past_comma (&str
) == (int) FAIL
1677 || reg_required_here (&str
, 10, REG_TYPE_SCORE
) == (int) FAIL
1678 || end_of_line (str
) == (int) FAIL
)
1681 if ((inst
.relax_inst
!= 0x8000) && (((inst
.instruction
>> 10) & 0x10) == 0)
1682 && (((inst
.instruction
>> 20) & 0x10) == 0))
1684 inst
.relax_inst
|= (((inst
.instruction
>> 10) & 0xf) << 4) | (((inst
.instruction
>> 20) & 0xf) << 8);
1685 inst
.relax_size
= 2;
1688 inst
.relax_inst
= 0x8000;
1691 /* Handle cmp.c/cmp<cond>. */
1695 skip_whitespace (str
);
1697 if (reg_required_here (&str
, 15, REG_TYPE_SCORE
) == (int) FAIL
1698 || skip_past_comma (&str
) == (int) FAIL
1699 || reg_required_here (&str
, 10, REG_TYPE_SCORE
) == (int) FAIL
1700 || end_of_line (str
) == (int) FAIL
)
1703 if ((inst
.relax_inst
!= 0x8000) && (((inst
.instruction
>> 20) & 0x1f) == 3)
1704 && (((inst
.instruction
>> 10) & 0x10) == 0) && (((inst
.instruction
>> 15) & 0x10) == 0))
1706 inst
.relax_inst
|= (((inst
.instruction
>> 10) & 0xf) << 4) | (((inst
.instruction
>> 15) & 0xf) << 8);
1707 inst
.relax_size
= 2;
1710 inst
.relax_inst
= 0x8000;
1714 do_ceinst (char *str
)
1719 skip_whitespace (str
);
1721 if (data_op2 (&str
, 20, _IMM5
) == (int) FAIL
1722 || skip_past_comma (&str
) == (int) FAIL
1723 || reg_required_here (&str
, 15, REG_TYPE_SCORE
) == (int) FAIL
1724 || skip_past_comma (&str
) == (int) FAIL
1725 || reg_required_here (&str
, 10, REG_TYPE_SCORE
) == (int) FAIL
1726 || skip_past_comma (&str
) == (int) FAIL
1727 || data_op2 (&str
, 5, _IMM5
) == (int) FAIL
1728 || skip_past_comma (&str
) == (int) FAIL
1729 || data_op2 (&str
, 0, _IMM5
) == (int) FAIL
1730 || end_of_line (str
) == (int) FAIL
)
1737 if (data_op2 (&str
, 0, _IMM25
) == (int) FAIL
)
1743 reglow_required_here (char **str
, int shift
)
1745 static char buff
[MAX_LITERAL_POOL_SIZE
];
1749 if ((reg
= score_reg_parse (str
, all_reg_maps
[REG_TYPE_SCORE
].htab
)) != (int) FAIL
)
1751 if ((reg
== 1) && (nor1
== 1) && (inst
.bwarn
== 0))
1753 as_warn (_("Using temp register(r1)"));
1759 inst
.instruction
|= reg
<< shift
;
1765 /* Restore the start point, we may have got a reg of the wrong class. */
1767 sprintf (buff
, _("low register(r0-r15)expected, not '%.100s'"), start
);
1772 /* Handle addc!/add!/and!/cmp!/neg!/not!/or!/sll!/srl!/sra!/xor!/sub!. */
1774 do16_rdrs (char *str
)
1776 skip_whitespace (str
);
1778 if (reglow_required_here (&str
, 8) == (int) FAIL
1779 || skip_past_comma (&str
) == (int) FAIL
1780 || reglow_required_here (&str
, 4) == (int) FAIL
1781 || end_of_line (str
) == (int) FAIL
)
1787 if ((inst
.instruction
& 0x700f) == 0x2003) /* cmp! */
1789 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 15)
1790 | (((inst
.instruction
>> 4) & 0xf) << 10);
1792 else if ((inst
.instruction
& 0x700f) == 0x2006) /* not! */
1794 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 20)
1795 | (((inst
.instruction
>> 4) & 0xf) << 15);
1799 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 20)
1800 | (((inst
.instruction
>> 8) & 0xf) << 15) | (((inst
.instruction
>> 4) & 0xf) << 10);
1802 inst
.relax_size
= 4;
1811 skip_whitespace (str
);
1813 if ((rd
= reglow_required_here (&str
, 4)) == (int) FAIL
1814 || end_of_line (str
) == (int) FAIL
)
1820 inst
.relax_inst
|= rd
<< 20;
1821 inst
.relax_size
= 4;
1825 /* Handle br!/brl!. */
1827 do16_xrs (char *str
)
1829 skip_whitespace (str
);
1831 if (reglow_required_here (&str
, 4) == (int) FAIL
|| end_of_line (str
) == (int) FAIL
)
1837 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 10)
1838 | (((inst
.instruction
>> 4) & 0xf) << 15);
1839 inst
.relax_size
= 4;
1844 reghigh_required_here (char **str
, int shift
)
1846 static char buff
[MAX_LITERAL_POOL_SIZE
];
1850 if ((reg
= score_reg_parse (str
, all_reg_maps
[REG_TYPE_SCORE
].htab
)) != (int) FAIL
)
1852 if (15 < reg
&& reg
< 32)
1855 inst
.instruction
|= (reg
& 0xf) << shift
;
1862 sprintf (buff
, _("high register(r16-r31)expected, not '%.100s'"), start
);
1869 do16_hrdrs (char *str
)
1871 skip_whitespace (str
);
1873 if (reghigh_required_here (&str
, 8) != (int) FAIL
1874 && skip_past_comma (&str
) != (int) FAIL
1875 && reglow_required_here (&str
, 4) != (int) FAIL
1876 && end_of_line (str
) != (int) FAIL
)
1878 inst
.relax_inst
|= ((((inst
.instruction
>> 8) & 0xf) | 0x10) << 20)
1879 | (((inst
.instruction
>> 4) & 0xf) << 15) | (0xf << 10);
1880 inst
.relax_size
= 4;
1886 do16_rdhrs (char *str
)
1888 skip_whitespace (str
);
1890 if (reglow_required_here (&str
, 8) != (int) FAIL
1891 && skip_past_comma (&str
) != (int) FAIL
1892 && reghigh_required_here (&str
, 4) != (int) FAIL
1893 && end_of_line (str
) != (int) FAIL
)
1895 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 20)
1896 | ((((inst
.instruction
>> 4) & 0xf) | 0x10) << 15) | (0xf << 10);
1897 inst
.relax_size
= 4;
1901 /* We need to be able to fix up arbitrary expressions in some statements.
1902 This is so that we can handle symbols that are an arbitrary distance from
1903 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
1904 which returns part of an address in a form which will be valid for
1905 a data instruction. We do this by pushing the expression into a symbol
1906 in the expr_section, and creating a fix for that. */
1908 fix_new_score (fragS
* frag
, int where
, short int size
, expressionS
* exp
, int pc_rel
, int reloc
)
1918 new_fix
= fix_new_exp (frag
, where
, size
, exp
, pc_rel
, reloc
);
1921 new_fix
= fix_new (frag
, where
, size
, make_expr_symbol (exp
), 0, pc_rel
, reloc
);
1928 init_dependency_vector (void)
1932 for (i
= 0; i
< vector_size
; i
++)
1933 memset (&dependency_vector
[i
], '\0', sizeof (dependency_vector
[i
]));
1938 static enum insn_type_for_dependency
1939 dependency_type_from_insn (char *insn_name
)
1941 char name
[INSN_NAME_LEN
];
1942 const struct insn_to_dependency
*tmp
;
1944 strcpy (name
, insn_name
);
1945 tmp
= (const struct insn_to_dependency
*) hash_find (dependency_insn_hsh
, name
);
1954 check_dependency (char *pre_insn
, char *pre_reg
,
1955 char *cur_insn
, char *cur_reg
, int *warn_or_error
)
1959 enum insn_type_for_dependency pre_insn_type
;
1960 enum insn_type_for_dependency cur_insn_type
;
1962 pre_insn_type
= dependency_type_from_insn (pre_insn
);
1963 cur_insn_type
= dependency_type_from_insn (cur_insn
);
1965 for (i
= 0; i
< sizeof (data_dependency_table
) / sizeof (data_dependency_table
[0]); i
++)
1967 if ((pre_insn_type
== data_dependency_table
[i
].pre_insn_type
)
1968 && (D_all_insn
== data_dependency_table
[i
].cur_insn_type
1969 || cur_insn_type
== data_dependency_table
[i
].cur_insn_type
)
1970 && (strcmp (data_dependency_table
[i
].pre_reg
, "") == 0
1971 || strcmp (data_dependency_table
[i
].pre_reg
, pre_reg
) == 0)
1972 && (strcmp (data_dependency_table
[i
].cur_reg
, "") == 0
1973 || strcmp (data_dependency_table
[i
].cur_reg
, cur_reg
) == 0))
1975 bubbles
= (score7
) ? data_dependency_table
[i
].bubblenum_7
: data_dependency_table
[i
].bubblenum_5
;
1976 *warn_or_error
= data_dependency_table
[i
].warn_or_error
;
1985 build_one_frag (struct score_it one_inst
)
1988 int relaxable_p
= g_opt
;
1991 /* Start a new frag if frag_now is not empty. */
1992 if (frag_now_fix () != 0)
1994 if (!frag_now
->tc_frag_data
.is_insn
)
1995 frag_wane (frag_now
);
2001 p
= frag_more (one_inst
.size
);
2002 md_number_to_chars (p
, one_inst
.instruction
, one_inst
.size
);
2005 dwarf2_emit_insn (one_inst
.size
);
2008 relaxable_p
&= (one_inst
.relax_size
!= 0);
2009 relax_size
= relaxable_p
? one_inst
.relax_size
: 0;
2011 p
= frag_var (rs_machine_dependent
, relax_size
+ RELAX_PAD_BYTE
, 0,
2012 RELAX_ENCODE (one_inst
.size
, one_inst
.relax_size
,
2013 one_inst
.type
, 0, 0, relaxable_p
),
2017 md_number_to_chars (p
, one_inst
.relax_inst
, relax_size
);
2021 handle_dependency (struct score_it
*theinst
)
2024 int warn_or_error
= 0; /* warn - 0; error - 1 */
2026 int remainder_bubbles
= 0;
2027 char cur_insn
[INSN_NAME_LEN
];
2028 char pre_insn
[INSN_NAME_LEN
];
2029 struct score_it nop_inst
;
2030 struct score_it pflush_inst
;
2032 nop_inst
.instruction
= 0x0000;
2034 nop_inst
.relax_inst
= 0x80008000;
2035 nop_inst
.relax_size
= 4;
2036 nop_inst
.type
= NO16_OPD
;
2038 pflush_inst
.instruction
= 0x8000800a;
2039 pflush_inst
.size
= 4;
2040 pflush_inst
.relax_inst
= 0x8000;
2041 pflush_inst
.relax_size
= 0;
2042 pflush_inst
.type
= NO_OPD
;
2044 /* pflush will clear all data dependency. */
2045 if (strcmp (theinst
->name
, "pflush") == 0)
2047 init_dependency_vector ();
2051 /* Push current instruction to dependency_vector[0]. */
2052 for (i
= vector_size
- 1; i
> 0; i
--)
2053 memcpy (&dependency_vector
[i
], &dependency_vector
[i
- 1], sizeof (dependency_vector
[i
]));
2055 memcpy (&dependency_vector
[0], theinst
, sizeof (dependency_vector
[i
]));
2057 /* There is no dependency between nop and any instruction. */
2058 if (strcmp (dependency_vector
[0].name
, "nop") == 0
2059 || strcmp (dependency_vector
[0].name
, "nop!") == 0)
2062 /* "pce" is defined in insn_to_dependency_table. */
2063 #define PCE_NAME "pce"
2065 if (dependency_vector
[0].type
== Insn_Type_PCE
)
2066 strcpy (cur_insn
, PCE_NAME
);
2068 strcpy (cur_insn
, dependency_vector
[0].name
);
2070 for (i
= 1; i
< vector_size
; i
++)
2072 /* The element of dependency_vector is NULL. */
2073 if (dependency_vector
[i
].name
[0] == '\0')
2076 if (dependency_vector
[i
].type
== Insn_Type_PCE
)
2077 strcpy (pre_insn
, PCE_NAME
);
2079 strcpy (pre_insn
, dependency_vector
[i
].name
);
2081 bubbles
= check_dependency (pre_insn
, dependency_vector
[i
].reg
,
2082 cur_insn
, dependency_vector
[0].reg
, &warn_or_error
);
2083 remainder_bubbles
= bubbles
- i
+ 1;
2085 if (remainder_bubbles
> 0)
2089 if (fix_data_dependency
== 1)
2091 if (remainder_bubbles
<= 2)
2093 if (warn_fix_data_dependency
)
2094 as_warn (_("Fix data dependency: %s %s -- %s %s (insert %d nop!/%d)"),
2095 dependency_vector
[i
].name
, dependency_vector
[i
].reg
,
2096 dependency_vector
[0].name
, dependency_vector
[0].reg
,
2097 remainder_bubbles
, bubbles
);
2099 for (j
= (vector_size
- 1); (j
- remainder_bubbles
) > 0; j
--)
2100 memcpy (&dependency_vector
[j
], &dependency_vector
[j
- remainder_bubbles
],
2101 sizeof (dependency_vector
[j
]));
2103 for (j
= 1; j
<= remainder_bubbles
; j
++)
2105 memset (&dependency_vector
[j
], '\0', sizeof (dependency_vector
[j
]));
2107 build_one_frag (nop_inst
);
2112 if (warn_fix_data_dependency
)
2113 as_warn (_("Fix data dependency: %s %s -- %s %s (insert 1 pflush/%d)"),
2114 dependency_vector
[i
].name
, dependency_vector
[i
].reg
,
2115 dependency_vector
[0].name
, dependency_vector
[0].reg
,
2118 for (j
= 1; j
< vector_size
; j
++)
2119 memset (&dependency_vector
[j
], '\0', sizeof (dependency_vector
[j
]));
2121 /* Insert pflush. */
2122 build_one_frag (pflush_inst
);
2129 as_bad (_("data dependency: %s %s -- %s %s (%d/%d bubble)"),
2130 dependency_vector
[i
].name
, dependency_vector
[i
].reg
,
2131 dependency_vector
[0].name
, dependency_vector
[0].reg
,
2132 remainder_bubbles
, bubbles
);
2136 as_warn (_("data dependency: %s %s -- %s %s (%d/%d bubble)"),
2137 dependency_vector
[i
].name
, dependency_vector
[i
].reg
,
2138 dependency_vector
[0].name
, dependency_vector
[0].reg
,
2139 remainder_bubbles
, bubbles
);
2146 static enum insn_class
2147 get_insn_class_from_type (enum score_insn_type type
)
2149 enum insn_class retval
= (int) FAIL
;
2155 case Rd_rvalueBP_I5
:
2156 case Rd_lvalueBP_I5
:
2167 retval
= INSN_CLASS_16
;
2176 case Rd_rvalueRs_SI10
:
2177 case Rd_lvalueRs_SI10
:
2178 case Rd_rvalueRs_preSI12
:
2179 case Rd_rvalueRs_postSI12
:
2180 case Rd_lvalueRs_preSI12
:
2181 case Rd_lvalueRs_postSI12
:
2183 case Rd_rvalueRs_SI15
:
2184 case Rd_lvalueRs_SI15
:
2193 case OP5_rvalueRs_SI15
:
2194 case I5_Rs_Rs_I5_OP5
:
2195 case x_rvalueRs_post4
:
2196 case Rd_rvalueRs_post4
:
2198 case Rd_lvalueRs_post4
:
2199 case x_lvalueRs_post4
:
2207 retval
= INSN_CLASS_32
;
2210 retval
= INSN_CLASS_PCE
;
2213 retval
= INSN_CLASS_SYN
;
2222 static unsigned long
2223 adjust_paritybit (unsigned long m_code
, enum insn_class
class)
2225 unsigned long result
= 0;
2226 unsigned long m_code_high
= 0;
2227 unsigned long m_code_low
= 0;
2228 unsigned long pb_high
= 0;
2229 unsigned long pb_low
= 0;
2231 if (class == INSN_CLASS_32
)
2233 pb_high
= 0x80000000;
2234 pb_low
= 0x00008000;
2236 else if (class == INSN_CLASS_16
)
2241 else if (class == INSN_CLASS_PCE
)
2244 pb_low
= 0x00008000;
2246 else if (class == INSN_CLASS_SYN
)
2248 /* FIXME. at this time, INSN_CLASS_SYN must be 32 bit, but, instruction type should
2249 be changed if macro instruction has been expanded. */
2250 pb_high
= 0x80000000;
2251 pb_low
= 0x00008000;
2258 m_code_high
= m_code
& 0x3fff8000;
2259 m_code_low
= m_code
& 0x00007fff;
2260 result
= pb_high
| (m_code_high
<< 1) | pb_low
| m_code_low
;
2266 gen_insn_frag (struct score_it
*part_1
, struct score_it
*part_2
)
2269 bfd_boolean pce_p
= FALSE
;
2270 int relaxable_p
= g_opt
;
2272 struct score_it
*inst1
= part_1
;
2273 struct score_it
*inst2
= part_2
;
2274 struct score_it backup_inst1
;
2276 pce_p
= (inst2
) ? TRUE
: FALSE
;
2277 memcpy (&backup_inst1
, inst1
, sizeof (struct score_it
));
2279 /* Adjust instruction opcode and to be relaxed instruction opcode. */
2282 backup_inst1
.instruction
= ((backup_inst1
.instruction
& 0x7FFF) << 15)
2283 | (inst2
->instruction
& 0x7FFF);
2284 backup_inst1
.instruction
= adjust_paritybit (backup_inst1
.instruction
, INSN_CLASS_PCE
);
2285 backup_inst1
.relax_inst
= 0x8000;
2286 backup_inst1
.size
= INSN_SIZE
;
2287 backup_inst1
.relax_size
= 0;
2288 backup_inst1
.type
= Insn_Type_PCE
;
2292 backup_inst1
.instruction
= adjust_paritybit (backup_inst1
.instruction
,
2293 GET_INSN_CLASS (backup_inst1
.type
));
2296 if (backup_inst1
.relax_size
!= 0)
2298 enum insn_class tmp
;
2300 tmp
= (backup_inst1
.size
== INSN_SIZE
) ? INSN_CLASS_16
: INSN_CLASS_32
;
2301 backup_inst1
.relax_inst
= adjust_paritybit (backup_inst1
.relax_inst
, tmp
);
2304 /* Check data dependency. */
2305 handle_dependency (&backup_inst1
);
2307 /* Start a new frag if frag_now is not empty and is not instruction frag, maybe it contains
2308 data produced by .ascii etc. Doing this is to make one instruction per frag. */
2309 if (frag_now_fix () != 0)
2311 if (!frag_now
->tc_frag_data
.is_insn
)
2312 frag_wane (frag_now
);
2317 /* Here, we must call frag_grow in order to keep the instruction frag type is
2318 rs_machine_dependent.
2319 For, frag_var may change frag_now->fr_type to rs_fill by calling frag_grow which
2320 acturally will call frag_wane.
2321 Calling frag_grow first will create a new frag_now which free size is 20 that is enough
2325 p
= frag_more (backup_inst1
.size
);
2326 md_number_to_chars (p
, backup_inst1
.instruction
, backup_inst1
.size
);
2329 dwarf2_emit_insn (backup_inst1
.size
);
2332 /* Generate fixup structure. */
2335 if (inst1
->reloc
.type
!= BFD_RELOC_NONE
)
2336 fix_new_score (frag_now
, p
- frag_now
->fr_literal
,
2337 inst1
->size
, &inst1
->reloc
.exp
,
2338 inst1
->reloc
.pc_rel
, inst1
->reloc
.type
);
2340 if (inst2
->reloc
.type
!= BFD_RELOC_NONE
)
2341 fix_new_score (frag_now
, p
- frag_now
->fr_literal
+ 2,
2342 inst2
->size
, &inst2
->reloc
.exp
, inst2
->reloc
.pc_rel
, inst2
->reloc
.type
);
2346 if (backup_inst1
.reloc
.type
!= BFD_RELOC_NONE
)
2347 fix_new_score (frag_now
, p
- frag_now
->fr_literal
,
2348 backup_inst1
.size
, &backup_inst1
.reloc
.exp
,
2349 backup_inst1
.reloc
.pc_rel
, backup_inst1
.reloc
.type
);
2352 /* relax_size may be 2, 4, 12 or 0, 0 indicates no relaxation. */
2353 relaxable_p
&= (backup_inst1
.relax_size
!= 0);
2354 relax_size
= relaxable_p
? backup_inst1
.relax_size
: 0;
2356 p
= frag_var (rs_machine_dependent
, relax_size
+ RELAX_PAD_BYTE
, 0,
2357 RELAX_ENCODE (backup_inst1
.size
, backup_inst1
.relax_size
,
2358 backup_inst1
.type
, 0, 0, relaxable_p
),
2359 backup_inst1
.reloc
.exp
.X_add_symbol
, 0, NULL
);
2362 md_number_to_chars (p
, backup_inst1
.relax_inst
, relax_size
);
2364 memcpy (inst1
, &backup_inst1
, sizeof (struct score_it
));
2368 parse_16_32_inst (char *insnstr
, bfd_boolean gen_frag_p
)
2372 char *operator = insnstr
;
2373 const struct asm_opcode
*opcode
;
2375 /* Parse operator and operands. */
2376 skip_whitespace (operator);
2378 for (p
= operator; *p
!= '\0'; p
++)
2379 if ((*p
== ' ') || (*p
== '!'))
2388 opcode
= (const struct asm_opcode
*) hash_find (score_ops_hsh
, operator);
2391 memset (&inst
, '\0', sizeof (inst
));
2392 sprintf (inst
.str
, "%s", insnstr
);
2395 inst
.instruction
= opcode
->value
;
2396 inst
.relax_inst
= opcode
->relax_value
;
2397 inst
.type
= opcode
->type
;
2398 inst
.size
= GET_INSN_SIZE (inst
.type
);
2399 inst
.relax_size
= 0;
2401 sprintf (inst
.name
, "%s", opcode
->template);
2402 strcpy (inst
.reg
, "");
2404 inst
.reloc
.type
= BFD_RELOC_NONE
;
2406 (*opcode
->parms
) (p
);
2408 /* It indicates current instruction is a macro instruction if inst.bwarn equals -1. */
2409 if ((inst
.bwarn
!= -1) && (!inst
.error
) && (gen_frag_p
))
2410 gen_insn_frag (&inst
, NULL
);
2413 inst
.error
= _("unrecognized opcode");
2417 append_insn (char *str
, bfd_boolean gen_frag_p
)
2419 int retval
= SUCCESS
;
2421 parse_16_32_inst (str
, gen_frag_p
);
2425 retval
= (int) FAIL
;
2426 as_bad (_("%s -- `%s'"), inst
.error
, inst
.str
);
2433 /* Handle mv! reg_high, reg_low;
2434 mv! reg_low, reg_high;
2435 mv! reg_low, reg_low; */
2437 do16_mv_rdrs (char *str
)
2441 char *backupstr
= NULL
;
2444 skip_whitespace (str
);
2446 if ((reg_rd
= reg_required_here (&str
, 8, REG_TYPE_SCORE
)) == (int) FAIL
2447 || skip_past_comma (&str
) == (int) FAIL
2448 || (reg_rs
= reg_required_here (&str
, 4, REG_TYPE_SCORE
)) == (int) FAIL
2449 || end_of_line (str
) == (int) FAIL
)
2455 /* Case 1 : mv! or mlfh!. */
2460 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 20)
2461 | (((inst
.instruction
>> 4) & 0xf) << 15) | (0xf << 10);
2462 inst
.relax_size
= 4;
2466 char append_str
[MAX_LITERAL_POOL_SIZE
];
2468 sprintf (append_str
, "mlfh! %s", backupstr
);
2469 if (append_insn (append_str
, TRUE
) == (int) FAIL
)
2471 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
2475 /* Case 2 : mhfl!. */
2480 SET_INSN_ERROR (BAD_ARGS
);
2485 char append_str
[MAX_LITERAL_POOL_SIZE
];
2487 sprintf (append_str
, "mhfl! %s", backupstr
);
2488 if (append_insn (append_str
, TRUE
) == (int) FAIL
)
2491 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
2499 do16_rdi4 (char *str
)
2501 skip_whitespace (str
);
2503 if (reglow_required_here (&str
, 8) == (int) FAIL
2504 || skip_past_comma (&str
) == (int) FAIL
2505 || data_op2 (&str
, 3, _IMM4
) == (int) FAIL
2506 || end_of_line (str
) == (int) FAIL
)
2512 if (((inst
.instruction
>> 3) & 0x10) == 0) /* for judge is addei or subei : bit 5 =0 : addei */
2514 if (((inst
.instruction
>> 3) & 0xf) != 0xf)
2516 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 20)
2517 | ((1 << ((inst
.instruction
>> 3) & 0xf)) << 1);
2518 inst
.relax_size
= 4;
2522 inst
.relax_inst
= 0x8000;
2527 if (((inst
.instruction
>> 3) & 0xf) != 0xf)
2529 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 20)
2530 | (((-(1 << ((inst
.instruction
>> 3) & 0xf))) & 0xffff) << 1);
2531 inst
.relax_size
= 4;
2535 inst
.relax_inst
= 0x8000;
2542 do16_rdi5 (char *str
)
2544 skip_whitespace (str
);
2546 if (reglow_required_here (&str
, 8) == (int) FAIL
2547 || skip_past_comma (&str
) == (int) FAIL
2548 || data_op2 (&str
, 3, _IMM5
) == (int) FAIL
2549 || end_of_line (str
) == (int) FAIL
)
2553 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 20)
2554 | (((inst
.instruction
>> 8) & 0xf) << 15) | (((inst
.instruction
>> 3) & 0x1f) << 10);
2555 inst
.relax_size
= 4;
2561 do16_xi5 (char *str
)
2563 skip_whitespace (str
);
2565 if (data_op2 (&str
, 3, _IMM5
) == (int) FAIL
|| end_of_line (str
) == (int) FAIL
)
2569 inst
.relax_inst
|= (((inst
.instruction
>> 3) & 0x1f) << 15);
2570 inst
.relax_size
= 4;
2574 /* Check that an immediate is word alignment or half word alignment.
2575 If so, convert it to the right format. */
2577 validate_immediate_align (int val
, unsigned int data_type
)
2579 if (data_type
== _IMM5_RSHIFT_1
)
2583 inst
.error
= _("address offset must be half word alignment");
2587 else if ((data_type
== _IMM5_RSHIFT_2
) || (data_type
== _IMM10_RSHIFT_2
))
2591 inst
.error
= _("address offset must be word alignment");
2600 exp_ldst_offset (char **str
, int shift
, unsigned int data_type
)
2606 if ((*dataptr
== '0') && (*(dataptr
+ 1) == 'x')
2607 && (data_type
!= _SIMM16_LA
)
2608 && (data_type
!= _VALUE_HI16
)
2609 && (data_type
!= _VALUE_LO16
)
2610 && (data_type
!= _IMM16
)
2611 && (data_type
!= _IMM15
)
2612 && (data_type
!= _IMM14
)
2613 && (data_type
!= _IMM4
)
2614 && (data_type
!= _IMM5
)
2615 && (data_type
!= _IMM8
)
2616 && (data_type
!= _IMM5_RSHIFT_1
)
2617 && (data_type
!= _IMM5_RSHIFT_2
)
2618 && (data_type
!= _SIMM14_NEG
)
2619 && (data_type
!= _IMM10_RSHIFT_2
))
2624 if (my_get_expression (&inst
.reloc
.exp
, str
) == (int) FAIL
)
2627 if (inst
.reloc
.exp
.X_op
== O_constant
)
2629 /* Need to check the immediate align. */
2630 int value
= validate_immediate_align (inst
.reloc
.exp
.X_add_number
, data_type
);
2632 if (value
== (int) FAIL
)
2635 value
= validate_immediate (inst
.reloc
.exp
.X_add_number
, data_type
, 0);
2636 if (value
== (int) FAIL
)
2640 _("invalid constant: %d bit expression not in range %d..%d"),
2641 score_df_range
[data_type
].bits
,
2642 score_df_range
[data_type
].range
[0], score_df_range
[data_type
].range
[1]);
2645 _("invalid constant: %d bit expression not in range %d..%d"),
2646 score_df_range
[data_type
- 24].bits
,
2647 score_df_range
[data_type
- 24].range
[0], score_df_range
[data_type
- 24].range
[1]);
2648 inst
.error
= err_msg
;
2652 if (data_type
== _IMM5_RSHIFT_1
)
2656 else if ((data_type
== _IMM5_RSHIFT_2
) || (data_type
== _IMM10_RSHIFT_2
))
2661 if (score_df_range
[data_type
].range
[0] != 0)
2663 value
&= (1 << score_df_range
[data_type
].bits
) - 1;
2666 inst
.instruction
|= value
<< shift
;
2670 inst
.reloc
.pc_rel
= 0;
2677 do_ldst_insn (char *str
)
2689 skip_whitespace (str
);
2691 if (((conflict_reg
= reg_required_here (&str
, 20, REG_TYPE_SCORE
)) == (int) FAIL
)
2692 || (skip_past_comma (&str
) == (int) FAIL
))
2695 /* ld/sw rD, [rA, simm15] ld/sw rD, [rA]+, simm12 ld/sw rD, [rA, simm12]+. */
2699 skip_whitespace (str
);
2701 if ((reg
= reg_required_here (&str
, 15, REG_TYPE_SCORE
)) == (int) FAIL
)
2704 /* Conflicts can occur on stores as well as loads. */
2705 conflict_reg
= (conflict_reg
== reg
);
2706 skip_whitespace (str
);
2707 temp
= str
+ 1; /* The latter will process decimal/hex expression. */
2709 /* ld/sw rD, [rA]+, simm12 ld/sw rD, [rA]+. */
2716 /* ld/sw rD, [rA]+, simm12. */
2717 if (skip_past_comma (&str
) == SUCCESS
)
2719 if ((exp_ldst_offset (&str
, 3, _SIMM12
) == (int) FAIL
)
2720 || (end_of_line (str
) == (int) FAIL
))
2725 unsigned int ldst_func
= inst
.instruction
& OPC_PSEUDOLDST_MASK
;
2727 if ((ldst_func
== INSN_LH
)
2728 || (ldst_func
== INSN_LHU
)
2729 || (ldst_func
== INSN_LW
)
2730 || (ldst_func
== INSN_LB
)
2731 || (ldst_func
== INSN_LBU
))
2733 inst
.error
= _("register same as write-back base");
2738 ldst_idx
= inst
.instruction
& OPC_PSEUDOLDST_MASK
;
2739 inst
.instruction
&= ~OPC_PSEUDOLDST_MASK
;
2740 inst
.instruction
|= score_ldst_insns
[ldst_idx
* 3 + LDST_POST
].value
;
2742 /* lw rD, [rA]+, 4 convert to pop rD, [rA]. */
2743 if ((inst
.instruction
& 0x3e000007) == 0x0e000000)
2745 /* rs = r0-r7, offset = 4 */
2746 if ((((inst
.instruction
>> 15) & 0x18) == 0)
2747 && (((inst
.instruction
>> 3) & 0xfff) == 4))
2749 /* Relax to pophi. */
2750 if ((((inst
.instruction
>> 20) & 0x10) == 0x10))
2752 inst
.relax_inst
= 0x0000200a | (((inst
.instruction
>> 20) & 0xf)
2754 (((inst
.instruction
>> 15) & 0x7) << 4);
2759 inst
.relax_inst
= 0x0000200a | (((inst
.instruction
>> 20) & 0xf)
2761 (((inst
.instruction
>> 15) & 0x7) << 4);
2763 inst
.relax_size
= 2;
2768 /* ld/sw rD, [rA]+ convert to ld/sw rD, [rA, 0]+. */
2771 SET_INSN_ERROR (NULL
);
2772 if (end_of_line (str
) == (int) FAIL
)
2778 value
= validate_immediate (inst
.reloc
.exp
.X_add_number
, _SIMM12
, 0);
2779 value
&= (1 << score_df_range
[_SIMM12
].bits
) - 1;
2780 ldst_idx
= inst
.instruction
& OPC_PSEUDOLDST_MASK
;
2781 inst
.instruction
&= ~OPC_PSEUDOLDST_MASK
;
2782 inst
.instruction
|= score_ldst_insns
[ldst_idx
* 3 + pre_inc
].value
;
2783 inst
.instruction
|= value
<< 3;
2784 inst
.relax_inst
= 0x8000;
2788 /* ld/sw rD, [rA] convert to ld/sw rD, [rA, simm15]. */
2791 if (end_of_line (str
) == (int) FAIL
)
2794 ldst_idx
= inst
.instruction
& OPC_PSEUDOLDST_MASK
;
2795 inst
.instruction
&= ~OPC_PSEUDOLDST_MASK
;
2796 inst
.instruction
|= score_ldst_insns
[ldst_idx
* 3 + LDST_NOUPDATE
].value
;
2798 /* lbu rd, [rs] -> lbu! rd, [rs] */
2799 if (ldst_idx
== INSN_LBU
)
2801 inst
.relax_inst
= INSN16_LBU
;
2803 else if (ldst_idx
== INSN_LH
)
2805 inst
.relax_inst
= INSN16_LH
;
2807 else if (ldst_idx
== INSN_LW
)
2809 inst
.relax_inst
= INSN16_LW
;
2811 else if (ldst_idx
== INSN_SB
)
2813 inst
.relax_inst
= INSN16_SB
;
2815 else if (ldst_idx
== INSN_SH
)
2817 inst
.relax_inst
= INSN16_SH
;
2819 else if (ldst_idx
== INSN_SW
)
2821 inst
.relax_inst
= INSN16_SW
;
2825 inst
.relax_inst
= 0x8000;
2828 /* lw/lh/lbu/sw/sh/sb, offset = 0, relax to 16 bit instruction. */
2829 if ((ldst_idx
== INSN_LBU
)
2830 || (ldst_idx
== INSN_LH
)
2831 || (ldst_idx
== INSN_LW
)
2832 || (ldst_idx
== INSN_SB
) || (ldst_idx
== INSN_SH
) || (ldst_idx
== INSN_SW
))
2834 if ((((inst
.instruction
>> 15) & 0x10) == 0) && (((inst
.instruction
>> 20) & 0x10) == 0))
2836 inst
.relax_inst
|= (2 << 12) | (((inst
.instruction
>> 20) & 0xf) << 8) |
2837 (((inst
.instruction
>> 15) & 0xf) << 4);
2838 inst
.relax_size
= 2;
2845 /* ld/sw rD, [rA, simm15] ld/sw rD, [rA, simm12]+. */
2848 if (skip_past_comma (&str
) == (int) FAIL
)
2850 inst
.error
= _("pre-indexed expression expected");
2854 if (my_get_expression (&inst
.reloc
.exp
, &str
) == (int) FAIL
)
2857 skip_whitespace (str
);
2860 inst
.error
= _("missing ]");
2864 skip_whitespace (str
);
2865 /* ld/sw rD, [rA, simm12]+. */
2872 unsigned int ldst_func
= inst
.instruction
& OPC_PSEUDOLDST_MASK
;
2874 if ((ldst_func
== INSN_LH
)
2875 || (ldst_func
== INSN_LHU
)
2876 || (ldst_func
== INSN_LW
)
2877 || (ldst_func
== INSN_LB
)
2878 || (ldst_func
== INSN_LBU
))
2880 inst
.error
= _("register same as write-back base");
2886 if (end_of_line (str
) == (int) FAIL
)
2889 if (inst
.reloc
.exp
.X_op
== O_constant
)
2892 unsigned int data_type
;
2895 data_type
= _SIMM12
;
2897 data_type
= _SIMM15
;
2900 if ((*dataptr
== '0') && (*(dataptr
+ 1) == 'x')
2901 && (data_type
!= _SIMM16_LA
)
2902 && (data_type
!= _VALUE_HI16
)
2903 && (data_type
!= _VALUE_LO16
)
2904 && (data_type
!= _IMM16
)
2905 && (data_type
!= _IMM15
)
2906 && (data_type
!= _IMM14
)
2907 && (data_type
!= _IMM4
)
2908 && (data_type
!= _IMM5
)
2909 && (data_type
!= _IMM8
)
2910 && (data_type
!= _IMM5_RSHIFT_1
)
2911 && (data_type
!= _IMM5_RSHIFT_2
)
2912 && (data_type
!= _SIMM14_NEG
)
2913 && (data_type
!= _IMM10_RSHIFT_2
))
2918 value
= validate_immediate (inst
.reloc
.exp
.X_add_number
, data_type
, 0);
2919 if (value
== (int) FAIL
)
2923 _("invalid constant: %d bit expression not in range %d..%d"),
2924 score_df_range
[data_type
].bits
,
2925 score_df_range
[data_type
].range
[0], score_df_range
[data_type
].range
[1]);
2928 _("invalid constant: %d bit expression not in range %d..%d"),
2929 score_df_range
[data_type
- 24].bits
,
2930 score_df_range
[data_type
- 24].range
[0],
2931 score_df_range
[data_type
- 24].range
[1]);
2932 inst
.error
= err_msg
;
2936 value
&= (1 << score_df_range
[data_type
].bits
) - 1;
2937 ldst_idx
= inst
.instruction
& OPC_PSEUDOLDST_MASK
;
2938 inst
.instruction
&= ~OPC_PSEUDOLDST_MASK
;
2939 inst
.instruction
|= score_ldst_insns
[ldst_idx
* 3 + pre_inc
].value
;
2941 inst
.instruction
|= value
<< 3;
2943 inst
.instruction
|= value
;
2945 /* lw rD, [rA, simm15] */
2946 if ((inst
.instruction
& 0x3e000000) == 0x20000000)
2948 /* Both rD and rA are in [r0 - r15]. */
2949 if ((((inst
.instruction
>> 15) & 0x10) == 0)
2950 && (((inst
.instruction
>> 20) & 0x10) == 0))
2952 /* simm15 = 0, lw -> lw!. */
2953 if ((inst
.instruction
& 0x7fff) == 0)
2955 inst
.relax_inst
|= (((inst
.instruction
>> 15) & 0xf) << 4)
2956 | (((inst
.instruction
>> 20) & 0xf) << 8);
2957 inst
.relax_size
= 2;
2959 /* rA = r2, lw -> lwp!. */
2960 else if ((((inst
.instruction
>> 15) & 0xf) == 2)
2961 && ((inst
.instruction
& 0x3) == 0)
2962 && ((inst
.instruction
& 0x7fff) < 128))
2964 inst
.relax_inst
= 0x7000 | (((inst
.instruction
>> 20) & 0xf) << 8)
2965 | (((inst
.instruction
& 0x7fff) >> 2) << 3);
2966 inst
.relax_size
= 2;
2970 inst
.relax_inst
= 0x8000;
2975 inst
.relax_inst
= 0x8000;
2978 /* sw rD, [rA, simm15] */
2979 else if ((inst
.instruction
& 0x3e000000) == 0x28000000)
2981 /* Both rD and rA are in [r0 - r15]. */
2982 if ((((inst
.instruction
>> 15) & 0x10) == 0) && (((inst
.instruction
>> 20) & 0x10) == 0))
2984 /* simm15 = 0, sw -> sw!. */
2985 if ((inst
.instruction
& 0x7fff) == 0)
2987 inst
.relax_inst
|= (((inst
.instruction
>> 15) & 0xf) << 4)
2988 | (((inst
.instruction
>> 20) & 0xf) << 8);
2989 inst
.relax_size
= 2;
2991 /* rA = r2, sw -> swp!. */
2992 else if ((((inst
.instruction
>> 15) & 0xf) == 2)
2993 && ((inst
.instruction
& 0x3) == 0)
2994 && ((inst
.instruction
& 0x7fff) < 128))
2996 inst
.relax_inst
= 0x7004 | (((inst
.instruction
>> 20) & 0xf) << 8)
2997 | (((inst
.instruction
& 0x7fff) >> 2) << 3);
2998 inst
.relax_size
= 2;
3002 inst
.relax_inst
= 0x8000;
3007 inst
.relax_inst
= 0x8000;
3010 /* sw rD, [rA, simm15]+ sw pre. */
3011 else if ((inst
.instruction
& 0x3e000007) == 0x06000004)
3013 /* rA is in [r0 - r7], and simm15 = -4. */
3014 if ((((inst
.instruction
>> 15) & 0x18) == 0)
3015 && (((inst
.instruction
>> 3) & 0xfff) == 0xffc))
3017 /* sw -> pushhi!. */
3018 if ((((inst
.instruction
>> 20) & 0x10) == 0x10))
3020 inst
.relax_inst
= 0x0000200e | (((inst
.instruction
>> 20) & 0xf) << 8)
3021 | 1 << 7 | (((inst
.instruction
>> 15) & 0x7) << 4);
3022 inst
.relax_size
= 2;
3027 inst
.relax_inst
= 0x0000200e | (((inst
.instruction
>> 20) & 0xf) << 8)
3028 | 0 << 7 | (((inst
.instruction
>> 15) & 0x7) << 4);
3029 inst
.relax_size
= 2;
3034 inst
.relax_inst
= 0x8000;
3037 /* lh rD, [rA, simm15] */
3038 else if ((inst
.instruction
& 0x3e000000) == 0x22000000)
3040 /* Both rD and rA are in [r0 - r15]. */
3041 if ((((inst
.instruction
>> 15) & 0x10) == 0) && (((inst
.instruction
>> 20) & 0x10) == 0))
3043 /* simm15 = 0, lh -> lh!. */
3044 if ((inst
.instruction
& 0x7fff) == 0)
3046 inst
.relax_inst
|= (((inst
.instruction
>> 15) & 0xf) << 4)
3047 | (((inst
.instruction
>> 20) & 0xf) << 8);
3048 inst
.relax_size
= 2;
3050 /* rA = r2, lh -> lhp!. */
3051 else if ((((inst
.instruction
>> 15) & 0xf) == 2)
3052 && ((inst
.instruction
& 0x1) == 0)
3053 && ((inst
.instruction
& 0x7fff) < 64))
3055 inst
.relax_inst
= 0x7001 | (((inst
.instruction
>> 20) & 0xf) << 8)
3056 | (((inst
.instruction
& 0x7fff) >> 1) << 3);
3057 inst
.relax_size
= 2;
3061 inst
.relax_inst
= 0x8000;
3066 inst
.relax_inst
= 0x8000;
3069 /* sh rD, [rA, simm15] */
3070 else if ((inst
.instruction
& 0x3e000000) == 0x2a000000)
3072 /* Both rD and rA are in [r0 - r15]. */
3073 if ((((inst
.instruction
>> 15) & 0x10) == 0) && (((inst
.instruction
>> 20) & 0x10) == 0))
3075 /* simm15 = 0, sh -> sh!. */
3076 if ((inst
.instruction
& 0x7fff) == 0)
3078 inst
.relax_inst
|= (((inst
.instruction
>> 15) & 0xf) << 4)
3079 | (((inst
.instruction
>> 20) & 0xf) << 8);
3080 inst
.relax_size
= 2;
3082 /* rA = r2, sh -> shp!. */
3083 else if ((((inst
.instruction
>> 15) & 0xf) == 2)
3084 && ((inst
.instruction
& 0x1) == 0)
3085 && ((inst
.instruction
& 0x7fff) < 64))
3087 inst
.relax_inst
= 0x7005 | (((inst
.instruction
>> 20) & 0xf) << 8)
3088 | (((inst
.instruction
& 0x7fff) >> 1) << 3);
3089 inst
.relax_size
= 2;
3093 inst
.relax_inst
= 0x8000;
3098 inst
.relax_inst
= 0x8000;
3101 /* lbu rD, [rA, simm15] */
3102 else if ((inst
.instruction
& 0x3e000000) == 0x2c000000)
3104 /* Both rD and rA are in [r0 - r15]. */
3105 if ((((inst
.instruction
>> 15) & 0x10) == 0) && (((inst
.instruction
>> 20) & 0x10) == 0))
3107 /* simm15 = 0, lbu -> lbu!. */
3108 if ((inst
.instruction
& 0x7fff) == 0)
3110 inst
.relax_inst
|= (((inst
.instruction
>> 15) & 0xf) << 4)
3111 | (((inst
.instruction
>> 20) & 0xf) << 8);
3112 inst
.relax_size
= 2;
3114 /* rA = r2, lbu -> lbup!. */
3115 else if ((((inst
.instruction
>> 15) & 0xf) == 2)
3116 && ((inst
.instruction
& 0x7fff) < 32))
3118 inst
.relax_inst
= 0x7003 | (((inst
.instruction
>> 20) & 0xf) << 8)
3119 | ((inst
.instruction
& 0x7fff) << 3);
3120 inst
.relax_size
= 2;
3124 inst
.relax_inst
= 0x8000;
3129 inst
.relax_inst
= 0x8000;
3132 /* sb rD, [rA, simm15] */
3133 else if ((inst
.instruction
& 0x3e000000) == 0x2e000000)
3135 /* Both rD and rA are in [r0 - r15]. */
3136 if ((((inst
.instruction
>> 15) & 0x10) == 0) && (((inst
.instruction
>> 20) & 0x10) == 0))
3138 /* simm15 = 0, sb -> sb!. */
3139 if ((inst
.instruction
& 0x7fff) == 0)
3141 inst
.relax_inst
|= (((inst
.instruction
>> 15) & 0xf) << 4)
3142 | (((inst
.instruction
>> 20) & 0xf) << 8);
3143 inst
.relax_size
= 2;
3145 /* rA = r2, sb -> sb!. */
3146 else if ((((inst
.instruction
>> 15) & 0xf) == 2)
3147 && ((inst
.instruction
& 0x7fff) < 32))
3149 inst
.relax_inst
= 0x7007 | (((inst
.instruction
>> 20) & 0xf) << 8)
3150 | ((inst
.instruction
& 0x7fff) << 3);
3151 inst
.relax_size
= 2;
3155 inst
.relax_inst
= 0x8000;
3160 inst
.relax_inst
= 0x8000;
3165 inst
.relax_inst
= 0x8000;
3172 /* FIXME: may set error, for there is no ld/sw rD, [rA, label] */
3173 inst
.reloc
.pc_rel
= 0;
3179 inst
.error
= BAD_ARGS
;
3186 do_cache (char *str
)
3188 skip_whitespace (str
);
3190 if ((data_op2 (&str
, 20, _IMM5
) == (int) FAIL
) || (skip_past_comma (&str
) == (int) FAIL
))
3198 cache_op
= (inst
.instruction
>> 20) & 0x1F;
3199 sprintf (inst
.name
, "cache %d", cache_op
);
3205 skip_whitespace (str
);
3207 if (reg_required_here (&str
, 15, REG_TYPE_SCORE
) == (int) FAIL
)
3210 skip_whitespace (str
);
3212 /* cache op, [rA] */
3213 if (skip_past_comma (&str
) == (int) FAIL
)
3215 SET_INSN_ERROR (NULL
);
3218 inst
.error
= _("missing ]");
3223 /* cache op, [rA, simm15] */
3226 if (exp_ldst_offset (&str
, 0, _SIMM15
) == (int) FAIL
)
3231 skip_whitespace (str
);
3234 inst
.error
= _("missing ]");
3239 if (end_of_line (str
) == (int) FAIL
)
3244 inst
.error
= BAD_ARGS
;
3249 do_crdcrscrsimm5 (char *str
)
3254 skip_whitespace (str
);
3256 if (reg_required_here (&str
, 20, REG_TYPE_SCORE_CR
) == (int) FAIL
3257 || skip_past_comma (&str
) == (int) FAIL
3258 || reg_required_here (&str
, 15, REG_TYPE_SCORE_CR
) == (int) FAIL
3259 || skip_past_comma (&str
) == (int) FAIL
3260 || reg_required_here (&str
, 10, REG_TYPE_SCORE_CR
) == (int) FAIL
3261 || skip_past_comma (&str
) == (int) FAIL
)
3264 /* cop1 cop_code20. */
3265 if (data_op2 (&str
, 5, _IMM20
) == (int) FAIL
)
3270 if (data_op2 (&str
, 5, _IMM5
) == (int) FAIL
)
3277 /* Handle ldc/stc. */
3279 do_ldst_cop (char *str
)
3281 skip_whitespace (str
);
3283 if ((reg_required_here (&str
, 15, REG_TYPE_SCORE_CR
) == (int) FAIL
)
3284 || (skip_past_comma (&str
) == (int) FAIL
))
3290 skip_whitespace (str
);
3292 if (reg_required_here (&str
, 20, REG_TYPE_SCORE
) == (int) FAIL
)
3295 skip_whitespace (str
);
3299 if (exp_ldst_offset (&str
, 5, _IMM10_RSHIFT_2
) == (int) FAIL
)
3302 skip_whitespace (str
);
3305 inst
.error
= _("missing ]");
3313 inst
.error
= BAD_ARGS
;
3317 do16_ldst_insn (char *str
)
3319 skip_whitespace (str
);
3321 if ((reglow_required_here (&str
, 8) == (int) FAIL
) || (skip_past_comma (&str
) == (int) FAIL
))
3329 skip_whitespace (str
);
3331 if ((reg
= reglow_required_here (&str
, 4)) == (int) FAIL
)
3334 skip_whitespace (str
);
3337 if (end_of_line (str
) == (int) FAIL
)
3341 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 20)
3342 | (((inst
.instruction
>> 4) & 0xf) << 15);
3343 inst
.relax_size
= 4;
3348 inst
.error
= _("missing ]");
3353 inst
.error
= BAD_ARGS
;
3357 /* Handle lbup!/lhp!/ldiu!/lwp!/sbp!/shp!/swp!. */
3359 do16_ldst_imm_insn (char *str
)
3361 char data_exp
[MAX_LITERAL_POOL_SIZE
];
3363 char *dataptr
= NULL
, *pp
= NULL
;
3365 int assign_data
= (int) FAIL
;
3366 unsigned int ldst_func
;
3368 skip_whitespace (str
);
3370 if (((reg_rd
= reglow_required_here (&str
, 8)) == (int) FAIL
)
3371 || (skip_past_comma (&str
) == (int) FAIL
))
3374 skip_whitespace (str
);
3377 while ((*dataptr
!= '\0') && (*dataptr
!= '|') && (cnt
<= MAX_LITERAL_POOL_SIZE
))
3379 data_exp
[cnt
] = *dataptr
;
3384 data_exp
[cnt
] = '\0';
3389 ldst_func
= inst
.instruction
& LDST16_RI_MASK
;
3390 if (ldst_func
== N16_LIU
)
3391 assign_data
= exp_ldst_offset (&pp
, 0, _IMM8
);
3392 else if (ldst_func
== N16_LHP
|| ldst_func
== N16_SHP
)
3393 assign_data
= exp_ldst_offset (&pp
, 3, _IMM5_RSHIFT_1
);
3394 else if (ldst_func
== N16_LWP
|| ldst_func
== N16_SWP
)
3395 assign_data
= exp_ldst_offset (&pp
, 3, _IMM5_RSHIFT_2
);
3397 assign_data
= exp_ldst_offset (&pp
, 3, _IMM5
);
3399 if ((assign_data
== (int) FAIL
) || (end_of_line (pp
) == (int) FAIL
))
3403 if ((inst
.instruction
& 0x7000) == N16_LIU
)
3405 inst
.relax_inst
|= ((inst
.instruction
>> 8) & 0xf) << 20
3406 | ((inst
.instruction
& 0xff) << 1);
3408 else if (((inst
.instruction
& 0x7007) == N16_LHP
)
3409 || ((inst
.instruction
& 0x7007) == N16_SHP
))
3411 inst
.relax_inst
|= ((inst
.instruction
>> 8) & 0xf) << 20 | 2 << 15
3412 | (((inst
.instruction
>> 3) & 0x1f) << 1);
3414 else if (((inst
.instruction
& 0x7007) == N16_LWP
)
3415 || ((inst
.instruction
& 0x7007) == N16_SWP
))
3417 inst
.relax_inst
|= ((inst
.instruction
>> 8) & 0xf) << 20 | 2 << 15
3418 | (((inst
.instruction
>> 3) & 0x1f) << 2);
3420 else if (((inst
.instruction
& 0x7007) == N16_LBUP
)
3421 || ((inst
.instruction
& 0x7007) == N16_SBP
))
3423 inst
.relax_inst
|= ((inst
.instruction
>> 8) & 0xf) << 20 | 2 << 15
3424 | (((inst
.instruction
>> 3) & 0x1f));
3427 inst
.relax_size
= 4;
3432 do16_push_pop (char *str
)
3437 skip_whitespace (str
);
3438 if (((reg_rd
= reg_required_here (&str
, 8, REG_TYPE_SCORE
)) == (int) FAIL
)
3439 || (skip_past_comma (&str
) == (int) FAIL
))
3445 /* reg_required_here will change bit 12 of opcode, so we must restore bit 12. */
3446 inst
.instruction
&= ~(1 << 12);
3448 inst
.instruction
|= H_bit_mask
<< 7;
3455 skip_whitespace (str
);
3456 if ((reg
= reg_required_here (&str
, 4, REG_TYPE_SCORE
)) == (int) FAIL
)
3461 inst
.error
= _("base register nums are over 3 bit");
3466 skip_whitespace (str
);
3467 if ((*str
++ != ']') || (end_of_line (str
) == (int) FAIL
))
3470 inst
.error
= _("missing ]");
3476 if ((inst
.instruction
& 0xf) == 0xa)
3480 inst
.relax_inst
|= ((((inst
.instruction
>> 8) & 0xf) | 0x10) << 20)
3481 | (((inst
.instruction
>> 4) & 0x7) << 15) | (4 << 3);
3485 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 20)
3486 | (((inst
.instruction
>> 4) & 0x7) << 15) | (4 << 3);
3494 inst
.relax_inst
|= ((((inst
.instruction
>> 8) & 0xf) | 0x10) << 20)
3495 | (((inst
.instruction
>> 4) & 0x7) << 15) | (((-4) & 0xfff) << 3);
3499 inst
.relax_inst
|= (((inst
.instruction
>> 8) & 0xf) << 20)
3500 | (((inst
.instruction
>> 4) & 0x7) << 15) | (((-4) & 0xfff) << 3);
3503 inst
.relax_size
= 4;
3507 inst
.error
= BAD_ARGS
;
3511 /* Handle lcb/lcw/lce/scb/scw/sce. */
3513 do_ldst_unalign (char *str
)
3517 if (university_version
== 1)
3519 inst
.error
= ERR_FOR_SCORE5U_ATOMIC
;
3523 skip_whitespace (str
);
3525 /* lcb/scb [rA]+. */
3529 skip_whitespace (str
);
3531 if (reg_required_here (&str
, 15, REG_TYPE_SCORE
) == (int) FAIL
)
3538 inst
.error
= _("missing +");
3544 inst
.error
= _("missing ]");
3548 if (end_of_line (str
) == (int) FAIL
)
3551 /* lcw/lce/scb/sce rD, [rA]+. */
3554 if (((conflict_reg
= reg_required_here (&str
, 20, REG_TYPE_SCORE
)) == (int) FAIL
)
3555 || (skip_past_comma (&str
) == (int) FAIL
))
3560 skip_whitespace (str
);
3565 skip_whitespace (str
);
3566 if ((reg
= reg_required_here (&str
, 15, REG_TYPE_SCORE
)) == (int) FAIL
)
3571 /* Conflicts can occur on stores as well as loads. */
3572 conflict_reg
= (conflict_reg
== reg
);
3573 skip_whitespace (str
);
3576 unsigned int ldst_func
= inst
.instruction
& LDST_UNALIGN_MASK
;
3582 as_warn (_("%s register same as write-back base"),
3583 ((ldst_func
& UA_LCE
) || (ldst_func
& UA_LCW
)
3584 ? _("destination") : _("source")));
3589 inst
.error
= _("missing +");
3593 if (end_of_line (str
) == (int) FAIL
)
3598 inst
.error
= _("missing ]");
3604 inst
.error
= BAD_ARGS
;
3610 /* Handle alw/asw. */
3612 do_ldst_atomic (char *str
)
3614 if (university_version
== 1)
3616 inst
.error
= ERR_FOR_SCORE5U_ATOMIC
;
3620 skip_whitespace (str
);
3622 if ((reg_required_here (&str
, 20, REG_TYPE_SCORE
) == (int) FAIL
)
3623 || (skip_past_comma (&str
) == (int) FAIL
))
3630 skip_whitespace (str
);
3635 skip_whitespace (str
);
3636 if ((reg
= reg_required_here (&str
, 15, REG_TYPE_SCORE
)) == (int) FAIL
)
3641 skip_whitespace (str
);
3644 inst
.error
= _("missing ]");
3651 inst
.error
= BAD_ARGS
;
3656 build_relax_frag (struct score_it fix_insts
[RELAX_INST_NUM
], int fix_num ATTRIBUTE_UNUSED
,
3657 struct score_it var_insts
[RELAX_INST_NUM
], int var_num
,
3658 symbolS
*add_symbol
)
3663 fixS
*cur_fixp
= NULL
;
3665 struct score_it inst_main
;
3667 memcpy (&inst_main
, &fix_insts
[0], sizeof (struct score_it
));
3669 /* Adjust instruction opcode and to be relaxed instruction opcode. */
3670 inst_main
.instruction
= adjust_paritybit (inst_main
.instruction
, GET_INSN_CLASS (inst_main
.type
));
3671 inst_main
.type
= Insn_PIC
;
3673 for (i
= 0; i
< var_num
; i
++)
3675 inst_main
.relax_size
+= var_insts
[i
].size
;
3676 var_insts
[i
].instruction
= adjust_paritybit (var_insts
[i
].instruction
,
3677 GET_INSN_CLASS (var_insts
[i
].type
));
3680 /* Check data dependency. */
3681 handle_dependency (&inst_main
);
3683 /* Start a new frag if frag_now is not empty. */
3684 if (frag_now_fix () != 0)
3686 if (!frag_now
->tc_frag_data
.is_insn
)
3688 frag_wane (frag_now
);
3694 /* Write fr_fix part. */
3695 p
= frag_more (inst_main
.size
);
3696 md_number_to_chars (p
, inst_main
.instruction
, inst_main
.size
);
3698 if (inst_main
.reloc
.type
!= BFD_RELOC_NONE
)
3699 fixp
= fix_new_score (frag_now
, p
- frag_now
->fr_literal
, inst_main
.size
,
3700 &inst_main
.reloc
.exp
, inst_main
.reloc
.pc_rel
, inst_main
.reloc
.type
);
3702 frag_now
->tc_frag_data
.fixp
= fixp
;
3703 cur_fixp
= frag_now
->tc_frag_data
.fixp
;
3706 dwarf2_emit_insn (inst_main
.size
);
3709 where
= p
- frag_now
->fr_literal
+ inst_main
.size
;
3710 for (i
= 0; i
< var_num
; i
++)
3713 where
+= var_insts
[i
- 1].size
;
3715 if (var_insts
[i
].reloc
.type
!= BFD_RELOC_NONE
)
3717 fixp
= fix_new_score (frag_now
, where
, var_insts
[i
].size
,
3718 &var_insts
[i
].reloc
.exp
, var_insts
[i
].reloc
.pc_rel
,
3719 var_insts
[i
].reloc
.type
);
3724 cur_fixp
->fx_next
= fixp
;
3725 cur_fixp
= cur_fixp
->fx_next
;
3729 frag_now
->tc_frag_data
.fixp
= fixp
;
3730 cur_fixp
= frag_now
->tc_frag_data
.fixp
;
3736 p
= frag_var (rs_machine_dependent
, inst_main
.relax_size
+ RELAX_PAD_BYTE
, 0,
3737 RELAX_ENCODE (inst_main
.size
, inst_main
.relax_size
, inst_main
.type
,
3738 0, inst_main
.size
, 0), add_symbol
, 0, NULL
);
3740 /* Write fr_var part.
3741 no calling gen_insn_frag, no fixS will be generated. */
3742 for (i
= 0; i
< var_num
; i
++)
3744 md_number_to_chars (p
, var_insts
[i
].instruction
, var_insts
[i
].size
);
3745 p
+= var_insts
[i
].size
;
3747 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
3751 /* Build a relax frag for la instruction when generating PIC,
3752 external symbol first and local symbol second. */
3755 build_la_pic (int reg_rd
, expressionS exp
)
3757 symbolS
*add_symbol
= exp
.X_add_symbol
;
3758 offsetT add_number
= exp
.X_add_number
;
3759 struct score_it fix_insts
[RELAX_INST_NUM
];
3760 struct score_it var_insts
[RELAX_INST_NUM
];
3763 char tmp
[MAX_LITERAL_POOL_SIZE
];
3769 if (add_number
== 0)
3774 /* For an external symbol, only one insn is generated;
3775 For a local symbol, two insns are generated. */
3777 For an external symbol: lw rD, <sym>($gp)
3778 (BFD_RELOC_SCORE_GOT15 or BFD_RELOC_SCORE_CALL15) */
3779 sprintf (tmp
, "lw_pic r%d, %s", reg_rd
, add_symbol
->bsym
->name
);
3780 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
3783 if (reg_rd
== PIC_CALL_REG
)
3784 inst
.reloc
.type
= BFD_RELOC_SCORE_CALL15
;
3785 memcpy (&fix_insts
[0], &inst
, sizeof (struct score_it
));
3788 For a local symbol :
3789 lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15)
3790 addi rD, <sym> (BFD_RELOC_GOT_LO16) */
3791 inst
.reloc
.type
= BFD_RELOC_SCORE_GOT15
;
3792 memcpy (&var_insts
[0], &inst
, sizeof (struct score_it
));
3793 sprintf (tmp
, "addi_s_pic r%d, %s", reg_rd
, add_symbol
->bsym
->name
);
3794 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
3797 memcpy (&var_insts
[1], &inst
, sizeof (struct score_it
));
3798 build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
3800 else if (add_number
>= -0x8000 && add_number
<= 0x7fff)
3802 /* Insn 1: lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15) */
3803 sprintf (tmp
, "lw_pic r%d, %s", reg_rd
, add_symbol
->bsym
->name
);
3804 if (append_insn (tmp
, TRUE
) == (int) FAIL
)
3811 For an external symbol: addi rD, <constant> */
3812 sprintf (tmp
, "addi r%d, %d", reg_rd
, (int)add_number
);
3813 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
3816 memcpy (&fix_insts
[0], &inst
, sizeof (struct score_it
));
3819 For a local symbol: addi rD, <sym>+<constant> (BFD_RELOC_GOT_LO16) */
3820 sprintf (tmp
, "addi_s_pic r%d, %s + %d", reg_rd
, add_symbol
->bsym
->name
, (int)add_number
);
3821 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
3824 memcpy (&var_insts
[0], &inst
, sizeof (struct score_it
));
3825 build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
3829 int hi
= (add_number
>> 16) & 0x0000FFFF;
3830 int lo
= add_number
& 0x0000FFFF;
3832 /* Insn 1: lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15) */
3833 sprintf (tmp
, "lw_pic r%d, %s", reg_rd
, add_symbol
->bsym
->name
);
3834 if (append_insn (tmp
, TRUE
) == (int) FAIL
)
3841 For an external symbol: ldis r1, HI%<constant> */
3842 sprintf (tmp
, "ldis r1, %d", hi
);
3843 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
3846 memcpy (&fix_insts
[0], &inst
, sizeof (struct score_it
));
3849 For a local symbol: ldis r1, HI%<constant>
3850 but, if lo is outof 16 bit, make hi plus 1 */
3851 if ((lo
< -0x8000) || (lo
> 0x7fff))
3855 sprintf (tmp
, "ldis_pic r1, %d", hi
);
3856 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
3859 memcpy (&var_insts
[0], &inst
, sizeof (struct score_it
));
3860 build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
3866 For an external symbol: ori r1, LO%<constant> */
3867 sprintf (tmp
, "ori r1, %d", lo
);
3868 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
3871 memcpy (&fix_insts
[0], &inst
, sizeof (struct score_it
));
3874 For a local symbol: addi r1, <sym>+LO%<constant> (BFD_RELOC_GOT_LO16) */
3875 sprintf (tmp
, "addi_u_pic r1, %s + %d", add_symbol
->bsym
->name
, lo
);
3876 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
3879 memcpy (&var_insts
[0], &inst
, sizeof (struct score_it
));
3880 build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
3882 /* Insn 4: add rD, rD, r1 */
3883 sprintf (tmp
, "add r%d, r%d, r1", reg_rd
, reg_rd
);
3884 if (append_insn (tmp
, TRUE
) == (int) FAIL
)
3887 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
3896 do_macro_la_rdi32 (char *str
)
3900 skip_whitespace (str
);
3901 if ((reg_rd
= reg_required_here (&str
, 20, REG_TYPE_SCORE
)) == (int) FAIL
3902 || skip_past_comma (&str
) == (int) FAIL
)
3908 char append_str
[MAX_LITERAL_POOL_SIZE
];
3909 char *keep_data
= str
;
3911 /* la rd, simm16. */
3912 if (data_op2 (&str
, 1, _SIMM16_LA
) != (int) FAIL
)
3917 /* la rd, imm32 or la rd, label. */
3920 SET_INSN_ERROR (NULL
);
3922 if ((data_op2 (&str
, 1, _VALUE_HI16
) == (int) FAIL
)
3923 || (end_of_line (str
) == (int) FAIL
))
3929 if ((score_pic
== NO_PIC
) || (!inst
.reloc
.exp
.X_add_symbol
))
3931 sprintf (append_str
, "ld_i32hi r%d, %s", reg_rd
, keep_data
);
3932 if (append_insn (append_str
, TRUE
) == (int) FAIL
)
3935 sprintf (append_str
, "ld_i32lo r%d, %s", reg_rd
, keep_data
);
3936 if (append_insn (append_str
, TRUE
) == (int) FAIL
)
3941 assert (inst
.reloc
.exp
.X_add_symbol
);
3942 build_la_pic (reg_rd
, inst
.reloc
.exp
);
3945 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
3954 do_macro_li_rdi32 (char *str
){
3958 skip_whitespace (str
);
3959 if ((reg_rd
= reg_required_here (&str
, 20, REG_TYPE_SCORE
)) == (int) FAIL
3960 || skip_past_comma (&str
) == (int) FAIL
)
3966 char *keep_data
= str
;
3968 /* li rd, simm16. */
3969 if (data_op2 (&str
, 1, _SIMM16_LA
) != (int) FAIL
)
3977 char append_str
[MAX_LITERAL_POOL_SIZE
];
3981 if ((data_op2 (&str
, 1, _VALUE_HI16
) == (int) FAIL
)
3982 || (end_of_line (str
) == (int) FAIL
))
3986 else if (inst
.reloc
.exp
.X_add_symbol
)
3988 inst
.error
= _("li rd label isn't correct instruction form");
3993 sprintf (append_str
, "ld_i32hi r%d, %s", reg_rd
, keep_data
);
3995 if (append_insn (append_str
, TRUE
) == (int) FAIL
)
3999 sprintf (append_str
, "ld_i32lo r%d, %s", reg_rd
, keep_data
);
4000 if (append_insn (append_str
, TRUE
) == (int) FAIL
)
4003 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4011 /* Handle mul/mulu/div/divu/rem/remu. */
4013 do_macro_mul_rdrsrs (char *str
)
4019 char append_str
[MAX_LITERAL_POOL_SIZE
];
4021 if (university_version
== 1)
4022 as_warn ("%s", ERR_FOR_SCORE5U_MUL_DIV
);
4024 strcpy (append_str
, str
);
4025 backupstr
= append_str
;
4026 skip_whitespace (backupstr
);
4027 if (((reg_rd
= reg_required_here (&backupstr
, -1, REG_TYPE_SCORE
)) == (int) FAIL
)
4028 || (skip_past_comma (&backupstr
) == (int) FAIL
)
4029 || ((reg_rs1
= reg_required_here (&backupstr
, -1, REG_TYPE_SCORE
)) == (int) FAIL
))
4031 inst
.error
= BAD_ARGS
;
4035 if (skip_past_comma (&backupstr
) == (int) FAIL
)
4037 /* rem/remu rA, rB is error format. */
4038 if (strcmp (inst
.name
, "rem") == 0 || strcmp (inst
.name
, "remu") == 0)
4040 SET_INSN_ERROR (BAD_ARGS
);
4044 SET_INSN_ERROR (NULL
);
4051 SET_INSN_ERROR (NULL
);
4052 if (((reg_rs2
= reg_required_here (&backupstr
, -1, REG_TYPE_SCORE
)) == (int) FAIL
)
4053 || (end_of_line (backupstr
) == (int) FAIL
))
4059 char append_str1
[MAX_LITERAL_POOL_SIZE
];
4061 if (strcmp (inst
.name
, "rem") == 0)
4063 sprintf (append_str
, "mul r%d, r%d", reg_rs1
, reg_rs2
);
4064 sprintf (append_str1
, "mfceh r%d", reg_rd
);
4066 else if (strcmp (inst
.name
, "remu") == 0)
4068 sprintf (append_str
, "mulu r%d, r%d", reg_rs1
, reg_rs2
);
4069 sprintf (append_str1
, "mfceh r%d", reg_rd
);
4073 sprintf (append_str
, "%s r%d, r%d", inst
.name
, reg_rs1
, reg_rs2
);
4074 sprintf (append_str1
, "mfcel r%d", reg_rd
);
4077 /* Output mul/mulu or div/divu or rem/remu. */
4078 if (append_insn (append_str
, TRUE
) == (int) FAIL
)
4081 /* Output mfcel or mfceh. */
4082 if (append_insn (append_str1
, TRUE
) == (int) FAIL
)
4085 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4092 exp_macro_ldst_abs (char *str
)
4095 char *backupstr
, *tmp
;
4096 char append_str
[MAX_LITERAL_POOL_SIZE
];
4097 char verifystr
[MAX_LITERAL_POOL_SIZE
];
4098 struct score_it inst_backup
;
4103 memcpy (&inst_backup
, &inst
, sizeof (struct score_it
));
4105 strcpy (verifystr
, str
);
4106 backupstr
= verifystr
;
4107 skip_whitespace (backupstr
);
4108 if ((reg_rd
= reg_required_here (&backupstr
, -1, REG_TYPE_SCORE
)) == (int) FAIL
)
4112 if (skip_past_comma (&backupstr
) == (int) FAIL
)
4116 sprintf (append_str
, "li r1 %s", backupstr
);
4117 append_insn (append_str
, TRUE
);
4119 memcpy (&inst
, &inst_backup
, sizeof (struct score_it
));
4120 sprintf (append_str
, " r%d, [r1,0]", reg_rd
);
4121 do_ldst_insn (append_str
);
4127 nopic_need_relax (symbolS
* sym
, int before_relaxing
)
4131 else if (USE_GLOBAL_POINTER_OPT
&& g_switch_value
> 0)
4133 const char *symname
;
4134 const char *segname
;
4136 /* Find out whether this symbol can be referenced off the $gp
4137 register. It can be if it is smaller than the -G size or if
4138 it is in the .sdata or .sbss section. Certain symbols can
4139 not be referenced off the $gp, although it appears as though
4141 symname
= S_GET_NAME (sym
);
4142 if (symname
!= (const char *)NULL
4143 && (strcmp (symname
, "eprol") == 0
4144 || strcmp (symname
, "etext") == 0
4145 || strcmp (symname
, "_gp") == 0
4146 || strcmp (symname
, "edata") == 0
4147 || strcmp (symname
, "_fbss") == 0
4148 || strcmp (symname
, "_fdata") == 0
4149 || strcmp (symname
, "_ftext") == 0
4150 || strcmp (symname
, "end") == 0
4151 || strcmp (symname
, GP_DISP_LABEL
) == 0))
4155 else if ((!S_IS_DEFINED (sym
) || S_IS_COMMON (sym
)) && (0
4156 /* We must defer this decision until after the whole file has been read,
4157 since there might be a .extern after the first use of this symbol. */
4159 && S_GET_VALUE (sym
) == 0)
4160 || (S_GET_VALUE (sym
) != 0
4161 && S_GET_VALUE (sym
) <= g_switch_value
)))
4166 segname
= segment_name (S_GET_SEGMENT (sym
));
4167 return (strcmp (segname
, ".sdata") != 0
4168 && strcmp (segname
, ".sbss") != 0
4169 && strncmp (segname
, ".sdata.", 7) != 0
4170 && strncmp (segname
, ".gnu.linkonce.s.", 16) != 0);
4172 /* We are not optimizing for the $gp register. */
4177 /* Build a relax frag for lw/st instruction when generating PIC,
4178 external symbol first and local symbol second. */
4181 build_lwst_pic (int reg_rd
, expressionS exp
, const char *insn_name
)
4183 symbolS
*add_symbol
= exp
.X_add_symbol
;
4184 int add_number
= exp
.X_add_number
;
4185 struct score_it fix_insts
[RELAX_INST_NUM
];
4186 struct score_it var_insts
[RELAX_INST_NUM
];
4189 char tmp
[MAX_LITERAL_POOL_SIZE
];
4195 if ((add_number
== 0) || (add_number
>= -0x8000 && add_number
<= 0x7fff))
4200 /* For an external symbol, two insns are generated;
4201 For a local symbol, three insns are generated. */
4203 For an external symbol: lw rD, <sym>($gp)
4204 (BFD_RELOC_SCORE_GOT15) */
4205 sprintf (tmp
, "lw_pic r1, %s", add_symbol
->bsym
->name
);
4206 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
4209 memcpy (&fix_insts
[0], &inst
, sizeof (struct score_it
));
4212 For a local symbol :
4213 lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15)
4214 addi rD, <sym> (BFD_RELOC_GOT_LO16) */
4215 inst
.reloc
.type
= BFD_RELOC_SCORE_GOT15
;
4216 memcpy (&var_insts
[0], &inst
, sizeof (struct score_it
));
4217 sprintf (tmp
, "addi_s_pic r1, %s", add_symbol
->bsym
->name
);
4218 if (append_insn (tmp
, FALSE
) == (int) FAIL
)
4221 memcpy (&var_insts
[1], &inst
, sizeof (struct score_it
));
4222 build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
4224 /* Insn 2 or Insn 3: lw/st rD, [r1, constant] */
4225 sprintf (tmp
, "%s r%d, [r1, %d]", insn_name
, reg_rd
, add_number
);
4226 if (append_insn (tmp
, TRUE
) == (int) FAIL
)
4229 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4234 inst
.error
= _("PIC code offset overflow (max 16 signed bits)");
4242 do_macro_ldst_label (char *str
)
4250 char *absolute_value
;
4251 char append_str
[3][MAX_LITERAL_POOL_SIZE
];
4252 char verifystr
[MAX_LITERAL_POOL_SIZE
];
4253 struct score_it inst_backup
;
4254 struct score_it inst_expand
[3];
4255 struct score_it inst_main
;
4257 memcpy (&inst_backup
, &inst
, sizeof (struct score_it
));
4258 strcpy (verifystr
, str
);
4259 backup_str
= verifystr
;
4261 skip_whitespace (backup_str
);
4262 if ((reg_rd
= reg_required_here (&backup_str
, -1, REG_TYPE_SCORE
)) == (int) FAIL
)
4265 if (skip_past_comma (&backup_str
) == (int) FAIL
)
4268 label_str
= backup_str
;
4270 /* Ld/st rD, [rA, imm] ld/st rD, [rA]+, imm ld/st rD, [rA, imm]+. */
4271 if (*backup_str
== '[')
4273 inst
.type
= Rd_rvalueRs_preSI12
;
4278 /* Ld/st rD, imm. */
4279 absolute_value
= backup_str
;
4280 inst
.type
= Rd_rvalueRs_SI15
;
4281 if ((my_get_expression (&inst
.reloc
.exp
, &backup_str
) == (int) FAIL
)
4282 || (validate_immediate (inst
.reloc
.exp
.X_add_number
, _VALUE
, 0) == (int) FAIL
)
4283 || (end_of_line (backup_str
) == (int) FAIL
))
4289 if (inst
.reloc
.exp
.X_add_symbol
== 0)
4291 memcpy (&inst
, &inst_backup
, sizeof (struct score_it
));
4292 exp_macro_ldst_abs (str
);
4297 /* Ld/st rD, label. */
4298 inst
.type
= Rd_rvalueRs_SI15
;
4299 backup_str
= absolute_value
;
4300 if ((data_op2 (&backup_str
, 1, _GP_IMM15
) == (int) FAIL
)
4301 || (end_of_line (backup_str
) == (int) FAIL
))
4307 if (inst
.reloc
.exp
.X_add_symbol
== 0)
4310 inst
.error
= BAD_ARGS
;
4315 if (score_pic
== PIC
)
4318 ldst_idx
= inst
.instruction
& OPC_PSEUDOLDST_MASK
;
4319 build_lwst_pic (reg_rd
, inst
.reloc
.exp
, score_ldst_insns
[ldst_idx
* 3 + 0].template);
4324 if ((inst
.reloc
.exp
.X_add_number
<= 0x3fff)
4325 && (inst
.reloc
.exp
.X_add_number
>= -0x4000)
4326 && (!nopic_need_relax (inst
.reloc
.exp
.X_add_symbol
, 1)))
4330 /* Assign the real opcode. */
4331 ldst_idx
= inst
.instruction
& OPC_PSEUDOLDST_MASK
;
4332 inst
.instruction
&= ~OPC_PSEUDOLDST_MASK
;
4333 inst
.instruction
|= score_ldst_insns
[ldst_idx
* 3 + 0].value
;
4334 inst
.instruction
|= reg_rd
<< 20;
4335 inst
.instruction
|= GP
<< 15;
4336 inst
.relax_inst
= 0x8000;
4337 inst
.relax_size
= 0;
4344 memcpy (&inst_main
, &inst
, sizeof (struct score_it
));
4348 /* Determine which instructions should be output. */
4349 sprintf (append_str
[0], "ld_i32hi r1, %s", label_str
);
4350 sprintf (append_str
[1], "ld_i32lo r1, %s", label_str
);
4351 sprintf (append_str
[2], "%s r%d, [r1, 0]", inst_backup
.name
, reg_rd
);
4353 /* Generate three instructions.
4355 ld/st rd, [r1, 0] */
4356 for (i
= 0; i
< 3; i
++)
4358 if (append_insn (append_str
[i
], FALSE
) == (int) FAIL
)
4361 memcpy (&inst_expand
[i
], &inst
, sizeof (struct score_it
));
4368 /* Adjust instruction opcode and to be relaxed instruction opcode. */
4369 inst_main
.instruction
= adjust_paritybit (inst_main
.instruction
, GET_INSN_CLASS (inst_main
.type
));
4370 inst_main
.relax_size
= inst_expand
[0].size
+ inst_expand
[1].size
+ inst_expand
[2].size
;
4371 inst_main
.type
= Insn_GP
;
4373 for (i
= 0; i
< 3; i
++)
4374 inst_expand
[i
].instruction
= adjust_paritybit (inst_expand
[i
].instruction
4375 , GET_INSN_CLASS (inst_expand
[i
].type
));
4377 /* Check data dependency. */
4378 handle_dependency (&inst_main
);
4380 /* Start a new frag if frag_now is not empty. */
4381 if (frag_now_fix () != 0)
4383 if (!frag_now
->tc_frag_data
.is_insn
)
4384 frag_wane (frag_now
);
4390 /* Write fr_fix part. */
4391 p
= frag_more (inst_main
.size
);
4392 md_number_to_chars (p
, inst_main
.instruction
, inst_main
.size
);
4394 if (inst_main
.reloc
.type
!= BFD_RELOC_NONE
)
4396 fix_new_score (frag_now
, p
- frag_now
->fr_literal
, inst_main
.size
,
4397 &inst_main
.reloc
.exp
, inst_main
.reloc
.pc_rel
, inst_main
.reloc
.type
);
4401 dwarf2_emit_insn (inst_main
.size
);
4404 /* GP instruction can not do optimization, only can do relax between
4405 1 instruction and 3 instructions. */
4406 p
= frag_var (rs_machine_dependent
, inst_main
.relax_size
+ RELAX_PAD_BYTE
, 0,
4407 RELAX_ENCODE (inst_main
.size
, inst_main
.relax_size
, inst_main
.type
, 0, 4, 0),
4408 inst_main
.reloc
.exp
.X_add_symbol
, 0, NULL
);
4410 /* Write fr_var part.
4411 no calling gen_insn_frag, no fixS will be generated. */
4412 md_number_to_chars (p
, inst_expand
[0].instruction
, inst_expand
[0].size
);
4413 p
+= inst_expand
[0].size
;
4414 md_number_to_chars (p
, inst_expand
[1].instruction
, inst_expand
[1].size
);
4415 p
+= inst_expand
[1].size
;
4416 md_number_to_chars (p
, inst_expand
[2].instruction
, inst_expand
[2].size
);
4420 gen_insn_frag (&inst_expand
[0], NULL
);
4421 gen_insn_frag (&inst_expand
[1], NULL
);
4422 gen_insn_frag (&inst_expand
[2], NULL
);
4426 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4431 do_lw_pic (char *str
)
4435 skip_whitespace (str
);
4436 if (((reg_rd
= reg_required_here (&str
, 20, REG_TYPE_SCORE
)) == (int) FAIL
)
4437 || (skip_past_comma (&str
) == (int) FAIL
)
4438 || (my_get_expression (&inst
.reloc
.exp
, &str
) == (int) FAIL
)
4439 || (end_of_line (str
) == (int) FAIL
))
4445 if (inst
.reloc
.exp
.X_add_symbol
== 0)
4448 inst
.error
= BAD_ARGS
;
4453 inst
.instruction
|= GP
<< 15;
4454 inst
.reloc
.type
= BFD_RELOC_SCORE_GOT15
;
4459 do_empty (char *str
)
4462 if (university_version
== 1)
4464 if (((inst
.instruction
& 0x3e0003ff) == 0x0c000004)
4465 || ((inst
.instruction
& 0x3e0003ff) == 0x0c000024)
4466 || ((inst
.instruction
& 0x3e0003ff) == 0x0c000044)
4467 || ((inst
.instruction
& 0x3e0003ff) == 0x0c000064))
4469 inst
.error
= ERR_FOR_SCORE5U_MMU
;
4473 if (end_of_line (str
) == (int) FAIL
)
4476 if (inst
.relax_inst
!= 0x8000)
4478 if (inst
.type
== NO_OPD
)
4480 inst
.relax_size
= 2;
4484 inst
.relax_size
= 4;
4494 skip_whitespace (str
);
4495 if (my_get_expression (&inst
.reloc
.exp
, &str
) == (int) FAIL
4496 || end_of_line (str
) == (int) FAIL
)
4499 if (inst
.reloc
.exp
.X_add_symbol
== 0)
4501 inst
.error
= _("lacking label ");
4505 if (((inst
.reloc
.exp
.X_add_number
& 0xff000000) != 0)
4506 && ((inst
.reloc
.exp
.X_add_number
& 0xff000000) != 0xff000000))
4508 inst
.error
= _("invalid constant: 25 bit expression not in range -2^24..2^24");
4512 save_in
= input_line_pointer
;
4513 input_line_pointer
= str
;
4514 inst
.reloc
.type
= BFD_RELOC_SCORE_JMP
;
4515 inst
.reloc
.pc_rel
= 1;
4516 input_line_pointer
= save_in
;
4520 do16_jump (char *str
)
4522 skip_whitespace (str
);
4523 if (my_get_expression (&inst
.reloc
.exp
, &str
) == (int) FAIL
4524 || end_of_line (str
) == (int) FAIL
)
4528 else if (inst
.reloc
.exp
.X_add_symbol
== 0)
4530 inst
.error
= _("lacking label ");
4533 else if (((inst
.reloc
.exp
.X_add_number
& 0xfffff800) != 0)
4534 && ((inst
.reloc
.exp
.X_add_number
& 0xfffff800) != 0xfffff800))
4536 inst
.error
= _("invalid constant: 12 bit expression not in range -2^11..2^11");
4540 inst
.reloc
.type
= BFD_RELOC_SCORE16_JMP
;
4541 inst
.reloc
.pc_rel
= 1;
4545 do_branch (char *str
)
4547 unsigned long abs_value
= 0;
4549 if (my_get_expression (&inst
.reloc
.exp
, &str
) == (int) FAIL
4550 || end_of_line (str
) == (int) FAIL
)
4554 else if (inst
.reloc
.exp
.X_add_symbol
== 0)
4556 inst
.error
= _("lacking label ");
4559 else if (((inst
.reloc
.exp
.X_add_number
& 0xff000000) != 0)
4560 && ((inst
.reloc
.exp
.X_add_number
& 0xff000000) != 0xff000000))
4562 inst
.error
= _("invalid constant: 20 bit expression not in range -2^19..2^19");
4566 inst
.reloc
.type
= BFD_RELOC_SCORE_BRANCH
;
4567 inst
.reloc
.pc_rel
= 1;
4569 /* Branch 32 offset field : 20 bit, 16 bit branch offset field : 8 bit. */
4570 inst
.instruction
|= (inst
.reloc
.exp
.X_add_number
& 0x3fe) | ((inst
.reloc
.exp
.X_add_number
& 0xffc00) << 5);
4572 /* Compute 16 bit branch instruction. */
4573 if ((inst
.relax_inst
!= 0x8000) && (abs_value
& 0xfffffe00) == 0)
4575 inst
.relax_inst
|= (((inst
.instruction
>> 10) & 0xf) << 8);
4576 inst
.relax_inst
|= ((inst
.reloc
.exp
.X_add_number
>> 1) & 0xff);
4577 inst
.relax_size
= 2;
4581 inst
.relax_inst
= 0x8000;
4586 do16_branch (char *str
)
4588 if ((my_get_expression (&inst
.reloc
.exp
, &str
) == (int) FAIL
4589 || end_of_line (str
) == (int) FAIL
))
4593 else if (inst
.reloc
.exp
.X_add_symbol
== 0)
4595 inst
.error
= _("lacking label");
4597 else if (((inst
.reloc
.exp
.X_add_number
& 0xffffff00) != 0)
4598 && ((inst
.reloc
.exp
.X_add_number
& 0xffffff00) != 0xffffff00))
4600 inst
.error
= _("invalid constant: 9 bit expression not in range -2^8..2^8");
4604 inst
.reloc
.type
= BFD_RELOC_SCORE16_BRANCH
;
4605 inst
.reloc
.pc_rel
= 1;
4606 inst
.instruction
|= ((inst
.reloc
.exp
.X_add_number
>> 1) & 0xff);
4610 /* Iterate over the base tables to create the instruction patterns. */
4612 build_score_ops_hsh (void)
4615 static struct obstack insn_obstack
;
4617 obstack_begin (&insn_obstack
, 4000);
4618 for (i
= 0; i
< sizeof (score_insns
) / sizeof (struct asm_opcode
); i
++)
4620 const struct asm_opcode
*insn
= score_insns
+ i
;
4621 unsigned len
= strlen (insn
->template);
4622 struct asm_opcode
*new;
4624 new = obstack_alloc (&insn_obstack
, sizeof (struct asm_opcode
));
4625 template = obstack_alloc (&insn_obstack
, len
+ 1);
4627 strcpy (template, insn
->template);
4628 new->template = template;
4629 new->parms
= insn
->parms
;
4630 new->value
= insn
->value
;
4631 new->relax_value
= insn
->relax_value
;
4632 new->type
= insn
->type
;
4633 new->bitmask
= insn
->bitmask
;
4634 hash_insert (score_ops_hsh
, new->template, (void *) new);
4639 build_dependency_insn_hsh (void)
4642 static struct obstack dependency_obstack
;
4644 obstack_begin (&dependency_obstack
, 4000);
4645 for (i
= 0; i
< sizeof (insn_to_dependency_table
) / sizeof (insn_to_dependency_table
[0]); i
++)
4647 const struct insn_to_dependency
*tmp
= insn_to_dependency_table
+ i
;
4648 unsigned len
= strlen (tmp
->insn_name
);
4649 struct insn_to_dependency
*new;
4651 new = obstack_alloc (&dependency_obstack
, sizeof (struct insn_to_dependency
));
4652 new->insn_name
= obstack_alloc (&dependency_obstack
, len
+ 1);
4654 strcpy (new->insn_name
, tmp
->insn_name
);
4655 new->type
= tmp
->type
;
4656 hash_insert (dependency_insn_hsh
, new->insn_name
, (void *) new);
4660 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
4661 for use in the a.out file, and stores them in the array pointed to by buf.
4662 This knows about the endian-ness of the target machine and does
4663 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
4664 2 (short) and 4 (long) Floating numbers are put out as a series of
4665 LITTLENUMS (shorts, here at least). */
4668 md_number_to_chars (char *buf
, valueT val
, int n
)
4670 if (target_big_endian
)
4671 number_to_chars_bigendian (buf
, val
, n
);
4673 number_to_chars_littleendian (buf
, val
, n
);
4677 md_chars_to_number (char *buf
, int n
)
4680 unsigned char *where
= (unsigned char *)buf
;
4682 if (target_big_endian
)
4687 result
|= (*where
++ & 255);
4695 result
|= (where
[n
] & 255);
4703 md_atof (int type
, char *litP
, int *sizeP
)
4705 return ieee_md_atof (type
, litP
, sizeP
, target_big_endian
);
4708 /* Return true if the given symbol should be considered local for PIC. */
4711 pic_need_relax (symbolS
*sym
, asection
*segtype
)
4714 bfd_boolean linkonce
;
4716 /* Handle the case of a symbol equated to another symbol. */
4717 while (symbol_equated_reloc_p (sym
))
4721 /* It's possible to get a loop here in a badly written
4723 n
= symbol_get_value_expression (sym
)->X_add_symbol
;
4729 symsec
= S_GET_SEGMENT (sym
);
4731 /* duplicate the test for LINK_ONCE sections as in adjust_reloc_syms */
4733 if (symsec
!= segtype
&& ! S_IS_LOCAL (sym
))
4735 if ((bfd_get_section_flags (stdoutput
, symsec
) & SEC_LINK_ONCE
) != 0)
4738 /* The GNU toolchain uses an extension for ELF: a section
4739 beginning with the magic string .gnu.linkonce is a linkonce
4741 if (strncmp (segment_name (symsec
), ".gnu.linkonce",
4742 sizeof ".gnu.linkonce" - 1) == 0)
4746 /* This must duplicate the test in adjust_reloc_syms. */
4747 return (symsec
!= &bfd_und_section
4748 && symsec
!= &bfd_abs_section
4749 && ! bfd_is_com_section (symsec
)
4752 /* A global or weak symbol is treated as external. */
4753 && (OUTPUT_FLAVOR
!= bfd_target_elf_flavour
4754 || (! S_IS_WEAK (sym
) && ! S_IS_EXTERNAL (sym
)))
4760 judge_size_before_relax (fragS
* fragp
, asection
*sec
)
4764 if (score_pic
== NO_PIC
)
4765 change
= nopic_need_relax (fragp
->fr_symbol
, 0);
4767 change
= pic_need_relax (fragp
->fr_symbol
, sec
);
4771 /* Only at the first time determining whether GP instruction relax should be done,
4772 return the difference between insntruction size and instruction relax size. */
4773 if (fragp
->fr_opcode
== NULL
)
4775 fragp
->fr_fix
= RELAX_NEW (fragp
->fr_subtype
);
4776 fragp
->fr_opcode
= fragp
->fr_literal
+ RELAX_RELOC1 (fragp
->fr_subtype
);
4777 return RELAX_NEW (fragp
->fr_subtype
) - RELAX_OLD (fragp
->fr_subtype
);
4784 /* In this function, we determine whether GP instruction should do relaxation,
4785 for the label being against was known now.
4786 Doing this here but not in md_relax_frag() can induce iteration times
4787 in stage of doing relax. */
4789 md_estimate_size_before_relax (fragS
* fragp
, asection
* sec ATTRIBUTE_UNUSED
)
4791 if ((RELAX_TYPE (fragp
->fr_subtype
) == Insn_GP
)
4792 || (RELAX_TYPE (fragp
->fr_subtype
) == Insn_PIC
))
4793 return judge_size_before_relax (fragp
, sec
);
4799 b32_relax_to_b16 (fragS
* fragp
)
4802 int relaxable_p
= 0;
4805 int frag_addr
= fragp
->fr_address
+ fragp
->insn_addr
;
4807 addressT symbol_address
= 0;
4810 unsigned long value
;
4811 unsigned long abs_value
;
4813 /* FIXME : here may be able to modify better .
4814 I don't know how to get the fragp's section ,
4815 so in relax stage , it may be wrong to calculate the symbol's offset when the frag's section
4816 is different from the symbol's. */
4818 old
= RELAX_OLD (fragp
->fr_subtype
);
4819 new = RELAX_NEW (fragp
->fr_subtype
);
4820 relaxable_p
= RELAX_OPT (fragp
->fr_subtype
);
4822 s
= fragp
->fr_symbol
;
4823 /* b/bl immediate */
4829 symbol_address
= (addressT
) s
->sy_frag
->fr_address
;
4832 value
= md_chars_to_number (fragp
->fr_literal
, INSN_SIZE
);
4834 /* b 32's offset : 20 bit, b 16's tolerate field : 0xff. */
4835 offset
= ((value
& 0x3ff0000) >> 6) | (value
& 0x3fe);
4836 if ((offset
& 0x80000) == 0x80000)
4837 offset
|= 0xfff00000;
4839 abs_value
= offset
+ symbol_address
- frag_addr
;
4840 if ((abs_value
& 0x80000000) == 0x80000000)
4841 abs_value
= 0xffffffff - abs_value
+ 1;
4843 /* Relax branch 32 to branch 16. */
4844 if (relaxable_p
&& (s
->bsym
!= NULL
) && ((abs_value
& 0xffffff00) == 0)
4845 && (S_IS_DEFINED (s
) && !S_IS_COMMON (s
) && !S_IS_EXTERNAL (s
)))
4851 /* Branch 32 can not be relaxed to b 16, so clear OPT bit. */
4852 fragp
->fr_opcode
= NULL
;
4853 fragp
->fr_subtype
= RELAX_OPT_CLEAR (fragp
->fr_subtype
);
4859 /* Main purpose is to determine whether one frag should do relax.
4860 frag->fr_opcode indicates this point. */
4863 score_relax_frag (asection
* sec ATTRIBUTE_UNUSED
, fragS
* fragp
, long stretch ATTRIBUTE_UNUSED
)
4867 int insn_relax_size
;
4868 int do_relax_p
= 0; /* Indicate doing relaxation for this frag. */
4869 int relaxable_p
= 0;
4870 bfd_boolean word_align_p
= FALSE
;
4873 /* If the instruction address is odd, make it half word align first. */
4874 if ((fragp
->fr_address
) % 2 != 0)
4876 if ((fragp
->fr_address
+ fragp
->insn_addr
) % 2 != 0)
4878 fragp
->insn_addr
= 1;
4883 word_align_p
= ((fragp
->fr_address
+ fragp
->insn_addr
) % 4 == 0) ? TRUE
: FALSE
;
4885 /* Get instruction size and relax size after the last relaxation. */
4886 if (fragp
->fr_opcode
)
4888 insn_size
= RELAX_NEW (fragp
->fr_subtype
);
4889 insn_relax_size
= RELAX_OLD (fragp
->fr_subtype
);
4893 insn_size
= RELAX_OLD (fragp
->fr_subtype
);
4894 insn_relax_size
= RELAX_NEW (fragp
->fr_subtype
);
4897 /* Handle specially for GP instruction. for, judge_size_before_relax() has already determine
4898 whether the GP instruction should do relax. */
4899 if ((RELAX_TYPE (fragp
->fr_subtype
) == Insn_GP
)
4900 || (RELAX_TYPE (fragp
->fr_subtype
) == Insn_PIC
))
4904 if (fragp
->insn_addr
< 2)
4906 fragp
->insn_addr
+= 2;
4911 fragp
->insn_addr
-= 2;
4916 if (fragp
->fr_opcode
)
4917 fragp
->fr_fix
= RELAX_NEW (fragp
->fr_subtype
) + fragp
->insn_addr
;
4919 fragp
->fr_fix
= RELAX_OLD (fragp
->fr_subtype
) + fragp
->insn_addr
;
4923 if (RELAX_TYPE (fragp
->fr_subtype
) == PC_DISP19div2
)
4924 b32_relax_to_b16 (fragp
);
4926 relaxable_p
= RELAX_OPT (fragp
->fr_subtype
);
4927 next_fragp
= fragp
->fr_next
;
4928 while ((next_fragp
) && (next_fragp
->fr_type
!= rs_machine_dependent
))
4930 next_fragp
= next_fragp
->fr_next
;
4936 int n_relaxable_p
= 0;
4938 if (next_fragp
->fr_opcode
)
4940 n_insn_size
= RELAX_NEW (next_fragp
->fr_subtype
);
4944 n_insn_size
= RELAX_OLD (next_fragp
->fr_subtype
);
4947 if (RELAX_TYPE (next_fragp
->fr_subtype
) == PC_DISP19div2
)
4948 b32_relax_to_b16 (next_fragp
);
4949 n_relaxable_p
= RELAX_OPT (next_fragp
->fr_subtype
);
4956 if (relaxable_p
&& ((n_insn_size
== 2) || n_relaxable_p
))
4962 else if (insn_size
== 2)
4965 if (relaxable_p
&& (((n_insn_size
== 4) && !n_relaxable_p
) || (n_insn_size
> 4)))
4986 /* Make the 32 bit insturction word align. */
4989 fragp
->insn_addr
+= 2;
4993 else if (insn_size
== 2)
5005 /* Here, try best to do relax regardless fragp->fr_next->fr_type. */
5006 if (word_align_p
== FALSE
)
5008 if (insn_size
% 4 == 0)
5018 fragp
->insn_addr
+= 2;
5029 /* fragp->fr_opcode indicates whether this frag should be relaxed. */
5032 if (fragp
->fr_opcode
)
5034 fragp
->fr_opcode
= NULL
;
5035 /* Guarantee estimate stage is correct. */
5036 fragp
->fr_fix
= RELAX_OLD (fragp
->fr_subtype
);
5037 fragp
->fr_fix
+= fragp
->insn_addr
;
5041 fragp
->fr_opcode
= fragp
->fr_literal
+ RELAX_RELOC1 (fragp
->fr_subtype
);
5042 /* Guarantee estimate stage is correct. */
5043 fragp
->fr_fix
= RELAX_NEW (fragp
->fr_subtype
);
5044 fragp
->fr_fix
+= fragp
->insn_addr
;
5049 if (fragp
->fr_opcode
)
5051 /* Guarantee estimate stage is correct. */
5052 fragp
->fr_fix
= RELAX_NEW (fragp
->fr_subtype
);
5053 fragp
->fr_fix
+= fragp
->insn_addr
;
5057 /* Guarantee estimate stage is correct. */
5058 fragp
->fr_fix
= RELAX_OLD (fragp
->fr_subtype
);
5059 fragp
->fr_fix
+= fragp
->insn_addr
;
5068 md_convert_frag (bfd
* abfd ATTRIBUTE_UNUSED
, segT sec ATTRIBUTE_UNUSED
, fragS
* fragp
)
5075 old
= RELAX_OLD (fragp
->fr_subtype
);
5076 new = RELAX_NEW (fragp
->fr_subtype
);
5078 /* fragp->fr_opcode indicates whether this frag should be relaxed. */
5079 if (fragp
->fr_opcode
== NULL
)
5081 memcpy (backup
, fragp
->fr_literal
, old
);
5082 fragp
->fr_fix
= old
;
5086 memcpy (backup
, fragp
->fr_literal
+ old
, new);
5087 fragp
->fr_fix
= new;
5090 fixp
= fragp
->tc_frag_data
.fixp
;
5091 while (fixp
&& fixp
->fx_frag
== fragp
&& fixp
->fx_where
< old
)
5093 if (fragp
->fr_opcode
)
5095 fixp
= fixp
->fx_next
;
5097 while (fixp
&& fixp
->fx_frag
== fragp
)
5099 if (fragp
->fr_opcode
)
5100 fixp
->fx_where
-= old
+ fragp
->insn_addr
;
5103 fixp
= fixp
->fx_next
;
5106 if (fragp
->insn_addr
)
5108 md_number_to_chars (fragp
->fr_literal
, 0x0, fragp
->insn_addr
);
5110 memcpy (fragp
->fr_literal
+ fragp
->insn_addr
, backup
, fragp
->fr_fix
);
5111 fragp
->fr_fix
+= fragp
->insn_addr
;
5114 /* Implementation of md_frag_check.
5115 Called after md_convert_frag(). */
5118 score_frag_check (fragS
* fragp ATTRIBUTE_UNUSED
)
5120 know (fragp
->insn_addr
<= RELAX_PAD_BYTE
);
5124 score_fix_adjustable (fixS
* fixP
)
5126 if (fixP
->fx_addsy
== NULL
)
5130 else if (OUTPUT_FLAVOR
== bfd_target_elf_flavour
5131 && (S_IS_EXTERNAL (fixP
->fx_addsy
) || S_IS_WEAK (fixP
->fx_addsy
)))
5135 else if (fixP
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
5136 || fixP
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
5144 /* Implementation of TC_VALIDATE_FIX.
5145 Called before md_apply_fix() and after md_convert_frag(). */
5147 score_validate_fix (fixS
*fixP
)
5149 fixP
->fx_where
+= fixP
->fx_frag
->insn_addr
;
5153 md_pcrel_from (fixS
* fixP
)
5158 && (S_GET_SEGMENT (fixP
->fx_addsy
) == undefined_section
)
5159 && (fixP
->fx_subsy
== NULL
))
5165 retval
= fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
5172 score_force_relocation (struct fix
*fixp
)
5176 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
5177 || fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
5178 || fixp
->fx_r_type
== BFD_RELOC_SCORE_JMP
5179 || fixp
->fx_r_type
== BFD_RELOC_SCORE_BRANCH
5180 || fixp
->fx_r_type
== BFD_RELOC_SCORE16_JMP
5181 || fixp
->fx_r_type
== BFD_RELOC_SCORE16_BRANCH
)
5189 /* Round up a section size to the appropriate boundary. */
5191 md_section_align (segT segment ATTRIBUTE_UNUSED
, valueT size
)
5193 int align
= bfd_get_section_alignment (stdoutput
, segment
);
5195 return ((size
+ (1 << align
) - 1) & (-1 << align
));
5199 md_apply_fix (fixS
*fixP
, valueT
*valP
, segT seg
)
5201 offsetT value
= *valP
;
5202 offsetT abs_value
= 0;
5205 unsigned short HI
, LO
;
5207 char *buf
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
5209 assert (fixP
->fx_r_type
< BFD_RELOC_UNUSED
);
5210 if (fixP
->fx_addsy
== 0 && !fixP
->fx_pcrel
)
5212 if (fixP
->fx_r_type
!= BFD_RELOC_SCORE_DUMMY_HI16
)
5216 /* If this symbol is in a different section then we need to leave it for
5217 the linker to deal with. Unfortunately, md_pcrel_from can't tell,
5218 so we have to undo it's effects here. */
5221 if (fixP
->fx_addsy
!= NULL
5222 && S_IS_DEFINED (fixP
->fx_addsy
)
5223 && S_GET_SEGMENT (fixP
->fx_addsy
) != seg
)
5224 value
+= md_pcrel_from (fixP
);
5227 /* Remember value for emit_reloc. */
5228 fixP
->fx_addnumber
= value
;
5230 switch (fixP
->fx_r_type
)
5232 case BFD_RELOC_HI16_S
:
5234 { /* For la rd, imm32. */
5235 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5236 HI
= (value
) >> 16; /* mul to 2, then take the hi 16 bit. */
5237 newval
|= (HI
& 0x3fff) << 1;
5238 newval
|= ((HI
>> 14) & 0x3) << 16;
5239 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5242 case BFD_RELOC_LO16
:
5243 if (fixP
->fx_done
) /* For la rd, imm32. */
5245 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5246 LO
= (value
) & 0xffff;
5247 newval
|= (LO
& 0x3fff) << 1; /* 16 bit: imm -> 14 bit in lo, 2 bit in hi. */
5248 newval
|= ((LO
>> 14) & 0x3) << 16;
5249 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5252 case BFD_RELOC_SCORE_JMP
:
5254 content
= md_chars_to_number (buf
, INSN_SIZE
);
5255 value
= fixP
->fx_offset
;
5256 content
= (content
& ~0x3ff7ffe) | ((value
<< 1) & 0x3ff0000) | (value
& 0x7fff);
5257 md_number_to_chars (buf
, content
, INSN_SIZE
);
5260 case BFD_RELOC_SCORE_BRANCH
:
5261 if ((S_GET_SEGMENT (fixP
->fx_addsy
) != seg
) || (fixP
->fx_addsy
!= NULL
&& S_IS_EXTERNAL (fixP
->fx_addsy
)))
5262 value
= fixP
->fx_offset
;
5266 content
= md_chars_to_number (buf
, INSN_SIZE
);
5267 if ((fixP
->fx_frag
->fr_opcode
!= 0) && ((content
& 0x80008000) != 0x80008000))
5269 if ((value
& 0x80000000) == 0x80000000)
5270 abs_value
= 0xffffffff - value
+ 1;
5271 if ((abs_value
& 0xffffff00) != 0)
5273 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5274 _(" branch relocation truncate (0x%x) [-2^8 ~ 2^8]"), (unsigned int)value
);
5277 content
= md_chars_to_number (buf
, INSN16_SIZE
);
5279 content
= (content
& 0xff00) | ((value
>> 1) & 0xff);
5280 md_number_to_chars (buf
, content
, INSN16_SIZE
);
5281 fixP
->fx_r_type
= BFD_RELOC_SCORE16_BRANCH
;
5286 if ((value
& 0x80000000) == 0x80000000)
5287 abs_value
= 0xffffffff - value
+ 1;
5288 if ((abs_value
& 0xfff80000) != 0)
5290 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5291 _(" branch relocation truncate (0x%x) [-2^19 ~ 2^19]"), (unsigned int)value
);
5294 content
= md_chars_to_number (buf
, INSN_SIZE
);
5295 content
&= 0xfc00fc01;
5296 content
= (content
& 0xfc00fc01) | (value
& 0x3fe) | ((value
<< 6) & 0x3ff0000);
5297 md_number_to_chars (buf
, content
, INSN_SIZE
);
5300 case BFD_RELOC_SCORE16_JMP
:
5301 content
= md_chars_to_number (buf
, INSN16_SIZE
);
5303 value
= fixP
->fx_offset
& 0xfff;
5304 content
= (content
& 0xfc01) | (value
& 0xffe);
5305 md_number_to_chars (buf
, content
, INSN16_SIZE
);
5307 case BFD_RELOC_SCORE16_BRANCH
:
5308 content
= md_chars_to_number (buf
, INSN_SIZE
);
5309 if ((fixP
->fx_frag
->fr_opcode
!= 0) && ((content
& 0x80008000) == 0x80008000))
5311 if ((S_GET_SEGMENT (fixP
->fx_addsy
) != seg
) ||
5312 (fixP
->fx_addsy
!= NULL
&& S_IS_EXTERNAL (fixP
->fx_addsy
)))
5313 value
= fixP
->fx_offset
;
5316 if ((value
& 0x80000000) == 0x80000000)
5317 abs_value
= 0xffffffff - value
+ 1;
5318 if ((abs_value
& 0xfff80000) != 0)
5320 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5321 _(" branch relocation truncate (0x%x) [-2^19 ~ 2^19]"), (unsigned int)value
);
5324 content
= md_chars_to_number (buf
, INSN_SIZE
);
5325 content
= (content
& 0xfc00fc01) | (value
& 0x3fe) | ((value
<< 6) & 0x3ff0000);
5326 md_number_to_chars (buf
, content
, INSN_SIZE
);
5327 fixP
->fx_r_type
= BFD_RELOC_SCORE_BRANCH
;
5333 /* In differnt section. */
5334 if ((S_GET_SEGMENT (fixP
->fx_addsy
) != seg
) ||
5335 (fixP
->fx_addsy
!= NULL
&& S_IS_EXTERNAL (fixP
->fx_addsy
)))
5336 value
= fixP
->fx_offset
;
5340 if ((value
& 0x80000000) == 0x80000000)
5341 abs_value
= 0xffffffff - value
+ 1;
5342 if ((abs_value
& 0xffffff00) != 0)
5344 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5345 _(" branch relocation truncate (0x%x) [-2^8 ~ 2^8]"), (unsigned int)value
);
5348 content
= md_chars_to_number (buf
, INSN16_SIZE
);
5349 content
= (content
& 0xff00) | ((value
>> 1) & 0xff);
5350 md_number_to_chars (buf
, content
, INSN16_SIZE
);
5354 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5355 md_number_to_chars (buf
, value
, 1);
5359 value
= fixP
->fx_offset
;
5360 md_number_to_chars (buf
, value
, 1);
5366 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5367 md_number_to_chars (buf
, value
, 2);
5371 value
= fixP
->fx_offset
;
5372 md_number_to_chars (buf
, value
, 2);
5378 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5379 md_number_to_chars (buf
, value
, 4);
5383 value
= fixP
->fx_offset
;
5384 md_number_to_chars (buf
, value
, 4);
5388 case BFD_RELOC_VTABLE_INHERIT
:
5390 if (fixP
->fx_addsy
&& !S_IS_DEFINED (fixP
->fx_addsy
) && !S_IS_WEAK (fixP
->fx_addsy
))
5391 S_SET_WEAK (fixP
->fx_addsy
);
5393 case BFD_RELOC_VTABLE_ENTRY
:
5396 case BFD_RELOC_SCORE_GPREL15
:
5397 content
= md_chars_to_number (buf
, INSN_SIZE
);
5398 if ((fixP
->fx_frag
->fr_opcode
!= 0) && ((content
& 0xfc1c8000) != 0x94188000))
5399 fixP
->fx_r_type
= BFD_RELOC_NONE
;
5402 case BFD_RELOC_SCORE_GOT15
:
5403 case BFD_RELOC_SCORE_DUMMY_HI16
:
5404 case BFD_RELOC_SCORE_GOT_LO16
:
5405 case BFD_RELOC_SCORE_CALL15
:
5406 case BFD_RELOC_GPREL32
:
5408 case BFD_RELOC_NONE
:
5410 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("bad relocation fixup type (%d)"), fixP
->fx_r_type
);
5414 /* Translate internal representation of relocation info to BFD target format. */
5416 tc_gen_reloc (asection
* section ATTRIBUTE_UNUSED
, fixS
* fixp
)
5418 static arelent
*retval
[MAX_RELOC_EXPANSION
+ 1]; /* MAX_RELOC_EXPANSION equals 2. */
5420 bfd_reloc_code_real_type code
;
5426 reloc
= retval
[0] = xmalloc (sizeof (arelent
));
5429 reloc
->sym_ptr_ptr
= xmalloc (sizeof (asymbol
*));
5430 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
5431 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
5432 reloc
->addend
= fixp
->fx_offset
;
5434 /* If this is a variant frag, we may need to adjust the existing
5435 reloc and generate a new one. */
5436 if (fixp
->fx_frag
->fr_opcode
!= NULL
&& (fixp
->fx_r_type
== BFD_RELOC_SCORE_GPREL15
))
5438 /* Update instruction imm bit. */
5443 buf
= fixp
->fx_frag
->fr_literal
+ fixp
->fx_frag
->insn_addr
;
5444 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5445 off
= fixp
->fx_offset
>> 16;
5446 newval
|= (off
& 0x3fff) << 1;
5447 newval
|= ((off
>> 14) & 0x3) << 16;
5448 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5451 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5452 off
= fixp
->fx_offset
& 0xffff;
5453 newval
|= ((off
& 0x3fff) << 1);
5454 newval
|= (((off
>> 14) & 0x3) << 16);
5455 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5457 retval
[1] = xmalloc (sizeof (arelent
));
5459 retval
[1]->sym_ptr_ptr
= xmalloc (sizeof (asymbol
*));
5460 *retval
[1]->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
5461 retval
[1]->address
= (reloc
->address
+ RELAX_RELOC2 (fixp
->fx_frag
->fr_subtype
));
5467 retval
[1]->addend
= 0;
5468 retval
[1]->howto
= bfd_reloc_type_lookup (stdoutput
, BFD_RELOC_LO16
);
5469 assert (retval
[1]->howto
!= NULL
);
5471 fixp
->fx_r_type
= BFD_RELOC_HI16_S
;
5474 code
= fixp
->fx_r_type
;
5475 switch (fixp
->fx_r_type
)
5480 code
= BFD_RELOC_32_PCREL
;
5483 case BFD_RELOC_HI16_S
:
5484 case BFD_RELOC_LO16
:
5485 case BFD_RELOC_SCORE_JMP
:
5486 case BFD_RELOC_SCORE_BRANCH
:
5487 case BFD_RELOC_SCORE16_JMP
:
5488 case BFD_RELOC_SCORE16_BRANCH
:
5489 case BFD_RELOC_VTABLE_ENTRY
:
5490 case BFD_RELOC_VTABLE_INHERIT
:
5491 case BFD_RELOC_SCORE_GPREL15
:
5492 case BFD_RELOC_SCORE_GOT15
:
5493 case BFD_RELOC_SCORE_DUMMY_HI16
:
5494 case BFD_RELOC_SCORE_GOT_LO16
:
5495 case BFD_RELOC_SCORE_CALL15
:
5496 case BFD_RELOC_GPREL32
:
5497 case BFD_RELOC_NONE
:
5498 code
= fixp
->fx_r_type
;
5501 type
= _("<unknown>");
5502 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5503 _("cannot represent %s relocation in this object file format"), type
);
5507 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
5508 if (reloc
->howto
== NULL
)
5510 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5511 _("cannot represent %s relocation in this object file format1"),
5512 bfd_get_reloc_code_name (code
));
5515 /* HACK: Since arm ELF uses Rel instead of Rela, encode the
5516 vtable entry to be used in the relocation's section offset. */
5517 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
5518 reloc
->address
= fixp
->fx_offset
;
5524 score_elf_final_processing (void)
5526 if (fix_data_dependency
== 1)
5528 elf_elfheader (stdoutput
)->e_flags
|= EF_SCORE_FIXDEP
;
5530 if (score_pic
== PIC
)
5532 elf_elfheader (stdoutput
)->e_flags
|= EF_SCORE_PIC
;
5537 parse_pce_inst (char *insnstr
)
5541 char first
[MAX_LITERAL_POOL_SIZE
];
5542 char second
[MAX_LITERAL_POOL_SIZE
];
5543 struct score_it pec_part_1
;
5545 /* Get first part string of PCE. */
5546 p
= strstr (insnstr
, "||");
5549 sprintf (first
, "%s", insnstr
);
5551 /* Get second part string of PCE. */
5554 sprintf (second
, "%s", p
);
5556 parse_16_32_inst (first
, FALSE
);
5560 memcpy (&pec_part_1
, &inst
, sizeof (inst
));
5562 parse_16_32_inst (second
, FALSE
);
5566 if ( ((pec_part_1
.size
== INSN_SIZE
) && (inst
.size
== INSN_SIZE
))
5567 || ((pec_part_1
.size
== INSN_SIZE
) && (inst
.size
== INSN16_SIZE
))
5568 || ((pec_part_1
.size
== INSN16_SIZE
) && (inst
.size
== INSN_SIZE
)))
5570 inst
.error
= _("pce instruction error (16 bit || 16 bit)'");
5571 sprintf (inst
.str
, insnstr
);
5576 gen_insn_frag (&pec_part_1
, &inst
);
5580 md_assemble (char *str
)
5583 know (strlen (str
) < MAX_LITERAL_POOL_SIZE
);
5585 memset (&inst
, '\0', sizeof (inst
));
5586 if (INSN_IS_PCE_P (str
))
5587 parse_pce_inst (str
);
5589 parse_16_32_inst (str
, TRUE
);
5592 as_bad (_("%s -- `%s'"), inst
.error
, inst
.str
);
5595 /* We handle all bad expressions here, so that we can report the faulty
5596 instruction in the error message. */
5598 md_operand (expressionS
* expr
)
5600 if (in_my_get_expression
)
5602 expr
->X_op
= O_illegal
;
5603 if (inst
.error
== NULL
)
5605 inst
.error
= _("bad expression");
5610 const char *md_shortopts
= "nO::g::G:";
5612 #ifdef SCORE_BI_ENDIAN
5613 #define OPTION_EB (OPTION_MD_BASE + 0)
5614 #define OPTION_EL (OPTION_MD_BASE + 1)
5616 #if TARGET_BYTES_BIG_ENDIAN
5617 #define OPTION_EB (OPTION_MD_BASE + 0)
5619 #define OPTION_EL (OPTION_MD_BASE + 1)
5622 #define OPTION_FIXDD (OPTION_MD_BASE + 2)
5623 #define OPTION_NWARN (OPTION_MD_BASE + 3)
5624 #define OPTION_SCORE5 (OPTION_MD_BASE + 4)
5625 #define OPTION_SCORE5U (OPTION_MD_BASE + 5)
5626 #define OPTION_SCORE7 (OPTION_MD_BASE + 6)
5627 #define OPTION_R1 (OPTION_MD_BASE + 7)
5628 #define OPTION_O0 (OPTION_MD_BASE + 8)
5629 #define OPTION_SCORE_VERSION (OPTION_MD_BASE + 9)
5630 #define OPTION_PIC (OPTION_MD_BASE + 10)
5632 struct option md_longopts
[] =
5635 {"EB" , no_argument
, NULL
, OPTION_EB
},
5638 {"EL" , no_argument
, NULL
, OPTION_EL
},
5640 {"FIXDD" , no_argument
, NULL
, OPTION_FIXDD
},
5641 {"NWARN" , no_argument
, NULL
, OPTION_NWARN
},
5642 {"SCORE5" , no_argument
, NULL
, OPTION_SCORE5
},
5643 {"SCORE5U", no_argument
, NULL
, OPTION_SCORE5U
},
5644 {"SCORE7" , no_argument
, NULL
, OPTION_SCORE7
},
5645 {"USE_R1" , no_argument
, NULL
, OPTION_R1
},
5646 {"O0" , no_argument
, NULL
, OPTION_O0
},
5647 {"V" , no_argument
, NULL
, OPTION_SCORE_VERSION
},
5648 {"KPIC" , no_argument
, NULL
, OPTION_PIC
},
5649 {NULL
, no_argument
, NULL
, 0}
5652 size_t md_longopts_size
= sizeof (md_longopts
);
5655 md_parse_option (int c
, char *arg
)
5661 target_big_endian
= 1;
5666 target_big_endian
= 0;
5670 fix_data_dependency
= 1;
5673 warn_fix_data_dependency
= 0;
5677 university_version
= 0;
5678 vector_size
= SCORE5_PIPELINE
;
5680 case OPTION_SCORE5U
:
5682 university_version
= 1;
5683 vector_size
= SCORE5_PIPELINE
;
5687 university_version
= 0;
5688 vector_size
= SCORE7_PIPELINE
;
5694 g_switch_value
= atoi (arg
);
5699 case OPTION_SCORE_VERSION
:
5700 printf (_("Sunplus-v2-0-0-20060510\n"));
5704 g_switch_value
= 0; /* Must set -G num as 0 to generate PIC code. */
5707 /* as_bad (_("unrecognized option `-%c%s'"), c, arg ? arg : ""); */
5714 md_show_usage (FILE * fp
)
5716 fprintf (fp
, _(" Score-specific assembler options:\n"));
5719 -EB\t\tassemble code for a big-endian cpu\n"));
5724 -EL\t\tassemble code for a little-endian cpu\n"));
5728 -FIXDD\t\tassemble code for fix data dependency\n"));
5730 -NWARN\t\tassemble code for no warning message for fix data dependency\n"));
5732 -SCORE5\t\tassemble code for target is SCORE5\n"));
5734 -SCORE5U\tassemble code for target is SCORE5U\n"));
5736 -SCORE7\t\tassemble code for target is SCORE7, this is default setting\n"));
5738 -USE_R1\t\tassemble code for no warning message when using temp register r1\n"));
5740 -KPIC\t\tassemble code for PIC\n"));
5742 -O0\t\tassembler will not perform any optimizations\n"));
5744 -G gpnum\tassemble code for setting gpsize and default is 8 byte\n"));
5746 -V \t\tSunplus release version \n"));
5750 /* Pesudo handling functions. */
5752 /* If we change section we must dump the literal pool first. */
5754 s_score_bss (int ignore ATTRIBUTE_UNUSED
)
5756 subseg_set (bss_section
, (subsegT
) get_absolute_expression ());
5757 demand_empty_rest_of_line ();
5761 s_score_text (int ignore
)
5763 obj_elf_text (ignore
);
5764 record_alignment (now_seg
, 2);
5768 score_s_section (int ignore
)
5770 obj_elf_section (ignore
);
5771 if ((bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
) != 0)
5772 record_alignment (now_seg
, 2);
5777 s_change_sec (int sec
)
5782 /* The ELF backend needs to know that we are changing sections, so
5783 that .previous works correctly. We could do something like check
5784 for an obj_section_change_hook macro, but that might be confusing
5785 as it would not be appropriate to use it in the section changing
5786 functions in read.c, since obj-elf.c intercepts those. FIXME:
5787 This should be cleaner, somehow. */
5788 obj_elf_section_change_hook ();
5793 seg
= subseg_new (RDATA_SECTION_NAME
, (subsegT
) get_absolute_expression ());
5794 bfd_set_section_flags (stdoutput
, seg
, (SEC_ALLOC
| SEC_LOAD
| SEC_READONLY
| SEC_RELOC
| SEC_DATA
));
5795 if (strcmp (TARGET_OS
, "elf") != 0)
5796 record_alignment (seg
, 4);
5797 demand_empty_rest_of_line ();
5800 seg
= subseg_new (".sdata", (subsegT
) get_absolute_expression ());
5801 bfd_set_section_flags (stdoutput
, seg
, SEC_ALLOC
| SEC_LOAD
| SEC_RELOC
| SEC_DATA
);
5802 if (strcmp (TARGET_OS
, "elf") != 0)
5803 record_alignment (seg
, 4);
5804 demand_empty_rest_of_line ();
5810 s_score_mask (int reg_type ATTRIBUTE_UNUSED
)
5814 if (cur_proc_ptr
== (procS
*) NULL
)
5816 as_warn (_(".mask outside of .ent"));
5817 demand_empty_rest_of_line ();
5820 if (get_absolute_expression_and_terminator (&mask
) != ',')
5822 as_warn (_("Bad .mask directive"));
5823 --input_line_pointer
;
5824 demand_empty_rest_of_line ();
5827 off
= get_absolute_expression ();
5828 cur_proc_ptr
->reg_mask
= mask
;
5829 cur_proc_ptr
->reg_offset
= off
;
5830 demand_empty_rest_of_line ();
5840 name
= input_line_pointer
;
5841 c
= get_symbol_end ();
5842 p
= (symbolS
*) symbol_find_or_make (name
);
5843 *input_line_pointer
= c
;
5853 if (*input_line_pointer
== '-')
5855 ++input_line_pointer
;
5858 if (!ISDIGIT (*input_line_pointer
))
5859 as_bad (_("expected simple number"));
5860 if (input_line_pointer
[0] == '0')
5862 if (input_line_pointer
[1] == 'x')
5864 input_line_pointer
+= 2;
5865 while (ISXDIGIT (*input_line_pointer
))
5868 val
|= hex_value (*input_line_pointer
++);
5870 return negative
? -val
: val
;
5874 ++input_line_pointer
;
5875 while (ISDIGIT (*input_line_pointer
))
5878 val
|= *input_line_pointer
++ - '0';
5880 return negative
? -val
: val
;
5883 if (!ISDIGIT (*input_line_pointer
))
5885 printf (_(" *input_line_pointer == '%c' 0x%02x\n"), *input_line_pointer
, *input_line_pointer
);
5886 as_warn (_("invalid number"));
5889 while (ISDIGIT (*input_line_pointer
))
5892 val
+= *input_line_pointer
++ - '0';
5894 return negative
? -val
: val
;
5897 /* The .aent and .ent directives. */
5900 s_score_ent (int aent
)
5905 symbolP
= get_symbol ();
5906 if (*input_line_pointer
== ',')
5907 ++input_line_pointer
;
5909 if (ISDIGIT (*input_line_pointer
) || *input_line_pointer
== '-')
5912 #ifdef BFD_ASSEMBLER
5913 if ((bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
) != 0)
5918 if (now_seg
!= data_section
&& now_seg
!= bss_section
)
5924 as_warn (_(".ent or .aent not in text section."));
5925 if (!aent
&& cur_proc_ptr
)
5926 as_warn (_("missing .end"));
5929 cur_proc_ptr
= &cur_proc
;
5930 cur_proc_ptr
->reg_mask
= 0xdeadbeaf;
5931 cur_proc_ptr
->reg_offset
= 0xdeadbeaf;
5932 cur_proc_ptr
->fpreg_mask
= 0xdeafbeaf;
5933 cur_proc_ptr
->leaf
= 0xdeafbeaf;
5934 cur_proc_ptr
->frame_offset
= 0xdeafbeaf;
5935 cur_proc_ptr
->frame_reg
= 0xdeafbeaf;
5936 cur_proc_ptr
->pc_reg
= 0xdeafbeaf;
5937 cur_proc_ptr
->isym
= symbolP
;
5938 symbol_get_bfdsym (symbolP
)->flags
|= BSF_FUNCTION
;
5940 if (debug_type
== DEBUG_STABS
)
5941 stabs_generate_asm_func (S_GET_NAME (symbolP
), S_GET_NAME (symbolP
));
5943 demand_empty_rest_of_line ();
5947 s_score_frame (int ignore ATTRIBUTE_UNUSED
)
5954 backupstr
= input_line_pointer
;
5957 if (cur_proc_ptr
== (procS
*) NULL
)
5959 as_warn (_(".frame outside of .ent"));
5960 demand_empty_rest_of_line ();
5963 cur_proc_ptr
->frame_reg
= reg_required_here ((&backupstr
), 0, REG_TYPE_SCORE
);
5965 skip_past_comma (&backupstr
);
5966 while (*backupstr
!= ',')
5968 str
[i
] = *backupstr
;
5976 skip_past_comma (&backupstr
);
5977 cur_proc_ptr
->frame_offset
= val
;
5978 cur_proc_ptr
->pc_reg
= reg_required_here ((&backupstr
), 0, REG_TYPE_SCORE
);
5981 skip_past_comma (&backupstr
);
5983 while (*backupstr
!= '\n')
5985 str
[i
] = *backupstr
;
5991 cur_proc_ptr
->leaf
= val
;
5993 skip_past_comma (&backupstr
);
5995 #endif /* OBJ_ELF */
5996 while (input_line_pointer
!= backupstr
)
5997 input_line_pointer
++;
6000 /* The .end directive. */
6002 s_score_end (int x ATTRIBUTE_UNUSED
)
6007 /* Generate a .pdr section. */
6008 segT saved_seg
= now_seg
;
6009 subsegT saved_subseg
= now_subseg
;
6014 if (!is_end_of_line
[(unsigned char)*input_line_pointer
])
6017 demand_empty_rest_of_line ();
6022 #ifdef BFD_ASSEMBLER
6023 if ((bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
) != 0)
6028 if (now_seg
!= data_section
&& now_seg
!= bss_section
)
6035 as_warn (_(".end not in text section"));
6038 as_warn (_(".end directive without a preceding .ent directive."));
6039 demand_empty_rest_of_line ();
6044 assert (S_GET_NAME (p
));
6045 if (strcmp (S_GET_NAME (p
), S_GET_NAME (cur_proc_ptr
->isym
)))
6046 as_warn (_(".end symbol does not match .ent symbol."));
6047 if (debug_type
== DEBUG_STABS
)
6048 stabs_generate_asm_endfunc (S_GET_NAME (p
), S_GET_NAME (p
));
6051 as_warn (_(".end directive missing or unknown symbol"));
6053 if ((cur_proc_ptr
->reg_mask
== 0xdeadbeaf) ||
6054 (cur_proc_ptr
->reg_offset
== 0xdeadbeaf) ||
6055 (cur_proc_ptr
->leaf
== 0xdeafbeaf) ||
6056 (cur_proc_ptr
->frame_offset
== 0xdeafbeaf) ||
6057 (cur_proc_ptr
->frame_reg
== 0xdeafbeaf) || (cur_proc_ptr
->pc_reg
== 0xdeafbeaf));
6061 dot
= frag_now_fix ();
6063 subseg_set (pdr_seg
, 0);
6064 /* Write the symbol. */
6065 exp
.X_op
= O_symbol
;
6066 exp
.X_add_symbol
= p
;
6067 exp
.X_add_number
= 0;
6068 emit_expr (&exp
, 4);
6069 fragp
= frag_more (7 * 4);
6070 md_number_to_chars (fragp
, (valueT
) cur_proc_ptr
->reg_mask
, 4);
6071 md_number_to_chars (fragp
+ 4, (valueT
) cur_proc_ptr
->reg_offset
, 4);
6072 md_number_to_chars (fragp
+ 8, (valueT
) cur_proc_ptr
->fpreg_mask
, 4);
6073 md_number_to_chars (fragp
+ 12, (valueT
) cur_proc_ptr
->leaf
, 4);
6074 md_number_to_chars (fragp
+ 16, (valueT
) cur_proc_ptr
->frame_offset
, 4);
6075 md_number_to_chars (fragp
+ 20, (valueT
) cur_proc_ptr
->frame_reg
, 4);
6076 md_number_to_chars (fragp
+ 24, (valueT
) cur_proc_ptr
->pc_reg
, 4);
6077 subseg_set (saved_seg
, saved_subseg
);
6080 cur_proc_ptr
= NULL
;
6083 /* Handle the .set pseudo-op. */
6085 s_score_set (int x ATTRIBUTE_UNUSED
)
6088 char name
[MAX_LITERAL_POOL_SIZE
];
6089 char * orig_ilp
= input_line_pointer
;
6091 while (!is_end_of_line
[(unsigned char)*input_line_pointer
])
6093 name
[i
] = (char) * input_line_pointer
;
6095 ++input_line_pointer
;
6100 if (strcmp (name
, "nwarn") == 0)
6102 warn_fix_data_dependency
= 0;
6104 else if (strcmp (name
, "fixdd") == 0)
6106 fix_data_dependency
= 1;
6108 else if (strcmp (name
, "nofixdd") == 0)
6110 fix_data_dependency
= 0;
6112 else if (strcmp (name
, "r1") == 0)
6116 else if (strcmp (name
, "nor1") == 0)
6120 else if (strcmp (name
, "optimize") == 0)
6124 else if (strcmp (name
, "volatile") == 0)
6128 else if (strcmp (name
, "pic") == 0)
6134 input_line_pointer
= orig_ilp
;
6139 /* Handle the .cpload pseudo-op. This is used when generating PIC code. It sets the
6140 $gp register for the function based on the function address, which is in the register
6141 named in the argument. This uses a relocation against GP_DISP_LABEL, which is handled
6142 specially by the linker. The result is:
6143 ldis gp, %hi(GP_DISP_LABEL)
6144 ori gp, %low(GP_DISP_LABEL)
6145 add gp, gp, .cpload argument
6146 The .cpload argument is normally r29. */
6149 s_score_cpload (int ignore ATTRIBUTE_UNUSED
)
6152 char insn_str
[MAX_LITERAL_POOL_SIZE
];
6154 /* If we are not generating PIC code, .cpload is ignored. */
6155 if (score_pic
== NO_PIC
)
6161 if ((reg
= reg_required_here (&input_line_pointer
, -1, REG_TYPE_SCORE
)) == (int) FAIL
)
6164 demand_empty_rest_of_line ();
6166 sprintf (insn_str
, "ld_i32hi r%d, %s", GP
, GP_DISP_LABEL
);
6167 if (append_insn (insn_str
, TRUE
) == (int) FAIL
)
6170 sprintf (insn_str
, "ld_i32lo r%d, %s", GP
, GP_DISP_LABEL
);
6171 if (append_insn (insn_str
, TRUE
) == (int) FAIL
)
6174 sprintf (insn_str
, "add r%d, r%d, r%d", GP
, GP
, reg
);
6175 if (append_insn (insn_str
, TRUE
) == (int) FAIL
)
6179 /* Handle the .cprestore pseudo-op. This stores $gp into a given
6180 offset from $sp. The offset is remembered, and after making a PIC
6181 call $gp is restored from that location. */
6184 s_score_cprestore (int ignore ATTRIBUTE_UNUSED
)
6187 int cprestore_offset
;
6188 char insn_str
[MAX_LITERAL_POOL_SIZE
];
6190 /* If we are not generating PIC code, .cprestore is ignored. */
6191 if (score_pic
== NO_PIC
)
6197 if ((reg
= reg_required_here (&input_line_pointer
, -1, REG_TYPE_SCORE
)) == (int) FAIL
6198 || skip_past_comma (&input_line_pointer
) == (int) FAIL
)
6203 cprestore_offset
= get_absolute_expression ();
6205 if (cprestore_offset
<= 0x3fff)
6207 sprintf (insn_str
, "sw r%d, [r%d, %d]", GP
, reg
, cprestore_offset
);
6208 if (append_insn (insn_str
, TRUE
) == (int) FAIL
)
6218 sprintf (insn_str
, "li r1, %d", cprestore_offset
);
6219 if (append_insn (insn_str
, TRUE
) == (int) FAIL
)
6222 sprintf (insn_str
, "add r1, r1, r%d", reg
);
6223 if (append_insn (insn_str
, TRUE
) == (int) FAIL
)
6226 sprintf (insn_str
, "sw r%d, [r1]", GP
);
6227 if (append_insn (insn_str
, TRUE
) == (int) FAIL
)
6233 demand_empty_rest_of_line ();
6236 /* Handle the .gpword pseudo-op. This is used when generating PIC
6237 code. It generates a 32 bit GP relative reloc. */
6239 s_score_gpword (int ignore ATTRIBUTE_UNUSED
)
6244 /* When not generating PIC code, this is treated as .word. */
6245 if (score_pic
== NO_PIC
)
6251 if (ex
.X_op
!= O_symbol
|| ex
.X_add_number
!= 0)
6253 as_bad (_("Unsupported use of .gpword"));
6254 ignore_rest_of_line ();
6257 md_number_to_chars (p
, (valueT
) 0, 4);
6258 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 4, &ex
, FALSE
, BFD_RELOC_GPREL32
);
6259 demand_empty_rest_of_line ();
6262 /* Handle the .cpadd pseudo-op. This is used when dealing with switch
6263 tables in PIC code. */
6266 s_score_cpadd (int ignore ATTRIBUTE_UNUSED
)
6269 char insn_str
[MAX_LITERAL_POOL_SIZE
];
6271 /* If we are not generating PIC code, .cpload is ignored. */
6272 if (score_pic
== NO_PIC
)
6278 if ((reg
= reg_required_here (&input_line_pointer
, -1, REG_TYPE_SCORE
)) == (int) FAIL
)
6282 demand_empty_rest_of_line ();
6284 /* Add $gp to the register named as an argument. */
6285 sprintf (insn_str
, "add r%d, r%d, r%d", reg
, reg
, GP
);
6286 if (append_insn (insn_str
, TRUE
) == (int) FAIL
)
6290 #ifndef TC_IMPLICIT_LCOMM_ALIGNMENT
6291 #define TC_IMPLICIT_LCOMM_ALIGNMENT(SIZE, P2VAR) \
6296 else if ((SIZE) >= 4) \
6298 else if ((SIZE) >= 2) \
6307 s_score_lcomm (int bytes_p
)
6314 segT current_seg
= now_seg
;
6315 subsegT current_subseg
= now_subseg
;
6316 const int max_alignment
= 15;
6318 segT bss_seg
= bss_section
;
6319 int needs_align
= 0;
6321 name
= input_line_pointer
;
6322 c
= get_symbol_end ();
6323 p
= input_line_pointer
;
6328 as_bad (_("expected symbol name"));
6329 discard_rest_of_line ();
6335 /* Accept an optional comma after the name. The comma used to be
6336 required, but Irix 5 cc does not generate it. */
6337 if (*input_line_pointer
== ',')
6339 ++input_line_pointer
;
6343 if (is_end_of_line
[(unsigned char)*input_line_pointer
])
6345 as_bad (_("missing size expression"));
6349 if ((temp
= get_absolute_expression ()) < 0)
6351 as_warn (_("BSS length (%d) < 0 ignored"), temp
);
6352 ignore_rest_of_line ();
6356 #if defined (TC_SCORE)
6357 if (OUTPUT_FLAVOR
== bfd_target_ecoff_flavour
|| OUTPUT_FLAVOR
== bfd_target_elf_flavour
)
6359 /* For Score and Alpha ECOFF or ELF, small objects are put in .sbss. */
6360 if ((unsigned)temp
<= bfd_get_gp_size (stdoutput
))
6362 bss_seg
= subseg_new (".sbss", 1);
6363 seg_info (bss_seg
)->bss
= 1;
6364 #ifdef BFD_ASSEMBLER
6365 if (!bfd_set_section_flags (stdoutput
, bss_seg
, SEC_ALLOC
))
6366 as_warn (_("error setting flags for \".sbss\": %s"), bfd_errmsg (bfd_get_error ()));
6373 if (*input_line_pointer
== ',')
6375 ++input_line_pointer
;
6378 if (is_end_of_line
[(unsigned char)*input_line_pointer
])
6380 as_bad (_("missing alignment"));
6385 align
= get_absolute_expression ();
6392 TC_IMPLICIT_LCOMM_ALIGNMENT (temp
, align
);
6394 /* Still zero unless TC_IMPLICIT_LCOMM_ALIGNMENT set it. */
6396 record_alignment (bss_seg
, align
);
6403 /* Convert to a power of 2. */
6408 for (i
= 0; align
!= 0; align
>>= 1, ++i
)
6414 if (align
> max_alignment
)
6416 align
= max_alignment
;
6417 as_warn (_("alignment too large; %d assumed"), align
);
6422 as_warn (_("alignment negative; 0 assumed"));
6425 record_alignment (bss_seg
, align
);
6429 /* Assume some objects may require alignment on some systems. */
6430 #if defined (TC_ALPHA) && ! defined (VMS)
6433 align
= ffs (temp
) - 1;
6434 if (temp
% (1 << align
))
6441 symbolP
= symbol_find_or_make (name
);
6445 #if (defined (OBJ_AOUT) || defined (OBJ_MAYBE_AOUT) \
6446 || defined (OBJ_BOUT) || defined (OBJ_MAYBE_BOUT))
6447 #ifdef BFD_ASSEMBLER
6448 (OUTPUT_FLAVOR
!= bfd_target_aout_flavour
6449 || (S_GET_OTHER (symbolP
) == 0 && S_GET_DESC (symbolP
) == 0)) &&
6451 (S_GET_OTHER (symbolP
) == 0 && S_GET_DESC (symbolP
) == 0) &&
6454 (S_GET_SEGMENT (symbolP
) == bss_seg
|| (!S_IS_DEFINED (symbolP
) && S_GET_VALUE (symbolP
) == 0)))
6458 subseg_set (bss_seg
, 1);
6461 frag_align (align
, 0, 0);
6463 /* Detach from old frag. */
6464 if (S_GET_SEGMENT (symbolP
) == bss_seg
)
6465 symbol_get_frag (symbolP
)->fr_symbol
= NULL
;
6467 symbol_set_frag (symbolP
, frag_now
);
6468 pfrag
= frag_var (rs_org
, 1, 1, (relax_substateT
) 0, symbolP
, (offsetT
) temp
, NULL
);
6472 S_SET_SEGMENT (symbolP
, bss_seg
);
6475 /* The symbol may already have been created with a preceding
6476 ".globl" directive -- be careful not to step on storage class
6477 in that case. Otherwise, set it to static. */
6478 if (S_GET_STORAGE_CLASS (symbolP
) != C_EXT
)
6480 S_SET_STORAGE_CLASS (symbolP
, C_STAT
);
6482 #endif /* OBJ_COFF */
6485 S_SET_SIZE (symbolP
, temp
);
6489 as_bad (_("symbol `%s' is already defined"), S_GET_NAME (symbolP
));
6491 subseg_set (current_seg
, current_subseg
);
6493 demand_empty_rest_of_line ();
6497 insert_reg (const struct reg_entry
*r
, struct hash_control
*htab
)
6500 int len
= strlen (r
->name
) + 2;
6501 char *buf
= xmalloc (len
);
6502 char *buf2
= xmalloc (len
);
6504 strcpy (buf
+ i
, r
->name
);
6505 for (i
= 0; buf
[i
]; i
++)
6507 buf2
[i
] = TOUPPER (buf
[i
]);
6511 hash_insert (htab
, buf
, (void *) r
);
6512 hash_insert (htab
, buf2
, (void *) r
);
6516 build_reg_hsh (struct reg_map
*map
)
6518 const struct reg_entry
*r
;
6520 if ((map
->htab
= hash_new ()) == NULL
)
6522 as_fatal (_("virtual memory exhausted"));
6524 for (r
= map
->names
; r
->name
!= NULL
; r
++)
6526 insert_reg (r
, map
->htab
);
6537 if ((score_ops_hsh
= hash_new ()) == NULL
)
6538 as_fatal (_("virtual memory exhausted"));
6540 build_score_ops_hsh ();
6542 if ((dependency_insn_hsh
= hash_new ()) == NULL
)
6543 as_fatal (_("virtual memory exhausted"));
6545 build_dependency_insn_hsh ();
6547 for (i
= (int)REG_TYPE_FIRST
; i
< (int)REG_TYPE_MAX
; i
++)
6548 build_reg_hsh (all_reg_maps
+ i
);
6550 /* Initialize dependency vector. */
6551 init_dependency_vector ();
6553 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
, 0);
6555 subseg
= now_subseg
;
6556 pdr_seg
= subseg_new (".pdr", (subsegT
) 0);
6557 (void)bfd_set_section_flags (stdoutput
, pdr_seg
, SEC_READONLY
| SEC_RELOC
| SEC_DEBUGGING
);
6558 (void)bfd_set_section_alignment (stdoutput
, pdr_seg
, 2);
6559 subseg_set (seg
, subseg
);
6561 if (USE_GLOBAL_POINTER_OPT
)
6562 bfd_set_gp_size (stdoutput
, g_switch_value
);
6566 const pseudo_typeS md_pseudo_table
[] =
6568 {"bss", s_score_bss
, 0},
6569 {"text", s_score_text
, 0},
6572 {"extend", float_cons
, 'x'},
6573 {"ldouble", float_cons
, 'x'},
6574 {"packed", float_cons
, 'p'},
6575 {"end", s_score_end
, 0},
6576 {"ent", s_score_ent
, 0},
6577 {"frame", s_score_frame
, 0},
6578 {"rdata", s_change_sec
, 'r'},
6579 {"sdata", s_change_sec
, 's'},
6580 {"set", s_score_set
, 0},
6581 {"mask", s_score_mask
, 'R'},
6583 {"lcomm", s_score_lcomm
, 1},
6584 {"section", score_s_section
, 0},
6585 {"cpload", s_score_cpload
, 0},
6586 {"cprestore", s_score_cprestore
, 0},
6587 {"gpword", s_score_gpword
, 0},
6588 {"cpadd", s_score_cpadd
, 0},