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
;
462 struct hash_control
*htab
;
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 struct hash_control
*s3_score_ops_hsh
= NULL
;
474 static struct hash_control
*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
, struct hash_control
*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
*) 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
*) hash_find (s3_dependency_insn_hsh
, name
);
2211 return s3_D_all_insn
;
2215 s3_check_dependency (char *pre_insn
, char *pre_reg
,
2216 char *cur_insn
, char *cur_reg
, int *warn_or_error
)
2220 enum s3_insn_type_for_dependency pre_insn_type
;
2221 enum s3_insn_type_for_dependency cur_insn_type
;
2223 pre_insn_type
= s3_dependency_type_from_insn (pre_insn
);
2224 cur_insn_type
= s3_dependency_type_from_insn (cur_insn
);
2226 for (i
= 0; i
< sizeof (s3_data_dependency_table
) / sizeof (s3_data_dependency_table
[0]); i
++)
2228 if ((pre_insn_type
== s3_data_dependency_table
[i
].pre_insn_type
)
2229 && (s3_D_all_insn
== s3_data_dependency_table
[i
].cur_insn_type
2230 || cur_insn_type
== s3_data_dependency_table
[i
].cur_insn_type
)
2231 && (strcmp (s3_data_dependency_table
[i
].pre_reg
, "") == 0
2232 || strcmp (s3_data_dependency_table
[i
].pre_reg
, pre_reg
) == 0)
2233 && (strcmp (s3_data_dependency_table
[i
].cur_reg
, "") == 0
2234 || strcmp (s3_data_dependency_table
[i
].cur_reg
, cur_reg
) == 0))
2236 bubbles
= s3_data_dependency_table
[i
].bubblenum_3
;
2237 *warn_or_error
= s3_data_dependency_table
[i
].warn_or_error
;
2246 s3_build_one_frag (struct s3_score_it one_inst
)
2249 int relaxable_p
= s3_g_opt
;
2252 /* Start a new frag if frag_now is not empty. */
2253 if (frag_now_fix () != 0)
2255 if (!frag_now
->tc_frag_data
.is_insn
)
2256 frag_wane (frag_now
);
2262 p
= frag_more (one_inst
.size
);
2263 s3_md_number_to_chars (p
, one_inst
.instruction
, one_inst
.size
);
2266 dwarf2_emit_insn (one_inst
.size
);
2269 relaxable_p
&= (one_inst
.relax_size
!= 0);
2270 relax_size
= relaxable_p
? one_inst
.relax_size
: 0;
2272 p
= frag_var (rs_machine_dependent
, relax_size
+ s3_RELAX_PAD_BYTE
, 0,
2273 s3_RELAX_ENCODE (one_inst
.size
, one_inst
.relax_size
,
2274 one_inst
.type
, 0, 0, relaxable_p
),
2278 s3_md_number_to_chars (p
, one_inst
.relax_inst
, relax_size
);
2282 s3_handle_dependency (struct s3_score_it
*theinst
)
2285 int warn_or_error
= 0; /* warn - 0; error - 1 */
2287 int remainder_bubbles
= 0;
2288 char cur_insn
[s3_INSN_NAME_LEN
];
2289 char pre_insn
[s3_INSN_NAME_LEN
];
2290 struct s3_score_it nop_inst
;
2291 struct s3_score_it pflush_inst
;
2293 nop_inst
.instruction
= 0x0000;
2295 nop_inst
.relax_inst
= 0x80008000;
2296 nop_inst
.relax_size
= 4;
2297 nop_inst
.type
= NO16_OPD
;
2299 pflush_inst
.instruction
= 0x8000800a;
2300 pflush_inst
.size
= 4;
2301 pflush_inst
.relax_inst
= 0x8000;
2302 pflush_inst
.relax_size
= 0;
2303 pflush_inst
.type
= NO_OPD
;
2305 /* pflush will clear all data dependency. */
2306 if (strcmp (theinst
->name
, "pflush") == 0)
2308 s3_init_dependency_vector ();
2312 /* Push current instruction to s3_dependency_vector[0]. */
2313 for (i
= s3_vector_size
- 1; i
> 0; i
--)
2314 memcpy (&s3_dependency_vector
[i
], &s3_dependency_vector
[i
- 1], sizeof (s3_dependency_vector
[i
]));
2316 memcpy (&s3_dependency_vector
[0], theinst
, sizeof (s3_dependency_vector
[i
]));
2318 /* There is no dependency between nop and any instruction. */
2319 if (strcmp (s3_dependency_vector
[0].name
, "nop") == 0
2320 || strcmp (s3_dependency_vector
[0].name
, "nop!") == 0)
2323 strcpy (cur_insn
, s3_dependency_vector
[0].name
);
2325 for (i
= 1; i
< s3_vector_size
; i
++)
2327 /* The element of s3_dependency_vector is NULL. */
2328 if (s3_dependency_vector
[i
].name
[0] == '\0')
2331 strcpy (pre_insn
, s3_dependency_vector
[i
].name
);
2333 bubbles
= s3_check_dependency (pre_insn
, s3_dependency_vector
[i
].reg
,
2334 cur_insn
, s3_dependency_vector
[0].reg
, &warn_or_error
);
2335 remainder_bubbles
= bubbles
- i
+ 1;
2337 if (remainder_bubbles
> 0)
2341 if (s3_fix_data_dependency
== 1)
2343 if (remainder_bubbles
<= 2)
2345 if (s3_warn_fix_data_dependency
)
2346 as_warn (_("Fix data dependency: %s %s -- %s %s (insert %d nop!/%d)"),
2347 s3_dependency_vector
[i
].name
, s3_dependency_vector
[i
].reg
,
2348 s3_dependency_vector
[0].name
, s3_dependency_vector
[0].reg
,
2349 remainder_bubbles
, bubbles
);
2351 for (j
= (s3_vector_size
- 1); (j
- remainder_bubbles
) > 0; j
--)
2352 memcpy (&s3_dependency_vector
[j
], &s3_dependency_vector
[j
- remainder_bubbles
],
2353 sizeof (s3_dependency_vector
[j
]));
2355 for (j
= 1; j
<= remainder_bubbles
; j
++)
2357 memset (&s3_dependency_vector
[j
], '\0', sizeof (s3_dependency_vector
[j
]));
2359 s3_build_one_frag (nop_inst
);
2364 if (s3_warn_fix_data_dependency
)
2365 as_warn (_("Fix data dependency: %s %s -- %s %s (insert 1 pflush/%d)"),
2366 s3_dependency_vector
[i
].name
, s3_dependency_vector
[i
].reg
,
2367 s3_dependency_vector
[0].name
, s3_dependency_vector
[0].reg
,
2370 for (j
= 1; j
< s3_vector_size
; j
++)
2371 memset (&s3_dependency_vector
[j
], '\0', sizeof (s3_dependency_vector
[j
]));
2373 /* Insert pflush. */
2374 s3_build_one_frag (pflush_inst
);
2381 as_bad (_("data dependency: %s %s -- %s %s (%d/%d bubble)"),
2382 s3_dependency_vector
[i
].name
, s3_dependency_vector
[i
].reg
,
2383 s3_dependency_vector
[0].name
, s3_dependency_vector
[0].reg
,
2384 remainder_bubbles
, bubbles
);
2388 as_warn (_("data dependency: %s %s -- %s %s (%d/%d bubble)"),
2389 s3_dependency_vector
[i
].name
, s3_dependency_vector
[i
].reg
,
2390 s3_dependency_vector
[0].name
, s3_dependency_vector
[0].reg
,
2391 remainder_bubbles
, bubbles
);
2398 static enum insn_class
2399 s3_get_insn_class_from_type (enum score_insn_type type
)
2401 enum insn_class retval
= (int) s3_FAIL
;
2407 case Rd_rvalueBP_I5
:
2408 case Rd_lvalueBP_I5
:
2421 retval
= INSN_CLASS_16
;
2430 case Rd_rvalueRs_SI10
:
2431 case Rd_lvalueRs_SI10
:
2432 case Rd_rvalueRs_preSI12
:
2433 case Rd_rvalueRs_postSI12
:
2434 case Rd_lvalueRs_preSI12
:
2435 case Rd_lvalueRs_postSI12
:
2437 case Rd_rvalueRs_SI15
:
2438 case Rd_lvalueRs_SI15
:
2447 case OP5_rvalueRs_SI15
:
2448 case I5_Rs_Rs_I5_OP5
:
2449 case x_rvalueRs_post4
:
2450 case Rd_rvalueRs_post4
:
2452 case Rd_lvalueRs_post4
:
2453 case x_lvalueRs_post4
:
2463 retval
= INSN_CLASS_32
;
2466 retval
= INSN_CLASS_PCE
;
2469 retval
= INSN_CLASS_SYN
;
2473 retval
= INSN_CLASS_48
;
2483 48-bit instruction: 1, 1, 0.
2484 32-bit instruction: 1, 0.
2485 16-bit instruction: 0. */
2487 s3_adjust_paritybit (bfd_vma m_code
, enum insn_class i_class
)
2490 bfd_vma m_code_high
= 0;
2491 unsigned long m_code_middle
= 0;
2492 unsigned long m_code_low
= 0;
2493 bfd_vma pb_high
= 0;
2494 unsigned long pb_middle
= 0;
2495 unsigned long pb_low
= 0;
2497 if (i_class
== INSN_CLASS_48
)
2499 pb_high
= 0x800000000000LL
;
2500 pb_middle
= 0x80000000;
2501 pb_low
= 0x00000000;
2502 m_code_high
= m_code
& 0x1fffc0000000LL
;
2503 m_code_middle
= m_code
& 0x3fff8000;
2504 m_code_low
= m_code
& 0x00007fff;
2505 result
= pb_high
| (m_code_high
<< 2) |
2506 pb_middle
| (m_code_middle
<< 1) |
2507 pb_low
| m_code_low
;
2509 else if (i_class
== INSN_CLASS_32
|| i_class
== INSN_CLASS_SYN
)
2511 pb_high
= 0x80000000;
2512 pb_low
= 0x00000000;
2513 m_code_high
= m_code
& 0x3fff8000;
2514 m_code_low
= m_code
& 0x00007fff;
2515 result
= pb_high
| (m_code_high
<< 1) | pb_low
| m_code_low
;
2517 else if (i_class
== INSN_CLASS_16
)
2521 m_code_high
= m_code
& 0x3fff8000;
2522 m_code_low
= m_code
& 0x00007fff;
2523 result
= pb_high
| (m_code_high
<< 1) | pb_low
| m_code_low
;
2525 else if (i_class
== INSN_CLASS_PCE
)
2527 /* Keep original. */
2529 pb_low
= 0x00008000;
2530 m_code_high
= m_code
& 0x3fff8000;
2531 m_code_low
= m_code
& 0x00007fff;
2532 result
= pb_high
| (m_code_high
<< 1) | pb_low
| m_code_low
;
2543 s3_gen_insn_frag (struct s3_score_it
*part_1
, struct s3_score_it
*part_2
)
2546 bfd_boolean pce_p
= FALSE
;
2547 int relaxable_p
= s3_g_opt
;
2549 struct s3_score_it
*inst1
= part_1
;
2550 struct s3_score_it
*inst2
= part_2
;
2551 struct s3_score_it backup_inst1
;
2553 pce_p
= (inst2
) ? TRUE
: FALSE
;
2554 memcpy (&backup_inst1
, inst1
, sizeof (struct s3_score_it
));
2556 /* Adjust instruction opcode and to be relaxed instruction opcode. */
2559 backup_inst1
.instruction
= ((backup_inst1
.instruction
& 0x7FFF) << 15)
2560 | (inst2
->instruction
& 0x7FFF);
2561 backup_inst1
.instruction
= s3_adjust_paritybit (backup_inst1
.instruction
, INSN_CLASS_PCE
);
2562 backup_inst1
.relax_inst
= 0x8000;
2563 backup_inst1
.size
= s3_INSN_SIZE
;
2564 backup_inst1
.relax_size
= 0;
2565 backup_inst1
.type
= Insn_Type_PCE
;
2569 backup_inst1
.instruction
= s3_adjust_paritybit (backup_inst1
.instruction
,
2570 s3_GET_INSN_CLASS (backup_inst1
.type
));
2573 if (backup_inst1
.relax_size
!= 0)
2575 enum insn_class tmp
;
2577 tmp
= (backup_inst1
.size
== s3_INSN_SIZE
) ? INSN_CLASS_16
: INSN_CLASS_32
;
2578 backup_inst1
.relax_inst
= s3_adjust_paritybit (backup_inst1
.relax_inst
, tmp
);
2581 /* Check data dependency. */
2582 s3_handle_dependency (&backup_inst1
);
2584 /* Start a new frag if frag_now is not empty and is not instruction frag, maybe it contains
2585 data produced by .ascii etc. Doing this is to make one instruction per frag. */
2586 if (frag_now_fix () != 0)
2588 if (!frag_now
->tc_frag_data
.is_insn
)
2589 frag_wane (frag_now
);
2594 /* Here, we must call frag_grow in order to keep the instruction frag type is
2595 rs_machine_dependent.
2596 For, frag_var may change frag_now->fr_type to rs_fill by calling frag_grow which
2597 actually will call frag_wane.
2598 Calling frag_grow first will create a new frag_now which free size is 20 that is enough
2602 p
= frag_more (backup_inst1
.size
);
2603 s3_md_number_to_chars (p
, backup_inst1
.instruction
, backup_inst1
.size
);
2606 dwarf2_emit_insn (backup_inst1
.size
);
2609 /* Generate fixup structure. */
2612 if (inst1
->reloc
.type
!= BFD_RELOC_NONE
)
2613 s3_fix_new_score (frag_now
, p
- frag_now
->fr_literal
,
2614 inst1
->size
, &inst1
->reloc
.exp
,
2615 inst1
->reloc
.pc_rel
, inst1
->reloc
.type
);
2617 if (inst2
->reloc
.type
!= BFD_RELOC_NONE
)
2618 s3_fix_new_score (frag_now
, p
- frag_now
->fr_literal
+ 2,
2619 inst2
->size
, &inst2
->reloc
.exp
, inst2
->reloc
.pc_rel
, inst2
->reloc
.type
);
2623 if (backup_inst1
.reloc
.type
!= BFD_RELOC_NONE
)
2624 s3_fix_new_score (frag_now
, p
- frag_now
->fr_literal
,
2625 backup_inst1
.size
, &backup_inst1
.reloc
.exp
,
2626 backup_inst1
.reloc
.pc_rel
, backup_inst1
.reloc
.type
);
2629 /* relax_size may be 2, 4, 12 or 0, 0 indicates no relaxation. */
2630 relaxable_p
&= (backup_inst1
.relax_size
!= 0);
2631 relax_size
= relaxable_p
? backup_inst1
.relax_size
: 0;
2633 p
= frag_var (rs_machine_dependent
, relax_size
+ s3_RELAX_PAD_BYTE
, 0,
2634 s3_RELAX_ENCODE (backup_inst1
.size
, backup_inst1
.relax_size
,
2635 backup_inst1
.type
, 0, 0, relaxable_p
),
2636 backup_inst1
.reloc
.exp
.X_add_symbol
, 0, NULL
);
2639 s3_md_number_to_chars (p
, backup_inst1
.relax_inst
, relax_size
);
2641 memcpy (inst1
, &backup_inst1
, sizeof (struct s3_score_it
));
2645 s3_parse_16_32_inst (char *insnstr
, bfd_boolean gen_frag_p
)
2649 char *operator = insnstr
;
2650 const struct s3_asm_opcode
*opcode
;
2652 /* Parse operator and operands. */
2653 s3_skip_whitespace (operator);
2655 for (p
= operator; *p
!= '\0'; p
++)
2656 if ((*p
== ' ') || (*p
== '!'))
2665 opcode
= (const struct s3_asm_opcode
*) hash_find (s3_score_ops_hsh
, operator);
2668 memset (&s3_inst
, '\0', sizeof (s3_inst
));
2669 sprintf (s3_inst
.str
, "%s", insnstr
);
2672 s3_inst
.instruction
= opcode
->value
;
2673 s3_inst
.relax_inst
= opcode
->relax_value
;
2674 s3_inst
.type
= opcode
->type
;
2675 s3_inst
.size
= s3_GET_INSN_SIZE (s3_inst
.type
);
2676 s3_inst
.relax_size
= 0;
2678 sprintf (s3_inst
.name
, "%s", opcode
->template_name
);
2679 strcpy (s3_inst
.reg
, "");
2680 s3_inst
.error
= NULL
;
2681 s3_inst
.reloc
.type
= BFD_RELOC_NONE
;
2683 (*opcode
->parms
) (p
);
2685 /* It indicates current instruction is a macro instruction if s3_inst.bwarn equals -1. */
2686 if ((s3_inst
.bwarn
!= -1) && (!s3_inst
.error
) && (gen_frag_p
))
2687 s3_gen_insn_frag (&s3_inst
, NULL
);
2690 s3_inst
.error
= _("unrecognized opcode");
2694 s3_parse_48_inst (char *insnstr
, bfd_boolean gen_frag_p
)
2698 char *operator = insnstr
;
2699 const struct s3_asm_opcode
*opcode
;
2701 /* Parse operator and operands. */
2702 s3_skip_whitespace (operator);
2704 for (p
= operator; *p
!= '\0'; p
++)
2711 opcode
= (const struct s3_asm_opcode
*) hash_find (s3_score_ops_hsh
, operator);
2714 memset (&s3_inst
, '\0', sizeof (s3_inst
));
2715 sprintf (s3_inst
.str
, "%s", insnstr
);
2718 s3_inst
.instruction
= opcode
->value
;
2719 s3_inst
.relax_inst
= opcode
->relax_value
;
2720 s3_inst
.type
= opcode
->type
;
2721 s3_inst
.size
= s3_GET_INSN_SIZE (s3_inst
.type
);
2722 s3_inst
.relax_size
= 0;
2724 sprintf (s3_inst
.name
, "%s", opcode
->template_name
);
2725 strcpy (s3_inst
.reg
, "");
2726 s3_inst
.error
= NULL
;
2727 s3_inst
.reloc
.type
= BFD_RELOC_NONE
;
2729 (*opcode
->parms
) (p
);
2731 /* It indicates current instruction is a macro instruction if s3_inst.bwarn equals -1. */
2732 if ((s3_inst
.bwarn
!= -1) && (!s3_inst
.error
) && (gen_frag_p
))
2733 s3_gen_insn_frag (&s3_inst
, NULL
);
2736 s3_inst
.error
= _("unrecognized opcode");
2740 s3_append_insn (char *str
, bfd_boolean gen_frag_p
)
2742 int retval
= s3_SUCCESS
;
2744 s3_parse_16_32_inst (str
, gen_frag_p
);
2748 retval
= (int) s3_FAIL
;
2749 as_bad (_("%s -- `%s'"), s3_inst
.error
, s3_inst
.str
);
2750 s3_inst
.error
= NULL
;
2757 s3_do16_mv_cmp (char *str
)
2759 s3_skip_whitespace (str
);
2761 if (s3_reg_required_here (&str
, 5, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
2762 || s3_skip_past_comma (&str
) == (int) s3_FAIL
2763 || s3_reg_required_here (&str
, 0, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
2764 || s3_end_of_line (str
) == (int) s3_FAIL
)
2771 s3_do16_cmpi (char *str
)
2773 s3_skip_whitespace (str
);
2775 if (s3_reg_required_here (&str
, 5, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
2776 || s3_skip_past_comma (&str
) == (int) s3_FAIL
2777 || s3_data_op2 (&str
, 0, _SIMM5
) == (int) s3_FAIL
2778 || s3_end_of_line (str
) == (int) s3_FAIL
)
2785 s3_do16_addi (char *str
)
2787 s3_skip_whitespace (str
);
2789 if (s3_reglow_required_here (&str
, 6) == (int) s3_FAIL
2790 || s3_skip_past_comma (&str
) == (int) s3_FAIL
2791 || s3_data_op2 (&str
, 0, _SIMM6
) == (int) s3_FAIL
2792 || s3_end_of_line (str
) == (int) s3_FAIL
)
2798 /* Handle bitclr! / bitset! / bittst! / bittgl! */
2800 s3_do16_rdi5 (char *str
)
2802 s3_skip_whitespace (str
);
2804 if (s3_reglow_required_here (&str
, 5) == (int) s3_FAIL
2805 || s3_skip_past_comma (&str
) == (int) s3_FAIL
2806 || s3_data_op2 (&str
, 0, _IMM5
) == (int) s3_FAIL
2807 || s3_end_of_line (str
) == (int) s3_FAIL
)
2811 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>>5) & 0xf) << 20)
2812 | (((s3_inst
.instruction
>> 5) & 0xf) << 15) | (((s3_inst
.instruction
) & 0x1f) << 10);
2813 s3_inst
.relax_size
= 4;
2818 /* Handle sdbbp!. */
2820 s3_do16_xi5 (char *str
)
2822 s3_skip_whitespace (str
);
2824 if (s3_data_op2 (&str
, 0, _IMM5
) == (int) s3_FAIL
|| s3_end_of_line (str
) == (int) s3_FAIL
)
2828 /* Check that an immediate is word alignment or half word alignment.
2829 If so, convert it to the right format. */
2831 s3_validate_immediate_align (int val
, unsigned int data_type
)
2833 if (data_type
== _IMM5_RSHIFT_1
)
2837 s3_inst
.error
= _("address offset must be half word alignment");
2838 return (int) s3_FAIL
;
2841 else if ((data_type
== _IMM5_RSHIFT_2
) || (data_type
== _IMM10_RSHIFT_2
))
2845 s3_inst
.error
= _("address offset must be word alignment");
2846 return (int) s3_FAIL
;
2854 s3_exp_ldst_offset (char **str
, int shift
, unsigned int data_type
)
2860 if ((*dataptr
== '0') && (*(dataptr
+ 1) == 'x')
2861 && (data_type
!= _SIMM16_LA
)
2862 && (data_type
!= _VALUE_HI16
)
2863 && (data_type
!= _VALUE_LO16
)
2864 && (data_type
!= _IMM16
)
2865 && (data_type
!= _IMM15
)
2866 && (data_type
!= _IMM14
)
2867 && (data_type
!= _IMM4
)
2868 && (data_type
!= _IMM5
)
2869 && (data_type
!= _IMM8
)
2870 && (data_type
!= _IMM5_RSHIFT_1
)
2871 && (data_type
!= _IMM5_RSHIFT_2
)
2872 && (data_type
!= _SIMM14_NEG
)
2873 && (data_type
!= _IMM10_RSHIFT_2
))
2878 if (s3_my_get_expression (&s3_inst
.reloc
.exp
, str
) == (int) s3_FAIL
)
2879 return (int) s3_FAIL
;
2881 if (s3_inst
.reloc
.exp
.X_op
== O_constant
)
2883 /* Need to check the immediate align. */
2884 int value
= s3_validate_immediate_align (s3_inst
.reloc
.exp
.X_add_number
, data_type
);
2886 if (value
== (int) s3_FAIL
)
2887 return (int) s3_FAIL
;
2889 value
= s3_validate_immediate (s3_inst
.reloc
.exp
.X_add_number
, data_type
, 0);
2890 if (value
== (int) s3_FAIL
)
2893 sprintf (s3_err_msg
,
2894 _("invalid constant: %d bit expression not in range %d..%d"),
2895 s3_score_df_range
[data_type
].bits
,
2896 s3_score_df_range
[data_type
].range
[0], s3_score_df_range
[data_type
].range
[1]);
2898 sprintf (s3_err_msg
,
2899 _("invalid constant: %d bit expression not in range %d..%d"),
2900 s3_score_df_range
[data_type
- 24].bits
,
2901 s3_score_df_range
[data_type
- 24].range
[0], s3_score_df_range
[data_type
- 24].range
[1]);
2902 s3_inst
.error
= s3_err_msg
;
2903 return (int) s3_FAIL
;
2906 if (data_type
== _IMM5_RSHIFT_1
)
2910 else if ((data_type
== _IMM5_RSHIFT_2
) || (data_type
== _IMM10_RSHIFT_2
))
2915 if (s3_score_df_range
[data_type
].range
[0] != 0)
2917 value
&= (1 << s3_score_df_range
[data_type
].bits
) - 1;
2920 s3_inst
.instruction
|= value
<< shift
;
2924 s3_inst
.reloc
.pc_rel
= 0;
2931 s3_do_ldst_insn (char *str
)
2941 s3_skip_whitespace (str
);
2943 if (((conflict_reg
= s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
)
2944 || (s3_skip_past_comma (&str
) == (int) s3_FAIL
))
2947 /* ld/sw rD, [rA, simm15] ld/sw rD, [rA]+, simm12 ld/sw rD, [rA, simm12]+. */
2951 s3_skip_whitespace (str
);
2953 if ((reg
= s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
)
2956 /* Conflicts can occur on stores as well as loads. */
2957 conflict_reg
= (conflict_reg
== reg
);
2958 s3_skip_whitespace (str
);
2959 temp
= str
+ 1; /* The latter will process decimal/hex expression. */
2961 /* ld/sw rD, [rA]+, simm12 ld/sw rD, [rA]+. */
2968 /* ld/sw rD, [rA]+, simm12. */
2969 if (s3_skip_past_comma (&str
) == s3_SUCCESS
)
2971 if ((s3_exp_ldst_offset (&str
, 3, _SIMM12
) == (int) s3_FAIL
)
2972 || (s3_end_of_line (str
) == (int) s3_FAIL
))
2977 unsigned int ldst_func
= s3_inst
.instruction
& OPC_PSEUDOLDST_MASK
;
2979 if ((ldst_func
== INSN_LH
)
2980 || (ldst_func
== INSN_LHU
)
2981 || (ldst_func
== INSN_LW
)
2982 || (ldst_func
== INSN_LB
)
2983 || (ldst_func
== INSN_LBU
))
2985 s3_inst
.error
= _("register same as write-back base");
2990 ldst_idx
= s3_inst
.instruction
& OPC_PSEUDOLDST_MASK
;
2991 s3_inst
.instruction
&= ~OPC_PSEUDOLDST_MASK
;
2992 s3_inst
.instruction
|= s3_score_ldst_insns
[ldst_idx
* 3 + LDST_POST
].value
;
2994 /* lw rD, [rA]+, 4 convert to pop rD, [rA]. */
2995 if ((s3_inst
.instruction
& 0x3e000007) == 0x0e000000)
2997 /* rs = r0, offset = 4 */
2998 if ((((s3_inst
.instruction
>> 15) & 0x1f) == 0)
2999 && (((s3_inst
.instruction
>> 3) & 0xfff) == 4))
3001 /* Relax to pop!. */
3002 s3_inst
.relax_inst
= 0x0040 | ((s3_inst
.instruction
>> 20) & 0x1f);
3003 s3_inst
.relax_size
= 2;
3008 /* ld/sw rD, [rA]+ convert to ld/sw rD, [rA, 0]+. */
3011 s3_SET_INSN_ERROR (NULL
);
3012 if (s3_end_of_line (str
) == (int) s3_FAIL
)
3018 value
= s3_validate_immediate (s3_inst
.reloc
.exp
.X_add_number
, _SIMM12
, 0);
3019 value
&= (1 << s3_score_df_range
[_SIMM12
].bits
) - 1;
3020 ldst_idx
= s3_inst
.instruction
& OPC_PSEUDOLDST_MASK
;
3021 s3_inst
.instruction
&= ~OPC_PSEUDOLDST_MASK
;
3022 s3_inst
.instruction
|= s3_score_ldst_insns
[ldst_idx
* 3 + pre_inc
].value
;
3023 s3_inst
.instruction
|= value
<< 3;
3024 s3_inst
.relax_inst
= 0x8000;
3028 /* ld/sw rD, [rA] convert to ld/sw rD, [rA, simm15]. */
3031 if (s3_end_of_line (str
) == (int) s3_FAIL
)
3034 ldst_idx
= s3_inst
.instruction
& OPC_PSEUDOLDST_MASK
;
3035 s3_inst
.instruction
&= ~OPC_PSEUDOLDST_MASK
;
3036 s3_inst
.instruction
|= s3_score_ldst_insns
[ldst_idx
* 3 + LDST_NOUPDATE
].value
;
3038 /* lbu rd, [rs] -> lbu! rd, [rs] */
3039 if (ldst_idx
== INSN_LBU
)
3041 s3_inst
.relax_inst
= INSN16_LBU
;
3043 else if (ldst_idx
== INSN_LH
)
3045 s3_inst
.relax_inst
= INSN16_LH
;
3047 else if (ldst_idx
== INSN_LW
)
3049 s3_inst
.relax_inst
= INSN16_LW
;
3051 else if (ldst_idx
== INSN_SB
)
3053 s3_inst
.relax_inst
= INSN16_SB
;
3055 else if (ldst_idx
== INSN_SH
)
3057 s3_inst
.relax_inst
= INSN16_SH
;
3059 else if (ldst_idx
== INSN_SW
)
3061 s3_inst
.relax_inst
= INSN16_SW
;
3065 s3_inst
.relax_inst
= 0x8000;
3068 /* lw/lh/lbu/sw/sh/sb, offset = 0, relax to 16 bit instruction. */
3069 /* if ((ldst_idx == INSN_LBU)
3070 || (ldst_idx == INSN_LH)
3071 || (ldst_idx == INSN_LW)
3072 || (ldst_idx == INSN_SB) || (ldst_idx == INSN_SH) || (ldst_idx == INSN_SW))*/
3073 if ( (ldst_idx
== INSN_LW
)|| (ldst_idx
== INSN_SW
))
3075 /* ra only 3 bit , rd only 4 bit for lw! and sw! */
3076 if ((((s3_inst
.instruction
>> 15) & 0x18) == 0) && (((s3_inst
.instruction
>> 20) & 0x10) == 0))
3078 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>> 20) & 0xf) << 8) |
3079 (((s3_inst
.instruction
>> 15) & 0x7) << 5);
3080 s3_inst
.relax_size
= 2;
3087 /* ld/sw rD, [rA, simm15] ld/sw rD, [rA, simm12]+. */
3090 if (s3_skip_past_comma (&str
) == (int) s3_FAIL
)
3092 s3_inst
.error
= _("pre-indexed expression expected");
3096 if (s3_my_get_expression (&s3_inst
.reloc
.exp
, &str
) == (int) s3_FAIL
)
3099 s3_skip_whitespace (str
);
3102 s3_inst
.error
= _("missing ]");
3106 s3_skip_whitespace (str
);
3107 /* ld/sw rD, [rA, simm12]+. */
3114 unsigned int ldst_func
= s3_inst
.instruction
& OPC_PSEUDOLDST_MASK
;
3116 if ((ldst_func
== INSN_LH
)
3117 || (ldst_func
== INSN_LHU
)
3118 || (ldst_func
== INSN_LW
)
3119 || (ldst_func
== INSN_LB
)
3120 || (ldst_func
== INSN_LBU
))
3122 s3_inst
.error
= _("register same as write-back base");
3128 if (s3_end_of_line (str
) == (int) s3_FAIL
)
3131 if (s3_inst
.reloc
.exp
.X_op
== O_constant
)
3133 unsigned int data_type
;
3136 data_type
= _SIMM12
;
3138 data_type
= _SIMM15
;
3141 if ((*dataptr
== '0') && (*(dataptr
+ 1) == 'x')
3142 && (data_type
!= _SIMM16_LA
)
3143 && (data_type
!= _VALUE_HI16
)
3144 && (data_type
!= _VALUE_LO16
)
3145 && (data_type
!= _IMM16
)
3146 && (data_type
!= _IMM15
)
3147 && (data_type
!= _IMM14
)
3148 && (data_type
!= _IMM4
)
3149 && (data_type
!= _IMM5
)
3150 && (data_type
!= _IMM8
)
3151 && (data_type
!= _IMM5_RSHIFT_1
)
3152 && (data_type
!= _IMM5_RSHIFT_2
)
3153 && (data_type
!= _SIMM14_NEG
)
3154 && (data_type
!= _IMM10_RSHIFT_2
))
3159 value
= s3_validate_immediate (s3_inst
.reloc
.exp
.X_add_number
, data_type
, 0);
3160 if (value
== (int) s3_FAIL
)
3163 sprintf (s3_err_msg
,
3164 _("invalid constant: %d bit expression not in range %d..%d"),
3165 s3_score_df_range
[data_type
].bits
,
3166 s3_score_df_range
[data_type
].range
[0], s3_score_df_range
[data_type
].range
[1]);
3168 sprintf (s3_err_msg
,
3169 _("invalid constant: %d bit expression not in range %d..%d"),
3170 s3_score_df_range
[data_type
- 24].bits
,
3171 s3_score_df_range
[data_type
- 24].range
[0],
3172 s3_score_df_range
[data_type
- 24].range
[1]);
3173 s3_inst
.error
= s3_err_msg
;
3177 value
&= (1 << s3_score_df_range
[data_type
].bits
) - 1;
3178 ldst_idx
= s3_inst
.instruction
& OPC_PSEUDOLDST_MASK
;
3179 s3_inst
.instruction
&= ~OPC_PSEUDOLDST_MASK
;
3180 s3_inst
.instruction
|= s3_score_ldst_insns
[ldst_idx
* 3 + pre_inc
].value
;
3182 s3_inst
.instruction
|= value
<< 3;
3184 s3_inst
.instruction
|= value
;
3186 /* lw rD, [rA, simm15] */
3187 if ((s3_inst
.instruction
& 0x3e000000) == 0x20000000)
3189 /* rD in [r0 - r15]. , ra in [r0-r7] */
3190 if ((((s3_inst
.instruction
>> 15) & 0x18) == 0)
3191 && (((s3_inst
.instruction
>> 20) & 0x10) == 0))
3193 /* simm = [bit 7], lw -> lw!. */
3194 if (((s3_inst
.instruction
& 0x7f80) == 0)&&((s3_inst
.instruction
&0x3)==0))
3196 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>> 15) & 0x7) << 5)
3197 | (((s3_inst
.instruction
>> 20) & 0xf) << 8)|(value
>>2);
3198 s3_inst
.relax_size
= 2;
3202 s3_inst
.relax_inst
= 0x8000;
3207 s3_inst
.relax_inst
= 0x8000;
3210 /* sw rD, [rA, simm15] */
3211 else if ((s3_inst
.instruction
& 0x3e000000) == 0x28000000)
3213 /* rD is in [r0 - r15] and ra in [r0-r7] */
3214 if ((((s3_inst
.instruction
>> 15) & 0x18) == 0) && (((s3_inst
.instruction
>> 20) & 0x10) == 0))
3216 /* simm15 =7 bit , sw -> sw!. */
3217 if (((s3_inst
.instruction
& 0x7f80) == 0)&&((s3_inst
.instruction
&0x3)==0))
3219 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>> 15) & 0xf) << 5)
3220 | (((s3_inst
.instruction
>> 20) & 0xf) << 8)|(value
>>2);
3221 s3_inst
.relax_size
= 2;
3223 /* rA = r2, sw -> swp!. */
3226 s3_inst
.relax_inst
= 0x8000;
3231 s3_inst
.relax_inst
= 0x8000;
3234 /* sw rD, [rA, simm15]+ sw pre. */
3235 else if ((s3_inst
.instruction
& 0x3e000007) == 0x06000004)
3237 /* simm15 = -4. and ra==r0 */
3238 if ((((s3_inst
.instruction
>> 15) & 0x1f) == 0)
3239 && (((s3_inst
.instruction
>> 3) & 0xfff) == 0xffc))
3242 s3_inst
.relax_inst
= 0x0060 | ((s3_inst
.instruction
>> 20) & 0x1f);
3243 s3_inst
.relax_size
= 2;
3247 s3_inst
.relax_inst
= 0x8000;
3252 s3_inst
.relax_inst
= 0x8000;
3259 /* FIXME: may set error, for there is no ld/sw rD, [rA, label] */
3260 s3_inst
.reloc
.pc_rel
= 0;
3266 s3_inst
.error
= s3_BAD_ARGS
;
3272 s3_do_cache (char *str
)
3274 s3_skip_whitespace (str
);
3276 if ((s3_data_op2 (&str
, 20, _IMM5
) == (int) s3_FAIL
) || (s3_skip_past_comma (&str
) == (int) s3_FAIL
))
3284 cache_op
= (s3_inst
.instruction
>> 20) & 0x1F;
3285 sprintf (s3_inst
.name
, "cache %d", cache_op
);
3291 s3_skip_whitespace (str
);
3293 if (s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
)
3296 s3_skip_whitespace (str
);
3298 /* cache op, [rA] */
3299 if (s3_skip_past_comma (&str
) == (int) s3_FAIL
)
3301 s3_SET_INSN_ERROR (NULL
);
3304 s3_inst
.error
= _("missing ]");
3309 /* cache op, [rA, simm15] */
3312 if (s3_exp_ldst_offset (&str
, 0, _SIMM15
) == (int) s3_FAIL
)
3317 s3_skip_whitespace (str
);
3320 s3_inst
.error
= _("missing ]");
3325 if (s3_end_of_line (str
) == (int) s3_FAIL
)
3330 s3_inst
.error
= s3_BAD_ARGS
;
3335 s3_do_crdcrscrsimm5 (char *str
)
3340 s3_skip_whitespace (str
);
3342 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE_CR
) == (int) s3_FAIL
3343 || s3_skip_past_comma (&str
) == (int) s3_FAIL
3344 || s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE_CR
) == (int) s3_FAIL
3345 || s3_skip_past_comma (&str
) == (int) s3_FAIL
3346 || s3_reg_required_here (&str
, 10, s3_REG_TYPE_SCORE_CR
) == (int) s3_FAIL
3347 || s3_skip_past_comma (&str
) == (int) s3_FAIL
)
3350 /* cop1 cop_code20. */
3351 if (s3_data_op2 (&str
, 5, _IMM20
) == (int) s3_FAIL
)
3356 if (s3_data_op2 (&str
, 5, _IMM5
) == (int) s3_FAIL
)
3360 s3_end_of_line (str
);
3363 /* Handle ldc/stc. */
3365 s3_do_ldst_cop (char *str
)
3367 s3_skip_whitespace (str
);
3369 if ((s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE_CR
) == (int) s3_FAIL
)
3370 || (s3_skip_past_comma (&str
) == (int) s3_FAIL
))
3376 s3_skip_whitespace (str
);
3378 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
)
3381 s3_skip_whitespace (str
);
3385 if (s3_exp_ldst_offset (&str
, 5, _IMM10_RSHIFT_2
) == (int) s3_FAIL
)
3388 s3_skip_whitespace (str
);
3391 s3_inst
.error
= _("missing ]");
3396 s3_end_of_line (str
);
3399 s3_inst
.error
= s3_BAD_ARGS
;
3403 s3_do16_ldst_insn (char *str
)
3405 int conflict_reg
= 0;
3406 s3_skip_whitespace (str
);
3408 if ((s3_reglow_required_here (&str
, 8) == (int) s3_FAIL
) || (s3_skip_past_comma (&str
) == (int) s3_FAIL
))
3415 s3_skip_whitespace (str
);
3417 if ((conflict_reg
= s3_reglow_required_here (&str
, 5)) == (int) s3_FAIL
)
3419 if (conflict_reg
&0x8)
3421 sprintf (s3_err_msg
, _("invalid register number: %d is not in [r0--r7]"),conflict_reg
);
3422 s3_inst
.error
= s3_err_msg
;
3426 s3_skip_whitespace (str
);
3431 if (s3_end_of_line (str
) == (int) s3_FAIL
)
3436 if (s3_skip_past_comma (&str
) == (int) s3_FAIL
)
3438 s3_inst
.error
= _("comma is expected");
3441 if (s3_my_get_expression (&s3_inst
.reloc
.exp
, &str
) == (int) s3_FAIL
)
3443 s3_skip_whitespace (str
);
3446 s3_inst
.error
= _("missing ]");
3449 if (s3_end_of_line (str
) == (int) s3_FAIL
)
3451 if (s3_inst
.reloc
.exp
.X_op
== O_constant
)
3454 unsigned int data_type
;
3455 data_type
= _IMM5_RSHIFT_2
;
3456 value
= s3_validate_immediate (s3_inst
.reloc
.exp
.X_add_number
, data_type
, 0);
3457 if (value
== (int) s3_FAIL
)
3460 sprintf (s3_err_msg
,
3461 _("invalid constant: %d bit expression not in range %d..%d"),
3462 s3_score_df_range
[data_type
].bits
,
3463 s3_score_df_range
[data_type
].range
[0], s3_score_df_range
[data_type
].range
[1]);
3464 s3_inst
.error
= s3_err_msg
;
3469 sprintf (s3_err_msg
, _("invalid constant: %d is not word align integer"),value
);
3470 s3_inst
.error
= s3_err_msg
;
3475 s3_inst
.instruction
|= value
;
3481 sprintf (s3_err_msg
, _("missing ["));
3482 s3_inst
.error
= s3_err_msg
;
3488 s3_do_lw48 (char *str
)
3490 bfd_signed_vma val
= 0;
3492 s3_skip_whitespace (str
);
3494 if ((s3_reg_required_here (&str
, 37, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
)
3495 || (s3_skip_past_comma (&str
) == (int) s3_FAIL
))
3498 if (s3_my_get_expression (&s3_inst
.reloc
.exp
, &str
) == (int) s3_FAIL
3499 || s3_end_of_line (str
) == (int) s3_FAIL
)
3504 /* Check word align for lw48 rd, value. */
3505 if ((s3_inst
.reloc
.exp
.X_add_symbol
== NULL
)
3506 && ((s3_inst
.reloc
.exp
.X_add_number
& 0x3) != 0))
3508 s3_inst
.error
= _("invalid constant: 32 bit expression not word align");
3512 /* Check and set offset. */
3513 val
= s3_inst
.reloc
.exp
.X_add_number
;
3514 if ((s3_inst
.reloc
.exp
.X_add_symbol
== NULL
)
3515 && (!(val
>= 0 && val
<= 0xffffffffLL
)))
3517 s3_inst
.error
= _("invalid constant: 32 bit expression not in range [0, 0xffffffff]");
3523 s3_inst
.instruction
|= (val
<< 7);
3525 /* Set reloc type. */
3526 s3_inst
.reloc
.type
= BFD_RELOC_SCORE_IMM30
;
3531 s3_do_sw48 (char *str
)
3533 bfd_signed_vma val
= 0;
3535 s3_skip_whitespace (str
);
3537 if ((s3_reg_required_here (&str
, 37, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
)
3538 || (s3_skip_past_comma (&str
) == (int) s3_FAIL
))
3541 if (s3_my_get_expression (&s3_inst
.reloc
.exp
, &str
) == (int) s3_FAIL
3542 || s3_end_of_line (str
) == (int) s3_FAIL
)
3547 /* Check word align for lw48 rd, value. */
3548 if ((s3_inst
.reloc
.exp
.X_add_symbol
== NULL
)
3549 && ((s3_inst
.reloc
.exp
.X_add_number
& 0x3) != 0))
3551 s3_inst
.error
= _("invalid constant: 32 bit expression not word align");
3555 /* Check and set offset. */
3556 val
= s3_inst
.reloc
.exp
.X_add_number
;
3557 if ((s3_inst
.reloc
.exp
.X_add_symbol
== NULL
)
3558 && (!(val
>= 0 && val
<= 0xffffffffLL
)))
3560 s3_inst
.error
= _("invalid constant: 32 bit expression not in range [0, 0xffffffff]");
3566 s3_inst
.instruction
|= (val
<< 7);
3568 /* Set reloc type. */
3569 s3_inst
.reloc
.type
= BFD_RELOC_SCORE_IMM30
;
3573 s3_do_ldi48 (char *str
)
3577 s3_skip_whitespace (str
);
3579 if (s3_reg_required_here (&str
, 37, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
3580 || s3_skip_past_comma (&str
) == (int) s3_FAIL
)
3583 if (s3_my_get_expression (&s3_inst
.reloc
.exp
, &str
) == (int) s3_FAIL
3584 || s3_end_of_line (str
) == (int) s3_FAIL
)
3589 /* Check and set offset. */
3590 val
= s3_inst
.reloc
.exp
.X_add_number
;
3591 if (!(val
>= -0xffffffffLL
&& val
<= 0xffffffffLL
))
3593 s3_inst
.error
= _("invalid constant: 32 bit expression not in range [-0x80000000, 0x7fffffff]");
3598 s3_inst
.instruction
|= (val
<< 5);
3600 /* Set reloc type. */
3601 s3_inst
.reloc
.type
= BFD_RELOC_SCORE_IMM32
;
3605 s3_do_sdbbp48 (char *str
)
3607 s3_skip_whitespace (str
);
3609 if (s3_data_op2 (&str
, 5, _IMM5
) == (int) s3_FAIL
|| s3_end_of_line (str
) == (int) s3_FAIL
)
3614 s3_do_and48 (char *str
)
3616 s3_skip_whitespace (str
);
3618 if (s3_reglow_required_here (&str
, 38) == (int) s3_FAIL
3619 || s3_skip_past_comma (&str
) == (int) s3_FAIL
3620 || s3_reglow_required_here (&str
, 34) == (int) s3_FAIL
3621 || s3_skip_past_comma (&str
) == (int) s3_FAIL
3622 || s3_data_op2 (&str
, 2, _IMM32
) == (int) s3_FAIL
3623 || s3_end_of_line (str
) == (int) s3_FAIL
)
3628 s3_do_or48 (char *str
)
3630 s3_skip_whitespace (str
);
3632 if (s3_reglow_required_here (&str
, 38) == (int) s3_FAIL
3633 || s3_skip_past_comma (&str
) == (int) s3_FAIL
3634 || s3_reglow_required_here (&str
, 34) == (int) s3_FAIL
3635 || s3_skip_past_comma (&str
) == (int) s3_FAIL
3636 || s3_data_op2 (&str
, 2, _IMM32
) == (int) s3_FAIL
3637 || s3_end_of_line (str
) == (int) s3_FAIL
)
3642 s3_do_mbitclr (char *str
)
3645 s3_skip_whitespace (str
);
3649 sprintf (s3_err_msg
, _("missing ["));
3650 s3_inst
.error
= s3_err_msg
;
3655 s3_inst
.instruction
&= 0x0;
3657 if ((s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
)
3658 || (s3_skip_past_comma (&str
) == (int) s3_FAIL
)
3659 || (s3_data_op2 (&str
, 0, _IMM11
) == (int) s3_FAIL
))
3662 /* Get imm11 and refill opcode. */
3663 val
= s3_inst
.instruction
& 0x7ff;
3665 s3_inst
.instruction
&= 0x000f8000;
3666 s3_inst
.instruction
|= 0x00000064;
3670 sprintf (s3_err_msg
, _("missing ]"));
3671 s3_inst
.error
= s3_err_msg
;
3676 if ((s3_skip_past_comma (&str
) == (int) s3_FAIL
)
3677 || (s3_data_op2 (&str
, 10, _IMM5
) == (int) s3_FAIL
))
3680 /* Set imm11 to opcode. */
3681 s3_inst
.instruction
|= (val
& 0x1)
3682 | (((val
>> 1 ) & 0x7) << 7)
3683 | (((val
>> 4 ) & 0x1f) << 20);
3687 s3_do_mbitset (char *str
)
3690 s3_skip_whitespace (str
);
3694 sprintf (s3_err_msg
, _("missing ["));
3695 s3_inst
.error
= s3_err_msg
;
3700 s3_inst
.instruction
&= 0x0;
3702 if ((s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
)
3703 || (s3_skip_past_comma (&str
) == (int) s3_FAIL
)
3704 || (s3_data_op2 (&str
, 0, _IMM11
) == (int) s3_FAIL
))
3707 /* Get imm11 and refill opcode. */
3708 val
= s3_inst
.instruction
& 0x7ff;
3710 s3_inst
.instruction
&= 0x000f8000;
3711 s3_inst
.instruction
|= 0x0000006c;
3715 sprintf (s3_err_msg
, _("missing ]"));
3716 s3_inst
.error
= s3_err_msg
;
3721 if ((s3_skip_past_comma (&str
) == (int) s3_FAIL
)
3722 || (s3_data_op2 (&str
, 10, _IMM5
) == (int) s3_FAIL
))
3725 /* Set imm11 to opcode. */
3726 s3_inst
.instruction
|= (val
& 0x1)
3727 | (((val
>> 1 ) & 0x7) << 7)
3728 | (((val
>> 4 ) & 0x1f) << 20);
3732 s3_do16_slli_srli (char *str
)
3734 s3_skip_whitespace (str
);
3736 if ((s3_reglow_required_here (&str
, 5) == (int) s3_FAIL
)
3737 || (s3_skip_past_comma (&str
) == (int) s3_FAIL
)
3738 || s3_data_op2 (&str
, 0, _IMM5
) == (int) s3_FAIL
3739 || s3_end_of_line (str
) == (int) s3_FAIL
)
3744 s3_do16_ldiu (char *str
)
3746 s3_skip_whitespace (str
);
3748 if ((s3_reg_required_here (&str
, 5,s3_REG_TYPE_SCORE
) == (int) s3_FAIL
)
3749 || (s3_skip_past_comma (&str
) == (int) s3_FAIL
)
3750 || s3_data_op2 (&str
, 0, _IMM5
) == (int) s3_FAIL
3751 || s3_end_of_line (str
) == (int) s3_FAIL
)
3756 s3_do16_push_pop (char *str
)
3758 s3_skip_whitespace (str
);
3759 if ((s3_reg_required_here (&str
, 0, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
3760 || s3_end_of_line (str
) == (int) s3_FAIL
)
3765 s3_do16_rpush (char *str
)
3769 s3_skip_whitespace (str
);
3770 if ((reg
= (s3_reg_required_here (&str
, 5, s3_REG_TYPE_SCORE
))) == (int) s3_FAIL
3771 || s3_skip_past_comma (&str
) == (int) s3_FAIL
3772 || s3_data_op2 (&str
, 0, _IMM5_MULTI_LOAD
) == (int) s3_FAIL
3773 || s3_end_of_line (str
) == (int) s3_FAIL
)
3778 2: to 31: normal value. */
3779 val
= s3_inst
.instruction
& 0x1f;
3782 s3_inst
.error
= _("imm5 should >= 2");
3787 s3_inst
.error
= _("reg should <= 31");
3793 s3_do16_rpop (char *str
)
3797 s3_skip_whitespace (str
);
3798 if ((reg
= (s3_reg_required_here (&str
, 5, s3_REG_TYPE_SCORE
))) == (int) s3_FAIL
3799 || s3_skip_past_comma (&str
) == (int) s3_FAIL
3800 || s3_data_op2 (&str
, 0, _IMM5_MULTI_LOAD
) == (int) s3_FAIL
3801 || s3_end_of_line (str
) == (int) s3_FAIL
)
3806 2: to 31: normal value. */
3807 val
= s3_inst
.instruction
& 0x1f;
3810 s3_inst
.error
= _("imm5 should >= 2");
3816 s3_inst
.error
= _("reg should <= 31");
3821 if ((reg
+ val
) <= 32)
3822 reg
= reg
+ val
- 1;
3824 reg
= reg
+ val
- 33;
3825 s3_inst
.instruction
&= 0x7c1f;
3826 s3_inst
.instruction
|= (reg
<< 5);
3831 /* Handle lcb/lcw/lce/scb/scw/sce. */
3833 s3_do_ldst_unalign (char *str
)
3837 if (s3_university_version
== 1)
3839 s3_inst
.error
= s3_ERR_FOR_SCORE5U_ATOMIC
;
3843 s3_skip_whitespace (str
);
3845 /* lcb/scb [rA]+. */
3849 s3_skip_whitespace (str
);
3851 if (s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
)
3858 s3_inst
.error
= _("missing +");
3864 s3_inst
.error
= _("missing ]");
3868 if (s3_end_of_line (str
) == (int) s3_FAIL
)
3871 /* lcw/lce/scb/sce rD, [rA]+. */
3874 if (((conflict_reg
= s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
)
3875 || (s3_skip_past_comma (&str
) == (int) s3_FAIL
))
3880 s3_skip_whitespace (str
);
3885 s3_skip_whitespace (str
);
3886 if ((reg
= s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
)
3891 /* Conflicts can occur on stores as well as loads. */
3892 conflict_reg
= (conflict_reg
== reg
);
3893 s3_skip_whitespace (str
);
3896 unsigned int ldst_func
= s3_inst
.instruction
& LDST_UNALIGN_MASK
;
3902 as_warn (_("%s register same as write-back base"),
3903 ((ldst_func
& UA_LCE
) || (ldst_func
& UA_LCW
)
3904 ? _("destination") : _("source")));
3909 s3_inst
.error
= _("missing +");
3913 if (s3_end_of_line (str
) == (int) s3_FAIL
)
3918 s3_inst
.error
= _("missing ]");
3924 s3_inst
.error
= s3_BAD_ARGS
;
3930 /* Handle alw/asw. */
3932 s3_do_ldst_atomic (char *str
)
3934 if (s3_university_version
== 1)
3936 s3_inst
.error
= s3_ERR_FOR_SCORE5U_ATOMIC
;
3940 s3_skip_whitespace (str
);
3942 if ((s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
)
3943 || (s3_skip_past_comma (&str
) == (int) s3_FAIL
))
3950 s3_skip_whitespace (str
);
3955 s3_skip_whitespace (str
);
3956 if ((reg
= s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
)
3961 s3_skip_whitespace (str
);
3964 s3_inst
.error
= _("missing ]");
3968 s3_end_of_line (str
);
3971 s3_inst
.error
= s3_BAD_ARGS
;
3976 s3_build_relax_frag (struct s3_score_it fix_insts
[s3_RELAX_INST_NUM
], int fix_num ATTRIBUTE_UNUSED
,
3977 struct s3_score_it var_insts
[s3_RELAX_INST_NUM
], int var_num
,
3978 symbolS
*add_symbol
)
3983 fixS
*cur_fixp
= NULL
;
3985 struct s3_score_it inst_main
;
3987 memcpy (&inst_main
, &fix_insts
[0], sizeof (struct s3_score_it
));
3989 /* Adjust instruction opcode and to be relaxed instruction opcode. */
3990 inst_main
.instruction
= s3_adjust_paritybit (inst_main
.instruction
, s3_GET_INSN_CLASS (inst_main
.type
));
3991 inst_main
.type
= Insn_PIC
;
3993 for (i
= 0; i
< var_num
; i
++)
3995 inst_main
.relax_size
+= var_insts
[i
].size
;
3996 var_insts
[i
].instruction
= s3_adjust_paritybit (var_insts
[i
].instruction
,
3997 s3_GET_INSN_CLASS (var_insts
[i
].type
));
4000 /* Check data dependency. */
4001 s3_handle_dependency (&inst_main
);
4003 /* Start a new frag if frag_now is not empty. */
4004 if (frag_now_fix () != 0)
4006 if (!frag_now
->tc_frag_data
.is_insn
)
4008 frag_wane (frag_now
);
4014 /* Write fr_fix part. */
4015 p
= frag_more (inst_main
.size
);
4016 s3_md_number_to_chars (p
, inst_main
.instruction
, inst_main
.size
);
4018 if (inst_main
.reloc
.type
!= BFD_RELOC_NONE
)
4019 fixp
= s3_fix_new_score (frag_now
, p
- frag_now
->fr_literal
, inst_main
.size
,
4020 &inst_main
.reloc
.exp
, inst_main
.reloc
.pc_rel
, inst_main
.reloc
.type
);
4022 frag_now
->tc_frag_data
.fixp
= fixp
;
4023 cur_fixp
= frag_now
->tc_frag_data
.fixp
;
4026 dwarf2_emit_insn (inst_main
.size
);
4029 where
= p
- frag_now
->fr_literal
+ inst_main
.size
;
4030 for (i
= 0; i
< var_num
; i
++)
4033 where
+= var_insts
[i
- 1].size
;
4035 if (var_insts
[i
].reloc
.type
!= BFD_RELOC_NONE
)
4037 fixp
= s3_fix_new_score (frag_now
, where
, var_insts
[i
].size
,
4038 &var_insts
[i
].reloc
.exp
, var_insts
[i
].reloc
.pc_rel
,
4039 var_insts
[i
].reloc
.type
);
4044 cur_fixp
->fx_next
= fixp
;
4045 cur_fixp
= cur_fixp
->fx_next
;
4049 frag_now
->tc_frag_data
.fixp
= fixp
;
4050 cur_fixp
= frag_now
->tc_frag_data
.fixp
;
4056 p
= frag_var (rs_machine_dependent
, inst_main
.relax_size
+ s3_RELAX_PAD_BYTE
, 0,
4057 s3_RELAX_ENCODE (inst_main
.size
, inst_main
.relax_size
, inst_main
.type
,
4058 0, inst_main
.size
, 0), add_symbol
, 0, NULL
);
4060 /* Write fr_var part.
4061 no calling s3_gen_insn_frag, no fixS will be generated. */
4062 for (i
= 0; i
< var_num
; i
++)
4064 s3_md_number_to_chars (p
, var_insts
[i
].instruction
, var_insts
[i
].size
);
4065 p
+= var_insts
[i
].size
;
4067 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4071 /* Build a relax frag for la instruction when generating s3_PIC,
4072 external symbol first and local symbol second. */
4074 s3_build_la_pic (int reg_rd
, expressionS exp
)
4076 symbolS
*add_symbol
= exp
.X_add_symbol
;
4077 offsetT add_number
= exp
.X_add_number
;
4078 struct s3_score_it fix_insts
[s3_RELAX_INST_NUM
];
4079 struct s3_score_it var_insts
[s3_RELAX_INST_NUM
];
4082 char tmp
[s3_MAX_LITERAL_POOL_SIZE
];
4088 if (add_number
== 0)
4093 /* For an external symbol, only one insn is generated;
4094 For a local symbol, two insns are generated. */
4096 For an external symbol: lw rD, <sym>($gp)
4097 (BFD_RELOC_SCORE_GOT15 or BFD_RELOC_SCORE_CALL15) */
4098 sprintf (tmp
, "lw_pic r%d, %s", reg_rd
, S_GET_NAME (add_symbol
));
4099 if (s3_append_insn (tmp
, FALSE
) == (int) s3_FAIL
)
4102 if (reg_rd
== s3_PIC_CALL_REG
)
4103 s3_inst
.reloc
.type
= BFD_RELOC_SCORE_CALL15
;
4104 memcpy (&fix_insts
[0], &s3_inst
, sizeof (struct s3_score_it
));
4107 For a local symbol :
4108 lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15)
4109 addi rD, <sym> (BFD_RELOC_GOT_LO16) */
4110 s3_inst
.reloc
.type
= BFD_RELOC_SCORE_GOT15
;
4111 memcpy (&var_insts
[0], &s3_inst
, sizeof (struct s3_score_it
));
4112 sprintf (tmp
, "addi_s_pic r%d, %s", reg_rd
, S_GET_NAME (add_symbol
));
4113 if (s3_append_insn (tmp
, FALSE
) == (int) s3_FAIL
)
4116 memcpy (&var_insts
[1], &s3_inst
, sizeof (struct s3_score_it
));
4117 s3_build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
4119 else if (add_number
>= -0x8000 && add_number
<= 0x7fff)
4121 /* Insn 1: lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15) */
4122 sprintf (tmp
, "lw_pic r%d, %s", reg_rd
, S_GET_NAME (add_symbol
));
4123 if (s3_append_insn (tmp
, TRUE
) == (int) s3_FAIL
)
4130 For an external symbol: addi rD, <constant> */
4131 sprintf (tmp
, "addi r%d, %d", reg_rd
, (int)add_number
);
4132 if (s3_append_insn (tmp
, FALSE
) == (int) s3_FAIL
)
4135 memcpy (&fix_insts
[0], &s3_inst
, sizeof (struct s3_score_it
));
4138 For a local symbol: addi rD, <sym>+<constant> (BFD_RELOC_GOT_LO16) */
4139 sprintf (tmp
, "addi_s_pic r%d, %s + %d", reg_rd
,
4140 S_GET_NAME (add_symbol
), (int) add_number
);
4141 if (s3_append_insn (tmp
, FALSE
) == (int) s3_FAIL
)
4144 memcpy (&var_insts
[0], &s3_inst
, sizeof (struct s3_score_it
));
4145 s3_build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
4149 int hi
= (add_number
>> 16) & 0x0000FFFF;
4150 int lo
= add_number
& 0x0000FFFF;
4152 /* Insn 1: lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15) */
4153 sprintf (tmp
, "lw_pic r%d, %s", reg_rd
, S_GET_NAME (add_symbol
));
4154 if (s3_append_insn (tmp
, TRUE
) == (int) s3_FAIL
)
4161 For an external symbol: ldis r1, HI%<constant> */
4162 sprintf (tmp
, "ldis r1, %d", hi
);
4163 if (s3_append_insn (tmp
, FALSE
) == (int) s3_FAIL
)
4166 memcpy (&fix_insts
[0], &s3_inst
, sizeof (struct s3_score_it
));
4169 For a local symbol: ldis r1, HI%<constant>
4170 but, if lo is out of 16 bit, make hi plus 1 */
4171 if ((lo
< -0x8000) || (lo
> 0x7fff))
4175 sprintf (tmp
, "ldis_pic r1, %d", hi
);
4176 if (s3_append_insn (tmp
, FALSE
) == (int) s3_FAIL
)
4179 memcpy (&var_insts
[0], &s3_inst
, sizeof (struct s3_score_it
));
4180 s3_build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
4186 For an external symbol: ori r1, LO%<constant> */
4187 sprintf (tmp
, "ori r1, %d", lo
);
4188 if (s3_append_insn (tmp
, FALSE
) == (int) s3_FAIL
)
4191 memcpy (&fix_insts
[0], &s3_inst
, sizeof (struct s3_score_it
));
4194 For a local symbol: addi r1, <sym>+LO%<constant> (BFD_RELOC_GOT_LO16) */
4195 sprintf (tmp
, "addi_u_pic r1, %s + %d", S_GET_NAME (add_symbol
), lo
);
4196 if (s3_append_insn (tmp
, FALSE
) == (int) s3_FAIL
)
4199 memcpy (&var_insts
[0], &s3_inst
, sizeof (struct s3_score_it
));
4200 s3_build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
4202 /* Insn 4: add rD, rD, r1 */
4203 sprintf (tmp
, "add r%d, r%d, r1", reg_rd
, reg_rd
);
4204 if (s3_append_insn (tmp
, TRUE
) == (int) s3_FAIL
)
4207 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4216 s3_do_macro_la_rdi32 (char *str
)
4220 s3_skip_whitespace (str
);
4221 if ((reg_rd
= s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
4222 || s3_skip_past_comma (&str
) == (int) s3_FAIL
)
4229 char *keep_data
= str
;
4230 char append_str
[s3_MAX_LITERAL_POOL_SIZE
];
4232 /* Check immediate value. */
4233 if (s3_my_get_expression (&s3_inst
.reloc
.exp
, &str
) == (int) s3_FAIL
)
4235 s3_inst
.error
= _("expression error");
4238 else if ((s3_inst
.reloc
.exp
.X_add_symbol
== NULL
)
4239 && (s3_validate_immediate (s3_inst
.reloc
.exp
.X_add_number
, _IMM32
, 0) == (int) s3_FAIL
))
4241 s3_inst
.error
= _("value not in range [0, 0xffffffff]");
4248 /* la rd, simm16. */
4249 if (s3_data_op2 (&str
, 1, _SIMM16_LA
) != (int) s3_FAIL
)
4251 s3_end_of_line (str
);
4254 /* la rd, imm32 or la rd, label. */
4257 s3_SET_INSN_ERROR (NULL
);
4260 if ((s3_data_op2 (&str
, 1, _VALUE_HI16
) == (int) s3_FAIL
)
4261 || (s3_end_of_line (str
) == (int) s3_FAIL
))
4267 if ((s3_score_pic
== s3_NO_PIC
) || (!s3_inst
.reloc
.exp
.X_add_symbol
))
4269 sprintf (append_str
, "ld_i32hi r%d, %s", reg_rd
, keep_data
);
4270 if (s3_append_insn (append_str
, TRUE
) == (int) s3_FAIL
)
4273 sprintf (append_str
, "ld_i32lo r%d, %s", reg_rd
, keep_data
);
4274 if (s3_append_insn (append_str
, TRUE
) == (int) s3_FAIL
)
4279 gas_assert (s3_inst
.reloc
.exp
.X_add_symbol
);
4280 s3_build_la_pic (reg_rd
, s3_inst
.reloc
.exp
);
4283 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4292 s3_do_macro_li_rdi32 (char *str
)
4297 s3_skip_whitespace (str
);
4298 if ((reg_rd
= s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
4299 || s3_skip_past_comma (&str
) == (int) s3_FAIL
)
4306 char *keep_data
= str
;
4308 /* Check immediate value. */
4309 if (s3_my_get_expression (&s3_inst
.reloc
.exp
, &str
) == (int) s3_FAIL
)
4311 s3_inst
.error
= _("expression error");
4314 else if (!(s3_inst
.reloc
.exp
.X_add_number
>= -0xffffffffLL
4315 && s3_inst
.reloc
.exp
.X_add_number
<= 0xffffffffLL
))
4317 s3_inst
.error
= _("value not in range [-0xffffffff, 0xffffffff]");
4324 /* li rd, simm16. */
4325 if (s3_data_op2 (&str
, 1, _SIMM16_LA
) != (int) s3_FAIL
)
4327 s3_end_of_line (str
);
4333 char append_str
[s3_MAX_LITERAL_POOL_SIZE
];
4338 if ((s3_data_op2 (&str
, 1, _VALUE_HI16
) == (int) s3_FAIL
)
4339 || (s3_end_of_line (str
) == (int) s3_FAIL
))
4343 else if (s3_inst
.reloc
.exp
.X_add_symbol
)
4345 s3_inst
.error
= _("li rd label isn't correct instruction form");
4350 sprintf (append_str
, "ld_i32hi r%d, %s", reg_rd
, keep_data
);
4352 if (s3_append_insn (append_str
, TRUE
) == (int) s3_FAIL
)
4356 sprintf (append_str
, "ld_i32lo r%d, %s", reg_rd
, keep_data
);
4357 if (s3_append_insn (append_str
, TRUE
) == (int) s3_FAIL
)
4360 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4368 /* Handle mul/mulu/div/divu/rem/remu. */
4370 s3_do_macro_mul_rdrsrs (char *str
)
4376 char append_str
[s3_MAX_LITERAL_POOL_SIZE
];
4378 if (s3_university_version
== 1)
4379 as_warn ("%s", s3_ERR_FOR_SCORE5U_MUL_DIV
);
4381 strcpy (append_str
, str
);
4382 backupstr
= append_str
;
4383 s3_skip_whitespace (backupstr
);
4384 if (((reg_rd
= s3_reg_required_here (&backupstr
, -1, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
)
4385 || (s3_skip_past_comma (&backupstr
) == (int) s3_FAIL
)
4386 || ((reg_rs1
= s3_reg_required_here (&backupstr
, -1, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
))
4388 s3_inst
.error
= s3_BAD_ARGS
;
4392 if (s3_skip_past_comma (&backupstr
) == (int) s3_FAIL
)
4394 /* rem/remu rA, rB is error format. */
4395 if (strcmp (s3_inst
.name
, "rem") == 0 || strcmp (s3_inst
.name
, "remu") == 0)
4397 s3_SET_INSN_ERROR (s3_BAD_ARGS
);
4401 s3_SET_INSN_ERROR (NULL
);
4408 s3_SET_INSN_ERROR (NULL
);
4409 if (((reg_rs2
= s3_reg_required_here (&backupstr
, -1, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
)
4410 || (s3_end_of_line (backupstr
) == (int) s3_FAIL
))
4416 char append_str1
[s3_MAX_LITERAL_POOL_SIZE
];
4418 if (strcmp (s3_inst
.name
, "rem") == 0)
4420 sprintf (append_str
, "mul r%d, r%d", reg_rs1
, reg_rs2
);
4421 sprintf (append_str1
, "mfceh r%d", reg_rd
);
4423 else if (strcmp (s3_inst
.name
, "remu") == 0)
4425 sprintf (append_str
, "mulu r%d, r%d", reg_rs1
, reg_rs2
);
4426 sprintf (append_str1
, "mfceh r%d", reg_rd
);
4430 sprintf (append_str
, "%s r%d, r%d", s3_inst
.name
, reg_rs1
, reg_rs2
);
4431 sprintf (append_str1
, "mfcel r%d", reg_rd
);
4434 /* Output mul/mulu or div/divu or rem/remu. */
4435 if (s3_append_insn (append_str
, TRUE
) == (int) s3_FAIL
)
4438 /* Output mfcel or mfceh. */
4439 if (s3_append_insn (append_str1
, TRUE
) == (int) s3_FAIL
)
4442 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4449 s3_exp_macro_ldst_abs (char *str
)
4452 char *backupstr
, *tmp
;
4453 char append_str
[s3_MAX_LITERAL_POOL_SIZE
];
4454 char verifystr
[s3_MAX_LITERAL_POOL_SIZE
];
4455 struct s3_score_it inst_backup
;
4460 memcpy (&inst_backup
, &s3_inst
, sizeof (struct s3_score_it
));
4462 strcpy (verifystr
, str
);
4463 backupstr
= verifystr
;
4464 s3_skip_whitespace (backupstr
);
4465 if ((reg_rd
= s3_reg_required_here (&backupstr
, -1, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
)
4469 if (s3_skip_past_comma (&backupstr
) == (int) s3_FAIL
)
4473 sprintf (append_str
, "li r1 %s", backupstr
);
4474 s3_append_insn (append_str
, TRUE
);
4476 memcpy (&s3_inst
, &inst_backup
, sizeof (struct s3_score_it
));
4477 sprintf (append_str
, " r%d, [r1,0]", reg_rd
);
4478 s3_do_ldst_insn (append_str
);
4483 /* Handle bcmpeq / bcmpne */
4485 s3_do_macro_bcmp (char *str
)
4489 size_t keep_data_size
;
4491 struct s3_score_it inst_expand
[2];
4492 struct s3_score_it inst_main
;
4494 memset (inst_expand
, 0, sizeof inst_expand
);
4495 s3_skip_whitespace (str
);
4496 if (( reg_a
= s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
4497 || s3_skip_past_comma (&str
) == (int) s3_FAIL
4498 ||(reg_b
= s3_reg_required_here (&str
, 10, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
4499 || s3_skip_past_comma (&str
) == (int) s3_FAIL
)
4502 keep_data_size
= strlen (str
) + 1;
4503 keep_data
= xmalloc (keep_data_size
* 2 + 14);
4504 memcpy (keep_data
, str
, keep_data_size
);
4506 if (s3_my_get_expression (&s3_inst
.reloc
.exp
, &str
) == (int) s3_FAIL
4508 || s3_end_of_line (str
) == (int) s3_FAIL
)
4510 else if (s3_inst
.reloc
.exp
.X_add_symbol
== 0)
4512 s3_inst
.error
= _("lacking label ");
4517 char *append_str
= keep_data
+ keep_data_size
;
4518 s3_SET_INSN_ERROR (NULL
);
4520 s3_inst
.reloc
.type
= BFD_RELOC_SCORE_BCMP
;
4521 s3_inst
.reloc
.pc_rel
= 1;
4522 bfd_signed_vma val
= s3_inst
.reloc
.exp
.X_add_number
;
4524 /* Branch 32 offset field : 20 bit, 16 bit branch offset field : 8 bit. */
4525 s3_inst
.instruction
|= ((s3_inst
.reloc
.exp
.X_add_number
>> 1) & 0x1)
4526 | ((s3_inst
.reloc
.exp
.X_add_number
>> 2) & 0x7) << 7
4527 | ((s3_inst
.reloc
.exp
.X_add_number
>> 5) & 0x1f) << 20;
4529 /* Check and set offset. */
4530 if (((val
& 0xfffffe00) != 0)
4531 && ((val
& 0xfffffe00) != 0xfffffe00))
4533 /* support bcmp --> cmp!+beq (bne) */
4534 if (s3_score_pic
== s3_NO_PIC
)
4536 sprintf (append_str
, "cmp! r%d, r%d", reg_a
, reg_b
);
4537 if (s3_append_insn (append_str
, TRUE
) == (int) s3_FAIL
)
4539 if ((inst_main
.instruction
& 0x3e00007e) == 0x0000004c)
4540 memcpy (append_str
, "beq ", 4);
4542 memcpy (append_str
, "bne ", 4);
4543 memmove (append_str
+ 4, keep_data
, strlen (keep_data
) + 1);
4544 if (s3_append_insn (append_str
, TRUE
) == (int) s3_FAIL
)
4549 gas_assert (s3_inst
.reloc
.exp
.X_add_symbol
);
4551 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4558 s3_inst
.instruction
|= (val
& 0x1)
4559 | (((val
>> 1) & 0x7) << 7)
4560 | (((val
>> 4) & 0x1f) << 20);
4563 /* Backup s3_inst. */
4564 memcpy (&inst_main
, &s3_inst
, sizeof (struct s3_score_it
));
4566 if (s3_score_pic
== s3_NO_PIC
)
4568 sprintf (append_str
, "cmp! r%d, r%d", reg_a
, reg_b
);
4569 if (s3_append_insn (append_str
, FALSE
) == (int) s3_FAIL
)
4571 memcpy (&inst_expand
[0], &s3_inst
, sizeof (struct s3_score_it
));
4573 if ((inst_main
.instruction
& 0x3e00007e) == 0x0000004c)
4574 memcpy (append_str
, "beq ", 4);
4576 memcpy (append_str
, "bne ", 4);
4577 memmove (append_str
+ 4, keep_data
, strlen (keep_data
) + 1);
4578 if (s3_append_insn (append_str
, FALSE
) == (int) s3_FAIL
)
4580 memcpy (&inst_expand
[1], &s3_inst
, sizeof (struct s3_score_it
));
4584 gas_assert (s3_inst
.reloc
.exp
.X_add_symbol
);
4586 inst_main
.relax_size
= inst_expand
[0].size
+ inst_expand
[1].size
;
4587 inst_main
.type
= Insn_BCMP
;
4589 /* Adjust instruction opcode and to be relaxed instruction opcode. */
4590 inst_main
.instruction
= s3_adjust_paritybit (inst_main
.instruction
, s3_GET_INSN_CLASS (inst_main
.type
));
4592 for (i
= 0; i
< 2; i
++)
4593 inst_expand
[i
].instruction
= s3_adjust_paritybit (inst_expand
[i
].instruction
,
4594 s3_GET_INSN_CLASS (inst_expand
[i
].type
));
4595 /* Check data dependency. */
4596 s3_handle_dependency (&inst_main
);
4597 /* Start a new frag if frag_now is not empty. */
4598 if (frag_now_fix () != 0)
4600 if (!frag_now
->tc_frag_data
.is_insn
)
4601 frag_wane (frag_now
);
4606 /* Write fr_fix part. */
4608 p
= frag_more (inst_main
.size
);
4609 s3_md_number_to_chars (p
, inst_main
.instruction
, inst_main
.size
);
4611 if (inst_main
.reloc
.type
!= BFD_RELOC_NONE
)
4613 s3_fix_new_score (frag_now
, p
- frag_now
->fr_literal
, inst_main
.size
,
4614 &inst_main
.reloc
.exp
, inst_main
.reloc
.pc_rel
, inst_main
.reloc
.type
);
4617 dwarf2_emit_insn (inst_main
.size
);
4620 /* s3_GP instruction can not do optimization, only can do relax between
4621 1 instruction and 3 instructions. */
4622 p
= frag_var (rs_machine_dependent
, inst_main
.relax_size
+ s3_RELAX_PAD_BYTE
, 0,
4623 s3_RELAX_ENCODE (inst_main
.size
, inst_main
.relax_size
, inst_main
.type
, 0, 4, 1),
4624 inst_main
.reloc
.exp
.X_add_symbol
, 0, NULL
);
4626 /* Write fr_var part.
4627 no calling s3_gen_insn_frag, no fixS will be generated. */
4628 s3_md_number_to_chars (p
, inst_expand
[0].instruction
, inst_expand
[0].size
);
4629 p
+= inst_expand
[0].size
;
4630 s3_md_number_to_chars (p
, inst_expand
[1].instruction
, inst_expand
[1].size
);
4631 p
+= inst_expand
[1].size
;
4633 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4640 /* Handle bcmpeqz / bcmpnez */
4642 s3_do_macro_bcmpz (char *str
)
4646 size_t keep_data_size
;
4648 struct s3_score_it inst_expand
[2];
4649 struct s3_score_it inst_main
;
4651 memset (inst_expand
, 0, sizeof inst_expand
);
4652 s3_skip_whitespace (str
);
4653 if (( reg_a
= s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
4654 || s3_skip_past_comma (&str
) == (int) s3_FAIL
)
4657 keep_data_size
= strlen (str
) + 1;
4658 keep_data
= xmalloc (keep_data_size
* 2 + 13);
4659 memcpy (keep_data
, str
, keep_data_size
);
4661 if (s3_my_get_expression (&s3_inst
.reloc
.exp
, &str
) == (int) s3_FAIL
4662 || s3_end_of_line (str
) == (int) s3_FAIL
)
4664 else if (s3_inst
.reloc
.exp
.X_add_symbol
== 0)
4666 s3_inst
.error
= _("lacking label ");
4671 char *append_str
= keep_data
+ keep_data_size
;
4672 s3_SET_INSN_ERROR (NULL
);
4673 s3_inst
.reloc
.type
= BFD_RELOC_SCORE_BCMP
;
4674 s3_inst
.reloc
.pc_rel
= 1;
4675 bfd_signed_vma val
= s3_inst
.reloc
.exp
.X_add_number
;
4677 /* Branch 32 offset field : 20 bit, 16 bit branch offset field : 8 bit. */
4678 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;
4680 /* Check and set offset. */
4681 if (((val
& 0xfffffe00) != 0)
4682 && ((val
& 0xfffffe00) != 0xfffffe00))
4684 if (s3_score_pic
== s3_NO_PIC
)
4686 sprintf (append_str
, "cmpi! r%d, 0", reg_a
);
4687 if (s3_append_insn (append_str
, TRUE
) == (int) s3_FAIL
)
4689 if ((inst_main
.instruction
& 0x3e00007e) == 0x0000004c)
4690 memcpy (append_str
, "beq ", 4);
4692 memcpy (append_str
, "bne ", 4);
4693 memmove (append_str
+ 4, keep_data
, strlen (keep_data
) + 1);
4694 if (s3_append_insn (append_str
, TRUE
) == (int) s3_FAIL
)
4699 gas_assert (s3_inst
.reloc
.exp
.X_add_symbol
);
4701 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4708 s3_inst
.instruction
|= (val
& 0x1)
4709 | (((val
>> 1) & 0x7) << 7)
4710 | (((val
>> 4) & 0x1f) << 20);
4713 /* Backup s3_inst. */
4714 memcpy (&inst_main
, &s3_inst
, sizeof (struct s3_score_it
));
4716 if (s3_score_pic
== s3_NO_PIC
)
4718 sprintf (append_str
, "cmpi! r%d, 0", reg_a
);
4719 if (s3_append_insn (append_str
, FALSE
) == (int) s3_FAIL
)
4721 memcpy (&inst_expand
[0], &s3_inst
, sizeof (struct s3_score_it
));
4722 if ((inst_main
.instruction
& 0x3e00007e) == 0x0000004c)
4723 memcpy (append_str
, "beq ", 4);
4725 memcpy (append_str
, "bne ", 4);
4726 memmove (append_str
+ 4, keep_data
, strlen (keep_data
) + 1);
4727 if (s3_append_insn (append_str
, FALSE
) == (int) s3_FAIL
)
4729 memcpy (&inst_expand
[1], &s3_inst
, sizeof (struct s3_score_it
));
4733 gas_assert (s3_inst
.reloc
.exp
.X_add_symbol
);
4735 inst_main
.relax_size
= inst_expand
[0].size
+ inst_expand
[1].size
;
4736 inst_main
.type
= Insn_BCMP
;
4738 /* Adjust instruction opcode and to be relaxed instruction opcode. */
4739 inst_main
.instruction
= s3_adjust_paritybit (inst_main
.instruction
, s3_GET_INSN_CLASS (inst_main
.type
));
4741 for (i
= 0; i
< 2; i
++)
4742 inst_expand
[i
].instruction
= s3_adjust_paritybit (inst_expand
[i
].instruction
,
4743 s3_GET_INSN_CLASS (inst_expand
[i
].type
));
4744 /* Check data dependency. */
4745 s3_handle_dependency (&inst_main
);
4746 /* Start a new frag if frag_now is not empty. */
4747 if (frag_now_fix () != 0)
4749 if (!frag_now
->tc_frag_data
.is_insn
)
4750 frag_wane (frag_now
);
4755 /* Write fr_fix part. */
4757 p
= frag_more (inst_main
.size
);
4758 s3_md_number_to_chars (p
, inst_main
.instruction
, inst_main
.size
);
4760 if (inst_main
.reloc
.type
!= BFD_RELOC_NONE
)
4762 s3_fix_new_score (frag_now
, p
- frag_now
->fr_literal
, inst_main
.size
,
4763 &inst_main
.reloc
.exp
, inst_main
.reloc
.pc_rel
, inst_main
.reloc
.type
);
4766 dwarf2_emit_insn (inst_main
.size
);
4769 /* s3_GP instruction can not do optimization, only can do relax between
4770 1 instruction and 3 instructions. */
4771 p
= frag_var (rs_machine_dependent
, inst_main
.relax_size
+ s3_RELAX_PAD_BYTE
, 0,
4772 s3_RELAX_ENCODE (inst_main
.size
, inst_main
.relax_size
, inst_main
.type
, 0, 4, 1),
4773 inst_main
.reloc
.exp
.X_add_symbol
, 0, NULL
);
4775 /* Write fr_var part.
4776 no calling s3_gen_insn_frag, no fixS will be generated. */
4777 s3_md_number_to_chars (p
, inst_expand
[0].instruction
, inst_expand
[0].size
);
4778 p
+= inst_expand
[0].size
;
4779 s3_md_number_to_chars (p
, inst_expand
[1].instruction
, inst_expand
[1].size
);
4780 p
+= inst_expand
[1].size
;
4782 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4790 s3_nopic_need_relax (symbolS
* sym
, int before_relaxing
)
4794 else if (s3_USE_GLOBAL_POINTER_OPT
&& s3_g_switch_value
> 0)
4796 const char *symname
;
4797 const char *segname
;
4799 /* Find out whether this symbol can be referenced off the $gp
4800 register. It can be if it is smaller than the -G size or if
4801 it is in the .sdata or .sbss section. Certain symbols can
4802 not be referenced off the $gp, although it appears as though
4804 symname
= S_GET_NAME (sym
);
4805 if (symname
!= (const char *)NULL
4806 && (strcmp (symname
, "eprol") == 0
4807 || strcmp (symname
, "etext") == 0
4808 || strcmp (symname
, "_gp") == 0
4809 || strcmp (symname
, "edata") == 0
4810 || strcmp (symname
, "_fbss") == 0
4811 || strcmp (symname
, "_fdata") == 0
4812 || strcmp (symname
, "_ftext") == 0
4813 || strcmp (symname
, "end") == 0
4814 || strcmp (symname
, GP_DISP_LABEL
) == 0))
4818 else if ((!S_IS_DEFINED (sym
) || S_IS_COMMON (sym
)) && (0
4819 /* We must defer this decision until after the whole file has been read,
4820 since there might be a .extern after the first use of this symbol. */
4822 && S_GET_VALUE (sym
) == 0)
4823 || (S_GET_VALUE (sym
) != 0
4824 && S_GET_VALUE (sym
) <= s3_g_switch_value
)))
4829 segname
= segment_name (S_GET_SEGMENT (sym
));
4830 return (strcmp (segname
, ".sdata") != 0
4831 && strcmp (segname
, ".sbss") != 0
4832 && strncmp (segname
, ".sdata.", 7) != 0
4833 && strncmp (segname
, ".gnu.linkonce.s.", 16) != 0);
4835 /* We are not optimizing for the $gp register. */
4840 /* Build a relax frag for lw/st instruction when generating s3_PIC,
4841 external symbol first and local symbol second. */
4843 s3_build_lwst_pic (int reg_rd
, expressionS exp
, const char *insn_name
)
4845 symbolS
*add_symbol
= exp
.X_add_symbol
;
4846 int add_number
= exp
.X_add_number
;
4847 struct s3_score_it fix_insts
[s3_RELAX_INST_NUM
];
4848 struct s3_score_it var_insts
[s3_RELAX_INST_NUM
];
4851 char tmp
[s3_MAX_LITERAL_POOL_SIZE
];
4857 if ((add_number
== 0) || (add_number
>= -0x8000 && add_number
<= 0x7fff))
4862 /* For an external symbol, two insns are generated;
4863 For a local symbol, three insns are generated. */
4865 For an external symbol: lw rD, <sym>($gp)
4866 (BFD_RELOC_SCORE_GOT15) */
4867 sprintf (tmp
, "lw_pic r1, %s", S_GET_NAME (add_symbol
));
4868 if (s3_append_insn (tmp
, FALSE
) == (int) s3_FAIL
)
4871 memcpy (&fix_insts
[0], &s3_inst
, sizeof (struct s3_score_it
));
4874 For a local symbol :
4875 lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15)
4876 addi rD, <sym> (BFD_RELOC_GOT_LO16) */
4877 s3_inst
.reloc
.type
= BFD_RELOC_SCORE_GOT15
;
4878 memcpy (&var_insts
[0], &s3_inst
, sizeof (struct s3_score_it
));
4879 sprintf (tmp
, "addi_s_pic r1, %s", S_GET_NAME (add_symbol
));
4880 if (s3_append_insn (tmp
, FALSE
) == (int) s3_FAIL
)
4883 memcpy (&var_insts
[1], &s3_inst
, sizeof (struct s3_score_it
));
4884 s3_build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
4886 /* Insn 2 or Insn 3: lw/st rD, [r1, constant] */
4887 sprintf (tmp
, "%s r%d, [r1, %d]", insn_name
, reg_rd
, add_number
);
4888 if (s3_append_insn (tmp
, TRUE
) == (int) s3_FAIL
)
4891 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4896 s3_inst
.error
= _("s3_PIC code offset overflow (max 16 signed bits)");
4904 s3_do_macro_ldst_label (char *str
)
4912 char *absolute_value
;
4913 char append_str
[3][s3_MAX_LITERAL_POOL_SIZE
];
4914 char verifystr
[s3_MAX_LITERAL_POOL_SIZE
];
4915 struct s3_score_it inst_backup
;
4916 struct s3_score_it inst_expand
[3];
4917 struct s3_score_it inst_main
;
4919 memcpy (&inst_backup
, &s3_inst
, sizeof (struct s3_score_it
));
4920 strcpy (verifystr
, str
);
4921 backup_str
= verifystr
;
4923 s3_skip_whitespace (backup_str
);
4924 if ((reg_rd
= s3_reg_required_here (&backup_str
, -1, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
)
4927 if (s3_skip_past_comma (&backup_str
) == (int) s3_FAIL
)
4930 label_str
= backup_str
;
4932 /* Ld/st rD, [rA, imm] ld/st rD, [rA]+, imm ld/st rD, [rA, imm]+. */
4933 if (*backup_str
== '[')
4935 s3_inst
.type
= Rd_rvalueRs_preSI12
;
4936 s3_do_ldst_insn (str
);
4940 /* Ld/st rD, imm. */
4941 absolute_value
= backup_str
;
4942 s3_inst
.type
= Rd_rvalueRs_SI15
;
4944 if (s3_my_get_expression (&s3_inst
.reloc
.exp
, &backup_str
) == (int) s3_FAIL
)
4946 s3_inst
.error
= _("expression error");
4949 else if ((s3_inst
.reloc
.exp
.X_add_symbol
== NULL
)
4950 && (s3_validate_immediate (s3_inst
.reloc
.exp
.X_add_number
, _VALUE
, 0) == (int) s3_FAIL
))
4952 s3_inst
.error
= _("value not in range [0, 0x7fffffff]");
4955 else if (s3_end_of_line (backup_str
) == (int) s3_FAIL
)
4957 s3_inst
.error
= _("end on line error");
4962 if (s3_inst
.reloc
.exp
.X_add_symbol
== 0)
4964 memcpy (&s3_inst
, &inst_backup
, sizeof (struct s3_score_it
));
4965 s3_exp_macro_ldst_abs (str
);
4970 /* Ld/st rD, label. */
4971 s3_inst
.type
= Rd_rvalueRs_SI15
;
4972 backup_str
= absolute_value
;
4973 if ((s3_data_op2 (&backup_str
, 1, _GP_IMM15
) == (int) s3_FAIL
)
4974 || (s3_end_of_line (backup_str
) == (int) s3_FAIL
))
4980 if (s3_inst
.reloc
.exp
.X_add_symbol
== 0)
4983 s3_inst
.error
= s3_BAD_ARGS
;
4988 if (s3_score_pic
== s3_PIC
)
4991 ldst_idx
= s3_inst
.instruction
& OPC_PSEUDOLDST_MASK
;
4992 s3_build_lwst_pic (reg_rd
, s3_inst
.reloc
.exp
,
4993 s3_score_ldst_insns
[ldst_idx
* 3 + 0].template_name
);
4998 if ((s3_inst
.reloc
.exp
.X_add_number
<= 0x3fff)
4999 && (s3_inst
.reloc
.exp
.X_add_number
>= -0x4000)
5000 && (!s3_nopic_need_relax (s3_inst
.reloc
.exp
.X_add_symbol
, 1)))
5004 /* Assign the real opcode. */
5005 ldst_idx
= s3_inst
.instruction
& OPC_PSEUDOLDST_MASK
;
5006 s3_inst
.instruction
&= ~OPC_PSEUDOLDST_MASK
;
5007 s3_inst
.instruction
|= s3_score_ldst_insns
[ldst_idx
* 3 + 0].value
;
5008 s3_inst
.instruction
|= reg_rd
<< 20;
5009 s3_inst
.instruction
|= s3_GP
<< 15;
5010 s3_inst
.relax_inst
= 0x8000;
5011 s3_inst
.relax_size
= 0;
5017 /* Backup s3_inst. */
5018 memcpy (&inst_main
, &s3_inst
, sizeof (struct s3_score_it
));
5022 /* Determine which instructions should be output. */
5023 sprintf (append_str
[0], "ld_i32hi r1, %s", label_str
);
5024 sprintf (append_str
[1], "ld_i32lo r1, %s", label_str
);
5025 sprintf (append_str
[2], "%s r%d, [r1, 0]", inst_backup
.name
, reg_rd
);
5027 /* Generate three instructions.
5029 ld/st rd, [r1, 0] */
5030 for (i
= 0; i
< 3; i
++)
5032 if (s3_append_insn (append_str
[i
], FALSE
) == (int) s3_FAIL
)
5035 memcpy (&inst_expand
[i
], &s3_inst
, sizeof (struct s3_score_it
));
5042 /* Adjust instruction opcode and to be relaxed instruction opcode. */
5043 inst_main
.instruction
= s3_adjust_paritybit (inst_main
.instruction
, s3_GET_INSN_CLASS (inst_main
.type
));
5045 /* relax lw rd, label -> ldis rs, imm16
5047 lw rd, [rs, imm15] or lw! rd, [rs, imm5]. */
5048 if (inst_expand
[2].relax_size
== 0)
5049 inst_main
.relax_size
= inst_expand
[0].size
+ inst_expand
[1].size
+ inst_expand
[2].size
;
5051 inst_main
.relax_size
= inst_expand
[0].size
+ inst_expand
[1].size
+ inst_expand
[2].relax_size
;
5053 inst_main
.type
= Insn_GP
;
5055 for (i
= 0; i
< 3; i
++)
5056 inst_expand
[i
].instruction
= s3_adjust_paritybit (inst_expand
[i
].instruction
,
5057 s3_GET_INSN_CLASS (inst_expand
[i
].type
));
5059 /* Check data dependency. */
5060 s3_handle_dependency (&inst_main
);
5062 /* Start a new frag if frag_now is not empty. */
5063 if (frag_now_fix () != 0)
5065 if (!frag_now
->tc_frag_data
.is_insn
)
5066 frag_wane (frag_now
);
5072 /* Write fr_fix part. */
5073 p
= frag_more (inst_main
.size
);
5074 s3_md_number_to_chars (p
, inst_main
.instruction
, inst_main
.size
);
5076 if (inst_main
.reloc
.type
!= BFD_RELOC_NONE
)
5078 s3_fix_new_score (frag_now
, p
- frag_now
->fr_literal
, inst_main
.size
,
5079 &inst_main
.reloc
.exp
, inst_main
.reloc
.pc_rel
, inst_main
.reloc
.type
);
5083 dwarf2_emit_insn (inst_main
.size
);
5086 /* s3_GP instruction can not do optimization, only can do relax between
5087 1 instruction and 3 instructions. */
5088 p
= frag_var (rs_machine_dependent
, inst_main
.relax_size
+ s3_RELAX_PAD_BYTE
, 0,
5089 s3_RELAX_ENCODE (inst_main
.size
, inst_main
.relax_size
, inst_main
.type
, 0, 4, 0),
5090 inst_main
.reloc
.exp
.X_add_symbol
, 0, NULL
);
5092 /* Write fr_var part.
5093 no calling s3_gen_insn_frag, no fixS will be generated. */
5094 s3_md_number_to_chars (p
, inst_expand
[0].instruction
, inst_expand
[0].size
);
5095 p
+= inst_expand
[0].size
;
5096 s3_md_number_to_chars (p
, inst_expand
[1].instruction
, inst_expand
[1].size
);
5097 p
+= inst_expand
[1].size
;
5099 /* relax lw rd, label -> ldis rs, imm16
5101 lw rd, [rs, imm15] or lw! rd, [rs, imm5]. */
5102 if (inst_expand
[2].relax_size
== 0)
5103 s3_md_number_to_chars (p
, inst_expand
[2].instruction
, inst_expand
[2].size
);
5105 s3_md_number_to_chars (p
, inst_expand
[2].relax_inst
, inst_expand
[2].relax_size
);
5109 s3_gen_insn_frag (&inst_expand
[0], NULL
);
5110 s3_gen_insn_frag (&inst_expand
[1], NULL
);
5111 s3_gen_insn_frag (&inst_expand
[2], NULL
);
5115 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
5120 s3_do_lw_pic (char *str
)
5124 s3_skip_whitespace (str
);
5125 if (((reg_rd
= s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
)
5126 || (s3_skip_past_comma (&str
) == (int) s3_FAIL
)
5127 || (s3_my_get_expression (&s3_inst
.reloc
.exp
, &str
) == (int) s3_FAIL
)
5128 || (s3_end_of_line (str
) == (int) s3_FAIL
))
5134 if (s3_inst
.reloc
.exp
.X_add_symbol
== 0)
5137 s3_inst
.error
= s3_BAD_ARGS
;
5142 s3_inst
.instruction
|= s3_GP
<< 15;
5143 s3_inst
.reloc
.type
= BFD_RELOC_SCORE_GOT15
;
5148 s3_do_empty (char *str
)
5151 if (s3_university_version
== 1)
5153 if (((s3_inst
.instruction
& 0x3e0003ff) == 0x0c000004)
5154 || ((s3_inst
.instruction
& 0x3e0003ff) == 0x0c000024)
5155 || ((s3_inst
.instruction
& 0x3e0003ff) == 0x0c000044)
5156 || ((s3_inst
.instruction
& 0x3e0003ff) == 0x0c000064))
5158 s3_inst
.error
= s3_ERR_FOR_SCORE5U_MMU
;
5162 if (s3_end_of_line (str
) == (int) s3_FAIL
)
5165 if (s3_inst
.relax_inst
!= 0x8000)
5167 if (s3_inst
.type
== NO_OPD
)
5169 s3_inst
.relax_size
= 2;
5173 s3_inst
.relax_size
= 4;
5179 s3_do16_int (char *str
)
5181 s3_skip_whitespace (str
);
5186 s3_do_jump (char *str
)
5190 s3_skip_whitespace (str
);
5191 if (s3_my_get_expression (&s3_inst
.reloc
.exp
, &str
) == (int) s3_FAIL
5192 || s3_end_of_line (str
) == (int) s3_FAIL
)
5195 if (s3_inst
.reloc
.exp
.X_add_symbol
== 0)
5197 s3_inst
.error
= _("lacking label ");
5201 if (!(s3_inst
.reloc
.exp
.X_add_number
>= -16777216
5202 && s3_inst
.reloc
.exp
.X_add_number
<= 16777215))
5204 s3_inst
.error
= _("invalid constant: 25 bit expression not in range [-16777216, 16777215]");
5208 save_in
= input_line_pointer
;
5209 input_line_pointer
= str
;
5210 s3_inst
.reloc
.type
= BFD_RELOC_SCORE_JMP
;
5211 s3_inst
.reloc
.pc_rel
= 1;
5212 input_line_pointer
= save_in
;
5216 s3_do_branch (char *str
)
5218 if (s3_my_get_expression (&s3_inst
.reloc
.exp
, &str
) == (int) s3_FAIL
5219 || s3_end_of_line (str
) == (int) s3_FAIL
)
5223 else if (s3_inst
.reloc
.exp
.X_add_symbol
== 0)
5225 s3_inst
.error
= _("lacking label ");
5228 else if (!(s3_inst
.reloc
.exp
.X_add_number
>= -524288
5229 && s3_inst
.reloc
.exp
.X_add_number
<= 524287))
5231 s3_inst
.error
= _("invalid constant: 20 bit expression not in range -2^19..2^19-1");
5235 s3_inst
.reloc
.type
= BFD_RELOC_SCORE_BRANCH
;
5236 s3_inst
.reloc
.pc_rel
= 1;
5238 /* Branch 32 offset field : 20 bit, 16 bit branch offset field : 8 bit. */
5239 s3_inst
.instruction
|= (s3_inst
.reloc
.exp
.X_add_number
& 0x3fe) | ((s3_inst
.reloc
.exp
.X_add_number
& 0xffc00) << 5);
5241 /* Compute 16 bit branch instruction. */
5242 if ((s3_inst
.relax_inst
!= 0x8000)
5243 && (s3_inst
.reloc
.exp
.X_add_number
>= -512 && s3_inst
.reloc
.exp
.X_add_number
<= 511))
5245 s3_inst
.relax_inst
|= ((s3_inst
.reloc
.exp
.X_add_number
>> 1) & 0x1ff);/*b! :disp 9 bit */
5246 s3_inst
.relax_size
= 2;
5250 s3_inst
.relax_inst
= 0x8000;
5255 s3_do16_branch (char *str
)
5257 if ((s3_my_get_expression (&s3_inst
.reloc
.exp
, &str
) == (int) s3_FAIL
5258 || s3_end_of_line (str
) == (int) s3_FAIL
))
5262 else if (s3_inst
.reloc
.exp
.X_add_symbol
== 0)
5264 s3_inst
.error
= _("lacking label");
5266 else if (!(s3_inst
.reloc
.exp
.X_add_number
>= -512
5267 && s3_inst
.reloc
.exp
.X_add_number
<= 511))
5269 s3_inst
.error
= _("invalid constant: 10 bit expression not in range [-2^9, 2^9-1]");
5273 s3_inst
.reloc
.type
= BFD_RELOC_SCORE16_BRANCH
;
5274 s3_inst
.reloc
.pc_rel
= 1;
5275 s3_inst
.instruction
|= ((s3_inst
.reloc
.exp
.X_add_number
>> 1) & 0x1ff);
5276 s3_inst
.relax_inst
|= ((s3_inst
.reloc
.exp
.X_add_number
) & 0x1ff);
5277 s3_inst
.relax_size
= 4;
5281 /* Return true if the given symbol should be considered local for s3_PIC. */
5283 s3_pic_need_relax (symbolS
*sym
, asection
*segtype
)
5286 bfd_boolean linkonce
;
5288 /* Handle the case of a symbol equated to another symbol. */
5289 while (symbol_equated_reloc_p (sym
))
5293 /* It's possible to get a loop here in a badly written
5295 n
= symbol_get_value_expression (sym
)->X_add_symbol
;
5301 symsec
= S_GET_SEGMENT (sym
);
5303 /* duplicate the test for LINK_ONCE sections as in adjust_reloc_syms */
5305 if (symsec
!= segtype
&& ! S_IS_LOCAL (sym
))
5307 if ((bfd_section_flags (symsec
) & SEC_LINK_ONCE
) != 0)
5310 /* The GNU toolchain uses an extension for ELF: a section
5311 beginning with the magic string .gnu.linkonce is a linkonce
5313 if (strncmp (segment_name (symsec
), ".gnu.linkonce",
5314 sizeof ".gnu.linkonce" - 1) == 0)
5318 /* This must duplicate the test in adjust_reloc_syms. */
5319 return (!bfd_is_und_section (symsec
)
5320 && !bfd_is_abs_section (symsec
)
5321 && !bfd_is_com_section (symsec
)
5324 /* A global or weak symbol is treated as external. */
5325 && (OUTPUT_FLAVOR
!= bfd_target_elf_flavour
5326 || (! S_IS_WEAK (sym
) && ! S_IS_EXTERNAL (sym
)))
5332 s3_parse_pce_inst (char *insnstr
)
5336 char first
[s3_MAX_LITERAL_POOL_SIZE
];
5337 char second
[s3_MAX_LITERAL_POOL_SIZE
];
5338 struct s3_score_it pec_part_1
;
5340 /* Get first part string of PCE. */
5341 p
= strstr (insnstr
, "||");
5344 sprintf (first
, "%s", insnstr
);
5346 /* Get second part string of PCE. */
5349 sprintf (second
, "%s", p
);
5351 s3_parse_16_32_inst (first
, FALSE
);
5355 memcpy (&pec_part_1
, &s3_inst
, sizeof (s3_inst
));
5357 s3_parse_16_32_inst (second
, FALSE
);
5361 if ( ((pec_part_1
.size
== s3_INSN_SIZE
) && (s3_inst
.size
== s3_INSN_SIZE
))
5362 || ((pec_part_1
.size
== s3_INSN_SIZE
) && (s3_inst
.size
== s3_INSN16_SIZE
))
5363 || ((pec_part_1
.size
== s3_INSN16_SIZE
) && (s3_inst
.size
== s3_INSN_SIZE
)))
5365 s3_inst
.error
= _("pce instruction error (16 bit || 16 bit).");
5366 sprintf (s3_inst
.str
, "%s", insnstr
);
5371 s3_gen_insn_frag (&pec_part_1
, &s3_inst
);
5376 s3_do16_dsp (char *str
)
5381 if (s3_score3d
== 0)
5383 s3_inst
.error
= _("score3d instruction.");
5387 s3_skip_whitespace (str
);
5389 if ((rd
= s3_reglow_required_here (&str
, 0)) == (int) s3_FAIL
5390 || s3_end_of_line (str
) == (int) s3_FAIL
)
5396 s3_inst
.relax_inst
|= rd
<< 20;
5397 s3_inst
.relax_size
= 4;
5402 s3_do16_dsp2 (char *str
)
5405 if (s3_score3d
== 0)
5407 s3_inst
.error
= _("score3d instruction.");
5411 s3_skip_whitespace (str
);
5413 if (s3_reglow_required_here (&str
, 4) == (int) s3_FAIL
5414 || s3_skip_past_comma (&str
) == (int) s3_FAIL
5415 || s3_reglow_required_here (&str
, 0) == (int) s3_FAIL
5416 || s3_end_of_line (str
) == (int) s3_FAIL
)
5422 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>> 8) & 0xf) << 20)
5423 | (((s3_inst
.instruction
>> 8) & 0xf) << 15) | (((s3_inst
.instruction
>> 4) & 0xf) << 10);
5424 s3_inst
.relax_size
= 4;
5429 s3_do_dsp (char *str
)
5432 if (s3_score3d
== 0)
5434 s3_inst
.error
= _("score3d instruction.");
5438 s3_skip_whitespace (str
);
5440 if (s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
5441 || s3_skip_past_comma (&str
) == (int) s3_FAIL
5442 || s3_reg_required_here (&str
, 10, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
5443 || s3_end_of_line (str
) == (int) s3_FAIL
)
5446 if ((s3_inst
.relax_inst
!= 0x8000) && (((s3_inst
.instruction
>> 20) & 0x1f) == 3) )
5448 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>> 10) & 0x1f)) | (((s3_inst
.instruction
>> 15) & 0x1f) << 5);
5449 s3_inst
.relax_size
= 2;
5452 s3_inst
.relax_inst
= 0x8000;
5456 s3_do_dsp2 (char *str
)
5461 if (s3_score3d
== 0)
5463 s3_inst
.error
= _("score3d instruction.");
5467 s3_skip_whitespace (str
);
5469 if ((reg
= s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
5470 || s3_skip_past_comma (&str
) == (int) s3_FAIL
5471 || s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
5472 || s3_skip_past_comma (&str
) == (int) s3_FAIL
5473 || s3_reg_required_here (&str
, 10, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
5474 || s3_end_of_line (str
) == (int) s3_FAIL
)
5480 /* Check mulr, mulur rd is even number. */
5481 if (((s3_inst
.instruction
& 0x3e0003ff) == 0x00000340
5482 || (s3_inst
.instruction
& 0x3e0003ff) == 0x00000342)
5485 s3_inst
.error
= _("rd must be even number.");
5489 if ((((s3_inst
.instruction
>> 15) & 0x10) == 0)
5490 && (((s3_inst
.instruction
>> 10) & 0x10) == 0)
5491 && (((s3_inst
.instruction
>> 20) & 0x10) == 0)
5492 && (s3_inst
.relax_inst
!= 0x8000)
5493 && (((s3_inst
.instruction
>> 20) & 0xf) == ((s3_inst
.instruction
>> 15) & 0xf)))
5495 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>> 10) & 0xf) )
5496 | (((s3_inst
.instruction
>> 15) & 0xf) << 4);
5497 s3_inst
.relax_size
= 2;
5501 s3_inst
.relax_inst
= 0x8000;
5507 s3_do_dsp3 (char *str
)
5510 if (s3_score3d
== 0)
5512 s3_inst
.error
= _("score3d instruction.");
5516 s3_skip_whitespace (str
);
5518 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
5519 || s3_skip_past_comma (&str
) == (int) s3_FAIL
5520 || s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
5521 || s3_end_of_line (str
) == (int) s3_FAIL
)
5524 if ((s3_inst
.relax_inst
!= 0x8000) && (((s3_inst
.instruction
>> 20) & 0x1f) == 3) )
5526 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>> 10) & 0x1f)) | (((s3_inst
.instruction
>> 15) & 0x1f) << 5);
5527 s3_inst
.relax_size
= 2;
5530 s3_inst
.relax_inst
= 0x8000;
5534 /* If we change section we must dump the literal pool first. */
5536 s3_s_score_bss (int ignore ATTRIBUTE_UNUSED
)
5538 subseg_set (bss_section
, (subsegT
) get_absolute_expression ());
5539 demand_empty_rest_of_line ();
5543 s3_s_score_text (int ignore
)
5545 obj_elf_text (ignore
);
5546 record_alignment (now_seg
, 2);
5550 s3_score_s_section (int ignore
)
5552 obj_elf_section (ignore
);
5553 if ((bfd_section_flags (now_seg
) & SEC_CODE
) != 0)
5554 record_alignment (now_seg
, 2);
5559 s3_s_change_sec (int sec
)
5564 /* The ELF backend needs to know that we are changing sections, so
5565 that .previous works correctly. We could do something like check
5566 for an obj_section_change_hook macro, but that might be confusing
5567 as it would not be appropriate to use it in the section changing
5568 functions in read.c, since obj-elf.c intercepts those. FIXME:
5569 This should be cleaner, somehow. */
5570 obj_elf_section_change_hook ();
5575 seg
= subseg_new (s3_RDATA_SECTION_NAME
, (subsegT
) get_absolute_expression ());
5576 bfd_set_section_flags (seg
, (SEC_ALLOC
| SEC_LOAD
| SEC_READONLY
5577 | SEC_RELOC
| SEC_DATA
));
5578 if (strcmp (TARGET_OS
, "elf") != 0)
5579 record_alignment (seg
, 4);
5580 demand_empty_rest_of_line ();
5583 seg
= subseg_new (".sdata", (subsegT
) get_absolute_expression ());
5584 bfd_set_section_flags (seg
, (SEC_ALLOC
| SEC_LOAD
| SEC_RELOC
5585 | SEC_DATA
| SEC_SMALL_DATA
));
5586 if (strcmp (TARGET_OS
, "elf") != 0)
5587 record_alignment (seg
, 4);
5588 demand_empty_rest_of_line ();
5594 s3_s_score_mask (int reg_type ATTRIBUTE_UNUSED
)
5598 if (s3_cur_proc_ptr
== (s3_procS
*) NULL
)
5600 as_warn (_(".mask outside of .ent"));
5601 demand_empty_rest_of_line ();
5604 if (get_absolute_expression_and_terminator (&mask
) != ',')
5606 as_warn (_("Bad .mask directive"));
5607 --input_line_pointer
;
5608 demand_empty_rest_of_line ();
5611 off
= get_absolute_expression ();
5612 s3_cur_proc_ptr
->reg_mask
= mask
;
5613 s3_cur_proc_ptr
->reg_offset
= off
;
5614 demand_empty_rest_of_line ();
5618 s3_get_symbol (void)
5624 c
= get_symbol_name (&name
);
5625 p
= (symbolS
*) symbol_find_or_make (name
);
5626 (void) restore_line_pointer (c
);
5631 s3_get_number (void)
5636 if (*input_line_pointer
== '-')
5638 ++input_line_pointer
;
5641 if (!ISDIGIT (*input_line_pointer
))
5642 as_bad (_("expected simple number"));
5643 if (input_line_pointer
[0] == '0')
5645 if (input_line_pointer
[1] == 'x')
5647 input_line_pointer
+= 2;
5648 while (ISXDIGIT (*input_line_pointer
))
5651 val
|= hex_value (*input_line_pointer
++);
5653 return negative
? -val
: val
;
5657 ++input_line_pointer
;
5658 while (ISDIGIT (*input_line_pointer
))
5661 val
|= *input_line_pointer
++ - '0';
5663 return negative
? -val
: val
;
5666 if (!ISDIGIT (*input_line_pointer
))
5668 printf (_(" *input_line_pointer == '%c' 0x%02x\n"), *input_line_pointer
, *input_line_pointer
);
5669 as_warn (_("invalid number"));
5672 while (ISDIGIT (*input_line_pointer
))
5675 val
+= *input_line_pointer
++ - '0';
5677 return negative
? -val
: val
;
5680 /* The .aent and .ent directives. */
5682 s3_s_score_ent (int aent
)
5687 symbolP
= s3_get_symbol ();
5688 if (*input_line_pointer
== ',')
5689 ++input_line_pointer
;
5691 if (ISDIGIT (*input_line_pointer
) || *input_line_pointer
== '-')
5694 if ((bfd_section_flags (now_seg
) & SEC_CODE
) != 0)
5699 as_warn (_(".ent or .aent not in text section."));
5700 if (!aent
&& s3_cur_proc_ptr
)
5701 as_warn (_("missing .end"));
5704 s3_cur_proc_ptr
= &s3_cur_proc
;
5705 s3_cur_proc_ptr
->reg_mask
= 0xdeadbeaf;
5706 s3_cur_proc_ptr
->reg_offset
= 0xdeadbeaf;
5707 s3_cur_proc_ptr
->fpreg_mask
= 0xdeafbeaf;
5708 s3_cur_proc_ptr
->leaf
= 0xdeafbeaf;
5709 s3_cur_proc_ptr
->frame_offset
= 0xdeafbeaf;
5710 s3_cur_proc_ptr
->frame_reg
= 0xdeafbeaf;
5711 s3_cur_proc_ptr
->pc_reg
= 0xdeafbeaf;
5712 s3_cur_proc_ptr
->isym
= symbolP
;
5713 symbol_get_bfdsym (symbolP
)->flags
|= BSF_FUNCTION
;
5715 if (debug_type
== DEBUG_STABS
)
5716 stabs_generate_asm_func (S_GET_NAME (symbolP
), S_GET_NAME (symbolP
));
5718 demand_empty_rest_of_line ();
5722 s3_s_score_frame (int ignore ATTRIBUTE_UNUSED
)
5729 backupstr
= input_line_pointer
;
5732 if (s3_cur_proc_ptr
== (s3_procS
*) NULL
)
5734 as_warn (_(".frame outside of .ent"));
5735 demand_empty_rest_of_line ();
5738 s3_cur_proc_ptr
->frame_reg
= s3_reg_required_here ((&backupstr
), 0, s3_REG_TYPE_SCORE
);
5740 s3_skip_past_comma (&backupstr
);
5741 while (*backupstr
!= ',')
5743 str
[i
] = *backupstr
;
5751 s3_skip_past_comma (&backupstr
);
5752 s3_cur_proc_ptr
->frame_offset
= val
;
5753 s3_cur_proc_ptr
->pc_reg
= s3_reg_required_here ((&backupstr
), 0, s3_REG_TYPE_SCORE
);
5756 s3_skip_past_comma (&backupstr
);
5758 while (*backupstr
!= '\n')
5760 str
[i
] = *backupstr
;
5766 s3_cur_proc_ptr
->leaf
= val
;
5768 s3_skip_past_comma (&backupstr
);
5770 #endif /* OBJ_ELF */
5771 while (input_line_pointer
!= backupstr
)
5772 input_line_pointer
++;
5775 /* The .end directive. */
5777 s3_s_score_end (int x ATTRIBUTE_UNUSED
)
5782 /* Generate a .pdr section. */
5783 segT saved_seg
= now_seg
;
5784 subsegT saved_subseg
= now_subseg
;
5788 if (!is_end_of_line
[(unsigned char)*input_line_pointer
])
5790 p
= s3_get_symbol ();
5791 demand_empty_rest_of_line ();
5796 if ((bfd_section_flags (now_seg
) & SEC_CODE
) != 0)
5802 as_warn (_(".end not in text section"));
5803 if (!s3_cur_proc_ptr
)
5805 as_warn (_(".end directive without a preceding .ent directive."));
5806 demand_empty_rest_of_line ();
5811 gas_assert (S_GET_NAME (p
));
5812 if (strcmp (S_GET_NAME (p
), S_GET_NAME (s3_cur_proc_ptr
->isym
)))
5813 as_warn (_(".end symbol does not match .ent symbol."));
5814 if (debug_type
== DEBUG_STABS
)
5815 stabs_generate_asm_endfunc (S_GET_NAME (p
), S_GET_NAME (p
));
5818 as_warn (_(".end directive missing or unknown symbol"));
5820 if ((s3_cur_proc_ptr
->reg_mask
== 0xdeadbeaf) ||
5821 (s3_cur_proc_ptr
->reg_offset
== 0xdeadbeaf) ||
5822 (s3_cur_proc_ptr
->leaf
== 0xdeafbeaf) ||
5823 (s3_cur_proc_ptr
->frame_offset
== 0xdeafbeaf) ||
5824 (s3_cur_proc_ptr
->frame_reg
== 0xdeafbeaf) || (s3_cur_proc_ptr
->pc_reg
== 0xdeafbeaf));
5828 (void) frag_now_fix ();
5829 gas_assert (s3_pdr_seg
);
5830 subseg_set (s3_pdr_seg
, 0);
5831 /* Write the symbol. */
5832 exp
.X_op
= O_symbol
;
5833 exp
.X_add_symbol
= p
;
5834 exp
.X_add_number
= 0;
5835 emit_expr (&exp
, 4);
5836 fragp
= frag_more (7 * 4);
5837 md_number_to_chars (fragp
, (valueT
) s3_cur_proc_ptr
->reg_mask
, 4);
5838 md_number_to_chars (fragp
+ 4, (valueT
) s3_cur_proc_ptr
->reg_offset
, 4);
5839 md_number_to_chars (fragp
+ 8, (valueT
) s3_cur_proc_ptr
->fpreg_mask
, 4);
5840 md_number_to_chars (fragp
+ 12, (valueT
) s3_cur_proc_ptr
->leaf
, 4);
5841 md_number_to_chars (fragp
+ 16, (valueT
) s3_cur_proc_ptr
->frame_offset
, 4);
5842 md_number_to_chars (fragp
+ 20, (valueT
) s3_cur_proc_ptr
->frame_reg
, 4);
5843 md_number_to_chars (fragp
+ 24, (valueT
) s3_cur_proc_ptr
->pc_reg
, 4);
5844 subseg_set (saved_seg
, saved_subseg
);
5847 s3_cur_proc_ptr
= NULL
;
5850 /* Handle the .set pseudo-op. */
5852 s3_s_score_set (int x ATTRIBUTE_UNUSED
)
5855 char name
[s3_MAX_LITERAL_POOL_SIZE
];
5856 char * orig_ilp
= input_line_pointer
;
5858 while (!is_end_of_line
[(unsigned char)*input_line_pointer
])
5860 name
[i
] = (char) * input_line_pointer
;
5862 ++input_line_pointer
;
5867 if (strcmp (name
, "nwarn") == 0)
5869 s3_warn_fix_data_dependency
= 0;
5871 else if (strcmp (name
, "fixdd") == 0)
5873 s3_fix_data_dependency
= 1;
5875 else if (strcmp (name
, "nofixdd") == 0)
5877 s3_fix_data_dependency
= 0;
5879 else if (strcmp (name
, "r1") == 0)
5883 else if (strcmp (name
, "nor1") == 0)
5887 else if (strcmp (name
, "optimize") == 0)
5891 else if (strcmp (name
, "volatile") == 0)
5895 else if (strcmp (name
, "pic") == 0)
5897 s3_score_pic
= s3_PIC
;
5901 input_line_pointer
= orig_ilp
;
5906 /* Handle the .cpload pseudo-op. This is used when generating s3_PIC code. It sets the
5907 $gp register for the function based on the function address, which is in the register
5908 named in the argument. This uses a relocation against GP_DISP_LABEL, which is handled
5909 specially by the linker. The result is:
5910 ldis gp, %hi(GP_DISP_LABEL)
5911 ori gp, %low(GP_DISP_LABEL)
5912 add gp, gp, .cpload argument
5913 The .cpload argument is normally r29. */
5915 s3_s_score_cpload (int ignore ATTRIBUTE_UNUSED
)
5918 char insn_str
[s3_MAX_LITERAL_POOL_SIZE
];
5920 /* If we are not generating s3_PIC code, .cpload is ignored. */
5921 if (s3_score_pic
== s3_NO_PIC
)
5927 if ((reg
= s3_reg_required_here (&input_line_pointer
, -1, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
)
5930 demand_empty_rest_of_line ();
5932 sprintf (insn_str
, "ld_i32hi r%d, %s", s3_GP
, GP_DISP_LABEL
);
5933 if (s3_append_insn (insn_str
, TRUE
) == (int) s3_FAIL
)
5936 sprintf (insn_str
, "ld_i32lo r%d, %s", s3_GP
, GP_DISP_LABEL
);
5937 if (s3_append_insn (insn_str
, TRUE
) == (int) s3_FAIL
)
5940 sprintf (insn_str
, "add r%d, r%d, r%d", s3_GP
, s3_GP
, reg
);
5941 if (s3_append_insn (insn_str
, TRUE
) == (int) s3_FAIL
)
5945 /* Handle the .cprestore pseudo-op. This stores $gp into a given
5946 offset from $sp. The offset is remembered, and after making a s3_PIC
5947 call $gp is restored from that location. */
5949 s3_s_score_cprestore (int ignore ATTRIBUTE_UNUSED
)
5952 int cprestore_offset
;
5953 char insn_str
[s3_MAX_LITERAL_POOL_SIZE
];
5955 /* If we are not generating s3_PIC code, .cprestore is ignored. */
5956 if (s3_score_pic
== s3_NO_PIC
)
5962 if ((reg
= s3_reg_required_here (&input_line_pointer
, -1, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
5963 || s3_skip_past_comma (&input_line_pointer
) == (int) s3_FAIL
)
5968 cprestore_offset
= get_absolute_expression ();
5970 if (cprestore_offset
<= 0x3fff)
5972 sprintf (insn_str
, "sw r%d, [r%d, %d]", s3_GP
, reg
, cprestore_offset
);
5973 if (s3_append_insn (insn_str
, TRUE
) == (int) s3_FAIL
)
5983 sprintf (insn_str
, "li r1, %d", cprestore_offset
);
5984 if (s3_append_insn (insn_str
, TRUE
) == (int) s3_FAIL
)
5987 sprintf (insn_str
, "add r1, r1, r%d", reg
);
5988 if (s3_append_insn (insn_str
, TRUE
) == (int) s3_FAIL
)
5991 sprintf (insn_str
, "sw r%d, [r1]", s3_GP
);
5992 if (s3_append_insn (insn_str
, TRUE
) == (int) s3_FAIL
)
5998 demand_empty_rest_of_line ();
6001 /* Handle the .gpword pseudo-op. This is used when generating s3_PIC
6002 code. It generates a 32 bit s3_GP relative reloc. */
6004 s3_s_score_gpword (int ignore ATTRIBUTE_UNUSED
)
6009 /* When not generating s3_PIC code, this is treated as .word. */
6010 if (s3_score_pic
== s3_NO_PIC
)
6016 if (ex
.X_op
!= O_symbol
|| ex
.X_add_number
!= 0)
6018 as_bad (_("Unsupported use of .gpword"));
6019 ignore_rest_of_line ();
6022 s3_md_number_to_chars (p
, (valueT
) 0, 4);
6023 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 4, &ex
, FALSE
, BFD_RELOC_GPREL32
);
6024 demand_empty_rest_of_line ();
6027 /* Handle the .cpadd pseudo-op. This is used when dealing with switch
6028 tables in s3_PIC code. */
6030 s3_s_score_cpadd (int ignore ATTRIBUTE_UNUSED
)
6033 char insn_str
[s3_MAX_LITERAL_POOL_SIZE
];
6035 /* If we are not generating s3_PIC code, .cpload is ignored. */
6036 if (s3_score_pic
== s3_NO_PIC
)
6042 if ((reg
= s3_reg_required_here (&input_line_pointer
, -1, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
)
6046 demand_empty_rest_of_line ();
6048 /* Add $gp to the register named as an argument. */
6049 sprintf (insn_str
, "add r%d, r%d, r%d", reg
, reg
, s3_GP
);
6050 if (s3_append_insn (insn_str
, TRUE
) == (int) s3_FAIL
)
6054 #ifndef TC_IMPLICIT_LCOMM_ALIGNMENT
6055 #define TC_IMPLICIT_LCOMM_ALIGNMENT(SIZE, P2VAR) \
6060 else if ((SIZE) >= 4) \
6062 else if ((SIZE) >= 2) \
6071 s3_s_score_lcomm (int bytes_p
)
6078 segT current_seg
= now_seg
;
6079 subsegT current_subseg
= now_subseg
;
6080 const int max_alignment
= 15;
6082 segT bss_seg
= bss_section
;
6083 int needs_align
= 0;
6085 c
= get_symbol_name (&name
);
6086 p
= input_line_pointer
;
6087 (void) restore_line_pointer (c
);
6091 as_bad (_("expected symbol name"));
6092 discard_rest_of_line ();
6098 /* Accept an optional comma after the name. The comma used to be
6099 required, but Irix 5 cc does not generate it. */
6100 if (*input_line_pointer
== ',')
6102 ++input_line_pointer
;
6106 if (is_end_of_line
[(unsigned char)*input_line_pointer
])
6108 as_bad (_("missing size expression"));
6112 if ((temp
= get_absolute_expression ()) < 0)
6114 as_warn (_("BSS length (%d) < 0 ignored"), temp
);
6115 ignore_rest_of_line ();
6119 #if defined (TC_SCORE)
6120 if (OUTPUT_FLAVOR
== bfd_target_ecoff_flavour
|| OUTPUT_FLAVOR
== bfd_target_elf_flavour
)
6122 /* For Score and Alpha ECOFF or ELF, small objects are put in .sbss. */
6123 if ((unsigned) temp
<= bfd_get_gp_size (stdoutput
))
6125 bss_seg
= subseg_new (".sbss", 1);
6126 seg_info (bss_seg
)->bss
= 1;
6127 if (!bfd_set_section_flags (bss_seg
, SEC_ALLOC
| SEC_SMALL_DATA
))
6128 as_warn (_("error setting flags for \".sbss\": %s"),
6129 bfd_errmsg (bfd_get_error ()));
6135 if (*input_line_pointer
== ',')
6137 ++input_line_pointer
;
6140 if (is_end_of_line
[(unsigned char)*input_line_pointer
])
6142 as_bad (_("missing alignment"));
6147 align
= get_absolute_expression ();
6154 TC_IMPLICIT_LCOMM_ALIGNMENT (temp
, align
);
6156 /* Still zero unless TC_IMPLICIT_LCOMM_ALIGNMENT set it. */
6158 record_alignment (bss_seg
, align
);
6165 /* Convert to a power of 2. */
6170 for (i
= 0; align
!= 0; align
>>= 1, ++i
)
6176 if (align
> max_alignment
)
6178 align
= max_alignment
;
6179 as_warn (_("alignment too large; %d assumed"), align
);
6184 as_warn (_("alignment negative; 0 assumed"));
6187 record_alignment (bss_seg
, align
);
6191 /* Assume some objects may require alignment on some systems. */
6192 #if defined (TC_ALPHA) && ! defined (VMS)
6195 align
= ffs (temp
) - 1;
6196 if (temp
% (1 << align
))
6203 symbolP
= symbol_find_or_make (name
);
6207 #if (defined (OBJ_AOUT) || defined (OBJ_MAYBE_AOUT))
6208 (OUTPUT_FLAVOR
!= bfd_target_aout_flavour
6209 || (S_GET_OTHER (symbolP
) == 0 && S_GET_DESC (symbolP
) == 0)) &&
6211 (S_GET_SEGMENT (symbolP
) == bss_seg
|| (!S_IS_DEFINED (symbolP
) && S_GET_VALUE (symbolP
) == 0)))
6215 subseg_set (bss_seg
, 1);
6218 frag_align (align
, 0, 0);
6220 /* Detach from old frag. */
6221 if (S_GET_SEGMENT (symbolP
) == bss_seg
)
6222 symbol_get_frag (symbolP
)->fr_symbol
= NULL
;
6224 symbol_set_frag (symbolP
, frag_now
);
6225 pfrag
= frag_var (rs_org
, 1, 1, (relax_substateT
) 0, symbolP
, (offsetT
) temp
, NULL
);
6229 S_SET_SEGMENT (symbolP
, bss_seg
);
6232 /* The symbol may already have been created with a preceding
6233 ".globl" directive -- be careful not to step on storage class
6234 in that case. Otherwise, set it to static. */
6235 if (S_GET_STORAGE_CLASS (symbolP
) != C_EXT
)
6237 S_SET_STORAGE_CLASS (symbolP
, C_STAT
);
6239 #endif /* OBJ_COFF */
6242 S_SET_SIZE (symbolP
, temp
);
6246 as_bad (_("symbol `%s' is already defined"), S_GET_NAME (symbolP
));
6248 subseg_set (current_seg
, current_subseg
);
6250 demand_empty_rest_of_line ();
6254 s3_insert_reg (const struct s3_reg_entry
*r
, struct hash_control
*htab
)
6257 int len
= strlen (r
->name
) + 2;
6258 char *buf
= XNEWVEC (char, len
);
6259 char *buf2
= XNEWVEC (char, len
);
6261 strcpy (buf
+ i
, r
->name
);
6262 for (i
= 0; buf
[i
]; i
++)
6264 buf2
[i
] = TOUPPER (buf
[i
]);
6268 hash_insert (htab
, buf
, (void *) r
);
6269 hash_insert (htab
, buf2
, (void *) r
);
6273 s3_build_reg_hsh (struct s3_reg_map
*map
)
6275 const struct s3_reg_entry
*r
;
6277 if ((map
->htab
= hash_new ()) == NULL
)
6279 as_fatal (_("virtual memory exhausted"));
6281 for (r
= map
->names
; r
->name
!= NULL
; r
++)
6283 s3_insert_reg (r
, map
->htab
);
6287 /* Iterate over the base tables to create the instruction patterns. */
6289 s3_build_score_ops_hsh (void)
6292 static struct obstack insn_obstack
;
6294 obstack_begin (&insn_obstack
, 4000);
6295 for (i
= 0; i
< sizeof (s3_score_insns
) / sizeof (struct s3_asm_opcode
); i
++)
6297 const struct s3_asm_opcode
*insn
= s3_score_insns
+ i
;
6298 size_t len
= strlen (insn
->template_name
);
6299 struct s3_asm_opcode
*new_opcode
;
6300 char *template_name
;
6301 new_opcode
= (struct s3_asm_opcode
*)
6302 obstack_alloc (&insn_obstack
, sizeof (struct s3_asm_opcode
));
6303 template_name
= (char *) obstack_alloc (& insn_obstack
, len
+ 1);
6305 strcpy (template_name
, insn
->template_name
);
6306 new_opcode
->template_name
= template_name
;
6307 new_opcode
->parms
= insn
->parms
;
6308 new_opcode
->value
= insn
->value
;
6309 new_opcode
->relax_value
= insn
->relax_value
;
6310 new_opcode
->type
= insn
->type
;
6311 new_opcode
->bitmask
= insn
->bitmask
;
6312 hash_insert (s3_score_ops_hsh
, new_opcode
->template_name
,
6313 (void *) new_opcode
);
6318 s3_build_dependency_insn_hsh (void)
6321 static struct obstack dependency_obstack
;
6323 obstack_begin (&dependency_obstack
, 4000);
6324 for (i
= 0; i
< sizeof (s3_insn_to_dependency_table
) / sizeof (s3_insn_to_dependency_table
[0]); i
++)
6326 const struct s3_insn_to_dependency
*tmp
= s3_insn_to_dependency_table
+ i
;
6327 size_t len
= strlen (tmp
->insn_name
);
6328 struct s3_insn_to_dependency
*new_i2n
;
6331 new_i2n
= (struct s3_insn_to_dependency
*)
6332 obstack_alloc (&dependency_obstack
,
6333 sizeof (struct s3_insn_to_dependency
));
6334 buf
= (char *) obstack_alloc (&dependency_obstack
, len
+ 1);
6336 strcpy (buf
, tmp
->insn_name
);
6337 new_i2n
->insn_name
= buf
;
6338 new_i2n
->type
= tmp
->type
;
6339 hash_insert (s3_dependency_insn_hsh
, new_i2n
->insn_name
,
6345 s_score_bss (int ignore ATTRIBUTE_UNUSED
)
6348 return s3_s_score_bss (ignore
);
6350 return s7_s_score_bss (ignore
);
6354 s_score_text (int ignore
)
6357 return s3_s_score_text (ignore
);
6359 return s7_s_score_text (ignore
);
6363 s_section (int ignore
)
6366 return s3_score_s_section (ignore
);
6368 return s7_s_section (ignore
);
6372 s_change_sec (int sec
)
6375 return s3_s_change_sec (sec
);
6377 return s7_s_change_sec (sec
);
6381 s_score_mask (int reg_type ATTRIBUTE_UNUSED
)
6384 return s3_s_score_mask (reg_type
);
6386 return s7_s_score_mask (reg_type
);
6390 s_score_ent (int aent
)
6393 return s3_s_score_ent (aent
);
6395 return s7_s_score_ent (aent
);
6399 s_score_frame (int ignore ATTRIBUTE_UNUSED
)
6402 return s3_s_score_frame (ignore
);
6404 return s7_s_score_frame (ignore
);
6408 s_score_end (int x ATTRIBUTE_UNUSED
)
6411 return s3_s_score_end (x
);
6413 return s7_s_score_end (x
);
6417 s_score_set (int x ATTRIBUTE_UNUSED
)
6420 return s3_s_score_set (x
);
6422 return s7_s_score_set (x
);
6426 s_score_cpload (int ignore ATTRIBUTE_UNUSED
)
6429 return s3_s_score_cpload (ignore
);
6431 return s7_s_score_cpload (ignore
);
6435 s_score_cprestore (int ignore ATTRIBUTE_UNUSED
)
6438 return s3_s_score_cprestore (ignore
);
6440 return s7_s_score_cprestore (ignore
);
6444 s_score_gpword (int ignore ATTRIBUTE_UNUSED
)
6447 return s3_s_score_gpword (ignore
);
6449 return s7_s_score_gpword (ignore
);
6453 s_score_cpadd (int ignore ATTRIBUTE_UNUSED
)
6456 return s3_s_score_cpadd (ignore
);
6458 return s7_s_score_cpadd (ignore
);
6462 s_score_lcomm (int bytes_p
)
6465 return s3_s_score_lcomm (bytes_p
);
6467 return s7_s_score_lcomm (bytes_p
);
6471 s3_assemble (char *str
)
6474 know (strlen (str
) < s3_MAX_LITERAL_POOL_SIZE
);
6476 memset (&s3_inst
, '\0', sizeof (s3_inst
));
6477 if (s3_INSN_IS_PCE_P (str
))
6478 s3_parse_pce_inst (str
);
6479 else if (s3_INSN_IS_48_P (str
))
6480 s3_parse_48_inst (str
, TRUE
);
6482 s3_parse_16_32_inst (str
, TRUE
);
6485 as_bad (_("%s -- `%s'"), s3_inst
.error
, s3_inst
.str
);
6489 s3_operand (expressionS
* exp
)
6491 if (s3_in_my_get_expression
)
6493 exp
->X_op
= O_illegal
;
6494 if (s3_inst
.error
== NULL
)
6496 s3_inst
.error
= _("bad expression");
6508 if ((s3_score_ops_hsh
= hash_new ()) == NULL
)
6509 as_fatal (_("virtual memory exhausted"));
6511 s3_build_score_ops_hsh ();
6513 if ((s3_dependency_insn_hsh
= hash_new ()) == NULL
)
6514 as_fatal (_("virtual memory exhausted"));
6516 s3_build_dependency_insn_hsh ();
6518 for (i
= (int)s3_REG_TYPE_FIRST
; i
< (int)s3_REG_TYPE_MAX
; i
++)
6519 s3_build_reg_hsh (s3_all_reg_maps
+ i
);
6521 /* Initialize dependency vector. */
6522 s3_init_dependency_vector ();
6524 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
, 0);
6526 subseg
= now_subseg
;
6527 s3_pdr_seg
= subseg_new (".pdr", (subsegT
) 0);
6528 bfd_set_section_flags (s3_pdr_seg
, SEC_READONLY
| SEC_RELOC
| SEC_DEBUGGING
);
6529 bfd_set_section_alignment (s3_pdr_seg
, 2);
6530 subseg_set (seg
, subseg
);
6532 if (s3_USE_GLOBAL_POINTER_OPT
)
6533 bfd_set_gp_size (stdoutput
, s3_g_switch_value
);
6537 s3_number_to_chars (char *buf
, valueT val
, int n
)
6539 if (target_big_endian
)
6540 number_to_chars_bigendian (buf
, val
, n
);
6542 number_to_chars_littleendian (buf
, val
, n
);
6546 s3_normal_chars_to_number (char *buf
, int n
)
6549 unsigned char *where
= (unsigned char *)buf
;
6551 if (target_big_endian
)
6556 result
|= (*where
++ & 255);
6564 result
|= (where
[n
] & 255);
6572 s3_number_to_chars_littleendian (void *p
, valueT data
, int n
)
6574 char *buf
= (char *) p
;
6579 md_number_to_chars (buf
, data
>> 16, 2);
6580 md_number_to_chars (buf
+ 2, data
, 2);
6583 md_number_to_chars (buf
, data
>> 32, 2);
6584 md_number_to_chars (buf
+ 2, data
>> 16, 2);
6585 md_number_to_chars (buf
+ 4, data
, 2);
6588 /* Error routine. */
6589 as_bad_where (__FILE__
, __LINE__
, _("size is not 4 or 6"));
6595 s3_chars_to_number_littleendian (const void *p
, int n
)
6597 char *buf
= (char *) p
;
6603 result
= s3_normal_chars_to_number (buf
, 2) << 16;
6604 result
|= s3_normal_chars_to_number (buf
+ 2, 2);
6607 result
= s3_normal_chars_to_number (buf
, 2) << 32;
6608 result
|= s3_normal_chars_to_number (buf
+ 2, 2) << 16;
6609 result
|= s3_normal_chars_to_number (buf
+ 4, 2);
6612 /* Error routine. */
6613 as_bad_where (__FILE__
, __LINE__
, _("size is not 4 or 6"));
6621 s3_md_number_to_chars (char *buf
, valueT val
, int n
)
6623 if (!target_big_endian
&& n
>= 4)
6624 s3_number_to_chars_littleendian (buf
, val
, n
);
6626 md_number_to_chars (buf
, val
, n
);
6630 s3_md_chars_to_number (char *buf
, int n
)
6634 if (!target_big_endian
&& n
>= 4)
6635 result
= s3_chars_to_number_littleendian (buf
, n
);
6637 result
= s3_normal_chars_to_number (buf
, n
);
6643 s3_atof (int type
, char *litP
, int *sizeP
)
6646 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
6672 return _("bad call to MD_ATOF()");
6675 t
= atof_ieee (input_line_pointer
, type
, words
);
6677 input_line_pointer
= t
;
6680 if (target_big_endian
)
6682 for (i
= 0; i
< prec
; i
++)
6684 s3_md_number_to_chars (litP
, (valueT
) words
[i
], 2);
6690 for (i
= 0; i
< prec
; i
+= 2)
6692 s3_md_number_to_chars (litP
, (valueT
) words
[i
+ 1], 2);
6693 s3_md_number_to_chars (litP
+ 2, (valueT
) words
[i
], 2);
6702 s3_frag_check (fragS
* fragp ATTRIBUTE_UNUSED
)
6704 know (fragp
->insn_addr
<= s3_RELAX_PAD_BYTE
);
6708 s3_validate_fix (fixS
*fixP
)
6710 fixP
->fx_where
+= fixP
->fx_frag
->insn_addr
;
6714 s3_force_relocation (struct fix
*fixp
)
6718 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
6719 || fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
6720 || fixp
->fx_r_type
== BFD_RELOC_SCORE_JMP
6721 || fixp
->fx_r_type
== BFD_RELOC_SCORE_BRANCH
6722 || fixp
->fx_r_type
== BFD_RELOC_SCORE16_JMP
6723 || fixp
->fx_r_type
== BFD_RELOC_SCORE16_BRANCH
6724 || fixp
->fx_r_type
== BFD_RELOC_SCORE_BCMP
)
6732 s3_fix_adjustable (fixS
* fixP
)
6734 if (fixP
->fx_addsy
== NULL
)
6738 else if (OUTPUT_FLAVOR
== bfd_target_elf_flavour
6739 && (S_IS_EXTERNAL (fixP
->fx_addsy
) || S_IS_WEAK (fixP
->fx_addsy
)))
6743 else if (fixP
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
6744 || fixP
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
6745 || fixP
->fx_r_type
== BFD_RELOC_SCORE_JMP
6746 || fixP
->fx_r_type
== BFD_RELOC_SCORE16_JMP
)
6755 s3_elf_final_processing (void)
6757 unsigned long val
= 0;
6760 val
= E_SCORE_MACH_SCORE3
;
6762 val
= E_SCORE_MACH_SCORE7
;
6764 elf_elfheader (stdoutput
)->e_machine
= EM_SCORE
;
6765 elf_elfheader (stdoutput
)->e_flags
&= ~EF_SCORE_MACH
;
6766 elf_elfheader (stdoutput
)->e_flags
|= val
;
6768 if (s3_fix_data_dependency
== 1)
6770 elf_elfheader (stdoutput
)->e_flags
|= EF_SCORE_FIXDEP
;
6772 if (s3_score_pic
== s3_PIC
)
6774 elf_elfheader (stdoutput
)->e_flags
|= EF_SCORE_PIC
;
6779 s3_judge_size_before_relax (fragS
* fragp
, asection
*sec
)
6783 if (s3_score_pic
== s3_NO_PIC
)
6784 change
= s3_nopic_need_relax (fragp
->fr_symbol
, 0);
6786 change
= s3_pic_need_relax (fragp
->fr_symbol
, sec
);
6790 /* Only at the first time determining whether s3_GP instruction relax should be done,
6791 return the difference between instruction size and instruction relax size. */
6792 if (fragp
->fr_opcode
== NULL
)
6794 fragp
->fr_fix
= s3_RELAX_NEW (fragp
->fr_subtype
);
6795 fragp
->fr_opcode
= fragp
->fr_literal
+ s3_RELAX_RELOC1 (fragp
->fr_subtype
);
6796 return s3_RELAX_NEW (fragp
->fr_subtype
) - s3_RELAX_OLD (fragp
->fr_subtype
);
6804 s3_estimate_size_before_relax (fragS
* fragp
, asection
* sec ATTRIBUTE_UNUSED
)
6806 if ((s3_RELAX_TYPE (fragp
->fr_subtype
) == Insn_GP
)
6807 || (s3_RELAX_TYPE (fragp
->fr_subtype
) == Insn_PIC
))
6808 return s3_judge_size_before_relax (fragp
, sec
);
6814 s3_relax_branch_inst32 (fragS
* fragp
)
6816 fragp
->fr_opcode
= NULL
;
6821 s3_relax_branch_inst16 (fragS
* fragp
)
6823 int relaxable_p
= 0;
6824 int frag_addr
= fragp
->fr_address
+ fragp
->insn_addr
;
6825 addressT symbol_address
= 0;
6829 unsigned long inst_value
;
6831 relaxable_p
= s3_RELAX_OPT (fragp
->fr_subtype
);
6833 s
= fragp
->fr_symbol
;
6837 symbol_address
= (addressT
) symbol_get_frag (s
)->fr_address
;
6839 inst_value
= s3_md_chars_to_number (fragp
->fr_literal
, s3_INSN16_SIZE
);
6840 offset
= (inst_value
& 0x1ff) << 1;
6841 if ((offset
& 0x200) == 0x200)
6842 offset
|= 0xfffffc00;
6844 value
= offset
+ symbol_address
- frag_addr
;
6847 && (!((value
& 0xfffffe00) == 0 || (value
& 0xfffffe00) == 0xfffffe00))
6848 && fragp
->fr_fix
== 2
6849 && (S_IS_DEFINED (s
)
6851 && !S_IS_EXTERNAL (s
)))
6853 /* Relax branch 32 to branch 16. */
6854 fragp
->fr_opcode
= fragp
->fr_literal
+ s3_RELAX_RELOC1 (fragp
->fr_subtype
);
6863 s3_relax_cmpbranch_inst32 (fragS
* fragp
)
6865 int relaxable_p
= 0;
6869 long frag_addr
= fragp
->fr_address
+ fragp
->insn_addr
;
6870 long symbol_address
= 0;
6872 unsigned long inst_value
;
6874 relaxable_p
= s3_RELAX_OPT (fragp
->fr_subtype
);
6876 s
= fragp
->fr_symbol
;
6880 symbol_address
= (addressT
) symbol_get_frag (s
)->fr_address
;
6882 inst_value
= s3_md_chars_to_number (fragp
->fr_literal
, s3_INSN_SIZE
);
6883 offset
= (inst_value
& 0x1)
6884 | (((inst_value
>> 7) & 0x7) << 1)
6885 | (((inst_value
>> 21) & 0x1f) << 4);
6887 if ((offset
& 0x200) == 0x200)
6888 offset
|= 0xfffffe00;
6890 value
= offset
+ symbol_address
- frag_addr
;
6891 /* change the order of judging rule is because
6892 1.not defined symbol or common symbol or external symbol will change
6893 bcmp to cmp!+beq/bne ,here need to record fragp->fr_opcode
6894 2.if the flow is as before : it will results to recursive loop
6896 if (fragp
->fr_fix
== 6)
6898 /* Have already relaxed! Just return 0 to terminate the loop. */
6901 /* need to translate when extern or not defined or common symbol */
6902 else if ((relaxable_p
6903 && (!((value
& 0xfffffe00) == 0 || (value
& 0xfffffe00) == 0xfffffe00))
6904 && fragp
->fr_fix
== 4)
6905 || !S_IS_DEFINED (s
)
6907 ||S_IS_EXTERNAL (s
))
6909 fragp
->fr_opcode
= fragp
->fr_literal
+ s3_RELAX_RELOC1 (fragp
->fr_subtype
);
6915 /* Never relax. Modify fr_opcode to NULL to verify it's value in
6917 fragp
->fr_opcode
= NULL
;
6924 s3_relax_other_inst32 (fragS
* fragp
)
6926 int relaxable_p
= s3_RELAX_OPT (fragp
->fr_subtype
);
6929 && fragp
->fr_fix
== 4)
6931 fragp
->fr_opcode
= fragp
->fr_literal
+ s3_RELAX_RELOC1 (fragp
->fr_subtype
);
6940 s3_relax_gp_and_pic_inst32 (void)
6942 /* md_estimate_size_before_relax has already relaxed s3_GP and s3_PIC
6943 instructions. We don't change relax size here. */
6948 s3_relax_frag (asection
* sec ATTRIBUTE_UNUSED
, fragS
* fragp
, long stretch ATTRIBUTE_UNUSED
)
6951 int adjust_align_p
= 0;
6953 /* If the instruction address is odd, make it half word align first. */
6954 if ((fragp
->fr_address
) % 2 != 0)
6956 if ((fragp
->fr_address
+ fragp
->insn_addr
) % 2 != 0)
6958 fragp
->insn_addr
= 1;
6964 switch (s3_RELAX_TYPE (fragp
->fr_subtype
))
6967 grows
+= s3_relax_branch_inst32 (fragp
);
6971 grows
+= s3_relax_branch_inst16 (fragp
);
6975 grows
+= s3_relax_cmpbranch_inst32 (fragp
);
6980 grows
+= s3_relax_gp_and_pic_inst32 ();
6984 grows
+= s3_relax_other_inst32 (fragp
);
6989 if (adjust_align_p
&& fragp
->insn_addr
)
6991 fragp
->fr_fix
+= fragp
->insn_addr
;
6998 s3_convert_frag (bfd
* abfd ATTRIBUTE_UNUSED
, segT sec ATTRIBUTE_UNUSED
, fragS
* fragp
)
7005 r_old
= s3_RELAX_OLD (fragp
->fr_subtype
);
7006 r_new
= s3_RELAX_NEW (fragp
->fr_subtype
);
7008 /* fragp->fr_opcode indicates whether this frag should be relaxed. */
7009 if (fragp
->fr_opcode
== NULL
)
7011 memcpy (backup
, fragp
->fr_literal
, r_old
);
7012 fragp
->fr_fix
= r_old
;
7016 memcpy (backup
, fragp
->fr_literal
+ r_old
, r_new
);
7017 fragp
->fr_fix
= r_new
;
7020 fixp
= fragp
->tc_frag_data
.fixp
;
7021 while (fixp
&& fixp
->fx_frag
== fragp
&& fixp
->fx_where
< r_old
)
7023 if (fragp
->fr_opcode
)
7025 fixp
= fixp
->fx_next
;
7027 while (fixp
&& fixp
->fx_frag
== fragp
)
7029 if (fragp
->fr_opcode
)
7030 fixp
->fx_where
-= r_old
+ fragp
->insn_addr
;
7033 fixp
= fixp
->fx_next
;
7036 if (fragp
->insn_addr
)
7038 s3_md_number_to_chars (fragp
->fr_literal
, 0x0, fragp
->insn_addr
);
7040 memcpy (fragp
->fr_literal
+ fragp
->insn_addr
, backup
, fragp
->fr_fix
);
7041 fragp
->fr_fix
+= fragp
->insn_addr
;
7045 s3_pcrel_from (fixS
* fixP
)
7050 && (S_GET_SEGMENT (fixP
->fx_addsy
) == undefined_section
)
7051 && (fixP
->fx_subsy
== NULL
))
7057 retval
= fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
7064 s3_section_align (segT segment ATTRIBUTE_UNUSED
, valueT size
)
7066 int align
= bfd_section_alignment (segment
);
7067 return ((size
+ (1 << align
) - 1) & -(1 << align
));
7071 s3_apply_fix (fixS
*fixP
, valueT
*valP
, segT seg
)
7073 offsetT value
= *valP
;
7076 unsigned short HI
, LO
;
7078 char *buf
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
7080 gas_assert (fixP
->fx_r_type
< BFD_RELOC_UNUSED
);
7081 if (fixP
->fx_addsy
== 0 && !fixP
->fx_pcrel
)
7083 if (fixP
->fx_r_type
!= BFD_RELOC_SCORE_DUMMY_HI16
)
7087 /* If this symbol is in a different section then we need to leave it for
7088 the linker to deal with. Unfortunately, md_pcrel_from can't tell,
7089 so we have to undo it's effects here. */
7092 if (fixP
->fx_addsy
!= NULL
7093 && S_IS_DEFINED (fixP
->fx_addsy
)
7094 && S_GET_SEGMENT (fixP
->fx_addsy
) != seg
)
7095 value
+= md_pcrel_from (fixP
);
7098 /* Remember value for emit_reloc. */
7099 fixP
->fx_addnumber
= value
;
7101 switch (fixP
->fx_r_type
)
7103 case BFD_RELOC_HI16_S
:
7104 if (fixP
->fx_done
) /* For la rd, imm32. */
7106 newval
= s3_md_chars_to_number (buf
, s3_INSN_SIZE
);
7107 HI
= (value
) >> 16; /* mul to 2, then take the hi 16 bit. */
7108 newval
|= (HI
& 0x3fff) << 1;
7109 newval
|= ((HI
>> 14) & 0x3) << 16;
7110 s3_md_number_to_chars (buf
, newval
, s3_INSN_SIZE
);
7113 case BFD_RELOC_LO16
:
7114 if (fixP
->fx_done
) /* For la rd, imm32. */
7116 newval
= s3_md_chars_to_number (buf
, s3_INSN_SIZE
);
7117 LO
= (value
) & 0xffff;
7118 newval
|= (LO
& 0x3fff) << 1; /* 16 bit: imm -> 14 bit in lo, 2 bit in hi. */
7119 newval
|= ((LO
>> 14) & 0x3) << 16;
7120 s3_md_number_to_chars (buf
, newval
, s3_INSN_SIZE
);
7123 case BFD_RELOC_SCORE_JMP
:
7125 content
= s3_md_chars_to_number (buf
, s3_INSN_SIZE
);
7126 value
= fixP
->fx_offset
;
7127 content
= (content
& ~0x3ff7ffe) | ((value
<< 1) & 0x3ff0000) | (value
& 0x7fff);
7128 s3_md_number_to_chars (buf
, content
, s3_INSN_SIZE
);
7132 case BFD_RELOC_SCORE_IMM30
:
7134 content
= s3_md_chars_to_number (buf
, s3_INSN48_SIZE
);
7135 value
= fixP
->fx_offset
;
7137 content
= (content
& ~0x7f7fff7f80LL
)
7138 | (((value
& 0xff) >> 0) << 7)
7139 | (((value
& 0x7fff00) >> 8) << 16)
7140 | (((value
& 0x3f800000) >> 23) << 32);
7141 s3_md_number_to_chars (buf
, content
, s3_INSN48_SIZE
);
7145 case BFD_RELOC_SCORE_IMM32
:
7147 content
= s3_md_chars_to_number (buf
, s3_INSN48_SIZE
);
7148 value
= fixP
->fx_offset
;
7149 content
= (content
& ~0x7f7fff7fe0LL
)
7150 | ((value
& 0x3ff) << 5)
7151 | (((value
>> 10) & 0x7fff) << 16)
7152 | (((value
>> 25) & 0x7f) << 32);
7153 s3_md_number_to_chars (buf
, content
, s3_INSN48_SIZE
);
7157 case BFD_RELOC_SCORE_BRANCH
:
7158 if ((S_GET_SEGMENT (fixP
->fx_addsy
) != seg
) || (fixP
->fx_addsy
!= NULL
&& S_IS_EXTERNAL (fixP
->fx_addsy
)))
7159 value
= fixP
->fx_offset
;
7163 content
= s3_md_chars_to_number (buf
, s3_INSN_SIZE
);
7165 /* Don't check c-bit. */
7166 if (fixP
->fx_frag
->fr_opcode
!= 0)
7168 if ((value
& 0xfffffe00) != 0 && (value
& 0xfffffe00) != 0xfffffe00)
7170 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7171 _(" branch relocation truncate (0x%x) [-2^9 ~ 2^9-1]"), (unsigned int) value
);
7174 content
= s3_md_chars_to_number (buf
, s3_INSN16_SIZE
);
7176 content
= (content
& 0xfe00) | ((value
>> 1) & 0x1ff);
7177 s3_md_number_to_chars (buf
, content
, s3_INSN16_SIZE
);
7178 fixP
->fx_r_type
= BFD_RELOC_SCORE16_BRANCH
;
7183 if ((value
& 0xfff80000) != 0 && (value
& 0xfff80000) != 0xfff80000)
7185 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7186 _(" branch relocation truncate (0x%x) [-2^19 ~ 2^19-1]"), (unsigned int) value
);
7189 content
= s3_md_chars_to_number (buf
, s3_INSN_SIZE
);
7190 content
&= 0xfc00fc01;
7191 content
= (content
& 0xfc00fc01) | (value
& 0x3fe) | ((value
<< 6) & 0x3ff0000);
7192 s3_md_number_to_chars (buf
, content
, s3_INSN_SIZE
);
7195 case BFD_RELOC_SCORE16_JMP
:
7196 content
= s3_md_chars_to_number (buf
, s3_INSN16_SIZE
);
7198 value
= fixP
->fx_offset
& 0xfff;
7199 content
= (content
& 0xfc01) | (value
& 0xffe);
7200 s3_md_number_to_chars (buf
, content
, s3_INSN16_SIZE
);
7202 case BFD_RELOC_SCORE16_BRANCH
:
7203 content
= s3_md_chars_to_number (buf
, s3_INSN_SIZE
);
7204 /* Don't check c-bit. */
7205 if (fixP
->fx_frag
->fr_opcode
!= 0)
7207 if ((S_GET_SEGMENT (fixP
->fx_addsy
) != seg
) ||
7208 (fixP
->fx_addsy
!= NULL
&& S_IS_EXTERNAL (fixP
->fx_addsy
)))
7209 value
= fixP
->fx_offset
;
7212 if ((value
& 0xfff80000) != 0 && (value
& 0xfff80000) != 0xfff80000)
7214 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7215 _(" branch relocation truncate (0x%x) [-2^19 ~ 2^19-1]"), (unsigned int) value
);
7218 content
= s3_md_chars_to_number (buf
, s3_INSN_SIZE
);
7219 content
= (content
& 0xfc00fc01) | (value
& 0x3fe) | ((value
<< 6) & 0x3ff0000);
7220 s3_md_number_to_chars (buf
, content
, s3_INSN_SIZE
);
7221 fixP
->fx_r_type
= BFD_RELOC_SCORE_BRANCH
;
7227 /* In different section. */
7228 if ((S_GET_SEGMENT (fixP
->fx_addsy
) != seg
) ||
7229 (fixP
->fx_addsy
!= NULL
&& S_IS_EXTERNAL (fixP
->fx_addsy
)))
7230 value
= fixP
->fx_offset
;
7234 if ((value
& 0xfffffe00) != 0 && (value
& 0xfffffe00) != 0xfffffe00)
7236 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7237 _(" branch relocation truncate (0x%x) [-2^9 ~ 2^9-1]"), (unsigned int) value
);
7241 content
= s3_md_chars_to_number (buf
, s3_INSN16_SIZE
);
7242 content
= (content
& 0xfe00) | ((value
>> 1) & 0x1ff);
7243 s3_md_number_to_chars (buf
, content
, s3_INSN16_SIZE
);
7249 case BFD_RELOC_SCORE_BCMP
:
7250 if (fixP
->fx_frag
->fr_opcode
!= 0)
7252 char *buf_ptr
= buf
;
7255 if ((S_GET_SEGMENT (fixP
->fx_addsy
) != seg
) || (fixP
->fx_addsy
!= NULL
&& S_IS_EXTERNAL (fixP
->fx_addsy
)))
7256 value
= fixP
->fx_offset
;
7261 bcmp -> cmp! and branch, so value -= 2. */
7264 if ((value
& 0xfff80000) != 0 && (value
& 0xfff80000) != 0xfff80000)
7266 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7267 _(" branch relocation truncate (0x%x) [-2^19 ~ 2^19-1]"), (unsigned int) value
);
7271 content
= s3_md_chars_to_number (buf_ptr
, s3_INSN_SIZE
);
7272 content
&= 0xfc00fc01;
7273 content
= (content
& 0xfc00fc01) | (value
& 0x3fe) | ((value
<< 6) & 0x3ff0000);
7274 s3_md_number_to_chars (buf_ptr
, content
, s3_INSN_SIZE
);
7275 /* change relocation type to BFD_RELOC_SCORE_BRANCH */
7276 fixP
->fx_r_type
= BFD_RELOC_SCORE_BRANCH
;
7277 fixP
->fx_where
+=2; /* first insn is cmp! , the second insn is beq/bne */
7282 if ((S_GET_SEGMENT (fixP
->fx_addsy
) != seg
) || (fixP
->fx_addsy
!= NULL
&& S_IS_EXTERNAL (fixP
->fx_addsy
)))
7283 value
= fixP
->fx_offset
;
7287 content
= s3_md_chars_to_number (buf
, s3_INSN_SIZE
);
7289 if ((value
& 0xfffffe00) != 0 && (value
& 0xfffffe00) != 0xfffffe00)
7291 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7292 _(" branch relocation truncate (0x%x) [-2^9 ~ 2^9-1]"), (unsigned int) value
);
7297 content
&= ~0x03e00381;
7300 | (((value
& 0xe) >> 1) << 7)
7301 | (((value
& 0x1f0) >> 4) << 21);
7303 s3_md_number_to_chars (buf
, content
, s3_INSN_SIZE
);
7308 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
7309 s3_md_number_to_chars (buf
, value
, 1);
7313 value
= fixP
->fx_offset
;
7314 s3_md_number_to_chars (buf
, value
, 1);
7320 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
7321 s3_md_number_to_chars (buf
, value
, 2);
7325 value
= fixP
->fx_offset
;
7326 s3_md_number_to_chars (buf
, value
, 2);
7332 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
7333 md_number_to_chars (buf
, value
, 4);
7337 value
= fixP
->fx_offset
;
7338 md_number_to_chars (buf
, value
, 4);
7342 case BFD_RELOC_VTABLE_INHERIT
:
7344 if (fixP
->fx_addsy
&& !S_IS_DEFINED (fixP
->fx_addsy
) && !S_IS_WEAK (fixP
->fx_addsy
))
7345 S_SET_WEAK (fixP
->fx_addsy
);
7347 case BFD_RELOC_VTABLE_ENTRY
:
7350 case BFD_RELOC_SCORE_GPREL15
:
7351 content
= s3_md_chars_to_number (buf
, s3_INSN_SIZE
);
7353 if ((fixP
->fx_frag
->fr_opcode
!= 0) && ((content
& 0xfc1c8000) != 0x94180000))
7354 fixP
->fx_r_type
= BFD_RELOC_NONE
;
7357 case BFD_RELOC_SCORE_GOT15
:
7358 case BFD_RELOC_SCORE_DUMMY_HI16
:
7359 case BFD_RELOC_SCORE_GOT_LO16
:
7360 case BFD_RELOC_SCORE_CALL15
:
7361 case BFD_RELOC_GPREL32
:
7363 case BFD_RELOC_NONE
:
7365 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("bad relocation fixup type (%d)"), fixP
->fx_r_type
);
7370 s3_gen_reloc (asection
* section ATTRIBUTE_UNUSED
, fixS
* fixp
)
7372 static arelent
*retval
[MAX_RELOC_EXPANSION
+ 1]; /* MAX_RELOC_EXPANSION equals 2. */
7374 bfd_reloc_code_real_type code
;
7377 reloc
= retval
[0] = XNEW (arelent
);
7380 reloc
->sym_ptr_ptr
= XNEW (asymbol
*);
7381 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
7382 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
7383 reloc
->addend
= fixp
->fx_offset
;
7385 /* If this is a variant frag, we may need to adjust the existing
7386 reloc and generate a new one. */
7387 if (fixp
->fx_frag
->fr_opcode
!= NULL
&& (fixp
->fx_r_type
== BFD_RELOC_SCORE_GPREL15
))
7389 /* Update instruction imm bit. */
7394 buf
= fixp
->fx_frag
->fr_literal
+ fixp
->fx_frag
->insn_addr
;
7395 newval
= s3_md_chars_to_number (buf
, s3_INSN_SIZE
);
7396 off
= fixp
->fx_offset
>> 16;
7397 newval
|= (off
& 0x3fff) << 1;
7398 newval
|= ((off
>> 14) & 0x3) << 16;
7399 s3_md_number_to_chars (buf
, newval
, s3_INSN_SIZE
);
7401 buf
+= s3_INSN_SIZE
;
7402 newval
= s3_md_chars_to_number (buf
, s3_INSN_SIZE
);
7403 off
= fixp
->fx_offset
& 0xffff;
7404 newval
|= ((off
& 0x3fff) << 1);
7405 newval
|= (((off
>> 14) & 0x3) << 16);
7406 s3_md_number_to_chars (buf
, newval
, s3_INSN_SIZE
);
7408 retval
[1] = XNEW (arelent
);
7410 retval
[1]->sym_ptr_ptr
= XNEW (asymbol
*);
7411 *retval
[1]->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
7412 retval
[1]->address
= (reloc
->address
+ s3_RELAX_RELOC2 (fixp
->fx_frag
->fr_subtype
));
7414 retval
[1]->addend
= 0;
7415 retval
[1]->howto
= bfd_reloc_type_lookup (stdoutput
, BFD_RELOC_LO16
);
7416 gas_assert (retval
[1]->howto
!= NULL
);
7418 fixp
->fx_r_type
= BFD_RELOC_HI16_S
;
7421 code
= fixp
->fx_r_type
;
7422 switch (fixp
->fx_r_type
)
7427 code
= BFD_RELOC_32_PCREL
;
7431 case BFD_RELOC_HI16_S
:
7432 case BFD_RELOC_LO16
:
7433 case BFD_RELOC_SCORE_JMP
:
7434 case BFD_RELOC_SCORE_BRANCH
:
7435 case BFD_RELOC_SCORE16_JMP
:
7436 case BFD_RELOC_SCORE16_BRANCH
:
7437 case BFD_RELOC_SCORE_BCMP
:
7438 case BFD_RELOC_VTABLE_ENTRY
:
7439 case BFD_RELOC_VTABLE_INHERIT
:
7440 case BFD_RELOC_SCORE_GPREL15
:
7441 case BFD_RELOC_SCORE_GOT15
:
7442 case BFD_RELOC_SCORE_DUMMY_HI16
:
7443 case BFD_RELOC_SCORE_GOT_LO16
:
7444 case BFD_RELOC_SCORE_CALL15
:
7445 case BFD_RELOC_GPREL32
:
7446 case BFD_RELOC_NONE
:
7447 case BFD_RELOC_SCORE_IMM30
:
7448 case BFD_RELOC_SCORE_IMM32
:
7449 code
= fixp
->fx_r_type
;
7452 type
= _("<unknown>");
7453 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
7454 _("cannot represent %s relocation in this object file format"), type
);
7458 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
7459 if (reloc
->howto
== NULL
)
7461 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
7462 _("cannot represent %s relocation in this object file format1"),
7463 bfd_get_reloc_code_name (code
));
7466 /* HACK: Since arm ELF uses Rel instead of Rela, encode the
7467 vtable entry to be used in the relocation's section offset. */
7468 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
7469 reloc
->address
= fixp
->fx_offset
;
7475 md_assemble (char *str
)
7483 /* We handle all bad expressions here, so that we can report the faulty
7484 instruction in the error message. */
7486 md_operand (expressionS
* exp
)
7494 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
7495 for use in the a.out file, and stores them in the array pointed to by buf.
7496 This knows about the endian-ness of the target machine and does
7497 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
7498 2 (short) and 4 (long) Floating numbers are put out as a series of
7499 LITTLENUMS (shorts, here at least). */
7501 md_number_to_chars (char *buf
, valueT val
, int n
)
7504 s3_number_to_chars (buf
, val
, n
);
7506 s7_number_to_chars (buf
, val
, n
);
7509 /* Turn a string in input_line_pointer into a floating point constant
7510 of type TYPE, and store the appropriate bytes in *LITP. The number
7511 of LITTLENUMS emitted is stored in *SIZEP. An error message is
7512 returned, or NULL on OK.
7514 Note that fp constants aren't represent in the normal way on the ARM.
7515 In big endian mode, things are as expected. However, in little endian
7516 mode fp constants are big-endian word-wise, and little-endian byte-wise
7517 within the words. For example, (double) 1.1 in big endian mode is
7518 the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
7519 the byte sequence 99 99 f1 3f 9a 99 99 99. */
7521 md_atof (int type
, char *litP
, int *sizeP
)
7524 return s3_atof (type
, litP
, sizeP
);
7526 return s7_atof (type
, litP
, sizeP
);
7530 score_frag_check (fragS
* fragp ATTRIBUTE_UNUSED
)
7533 s3_frag_check (fragp
);
7535 s7_frag_check (fragp
);
7538 /* Implementation of TC_VALIDATE_FIX.
7539 Called before md_apply_fix() and after md_convert_frag(). */
7541 score_validate_fix (fixS
*fixP
)
7544 s3_validate_fix (fixP
);
7546 s7_validate_fix (fixP
);
7550 score_force_relocation (struct fix
*fixp
)
7553 return s3_force_relocation (fixp
);
7555 return s7_force_relocation (fixp
);
7558 /* Implementation of md_frag_check.
7559 Called after md_convert_frag(). */
7561 score_fix_adjustable (fixS
* fixP
)
7564 return s3_fix_adjustable (fixP
);
7566 return s7_fix_adjustable (fixP
);
7570 score_elf_final_processing (void)
7573 s3_elf_final_processing ();
7575 s7_elf_final_processing ();
7578 /* In this function, we determine whether s3_GP instruction should do relaxation,
7579 for the label being against was known now.
7580 Doing this here but not in md_relax_frag() can induce iteration times
7581 in stage of doing relax. */
7583 md_estimate_size_before_relax (fragS
* fragp
, asection
* sec ATTRIBUTE_UNUSED
)
7586 return s3_estimate_size_before_relax (fragp
, sec
);
7588 return s7_estimate_size_before_relax (fragp
, sec
);
7592 score_relax_frag (asection
* sec ATTRIBUTE_UNUSED
, fragS
* fragp
, long stretch ATTRIBUTE_UNUSED
)
7595 return s3_relax_frag (sec
, fragp
, stretch
);
7597 return s7_relax_frag (sec
, fragp
, stretch
);
7601 md_convert_frag (bfd
* abfd ATTRIBUTE_UNUSED
, segT sec ATTRIBUTE_UNUSED
, fragS
* fragp
)
7604 return s3_convert_frag (abfd
, sec
, fragp
);
7606 return s7_convert_frag (abfd
, sec
, fragp
);
7610 md_pcrel_from (fixS
* fixP
)
7613 return s3_pcrel_from (fixP
);
7615 return s7_pcrel_from (fixP
);
7618 /* Round up a section size to the appropriate boundary. */
7620 md_section_align (segT segment ATTRIBUTE_UNUSED
, valueT size
)
7623 return s3_section_align (segment
, size
);
7625 return s7_section_align (segment
, size
);
7629 md_apply_fix (fixS
*fixP
, valueT
*valP
, segT seg
)
7632 return s3_apply_fix (fixP
, valP
, seg
);
7634 return s7_apply_fix (fixP
, valP
, seg
);
7637 /* Translate internal representation of relocation info to BFD target format. */
7639 tc_gen_reloc (asection
* section ATTRIBUTE_UNUSED
, fixS
* fixp
)
7642 return s3_gen_reloc (section
, fixp
);
7644 return s7_gen_reloc (section
, fixp
);
7655 score_set_mach (const char *arg
)
7657 if (strcmp (arg
, MARCH_SCORE3
) == 0)
7663 else if (strcmp (arg
, MARCH_SCORE7
) == 0)
7668 s7_university_version
= 0;
7669 s7_vector_size
= s7_SCORE7_PIPELINE
;
7671 else if (strcmp (arg
, MARCH_SCORE5
) == 0)
7676 s7_university_version
= 0;
7677 s7_vector_size
= s7_SCORE5_PIPELINE
;
7679 else if (strcmp (arg
, MARCH_SCORE5U
) == 0)
7684 s7_university_version
= 1;
7685 s7_vector_size
= s7_SCORE5_PIPELINE
;
7689 as_bad (_("unknown architecture `%s'\n"), arg
);
7694 md_parse_option (int c
, const char *arg
)
7700 target_big_endian
= 1;
7705 target_big_endian
= 0;
7709 s3_fix_data_dependency
= 1;
7710 s7_fix_data_dependency
= 1;
7713 s3_warn_fix_data_dependency
= 0;
7714 s7_warn_fix_data_dependency
= 0;
7719 s7_university_version
= 0;
7720 s7_vector_size
= s7_SCORE5_PIPELINE
;
7722 case OPTION_SCORE5U
:
7725 s7_university_version
= 1;
7726 s7_vector_size
= s7_SCORE5_PIPELINE
;
7732 s7_university_version
= 0;
7733 s7_vector_size
= s7_SCORE7_PIPELINE
;
7745 s3_g_switch_value
= atoi (arg
);
7746 s7_g_switch_value
= atoi (arg
);
7752 case OPTION_SCORE_VERSION
:
7753 printf (_("Sunplus-v2-0-0-20060510\n"));
7756 s3_score_pic
= s3_NO_PIC
; /* Score3 doesn't support PIC now. */
7757 s7_score_pic
= s7_PIC
;
7758 s3_g_switch_value
= 0; /* Must set -G num as 0 to generate s3_PIC code. */
7759 s7_g_switch_value
= 0; /* Must set -G num as 0 to generate s7_PIC code. */
7762 score_set_mach (arg
);
7771 md_show_usage (FILE * fp
)
7773 fprintf (fp
, _(" Score-specific assembler options:\n"));
7776 -EB\t\tassemble code for a big-endian cpu\n"));
7781 -EL\t\tassemble code for a little-endian cpu\n"));
7785 -FIXDD\t\tfix data dependencies\n"));
7787 -NWARN\t\tdo not print warning message when fixing data dependencies\n"));
7789 -SCORE5\t\tassemble code for target SCORE5\n"));
7791 -SCORE5U\tassemble code for target SCORE5U\n"));
7793 -SCORE7\t\tassemble code for target SCORE7 [default]\n"));
7795 -SCORE3\t\tassemble code for target SCORE3\n"));
7797 -march=score7\tassemble code for target SCORE7 [default]\n"));
7799 -march=score3\tassemble code for target SCORE3\n"));
7801 -USE_R1\t\tassemble code for no warning message when using temp register r1\n"));
7803 -KPIC\t\tgenerate PIC\n"));
7805 -O0\t\tdo not perform any optimizations\n"));
7807 -G gpnum\tassemble code for setting gpsize, default is 8 bytes\n"));
7809 -V \t\tSunplus release version\n"));