1 /* tc-score7.c -- Assembler for Score7
2 Copyright (C) 2009-2019 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_INSN_NAME_LEN 16
147 /* Relax will need some padding for alignment. */
148 #define s7_RELAX_PAD_BYTE 3
150 #define s7_USE_GLOBAL_POINTER_OPT 1
154 /* Enumeration matching entries in table above. */
155 enum s7_score_reg_type
157 s7_REG_TYPE_SCORE
= 0,
158 #define REG_TYPE_FIRST s7_REG_TYPE_SCORE
159 s7_REG_TYPE_SCORE_SR
= 1,
160 s7_REG_TYPE_SCORE_CR
= 2,
164 enum s7_score_pic_level
169 static enum s7_score_pic_level s7_score_pic
= s7_NO_PIC
;
171 enum s7_insn_type_for_dependency
190 struct s7_insn_to_dependency
192 const char *insn_name
;
193 enum s7_insn_type_for_dependency type
;
196 struct s7_data_dependency
198 enum s7_insn_type_for_dependency pre_insn_type
;
200 enum s7_insn_type_for_dependency cur_insn_type
;
204 int warn_or_error
; /* warning - 0; error - 1 */
207 static const struct s7_insn_to_dependency s7_insn_to_dependency_table
[] =
209 /* pce instruction. */
211 /* conditional branch instruction. */
212 {"bcs", s7_D_cond_br
},
213 {"bcc", s7_D_cond_br
},
214 {"bgtu", s7_D_cond_br
},
215 {"bleu", s7_D_cond_br
},
216 {"beq", s7_D_cond_br
},
217 {"bne", s7_D_cond_br
},
218 {"bgt", s7_D_cond_br
},
219 {"ble", s7_D_cond_br
},
220 {"bge", s7_D_cond_br
},
221 {"blt", s7_D_cond_br
},
222 {"bmi", s7_D_cond_br
},
223 {"bpl", s7_D_cond_br
},
224 {"bvs", s7_D_cond_br
},
225 {"bvc", s7_D_cond_br
},
226 {"bcsl", s7_D_cond_br
},
227 {"bccl", s7_D_cond_br
},
228 {"bgtul", s7_D_cond_br
},
229 {"bleul", s7_D_cond_br
},
230 {"beql", s7_D_cond_br
},
231 {"bnel", s7_D_cond_br
},
232 {"bgtl", s7_D_cond_br
},
233 {"blel", s7_D_cond_br
},
234 {"bgel", s7_D_cond_br
},
235 {"bltl", s7_D_cond_br
},
236 {"bmil", s7_D_cond_br
},
237 {"bpll", s7_D_cond_br
},
238 {"bvsl", s7_D_cond_br
},
239 {"bvcl", s7_D_cond_br
},
240 {"bcs!", s7_D_cond_br
},
241 {"bcc!", s7_D_cond_br
},
242 {"bgtu!", s7_D_cond_br
},
243 {"bleu!", s7_D_cond_br
},
244 {"beq!", s7_D_cond_br
},
245 {"bne!", s7_D_cond_br
},
246 {"bgt!", s7_D_cond_br
},
247 {"ble!", s7_D_cond_br
},
248 {"bge!", s7_D_cond_br
},
249 {"blt!", s7_D_cond_br
},
250 {"bmi!", s7_D_cond_br
},
251 {"bpl!", s7_D_cond_br
},
252 {"bvs!", s7_D_cond_br
},
253 {"bvc!", s7_D_cond_br
},
254 {"brcs", s7_D_cond_br
},
255 {"brcc", s7_D_cond_br
},
256 {"brgtu", s7_D_cond_br
},
257 {"brleu", s7_D_cond_br
},
258 {"breq", s7_D_cond_br
},
259 {"brne", s7_D_cond_br
},
260 {"brgt", s7_D_cond_br
},
261 {"brle", s7_D_cond_br
},
262 {"brge", s7_D_cond_br
},
263 {"brlt", s7_D_cond_br
},
264 {"brmi", s7_D_cond_br
},
265 {"brpl", s7_D_cond_br
},
266 {"brvs", s7_D_cond_br
},
267 {"brvc", s7_D_cond_br
},
268 {"brcsl", s7_D_cond_br
},
269 {"brccl", s7_D_cond_br
},
270 {"brgtul", s7_D_cond_br
},
271 {"brleul", s7_D_cond_br
},
272 {"breql", s7_D_cond_br
},
273 {"brnel", s7_D_cond_br
},
274 {"brgtl", s7_D_cond_br
},
275 {"brlel", s7_D_cond_br
},
276 {"brgel", s7_D_cond_br
},
277 {"brltl", s7_D_cond_br
},
278 {"brmil", s7_D_cond_br
},
279 {"brpll", s7_D_cond_br
},
280 {"brvsl", s7_D_cond_br
},
281 {"brvcl", s7_D_cond_br
},
282 {"brcs!", s7_D_cond_br
},
283 {"brcc!", s7_D_cond_br
},
284 {"brgtu!", s7_D_cond_br
},
285 {"brleu!", s7_D_cond_br
},
286 {"breq!", s7_D_cond_br
},
287 {"brne!", s7_D_cond_br
},
288 {"brgt!", s7_D_cond_br
},
289 {"brle!", s7_D_cond_br
},
290 {"brge!", s7_D_cond_br
},
291 {"brlt!", s7_D_cond_br
},
292 {"brmi!", s7_D_cond_br
},
293 {"brpl!", s7_D_cond_br
},
294 {"brvs!", s7_D_cond_br
},
295 {"brvc!", s7_D_cond_br
},
296 {"brcsl!", s7_D_cond_br
},
297 {"brccl!", s7_D_cond_br
},
298 {"brgtul!", s7_D_cond_br
},
299 {"brleul!", s7_D_cond_br
},
300 {"breql!", s7_D_cond_br
},
301 {"brnel!", s7_D_cond_br
},
302 {"brgtl!", s7_D_cond_br
},
303 {"brlel!", s7_D_cond_br
},
304 {"brgel!", s7_D_cond_br
},
305 {"brltl!", s7_D_cond_br
},
306 {"brmil!", s7_D_cond_br
},
307 {"brpll!", s7_D_cond_br
},
308 {"brvsl!", s7_D_cond_br
},
309 {"brvcl!", s7_D_cond_br
},
310 /* conditional move instruction. */
311 {"mvcs", s7_D_cond_mv
},
312 {"mvcc", s7_D_cond_mv
},
313 {"mvgtu", s7_D_cond_mv
},
314 {"mvleu", s7_D_cond_mv
},
315 {"mveq", s7_D_cond_mv
},
316 {"mvne", s7_D_cond_mv
},
317 {"mvgt", s7_D_cond_mv
},
318 {"mvle", s7_D_cond_mv
},
319 {"mvge", s7_D_cond_mv
},
320 {"mvlt", s7_D_cond_mv
},
321 {"mvmi", s7_D_cond_mv
},
322 {"mvpl", s7_D_cond_mv
},
323 {"mvvs", s7_D_cond_mv
},
324 {"mvvc", s7_D_cond_mv
},
325 /* move special instruction. */
327 {"mftlb", s7_D_mftlb
},
328 {"mtptlb", s7_D_mtptlb
},
329 {"mtrtlb", s7_D_mtrtlb
},
333 /* cache instruction. */
334 {"cache 8", s7_D_cached
},
335 {"cache 9", s7_D_cached
},
336 {"cache 10", s7_D_cached
},
337 {"cache 11", s7_D_cached
},
338 {"cache 12", s7_D_cached
},
339 {"cache 13", s7_D_cached
},
340 {"cache 14", s7_D_cached
},
341 {"cache 24", s7_D_cached
},
342 {"cache 26", s7_D_cached
},
343 {"cache 27", s7_D_cached
},
344 {"cache 29", s7_D_cached
},
345 {"cache 30", s7_D_cached
},
346 {"cache 31", s7_D_cached
},
347 {"cache 0", s7_D_cachei
},
348 {"cache 1", s7_D_cachei
},
349 {"cache 2", s7_D_cachei
},
350 {"cache 3", s7_D_cachei
},
351 {"cache 4", s7_D_cachei
},
352 {"cache 16", s7_D_cachei
},
353 {"cache 17", s7_D_cachei
},
354 /* load/store instruction. */
358 {"lbup!", s7_D_ldst
},
377 {"push!", s7_D_ldst
},
378 {"pushhi!", s7_D_ldst
},
380 {"pophi!", s7_D_ldst
},
390 /* load combine instruction. */
391 {"lcb", s7_D_ldcombine
},
392 {"lcw", s7_D_ldcombine
},
393 {"lce", s7_D_ldcombine
},
396 static const struct s7_data_dependency s7_data_dependency_table
[] =
398 /* Condition register. */
399 {s7_D_mtcr
, "cr1", s7_D_pce
, "", 2, 1, 0},
400 {s7_D_mtcr
, "cr1", s7_D_cond_br
, "", 1, 0, 1},
401 {s7_D_mtcr
, "cr1", s7_D_cond_mv
, "", 1, 0, 1},
402 /* Status register. */
403 {s7_D_mtcr
, "cr0", s7_D_all_insn
, "", 5, 4, 0},
405 {s7_D_mtcr
, "cr4", s7_D_all_insn
, "", 6, 5, 0},
406 /* EntryHi/EntryLo register. */
407 {s7_D_mftlb
, "", s7_D_mtptlb
, "", 1, 1, 1},
408 {s7_D_mftlb
, "", s7_D_mtrtlb
, "", 1, 1, 1},
409 {s7_D_mftlb
, "", s7_D_stlb
, "", 1, 1,1},
410 {s7_D_mftlb
, "", s7_D_mfcr
, "cr11", 1, 1, 1},
411 {s7_D_mftlb
, "", s7_D_mfcr
, "cr12", 1, 1, 1},
412 /* Index register. */
413 {s7_D_stlb
, "", s7_D_mtptlb
, "", 1, 1, 1},
414 {s7_D_stlb
, "", s7_D_mftlb
, "", 1, 1, 1},
415 {s7_D_stlb
, "", s7_D_mfcr
, "cr8", 2, 2, 1},
417 {s7_D_cached
, "", s7_D_ldst
, "", 1, 1, 0},
418 {s7_D_cached
, "", s7_D_ldcombine
, "", 1, 1, 0},
419 {s7_D_cachei
, "", s7_D_all_insn
, "", 5, 4, 0},
421 {s7_D_ldcombine
, "", s7_D_mfsr
, "sr1", 3, 3, 1},
426 /* Used to contain constructed error messages. */
427 static char s7_err_msg
[255];
428 static int s7_fix_data_dependency
= 0;
429 static int s7_warn_fix_data_dependency
= 1;
431 static int s7_in_my_get_expression
= 0;
433 /* Default, pop warning message when using r1. */
434 static int s7_nor1
= 1;
436 /* Default will do instruction relax, -O0 will set s7_g_opt = 0. */
437 static unsigned int s7_g_opt
= 1;
439 /* The size of the small data section. */
440 static unsigned int s7_g_switch_value
= 8;
442 static segT s7_pdr_seg
;
446 char name
[s7_INSN_NAME_LEN
];
447 unsigned long instruction
;
448 unsigned long relax_inst
;
451 enum score_insn_type type
;
452 char str
[s7_MAX_LITERAL_POOL_SIZE
];
455 char reg
[s7_INSN_NAME_LEN
];
458 bfd_reloc_code_real_type type
;
463 static struct s7_score_it s7_inst
;
468 unsigned long reg_mask
;
469 unsigned long reg_offset
;
470 unsigned long fpreg_mask
;
472 unsigned long frame_offset
;
473 unsigned long frame_reg
;
474 unsigned long pc_reg
;
476 static s7_procS s7_cur_proc
;
477 static s7_procS
*s7_cur_proc_ptr
;
478 static int s7_numprocs
;
480 /* Structure for a hash table entry for a register. */
487 static const struct s7_reg_entry s7_score_rn_table
[] =
489 {"r0", 0}, {"r1", 1}, {"r2", 2}, {"r3", 3},
490 {"r4", 4}, {"r5", 5}, {"r6", 6}, {"r7", 7},
491 {"r8", 8}, {"r9", 9}, {"r10", 10}, {"r11", 11},
492 {"r12", 12}, {"r13", 13}, {"r14", 14}, {"r15", 15},
493 {"r16", 16}, {"r17", 17}, {"r18", 18}, {"r19", 19},
494 {"r20", 20}, {"r21", 21}, {"r22", 22}, {"r23", 23},
495 {"r24", 24}, {"r25", 25}, {"r26", 26}, {"r27", 27},
496 {"r28", 28}, {"r29", 29}, {"r30", 30}, {"r31", 31},
500 static const struct s7_reg_entry s7_score_srn_table
[] =
502 {"sr0", 0}, {"sr1", 1}, {"sr2", 2},
506 static const struct s7_reg_entry s7_score_crn_table
[] =
508 {"cr0", 0}, {"cr1", 1}, {"cr2", 2}, {"cr3", 3},
509 {"cr4", 4}, {"cr5", 5}, {"cr6", 6}, {"cr7", 7},
510 {"cr8", 8}, {"cr9", 9}, {"cr10", 10}, {"cr11", 11},
511 {"cr12", 12}, {"cr13", 13}, {"cr14", 14}, {"cr15", 15},
512 {"cr16", 16}, {"cr17", 17}, {"cr18", 18}, {"cr19", 19},
513 {"cr20", 20}, {"cr21", 21}, {"cr22", 22}, {"cr23", 23},
514 {"cr24", 24}, {"cr25", 25}, {"cr26", 26}, {"cr27", 27},
515 {"cr28", 28}, {"cr29", 29}, {"cr30", 30}, {"cr31", 31},
521 const struct s7_reg_entry
*names
;
523 struct hash_control
*htab
;
524 const char *expected
;
527 static struct s7_reg_map s7_all_reg_maps
[] =
529 {s7_score_rn_table
, 31, NULL
, N_("S+core register expected")},
530 {s7_score_srn_table
, 2, NULL
, N_("S+core special-register expected")},
531 {s7_score_crn_table
, 31, NULL
, N_("S+core co-processor register expected")},
534 static struct hash_control
*s7_score_ops_hsh
= NULL
;
535 static struct hash_control
*s7_dependency_insn_hsh
= NULL
;
538 struct s7_datafield_range
545 static struct s7_datafield_range s7_score_df_range
[] =
547 {_IMM4
, 4, {0, (1 << 4) - 1}}, /* ( 0 ~ 15 ) */
548 {_IMM5
, 5, {0, (1 << 5) - 1}}, /* ( 0 ~ 31 ) */
549 {_IMM8
, 8, {0, (1 << 8) - 1}}, /* ( 0 ~ 255 ) */
550 {_IMM14
, 14, {0, (1 << 14) - 1}}, /* ( 0 ~ 16383) */
551 {_IMM15
, 15, {0, (1 << 15) - 1}}, /* ( 0 ~ 32767) */
552 {_IMM16
, 16, {0, (1 << 16) - 1}}, /* ( 0 ~ 65535) */
553 {_SIMM10
, 10, {-(1 << 9), (1 << 9) - 1}}, /* ( -512 ~ 511 ) */
554 {_SIMM12
, 12, {-(1 << 11), (1 << 11) - 1}}, /* ( -2048 ~ 2047 ) */
555 {_SIMM14
, 14, {-(1 << 13), (1 << 13) - 1}}, /* ( -8192 ~ 8191 ) */
556 {_SIMM15
, 15, {-(1 << 14), (1 << 14) - 1}}, /* (-16384 ~ 16383) */
557 {_SIMM16
, 16, {-(1 << 15), (1 << 15) - 1}}, /* (-32768 ~ 32767) */
558 {_SIMM14_NEG
, 14, {-(1 << 13), (1 << 13) - 1}}, /* ( -8191 ~ 8192 ) */
559 {_IMM16_NEG
, 16, {0, (1 << 16) - 1}}, /* (-65535 ~ 0 ) */
560 {_SIMM16_NEG
, 16, {-(1 << 15), (1 << 15) - 1}}, /* (-32768 ~ 32767) */
561 {_IMM20
, 20, {0, (1 << 20) - 1}},
562 {_IMM25
, 25, {0, (1 << 25) - 1}},
563 {_DISP8div2
, 8, {-(1 << 8), (1 << 8) - 1}}, /* ( -256 ~ 255 ) */
564 {_DISP11div2
, 11, {0, 0}},
565 {_DISP19div2
, 19, {-(1 << 19), (1 << 19) - 1}}, /* (-524288 ~ 524287) */
566 {_DISP24div2
, 24, {0, 0}},
567 {_VALUE
, 32, {0, ((unsigned int)1 << 31) - 1}},
568 {_VALUE_HI16
, 16, {0, (1 << 16) - 1}},
569 {_VALUE_LO16
, 16, {0, (1 << 16) - 1}},
570 {_VALUE_LDST_LO16
, 16, {0, (1 << 16) - 1}},
571 {_SIMM16_LA
, 16, {-(1 << 15), (1 << 15) - 1}}, /* (-32768 ~ 32767) */
572 {_IMM5_RSHIFT_1
, 5, {0, (1 << 6) - 1}}, /* ( 0 ~ 63 ) */
573 {_IMM5_RSHIFT_2
, 5, {0, (1 << 7) - 1}}, /* ( 0 ~ 127 ) */
574 {_SIMM16_LA_POS
, 16, {0, (1 << 15) - 1}}, /* ( 0 ~ 32767) */
575 {_IMM5_RANGE_8_31
, 5, {8, 31}}, /* But for cop0 the valid data : (8 ~ 31). */
576 {_IMM10_RSHIFT_2
, 10, {-(1 << 11), (1 << 11) - 1}}, /* For ldc#, stc#. */
577 {_SIMM10
, 10, {0, (1 << 10) - 1}}, /* ( -1024 ~ 1023 ) */
578 {_SIMM12
, 12, {0, (1 << 12) - 1}}, /* ( -2048 ~ 2047 ) */
579 {_SIMM14
, 14, {0, (1 << 14) - 1}}, /* ( -8192 ~ 8191 ) */
580 {_SIMM15
, 15, {0, (1 << 15) - 1}}, /* (-16384 ~ 16383) */
581 {_SIMM16
, 16, {0, (1 << 16) - 1}}, /* (-65536 ~ 65536) */
582 {_SIMM14_NEG
, 14, {0, (1 << 16) - 1}}, /* ( -8191 ~ 8192 ) */
583 {_IMM16_NEG
, 16, {0, (1 << 16) - 1}}, /* ( 65535 ~ 0 ) */
584 {_SIMM16_NEG
, 16, {0, (1 << 16) - 1}}, /* ( 65535 ~ 0 ) */
585 {_IMM20
, 20, {0, (1 << 20) - 1}}, /* (-32768 ~ 32767) */
586 {_IMM25
, 25, {0, (1 << 25) - 1}}, /* (-32768 ~ 32767) */
587 {_GP_IMM15
, 15, {0, (1 << 15) - 1}}, /* ( 0 ~ 65535) */
588 {_GP_IMM14
, 14, {0, (1 << 14) - 1}}, /* ( 0 ~ 65535) */
589 {_SIMM16_pic
, 16, {-(1 << 15), (1 << 15) - 1}}, /* (-32768 ~ 32767) */
590 {_IMM16_LO16_pic
, 16, {0, (1 << 16) - 1}}, /* ( 65535 ~ 0 ) */
591 {_IMM16_pic
, 16, {0, (1 << 16) - 1}}, /* ( 0 ~ 65535) */
597 /* Instruction name. */
598 const char *template_name
;
600 /* Instruction Opcode. */
603 /* Instruction bit mask. */
606 /* Relax instruction opcode. 0x8000 imply no relaxation. */
609 /* Instruction type. */
610 enum score_insn_type type
;
612 /* Function to call to parse args. */
613 void (*parms
) (char *);
616 static const struct s7_asm_opcode s7_score_ldst_insns
[] =
618 {"lw", 0x20000000, 0x3e000000, 0x2008, Rd_rvalueRs_SI15
, s7_do_ldst_insn
},
619 {"lw", 0x06000000, 0x3e000007, 0x8000, Rd_rvalueRs_preSI12
, s7_do_ldst_insn
},
620 {"lw", 0x0e000000, 0x3e000007, 0x200a, Rd_rvalueRs_postSI12
, s7_do_ldst_insn
},
621 {"lh", 0x22000000, 0x3e000000, 0x2009, Rd_rvalueRs_SI15
, s7_do_ldst_insn
},
622 {"lh", 0x06000001, 0x3e000007, 0x8000, Rd_rvalueRs_preSI12
, s7_do_ldst_insn
},
623 {"lh", 0x0e000001, 0x3e000007, 0x8000, Rd_rvalueRs_postSI12
, s7_do_ldst_insn
},
624 {"lhu", 0x24000000, 0x3e000000, 0x8000, Rd_rvalueRs_SI15
, s7_do_ldst_insn
},
625 {"lhu", 0x06000002, 0x3e000007, 0x8000, Rd_rvalueRs_preSI12
, s7_do_ldst_insn
},
626 {"lhu", 0x0e000002, 0x3e000007, 0x8000, Rd_rvalueRs_postSI12
, s7_do_ldst_insn
},
627 {"lb", 0x26000000, 0x3e000000, 0x8000, Rd_rvalueRs_SI15
, s7_do_ldst_insn
},
628 {"lb", 0x06000003, 0x3e000007, 0x8000, Rd_rvalueRs_preSI12
, s7_do_ldst_insn
},
629 {"lb", 0x0e000003, 0x3e000007, 0x8000, Rd_rvalueRs_postSI12
, s7_do_ldst_insn
},
630 {"sw", 0x28000000, 0x3e000000, 0x200c, Rd_lvalueRs_SI15
, s7_do_ldst_insn
},
631 {"sw", 0x06000004, 0x3e000007, 0x200e, Rd_lvalueRs_preSI12
, s7_do_ldst_insn
},
632 {"sw", 0x0e000004, 0x3e000007, 0x8000, Rd_lvalueRs_postSI12
, s7_do_ldst_insn
},
633 {"sh", 0x2a000000, 0x3e000000, 0x200d, Rd_lvalueRs_SI15
, s7_do_ldst_insn
},
634 {"sh", 0x06000005, 0x3e000007, 0x8000, Rd_lvalueRs_preSI12
, s7_do_ldst_insn
},
635 {"sh", 0x0e000005, 0x3e000007, 0x8000, Rd_lvalueRs_postSI12
, s7_do_ldst_insn
},
636 {"lbu", 0x2c000000, 0x3e000000, 0x200b, Rd_rvalueRs_SI15
, s7_do_ldst_insn
},
637 {"lbu", 0x06000006, 0x3e000007, 0x8000, Rd_rvalueRs_preSI12
, s7_do_ldst_insn
},
638 {"lbu", 0x0e000006, 0x3e000007, 0x8000, Rd_rvalueRs_postSI12
, s7_do_ldst_insn
},
639 {"sb", 0x2e000000, 0x3e000000, 0x200f, Rd_lvalueRs_SI15
, s7_do_ldst_insn
},
640 {"sb", 0x06000007, 0x3e000007, 0x8000, Rd_lvalueRs_preSI12
, s7_do_ldst_insn
},
641 {"sb", 0x0e000007, 0x3e000007, 0x8000, Rd_lvalueRs_postSI12
, s7_do_ldst_insn
},
644 static const struct s7_asm_opcode s7_score_insns
[] =
646 {"abs", 0x3800000a, 0x3e007fff, 0x8000, Rd_Rs_x
, s7_do_rdrs
},
647 {"abs.s", 0x3800004b, 0x3e007fff, 0x8000, Rd_Rs_x
, s7_do_rdrs
},
648 {"add", 0x00000010, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s7_do_rdrsrs
},
649 {"add.c", 0x00000011, 0x3e0003ff, 0x2000, Rd_Rs_Rs
, s7_do_rdrsrs
},
650 {"add.s", 0x38000048, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s7_do_rdrsrs
},
651 {"addc", 0x00000012, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s7_do_rdrsrs
},
652 {"addc.c", 0x00000013, 0x3e0003ff, 0x0009, Rd_Rs_Rs
, s7_do_rdrsrs
},
653 {"addi", 0x02000000, 0x3e0e0001, 0x8000, Rd_SI16
, s7_do_rdsi16
},
654 {"addi.c", 0x02000001, 0x3e0e0001, 0x8000, Rd_SI16
, s7_do_rdsi16
},
655 {"addis", 0x0a000000, 0x3e0e0001, 0x8000, Rd_SI16
, s7_do_rdi16
},
656 {"addis.c", 0x0a000001, 0x3e0e0001, 0x8000, Rd_SI16
, s7_do_rdi16
},
657 {"addri", 0x10000000, 0x3e000001, 0x8000, Rd_Rs_SI14
, s7_do_rdrssi14
},
658 {"addri.c", 0x10000001, 0x3e000001, 0x8000, Rd_Rs_SI14
, s7_do_rdrssi14
},
659 {"addc!", 0x0009, 0x700f, 0x00000013, Rd_Rs
, s7_do16_rdrs
},
660 {"add!", 0x2000, 0x700f, 0x00000011, Rd_Rs
, s7_do16_rdrs
},
661 {"addei!", 0x6000 , 0x7087, 0x02000001, Rd_I4
, s7_do16_rdi4
},
662 {"subi", 0x02000000, 0x3e0e0001, 0x8000, Rd_SI16
, s7_do_sub_rdsi16
},
663 {"subi.c", 0x02000001, 0x3e0e0001, 0x8000, Rd_SI16
, s7_do_sub_rdsi16
},
664 {"subri", 0x10000000, 0x3e000001, 0x8000, Rd_Rs_SI14
, s7_do_sub_rdrssi14
},
665 {"subri.c", 0x10000001, 0x3e000001, 0x8000, Rd_Rs_SI14
, s7_do_sub_rdrssi14
},
666 {"and", 0x00000020, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s7_do_rdrsrs
},
667 {"and.c", 0x00000021, 0x3e0003ff, 0x2004, Rd_Rs_Rs
, s7_do_rdrsrs
},
668 {"andi", 0x02080000, 0x3e0e0001, 0x8000, Rd_I16
, s7_do_rdi16
},
669 {"andi.c", 0x02080001, 0x3e0e0001, 0x8000, Rd_I16
, s7_do_rdi16
},
670 {"andis", 0x0a080000, 0x3e0e0001, 0x8000, Rd_I16
, s7_do_rdi16
},
671 {"andis.c", 0x0a080001, 0x3e0e0001, 0x8000, Rd_I16
, s7_do_rdi16
},
672 {"andri", 0x18000000, 0x3e000001, 0x8000, Rd_Rs_I14
, s7_do_rdrsi14
},
673 {"andri.c", 0x18000001, 0x3e000001, 0x8000, Rd_Rs_I14
, s7_do_rdrsi14
},
674 {"and!", 0x2004, 0x700f, 0x00000021, Rd_Rs
, s7_do16_rdrs
},
675 {"bcs", 0x08000000, 0x3e007c01, 0x4000, PC_DISP19div2
, s7_do_branch
},
676 {"bcc", 0x08000400, 0x3e007c01, 0x4000, PC_DISP19div2
, s7_do_branch
},
677 {"bcnz", 0x08003800, 0x3e007c01, 0x4000, PC_DISP19div2
, s7_do_branch
},
678 {"bcsl", 0x08000001, 0x3e007c01, 0x8000, PC_DISP19div2
, s7_do_branch
},
679 {"bccl", 0x08000401, 0x3e007c01, 0x8000, PC_DISP19div2
, s7_do_branch
},
680 {"bcnzl", 0x08003801, 0x3e007c01, 0x8000, PC_DISP19div2
, s7_do_branch
},
681 {"bcs!", 0x4000, 0x7f00, 0x08000000, PC_DISP8div2
, s7_do16_branch
},
682 {"bcc!", 0x4100, 0x7f00, 0x08000400, PC_DISP8div2
, s7_do16_branch
},
683 {"bcnz!", 0x4e00, 0x7f00, 0x08003800, PC_DISP8div2
, s7_do16_branch
},
684 {"beq", 0x08001000, 0x3e007c01, 0x4000, PC_DISP19div2
, s7_do_branch
},
685 {"beql", 0x08001001, 0x3e007c01, 0x8000, PC_DISP19div2
, s7_do_branch
},
686 {"beq!", 0x4400, 0x7f00, 0x08001000, PC_DISP8div2
, s7_do16_branch
},
687 {"bgtu", 0x08000800, 0x3e007c01, 0x4000, PC_DISP19div2
, s7_do_branch
},
688 {"bgt", 0x08001800, 0x3e007c01, 0x4000, PC_DISP19div2
, s7_do_branch
},
689 {"bge", 0x08002000, 0x3e007c01, 0x4000, PC_DISP19div2
, s7_do_branch
},
690 {"bgtul", 0x08000801, 0x3e007c01, 0x8000, PC_DISP19div2
, s7_do_branch
},
691 {"bgtl", 0x08001801, 0x3e007c01, 0x8000, PC_DISP19div2
, s7_do_branch
},
692 {"bgel", 0x08002001, 0x3e007c01, 0x8000, PC_DISP19div2
, s7_do_branch
},
693 {"bgtu!", 0x4200, 0x7f00, 0x08000800, PC_DISP8div2
, s7_do16_branch
},
694 {"bgt!", 0x4600, 0x7f00, 0x08001800, PC_DISP8div2
, s7_do16_branch
},
695 {"bge!", 0x4800, 0x7f00, 0x08002000, PC_DISP8div2
, s7_do16_branch
},
696 {"bitclr.c", 0x00000029, 0x3e0003ff, 0x6004, Rd_Rs_I5
, s7_do_rdrsi5
},
697 {"bitrev", 0x3800000c, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s7_do_rdrsrs
},
698 {"bitset.c", 0x0000002b, 0x3e0003ff, 0x6005, Rd_Rs_I5
, s7_do_rdrsi5
},
699 {"bittst.c", 0x0000002d, 0x3e0003ff, 0x6006, x_Rs_I5
, s7_do_xrsi5
},
700 {"bittgl.c", 0x0000002f, 0x3e0003ff, 0x6007, Rd_Rs_I5
, s7_do_rdrsi5
},
701 {"bitclr!", 0x6004, 0x7007, 0x00000029, Rd_I5
, s7_do16_rdi5
},
702 {"bitset!", 0x6005, 0x7007, 0x0000002b, Rd_I5
, s7_do16_rdi5
},
703 {"bittst!", 0x6006, 0x7007, 0x0000002d, Rd_I5
, s7_do16_rdi5
},
704 {"bittgl!", 0x6007, 0x7007, 0x0000002f, Rd_I5
, s7_do16_rdi5
},
705 {"bleu", 0x08000c00, 0x3e007c01, 0x4000, PC_DISP19div2
, s7_do_branch
},
706 {"ble", 0x08001c00, 0x3e007c01, 0x4000, PC_DISP19div2
, s7_do_branch
},
707 {"blt", 0x08002400, 0x3e007c01, 0x4000, PC_DISP19div2
, s7_do_branch
},
708 {"bleul", 0x08000c01, 0x3e007c01, 0x8000, PC_DISP19div2
, s7_do_branch
},
709 {"blel", 0x08001c01, 0x3e007c01, 0x8000, PC_DISP19div2
, s7_do_branch
},
710 {"bltl", 0x08002401, 0x3e007c01, 0x8000, PC_DISP19div2
, s7_do_branch
},
711 {"bl", 0x08003c01, 0x3e007c01, 0x8000, PC_DISP19div2
, s7_do_branch
},
712 {"bleu!", 0x4300, 0x7f00, 0x08000c00, PC_DISP8div2
, s7_do16_branch
},
713 {"ble!", 0x4700, 0x7f00, 0x08001c00, PC_DISP8div2
, s7_do16_branch
},
714 {"blt!", 0x4900, 0x7f00, 0x08002400, PC_DISP8div2
, s7_do16_branch
},
715 {"bmi", 0x08002800, 0x3e007c01, 0x4000, PC_DISP19div2
, s7_do_branch
},
716 {"bmil", 0x08002801, 0x3e007c01, 0x8000, PC_DISP19div2
, s7_do_branch
},
717 {"bmi!", 0x00004a00, 0x00007f00, 0x08002800, PC_DISP8div2
, s7_do16_branch
},
718 {"bne", 0x08001400, 0x3e007c01, 0x4000, PC_DISP19div2
, s7_do_branch
},
719 {"bnel", 0x08001401, 0x3e007c01, 0x8000, PC_DISP19div2
, s7_do_branch
},
720 {"bne!", 0x4500, 0x7f00, 0x08001400, PC_DISP8div2
, s7_do16_branch
},
721 {"bpl", 0x08002c00, 0x3e007c01, 0x4000, PC_DISP19div2
, s7_do_branch
},
722 {"bpll", 0x08002c01, 0x3e007c01, 0x8000, PC_DISP19div2
, s7_do_branch
},
723 {"bpl!", 0x4b00, 0x7f00, 0x08002c00, PC_DISP8div2
, s7_do16_branch
},
724 {"brcs", 0x00000008, 0x3e007fff, 0x0004, x_Rs_x
, s7_do_rs
},
725 {"brcc", 0x00000408, 0x3e007fff, 0x0104, x_Rs_x
, s7_do_rs
},
726 {"brgtu", 0x00000808, 0x3e007fff, 0x0204, x_Rs_x
, s7_do_rs
},
727 {"brleu", 0x00000c08, 0x3e007fff, 0x0304, x_Rs_x
, s7_do_rs
},
728 {"breq", 0x00001008, 0x3e007fff, 0x0404, x_Rs_x
, s7_do_rs
},
729 {"brne", 0x00001408, 0x3e007fff, 0x0504, x_Rs_x
, s7_do_rs
},
730 {"brgt", 0x00001808, 0x3e007fff, 0x0604, x_Rs_x
, s7_do_rs
},
731 {"brle", 0x00001c08, 0x3e007fff, 0x0704, x_Rs_x
, s7_do_rs
},
732 {"brge", 0x00002008, 0x3e007fff, 0x0804, x_Rs_x
, s7_do_rs
},
733 {"brlt", 0x00002408, 0x3e007fff, 0x0904, x_Rs_x
, s7_do_rs
},
734 {"brmi", 0x00002808, 0x3e007fff, 0x0a04, x_Rs_x
, s7_do_rs
},
735 {"brpl", 0x00002c08, 0x3e007fff, 0x0b04, x_Rs_x
, s7_do_rs
},
736 {"brvs", 0x00003008, 0x3e007fff, 0x0c04, x_Rs_x
, s7_do_rs
},
737 {"brvc", 0x00003408, 0x3e007fff, 0x0d04, x_Rs_x
, s7_do_rs
},
738 {"brcnz", 0x00003808, 0x3e007fff, 0x0e04, x_Rs_x
, s7_do_rs
},
739 {"br", 0x00003c08, 0x3e007fff, 0x0f04, x_Rs_x
, s7_do_rs
},
740 {"brcsl", 0x00000009, 0x3e007fff, 0x000c, x_Rs_x
, s7_do_rs
},
741 {"brccl", 0x00000409, 0x3e007fff, 0x010c, x_Rs_x
, s7_do_rs
},
742 {"brgtul", 0x00000809, 0x3e007fff, 0x020c, x_Rs_x
, s7_do_rs
},
743 {"brleul", 0x00000c09, 0x3e007fff, 0x030c, x_Rs_x
, s7_do_rs
},
744 {"breql", 0x00001009, 0x3e007fff, 0x040c, x_Rs_x
, s7_do_rs
},
745 {"brnel", 0x00001409, 0x3e007fff, 0x050c, x_Rs_x
, s7_do_rs
},
746 {"brgtl", 0x00001809, 0x3e007fff, 0x060c, x_Rs_x
, s7_do_rs
},
747 {"brlel", 0x00001c09, 0x3e007fff, 0x070c, x_Rs_x
, s7_do_rs
},
748 {"brgel", 0x00002009, 0x3e007fff, 0x080c, x_Rs_x
, s7_do_rs
},
749 {"brltl", 0x00002409, 0x3e007fff, 0x090c, x_Rs_x
, s7_do_rs
},
750 {"brmil", 0x00002809, 0x3e007fff, 0x0a0c, x_Rs_x
, s7_do_rs
},
751 {"brpll", 0x00002c09, 0x3e007fff, 0x0b0c, x_Rs_x
, s7_do_rs
},
752 {"brvsl", 0x00003009, 0x3e007fff, 0x0c0c, x_Rs_x
, s7_do_rs
},
753 {"brvcl", 0x00003409, 0x3e007fff, 0x0d0c, x_Rs_x
, s7_do_rs
},
754 {"brcnzl", 0x00003809, 0x3e007fff, 0x0e0c, x_Rs_x
, s7_do_rs
},
755 {"brl", 0x00003c09, 0x3e007fff, 0x0f0c, x_Rs_x
, s7_do_rs
},
756 {"brcs!", 0x0004, 0x7f0f, 0x00000008, x_Rs
, s7_do16_xrs
},
757 {"brcc!", 0x0104, 0x7f0f, 0x00000408, x_Rs
, s7_do16_xrs
},
758 {"brgtu!", 0x0204, 0x7f0f, 0x00000808, x_Rs
, s7_do16_xrs
},
759 {"brleu!", 0x0304, 0x7f0f, 0x00000c08, x_Rs
, s7_do16_xrs
},
760 {"breq!", 0x0404, 0x7f0f, 0x00001008, x_Rs
, s7_do16_xrs
},
761 {"brne!", 0x0504, 0x7f0f, 0x00001408, x_Rs
, s7_do16_xrs
},
762 {"brgt!", 0x0604, 0x7f0f, 0x00001808, x_Rs
, s7_do16_xrs
},
763 {"brle!", 0x0704, 0x7f0f, 0x00001c08, x_Rs
, s7_do16_xrs
},
764 {"brge!", 0x0804, 0x7f0f, 0x00002008, x_Rs
, s7_do16_xrs
},
765 {"brlt!", 0x0904, 0x7f0f, 0x00002408, x_Rs
, s7_do16_xrs
},
766 {"brmi!", 0x0a04, 0x7f0f, 0x00002808, x_Rs
, s7_do16_xrs
},
767 {"brpl!", 0x0b04, 0x7f0f, 0x00002c08, x_Rs
, s7_do16_xrs
},
768 {"brvs!", 0x0c04, 0x7f0f, 0x00003008, x_Rs
, s7_do16_xrs
},
769 {"brvc!", 0x0d04, 0x7f0f, 0x00003408, x_Rs
, s7_do16_xrs
},
770 {"brcnz!", 0x0e04, 0x7f0f, 0x00003808, x_Rs
, s7_do16_xrs
},
771 {"br!", 0x0f04, 0x7f0f, 0x00003c08, x_Rs
, s7_do16_xrs
},
772 {"brcsl!", 0x000c, 0x7f0f, 0x00000009, x_Rs
, s7_do16_xrs
},
773 {"brccl!", 0x010c, 0x7f0f, 0x00000409, x_Rs
, s7_do16_xrs
},
774 {"brgtul!", 0x020c, 0x7f0f, 0x00000809, x_Rs
, s7_do16_xrs
},
775 {"brleul!", 0x030c, 0x7f0f, 0x00000c09, x_Rs
, s7_do16_xrs
},
776 {"breql!", 0x040c, 0x7f0f, 0x00001009, x_Rs
, s7_do16_xrs
},
777 {"brnel!", 0x050c, 0x7f0f, 0x00001409, x_Rs
, s7_do16_xrs
},
778 {"brgtl!", 0x060c, 0x7f0f, 0x00001809, x_Rs
, s7_do16_xrs
},
779 {"brlel!", 0x070c, 0x7f0f, 0x00001c09, x_Rs
, s7_do16_xrs
},
780 {"brgel!", 0x080c, 0x7f0f, 0x00002009, x_Rs
, s7_do16_xrs
},
781 {"brltl!", 0x090c, 0x7f0f, 0x00002409, x_Rs
, s7_do16_xrs
},
782 {"brmil!", 0x0a0c, 0x7f0f, 0x00002809, x_Rs
, s7_do16_xrs
},
783 {"brpll!", 0x0b0c, 0x7f0f, 0x00002c09, x_Rs
, s7_do16_xrs
},
784 {"brvsl!", 0x0c0c, 0x7f0f, 0x00003009, x_Rs
, s7_do16_xrs
},
785 {"brvcl!", 0x0d0c, 0x7f0f, 0x00003409, x_Rs
, s7_do16_xrs
},
786 {"brcnzl!", 0x0e0c, 0x7f0f, 0x00003809, x_Rs
, s7_do16_xrs
},
787 {"brl!", 0x0f0c, 0x7f0f, 0x00003c09, x_Rs
, s7_do16_xrs
},
788 {"bvs", 0x08003000, 0x3e007c01, 0x4000, PC_DISP19div2
, s7_do_branch
},
789 {"bvc", 0x08003400, 0x3e007c01, 0x4000, PC_DISP19div2
, s7_do_branch
},
790 {"bvsl", 0x08003001, 0x3e007c01, 0x8000, PC_DISP19div2
, s7_do_branch
},
791 {"bvcl", 0x08003401, 0x3e007c01, 0x8000, PC_DISP19div2
, s7_do_branch
},
792 {"bvs!", 0x4c00, 0x7f00, 0x08003000, PC_DISP8div2
, s7_do16_branch
},
793 {"bvc!", 0x4d00, 0x7f00, 0x08003400, PC_DISP8div2
, s7_do16_branch
},
794 {"b!", 0x4f00, 0x7f00, 0x08003c00, PC_DISP8div2
, s7_do16_branch
},
795 {"b", 0x08003c00, 0x3e007c01, 0x4000, PC_DISP19div2
, s7_do_branch
},
796 {"cache", 0x30000000, 0x3ff00000, 0x8000, OP5_rvalueRs_SI15
, s7_do_cache
},
797 {"ceinst", 0x38000000, 0x3e000000, 0x8000, I5_Rs_Rs_I5_OP5
, s7_do_ceinst
},
798 {"clz", 0x3800000d, 0x3e007fff, 0x8000, Rd_Rs_x
, s7_do_rdrs
},
799 {"cmpteq.c", 0x00000019, 0x3ff003ff, 0x8000, x_Rs_Rs
, s7_do_rsrs
},
800 {"cmptmi.c", 0x00100019, 0x3ff003ff, 0x8000, x_Rs_Rs
, s7_do_rsrs
},
801 {"cmp.c", 0x00300019, 0x3ff003ff, 0x2003, x_Rs_Rs
, s7_do_rsrs
},
802 {"cmpzteq.c", 0x0000001b, 0x3ff07fff, 0x8000, x_Rs_x
, s7_do_rs
},
803 {"cmpztmi.c", 0x0010001b, 0x3ff07fff, 0x8000, x_Rs_x
, s7_do_rs
},
804 {"cmpz.c", 0x0030001b, 0x3ff07fff, 0x8000, x_Rs_x
, s7_do_rs
},
805 {"cmpi.c", 0x02040001, 0x3e0e0001, 0x8000, Rd_SI16
, s7_do_rdsi16
},
806 {"cmp!", 0x2003, 0x700f, 0x00300019, Rd_Rs
, s7_do16_rdrs
},
807 {"cop1", 0x0c00000c, 0x3e00001f, 0x8000, Rd_Rs_Rs_imm
, s7_do_crdcrscrsimm5
},
808 {"cop2", 0x0c000014, 0x3e00001f, 0x8000, Rd_Rs_Rs_imm
, s7_do_crdcrscrsimm5
},
809 {"cop3", 0x0c00001c, 0x3e00001f, 0x8000, Rd_Rs_Rs_imm
, s7_do_crdcrscrsimm5
},
810 {"drte", 0x0c0000a4, 0x3e0003ff, 0x8000, NO_OPD
, s7_do_empty
},
811 {"extsb", 0x00000058, 0x3e0003ff, 0x8000, Rd_Rs_x
, s7_do_rdrs
},
812 {"extsb.c", 0x00000059, 0x3e0003ff, 0x8000, Rd_Rs_x
, s7_do_rdrs
},
813 {"extsh", 0x0000005a, 0x3e0003ff, 0x8000, Rd_Rs_x
, s7_do_rdrs
},
814 {"extsh.c", 0x0000005b, 0x3e0003ff, 0x8000, Rd_Rs_x
, s7_do_rdrs
},
815 {"extzb", 0x0000005c, 0x3e0003ff, 0x8000, Rd_Rs_x
, s7_do_rdrs
},
816 {"extzb.c", 0x0000005d, 0x3e0003ff, 0x8000, Rd_Rs_x
, s7_do_rdrs
},
817 {"extzh", 0x0000005e, 0x3e0003ff, 0x8000, Rd_Rs_x
, s7_do_rdrs
},
818 {"extzh.c", 0x0000005f, 0x3e0003ff, 0x8000, Rd_Rs_x
, s7_do_rdrs
},
819 {"jl", 0x04000001, 0x3e000001, 0x8000, PC_DISP24div2
, s7_do_jump
},
820 {"jl!", 0x3001, 0x7001, 0x04000001, PC_DISP11div2
, s7_do16_jump
},
821 {"j!", 0x3000, 0x7001, 0x04000000, PC_DISP11div2
, s7_do16_jump
},
822 {"j", 0x04000000, 0x3e000001, 0x8000, PC_DISP24div2
, s7_do_jump
},
823 {"lbu!", 0x200b, 0x0000700f, 0x2c000000, Rd_rvalueRs
, s7_do16_ldst_insn
},
824 {"lbup!", 0x7003, 0x7007, 0x2c000000, Rd_rvalueBP_I5
, s7_do16_ldst_imm_insn
},
825 {"alw", 0x0000000c, 0x3e0003ff, 0x8000, Rd_rvalue32Rs
, s7_do_ldst_atomic
},
826 {"lcb", 0x00000060, 0x3e0003ff, 0x8000, x_rvalueRs_post4
, s7_do_ldst_unalign
},
827 {"lcw", 0x00000062, 0x3e0003ff, 0x8000, Rd_rvalueRs_post4
, s7_do_ldst_unalign
},
828 {"lce", 0x00000066, 0x3e0003ff, 0x8000, Rd_rvalueRs_post4
, s7_do_ldst_unalign
},
829 {"ldc1", 0x0c00000a, 0x3e00001f, 0x8000, Rd_rvalueRs_SI10
, s7_do_ldst_cop
},
830 {"ldc2", 0x0c000012, 0x3e00001f, 0x8000, Rd_rvalueRs_SI10
, s7_do_ldst_cop
},
831 {"ldc3", 0x0c00001a, 0x3e00001f, 0x8000, Rd_rvalueRs_SI10
, s7_do_ldst_cop
},
832 {"lh!", 0x2009, 0x700f, 0x22000000, Rd_rvalueRs
, s7_do16_ldst_insn
},
833 {"lhp!", 0x7001, 0x7007, 0x22000000, Rd_rvalueBP_I5
, s7_do16_ldst_imm_insn
},
834 {"ldi", 0x020c0000, 0x3e0e0000, 0x5000, Rd_SI16
, s7_do_rdsi16
},
835 {"ldis", 0x0a0c0000, 0x3e0e0000, 0x8000, Rd_I16
, s7_do_rdi16
},
836 {"ldiu!", 0x5000, 0x7000, 0x020c0000, Rd_I8
, s7_do16_ldst_imm_insn
},
837 {"lw!", 0x2008, 0x700f, 0x20000000, Rd_rvalueRs
, s7_do16_ldst_insn
},
838 {"lwp!", 0x7000, 0x7007, 0x20000000, Rd_rvalueBP_I5
, s7_do16_ldst_imm_insn
},
839 {"mfcel", 0x00000448, 0x3e007fff, 0x8000, Rd_x_x
, s7_do_rd
},
840 {"mfcel!", 0x1001, 0x7f0f, 0x00000448, x_Rs
, s7_do16_rs
},
841 {"mad", 0x38000000, 0x3ff003ff, 0x8000, x_Rs_Rs
, s7_do_rsrs
},
842 {"mad.f!", 0x1004, 0x700f, 0x38000080, Rd_Rs
, s7_do16_rdrs
},
843 {"madh", 0x38000203, 0x3ff003ff, 0x8000, x_Rs_Rs
, s7_do_rsrs
},
844 {"madh.fs", 0x380002c3, 0x3ff003ff, 0x8000, x_Rs_Rs
, s7_do_rsrs
},
845 {"madh.fs!", 0x100b, 0x700f, 0x380002c3, Rd_Rs
, s7_do16_rdrs
},
846 {"madl", 0x38000002, 0x3ff003ff, 0x8000, x_Rs_Rs
, s7_do_rsrs
},
847 {"madl.fs", 0x380000c2, 0x3ff003ff, 0x8000, x_Rs_Rs
, s7_do_rsrs
},
848 {"madl.fs!", 0x100a, 0x700f, 0x380000c2, Rd_Rs
, s7_do16_rdrs
},
849 {"madu", 0x38000020, 0x3ff003ff, 0x8000, x_Rs_Rs
, s7_do_rsrs
},
850 {"madu!", 0x1005, 0x700f, 0x38000020, Rd_Rs
, s7_do16_rdrs
},
851 {"mad.f", 0x38000080, 0x3ff003ff, 0x8000, x_Rs_Rs
, s7_do_rsrs
},
852 {"max", 0x38000007, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s7_do_rdrsrs
},
853 {"mazh", 0x38000303, 0x3ff003ff, 0x8000, x_Rs_Rs
, s7_do_rsrs
},
854 {"mazh.f", 0x38000383, 0x3ff003ff, 0x8000, x_Rs_Rs
, s7_do_rsrs
},
855 {"mazh.f!", 0x1009, 0x700f, 0x38000383, Rd_Rs
, s7_do16_rdrs
},
856 {"mazl", 0x38000102, 0x3ff003ff, 0x8000, x_Rs_Rs
, s7_do_rsrs
},
857 {"mazl.f", 0x38000182, 0x3ff003ff, 0x8000, x_Rs_Rs
, s7_do_rsrs
},
858 {"mazl.f!", 0x1008, 0x700f, 0x38000182, Rd_Rs
, s7_do16_rdrs
},
859 {"mfceh", 0x00000848, 0x3e007fff, 0x8000, Rd_x_x
, s7_do_rd
},
860 {"mfceh!", 0x1101, 0x7f0f, 0x00000848, x_Rs
, s7_do16_rs
},
861 {"mfcehl", 0x00000c48, 0x3e007fff, 0x8000, Rd_Rs_x
, s7_do_rdrs
},
862 {"mfsr", 0x00000050, 0x3e0003ff, 0x8000, Rd_x_I5
, s7_do_rdsrs
},
863 {"mfcr", 0x0c000001, 0x3e00001f, 0x8000, Rd_Rs_x
, s7_do_rdcrs
},
864 {"mfc1", 0x0c000009, 0x3e00001f, 0x8000, Rd_Rs_x
, s7_do_rdcrs
},
865 {"mfc2", 0x0c000011, 0x3e00001f, 0x8000, Rd_Rs_x
, s7_do_rdcrs
},
866 {"mfc3", 0x0c000019, 0x3e00001f, 0x8000, Rd_Rs_x
, s7_do_rdcrs
},
867 {"mfcc1", 0x0c00000f, 0x3e00001f, 0x8000, Rd_Rs_x
, s7_do_rdcrs
},
868 {"mfcc2", 0x0c000017, 0x3e00001f, 0x8000, Rd_Rs_x
, s7_do_rdcrs
},
869 {"mfcc3", 0x0c00001f, 0x3e00001f, 0x8000, Rd_Rs_x
, s7_do_rdcrs
},
870 {"mhfl!", 0x0002, 0x700f, 0x00003c56, Rd_LowRs
, s7_do16_hrdrs
},
871 {"min", 0x38000006, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s7_do_rdrsrs
},
872 {"mlfh!", 0x0001, 0x700f, 0x00003c56, Rd_HighRs
, s7_do16_rdhrs
},
873 {"msb", 0x38000001, 0x3ff003ff, 0x8000, x_Rs_Rs
, s7_do_rsrs
},
874 {"msb.f!", 0x1006, 0x700f, 0x38000081, Rd_Rs
, s7_do16_rdrs
},
875 {"msbh", 0x38000205, 0x3ff003ff, 0x8000, x_Rs_Rs
, s7_do_rsrs
},
876 {"msbh.fs", 0x380002c5, 0x3ff003ff, 0x8000, x_Rs_Rs
, s7_do_rsrs
},
877 {"msbh.fs!", 0x100f, 0x700f, 0x380002c5, Rd_Rs
, s7_do16_rdrs
},
878 {"msbl", 0x38000004, 0x3ff003ff, 0x8000, x_Rs_Rs
, s7_do_rsrs
},
879 {"msbl.fs", 0x380000c4, 0x3ff003ff, 0x8000, x_Rs_Rs
, s7_do_rsrs
},
880 {"msbl.fs!", 0x100e, 0x700f, 0x380000c4, Rd_Rs
, s7_do16_rdrs
},
881 {"msbu", 0x38000021, 0x3ff003ff, 0x8000, x_Rs_Rs
, s7_do_rsrs
},
882 {"msbu!", 0x1007, 0x700f, 0x38000021, Rd_Rs
, s7_do16_rdrs
},
883 {"msb.f", 0x38000081, 0x3ff003ff, 0x8000, x_Rs_Rs
, s7_do_rsrs
},
884 {"mszh", 0x38000305, 0x3ff003ff, 0x8000, x_Rs_Rs
, s7_do_rsrs
},
885 {"mszh.f", 0x38000385, 0x3ff003ff, 0x8000, x_Rs_Rs
, s7_do_rsrs
},
886 {"mszh.f!", 0x100d, 0x700f, 0x38000385, Rd_Rs
, s7_do16_rdrs
},
887 {"mszl", 0x38000104, 0x3ff003ff, 0x8000, x_Rs_Rs
, s7_do_rsrs
},
888 {"mszl.f", 0x38000184, 0x3ff003ff, 0x8000, x_Rs_Rs
, s7_do_rsrs
},
889 {"mszl.f!", 0x100c, 0x700f, 0x38000184, Rd_Rs
, s7_do16_rdrs
},
890 {"mtcel!", 0x1000, 0x7f0f, 0x0000044a, x_Rs
, s7_do16_rs
},
891 {"mtcel", 0x0000044a, 0x3e007fff, 0x8000, Rd_x_x
, s7_do_rd
},
892 {"mtceh", 0x0000084a, 0x3e007fff, 0x8000, Rd_x_x
, s7_do_rd
},
893 {"mtceh!", 0x1100, 0x7f0f, 0x0000084a, x_Rs
, s7_do16_rs
},
894 {"mtcehl", 0x00000c4a, 0x3e007fff, 0x8000, Rd_Rs_x
, s7_do_rdrs
},
895 {"mtsr", 0x00000052, 0x3e0003ff, 0x8000, x_Rs_I5
, s7_do_rdsrs
},
896 {"mtcr", 0x0c000000, 0x3e00001f, 0x8000, Rd_Rs_x
, s7_do_rdcrs
},
897 {"mtc1", 0x0c000008, 0x3e00001f, 0x8000, Rd_Rs_x
, s7_do_rdcrs
},
898 {"mtc2", 0x0c000010, 0x3e00001f, 0x8000, Rd_Rs_x
, s7_do_rdcrs
},
899 {"mtc3", 0x0c000018, 0x3e00001f, 0x8000, Rd_Rs_x
, s7_do_rdcrs
},
900 {"mtcc1", 0x0c00000e, 0x3e00001f, 0x8000, Rd_Rs_x
, s7_do_rdcrs
},
901 {"mtcc2", 0x0c000016, 0x3e00001f, 0x8000, Rd_Rs_x
, s7_do_rdcrs
},
902 {"mtcc3", 0x0c00001e, 0x3e00001f, 0x8000, Rd_Rs_x
, s7_do_rdcrs
},
903 {"mul.f!", 0x1002, 0x700f, 0x00000041, Rd_Rs
, s7_do16_rdrs
},
904 {"mulu!", 0x1003, 0x700f, 0x00000042, Rd_Rs
, s7_do16_rdrs
},
905 {"mvcs", 0x00000056, 0x3e007fff, 0x8000, Rd_Rs_x
, s7_do_rdrs
},
906 {"mvcc", 0x00000456, 0x3e007fff, 0x8000, Rd_Rs_x
, s7_do_rdrs
},
907 {"mvgtu", 0x00000856, 0x3e007fff, 0x8000, Rd_Rs_x
, s7_do_rdrs
},
908 {"mvleu", 0x00000c56, 0x3e007fff, 0x8000, Rd_Rs_x
, s7_do_rdrs
},
909 {"mveq", 0x00001056, 0x3e007fff, 0x8000, Rd_Rs_x
, s7_do_rdrs
},
910 {"mvne", 0x00001456, 0x3e007fff, 0x8000, Rd_Rs_x
, s7_do_rdrs
},
911 {"mvgt", 0x00001856, 0x3e007fff, 0x8000, Rd_Rs_x
, s7_do_rdrs
},
912 {"mvle", 0x00001c56, 0x3e007fff, 0x8000, Rd_Rs_x
, s7_do_rdrs
},
913 {"mvge", 0x00002056, 0x3e007fff, 0x8000, Rd_Rs_x
, s7_do_rdrs
},
914 {"mvlt", 0x00002456, 0x3e007fff, 0x8000, Rd_Rs_x
, s7_do_rdrs
},
915 {"mvmi", 0x00002856, 0x3e007fff, 0x8000, Rd_Rs_x
, s7_do_rdrs
},
916 {"mvpl", 0x00002c56, 0x3e007fff, 0x8000, Rd_Rs_x
, s7_do_rdrs
},
917 {"mvvs", 0x00003056, 0x3e007fff, 0x8000, Rd_Rs_x
, s7_do_rdrs
},
918 {"mvvc", 0x00003456, 0x3e007fff, 0x8000, Rd_Rs_x
, s7_do_rdrs
},
919 {"mv", 0x00003c56, 0x3e007fff, 0x0003, Rd_Rs_x
, s7_do_rdrs
},
920 {"mv!", 0x0003, 0x700f, 0x00003c56, Rd_Rs
, s7_do16_mv_rdrs
},
921 {"neg", 0x0000001e, 0x3e0003ff, 0x8000, Rd_x_Rs
, s7_do_rdxrs
},
922 {"neg.c", 0x0000001f, 0x3e0003ff, 0x2002, Rd_x_Rs
, s7_do_rdxrs
},
923 {"neg!", 0x2002, 0x700f, 0x0000001f, Rd_Rs
, s7_do16_rdrs
},
924 {"nop", 0x00000000, 0x3e0003ff, 0x0000, NO_OPD
, s7_do_empty
},
925 {"not", 0x00000024, 0x3e0003ff, 0x8000, Rd_Rs_x
, s7_do_rdrs
},
926 {"not.c", 0x00000025, 0x3e0003ff, 0x2006, Rd_Rs_x
, s7_do_rdrs
},
927 {"nop!", 0x0000, 0x700f, 0x00000000, NO16_OPD
, s7_do_empty
},
928 {"not!", 0x2006, 0x700f, 0x00000025, Rd_Rs
, s7_do16_rdrs
},
929 {"or", 0x00000022, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s7_do_rdrsrs
},
930 {"or.c", 0x00000023, 0x3e0003ff, 0x2005, Rd_Rs_Rs
, s7_do_rdrsrs
},
931 {"ori", 0x020a0000, 0x3e0e0001, 0x8000, Rd_I16
, s7_do_rdi16
},
932 {"ori.c", 0x020a0001, 0x3e0e0001, 0x8000, Rd_I16
, s7_do_rdi16
},
933 {"oris", 0x0a0a0000, 0x3e0e0001, 0x8000, Rd_I16
, s7_do_rdi16
},
934 {"oris.c", 0x0a0a0001, 0x3e0e0001, 0x8000, Rd_I16
, s7_do_rdi16
},
935 {"orri", 0x1a000000, 0x3e000001, 0x8000, Rd_Rs_I14
, s7_do_rdrsi14
},
936 {"orri.c", 0x1a000001, 0x3e000001, 0x8000, Rd_Rs_I14
, s7_do_rdrsi14
},
937 {"or!", 0x2005, 0x700f, 0x00000023, Rd_Rs
, s7_do16_rdrs
},
938 {"pflush", 0x0000000a, 0x3e0003ff, 0x8000, NO_OPD
, s7_do_empty
},
939 {"pop!", 0x200a, 0x700f, 0x0e000000, Rd_rvalueRs
, s7_do16_push_pop
},
940 {"push!", 0x200e, 0x700f, 0x06000004, Rd_lvalueRs
, s7_do16_push_pop
},
941 {"ror", 0x00000038, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s7_do_rdrsrs
},
942 {"ror.c", 0x00000039, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s7_do_rdrsrs
},
943 {"rorc.c", 0x0000003b, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s7_do_rdrsrs
},
944 {"rol", 0x0000003c, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s7_do_rdrsrs
},
945 {"rol.c", 0x0000003d, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s7_do_rdrsrs
},
946 {"rolc.c", 0x0000003f, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s7_do_rdrsrs
},
947 {"rori", 0x00000078, 0x3e0003ff, 0x8000, Rd_Rs_I5
, s7_do_rdrsi5
},
948 {"rori.c", 0x00000079, 0x3e0003ff, 0x8000, Rd_Rs_I5
, s7_do_rdrsi5
},
949 {"roric.c", 0x0000007b, 0x3e0003ff, 0x8000, Rd_Rs_I5
, s7_do_rdrsi5
},
950 {"roli", 0x0000007c, 0x3e0003ff, 0x8000, Rd_Rs_I5
, s7_do_rdrsi5
},
951 {"roli.c", 0x0000007d, 0x3e0003ff, 0x8000, Rd_Rs_I5
, s7_do_rdrsi5
},
952 {"rolic.c", 0x0000007f, 0x3e0003ff, 0x8000, Rd_Rs_I5
, s7_do_rdrsi5
},
953 {"rte", 0x0c000084, 0x3e0003ff, 0x8000, NO_OPD
, s7_do_empty
},
954 {"sb!", 0x200f, 0x700f, 0x2e000000, Rd_lvalueRs
, s7_do16_ldst_insn
},
955 {"sbp!", 0x7007, 0x7007, 0x2e000000, Rd_lvalueBP_I5
, s7_do16_ldst_imm_insn
},
956 {"asw", 0x0000000e, 0x3e0003ff, 0x8000, Rd_lvalue32Rs
, s7_do_ldst_atomic
},
957 {"scb", 0x00000068, 0x3e0003ff, 0x8000, Rd_lvalueRs_post4
, s7_do_ldst_unalign
},
958 {"scw", 0x0000006a, 0x3e0003ff, 0x8000, Rd_lvalueRs_post4
, s7_do_ldst_unalign
},
959 {"sce", 0x0000006e, 0x3e0003ff, 0x8000, x_lvalueRs_post4
, s7_do_ldst_unalign
},
960 {"sdbbp", 0x00000006, 0x3e0003ff, 0x6002, x_I5_x
, s7_do_xi5x
},
961 {"sdbbp!", 0x6002, 0x7007, 0x00000006, Rd_I5
, s7_do16_xi5
},
962 {"sh!", 0x200d, 0x700f, 0x2a000000, Rd_lvalueRs
, s7_do16_ldst_insn
},
963 {"shp!", 0x7005, 0x7007, 0x2a000000, Rd_lvalueBP_I5
, s7_do16_ldst_imm_insn
},
964 {"sleep", 0x0c0000c4, 0x3e0003ff, 0x8000, NO_OPD
, s7_do_empty
},
965 {"sll", 0x00000030, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s7_do_rdrsrs
},
966 {"sll.c", 0x00000031, 0x3e0003ff, 0x0008, Rd_Rs_Rs
, s7_do_rdrsrs
},
967 {"sll.s", 0x3800004e, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s7_do_rdrsrs
},
968 {"slli", 0x00000070, 0x3e0003ff, 0x8000, Rd_Rs_I5
, s7_do_rdrsi5
},
969 {"slli.c", 0x00000071, 0x3e0003ff, 0x6001, Rd_Rs_I5
, s7_do_rdrsi5
},
970 {"sll!", 0x0008, 0x700f, 0x00000031, Rd_Rs
, s7_do16_rdrs
},
971 {"slli!", 0x6001, 0x7007, 0x00000071, Rd_I5
, s7_do16_rdi5
},
972 {"srl", 0x00000034, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s7_do_rdrsrs
},
973 {"srl.c", 0x00000035, 0x3e0003ff, 0x000a, Rd_Rs_Rs
, s7_do_rdrsrs
},
974 {"sra", 0x00000036, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s7_do_rdrsrs
},
975 {"sra.c", 0x00000037, 0x3e0003ff, 0x000b, Rd_Rs_Rs
, s7_do_rdrsrs
},
976 {"srli", 0x00000074, 0x3e0003ff, 0x8000, Rd_Rs_I5
, s7_do_rdrsi5
},
977 {"srli.c", 0x00000075, 0x3e0003ff, 0x6003, Rd_Rs_I5
, s7_do_rdrsi5
},
978 {"srai", 0x00000076, 0x3e0003ff, 0x8000, Rd_Rs_I5
, s7_do_rdrsi5
},
979 {"srai.c", 0x00000077, 0x3e0003ff, 0x8000, Rd_Rs_I5
, s7_do_rdrsi5
},
980 {"srl!", 0x000a, 0x700f, 0x00000035, Rd_Rs
, s7_do16_rdrs
},
981 {"sra!", 0x000b, 0x700f, 0x00000037, Rd_Rs
, s7_do16_rdrs
},
982 {"srli!", 0x6003, 0x7007, 0x00000075, Rd_Rs
, s7_do16_rdi5
},
983 {"stc1", 0x0c00000b, 0x3e00001f, 0x8000, Rd_lvalueRs_SI10
, s7_do_ldst_cop
},
984 {"stc2", 0x0c000013, 0x3e00001f, 0x8000, Rd_lvalueRs_SI10
, s7_do_ldst_cop
},
985 {"stc3", 0x0c00001b, 0x3e00001f, 0x8000, Rd_lvalueRs_SI10
, s7_do_ldst_cop
},
986 {"sub", 0x00000014, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s7_do_rdrsrs
},
987 {"sub.c", 0x00000015, 0x3e0003ff, 0x2001, Rd_Rs_Rs
, s7_do_rdrsrs
},
988 {"sub.s", 0x38000049, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s7_do_rdrsrs
},
989 {"subc", 0x00000016, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s7_do_rdrsrs
},
990 {"subc.c", 0x00000017, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s7_do_rdrsrs
},
991 {"sub!", 0x2001, 0x700f, 0x00000015, Rd_Rs
, s7_do16_rdrs
},
992 {"subei!", 0x6080, 0x7087, 0x02000001, Rd_I4
, s7_do16_rdi4
},
993 {"sw!", 0x200c, 0x700f, 0x28000000, Rd_lvalueRs
, s7_do16_ldst_insn
},
994 {"swp!", 0x7004, 0x7007, 0x28000000, Rd_lvalueBP_I5
, s7_do16_ldst_imm_insn
},
995 {"syscall", 0x00000002, 0x3e0003ff, 0x8000, I15
, s7_do_i15
},
996 {"tcs", 0x00000054, 0x3e007fff, 0x0005, NO_OPD
, s7_do_empty
},
997 {"tcc", 0x00000454, 0x3e007fff, 0x0105, NO_OPD
, s7_do_empty
},
998 {"tcnz", 0x00003854, 0x3e007fff, 0x0e05, NO_OPD
, s7_do_empty
},
999 {"tcs!", 0x0005, 0x7f0f, 0x00000054, NO16_OPD
, s7_do_empty
},
1000 {"tcc!", 0x0105, 0x7f0f, 0x00000454, NO16_OPD
, s7_do_empty
},
1001 {"tcnz!", 0x0e05, 0x7f0f, 0x00003854, NO16_OPD
, s7_do_empty
},
1002 {"teq", 0x00001054, 0x3e007fff, 0x0405, NO_OPD
, s7_do_empty
},
1003 {"teq!", 0x0405, 0x7f0f, 0x00001054, NO16_OPD
, s7_do_empty
},
1004 {"tgtu", 0x00000854, 0x3e007fff, 0x0205, NO_OPD
, s7_do_empty
},
1005 {"tgt", 0x00001854, 0x3e007fff, 0x0605, NO_OPD
, s7_do_empty
},
1006 {"tge", 0x00002054, 0x3e007fff, 0x0805, NO_OPD
, s7_do_empty
},
1007 {"tgtu!", 0x0205, 0x7f0f, 0x00000854, NO16_OPD
, s7_do_empty
},
1008 {"tgt!", 0x0605, 0x7f0f, 0x00001854, NO16_OPD
, s7_do_empty
},
1009 {"tge!", 0x0805, 0x7f0f, 0x00002054, NO16_OPD
, s7_do_empty
},
1010 {"tleu", 0x00000c54, 0x3e007fff, 0x0305, NO_OPD
, s7_do_empty
},
1011 {"tle", 0x00001c54, 0x3e007fff, 0x0705, NO_OPD
, s7_do_empty
},
1012 {"tlt", 0x00002454, 0x3e007fff, 0x0905, NO_OPD
, s7_do_empty
},
1013 {"stlb", 0x0c000004, 0x3e0003ff, 0x8000, NO_OPD
, s7_do_empty
},
1014 {"mftlb", 0x0c000024, 0x3e0003ff, 0x8000, NO_OPD
, s7_do_empty
},
1015 {"mtptlb", 0x0c000044, 0x3e0003ff, 0x8000, NO_OPD
, s7_do_empty
},
1016 {"mtrtlb", 0x0c000064, 0x3e0003ff, 0x8000, NO_OPD
, s7_do_empty
},
1017 {"tleu!", 0x0305, 0x7f0f, 0x00000c54, NO16_OPD
, s7_do_empty
},
1018 {"tle!", 0x0705, 0x7f0f, 0x00001c54, NO16_OPD
, s7_do_empty
},
1019 {"tlt!", 0x0905, 0x7f0f, 0x00002454, NO16_OPD
, s7_do_empty
},
1020 {"tmi", 0x00002854, 0x3e007fff, 0x0a05, NO_OPD
, s7_do_empty
},
1021 {"tmi!", 0x0a05, 0x7f0f, 0x00002854, NO16_OPD
, s7_do_empty
},
1022 {"tne", 0x00001454, 0x3e007fff, 0x0505, NO_OPD
, s7_do_empty
},
1023 {"tne!", 0x0505, 0x7f0f, 0x00001454, NO16_OPD
, s7_do_empty
},
1024 {"tpl", 0x00002c54, 0x3e007fff, 0x0b05, NO_OPD
, s7_do_empty
},
1025 {"tpl!", 0x0b05, 0x7f0f, 0x00002c54, NO16_OPD
, s7_do_empty
},
1026 {"trapcs", 0x00000004, 0x3e007fff, 0x8000, x_I5_x
, s7_do_xi5x
},
1027 {"trapcc", 0x00000404, 0x3e007fff, 0x8000, x_I5_x
, s7_do_xi5x
},
1028 {"trapgtu", 0x00000804, 0x3e007fff, 0x8000, x_I5_x
, s7_do_xi5x
},
1029 {"trapleu", 0x00000c04, 0x3e007fff, 0x8000, x_I5_x
, s7_do_xi5x
},
1030 {"trapeq", 0x00001004, 0x3e007fff, 0x8000, x_I5_x
, s7_do_xi5x
},
1031 {"trapne", 0x00001404, 0x3e007fff, 0x8000, x_I5_x
, s7_do_xi5x
},
1032 {"trapgt", 0x00001804, 0x3e007fff, 0x8000, x_I5_x
, s7_do_xi5x
},
1033 {"traple", 0x00001c04, 0x3e007fff, 0x8000, x_I5_x
, s7_do_xi5x
},
1034 {"trapge", 0x00002004, 0x3e007fff, 0x8000, x_I5_x
, s7_do_xi5x
},
1035 {"traplt", 0x00002404, 0x3e007fff, 0x8000, x_I5_x
, s7_do_xi5x
},
1036 {"trapmi", 0x00002804, 0x3e007fff, 0x8000, x_I5_x
, s7_do_xi5x
},
1037 {"trappl", 0x00002c04, 0x3e007fff, 0x8000, x_I5_x
, s7_do_xi5x
},
1038 {"trapvs", 0x00003004, 0x3e007fff, 0x8000, x_I5_x
, s7_do_xi5x
},
1039 {"trapvc", 0x00003404, 0x3e007fff, 0x8000, x_I5_x
, s7_do_xi5x
},
1040 {"trap", 0x00003c04, 0x3e007fff, 0x8000, x_I5_x
, s7_do_xi5x
},
1041 {"tset", 0x00003c54, 0x3e007fff, 0x0f05, NO_OPD
, s7_do_empty
},
1042 {"tset!", 0x0f05, 0x00007f0f, 0x00003c54, NO16_OPD
, s7_do_empty
},
1043 {"tvs", 0x00003054, 0x3e007fff, 0x0c05, NO_OPD
, s7_do_empty
},
1044 {"tvc", 0x00003454, 0x3e007fff, 0x0d05, NO_OPD
, s7_do_empty
},
1045 {"tvs!", 0x0c05, 0x7f0f, 0x00003054, NO16_OPD
, s7_do_empty
},
1046 {"tvc!", 0x0d05, 0x7f0f, 0x00003454, NO16_OPD
, s7_do_empty
},
1047 {"xor", 0x00000026, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s7_do_rdrsrs
},
1048 {"xor.c", 0x00000027, 0x3e0003ff, 0x2007, Rd_Rs_Rs
, s7_do_rdrsrs
},
1049 {"xor!", 0x2007, 0x700f, 0x00000027, Rd_Rs
, s7_do16_rdrs
},
1050 /* Macro instruction. */
1051 {"li", 0x020c0000, 0x3e0e0000, 0x8000, Insn_Type_SYN
, s7_do_macro_li_rdi32
},
1052 /* la reg, imm32 -->(1) ldi reg, simm16
1053 (2) ldis reg, %HI(imm32)
1056 la reg, symbol -->(1) lis reg, %HI(imm32)
1057 ori reg, %LO(imm32) */
1058 {"la", 0x020c0000, 0x3e0e0000, 0x8000, Insn_Type_SYN
, s7_do_macro_la_rdi32
},
1059 {"div", 0x00000044, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s7_do_macro_mul_rdrsrs
},
1060 {"divu", 0x00000046, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s7_do_macro_mul_rdrsrs
},
1061 {"rem", 0x00000044, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s7_do_macro_mul_rdrsrs
},
1062 {"remu", 0x00000046, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s7_do_macro_mul_rdrsrs
},
1063 {"mul", 0x00000040, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s7_do_macro_mul_rdrsrs
},
1064 {"mulu", 0x00000042, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s7_do_macro_mul_rdrsrs
},
1065 {"maz", 0x00000040, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s7_do_macro_mul_rdrsrs
},
1066 {"mazu", 0x00000042, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s7_do_macro_mul_rdrsrs
},
1067 {"mul.f", 0x00000041, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s7_do_macro_mul_rdrsrs
},
1068 {"maz.f", 0x00000041, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s7_do_macro_mul_rdrsrs
},
1069 {"lb", INSN_LB
, 0x00000000, 0x8000, Insn_Type_SYN
, s7_do_macro_ldst_label
},
1070 {"lbu", INSN_LBU
, 0x00000000, 0x200b, Insn_Type_SYN
, s7_do_macro_ldst_label
},
1071 {"lh", INSN_LH
, 0x00000000, 0x2009, Insn_Type_SYN
, s7_do_macro_ldst_label
},
1072 {"lhu", INSN_LHU
, 0x00000000, 0x8000, Insn_Type_SYN
, s7_do_macro_ldst_label
},
1073 {"lw", INSN_LW
, 0x00000000, 0x2008, Insn_Type_SYN
, s7_do_macro_ldst_label
},
1074 {"sb", INSN_SB
, 0x00000000, 0x200f, Insn_Type_SYN
, s7_do_macro_ldst_label
},
1075 {"sh", INSN_SH
, 0x00000000, 0x200d, Insn_Type_SYN
, s7_do_macro_ldst_label
},
1076 {"sw", INSN_SW
, 0x00000000, 0x200c, Insn_Type_SYN
, s7_do_macro_ldst_label
},
1077 /* Assembler use internal. */
1078 {"ld_i32hi", 0x0a0c0000, 0x3e0e0000, 0x8000, Insn_internal
, s7_do_macro_rdi32hi
},
1079 {"ld_i32lo", 0x020a0000, 0x3e0e0001, 0x8000, Insn_internal
, s7_do_macro_rdi32lo
},
1080 {"ldis_pic", 0x0a0c0000, 0x3e0e0000, 0x5000, Insn_internal
, s7_do_rdi16_pic
},
1081 {"addi_s_pic",0x02000000, 0x3e0e0001, 0x8000, Insn_internal
, s7_do_addi_s_pic
},
1082 {"addi_u_pic",0x02000000, 0x3e0e0001, 0x8000, Insn_internal
, s7_do_addi_u_pic
},
1083 {"lw_pic", 0x20000000, 0x3e000000, 0x8000, Insn_internal
, s7_do_lw_pic
},
1086 #define s7_SCORE5_PIPELINE 5
1087 #define s7_SCORE7_PIPELINE 7
1089 static int s7_university_version
= 0;
1090 static int s7_vector_size
= s7_SCORE7_PIPELINE
;
1091 static struct s7_score_it s7_dependency_vector
[s7_SCORE7_PIPELINE
];
1093 static int s7_score7d
= 1;
1098 s7_end_of_line (char *str
)
1100 int retval
= s7_SUCCESS
;
1102 s7_skip_whitespace (str
);
1105 retval
= (int) s7_FAIL
;
1108 s7_inst
.error
= s7_BAD_GARBAGE
;
1115 s7_score_reg_parse (char **ccp
, struct hash_control
*htab
)
1120 struct s7_reg_entry
*reg
;
1123 if (!ISALPHA (*p
) || !is_name_beginner (*p
))
1124 return (int) s7_FAIL
;
1128 while (ISALPHA (c
) || ISDIGIT (c
) || c
== '_')
1132 reg
= (struct s7_reg_entry
*) hash_find (htab
, start
);
1140 return (int) s7_FAIL
;
1143 /* If shift <= 0, only return reg. */
1145 s7_reg_required_here (char **str
, int shift
, enum s7_score_reg_type reg_type
)
1147 static char buff
[s7_MAX_LITERAL_POOL_SIZE
];
1148 int reg
= (int) s7_FAIL
;
1151 if ((reg
= s7_score_reg_parse (str
, s7_all_reg_maps
[reg_type
].htab
)) != (int) s7_FAIL
)
1153 if (reg_type
== s7_REG_TYPE_SCORE
)
1155 if ((reg
== 1) && (s7_nor1
== 1) && (s7_inst
.bwarn
== 0))
1157 as_warn (_("Using temp register(r1)"));
1163 if (reg_type
== s7_REG_TYPE_SCORE_CR
)
1164 strcpy (s7_inst
.reg
, s7_score_crn_table
[reg
].name
);
1165 else if (reg_type
== s7_REG_TYPE_SCORE_SR
)
1166 strcpy (s7_inst
.reg
, s7_score_srn_table
[reg
].name
);
1168 strcpy (s7_inst
.reg
, "");
1170 s7_inst
.instruction
|= reg
<< shift
;
1176 sprintf (buff
, _("register expected, not '%.100s'"), start
);
1177 s7_inst
.error
= buff
;
1184 s7_skip_past_comma (char **str
)
1190 while ((c
= *p
) == ' ' || c
== ',')
1193 if (c
== ',' && comma
++)
1195 s7_inst
.error
= s7_BAD_SKIP_COMMA
;
1196 return (int) s7_FAIL
;
1200 if ((c
== '\0') || (comma
== 0))
1202 s7_inst
.error
= s7_BAD_SKIP_COMMA
;
1203 return (int) s7_FAIL
;
1207 return comma
? s7_SUCCESS
: (int) s7_FAIL
;
1211 s7_do_rdrsrs (char *str
)
1213 s7_skip_whitespace (str
);
1215 if (s7_reg_required_here (&str
, 20, s7_REG_TYPE_SCORE
) == (int) s7_FAIL
1216 || s7_skip_past_comma (&str
) == (int) s7_FAIL
1217 || s7_reg_required_here (&str
, 15, s7_REG_TYPE_SCORE
) == (int) s7_FAIL
1218 || s7_skip_past_comma (&str
) == (int) s7_FAIL
1219 || s7_reg_required_here (&str
, 10, s7_REG_TYPE_SCORE
) == (int) s7_FAIL
1220 || s7_end_of_line (str
) == (int) s7_FAIL
)
1226 if ((((s7_inst
.instruction
>> 15) & 0x10) == 0)
1227 && (((s7_inst
.instruction
>> 10) & 0x10) == 0)
1228 && (((s7_inst
.instruction
>> 20) & 0x10) == 0)
1229 && (s7_inst
.relax_inst
!= 0x8000)
1230 && (((s7_inst
.instruction
>> 20) & 0xf) == ((s7_inst
.instruction
>> 15) & 0xf)))
1232 s7_inst
.relax_inst
|= (((s7_inst
.instruction
>> 10) & 0xf) << 4)
1233 | (((s7_inst
.instruction
>> 15) & 0xf) << 8);
1234 s7_inst
.relax_size
= 2;
1238 s7_inst
.relax_inst
= 0x8000;
1244 s7_walk_no_bignums (symbolS
* sp
)
1246 if (symbol_get_value_expression (sp
)->X_op
== O_big
)
1249 if (symbol_get_value_expression (sp
)->X_add_symbol
)
1250 return (s7_walk_no_bignums (symbol_get_value_expression (sp
)->X_add_symbol
)
1251 || (symbol_get_value_expression (sp
)->X_op_symbol
1252 && s7_walk_no_bignums (symbol_get_value_expression (sp
)->X_op_symbol
)));
1258 s7_my_get_expression (expressionS
* ep
, char **str
)
1262 save_in
= input_line_pointer
;
1263 input_line_pointer
= *str
;
1264 s7_in_my_get_expression
= 1;
1266 (void) expression (ep
);
1267 s7_in_my_get_expression
= 0;
1269 if (ep
->X_op
== O_illegal
)
1271 *str
= input_line_pointer
;
1272 input_line_pointer
= save_in
;
1273 s7_inst
.error
= _("illegal expression");
1274 return (int) s7_FAIL
;
1276 /* Get rid of any bignums now, so that we don't generate an error for which
1277 we can't establish a line number later on. Big numbers are never valid
1278 in instructions, which is where this routine is always called. */
1279 if (ep
->X_op
== O_big
1280 || (ep
->X_add_symbol
1281 && (s7_walk_no_bignums (ep
->X_add_symbol
)
1282 || (ep
->X_op_symbol
&& s7_walk_no_bignums (ep
->X_op_symbol
)))))
1284 s7_inst
.error
= _("invalid constant");
1285 *str
= input_line_pointer
;
1286 input_line_pointer
= save_in
;
1287 return (int) s7_FAIL
;
1290 if ((ep
->X_add_symbol
!= NULL
)
1291 && (s7_inst
.type
!= PC_DISP19div2
)
1292 && (s7_inst
.type
!= PC_DISP8div2
)
1293 && (s7_inst
.type
!= PC_DISP24div2
)
1294 && (s7_inst
.type
!= PC_DISP11div2
)
1295 && (s7_inst
.type
!= Insn_Type_SYN
)
1296 && (s7_inst
.type
!= Rd_rvalueRs_SI15
)
1297 && (s7_inst
.type
!= Rd_lvalueRs_SI15
)
1298 && (s7_inst
.type
!= Insn_internal
))
1300 s7_inst
.error
= s7_BAD_ARGS
;
1301 *str
= input_line_pointer
;
1302 input_line_pointer
= save_in
;
1303 return (int) s7_FAIL
;
1306 *str
= input_line_pointer
;
1307 input_line_pointer
= save_in
;
1311 /* Check if an immediate is valid. If so, convert it to the right format. */
1313 static bfd_signed_vma
1314 s7_validate_immediate (bfd_signed_vma val
, unsigned int data_type
, int hex_p
)
1320 int val_hi
= ((val
& 0xffff0000) >> 16);
1322 if (s7_score_df_range
[data_type
].range
[0] <= val_hi
1323 && val_hi
<= s7_score_df_range
[data_type
].range
[1])
1330 int val_lo
= (val
& 0xffff);
1332 if (s7_score_df_range
[data_type
].range
[0] <= val_lo
1333 && val_lo
<= s7_score_df_range
[data_type
].range
[1])
1341 if (!(val
>= -0x800 && val
<= 0xfff))
1343 return (int) s7_FAIL
;
1348 if (!(val
>= -2048 && val
<= 2047))
1350 return (int) s7_FAIL
;
1360 if (!(val
>= -0x2000 && val
<= 0x3fff))
1362 return (int) s7_FAIL
;
1367 if (!(val
>= -8192 && val
<= 8191))
1369 return (int) s7_FAIL
;
1379 if (!(val
>= -0x4000 && val
<= 0x7fff))
1381 return (int) s7_FAIL
;
1386 if (!(val
>= -16384 && val
<= 16383))
1388 return (int) s7_FAIL
;
1398 if (!(val
>= -0x8000 && val
<= 0xffff))
1400 return (int) s7_FAIL
;
1405 if (!(val
>= -32768 && val
<= 32767))
1407 return (int) s7_FAIL
;
1417 if (!(val
>= -0x7fff && val
<= 0xffff && val
!= 0x8000))
1419 return (int) s7_FAIL
;
1424 if (!(val
>= -32767 && val
<= 32768))
1426 return (int) s7_FAIL
;
1435 if (val
>= 0 && val
<= 0xffffffff)
1441 return (int) s7_FAIL
;
1445 if (data_type
== _SIMM14_NEG
|| data_type
== _IMM16_NEG
)
1448 if (s7_score_df_range
[data_type
].range
[0] <= val
1449 && val
<= s7_score_df_range
[data_type
].range
[1])
1455 return (int) s7_FAIL
;
1459 s7_data_op2 (char **str
, int shift
, enum score_data_type data_type
)
1462 char data_exp
[s7_MAX_LITERAL_POOL_SIZE
];
1467 s7_skip_whitespace (*str
);
1468 s7_inst
.error
= NULL
;
1471 /* Set hex_p to zero. */
1474 while ((*dataptr
!= '\0') && (*dataptr
!= '|') && (cnt
<= s7_MAX_LITERAL_POOL_SIZE
)) /* 0x7c = ='|' */
1476 data_exp
[cnt
] = *dataptr
;
1481 data_exp
[cnt
] = '\0';
1482 pp
= (char *)&data_exp
;
1484 if (*dataptr
== '|') /* process PCE */
1486 if (s7_my_get_expression (&s7_inst
.reloc
.exp
, &pp
) == (int) s7_FAIL
)
1487 return (int) s7_FAIL
;
1488 s7_end_of_line (pp
);
1489 if (s7_inst
.error
!= 0)
1490 return (int) s7_FAIL
; /* to ouptut_inst to printf out the error */
1493 else /* process 16 bit */
1495 if (s7_my_get_expression (&s7_inst
.reloc
.exp
, str
) == (int) s7_FAIL
)
1497 return (int) s7_FAIL
;
1500 dataptr
= (char *) data_exp
;
1501 for (; *dataptr
!= '\0'; dataptr
++)
1503 *dataptr
= TOLOWER (*dataptr
);
1504 if (*dataptr
== '!' || *dataptr
== ' ')
1507 dataptr
= (char *) data_exp
;
1509 if ((dataptr
!= NULL
)
1510 && (((strstr (dataptr
, "0x")) != NULL
)
1511 || ((strstr (dataptr
, "0X")) != NULL
)))
1514 if ((data_type
!= _SIMM16_LA
)
1515 && (data_type
!= _VALUE_HI16
)
1516 && (data_type
!= _VALUE_LO16
)
1517 && (data_type
!= _IMM16
)
1518 && (data_type
!= _IMM15
)
1519 && (data_type
!= _IMM14
)
1520 && (data_type
!= _IMM4
)
1521 && (data_type
!= _IMM5
)
1522 && (data_type
!= _IMM8
)
1523 && (data_type
!= _IMM5_RSHIFT_1
)
1524 && (data_type
!= _IMM5_RSHIFT_2
)
1525 && (data_type
!= _SIMM14
)
1526 && (data_type
!= _SIMM16
)
1527 && (data_type
!= _SIMM14_NEG
)
1528 && (data_type
!= _SIMM16_NEG
)
1529 && (data_type
!= _IMM10_RSHIFT_2
)
1530 && (data_type
!= _GP_IMM15
))
1536 if ((s7_inst
.reloc
.exp
.X_add_number
== 0)
1537 /* for "addi r0,-((((((32*4)+4)+4)+4)+4)&0xf)". */
1538 && (s7_inst
.type
!= Rd_SI16
)
1539 && (s7_inst
.type
!= Insn_Type_SYN
)
1540 && (s7_inst
.type
!= Rd_rvalueRs_SI15
)
1541 && (s7_inst
.type
!= Rd_lvalueRs_SI15
)
1542 && (s7_inst
.type
!= Insn_internal
)
1543 && (((*dataptr
>= 'a') && (*dataptr
<= 'z'))
1544 || ((*dataptr
== '0') && (*(dataptr
+ 1) == 'x') && (*(dataptr
+ 2) != '0'))
1545 || ((*dataptr
== '+') && (*(dataptr
+ 1) != '0'))
1546 || ((*dataptr
== '-') && (*(dataptr
+ 1) != '0'))))
1548 s7_inst
.error
= s7_BAD_ARGS
;
1549 return (int) s7_FAIL
;
1553 if ((s7_inst
.reloc
.exp
.X_add_symbol
)
1554 && ((data_type
== _SIMM16
)
1555 || (data_type
== _SIMM16_NEG
)
1556 || (data_type
== _IMM16_NEG
)
1557 || (data_type
== _SIMM14
)
1558 || (data_type
== _SIMM14_NEG
)
1559 || (data_type
== _IMM5
)
1560 || (data_type
== _IMM14
)
1561 || (data_type
== _IMM20
)
1562 || (data_type
== _IMM16
)
1563 || (data_type
== _IMM15
)
1564 || (data_type
== _IMM4
)))
1566 s7_inst
.error
= s7_BAD_ARGS
;
1567 return (int) s7_FAIL
;
1570 if (s7_inst
.reloc
.exp
.X_add_symbol
)
1575 return (int) s7_FAIL
;
1577 s7_inst
.reloc
.type
= BFD_RELOC_HI16_S
;
1578 s7_inst
.reloc
.pc_rel
= 0;
1581 s7_inst
.reloc
.type
= BFD_RELOC_LO16
;
1582 s7_inst
.reloc
.pc_rel
= 0;
1585 s7_inst
.reloc
.type
= BFD_RELOC_SCORE_GPREL15
;
1586 s7_inst
.reloc
.pc_rel
= 0;
1589 case _IMM16_LO16_pic
:
1590 s7_inst
.reloc
.type
= BFD_RELOC_SCORE_GOT_LO16
;
1591 s7_inst
.reloc
.pc_rel
= 0;
1594 s7_inst
.reloc
.type
= BFD_RELOC_32
;
1595 s7_inst
.reloc
.pc_rel
= 0;
1601 if (data_type
== _IMM16_pic
)
1603 s7_inst
.reloc
.type
= BFD_RELOC_SCORE_DUMMY_HI16
;
1604 s7_inst
.reloc
.pc_rel
= 0;
1607 if (data_type
== _SIMM16_LA
&& s7_inst
.reloc
.exp
.X_unsigned
== 1)
1609 value
= s7_validate_immediate (s7_inst
.reloc
.exp
.X_add_number
, _SIMM16_LA_POS
, hex_p
);
1610 if (value
== (int) s7_FAIL
) /* for advance to check if this is ldis */
1611 if ((s7_inst
.reloc
.exp
.X_add_number
& 0xffff) == 0)
1613 s7_inst
.instruction
|= 0x8000000;
1614 s7_inst
.instruction
|= ((s7_inst
.reloc
.exp
.X_add_number
>> 16) << 1) & 0x1fffe;
1620 value
= s7_validate_immediate (s7_inst
.reloc
.exp
.X_add_number
, data_type
, hex_p
);
1623 if (value
== (int) s7_FAIL
)
1625 if ((data_type
!= _SIMM14_NEG
) && (data_type
!= _SIMM16_NEG
) && (data_type
!= _IMM16_NEG
))
1627 sprintf (s7_err_msg
,
1628 _("invalid constant: %d bit expression not in range %d..%d"),
1629 s7_score_df_range
[data_type
].bits
,
1630 s7_score_df_range
[data_type
].range
[0], s7_score_df_range
[data_type
].range
[1]);
1634 sprintf (s7_err_msg
,
1635 _("invalid constant: %d bit expression not in range %d..%d"),
1636 s7_score_df_range
[data_type
].bits
,
1637 -s7_score_df_range
[data_type
].range
[1], -s7_score_df_range
[data_type
].range
[0]);
1640 s7_inst
.error
= s7_err_msg
;
1641 return (int) s7_FAIL
;
1644 if ((s7_score_df_range
[data_type
].range
[0] != 0) || (data_type
== _IMM5_RANGE_8_31
))
1646 value
&= (1 << s7_score_df_range
[data_type
].bits
) - 1;
1649 s7_inst
.instruction
|= value
<< shift
;
1652 if ((s7_inst
.instruction
& 0x3e000000) == 0x30000000)
1654 if ((((s7_inst
.instruction
>> 20) & 0x1F) != 0)
1655 && (((s7_inst
.instruction
>> 20) & 0x1F) != 1)
1656 && (((s7_inst
.instruction
>> 20) & 0x1F) != 2)
1657 && (((s7_inst
.instruction
>> 20) & 0x1F) != 3)
1658 && (((s7_inst
.instruction
>> 20) & 0x1F) != 4)
1659 && (((s7_inst
.instruction
>> 20) & 0x1F) != 8)
1660 && (((s7_inst
.instruction
>> 20) & 0x1F) != 9)
1661 && (((s7_inst
.instruction
>> 20) & 0x1F) != 0xa)
1662 && (((s7_inst
.instruction
>> 20) & 0x1F) != 0xb)
1663 && (((s7_inst
.instruction
>> 20) & 0x1F) != 0xc)
1664 && (((s7_inst
.instruction
>> 20) & 0x1F) != 0xd)
1665 && (((s7_inst
.instruction
>> 20) & 0x1F) != 0xe)
1666 && (((s7_inst
.instruction
>> 20) & 0x1F) != 0x10)
1667 && (((s7_inst
.instruction
>> 20) & 0x1F) != 0x11)
1668 && (((s7_inst
.instruction
>> 20) & 0x1F) != 0x18)
1669 && (((s7_inst
.instruction
>> 20) & 0x1F) != 0x1A)
1670 && (((s7_inst
.instruction
>> 20) & 0x1F) != 0x1B)
1671 && (((s7_inst
.instruction
>> 20) & 0x1F) != 0x1d)
1672 && (((s7_inst
.instruction
>> 20) & 0x1F) != 0x1e)
1673 && (((s7_inst
.instruction
>> 20) & 0x1F) != 0x1f))
1675 s7_inst
.error
= _("invalid constant: bit expression not defined");
1676 return (int) s7_FAIL
;
1683 /* Handle addi/addi.c/addis.c/cmpi.c/addis.c/ldi. */
1686 s7_do_rdsi16 (char *str
)
1688 s7_skip_whitespace (str
);
1690 if (s7_reg_required_here (&str
, 20, s7_REG_TYPE_SCORE
) == (int) s7_FAIL
1691 || s7_skip_past_comma (&str
) == (int) s7_FAIL
1692 || s7_data_op2 (&str
, 1, _SIMM16
) == (int) s7_FAIL
1693 || s7_end_of_line (str
) == (int) s7_FAIL
)
1697 if ((s7_inst
.instruction
& 0x20c0000) == 0x20c0000)
1699 if ((((s7_inst
.instruction
>> 20) & 0x10) == 0x10) || ((s7_inst
.instruction
& 0x1fe00) != 0))
1701 s7_inst
.relax_inst
= 0x8000;
1705 s7_inst
.relax_inst
|= (s7_inst
.instruction
>> 1) & 0xff;
1706 s7_inst
.relax_inst
|= (((s7_inst
.instruction
>> 20) & 0xf) << 8);
1707 s7_inst
.relax_size
= 2;
1710 else if (((s7_inst
.instruction
>> 20) & 0x10) == 0x10)
1712 s7_inst
.relax_inst
= 0x8000;
1716 /* Handle subi/subi.c. */
1719 s7_do_sub_rdsi16 (char *str
)
1721 s7_skip_whitespace (str
);
1723 if (s7_reg_required_here (&str
, 20, s7_REG_TYPE_SCORE
) != (int) s7_FAIL
1724 && s7_skip_past_comma (&str
) != (int) s7_FAIL
1725 && s7_data_op2 (&str
, 1, _SIMM16_NEG
) != (int) s7_FAIL
)
1726 s7_end_of_line (str
);
1730 /* Handle addri/addri.c. */
1733 s7_do_rdrssi14 (char *str
) /* -(2^13)~((2^13)-1) */
1735 s7_skip_whitespace (str
);
1737 if (s7_reg_required_here (&str
, 20, s7_REG_TYPE_SCORE
) != (int) s7_FAIL
1738 && s7_skip_past_comma (&str
) != (int) s7_FAIL
1739 && s7_reg_required_here (&str
, 15, s7_REG_TYPE_SCORE
) != (int) s7_FAIL
1740 && s7_skip_past_comma (&str
) != (int) s7_FAIL
)
1741 s7_data_op2 (&str
, 1, _SIMM14
);
1744 /* Handle subri.c/subri. */
1747 s7_do_sub_rdrssi14 (char *str
) /* -(2^13)~((2^13)-1) */
1749 s7_skip_whitespace (str
);
1751 if (s7_reg_required_here (&str
, 20, s7_REG_TYPE_SCORE
) != (int) s7_FAIL
1752 && s7_skip_past_comma (&str
) != (int) s7_FAIL
1753 && s7_reg_required_here (&str
, 15, s7_REG_TYPE_SCORE
) != (int) s7_FAIL
1754 && s7_skip_past_comma (&str
) != (int) s7_FAIL
1755 && s7_data_op2 (&str
, 1, _SIMM14_NEG
) != (int) s7_FAIL
)
1756 s7_end_of_line (str
);
1759 /* Handle bitclr.c/bitset.c/bittgl.c/slli.c/srai.c/srli.c/roli.c/rori.c/rolic.c. */
1762 s7_do_rdrsi5 (char *str
) /* 0~((2^14)-1) */
1764 s7_skip_whitespace (str
);
1766 if (s7_reg_required_here (&str
, 20, s7_REG_TYPE_SCORE
) == (int) s7_FAIL
1767 || s7_skip_past_comma (&str
) == (int) s7_FAIL
1768 || s7_reg_required_here (&str
, 15, s7_REG_TYPE_SCORE
) == (int) s7_FAIL
1769 || s7_skip_past_comma (&str
) == (int) s7_FAIL
1770 || s7_data_op2 (&str
, 10, _IMM5
) == (int) s7_FAIL
1771 || s7_end_of_line (str
) == (int) s7_FAIL
)
1774 if ((((s7_inst
.instruction
>> 20) & 0x1f) == ((s7_inst
.instruction
>> 15) & 0x1f))
1775 && (s7_inst
.relax_inst
!= 0x8000) && (((s7_inst
.instruction
>> 15) & 0x10) == 0))
1777 s7_inst
.relax_inst
|= (((s7_inst
.instruction
>> 10) & 0x1f) << 3) | (((s7_inst
.instruction
>> 15) & 0xf) << 8);
1778 s7_inst
.relax_size
= 2;
1781 s7_inst
.relax_inst
= 0x8000;
1784 /* Handle andri/orri/andri.c/orri.c. */
1787 s7_do_rdrsi14 (char *str
) /* 0 ~ ((2^14)-1) */
1789 s7_skip_whitespace (str
);
1791 if (s7_reg_required_here (&str
, 20, s7_REG_TYPE_SCORE
) != (int) s7_FAIL
1792 && s7_skip_past_comma (&str
) != (int) s7_FAIL
1793 && s7_reg_required_here (&str
, 15, s7_REG_TYPE_SCORE
) != (int) s7_FAIL
1794 && s7_skip_past_comma (&str
) != (int) s7_FAIL
1795 && s7_data_op2 (&str
, 1, _IMM14
) != (int) s7_FAIL
)
1796 s7_end_of_line (str
);
1799 /* Handle bittst.c. */
1802 s7_do_xrsi5 (char *str
)
1804 s7_skip_whitespace (str
);
1806 if (s7_reg_required_here (&str
, 15, s7_REG_TYPE_SCORE
) == (int) s7_FAIL
1807 || s7_skip_past_comma (&str
) == (int) s7_FAIL
1808 || s7_data_op2 (&str
, 10, _IMM5
) == (int) s7_FAIL
1809 || s7_end_of_line (str
) == (int) s7_FAIL
)
1812 if ((s7_inst
.relax_inst
!= 0x8000) && (((s7_inst
.instruction
>> 15) & 0x10) == 0))
1814 s7_inst
.relax_inst
|= (((s7_inst
.instruction
>> 10) & 0x1f) << 3) | (((s7_inst
.instruction
>> 15) & 0xf) << 8);
1815 s7_inst
.relax_size
= 2;
1818 s7_inst
.relax_inst
= 0x8000;
1821 /* Handle addis/andi/ori/andis/oris/ldis. */
1824 s7_do_rdi16 (char *str
)
1826 s7_skip_whitespace (str
);
1828 if (s7_reg_required_here (&str
, 20, s7_REG_TYPE_SCORE
) == (int) s7_FAIL
1829 || s7_skip_past_comma (&str
) == (int) s7_FAIL
1830 || s7_data_op2 (&str
, 1, _IMM16
) == (int) s7_FAIL
1831 || s7_end_of_line (str
) == (int) s7_FAIL
)
1836 s7_do_macro_rdi32hi (char *str
)
1838 s7_skip_whitespace (str
);
1840 /* Do not handle s7_end_of_line(). */
1841 if (s7_reg_required_here (&str
, 20, s7_REG_TYPE_SCORE
) != (int) s7_FAIL
1842 && s7_skip_past_comma (&str
) != (int) s7_FAIL
)
1843 s7_data_op2 (&str
, 1, _VALUE_HI16
);
1847 s7_do_macro_rdi32lo (char *str
)
1849 s7_skip_whitespace (str
);
1851 /* Do not handle s7_end_of_line(). */
1852 if (s7_reg_required_here (&str
, 20, s7_REG_TYPE_SCORE
) != (int) s7_FAIL
1853 && s7_skip_past_comma (&str
) != (int) s7_FAIL
)
1854 s7_data_op2 (&str
, 1, _VALUE_LO16
);
1857 /* Handle ldis_pic. */
1860 s7_do_rdi16_pic (char *str
)
1862 s7_skip_whitespace (str
);
1864 if (s7_reg_required_here (&str
, 20, s7_REG_TYPE_SCORE
) != (int) s7_FAIL
1865 && s7_skip_past_comma (&str
) != (int) s7_FAIL
1866 && s7_data_op2 (&str
, 1, _IMM16_pic
) != (int) s7_FAIL
)
1867 s7_end_of_line (str
);
1870 /* Handle addi_s_pic to generate R_SCORE_GOT_LO16 . */
1873 s7_do_addi_s_pic (char *str
)
1875 s7_skip_whitespace (str
);
1877 if (s7_reg_required_here (&str
, 20, s7_REG_TYPE_SCORE
) != (int) s7_FAIL
1878 && s7_skip_past_comma (&str
) != (int) s7_FAIL
1879 && s7_data_op2 (&str
, 1, _SIMM16_pic
) != (int) s7_FAIL
)
1880 s7_end_of_line (str
);
1883 /* Handle addi_u_pic to generate R_SCORE_GOT_LO16 . */
1886 s7_do_addi_u_pic (char *str
)
1888 s7_skip_whitespace (str
);
1890 if (s7_reg_required_here (&str
, 20, s7_REG_TYPE_SCORE
) != (int) s7_FAIL
1891 && s7_skip_past_comma (&str
) != (int) s7_FAIL
1892 && s7_data_op2 (&str
, 1, _IMM16_LO16_pic
) != (int) s7_FAIL
)
1893 s7_end_of_line (str
);
1896 /* Handle mfceh/mfcel/mtceh/mtchl. */
1899 s7_do_rd (char *str
)
1901 s7_skip_whitespace (str
);
1903 if (s7_reg_required_here (&str
, 20, s7_REG_TYPE_SCORE
) != (int) s7_FAIL
)
1904 s7_end_of_line (str
);
1908 s7_do_rs (char *str
)
1910 s7_skip_whitespace (str
);
1912 if (s7_reg_required_here (&str
, 15, s7_REG_TYPE_SCORE
) == (int) s7_FAIL
1913 || s7_end_of_line (str
) == (int) s7_FAIL
)
1916 if ((s7_inst
.relax_inst
!= 0x8000) && (((s7_inst
.instruction
>> 15) & 0x10) == 0))
1918 s7_inst
.relax_inst
|= (((s7_inst
.instruction
>> 10) & 0xf) << 8) | (((s7_inst
.instruction
>> 15) & 0xf) << 4);
1919 s7_inst
.relax_size
= 2;
1922 s7_inst
.relax_inst
= 0x8000;
1926 s7_do_i15 (char *str
)
1928 s7_skip_whitespace (str
);
1930 if (s7_data_op2 (&str
, 10, _IMM15
) != (int) s7_FAIL
)
1931 s7_end_of_line (str
);
1935 s7_do_xi5x (char *str
)
1937 s7_skip_whitespace (str
);
1939 if (s7_data_op2 (&str
, 15, _IMM5
) == (int) s7_FAIL
|| s7_end_of_line (str
) == (int) s7_FAIL
)
1942 if (s7_inst
.relax_inst
!= 0x8000)
1944 s7_inst
.relax_inst
|= (((s7_inst
.instruction
>> 15) & 0x1f) << 3);
1945 s7_inst
.relax_size
= 2;
1950 s7_do_rdrs (char *str
)
1952 s7_skip_whitespace (str
);
1954 if (s7_reg_required_here (&str
, 20, s7_REG_TYPE_SCORE
) == (int) s7_FAIL
1955 || s7_skip_past_comma (&str
) == (int) s7_FAIL
1956 || s7_reg_required_here (&str
, 15, s7_REG_TYPE_SCORE
) == (int) s7_FAIL
1957 || s7_end_of_line (str
) == (int) s7_FAIL
)
1960 if (s7_inst
.relax_inst
!= 0x8000)
1962 if (((s7_inst
.instruction
& 0x7f) == 0x56)) /* adjust mv -> mv! / mlfh! / mhfl! */
1965 if ((((s7_inst
.instruction
>> 15) & 0x10) != 0x0) && (((s7_inst
.instruction
>> 20) & 0x10) == 0))
1967 s7_inst
.relax_inst
= 0x00000001 | (((s7_inst
.instruction
>> 15) & 0xf) << 4)
1968 | (((s7_inst
.instruction
>> 20) & 0xf) << 8);
1969 s7_inst
.relax_size
= 2;
1972 else if ((((s7_inst
.instruction
>> 15) & 0x10) == 0x0) && ((s7_inst
.instruction
>> 20) & 0x10) != 0)
1974 s7_inst
.relax_inst
= 0x00000002 | (((s7_inst
.instruction
>> 15) & 0xf) << 4)
1975 | (((s7_inst
.instruction
>> 20) & 0xf) << 8);
1976 s7_inst
.relax_size
= 2;
1978 else if ((((s7_inst
.instruction
>> 15) & 0x10) == 0x0) && (((s7_inst
.instruction
>> 20) & 0x10) == 0))
1980 s7_inst
.relax_inst
|= (((s7_inst
.instruction
>> 15) & 0xf) << 4)
1981 | (((s7_inst
.instruction
>> 20) & 0xf) << 8);
1982 s7_inst
.relax_size
= 2;
1986 s7_inst
.relax_inst
= 0x8000;
1989 else if ((((s7_inst
.instruction
>> 15) & 0x10) == 0x0) && (((s7_inst
.instruction
>> 20) & 0x10) == 0))
1991 s7_inst
.relax_inst
|= (((s7_inst
.instruction
>> 15) & 0xf) << 4)
1992 | (((s7_inst
.instruction
>> 20) & 0xf) << 8);
1993 s7_inst
.relax_size
= 2;
1997 s7_inst
.relax_inst
= 0x8000;
2002 /* Handle mfcr/mtcr. */
2004 s7_do_rdcrs (char *str
)
2006 s7_skip_whitespace (str
);
2008 if (s7_reg_required_here (&str
, 20, s7_REG_TYPE_SCORE
) != (int) s7_FAIL
2009 && s7_skip_past_comma (&str
) != (int) s7_FAIL
2010 && s7_reg_required_here (&str
, 15, s7_REG_TYPE_SCORE_CR
) != (int) s7_FAIL
)
2011 s7_end_of_line (str
);
2014 /* Handle mfsr/mtsr. */
2017 s7_do_rdsrs (char *str
)
2019 s7_skip_whitespace (str
);
2022 if ((s7_inst
.instruction
& 0xff) == 0x50)
2024 if (s7_reg_required_here (&str
, 20, s7_REG_TYPE_SCORE
) != (int) s7_FAIL
2025 && s7_skip_past_comma (&str
) != (int) s7_FAIL
2026 && s7_reg_required_here (&str
, 10, s7_REG_TYPE_SCORE_SR
) != (int) s7_FAIL
)
2027 s7_end_of_line (str
);
2031 if (s7_reg_required_here (&str
, 15, s7_REG_TYPE_SCORE
) != (int) s7_FAIL
2032 && s7_skip_past_comma (&str
) != (int) s7_FAIL
)
2033 s7_reg_required_here (&str
, 10, s7_REG_TYPE_SCORE_SR
);
2040 s7_do_rdxrs (char *str
)
2042 s7_skip_whitespace (str
);
2044 if (s7_reg_required_here (&str
, 20, s7_REG_TYPE_SCORE
) == (int) s7_FAIL
2045 || s7_skip_past_comma (&str
) == (int) s7_FAIL
2046 || s7_reg_required_here (&str
, 10, s7_REG_TYPE_SCORE
) == (int) s7_FAIL
2047 || s7_end_of_line (str
) == (int) s7_FAIL
)
2050 if ((s7_inst
.relax_inst
!= 0x8000) && (((s7_inst
.instruction
>> 10) & 0x10) == 0)
2051 && (((s7_inst
.instruction
>> 20) & 0x10) == 0))
2053 s7_inst
.relax_inst
|= (((s7_inst
.instruction
>> 10) & 0xf) << 4) | (((s7_inst
.instruction
>> 20) & 0xf) << 8);
2054 s7_inst
.relax_size
= 2;
2057 s7_inst
.relax_inst
= 0x8000;
2060 /* Handle cmp.c/cmp<cond>. */
2062 s7_do_rsrs (char *str
)
2064 s7_skip_whitespace (str
);
2066 if (s7_reg_required_here (&str
, 15, s7_REG_TYPE_SCORE
) == (int) s7_FAIL
2067 || s7_skip_past_comma (&str
) == (int) s7_FAIL
2068 || s7_reg_required_here (&str
, 10, s7_REG_TYPE_SCORE
) == (int) s7_FAIL
2069 || s7_end_of_line (str
) == (int) s7_FAIL
)
2072 if ((s7_inst
.relax_inst
!= 0x8000) && (((s7_inst
.instruction
>> 20) & 0x1f) == 3)
2073 && (((s7_inst
.instruction
>> 10) & 0x10) == 0) && (((s7_inst
.instruction
>> 15) & 0x10) == 0))
2075 s7_inst
.relax_inst
|= (((s7_inst
.instruction
>> 10) & 0xf) << 4) | (((s7_inst
.instruction
>> 15) & 0xf) << 8);
2076 s7_inst
.relax_size
= 2;
2079 s7_inst
.relax_inst
= 0x8000;
2083 s7_do_ceinst (char *str
)
2088 s7_skip_whitespace (str
);
2090 if (s7_data_op2 (&str
, 20, _IMM5
) == (int) s7_FAIL
2091 || s7_skip_past_comma (&str
) == (int) s7_FAIL
2092 || s7_reg_required_here (&str
, 15, s7_REG_TYPE_SCORE
) == (int) s7_FAIL
2093 || s7_skip_past_comma (&str
) == (int) s7_FAIL
2094 || s7_reg_required_here (&str
, 10, s7_REG_TYPE_SCORE
) == (int) s7_FAIL
2095 || s7_skip_past_comma (&str
) == (int) s7_FAIL
2096 || s7_data_op2 (&str
, 5, _IMM5
) == (int) s7_FAIL
2097 || s7_skip_past_comma (&str
) == (int) s7_FAIL
2098 || s7_data_op2 (&str
, 0, _IMM5
) == (int) s7_FAIL
2099 || s7_end_of_line (str
) == (int) s7_FAIL
)
2106 if (s7_data_op2 (&str
, 0, _IMM25
) == (int) s7_FAIL
)
2112 s7_reglow_required_here (char **str
, int shift
)
2114 static char buff
[s7_MAX_LITERAL_POOL_SIZE
];
2118 if ((reg
= s7_score_reg_parse (str
, s7_all_reg_maps
[s7_REG_TYPE_SCORE
].htab
)) != (int) s7_FAIL
)
2120 if ((reg
== 1) && (s7_nor1
== 1) && (s7_inst
.bwarn
== 0))
2122 as_warn (_("Using temp register(r1)"));
2128 s7_inst
.instruction
|= reg
<< shift
;
2134 /* Restore the start point, we may have got a reg of the wrong class. */
2136 sprintf (buff
, _("low register(r0-r15)expected, not '%.100s'"), start
);
2137 s7_inst
.error
= buff
;
2138 return (int) s7_FAIL
;
2141 /* Handle addc!/add!/and!/cmp!/neg!/not!/or!/sll!/srl!/sra!/xor!/sub!. */
2144 s7_do16_rdrs (char *str
)
2146 s7_skip_whitespace (str
);
2148 if (s7_reglow_required_here (&str
, 8) == (int) s7_FAIL
2149 || s7_skip_past_comma (&str
) == (int) s7_FAIL
2150 || s7_reglow_required_here (&str
, 4) == (int) s7_FAIL
2151 || s7_end_of_line (str
) == (int) s7_FAIL
)
2157 if ((s7_inst
.instruction
& 0x700f) == 0x2003) /* cmp! */
2159 s7_inst
.relax_inst
|= (((s7_inst
.instruction
>> 8) & 0xf) << 15)
2160 | (((s7_inst
.instruction
>> 4) & 0xf) << 10);
2162 else if ((s7_inst
.instruction
& 0x700f) == 0x2006) /* not! */
2164 s7_inst
.relax_inst
|= (((s7_inst
.instruction
>> 8) & 0xf) << 20)
2165 | (((s7_inst
.instruction
>> 4) & 0xf) << 15);
2167 else if ((s7_inst
.instruction
& 0x700f) == 0x1009) /* mazh.f! */
2169 s7_inst
.relax_inst
|= (((s7_inst
.instruction
>> 8) & 0xf) << 15)
2170 | (((s7_inst
.instruction
>> 4) & 0xf) << 10);
2174 s7_inst
.relax_inst
|= (((s7_inst
.instruction
>> 8) & 0xf) << 20)
2175 | (((s7_inst
.instruction
>> 8) & 0xf) << 15) | (((s7_inst
.instruction
>> 4) & 0xf) << 10);
2177 s7_inst
.relax_size
= 4;
2182 s7_do16_rs (char *str
)
2186 s7_skip_whitespace (str
);
2188 if ((rd
= s7_reglow_required_here (&str
, 4)) == (int) s7_FAIL
2189 || s7_end_of_line (str
) == (int) s7_FAIL
)
2195 s7_inst
.relax_inst
|= rd
<< 20;
2196 s7_inst
.relax_size
= 4;
2200 /* Handle br!/brl!. */
2203 s7_do16_xrs (char *str
)
2205 s7_skip_whitespace (str
);
2207 if (s7_reglow_required_here (&str
, 4) == (int) s7_FAIL
|| s7_end_of_line (str
) == (int) s7_FAIL
)
2213 s7_inst
.relax_inst
|= (((s7_inst
.instruction
>> 8) & 0xf) << 10)
2214 | (((s7_inst
.instruction
>> 4) & 0xf) << 15);
2215 s7_inst
.relax_size
= 4;
2220 s7_reghigh_required_here (char **str
, int shift
)
2222 static char buff
[s7_MAX_LITERAL_POOL_SIZE
];
2226 if ((reg
= s7_score_reg_parse (str
, s7_all_reg_maps
[s7_REG_TYPE_SCORE
].htab
)) != (int) s7_FAIL
)
2228 if (15 < reg
&& reg
< 32)
2231 s7_inst
.instruction
|= (reg
& 0xf) << shift
;
2238 sprintf (buff
, _("high register(r16-r31)expected, not '%.100s'"), start
);
2239 s7_inst
.error
= buff
;
2240 return (int) s7_FAIL
;
2246 s7_do16_hrdrs (char *str
)
2248 s7_skip_whitespace (str
);
2250 if (s7_reghigh_required_here (&str
, 8) != (int) s7_FAIL
2251 && s7_skip_past_comma (&str
) != (int) s7_FAIL
2252 && s7_reglow_required_here (&str
, 4) != (int) s7_FAIL
2253 && s7_end_of_line (str
) != (int) s7_FAIL
)
2255 s7_inst
.relax_inst
|= ((((s7_inst
.instruction
>> 8) & 0xf) | 0x10) << 20)
2256 | (((s7_inst
.instruction
>> 4) & 0xf) << 15) | (0xf << 10);
2257 s7_inst
.relax_size
= 4;
2264 s7_do16_rdhrs (char *str
)
2266 s7_skip_whitespace (str
);
2268 if (s7_reglow_required_here (&str
, 8) != (int) s7_FAIL
2269 && s7_skip_past_comma (&str
) != (int) s7_FAIL
2270 && s7_reghigh_required_here (&str
, 4) != (int) s7_FAIL
2271 && s7_end_of_line (str
) != (int) s7_FAIL
)
2273 s7_inst
.relax_inst
|= (((s7_inst
.instruction
>> 8) & 0xf) << 20)
2274 | ((((s7_inst
.instruction
>> 4) & 0xf) | 0x10) << 15) | (0xf << 10);
2275 s7_inst
.relax_size
= 4;
2279 /* We need to be able to fix up arbitrary expressions in some statements.
2280 This is so that we can handle symbols that are an arbitrary distance from
2281 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
2282 which returns part of an address in a form which will be valid for
2283 a data instruction. We do this by pushing the expression into a symbol
2284 in the expr_section, and creating a fix for that. */
2287 s7_fix_new_score (fragS
* frag
, int where
, short int size
, expressionS
* exp
, int pc_rel
, int reloc
)
2297 new_fix
= fix_new_exp (frag
, where
, size
, exp
, pc_rel
, reloc
);
2300 new_fix
= fix_new (frag
, where
, size
, make_expr_symbol (exp
), 0, pc_rel
, reloc
);
2307 s7_init_dependency_vector (void)
2311 for (i
= 0; i
< s7_vector_size
; i
++)
2312 memset (&s7_dependency_vector
[i
], '\0', sizeof (s7_dependency_vector
[i
]));
2317 static enum s7_insn_type_for_dependency
2318 s7_dependency_type_from_insn (char *insn_name
)
2320 char name
[s7_INSN_NAME_LEN
];
2321 const struct s7_insn_to_dependency
*tmp
;
2323 strcpy (name
, insn_name
);
2324 tmp
= (const struct s7_insn_to_dependency
*) hash_find (s7_dependency_insn_hsh
, name
);
2329 return s7_D_all_insn
;
2333 s7_check_dependency (char *pre_insn
, char *pre_reg
,
2334 char *cur_insn
, char *cur_reg
, int *warn_or_error
)
2338 enum s7_insn_type_for_dependency pre_insn_type
;
2339 enum s7_insn_type_for_dependency cur_insn_type
;
2341 pre_insn_type
= s7_dependency_type_from_insn (pre_insn
);
2342 cur_insn_type
= s7_dependency_type_from_insn (cur_insn
);
2344 for (i
= 0; i
< sizeof (s7_data_dependency_table
) / sizeof (s7_data_dependency_table
[0]); i
++)
2346 if ((pre_insn_type
== s7_data_dependency_table
[i
].pre_insn_type
)
2347 && (s7_D_all_insn
== s7_data_dependency_table
[i
].cur_insn_type
2348 || cur_insn_type
== s7_data_dependency_table
[i
].cur_insn_type
)
2349 && (strcmp (s7_data_dependency_table
[i
].pre_reg
, "") == 0
2350 || strcmp (s7_data_dependency_table
[i
].pre_reg
, pre_reg
) == 0)
2351 && (strcmp (s7_data_dependency_table
[i
].cur_reg
, "") == 0
2352 || strcmp (s7_data_dependency_table
[i
].cur_reg
, cur_reg
) == 0))
2354 if (s7_vector_size
== s7_SCORE5_PIPELINE
)
2355 bubbles
= s7_data_dependency_table
[i
].bubblenum_5
;
2357 bubbles
= s7_data_dependency_table
[i
].bubblenum_7
;
2358 *warn_or_error
= s7_data_dependency_table
[i
].warn_or_error
;
2366 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
2367 for use in the a.out file, and stores them in the array pointed to by buf.
2368 This knows about the endian-ness of the target machine and does
2369 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
2370 2 (short) and 4 (long) Floating numbers are put out as a series of
2371 LITTLENUMS (shorts, here at least). */
2374 s7_number_to_chars (char *buf
, valueT val
, int n
)
2376 if (target_big_endian
)
2377 number_to_chars_bigendian (buf
, val
, n
);
2379 number_to_chars_littleendian (buf
, val
, n
);
2383 s7_build_one_frag (struct s7_score_it one_inst
)
2386 int relaxable_p
= s7_g_opt
;
2389 /* Start a new frag if frag_now is not empty. */
2390 if (frag_now_fix () != 0)
2392 if (!frag_now
->tc_frag_data
.is_insn
)
2393 frag_wane (frag_now
);
2399 p
= frag_more (one_inst
.size
);
2400 s7_number_to_chars (p
, one_inst
.instruction
, one_inst
.size
);
2403 dwarf2_emit_insn (one_inst
.size
);
2406 relaxable_p
&= (one_inst
.relax_size
!= 0);
2407 relax_size
= relaxable_p
? one_inst
.relax_size
: 0;
2409 p
= frag_var (rs_machine_dependent
, relax_size
+ s7_RELAX_PAD_BYTE
, 0,
2410 s7_RELAX_ENCODE (one_inst
.size
, one_inst
.relax_size
,
2411 one_inst
.type
, 0, 0, relaxable_p
),
2415 s7_number_to_chars (p
, one_inst
.relax_inst
, relax_size
);
2419 s7_handle_dependency (struct s7_score_it
*theinst
)
2422 int warn_or_error
= 0; /* warn - 0; error - 1 */
2424 int remainder_bubbles
= 0;
2425 char cur_insn
[s7_INSN_NAME_LEN
];
2426 char pre_insn
[s7_INSN_NAME_LEN
];
2427 struct s7_score_it nop_inst
;
2428 struct s7_score_it pflush_inst
;
2430 nop_inst
.instruction
= 0x0000;
2432 nop_inst
.relax_inst
= 0x80008000;
2433 nop_inst
.relax_size
= 4;
2434 nop_inst
.type
= NO16_OPD
;
2436 pflush_inst
.instruction
= 0x8000800a;
2437 pflush_inst
.size
= 4;
2438 pflush_inst
.relax_inst
= 0x8000;
2439 pflush_inst
.relax_size
= 0;
2440 pflush_inst
.type
= NO_OPD
;
2442 /* pflush will clear all data dependency. */
2443 if (strcmp (theinst
->name
, "pflush") == 0)
2445 s7_init_dependency_vector ();
2449 /* Push current instruction to s7_dependency_vector[0]. */
2450 for (i
= s7_vector_size
- 1; i
> 0; i
--)
2451 memcpy (&s7_dependency_vector
[i
], &s7_dependency_vector
[i
- 1], sizeof (s7_dependency_vector
[i
]));
2453 memcpy (&s7_dependency_vector
[0], theinst
, sizeof (s7_dependency_vector
[i
]));
2455 /* There is no dependency between nop and any instruction. */
2456 if (strcmp (s7_dependency_vector
[0].name
, "nop") == 0
2457 || strcmp (s7_dependency_vector
[0].name
, "nop!") == 0)
2460 /* "pce" is defined in s7_insn_to_dependency_table. */
2461 #define PCE_NAME "pce"
2463 if (s7_dependency_vector
[0].type
== Insn_Type_PCE
)
2464 strcpy (cur_insn
, PCE_NAME
);
2466 strcpy (cur_insn
, s7_dependency_vector
[0].name
);
2468 for (i
= 1; i
< s7_vector_size
; i
++)
2470 /* The element of s7_dependency_vector is NULL. */
2471 if (s7_dependency_vector
[i
].name
[0] == '\0')
2474 if (s7_dependency_vector
[i
].type
== Insn_Type_PCE
)
2475 strcpy (pre_insn
, PCE_NAME
);
2477 strcpy (pre_insn
, s7_dependency_vector
[i
].name
);
2479 bubbles
= s7_check_dependency (pre_insn
, s7_dependency_vector
[i
].reg
,
2480 cur_insn
, s7_dependency_vector
[0].reg
, &warn_or_error
);
2481 remainder_bubbles
= bubbles
- i
+ 1;
2483 if (remainder_bubbles
> 0)
2487 if (s7_fix_data_dependency
== 1)
2489 if (remainder_bubbles
<= 2)
2491 if (s7_warn_fix_data_dependency
)
2492 as_warn (_("Fix data dependency: %s %s -- %s %s (insert %d nop!/%d)"),
2493 s7_dependency_vector
[i
].name
, s7_dependency_vector
[i
].reg
,
2494 s7_dependency_vector
[0].name
, s7_dependency_vector
[0].reg
,
2495 remainder_bubbles
, bubbles
);
2497 for (j
= (s7_vector_size
- 1); (j
- remainder_bubbles
) > 0; j
--)
2498 memcpy (&s7_dependency_vector
[j
], &s7_dependency_vector
[j
- remainder_bubbles
],
2499 sizeof (s7_dependency_vector
[j
]));
2501 for (j
= 1; j
<= remainder_bubbles
; j
++)
2503 memset (&s7_dependency_vector
[j
], '\0', sizeof (s7_dependency_vector
[j
]));
2505 s7_build_one_frag (nop_inst
);
2510 if (s7_warn_fix_data_dependency
)
2511 as_warn (_("Fix data dependency: %s %s -- %s %s (insert 1 pflush/%d)"),
2512 s7_dependency_vector
[i
].name
, s7_dependency_vector
[i
].reg
,
2513 s7_dependency_vector
[0].name
, s7_dependency_vector
[0].reg
,
2516 for (j
= 1; j
< s7_vector_size
; j
++)
2517 memset (&s7_dependency_vector
[j
], '\0', sizeof (s7_dependency_vector
[j
]));
2519 /* Insert pflush. */
2520 s7_build_one_frag (pflush_inst
);
2527 as_bad (_("data dependency: %s %s -- %s %s (%d/%d bubble)"),
2528 s7_dependency_vector
[i
].name
, s7_dependency_vector
[i
].reg
,
2529 s7_dependency_vector
[0].name
, s7_dependency_vector
[0].reg
,
2530 remainder_bubbles
, bubbles
);
2534 as_warn (_("data dependency: %s %s -- %s %s (%d/%d bubble)"),
2535 s7_dependency_vector
[i
].name
, s7_dependency_vector
[i
].reg
,
2536 s7_dependency_vector
[0].name
, s7_dependency_vector
[0].reg
,
2537 remainder_bubbles
, bubbles
);
2544 static enum insn_class
2545 s7_get_insn_class_from_type (enum score_insn_type type
)
2547 enum insn_class retval
= (int) s7_FAIL
;
2553 case Rd_rvalueBP_I5
:
2554 case Rd_lvalueBP_I5
:
2565 retval
= INSN_CLASS_16
;
2574 case Rd_rvalueRs_SI10
:
2575 case Rd_lvalueRs_SI10
:
2576 case Rd_rvalueRs_preSI12
:
2577 case Rd_rvalueRs_postSI12
:
2578 case Rd_lvalueRs_preSI12
:
2579 case Rd_lvalueRs_postSI12
:
2581 case Rd_rvalueRs_SI15
:
2582 case Rd_lvalueRs_SI15
:
2591 case OP5_rvalueRs_SI15
:
2592 case I5_Rs_Rs_I5_OP5
:
2593 case x_rvalueRs_post4
:
2594 case Rd_rvalueRs_post4
:
2596 case Rd_lvalueRs_post4
:
2597 case x_lvalueRs_post4
:
2605 retval
= INSN_CLASS_32
;
2608 retval
= INSN_CLASS_PCE
;
2611 retval
= INSN_CLASS_SYN
;
2620 static unsigned long
2621 s7_adjust_paritybit (unsigned long m_code
, enum insn_class i_class
)
2623 unsigned long result
= 0;
2624 unsigned long m_code_high
= 0;
2625 unsigned long m_code_low
= 0;
2626 unsigned long pb_high
= 0;
2627 unsigned long pb_low
= 0;
2629 if (i_class
== INSN_CLASS_32
)
2631 pb_high
= 0x80000000;
2632 pb_low
= 0x00008000;
2634 else if (i_class
== INSN_CLASS_16
)
2639 else if (i_class
== INSN_CLASS_PCE
)
2642 pb_low
= 0x00008000;
2644 else if (i_class
== INSN_CLASS_SYN
)
2646 /* FIXME. at this time, INSN_CLASS_SYN must be 32 bit, but, instruction type should
2647 be changed if macro instruction has been expanded. */
2648 pb_high
= 0x80000000;
2649 pb_low
= 0x00008000;
2656 m_code_high
= m_code
& 0x3fff8000;
2657 m_code_low
= m_code
& 0x00007fff;
2658 result
= pb_high
| (m_code_high
<< 1) | pb_low
| m_code_low
;
2664 s7_gen_insn_frag (struct s7_score_it
*part_1
, struct s7_score_it
*part_2
)
2667 bfd_boolean pce_p
= FALSE
;
2668 int relaxable_p
= s7_g_opt
;
2670 struct s7_score_it
*inst1
= part_1
;
2671 struct s7_score_it
*inst2
= part_2
;
2672 struct s7_score_it backup_inst1
;
2674 pce_p
= (inst2
) ? TRUE
: FALSE
;
2675 memcpy (&backup_inst1
, inst1
, sizeof (struct s7_score_it
));
2677 /* Adjust instruction opcode and to be relaxed instruction opcode. */
2680 backup_inst1
.instruction
= ((backup_inst1
.instruction
& 0x7FFF) << 15)
2681 | (inst2
->instruction
& 0x7FFF);
2682 backup_inst1
.instruction
= s7_adjust_paritybit (backup_inst1
.instruction
, INSN_CLASS_PCE
);
2683 if (!target_big_endian
)
2685 unsigned long tmp
= backup_inst1
.instruction
;
2686 backup_inst1
.instruction
= ((tmp
& 0xffff) << 16)
2689 backup_inst1
.relax_inst
= 0x8000;
2690 backup_inst1
.size
= s7_INSN_SIZE
;
2691 backup_inst1
.relax_size
= 0;
2692 backup_inst1
.type
= Insn_Type_PCE
;
2696 backup_inst1
.instruction
= s7_adjust_paritybit (backup_inst1
.instruction
,
2697 s7_GET_INSN_CLASS (backup_inst1
.type
));
2700 if (backup_inst1
.relax_size
!= 0)
2702 enum insn_class tmp
;
2704 tmp
= (backup_inst1
.size
== s7_INSN_SIZE
) ? INSN_CLASS_16
: INSN_CLASS_32
;
2705 backup_inst1
.relax_inst
= s7_adjust_paritybit (backup_inst1
.relax_inst
, tmp
);
2708 /* Check data dependency. */
2709 s7_handle_dependency (&backup_inst1
);
2711 /* Start a new frag if frag_now is not empty and is not instruction frag, maybe it contains
2712 data produced by .ascii etc. Doing this is to make one instruction per frag. */
2713 if (frag_now_fix () != 0)
2715 if (!frag_now
->tc_frag_data
.is_insn
)
2716 frag_wane (frag_now
);
2721 /* Here, we must call frag_grow in order to keep the instruction frag type is
2722 rs_machine_dependent.
2723 For, frag_var may change frag_now->fr_type to rs_fill by calling frag_grow which
2724 actually will call frag_wane.
2725 Calling frag_grow first will create a new frag_now which free size is 20 that is enough
2729 p
= frag_more (backup_inst1
.size
);
2730 s7_number_to_chars (p
, backup_inst1
.instruction
, backup_inst1
.size
);
2733 dwarf2_emit_insn (backup_inst1
.size
);
2736 /* Generate fixup structure. */
2739 if (inst1
->reloc
.type
!= BFD_RELOC_NONE
)
2740 s7_fix_new_score (frag_now
, p
- frag_now
->fr_literal
,
2741 inst1
->size
, &inst1
->reloc
.exp
,
2742 inst1
->reloc
.pc_rel
, inst1
->reloc
.type
);
2744 if (inst2
->reloc
.type
!= BFD_RELOC_NONE
)
2745 s7_fix_new_score (frag_now
, p
- frag_now
->fr_literal
+ 2,
2746 inst2
->size
, &inst2
->reloc
.exp
, inst2
->reloc
.pc_rel
, inst2
->reloc
.type
);
2750 if (backup_inst1
.reloc
.type
!= BFD_RELOC_NONE
)
2751 s7_fix_new_score (frag_now
, p
- frag_now
->fr_literal
,
2752 backup_inst1
.size
, &backup_inst1
.reloc
.exp
,
2753 backup_inst1
.reloc
.pc_rel
, backup_inst1
.reloc
.type
);
2756 /* relax_size may be 2, 4, 12 or 0, 0 indicates no relaxation. */
2757 relaxable_p
&= (backup_inst1
.relax_size
!= 0);
2758 relax_size
= relaxable_p
? backup_inst1
.relax_size
: 0;
2760 p
= frag_var (rs_machine_dependent
, relax_size
+ s7_RELAX_PAD_BYTE
, 0,
2761 s7_RELAX_ENCODE (backup_inst1
.size
, backup_inst1
.relax_size
,
2762 backup_inst1
.type
, 0, 0, relaxable_p
),
2763 backup_inst1
.reloc
.exp
.X_add_symbol
, 0, NULL
);
2766 s7_number_to_chars (p
, backup_inst1
.relax_inst
, relax_size
);
2768 memcpy (inst1
, &backup_inst1
, sizeof (struct s7_score_it
));
2772 s7_parse_16_32_inst (char *insnstr
, bfd_boolean gen_frag_p
)
2776 char *operator = insnstr
;
2777 const struct s7_asm_opcode
*opcode
;
2779 /* Parse operator and operands. */
2780 s7_skip_whitespace (operator);
2782 for (p
= operator; *p
!= '\0'; p
++)
2783 if ((*p
== ' ') || (*p
== '!'))
2792 opcode
= (const struct s7_asm_opcode
*) hash_find (s7_score_ops_hsh
, operator);
2795 memset (&s7_inst
, '\0', sizeof (s7_inst
));
2796 strcpy (s7_inst
.str
, insnstr
);
2799 s7_inst
.instruction
= opcode
->value
;
2800 s7_inst
.relax_inst
= opcode
->relax_value
;
2801 s7_inst
.type
= opcode
->type
;
2802 s7_inst
.size
= s7_GET_INSN_SIZE (s7_inst
.type
);
2803 s7_inst
.relax_size
= 0;
2805 strcpy (s7_inst
.name
, opcode
->template_name
);
2806 strcpy (s7_inst
.reg
, "");
2807 s7_inst
.error
= NULL
;
2808 s7_inst
.reloc
.type
= BFD_RELOC_NONE
;
2810 (*opcode
->parms
) (p
);
2812 /* It indicates current instruction is a macro instruction if s7_inst.bwarn equals -1. */
2813 if ((s7_inst
.bwarn
!= -1) && (!s7_inst
.error
) && (gen_frag_p
))
2814 s7_gen_insn_frag (&s7_inst
, NULL
);
2817 s7_inst
.error
= _("unrecognized opcode");
2821 s7_append_insn (char *str
, bfd_boolean gen_frag_p
)
2823 int retval
= s7_SUCCESS
;
2825 s7_parse_16_32_inst (str
, gen_frag_p
);
2829 retval
= (int) s7_FAIL
;
2830 as_bad (_("%s -- `%s'"), s7_inst
.error
, s7_inst
.str
);
2831 s7_inst
.error
= NULL
;
2837 /* Handle mv! reg_high, reg_low;
2838 mv! reg_low, reg_high;
2839 mv! reg_low, reg_low; */
2841 s7_do16_mv_rdrs (char *str
)
2845 char *backupstr
= NULL
;
2848 s7_skip_whitespace (str
);
2850 if ((reg_rd
= s7_reg_required_here (&str
, 8, s7_REG_TYPE_SCORE
)) == (int) s7_FAIL
2851 || s7_skip_past_comma (&str
) == (int) s7_FAIL
2852 || (reg_rs
= s7_reg_required_here (&str
, 4, s7_REG_TYPE_SCORE
)) == (int) s7_FAIL
2853 || s7_end_of_line (str
) == (int) s7_FAIL
)
2859 /* Case 1 : mv! or mlfh!. */
2864 s7_inst
.relax_inst
|= (((s7_inst
.instruction
>> 8) & 0xf) << 20)
2865 | (((s7_inst
.instruction
>> 4) & 0xf) << 15) | (0xf << 10);
2866 s7_inst
.relax_size
= 4;
2870 char append_str
[s7_MAX_LITERAL_POOL_SIZE
];
2872 sprintf (append_str
, "mlfh! %s", backupstr
);
2873 if (s7_append_insn (append_str
, TRUE
) == (int) s7_FAIL
)
2875 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
2879 /* Case 2 : mhfl!. */
2884 s7_SET_INSN_ERROR (s7_BAD_ARGS
);
2889 char append_str
[s7_MAX_LITERAL_POOL_SIZE
];
2891 sprintf (append_str
, "mhfl! %s", backupstr
);
2892 if (s7_append_insn (append_str
, TRUE
) == (int) s7_FAIL
)
2895 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
2903 s7_do16_rdi4 (char *str
)
2905 s7_skip_whitespace (str
);
2907 if (s7_reglow_required_here (&str
, 8) == (int) s7_FAIL
2908 || s7_skip_past_comma (&str
) == (int) s7_FAIL
2909 || s7_data_op2 (&str
, 3, _IMM4
) == (int) s7_FAIL
2910 || s7_end_of_line (str
) == (int) s7_FAIL
)
2916 if (((s7_inst
.instruction
>> 3) & 0x10) == 0) /* for judge is addei or subei : bit 5 =0 : addei */
2918 if (((s7_inst
.instruction
>> 3) & 0xf) != 0xf)
2920 s7_inst
.relax_inst
|= (((s7_inst
.instruction
>> 8) & 0xf) << 20)
2921 | ((1 << ((s7_inst
.instruction
>> 3) & 0xf)) << 1);
2922 s7_inst
.relax_size
= 4;
2926 s7_inst
.relax_inst
= 0x8000;
2931 if (((s7_inst
.instruction
>> 3) & 0xf) != 0xf)
2933 s7_inst
.relax_inst
|= (((s7_inst
.instruction
>> 8) & 0xf) << 20)
2934 | (((-(1 << ((s7_inst
.instruction
>> 3) & 0xf))) & 0xffff) << 1);
2935 s7_inst
.relax_size
= 4;
2939 s7_inst
.relax_inst
= 0x8000;
2946 s7_do16_rdi5 (char *str
)
2948 s7_skip_whitespace (str
);
2950 if (s7_reglow_required_here (&str
, 8) == (int) s7_FAIL
2951 || s7_skip_past_comma (&str
) == (int) s7_FAIL
2952 || s7_data_op2 (&str
, 3, _IMM5
) == (int) s7_FAIL
2953 || s7_end_of_line (str
) == (int) s7_FAIL
)
2957 s7_inst
.relax_inst
|= (((s7_inst
.instruction
>> 8) & 0xf) << 20)
2958 | (((s7_inst
.instruction
>> 8) & 0xf) << 15) | (((s7_inst
.instruction
>> 3) & 0x1f) << 10);
2959 s7_inst
.relax_size
= 4;
2966 s7_do16_xi5 (char *str
)
2968 s7_skip_whitespace (str
);
2970 if (s7_data_op2 (&str
, 3, _IMM5
) == (int) s7_FAIL
|| s7_end_of_line (str
) == (int) s7_FAIL
)
2974 s7_inst
.relax_inst
|= (((s7_inst
.instruction
>> 3) & 0x1f) << 15);
2975 s7_inst
.relax_size
= 4;
2979 /* Check that an immediate is word alignment or half word alignment.
2980 If so, convert it to the right format. */
2983 s7_validate_immediate_align (int val
, unsigned int data_type
)
2985 if (data_type
== _IMM5_RSHIFT_1
)
2989 s7_inst
.error
= _("address offset must be half word alignment");
2990 return (int) s7_FAIL
;
2993 else if ((data_type
== _IMM5_RSHIFT_2
) || (data_type
== _IMM10_RSHIFT_2
))
2997 s7_inst
.error
= _("address offset must be word alignment");
2998 return (int) s7_FAIL
;
3006 s7_exp_ldst_offset (char **str
, int shift
, unsigned int data_type
)
3013 if ((dataptr
!= NULL
)
3014 && (((strstr (dataptr
, "0x")) != NULL
)
3015 || ((strstr (dataptr
, "0X")) != NULL
)))
3018 if ((data_type
!= _SIMM16_LA
)
3019 && (data_type
!= _VALUE_HI16
)
3020 && (data_type
!= _VALUE_LO16
)
3021 && (data_type
!= _IMM16
)
3022 && (data_type
!= _IMM15
)
3023 && (data_type
!= _IMM14
)
3024 && (data_type
!= _IMM4
)
3025 && (data_type
!= _IMM5
)
3026 && (data_type
!= _IMM8
)
3027 && (data_type
!= _IMM5_RSHIFT_1
)
3028 && (data_type
!= _IMM5_RSHIFT_2
)
3029 && (data_type
!= _SIMM12
)
3030 && (data_type
!= _SIMM15
)
3031 && (data_type
!= _SIMM14_NEG
)
3032 && (data_type
!= _IMM10_RSHIFT_2
))
3038 if (s7_my_get_expression (&s7_inst
.reloc
.exp
, str
) == (int) s7_FAIL
)
3039 return (int) s7_FAIL
;
3041 if (s7_inst
.reloc
.exp
.X_op
== O_constant
)
3043 /* Need to check the immediate align. */
3044 int value
= s7_validate_immediate_align (s7_inst
.reloc
.exp
.X_add_number
, data_type
);
3046 if (value
== (int) s7_FAIL
)
3047 return (int) s7_FAIL
;
3049 value
= s7_validate_immediate (s7_inst
.reloc
.exp
.X_add_number
, data_type
, hex_p
);
3050 if (value
== (int) s7_FAIL
)
3053 sprintf (s7_err_msg
,
3054 _("invalid constant: %d bit expression not in range %d..%d"),
3055 s7_score_df_range
[data_type
].bits
,
3056 s7_score_df_range
[data_type
].range
[0], s7_score_df_range
[data_type
].range
[1]);
3058 sprintf (s7_err_msg
,
3059 _("invalid constant: %d bit expression not in range %d..%d"),
3060 s7_score_df_range
[data_type
- 24].bits
,
3061 s7_score_df_range
[data_type
- 24].range
[0], s7_score_df_range
[data_type
- 24].range
[1]);
3062 s7_inst
.error
= s7_err_msg
;
3063 return (int) s7_FAIL
;
3066 if (data_type
== _IMM5_RSHIFT_1
)
3070 else if ((data_type
== _IMM5_RSHIFT_2
) || (data_type
== _IMM10_RSHIFT_2
))
3075 if (s7_score_df_range
[data_type
].range
[0] != 0)
3077 value
&= (1 << s7_score_df_range
[data_type
].bits
) - 1;
3080 s7_inst
.instruction
|= value
<< shift
;
3084 s7_inst
.reloc
.pc_rel
= 0;
3091 s7_do_ldst_insn (char *str
)
3103 s7_skip_whitespace (str
);
3105 if (((conflict_reg
= s7_reg_required_here (&str
, 20, s7_REG_TYPE_SCORE
)) == (int) s7_FAIL
)
3106 || (s7_skip_past_comma (&str
) == (int) s7_FAIL
))
3109 /* ld/sw rD, [rA, simm15] ld/sw rD, [rA]+, simm12 ld/sw rD, [rA, simm12]+. */
3113 s7_skip_whitespace (str
);
3115 if ((reg
= s7_reg_required_here (&str
, 15, s7_REG_TYPE_SCORE
)) == (int) s7_FAIL
)
3118 /* Conflicts can occur on stores as well as loads. */
3119 conflict_reg
= (conflict_reg
== reg
);
3120 s7_skip_whitespace (str
);
3121 temp
= str
+ 1; /* The latter will process decimal/hex expression. */
3123 /* ld/sw rD, [rA]+, simm12 ld/sw rD, [rA]+. */
3130 /* ld/sw rD, [rA]+, simm12. */
3131 if (s7_skip_past_comma (&str
) == s7_SUCCESS
)
3133 if ((s7_exp_ldst_offset (&str
, 3, _SIMM12
) == (int) s7_FAIL
)
3134 || (s7_end_of_line (str
) == (int) s7_FAIL
))
3139 unsigned int ldst_func
= s7_inst
.instruction
& OPC_PSEUDOLDST_MASK
;
3141 if ((ldst_func
== INSN_LH
)
3142 || (ldst_func
== INSN_LHU
)
3143 || (ldst_func
== INSN_LW
)
3144 || (ldst_func
== INSN_LB
)
3145 || (ldst_func
== INSN_LBU
))
3147 s7_inst
.error
= _("register same as write-back base");
3152 ldst_idx
= s7_inst
.instruction
& OPC_PSEUDOLDST_MASK
;
3153 s7_inst
.instruction
&= ~OPC_PSEUDOLDST_MASK
;
3154 s7_inst
.instruction
|= s7_score_ldst_insns
[ldst_idx
* 3 + LDST_POST
].value
;
3156 /* lw rD, [rA]+, 4 convert to pop rD, [rA]. */
3157 if ((s7_inst
.instruction
& 0x3e000007) == 0x0e000000)
3159 /* rs = r0-r7, offset = 4 */
3160 if ((((s7_inst
.instruction
>> 15) & 0x18) == 0)
3161 && (((s7_inst
.instruction
>> 3) & 0xfff) == 4))
3163 /* Relax to pophi. */
3164 if ((((s7_inst
.instruction
>> 20) & 0x10) == 0x10))
3166 s7_inst
.relax_inst
= 0x0000200a | (((s7_inst
.instruction
>> 20) & 0xf)
3168 (((s7_inst
.instruction
>> 15) & 0x7) << 4);
3173 s7_inst
.relax_inst
= 0x0000200a | (((s7_inst
.instruction
>> 20) & 0xf)
3175 (((s7_inst
.instruction
>> 15) & 0x7) << 4);
3177 s7_inst
.relax_size
= 2;
3182 /* ld/sw rD, [rA]+ convert to ld/sw rD, [rA, 0]+. */
3185 s7_SET_INSN_ERROR (NULL
);
3186 if (s7_end_of_line (str
) == (int) s7_FAIL
)
3192 value
= s7_validate_immediate (s7_inst
.reloc
.exp
.X_add_number
, _SIMM12
, 0);
3193 value
&= (1 << s7_score_df_range
[_SIMM12
].bits
) - 1;
3194 ldst_idx
= s7_inst
.instruction
& OPC_PSEUDOLDST_MASK
;
3195 s7_inst
.instruction
&= ~OPC_PSEUDOLDST_MASK
;
3196 s7_inst
.instruction
|= s7_score_ldst_insns
[ldst_idx
* 3 + pre_inc
].value
;
3197 s7_inst
.instruction
|= value
<< 3;
3198 s7_inst
.relax_inst
= 0x8000;
3202 /* ld/sw rD, [rA] convert to ld/sw rD, [rA, simm15]. */
3205 if (s7_end_of_line (str
) == (int) s7_FAIL
)
3208 ldst_idx
= s7_inst
.instruction
& OPC_PSEUDOLDST_MASK
;
3209 s7_inst
.instruction
&= ~OPC_PSEUDOLDST_MASK
;
3210 s7_inst
.instruction
|= s7_score_ldst_insns
[ldst_idx
* 3 + LDST_NOUPDATE
].value
;
3212 /* lbu rd, [rs] -> lbu! rd, [rs] */
3213 if (ldst_idx
== INSN_LBU
)
3215 s7_inst
.relax_inst
= INSN16_LBU
;
3217 else if (ldst_idx
== INSN_LH
)
3219 s7_inst
.relax_inst
= INSN16_LH
;
3221 else if (ldst_idx
== INSN_LW
)
3223 s7_inst
.relax_inst
= INSN16_LW
;
3225 else if (ldst_idx
== INSN_SB
)
3227 s7_inst
.relax_inst
= INSN16_SB
;
3229 else if (ldst_idx
== INSN_SH
)
3231 s7_inst
.relax_inst
= INSN16_SH
;
3233 else if (ldst_idx
== INSN_SW
)
3235 s7_inst
.relax_inst
= INSN16_SW
;
3239 s7_inst
.relax_inst
= 0x8000;
3242 /* lw/lh/lbu/sw/sh/sb, offset = 0, relax to 16 bit instruction. */
3243 if ((ldst_idx
== INSN_LBU
)
3244 || (ldst_idx
== INSN_LH
)
3245 || (ldst_idx
== INSN_LW
)
3246 || (ldst_idx
== INSN_SB
) || (ldst_idx
== INSN_SH
) || (ldst_idx
== INSN_SW
))
3248 if ((((s7_inst
.instruction
>> 15) & 0x10) == 0) && (((s7_inst
.instruction
>> 20) & 0x10) == 0))
3250 s7_inst
.relax_inst
|= (2 << 12) | (((s7_inst
.instruction
>> 20) & 0xf) << 8) |
3251 (((s7_inst
.instruction
>> 15) & 0xf) << 4);
3252 s7_inst
.relax_size
= 2;
3259 /* ld/sw rD, [rA, simm15] ld/sw rD, [rA, simm12]+. */
3262 if (s7_skip_past_comma (&str
) == (int) s7_FAIL
)
3264 s7_inst
.error
= _("pre-indexed expression expected");
3268 if (s7_my_get_expression (&s7_inst
.reloc
.exp
, &str
) == (int) s7_FAIL
)
3271 s7_skip_whitespace (str
);
3274 s7_inst
.error
= _("missing ]");
3278 s7_skip_whitespace (str
);
3279 /* ld/sw rD, [rA, simm12]+. */
3286 unsigned int ldst_func
= s7_inst
.instruction
& OPC_PSEUDOLDST_MASK
;
3288 if ((ldst_func
== INSN_LH
)
3289 || (ldst_func
== INSN_LHU
)
3290 || (ldst_func
== INSN_LW
)
3291 || (ldst_func
== INSN_LB
)
3292 || (ldst_func
== INSN_LBU
))
3294 s7_inst
.error
= _("register same as write-back base");
3300 if (s7_end_of_line (str
) == (int) s7_FAIL
)
3303 if (s7_inst
.reloc
.exp
.X_op
== O_constant
)
3305 unsigned int data_type
;
3308 data_type
= _SIMM12
;
3310 data_type
= _SIMM15
;
3313 if ((dataptr
!= NULL
)
3314 && (((strstr (dataptr
, "0x")) != NULL
)
3315 || ((strstr (dataptr
, "0X")) != NULL
)))
3318 if ((data_type
!= _SIMM16_LA
)
3319 && (data_type
!= _VALUE_HI16
)
3320 && (data_type
!= _VALUE_LO16
)
3321 && (data_type
!= _IMM16
)
3322 && (data_type
!= _IMM15
)
3323 && (data_type
!= _IMM14
)
3324 && (data_type
!= _IMM4
)
3325 && (data_type
!= _IMM5
)
3326 && (data_type
!= _IMM8
)
3327 && (data_type
!= _SIMM12
)
3328 && (data_type
!= _SIMM15
)
3329 && (data_type
!= _IMM5_RSHIFT_1
)
3330 && (data_type
!= _IMM5_RSHIFT_2
)
3331 && (data_type
!= _SIMM14_NEG
)
3332 && (data_type
!= _IMM10_RSHIFT_2
))
3338 value
= s7_validate_immediate (s7_inst
.reloc
.exp
.X_add_number
, data_type
, hex_p
);
3339 if (value
== (int) s7_FAIL
)
3342 sprintf (s7_err_msg
,
3343 _("invalid constant: %d bit expression not in range %d..%d"),
3344 s7_score_df_range
[data_type
].bits
,
3345 s7_score_df_range
[data_type
].range
[0], s7_score_df_range
[data_type
].range
[1]);
3347 sprintf (s7_err_msg
,
3348 _("invalid constant: %d bit expression not in range %d..%d"),
3349 s7_score_df_range
[data_type
- 24].bits
,
3350 s7_score_df_range
[data_type
- 24].range
[0],
3351 s7_score_df_range
[data_type
- 24].range
[1]);
3352 s7_inst
.error
= s7_err_msg
;
3356 value
&= (1 << s7_score_df_range
[data_type
].bits
) - 1;
3357 ldst_idx
= s7_inst
.instruction
& OPC_PSEUDOLDST_MASK
;
3358 s7_inst
.instruction
&= ~OPC_PSEUDOLDST_MASK
;
3359 s7_inst
.instruction
|= s7_score_ldst_insns
[ldst_idx
* 3 + pre_inc
].value
;
3361 s7_inst
.instruction
|= value
<< 3;
3363 s7_inst
.instruction
|= value
;
3365 /* lw rD, [rA, simm15] */
3366 if ((s7_inst
.instruction
& 0x3e000000) == 0x20000000)
3368 /* Both rD and rA are in [r0 - r15]. */
3369 if ((((s7_inst
.instruction
>> 15) & 0x10) == 0)
3370 && (((s7_inst
.instruction
>> 20) & 0x10) == 0))
3372 /* simm15 = 0, lw -> lw!. */
3373 if ((s7_inst
.instruction
& 0x7fff) == 0)
3375 s7_inst
.relax_inst
|= (((s7_inst
.instruction
>> 15) & 0xf) << 4)
3376 | (((s7_inst
.instruction
>> 20) & 0xf) << 8);
3377 s7_inst
.relax_size
= 2;
3379 /* rA = r2, lw -> lwp!. */
3380 else if ((((s7_inst
.instruction
>> 15) & 0xf) == 2)
3381 && ((s7_inst
.instruction
& 0x3) == 0)
3382 && ((s7_inst
.instruction
& 0x7fff) < 128))
3384 s7_inst
.relax_inst
= 0x7000 | (((s7_inst
.instruction
>> 20) & 0xf) << 8)
3385 | (((s7_inst
.instruction
& 0x7fff) >> 2) << 3);
3386 s7_inst
.relax_size
= 2;
3390 s7_inst
.relax_inst
= 0x8000;
3395 s7_inst
.relax_inst
= 0x8000;
3398 /* sw rD, [rA, simm15] */
3399 else if ((s7_inst
.instruction
& 0x3e000000) == 0x28000000)
3401 /* Both rD and rA are in [r0 - r15]. */
3402 if ((((s7_inst
.instruction
>> 15) & 0x10) == 0) && (((s7_inst
.instruction
>> 20) & 0x10) == 0))
3404 /* simm15 = 0, sw -> sw!. */
3405 if ((s7_inst
.instruction
& 0x7fff) == 0)
3407 s7_inst
.relax_inst
|= (((s7_inst
.instruction
>> 15) & 0xf) << 4)
3408 | (((s7_inst
.instruction
>> 20) & 0xf) << 8);
3409 s7_inst
.relax_size
= 2;
3411 /* rA = r2, sw -> swp!. */
3412 else if ((((s7_inst
.instruction
>> 15) & 0xf) == 2)
3413 && ((s7_inst
.instruction
& 0x3) == 0)
3414 && ((s7_inst
.instruction
& 0x7fff) < 128))
3416 s7_inst
.relax_inst
= 0x7004 | (((s7_inst
.instruction
>> 20) & 0xf) << 8)
3417 | (((s7_inst
.instruction
& 0x7fff) >> 2) << 3);
3418 s7_inst
.relax_size
= 2;
3422 s7_inst
.relax_inst
= 0x8000;
3427 s7_inst
.relax_inst
= 0x8000;
3430 /* sw rD, [rA, simm15]+ sw pre. */
3431 else if ((s7_inst
.instruction
& 0x3e000007) == 0x06000004)
3433 /* rA is in [r0 - r7], and simm15 = -4. */
3434 if ((((s7_inst
.instruction
>> 15) & 0x18) == 0)
3435 && (((s7_inst
.instruction
>> 3) & 0xfff) == 0xffc))
3437 /* sw -> pushhi!. */
3438 if ((((s7_inst
.instruction
>> 20) & 0x10) == 0x10))
3440 s7_inst
.relax_inst
= 0x0000200e | (((s7_inst
.instruction
>> 20) & 0xf) << 8)
3441 | 1 << 7 | (((s7_inst
.instruction
>> 15) & 0x7) << 4);
3442 s7_inst
.relax_size
= 2;
3447 s7_inst
.relax_inst
= 0x0000200e | (((s7_inst
.instruction
>> 20) & 0xf) << 8)
3448 | 0 << 7 | (((s7_inst
.instruction
>> 15) & 0x7) << 4);
3449 s7_inst
.relax_size
= 2;
3454 s7_inst
.relax_inst
= 0x8000;
3457 /* lh rD, [rA, simm15] */
3458 else if ((s7_inst
.instruction
& 0x3e000000) == 0x22000000)
3460 /* Both rD and rA are in [r0 - r15]. */
3461 if ((((s7_inst
.instruction
>> 15) & 0x10) == 0) && (((s7_inst
.instruction
>> 20) & 0x10) == 0))
3463 /* simm15 = 0, lh -> lh!. */
3464 if ((s7_inst
.instruction
& 0x7fff) == 0)
3466 s7_inst
.relax_inst
|= (((s7_inst
.instruction
>> 15) & 0xf) << 4)
3467 | (((s7_inst
.instruction
>> 20) & 0xf) << 8);
3468 s7_inst
.relax_size
= 2;
3470 /* rA = r2, lh -> lhp!. */
3471 else if ((((s7_inst
.instruction
>> 15) & 0xf) == 2)
3472 && ((s7_inst
.instruction
& 0x1) == 0)
3473 && ((s7_inst
.instruction
& 0x7fff) < 64))
3475 s7_inst
.relax_inst
= 0x7001 | (((s7_inst
.instruction
>> 20) & 0xf) << 8)
3476 | (((s7_inst
.instruction
& 0x7fff) >> 1) << 3);
3477 s7_inst
.relax_size
= 2;
3481 s7_inst
.relax_inst
= 0x8000;
3486 s7_inst
.relax_inst
= 0x8000;
3489 /* sh rD, [rA, simm15] */
3490 else if ((s7_inst
.instruction
& 0x3e000000) == 0x2a000000)
3492 /* Both rD and rA are in [r0 - r15]. */
3493 if ((((s7_inst
.instruction
>> 15) & 0x10) == 0) && (((s7_inst
.instruction
>> 20) & 0x10) == 0))
3495 /* simm15 = 0, sh -> sh!. */
3496 if ((s7_inst
.instruction
& 0x7fff) == 0)
3498 s7_inst
.relax_inst
|= (((s7_inst
.instruction
>> 15) & 0xf) << 4)
3499 | (((s7_inst
.instruction
>> 20) & 0xf) << 8);
3500 s7_inst
.relax_size
= 2;
3502 /* rA = r2, sh -> shp!. */
3503 else if ((((s7_inst
.instruction
>> 15) & 0xf) == 2)
3504 && ((s7_inst
.instruction
& 0x1) == 0)
3505 && ((s7_inst
.instruction
& 0x7fff) < 64))
3507 s7_inst
.relax_inst
= 0x7005 | (((s7_inst
.instruction
>> 20) & 0xf) << 8)
3508 | (((s7_inst
.instruction
& 0x7fff) >> 1) << 3);
3509 s7_inst
.relax_size
= 2;
3513 s7_inst
.relax_inst
= 0x8000;
3518 s7_inst
.relax_inst
= 0x8000;
3521 /* lbu rD, [rA, simm15] */
3522 else if ((s7_inst
.instruction
& 0x3e000000) == 0x2c000000)
3524 /* Both rD and rA are in [r0 - r15]. */
3525 if ((((s7_inst
.instruction
>> 15) & 0x10) == 0) && (((s7_inst
.instruction
>> 20) & 0x10) == 0))
3527 /* simm15 = 0, lbu -> lbu!. */
3528 if ((s7_inst
.instruction
& 0x7fff) == 0)
3530 s7_inst
.relax_inst
|= (((s7_inst
.instruction
>> 15) & 0xf) << 4)
3531 | (((s7_inst
.instruction
>> 20) & 0xf) << 8);
3532 s7_inst
.relax_size
= 2;
3534 /* rA = r2, lbu -> lbup!. */
3535 else if ((((s7_inst
.instruction
>> 15) & 0xf) == 2)
3536 && ((s7_inst
.instruction
& 0x7fff) < 32))
3538 s7_inst
.relax_inst
= 0x7003 | (((s7_inst
.instruction
>> 20) & 0xf) << 8)
3539 | ((s7_inst
.instruction
& 0x7fff) << 3);
3540 s7_inst
.relax_size
= 2;
3544 s7_inst
.relax_inst
= 0x8000;
3549 s7_inst
.relax_inst
= 0x8000;
3552 /* sb rD, [rA, simm15] */
3553 else if ((s7_inst
.instruction
& 0x3e000000) == 0x2e000000)
3555 /* Both rD and rA are in [r0 - r15]. */
3556 if ((((s7_inst
.instruction
>> 15) & 0x10) == 0) && (((s7_inst
.instruction
>> 20) & 0x10) == 0))
3558 /* simm15 = 0, sb -> sb!. */
3559 if ((s7_inst
.instruction
& 0x7fff) == 0)
3561 s7_inst
.relax_inst
|= (((s7_inst
.instruction
>> 15) & 0xf) << 4)
3562 | (((s7_inst
.instruction
>> 20) & 0xf) << 8);
3563 s7_inst
.relax_size
= 2;
3565 /* rA = r2, sb -> sb!. */
3566 else if ((((s7_inst
.instruction
>> 15) & 0xf) == 2)
3567 && ((s7_inst
.instruction
& 0x7fff) < 32))
3569 s7_inst
.relax_inst
= 0x7007 | (((s7_inst
.instruction
>> 20) & 0xf) << 8)
3570 | ((s7_inst
.instruction
& 0x7fff) << 3);
3571 s7_inst
.relax_size
= 2;
3575 s7_inst
.relax_inst
= 0x8000;
3580 s7_inst
.relax_inst
= 0x8000;
3585 s7_inst
.relax_inst
= 0x8000;
3592 /* FIXME: may set error, for there is no ld/sw rD, [rA, label] */
3593 s7_inst
.reloc
.pc_rel
= 0;
3599 s7_inst
.error
= s7_BAD_ARGS
;
3605 s7_do_cache (char *str
)
3607 s7_skip_whitespace (str
);
3609 if ((s7_data_op2 (&str
, 20, _IMM5
) == (int) s7_FAIL
) || (s7_skip_past_comma (&str
) == (int) s7_FAIL
))
3617 cache_op
= (s7_inst
.instruction
>> 20) & 0x1F;
3618 sprintf (s7_inst
.name
, "cache %d", cache_op
);
3624 s7_skip_whitespace (str
);
3626 if (s7_reg_required_here (&str
, 15, s7_REG_TYPE_SCORE
) == (int) s7_FAIL
)
3629 s7_skip_whitespace (str
);
3631 /* cache op, [rA] */
3632 if (s7_skip_past_comma (&str
) == (int) s7_FAIL
)
3634 s7_SET_INSN_ERROR (NULL
);
3637 s7_inst
.error
= _("missing ]");
3642 /* cache op, [rA, simm15] */
3645 if (s7_exp_ldst_offset (&str
, 0, _SIMM15
) == (int) s7_FAIL
)
3650 s7_skip_whitespace (str
);
3653 s7_inst
.error
= _("missing ]");
3658 if (s7_end_of_line (str
) == (int) s7_FAIL
)
3663 s7_inst
.error
= s7_BAD_ARGS
;
3668 s7_do_crdcrscrsimm5 (char *str
)
3673 s7_skip_whitespace (str
);
3675 if (s7_reg_required_here (&str
, 20, s7_REG_TYPE_SCORE_CR
) == (int) s7_FAIL
3676 || s7_skip_past_comma (&str
) == (int) s7_FAIL
3677 || s7_reg_required_here (&str
, 15, s7_REG_TYPE_SCORE_CR
) == (int) s7_FAIL
3678 || s7_skip_past_comma (&str
) == (int) s7_FAIL
3679 || s7_reg_required_here (&str
, 10, s7_REG_TYPE_SCORE_CR
) == (int) s7_FAIL
3680 || s7_skip_past_comma (&str
) == (int) s7_FAIL
)
3683 /* cop1 cop_code20. */
3684 if (s7_data_op2 (&str
, 5, _IMM20
) == (int) s7_FAIL
)
3689 if (s7_data_op2 (&str
, 5, _IMM5
) == (int) s7_FAIL
)
3693 s7_end_of_line (str
);
3696 /* Handle ldc/stc. */
3698 s7_do_ldst_cop (char *str
)
3700 s7_skip_whitespace (str
);
3702 if ((s7_reg_required_here (&str
, 15, s7_REG_TYPE_SCORE_CR
) == (int) s7_FAIL
)
3703 || (s7_skip_past_comma (&str
) == (int) s7_FAIL
))
3709 s7_skip_whitespace (str
);
3711 if (s7_reg_required_here (&str
, 20, s7_REG_TYPE_SCORE
) == (int) s7_FAIL
)
3714 s7_skip_whitespace (str
);
3718 if (s7_exp_ldst_offset (&str
, 5, _IMM10_RSHIFT_2
) == (int) s7_FAIL
)
3721 s7_skip_whitespace (str
);
3724 s7_inst
.error
= _("missing ]");
3729 s7_end_of_line (str
);
3732 s7_inst
.error
= s7_BAD_ARGS
;
3736 s7_do16_ldst_insn (char *str
)
3738 s7_skip_whitespace (str
);
3740 if ((s7_reglow_required_here (&str
, 8) == (int) s7_FAIL
) || (s7_skip_past_comma (&str
) == (int) s7_FAIL
))
3748 s7_skip_whitespace (str
);
3750 if ((reg
= s7_reglow_required_here (&str
, 4)) == (int) s7_FAIL
)
3753 s7_skip_whitespace (str
);
3756 if (s7_end_of_line (str
) == (int) s7_FAIL
)
3760 s7_inst
.relax_inst
|= (((s7_inst
.instruction
>> 8) & 0xf) << 20)
3761 | (((s7_inst
.instruction
>> 4) & 0xf) << 15);
3762 s7_inst
.relax_size
= 4;
3767 s7_inst
.error
= _("missing ]");
3772 s7_inst
.error
= s7_BAD_ARGS
;
3776 /* Handle lbup!/lhp!/ldiu!/lwp!/sbp!/shp!/swp!. */
3779 s7_do16_ldst_imm_insn (char *str
)
3781 char data_exp
[s7_MAX_LITERAL_POOL_SIZE
];
3783 char *dataptr
= NULL
, *pp
= NULL
;
3785 int assign_data
= (int) s7_FAIL
;
3786 unsigned int ldst_func
;
3788 s7_skip_whitespace (str
);
3790 if (((reg_rd
= s7_reglow_required_here (&str
, 8)) == (int) s7_FAIL
)
3791 || (s7_skip_past_comma (&str
) == (int) s7_FAIL
))
3794 s7_skip_whitespace (str
);
3797 while ((*dataptr
!= '\0') && (*dataptr
!= '|') && (cnt
<= s7_MAX_LITERAL_POOL_SIZE
))
3799 data_exp
[cnt
] = *dataptr
;
3804 data_exp
[cnt
] = '\0';
3809 ldst_func
= s7_inst
.instruction
& LDST16_RI_MASK
;
3810 if (ldst_func
== N16_LIU
)
3811 assign_data
= s7_exp_ldst_offset (&pp
, 0, _IMM8
);
3812 else if (ldst_func
== N16_LHP
|| ldst_func
== N16_SHP
)
3813 assign_data
= s7_exp_ldst_offset (&pp
, 3, _IMM5_RSHIFT_1
);
3814 else if (ldst_func
== N16_LWP
|| ldst_func
== N16_SWP
)
3815 assign_data
= s7_exp_ldst_offset (&pp
, 3, _IMM5_RSHIFT_2
);
3817 assign_data
= s7_exp_ldst_offset (&pp
, 3, _IMM5
);
3819 if ((assign_data
== (int) s7_FAIL
) || (s7_end_of_line (pp
) == (int) s7_FAIL
))
3823 if ((s7_inst
.instruction
& 0x7000) == N16_LIU
)
3825 s7_inst
.relax_inst
|= ((s7_inst
.instruction
>> 8) & 0xf) << 20
3826 | ((s7_inst
.instruction
& 0xff) << 1);
3828 else if (((s7_inst
.instruction
& 0x7007) == N16_LHP
)
3829 || ((s7_inst
.instruction
& 0x7007) == N16_SHP
))
3831 s7_inst
.relax_inst
|= ((s7_inst
.instruction
>> 8) & 0xf) << 20 | 2 << 15
3832 | (((s7_inst
.instruction
>> 3) & 0x1f) << 1);
3834 else if (((s7_inst
.instruction
& 0x7007) == N16_LWP
)
3835 || ((s7_inst
.instruction
& 0x7007) == N16_SWP
))
3837 s7_inst
.relax_inst
|= ((s7_inst
.instruction
>> 8) & 0xf) << 20 | 2 << 15
3838 | (((s7_inst
.instruction
>> 3) & 0x1f) << 2);
3840 else if (((s7_inst
.instruction
& 0x7007) == N16_LBUP
)
3841 || ((s7_inst
.instruction
& 0x7007) == N16_SBP
))
3843 s7_inst
.relax_inst
|= ((s7_inst
.instruction
>> 8) & 0xf) << 20 | 2 << 15
3844 | (((s7_inst
.instruction
>> 3) & 0x1f));
3847 s7_inst
.relax_size
= 4;
3852 s7_do16_push_pop (char *str
)
3857 s7_skip_whitespace (str
);
3858 if (((reg_rd
= s7_reg_required_here (&str
, 8, s7_REG_TYPE_SCORE
)) == (int) s7_FAIL
)
3859 || (s7_skip_past_comma (&str
) == (int) s7_FAIL
))
3865 /* s7_reg_required_here will change bit 12 of opcode, so we must restore bit 12. */
3866 s7_inst
.instruction
&= ~(1 << 12);
3868 s7_inst
.instruction
|= H_bit_mask
<< 7;
3875 s7_skip_whitespace (str
);
3876 if ((reg
= s7_reg_required_here (&str
, 4, s7_REG_TYPE_SCORE
)) == (int) s7_FAIL
)
3881 s7_inst
.error
= _("base register nums are over 3 bit");
3886 s7_skip_whitespace (str
);
3887 if ((*str
++ != ']') || (s7_end_of_line (str
) == (int) s7_FAIL
))
3890 s7_inst
.error
= _("missing ]");
3896 if ((s7_inst
.instruction
& 0xf) == 0xa)
3900 s7_inst
.relax_inst
|= ((((s7_inst
.instruction
>> 8) & 0xf) | 0x10) << 20)
3901 | (((s7_inst
.instruction
>> 4) & 0x7) << 15) | (4 << 3);
3905 s7_inst
.relax_inst
|= (((s7_inst
.instruction
>> 8) & 0xf) << 20)
3906 | (((s7_inst
.instruction
>> 4) & 0x7) << 15) | (4 << 3);
3914 s7_inst
.relax_inst
|= ((((s7_inst
.instruction
>> 8) & 0xf) | 0x10) << 20)
3915 | (((s7_inst
.instruction
>> 4) & 0x7) << 15) | (((-4) & 0xfff) << 3);
3919 s7_inst
.relax_inst
|= (((s7_inst
.instruction
>> 8) & 0xf) << 20)
3920 | (((s7_inst
.instruction
>> 4) & 0x7) << 15) | (((-4) & 0xfff) << 3);
3923 s7_inst
.relax_size
= 4;
3927 s7_inst
.error
= s7_BAD_ARGS
;
3931 /* Handle lcb/lcw/lce/scb/scw/sce. */
3933 s7_do_ldst_unalign (char *str
)
3937 if (s7_university_version
== 1)
3939 s7_inst
.error
= s7_ERR_FOR_SCORE5U_ATOMIC
;
3943 s7_skip_whitespace (str
);
3945 /* lcb/scb [rA]+. */
3949 s7_skip_whitespace (str
);
3951 if (s7_reg_required_here (&str
, 15, s7_REG_TYPE_SCORE
) == (int) s7_FAIL
)
3958 s7_inst
.error
= _("missing +");
3964 s7_inst
.error
= _("missing ]");
3968 if (s7_end_of_line (str
) == (int) s7_FAIL
)
3971 /* lcw/lce/scb/sce rD, [rA]+. */
3974 if (((conflict_reg
= s7_reg_required_here (&str
, 20, s7_REG_TYPE_SCORE
)) == (int) s7_FAIL
)
3975 || (s7_skip_past_comma (&str
) == (int) s7_FAIL
))
3980 s7_skip_whitespace (str
);
3985 s7_skip_whitespace (str
);
3986 if ((reg
= s7_reg_required_here (&str
, 15, s7_REG_TYPE_SCORE
)) == (int) s7_FAIL
)
3991 /* Conflicts can occur on stores as well as loads. */
3992 conflict_reg
= (conflict_reg
== reg
);
3993 s7_skip_whitespace (str
);
3996 unsigned int ldst_func
= s7_inst
.instruction
& LDST_UNALIGN_MASK
;
4002 as_warn (_("%s register same as write-back base"),
4003 ((ldst_func
& UA_LCE
) || (ldst_func
& UA_LCW
)
4004 ? _("destination") : _("source")));
4009 s7_inst
.error
= _("missing +");
4013 if (s7_end_of_line (str
) == (int) s7_FAIL
)
4018 s7_inst
.error
= _("missing ]");
4024 s7_inst
.error
= s7_BAD_ARGS
;
4030 /* Handle alw/asw. */
4033 s7_do_ldst_atomic (char *str
)
4035 if (s7_university_version
== 1)
4037 s7_inst
.error
= s7_ERR_FOR_SCORE5U_ATOMIC
;
4041 s7_skip_whitespace (str
);
4043 if ((s7_reg_required_here (&str
, 20, s7_REG_TYPE_SCORE
) == (int) s7_FAIL
)
4044 || (s7_skip_past_comma (&str
) == (int) s7_FAIL
))
4051 s7_skip_whitespace (str
);
4056 s7_skip_whitespace (str
);
4057 if ((reg
= s7_reg_required_here (&str
, 15, s7_REG_TYPE_SCORE
)) == (int) s7_FAIL
)
4062 s7_skip_whitespace (str
);
4065 s7_inst
.error
= _("missing ]");
4069 s7_end_of_line (str
);
4072 s7_inst
.error
= s7_BAD_ARGS
;
4077 s7_build_relax_frag (struct s7_score_it fix_insts
[s7_RELAX_INST_NUM
],
4078 int fix_num ATTRIBUTE_UNUSED
,
4079 struct s7_score_it var_insts
[s7_RELAX_INST_NUM
], int var_num
,
4080 symbolS
*add_symbol
)
4085 fixS
*cur_fixp
= NULL
;
4087 struct s7_score_it inst_main
;
4089 memcpy (&inst_main
, &fix_insts
[0], sizeof (struct s7_score_it
));
4091 /* Adjust instruction opcode and to be relaxed instruction opcode. */
4092 inst_main
.instruction
= s7_adjust_paritybit (inst_main
.instruction
, s7_GET_INSN_CLASS (inst_main
.type
));
4093 inst_main
.type
= Insn_PIC
;
4095 for (i
= 0; i
< var_num
; i
++)
4097 inst_main
.relax_size
+= var_insts
[i
].size
;
4098 var_insts
[i
].instruction
= s7_adjust_paritybit (var_insts
[i
].instruction
,
4099 s7_GET_INSN_CLASS (var_insts
[i
].type
));
4102 /* Check data dependency. */
4103 s7_handle_dependency (&inst_main
);
4105 /* Start a new frag if frag_now is not empty. */
4106 if (frag_now_fix () != 0)
4108 if (!frag_now
->tc_frag_data
.is_insn
)
4110 frag_wane (frag_now
);
4116 /* Write fr_fix part. */
4117 p
= frag_more (inst_main
.size
);
4118 s7_number_to_chars (p
, inst_main
.instruction
, inst_main
.size
);
4120 if (inst_main
.reloc
.type
!= BFD_RELOC_NONE
)
4121 fixp
= s7_fix_new_score (frag_now
, p
- frag_now
->fr_literal
, inst_main
.size
,
4122 &inst_main
.reloc
.exp
, inst_main
.reloc
.pc_rel
, inst_main
.reloc
.type
);
4124 frag_now
->tc_frag_data
.fixp
= fixp
;
4125 cur_fixp
= frag_now
->tc_frag_data
.fixp
;
4128 dwarf2_emit_insn (inst_main
.size
);
4131 where
= p
- frag_now
->fr_literal
+ inst_main
.size
;
4132 for (i
= 0; i
< var_num
; i
++)
4135 where
+= var_insts
[i
- 1].size
;
4137 if (var_insts
[i
].reloc
.type
!= BFD_RELOC_NONE
)
4139 fixp
= s7_fix_new_score (frag_now
, where
, var_insts
[i
].size
,
4140 &var_insts
[i
].reloc
.exp
, var_insts
[i
].reloc
.pc_rel
,
4141 var_insts
[i
].reloc
.type
);
4146 cur_fixp
->fx_next
= fixp
;
4147 cur_fixp
= cur_fixp
->fx_next
;
4151 frag_now
->tc_frag_data
.fixp
= fixp
;
4152 cur_fixp
= frag_now
->tc_frag_data
.fixp
;
4158 p
= frag_var (rs_machine_dependent
, inst_main
.relax_size
+ s7_RELAX_PAD_BYTE
, 0,
4159 s7_RELAX_ENCODE (inst_main
.size
, inst_main
.relax_size
, inst_main
.type
,
4160 0, inst_main
.size
, 0), add_symbol
, 0, NULL
);
4162 /* Write fr_var part.
4163 no calling s7_gen_insn_frag, no fixS will be generated. */
4164 for (i
= 0; i
< var_num
; i
++)
4166 s7_number_to_chars (p
, var_insts
[i
].instruction
, var_insts
[i
].size
);
4167 p
+= var_insts
[i
].size
;
4169 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4173 /* Build a relax frag for la instruction when generating s7_PIC,
4174 external symbol first and local symbol second. */
4177 s7_build_la_pic (int reg_rd
, expressionS exp
)
4179 symbolS
*add_symbol
= exp
.X_add_symbol
;
4180 offsetT add_number
= exp
.X_add_number
;
4181 struct s7_score_it fix_insts
[s7_RELAX_INST_NUM
];
4182 struct s7_score_it var_insts
[s7_RELAX_INST_NUM
];
4185 char tmp
[s7_MAX_LITERAL_POOL_SIZE
];
4191 if (add_number
== 0)
4196 /* For an external symbol, only one insn is generated;
4197 For a local symbol, two insns are generated. */
4199 For an external symbol: lw rD, <sym>($gp)
4200 (BFD_RELOC_SCORE_GOT15 or BFD_RELOC_SCORE_CALL15) */
4201 sprintf (tmp
, "lw_pic r%d, %s", reg_rd
, S_GET_NAME (add_symbol
));
4202 if (s7_append_insn (tmp
, FALSE
) == (int) s7_FAIL
)
4205 if (reg_rd
== s7_PIC_CALL_REG
)
4206 s7_inst
.reloc
.type
= BFD_RELOC_SCORE_CALL15
;
4207 memcpy (&fix_insts
[0], &s7_inst
, sizeof (struct s7_score_it
));
4210 For a local symbol :
4211 lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15)
4212 addi rD, <sym> (BFD_RELOC_GOT_LO16) */
4213 s7_inst
.reloc
.type
= BFD_RELOC_SCORE_GOT15
;
4214 memcpy (&var_insts
[0], &s7_inst
, sizeof (struct s7_score_it
));
4215 sprintf (tmp
, "addi_s_pic r%d, %s", reg_rd
, S_GET_NAME (add_symbol
));
4216 if (s7_append_insn (tmp
, FALSE
) == (int) s7_FAIL
)
4219 memcpy (&var_insts
[1], &s7_inst
, sizeof (struct s7_score_it
));
4220 s7_build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
4222 else if (add_number
>= -0x8000 && add_number
<= 0x7fff)
4224 /* Insn 1: lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15) */
4225 sprintf (tmp
, "lw_pic r%d, %s", reg_rd
, S_GET_NAME (add_symbol
));
4226 if (s7_append_insn (tmp
, TRUE
) == (int) s7_FAIL
)
4233 For an external symbol: addi rD, <constant> */
4234 sprintf (tmp
, "addi r%d, %d", reg_rd
, (int) add_number
);
4235 if (s7_append_insn (tmp
, FALSE
) == (int) s7_FAIL
)
4238 memcpy (&fix_insts
[0], &s7_inst
, sizeof (struct s7_score_it
));
4241 For a local symbol: addi rD, <sym>+<constant> (BFD_RELOC_GOT_LO16) */
4242 sprintf (tmp
, "addi_s_pic r%d, %s + %d", reg_rd
,
4243 S_GET_NAME (add_symbol
), (int) add_number
);
4244 if (s7_append_insn (tmp
, FALSE
) == (int) s7_FAIL
)
4247 memcpy (&var_insts
[0], &s7_inst
, sizeof (struct s7_score_it
));
4248 s7_build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
4252 int hi
= (add_number
>> 16) & 0x0000FFFF;
4253 int lo
= add_number
& 0x0000FFFF;
4255 /* Insn 1: lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15) */
4256 sprintf (tmp
, "lw_pic r%d, %s", reg_rd
, S_GET_NAME (add_symbol
));
4257 if (s7_append_insn (tmp
, TRUE
) == (int) s7_FAIL
)
4264 For an external symbol: ldis r1, HI%<constant> */
4265 sprintf (tmp
, "ldis r1, %d", hi
);
4266 if (s7_append_insn (tmp
, FALSE
) == (int) s7_FAIL
)
4269 memcpy (&fix_insts
[0], &s7_inst
, sizeof (struct s7_score_it
));
4272 For a local symbol: ldis r1, HI%<constant>
4273 but, if lo is out of 16 bit, make hi plus 1 */
4274 if ((lo
< -0x8000) || (lo
> 0x7fff))
4278 sprintf (tmp
, "ldis_pic r1, %d", hi
);
4279 if (s7_append_insn (tmp
, FALSE
) == (int) s7_FAIL
)
4282 memcpy (&var_insts
[0], &s7_inst
, sizeof (struct s7_score_it
));
4283 s7_build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
4289 For an external symbol: ori r1, LO%<constant> */
4290 sprintf (tmp
, "ori r1, %d", lo
);
4291 if (s7_append_insn (tmp
, FALSE
) == (int) s7_FAIL
)
4294 memcpy (&fix_insts
[0], &s7_inst
, sizeof (struct s7_score_it
));
4297 For a local symbol: addi r1, <sym>+LO%<constant> (BFD_RELOC_GOT_LO16) */
4298 sprintf (tmp
, "addi_u_pic r1, %s + %d", S_GET_NAME (add_symbol
), lo
);
4299 if (s7_append_insn (tmp
, FALSE
) == (int) s7_FAIL
)
4302 memcpy (&var_insts
[0], &s7_inst
, sizeof (struct s7_score_it
));
4303 s7_build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
4305 /* Insn 4: add rD, rD, r1 */
4306 sprintf (tmp
, "add r%d, r%d, r1", reg_rd
, reg_rd
);
4307 if (s7_append_insn (tmp
, TRUE
) == (int) s7_FAIL
)
4310 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4320 s7_do_macro_la_rdi32 (char *str
)
4324 s7_skip_whitespace (str
);
4325 if ((reg_rd
= s7_reg_required_here (&str
, 20, s7_REG_TYPE_SCORE
)) == (int) s7_FAIL
4326 || s7_skip_past_comma (&str
) == (int) s7_FAIL
)
4332 char append_str
[s7_MAX_LITERAL_POOL_SIZE
];
4333 char *keep_data
= str
;
4335 /* Check immediate value. */
4336 if (s7_my_get_expression (&s7_inst
.reloc
.exp
, &str
) == (int) s7_FAIL
)
4338 s7_inst
.error
= _("expression error");
4341 else if ((s7_inst
.reloc
.exp
.X_add_symbol
== NULL
)
4342 && (s7_validate_immediate (s7_inst
.reloc
.exp
.X_add_number
, _IMM32
, 0) == (int) s7_FAIL
))
4344 s7_inst
.error
= _("value not in range [0, 0xffffffff]");
4351 /* la rd, simm16. */
4352 if (s7_data_op2 (&str
, 1, _SIMM16_LA
) != (int) s7_FAIL
)
4354 s7_end_of_line (str
);
4357 /* la rd, imm32 or la rd, label. */
4360 s7_SET_INSN_ERROR (NULL
);
4362 if ((s7_data_op2 (&str
, 1, _VALUE_HI16
) == (int) s7_FAIL
)
4363 || (s7_end_of_line (str
) == (int) s7_FAIL
))
4369 if ((s7_score_pic
== s7_NO_PIC
) || (!s7_inst
.reloc
.exp
.X_add_symbol
))
4371 sprintf (append_str
, "ld_i32hi r%d, %s", reg_rd
, keep_data
);
4372 if (s7_append_insn (append_str
, TRUE
) == (int) s7_FAIL
)
4375 sprintf (append_str
, "ld_i32lo r%d, %s", reg_rd
, keep_data
);
4376 if (s7_append_insn (append_str
, TRUE
) == (int) s7_FAIL
)
4381 gas_assert (s7_inst
.reloc
.exp
.X_add_symbol
);
4382 s7_build_la_pic (reg_rd
, s7_inst
.reloc
.exp
);
4385 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4395 s7_do_macro_li_rdi32 (char *str
)
4399 s7_skip_whitespace (str
);
4400 if ((reg_rd
= s7_reg_required_here (&str
, 20, s7_REG_TYPE_SCORE
)) == (int) s7_FAIL
4401 || s7_skip_past_comma (&str
) == (int) s7_FAIL
)
4407 char *keep_data
= str
;
4409 /* Check immediate value. */
4410 if (s7_my_get_expression (&s7_inst
.reloc
.exp
, &str
) == (int) s7_FAIL
)
4412 s7_inst
.error
= _("expression error");
4415 else if (!(s7_inst
.reloc
.exp
.X_add_number
>= -0xffffffffLL
4416 && s7_inst
.reloc
.exp
.X_add_number
<= 0xffffffffLL
))
4418 s7_inst
.error
= _("value not in range [-0xffffffff, 0xffffffff]");
4425 /* li rd, simm16. */
4426 if (s7_data_op2 (&str
, 1, _SIMM16_LA
) != (int) s7_FAIL
)
4428 s7_end_of_line (str
);
4434 char append_str
[s7_MAX_LITERAL_POOL_SIZE
];
4438 if ((s7_data_op2 (&str
, 1, _VALUE_HI16
) == (int) s7_FAIL
)
4439 || (s7_end_of_line (str
) == (int) s7_FAIL
))
4443 else if (s7_inst
.reloc
.exp
.X_add_symbol
)
4445 s7_inst
.error
= _("li rd label isn't correct instruction form");
4450 sprintf (append_str
, "ld_i32hi r%d, %s", reg_rd
, keep_data
);
4452 if (s7_append_insn (append_str
, TRUE
) == (int) s7_FAIL
)
4456 sprintf (append_str
, "ld_i32lo r%d, %s", reg_rd
, keep_data
);
4457 if (s7_append_insn (append_str
, TRUE
) == (int) s7_FAIL
)
4460 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4468 /* Handle mul/mulu/div/divu/rem/remu. */
4471 s7_do_macro_mul_rdrsrs (char *str
)
4477 char append_str
[s7_MAX_LITERAL_POOL_SIZE
];
4479 if (s7_university_version
== 1)
4480 as_warn ("%s", s7_ERR_FOR_SCORE5U_MUL_DIV
);
4482 strcpy (append_str
, str
);
4483 backupstr
= append_str
;
4484 s7_skip_whitespace (backupstr
);
4485 if (((reg_rd
= s7_reg_required_here (&backupstr
, -1, s7_REG_TYPE_SCORE
)) == (int) s7_FAIL
)
4486 || (s7_skip_past_comma (&backupstr
) == (int) s7_FAIL
)
4487 || ((reg_rs1
= s7_reg_required_here (&backupstr
, -1, s7_REG_TYPE_SCORE
)) == (int) s7_FAIL
))
4489 s7_inst
.error
= s7_BAD_ARGS
;
4493 if (s7_skip_past_comma (&backupstr
) == (int) s7_FAIL
)
4495 /* rem/remu rA, rB is error format. */
4496 if (strcmp (s7_inst
.name
, "rem") == 0 || strcmp (s7_inst
.name
, "remu") == 0)
4498 s7_SET_INSN_ERROR (s7_BAD_ARGS
);
4502 s7_SET_INSN_ERROR (NULL
);
4509 s7_SET_INSN_ERROR (NULL
);
4510 if (((reg_rs2
= s7_reg_required_here (&backupstr
, -1, s7_REG_TYPE_SCORE
)) == (int) s7_FAIL
)
4511 || (s7_end_of_line (backupstr
) == (int) s7_FAIL
))
4517 char append_str1
[s7_MAX_LITERAL_POOL_SIZE
];
4519 if (strcmp (s7_inst
.name
, "rem") == 0)
4521 sprintf (append_str
, "mul r%d, r%d", reg_rs1
, reg_rs2
);
4522 sprintf (append_str1
, "mfceh r%d", reg_rd
);
4524 else if (strcmp (s7_inst
.name
, "remu") == 0)
4526 sprintf (append_str
, "mulu r%d, r%d", reg_rs1
, reg_rs2
);
4527 sprintf (append_str1
, "mfceh r%d", reg_rd
);
4531 sprintf (append_str
, "%s r%d, r%d", s7_inst
.name
, reg_rs1
, reg_rs2
);
4532 sprintf (append_str1
, "mfcel r%d", reg_rd
);
4535 /* Output mul/mulu or div/divu or rem/remu. */
4536 if (s7_append_insn (append_str
, TRUE
) == (int) s7_FAIL
)
4539 /* Output mfcel or mfceh. */
4540 if (s7_append_insn (append_str1
, TRUE
) == (int) s7_FAIL
)
4543 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4550 s7_exp_macro_ldst_abs (char *str
)
4553 char *backupstr
, *tmp
;
4554 char append_str
[s7_MAX_LITERAL_POOL_SIZE
];
4555 char verifystr
[s7_MAX_LITERAL_POOL_SIZE
];
4556 struct s7_score_it inst_backup
;
4561 memcpy (&inst_backup
, &s7_inst
, sizeof (struct s7_score_it
));
4563 strcpy (verifystr
, str
);
4564 backupstr
= verifystr
;
4565 s7_skip_whitespace (backupstr
);
4566 if ((reg_rd
= s7_reg_required_here (&backupstr
, -1, s7_REG_TYPE_SCORE
)) == (int) s7_FAIL
)
4570 if (s7_skip_past_comma (&backupstr
) == (int) s7_FAIL
)
4574 sprintf (append_str
, "li r1 %s", backupstr
);
4575 s7_append_insn (append_str
, TRUE
);
4577 memcpy (&s7_inst
, &inst_backup
, sizeof (struct s7_score_it
));
4578 sprintf (append_str
, " r%d, [r1,0]", reg_rd
);
4579 s7_do_ldst_insn (append_str
);
4585 s7_nopic_need_relax (symbolS
* sym
, int before_relaxing
)
4589 else if (s7_USE_GLOBAL_POINTER_OPT
&& s7_g_switch_value
> 0)
4591 const char *symname
;
4592 const char *segname
;
4594 /* Find out whether this symbol can be referenced off the $gp
4595 register. It can be if it is smaller than the -G size or if
4596 it is in the .sdata or .sbss section. Certain symbols can
4597 not be referenced off the $gp, although it appears as though
4599 symname
= S_GET_NAME (sym
);
4601 && (strcmp (symname
, "eprol") == 0
4602 || strcmp (symname
, "etext") == 0
4603 || strcmp (symname
, "_gp") == 0
4604 || strcmp (symname
, "edata") == 0
4605 || strcmp (symname
, "_fbss") == 0
4606 || strcmp (symname
, "_fdata") == 0
4607 || strcmp (symname
, "_ftext") == 0
4608 || strcmp (symname
, "end") == 0
4609 || strcmp (symname
, GP_DISP_LABEL
) == 0))
4613 else if ((!S_IS_DEFINED (sym
) || S_IS_COMMON (sym
)) && (0
4614 /* We must defer this decision until after the whole file has been read,
4615 since there might be a .extern after the first use of this symbol. */
4617 && S_GET_VALUE (sym
) == 0)
4618 || (S_GET_VALUE (sym
) != 0
4619 && S_GET_VALUE (sym
) <= s7_g_switch_value
)))
4624 segname
= segment_name (S_GET_SEGMENT (sym
));
4625 return (strcmp (segname
, ".sdata") != 0
4626 && strcmp (segname
, ".sbss") != 0
4627 && strncmp (segname
, ".sdata.", 7) != 0
4628 && strncmp (segname
, ".gnu.linkonce.s.", 16) != 0);
4630 /* We are not optimizing for the $gp register. */
4635 /* Build a relax frag for lw/st instruction when generating s7_PIC,
4636 external symbol first and local symbol second. */
4639 s7_build_lwst_pic (int reg_rd
, expressionS exp
, const char *insn_name
)
4641 symbolS
*add_symbol
= exp
.X_add_symbol
;
4642 int add_number
= exp
.X_add_number
;
4643 struct s7_score_it fix_insts
[s7_RELAX_INST_NUM
];
4644 struct s7_score_it var_insts
[s7_RELAX_INST_NUM
];
4647 char tmp
[s7_MAX_LITERAL_POOL_SIZE
];
4653 if ((add_number
== 0) || (add_number
>= -0x8000 && add_number
<= 0x7fff))
4658 /* For an external symbol, two insns are generated;
4659 For a local symbol, three insns are generated. */
4661 For an external symbol: lw rD, <sym>($gp)
4662 (BFD_RELOC_SCORE_GOT15) */
4663 sprintf (tmp
, "lw_pic r1, %s", S_GET_NAME (add_symbol
));
4664 if (s7_append_insn (tmp
, FALSE
) == (int) s7_FAIL
)
4667 memcpy (&fix_insts
[0], &s7_inst
, sizeof (struct s7_score_it
));
4670 For a local symbol :
4671 lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15)
4672 addi rD, <sym> (BFD_RELOC_GOT_LO16) */
4673 s7_inst
.reloc
.type
= BFD_RELOC_SCORE_GOT15
;
4674 memcpy (&var_insts
[0], &s7_inst
, sizeof (struct s7_score_it
));
4675 sprintf (tmp
, "addi_s_pic r1, %s", S_GET_NAME (add_symbol
));
4676 if (s7_append_insn (tmp
, FALSE
) == (int) s7_FAIL
)
4679 memcpy (&var_insts
[1], &s7_inst
, sizeof (struct s7_score_it
));
4680 s7_build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
4682 /* Insn 2 or Insn 3: lw/st rD, [r1, constant] */
4683 sprintf (tmp
, "%s r%d, [r1, %d]", insn_name
, reg_rd
, add_number
);
4684 if (s7_append_insn (tmp
, TRUE
) == (int) s7_FAIL
)
4687 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4692 s7_inst
.error
= _("PIC code offset overflow (max 16 signed bits)");
4700 s7_do_macro_ldst_label (char *str
)
4708 char *absolute_value
;
4709 char append_str
[3][s7_MAX_LITERAL_POOL_SIZE
];
4710 char verifystr
[s7_MAX_LITERAL_POOL_SIZE
];
4711 struct s7_score_it inst_backup
;
4712 struct s7_score_it inst_expand
[3];
4713 struct s7_score_it inst_main
;
4715 memcpy (&inst_backup
, &s7_inst
, sizeof (struct s7_score_it
));
4716 strcpy (verifystr
, str
);
4717 backup_str
= verifystr
;
4719 s7_skip_whitespace (backup_str
);
4720 if ((reg_rd
= s7_reg_required_here (&backup_str
, -1, s7_REG_TYPE_SCORE
)) == (int) s7_FAIL
)
4723 if (s7_skip_past_comma (&backup_str
) == (int) s7_FAIL
)
4726 label_str
= backup_str
;
4728 /* Ld/st rD, [rA, imm] ld/st rD, [rA]+, imm ld/st rD, [rA, imm]+. */
4729 if (*backup_str
== '[')
4731 s7_inst
.type
= Rd_rvalueRs_preSI12
;
4732 s7_do_ldst_insn (str
);
4736 /* Ld/st rD, imm. */
4737 absolute_value
= backup_str
;
4738 s7_inst
.type
= Rd_rvalueRs_SI15
;
4740 if (s7_my_get_expression (&s7_inst
.reloc
.exp
, &backup_str
) == (int) s7_FAIL
)
4742 s7_inst
.error
= _("expression error");
4745 else if ((s7_inst
.reloc
.exp
.X_add_symbol
== NULL
)
4746 && (s7_validate_immediate (s7_inst
.reloc
.exp
.X_add_number
, _VALUE
, 0) == (int) s7_FAIL
))
4748 s7_inst
.error
= _("value not in range [0, 0x7fffffff]");
4751 else if (s7_end_of_line (backup_str
) == (int) s7_FAIL
)
4753 s7_inst
.error
= _("end on line error");
4758 if (s7_inst
.reloc
.exp
.X_add_symbol
== 0)
4760 memcpy (&s7_inst
, &inst_backup
, sizeof (struct s7_score_it
));
4761 s7_exp_macro_ldst_abs (str
);
4766 /* Ld/st rD, label. */
4767 s7_inst
.type
= Rd_rvalueRs_SI15
;
4768 backup_str
= absolute_value
;
4769 if ((s7_data_op2 (&backup_str
, 1, _GP_IMM15
) == (int) s7_FAIL
)
4770 || (s7_end_of_line (backup_str
) == (int) s7_FAIL
))
4776 if (s7_inst
.reloc
.exp
.X_add_symbol
== 0)
4779 s7_inst
.error
= s7_BAD_ARGS
;
4784 if (s7_score_pic
== s7_PIC
)
4787 ldst_idx
= s7_inst
.instruction
& OPC_PSEUDOLDST_MASK
;
4788 s7_build_lwst_pic (reg_rd
, s7_inst
.reloc
.exp
,
4789 s7_score_ldst_insns
[ldst_idx
* 3 + 0].template_name
);
4794 if ((s7_inst
.reloc
.exp
.X_add_number
<= 0x3fff)
4795 && (s7_inst
.reloc
.exp
.X_add_number
>= -0x4000)
4796 && (!s7_nopic_need_relax (s7_inst
.reloc
.exp
.X_add_symbol
, 1)))
4800 /* Assign the real opcode. */
4801 ldst_idx
= s7_inst
.instruction
& OPC_PSEUDOLDST_MASK
;
4802 s7_inst
.instruction
&= ~OPC_PSEUDOLDST_MASK
;
4803 s7_inst
.instruction
|= s7_score_ldst_insns
[ldst_idx
* 3 + 0].value
;
4804 s7_inst
.instruction
|= reg_rd
<< 20;
4805 s7_inst
.instruction
|= s7_GP
<< 15;
4806 s7_inst
.relax_inst
= 0x8000;
4807 s7_inst
.relax_size
= 0;
4813 /* Backup s7_inst. */
4814 memcpy (&inst_main
, &s7_inst
, sizeof (struct s7_score_it
));
4818 /* Determine which instructions should be output. */
4819 sprintf (append_str
[0], "ld_i32hi r1, %s", label_str
);
4820 sprintf (append_str
[1], "ld_i32lo r1, %s", label_str
);
4821 sprintf (append_str
[2], "%s r%d, [r1, 0]", inst_backup
.name
, reg_rd
);
4823 /* Generate three instructions.
4825 ld/st rd, [r1, 0] */
4826 for (i
= 0; i
< 3; i
++)
4828 if (s7_append_insn (append_str
[i
], FALSE
) == (int) s7_FAIL
)
4831 memcpy (&inst_expand
[i
], &s7_inst
, sizeof (struct s7_score_it
));
4838 /* Adjust instruction opcode and to be relaxed instruction opcode. */
4839 inst_main
.instruction
= s7_adjust_paritybit (inst_main
.instruction
, s7_GET_INSN_CLASS (inst_main
.type
));
4840 inst_main
.relax_size
= inst_expand
[0].size
+ inst_expand
[1].size
+ inst_expand
[2].size
;
4841 inst_main
.type
= Insn_GP
;
4843 for (i
= 0; i
< 3; i
++)
4844 inst_expand
[i
].instruction
= s7_adjust_paritybit (inst_expand
[i
].instruction
4845 , s7_GET_INSN_CLASS (inst_expand
[i
].type
));
4847 /* Check data dependency. */
4848 s7_handle_dependency (&inst_main
);
4850 /* Start a new frag if frag_now is not empty. */
4851 if (frag_now_fix () != 0)
4853 if (!frag_now
->tc_frag_data
.is_insn
)
4854 frag_wane (frag_now
);
4860 /* Write fr_fix part. */
4861 p
= frag_more (inst_main
.size
);
4862 s7_number_to_chars (p
, inst_main
.instruction
, inst_main
.size
);
4864 if (inst_main
.reloc
.type
!= BFD_RELOC_NONE
)
4866 s7_fix_new_score (frag_now
, p
- frag_now
->fr_literal
, inst_main
.size
,
4867 &inst_main
.reloc
.exp
, inst_main
.reloc
.pc_rel
, inst_main
.reloc
.type
);
4871 dwarf2_emit_insn (inst_main
.size
);
4874 /* s7_GP instruction can not do optimization, only can do relax between
4875 1 instruction and 3 instructions. */
4876 p
= frag_var (rs_machine_dependent
, inst_main
.relax_size
+ s7_RELAX_PAD_BYTE
, 0,
4877 s7_RELAX_ENCODE (inst_main
.size
, inst_main
.relax_size
, inst_main
.type
, 0, 4, 0),
4878 inst_main
.reloc
.exp
.X_add_symbol
, 0, NULL
);
4880 /* Write fr_var part.
4881 no calling s7_gen_insn_frag, no fixS will be generated. */
4882 s7_number_to_chars (p
, inst_expand
[0].instruction
, inst_expand
[0].size
);
4883 p
+= inst_expand
[0].size
;
4884 s7_number_to_chars (p
, inst_expand
[1].instruction
, inst_expand
[1].size
);
4885 p
+= inst_expand
[1].size
;
4886 s7_number_to_chars (p
, inst_expand
[2].instruction
, inst_expand
[2].size
);
4890 s7_gen_insn_frag (&inst_expand
[0], NULL
);
4891 s7_gen_insn_frag (&inst_expand
[1], NULL
);
4892 s7_gen_insn_frag (&inst_expand
[2], NULL
);
4896 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4901 s7_do_lw_pic (char *str
)
4905 s7_skip_whitespace (str
);
4906 if (((reg_rd
= s7_reg_required_here (&str
, 20, s7_REG_TYPE_SCORE
)) == (int) s7_FAIL
)
4907 || (s7_skip_past_comma (&str
) == (int) s7_FAIL
)
4908 || (s7_my_get_expression (&s7_inst
.reloc
.exp
, &str
) == (int) s7_FAIL
)
4909 || (s7_end_of_line (str
) == (int) s7_FAIL
))
4915 if (s7_inst
.reloc
.exp
.X_add_symbol
== 0)
4918 s7_inst
.error
= s7_BAD_ARGS
;
4923 s7_inst
.instruction
|= s7_GP
<< 15;
4924 s7_inst
.reloc
.type
= BFD_RELOC_SCORE_GOT15
;
4929 s7_do_empty (char *str
)
4932 if (s7_university_version
== 1)
4934 if (((s7_inst
.instruction
& 0x3e0003ff) == 0x0c000004)
4935 || ((s7_inst
.instruction
& 0x3e0003ff) == 0x0c000024)
4936 || ((s7_inst
.instruction
& 0x3e0003ff) == 0x0c000044)
4937 || ((s7_inst
.instruction
& 0x3e0003ff) == 0x0c000064))
4939 s7_inst
.error
= s7_ERR_FOR_SCORE5U_MMU
;
4943 if (s7_end_of_line (str
) == (int) s7_FAIL
)
4946 if (s7_inst
.relax_inst
!= 0x8000)
4948 if (s7_inst
.type
== NO_OPD
)
4950 s7_inst
.relax_size
= 2;
4954 s7_inst
.relax_size
= 4;
4960 s7_do_jump (char *str
)
4964 s7_skip_whitespace (str
);
4965 if (s7_my_get_expression (&s7_inst
.reloc
.exp
, &str
) == (int) s7_FAIL
4966 || s7_end_of_line (str
) == (int) s7_FAIL
)
4969 if (s7_inst
.reloc
.exp
.X_add_symbol
== 0)
4971 s7_inst
.error
= _("lacking label ");
4975 if (!(s7_inst
.reloc
.exp
.X_add_number
>= -16777216
4976 && s7_inst
.reloc
.exp
.X_add_number
<= 16777215))
4978 s7_inst
.error
= _("invalid constant: 25 bit expression not in range [-16777216, 16777215]");
4982 save_in
= input_line_pointer
;
4983 input_line_pointer
= str
;
4984 s7_inst
.reloc
.type
= BFD_RELOC_SCORE_JMP
;
4985 s7_inst
.reloc
.pc_rel
= 1;
4986 input_line_pointer
= save_in
;
4990 s7_do16_jump (char *str
)
4992 s7_skip_whitespace (str
);
4993 if (s7_my_get_expression (&s7_inst
.reloc
.exp
, &str
) == (int) s7_FAIL
4994 || s7_end_of_line (str
) == (int) s7_FAIL
)
4998 else if (s7_inst
.reloc
.exp
.X_add_symbol
== 0)
5000 s7_inst
.error
= _("lacking label ");
5003 else if (!(s7_inst
.reloc
.exp
.X_add_number
>= 0
5004 && s7_inst
.reloc
.exp
.X_add_number
<= 4095))
5006 s7_inst
.error
= _("invalid constant: 12 bit expression not in range [0, 4095]");
5010 s7_inst
.reloc
.type
= BFD_RELOC_SCORE16_JMP
;
5011 s7_inst
.reloc
.pc_rel
= 1;
5015 s7_do_branch (char *str
)
5017 unsigned long abs_value
= 0;
5019 if (s7_my_get_expression (&s7_inst
.reloc
.exp
, &str
) == (int) s7_FAIL
5020 || s7_end_of_line (str
) == (int) s7_FAIL
)
5024 else if (s7_inst
.reloc
.exp
.X_add_symbol
== 0)
5026 s7_inst
.error
= _("lacking label ");
5029 else if (!(s7_inst
.reloc
.exp
.X_add_number
>= -524288
5030 && s7_inst
.reloc
.exp
.X_add_number
<= 524287))
5032 s7_inst
.error
= _("invalid constant: 20 bit expression not in range -2^19..2^19");
5036 s7_inst
.reloc
.type
= BFD_RELOC_SCORE_BRANCH
;
5037 s7_inst
.reloc
.pc_rel
= 1;
5039 /* Branch 32 offset field : 20 bit, 16 bit branch offset field : 8 bit. */
5040 s7_inst
.instruction
|= (s7_inst
.reloc
.exp
.X_add_number
& 0x3fe) | ((s7_inst
.reloc
.exp
.X_add_number
& 0xffc00) << 5);
5042 /* Compute 16 bit branch instruction. */
5043 if ((s7_inst
.relax_inst
!= 0x8000) && (abs_value
& 0xfffffe00) == 0)
5045 s7_inst
.relax_inst
|= (((s7_inst
.instruction
>> 10) & 0xf) << 8);
5046 s7_inst
.relax_inst
|= ((s7_inst
.reloc
.exp
.X_add_number
>> 1) & 0xff);
5047 s7_inst
.relax_size
= 2;
5051 s7_inst
.relax_inst
= 0x8000;
5056 s7_do16_branch (char *str
)
5058 if ((s7_my_get_expression (&s7_inst
.reloc
.exp
, &str
) == (int) s7_FAIL
5059 || s7_end_of_line (str
) == (int) s7_FAIL
))
5063 else if (s7_inst
.reloc
.exp
.X_add_symbol
== 0)
5065 s7_inst
.error
= _("lacking label");
5067 else if (!(s7_inst
.reloc
.exp
.X_add_number
>= -512
5068 && s7_inst
.reloc
.exp
.X_add_number
<= 511))
5070 s7_inst
.error
= _("invalid constant: 10 bit expression not in range [-2^9, 2^9-1]");
5074 s7_inst
.reloc
.type
= BFD_RELOC_SCORE16_BRANCH
;
5075 s7_inst
.reloc
.pc_rel
= 1;
5076 s7_inst
.instruction
|= ((s7_inst
.reloc
.exp
.X_add_number
>> 1) & 0xff);
5080 /* Iterate over the base tables to create the instruction patterns. */
5083 s7_build_score_ops_hsh (void)
5086 static struct obstack insn_obstack
;
5088 obstack_begin (&insn_obstack
, 4000);
5089 for (i
= 0; i
< sizeof (s7_score_insns
) / sizeof (struct s7_asm_opcode
); i
++)
5091 const struct s7_asm_opcode
*insn
= s7_score_insns
+ i
;
5092 size_t len
= strlen (insn
->template_name
);
5093 struct s7_asm_opcode
*new_opcode
;
5094 char *template_name
;
5095 new_opcode
= (struct s7_asm_opcode
*)
5096 obstack_alloc (&insn_obstack
, sizeof (struct s7_asm_opcode
));
5097 template_name
= (char *) obstack_alloc (&insn_obstack
, len
+ 1);
5099 strcpy (template_name
, insn
->template_name
);
5100 new_opcode
->template_name
= template_name
;
5101 new_opcode
->parms
= insn
->parms
;
5102 new_opcode
->value
= insn
->value
;
5103 new_opcode
->relax_value
= insn
->relax_value
;
5104 new_opcode
->type
= insn
->type
;
5105 new_opcode
->bitmask
= insn
->bitmask
;
5106 hash_insert (s7_score_ops_hsh
, new_opcode
->template_name
,
5107 (void *) new_opcode
);
5112 s7_build_dependency_insn_hsh (void)
5115 static struct obstack dependency_obstack
;
5117 obstack_begin (&dependency_obstack
, 4000);
5118 for (i
= 0; i
< ARRAY_SIZE (s7_insn_to_dependency_table
); i
++)
5120 const struct s7_insn_to_dependency
*tmp
= s7_insn_to_dependency_table
+ i
;
5121 size_t len
= strlen (tmp
->insn_name
);
5122 struct s7_insn_to_dependency
*new_i2d
;
5125 new_i2d
= (struct s7_insn_to_dependency
*)
5126 obstack_alloc (&dependency_obstack
,
5127 sizeof (struct s7_insn_to_dependency
));
5128 insn_name
= (char *) obstack_alloc (&dependency_obstack
, len
+ 1);
5130 strcpy (insn_name
, tmp
->insn_name
);
5131 new_i2d
->insn_name
= insn_name
;
5132 new_i2d
->type
= tmp
->type
;
5133 hash_insert (s7_dependency_insn_hsh
, new_i2d
->insn_name
,
5139 s7_md_chars_to_number (char *buf
, int n
)
5142 unsigned char *where
= (unsigned char *) buf
;
5144 if (target_big_endian
)
5149 result
|= (*where
++ & 255);
5157 result
|= (where
[n
] & 255);
5164 /* Return true if the given symbol should be considered local for s7_PIC. */
5167 s7_pic_need_relax (symbolS
*sym
, asection
*segtype
)
5170 bfd_boolean linkonce
;
5172 /* Handle the case of a symbol equated to another symbol. */
5173 while (symbol_equated_reloc_p (sym
))
5177 /* It's possible to get a loop here in a badly written
5179 n
= symbol_get_value_expression (sym
)->X_add_symbol
;
5185 symsec
= S_GET_SEGMENT (sym
);
5187 /* Duplicate the test for LINK_ONCE sections as in adjust_reloc_syms */
5189 if (symsec
!= segtype
&& ! S_IS_LOCAL (sym
))
5191 if ((bfd_get_section_flags (stdoutput
, symsec
) & SEC_LINK_ONCE
) != 0)
5194 /* The GNU toolchain uses an extension for ELF: a section
5195 beginning with the magic string .gnu.linkonce is a linkonce
5197 if (strncmp (segment_name (symsec
), ".gnu.linkonce",
5198 sizeof ".gnu.linkonce" - 1) == 0)
5202 /* This must duplicate the test in adjust_reloc_syms. */
5203 return (!bfd_is_und_section (symsec
)
5204 && !bfd_is_abs_section (symsec
)
5205 && !bfd_is_com_section (symsec
)
5208 /* A global or weak symbol is treated as external. */
5209 && (OUTPUT_FLAVOR
!= bfd_target_elf_flavour
5210 || (! S_IS_WEAK (sym
) && ! S_IS_EXTERNAL (sym
)))
5216 s7_judge_size_before_relax (fragS
* fragp
, asection
*sec
)
5220 if (s7_score_pic
== s7_NO_PIC
)
5221 change
= s7_nopic_need_relax (fragp
->fr_symbol
, 0);
5223 change
= s7_pic_need_relax (fragp
->fr_symbol
, sec
);
5227 /* Only at the first time determining whether s7_GP instruction relax should be done,
5228 return the difference between instruction size and instruction relax size. */
5229 if (fragp
->fr_opcode
== NULL
)
5231 fragp
->fr_fix
= s7_RELAX_NEW (fragp
->fr_subtype
);
5232 fragp
->fr_opcode
= fragp
->fr_literal
+ s7_RELAX_RELOC1 (fragp
->fr_subtype
);
5233 return s7_RELAX_NEW (fragp
->fr_subtype
) - s7_RELAX_OLD (fragp
->fr_subtype
);
5241 s7_b32_relax_to_b16 (fragS
* fragp
)
5244 int relaxable_p
= 0;
5245 int frag_addr
= fragp
->fr_address
+ fragp
->insn_addr
;
5247 addressT symbol_address
= 0;
5250 unsigned long value
;
5251 unsigned long abs_value
;
5253 /* FIXME : here may be able to modify better .
5254 I don't know how to get the fragp's section ,
5255 so in relax stage , it may be wrong to calculate the symbol's offset when the frag's section
5256 is different from the symbol's. */
5258 relaxable_p
= s7_RELAX_OPT (fragp
->fr_subtype
);
5260 s
= fragp
->fr_symbol
;
5261 /* b/bl immediate */
5265 symbol_address
= (addressT
) symbol_get_frag (s
)->fr_address
;
5267 value
= s7_md_chars_to_number (fragp
->fr_literal
, s7_INSN_SIZE
);
5269 /* b 32's offset : 20 bit, b 16's tolerate field : 0xff. */
5270 offset
= ((value
& 0x3ff0000) >> 6) | (value
& 0x3fe);
5271 if ((offset
& 0x80000) == 0x80000)
5272 offset
|= 0xfff00000;
5274 abs_value
= offset
+ symbol_address
- frag_addr
;
5275 if ((abs_value
& 0x80000000) == 0x80000000)
5276 abs_value
= 0xffffffff - abs_value
+ 1;
5278 /* Relax branch 32 to branch 16. */
5279 if (relaxable_p
&& ((abs_value
& 0xffffff00) == 0)
5280 && (S_IS_DEFINED (s
) && !S_IS_COMMON (s
) && !S_IS_EXTERNAL (s
)))
5286 /* Branch 32 can not be relaxed to b 16, so clear OPT bit. */
5287 fragp
->fr_opcode
= NULL
;
5288 fragp
->fr_subtype
= s7_RELAX_OPT_CLEAR (fragp
->fr_subtype
);
5295 s7_parse_pce_inst (char *insnstr
)
5300 char first
[s7_MAX_LITERAL_POOL_SIZE
];
5301 char second
[s7_MAX_LITERAL_POOL_SIZE
];
5302 struct s7_score_it pec_part_1
;
5304 /* Get first part string of PCE. */
5305 p
= strstr (insnstr
, "||");
5308 strcpy (first
, insnstr
);
5310 /* Get second part string of PCE. */
5315 s7_parse_16_32_inst (first
, FALSE
);
5319 memcpy (&pec_part_1
, &s7_inst
, sizeof (s7_inst
));
5328 s7_parse_16_32_inst (second
, FALSE
);
5332 if ( ((pec_part_1
.size
== s7_INSN_SIZE
) && (s7_inst
.size
== s7_INSN_SIZE
))
5333 || ((pec_part_1
.size
== s7_INSN_SIZE
) && (s7_inst
.size
== s7_INSN16_SIZE
))
5334 || ((pec_part_1
.size
== s7_INSN16_SIZE
) && (s7_inst
.size
== s7_INSN_SIZE
)))
5336 s7_inst
.error
= _("pce instruction error (16 bit || 16 bit)'");
5337 strcpy (s7_inst
.str
, insnstr
);
5342 s7_gen_insn_frag (&pec_part_1
, &s7_inst
);
5348 s7_insert_reg (const struct s7_reg_entry
*r
, struct hash_control
*htab
)
5351 int len
= strlen (r
->name
) + 2;
5352 char *buf
= XNEWVEC (char, len
);
5353 char *buf2
= XNEWVEC (char, len
);
5355 strcpy (buf
+ i
, r
->name
);
5356 for (i
= 0; buf
[i
]; i
++)
5358 buf2
[i
] = TOUPPER (buf
[i
]);
5362 hash_insert (htab
, buf
, (void *) r
);
5363 hash_insert (htab
, buf2
, (void *) r
);
5367 s7_build_reg_hsh (struct s7_reg_map
*map
)
5369 const struct s7_reg_entry
*r
;
5371 if ((map
->htab
= hash_new ()) == NULL
)
5373 as_fatal (_("virtual memory exhausted"));
5375 for (r
= map
->names
; r
->name
!= NULL
; r
++)
5377 s7_insert_reg (r
, map
->htab
);
5383 /* If we change section we must dump the literal pool first. */
5385 s7_s_score_bss (int ignore ATTRIBUTE_UNUSED
)
5387 subseg_set (bss_section
, (subsegT
) get_absolute_expression ());
5388 demand_empty_rest_of_line ();
5392 s7_s_score_text (int ignore
)
5394 obj_elf_text (ignore
);
5395 record_alignment (now_seg
, 2);
5399 s7_s_section (int ignore
)
5401 obj_elf_section (ignore
);
5402 if ((bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
) != 0)
5403 record_alignment (now_seg
, 2);
5408 s7_s_change_sec (int sec
)
5413 /* The ELF backend needs to know that we are changing sections, so
5414 that .previous works correctly. We could do something like check
5415 for an obj_section_change_hook macro, but that might be confusing
5416 as it would not be appropriate to use it in the section changing
5417 functions in read.c, since obj-elf.c intercepts those. FIXME:
5418 This should be cleaner, somehow. */
5419 obj_elf_section_change_hook ();
5424 seg
= subseg_new (s7_RDATA_SECTION_NAME
, (subsegT
) get_absolute_expression ());
5425 bfd_set_section_flags (stdoutput
, seg
, (SEC_ALLOC
| SEC_LOAD
| SEC_READONLY
| SEC_RELOC
| SEC_DATA
));
5426 if (strcmp (TARGET_OS
, "elf") != 0)
5427 record_alignment (seg
, 4);
5428 demand_empty_rest_of_line ();
5431 seg
= subseg_new (".sdata", (subsegT
) get_absolute_expression ());
5432 bfd_set_section_flags (stdoutput
, seg
, SEC_ALLOC
| SEC_LOAD
| SEC_RELOC
| SEC_DATA
);
5433 if (strcmp (TARGET_OS
, "elf") != 0)
5434 record_alignment (seg
, 4);
5435 demand_empty_rest_of_line ();
5441 s7_s_score_mask (int reg_type ATTRIBUTE_UNUSED
)
5445 if (s7_cur_proc_ptr
== NULL
)
5447 as_warn (_(".mask outside of .ent"));
5448 demand_empty_rest_of_line ();
5451 if (get_absolute_expression_and_terminator (&mask
) != ',')
5453 as_warn (_("Bad .mask directive"));
5454 --input_line_pointer
;
5455 demand_empty_rest_of_line ();
5458 off
= get_absolute_expression ();
5459 s7_cur_proc_ptr
->reg_mask
= mask
;
5460 s7_cur_proc_ptr
->reg_offset
= off
;
5461 demand_empty_rest_of_line ();
5465 s7_get_symbol (void)
5471 c
= get_symbol_name (&name
);
5472 p
= (symbolS
*) symbol_find_or_make (name
);
5473 (void) restore_line_pointer (c
);
5478 s7_get_number (void)
5483 if (*input_line_pointer
== '-')
5485 ++input_line_pointer
;
5488 if (!ISDIGIT (*input_line_pointer
))
5489 as_bad (_("expected simple number"));
5490 if (input_line_pointer
[0] == '0')
5492 if (input_line_pointer
[1] == 'x')
5494 input_line_pointer
+= 2;
5495 while (ISXDIGIT (*input_line_pointer
))
5498 val
|= hex_value (*input_line_pointer
++);
5500 return negative
? -val
: val
;
5504 ++input_line_pointer
;
5505 while (ISDIGIT (*input_line_pointer
))
5508 val
|= *input_line_pointer
++ - '0';
5510 return negative
? -val
: val
;
5513 if (!ISDIGIT (*input_line_pointer
))
5515 printf (_(" *input_line_pointer == '%c' 0x%02x\n"), *input_line_pointer
, *input_line_pointer
);
5516 as_warn (_("invalid number"));
5519 while (ISDIGIT (*input_line_pointer
))
5522 val
+= *input_line_pointer
++ - '0';
5524 return negative
? -val
: val
;
5527 /* The .aent and .ent directives. */
5530 s7_s_score_ent (int aent
)
5535 symbolP
= s7_get_symbol ();
5536 if (*input_line_pointer
== ',')
5537 ++input_line_pointer
;
5539 if (ISDIGIT (*input_line_pointer
) || *input_line_pointer
== '-')
5542 #ifdef BFD_ASSEMBLER
5543 if ((bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
) != 0)
5548 if (now_seg
!= data_section
&& now_seg
!= bss_section
)
5554 as_warn (_(".ent or .aent not in text section."));
5555 if (!aent
&& s7_cur_proc_ptr
)
5556 as_warn (_("missing .end"));
5559 s7_cur_proc_ptr
= &s7_cur_proc
;
5560 s7_cur_proc_ptr
->reg_mask
= 0xdeadbeaf;
5561 s7_cur_proc_ptr
->reg_offset
= 0xdeadbeaf;
5562 s7_cur_proc_ptr
->fpreg_mask
= 0xdeafbeaf;
5563 s7_cur_proc_ptr
->leaf
= 0xdeafbeaf;
5564 s7_cur_proc_ptr
->frame_offset
= 0xdeafbeaf;
5565 s7_cur_proc_ptr
->frame_reg
= 0xdeafbeaf;
5566 s7_cur_proc_ptr
->pc_reg
= 0xdeafbeaf;
5567 s7_cur_proc_ptr
->isym
= symbolP
;
5568 symbol_get_bfdsym (symbolP
)->flags
|= BSF_FUNCTION
;
5570 if (debug_type
== DEBUG_STABS
)
5571 stabs_generate_asm_func (S_GET_NAME (symbolP
), S_GET_NAME (symbolP
));
5573 demand_empty_rest_of_line ();
5577 s7_s_score_frame (int ignore ATTRIBUTE_UNUSED
)
5584 backupstr
= input_line_pointer
;
5587 if (s7_cur_proc_ptr
== NULL
)
5589 as_warn (_(".frame outside of .ent"));
5590 demand_empty_rest_of_line ();
5593 s7_cur_proc_ptr
->frame_reg
= s7_reg_required_here ((&backupstr
), 0, s7_REG_TYPE_SCORE
);
5595 s7_skip_past_comma (&backupstr
);
5596 while (*backupstr
!= ',')
5598 str
[i
] = *backupstr
;
5606 s7_skip_past_comma (&backupstr
);
5607 s7_cur_proc_ptr
->frame_offset
= val
;
5608 s7_cur_proc_ptr
->pc_reg
= s7_reg_required_here ((&backupstr
), 0, s7_REG_TYPE_SCORE
);
5611 s7_skip_past_comma (&backupstr
);
5613 while (*backupstr
!= '\n')
5615 str
[i
] = *backupstr
;
5621 s7_cur_proc_ptr
->leaf
= val
;
5623 s7_skip_past_comma (&backupstr
);
5625 #endif /* OBJ_ELF */
5626 while (input_line_pointer
!= backupstr
)
5627 input_line_pointer
++;
5630 /* The .end directive. */
5633 s7_s_score_end (int x ATTRIBUTE_UNUSED
)
5638 /* Generate a .pdr section. */
5639 segT saved_seg
= now_seg
;
5640 subsegT saved_subseg
= now_subseg
;
5644 if (!is_end_of_line
[(unsigned char)*input_line_pointer
])
5646 p
= s7_get_symbol ();
5647 demand_empty_rest_of_line ();
5652 #ifdef BFD_ASSEMBLER
5653 if ((bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
) != 0)
5658 if (now_seg
!= data_section
&& now_seg
!= bss_section
)
5665 as_warn (_(".end not in text section"));
5666 if (!s7_cur_proc_ptr
)
5668 as_warn (_(".end directive without a preceding .ent directive."));
5669 demand_empty_rest_of_line ();
5674 gas_assert (S_GET_NAME (p
));
5675 if (strcmp (S_GET_NAME (p
), S_GET_NAME (s7_cur_proc_ptr
->isym
)))
5676 as_warn (_(".end symbol does not match .ent symbol."));
5677 if (debug_type
== DEBUG_STABS
)
5678 stabs_generate_asm_endfunc (S_GET_NAME (p
), S_GET_NAME (p
));
5681 as_warn (_(".end directive missing or unknown symbol"));
5683 if ((s7_cur_proc_ptr
->reg_mask
== 0xdeadbeaf) ||
5684 (s7_cur_proc_ptr
->reg_offset
== 0xdeadbeaf) ||
5685 (s7_cur_proc_ptr
->leaf
== 0xdeafbeaf) ||
5686 (s7_cur_proc_ptr
->frame_offset
== 0xdeafbeaf) ||
5687 (s7_cur_proc_ptr
->frame_reg
== 0xdeafbeaf) || (s7_cur_proc_ptr
->pc_reg
== 0xdeafbeaf));
5691 (void) frag_now_fix ();
5692 gas_assert (s7_pdr_seg
);
5693 subseg_set (s7_pdr_seg
, 0);
5694 /* Write the symbol. */
5695 exp
.X_op
= O_symbol
;
5696 exp
.X_add_symbol
= p
;
5697 exp
.X_add_number
= 0;
5698 emit_expr (&exp
, 4);
5699 fragp
= frag_more (7 * 4);
5700 s7_number_to_chars (fragp
, (valueT
) s7_cur_proc_ptr
->reg_mask
, 4);
5701 s7_number_to_chars (fragp
+ 4, (valueT
) s7_cur_proc_ptr
->reg_offset
, 4);
5702 s7_number_to_chars (fragp
+ 8, (valueT
) s7_cur_proc_ptr
->fpreg_mask
, 4);
5703 s7_number_to_chars (fragp
+ 12, (valueT
) s7_cur_proc_ptr
->leaf
, 4);
5704 s7_number_to_chars (fragp
+ 16, (valueT
) s7_cur_proc_ptr
->frame_offset
, 4);
5705 s7_number_to_chars (fragp
+ 20, (valueT
) s7_cur_proc_ptr
->frame_reg
, 4);
5706 s7_number_to_chars (fragp
+ 24, (valueT
) s7_cur_proc_ptr
->pc_reg
, 4);
5707 subseg_set (saved_seg
, saved_subseg
);
5710 s7_cur_proc_ptr
= NULL
;
5713 /* Handle the .set pseudo-op. */
5716 s7_s_score_set (int x ATTRIBUTE_UNUSED
)
5719 char name
[s7_MAX_LITERAL_POOL_SIZE
];
5720 char * orig_ilp
= input_line_pointer
;
5722 while (!is_end_of_line
[(unsigned char)*input_line_pointer
])
5724 name
[i
] = (char) * input_line_pointer
;
5726 ++input_line_pointer
;
5731 if (strcmp (name
, "nwarn") == 0)
5733 s7_warn_fix_data_dependency
= 0;
5735 else if (strcmp (name
, "fixdd") == 0)
5737 s7_fix_data_dependency
= 1;
5739 else if (strcmp (name
, "nofixdd") == 0)
5741 s7_fix_data_dependency
= 0;
5743 else if (strcmp (name
, "r1") == 0)
5747 else if (strcmp (name
, "nor1") == 0)
5751 else if (strcmp (name
, "optimize") == 0)
5755 else if (strcmp (name
, "volatile") == 0)
5759 else if (strcmp (name
, "pic") == 0)
5761 s7_score_pic
= s7_PIC
;
5765 input_line_pointer
= orig_ilp
;
5770 /* Handle the .cpload pseudo-op. This is used when generating s7_PIC code. It sets the
5771 $gp register for the function based on the function address, which is in the register
5772 named in the argument. This uses a relocation against GP_DISP_LABEL, which is handled
5773 specially by the linker. The result is:
5774 ldis gp, %hi(GP_DISP_LABEL)
5775 ori gp, %low(GP_DISP_LABEL)
5776 add gp, gp, .cpload argument
5777 The .cpload argument is normally r29. */
5780 s7_s_score_cpload (int ignore ATTRIBUTE_UNUSED
)
5783 char insn_str
[s7_MAX_LITERAL_POOL_SIZE
];
5785 /* If we are not generating s7_PIC code, .cpload is ignored. */
5786 if (s7_score_pic
== s7_NO_PIC
)
5792 if ((reg
= s7_reg_required_here (&input_line_pointer
, -1, s7_REG_TYPE_SCORE
)) == (int) s7_FAIL
)
5795 demand_empty_rest_of_line ();
5797 sprintf (insn_str
, "ld_i32hi r%d, %s", s7_GP
, GP_DISP_LABEL
);
5798 if (s7_append_insn (insn_str
, TRUE
) == (int) s7_FAIL
)
5801 sprintf (insn_str
, "ld_i32lo r%d, %s", s7_GP
, GP_DISP_LABEL
);
5802 if (s7_append_insn (insn_str
, TRUE
) == (int) s7_FAIL
)
5805 sprintf (insn_str
, "add r%d, r%d, r%d", s7_GP
, s7_GP
, reg
);
5806 if (s7_append_insn (insn_str
, TRUE
) == (int) s7_FAIL
)
5810 /* Handle the .cprestore pseudo-op. This stores $gp into a given
5811 offset from $sp. The offset is remembered, and after making a s7_PIC
5812 call $gp is restored from that location. */
5815 s7_s_score_cprestore (int ignore ATTRIBUTE_UNUSED
)
5818 int cprestore_offset
;
5819 char insn_str
[s7_MAX_LITERAL_POOL_SIZE
];
5821 /* If we are not generating s7_PIC code, .cprestore is ignored. */
5822 if (s7_score_pic
== s7_NO_PIC
)
5828 if ((reg
= s7_reg_required_here (&input_line_pointer
, -1, s7_REG_TYPE_SCORE
)) == (int) s7_FAIL
5829 || s7_skip_past_comma (&input_line_pointer
) == (int) s7_FAIL
)
5834 cprestore_offset
= get_absolute_expression ();
5836 if (cprestore_offset
<= 0x3fff)
5838 sprintf (insn_str
, "sw r%d, [r%d, %d]", s7_GP
, reg
, cprestore_offset
);
5839 if (s7_append_insn (insn_str
, TRUE
) == (int) s7_FAIL
)
5849 sprintf (insn_str
, "li r1, %d", cprestore_offset
);
5850 if (s7_append_insn (insn_str
, TRUE
) == (int) s7_FAIL
)
5853 sprintf (insn_str
, "add r1, r1, r%d", reg
);
5854 if (s7_append_insn (insn_str
, TRUE
) == (int) s7_FAIL
)
5857 sprintf (insn_str
, "sw r%d, [r1]", s7_GP
);
5858 if (s7_append_insn (insn_str
, TRUE
) == (int) s7_FAIL
)
5864 demand_empty_rest_of_line ();
5867 /* Handle the .gpword pseudo-op. This is used when generating s7_PIC
5868 code. It generates a 32 bit s7_GP relative reloc. */
5871 s7_s_score_gpword (int ignore ATTRIBUTE_UNUSED
)
5876 /* When not generating s7_PIC code, this is treated as .word. */
5877 if (s7_score_pic
== s7_NO_PIC
)
5883 if (ex
.X_op
!= O_symbol
|| ex
.X_add_number
!= 0)
5885 as_bad (_("Unsupported use of .gpword"));
5886 ignore_rest_of_line ();
5889 s7_number_to_chars (p
, (valueT
) 0, 4);
5890 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 4, &ex
, FALSE
, BFD_RELOC_GPREL32
);
5891 demand_empty_rest_of_line ();
5894 /* Handle the .cpadd pseudo-op. This is used when dealing with switch
5895 tables in s7_PIC code. */
5898 s7_s_score_cpadd (int ignore ATTRIBUTE_UNUSED
)
5901 char insn_str
[s7_MAX_LITERAL_POOL_SIZE
];
5903 /* If we are not generating s7_PIC code, .cpload is ignored. */
5904 if (s7_score_pic
== s7_NO_PIC
)
5910 if ((reg
= s7_reg_required_here (&input_line_pointer
, -1, s7_REG_TYPE_SCORE
)) == (int) s7_FAIL
)
5914 demand_empty_rest_of_line ();
5916 /* Add $gp to the register named as an argument. */
5917 sprintf (insn_str
, "add r%d, r%d, r%d", reg
, reg
, s7_GP
);
5918 if (s7_append_insn (insn_str
, TRUE
) == (int) s7_FAIL
)
5922 #ifndef TC_IMPLICIT_LCOMM_ALIGNMENT
5923 #define TC_IMPLICIT_LCOMM_ALIGNMENT(SIZE, P2VAR) \
5928 else if ((SIZE) >= 4) \
5930 else if ((SIZE) >= 2) \
5939 s7_s_score_lcomm (int bytes_p
)
5946 segT current_seg
= now_seg
;
5947 subsegT current_subseg
= now_subseg
;
5948 const int max_alignment
= 15;
5950 segT bss_seg
= bss_section
;
5951 int needs_align
= 0;
5953 c
= get_symbol_name (&name
);
5954 p
= input_line_pointer
;
5959 as_bad (_("expected symbol name"));
5960 discard_rest_of_line ();
5964 SKIP_WHITESPACE_AFTER_NAME ();
5966 /* Accept an optional comma after the name. The comma used to be
5967 required, but Irix 5 cc does not generate it. */
5968 if (*input_line_pointer
== ',')
5970 ++input_line_pointer
;
5974 if (is_end_of_line
[(unsigned char)*input_line_pointer
])
5976 as_bad (_("missing size expression"));
5980 if ((temp
= get_absolute_expression ()) < 0)
5982 as_warn (_("BSS length (%d) < 0 ignored"), temp
);
5983 ignore_rest_of_line ();
5987 #if defined (TC_SCORE)
5988 if (OUTPUT_FLAVOR
== bfd_target_ecoff_flavour
|| OUTPUT_FLAVOR
== bfd_target_elf_flavour
)
5990 /* For Score and Alpha ECOFF or ELF, small objects are put in .sbss. */
5991 if ((unsigned) temp
<= bfd_get_gp_size (stdoutput
))
5993 bss_seg
= subseg_new (".sbss", 1);
5994 seg_info (bss_seg
)->bss
= 1;
5995 #ifdef BFD_ASSEMBLER
5996 if (!bfd_set_section_flags (stdoutput
, bss_seg
, SEC_ALLOC
))
5997 as_warn (_("error setting flags for \".sbss\": %s"), bfd_errmsg (bfd_get_error ()));
6004 if (*input_line_pointer
== ',')
6006 ++input_line_pointer
;
6009 if (is_end_of_line
[(unsigned char)*input_line_pointer
])
6011 as_bad (_("missing alignment"));
6016 align
= get_absolute_expression ();
6023 TC_IMPLICIT_LCOMM_ALIGNMENT (temp
, align
);
6025 /* Still zero unless TC_IMPLICIT_LCOMM_ALIGNMENT set it. */
6027 record_alignment (bss_seg
, align
);
6034 /* Convert to a power of 2. */
6039 for (i
= 0; align
!= 0; align
>>= 1, ++i
)
6045 if (align
> max_alignment
)
6047 align
= max_alignment
;
6048 as_warn (_("alignment too large; %d assumed"), align
);
6053 as_warn (_("alignment negative; 0 assumed"));
6056 record_alignment (bss_seg
, align
);
6060 /* Assume some objects may require alignment on some systems. */
6061 #if defined (TC_ALPHA) && ! defined (VMS)
6064 align
= ffs (temp
) - 1;
6065 if (temp
% (1 << align
))
6072 symbolP
= symbol_find_or_make (name
);
6076 #if (defined (OBJ_AOUT) || defined (OBJ_MAYBE_AOUT))
6077 #ifdef BFD_ASSEMBLER
6078 (OUTPUT_FLAVOR
!= bfd_target_aout_flavour
6079 || (S_GET_OTHER (symbolP
) == 0 && S_GET_DESC (symbolP
) == 0)) &&
6081 (S_GET_OTHER (symbolP
) == 0 && S_GET_DESC (symbolP
) == 0) &&
6084 (S_GET_SEGMENT (symbolP
) == bss_seg
|| (!S_IS_DEFINED (symbolP
) && S_GET_VALUE (symbolP
) == 0)))
6088 subseg_set (bss_seg
, 1);
6091 frag_align (align
, 0, 0);
6093 /* Detach from old frag. */
6094 if (S_GET_SEGMENT (symbolP
) == bss_seg
)
6095 symbol_get_frag (symbolP
)->fr_symbol
= NULL
;
6097 symbol_set_frag (symbolP
, frag_now
);
6098 pfrag
= frag_var (rs_org
, 1, 1, (relax_substateT
) 0, symbolP
, (offsetT
) temp
, NULL
);
6102 S_SET_SEGMENT (symbolP
, bss_seg
);
6105 /* The symbol may already have been created with a preceding
6106 ".globl" directive -- be careful not to step on storage class
6107 in that case. Otherwise, set it to static. */
6108 if (S_GET_STORAGE_CLASS (symbolP
) != C_EXT
)
6110 S_SET_STORAGE_CLASS (symbolP
, C_STAT
);
6112 #endif /* OBJ_COFF */
6115 S_SET_SIZE (symbolP
, temp
);
6119 as_bad (_("symbol `%s' is already defined"), S_GET_NAME (symbolP
));
6121 subseg_set (current_seg
, current_subseg
);
6123 demand_empty_rest_of_line ();
6135 if ((s7_score_ops_hsh
= hash_new ()) == NULL
)
6136 as_fatal (_("virtual memory exhausted"));
6138 s7_build_score_ops_hsh ();
6140 if ((s7_dependency_insn_hsh
= hash_new ()) == NULL
)
6141 as_fatal (_("virtual memory exhausted"));
6143 s7_build_dependency_insn_hsh ();
6145 for (i
= (int) REG_TYPE_FIRST
; i
< (int) s7_REG_TYPE_MAX
; i
++)
6146 s7_build_reg_hsh (s7_all_reg_maps
+ i
);
6148 /* Initialize dependency vector. */
6149 s7_init_dependency_vector ();
6151 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
, 0);
6153 subseg
= now_subseg
;
6154 s7_pdr_seg
= subseg_new (".pdr", (subsegT
) 0);
6155 (void) bfd_set_section_flags (stdoutput
, s7_pdr_seg
, SEC_READONLY
| SEC_RELOC
| SEC_DEBUGGING
);
6156 (void) bfd_set_section_alignment (stdoutput
, s7_pdr_seg
, 2);
6157 subseg_set (seg
, subseg
);
6159 if (s7_USE_GLOBAL_POINTER_OPT
)
6160 bfd_set_gp_size (stdoutput
, s7_g_switch_value
);
6164 s7_assemble (char *str
)
6167 know (strlen (str
) < s7_MAX_LITERAL_POOL_SIZE
);
6169 memset (&s7_inst
, '\0', sizeof (s7_inst
));
6170 if (s7_INSN_IS_PCE_P (str
))
6171 s7_parse_pce_inst (str
);
6173 s7_parse_16_32_inst (str
, TRUE
);
6176 as_bad (_("%s -- `%s'"), s7_inst
.error
, s7_inst
.str
);
6179 /* We handle all bad expressions here, so that we can report the faulty
6180 instruction in the error message. */
6183 s7_operand (expressionS
* exp
)
6185 if (s7_in_my_get_expression
)
6187 exp
->X_op
= O_illegal
;
6188 if (s7_inst
.error
== NULL
)
6190 s7_inst
.error
= _("bad expression");
6195 /* Turn a string in input_line_pointer into a floating point constant
6196 of type TYPE, and store the appropriate bytes in *LITP. The number
6197 of LITTLENUMS emitted is stored in *SIZEP. An error message is
6198 returned, or NULL on OK.
6200 Note that fp constants aren't represent in the normal way on the ARM.
6201 In big endian mode, things are as expected. However, in little endian
6202 mode fp constants are big-endian word-wise, and little-endian byte-wise
6203 within the words. For example, (double) 1.1 in big endian mode is
6204 the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
6205 the byte sequence 99 99 f1 3f 9a 99 99 99. */
6208 s7_atof (int type
, char *litP
, int *sizeP
)
6211 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
6237 return _("bad call to MD_ATOF()");
6240 t
= atof_ieee (input_line_pointer
, type
, words
);
6242 input_line_pointer
= t
;
6245 if (target_big_endian
)
6247 for (i
= 0; i
< prec
; i
++)
6249 s7_number_to_chars (litP
, (valueT
) words
[i
], 2);
6255 for (i
= 0; i
< prec
; i
+= 2)
6257 s7_number_to_chars (litP
, (valueT
) words
[i
+ 1], 2);
6258 s7_number_to_chars (litP
+ 2, (valueT
) words
[i
], 2);
6266 /* Implementation of md_frag_check.
6267 Called after md_convert_frag(). */
6270 s7_frag_check (fragS
* fragp ATTRIBUTE_UNUSED
)
6272 know (fragp
->insn_addr
<= s7_RELAX_PAD_BYTE
);
6275 /* Implementation of TC_VALIDATE_FIX.
6276 Called before md_apply_fix() and after md_convert_frag(). */
6279 s7_validate_fix (fixS
*fixP
)
6281 fixP
->fx_where
+= fixP
->fx_frag
->insn_addr
;
6285 s7_force_relocation (struct fix
*fixp
)
6289 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
6290 || fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
6291 || fixp
->fx_r_type
== BFD_RELOC_SCORE_JMP
6292 || fixp
->fx_r_type
== BFD_RELOC_SCORE_BRANCH
6293 || fixp
->fx_r_type
== BFD_RELOC_SCORE16_JMP
6294 || fixp
->fx_r_type
== BFD_RELOC_SCORE16_BRANCH
)
6303 s7_fix_adjustable (fixS
* fixP
)
6305 if (fixP
->fx_addsy
== NULL
)
6309 else if (OUTPUT_FLAVOR
== bfd_target_elf_flavour
6310 && (S_IS_EXTERNAL (fixP
->fx_addsy
) || S_IS_WEAK (fixP
->fx_addsy
)))
6314 else if (fixP
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
6315 || fixP
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
6316 || fixP
->fx_r_type
== BFD_RELOC_SCORE_JMP
6317 || fixP
->fx_r_type
== BFD_RELOC_SCORE16_JMP
)
6326 s7_elf_final_processing (void)
6328 unsigned long val
= E_SCORE_MACH_SCORE7
;
6330 elf_elfheader (stdoutput
)->e_machine
= EM_SCORE
;
6331 elf_elfheader (stdoutput
)->e_flags
&= ~EF_SCORE_MACH
;
6332 elf_elfheader (stdoutput
)->e_flags
|= val
;
6334 if (s7_fix_data_dependency
== 1)
6336 elf_elfheader (stdoutput
)->e_flags
|= EF_SCORE_FIXDEP
;
6338 if (s7_score_pic
== s7_PIC
)
6340 elf_elfheader (stdoutput
)->e_flags
|= EF_SCORE_PIC
;
6344 /* In this function, we determine whether s7_GP instruction should do relaxation,
6345 for the label being against was known now.
6346 Doing this here but not in md_relax_frag() can induce iteration times
6347 in stage of doing relax. */
6350 s7_estimate_size_before_relax (fragS
* fragp
, asection
* sec
)
6352 if ((s7_RELAX_TYPE (fragp
->fr_subtype
) == Insn_GP
)
6353 || (s7_RELAX_TYPE (fragp
->fr_subtype
) == Insn_PIC
))
6354 return s7_judge_size_before_relax (fragp
, sec
);
6360 s7_relax_frag (asection
* sec ATTRIBUTE_UNUSED
,
6362 long stretch ATTRIBUTE_UNUSED
)
6366 int do_relax_p
= 0; /* Indicate doing relaxation for this frag. */
6367 int relaxable_p
= 0;
6368 bfd_boolean word_align_p
= FALSE
;
6371 /* If the instruction address is odd, make it half word align first. */
6372 if ((fragp
->fr_address
) % 2 != 0)
6374 if ((fragp
->fr_address
+ fragp
->insn_addr
) % 2 != 0)
6376 fragp
->insn_addr
= 1;
6381 word_align_p
= ((fragp
->fr_address
+ fragp
->insn_addr
) % 4 == 0) ? TRUE
: FALSE
;
6383 /* Get instruction size and relax size after the last relaxation. */
6384 if (fragp
->fr_opcode
)
6385 insn_size
= s7_RELAX_NEW (fragp
->fr_subtype
);
6387 insn_size
= s7_RELAX_OLD (fragp
->fr_subtype
);
6389 /* Handle specially for s7_GP instruction. for, s7_judge_size_before_relax() has already determine
6390 whether the s7_GP instruction should do relax. */
6391 if ((s7_RELAX_TYPE (fragp
->fr_subtype
) == Insn_GP
)
6392 || (s7_RELAX_TYPE (fragp
->fr_subtype
) == Insn_PIC
))
6396 if (fragp
->insn_addr
< 2)
6398 fragp
->insn_addr
+= 2;
6403 fragp
->insn_addr
-= 2;
6408 if (fragp
->fr_opcode
)
6409 fragp
->fr_fix
= s7_RELAX_NEW (fragp
->fr_subtype
) + fragp
->insn_addr
;
6411 fragp
->fr_fix
= s7_RELAX_OLD (fragp
->fr_subtype
) + fragp
->insn_addr
;
6415 if (s7_RELAX_TYPE (fragp
->fr_subtype
) == PC_DISP19div2
)
6416 s7_b32_relax_to_b16 (fragp
);
6418 relaxable_p
= s7_RELAX_OPT (fragp
->fr_subtype
);
6419 next_fragp
= fragp
->fr_next
;
6420 while ((next_fragp
) && (next_fragp
->fr_type
!= rs_machine_dependent
))
6422 next_fragp
= next_fragp
->fr_next
;
6428 int n_relaxable_p
= 0;
6430 if (next_fragp
->fr_opcode
)
6432 n_insn_size
= s7_RELAX_NEW (next_fragp
->fr_subtype
);
6436 n_insn_size
= s7_RELAX_OLD (next_fragp
->fr_subtype
);
6439 if (s7_RELAX_TYPE (next_fragp
->fr_subtype
) == PC_DISP19div2
)
6440 s7_b32_relax_to_b16 (next_fragp
);
6441 n_relaxable_p
= s7_RELAX_OPT (next_fragp
->fr_subtype
);
6448 if (relaxable_p
&& ((n_insn_size
== 2) || n_relaxable_p
))
6454 else if (insn_size
== 2)
6457 if (relaxable_p
&& (((n_insn_size
== 4) && !n_relaxable_p
) || (n_insn_size
> 4)))
6478 /* Make the 32 bit instruction word align. */
6481 fragp
->insn_addr
+= 2;
6485 else if (insn_size
== 2)
6497 /* Here, try best to do relax regardless fragp->fr_next->fr_type. */
6500 if (insn_size
% 4 == 0)
6510 fragp
->insn_addr
+= 2;
6521 /* fragp->fr_opcode indicates whether this frag should be relaxed. */
6524 if (fragp
->fr_opcode
)
6526 fragp
->fr_opcode
= NULL
;
6527 /* Guarantee estimate stage is correct. */
6528 fragp
->fr_fix
= s7_RELAX_OLD (fragp
->fr_subtype
);
6529 fragp
->fr_fix
+= fragp
->insn_addr
;
6533 fragp
->fr_opcode
= fragp
->fr_literal
+ s7_RELAX_RELOC1 (fragp
->fr_subtype
);
6534 /* Guarantee estimate stage is correct. */
6535 fragp
->fr_fix
= s7_RELAX_NEW (fragp
->fr_subtype
);
6536 fragp
->fr_fix
+= fragp
->insn_addr
;
6541 if (fragp
->fr_opcode
)
6543 /* Guarantee estimate stage is correct. */
6544 fragp
->fr_fix
= s7_RELAX_NEW (fragp
->fr_subtype
);
6545 fragp
->fr_fix
+= fragp
->insn_addr
;
6549 /* Guarantee estimate stage is correct. */
6550 fragp
->fr_fix
= s7_RELAX_OLD (fragp
->fr_subtype
);
6551 fragp
->fr_fix
+= fragp
->insn_addr
;
6560 s7_convert_frag (bfd
* abfd ATTRIBUTE_UNUSED
,
6561 segT sec ATTRIBUTE_UNUSED
,
6569 r_old
= s7_RELAX_OLD (fragp
->fr_subtype
);
6570 r_new
= s7_RELAX_NEW (fragp
->fr_subtype
);
6572 /* fragp->fr_opcode indicates whether this frag should be relaxed. */
6573 if (fragp
->fr_opcode
== NULL
)
6575 memcpy (backup
, fragp
->fr_literal
, r_old
);
6576 fragp
->fr_fix
= r_old
;
6580 memcpy (backup
, fragp
->fr_literal
+ r_old
, r_new
);
6581 fragp
->fr_fix
= r_new
;
6584 fixp
= fragp
->tc_frag_data
.fixp
;
6585 while (fixp
&& fixp
->fx_frag
== fragp
&& fixp
->fx_where
< r_old
)
6587 if (fragp
->fr_opcode
)
6589 fixp
= fixp
->fx_next
;
6591 while (fixp
&& fixp
->fx_frag
== fragp
)
6593 if (fragp
->fr_opcode
)
6594 fixp
->fx_where
-= r_old
+ fragp
->insn_addr
;
6597 fixp
= fixp
->fx_next
;
6600 if (fragp
->insn_addr
)
6602 s7_number_to_chars (fragp
->fr_literal
, 0x0, fragp
->insn_addr
);
6604 memcpy (fragp
->fr_literal
+ fragp
->insn_addr
, backup
, fragp
->fr_fix
);
6605 fragp
->fr_fix
+= fragp
->insn_addr
;
6609 s7_pcrel_from (fixS
* fixP
)
6614 && (S_GET_SEGMENT (fixP
->fx_addsy
) == undefined_section
)
6615 && (fixP
->fx_subsy
== NULL
))
6621 retval
= fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
6627 /* Round up a section size to the appropriate boundary. */
6629 s7_section_align (segT segment
, valueT size
)
6631 int align
= bfd_get_section_alignment (stdoutput
, segment
);
6633 return ((size
+ (1 << align
) - 1) & -(1 << align
));
6637 s7_apply_fix (fixS
*fixP
, valueT
*valP
, segT seg
)
6639 offsetT value
= *valP
;
6640 offsetT abs_value
= 0;
6643 unsigned short HI
, LO
;
6645 char *buf
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
6647 gas_assert (fixP
->fx_r_type
< BFD_RELOC_UNUSED
);
6648 if (fixP
->fx_addsy
== 0 && !fixP
->fx_pcrel
)
6650 if (fixP
->fx_r_type
!= BFD_RELOC_SCORE_DUMMY_HI16
)
6654 /* If this symbol is in a different section then we need to leave it for
6655 the linker to deal with. Unfortunately, md_pcrel_from can't tell,
6656 so we have to undo it's effects here. */
6659 if (fixP
->fx_addsy
!= NULL
6660 && S_IS_DEFINED (fixP
->fx_addsy
)
6661 && S_GET_SEGMENT (fixP
->fx_addsy
) != seg
)
6662 value
+= md_pcrel_from (fixP
);
6665 /* Remember value for emit_reloc. */
6666 fixP
->fx_addnumber
= value
;
6668 switch (fixP
->fx_r_type
)
6670 case BFD_RELOC_HI16_S
:
6672 { /* For la rd, imm32. */
6673 newval
= s7_md_chars_to_number (buf
, s7_INSN_SIZE
);
6674 HI
= (value
) >> 16; /* mul to 2, then take the hi 16 bit. */
6675 newval
|= (HI
& 0x3fff) << 1;
6676 newval
|= ((HI
>> 14) & 0x3) << 16;
6677 s7_number_to_chars (buf
, newval
, s7_INSN_SIZE
);
6680 case BFD_RELOC_LO16
:
6681 if (fixP
->fx_done
) /* For la rd, imm32. */
6683 newval
= s7_md_chars_to_number (buf
, s7_INSN_SIZE
);
6684 LO
= (value
) & 0xffff;
6685 newval
|= (LO
& 0x3fff) << 1; /* 16 bit: imm -> 14 bit in lo, 2 bit in hi. */
6686 newval
|= ((LO
>> 14) & 0x3) << 16;
6687 s7_number_to_chars (buf
, newval
, s7_INSN_SIZE
);
6690 case BFD_RELOC_SCORE_JMP
:
6692 content
= s7_md_chars_to_number (buf
, s7_INSN_SIZE
);
6693 value
= fixP
->fx_offset
;
6694 if (!(value
>= 0 && value
<= 0x1ffffff))
6696 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6697 _("j or jl truncate (0x%x) [0 ~ 2^25-1]"), (unsigned int) value
);
6700 content
= (content
& ~0x3ff7ffe) | ((value
<< 1) & 0x3ff0000) | (value
& 0x7fff);
6701 s7_number_to_chars (buf
, content
, s7_INSN_SIZE
);
6704 case BFD_RELOC_SCORE_BRANCH
:
6705 if ((S_GET_SEGMENT (fixP
->fx_addsy
) != seg
) || (fixP
->fx_addsy
!= NULL
&& S_IS_EXTERNAL (fixP
->fx_addsy
)))
6706 value
= fixP
->fx_offset
;
6710 content
= s7_md_chars_to_number (buf
, s7_INSN_SIZE
);
6711 if ((fixP
->fx_frag
->fr_opcode
!= 0) && ((content
& 0x80008000) != 0x80008000))
6713 if ((value
& 0x80000000) == 0x80000000)
6714 abs_value
= 0xffffffff - value
+ 1;
6715 if ((abs_value
& 0xffffff00) != 0)
6717 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6718 _(" branch relocation truncate (0x%x) [-2^8 ~ 2^8]"), (unsigned int) value
);
6721 content
= s7_md_chars_to_number (buf
, s7_INSN16_SIZE
);
6723 content
= (content
& 0xff00) | ((value
>> 1) & 0xff);
6724 s7_number_to_chars (buf
, content
, s7_INSN16_SIZE
);
6725 fixP
->fx_r_type
= BFD_RELOC_SCORE16_BRANCH
;
6730 if ((value
& 0x80000000) == 0x80000000)
6731 abs_value
= 0xffffffff - value
+ 1;
6732 if ((abs_value
& 0xfff80000) != 0)
6734 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6735 _(" branch relocation truncate (0x%x) [-2^19 ~ 2^19]"),
6736 (unsigned int) value
);
6739 content
= s7_md_chars_to_number (buf
, s7_INSN_SIZE
);
6740 content
&= 0xfc00fc01;
6741 content
= (content
& 0xfc00fc01) | (value
& 0x3fe) | ((value
<< 6) & 0x3ff0000);
6742 s7_number_to_chars (buf
, content
, s7_INSN_SIZE
);
6745 case BFD_RELOC_SCORE16_JMP
:
6746 content
= s7_md_chars_to_number (buf
, s7_INSN16_SIZE
);
6748 value
= fixP
->fx_offset
;
6749 if (!(value
>= 0 && value
<= 0xfff))
6751 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6752 _("j! or jl! truncate (0x%x) [0 ~ 2^12-1]"), (unsigned int) value
);
6755 value
= fixP
->fx_offset
& 0xfff;
6756 content
= (content
& 0xfc01) | (value
& 0xffe);
6757 s7_number_to_chars (buf
, content
, s7_INSN16_SIZE
);
6759 case BFD_RELOC_SCORE16_BRANCH
:
6760 content
= s7_md_chars_to_number (buf
, s7_INSN_SIZE
);
6761 if ((fixP
->fx_frag
->fr_opcode
!= 0) && ((content
& 0x80008000) == 0x80008000))
6763 if ((S_GET_SEGMENT (fixP
->fx_addsy
) != seg
) ||
6764 (fixP
->fx_addsy
!= NULL
&& S_IS_EXTERNAL (fixP
->fx_addsy
)))
6765 value
= fixP
->fx_offset
;
6769 if ((value
& 0xfff80000) != 0 && (value
& 0xfff80000) != 0xfff80000)
6771 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6772 _(" branch relocation truncate (0x%x) [-2^19 ~ 2^19]"),
6773 (unsigned int) value
);
6776 content
= s7_md_chars_to_number (buf
, s7_INSN_SIZE
);
6777 content
= (content
& 0xfc00fc01) | (value
& 0x3fe) | ((value
<< 6) & 0x3ff0000);
6778 s7_number_to_chars (buf
, content
, s7_INSN_SIZE
);
6779 fixP
->fx_r_type
= BFD_RELOC_SCORE_BRANCH
;
6785 /* In different section. */
6786 if ((S_GET_SEGMENT (fixP
->fx_addsy
) != seg
) ||
6787 (fixP
->fx_addsy
!= NULL
&& S_IS_EXTERNAL (fixP
->fx_addsy
)))
6788 value
= fixP
->fx_offset
;
6792 if ((value
& 0xffffff00) != 0 && (value
& 0xffffff00) != 0xffffff00)
6794 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6795 _(" branch relocation truncate (0x%x) [-2^8 ~ 2^8]"),
6796 (unsigned int) value
);
6799 content
= s7_md_chars_to_number (buf
, s7_INSN16_SIZE
);
6800 content
= (content
& 0xff00) | ((value
>> 1) & 0xff);
6801 s7_number_to_chars (buf
, content
, s7_INSN16_SIZE
);
6805 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
6806 s7_number_to_chars (buf
, value
, 1);
6810 value
= fixP
->fx_offset
;
6811 s7_number_to_chars (buf
, value
, 1);
6817 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
6818 s7_number_to_chars (buf
, value
, 2);
6822 value
= fixP
->fx_offset
;
6823 s7_number_to_chars (buf
, value
, 2);
6829 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
6830 s7_number_to_chars (buf
, value
, 4);
6834 value
= fixP
->fx_offset
;
6835 s7_number_to_chars (buf
, value
, 4);
6839 case BFD_RELOC_VTABLE_INHERIT
:
6841 if (fixP
->fx_addsy
&& !S_IS_DEFINED (fixP
->fx_addsy
) && !S_IS_WEAK (fixP
->fx_addsy
))
6842 S_SET_WEAK (fixP
->fx_addsy
);
6844 case BFD_RELOC_VTABLE_ENTRY
:
6847 case BFD_RELOC_SCORE_GPREL15
:
6848 content
= s7_md_chars_to_number (buf
, s7_INSN_SIZE
);
6849 if ((fixP
->fx_frag
->fr_opcode
!= 0) && ((content
& 0xfc1c8000) != 0x94188000))
6850 fixP
->fx_r_type
= BFD_RELOC_NONE
;
6853 case BFD_RELOC_SCORE_GOT15
:
6854 case BFD_RELOC_SCORE_DUMMY_HI16
:
6855 case BFD_RELOC_SCORE_GOT_LO16
:
6856 case BFD_RELOC_SCORE_CALL15
:
6857 case BFD_RELOC_GPREL32
:
6859 case BFD_RELOC_NONE
:
6861 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("bad relocation fixup type (%d)"), fixP
->fx_r_type
);
6865 /* Translate internal representation of relocation info to BFD target format. */
6868 s7_gen_reloc (asection
* section ATTRIBUTE_UNUSED
, fixS
* fixp
)
6870 static arelent
*retval
[MAX_RELOC_EXPANSION
+ 1]; /* MAX_RELOC_EXPANSION equals 2. */
6872 bfd_reloc_code_real_type code
;
6875 reloc
= retval
[0] = XNEW (arelent
);
6878 reloc
->sym_ptr_ptr
= XNEW (asymbol
*);
6879 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
6880 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
6881 reloc
->addend
= fixp
->fx_offset
;
6883 /* If this is a variant frag, we may need to adjust the existing
6884 reloc and generate a new one. */
6885 if (fixp
->fx_frag
->fr_opcode
!= NULL
&& (fixp
->fx_r_type
== BFD_RELOC_SCORE_GPREL15
))
6887 /* Update instruction imm bit. */
6892 buf
= fixp
->fx_frag
->fr_literal
+ fixp
->fx_frag
->insn_addr
;
6893 newval
= s7_md_chars_to_number (buf
, s7_INSN_SIZE
);
6894 off
= fixp
->fx_offset
>> 16;
6895 newval
|= (off
& 0x3fff) << 1;
6896 newval
|= ((off
>> 14) & 0x3) << 16;
6897 s7_number_to_chars (buf
, newval
, s7_INSN_SIZE
);
6899 buf
+= s7_INSN_SIZE
;
6900 newval
= s7_md_chars_to_number (buf
, s7_INSN_SIZE
);
6901 off
= fixp
->fx_offset
& 0xffff;
6902 newval
|= ((off
& 0x3fff) << 1);
6903 newval
|= (((off
>> 14) & 0x3) << 16);
6904 s7_number_to_chars (buf
, newval
, s7_INSN_SIZE
);
6906 retval
[1] = XNEW (arelent
);
6908 retval
[1]->sym_ptr_ptr
= XNEW (asymbol
*);
6909 *retval
[1]->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
6910 retval
[1]->address
= (reloc
->address
+ s7_RELAX_RELOC2 (fixp
->fx_frag
->fr_subtype
));
6912 retval
[1]->addend
= 0;
6913 retval
[1]->howto
= bfd_reloc_type_lookup (stdoutput
, BFD_RELOC_LO16
);
6914 gas_assert (retval
[1]->howto
!= NULL
);
6916 fixp
->fx_r_type
= BFD_RELOC_HI16_S
;
6919 code
= fixp
->fx_r_type
;
6920 switch (fixp
->fx_r_type
)
6925 code
= BFD_RELOC_32_PCREL
;
6929 case BFD_RELOC_HI16_S
:
6930 case BFD_RELOC_LO16
:
6931 case BFD_RELOC_SCORE_JMP
:
6932 case BFD_RELOC_SCORE_BRANCH
:
6933 case BFD_RELOC_SCORE16_JMP
:
6934 case BFD_RELOC_SCORE16_BRANCH
:
6935 case BFD_RELOC_VTABLE_ENTRY
:
6936 case BFD_RELOC_VTABLE_INHERIT
:
6937 case BFD_RELOC_SCORE_GPREL15
:
6938 case BFD_RELOC_SCORE_GOT15
:
6939 case BFD_RELOC_SCORE_DUMMY_HI16
:
6940 case BFD_RELOC_SCORE_GOT_LO16
:
6941 case BFD_RELOC_SCORE_CALL15
:
6942 case BFD_RELOC_GPREL32
:
6943 case BFD_RELOC_NONE
:
6944 code
= fixp
->fx_r_type
;
6947 type
= _("<unknown>");
6948 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
6949 _("cannot represent %s relocation in this object file format"), type
);
6953 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
6954 if (reloc
->howto
== NULL
)
6956 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
6957 _("cannot represent %s relocation in this object file format1"),
6958 bfd_get_reloc_code_name (code
));
6961 /* HACK: Since arm ELF uses Rel instead of Rela, encode the
6962 vtable entry to be used in the relocation's section offset. */
6963 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
6964 reloc
->address
= fixp
->fx_offset
;