1 /* tc-score7.c -- Assembler for Score7
2 Copyright (C) 2009-2018 Free Software Foundation, Inc.
4 Brain.lin (brain.lin@sunplusct.com)
5 Mei Ligang (ligang@sunnorth.com.cn)
6 Pei-Lin Tsai (pltsai@sunplus.com)
8 This file is part of GAS, the GNU Assembler.
10 GAS is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3, or (at your option)
15 GAS is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with GAS; see the file COPYING. If not, write to the Free
22 Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
23 MA 02110-1301, USA. */
28 #include "safe-ctype.h"
29 #include "opcode/score-inst.h"
30 #include "libiberty.h"
33 #include "elf/score.h"
34 #include "dwarf2dbg.h"
37 static void s7_do_ldst_insn (char *);
38 static void s7_do_crdcrscrsimm5 (char *);
39 static void s7_do_ldst_unalign (char *);
40 static void s7_do_ldst_atomic (char *);
41 static void s7_do_ldst_cop (char *);
42 static void s7_do_macro_li_rdi32 (char *);
43 static void s7_do_macro_la_rdi32 (char *);
44 static void s7_do_macro_rdi32hi (char *);
45 static void s7_do_macro_rdi32lo (char *);
46 static void s7_do_macro_mul_rdrsrs (char *);
47 static void s7_do_macro_ldst_label (char *);
48 static void s7_do_branch (char *);
49 static void s7_do_jump (char *);
50 static void s7_do_empty (char *);
51 static void s7_do_rdrsrs (char *);
52 static void s7_do_rdsi16 (char *);
53 static void s7_do_rdrssi14 (char *);
54 static void s7_do_sub_rdsi16 (char *);
55 static void s7_do_sub_rdrssi14 (char *);
56 static void s7_do_rdrsi5 (char *);
57 static void s7_do_rdrsi14 (char *);
58 static void s7_do_rdi16 (char *);
59 static void s7_do_xrsi5 (char *);
60 static void s7_do_rdrs (char *);
61 static void s7_do_rdxrs (char *);
62 static void s7_do_rsrs (char *);
63 static void s7_do_rdcrs (char *);
64 static void s7_do_rdsrs (char *);
65 static void s7_do_rd (char *);
66 static void s7_do_rs (char *);
67 static void s7_do_i15 (char *);
68 static void s7_do_xi5x (char *);
69 static void s7_do_ceinst (char *);
70 static void s7_do_cache (char *);
71 static void s7_do16_rdrs (char *);
72 static void s7_do16_rs (char *);
73 static void s7_do16_xrs (char *);
74 static void s7_do16_mv_rdrs (char *);
75 static void s7_do16_hrdrs (char *);
76 static void s7_do16_rdhrs (char *);
77 static void s7_do16_rdi4 (char *);
78 static void s7_do16_rdi5 (char *);
79 static void s7_do16_xi5 (char *);
80 static void s7_do16_ldst_insn (char *);
81 static void s7_do16_ldst_imm_insn (char *);
82 static void s7_do16_push_pop (char *);
83 static void s7_do16_branch (char *);
84 static void s7_do16_jump (char *);
85 static void s7_do_rdi16_pic (char *);
86 static void s7_do_addi_s_pic (char *);
87 static void s7_do_addi_u_pic (char *);
88 static void s7_do_lw_pic (char *);
91 #define s7_PIC_CALL_REG 29
92 #define s7_MAX_LITERAL_POOL_SIZE 1024
93 #define s7_FAIL 0x80000000
95 #define s7_INSN_SIZE 4
96 #define s7_INSN16_SIZE 2
97 #define s7_RELAX_INST_NUM 3
99 /* For score5u : div/mul will pop warning message, mmu/alw/asw will pop error message. */
100 #define s7_BAD_ARGS _("bad arguments to instruction")
101 #define s7_ERR_FOR_SCORE5U_MUL_DIV _("div / mul are reserved instructions")
102 #define s7_ERR_FOR_SCORE5U_MMU _("This architecture doesn't support mmu")
103 #define s7_ERR_FOR_SCORE5U_ATOMIC _("This architecture doesn't support atomic instruction")
104 #define s7_BAD_SKIP_COMMA s7_BAD_ARGS
105 #define s7_BAD_GARBAGE _("garbage following instruction");
107 #define s7_skip_whitespace(str) while (*(str) == ' ') ++(str)
109 /* The name of the readonly data section. */
110 #define s7_RDATA_SECTION_NAME (OUTPUT_FLAVOR == bfd_target_aout_flavour \
112 : OUTPUT_FLAVOR == bfd_target_ecoff_flavour \
114 : OUTPUT_FLAVOR == bfd_target_coff_flavour \
116 : OUTPUT_FLAVOR == bfd_target_elf_flavour \
120 #define s7_RELAX_ENCODE(old, new, type, reloc1, reloc2, opt) \
129 #define s7_RELAX_OLD(i) (((i) >> 23) & 0x7f)
130 #define s7_RELAX_NEW(i) (((i) >> 16) & 0x7f)
131 #define s7_RELAX_TYPE(i) (((i) >> 9) & 0x7f)
132 #define s7_RELAX_RELOC1(i) ((valueT) ((i) >> 5) & 0xf)
133 #define s7_RELAX_RELOC2(i) ((valueT) ((i) >> 1) & 0xf)
134 #define s7_RELAX_OPT(i) ((i) & 1)
135 #define s7_RELAX_OPT_CLEAR(i) ((i) & ~1)
137 #define s7_SET_INSN_ERROR(s) (s7_inst.error = (s))
138 #define s7_INSN_IS_PCE_P(s) (strstr (str, "||") != NULL)
140 #define s7_GET_INSN_CLASS(type) (s7_get_insn_class_from_type (type))
142 #define s7_GET_INSN_SIZE(type) ((s7_GET_INSN_CLASS (type) == INSN_CLASS_16) \
143 ? s7_INSN16_SIZE : s7_INSN_SIZE)
145 #define s7_MAX_LITTLENUMS 6
146 #define s7_INSN_NAME_LEN 16
148 /* Relax will need some padding for alignment. */
149 #define s7_RELAX_PAD_BYTE 3
151 #define s7_USE_GLOBAL_POINTER_OPT 1
155 /* Enumeration matching entries in table above. */
156 enum s7_score_reg_type
158 s7_REG_TYPE_SCORE
= 0,
159 #define REG_TYPE_FIRST s7_REG_TYPE_SCORE
160 s7_REG_TYPE_SCORE_SR
= 1,
161 s7_REG_TYPE_SCORE_CR
= 2,
165 enum s7_score_pic_level
170 static enum s7_score_pic_level s7_score_pic
= s7_NO_PIC
;
172 enum s7_insn_type_for_dependency
191 struct s7_insn_to_dependency
193 const char *insn_name
;
194 enum s7_insn_type_for_dependency type
;
197 struct s7_data_dependency
199 enum s7_insn_type_for_dependency pre_insn_type
;
201 enum s7_insn_type_for_dependency cur_insn_type
;
205 int warn_or_error
; /* warning - 0; error - 1 */
208 static const struct s7_insn_to_dependency s7_insn_to_dependency_table
[] =
210 /* pce instruction. */
212 /* conditional branch instruction. */
213 {"bcs", s7_D_cond_br
},
214 {"bcc", s7_D_cond_br
},
215 {"bgtu", s7_D_cond_br
},
216 {"bleu", s7_D_cond_br
},
217 {"beq", s7_D_cond_br
},
218 {"bne", s7_D_cond_br
},
219 {"bgt", s7_D_cond_br
},
220 {"ble", s7_D_cond_br
},
221 {"bge", s7_D_cond_br
},
222 {"blt", s7_D_cond_br
},
223 {"bmi", s7_D_cond_br
},
224 {"bpl", s7_D_cond_br
},
225 {"bvs", s7_D_cond_br
},
226 {"bvc", s7_D_cond_br
},
227 {"bcsl", s7_D_cond_br
},
228 {"bccl", s7_D_cond_br
},
229 {"bgtul", s7_D_cond_br
},
230 {"bleul", s7_D_cond_br
},
231 {"beql", s7_D_cond_br
},
232 {"bnel", s7_D_cond_br
},
233 {"bgtl", s7_D_cond_br
},
234 {"blel", s7_D_cond_br
},
235 {"bgel", s7_D_cond_br
},
236 {"bltl", s7_D_cond_br
},
237 {"bmil", s7_D_cond_br
},
238 {"bpll", s7_D_cond_br
},
239 {"bvsl", s7_D_cond_br
},
240 {"bvcl", s7_D_cond_br
},
241 {"bcs!", s7_D_cond_br
},
242 {"bcc!", s7_D_cond_br
},
243 {"bgtu!", s7_D_cond_br
},
244 {"bleu!", s7_D_cond_br
},
245 {"beq!", s7_D_cond_br
},
246 {"bne!", s7_D_cond_br
},
247 {"bgt!", s7_D_cond_br
},
248 {"ble!", s7_D_cond_br
},
249 {"bge!", s7_D_cond_br
},
250 {"blt!", s7_D_cond_br
},
251 {"bmi!", s7_D_cond_br
},
252 {"bpl!", s7_D_cond_br
},
253 {"bvs!", s7_D_cond_br
},
254 {"bvc!", s7_D_cond_br
},
255 {"brcs", s7_D_cond_br
},
256 {"brcc", s7_D_cond_br
},
257 {"brgtu", s7_D_cond_br
},
258 {"brleu", s7_D_cond_br
},
259 {"breq", s7_D_cond_br
},
260 {"brne", s7_D_cond_br
},
261 {"brgt", s7_D_cond_br
},
262 {"brle", s7_D_cond_br
},
263 {"brge", s7_D_cond_br
},
264 {"brlt", s7_D_cond_br
},
265 {"brmi", s7_D_cond_br
},
266 {"brpl", s7_D_cond_br
},
267 {"brvs", s7_D_cond_br
},
268 {"brvc", s7_D_cond_br
},
269 {"brcsl", s7_D_cond_br
},
270 {"brccl", s7_D_cond_br
},
271 {"brgtul", s7_D_cond_br
},
272 {"brleul", s7_D_cond_br
},
273 {"breql", s7_D_cond_br
},
274 {"brnel", s7_D_cond_br
},
275 {"brgtl", s7_D_cond_br
},
276 {"brlel", s7_D_cond_br
},
277 {"brgel", s7_D_cond_br
},
278 {"brltl", s7_D_cond_br
},
279 {"brmil", s7_D_cond_br
},
280 {"brpll", s7_D_cond_br
},
281 {"brvsl", s7_D_cond_br
},
282 {"brvcl", s7_D_cond_br
},
283 {"brcs!", s7_D_cond_br
},
284 {"brcc!", s7_D_cond_br
},
285 {"brgtu!", s7_D_cond_br
},
286 {"brleu!", s7_D_cond_br
},
287 {"breq!", s7_D_cond_br
},
288 {"brne!", s7_D_cond_br
},
289 {"brgt!", s7_D_cond_br
},
290 {"brle!", s7_D_cond_br
},
291 {"brge!", s7_D_cond_br
},
292 {"brlt!", s7_D_cond_br
},
293 {"brmi!", s7_D_cond_br
},
294 {"brpl!", s7_D_cond_br
},
295 {"brvs!", s7_D_cond_br
},
296 {"brvc!", s7_D_cond_br
},
297 {"brcsl!", s7_D_cond_br
},
298 {"brccl!", s7_D_cond_br
},
299 {"brgtul!", s7_D_cond_br
},
300 {"brleul!", s7_D_cond_br
},
301 {"breql!", s7_D_cond_br
},
302 {"brnel!", s7_D_cond_br
},
303 {"brgtl!", s7_D_cond_br
},
304 {"brlel!", s7_D_cond_br
},
305 {"brgel!", s7_D_cond_br
},
306 {"brltl!", s7_D_cond_br
},
307 {"brmil!", s7_D_cond_br
},
308 {"brpll!", s7_D_cond_br
},
309 {"brvsl!", s7_D_cond_br
},
310 {"brvcl!", s7_D_cond_br
},
311 /* conditional move instruction. */
312 {"mvcs", s7_D_cond_mv
},
313 {"mvcc", s7_D_cond_mv
},
314 {"mvgtu", s7_D_cond_mv
},
315 {"mvleu", s7_D_cond_mv
},
316 {"mveq", s7_D_cond_mv
},
317 {"mvne", s7_D_cond_mv
},
318 {"mvgt", s7_D_cond_mv
},
319 {"mvle", s7_D_cond_mv
},
320 {"mvge", s7_D_cond_mv
},
321 {"mvlt", s7_D_cond_mv
},
322 {"mvmi", s7_D_cond_mv
},
323 {"mvpl", s7_D_cond_mv
},
324 {"mvvs", s7_D_cond_mv
},
325 {"mvvc", s7_D_cond_mv
},
326 /* move special instruction. */
328 {"mftlb", s7_D_mftlb
},
329 {"mtptlb", s7_D_mtptlb
},
330 {"mtrtlb", s7_D_mtrtlb
},
334 /* cache instruction. */
335 {"cache 8", s7_D_cached
},
336 {"cache 9", s7_D_cached
},
337 {"cache 10", s7_D_cached
},
338 {"cache 11", s7_D_cached
},
339 {"cache 12", s7_D_cached
},
340 {"cache 13", s7_D_cached
},
341 {"cache 14", s7_D_cached
},
342 {"cache 24", s7_D_cached
},
343 {"cache 26", s7_D_cached
},
344 {"cache 27", s7_D_cached
},
345 {"cache 29", s7_D_cached
},
346 {"cache 30", s7_D_cached
},
347 {"cache 31", s7_D_cached
},
348 {"cache 0", s7_D_cachei
},
349 {"cache 1", s7_D_cachei
},
350 {"cache 2", s7_D_cachei
},
351 {"cache 3", s7_D_cachei
},
352 {"cache 4", s7_D_cachei
},
353 {"cache 16", s7_D_cachei
},
354 {"cache 17", s7_D_cachei
},
355 /* load/store instruction. */
359 {"lbup!", s7_D_ldst
},
378 {"push!", s7_D_ldst
},
379 {"pushhi!", s7_D_ldst
},
381 {"pophi!", s7_D_ldst
},
391 /* load combine instruction. */
392 {"lcb", s7_D_ldcombine
},
393 {"lcw", s7_D_ldcombine
},
394 {"lce", s7_D_ldcombine
},
397 static const struct s7_data_dependency s7_data_dependency_table
[] =
399 /* Condition register. */
400 {s7_D_mtcr
, "cr1", s7_D_pce
, "", 2, 1, 0},
401 {s7_D_mtcr
, "cr1", s7_D_cond_br
, "", 1, 0, 1},
402 {s7_D_mtcr
, "cr1", s7_D_cond_mv
, "", 1, 0, 1},
403 /* Status register. */
404 {s7_D_mtcr
, "cr0", s7_D_all_insn
, "", 5, 4, 0},
406 {s7_D_mtcr
, "cr4", s7_D_all_insn
, "", 6, 5, 0},
407 /* EntryHi/EntryLo register. */
408 {s7_D_mftlb
, "", s7_D_mtptlb
, "", 1, 1, 1},
409 {s7_D_mftlb
, "", s7_D_mtrtlb
, "", 1, 1, 1},
410 {s7_D_mftlb
, "", s7_D_stlb
, "", 1, 1,1},
411 {s7_D_mftlb
, "", s7_D_mfcr
, "cr11", 1, 1, 1},
412 {s7_D_mftlb
, "", s7_D_mfcr
, "cr12", 1, 1, 1},
413 /* Index register. */
414 {s7_D_stlb
, "", s7_D_mtptlb
, "", 1, 1, 1},
415 {s7_D_stlb
, "", s7_D_mftlb
, "", 1, 1, 1},
416 {s7_D_stlb
, "", s7_D_mfcr
, "cr8", 2, 2, 1},
418 {s7_D_cached
, "", s7_D_ldst
, "", 1, 1, 0},
419 {s7_D_cached
, "", s7_D_ldcombine
, "", 1, 1, 0},
420 {s7_D_cachei
, "", s7_D_all_insn
, "", 5, 4, 0},
422 {s7_D_ldcombine
, "", s7_D_mfsr
, "sr1", 3, 3, 1},
427 /* Used to contain constructed error messages. */
428 static char s7_err_msg
[255];
429 static int s7_fix_data_dependency
= 0;
430 static int s7_warn_fix_data_dependency
= 1;
432 static int s7_in_my_get_expression
= 0;
434 /* Default, pop warning message when using r1. */
435 static int s7_nor1
= 1;
437 /* Default will do instruction relax, -O0 will set s7_g_opt = 0. */
438 static unsigned int s7_g_opt
= 1;
440 /* The size of the small data section. */
441 static unsigned int s7_g_switch_value
= 8;
443 static segT s7_pdr_seg
;
447 char name
[s7_INSN_NAME_LEN
];
448 unsigned long instruction
;
449 unsigned long relax_inst
;
452 enum score_insn_type type
;
453 char str
[s7_MAX_LITERAL_POOL_SIZE
];
456 char reg
[s7_INSN_NAME_LEN
];
459 bfd_reloc_code_real_type type
;
464 static struct s7_score_it s7_inst
;
469 unsigned long reg_mask
;
470 unsigned long reg_offset
;
471 unsigned long fpreg_mask
;
473 unsigned long frame_offset
;
474 unsigned long frame_reg
;
475 unsigned long pc_reg
;
477 static s7_procS s7_cur_proc
;
478 static s7_procS
*s7_cur_proc_ptr
;
479 static int s7_numprocs
;
481 /* Structure for a hash table entry for a register. */
488 static const struct s7_reg_entry s7_score_rn_table
[] =
490 {"r0", 0}, {"r1", 1}, {"r2", 2}, {"r3", 3},
491 {"r4", 4}, {"r5", 5}, {"r6", 6}, {"r7", 7},
492 {"r8", 8}, {"r9", 9}, {"r10", 10}, {"r11", 11},
493 {"r12", 12}, {"r13", 13}, {"r14", 14}, {"r15", 15},
494 {"r16", 16}, {"r17", 17}, {"r18", 18}, {"r19", 19},
495 {"r20", 20}, {"r21", 21}, {"r22", 22}, {"r23", 23},
496 {"r24", 24}, {"r25", 25}, {"r26", 26}, {"r27", 27},
497 {"r28", 28}, {"r29", 29}, {"r30", 30}, {"r31", 31},
501 static const struct s7_reg_entry s7_score_srn_table
[] =
503 {"sr0", 0}, {"sr1", 1}, {"sr2", 2},
507 static const struct s7_reg_entry s7_score_crn_table
[] =
509 {"cr0", 0}, {"cr1", 1}, {"cr2", 2}, {"cr3", 3},
510 {"cr4", 4}, {"cr5", 5}, {"cr6", 6}, {"cr7", 7},
511 {"cr8", 8}, {"cr9", 9}, {"cr10", 10}, {"cr11", 11},
512 {"cr12", 12}, {"cr13", 13}, {"cr14", 14}, {"cr15", 15},
513 {"cr16", 16}, {"cr17", 17}, {"cr18", 18}, {"cr19", 19},
514 {"cr20", 20}, {"cr21", 21}, {"cr22", 22}, {"cr23", 23},
515 {"cr24", 24}, {"cr25", 25}, {"cr26", 26}, {"cr27", 27},
516 {"cr28", 28}, {"cr29", 29}, {"cr30", 30}, {"cr31", 31},
522 const struct s7_reg_entry
*names
;
524 struct hash_control
*htab
;
525 const char *expected
;
528 static struct s7_reg_map s7_all_reg_maps
[] =
530 {s7_score_rn_table
, 31, NULL
, N_("S+core register expected")},
531 {s7_score_srn_table
, 2, NULL
, N_("S+core special-register expected")},
532 {s7_score_crn_table
, 31, NULL
, N_("S+core co-processor register expected")},
535 static struct hash_control
*s7_score_ops_hsh
= NULL
;
536 static struct hash_control
*s7_dependency_insn_hsh
= NULL
;
539 struct s7_datafield_range
546 static struct s7_datafield_range s7_score_df_range
[] =
548 {_IMM4
, 4, {0, (1 << 4) - 1}}, /* ( 0 ~ 15 ) */
549 {_IMM5
, 5, {0, (1 << 5) - 1}}, /* ( 0 ~ 31 ) */
550 {_IMM8
, 8, {0, (1 << 8) - 1}}, /* ( 0 ~ 255 ) */
551 {_IMM14
, 14, {0, (1 << 14) - 1}}, /* ( 0 ~ 16383) */
552 {_IMM15
, 15, {0, (1 << 15) - 1}}, /* ( 0 ~ 32767) */
553 {_IMM16
, 16, {0, (1 << 16) - 1}}, /* ( 0 ~ 65535) */
554 {_SIMM10
, 10, {-(1 << 9), (1 << 9) - 1}}, /* ( -512 ~ 511 ) */
555 {_SIMM12
, 12, {-(1 << 11), (1 << 11) - 1}}, /* ( -2048 ~ 2047 ) */
556 {_SIMM14
, 14, {-(1 << 13), (1 << 13) - 1}}, /* ( -8192 ~ 8191 ) */
557 {_SIMM15
, 15, {-(1 << 14), (1 << 14) - 1}}, /* (-16384 ~ 16383) */
558 {_SIMM16
, 16, {-(1 << 15), (1 << 15) - 1}}, /* (-32768 ~ 32767) */
559 {_SIMM14_NEG
, 14, {-(1 << 13), (1 << 13) - 1}}, /* ( -8191 ~ 8192 ) */
560 {_IMM16_NEG
, 16, {0, (1 << 16) - 1}}, /* (-65535 ~ 0 ) */
561 {_SIMM16_NEG
, 16, {-(1 << 15), (1 << 15) - 1}}, /* (-32768 ~ 32767) */
562 {_IMM20
, 20, {0, (1 << 20) - 1}},
563 {_IMM25
, 25, {0, (1 << 25) - 1}},
564 {_DISP8div2
, 8, {-(1 << 8), (1 << 8) - 1}}, /* ( -256 ~ 255 ) */
565 {_DISP11div2
, 11, {0, 0}},
566 {_DISP19div2
, 19, {-(1 << 19), (1 << 19) - 1}}, /* (-524288 ~ 524287) */
567 {_DISP24div2
, 24, {0, 0}},
568 {_VALUE
, 32, {0, ((unsigned int)1 << 31) - 1}},
569 {_VALUE_HI16
, 16, {0, (1 << 16) - 1}},
570 {_VALUE_LO16
, 16, {0, (1 << 16) - 1}},
571 {_VALUE_LDST_LO16
, 16, {0, (1 << 16) - 1}},
572 {_SIMM16_LA
, 16, {-(1 << 15), (1 << 15) - 1}}, /* (-32768 ~ 32767) */
573 {_IMM5_RSHIFT_1
, 5, {0, (1 << 6) - 1}}, /* ( 0 ~ 63 ) */
574 {_IMM5_RSHIFT_2
, 5, {0, (1 << 7) - 1}}, /* ( 0 ~ 127 ) */
575 {_SIMM16_LA_POS
, 16, {0, (1 << 15) - 1}}, /* ( 0 ~ 32767) */
576 {_IMM5_RANGE_8_31
, 5, {8, 31}}, /* But for cop0 the valid data : (8 ~ 31). */
577 {_IMM10_RSHIFT_2
, 10, {-(1 << 11), (1 << 11) - 1}}, /* For ldc#, stc#. */
578 {_SIMM10
, 10, {0, (1 << 10) - 1}}, /* ( -1024 ~ 1023 ) */
579 {_SIMM12
, 12, {0, (1 << 12) - 1}}, /* ( -2048 ~ 2047 ) */
580 {_SIMM14
, 14, {0, (1 << 14) - 1}}, /* ( -8192 ~ 8191 ) */
581 {_SIMM15
, 15, {0, (1 << 15) - 1}}, /* (-16384 ~ 16383) */
582 {_SIMM16
, 16, {0, (1 << 16) - 1}}, /* (-65536 ~ 65536) */
583 {_SIMM14_NEG
, 14, {0, (1 << 16) - 1}}, /* ( -8191 ~ 8192 ) */
584 {_IMM16_NEG
, 16, {0, (1 << 16) - 1}}, /* ( 65535 ~ 0 ) */
585 {_SIMM16_NEG
, 16, {0, (1 << 16) - 1}}, /* ( 65535 ~ 0 ) */
586 {_IMM20
, 20, {0, (1 << 20) - 1}}, /* (-32768 ~ 32767) */
587 {_IMM25
, 25, {0, (1 << 25) - 1}}, /* (-32768 ~ 32767) */
588 {_GP_IMM15
, 15, {0, (1 << 15) - 1}}, /* ( 0 ~ 65535) */
589 {_GP_IMM14
, 14, {0, (1 << 14) - 1}}, /* ( 0 ~ 65535) */
590 {_SIMM16_pic
, 16, {-(1 << 15), (1 << 15) - 1}}, /* (-32768 ~ 32767) */
591 {_IMM16_LO16_pic
, 16, {0, (1 << 16) - 1}}, /* ( 65535 ~ 0 ) */
592 {_IMM16_pic
, 16, {0, (1 << 16) - 1}}, /* ( 0 ~ 65535) */
598 /* Instruction name. */
599 const char *template_name
;
601 /* Instruction Opcode. */
604 /* Instruction bit mask. */
607 /* Relax instruction opcode. 0x8000 imply no relaxation. */
610 /* Instruction type. */
611 enum score_insn_type type
;
613 /* Function to call to parse args. */
614 void (*parms
) (char *);
617 static const struct s7_asm_opcode s7_score_ldst_insns
[] =
619 {"lw", 0x20000000, 0x3e000000, 0x2008, Rd_rvalueRs_SI15
, s7_do_ldst_insn
},
620 {"lw", 0x06000000, 0x3e000007, 0x8000, Rd_rvalueRs_preSI12
, s7_do_ldst_insn
},
621 {"lw", 0x0e000000, 0x3e000007, 0x200a, Rd_rvalueRs_postSI12
, s7_do_ldst_insn
},
622 {"lh", 0x22000000, 0x3e000000, 0x2009, Rd_rvalueRs_SI15
, s7_do_ldst_insn
},
623 {"lh", 0x06000001, 0x3e000007, 0x8000, Rd_rvalueRs_preSI12
, s7_do_ldst_insn
},
624 {"lh", 0x0e000001, 0x3e000007, 0x8000, Rd_rvalueRs_postSI12
, s7_do_ldst_insn
},
625 {"lhu", 0x24000000, 0x3e000000, 0x8000, Rd_rvalueRs_SI15
, s7_do_ldst_insn
},
626 {"lhu", 0x06000002, 0x3e000007, 0x8000, Rd_rvalueRs_preSI12
, s7_do_ldst_insn
},
627 {"lhu", 0x0e000002, 0x3e000007, 0x8000, Rd_rvalueRs_postSI12
, s7_do_ldst_insn
},
628 {"lb", 0x26000000, 0x3e000000, 0x8000, Rd_rvalueRs_SI15
, s7_do_ldst_insn
},
629 {"lb", 0x06000003, 0x3e000007, 0x8000, Rd_rvalueRs_preSI12
, s7_do_ldst_insn
},
630 {"lb", 0x0e000003, 0x3e000007, 0x8000, Rd_rvalueRs_postSI12
, s7_do_ldst_insn
},
631 {"sw", 0x28000000, 0x3e000000, 0x200c, Rd_lvalueRs_SI15
, s7_do_ldst_insn
},
632 {"sw", 0x06000004, 0x3e000007, 0x200e, Rd_lvalueRs_preSI12
, s7_do_ldst_insn
},
633 {"sw", 0x0e000004, 0x3e000007, 0x8000, Rd_lvalueRs_postSI12
, s7_do_ldst_insn
},
634 {"sh", 0x2a000000, 0x3e000000, 0x200d, Rd_lvalueRs_SI15
, s7_do_ldst_insn
},
635 {"sh", 0x06000005, 0x3e000007, 0x8000, Rd_lvalueRs_preSI12
, s7_do_ldst_insn
},
636 {"sh", 0x0e000005, 0x3e000007, 0x8000, Rd_lvalueRs_postSI12
, s7_do_ldst_insn
},
637 {"lbu", 0x2c000000, 0x3e000000, 0x200b, Rd_rvalueRs_SI15
, s7_do_ldst_insn
},
638 {"lbu", 0x06000006, 0x3e000007, 0x8000, Rd_rvalueRs_preSI12
, s7_do_ldst_insn
},
639 {"lbu", 0x0e000006, 0x3e000007, 0x8000, Rd_rvalueRs_postSI12
, s7_do_ldst_insn
},
640 {"sb", 0x2e000000, 0x3e000000, 0x200f, Rd_lvalueRs_SI15
, s7_do_ldst_insn
},
641 {"sb", 0x06000007, 0x3e000007, 0x8000, Rd_lvalueRs_preSI12
, s7_do_ldst_insn
},
642 {"sb", 0x0e000007, 0x3e000007, 0x8000, Rd_lvalueRs_postSI12
, s7_do_ldst_insn
},
645 static const struct s7_asm_opcode s7_score_insns
[] =
647 {"abs", 0x3800000a, 0x3e007fff, 0x8000, Rd_Rs_x
, s7_do_rdrs
},
648 {"abs.s", 0x3800004b, 0x3e007fff, 0x8000, Rd_Rs_x
, s7_do_rdrs
},
649 {"add", 0x00000010, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s7_do_rdrsrs
},
650 {"add.c", 0x00000011, 0x3e0003ff, 0x2000, Rd_Rs_Rs
, s7_do_rdrsrs
},
651 {"add.s", 0x38000048, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s7_do_rdrsrs
},
652 {"addc", 0x00000012, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s7_do_rdrsrs
},
653 {"addc.c", 0x00000013, 0x3e0003ff, 0x0009, Rd_Rs_Rs
, s7_do_rdrsrs
},
654 {"addi", 0x02000000, 0x3e0e0001, 0x8000, Rd_SI16
, s7_do_rdsi16
},
655 {"addi.c", 0x02000001, 0x3e0e0001, 0x8000, Rd_SI16
, s7_do_rdsi16
},
656 {"addis", 0x0a000000, 0x3e0e0001, 0x8000, Rd_SI16
, s7_do_rdi16
},
657 {"addis.c", 0x0a000001, 0x3e0e0001, 0x8000, Rd_SI16
, s7_do_rdi16
},
658 {"addri", 0x10000000, 0x3e000001, 0x8000, Rd_Rs_SI14
, s7_do_rdrssi14
},
659 {"addri.c", 0x10000001, 0x3e000001, 0x8000, Rd_Rs_SI14
, s7_do_rdrssi14
},
660 {"addc!", 0x0009, 0x700f, 0x00000013, Rd_Rs
, s7_do16_rdrs
},
661 {"add!", 0x2000, 0x700f, 0x00000011, Rd_Rs
, s7_do16_rdrs
},
662 {"addei!", 0x6000 , 0x7087, 0x02000001, Rd_I4
, s7_do16_rdi4
},
663 {"subi", 0x02000000, 0x3e0e0001, 0x8000, Rd_SI16
, s7_do_sub_rdsi16
},
664 {"subi.c", 0x02000001, 0x3e0e0001, 0x8000, Rd_SI16
, s7_do_sub_rdsi16
},
665 {"subri", 0x10000000, 0x3e000001, 0x8000, Rd_Rs_SI14
, s7_do_sub_rdrssi14
},
666 {"subri.c", 0x10000001, 0x3e000001, 0x8000, Rd_Rs_SI14
, s7_do_sub_rdrssi14
},
667 {"and", 0x00000020, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s7_do_rdrsrs
},
668 {"and.c", 0x00000021, 0x3e0003ff, 0x2004, Rd_Rs_Rs
, s7_do_rdrsrs
},
669 {"andi", 0x02080000, 0x3e0e0001, 0x8000, Rd_I16
, s7_do_rdi16
},
670 {"andi.c", 0x02080001, 0x3e0e0001, 0x8000, Rd_I16
, s7_do_rdi16
},
671 {"andis", 0x0a080000, 0x3e0e0001, 0x8000, Rd_I16
, s7_do_rdi16
},
672 {"andis.c", 0x0a080001, 0x3e0e0001, 0x8000, Rd_I16
, s7_do_rdi16
},
673 {"andri", 0x18000000, 0x3e000001, 0x8000, Rd_Rs_I14
, s7_do_rdrsi14
},
674 {"andri.c", 0x18000001, 0x3e000001, 0x8000, Rd_Rs_I14
, s7_do_rdrsi14
},
675 {"and!", 0x2004, 0x700f, 0x00000021, Rd_Rs
, s7_do16_rdrs
},
676 {"bcs", 0x08000000, 0x3e007c01, 0x4000, PC_DISP19div2
, s7_do_branch
},
677 {"bcc", 0x08000400, 0x3e007c01, 0x4000, PC_DISP19div2
, s7_do_branch
},
678 {"bcnz", 0x08003800, 0x3e007c01, 0x4000, PC_DISP19div2
, s7_do_branch
},
679 {"bcsl", 0x08000001, 0x3e007c01, 0x8000, PC_DISP19div2
, s7_do_branch
},
680 {"bccl", 0x08000401, 0x3e007c01, 0x8000, PC_DISP19div2
, s7_do_branch
},
681 {"bcnzl", 0x08003801, 0x3e007c01, 0x8000, PC_DISP19div2
, s7_do_branch
},
682 {"bcs!", 0x4000, 0x7f00, 0x08000000, PC_DISP8div2
, s7_do16_branch
},
683 {"bcc!", 0x4100, 0x7f00, 0x08000400, PC_DISP8div2
, s7_do16_branch
},
684 {"bcnz!", 0x4e00, 0x7f00, 0x08003800, PC_DISP8div2
, s7_do16_branch
},
685 {"beq", 0x08001000, 0x3e007c01, 0x4000, PC_DISP19div2
, s7_do_branch
},
686 {"beql", 0x08001001, 0x3e007c01, 0x8000, PC_DISP19div2
, s7_do_branch
},
687 {"beq!", 0x4400, 0x7f00, 0x08001000, PC_DISP8div2
, s7_do16_branch
},
688 {"bgtu", 0x08000800, 0x3e007c01, 0x4000, PC_DISP19div2
, s7_do_branch
},
689 {"bgt", 0x08001800, 0x3e007c01, 0x4000, PC_DISP19div2
, s7_do_branch
},
690 {"bge", 0x08002000, 0x3e007c01, 0x4000, PC_DISP19div2
, s7_do_branch
},
691 {"bgtul", 0x08000801, 0x3e007c01, 0x8000, PC_DISP19div2
, s7_do_branch
},
692 {"bgtl", 0x08001801, 0x3e007c01, 0x8000, PC_DISP19div2
, s7_do_branch
},
693 {"bgel", 0x08002001, 0x3e007c01, 0x8000, PC_DISP19div2
, s7_do_branch
},
694 {"bgtu!", 0x4200, 0x7f00, 0x08000800, PC_DISP8div2
, s7_do16_branch
},
695 {"bgt!", 0x4600, 0x7f00, 0x08001800, PC_DISP8div2
, s7_do16_branch
},
696 {"bge!", 0x4800, 0x7f00, 0x08002000, PC_DISP8div2
, s7_do16_branch
},
697 {"bitclr.c", 0x00000029, 0x3e0003ff, 0x6004, Rd_Rs_I5
, s7_do_rdrsi5
},
698 {"bitrev", 0x3800000c, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s7_do_rdrsrs
},
699 {"bitset.c", 0x0000002b, 0x3e0003ff, 0x6005, Rd_Rs_I5
, s7_do_rdrsi5
},
700 {"bittst.c", 0x0000002d, 0x3e0003ff, 0x6006, x_Rs_I5
, s7_do_xrsi5
},
701 {"bittgl.c", 0x0000002f, 0x3e0003ff, 0x6007, Rd_Rs_I5
, s7_do_rdrsi5
},
702 {"bitclr!", 0x6004, 0x7007, 0x00000029, Rd_I5
, s7_do16_rdi5
},
703 {"bitset!", 0x6005, 0x7007, 0x0000002b, Rd_I5
, s7_do16_rdi5
},
704 {"bittst!", 0x6006, 0x7007, 0x0000002d, Rd_I5
, s7_do16_rdi5
},
705 {"bittgl!", 0x6007, 0x7007, 0x0000002f, Rd_I5
, s7_do16_rdi5
},
706 {"bleu", 0x08000c00, 0x3e007c01, 0x4000, PC_DISP19div2
, s7_do_branch
},
707 {"ble", 0x08001c00, 0x3e007c01, 0x4000, PC_DISP19div2
, s7_do_branch
},
708 {"blt", 0x08002400, 0x3e007c01, 0x4000, PC_DISP19div2
, s7_do_branch
},
709 {"bleul", 0x08000c01, 0x3e007c01, 0x8000, PC_DISP19div2
, s7_do_branch
},
710 {"blel", 0x08001c01, 0x3e007c01, 0x8000, PC_DISP19div2
, s7_do_branch
},
711 {"bltl", 0x08002401, 0x3e007c01, 0x8000, PC_DISP19div2
, s7_do_branch
},
712 {"bl", 0x08003c01, 0x3e007c01, 0x8000, PC_DISP19div2
, s7_do_branch
},
713 {"bleu!", 0x4300, 0x7f00, 0x08000c00, PC_DISP8div2
, s7_do16_branch
},
714 {"ble!", 0x4700, 0x7f00, 0x08001c00, PC_DISP8div2
, s7_do16_branch
},
715 {"blt!", 0x4900, 0x7f00, 0x08002400, PC_DISP8div2
, s7_do16_branch
},
716 {"bmi", 0x08002800, 0x3e007c01, 0x4000, PC_DISP19div2
, s7_do_branch
},
717 {"bmil", 0x08002801, 0x3e007c01, 0x8000, PC_DISP19div2
, s7_do_branch
},
718 {"bmi!", 0x00004a00, 0x00007f00, 0x08002800, PC_DISP8div2
, s7_do16_branch
},
719 {"bne", 0x08001400, 0x3e007c01, 0x4000, PC_DISP19div2
, s7_do_branch
},
720 {"bnel", 0x08001401, 0x3e007c01, 0x8000, PC_DISP19div2
, s7_do_branch
},
721 {"bne!", 0x4500, 0x7f00, 0x08001400, PC_DISP8div2
, s7_do16_branch
},
722 {"bpl", 0x08002c00, 0x3e007c01, 0x4000, PC_DISP19div2
, s7_do_branch
},
723 {"bpll", 0x08002c01, 0x3e007c01, 0x8000, PC_DISP19div2
, s7_do_branch
},
724 {"bpl!", 0x4b00, 0x7f00, 0x08002c00, PC_DISP8div2
, s7_do16_branch
},
725 {"brcs", 0x00000008, 0x3e007fff, 0x0004, x_Rs_x
, s7_do_rs
},
726 {"brcc", 0x00000408, 0x3e007fff, 0x0104, x_Rs_x
, s7_do_rs
},
727 {"brgtu", 0x00000808, 0x3e007fff, 0x0204, x_Rs_x
, s7_do_rs
},
728 {"brleu", 0x00000c08, 0x3e007fff, 0x0304, x_Rs_x
, s7_do_rs
},
729 {"breq", 0x00001008, 0x3e007fff, 0x0404, x_Rs_x
, s7_do_rs
},
730 {"brne", 0x00001408, 0x3e007fff, 0x0504, x_Rs_x
, s7_do_rs
},
731 {"brgt", 0x00001808, 0x3e007fff, 0x0604, x_Rs_x
, s7_do_rs
},
732 {"brle", 0x00001c08, 0x3e007fff, 0x0704, x_Rs_x
, s7_do_rs
},
733 {"brge", 0x00002008, 0x3e007fff, 0x0804, x_Rs_x
, s7_do_rs
},
734 {"brlt", 0x00002408, 0x3e007fff, 0x0904, x_Rs_x
, s7_do_rs
},
735 {"brmi", 0x00002808, 0x3e007fff, 0x0a04, x_Rs_x
, s7_do_rs
},
736 {"brpl", 0x00002c08, 0x3e007fff, 0x0b04, x_Rs_x
, s7_do_rs
},
737 {"brvs", 0x00003008, 0x3e007fff, 0x0c04, x_Rs_x
, s7_do_rs
},
738 {"brvc", 0x00003408, 0x3e007fff, 0x0d04, x_Rs_x
, s7_do_rs
},
739 {"brcnz", 0x00003808, 0x3e007fff, 0x0e04, x_Rs_x
, s7_do_rs
},
740 {"br", 0x00003c08, 0x3e007fff, 0x0f04, x_Rs_x
, s7_do_rs
},
741 {"brcsl", 0x00000009, 0x3e007fff, 0x000c, x_Rs_x
, s7_do_rs
},
742 {"brccl", 0x00000409, 0x3e007fff, 0x010c, x_Rs_x
, s7_do_rs
},
743 {"brgtul", 0x00000809, 0x3e007fff, 0x020c, x_Rs_x
, s7_do_rs
},
744 {"brleul", 0x00000c09, 0x3e007fff, 0x030c, x_Rs_x
, s7_do_rs
},
745 {"breql", 0x00001009, 0x3e007fff, 0x040c, x_Rs_x
, s7_do_rs
},
746 {"brnel", 0x00001409, 0x3e007fff, 0x050c, x_Rs_x
, s7_do_rs
},
747 {"brgtl", 0x00001809, 0x3e007fff, 0x060c, x_Rs_x
, s7_do_rs
},
748 {"brlel", 0x00001c09, 0x3e007fff, 0x070c, x_Rs_x
, s7_do_rs
},
749 {"brgel", 0x00002009, 0x3e007fff, 0x080c, x_Rs_x
, s7_do_rs
},
750 {"brltl", 0x00002409, 0x3e007fff, 0x090c, x_Rs_x
, s7_do_rs
},
751 {"brmil", 0x00002809, 0x3e007fff, 0x0a0c, x_Rs_x
, s7_do_rs
},
752 {"brpll", 0x00002c09, 0x3e007fff, 0x0b0c, x_Rs_x
, s7_do_rs
},
753 {"brvsl", 0x00003009, 0x3e007fff, 0x0c0c, x_Rs_x
, s7_do_rs
},
754 {"brvcl", 0x00003409, 0x3e007fff, 0x0d0c, x_Rs_x
, s7_do_rs
},
755 {"brcnzl", 0x00003809, 0x3e007fff, 0x0e0c, x_Rs_x
, s7_do_rs
},
756 {"brl", 0x00003c09, 0x3e007fff, 0x0f0c, x_Rs_x
, s7_do_rs
},
757 {"brcs!", 0x0004, 0x7f0f, 0x00000008, x_Rs
, s7_do16_xrs
},
758 {"brcc!", 0x0104, 0x7f0f, 0x00000408, x_Rs
, s7_do16_xrs
},
759 {"brgtu!", 0x0204, 0x7f0f, 0x00000808, x_Rs
, s7_do16_xrs
},
760 {"brleu!", 0x0304, 0x7f0f, 0x00000c08, x_Rs
, s7_do16_xrs
},
761 {"breq!", 0x0404, 0x7f0f, 0x00001008, x_Rs
, s7_do16_xrs
},
762 {"brne!", 0x0504, 0x7f0f, 0x00001408, x_Rs
, s7_do16_xrs
},
763 {"brgt!", 0x0604, 0x7f0f, 0x00001808, x_Rs
, s7_do16_xrs
},
764 {"brle!", 0x0704, 0x7f0f, 0x00001c08, x_Rs
, s7_do16_xrs
},
765 {"brge!", 0x0804, 0x7f0f, 0x00002008, x_Rs
, s7_do16_xrs
},
766 {"brlt!", 0x0904, 0x7f0f, 0x00002408, x_Rs
, s7_do16_xrs
},
767 {"brmi!", 0x0a04, 0x7f0f, 0x00002808, x_Rs
, s7_do16_xrs
},
768 {"brpl!", 0x0b04, 0x7f0f, 0x00002c08, x_Rs
, s7_do16_xrs
},
769 {"brvs!", 0x0c04, 0x7f0f, 0x00003008, x_Rs
, s7_do16_xrs
},
770 {"brvc!", 0x0d04, 0x7f0f, 0x00003408, x_Rs
, s7_do16_xrs
},
771 {"brcnz!", 0x0e04, 0x7f0f, 0x00003808, x_Rs
, s7_do16_xrs
},
772 {"br!", 0x0f04, 0x7f0f, 0x00003c08, x_Rs
, s7_do16_xrs
},
773 {"brcsl!", 0x000c, 0x7f0f, 0x00000009, x_Rs
, s7_do16_xrs
},
774 {"brccl!", 0x010c, 0x7f0f, 0x00000409, x_Rs
, s7_do16_xrs
},
775 {"brgtul!", 0x020c, 0x7f0f, 0x00000809, x_Rs
, s7_do16_xrs
},
776 {"brleul!", 0x030c, 0x7f0f, 0x00000c09, x_Rs
, s7_do16_xrs
},
777 {"breql!", 0x040c, 0x7f0f, 0x00001009, x_Rs
, s7_do16_xrs
},
778 {"brnel!", 0x050c, 0x7f0f, 0x00001409, x_Rs
, s7_do16_xrs
},
779 {"brgtl!", 0x060c, 0x7f0f, 0x00001809, x_Rs
, s7_do16_xrs
},
780 {"brlel!", 0x070c, 0x7f0f, 0x00001c09, x_Rs
, s7_do16_xrs
},
781 {"brgel!", 0x080c, 0x7f0f, 0x00002009, x_Rs
, s7_do16_xrs
},
782 {"brltl!", 0x090c, 0x7f0f, 0x00002409, x_Rs
, s7_do16_xrs
},
783 {"brmil!", 0x0a0c, 0x7f0f, 0x00002809, x_Rs
, s7_do16_xrs
},
784 {"brpll!", 0x0b0c, 0x7f0f, 0x00002c09, x_Rs
, s7_do16_xrs
},
785 {"brvsl!", 0x0c0c, 0x7f0f, 0x00003009, x_Rs
, s7_do16_xrs
},
786 {"brvcl!", 0x0d0c, 0x7f0f, 0x00003409, x_Rs
, s7_do16_xrs
},
787 {"brcnzl!", 0x0e0c, 0x7f0f, 0x00003809, x_Rs
, s7_do16_xrs
},
788 {"brl!", 0x0f0c, 0x7f0f, 0x00003c09, x_Rs
, s7_do16_xrs
},
789 {"bvs", 0x08003000, 0x3e007c01, 0x4000, PC_DISP19div2
, s7_do_branch
},
790 {"bvc", 0x08003400, 0x3e007c01, 0x4000, PC_DISP19div2
, s7_do_branch
},
791 {"bvsl", 0x08003001, 0x3e007c01, 0x8000, PC_DISP19div2
, s7_do_branch
},
792 {"bvcl", 0x08003401, 0x3e007c01, 0x8000, PC_DISP19div2
, s7_do_branch
},
793 {"bvs!", 0x4c00, 0x7f00, 0x08003000, PC_DISP8div2
, s7_do16_branch
},
794 {"bvc!", 0x4d00, 0x7f00, 0x08003400, PC_DISP8div2
, s7_do16_branch
},
795 {"b!", 0x4f00, 0x7f00, 0x08003c00, PC_DISP8div2
, s7_do16_branch
},
796 {"b", 0x08003c00, 0x3e007c01, 0x4000, PC_DISP19div2
, s7_do_branch
},
797 {"cache", 0x30000000, 0x3ff00000, 0x8000, OP5_rvalueRs_SI15
, s7_do_cache
},
798 {"ceinst", 0x38000000, 0x3e000000, 0x8000, I5_Rs_Rs_I5_OP5
, s7_do_ceinst
},
799 {"clz", 0x3800000d, 0x3e007fff, 0x8000, Rd_Rs_x
, s7_do_rdrs
},
800 {"cmpteq.c", 0x00000019, 0x3ff003ff, 0x8000, x_Rs_Rs
, s7_do_rsrs
},
801 {"cmptmi.c", 0x00100019, 0x3ff003ff, 0x8000, x_Rs_Rs
, s7_do_rsrs
},
802 {"cmp.c", 0x00300019, 0x3ff003ff, 0x2003, x_Rs_Rs
, s7_do_rsrs
},
803 {"cmpzteq.c", 0x0000001b, 0x3ff07fff, 0x8000, x_Rs_x
, s7_do_rs
},
804 {"cmpztmi.c", 0x0010001b, 0x3ff07fff, 0x8000, x_Rs_x
, s7_do_rs
},
805 {"cmpz.c", 0x0030001b, 0x3ff07fff, 0x8000, x_Rs_x
, s7_do_rs
},
806 {"cmpi.c", 0x02040001, 0x3e0e0001, 0x8000, Rd_SI16
, s7_do_rdsi16
},
807 {"cmp!", 0x2003, 0x700f, 0x00300019, Rd_Rs
, s7_do16_rdrs
},
808 {"cop1", 0x0c00000c, 0x3e00001f, 0x8000, Rd_Rs_Rs_imm
, s7_do_crdcrscrsimm5
},
809 {"cop2", 0x0c000014, 0x3e00001f, 0x8000, Rd_Rs_Rs_imm
, s7_do_crdcrscrsimm5
},
810 {"cop3", 0x0c00001c, 0x3e00001f, 0x8000, Rd_Rs_Rs_imm
, s7_do_crdcrscrsimm5
},
811 {"drte", 0x0c0000a4, 0x3e0003ff, 0x8000, NO_OPD
, s7_do_empty
},
812 {"extsb", 0x00000058, 0x3e0003ff, 0x8000, Rd_Rs_x
, s7_do_rdrs
},
813 {"extsb.c", 0x00000059, 0x3e0003ff, 0x8000, Rd_Rs_x
, s7_do_rdrs
},
814 {"extsh", 0x0000005a, 0x3e0003ff, 0x8000, Rd_Rs_x
, s7_do_rdrs
},
815 {"extsh.c", 0x0000005b, 0x3e0003ff, 0x8000, Rd_Rs_x
, s7_do_rdrs
},
816 {"extzb", 0x0000005c, 0x3e0003ff, 0x8000, Rd_Rs_x
, s7_do_rdrs
},
817 {"extzb.c", 0x0000005d, 0x3e0003ff, 0x8000, Rd_Rs_x
, s7_do_rdrs
},
818 {"extzh", 0x0000005e, 0x3e0003ff, 0x8000, Rd_Rs_x
, s7_do_rdrs
},
819 {"extzh.c", 0x0000005f, 0x3e0003ff, 0x8000, Rd_Rs_x
, s7_do_rdrs
},
820 {"jl", 0x04000001, 0x3e000001, 0x8000, PC_DISP24div2
, s7_do_jump
},
821 {"jl!", 0x3001, 0x7001, 0x04000001, PC_DISP11div2
, s7_do16_jump
},
822 {"j!", 0x3000, 0x7001, 0x04000000, PC_DISP11div2
, s7_do16_jump
},
823 {"j", 0x04000000, 0x3e000001, 0x8000, PC_DISP24div2
, s7_do_jump
},
824 {"lbu!", 0x200b, 0x0000700f, 0x2c000000, Rd_rvalueRs
, s7_do16_ldst_insn
},
825 {"lbup!", 0x7003, 0x7007, 0x2c000000, Rd_rvalueBP_I5
, s7_do16_ldst_imm_insn
},
826 {"alw", 0x0000000c, 0x3e0003ff, 0x8000, Rd_rvalue32Rs
, s7_do_ldst_atomic
},
827 {"lcb", 0x00000060, 0x3e0003ff, 0x8000, x_rvalueRs_post4
, s7_do_ldst_unalign
},
828 {"lcw", 0x00000062, 0x3e0003ff, 0x8000, Rd_rvalueRs_post4
, s7_do_ldst_unalign
},
829 {"lce", 0x00000066, 0x3e0003ff, 0x8000, Rd_rvalueRs_post4
, s7_do_ldst_unalign
},
830 {"ldc1", 0x0c00000a, 0x3e00001f, 0x8000, Rd_rvalueRs_SI10
, s7_do_ldst_cop
},
831 {"ldc2", 0x0c000012, 0x3e00001f, 0x8000, Rd_rvalueRs_SI10
, s7_do_ldst_cop
},
832 {"ldc3", 0x0c00001a, 0x3e00001f, 0x8000, Rd_rvalueRs_SI10
, s7_do_ldst_cop
},
833 {"lh!", 0x2009, 0x700f, 0x22000000, Rd_rvalueRs
, s7_do16_ldst_insn
},
834 {"lhp!", 0x7001, 0x7007, 0x22000000, Rd_rvalueBP_I5
, s7_do16_ldst_imm_insn
},
835 {"ldi", 0x020c0000, 0x3e0e0000, 0x5000, Rd_SI16
, s7_do_rdsi16
},
836 {"ldis", 0x0a0c0000, 0x3e0e0000, 0x8000, Rd_I16
, s7_do_rdi16
},
837 {"ldiu!", 0x5000, 0x7000, 0x020c0000, Rd_I8
, s7_do16_ldst_imm_insn
},
838 {"lw!", 0x2008, 0x700f, 0x20000000, Rd_rvalueRs
, s7_do16_ldst_insn
},
839 {"lwp!", 0x7000, 0x7007, 0x20000000, Rd_rvalueBP_I5
, s7_do16_ldst_imm_insn
},
840 {"mfcel", 0x00000448, 0x3e007fff, 0x8000, Rd_x_x
, s7_do_rd
},
841 {"mfcel!", 0x1001, 0x7f0f, 0x00000448, x_Rs
, s7_do16_rs
},
842 {"mad", 0x38000000, 0x3ff003ff, 0x8000, x_Rs_Rs
, s7_do_rsrs
},
843 {"mad.f!", 0x1004, 0x700f, 0x38000080, Rd_Rs
, s7_do16_rdrs
},
844 {"madh", 0x38000203, 0x3ff003ff, 0x8000, x_Rs_Rs
, s7_do_rsrs
},
845 {"madh.fs", 0x380002c3, 0x3ff003ff, 0x8000, x_Rs_Rs
, s7_do_rsrs
},
846 {"madh.fs!", 0x100b, 0x700f, 0x380002c3, Rd_Rs
, s7_do16_rdrs
},
847 {"madl", 0x38000002, 0x3ff003ff, 0x8000, x_Rs_Rs
, s7_do_rsrs
},
848 {"madl.fs", 0x380000c2, 0x3ff003ff, 0x8000, x_Rs_Rs
, s7_do_rsrs
},
849 {"madl.fs!", 0x100a, 0x700f, 0x380000c2, Rd_Rs
, s7_do16_rdrs
},
850 {"madu", 0x38000020, 0x3ff003ff, 0x8000, x_Rs_Rs
, s7_do_rsrs
},
851 {"madu!", 0x1005, 0x700f, 0x38000020, Rd_Rs
, s7_do16_rdrs
},
852 {"mad.f", 0x38000080, 0x3ff003ff, 0x8000, x_Rs_Rs
, s7_do_rsrs
},
853 {"max", 0x38000007, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s7_do_rdrsrs
},
854 {"mazh", 0x38000303, 0x3ff003ff, 0x8000, x_Rs_Rs
, s7_do_rsrs
},
855 {"mazh.f", 0x38000383, 0x3ff003ff, 0x8000, x_Rs_Rs
, s7_do_rsrs
},
856 {"mazh.f!", 0x1009, 0x700f, 0x38000383, Rd_Rs
, s7_do16_rdrs
},
857 {"mazl", 0x38000102, 0x3ff003ff, 0x8000, x_Rs_Rs
, s7_do_rsrs
},
858 {"mazl.f", 0x38000182, 0x3ff003ff, 0x8000, x_Rs_Rs
, s7_do_rsrs
},
859 {"mazl.f!", 0x1008, 0x700f, 0x38000182, Rd_Rs
, s7_do16_rdrs
},
860 {"mfceh", 0x00000848, 0x3e007fff, 0x8000, Rd_x_x
, s7_do_rd
},
861 {"mfceh!", 0x1101, 0x7f0f, 0x00000848, x_Rs
, s7_do16_rs
},
862 {"mfcehl", 0x00000c48, 0x3e007fff, 0x8000, Rd_Rs_x
, s7_do_rdrs
},
863 {"mfsr", 0x00000050, 0x3e0003ff, 0x8000, Rd_x_I5
, s7_do_rdsrs
},
864 {"mfcr", 0x0c000001, 0x3e00001f, 0x8000, Rd_Rs_x
, s7_do_rdcrs
},
865 {"mfc1", 0x0c000009, 0x3e00001f, 0x8000, Rd_Rs_x
, s7_do_rdcrs
},
866 {"mfc2", 0x0c000011, 0x3e00001f, 0x8000, Rd_Rs_x
, s7_do_rdcrs
},
867 {"mfc3", 0x0c000019, 0x3e00001f, 0x8000, Rd_Rs_x
, s7_do_rdcrs
},
868 {"mfcc1", 0x0c00000f, 0x3e00001f, 0x8000, Rd_Rs_x
, s7_do_rdcrs
},
869 {"mfcc2", 0x0c000017, 0x3e00001f, 0x8000, Rd_Rs_x
, s7_do_rdcrs
},
870 {"mfcc3", 0x0c00001f, 0x3e00001f, 0x8000, Rd_Rs_x
, s7_do_rdcrs
},
871 {"mhfl!", 0x0002, 0x700f, 0x00003c56, Rd_LowRs
, s7_do16_hrdrs
},
872 {"min", 0x38000006, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s7_do_rdrsrs
},
873 {"mlfh!", 0x0001, 0x700f, 0x00003c56, Rd_HighRs
, s7_do16_rdhrs
},
874 {"msb", 0x38000001, 0x3ff003ff, 0x8000, x_Rs_Rs
, s7_do_rsrs
},
875 {"msb.f!", 0x1006, 0x700f, 0x38000081, Rd_Rs
, s7_do16_rdrs
},
876 {"msbh", 0x38000205, 0x3ff003ff, 0x8000, x_Rs_Rs
, s7_do_rsrs
},
877 {"msbh.fs", 0x380002c5, 0x3ff003ff, 0x8000, x_Rs_Rs
, s7_do_rsrs
},
878 {"msbh.fs!", 0x100f, 0x700f, 0x380002c5, Rd_Rs
, s7_do16_rdrs
},
879 {"msbl", 0x38000004, 0x3ff003ff, 0x8000, x_Rs_Rs
, s7_do_rsrs
},
880 {"msbl.fs", 0x380000c4, 0x3ff003ff, 0x8000, x_Rs_Rs
, s7_do_rsrs
},
881 {"msbl.fs!", 0x100e, 0x700f, 0x380000c4, Rd_Rs
, s7_do16_rdrs
},
882 {"msbu", 0x38000021, 0x3ff003ff, 0x8000, x_Rs_Rs
, s7_do_rsrs
},
883 {"msbu!", 0x1007, 0x700f, 0x38000021, Rd_Rs
, s7_do16_rdrs
},
884 {"msb.f", 0x38000081, 0x3ff003ff, 0x8000, x_Rs_Rs
, s7_do_rsrs
},
885 {"mszh", 0x38000305, 0x3ff003ff, 0x8000, x_Rs_Rs
, s7_do_rsrs
},
886 {"mszh.f", 0x38000385, 0x3ff003ff, 0x8000, x_Rs_Rs
, s7_do_rsrs
},
887 {"mszh.f!", 0x100d, 0x700f, 0x38000385, Rd_Rs
, s7_do16_rdrs
},
888 {"mszl", 0x38000104, 0x3ff003ff, 0x8000, x_Rs_Rs
, s7_do_rsrs
},
889 {"mszl.f", 0x38000184, 0x3ff003ff, 0x8000, x_Rs_Rs
, s7_do_rsrs
},
890 {"mszl.f!", 0x100c, 0x700f, 0x38000184, Rd_Rs
, s7_do16_rdrs
},
891 {"mtcel!", 0x1000, 0x7f0f, 0x0000044a, x_Rs
, s7_do16_rs
},
892 {"mtcel", 0x0000044a, 0x3e007fff, 0x8000, Rd_x_x
, s7_do_rd
},
893 {"mtceh", 0x0000084a, 0x3e007fff, 0x8000, Rd_x_x
, s7_do_rd
},
894 {"mtceh!", 0x1100, 0x7f0f, 0x0000084a, x_Rs
, s7_do16_rs
},
895 {"mtcehl", 0x00000c4a, 0x3e007fff, 0x8000, Rd_Rs_x
, s7_do_rdrs
},
896 {"mtsr", 0x00000052, 0x3e0003ff, 0x8000, x_Rs_I5
, s7_do_rdsrs
},
897 {"mtcr", 0x0c000000, 0x3e00001f, 0x8000, Rd_Rs_x
, s7_do_rdcrs
},
898 {"mtc1", 0x0c000008, 0x3e00001f, 0x8000, Rd_Rs_x
, s7_do_rdcrs
},
899 {"mtc2", 0x0c000010, 0x3e00001f, 0x8000, Rd_Rs_x
, s7_do_rdcrs
},
900 {"mtc3", 0x0c000018, 0x3e00001f, 0x8000, Rd_Rs_x
, s7_do_rdcrs
},
901 {"mtcc1", 0x0c00000e, 0x3e00001f, 0x8000, Rd_Rs_x
, s7_do_rdcrs
},
902 {"mtcc2", 0x0c000016, 0x3e00001f, 0x8000, Rd_Rs_x
, s7_do_rdcrs
},
903 {"mtcc3", 0x0c00001e, 0x3e00001f, 0x8000, Rd_Rs_x
, s7_do_rdcrs
},
904 {"mul.f!", 0x1002, 0x700f, 0x00000041, Rd_Rs
, s7_do16_rdrs
},
905 {"mulu!", 0x1003, 0x700f, 0x00000042, Rd_Rs
, s7_do16_rdrs
},
906 {"mvcs", 0x00000056, 0x3e007fff, 0x8000, Rd_Rs_x
, s7_do_rdrs
},
907 {"mvcc", 0x00000456, 0x3e007fff, 0x8000, Rd_Rs_x
, s7_do_rdrs
},
908 {"mvgtu", 0x00000856, 0x3e007fff, 0x8000, Rd_Rs_x
, s7_do_rdrs
},
909 {"mvleu", 0x00000c56, 0x3e007fff, 0x8000, Rd_Rs_x
, s7_do_rdrs
},
910 {"mveq", 0x00001056, 0x3e007fff, 0x8000, Rd_Rs_x
, s7_do_rdrs
},
911 {"mvne", 0x00001456, 0x3e007fff, 0x8000, Rd_Rs_x
, s7_do_rdrs
},
912 {"mvgt", 0x00001856, 0x3e007fff, 0x8000, Rd_Rs_x
, s7_do_rdrs
},
913 {"mvle", 0x00001c56, 0x3e007fff, 0x8000, Rd_Rs_x
, s7_do_rdrs
},
914 {"mvge", 0x00002056, 0x3e007fff, 0x8000, Rd_Rs_x
, s7_do_rdrs
},
915 {"mvlt", 0x00002456, 0x3e007fff, 0x8000, Rd_Rs_x
, s7_do_rdrs
},
916 {"mvmi", 0x00002856, 0x3e007fff, 0x8000, Rd_Rs_x
, s7_do_rdrs
},
917 {"mvpl", 0x00002c56, 0x3e007fff, 0x8000, Rd_Rs_x
, s7_do_rdrs
},
918 {"mvvs", 0x00003056, 0x3e007fff, 0x8000, Rd_Rs_x
, s7_do_rdrs
},
919 {"mvvc", 0x00003456, 0x3e007fff, 0x8000, Rd_Rs_x
, s7_do_rdrs
},
920 {"mv", 0x00003c56, 0x3e007fff, 0x0003, Rd_Rs_x
, s7_do_rdrs
},
921 {"mv!", 0x0003, 0x700f, 0x00003c56, Rd_Rs
, s7_do16_mv_rdrs
},
922 {"neg", 0x0000001e, 0x3e0003ff, 0x8000, Rd_x_Rs
, s7_do_rdxrs
},
923 {"neg.c", 0x0000001f, 0x3e0003ff, 0x2002, Rd_x_Rs
, s7_do_rdxrs
},
924 {"neg!", 0x2002, 0x700f, 0x0000001f, Rd_Rs
, s7_do16_rdrs
},
925 {"nop", 0x00000000, 0x3e0003ff, 0x0000, NO_OPD
, s7_do_empty
},
926 {"not", 0x00000024, 0x3e0003ff, 0x8000, Rd_Rs_x
, s7_do_rdrs
},
927 {"not.c", 0x00000025, 0x3e0003ff, 0x2006, Rd_Rs_x
, s7_do_rdrs
},
928 {"nop!", 0x0000, 0x700f, 0x00000000, NO16_OPD
, s7_do_empty
},
929 {"not!", 0x2006, 0x700f, 0x00000025, Rd_Rs
, s7_do16_rdrs
},
930 {"or", 0x00000022, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s7_do_rdrsrs
},
931 {"or.c", 0x00000023, 0x3e0003ff, 0x2005, Rd_Rs_Rs
, s7_do_rdrsrs
},
932 {"ori", 0x020a0000, 0x3e0e0001, 0x8000, Rd_I16
, s7_do_rdi16
},
933 {"ori.c", 0x020a0001, 0x3e0e0001, 0x8000, Rd_I16
, s7_do_rdi16
},
934 {"oris", 0x0a0a0000, 0x3e0e0001, 0x8000, Rd_I16
, s7_do_rdi16
},
935 {"oris.c", 0x0a0a0001, 0x3e0e0001, 0x8000, Rd_I16
, s7_do_rdi16
},
936 {"orri", 0x1a000000, 0x3e000001, 0x8000, Rd_Rs_I14
, s7_do_rdrsi14
},
937 {"orri.c", 0x1a000001, 0x3e000001, 0x8000, Rd_Rs_I14
, s7_do_rdrsi14
},
938 {"or!", 0x2005, 0x700f, 0x00000023, Rd_Rs
, s7_do16_rdrs
},
939 {"pflush", 0x0000000a, 0x3e0003ff, 0x8000, NO_OPD
, s7_do_empty
},
940 {"pop!", 0x200a, 0x700f, 0x0e000000, Rd_rvalueRs
, s7_do16_push_pop
},
941 {"push!", 0x200e, 0x700f, 0x06000004, Rd_lvalueRs
, s7_do16_push_pop
},
942 {"ror", 0x00000038, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s7_do_rdrsrs
},
943 {"ror.c", 0x00000039, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s7_do_rdrsrs
},
944 {"rorc.c", 0x0000003b, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s7_do_rdrsrs
},
945 {"rol", 0x0000003c, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s7_do_rdrsrs
},
946 {"rol.c", 0x0000003d, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s7_do_rdrsrs
},
947 {"rolc.c", 0x0000003f, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s7_do_rdrsrs
},
948 {"rori", 0x00000078, 0x3e0003ff, 0x8000, Rd_Rs_I5
, s7_do_rdrsi5
},
949 {"rori.c", 0x00000079, 0x3e0003ff, 0x8000, Rd_Rs_I5
, s7_do_rdrsi5
},
950 {"roric.c", 0x0000007b, 0x3e0003ff, 0x8000, Rd_Rs_I5
, s7_do_rdrsi5
},
951 {"roli", 0x0000007c, 0x3e0003ff, 0x8000, Rd_Rs_I5
, s7_do_rdrsi5
},
952 {"roli.c", 0x0000007d, 0x3e0003ff, 0x8000, Rd_Rs_I5
, s7_do_rdrsi5
},
953 {"rolic.c", 0x0000007f, 0x3e0003ff, 0x8000, Rd_Rs_I5
, s7_do_rdrsi5
},
954 {"rte", 0x0c000084, 0x3e0003ff, 0x8000, NO_OPD
, s7_do_empty
},
955 {"sb!", 0x200f, 0x700f, 0x2e000000, Rd_lvalueRs
, s7_do16_ldst_insn
},
956 {"sbp!", 0x7007, 0x7007, 0x2e000000, Rd_lvalueBP_I5
, s7_do16_ldst_imm_insn
},
957 {"asw", 0x0000000e, 0x3e0003ff, 0x8000, Rd_lvalue32Rs
, s7_do_ldst_atomic
},
958 {"scb", 0x00000068, 0x3e0003ff, 0x8000, Rd_lvalueRs_post4
, s7_do_ldst_unalign
},
959 {"scw", 0x0000006a, 0x3e0003ff, 0x8000, Rd_lvalueRs_post4
, s7_do_ldst_unalign
},
960 {"sce", 0x0000006e, 0x3e0003ff, 0x8000, x_lvalueRs_post4
, s7_do_ldst_unalign
},
961 {"sdbbp", 0x00000006, 0x3e0003ff, 0x6002, x_I5_x
, s7_do_xi5x
},
962 {"sdbbp!", 0x6002, 0x7007, 0x00000006, Rd_I5
, s7_do16_xi5
},
963 {"sh!", 0x200d, 0x700f, 0x2a000000, Rd_lvalueRs
, s7_do16_ldst_insn
},
964 {"shp!", 0x7005, 0x7007, 0x2a000000, Rd_lvalueBP_I5
, s7_do16_ldst_imm_insn
},
965 {"sleep", 0x0c0000c4, 0x3e0003ff, 0x8000, NO_OPD
, s7_do_empty
},
966 {"sll", 0x00000030, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s7_do_rdrsrs
},
967 {"sll.c", 0x00000031, 0x3e0003ff, 0x0008, Rd_Rs_Rs
, s7_do_rdrsrs
},
968 {"sll.s", 0x3800004e, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s7_do_rdrsrs
},
969 {"slli", 0x00000070, 0x3e0003ff, 0x8000, Rd_Rs_I5
, s7_do_rdrsi5
},
970 {"slli.c", 0x00000071, 0x3e0003ff, 0x6001, Rd_Rs_I5
, s7_do_rdrsi5
},
971 {"sll!", 0x0008, 0x700f, 0x00000031, Rd_Rs
, s7_do16_rdrs
},
972 {"slli!", 0x6001, 0x7007, 0x00000071, Rd_I5
, s7_do16_rdi5
},
973 {"srl", 0x00000034, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s7_do_rdrsrs
},
974 {"srl.c", 0x00000035, 0x3e0003ff, 0x000a, Rd_Rs_Rs
, s7_do_rdrsrs
},
975 {"sra", 0x00000036, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s7_do_rdrsrs
},
976 {"sra.c", 0x00000037, 0x3e0003ff, 0x000b, Rd_Rs_Rs
, s7_do_rdrsrs
},
977 {"srli", 0x00000074, 0x3e0003ff, 0x8000, Rd_Rs_I5
, s7_do_rdrsi5
},
978 {"srli.c", 0x00000075, 0x3e0003ff, 0x6003, Rd_Rs_I5
, s7_do_rdrsi5
},
979 {"srai", 0x00000076, 0x3e0003ff, 0x8000, Rd_Rs_I5
, s7_do_rdrsi5
},
980 {"srai.c", 0x00000077, 0x3e0003ff, 0x8000, Rd_Rs_I5
, s7_do_rdrsi5
},
981 {"srl!", 0x000a, 0x700f, 0x00000035, Rd_Rs
, s7_do16_rdrs
},
982 {"sra!", 0x000b, 0x700f, 0x00000037, Rd_Rs
, s7_do16_rdrs
},
983 {"srli!", 0x6003, 0x7007, 0x00000075, Rd_Rs
, s7_do16_rdi5
},
984 {"stc1", 0x0c00000b, 0x3e00001f, 0x8000, Rd_lvalueRs_SI10
, s7_do_ldst_cop
},
985 {"stc2", 0x0c000013, 0x3e00001f, 0x8000, Rd_lvalueRs_SI10
, s7_do_ldst_cop
},
986 {"stc3", 0x0c00001b, 0x3e00001f, 0x8000, Rd_lvalueRs_SI10
, s7_do_ldst_cop
},
987 {"sub", 0x00000014, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s7_do_rdrsrs
},
988 {"sub.c", 0x00000015, 0x3e0003ff, 0x2001, Rd_Rs_Rs
, s7_do_rdrsrs
},
989 {"sub.s", 0x38000049, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s7_do_rdrsrs
},
990 {"subc", 0x00000016, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s7_do_rdrsrs
},
991 {"subc.c", 0x00000017, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s7_do_rdrsrs
},
992 {"sub!", 0x2001, 0x700f, 0x00000015, Rd_Rs
, s7_do16_rdrs
},
993 {"subei!", 0x6080, 0x7087, 0x02000001, Rd_I4
, s7_do16_rdi4
},
994 {"sw!", 0x200c, 0x700f, 0x28000000, Rd_lvalueRs
, s7_do16_ldst_insn
},
995 {"swp!", 0x7004, 0x7007, 0x28000000, Rd_lvalueBP_I5
, s7_do16_ldst_imm_insn
},
996 {"syscall", 0x00000002, 0x3e0003ff, 0x8000, I15
, s7_do_i15
},
997 {"tcs", 0x00000054, 0x3e007fff, 0x0005, NO_OPD
, s7_do_empty
},
998 {"tcc", 0x00000454, 0x3e007fff, 0x0105, NO_OPD
, s7_do_empty
},
999 {"tcnz", 0x00003854, 0x3e007fff, 0x0e05, NO_OPD
, s7_do_empty
},
1000 {"tcs!", 0x0005, 0x7f0f, 0x00000054, NO16_OPD
, s7_do_empty
},
1001 {"tcc!", 0x0105, 0x7f0f, 0x00000454, NO16_OPD
, s7_do_empty
},
1002 {"tcnz!", 0x0e05, 0x7f0f, 0x00003854, NO16_OPD
, s7_do_empty
},
1003 {"teq", 0x00001054, 0x3e007fff, 0x0405, NO_OPD
, s7_do_empty
},
1004 {"teq!", 0x0405, 0x7f0f, 0x00001054, NO16_OPD
, s7_do_empty
},
1005 {"tgtu", 0x00000854, 0x3e007fff, 0x0205, NO_OPD
, s7_do_empty
},
1006 {"tgt", 0x00001854, 0x3e007fff, 0x0605, NO_OPD
, s7_do_empty
},
1007 {"tge", 0x00002054, 0x3e007fff, 0x0805, NO_OPD
, s7_do_empty
},
1008 {"tgtu!", 0x0205, 0x7f0f, 0x00000854, NO16_OPD
, s7_do_empty
},
1009 {"tgt!", 0x0605, 0x7f0f, 0x00001854, NO16_OPD
, s7_do_empty
},
1010 {"tge!", 0x0805, 0x7f0f, 0x00002054, NO16_OPD
, s7_do_empty
},
1011 {"tleu", 0x00000c54, 0x3e007fff, 0x0305, NO_OPD
, s7_do_empty
},
1012 {"tle", 0x00001c54, 0x3e007fff, 0x0705, NO_OPD
, s7_do_empty
},
1013 {"tlt", 0x00002454, 0x3e007fff, 0x0905, NO_OPD
, s7_do_empty
},
1014 {"stlb", 0x0c000004, 0x3e0003ff, 0x8000, NO_OPD
, s7_do_empty
},
1015 {"mftlb", 0x0c000024, 0x3e0003ff, 0x8000, NO_OPD
, s7_do_empty
},
1016 {"mtptlb", 0x0c000044, 0x3e0003ff, 0x8000, NO_OPD
, s7_do_empty
},
1017 {"mtrtlb", 0x0c000064, 0x3e0003ff, 0x8000, NO_OPD
, s7_do_empty
},
1018 {"tleu!", 0x0305, 0x7f0f, 0x00000c54, NO16_OPD
, s7_do_empty
},
1019 {"tle!", 0x0705, 0x7f0f, 0x00001c54, NO16_OPD
, s7_do_empty
},
1020 {"tlt!", 0x0905, 0x7f0f, 0x00002454, NO16_OPD
, s7_do_empty
},
1021 {"tmi", 0x00002854, 0x3e007fff, 0x0a05, NO_OPD
, s7_do_empty
},
1022 {"tmi!", 0x0a05, 0x7f0f, 0x00002854, NO16_OPD
, s7_do_empty
},
1023 {"tne", 0x00001454, 0x3e007fff, 0x0505, NO_OPD
, s7_do_empty
},
1024 {"tne!", 0x0505, 0x7f0f, 0x00001454, NO16_OPD
, s7_do_empty
},
1025 {"tpl", 0x00002c54, 0x3e007fff, 0x0b05, NO_OPD
, s7_do_empty
},
1026 {"tpl!", 0x0b05, 0x7f0f, 0x00002c54, NO16_OPD
, s7_do_empty
},
1027 {"trapcs", 0x00000004, 0x3e007fff, 0x8000, x_I5_x
, s7_do_xi5x
},
1028 {"trapcc", 0x00000404, 0x3e007fff, 0x8000, x_I5_x
, s7_do_xi5x
},
1029 {"trapgtu", 0x00000804, 0x3e007fff, 0x8000, x_I5_x
, s7_do_xi5x
},
1030 {"trapleu", 0x00000c04, 0x3e007fff, 0x8000, x_I5_x
, s7_do_xi5x
},
1031 {"trapeq", 0x00001004, 0x3e007fff, 0x8000, x_I5_x
, s7_do_xi5x
},
1032 {"trapne", 0x00001404, 0x3e007fff, 0x8000, x_I5_x
, s7_do_xi5x
},
1033 {"trapgt", 0x00001804, 0x3e007fff, 0x8000, x_I5_x
, s7_do_xi5x
},
1034 {"traple", 0x00001c04, 0x3e007fff, 0x8000, x_I5_x
, s7_do_xi5x
},
1035 {"trapge", 0x00002004, 0x3e007fff, 0x8000, x_I5_x
, s7_do_xi5x
},
1036 {"traplt", 0x00002404, 0x3e007fff, 0x8000, x_I5_x
, s7_do_xi5x
},
1037 {"trapmi", 0x00002804, 0x3e007fff, 0x8000, x_I5_x
, s7_do_xi5x
},
1038 {"trappl", 0x00002c04, 0x3e007fff, 0x8000, x_I5_x
, s7_do_xi5x
},
1039 {"trapvs", 0x00003004, 0x3e007fff, 0x8000, x_I5_x
, s7_do_xi5x
},
1040 {"trapvc", 0x00003404, 0x3e007fff, 0x8000, x_I5_x
, s7_do_xi5x
},
1041 {"trap", 0x00003c04, 0x3e007fff, 0x8000, x_I5_x
, s7_do_xi5x
},
1042 {"tset", 0x00003c54, 0x3e007fff, 0x0f05, NO_OPD
, s7_do_empty
},
1043 {"tset!", 0x0f05, 0x00007f0f, 0x00003c54, NO16_OPD
, s7_do_empty
},
1044 {"tvs", 0x00003054, 0x3e007fff, 0x0c05, NO_OPD
, s7_do_empty
},
1045 {"tvc", 0x00003454, 0x3e007fff, 0x0d05, NO_OPD
, s7_do_empty
},
1046 {"tvs!", 0x0c05, 0x7f0f, 0x00003054, NO16_OPD
, s7_do_empty
},
1047 {"tvc!", 0x0d05, 0x7f0f, 0x00003454, NO16_OPD
, s7_do_empty
},
1048 {"xor", 0x00000026, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s7_do_rdrsrs
},
1049 {"xor.c", 0x00000027, 0x3e0003ff, 0x2007, Rd_Rs_Rs
, s7_do_rdrsrs
},
1050 {"xor!", 0x2007, 0x700f, 0x00000027, Rd_Rs
, s7_do16_rdrs
},
1051 /* Macro instruction. */
1052 {"li", 0x020c0000, 0x3e0e0000, 0x8000, Insn_Type_SYN
, s7_do_macro_li_rdi32
},
1053 /* la reg, imm32 -->(1) ldi reg, simm16
1054 (2) ldis reg, %HI(imm32)
1057 la reg, symbol -->(1) lis reg, %HI(imm32)
1058 ori reg, %LO(imm32) */
1059 {"la", 0x020c0000, 0x3e0e0000, 0x8000, Insn_Type_SYN
, s7_do_macro_la_rdi32
},
1060 {"div", 0x00000044, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s7_do_macro_mul_rdrsrs
},
1061 {"divu", 0x00000046, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s7_do_macro_mul_rdrsrs
},
1062 {"rem", 0x00000044, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s7_do_macro_mul_rdrsrs
},
1063 {"remu", 0x00000046, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s7_do_macro_mul_rdrsrs
},
1064 {"mul", 0x00000040, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s7_do_macro_mul_rdrsrs
},
1065 {"mulu", 0x00000042, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s7_do_macro_mul_rdrsrs
},
1066 {"maz", 0x00000040, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s7_do_macro_mul_rdrsrs
},
1067 {"mazu", 0x00000042, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s7_do_macro_mul_rdrsrs
},
1068 {"mul.f", 0x00000041, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s7_do_macro_mul_rdrsrs
},
1069 {"maz.f", 0x00000041, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s7_do_macro_mul_rdrsrs
},
1070 {"lb", INSN_LB
, 0x00000000, 0x8000, Insn_Type_SYN
, s7_do_macro_ldst_label
},
1071 {"lbu", INSN_LBU
, 0x00000000, 0x200b, Insn_Type_SYN
, s7_do_macro_ldst_label
},
1072 {"lh", INSN_LH
, 0x00000000, 0x2009, Insn_Type_SYN
, s7_do_macro_ldst_label
},
1073 {"lhu", INSN_LHU
, 0x00000000, 0x8000, Insn_Type_SYN
, s7_do_macro_ldst_label
},
1074 {"lw", INSN_LW
, 0x00000000, 0x2008, Insn_Type_SYN
, s7_do_macro_ldst_label
},
1075 {"sb", INSN_SB
, 0x00000000, 0x200f, Insn_Type_SYN
, s7_do_macro_ldst_label
},
1076 {"sh", INSN_SH
, 0x00000000, 0x200d, Insn_Type_SYN
, s7_do_macro_ldst_label
},
1077 {"sw", INSN_SW
, 0x00000000, 0x200c, Insn_Type_SYN
, s7_do_macro_ldst_label
},
1078 /* Assembler use internal. */
1079 {"ld_i32hi", 0x0a0c0000, 0x3e0e0000, 0x8000, Insn_internal
, s7_do_macro_rdi32hi
},
1080 {"ld_i32lo", 0x020a0000, 0x3e0e0001, 0x8000, Insn_internal
, s7_do_macro_rdi32lo
},
1081 {"ldis_pic", 0x0a0c0000, 0x3e0e0000, 0x5000, Insn_internal
, s7_do_rdi16_pic
},
1082 {"addi_s_pic",0x02000000, 0x3e0e0001, 0x8000, Insn_internal
, s7_do_addi_s_pic
},
1083 {"addi_u_pic",0x02000000, 0x3e0e0001, 0x8000, Insn_internal
, s7_do_addi_u_pic
},
1084 {"lw_pic", 0x20000000, 0x3e000000, 0x8000, Insn_internal
, s7_do_lw_pic
},
1087 #define s7_SCORE5_PIPELINE 5
1088 #define s7_SCORE7_PIPELINE 7
1090 static int s7_university_version
= 0;
1091 static int s7_vector_size
= s7_SCORE7_PIPELINE
;
1092 static struct s7_score_it s7_dependency_vector
[s7_SCORE7_PIPELINE
];
1094 static int s7_score7d
= 1;
1099 s7_end_of_line (char *str
)
1101 int retval
= s7_SUCCESS
;
1103 s7_skip_whitespace (str
);
1106 retval
= (int) s7_FAIL
;
1109 s7_inst
.error
= s7_BAD_GARBAGE
;
1116 s7_score_reg_parse (char **ccp
, struct hash_control
*htab
)
1121 struct s7_reg_entry
*reg
;
1124 if (!ISALPHA (*p
) || !is_name_beginner (*p
))
1125 return (int) s7_FAIL
;
1129 while (ISALPHA (c
) || ISDIGIT (c
) || c
== '_')
1133 reg
= (struct s7_reg_entry
*) hash_find (htab
, start
);
1141 return (int) s7_FAIL
;
1144 /* If shift <= 0, only return reg. */
1146 s7_reg_required_here (char **str
, int shift
, enum s7_score_reg_type reg_type
)
1148 static char buff
[s7_MAX_LITERAL_POOL_SIZE
];
1149 int reg
= (int) s7_FAIL
;
1152 if ((reg
= s7_score_reg_parse (str
, s7_all_reg_maps
[reg_type
].htab
)) != (int) s7_FAIL
)
1154 if (reg_type
== s7_REG_TYPE_SCORE
)
1156 if ((reg
== 1) && (s7_nor1
== 1) && (s7_inst
.bwarn
== 0))
1158 as_warn (_("Using temp register(r1)"));
1164 if (reg_type
== s7_REG_TYPE_SCORE_CR
)
1165 strcpy (s7_inst
.reg
, s7_score_crn_table
[reg
].name
);
1166 else if (reg_type
== s7_REG_TYPE_SCORE_SR
)
1167 strcpy (s7_inst
.reg
, s7_score_srn_table
[reg
].name
);
1169 strcpy (s7_inst
.reg
, "");
1171 s7_inst
.instruction
|= reg
<< shift
;
1177 sprintf (buff
, _("register expected, not '%.100s'"), start
);
1178 s7_inst
.error
= buff
;
1185 s7_skip_past_comma (char **str
)
1191 while ((c
= *p
) == ' ' || c
== ',')
1194 if (c
== ',' && comma
++)
1196 s7_inst
.error
= s7_BAD_SKIP_COMMA
;
1197 return (int) s7_FAIL
;
1201 if ((c
== '\0') || (comma
== 0))
1203 s7_inst
.error
= s7_BAD_SKIP_COMMA
;
1204 return (int) s7_FAIL
;
1208 return comma
? s7_SUCCESS
: (int) s7_FAIL
;
1212 s7_do_rdrsrs (char *str
)
1214 s7_skip_whitespace (str
);
1216 if (s7_reg_required_here (&str
, 20, s7_REG_TYPE_SCORE
) == (int) s7_FAIL
1217 || s7_skip_past_comma (&str
) == (int) s7_FAIL
1218 || s7_reg_required_here (&str
, 15, s7_REG_TYPE_SCORE
) == (int) s7_FAIL
1219 || s7_skip_past_comma (&str
) == (int) s7_FAIL
1220 || s7_reg_required_here (&str
, 10, s7_REG_TYPE_SCORE
) == (int) s7_FAIL
1221 || s7_end_of_line (str
) == (int) s7_FAIL
)
1227 if ((((s7_inst
.instruction
>> 15) & 0x10) == 0)
1228 && (((s7_inst
.instruction
>> 10) & 0x10) == 0)
1229 && (((s7_inst
.instruction
>> 20) & 0x10) == 0)
1230 && (s7_inst
.relax_inst
!= 0x8000)
1231 && (((s7_inst
.instruction
>> 20) & 0xf) == ((s7_inst
.instruction
>> 15) & 0xf)))
1233 s7_inst
.relax_inst
|= (((s7_inst
.instruction
>> 10) & 0xf) << 4)
1234 | (((s7_inst
.instruction
>> 15) & 0xf) << 8);
1235 s7_inst
.relax_size
= 2;
1239 s7_inst
.relax_inst
= 0x8000;
1245 s7_walk_no_bignums (symbolS
* sp
)
1247 if (symbol_get_value_expression (sp
)->X_op
== O_big
)
1250 if (symbol_get_value_expression (sp
)->X_add_symbol
)
1251 return (s7_walk_no_bignums (symbol_get_value_expression (sp
)->X_add_symbol
)
1252 || (symbol_get_value_expression (sp
)->X_op_symbol
1253 && s7_walk_no_bignums (symbol_get_value_expression (sp
)->X_op_symbol
)));
1259 s7_my_get_expression (expressionS
* ep
, char **str
)
1263 save_in
= input_line_pointer
;
1264 input_line_pointer
= *str
;
1265 s7_in_my_get_expression
= 1;
1267 (void) expression (ep
);
1268 s7_in_my_get_expression
= 0;
1270 if (ep
->X_op
== O_illegal
)
1272 *str
= input_line_pointer
;
1273 input_line_pointer
= save_in
;
1274 s7_inst
.error
= _("illegal expression");
1275 return (int) s7_FAIL
;
1277 /* Get rid of any bignums now, so that we don't generate an error for which
1278 we can't establish a line number later on. Big numbers are never valid
1279 in instructions, which is where this routine is always called. */
1280 if (ep
->X_op
== O_big
1281 || (ep
->X_add_symbol
1282 && (s7_walk_no_bignums (ep
->X_add_symbol
)
1283 || (ep
->X_op_symbol
&& s7_walk_no_bignums (ep
->X_op_symbol
)))))
1285 s7_inst
.error
= _("invalid constant");
1286 *str
= input_line_pointer
;
1287 input_line_pointer
= save_in
;
1288 return (int) s7_FAIL
;
1291 if ((ep
->X_add_symbol
!= NULL
)
1292 && (s7_inst
.type
!= PC_DISP19div2
)
1293 && (s7_inst
.type
!= PC_DISP8div2
)
1294 && (s7_inst
.type
!= PC_DISP24div2
)
1295 && (s7_inst
.type
!= PC_DISP11div2
)
1296 && (s7_inst
.type
!= Insn_Type_SYN
)
1297 && (s7_inst
.type
!= Rd_rvalueRs_SI15
)
1298 && (s7_inst
.type
!= Rd_lvalueRs_SI15
)
1299 && (s7_inst
.type
!= Insn_internal
))
1301 s7_inst
.error
= s7_BAD_ARGS
;
1302 *str
= input_line_pointer
;
1303 input_line_pointer
= save_in
;
1304 return (int) s7_FAIL
;
1307 *str
= input_line_pointer
;
1308 input_line_pointer
= save_in
;
1312 /* Check if an immediate is valid. If so, convert it to the right format. */
1314 static bfd_signed_vma
1315 s7_validate_immediate (bfd_signed_vma val
, unsigned int data_type
, int hex_p
)
1321 int val_hi
= ((val
& 0xffff0000) >> 16);
1323 if (s7_score_df_range
[data_type
].range
[0] <= val_hi
1324 && val_hi
<= s7_score_df_range
[data_type
].range
[1])
1331 int val_lo
= (val
& 0xffff);
1333 if (s7_score_df_range
[data_type
].range
[0] <= val_lo
1334 && val_lo
<= s7_score_df_range
[data_type
].range
[1])
1342 if (!(val
>= -0x800 && val
<= 0xfff))
1344 return (int) s7_FAIL
;
1349 if (!(val
>= -2048 && val
<= 2047))
1351 return (int) s7_FAIL
;
1361 if (!(val
>= -0x2000 && val
<= 0x3fff))
1363 return (int) s7_FAIL
;
1368 if (!(val
>= -8192 && val
<= 8191))
1370 return (int) s7_FAIL
;
1380 if (!(val
>= -0x4000 && val
<= 0x7fff))
1382 return (int) s7_FAIL
;
1387 if (!(val
>= -16384 && val
<= 16383))
1389 return (int) s7_FAIL
;
1399 if (!(val
>= -0x8000 && val
<= 0xffff))
1401 return (int) s7_FAIL
;
1406 if (!(val
>= -32768 && val
<= 32767))
1408 return (int) s7_FAIL
;
1418 if (!(val
>= -0x7fff && val
<= 0xffff && val
!= 0x8000))
1420 return (int) s7_FAIL
;
1425 if (!(val
>= -32767 && val
<= 32768))
1427 return (int) s7_FAIL
;
1436 if (val
>= 0 && val
<= 0xffffffff)
1442 return (int) s7_FAIL
;
1446 if (data_type
== _SIMM14_NEG
|| data_type
== _IMM16_NEG
)
1449 if (s7_score_df_range
[data_type
].range
[0] <= val
1450 && val
<= s7_score_df_range
[data_type
].range
[1])
1456 return (int) s7_FAIL
;
1460 s7_data_op2 (char **str
, int shift
, enum score_data_type data_type
)
1463 char data_exp
[s7_MAX_LITERAL_POOL_SIZE
];
1468 s7_skip_whitespace (*str
);
1469 s7_inst
.error
= NULL
;
1472 /* Set hex_p to zero. */
1475 while ((*dataptr
!= '\0') && (*dataptr
!= '|') && (cnt
<= s7_MAX_LITERAL_POOL_SIZE
)) /* 0x7c = ='|' */
1477 data_exp
[cnt
] = *dataptr
;
1482 data_exp
[cnt
] = '\0';
1483 pp
= (char *)&data_exp
;
1485 if (*dataptr
== '|') /* process PCE */
1487 if (s7_my_get_expression (&s7_inst
.reloc
.exp
, &pp
) == (int) s7_FAIL
)
1488 return (int) s7_FAIL
;
1489 s7_end_of_line (pp
);
1490 if (s7_inst
.error
!= 0)
1491 return (int) s7_FAIL
; /* to ouptut_inst to printf out the error */
1494 else /* process 16 bit */
1496 if (s7_my_get_expression (&s7_inst
.reloc
.exp
, str
) == (int) s7_FAIL
)
1498 return (int) s7_FAIL
;
1501 dataptr
= (char *) data_exp
;
1502 for (; *dataptr
!= '\0'; dataptr
++)
1504 *dataptr
= TOLOWER (*dataptr
);
1505 if (*dataptr
== '!' || *dataptr
== ' ')
1508 dataptr
= (char *) data_exp
;
1510 if ((dataptr
!= NULL
)
1511 && (((strstr (dataptr
, "0x")) != NULL
)
1512 || ((strstr (dataptr
, "0X")) != NULL
)))
1515 if ((data_type
!= _SIMM16_LA
)
1516 && (data_type
!= _VALUE_HI16
)
1517 && (data_type
!= _VALUE_LO16
)
1518 && (data_type
!= _IMM16
)
1519 && (data_type
!= _IMM15
)
1520 && (data_type
!= _IMM14
)
1521 && (data_type
!= _IMM4
)
1522 && (data_type
!= _IMM5
)
1523 && (data_type
!= _IMM8
)
1524 && (data_type
!= _IMM5_RSHIFT_1
)
1525 && (data_type
!= _IMM5_RSHIFT_2
)
1526 && (data_type
!= _SIMM14
)
1527 && (data_type
!= _SIMM16
)
1528 && (data_type
!= _SIMM14_NEG
)
1529 && (data_type
!= _SIMM16_NEG
)
1530 && (data_type
!= _IMM10_RSHIFT_2
)
1531 && (data_type
!= _GP_IMM15
))
1537 if ((s7_inst
.reloc
.exp
.X_add_number
== 0)
1538 /* for "addi r0,-((((((32*4)+4)+4)+4)+4)&0xf)". */
1539 && (s7_inst
.type
!= Rd_SI16
)
1540 && (s7_inst
.type
!= Insn_Type_SYN
)
1541 && (s7_inst
.type
!= Rd_rvalueRs_SI15
)
1542 && (s7_inst
.type
!= Rd_lvalueRs_SI15
)
1543 && (s7_inst
.type
!= Insn_internal
)
1544 && (((*dataptr
>= 'a') && (*dataptr
<= 'z'))
1545 || ((*dataptr
== '0') && (*(dataptr
+ 1) == 'x') && (*(dataptr
+ 2) != '0'))
1546 || ((*dataptr
== '+') && (*(dataptr
+ 1) != '0'))
1547 || ((*dataptr
== '-') && (*(dataptr
+ 1) != '0'))))
1549 s7_inst
.error
= s7_BAD_ARGS
;
1550 return (int) s7_FAIL
;
1554 if ((s7_inst
.reloc
.exp
.X_add_symbol
)
1555 && ((data_type
== _SIMM16
)
1556 || (data_type
== _SIMM16_NEG
)
1557 || (data_type
== _IMM16_NEG
)
1558 || (data_type
== _SIMM14
)
1559 || (data_type
== _SIMM14_NEG
)
1560 || (data_type
== _IMM5
)
1561 || (data_type
== _IMM14
)
1562 || (data_type
== _IMM20
)
1563 || (data_type
== _IMM16
)
1564 || (data_type
== _IMM15
)
1565 || (data_type
== _IMM4
)))
1567 s7_inst
.error
= s7_BAD_ARGS
;
1568 return (int) s7_FAIL
;
1571 if (s7_inst
.reloc
.exp
.X_add_symbol
)
1576 return (int) s7_FAIL
;
1578 s7_inst
.reloc
.type
= BFD_RELOC_HI16_S
;
1579 s7_inst
.reloc
.pc_rel
= 0;
1582 s7_inst
.reloc
.type
= BFD_RELOC_LO16
;
1583 s7_inst
.reloc
.pc_rel
= 0;
1586 s7_inst
.reloc
.type
= BFD_RELOC_SCORE_GPREL15
;
1587 s7_inst
.reloc
.pc_rel
= 0;
1590 case _IMM16_LO16_pic
:
1591 s7_inst
.reloc
.type
= BFD_RELOC_SCORE_GOT_LO16
;
1592 s7_inst
.reloc
.pc_rel
= 0;
1595 s7_inst
.reloc
.type
= BFD_RELOC_32
;
1596 s7_inst
.reloc
.pc_rel
= 0;
1602 if (data_type
== _IMM16_pic
)
1604 s7_inst
.reloc
.type
= BFD_RELOC_SCORE_DUMMY_HI16
;
1605 s7_inst
.reloc
.pc_rel
= 0;
1608 if (data_type
== _SIMM16_LA
&& s7_inst
.reloc
.exp
.X_unsigned
== 1)
1610 value
= s7_validate_immediate (s7_inst
.reloc
.exp
.X_add_number
, _SIMM16_LA_POS
, hex_p
);
1611 if (value
== (int) s7_FAIL
) /* for advance to check if this is ldis */
1612 if ((s7_inst
.reloc
.exp
.X_add_number
& 0xffff) == 0)
1614 s7_inst
.instruction
|= 0x8000000;
1615 s7_inst
.instruction
|= ((s7_inst
.reloc
.exp
.X_add_number
>> 16) << 1) & 0x1fffe;
1621 value
= s7_validate_immediate (s7_inst
.reloc
.exp
.X_add_number
, data_type
, hex_p
);
1624 if (value
== (int) s7_FAIL
)
1626 if ((data_type
!= _SIMM14_NEG
) && (data_type
!= _SIMM16_NEG
) && (data_type
!= _IMM16_NEG
))
1628 sprintf (s7_err_msg
,
1629 _("invalid constant: %d bit expression not in range %d..%d"),
1630 s7_score_df_range
[data_type
].bits
,
1631 s7_score_df_range
[data_type
].range
[0], s7_score_df_range
[data_type
].range
[1]);
1635 sprintf (s7_err_msg
,
1636 _("invalid constant: %d bit expression not in range %d..%d"),
1637 s7_score_df_range
[data_type
].bits
,
1638 -s7_score_df_range
[data_type
].range
[1], -s7_score_df_range
[data_type
].range
[0]);
1641 s7_inst
.error
= s7_err_msg
;
1642 return (int) s7_FAIL
;
1645 if ((s7_score_df_range
[data_type
].range
[0] != 0) || (data_type
== _IMM5_RANGE_8_31
))
1647 value
&= (1 << s7_score_df_range
[data_type
].bits
) - 1;
1650 s7_inst
.instruction
|= value
<< shift
;
1653 if ((s7_inst
.instruction
& 0x3e000000) == 0x30000000)
1655 if ((((s7_inst
.instruction
>> 20) & 0x1F) != 0)
1656 && (((s7_inst
.instruction
>> 20) & 0x1F) != 1)
1657 && (((s7_inst
.instruction
>> 20) & 0x1F) != 2)
1658 && (((s7_inst
.instruction
>> 20) & 0x1F) != 3)
1659 && (((s7_inst
.instruction
>> 20) & 0x1F) != 4)
1660 && (((s7_inst
.instruction
>> 20) & 0x1F) != 8)
1661 && (((s7_inst
.instruction
>> 20) & 0x1F) != 9)
1662 && (((s7_inst
.instruction
>> 20) & 0x1F) != 0xa)
1663 && (((s7_inst
.instruction
>> 20) & 0x1F) != 0xb)
1664 && (((s7_inst
.instruction
>> 20) & 0x1F) != 0xc)
1665 && (((s7_inst
.instruction
>> 20) & 0x1F) != 0xd)
1666 && (((s7_inst
.instruction
>> 20) & 0x1F) != 0xe)
1667 && (((s7_inst
.instruction
>> 20) & 0x1F) != 0x10)
1668 && (((s7_inst
.instruction
>> 20) & 0x1F) != 0x11)
1669 && (((s7_inst
.instruction
>> 20) & 0x1F) != 0x18)
1670 && (((s7_inst
.instruction
>> 20) & 0x1F) != 0x1A)
1671 && (((s7_inst
.instruction
>> 20) & 0x1F) != 0x1B)
1672 && (((s7_inst
.instruction
>> 20) & 0x1F) != 0x1d)
1673 && (((s7_inst
.instruction
>> 20) & 0x1F) != 0x1e)
1674 && (((s7_inst
.instruction
>> 20) & 0x1F) != 0x1f))
1676 s7_inst
.error
= _("invalid constant: bit expression not defined");
1677 return (int) s7_FAIL
;
1684 /* Handle addi/addi.c/addis.c/cmpi.c/addis.c/ldi. */
1687 s7_do_rdsi16 (char *str
)
1689 s7_skip_whitespace (str
);
1691 if (s7_reg_required_here (&str
, 20, s7_REG_TYPE_SCORE
) == (int) s7_FAIL
1692 || s7_skip_past_comma (&str
) == (int) s7_FAIL
1693 || s7_data_op2 (&str
, 1, _SIMM16
) == (int) s7_FAIL
1694 || s7_end_of_line (str
) == (int) s7_FAIL
)
1698 if ((s7_inst
.instruction
& 0x20c0000) == 0x20c0000)
1700 if ((((s7_inst
.instruction
>> 20) & 0x10) == 0x10) || ((s7_inst
.instruction
& 0x1fe00) != 0))
1702 s7_inst
.relax_inst
= 0x8000;
1706 s7_inst
.relax_inst
|= (s7_inst
.instruction
>> 1) & 0xff;
1707 s7_inst
.relax_inst
|= (((s7_inst
.instruction
>> 20) & 0xf) << 8);
1708 s7_inst
.relax_size
= 2;
1711 else if (((s7_inst
.instruction
>> 20) & 0x10) == 0x10)
1713 s7_inst
.relax_inst
= 0x8000;
1717 /* Handle subi/subi.c. */
1720 s7_do_sub_rdsi16 (char *str
)
1722 s7_skip_whitespace (str
);
1724 if (s7_reg_required_here (&str
, 20, s7_REG_TYPE_SCORE
) != (int) s7_FAIL
1725 && s7_skip_past_comma (&str
) != (int) s7_FAIL
1726 && s7_data_op2 (&str
, 1, _SIMM16_NEG
) != (int) s7_FAIL
)
1727 s7_end_of_line (str
);
1731 /* Handle addri/addri.c. */
1734 s7_do_rdrssi14 (char *str
) /* -(2^13)~((2^13)-1) */
1736 s7_skip_whitespace (str
);
1738 if (s7_reg_required_here (&str
, 20, s7_REG_TYPE_SCORE
) != (int) s7_FAIL
1739 && s7_skip_past_comma (&str
) != (int) s7_FAIL
1740 && s7_reg_required_here (&str
, 15, s7_REG_TYPE_SCORE
) != (int) s7_FAIL
1741 && s7_skip_past_comma (&str
) != (int) s7_FAIL
)
1742 s7_data_op2 (&str
, 1, _SIMM14
);
1745 /* Handle subri.c/subri. */
1748 s7_do_sub_rdrssi14 (char *str
) /* -(2^13)~((2^13)-1) */
1750 s7_skip_whitespace (str
);
1752 if (s7_reg_required_here (&str
, 20, s7_REG_TYPE_SCORE
) != (int) s7_FAIL
1753 && s7_skip_past_comma (&str
) != (int) s7_FAIL
1754 && s7_reg_required_here (&str
, 15, s7_REG_TYPE_SCORE
) != (int) s7_FAIL
1755 && s7_skip_past_comma (&str
) != (int) s7_FAIL
1756 && s7_data_op2 (&str
, 1, _SIMM14_NEG
) != (int) s7_FAIL
)
1757 s7_end_of_line (str
);
1760 /* Handle bitclr.c/bitset.c/bittgl.c/slli.c/srai.c/srli.c/roli.c/rori.c/rolic.c. */
1763 s7_do_rdrsi5 (char *str
) /* 0~((2^14)-1) */
1765 s7_skip_whitespace (str
);
1767 if (s7_reg_required_here (&str
, 20, s7_REG_TYPE_SCORE
) == (int) s7_FAIL
1768 || s7_skip_past_comma (&str
) == (int) s7_FAIL
1769 || s7_reg_required_here (&str
, 15, s7_REG_TYPE_SCORE
) == (int) s7_FAIL
1770 || s7_skip_past_comma (&str
) == (int) s7_FAIL
1771 || s7_data_op2 (&str
, 10, _IMM5
) == (int) s7_FAIL
1772 || s7_end_of_line (str
) == (int) s7_FAIL
)
1775 if ((((s7_inst
.instruction
>> 20) & 0x1f) == ((s7_inst
.instruction
>> 15) & 0x1f))
1776 && (s7_inst
.relax_inst
!= 0x8000) && (((s7_inst
.instruction
>> 15) & 0x10) == 0))
1778 s7_inst
.relax_inst
|= (((s7_inst
.instruction
>> 10) & 0x1f) << 3) | (((s7_inst
.instruction
>> 15) & 0xf) << 8);
1779 s7_inst
.relax_size
= 2;
1782 s7_inst
.relax_inst
= 0x8000;
1785 /* Handle andri/orri/andri.c/orri.c. */
1788 s7_do_rdrsi14 (char *str
) /* 0 ~ ((2^14)-1) */
1790 s7_skip_whitespace (str
);
1792 if (s7_reg_required_here (&str
, 20, s7_REG_TYPE_SCORE
) != (int) s7_FAIL
1793 && s7_skip_past_comma (&str
) != (int) s7_FAIL
1794 && s7_reg_required_here (&str
, 15, s7_REG_TYPE_SCORE
) != (int) s7_FAIL
1795 && s7_skip_past_comma (&str
) != (int) s7_FAIL
1796 && s7_data_op2 (&str
, 1, _IMM14
) != (int) s7_FAIL
)
1797 s7_end_of_line (str
);
1800 /* Handle bittst.c. */
1803 s7_do_xrsi5 (char *str
)
1805 s7_skip_whitespace (str
);
1807 if (s7_reg_required_here (&str
, 15, s7_REG_TYPE_SCORE
) == (int) s7_FAIL
1808 || s7_skip_past_comma (&str
) == (int) s7_FAIL
1809 || s7_data_op2 (&str
, 10, _IMM5
) == (int) s7_FAIL
1810 || s7_end_of_line (str
) == (int) s7_FAIL
)
1813 if ((s7_inst
.relax_inst
!= 0x8000) && (((s7_inst
.instruction
>> 15) & 0x10) == 0))
1815 s7_inst
.relax_inst
|= (((s7_inst
.instruction
>> 10) & 0x1f) << 3) | (((s7_inst
.instruction
>> 15) & 0xf) << 8);
1816 s7_inst
.relax_size
= 2;
1819 s7_inst
.relax_inst
= 0x8000;
1822 /* Handle addis/andi/ori/andis/oris/ldis. */
1825 s7_do_rdi16 (char *str
)
1827 s7_skip_whitespace (str
);
1829 if (s7_reg_required_here (&str
, 20, s7_REG_TYPE_SCORE
) == (int) s7_FAIL
1830 || s7_skip_past_comma (&str
) == (int) s7_FAIL
1831 || s7_data_op2 (&str
, 1, _IMM16
) == (int) s7_FAIL
1832 || s7_end_of_line (str
) == (int) s7_FAIL
)
1837 s7_do_macro_rdi32hi (char *str
)
1839 s7_skip_whitespace (str
);
1841 /* Do not handle s7_end_of_line(). */
1842 if (s7_reg_required_here (&str
, 20, s7_REG_TYPE_SCORE
) != (int) s7_FAIL
1843 && s7_skip_past_comma (&str
) != (int) s7_FAIL
)
1844 s7_data_op2 (&str
, 1, _VALUE_HI16
);
1848 s7_do_macro_rdi32lo (char *str
)
1850 s7_skip_whitespace (str
);
1852 /* Do not handle s7_end_of_line(). */
1853 if (s7_reg_required_here (&str
, 20, s7_REG_TYPE_SCORE
) != (int) s7_FAIL
1854 && s7_skip_past_comma (&str
) != (int) s7_FAIL
)
1855 s7_data_op2 (&str
, 1, _VALUE_LO16
);
1858 /* Handle ldis_pic. */
1861 s7_do_rdi16_pic (char *str
)
1863 s7_skip_whitespace (str
);
1865 if (s7_reg_required_here (&str
, 20, s7_REG_TYPE_SCORE
) != (int) s7_FAIL
1866 && s7_skip_past_comma (&str
) != (int) s7_FAIL
1867 && s7_data_op2 (&str
, 1, _IMM16_pic
) != (int) s7_FAIL
)
1868 s7_end_of_line (str
);
1871 /* Handle addi_s_pic to generate R_SCORE_GOT_LO16 . */
1874 s7_do_addi_s_pic (char *str
)
1876 s7_skip_whitespace (str
);
1878 if (s7_reg_required_here (&str
, 20, s7_REG_TYPE_SCORE
) != (int) s7_FAIL
1879 && s7_skip_past_comma (&str
) != (int) s7_FAIL
1880 && s7_data_op2 (&str
, 1, _SIMM16_pic
) != (int) s7_FAIL
)
1881 s7_end_of_line (str
);
1884 /* Handle addi_u_pic to generate R_SCORE_GOT_LO16 . */
1887 s7_do_addi_u_pic (char *str
)
1889 s7_skip_whitespace (str
);
1891 if (s7_reg_required_here (&str
, 20, s7_REG_TYPE_SCORE
) != (int) s7_FAIL
1892 && s7_skip_past_comma (&str
) != (int) s7_FAIL
1893 && s7_data_op2 (&str
, 1, _IMM16_LO16_pic
) != (int) s7_FAIL
)
1894 s7_end_of_line (str
);
1897 /* Handle mfceh/mfcel/mtceh/mtchl. */
1900 s7_do_rd (char *str
)
1902 s7_skip_whitespace (str
);
1904 if (s7_reg_required_here (&str
, 20, s7_REG_TYPE_SCORE
) != (int) s7_FAIL
)
1905 s7_end_of_line (str
);
1909 s7_do_rs (char *str
)
1911 s7_skip_whitespace (str
);
1913 if (s7_reg_required_here (&str
, 15, s7_REG_TYPE_SCORE
) == (int) s7_FAIL
1914 || s7_end_of_line (str
) == (int) s7_FAIL
)
1917 if ((s7_inst
.relax_inst
!= 0x8000) && (((s7_inst
.instruction
>> 15) & 0x10) == 0))
1919 s7_inst
.relax_inst
|= (((s7_inst
.instruction
>> 10) & 0xf) << 8) | (((s7_inst
.instruction
>> 15) & 0xf) << 4);
1920 s7_inst
.relax_size
= 2;
1923 s7_inst
.relax_inst
= 0x8000;
1927 s7_do_i15 (char *str
)
1929 s7_skip_whitespace (str
);
1931 if (s7_data_op2 (&str
, 10, _IMM15
) != (int) s7_FAIL
)
1932 s7_end_of_line (str
);
1936 s7_do_xi5x (char *str
)
1938 s7_skip_whitespace (str
);
1940 if (s7_data_op2 (&str
, 15, _IMM5
) == (int) s7_FAIL
|| s7_end_of_line (str
) == (int) s7_FAIL
)
1943 if (s7_inst
.relax_inst
!= 0x8000)
1945 s7_inst
.relax_inst
|= (((s7_inst
.instruction
>> 15) & 0x1f) << 3);
1946 s7_inst
.relax_size
= 2;
1951 s7_do_rdrs (char *str
)
1953 s7_skip_whitespace (str
);
1955 if (s7_reg_required_here (&str
, 20, s7_REG_TYPE_SCORE
) == (int) s7_FAIL
1956 || s7_skip_past_comma (&str
) == (int) s7_FAIL
1957 || s7_reg_required_here (&str
, 15, s7_REG_TYPE_SCORE
) == (int) s7_FAIL
1958 || s7_end_of_line (str
) == (int) s7_FAIL
)
1961 if (s7_inst
.relax_inst
!= 0x8000)
1963 if (((s7_inst
.instruction
& 0x7f) == 0x56)) /* adjust mv -> mv! / mlfh! / mhfl! */
1966 if ((((s7_inst
.instruction
>> 15) & 0x10) != 0x0) && (((s7_inst
.instruction
>> 20) & 0x10) == 0))
1968 s7_inst
.relax_inst
= 0x00000001 | (((s7_inst
.instruction
>> 15) & 0xf) << 4)
1969 | (((s7_inst
.instruction
>> 20) & 0xf) << 8);
1970 s7_inst
.relax_size
= 2;
1973 else if ((((s7_inst
.instruction
>> 15) & 0x10) == 0x0) && ((s7_inst
.instruction
>> 20) & 0x10) != 0)
1975 s7_inst
.relax_inst
= 0x00000002 | (((s7_inst
.instruction
>> 15) & 0xf) << 4)
1976 | (((s7_inst
.instruction
>> 20) & 0xf) << 8);
1977 s7_inst
.relax_size
= 2;
1979 else if ((((s7_inst
.instruction
>> 15) & 0x10) == 0x0) && (((s7_inst
.instruction
>> 20) & 0x10) == 0))
1981 s7_inst
.relax_inst
|= (((s7_inst
.instruction
>> 15) & 0xf) << 4)
1982 | (((s7_inst
.instruction
>> 20) & 0xf) << 8);
1983 s7_inst
.relax_size
= 2;
1987 s7_inst
.relax_inst
= 0x8000;
1990 else if ((((s7_inst
.instruction
>> 15) & 0x10) == 0x0) && (((s7_inst
.instruction
>> 20) & 0x10) == 0))
1992 s7_inst
.relax_inst
|= (((s7_inst
.instruction
>> 15) & 0xf) << 4)
1993 | (((s7_inst
.instruction
>> 20) & 0xf) << 8);
1994 s7_inst
.relax_size
= 2;
1998 s7_inst
.relax_inst
= 0x8000;
2003 /* Handle mfcr/mtcr. */
2005 s7_do_rdcrs (char *str
)
2007 s7_skip_whitespace (str
);
2009 if (s7_reg_required_here (&str
, 20, s7_REG_TYPE_SCORE
) != (int) s7_FAIL
2010 && s7_skip_past_comma (&str
) != (int) s7_FAIL
2011 && s7_reg_required_here (&str
, 15, s7_REG_TYPE_SCORE_CR
) != (int) s7_FAIL
)
2012 s7_end_of_line (str
);
2015 /* Handle mfsr/mtsr. */
2018 s7_do_rdsrs (char *str
)
2020 s7_skip_whitespace (str
);
2023 if ((s7_inst
.instruction
& 0xff) == 0x50)
2025 if (s7_reg_required_here (&str
, 20, s7_REG_TYPE_SCORE
) != (int) s7_FAIL
2026 && s7_skip_past_comma (&str
) != (int) s7_FAIL
2027 && s7_reg_required_here (&str
, 10, s7_REG_TYPE_SCORE_SR
) != (int) s7_FAIL
)
2028 s7_end_of_line (str
);
2032 if (s7_reg_required_here (&str
, 15, s7_REG_TYPE_SCORE
) != (int) s7_FAIL
2033 && s7_skip_past_comma (&str
) != (int) s7_FAIL
)
2034 s7_reg_required_here (&str
, 10, s7_REG_TYPE_SCORE_SR
);
2041 s7_do_rdxrs (char *str
)
2043 s7_skip_whitespace (str
);
2045 if (s7_reg_required_here (&str
, 20, s7_REG_TYPE_SCORE
) == (int) s7_FAIL
2046 || s7_skip_past_comma (&str
) == (int) s7_FAIL
2047 || s7_reg_required_here (&str
, 10, s7_REG_TYPE_SCORE
) == (int) s7_FAIL
2048 || s7_end_of_line (str
) == (int) s7_FAIL
)
2051 if ((s7_inst
.relax_inst
!= 0x8000) && (((s7_inst
.instruction
>> 10) & 0x10) == 0)
2052 && (((s7_inst
.instruction
>> 20) & 0x10) == 0))
2054 s7_inst
.relax_inst
|= (((s7_inst
.instruction
>> 10) & 0xf) << 4) | (((s7_inst
.instruction
>> 20) & 0xf) << 8);
2055 s7_inst
.relax_size
= 2;
2058 s7_inst
.relax_inst
= 0x8000;
2061 /* Handle cmp.c/cmp<cond>. */
2063 s7_do_rsrs (char *str
)
2065 s7_skip_whitespace (str
);
2067 if (s7_reg_required_here (&str
, 15, s7_REG_TYPE_SCORE
) == (int) s7_FAIL
2068 || s7_skip_past_comma (&str
) == (int) s7_FAIL
2069 || s7_reg_required_here (&str
, 10, s7_REG_TYPE_SCORE
) == (int) s7_FAIL
2070 || s7_end_of_line (str
) == (int) s7_FAIL
)
2073 if ((s7_inst
.relax_inst
!= 0x8000) && (((s7_inst
.instruction
>> 20) & 0x1f) == 3)
2074 && (((s7_inst
.instruction
>> 10) & 0x10) == 0) && (((s7_inst
.instruction
>> 15) & 0x10) == 0))
2076 s7_inst
.relax_inst
|= (((s7_inst
.instruction
>> 10) & 0xf) << 4) | (((s7_inst
.instruction
>> 15) & 0xf) << 8);
2077 s7_inst
.relax_size
= 2;
2080 s7_inst
.relax_inst
= 0x8000;
2084 s7_do_ceinst (char *str
)
2089 s7_skip_whitespace (str
);
2091 if (s7_data_op2 (&str
, 20, _IMM5
) == (int) s7_FAIL
2092 || s7_skip_past_comma (&str
) == (int) s7_FAIL
2093 || s7_reg_required_here (&str
, 15, s7_REG_TYPE_SCORE
) == (int) s7_FAIL
2094 || s7_skip_past_comma (&str
) == (int) s7_FAIL
2095 || s7_reg_required_here (&str
, 10, s7_REG_TYPE_SCORE
) == (int) s7_FAIL
2096 || s7_skip_past_comma (&str
) == (int) s7_FAIL
2097 || s7_data_op2 (&str
, 5, _IMM5
) == (int) s7_FAIL
2098 || s7_skip_past_comma (&str
) == (int) s7_FAIL
2099 || s7_data_op2 (&str
, 0, _IMM5
) == (int) s7_FAIL
2100 || s7_end_of_line (str
) == (int) s7_FAIL
)
2107 if (s7_data_op2 (&str
, 0, _IMM25
) == (int) s7_FAIL
)
2113 s7_reglow_required_here (char **str
, int shift
)
2115 static char buff
[s7_MAX_LITERAL_POOL_SIZE
];
2119 if ((reg
= s7_score_reg_parse (str
, s7_all_reg_maps
[s7_REG_TYPE_SCORE
].htab
)) != (int) s7_FAIL
)
2121 if ((reg
== 1) && (s7_nor1
== 1) && (s7_inst
.bwarn
== 0))
2123 as_warn (_("Using temp register(r1)"));
2129 s7_inst
.instruction
|= reg
<< shift
;
2135 /* Restore the start point, we may have got a reg of the wrong class. */
2137 sprintf (buff
, _("low register(r0-r15)expected, not '%.100s'"), start
);
2138 s7_inst
.error
= buff
;
2139 return (int) s7_FAIL
;
2142 /* Handle addc!/add!/and!/cmp!/neg!/not!/or!/sll!/srl!/sra!/xor!/sub!. */
2145 s7_do16_rdrs (char *str
)
2147 s7_skip_whitespace (str
);
2149 if (s7_reglow_required_here (&str
, 8) == (int) s7_FAIL
2150 || s7_skip_past_comma (&str
) == (int) s7_FAIL
2151 || s7_reglow_required_here (&str
, 4) == (int) s7_FAIL
2152 || s7_end_of_line (str
) == (int) s7_FAIL
)
2158 if ((s7_inst
.instruction
& 0x700f) == 0x2003) /* cmp! */
2160 s7_inst
.relax_inst
|= (((s7_inst
.instruction
>> 8) & 0xf) << 15)
2161 | (((s7_inst
.instruction
>> 4) & 0xf) << 10);
2163 else if ((s7_inst
.instruction
& 0x700f) == 0x2006) /* not! */
2165 s7_inst
.relax_inst
|= (((s7_inst
.instruction
>> 8) & 0xf) << 20)
2166 | (((s7_inst
.instruction
>> 4) & 0xf) << 15);
2168 else if ((s7_inst
.instruction
& 0x700f) == 0x1009) /* mazh.f! */
2170 s7_inst
.relax_inst
|= (((s7_inst
.instruction
>> 8) & 0xf) << 15)
2171 | (((s7_inst
.instruction
>> 4) & 0xf) << 10);
2175 s7_inst
.relax_inst
|= (((s7_inst
.instruction
>> 8) & 0xf) << 20)
2176 | (((s7_inst
.instruction
>> 8) & 0xf) << 15) | (((s7_inst
.instruction
>> 4) & 0xf) << 10);
2178 s7_inst
.relax_size
= 4;
2183 s7_do16_rs (char *str
)
2187 s7_skip_whitespace (str
);
2189 if ((rd
= s7_reglow_required_here (&str
, 4)) == (int) s7_FAIL
2190 || s7_end_of_line (str
) == (int) s7_FAIL
)
2196 s7_inst
.relax_inst
|= rd
<< 20;
2197 s7_inst
.relax_size
= 4;
2201 /* Handle br!/brl!. */
2204 s7_do16_xrs (char *str
)
2206 s7_skip_whitespace (str
);
2208 if (s7_reglow_required_here (&str
, 4) == (int) s7_FAIL
|| s7_end_of_line (str
) == (int) s7_FAIL
)
2214 s7_inst
.relax_inst
|= (((s7_inst
.instruction
>> 8) & 0xf) << 10)
2215 | (((s7_inst
.instruction
>> 4) & 0xf) << 15);
2216 s7_inst
.relax_size
= 4;
2221 s7_reghigh_required_here (char **str
, int shift
)
2223 static char buff
[s7_MAX_LITERAL_POOL_SIZE
];
2227 if ((reg
= s7_score_reg_parse (str
, s7_all_reg_maps
[s7_REG_TYPE_SCORE
].htab
)) != (int) s7_FAIL
)
2229 if (15 < reg
&& reg
< 32)
2232 s7_inst
.instruction
|= (reg
& 0xf) << shift
;
2239 sprintf (buff
, _("high register(r16-r31)expected, not '%.100s'"), start
);
2240 s7_inst
.error
= buff
;
2241 return (int) s7_FAIL
;
2247 s7_do16_hrdrs (char *str
)
2249 s7_skip_whitespace (str
);
2251 if (s7_reghigh_required_here (&str
, 8) != (int) s7_FAIL
2252 && s7_skip_past_comma (&str
) != (int) s7_FAIL
2253 && s7_reglow_required_here (&str
, 4) != (int) s7_FAIL
2254 && s7_end_of_line (str
) != (int) s7_FAIL
)
2256 s7_inst
.relax_inst
|= ((((s7_inst
.instruction
>> 8) & 0xf) | 0x10) << 20)
2257 | (((s7_inst
.instruction
>> 4) & 0xf) << 15) | (0xf << 10);
2258 s7_inst
.relax_size
= 4;
2265 s7_do16_rdhrs (char *str
)
2267 s7_skip_whitespace (str
);
2269 if (s7_reglow_required_here (&str
, 8) != (int) s7_FAIL
2270 && s7_skip_past_comma (&str
) != (int) s7_FAIL
2271 && s7_reghigh_required_here (&str
, 4) != (int) s7_FAIL
2272 && s7_end_of_line (str
) != (int) s7_FAIL
)
2274 s7_inst
.relax_inst
|= (((s7_inst
.instruction
>> 8) & 0xf) << 20)
2275 | ((((s7_inst
.instruction
>> 4) & 0xf) | 0x10) << 15) | (0xf << 10);
2276 s7_inst
.relax_size
= 4;
2280 /* We need to be able to fix up arbitrary expressions in some statements.
2281 This is so that we can handle symbols that are an arbitrary distance from
2282 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
2283 which returns part of an address in a form which will be valid for
2284 a data instruction. We do this by pushing the expression into a symbol
2285 in the expr_section, and creating a fix for that. */
2288 s7_fix_new_score (fragS
* frag
, int where
, short int size
, expressionS
* exp
, int pc_rel
, int reloc
)
2298 new_fix
= fix_new_exp (frag
, where
, size
, exp
, pc_rel
, reloc
);
2301 new_fix
= fix_new (frag
, where
, size
, make_expr_symbol (exp
), 0, pc_rel
, reloc
);
2308 s7_init_dependency_vector (void)
2312 for (i
= 0; i
< s7_vector_size
; i
++)
2313 memset (&s7_dependency_vector
[i
], '\0', sizeof (s7_dependency_vector
[i
]));
2318 static enum s7_insn_type_for_dependency
2319 s7_dependency_type_from_insn (char *insn_name
)
2321 char name
[s7_INSN_NAME_LEN
];
2322 const struct s7_insn_to_dependency
*tmp
;
2324 strcpy (name
, insn_name
);
2325 tmp
= (const struct s7_insn_to_dependency
*) hash_find (s7_dependency_insn_hsh
, name
);
2330 return s7_D_all_insn
;
2334 s7_check_dependency (char *pre_insn
, char *pre_reg
,
2335 char *cur_insn
, char *cur_reg
, int *warn_or_error
)
2339 enum s7_insn_type_for_dependency pre_insn_type
;
2340 enum s7_insn_type_for_dependency cur_insn_type
;
2342 pre_insn_type
= s7_dependency_type_from_insn (pre_insn
);
2343 cur_insn_type
= s7_dependency_type_from_insn (cur_insn
);
2345 for (i
= 0; i
< sizeof (s7_data_dependency_table
) / sizeof (s7_data_dependency_table
[0]); i
++)
2347 if ((pre_insn_type
== s7_data_dependency_table
[i
].pre_insn_type
)
2348 && (s7_D_all_insn
== s7_data_dependency_table
[i
].cur_insn_type
2349 || cur_insn_type
== s7_data_dependency_table
[i
].cur_insn_type
)
2350 && (strcmp (s7_data_dependency_table
[i
].pre_reg
, "") == 0
2351 || strcmp (s7_data_dependency_table
[i
].pre_reg
, pre_reg
) == 0)
2352 && (strcmp (s7_data_dependency_table
[i
].cur_reg
, "") == 0
2353 || strcmp (s7_data_dependency_table
[i
].cur_reg
, cur_reg
) == 0))
2355 if (s7_vector_size
== s7_SCORE5_PIPELINE
)
2356 bubbles
= s7_data_dependency_table
[i
].bubblenum_5
;
2358 bubbles
= s7_data_dependency_table
[i
].bubblenum_7
;
2359 *warn_or_error
= s7_data_dependency_table
[i
].warn_or_error
;
2367 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
2368 for use in the a.out file, and stores them in the array pointed to by buf.
2369 This knows about the endian-ness of the target machine and does
2370 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
2371 2 (short) and 4 (long) Floating numbers are put out as a series of
2372 LITTLENUMS (shorts, here at least). */
2375 s7_number_to_chars (char *buf
, valueT val
, int n
)
2377 if (target_big_endian
)
2378 number_to_chars_bigendian (buf
, val
, n
);
2380 number_to_chars_littleendian (buf
, val
, n
);
2384 s7_build_one_frag (struct s7_score_it one_inst
)
2387 int relaxable_p
= s7_g_opt
;
2390 /* Start a new frag if frag_now is not empty. */
2391 if (frag_now_fix () != 0)
2393 if (!frag_now
->tc_frag_data
.is_insn
)
2394 frag_wane (frag_now
);
2400 p
= frag_more (one_inst
.size
);
2401 s7_number_to_chars (p
, one_inst
.instruction
, one_inst
.size
);
2404 dwarf2_emit_insn (one_inst
.size
);
2407 relaxable_p
&= (one_inst
.relax_size
!= 0);
2408 relax_size
= relaxable_p
? one_inst
.relax_size
: 0;
2410 p
= frag_var (rs_machine_dependent
, relax_size
+ s7_RELAX_PAD_BYTE
, 0,
2411 s7_RELAX_ENCODE (one_inst
.size
, one_inst
.relax_size
,
2412 one_inst
.type
, 0, 0, relaxable_p
),
2416 s7_number_to_chars (p
, one_inst
.relax_inst
, relax_size
);
2420 s7_handle_dependency (struct s7_score_it
*theinst
)
2423 int warn_or_error
= 0; /* warn - 0; error - 1 */
2425 int remainder_bubbles
= 0;
2426 char cur_insn
[s7_INSN_NAME_LEN
];
2427 char pre_insn
[s7_INSN_NAME_LEN
];
2428 struct s7_score_it nop_inst
;
2429 struct s7_score_it pflush_inst
;
2431 nop_inst
.instruction
= 0x0000;
2433 nop_inst
.relax_inst
= 0x80008000;
2434 nop_inst
.relax_size
= 4;
2435 nop_inst
.type
= NO16_OPD
;
2437 pflush_inst
.instruction
= 0x8000800a;
2438 pflush_inst
.size
= 4;
2439 pflush_inst
.relax_inst
= 0x8000;
2440 pflush_inst
.relax_size
= 0;
2441 pflush_inst
.type
= NO_OPD
;
2443 /* pflush will clear all data dependency. */
2444 if (strcmp (theinst
->name
, "pflush") == 0)
2446 s7_init_dependency_vector ();
2450 /* Push current instruction to s7_dependency_vector[0]. */
2451 for (i
= s7_vector_size
- 1; i
> 0; i
--)
2452 memcpy (&s7_dependency_vector
[i
], &s7_dependency_vector
[i
- 1], sizeof (s7_dependency_vector
[i
]));
2454 memcpy (&s7_dependency_vector
[0], theinst
, sizeof (s7_dependency_vector
[i
]));
2456 /* There is no dependency between nop and any instruction. */
2457 if (strcmp (s7_dependency_vector
[0].name
, "nop") == 0
2458 || strcmp (s7_dependency_vector
[0].name
, "nop!") == 0)
2461 /* "pce" is defined in s7_insn_to_dependency_table. */
2462 #define PCE_NAME "pce"
2464 if (s7_dependency_vector
[0].type
== Insn_Type_PCE
)
2465 strcpy (cur_insn
, PCE_NAME
);
2467 strcpy (cur_insn
, s7_dependency_vector
[0].name
);
2469 for (i
= 1; i
< s7_vector_size
; i
++)
2471 /* The element of s7_dependency_vector is NULL. */
2472 if (s7_dependency_vector
[i
].name
[0] == '\0')
2475 if (s7_dependency_vector
[i
].type
== Insn_Type_PCE
)
2476 strcpy (pre_insn
, PCE_NAME
);
2478 strcpy (pre_insn
, s7_dependency_vector
[i
].name
);
2480 bubbles
= s7_check_dependency (pre_insn
, s7_dependency_vector
[i
].reg
,
2481 cur_insn
, s7_dependency_vector
[0].reg
, &warn_or_error
);
2482 remainder_bubbles
= bubbles
- i
+ 1;
2484 if (remainder_bubbles
> 0)
2488 if (s7_fix_data_dependency
== 1)
2490 if (remainder_bubbles
<= 2)
2492 if (s7_warn_fix_data_dependency
)
2493 as_warn (_("Fix data dependency: %s %s -- %s %s (insert %d nop!/%d)"),
2494 s7_dependency_vector
[i
].name
, s7_dependency_vector
[i
].reg
,
2495 s7_dependency_vector
[0].name
, s7_dependency_vector
[0].reg
,
2496 remainder_bubbles
, bubbles
);
2498 for (j
= (s7_vector_size
- 1); (j
- remainder_bubbles
) > 0; j
--)
2499 memcpy (&s7_dependency_vector
[j
], &s7_dependency_vector
[j
- remainder_bubbles
],
2500 sizeof (s7_dependency_vector
[j
]));
2502 for (j
= 1; j
<= remainder_bubbles
; j
++)
2504 memset (&s7_dependency_vector
[j
], '\0', sizeof (s7_dependency_vector
[j
]));
2506 s7_build_one_frag (nop_inst
);
2511 if (s7_warn_fix_data_dependency
)
2512 as_warn (_("Fix data dependency: %s %s -- %s %s (insert 1 pflush/%d)"),
2513 s7_dependency_vector
[i
].name
, s7_dependency_vector
[i
].reg
,
2514 s7_dependency_vector
[0].name
, s7_dependency_vector
[0].reg
,
2517 for (j
= 1; j
< s7_vector_size
; j
++)
2518 memset (&s7_dependency_vector
[j
], '\0', sizeof (s7_dependency_vector
[j
]));
2520 /* Insert pflush. */
2521 s7_build_one_frag (pflush_inst
);
2528 as_bad (_("data dependency: %s %s -- %s %s (%d/%d bubble)"),
2529 s7_dependency_vector
[i
].name
, s7_dependency_vector
[i
].reg
,
2530 s7_dependency_vector
[0].name
, s7_dependency_vector
[0].reg
,
2531 remainder_bubbles
, bubbles
);
2535 as_warn (_("data dependency: %s %s -- %s %s (%d/%d bubble)"),
2536 s7_dependency_vector
[i
].name
, s7_dependency_vector
[i
].reg
,
2537 s7_dependency_vector
[0].name
, s7_dependency_vector
[0].reg
,
2538 remainder_bubbles
, bubbles
);
2545 static enum insn_class
2546 s7_get_insn_class_from_type (enum score_insn_type type
)
2548 enum insn_class retval
= (int) s7_FAIL
;
2554 case Rd_rvalueBP_I5
:
2555 case Rd_lvalueBP_I5
:
2566 retval
= INSN_CLASS_16
;
2575 case Rd_rvalueRs_SI10
:
2576 case Rd_lvalueRs_SI10
:
2577 case Rd_rvalueRs_preSI12
:
2578 case Rd_rvalueRs_postSI12
:
2579 case Rd_lvalueRs_preSI12
:
2580 case Rd_lvalueRs_postSI12
:
2582 case Rd_rvalueRs_SI15
:
2583 case Rd_lvalueRs_SI15
:
2592 case OP5_rvalueRs_SI15
:
2593 case I5_Rs_Rs_I5_OP5
:
2594 case x_rvalueRs_post4
:
2595 case Rd_rvalueRs_post4
:
2597 case Rd_lvalueRs_post4
:
2598 case x_lvalueRs_post4
:
2606 retval
= INSN_CLASS_32
;
2609 retval
= INSN_CLASS_PCE
;
2612 retval
= INSN_CLASS_SYN
;
2621 static unsigned long
2622 s7_adjust_paritybit (unsigned long m_code
, enum insn_class i_class
)
2624 unsigned long result
= 0;
2625 unsigned long m_code_high
= 0;
2626 unsigned long m_code_low
= 0;
2627 unsigned long pb_high
= 0;
2628 unsigned long pb_low
= 0;
2630 if (i_class
== INSN_CLASS_32
)
2632 pb_high
= 0x80000000;
2633 pb_low
= 0x00008000;
2635 else if (i_class
== INSN_CLASS_16
)
2640 else if (i_class
== INSN_CLASS_PCE
)
2643 pb_low
= 0x00008000;
2645 else if (i_class
== INSN_CLASS_SYN
)
2647 /* FIXME. at this time, INSN_CLASS_SYN must be 32 bit, but, instruction type should
2648 be changed if macro instruction has been expanded. */
2649 pb_high
= 0x80000000;
2650 pb_low
= 0x00008000;
2657 m_code_high
= m_code
& 0x3fff8000;
2658 m_code_low
= m_code
& 0x00007fff;
2659 result
= pb_high
| (m_code_high
<< 1) | pb_low
| m_code_low
;
2665 s7_gen_insn_frag (struct s7_score_it
*part_1
, struct s7_score_it
*part_2
)
2668 bfd_boolean pce_p
= FALSE
;
2669 int relaxable_p
= s7_g_opt
;
2671 struct s7_score_it
*inst1
= part_1
;
2672 struct s7_score_it
*inst2
= part_2
;
2673 struct s7_score_it backup_inst1
;
2675 pce_p
= (inst2
) ? TRUE
: FALSE
;
2676 memcpy (&backup_inst1
, inst1
, sizeof (struct s7_score_it
));
2678 /* Adjust instruction opcode and to be relaxed instruction opcode. */
2681 backup_inst1
.instruction
= ((backup_inst1
.instruction
& 0x7FFF) << 15)
2682 | (inst2
->instruction
& 0x7FFF);
2683 backup_inst1
.instruction
= s7_adjust_paritybit (backup_inst1
.instruction
, INSN_CLASS_PCE
);
2684 if (!target_big_endian
)
2686 unsigned long tmp
= backup_inst1
.instruction
;
2687 backup_inst1
.instruction
= ((tmp
& 0xffff) << 16)
2690 backup_inst1
.relax_inst
= 0x8000;
2691 backup_inst1
.size
= s7_INSN_SIZE
;
2692 backup_inst1
.relax_size
= 0;
2693 backup_inst1
.type
= Insn_Type_PCE
;
2697 backup_inst1
.instruction
= s7_adjust_paritybit (backup_inst1
.instruction
,
2698 s7_GET_INSN_CLASS (backup_inst1
.type
));
2701 if (backup_inst1
.relax_size
!= 0)
2703 enum insn_class tmp
;
2705 tmp
= (backup_inst1
.size
== s7_INSN_SIZE
) ? INSN_CLASS_16
: INSN_CLASS_32
;
2706 backup_inst1
.relax_inst
= s7_adjust_paritybit (backup_inst1
.relax_inst
, tmp
);
2709 /* Check data dependency. */
2710 s7_handle_dependency (&backup_inst1
);
2712 /* Start a new frag if frag_now is not empty and is not instruction frag, maybe it contains
2713 data produced by .ascii etc. Doing this is to make one instruction per frag. */
2714 if (frag_now_fix () != 0)
2716 if (!frag_now
->tc_frag_data
.is_insn
)
2717 frag_wane (frag_now
);
2722 /* Here, we must call frag_grow in order to keep the instruction frag type is
2723 rs_machine_dependent.
2724 For, frag_var may change frag_now->fr_type to rs_fill by calling frag_grow which
2725 actually will call frag_wane.
2726 Calling frag_grow first will create a new frag_now which free size is 20 that is enough
2730 p
= frag_more (backup_inst1
.size
);
2731 s7_number_to_chars (p
, backup_inst1
.instruction
, backup_inst1
.size
);
2734 dwarf2_emit_insn (backup_inst1
.size
);
2737 /* Generate fixup structure. */
2740 if (inst1
->reloc
.type
!= BFD_RELOC_NONE
)
2741 s7_fix_new_score (frag_now
, p
- frag_now
->fr_literal
,
2742 inst1
->size
, &inst1
->reloc
.exp
,
2743 inst1
->reloc
.pc_rel
, inst1
->reloc
.type
);
2745 if (inst2
->reloc
.type
!= BFD_RELOC_NONE
)
2746 s7_fix_new_score (frag_now
, p
- frag_now
->fr_literal
+ 2,
2747 inst2
->size
, &inst2
->reloc
.exp
, inst2
->reloc
.pc_rel
, inst2
->reloc
.type
);
2751 if (backup_inst1
.reloc
.type
!= BFD_RELOC_NONE
)
2752 s7_fix_new_score (frag_now
, p
- frag_now
->fr_literal
,
2753 backup_inst1
.size
, &backup_inst1
.reloc
.exp
,
2754 backup_inst1
.reloc
.pc_rel
, backup_inst1
.reloc
.type
);
2757 /* relax_size may be 2, 4, 12 or 0, 0 indicates no relaxation. */
2758 relaxable_p
&= (backup_inst1
.relax_size
!= 0);
2759 relax_size
= relaxable_p
? backup_inst1
.relax_size
: 0;
2761 p
= frag_var (rs_machine_dependent
, relax_size
+ s7_RELAX_PAD_BYTE
, 0,
2762 s7_RELAX_ENCODE (backup_inst1
.size
, backup_inst1
.relax_size
,
2763 backup_inst1
.type
, 0, 0, relaxable_p
),
2764 backup_inst1
.reloc
.exp
.X_add_symbol
, 0, NULL
);
2767 s7_number_to_chars (p
, backup_inst1
.relax_inst
, relax_size
);
2769 memcpy (inst1
, &backup_inst1
, sizeof (struct s7_score_it
));
2773 s7_parse_16_32_inst (char *insnstr
, bfd_boolean gen_frag_p
)
2777 char *operator = insnstr
;
2778 const struct s7_asm_opcode
*opcode
;
2780 /* Parse operator and operands. */
2781 s7_skip_whitespace (operator);
2783 for (p
= operator; *p
!= '\0'; p
++)
2784 if ((*p
== ' ') || (*p
== '!'))
2793 opcode
= (const struct s7_asm_opcode
*) hash_find (s7_score_ops_hsh
, operator);
2796 memset (&s7_inst
, '\0', sizeof (s7_inst
));
2797 strcpy (s7_inst
.str
, insnstr
);
2800 s7_inst
.instruction
= opcode
->value
;
2801 s7_inst
.relax_inst
= opcode
->relax_value
;
2802 s7_inst
.type
= opcode
->type
;
2803 s7_inst
.size
= s7_GET_INSN_SIZE (s7_inst
.type
);
2804 s7_inst
.relax_size
= 0;
2806 strcpy (s7_inst
.name
, opcode
->template_name
);
2807 strcpy (s7_inst
.reg
, "");
2808 s7_inst
.error
= NULL
;
2809 s7_inst
.reloc
.type
= BFD_RELOC_NONE
;
2811 (*opcode
->parms
) (p
);
2813 /* It indicates current instruction is a macro instruction if s7_inst.bwarn equals -1. */
2814 if ((s7_inst
.bwarn
!= -1) && (!s7_inst
.error
) && (gen_frag_p
))
2815 s7_gen_insn_frag (&s7_inst
, NULL
);
2818 s7_inst
.error
= _("unrecognized opcode");
2822 s7_append_insn (char *str
, bfd_boolean gen_frag_p
)
2824 int retval
= s7_SUCCESS
;
2826 s7_parse_16_32_inst (str
, gen_frag_p
);
2830 retval
= (int) s7_FAIL
;
2831 as_bad (_("%s -- `%s'"), s7_inst
.error
, s7_inst
.str
);
2832 s7_inst
.error
= NULL
;
2838 /* Handle mv! reg_high, reg_low;
2839 mv! reg_low, reg_high;
2840 mv! reg_low, reg_low; */
2842 s7_do16_mv_rdrs (char *str
)
2846 char *backupstr
= NULL
;
2849 s7_skip_whitespace (str
);
2851 if ((reg_rd
= s7_reg_required_here (&str
, 8, s7_REG_TYPE_SCORE
)) == (int) s7_FAIL
2852 || s7_skip_past_comma (&str
) == (int) s7_FAIL
2853 || (reg_rs
= s7_reg_required_here (&str
, 4, s7_REG_TYPE_SCORE
)) == (int) s7_FAIL
2854 || s7_end_of_line (str
) == (int) s7_FAIL
)
2860 /* Case 1 : mv! or mlfh!. */
2865 s7_inst
.relax_inst
|= (((s7_inst
.instruction
>> 8) & 0xf) << 20)
2866 | (((s7_inst
.instruction
>> 4) & 0xf) << 15) | (0xf << 10);
2867 s7_inst
.relax_size
= 4;
2871 char append_str
[s7_MAX_LITERAL_POOL_SIZE
];
2873 sprintf (append_str
, "mlfh! %s", backupstr
);
2874 if (s7_append_insn (append_str
, TRUE
) == (int) s7_FAIL
)
2876 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
2880 /* Case 2 : mhfl!. */
2885 s7_SET_INSN_ERROR (s7_BAD_ARGS
);
2890 char append_str
[s7_MAX_LITERAL_POOL_SIZE
];
2892 sprintf (append_str
, "mhfl! %s", backupstr
);
2893 if (s7_append_insn (append_str
, TRUE
) == (int) s7_FAIL
)
2896 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
2904 s7_do16_rdi4 (char *str
)
2906 s7_skip_whitespace (str
);
2908 if (s7_reglow_required_here (&str
, 8) == (int) s7_FAIL
2909 || s7_skip_past_comma (&str
) == (int) s7_FAIL
2910 || s7_data_op2 (&str
, 3, _IMM4
) == (int) s7_FAIL
2911 || s7_end_of_line (str
) == (int) s7_FAIL
)
2917 if (((s7_inst
.instruction
>> 3) & 0x10) == 0) /* for judge is addei or subei : bit 5 =0 : addei */
2919 if (((s7_inst
.instruction
>> 3) & 0xf) != 0xf)
2921 s7_inst
.relax_inst
|= (((s7_inst
.instruction
>> 8) & 0xf) << 20)
2922 | ((1 << ((s7_inst
.instruction
>> 3) & 0xf)) << 1);
2923 s7_inst
.relax_size
= 4;
2927 s7_inst
.relax_inst
= 0x8000;
2932 if (((s7_inst
.instruction
>> 3) & 0xf) != 0xf)
2934 s7_inst
.relax_inst
|= (((s7_inst
.instruction
>> 8) & 0xf) << 20)
2935 | (((-(1 << ((s7_inst
.instruction
>> 3) & 0xf))) & 0xffff) << 1);
2936 s7_inst
.relax_size
= 4;
2940 s7_inst
.relax_inst
= 0x8000;
2947 s7_do16_rdi5 (char *str
)
2949 s7_skip_whitespace (str
);
2951 if (s7_reglow_required_here (&str
, 8) == (int) s7_FAIL
2952 || s7_skip_past_comma (&str
) == (int) s7_FAIL
2953 || s7_data_op2 (&str
, 3, _IMM5
) == (int) s7_FAIL
2954 || s7_end_of_line (str
) == (int) s7_FAIL
)
2958 s7_inst
.relax_inst
|= (((s7_inst
.instruction
>> 8) & 0xf) << 20)
2959 | (((s7_inst
.instruction
>> 8) & 0xf) << 15) | (((s7_inst
.instruction
>> 3) & 0x1f) << 10);
2960 s7_inst
.relax_size
= 4;
2967 s7_do16_xi5 (char *str
)
2969 s7_skip_whitespace (str
);
2971 if (s7_data_op2 (&str
, 3, _IMM5
) == (int) s7_FAIL
|| s7_end_of_line (str
) == (int) s7_FAIL
)
2975 s7_inst
.relax_inst
|= (((s7_inst
.instruction
>> 3) & 0x1f) << 15);
2976 s7_inst
.relax_size
= 4;
2980 /* Check that an immediate is word alignment or half word alignment.
2981 If so, convert it to the right format. */
2984 s7_validate_immediate_align (int val
, unsigned int data_type
)
2986 if (data_type
== _IMM5_RSHIFT_1
)
2990 s7_inst
.error
= _("address offset must be half word alignment");
2991 return (int) s7_FAIL
;
2994 else if ((data_type
== _IMM5_RSHIFT_2
) || (data_type
== _IMM10_RSHIFT_2
))
2998 s7_inst
.error
= _("address offset must be word alignment");
2999 return (int) s7_FAIL
;
3007 s7_exp_ldst_offset (char **str
, int shift
, unsigned int data_type
)
3014 if ((dataptr
!= NULL
)
3015 && (((strstr (dataptr
, "0x")) != NULL
)
3016 || ((strstr (dataptr
, "0X")) != NULL
)))
3019 if ((data_type
!= _SIMM16_LA
)
3020 && (data_type
!= _VALUE_HI16
)
3021 && (data_type
!= _VALUE_LO16
)
3022 && (data_type
!= _IMM16
)
3023 && (data_type
!= _IMM15
)
3024 && (data_type
!= _IMM14
)
3025 && (data_type
!= _IMM4
)
3026 && (data_type
!= _IMM5
)
3027 && (data_type
!= _IMM8
)
3028 && (data_type
!= _IMM5_RSHIFT_1
)
3029 && (data_type
!= _IMM5_RSHIFT_2
)
3030 && (data_type
!= _SIMM12
)
3031 && (data_type
!= _SIMM15
)
3032 && (data_type
!= _SIMM14_NEG
)
3033 && (data_type
!= _IMM10_RSHIFT_2
))
3039 if (s7_my_get_expression (&s7_inst
.reloc
.exp
, str
) == (int) s7_FAIL
)
3040 return (int) s7_FAIL
;
3042 if (s7_inst
.reloc
.exp
.X_op
== O_constant
)
3044 /* Need to check the immediate align. */
3045 int value
= s7_validate_immediate_align (s7_inst
.reloc
.exp
.X_add_number
, data_type
);
3047 if (value
== (int) s7_FAIL
)
3048 return (int) s7_FAIL
;
3050 value
= s7_validate_immediate (s7_inst
.reloc
.exp
.X_add_number
, data_type
, hex_p
);
3051 if (value
== (int) s7_FAIL
)
3054 sprintf (s7_err_msg
,
3055 _("invalid constant: %d bit expression not in range %d..%d"),
3056 s7_score_df_range
[data_type
].bits
,
3057 s7_score_df_range
[data_type
].range
[0], s7_score_df_range
[data_type
].range
[1]);
3059 sprintf (s7_err_msg
,
3060 _("invalid constant: %d bit expression not in range %d..%d"),
3061 s7_score_df_range
[data_type
- 24].bits
,
3062 s7_score_df_range
[data_type
- 24].range
[0], s7_score_df_range
[data_type
- 24].range
[1]);
3063 s7_inst
.error
= s7_err_msg
;
3064 return (int) s7_FAIL
;
3067 if (data_type
== _IMM5_RSHIFT_1
)
3071 else if ((data_type
== _IMM5_RSHIFT_2
) || (data_type
== _IMM10_RSHIFT_2
))
3076 if (s7_score_df_range
[data_type
].range
[0] != 0)
3078 value
&= (1 << s7_score_df_range
[data_type
].bits
) - 1;
3081 s7_inst
.instruction
|= value
<< shift
;
3085 s7_inst
.reloc
.pc_rel
= 0;
3092 s7_do_ldst_insn (char *str
)
3104 s7_skip_whitespace (str
);
3106 if (((conflict_reg
= s7_reg_required_here (&str
, 20, s7_REG_TYPE_SCORE
)) == (int) s7_FAIL
)
3107 || (s7_skip_past_comma (&str
) == (int) s7_FAIL
))
3110 /* ld/sw rD, [rA, simm15] ld/sw rD, [rA]+, simm12 ld/sw rD, [rA, simm12]+. */
3114 s7_skip_whitespace (str
);
3116 if ((reg
= s7_reg_required_here (&str
, 15, s7_REG_TYPE_SCORE
)) == (int) s7_FAIL
)
3119 /* Conflicts can occur on stores as well as loads. */
3120 conflict_reg
= (conflict_reg
== reg
);
3121 s7_skip_whitespace (str
);
3122 temp
= str
+ 1; /* The latter will process decimal/hex expression. */
3124 /* ld/sw rD, [rA]+, simm12 ld/sw rD, [rA]+. */
3131 /* ld/sw rD, [rA]+, simm12. */
3132 if (s7_skip_past_comma (&str
) == s7_SUCCESS
)
3134 if ((s7_exp_ldst_offset (&str
, 3, _SIMM12
) == (int) s7_FAIL
)
3135 || (s7_end_of_line (str
) == (int) s7_FAIL
))
3140 unsigned int ldst_func
= s7_inst
.instruction
& OPC_PSEUDOLDST_MASK
;
3142 if ((ldst_func
== INSN_LH
)
3143 || (ldst_func
== INSN_LHU
)
3144 || (ldst_func
== INSN_LW
)
3145 || (ldst_func
== INSN_LB
)
3146 || (ldst_func
== INSN_LBU
))
3148 s7_inst
.error
= _("register same as write-back base");
3153 ldst_idx
= s7_inst
.instruction
& OPC_PSEUDOLDST_MASK
;
3154 s7_inst
.instruction
&= ~OPC_PSEUDOLDST_MASK
;
3155 s7_inst
.instruction
|= s7_score_ldst_insns
[ldst_idx
* 3 + LDST_POST
].value
;
3157 /* lw rD, [rA]+, 4 convert to pop rD, [rA]. */
3158 if ((s7_inst
.instruction
& 0x3e000007) == 0x0e000000)
3160 /* rs = r0-r7, offset = 4 */
3161 if ((((s7_inst
.instruction
>> 15) & 0x18) == 0)
3162 && (((s7_inst
.instruction
>> 3) & 0xfff) == 4))
3164 /* Relax to pophi. */
3165 if ((((s7_inst
.instruction
>> 20) & 0x10) == 0x10))
3167 s7_inst
.relax_inst
= 0x0000200a | (((s7_inst
.instruction
>> 20) & 0xf)
3169 (((s7_inst
.instruction
>> 15) & 0x7) << 4);
3174 s7_inst
.relax_inst
= 0x0000200a | (((s7_inst
.instruction
>> 20) & 0xf)
3176 (((s7_inst
.instruction
>> 15) & 0x7) << 4);
3178 s7_inst
.relax_size
= 2;
3183 /* ld/sw rD, [rA]+ convert to ld/sw rD, [rA, 0]+. */
3186 s7_SET_INSN_ERROR (NULL
);
3187 if (s7_end_of_line (str
) == (int) s7_FAIL
)
3193 value
= s7_validate_immediate (s7_inst
.reloc
.exp
.X_add_number
, _SIMM12
, 0);
3194 value
&= (1 << s7_score_df_range
[_SIMM12
].bits
) - 1;
3195 ldst_idx
= s7_inst
.instruction
& OPC_PSEUDOLDST_MASK
;
3196 s7_inst
.instruction
&= ~OPC_PSEUDOLDST_MASK
;
3197 s7_inst
.instruction
|= s7_score_ldst_insns
[ldst_idx
* 3 + pre_inc
].value
;
3198 s7_inst
.instruction
|= value
<< 3;
3199 s7_inst
.relax_inst
= 0x8000;
3203 /* ld/sw rD, [rA] convert to ld/sw rD, [rA, simm15]. */
3206 if (s7_end_of_line (str
) == (int) s7_FAIL
)
3209 ldst_idx
= s7_inst
.instruction
& OPC_PSEUDOLDST_MASK
;
3210 s7_inst
.instruction
&= ~OPC_PSEUDOLDST_MASK
;
3211 s7_inst
.instruction
|= s7_score_ldst_insns
[ldst_idx
* 3 + LDST_NOUPDATE
].value
;
3213 /* lbu rd, [rs] -> lbu! rd, [rs] */
3214 if (ldst_idx
== INSN_LBU
)
3216 s7_inst
.relax_inst
= INSN16_LBU
;
3218 else if (ldst_idx
== INSN_LH
)
3220 s7_inst
.relax_inst
= INSN16_LH
;
3222 else if (ldst_idx
== INSN_LW
)
3224 s7_inst
.relax_inst
= INSN16_LW
;
3226 else if (ldst_idx
== INSN_SB
)
3228 s7_inst
.relax_inst
= INSN16_SB
;
3230 else if (ldst_idx
== INSN_SH
)
3232 s7_inst
.relax_inst
= INSN16_SH
;
3234 else if (ldst_idx
== INSN_SW
)
3236 s7_inst
.relax_inst
= INSN16_SW
;
3240 s7_inst
.relax_inst
= 0x8000;
3243 /* lw/lh/lbu/sw/sh/sb, offset = 0, relax to 16 bit instruction. */
3244 if ((ldst_idx
== INSN_LBU
)
3245 || (ldst_idx
== INSN_LH
)
3246 || (ldst_idx
== INSN_LW
)
3247 || (ldst_idx
== INSN_SB
) || (ldst_idx
== INSN_SH
) || (ldst_idx
== INSN_SW
))
3249 if ((((s7_inst
.instruction
>> 15) & 0x10) == 0) && (((s7_inst
.instruction
>> 20) & 0x10) == 0))
3251 s7_inst
.relax_inst
|= (2 << 12) | (((s7_inst
.instruction
>> 20) & 0xf) << 8) |
3252 (((s7_inst
.instruction
>> 15) & 0xf) << 4);
3253 s7_inst
.relax_size
= 2;
3260 /* ld/sw rD, [rA, simm15] ld/sw rD, [rA, simm12]+. */
3263 if (s7_skip_past_comma (&str
) == (int) s7_FAIL
)
3265 s7_inst
.error
= _("pre-indexed expression expected");
3269 if (s7_my_get_expression (&s7_inst
.reloc
.exp
, &str
) == (int) s7_FAIL
)
3272 s7_skip_whitespace (str
);
3275 s7_inst
.error
= _("missing ]");
3279 s7_skip_whitespace (str
);
3280 /* ld/sw rD, [rA, simm12]+. */
3287 unsigned int ldst_func
= s7_inst
.instruction
& OPC_PSEUDOLDST_MASK
;
3289 if ((ldst_func
== INSN_LH
)
3290 || (ldst_func
== INSN_LHU
)
3291 || (ldst_func
== INSN_LW
)
3292 || (ldst_func
== INSN_LB
)
3293 || (ldst_func
== INSN_LBU
))
3295 s7_inst
.error
= _("register same as write-back base");
3301 if (s7_end_of_line (str
) == (int) s7_FAIL
)
3304 if (s7_inst
.reloc
.exp
.X_op
== O_constant
)
3306 unsigned int data_type
;
3309 data_type
= _SIMM12
;
3311 data_type
= _SIMM15
;
3314 if ((dataptr
!= NULL
)
3315 && (((strstr (dataptr
, "0x")) != NULL
)
3316 || ((strstr (dataptr
, "0X")) != NULL
)))
3319 if ((data_type
!= _SIMM16_LA
)
3320 && (data_type
!= _VALUE_HI16
)
3321 && (data_type
!= _VALUE_LO16
)
3322 && (data_type
!= _IMM16
)
3323 && (data_type
!= _IMM15
)
3324 && (data_type
!= _IMM14
)
3325 && (data_type
!= _IMM4
)
3326 && (data_type
!= _IMM5
)
3327 && (data_type
!= _IMM8
)
3328 && (data_type
!= _SIMM12
)
3329 && (data_type
!= _SIMM15
)
3330 && (data_type
!= _IMM5_RSHIFT_1
)
3331 && (data_type
!= _IMM5_RSHIFT_2
)
3332 && (data_type
!= _SIMM14_NEG
)
3333 && (data_type
!= _IMM10_RSHIFT_2
))
3339 value
= s7_validate_immediate (s7_inst
.reloc
.exp
.X_add_number
, data_type
, hex_p
);
3340 if (value
== (int) s7_FAIL
)
3343 sprintf (s7_err_msg
,
3344 _("invalid constant: %d bit expression not in range %d..%d"),
3345 s7_score_df_range
[data_type
].bits
,
3346 s7_score_df_range
[data_type
].range
[0], s7_score_df_range
[data_type
].range
[1]);
3348 sprintf (s7_err_msg
,
3349 _("invalid constant: %d bit expression not in range %d..%d"),
3350 s7_score_df_range
[data_type
- 24].bits
,
3351 s7_score_df_range
[data_type
- 24].range
[0],
3352 s7_score_df_range
[data_type
- 24].range
[1]);
3353 s7_inst
.error
= s7_err_msg
;
3357 value
&= (1 << s7_score_df_range
[data_type
].bits
) - 1;
3358 ldst_idx
= s7_inst
.instruction
& OPC_PSEUDOLDST_MASK
;
3359 s7_inst
.instruction
&= ~OPC_PSEUDOLDST_MASK
;
3360 s7_inst
.instruction
|= s7_score_ldst_insns
[ldst_idx
* 3 + pre_inc
].value
;
3362 s7_inst
.instruction
|= value
<< 3;
3364 s7_inst
.instruction
|= value
;
3366 /* lw rD, [rA, simm15] */
3367 if ((s7_inst
.instruction
& 0x3e000000) == 0x20000000)
3369 /* Both rD and rA are in [r0 - r15]. */
3370 if ((((s7_inst
.instruction
>> 15) & 0x10) == 0)
3371 && (((s7_inst
.instruction
>> 20) & 0x10) == 0))
3373 /* simm15 = 0, lw -> lw!. */
3374 if ((s7_inst
.instruction
& 0x7fff) == 0)
3376 s7_inst
.relax_inst
|= (((s7_inst
.instruction
>> 15) & 0xf) << 4)
3377 | (((s7_inst
.instruction
>> 20) & 0xf) << 8);
3378 s7_inst
.relax_size
= 2;
3380 /* rA = r2, lw -> lwp!. */
3381 else if ((((s7_inst
.instruction
>> 15) & 0xf) == 2)
3382 && ((s7_inst
.instruction
& 0x3) == 0)
3383 && ((s7_inst
.instruction
& 0x7fff) < 128))
3385 s7_inst
.relax_inst
= 0x7000 | (((s7_inst
.instruction
>> 20) & 0xf) << 8)
3386 | (((s7_inst
.instruction
& 0x7fff) >> 2) << 3);
3387 s7_inst
.relax_size
= 2;
3391 s7_inst
.relax_inst
= 0x8000;
3396 s7_inst
.relax_inst
= 0x8000;
3399 /* sw rD, [rA, simm15] */
3400 else if ((s7_inst
.instruction
& 0x3e000000) == 0x28000000)
3402 /* Both rD and rA are in [r0 - r15]. */
3403 if ((((s7_inst
.instruction
>> 15) & 0x10) == 0) && (((s7_inst
.instruction
>> 20) & 0x10) == 0))
3405 /* simm15 = 0, sw -> sw!. */
3406 if ((s7_inst
.instruction
& 0x7fff) == 0)
3408 s7_inst
.relax_inst
|= (((s7_inst
.instruction
>> 15) & 0xf) << 4)
3409 | (((s7_inst
.instruction
>> 20) & 0xf) << 8);
3410 s7_inst
.relax_size
= 2;
3412 /* rA = r2, sw -> swp!. */
3413 else if ((((s7_inst
.instruction
>> 15) & 0xf) == 2)
3414 && ((s7_inst
.instruction
& 0x3) == 0)
3415 && ((s7_inst
.instruction
& 0x7fff) < 128))
3417 s7_inst
.relax_inst
= 0x7004 | (((s7_inst
.instruction
>> 20) & 0xf) << 8)
3418 | (((s7_inst
.instruction
& 0x7fff) >> 2) << 3);
3419 s7_inst
.relax_size
= 2;
3423 s7_inst
.relax_inst
= 0x8000;
3428 s7_inst
.relax_inst
= 0x8000;
3431 /* sw rD, [rA, simm15]+ sw pre. */
3432 else if ((s7_inst
.instruction
& 0x3e000007) == 0x06000004)
3434 /* rA is in [r0 - r7], and simm15 = -4. */
3435 if ((((s7_inst
.instruction
>> 15) & 0x18) == 0)
3436 && (((s7_inst
.instruction
>> 3) & 0xfff) == 0xffc))
3438 /* sw -> pushhi!. */
3439 if ((((s7_inst
.instruction
>> 20) & 0x10) == 0x10))
3441 s7_inst
.relax_inst
= 0x0000200e | (((s7_inst
.instruction
>> 20) & 0xf) << 8)
3442 | 1 << 7 | (((s7_inst
.instruction
>> 15) & 0x7) << 4);
3443 s7_inst
.relax_size
= 2;
3448 s7_inst
.relax_inst
= 0x0000200e | (((s7_inst
.instruction
>> 20) & 0xf) << 8)
3449 | 0 << 7 | (((s7_inst
.instruction
>> 15) & 0x7) << 4);
3450 s7_inst
.relax_size
= 2;
3455 s7_inst
.relax_inst
= 0x8000;
3458 /* lh rD, [rA, simm15] */
3459 else if ((s7_inst
.instruction
& 0x3e000000) == 0x22000000)
3461 /* Both rD and rA are in [r0 - r15]. */
3462 if ((((s7_inst
.instruction
>> 15) & 0x10) == 0) && (((s7_inst
.instruction
>> 20) & 0x10) == 0))
3464 /* simm15 = 0, lh -> lh!. */
3465 if ((s7_inst
.instruction
& 0x7fff) == 0)
3467 s7_inst
.relax_inst
|= (((s7_inst
.instruction
>> 15) & 0xf) << 4)
3468 | (((s7_inst
.instruction
>> 20) & 0xf) << 8);
3469 s7_inst
.relax_size
= 2;
3471 /* rA = r2, lh -> lhp!. */
3472 else if ((((s7_inst
.instruction
>> 15) & 0xf) == 2)
3473 && ((s7_inst
.instruction
& 0x1) == 0)
3474 && ((s7_inst
.instruction
& 0x7fff) < 64))
3476 s7_inst
.relax_inst
= 0x7001 | (((s7_inst
.instruction
>> 20) & 0xf) << 8)
3477 | (((s7_inst
.instruction
& 0x7fff) >> 1) << 3);
3478 s7_inst
.relax_size
= 2;
3482 s7_inst
.relax_inst
= 0x8000;
3487 s7_inst
.relax_inst
= 0x8000;
3490 /* sh rD, [rA, simm15] */
3491 else if ((s7_inst
.instruction
& 0x3e000000) == 0x2a000000)
3493 /* Both rD and rA are in [r0 - r15]. */
3494 if ((((s7_inst
.instruction
>> 15) & 0x10) == 0) && (((s7_inst
.instruction
>> 20) & 0x10) == 0))
3496 /* simm15 = 0, sh -> sh!. */
3497 if ((s7_inst
.instruction
& 0x7fff) == 0)
3499 s7_inst
.relax_inst
|= (((s7_inst
.instruction
>> 15) & 0xf) << 4)
3500 | (((s7_inst
.instruction
>> 20) & 0xf) << 8);
3501 s7_inst
.relax_size
= 2;
3503 /* rA = r2, sh -> shp!. */
3504 else if ((((s7_inst
.instruction
>> 15) & 0xf) == 2)
3505 && ((s7_inst
.instruction
& 0x1) == 0)
3506 && ((s7_inst
.instruction
& 0x7fff) < 64))
3508 s7_inst
.relax_inst
= 0x7005 | (((s7_inst
.instruction
>> 20) & 0xf) << 8)
3509 | (((s7_inst
.instruction
& 0x7fff) >> 1) << 3);
3510 s7_inst
.relax_size
= 2;
3514 s7_inst
.relax_inst
= 0x8000;
3519 s7_inst
.relax_inst
= 0x8000;
3522 /* lbu rD, [rA, simm15] */
3523 else if ((s7_inst
.instruction
& 0x3e000000) == 0x2c000000)
3525 /* Both rD and rA are in [r0 - r15]. */
3526 if ((((s7_inst
.instruction
>> 15) & 0x10) == 0) && (((s7_inst
.instruction
>> 20) & 0x10) == 0))
3528 /* simm15 = 0, lbu -> lbu!. */
3529 if ((s7_inst
.instruction
& 0x7fff) == 0)
3531 s7_inst
.relax_inst
|= (((s7_inst
.instruction
>> 15) & 0xf) << 4)
3532 | (((s7_inst
.instruction
>> 20) & 0xf) << 8);
3533 s7_inst
.relax_size
= 2;
3535 /* rA = r2, lbu -> lbup!. */
3536 else if ((((s7_inst
.instruction
>> 15) & 0xf) == 2)
3537 && ((s7_inst
.instruction
& 0x7fff) < 32))
3539 s7_inst
.relax_inst
= 0x7003 | (((s7_inst
.instruction
>> 20) & 0xf) << 8)
3540 | ((s7_inst
.instruction
& 0x7fff) << 3);
3541 s7_inst
.relax_size
= 2;
3545 s7_inst
.relax_inst
= 0x8000;
3550 s7_inst
.relax_inst
= 0x8000;
3553 /* sb rD, [rA, simm15] */
3554 else if ((s7_inst
.instruction
& 0x3e000000) == 0x2e000000)
3556 /* Both rD and rA are in [r0 - r15]. */
3557 if ((((s7_inst
.instruction
>> 15) & 0x10) == 0) && (((s7_inst
.instruction
>> 20) & 0x10) == 0))
3559 /* simm15 = 0, sb -> sb!. */
3560 if ((s7_inst
.instruction
& 0x7fff) == 0)
3562 s7_inst
.relax_inst
|= (((s7_inst
.instruction
>> 15) & 0xf) << 4)
3563 | (((s7_inst
.instruction
>> 20) & 0xf) << 8);
3564 s7_inst
.relax_size
= 2;
3566 /* rA = r2, sb -> sb!. */
3567 else if ((((s7_inst
.instruction
>> 15) & 0xf) == 2)
3568 && ((s7_inst
.instruction
& 0x7fff) < 32))
3570 s7_inst
.relax_inst
= 0x7007 | (((s7_inst
.instruction
>> 20) & 0xf) << 8)
3571 | ((s7_inst
.instruction
& 0x7fff) << 3);
3572 s7_inst
.relax_size
= 2;
3576 s7_inst
.relax_inst
= 0x8000;
3581 s7_inst
.relax_inst
= 0x8000;
3586 s7_inst
.relax_inst
= 0x8000;
3593 /* FIXME: may set error, for there is no ld/sw rD, [rA, label] */
3594 s7_inst
.reloc
.pc_rel
= 0;
3600 s7_inst
.error
= s7_BAD_ARGS
;
3606 s7_do_cache (char *str
)
3608 s7_skip_whitespace (str
);
3610 if ((s7_data_op2 (&str
, 20, _IMM5
) == (int) s7_FAIL
) || (s7_skip_past_comma (&str
) == (int) s7_FAIL
))
3618 cache_op
= (s7_inst
.instruction
>> 20) & 0x1F;
3619 sprintf (s7_inst
.name
, "cache %d", cache_op
);
3625 s7_skip_whitespace (str
);
3627 if (s7_reg_required_here (&str
, 15, s7_REG_TYPE_SCORE
) == (int) s7_FAIL
)
3630 s7_skip_whitespace (str
);
3632 /* cache op, [rA] */
3633 if (s7_skip_past_comma (&str
) == (int) s7_FAIL
)
3635 s7_SET_INSN_ERROR (NULL
);
3638 s7_inst
.error
= _("missing ]");
3643 /* cache op, [rA, simm15] */
3646 if (s7_exp_ldst_offset (&str
, 0, _SIMM15
) == (int) s7_FAIL
)
3651 s7_skip_whitespace (str
);
3654 s7_inst
.error
= _("missing ]");
3659 if (s7_end_of_line (str
) == (int) s7_FAIL
)
3664 s7_inst
.error
= s7_BAD_ARGS
;
3669 s7_do_crdcrscrsimm5 (char *str
)
3674 s7_skip_whitespace (str
);
3676 if (s7_reg_required_here (&str
, 20, s7_REG_TYPE_SCORE_CR
) == (int) s7_FAIL
3677 || s7_skip_past_comma (&str
) == (int) s7_FAIL
3678 || s7_reg_required_here (&str
, 15, s7_REG_TYPE_SCORE_CR
) == (int) s7_FAIL
3679 || s7_skip_past_comma (&str
) == (int) s7_FAIL
3680 || s7_reg_required_here (&str
, 10, s7_REG_TYPE_SCORE_CR
) == (int) s7_FAIL
3681 || s7_skip_past_comma (&str
) == (int) s7_FAIL
)
3684 /* cop1 cop_code20. */
3685 if (s7_data_op2 (&str
, 5, _IMM20
) == (int) s7_FAIL
)
3690 if (s7_data_op2 (&str
, 5, _IMM5
) == (int) s7_FAIL
)
3694 s7_end_of_line (str
);
3697 /* Handle ldc/stc. */
3699 s7_do_ldst_cop (char *str
)
3701 s7_skip_whitespace (str
);
3703 if ((s7_reg_required_here (&str
, 15, s7_REG_TYPE_SCORE_CR
) == (int) s7_FAIL
)
3704 || (s7_skip_past_comma (&str
) == (int) s7_FAIL
))
3710 s7_skip_whitespace (str
);
3712 if (s7_reg_required_here (&str
, 20, s7_REG_TYPE_SCORE
) == (int) s7_FAIL
)
3715 s7_skip_whitespace (str
);
3719 if (s7_exp_ldst_offset (&str
, 5, _IMM10_RSHIFT_2
) == (int) s7_FAIL
)
3722 s7_skip_whitespace (str
);
3725 s7_inst
.error
= _("missing ]");
3730 s7_end_of_line (str
);
3733 s7_inst
.error
= s7_BAD_ARGS
;
3737 s7_do16_ldst_insn (char *str
)
3739 s7_skip_whitespace (str
);
3741 if ((s7_reglow_required_here (&str
, 8) == (int) s7_FAIL
) || (s7_skip_past_comma (&str
) == (int) s7_FAIL
))
3749 s7_skip_whitespace (str
);
3751 if ((reg
= s7_reglow_required_here (&str
, 4)) == (int) s7_FAIL
)
3754 s7_skip_whitespace (str
);
3757 if (s7_end_of_line (str
) == (int) s7_FAIL
)
3761 s7_inst
.relax_inst
|= (((s7_inst
.instruction
>> 8) & 0xf) << 20)
3762 | (((s7_inst
.instruction
>> 4) & 0xf) << 15);
3763 s7_inst
.relax_size
= 4;
3768 s7_inst
.error
= _("missing ]");
3773 s7_inst
.error
= s7_BAD_ARGS
;
3777 /* Handle lbup!/lhp!/ldiu!/lwp!/sbp!/shp!/swp!. */
3780 s7_do16_ldst_imm_insn (char *str
)
3782 char data_exp
[s7_MAX_LITERAL_POOL_SIZE
];
3784 char *dataptr
= NULL
, *pp
= NULL
;
3786 int assign_data
= (int) s7_FAIL
;
3787 unsigned int ldst_func
;
3789 s7_skip_whitespace (str
);
3791 if (((reg_rd
= s7_reglow_required_here (&str
, 8)) == (int) s7_FAIL
)
3792 || (s7_skip_past_comma (&str
) == (int) s7_FAIL
))
3795 s7_skip_whitespace (str
);
3798 while ((*dataptr
!= '\0') && (*dataptr
!= '|') && (cnt
<= s7_MAX_LITERAL_POOL_SIZE
))
3800 data_exp
[cnt
] = *dataptr
;
3805 data_exp
[cnt
] = '\0';
3810 ldst_func
= s7_inst
.instruction
& LDST16_RI_MASK
;
3811 if (ldst_func
== N16_LIU
)
3812 assign_data
= s7_exp_ldst_offset (&pp
, 0, _IMM8
);
3813 else if (ldst_func
== N16_LHP
|| ldst_func
== N16_SHP
)
3814 assign_data
= s7_exp_ldst_offset (&pp
, 3, _IMM5_RSHIFT_1
);
3815 else if (ldst_func
== N16_LWP
|| ldst_func
== N16_SWP
)
3816 assign_data
= s7_exp_ldst_offset (&pp
, 3, _IMM5_RSHIFT_2
);
3818 assign_data
= s7_exp_ldst_offset (&pp
, 3, _IMM5
);
3820 if ((assign_data
== (int) s7_FAIL
) || (s7_end_of_line (pp
) == (int) s7_FAIL
))
3824 if ((s7_inst
.instruction
& 0x7000) == N16_LIU
)
3826 s7_inst
.relax_inst
|= ((s7_inst
.instruction
>> 8) & 0xf) << 20
3827 | ((s7_inst
.instruction
& 0xff) << 1);
3829 else if (((s7_inst
.instruction
& 0x7007) == N16_LHP
)
3830 || ((s7_inst
.instruction
& 0x7007) == N16_SHP
))
3832 s7_inst
.relax_inst
|= ((s7_inst
.instruction
>> 8) & 0xf) << 20 | 2 << 15
3833 | (((s7_inst
.instruction
>> 3) & 0x1f) << 1);
3835 else if (((s7_inst
.instruction
& 0x7007) == N16_LWP
)
3836 || ((s7_inst
.instruction
& 0x7007) == N16_SWP
))
3838 s7_inst
.relax_inst
|= ((s7_inst
.instruction
>> 8) & 0xf) << 20 | 2 << 15
3839 | (((s7_inst
.instruction
>> 3) & 0x1f) << 2);
3841 else if (((s7_inst
.instruction
& 0x7007) == N16_LBUP
)
3842 || ((s7_inst
.instruction
& 0x7007) == N16_SBP
))
3844 s7_inst
.relax_inst
|= ((s7_inst
.instruction
>> 8) & 0xf) << 20 | 2 << 15
3845 | (((s7_inst
.instruction
>> 3) & 0x1f));
3848 s7_inst
.relax_size
= 4;
3853 s7_do16_push_pop (char *str
)
3858 s7_skip_whitespace (str
);
3859 if (((reg_rd
= s7_reg_required_here (&str
, 8, s7_REG_TYPE_SCORE
)) == (int) s7_FAIL
)
3860 || (s7_skip_past_comma (&str
) == (int) s7_FAIL
))
3866 /* s7_reg_required_here will change bit 12 of opcode, so we must restore bit 12. */
3867 s7_inst
.instruction
&= ~(1 << 12);
3869 s7_inst
.instruction
|= H_bit_mask
<< 7;
3876 s7_skip_whitespace (str
);
3877 if ((reg
= s7_reg_required_here (&str
, 4, s7_REG_TYPE_SCORE
)) == (int) s7_FAIL
)
3882 s7_inst
.error
= _("base register nums are over 3 bit");
3887 s7_skip_whitespace (str
);
3888 if ((*str
++ != ']') || (s7_end_of_line (str
) == (int) s7_FAIL
))
3891 s7_inst
.error
= _("missing ]");
3897 if ((s7_inst
.instruction
& 0xf) == 0xa)
3901 s7_inst
.relax_inst
|= ((((s7_inst
.instruction
>> 8) & 0xf) | 0x10) << 20)
3902 | (((s7_inst
.instruction
>> 4) & 0x7) << 15) | (4 << 3);
3906 s7_inst
.relax_inst
|= (((s7_inst
.instruction
>> 8) & 0xf) << 20)
3907 | (((s7_inst
.instruction
>> 4) & 0x7) << 15) | (4 << 3);
3915 s7_inst
.relax_inst
|= ((((s7_inst
.instruction
>> 8) & 0xf) | 0x10) << 20)
3916 | (((s7_inst
.instruction
>> 4) & 0x7) << 15) | (((-4) & 0xfff) << 3);
3920 s7_inst
.relax_inst
|= (((s7_inst
.instruction
>> 8) & 0xf) << 20)
3921 | (((s7_inst
.instruction
>> 4) & 0x7) << 15) | (((-4) & 0xfff) << 3);
3924 s7_inst
.relax_size
= 4;
3928 s7_inst
.error
= s7_BAD_ARGS
;
3932 /* Handle lcb/lcw/lce/scb/scw/sce. */
3934 s7_do_ldst_unalign (char *str
)
3938 if (s7_university_version
== 1)
3940 s7_inst
.error
= s7_ERR_FOR_SCORE5U_ATOMIC
;
3944 s7_skip_whitespace (str
);
3946 /* lcb/scb [rA]+. */
3950 s7_skip_whitespace (str
);
3952 if (s7_reg_required_here (&str
, 15, s7_REG_TYPE_SCORE
) == (int) s7_FAIL
)
3959 s7_inst
.error
= _("missing +");
3965 s7_inst
.error
= _("missing ]");
3969 if (s7_end_of_line (str
) == (int) s7_FAIL
)
3972 /* lcw/lce/scb/sce rD, [rA]+. */
3975 if (((conflict_reg
= s7_reg_required_here (&str
, 20, s7_REG_TYPE_SCORE
)) == (int) s7_FAIL
)
3976 || (s7_skip_past_comma (&str
) == (int) s7_FAIL
))
3981 s7_skip_whitespace (str
);
3986 s7_skip_whitespace (str
);
3987 if ((reg
= s7_reg_required_here (&str
, 15, s7_REG_TYPE_SCORE
)) == (int) s7_FAIL
)
3992 /* Conflicts can occur on stores as well as loads. */
3993 conflict_reg
= (conflict_reg
== reg
);
3994 s7_skip_whitespace (str
);
3997 unsigned int ldst_func
= s7_inst
.instruction
& LDST_UNALIGN_MASK
;
4003 as_warn (_("%s register same as write-back base"),
4004 ((ldst_func
& UA_LCE
) || (ldst_func
& UA_LCW
)
4005 ? _("destination") : _("source")));
4010 s7_inst
.error
= _("missing +");
4014 if (s7_end_of_line (str
) == (int) s7_FAIL
)
4019 s7_inst
.error
= _("missing ]");
4025 s7_inst
.error
= s7_BAD_ARGS
;
4031 /* Handle alw/asw. */
4034 s7_do_ldst_atomic (char *str
)
4036 if (s7_university_version
== 1)
4038 s7_inst
.error
= s7_ERR_FOR_SCORE5U_ATOMIC
;
4042 s7_skip_whitespace (str
);
4044 if ((s7_reg_required_here (&str
, 20, s7_REG_TYPE_SCORE
) == (int) s7_FAIL
)
4045 || (s7_skip_past_comma (&str
) == (int) s7_FAIL
))
4052 s7_skip_whitespace (str
);
4057 s7_skip_whitespace (str
);
4058 if ((reg
= s7_reg_required_here (&str
, 15, s7_REG_TYPE_SCORE
)) == (int) s7_FAIL
)
4063 s7_skip_whitespace (str
);
4066 s7_inst
.error
= _("missing ]");
4070 s7_end_of_line (str
);
4073 s7_inst
.error
= s7_BAD_ARGS
;
4078 s7_build_relax_frag (struct s7_score_it fix_insts
[s7_RELAX_INST_NUM
],
4079 int fix_num ATTRIBUTE_UNUSED
,
4080 struct s7_score_it var_insts
[s7_RELAX_INST_NUM
], int var_num
,
4081 symbolS
*add_symbol
)
4086 fixS
*cur_fixp
= NULL
;
4088 struct s7_score_it inst_main
;
4090 memcpy (&inst_main
, &fix_insts
[0], sizeof (struct s7_score_it
));
4092 /* Adjust instruction opcode and to be relaxed instruction opcode. */
4093 inst_main
.instruction
= s7_adjust_paritybit (inst_main
.instruction
, s7_GET_INSN_CLASS (inst_main
.type
));
4094 inst_main
.type
= Insn_PIC
;
4096 for (i
= 0; i
< var_num
; i
++)
4098 inst_main
.relax_size
+= var_insts
[i
].size
;
4099 var_insts
[i
].instruction
= s7_adjust_paritybit (var_insts
[i
].instruction
,
4100 s7_GET_INSN_CLASS (var_insts
[i
].type
));
4103 /* Check data dependency. */
4104 s7_handle_dependency (&inst_main
);
4106 /* Start a new frag if frag_now is not empty. */
4107 if (frag_now_fix () != 0)
4109 if (!frag_now
->tc_frag_data
.is_insn
)
4111 frag_wane (frag_now
);
4117 /* Write fr_fix part. */
4118 p
= frag_more (inst_main
.size
);
4119 s7_number_to_chars (p
, inst_main
.instruction
, inst_main
.size
);
4121 if (inst_main
.reloc
.type
!= BFD_RELOC_NONE
)
4122 fixp
= s7_fix_new_score (frag_now
, p
- frag_now
->fr_literal
, inst_main
.size
,
4123 &inst_main
.reloc
.exp
, inst_main
.reloc
.pc_rel
, inst_main
.reloc
.type
);
4125 frag_now
->tc_frag_data
.fixp
= fixp
;
4126 cur_fixp
= frag_now
->tc_frag_data
.fixp
;
4129 dwarf2_emit_insn (inst_main
.size
);
4132 where
= p
- frag_now
->fr_literal
+ inst_main
.size
;
4133 for (i
= 0; i
< var_num
; i
++)
4136 where
+= var_insts
[i
- 1].size
;
4138 if (var_insts
[i
].reloc
.type
!= BFD_RELOC_NONE
)
4140 fixp
= s7_fix_new_score (frag_now
, where
, var_insts
[i
].size
,
4141 &var_insts
[i
].reloc
.exp
, var_insts
[i
].reloc
.pc_rel
,
4142 var_insts
[i
].reloc
.type
);
4147 cur_fixp
->fx_next
= fixp
;
4148 cur_fixp
= cur_fixp
->fx_next
;
4152 frag_now
->tc_frag_data
.fixp
= fixp
;
4153 cur_fixp
= frag_now
->tc_frag_data
.fixp
;
4159 p
= frag_var (rs_machine_dependent
, inst_main
.relax_size
+ s7_RELAX_PAD_BYTE
, 0,
4160 s7_RELAX_ENCODE (inst_main
.size
, inst_main
.relax_size
, inst_main
.type
,
4161 0, inst_main
.size
, 0), add_symbol
, 0, NULL
);
4163 /* Write fr_var part.
4164 no calling s7_gen_insn_frag, no fixS will be generated. */
4165 for (i
= 0; i
< var_num
; i
++)
4167 s7_number_to_chars (p
, var_insts
[i
].instruction
, var_insts
[i
].size
);
4168 p
+= var_insts
[i
].size
;
4170 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4174 /* Build a relax frag for la instruction when generating s7_PIC,
4175 external symbol first and local symbol second. */
4178 s7_build_la_pic (int reg_rd
, expressionS exp
)
4180 symbolS
*add_symbol
= exp
.X_add_symbol
;
4181 offsetT add_number
= exp
.X_add_number
;
4182 struct s7_score_it fix_insts
[s7_RELAX_INST_NUM
];
4183 struct s7_score_it var_insts
[s7_RELAX_INST_NUM
];
4186 char tmp
[s7_MAX_LITERAL_POOL_SIZE
];
4192 if (add_number
== 0)
4197 /* For an external symbol, only one insn is generated;
4198 For a local symbol, two insns are generated. */
4200 For an external symbol: lw rD, <sym>($gp)
4201 (BFD_RELOC_SCORE_GOT15 or BFD_RELOC_SCORE_CALL15) */
4202 sprintf (tmp
, "lw_pic r%d, %s", reg_rd
, S_GET_NAME (add_symbol
));
4203 if (s7_append_insn (tmp
, FALSE
) == (int) s7_FAIL
)
4206 if (reg_rd
== s7_PIC_CALL_REG
)
4207 s7_inst
.reloc
.type
= BFD_RELOC_SCORE_CALL15
;
4208 memcpy (&fix_insts
[0], &s7_inst
, sizeof (struct s7_score_it
));
4211 For a local symbol :
4212 lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15)
4213 addi rD, <sym> (BFD_RELOC_GOT_LO16) */
4214 s7_inst
.reloc
.type
= BFD_RELOC_SCORE_GOT15
;
4215 memcpy (&var_insts
[0], &s7_inst
, sizeof (struct s7_score_it
));
4216 sprintf (tmp
, "addi_s_pic r%d, %s", reg_rd
, S_GET_NAME (add_symbol
));
4217 if (s7_append_insn (tmp
, FALSE
) == (int) s7_FAIL
)
4220 memcpy (&var_insts
[1], &s7_inst
, sizeof (struct s7_score_it
));
4221 s7_build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
4223 else if (add_number
>= -0x8000 && add_number
<= 0x7fff)
4225 /* Insn 1: lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15) */
4226 sprintf (tmp
, "lw_pic r%d, %s", reg_rd
, S_GET_NAME (add_symbol
));
4227 if (s7_append_insn (tmp
, TRUE
) == (int) s7_FAIL
)
4234 For an external symbol: addi rD, <constant> */
4235 sprintf (tmp
, "addi r%d, %d", reg_rd
, (int) add_number
);
4236 if (s7_append_insn (tmp
, FALSE
) == (int) s7_FAIL
)
4239 memcpy (&fix_insts
[0], &s7_inst
, sizeof (struct s7_score_it
));
4242 For a local symbol: addi rD, <sym>+<constant> (BFD_RELOC_GOT_LO16) */
4243 sprintf (tmp
, "addi_s_pic r%d, %s + %d", reg_rd
,
4244 S_GET_NAME (add_symbol
), (int) add_number
);
4245 if (s7_append_insn (tmp
, FALSE
) == (int) s7_FAIL
)
4248 memcpy (&var_insts
[0], &s7_inst
, sizeof (struct s7_score_it
));
4249 s7_build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
4253 int hi
= (add_number
>> 16) & 0x0000FFFF;
4254 int lo
= add_number
& 0x0000FFFF;
4256 /* Insn 1: lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15) */
4257 sprintf (tmp
, "lw_pic r%d, %s", reg_rd
, S_GET_NAME (add_symbol
));
4258 if (s7_append_insn (tmp
, TRUE
) == (int) s7_FAIL
)
4265 For an external symbol: ldis r1, HI%<constant> */
4266 sprintf (tmp
, "ldis r1, %d", hi
);
4267 if (s7_append_insn (tmp
, FALSE
) == (int) s7_FAIL
)
4270 memcpy (&fix_insts
[0], &s7_inst
, sizeof (struct s7_score_it
));
4273 For a local symbol: ldis r1, HI%<constant>
4274 but, if lo is out of 16 bit, make hi plus 1 */
4275 if ((lo
< -0x8000) || (lo
> 0x7fff))
4279 sprintf (tmp
, "ldis_pic r1, %d", hi
);
4280 if (s7_append_insn (tmp
, FALSE
) == (int) s7_FAIL
)
4283 memcpy (&var_insts
[0], &s7_inst
, sizeof (struct s7_score_it
));
4284 s7_build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
4290 For an external symbol: ori r1, LO%<constant> */
4291 sprintf (tmp
, "ori r1, %d", lo
);
4292 if (s7_append_insn (tmp
, FALSE
) == (int) s7_FAIL
)
4295 memcpy (&fix_insts
[0], &s7_inst
, sizeof (struct s7_score_it
));
4298 For a local symbol: addi r1, <sym>+LO%<constant> (BFD_RELOC_GOT_LO16) */
4299 sprintf (tmp
, "addi_u_pic r1, %s + %d", S_GET_NAME (add_symbol
), lo
);
4300 if (s7_append_insn (tmp
, FALSE
) == (int) s7_FAIL
)
4303 memcpy (&var_insts
[0], &s7_inst
, sizeof (struct s7_score_it
));
4304 s7_build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
4306 /* Insn 4: add rD, rD, r1 */
4307 sprintf (tmp
, "add r%d, r%d, r1", reg_rd
, reg_rd
);
4308 if (s7_append_insn (tmp
, TRUE
) == (int) s7_FAIL
)
4311 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4321 s7_do_macro_la_rdi32 (char *str
)
4325 s7_skip_whitespace (str
);
4326 if ((reg_rd
= s7_reg_required_here (&str
, 20, s7_REG_TYPE_SCORE
)) == (int) s7_FAIL
4327 || s7_skip_past_comma (&str
) == (int) s7_FAIL
)
4333 char append_str
[s7_MAX_LITERAL_POOL_SIZE
];
4334 char *keep_data
= str
;
4336 /* Check immediate value. */
4337 if (s7_my_get_expression (&s7_inst
.reloc
.exp
, &str
) == (int) s7_FAIL
)
4339 s7_inst
.error
= _("expression error");
4342 else if ((s7_inst
.reloc
.exp
.X_add_symbol
== NULL
)
4343 && (s7_validate_immediate (s7_inst
.reloc
.exp
.X_add_number
, _IMM32
, 0) == (int) s7_FAIL
))
4345 s7_inst
.error
= _("value not in range [0, 0xffffffff]");
4352 /* la rd, simm16. */
4353 if (s7_data_op2 (&str
, 1, _SIMM16_LA
) != (int) s7_FAIL
)
4355 s7_end_of_line (str
);
4358 /* la rd, imm32 or la rd, label. */
4361 s7_SET_INSN_ERROR (NULL
);
4363 if ((s7_data_op2 (&str
, 1, _VALUE_HI16
) == (int) s7_FAIL
)
4364 || (s7_end_of_line (str
) == (int) s7_FAIL
))
4370 if ((s7_score_pic
== s7_NO_PIC
) || (!s7_inst
.reloc
.exp
.X_add_symbol
))
4372 sprintf (append_str
, "ld_i32hi r%d, %s", reg_rd
, keep_data
);
4373 if (s7_append_insn (append_str
, TRUE
) == (int) s7_FAIL
)
4376 sprintf (append_str
, "ld_i32lo r%d, %s", reg_rd
, keep_data
);
4377 if (s7_append_insn (append_str
, TRUE
) == (int) s7_FAIL
)
4382 gas_assert (s7_inst
.reloc
.exp
.X_add_symbol
);
4383 s7_build_la_pic (reg_rd
, s7_inst
.reloc
.exp
);
4386 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4396 s7_do_macro_li_rdi32 (char *str
)
4400 s7_skip_whitespace (str
);
4401 if ((reg_rd
= s7_reg_required_here (&str
, 20, s7_REG_TYPE_SCORE
)) == (int) s7_FAIL
4402 || s7_skip_past_comma (&str
) == (int) s7_FAIL
)
4408 char *keep_data
= str
;
4410 /* Check immediate value. */
4411 if (s7_my_get_expression (&s7_inst
.reloc
.exp
, &str
) == (int) s7_FAIL
)
4413 s7_inst
.error
= _("expression error");
4416 else if (!(s7_inst
.reloc
.exp
.X_add_number
>= -0xffffffffLL
4417 && s7_inst
.reloc
.exp
.X_add_number
<= 0xffffffffLL
))
4419 s7_inst
.error
= _("value not in range [-0xffffffff, 0xffffffff]");
4426 /* li rd, simm16. */
4427 if (s7_data_op2 (&str
, 1, _SIMM16_LA
) != (int) s7_FAIL
)
4429 s7_end_of_line (str
);
4435 char append_str
[s7_MAX_LITERAL_POOL_SIZE
];
4439 if ((s7_data_op2 (&str
, 1, _VALUE_HI16
) == (int) s7_FAIL
)
4440 || (s7_end_of_line (str
) == (int) s7_FAIL
))
4444 else if (s7_inst
.reloc
.exp
.X_add_symbol
)
4446 s7_inst
.error
= _("li rd label isn't correct instruction form");
4451 sprintf (append_str
, "ld_i32hi r%d, %s", reg_rd
, keep_data
);
4453 if (s7_append_insn (append_str
, TRUE
) == (int) s7_FAIL
)
4457 sprintf (append_str
, "ld_i32lo r%d, %s", reg_rd
, keep_data
);
4458 if (s7_append_insn (append_str
, TRUE
) == (int) s7_FAIL
)
4461 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4469 /* Handle mul/mulu/div/divu/rem/remu. */
4472 s7_do_macro_mul_rdrsrs (char *str
)
4478 char append_str
[s7_MAX_LITERAL_POOL_SIZE
];
4480 if (s7_university_version
== 1)
4481 as_warn ("%s", s7_ERR_FOR_SCORE5U_MUL_DIV
);
4483 strcpy (append_str
, str
);
4484 backupstr
= append_str
;
4485 s7_skip_whitespace (backupstr
);
4486 if (((reg_rd
= s7_reg_required_here (&backupstr
, -1, s7_REG_TYPE_SCORE
)) == (int) s7_FAIL
)
4487 || (s7_skip_past_comma (&backupstr
) == (int) s7_FAIL
)
4488 || ((reg_rs1
= s7_reg_required_here (&backupstr
, -1, s7_REG_TYPE_SCORE
)) == (int) s7_FAIL
))
4490 s7_inst
.error
= s7_BAD_ARGS
;
4494 if (s7_skip_past_comma (&backupstr
) == (int) s7_FAIL
)
4496 /* rem/remu rA, rB is error format. */
4497 if (strcmp (s7_inst
.name
, "rem") == 0 || strcmp (s7_inst
.name
, "remu") == 0)
4499 s7_SET_INSN_ERROR (s7_BAD_ARGS
);
4503 s7_SET_INSN_ERROR (NULL
);
4510 s7_SET_INSN_ERROR (NULL
);
4511 if (((reg_rs2
= s7_reg_required_here (&backupstr
, -1, s7_REG_TYPE_SCORE
)) == (int) s7_FAIL
)
4512 || (s7_end_of_line (backupstr
) == (int) s7_FAIL
))
4518 char append_str1
[s7_MAX_LITERAL_POOL_SIZE
];
4520 if (strcmp (s7_inst
.name
, "rem") == 0)
4522 sprintf (append_str
, "mul r%d, r%d", reg_rs1
, reg_rs2
);
4523 sprintf (append_str1
, "mfceh r%d", reg_rd
);
4525 else if (strcmp (s7_inst
.name
, "remu") == 0)
4527 sprintf (append_str
, "mulu r%d, r%d", reg_rs1
, reg_rs2
);
4528 sprintf (append_str1
, "mfceh r%d", reg_rd
);
4532 sprintf (append_str
, "%s r%d, r%d", s7_inst
.name
, reg_rs1
, reg_rs2
);
4533 sprintf (append_str1
, "mfcel r%d", reg_rd
);
4536 /* Output mul/mulu or div/divu or rem/remu. */
4537 if (s7_append_insn (append_str
, TRUE
) == (int) s7_FAIL
)
4540 /* Output mfcel or mfceh. */
4541 if (s7_append_insn (append_str1
, TRUE
) == (int) s7_FAIL
)
4544 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4551 s7_exp_macro_ldst_abs (char *str
)
4554 char *backupstr
, *tmp
;
4555 char append_str
[s7_MAX_LITERAL_POOL_SIZE
];
4556 char verifystr
[s7_MAX_LITERAL_POOL_SIZE
];
4557 struct s7_score_it inst_backup
;
4562 memcpy (&inst_backup
, &s7_inst
, sizeof (struct s7_score_it
));
4564 strcpy (verifystr
, str
);
4565 backupstr
= verifystr
;
4566 s7_skip_whitespace (backupstr
);
4567 if ((reg_rd
= s7_reg_required_here (&backupstr
, -1, s7_REG_TYPE_SCORE
)) == (int) s7_FAIL
)
4571 if (s7_skip_past_comma (&backupstr
) == (int) s7_FAIL
)
4575 sprintf (append_str
, "li r1 %s", backupstr
);
4576 s7_append_insn (append_str
, TRUE
);
4578 memcpy (&s7_inst
, &inst_backup
, sizeof (struct s7_score_it
));
4579 sprintf (append_str
, " r%d, [r1,0]", reg_rd
);
4580 s7_do_ldst_insn (append_str
);
4586 s7_nopic_need_relax (symbolS
* sym
, int before_relaxing
)
4590 else if (s7_USE_GLOBAL_POINTER_OPT
&& s7_g_switch_value
> 0)
4592 const char *symname
;
4593 const char *segname
;
4595 /* Find out whether this symbol can be referenced off the $gp
4596 register. It can be if it is smaller than the -G size or if
4597 it is in the .sdata or .sbss section. Certain symbols can
4598 not be referenced off the $gp, although it appears as though
4600 symname
= S_GET_NAME (sym
);
4602 && (strcmp (symname
, "eprol") == 0
4603 || strcmp (symname
, "etext") == 0
4604 || strcmp (symname
, "_gp") == 0
4605 || strcmp (symname
, "edata") == 0
4606 || strcmp (symname
, "_fbss") == 0
4607 || strcmp (symname
, "_fdata") == 0
4608 || strcmp (symname
, "_ftext") == 0
4609 || strcmp (symname
, "end") == 0
4610 || strcmp (symname
, GP_DISP_LABEL
) == 0))
4614 else if ((!S_IS_DEFINED (sym
) || S_IS_COMMON (sym
)) && (0
4615 /* We must defer this decision until after the whole file has been read,
4616 since there might be a .extern after the first use of this symbol. */
4618 && S_GET_VALUE (sym
) == 0)
4619 || (S_GET_VALUE (sym
) != 0
4620 && S_GET_VALUE (sym
) <= s7_g_switch_value
)))
4625 segname
= segment_name (S_GET_SEGMENT (sym
));
4626 return (strcmp (segname
, ".sdata") != 0
4627 && strcmp (segname
, ".sbss") != 0
4628 && strncmp (segname
, ".sdata.", 7) != 0
4629 && strncmp (segname
, ".gnu.linkonce.s.", 16) != 0);
4631 /* We are not optimizing for the $gp register. */
4636 /* Build a relax frag for lw/st instruction when generating s7_PIC,
4637 external symbol first and local symbol second. */
4640 s7_build_lwst_pic (int reg_rd
, expressionS exp
, const char *insn_name
)
4642 symbolS
*add_symbol
= exp
.X_add_symbol
;
4643 int add_number
= exp
.X_add_number
;
4644 struct s7_score_it fix_insts
[s7_RELAX_INST_NUM
];
4645 struct s7_score_it var_insts
[s7_RELAX_INST_NUM
];
4648 char tmp
[s7_MAX_LITERAL_POOL_SIZE
];
4654 if ((add_number
== 0) || (add_number
>= -0x8000 && add_number
<= 0x7fff))
4659 /* For an external symbol, two insns are generated;
4660 For a local symbol, three insns are generated. */
4662 For an external symbol: lw rD, <sym>($gp)
4663 (BFD_RELOC_SCORE_GOT15) */
4664 sprintf (tmp
, "lw_pic r1, %s", S_GET_NAME (add_symbol
));
4665 if (s7_append_insn (tmp
, FALSE
) == (int) s7_FAIL
)
4668 memcpy (&fix_insts
[0], &s7_inst
, sizeof (struct s7_score_it
));
4671 For a local symbol :
4672 lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15)
4673 addi rD, <sym> (BFD_RELOC_GOT_LO16) */
4674 s7_inst
.reloc
.type
= BFD_RELOC_SCORE_GOT15
;
4675 memcpy (&var_insts
[0], &s7_inst
, sizeof (struct s7_score_it
));
4676 sprintf (tmp
, "addi_s_pic r1, %s", S_GET_NAME (add_symbol
));
4677 if (s7_append_insn (tmp
, FALSE
) == (int) s7_FAIL
)
4680 memcpy (&var_insts
[1], &s7_inst
, sizeof (struct s7_score_it
));
4681 s7_build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
4683 /* Insn 2 or Insn 3: lw/st rD, [r1, constant] */
4684 sprintf (tmp
, "%s r%d, [r1, %d]", insn_name
, reg_rd
, add_number
);
4685 if (s7_append_insn (tmp
, TRUE
) == (int) s7_FAIL
)
4688 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4693 s7_inst
.error
= _("PIC code offset overflow (max 16 signed bits)");
4701 s7_do_macro_ldst_label (char *str
)
4709 char *absolute_value
;
4710 char append_str
[3][s7_MAX_LITERAL_POOL_SIZE
];
4711 char verifystr
[s7_MAX_LITERAL_POOL_SIZE
];
4712 struct s7_score_it inst_backup
;
4713 struct s7_score_it inst_expand
[3];
4714 struct s7_score_it inst_main
;
4716 memcpy (&inst_backup
, &s7_inst
, sizeof (struct s7_score_it
));
4717 strcpy (verifystr
, str
);
4718 backup_str
= verifystr
;
4720 s7_skip_whitespace (backup_str
);
4721 if ((reg_rd
= s7_reg_required_here (&backup_str
, -1, s7_REG_TYPE_SCORE
)) == (int) s7_FAIL
)
4724 if (s7_skip_past_comma (&backup_str
) == (int) s7_FAIL
)
4727 label_str
= backup_str
;
4729 /* Ld/st rD, [rA, imm] ld/st rD, [rA]+, imm ld/st rD, [rA, imm]+. */
4730 if (*backup_str
== '[')
4732 s7_inst
.type
= Rd_rvalueRs_preSI12
;
4733 s7_do_ldst_insn (str
);
4737 /* Ld/st rD, imm. */
4738 absolute_value
= backup_str
;
4739 s7_inst
.type
= Rd_rvalueRs_SI15
;
4741 if (s7_my_get_expression (&s7_inst
.reloc
.exp
, &backup_str
) == (int) s7_FAIL
)
4743 s7_inst
.error
= _("expression error");
4746 else if ((s7_inst
.reloc
.exp
.X_add_symbol
== NULL
)
4747 && (s7_validate_immediate (s7_inst
.reloc
.exp
.X_add_number
, _VALUE
, 0) == (int) s7_FAIL
))
4749 s7_inst
.error
= _("value not in range [0, 0x7fffffff]");
4752 else if (s7_end_of_line (backup_str
) == (int) s7_FAIL
)
4754 s7_inst
.error
= _("end on line error");
4759 if (s7_inst
.reloc
.exp
.X_add_symbol
== 0)
4761 memcpy (&s7_inst
, &inst_backup
, sizeof (struct s7_score_it
));
4762 s7_exp_macro_ldst_abs (str
);
4767 /* Ld/st rD, label. */
4768 s7_inst
.type
= Rd_rvalueRs_SI15
;
4769 backup_str
= absolute_value
;
4770 if ((s7_data_op2 (&backup_str
, 1, _GP_IMM15
) == (int) s7_FAIL
)
4771 || (s7_end_of_line (backup_str
) == (int) s7_FAIL
))
4777 if (s7_inst
.reloc
.exp
.X_add_symbol
== 0)
4780 s7_inst
.error
= s7_BAD_ARGS
;
4785 if (s7_score_pic
== s7_PIC
)
4788 ldst_idx
= s7_inst
.instruction
& OPC_PSEUDOLDST_MASK
;
4789 s7_build_lwst_pic (reg_rd
, s7_inst
.reloc
.exp
,
4790 s7_score_ldst_insns
[ldst_idx
* 3 + 0].template_name
);
4795 if ((s7_inst
.reloc
.exp
.X_add_number
<= 0x3fff)
4796 && (s7_inst
.reloc
.exp
.X_add_number
>= -0x4000)
4797 && (!s7_nopic_need_relax (s7_inst
.reloc
.exp
.X_add_symbol
, 1)))
4801 /* Assign the real opcode. */
4802 ldst_idx
= s7_inst
.instruction
& OPC_PSEUDOLDST_MASK
;
4803 s7_inst
.instruction
&= ~OPC_PSEUDOLDST_MASK
;
4804 s7_inst
.instruction
|= s7_score_ldst_insns
[ldst_idx
* 3 + 0].value
;
4805 s7_inst
.instruction
|= reg_rd
<< 20;
4806 s7_inst
.instruction
|= s7_GP
<< 15;
4807 s7_inst
.relax_inst
= 0x8000;
4808 s7_inst
.relax_size
= 0;
4814 /* Backup s7_inst. */
4815 memcpy (&inst_main
, &s7_inst
, sizeof (struct s7_score_it
));
4819 /* Determine which instructions should be output. */
4820 sprintf (append_str
[0], "ld_i32hi r1, %s", label_str
);
4821 sprintf (append_str
[1], "ld_i32lo r1, %s", label_str
);
4822 sprintf (append_str
[2], "%s r%d, [r1, 0]", inst_backup
.name
, reg_rd
);
4824 /* Generate three instructions.
4826 ld/st rd, [r1, 0] */
4827 for (i
= 0; i
< 3; i
++)
4829 if (s7_append_insn (append_str
[i
], FALSE
) == (int) s7_FAIL
)
4832 memcpy (&inst_expand
[i
], &s7_inst
, sizeof (struct s7_score_it
));
4839 /* Adjust instruction opcode and to be relaxed instruction opcode. */
4840 inst_main
.instruction
= s7_adjust_paritybit (inst_main
.instruction
, s7_GET_INSN_CLASS (inst_main
.type
));
4841 inst_main
.relax_size
= inst_expand
[0].size
+ inst_expand
[1].size
+ inst_expand
[2].size
;
4842 inst_main
.type
= Insn_GP
;
4844 for (i
= 0; i
< 3; i
++)
4845 inst_expand
[i
].instruction
= s7_adjust_paritybit (inst_expand
[i
].instruction
4846 , s7_GET_INSN_CLASS (inst_expand
[i
].type
));
4848 /* Check data dependency. */
4849 s7_handle_dependency (&inst_main
);
4851 /* Start a new frag if frag_now is not empty. */
4852 if (frag_now_fix () != 0)
4854 if (!frag_now
->tc_frag_data
.is_insn
)
4855 frag_wane (frag_now
);
4861 /* Write fr_fix part. */
4862 p
= frag_more (inst_main
.size
);
4863 s7_number_to_chars (p
, inst_main
.instruction
, inst_main
.size
);
4865 if (inst_main
.reloc
.type
!= BFD_RELOC_NONE
)
4867 s7_fix_new_score (frag_now
, p
- frag_now
->fr_literal
, inst_main
.size
,
4868 &inst_main
.reloc
.exp
, inst_main
.reloc
.pc_rel
, inst_main
.reloc
.type
);
4872 dwarf2_emit_insn (inst_main
.size
);
4875 /* s7_GP instruction can not do optimization, only can do relax between
4876 1 instruction and 3 instructions. */
4877 p
= frag_var (rs_machine_dependent
, inst_main
.relax_size
+ s7_RELAX_PAD_BYTE
, 0,
4878 s7_RELAX_ENCODE (inst_main
.size
, inst_main
.relax_size
, inst_main
.type
, 0, 4, 0),
4879 inst_main
.reloc
.exp
.X_add_symbol
, 0, NULL
);
4881 /* Write fr_var part.
4882 no calling s7_gen_insn_frag, no fixS will be generated. */
4883 s7_number_to_chars (p
, inst_expand
[0].instruction
, inst_expand
[0].size
);
4884 p
+= inst_expand
[0].size
;
4885 s7_number_to_chars (p
, inst_expand
[1].instruction
, inst_expand
[1].size
);
4886 p
+= inst_expand
[1].size
;
4887 s7_number_to_chars (p
, inst_expand
[2].instruction
, inst_expand
[2].size
);
4891 s7_gen_insn_frag (&inst_expand
[0], NULL
);
4892 s7_gen_insn_frag (&inst_expand
[1], NULL
);
4893 s7_gen_insn_frag (&inst_expand
[2], NULL
);
4897 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4902 s7_do_lw_pic (char *str
)
4906 s7_skip_whitespace (str
);
4907 if (((reg_rd
= s7_reg_required_here (&str
, 20, s7_REG_TYPE_SCORE
)) == (int) s7_FAIL
)
4908 || (s7_skip_past_comma (&str
) == (int) s7_FAIL
)
4909 || (s7_my_get_expression (&s7_inst
.reloc
.exp
, &str
) == (int) s7_FAIL
)
4910 || (s7_end_of_line (str
) == (int) s7_FAIL
))
4916 if (s7_inst
.reloc
.exp
.X_add_symbol
== 0)
4919 s7_inst
.error
= s7_BAD_ARGS
;
4924 s7_inst
.instruction
|= s7_GP
<< 15;
4925 s7_inst
.reloc
.type
= BFD_RELOC_SCORE_GOT15
;
4930 s7_do_empty (char *str
)
4933 if (s7_university_version
== 1)
4935 if (((s7_inst
.instruction
& 0x3e0003ff) == 0x0c000004)
4936 || ((s7_inst
.instruction
& 0x3e0003ff) == 0x0c000024)
4937 || ((s7_inst
.instruction
& 0x3e0003ff) == 0x0c000044)
4938 || ((s7_inst
.instruction
& 0x3e0003ff) == 0x0c000064))
4940 s7_inst
.error
= s7_ERR_FOR_SCORE5U_MMU
;
4944 if (s7_end_of_line (str
) == (int) s7_FAIL
)
4947 if (s7_inst
.relax_inst
!= 0x8000)
4949 if (s7_inst
.type
== NO_OPD
)
4951 s7_inst
.relax_size
= 2;
4955 s7_inst
.relax_size
= 4;
4961 s7_do_jump (char *str
)
4965 s7_skip_whitespace (str
);
4966 if (s7_my_get_expression (&s7_inst
.reloc
.exp
, &str
) == (int) s7_FAIL
4967 || s7_end_of_line (str
) == (int) s7_FAIL
)
4970 if (s7_inst
.reloc
.exp
.X_add_symbol
== 0)
4972 s7_inst
.error
= _("lacking label ");
4976 if (!(s7_inst
.reloc
.exp
.X_add_number
>= -16777216
4977 && s7_inst
.reloc
.exp
.X_add_number
<= 16777215))
4979 s7_inst
.error
= _("invalid constant: 25 bit expression not in range [-16777216, 16777215]");
4983 save_in
= input_line_pointer
;
4984 input_line_pointer
= str
;
4985 s7_inst
.reloc
.type
= BFD_RELOC_SCORE_JMP
;
4986 s7_inst
.reloc
.pc_rel
= 1;
4987 input_line_pointer
= save_in
;
4991 s7_do16_jump (char *str
)
4993 s7_skip_whitespace (str
);
4994 if (s7_my_get_expression (&s7_inst
.reloc
.exp
, &str
) == (int) s7_FAIL
4995 || s7_end_of_line (str
) == (int) s7_FAIL
)
4999 else if (s7_inst
.reloc
.exp
.X_add_symbol
== 0)
5001 s7_inst
.error
= _("lacking label ");
5004 else if (!(s7_inst
.reloc
.exp
.X_add_number
>= 0
5005 && s7_inst
.reloc
.exp
.X_add_number
<= 4095))
5007 s7_inst
.error
= _("invalid constant: 12 bit expression not in range [0, 4095]");
5011 s7_inst
.reloc
.type
= BFD_RELOC_SCORE16_JMP
;
5012 s7_inst
.reloc
.pc_rel
= 1;
5016 s7_do_branch (char *str
)
5018 unsigned long abs_value
= 0;
5020 if (s7_my_get_expression (&s7_inst
.reloc
.exp
, &str
) == (int) s7_FAIL
5021 || s7_end_of_line (str
) == (int) s7_FAIL
)
5025 else if (s7_inst
.reloc
.exp
.X_add_symbol
== 0)
5027 s7_inst
.error
= _("lacking label ");
5030 else if (!(s7_inst
.reloc
.exp
.X_add_number
>= -524288
5031 && s7_inst
.reloc
.exp
.X_add_number
<= 524287))
5033 s7_inst
.error
= _("invalid constant: 20 bit expression not in range -2^19..2^19");
5037 s7_inst
.reloc
.type
= BFD_RELOC_SCORE_BRANCH
;
5038 s7_inst
.reloc
.pc_rel
= 1;
5040 /* Branch 32 offset field : 20 bit, 16 bit branch offset field : 8 bit. */
5041 s7_inst
.instruction
|= (s7_inst
.reloc
.exp
.X_add_number
& 0x3fe) | ((s7_inst
.reloc
.exp
.X_add_number
& 0xffc00) << 5);
5043 /* Compute 16 bit branch instruction. */
5044 if ((s7_inst
.relax_inst
!= 0x8000) && (abs_value
& 0xfffffe00) == 0)
5046 s7_inst
.relax_inst
|= (((s7_inst
.instruction
>> 10) & 0xf) << 8);
5047 s7_inst
.relax_inst
|= ((s7_inst
.reloc
.exp
.X_add_number
>> 1) & 0xff);
5048 s7_inst
.relax_size
= 2;
5052 s7_inst
.relax_inst
= 0x8000;
5057 s7_do16_branch (char *str
)
5059 if ((s7_my_get_expression (&s7_inst
.reloc
.exp
, &str
) == (int) s7_FAIL
5060 || s7_end_of_line (str
) == (int) s7_FAIL
))
5064 else if (s7_inst
.reloc
.exp
.X_add_symbol
== 0)
5066 s7_inst
.error
= _("lacking label");
5068 else if (!(s7_inst
.reloc
.exp
.X_add_number
>= -512
5069 && s7_inst
.reloc
.exp
.X_add_number
<= 511))
5071 s7_inst
.error
= _("invalid constant: 10 bit expression not in range [-2^9, 2^9-1]");
5075 s7_inst
.reloc
.type
= BFD_RELOC_SCORE16_BRANCH
;
5076 s7_inst
.reloc
.pc_rel
= 1;
5077 s7_inst
.instruction
|= ((s7_inst
.reloc
.exp
.X_add_number
>> 1) & 0xff);
5081 /* Iterate over the base tables to create the instruction patterns. */
5084 s7_build_score_ops_hsh (void)
5087 static struct obstack insn_obstack
;
5089 obstack_begin (&insn_obstack
, 4000);
5090 for (i
= 0; i
< sizeof (s7_score_insns
) / sizeof (struct s7_asm_opcode
); i
++)
5092 const struct s7_asm_opcode
*insn
= s7_score_insns
+ i
;
5093 size_t len
= strlen (insn
->template_name
);
5094 struct s7_asm_opcode
*new_opcode
;
5095 char *template_name
;
5096 new_opcode
= (struct s7_asm_opcode
*)
5097 obstack_alloc (&insn_obstack
, sizeof (struct s7_asm_opcode
));
5098 template_name
= (char *) obstack_alloc (&insn_obstack
, len
+ 1);
5100 strcpy (template_name
, insn
->template_name
);
5101 new_opcode
->template_name
= template_name
;
5102 new_opcode
->parms
= insn
->parms
;
5103 new_opcode
->value
= insn
->value
;
5104 new_opcode
->relax_value
= insn
->relax_value
;
5105 new_opcode
->type
= insn
->type
;
5106 new_opcode
->bitmask
= insn
->bitmask
;
5107 hash_insert (s7_score_ops_hsh
, new_opcode
->template_name
,
5108 (void *) new_opcode
);
5113 s7_build_dependency_insn_hsh (void)
5116 static struct obstack dependency_obstack
;
5118 obstack_begin (&dependency_obstack
, 4000);
5119 for (i
= 0; i
< ARRAY_SIZE (s7_insn_to_dependency_table
); i
++)
5121 const struct s7_insn_to_dependency
*tmp
= s7_insn_to_dependency_table
+ i
;
5122 size_t len
= strlen (tmp
->insn_name
);
5123 struct s7_insn_to_dependency
*new_i2d
;
5126 new_i2d
= (struct s7_insn_to_dependency
*)
5127 obstack_alloc (&dependency_obstack
,
5128 sizeof (struct s7_insn_to_dependency
));
5129 insn_name
= (char *) obstack_alloc (&dependency_obstack
, len
+ 1);
5131 strcpy (insn_name
, tmp
->insn_name
);
5132 new_i2d
->insn_name
= insn_name
;
5133 new_i2d
->type
= tmp
->type
;
5134 hash_insert (s7_dependency_insn_hsh
, new_i2d
->insn_name
,
5140 s7_md_chars_to_number (char *buf
, int n
)
5143 unsigned char *where
= (unsigned char *) buf
;
5145 if (target_big_endian
)
5150 result
|= (*where
++ & 255);
5158 result
|= (where
[n
] & 255);
5165 /* Return true if the given symbol should be considered local for s7_PIC. */
5168 s7_pic_need_relax (symbolS
*sym
, asection
*segtype
)
5171 bfd_boolean linkonce
;
5173 /* Handle the case of a symbol equated to another symbol. */
5174 while (symbol_equated_reloc_p (sym
))
5178 /* It's possible to get a loop here in a badly written
5180 n
= symbol_get_value_expression (sym
)->X_add_symbol
;
5186 symsec
= S_GET_SEGMENT (sym
);
5188 /* Duplicate the test for LINK_ONCE sections as in adjust_reloc_syms */
5190 if (symsec
!= segtype
&& ! S_IS_LOCAL (sym
))
5192 if ((bfd_get_section_flags (stdoutput
, symsec
) & SEC_LINK_ONCE
) != 0)
5195 /* The GNU toolchain uses an extension for ELF: a section
5196 beginning with the magic string .gnu.linkonce is a linkonce
5198 if (strncmp (segment_name (symsec
), ".gnu.linkonce",
5199 sizeof ".gnu.linkonce" - 1) == 0)
5203 /* This must duplicate the test in adjust_reloc_syms. */
5204 return (!bfd_is_und_section (symsec
)
5205 && !bfd_is_abs_section (symsec
)
5206 && !bfd_is_com_section (symsec
)
5209 /* A global or weak symbol is treated as external. */
5210 && (OUTPUT_FLAVOR
!= bfd_target_elf_flavour
5211 || (! S_IS_WEAK (sym
) && ! S_IS_EXTERNAL (sym
)))
5217 s7_judge_size_before_relax (fragS
* fragp
, asection
*sec
)
5221 if (s7_score_pic
== s7_NO_PIC
)
5222 change
= s7_nopic_need_relax (fragp
->fr_symbol
, 0);
5224 change
= s7_pic_need_relax (fragp
->fr_symbol
, sec
);
5228 /* Only at the first time determining whether s7_GP instruction relax should be done,
5229 return the difference between instruction size and instruction relax size. */
5230 if (fragp
->fr_opcode
== NULL
)
5232 fragp
->fr_fix
= s7_RELAX_NEW (fragp
->fr_subtype
);
5233 fragp
->fr_opcode
= fragp
->fr_literal
+ s7_RELAX_RELOC1 (fragp
->fr_subtype
);
5234 return s7_RELAX_NEW (fragp
->fr_subtype
) - s7_RELAX_OLD (fragp
->fr_subtype
);
5242 s7_b32_relax_to_b16 (fragS
* fragp
)
5245 int relaxable_p
= 0;
5246 int frag_addr
= fragp
->fr_address
+ fragp
->insn_addr
;
5248 addressT symbol_address
= 0;
5251 unsigned long value
;
5252 unsigned long abs_value
;
5254 /* FIXME : here may be able to modify better .
5255 I don't know how to get the fragp's section ,
5256 so in relax stage , it may be wrong to calculate the symbol's offset when the frag's section
5257 is different from the symbol's. */
5259 relaxable_p
= s7_RELAX_OPT (fragp
->fr_subtype
);
5261 s
= fragp
->fr_symbol
;
5262 /* b/bl immediate */
5266 symbol_address
= (addressT
) symbol_get_frag (s
)->fr_address
;
5268 value
= s7_md_chars_to_number (fragp
->fr_literal
, s7_INSN_SIZE
);
5270 /* b 32's offset : 20 bit, b 16's tolerate field : 0xff. */
5271 offset
= ((value
& 0x3ff0000) >> 6) | (value
& 0x3fe);
5272 if ((offset
& 0x80000) == 0x80000)
5273 offset
|= 0xfff00000;
5275 abs_value
= offset
+ symbol_address
- frag_addr
;
5276 if ((abs_value
& 0x80000000) == 0x80000000)
5277 abs_value
= 0xffffffff - abs_value
+ 1;
5279 /* Relax branch 32 to branch 16. */
5280 if (relaxable_p
&& ((abs_value
& 0xffffff00) == 0)
5281 && (S_IS_DEFINED (s
) && !S_IS_COMMON (s
) && !S_IS_EXTERNAL (s
)))
5287 /* Branch 32 can not be relaxed to b 16, so clear OPT bit. */
5288 fragp
->fr_opcode
= NULL
;
5289 fragp
->fr_subtype
= s7_RELAX_OPT_CLEAR (fragp
->fr_subtype
);
5296 s7_parse_pce_inst (char *insnstr
)
5301 char first
[s7_MAX_LITERAL_POOL_SIZE
];
5302 char second
[s7_MAX_LITERAL_POOL_SIZE
];
5303 struct s7_score_it pec_part_1
;
5305 /* Get first part string of PCE. */
5306 p
= strstr (insnstr
, "||");
5309 strcpy (first
, insnstr
);
5311 /* Get second part string of PCE. */
5316 s7_parse_16_32_inst (first
, FALSE
);
5320 memcpy (&pec_part_1
, &s7_inst
, sizeof (s7_inst
));
5329 s7_parse_16_32_inst (second
, FALSE
);
5333 if ( ((pec_part_1
.size
== s7_INSN_SIZE
) && (s7_inst
.size
== s7_INSN_SIZE
))
5334 || ((pec_part_1
.size
== s7_INSN_SIZE
) && (s7_inst
.size
== s7_INSN16_SIZE
))
5335 || ((pec_part_1
.size
== s7_INSN16_SIZE
) && (s7_inst
.size
== s7_INSN_SIZE
)))
5337 s7_inst
.error
= _("pce instruction error (16 bit || 16 bit)'");
5338 strcpy (s7_inst
.str
, insnstr
);
5343 s7_gen_insn_frag (&pec_part_1
, &s7_inst
);
5349 s7_insert_reg (const struct s7_reg_entry
*r
, struct hash_control
*htab
)
5352 int len
= strlen (r
->name
) + 2;
5353 char *buf
= XNEWVEC (char, len
);
5354 char *buf2
= XNEWVEC (char, len
);
5356 strcpy (buf
+ i
, r
->name
);
5357 for (i
= 0; buf
[i
]; i
++)
5359 buf2
[i
] = TOUPPER (buf
[i
]);
5363 hash_insert (htab
, buf
, (void *) r
);
5364 hash_insert (htab
, buf2
, (void *) r
);
5368 s7_build_reg_hsh (struct s7_reg_map
*map
)
5370 const struct s7_reg_entry
*r
;
5372 if ((map
->htab
= hash_new ()) == NULL
)
5374 as_fatal (_("virtual memory exhausted"));
5376 for (r
= map
->names
; r
->name
!= NULL
; r
++)
5378 s7_insert_reg (r
, map
->htab
);
5384 /* If we change section we must dump the literal pool first. */
5386 s7_s_score_bss (int ignore ATTRIBUTE_UNUSED
)
5388 subseg_set (bss_section
, (subsegT
) get_absolute_expression ());
5389 demand_empty_rest_of_line ();
5393 s7_s_score_text (int ignore
)
5395 obj_elf_text (ignore
);
5396 record_alignment (now_seg
, 2);
5400 s7_s_section (int ignore
)
5402 obj_elf_section (ignore
);
5403 if ((bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
) != 0)
5404 record_alignment (now_seg
, 2);
5409 s7_s_change_sec (int sec
)
5414 /* The ELF backend needs to know that we are changing sections, so
5415 that .previous works correctly. We could do something like check
5416 for an obj_section_change_hook macro, but that might be confusing
5417 as it would not be appropriate to use it in the section changing
5418 functions in read.c, since obj-elf.c intercepts those. FIXME:
5419 This should be cleaner, somehow. */
5420 obj_elf_section_change_hook ();
5425 seg
= subseg_new (s7_RDATA_SECTION_NAME
, (subsegT
) get_absolute_expression ());
5426 bfd_set_section_flags (stdoutput
, seg
, (SEC_ALLOC
| SEC_LOAD
| SEC_READONLY
| SEC_RELOC
| SEC_DATA
));
5427 if (strcmp (TARGET_OS
, "elf") != 0)
5428 record_alignment (seg
, 4);
5429 demand_empty_rest_of_line ();
5432 seg
= subseg_new (".sdata", (subsegT
) get_absolute_expression ());
5433 bfd_set_section_flags (stdoutput
, seg
, SEC_ALLOC
| SEC_LOAD
| SEC_RELOC
| SEC_DATA
);
5434 if (strcmp (TARGET_OS
, "elf") != 0)
5435 record_alignment (seg
, 4);
5436 demand_empty_rest_of_line ();
5442 s7_s_score_mask (int reg_type ATTRIBUTE_UNUSED
)
5446 if (s7_cur_proc_ptr
== NULL
)
5448 as_warn (_(".mask outside of .ent"));
5449 demand_empty_rest_of_line ();
5452 if (get_absolute_expression_and_terminator (&mask
) != ',')
5454 as_warn (_("Bad .mask directive"));
5455 --input_line_pointer
;
5456 demand_empty_rest_of_line ();
5459 off
= get_absolute_expression ();
5460 s7_cur_proc_ptr
->reg_mask
= mask
;
5461 s7_cur_proc_ptr
->reg_offset
= off
;
5462 demand_empty_rest_of_line ();
5466 s7_get_symbol (void)
5472 c
= get_symbol_name (&name
);
5473 p
= (symbolS
*) symbol_find_or_make (name
);
5474 (void) restore_line_pointer (c
);
5479 s7_get_number (void)
5484 if (*input_line_pointer
== '-')
5486 ++input_line_pointer
;
5489 if (!ISDIGIT (*input_line_pointer
))
5490 as_bad (_("expected simple number"));
5491 if (input_line_pointer
[0] == '0')
5493 if (input_line_pointer
[1] == 'x')
5495 input_line_pointer
+= 2;
5496 while (ISXDIGIT (*input_line_pointer
))
5499 val
|= hex_value (*input_line_pointer
++);
5501 return negative
? -val
: val
;
5505 ++input_line_pointer
;
5506 while (ISDIGIT (*input_line_pointer
))
5509 val
|= *input_line_pointer
++ - '0';
5511 return negative
? -val
: val
;
5514 if (!ISDIGIT (*input_line_pointer
))
5516 printf (_(" *input_line_pointer == '%c' 0x%02x\n"), *input_line_pointer
, *input_line_pointer
);
5517 as_warn (_("invalid number"));
5520 while (ISDIGIT (*input_line_pointer
))
5523 val
+= *input_line_pointer
++ - '0';
5525 return negative
? -val
: val
;
5528 /* The .aent and .ent directives. */
5531 s7_s_score_ent (int aent
)
5536 symbolP
= s7_get_symbol ();
5537 if (*input_line_pointer
== ',')
5538 ++input_line_pointer
;
5540 if (ISDIGIT (*input_line_pointer
) || *input_line_pointer
== '-')
5543 #ifdef BFD_ASSEMBLER
5544 if ((bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
) != 0)
5549 if (now_seg
!= data_section
&& now_seg
!= bss_section
)
5555 as_warn (_(".ent or .aent not in text section."));
5556 if (!aent
&& s7_cur_proc_ptr
)
5557 as_warn (_("missing .end"));
5560 s7_cur_proc_ptr
= &s7_cur_proc
;
5561 s7_cur_proc_ptr
->reg_mask
= 0xdeadbeaf;
5562 s7_cur_proc_ptr
->reg_offset
= 0xdeadbeaf;
5563 s7_cur_proc_ptr
->fpreg_mask
= 0xdeafbeaf;
5564 s7_cur_proc_ptr
->leaf
= 0xdeafbeaf;
5565 s7_cur_proc_ptr
->frame_offset
= 0xdeafbeaf;
5566 s7_cur_proc_ptr
->frame_reg
= 0xdeafbeaf;
5567 s7_cur_proc_ptr
->pc_reg
= 0xdeafbeaf;
5568 s7_cur_proc_ptr
->isym
= symbolP
;
5569 symbol_get_bfdsym (symbolP
)->flags
|= BSF_FUNCTION
;
5571 if (debug_type
== DEBUG_STABS
)
5572 stabs_generate_asm_func (S_GET_NAME (symbolP
), S_GET_NAME (symbolP
));
5574 demand_empty_rest_of_line ();
5578 s7_s_score_frame (int ignore ATTRIBUTE_UNUSED
)
5585 backupstr
= input_line_pointer
;
5588 if (s7_cur_proc_ptr
== NULL
)
5590 as_warn (_(".frame outside of .ent"));
5591 demand_empty_rest_of_line ();
5594 s7_cur_proc_ptr
->frame_reg
= s7_reg_required_here ((&backupstr
), 0, s7_REG_TYPE_SCORE
);
5596 s7_skip_past_comma (&backupstr
);
5597 while (*backupstr
!= ',')
5599 str
[i
] = *backupstr
;
5607 s7_skip_past_comma (&backupstr
);
5608 s7_cur_proc_ptr
->frame_offset
= val
;
5609 s7_cur_proc_ptr
->pc_reg
= s7_reg_required_here ((&backupstr
), 0, s7_REG_TYPE_SCORE
);
5612 s7_skip_past_comma (&backupstr
);
5614 while (*backupstr
!= '\n')
5616 str
[i
] = *backupstr
;
5622 s7_cur_proc_ptr
->leaf
= val
;
5624 s7_skip_past_comma (&backupstr
);
5626 #endif /* OBJ_ELF */
5627 while (input_line_pointer
!= backupstr
)
5628 input_line_pointer
++;
5631 /* The .end directive. */
5634 s7_s_score_end (int x ATTRIBUTE_UNUSED
)
5639 /* Generate a .pdr section. */
5640 segT saved_seg
= now_seg
;
5641 subsegT saved_subseg
= now_subseg
;
5645 if (!is_end_of_line
[(unsigned char)*input_line_pointer
])
5647 p
= s7_get_symbol ();
5648 demand_empty_rest_of_line ();
5653 #ifdef BFD_ASSEMBLER
5654 if ((bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
) != 0)
5659 if (now_seg
!= data_section
&& now_seg
!= bss_section
)
5666 as_warn (_(".end not in text section"));
5667 if (!s7_cur_proc_ptr
)
5669 as_warn (_(".end directive without a preceding .ent directive."));
5670 demand_empty_rest_of_line ();
5675 gas_assert (S_GET_NAME (p
));
5676 if (strcmp (S_GET_NAME (p
), S_GET_NAME (s7_cur_proc_ptr
->isym
)))
5677 as_warn (_(".end symbol does not match .ent symbol."));
5678 if (debug_type
== DEBUG_STABS
)
5679 stabs_generate_asm_endfunc (S_GET_NAME (p
), S_GET_NAME (p
));
5682 as_warn (_(".end directive missing or unknown symbol"));
5684 if ((s7_cur_proc_ptr
->reg_mask
== 0xdeadbeaf) ||
5685 (s7_cur_proc_ptr
->reg_offset
== 0xdeadbeaf) ||
5686 (s7_cur_proc_ptr
->leaf
== 0xdeafbeaf) ||
5687 (s7_cur_proc_ptr
->frame_offset
== 0xdeafbeaf) ||
5688 (s7_cur_proc_ptr
->frame_reg
== 0xdeafbeaf) || (s7_cur_proc_ptr
->pc_reg
== 0xdeafbeaf));
5692 (void) frag_now_fix ();
5693 gas_assert (s7_pdr_seg
);
5694 subseg_set (s7_pdr_seg
, 0);
5695 /* Write the symbol. */
5696 exp
.X_op
= O_symbol
;
5697 exp
.X_add_symbol
= p
;
5698 exp
.X_add_number
= 0;
5699 emit_expr (&exp
, 4);
5700 fragp
= frag_more (7 * 4);
5701 s7_number_to_chars (fragp
, (valueT
) s7_cur_proc_ptr
->reg_mask
, 4);
5702 s7_number_to_chars (fragp
+ 4, (valueT
) s7_cur_proc_ptr
->reg_offset
, 4);
5703 s7_number_to_chars (fragp
+ 8, (valueT
) s7_cur_proc_ptr
->fpreg_mask
, 4);
5704 s7_number_to_chars (fragp
+ 12, (valueT
) s7_cur_proc_ptr
->leaf
, 4);
5705 s7_number_to_chars (fragp
+ 16, (valueT
) s7_cur_proc_ptr
->frame_offset
, 4);
5706 s7_number_to_chars (fragp
+ 20, (valueT
) s7_cur_proc_ptr
->frame_reg
, 4);
5707 s7_number_to_chars (fragp
+ 24, (valueT
) s7_cur_proc_ptr
->pc_reg
, 4);
5708 subseg_set (saved_seg
, saved_subseg
);
5711 s7_cur_proc_ptr
= NULL
;
5714 /* Handle the .set pseudo-op. */
5717 s7_s_score_set (int x ATTRIBUTE_UNUSED
)
5720 char name
[s7_MAX_LITERAL_POOL_SIZE
];
5721 char * orig_ilp
= input_line_pointer
;
5723 while (!is_end_of_line
[(unsigned char)*input_line_pointer
])
5725 name
[i
] = (char) * input_line_pointer
;
5727 ++input_line_pointer
;
5732 if (strcmp (name
, "nwarn") == 0)
5734 s7_warn_fix_data_dependency
= 0;
5736 else if (strcmp (name
, "fixdd") == 0)
5738 s7_fix_data_dependency
= 1;
5740 else if (strcmp (name
, "nofixdd") == 0)
5742 s7_fix_data_dependency
= 0;
5744 else if (strcmp (name
, "r1") == 0)
5748 else if (strcmp (name
, "nor1") == 0)
5752 else if (strcmp (name
, "optimize") == 0)
5756 else if (strcmp (name
, "volatile") == 0)
5760 else if (strcmp (name
, "pic") == 0)
5762 s7_score_pic
= s7_PIC
;
5766 input_line_pointer
= orig_ilp
;
5771 /* Handle the .cpload pseudo-op. This is used when generating s7_PIC code. It sets the
5772 $gp register for the function based on the function address, which is in the register
5773 named in the argument. This uses a relocation against GP_DISP_LABEL, which is handled
5774 specially by the linker. The result is:
5775 ldis gp, %hi(GP_DISP_LABEL)
5776 ori gp, %low(GP_DISP_LABEL)
5777 add gp, gp, .cpload argument
5778 The .cpload argument is normally r29. */
5781 s7_s_score_cpload (int ignore ATTRIBUTE_UNUSED
)
5784 char insn_str
[s7_MAX_LITERAL_POOL_SIZE
];
5786 /* If we are not generating s7_PIC code, .cpload is ignored. */
5787 if (s7_score_pic
== s7_NO_PIC
)
5793 if ((reg
= s7_reg_required_here (&input_line_pointer
, -1, s7_REG_TYPE_SCORE
)) == (int) s7_FAIL
)
5796 demand_empty_rest_of_line ();
5798 sprintf (insn_str
, "ld_i32hi r%d, %s", s7_GP
, GP_DISP_LABEL
);
5799 if (s7_append_insn (insn_str
, TRUE
) == (int) s7_FAIL
)
5802 sprintf (insn_str
, "ld_i32lo r%d, %s", s7_GP
, GP_DISP_LABEL
);
5803 if (s7_append_insn (insn_str
, TRUE
) == (int) s7_FAIL
)
5806 sprintf (insn_str
, "add r%d, r%d, r%d", s7_GP
, s7_GP
, reg
);
5807 if (s7_append_insn (insn_str
, TRUE
) == (int) s7_FAIL
)
5811 /* Handle the .cprestore pseudo-op. This stores $gp into a given
5812 offset from $sp. The offset is remembered, and after making a s7_PIC
5813 call $gp is restored from that location. */
5816 s7_s_score_cprestore (int ignore ATTRIBUTE_UNUSED
)
5819 int cprestore_offset
;
5820 char insn_str
[s7_MAX_LITERAL_POOL_SIZE
];
5822 /* If we are not generating s7_PIC code, .cprestore is ignored. */
5823 if (s7_score_pic
== s7_NO_PIC
)
5829 if ((reg
= s7_reg_required_here (&input_line_pointer
, -1, s7_REG_TYPE_SCORE
)) == (int) s7_FAIL
5830 || s7_skip_past_comma (&input_line_pointer
) == (int) s7_FAIL
)
5835 cprestore_offset
= get_absolute_expression ();
5837 if (cprestore_offset
<= 0x3fff)
5839 sprintf (insn_str
, "sw r%d, [r%d, %d]", s7_GP
, reg
, cprestore_offset
);
5840 if (s7_append_insn (insn_str
, TRUE
) == (int) s7_FAIL
)
5850 sprintf (insn_str
, "li r1, %d", cprestore_offset
);
5851 if (s7_append_insn (insn_str
, TRUE
) == (int) s7_FAIL
)
5854 sprintf (insn_str
, "add r1, r1, r%d", reg
);
5855 if (s7_append_insn (insn_str
, TRUE
) == (int) s7_FAIL
)
5858 sprintf (insn_str
, "sw r%d, [r1]", s7_GP
);
5859 if (s7_append_insn (insn_str
, TRUE
) == (int) s7_FAIL
)
5865 demand_empty_rest_of_line ();
5868 /* Handle the .gpword pseudo-op. This is used when generating s7_PIC
5869 code. It generates a 32 bit s7_GP relative reloc. */
5872 s7_s_score_gpword (int ignore ATTRIBUTE_UNUSED
)
5877 /* When not generating s7_PIC code, this is treated as .word. */
5878 if (s7_score_pic
== s7_NO_PIC
)
5884 if (ex
.X_op
!= O_symbol
|| ex
.X_add_number
!= 0)
5886 as_bad (_("Unsupported use of .gpword"));
5887 ignore_rest_of_line ();
5890 s7_number_to_chars (p
, (valueT
) 0, 4);
5891 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 4, &ex
, FALSE
, BFD_RELOC_GPREL32
);
5892 demand_empty_rest_of_line ();
5895 /* Handle the .cpadd pseudo-op. This is used when dealing with switch
5896 tables in s7_PIC code. */
5899 s7_s_score_cpadd (int ignore ATTRIBUTE_UNUSED
)
5902 char insn_str
[s7_MAX_LITERAL_POOL_SIZE
];
5904 /* If we are not generating s7_PIC code, .cpload is ignored. */
5905 if (s7_score_pic
== s7_NO_PIC
)
5911 if ((reg
= s7_reg_required_here (&input_line_pointer
, -1, s7_REG_TYPE_SCORE
)) == (int) s7_FAIL
)
5915 demand_empty_rest_of_line ();
5917 /* Add $gp to the register named as an argument. */
5918 sprintf (insn_str
, "add r%d, r%d, r%d", reg
, reg
, s7_GP
);
5919 if (s7_append_insn (insn_str
, TRUE
) == (int) s7_FAIL
)
5923 #ifndef TC_IMPLICIT_LCOMM_ALIGNMENT
5924 #define TC_IMPLICIT_LCOMM_ALIGNMENT(SIZE, P2VAR) \
5929 else if ((SIZE) >= 4) \
5931 else if ((SIZE) >= 2) \
5940 s7_s_score_lcomm (int bytes_p
)
5947 segT current_seg
= now_seg
;
5948 subsegT current_subseg
= now_subseg
;
5949 const int max_alignment
= 15;
5951 segT bss_seg
= bss_section
;
5952 int needs_align
= 0;
5954 c
= get_symbol_name (&name
);
5955 p
= input_line_pointer
;
5960 as_bad (_("expected symbol name"));
5961 discard_rest_of_line ();
5965 SKIP_WHITESPACE_AFTER_NAME ();
5967 /* Accept an optional comma after the name. The comma used to be
5968 required, but Irix 5 cc does not generate it. */
5969 if (*input_line_pointer
== ',')
5971 ++input_line_pointer
;
5975 if (is_end_of_line
[(unsigned char)*input_line_pointer
])
5977 as_bad (_("missing size expression"));
5981 if ((temp
= get_absolute_expression ()) < 0)
5983 as_warn (_("BSS length (%d) < 0 ignored"), temp
);
5984 ignore_rest_of_line ();
5988 #if defined (TC_SCORE)
5989 if (OUTPUT_FLAVOR
== bfd_target_ecoff_flavour
|| OUTPUT_FLAVOR
== bfd_target_elf_flavour
)
5991 /* For Score and Alpha ECOFF or ELF, small objects are put in .sbss. */
5992 if ((unsigned) temp
<= bfd_get_gp_size (stdoutput
))
5994 bss_seg
= subseg_new (".sbss", 1);
5995 seg_info (bss_seg
)->bss
= 1;
5996 #ifdef BFD_ASSEMBLER
5997 if (!bfd_set_section_flags (stdoutput
, bss_seg
, SEC_ALLOC
))
5998 as_warn (_("error setting flags for \".sbss\": %s"), bfd_errmsg (bfd_get_error ()));
6005 if (*input_line_pointer
== ',')
6007 ++input_line_pointer
;
6010 if (is_end_of_line
[(unsigned char)*input_line_pointer
])
6012 as_bad (_("missing alignment"));
6017 align
= get_absolute_expression ();
6024 TC_IMPLICIT_LCOMM_ALIGNMENT (temp
, align
);
6026 /* Still zero unless TC_IMPLICIT_LCOMM_ALIGNMENT set it. */
6028 record_alignment (bss_seg
, align
);
6035 /* Convert to a power of 2. */
6040 for (i
= 0; align
!= 0; align
>>= 1, ++i
)
6046 if (align
> max_alignment
)
6048 align
= max_alignment
;
6049 as_warn (_("alignment too large; %d assumed"), align
);
6054 as_warn (_("alignment negative; 0 assumed"));
6057 record_alignment (bss_seg
, align
);
6061 /* Assume some objects may require alignment on some systems. */
6062 #if defined (TC_ALPHA) && ! defined (VMS)
6065 align
= ffs (temp
) - 1;
6066 if (temp
% (1 << align
))
6073 symbolP
= symbol_find_or_make (name
);
6077 #if (defined (OBJ_AOUT) || defined (OBJ_MAYBE_AOUT))
6078 #ifdef BFD_ASSEMBLER
6079 (OUTPUT_FLAVOR
!= bfd_target_aout_flavour
6080 || (S_GET_OTHER (symbolP
) == 0 && S_GET_DESC (symbolP
) == 0)) &&
6082 (S_GET_OTHER (symbolP
) == 0 && S_GET_DESC (symbolP
) == 0) &&
6085 (S_GET_SEGMENT (symbolP
) == bss_seg
|| (!S_IS_DEFINED (symbolP
) && S_GET_VALUE (symbolP
) == 0)))
6089 subseg_set (bss_seg
, 1);
6092 frag_align (align
, 0, 0);
6094 /* Detach from old frag. */
6095 if (S_GET_SEGMENT (symbolP
) == bss_seg
)
6096 symbol_get_frag (symbolP
)->fr_symbol
= NULL
;
6098 symbol_set_frag (symbolP
, frag_now
);
6099 pfrag
= frag_var (rs_org
, 1, 1, (relax_substateT
) 0, symbolP
, (offsetT
) temp
, NULL
);
6103 S_SET_SEGMENT (symbolP
, bss_seg
);
6106 /* The symbol may already have been created with a preceding
6107 ".globl" directive -- be careful not to step on storage class
6108 in that case. Otherwise, set it to static. */
6109 if (S_GET_STORAGE_CLASS (symbolP
) != C_EXT
)
6111 S_SET_STORAGE_CLASS (symbolP
, C_STAT
);
6113 #endif /* OBJ_COFF */
6116 S_SET_SIZE (symbolP
, temp
);
6120 as_bad (_("symbol `%s' is already defined"), S_GET_NAME (symbolP
));
6122 subseg_set (current_seg
, current_subseg
);
6124 demand_empty_rest_of_line ();
6136 if ((s7_score_ops_hsh
= hash_new ()) == NULL
)
6137 as_fatal (_("virtual memory exhausted"));
6139 s7_build_score_ops_hsh ();
6141 if ((s7_dependency_insn_hsh
= hash_new ()) == NULL
)
6142 as_fatal (_("virtual memory exhausted"));
6144 s7_build_dependency_insn_hsh ();
6146 for (i
= (int) REG_TYPE_FIRST
; i
< (int) s7_REG_TYPE_MAX
; i
++)
6147 s7_build_reg_hsh (s7_all_reg_maps
+ i
);
6149 /* Initialize dependency vector. */
6150 s7_init_dependency_vector ();
6152 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
, 0);
6154 subseg
= now_subseg
;
6155 s7_pdr_seg
= subseg_new (".pdr", (subsegT
) 0);
6156 (void) bfd_set_section_flags (stdoutput
, s7_pdr_seg
, SEC_READONLY
| SEC_RELOC
| SEC_DEBUGGING
);
6157 (void) bfd_set_section_alignment (stdoutput
, s7_pdr_seg
, 2);
6158 subseg_set (seg
, subseg
);
6160 if (s7_USE_GLOBAL_POINTER_OPT
)
6161 bfd_set_gp_size (stdoutput
, s7_g_switch_value
);
6165 s7_assemble (char *str
)
6168 know (strlen (str
) < s7_MAX_LITERAL_POOL_SIZE
);
6170 memset (&s7_inst
, '\0', sizeof (s7_inst
));
6171 if (s7_INSN_IS_PCE_P (str
))
6172 s7_parse_pce_inst (str
);
6174 s7_parse_16_32_inst (str
, TRUE
);
6177 as_bad (_("%s -- `%s'"), s7_inst
.error
, s7_inst
.str
);
6180 /* We handle all bad expressions here, so that we can report the faulty
6181 instruction in the error message. */
6184 s7_operand (expressionS
* exp
)
6186 if (s7_in_my_get_expression
)
6188 exp
->X_op
= O_illegal
;
6189 if (s7_inst
.error
== NULL
)
6191 s7_inst
.error
= _("bad expression");
6196 /* Turn a string in input_line_pointer into a floating point constant
6197 of type TYPE, and store the appropriate bytes in *LITP. The number
6198 of LITTLENUMS emitted is stored in *SIZEP. An error message is
6199 returned, or NULL on OK.
6201 Note that fp constants aren't represent in the normal way on the ARM.
6202 In big endian mode, things are as expected. However, in little endian
6203 mode fp constants are big-endian word-wise, and little-endian byte-wise
6204 within the words. For example, (double) 1.1 in big endian mode is
6205 the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
6206 the byte sequence 99 99 f1 3f 9a 99 99 99. */
6209 s7_atof (int type
, char *litP
, int *sizeP
)
6212 LITTLENUM_TYPE words
[s7_MAX_LITTLENUMS
];
6238 return _("bad call to MD_ATOF()");
6241 t
= atof_ieee (input_line_pointer
, type
, words
);
6243 input_line_pointer
= t
;
6246 if (target_big_endian
)
6248 for (i
= 0; i
< prec
; i
++)
6250 s7_number_to_chars (litP
, (valueT
) words
[i
], 2);
6256 for (i
= 0; i
< prec
; i
+= 2)
6258 s7_number_to_chars (litP
, (valueT
) words
[i
+ 1], 2);
6259 s7_number_to_chars (litP
+ 2, (valueT
) words
[i
], 2);
6267 /* Implementation of md_frag_check.
6268 Called after md_convert_frag(). */
6271 s7_frag_check (fragS
* fragp ATTRIBUTE_UNUSED
)
6273 know (fragp
->insn_addr
<= s7_RELAX_PAD_BYTE
);
6276 /* Implementation of TC_VALIDATE_FIX.
6277 Called before md_apply_fix() and after md_convert_frag(). */
6280 s7_validate_fix (fixS
*fixP
)
6282 fixP
->fx_where
+= fixP
->fx_frag
->insn_addr
;
6286 s7_force_relocation (struct fix
*fixp
)
6290 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
6291 || fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
6292 || fixp
->fx_r_type
== BFD_RELOC_SCORE_JMP
6293 || fixp
->fx_r_type
== BFD_RELOC_SCORE_BRANCH
6294 || fixp
->fx_r_type
== BFD_RELOC_SCORE16_JMP
6295 || fixp
->fx_r_type
== BFD_RELOC_SCORE16_BRANCH
)
6304 s7_fix_adjustable (fixS
* fixP
)
6306 if (fixP
->fx_addsy
== NULL
)
6310 else if (OUTPUT_FLAVOR
== bfd_target_elf_flavour
6311 && (S_IS_EXTERNAL (fixP
->fx_addsy
) || S_IS_WEAK (fixP
->fx_addsy
)))
6315 else if (fixP
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
6316 || fixP
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
6317 || fixP
->fx_r_type
== BFD_RELOC_SCORE_JMP
6318 || fixP
->fx_r_type
== BFD_RELOC_SCORE16_JMP
)
6327 s7_elf_final_processing (void)
6329 unsigned long val
= E_SCORE_MACH_SCORE7
;
6331 elf_elfheader (stdoutput
)->e_machine
= EM_SCORE
;
6332 elf_elfheader (stdoutput
)->e_flags
&= ~EF_SCORE_MACH
;
6333 elf_elfheader (stdoutput
)->e_flags
|= val
;
6335 if (s7_fix_data_dependency
== 1)
6337 elf_elfheader (stdoutput
)->e_flags
|= EF_SCORE_FIXDEP
;
6339 if (s7_score_pic
== s7_PIC
)
6341 elf_elfheader (stdoutput
)->e_flags
|= EF_SCORE_PIC
;
6345 /* In this function, we determine whether s7_GP instruction should do relaxation,
6346 for the label being against was known now.
6347 Doing this here but not in md_relax_frag() can induce iteration times
6348 in stage of doing relax. */
6351 s7_estimate_size_before_relax (fragS
* fragp
, asection
* sec
)
6353 if ((s7_RELAX_TYPE (fragp
->fr_subtype
) == Insn_GP
)
6354 || (s7_RELAX_TYPE (fragp
->fr_subtype
) == Insn_PIC
))
6355 return s7_judge_size_before_relax (fragp
, sec
);
6361 s7_relax_frag (asection
* sec ATTRIBUTE_UNUSED
,
6363 long stretch ATTRIBUTE_UNUSED
)
6367 int do_relax_p
= 0; /* Indicate doing relaxation for this frag. */
6368 int relaxable_p
= 0;
6369 bfd_boolean word_align_p
= FALSE
;
6372 /* If the instruction address is odd, make it half word align first. */
6373 if ((fragp
->fr_address
) % 2 != 0)
6375 if ((fragp
->fr_address
+ fragp
->insn_addr
) % 2 != 0)
6377 fragp
->insn_addr
= 1;
6382 word_align_p
= ((fragp
->fr_address
+ fragp
->insn_addr
) % 4 == 0) ? TRUE
: FALSE
;
6384 /* Get instruction size and relax size after the last relaxation. */
6385 if (fragp
->fr_opcode
)
6386 insn_size
= s7_RELAX_NEW (fragp
->fr_subtype
);
6388 insn_size
= s7_RELAX_OLD (fragp
->fr_subtype
);
6390 /* Handle specially for s7_GP instruction. for, s7_judge_size_before_relax() has already determine
6391 whether the s7_GP instruction should do relax. */
6392 if ((s7_RELAX_TYPE (fragp
->fr_subtype
) == Insn_GP
)
6393 || (s7_RELAX_TYPE (fragp
->fr_subtype
) == Insn_PIC
))
6397 if (fragp
->insn_addr
< 2)
6399 fragp
->insn_addr
+= 2;
6404 fragp
->insn_addr
-= 2;
6409 if (fragp
->fr_opcode
)
6410 fragp
->fr_fix
= s7_RELAX_NEW (fragp
->fr_subtype
) + fragp
->insn_addr
;
6412 fragp
->fr_fix
= s7_RELAX_OLD (fragp
->fr_subtype
) + fragp
->insn_addr
;
6416 if (s7_RELAX_TYPE (fragp
->fr_subtype
) == PC_DISP19div2
)
6417 s7_b32_relax_to_b16 (fragp
);
6419 relaxable_p
= s7_RELAX_OPT (fragp
->fr_subtype
);
6420 next_fragp
= fragp
->fr_next
;
6421 while ((next_fragp
) && (next_fragp
->fr_type
!= rs_machine_dependent
))
6423 next_fragp
= next_fragp
->fr_next
;
6429 int n_relaxable_p
= 0;
6431 if (next_fragp
->fr_opcode
)
6433 n_insn_size
= s7_RELAX_NEW (next_fragp
->fr_subtype
);
6437 n_insn_size
= s7_RELAX_OLD (next_fragp
->fr_subtype
);
6440 if (s7_RELAX_TYPE (next_fragp
->fr_subtype
) == PC_DISP19div2
)
6441 s7_b32_relax_to_b16 (next_fragp
);
6442 n_relaxable_p
= s7_RELAX_OPT (next_fragp
->fr_subtype
);
6449 if (relaxable_p
&& ((n_insn_size
== 2) || n_relaxable_p
))
6455 else if (insn_size
== 2)
6458 if (relaxable_p
&& (((n_insn_size
== 4) && !n_relaxable_p
) || (n_insn_size
> 4)))
6479 /* Make the 32 bit instruction word align. */
6482 fragp
->insn_addr
+= 2;
6486 else if (insn_size
== 2)
6498 /* Here, try best to do relax regardless fragp->fr_next->fr_type. */
6501 if (insn_size
% 4 == 0)
6511 fragp
->insn_addr
+= 2;
6522 /* fragp->fr_opcode indicates whether this frag should be relaxed. */
6525 if (fragp
->fr_opcode
)
6527 fragp
->fr_opcode
= NULL
;
6528 /* Guarantee estimate stage is correct. */
6529 fragp
->fr_fix
= s7_RELAX_OLD (fragp
->fr_subtype
);
6530 fragp
->fr_fix
+= fragp
->insn_addr
;
6534 fragp
->fr_opcode
= fragp
->fr_literal
+ s7_RELAX_RELOC1 (fragp
->fr_subtype
);
6535 /* Guarantee estimate stage is correct. */
6536 fragp
->fr_fix
= s7_RELAX_NEW (fragp
->fr_subtype
);
6537 fragp
->fr_fix
+= fragp
->insn_addr
;
6542 if (fragp
->fr_opcode
)
6544 /* Guarantee estimate stage is correct. */
6545 fragp
->fr_fix
= s7_RELAX_NEW (fragp
->fr_subtype
);
6546 fragp
->fr_fix
+= fragp
->insn_addr
;
6550 /* Guarantee estimate stage is correct. */
6551 fragp
->fr_fix
= s7_RELAX_OLD (fragp
->fr_subtype
);
6552 fragp
->fr_fix
+= fragp
->insn_addr
;
6561 s7_convert_frag (bfd
* abfd ATTRIBUTE_UNUSED
,
6562 segT sec ATTRIBUTE_UNUSED
,
6570 r_old
= s7_RELAX_OLD (fragp
->fr_subtype
);
6571 r_new
= s7_RELAX_NEW (fragp
->fr_subtype
);
6573 /* fragp->fr_opcode indicates whether this frag should be relaxed. */
6574 if (fragp
->fr_opcode
== NULL
)
6576 memcpy (backup
, fragp
->fr_literal
, r_old
);
6577 fragp
->fr_fix
= r_old
;
6581 memcpy (backup
, fragp
->fr_literal
+ r_old
, r_new
);
6582 fragp
->fr_fix
= r_new
;
6585 fixp
= fragp
->tc_frag_data
.fixp
;
6586 while (fixp
&& fixp
->fx_frag
== fragp
&& fixp
->fx_where
< r_old
)
6588 if (fragp
->fr_opcode
)
6590 fixp
= fixp
->fx_next
;
6592 while (fixp
&& fixp
->fx_frag
== fragp
)
6594 if (fragp
->fr_opcode
)
6595 fixp
->fx_where
-= r_old
+ fragp
->insn_addr
;
6598 fixp
= fixp
->fx_next
;
6601 if (fragp
->insn_addr
)
6603 s7_number_to_chars (fragp
->fr_literal
, 0x0, fragp
->insn_addr
);
6605 memcpy (fragp
->fr_literal
+ fragp
->insn_addr
, backup
, fragp
->fr_fix
);
6606 fragp
->fr_fix
+= fragp
->insn_addr
;
6610 s7_pcrel_from (fixS
* fixP
)
6615 && (S_GET_SEGMENT (fixP
->fx_addsy
) == undefined_section
)
6616 && (fixP
->fx_subsy
== NULL
))
6622 retval
= fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
6628 /* Round up a section size to the appropriate boundary. */
6630 s7_section_align (segT segment
, valueT size
)
6632 int align
= bfd_get_section_alignment (stdoutput
, segment
);
6634 return ((size
+ (1 << align
) - 1) & -(1 << align
));
6638 s7_apply_fix (fixS
*fixP
, valueT
*valP
, segT seg
)
6640 offsetT value
= *valP
;
6641 offsetT abs_value
= 0;
6644 unsigned short HI
, LO
;
6646 char *buf
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
6648 gas_assert (fixP
->fx_r_type
< BFD_RELOC_UNUSED
);
6649 if (fixP
->fx_addsy
== 0 && !fixP
->fx_pcrel
)
6651 if (fixP
->fx_r_type
!= BFD_RELOC_SCORE_DUMMY_HI16
)
6655 /* If this symbol is in a different section then we need to leave it for
6656 the linker to deal with. Unfortunately, md_pcrel_from can't tell,
6657 so we have to undo it's effects here. */
6660 if (fixP
->fx_addsy
!= NULL
6661 && S_IS_DEFINED (fixP
->fx_addsy
)
6662 && S_GET_SEGMENT (fixP
->fx_addsy
) != seg
)
6663 value
+= md_pcrel_from (fixP
);
6666 /* Remember value for emit_reloc. */
6667 fixP
->fx_addnumber
= value
;
6669 switch (fixP
->fx_r_type
)
6671 case BFD_RELOC_HI16_S
:
6673 { /* For la rd, imm32. */
6674 newval
= s7_md_chars_to_number (buf
, s7_INSN_SIZE
);
6675 HI
= (value
) >> 16; /* mul to 2, then take the hi 16 bit. */
6676 newval
|= (HI
& 0x3fff) << 1;
6677 newval
|= ((HI
>> 14) & 0x3) << 16;
6678 s7_number_to_chars (buf
, newval
, s7_INSN_SIZE
);
6681 case BFD_RELOC_LO16
:
6682 if (fixP
->fx_done
) /* For la rd, imm32. */
6684 newval
= s7_md_chars_to_number (buf
, s7_INSN_SIZE
);
6685 LO
= (value
) & 0xffff;
6686 newval
|= (LO
& 0x3fff) << 1; /* 16 bit: imm -> 14 bit in lo, 2 bit in hi. */
6687 newval
|= ((LO
>> 14) & 0x3) << 16;
6688 s7_number_to_chars (buf
, newval
, s7_INSN_SIZE
);
6691 case BFD_RELOC_SCORE_JMP
:
6693 content
= s7_md_chars_to_number (buf
, s7_INSN_SIZE
);
6694 value
= fixP
->fx_offset
;
6695 if (!(value
>= 0 && value
<= 0x1ffffff))
6697 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6698 _("j or jl truncate (0x%x) [0 ~ 2^25-1]"), (unsigned int) value
);
6701 content
= (content
& ~0x3ff7ffe) | ((value
<< 1) & 0x3ff0000) | (value
& 0x7fff);
6702 s7_number_to_chars (buf
, content
, s7_INSN_SIZE
);
6705 case BFD_RELOC_SCORE_BRANCH
:
6706 if ((S_GET_SEGMENT (fixP
->fx_addsy
) != seg
) || (fixP
->fx_addsy
!= NULL
&& S_IS_EXTERNAL (fixP
->fx_addsy
)))
6707 value
= fixP
->fx_offset
;
6711 content
= s7_md_chars_to_number (buf
, s7_INSN_SIZE
);
6712 if ((fixP
->fx_frag
->fr_opcode
!= 0) && ((content
& 0x80008000) != 0x80008000))
6714 if ((value
& 0x80000000) == 0x80000000)
6715 abs_value
= 0xffffffff - value
+ 1;
6716 if ((abs_value
& 0xffffff00) != 0)
6718 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6719 _(" branch relocation truncate (0x%x) [-2^8 ~ 2^8]"), (unsigned int) value
);
6722 content
= s7_md_chars_to_number (buf
, s7_INSN16_SIZE
);
6724 content
= (content
& 0xff00) | ((value
>> 1) & 0xff);
6725 s7_number_to_chars (buf
, content
, s7_INSN16_SIZE
);
6726 fixP
->fx_r_type
= BFD_RELOC_SCORE16_BRANCH
;
6731 if ((value
& 0x80000000) == 0x80000000)
6732 abs_value
= 0xffffffff - value
+ 1;
6733 if ((abs_value
& 0xfff80000) != 0)
6735 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6736 _(" branch relocation truncate (0x%x) [-2^19 ~ 2^19]"),
6737 (unsigned int) value
);
6740 content
= s7_md_chars_to_number (buf
, s7_INSN_SIZE
);
6741 content
&= 0xfc00fc01;
6742 content
= (content
& 0xfc00fc01) | (value
& 0x3fe) | ((value
<< 6) & 0x3ff0000);
6743 s7_number_to_chars (buf
, content
, s7_INSN_SIZE
);
6746 case BFD_RELOC_SCORE16_JMP
:
6747 content
= s7_md_chars_to_number (buf
, s7_INSN16_SIZE
);
6749 value
= fixP
->fx_offset
;
6750 if (!(value
>= 0 && value
<= 0xfff))
6752 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6753 _("j! or jl! truncate (0x%x) [0 ~ 2^12-1]"), (unsigned int) value
);
6756 value
= fixP
->fx_offset
& 0xfff;
6757 content
= (content
& 0xfc01) | (value
& 0xffe);
6758 s7_number_to_chars (buf
, content
, s7_INSN16_SIZE
);
6760 case BFD_RELOC_SCORE16_BRANCH
:
6761 content
= s7_md_chars_to_number (buf
, s7_INSN_SIZE
);
6762 if ((fixP
->fx_frag
->fr_opcode
!= 0) && ((content
& 0x80008000) == 0x80008000))
6764 if ((S_GET_SEGMENT (fixP
->fx_addsy
) != seg
) ||
6765 (fixP
->fx_addsy
!= NULL
&& S_IS_EXTERNAL (fixP
->fx_addsy
)))
6766 value
= fixP
->fx_offset
;
6770 if ((value
& 0xfff80000) != 0 && (value
& 0xfff80000) != 0xfff80000)
6772 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6773 _(" branch relocation truncate (0x%x) [-2^19 ~ 2^19]"),
6774 (unsigned int) value
);
6777 content
= s7_md_chars_to_number (buf
, s7_INSN_SIZE
);
6778 content
= (content
& 0xfc00fc01) | (value
& 0x3fe) | ((value
<< 6) & 0x3ff0000);
6779 s7_number_to_chars (buf
, content
, s7_INSN_SIZE
);
6780 fixP
->fx_r_type
= BFD_RELOC_SCORE_BRANCH
;
6786 /* In different section. */
6787 if ((S_GET_SEGMENT (fixP
->fx_addsy
) != seg
) ||
6788 (fixP
->fx_addsy
!= NULL
&& S_IS_EXTERNAL (fixP
->fx_addsy
)))
6789 value
= fixP
->fx_offset
;
6793 if ((value
& 0xffffff00) != 0 && (value
& 0xffffff00) != 0xffffff00)
6795 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6796 _(" branch relocation truncate (0x%x) [-2^8 ~ 2^8]"),
6797 (unsigned int) value
);
6800 content
= s7_md_chars_to_number (buf
, s7_INSN16_SIZE
);
6801 content
= (content
& 0xff00) | ((value
>> 1) & 0xff);
6802 s7_number_to_chars (buf
, content
, s7_INSN16_SIZE
);
6806 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
6807 s7_number_to_chars (buf
, value
, 1);
6811 value
= fixP
->fx_offset
;
6812 s7_number_to_chars (buf
, value
, 1);
6818 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
6819 s7_number_to_chars (buf
, value
, 2);
6823 value
= fixP
->fx_offset
;
6824 s7_number_to_chars (buf
, value
, 2);
6830 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
6831 s7_number_to_chars (buf
, value
, 4);
6835 value
= fixP
->fx_offset
;
6836 s7_number_to_chars (buf
, value
, 4);
6840 case BFD_RELOC_VTABLE_INHERIT
:
6842 if (fixP
->fx_addsy
&& !S_IS_DEFINED (fixP
->fx_addsy
) && !S_IS_WEAK (fixP
->fx_addsy
))
6843 S_SET_WEAK (fixP
->fx_addsy
);
6845 case BFD_RELOC_VTABLE_ENTRY
:
6848 case BFD_RELOC_SCORE_GPREL15
:
6849 content
= s7_md_chars_to_number (buf
, s7_INSN_SIZE
);
6850 if ((fixP
->fx_frag
->fr_opcode
!= 0) && ((content
& 0xfc1c8000) != 0x94188000))
6851 fixP
->fx_r_type
= BFD_RELOC_NONE
;
6854 case BFD_RELOC_SCORE_GOT15
:
6855 case BFD_RELOC_SCORE_DUMMY_HI16
:
6856 case BFD_RELOC_SCORE_GOT_LO16
:
6857 case BFD_RELOC_SCORE_CALL15
:
6858 case BFD_RELOC_GPREL32
:
6860 case BFD_RELOC_NONE
:
6862 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("bad relocation fixup type (%d)"), fixP
->fx_r_type
);
6866 /* Translate internal representation of relocation info to BFD target format. */
6869 s7_gen_reloc (asection
* section ATTRIBUTE_UNUSED
, fixS
* fixp
)
6871 static arelent
*retval
[MAX_RELOC_EXPANSION
+ 1]; /* MAX_RELOC_EXPANSION equals 2. */
6873 bfd_reloc_code_real_type code
;
6876 reloc
= retval
[0] = XNEW (arelent
);
6879 reloc
->sym_ptr_ptr
= XNEW (asymbol
*);
6880 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
6881 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
6882 reloc
->addend
= fixp
->fx_offset
;
6884 /* If this is a variant frag, we may need to adjust the existing
6885 reloc and generate a new one. */
6886 if (fixp
->fx_frag
->fr_opcode
!= NULL
&& (fixp
->fx_r_type
== BFD_RELOC_SCORE_GPREL15
))
6888 /* Update instruction imm bit. */
6893 buf
= fixp
->fx_frag
->fr_literal
+ fixp
->fx_frag
->insn_addr
;
6894 newval
= s7_md_chars_to_number (buf
, s7_INSN_SIZE
);
6895 off
= fixp
->fx_offset
>> 16;
6896 newval
|= (off
& 0x3fff) << 1;
6897 newval
|= ((off
>> 14) & 0x3) << 16;
6898 s7_number_to_chars (buf
, newval
, s7_INSN_SIZE
);
6900 buf
+= s7_INSN_SIZE
;
6901 newval
= s7_md_chars_to_number (buf
, s7_INSN_SIZE
);
6902 off
= fixp
->fx_offset
& 0xffff;
6903 newval
|= ((off
& 0x3fff) << 1);
6904 newval
|= (((off
>> 14) & 0x3) << 16);
6905 s7_number_to_chars (buf
, newval
, s7_INSN_SIZE
);
6907 retval
[1] = XNEW (arelent
);
6909 retval
[1]->sym_ptr_ptr
= XNEW (asymbol
*);
6910 *retval
[1]->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
6911 retval
[1]->address
= (reloc
->address
+ s7_RELAX_RELOC2 (fixp
->fx_frag
->fr_subtype
));
6913 retval
[1]->addend
= 0;
6914 retval
[1]->howto
= bfd_reloc_type_lookup (stdoutput
, BFD_RELOC_LO16
);
6915 gas_assert (retval
[1]->howto
!= NULL
);
6917 fixp
->fx_r_type
= BFD_RELOC_HI16_S
;
6920 code
= fixp
->fx_r_type
;
6921 switch (fixp
->fx_r_type
)
6926 code
= BFD_RELOC_32_PCREL
;
6930 case BFD_RELOC_HI16_S
:
6931 case BFD_RELOC_LO16
:
6932 case BFD_RELOC_SCORE_JMP
:
6933 case BFD_RELOC_SCORE_BRANCH
:
6934 case BFD_RELOC_SCORE16_JMP
:
6935 case BFD_RELOC_SCORE16_BRANCH
:
6936 case BFD_RELOC_VTABLE_ENTRY
:
6937 case BFD_RELOC_VTABLE_INHERIT
:
6938 case BFD_RELOC_SCORE_GPREL15
:
6939 case BFD_RELOC_SCORE_GOT15
:
6940 case BFD_RELOC_SCORE_DUMMY_HI16
:
6941 case BFD_RELOC_SCORE_GOT_LO16
:
6942 case BFD_RELOC_SCORE_CALL15
:
6943 case BFD_RELOC_GPREL32
:
6944 case BFD_RELOC_NONE
:
6945 code
= fixp
->fx_r_type
;
6948 type
= _("<unknown>");
6949 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
6950 _("cannot represent %s relocation in this object file format"), type
);
6954 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
6955 if (reloc
->howto
== NULL
)
6957 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
6958 _("cannot represent %s relocation in this object file format1"),
6959 bfd_get_reloc_code_name (code
));
6962 /* HACK: Since arm ELF uses Rel instead of Rela, encode the
6963 vtable entry to be used in the relocation's section offset. */
6964 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
6965 reloc
->address
= fixp
->fx_offset
;