1 /* tc-score.c -- Assembler for Score
2 Copyright (C) 2006-2020 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_s_score_bss (int ignore ATTRIBUTE_UNUSED
);
28 static void s3_s_score_text (int ignore
);
29 static void s3_score_s_section (int ignore
);
30 static void s3_s_change_sec (int sec
);
31 static void s3_s_score_mask (int reg_type ATTRIBUTE_UNUSED
);
32 static void s3_s_score_ent (int aent
);
33 static void s3_s_score_frame (int ignore ATTRIBUTE_UNUSED
);
34 static void s3_s_score_end (int x ATTRIBUTE_UNUSED
);
35 static void s3_s_score_set (int x ATTRIBUTE_UNUSED
);
36 static void s3_s_score_cpload (int ignore ATTRIBUTE_UNUSED
);
37 static void s3_s_score_cprestore (int ignore ATTRIBUTE_UNUSED
);
38 static void s3_s_score_gpword (int ignore ATTRIBUTE_UNUSED
);
39 static void s3_s_score_cpadd (int ignore ATTRIBUTE_UNUSED
);
40 static void s3_s_score_lcomm (int bytes_p
);
42 static void s_score_bss (int ignore ATTRIBUTE_UNUSED
);
43 static void s_score_text (int ignore
);
44 static void s_section (int ignore
);
45 static void s_change_sec (int sec
);
46 static void s_score_mask (int reg_type ATTRIBUTE_UNUSED
);
47 static void s_score_ent (int aent
);
48 static void s_score_frame (int ignore ATTRIBUTE_UNUSED
);
49 static void s_score_end (int x ATTRIBUTE_UNUSED
);
50 static void s_score_set (int x ATTRIBUTE_UNUSED
);
51 static void s_score_cpload (int ignore ATTRIBUTE_UNUSED
);
52 static void s_score_cprestore (int ignore ATTRIBUTE_UNUSED
);
53 static void s_score_gpword (int ignore ATTRIBUTE_UNUSED
);
54 static void s_score_cpadd (int ignore ATTRIBUTE_UNUSED
);
55 static void s_score_lcomm (int bytes_p
);
58 static void s3_md_number_to_chars (char *buf
, valueT val
, int n
);
59 static valueT
s3_md_chars_to_number (char *buf
, int n
);
60 static void s3_assemble (char *str
);
61 static void s3_operand (expressionS
*);
62 static void s3_begin (void);
63 static void s3_number_to_chars (char *buf
, valueT val
, int n
);
64 static const char *s3_atof (int type
, char *litP
, int *sizeP
);
65 static void s3_frag_check (fragS
* fragp ATTRIBUTE_UNUSED
);
66 static void s3_validate_fix (fixS
*fixP
);
67 static int s3_force_relocation (struct fix
*fixp
);
68 static bfd_boolean
s3_fix_adjustable (fixS
* fixP
);
69 static void s3_elf_final_processing (void);
70 static int s3_estimate_size_before_relax (fragS
* fragp
, asection
* sec ATTRIBUTE_UNUSED
);
71 static int s3_relax_frag (asection
* sec ATTRIBUTE_UNUSED
, fragS
* fragp
, long stretch ATTRIBUTE_UNUSED
);
72 static void s3_convert_frag (bfd
* abfd ATTRIBUTE_UNUSED
, segT sec ATTRIBUTE_UNUSED
, fragS
* fragp
);
73 static long s3_pcrel_from (fixS
* fixP
);
74 static valueT
s3_section_align (segT segment ATTRIBUTE_UNUSED
, valueT size
);
75 static void s3_apply_fix (fixS
*fixP
, valueT
*valP
, segT seg
);
76 static arelent
**s3_gen_reloc (asection
* section ATTRIBUTE_UNUSED
, fixS
* fixp
);
79 static void s3_do_ldst_insn (char *);
80 static void s3_do_crdcrscrsimm5 (char *);
81 static void s3_do_ldst_unalign (char *);
82 static void s3_do_ldst_atomic (char *);
83 static void s3_do_ldst_cop (char *);
84 static void s3_do_macro_li_rdi32 (char *);
85 static void s3_do_macro_la_rdi32 (char *);
86 static void s3_do_macro_rdi32hi (char *);
87 static void s3_do_macro_rdi32lo (char *);
88 static void s3_do_macro_mul_rdrsrs (char *);
89 static void s3_do_macro_bcmp (char *);
90 static void s3_do_macro_bcmpz (char *);
91 static void s3_do_macro_ldst_label (char *);
92 static void s3_do_branch (char *);
93 static void s3_do_jump (char *);
94 static void s3_do_empty (char *);
95 static void s3_do16_int (char *);
96 static void s3_do_rdrsrs (char *);
97 static void s3_do_rdsi16 (char *);
98 static void s3_do_rdrssi14 (char *);
99 static void s3_do_sub_rdsi16 (char *);
100 static void s3_do_sub_rdi16 (char *);
101 static void s3_do_sub_rdrssi14 (char *);
102 static void s3_do_rdrsi5 (char *);
103 static void s3_do_rdrsi14 (char *);
104 static void s3_do_rdi16 (char *);
105 static void s3_do_ldis (char *);
106 static void s3_do_xrsi5 (char *);
107 static void s3_do_rdrs (char *);
108 static void s3_do_rdxrs (char *);
109 static void s3_do_rsrs (char *);
110 static void s3_do_rdcrs (char *);
111 static void s3_do_rdsrs (char *);
112 static void s3_do_rd (char *);
113 static void s3_do16_dsp (char *);
114 static void s3_do16_dsp2 (char *);
115 static void s3_do_dsp (char *);
116 static void s3_do_dsp2 (char *);
117 static void s3_do_dsp3 (char *);
118 static void s3_do_rs (char *);
119 static void s3_do_i15 (char *);
120 static void s3_do_xi5x (char *);
121 static void s3_do_ceinst (char *);
122 static void s3_do_cache (char *);
123 static void s3_do16_rdrs2 (char *);
124 static void s3_do16_br (char *);
125 static void s3_do16_brr (char *);
126 static void s3_do_ltb (char *);
127 static void s3_do16_mv_cmp (char *);
128 static void s3_do16_addi (char *);
129 static void s3_do16_cmpi (char *);
130 static void s3_do16_rdi5 (char *);
131 static void s3_do16_xi5 (char *);
132 static void s3_do16_ldst_insn (char *);
133 static void s3_do16_slli_srli (char *);
134 static void s3_do16_ldiu (char *);
135 static void s3_do16_push_pop (char *);
136 static void s3_do16_rpush (char *);
137 static void s3_do16_rpop (char *);
138 static void s3_do16_branch (char *);
139 static void s3_do_lw48 (char *);
140 static void s3_do_sw48 (char *);
141 static void s3_do_ldi48 (char *);
142 static void s3_do_sdbbp48 (char *);
143 static void s3_do_and48 (char *);
144 static void s3_do_or48 (char *);
145 static void s3_do_mbitclr (char *);
146 static void s3_do_mbitset (char *);
147 static void s3_do_rdi16_pic (char *);
148 static void s3_do_addi_s_pic (char *);
149 static void s3_do_addi_u_pic (char *);
150 static void s3_do_lw_pic (char *);
152 #define MARCH_SCORE3 "score3"
153 #define MARCH_SCORE3D "score3d"
154 #define MARCH_SCORE7 "score7"
155 #define MARCH_SCORE7D "score7d"
156 #define MARCH_SCORE5 "score5"
157 #define MARCH_SCORE5U "score5u"
159 #define SCORE_BI_ENDIAN
161 #ifdef SCORE_BI_ENDIAN
162 #define OPTION_EB (OPTION_MD_BASE + 0)
163 #define OPTION_EL (OPTION_MD_BASE + 1)
165 #if TARGET_BYTES_BIG_ENDIAN
166 #define OPTION_EB (OPTION_MD_BASE + 0)
168 #define OPTION_EL (OPTION_MD_BASE + 1)
171 #define OPTION_FIXDD (OPTION_MD_BASE + 2)
172 #define OPTION_NWARN (OPTION_MD_BASE + 3)
173 #define OPTION_SCORE5 (OPTION_MD_BASE + 4)
174 #define OPTION_SCORE5U (OPTION_MD_BASE + 5)
175 #define OPTION_SCORE7 (OPTION_MD_BASE + 6)
176 #define OPTION_R1 (OPTION_MD_BASE + 7)
177 #define OPTION_O0 (OPTION_MD_BASE + 8)
178 #define OPTION_SCORE_VERSION (OPTION_MD_BASE + 9)
179 #define OPTION_PIC (OPTION_MD_BASE + 10)
180 #define OPTION_MARCH (OPTION_MD_BASE + 11)
181 #define OPTION_SCORE3 (OPTION_MD_BASE + 12)
183 /* This array holds the chars that always start a comment. If the
184 pre-processor is disabled, these aren't very useful. */
185 const char comment_chars
[] = "#";
186 const char line_comment_chars
[] = "#";
187 const char line_separator_chars
[] = ";";
188 /* Chars that can be used to separate mant from exp in floating point numbers. */
189 const char EXP_CHARS
[] = "eE";
190 const char FLT_CHARS
[] = "rRsSfFdDxXeEpP";
193 /* Pre-defined "_GLOBAL_OFFSET_TABLE_" */
197 const pseudo_typeS md_pseudo_table
[] =
199 {"bss", s_score_bss
, 0},
200 {"text", s_score_text
, 0},
203 {"extend", float_cons
, 'x'},
204 {"ldouble", float_cons
, 'x'},
205 {"packed", float_cons
, 'p'},
206 {"end", s_score_end
, 0},
207 {"ent", s_score_ent
, 0},
208 {"frame", s_score_frame
, 0},
209 {"rdata", s_change_sec
, 'r'},
210 {"sdata", s_change_sec
, 's'},
211 {"set", s_score_set
, 0},
212 {"mask", s_score_mask
, 'R'},
214 {"lcomm", s_score_lcomm
, 1},
215 {"section", s_section
, 0},
216 {"cpload", s_score_cpload
, 0},
217 {"cprestore", s_score_cprestore
, 0},
218 {"gpword", s_score_gpword
, 0},
219 {"cpadd", s_score_cpadd
, 0},
223 const char *md_shortopts
= "nO::g::G:";
224 struct option md_longopts
[] =
227 {"EB" , no_argument
, NULL
, OPTION_EB
},
230 {"EL" , no_argument
, NULL
, OPTION_EL
},
232 {"FIXDD" , no_argument
, NULL
, OPTION_FIXDD
},
233 {"NWARN" , no_argument
, NULL
, OPTION_NWARN
},
234 {"SCORE5" , no_argument
, NULL
, OPTION_SCORE5
},
235 {"SCORE5U", no_argument
, NULL
, OPTION_SCORE5U
},
236 {"SCORE7" , no_argument
, NULL
, OPTION_SCORE7
},
237 {"USE_R1" , no_argument
, NULL
, OPTION_R1
},
238 {"O0" , no_argument
, NULL
, OPTION_O0
},
239 {"V" , no_argument
, NULL
, OPTION_SCORE_VERSION
},
240 {"KPIC" , no_argument
, NULL
, OPTION_PIC
},
241 {"march=" , required_argument
, NULL
, OPTION_MARCH
},
242 {"SCORE3" , no_argument
, NULL
, OPTION_SCORE3
},
243 {NULL
, no_argument
, NULL
, 0}
246 size_t md_longopts_size
= sizeof (md_longopts
);
249 #define s3_PIC_CALL_REG 29
250 #define s3_MAX_LITERAL_POOL_SIZE 1024
251 #define s3_FAIL 0x80000000
253 #define s3_INSN48_SIZE 6
254 #define s3_INSN_SIZE 4
255 #define s3_INSN16_SIZE 2
256 #define s3_RELAX_INST_NUM 3
258 /* For score5u : div/mul will pop warning message, mmu/alw/asw will pop error message. */
259 #define s3_BAD_ARGS _("bad arguments to instruction")
260 #define s3_ERR_FOR_SCORE5U_MUL_DIV _("div / mul are reserved instructions")
261 #define s3_ERR_FOR_SCORE5U_MMU _("This architecture doesn't support mmu")
262 #define s3_ERR_FOR_SCORE5U_ATOMIC _("This architecture doesn't support atomic instruction")
263 #define s3_BAD_SKIP_COMMA s3_BAD_ARGS
264 #define s3_BAD_GARBAGE _("garbage following instruction");
266 #define s3_skip_whitespace(str) while (*(str) == ' ') ++(str)
268 /* The name of the readonly data section. */
269 #define s3_RDATA_SECTION_NAME (OUTPUT_FLAVOR == bfd_target_aout_flavour \
271 : OUTPUT_FLAVOR == bfd_target_ecoff_flavour \
273 : OUTPUT_FLAVOR == bfd_target_coff_flavour \
275 : OUTPUT_FLAVOR == bfd_target_elf_flavour \
279 #define s3_RELAX_ENCODE(old, new, type, reloc1, reloc2, opt) \
288 #define s3_RELAX_OLD(i) (((i) >> 23) & 0x7f)
289 #define s3_RELAX_NEW(i) (((i) >> 16) & 0x7f)
290 #define s3_RELAX_TYPE(i) (((i) >> 9) & 0x7f)
291 #define s3_RELAX_RELOC1(i) ((valueT) ((i) >> 5) & 0xf)
292 #define s3_RELAX_RELOC2(i) ((valueT) ((i) >> 1) & 0xf)
293 #define s3_RELAX_OPT(i) ((i) & 1)
295 #define s3_SET_INSN_ERROR(s) (s3_inst.error = (s))
296 #define s3_INSN_IS_PCE_P(s) (strstr (str, "||") != NULL)
297 #define s3_INSN_IS_48_P(s) (strstr (str, "48") != NULL)
298 #define s3_GET_INSN_CLASS(type) (s3_get_insn_class_from_type (type))
299 #define s3_GET_INSN_SIZE(type) ((s3_GET_INSN_CLASS (type) == INSN_CLASS_16) \
300 ? s3_INSN16_SIZE : (s3_GET_INSN_CLASS (type) == INSN_CLASS_48) \
301 ? s3_INSN48_SIZE : s3_INSN_SIZE)
303 #define s3_INSN_NAME_LEN 16
305 /* Relax will need some padding for alignment. */
306 #define s3_RELAX_PAD_BYTE 3
309 #define s3_USE_GLOBAL_POINTER_OPT 1
311 /* Enumeration matching entries in table above. */
312 enum s3_score_reg_type
314 s3_REG_TYPE_SCORE
= 0,
315 #define s3_REG_TYPE_FIRST s3_REG_TYPE_SCORE
316 s3_REG_TYPE_SCORE_SR
= 1,
317 s3_REG_TYPE_SCORE_CR
= 2,
321 enum s3_score_pic_level
326 static enum s3_score_pic_level s3_score_pic
= s3_NO_PIC
;
328 enum s3_insn_type_for_dependency
334 struct s3_insn_to_dependency
336 const char *insn_name
;
337 enum s3_insn_type_for_dependency type
;
340 struct s3_data_dependency
342 enum s3_insn_type_for_dependency pre_insn_type
;
344 enum s3_insn_type_for_dependency cur_insn_type
;
348 int warn_or_error
; /* warning - 0; error - 1 */
351 static const struct s3_insn_to_dependency s3_insn_to_dependency_table
[] =
353 /* move special instruction. */
357 static const struct s3_data_dependency s3_data_dependency_table
[] =
359 /* Status register. */
360 {s3_D_mtcr
, "cr0", s3_D_all_insn
, "", 5, 1, 0},
363 /* Used to contain constructed error messages. */
364 static char s3_err_msg
[255];
366 static int s3_fix_data_dependency
= 0;
367 static int s3_warn_fix_data_dependency
= 1;
369 static int s3_in_my_get_expression
= 0;
371 /* Default, pop warning message when using r1. */
372 static int s3_nor1
= 1;
374 /* Default will do instruction relax, -O0 will set s3_g_opt = 0. */
375 static unsigned int s3_g_opt
= 1;
377 /* The size of the small data section. */
378 static unsigned int s3_g_switch_value
= 8;
380 static segT s3_pdr_seg
;
384 char name
[s3_INSN_NAME_LEN
];
389 enum score_insn_type type
;
390 char str
[s3_MAX_LITERAL_POOL_SIZE
];
393 char reg
[s3_INSN_NAME_LEN
];
396 bfd_reloc_code_real_type type
;
401 static struct s3_score_it s3_inst
;
403 typedef struct s3_proc
406 unsigned long reg_mask
;
407 unsigned long reg_offset
;
408 unsigned long fpreg_mask
;
410 unsigned long frame_offset
;
411 unsigned long frame_reg
;
412 unsigned long pc_reg
;
414 static s3_procS s3_cur_proc
;
415 static s3_procS
*s3_cur_proc_ptr
;
416 static int s3_numprocs
;
419 /* Structure for a hash table entry for a register. */
426 static const struct s3_reg_entry s3_score_rn_table
[] =
428 {"r0", 0}, {"r1", 1}, {"r2", 2}, {"r3", 3},
429 {"r4", 4}, {"r5", 5}, {"r6", 6}, {"r7", 7},
430 {"r8", 8}, {"r9", 9}, {"r10", 10}, {"r11", 11},
431 {"r12", 12}, {"r13", 13}, {"r14", 14}, {"r15", 15},
432 {"r16", 16}, {"r17", 17}, {"r18", 18}, {"r19", 19},
433 {"r20", 20}, {"r21", 21}, {"r22", 22}, {"r23", 23},
434 {"r24", 24}, {"r25", 25}, {"r26", 26}, {"r27", 27},
435 {"r28", 28}, {"r29", 29}, {"r30", 30}, {"r31", 31},
439 static const struct s3_reg_entry s3_score_srn_table
[] =
441 {"sr0", 0}, {"sr1", 1}, {"sr2", 2},
445 static const struct s3_reg_entry s3_score_crn_table
[] =
447 {"cr0", 0}, {"cr1", 1}, {"cr2", 2}, {"cr3", 3},
448 {"cr4", 4}, {"cr5", 5}, {"cr6", 6}, {"cr7", 7},
449 {"cr8", 8}, {"cr9", 9}, {"cr10", 10}, {"cr11", 11},
450 {"cr12", 12}, {"cr13", 13}, {"cr14", 14}, {"cr15", 15},
451 {"cr16", 16}, {"cr17", 17}, {"cr18", 18}, {"cr19", 19},
452 {"cr20", 20}, {"cr21", 21}, {"cr22", 22}, {"cr23", 23},
453 {"cr24", 24}, {"cr25", 25}, {"cr26", 26}, {"cr27", 27},
454 {"cr28", 28}, {"cr29", 29}, {"cr30", 30}, {"cr31", 31},
460 const struct s3_reg_entry
*names
;
463 const char *expected
;
466 static struct s3_reg_map s3_all_reg_maps
[] =
468 {s3_score_rn_table
, 31, NULL
, N_("S+core register expected")},
469 {s3_score_srn_table
, 2, NULL
, N_("S+core special-register expected")},
470 {s3_score_crn_table
, 31, NULL
, N_("S+core co-processor register expected")},
473 static htab_t s3_score_ops_hsh
= NULL
;
474 static htab_t s3_dependency_insn_hsh
= NULL
;
477 struct s3_datafield_range
484 static struct s3_datafield_range s3_score_df_range
[] =
486 {_IMM4
, 4, {0, (1 << 4) - 1}}, /* ( 0 ~ 15 ) */
487 {_IMM5
, 5, {0, (1 << 5) - 1}}, /* ( 0 ~ 31 ) */
488 {_IMM8
, 8, {0, (1 << 8) - 1}}, /* ( 0 ~ 255 ) */
489 {_IMM14
, 14, {0, (1 << 14) - 1}}, /* ( 0 ~ 16383) */
490 {_IMM15
, 15, {0, (1 << 15) - 1}}, /* ( 0 ~ 32767) */
491 {_IMM16
, 16, {0, (1 << 16) - 1}}, /* ( 0 ~ 65535) */
492 {_SIMM10
, 10, {-(1 << 9), (1 << 9) - 1}}, /* ( -512 ~ 511 ) */
493 {_SIMM12
, 12, {-(1 << 11), (1 << 11) - 1}}, /* ( -2048 ~ 2047 ) */
494 {_SIMM14
, 14, {-(1 << 13), (1 << 13) - 1}}, /* ( -8192 ~ 8191 ) */
495 {_SIMM15
, 15, {-(1 << 14), (1 << 14) - 1}}, /* (-16384 ~ 16383) */
496 {_SIMM16
, 16, {-(1 << 15), (1 << 15) - 1}}, /* (-32768 ~ 32767) */
497 {_SIMM14_NEG
, 14, {-(1 << 13), (1 << 13) - 1}}, /* ( -8191 ~ 8192 ) */
498 {_IMM16_NEG
, 16, {0, (1 << 16) - 1}}, /* (-65535 ~ 0 ) */
499 {_SIMM16_NEG
, 16, {-(1 << 15), (1 << 15) - 1}}, /* (-32768 ~ 32767) */
500 {_IMM20
, 20, {0, (1 << 20) - 1}},
501 {_IMM25
, 25, {0, (1 << 25) - 1}},
502 {_DISP8div2
, 8, {-(1 << 8), (1 << 8) - 1}}, /* ( -256 ~ 255 ) */
503 {_DISP11div2
, 11, {0, 0}},
504 {_DISP19div2
, 19, {-(1 << 19), (1 << 19) - 1}}, /* (-524288 ~ 524287) */
505 {_DISP24div2
, 24, {0, 0}},
506 {_VALUE
, 32, {0, ((unsigned int)1 << 31) - 1}},
507 {_VALUE_HI16
, 16, {0, (1 << 16) - 1}},
508 {_VALUE_LO16
, 16, {0, (1 << 16) - 1}},
509 {_VALUE_LDST_LO16
, 16, {0, (1 << 16) - 1}},
510 {_SIMM16_LA
, 16, {-(1 << 15), (1 << 15) - 1}}, /* (-32768 ~ 32767) */
511 {_IMM5_RSHIFT_1
, 5, {0, (1 << 6) - 1}}, /* ( 0 ~ 63 ) */
512 {_IMM5_RSHIFT_2
, 5, {0, (1 << 7) - 1}}, /* ( 0 ~ 127 ) */
513 {_SIMM16_LA_POS
, 16, {0, (1 << 15) - 1}}, /* ( 0 ~ 32767) */
514 {_IMM5_RANGE_8_31
, 5, {8, 31}}, /* But for cop0 the valid data : (8 ~ 31). */
515 {_IMM10_RSHIFT_2
, 10, {-(1 << 11), (1 << 11) - 1}}, /* For ldc#, stc#. */
516 {_SIMM10
, 10, {0, (1 << 10) - 1}}, /* ( -1024 ~ 1023 ) */
517 {_SIMM12
, 12, {0, (1 << 12) - 1}}, /* ( -2048 ~ 2047 ) */
518 {_SIMM14
, 14, {0, (1 << 14) - 1}}, /* ( -8192 ~ 8191 ) */
519 {_SIMM15
, 15, {0, (1 << 15) - 1}}, /* (-16384 ~ 16383) */
520 {_SIMM16
, 16, {0, (1 << 16) - 1}}, /* (-65536 ~ 65536) */
521 {_SIMM14_NEG
, 14, {0, (1 << 16) - 1}}, /* ( -8191 ~ 8192 ) */
522 {_IMM16_NEG
, 16, {0, (1 << 16) - 1}}, /* ( 65535 ~ 0 ) */
523 {_SIMM16_NEG
, 16, {0, (1 << 16) - 1}}, /* ( 65535 ~ 0 ) */
524 {_IMM20
, 20, {0, (1 << 20) - 1}}, /* (-32768 ~ 32767) */
525 {_IMM25
, 25, {0, (1 << 25) - 1}}, /* (-32768 ~ 32767) */
526 {_GP_IMM15
, 15, {0, (1 << 15) - 1}}, /* ( 0 ~ 65535) */
527 {_GP_IMM14
, 14, {0, (1 << 14) - 1}}, /* ( 0 ~ 65535) */
528 {_SIMM16_pic
, 16, {-(1 << 15), (1 << 15) - 1}}, /* (-32768 ~ 32767) */
529 {_IMM16_LO16_pic
, 16, {0, (1 << 16) - 1}}, /* ( 65535 ~ 0 ) */
530 {_IMM16_pic
, 16, {0, (1 << 16) - 1}}, /* ( 0 ~ 65535) */
531 {_SIMM5
, 5, {-(1 << 4), (1 << 4) - 1}}, /* ( -16 ~ 15 ) */
532 {_SIMM6
, 6, {-(1 << 5), (1 << 5) - 1}}, /* ( -32 ~ 31 ) */
533 {_IMM32
, 32, {0, 0xfffffff}},
534 {_SIMM32
, 32, {-0x80000000, 0x7fffffff}},
535 {_IMM11
, 11, {0, (1 << 11) - 1}},
540 /* Instruction name. */
541 const char *template_name
;
543 /* Instruction Opcode. */
546 /* Instruction bit mask. */
549 /* Relax instruction opcode. 0x8000 imply no relaxation. */
552 /* Instruction type. */
553 enum score_insn_type type
;
555 /* Function to call to parse args. */
556 void (*parms
) (char *);
559 static const struct s3_asm_opcode s3_score_ldst_insns
[] =
561 {"lw", 0x20000000, 0x3e000000, 0x1000, Rd_rvalueRs_SI15
, s3_do_ldst_insn
},
562 {"lw", 0x06000000, 0x3e000007, 0x8000, Rd_rvalueRs_preSI12
, s3_do_ldst_insn
},
563 {"lw", 0x0e000000, 0x3e000007, 0x0040, Rd_rvalueRs_postSI12
, s3_do_ldst_insn
},
564 {"lh", 0x22000000, 0x3e000000, 0x8000, Rd_rvalueRs_SI15
, s3_do_ldst_insn
},
565 {"lh", 0x06000001, 0x3e000007, 0x8000, Rd_rvalueRs_preSI12
, s3_do_ldst_insn
},
566 {"lh", 0x0e000001, 0x3e000007, 0x8000, Rd_rvalueRs_postSI12
, s3_do_ldst_insn
},
567 {"lhu", 0x24000000, 0x3e000000, 0x8000, Rd_rvalueRs_SI15
, s3_do_ldst_insn
},
568 {"lhu", 0x06000002, 0x3e000007, 0x8000, Rd_rvalueRs_preSI12
, s3_do_ldst_insn
},
569 {"lhu", 0x0e000002, 0x3e000007, 0x8000, Rd_rvalueRs_postSI12
, s3_do_ldst_insn
},
570 {"lb", 0x26000000, 0x3e000000, 0x8000, Rd_rvalueRs_SI15
, s3_do_ldst_insn
},
571 {"lb", 0x06000003, 0x3e000007, 0x8000, Rd_rvalueRs_preSI12
, s3_do_ldst_insn
},
572 {"lb", 0x0e000003, 0x3e000007, 0x8000, Rd_rvalueRs_postSI12
, s3_do_ldst_insn
},
573 {"sw", 0x28000000, 0x3e000000, 0x2000, Rd_lvalueRs_SI15
, s3_do_ldst_insn
},
574 {"sw", 0x06000004, 0x3e000007, 0x0060, Rd_lvalueRs_preSI12
, s3_do_ldst_insn
},
575 {"sw", 0x0e000004, 0x3e000007, 0x8000, Rd_lvalueRs_postSI12
, s3_do_ldst_insn
},
576 {"sh", 0x2a000000, 0x3e000000, 0x8000, Rd_lvalueRs_SI15
, s3_do_ldst_insn
},
577 {"sh", 0x06000005, 0x3e000007, 0x8000, Rd_lvalueRs_preSI12
, s3_do_ldst_insn
},
578 {"sh", 0x0e000005, 0x3e000007, 0x8000, Rd_lvalueRs_postSI12
, s3_do_ldst_insn
},
579 {"lbu", 0x2c000000, 0x3e000000, 0x8000, Rd_rvalueRs_SI15
, s3_do_ldst_insn
},
580 {"lbu", 0x06000006, 0x3e000007, 0x8000, Rd_rvalueRs_preSI12
, s3_do_ldst_insn
},
581 {"lbu", 0x0e000006, 0x3e000007, 0x8000, Rd_rvalueRs_postSI12
, s3_do_ldst_insn
},
582 {"sb", 0x2e000000, 0x3e000000, 0x8000, Rd_lvalueRs_SI15
, s3_do_ldst_insn
},
583 {"sb", 0x06000007, 0x3e000007, 0x8000, Rd_lvalueRs_preSI12
, s3_do_ldst_insn
},
584 {"sb", 0x0e000007, 0x3e000007, 0x8000, Rd_lvalueRs_postSI12
, s3_do_ldst_insn
},
587 static const struct s3_asm_opcode s3_score_insns
[] =
589 {"abs", 0x3800000a, 0x3e007fff, 0x8000, Rd_Rs_x
, s3_do_dsp3
},
590 {"abs.s", 0x3800004b, 0x3e007fff, 0x8000, Rd_Rs_x
, s3_do_dsp3
},
591 {"add", 0x00000010, 0x3e0003ff, 0x4800, Rd_Rs_Rs
, s3_do_rdrsrs
},
592 {"add.c", 0x00000011, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_rdrsrs
},
593 {"add.s", 0x38000048, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_dsp2
},
594 {"addc", 0x00000012, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_rdrsrs
},
595 {"addc.c", 0x00000013, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_rdrsrs
},
596 {"addi", 0x02000000, 0x3e0e0001, 0x5c00, Rd_SI16
, s3_do_rdsi16
},
597 {"addi.c", 0x02000001, 0x3e0e0001, 0x8000, Rd_SI16
, s3_do_rdsi16
},
598 {"addis", 0x0a000000, 0x3e0e0001, 0x8000, Rd_SI16
, s3_do_rdi16
},
599 {"addis.c", 0x0a000001, 0x3e0e0001, 0x8000, Rd_SI16
, s3_do_rdi16
},
600 {"addi!", 0x5c00, 0x7c00, 0x8000, Rd_SI6
, s3_do16_addi
},
601 {"addri", 0x10000000, 0x3e000001, 0x8000, Rd_Rs_SI14
, s3_do_rdrssi14
},
602 {"addri.c", 0x10000001, 0x3e000001, 0x8000, Rd_Rs_SI14
, s3_do_rdrssi14
},
604 /* add.c <-> add!. */
605 {"add!", 0x4800, 0x7f00, 0x8000, Rd_Rs
, s3_do16_rdrs2
},
606 {"subi", 0x02000000, 0x3e0e0001, 0x8000, Rd_SI16
, s3_do_sub_rdsi16
},
607 {"subi.c", 0x02000001, 0x3e0e0001, 0x8000, Rd_SI16
, s3_do_sub_rdsi16
},
608 {"subis", 0x0a000000, 0x3e0e0001, 0x8000, Rd_SI16
, s3_do_sub_rdi16
},
609 {"subis.c", 0x0a000001, 0x3e0e0001, 0x8000, Rd_SI16
, s3_do_sub_rdi16
},
610 {"subri", 0x10000000, 0x3e000001, 0x8000, Rd_Rs_SI14
, s3_do_sub_rdrssi14
},
611 {"subri.c", 0x10000001, 0x3e000001, 0x8000, Rd_Rs_SI14
, s3_do_sub_rdrssi14
},
612 {"and", 0x00000020, 0x3e0003ff, 0x4b00, Rd_Rs_Rs
, s3_do_rdrsrs
},
613 {"and.c", 0x00000021, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_rdrsrs
},
614 {"andi", 0x02080000, 0x3e0e0001, 0x8000, Rd_I16
, s3_do_rdi16
},
615 {"andi.c", 0x02080001, 0x3e0e0001, 0x8000, Rd_I16
, s3_do_rdi16
},
616 {"andis", 0x0a080000, 0x3e0e0001, 0x8000, Rd_I16
, s3_do_rdi16
},
617 {"andis.c", 0x0a080001, 0x3e0e0001, 0x8000, Rd_I16
, s3_do_rdi16
},
618 {"andri", 0x18000000, 0x3e000001, 0x8000, Rd_Rs_I14
, s3_do_rdrsi14
},
619 {"andri.c", 0x18000001, 0x3e000001, 0x8000, Rd_Rs_I14
, s3_do_rdrsi14
},
621 /* and.c <-> and!. */
622 {"and!", 0x4b00, 0x7f00, 0x8000, Rd_Rs
, s3_do16_rdrs2
},
623 {"bcs", 0x08000000, 0x3e007c01, 0x8000, PC_DISP19div2
, s3_do_branch
},
624 {"bcc", 0x08000400, 0x3e007c01, 0x8000, PC_DISP19div2
, s3_do_branch
},
625 {"bcnz", 0x08003800, 0x3e007c01, 0x3200, PC_DISP19div2
, s3_do_branch
},
626 {"bcsl", 0x08000001, 0x3e007c01, 0x8000, PC_DISP19div2
, s3_do_branch
},
627 {"bccl", 0x08000401, 0x3e007c01, 0x8000, PC_DISP19div2
, s3_do_branch
},
628 {"bcnzl", 0x08003801, 0x3e007c01, 0x8000, PC_DISP19div2
, s3_do_branch
},
629 {"bcnz!", 0x3200, 0x7f00, 0x08003800, PC_DISP8div2
, s3_do16_branch
},
630 {"beq", 0x08001000, 0x3e007c01, 0x3800, PC_DISP19div2
, s3_do_branch
},
631 {"beql", 0x08001001, 0x3e007c01, 0x8000, PC_DISP19div2
, s3_do_branch
},
632 {"beq!", 0x3800, 0x7e00, 0x08001000, PC_DISP8div2
, s3_do16_branch
},
633 {"bgtu", 0x08000800, 0x3e007c01, 0x3400, PC_DISP19div2
, s3_do_branch
},
634 {"bgt", 0x08001800, 0x3e007c01, 0x3c00, PC_DISP19div2
, s3_do_branch
},
635 {"bge", 0x08002000, 0x3e007c01, 0x8000, PC_DISP19div2
, s3_do_branch
},
636 {"bgtul", 0x08000801, 0x3e007c01, 0x8000, PC_DISP19div2
, s3_do_branch
},
637 {"bgtl", 0x08001801, 0x3e007c01, 0x8000, PC_DISP19div2
, s3_do_branch
},
638 {"bgel", 0x08002001, 0x3e007c01, 0x8000, PC_DISP19div2
, s3_do_branch
},
639 {"bgtu!", 0x3400, 0x7e00, 0x08000800, PC_DISP8div2
, s3_do16_branch
},
640 {"bgt!", 0x3c00, 0x7e00, 0x08001800, PC_DISP8div2
, s3_do16_branch
},
641 {"bitclr", 0x00000028, 0x3e0003ff, 0x5000, Rd_Rs_I5
, s3_do_rdrsi5
},
642 {"bitclr.c", 0x00000029, 0x3e0003ff, 0x8000, Rd_Rs_I5
, s3_do_rdrsi5
},
644 {"mbitclr", 0x00000064, 0x3e00007e, 0x8000, Ra_I9_I5
, s3_do_mbitclr
},
645 {"mbitset", 0x0000006c, 0x3e00007e, 0x8000, Ra_I9_I5
, s3_do_mbitset
},
647 {"bitrev", 0x3800000c, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_dsp2
},
648 {"bitset", 0x0000002a, 0x3e0003ff, 0x5200, Rd_Rs_I5
, s3_do_rdrsi5
},
649 {"bitset.c", 0x0000002b, 0x3e0003ff, 0x8000, Rd_Rs_I5
, s3_do_rdrsi5
},
650 {"bittst.c", 0x0000002d, 0x3e0003ff, 0x5400, x_Rs_I5
, s3_do_xrsi5
},
651 {"bittgl", 0x0000002e, 0x3e0003ff, 0x5600, Rd_Rs_I5
, s3_do_rdrsi5
},
652 {"bittgl.c", 0x0000002f, 0x3e0003ff, 0x8000, Rd_Rs_I5
, s3_do_rdrsi5
},
653 {"bitclr!", 0x5000, 0x7e00, 0x8000, Rd_I5
, s3_do16_rdi5
},
654 {"bitset!", 0x5200, 0x7e00, 0x8000, Rd_I5
, s3_do16_rdi5
},
655 {"bittst!", 0x5400, 0x7e00, 0x8000, Rd_I5
, s3_do16_rdi5
},
656 {"bittgl!", 0x5600, 0x7e00, 0x8000, Rd_I5
, s3_do16_rdi5
},
657 {"bleu", 0x08000c00, 0x3e007c01, 0x3600, PC_DISP19div2
, s3_do_branch
},
658 {"ble", 0x08001c00, 0x3e007c01, 0x3e00, PC_DISP19div2
, s3_do_branch
},
659 {"blt", 0x08002400, 0x3e007c01, 0x8000, PC_DISP19div2
, s3_do_branch
},
660 {"bleul", 0x08000c01, 0x3e007c01, 0x8000, PC_DISP19div2
, s3_do_branch
},
661 {"blel", 0x08001c01, 0x3e007c01, 0x8000, PC_DISP19div2
, s3_do_branch
},
662 {"bltl", 0x08002401, 0x3e007c01, 0x8000, PC_DISP19div2
, s3_do_branch
},
663 {"bl", 0x08003c01, 0x3e007c01, 0x8000, PC_DISP19div2
, s3_do_branch
},
664 {"bleu!", 0x3600, 0x7e00, 0x08000c00, PC_DISP8div2
, s3_do16_branch
},
665 {"ble!", 0x3e00, 0x7e00, 0x08001c00, PC_DISP8div2
, s3_do16_branch
},
666 {"bmi", 0x08002800, 0x3e007c01, 0x8000, PC_DISP19div2
, s3_do_branch
},
667 {"bmil", 0x08002801, 0x3e007c01, 0x8000, PC_DISP19div2
, s3_do_branch
},
668 {"bne", 0x08001400, 0x3e007c01, 0x3a00, PC_DISP19div2
, s3_do_branch
},
669 {"bnel", 0x08001401, 0x3e007c01, 0x8000, PC_DISP19div2
, s3_do_branch
},
670 {"bne!", 0x3a00, 0x7e00, 0x08001400, PC_DISP8div2
, s3_do16_branch
},
671 {"bpl", 0x08002c00, 0x3e007c01, 0x8000, PC_DISP19div2
, s3_do_branch
},
672 {"bpll", 0x08002c01, 0x3e007c01, 0x8000, PC_DISP19div2
, s3_do_branch
},
673 {"brcs", 0x00000008, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
674 {"brcc", 0x00000408, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
675 {"brgtu", 0x00000808, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
676 {"brleu", 0x00000c08, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
677 {"breq", 0x00001008, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
678 {"brne", 0x00001408, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
679 {"brgt", 0x00001808, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
680 {"brle", 0x00001c08, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
681 {"brge", 0x00002008, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
682 {"brlt", 0x00002408, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
683 {"brmi", 0x00002808, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
684 {"brpl", 0x00002c08, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
685 {"brvs", 0x00003008, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
686 {"brvc", 0x00003408, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
687 {"brcnz", 0x00003808, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
688 {"br", 0x00003c08, 0x3e007fff, 0x0080, x_Rs_x
, s3_do_rs
},
689 {"brcsl", 0x00000009, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
690 {"brccl", 0x00000409, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
691 {"brgtul", 0x00000809, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
692 {"brleul", 0x00000c09, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
693 {"breql", 0x00001009, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
694 {"brnel", 0x00001409, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
695 {"brgtl", 0x00001809, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
696 {"brlel", 0x00001c09, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
697 {"brgel", 0x00002009, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
698 {"brltl", 0x00002409, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
699 {"brmil", 0x00002809, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
700 {"brpll", 0x00002c09, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
701 {"brvsl", 0x00003009, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
702 {"brvcl", 0x00003409, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
703 {"brcnzl", 0x00003809, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
704 {"brl", 0x00003c09, 0x3e007fff, 0x00a0, x_Rs_x
, s3_do_rs
},
705 {"br!", 0x0080, 0x7fe0, 0x8000, x_Rs
, s3_do16_br
},
706 {"brl!", 0x00a0, 0x7fe0, 0x8000, x_Rs
, s3_do16_br
},
707 {"brr!", 0x00c0, 0x7fe0, 0x8000, x_Rs
, s3_do16_brr
},
708 {"bvs", 0x08003000, 0x3e007c01, 0x8000, PC_DISP19div2
, s3_do_branch
},
709 {"bvc", 0x08003400, 0x3e007c01, 0x8000, PC_DISP19div2
, s3_do_branch
},
710 {"bvsl", 0x08003001, 0x3e007c01, 0x8000, PC_DISP19div2
, s3_do_branch
},
711 {"bvcl", 0x08003401, 0x3e007c01, 0x8000, PC_DISP19div2
, s3_do_branch
},
712 {"b!", 0x3000, 0x7e00, 0x08003c00, PC_DISP8div2
, s3_do16_branch
},
713 {"b", 0x08003c00, 0x3e007c01, 0x3000, PC_DISP19div2
, s3_do_branch
},
714 {"cache", 0x30000000, 0x3ff00000, 0x8000, OP5_rvalueRs_SI15
, s3_do_cache
},
715 {"ceinst", 0x38000000, 0x3e000000, 0x8000, I5_Rs_Rs_I5_OP5
, s3_do_ceinst
},
716 {"clz", 0x0000001c, 0x3e007fff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
717 {"cmp.c", 0x00300019, 0x3ff003ff, 0x4400, x_Rs_Rs
, s3_do_rsrs
},
718 {"cmpz.c", 0x0030001b, 0x3ff07fff, 0x8000, x_Rs_x
, s3_do_rs
},
719 {"cmpi.c", 0x02040001, 0x3e0e0001, 0x6000, Rd_SI16
, s3_do_rdsi16
},
721 /* cmp.c <-> cmp!. */
722 {"cmp!", 0x4400, 0x7c00, 0x8000, Rd_Rs
, s3_do16_mv_cmp
},
723 {"cmpi!", 0x6000, 0x7c00, 0x8000, Rd_SI5
, s3_do16_cmpi
},
724 {"cop1", 0x0c00000c, 0x3e00001f, 0x8000, Rd_Rs_Rs_imm
, s3_do_crdcrscrsimm5
},
725 {"cop2", 0x0c000014, 0x3e00001f, 0x8000, Rd_Rs_Rs_imm
, s3_do_crdcrscrsimm5
},
726 {"cop3", 0x0c00001c, 0x3e00001f, 0x8000, Rd_Rs_Rs_imm
, s3_do_crdcrscrsimm5
},
727 {"drte", 0x0c0000a4, 0x3e0003ff, 0x8000, NO_OPD
, s3_do_empty
},
728 {"disint!", 0x00e0, 0xffe1, 0x8000, NO16_OPD
, s3_do16_int
},
729 {"enint!", 0x00e1, 0xffe1, 0x8000, NO16_OPD
, s3_do16_int
},
730 {"extsb", 0x00000058, 0x3e0003ff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
731 {"extsb.c", 0x00000059, 0x3e0003ff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
732 {"extsh", 0x0000005a, 0x3e0003ff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
733 {"extsh.c", 0x0000005b, 0x3e0003ff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
734 {"extzb", 0x0000005c, 0x3e0003ff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
735 {"extzb.c", 0x0000005d, 0x3e0003ff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
736 {"extzh", 0x0000005e, 0x3e0003ff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
737 {"extzh.c", 0x0000005f, 0x3e0003ff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
738 {"jl", 0x04000001, 0x3e000001, 0x8000, PC_DISP24div2
, s3_do_jump
},
739 {"j", 0x04000000, 0x3e000001, 0x8000, PC_DISP24div2
, s3_do_jump
},
740 {"alw", 0x0000000c, 0x3e0003ff, 0x8000, Rd_rvalue32Rs
, s3_do_ldst_atomic
},
741 {"lcb", 0x00000060, 0x3e0003ff, 0x8000, x_rvalueRs_post4
, s3_do_ldst_unalign
},
742 {"lcw", 0x00000062, 0x3e0003ff, 0x8000, Rd_rvalueRs_post4
, s3_do_ldst_unalign
},
743 {"lce", 0x00000066, 0x3e0003ff, 0x8000, Rd_rvalueRs_post4
, s3_do_ldst_unalign
},
744 {"ldc1", 0x0c00000a, 0x3e00001f, 0x8000, Rd_rvalueRs_SI10
, s3_do_ldst_cop
},
745 {"ldc2", 0x0c000012, 0x3e00001f, 0x8000, Rd_rvalueRs_SI10
, s3_do_ldst_cop
},
746 {"ldc3", 0x0c00001a, 0x3e00001f, 0x8000, Rd_rvalueRs_SI10
, s3_do_ldst_cop
},
749 {"ldi", 0x020c0000, 0x3e0e0000, 0x6400, Rd_SI16
, s3_do_rdsi16
},
750 {"ldis", 0x0a0c0000, 0x3e0e0000, 0x8000, Rd_I16
, s3_do_ldis
},
753 {"ldiu!", 0x6400, 0x7c00, 0x8000, Rd_I5
, s3_do16_ldiu
},
755 /*ltbb! , ltbh! ltbw! */
756 {"ltbw", 0x00000032, 0x03ff, 0x8000, Rd_Rs_Rs
, s3_do_ltb
},
757 {"ltbh", 0x00000132, 0x03ff, 0x8000, Rd_Rs_Rs
, s3_do_ltb
},
758 {"ltbb", 0x00000332, 0x03ff, 0x8000, Rd_Rs_Rs
, s3_do_ltb
},
759 {"lw!", 0x1000, 0x7000, 0x8000, Rd_rvalueRs
, s3_do16_ldst_insn
},
760 {"mfcel", 0x00000448, 0x3e007fff, 0x8000, Rd_x_x
, s3_do_rd
},
761 {"mfcel!", 0x7100, 0x7ff0, 0x00000448, x_Rs
, s3_do16_dsp
},
762 {"mad", 0x38000000, 0x3ff003ff, 0x8000, x_Rs_Rs
, s3_do_dsp
},
763 {"mad.f!", 0x7400, 0x7f00, 0x38000080, Rd_Rs
, s3_do16_dsp2
},
764 {"madh", 0x38000203, 0x3ff003ff, 0x8000, x_Rs_Rs
, s3_do_dsp
},
765 {"madh.fs", 0x380002c3, 0x3ff003ff, 0x8000, x_Rs_Rs
, s3_do_dsp
},
766 {"madh.fs!", 0x7b00, 0x7f00, 0x380002c3, Rd_Rs
, s3_do16_dsp2
},
767 {"madl", 0x38000002, 0x3ff003ff, 0x8000, x_Rs_Rs
, s3_do_dsp
},
768 {"madl.fs", 0x380000c2, 0x3ff003ff, 0x8000, x_Rs_Rs
, s3_do_dsp
},
769 {"madl.fs!", 0x7a00, 0x7f00, 0x380000c2, Rd_Rs
, s3_do16_dsp2
},
770 {"madu", 0x38000020, 0x3ff003ff, 0x8000, x_Rs_Rs
, s3_do_dsp
},
771 {"madu!", 0x7500, 0x7f00, 0x38000020, Rd_Rs
, s3_do16_dsp2
},
772 {"mad.f", 0x38000080, 0x3ff003ff, 0x8000, x_Rs_Rs
, s3_do_dsp
},
773 {"max", 0x38000007, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_dsp2
},
774 {"mazh", 0x38000303, 0x3ff003ff, 0x8000, x_Rs_Rs
, s3_do_dsp
},
775 {"mazh.f", 0x38000383, 0x3ff003ff, 0x8000, x_Rs_Rs
, s3_do_dsp
},
776 {"mazh.f!", 0x7900, 0x7f00, 0x3800038c, Rd_Rs
, s3_do16_dsp2
},
777 {"mazl", 0x38000102, 0x3ff003ff, 0x8000, x_Rs_Rs
, s3_do_dsp
},
778 {"mazl.f", 0x38000182, 0x3ff003ff, 0x8000, x_Rs_Rs
, s3_do_dsp
},
779 {"mazl.f!", 0x7800, 0x7f00, 0x38000182, Rd_Rs
, s3_do16_dsp2
},
780 {"mfceh", 0x00000848, 0x3e007fff, 0x8000, Rd_x_x
, s3_do_rd
},
781 {"mfceh!", 0x7110, 0x7ff0, 0x00000848, x_Rs
, s3_do16_dsp
},
782 {"mfcehl", 0x00000c48, 0x3e007fff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
783 {"mfsr", 0x00000050, 0x3e0003ff, 0x8000, Rd_x_I5
, s3_do_rdsrs
},
784 {"mfcr", 0x0c000001, 0x3e00001f, 0x8000, Rd_Rs_x
, s3_do_rdcrs
},
785 {"mfc1", 0x0c000009, 0x3e00001f, 0x8000, Rd_Rs_x
, s3_do_rdcrs
},
786 {"mfc2", 0x0c000011, 0x3e00001f, 0x8000, Rd_Rs_x
, s3_do_rdcrs
},
787 {"mfc3", 0x0c000019, 0x3e00001f, 0x8000, Rd_Rs_x
, s3_do_rdcrs
},
788 {"mfcc1", 0x0c00000f, 0x3e00001f, 0x8000, Rd_Rs_x
, s3_do_rdcrs
},
789 {"mfcc2", 0x0c000017, 0x3e00001f, 0x8000, Rd_Rs_x
, s3_do_rdcrs
},
790 {"mfcc3", 0x0c00001f, 0x3e00001f, 0x8000, Rd_Rs_x
, s3_do_rdcrs
},
791 {"min", 0x38000006, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_dsp2
},
792 {"msb", 0x38000001, 0x3ff003ff, 0x8000, x_Rs_Rs
, s3_do_dsp
},
793 {"msb.f!", 0x7600, 0x7f00, 0x38000081, Rd_Rs
, s3_do16_dsp2
},
794 {"msbh", 0x38000205, 0x3ff003ff, 0x8000, x_Rs_Rs
, s3_do_dsp
},
795 {"msbh.fs", 0x380002c5, 0x3ff003ff, 0x8000, x_Rs_Rs
, s3_do_dsp
},
796 {"msbh.fs!", 0x7f00, 0x7f00, 0x380002c5, Rd_Rs
, s3_do16_dsp2
},
797 {"msbl", 0x38000004, 0x3ff003ff, 0x8000, x_Rs_Rs
, s3_do_dsp
},
798 {"msbl.fs", 0x380000c4, 0x3ff003ff, 0x8000, x_Rs_Rs
, s3_do_dsp
},
799 {"msbl.fs!", 0x7e00, 0x7f00, 0x380000c4, Rd_Rs
, s3_do16_dsp2
},
800 {"msbu", 0x38000021, 0x3ff003ff, 0x8000, x_Rs_Rs
, s3_do_dsp
},
801 {"msbu!", 0x7700, 0x7f00, 0x38000021, Rd_Rs
, s3_do16_dsp2
},
802 {"msb.f", 0x38000081, 0x3ff003ff, 0x8000, x_Rs_Rs
, s3_do_dsp
},
803 {"mszh", 0x38000305, 0x3ff003ff, 0x8000, x_Rs_Rs
, s3_do_dsp
},
804 {"mszh.f", 0x38000385, 0x3ff003ff, 0x8000, x_Rs_Rs
, s3_do_dsp
},
805 {"mszh.f!", 0x7d00, 0x7f00, 0x38000385, Rd_Rs
, s3_do16_dsp2
},
806 {"mszl", 0x38000104, 0x3ff003ff, 0x8000, x_Rs_Rs
, s3_do_dsp
},
807 {"mszl.f", 0x38000184, 0x3ff003ff, 0x8000, x_Rs_Rs
, s3_do_dsp
},
808 {"mszl.f!", 0x7c00, 0x7f00, 0x38000184, Rd_Rs
, s3_do16_dsp2
},
809 {"mtcel!", 0x7000, 0x7ff0, 0x0000044a, x_Rs
, s3_do16_dsp
},
810 {"mtcel", 0x0000044a, 0x3e007fff, 0x8000, Rd_x_x
, s3_do_rd
},
811 {"mtceh", 0x0000084a, 0x3e007fff, 0x8000, Rd_x_x
, s3_do_rd
},
812 {"mtceh!", 0x7010, 0x7ff0, 0x0000084a, x_Rs
, s3_do16_dsp
},
813 {"mtcehl", 0x00000c4a, 0x3e007fff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
814 {"mtsr", 0x00000052, 0x3e0003ff, 0x8000, x_Rs_I5
, s3_do_rdsrs
},
815 {"mtcr", 0x0c000000, 0x3e00001f, 0x8000, Rd_Rs_x
, s3_do_rdcrs
},
816 {"mtc1", 0x0c000008, 0x3e00001f, 0x8000, Rd_Rs_x
, s3_do_rdcrs
},
817 {"mtc2", 0x0c000010, 0x3e00001f, 0x8000, Rd_Rs_x
, s3_do_rdcrs
},
818 {"mtc3", 0x0c000018, 0x3e00001f, 0x8000, Rd_Rs_x
, s3_do_rdcrs
},
819 {"mtcc1", 0x0c00000e, 0x3e00001f, 0x8000, Rd_Rs_x
, s3_do_rdcrs
},
820 {"mtcc2", 0x0c000016, 0x3e00001f, 0x8000, Rd_Rs_x
, s3_do_rdcrs
},
821 {"mtcc3", 0x0c00001e, 0x3e00001f, 0x8000, Rd_Rs_x
, s3_do_rdcrs
},
822 {"mul.f!", 0x7200, 0x7f00, 0x00000041, Rd_Rs
, s3_do16_dsp2
},
823 {"mulu!", 0x7300, 0x7f00, 0x00000042, Rd_Rs
, s3_do16_dsp2
},
824 {"mulr.l", 0x00000140, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s3_do_rdrsrs
},
825 {"mulr.h", 0x00000240, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s3_do_rdrsrs
},
826 {"mulr", 0x00000340, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s3_do_rdrsrs
},
827 {"mulr.lf", 0x00000141, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s3_do_rdrsrs
},
828 {"mulr.hf", 0x00000241, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s3_do_rdrsrs
},
829 {"mulr.f", 0x00000341, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s3_do_rdrsrs
},
830 {"mulur.l", 0x00000142, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s3_do_rdrsrs
},
831 {"mulur.h", 0x00000242, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s3_do_rdrsrs
},
832 {"mulur", 0x00000342, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s3_do_rdrsrs
},
833 {"divr.q", 0x00000144, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s3_do_rdrsrs
},
834 {"divr.r", 0x00000244, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s3_do_rdrsrs
},
835 {"divr", 0x00000344, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s3_do_rdrsrs
},
836 {"divur.q", 0x00000146, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s3_do_rdrsrs
},
837 {"divur.r", 0x00000246, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s3_do_rdrsrs
},
838 {"divur", 0x00000346, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s3_do_rdrsrs
},
839 {"mvcs", 0x00000056, 0x3e007fff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
840 {"mvcc", 0x00000456, 0x3e007fff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
841 {"mvgtu", 0x00000856, 0x3e007fff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
842 {"mvleu", 0x00000c56, 0x3e007fff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
843 {"mveq", 0x00001056, 0x3e007fff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
844 {"mvne", 0x00001456, 0x3e007fff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
845 {"mvgt", 0x00001856, 0x3e007fff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
846 {"mvle", 0x00001c56, 0x3e007fff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
847 {"mvge", 0x00002056, 0x3e007fff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
848 {"mvlt", 0x00002456, 0x3e007fff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
849 {"mvmi", 0x00002856, 0x3e007fff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
850 {"mvpl", 0x00002c56, 0x3e007fff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
851 {"mvvs", 0x00003056, 0x3e007fff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
852 {"mvvc", 0x00003456, 0x3e007fff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
855 {"mv", 0x00003c56, 0x3e007fff, 0x4000, Rd_Rs_x
, s3_do_rdrs
},
856 {"mv!", 0x4000, 0x7c00, 0x8000, Rd_Rs
, s3_do16_mv_cmp
},
857 {"neg", 0x0000001e, 0x3e0003ff, 0x8000, Rd_x_Rs
, s3_do_rdxrs
},
858 {"neg.c", 0x0000001f, 0x3e0003ff, 0x8000, Rd_x_Rs
, s3_do_rdxrs
},
859 {"nop", 0x00000000, 0x3e0003ff, 0x0000, NO_OPD
, s3_do_empty
},
860 {"not", 0x00000024, 0x3e0003ff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
861 {"not.c", 0x00000025, 0x3e0003ff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
862 {"nop!", 0x0000, 0x7fff, 0x8000, NO16_OPD
, s3_do_empty
},
863 {"or", 0x00000022, 0x3e0003ff, 0x4a00, Rd_Rs_Rs
, s3_do_rdrsrs
},
864 {"or.c", 0x00000023, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_rdrsrs
},
865 {"ori", 0x020a0000, 0x3e0e0001, 0x8000, Rd_I16
, s3_do_rdi16
},
866 {"ori.c", 0x020a0001, 0x3e0e0001, 0x8000, Rd_I16
, s3_do_rdi16
},
867 {"oris", 0x0a0a0000, 0x3e0e0001, 0x8000, Rd_I16
, s3_do_rdi16
},
868 {"oris.c", 0x0a0a0001, 0x3e0e0001, 0x8000, Rd_I16
, s3_do_rdi16
},
869 {"orri", 0x1a000000, 0x3e000001, 0x8000, Rd_Rs_I14
, s3_do_rdrsi14
},
870 {"orri.c", 0x1a000001, 0x3e000001, 0x8000, Rd_Rs_I14
, s3_do_rdrsi14
},
873 {"or!", 0x4a00, 0x7f00, 0x8000, Rd_Rs
, s3_do16_rdrs2
},
874 {"pflush", 0x0000000a, 0x3e0003ff, 0x8000, NO_OPD
, s3_do_empty
},
875 {"pop!", 0x0040, 0x7fe0, 0x8000, Rd_rvalueRs
, s3_do16_push_pop
},
876 {"push!", 0x0060, 0x7fe0, 0x8000, Rd_lvalueRs
, s3_do16_push_pop
},
878 {"rpop!", 0x6800, 0x7c00, 0x8000, Rd_I5
, s3_do16_rpop
},
879 {"rpush!", 0x6c00, 0x7c00, 0x8000, Rd_I5
, s3_do16_rpush
},
881 {"ror", 0x00000038, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_rdrsrs
},
882 {"ror.c", 0x00000039, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_rdrsrs
},
883 {"rorc.c", 0x0000003b, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_rdrsrs
},
884 {"rol", 0x0000003c, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_rdrsrs
},
885 {"rol.c", 0x0000003d, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_rdrsrs
},
886 {"rolc.c", 0x0000003f, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_rdrsrs
},
887 {"rori", 0x00000078, 0x3e0003ff, 0x8000, Rd_Rs_I5
, s3_do_rdrsi5
},
888 {"rori.c", 0x00000079, 0x3e0003ff, 0x8000, Rd_Rs_I5
, s3_do_rdrsi5
},
889 {"roric.c", 0x0000007b, 0x3e0003ff, 0x8000, Rd_Rs_I5
, s3_do_rdrsi5
},
890 {"roli", 0x0000007c, 0x3e0003ff, 0x8000, Rd_Rs_I5
, s3_do_rdrsi5
},
891 {"roli.c", 0x0000007d, 0x3e0003ff, 0x8000, Rd_Rs_I5
, s3_do_rdrsi5
},
892 {"rolic.c", 0x0000007f, 0x3e0003ff, 0x8000, Rd_Rs_I5
, s3_do_rdrsi5
},
893 {"rte", 0x0c000084, 0x3e0003ff, 0x8000, NO_OPD
, s3_do_empty
},
894 {"asw", 0x0000000e, 0x3e0003ff, 0x8000, Rd_lvalue32Rs
, s3_do_ldst_atomic
},
895 {"scb", 0x00000068, 0x3e0003ff, 0x8000, Rd_lvalueRs_post4
, s3_do_ldst_unalign
},
896 {"scw", 0x0000006a, 0x3e0003ff, 0x8000, Rd_lvalueRs_post4
, s3_do_ldst_unalign
},
897 {"sce", 0x0000006e, 0x3e0003ff, 0x8000, x_lvalueRs_post4
, s3_do_ldst_unalign
},
898 {"sdbbp", 0x00000006, 0x3e0003ff, 0x0020, x_I5_x
, s3_do_xi5x
},
899 {"sdbbp!", 0x0020, 0x7fe0, 0x8000, Rd_I5
, s3_do16_xi5
},
900 {"sleep", 0x0c0000c4, 0x3e0003ff, 0x8000, NO_OPD
, s3_do_empty
},
901 {"rti", 0x0c0000e4, 0x3e0003ff, 0x8000, NO_OPD
, s3_do_empty
},
902 {"sll", 0x00000030, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_rdrsrs
},
903 {"sll.c", 0x00000031, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_rdrsrs
},
904 {"sll.s", 0x3800004e, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_dsp2
},
905 {"slli", 0x00000070, 0x3e0003ff, 0x5800, Rd_Rs_I5
, s3_do_rdrsi5
},
906 {"slli.c", 0x00000071, 0x3e0003ff, 0x8000, Rd_Rs_I5
, s3_do_rdrsi5
},
908 /* slli.c <-> slli!. */
909 {"slli!", 0x5800, 0x7e00, 0x8000, Rd_I5
, s3_do16_slli_srli
},
910 {"srl", 0x00000034, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_rdrsrs
},
911 {"srl.c", 0x00000035, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_rdrsrs
},
912 {"sra", 0x00000036, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_rdrsrs
},
913 {"sra.c", 0x00000037, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_rdrsrs
},
914 {"srli", 0x00000074, 0x3e0003ff, 0x5a00, Rd_Rs_I5
, s3_do_rdrsi5
},
915 {"srli.c", 0x00000075, 0x3e0003ff, 0x8000, Rd_Rs_I5
, s3_do_rdrsi5
},
916 {"srai", 0x00000076, 0x3e0003ff, 0x8000, Rd_Rs_I5
, s3_do_rdrsi5
},
917 {"srai.c", 0x00000077, 0x3e0003ff, 0x8000, Rd_Rs_I5
, s3_do_rdrsi5
},
919 /* srli.c <-> srli!. */
920 {"srli!", 0x5a00, 0x7e00, 0x8000, Rd_Rs
, s3_do16_slli_srli
},
921 {"stc1", 0x0c00000b, 0x3e00001f, 0x8000, Rd_lvalueRs_SI10
, s3_do_ldst_cop
},
922 {"stc2", 0x0c000013, 0x3e00001f, 0x8000, Rd_lvalueRs_SI10
, s3_do_ldst_cop
},
923 {"stc3", 0x0c00001b, 0x3e00001f, 0x8000, Rd_lvalueRs_SI10
, s3_do_ldst_cop
},
924 {"sub", 0x00000014, 0x3e0003ff, 0x4900, Rd_Rs_Rs
, s3_do_rdrsrs
},
925 {"sub.c", 0x00000015, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_rdrsrs
},
926 {"sub.s", 0x38000049, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_dsp2
},
927 {"subc", 0x00000016, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_rdrsrs
},
928 {"subc.c", 0x00000017, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_rdrsrs
},
930 /* sub.c <-> sub!. */
931 {"sub!", 0x4900, 0x7f00, 0x8000, Rd_Rs
, s3_do16_rdrs2
},
932 {"sw!", 0x2000, 0x7000, 0x8000, Rd_lvalueRs
, s3_do16_ldst_insn
},
933 {"syscall", 0x00000002, 0x3e0003ff, 0x8000, I15
, s3_do_i15
},
934 {"trapcs", 0x00000004, 0x3e007fff, 0x8000, x_I5_x
, s3_do_xi5x
},
935 {"trapcc", 0x00000404, 0x3e007fff, 0x8000, x_I5_x
, s3_do_xi5x
},
936 {"trapgtu", 0x00000804, 0x3e007fff, 0x8000, x_I5_x
, s3_do_xi5x
},
937 {"trapleu", 0x00000c04, 0x3e007fff, 0x8000, x_I5_x
, s3_do_xi5x
},
938 {"trapeq", 0x00001004, 0x3e007fff, 0x8000, x_I5_x
, s3_do_xi5x
},
939 {"trapne", 0x00001404, 0x3e007fff, 0x8000, x_I5_x
, s3_do_xi5x
},
940 {"trapgt", 0x00001804, 0x3e007fff, 0x8000, x_I5_x
, s3_do_xi5x
},
941 {"traple", 0x00001c04, 0x3e007fff, 0x8000, x_I5_x
, s3_do_xi5x
},
942 {"trapge", 0x00002004, 0x3e007fff, 0x8000, x_I5_x
, s3_do_xi5x
},
943 {"traplt", 0x00002404, 0x3e007fff, 0x8000, x_I5_x
, s3_do_xi5x
},
944 {"trapmi", 0x00002804, 0x3e007fff, 0x8000, x_I5_x
, s3_do_xi5x
},
945 {"trappl", 0x00002c04, 0x3e007fff, 0x8000, x_I5_x
, s3_do_xi5x
},
946 {"trapvs", 0x00003004, 0x3e007fff, 0x8000, x_I5_x
, s3_do_xi5x
},
947 {"trapvc", 0x00003404, 0x3e007fff, 0x8000, x_I5_x
, s3_do_xi5x
},
948 {"trap", 0x00003c04, 0x3e007fff, 0x8000, x_I5_x
, s3_do_xi5x
},
949 {"xor", 0x00000026, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_rdrsrs
},
950 {"xor.c", 0x00000027, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_rdrsrs
},
952 /* Macro instruction. */
953 {"li", 0x020c0000, 0x3e0e0000, 0x8000, Insn_Type_SYN
, s3_do_macro_li_rdi32
},
955 /* la reg, imm32 -->(1) ldi reg, simm16
956 (2) ldis reg, %HI(imm32)
959 la reg, symbol -->(1) lis reg, %HI(imm32)
960 ori reg, %LO(imm32) */
961 {"la", 0x020c0000, 0x3e0e0000, 0x8000, Insn_Type_SYN
, s3_do_macro_la_rdi32
},
962 {"bcmpeqz", 0x0000004c, 0x3e00007e, 0x8000, Insn_BCMP
, s3_do_macro_bcmpz
},
963 {"bcmpeq", 0x0000004c, 0x3e00007e, 0x8000, Insn_BCMP
, s3_do_macro_bcmp
},
964 {"bcmpnez", 0x0000004e, 0x3e00007e, 0x8000, Insn_BCMP
, s3_do_macro_bcmpz
},
965 {"bcmpne", 0x0000004e, 0x3e00007e, 0x8000, Insn_BCMP
, s3_do_macro_bcmp
},
966 {"div", 0x00000044, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s3_do_macro_mul_rdrsrs
},
967 {"divu", 0x00000046, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s3_do_macro_mul_rdrsrs
},
968 {"rem", 0x00000044, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s3_do_macro_mul_rdrsrs
},
969 {"remu", 0x00000046, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s3_do_macro_mul_rdrsrs
},
970 {"mul", 0x00000040, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s3_do_macro_mul_rdrsrs
},
971 {"mulu", 0x00000042, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s3_do_macro_mul_rdrsrs
},
972 {"maz", 0x00000040, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s3_do_macro_mul_rdrsrs
},
973 {"mazu", 0x00000042, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s3_do_macro_mul_rdrsrs
},
974 {"mul.f", 0x00000041, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s3_do_macro_mul_rdrsrs
},
975 {"maz.f", 0x00000041, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s3_do_macro_mul_rdrsrs
},
976 {"lb", INSN_LB
, 0x00000000, 0x8000, Insn_Type_SYN
, s3_do_macro_ldst_label
},
977 {"lbu", INSN_LBU
, 0x00000000, 0x8000, Insn_Type_SYN
, s3_do_macro_ldst_label
},
978 {"lh", INSN_LH
, 0x00000000, 0x8000, Insn_Type_SYN
, s3_do_macro_ldst_label
},
979 {"lhu", INSN_LHU
, 0x00000000, 0x8000, Insn_Type_SYN
, s3_do_macro_ldst_label
},
980 {"lw", INSN_LW
, 0x00000000, 0x1000, Insn_Type_SYN
, s3_do_macro_ldst_label
},
981 {"sb", INSN_SB
, 0x00000000, 0x8000, Insn_Type_SYN
, s3_do_macro_ldst_label
},
982 {"sh", INSN_SH
, 0x00000000, 0x8000, Insn_Type_SYN
, s3_do_macro_ldst_label
},
983 {"sw", INSN_SW
, 0x00000000, 0x2000, Insn_Type_SYN
, s3_do_macro_ldst_label
},
985 /* Assembler use internal. */
986 {"ld_i32hi", 0x0a0c0000, 0x3e0e0000, 0x8000, Insn_internal
, s3_do_macro_rdi32hi
},
987 {"ld_i32lo", 0x020a0000, 0x3e0e0001, 0x8000, Insn_internal
, s3_do_macro_rdi32lo
},
988 {"ldis_pic", 0x0a0c0000, 0x3e0e0000, 0x8000, Insn_internal
, s3_do_rdi16_pic
},
989 {"addi_s_pic",0x02000000, 0x3e0e0001, 0x8000, Insn_internal
, s3_do_addi_s_pic
},
990 {"addi_u_pic",0x02000000, 0x3e0e0001, 0x8000, Insn_internal
, s3_do_addi_u_pic
},
991 {"lw_pic", 0x20000000, 0x3e000000, 0x8000, Insn_internal
, s3_do_lw_pic
},
993 /* 48-bit instructions. */
994 {"sdbbp48", 0x000000000000LL
, 0x1c000000001fLL
, 0x8000, Rd_I32
, s3_do_sdbbp48
},
995 {"ldi48", 0x000000000001LL
, 0x1c000000001fLL
, 0x8000, Rd_I32
, s3_do_ldi48
},
996 {"lw48", 0x000000000002LL
, 0x1c000000001fLL
, 0x8000, Rd_I30
, s3_do_lw48
},
997 {"sw48", 0x000000000003LL
, 0x1c000000001fLL
, 0x8000, Rd_I30
, s3_do_sw48
},
998 {"andri48", 0x040000000000LL
, 0x1c0000000003LL
, 0x8000, Rd_I32
, s3_do_and48
},
999 {"andri48.c", 0x040000000001LL
, 0x1c0000000003LL
, 0x8000, Rd_I32
, s3_do_and48
},
1000 {"orri48", 0x040000000002LL
, 0x1c0000000003LL
, 0x8000, Rd_I32
, s3_do_or48
},
1001 {"orri48.c", 0x040000000003LL
, 0x1c0000000003LL
, 0x8000, Rd_I32
, s3_do_or48
},
1004 #define s3_SCORE3_PIPELINE 3
1006 static int s3_university_version
= 0;
1007 static int s3_vector_size
= s3_SCORE3_PIPELINE
;
1008 static struct s3_score_it s3_dependency_vector
[s3_SCORE3_PIPELINE
];
1010 static int s3_score3d
= 1;
1013 s3_end_of_line (char *str
)
1015 int retval
= s3_SUCCESS
;
1017 s3_skip_whitespace (str
);
1020 retval
= (int) s3_FAIL
;
1023 s3_inst
.error
= s3_BAD_GARBAGE
;
1030 s3_score_reg_parse (char **ccp
, htab_t htab
)
1035 struct s3_reg_entry
*reg
;
1038 if (!ISALPHA (*p
) || !is_name_beginner (*p
))
1039 return (int) s3_FAIL
;
1043 while (ISALPHA (c
) || ISDIGIT (c
) || c
== '_')
1047 reg
= (struct s3_reg_entry
*) str_hash_find (htab
, start
);
1055 return (int) s3_FAIL
;
1058 /* If shift <= 0, only return reg. */
1061 s3_reg_required_here (char **str
, int shift
, enum s3_score_reg_type reg_type
)
1063 static char buff
[s3_MAX_LITERAL_POOL_SIZE
];
1064 int reg
= (int) s3_FAIL
;
1067 if ((reg
= s3_score_reg_parse (str
, s3_all_reg_maps
[reg_type
].htab
)) != (int) s3_FAIL
)
1069 if (reg_type
== s3_REG_TYPE_SCORE
)
1071 if ((reg
== 1) && (s3_nor1
== 1) && (s3_inst
.bwarn
== 0))
1073 as_warn (_("Using temp register (r1)"));
1079 if (reg_type
== s3_REG_TYPE_SCORE_CR
)
1080 strcpy (s3_inst
.reg
, s3_score_crn_table
[reg
].name
);
1081 else if (reg_type
== s3_REG_TYPE_SCORE_SR
)
1082 strcpy (s3_inst
.reg
, s3_score_srn_table
[reg
].name
);
1084 strcpy (s3_inst
.reg
, "");
1086 s3_inst
.instruction
|= (bfd_vma
) reg
<< shift
;
1092 sprintf (buff
, _("register expected, not '%.100s'"), start
);
1093 s3_inst
.error
= buff
;
1100 s3_skip_past_comma (char **str
)
1106 while ((c
= *p
) == ' ' || c
== ',')
1109 if (c
== ',' && comma
++)
1111 s3_inst
.error
= s3_BAD_SKIP_COMMA
;
1112 return (int) s3_FAIL
;
1116 if ((c
== '\0') || (comma
== 0))
1118 s3_inst
.error
= s3_BAD_SKIP_COMMA
;
1119 return (int) s3_FAIL
;
1123 return comma
? s3_SUCCESS
: (int) s3_FAIL
;
1127 s3_do_rdrsrs (char *str
)
1130 s3_skip_whitespace (str
);
1132 if ((reg
= s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
1133 || s3_skip_past_comma (&str
) == (int) s3_FAIL
1134 || s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
1135 || s3_skip_past_comma (&str
) == (int) s3_FAIL
1136 || s3_reg_required_here (&str
, 10, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
1137 || s3_end_of_line (str
) == (int) s3_FAIL
)
1143 /* Check mulr, mulur rd is even number. */
1144 if (((s3_inst
.instruction
& 0x3e0003ff) == 0x00000340
1145 || (s3_inst
.instruction
& 0x3e0003ff) == 0x00000342)
1148 s3_inst
.error
= _("rd must be even number.");
1152 if ((((s3_inst
.instruction
>> 15) & 0x10) == 0)
1153 && (((s3_inst
.instruction
>> 10) & 0x10) == 0)
1154 && (((s3_inst
.instruction
>> 20) & 0x10) == 0)
1155 && (s3_inst
.relax_inst
!= 0x8000)
1156 && (((s3_inst
.instruction
>> 20) & 0xf) == ((s3_inst
.instruction
>> 15) & 0xf)))
1158 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>> 10) & 0xf) )
1159 | (((s3_inst
.instruction
>> 15) & 0xf) << 4);
1160 s3_inst
.relax_size
= 2;
1164 s3_inst
.relax_inst
= 0x8000;
1170 s3_walk_no_bignums (symbolS
* sp
)
1172 if (symbol_get_value_expression (sp
)->X_op
== O_big
)
1175 if (symbol_get_value_expression (sp
)->X_add_symbol
)
1176 return (s3_walk_no_bignums (symbol_get_value_expression (sp
)->X_add_symbol
)
1177 || (symbol_get_value_expression (sp
)->X_op_symbol
1178 && s3_walk_no_bignums (symbol_get_value_expression (sp
)->X_op_symbol
)));
1184 s3_my_get_expression (expressionS
* ep
, char **str
)
1188 save_in
= input_line_pointer
;
1189 input_line_pointer
= *str
;
1190 s3_in_my_get_expression
= 1;
1191 (void) expression (ep
);
1192 s3_in_my_get_expression
= 0;
1194 if (ep
->X_op
== O_illegal
)
1196 *str
= input_line_pointer
;
1197 input_line_pointer
= save_in
;
1198 s3_inst
.error
= _("illegal expression");
1199 return (int) s3_FAIL
;
1201 /* Get rid of any bignums now, so that we don't generate an error for which
1202 we can't establish a line number later on. Big numbers are never valid
1203 in instructions, which is where this routine is always called. */
1204 if (ep
->X_op
== O_big
1205 || (ep
->X_add_symbol
1206 && (s3_walk_no_bignums (ep
->X_add_symbol
)
1207 || (ep
->X_op_symbol
&& s3_walk_no_bignums (ep
->X_op_symbol
)))))
1209 s3_inst
.error
= _("invalid constant");
1210 *str
= input_line_pointer
;
1211 input_line_pointer
= save_in
;
1212 return (int) s3_FAIL
;
1215 if ((ep
->X_add_symbol
!= NULL
)
1216 && (s3_inst
.type
!= PC_DISP19div2
)
1217 && (s3_inst
.type
!= PC_DISP8div2
)
1218 && (s3_inst
.type
!= PC_DISP24div2
)
1219 && (s3_inst
.type
!= PC_DISP11div2
)
1220 && (s3_inst
.type
!= Insn_Type_SYN
)
1221 && (s3_inst
.type
!= Rd_rvalueRs_SI15
)
1222 && (s3_inst
.type
!= Rd_lvalueRs_SI15
)
1223 && (s3_inst
.type
!= Insn_internal
)
1224 && (s3_inst
.type
!= Rd_I30
)
1225 && (s3_inst
.type
!= Rd_I32
)
1226 && (s3_inst
.type
!= Insn_BCMP
))
1228 s3_inst
.error
= s3_BAD_ARGS
;
1229 *str
= input_line_pointer
;
1230 input_line_pointer
= save_in
;
1231 return (int) s3_FAIL
;
1234 *str
= input_line_pointer
;
1235 input_line_pointer
= save_in
;
1239 /* Check if an immediate is valid. If so, convert it to the right format. */
1240 static bfd_signed_vma
1241 s3_validate_immediate (bfd_signed_vma val
, unsigned int data_type
, int hex_p
)
1247 bfd_signed_vma val_hi
= ((val
& 0xffff0000) >> 16);
1249 if (s3_score_df_range
[data_type
].range
[0] <= val_hi
1250 && val_hi
<= s3_score_df_range
[data_type
].range
[1])
1257 bfd_signed_vma val_lo
= (val
& 0xffff);
1259 if (s3_score_df_range
[data_type
].range
[0] <= val_lo
1260 && val_lo
<= s3_score_df_range
[data_type
].range
[1])
1268 if (!(val
>= -0x2000 && val
<= 0x3fff))
1270 return (int) s3_FAIL
;
1275 if (!(val
>= -8192 && val
<= 8191))
1277 return (int) s3_FAIL
;
1287 if (!(val
>= -0x7fff && val
<= 0xffff && val
!= 0x8000))
1289 return (int) s3_FAIL
;
1294 if (!(val
>= -32767 && val
<= 32768))
1296 return (int) s3_FAIL
;
1304 case _IMM5_MULTI_LOAD
:
1305 if (val
>= 2 && val
<= 32)
1311 return (int) s3_FAIL
;
1314 if (val
>= 0 && val
<= 0xffffffff)
1320 return (int) s3_FAIL
;
1324 if (data_type
== _SIMM14_NEG
|| data_type
== _IMM16_NEG
)
1327 if (s3_score_df_range
[data_type
].range
[0] <= val
1328 && val
<= s3_score_df_range
[data_type
].range
[1])
1334 return (int) s3_FAIL
;
1338 s3_data_op2 (char **str
, int shift
, enum score_data_type data_type
)
1340 bfd_signed_vma value
;
1341 char data_exp
[s3_MAX_LITERAL_POOL_SIZE
];
1346 s3_skip_whitespace (*str
);
1347 s3_inst
.error
= NULL
;
1350 /* Set hex_p to zero. */
1353 while ((*dataptr
!= '\0') && (*dataptr
!= '|') && (cnt
<= s3_MAX_LITERAL_POOL_SIZE
)) /* 0x7c = ='|' */
1355 data_exp
[cnt
] = *dataptr
;
1360 data_exp
[cnt
] = '\0';
1361 pp
= (char *)&data_exp
;
1363 if (*dataptr
== '|') /* process PCE */
1365 if (s3_my_get_expression (&s3_inst
.reloc
.exp
, &pp
) == (int) s3_FAIL
)
1366 return (int) s3_FAIL
;
1367 s3_end_of_line (pp
);
1368 if (s3_inst
.error
!= 0)
1369 return (int) s3_FAIL
; /* to ouptut_inst to printf out the error */
1372 else /* process 16 bit */
1374 if (s3_my_get_expression (&s3_inst
.reloc
.exp
, str
) == (int) s3_FAIL
)
1376 return (int) s3_FAIL
;
1379 dataptr
= (char *)data_exp
;
1380 for (; *dataptr
!= '\0'; dataptr
++)
1382 *dataptr
= TOLOWER (*dataptr
);
1383 if (*dataptr
== '!' || *dataptr
== ' ')
1386 dataptr
= (char *)data_exp
;
1388 if ((dataptr
!= NULL
)
1389 && (((strstr (dataptr
, "0x")) != NULL
)
1390 || ((strstr (dataptr
, "0X")) != NULL
)))
1393 if ((data_type
!= _SIMM16_LA
)
1394 && (data_type
!= _VALUE_HI16
)
1395 && (data_type
!= _VALUE_LO16
)
1396 && (data_type
!= _IMM16
)
1397 && (data_type
!= _IMM15
)
1398 && (data_type
!= _IMM14
)
1399 && (data_type
!= _IMM4
)
1400 && (data_type
!= _IMM5
)
1401 && (data_type
!= _IMM5_MULTI_LOAD
)
1402 && (data_type
!= _IMM11
)
1403 && (data_type
!= _IMM8
)
1404 && (data_type
!= _IMM5_RSHIFT_1
)
1405 && (data_type
!= _IMM5_RSHIFT_2
)
1406 && (data_type
!= _SIMM14
)
1407 && (data_type
!= _SIMM14_NEG
)
1408 && (data_type
!= _SIMM16_NEG
)
1409 && (data_type
!= _IMM10_RSHIFT_2
)
1410 && (data_type
!= _GP_IMM15
)
1411 && (data_type
!= _SIMM5
)
1412 && (data_type
!= _SIMM6
)
1413 && (data_type
!= _IMM32
)
1414 && (data_type
!= _SIMM32
))
1420 if ((s3_inst
.reloc
.exp
.X_add_number
== 0)
1421 && (s3_inst
.type
!= Insn_Type_SYN
)
1422 && (s3_inst
.type
!= Rd_rvalueRs_SI15
)
1423 && (s3_inst
.type
!= Rd_lvalueRs_SI15
)
1424 && (s3_inst
.type
!= Insn_internal
)
1425 && (((*dataptr
>= 'a') && (*dataptr
<= 'z'))
1426 || ((*dataptr
== '0') && (*(dataptr
+ 1) == 'x') && (*(dataptr
+ 2) != '0'))
1427 || ((*dataptr
== '+') && (*(dataptr
+ 1) != '0'))
1428 || ((*dataptr
== '-') && (*(dataptr
+ 1) != '0'))))
1430 s3_inst
.error
= s3_BAD_ARGS
;
1431 return (int) s3_FAIL
;
1435 if ((s3_inst
.reloc
.exp
.X_add_symbol
)
1436 && ((data_type
== _SIMM16
)
1437 || (data_type
== _SIMM16_NEG
)
1438 || (data_type
== _IMM16_NEG
)
1439 || (data_type
== _SIMM14
)
1440 || (data_type
== _SIMM14_NEG
)
1441 || (data_type
== _IMM5
)
1442 || (data_type
== _IMM5_MULTI_LOAD
)
1443 || (data_type
== _IMM11
)
1444 || (data_type
== _IMM14
)
1445 || (data_type
== _IMM20
)
1446 || (data_type
== _IMM16
)
1447 || (data_type
== _IMM15
)
1448 || (data_type
== _IMM4
)))
1450 s3_inst
.error
= s3_BAD_ARGS
;
1451 return (int) s3_FAIL
;
1454 if (s3_inst
.reloc
.exp
.X_add_symbol
)
1459 return (int) s3_FAIL
;
1461 s3_inst
.reloc
.type
= BFD_RELOC_HI16_S
;
1462 s3_inst
.reloc
.pc_rel
= 0;
1465 s3_inst
.reloc
.type
= BFD_RELOC_LO16
;
1466 s3_inst
.reloc
.pc_rel
= 0;
1469 s3_inst
.reloc
.type
= BFD_RELOC_SCORE_GPREL15
;
1470 s3_inst
.reloc
.pc_rel
= 0;
1473 case _IMM16_LO16_pic
:
1474 s3_inst
.reloc
.type
= BFD_RELOC_SCORE_GOT_LO16
;
1475 s3_inst
.reloc
.pc_rel
= 0;
1478 s3_inst
.reloc
.type
= BFD_RELOC_32
;
1479 s3_inst
.reloc
.pc_rel
= 0;
1485 if (data_type
== _IMM16_pic
)
1487 s3_inst
.reloc
.type
= BFD_RELOC_SCORE_DUMMY_HI16
;
1488 s3_inst
.reloc
.pc_rel
= 0;
1491 if (data_type
== _SIMM16_LA
&& s3_inst
.reloc
.exp
.X_unsigned
== 1)
1493 value
= s3_validate_immediate (s3_inst
.reloc
.exp
.X_add_number
, _SIMM16_LA_POS
, hex_p
);
1494 if (value
== (int) s3_FAIL
) /* for advance to check if this is ldis */
1495 if ((s3_inst
.reloc
.exp
.X_add_number
& 0xffff) == 0)
1497 s3_inst
.instruction
|= 0x8000000;
1498 s3_inst
.instruction
|= ((s3_inst
.reloc
.exp
.X_add_number
>> 16) << 1) & 0x1fffe;
1504 value
= s3_validate_immediate (s3_inst
.reloc
.exp
.X_add_number
, data_type
, hex_p
);
1507 if (value
== (int) s3_FAIL
)
1509 if (data_type
== _IMM32
)
1511 sprintf (s3_err_msg
,
1512 _("invalid constant: %d bit expression not in range %u..%u"),
1513 s3_score_df_range
[data_type
].bits
,
1514 0, (unsigned)0xffffffff);
1516 else if (data_type
== _IMM5_MULTI_LOAD
)
1518 sprintf (s3_err_msg
,
1519 _("invalid constant: %d bit expression not in range %u..%u"),
1522 else if ((data_type
!= _SIMM14_NEG
) && (data_type
!= _SIMM16_NEG
) && (data_type
!= _IMM16_NEG
))
1524 sprintf (s3_err_msg
,
1525 _("invalid constant: %d bit expression not in range %d..%d"),
1526 s3_score_df_range
[data_type
].bits
,
1527 s3_score_df_range
[data_type
].range
[0], s3_score_df_range
[data_type
].range
[1]);
1531 sprintf (s3_err_msg
,
1532 _("invalid constant: %d bit expression not in range %d..%d"),
1533 s3_score_df_range
[data_type
].bits
,
1534 -s3_score_df_range
[data_type
].range
[1], -s3_score_df_range
[data_type
].range
[0]);
1537 s3_inst
.error
= s3_err_msg
;
1538 return (int) s3_FAIL
;
1541 if (((s3_score_df_range
[data_type
].range
[0] != 0) || (data_type
== _IMM5_RANGE_8_31
))
1542 && data_type
!= _IMM5_MULTI_LOAD
)
1544 value
&= (1 << s3_score_df_range
[data_type
].bits
) - 1;
1547 s3_inst
.instruction
|= value
<< shift
;
1550 if ((s3_inst
.instruction
& 0x3e000000) == 0x30000000)
1552 if ((((s3_inst
.instruction
>> 20) & 0x1F) != 0)
1553 && (((s3_inst
.instruction
>> 20) & 0x1F) != 1)
1554 && (((s3_inst
.instruction
>> 20) & 0x1F) != 2)
1555 && (((s3_inst
.instruction
>> 20) & 0x1F) != 0x10))
1557 s3_inst
.error
= _("invalid constant: bit expression not defined");
1558 return (int) s3_FAIL
;
1565 /* Handle addi/addi.c/addis.c/cmpi.c/addis.c/ldi. */
1567 s3_do_rdsi16 (char *str
)
1569 s3_skip_whitespace (str
);
1571 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
1572 || s3_skip_past_comma (&str
) == (int) s3_FAIL
1573 || s3_data_op2 (&str
, 1, _SIMM16
) == (int) s3_FAIL
1574 || s3_end_of_line (str
) == (int) s3_FAIL
)
1577 /* ldi.->ldiu! only for imm5 */
1578 if ((s3_inst
.instruction
& 0x20c0000) == 0x20c0000)
1580 if ((s3_inst
.instruction
& 0x1ffc0) != 0)
1582 s3_inst
.relax_inst
= 0x8000;
1586 s3_inst
.relax_inst
|= (s3_inst
.instruction
>> 1) & 0x1f;
1587 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>> 20)& 0x1f) <<5);
1588 s3_inst
.relax_size
= 2;
1592 else if ((s3_inst
.instruction
& 0x02040001) == 0x02040001)
1594 /* imm <=0x3f (5 bit<<1)*/
1595 if (((s3_inst
.instruction
& 0x1ffe0) == 0)
1596 || (((s3_inst
.instruction
& 0x1ffe0) == 0x1ffe0)
1597 && (s3_inst
.instruction
& 0x003e) != 0))
1599 s3_inst
.relax_inst
|= (s3_inst
.instruction
>> 1) & 0x1f;
1600 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>> 20) & 0x1f) << 5);
1601 s3_inst
.relax_size
= 2;
1605 s3_inst
.relax_inst
=0x8000;
1610 else if (((s3_inst
.instruction
& 0x2000000) == 0x02000000) && (s3_inst
.relax_inst
!=0x8000))
1612 /* rd : 0-16 ; imm <=0x7f (6 bit<<1)*/
1613 if ((((s3_inst
.instruction
>> 20) & 0x10) != 0x10)
1614 && (((s3_inst
.instruction
& 0x1ffc0) == 0)
1615 || (((s3_inst
.instruction
& 0x1ffc0) == 0x1ffc0)
1616 && (s3_inst
.instruction
& 0x007e) != 0)))
1618 s3_inst
.relax_inst
|= (s3_inst
.instruction
>> 1) & 0x3f;
1619 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>> 20) & 0xf) << 6);
1620 s3_inst
.relax_size
= 2;
1624 s3_inst
.relax_inst
=0x8000;
1628 else if (((s3_inst
.instruction
>> 20) & 0x10) == 0x10)
1630 s3_inst
.relax_inst
= 0x8000;
1635 s3_do_ldis (char *str
)
1637 s3_skip_whitespace (str
);
1639 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
1640 || s3_skip_past_comma (&str
) == (int) s3_FAIL
1641 || s3_data_op2 (&str
, 1, _IMM16
) == (int) s3_FAIL
1642 || s3_end_of_line (str
) == (int) s3_FAIL
)
1646 /* Handle subi/subi.c. */
1648 s3_do_sub_rdsi16 (char *str
)
1650 s3_skip_whitespace (str
);
1652 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) != (int) s3_FAIL
1653 && s3_skip_past_comma (&str
) != (int) s3_FAIL
1654 && s3_data_op2 (&str
, 1, _SIMM16_NEG
) != (int) s3_FAIL
)
1655 s3_end_of_line (str
);
1658 /* Handle subis/subis.c. */
1660 s3_do_sub_rdi16 (char *str
)
1662 s3_skip_whitespace (str
);
1664 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) != (int) s3_FAIL
1665 && s3_skip_past_comma (&str
) != (int) s3_FAIL
1666 && s3_data_op2 (&str
, 1, _IMM16_NEG
) != (int) s3_FAIL
)
1667 s3_end_of_line (str
);
1670 /* Handle addri/addri.c. */
1672 s3_do_rdrssi14 (char *str
) /* -(2^13)~((2^13)-1) */
1674 s3_skip_whitespace (str
);
1676 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) != (int) s3_FAIL
1677 && s3_skip_past_comma (&str
) != (int) s3_FAIL
1678 && s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) != (int) s3_FAIL
1679 && s3_skip_past_comma (&str
) != (int) s3_FAIL
)
1680 s3_data_op2 (&str
, 1, _SIMM14
);
1683 /* Handle subri.c/subri. */
1685 s3_do_sub_rdrssi14 (char *str
) /* -(2^13)~((2^13)-1) */
1687 s3_skip_whitespace (str
);
1689 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) != (int) s3_FAIL
1690 && s3_skip_past_comma (&str
) != (int) s3_FAIL
1691 && s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) != (int) s3_FAIL
1692 && s3_skip_past_comma (&str
) != (int) s3_FAIL
1693 && s3_data_op2 (&str
, 1, _SIMM14_NEG
) != (int) s3_FAIL
)
1694 s3_end_of_line (str
);
1697 /* Handle bitclr.c/bitset.c/bittgl.c/slli.c/srai.c/srli.c/roli.c/rori.c/rolic.c.
1700 s3_do_rdrsi5 (char *str
)
1702 s3_skip_whitespace (str
);
1704 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
1705 || s3_skip_past_comma (&str
) == (int) s3_FAIL
1706 || s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
1707 || s3_skip_past_comma (&str
) == (int) s3_FAIL
1708 || s3_data_op2 (&str
, 10, _IMM5
) == (int) s3_FAIL
1709 || s3_end_of_line (str
) == (int) s3_FAIL
)
1712 if ((((s3_inst
.instruction
>> 20) & 0x1f) == ((s3_inst
.instruction
>> 15) & 0x1f))
1713 && (s3_inst
.relax_inst
!= 0x8000) && (((s3_inst
.instruction
>> 15) & 0x10) == 0))
1715 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>> 10) & 0x1f) ) | (((s3_inst
.instruction
>> 15) & 0xf) << 5);
1716 s3_inst
.relax_size
= 2;
1719 s3_inst
.relax_inst
= 0x8000;
1722 /* Handle andri/orri/andri.c/orri.c.
1725 s3_do_rdrsi14 (char *str
)
1727 s3_skip_whitespace (str
);
1729 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) != (int) s3_FAIL
1730 && s3_skip_past_comma (&str
) != (int) s3_FAIL
1731 && s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) != (int) s3_FAIL
1732 && s3_skip_past_comma (&str
) != (int) s3_FAIL
1733 && s3_data_op2 (&str
, 1, _IMM14
) != (int) s3_FAIL
)
1734 s3_end_of_line (str
);
1737 /* Handle bittst.c. */
1739 s3_do_xrsi5 (char *str
)
1741 s3_skip_whitespace (str
);
1743 if (s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
1744 || s3_skip_past_comma (&str
) == (int) s3_FAIL
1745 || s3_data_op2 (&str
, 10, _IMM5
) == (int) s3_FAIL
1746 || s3_end_of_line (str
) == (int) s3_FAIL
)
1749 if ((s3_inst
.relax_inst
!= 0x8000) && (((s3_inst
.instruction
>> 15) & 0x10) == 0))
1751 s3_inst
.relax_inst
|= ((s3_inst
.instruction
>> 10) & 0x1f) | (((s3_inst
.instruction
>> 15) & 0xf) << 5);
1752 s3_inst
.relax_size
= 2;
1755 s3_inst
.relax_inst
= 0x8000;
1758 /* Handle addis/andi/ori/andis/oris/ldis. */
1760 s3_do_rdi16 (char *str
)
1762 s3_skip_whitespace (str
);
1764 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
1765 || s3_skip_past_comma (&str
) == (int) s3_FAIL
1766 || s3_data_op2 (&str
, 1, _IMM16
) == (int) s3_FAIL
1767 || s3_end_of_line (str
) == (int) s3_FAIL
)
1771 if ((s3_inst
.instruction
& 0x3e0e0000) == 0x0a0c0000)
1773 /* rd : 0-16 ;imm =0 -> can transform to addi!*/
1774 if ((((s3_inst
.instruction
>> 20) & 0x10) != 0x10) && ((s3_inst
.instruction
& 0x1ffff)==0))
1776 s3_inst
.relax_inst
=0x5400; /* ldiu! */
1777 s3_inst
.relax_inst
|= (s3_inst
.instruction
>> 1) & 0x1f;
1778 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>> 20) & 0xf) << 5);
1779 s3_inst
.relax_size
= 2;
1783 s3_inst
.relax_inst
=0x8000;
1789 else if ((s3_inst
.instruction
& 0x3e0e0001) == 0x0a000000)
1791 /* rd : 0-16 ;imm =0 -> can transform to addi!*/
1792 if ((((s3_inst
.instruction
>> 20) & 0x10) != 0x10) && ((s3_inst
.instruction
& 0x1ffff)==0))
1794 s3_inst
.relax_inst
=0x5c00; /* addi! */
1795 s3_inst
.relax_inst
|= (s3_inst
.instruction
>> 1) & 0x3f;
1796 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>> 20) & 0xf) << 6);
1797 s3_inst
.relax_size
= 2;
1801 s3_inst
.relax_inst
=0x8000;
1808 s3_do_macro_rdi32hi (char *str
)
1810 s3_skip_whitespace (str
);
1812 /* Do not handle s3_end_of_line(). */
1813 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) != (int) s3_FAIL
1814 && s3_skip_past_comma (&str
) != (int) s3_FAIL
)
1815 s3_data_op2 (&str
, 1, _VALUE_HI16
);
1819 s3_do_macro_rdi32lo (char *str
)
1821 s3_skip_whitespace (str
);
1823 /* Do not handle s3_end_of_line(). */
1824 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) != (int) s3_FAIL
1825 && s3_skip_past_comma (&str
) != (int) s3_FAIL
)
1826 s3_data_op2 (&str
, 1, _VALUE_LO16
);
1829 /* Handle ldis_pic. */
1831 s3_do_rdi16_pic (char *str
)
1833 s3_skip_whitespace (str
);
1835 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) != (int) s3_FAIL
1836 && s3_skip_past_comma (&str
) != (int) s3_FAIL
1837 && s3_data_op2 (&str
, 1, _IMM16_pic
) != (int) s3_FAIL
)
1838 s3_end_of_line (str
);
1841 /* Handle addi_s_pic to generate R_SCORE_GOT_LO16 . */
1843 s3_do_addi_s_pic (char *str
)
1845 s3_skip_whitespace (str
);
1847 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) != (int) s3_FAIL
1848 && s3_skip_past_comma (&str
) != (int) s3_FAIL
1849 && s3_data_op2 (&str
, 1, _SIMM16_pic
) != (int) s3_FAIL
)
1850 s3_end_of_line (str
);
1853 /* Handle addi_u_pic to generate R_SCORE_GOT_LO16 . */
1855 s3_do_addi_u_pic (char *str
)
1857 s3_skip_whitespace (str
);
1859 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) != (int) s3_FAIL
1860 && s3_skip_past_comma (&str
) != (int) s3_FAIL
1861 && s3_data_op2 (&str
, 1, _IMM16_LO16_pic
) != (int) s3_FAIL
)
1862 s3_end_of_line (str
);
1865 /* Handle mfceh/mfcel/mtceh/mtchl. */
1867 s3_do_rd (char *str
)
1869 s3_skip_whitespace (str
);
1871 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) != (int) s3_FAIL
)
1872 s3_end_of_line (str
);
1875 /* Handle br{cond},cmpzteq.c ,cmpztmi.c ,cmpz.c */
1877 s3_do_rs (char *str
)
1879 s3_skip_whitespace (str
);
1881 if (s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
1882 || s3_end_of_line (str
) == (int) s3_FAIL
)
1885 if ((s3_inst
.relax_inst
!= 0x8000) )
1887 s3_inst
.relax_inst
|= ((s3_inst
.instruction
>> 15) &0x1f);
1888 s3_inst
.relax_size
= 2;
1891 s3_inst
.relax_inst
= 0x8000;
1895 s3_do_i15 (char *str
)
1897 s3_skip_whitespace (str
);
1899 if (s3_data_op2 (&str
, 10, _IMM15
) != (int) s3_FAIL
)
1900 s3_end_of_line (str
);
1904 s3_do_xi5x (char *str
)
1906 s3_skip_whitespace (str
);
1908 if (s3_data_op2 (&str
, 15, _IMM5
) == (int) s3_FAIL
|| s3_end_of_line (str
) == (int) s3_FAIL
)
1911 if (s3_inst
.relax_inst
!= 0x8000)
1913 s3_inst
.relax_inst
|= ((s3_inst
.instruction
>> 15) & 0x1f);
1914 s3_inst
.relax_size
= 2;
1919 s3_do_rdrs (char *str
)
1921 s3_skip_whitespace (str
);
1923 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
1924 || s3_skip_past_comma (&str
) == (int) s3_FAIL
1925 || s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
1926 || s3_end_of_line (str
) == (int) s3_FAIL
)
1929 if (s3_inst
.relax_inst
!= 0x8000)
1931 if (((s3_inst
.instruction
& 0x7f) == 0x56)) /* adjust mv -> mv!*/
1933 /* mv! rd : 5bit , ra : 5bit */
1934 s3_inst
.relax_inst
|= ((s3_inst
.instruction
>> 15) & 0x1f) | (((s3_inst
.instruction
>> 20) & 0x1f) << 5);
1935 s3_inst
.relax_size
= 2;
1937 else if ((((s3_inst
.instruction
>> 15) & 0x10) == 0x0) && (((s3_inst
.instruction
>> 20) & 0x10) == 0))
1939 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>> 15) & 0xf) << 4)
1940 | (((s3_inst
.instruction
>> 20) & 0xf) << 8);
1941 s3_inst
.relax_size
= 2;
1945 s3_inst
.relax_inst
= 0x8000;
1950 /* Handle mfcr/mtcr. */
1952 s3_do_rdcrs (char *str
)
1954 s3_skip_whitespace (str
);
1956 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) != (int) s3_FAIL
1957 && s3_skip_past_comma (&str
) != (int) s3_FAIL
1958 && s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE_CR
) != (int) s3_FAIL
)
1959 s3_end_of_line (str
);
1962 /* Handle mfsr/mtsr. */
1964 s3_do_rdsrs (char *str
)
1966 s3_skip_whitespace (str
);
1969 if ((s3_inst
.instruction
& 0xff) == 0x50)
1971 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) != (int) s3_FAIL
1972 && s3_skip_past_comma (&str
) != (int) s3_FAIL
1973 && s3_reg_required_here (&str
, 10, s3_REG_TYPE_SCORE_SR
) != (int) s3_FAIL
)
1974 s3_end_of_line (str
);
1978 if (s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) != (int) s3_FAIL
1979 && s3_skip_past_comma (&str
) != (int) s3_FAIL
)
1980 s3_reg_required_here (&str
, 10, s3_REG_TYPE_SCORE_SR
);
1986 s3_do_rdxrs (char *str
)
1988 s3_skip_whitespace (str
);
1990 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
1991 || s3_skip_past_comma (&str
) == (int) s3_FAIL
1992 || s3_reg_required_here (&str
, 10, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
1993 || s3_end_of_line (str
) == (int) s3_FAIL
)
1996 if ((s3_inst
.relax_inst
!= 0x8000) && (((s3_inst
.instruction
>> 10) & 0x10) == 0)
1997 && (((s3_inst
.instruction
>> 20) & 0x10) == 0))
1999 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>> 10) & 0xf) << 4) | (((s3_inst
.instruction
>> 20) & 0xf) << 8);
2000 s3_inst
.relax_size
= 2;
2003 s3_inst
.relax_inst
= 0x8000;
2006 /* Handle cmp.c/cmp<cond>. */
2008 s3_do_rsrs (char *str
)
2010 s3_skip_whitespace (str
);
2012 if (s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
2013 || s3_skip_past_comma (&str
) == (int) s3_FAIL
2014 || s3_reg_required_here (&str
, 10, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
2015 || s3_end_of_line (str
) == (int) s3_FAIL
)
2018 if ((s3_inst
.relax_inst
!= 0x8000) && (((s3_inst
.instruction
>> 20) & 0x1f) == 3) )
2020 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>> 10) & 0x1f)) | (((s3_inst
.instruction
>> 15) & 0x1f) << 5);
2021 s3_inst
.relax_size
= 2;
2024 s3_inst
.relax_inst
= 0x8000;
2028 s3_do_ceinst (char *str
)
2033 s3_skip_whitespace (str
);
2035 if (s3_data_op2 (&str
, 20, _IMM5
) == (int) s3_FAIL
2036 || s3_skip_past_comma (&str
) == (int) s3_FAIL
2037 || s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
2038 || s3_skip_past_comma (&str
) == (int) s3_FAIL
2039 || s3_reg_required_here (&str
, 10, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
2040 || s3_skip_past_comma (&str
) == (int) s3_FAIL
2041 || s3_data_op2 (&str
, 5, _IMM5
) == (int) s3_FAIL
2042 || s3_skip_past_comma (&str
) == (int) s3_FAIL
2043 || s3_data_op2 (&str
, 0, _IMM5
) == (int) s3_FAIL
2044 || s3_end_of_line (str
) == (int) s3_FAIL
)
2051 if (s3_data_op2 (&str
, 0, _IMM25
) == (int) s3_FAIL
)
2057 s3_reglow_required_here (char **str
, int shift
)
2059 static char buff
[s3_MAX_LITERAL_POOL_SIZE
];
2063 if ((reg
= s3_score_reg_parse (str
, s3_all_reg_maps
[s3_REG_TYPE_SCORE
].htab
)) != (int) s3_FAIL
)
2065 if ((reg
== 1) && (s3_nor1
== 1) && (s3_inst
.bwarn
== 0))
2067 as_warn (_("Using temp register(r1)"));
2073 s3_inst
.instruction
|= (bfd_vma
) reg
<< shift
;
2079 /* Restore the start point, we may have got a reg of the wrong class. */
2081 sprintf (buff
, _("low register (r0-r15) expected, not '%.100s'"), start
);
2082 s3_inst
.error
= buff
;
2083 return (int) s3_FAIL
;
2086 /* Handle add!/and!/or!/sub!. */
2088 s3_do16_rdrs2 (char *str
)
2090 s3_skip_whitespace (str
);
2092 if (s3_reglow_required_here (&str
, 4) == (int) s3_FAIL
2093 || s3_skip_past_comma (&str
) == (int) s3_FAIL
2094 || s3_reglow_required_here (&str
, 0) == (int) s3_FAIL
2095 || s3_end_of_line (str
) == (int) s3_FAIL
)
2101 /* Handle br!/brl!. */
2103 s3_do16_br (char *str
)
2105 s3_skip_whitespace (str
);
2107 if (s3_reg_required_here (&str
, 0, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
2108 || s3_end_of_line (str
) == (int) s3_FAIL
)
2116 s3_do16_brr (char *str
)
2120 s3_skip_whitespace (str
);
2122 if ((rd
= s3_reg_required_here (&str
, 0,s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
2123 || s3_end_of_line (str
) == (int) s3_FAIL
)
2129 /*Handle ltbw / ltbh / ltbb */
2131 s3_do_ltb (char *str
)
2133 s3_skip_whitespace (str
);
2134 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
2135 || s3_skip_past_comma (&str
) == (int) s3_FAIL
)
2140 s3_skip_whitespace (str
);
2143 s3_inst
.error
= _("missing [");
2147 if (s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
2148 || s3_skip_past_comma (&str
) == (int) s3_FAIL
2149 || s3_reg_required_here (&str
, 10, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
)
2154 s3_skip_whitespace (str
);
2157 s3_inst
.error
= _("missing ]");
2162 /* We need to be able to fix up arbitrary expressions in some statements.
2163 This is so that we can handle symbols that are an arbitrary distance from
2164 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
2165 which returns part of an address in a form which will be valid for
2166 a data instruction. We do this by pushing the expression into a symbol
2167 in the expr_section, and creating a fix for that. */
2169 s3_fix_new_score (fragS
* frag
, int where
, short int size
, expressionS
* exp
, int pc_rel
, int reloc
)
2179 new_fix
= fix_new_exp (frag
, where
, size
, exp
, pc_rel
, reloc
);
2182 new_fix
= fix_new (frag
, where
, size
, make_expr_symbol (exp
), 0, pc_rel
, reloc
);
2189 s3_init_dependency_vector (void)
2193 for (i
= 0; i
< s3_vector_size
; i
++)
2194 memset (&s3_dependency_vector
[i
], '\0', sizeof (s3_dependency_vector
[i
]));
2199 static enum s3_insn_type_for_dependency
2200 s3_dependency_type_from_insn (char *insn_name
)
2202 char name
[s3_INSN_NAME_LEN
];
2203 const struct s3_insn_to_dependency
*tmp
;
2205 strcpy (name
, insn_name
);
2206 tmp
= (const struct s3_insn_to_dependency
*)
2207 str_hash_find (s3_dependency_insn_hsh
, name
);
2212 return s3_D_all_insn
;
2216 s3_check_dependency (char *pre_insn
, char *pre_reg
,
2217 char *cur_insn
, char *cur_reg
, int *warn_or_error
)
2221 enum s3_insn_type_for_dependency pre_insn_type
;
2222 enum s3_insn_type_for_dependency cur_insn_type
;
2224 pre_insn_type
= s3_dependency_type_from_insn (pre_insn
);
2225 cur_insn_type
= s3_dependency_type_from_insn (cur_insn
);
2227 for (i
= 0; i
< sizeof (s3_data_dependency_table
) / sizeof (s3_data_dependency_table
[0]); i
++)
2229 if ((pre_insn_type
== s3_data_dependency_table
[i
].pre_insn_type
)
2230 && (s3_D_all_insn
== s3_data_dependency_table
[i
].cur_insn_type
2231 || cur_insn_type
== s3_data_dependency_table
[i
].cur_insn_type
)
2232 && (strcmp (s3_data_dependency_table
[i
].pre_reg
, "") == 0
2233 || strcmp (s3_data_dependency_table
[i
].pre_reg
, pre_reg
) == 0)
2234 && (strcmp (s3_data_dependency_table
[i
].cur_reg
, "") == 0
2235 || strcmp (s3_data_dependency_table
[i
].cur_reg
, cur_reg
) == 0))
2237 bubbles
= s3_data_dependency_table
[i
].bubblenum_3
;
2238 *warn_or_error
= s3_data_dependency_table
[i
].warn_or_error
;
2247 s3_build_one_frag (struct s3_score_it one_inst
)
2250 int relaxable_p
= s3_g_opt
;
2253 /* Start a new frag if frag_now is not empty. */
2254 if (frag_now_fix () != 0)
2256 if (!frag_now
->tc_frag_data
.is_insn
)
2257 frag_wane (frag_now
);
2263 p
= frag_more (one_inst
.size
);
2264 s3_md_number_to_chars (p
, one_inst
.instruction
, one_inst
.size
);
2267 dwarf2_emit_insn (one_inst
.size
);
2270 relaxable_p
&= (one_inst
.relax_size
!= 0);
2271 relax_size
= relaxable_p
? one_inst
.relax_size
: 0;
2273 p
= frag_var (rs_machine_dependent
, relax_size
+ s3_RELAX_PAD_BYTE
, 0,
2274 s3_RELAX_ENCODE (one_inst
.size
, one_inst
.relax_size
,
2275 one_inst
.type
, 0, 0, relaxable_p
),
2279 s3_md_number_to_chars (p
, one_inst
.relax_inst
, relax_size
);
2283 s3_handle_dependency (struct s3_score_it
*theinst
)
2286 int warn_or_error
= 0; /* warn - 0; error - 1 */
2288 int remainder_bubbles
= 0;
2289 char cur_insn
[s3_INSN_NAME_LEN
];
2290 char pre_insn
[s3_INSN_NAME_LEN
];
2291 struct s3_score_it nop_inst
;
2292 struct s3_score_it pflush_inst
;
2294 nop_inst
.instruction
= 0x0000;
2296 nop_inst
.relax_inst
= 0x80008000;
2297 nop_inst
.relax_size
= 4;
2298 nop_inst
.type
= NO16_OPD
;
2300 pflush_inst
.instruction
= 0x8000800a;
2301 pflush_inst
.size
= 4;
2302 pflush_inst
.relax_inst
= 0x8000;
2303 pflush_inst
.relax_size
= 0;
2304 pflush_inst
.type
= NO_OPD
;
2306 /* pflush will clear all data dependency. */
2307 if (strcmp (theinst
->name
, "pflush") == 0)
2309 s3_init_dependency_vector ();
2313 /* Push current instruction to s3_dependency_vector[0]. */
2314 for (i
= s3_vector_size
- 1; i
> 0; i
--)
2315 memcpy (&s3_dependency_vector
[i
], &s3_dependency_vector
[i
- 1], sizeof (s3_dependency_vector
[i
]));
2317 memcpy (&s3_dependency_vector
[0], theinst
, sizeof (s3_dependency_vector
[i
]));
2319 /* There is no dependency between nop and any instruction. */
2320 if (strcmp (s3_dependency_vector
[0].name
, "nop") == 0
2321 || strcmp (s3_dependency_vector
[0].name
, "nop!") == 0)
2324 strcpy (cur_insn
, s3_dependency_vector
[0].name
);
2326 for (i
= 1; i
< s3_vector_size
; i
++)
2328 /* The element of s3_dependency_vector is NULL. */
2329 if (s3_dependency_vector
[i
].name
[0] == '\0')
2332 strcpy (pre_insn
, s3_dependency_vector
[i
].name
);
2334 bubbles
= s3_check_dependency (pre_insn
, s3_dependency_vector
[i
].reg
,
2335 cur_insn
, s3_dependency_vector
[0].reg
, &warn_or_error
);
2336 remainder_bubbles
= bubbles
- i
+ 1;
2338 if (remainder_bubbles
> 0)
2342 if (s3_fix_data_dependency
== 1)
2344 if (remainder_bubbles
<= 2)
2346 if (s3_warn_fix_data_dependency
)
2347 as_warn (_("Fix data dependency: %s %s -- %s %s (insert %d nop!/%d)"),
2348 s3_dependency_vector
[i
].name
, s3_dependency_vector
[i
].reg
,
2349 s3_dependency_vector
[0].name
, s3_dependency_vector
[0].reg
,
2350 remainder_bubbles
, bubbles
);
2352 for (j
= (s3_vector_size
- 1); (j
- remainder_bubbles
) > 0; j
--)
2353 memcpy (&s3_dependency_vector
[j
], &s3_dependency_vector
[j
- remainder_bubbles
],
2354 sizeof (s3_dependency_vector
[j
]));
2356 for (j
= 1; j
<= remainder_bubbles
; j
++)
2358 memset (&s3_dependency_vector
[j
], '\0', sizeof (s3_dependency_vector
[j
]));
2360 s3_build_one_frag (nop_inst
);
2365 if (s3_warn_fix_data_dependency
)
2366 as_warn (_("Fix data dependency: %s %s -- %s %s (insert 1 pflush/%d)"),
2367 s3_dependency_vector
[i
].name
, s3_dependency_vector
[i
].reg
,
2368 s3_dependency_vector
[0].name
, s3_dependency_vector
[0].reg
,
2371 for (j
= 1; j
< s3_vector_size
; j
++)
2372 memset (&s3_dependency_vector
[j
], '\0', sizeof (s3_dependency_vector
[j
]));
2374 /* Insert pflush. */
2375 s3_build_one_frag (pflush_inst
);
2382 as_bad (_("data dependency: %s %s -- %s %s (%d/%d bubble)"),
2383 s3_dependency_vector
[i
].name
, s3_dependency_vector
[i
].reg
,
2384 s3_dependency_vector
[0].name
, s3_dependency_vector
[0].reg
,
2385 remainder_bubbles
, bubbles
);
2389 as_warn (_("data dependency: %s %s -- %s %s (%d/%d bubble)"),
2390 s3_dependency_vector
[i
].name
, s3_dependency_vector
[i
].reg
,
2391 s3_dependency_vector
[0].name
, s3_dependency_vector
[0].reg
,
2392 remainder_bubbles
, bubbles
);
2399 static enum insn_class
2400 s3_get_insn_class_from_type (enum score_insn_type type
)
2402 enum insn_class retval
= (int) s3_FAIL
;
2408 case Rd_rvalueBP_I5
:
2409 case Rd_lvalueBP_I5
:
2422 retval
= INSN_CLASS_16
;
2431 case Rd_rvalueRs_SI10
:
2432 case Rd_lvalueRs_SI10
:
2433 case Rd_rvalueRs_preSI12
:
2434 case Rd_rvalueRs_postSI12
:
2435 case Rd_lvalueRs_preSI12
:
2436 case Rd_lvalueRs_postSI12
:
2438 case Rd_rvalueRs_SI15
:
2439 case Rd_lvalueRs_SI15
:
2448 case OP5_rvalueRs_SI15
:
2449 case I5_Rs_Rs_I5_OP5
:
2450 case x_rvalueRs_post4
:
2451 case Rd_rvalueRs_post4
:
2453 case Rd_lvalueRs_post4
:
2454 case x_lvalueRs_post4
:
2464 retval
= INSN_CLASS_32
;
2467 retval
= INSN_CLASS_PCE
;
2470 retval
= INSN_CLASS_SYN
;
2474 retval
= INSN_CLASS_48
;
2484 48-bit instruction: 1, 1, 0.
2485 32-bit instruction: 1, 0.
2486 16-bit instruction: 0. */
2488 s3_adjust_paritybit (bfd_vma m_code
, enum insn_class i_class
)
2491 bfd_vma m_code_high
= 0;
2492 unsigned long m_code_middle
= 0;
2493 unsigned long m_code_low
= 0;
2494 bfd_vma pb_high
= 0;
2495 unsigned long pb_middle
= 0;
2496 unsigned long pb_low
= 0;
2498 if (i_class
== INSN_CLASS_48
)
2500 pb_high
= 0x800000000000LL
;
2501 pb_middle
= 0x80000000;
2502 pb_low
= 0x00000000;
2503 m_code_high
= m_code
& 0x1fffc0000000LL
;
2504 m_code_middle
= m_code
& 0x3fff8000;
2505 m_code_low
= m_code
& 0x00007fff;
2506 result
= pb_high
| (m_code_high
<< 2) |
2507 pb_middle
| (m_code_middle
<< 1) |
2508 pb_low
| m_code_low
;
2510 else if (i_class
== INSN_CLASS_32
|| i_class
== INSN_CLASS_SYN
)
2512 pb_high
= 0x80000000;
2513 pb_low
= 0x00000000;
2514 m_code_high
= m_code
& 0x3fff8000;
2515 m_code_low
= m_code
& 0x00007fff;
2516 result
= pb_high
| (m_code_high
<< 1) | pb_low
| m_code_low
;
2518 else if (i_class
== INSN_CLASS_16
)
2522 m_code_high
= m_code
& 0x3fff8000;
2523 m_code_low
= m_code
& 0x00007fff;
2524 result
= pb_high
| (m_code_high
<< 1) | pb_low
| m_code_low
;
2526 else if (i_class
== INSN_CLASS_PCE
)
2528 /* Keep original. */
2530 pb_low
= 0x00008000;
2531 m_code_high
= m_code
& 0x3fff8000;
2532 m_code_low
= m_code
& 0x00007fff;
2533 result
= pb_high
| (m_code_high
<< 1) | pb_low
| m_code_low
;
2544 s3_gen_insn_frag (struct s3_score_it
*part_1
, struct s3_score_it
*part_2
)
2547 bfd_boolean pce_p
= FALSE
;
2548 int relaxable_p
= s3_g_opt
;
2550 struct s3_score_it
*inst1
= part_1
;
2551 struct s3_score_it
*inst2
= part_2
;
2552 struct s3_score_it backup_inst1
;
2554 pce_p
= (inst2
) ? TRUE
: FALSE
;
2555 memcpy (&backup_inst1
, inst1
, sizeof (struct s3_score_it
));
2557 /* Adjust instruction opcode and to be relaxed instruction opcode. */
2560 backup_inst1
.instruction
= ((backup_inst1
.instruction
& 0x7FFF) << 15)
2561 | (inst2
->instruction
& 0x7FFF);
2562 backup_inst1
.instruction
= s3_adjust_paritybit (backup_inst1
.instruction
, INSN_CLASS_PCE
);
2563 backup_inst1
.relax_inst
= 0x8000;
2564 backup_inst1
.size
= s3_INSN_SIZE
;
2565 backup_inst1
.relax_size
= 0;
2566 backup_inst1
.type
= Insn_Type_PCE
;
2570 backup_inst1
.instruction
= s3_adjust_paritybit (backup_inst1
.instruction
,
2571 s3_GET_INSN_CLASS (backup_inst1
.type
));
2574 if (backup_inst1
.relax_size
!= 0)
2576 enum insn_class tmp
;
2578 tmp
= (backup_inst1
.size
== s3_INSN_SIZE
) ? INSN_CLASS_16
: INSN_CLASS_32
;
2579 backup_inst1
.relax_inst
= s3_adjust_paritybit (backup_inst1
.relax_inst
, tmp
);
2582 /* Check data dependency. */
2583 s3_handle_dependency (&backup_inst1
);
2585 /* Start a new frag if frag_now is not empty and is not instruction frag, maybe it contains
2586 data produced by .ascii etc. Doing this is to make one instruction per frag. */
2587 if (frag_now_fix () != 0)
2589 if (!frag_now
->tc_frag_data
.is_insn
)
2590 frag_wane (frag_now
);
2595 /* Here, we must call frag_grow in order to keep the instruction frag type is
2596 rs_machine_dependent.
2597 For, frag_var may change frag_now->fr_type to rs_fill by calling frag_grow which
2598 actually will call frag_wane.
2599 Calling frag_grow first will create a new frag_now which free size is 20 that is enough
2603 p
= frag_more (backup_inst1
.size
);
2604 s3_md_number_to_chars (p
, backup_inst1
.instruction
, backup_inst1
.size
);
2607 dwarf2_emit_insn (backup_inst1
.size
);
2610 /* Generate fixup structure. */
2613 if (inst1
->reloc
.type
!= BFD_RELOC_NONE
)
2614 s3_fix_new_score (frag_now
, p
- frag_now
->fr_literal
,
2615 inst1
->size
, &inst1
->reloc
.exp
,
2616 inst1
->reloc
.pc_rel
, inst1
->reloc
.type
);
2618 if (inst2
->reloc
.type
!= BFD_RELOC_NONE
)
2619 s3_fix_new_score (frag_now
, p
- frag_now
->fr_literal
+ 2,
2620 inst2
->size
, &inst2
->reloc
.exp
, inst2
->reloc
.pc_rel
, inst2
->reloc
.type
);
2624 if (backup_inst1
.reloc
.type
!= BFD_RELOC_NONE
)
2625 s3_fix_new_score (frag_now
, p
- frag_now
->fr_literal
,
2626 backup_inst1
.size
, &backup_inst1
.reloc
.exp
,
2627 backup_inst1
.reloc
.pc_rel
, backup_inst1
.reloc
.type
);
2630 /* relax_size may be 2, 4, 12 or 0, 0 indicates no relaxation. */
2631 relaxable_p
&= (backup_inst1
.relax_size
!= 0);
2632 relax_size
= relaxable_p
? backup_inst1
.relax_size
: 0;
2634 p
= frag_var (rs_machine_dependent
, relax_size
+ s3_RELAX_PAD_BYTE
, 0,
2635 s3_RELAX_ENCODE (backup_inst1
.size
, backup_inst1
.relax_size
,
2636 backup_inst1
.type
, 0, 0, relaxable_p
),
2637 backup_inst1
.reloc
.exp
.X_add_symbol
, 0, NULL
);
2640 s3_md_number_to_chars (p
, backup_inst1
.relax_inst
, relax_size
);
2642 memcpy (inst1
, &backup_inst1
, sizeof (struct s3_score_it
));
2646 s3_parse_16_32_inst (char *insnstr
, bfd_boolean gen_frag_p
)
2650 char *operator = insnstr
;
2651 const struct s3_asm_opcode
*opcode
;
2653 /* Parse operator and operands. */
2654 s3_skip_whitespace (operator);
2656 for (p
= operator; *p
!= '\0'; p
++)
2657 if ((*p
== ' ') || (*p
== '!'))
2666 opcode
= (const struct s3_asm_opcode
*) str_hash_find (s3_score_ops_hsh
,
2670 memset (&s3_inst
, '\0', sizeof (s3_inst
));
2671 sprintf (s3_inst
.str
, "%s", insnstr
);
2674 s3_inst
.instruction
= opcode
->value
;
2675 s3_inst
.relax_inst
= opcode
->relax_value
;
2676 s3_inst
.type
= opcode
->type
;
2677 s3_inst
.size
= s3_GET_INSN_SIZE (s3_inst
.type
);
2678 s3_inst
.relax_size
= 0;
2680 sprintf (s3_inst
.name
, "%s", opcode
->template_name
);
2681 strcpy (s3_inst
.reg
, "");
2682 s3_inst
.error
= NULL
;
2683 s3_inst
.reloc
.type
= BFD_RELOC_NONE
;
2685 (*opcode
->parms
) (p
);
2687 /* It indicates current instruction is a macro instruction if s3_inst.bwarn equals -1. */
2688 if ((s3_inst
.bwarn
!= -1) && (!s3_inst
.error
) && (gen_frag_p
))
2689 s3_gen_insn_frag (&s3_inst
, NULL
);
2692 s3_inst
.error
= _("unrecognized opcode");
2696 s3_parse_48_inst (char *insnstr
, bfd_boolean gen_frag_p
)
2700 char *operator = insnstr
;
2701 const struct s3_asm_opcode
*opcode
;
2703 /* Parse operator and operands. */
2704 s3_skip_whitespace (operator);
2706 for (p
= operator; *p
!= '\0'; p
++)
2713 opcode
= (const struct s3_asm_opcode
*) str_hash_find (s3_score_ops_hsh
,
2717 memset (&s3_inst
, '\0', sizeof (s3_inst
));
2718 sprintf (s3_inst
.str
, "%s", insnstr
);
2721 s3_inst
.instruction
= opcode
->value
;
2722 s3_inst
.relax_inst
= opcode
->relax_value
;
2723 s3_inst
.type
= opcode
->type
;
2724 s3_inst
.size
= s3_GET_INSN_SIZE (s3_inst
.type
);
2725 s3_inst
.relax_size
= 0;
2727 sprintf (s3_inst
.name
, "%s", opcode
->template_name
);
2728 strcpy (s3_inst
.reg
, "");
2729 s3_inst
.error
= NULL
;
2730 s3_inst
.reloc
.type
= BFD_RELOC_NONE
;
2732 (*opcode
->parms
) (p
);
2734 /* It indicates current instruction is a macro instruction if s3_inst.bwarn equals -1. */
2735 if ((s3_inst
.bwarn
!= -1) && (!s3_inst
.error
) && (gen_frag_p
))
2736 s3_gen_insn_frag (&s3_inst
, NULL
);
2739 s3_inst
.error
= _("unrecognized opcode");
2743 s3_append_insn (char *str
, bfd_boolean gen_frag_p
)
2745 int retval
= s3_SUCCESS
;
2747 s3_parse_16_32_inst (str
, gen_frag_p
);
2751 retval
= (int) s3_FAIL
;
2752 as_bad (_("%s -- `%s'"), s3_inst
.error
, s3_inst
.str
);
2753 s3_inst
.error
= NULL
;
2760 s3_do16_mv_cmp (char *str
)
2762 s3_skip_whitespace (str
);
2764 if (s3_reg_required_here (&str
, 5, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
2765 || s3_skip_past_comma (&str
) == (int) s3_FAIL
2766 || s3_reg_required_here (&str
, 0, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
2767 || s3_end_of_line (str
) == (int) s3_FAIL
)
2774 s3_do16_cmpi (char *str
)
2776 s3_skip_whitespace (str
);
2778 if (s3_reg_required_here (&str
, 5, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
2779 || s3_skip_past_comma (&str
) == (int) s3_FAIL
2780 || s3_data_op2 (&str
, 0, _SIMM5
) == (int) s3_FAIL
2781 || s3_end_of_line (str
) == (int) s3_FAIL
)
2788 s3_do16_addi (char *str
)
2790 s3_skip_whitespace (str
);
2792 if (s3_reglow_required_here (&str
, 6) == (int) s3_FAIL
2793 || s3_skip_past_comma (&str
) == (int) s3_FAIL
2794 || s3_data_op2 (&str
, 0, _SIMM6
) == (int) s3_FAIL
2795 || s3_end_of_line (str
) == (int) s3_FAIL
)
2801 /* Handle bitclr! / bitset! / bittst! / bittgl! */
2803 s3_do16_rdi5 (char *str
)
2805 s3_skip_whitespace (str
);
2807 if (s3_reglow_required_here (&str
, 5) == (int) s3_FAIL
2808 || s3_skip_past_comma (&str
) == (int) s3_FAIL
2809 || s3_data_op2 (&str
, 0, _IMM5
) == (int) s3_FAIL
2810 || s3_end_of_line (str
) == (int) s3_FAIL
)
2814 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>>5) & 0xf) << 20)
2815 | (((s3_inst
.instruction
>> 5) & 0xf) << 15) | (((s3_inst
.instruction
) & 0x1f) << 10);
2816 s3_inst
.relax_size
= 4;
2821 /* Handle sdbbp!. */
2823 s3_do16_xi5 (char *str
)
2825 s3_skip_whitespace (str
);
2827 if (s3_data_op2 (&str
, 0, _IMM5
) == (int) s3_FAIL
|| s3_end_of_line (str
) == (int) s3_FAIL
)
2831 /* Check that an immediate is word alignment or half word alignment.
2832 If so, convert it to the right format. */
2834 s3_validate_immediate_align (int val
, unsigned int data_type
)
2836 if (data_type
== _IMM5_RSHIFT_1
)
2840 s3_inst
.error
= _("address offset must be half word alignment");
2841 return (int) s3_FAIL
;
2844 else if ((data_type
== _IMM5_RSHIFT_2
) || (data_type
== _IMM10_RSHIFT_2
))
2848 s3_inst
.error
= _("address offset must be word alignment");
2849 return (int) s3_FAIL
;
2857 s3_exp_ldst_offset (char **str
, int shift
, unsigned int data_type
)
2863 if ((*dataptr
== '0') && (*(dataptr
+ 1) == 'x')
2864 && (data_type
!= _SIMM16_LA
)
2865 && (data_type
!= _VALUE_HI16
)
2866 && (data_type
!= _VALUE_LO16
)
2867 && (data_type
!= _IMM16
)
2868 && (data_type
!= _IMM15
)
2869 && (data_type
!= _IMM14
)
2870 && (data_type
!= _IMM4
)
2871 && (data_type
!= _IMM5
)
2872 && (data_type
!= _IMM8
)
2873 && (data_type
!= _IMM5_RSHIFT_1
)
2874 && (data_type
!= _IMM5_RSHIFT_2
)
2875 && (data_type
!= _SIMM14_NEG
)
2876 && (data_type
!= _IMM10_RSHIFT_2
))
2881 if (s3_my_get_expression (&s3_inst
.reloc
.exp
, str
) == (int) s3_FAIL
)
2882 return (int) s3_FAIL
;
2884 if (s3_inst
.reloc
.exp
.X_op
== O_constant
)
2886 /* Need to check the immediate align. */
2887 int value
= s3_validate_immediate_align (s3_inst
.reloc
.exp
.X_add_number
, data_type
);
2889 if (value
== (int) s3_FAIL
)
2890 return (int) s3_FAIL
;
2892 value
= s3_validate_immediate (s3_inst
.reloc
.exp
.X_add_number
, data_type
, 0);
2893 if (value
== (int) s3_FAIL
)
2896 sprintf (s3_err_msg
,
2897 _("invalid constant: %d bit expression not in range %d..%d"),
2898 s3_score_df_range
[data_type
].bits
,
2899 s3_score_df_range
[data_type
].range
[0], s3_score_df_range
[data_type
].range
[1]);
2901 sprintf (s3_err_msg
,
2902 _("invalid constant: %d bit expression not in range %d..%d"),
2903 s3_score_df_range
[data_type
- 24].bits
,
2904 s3_score_df_range
[data_type
- 24].range
[0], s3_score_df_range
[data_type
- 24].range
[1]);
2905 s3_inst
.error
= s3_err_msg
;
2906 return (int) s3_FAIL
;
2909 if (data_type
== _IMM5_RSHIFT_1
)
2913 else if ((data_type
== _IMM5_RSHIFT_2
) || (data_type
== _IMM10_RSHIFT_2
))
2918 if (s3_score_df_range
[data_type
].range
[0] != 0)
2920 value
&= (1 << s3_score_df_range
[data_type
].bits
) - 1;
2923 s3_inst
.instruction
|= value
<< shift
;
2927 s3_inst
.reloc
.pc_rel
= 0;
2934 s3_do_ldst_insn (char *str
)
2944 s3_skip_whitespace (str
);
2946 if (((conflict_reg
= s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
)
2947 || (s3_skip_past_comma (&str
) == (int) s3_FAIL
))
2950 /* ld/sw rD, [rA, simm15] ld/sw rD, [rA]+, simm12 ld/sw rD, [rA, simm12]+. */
2954 s3_skip_whitespace (str
);
2956 if ((reg
= s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
)
2959 /* Conflicts can occur on stores as well as loads. */
2960 conflict_reg
= (conflict_reg
== reg
);
2961 s3_skip_whitespace (str
);
2962 temp
= str
+ 1; /* The latter will process decimal/hex expression. */
2964 /* ld/sw rD, [rA]+, simm12 ld/sw rD, [rA]+. */
2971 /* ld/sw rD, [rA]+, simm12. */
2972 if (s3_skip_past_comma (&str
) == s3_SUCCESS
)
2974 if ((s3_exp_ldst_offset (&str
, 3, _SIMM12
) == (int) s3_FAIL
)
2975 || (s3_end_of_line (str
) == (int) s3_FAIL
))
2980 unsigned int ldst_func
= s3_inst
.instruction
& OPC_PSEUDOLDST_MASK
;
2982 if ((ldst_func
== INSN_LH
)
2983 || (ldst_func
== INSN_LHU
)
2984 || (ldst_func
== INSN_LW
)
2985 || (ldst_func
== INSN_LB
)
2986 || (ldst_func
== INSN_LBU
))
2988 s3_inst
.error
= _("register same as write-back base");
2993 ldst_idx
= s3_inst
.instruction
& OPC_PSEUDOLDST_MASK
;
2994 s3_inst
.instruction
&= ~OPC_PSEUDOLDST_MASK
;
2995 s3_inst
.instruction
|= s3_score_ldst_insns
[ldst_idx
* 3 + LDST_POST
].value
;
2997 /* lw rD, [rA]+, 4 convert to pop rD, [rA]. */
2998 if ((s3_inst
.instruction
& 0x3e000007) == 0x0e000000)
3000 /* rs = r0, offset = 4 */
3001 if ((((s3_inst
.instruction
>> 15) & 0x1f) == 0)
3002 && (((s3_inst
.instruction
>> 3) & 0xfff) == 4))
3004 /* Relax to pop!. */
3005 s3_inst
.relax_inst
= 0x0040 | ((s3_inst
.instruction
>> 20) & 0x1f);
3006 s3_inst
.relax_size
= 2;
3011 /* ld/sw rD, [rA]+ convert to ld/sw rD, [rA, 0]+. */
3014 s3_SET_INSN_ERROR (NULL
);
3015 if (s3_end_of_line (str
) == (int) s3_FAIL
)
3021 value
= s3_validate_immediate (s3_inst
.reloc
.exp
.X_add_number
, _SIMM12
, 0);
3022 value
&= (1 << s3_score_df_range
[_SIMM12
].bits
) - 1;
3023 ldst_idx
= s3_inst
.instruction
& OPC_PSEUDOLDST_MASK
;
3024 s3_inst
.instruction
&= ~OPC_PSEUDOLDST_MASK
;
3025 s3_inst
.instruction
|= s3_score_ldst_insns
[ldst_idx
* 3 + pre_inc
].value
;
3026 s3_inst
.instruction
|= value
<< 3;
3027 s3_inst
.relax_inst
= 0x8000;
3031 /* ld/sw rD, [rA] convert to ld/sw rD, [rA, simm15]. */
3034 if (s3_end_of_line (str
) == (int) s3_FAIL
)
3037 ldst_idx
= s3_inst
.instruction
& OPC_PSEUDOLDST_MASK
;
3038 s3_inst
.instruction
&= ~OPC_PSEUDOLDST_MASK
;
3039 s3_inst
.instruction
|= s3_score_ldst_insns
[ldst_idx
* 3 + LDST_NOUPDATE
].value
;
3041 /* lbu rd, [rs] -> lbu! rd, [rs] */
3042 if (ldst_idx
== INSN_LBU
)
3044 s3_inst
.relax_inst
= INSN16_LBU
;
3046 else if (ldst_idx
== INSN_LH
)
3048 s3_inst
.relax_inst
= INSN16_LH
;
3050 else if (ldst_idx
== INSN_LW
)
3052 s3_inst
.relax_inst
= INSN16_LW
;
3054 else if (ldst_idx
== INSN_SB
)
3056 s3_inst
.relax_inst
= INSN16_SB
;
3058 else if (ldst_idx
== INSN_SH
)
3060 s3_inst
.relax_inst
= INSN16_SH
;
3062 else if (ldst_idx
== INSN_SW
)
3064 s3_inst
.relax_inst
= INSN16_SW
;
3068 s3_inst
.relax_inst
= 0x8000;
3071 /* lw/lh/lbu/sw/sh/sb, offset = 0, relax to 16 bit instruction. */
3072 /* if ((ldst_idx == INSN_LBU)
3073 || (ldst_idx == INSN_LH)
3074 || (ldst_idx == INSN_LW)
3075 || (ldst_idx == INSN_SB) || (ldst_idx == INSN_SH) || (ldst_idx == INSN_SW))*/
3076 if ( (ldst_idx
== INSN_LW
)|| (ldst_idx
== INSN_SW
))
3078 /* ra only 3 bit , rd only 4 bit for lw! and sw! */
3079 if ((((s3_inst
.instruction
>> 15) & 0x18) == 0) && (((s3_inst
.instruction
>> 20) & 0x10) == 0))
3081 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>> 20) & 0xf) << 8) |
3082 (((s3_inst
.instruction
>> 15) & 0x7) << 5);
3083 s3_inst
.relax_size
= 2;
3090 /* ld/sw rD, [rA, simm15] ld/sw rD, [rA, simm12]+. */
3093 if (s3_skip_past_comma (&str
) == (int) s3_FAIL
)
3095 s3_inst
.error
= _("pre-indexed expression expected");
3099 if (s3_my_get_expression (&s3_inst
.reloc
.exp
, &str
) == (int) s3_FAIL
)
3102 s3_skip_whitespace (str
);
3105 s3_inst
.error
= _("missing ]");
3109 s3_skip_whitespace (str
);
3110 /* ld/sw rD, [rA, simm12]+. */
3117 unsigned int ldst_func
= s3_inst
.instruction
& OPC_PSEUDOLDST_MASK
;
3119 if ((ldst_func
== INSN_LH
)
3120 || (ldst_func
== INSN_LHU
)
3121 || (ldst_func
== INSN_LW
)
3122 || (ldst_func
== INSN_LB
)
3123 || (ldst_func
== INSN_LBU
))
3125 s3_inst
.error
= _("register same as write-back base");
3131 if (s3_end_of_line (str
) == (int) s3_FAIL
)
3134 if (s3_inst
.reloc
.exp
.X_op
== O_constant
)
3136 unsigned int data_type
;
3139 data_type
= _SIMM12
;
3141 data_type
= _SIMM15
;
3144 if ((*dataptr
== '0') && (*(dataptr
+ 1) == 'x')
3145 && (data_type
!= _SIMM16_LA
)
3146 && (data_type
!= _VALUE_HI16
)
3147 && (data_type
!= _VALUE_LO16
)
3148 && (data_type
!= _IMM16
)
3149 && (data_type
!= _IMM15
)
3150 && (data_type
!= _IMM14
)
3151 && (data_type
!= _IMM4
)
3152 && (data_type
!= _IMM5
)
3153 && (data_type
!= _IMM8
)
3154 && (data_type
!= _IMM5_RSHIFT_1
)
3155 && (data_type
!= _IMM5_RSHIFT_2
)
3156 && (data_type
!= _SIMM14_NEG
)
3157 && (data_type
!= _IMM10_RSHIFT_2
))
3162 value
= s3_validate_immediate (s3_inst
.reloc
.exp
.X_add_number
, data_type
, 0);
3163 if (value
== (int) s3_FAIL
)
3166 sprintf (s3_err_msg
,
3167 _("invalid constant: %d bit expression not in range %d..%d"),
3168 s3_score_df_range
[data_type
].bits
,
3169 s3_score_df_range
[data_type
].range
[0], s3_score_df_range
[data_type
].range
[1]);
3171 sprintf (s3_err_msg
,
3172 _("invalid constant: %d bit expression not in range %d..%d"),
3173 s3_score_df_range
[data_type
- 24].bits
,
3174 s3_score_df_range
[data_type
- 24].range
[0],
3175 s3_score_df_range
[data_type
- 24].range
[1]);
3176 s3_inst
.error
= s3_err_msg
;
3180 value
&= (1 << s3_score_df_range
[data_type
].bits
) - 1;
3181 ldst_idx
= s3_inst
.instruction
& OPC_PSEUDOLDST_MASK
;
3182 s3_inst
.instruction
&= ~OPC_PSEUDOLDST_MASK
;
3183 s3_inst
.instruction
|= s3_score_ldst_insns
[ldst_idx
* 3 + pre_inc
].value
;
3185 s3_inst
.instruction
|= value
<< 3;
3187 s3_inst
.instruction
|= value
;
3189 /* lw rD, [rA, simm15] */
3190 if ((s3_inst
.instruction
& 0x3e000000) == 0x20000000)
3192 /* rD in [r0 - r15]. , ra in [r0-r7] */
3193 if ((((s3_inst
.instruction
>> 15) & 0x18) == 0)
3194 && (((s3_inst
.instruction
>> 20) & 0x10) == 0))
3196 /* simm = [bit 7], lw -> lw!. */
3197 if (((s3_inst
.instruction
& 0x7f80) == 0)&&((s3_inst
.instruction
&0x3)==0))
3199 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>> 15) & 0x7) << 5)
3200 | (((s3_inst
.instruction
>> 20) & 0xf) << 8)|(value
>>2);
3201 s3_inst
.relax_size
= 2;
3205 s3_inst
.relax_inst
= 0x8000;
3210 s3_inst
.relax_inst
= 0x8000;
3213 /* sw rD, [rA, simm15] */
3214 else if ((s3_inst
.instruction
& 0x3e000000) == 0x28000000)
3216 /* rD is in [r0 - r15] and ra in [r0-r7] */
3217 if ((((s3_inst
.instruction
>> 15) & 0x18) == 0) && (((s3_inst
.instruction
>> 20) & 0x10) == 0))
3219 /* simm15 =7 bit , sw -> sw!. */
3220 if (((s3_inst
.instruction
& 0x7f80) == 0)&&((s3_inst
.instruction
&0x3)==0))
3222 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>> 15) & 0xf) << 5)
3223 | (((s3_inst
.instruction
>> 20) & 0xf) << 8)|(value
>>2);
3224 s3_inst
.relax_size
= 2;
3226 /* rA = r2, sw -> swp!. */
3229 s3_inst
.relax_inst
= 0x8000;
3234 s3_inst
.relax_inst
= 0x8000;
3237 /* sw rD, [rA, simm15]+ sw pre. */
3238 else if ((s3_inst
.instruction
& 0x3e000007) == 0x06000004)
3240 /* simm15 = -4. and ra==r0 */
3241 if ((((s3_inst
.instruction
>> 15) & 0x1f) == 0)
3242 && (((s3_inst
.instruction
>> 3) & 0xfff) == 0xffc))
3245 s3_inst
.relax_inst
= 0x0060 | ((s3_inst
.instruction
>> 20) & 0x1f);
3246 s3_inst
.relax_size
= 2;
3250 s3_inst
.relax_inst
= 0x8000;
3255 s3_inst
.relax_inst
= 0x8000;
3262 /* FIXME: may set error, for there is no ld/sw rD, [rA, label] */
3263 s3_inst
.reloc
.pc_rel
= 0;
3269 s3_inst
.error
= s3_BAD_ARGS
;
3275 s3_do_cache (char *str
)
3277 s3_skip_whitespace (str
);
3279 if ((s3_data_op2 (&str
, 20, _IMM5
) == (int) s3_FAIL
) || (s3_skip_past_comma (&str
) == (int) s3_FAIL
))
3287 cache_op
= (s3_inst
.instruction
>> 20) & 0x1F;
3288 sprintf (s3_inst
.name
, "cache %d", cache_op
);
3294 s3_skip_whitespace (str
);
3296 if (s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
)
3299 s3_skip_whitespace (str
);
3301 /* cache op, [rA] */
3302 if (s3_skip_past_comma (&str
) == (int) s3_FAIL
)
3304 s3_SET_INSN_ERROR (NULL
);
3307 s3_inst
.error
= _("missing ]");
3312 /* cache op, [rA, simm15] */
3315 if (s3_exp_ldst_offset (&str
, 0, _SIMM15
) == (int) s3_FAIL
)
3320 s3_skip_whitespace (str
);
3323 s3_inst
.error
= _("missing ]");
3328 if (s3_end_of_line (str
) == (int) s3_FAIL
)
3333 s3_inst
.error
= s3_BAD_ARGS
;
3338 s3_do_crdcrscrsimm5 (char *str
)
3343 s3_skip_whitespace (str
);
3345 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE_CR
) == (int) s3_FAIL
3346 || s3_skip_past_comma (&str
) == (int) s3_FAIL
3347 || s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE_CR
) == (int) s3_FAIL
3348 || s3_skip_past_comma (&str
) == (int) s3_FAIL
3349 || s3_reg_required_here (&str
, 10, s3_REG_TYPE_SCORE_CR
) == (int) s3_FAIL
3350 || s3_skip_past_comma (&str
) == (int) s3_FAIL
)
3353 /* cop1 cop_code20. */
3354 if (s3_data_op2 (&str
, 5, _IMM20
) == (int) s3_FAIL
)
3359 if (s3_data_op2 (&str
, 5, _IMM5
) == (int) s3_FAIL
)
3363 s3_end_of_line (str
);
3366 /* Handle ldc/stc. */
3368 s3_do_ldst_cop (char *str
)
3370 s3_skip_whitespace (str
);
3372 if ((s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE_CR
) == (int) s3_FAIL
)
3373 || (s3_skip_past_comma (&str
) == (int) s3_FAIL
))
3379 s3_skip_whitespace (str
);
3381 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
)
3384 s3_skip_whitespace (str
);
3388 if (s3_exp_ldst_offset (&str
, 5, _IMM10_RSHIFT_2
) == (int) s3_FAIL
)
3391 s3_skip_whitespace (str
);
3394 s3_inst
.error
= _("missing ]");
3399 s3_end_of_line (str
);
3402 s3_inst
.error
= s3_BAD_ARGS
;
3406 s3_do16_ldst_insn (char *str
)
3408 int conflict_reg
= 0;
3409 s3_skip_whitespace (str
);
3411 if ((s3_reglow_required_here (&str
, 8) == (int) s3_FAIL
) || (s3_skip_past_comma (&str
) == (int) s3_FAIL
))
3418 s3_skip_whitespace (str
);
3420 if ((conflict_reg
= s3_reglow_required_here (&str
, 5)) == (int) s3_FAIL
)
3422 if (conflict_reg
&0x8)
3424 sprintf (s3_err_msg
, _("invalid register number: %d is not in [r0--r7]"),conflict_reg
);
3425 s3_inst
.error
= s3_err_msg
;
3429 s3_skip_whitespace (str
);
3434 if (s3_end_of_line (str
) == (int) s3_FAIL
)
3439 if (s3_skip_past_comma (&str
) == (int) s3_FAIL
)
3441 s3_inst
.error
= _("comma is expected");
3444 if (s3_my_get_expression (&s3_inst
.reloc
.exp
, &str
) == (int) s3_FAIL
)
3446 s3_skip_whitespace (str
);
3449 s3_inst
.error
= _("missing ]");
3452 if (s3_end_of_line (str
) == (int) s3_FAIL
)
3454 if (s3_inst
.reloc
.exp
.X_op
== O_constant
)
3457 unsigned int data_type
;
3458 data_type
= _IMM5_RSHIFT_2
;
3459 value
= s3_validate_immediate (s3_inst
.reloc
.exp
.X_add_number
, data_type
, 0);
3460 if (value
== (int) s3_FAIL
)
3463 sprintf (s3_err_msg
,
3464 _("invalid constant: %d bit expression not in range %d..%d"),
3465 s3_score_df_range
[data_type
].bits
,
3466 s3_score_df_range
[data_type
].range
[0], s3_score_df_range
[data_type
].range
[1]);
3467 s3_inst
.error
= s3_err_msg
;
3472 sprintf (s3_err_msg
, _("invalid constant: %d is not word align integer"),value
);
3473 s3_inst
.error
= s3_err_msg
;
3478 s3_inst
.instruction
|= value
;
3484 sprintf (s3_err_msg
, _("missing ["));
3485 s3_inst
.error
= s3_err_msg
;
3491 s3_do_lw48 (char *str
)
3493 bfd_signed_vma val
= 0;
3495 s3_skip_whitespace (str
);
3497 if ((s3_reg_required_here (&str
, 37, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
)
3498 || (s3_skip_past_comma (&str
) == (int) s3_FAIL
))
3501 if (s3_my_get_expression (&s3_inst
.reloc
.exp
, &str
) == (int) s3_FAIL
3502 || s3_end_of_line (str
) == (int) s3_FAIL
)
3507 /* Check word align for lw48 rd, value. */
3508 if ((s3_inst
.reloc
.exp
.X_add_symbol
== NULL
)
3509 && ((s3_inst
.reloc
.exp
.X_add_number
& 0x3) != 0))
3511 s3_inst
.error
= _("invalid constant: 32 bit expression not word align");
3515 /* Check and set offset. */
3516 val
= s3_inst
.reloc
.exp
.X_add_number
;
3517 if ((s3_inst
.reloc
.exp
.X_add_symbol
== NULL
)
3518 && (!(val
>= 0 && val
<= 0xffffffffLL
)))
3520 s3_inst
.error
= _("invalid constant: 32 bit expression not in range [0, 0xffffffff]");
3526 s3_inst
.instruction
|= (val
<< 7);
3528 /* Set reloc type. */
3529 s3_inst
.reloc
.type
= BFD_RELOC_SCORE_IMM30
;
3534 s3_do_sw48 (char *str
)
3536 bfd_signed_vma val
= 0;
3538 s3_skip_whitespace (str
);
3540 if ((s3_reg_required_here (&str
, 37, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
)
3541 || (s3_skip_past_comma (&str
) == (int) s3_FAIL
))
3544 if (s3_my_get_expression (&s3_inst
.reloc
.exp
, &str
) == (int) s3_FAIL
3545 || s3_end_of_line (str
) == (int) s3_FAIL
)
3550 /* Check word align for lw48 rd, value. */
3551 if ((s3_inst
.reloc
.exp
.X_add_symbol
== NULL
)
3552 && ((s3_inst
.reloc
.exp
.X_add_number
& 0x3) != 0))
3554 s3_inst
.error
= _("invalid constant: 32 bit expression not word align");
3558 /* Check and set offset. */
3559 val
= s3_inst
.reloc
.exp
.X_add_number
;
3560 if ((s3_inst
.reloc
.exp
.X_add_symbol
== NULL
)
3561 && (!(val
>= 0 && val
<= 0xffffffffLL
)))
3563 s3_inst
.error
= _("invalid constant: 32 bit expression not in range [0, 0xffffffff]");
3569 s3_inst
.instruction
|= (val
<< 7);
3571 /* Set reloc type. */
3572 s3_inst
.reloc
.type
= BFD_RELOC_SCORE_IMM30
;
3576 s3_do_ldi48 (char *str
)
3580 s3_skip_whitespace (str
);
3582 if (s3_reg_required_here (&str
, 37, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
3583 || s3_skip_past_comma (&str
) == (int) s3_FAIL
)
3586 if (s3_my_get_expression (&s3_inst
.reloc
.exp
, &str
) == (int) s3_FAIL
3587 || s3_end_of_line (str
) == (int) s3_FAIL
)
3592 /* Check and set offset. */
3593 val
= s3_inst
.reloc
.exp
.X_add_number
;
3594 if (!(val
>= -0xffffffffLL
&& val
<= 0xffffffffLL
))
3596 s3_inst
.error
= _("invalid constant: 32 bit expression not in range [-0x80000000, 0x7fffffff]");
3601 s3_inst
.instruction
|= (val
<< 5);
3603 /* Set reloc type. */
3604 s3_inst
.reloc
.type
= BFD_RELOC_SCORE_IMM32
;
3608 s3_do_sdbbp48 (char *str
)
3610 s3_skip_whitespace (str
);
3612 if (s3_data_op2 (&str
, 5, _IMM5
) == (int) s3_FAIL
|| s3_end_of_line (str
) == (int) s3_FAIL
)
3617 s3_do_and48 (char *str
)
3619 s3_skip_whitespace (str
);
3621 if (s3_reglow_required_here (&str
, 38) == (int) s3_FAIL
3622 || s3_skip_past_comma (&str
) == (int) s3_FAIL
3623 || s3_reglow_required_here (&str
, 34) == (int) s3_FAIL
3624 || s3_skip_past_comma (&str
) == (int) s3_FAIL
3625 || s3_data_op2 (&str
, 2, _IMM32
) == (int) s3_FAIL
3626 || s3_end_of_line (str
) == (int) s3_FAIL
)
3631 s3_do_or48 (char *str
)
3633 s3_skip_whitespace (str
);
3635 if (s3_reglow_required_here (&str
, 38) == (int) s3_FAIL
3636 || s3_skip_past_comma (&str
) == (int) s3_FAIL
3637 || s3_reglow_required_here (&str
, 34) == (int) s3_FAIL
3638 || s3_skip_past_comma (&str
) == (int) s3_FAIL
3639 || s3_data_op2 (&str
, 2, _IMM32
) == (int) s3_FAIL
3640 || s3_end_of_line (str
) == (int) s3_FAIL
)
3645 s3_do_mbitclr (char *str
)
3648 s3_skip_whitespace (str
);
3652 sprintf (s3_err_msg
, _("missing ["));
3653 s3_inst
.error
= s3_err_msg
;
3658 s3_inst
.instruction
&= 0x0;
3660 if ((s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
)
3661 || (s3_skip_past_comma (&str
) == (int) s3_FAIL
)
3662 || (s3_data_op2 (&str
, 0, _IMM11
) == (int) s3_FAIL
))
3665 /* Get imm11 and refill opcode. */
3666 val
= s3_inst
.instruction
& 0x7ff;
3668 s3_inst
.instruction
&= 0x000f8000;
3669 s3_inst
.instruction
|= 0x00000064;
3673 sprintf (s3_err_msg
, _("missing ]"));
3674 s3_inst
.error
= s3_err_msg
;
3679 if ((s3_skip_past_comma (&str
) == (int) s3_FAIL
)
3680 || (s3_data_op2 (&str
, 10, _IMM5
) == (int) s3_FAIL
))
3683 /* Set imm11 to opcode. */
3684 s3_inst
.instruction
|= (val
& 0x1)
3685 | (((val
>> 1 ) & 0x7) << 7)
3686 | (((val
>> 4 ) & 0x1f) << 20);
3690 s3_do_mbitset (char *str
)
3693 s3_skip_whitespace (str
);
3697 sprintf (s3_err_msg
, _("missing ["));
3698 s3_inst
.error
= s3_err_msg
;
3703 s3_inst
.instruction
&= 0x0;
3705 if ((s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
)
3706 || (s3_skip_past_comma (&str
) == (int) s3_FAIL
)
3707 || (s3_data_op2 (&str
, 0, _IMM11
) == (int) s3_FAIL
))
3710 /* Get imm11 and refill opcode. */
3711 val
= s3_inst
.instruction
& 0x7ff;
3713 s3_inst
.instruction
&= 0x000f8000;
3714 s3_inst
.instruction
|= 0x0000006c;
3718 sprintf (s3_err_msg
, _("missing ]"));
3719 s3_inst
.error
= s3_err_msg
;
3724 if ((s3_skip_past_comma (&str
) == (int) s3_FAIL
)
3725 || (s3_data_op2 (&str
, 10, _IMM5
) == (int) s3_FAIL
))
3728 /* Set imm11 to opcode. */
3729 s3_inst
.instruction
|= (val
& 0x1)
3730 | (((val
>> 1 ) & 0x7) << 7)
3731 | (((val
>> 4 ) & 0x1f) << 20);
3735 s3_do16_slli_srli (char *str
)
3737 s3_skip_whitespace (str
);
3739 if ((s3_reglow_required_here (&str
, 5) == (int) s3_FAIL
)
3740 || (s3_skip_past_comma (&str
) == (int) s3_FAIL
)
3741 || s3_data_op2 (&str
, 0, _IMM5
) == (int) s3_FAIL
3742 || s3_end_of_line (str
) == (int) s3_FAIL
)
3747 s3_do16_ldiu (char *str
)
3749 s3_skip_whitespace (str
);
3751 if ((s3_reg_required_here (&str
, 5,s3_REG_TYPE_SCORE
) == (int) s3_FAIL
)
3752 || (s3_skip_past_comma (&str
) == (int) s3_FAIL
)
3753 || s3_data_op2 (&str
, 0, _IMM5
) == (int) s3_FAIL
3754 || s3_end_of_line (str
) == (int) s3_FAIL
)
3759 s3_do16_push_pop (char *str
)
3761 s3_skip_whitespace (str
);
3762 if ((s3_reg_required_here (&str
, 0, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
3763 || s3_end_of_line (str
) == (int) s3_FAIL
)
3768 s3_do16_rpush (char *str
)
3772 s3_skip_whitespace (str
);
3773 if ((reg
= (s3_reg_required_here (&str
, 5, s3_REG_TYPE_SCORE
))) == (int) s3_FAIL
3774 || s3_skip_past_comma (&str
) == (int) s3_FAIL
3775 || s3_data_op2 (&str
, 0, _IMM5_MULTI_LOAD
) == (int) s3_FAIL
3776 || s3_end_of_line (str
) == (int) s3_FAIL
)
3781 2: to 31: normal value. */
3782 val
= s3_inst
.instruction
& 0x1f;
3785 s3_inst
.error
= _("imm5 should >= 2");
3790 s3_inst
.error
= _("reg should <= 31");
3796 s3_do16_rpop (char *str
)
3800 s3_skip_whitespace (str
);
3801 if ((reg
= (s3_reg_required_here (&str
, 5, s3_REG_TYPE_SCORE
))) == (int) s3_FAIL
3802 || s3_skip_past_comma (&str
) == (int) s3_FAIL
3803 || s3_data_op2 (&str
, 0, _IMM5_MULTI_LOAD
) == (int) s3_FAIL
3804 || s3_end_of_line (str
) == (int) s3_FAIL
)
3809 2: to 31: normal value. */
3810 val
= s3_inst
.instruction
& 0x1f;
3813 s3_inst
.error
= _("imm5 should >= 2");
3819 s3_inst
.error
= _("reg should <= 31");
3824 if ((reg
+ val
) <= 32)
3825 reg
= reg
+ val
- 1;
3827 reg
= reg
+ val
- 33;
3828 s3_inst
.instruction
&= 0x7c1f;
3829 s3_inst
.instruction
|= (reg
<< 5);
3834 /* Handle lcb/lcw/lce/scb/scw/sce. */
3836 s3_do_ldst_unalign (char *str
)
3840 if (s3_university_version
== 1)
3842 s3_inst
.error
= s3_ERR_FOR_SCORE5U_ATOMIC
;
3846 s3_skip_whitespace (str
);
3848 /* lcb/scb [rA]+. */
3852 s3_skip_whitespace (str
);
3854 if (s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
)
3861 s3_inst
.error
= _("missing +");
3867 s3_inst
.error
= _("missing ]");
3871 if (s3_end_of_line (str
) == (int) s3_FAIL
)
3874 /* lcw/lce/scb/sce rD, [rA]+. */
3877 if (((conflict_reg
= s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
)
3878 || (s3_skip_past_comma (&str
) == (int) s3_FAIL
))
3883 s3_skip_whitespace (str
);
3888 s3_skip_whitespace (str
);
3889 if ((reg
= s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
)
3894 /* Conflicts can occur on stores as well as loads. */
3895 conflict_reg
= (conflict_reg
== reg
);
3896 s3_skip_whitespace (str
);
3899 unsigned int ldst_func
= s3_inst
.instruction
& LDST_UNALIGN_MASK
;
3905 as_warn (_("%s register same as write-back base"),
3906 ((ldst_func
& UA_LCE
) || (ldst_func
& UA_LCW
)
3907 ? _("destination") : _("source")));
3912 s3_inst
.error
= _("missing +");
3916 if (s3_end_of_line (str
) == (int) s3_FAIL
)
3921 s3_inst
.error
= _("missing ]");
3927 s3_inst
.error
= s3_BAD_ARGS
;
3933 /* Handle alw/asw. */
3935 s3_do_ldst_atomic (char *str
)
3937 if (s3_university_version
== 1)
3939 s3_inst
.error
= s3_ERR_FOR_SCORE5U_ATOMIC
;
3943 s3_skip_whitespace (str
);
3945 if ((s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
)
3946 || (s3_skip_past_comma (&str
) == (int) s3_FAIL
))
3953 s3_skip_whitespace (str
);
3958 s3_skip_whitespace (str
);
3959 if ((reg
= s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
)
3964 s3_skip_whitespace (str
);
3967 s3_inst
.error
= _("missing ]");
3971 s3_end_of_line (str
);
3974 s3_inst
.error
= s3_BAD_ARGS
;
3979 s3_build_relax_frag (struct s3_score_it fix_insts
[s3_RELAX_INST_NUM
], int fix_num ATTRIBUTE_UNUSED
,
3980 struct s3_score_it var_insts
[s3_RELAX_INST_NUM
], int var_num
,
3981 symbolS
*add_symbol
)
3986 fixS
*cur_fixp
= NULL
;
3988 struct s3_score_it inst_main
;
3990 memcpy (&inst_main
, &fix_insts
[0], sizeof (struct s3_score_it
));
3992 /* Adjust instruction opcode and to be relaxed instruction opcode. */
3993 inst_main
.instruction
= s3_adjust_paritybit (inst_main
.instruction
, s3_GET_INSN_CLASS (inst_main
.type
));
3994 inst_main
.type
= Insn_PIC
;
3996 for (i
= 0; i
< var_num
; i
++)
3998 inst_main
.relax_size
+= var_insts
[i
].size
;
3999 var_insts
[i
].instruction
= s3_adjust_paritybit (var_insts
[i
].instruction
,
4000 s3_GET_INSN_CLASS (var_insts
[i
].type
));
4003 /* Check data dependency. */
4004 s3_handle_dependency (&inst_main
);
4006 /* Start a new frag if frag_now is not empty. */
4007 if (frag_now_fix () != 0)
4009 if (!frag_now
->tc_frag_data
.is_insn
)
4011 frag_wane (frag_now
);
4017 /* Write fr_fix part. */
4018 p
= frag_more (inst_main
.size
);
4019 s3_md_number_to_chars (p
, inst_main
.instruction
, inst_main
.size
);
4021 if (inst_main
.reloc
.type
!= BFD_RELOC_NONE
)
4022 fixp
= s3_fix_new_score (frag_now
, p
- frag_now
->fr_literal
, inst_main
.size
,
4023 &inst_main
.reloc
.exp
, inst_main
.reloc
.pc_rel
, inst_main
.reloc
.type
);
4025 frag_now
->tc_frag_data
.fixp
= fixp
;
4026 cur_fixp
= frag_now
->tc_frag_data
.fixp
;
4029 dwarf2_emit_insn (inst_main
.size
);
4032 where
= p
- frag_now
->fr_literal
+ inst_main
.size
;
4033 for (i
= 0; i
< var_num
; i
++)
4036 where
+= var_insts
[i
- 1].size
;
4038 if (var_insts
[i
].reloc
.type
!= BFD_RELOC_NONE
)
4040 fixp
= s3_fix_new_score (frag_now
, where
, var_insts
[i
].size
,
4041 &var_insts
[i
].reloc
.exp
, var_insts
[i
].reloc
.pc_rel
,
4042 var_insts
[i
].reloc
.type
);
4047 cur_fixp
->fx_next
= fixp
;
4048 cur_fixp
= cur_fixp
->fx_next
;
4052 frag_now
->tc_frag_data
.fixp
= fixp
;
4053 cur_fixp
= frag_now
->tc_frag_data
.fixp
;
4059 p
= frag_var (rs_machine_dependent
, inst_main
.relax_size
+ s3_RELAX_PAD_BYTE
, 0,
4060 s3_RELAX_ENCODE (inst_main
.size
, inst_main
.relax_size
, inst_main
.type
,
4061 0, inst_main
.size
, 0), add_symbol
, 0, NULL
);
4063 /* Write fr_var part.
4064 no calling s3_gen_insn_frag, no fixS will be generated. */
4065 for (i
= 0; i
< var_num
; i
++)
4067 s3_md_number_to_chars (p
, var_insts
[i
].instruction
, var_insts
[i
].size
);
4068 p
+= var_insts
[i
].size
;
4070 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4074 /* Build a relax frag for la instruction when generating s3_PIC,
4075 external symbol first and local symbol second. */
4077 s3_build_la_pic (int reg_rd
, expressionS exp
)
4079 symbolS
*add_symbol
= exp
.X_add_symbol
;
4080 offsetT add_number
= exp
.X_add_number
;
4081 struct s3_score_it fix_insts
[s3_RELAX_INST_NUM
];
4082 struct s3_score_it var_insts
[s3_RELAX_INST_NUM
];
4085 char tmp
[s3_MAX_LITERAL_POOL_SIZE
];
4091 if (add_number
== 0)
4096 /* For an external symbol, only one insn is generated;
4097 For a local symbol, two insns are generated. */
4099 For an external symbol: lw rD, <sym>($gp)
4100 (BFD_RELOC_SCORE_GOT15 or BFD_RELOC_SCORE_CALL15) */
4101 sprintf (tmp
, "lw_pic r%d, %s", reg_rd
, S_GET_NAME (add_symbol
));
4102 if (s3_append_insn (tmp
, FALSE
) == (int) s3_FAIL
)
4105 if (reg_rd
== s3_PIC_CALL_REG
)
4106 s3_inst
.reloc
.type
= BFD_RELOC_SCORE_CALL15
;
4107 memcpy (&fix_insts
[0], &s3_inst
, sizeof (struct s3_score_it
));
4110 For a local symbol :
4111 lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15)
4112 addi rD, <sym> (BFD_RELOC_GOT_LO16) */
4113 s3_inst
.reloc
.type
= BFD_RELOC_SCORE_GOT15
;
4114 memcpy (&var_insts
[0], &s3_inst
, sizeof (struct s3_score_it
));
4115 sprintf (tmp
, "addi_s_pic r%d, %s", reg_rd
, S_GET_NAME (add_symbol
));
4116 if (s3_append_insn (tmp
, FALSE
) == (int) s3_FAIL
)
4119 memcpy (&var_insts
[1], &s3_inst
, sizeof (struct s3_score_it
));
4120 s3_build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
4122 else if (add_number
>= -0x8000 && add_number
<= 0x7fff)
4124 /* Insn 1: lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15) */
4125 sprintf (tmp
, "lw_pic r%d, %s", reg_rd
, S_GET_NAME (add_symbol
));
4126 if (s3_append_insn (tmp
, TRUE
) == (int) s3_FAIL
)
4133 For an external symbol: addi rD, <constant> */
4134 sprintf (tmp
, "addi r%d, %d", reg_rd
, (int)add_number
);
4135 if (s3_append_insn (tmp
, FALSE
) == (int) s3_FAIL
)
4138 memcpy (&fix_insts
[0], &s3_inst
, sizeof (struct s3_score_it
));
4141 For a local symbol: addi rD, <sym>+<constant> (BFD_RELOC_GOT_LO16) */
4142 sprintf (tmp
, "addi_s_pic r%d, %s + %d", reg_rd
,
4143 S_GET_NAME (add_symbol
), (int) add_number
);
4144 if (s3_append_insn (tmp
, FALSE
) == (int) s3_FAIL
)
4147 memcpy (&var_insts
[0], &s3_inst
, sizeof (struct s3_score_it
));
4148 s3_build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
4152 int hi
= (add_number
>> 16) & 0x0000FFFF;
4153 int lo
= add_number
& 0x0000FFFF;
4155 /* Insn 1: lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15) */
4156 sprintf (tmp
, "lw_pic r%d, %s", reg_rd
, S_GET_NAME (add_symbol
));
4157 if (s3_append_insn (tmp
, TRUE
) == (int) s3_FAIL
)
4164 For an external symbol: ldis r1, HI%<constant> */
4165 sprintf (tmp
, "ldis r1, %d", hi
);
4166 if (s3_append_insn (tmp
, FALSE
) == (int) s3_FAIL
)
4169 memcpy (&fix_insts
[0], &s3_inst
, sizeof (struct s3_score_it
));
4172 For a local symbol: ldis r1, HI%<constant>
4173 but, if lo is out of 16 bit, make hi plus 1 */
4174 if ((lo
< -0x8000) || (lo
> 0x7fff))
4178 sprintf (tmp
, "ldis_pic r1, %d", hi
);
4179 if (s3_append_insn (tmp
, FALSE
) == (int) s3_FAIL
)
4182 memcpy (&var_insts
[0], &s3_inst
, sizeof (struct s3_score_it
));
4183 s3_build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
4189 For an external symbol: ori r1, LO%<constant> */
4190 sprintf (tmp
, "ori r1, %d", lo
);
4191 if (s3_append_insn (tmp
, FALSE
) == (int) s3_FAIL
)
4194 memcpy (&fix_insts
[0], &s3_inst
, sizeof (struct s3_score_it
));
4197 For a local symbol: addi r1, <sym>+LO%<constant> (BFD_RELOC_GOT_LO16) */
4198 sprintf (tmp
, "addi_u_pic r1, %s + %d", S_GET_NAME (add_symbol
), lo
);
4199 if (s3_append_insn (tmp
, FALSE
) == (int) s3_FAIL
)
4202 memcpy (&var_insts
[0], &s3_inst
, sizeof (struct s3_score_it
));
4203 s3_build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
4205 /* Insn 4: add rD, rD, r1 */
4206 sprintf (tmp
, "add r%d, r%d, r1", reg_rd
, reg_rd
);
4207 if (s3_append_insn (tmp
, TRUE
) == (int) s3_FAIL
)
4210 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4219 s3_do_macro_la_rdi32 (char *str
)
4223 s3_skip_whitespace (str
);
4224 if ((reg_rd
= s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
4225 || s3_skip_past_comma (&str
) == (int) s3_FAIL
)
4232 char *keep_data
= str
;
4233 char append_str
[s3_MAX_LITERAL_POOL_SIZE
];
4235 /* Check immediate value. */
4236 if (s3_my_get_expression (&s3_inst
.reloc
.exp
, &str
) == (int) s3_FAIL
)
4238 s3_inst
.error
= _("expression error");
4241 else if ((s3_inst
.reloc
.exp
.X_add_symbol
== NULL
)
4242 && (s3_validate_immediate (s3_inst
.reloc
.exp
.X_add_number
, _IMM32
, 0) == (int) s3_FAIL
))
4244 s3_inst
.error
= _("value not in range [0, 0xffffffff]");
4251 /* la rd, simm16. */
4252 if (s3_data_op2 (&str
, 1, _SIMM16_LA
) != (int) s3_FAIL
)
4254 s3_end_of_line (str
);
4257 /* la rd, imm32 or la rd, label. */
4260 s3_SET_INSN_ERROR (NULL
);
4263 if ((s3_data_op2 (&str
, 1, _VALUE_HI16
) == (int) s3_FAIL
)
4264 || (s3_end_of_line (str
) == (int) s3_FAIL
))
4270 if ((s3_score_pic
== s3_NO_PIC
) || (!s3_inst
.reloc
.exp
.X_add_symbol
))
4272 sprintf (append_str
, "ld_i32hi r%d, %s", reg_rd
, keep_data
);
4273 if (s3_append_insn (append_str
, TRUE
) == (int) s3_FAIL
)
4276 sprintf (append_str
, "ld_i32lo r%d, %s", reg_rd
, keep_data
);
4277 if (s3_append_insn (append_str
, TRUE
) == (int) s3_FAIL
)
4282 gas_assert (s3_inst
.reloc
.exp
.X_add_symbol
);
4283 s3_build_la_pic (reg_rd
, s3_inst
.reloc
.exp
);
4286 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4295 s3_do_macro_li_rdi32 (char *str
)
4300 s3_skip_whitespace (str
);
4301 if ((reg_rd
= s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
4302 || s3_skip_past_comma (&str
) == (int) s3_FAIL
)
4309 char *keep_data
= str
;
4311 /* Check immediate value. */
4312 if (s3_my_get_expression (&s3_inst
.reloc
.exp
, &str
) == (int) s3_FAIL
)
4314 s3_inst
.error
= _("expression error");
4317 else if (!(s3_inst
.reloc
.exp
.X_add_number
>= -0xffffffffLL
4318 && s3_inst
.reloc
.exp
.X_add_number
<= 0xffffffffLL
))
4320 s3_inst
.error
= _("value not in range [-0xffffffff, 0xffffffff]");
4327 /* li rd, simm16. */
4328 if (s3_data_op2 (&str
, 1, _SIMM16_LA
) != (int) s3_FAIL
)
4330 s3_end_of_line (str
);
4336 char append_str
[s3_MAX_LITERAL_POOL_SIZE
];
4341 if ((s3_data_op2 (&str
, 1, _VALUE_HI16
) == (int) s3_FAIL
)
4342 || (s3_end_of_line (str
) == (int) s3_FAIL
))
4346 else if (s3_inst
.reloc
.exp
.X_add_symbol
)
4348 s3_inst
.error
= _("li rd label isn't correct instruction form");
4353 sprintf (append_str
, "ld_i32hi r%d, %s", reg_rd
, keep_data
);
4355 if (s3_append_insn (append_str
, TRUE
) == (int) s3_FAIL
)
4359 sprintf (append_str
, "ld_i32lo r%d, %s", reg_rd
, keep_data
);
4360 if (s3_append_insn (append_str
, TRUE
) == (int) s3_FAIL
)
4363 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4371 /* Handle mul/mulu/div/divu/rem/remu. */
4373 s3_do_macro_mul_rdrsrs (char *str
)
4379 char append_str
[s3_MAX_LITERAL_POOL_SIZE
];
4381 if (s3_university_version
== 1)
4382 as_warn ("%s", s3_ERR_FOR_SCORE5U_MUL_DIV
);
4384 strcpy (append_str
, str
);
4385 backupstr
= append_str
;
4386 s3_skip_whitespace (backupstr
);
4387 if (((reg_rd
= s3_reg_required_here (&backupstr
, -1, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
)
4388 || (s3_skip_past_comma (&backupstr
) == (int) s3_FAIL
)
4389 || ((reg_rs1
= s3_reg_required_here (&backupstr
, -1, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
))
4391 s3_inst
.error
= s3_BAD_ARGS
;
4395 if (s3_skip_past_comma (&backupstr
) == (int) s3_FAIL
)
4397 /* rem/remu rA, rB is error format. */
4398 if (strcmp (s3_inst
.name
, "rem") == 0 || strcmp (s3_inst
.name
, "remu") == 0)
4400 s3_SET_INSN_ERROR (s3_BAD_ARGS
);
4404 s3_SET_INSN_ERROR (NULL
);
4411 s3_SET_INSN_ERROR (NULL
);
4412 if (((reg_rs2
= s3_reg_required_here (&backupstr
, -1, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
)
4413 || (s3_end_of_line (backupstr
) == (int) s3_FAIL
))
4419 char append_str1
[s3_MAX_LITERAL_POOL_SIZE
];
4421 if (strcmp (s3_inst
.name
, "rem") == 0)
4423 sprintf (append_str
, "mul r%d, r%d", reg_rs1
, reg_rs2
);
4424 sprintf (append_str1
, "mfceh r%d", reg_rd
);
4426 else if (strcmp (s3_inst
.name
, "remu") == 0)
4428 sprintf (append_str
, "mulu r%d, r%d", reg_rs1
, reg_rs2
);
4429 sprintf (append_str1
, "mfceh r%d", reg_rd
);
4433 sprintf (append_str
, "%s r%d, r%d", s3_inst
.name
, reg_rs1
, reg_rs2
);
4434 sprintf (append_str1
, "mfcel r%d", reg_rd
);
4437 /* Output mul/mulu or div/divu or rem/remu. */
4438 if (s3_append_insn (append_str
, TRUE
) == (int) s3_FAIL
)
4441 /* Output mfcel or mfceh. */
4442 if (s3_append_insn (append_str1
, TRUE
) == (int) s3_FAIL
)
4445 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4452 s3_exp_macro_ldst_abs (char *str
)
4455 char *backupstr
, *tmp
;
4456 char append_str
[s3_MAX_LITERAL_POOL_SIZE
];
4457 char verifystr
[s3_MAX_LITERAL_POOL_SIZE
];
4458 struct s3_score_it inst_backup
;
4463 memcpy (&inst_backup
, &s3_inst
, sizeof (struct s3_score_it
));
4465 strcpy (verifystr
, str
);
4466 backupstr
= verifystr
;
4467 s3_skip_whitespace (backupstr
);
4468 if ((reg_rd
= s3_reg_required_here (&backupstr
, -1, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
)
4472 if (s3_skip_past_comma (&backupstr
) == (int) s3_FAIL
)
4476 sprintf (append_str
, "li r1 %s", backupstr
);
4477 s3_append_insn (append_str
, TRUE
);
4479 memcpy (&s3_inst
, &inst_backup
, sizeof (struct s3_score_it
));
4480 sprintf (append_str
, " r%d, [r1,0]", reg_rd
);
4481 s3_do_ldst_insn (append_str
);
4486 /* Handle bcmpeq / bcmpne */
4488 s3_do_macro_bcmp (char *str
)
4492 size_t keep_data_size
;
4494 struct s3_score_it inst_expand
[2];
4495 struct s3_score_it inst_main
;
4497 memset (inst_expand
, 0, sizeof inst_expand
);
4498 s3_skip_whitespace (str
);
4499 if (( reg_a
= s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
4500 || s3_skip_past_comma (&str
) == (int) s3_FAIL
4501 ||(reg_b
= s3_reg_required_here (&str
, 10, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
4502 || s3_skip_past_comma (&str
) == (int) s3_FAIL
)
4505 keep_data_size
= strlen (str
) + 1;
4506 keep_data
= xmalloc (keep_data_size
* 2 + 14);
4507 memcpy (keep_data
, str
, keep_data_size
);
4509 if (s3_my_get_expression (&s3_inst
.reloc
.exp
, &str
) == (int) s3_FAIL
4511 || s3_end_of_line (str
) == (int) s3_FAIL
)
4513 else if (s3_inst
.reloc
.exp
.X_add_symbol
== 0)
4515 s3_inst
.error
= _("lacking label ");
4520 char *append_str
= keep_data
+ keep_data_size
;
4521 s3_SET_INSN_ERROR (NULL
);
4523 s3_inst
.reloc
.type
= BFD_RELOC_SCORE_BCMP
;
4524 s3_inst
.reloc
.pc_rel
= 1;
4525 bfd_signed_vma val
= s3_inst
.reloc
.exp
.X_add_number
;
4527 /* Branch 32 offset field : 20 bit, 16 bit branch offset field : 8 bit. */
4528 s3_inst
.instruction
|= ((s3_inst
.reloc
.exp
.X_add_number
>> 1) & 0x1)
4529 | ((s3_inst
.reloc
.exp
.X_add_number
>> 2) & 0x7) << 7
4530 | ((s3_inst
.reloc
.exp
.X_add_number
>> 5) & 0x1f) << 20;
4532 /* Check and set offset. */
4533 if (((val
& 0xfffffe00) != 0)
4534 && ((val
& 0xfffffe00) != 0xfffffe00))
4536 /* support bcmp --> cmp!+beq (bne) */
4537 if (s3_score_pic
== s3_NO_PIC
)
4539 sprintf (append_str
, "cmp! r%d, r%d", reg_a
, reg_b
);
4540 if (s3_append_insn (append_str
, TRUE
) == (int) s3_FAIL
)
4542 if ((inst_main
.instruction
& 0x3e00007e) == 0x0000004c)
4543 memcpy (append_str
, "beq ", 4);
4545 memcpy (append_str
, "bne ", 4);
4546 memmove (append_str
+ 4, keep_data
, strlen (keep_data
) + 1);
4547 if (s3_append_insn (append_str
, TRUE
) == (int) s3_FAIL
)
4552 gas_assert (s3_inst
.reloc
.exp
.X_add_symbol
);
4554 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4561 s3_inst
.instruction
|= (val
& 0x1)
4562 | (((val
>> 1) & 0x7) << 7)
4563 | (((val
>> 4) & 0x1f) << 20);
4566 /* Backup s3_inst. */
4567 memcpy (&inst_main
, &s3_inst
, sizeof (struct s3_score_it
));
4569 if (s3_score_pic
== s3_NO_PIC
)
4571 sprintf (append_str
, "cmp! r%d, r%d", reg_a
, reg_b
);
4572 if (s3_append_insn (append_str
, FALSE
) == (int) s3_FAIL
)
4574 memcpy (&inst_expand
[0], &s3_inst
, sizeof (struct s3_score_it
));
4576 if ((inst_main
.instruction
& 0x3e00007e) == 0x0000004c)
4577 memcpy (append_str
, "beq ", 4);
4579 memcpy (append_str
, "bne ", 4);
4580 memmove (append_str
+ 4, keep_data
, strlen (keep_data
) + 1);
4581 if (s3_append_insn (append_str
, FALSE
) == (int) s3_FAIL
)
4583 memcpy (&inst_expand
[1], &s3_inst
, sizeof (struct s3_score_it
));
4587 gas_assert (s3_inst
.reloc
.exp
.X_add_symbol
);
4589 inst_main
.relax_size
= inst_expand
[0].size
+ inst_expand
[1].size
;
4590 inst_main
.type
= Insn_BCMP
;
4592 /* Adjust instruction opcode and to be relaxed instruction opcode. */
4593 inst_main
.instruction
= s3_adjust_paritybit (inst_main
.instruction
, s3_GET_INSN_CLASS (inst_main
.type
));
4595 for (i
= 0; i
< 2; i
++)
4596 inst_expand
[i
].instruction
= s3_adjust_paritybit (inst_expand
[i
].instruction
,
4597 s3_GET_INSN_CLASS (inst_expand
[i
].type
));
4598 /* Check data dependency. */
4599 s3_handle_dependency (&inst_main
);
4600 /* Start a new frag if frag_now is not empty. */
4601 if (frag_now_fix () != 0)
4603 if (!frag_now
->tc_frag_data
.is_insn
)
4604 frag_wane (frag_now
);
4609 /* Write fr_fix part. */
4611 p
= frag_more (inst_main
.size
);
4612 s3_md_number_to_chars (p
, inst_main
.instruction
, inst_main
.size
);
4614 if (inst_main
.reloc
.type
!= BFD_RELOC_NONE
)
4616 s3_fix_new_score (frag_now
, p
- frag_now
->fr_literal
, inst_main
.size
,
4617 &inst_main
.reloc
.exp
, inst_main
.reloc
.pc_rel
, inst_main
.reloc
.type
);
4620 dwarf2_emit_insn (inst_main
.size
);
4623 /* s3_GP instruction can not do optimization, only can do relax between
4624 1 instruction and 3 instructions. */
4625 p
= frag_var (rs_machine_dependent
, inst_main
.relax_size
+ s3_RELAX_PAD_BYTE
, 0,
4626 s3_RELAX_ENCODE (inst_main
.size
, inst_main
.relax_size
, inst_main
.type
, 0, 4, 1),
4627 inst_main
.reloc
.exp
.X_add_symbol
, 0, NULL
);
4629 /* Write fr_var part.
4630 no calling s3_gen_insn_frag, no fixS will be generated. */
4631 s3_md_number_to_chars (p
, inst_expand
[0].instruction
, inst_expand
[0].size
);
4632 p
+= inst_expand
[0].size
;
4633 s3_md_number_to_chars (p
, inst_expand
[1].instruction
, inst_expand
[1].size
);
4634 p
+= inst_expand
[1].size
;
4636 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4643 /* Handle bcmpeqz / bcmpnez */
4645 s3_do_macro_bcmpz (char *str
)
4649 size_t keep_data_size
;
4651 struct s3_score_it inst_expand
[2];
4652 struct s3_score_it inst_main
;
4654 memset (inst_expand
, 0, sizeof inst_expand
);
4655 s3_skip_whitespace (str
);
4656 if (( reg_a
= s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
4657 || s3_skip_past_comma (&str
) == (int) s3_FAIL
)
4660 keep_data_size
= strlen (str
) + 1;
4661 keep_data
= xmalloc (keep_data_size
* 2 + 13);
4662 memcpy (keep_data
, str
, keep_data_size
);
4664 if (s3_my_get_expression (&s3_inst
.reloc
.exp
, &str
) == (int) s3_FAIL
4665 || s3_end_of_line (str
) == (int) s3_FAIL
)
4667 else if (s3_inst
.reloc
.exp
.X_add_symbol
== 0)
4669 s3_inst
.error
= _("lacking label ");
4674 char *append_str
= keep_data
+ keep_data_size
;
4675 s3_SET_INSN_ERROR (NULL
);
4676 s3_inst
.reloc
.type
= BFD_RELOC_SCORE_BCMP
;
4677 s3_inst
.reloc
.pc_rel
= 1;
4678 bfd_signed_vma val
= s3_inst
.reloc
.exp
.X_add_number
;
4680 /* Branch 32 offset field : 20 bit, 16 bit branch offset field : 8 bit. */
4681 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;
4683 /* Check and set offset. */
4684 if (((val
& 0xfffffe00) != 0)
4685 && ((val
& 0xfffffe00) != 0xfffffe00))
4687 if (s3_score_pic
== s3_NO_PIC
)
4689 sprintf (append_str
, "cmpi! r%d, 0", reg_a
);
4690 if (s3_append_insn (append_str
, TRUE
) == (int) s3_FAIL
)
4692 if ((inst_main
.instruction
& 0x3e00007e) == 0x0000004c)
4693 memcpy (append_str
, "beq ", 4);
4695 memcpy (append_str
, "bne ", 4);
4696 memmove (append_str
+ 4, keep_data
, strlen (keep_data
) + 1);
4697 if (s3_append_insn (append_str
, TRUE
) == (int) s3_FAIL
)
4702 gas_assert (s3_inst
.reloc
.exp
.X_add_symbol
);
4704 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4711 s3_inst
.instruction
|= (val
& 0x1)
4712 | (((val
>> 1) & 0x7) << 7)
4713 | (((val
>> 4) & 0x1f) << 20);
4716 /* Backup s3_inst. */
4717 memcpy (&inst_main
, &s3_inst
, sizeof (struct s3_score_it
));
4719 if (s3_score_pic
== s3_NO_PIC
)
4721 sprintf (append_str
, "cmpi! r%d, 0", reg_a
);
4722 if (s3_append_insn (append_str
, FALSE
) == (int) s3_FAIL
)
4724 memcpy (&inst_expand
[0], &s3_inst
, sizeof (struct s3_score_it
));
4725 if ((inst_main
.instruction
& 0x3e00007e) == 0x0000004c)
4726 memcpy (append_str
, "beq ", 4);
4728 memcpy (append_str
, "bne ", 4);
4729 memmove (append_str
+ 4, keep_data
, strlen (keep_data
) + 1);
4730 if (s3_append_insn (append_str
, FALSE
) == (int) s3_FAIL
)
4732 memcpy (&inst_expand
[1], &s3_inst
, sizeof (struct s3_score_it
));
4736 gas_assert (s3_inst
.reloc
.exp
.X_add_symbol
);
4738 inst_main
.relax_size
= inst_expand
[0].size
+ inst_expand
[1].size
;
4739 inst_main
.type
= Insn_BCMP
;
4741 /* Adjust instruction opcode and to be relaxed instruction opcode. */
4742 inst_main
.instruction
= s3_adjust_paritybit (inst_main
.instruction
, s3_GET_INSN_CLASS (inst_main
.type
));
4744 for (i
= 0; i
< 2; i
++)
4745 inst_expand
[i
].instruction
= s3_adjust_paritybit (inst_expand
[i
].instruction
,
4746 s3_GET_INSN_CLASS (inst_expand
[i
].type
));
4747 /* Check data dependency. */
4748 s3_handle_dependency (&inst_main
);
4749 /* Start a new frag if frag_now is not empty. */
4750 if (frag_now_fix () != 0)
4752 if (!frag_now
->tc_frag_data
.is_insn
)
4753 frag_wane (frag_now
);
4758 /* Write fr_fix part. */
4760 p
= frag_more (inst_main
.size
);
4761 s3_md_number_to_chars (p
, inst_main
.instruction
, inst_main
.size
);
4763 if (inst_main
.reloc
.type
!= BFD_RELOC_NONE
)
4765 s3_fix_new_score (frag_now
, p
- frag_now
->fr_literal
, inst_main
.size
,
4766 &inst_main
.reloc
.exp
, inst_main
.reloc
.pc_rel
, inst_main
.reloc
.type
);
4769 dwarf2_emit_insn (inst_main
.size
);
4772 /* s3_GP instruction can not do optimization, only can do relax between
4773 1 instruction and 3 instructions. */
4774 p
= frag_var (rs_machine_dependent
, inst_main
.relax_size
+ s3_RELAX_PAD_BYTE
, 0,
4775 s3_RELAX_ENCODE (inst_main
.size
, inst_main
.relax_size
, inst_main
.type
, 0, 4, 1),
4776 inst_main
.reloc
.exp
.X_add_symbol
, 0, NULL
);
4778 /* Write fr_var part.
4779 no calling s3_gen_insn_frag, no fixS will be generated. */
4780 s3_md_number_to_chars (p
, inst_expand
[0].instruction
, inst_expand
[0].size
);
4781 p
+= inst_expand
[0].size
;
4782 s3_md_number_to_chars (p
, inst_expand
[1].instruction
, inst_expand
[1].size
);
4783 p
+= inst_expand
[1].size
;
4785 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4793 s3_nopic_need_relax (symbolS
* sym
, int before_relaxing
)
4797 else if (s3_USE_GLOBAL_POINTER_OPT
&& s3_g_switch_value
> 0)
4799 const char *symname
;
4800 const char *segname
;
4802 /* Find out whether this symbol can be referenced off the $gp
4803 register. It can be if it is smaller than the -G size or if
4804 it is in the .sdata or .sbss section. Certain symbols can
4805 not be referenced off the $gp, although it appears as though
4807 symname
= S_GET_NAME (sym
);
4808 if (symname
!= (const char *)NULL
4809 && (strcmp (symname
, "eprol") == 0
4810 || strcmp (symname
, "etext") == 0
4811 || strcmp (symname
, "_gp") == 0
4812 || strcmp (symname
, "edata") == 0
4813 || strcmp (symname
, "_fbss") == 0
4814 || strcmp (symname
, "_fdata") == 0
4815 || strcmp (symname
, "_ftext") == 0
4816 || strcmp (symname
, "end") == 0
4817 || strcmp (symname
, GP_DISP_LABEL
) == 0))
4821 else if ((!S_IS_DEFINED (sym
) || S_IS_COMMON (sym
)) && (0
4822 /* We must defer this decision until after the whole file has been read,
4823 since there might be a .extern after the first use of this symbol. */
4825 && S_GET_VALUE (sym
) == 0)
4826 || (S_GET_VALUE (sym
) != 0
4827 && S_GET_VALUE (sym
) <= s3_g_switch_value
)))
4832 segname
= segment_name (S_GET_SEGMENT (sym
));
4833 return (strcmp (segname
, ".sdata") != 0
4834 && strcmp (segname
, ".sbss") != 0
4835 && strncmp (segname
, ".sdata.", 7) != 0
4836 && strncmp (segname
, ".gnu.linkonce.s.", 16) != 0);
4838 /* We are not optimizing for the $gp register. */
4843 /* Build a relax frag for lw/st instruction when generating s3_PIC,
4844 external symbol first and local symbol second. */
4846 s3_build_lwst_pic (int reg_rd
, expressionS exp
, const char *insn_name
)
4848 symbolS
*add_symbol
= exp
.X_add_symbol
;
4849 int add_number
= exp
.X_add_number
;
4850 struct s3_score_it fix_insts
[s3_RELAX_INST_NUM
];
4851 struct s3_score_it var_insts
[s3_RELAX_INST_NUM
];
4854 char tmp
[s3_MAX_LITERAL_POOL_SIZE
];
4860 if ((add_number
== 0) || (add_number
>= -0x8000 && add_number
<= 0x7fff))
4865 /* For an external symbol, two insns are generated;
4866 For a local symbol, three insns are generated. */
4868 For an external symbol: lw rD, <sym>($gp)
4869 (BFD_RELOC_SCORE_GOT15) */
4870 sprintf (tmp
, "lw_pic r1, %s", S_GET_NAME (add_symbol
));
4871 if (s3_append_insn (tmp
, FALSE
) == (int) s3_FAIL
)
4874 memcpy (&fix_insts
[0], &s3_inst
, sizeof (struct s3_score_it
));
4877 For a local symbol :
4878 lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15)
4879 addi rD, <sym> (BFD_RELOC_GOT_LO16) */
4880 s3_inst
.reloc
.type
= BFD_RELOC_SCORE_GOT15
;
4881 memcpy (&var_insts
[0], &s3_inst
, sizeof (struct s3_score_it
));
4882 sprintf (tmp
, "addi_s_pic r1, %s", S_GET_NAME (add_symbol
));
4883 if (s3_append_insn (tmp
, FALSE
) == (int) s3_FAIL
)
4886 memcpy (&var_insts
[1], &s3_inst
, sizeof (struct s3_score_it
));
4887 s3_build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
4889 /* Insn 2 or Insn 3: lw/st rD, [r1, constant] */
4890 sprintf (tmp
, "%s r%d, [r1, %d]", insn_name
, reg_rd
, add_number
);
4891 if (s3_append_insn (tmp
, TRUE
) == (int) s3_FAIL
)
4894 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4899 s3_inst
.error
= _("s3_PIC code offset overflow (max 16 signed bits)");
4907 s3_do_macro_ldst_label (char *str
)
4915 char *absolute_value
;
4916 char append_str
[3][s3_MAX_LITERAL_POOL_SIZE
];
4917 char verifystr
[s3_MAX_LITERAL_POOL_SIZE
];
4918 struct s3_score_it inst_backup
;
4919 struct s3_score_it inst_expand
[3];
4920 struct s3_score_it inst_main
;
4922 memcpy (&inst_backup
, &s3_inst
, sizeof (struct s3_score_it
));
4923 strcpy (verifystr
, str
);
4924 backup_str
= verifystr
;
4926 s3_skip_whitespace (backup_str
);
4927 if ((reg_rd
= s3_reg_required_here (&backup_str
, -1, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
)
4930 if (s3_skip_past_comma (&backup_str
) == (int) s3_FAIL
)
4933 label_str
= backup_str
;
4935 /* Ld/st rD, [rA, imm] ld/st rD, [rA]+, imm ld/st rD, [rA, imm]+. */
4936 if (*backup_str
== '[')
4938 s3_inst
.type
= Rd_rvalueRs_preSI12
;
4939 s3_do_ldst_insn (str
);
4943 /* Ld/st rD, imm. */
4944 absolute_value
= backup_str
;
4945 s3_inst
.type
= Rd_rvalueRs_SI15
;
4947 if (s3_my_get_expression (&s3_inst
.reloc
.exp
, &backup_str
) == (int) s3_FAIL
)
4949 s3_inst
.error
= _("expression error");
4952 else if ((s3_inst
.reloc
.exp
.X_add_symbol
== NULL
)
4953 && (s3_validate_immediate (s3_inst
.reloc
.exp
.X_add_number
, _VALUE
, 0) == (int) s3_FAIL
))
4955 s3_inst
.error
= _("value not in range [0, 0x7fffffff]");
4958 else if (s3_end_of_line (backup_str
) == (int) s3_FAIL
)
4960 s3_inst
.error
= _("end on line error");
4965 if (s3_inst
.reloc
.exp
.X_add_symbol
== 0)
4967 memcpy (&s3_inst
, &inst_backup
, sizeof (struct s3_score_it
));
4968 s3_exp_macro_ldst_abs (str
);
4973 /* Ld/st rD, label. */
4974 s3_inst
.type
= Rd_rvalueRs_SI15
;
4975 backup_str
= absolute_value
;
4976 if ((s3_data_op2 (&backup_str
, 1, _GP_IMM15
) == (int) s3_FAIL
)
4977 || (s3_end_of_line (backup_str
) == (int) s3_FAIL
))
4983 if (s3_inst
.reloc
.exp
.X_add_symbol
== 0)
4986 s3_inst
.error
= s3_BAD_ARGS
;
4991 if (s3_score_pic
== s3_PIC
)
4994 ldst_idx
= s3_inst
.instruction
& OPC_PSEUDOLDST_MASK
;
4995 s3_build_lwst_pic (reg_rd
, s3_inst
.reloc
.exp
,
4996 s3_score_ldst_insns
[ldst_idx
* 3 + 0].template_name
);
5001 if ((s3_inst
.reloc
.exp
.X_add_number
<= 0x3fff)
5002 && (s3_inst
.reloc
.exp
.X_add_number
>= -0x4000)
5003 && (!s3_nopic_need_relax (s3_inst
.reloc
.exp
.X_add_symbol
, 1)))
5007 /* Assign the real opcode. */
5008 ldst_idx
= s3_inst
.instruction
& OPC_PSEUDOLDST_MASK
;
5009 s3_inst
.instruction
&= ~OPC_PSEUDOLDST_MASK
;
5010 s3_inst
.instruction
|= s3_score_ldst_insns
[ldst_idx
* 3 + 0].value
;
5011 s3_inst
.instruction
|= reg_rd
<< 20;
5012 s3_inst
.instruction
|= s3_GP
<< 15;
5013 s3_inst
.relax_inst
= 0x8000;
5014 s3_inst
.relax_size
= 0;
5020 /* Backup s3_inst. */
5021 memcpy (&inst_main
, &s3_inst
, sizeof (struct s3_score_it
));
5025 /* Determine which instructions should be output. */
5026 sprintf (append_str
[0], "ld_i32hi r1, %s", label_str
);
5027 sprintf (append_str
[1], "ld_i32lo r1, %s", label_str
);
5028 sprintf (append_str
[2], "%s r%d, [r1, 0]", inst_backup
.name
, reg_rd
);
5030 /* Generate three instructions.
5032 ld/st rd, [r1, 0] */
5033 for (i
= 0; i
< 3; i
++)
5035 if (s3_append_insn (append_str
[i
], FALSE
) == (int) s3_FAIL
)
5038 memcpy (&inst_expand
[i
], &s3_inst
, sizeof (struct s3_score_it
));
5045 /* Adjust instruction opcode and to be relaxed instruction opcode. */
5046 inst_main
.instruction
= s3_adjust_paritybit (inst_main
.instruction
, s3_GET_INSN_CLASS (inst_main
.type
));
5048 /* relax lw rd, label -> ldis rs, imm16
5050 lw rd, [rs, imm15] or lw! rd, [rs, imm5]. */
5051 if (inst_expand
[2].relax_size
== 0)
5052 inst_main
.relax_size
= inst_expand
[0].size
+ inst_expand
[1].size
+ inst_expand
[2].size
;
5054 inst_main
.relax_size
= inst_expand
[0].size
+ inst_expand
[1].size
+ inst_expand
[2].relax_size
;
5056 inst_main
.type
= Insn_GP
;
5058 for (i
= 0; i
< 3; i
++)
5059 inst_expand
[i
].instruction
= s3_adjust_paritybit (inst_expand
[i
].instruction
,
5060 s3_GET_INSN_CLASS (inst_expand
[i
].type
));
5062 /* Check data dependency. */
5063 s3_handle_dependency (&inst_main
);
5065 /* Start a new frag if frag_now is not empty. */
5066 if (frag_now_fix () != 0)
5068 if (!frag_now
->tc_frag_data
.is_insn
)
5069 frag_wane (frag_now
);
5075 /* Write fr_fix part. */
5076 p
= frag_more (inst_main
.size
);
5077 s3_md_number_to_chars (p
, inst_main
.instruction
, inst_main
.size
);
5079 if (inst_main
.reloc
.type
!= BFD_RELOC_NONE
)
5081 s3_fix_new_score (frag_now
, p
- frag_now
->fr_literal
, inst_main
.size
,
5082 &inst_main
.reloc
.exp
, inst_main
.reloc
.pc_rel
, inst_main
.reloc
.type
);
5086 dwarf2_emit_insn (inst_main
.size
);
5089 /* s3_GP instruction can not do optimization, only can do relax between
5090 1 instruction and 3 instructions. */
5091 p
= frag_var (rs_machine_dependent
, inst_main
.relax_size
+ s3_RELAX_PAD_BYTE
, 0,
5092 s3_RELAX_ENCODE (inst_main
.size
, inst_main
.relax_size
, inst_main
.type
, 0, 4, 0),
5093 inst_main
.reloc
.exp
.X_add_symbol
, 0, NULL
);
5095 /* Write fr_var part.
5096 no calling s3_gen_insn_frag, no fixS will be generated. */
5097 s3_md_number_to_chars (p
, inst_expand
[0].instruction
, inst_expand
[0].size
);
5098 p
+= inst_expand
[0].size
;
5099 s3_md_number_to_chars (p
, inst_expand
[1].instruction
, inst_expand
[1].size
);
5100 p
+= inst_expand
[1].size
;
5102 /* relax lw rd, label -> ldis rs, imm16
5104 lw rd, [rs, imm15] or lw! rd, [rs, imm5]. */
5105 if (inst_expand
[2].relax_size
== 0)
5106 s3_md_number_to_chars (p
, inst_expand
[2].instruction
, inst_expand
[2].size
);
5108 s3_md_number_to_chars (p
, inst_expand
[2].relax_inst
, inst_expand
[2].relax_size
);
5112 s3_gen_insn_frag (&inst_expand
[0], NULL
);
5113 s3_gen_insn_frag (&inst_expand
[1], NULL
);
5114 s3_gen_insn_frag (&inst_expand
[2], NULL
);
5118 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
5123 s3_do_lw_pic (char *str
)
5127 s3_skip_whitespace (str
);
5128 if (((reg_rd
= s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
)
5129 || (s3_skip_past_comma (&str
) == (int) s3_FAIL
)
5130 || (s3_my_get_expression (&s3_inst
.reloc
.exp
, &str
) == (int) s3_FAIL
)
5131 || (s3_end_of_line (str
) == (int) s3_FAIL
))
5137 if (s3_inst
.reloc
.exp
.X_add_symbol
== 0)
5140 s3_inst
.error
= s3_BAD_ARGS
;
5145 s3_inst
.instruction
|= s3_GP
<< 15;
5146 s3_inst
.reloc
.type
= BFD_RELOC_SCORE_GOT15
;
5151 s3_do_empty (char *str
)
5154 if (s3_university_version
== 1)
5156 if (((s3_inst
.instruction
& 0x3e0003ff) == 0x0c000004)
5157 || ((s3_inst
.instruction
& 0x3e0003ff) == 0x0c000024)
5158 || ((s3_inst
.instruction
& 0x3e0003ff) == 0x0c000044)
5159 || ((s3_inst
.instruction
& 0x3e0003ff) == 0x0c000064))
5161 s3_inst
.error
= s3_ERR_FOR_SCORE5U_MMU
;
5165 if (s3_end_of_line (str
) == (int) s3_FAIL
)
5168 if (s3_inst
.relax_inst
!= 0x8000)
5170 if (s3_inst
.type
== NO_OPD
)
5172 s3_inst
.relax_size
= 2;
5176 s3_inst
.relax_size
= 4;
5182 s3_do16_int (char *str
)
5184 s3_skip_whitespace (str
);
5189 s3_do_jump (char *str
)
5193 s3_skip_whitespace (str
);
5194 if (s3_my_get_expression (&s3_inst
.reloc
.exp
, &str
) == (int) s3_FAIL
5195 || s3_end_of_line (str
) == (int) s3_FAIL
)
5198 if (s3_inst
.reloc
.exp
.X_add_symbol
== 0)
5200 s3_inst
.error
= _("lacking label ");
5204 if (!(s3_inst
.reloc
.exp
.X_add_number
>= -16777216
5205 && s3_inst
.reloc
.exp
.X_add_number
<= 16777215))
5207 s3_inst
.error
= _("invalid constant: 25 bit expression not in range [-16777216, 16777215]");
5211 save_in
= input_line_pointer
;
5212 input_line_pointer
= str
;
5213 s3_inst
.reloc
.type
= BFD_RELOC_SCORE_JMP
;
5214 s3_inst
.reloc
.pc_rel
= 1;
5215 input_line_pointer
= save_in
;
5219 s3_do_branch (char *str
)
5221 if (s3_my_get_expression (&s3_inst
.reloc
.exp
, &str
) == (int) s3_FAIL
5222 || s3_end_of_line (str
) == (int) s3_FAIL
)
5226 else if (s3_inst
.reloc
.exp
.X_add_symbol
== 0)
5228 s3_inst
.error
= _("lacking label ");
5231 else if (!(s3_inst
.reloc
.exp
.X_add_number
>= -524288
5232 && s3_inst
.reloc
.exp
.X_add_number
<= 524287))
5234 s3_inst
.error
= _("invalid constant: 20 bit expression not in range -2^19..2^19-1");
5238 s3_inst
.reloc
.type
= BFD_RELOC_SCORE_BRANCH
;
5239 s3_inst
.reloc
.pc_rel
= 1;
5241 /* Branch 32 offset field : 20 bit, 16 bit branch offset field : 8 bit. */
5242 s3_inst
.instruction
|= (s3_inst
.reloc
.exp
.X_add_number
& 0x3fe) | ((s3_inst
.reloc
.exp
.X_add_number
& 0xffc00) << 5);
5244 /* Compute 16 bit branch instruction. */
5245 if ((s3_inst
.relax_inst
!= 0x8000)
5246 && (s3_inst
.reloc
.exp
.X_add_number
>= -512 && s3_inst
.reloc
.exp
.X_add_number
<= 511))
5248 s3_inst
.relax_inst
|= ((s3_inst
.reloc
.exp
.X_add_number
>> 1) & 0x1ff);/*b! :disp 9 bit */
5249 s3_inst
.relax_size
= 2;
5253 s3_inst
.relax_inst
= 0x8000;
5258 s3_do16_branch (char *str
)
5260 if ((s3_my_get_expression (&s3_inst
.reloc
.exp
, &str
) == (int) s3_FAIL
5261 || s3_end_of_line (str
) == (int) s3_FAIL
))
5265 else if (s3_inst
.reloc
.exp
.X_add_symbol
== 0)
5267 s3_inst
.error
= _("lacking label");
5269 else if (!(s3_inst
.reloc
.exp
.X_add_number
>= -512
5270 && s3_inst
.reloc
.exp
.X_add_number
<= 511))
5272 s3_inst
.error
= _("invalid constant: 10 bit expression not in range [-2^9, 2^9-1]");
5276 s3_inst
.reloc
.type
= BFD_RELOC_SCORE16_BRANCH
;
5277 s3_inst
.reloc
.pc_rel
= 1;
5278 s3_inst
.instruction
|= ((s3_inst
.reloc
.exp
.X_add_number
>> 1) & 0x1ff);
5279 s3_inst
.relax_inst
|= ((s3_inst
.reloc
.exp
.X_add_number
) & 0x1ff);
5280 s3_inst
.relax_size
= 4;
5284 /* Return true if the given symbol should be considered local for s3_PIC. */
5286 s3_pic_need_relax (symbolS
*sym
, asection
*segtype
)
5289 bfd_boolean linkonce
;
5291 /* Handle the case of a symbol equated to another symbol. */
5292 while (symbol_equated_reloc_p (sym
))
5296 /* It's possible to get a loop here in a badly written
5298 n
= symbol_get_value_expression (sym
)->X_add_symbol
;
5304 symsec
= S_GET_SEGMENT (sym
);
5306 /* duplicate the test for LINK_ONCE sections as in adjust_reloc_syms */
5308 if (symsec
!= segtype
&& ! S_IS_LOCAL (sym
))
5310 if ((bfd_section_flags (symsec
) & SEC_LINK_ONCE
) != 0)
5313 /* The GNU toolchain uses an extension for ELF: a section
5314 beginning with the magic string .gnu.linkonce is a linkonce
5316 if (strncmp (segment_name (symsec
), ".gnu.linkonce",
5317 sizeof ".gnu.linkonce" - 1) == 0)
5321 /* This must duplicate the test in adjust_reloc_syms. */
5322 return (!bfd_is_und_section (symsec
)
5323 && !bfd_is_abs_section (symsec
)
5324 && !bfd_is_com_section (symsec
)
5327 /* A global or weak symbol is treated as external. */
5328 && (OUTPUT_FLAVOR
!= bfd_target_elf_flavour
5329 || (! S_IS_WEAK (sym
) && ! S_IS_EXTERNAL (sym
)))
5335 s3_parse_pce_inst (char *insnstr
)
5339 char first
[s3_MAX_LITERAL_POOL_SIZE
];
5340 char second
[s3_MAX_LITERAL_POOL_SIZE
];
5341 struct s3_score_it pec_part_1
;
5343 /* Get first part string of PCE. */
5344 p
= strstr (insnstr
, "||");
5347 sprintf (first
, "%s", insnstr
);
5349 /* Get second part string of PCE. */
5352 sprintf (second
, "%s", p
);
5354 s3_parse_16_32_inst (first
, FALSE
);
5358 memcpy (&pec_part_1
, &s3_inst
, sizeof (s3_inst
));
5360 s3_parse_16_32_inst (second
, FALSE
);
5364 if ( ((pec_part_1
.size
== s3_INSN_SIZE
) && (s3_inst
.size
== s3_INSN_SIZE
))
5365 || ((pec_part_1
.size
== s3_INSN_SIZE
) && (s3_inst
.size
== s3_INSN16_SIZE
))
5366 || ((pec_part_1
.size
== s3_INSN16_SIZE
) && (s3_inst
.size
== s3_INSN_SIZE
)))
5368 s3_inst
.error
= _("pce instruction error (16 bit || 16 bit).");
5369 sprintf (s3_inst
.str
, "%s", insnstr
);
5374 s3_gen_insn_frag (&pec_part_1
, &s3_inst
);
5379 s3_do16_dsp (char *str
)
5384 if (s3_score3d
== 0)
5386 s3_inst
.error
= _("score3d instruction.");
5390 s3_skip_whitespace (str
);
5392 if ((rd
= s3_reglow_required_here (&str
, 0)) == (int) s3_FAIL
5393 || s3_end_of_line (str
) == (int) s3_FAIL
)
5399 s3_inst
.relax_inst
|= rd
<< 20;
5400 s3_inst
.relax_size
= 4;
5405 s3_do16_dsp2 (char *str
)
5408 if (s3_score3d
== 0)
5410 s3_inst
.error
= _("score3d instruction.");
5414 s3_skip_whitespace (str
);
5416 if (s3_reglow_required_here (&str
, 4) == (int) s3_FAIL
5417 || s3_skip_past_comma (&str
) == (int) s3_FAIL
5418 || s3_reglow_required_here (&str
, 0) == (int) s3_FAIL
5419 || s3_end_of_line (str
) == (int) s3_FAIL
)
5425 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>> 8) & 0xf) << 20)
5426 | (((s3_inst
.instruction
>> 8) & 0xf) << 15) | (((s3_inst
.instruction
>> 4) & 0xf) << 10);
5427 s3_inst
.relax_size
= 4;
5432 s3_do_dsp (char *str
)
5435 if (s3_score3d
== 0)
5437 s3_inst
.error
= _("score3d instruction.");
5441 s3_skip_whitespace (str
);
5443 if (s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
5444 || s3_skip_past_comma (&str
) == (int) s3_FAIL
5445 || s3_reg_required_here (&str
, 10, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
5446 || s3_end_of_line (str
) == (int) s3_FAIL
)
5449 if ((s3_inst
.relax_inst
!= 0x8000) && (((s3_inst
.instruction
>> 20) & 0x1f) == 3) )
5451 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>> 10) & 0x1f)) | (((s3_inst
.instruction
>> 15) & 0x1f) << 5);
5452 s3_inst
.relax_size
= 2;
5455 s3_inst
.relax_inst
= 0x8000;
5459 s3_do_dsp2 (char *str
)
5464 if (s3_score3d
== 0)
5466 s3_inst
.error
= _("score3d instruction.");
5470 s3_skip_whitespace (str
);
5472 if ((reg
= s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
5473 || s3_skip_past_comma (&str
) == (int) s3_FAIL
5474 || s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
5475 || s3_skip_past_comma (&str
) == (int) s3_FAIL
5476 || s3_reg_required_here (&str
, 10, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
5477 || s3_end_of_line (str
) == (int) s3_FAIL
)
5483 /* Check mulr, mulur rd is even number. */
5484 if (((s3_inst
.instruction
& 0x3e0003ff) == 0x00000340
5485 || (s3_inst
.instruction
& 0x3e0003ff) == 0x00000342)
5488 s3_inst
.error
= _("rd must be even number.");
5492 if ((((s3_inst
.instruction
>> 15) & 0x10) == 0)
5493 && (((s3_inst
.instruction
>> 10) & 0x10) == 0)
5494 && (((s3_inst
.instruction
>> 20) & 0x10) == 0)
5495 && (s3_inst
.relax_inst
!= 0x8000)
5496 && (((s3_inst
.instruction
>> 20) & 0xf) == ((s3_inst
.instruction
>> 15) & 0xf)))
5498 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>> 10) & 0xf) )
5499 | (((s3_inst
.instruction
>> 15) & 0xf) << 4);
5500 s3_inst
.relax_size
= 2;
5504 s3_inst
.relax_inst
= 0x8000;
5510 s3_do_dsp3 (char *str
)
5513 if (s3_score3d
== 0)
5515 s3_inst
.error
= _("score3d instruction.");
5519 s3_skip_whitespace (str
);
5521 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
5522 || s3_skip_past_comma (&str
) == (int) s3_FAIL
5523 || s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
5524 || s3_end_of_line (str
) == (int) s3_FAIL
)
5527 if ((s3_inst
.relax_inst
!= 0x8000) && (((s3_inst
.instruction
>> 20) & 0x1f) == 3) )
5529 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>> 10) & 0x1f)) | (((s3_inst
.instruction
>> 15) & 0x1f) << 5);
5530 s3_inst
.relax_size
= 2;
5533 s3_inst
.relax_inst
= 0x8000;
5537 /* If we change section we must dump the literal pool first. */
5539 s3_s_score_bss (int ignore ATTRIBUTE_UNUSED
)
5541 subseg_set (bss_section
, (subsegT
) get_absolute_expression ());
5542 demand_empty_rest_of_line ();
5546 s3_s_score_text (int ignore
)
5548 obj_elf_text (ignore
);
5549 record_alignment (now_seg
, 2);
5553 s3_score_s_section (int ignore
)
5555 obj_elf_section (ignore
);
5556 if ((bfd_section_flags (now_seg
) & SEC_CODE
) != 0)
5557 record_alignment (now_seg
, 2);
5562 s3_s_change_sec (int sec
)
5567 /* The ELF backend needs to know that we are changing sections, so
5568 that .previous works correctly. We could do something like check
5569 for an obj_section_change_hook macro, but that might be confusing
5570 as it would not be appropriate to use it in the section changing
5571 functions in read.c, since obj-elf.c intercepts those. FIXME:
5572 This should be cleaner, somehow. */
5573 obj_elf_section_change_hook ();
5578 seg
= subseg_new (s3_RDATA_SECTION_NAME
, (subsegT
) get_absolute_expression ());
5579 bfd_set_section_flags (seg
, (SEC_ALLOC
| SEC_LOAD
| SEC_READONLY
5580 | SEC_RELOC
| SEC_DATA
));
5581 if (strcmp (TARGET_OS
, "elf") != 0)
5582 record_alignment (seg
, 4);
5583 demand_empty_rest_of_line ();
5586 seg
= subseg_new (".sdata", (subsegT
) get_absolute_expression ());
5587 bfd_set_section_flags (seg
, (SEC_ALLOC
| SEC_LOAD
| SEC_RELOC
5588 | SEC_DATA
| SEC_SMALL_DATA
));
5589 if (strcmp (TARGET_OS
, "elf") != 0)
5590 record_alignment (seg
, 4);
5591 demand_empty_rest_of_line ();
5597 s3_s_score_mask (int reg_type ATTRIBUTE_UNUSED
)
5601 if (s3_cur_proc_ptr
== (s3_procS
*) NULL
)
5603 as_warn (_(".mask outside of .ent"));
5604 demand_empty_rest_of_line ();
5607 if (get_absolute_expression_and_terminator (&mask
) != ',')
5609 as_warn (_("Bad .mask directive"));
5610 --input_line_pointer
;
5611 demand_empty_rest_of_line ();
5614 off
= get_absolute_expression ();
5615 s3_cur_proc_ptr
->reg_mask
= mask
;
5616 s3_cur_proc_ptr
->reg_offset
= off
;
5617 demand_empty_rest_of_line ();
5621 s3_get_symbol (void)
5627 c
= get_symbol_name (&name
);
5628 p
= (symbolS
*) symbol_find_or_make (name
);
5629 (void) restore_line_pointer (c
);
5634 s3_get_number (void)
5639 if (*input_line_pointer
== '-')
5641 ++input_line_pointer
;
5644 if (!ISDIGIT (*input_line_pointer
))
5645 as_bad (_("expected simple number"));
5646 if (input_line_pointer
[0] == '0')
5648 if (input_line_pointer
[1] == 'x')
5650 input_line_pointer
+= 2;
5651 while (ISXDIGIT (*input_line_pointer
))
5654 val
|= hex_value (*input_line_pointer
++);
5656 return negative
? -val
: val
;
5660 ++input_line_pointer
;
5661 while (ISDIGIT (*input_line_pointer
))
5664 val
|= *input_line_pointer
++ - '0';
5666 return negative
? -val
: val
;
5669 if (!ISDIGIT (*input_line_pointer
))
5671 printf (_(" *input_line_pointer == '%c' 0x%02x\n"), *input_line_pointer
, *input_line_pointer
);
5672 as_warn (_("invalid number"));
5675 while (ISDIGIT (*input_line_pointer
))
5678 val
+= *input_line_pointer
++ - '0';
5680 return negative
? -val
: val
;
5683 /* The .aent and .ent directives. */
5685 s3_s_score_ent (int aent
)
5690 symbolP
= s3_get_symbol ();
5691 if (*input_line_pointer
== ',')
5692 ++input_line_pointer
;
5694 if (ISDIGIT (*input_line_pointer
) || *input_line_pointer
== '-')
5697 if ((bfd_section_flags (now_seg
) & SEC_CODE
) != 0)
5702 as_warn (_(".ent or .aent not in text section."));
5703 if (!aent
&& s3_cur_proc_ptr
)
5704 as_warn (_("missing .end"));
5707 s3_cur_proc_ptr
= &s3_cur_proc
;
5708 s3_cur_proc_ptr
->reg_mask
= 0xdeadbeaf;
5709 s3_cur_proc_ptr
->reg_offset
= 0xdeadbeaf;
5710 s3_cur_proc_ptr
->fpreg_mask
= 0xdeafbeaf;
5711 s3_cur_proc_ptr
->leaf
= 0xdeafbeaf;
5712 s3_cur_proc_ptr
->frame_offset
= 0xdeafbeaf;
5713 s3_cur_proc_ptr
->frame_reg
= 0xdeafbeaf;
5714 s3_cur_proc_ptr
->pc_reg
= 0xdeafbeaf;
5715 s3_cur_proc_ptr
->isym
= symbolP
;
5716 symbol_get_bfdsym (symbolP
)->flags
|= BSF_FUNCTION
;
5718 if (debug_type
== DEBUG_STABS
)
5719 stabs_generate_asm_func (S_GET_NAME (symbolP
), S_GET_NAME (symbolP
));
5721 demand_empty_rest_of_line ();
5725 s3_s_score_frame (int ignore ATTRIBUTE_UNUSED
)
5732 backupstr
= input_line_pointer
;
5735 if (s3_cur_proc_ptr
== (s3_procS
*) NULL
)
5737 as_warn (_(".frame outside of .ent"));
5738 demand_empty_rest_of_line ();
5741 s3_cur_proc_ptr
->frame_reg
= s3_reg_required_here ((&backupstr
), 0, s3_REG_TYPE_SCORE
);
5743 s3_skip_past_comma (&backupstr
);
5744 while (*backupstr
!= ',')
5746 str
[i
] = *backupstr
;
5754 s3_skip_past_comma (&backupstr
);
5755 s3_cur_proc_ptr
->frame_offset
= val
;
5756 s3_cur_proc_ptr
->pc_reg
= s3_reg_required_here ((&backupstr
), 0, s3_REG_TYPE_SCORE
);
5759 s3_skip_past_comma (&backupstr
);
5761 while (*backupstr
!= '\n')
5763 str
[i
] = *backupstr
;
5769 s3_cur_proc_ptr
->leaf
= val
;
5771 s3_skip_past_comma (&backupstr
);
5773 #endif /* OBJ_ELF */
5774 while (input_line_pointer
!= backupstr
)
5775 input_line_pointer
++;
5778 /* The .end directive. */
5780 s3_s_score_end (int x ATTRIBUTE_UNUSED
)
5785 /* Generate a .pdr section. */
5786 segT saved_seg
= now_seg
;
5787 subsegT saved_subseg
= now_subseg
;
5791 if (!is_end_of_line
[(unsigned char)*input_line_pointer
])
5793 p
= s3_get_symbol ();
5794 demand_empty_rest_of_line ();
5799 if ((bfd_section_flags (now_seg
) & SEC_CODE
) != 0)
5805 as_warn (_(".end not in text section"));
5806 if (!s3_cur_proc_ptr
)
5808 as_warn (_(".end directive without a preceding .ent directive."));
5809 demand_empty_rest_of_line ();
5814 gas_assert (S_GET_NAME (p
));
5815 if (strcmp (S_GET_NAME (p
), S_GET_NAME (s3_cur_proc_ptr
->isym
)))
5816 as_warn (_(".end symbol does not match .ent symbol."));
5817 if (debug_type
== DEBUG_STABS
)
5818 stabs_generate_asm_endfunc (S_GET_NAME (p
), S_GET_NAME (p
));
5821 as_warn (_(".end directive missing or unknown symbol"));
5823 if ((s3_cur_proc_ptr
->reg_mask
== 0xdeadbeaf) ||
5824 (s3_cur_proc_ptr
->reg_offset
== 0xdeadbeaf) ||
5825 (s3_cur_proc_ptr
->leaf
== 0xdeafbeaf) ||
5826 (s3_cur_proc_ptr
->frame_offset
== 0xdeafbeaf) ||
5827 (s3_cur_proc_ptr
->frame_reg
== 0xdeafbeaf) || (s3_cur_proc_ptr
->pc_reg
== 0xdeafbeaf));
5831 (void) frag_now_fix ();
5832 gas_assert (s3_pdr_seg
);
5833 subseg_set (s3_pdr_seg
, 0);
5834 /* Write the symbol. */
5835 exp
.X_op
= O_symbol
;
5836 exp
.X_add_symbol
= p
;
5837 exp
.X_add_number
= 0;
5838 emit_expr (&exp
, 4);
5839 fragp
= frag_more (7 * 4);
5840 md_number_to_chars (fragp
, (valueT
) s3_cur_proc_ptr
->reg_mask
, 4);
5841 md_number_to_chars (fragp
+ 4, (valueT
) s3_cur_proc_ptr
->reg_offset
, 4);
5842 md_number_to_chars (fragp
+ 8, (valueT
) s3_cur_proc_ptr
->fpreg_mask
, 4);
5843 md_number_to_chars (fragp
+ 12, (valueT
) s3_cur_proc_ptr
->leaf
, 4);
5844 md_number_to_chars (fragp
+ 16, (valueT
) s3_cur_proc_ptr
->frame_offset
, 4);
5845 md_number_to_chars (fragp
+ 20, (valueT
) s3_cur_proc_ptr
->frame_reg
, 4);
5846 md_number_to_chars (fragp
+ 24, (valueT
) s3_cur_proc_ptr
->pc_reg
, 4);
5847 subseg_set (saved_seg
, saved_subseg
);
5850 s3_cur_proc_ptr
= NULL
;
5853 /* Handle the .set pseudo-op. */
5855 s3_s_score_set (int x ATTRIBUTE_UNUSED
)
5858 char name
[s3_MAX_LITERAL_POOL_SIZE
];
5859 char * orig_ilp
= input_line_pointer
;
5861 while (!is_end_of_line
[(unsigned char)*input_line_pointer
])
5863 name
[i
] = (char) * input_line_pointer
;
5865 ++input_line_pointer
;
5870 if (strcmp (name
, "nwarn") == 0)
5872 s3_warn_fix_data_dependency
= 0;
5874 else if (strcmp (name
, "fixdd") == 0)
5876 s3_fix_data_dependency
= 1;
5878 else if (strcmp (name
, "nofixdd") == 0)
5880 s3_fix_data_dependency
= 0;
5882 else if (strcmp (name
, "r1") == 0)
5886 else if (strcmp (name
, "nor1") == 0)
5890 else if (strcmp (name
, "optimize") == 0)
5894 else if (strcmp (name
, "volatile") == 0)
5898 else if (strcmp (name
, "pic") == 0)
5900 s3_score_pic
= s3_PIC
;
5904 input_line_pointer
= orig_ilp
;
5909 /* Handle the .cpload pseudo-op. This is used when generating s3_PIC code. It sets the
5910 $gp register for the function based on the function address, which is in the register
5911 named in the argument. This uses a relocation against GP_DISP_LABEL, which is handled
5912 specially by the linker. The result is:
5913 ldis gp, %hi(GP_DISP_LABEL)
5914 ori gp, %low(GP_DISP_LABEL)
5915 add gp, gp, .cpload argument
5916 The .cpload argument is normally r29. */
5918 s3_s_score_cpload (int ignore ATTRIBUTE_UNUSED
)
5921 char insn_str
[s3_MAX_LITERAL_POOL_SIZE
];
5923 /* If we are not generating s3_PIC code, .cpload is ignored. */
5924 if (s3_score_pic
== s3_NO_PIC
)
5930 if ((reg
= s3_reg_required_here (&input_line_pointer
, -1, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
)
5933 demand_empty_rest_of_line ();
5935 sprintf (insn_str
, "ld_i32hi r%d, %s", s3_GP
, GP_DISP_LABEL
);
5936 if (s3_append_insn (insn_str
, TRUE
) == (int) s3_FAIL
)
5939 sprintf (insn_str
, "ld_i32lo r%d, %s", s3_GP
, GP_DISP_LABEL
);
5940 if (s3_append_insn (insn_str
, TRUE
) == (int) s3_FAIL
)
5943 sprintf (insn_str
, "add r%d, r%d, r%d", s3_GP
, s3_GP
, reg
);
5944 if (s3_append_insn (insn_str
, TRUE
) == (int) s3_FAIL
)
5948 /* Handle the .cprestore pseudo-op. This stores $gp into a given
5949 offset from $sp. The offset is remembered, and after making a s3_PIC
5950 call $gp is restored from that location. */
5952 s3_s_score_cprestore (int ignore ATTRIBUTE_UNUSED
)
5955 int cprestore_offset
;
5956 char insn_str
[s3_MAX_LITERAL_POOL_SIZE
];
5958 /* If we are not generating s3_PIC code, .cprestore is ignored. */
5959 if (s3_score_pic
== s3_NO_PIC
)
5965 if ((reg
= s3_reg_required_here (&input_line_pointer
, -1, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
5966 || s3_skip_past_comma (&input_line_pointer
) == (int) s3_FAIL
)
5971 cprestore_offset
= get_absolute_expression ();
5973 if (cprestore_offset
<= 0x3fff)
5975 sprintf (insn_str
, "sw r%d, [r%d, %d]", s3_GP
, reg
, cprestore_offset
);
5976 if (s3_append_insn (insn_str
, TRUE
) == (int) s3_FAIL
)
5986 sprintf (insn_str
, "li r1, %d", cprestore_offset
);
5987 if (s3_append_insn (insn_str
, TRUE
) == (int) s3_FAIL
)
5990 sprintf (insn_str
, "add r1, r1, r%d", reg
);
5991 if (s3_append_insn (insn_str
, TRUE
) == (int) s3_FAIL
)
5994 sprintf (insn_str
, "sw r%d, [r1]", s3_GP
);
5995 if (s3_append_insn (insn_str
, TRUE
) == (int) s3_FAIL
)
6001 demand_empty_rest_of_line ();
6004 /* Handle the .gpword pseudo-op. This is used when generating s3_PIC
6005 code. It generates a 32 bit s3_GP relative reloc. */
6007 s3_s_score_gpword (int ignore ATTRIBUTE_UNUSED
)
6012 /* When not generating s3_PIC code, this is treated as .word. */
6013 if (s3_score_pic
== s3_NO_PIC
)
6019 if (ex
.X_op
!= O_symbol
|| ex
.X_add_number
!= 0)
6021 as_bad (_("Unsupported use of .gpword"));
6022 ignore_rest_of_line ();
6025 s3_md_number_to_chars (p
, (valueT
) 0, 4);
6026 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 4, &ex
, FALSE
, BFD_RELOC_GPREL32
);
6027 demand_empty_rest_of_line ();
6030 /* Handle the .cpadd pseudo-op. This is used when dealing with switch
6031 tables in s3_PIC code. */
6033 s3_s_score_cpadd (int ignore ATTRIBUTE_UNUSED
)
6036 char insn_str
[s3_MAX_LITERAL_POOL_SIZE
];
6038 /* If we are not generating s3_PIC code, .cpload is ignored. */
6039 if (s3_score_pic
== s3_NO_PIC
)
6045 if ((reg
= s3_reg_required_here (&input_line_pointer
, -1, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
)
6049 demand_empty_rest_of_line ();
6051 /* Add $gp to the register named as an argument. */
6052 sprintf (insn_str
, "add r%d, r%d, r%d", reg
, reg
, s3_GP
);
6053 if (s3_append_insn (insn_str
, TRUE
) == (int) s3_FAIL
)
6057 #ifndef TC_IMPLICIT_LCOMM_ALIGNMENT
6058 #define TC_IMPLICIT_LCOMM_ALIGNMENT(SIZE, P2VAR) \
6063 else if ((SIZE) >= 4) \
6065 else if ((SIZE) >= 2) \
6074 s3_s_score_lcomm (int bytes_p
)
6081 segT current_seg
= now_seg
;
6082 subsegT current_subseg
= now_subseg
;
6083 const int max_alignment
= 15;
6085 segT bss_seg
= bss_section
;
6086 int needs_align
= 0;
6088 c
= get_symbol_name (&name
);
6089 p
= input_line_pointer
;
6090 (void) restore_line_pointer (c
);
6094 as_bad (_("expected symbol name"));
6095 discard_rest_of_line ();
6101 /* Accept an optional comma after the name. The comma used to be
6102 required, but Irix 5 cc does not generate it. */
6103 if (*input_line_pointer
== ',')
6105 ++input_line_pointer
;
6109 if (is_end_of_line
[(unsigned char)*input_line_pointer
])
6111 as_bad (_("missing size expression"));
6115 if ((temp
= get_absolute_expression ()) < 0)
6117 as_warn (_("BSS length (%d) < 0 ignored"), temp
);
6118 ignore_rest_of_line ();
6122 #if defined (TC_SCORE)
6123 if (OUTPUT_FLAVOR
== bfd_target_ecoff_flavour
|| OUTPUT_FLAVOR
== bfd_target_elf_flavour
)
6125 /* For Score and Alpha ECOFF or ELF, small objects are put in .sbss. */
6126 if ((unsigned) temp
<= bfd_get_gp_size (stdoutput
))
6128 bss_seg
= subseg_new (".sbss", 1);
6129 seg_info (bss_seg
)->bss
= 1;
6130 if (!bfd_set_section_flags (bss_seg
, SEC_ALLOC
| SEC_SMALL_DATA
))
6131 as_warn (_("error setting flags for \".sbss\": %s"),
6132 bfd_errmsg (bfd_get_error ()));
6138 if (*input_line_pointer
== ',')
6140 ++input_line_pointer
;
6143 if (is_end_of_line
[(unsigned char)*input_line_pointer
])
6145 as_bad (_("missing alignment"));
6150 align
= get_absolute_expression ();
6157 TC_IMPLICIT_LCOMM_ALIGNMENT (temp
, align
);
6159 /* Still zero unless TC_IMPLICIT_LCOMM_ALIGNMENT set it. */
6161 record_alignment (bss_seg
, align
);
6168 /* Convert to a power of 2. */
6173 for (i
= 0; align
!= 0; align
>>= 1, ++i
)
6179 if (align
> max_alignment
)
6181 align
= max_alignment
;
6182 as_warn (_("alignment too large; %d assumed"), align
);
6187 as_warn (_("alignment negative; 0 assumed"));
6190 record_alignment (bss_seg
, align
);
6194 /* Assume some objects may require alignment on some systems. */
6195 #if defined (TC_ALPHA) && ! defined (VMS)
6198 align
= ffs (temp
) - 1;
6199 if (temp
% (1 << align
))
6206 symbolP
= symbol_find_or_make (name
);
6210 #if (defined (OBJ_AOUT) || defined (OBJ_MAYBE_AOUT))
6211 (OUTPUT_FLAVOR
!= bfd_target_aout_flavour
6212 || (S_GET_OTHER (symbolP
) == 0 && S_GET_DESC (symbolP
) == 0)) &&
6214 (S_GET_SEGMENT (symbolP
) == bss_seg
|| (!S_IS_DEFINED (symbolP
) && S_GET_VALUE (symbolP
) == 0)))
6218 subseg_set (bss_seg
, 1);
6221 frag_align (align
, 0, 0);
6223 /* Detach from old frag. */
6224 if (S_GET_SEGMENT (symbolP
) == bss_seg
)
6225 symbol_get_frag (symbolP
)->fr_symbol
= NULL
;
6227 symbol_set_frag (symbolP
, frag_now
);
6228 pfrag
= frag_var (rs_org
, 1, 1, (relax_substateT
) 0, symbolP
, (offsetT
) temp
, NULL
);
6232 S_SET_SEGMENT (symbolP
, bss_seg
);
6235 /* The symbol may already have been created with a preceding
6236 ".globl" directive -- be careful not to step on storage class
6237 in that case. Otherwise, set it to static. */
6238 if (S_GET_STORAGE_CLASS (symbolP
) != C_EXT
)
6240 S_SET_STORAGE_CLASS (symbolP
, C_STAT
);
6242 #endif /* OBJ_COFF */
6245 S_SET_SIZE (symbolP
, temp
);
6249 as_bad (_("symbol `%s' is already defined"), S_GET_NAME (symbolP
));
6251 subseg_set (current_seg
, current_subseg
);
6253 demand_empty_rest_of_line ();
6257 s3_insert_reg (const struct s3_reg_entry
*r
, htab_t htab
)
6260 int len
= strlen (r
->name
) + 2;
6261 char *buf
= XNEWVEC (char, len
);
6262 char *buf2
= XNEWVEC (char, len
);
6264 strcpy (buf
+ i
, r
->name
);
6265 for (i
= 0; buf
[i
]; i
++)
6267 buf2
[i
] = TOUPPER (buf
[i
]);
6271 str_hash_insert (htab
, buf
, r
, 0);
6272 str_hash_insert (htab
, buf2
, r
, 0);
6276 s3_build_reg_hsh (struct s3_reg_map
*map
)
6278 const struct s3_reg_entry
*r
;
6280 map
->htab
= str_htab_create ();
6281 for (r
= map
->names
; r
->name
!= NULL
; r
++)
6282 s3_insert_reg (r
, map
->htab
);
6285 /* Iterate over the base tables to create the instruction patterns. */
6287 s3_build_score_ops_hsh (void)
6290 static struct obstack insn_obstack
;
6292 obstack_begin (&insn_obstack
, 4000);
6293 for (i
= 0; i
< sizeof (s3_score_insns
) / sizeof (struct s3_asm_opcode
); i
++)
6295 const struct s3_asm_opcode
*insn
= s3_score_insns
+ i
;
6296 size_t len
= strlen (insn
->template_name
);
6297 struct s3_asm_opcode
*new_opcode
;
6298 char *template_name
;
6299 new_opcode
= (struct s3_asm_opcode
*)
6300 obstack_alloc (&insn_obstack
, sizeof (struct s3_asm_opcode
));
6301 template_name
= (char *) obstack_alloc (& insn_obstack
, len
+ 1);
6303 strcpy (template_name
, insn
->template_name
);
6304 new_opcode
->template_name
= template_name
;
6305 new_opcode
->parms
= insn
->parms
;
6306 new_opcode
->value
= insn
->value
;
6307 new_opcode
->relax_value
= insn
->relax_value
;
6308 new_opcode
->type
= insn
->type
;
6309 new_opcode
->bitmask
= insn
->bitmask
;
6310 str_hash_insert (s3_score_ops_hsh
, new_opcode
->template_name
,
6316 s3_build_dependency_insn_hsh (void)
6319 static struct obstack dependency_obstack
;
6321 obstack_begin (&dependency_obstack
, 4000);
6322 for (i
= 0; i
< sizeof (s3_insn_to_dependency_table
) / sizeof (s3_insn_to_dependency_table
[0]); i
++)
6324 const struct s3_insn_to_dependency
*tmp
= s3_insn_to_dependency_table
+ i
;
6325 size_t len
= strlen (tmp
->insn_name
);
6326 struct s3_insn_to_dependency
*new_i2n
;
6329 new_i2n
= (struct s3_insn_to_dependency
*)
6330 obstack_alloc (&dependency_obstack
,
6331 sizeof (struct s3_insn_to_dependency
));
6332 buf
= (char *) obstack_alloc (&dependency_obstack
, len
+ 1);
6334 strcpy (buf
, tmp
->insn_name
);
6335 new_i2n
->insn_name
= buf
;
6336 new_i2n
->type
= tmp
->type
;
6337 str_hash_insert (s3_dependency_insn_hsh
, new_i2n
->insn_name
, new_i2n
, 0);
6342 s_score_bss (int ignore ATTRIBUTE_UNUSED
)
6345 return s3_s_score_bss (ignore
);
6347 return s7_s_score_bss (ignore
);
6351 s_score_text (int ignore
)
6354 return s3_s_score_text (ignore
);
6356 return s7_s_score_text (ignore
);
6360 s_section (int ignore
)
6363 return s3_score_s_section (ignore
);
6365 return s7_s_section (ignore
);
6369 s_change_sec (int sec
)
6372 return s3_s_change_sec (sec
);
6374 return s7_s_change_sec (sec
);
6378 s_score_mask (int reg_type ATTRIBUTE_UNUSED
)
6381 return s3_s_score_mask (reg_type
);
6383 return s7_s_score_mask (reg_type
);
6387 s_score_ent (int aent
)
6390 return s3_s_score_ent (aent
);
6392 return s7_s_score_ent (aent
);
6396 s_score_frame (int ignore ATTRIBUTE_UNUSED
)
6399 return s3_s_score_frame (ignore
);
6401 return s7_s_score_frame (ignore
);
6405 s_score_end (int x ATTRIBUTE_UNUSED
)
6408 return s3_s_score_end (x
);
6410 return s7_s_score_end (x
);
6414 s_score_set (int x ATTRIBUTE_UNUSED
)
6417 return s3_s_score_set (x
);
6419 return s7_s_score_set (x
);
6423 s_score_cpload (int ignore ATTRIBUTE_UNUSED
)
6426 return s3_s_score_cpload (ignore
);
6428 return s7_s_score_cpload (ignore
);
6432 s_score_cprestore (int ignore ATTRIBUTE_UNUSED
)
6435 return s3_s_score_cprestore (ignore
);
6437 return s7_s_score_cprestore (ignore
);
6441 s_score_gpword (int ignore ATTRIBUTE_UNUSED
)
6444 return s3_s_score_gpword (ignore
);
6446 return s7_s_score_gpword (ignore
);
6450 s_score_cpadd (int ignore ATTRIBUTE_UNUSED
)
6453 return s3_s_score_cpadd (ignore
);
6455 return s7_s_score_cpadd (ignore
);
6459 s_score_lcomm (int bytes_p
)
6462 return s3_s_score_lcomm (bytes_p
);
6464 return s7_s_score_lcomm (bytes_p
);
6468 s3_assemble (char *str
)
6471 know (strlen (str
) < s3_MAX_LITERAL_POOL_SIZE
);
6473 memset (&s3_inst
, '\0', sizeof (s3_inst
));
6474 if (s3_INSN_IS_PCE_P (str
))
6475 s3_parse_pce_inst (str
);
6476 else if (s3_INSN_IS_48_P (str
))
6477 s3_parse_48_inst (str
, TRUE
);
6479 s3_parse_16_32_inst (str
, TRUE
);
6482 as_bad (_("%s -- `%s'"), s3_inst
.error
, s3_inst
.str
);
6486 s3_operand (expressionS
* exp
)
6488 if (s3_in_my_get_expression
)
6490 exp
->X_op
= O_illegal
;
6491 if (s3_inst
.error
== NULL
)
6493 s3_inst
.error
= _("bad expression");
6505 s3_score_ops_hsh
= str_htab_create ();
6507 s3_build_score_ops_hsh ();
6509 s3_dependency_insn_hsh
= str_htab_create ();
6511 s3_build_dependency_insn_hsh ();
6513 for (i
= (int)s3_REG_TYPE_FIRST
; i
< (int)s3_REG_TYPE_MAX
; i
++)
6514 s3_build_reg_hsh (s3_all_reg_maps
+ i
);
6516 /* Initialize dependency vector. */
6517 s3_init_dependency_vector ();
6519 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
, 0);
6521 subseg
= now_subseg
;
6522 s3_pdr_seg
= subseg_new (".pdr", (subsegT
) 0);
6523 bfd_set_section_flags (s3_pdr_seg
, SEC_READONLY
| SEC_RELOC
| SEC_DEBUGGING
);
6524 bfd_set_section_alignment (s3_pdr_seg
, 2);
6525 subseg_set (seg
, subseg
);
6527 if (s3_USE_GLOBAL_POINTER_OPT
)
6528 bfd_set_gp_size (stdoutput
, s3_g_switch_value
);
6532 s3_number_to_chars (char *buf
, valueT val
, int n
)
6534 if (target_big_endian
)
6535 number_to_chars_bigendian (buf
, val
, n
);
6537 number_to_chars_littleendian (buf
, val
, n
);
6541 s3_normal_chars_to_number (char *buf
, int n
)
6544 unsigned char *where
= (unsigned char *)buf
;
6546 if (target_big_endian
)
6551 result
|= (*where
++ & 255);
6559 result
|= (where
[n
] & 255);
6567 s3_number_to_chars_littleendian (void *p
, valueT data
, int n
)
6569 char *buf
= (char *) p
;
6574 md_number_to_chars (buf
, data
>> 16, 2);
6575 md_number_to_chars (buf
+ 2, data
, 2);
6578 md_number_to_chars (buf
, data
>> 32, 2);
6579 md_number_to_chars (buf
+ 2, data
>> 16, 2);
6580 md_number_to_chars (buf
+ 4, data
, 2);
6583 /* Error routine. */
6584 as_bad_where (__FILE__
, __LINE__
, _("size is not 4 or 6"));
6590 s3_chars_to_number_littleendian (const void *p
, int n
)
6592 char *buf
= (char *) p
;
6598 result
= s3_normal_chars_to_number (buf
, 2) << 16;
6599 result
|= s3_normal_chars_to_number (buf
+ 2, 2);
6602 result
= s3_normal_chars_to_number (buf
, 2) << 32;
6603 result
|= s3_normal_chars_to_number (buf
+ 2, 2) << 16;
6604 result
|= s3_normal_chars_to_number (buf
+ 4, 2);
6607 /* Error routine. */
6608 as_bad_where (__FILE__
, __LINE__
, _("size is not 4 or 6"));
6616 s3_md_number_to_chars (char *buf
, valueT val
, int n
)
6618 if (!target_big_endian
&& n
>= 4)
6619 s3_number_to_chars_littleendian (buf
, val
, n
);
6621 md_number_to_chars (buf
, val
, n
);
6625 s3_md_chars_to_number (char *buf
, int n
)
6629 if (!target_big_endian
&& n
>= 4)
6630 result
= s3_chars_to_number_littleendian (buf
, n
);
6632 result
= s3_normal_chars_to_number (buf
, n
);
6638 s3_atof (int type
, char *litP
, int *sizeP
)
6641 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
6667 return _("bad call to MD_ATOF()");
6670 t
= atof_ieee (input_line_pointer
, type
, words
);
6672 input_line_pointer
= t
;
6675 if (target_big_endian
)
6677 for (i
= 0; i
< prec
; i
++)
6679 s3_md_number_to_chars (litP
, (valueT
) words
[i
], 2);
6685 for (i
= 0; i
< prec
; i
+= 2)
6687 s3_md_number_to_chars (litP
, (valueT
) words
[i
+ 1], 2);
6688 s3_md_number_to_chars (litP
+ 2, (valueT
) words
[i
], 2);
6697 s3_frag_check (fragS
* fragp ATTRIBUTE_UNUSED
)
6699 know (fragp
->insn_addr
<= s3_RELAX_PAD_BYTE
);
6703 s3_validate_fix (fixS
*fixP
)
6705 fixP
->fx_where
+= fixP
->fx_frag
->insn_addr
;
6709 s3_force_relocation (struct fix
*fixp
)
6713 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
6714 || fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
6715 || fixp
->fx_r_type
== BFD_RELOC_SCORE_JMP
6716 || fixp
->fx_r_type
== BFD_RELOC_SCORE_BRANCH
6717 || fixp
->fx_r_type
== BFD_RELOC_SCORE16_JMP
6718 || fixp
->fx_r_type
== BFD_RELOC_SCORE16_BRANCH
6719 || fixp
->fx_r_type
== BFD_RELOC_SCORE_BCMP
)
6727 s3_fix_adjustable (fixS
* fixP
)
6729 if (fixP
->fx_addsy
== NULL
)
6733 else if (OUTPUT_FLAVOR
== bfd_target_elf_flavour
6734 && (S_IS_EXTERNAL (fixP
->fx_addsy
) || S_IS_WEAK (fixP
->fx_addsy
)))
6738 else if (fixP
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
6739 || fixP
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
6740 || fixP
->fx_r_type
== BFD_RELOC_SCORE_JMP
6741 || fixP
->fx_r_type
== BFD_RELOC_SCORE16_JMP
)
6750 s3_elf_final_processing (void)
6752 unsigned long val
= 0;
6755 val
= E_SCORE_MACH_SCORE3
;
6757 val
= E_SCORE_MACH_SCORE7
;
6759 elf_elfheader (stdoutput
)->e_machine
= EM_SCORE
;
6760 elf_elfheader (stdoutput
)->e_flags
&= ~EF_SCORE_MACH
;
6761 elf_elfheader (stdoutput
)->e_flags
|= val
;
6763 if (s3_fix_data_dependency
== 1)
6765 elf_elfheader (stdoutput
)->e_flags
|= EF_SCORE_FIXDEP
;
6767 if (s3_score_pic
== s3_PIC
)
6769 elf_elfheader (stdoutput
)->e_flags
|= EF_SCORE_PIC
;
6774 s3_judge_size_before_relax (fragS
* fragp
, asection
*sec
)
6778 if (s3_score_pic
== s3_NO_PIC
)
6779 change
= s3_nopic_need_relax (fragp
->fr_symbol
, 0);
6781 change
= s3_pic_need_relax (fragp
->fr_symbol
, sec
);
6785 /* Only at the first time determining whether s3_GP instruction relax should be done,
6786 return the difference between instruction size and instruction relax size. */
6787 if (fragp
->fr_opcode
== NULL
)
6789 fragp
->fr_fix
= s3_RELAX_NEW (fragp
->fr_subtype
);
6790 fragp
->fr_opcode
= fragp
->fr_literal
+ s3_RELAX_RELOC1 (fragp
->fr_subtype
);
6791 return s3_RELAX_NEW (fragp
->fr_subtype
) - s3_RELAX_OLD (fragp
->fr_subtype
);
6799 s3_estimate_size_before_relax (fragS
* fragp
, asection
* sec ATTRIBUTE_UNUSED
)
6801 if ((s3_RELAX_TYPE (fragp
->fr_subtype
) == Insn_GP
)
6802 || (s3_RELAX_TYPE (fragp
->fr_subtype
) == Insn_PIC
))
6803 return s3_judge_size_before_relax (fragp
, sec
);
6809 s3_relax_branch_inst32 (fragS
* fragp
)
6811 fragp
->fr_opcode
= NULL
;
6816 s3_relax_branch_inst16 (fragS
* fragp
)
6818 int relaxable_p
= 0;
6819 int frag_addr
= fragp
->fr_address
+ fragp
->insn_addr
;
6820 addressT symbol_address
= 0;
6824 unsigned long inst_value
;
6826 relaxable_p
= s3_RELAX_OPT (fragp
->fr_subtype
);
6828 s
= fragp
->fr_symbol
;
6832 symbol_address
= (addressT
) symbol_get_frag (s
)->fr_address
;
6834 inst_value
= s3_md_chars_to_number (fragp
->fr_literal
, s3_INSN16_SIZE
);
6835 offset
= (inst_value
& 0x1ff) << 1;
6836 if ((offset
& 0x200) == 0x200)
6837 offset
|= 0xfffffc00;
6839 value
= offset
+ symbol_address
- frag_addr
;
6842 && (!((value
& 0xfffffe00) == 0 || (value
& 0xfffffe00) == 0xfffffe00))
6843 && fragp
->fr_fix
== 2
6844 && (S_IS_DEFINED (s
)
6846 && !S_IS_EXTERNAL (s
)))
6848 /* Relax branch 32 to branch 16. */
6849 fragp
->fr_opcode
= fragp
->fr_literal
+ s3_RELAX_RELOC1 (fragp
->fr_subtype
);
6858 s3_relax_cmpbranch_inst32 (fragS
* fragp
)
6860 int relaxable_p
= 0;
6864 long frag_addr
= fragp
->fr_address
+ fragp
->insn_addr
;
6865 long symbol_address
= 0;
6867 unsigned long inst_value
;
6869 relaxable_p
= s3_RELAX_OPT (fragp
->fr_subtype
);
6871 s
= fragp
->fr_symbol
;
6875 symbol_address
= (addressT
) symbol_get_frag (s
)->fr_address
;
6877 inst_value
= s3_md_chars_to_number (fragp
->fr_literal
, s3_INSN_SIZE
);
6878 offset
= (inst_value
& 0x1)
6879 | (((inst_value
>> 7) & 0x7) << 1)
6880 | (((inst_value
>> 21) & 0x1f) << 4);
6882 if ((offset
& 0x200) == 0x200)
6883 offset
|= 0xfffffe00;
6885 value
= offset
+ symbol_address
- frag_addr
;
6886 /* change the order of judging rule is because
6887 1.not defined symbol or common symbol or external symbol will change
6888 bcmp to cmp!+beq/bne ,here need to record fragp->fr_opcode
6889 2.if the flow is as before : it will results to recursive loop
6891 if (fragp
->fr_fix
== 6)
6893 /* Have already relaxed! Just return 0 to terminate the loop. */
6896 /* need to translate when extern or not defined or common symbol */
6897 else if ((relaxable_p
6898 && (!((value
& 0xfffffe00) == 0 || (value
& 0xfffffe00) == 0xfffffe00))
6899 && fragp
->fr_fix
== 4)
6900 || !S_IS_DEFINED (s
)
6902 ||S_IS_EXTERNAL (s
))
6904 fragp
->fr_opcode
= fragp
->fr_literal
+ s3_RELAX_RELOC1 (fragp
->fr_subtype
);
6910 /* Never relax. Modify fr_opcode to NULL to verify it's value in
6912 fragp
->fr_opcode
= NULL
;
6919 s3_relax_other_inst32 (fragS
* fragp
)
6921 int relaxable_p
= s3_RELAX_OPT (fragp
->fr_subtype
);
6924 && fragp
->fr_fix
== 4)
6926 fragp
->fr_opcode
= fragp
->fr_literal
+ s3_RELAX_RELOC1 (fragp
->fr_subtype
);
6935 s3_relax_gp_and_pic_inst32 (void)
6937 /* md_estimate_size_before_relax has already relaxed s3_GP and s3_PIC
6938 instructions. We don't change relax size here. */
6943 s3_relax_frag (asection
* sec ATTRIBUTE_UNUSED
, fragS
* fragp
, long stretch ATTRIBUTE_UNUSED
)
6946 int adjust_align_p
= 0;
6948 /* If the instruction address is odd, make it half word align first. */
6949 if ((fragp
->fr_address
) % 2 != 0)
6951 if ((fragp
->fr_address
+ fragp
->insn_addr
) % 2 != 0)
6953 fragp
->insn_addr
= 1;
6959 switch (s3_RELAX_TYPE (fragp
->fr_subtype
))
6962 grows
+= s3_relax_branch_inst32 (fragp
);
6966 grows
+= s3_relax_branch_inst16 (fragp
);
6970 grows
+= s3_relax_cmpbranch_inst32 (fragp
);
6975 grows
+= s3_relax_gp_and_pic_inst32 ();
6979 grows
+= s3_relax_other_inst32 (fragp
);
6984 if (adjust_align_p
&& fragp
->insn_addr
)
6986 fragp
->fr_fix
+= fragp
->insn_addr
;
6993 s3_convert_frag (bfd
* abfd ATTRIBUTE_UNUSED
, segT sec ATTRIBUTE_UNUSED
, fragS
* fragp
)
7000 r_old
= s3_RELAX_OLD (fragp
->fr_subtype
);
7001 r_new
= s3_RELAX_NEW (fragp
->fr_subtype
);
7003 /* fragp->fr_opcode indicates whether this frag should be relaxed. */
7004 if (fragp
->fr_opcode
== NULL
)
7006 memcpy (backup
, fragp
->fr_literal
, r_old
);
7007 fragp
->fr_fix
= r_old
;
7011 memcpy (backup
, fragp
->fr_literal
+ r_old
, r_new
);
7012 fragp
->fr_fix
= r_new
;
7015 fixp
= fragp
->tc_frag_data
.fixp
;
7016 while (fixp
&& fixp
->fx_frag
== fragp
&& fixp
->fx_where
< r_old
)
7018 if (fragp
->fr_opcode
)
7020 fixp
= fixp
->fx_next
;
7022 while (fixp
&& fixp
->fx_frag
== fragp
)
7024 if (fragp
->fr_opcode
)
7025 fixp
->fx_where
-= r_old
+ fragp
->insn_addr
;
7028 fixp
= fixp
->fx_next
;
7031 if (fragp
->insn_addr
)
7033 s3_md_number_to_chars (fragp
->fr_literal
, 0x0, fragp
->insn_addr
);
7035 memcpy (fragp
->fr_literal
+ fragp
->insn_addr
, backup
, fragp
->fr_fix
);
7036 fragp
->fr_fix
+= fragp
->insn_addr
;
7040 s3_pcrel_from (fixS
* fixP
)
7045 && (S_GET_SEGMENT (fixP
->fx_addsy
) == undefined_section
)
7046 && (fixP
->fx_subsy
== NULL
))
7052 retval
= fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
7059 s3_section_align (segT segment ATTRIBUTE_UNUSED
, valueT size
)
7061 int align
= bfd_section_alignment (segment
);
7062 return ((size
+ (1 << align
) - 1) & -(1 << align
));
7066 s3_apply_fix (fixS
*fixP
, valueT
*valP
, segT seg
)
7068 valueT value
= *valP
;
7073 char *buf
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
7075 gas_assert (fixP
->fx_r_type
< BFD_RELOC_UNUSED
);
7076 if (fixP
->fx_addsy
== 0 && !fixP
->fx_pcrel
)
7078 if (fixP
->fx_r_type
!= BFD_RELOC_SCORE_DUMMY_HI16
)
7082 /* If this symbol is in a different section then we need to leave it for
7083 the linker to deal with. Unfortunately, md_pcrel_from can't tell,
7084 so we have to undo it's effects here. */
7087 if (fixP
->fx_addsy
!= NULL
7088 && S_IS_DEFINED (fixP
->fx_addsy
)
7089 && S_GET_SEGMENT (fixP
->fx_addsy
) != seg
)
7090 value
+= md_pcrel_from (fixP
);
7093 /* Remember value for emit_reloc. */
7094 fixP
->fx_addnumber
= value
;
7096 switch (fixP
->fx_r_type
)
7098 case BFD_RELOC_HI16_S
:
7099 if (fixP
->fx_done
) /* For la rd, imm32. */
7101 newval
= s3_md_chars_to_number (buf
, s3_INSN_SIZE
);
7102 HI
= value
>> 16; /* mul to 2, then take the hi 16 bit. */
7103 newval
|= (HI
& 0x3fff) << 1;
7104 newval
|= ((HI
>> 14) & 0x3) << 16;
7105 s3_md_number_to_chars (buf
, newval
, s3_INSN_SIZE
);
7108 case BFD_RELOC_LO16
:
7109 if (fixP
->fx_done
) /* For la rd, imm32. */
7111 newval
= s3_md_chars_to_number (buf
, s3_INSN_SIZE
);
7112 LO
= value
& 0xffff;
7113 newval
|= (LO
& 0x3fff) << 1; /* 16 bit: imm -> 14 bit in lo, 2 bit in hi. */
7114 newval
|= ((LO
>> 14) & 0x3) << 16;
7115 s3_md_number_to_chars (buf
, newval
, s3_INSN_SIZE
);
7118 case BFD_RELOC_SCORE_JMP
:
7120 content
= s3_md_chars_to_number (buf
, s3_INSN_SIZE
);
7121 value
= fixP
->fx_offset
;
7122 content
= (content
& ~0x3ff7ffe) | ((value
<< 1) & 0x3ff0000) | (value
& 0x7fff);
7123 s3_md_number_to_chars (buf
, content
, s3_INSN_SIZE
);
7127 case BFD_RELOC_SCORE_IMM30
:
7129 content
= s3_md_chars_to_number (buf
, s3_INSN48_SIZE
);
7130 value
= fixP
->fx_offset
;
7132 content
= (content
& ~0x7f7fff7f80LL
)
7133 | (((value
& 0xff) >> 0) << 7)
7134 | (((value
& 0x7fff00) >> 8) << 16)
7135 | (((value
& 0x3f800000) >> 23) << 32);
7136 s3_md_number_to_chars (buf
, content
, s3_INSN48_SIZE
);
7140 case BFD_RELOC_SCORE_IMM32
:
7142 content
= s3_md_chars_to_number (buf
, s3_INSN48_SIZE
);
7143 value
= fixP
->fx_offset
;
7144 content
= (content
& ~0x7f7fff7fe0LL
)
7145 | ((value
& 0x3ff) << 5)
7146 | (((value
>> 10) & 0x7fff) << 16)
7147 | (((value
>> 25) & 0x7f) << 32);
7148 s3_md_number_to_chars (buf
, content
, s3_INSN48_SIZE
);
7152 case BFD_RELOC_SCORE_BRANCH
:
7153 if ((S_GET_SEGMENT (fixP
->fx_addsy
) != seg
) || (fixP
->fx_addsy
!= NULL
&& S_IS_EXTERNAL (fixP
->fx_addsy
)))
7154 value
= fixP
->fx_offset
;
7158 content
= s3_md_chars_to_number (buf
, s3_INSN_SIZE
);
7160 /* Don't check c-bit. */
7161 if (fixP
->fx_frag
->fr_opcode
!= 0)
7163 if ((value
& 0xfffffe00) != 0 && (value
& 0xfffffe00) != 0xfffffe00)
7165 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7166 _(" branch relocation truncate (0x%x) [-2^9 ~ 2^9-1]"), (unsigned int) value
);
7169 content
= s3_md_chars_to_number (buf
, s3_INSN16_SIZE
);
7171 content
= (content
& 0xfe00) | ((value
>> 1) & 0x1ff);
7172 s3_md_number_to_chars (buf
, content
, s3_INSN16_SIZE
);
7173 fixP
->fx_r_type
= BFD_RELOC_SCORE16_BRANCH
;
7178 if ((value
& 0xfff80000) != 0 && (value
& 0xfff80000) != 0xfff80000)
7180 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7181 _(" branch relocation truncate (0x%x) [-2^19 ~ 2^19-1]"), (unsigned int) value
);
7184 content
= s3_md_chars_to_number (buf
, s3_INSN_SIZE
);
7185 content
&= 0xfc00fc01;
7186 content
= (content
& 0xfc00fc01) | (value
& 0x3fe) | ((value
<< 6) & 0x3ff0000);
7187 s3_md_number_to_chars (buf
, content
, s3_INSN_SIZE
);
7190 case BFD_RELOC_SCORE16_JMP
:
7191 content
= s3_md_chars_to_number (buf
, s3_INSN16_SIZE
);
7193 value
= fixP
->fx_offset
& 0xfff;
7194 content
= (content
& 0xfc01) | (value
& 0xffe);
7195 s3_md_number_to_chars (buf
, content
, s3_INSN16_SIZE
);
7197 case BFD_RELOC_SCORE16_BRANCH
:
7198 content
= s3_md_chars_to_number (buf
, s3_INSN_SIZE
);
7199 /* Don't check c-bit. */
7200 if (fixP
->fx_frag
->fr_opcode
!= 0)
7202 if ((S_GET_SEGMENT (fixP
->fx_addsy
) != seg
) ||
7203 (fixP
->fx_addsy
!= NULL
&& S_IS_EXTERNAL (fixP
->fx_addsy
)))
7204 value
= fixP
->fx_offset
;
7207 if ((value
& 0xfff80000) != 0 && (value
& 0xfff80000) != 0xfff80000)
7209 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7210 _(" branch relocation truncate (0x%x) [-2^19 ~ 2^19-1]"), (unsigned int) value
);
7213 content
= s3_md_chars_to_number (buf
, s3_INSN_SIZE
);
7214 content
= (content
& 0xfc00fc01) | (value
& 0x3fe) | ((value
<< 6) & 0x3ff0000);
7215 s3_md_number_to_chars (buf
, content
, s3_INSN_SIZE
);
7216 fixP
->fx_r_type
= BFD_RELOC_SCORE_BRANCH
;
7222 /* In different section. */
7223 if ((S_GET_SEGMENT (fixP
->fx_addsy
) != seg
) ||
7224 (fixP
->fx_addsy
!= NULL
&& S_IS_EXTERNAL (fixP
->fx_addsy
)))
7225 value
= fixP
->fx_offset
;
7229 if ((value
& 0xfffffe00) != 0 && (value
& 0xfffffe00) != 0xfffffe00)
7231 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7232 _(" branch relocation truncate (0x%x) [-2^9 ~ 2^9-1]"), (unsigned int) value
);
7236 content
= s3_md_chars_to_number (buf
, s3_INSN16_SIZE
);
7237 content
= (content
& 0xfe00) | ((value
>> 1) & 0x1ff);
7238 s3_md_number_to_chars (buf
, content
, s3_INSN16_SIZE
);
7244 case BFD_RELOC_SCORE_BCMP
:
7245 if (fixP
->fx_frag
->fr_opcode
!= 0)
7247 char *buf_ptr
= buf
;
7250 if ((S_GET_SEGMENT (fixP
->fx_addsy
) != seg
) || (fixP
->fx_addsy
!= NULL
&& S_IS_EXTERNAL (fixP
->fx_addsy
)))
7251 value
= fixP
->fx_offset
;
7256 bcmp -> cmp! and branch, so value -= 2. */
7259 if ((value
& 0xfff80000) != 0 && (value
& 0xfff80000) != 0xfff80000)
7261 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7262 _(" branch relocation truncate (0x%x) [-2^19 ~ 2^19-1]"), (unsigned int) value
);
7266 content
= s3_md_chars_to_number (buf_ptr
, s3_INSN_SIZE
);
7267 content
&= 0xfc00fc01;
7268 content
= (content
& 0xfc00fc01) | (value
& 0x3fe) | ((value
<< 6) & 0x3ff0000);
7269 s3_md_number_to_chars (buf_ptr
, content
, s3_INSN_SIZE
);
7270 /* change relocation type to BFD_RELOC_SCORE_BRANCH */
7271 fixP
->fx_r_type
= BFD_RELOC_SCORE_BRANCH
;
7272 fixP
->fx_where
+=2; /* first insn is cmp! , the second insn is beq/bne */
7277 if ((S_GET_SEGMENT (fixP
->fx_addsy
) != seg
) || (fixP
->fx_addsy
!= NULL
&& S_IS_EXTERNAL (fixP
->fx_addsy
)))
7278 value
= fixP
->fx_offset
;
7282 content
= s3_md_chars_to_number (buf
, s3_INSN_SIZE
);
7284 if ((value
& 0xfffffe00) != 0 && (value
& 0xfffffe00) != 0xfffffe00)
7286 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7287 _(" branch relocation truncate (0x%x) [-2^9 ~ 2^9-1]"), (unsigned int) value
);
7292 content
&= ~0x03e00381;
7295 | (((value
& 0xe) >> 1) << 7)
7296 | (((value
& 0x1f0) >> 4) << 21);
7298 s3_md_number_to_chars (buf
, content
, s3_INSN_SIZE
);
7303 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
7304 s3_md_number_to_chars (buf
, value
, 1);
7308 value
= fixP
->fx_offset
;
7309 s3_md_number_to_chars (buf
, value
, 1);
7315 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
7316 s3_md_number_to_chars (buf
, value
, 2);
7320 value
= fixP
->fx_offset
;
7321 s3_md_number_to_chars (buf
, value
, 2);
7327 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
7328 md_number_to_chars (buf
, value
, 4);
7332 value
= fixP
->fx_offset
;
7333 md_number_to_chars (buf
, value
, 4);
7337 case BFD_RELOC_VTABLE_INHERIT
:
7339 if (fixP
->fx_addsy
&& !S_IS_DEFINED (fixP
->fx_addsy
) && !S_IS_WEAK (fixP
->fx_addsy
))
7340 S_SET_WEAK (fixP
->fx_addsy
);
7342 case BFD_RELOC_VTABLE_ENTRY
:
7345 case BFD_RELOC_SCORE_GPREL15
:
7346 content
= s3_md_chars_to_number (buf
, s3_INSN_SIZE
);
7348 if ((fixP
->fx_frag
->fr_opcode
!= 0) && ((content
& 0xfc1c8000) != 0x94180000))
7349 fixP
->fx_r_type
= BFD_RELOC_NONE
;
7352 case BFD_RELOC_SCORE_GOT15
:
7353 case BFD_RELOC_SCORE_DUMMY_HI16
:
7354 case BFD_RELOC_SCORE_GOT_LO16
:
7355 case BFD_RELOC_SCORE_CALL15
:
7356 case BFD_RELOC_GPREL32
:
7358 case BFD_RELOC_NONE
:
7360 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("bad relocation fixup type (%d)"), fixP
->fx_r_type
);
7365 s3_gen_reloc (asection
* section ATTRIBUTE_UNUSED
, fixS
* fixp
)
7367 static arelent
*retval
[MAX_RELOC_EXPANSION
+ 1]; /* MAX_RELOC_EXPANSION equals 2. */
7369 bfd_reloc_code_real_type code
;
7372 reloc
= retval
[0] = XNEW (arelent
);
7375 reloc
->sym_ptr_ptr
= XNEW (asymbol
*);
7376 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
7377 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
7378 reloc
->addend
= fixp
->fx_offset
;
7380 /* If this is a variant frag, we may need to adjust the existing
7381 reloc and generate a new one. */
7382 if (fixp
->fx_frag
->fr_opcode
!= NULL
&& (fixp
->fx_r_type
== BFD_RELOC_SCORE_GPREL15
))
7384 /* Update instruction imm bit. */
7389 buf
= fixp
->fx_frag
->fr_literal
+ fixp
->fx_frag
->insn_addr
;
7390 newval
= s3_md_chars_to_number (buf
, s3_INSN_SIZE
);
7391 off
= fixp
->fx_offset
>> 16;
7392 newval
|= (off
& 0x3fff) << 1;
7393 newval
|= ((off
>> 14) & 0x3) << 16;
7394 s3_md_number_to_chars (buf
, newval
, s3_INSN_SIZE
);
7396 buf
+= s3_INSN_SIZE
;
7397 newval
= s3_md_chars_to_number (buf
, s3_INSN_SIZE
);
7398 off
= fixp
->fx_offset
& 0xffff;
7399 newval
|= ((off
& 0x3fff) << 1);
7400 newval
|= (((off
>> 14) & 0x3) << 16);
7401 s3_md_number_to_chars (buf
, newval
, s3_INSN_SIZE
);
7403 retval
[1] = XNEW (arelent
);
7405 retval
[1]->sym_ptr_ptr
= XNEW (asymbol
*);
7406 *retval
[1]->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
7407 retval
[1]->address
= (reloc
->address
+ s3_RELAX_RELOC2 (fixp
->fx_frag
->fr_subtype
));
7409 retval
[1]->addend
= 0;
7410 retval
[1]->howto
= bfd_reloc_type_lookup (stdoutput
, BFD_RELOC_LO16
);
7411 gas_assert (retval
[1]->howto
!= NULL
);
7413 fixp
->fx_r_type
= BFD_RELOC_HI16_S
;
7416 code
= fixp
->fx_r_type
;
7417 switch (fixp
->fx_r_type
)
7422 code
= BFD_RELOC_32_PCREL
;
7426 case BFD_RELOC_HI16_S
:
7427 case BFD_RELOC_LO16
:
7428 case BFD_RELOC_SCORE_JMP
:
7429 case BFD_RELOC_SCORE_BRANCH
:
7430 case BFD_RELOC_SCORE16_JMP
:
7431 case BFD_RELOC_SCORE16_BRANCH
:
7432 case BFD_RELOC_SCORE_BCMP
:
7433 case BFD_RELOC_VTABLE_ENTRY
:
7434 case BFD_RELOC_VTABLE_INHERIT
:
7435 case BFD_RELOC_SCORE_GPREL15
:
7436 case BFD_RELOC_SCORE_GOT15
:
7437 case BFD_RELOC_SCORE_DUMMY_HI16
:
7438 case BFD_RELOC_SCORE_GOT_LO16
:
7439 case BFD_RELOC_SCORE_CALL15
:
7440 case BFD_RELOC_GPREL32
:
7441 case BFD_RELOC_NONE
:
7442 case BFD_RELOC_SCORE_IMM30
:
7443 case BFD_RELOC_SCORE_IMM32
:
7444 code
= fixp
->fx_r_type
;
7447 type
= _("<unknown>");
7448 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
7449 _("cannot represent %s relocation in this object file format"), type
);
7453 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
7454 if (reloc
->howto
== NULL
)
7456 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
7457 _("cannot represent %s relocation in this object file format1"),
7458 bfd_get_reloc_code_name (code
));
7461 /* HACK: Since arm ELF uses Rel instead of Rela, encode the
7462 vtable entry to be used in the relocation's section offset. */
7463 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
7464 reloc
->address
= fixp
->fx_offset
;
7470 md_assemble (char *str
)
7478 /* We handle all bad expressions here, so that we can report the faulty
7479 instruction in the error message. */
7481 md_operand (expressionS
* exp
)
7489 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
7490 for use in the a.out file, and stores them in the array pointed to by buf.
7491 This knows about the endian-ness of the target machine and does
7492 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
7493 2 (short) and 4 (long) Floating numbers are put out as a series of
7494 LITTLENUMS (shorts, here at least). */
7496 md_number_to_chars (char *buf
, valueT val
, int n
)
7499 s3_number_to_chars (buf
, val
, n
);
7501 s7_number_to_chars (buf
, val
, n
);
7504 /* Turn a string in input_line_pointer into a floating point constant
7505 of type TYPE, and store the appropriate bytes in *LITP. The number
7506 of LITTLENUMS emitted is stored in *SIZEP. An error message is
7507 returned, or NULL on OK.
7509 Note that fp constants aren't represent in the normal way on the ARM.
7510 In big endian mode, things are as expected. However, in little endian
7511 mode fp constants are big-endian word-wise, and little-endian byte-wise
7512 within the words. For example, (double) 1.1 in big endian mode is
7513 the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
7514 the byte sequence 99 99 f1 3f 9a 99 99 99. */
7516 md_atof (int type
, char *litP
, int *sizeP
)
7519 return s3_atof (type
, litP
, sizeP
);
7521 return s7_atof (type
, litP
, sizeP
);
7525 score_frag_check (fragS
* fragp ATTRIBUTE_UNUSED
)
7528 s3_frag_check (fragp
);
7530 s7_frag_check (fragp
);
7533 /* Implementation of TC_VALIDATE_FIX.
7534 Called before md_apply_fix() and after md_convert_frag(). */
7536 score_validate_fix (fixS
*fixP
)
7539 s3_validate_fix (fixP
);
7541 s7_validate_fix (fixP
);
7545 score_force_relocation (struct fix
*fixp
)
7548 return s3_force_relocation (fixp
);
7550 return s7_force_relocation (fixp
);
7553 /* Implementation of md_frag_check.
7554 Called after md_convert_frag(). */
7556 score_fix_adjustable (fixS
* fixP
)
7559 return s3_fix_adjustable (fixP
);
7561 return s7_fix_adjustable (fixP
);
7565 score_elf_final_processing (void)
7568 s3_elf_final_processing ();
7570 s7_elf_final_processing ();
7573 /* In this function, we determine whether s3_GP instruction should do relaxation,
7574 for the label being against was known now.
7575 Doing this here but not in md_relax_frag() can induce iteration times
7576 in stage of doing relax. */
7578 md_estimate_size_before_relax (fragS
* fragp
, asection
* sec ATTRIBUTE_UNUSED
)
7581 return s3_estimate_size_before_relax (fragp
, sec
);
7583 return s7_estimate_size_before_relax (fragp
, sec
);
7587 score_relax_frag (asection
* sec ATTRIBUTE_UNUSED
, fragS
* fragp
, long stretch ATTRIBUTE_UNUSED
)
7590 return s3_relax_frag (sec
, fragp
, stretch
);
7592 return s7_relax_frag (sec
, fragp
, stretch
);
7596 md_convert_frag (bfd
* abfd ATTRIBUTE_UNUSED
, segT sec ATTRIBUTE_UNUSED
, fragS
* fragp
)
7599 return s3_convert_frag (abfd
, sec
, fragp
);
7601 return s7_convert_frag (abfd
, sec
, fragp
);
7605 md_pcrel_from (fixS
* fixP
)
7608 return s3_pcrel_from (fixP
);
7610 return s7_pcrel_from (fixP
);
7613 /* Round up a section size to the appropriate boundary. */
7615 md_section_align (segT segment ATTRIBUTE_UNUSED
, valueT size
)
7618 return s3_section_align (segment
, size
);
7620 return s7_section_align (segment
, size
);
7624 md_apply_fix (fixS
*fixP
, valueT
*valP
, segT seg
)
7627 return s3_apply_fix (fixP
, valP
, seg
);
7629 return s7_apply_fix (fixP
, valP
, seg
);
7632 /* Translate internal representation of relocation info to BFD target format. */
7634 tc_gen_reloc (asection
* section ATTRIBUTE_UNUSED
, fixS
* fixp
)
7637 return s3_gen_reloc (section
, fixp
);
7639 return s7_gen_reloc (section
, fixp
);
7650 score_set_mach (const char *arg
)
7652 if (strcmp (arg
, MARCH_SCORE3
) == 0)
7658 else if (strcmp (arg
, MARCH_SCORE7
) == 0)
7663 s7_university_version
= 0;
7664 s7_vector_size
= s7_SCORE7_PIPELINE
;
7666 else if (strcmp (arg
, MARCH_SCORE5
) == 0)
7671 s7_university_version
= 0;
7672 s7_vector_size
= s7_SCORE5_PIPELINE
;
7674 else if (strcmp (arg
, MARCH_SCORE5U
) == 0)
7679 s7_university_version
= 1;
7680 s7_vector_size
= s7_SCORE5_PIPELINE
;
7684 as_bad (_("unknown architecture `%s'\n"), arg
);
7689 md_parse_option (int c
, const char *arg
)
7695 target_big_endian
= 1;
7700 target_big_endian
= 0;
7704 s3_fix_data_dependency
= 1;
7705 s7_fix_data_dependency
= 1;
7708 s3_warn_fix_data_dependency
= 0;
7709 s7_warn_fix_data_dependency
= 0;
7714 s7_university_version
= 0;
7715 s7_vector_size
= s7_SCORE5_PIPELINE
;
7717 case OPTION_SCORE5U
:
7720 s7_university_version
= 1;
7721 s7_vector_size
= s7_SCORE5_PIPELINE
;
7727 s7_university_version
= 0;
7728 s7_vector_size
= s7_SCORE7_PIPELINE
;
7740 s3_g_switch_value
= atoi (arg
);
7741 s7_g_switch_value
= atoi (arg
);
7747 case OPTION_SCORE_VERSION
:
7748 printf (_("Sunplus-v2-0-0-20060510\n"));
7751 s3_score_pic
= s3_NO_PIC
; /* Score3 doesn't support PIC now. */
7752 s7_score_pic
= s7_PIC
;
7753 s3_g_switch_value
= 0; /* Must set -G num as 0 to generate s3_PIC code. */
7754 s7_g_switch_value
= 0; /* Must set -G num as 0 to generate s7_PIC code. */
7757 score_set_mach (arg
);
7766 md_show_usage (FILE * fp
)
7768 fprintf (fp
, _(" Score-specific assembler options:\n"));
7771 -EB\t\tassemble code for a big-endian cpu\n"));
7776 -EL\t\tassemble code for a little-endian cpu\n"));
7780 -FIXDD\t\tfix data dependencies\n"));
7782 -NWARN\t\tdo not print warning message when fixing data dependencies\n"));
7784 -SCORE5\t\tassemble code for target SCORE5\n"));
7786 -SCORE5U\tassemble code for target SCORE5U\n"));
7788 -SCORE7\t\tassemble code for target SCORE7 [default]\n"));
7790 -SCORE3\t\tassemble code for target SCORE3\n"));
7792 -march=score7\tassemble code for target SCORE7 [default]\n"));
7794 -march=score3\tassemble code for target SCORE3\n"));
7796 -USE_R1\t\tassemble code for no warning message when using temp register r1\n"));
7798 -KPIC\t\tgenerate PIC\n"));
7800 -O0\t\tdo not perform any optimizations\n"));
7802 -G gpnum\tassemble code for setting gpsize, default is 8 bytes\n"));
7804 -V \t\tSunplus release version\n"));