1 /* tc-score.c -- Assembler for Score
2 Copyright (C) 2006-2025 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, MA
25 #include "tc-score7.c"
27 static void s3_score_s_section (int ignore
);
28 static void s3_s_change_sec (int sec
);
29 static void s3_s_score_mask (int reg_type ATTRIBUTE_UNUSED
);
30 static void s3_s_score_ent (int aent
);
31 static void s3_s_score_frame (int ignore ATTRIBUTE_UNUSED
);
32 static void s3_s_score_end (int x ATTRIBUTE_UNUSED
);
33 static void s3_s_score_set (int x ATTRIBUTE_UNUSED
);
34 static void s3_s_score_cpload (int ignore ATTRIBUTE_UNUSED
);
35 static void s3_s_score_cprestore (int ignore ATTRIBUTE_UNUSED
);
36 static void s3_s_score_gpword (int ignore ATTRIBUTE_UNUSED
);
37 static void s3_s_score_cpadd (int ignore ATTRIBUTE_UNUSED
);
38 static void s3_s_score_lcomm (int bytes_p
);
40 static void s_score_text (int ignore
);
41 static void s_section (int ignore
);
42 static void s_change_sec (int sec
);
43 static void s_score_mask (int reg_type ATTRIBUTE_UNUSED
);
44 static void s_score_ent (int aent
);
45 static void s_score_frame (int ignore ATTRIBUTE_UNUSED
);
46 static void s_score_end (int x ATTRIBUTE_UNUSED
);
47 static void s_score_set (int x ATTRIBUTE_UNUSED
);
48 static void s_score_cpload (int ignore ATTRIBUTE_UNUSED
);
49 static void s_score_cprestore (int ignore ATTRIBUTE_UNUSED
);
50 static void s_score_gpword (int ignore ATTRIBUTE_UNUSED
);
51 static void s_score_cpadd (int ignore ATTRIBUTE_UNUSED
);
52 static void s_score_lcomm (int bytes_p
);
55 static void s3_md_number_to_chars (char *buf
, valueT val
, int n
);
56 static valueT
s3_md_chars_to_number (char *buf
, int n
);
57 static void s3_assemble (char *str
);
58 static void s3_operand (expressionS
*);
59 static void s3_begin (void);
60 static void s3_number_to_chars (char *buf
, valueT val
, int n
);
61 static const char *s3_atof (int type
, char *litP
, int *sizeP
);
62 static void s3_frag_check (fragS
* fragp ATTRIBUTE_UNUSED
);
63 static void s3_validate_fix (fixS
*fixP
);
64 static int s3_force_relocation (struct fix
*fixp
);
65 static bool s3_fix_adjustable (fixS
* fixP
);
66 static void s3_elf_final_processing (void);
67 static int s3_estimate_size_before_relax (fragS
* fragp
, asection
* sec ATTRIBUTE_UNUSED
);
68 static int s3_relax_frag (asection
* sec ATTRIBUTE_UNUSED
, fragS
* fragp
, long stretch ATTRIBUTE_UNUSED
);
69 static void s3_convert_frag (bfd
* abfd ATTRIBUTE_UNUSED
, segT sec ATTRIBUTE_UNUSED
, fragS
* fragp
);
70 static long s3_pcrel_from (fixS
* fixP
);
71 static valueT
s3_section_align (segT segment ATTRIBUTE_UNUSED
, valueT size
);
72 static void s3_apply_fix (fixS
*fixP
, valueT
*valP
, segT seg
);
73 static arelent
**s3_gen_reloc (asection
* section ATTRIBUTE_UNUSED
, fixS
* fixp
);
76 static void s3_do_ldst_insn (char *);
77 static void s3_do_crdcrscrsimm5 (char *);
78 static void s3_do_ldst_unalign (char *);
79 static void s3_do_ldst_atomic (char *);
80 static void s3_do_ldst_cop (char *);
81 static void s3_do_macro_li_rdi32 (char *);
82 static void s3_do_macro_la_rdi32 (char *);
83 static void s3_do_macro_rdi32hi (char *);
84 static void s3_do_macro_rdi32lo (char *);
85 static void s3_do_macro_mul_rdrsrs (char *);
86 static void s3_do_macro_bcmp (char *);
87 static void s3_do_macro_bcmpz (char *);
88 static void s3_do_macro_ldst_label (char *);
89 static void s3_do_branch (char *);
90 static void s3_do_jump (char *);
91 static void s3_do_empty (char *);
92 static void s3_do16_int (char *);
93 static void s3_do_rdrsrs (char *);
94 static void s3_do_rdsi16 (char *);
95 static void s3_do_rdrssi14 (char *);
96 static void s3_do_sub_rdsi16 (char *);
97 static void s3_do_sub_rdi16 (char *);
98 static void s3_do_sub_rdrssi14 (char *);
99 static void s3_do_rdrsi5 (char *);
100 static void s3_do_rdrsi14 (char *);
101 static void s3_do_rdi16 (char *);
102 static void s3_do_ldis (char *);
103 static void s3_do_xrsi5 (char *);
104 static void s3_do_rdrs (char *);
105 static void s3_do_rdxrs (char *);
106 static void s3_do_rsrs (char *);
107 static void s3_do_rdcrs (char *);
108 static void s3_do_rdsrs (char *);
109 static void s3_do_rd (char *);
110 static void s3_do16_dsp (char *);
111 static void s3_do16_dsp2 (char *);
112 static void s3_do_dsp (char *);
113 static void s3_do_dsp2 (char *);
114 static void s3_do_dsp3 (char *);
115 static void s3_do_rs (char *);
116 static void s3_do_i15 (char *);
117 static void s3_do_xi5x (char *);
118 static void s3_do_ceinst (char *);
119 static void s3_do_cache (char *);
120 static void s3_do16_rdrs2 (char *);
121 static void s3_do16_br (char *);
122 static void s3_do16_brr (char *);
123 static void s3_do_ltb (char *);
124 static void s3_do16_mv_cmp (char *);
125 static void s3_do16_addi (char *);
126 static void s3_do16_cmpi (char *);
127 static void s3_do16_rdi5 (char *);
128 static void s3_do16_xi5 (char *);
129 static void s3_do16_ldst_insn (char *);
130 static void s3_do16_slli_srli (char *);
131 static void s3_do16_ldiu (char *);
132 static void s3_do16_push_pop (char *);
133 static void s3_do16_rpush (char *);
134 static void s3_do16_rpop (char *);
135 static void s3_do16_branch (char *);
136 static void s3_do_lw48 (char *);
137 static void s3_do_sw48 (char *);
138 static void s3_do_ldi48 (char *);
139 static void s3_do_sdbbp48 (char *);
140 static void s3_do_and48 (char *);
141 static void s3_do_or48 (char *);
142 static void s3_do_mbitclr (char *);
143 static void s3_do_mbitset (char *);
144 static void s3_do_rdi16_pic (char *);
145 static void s3_do_addi_s_pic (char *);
146 static void s3_do_addi_u_pic (char *);
147 static void s3_do_lw_pic (char *);
149 #define MARCH_SCORE3 "score3"
150 #define MARCH_SCORE3D "score3d"
151 #define MARCH_SCORE7 "score7"
152 #define MARCH_SCORE7D "score7d"
153 #define MARCH_SCORE5 "score5"
154 #define MARCH_SCORE5U "score5u"
156 #define SCORE_BI_ENDIAN
158 #ifdef SCORE_BI_ENDIAN
159 #define OPTION_EB (OPTION_MD_BASE + 0)
160 #define OPTION_EL (OPTION_MD_BASE + 1)
162 #if TARGET_BYTES_BIG_ENDIAN
163 #define OPTION_EB (OPTION_MD_BASE + 0)
165 #define OPTION_EL (OPTION_MD_BASE + 1)
168 #define OPTION_FIXDD (OPTION_MD_BASE + 2)
169 #define OPTION_NWARN (OPTION_MD_BASE + 3)
170 #define OPTION_SCORE5 (OPTION_MD_BASE + 4)
171 #define OPTION_SCORE5U (OPTION_MD_BASE + 5)
172 #define OPTION_SCORE7 (OPTION_MD_BASE + 6)
173 #define OPTION_R1 (OPTION_MD_BASE + 7)
174 #define OPTION_O0 (OPTION_MD_BASE + 8)
175 #define OPTION_SCORE_VERSION (OPTION_MD_BASE + 9)
176 #define OPTION_PIC (OPTION_MD_BASE + 10)
177 #define OPTION_MARCH (OPTION_MD_BASE + 11)
178 #define OPTION_SCORE3 (OPTION_MD_BASE + 12)
180 /* This array holds the chars that always start a comment. If the
181 pre-processor is disabled, these aren't very useful. */
182 const char comment_chars
[] = "#";
183 const char line_comment_chars
[] = "#";
184 const char line_separator_chars
[] = ";";
185 /* Chars that can be used to separate mant from exp in floating point numbers. */
186 const char EXP_CHARS
[] = "eE";
187 const char FLT_CHARS
[] = "rRsSfFdDxXeEpP";
190 /* Pre-defined "_GLOBAL_OFFSET_TABLE_" */
194 const pseudo_typeS md_pseudo_table
[] =
196 {"text", s_score_text
, 0},
199 {"extend", float_cons
, 'x'},
200 {"ldouble", float_cons
, 'x'},
201 {"packed", float_cons
, 'p'},
202 {"end", s_score_end
, 0},
203 {"ent", s_score_ent
, 0},
204 {"frame", s_score_frame
, 0},
205 {"rdata", s_change_sec
, 'r'},
206 {"sdata", s_change_sec
, 's'},
207 {"set", s_score_set
, 0},
208 {"mask", s_score_mask
, 'R'},
210 {"lcomm", s_score_lcomm
, 1},
211 {"section", s_section
, 0},
212 {"cpload", s_score_cpload
, 0},
213 {"cprestore", s_score_cprestore
, 0},
214 {"gpword", s_score_gpword
, 0},
215 {"cpadd", s_score_cpadd
, 0},
219 const char md_shortopts
[] = "nO::g::G:";
220 const struct option md_longopts
[] =
223 {"EB" , no_argument
, NULL
, OPTION_EB
},
226 {"EL" , no_argument
, NULL
, OPTION_EL
},
228 {"FIXDD" , no_argument
, NULL
, OPTION_FIXDD
},
229 {"NWARN" , no_argument
, NULL
, OPTION_NWARN
},
230 {"SCORE5" , no_argument
, NULL
, OPTION_SCORE5
},
231 {"SCORE5U", no_argument
, NULL
, OPTION_SCORE5U
},
232 {"SCORE7" , no_argument
, NULL
, OPTION_SCORE7
},
233 {"USE_R1" , no_argument
, NULL
, OPTION_R1
},
234 {"O0" , no_argument
, NULL
, OPTION_O0
},
235 {"V" , no_argument
, NULL
, OPTION_SCORE_VERSION
},
236 {"KPIC" , no_argument
, NULL
, OPTION_PIC
},
237 {"march=" , required_argument
, NULL
, OPTION_MARCH
},
238 {"SCORE3" , no_argument
, NULL
, OPTION_SCORE3
},
239 {NULL
, no_argument
, NULL
, 0}
242 const size_t md_longopts_size
= sizeof (md_longopts
);
245 #define s3_PIC_CALL_REG 29
246 #define s3_MAX_LITERAL_POOL_SIZE 1024
247 #define s3_FAIL 0x80000000
249 #define s3_INSN48_SIZE 6
250 #define s3_INSN_SIZE 4
251 #define s3_INSN16_SIZE 2
252 #define s3_RELAX_INST_NUM 3
254 /* For score5u : div/mul will pop warning message, mmu/alw/asw will pop error message. */
255 #define s3_BAD_ARGS _("bad arguments to instruction")
256 #define s3_ERR_FOR_SCORE5U_MUL_DIV _("div / mul are reserved instructions")
257 #define s3_ERR_FOR_SCORE5U_MMU _("This architecture doesn't support mmu")
258 #define s3_ERR_FOR_SCORE5U_ATOMIC _("This architecture doesn't support atomic instruction")
259 #define s3_BAD_SKIP_COMMA s3_BAD_ARGS
260 #define s3_BAD_GARBAGE _("garbage following instruction");
262 #define s3_skip_whitespace(str) while (*(str) == ' ') ++(str)
264 /* The name of the readonly data section. */
265 #define s3_RDATA_SECTION_NAME (OUTPUT_FLAVOR == bfd_target_aout_flavour \
267 : OUTPUT_FLAVOR == bfd_target_ecoff_flavour \
269 : OUTPUT_FLAVOR == bfd_target_coff_flavour \
271 : OUTPUT_FLAVOR == bfd_target_elf_flavour \
275 #define s3_RELAX_ENCODE(old, new, type, reloc1, reloc2, opt) \
284 #define s3_RELAX_OLD(i) (((i) >> 23) & 0x7f)
285 #define s3_RELAX_NEW(i) (((i) >> 16) & 0x7f)
286 #define s3_RELAX_TYPE(i) (((i) >> 9) & 0x7f)
287 #define s3_RELAX_RELOC1(i) ((valueT) ((i) >> 5) & 0xf)
288 #define s3_RELAX_RELOC2(i) ((valueT) ((i) >> 1) & 0xf)
289 #define s3_RELAX_OPT(i) ((i) & 1)
291 #define s3_SET_INSN_ERROR(s) (s3_inst.error = (s))
292 #define s3_INSN_IS_PCE_P(s) (strstr (str, "||") != NULL)
293 #define s3_INSN_IS_48_P(s) (strstr (str, "48") != NULL)
294 #define s3_GET_INSN_CLASS(type) (s3_get_insn_class_from_type (type))
295 #define s3_GET_INSN_SIZE(type) ((s3_GET_INSN_CLASS (type) == INSN_CLASS_16) \
296 ? s3_INSN16_SIZE : (s3_GET_INSN_CLASS (type) == INSN_CLASS_48) \
297 ? s3_INSN48_SIZE : s3_INSN_SIZE)
299 #define s3_INSN_NAME_LEN 16
301 /* Relax will need some padding for alignment. */
302 #define s3_RELAX_PAD_BYTE 3
305 #define s3_USE_GLOBAL_POINTER_OPT 1
307 /* Enumeration matching entries in table above. */
308 enum s3_score_reg_type
310 s3_REG_TYPE_SCORE
= 0,
311 #define s3_REG_TYPE_FIRST s3_REG_TYPE_SCORE
312 s3_REG_TYPE_SCORE_SR
= 1,
313 s3_REG_TYPE_SCORE_CR
= 2,
317 enum s3_score_pic_level
322 static enum s3_score_pic_level s3_score_pic
= s3_NO_PIC
;
324 enum s3_insn_type_for_dependency
330 struct s3_insn_to_dependency
332 const char *insn_name
;
333 enum s3_insn_type_for_dependency type
;
336 struct s3_data_dependency
338 enum s3_insn_type_for_dependency pre_insn_type
;
340 enum s3_insn_type_for_dependency cur_insn_type
;
344 int warn_or_error
; /* warning - 0; error - 1 */
347 static const struct s3_insn_to_dependency s3_insn_to_dependency_table
[] =
349 /* move special instruction. */
353 static const struct s3_data_dependency s3_data_dependency_table
[] =
355 /* Status register. */
356 {s3_D_mtcr
, "cr0", s3_D_all_insn
, "", 5, 1, 0},
359 /* Used to contain constructed error messages. */
360 static char s3_err_msg
[255];
362 static int s3_fix_data_dependency
= 0;
363 static int s3_warn_fix_data_dependency
= 1;
365 static int s3_in_my_get_expression
= 0;
367 /* Default, pop warning message when using r1. */
368 static int s3_nor1
= 1;
370 /* Default will do instruction relax, -O0 will set s3_g_opt = 0. */
371 static unsigned int s3_g_opt
= 1;
373 /* The size of the small data section. */
374 static unsigned int s3_g_switch_value
= 8;
376 static segT s3_pdr_seg
;
380 char name
[s3_INSN_NAME_LEN
];
385 enum score_insn_type type
;
386 char str
[s3_MAX_LITERAL_POOL_SIZE
];
389 char reg
[s3_INSN_NAME_LEN
];
392 bfd_reloc_code_real_type type
;
397 static struct s3_score_it s3_inst
;
399 typedef struct s3_proc
402 unsigned long reg_mask
;
403 unsigned long reg_offset
;
404 unsigned long fpreg_mask
;
406 unsigned long frame_offset
;
407 unsigned long frame_reg
;
408 unsigned long pc_reg
;
410 static s3_procS s3_cur_proc
;
411 static s3_procS
*s3_cur_proc_ptr
;
412 static int s3_numprocs
;
415 /* Structure for a hash table entry for a register. */
422 static const struct s3_reg_entry s3_score_rn_table
[] =
424 {"r0", 0}, {"r1", 1}, {"r2", 2}, {"r3", 3},
425 {"r4", 4}, {"r5", 5}, {"r6", 6}, {"r7", 7},
426 {"r8", 8}, {"r9", 9}, {"r10", 10}, {"r11", 11},
427 {"r12", 12}, {"r13", 13}, {"r14", 14}, {"r15", 15},
428 {"r16", 16}, {"r17", 17}, {"r18", 18}, {"r19", 19},
429 {"r20", 20}, {"r21", 21}, {"r22", 22}, {"r23", 23},
430 {"r24", 24}, {"r25", 25}, {"r26", 26}, {"r27", 27},
431 {"r28", 28}, {"r29", 29}, {"r30", 30}, {"r31", 31},
435 static const struct s3_reg_entry s3_score_srn_table
[] =
437 {"sr0", 0}, {"sr1", 1}, {"sr2", 2},
441 static const struct s3_reg_entry s3_score_crn_table
[] =
443 {"cr0", 0}, {"cr1", 1}, {"cr2", 2}, {"cr3", 3},
444 {"cr4", 4}, {"cr5", 5}, {"cr6", 6}, {"cr7", 7},
445 {"cr8", 8}, {"cr9", 9}, {"cr10", 10}, {"cr11", 11},
446 {"cr12", 12}, {"cr13", 13}, {"cr14", 14}, {"cr15", 15},
447 {"cr16", 16}, {"cr17", 17}, {"cr18", 18}, {"cr19", 19},
448 {"cr20", 20}, {"cr21", 21}, {"cr22", 22}, {"cr23", 23},
449 {"cr24", 24}, {"cr25", 25}, {"cr26", 26}, {"cr27", 27},
450 {"cr28", 28}, {"cr29", 29}, {"cr30", 30}, {"cr31", 31},
456 const struct s3_reg_entry
*names
;
459 const char *expected
;
462 static struct s3_reg_map s3_all_reg_maps
[] =
464 {s3_score_rn_table
, 31, NULL
, N_("S+core register expected")},
465 {s3_score_srn_table
, 2, NULL
, N_("S+core special-register expected")},
466 {s3_score_crn_table
, 31, NULL
, N_("S+core co-processor register expected")},
469 static htab_t s3_score_ops_hsh
= NULL
;
470 static htab_t s3_dependency_insn_hsh
= NULL
;
473 struct s3_datafield_range
480 static struct s3_datafield_range s3_score_df_range
[] =
482 {_IMM4
, 4, {0, (1 << 4) - 1}}, /* ( 0 ~ 15 ) */
483 {_IMM5
, 5, {0, (1 << 5) - 1}}, /* ( 0 ~ 31 ) */
484 {_IMM8
, 8, {0, (1 << 8) - 1}}, /* ( 0 ~ 255 ) */
485 {_IMM14
, 14, {0, (1 << 14) - 1}}, /* ( 0 ~ 16383) */
486 {_IMM15
, 15, {0, (1 << 15) - 1}}, /* ( 0 ~ 32767) */
487 {_IMM16
, 16, {0, (1 << 16) - 1}}, /* ( 0 ~ 65535) */
488 {_SIMM10
, 10, {-(1 << 9), (1 << 9) - 1}}, /* ( -512 ~ 511 ) */
489 {_SIMM12
, 12, {-(1 << 11), (1 << 11) - 1}}, /* ( -2048 ~ 2047 ) */
490 {_SIMM14
, 14, {-(1 << 13), (1 << 13) - 1}}, /* ( -8192 ~ 8191 ) */
491 {_SIMM15
, 15, {-(1 << 14), (1 << 14) - 1}}, /* (-16384 ~ 16383) */
492 {_SIMM16
, 16, {-(1 << 15), (1 << 15) - 1}}, /* (-32768 ~ 32767) */
493 {_SIMM14_NEG
, 14, {-(1 << 13), (1 << 13) - 1}}, /* ( -8191 ~ 8192 ) */
494 {_IMM16_NEG
, 16, {0, (1 << 16) - 1}}, /* (-65535 ~ 0 ) */
495 {_SIMM16_NEG
, 16, {-(1 << 15), (1 << 15) - 1}}, /* (-32768 ~ 32767) */
496 {_IMM20
, 20, {0, (1 << 20) - 1}},
497 {_IMM25
, 25, {0, (1 << 25) - 1}},
498 {_DISP8div2
, 8, {-(1 << 8), (1 << 8) - 1}}, /* ( -256 ~ 255 ) */
499 {_DISP11div2
, 11, {0, 0}},
500 {_DISP19div2
, 19, {-(1 << 19), (1 << 19) - 1}}, /* (-524288 ~ 524287) */
501 {_DISP24div2
, 24, {0, 0}},
502 {_VALUE
, 32, {0, ((unsigned int)1 << 31) - 1}},
503 {_VALUE_HI16
, 16, {0, (1 << 16) - 1}},
504 {_VALUE_LO16
, 16, {0, (1 << 16) - 1}},
505 {_VALUE_LDST_LO16
, 16, {0, (1 << 16) - 1}},
506 {_SIMM16_LA
, 16, {-(1 << 15), (1 << 15) - 1}}, /* (-32768 ~ 32767) */
507 {_IMM5_RSHIFT_1
, 5, {0, (1 << 6) - 1}}, /* ( 0 ~ 63 ) */
508 {_IMM5_RSHIFT_2
, 5, {0, (1 << 7) - 1}}, /* ( 0 ~ 127 ) */
509 {_SIMM16_LA_POS
, 16, {0, (1 << 15) - 1}}, /* ( 0 ~ 32767) */
510 {_IMM5_RANGE_8_31
, 5, {8, 31}}, /* But for cop0 the valid data : (8 ~ 31). */
511 {_IMM10_RSHIFT_2
, 10, {-(1 << 11), (1 << 11) - 1}}, /* For ldc#, stc#. */
512 {_SIMM10
, 10, {0, (1 << 10) - 1}}, /* ( -1024 ~ 1023 ) */
513 {_SIMM12
, 12, {0, (1 << 12) - 1}}, /* ( -2048 ~ 2047 ) */
514 {_SIMM14
, 14, {0, (1 << 14) - 1}}, /* ( -8192 ~ 8191 ) */
515 {_SIMM15
, 15, {0, (1 << 15) - 1}}, /* (-16384 ~ 16383) */
516 {_SIMM16
, 16, {0, (1 << 16) - 1}}, /* (-65536 ~ 65536) */
517 {_SIMM14_NEG
, 14, {0, (1 << 16) - 1}}, /* ( -8191 ~ 8192 ) */
518 {_IMM16_NEG
, 16, {0, (1 << 16) - 1}}, /* ( 65535 ~ 0 ) */
519 {_SIMM16_NEG
, 16, {0, (1 << 16) - 1}}, /* ( 65535 ~ 0 ) */
520 {_IMM20
, 20, {0, (1 << 20) - 1}}, /* (-32768 ~ 32767) */
521 {_IMM25
, 25, {0, (1 << 25) - 1}}, /* (-32768 ~ 32767) */
522 {_GP_IMM15
, 15, {0, (1 << 15) - 1}}, /* ( 0 ~ 65535) */
523 {_GP_IMM14
, 14, {0, (1 << 14) - 1}}, /* ( 0 ~ 65535) */
524 {_SIMM16_pic
, 16, {-(1 << 15), (1 << 15) - 1}}, /* (-32768 ~ 32767) */
525 {_IMM16_LO16_pic
, 16, {0, (1 << 16) - 1}}, /* ( 65535 ~ 0 ) */
526 {_IMM16_pic
, 16, {0, (1 << 16) - 1}}, /* ( 0 ~ 65535) */
527 {_SIMM5
, 5, {-(1 << 4), (1 << 4) - 1}}, /* ( -16 ~ 15 ) */
528 {_SIMM6
, 6, {-(1 << 5), (1 << 5) - 1}}, /* ( -32 ~ 31 ) */
529 {_IMM32
, 32, {0, 0xfffffff}},
530 {_SIMM32
, 32, {-0x80000000, 0x7fffffff}},
531 {_IMM11
, 11, {0, (1 << 11) - 1}},
536 /* Instruction name. */
537 const char *template_name
;
539 /* Instruction Opcode. */
542 /* Instruction bit mask. */
545 /* Relax instruction opcode. 0x8000 imply no relaxation. */
548 /* Instruction type. */
549 enum score_insn_type type
;
551 /* Function to call to parse args. */
552 void (*parms
) (char *);
555 static const struct s3_asm_opcode s3_score_ldst_insns
[] =
557 {"lw", 0x20000000, 0x3e000000, 0x1000, Rd_rvalueRs_SI15
, s3_do_ldst_insn
},
558 {"lw", 0x06000000, 0x3e000007, 0x8000, Rd_rvalueRs_preSI12
, s3_do_ldst_insn
},
559 {"lw", 0x0e000000, 0x3e000007, 0x0040, Rd_rvalueRs_postSI12
, s3_do_ldst_insn
},
560 {"lh", 0x22000000, 0x3e000000, 0x8000, Rd_rvalueRs_SI15
, s3_do_ldst_insn
},
561 {"lh", 0x06000001, 0x3e000007, 0x8000, Rd_rvalueRs_preSI12
, s3_do_ldst_insn
},
562 {"lh", 0x0e000001, 0x3e000007, 0x8000, Rd_rvalueRs_postSI12
, s3_do_ldst_insn
},
563 {"lhu", 0x24000000, 0x3e000000, 0x8000, Rd_rvalueRs_SI15
, s3_do_ldst_insn
},
564 {"lhu", 0x06000002, 0x3e000007, 0x8000, Rd_rvalueRs_preSI12
, s3_do_ldst_insn
},
565 {"lhu", 0x0e000002, 0x3e000007, 0x8000, Rd_rvalueRs_postSI12
, s3_do_ldst_insn
},
566 {"lb", 0x26000000, 0x3e000000, 0x8000, Rd_rvalueRs_SI15
, s3_do_ldst_insn
},
567 {"lb", 0x06000003, 0x3e000007, 0x8000, Rd_rvalueRs_preSI12
, s3_do_ldst_insn
},
568 {"lb", 0x0e000003, 0x3e000007, 0x8000, Rd_rvalueRs_postSI12
, s3_do_ldst_insn
},
569 {"sw", 0x28000000, 0x3e000000, 0x2000, Rd_lvalueRs_SI15
, s3_do_ldst_insn
},
570 {"sw", 0x06000004, 0x3e000007, 0x0060, Rd_lvalueRs_preSI12
, s3_do_ldst_insn
},
571 {"sw", 0x0e000004, 0x3e000007, 0x8000, Rd_lvalueRs_postSI12
, s3_do_ldst_insn
},
572 {"sh", 0x2a000000, 0x3e000000, 0x8000, Rd_lvalueRs_SI15
, s3_do_ldst_insn
},
573 {"sh", 0x06000005, 0x3e000007, 0x8000, Rd_lvalueRs_preSI12
, s3_do_ldst_insn
},
574 {"sh", 0x0e000005, 0x3e000007, 0x8000, Rd_lvalueRs_postSI12
, s3_do_ldst_insn
},
575 {"lbu", 0x2c000000, 0x3e000000, 0x8000, Rd_rvalueRs_SI15
, s3_do_ldst_insn
},
576 {"lbu", 0x06000006, 0x3e000007, 0x8000, Rd_rvalueRs_preSI12
, s3_do_ldst_insn
},
577 {"lbu", 0x0e000006, 0x3e000007, 0x8000, Rd_rvalueRs_postSI12
, s3_do_ldst_insn
},
578 {"sb", 0x2e000000, 0x3e000000, 0x8000, Rd_lvalueRs_SI15
, s3_do_ldst_insn
},
579 {"sb", 0x06000007, 0x3e000007, 0x8000, Rd_lvalueRs_preSI12
, s3_do_ldst_insn
},
580 {"sb", 0x0e000007, 0x3e000007, 0x8000, Rd_lvalueRs_postSI12
, s3_do_ldst_insn
},
583 static const struct s3_asm_opcode s3_score_insns
[] =
585 {"abs", 0x3800000a, 0x3e007fff, 0x8000, Rd_Rs_x
, s3_do_dsp3
},
586 {"abs.s", 0x3800004b, 0x3e007fff, 0x8000, Rd_Rs_x
, s3_do_dsp3
},
587 {"add", 0x00000010, 0x3e0003ff, 0x4800, Rd_Rs_Rs
, s3_do_rdrsrs
},
588 {"add.c", 0x00000011, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_rdrsrs
},
589 {"add.s", 0x38000048, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_dsp2
},
590 {"addc", 0x00000012, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_rdrsrs
},
591 {"addc.c", 0x00000013, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_rdrsrs
},
592 {"addi", 0x02000000, 0x3e0e0001, 0x5c00, Rd_SI16
, s3_do_rdsi16
},
593 {"addi.c", 0x02000001, 0x3e0e0001, 0x8000, Rd_SI16
, s3_do_rdsi16
},
594 {"addis", 0x0a000000, 0x3e0e0001, 0x8000, Rd_SI16
, s3_do_rdi16
},
595 {"addis.c", 0x0a000001, 0x3e0e0001, 0x8000, Rd_SI16
, s3_do_rdi16
},
596 {"addi!", 0x5c00, 0x7c00, 0x8000, Rd_SI6
, s3_do16_addi
},
597 {"addri", 0x10000000, 0x3e000001, 0x8000, Rd_Rs_SI14
, s3_do_rdrssi14
},
598 {"addri.c", 0x10000001, 0x3e000001, 0x8000, Rd_Rs_SI14
, s3_do_rdrssi14
},
600 /* add.c <-> add!. */
601 {"add!", 0x4800, 0x7f00, 0x8000, Rd_Rs
, s3_do16_rdrs2
},
602 {"subi", 0x02000000, 0x3e0e0001, 0x8000, Rd_SI16
, s3_do_sub_rdsi16
},
603 {"subi.c", 0x02000001, 0x3e0e0001, 0x8000, Rd_SI16
, s3_do_sub_rdsi16
},
604 {"subis", 0x0a000000, 0x3e0e0001, 0x8000, Rd_SI16
, s3_do_sub_rdi16
},
605 {"subis.c", 0x0a000001, 0x3e0e0001, 0x8000, Rd_SI16
, s3_do_sub_rdi16
},
606 {"subri", 0x10000000, 0x3e000001, 0x8000, Rd_Rs_SI14
, s3_do_sub_rdrssi14
},
607 {"subri.c", 0x10000001, 0x3e000001, 0x8000, Rd_Rs_SI14
, s3_do_sub_rdrssi14
},
608 {"and", 0x00000020, 0x3e0003ff, 0x4b00, Rd_Rs_Rs
, s3_do_rdrsrs
},
609 {"and.c", 0x00000021, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_rdrsrs
},
610 {"andi", 0x02080000, 0x3e0e0001, 0x8000, Rd_I16
, s3_do_rdi16
},
611 {"andi.c", 0x02080001, 0x3e0e0001, 0x8000, Rd_I16
, s3_do_rdi16
},
612 {"andis", 0x0a080000, 0x3e0e0001, 0x8000, Rd_I16
, s3_do_rdi16
},
613 {"andis.c", 0x0a080001, 0x3e0e0001, 0x8000, Rd_I16
, s3_do_rdi16
},
614 {"andri", 0x18000000, 0x3e000001, 0x8000, Rd_Rs_I14
, s3_do_rdrsi14
},
615 {"andri.c", 0x18000001, 0x3e000001, 0x8000, Rd_Rs_I14
, s3_do_rdrsi14
},
617 /* and.c <-> and!. */
618 {"and!", 0x4b00, 0x7f00, 0x8000, Rd_Rs
, s3_do16_rdrs2
},
619 {"bcs", 0x08000000, 0x3e007c01, 0x8000, PC_DISP19div2
, s3_do_branch
},
620 {"bcc", 0x08000400, 0x3e007c01, 0x8000, PC_DISP19div2
, s3_do_branch
},
621 {"bcnz", 0x08003800, 0x3e007c01, 0x3200, PC_DISP19div2
, s3_do_branch
},
622 {"bcsl", 0x08000001, 0x3e007c01, 0x8000, PC_DISP19div2
, s3_do_branch
},
623 {"bccl", 0x08000401, 0x3e007c01, 0x8000, PC_DISP19div2
, s3_do_branch
},
624 {"bcnzl", 0x08003801, 0x3e007c01, 0x8000, PC_DISP19div2
, s3_do_branch
},
625 {"bcnz!", 0x3200, 0x7f00, 0x08003800, PC_DISP8div2
, s3_do16_branch
},
626 {"beq", 0x08001000, 0x3e007c01, 0x3800, PC_DISP19div2
, s3_do_branch
},
627 {"beql", 0x08001001, 0x3e007c01, 0x8000, PC_DISP19div2
, s3_do_branch
},
628 {"beq!", 0x3800, 0x7e00, 0x08001000, PC_DISP8div2
, s3_do16_branch
},
629 {"bgtu", 0x08000800, 0x3e007c01, 0x3400, PC_DISP19div2
, s3_do_branch
},
630 {"bgt", 0x08001800, 0x3e007c01, 0x3c00, PC_DISP19div2
, s3_do_branch
},
631 {"bge", 0x08002000, 0x3e007c01, 0x8000, PC_DISP19div2
, s3_do_branch
},
632 {"bgtul", 0x08000801, 0x3e007c01, 0x8000, PC_DISP19div2
, s3_do_branch
},
633 {"bgtl", 0x08001801, 0x3e007c01, 0x8000, PC_DISP19div2
, s3_do_branch
},
634 {"bgel", 0x08002001, 0x3e007c01, 0x8000, PC_DISP19div2
, s3_do_branch
},
635 {"bgtu!", 0x3400, 0x7e00, 0x08000800, PC_DISP8div2
, s3_do16_branch
},
636 {"bgt!", 0x3c00, 0x7e00, 0x08001800, PC_DISP8div2
, s3_do16_branch
},
637 {"bitclr", 0x00000028, 0x3e0003ff, 0x5000, Rd_Rs_I5
, s3_do_rdrsi5
},
638 {"bitclr.c", 0x00000029, 0x3e0003ff, 0x8000, Rd_Rs_I5
, s3_do_rdrsi5
},
640 {"mbitclr", 0x00000064, 0x3e00007e, 0x8000, Ra_I9_I5
, s3_do_mbitclr
},
641 {"mbitset", 0x0000006c, 0x3e00007e, 0x8000, Ra_I9_I5
, s3_do_mbitset
},
643 {"bitrev", 0x3800000c, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_dsp2
},
644 {"bitset", 0x0000002a, 0x3e0003ff, 0x5200, Rd_Rs_I5
, s3_do_rdrsi5
},
645 {"bitset.c", 0x0000002b, 0x3e0003ff, 0x8000, Rd_Rs_I5
, s3_do_rdrsi5
},
646 {"bittst.c", 0x0000002d, 0x3e0003ff, 0x5400, x_Rs_I5
, s3_do_xrsi5
},
647 {"bittgl", 0x0000002e, 0x3e0003ff, 0x5600, Rd_Rs_I5
, s3_do_rdrsi5
},
648 {"bittgl.c", 0x0000002f, 0x3e0003ff, 0x8000, Rd_Rs_I5
, s3_do_rdrsi5
},
649 {"bitclr!", 0x5000, 0x7e00, 0x8000, Rd_I5
, s3_do16_rdi5
},
650 {"bitset!", 0x5200, 0x7e00, 0x8000, Rd_I5
, s3_do16_rdi5
},
651 {"bittst!", 0x5400, 0x7e00, 0x8000, Rd_I5
, s3_do16_rdi5
},
652 {"bittgl!", 0x5600, 0x7e00, 0x8000, Rd_I5
, s3_do16_rdi5
},
653 {"bleu", 0x08000c00, 0x3e007c01, 0x3600, PC_DISP19div2
, s3_do_branch
},
654 {"ble", 0x08001c00, 0x3e007c01, 0x3e00, PC_DISP19div2
, s3_do_branch
},
655 {"blt", 0x08002400, 0x3e007c01, 0x8000, PC_DISP19div2
, s3_do_branch
},
656 {"bleul", 0x08000c01, 0x3e007c01, 0x8000, PC_DISP19div2
, s3_do_branch
},
657 {"blel", 0x08001c01, 0x3e007c01, 0x8000, PC_DISP19div2
, s3_do_branch
},
658 {"bltl", 0x08002401, 0x3e007c01, 0x8000, PC_DISP19div2
, s3_do_branch
},
659 {"bl", 0x08003c01, 0x3e007c01, 0x8000, PC_DISP19div2
, s3_do_branch
},
660 {"bleu!", 0x3600, 0x7e00, 0x08000c00, PC_DISP8div2
, s3_do16_branch
},
661 {"ble!", 0x3e00, 0x7e00, 0x08001c00, PC_DISP8div2
, s3_do16_branch
},
662 {"bmi", 0x08002800, 0x3e007c01, 0x8000, PC_DISP19div2
, s3_do_branch
},
663 {"bmil", 0x08002801, 0x3e007c01, 0x8000, PC_DISP19div2
, s3_do_branch
},
664 {"bne", 0x08001400, 0x3e007c01, 0x3a00, PC_DISP19div2
, s3_do_branch
},
665 {"bnel", 0x08001401, 0x3e007c01, 0x8000, PC_DISP19div2
, s3_do_branch
},
666 {"bne!", 0x3a00, 0x7e00, 0x08001400, PC_DISP8div2
, s3_do16_branch
},
667 {"bpl", 0x08002c00, 0x3e007c01, 0x8000, PC_DISP19div2
, s3_do_branch
},
668 {"bpll", 0x08002c01, 0x3e007c01, 0x8000, PC_DISP19div2
, s3_do_branch
},
669 {"brcs", 0x00000008, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
670 {"brcc", 0x00000408, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
671 {"brgtu", 0x00000808, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
672 {"brleu", 0x00000c08, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
673 {"breq", 0x00001008, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
674 {"brne", 0x00001408, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
675 {"brgt", 0x00001808, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
676 {"brle", 0x00001c08, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
677 {"brge", 0x00002008, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
678 {"brlt", 0x00002408, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
679 {"brmi", 0x00002808, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
680 {"brpl", 0x00002c08, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
681 {"brvs", 0x00003008, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
682 {"brvc", 0x00003408, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
683 {"brcnz", 0x00003808, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
684 {"br", 0x00003c08, 0x3e007fff, 0x0080, x_Rs_x
, s3_do_rs
},
685 {"brcsl", 0x00000009, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
686 {"brccl", 0x00000409, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
687 {"brgtul", 0x00000809, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
688 {"brleul", 0x00000c09, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
689 {"breql", 0x00001009, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
690 {"brnel", 0x00001409, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
691 {"brgtl", 0x00001809, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
692 {"brlel", 0x00001c09, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
693 {"brgel", 0x00002009, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
694 {"brltl", 0x00002409, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
695 {"brmil", 0x00002809, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
696 {"brpll", 0x00002c09, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
697 {"brvsl", 0x00003009, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
698 {"brvcl", 0x00003409, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
699 {"brcnzl", 0x00003809, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
700 {"brl", 0x00003c09, 0x3e007fff, 0x00a0, x_Rs_x
, s3_do_rs
},
701 {"br!", 0x0080, 0x7fe0, 0x8000, x_Rs
, s3_do16_br
},
702 {"brl!", 0x00a0, 0x7fe0, 0x8000, x_Rs
, s3_do16_br
},
703 {"brr!", 0x00c0, 0x7fe0, 0x8000, x_Rs
, s3_do16_brr
},
704 {"bvs", 0x08003000, 0x3e007c01, 0x8000, PC_DISP19div2
, s3_do_branch
},
705 {"bvc", 0x08003400, 0x3e007c01, 0x8000, PC_DISP19div2
, s3_do_branch
},
706 {"bvsl", 0x08003001, 0x3e007c01, 0x8000, PC_DISP19div2
, s3_do_branch
},
707 {"bvcl", 0x08003401, 0x3e007c01, 0x8000, PC_DISP19div2
, s3_do_branch
},
708 {"b!", 0x3000, 0x7e00, 0x08003c00, PC_DISP8div2
, s3_do16_branch
},
709 {"b", 0x08003c00, 0x3e007c01, 0x3000, PC_DISP19div2
, s3_do_branch
},
710 {"cache", 0x30000000, 0x3ff00000, 0x8000, OP5_rvalueRs_SI15
, s3_do_cache
},
711 {"ceinst", 0x38000000, 0x3e000000, 0x8000, I5_Rs_Rs_I5_OP5
, s3_do_ceinst
},
712 {"clz", 0x0000001c, 0x3e007fff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
713 {"cmp.c", 0x00300019, 0x3ff003ff, 0x4400, x_Rs_Rs
, s3_do_rsrs
},
714 {"cmpz.c", 0x0030001b, 0x3ff07fff, 0x8000, x_Rs_x
, s3_do_rs
},
715 {"cmpi.c", 0x02040001, 0x3e0e0001, 0x6000, Rd_SI16
, s3_do_rdsi16
},
717 /* cmp.c <-> cmp!. */
718 {"cmp!", 0x4400, 0x7c00, 0x8000, Rd_Rs
, s3_do16_mv_cmp
},
719 {"cmpi!", 0x6000, 0x7c00, 0x8000, Rd_SI5
, s3_do16_cmpi
},
720 {"cop1", 0x0c00000c, 0x3e00001f, 0x8000, Rd_Rs_Rs_imm
, s3_do_crdcrscrsimm5
},
721 {"cop2", 0x0c000014, 0x3e00001f, 0x8000, Rd_Rs_Rs_imm
, s3_do_crdcrscrsimm5
},
722 {"cop3", 0x0c00001c, 0x3e00001f, 0x8000, Rd_Rs_Rs_imm
, s3_do_crdcrscrsimm5
},
723 {"drte", 0x0c0000a4, 0x3e0003ff, 0x8000, NO_OPD
, s3_do_empty
},
724 {"disint!", 0x00e0, 0xffe1, 0x8000, NO16_OPD
, s3_do16_int
},
725 {"enint!", 0x00e1, 0xffe1, 0x8000, NO16_OPD
, s3_do16_int
},
726 {"extsb", 0x00000058, 0x3e0003ff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
727 {"extsb.c", 0x00000059, 0x3e0003ff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
728 {"extsh", 0x0000005a, 0x3e0003ff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
729 {"extsh.c", 0x0000005b, 0x3e0003ff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
730 {"extzb", 0x0000005c, 0x3e0003ff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
731 {"extzb.c", 0x0000005d, 0x3e0003ff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
732 {"extzh", 0x0000005e, 0x3e0003ff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
733 {"extzh.c", 0x0000005f, 0x3e0003ff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
734 {"jl", 0x04000001, 0x3e000001, 0x8000, PC_DISP24div2
, s3_do_jump
},
735 {"j", 0x04000000, 0x3e000001, 0x8000, PC_DISP24div2
, s3_do_jump
},
736 {"alw", 0x0000000c, 0x3e0003ff, 0x8000, Rd_rvalue32Rs
, s3_do_ldst_atomic
},
737 {"lcb", 0x00000060, 0x3e0003ff, 0x8000, x_rvalueRs_post4
, s3_do_ldst_unalign
},
738 {"lcw", 0x00000062, 0x3e0003ff, 0x8000, Rd_rvalueRs_post4
, s3_do_ldst_unalign
},
739 {"lce", 0x00000066, 0x3e0003ff, 0x8000, Rd_rvalueRs_post4
, s3_do_ldst_unalign
},
740 {"ldc1", 0x0c00000a, 0x3e00001f, 0x8000, Rd_rvalueRs_SI10
, s3_do_ldst_cop
},
741 {"ldc2", 0x0c000012, 0x3e00001f, 0x8000, Rd_rvalueRs_SI10
, s3_do_ldst_cop
},
742 {"ldc3", 0x0c00001a, 0x3e00001f, 0x8000, Rd_rvalueRs_SI10
, s3_do_ldst_cop
},
745 {"ldi", 0x020c0000, 0x3e0e0000, 0x6400, Rd_SI16
, s3_do_rdsi16
},
746 {"ldis", 0x0a0c0000, 0x3e0e0000, 0x8000, Rd_I16
, s3_do_ldis
},
749 {"ldiu!", 0x6400, 0x7c00, 0x8000, Rd_I5
, s3_do16_ldiu
},
751 /*ltbb! , ltbh! ltbw! */
752 {"ltbw", 0x00000032, 0x03ff, 0x8000, Rd_Rs_Rs
, s3_do_ltb
},
753 {"ltbh", 0x00000132, 0x03ff, 0x8000, Rd_Rs_Rs
, s3_do_ltb
},
754 {"ltbb", 0x00000332, 0x03ff, 0x8000, Rd_Rs_Rs
, s3_do_ltb
},
755 {"lw!", 0x1000, 0x7000, 0x8000, Rd_rvalueRs
, s3_do16_ldst_insn
},
756 {"mfcel", 0x00000448, 0x3e007fff, 0x8000, Rd_x_x
, s3_do_rd
},
757 {"mfcel!", 0x7100, 0x7ff0, 0x00000448, x_Rs
, s3_do16_dsp
},
758 {"mad", 0x38000000, 0x3ff003ff, 0x8000, x_Rs_Rs
, s3_do_dsp
},
759 {"mad.f!", 0x7400, 0x7f00, 0x38000080, Rd_Rs
, s3_do16_dsp2
},
760 {"madh", 0x38000203, 0x3ff003ff, 0x8000, x_Rs_Rs
, s3_do_dsp
},
761 {"madh.fs", 0x380002c3, 0x3ff003ff, 0x8000, x_Rs_Rs
, s3_do_dsp
},
762 {"madh.fs!", 0x7b00, 0x7f00, 0x380002c3, Rd_Rs
, s3_do16_dsp2
},
763 {"madl", 0x38000002, 0x3ff003ff, 0x8000, x_Rs_Rs
, s3_do_dsp
},
764 {"madl.fs", 0x380000c2, 0x3ff003ff, 0x8000, x_Rs_Rs
, s3_do_dsp
},
765 {"madl.fs!", 0x7a00, 0x7f00, 0x380000c2, Rd_Rs
, s3_do16_dsp2
},
766 {"madu", 0x38000020, 0x3ff003ff, 0x8000, x_Rs_Rs
, s3_do_dsp
},
767 {"madu!", 0x7500, 0x7f00, 0x38000020, Rd_Rs
, s3_do16_dsp2
},
768 {"mad.f", 0x38000080, 0x3ff003ff, 0x8000, x_Rs_Rs
, s3_do_dsp
},
769 {"max", 0x38000007, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_dsp2
},
770 {"mazh", 0x38000303, 0x3ff003ff, 0x8000, x_Rs_Rs
, s3_do_dsp
},
771 {"mazh.f", 0x38000383, 0x3ff003ff, 0x8000, x_Rs_Rs
, s3_do_dsp
},
772 {"mazh.f!", 0x7900, 0x7f00, 0x3800038c, Rd_Rs
, s3_do16_dsp2
},
773 {"mazl", 0x38000102, 0x3ff003ff, 0x8000, x_Rs_Rs
, s3_do_dsp
},
774 {"mazl.f", 0x38000182, 0x3ff003ff, 0x8000, x_Rs_Rs
, s3_do_dsp
},
775 {"mazl.f!", 0x7800, 0x7f00, 0x38000182, Rd_Rs
, s3_do16_dsp2
},
776 {"mfceh", 0x00000848, 0x3e007fff, 0x8000, Rd_x_x
, s3_do_rd
},
777 {"mfceh!", 0x7110, 0x7ff0, 0x00000848, x_Rs
, s3_do16_dsp
},
778 {"mfcehl", 0x00000c48, 0x3e007fff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
779 {"mfsr", 0x00000050, 0x3e0003ff, 0x8000, Rd_x_I5
, s3_do_rdsrs
},
780 {"mfcr", 0x0c000001, 0x3e00001f, 0x8000, Rd_Rs_x
, s3_do_rdcrs
},
781 {"mfc1", 0x0c000009, 0x3e00001f, 0x8000, Rd_Rs_x
, s3_do_rdcrs
},
782 {"mfc2", 0x0c000011, 0x3e00001f, 0x8000, Rd_Rs_x
, s3_do_rdcrs
},
783 {"mfc3", 0x0c000019, 0x3e00001f, 0x8000, Rd_Rs_x
, s3_do_rdcrs
},
784 {"mfcc1", 0x0c00000f, 0x3e00001f, 0x8000, Rd_Rs_x
, s3_do_rdcrs
},
785 {"mfcc2", 0x0c000017, 0x3e00001f, 0x8000, Rd_Rs_x
, s3_do_rdcrs
},
786 {"mfcc3", 0x0c00001f, 0x3e00001f, 0x8000, Rd_Rs_x
, s3_do_rdcrs
},
787 {"min", 0x38000006, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_dsp2
},
788 {"msb", 0x38000001, 0x3ff003ff, 0x8000, x_Rs_Rs
, s3_do_dsp
},
789 {"msb.f!", 0x7600, 0x7f00, 0x38000081, Rd_Rs
, s3_do16_dsp2
},
790 {"msbh", 0x38000205, 0x3ff003ff, 0x8000, x_Rs_Rs
, s3_do_dsp
},
791 {"msbh.fs", 0x380002c5, 0x3ff003ff, 0x8000, x_Rs_Rs
, s3_do_dsp
},
792 {"msbh.fs!", 0x7f00, 0x7f00, 0x380002c5, Rd_Rs
, s3_do16_dsp2
},
793 {"msbl", 0x38000004, 0x3ff003ff, 0x8000, x_Rs_Rs
, s3_do_dsp
},
794 {"msbl.fs", 0x380000c4, 0x3ff003ff, 0x8000, x_Rs_Rs
, s3_do_dsp
},
795 {"msbl.fs!", 0x7e00, 0x7f00, 0x380000c4, Rd_Rs
, s3_do16_dsp2
},
796 {"msbu", 0x38000021, 0x3ff003ff, 0x8000, x_Rs_Rs
, s3_do_dsp
},
797 {"msbu!", 0x7700, 0x7f00, 0x38000021, Rd_Rs
, s3_do16_dsp2
},
798 {"msb.f", 0x38000081, 0x3ff003ff, 0x8000, x_Rs_Rs
, s3_do_dsp
},
799 {"mszh", 0x38000305, 0x3ff003ff, 0x8000, x_Rs_Rs
, s3_do_dsp
},
800 {"mszh.f", 0x38000385, 0x3ff003ff, 0x8000, x_Rs_Rs
, s3_do_dsp
},
801 {"mszh.f!", 0x7d00, 0x7f00, 0x38000385, Rd_Rs
, s3_do16_dsp2
},
802 {"mszl", 0x38000104, 0x3ff003ff, 0x8000, x_Rs_Rs
, s3_do_dsp
},
803 {"mszl.f", 0x38000184, 0x3ff003ff, 0x8000, x_Rs_Rs
, s3_do_dsp
},
804 {"mszl.f!", 0x7c00, 0x7f00, 0x38000184, Rd_Rs
, s3_do16_dsp2
},
805 {"mtcel!", 0x7000, 0x7ff0, 0x0000044a, x_Rs
, s3_do16_dsp
},
806 {"mtcel", 0x0000044a, 0x3e007fff, 0x8000, Rd_x_x
, s3_do_rd
},
807 {"mtceh", 0x0000084a, 0x3e007fff, 0x8000, Rd_x_x
, s3_do_rd
},
808 {"mtceh!", 0x7010, 0x7ff0, 0x0000084a, x_Rs
, s3_do16_dsp
},
809 {"mtcehl", 0x00000c4a, 0x3e007fff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
810 {"mtsr", 0x00000052, 0x3e0003ff, 0x8000, x_Rs_I5
, s3_do_rdsrs
},
811 {"mtcr", 0x0c000000, 0x3e00001f, 0x8000, Rd_Rs_x
, s3_do_rdcrs
},
812 {"mtc1", 0x0c000008, 0x3e00001f, 0x8000, Rd_Rs_x
, s3_do_rdcrs
},
813 {"mtc2", 0x0c000010, 0x3e00001f, 0x8000, Rd_Rs_x
, s3_do_rdcrs
},
814 {"mtc3", 0x0c000018, 0x3e00001f, 0x8000, Rd_Rs_x
, s3_do_rdcrs
},
815 {"mtcc1", 0x0c00000e, 0x3e00001f, 0x8000, Rd_Rs_x
, s3_do_rdcrs
},
816 {"mtcc2", 0x0c000016, 0x3e00001f, 0x8000, Rd_Rs_x
, s3_do_rdcrs
},
817 {"mtcc3", 0x0c00001e, 0x3e00001f, 0x8000, Rd_Rs_x
, s3_do_rdcrs
},
818 {"mul.f!", 0x7200, 0x7f00, 0x00000041, Rd_Rs
, s3_do16_dsp2
},
819 {"mulu!", 0x7300, 0x7f00, 0x00000042, Rd_Rs
, s3_do16_dsp2
},
820 {"mulr.l", 0x00000140, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s3_do_rdrsrs
},
821 {"mulr.h", 0x00000240, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s3_do_rdrsrs
},
822 {"mulr", 0x00000340, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s3_do_rdrsrs
},
823 {"mulr.lf", 0x00000141, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s3_do_rdrsrs
},
824 {"mulr.hf", 0x00000241, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s3_do_rdrsrs
},
825 {"mulr.f", 0x00000341, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s3_do_rdrsrs
},
826 {"mulur.l", 0x00000142, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s3_do_rdrsrs
},
827 {"mulur.h", 0x00000242, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s3_do_rdrsrs
},
828 {"mulur", 0x00000342, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s3_do_rdrsrs
},
829 {"divr.q", 0x00000144, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s3_do_rdrsrs
},
830 {"divr.r", 0x00000244, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s3_do_rdrsrs
},
831 {"divr", 0x00000344, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s3_do_rdrsrs
},
832 {"divur.q", 0x00000146, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s3_do_rdrsrs
},
833 {"divur.r", 0x00000246, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s3_do_rdrsrs
},
834 {"divur", 0x00000346, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s3_do_rdrsrs
},
835 {"mvcs", 0x00000056, 0x3e007fff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
836 {"mvcc", 0x00000456, 0x3e007fff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
837 {"mvgtu", 0x00000856, 0x3e007fff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
838 {"mvleu", 0x00000c56, 0x3e007fff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
839 {"mveq", 0x00001056, 0x3e007fff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
840 {"mvne", 0x00001456, 0x3e007fff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
841 {"mvgt", 0x00001856, 0x3e007fff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
842 {"mvle", 0x00001c56, 0x3e007fff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
843 {"mvge", 0x00002056, 0x3e007fff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
844 {"mvlt", 0x00002456, 0x3e007fff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
845 {"mvmi", 0x00002856, 0x3e007fff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
846 {"mvpl", 0x00002c56, 0x3e007fff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
847 {"mvvs", 0x00003056, 0x3e007fff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
848 {"mvvc", 0x00003456, 0x3e007fff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
851 {"mv", 0x00003c56, 0x3e007fff, 0x4000, Rd_Rs_x
, s3_do_rdrs
},
852 {"mv!", 0x4000, 0x7c00, 0x8000, Rd_Rs
, s3_do16_mv_cmp
},
853 {"neg", 0x0000001e, 0x3e0003ff, 0x8000, Rd_x_Rs
, s3_do_rdxrs
},
854 {"neg.c", 0x0000001f, 0x3e0003ff, 0x8000, Rd_x_Rs
, s3_do_rdxrs
},
855 {"nop", 0x00000000, 0x3e0003ff, 0x0000, NO_OPD
, s3_do_empty
},
856 {"not", 0x00000024, 0x3e0003ff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
857 {"not.c", 0x00000025, 0x3e0003ff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
858 {"nop!", 0x0000, 0x7fff, 0x8000, NO16_OPD
, s3_do_empty
},
859 {"or", 0x00000022, 0x3e0003ff, 0x4a00, Rd_Rs_Rs
, s3_do_rdrsrs
},
860 {"or.c", 0x00000023, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_rdrsrs
},
861 {"ori", 0x020a0000, 0x3e0e0001, 0x8000, Rd_I16
, s3_do_rdi16
},
862 {"ori.c", 0x020a0001, 0x3e0e0001, 0x8000, Rd_I16
, s3_do_rdi16
},
863 {"oris", 0x0a0a0000, 0x3e0e0001, 0x8000, Rd_I16
, s3_do_rdi16
},
864 {"oris.c", 0x0a0a0001, 0x3e0e0001, 0x8000, Rd_I16
, s3_do_rdi16
},
865 {"orri", 0x1a000000, 0x3e000001, 0x8000, Rd_Rs_I14
, s3_do_rdrsi14
},
866 {"orri.c", 0x1a000001, 0x3e000001, 0x8000, Rd_Rs_I14
, s3_do_rdrsi14
},
869 {"or!", 0x4a00, 0x7f00, 0x8000, Rd_Rs
, s3_do16_rdrs2
},
870 {"pflush", 0x0000000a, 0x3e0003ff, 0x8000, NO_OPD
, s3_do_empty
},
871 {"pop!", 0x0040, 0x7fe0, 0x8000, Rd_rvalueRs
, s3_do16_push_pop
},
872 {"push!", 0x0060, 0x7fe0, 0x8000, Rd_lvalueRs
, s3_do16_push_pop
},
874 {"rpop!", 0x6800, 0x7c00, 0x8000, Rd_I5
, s3_do16_rpop
},
875 {"rpush!", 0x6c00, 0x7c00, 0x8000, Rd_I5
, s3_do16_rpush
},
877 {"ror", 0x00000038, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_rdrsrs
},
878 {"ror.c", 0x00000039, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_rdrsrs
},
879 {"rorc.c", 0x0000003b, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_rdrsrs
},
880 {"rol", 0x0000003c, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_rdrsrs
},
881 {"rol.c", 0x0000003d, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_rdrsrs
},
882 {"rolc.c", 0x0000003f, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_rdrsrs
},
883 {"rori", 0x00000078, 0x3e0003ff, 0x8000, Rd_Rs_I5
, s3_do_rdrsi5
},
884 {"rori.c", 0x00000079, 0x3e0003ff, 0x8000, Rd_Rs_I5
, s3_do_rdrsi5
},
885 {"roric.c", 0x0000007b, 0x3e0003ff, 0x8000, Rd_Rs_I5
, s3_do_rdrsi5
},
886 {"roli", 0x0000007c, 0x3e0003ff, 0x8000, Rd_Rs_I5
, s3_do_rdrsi5
},
887 {"roli.c", 0x0000007d, 0x3e0003ff, 0x8000, Rd_Rs_I5
, s3_do_rdrsi5
},
888 {"rolic.c", 0x0000007f, 0x3e0003ff, 0x8000, Rd_Rs_I5
, s3_do_rdrsi5
},
889 {"rte", 0x0c000084, 0x3e0003ff, 0x8000, NO_OPD
, s3_do_empty
},
890 {"asw", 0x0000000e, 0x3e0003ff, 0x8000, Rd_lvalue32Rs
, s3_do_ldst_atomic
},
891 {"scb", 0x00000068, 0x3e0003ff, 0x8000, Rd_lvalueRs_post4
, s3_do_ldst_unalign
},
892 {"scw", 0x0000006a, 0x3e0003ff, 0x8000, Rd_lvalueRs_post4
, s3_do_ldst_unalign
},
893 {"sce", 0x0000006e, 0x3e0003ff, 0x8000, x_lvalueRs_post4
, s3_do_ldst_unalign
},
894 {"sdbbp", 0x00000006, 0x3e0003ff, 0x0020, x_I5_x
, s3_do_xi5x
},
895 {"sdbbp!", 0x0020, 0x7fe0, 0x8000, Rd_I5
, s3_do16_xi5
},
896 {"sleep", 0x0c0000c4, 0x3e0003ff, 0x8000, NO_OPD
, s3_do_empty
},
897 {"rti", 0x0c0000e4, 0x3e0003ff, 0x8000, NO_OPD
, s3_do_empty
},
898 {"sll", 0x00000030, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_rdrsrs
},
899 {"sll.c", 0x00000031, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_rdrsrs
},
900 {"sll.s", 0x3800004e, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_dsp2
},
901 {"slli", 0x00000070, 0x3e0003ff, 0x5800, Rd_Rs_I5
, s3_do_rdrsi5
},
902 {"slli.c", 0x00000071, 0x3e0003ff, 0x8000, Rd_Rs_I5
, s3_do_rdrsi5
},
904 /* slli.c <-> slli!. */
905 {"slli!", 0x5800, 0x7e00, 0x8000, Rd_I5
, s3_do16_slli_srli
},
906 {"srl", 0x00000034, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_rdrsrs
},
907 {"srl.c", 0x00000035, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_rdrsrs
},
908 {"sra", 0x00000036, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_rdrsrs
},
909 {"sra.c", 0x00000037, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_rdrsrs
},
910 {"srli", 0x00000074, 0x3e0003ff, 0x5a00, Rd_Rs_I5
, s3_do_rdrsi5
},
911 {"srli.c", 0x00000075, 0x3e0003ff, 0x8000, Rd_Rs_I5
, s3_do_rdrsi5
},
912 {"srai", 0x00000076, 0x3e0003ff, 0x8000, Rd_Rs_I5
, s3_do_rdrsi5
},
913 {"srai.c", 0x00000077, 0x3e0003ff, 0x8000, Rd_Rs_I5
, s3_do_rdrsi5
},
915 /* srli.c <-> srli!. */
916 {"srli!", 0x5a00, 0x7e00, 0x8000, Rd_Rs
, s3_do16_slli_srli
},
917 {"stc1", 0x0c00000b, 0x3e00001f, 0x8000, Rd_lvalueRs_SI10
, s3_do_ldst_cop
},
918 {"stc2", 0x0c000013, 0x3e00001f, 0x8000, Rd_lvalueRs_SI10
, s3_do_ldst_cop
},
919 {"stc3", 0x0c00001b, 0x3e00001f, 0x8000, Rd_lvalueRs_SI10
, s3_do_ldst_cop
},
920 {"sub", 0x00000014, 0x3e0003ff, 0x4900, Rd_Rs_Rs
, s3_do_rdrsrs
},
921 {"sub.c", 0x00000015, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_rdrsrs
},
922 {"sub.s", 0x38000049, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_dsp2
},
923 {"subc", 0x00000016, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_rdrsrs
},
924 {"subc.c", 0x00000017, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_rdrsrs
},
926 /* sub.c <-> sub!. */
927 {"sub!", 0x4900, 0x7f00, 0x8000, Rd_Rs
, s3_do16_rdrs2
},
928 {"sw!", 0x2000, 0x7000, 0x8000, Rd_lvalueRs
, s3_do16_ldst_insn
},
929 {"syscall", 0x00000002, 0x3e0003ff, 0x8000, I15
, s3_do_i15
},
930 {"trapcs", 0x00000004, 0x3e007fff, 0x8000, x_I5_x
, s3_do_xi5x
},
931 {"trapcc", 0x00000404, 0x3e007fff, 0x8000, x_I5_x
, s3_do_xi5x
},
932 {"trapgtu", 0x00000804, 0x3e007fff, 0x8000, x_I5_x
, s3_do_xi5x
},
933 {"trapleu", 0x00000c04, 0x3e007fff, 0x8000, x_I5_x
, s3_do_xi5x
},
934 {"trapeq", 0x00001004, 0x3e007fff, 0x8000, x_I5_x
, s3_do_xi5x
},
935 {"trapne", 0x00001404, 0x3e007fff, 0x8000, x_I5_x
, s3_do_xi5x
},
936 {"trapgt", 0x00001804, 0x3e007fff, 0x8000, x_I5_x
, s3_do_xi5x
},
937 {"traple", 0x00001c04, 0x3e007fff, 0x8000, x_I5_x
, s3_do_xi5x
},
938 {"trapge", 0x00002004, 0x3e007fff, 0x8000, x_I5_x
, s3_do_xi5x
},
939 {"traplt", 0x00002404, 0x3e007fff, 0x8000, x_I5_x
, s3_do_xi5x
},
940 {"trapmi", 0x00002804, 0x3e007fff, 0x8000, x_I5_x
, s3_do_xi5x
},
941 {"trappl", 0x00002c04, 0x3e007fff, 0x8000, x_I5_x
, s3_do_xi5x
},
942 {"trapvs", 0x00003004, 0x3e007fff, 0x8000, x_I5_x
, s3_do_xi5x
},
943 {"trapvc", 0x00003404, 0x3e007fff, 0x8000, x_I5_x
, s3_do_xi5x
},
944 {"trap", 0x00003c04, 0x3e007fff, 0x8000, x_I5_x
, s3_do_xi5x
},
945 {"xor", 0x00000026, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_rdrsrs
},
946 {"xor.c", 0x00000027, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_rdrsrs
},
948 /* Macro instruction. */
949 {"li", 0x020c0000, 0x3e0e0000, 0x8000, Insn_Type_SYN
, s3_do_macro_li_rdi32
},
951 /* la reg, imm32 -->(1) ldi reg, simm16
952 (2) ldis reg, %HI(imm32)
955 la reg, symbol -->(1) lis reg, %HI(imm32)
956 ori reg, %LO(imm32) */
957 {"la", 0x020c0000, 0x3e0e0000, 0x8000, Insn_Type_SYN
, s3_do_macro_la_rdi32
},
958 {"bcmpeqz", 0x0000004c, 0x3e00007e, 0x8000, Insn_BCMP
, s3_do_macro_bcmpz
},
959 {"bcmpeq", 0x0000004c, 0x3e00007e, 0x8000, Insn_BCMP
, s3_do_macro_bcmp
},
960 {"bcmpnez", 0x0000004e, 0x3e00007e, 0x8000, Insn_BCMP
, s3_do_macro_bcmpz
},
961 {"bcmpne", 0x0000004e, 0x3e00007e, 0x8000, Insn_BCMP
, s3_do_macro_bcmp
},
962 {"div", 0x00000044, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s3_do_macro_mul_rdrsrs
},
963 {"divu", 0x00000046, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s3_do_macro_mul_rdrsrs
},
964 {"rem", 0x00000044, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s3_do_macro_mul_rdrsrs
},
965 {"remu", 0x00000046, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s3_do_macro_mul_rdrsrs
},
966 {"mul", 0x00000040, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s3_do_macro_mul_rdrsrs
},
967 {"mulu", 0x00000042, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s3_do_macro_mul_rdrsrs
},
968 {"maz", 0x00000040, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s3_do_macro_mul_rdrsrs
},
969 {"mazu", 0x00000042, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s3_do_macro_mul_rdrsrs
},
970 {"mul.f", 0x00000041, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s3_do_macro_mul_rdrsrs
},
971 {"maz.f", 0x00000041, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s3_do_macro_mul_rdrsrs
},
972 {"lb", INSN_LB
, 0x00000000, 0x8000, Insn_Type_SYN
, s3_do_macro_ldst_label
},
973 {"lbu", INSN_LBU
, 0x00000000, 0x8000, Insn_Type_SYN
, s3_do_macro_ldst_label
},
974 {"lh", INSN_LH
, 0x00000000, 0x8000, Insn_Type_SYN
, s3_do_macro_ldst_label
},
975 {"lhu", INSN_LHU
, 0x00000000, 0x8000, Insn_Type_SYN
, s3_do_macro_ldst_label
},
976 {"lw", INSN_LW
, 0x00000000, 0x1000, Insn_Type_SYN
, s3_do_macro_ldst_label
},
977 {"sb", INSN_SB
, 0x00000000, 0x8000, Insn_Type_SYN
, s3_do_macro_ldst_label
},
978 {"sh", INSN_SH
, 0x00000000, 0x8000, Insn_Type_SYN
, s3_do_macro_ldst_label
},
979 {"sw", INSN_SW
, 0x00000000, 0x2000, Insn_Type_SYN
, s3_do_macro_ldst_label
},
981 /* Assembler use internal. */
982 {"ld_i32hi", 0x0a0c0000, 0x3e0e0000, 0x8000, Insn_internal
, s3_do_macro_rdi32hi
},
983 {"ld_i32lo", 0x020a0000, 0x3e0e0001, 0x8000, Insn_internal
, s3_do_macro_rdi32lo
},
984 {"ldis_pic", 0x0a0c0000, 0x3e0e0000, 0x8000, Insn_internal
, s3_do_rdi16_pic
},
985 {"addi_s_pic",0x02000000, 0x3e0e0001, 0x8000, Insn_internal
, s3_do_addi_s_pic
},
986 {"addi_u_pic",0x02000000, 0x3e0e0001, 0x8000, Insn_internal
, s3_do_addi_u_pic
},
987 {"lw_pic", 0x20000000, 0x3e000000, 0x8000, Insn_internal
, s3_do_lw_pic
},
989 /* 48-bit instructions. */
990 {"sdbbp48", 0x000000000000LL
, 0x1c000000001fLL
, 0x8000, Rd_I32
, s3_do_sdbbp48
},
991 {"ldi48", 0x000000000001LL
, 0x1c000000001fLL
, 0x8000, Rd_I32
, s3_do_ldi48
},
992 {"lw48", 0x000000000002LL
, 0x1c000000001fLL
, 0x8000, Rd_I30
, s3_do_lw48
},
993 {"sw48", 0x000000000003LL
, 0x1c000000001fLL
, 0x8000, Rd_I30
, s3_do_sw48
},
994 {"andri48", 0x040000000000LL
, 0x1c0000000003LL
, 0x8000, Rd_I32
, s3_do_and48
},
995 {"andri48.c", 0x040000000001LL
, 0x1c0000000003LL
, 0x8000, Rd_I32
, s3_do_and48
},
996 {"orri48", 0x040000000002LL
, 0x1c0000000003LL
, 0x8000, Rd_I32
, s3_do_or48
},
997 {"orri48.c", 0x040000000003LL
, 0x1c0000000003LL
, 0x8000, Rd_I32
, s3_do_or48
},
1000 #define s3_SCORE3_PIPELINE 3
1002 static int s3_university_version
= 0;
1003 static int s3_vector_size
= s3_SCORE3_PIPELINE
;
1004 static struct s3_score_it s3_dependency_vector
[s3_SCORE3_PIPELINE
];
1006 static int s3_score3d
= 1;
1009 s3_end_of_line (char *str
)
1011 int retval
= s3_SUCCESS
;
1013 s3_skip_whitespace (str
);
1016 retval
= (int) s3_FAIL
;
1019 s3_inst
.error
= s3_BAD_GARBAGE
;
1026 s3_score_reg_parse (char **ccp
, htab_t htab
)
1031 struct s3_reg_entry
*reg
;
1034 if (!ISALPHA (*p
) || !is_name_beginner (*p
))
1035 return (int) s3_FAIL
;
1039 while (ISALPHA (c
) || ISDIGIT (c
) || c
== '_')
1043 reg
= (struct s3_reg_entry
*) str_hash_find (htab
, start
);
1051 return (int) s3_FAIL
;
1054 /* If shift <= 0, only return reg. */
1057 s3_reg_required_here (char **str
, int shift
, enum s3_score_reg_type reg_type
)
1059 static char buff
[s3_MAX_LITERAL_POOL_SIZE
];
1060 int reg
= (int) s3_FAIL
;
1063 if ((reg
= s3_score_reg_parse (str
, s3_all_reg_maps
[reg_type
].htab
)) != (int) s3_FAIL
)
1065 if (reg_type
== s3_REG_TYPE_SCORE
)
1067 if ((reg
== 1) && (s3_nor1
== 1) && (s3_inst
.bwarn
== 0))
1069 as_warn (_("Using temp register (r1)"));
1075 if (reg_type
== s3_REG_TYPE_SCORE_CR
)
1076 strcpy (s3_inst
.reg
, s3_score_crn_table
[reg
].name
);
1077 else if (reg_type
== s3_REG_TYPE_SCORE_SR
)
1078 strcpy (s3_inst
.reg
, s3_score_srn_table
[reg
].name
);
1080 strcpy (s3_inst
.reg
, "");
1082 s3_inst
.instruction
|= (bfd_vma
) reg
<< shift
;
1088 sprintf (buff
, _("register expected, not '%.100s'"), start
);
1089 s3_inst
.error
= buff
;
1096 s3_skip_past_comma (char **str
)
1102 while ((c
= *p
) == ' ' || c
== ',')
1105 if (c
== ',' && comma
++)
1107 s3_inst
.error
= s3_BAD_SKIP_COMMA
;
1108 return (int) s3_FAIL
;
1112 if ((c
== '\0') || (comma
== 0))
1114 s3_inst
.error
= s3_BAD_SKIP_COMMA
;
1115 return (int) s3_FAIL
;
1119 return comma
? s3_SUCCESS
: (int) s3_FAIL
;
1123 s3_do_rdrsrs (char *str
)
1126 s3_skip_whitespace (str
);
1128 if ((reg
= s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
1129 || s3_skip_past_comma (&str
) == (int) s3_FAIL
1130 || s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
1131 || s3_skip_past_comma (&str
) == (int) s3_FAIL
1132 || s3_reg_required_here (&str
, 10, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
1133 || s3_end_of_line (str
) == (int) s3_FAIL
)
1139 /* Check mulr, mulur rd is even number. */
1140 if (((s3_inst
.instruction
& 0x3e0003ff) == 0x00000340
1141 || (s3_inst
.instruction
& 0x3e0003ff) == 0x00000342)
1144 s3_inst
.error
= _("rd must be even number.");
1148 if ((((s3_inst
.instruction
>> 15) & 0x10) == 0)
1149 && (((s3_inst
.instruction
>> 10) & 0x10) == 0)
1150 && (((s3_inst
.instruction
>> 20) & 0x10) == 0)
1151 && (s3_inst
.relax_inst
!= 0x8000)
1152 && (((s3_inst
.instruction
>> 20) & 0xf) == ((s3_inst
.instruction
>> 15) & 0xf)))
1154 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>> 10) & 0xf) )
1155 | (((s3_inst
.instruction
>> 15) & 0xf) << 4);
1156 s3_inst
.relax_size
= 2;
1160 s3_inst
.relax_inst
= 0x8000;
1166 s3_walk_no_bignums (symbolS
* sp
)
1168 if (symbol_get_value_expression (sp
)->X_op
== O_big
)
1171 if (symbol_get_value_expression (sp
)->X_add_symbol
)
1172 return (s3_walk_no_bignums (symbol_get_value_expression (sp
)->X_add_symbol
)
1173 || (symbol_get_value_expression (sp
)->X_op_symbol
1174 && s3_walk_no_bignums (symbol_get_value_expression (sp
)->X_op_symbol
)));
1180 s3_my_get_expression (expressionS
* ep
, char **str
)
1184 save_in
= input_line_pointer
;
1185 input_line_pointer
= *str
;
1186 s3_in_my_get_expression
= 1;
1187 (void) expression (ep
);
1188 s3_in_my_get_expression
= 0;
1190 if (ep
->X_op
== O_illegal
)
1192 *str
= input_line_pointer
;
1193 input_line_pointer
= save_in
;
1194 s3_inst
.error
= _("illegal expression");
1195 return (int) s3_FAIL
;
1197 /* Get rid of any bignums now, so that we don't generate an error for which
1198 we can't establish a line number later on. Big numbers are never valid
1199 in instructions, which is where this routine is always called. */
1200 if (ep
->X_op
== O_big
1201 || (ep
->X_add_symbol
1202 && (s3_walk_no_bignums (ep
->X_add_symbol
)
1203 || (ep
->X_op_symbol
&& s3_walk_no_bignums (ep
->X_op_symbol
)))))
1205 s3_inst
.error
= _("invalid constant");
1206 *str
= input_line_pointer
;
1207 input_line_pointer
= save_in
;
1208 return (int) s3_FAIL
;
1211 if ((ep
->X_add_symbol
!= NULL
)
1212 && (s3_inst
.type
!= PC_DISP19div2
)
1213 && (s3_inst
.type
!= PC_DISP8div2
)
1214 && (s3_inst
.type
!= PC_DISP24div2
)
1215 && (s3_inst
.type
!= PC_DISP11div2
)
1216 && (s3_inst
.type
!= Insn_Type_SYN
)
1217 && (s3_inst
.type
!= Rd_rvalueRs_SI15
)
1218 && (s3_inst
.type
!= Rd_lvalueRs_SI15
)
1219 && (s3_inst
.type
!= Insn_internal
)
1220 && (s3_inst
.type
!= Rd_I30
)
1221 && (s3_inst
.type
!= Rd_I32
)
1222 && (s3_inst
.type
!= Insn_BCMP
))
1224 s3_inst
.error
= s3_BAD_ARGS
;
1225 *str
= input_line_pointer
;
1226 input_line_pointer
= save_in
;
1227 return (int) s3_FAIL
;
1230 *str
= input_line_pointer
;
1231 input_line_pointer
= save_in
;
1235 /* Check if an immediate is valid. If so, convert it to the right format. */
1236 static bfd_signed_vma
1237 s3_validate_immediate (bfd_signed_vma val
, unsigned int data_type
, int hex_p
)
1243 bfd_signed_vma val_hi
= ((val
& 0xffff0000) >> 16);
1245 if (s3_score_df_range
[data_type
].range
[0] <= val_hi
1246 && val_hi
<= s3_score_df_range
[data_type
].range
[1])
1253 bfd_signed_vma val_lo
= (val
& 0xffff);
1255 if (s3_score_df_range
[data_type
].range
[0] <= val_lo
1256 && val_lo
<= s3_score_df_range
[data_type
].range
[1])
1264 if (!(val
>= -0x2000 && val
<= 0x3fff))
1266 return (int) s3_FAIL
;
1271 if (!(val
>= -8192 && val
<= 8191))
1273 return (int) s3_FAIL
;
1283 if (!(val
>= -0x7fff && val
<= 0xffff && val
!= 0x8000))
1285 return (int) s3_FAIL
;
1290 if (!(val
>= -32767 && val
<= 32768))
1292 return (int) s3_FAIL
;
1300 case _IMM5_MULTI_LOAD
:
1301 if (val
>= 2 && val
<= 32)
1307 return (int) s3_FAIL
;
1310 if (val
>= 0 && val
<= 0xffffffff)
1316 return (int) s3_FAIL
;
1320 if (data_type
== _SIMM14_NEG
|| data_type
== _IMM16_NEG
)
1323 if (s3_score_df_range
[data_type
].range
[0] <= val
1324 && val
<= s3_score_df_range
[data_type
].range
[1])
1330 return (int) s3_FAIL
;
1334 s3_data_op2 (char **str
, int shift
, enum score_data_type data_type
)
1336 bfd_signed_vma value
;
1337 char data_exp
[s3_MAX_LITERAL_POOL_SIZE
];
1342 s3_skip_whitespace (*str
);
1343 s3_inst
.error
= NULL
;
1346 /* Set hex_p to zero. */
1349 while ((*dataptr
!= '\0') && (*dataptr
!= '|') && (cnt
<= s3_MAX_LITERAL_POOL_SIZE
)) /* 0x7c = ='|' */
1351 data_exp
[cnt
] = *dataptr
;
1356 data_exp
[cnt
] = '\0';
1357 pp
= (char *)&data_exp
;
1359 if (*dataptr
== '|') /* process PCE */
1361 if (s3_my_get_expression (&s3_inst
.reloc
.exp
, &pp
) == (int) s3_FAIL
)
1362 return (int) s3_FAIL
;
1363 s3_end_of_line (pp
);
1364 if (s3_inst
.error
!= 0)
1365 return (int) s3_FAIL
; /* to ouptut_inst to printf out the error */
1368 else /* process 16 bit */
1370 if (s3_my_get_expression (&s3_inst
.reloc
.exp
, str
) == (int) s3_FAIL
)
1372 return (int) s3_FAIL
;
1375 dataptr
= (char *)data_exp
;
1376 for (; *dataptr
!= '\0'; dataptr
++)
1378 *dataptr
= TOLOWER (*dataptr
);
1379 if (*dataptr
== '!' || *dataptr
== ' ')
1382 dataptr
= (char *)data_exp
;
1384 if ((dataptr
!= NULL
)
1385 && (((strstr (dataptr
, "0x")) != NULL
)
1386 || ((strstr (dataptr
, "0X")) != NULL
)))
1389 if ((data_type
!= _SIMM16_LA
)
1390 && (data_type
!= _VALUE_HI16
)
1391 && (data_type
!= _VALUE_LO16
)
1392 && (data_type
!= _IMM16
)
1393 && (data_type
!= _IMM15
)
1394 && (data_type
!= _IMM14
)
1395 && (data_type
!= _IMM4
)
1396 && (data_type
!= _IMM5
)
1397 && (data_type
!= _IMM5_MULTI_LOAD
)
1398 && (data_type
!= _IMM11
)
1399 && (data_type
!= _IMM8
)
1400 && (data_type
!= _IMM5_RSHIFT_1
)
1401 && (data_type
!= _IMM5_RSHIFT_2
)
1402 && (data_type
!= _SIMM14
)
1403 && (data_type
!= _SIMM14_NEG
)
1404 && (data_type
!= _SIMM16_NEG
)
1405 && (data_type
!= _IMM10_RSHIFT_2
)
1406 && (data_type
!= _GP_IMM15
)
1407 && (data_type
!= _SIMM5
)
1408 && (data_type
!= _SIMM6
)
1409 && (data_type
!= _IMM32
)
1410 && (data_type
!= _SIMM32
))
1416 if ((s3_inst
.reloc
.exp
.X_add_number
== 0)
1417 && (s3_inst
.type
!= Insn_Type_SYN
)
1418 && (s3_inst
.type
!= Rd_rvalueRs_SI15
)
1419 && (s3_inst
.type
!= Rd_lvalueRs_SI15
)
1420 && (s3_inst
.type
!= Insn_internal
)
1421 && (((*dataptr
>= 'a') && (*dataptr
<= 'z'))
1422 || ((*dataptr
== '0') && (*(dataptr
+ 1) == 'x') && (*(dataptr
+ 2) != '0'))
1423 || ((*dataptr
== '+') && (*(dataptr
+ 1) != '0'))
1424 || ((*dataptr
== '-') && (*(dataptr
+ 1) != '0'))))
1426 s3_inst
.error
= s3_BAD_ARGS
;
1427 return (int) s3_FAIL
;
1431 if ((s3_inst
.reloc
.exp
.X_add_symbol
)
1432 && ((data_type
== _SIMM16
)
1433 || (data_type
== _SIMM16_NEG
)
1434 || (data_type
== _IMM16_NEG
)
1435 || (data_type
== _SIMM14
)
1436 || (data_type
== _SIMM14_NEG
)
1437 || (data_type
== _IMM5
)
1438 || (data_type
== _IMM5_MULTI_LOAD
)
1439 || (data_type
== _IMM11
)
1440 || (data_type
== _IMM14
)
1441 || (data_type
== _IMM20
)
1442 || (data_type
== _IMM16
)
1443 || (data_type
== _IMM15
)
1444 || (data_type
== _IMM4
)))
1446 s3_inst
.error
= s3_BAD_ARGS
;
1447 return (int) s3_FAIL
;
1450 if (s3_inst
.reloc
.exp
.X_add_symbol
)
1455 return (int) s3_FAIL
;
1457 s3_inst
.reloc
.type
= BFD_RELOC_HI16_S
;
1458 s3_inst
.reloc
.pc_rel
= 0;
1461 s3_inst
.reloc
.type
= BFD_RELOC_LO16
;
1462 s3_inst
.reloc
.pc_rel
= 0;
1465 s3_inst
.reloc
.type
= BFD_RELOC_SCORE_GPREL15
;
1466 s3_inst
.reloc
.pc_rel
= 0;
1469 case _IMM16_LO16_pic
:
1470 s3_inst
.reloc
.type
= BFD_RELOC_SCORE_GOT_LO16
;
1471 s3_inst
.reloc
.pc_rel
= 0;
1474 s3_inst
.reloc
.type
= BFD_RELOC_32
;
1475 s3_inst
.reloc
.pc_rel
= 0;
1481 if (data_type
== _IMM16_pic
)
1483 s3_inst
.reloc
.type
= BFD_RELOC_SCORE_DUMMY_HI16
;
1484 s3_inst
.reloc
.pc_rel
= 0;
1487 if (data_type
== _SIMM16_LA
&& s3_inst
.reloc
.exp
.X_unsigned
== 1)
1489 value
= s3_validate_immediate (s3_inst
.reloc
.exp
.X_add_number
, _SIMM16_LA_POS
, hex_p
);
1490 if (value
== (int) s3_FAIL
) /* for advance to check if this is ldis */
1491 if ((s3_inst
.reloc
.exp
.X_add_number
& 0xffff) == 0)
1493 s3_inst
.instruction
|= 0x8000000;
1494 s3_inst
.instruction
|= ((s3_inst
.reloc
.exp
.X_add_number
>> 16) << 1) & 0x1fffe;
1500 value
= s3_validate_immediate (s3_inst
.reloc
.exp
.X_add_number
, data_type
, hex_p
);
1503 if (value
== (int) s3_FAIL
)
1505 if (data_type
== _IMM32
)
1507 sprintf (s3_err_msg
,
1508 _("invalid constant: %d bit expression not in range %u..%u"),
1509 s3_score_df_range
[data_type
].bits
,
1510 0, (unsigned)0xffffffff);
1512 else if (data_type
== _IMM5_MULTI_LOAD
)
1514 sprintf (s3_err_msg
,
1515 _("invalid constant: %d bit expression not in range %u..%u"),
1518 else if ((data_type
!= _SIMM14_NEG
) && (data_type
!= _SIMM16_NEG
) && (data_type
!= _IMM16_NEG
))
1520 sprintf (s3_err_msg
,
1521 _("invalid constant: %d bit expression not in range %d..%d"),
1522 s3_score_df_range
[data_type
].bits
,
1523 s3_score_df_range
[data_type
].range
[0], s3_score_df_range
[data_type
].range
[1]);
1527 sprintf (s3_err_msg
,
1528 _("invalid constant: %d bit expression not in range %d..%d"),
1529 s3_score_df_range
[data_type
].bits
,
1530 -s3_score_df_range
[data_type
].range
[1], -s3_score_df_range
[data_type
].range
[0]);
1533 s3_inst
.error
= s3_err_msg
;
1534 return (int) s3_FAIL
;
1537 if (((s3_score_df_range
[data_type
].range
[0] != 0) || (data_type
== _IMM5_RANGE_8_31
))
1538 && data_type
!= _IMM5_MULTI_LOAD
)
1540 value
&= (1 << s3_score_df_range
[data_type
].bits
) - 1;
1543 s3_inst
.instruction
|= value
<< shift
;
1546 if ((s3_inst
.instruction
& 0x3e000000) == 0x30000000)
1548 if ((((s3_inst
.instruction
>> 20) & 0x1F) != 0)
1549 && (((s3_inst
.instruction
>> 20) & 0x1F) != 1)
1550 && (((s3_inst
.instruction
>> 20) & 0x1F) != 2)
1551 && (((s3_inst
.instruction
>> 20) & 0x1F) != 0x10))
1553 s3_inst
.error
= _("invalid constant: bit expression not defined");
1554 return (int) s3_FAIL
;
1561 /* Handle addi/addi.c/addis.c/cmpi.c/addis.c/ldi. */
1563 s3_do_rdsi16 (char *str
)
1565 s3_skip_whitespace (str
);
1567 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
1568 || s3_skip_past_comma (&str
) == (int) s3_FAIL
1569 || s3_data_op2 (&str
, 1, _SIMM16
) == (int) s3_FAIL
1570 || s3_end_of_line (str
) == (int) s3_FAIL
)
1573 /* ldi.->ldiu! only for imm5 */
1574 if ((s3_inst
.instruction
& 0x20c0000) == 0x20c0000)
1576 if ((s3_inst
.instruction
& 0x1ffc0) != 0)
1578 s3_inst
.relax_inst
= 0x8000;
1582 s3_inst
.relax_inst
|= (s3_inst
.instruction
>> 1) & 0x1f;
1583 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>> 20)& 0x1f) <<5);
1584 s3_inst
.relax_size
= 2;
1588 else if ((s3_inst
.instruction
& 0x02040001) == 0x02040001)
1590 /* imm <=0x3f (5 bit<<1)*/
1591 if (((s3_inst
.instruction
& 0x1ffe0) == 0)
1592 || (((s3_inst
.instruction
& 0x1ffe0) == 0x1ffe0)
1593 && (s3_inst
.instruction
& 0x003e) != 0))
1595 s3_inst
.relax_inst
|= (s3_inst
.instruction
>> 1) & 0x1f;
1596 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>> 20) & 0x1f) << 5);
1597 s3_inst
.relax_size
= 2;
1601 s3_inst
.relax_inst
=0x8000;
1606 else if (((s3_inst
.instruction
& 0x2000000) == 0x02000000) && (s3_inst
.relax_inst
!=0x8000))
1608 /* rd : 0-16 ; imm <=0x7f (6 bit<<1)*/
1609 if ((((s3_inst
.instruction
>> 20) & 0x10) != 0x10)
1610 && (((s3_inst
.instruction
& 0x1ffc0) == 0)
1611 || (((s3_inst
.instruction
& 0x1ffc0) == 0x1ffc0)
1612 && (s3_inst
.instruction
& 0x007e) != 0)))
1614 s3_inst
.relax_inst
|= (s3_inst
.instruction
>> 1) & 0x3f;
1615 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>> 20) & 0xf) << 6);
1616 s3_inst
.relax_size
= 2;
1620 s3_inst
.relax_inst
=0x8000;
1624 else if (((s3_inst
.instruction
>> 20) & 0x10) == 0x10)
1626 s3_inst
.relax_inst
= 0x8000;
1631 s3_do_ldis (char *str
)
1633 s3_skip_whitespace (str
);
1635 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
1636 || s3_skip_past_comma (&str
) == (int) s3_FAIL
1637 || s3_data_op2 (&str
, 1, _IMM16
) == (int) s3_FAIL
1638 || s3_end_of_line (str
) == (int) s3_FAIL
)
1642 /* Handle subi/subi.c. */
1644 s3_do_sub_rdsi16 (char *str
)
1646 s3_skip_whitespace (str
);
1648 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) != (int) s3_FAIL
1649 && s3_skip_past_comma (&str
) != (int) s3_FAIL
1650 && s3_data_op2 (&str
, 1, _SIMM16_NEG
) != (int) s3_FAIL
)
1651 s3_end_of_line (str
);
1654 /* Handle subis/subis.c. */
1656 s3_do_sub_rdi16 (char *str
)
1658 s3_skip_whitespace (str
);
1660 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) != (int) s3_FAIL
1661 && s3_skip_past_comma (&str
) != (int) s3_FAIL
1662 && s3_data_op2 (&str
, 1, _IMM16_NEG
) != (int) s3_FAIL
)
1663 s3_end_of_line (str
);
1666 /* Handle addri/addri.c. */
1668 s3_do_rdrssi14 (char *str
) /* -(2^13)~((2^13)-1) */
1670 s3_skip_whitespace (str
);
1672 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) != (int) s3_FAIL
1673 && s3_skip_past_comma (&str
) != (int) s3_FAIL
1674 && s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) != (int) s3_FAIL
1675 && s3_skip_past_comma (&str
) != (int) s3_FAIL
)
1676 s3_data_op2 (&str
, 1, _SIMM14
);
1679 /* Handle subri.c/subri. */
1681 s3_do_sub_rdrssi14 (char *str
) /* -(2^13)~((2^13)-1) */
1683 s3_skip_whitespace (str
);
1685 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) != (int) s3_FAIL
1686 && s3_skip_past_comma (&str
) != (int) s3_FAIL
1687 && s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) != (int) s3_FAIL
1688 && s3_skip_past_comma (&str
) != (int) s3_FAIL
1689 && s3_data_op2 (&str
, 1, _SIMM14_NEG
) != (int) s3_FAIL
)
1690 s3_end_of_line (str
);
1693 /* Handle bitclr.c/bitset.c/bittgl.c/slli.c/srai.c/srli.c/roli.c/rori.c/rolic.c.
1696 s3_do_rdrsi5 (char *str
)
1698 s3_skip_whitespace (str
);
1700 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
1701 || s3_skip_past_comma (&str
) == (int) s3_FAIL
1702 || s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
1703 || s3_skip_past_comma (&str
) == (int) s3_FAIL
1704 || s3_data_op2 (&str
, 10, _IMM5
) == (int) s3_FAIL
1705 || s3_end_of_line (str
) == (int) s3_FAIL
)
1708 if ((((s3_inst
.instruction
>> 20) & 0x1f) == ((s3_inst
.instruction
>> 15) & 0x1f))
1709 && (s3_inst
.relax_inst
!= 0x8000) && (((s3_inst
.instruction
>> 15) & 0x10) == 0))
1711 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>> 10) & 0x1f) ) | (((s3_inst
.instruction
>> 15) & 0xf) << 5);
1712 s3_inst
.relax_size
= 2;
1715 s3_inst
.relax_inst
= 0x8000;
1718 /* Handle andri/orri/andri.c/orri.c.
1721 s3_do_rdrsi14 (char *str
)
1723 s3_skip_whitespace (str
);
1725 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) != (int) s3_FAIL
1726 && s3_skip_past_comma (&str
) != (int) s3_FAIL
1727 && s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) != (int) s3_FAIL
1728 && s3_skip_past_comma (&str
) != (int) s3_FAIL
1729 && s3_data_op2 (&str
, 1, _IMM14
) != (int) s3_FAIL
)
1730 s3_end_of_line (str
);
1733 /* Handle bittst.c. */
1735 s3_do_xrsi5 (char *str
)
1737 s3_skip_whitespace (str
);
1739 if (s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
1740 || s3_skip_past_comma (&str
) == (int) s3_FAIL
1741 || s3_data_op2 (&str
, 10, _IMM5
) == (int) s3_FAIL
1742 || s3_end_of_line (str
) == (int) s3_FAIL
)
1745 if ((s3_inst
.relax_inst
!= 0x8000) && (((s3_inst
.instruction
>> 15) & 0x10) == 0))
1747 s3_inst
.relax_inst
|= ((s3_inst
.instruction
>> 10) & 0x1f) | (((s3_inst
.instruction
>> 15) & 0xf) << 5);
1748 s3_inst
.relax_size
= 2;
1751 s3_inst
.relax_inst
= 0x8000;
1754 /* Handle addis/andi/ori/andis/oris/ldis. */
1756 s3_do_rdi16 (char *str
)
1758 s3_skip_whitespace (str
);
1760 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
1761 || s3_skip_past_comma (&str
) == (int) s3_FAIL
1762 || s3_data_op2 (&str
, 1, _IMM16
) == (int) s3_FAIL
1763 || s3_end_of_line (str
) == (int) s3_FAIL
)
1767 if ((s3_inst
.instruction
& 0x3e0e0000) == 0x0a0c0000)
1769 /* rd : 0-16 ;imm =0 -> can transform to addi!*/
1770 if ((((s3_inst
.instruction
>> 20) & 0x10) != 0x10) && ((s3_inst
.instruction
& 0x1ffff)==0))
1772 s3_inst
.relax_inst
=0x5400; /* ldiu! */
1773 s3_inst
.relax_inst
|= (s3_inst
.instruction
>> 1) & 0x1f;
1774 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>> 20) & 0xf) << 5);
1775 s3_inst
.relax_size
= 2;
1779 s3_inst
.relax_inst
=0x8000;
1785 else if ((s3_inst
.instruction
& 0x3e0e0001) == 0x0a000000)
1787 /* rd : 0-16 ;imm =0 -> can transform to addi!*/
1788 if ((((s3_inst
.instruction
>> 20) & 0x10) != 0x10) && ((s3_inst
.instruction
& 0x1ffff)==0))
1790 s3_inst
.relax_inst
=0x5c00; /* addi! */
1791 s3_inst
.relax_inst
|= (s3_inst
.instruction
>> 1) & 0x3f;
1792 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>> 20) & 0xf) << 6);
1793 s3_inst
.relax_size
= 2;
1797 s3_inst
.relax_inst
=0x8000;
1804 s3_do_macro_rdi32hi (char *str
)
1806 s3_skip_whitespace (str
);
1808 /* Do not handle s3_end_of_line(). */
1809 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) != (int) s3_FAIL
1810 && s3_skip_past_comma (&str
) != (int) s3_FAIL
)
1811 s3_data_op2 (&str
, 1, _VALUE_HI16
);
1815 s3_do_macro_rdi32lo (char *str
)
1817 s3_skip_whitespace (str
);
1819 /* Do not handle s3_end_of_line(). */
1820 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) != (int) s3_FAIL
1821 && s3_skip_past_comma (&str
) != (int) s3_FAIL
)
1822 s3_data_op2 (&str
, 1, _VALUE_LO16
);
1825 /* Handle ldis_pic. */
1827 s3_do_rdi16_pic (char *str
)
1829 s3_skip_whitespace (str
);
1831 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) != (int) s3_FAIL
1832 && s3_skip_past_comma (&str
) != (int) s3_FAIL
1833 && s3_data_op2 (&str
, 1, _IMM16_pic
) != (int) s3_FAIL
)
1834 s3_end_of_line (str
);
1837 /* Handle addi_s_pic to generate R_SCORE_GOT_LO16 . */
1839 s3_do_addi_s_pic (char *str
)
1841 s3_skip_whitespace (str
);
1843 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) != (int) s3_FAIL
1844 && s3_skip_past_comma (&str
) != (int) s3_FAIL
1845 && s3_data_op2 (&str
, 1, _SIMM16_pic
) != (int) s3_FAIL
)
1846 s3_end_of_line (str
);
1849 /* Handle addi_u_pic to generate R_SCORE_GOT_LO16 . */
1851 s3_do_addi_u_pic (char *str
)
1853 s3_skip_whitespace (str
);
1855 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) != (int) s3_FAIL
1856 && s3_skip_past_comma (&str
) != (int) s3_FAIL
1857 && s3_data_op2 (&str
, 1, _IMM16_LO16_pic
) != (int) s3_FAIL
)
1858 s3_end_of_line (str
);
1861 /* Handle mfceh/mfcel/mtceh/mtchl. */
1863 s3_do_rd (char *str
)
1865 s3_skip_whitespace (str
);
1867 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) != (int) s3_FAIL
)
1868 s3_end_of_line (str
);
1871 /* Handle br{cond},cmpzteq.c ,cmpztmi.c ,cmpz.c */
1873 s3_do_rs (char *str
)
1875 s3_skip_whitespace (str
);
1877 if (s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
1878 || s3_end_of_line (str
) == (int) s3_FAIL
)
1881 if ((s3_inst
.relax_inst
!= 0x8000) )
1883 s3_inst
.relax_inst
|= ((s3_inst
.instruction
>> 15) &0x1f);
1884 s3_inst
.relax_size
= 2;
1887 s3_inst
.relax_inst
= 0x8000;
1891 s3_do_i15 (char *str
)
1893 s3_skip_whitespace (str
);
1895 if (s3_data_op2 (&str
, 10, _IMM15
) != (int) s3_FAIL
)
1896 s3_end_of_line (str
);
1900 s3_do_xi5x (char *str
)
1902 s3_skip_whitespace (str
);
1904 if (s3_data_op2 (&str
, 15, _IMM5
) == (int) s3_FAIL
|| s3_end_of_line (str
) == (int) s3_FAIL
)
1907 if (s3_inst
.relax_inst
!= 0x8000)
1909 s3_inst
.relax_inst
|= ((s3_inst
.instruction
>> 15) & 0x1f);
1910 s3_inst
.relax_size
= 2;
1915 s3_do_rdrs (char *str
)
1917 s3_skip_whitespace (str
);
1919 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
1920 || s3_skip_past_comma (&str
) == (int) s3_FAIL
1921 || s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
1922 || s3_end_of_line (str
) == (int) s3_FAIL
)
1925 if (s3_inst
.relax_inst
!= 0x8000)
1927 if (((s3_inst
.instruction
& 0x7f) == 0x56)) /* adjust mv -> mv!*/
1929 /* mv! rd : 5bit , ra : 5bit */
1930 s3_inst
.relax_inst
|= ((s3_inst
.instruction
>> 15) & 0x1f) | (((s3_inst
.instruction
>> 20) & 0x1f) << 5);
1931 s3_inst
.relax_size
= 2;
1933 else if ((((s3_inst
.instruction
>> 15) & 0x10) == 0x0) && (((s3_inst
.instruction
>> 20) & 0x10) == 0))
1935 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>> 15) & 0xf) << 4)
1936 | (((s3_inst
.instruction
>> 20) & 0xf) << 8);
1937 s3_inst
.relax_size
= 2;
1941 s3_inst
.relax_inst
= 0x8000;
1946 /* Handle mfcr/mtcr. */
1948 s3_do_rdcrs (char *str
)
1950 s3_skip_whitespace (str
);
1952 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) != (int) s3_FAIL
1953 && s3_skip_past_comma (&str
) != (int) s3_FAIL
1954 && s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE_CR
) != (int) s3_FAIL
)
1955 s3_end_of_line (str
);
1958 /* Handle mfsr/mtsr. */
1960 s3_do_rdsrs (char *str
)
1962 s3_skip_whitespace (str
);
1965 if ((s3_inst
.instruction
& 0xff) == 0x50)
1967 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) != (int) s3_FAIL
1968 && s3_skip_past_comma (&str
) != (int) s3_FAIL
1969 && s3_reg_required_here (&str
, 10, s3_REG_TYPE_SCORE_SR
) != (int) s3_FAIL
)
1970 s3_end_of_line (str
);
1974 if (s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) != (int) s3_FAIL
1975 && s3_skip_past_comma (&str
) != (int) s3_FAIL
)
1976 s3_reg_required_here (&str
, 10, s3_REG_TYPE_SCORE_SR
);
1982 s3_do_rdxrs (char *str
)
1984 s3_skip_whitespace (str
);
1986 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
1987 || s3_skip_past_comma (&str
) == (int) s3_FAIL
1988 || s3_reg_required_here (&str
, 10, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
1989 || s3_end_of_line (str
) == (int) s3_FAIL
)
1992 if ((s3_inst
.relax_inst
!= 0x8000) && (((s3_inst
.instruction
>> 10) & 0x10) == 0)
1993 && (((s3_inst
.instruction
>> 20) & 0x10) == 0))
1995 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>> 10) & 0xf) << 4) | (((s3_inst
.instruction
>> 20) & 0xf) << 8);
1996 s3_inst
.relax_size
= 2;
1999 s3_inst
.relax_inst
= 0x8000;
2002 /* Handle cmp.c/cmp<cond>. */
2004 s3_do_rsrs (char *str
)
2006 s3_skip_whitespace (str
);
2008 if (s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
2009 || s3_skip_past_comma (&str
) == (int) s3_FAIL
2010 || s3_reg_required_here (&str
, 10, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
2011 || s3_end_of_line (str
) == (int) s3_FAIL
)
2014 if ((s3_inst
.relax_inst
!= 0x8000) && (((s3_inst
.instruction
>> 20) & 0x1f) == 3) )
2016 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>> 10) & 0x1f)) | (((s3_inst
.instruction
>> 15) & 0x1f) << 5);
2017 s3_inst
.relax_size
= 2;
2020 s3_inst
.relax_inst
= 0x8000;
2024 s3_do_ceinst (char *str
)
2029 s3_skip_whitespace (str
);
2031 if (s3_data_op2 (&str
, 20, _IMM5
) == (int) s3_FAIL
2032 || s3_skip_past_comma (&str
) == (int) s3_FAIL
2033 || s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
2034 || s3_skip_past_comma (&str
) == (int) s3_FAIL
2035 || s3_reg_required_here (&str
, 10, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
2036 || s3_skip_past_comma (&str
) == (int) s3_FAIL
2037 || s3_data_op2 (&str
, 5, _IMM5
) == (int) s3_FAIL
2038 || s3_skip_past_comma (&str
) == (int) s3_FAIL
2039 || s3_data_op2 (&str
, 0, _IMM5
) == (int) s3_FAIL
2040 || s3_end_of_line (str
) == (int) s3_FAIL
)
2047 if (s3_data_op2 (&str
, 0, _IMM25
) == (int) s3_FAIL
)
2053 s3_reglow_required_here (char **str
, int shift
)
2055 static char buff
[s3_MAX_LITERAL_POOL_SIZE
];
2059 if ((reg
= s3_score_reg_parse (str
, s3_all_reg_maps
[s3_REG_TYPE_SCORE
].htab
)) != (int) s3_FAIL
)
2061 if ((reg
== 1) && (s3_nor1
== 1) && (s3_inst
.bwarn
== 0))
2063 as_warn (_("Using temp register(r1)"));
2069 s3_inst
.instruction
|= (bfd_vma
) reg
<< shift
;
2075 /* Restore the start point, we may have got a reg of the wrong class. */
2077 sprintf (buff
, _("low register (r0-r15) expected, not '%.100s'"), start
);
2078 s3_inst
.error
= buff
;
2079 return (int) s3_FAIL
;
2082 /* Handle add!/and!/or!/sub!. */
2084 s3_do16_rdrs2 (char *str
)
2086 s3_skip_whitespace (str
);
2088 if (s3_reglow_required_here (&str
, 4) == (int) s3_FAIL
2089 || s3_skip_past_comma (&str
) == (int) s3_FAIL
2090 || s3_reglow_required_here (&str
, 0) == (int) s3_FAIL
2091 || s3_end_of_line (str
) == (int) s3_FAIL
)
2097 /* Handle br!/brl!. */
2099 s3_do16_br (char *str
)
2101 s3_skip_whitespace (str
);
2103 if (s3_reg_required_here (&str
, 0, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
2104 || s3_end_of_line (str
) == (int) s3_FAIL
)
2112 s3_do16_brr (char *str
)
2116 s3_skip_whitespace (str
);
2118 if ((rd
= s3_reg_required_here (&str
, 0,s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
2119 || s3_end_of_line (str
) == (int) s3_FAIL
)
2125 /*Handle ltbw / ltbh / ltbb */
2127 s3_do_ltb (char *str
)
2129 s3_skip_whitespace (str
);
2130 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
2131 || s3_skip_past_comma (&str
) == (int) s3_FAIL
)
2136 s3_skip_whitespace (str
);
2139 s3_inst
.error
= _("missing [");
2143 if (s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
2144 || s3_skip_past_comma (&str
) == (int) s3_FAIL
2145 || s3_reg_required_here (&str
, 10, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
)
2150 s3_skip_whitespace (str
);
2153 s3_inst
.error
= _("missing ]");
2158 /* We need to be able to fix up arbitrary expressions in some statements.
2159 This is so that we can handle symbols that are an arbitrary distance from
2160 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
2161 which returns part of an address in a form which will be valid for
2162 a data instruction. We do this by pushing the expression into a symbol
2163 in the expr_section, and creating a fix for that. */
2165 s3_fix_new_score (fragS
* frag
, int where
, short int size
, expressionS
* exp
, int pc_rel
, int reloc
)
2175 new_fix
= fix_new_exp (frag
, where
, size
, exp
, pc_rel
, reloc
);
2178 new_fix
= fix_new (frag
, where
, size
, make_expr_symbol (exp
), 0, pc_rel
, reloc
);
2185 s3_init_dependency_vector (void)
2189 for (i
= 0; i
< s3_vector_size
; i
++)
2190 memset (&s3_dependency_vector
[i
], '\0', sizeof (s3_dependency_vector
[i
]));
2195 static enum s3_insn_type_for_dependency
2196 s3_dependency_type_from_insn (char *insn_name
)
2198 char name
[s3_INSN_NAME_LEN
];
2199 const struct s3_insn_to_dependency
*tmp
;
2201 strcpy (name
, insn_name
);
2202 tmp
= (const struct s3_insn_to_dependency
*)
2203 str_hash_find (s3_dependency_insn_hsh
, name
);
2208 return s3_D_all_insn
;
2212 s3_check_dependency (char *pre_insn
, char *pre_reg
,
2213 char *cur_insn
, char *cur_reg
, int *warn_or_error
)
2217 enum s3_insn_type_for_dependency pre_insn_type
;
2218 enum s3_insn_type_for_dependency cur_insn_type
;
2220 pre_insn_type
= s3_dependency_type_from_insn (pre_insn
);
2221 cur_insn_type
= s3_dependency_type_from_insn (cur_insn
);
2223 for (i
= 0; i
< sizeof (s3_data_dependency_table
) / sizeof (s3_data_dependency_table
[0]); i
++)
2225 if ((pre_insn_type
== s3_data_dependency_table
[i
].pre_insn_type
)
2226 && (s3_D_all_insn
== s3_data_dependency_table
[i
].cur_insn_type
2227 || cur_insn_type
== s3_data_dependency_table
[i
].cur_insn_type
)
2228 && (strcmp (s3_data_dependency_table
[i
].pre_reg
, "") == 0
2229 || strcmp (s3_data_dependency_table
[i
].pre_reg
, pre_reg
) == 0)
2230 && (strcmp (s3_data_dependency_table
[i
].cur_reg
, "") == 0
2231 || strcmp (s3_data_dependency_table
[i
].cur_reg
, cur_reg
) == 0))
2233 bubbles
= s3_data_dependency_table
[i
].bubblenum_3
;
2234 *warn_or_error
= s3_data_dependency_table
[i
].warn_or_error
;
2243 s3_build_one_frag (struct s3_score_it one_inst
)
2246 int relaxable_p
= s3_g_opt
;
2249 /* Start a new frag if frag_now is not empty. */
2250 if (frag_now_fix () != 0)
2252 if (!frag_now
->tc_frag_data
.is_insn
)
2253 frag_wane (frag_now
);
2259 p
= frag_more (one_inst
.size
);
2260 s3_md_number_to_chars (p
, one_inst
.instruction
, one_inst
.size
);
2263 dwarf2_emit_insn (one_inst
.size
);
2266 relaxable_p
&= (one_inst
.relax_size
!= 0);
2267 relax_size
= relaxable_p
? one_inst
.relax_size
: 0;
2269 p
= frag_var (rs_machine_dependent
, relax_size
+ s3_RELAX_PAD_BYTE
, 0,
2270 s3_RELAX_ENCODE (one_inst
.size
, one_inst
.relax_size
,
2271 one_inst
.type
, 0, 0, relaxable_p
),
2275 s3_md_number_to_chars (p
, one_inst
.relax_inst
, relax_size
);
2279 s3_handle_dependency (struct s3_score_it
*theinst
)
2282 int warn_or_error
= 0; /* warn - 0; error - 1 */
2284 int remainder_bubbles
= 0;
2285 char cur_insn
[s3_INSN_NAME_LEN
];
2286 char pre_insn
[s3_INSN_NAME_LEN
];
2287 struct s3_score_it nop_inst
;
2288 struct s3_score_it pflush_inst
;
2290 nop_inst
.instruction
= 0x0000;
2292 nop_inst
.relax_inst
= 0x80008000;
2293 nop_inst
.relax_size
= 4;
2294 nop_inst
.type
= NO16_OPD
;
2296 pflush_inst
.instruction
= 0x8000800a;
2297 pflush_inst
.size
= 4;
2298 pflush_inst
.relax_inst
= 0x8000;
2299 pflush_inst
.relax_size
= 0;
2300 pflush_inst
.type
= NO_OPD
;
2302 /* pflush will clear all data dependency. */
2303 if (strcmp (theinst
->name
, "pflush") == 0)
2305 s3_init_dependency_vector ();
2309 /* Push current instruction to s3_dependency_vector[0]. */
2310 for (i
= s3_vector_size
- 1; i
> 0; i
--)
2311 memcpy (&s3_dependency_vector
[i
], &s3_dependency_vector
[i
- 1], sizeof (s3_dependency_vector
[i
]));
2313 memcpy (&s3_dependency_vector
[0], theinst
, sizeof (s3_dependency_vector
[i
]));
2315 /* There is no dependency between nop and any instruction. */
2316 if (strcmp (s3_dependency_vector
[0].name
, "nop") == 0
2317 || strcmp (s3_dependency_vector
[0].name
, "nop!") == 0)
2320 strcpy (cur_insn
, s3_dependency_vector
[0].name
);
2322 for (i
= 1; i
< s3_vector_size
; i
++)
2324 /* The element of s3_dependency_vector is NULL. */
2325 if (s3_dependency_vector
[i
].name
[0] == '\0')
2328 strcpy (pre_insn
, s3_dependency_vector
[i
].name
);
2330 bubbles
= s3_check_dependency (pre_insn
, s3_dependency_vector
[i
].reg
,
2331 cur_insn
, s3_dependency_vector
[0].reg
, &warn_or_error
);
2332 remainder_bubbles
= bubbles
- i
+ 1;
2334 if (remainder_bubbles
> 0)
2338 if (s3_fix_data_dependency
== 1)
2340 if (remainder_bubbles
<= 2)
2342 if (s3_warn_fix_data_dependency
)
2343 as_warn (_("Fix data dependency: %s %s -- %s %s (insert %d nop!/%d)"),
2344 s3_dependency_vector
[i
].name
, s3_dependency_vector
[i
].reg
,
2345 s3_dependency_vector
[0].name
, s3_dependency_vector
[0].reg
,
2346 remainder_bubbles
, bubbles
);
2348 for (j
= (s3_vector_size
- 1); (j
- remainder_bubbles
) > 0; j
--)
2349 memcpy (&s3_dependency_vector
[j
], &s3_dependency_vector
[j
- remainder_bubbles
],
2350 sizeof (s3_dependency_vector
[j
]));
2352 for (j
= 1; j
<= remainder_bubbles
; j
++)
2354 memset (&s3_dependency_vector
[j
], '\0', sizeof (s3_dependency_vector
[j
]));
2356 s3_build_one_frag (nop_inst
);
2361 if (s3_warn_fix_data_dependency
)
2362 as_warn (_("Fix data dependency: %s %s -- %s %s (insert 1 pflush/%d)"),
2363 s3_dependency_vector
[i
].name
, s3_dependency_vector
[i
].reg
,
2364 s3_dependency_vector
[0].name
, s3_dependency_vector
[0].reg
,
2367 for (j
= 1; j
< s3_vector_size
; j
++)
2368 memset (&s3_dependency_vector
[j
], '\0', sizeof (s3_dependency_vector
[j
]));
2370 /* Insert pflush. */
2371 s3_build_one_frag (pflush_inst
);
2378 as_bad (_("data dependency: %s %s -- %s %s (%d/%d bubble)"),
2379 s3_dependency_vector
[i
].name
, s3_dependency_vector
[i
].reg
,
2380 s3_dependency_vector
[0].name
, s3_dependency_vector
[0].reg
,
2381 remainder_bubbles
, bubbles
);
2385 as_warn (_("data dependency: %s %s -- %s %s (%d/%d bubble)"),
2386 s3_dependency_vector
[i
].name
, s3_dependency_vector
[i
].reg
,
2387 s3_dependency_vector
[0].name
, s3_dependency_vector
[0].reg
,
2388 remainder_bubbles
, bubbles
);
2395 static enum insn_class
2396 s3_get_insn_class_from_type (enum score_insn_type type
)
2398 enum insn_class retval
= (int) s3_FAIL
;
2404 case Rd_rvalueBP_I5
:
2405 case Rd_lvalueBP_I5
:
2418 retval
= INSN_CLASS_16
;
2427 case Rd_rvalueRs_SI10
:
2428 case Rd_lvalueRs_SI10
:
2429 case Rd_rvalueRs_preSI12
:
2430 case Rd_rvalueRs_postSI12
:
2431 case Rd_lvalueRs_preSI12
:
2432 case Rd_lvalueRs_postSI12
:
2434 case Rd_rvalueRs_SI15
:
2435 case Rd_lvalueRs_SI15
:
2444 case OP5_rvalueRs_SI15
:
2445 case I5_Rs_Rs_I5_OP5
:
2446 case x_rvalueRs_post4
:
2447 case Rd_rvalueRs_post4
:
2449 case Rd_lvalueRs_post4
:
2450 case x_lvalueRs_post4
:
2460 retval
= INSN_CLASS_32
;
2463 retval
= INSN_CLASS_PCE
;
2466 retval
= INSN_CLASS_SYN
;
2470 retval
= INSN_CLASS_48
;
2480 48-bit instruction: 1, 1, 0.
2481 32-bit instruction: 1, 0.
2482 16-bit instruction: 0. */
2484 s3_adjust_paritybit (bfd_vma m_code
, enum insn_class i_class
)
2487 bfd_vma m_code_high
= 0;
2488 unsigned long m_code_middle
= 0;
2489 unsigned long m_code_low
= 0;
2490 bfd_vma pb_high
= 0;
2491 unsigned long pb_middle
= 0;
2492 unsigned long pb_low
= 0;
2494 if (i_class
== INSN_CLASS_48
)
2496 pb_high
= 0x800000000000LL
;
2497 pb_middle
= 0x80000000;
2498 pb_low
= 0x00000000;
2499 m_code_high
= m_code
& 0x1fffc0000000LL
;
2500 m_code_middle
= m_code
& 0x3fff8000;
2501 m_code_low
= m_code
& 0x00007fff;
2502 result
= pb_high
| (m_code_high
<< 2) |
2503 pb_middle
| (m_code_middle
<< 1) |
2504 pb_low
| m_code_low
;
2506 else if (i_class
== INSN_CLASS_32
|| i_class
== INSN_CLASS_SYN
)
2508 pb_high
= 0x80000000;
2509 pb_low
= 0x00000000;
2510 m_code_high
= m_code
& 0x3fff8000;
2511 m_code_low
= m_code
& 0x00007fff;
2512 result
= pb_high
| (m_code_high
<< 1) | pb_low
| m_code_low
;
2514 else if (i_class
== INSN_CLASS_16
)
2518 m_code_high
= m_code
& 0x3fff8000;
2519 m_code_low
= m_code
& 0x00007fff;
2520 result
= pb_high
| (m_code_high
<< 1) | pb_low
| m_code_low
;
2522 else if (i_class
== INSN_CLASS_PCE
)
2524 /* Keep original. */
2526 pb_low
= 0x00008000;
2527 m_code_high
= m_code
& 0x3fff8000;
2528 m_code_low
= m_code
& 0x00007fff;
2529 result
= pb_high
| (m_code_high
<< 1) | pb_low
| m_code_low
;
2540 s3_gen_insn_frag (struct s3_score_it
*part_1
, struct s3_score_it
*part_2
)
2544 int relaxable_p
= s3_g_opt
;
2546 struct s3_score_it
*inst1
= part_1
;
2547 struct s3_score_it
*inst2
= part_2
;
2548 struct s3_score_it backup_inst1
;
2550 pce_p
= inst2
!= NULL
;
2551 memcpy (&backup_inst1
, inst1
, sizeof (struct s3_score_it
));
2553 /* Adjust instruction opcode and to be relaxed instruction opcode. */
2556 backup_inst1
.instruction
= ((backup_inst1
.instruction
& 0x7FFF) << 15)
2557 | (inst2
->instruction
& 0x7FFF);
2558 backup_inst1
.instruction
= s3_adjust_paritybit (backup_inst1
.instruction
, INSN_CLASS_PCE
);
2559 backup_inst1
.relax_inst
= 0x8000;
2560 backup_inst1
.size
= s3_INSN_SIZE
;
2561 backup_inst1
.relax_size
= 0;
2562 backup_inst1
.type
= Insn_Type_PCE
;
2566 backup_inst1
.instruction
= s3_adjust_paritybit (backup_inst1
.instruction
,
2567 s3_GET_INSN_CLASS (backup_inst1
.type
));
2570 if (backup_inst1
.relax_size
!= 0)
2572 enum insn_class tmp
;
2574 tmp
= (backup_inst1
.size
== s3_INSN_SIZE
) ? INSN_CLASS_16
: INSN_CLASS_32
;
2575 backup_inst1
.relax_inst
= s3_adjust_paritybit (backup_inst1
.relax_inst
, tmp
);
2578 /* Check data dependency. */
2579 s3_handle_dependency (&backup_inst1
);
2581 /* Start a new frag if frag_now is not empty and is not instruction frag, maybe it contains
2582 data produced by .ascii etc. Doing this is to make one instruction per frag. */
2583 if (frag_now_fix () != 0)
2585 if (!frag_now
->tc_frag_data
.is_insn
)
2586 frag_wane (frag_now
);
2591 /* Here, we must call frag_grow in order to keep the instruction frag type is
2592 rs_machine_dependent.
2593 For, frag_var may change frag_now->fr_type to rs_fill by calling frag_grow which
2594 actually will call frag_wane.
2595 Calling frag_grow first will create a new frag_now which free size is 20 that is enough
2599 p
= frag_more (backup_inst1
.size
);
2600 s3_md_number_to_chars (p
, backup_inst1
.instruction
, backup_inst1
.size
);
2603 dwarf2_emit_insn (backup_inst1
.size
);
2606 /* Generate fixup structure. */
2609 if (inst1
->reloc
.type
!= BFD_RELOC_NONE
)
2610 s3_fix_new_score (frag_now
, p
- frag_now
->fr_literal
,
2611 inst1
->size
, &inst1
->reloc
.exp
,
2612 inst1
->reloc
.pc_rel
, inst1
->reloc
.type
);
2614 if (inst2
->reloc
.type
!= BFD_RELOC_NONE
)
2615 s3_fix_new_score (frag_now
, p
- frag_now
->fr_literal
+ 2,
2616 inst2
->size
, &inst2
->reloc
.exp
, inst2
->reloc
.pc_rel
, inst2
->reloc
.type
);
2620 if (backup_inst1
.reloc
.type
!= BFD_RELOC_NONE
)
2621 s3_fix_new_score (frag_now
, p
- frag_now
->fr_literal
,
2622 backup_inst1
.size
, &backup_inst1
.reloc
.exp
,
2623 backup_inst1
.reloc
.pc_rel
, backup_inst1
.reloc
.type
);
2626 /* relax_size may be 2, 4, 12 or 0, 0 indicates no relaxation. */
2627 relaxable_p
&= (backup_inst1
.relax_size
!= 0);
2628 relax_size
= relaxable_p
? backup_inst1
.relax_size
: 0;
2630 p
= frag_var (rs_machine_dependent
, relax_size
+ s3_RELAX_PAD_BYTE
, 0,
2631 s3_RELAX_ENCODE (backup_inst1
.size
, backup_inst1
.relax_size
,
2632 backup_inst1
.type
, 0, 0, relaxable_p
),
2633 backup_inst1
.reloc
.exp
.X_add_symbol
, 0, NULL
);
2636 s3_md_number_to_chars (p
, backup_inst1
.relax_inst
, relax_size
);
2638 memcpy (inst1
, &backup_inst1
, sizeof (struct s3_score_it
));
2642 s3_parse_16_32_inst (char *insnstr
, bool gen_frag_p
)
2646 char *operator = insnstr
;
2647 const struct s3_asm_opcode
*opcode
;
2649 /* Parse operator and operands. */
2650 s3_skip_whitespace (operator);
2652 for (p
= operator; *p
!= '\0'; p
++)
2653 if ((*p
== ' ') || (*p
== '!'))
2662 opcode
= (const struct s3_asm_opcode
*) str_hash_find (s3_score_ops_hsh
,
2666 memset (&s3_inst
, '\0', sizeof (s3_inst
));
2667 sprintf (s3_inst
.str
, "%s", insnstr
);
2670 s3_inst
.instruction
= opcode
->value
;
2671 s3_inst
.relax_inst
= opcode
->relax_value
;
2672 s3_inst
.type
= opcode
->type
;
2673 s3_inst
.size
= s3_GET_INSN_SIZE (s3_inst
.type
);
2674 s3_inst
.relax_size
= 0;
2676 sprintf (s3_inst
.name
, "%s", opcode
->template_name
);
2677 strcpy (s3_inst
.reg
, "");
2678 s3_inst
.error
= NULL
;
2679 s3_inst
.reloc
.type
= BFD_RELOC_NONE
;
2681 (*opcode
->parms
) (p
);
2683 /* It indicates current instruction is a macro instruction if s3_inst.bwarn equals -1. */
2684 if ((s3_inst
.bwarn
!= -1) && (!s3_inst
.error
) && (gen_frag_p
))
2685 s3_gen_insn_frag (&s3_inst
, NULL
);
2688 s3_inst
.error
= _("unrecognized opcode");
2692 s3_parse_48_inst (char *insnstr
, bool gen_frag_p
)
2696 char *operator = insnstr
;
2697 const struct s3_asm_opcode
*opcode
;
2699 /* Parse operator and operands. */
2700 s3_skip_whitespace (operator);
2702 for (p
= operator; *p
!= '\0'; p
++)
2709 opcode
= (const struct s3_asm_opcode
*) str_hash_find (s3_score_ops_hsh
,
2713 memset (&s3_inst
, '\0', sizeof (s3_inst
));
2714 sprintf (s3_inst
.str
, "%s", insnstr
);
2717 s3_inst
.instruction
= opcode
->value
;
2718 s3_inst
.relax_inst
= opcode
->relax_value
;
2719 s3_inst
.type
= opcode
->type
;
2720 s3_inst
.size
= s3_GET_INSN_SIZE (s3_inst
.type
);
2721 s3_inst
.relax_size
= 0;
2723 sprintf (s3_inst
.name
, "%s", opcode
->template_name
);
2724 strcpy (s3_inst
.reg
, "");
2725 s3_inst
.error
= NULL
;
2726 s3_inst
.reloc
.type
= BFD_RELOC_NONE
;
2728 (*opcode
->parms
) (p
);
2730 /* It indicates current instruction is a macro instruction if s3_inst.bwarn equals -1. */
2731 if ((s3_inst
.bwarn
!= -1) && (!s3_inst
.error
) && (gen_frag_p
))
2732 s3_gen_insn_frag (&s3_inst
, NULL
);
2735 s3_inst
.error
= _("unrecognized opcode");
2739 s3_append_insn (char *str
, bool gen_frag_p
)
2741 int retval
= s3_SUCCESS
;
2743 s3_parse_16_32_inst (str
, gen_frag_p
);
2747 retval
= (int) s3_FAIL
;
2748 as_bad (_("%s -- `%s'"), s3_inst
.error
, s3_inst
.str
);
2749 s3_inst
.error
= NULL
;
2756 s3_do16_mv_cmp (char *str
)
2758 s3_skip_whitespace (str
);
2760 if (s3_reg_required_here (&str
, 5, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
2761 || s3_skip_past_comma (&str
) == (int) s3_FAIL
2762 || s3_reg_required_here (&str
, 0, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
2763 || s3_end_of_line (str
) == (int) s3_FAIL
)
2770 s3_do16_cmpi (char *str
)
2772 s3_skip_whitespace (str
);
2774 if (s3_reg_required_here (&str
, 5, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
2775 || s3_skip_past_comma (&str
) == (int) s3_FAIL
2776 || s3_data_op2 (&str
, 0, _SIMM5
) == (int) s3_FAIL
2777 || s3_end_of_line (str
) == (int) s3_FAIL
)
2784 s3_do16_addi (char *str
)
2786 s3_skip_whitespace (str
);
2788 if (s3_reglow_required_here (&str
, 6) == (int) s3_FAIL
2789 || s3_skip_past_comma (&str
) == (int) s3_FAIL
2790 || s3_data_op2 (&str
, 0, _SIMM6
) == (int) s3_FAIL
2791 || s3_end_of_line (str
) == (int) s3_FAIL
)
2797 /* Handle bitclr! / bitset! / bittst! / bittgl! */
2799 s3_do16_rdi5 (char *str
)
2801 s3_skip_whitespace (str
);
2803 if (s3_reglow_required_here (&str
, 5) == (int) s3_FAIL
2804 || s3_skip_past_comma (&str
) == (int) s3_FAIL
2805 || s3_data_op2 (&str
, 0, _IMM5
) == (int) s3_FAIL
2806 || s3_end_of_line (str
) == (int) s3_FAIL
)
2810 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>>5) & 0xf) << 20)
2811 | (((s3_inst
.instruction
>> 5) & 0xf) << 15) | (((s3_inst
.instruction
) & 0x1f) << 10);
2812 s3_inst
.relax_size
= 4;
2817 /* Handle sdbbp!. */
2819 s3_do16_xi5 (char *str
)
2821 s3_skip_whitespace (str
);
2823 if (s3_data_op2 (&str
, 0, _IMM5
) == (int) s3_FAIL
|| s3_end_of_line (str
) == (int) s3_FAIL
)
2827 /* Check that an immediate is word alignment or half word alignment.
2828 If so, convert it to the right format. */
2830 s3_validate_immediate_align (int val
, unsigned int data_type
)
2832 if (data_type
== _IMM5_RSHIFT_1
)
2836 s3_inst
.error
= _("address offset must be half word alignment");
2837 return (int) s3_FAIL
;
2840 else if ((data_type
== _IMM5_RSHIFT_2
) || (data_type
== _IMM10_RSHIFT_2
))
2844 s3_inst
.error
= _("address offset must be word alignment");
2845 return (int) s3_FAIL
;
2853 s3_exp_ldst_offset (char **str
, int shift
, unsigned int data_type
)
2859 if ((*dataptr
== '0') && (*(dataptr
+ 1) == 'x')
2860 && (data_type
!= _SIMM16_LA
)
2861 && (data_type
!= _VALUE_HI16
)
2862 && (data_type
!= _VALUE_LO16
)
2863 && (data_type
!= _IMM16
)
2864 && (data_type
!= _IMM15
)
2865 && (data_type
!= _IMM14
)
2866 && (data_type
!= _IMM4
)
2867 && (data_type
!= _IMM5
)
2868 && (data_type
!= _IMM8
)
2869 && (data_type
!= _IMM5_RSHIFT_1
)
2870 && (data_type
!= _IMM5_RSHIFT_2
)
2871 && (data_type
!= _SIMM14_NEG
)
2872 && (data_type
!= _IMM10_RSHIFT_2
))
2877 if (s3_my_get_expression (&s3_inst
.reloc
.exp
, str
) == (int) s3_FAIL
)
2878 return (int) s3_FAIL
;
2880 if (s3_inst
.reloc
.exp
.X_op
== O_constant
)
2882 /* Need to check the immediate align. */
2883 int value
= s3_validate_immediate_align (s3_inst
.reloc
.exp
.X_add_number
, data_type
);
2885 if (value
== (int) s3_FAIL
)
2886 return (int) s3_FAIL
;
2888 value
= s3_validate_immediate (s3_inst
.reloc
.exp
.X_add_number
, data_type
, 0);
2889 if (value
== (int) s3_FAIL
)
2892 sprintf (s3_err_msg
,
2893 _("invalid constant: %d bit expression not in range %d..%d"),
2894 s3_score_df_range
[data_type
].bits
,
2895 s3_score_df_range
[data_type
].range
[0], s3_score_df_range
[data_type
].range
[1]);
2897 sprintf (s3_err_msg
,
2898 _("invalid constant: %d bit expression not in range %d..%d"),
2899 s3_score_df_range
[data_type
- 24].bits
,
2900 s3_score_df_range
[data_type
- 24].range
[0], s3_score_df_range
[data_type
- 24].range
[1]);
2901 s3_inst
.error
= s3_err_msg
;
2902 return (int) s3_FAIL
;
2905 if (data_type
== _IMM5_RSHIFT_1
)
2909 else if ((data_type
== _IMM5_RSHIFT_2
) || (data_type
== _IMM10_RSHIFT_2
))
2914 if (s3_score_df_range
[data_type
].range
[0] != 0)
2916 value
&= (1 << s3_score_df_range
[data_type
].bits
) - 1;
2919 s3_inst
.instruction
|= value
<< shift
;
2923 s3_inst
.reloc
.pc_rel
= 0;
2930 s3_do_ldst_insn (char *str
)
2940 s3_skip_whitespace (str
);
2942 if (((conflict_reg
= s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
)
2943 || (s3_skip_past_comma (&str
) == (int) s3_FAIL
))
2946 /* ld/sw rD, [rA, simm15] ld/sw rD, [rA]+, simm12 ld/sw rD, [rA, simm12]+. */
2950 s3_skip_whitespace (str
);
2952 if ((reg
= s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
)
2955 /* Conflicts can occur on stores as well as loads. */
2956 conflict_reg
= (conflict_reg
== reg
);
2957 s3_skip_whitespace (str
);
2958 temp
= str
+ 1; /* The latter will process decimal/hex expression. */
2960 /* ld/sw rD, [rA]+, simm12 ld/sw rD, [rA]+. */
2967 /* ld/sw rD, [rA]+, simm12. */
2968 if (s3_skip_past_comma (&str
) == s3_SUCCESS
)
2970 if ((s3_exp_ldst_offset (&str
, 3, _SIMM12
) == (int) s3_FAIL
)
2971 || (s3_end_of_line (str
) == (int) s3_FAIL
))
2976 unsigned int ldst_func
= s3_inst
.instruction
& OPC_PSEUDOLDST_MASK
;
2978 if ((ldst_func
== INSN_LH
)
2979 || (ldst_func
== INSN_LHU
)
2980 || (ldst_func
== INSN_LW
)
2981 || (ldst_func
== INSN_LB
)
2982 || (ldst_func
== INSN_LBU
))
2984 s3_inst
.error
= _("register same as write-back base");
2989 ldst_idx
= s3_inst
.instruction
& OPC_PSEUDOLDST_MASK
;
2990 s3_inst
.instruction
&= ~OPC_PSEUDOLDST_MASK
;
2991 s3_inst
.instruction
|= s3_score_ldst_insns
[ldst_idx
* 3 + LDST_POST
].value
;
2993 /* lw rD, [rA]+, 4 convert to pop rD, [rA]. */
2994 if ((s3_inst
.instruction
& 0x3e000007) == 0x0e000000)
2996 /* rs = r0, offset = 4 */
2997 if ((((s3_inst
.instruction
>> 15) & 0x1f) == 0)
2998 && (((s3_inst
.instruction
>> 3) & 0xfff) == 4))
3000 /* Relax to pop!. */
3001 s3_inst
.relax_inst
= 0x0040 | ((s3_inst
.instruction
>> 20) & 0x1f);
3002 s3_inst
.relax_size
= 2;
3007 /* ld/sw rD, [rA]+ convert to ld/sw rD, [rA, 0]+. */
3010 s3_SET_INSN_ERROR (NULL
);
3011 if (s3_end_of_line (str
) == (int) s3_FAIL
)
3017 value
= s3_validate_immediate (s3_inst
.reloc
.exp
.X_add_number
, _SIMM12
, 0);
3018 value
&= (1 << s3_score_df_range
[_SIMM12
].bits
) - 1;
3019 ldst_idx
= s3_inst
.instruction
& OPC_PSEUDOLDST_MASK
;
3020 s3_inst
.instruction
&= ~OPC_PSEUDOLDST_MASK
;
3021 s3_inst
.instruction
|= s3_score_ldst_insns
[ldst_idx
* 3 + pre_inc
].value
;
3022 s3_inst
.instruction
|= value
<< 3;
3023 s3_inst
.relax_inst
= 0x8000;
3027 /* ld/sw rD, [rA] convert to ld/sw rD, [rA, simm15]. */
3030 if (s3_end_of_line (str
) == (int) s3_FAIL
)
3033 ldst_idx
= s3_inst
.instruction
& OPC_PSEUDOLDST_MASK
;
3034 s3_inst
.instruction
&= ~OPC_PSEUDOLDST_MASK
;
3035 s3_inst
.instruction
|= s3_score_ldst_insns
[ldst_idx
* 3 + LDST_NOUPDATE
].value
;
3037 /* lbu rd, [rs] -> lbu! rd, [rs] */
3038 if (ldst_idx
== INSN_LBU
)
3040 s3_inst
.relax_inst
= INSN16_LBU
;
3042 else if (ldst_idx
== INSN_LH
)
3044 s3_inst
.relax_inst
= INSN16_LH
;
3046 else if (ldst_idx
== INSN_LW
)
3048 s3_inst
.relax_inst
= INSN16_LW
;
3050 else if (ldst_idx
== INSN_SB
)
3052 s3_inst
.relax_inst
= INSN16_SB
;
3054 else if (ldst_idx
== INSN_SH
)
3056 s3_inst
.relax_inst
= INSN16_SH
;
3058 else if (ldst_idx
== INSN_SW
)
3060 s3_inst
.relax_inst
= INSN16_SW
;
3064 s3_inst
.relax_inst
= 0x8000;
3067 /* lw/lh/lbu/sw/sh/sb, offset = 0, relax to 16 bit instruction. */
3068 /* if ((ldst_idx == INSN_LBU)
3069 || (ldst_idx == INSN_LH)
3070 || (ldst_idx == INSN_LW)
3071 || (ldst_idx == INSN_SB) || (ldst_idx == INSN_SH) || (ldst_idx == INSN_SW))*/
3072 if ( (ldst_idx
== INSN_LW
)|| (ldst_idx
== INSN_SW
))
3074 /* ra only 3 bit , rd only 4 bit for lw! and sw! */
3075 if ((((s3_inst
.instruction
>> 15) & 0x18) == 0) && (((s3_inst
.instruction
>> 20) & 0x10) == 0))
3077 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>> 20) & 0xf) << 8) |
3078 (((s3_inst
.instruction
>> 15) & 0x7) << 5);
3079 s3_inst
.relax_size
= 2;
3086 /* ld/sw rD, [rA, simm15] ld/sw rD, [rA, simm12]+. */
3089 if (s3_skip_past_comma (&str
) == (int) s3_FAIL
)
3091 s3_inst
.error
= _("pre-indexed expression expected");
3095 if (s3_my_get_expression (&s3_inst
.reloc
.exp
, &str
) == (int) s3_FAIL
)
3098 s3_skip_whitespace (str
);
3101 s3_inst
.error
= _("missing ]");
3105 s3_skip_whitespace (str
);
3106 /* ld/sw rD, [rA, simm12]+. */
3113 unsigned int ldst_func
= s3_inst
.instruction
& OPC_PSEUDOLDST_MASK
;
3115 if ((ldst_func
== INSN_LH
)
3116 || (ldst_func
== INSN_LHU
)
3117 || (ldst_func
== INSN_LW
)
3118 || (ldst_func
== INSN_LB
)
3119 || (ldst_func
== INSN_LBU
))
3121 s3_inst
.error
= _("register same as write-back base");
3127 if (s3_end_of_line (str
) == (int) s3_FAIL
)
3130 if (s3_inst
.reloc
.exp
.X_op
== O_constant
)
3132 unsigned int data_type
;
3135 data_type
= _SIMM12
;
3137 data_type
= _SIMM15
;
3140 if ((*dataptr
== '0') && (*(dataptr
+ 1) == 'x')
3141 && (data_type
!= _SIMM16_LA
)
3142 && (data_type
!= _VALUE_HI16
)
3143 && (data_type
!= _VALUE_LO16
)
3144 && (data_type
!= _IMM16
)
3145 && (data_type
!= _IMM15
)
3146 && (data_type
!= _IMM14
)
3147 && (data_type
!= _IMM4
)
3148 && (data_type
!= _IMM5
)
3149 && (data_type
!= _IMM8
)
3150 && (data_type
!= _IMM5_RSHIFT_1
)
3151 && (data_type
!= _IMM5_RSHIFT_2
)
3152 && (data_type
!= _SIMM14_NEG
)
3153 && (data_type
!= _IMM10_RSHIFT_2
))
3158 value
= s3_validate_immediate (s3_inst
.reloc
.exp
.X_add_number
, data_type
, 0);
3159 if (value
== (int) s3_FAIL
)
3162 sprintf (s3_err_msg
,
3163 _("invalid constant: %d bit expression not in range %d..%d"),
3164 s3_score_df_range
[data_type
].bits
,
3165 s3_score_df_range
[data_type
].range
[0], s3_score_df_range
[data_type
].range
[1]);
3167 sprintf (s3_err_msg
,
3168 _("invalid constant: %d bit expression not in range %d..%d"),
3169 s3_score_df_range
[data_type
- 24].bits
,
3170 s3_score_df_range
[data_type
- 24].range
[0],
3171 s3_score_df_range
[data_type
- 24].range
[1]);
3172 s3_inst
.error
= s3_err_msg
;
3176 value
&= (1 << s3_score_df_range
[data_type
].bits
) - 1;
3177 ldst_idx
= s3_inst
.instruction
& OPC_PSEUDOLDST_MASK
;
3178 s3_inst
.instruction
&= ~OPC_PSEUDOLDST_MASK
;
3179 s3_inst
.instruction
|= s3_score_ldst_insns
[ldst_idx
* 3 + pre_inc
].value
;
3181 s3_inst
.instruction
|= value
<< 3;
3183 s3_inst
.instruction
|= value
;
3185 /* lw rD, [rA, simm15] */
3186 if ((s3_inst
.instruction
& 0x3e000000) == 0x20000000)
3188 /* rD in [r0 - r15]. , ra in [r0-r7] */
3189 if ((((s3_inst
.instruction
>> 15) & 0x18) == 0)
3190 && (((s3_inst
.instruction
>> 20) & 0x10) == 0))
3192 /* simm = [bit 7], lw -> lw!. */
3193 if (((s3_inst
.instruction
& 0x7f80) == 0)&&((s3_inst
.instruction
&0x3)==0))
3195 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>> 15) & 0x7) << 5)
3196 | (((s3_inst
.instruction
>> 20) & 0xf) << 8)|(value
>>2);
3197 s3_inst
.relax_size
= 2;
3201 s3_inst
.relax_inst
= 0x8000;
3206 s3_inst
.relax_inst
= 0x8000;
3209 /* sw rD, [rA, simm15] */
3210 else if ((s3_inst
.instruction
& 0x3e000000) == 0x28000000)
3212 /* rD is in [r0 - r15] and ra in [r0-r7] */
3213 if ((((s3_inst
.instruction
>> 15) & 0x18) == 0) && (((s3_inst
.instruction
>> 20) & 0x10) == 0))
3215 /* simm15 =7 bit , sw -> sw!. */
3216 if (((s3_inst
.instruction
& 0x7f80) == 0)&&((s3_inst
.instruction
&0x3)==0))
3218 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>> 15) & 0xf) << 5)
3219 | (((s3_inst
.instruction
>> 20) & 0xf) << 8)|(value
>>2);
3220 s3_inst
.relax_size
= 2;
3222 /* rA = r2, sw -> swp!. */
3225 s3_inst
.relax_inst
= 0x8000;
3230 s3_inst
.relax_inst
= 0x8000;
3233 /* sw rD, [rA, simm15]+ sw pre. */
3234 else if ((s3_inst
.instruction
& 0x3e000007) == 0x06000004)
3236 /* simm15 = -4. and ra==r0 */
3237 if ((((s3_inst
.instruction
>> 15) & 0x1f) == 0)
3238 && (((s3_inst
.instruction
>> 3) & 0xfff) == 0xffc))
3241 s3_inst
.relax_inst
= 0x0060 | ((s3_inst
.instruction
>> 20) & 0x1f);
3242 s3_inst
.relax_size
= 2;
3246 s3_inst
.relax_inst
= 0x8000;
3251 s3_inst
.relax_inst
= 0x8000;
3258 /* FIXME: may set error, for there is no ld/sw rD, [rA, label] */
3259 s3_inst
.reloc
.pc_rel
= 0;
3265 s3_inst
.error
= s3_BAD_ARGS
;
3271 s3_do_cache (char *str
)
3273 s3_skip_whitespace (str
);
3275 if ((s3_data_op2 (&str
, 20, _IMM5
) == (int) s3_FAIL
) || (s3_skip_past_comma (&str
) == (int) s3_FAIL
))
3283 cache_op
= (s3_inst
.instruction
>> 20) & 0x1F;
3284 sprintf (s3_inst
.name
, "cache %d", cache_op
);
3290 s3_skip_whitespace (str
);
3292 if (s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
)
3295 s3_skip_whitespace (str
);
3297 /* cache op, [rA] */
3298 if (s3_skip_past_comma (&str
) == (int) s3_FAIL
)
3300 s3_SET_INSN_ERROR (NULL
);
3303 s3_inst
.error
= _("missing ]");
3308 /* cache op, [rA, simm15] */
3311 if (s3_exp_ldst_offset (&str
, 0, _SIMM15
) == (int) s3_FAIL
)
3316 s3_skip_whitespace (str
);
3319 s3_inst
.error
= _("missing ]");
3324 if (s3_end_of_line (str
) == (int) s3_FAIL
)
3329 s3_inst
.error
= s3_BAD_ARGS
;
3334 s3_do_crdcrscrsimm5 (char *str
)
3339 s3_skip_whitespace (str
);
3341 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE_CR
) == (int) s3_FAIL
3342 || s3_skip_past_comma (&str
) == (int) s3_FAIL
3343 || s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE_CR
) == (int) s3_FAIL
3344 || s3_skip_past_comma (&str
) == (int) s3_FAIL
3345 || s3_reg_required_here (&str
, 10, s3_REG_TYPE_SCORE_CR
) == (int) s3_FAIL
3346 || s3_skip_past_comma (&str
) == (int) s3_FAIL
)
3349 /* cop1 cop_code20. */
3350 if (s3_data_op2 (&str
, 5, _IMM20
) == (int) s3_FAIL
)
3355 if (s3_data_op2 (&str
, 5, _IMM5
) == (int) s3_FAIL
)
3359 s3_end_of_line (str
);
3362 /* Handle ldc/stc. */
3364 s3_do_ldst_cop (char *str
)
3366 s3_skip_whitespace (str
);
3368 if ((s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE_CR
) == (int) s3_FAIL
)
3369 || (s3_skip_past_comma (&str
) == (int) s3_FAIL
))
3375 s3_skip_whitespace (str
);
3377 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
)
3380 s3_skip_whitespace (str
);
3384 if (s3_exp_ldst_offset (&str
, 5, _IMM10_RSHIFT_2
) == (int) s3_FAIL
)
3387 s3_skip_whitespace (str
);
3390 s3_inst
.error
= _("missing ]");
3395 s3_end_of_line (str
);
3398 s3_inst
.error
= s3_BAD_ARGS
;
3402 s3_do16_ldst_insn (char *str
)
3404 int conflict_reg
= 0;
3405 s3_skip_whitespace (str
);
3407 if ((s3_reglow_required_here (&str
, 8) == (int) s3_FAIL
) || (s3_skip_past_comma (&str
) == (int) s3_FAIL
))
3414 s3_skip_whitespace (str
);
3416 if ((conflict_reg
= s3_reglow_required_here (&str
, 5)) == (int) s3_FAIL
)
3418 if (conflict_reg
&0x8)
3420 sprintf (s3_err_msg
, _("invalid register number: %d is not in [r0--r7]"),conflict_reg
);
3421 s3_inst
.error
= s3_err_msg
;
3425 s3_skip_whitespace (str
);
3430 if (s3_end_of_line (str
) == (int) s3_FAIL
)
3435 if (s3_skip_past_comma (&str
) == (int) s3_FAIL
)
3437 s3_inst
.error
= _("comma is expected");
3440 if (s3_my_get_expression (&s3_inst
.reloc
.exp
, &str
) == (int) s3_FAIL
)
3442 s3_skip_whitespace (str
);
3445 s3_inst
.error
= _("missing ]");
3448 if (s3_end_of_line (str
) == (int) s3_FAIL
)
3450 if (s3_inst
.reloc
.exp
.X_op
== O_constant
)
3453 unsigned int data_type
;
3454 data_type
= _IMM5_RSHIFT_2
;
3455 value
= s3_validate_immediate (s3_inst
.reloc
.exp
.X_add_number
, data_type
, 0);
3456 if (value
== (int) s3_FAIL
)
3459 sprintf (s3_err_msg
,
3460 _("invalid constant: %d bit expression not in range %d..%d"),
3461 s3_score_df_range
[data_type
].bits
,
3462 s3_score_df_range
[data_type
].range
[0], s3_score_df_range
[data_type
].range
[1]);
3463 s3_inst
.error
= s3_err_msg
;
3468 sprintf (s3_err_msg
, _("invalid constant: %d is not word align integer"),value
);
3469 s3_inst
.error
= s3_err_msg
;
3474 s3_inst
.instruction
|= value
;
3480 sprintf (s3_err_msg
, _("missing ["));
3481 s3_inst
.error
= s3_err_msg
;
3487 s3_do_lw48 (char *str
)
3489 bfd_signed_vma val
= 0;
3491 s3_skip_whitespace (str
);
3493 if ((s3_reg_required_here (&str
, 37, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
)
3494 || (s3_skip_past_comma (&str
) == (int) s3_FAIL
))
3497 if (s3_my_get_expression (&s3_inst
.reloc
.exp
, &str
) == (int) s3_FAIL
3498 || s3_end_of_line (str
) == (int) s3_FAIL
)
3503 /* Check word align for lw48 rd, value. */
3504 if ((s3_inst
.reloc
.exp
.X_add_symbol
== NULL
)
3505 && ((s3_inst
.reloc
.exp
.X_add_number
& 0x3) != 0))
3507 s3_inst
.error
= _("invalid constant: 32 bit expression not word align");
3511 /* Check and set offset. */
3512 val
= s3_inst
.reloc
.exp
.X_add_number
;
3513 if ((s3_inst
.reloc
.exp
.X_add_symbol
== NULL
)
3514 && (!(val
>= 0 && val
<= 0xffffffffLL
)))
3516 s3_inst
.error
= _("invalid constant: 32 bit expression not in range [0, 0xffffffff]");
3522 s3_inst
.instruction
|= (val
<< 7);
3524 /* Set reloc type. */
3525 s3_inst
.reloc
.type
= BFD_RELOC_SCORE_IMM30
;
3530 s3_do_sw48 (char *str
)
3532 bfd_signed_vma val
= 0;
3534 s3_skip_whitespace (str
);
3536 if ((s3_reg_required_here (&str
, 37, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
)
3537 || (s3_skip_past_comma (&str
) == (int) s3_FAIL
))
3540 if (s3_my_get_expression (&s3_inst
.reloc
.exp
, &str
) == (int) s3_FAIL
3541 || s3_end_of_line (str
) == (int) s3_FAIL
)
3546 /* Check word align for lw48 rd, value. */
3547 if ((s3_inst
.reloc
.exp
.X_add_symbol
== NULL
)
3548 && ((s3_inst
.reloc
.exp
.X_add_number
& 0x3) != 0))
3550 s3_inst
.error
= _("invalid constant: 32 bit expression not word align");
3554 /* Check and set offset. */
3555 val
= s3_inst
.reloc
.exp
.X_add_number
;
3556 if ((s3_inst
.reloc
.exp
.X_add_symbol
== NULL
)
3557 && (!(val
>= 0 && val
<= 0xffffffffLL
)))
3559 s3_inst
.error
= _("invalid constant: 32 bit expression not in range [0, 0xffffffff]");
3565 s3_inst
.instruction
|= (val
<< 7);
3567 /* Set reloc type. */
3568 s3_inst
.reloc
.type
= BFD_RELOC_SCORE_IMM30
;
3572 s3_do_ldi48 (char *str
)
3576 s3_skip_whitespace (str
);
3578 if (s3_reg_required_here (&str
, 37, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
3579 || s3_skip_past_comma (&str
) == (int) s3_FAIL
)
3582 if (s3_my_get_expression (&s3_inst
.reloc
.exp
, &str
) == (int) s3_FAIL
3583 || s3_end_of_line (str
) == (int) s3_FAIL
)
3588 /* Check and set offset. */
3589 val
= s3_inst
.reloc
.exp
.X_add_number
;
3590 if (!(val
>= -0xffffffffLL
&& val
<= 0xffffffffLL
))
3592 s3_inst
.error
= _("invalid constant: 32 bit expression not in range [-0x80000000, 0x7fffffff]");
3597 s3_inst
.instruction
|= (val
<< 5);
3599 /* Set reloc type. */
3600 s3_inst
.reloc
.type
= BFD_RELOC_SCORE_IMM32
;
3604 s3_do_sdbbp48 (char *str
)
3606 s3_skip_whitespace (str
);
3608 if (s3_data_op2 (&str
, 5, _IMM5
) == (int) s3_FAIL
|| s3_end_of_line (str
) == (int) s3_FAIL
)
3613 s3_do_and48 (char *str
)
3615 s3_skip_whitespace (str
);
3617 if (s3_reglow_required_here (&str
, 38) == (int) s3_FAIL
3618 || s3_skip_past_comma (&str
) == (int) s3_FAIL
3619 || s3_reglow_required_here (&str
, 34) == (int) s3_FAIL
3620 || s3_skip_past_comma (&str
) == (int) s3_FAIL
3621 || s3_data_op2 (&str
, 2, _IMM32
) == (int) s3_FAIL
3622 || s3_end_of_line (str
) == (int) s3_FAIL
)
3627 s3_do_or48 (char *str
)
3629 s3_skip_whitespace (str
);
3631 if (s3_reglow_required_here (&str
, 38) == (int) s3_FAIL
3632 || s3_skip_past_comma (&str
) == (int) s3_FAIL
3633 || s3_reglow_required_here (&str
, 34) == (int) s3_FAIL
3634 || s3_skip_past_comma (&str
) == (int) s3_FAIL
3635 || s3_data_op2 (&str
, 2, _IMM32
) == (int) s3_FAIL
3636 || s3_end_of_line (str
) == (int) s3_FAIL
)
3641 s3_do_mbitclr (char *str
)
3644 s3_skip_whitespace (str
);
3648 sprintf (s3_err_msg
, _("missing ["));
3649 s3_inst
.error
= s3_err_msg
;
3654 s3_inst
.instruction
&= 0x0;
3656 if ((s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
)
3657 || (s3_skip_past_comma (&str
) == (int) s3_FAIL
)
3658 || (s3_data_op2 (&str
, 0, _IMM11
) == (int) s3_FAIL
))
3661 /* Get imm11 and refill opcode. */
3662 val
= s3_inst
.instruction
& 0x7ff;
3664 s3_inst
.instruction
&= 0x000f8000;
3665 s3_inst
.instruction
|= 0x00000064;
3669 sprintf (s3_err_msg
, _("missing ]"));
3670 s3_inst
.error
= s3_err_msg
;
3675 if ((s3_skip_past_comma (&str
) == (int) s3_FAIL
)
3676 || (s3_data_op2 (&str
, 10, _IMM5
) == (int) s3_FAIL
))
3679 /* Set imm11 to opcode. */
3680 s3_inst
.instruction
|= (val
& 0x1)
3681 | (((val
>> 1 ) & 0x7) << 7)
3682 | (((val
>> 4 ) & 0x1f) << 20);
3686 s3_do_mbitset (char *str
)
3689 s3_skip_whitespace (str
);
3693 sprintf (s3_err_msg
, _("missing ["));
3694 s3_inst
.error
= s3_err_msg
;
3699 s3_inst
.instruction
&= 0x0;
3701 if ((s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
)
3702 || (s3_skip_past_comma (&str
) == (int) s3_FAIL
)
3703 || (s3_data_op2 (&str
, 0, _IMM11
) == (int) s3_FAIL
))
3706 /* Get imm11 and refill opcode. */
3707 val
= s3_inst
.instruction
& 0x7ff;
3709 s3_inst
.instruction
&= 0x000f8000;
3710 s3_inst
.instruction
|= 0x0000006c;
3714 sprintf (s3_err_msg
, _("missing ]"));
3715 s3_inst
.error
= s3_err_msg
;
3720 if ((s3_skip_past_comma (&str
) == (int) s3_FAIL
)
3721 || (s3_data_op2 (&str
, 10, _IMM5
) == (int) s3_FAIL
))
3724 /* Set imm11 to opcode. */
3725 s3_inst
.instruction
|= (val
& 0x1)
3726 | (((val
>> 1 ) & 0x7) << 7)
3727 | (((val
>> 4 ) & 0x1f) << 20);
3731 s3_do16_slli_srli (char *str
)
3733 s3_skip_whitespace (str
);
3735 if ((s3_reglow_required_here (&str
, 5) == (int) s3_FAIL
)
3736 || (s3_skip_past_comma (&str
) == (int) s3_FAIL
)
3737 || s3_data_op2 (&str
, 0, _IMM5
) == (int) s3_FAIL
3738 || s3_end_of_line (str
) == (int) s3_FAIL
)
3743 s3_do16_ldiu (char *str
)
3745 s3_skip_whitespace (str
);
3747 if ((s3_reg_required_here (&str
, 5,s3_REG_TYPE_SCORE
) == (int) s3_FAIL
)
3748 || (s3_skip_past_comma (&str
) == (int) s3_FAIL
)
3749 || s3_data_op2 (&str
, 0, _IMM5
) == (int) s3_FAIL
3750 || s3_end_of_line (str
) == (int) s3_FAIL
)
3755 s3_do16_push_pop (char *str
)
3757 s3_skip_whitespace (str
);
3758 if ((s3_reg_required_here (&str
, 0, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
3759 || s3_end_of_line (str
) == (int) s3_FAIL
)
3764 s3_do16_rpush (char *str
)
3768 s3_skip_whitespace (str
);
3769 if ((reg
= (s3_reg_required_here (&str
, 5, s3_REG_TYPE_SCORE
))) == (int) s3_FAIL
3770 || s3_skip_past_comma (&str
) == (int) s3_FAIL
3771 || s3_data_op2 (&str
, 0, _IMM5_MULTI_LOAD
) == (int) s3_FAIL
3772 || s3_end_of_line (str
) == (int) s3_FAIL
)
3777 2: to 31: normal value. */
3778 val
= s3_inst
.instruction
& 0x1f;
3781 s3_inst
.error
= _("imm5 should >= 2");
3786 s3_inst
.error
= _("reg should <= 31");
3792 s3_do16_rpop (char *str
)
3796 s3_skip_whitespace (str
);
3797 if ((reg
= (s3_reg_required_here (&str
, 5, s3_REG_TYPE_SCORE
))) == (int) s3_FAIL
3798 || s3_skip_past_comma (&str
) == (int) s3_FAIL
3799 || s3_data_op2 (&str
, 0, _IMM5_MULTI_LOAD
) == (int) s3_FAIL
3800 || s3_end_of_line (str
) == (int) s3_FAIL
)
3805 2: to 31: normal value. */
3806 val
= s3_inst
.instruction
& 0x1f;
3809 s3_inst
.error
= _("imm5 should >= 2");
3815 s3_inst
.error
= _("reg should <= 31");
3820 if ((reg
+ val
) <= 32)
3821 reg
= reg
+ val
- 1;
3823 reg
= reg
+ val
- 33;
3824 s3_inst
.instruction
&= 0x7c1f;
3825 s3_inst
.instruction
|= (reg
<< 5);
3830 /* Handle lcb/lcw/lce/scb/scw/sce. */
3832 s3_do_ldst_unalign (char *str
)
3836 if (s3_university_version
== 1)
3838 s3_inst
.error
= s3_ERR_FOR_SCORE5U_ATOMIC
;
3842 s3_skip_whitespace (str
);
3844 /* lcb/scb [rA]+. */
3848 s3_skip_whitespace (str
);
3850 if (s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
)
3857 s3_inst
.error
= _("missing +");
3863 s3_inst
.error
= _("missing ]");
3867 if (s3_end_of_line (str
) == (int) s3_FAIL
)
3870 /* lcw/lce/scb/sce rD, [rA]+. */
3873 if (((conflict_reg
= s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
)
3874 || (s3_skip_past_comma (&str
) == (int) s3_FAIL
))
3879 s3_skip_whitespace (str
);
3884 s3_skip_whitespace (str
);
3885 if ((reg
= s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
)
3890 /* Conflicts can occur on stores as well as loads. */
3891 conflict_reg
= (conflict_reg
== reg
);
3892 s3_skip_whitespace (str
);
3895 unsigned int ldst_func
= s3_inst
.instruction
& LDST_UNALIGN_MASK
;
3901 as_warn (_("%s register same as write-back base"),
3902 ((ldst_func
& UA_LCE
) || (ldst_func
& UA_LCW
)
3903 ? _("destination") : _("source")));
3908 s3_inst
.error
= _("missing +");
3912 if (s3_end_of_line (str
) == (int) s3_FAIL
)
3917 s3_inst
.error
= _("missing ]");
3923 s3_inst
.error
= s3_BAD_ARGS
;
3929 /* Handle alw/asw. */
3931 s3_do_ldst_atomic (char *str
)
3933 if (s3_university_version
== 1)
3935 s3_inst
.error
= s3_ERR_FOR_SCORE5U_ATOMIC
;
3939 s3_skip_whitespace (str
);
3941 if ((s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
)
3942 || (s3_skip_past_comma (&str
) == (int) s3_FAIL
))
3949 s3_skip_whitespace (str
);
3954 s3_skip_whitespace (str
);
3955 if ((reg
= s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
)
3960 s3_skip_whitespace (str
);
3963 s3_inst
.error
= _("missing ]");
3967 s3_end_of_line (str
);
3970 s3_inst
.error
= s3_BAD_ARGS
;
3975 s3_build_relax_frag (struct s3_score_it fix_insts
[s3_RELAX_INST_NUM
], int fix_num ATTRIBUTE_UNUSED
,
3976 struct s3_score_it var_insts
[s3_RELAX_INST_NUM
], int var_num
,
3977 symbolS
*add_symbol
)
3982 fixS
*cur_fixp
= NULL
;
3984 struct s3_score_it inst_main
;
3986 memcpy (&inst_main
, &fix_insts
[0], sizeof (struct s3_score_it
));
3988 /* Adjust instruction opcode and to be relaxed instruction opcode. */
3989 inst_main
.instruction
= s3_adjust_paritybit (inst_main
.instruction
, s3_GET_INSN_CLASS (inst_main
.type
));
3990 inst_main
.type
= Insn_PIC
;
3992 for (i
= 0; i
< var_num
; i
++)
3994 inst_main
.relax_size
+= var_insts
[i
].size
;
3995 var_insts
[i
].instruction
= s3_adjust_paritybit (var_insts
[i
].instruction
,
3996 s3_GET_INSN_CLASS (var_insts
[i
].type
));
3999 /* Check data dependency. */
4000 s3_handle_dependency (&inst_main
);
4002 /* Start a new frag if frag_now is not empty. */
4003 if (frag_now_fix () != 0)
4005 if (!frag_now
->tc_frag_data
.is_insn
)
4007 frag_wane (frag_now
);
4013 /* Write fr_fix part. */
4014 p
= frag_more (inst_main
.size
);
4015 s3_md_number_to_chars (p
, inst_main
.instruction
, inst_main
.size
);
4017 if (inst_main
.reloc
.type
!= BFD_RELOC_NONE
)
4018 fixp
= s3_fix_new_score (frag_now
, p
- frag_now
->fr_literal
, inst_main
.size
,
4019 &inst_main
.reloc
.exp
, inst_main
.reloc
.pc_rel
, inst_main
.reloc
.type
);
4021 frag_now
->tc_frag_data
.fixp
= fixp
;
4022 cur_fixp
= frag_now
->tc_frag_data
.fixp
;
4025 dwarf2_emit_insn (inst_main
.size
);
4028 where
= p
- frag_now
->fr_literal
+ inst_main
.size
;
4029 for (i
= 0; i
< var_num
; i
++)
4032 where
+= var_insts
[i
- 1].size
;
4034 if (var_insts
[i
].reloc
.type
!= BFD_RELOC_NONE
)
4036 fixp
= s3_fix_new_score (frag_now
, where
, var_insts
[i
].size
,
4037 &var_insts
[i
].reloc
.exp
, var_insts
[i
].reloc
.pc_rel
,
4038 var_insts
[i
].reloc
.type
);
4043 cur_fixp
->fx_next
= fixp
;
4044 cur_fixp
= cur_fixp
->fx_next
;
4048 frag_now
->tc_frag_data
.fixp
= fixp
;
4049 cur_fixp
= frag_now
->tc_frag_data
.fixp
;
4055 p
= frag_var (rs_machine_dependent
, inst_main
.relax_size
+ s3_RELAX_PAD_BYTE
, 0,
4056 s3_RELAX_ENCODE (inst_main
.size
, inst_main
.relax_size
, inst_main
.type
,
4057 0, inst_main
.size
, 0), add_symbol
, 0, NULL
);
4059 /* Write fr_var part.
4060 no calling s3_gen_insn_frag, no fixS will be generated. */
4061 for (i
= 0; i
< var_num
; i
++)
4063 s3_md_number_to_chars (p
, var_insts
[i
].instruction
, var_insts
[i
].size
);
4064 p
+= var_insts
[i
].size
;
4066 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4070 /* Build a relax frag for la instruction when generating s3_PIC,
4071 external symbol first and local symbol second. */
4073 s3_build_la_pic (int reg_rd
, expressionS exp
)
4075 symbolS
*add_symbol
= exp
.X_add_symbol
;
4076 offsetT add_number
= exp
.X_add_number
;
4077 struct s3_score_it fix_insts
[s3_RELAX_INST_NUM
];
4078 struct s3_score_it var_insts
[s3_RELAX_INST_NUM
];
4081 char tmp
[s3_MAX_LITERAL_POOL_SIZE
];
4087 if (add_number
== 0)
4092 /* For an external symbol, only one insn is generated;
4093 For a local symbol, two insns are generated. */
4095 For an external symbol: lw rD, <sym>($gp)
4096 (BFD_RELOC_SCORE_GOT15 or BFD_RELOC_SCORE_CALL15) */
4097 sprintf (tmp
, "lw_pic r%d, %s", reg_rd
, S_GET_NAME (add_symbol
));
4098 if (s3_append_insn (tmp
, false) == (int) s3_FAIL
)
4101 if (reg_rd
== s3_PIC_CALL_REG
)
4102 s3_inst
.reloc
.type
= BFD_RELOC_SCORE_CALL15
;
4103 memcpy (&fix_insts
[0], &s3_inst
, sizeof (struct s3_score_it
));
4106 For a local symbol :
4107 lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15)
4108 addi rD, <sym> (BFD_RELOC_GOT_LO16) */
4109 s3_inst
.reloc
.type
= BFD_RELOC_SCORE_GOT15
;
4110 memcpy (&var_insts
[0], &s3_inst
, sizeof (struct s3_score_it
));
4111 sprintf (tmp
, "addi_s_pic r%d, %s", reg_rd
, S_GET_NAME (add_symbol
));
4112 if (s3_append_insn (tmp
, false) == (int) s3_FAIL
)
4115 memcpy (&var_insts
[1], &s3_inst
, sizeof (struct s3_score_it
));
4116 s3_build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
4118 else if (add_number
>= -0x8000 && add_number
<= 0x7fff)
4120 /* Insn 1: lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15) */
4121 sprintf (tmp
, "lw_pic r%d, %s", reg_rd
, S_GET_NAME (add_symbol
));
4122 if (s3_append_insn (tmp
, true) == (int) s3_FAIL
)
4129 For an external symbol: addi rD, <constant> */
4130 sprintf (tmp
, "addi r%d, %d", reg_rd
, (int)add_number
);
4131 if (s3_append_insn (tmp
, false) == (int) s3_FAIL
)
4134 memcpy (&fix_insts
[0], &s3_inst
, sizeof (struct s3_score_it
));
4137 For a local symbol: addi rD, <sym>+<constant> (BFD_RELOC_GOT_LO16) */
4138 sprintf (tmp
, "addi_s_pic r%d, %s + %d", reg_rd
,
4139 S_GET_NAME (add_symbol
), (int) add_number
);
4140 if (s3_append_insn (tmp
, false) == (int) s3_FAIL
)
4143 memcpy (&var_insts
[0], &s3_inst
, sizeof (struct s3_score_it
));
4144 s3_build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
4148 int hi
= (add_number
>> 16) & 0x0000FFFF;
4149 int lo
= add_number
& 0x0000FFFF;
4151 /* Insn 1: lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15) */
4152 sprintf (tmp
, "lw_pic r%d, %s", reg_rd
, S_GET_NAME (add_symbol
));
4153 if (s3_append_insn (tmp
, true) == (int) s3_FAIL
)
4160 For an external symbol: ldis r1, HI%<constant> */
4161 sprintf (tmp
, "ldis r1, %d", hi
);
4162 if (s3_append_insn (tmp
, false) == (int) s3_FAIL
)
4165 memcpy (&fix_insts
[0], &s3_inst
, sizeof (struct s3_score_it
));
4168 For a local symbol: ldis r1, HI%<constant>
4169 but, if lo is out of 16 bit, make hi plus 1 */
4170 if ((lo
< -0x8000) || (lo
> 0x7fff))
4174 sprintf (tmp
, "ldis_pic r1, %d", hi
);
4175 if (s3_append_insn (tmp
, false) == (int) s3_FAIL
)
4178 memcpy (&var_insts
[0], &s3_inst
, sizeof (struct s3_score_it
));
4179 s3_build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
4185 For an external symbol: ori r1, LO%<constant> */
4186 sprintf (tmp
, "ori r1, %d", lo
);
4187 if (s3_append_insn (tmp
, false) == (int) s3_FAIL
)
4190 memcpy (&fix_insts
[0], &s3_inst
, sizeof (struct s3_score_it
));
4193 For a local symbol: addi r1, <sym>+LO%<constant> (BFD_RELOC_GOT_LO16) */
4194 sprintf (tmp
, "addi_u_pic r1, %s + %d", S_GET_NAME (add_symbol
), lo
);
4195 if (s3_append_insn (tmp
, false) == (int) s3_FAIL
)
4198 memcpy (&var_insts
[0], &s3_inst
, sizeof (struct s3_score_it
));
4199 s3_build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
4201 /* Insn 4: add rD, rD, r1 */
4202 sprintf (tmp
, "add r%d, r%d, r1", reg_rd
, reg_rd
);
4203 if (s3_append_insn (tmp
, true) == (int) s3_FAIL
)
4206 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4215 s3_do_macro_la_rdi32 (char *str
)
4219 s3_skip_whitespace (str
);
4220 if ((reg_rd
= s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
4221 || s3_skip_past_comma (&str
) == (int) s3_FAIL
)
4228 char *keep_data
= str
;
4229 char append_str
[s3_MAX_LITERAL_POOL_SIZE
];
4231 /* Check immediate value. */
4232 if (s3_my_get_expression (&s3_inst
.reloc
.exp
, &str
) == (int) s3_FAIL
)
4234 s3_inst
.error
= _("expression error");
4237 else if ((s3_inst
.reloc
.exp
.X_add_symbol
== NULL
)
4238 && (s3_validate_immediate (s3_inst
.reloc
.exp
.X_add_number
, _IMM32
, 0) == (int) s3_FAIL
))
4240 s3_inst
.error
= _("value not in range [0, 0xffffffff]");
4247 /* la rd, simm16. */
4248 if (s3_data_op2 (&str
, 1, _SIMM16_LA
) != (int) s3_FAIL
)
4250 s3_end_of_line (str
);
4253 /* la rd, imm32 or la rd, label. */
4256 s3_SET_INSN_ERROR (NULL
);
4259 if ((s3_data_op2 (&str
, 1, _VALUE_HI16
) == (int) s3_FAIL
)
4260 || (s3_end_of_line (str
) == (int) s3_FAIL
))
4266 if ((s3_score_pic
== s3_NO_PIC
) || (!s3_inst
.reloc
.exp
.X_add_symbol
))
4268 sprintf (append_str
, "ld_i32hi r%d, %s", reg_rd
, keep_data
);
4269 if (s3_append_insn (append_str
, true) == (int) s3_FAIL
)
4272 sprintf (append_str
, "ld_i32lo r%d, %s", reg_rd
, keep_data
);
4273 if (s3_append_insn (append_str
, true) == (int) s3_FAIL
)
4278 gas_assert (s3_inst
.reloc
.exp
.X_add_symbol
);
4279 s3_build_la_pic (reg_rd
, s3_inst
.reloc
.exp
);
4282 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4291 s3_do_macro_li_rdi32 (char *str
)
4296 s3_skip_whitespace (str
);
4297 if ((reg_rd
= s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
4298 || s3_skip_past_comma (&str
) == (int) s3_FAIL
)
4305 char *keep_data
= str
;
4307 /* Check immediate value. */
4308 if (s3_my_get_expression (&s3_inst
.reloc
.exp
, &str
) == (int) s3_FAIL
)
4310 s3_inst
.error
= _("expression error");
4313 else if (!(s3_inst
.reloc
.exp
.X_add_number
>= -0xffffffffLL
4314 && s3_inst
.reloc
.exp
.X_add_number
<= 0xffffffffLL
))
4316 s3_inst
.error
= _("value not in range [-0xffffffff, 0xffffffff]");
4323 /* li rd, simm16. */
4324 if (s3_data_op2 (&str
, 1, _SIMM16_LA
) != (int) s3_FAIL
)
4326 s3_end_of_line (str
);
4332 char append_str
[s3_MAX_LITERAL_POOL_SIZE
];
4337 if ((s3_data_op2 (&str
, 1, _VALUE_HI16
) == (int) s3_FAIL
)
4338 || (s3_end_of_line (str
) == (int) s3_FAIL
))
4342 else if (s3_inst
.reloc
.exp
.X_add_symbol
)
4344 s3_inst
.error
= _("li rd label isn't correct instruction form");
4349 sprintf (append_str
, "ld_i32hi r%d, %s", reg_rd
, keep_data
);
4351 if (s3_append_insn (append_str
, true) == (int) s3_FAIL
)
4355 sprintf (append_str
, "ld_i32lo r%d, %s", reg_rd
, keep_data
);
4356 if (s3_append_insn (append_str
, true) == (int) s3_FAIL
)
4359 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4367 /* Handle mul/mulu/div/divu/rem/remu. */
4369 s3_do_macro_mul_rdrsrs (char *str
)
4375 char append_str
[s3_MAX_LITERAL_POOL_SIZE
];
4377 if (s3_university_version
== 1)
4378 as_warn ("%s", s3_ERR_FOR_SCORE5U_MUL_DIV
);
4380 strcpy (append_str
, str
);
4381 backupstr
= append_str
;
4382 s3_skip_whitespace (backupstr
);
4383 if (((reg_rd
= s3_reg_required_here (&backupstr
, -1, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
)
4384 || (s3_skip_past_comma (&backupstr
) == (int) s3_FAIL
)
4385 || ((reg_rs1
= s3_reg_required_here (&backupstr
, -1, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
))
4387 s3_inst
.error
= s3_BAD_ARGS
;
4391 if (s3_skip_past_comma (&backupstr
) == (int) s3_FAIL
)
4393 /* rem/remu rA, rB is error format. */
4394 if (strcmp (s3_inst
.name
, "rem") == 0 || strcmp (s3_inst
.name
, "remu") == 0)
4396 s3_SET_INSN_ERROR (s3_BAD_ARGS
);
4400 s3_SET_INSN_ERROR (NULL
);
4407 s3_SET_INSN_ERROR (NULL
);
4408 if (((reg_rs2
= s3_reg_required_here (&backupstr
, -1, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
)
4409 || (s3_end_of_line (backupstr
) == (int) s3_FAIL
))
4415 char append_str1
[s3_MAX_LITERAL_POOL_SIZE
];
4417 if (strcmp (s3_inst
.name
, "rem") == 0)
4419 sprintf (append_str
, "mul r%d, r%d", reg_rs1
, reg_rs2
);
4420 sprintf (append_str1
, "mfceh r%d", reg_rd
);
4422 else if (strcmp (s3_inst
.name
, "remu") == 0)
4424 sprintf (append_str
, "mulu r%d, r%d", reg_rs1
, reg_rs2
);
4425 sprintf (append_str1
, "mfceh r%d", reg_rd
);
4429 sprintf (append_str
, "%s r%d, r%d", s3_inst
.name
, reg_rs1
, reg_rs2
);
4430 sprintf (append_str1
, "mfcel r%d", reg_rd
);
4433 /* Output mul/mulu or div/divu or rem/remu. */
4434 if (s3_append_insn (append_str
, true) == (int) s3_FAIL
)
4437 /* Output mfcel or mfceh. */
4438 if (s3_append_insn (append_str1
, true) == (int) s3_FAIL
)
4441 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4448 s3_exp_macro_ldst_abs (char *str
)
4451 char *backupstr
, *tmp
;
4452 char append_str
[s3_MAX_LITERAL_POOL_SIZE
];
4453 char verifystr
[s3_MAX_LITERAL_POOL_SIZE
];
4454 struct s3_score_it inst_backup
;
4459 memcpy (&inst_backup
, &s3_inst
, sizeof (struct s3_score_it
));
4461 strcpy (verifystr
, str
);
4462 backupstr
= verifystr
;
4463 s3_skip_whitespace (backupstr
);
4464 if ((reg_rd
= s3_reg_required_here (&backupstr
, -1, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
)
4468 if (s3_skip_past_comma (&backupstr
) == (int) s3_FAIL
)
4472 sprintf (append_str
, "li r1 %s", backupstr
);
4473 s3_append_insn (append_str
, true);
4475 memcpy (&s3_inst
, &inst_backup
, sizeof (struct s3_score_it
));
4476 sprintf (append_str
, " r%d, [r1,0]", reg_rd
);
4477 s3_do_ldst_insn (append_str
);
4482 /* Handle bcmpeq / bcmpne */
4484 s3_do_macro_bcmp (char *str
)
4488 size_t keep_data_size
;
4490 struct s3_score_it inst_expand
[2];
4491 struct s3_score_it inst_main
;
4493 memset (inst_expand
, 0, sizeof inst_expand
);
4494 s3_skip_whitespace (str
);
4495 if (( reg_a
= s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
4496 || s3_skip_past_comma (&str
) == (int) s3_FAIL
4497 ||(reg_b
= s3_reg_required_here (&str
, 10, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
4498 || s3_skip_past_comma (&str
) == (int) s3_FAIL
)
4501 keep_data_size
= strlen (str
) + 1;
4502 keep_data
= xmalloc (keep_data_size
* 2 + 14);
4503 memcpy (keep_data
, str
, keep_data_size
);
4505 if (s3_my_get_expression (&s3_inst
.reloc
.exp
, &str
) == (int) s3_FAIL
4507 || s3_end_of_line (str
) == (int) s3_FAIL
)
4509 else if (s3_inst
.reloc
.exp
.X_add_symbol
== 0)
4511 s3_inst
.error
= _("lacking label ");
4516 char *append_str
= keep_data
+ keep_data_size
;
4517 s3_SET_INSN_ERROR (NULL
);
4519 s3_inst
.reloc
.type
= BFD_RELOC_SCORE_BCMP
;
4520 s3_inst
.reloc
.pc_rel
= 1;
4521 bfd_signed_vma val
= s3_inst
.reloc
.exp
.X_add_number
;
4523 /* Branch 32 offset field : 20 bit, 16 bit branch offset field : 8 bit. */
4524 s3_inst
.instruction
|= ((s3_inst
.reloc
.exp
.X_add_number
>> 1) & 0x1)
4525 | ((s3_inst
.reloc
.exp
.X_add_number
>> 2) & 0x7) << 7
4526 | ((s3_inst
.reloc
.exp
.X_add_number
>> 5) & 0x1f) << 20;
4528 /* Check and set offset. */
4529 if (((val
& 0xfffffe00) != 0)
4530 && ((val
& 0xfffffe00) != 0xfffffe00))
4532 /* support bcmp --> cmp!+beq (bne) */
4533 if (s3_score_pic
== s3_NO_PIC
)
4535 sprintf (append_str
, "cmp! r%d, r%d", reg_a
, reg_b
);
4536 if (s3_append_insn (append_str
, true) == (int) s3_FAIL
)
4538 if ((inst_main
.instruction
& 0x3e00007e) == 0x0000004c)
4539 memcpy (append_str
, "beq ", 4);
4541 memcpy (append_str
, "bne ", 4);
4542 memmove (append_str
+ 4, keep_data
, strlen (keep_data
) + 1);
4543 if (s3_append_insn (append_str
, true) == (int) s3_FAIL
)
4548 gas_assert (s3_inst
.reloc
.exp
.X_add_symbol
);
4550 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4557 s3_inst
.instruction
|= (val
& 0x1)
4558 | (((val
>> 1) & 0x7) << 7)
4559 | (((val
>> 4) & 0x1f) << 20);
4562 /* Backup s3_inst. */
4563 memcpy (&inst_main
, &s3_inst
, sizeof (struct s3_score_it
));
4565 if (s3_score_pic
== s3_NO_PIC
)
4567 sprintf (append_str
, "cmp! r%d, r%d", reg_a
, reg_b
);
4568 if (s3_append_insn (append_str
, false) == (int) s3_FAIL
)
4570 memcpy (&inst_expand
[0], &s3_inst
, sizeof (struct s3_score_it
));
4572 if ((inst_main
.instruction
& 0x3e00007e) == 0x0000004c)
4573 memcpy (append_str
, "beq ", 4);
4575 memcpy (append_str
, "bne ", 4);
4576 memmove (append_str
+ 4, keep_data
, strlen (keep_data
) + 1);
4577 if (s3_append_insn (append_str
, false) == (int) s3_FAIL
)
4579 memcpy (&inst_expand
[1], &s3_inst
, sizeof (struct s3_score_it
));
4583 gas_assert (s3_inst
.reloc
.exp
.X_add_symbol
);
4585 inst_main
.relax_size
= inst_expand
[0].size
+ inst_expand
[1].size
;
4586 inst_main
.type
= Insn_BCMP
;
4588 /* Adjust instruction opcode and to be relaxed instruction opcode. */
4589 inst_main
.instruction
= s3_adjust_paritybit (inst_main
.instruction
, s3_GET_INSN_CLASS (inst_main
.type
));
4591 for (i
= 0; i
< 2; i
++)
4592 inst_expand
[i
].instruction
= s3_adjust_paritybit (inst_expand
[i
].instruction
,
4593 s3_GET_INSN_CLASS (inst_expand
[i
].type
));
4594 /* Check data dependency. */
4595 s3_handle_dependency (&inst_main
);
4596 /* Start a new frag if frag_now is not empty. */
4597 if (frag_now_fix () != 0)
4599 if (!frag_now
->tc_frag_data
.is_insn
)
4600 frag_wane (frag_now
);
4605 /* Write fr_fix part. */
4607 p
= frag_more (inst_main
.size
);
4608 s3_md_number_to_chars (p
, inst_main
.instruction
, inst_main
.size
);
4610 if (inst_main
.reloc
.type
!= BFD_RELOC_NONE
)
4612 s3_fix_new_score (frag_now
, p
- frag_now
->fr_literal
, inst_main
.size
,
4613 &inst_main
.reloc
.exp
, inst_main
.reloc
.pc_rel
, inst_main
.reloc
.type
);
4616 dwarf2_emit_insn (inst_main
.size
);
4619 /* s3_GP instruction can not do optimization, only can do relax between
4620 1 instruction and 3 instructions. */
4621 p
= frag_var (rs_machine_dependent
, inst_main
.relax_size
+ s3_RELAX_PAD_BYTE
, 0,
4622 s3_RELAX_ENCODE (inst_main
.size
, inst_main
.relax_size
, inst_main
.type
, 0, 4, 1),
4623 inst_main
.reloc
.exp
.X_add_symbol
, 0, NULL
);
4625 /* Write fr_var part.
4626 no calling s3_gen_insn_frag, no fixS will be generated. */
4627 s3_md_number_to_chars (p
, inst_expand
[0].instruction
, inst_expand
[0].size
);
4628 p
+= inst_expand
[0].size
;
4629 s3_md_number_to_chars (p
, inst_expand
[1].instruction
, inst_expand
[1].size
);
4630 p
+= inst_expand
[1].size
;
4632 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4639 /* Handle bcmpeqz / bcmpnez */
4641 s3_do_macro_bcmpz (char *str
)
4645 size_t keep_data_size
;
4647 struct s3_score_it inst_expand
[2];
4648 struct s3_score_it inst_main
;
4650 memset (inst_expand
, 0, sizeof inst_expand
);
4651 s3_skip_whitespace (str
);
4652 if (( reg_a
= s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
4653 || s3_skip_past_comma (&str
) == (int) s3_FAIL
)
4656 keep_data_size
= strlen (str
) + 1;
4657 keep_data
= xmalloc (keep_data_size
* 2 + 13);
4658 memcpy (keep_data
, str
, keep_data_size
);
4660 if (s3_my_get_expression (&s3_inst
.reloc
.exp
, &str
) == (int) s3_FAIL
4661 || s3_end_of_line (str
) == (int) s3_FAIL
)
4663 else if (s3_inst
.reloc
.exp
.X_add_symbol
== 0)
4665 s3_inst
.error
= _("lacking label ");
4670 char *append_str
= keep_data
+ keep_data_size
;
4671 s3_SET_INSN_ERROR (NULL
);
4672 s3_inst
.reloc
.type
= BFD_RELOC_SCORE_BCMP
;
4673 s3_inst
.reloc
.pc_rel
= 1;
4674 bfd_signed_vma val
= s3_inst
.reloc
.exp
.X_add_number
;
4676 /* Branch 32 offset field : 20 bit, 16 bit branch offset field : 8 bit. */
4677 s3_inst
.instruction
|= ((s3_inst
.reloc
.exp
.X_add_number
>>1) & 0x1) | ((s3_inst
.reloc
.exp
.X_add_number
>>2) & 0x7)<<7 |((s3_inst
.reloc
.exp
.X_add_number
>>5) & 0x1f)<<20;
4679 /* Check and set offset. */
4680 if (((val
& 0xfffffe00) != 0)
4681 && ((val
& 0xfffffe00) != 0xfffffe00))
4683 if (s3_score_pic
== s3_NO_PIC
)
4685 sprintf (append_str
, "cmpi! r%d, 0", reg_a
);
4686 if (s3_append_insn (append_str
, true) == (int) s3_FAIL
)
4688 if ((inst_main
.instruction
& 0x3e00007e) == 0x0000004c)
4689 memcpy (append_str
, "beq ", 4);
4691 memcpy (append_str
, "bne ", 4);
4692 memmove (append_str
+ 4, keep_data
, strlen (keep_data
) + 1);
4693 if (s3_append_insn (append_str
, true) == (int) s3_FAIL
)
4698 gas_assert (s3_inst
.reloc
.exp
.X_add_symbol
);
4700 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4707 s3_inst
.instruction
|= (val
& 0x1)
4708 | (((val
>> 1) & 0x7) << 7)
4709 | (((val
>> 4) & 0x1f) << 20);
4712 /* Backup s3_inst. */
4713 memcpy (&inst_main
, &s3_inst
, sizeof (struct s3_score_it
));
4715 if (s3_score_pic
== s3_NO_PIC
)
4717 sprintf (append_str
, "cmpi! r%d, 0", reg_a
);
4718 if (s3_append_insn (append_str
, false) == (int) s3_FAIL
)
4720 memcpy (&inst_expand
[0], &s3_inst
, sizeof (struct s3_score_it
));
4721 if ((inst_main
.instruction
& 0x3e00007e) == 0x0000004c)
4722 memcpy (append_str
, "beq ", 4);
4724 memcpy (append_str
, "bne ", 4);
4725 memmove (append_str
+ 4, keep_data
, strlen (keep_data
) + 1);
4726 if (s3_append_insn (append_str
, false) == (int) s3_FAIL
)
4728 memcpy (&inst_expand
[1], &s3_inst
, sizeof (struct s3_score_it
));
4732 gas_assert (s3_inst
.reloc
.exp
.X_add_symbol
);
4734 inst_main
.relax_size
= inst_expand
[0].size
+ inst_expand
[1].size
;
4735 inst_main
.type
= Insn_BCMP
;
4737 /* Adjust instruction opcode and to be relaxed instruction opcode. */
4738 inst_main
.instruction
= s3_adjust_paritybit (inst_main
.instruction
, s3_GET_INSN_CLASS (inst_main
.type
));
4740 for (i
= 0; i
< 2; i
++)
4741 inst_expand
[i
].instruction
= s3_adjust_paritybit (inst_expand
[i
].instruction
,
4742 s3_GET_INSN_CLASS (inst_expand
[i
].type
));
4743 /* Check data dependency. */
4744 s3_handle_dependency (&inst_main
);
4745 /* Start a new frag if frag_now is not empty. */
4746 if (frag_now_fix () != 0)
4748 if (!frag_now
->tc_frag_data
.is_insn
)
4749 frag_wane (frag_now
);
4754 /* Write fr_fix part. */
4756 p
= frag_more (inst_main
.size
);
4757 s3_md_number_to_chars (p
, inst_main
.instruction
, inst_main
.size
);
4759 if (inst_main
.reloc
.type
!= BFD_RELOC_NONE
)
4761 s3_fix_new_score (frag_now
, p
- frag_now
->fr_literal
, inst_main
.size
,
4762 &inst_main
.reloc
.exp
, inst_main
.reloc
.pc_rel
, inst_main
.reloc
.type
);
4765 dwarf2_emit_insn (inst_main
.size
);
4768 /* s3_GP instruction can not do optimization, only can do relax between
4769 1 instruction and 3 instructions. */
4770 p
= frag_var (rs_machine_dependent
, inst_main
.relax_size
+ s3_RELAX_PAD_BYTE
, 0,
4771 s3_RELAX_ENCODE (inst_main
.size
, inst_main
.relax_size
, inst_main
.type
, 0, 4, 1),
4772 inst_main
.reloc
.exp
.X_add_symbol
, 0, NULL
);
4774 /* Write fr_var part.
4775 no calling s3_gen_insn_frag, no fixS will be generated. */
4776 s3_md_number_to_chars (p
, inst_expand
[0].instruction
, inst_expand
[0].size
);
4777 p
+= inst_expand
[0].size
;
4778 s3_md_number_to_chars (p
, inst_expand
[1].instruction
, inst_expand
[1].size
);
4779 p
+= inst_expand
[1].size
;
4781 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4789 s3_nopic_need_relax (symbolS
* sym
, int before_relaxing
)
4793 else if (s3_USE_GLOBAL_POINTER_OPT
&& s3_g_switch_value
> 0)
4795 const char *symname
;
4796 const char *segname
;
4798 /* Find out whether this symbol can be referenced off the $gp
4799 register. It can be if it is smaller than the -G size or if
4800 it is in the .sdata or .sbss section. Certain symbols can
4801 not be referenced off the $gp, although it appears as though
4803 symname
= S_GET_NAME (sym
);
4804 if (symname
!= (const char *)NULL
4805 && (strcmp (symname
, "eprol") == 0
4806 || strcmp (symname
, "etext") == 0
4807 || strcmp (symname
, "_gp") == 0
4808 || strcmp (symname
, "edata") == 0
4809 || strcmp (symname
, "_fbss") == 0
4810 || strcmp (symname
, "_fdata") == 0
4811 || strcmp (symname
, "_ftext") == 0
4812 || strcmp (symname
, "end") == 0
4813 || strcmp (symname
, GP_DISP_LABEL
) == 0))
4817 else if ((!S_IS_DEFINED (sym
) || S_IS_COMMON (sym
)) && (0
4818 /* We must defer this decision until after the whole file has been read,
4819 since there might be a .extern after the first use of this symbol. */
4821 && S_GET_VALUE (sym
) == 0)
4822 || (S_GET_VALUE (sym
) != 0
4823 && S_GET_VALUE (sym
) <= s3_g_switch_value
)))
4828 segname
= segment_name (S_GET_SEGMENT (sym
));
4829 return (strcmp (segname
, ".sdata") != 0
4830 && strcmp (segname
, ".sbss") != 0
4831 && !startswith (segname
, ".sdata.")
4832 && !startswith (segname
, ".gnu.linkonce.s."));
4834 /* We are not optimizing for the $gp register. */
4839 /* Build a relax frag for lw/st instruction when generating s3_PIC,
4840 external symbol first and local symbol second. */
4842 s3_build_lwst_pic (int reg_rd
, expressionS exp
, const char *insn_name
)
4844 symbolS
*add_symbol
= exp
.X_add_symbol
;
4845 int add_number
= exp
.X_add_number
;
4846 struct s3_score_it fix_insts
[s3_RELAX_INST_NUM
];
4847 struct s3_score_it var_insts
[s3_RELAX_INST_NUM
];
4850 char tmp
[s3_MAX_LITERAL_POOL_SIZE
];
4856 if ((add_number
== 0) || (add_number
>= -0x8000 && add_number
<= 0x7fff))
4861 /* For an external symbol, two insns are generated;
4862 For a local symbol, three insns are generated. */
4864 For an external symbol: lw rD, <sym>($gp)
4865 (BFD_RELOC_SCORE_GOT15) */
4866 sprintf (tmp
, "lw_pic r1, %s", S_GET_NAME (add_symbol
));
4867 if (s3_append_insn (tmp
, false) == (int) s3_FAIL
)
4870 memcpy (&fix_insts
[0], &s3_inst
, sizeof (struct s3_score_it
));
4873 For a local symbol :
4874 lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15)
4875 addi rD, <sym> (BFD_RELOC_GOT_LO16) */
4876 s3_inst
.reloc
.type
= BFD_RELOC_SCORE_GOT15
;
4877 memcpy (&var_insts
[0], &s3_inst
, sizeof (struct s3_score_it
));
4878 sprintf (tmp
, "addi_s_pic r1, %s", S_GET_NAME (add_symbol
));
4879 if (s3_append_insn (tmp
, false) == (int) s3_FAIL
)
4882 memcpy (&var_insts
[1], &s3_inst
, sizeof (struct s3_score_it
));
4883 s3_build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
4885 /* Insn 2 or Insn 3: lw/st rD, [r1, constant] */
4886 sprintf (tmp
, "%s r%d, [r1, %d]", insn_name
, reg_rd
, add_number
);
4887 if (s3_append_insn (tmp
, true) == (int) s3_FAIL
)
4890 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4895 s3_inst
.error
= _("s3_PIC code offset overflow (max 16 signed bits)");
4903 s3_do_macro_ldst_label (char *str
)
4911 char *absolute_value
;
4912 char append_str
[3][s3_MAX_LITERAL_POOL_SIZE
];
4913 char verifystr
[s3_MAX_LITERAL_POOL_SIZE
];
4914 struct s3_score_it inst_backup
;
4915 struct s3_score_it inst_expand
[3];
4916 struct s3_score_it inst_main
;
4918 memcpy (&inst_backup
, &s3_inst
, sizeof (struct s3_score_it
));
4919 strcpy (verifystr
, str
);
4920 backup_str
= verifystr
;
4922 s3_skip_whitespace (backup_str
);
4923 if ((reg_rd
= s3_reg_required_here (&backup_str
, -1, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
)
4926 if (s3_skip_past_comma (&backup_str
) == (int) s3_FAIL
)
4929 label_str
= backup_str
;
4931 /* Ld/st rD, [rA, imm] ld/st rD, [rA]+, imm ld/st rD, [rA, imm]+. */
4932 if (*backup_str
== '[')
4934 s3_inst
.type
= Rd_rvalueRs_preSI12
;
4935 s3_do_ldst_insn (str
);
4939 /* Ld/st rD, imm. */
4940 absolute_value
= backup_str
;
4941 s3_inst
.type
= Rd_rvalueRs_SI15
;
4943 if (s3_my_get_expression (&s3_inst
.reloc
.exp
, &backup_str
) == (int) s3_FAIL
)
4945 s3_inst
.error
= _("expression error");
4948 else if ((s3_inst
.reloc
.exp
.X_add_symbol
== NULL
)
4949 && (s3_validate_immediate (s3_inst
.reloc
.exp
.X_add_number
, _VALUE
, 0) == (int) s3_FAIL
))
4951 s3_inst
.error
= _("value not in range [0, 0x7fffffff]");
4954 else if (s3_end_of_line (backup_str
) == (int) s3_FAIL
)
4956 s3_inst
.error
= _("end on line error");
4961 if (s3_inst
.reloc
.exp
.X_add_symbol
== 0)
4963 memcpy (&s3_inst
, &inst_backup
, sizeof (struct s3_score_it
));
4964 s3_exp_macro_ldst_abs (str
);
4969 /* Ld/st rD, label. */
4970 s3_inst
.type
= Rd_rvalueRs_SI15
;
4971 backup_str
= absolute_value
;
4972 if ((s3_data_op2 (&backup_str
, 1, _GP_IMM15
) == (int) s3_FAIL
)
4973 || (s3_end_of_line (backup_str
) == (int) s3_FAIL
))
4979 if (s3_inst
.reloc
.exp
.X_add_symbol
== 0)
4982 s3_inst
.error
= s3_BAD_ARGS
;
4987 if (s3_score_pic
== s3_PIC
)
4990 ldst_idx
= s3_inst
.instruction
& OPC_PSEUDOLDST_MASK
;
4991 s3_build_lwst_pic (reg_rd
, s3_inst
.reloc
.exp
,
4992 s3_score_ldst_insns
[ldst_idx
* 3 + 0].template_name
);
4997 if ((s3_inst
.reloc
.exp
.X_add_number
<= 0x3fff)
4998 && (s3_inst
.reloc
.exp
.X_add_number
>= -0x4000)
4999 && (!s3_nopic_need_relax (s3_inst
.reloc
.exp
.X_add_symbol
, 1)))
5003 /* Assign the real opcode. */
5004 ldst_idx
= s3_inst
.instruction
& OPC_PSEUDOLDST_MASK
;
5005 s3_inst
.instruction
&= ~OPC_PSEUDOLDST_MASK
;
5006 s3_inst
.instruction
|= s3_score_ldst_insns
[ldst_idx
* 3 + 0].value
;
5007 s3_inst
.instruction
|= reg_rd
<< 20;
5008 s3_inst
.instruction
|= s3_GP
<< 15;
5009 s3_inst
.relax_inst
= 0x8000;
5010 s3_inst
.relax_size
= 0;
5016 /* Backup s3_inst. */
5017 memcpy (&inst_main
, &s3_inst
, sizeof (struct s3_score_it
));
5021 /* Determine which instructions should be output. */
5022 sprintf (append_str
[0], "ld_i32hi r1, %s", label_str
);
5023 sprintf (append_str
[1], "ld_i32lo r1, %s", label_str
);
5024 sprintf (append_str
[2], "%s r%d, [r1, 0]", inst_backup
.name
, reg_rd
);
5026 /* Generate three instructions.
5028 ld/st rd, [r1, 0] */
5029 for (i
= 0; i
< 3; i
++)
5031 if (s3_append_insn (append_str
[i
], false) == (int) s3_FAIL
)
5034 memcpy (&inst_expand
[i
], &s3_inst
, sizeof (struct s3_score_it
));
5041 /* Adjust instruction opcode and to be relaxed instruction opcode. */
5042 inst_main
.instruction
= s3_adjust_paritybit (inst_main
.instruction
, s3_GET_INSN_CLASS (inst_main
.type
));
5044 /* relax lw rd, label -> ldis rs, imm16
5046 lw rd, [rs, imm15] or lw! rd, [rs, imm5]. */
5047 if (inst_expand
[2].relax_size
== 0)
5048 inst_main
.relax_size
= inst_expand
[0].size
+ inst_expand
[1].size
+ inst_expand
[2].size
;
5050 inst_main
.relax_size
= inst_expand
[0].size
+ inst_expand
[1].size
+ inst_expand
[2].relax_size
;
5052 inst_main
.type
= Insn_GP
;
5054 for (i
= 0; i
< 3; i
++)
5055 inst_expand
[i
].instruction
= s3_adjust_paritybit (inst_expand
[i
].instruction
,
5056 s3_GET_INSN_CLASS (inst_expand
[i
].type
));
5058 /* Check data dependency. */
5059 s3_handle_dependency (&inst_main
);
5061 /* Start a new frag if frag_now is not empty. */
5062 if (frag_now_fix () != 0)
5064 if (!frag_now
->tc_frag_data
.is_insn
)
5065 frag_wane (frag_now
);
5071 /* Write fr_fix part. */
5072 p
= frag_more (inst_main
.size
);
5073 s3_md_number_to_chars (p
, inst_main
.instruction
, inst_main
.size
);
5075 if (inst_main
.reloc
.type
!= BFD_RELOC_NONE
)
5077 s3_fix_new_score (frag_now
, p
- frag_now
->fr_literal
, inst_main
.size
,
5078 &inst_main
.reloc
.exp
, inst_main
.reloc
.pc_rel
, inst_main
.reloc
.type
);
5082 dwarf2_emit_insn (inst_main
.size
);
5085 /* s3_GP instruction can not do optimization, only can do relax between
5086 1 instruction and 3 instructions. */
5087 p
= frag_var (rs_machine_dependent
, inst_main
.relax_size
+ s3_RELAX_PAD_BYTE
, 0,
5088 s3_RELAX_ENCODE (inst_main
.size
, inst_main
.relax_size
, inst_main
.type
, 0, 4, 0),
5089 inst_main
.reloc
.exp
.X_add_symbol
, 0, NULL
);
5091 /* Write fr_var part.
5092 no calling s3_gen_insn_frag, no fixS will be generated. */
5093 s3_md_number_to_chars (p
, inst_expand
[0].instruction
, inst_expand
[0].size
);
5094 p
+= inst_expand
[0].size
;
5095 s3_md_number_to_chars (p
, inst_expand
[1].instruction
, inst_expand
[1].size
);
5096 p
+= inst_expand
[1].size
;
5098 /* relax lw rd, label -> ldis rs, imm16
5100 lw rd, [rs, imm15] or lw! rd, [rs, imm5]. */
5101 if (inst_expand
[2].relax_size
== 0)
5102 s3_md_number_to_chars (p
, inst_expand
[2].instruction
, inst_expand
[2].size
);
5104 s3_md_number_to_chars (p
, inst_expand
[2].relax_inst
, inst_expand
[2].relax_size
);
5108 s3_gen_insn_frag (&inst_expand
[0], NULL
);
5109 s3_gen_insn_frag (&inst_expand
[1], NULL
);
5110 s3_gen_insn_frag (&inst_expand
[2], NULL
);
5114 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
5119 s3_do_lw_pic (char *str
)
5123 s3_skip_whitespace (str
);
5124 if (((reg_rd
= s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
)
5125 || (s3_skip_past_comma (&str
) == (int) s3_FAIL
)
5126 || (s3_my_get_expression (&s3_inst
.reloc
.exp
, &str
) == (int) s3_FAIL
)
5127 || (s3_end_of_line (str
) == (int) s3_FAIL
))
5133 if (s3_inst
.reloc
.exp
.X_add_symbol
== 0)
5136 s3_inst
.error
= s3_BAD_ARGS
;
5141 s3_inst
.instruction
|= s3_GP
<< 15;
5142 s3_inst
.reloc
.type
= BFD_RELOC_SCORE_GOT15
;
5147 s3_do_empty (char *str
)
5150 if (s3_university_version
== 1)
5152 if (((s3_inst
.instruction
& 0x3e0003ff) == 0x0c000004)
5153 || ((s3_inst
.instruction
& 0x3e0003ff) == 0x0c000024)
5154 || ((s3_inst
.instruction
& 0x3e0003ff) == 0x0c000044)
5155 || ((s3_inst
.instruction
& 0x3e0003ff) == 0x0c000064))
5157 s3_inst
.error
= s3_ERR_FOR_SCORE5U_MMU
;
5161 if (s3_end_of_line (str
) == (int) s3_FAIL
)
5164 if (s3_inst
.relax_inst
!= 0x8000)
5166 if (s3_inst
.type
== NO_OPD
)
5168 s3_inst
.relax_size
= 2;
5172 s3_inst
.relax_size
= 4;
5178 s3_do16_int (char *str
)
5180 s3_skip_whitespace (str
);
5185 s3_do_jump (char *str
)
5189 s3_skip_whitespace (str
);
5190 if (s3_my_get_expression (&s3_inst
.reloc
.exp
, &str
) == (int) s3_FAIL
5191 || s3_end_of_line (str
) == (int) s3_FAIL
)
5194 if (s3_inst
.reloc
.exp
.X_add_symbol
== 0)
5196 s3_inst
.error
= _("lacking label ");
5200 if (!(s3_inst
.reloc
.exp
.X_add_number
>= -16777216
5201 && s3_inst
.reloc
.exp
.X_add_number
<= 16777215))
5203 s3_inst
.error
= _("invalid constant: 25 bit expression not in range [-16777216, 16777215]");
5207 save_in
= input_line_pointer
;
5208 input_line_pointer
= str
;
5209 s3_inst
.reloc
.type
= BFD_RELOC_SCORE_JMP
;
5210 s3_inst
.reloc
.pc_rel
= 1;
5211 input_line_pointer
= save_in
;
5215 s3_do_branch (char *str
)
5217 if (s3_my_get_expression (&s3_inst
.reloc
.exp
, &str
) == (int) s3_FAIL
5218 || s3_end_of_line (str
) == (int) s3_FAIL
)
5222 else if (s3_inst
.reloc
.exp
.X_add_symbol
== 0)
5224 s3_inst
.error
= _("lacking label ");
5227 else if (!(s3_inst
.reloc
.exp
.X_add_number
>= -524288
5228 && s3_inst
.reloc
.exp
.X_add_number
<= 524287))
5230 s3_inst
.error
= _("invalid constant: 20 bit expression not in range -2^19..2^19-1");
5234 s3_inst
.reloc
.type
= BFD_RELOC_SCORE_BRANCH
;
5235 s3_inst
.reloc
.pc_rel
= 1;
5237 /* Branch 32 offset field : 20 bit, 16 bit branch offset field : 8 bit. */
5238 s3_inst
.instruction
|= (s3_inst
.reloc
.exp
.X_add_number
& 0x3fe) | ((s3_inst
.reloc
.exp
.X_add_number
& 0xffc00) << 5);
5240 /* Compute 16 bit branch instruction. */
5241 if ((s3_inst
.relax_inst
!= 0x8000)
5242 && (s3_inst
.reloc
.exp
.X_add_number
>= -512 && s3_inst
.reloc
.exp
.X_add_number
<= 511))
5244 s3_inst
.relax_inst
|= ((s3_inst
.reloc
.exp
.X_add_number
>> 1) & 0x1ff);/*b! :disp 9 bit */
5245 s3_inst
.relax_size
= 2;
5249 s3_inst
.relax_inst
= 0x8000;
5254 s3_do16_branch (char *str
)
5256 if ((s3_my_get_expression (&s3_inst
.reloc
.exp
, &str
) == (int) s3_FAIL
5257 || s3_end_of_line (str
) == (int) s3_FAIL
))
5261 else if (s3_inst
.reloc
.exp
.X_add_symbol
== 0)
5263 s3_inst
.error
= _("lacking label");
5265 else if (!(s3_inst
.reloc
.exp
.X_add_number
>= -512
5266 && s3_inst
.reloc
.exp
.X_add_number
<= 511))
5268 s3_inst
.error
= _("invalid constant: 10 bit expression not in range [-2^9, 2^9-1]");
5272 s3_inst
.reloc
.type
= BFD_RELOC_SCORE16_BRANCH
;
5273 s3_inst
.reloc
.pc_rel
= 1;
5274 s3_inst
.instruction
|= ((s3_inst
.reloc
.exp
.X_add_number
>> 1) & 0x1ff);
5275 s3_inst
.relax_inst
|= ((s3_inst
.reloc
.exp
.X_add_number
) & 0x1ff);
5276 s3_inst
.relax_size
= 4;
5280 /* Return true if the given symbol should be considered local for s3_PIC. */
5282 s3_pic_need_relax (symbolS
*sym
, asection
*segtype
)
5287 /* Handle the case of a symbol equated to another symbol. */
5288 while (symbol_equated_reloc_p (sym
))
5292 /* It's possible to get a loop here in a badly written
5294 n
= symbol_get_value_expression (sym
)->X_add_symbol
;
5300 symsec
= S_GET_SEGMENT (sym
);
5302 /* duplicate the test for LINK_ONCE sections as in adjust_reloc_syms */
5304 if (symsec
!= segtype
&& ! S_IS_LOCAL (sym
))
5306 if ((bfd_section_flags (symsec
) & SEC_LINK_ONCE
) != 0)
5309 /* The GNU toolchain uses an extension for ELF: a section
5310 beginning with the magic string .gnu.linkonce is a linkonce
5312 if (startswith (segment_name (symsec
), ".gnu.linkonce"))
5316 /* This must duplicate the test in adjust_reloc_syms. */
5317 return (!bfd_is_und_section (symsec
)
5318 && !bfd_is_abs_section (symsec
)
5319 && !bfd_is_com_section (symsec
)
5322 /* A global or weak symbol is treated as external. */
5323 && (OUTPUT_FLAVOR
!= bfd_target_elf_flavour
5324 || (! S_IS_WEAK (sym
) && ! S_IS_EXTERNAL (sym
)))
5330 s3_parse_pce_inst (char *insnstr
)
5334 char first
[s3_MAX_LITERAL_POOL_SIZE
];
5335 char second
[s3_MAX_LITERAL_POOL_SIZE
];
5336 struct s3_score_it pec_part_1
;
5338 /* Get first part string of PCE. */
5339 p
= strstr (insnstr
, "||");
5342 sprintf (first
, "%s", insnstr
);
5344 /* Get second part string of PCE. */
5347 sprintf (second
, "%s", p
);
5349 s3_parse_16_32_inst (first
, false);
5353 memcpy (&pec_part_1
, &s3_inst
, sizeof (s3_inst
));
5355 s3_parse_16_32_inst (second
, false);
5359 if ( ((pec_part_1
.size
== s3_INSN_SIZE
) && (s3_inst
.size
== s3_INSN_SIZE
))
5360 || ((pec_part_1
.size
== s3_INSN_SIZE
) && (s3_inst
.size
== s3_INSN16_SIZE
))
5361 || ((pec_part_1
.size
== s3_INSN16_SIZE
) && (s3_inst
.size
== s3_INSN_SIZE
)))
5363 s3_inst
.error
= _("pce instruction error (16 bit || 16 bit).");
5364 sprintf (s3_inst
.str
, "%s", insnstr
);
5369 s3_gen_insn_frag (&pec_part_1
, &s3_inst
);
5374 s3_do16_dsp (char *str
)
5379 if (s3_score3d
== 0)
5381 s3_inst
.error
= _("score3d instruction.");
5385 s3_skip_whitespace (str
);
5387 if ((rd
= s3_reglow_required_here (&str
, 0)) == (int) s3_FAIL
5388 || s3_end_of_line (str
) == (int) s3_FAIL
)
5394 s3_inst
.relax_inst
|= rd
<< 20;
5395 s3_inst
.relax_size
= 4;
5400 s3_do16_dsp2 (char *str
)
5403 if (s3_score3d
== 0)
5405 s3_inst
.error
= _("score3d instruction.");
5409 s3_skip_whitespace (str
);
5411 if (s3_reglow_required_here (&str
, 4) == (int) s3_FAIL
5412 || s3_skip_past_comma (&str
) == (int) s3_FAIL
5413 || s3_reglow_required_here (&str
, 0) == (int) s3_FAIL
5414 || s3_end_of_line (str
) == (int) s3_FAIL
)
5420 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>> 8) & 0xf) << 20)
5421 | (((s3_inst
.instruction
>> 8) & 0xf) << 15) | (((s3_inst
.instruction
>> 4) & 0xf) << 10);
5422 s3_inst
.relax_size
= 4;
5427 s3_do_dsp (char *str
)
5430 if (s3_score3d
== 0)
5432 s3_inst
.error
= _("score3d instruction.");
5436 s3_skip_whitespace (str
);
5438 if (s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
5439 || s3_skip_past_comma (&str
) == (int) s3_FAIL
5440 || s3_reg_required_here (&str
, 10, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
5441 || s3_end_of_line (str
) == (int) s3_FAIL
)
5444 if ((s3_inst
.relax_inst
!= 0x8000) && (((s3_inst
.instruction
>> 20) & 0x1f) == 3) )
5446 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>> 10) & 0x1f)) | (((s3_inst
.instruction
>> 15) & 0x1f) << 5);
5447 s3_inst
.relax_size
= 2;
5450 s3_inst
.relax_inst
= 0x8000;
5454 s3_do_dsp2 (char *str
)
5459 if (s3_score3d
== 0)
5461 s3_inst
.error
= _("score3d instruction.");
5465 s3_skip_whitespace (str
);
5467 if ((reg
= s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
5468 || s3_skip_past_comma (&str
) == (int) s3_FAIL
5469 || s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
5470 || s3_skip_past_comma (&str
) == (int) s3_FAIL
5471 || s3_reg_required_here (&str
, 10, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
5472 || s3_end_of_line (str
) == (int) s3_FAIL
)
5478 /* Check mulr, mulur rd is even number. */
5479 if (((s3_inst
.instruction
& 0x3e0003ff) == 0x00000340
5480 || (s3_inst
.instruction
& 0x3e0003ff) == 0x00000342)
5483 s3_inst
.error
= _("rd must be even number.");
5487 if ((((s3_inst
.instruction
>> 15) & 0x10) == 0)
5488 && (((s3_inst
.instruction
>> 10) & 0x10) == 0)
5489 && (((s3_inst
.instruction
>> 20) & 0x10) == 0)
5490 && (s3_inst
.relax_inst
!= 0x8000)
5491 && (((s3_inst
.instruction
>> 20) & 0xf) == ((s3_inst
.instruction
>> 15) & 0xf)))
5493 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>> 10) & 0xf) )
5494 | (((s3_inst
.instruction
>> 15) & 0xf) << 4);
5495 s3_inst
.relax_size
= 2;
5499 s3_inst
.relax_inst
= 0x8000;
5505 s3_do_dsp3 (char *str
)
5508 if (s3_score3d
== 0)
5510 s3_inst
.error
= _("score3d instruction.");
5514 s3_skip_whitespace (str
);
5516 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
5517 || s3_skip_past_comma (&str
) == (int) s3_FAIL
5518 || s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
5519 || s3_end_of_line (str
) == (int) s3_FAIL
)
5522 if ((s3_inst
.relax_inst
!= 0x8000) && (((s3_inst
.instruction
>> 20) & 0x1f) == 3) )
5524 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>> 10) & 0x1f)) | (((s3_inst
.instruction
>> 15) & 0x1f) << 5);
5525 s3_inst
.relax_size
= 2;
5528 s3_inst
.relax_inst
= 0x8000;
5532 s3_score_s_section (int ignore
)
5534 obj_elf_section (ignore
);
5535 if ((bfd_section_flags (now_seg
) & SEC_CODE
) != 0)
5536 record_alignment (now_seg
, 2);
5541 s3_s_change_sec (int sec
)
5546 /* The ELF backend needs to know that we are changing sections, so
5547 that .previous works correctly. We could do something like check
5548 for an obj_section_change_hook macro, but that might be confusing
5549 as it would not be appropriate to use it in the section changing
5550 functions in read.c, since obj-elf.c intercepts those. FIXME:
5551 This should be cleaner, somehow. */
5552 obj_elf_section_change_hook ();
5557 seg
= subseg_new (s3_RDATA_SECTION_NAME
, (subsegT
) get_absolute_expression ());
5558 bfd_set_section_flags (seg
, (SEC_ALLOC
| SEC_LOAD
| SEC_READONLY
5559 | SEC_RELOC
| SEC_DATA
));
5560 if (strcmp (TARGET_OS
, "elf") != 0)
5561 record_alignment (seg
, 4);
5562 demand_empty_rest_of_line ();
5565 seg
= subseg_new (".sdata", (subsegT
) get_absolute_expression ());
5566 bfd_set_section_flags (seg
, (SEC_ALLOC
| SEC_LOAD
| SEC_RELOC
5567 | SEC_DATA
| SEC_SMALL_DATA
));
5568 if (strcmp (TARGET_OS
, "elf") != 0)
5569 record_alignment (seg
, 4);
5570 demand_empty_rest_of_line ();
5576 s3_s_score_mask (int reg_type ATTRIBUTE_UNUSED
)
5580 if (s3_cur_proc_ptr
== (s3_procS
*) NULL
)
5582 as_warn (_(".mask outside of .ent"));
5583 demand_empty_rest_of_line ();
5586 if (get_absolute_expression_and_terminator (&mask
) != ',')
5588 as_warn (_("Bad .mask directive"));
5589 --input_line_pointer
;
5590 demand_empty_rest_of_line ();
5593 off
= get_absolute_expression ();
5594 s3_cur_proc_ptr
->reg_mask
= mask
;
5595 s3_cur_proc_ptr
->reg_offset
= off
;
5596 demand_empty_rest_of_line ();
5600 s3_get_symbol (void)
5606 c
= get_symbol_name (&name
);
5607 p
= (symbolS
*) symbol_find_or_make (name
);
5608 (void) restore_line_pointer (c
);
5613 s3_get_number (void)
5618 if (*input_line_pointer
== '-')
5620 ++input_line_pointer
;
5623 if (!ISDIGIT (*input_line_pointer
))
5624 as_bad (_("expected simple number"));
5625 if (input_line_pointer
[0] == '0')
5627 if (input_line_pointer
[1] == 'x')
5629 input_line_pointer
+= 2;
5630 while (ISXDIGIT (*input_line_pointer
))
5633 val
|= hex_value (*input_line_pointer
++);
5635 return negative
? -val
: val
;
5639 ++input_line_pointer
;
5640 while (ISDIGIT (*input_line_pointer
))
5643 val
|= *input_line_pointer
++ - '0';
5645 return negative
? -val
: val
;
5648 if (!ISDIGIT (*input_line_pointer
))
5650 printf (_(" *input_line_pointer == '%c' 0x%02x\n"), *input_line_pointer
, *input_line_pointer
);
5651 as_warn (_("invalid number"));
5654 while (ISDIGIT (*input_line_pointer
))
5657 val
+= *input_line_pointer
++ - '0';
5659 return negative
? -val
: val
;
5662 /* The .aent and .ent directives. */
5664 s3_s_score_ent (int aent
)
5669 symbolP
= s3_get_symbol ();
5670 if (*input_line_pointer
== ',')
5671 ++input_line_pointer
;
5673 if (ISDIGIT (*input_line_pointer
) || *input_line_pointer
== '-')
5676 if ((bfd_section_flags (now_seg
) & SEC_CODE
) != 0)
5681 as_warn (_(".ent or .aent not in text section."));
5682 if (!aent
&& s3_cur_proc_ptr
)
5683 as_warn (_("missing .end"));
5686 s3_cur_proc_ptr
= &s3_cur_proc
;
5687 s3_cur_proc_ptr
->reg_mask
= 0xdeadbeaf;
5688 s3_cur_proc_ptr
->reg_offset
= 0xdeadbeaf;
5689 s3_cur_proc_ptr
->fpreg_mask
= 0xdeafbeaf;
5690 s3_cur_proc_ptr
->leaf
= 0xdeafbeaf;
5691 s3_cur_proc_ptr
->frame_offset
= 0xdeafbeaf;
5692 s3_cur_proc_ptr
->frame_reg
= 0xdeafbeaf;
5693 s3_cur_proc_ptr
->pc_reg
= 0xdeafbeaf;
5694 s3_cur_proc_ptr
->isym
= symbolP
;
5695 symbol_get_bfdsym (symbolP
)->flags
|= BSF_FUNCTION
;
5697 if (debug_type
== DEBUG_STABS
)
5698 stabs_generate_asm_func (S_GET_NAME (symbolP
), S_GET_NAME (symbolP
));
5700 demand_empty_rest_of_line ();
5704 s3_s_score_frame (int ignore ATTRIBUTE_UNUSED
)
5711 backupstr
= input_line_pointer
;
5714 if (s3_cur_proc_ptr
== (s3_procS
*) NULL
)
5716 as_warn (_(".frame outside of .ent"));
5717 demand_empty_rest_of_line ();
5720 s3_cur_proc_ptr
->frame_reg
= s3_reg_required_here ((&backupstr
), 0, s3_REG_TYPE_SCORE
);
5722 s3_skip_past_comma (&backupstr
);
5723 while (*backupstr
!= ',')
5725 str
[i
] = *backupstr
;
5733 s3_skip_past_comma (&backupstr
);
5734 s3_cur_proc_ptr
->frame_offset
= val
;
5735 s3_cur_proc_ptr
->pc_reg
= s3_reg_required_here ((&backupstr
), 0, s3_REG_TYPE_SCORE
);
5738 s3_skip_past_comma (&backupstr
);
5740 while (*backupstr
!= '\n')
5742 str
[i
] = *backupstr
;
5748 s3_cur_proc_ptr
->leaf
= val
;
5750 s3_skip_past_comma (&backupstr
);
5752 #endif /* OBJ_ELF */
5753 while (input_line_pointer
!= backupstr
)
5754 input_line_pointer
++;
5757 /* The .end directive. */
5759 s3_s_score_end (int x ATTRIBUTE_UNUSED
)
5764 /* Generate a .pdr section. */
5765 segT saved_seg
= now_seg
;
5766 subsegT saved_subseg
= now_subseg
;
5770 if (!is_end_of_line
[(unsigned char)*input_line_pointer
])
5772 p
= s3_get_symbol ();
5773 demand_empty_rest_of_line ();
5778 if ((bfd_section_flags (now_seg
) & SEC_CODE
) != 0)
5784 as_warn (_(".end not in text section"));
5785 if (!s3_cur_proc_ptr
)
5787 as_warn (_(".end directive without a preceding .ent directive."));
5788 demand_empty_rest_of_line ();
5793 gas_assert (S_GET_NAME (p
));
5794 if (strcmp (S_GET_NAME (p
), S_GET_NAME (s3_cur_proc_ptr
->isym
)))
5795 as_warn (_(".end symbol does not match .ent symbol."));
5796 if (debug_type
== DEBUG_STABS
)
5797 stabs_generate_asm_endfunc (S_GET_NAME (p
), S_GET_NAME (p
));
5800 as_warn (_(".end directive missing or unknown symbol"));
5802 if ((s3_cur_proc_ptr
->reg_mask
== 0xdeadbeaf) ||
5803 (s3_cur_proc_ptr
->reg_offset
== 0xdeadbeaf) ||
5804 (s3_cur_proc_ptr
->leaf
== 0xdeafbeaf) ||
5805 (s3_cur_proc_ptr
->frame_offset
== 0xdeafbeaf) ||
5806 (s3_cur_proc_ptr
->frame_reg
== 0xdeafbeaf) || (s3_cur_proc_ptr
->pc_reg
== 0xdeafbeaf));
5810 (void) frag_now_fix ();
5811 gas_assert (s3_pdr_seg
);
5812 subseg_set (s3_pdr_seg
, 0);
5813 /* Write the symbol. */
5814 exp
.X_op
= O_symbol
;
5815 exp
.X_add_symbol
= p
;
5816 exp
.X_add_number
= 0;
5817 emit_expr (&exp
, 4);
5818 fragp
= frag_more (7 * 4);
5819 md_number_to_chars (fragp
, (valueT
) s3_cur_proc_ptr
->reg_mask
, 4);
5820 md_number_to_chars (fragp
+ 4, (valueT
) s3_cur_proc_ptr
->reg_offset
, 4);
5821 md_number_to_chars (fragp
+ 8, (valueT
) s3_cur_proc_ptr
->fpreg_mask
, 4);
5822 md_number_to_chars (fragp
+ 12, (valueT
) s3_cur_proc_ptr
->leaf
, 4);
5823 md_number_to_chars (fragp
+ 16, (valueT
) s3_cur_proc_ptr
->frame_offset
, 4);
5824 md_number_to_chars (fragp
+ 20, (valueT
) s3_cur_proc_ptr
->frame_reg
, 4);
5825 md_number_to_chars (fragp
+ 24, (valueT
) s3_cur_proc_ptr
->pc_reg
, 4);
5826 subseg_set (saved_seg
, saved_subseg
);
5829 s3_cur_proc_ptr
= NULL
;
5832 /* Handle the .set pseudo-op. */
5834 s3_s_score_set (int x ATTRIBUTE_UNUSED
)
5837 char name
[s3_MAX_LITERAL_POOL_SIZE
];
5838 char * orig_ilp
= input_line_pointer
;
5840 while (!is_end_of_line
[(unsigned char)*input_line_pointer
])
5842 name
[i
] = (char) * input_line_pointer
;
5844 ++input_line_pointer
;
5849 if (strcmp (name
, "nwarn") == 0)
5851 s3_warn_fix_data_dependency
= 0;
5853 else if (strcmp (name
, "fixdd") == 0)
5855 s3_fix_data_dependency
= 1;
5857 else if (strcmp (name
, "nofixdd") == 0)
5859 s3_fix_data_dependency
= 0;
5861 else if (strcmp (name
, "r1") == 0)
5865 else if (strcmp (name
, "nor1") == 0)
5869 else if (strcmp (name
, "optimize") == 0)
5873 else if (strcmp (name
, "volatile") == 0)
5877 else if (strcmp (name
, "pic") == 0)
5879 s3_score_pic
= s3_PIC
;
5883 input_line_pointer
= orig_ilp
;
5888 /* Handle the .cpload pseudo-op. This is used when generating s3_PIC code. It sets the
5889 $gp register for the function based on the function address, which is in the register
5890 named in the argument. This uses a relocation against GP_DISP_LABEL, which is handled
5891 specially by the linker. The result is:
5892 ldis gp, %hi(GP_DISP_LABEL)
5893 ori gp, %low(GP_DISP_LABEL)
5894 add gp, gp, .cpload argument
5895 The .cpload argument is normally r29. */
5897 s3_s_score_cpload (int ignore ATTRIBUTE_UNUSED
)
5900 char insn_str
[s3_MAX_LITERAL_POOL_SIZE
];
5902 /* If we are not generating s3_PIC code, .cpload is ignored. */
5903 if (s3_score_pic
== s3_NO_PIC
)
5909 if ((reg
= s3_reg_required_here (&input_line_pointer
, -1, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
)
5912 demand_empty_rest_of_line ();
5914 sprintf (insn_str
, "ld_i32hi r%d, %s", s3_GP
, GP_DISP_LABEL
);
5915 if (s3_append_insn (insn_str
, true) == (int) s3_FAIL
)
5918 sprintf (insn_str
, "ld_i32lo r%d, %s", s3_GP
, GP_DISP_LABEL
);
5919 if (s3_append_insn (insn_str
, true) == (int) s3_FAIL
)
5922 sprintf (insn_str
, "add r%d, r%d, r%d", s3_GP
, s3_GP
, reg
);
5923 if (s3_append_insn (insn_str
, true) == (int) s3_FAIL
)
5927 /* Handle the .cprestore pseudo-op. This stores $gp into a given
5928 offset from $sp. The offset is remembered, and after making a s3_PIC
5929 call $gp is restored from that location. */
5931 s3_s_score_cprestore (int ignore ATTRIBUTE_UNUSED
)
5934 int cprestore_offset
;
5935 char insn_str
[s3_MAX_LITERAL_POOL_SIZE
];
5937 /* If we are not generating s3_PIC code, .cprestore is ignored. */
5938 if (s3_score_pic
== s3_NO_PIC
)
5944 if ((reg
= s3_reg_required_here (&input_line_pointer
, -1, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
5945 || s3_skip_past_comma (&input_line_pointer
) == (int) s3_FAIL
)
5950 cprestore_offset
= get_absolute_expression ();
5952 if (cprestore_offset
<= 0x3fff)
5954 sprintf (insn_str
, "sw r%d, [r%d, %d]", s3_GP
, reg
, cprestore_offset
);
5955 if (s3_append_insn (insn_str
, true) == (int) s3_FAIL
)
5965 sprintf (insn_str
, "li r1, %d", cprestore_offset
);
5966 if (s3_append_insn (insn_str
, true) == (int) s3_FAIL
)
5969 sprintf (insn_str
, "add r1, r1, r%d", reg
);
5970 if (s3_append_insn (insn_str
, true) == (int) s3_FAIL
)
5973 sprintf (insn_str
, "sw r%d, [r1]", s3_GP
);
5974 if (s3_append_insn (insn_str
, true) == (int) s3_FAIL
)
5980 demand_empty_rest_of_line ();
5983 /* Handle the .gpword pseudo-op. This is used when generating s3_PIC
5984 code. It generates a 32 bit s3_GP relative reloc. */
5986 s3_s_score_gpword (int ignore ATTRIBUTE_UNUSED
)
5991 /* When not generating s3_PIC code, this is treated as .word. */
5992 if (s3_score_pic
== s3_NO_PIC
)
5998 if (ex
.X_op
!= O_symbol
|| ex
.X_add_number
!= 0)
6000 as_bad (_("Unsupported use of .gpword"));
6001 ignore_rest_of_line ();
6004 s3_md_number_to_chars (p
, (valueT
) 0, 4);
6005 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 4, &ex
, false, BFD_RELOC_GPREL32
);
6006 demand_empty_rest_of_line ();
6009 /* Handle the .cpadd pseudo-op. This is used when dealing with switch
6010 tables in s3_PIC code. */
6012 s3_s_score_cpadd (int ignore ATTRIBUTE_UNUSED
)
6015 char insn_str
[s3_MAX_LITERAL_POOL_SIZE
];
6017 /* If we are not generating s3_PIC code, .cpload is ignored. */
6018 if (s3_score_pic
== s3_NO_PIC
)
6024 if ((reg
= s3_reg_required_here (&input_line_pointer
, -1, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
)
6028 demand_empty_rest_of_line ();
6030 /* Add $gp to the register named as an argument. */
6031 sprintf (insn_str
, "add r%d, r%d, r%d", reg
, reg
, s3_GP
);
6032 if (s3_append_insn (insn_str
, true) == (int) s3_FAIL
)
6036 #ifndef TC_IMPLICIT_LCOMM_ALIGNMENT
6037 #define TC_IMPLICIT_LCOMM_ALIGNMENT(SIZE, P2VAR) \
6042 else if ((SIZE) >= 4) \
6044 else if ((SIZE) >= 2) \
6053 s3_s_score_lcomm (int bytes_p
)
6060 segT current_seg
= now_seg
;
6061 subsegT current_subseg
= now_subseg
;
6062 const int max_alignment
= 15;
6064 segT bss_seg
= bss_section
;
6065 int needs_align
= 0;
6067 c
= get_symbol_name (&name
);
6068 p
= input_line_pointer
;
6069 (void) restore_line_pointer (c
);
6073 as_bad (_("expected symbol name"));
6074 discard_rest_of_line ();
6080 /* Accept an optional comma after the name. The comma used to be
6081 required, but Irix 5 cc does not generate it. */
6082 if (*input_line_pointer
== ',')
6084 ++input_line_pointer
;
6088 if (is_end_of_line
[(unsigned char)*input_line_pointer
])
6090 as_bad (_("missing size expression"));
6094 if ((temp
= get_absolute_expression ()) < 0)
6096 as_warn (_("BSS length (%d) < 0 ignored"), temp
);
6097 ignore_rest_of_line ();
6101 #if defined (TC_SCORE)
6102 if (OUTPUT_FLAVOR
== bfd_target_ecoff_flavour
|| OUTPUT_FLAVOR
== bfd_target_elf_flavour
)
6104 /* For Score and Alpha ECOFF or ELF, small objects are put in .sbss. */
6105 if ((unsigned) temp
<= bfd_get_gp_size (stdoutput
))
6107 bss_seg
= subseg_new (".sbss", 1);
6108 seg_info (bss_seg
)->bss
= 1;
6109 if (!bfd_set_section_flags (bss_seg
, SEC_ALLOC
| SEC_SMALL_DATA
))
6110 as_warn (_("error setting flags for \".sbss\": %s"),
6111 bfd_errmsg (bfd_get_error ()));
6117 if (*input_line_pointer
== ',')
6119 ++input_line_pointer
;
6122 if (is_end_of_line
[(unsigned char)*input_line_pointer
])
6124 as_bad (_("missing alignment"));
6129 align
= get_absolute_expression ();
6136 TC_IMPLICIT_LCOMM_ALIGNMENT (temp
, align
);
6138 /* Still zero unless TC_IMPLICIT_LCOMM_ALIGNMENT set it. */
6140 record_alignment (bss_seg
, align
);
6147 /* Convert to a power of 2. */
6152 for (i
= 0; align
!= 0; align
>>= 1, ++i
)
6158 if (align
> max_alignment
)
6160 align
= max_alignment
;
6161 as_warn (_("alignment too large; %d assumed"), align
);
6166 as_warn (_("alignment negative; 0 assumed"));
6169 record_alignment (bss_seg
, align
);
6173 symbolP
= symbol_find_or_make (name
);
6177 #if (defined (OBJ_AOUT) || defined (OBJ_MAYBE_AOUT))
6178 (OUTPUT_FLAVOR
!= bfd_target_aout_flavour
6179 || (S_GET_OTHER (symbolP
) == 0 && S_GET_DESC (symbolP
) == 0)) &&
6181 (S_GET_SEGMENT (symbolP
) == bss_seg
|| (!S_IS_DEFINED (symbolP
) && S_GET_VALUE (symbolP
) == 0)))
6185 subseg_set (bss_seg
, 1);
6188 frag_align (align
, 0, 0);
6190 /* Detach from old frag. */
6191 if (S_GET_SEGMENT (symbolP
) == bss_seg
)
6192 symbol_get_frag (symbolP
)->fr_symbol
= NULL
;
6194 symbol_set_frag (symbolP
, frag_now
);
6195 pfrag
= frag_var (rs_org
, 1, 1, (relax_substateT
) 0, symbolP
, (offsetT
) temp
, NULL
);
6199 S_SET_SEGMENT (symbolP
, bss_seg
);
6202 /* The symbol may already have been created with a preceding
6203 ".globl" directive -- be careful not to step on storage class
6204 in that case. Otherwise, set it to static. */
6205 if (S_GET_STORAGE_CLASS (symbolP
) != C_EXT
)
6207 S_SET_STORAGE_CLASS (symbolP
, C_STAT
);
6209 #endif /* OBJ_COFF */
6212 S_SET_SIZE (symbolP
, temp
);
6216 as_bad (_("symbol `%s' is already defined"), S_GET_NAME (symbolP
));
6218 subseg_set (current_seg
, current_subseg
);
6220 demand_empty_rest_of_line ();
6224 s3_insert_reg (const struct s3_reg_entry
*r
, htab_t htab
)
6226 char *buf
= notes_strdup (r
->name
);
6229 for (p
= buf
; *p
; p
++)
6232 str_hash_insert (htab
, r
->name
, r
, 0);
6233 str_hash_insert (htab
, buf
, r
, 0);
6237 s3_build_reg_hsh (struct s3_reg_map
*map
)
6239 const struct s3_reg_entry
*r
;
6241 map
->htab
= str_htab_create ();
6242 for (r
= map
->names
; r
->name
!= NULL
; r
++)
6243 s3_insert_reg (r
, map
->htab
);
6246 /* Iterate over the base tables to create the instruction patterns. */
6248 s3_build_score_ops_hsh (void)
6252 for (i
= 0; i
< sizeof (s3_score_insns
) / sizeof (struct s3_asm_opcode
); i
++)
6254 const struct s3_asm_opcode
*insn
= s3_score_insns
+ i
;
6255 size_t len
= strlen (insn
->template_name
) + 1;
6256 struct s3_asm_opcode
*new_opcode
;
6257 char *template_name
;
6259 new_opcode
= notes_alloc (sizeof (*new_opcode
));
6260 template_name
= notes_memdup (insn
->template_name
, len
, len
);
6262 new_opcode
->template_name
= template_name
;
6263 new_opcode
->parms
= insn
->parms
;
6264 new_opcode
->value
= insn
->value
;
6265 new_opcode
->relax_value
= insn
->relax_value
;
6266 new_opcode
->type
= insn
->type
;
6267 new_opcode
->bitmask
= insn
->bitmask
;
6268 str_hash_insert (s3_score_ops_hsh
, new_opcode
->template_name
,
6274 s3_build_dependency_insn_hsh (void)
6278 for (i
= 0; i
< sizeof (s3_insn_to_dependency_table
) / sizeof (s3_insn_to_dependency_table
[0]); i
++)
6280 const struct s3_insn_to_dependency
*tmp
= s3_insn_to_dependency_table
+ i
;
6281 size_t len
= strlen (tmp
->insn_name
) + 1;
6282 struct s3_insn_to_dependency
*new_i2n
;
6285 new_i2n
= notes_alloc (sizeof (*new_i2n
));
6286 buf
= notes_memdup (tmp
->insn_name
, len
, len
);
6288 new_i2n
->insn_name
= buf
;
6289 new_i2n
->type
= tmp
->type
;
6290 str_hash_insert (s3_dependency_insn_hsh
, new_i2n
->insn_name
, new_i2n
, 0);
6295 s_score_text (int ignore
)
6297 obj_elf_text (ignore
);
6298 record_alignment (now_seg
, 2);
6302 s_section (int ignore
)
6305 return s3_score_s_section (ignore
);
6307 return s7_s_section (ignore
);
6311 s_change_sec (int sec
)
6314 return s3_s_change_sec (sec
);
6316 return s7_s_change_sec (sec
);
6320 s_score_mask (int reg_type ATTRIBUTE_UNUSED
)
6323 return s3_s_score_mask (reg_type
);
6325 return s7_s_score_mask (reg_type
);
6329 s_score_ent (int aent
)
6332 return s3_s_score_ent (aent
);
6334 return s7_s_score_ent (aent
);
6338 s_score_frame (int ignore ATTRIBUTE_UNUSED
)
6341 return s3_s_score_frame (ignore
);
6343 return s7_s_score_frame (ignore
);
6347 s_score_end (int x ATTRIBUTE_UNUSED
)
6350 return s3_s_score_end (x
);
6352 return s7_s_score_end (x
);
6356 s_score_set (int x ATTRIBUTE_UNUSED
)
6359 return s3_s_score_set (x
);
6361 return s7_s_score_set (x
);
6365 s_score_cpload (int ignore ATTRIBUTE_UNUSED
)
6368 return s3_s_score_cpload (ignore
);
6370 return s7_s_score_cpload (ignore
);
6374 s_score_cprestore (int ignore ATTRIBUTE_UNUSED
)
6377 return s3_s_score_cprestore (ignore
);
6379 return s7_s_score_cprestore (ignore
);
6383 s_score_gpword (int ignore ATTRIBUTE_UNUSED
)
6386 return s3_s_score_gpword (ignore
);
6388 return s7_s_score_gpword (ignore
);
6392 s_score_cpadd (int ignore ATTRIBUTE_UNUSED
)
6395 return s3_s_score_cpadd (ignore
);
6397 return s7_s_score_cpadd (ignore
);
6401 s_score_lcomm (int bytes_p
)
6404 return s3_s_score_lcomm (bytes_p
);
6406 return s7_s_score_lcomm (bytes_p
);
6410 s3_assemble (char *str
)
6413 know (strlen (str
) < s3_MAX_LITERAL_POOL_SIZE
);
6415 memset (&s3_inst
, '\0', sizeof (s3_inst
));
6416 if (s3_INSN_IS_PCE_P (str
))
6417 s3_parse_pce_inst (str
);
6418 else if (s3_INSN_IS_48_P (str
))
6419 s3_parse_48_inst (str
, true);
6421 s3_parse_16_32_inst (str
, true);
6424 as_bad (_("%s -- `%s'"), s3_inst
.error
, s3_inst
.str
);
6428 s3_operand (expressionS
* exp
)
6430 if (s3_in_my_get_expression
)
6432 exp
->X_op
= O_illegal
;
6433 if (s3_inst
.error
== NULL
)
6435 s3_inst
.error
= _("bad expression");
6447 s3_score_ops_hsh
= str_htab_create ();
6449 s3_build_score_ops_hsh ();
6451 s3_dependency_insn_hsh
= str_htab_create ();
6453 s3_build_dependency_insn_hsh ();
6455 for (i
= (int)s3_REG_TYPE_FIRST
; i
< (int)s3_REG_TYPE_MAX
; i
++)
6456 s3_build_reg_hsh (s3_all_reg_maps
+ i
);
6458 /* Initialize dependency vector. */
6459 s3_init_dependency_vector ();
6461 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
, 0);
6463 subseg
= now_subseg
;
6464 s3_pdr_seg
= subseg_new (".pdr", (subsegT
) 0);
6465 bfd_set_section_flags (s3_pdr_seg
, SEC_READONLY
| SEC_RELOC
| SEC_DEBUGGING
);
6466 bfd_set_section_alignment (s3_pdr_seg
, 2);
6467 subseg_set (seg
, subseg
);
6469 if (s3_USE_GLOBAL_POINTER_OPT
)
6470 bfd_set_gp_size (stdoutput
, s3_g_switch_value
);
6474 s3_number_to_chars (char *buf
, valueT val
, int n
)
6476 if (target_big_endian
)
6477 number_to_chars_bigendian (buf
, val
, n
);
6479 number_to_chars_littleendian (buf
, val
, n
);
6483 s3_normal_chars_to_number (char *buf
, int n
)
6486 unsigned char *where
= (unsigned char *)buf
;
6488 if (target_big_endian
)
6493 result
|= (*where
++ & 255);
6501 result
|= (where
[n
] & 255);
6509 s3_number_to_chars_littleendian (void *p
, valueT data
, int n
)
6511 char *buf
= (char *) p
;
6516 md_number_to_chars (buf
, data
>> 16, 2);
6517 md_number_to_chars (buf
+ 2, data
, 2);
6520 md_number_to_chars (buf
, data
>> 32, 2);
6521 md_number_to_chars (buf
+ 2, data
>> 16, 2);
6522 md_number_to_chars (buf
+ 4, data
, 2);
6525 /* Error routine. */
6526 as_bad_where (__FILE__
, __LINE__
, _("size is not 4 or 6"));
6532 s3_chars_to_number_littleendian (const void *p
, int n
)
6534 char *buf
= (char *) p
;
6540 result
= s3_normal_chars_to_number (buf
, 2) << 16;
6541 result
|= s3_normal_chars_to_number (buf
+ 2, 2);
6544 result
= s3_normal_chars_to_number (buf
, 2) << 32;
6545 result
|= s3_normal_chars_to_number (buf
+ 2, 2) << 16;
6546 result
|= s3_normal_chars_to_number (buf
+ 4, 2);
6549 /* Error routine. */
6550 as_bad_where (__FILE__
, __LINE__
, _("size is not 4 or 6"));
6558 s3_md_number_to_chars (char *buf
, valueT val
, int n
)
6560 if (!target_big_endian
&& n
>= 4)
6561 s3_number_to_chars_littleendian (buf
, val
, n
);
6563 md_number_to_chars (buf
, val
, n
);
6567 s3_md_chars_to_number (char *buf
, int n
)
6571 if (!target_big_endian
&& n
>= 4)
6572 result
= s3_chars_to_number_littleendian (buf
, n
);
6574 result
= s3_normal_chars_to_number (buf
, n
);
6580 s3_atof (int type
, char *litP
, int *sizeP
)
6583 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
6609 return _("bad call to MD_ATOF()");
6612 t
= atof_ieee (input_line_pointer
, type
, words
);
6614 input_line_pointer
= t
;
6617 if (target_big_endian
)
6619 for (i
= 0; i
< prec
; i
++)
6621 s3_md_number_to_chars (litP
, (valueT
) words
[i
], 2);
6627 for (i
= 0; i
< prec
; i
+= 2)
6629 s3_md_number_to_chars (litP
, (valueT
) words
[i
+ 1], 2);
6630 s3_md_number_to_chars (litP
+ 2, (valueT
) words
[i
], 2);
6639 s3_frag_check (fragS
* fragp ATTRIBUTE_UNUSED
)
6641 know (fragp
->insn_addr
<= s3_RELAX_PAD_BYTE
);
6645 s3_validate_fix (fixS
*fixP
)
6647 fixP
->fx_where
+= fixP
->fx_frag
->insn_addr
;
6651 s3_force_relocation (struct fix
*fixp
)
6655 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
6656 || fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
6657 || fixp
->fx_r_type
== BFD_RELOC_SCORE_JMP
6658 || fixp
->fx_r_type
== BFD_RELOC_SCORE_BRANCH
6659 || fixp
->fx_r_type
== BFD_RELOC_SCORE16_JMP
6660 || fixp
->fx_r_type
== BFD_RELOC_SCORE16_BRANCH
6661 || fixp
->fx_r_type
== BFD_RELOC_SCORE_BCMP
)
6669 s3_fix_adjustable (fixS
* fixP
)
6671 if (fixP
->fx_addsy
== NULL
)
6675 else if (OUTPUT_FLAVOR
== bfd_target_elf_flavour
6676 && (S_IS_EXTERNAL (fixP
->fx_addsy
) || S_IS_WEAK (fixP
->fx_addsy
)))
6680 else if (fixP
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
6681 || fixP
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
6682 || fixP
->fx_r_type
== BFD_RELOC_SCORE_JMP
6683 || fixP
->fx_r_type
== BFD_RELOC_SCORE16_JMP
)
6692 s3_elf_final_processing (void)
6694 unsigned long val
= 0;
6697 val
= E_SCORE_MACH_SCORE3
;
6699 val
= E_SCORE_MACH_SCORE7
;
6701 elf_elfheader (stdoutput
)->e_machine
= EM_SCORE
;
6702 elf_elfheader (stdoutput
)->e_flags
&= ~EF_SCORE_MACH
;
6703 elf_elfheader (stdoutput
)->e_flags
|= val
;
6705 if (s3_fix_data_dependency
== 1)
6707 elf_elfheader (stdoutput
)->e_flags
|= EF_SCORE_FIXDEP
;
6709 if (s3_score_pic
== s3_PIC
)
6711 elf_elfheader (stdoutput
)->e_flags
|= EF_SCORE_PIC
;
6716 s3_judge_size_before_relax (fragS
* fragp
, asection
*sec
)
6720 if (s3_score_pic
== s3_NO_PIC
)
6721 change
= s3_nopic_need_relax (fragp
->fr_symbol
, 0);
6723 change
= s3_pic_need_relax (fragp
->fr_symbol
, sec
);
6727 /* Only at the first time determining whether s3_GP instruction relax should be done,
6728 return the difference between instruction size and instruction relax size. */
6729 if (fragp
->fr_opcode
== NULL
)
6731 fragp
->fr_fix
= s3_RELAX_NEW (fragp
->fr_subtype
);
6732 fragp
->fr_opcode
= fragp
->fr_literal
+ s3_RELAX_RELOC1 (fragp
->fr_subtype
);
6733 return s3_RELAX_NEW (fragp
->fr_subtype
) - s3_RELAX_OLD (fragp
->fr_subtype
);
6741 s3_estimate_size_before_relax (fragS
* fragp
, asection
* sec ATTRIBUTE_UNUSED
)
6743 if ((s3_RELAX_TYPE (fragp
->fr_subtype
) == Insn_GP
)
6744 || (s3_RELAX_TYPE (fragp
->fr_subtype
) == Insn_PIC
))
6745 return s3_judge_size_before_relax (fragp
, sec
);
6751 s3_relax_branch_inst32 (fragS
* fragp
)
6753 fragp
->fr_opcode
= NULL
;
6758 s3_relax_branch_inst16 (fragS
* fragp
)
6760 int relaxable_p
= 0;
6761 int frag_addr
= fragp
->fr_address
+ fragp
->insn_addr
;
6762 addressT symbol_address
= 0;
6766 unsigned long inst_value
;
6768 relaxable_p
= s3_RELAX_OPT (fragp
->fr_subtype
);
6770 s
= fragp
->fr_symbol
;
6774 symbol_address
= (addressT
) symbol_get_frag (s
)->fr_address
;
6776 inst_value
= s3_md_chars_to_number (fragp
->fr_literal
, s3_INSN16_SIZE
);
6777 offset
= (inst_value
& 0x1ff) << 1;
6778 if ((offset
& 0x200) == 0x200)
6779 offset
|= 0xfffffc00;
6781 value
= offset
+ symbol_address
- frag_addr
;
6784 && (!((value
& 0xfffffe00) == 0 || (value
& 0xfffffe00) == 0xfffffe00))
6785 && fragp
->fr_fix
== 2
6786 && (S_IS_DEFINED (s
)
6788 && !S_IS_EXTERNAL (s
)))
6790 /* Relax branch 32 to branch 16. */
6791 fragp
->fr_opcode
= fragp
->fr_literal
+ s3_RELAX_RELOC1 (fragp
->fr_subtype
);
6800 s3_relax_cmpbranch_inst32 (fragS
* fragp
)
6802 int relaxable_p
= 0;
6806 long frag_addr
= fragp
->fr_address
+ fragp
->insn_addr
;
6807 long symbol_address
= 0;
6809 unsigned long inst_value
;
6811 relaxable_p
= s3_RELAX_OPT (fragp
->fr_subtype
);
6813 s
= fragp
->fr_symbol
;
6817 symbol_address
= (addressT
) symbol_get_frag (s
)->fr_address
;
6819 inst_value
= s3_md_chars_to_number (fragp
->fr_literal
, s3_INSN_SIZE
);
6820 offset
= (inst_value
& 0x1)
6821 | (((inst_value
>> 7) & 0x7) << 1)
6822 | (((inst_value
>> 21) & 0x1f) << 4);
6824 if ((offset
& 0x200) == 0x200)
6825 offset
|= 0xfffffe00;
6827 value
= offset
+ symbol_address
- frag_addr
;
6828 /* change the order of judging rule is because
6829 1.not defined symbol or common symbol or external symbol will change
6830 bcmp to cmp!+beq/bne ,here need to record fragp->fr_opcode
6831 2.if the flow is as before : it will results to recursive loop
6833 if (fragp
->fr_fix
== 6)
6835 /* Have already relaxed! Just return 0 to terminate the loop. */
6838 /* need to translate when extern or not defined or common symbol */
6839 else if ((relaxable_p
6840 && (!((value
& 0xfffffe00) == 0 || (value
& 0xfffffe00) == 0xfffffe00))
6841 && fragp
->fr_fix
== 4)
6842 || !S_IS_DEFINED (s
)
6844 ||S_IS_EXTERNAL (s
))
6846 fragp
->fr_opcode
= fragp
->fr_literal
+ s3_RELAX_RELOC1 (fragp
->fr_subtype
);
6852 /* Never relax. Modify fr_opcode to NULL to verify it's value in
6854 fragp
->fr_opcode
= NULL
;
6861 s3_relax_other_inst32 (fragS
* fragp
)
6863 int relaxable_p
= s3_RELAX_OPT (fragp
->fr_subtype
);
6866 && fragp
->fr_fix
== 4)
6868 fragp
->fr_opcode
= fragp
->fr_literal
+ s3_RELAX_RELOC1 (fragp
->fr_subtype
);
6877 s3_relax_gp_and_pic_inst32 (void)
6879 /* md_estimate_size_before_relax has already relaxed s3_GP and s3_PIC
6880 instructions. We don't change relax size here. */
6885 s3_relax_frag (asection
* sec ATTRIBUTE_UNUSED
, fragS
* fragp
, long stretch ATTRIBUTE_UNUSED
)
6888 int adjust_align_p
= 0;
6890 /* If the instruction address is odd, make it half word align first. */
6891 if ((fragp
->fr_address
) % 2 != 0)
6893 if ((fragp
->fr_address
+ fragp
->insn_addr
) % 2 != 0)
6895 fragp
->insn_addr
= 1;
6901 switch (s3_RELAX_TYPE (fragp
->fr_subtype
))
6904 grows
+= s3_relax_branch_inst32 (fragp
);
6908 grows
+= s3_relax_branch_inst16 (fragp
);
6912 grows
+= s3_relax_cmpbranch_inst32 (fragp
);
6917 grows
+= s3_relax_gp_and_pic_inst32 ();
6921 grows
+= s3_relax_other_inst32 (fragp
);
6926 if (adjust_align_p
&& fragp
->insn_addr
)
6928 fragp
->fr_fix
+= fragp
->insn_addr
;
6935 s3_convert_frag (bfd
* abfd ATTRIBUTE_UNUSED
, segT sec ATTRIBUTE_UNUSED
, fragS
* fragp
)
6942 r_old
= s3_RELAX_OLD (fragp
->fr_subtype
);
6943 r_new
= s3_RELAX_NEW (fragp
->fr_subtype
);
6945 /* fragp->fr_opcode indicates whether this frag should be relaxed. */
6946 if (fragp
->fr_opcode
== NULL
)
6948 memcpy (backup
, fragp
->fr_literal
, r_old
);
6949 fragp
->fr_fix
= r_old
;
6953 memcpy (backup
, fragp
->fr_literal
+ r_old
, r_new
);
6954 fragp
->fr_fix
= r_new
;
6957 fixp
= fragp
->tc_frag_data
.fixp
;
6958 while (fixp
&& fixp
->fx_frag
== fragp
&& fixp
->fx_where
< r_old
)
6960 if (fragp
->fr_opcode
)
6962 fixp
= fixp
->fx_next
;
6964 while (fixp
&& fixp
->fx_frag
== fragp
)
6966 if (fragp
->fr_opcode
)
6967 fixp
->fx_where
-= r_old
+ fragp
->insn_addr
;
6970 fixp
= fixp
->fx_next
;
6973 if (fragp
->insn_addr
)
6975 s3_md_number_to_chars (fragp
->fr_literal
, 0x0, fragp
->insn_addr
);
6977 memcpy (fragp
->fr_literal
+ fragp
->insn_addr
, backup
, fragp
->fr_fix
);
6978 fragp
->fr_fix
+= fragp
->insn_addr
;
6982 s3_pcrel_from (fixS
* fixP
)
6987 && (S_GET_SEGMENT (fixP
->fx_addsy
) == undefined_section
)
6988 && (fixP
->fx_subsy
== NULL
))
6994 retval
= fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
7001 s3_section_align (segT segment ATTRIBUTE_UNUSED
, valueT size
)
7003 int align
= bfd_section_alignment (segment
);
7004 return ((size
+ (1 << align
) - 1) & -(1 << align
));
7008 s3_apply_fix (fixS
*fixP
, valueT
*valP
, segT seg
)
7010 valueT value
= *valP
;
7015 char *buf
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
7017 gas_assert (fixP
->fx_r_type
< BFD_RELOC_UNUSED
);
7018 if (fixP
->fx_addsy
== 0 && !fixP
->fx_pcrel
)
7020 if (fixP
->fx_r_type
!= BFD_RELOC_SCORE_DUMMY_HI16
)
7024 /* If this symbol is in a different section then we need to leave it for
7025 the linker to deal with. Unfortunately, md_pcrel_from can't tell,
7026 so we have to undo it's effects here. */
7029 if (fixP
->fx_addsy
!= NULL
7030 && S_IS_DEFINED (fixP
->fx_addsy
)
7031 && S_GET_SEGMENT (fixP
->fx_addsy
) != seg
)
7032 value
+= md_pcrel_from (fixP
);
7035 /* Remember value for emit_reloc. */
7036 fixP
->fx_addnumber
= value
;
7038 switch (fixP
->fx_r_type
)
7040 case BFD_RELOC_HI16_S
:
7041 if (fixP
->fx_done
) /* For la rd, imm32. */
7043 newval
= s3_md_chars_to_number (buf
, s3_INSN_SIZE
);
7044 HI
= value
>> 16; /* mul to 2, then take the hi 16 bit. */
7045 newval
|= (HI
& 0x3fff) << 1;
7046 newval
|= ((HI
>> 14) & 0x3) << 16;
7047 s3_md_number_to_chars (buf
, newval
, s3_INSN_SIZE
);
7050 case BFD_RELOC_LO16
:
7051 if (fixP
->fx_done
) /* For la rd, imm32. */
7053 newval
= s3_md_chars_to_number (buf
, s3_INSN_SIZE
);
7054 LO
= value
& 0xffff;
7055 newval
|= (LO
& 0x3fff) << 1; /* 16 bit: imm -> 14 bit in lo, 2 bit in hi. */
7056 newval
|= ((LO
>> 14) & 0x3) << 16;
7057 s3_md_number_to_chars (buf
, newval
, s3_INSN_SIZE
);
7060 case BFD_RELOC_SCORE_JMP
:
7062 content
= s3_md_chars_to_number (buf
, s3_INSN_SIZE
);
7063 value
= fixP
->fx_offset
;
7064 content
= (content
& ~0x3ff7ffe) | ((value
<< 1) & 0x3ff0000) | (value
& 0x7fff);
7065 s3_md_number_to_chars (buf
, content
, s3_INSN_SIZE
);
7069 case BFD_RELOC_SCORE_IMM30
:
7071 content
= s3_md_chars_to_number (buf
, s3_INSN48_SIZE
);
7072 value
= fixP
->fx_offset
;
7074 content
= (content
& ~0x7f7fff7f80LL
)
7075 | (((value
& 0xff) >> 0) << 7)
7076 | (((value
& 0x7fff00) >> 8) << 16)
7077 | (((value
& 0x3f800000) >> 23) << 32);
7078 s3_md_number_to_chars (buf
, content
, s3_INSN48_SIZE
);
7082 case BFD_RELOC_SCORE_IMM32
:
7084 content
= s3_md_chars_to_number (buf
, s3_INSN48_SIZE
);
7085 value
= fixP
->fx_offset
;
7086 content
= (content
& ~0x7f7fff7fe0LL
)
7087 | ((value
& 0x3ff) << 5)
7088 | (((value
>> 10) & 0x7fff) << 16)
7089 | (((value
>> 25) & 0x7f) << 32);
7090 s3_md_number_to_chars (buf
, content
, s3_INSN48_SIZE
);
7094 case BFD_RELOC_SCORE_BRANCH
:
7095 if ((S_GET_SEGMENT (fixP
->fx_addsy
) != seg
) || (fixP
->fx_addsy
!= NULL
&& S_IS_EXTERNAL (fixP
->fx_addsy
)))
7096 value
= fixP
->fx_offset
;
7100 content
= s3_md_chars_to_number (buf
, s3_INSN_SIZE
);
7102 /* Don't check c-bit. */
7103 if (fixP
->fx_frag
->fr_opcode
!= 0)
7105 if ((value
& 0xfffffe00) != 0 && (value
& 0xfffffe00) != 0xfffffe00)
7107 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7108 _(" branch relocation truncate (0x%x) [-2^9 ~ 2^9-1]"), (unsigned int) value
);
7111 content
= s3_md_chars_to_number (buf
, s3_INSN16_SIZE
);
7113 content
= (content
& 0xfe00) | ((value
>> 1) & 0x1ff);
7114 s3_md_number_to_chars (buf
, content
, s3_INSN16_SIZE
);
7115 fixP
->fx_r_type
= BFD_RELOC_SCORE16_BRANCH
;
7120 if ((value
& 0xfff80000) != 0 && (value
& 0xfff80000) != 0xfff80000)
7122 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7123 _(" branch relocation truncate (0x%x) [-2^19 ~ 2^19-1]"), (unsigned int) value
);
7126 content
= s3_md_chars_to_number (buf
, s3_INSN_SIZE
);
7127 content
&= 0xfc00fc01;
7128 content
= (content
& 0xfc00fc01) | (value
& 0x3fe) | ((value
<< 6) & 0x3ff0000);
7129 s3_md_number_to_chars (buf
, content
, s3_INSN_SIZE
);
7132 case BFD_RELOC_SCORE16_JMP
:
7133 content
= s3_md_chars_to_number (buf
, s3_INSN16_SIZE
);
7135 value
= fixP
->fx_offset
& 0xfff;
7136 content
= (content
& 0xfc01) | (value
& 0xffe);
7137 s3_md_number_to_chars (buf
, content
, s3_INSN16_SIZE
);
7139 case BFD_RELOC_SCORE16_BRANCH
:
7140 content
= s3_md_chars_to_number (buf
, s3_INSN_SIZE
);
7141 /* Don't check c-bit. */
7142 if (fixP
->fx_frag
->fr_opcode
!= 0)
7144 if ((S_GET_SEGMENT (fixP
->fx_addsy
) != seg
) ||
7145 (fixP
->fx_addsy
!= NULL
&& S_IS_EXTERNAL (fixP
->fx_addsy
)))
7146 value
= fixP
->fx_offset
;
7149 if ((value
& 0xfff80000) != 0 && (value
& 0xfff80000) != 0xfff80000)
7151 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7152 _(" branch relocation truncate (0x%x) [-2^19 ~ 2^19-1]"), (unsigned int) value
);
7155 content
= s3_md_chars_to_number (buf
, s3_INSN_SIZE
);
7156 content
= (content
& 0xfc00fc01) | (value
& 0x3fe) | ((value
<< 6) & 0x3ff0000);
7157 s3_md_number_to_chars (buf
, content
, s3_INSN_SIZE
);
7158 fixP
->fx_r_type
= BFD_RELOC_SCORE_BRANCH
;
7164 /* In different section. */
7165 if ((S_GET_SEGMENT (fixP
->fx_addsy
) != seg
) ||
7166 (fixP
->fx_addsy
!= NULL
&& S_IS_EXTERNAL (fixP
->fx_addsy
)))
7167 value
= fixP
->fx_offset
;
7171 if ((value
& 0xfffffe00) != 0 && (value
& 0xfffffe00) != 0xfffffe00)
7173 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7174 _(" branch relocation truncate (0x%x) [-2^9 ~ 2^9-1]"), (unsigned int) value
);
7178 content
= s3_md_chars_to_number (buf
, s3_INSN16_SIZE
);
7179 content
= (content
& 0xfe00) | ((value
>> 1) & 0x1ff);
7180 s3_md_number_to_chars (buf
, content
, s3_INSN16_SIZE
);
7186 case BFD_RELOC_SCORE_BCMP
:
7187 if (fixP
->fx_frag
->fr_opcode
!= 0)
7189 char *buf_ptr
= buf
;
7192 if ((S_GET_SEGMENT (fixP
->fx_addsy
) != seg
) || (fixP
->fx_addsy
!= NULL
&& S_IS_EXTERNAL (fixP
->fx_addsy
)))
7193 value
= fixP
->fx_offset
;
7198 bcmp -> cmp! and branch, so value -= 2. */
7201 if ((value
& 0xfff80000) != 0 && (value
& 0xfff80000) != 0xfff80000)
7203 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7204 _(" branch relocation truncate (0x%x) [-2^19 ~ 2^19-1]"), (unsigned int) value
);
7208 content
= s3_md_chars_to_number (buf_ptr
, s3_INSN_SIZE
);
7209 content
&= 0xfc00fc01;
7210 content
= (content
& 0xfc00fc01) | (value
& 0x3fe) | ((value
<< 6) & 0x3ff0000);
7211 s3_md_number_to_chars (buf_ptr
, content
, s3_INSN_SIZE
);
7212 /* change relocation type to BFD_RELOC_SCORE_BRANCH */
7213 fixP
->fx_r_type
= BFD_RELOC_SCORE_BRANCH
;
7214 fixP
->fx_where
+=2; /* first insn is cmp! , the second insn is beq/bne */
7219 if ((S_GET_SEGMENT (fixP
->fx_addsy
) != seg
) || (fixP
->fx_addsy
!= NULL
&& S_IS_EXTERNAL (fixP
->fx_addsy
)))
7220 value
= fixP
->fx_offset
;
7224 content
= s3_md_chars_to_number (buf
, s3_INSN_SIZE
);
7226 if ((value
& 0xfffffe00) != 0 && (value
& 0xfffffe00) != 0xfffffe00)
7228 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7229 _(" branch relocation truncate (0x%x) [-2^9 ~ 2^9-1]"), (unsigned int) value
);
7234 content
&= ~0x03e00381;
7237 | (((value
& 0xe) >> 1) << 7)
7238 | (((value
& 0x1f0) >> 4) << 21);
7240 s3_md_number_to_chars (buf
, content
, s3_INSN_SIZE
);
7245 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
7246 s3_md_number_to_chars (buf
, value
, 1);
7250 value
= fixP
->fx_offset
;
7251 s3_md_number_to_chars (buf
, value
, 1);
7257 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
7258 s3_md_number_to_chars (buf
, value
, 2);
7262 value
= fixP
->fx_offset
;
7263 s3_md_number_to_chars (buf
, value
, 2);
7269 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
7270 md_number_to_chars (buf
, value
, 4);
7274 value
= fixP
->fx_offset
;
7275 md_number_to_chars (buf
, value
, 4);
7279 case BFD_RELOC_VTABLE_INHERIT
:
7281 if (fixP
->fx_addsy
&& !S_IS_DEFINED (fixP
->fx_addsy
) && !S_IS_WEAK (fixP
->fx_addsy
))
7282 S_SET_WEAK (fixP
->fx_addsy
);
7284 case BFD_RELOC_VTABLE_ENTRY
:
7287 case BFD_RELOC_SCORE_GPREL15
:
7288 content
= s3_md_chars_to_number (buf
, s3_INSN_SIZE
);
7290 if ((fixP
->fx_frag
->fr_opcode
!= 0) && ((content
& 0xfc1c8000) != 0x94180000))
7291 fixP
->fx_r_type
= BFD_RELOC_NONE
;
7294 case BFD_RELOC_SCORE_GOT15
:
7295 case BFD_RELOC_SCORE_DUMMY_HI16
:
7296 case BFD_RELOC_SCORE_GOT_LO16
:
7297 case BFD_RELOC_SCORE_CALL15
:
7298 case BFD_RELOC_GPREL32
:
7300 case BFD_RELOC_NONE
:
7302 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("bad relocation fixup type (%d)"), fixP
->fx_r_type
);
7307 s3_gen_reloc (asection
* section ATTRIBUTE_UNUSED
, fixS
* fixp
)
7309 static arelent
*retval
[MAX_RELOC_EXPANSION
+ 1]; /* MAX_RELOC_EXPANSION equals 2. */
7311 bfd_reloc_code_real_type code
;
7314 reloc
= notes_alloc (sizeof (arelent
));
7315 reloc
->sym_ptr_ptr
= notes_alloc (sizeof (asymbol
*));
7318 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
7319 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
7320 reloc
->addend
= fixp
->fx_offset
;
7322 /* If this is a variant frag, we may need to adjust the existing
7323 reloc and generate a new one. */
7324 if (fixp
->fx_frag
->fr_opcode
!= NULL
&& (fixp
->fx_r_type
== BFD_RELOC_SCORE_GPREL15
))
7326 /* Update instruction imm bit. */
7331 buf
= fixp
->fx_frag
->fr_literal
+ fixp
->fx_frag
->insn_addr
;
7332 newval
= s3_md_chars_to_number (buf
, s3_INSN_SIZE
);
7333 off
= fixp
->fx_offset
>> 16;
7334 newval
|= (off
& 0x3fff) << 1;
7335 newval
|= ((off
>> 14) & 0x3) << 16;
7336 s3_md_number_to_chars (buf
, newval
, s3_INSN_SIZE
);
7338 buf
+= s3_INSN_SIZE
;
7339 newval
= s3_md_chars_to_number (buf
, s3_INSN_SIZE
);
7340 off
= fixp
->fx_offset
& 0xffff;
7341 newval
|= ((off
& 0x3fff) << 1);
7342 newval
|= (((off
>> 14) & 0x3) << 16);
7343 s3_md_number_to_chars (buf
, newval
, s3_INSN_SIZE
);
7345 retval
[1] = notes_alloc (sizeof (arelent
));
7346 retval
[1]->sym_ptr_ptr
= notes_alloc (sizeof (asymbol
*));
7348 *retval
[1]->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
7349 retval
[1]->address
= (reloc
->address
+ s3_RELAX_RELOC2 (fixp
->fx_frag
->fr_subtype
));
7351 retval
[1]->addend
= 0;
7352 retval
[1]->howto
= bfd_reloc_type_lookup (stdoutput
, BFD_RELOC_LO16
);
7353 gas_assert (retval
[1]->howto
!= NULL
);
7355 fixp
->fx_r_type
= BFD_RELOC_HI16_S
;
7358 code
= fixp
->fx_r_type
;
7359 switch (fixp
->fx_r_type
)
7364 code
= BFD_RELOC_32_PCREL
;
7368 case BFD_RELOC_HI16_S
:
7369 case BFD_RELOC_LO16
:
7370 case BFD_RELOC_SCORE_JMP
:
7371 case BFD_RELOC_SCORE_BRANCH
:
7372 case BFD_RELOC_SCORE16_JMP
:
7373 case BFD_RELOC_SCORE16_BRANCH
:
7374 case BFD_RELOC_SCORE_BCMP
:
7375 case BFD_RELOC_VTABLE_ENTRY
:
7376 case BFD_RELOC_VTABLE_INHERIT
:
7377 case BFD_RELOC_SCORE_GPREL15
:
7378 case BFD_RELOC_SCORE_GOT15
:
7379 case BFD_RELOC_SCORE_DUMMY_HI16
:
7380 case BFD_RELOC_SCORE_GOT_LO16
:
7381 case BFD_RELOC_SCORE_CALL15
:
7382 case BFD_RELOC_GPREL32
:
7383 case BFD_RELOC_NONE
:
7384 case BFD_RELOC_SCORE_IMM30
:
7385 case BFD_RELOC_SCORE_IMM32
:
7386 code
= fixp
->fx_r_type
;
7389 type
= _("<unknown>");
7390 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
7391 _("cannot represent %s relocation in this object file format"), type
);
7395 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
7396 if (reloc
->howto
== NULL
)
7398 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
7399 _("cannot represent %s relocation in this object file format1"),
7400 bfd_get_reloc_code_name (code
));
7403 /* HACK: Since arm ELF uses Rel instead of Rela, encode the
7404 vtable entry to be used in the relocation's section offset. */
7405 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
7406 reloc
->address
= fixp
->fx_offset
;
7412 md_assemble (char *str
)
7420 /* We handle all bad expressions here, so that we can report the faulty
7421 instruction in the error message. */
7423 md_operand (expressionS
* exp
)
7431 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
7432 for use in the a.out file, and stores them in the array pointed to by buf.
7433 This knows about the endian-ness of the target machine and does
7434 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
7435 2 (short) and 4 (long) Floating numbers are put out as a series of
7436 LITTLENUMS (shorts, here at least). */
7438 md_number_to_chars (char *buf
, valueT val
, int n
)
7441 s3_number_to_chars (buf
, val
, n
);
7443 s7_number_to_chars (buf
, val
, n
);
7446 /* Turn a string in input_line_pointer into a floating point constant
7447 of type TYPE, and store the appropriate bytes in *LITP. The number
7448 of LITTLENUMS emitted is stored in *SIZEP. An error message is
7449 returned, or NULL on OK.
7451 Note that fp constants aren't represent in the normal way on the ARM.
7452 In big endian mode, things are as expected. However, in little endian
7453 mode fp constants are big-endian word-wise, and little-endian byte-wise
7454 within the words. For example, (double) 1.1 in big endian mode is
7455 the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
7456 the byte sequence 99 99 f1 3f 9a 99 99 99. */
7458 md_atof (int type
, char *litP
, int *sizeP
)
7461 return s3_atof (type
, litP
, sizeP
);
7463 return s7_atof (type
, litP
, sizeP
);
7467 score_frag_check (fragS
* fragp ATTRIBUTE_UNUSED
)
7470 s3_frag_check (fragp
);
7472 s7_frag_check (fragp
);
7475 /* Implementation of TC_VALIDATE_FIX.
7476 Called before md_apply_fix() and after md_convert_frag(). */
7478 score_validate_fix (fixS
*fixP
)
7481 s3_validate_fix (fixP
);
7483 s7_validate_fix (fixP
);
7487 score_force_relocation (struct fix
*fixp
)
7490 return s3_force_relocation (fixp
);
7492 return s7_force_relocation (fixp
);
7495 /* Implementation of md_frag_check.
7496 Called after md_convert_frag(). */
7498 score_fix_adjustable (fixS
* fixP
)
7501 return s3_fix_adjustable (fixP
);
7503 return s7_fix_adjustable (fixP
);
7507 score_elf_final_processing (void)
7510 s3_elf_final_processing ();
7512 s7_elf_final_processing ();
7515 /* In this function, we determine whether s3_GP instruction should do relaxation,
7516 for the label being against was known now.
7517 Doing this here but not in md_relax_frag() can induce iteration times
7518 in stage of doing relax. */
7520 md_estimate_size_before_relax (fragS
* fragp
, asection
* sec ATTRIBUTE_UNUSED
)
7523 return s3_estimate_size_before_relax (fragp
, sec
);
7525 return s7_estimate_size_before_relax (fragp
, sec
);
7529 score_relax_frag (asection
* sec ATTRIBUTE_UNUSED
, fragS
* fragp
, long stretch ATTRIBUTE_UNUSED
)
7532 return s3_relax_frag (sec
, fragp
, stretch
);
7534 return s7_relax_frag (sec
, fragp
, stretch
);
7538 md_convert_frag (bfd
* abfd ATTRIBUTE_UNUSED
, segT sec ATTRIBUTE_UNUSED
, fragS
* fragp
)
7541 return s3_convert_frag (abfd
, sec
, fragp
);
7543 return s7_convert_frag (abfd
, sec
, fragp
);
7547 md_pcrel_from (fixS
* fixP
)
7550 return s3_pcrel_from (fixP
);
7552 return s7_pcrel_from (fixP
);
7555 /* Round up a section size to the appropriate boundary. */
7557 md_section_align (segT segment ATTRIBUTE_UNUSED
, valueT size
)
7560 return s3_section_align (segment
, size
);
7562 return s7_section_align (segment
, size
);
7566 md_apply_fix (fixS
*fixP
, valueT
*valP
, segT seg
)
7569 return s3_apply_fix (fixP
, valP
, seg
);
7571 return s7_apply_fix (fixP
, valP
, seg
);
7574 /* Translate internal representation of relocation info to BFD target format. */
7576 tc_gen_reloc (asection
* section ATTRIBUTE_UNUSED
, fixS
* fixp
)
7579 return s3_gen_reloc (section
, fixp
);
7581 return s7_gen_reloc (section
, fixp
);
7592 score_set_mach (const char *arg
)
7594 if (strcmp (arg
, MARCH_SCORE3
) == 0)
7600 else if (strcmp (arg
, MARCH_SCORE7
) == 0)
7605 s7_university_version
= 0;
7606 s7_vector_size
= s7_SCORE7_PIPELINE
;
7608 else if (strcmp (arg
, MARCH_SCORE5
) == 0)
7613 s7_university_version
= 0;
7614 s7_vector_size
= s7_SCORE5_PIPELINE
;
7616 else if (strcmp (arg
, MARCH_SCORE5U
) == 0)
7621 s7_university_version
= 1;
7622 s7_vector_size
= s7_SCORE5_PIPELINE
;
7626 as_bad (_("unknown architecture `%s'\n"), arg
);
7631 md_parse_option (int c
, const char *arg
)
7637 target_big_endian
= 1;
7642 target_big_endian
= 0;
7646 s3_fix_data_dependency
= 1;
7647 s7_fix_data_dependency
= 1;
7650 s3_warn_fix_data_dependency
= 0;
7651 s7_warn_fix_data_dependency
= 0;
7656 s7_university_version
= 0;
7657 s7_vector_size
= s7_SCORE5_PIPELINE
;
7659 case OPTION_SCORE5U
:
7662 s7_university_version
= 1;
7663 s7_vector_size
= s7_SCORE5_PIPELINE
;
7669 s7_university_version
= 0;
7670 s7_vector_size
= s7_SCORE7_PIPELINE
;
7682 s3_g_switch_value
= atoi (arg
);
7683 s7_g_switch_value
= atoi (arg
);
7689 case OPTION_SCORE_VERSION
:
7690 printf (_("Sunplus-v2-0-0-20060510\n"));
7693 s3_score_pic
= s3_NO_PIC
; /* Score3 doesn't support PIC now. */
7694 s7_score_pic
= s7_PIC
;
7695 s3_g_switch_value
= 0; /* Must set -G num as 0 to generate s3_PIC code. */
7696 s7_g_switch_value
= 0; /* Must set -G num as 0 to generate s7_PIC code. */
7699 score_set_mach (arg
);
7708 md_show_usage (FILE * fp
)
7710 fprintf (fp
, _(" Score-specific assembler options:\n"));
7713 -EB\t\tassemble code for a big-endian cpu\n"));
7718 -EL\t\tassemble code for a little-endian cpu\n"));
7722 -FIXDD\t\tfix data dependencies\n"));
7724 -NWARN\t\tdo not print warning message when fixing data dependencies\n"));
7726 -SCORE5\t\tassemble code for target SCORE5\n"));
7728 -SCORE5U\tassemble code for target SCORE5U\n"));
7730 -SCORE7\t\tassemble code for target SCORE7 [default]\n"));
7732 -SCORE3\t\tassemble code for target SCORE3\n"));
7734 -march=score7\tassemble code for target SCORE7 [default]\n"));
7736 -march=score3\tassemble code for target SCORE3\n"));
7738 -USE_R1\t\tassemble code for no warning message when using temp register r1\n"));
7740 -KPIC\t\tgenerate PIC\n"));
7742 -O0\t\tdo not perform any optimizations\n"));
7744 -G gpnum\tassemble code for setting gpsize, default is 8 bytes\n"));
7746 -V \t\tSunplus release version\n"));