1 /* tc-score.c -- Assembler for Score
2 Copyright (C) 2006-2018 Free Software Foundation, Inc.
4 Brain.lin (brain.lin@sunplusct.com)
5 Mei Ligang (ligang@sunnorth.com.cn)
6 Pei-Lin Tsai (pltsai@sunplus.com)
8 This file is part of GAS, the GNU Assembler.
10 GAS is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3, or (at your option)
15 GAS is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with GAS; see the file COPYING. If not, write to the Free
22 Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 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_MAX_LITTLENUMS 6
304 #define s3_INSN_NAME_LEN 16
306 /* Relax will need some padding for alignment. */
307 #define s3_RELAX_PAD_BYTE 3
310 #define s3_USE_GLOBAL_POINTER_OPT 1
312 /* Enumeration matching entries in table above. */
313 enum s3_score_reg_type
315 s3_REG_TYPE_SCORE
= 0,
316 #define s3_REG_TYPE_FIRST s3_REG_TYPE_SCORE
317 s3_REG_TYPE_SCORE_SR
= 1,
318 s3_REG_TYPE_SCORE_CR
= 2,
322 enum s3_score_pic_level
327 static enum s3_score_pic_level s3_score_pic
= s3_NO_PIC
;
329 enum s3_insn_type_for_dependency
335 struct s3_insn_to_dependency
337 const char *insn_name
;
338 enum s3_insn_type_for_dependency type
;
341 struct s3_data_dependency
343 enum s3_insn_type_for_dependency pre_insn_type
;
345 enum s3_insn_type_for_dependency cur_insn_type
;
349 int warn_or_error
; /* warning - 0; error - 1 */
352 static const struct s3_insn_to_dependency s3_insn_to_dependency_table
[] =
354 /* move special instruction. */
358 static const struct s3_data_dependency s3_data_dependency_table
[] =
360 /* Status register. */
361 {s3_D_mtcr
, "cr0", s3_D_all_insn
, "", 5, 1, 0},
364 /* Used to contain constructed error messages. */
365 static char s3_err_msg
[255];
367 static int s3_fix_data_dependency
= 0;
368 static int s3_warn_fix_data_dependency
= 1;
370 static int s3_in_my_get_expression
= 0;
372 /* Default, pop warning message when using r1. */
373 static int s3_nor1
= 1;
375 /* Default will do instruction relax, -O0 will set s3_g_opt = 0. */
376 static unsigned int s3_g_opt
= 1;
378 /* The size of the small data section. */
379 static unsigned int s3_g_switch_value
= 8;
381 static segT s3_pdr_seg
;
385 char name
[s3_INSN_NAME_LEN
];
390 enum score_insn_type type
;
391 char str
[s3_MAX_LITERAL_POOL_SIZE
];
394 char reg
[s3_INSN_NAME_LEN
];
397 bfd_reloc_code_real_type type
;
402 static struct s3_score_it s3_inst
;
404 typedef struct s3_proc
407 unsigned long reg_mask
;
408 unsigned long reg_offset
;
409 unsigned long fpreg_mask
;
411 unsigned long frame_offset
;
412 unsigned long frame_reg
;
413 unsigned long pc_reg
;
415 static s3_procS s3_cur_proc
;
416 static s3_procS
*s3_cur_proc_ptr
;
417 static int s3_numprocs
;
420 /* Structure for a hash table entry for a register. */
427 static const struct s3_reg_entry s3_score_rn_table
[] =
429 {"r0", 0}, {"r1", 1}, {"r2", 2}, {"r3", 3},
430 {"r4", 4}, {"r5", 5}, {"r6", 6}, {"r7", 7},
431 {"r8", 8}, {"r9", 9}, {"r10", 10}, {"r11", 11},
432 {"r12", 12}, {"r13", 13}, {"r14", 14}, {"r15", 15},
433 {"r16", 16}, {"r17", 17}, {"r18", 18}, {"r19", 19},
434 {"r20", 20}, {"r21", 21}, {"r22", 22}, {"r23", 23},
435 {"r24", 24}, {"r25", 25}, {"r26", 26}, {"r27", 27},
436 {"r28", 28}, {"r29", 29}, {"r30", 30}, {"r31", 31},
440 static const struct s3_reg_entry s3_score_srn_table
[] =
442 {"sr0", 0}, {"sr1", 1}, {"sr2", 2},
446 static const struct s3_reg_entry s3_score_crn_table
[] =
448 {"cr0", 0}, {"cr1", 1}, {"cr2", 2}, {"cr3", 3},
449 {"cr4", 4}, {"cr5", 5}, {"cr6", 6}, {"cr7", 7},
450 {"cr8", 8}, {"cr9", 9}, {"cr10", 10}, {"cr11", 11},
451 {"cr12", 12}, {"cr13", 13}, {"cr14", 14}, {"cr15", 15},
452 {"cr16", 16}, {"cr17", 17}, {"cr18", 18}, {"cr19", 19},
453 {"cr20", 20}, {"cr21", 21}, {"cr22", 22}, {"cr23", 23},
454 {"cr24", 24}, {"cr25", 25}, {"cr26", 26}, {"cr27", 27},
455 {"cr28", 28}, {"cr29", 29}, {"cr30", 30}, {"cr31", 31},
461 const struct s3_reg_entry
*names
;
463 struct hash_control
*htab
;
464 const char *expected
;
467 static struct s3_reg_map s3_all_reg_maps
[] =
469 {s3_score_rn_table
, 31, NULL
, N_("S+core register expected")},
470 {s3_score_srn_table
, 2, NULL
, N_("S+core special-register expected")},
471 {s3_score_crn_table
, 31, NULL
, N_("S+core co-processor register expected")},
474 static struct hash_control
*s3_score_ops_hsh
= NULL
;
475 static struct hash_control
*s3_dependency_insn_hsh
= NULL
;
478 struct s3_datafield_range
485 static struct s3_datafield_range s3_score_df_range
[] =
487 {_IMM4
, 4, {0, (1 << 4) - 1}}, /* ( 0 ~ 15 ) */
488 {_IMM5
, 5, {0, (1 << 5) - 1}}, /* ( 0 ~ 31 ) */
489 {_IMM8
, 8, {0, (1 << 8) - 1}}, /* ( 0 ~ 255 ) */
490 {_IMM14
, 14, {0, (1 << 14) - 1}}, /* ( 0 ~ 16383) */
491 {_IMM15
, 15, {0, (1 << 15) - 1}}, /* ( 0 ~ 32767) */
492 {_IMM16
, 16, {0, (1 << 16) - 1}}, /* ( 0 ~ 65535) */
493 {_SIMM10
, 10, {-(1 << 9), (1 << 9) - 1}}, /* ( -512 ~ 511 ) */
494 {_SIMM12
, 12, {-(1 << 11), (1 << 11) - 1}}, /* ( -2048 ~ 2047 ) */
495 {_SIMM14
, 14, {-(1 << 13), (1 << 13) - 1}}, /* ( -8192 ~ 8191 ) */
496 {_SIMM15
, 15, {-(1 << 14), (1 << 14) - 1}}, /* (-16384 ~ 16383) */
497 {_SIMM16
, 16, {-(1 << 15), (1 << 15) - 1}}, /* (-32768 ~ 32767) */
498 {_SIMM14_NEG
, 14, {-(1 << 13), (1 << 13) - 1}}, /* ( -8191 ~ 8192 ) */
499 {_IMM16_NEG
, 16, {0, (1 << 16) - 1}}, /* (-65535 ~ 0 ) */
500 {_SIMM16_NEG
, 16, {-(1 << 15), (1 << 15) - 1}}, /* (-32768 ~ 32767) */
501 {_IMM20
, 20, {0, (1 << 20) - 1}},
502 {_IMM25
, 25, {0, (1 << 25) - 1}},
503 {_DISP8div2
, 8, {-(1 << 8), (1 << 8) - 1}}, /* ( -256 ~ 255 ) */
504 {_DISP11div2
, 11, {0, 0}},
505 {_DISP19div2
, 19, {-(1 << 19), (1 << 19) - 1}}, /* (-524288 ~ 524287) */
506 {_DISP24div2
, 24, {0, 0}},
507 {_VALUE
, 32, {0, ((unsigned int)1 << 31) - 1}},
508 {_VALUE_HI16
, 16, {0, (1 << 16) - 1}},
509 {_VALUE_LO16
, 16, {0, (1 << 16) - 1}},
510 {_VALUE_LDST_LO16
, 16, {0, (1 << 16) - 1}},
511 {_SIMM16_LA
, 16, {-(1 << 15), (1 << 15) - 1}}, /* (-32768 ~ 32767) */
512 {_IMM5_RSHIFT_1
, 5, {0, (1 << 6) - 1}}, /* ( 0 ~ 63 ) */
513 {_IMM5_RSHIFT_2
, 5, {0, (1 << 7) - 1}}, /* ( 0 ~ 127 ) */
514 {_SIMM16_LA_POS
, 16, {0, (1 << 15) - 1}}, /* ( 0 ~ 32767) */
515 {_IMM5_RANGE_8_31
, 5, {8, 31}}, /* But for cop0 the valid data : (8 ~ 31). */
516 {_IMM10_RSHIFT_2
, 10, {-(1 << 11), (1 << 11) - 1}}, /* For ldc#, stc#. */
517 {_SIMM10
, 10, {0, (1 << 10) - 1}}, /* ( -1024 ~ 1023 ) */
518 {_SIMM12
, 12, {0, (1 << 12) - 1}}, /* ( -2048 ~ 2047 ) */
519 {_SIMM14
, 14, {0, (1 << 14) - 1}}, /* ( -8192 ~ 8191 ) */
520 {_SIMM15
, 15, {0, (1 << 15) - 1}}, /* (-16384 ~ 16383) */
521 {_SIMM16
, 16, {0, (1 << 16) - 1}}, /* (-65536 ~ 65536) */
522 {_SIMM14_NEG
, 14, {0, (1 << 16) - 1}}, /* ( -8191 ~ 8192 ) */
523 {_IMM16_NEG
, 16, {0, (1 << 16) - 1}}, /* ( 65535 ~ 0 ) */
524 {_SIMM16_NEG
, 16, {0, (1 << 16) - 1}}, /* ( 65535 ~ 0 ) */
525 {_IMM20
, 20, {0, (1 << 20) - 1}}, /* (-32768 ~ 32767) */
526 {_IMM25
, 25, {0, (1 << 25) - 1}}, /* (-32768 ~ 32767) */
527 {_GP_IMM15
, 15, {0, (1 << 15) - 1}}, /* ( 0 ~ 65535) */
528 {_GP_IMM14
, 14, {0, (1 << 14) - 1}}, /* ( 0 ~ 65535) */
529 {_SIMM16_pic
, 16, {-(1 << 15), (1 << 15) - 1}}, /* (-32768 ~ 32767) */
530 {_IMM16_LO16_pic
, 16, {0, (1 << 16) - 1}}, /* ( 65535 ~ 0 ) */
531 {_IMM16_pic
, 16, {0, (1 << 16) - 1}}, /* ( 0 ~ 65535) */
532 {_SIMM5
, 5, {-(1 << 4), (1 << 4) - 1}}, /* ( -16 ~ 15 ) */
533 {_SIMM6
, 6, {-(1 << 5), (1 << 5) - 1}}, /* ( -32 ~ 31 ) */
534 {_IMM32
, 32, {0, 0xfffffff}},
535 {_SIMM32
, 32, {-0x80000000, 0x7fffffff}},
536 {_IMM11
, 11, {0, (1 << 11) - 1}},
541 /* Instruction name. */
542 const char *template_name
;
544 /* Instruction Opcode. */
547 /* Instruction bit mask. */
550 /* Relax instruction opcode. 0x8000 imply no relaxation. */
553 /* Instruction type. */
554 enum score_insn_type type
;
556 /* Function to call to parse args. */
557 void (*parms
) (char *);
560 static const struct s3_asm_opcode s3_score_ldst_insns
[] =
562 {"lw", 0x20000000, 0x3e000000, 0x1000, Rd_rvalueRs_SI15
, s3_do_ldst_insn
},
563 {"lw", 0x06000000, 0x3e000007, 0x8000, Rd_rvalueRs_preSI12
, s3_do_ldst_insn
},
564 {"lw", 0x0e000000, 0x3e000007, 0x0040, Rd_rvalueRs_postSI12
, s3_do_ldst_insn
},
565 {"lh", 0x22000000, 0x3e000000, 0x8000, Rd_rvalueRs_SI15
, s3_do_ldst_insn
},
566 {"lh", 0x06000001, 0x3e000007, 0x8000, Rd_rvalueRs_preSI12
, s3_do_ldst_insn
},
567 {"lh", 0x0e000001, 0x3e000007, 0x8000, Rd_rvalueRs_postSI12
, s3_do_ldst_insn
},
568 {"lhu", 0x24000000, 0x3e000000, 0x8000, Rd_rvalueRs_SI15
, s3_do_ldst_insn
},
569 {"lhu", 0x06000002, 0x3e000007, 0x8000, Rd_rvalueRs_preSI12
, s3_do_ldst_insn
},
570 {"lhu", 0x0e000002, 0x3e000007, 0x8000, Rd_rvalueRs_postSI12
, s3_do_ldst_insn
},
571 {"lb", 0x26000000, 0x3e000000, 0x8000, Rd_rvalueRs_SI15
, s3_do_ldst_insn
},
572 {"lb", 0x06000003, 0x3e000007, 0x8000, Rd_rvalueRs_preSI12
, s3_do_ldst_insn
},
573 {"lb", 0x0e000003, 0x3e000007, 0x8000, Rd_rvalueRs_postSI12
, s3_do_ldst_insn
},
574 {"sw", 0x28000000, 0x3e000000, 0x2000, Rd_lvalueRs_SI15
, s3_do_ldst_insn
},
575 {"sw", 0x06000004, 0x3e000007, 0x0060, Rd_lvalueRs_preSI12
, s3_do_ldst_insn
},
576 {"sw", 0x0e000004, 0x3e000007, 0x8000, Rd_lvalueRs_postSI12
, s3_do_ldst_insn
},
577 {"sh", 0x2a000000, 0x3e000000, 0x8000, Rd_lvalueRs_SI15
, s3_do_ldst_insn
},
578 {"sh", 0x06000005, 0x3e000007, 0x8000, Rd_lvalueRs_preSI12
, s3_do_ldst_insn
},
579 {"sh", 0x0e000005, 0x3e000007, 0x8000, Rd_lvalueRs_postSI12
, s3_do_ldst_insn
},
580 {"lbu", 0x2c000000, 0x3e000000, 0x8000, Rd_rvalueRs_SI15
, s3_do_ldst_insn
},
581 {"lbu", 0x06000006, 0x3e000007, 0x8000, Rd_rvalueRs_preSI12
, s3_do_ldst_insn
},
582 {"lbu", 0x0e000006, 0x3e000007, 0x8000, Rd_rvalueRs_postSI12
, s3_do_ldst_insn
},
583 {"sb", 0x2e000000, 0x3e000000, 0x8000, Rd_lvalueRs_SI15
, s3_do_ldst_insn
},
584 {"sb", 0x06000007, 0x3e000007, 0x8000, Rd_lvalueRs_preSI12
, s3_do_ldst_insn
},
585 {"sb", 0x0e000007, 0x3e000007, 0x8000, Rd_lvalueRs_postSI12
, s3_do_ldst_insn
},
588 static const struct s3_asm_opcode s3_score_insns
[] =
590 {"abs", 0x3800000a, 0x3e007fff, 0x8000, Rd_Rs_x
, s3_do_dsp3
},
591 {"abs.s", 0x3800004b, 0x3e007fff, 0x8000, Rd_Rs_x
, s3_do_dsp3
},
592 {"add", 0x00000010, 0x3e0003ff, 0x4800, Rd_Rs_Rs
, s3_do_rdrsrs
},
593 {"add.c", 0x00000011, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_rdrsrs
},
594 {"add.s", 0x38000048, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_dsp2
},
595 {"addc", 0x00000012, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_rdrsrs
},
596 {"addc.c", 0x00000013, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_rdrsrs
},
597 {"addi", 0x02000000, 0x3e0e0001, 0x5c00, Rd_SI16
, s3_do_rdsi16
},
598 {"addi.c", 0x02000001, 0x3e0e0001, 0x8000, Rd_SI16
, s3_do_rdsi16
},
599 {"addis", 0x0a000000, 0x3e0e0001, 0x8000, Rd_SI16
, s3_do_rdi16
},
600 {"addis.c", 0x0a000001, 0x3e0e0001, 0x8000, Rd_SI16
, s3_do_rdi16
},
601 {"addi!", 0x5c00, 0x7c00, 0x8000, Rd_SI6
, s3_do16_addi
},
602 {"addri", 0x10000000, 0x3e000001, 0x8000, Rd_Rs_SI14
, s3_do_rdrssi14
},
603 {"addri.c", 0x10000001, 0x3e000001, 0x8000, Rd_Rs_SI14
, s3_do_rdrssi14
},
605 /* add.c <-> add!. */
606 {"add!", 0x4800, 0x7f00, 0x8000, Rd_Rs
, s3_do16_rdrs2
},
607 {"subi", 0x02000000, 0x3e0e0001, 0x8000, Rd_SI16
, s3_do_sub_rdsi16
},
608 {"subi.c", 0x02000001, 0x3e0e0001, 0x8000, Rd_SI16
, s3_do_sub_rdsi16
},
609 {"subis", 0x0a000000, 0x3e0e0001, 0x8000, Rd_SI16
, s3_do_sub_rdi16
},
610 {"subis.c", 0x0a000001, 0x3e0e0001, 0x8000, Rd_SI16
, s3_do_sub_rdi16
},
611 {"subri", 0x10000000, 0x3e000001, 0x8000, Rd_Rs_SI14
, s3_do_sub_rdrssi14
},
612 {"subri.c", 0x10000001, 0x3e000001, 0x8000, Rd_Rs_SI14
, s3_do_sub_rdrssi14
},
613 {"and", 0x00000020, 0x3e0003ff, 0x4b00, Rd_Rs_Rs
, s3_do_rdrsrs
},
614 {"and.c", 0x00000021, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_rdrsrs
},
615 {"andi", 0x02080000, 0x3e0e0001, 0x8000, Rd_I16
, s3_do_rdi16
},
616 {"andi.c", 0x02080001, 0x3e0e0001, 0x8000, Rd_I16
, s3_do_rdi16
},
617 {"andis", 0x0a080000, 0x3e0e0001, 0x8000, Rd_I16
, s3_do_rdi16
},
618 {"andis.c", 0x0a080001, 0x3e0e0001, 0x8000, Rd_I16
, s3_do_rdi16
},
619 {"andri", 0x18000000, 0x3e000001, 0x8000, Rd_Rs_I14
, s3_do_rdrsi14
},
620 {"andri.c", 0x18000001, 0x3e000001, 0x8000, Rd_Rs_I14
, s3_do_rdrsi14
},
622 /* and.c <-> and!. */
623 {"and!", 0x4b00, 0x7f00, 0x8000, Rd_Rs
, s3_do16_rdrs2
},
624 {"bcs", 0x08000000, 0x3e007c01, 0x8000, PC_DISP19div2
, s3_do_branch
},
625 {"bcc", 0x08000400, 0x3e007c01, 0x8000, PC_DISP19div2
, s3_do_branch
},
626 {"bcnz", 0x08003800, 0x3e007c01, 0x3200, PC_DISP19div2
, s3_do_branch
},
627 {"bcsl", 0x08000001, 0x3e007c01, 0x8000, PC_DISP19div2
, s3_do_branch
},
628 {"bccl", 0x08000401, 0x3e007c01, 0x8000, PC_DISP19div2
, s3_do_branch
},
629 {"bcnzl", 0x08003801, 0x3e007c01, 0x8000, PC_DISP19div2
, s3_do_branch
},
630 {"bcnz!", 0x3200, 0x7f00, 0x08003800, PC_DISP8div2
, s3_do16_branch
},
631 {"beq", 0x08001000, 0x3e007c01, 0x3800, PC_DISP19div2
, s3_do_branch
},
632 {"beql", 0x08001001, 0x3e007c01, 0x8000, PC_DISP19div2
, s3_do_branch
},
633 {"beq!", 0x3800, 0x7e00, 0x08001000, PC_DISP8div2
, s3_do16_branch
},
634 {"bgtu", 0x08000800, 0x3e007c01, 0x3400, PC_DISP19div2
, s3_do_branch
},
635 {"bgt", 0x08001800, 0x3e007c01, 0x3c00, PC_DISP19div2
, s3_do_branch
},
636 {"bge", 0x08002000, 0x3e007c01, 0x8000, PC_DISP19div2
, s3_do_branch
},
637 {"bgtul", 0x08000801, 0x3e007c01, 0x8000, PC_DISP19div2
, s3_do_branch
},
638 {"bgtl", 0x08001801, 0x3e007c01, 0x8000, PC_DISP19div2
, s3_do_branch
},
639 {"bgel", 0x08002001, 0x3e007c01, 0x8000, PC_DISP19div2
, s3_do_branch
},
640 {"bgtu!", 0x3400, 0x7e00, 0x08000800, PC_DISP8div2
, s3_do16_branch
},
641 {"bgt!", 0x3c00, 0x7e00, 0x08001800, PC_DISP8div2
, s3_do16_branch
},
642 {"bitclr", 0x00000028, 0x3e0003ff, 0x5000, Rd_Rs_I5
, s3_do_rdrsi5
},
643 {"bitclr.c", 0x00000029, 0x3e0003ff, 0x8000, Rd_Rs_I5
, s3_do_rdrsi5
},
645 {"mbitclr", 0x00000064, 0x3e00007e, 0x8000, Ra_I9_I5
, s3_do_mbitclr
},
646 {"mbitset", 0x0000006c, 0x3e00007e, 0x8000, Ra_I9_I5
, s3_do_mbitset
},
648 {"bitrev", 0x3800000c, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_dsp2
},
649 {"bitset", 0x0000002a, 0x3e0003ff, 0x5200, Rd_Rs_I5
, s3_do_rdrsi5
},
650 {"bitset.c", 0x0000002b, 0x3e0003ff, 0x8000, Rd_Rs_I5
, s3_do_rdrsi5
},
651 {"bittst.c", 0x0000002d, 0x3e0003ff, 0x5400, x_Rs_I5
, s3_do_xrsi5
},
652 {"bittgl", 0x0000002e, 0x3e0003ff, 0x5600, Rd_Rs_I5
, s3_do_rdrsi5
},
653 {"bittgl.c", 0x0000002f, 0x3e0003ff, 0x8000, Rd_Rs_I5
, s3_do_rdrsi5
},
654 {"bitclr!", 0x5000, 0x7e00, 0x8000, Rd_I5
, s3_do16_rdi5
},
655 {"bitset!", 0x5200, 0x7e00, 0x8000, Rd_I5
, s3_do16_rdi5
},
656 {"bittst!", 0x5400, 0x7e00, 0x8000, Rd_I5
, s3_do16_rdi5
},
657 {"bittgl!", 0x5600, 0x7e00, 0x8000, Rd_I5
, s3_do16_rdi5
},
658 {"bleu", 0x08000c00, 0x3e007c01, 0x3600, PC_DISP19div2
, s3_do_branch
},
659 {"ble", 0x08001c00, 0x3e007c01, 0x3e00, PC_DISP19div2
, s3_do_branch
},
660 {"blt", 0x08002400, 0x3e007c01, 0x8000, PC_DISP19div2
, s3_do_branch
},
661 {"bleul", 0x08000c01, 0x3e007c01, 0x8000, PC_DISP19div2
, s3_do_branch
},
662 {"blel", 0x08001c01, 0x3e007c01, 0x8000, PC_DISP19div2
, s3_do_branch
},
663 {"bltl", 0x08002401, 0x3e007c01, 0x8000, PC_DISP19div2
, s3_do_branch
},
664 {"bl", 0x08003c01, 0x3e007c01, 0x8000, PC_DISP19div2
, s3_do_branch
},
665 {"bleu!", 0x3600, 0x7e00, 0x08000c00, PC_DISP8div2
, s3_do16_branch
},
666 {"ble!", 0x3e00, 0x7e00, 0x08001c00, PC_DISP8div2
, s3_do16_branch
},
667 {"bmi", 0x08002800, 0x3e007c01, 0x8000, PC_DISP19div2
, s3_do_branch
},
668 {"bmil", 0x08002801, 0x3e007c01, 0x8000, PC_DISP19div2
, s3_do_branch
},
669 {"bne", 0x08001400, 0x3e007c01, 0x3a00, PC_DISP19div2
, s3_do_branch
},
670 {"bnel", 0x08001401, 0x3e007c01, 0x8000, PC_DISP19div2
, s3_do_branch
},
671 {"bne!", 0x3a00, 0x7e00, 0x08001400, PC_DISP8div2
, s3_do16_branch
},
672 {"bpl", 0x08002c00, 0x3e007c01, 0x8000, PC_DISP19div2
, s3_do_branch
},
673 {"bpll", 0x08002c01, 0x3e007c01, 0x8000, PC_DISP19div2
, s3_do_branch
},
674 {"brcs", 0x00000008, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
675 {"brcc", 0x00000408, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
676 {"brgtu", 0x00000808, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
677 {"brleu", 0x00000c08, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
678 {"breq", 0x00001008, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
679 {"brne", 0x00001408, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
680 {"brgt", 0x00001808, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
681 {"brle", 0x00001c08, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
682 {"brge", 0x00002008, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
683 {"brlt", 0x00002408, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
684 {"brmi", 0x00002808, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
685 {"brpl", 0x00002c08, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
686 {"brvs", 0x00003008, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
687 {"brvc", 0x00003408, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
688 {"brcnz", 0x00003808, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
689 {"br", 0x00003c08, 0x3e007fff, 0x0080, x_Rs_x
, s3_do_rs
},
690 {"brcsl", 0x00000009, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
691 {"brccl", 0x00000409, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
692 {"brgtul", 0x00000809, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
693 {"brleul", 0x00000c09, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
694 {"breql", 0x00001009, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
695 {"brnel", 0x00001409, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
696 {"brgtl", 0x00001809, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
697 {"brlel", 0x00001c09, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
698 {"brgel", 0x00002009, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
699 {"brltl", 0x00002409, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
700 {"brmil", 0x00002809, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
701 {"brpll", 0x00002c09, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
702 {"brvsl", 0x00003009, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
703 {"brvcl", 0x00003409, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
704 {"brcnzl", 0x00003809, 0x3e007fff, 0x8000, x_Rs_x
, s3_do_rs
},
705 {"brl", 0x00003c09, 0x3e007fff, 0x00a0, x_Rs_x
, s3_do_rs
},
706 {"br!", 0x0080, 0x7fe0, 0x8000, x_Rs
, s3_do16_br
},
707 {"brl!", 0x00a0, 0x7fe0, 0x8000, x_Rs
, s3_do16_br
},
708 {"brr!", 0x00c0, 0x7fe0, 0x8000, x_Rs
, s3_do16_brr
},
709 {"bvs", 0x08003000, 0x3e007c01, 0x8000, PC_DISP19div2
, s3_do_branch
},
710 {"bvc", 0x08003400, 0x3e007c01, 0x8000, PC_DISP19div2
, s3_do_branch
},
711 {"bvsl", 0x08003001, 0x3e007c01, 0x8000, PC_DISP19div2
, s3_do_branch
},
712 {"bvcl", 0x08003401, 0x3e007c01, 0x8000, PC_DISP19div2
, s3_do_branch
},
713 {"b!", 0x3000, 0x7e00, 0x08003c00, PC_DISP8div2
, s3_do16_branch
},
714 {"b", 0x08003c00, 0x3e007c01, 0x3000, PC_DISP19div2
, s3_do_branch
},
715 {"cache", 0x30000000, 0x3ff00000, 0x8000, OP5_rvalueRs_SI15
, s3_do_cache
},
716 {"ceinst", 0x38000000, 0x3e000000, 0x8000, I5_Rs_Rs_I5_OP5
, s3_do_ceinst
},
717 {"clz", 0x0000001c, 0x3e007fff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
718 {"cmp.c", 0x00300019, 0x3ff003ff, 0x4400, x_Rs_Rs
, s3_do_rsrs
},
719 {"cmpz.c", 0x0030001b, 0x3ff07fff, 0x8000, x_Rs_x
, s3_do_rs
},
720 {"cmpi.c", 0x02040001, 0x3e0e0001, 0x6000, Rd_SI16
, s3_do_rdsi16
},
722 /* cmp.c <-> cmp!. */
723 {"cmp!", 0x4400, 0x7c00, 0x8000, Rd_Rs
, s3_do16_mv_cmp
},
724 {"cmpi!", 0x6000, 0x7c00, 0x8000, Rd_SI5
, s3_do16_cmpi
},
725 {"cop1", 0x0c00000c, 0x3e00001f, 0x8000, Rd_Rs_Rs_imm
, s3_do_crdcrscrsimm5
},
726 {"cop2", 0x0c000014, 0x3e00001f, 0x8000, Rd_Rs_Rs_imm
, s3_do_crdcrscrsimm5
},
727 {"cop3", 0x0c00001c, 0x3e00001f, 0x8000, Rd_Rs_Rs_imm
, s3_do_crdcrscrsimm5
},
728 {"drte", 0x0c0000a4, 0x3e0003ff, 0x8000, NO_OPD
, s3_do_empty
},
729 {"disint!", 0x00e0, 0xffe1, 0x8000, NO16_OPD
, s3_do16_int
},
730 {"enint!", 0x00e1, 0xffe1, 0x8000, NO16_OPD
, s3_do16_int
},
731 {"extsb", 0x00000058, 0x3e0003ff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
732 {"extsb.c", 0x00000059, 0x3e0003ff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
733 {"extsh", 0x0000005a, 0x3e0003ff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
734 {"extsh.c", 0x0000005b, 0x3e0003ff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
735 {"extzb", 0x0000005c, 0x3e0003ff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
736 {"extzb.c", 0x0000005d, 0x3e0003ff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
737 {"extzh", 0x0000005e, 0x3e0003ff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
738 {"extzh.c", 0x0000005f, 0x3e0003ff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
739 {"jl", 0x04000001, 0x3e000001, 0x8000, PC_DISP24div2
, s3_do_jump
},
740 {"j", 0x04000000, 0x3e000001, 0x8000, PC_DISP24div2
, s3_do_jump
},
741 {"alw", 0x0000000c, 0x3e0003ff, 0x8000, Rd_rvalue32Rs
, s3_do_ldst_atomic
},
742 {"lcb", 0x00000060, 0x3e0003ff, 0x8000, x_rvalueRs_post4
, s3_do_ldst_unalign
},
743 {"lcw", 0x00000062, 0x3e0003ff, 0x8000, Rd_rvalueRs_post4
, s3_do_ldst_unalign
},
744 {"lce", 0x00000066, 0x3e0003ff, 0x8000, Rd_rvalueRs_post4
, s3_do_ldst_unalign
},
745 {"ldc1", 0x0c00000a, 0x3e00001f, 0x8000, Rd_rvalueRs_SI10
, s3_do_ldst_cop
},
746 {"ldc2", 0x0c000012, 0x3e00001f, 0x8000, Rd_rvalueRs_SI10
, s3_do_ldst_cop
},
747 {"ldc3", 0x0c00001a, 0x3e00001f, 0x8000, Rd_rvalueRs_SI10
, s3_do_ldst_cop
},
750 {"ldi", 0x020c0000, 0x3e0e0000, 0x6400, Rd_SI16
, s3_do_rdsi16
},
751 {"ldis", 0x0a0c0000, 0x3e0e0000, 0x8000, Rd_I16
, s3_do_ldis
},
754 {"ldiu!", 0x6400, 0x7c00, 0x8000, Rd_I5
, s3_do16_ldiu
},
756 /*ltbb! , ltbh! ltbw! */
757 {"ltbw", 0x00000032, 0x03ff, 0x8000, Rd_Rs_Rs
, s3_do_ltb
},
758 {"ltbh", 0x00000132, 0x03ff, 0x8000, Rd_Rs_Rs
, s3_do_ltb
},
759 {"ltbb", 0x00000332, 0x03ff, 0x8000, Rd_Rs_Rs
, s3_do_ltb
},
760 {"lw!", 0x1000, 0x7000, 0x8000, Rd_rvalueRs
, s3_do16_ldst_insn
},
761 {"mfcel", 0x00000448, 0x3e007fff, 0x8000, Rd_x_x
, s3_do_rd
},
762 {"mfcel!", 0x7100, 0x7ff0, 0x00000448, x_Rs
, s3_do16_dsp
},
763 {"mad", 0x38000000, 0x3ff003ff, 0x8000, x_Rs_Rs
, s3_do_dsp
},
764 {"mad.f!", 0x7400, 0x7f00, 0x38000080, Rd_Rs
, s3_do16_dsp2
},
765 {"madh", 0x38000203, 0x3ff003ff, 0x8000, x_Rs_Rs
, s3_do_dsp
},
766 {"madh.fs", 0x380002c3, 0x3ff003ff, 0x8000, x_Rs_Rs
, s3_do_dsp
},
767 {"madh.fs!", 0x7b00, 0x7f00, 0x380002c3, Rd_Rs
, s3_do16_dsp2
},
768 {"madl", 0x38000002, 0x3ff003ff, 0x8000, x_Rs_Rs
, s3_do_dsp
},
769 {"madl.fs", 0x380000c2, 0x3ff003ff, 0x8000, x_Rs_Rs
, s3_do_dsp
},
770 {"madl.fs!", 0x7a00, 0x7f00, 0x380000c2, Rd_Rs
, s3_do16_dsp2
},
771 {"madu", 0x38000020, 0x3ff003ff, 0x8000, x_Rs_Rs
, s3_do_dsp
},
772 {"madu!", 0x7500, 0x7f00, 0x38000020, Rd_Rs
, s3_do16_dsp2
},
773 {"mad.f", 0x38000080, 0x3ff003ff, 0x8000, x_Rs_Rs
, s3_do_dsp
},
774 {"max", 0x38000007, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_dsp2
},
775 {"mazh", 0x38000303, 0x3ff003ff, 0x8000, x_Rs_Rs
, s3_do_dsp
},
776 {"mazh.f", 0x38000383, 0x3ff003ff, 0x8000, x_Rs_Rs
, s3_do_dsp
},
777 {"mazh.f!", 0x7900, 0x7f00, 0x3800038c, Rd_Rs
, s3_do16_dsp2
},
778 {"mazl", 0x38000102, 0x3ff003ff, 0x8000, x_Rs_Rs
, s3_do_dsp
},
779 {"mazl.f", 0x38000182, 0x3ff003ff, 0x8000, x_Rs_Rs
, s3_do_dsp
},
780 {"mazl.f!", 0x7800, 0x7f00, 0x38000182, Rd_Rs
, s3_do16_dsp2
},
781 {"mfceh", 0x00000848, 0x3e007fff, 0x8000, Rd_x_x
, s3_do_rd
},
782 {"mfceh!", 0x7110, 0x7ff0, 0x00000848, x_Rs
, s3_do16_dsp
},
783 {"mfcehl", 0x00000c48, 0x3e007fff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
784 {"mfsr", 0x00000050, 0x3e0003ff, 0x8000, Rd_x_I5
, s3_do_rdsrs
},
785 {"mfcr", 0x0c000001, 0x3e00001f, 0x8000, Rd_Rs_x
, s3_do_rdcrs
},
786 {"mfc1", 0x0c000009, 0x3e00001f, 0x8000, Rd_Rs_x
, s3_do_rdcrs
},
787 {"mfc2", 0x0c000011, 0x3e00001f, 0x8000, Rd_Rs_x
, s3_do_rdcrs
},
788 {"mfc3", 0x0c000019, 0x3e00001f, 0x8000, Rd_Rs_x
, s3_do_rdcrs
},
789 {"mfcc1", 0x0c00000f, 0x3e00001f, 0x8000, Rd_Rs_x
, s3_do_rdcrs
},
790 {"mfcc2", 0x0c000017, 0x3e00001f, 0x8000, Rd_Rs_x
, s3_do_rdcrs
},
791 {"mfcc3", 0x0c00001f, 0x3e00001f, 0x8000, Rd_Rs_x
, s3_do_rdcrs
},
792 {"min", 0x38000006, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_dsp2
},
793 {"msb", 0x38000001, 0x3ff003ff, 0x8000, x_Rs_Rs
, s3_do_dsp
},
794 {"msb.f!", 0x7600, 0x7f00, 0x38000081, Rd_Rs
, s3_do16_dsp2
},
795 {"msbh", 0x38000205, 0x3ff003ff, 0x8000, x_Rs_Rs
, s3_do_dsp
},
796 {"msbh.fs", 0x380002c5, 0x3ff003ff, 0x8000, x_Rs_Rs
, s3_do_dsp
},
797 {"msbh.fs!", 0x7f00, 0x7f00, 0x380002c5, Rd_Rs
, s3_do16_dsp2
},
798 {"msbl", 0x38000004, 0x3ff003ff, 0x8000, x_Rs_Rs
, s3_do_dsp
},
799 {"msbl.fs", 0x380000c4, 0x3ff003ff, 0x8000, x_Rs_Rs
, s3_do_dsp
},
800 {"msbl.fs!", 0x7e00, 0x7f00, 0x380000c4, Rd_Rs
, s3_do16_dsp2
},
801 {"msbu", 0x38000021, 0x3ff003ff, 0x8000, x_Rs_Rs
, s3_do_dsp
},
802 {"msbu!", 0x7700, 0x7f00, 0x38000021, Rd_Rs
, s3_do16_dsp2
},
803 {"msb.f", 0x38000081, 0x3ff003ff, 0x8000, x_Rs_Rs
, s3_do_dsp
},
804 {"mszh", 0x38000305, 0x3ff003ff, 0x8000, x_Rs_Rs
, s3_do_dsp
},
805 {"mszh.f", 0x38000385, 0x3ff003ff, 0x8000, x_Rs_Rs
, s3_do_dsp
},
806 {"mszh.f!", 0x7d00, 0x7f00, 0x38000385, Rd_Rs
, s3_do16_dsp2
},
807 {"mszl", 0x38000104, 0x3ff003ff, 0x8000, x_Rs_Rs
, s3_do_dsp
},
808 {"mszl.f", 0x38000184, 0x3ff003ff, 0x8000, x_Rs_Rs
, s3_do_dsp
},
809 {"mszl.f!", 0x7c00, 0x7f00, 0x38000184, Rd_Rs
, s3_do16_dsp2
},
810 {"mtcel!", 0x7000, 0x7ff0, 0x0000044a, x_Rs
, s3_do16_dsp
},
811 {"mtcel", 0x0000044a, 0x3e007fff, 0x8000, Rd_x_x
, s3_do_rd
},
812 {"mtceh", 0x0000084a, 0x3e007fff, 0x8000, Rd_x_x
, s3_do_rd
},
813 {"mtceh!", 0x7010, 0x7ff0, 0x0000084a, x_Rs
, s3_do16_dsp
},
814 {"mtcehl", 0x00000c4a, 0x3e007fff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
815 {"mtsr", 0x00000052, 0x3e0003ff, 0x8000, x_Rs_I5
, s3_do_rdsrs
},
816 {"mtcr", 0x0c000000, 0x3e00001f, 0x8000, Rd_Rs_x
, s3_do_rdcrs
},
817 {"mtc1", 0x0c000008, 0x3e00001f, 0x8000, Rd_Rs_x
, s3_do_rdcrs
},
818 {"mtc2", 0x0c000010, 0x3e00001f, 0x8000, Rd_Rs_x
, s3_do_rdcrs
},
819 {"mtc3", 0x0c000018, 0x3e00001f, 0x8000, Rd_Rs_x
, s3_do_rdcrs
},
820 {"mtcc1", 0x0c00000e, 0x3e00001f, 0x8000, Rd_Rs_x
, s3_do_rdcrs
},
821 {"mtcc2", 0x0c000016, 0x3e00001f, 0x8000, Rd_Rs_x
, s3_do_rdcrs
},
822 {"mtcc3", 0x0c00001e, 0x3e00001f, 0x8000, Rd_Rs_x
, s3_do_rdcrs
},
823 {"mul.f!", 0x7200, 0x7f00, 0x00000041, Rd_Rs
, s3_do16_dsp2
},
824 {"mulu!", 0x7300, 0x7f00, 0x00000042, Rd_Rs
, s3_do16_dsp2
},
825 {"mulr.l", 0x00000140, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s3_do_rdrsrs
},
826 {"mulr.h", 0x00000240, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s3_do_rdrsrs
},
827 {"mulr", 0x00000340, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s3_do_rdrsrs
},
828 {"mulr.lf", 0x00000141, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s3_do_rdrsrs
},
829 {"mulr.hf", 0x00000241, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s3_do_rdrsrs
},
830 {"mulr.f", 0x00000341, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s3_do_rdrsrs
},
831 {"mulur.l", 0x00000142, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s3_do_rdrsrs
},
832 {"mulur.h", 0x00000242, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s3_do_rdrsrs
},
833 {"mulur", 0x00000342, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s3_do_rdrsrs
},
834 {"divr.q", 0x00000144, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s3_do_rdrsrs
},
835 {"divr.r", 0x00000244, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s3_do_rdrsrs
},
836 {"divr", 0x00000344, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s3_do_rdrsrs
},
837 {"divur.q", 0x00000146, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s3_do_rdrsrs
},
838 {"divur.r", 0x00000246, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s3_do_rdrsrs
},
839 {"divur", 0x00000346, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s3_do_rdrsrs
},
840 {"mvcs", 0x00000056, 0x3e007fff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
841 {"mvcc", 0x00000456, 0x3e007fff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
842 {"mvgtu", 0x00000856, 0x3e007fff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
843 {"mvleu", 0x00000c56, 0x3e007fff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
844 {"mveq", 0x00001056, 0x3e007fff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
845 {"mvne", 0x00001456, 0x3e007fff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
846 {"mvgt", 0x00001856, 0x3e007fff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
847 {"mvle", 0x00001c56, 0x3e007fff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
848 {"mvge", 0x00002056, 0x3e007fff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
849 {"mvlt", 0x00002456, 0x3e007fff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
850 {"mvmi", 0x00002856, 0x3e007fff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
851 {"mvpl", 0x00002c56, 0x3e007fff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
852 {"mvvs", 0x00003056, 0x3e007fff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
853 {"mvvc", 0x00003456, 0x3e007fff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
856 {"mv", 0x00003c56, 0x3e007fff, 0x4000, Rd_Rs_x
, s3_do_rdrs
},
857 {"mv!", 0x4000, 0x7c00, 0x8000, Rd_Rs
, s3_do16_mv_cmp
},
858 {"neg", 0x0000001e, 0x3e0003ff, 0x8000, Rd_x_Rs
, s3_do_rdxrs
},
859 {"neg.c", 0x0000001f, 0x3e0003ff, 0x8000, Rd_x_Rs
, s3_do_rdxrs
},
860 {"nop", 0x00000000, 0x3e0003ff, 0x0000, NO_OPD
, s3_do_empty
},
861 {"not", 0x00000024, 0x3e0003ff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
862 {"not.c", 0x00000025, 0x3e0003ff, 0x8000, Rd_Rs_x
, s3_do_rdrs
},
863 {"nop!", 0x0000, 0x7fff, 0x8000, NO16_OPD
, s3_do_empty
},
864 {"or", 0x00000022, 0x3e0003ff, 0x4a00, Rd_Rs_Rs
, s3_do_rdrsrs
},
865 {"or.c", 0x00000023, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_rdrsrs
},
866 {"ori", 0x020a0000, 0x3e0e0001, 0x8000, Rd_I16
, s3_do_rdi16
},
867 {"ori.c", 0x020a0001, 0x3e0e0001, 0x8000, Rd_I16
, s3_do_rdi16
},
868 {"oris", 0x0a0a0000, 0x3e0e0001, 0x8000, Rd_I16
, s3_do_rdi16
},
869 {"oris.c", 0x0a0a0001, 0x3e0e0001, 0x8000, Rd_I16
, s3_do_rdi16
},
870 {"orri", 0x1a000000, 0x3e000001, 0x8000, Rd_Rs_I14
, s3_do_rdrsi14
},
871 {"orri.c", 0x1a000001, 0x3e000001, 0x8000, Rd_Rs_I14
, s3_do_rdrsi14
},
874 {"or!", 0x4a00, 0x7f00, 0x8000, Rd_Rs
, s3_do16_rdrs2
},
875 {"pflush", 0x0000000a, 0x3e0003ff, 0x8000, NO_OPD
, s3_do_empty
},
876 {"pop!", 0x0040, 0x7fe0, 0x8000, Rd_rvalueRs
, s3_do16_push_pop
},
877 {"push!", 0x0060, 0x7fe0, 0x8000, Rd_lvalueRs
, s3_do16_push_pop
},
879 {"rpop!", 0x6800, 0x7c00, 0x8000, Rd_I5
, s3_do16_rpop
},
880 {"rpush!", 0x6c00, 0x7c00, 0x8000, Rd_I5
, s3_do16_rpush
},
882 {"ror", 0x00000038, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_rdrsrs
},
883 {"ror.c", 0x00000039, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_rdrsrs
},
884 {"rorc.c", 0x0000003b, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_rdrsrs
},
885 {"rol", 0x0000003c, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_rdrsrs
},
886 {"rol.c", 0x0000003d, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_rdrsrs
},
887 {"rolc.c", 0x0000003f, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_rdrsrs
},
888 {"rori", 0x00000078, 0x3e0003ff, 0x8000, Rd_Rs_I5
, s3_do_rdrsi5
},
889 {"rori.c", 0x00000079, 0x3e0003ff, 0x8000, Rd_Rs_I5
, s3_do_rdrsi5
},
890 {"roric.c", 0x0000007b, 0x3e0003ff, 0x8000, Rd_Rs_I5
, s3_do_rdrsi5
},
891 {"roli", 0x0000007c, 0x3e0003ff, 0x8000, Rd_Rs_I5
, s3_do_rdrsi5
},
892 {"roli.c", 0x0000007d, 0x3e0003ff, 0x8000, Rd_Rs_I5
, s3_do_rdrsi5
},
893 {"rolic.c", 0x0000007f, 0x3e0003ff, 0x8000, Rd_Rs_I5
, s3_do_rdrsi5
},
894 {"rte", 0x0c000084, 0x3e0003ff, 0x8000, NO_OPD
, s3_do_empty
},
895 {"asw", 0x0000000e, 0x3e0003ff, 0x8000, Rd_lvalue32Rs
, s3_do_ldst_atomic
},
896 {"scb", 0x00000068, 0x3e0003ff, 0x8000, Rd_lvalueRs_post4
, s3_do_ldst_unalign
},
897 {"scw", 0x0000006a, 0x3e0003ff, 0x8000, Rd_lvalueRs_post4
, s3_do_ldst_unalign
},
898 {"sce", 0x0000006e, 0x3e0003ff, 0x8000, x_lvalueRs_post4
, s3_do_ldst_unalign
},
899 {"sdbbp", 0x00000006, 0x3e0003ff, 0x0020, x_I5_x
, s3_do_xi5x
},
900 {"sdbbp!", 0x0020, 0x7fe0, 0x8000, Rd_I5
, s3_do16_xi5
},
901 {"sleep", 0x0c0000c4, 0x3e0003ff, 0x8000, NO_OPD
, s3_do_empty
},
902 {"rti", 0x0c0000e4, 0x3e0003ff, 0x8000, NO_OPD
, s3_do_empty
},
903 {"sll", 0x00000030, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_rdrsrs
},
904 {"sll.c", 0x00000031, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_rdrsrs
},
905 {"sll.s", 0x3800004e, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_dsp2
},
906 {"slli", 0x00000070, 0x3e0003ff, 0x5800, Rd_Rs_I5
, s3_do_rdrsi5
},
907 {"slli.c", 0x00000071, 0x3e0003ff, 0x8000, Rd_Rs_I5
, s3_do_rdrsi5
},
909 /* slli.c <-> slli!. */
910 {"slli!", 0x5800, 0x7e00, 0x8000, Rd_I5
, s3_do16_slli_srli
},
911 {"srl", 0x00000034, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_rdrsrs
},
912 {"srl.c", 0x00000035, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_rdrsrs
},
913 {"sra", 0x00000036, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_rdrsrs
},
914 {"sra.c", 0x00000037, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_rdrsrs
},
915 {"srli", 0x00000074, 0x3e0003ff, 0x5a00, Rd_Rs_I5
, s3_do_rdrsi5
},
916 {"srli.c", 0x00000075, 0x3e0003ff, 0x8000, Rd_Rs_I5
, s3_do_rdrsi5
},
917 {"srai", 0x00000076, 0x3e0003ff, 0x8000, Rd_Rs_I5
, s3_do_rdrsi5
},
918 {"srai.c", 0x00000077, 0x3e0003ff, 0x8000, Rd_Rs_I5
, s3_do_rdrsi5
},
920 /* srli.c <-> srli!. */
921 {"srli!", 0x5a00, 0x7e00, 0x8000, Rd_Rs
, s3_do16_slli_srli
},
922 {"stc1", 0x0c00000b, 0x3e00001f, 0x8000, Rd_lvalueRs_SI10
, s3_do_ldst_cop
},
923 {"stc2", 0x0c000013, 0x3e00001f, 0x8000, Rd_lvalueRs_SI10
, s3_do_ldst_cop
},
924 {"stc3", 0x0c00001b, 0x3e00001f, 0x8000, Rd_lvalueRs_SI10
, s3_do_ldst_cop
},
925 {"sub", 0x00000014, 0x3e0003ff, 0x4900, Rd_Rs_Rs
, s3_do_rdrsrs
},
926 {"sub.c", 0x00000015, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_rdrsrs
},
927 {"sub.s", 0x38000049, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_dsp2
},
928 {"subc", 0x00000016, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_rdrsrs
},
929 {"subc.c", 0x00000017, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_rdrsrs
},
931 /* sub.c <-> sub!. */
932 {"sub!", 0x4900, 0x7f00, 0x8000, Rd_Rs
, s3_do16_rdrs2
},
933 {"sw!", 0x2000, 0x7000, 0x8000, Rd_lvalueRs
, s3_do16_ldst_insn
},
934 {"syscall", 0x00000002, 0x3e0003ff, 0x8000, I15
, s3_do_i15
},
935 {"trapcs", 0x00000004, 0x3e007fff, 0x8000, x_I5_x
, s3_do_xi5x
},
936 {"trapcc", 0x00000404, 0x3e007fff, 0x8000, x_I5_x
, s3_do_xi5x
},
937 {"trapgtu", 0x00000804, 0x3e007fff, 0x8000, x_I5_x
, s3_do_xi5x
},
938 {"trapleu", 0x00000c04, 0x3e007fff, 0x8000, x_I5_x
, s3_do_xi5x
},
939 {"trapeq", 0x00001004, 0x3e007fff, 0x8000, x_I5_x
, s3_do_xi5x
},
940 {"trapne", 0x00001404, 0x3e007fff, 0x8000, x_I5_x
, s3_do_xi5x
},
941 {"trapgt", 0x00001804, 0x3e007fff, 0x8000, x_I5_x
, s3_do_xi5x
},
942 {"traple", 0x00001c04, 0x3e007fff, 0x8000, x_I5_x
, s3_do_xi5x
},
943 {"trapge", 0x00002004, 0x3e007fff, 0x8000, x_I5_x
, s3_do_xi5x
},
944 {"traplt", 0x00002404, 0x3e007fff, 0x8000, x_I5_x
, s3_do_xi5x
},
945 {"trapmi", 0x00002804, 0x3e007fff, 0x8000, x_I5_x
, s3_do_xi5x
},
946 {"trappl", 0x00002c04, 0x3e007fff, 0x8000, x_I5_x
, s3_do_xi5x
},
947 {"trapvs", 0x00003004, 0x3e007fff, 0x8000, x_I5_x
, s3_do_xi5x
},
948 {"trapvc", 0x00003404, 0x3e007fff, 0x8000, x_I5_x
, s3_do_xi5x
},
949 {"trap", 0x00003c04, 0x3e007fff, 0x8000, x_I5_x
, s3_do_xi5x
},
950 {"xor", 0x00000026, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_rdrsrs
},
951 {"xor.c", 0x00000027, 0x3e0003ff, 0x8000, Rd_Rs_Rs
, s3_do_rdrsrs
},
953 /* Macro instruction. */
954 {"li", 0x020c0000, 0x3e0e0000, 0x8000, Insn_Type_SYN
, s3_do_macro_li_rdi32
},
956 /* la reg, imm32 -->(1) ldi reg, simm16
957 (2) ldis reg, %HI(imm32)
960 la reg, symbol -->(1) lis reg, %HI(imm32)
961 ori reg, %LO(imm32) */
962 {"la", 0x020c0000, 0x3e0e0000, 0x8000, Insn_Type_SYN
, s3_do_macro_la_rdi32
},
963 {"bcmpeqz", 0x0000004c, 0x3e00007e, 0x8000, Insn_BCMP
, s3_do_macro_bcmpz
},
964 {"bcmpeq", 0x0000004c, 0x3e00007e, 0x8000, Insn_BCMP
, s3_do_macro_bcmp
},
965 {"bcmpnez", 0x0000004e, 0x3e00007e, 0x8000, Insn_BCMP
, s3_do_macro_bcmpz
},
966 {"bcmpne", 0x0000004e, 0x3e00007e, 0x8000, Insn_BCMP
, s3_do_macro_bcmp
},
967 {"div", 0x00000044, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s3_do_macro_mul_rdrsrs
},
968 {"divu", 0x00000046, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s3_do_macro_mul_rdrsrs
},
969 {"rem", 0x00000044, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s3_do_macro_mul_rdrsrs
},
970 {"remu", 0x00000046, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s3_do_macro_mul_rdrsrs
},
971 {"mul", 0x00000040, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s3_do_macro_mul_rdrsrs
},
972 {"mulu", 0x00000042, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s3_do_macro_mul_rdrsrs
},
973 {"maz", 0x00000040, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s3_do_macro_mul_rdrsrs
},
974 {"mazu", 0x00000042, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s3_do_macro_mul_rdrsrs
},
975 {"mul.f", 0x00000041, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s3_do_macro_mul_rdrsrs
},
976 {"maz.f", 0x00000041, 0x3e0003ff, 0x8000, Insn_Type_SYN
, s3_do_macro_mul_rdrsrs
},
977 {"lb", INSN_LB
, 0x00000000, 0x8000, Insn_Type_SYN
, s3_do_macro_ldst_label
},
978 {"lbu", INSN_LBU
, 0x00000000, 0x8000, Insn_Type_SYN
, s3_do_macro_ldst_label
},
979 {"lh", INSN_LH
, 0x00000000, 0x8000, Insn_Type_SYN
, s3_do_macro_ldst_label
},
980 {"lhu", INSN_LHU
, 0x00000000, 0x8000, Insn_Type_SYN
, s3_do_macro_ldst_label
},
981 {"lw", INSN_LW
, 0x00000000, 0x1000, Insn_Type_SYN
, s3_do_macro_ldst_label
},
982 {"sb", INSN_SB
, 0x00000000, 0x8000, Insn_Type_SYN
, s3_do_macro_ldst_label
},
983 {"sh", INSN_SH
, 0x00000000, 0x8000, Insn_Type_SYN
, s3_do_macro_ldst_label
},
984 {"sw", INSN_SW
, 0x00000000, 0x2000, Insn_Type_SYN
, s3_do_macro_ldst_label
},
986 /* Assembler use internal. */
987 {"ld_i32hi", 0x0a0c0000, 0x3e0e0000, 0x8000, Insn_internal
, s3_do_macro_rdi32hi
},
988 {"ld_i32lo", 0x020a0000, 0x3e0e0001, 0x8000, Insn_internal
, s3_do_macro_rdi32lo
},
989 {"ldis_pic", 0x0a0c0000, 0x3e0e0000, 0x8000, Insn_internal
, s3_do_rdi16_pic
},
990 {"addi_s_pic",0x02000000, 0x3e0e0001, 0x8000, Insn_internal
, s3_do_addi_s_pic
},
991 {"addi_u_pic",0x02000000, 0x3e0e0001, 0x8000, Insn_internal
, s3_do_addi_u_pic
},
992 {"lw_pic", 0x20000000, 0x3e000000, 0x8000, Insn_internal
, s3_do_lw_pic
},
994 /* 48-bit instructions. */
995 {"sdbbp48", 0x000000000000LL
, 0x1c000000001fLL
, 0x8000, Rd_I32
, s3_do_sdbbp48
},
996 {"ldi48", 0x000000000001LL
, 0x1c000000001fLL
, 0x8000, Rd_I32
, s3_do_ldi48
},
997 {"lw48", 0x000000000002LL
, 0x1c000000001fLL
, 0x8000, Rd_I30
, s3_do_lw48
},
998 {"sw48", 0x000000000003LL
, 0x1c000000001fLL
, 0x8000, Rd_I30
, s3_do_sw48
},
999 {"andri48", 0x040000000000LL
, 0x1c0000000003LL
, 0x8000, Rd_I32
, s3_do_and48
},
1000 {"andri48.c", 0x040000000001LL
, 0x1c0000000003LL
, 0x8000, Rd_I32
, s3_do_and48
},
1001 {"orri48", 0x040000000002LL
, 0x1c0000000003LL
, 0x8000, Rd_I32
, s3_do_or48
},
1002 {"orri48.c", 0x040000000003LL
, 0x1c0000000003LL
, 0x8000, Rd_I32
, s3_do_or48
},
1005 #define s3_SCORE3_PIPELINE 3
1007 static int s3_university_version
= 0;
1008 static int s3_vector_size
= s3_SCORE3_PIPELINE
;
1009 static struct s3_score_it s3_dependency_vector
[s3_SCORE3_PIPELINE
];
1011 static int s3_score3d
= 1;
1014 s3_end_of_line (char *str
)
1016 int retval
= s3_SUCCESS
;
1018 s3_skip_whitespace (str
);
1021 retval
= (int) s3_FAIL
;
1024 s3_inst
.error
= s3_BAD_GARBAGE
;
1031 s3_score_reg_parse (char **ccp
, struct hash_control
*htab
)
1036 struct s3_reg_entry
*reg
;
1039 if (!ISALPHA (*p
) || !is_name_beginner (*p
))
1040 return (int) s3_FAIL
;
1044 while (ISALPHA (c
) || ISDIGIT (c
) || c
== '_')
1048 reg
= (struct s3_reg_entry
*) hash_find (htab
, start
);
1056 return (int) s3_FAIL
;
1059 /* If shift <= 0, only return reg. */
1062 s3_reg_required_here (char **str
, int shift
, enum s3_score_reg_type reg_type
)
1064 static char buff
[s3_MAX_LITERAL_POOL_SIZE
];
1065 int reg
= (int) s3_FAIL
;
1068 if ((reg
= s3_score_reg_parse (str
, s3_all_reg_maps
[reg_type
].htab
)) != (int) s3_FAIL
)
1070 if (reg_type
== s3_REG_TYPE_SCORE
)
1072 if ((reg
== 1) && (s3_nor1
== 1) && (s3_inst
.bwarn
== 0))
1074 as_warn (_("Using temp register (r1)"));
1080 if (reg_type
== s3_REG_TYPE_SCORE_CR
)
1081 strcpy (s3_inst
.reg
, s3_score_crn_table
[reg
].name
);
1082 else if (reg_type
== s3_REG_TYPE_SCORE_SR
)
1083 strcpy (s3_inst
.reg
, s3_score_srn_table
[reg
].name
);
1085 strcpy (s3_inst
.reg
, "");
1087 s3_inst
.instruction
|= (bfd_vma
) reg
<< shift
;
1093 sprintf (buff
, _("register expected, not '%.100s'"), start
);
1094 s3_inst
.error
= buff
;
1101 s3_skip_past_comma (char **str
)
1107 while ((c
= *p
) == ' ' || c
== ',')
1110 if (c
== ',' && comma
++)
1112 s3_inst
.error
= s3_BAD_SKIP_COMMA
;
1113 return (int) s3_FAIL
;
1117 if ((c
== '\0') || (comma
== 0))
1119 s3_inst
.error
= s3_BAD_SKIP_COMMA
;
1120 return (int) s3_FAIL
;
1124 return comma
? s3_SUCCESS
: (int) s3_FAIL
;
1128 s3_do_rdrsrs (char *str
)
1131 s3_skip_whitespace (str
);
1133 if ((reg
= s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
1134 || s3_skip_past_comma (&str
) == (int) s3_FAIL
1135 || s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
1136 || s3_skip_past_comma (&str
) == (int) s3_FAIL
1137 || s3_reg_required_here (&str
, 10, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
1138 || s3_end_of_line (str
) == (int) s3_FAIL
)
1144 /* Check mulr, mulur rd is even number. */
1145 if (((s3_inst
.instruction
& 0x3e0003ff) == 0x00000340
1146 || (s3_inst
.instruction
& 0x3e0003ff) == 0x00000342)
1149 s3_inst
.error
= _("rd must be even number.");
1153 if ((((s3_inst
.instruction
>> 15) & 0x10) == 0)
1154 && (((s3_inst
.instruction
>> 10) & 0x10) == 0)
1155 && (((s3_inst
.instruction
>> 20) & 0x10) == 0)
1156 && (s3_inst
.relax_inst
!= 0x8000)
1157 && (((s3_inst
.instruction
>> 20) & 0xf) == ((s3_inst
.instruction
>> 15) & 0xf)))
1159 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>> 10) & 0xf) )
1160 | (((s3_inst
.instruction
>> 15) & 0xf) << 4);
1161 s3_inst
.relax_size
= 2;
1165 s3_inst
.relax_inst
= 0x8000;
1171 s3_walk_no_bignums (symbolS
* sp
)
1173 if (symbol_get_value_expression (sp
)->X_op
== O_big
)
1176 if (symbol_get_value_expression (sp
)->X_add_symbol
)
1177 return (s3_walk_no_bignums (symbol_get_value_expression (sp
)->X_add_symbol
)
1178 || (symbol_get_value_expression (sp
)->X_op_symbol
1179 && s3_walk_no_bignums (symbol_get_value_expression (sp
)->X_op_symbol
)));
1185 s3_my_get_expression (expressionS
* ep
, char **str
)
1189 save_in
= input_line_pointer
;
1190 input_line_pointer
= *str
;
1191 s3_in_my_get_expression
= 1;
1192 (void) expression (ep
);
1193 s3_in_my_get_expression
= 0;
1195 if (ep
->X_op
== O_illegal
)
1197 *str
= input_line_pointer
;
1198 input_line_pointer
= save_in
;
1199 s3_inst
.error
= _("illegal expression");
1200 return (int) s3_FAIL
;
1202 /* Get rid of any bignums now, so that we don't generate an error for which
1203 we can't establish a line number later on. Big numbers are never valid
1204 in instructions, which is where this routine is always called. */
1205 if (ep
->X_op
== O_big
1206 || (ep
->X_add_symbol
1207 && (s3_walk_no_bignums (ep
->X_add_symbol
)
1208 || (ep
->X_op_symbol
&& s3_walk_no_bignums (ep
->X_op_symbol
)))))
1210 s3_inst
.error
= _("invalid constant");
1211 *str
= input_line_pointer
;
1212 input_line_pointer
= save_in
;
1213 return (int) s3_FAIL
;
1216 if ((ep
->X_add_symbol
!= NULL
)
1217 && (s3_inst
.type
!= PC_DISP19div2
)
1218 && (s3_inst
.type
!= PC_DISP8div2
)
1219 && (s3_inst
.type
!= PC_DISP24div2
)
1220 && (s3_inst
.type
!= PC_DISP11div2
)
1221 && (s3_inst
.type
!= Insn_Type_SYN
)
1222 && (s3_inst
.type
!= Rd_rvalueRs_SI15
)
1223 && (s3_inst
.type
!= Rd_lvalueRs_SI15
)
1224 && (s3_inst
.type
!= Insn_internal
)
1225 && (s3_inst
.type
!= Rd_I30
)
1226 && (s3_inst
.type
!= Rd_I32
)
1227 && (s3_inst
.type
!= Insn_BCMP
))
1229 s3_inst
.error
= s3_BAD_ARGS
;
1230 *str
= input_line_pointer
;
1231 input_line_pointer
= save_in
;
1232 return (int) s3_FAIL
;
1235 *str
= input_line_pointer
;
1236 input_line_pointer
= save_in
;
1240 /* Check if an immediate is valid. If so, convert it to the right format. */
1241 static bfd_signed_vma
1242 s3_validate_immediate (bfd_signed_vma val
, unsigned int data_type
, int hex_p
)
1248 bfd_signed_vma val_hi
= ((val
& 0xffff0000) >> 16);
1250 if (s3_score_df_range
[data_type
].range
[0] <= val_hi
1251 && val_hi
<= s3_score_df_range
[data_type
].range
[1])
1258 bfd_signed_vma val_lo
= (val
& 0xffff);
1260 if (s3_score_df_range
[data_type
].range
[0] <= val_lo
1261 && val_lo
<= s3_score_df_range
[data_type
].range
[1])
1269 if (!(val
>= -0x2000 && val
<= 0x3fff))
1271 return (int) s3_FAIL
;
1276 if (!(val
>= -8192 && val
<= 8191))
1278 return (int) s3_FAIL
;
1288 if (!(val
>= -0x7fff && val
<= 0xffff && val
!= 0x8000))
1290 return (int) s3_FAIL
;
1295 if (!(val
>= -32767 && val
<= 32768))
1297 return (int) s3_FAIL
;
1305 case _IMM5_MULTI_LOAD
:
1306 if (val
>= 2 && val
<= 32)
1312 return (int) s3_FAIL
;
1315 if (val
>= 0 && val
<= 0xffffffff)
1321 return (int) s3_FAIL
;
1325 if (data_type
== _SIMM14_NEG
|| data_type
== _IMM16_NEG
)
1328 if (s3_score_df_range
[data_type
].range
[0] <= val
1329 && val
<= s3_score_df_range
[data_type
].range
[1])
1335 return (int) s3_FAIL
;
1339 s3_data_op2 (char **str
, int shift
, enum score_data_type data_type
)
1341 bfd_signed_vma value
;
1342 char data_exp
[s3_MAX_LITERAL_POOL_SIZE
];
1347 s3_skip_whitespace (*str
);
1348 s3_inst
.error
= NULL
;
1351 /* Set hex_p to zero. */
1354 while ((*dataptr
!= '\0') && (*dataptr
!= '|') && (cnt
<= s3_MAX_LITERAL_POOL_SIZE
)) /* 0x7c = ='|' */
1356 data_exp
[cnt
] = *dataptr
;
1361 data_exp
[cnt
] = '\0';
1362 pp
= (char *)&data_exp
;
1364 if (*dataptr
== '|') /* process PCE */
1366 if (s3_my_get_expression (&s3_inst
.reloc
.exp
, &pp
) == (int) s3_FAIL
)
1367 return (int) s3_FAIL
;
1368 s3_end_of_line (pp
);
1369 if (s3_inst
.error
!= 0)
1370 return (int) s3_FAIL
; /* to ouptut_inst to printf out the error */
1373 else /* process 16 bit */
1375 if (s3_my_get_expression (&s3_inst
.reloc
.exp
, str
) == (int) s3_FAIL
)
1377 return (int) s3_FAIL
;
1380 dataptr
= (char *)data_exp
;
1381 for (; *dataptr
!= '\0'; dataptr
++)
1383 *dataptr
= TOLOWER (*dataptr
);
1384 if (*dataptr
== '!' || *dataptr
== ' ')
1387 dataptr
= (char *)data_exp
;
1389 if ((dataptr
!= NULL
)
1390 && (((strstr (dataptr
, "0x")) != NULL
)
1391 || ((strstr (dataptr
, "0X")) != NULL
)))
1394 if ((data_type
!= _SIMM16_LA
)
1395 && (data_type
!= _VALUE_HI16
)
1396 && (data_type
!= _VALUE_LO16
)
1397 && (data_type
!= _IMM16
)
1398 && (data_type
!= _IMM15
)
1399 && (data_type
!= _IMM14
)
1400 && (data_type
!= _IMM4
)
1401 && (data_type
!= _IMM5
)
1402 && (data_type
!= _IMM5_MULTI_LOAD
)
1403 && (data_type
!= _IMM11
)
1404 && (data_type
!= _IMM8
)
1405 && (data_type
!= _IMM5_RSHIFT_1
)
1406 && (data_type
!= _IMM5_RSHIFT_2
)
1407 && (data_type
!= _SIMM14
)
1408 && (data_type
!= _SIMM14_NEG
)
1409 && (data_type
!= _SIMM16_NEG
)
1410 && (data_type
!= _IMM10_RSHIFT_2
)
1411 && (data_type
!= _GP_IMM15
)
1412 && (data_type
!= _SIMM5
)
1413 && (data_type
!= _SIMM6
)
1414 && (data_type
!= _IMM32
)
1415 && (data_type
!= _SIMM32
))
1421 if ((s3_inst
.reloc
.exp
.X_add_number
== 0)
1422 && (s3_inst
.type
!= Insn_Type_SYN
)
1423 && (s3_inst
.type
!= Rd_rvalueRs_SI15
)
1424 && (s3_inst
.type
!= Rd_lvalueRs_SI15
)
1425 && (s3_inst
.type
!= Insn_internal
)
1426 && (((*dataptr
>= 'a') && (*dataptr
<= 'z'))
1427 || ((*dataptr
== '0') && (*(dataptr
+ 1) == 'x') && (*(dataptr
+ 2) != '0'))
1428 || ((*dataptr
== '+') && (*(dataptr
+ 1) != '0'))
1429 || ((*dataptr
== '-') && (*(dataptr
+ 1) != '0'))))
1431 s3_inst
.error
= s3_BAD_ARGS
;
1432 return (int) s3_FAIL
;
1436 if ((s3_inst
.reloc
.exp
.X_add_symbol
)
1437 && ((data_type
== _SIMM16
)
1438 || (data_type
== _SIMM16_NEG
)
1439 || (data_type
== _IMM16_NEG
)
1440 || (data_type
== _SIMM14
)
1441 || (data_type
== _SIMM14_NEG
)
1442 || (data_type
== _IMM5
)
1443 || (data_type
== _IMM5_MULTI_LOAD
)
1444 || (data_type
== _IMM11
)
1445 || (data_type
== _IMM14
)
1446 || (data_type
== _IMM20
)
1447 || (data_type
== _IMM16
)
1448 || (data_type
== _IMM15
)
1449 || (data_type
== _IMM4
)))
1451 s3_inst
.error
= s3_BAD_ARGS
;
1452 return (int) s3_FAIL
;
1455 if (s3_inst
.reloc
.exp
.X_add_symbol
)
1460 return (int) s3_FAIL
;
1462 s3_inst
.reloc
.type
= BFD_RELOC_HI16_S
;
1463 s3_inst
.reloc
.pc_rel
= 0;
1466 s3_inst
.reloc
.type
= BFD_RELOC_LO16
;
1467 s3_inst
.reloc
.pc_rel
= 0;
1470 s3_inst
.reloc
.type
= BFD_RELOC_SCORE_GPREL15
;
1471 s3_inst
.reloc
.pc_rel
= 0;
1474 case _IMM16_LO16_pic
:
1475 s3_inst
.reloc
.type
= BFD_RELOC_SCORE_GOT_LO16
;
1476 s3_inst
.reloc
.pc_rel
= 0;
1479 s3_inst
.reloc
.type
= BFD_RELOC_32
;
1480 s3_inst
.reloc
.pc_rel
= 0;
1486 if (data_type
== _IMM16_pic
)
1488 s3_inst
.reloc
.type
= BFD_RELOC_SCORE_DUMMY_HI16
;
1489 s3_inst
.reloc
.pc_rel
= 0;
1492 if (data_type
== _SIMM16_LA
&& s3_inst
.reloc
.exp
.X_unsigned
== 1)
1494 value
= s3_validate_immediate (s3_inst
.reloc
.exp
.X_add_number
, _SIMM16_LA_POS
, hex_p
);
1495 if (value
== (int) s3_FAIL
) /* for advance to check if this is ldis */
1496 if ((s3_inst
.reloc
.exp
.X_add_number
& 0xffff) == 0)
1498 s3_inst
.instruction
|= 0x8000000;
1499 s3_inst
.instruction
|= ((s3_inst
.reloc
.exp
.X_add_number
>> 16) << 1) & 0x1fffe;
1505 value
= s3_validate_immediate (s3_inst
.reloc
.exp
.X_add_number
, data_type
, hex_p
);
1508 if (value
== (int) s3_FAIL
)
1510 if (data_type
== _IMM32
)
1512 sprintf (s3_err_msg
,
1513 _("invalid constant: %d bit expression not in range %u..%u"),
1514 s3_score_df_range
[data_type
].bits
,
1515 0, (unsigned)0xffffffff);
1517 else if (data_type
== _IMM5_MULTI_LOAD
)
1519 sprintf (s3_err_msg
,
1520 _("invalid constant: %d bit expression not in range %u..%u"),
1523 else if ((data_type
!= _SIMM14_NEG
) && (data_type
!= _SIMM16_NEG
) && (data_type
!= _IMM16_NEG
))
1525 sprintf (s3_err_msg
,
1526 _("invalid constant: %d bit expression not in range %d..%d"),
1527 s3_score_df_range
[data_type
].bits
,
1528 s3_score_df_range
[data_type
].range
[0], s3_score_df_range
[data_type
].range
[1]);
1532 sprintf (s3_err_msg
,
1533 _("invalid constant: %d bit expression not in range %d..%d"),
1534 s3_score_df_range
[data_type
].bits
,
1535 -s3_score_df_range
[data_type
].range
[1], -s3_score_df_range
[data_type
].range
[0]);
1538 s3_inst
.error
= s3_err_msg
;
1539 return (int) s3_FAIL
;
1542 if (((s3_score_df_range
[data_type
].range
[0] != 0) || (data_type
== _IMM5_RANGE_8_31
))
1543 && data_type
!= _IMM5_MULTI_LOAD
)
1545 value
&= (1 << s3_score_df_range
[data_type
].bits
) - 1;
1548 s3_inst
.instruction
|= value
<< shift
;
1551 if ((s3_inst
.instruction
& 0x3e000000) == 0x30000000)
1553 if ((((s3_inst
.instruction
>> 20) & 0x1F) != 0)
1554 && (((s3_inst
.instruction
>> 20) & 0x1F) != 1)
1555 && (((s3_inst
.instruction
>> 20) & 0x1F) != 2)
1556 && (((s3_inst
.instruction
>> 20) & 0x1F) != 0x10))
1558 s3_inst
.error
= _("invalid constant: bit expression not defined");
1559 return (int) s3_FAIL
;
1566 /* Handle addi/addi.c/addis.c/cmpi.c/addis.c/ldi. */
1568 s3_do_rdsi16 (char *str
)
1570 s3_skip_whitespace (str
);
1572 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
1573 || s3_skip_past_comma (&str
) == (int) s3_FAIL
1574 || s3_data_op2 (&str
, 1, _SIMM16
) == (int) s3_FAIL
1575 || s3_end_of_line (str
) == (int) s3_FAIL
)
1578 /* ldi.->ldiu! only for imm5 */
1579 if ((s3_inst
.instruction
& 0x20c0000) == 0x20c0000)
1581 if ((s3_inst
.instruction
& 0x1ffc0) != 0)
1583 s3_inst
.relax_inst
= 0x8000;
1587 s3_inst
.relax_inst
|= (s3_inst
.instruction
>> 1) & 0x1f;
1588 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>> 20)& 0x1f) <<5);
1589 s3_inst
.relax_size
= 2;
1593 else if ((s3_inst
.instruction
& 0x02040001) == 0x02040001)
1595 /* imm <=0x3f (5 bit<<1)*/
1596 if (((s3_inst
.instruction
& 0x1ffe0) == 0)
1597 || (((s3_inst
.instruction
& 0x1ffe0) == 0x1ffe0)
1598 && (s3_inst
.instruction
& 0x003e) != 0))
1600 s3_inst
.relax_inst
|= (s3_inst
.instruction
>> 1) & 0x1f;
1601 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>> 20) & 0x1f) << 5);
1602 s3_inst
.relax_size
= 2;
1606 s3_inst
.relax_inst
=0x8000;
1611 else if (((s3_inst
.instruction
& 0x2000000) == 0x02000000) && (s3_inst
.relax_inst
!=0x8000))
1613 /* rd : 0-16 ; imm <=0x7f (6 bit<<1)*/
1614 if ((((s3_inst
.instruction
>> 20) & 0x10) != 0x10)
1615 && (((s3_inst
.instruction
& 0x1ffc0) == 0)
1616 || (((s3_inst
.instruction
& 0x1ffc0) == 0x1ffc0)
1617 && (s3_inst
.instruction
& 0x007e) != 0)))
1619 s3_inst
.relax_inst
|= (s3_inst
.instruction
>> 1) & 0x3f;
1620 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>> 20) & 0xf) << 6);
1621 s3_inst
.relax_size
= 2;
1625 s3_inst
.relax_inst
=0x8000;
1629 else if (((s3_inst
.instruction
>> 20) & 0x10) == 0x10)
1631 s3_inst
.relax_inst
= 0x8000;
1636 s3_do_ldis (char *str
)
1638 s3_skip_whitespace (str
);
1640 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
1641 || s3_skip_past_comma (&str
) == (int) s3_FAIL
1642 || s3_data_op2 (&str
, 1, _IMM16
) == (int) s3_FAIL
1643 || s3_end_of_line (str
) == (int) s3_FAIL
)
1647 /* Handle subi/subi.c. */
1649 s3_do_sub_rdsi16 (char *str
)
1651 s3_skip_whitespace (str
);
1653 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) != (int) s3_FAIL
1654 && s3_skip_past_comma (&str
) != (int) s3_FAIL
1655 && s3_data_op2 (&str
, 1, _SIMM16_NEG
) != (int) s3_FAIL
)
1656 s3_end_of_line (str
);
1659 /* Handle subis/subis.c. */
1661 s3_do_sub_rdi16 (char *str
)
1663 s3_skip_whitespace (str
);
1665 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) != (int) s3_FAIL
1666 && s3_skip_past_comma (&str
) != (int) s3_FAIL
1667 && s3_data_op2 (&str
, 1, _IMM16_NEG
) != (int) s3_FAIL
)
1668 s3_end_of_line (str
);
1671 /* Handle addri/addri.c. */
1673 s3_do_rdrssi14 (char *str
) /* -(2^13)~((2^13)-1) */
1675 s3_skip_whitespace (str
);
1677 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) != (int) s3_FAIL
1678 && s3_skip_past_comma (&str
) != (int) s3_FAIL
1679 && s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) != (int) s3_FAIL
1680 && s3_skip_past_comma (&str
) != (int) s3_FAIL
)
1681 s3_data_op2 (&str
, 1, _SIMM14
);
1684 /* Handle subri.c/subri. */
1686 s3_do_sub_rdrssi14 (char *str
) /* -(2^13)~((2^13)-1) */
1688 s3_skip_whitespace (str
);
1690 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) != (int) s3_FAIL
1691 && s3_skip_past_comma (&str
) != (int) s3_FAIL
1692 && s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) != (int) s3_FAIL
1693 && s3_skip_past_comma (&str
) != (int) s3_FAIL
1694 && s3_data_op2 (&str
, 1, _SIMM14_NEG
) != (int) s3_FAIL
)
1695 s3_end_of_line (str
);
1698 /* Handle bitclr.c/bitset.c/bittgl.c/slli.c/srai.c/srli.c/roli.c/rori.c/rolic.c.
1701 s3_do_rdrsi5 (char *str
)
1703 s3_skip_whitespace (str
);
1705 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
1706 || s3_skip_past_comma (&str
) == (int) s3_FAIL
1707 || s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
1708 || s3_skip_past_comma (&str
) == (int) s3_FAIL
1709 || s3_data_op2 (&str
, 10, _IMM5
) == (int) s3_FAIL
1710 || s3_end_of_line (str
) == (int) s3_FAIL
)
1713 if ((((s3_inst
.instruction
>> 20) & 0x1f) == ((s3_inst
.instruction
>> 15) & 0x1f))
1714 && (s3_inst
.relax_inst
!= 0x8000) && (((s3_inst
.instruction
>> 15) & 0x10) == 0))
1716 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>> 10) & 0x1f) ) | (((s3_inst
.instruction
>> 15) & 0xf) << 5);
1717 s3_inst
.relax_size
= 2;
1720 s3_inst
.relax_inst
= 0x8000;
1723 /* Handle andri/orri/andri.c/orri.c.
1726 s3_do_rdrsi14 (char *str
)
1728 s3_skip_whitespace (str
);
1730 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) != (int) s3_FAIL
1731 && s3_skip_past_comma (&str
) != (int) s3_FAIL
1732 && s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) != (int) s3_FAIL
1733 && s3_skip_past_comma (&str
) != (int) s3_FAIL
1734 && s3_data_op2 (&str
, 1, _IMM14
) != (int) s3_FAIL
)
1735 s3_end_of_line (str
);
1738 /* Handle bittst.c. */
1740 s3_do_xrsi5 (char *str
)
1742 s3_skip_whitespace (str
);
1744 if (s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
1745 || s3_skip_past_comma (&str
) == (int) s3_FAIL
1746 || s3_data_op2 (&str
, 10, _IMM5
) == (int) s3_FAIL
1747 || s3_end_of_line (str
) == (int) s3_FAIL
)
1750 if ((s3_inst
.relax_inst
!= 0x8000) && (((s3_inst
.instruction
>> 15) & 0x10) == 0))
1752 s3_inst
.relax_inst
|= ((s3_inst
.instruction
>> 10) & 0x1f) | (((s3_inst
.instruction
>> 15) & 0xf) << 5);
1753 s3_inst
.relax_size
= 2;
1756 s3_inst
.relax_inst
= 0x8000;
1759 /* Handle addis/andi/ori/andis/oris/ldis. */
1761 s3_do_rdi16 (char *str
)
1763 s3_skip_whitespace (str
);
1765 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
1766 || s3_skip_past_comma (&str
) == (int) s3_FAIL
1767 || s3_data_op2 (&str
, 1, _IMM16
) == (int) s3_FAIL
1768 || s3_end_of_line (str
) == (int) s3_FAIL
)
1772 if ((s3_inst
.instruction
& 0x3e0e0000) == 0x0a0c0000)
1774 /* rd : 0-16 ;imm =0 -> can transform to addi!*/
1775 if ((((s3_inst
.instruction
>> 20) & 0x10) != 0x10) && ((s3_inst
.instruction
& 0x1ffff)==0))
1777 s3_inst
.relax_inst
=0x5400; /* ldiu! */
1778 s3_inst
.relax_inst
|= (s3_inst
.instruction
>> 1) & 0x1f;
1779 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>> 20) & 0xf) << 5);
1780 s3_inst
.relax_size
= 2;
1784 s3_inst
.relax_inst
=0x8000;
1790 else if ((s3_inst
.instruction
& 0x3e0e0001) == 0x0a000000)
1792 /* rd : 0-16 ;imm =0 -> can transform to addi!*/
1793 if ((((s3_inst
.instruction
>> 20) & 0x10) != 0x10) && ((s3_inst
.instruction
& 0x1ffff)==0))
1795 s3_inst
.relax_inst
=0x5c00; /* addi! */
1796 s3_inst
.relax_inst
|= (s3_inst
.instruction
>> 1) & 0x3f;
1797 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>> 20) & 0xf) << 6);
1798 s3_inst
.relax_size
= 2;
1802 s3_inst
.relax_inst
=0x8000;
1809 s3_do_macro_rdi32hi (char *str
)
1811 s3_skip_whitespace (str
);
1813 /* Do not handle s3_end_of_line(). */
1814 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) != (int) s3_FAIL
1815 && s3_skip_past_comma (&str
) != (int) s3_FAIL
)
1816 s3_data_op2 (&str
, 1, _VALUE_HI16
);
1820 s3_do_macro_rdi32lo (char *str
)
1822 s3_skip_whitespace (str
);
1824 /* Do not handle s3_end_of_line(). */
1825 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) != (int) s3_FAIL
1826 && s3_skip_past_comma (&str
) != (int) s3_FAIL
)
1827 s3_data_op2 (&str
, 1, _VALUE_LO16
);
1830 /* Handle ldis_pic. */
1832 s3_do_rdi16_pic (char *str
)
1834 s3_skip_whitespace (str
);
1836 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) != (int) s3_FAIL
1837 && s3_skip_past_comma (&str
) != (int) s3_FAIL
1838 && s3_data_op2 (&str
, 1, _IMM16_pic
) != (int) s3_FAIL
)
1839 s3_end_of_line (str
);
1842 /* Handle addi_s_pic to generate R_SCORE_GOT_LO16 . */
1844 s3_do_addi_s_pic (char *str
)
1846 s3_skip_whitespace (str
);
1848 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) != (int) s3_FAIL
1849 && s3_skip_past_comma (&str
) != (int) s3_FAIL
1850 && s3_data_op2 (&str
, 1, _SIMM16_pic
) != (int) s3_FAIL
)
1851 s3_end_of_line (str
);
1854 /* Handle addi_u_pic to generate R_SCORE_GOT_LO16 . */
1856 s3_do_addi_u_pic (char *str
)
1858 s3_skip_whitespace (str
);
1860 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) != (int) s3_FAIL
1861 && s3_skip_past_comma (&str
) != (int) s3_FAIL
1862 && s3_data_op2 (&str
, 1, _IMM16_LO16_pic
) != (int) s3_FAIL
)
1863 s3_end_of_line (str
);
1866 /* Handle mfceh/mfcel/mtceh/mtchl. */
1868 s3_do_rd (char *str
)
1870 s3_skip_whitespace (str
);
1872 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) != (int) s3_FAIL
)
1873 s3_end_of_line (str
);
1876 /* Handle br{cond},cmpzteq.c ,cmpztmi.c ,cmpz.c */
1878 s3_do_rs (char *str
)
1880 s3_skip_whitespace (str
);
1882 if (s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
1883 || s3_end_of_line (str
) == (int) s3_FAIL
)
1886 if ((s3_inst
.relax_inst
!= 0x8000) )
1888 s3_inst
.relax_inst
|= ((s3_inst
.instruction
>> 15) &0x1f);
1889 s3_inst
.relax_size
= 2;
1892 s3_inst
.relax_inst
= 0x8000;
1896 s3_do_i15 (char *str
)
1898 s3_skip_whitespace (str
);
1900 if (s3_data_op2 (&str
, 10, _IMM15
) != (int) s3_FAIL
)
1901 s3_end_of_line (str
);
1905 s3_do_xi5x (char *str
)
1907 s3_skip_whitespace (str
);
1909 if (s3_data_op2 (&str
, 15, _IMM5
) == (int) s3_FAIL
|| s3_end_of_line (str
) == (int) s3_FAIL
)
1912 if (s3_inst
.relax_inst
!= 0x8000)
1914 s3_inst
.relax_inst
|= ((s3_inst
.instruction
>> 15) & 0x1f);
1915 s3_inst
.relax_size
= 2;
1920 s3_do_rdrs (char *str
)
1922 s3_skip_whitespace (str
);
1924 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
1925 || s3_skip_past_comma (&str
) == (int) s3_FAIL
1926 || s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
1927 || s3_end_of_line (str
) == (int) s3_FAIL
)
1930 if (s3_inst
.relax_inst
!= 0x8000)
1932 if (((s3_inst
.instruction
& 0x7f) == 0x56)) /* adjust mv -> mv!*/
1934 /* mv! rd : 5bit , ra : 5bit */
1935 s3_inst
.relax_inst
|= ((s3_inst
.instruction
>> 15) & 0x1f) | (((s3_inst
.instruction
>> 20) & 0x1f) << 5);
1936 s3_inst
.relax_size
= 2;
1938 else if ((((s3_inst
.instruction
>> 15) & 0x10) == 0x0) && (((s3_inst
.instruction
>> 20) & 0x10) == 0))
1940 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>> 15) & 0xf) << 4)
1941 | (((s3_inst
.instruction
>> 20) & 0xf) << 8);
1942 s3_inst
.relax_size
= 2;
1946 s3_inst
.relax_inst
= 0x8000;
1951 /* Handle mfcr/mtcr. */
1953 s3_do_rdcrs (char *str
)
1955 s3_skip_whitespace (str
);
1957 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) != (int) s3_FAIL
1958 && s3_skip_past_comma (&str
) != (int) s3_FAIL
1959 && s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE_CR
) != (int) s3_FAIL
)
1960 s3_end_of_line (str
);
1963 /* Handle mfsr/mtsr. */
1965 s3_do_rdsrs (char *str
)
1967 s3_skip_whitespace (str
);
1970 if ((s3_inst
.instruction
& 0xff) == 0x50)
1972 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) != (int) s3_FAIL
1973 && s3_skip_past_comma (&str
) != (int) s3_FAIL
1974 && s3_reg_required_here (&str
, 10, s3_REG_TYPE_SCORE_SR
) != (int) s3_FAIL
)
1975 s3_end_of_line (str
);
1979 if (s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) != (int) s3_FAIL
1980 && s3_skip_past_comma (&str
) != (int) s3_FAIL
)
1981 s3_reg_required_here (&str
, 10, s3_REG_TYPE_SCORE_SR
);
1987 s3_do_rdxrs (char *str
)
1989 s3_skip_whitespace (str
);
1991 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
1992 || s3_skip_past_comma (&str
) == (int) s3_FAIL
1993 || s3_reg_required_here (&str
, 10, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
1994 || s3_end_of_line (str
) == (int) s3_FAIL
)
1997 if ((s3_inst
.relax_inst
!= 0x8000) && (((s3_inst
.instruction
>> 10) & 0x10) == 0)
1998 && (((s3_inst
.instruction
>> 20) & 0x10) == 0))
2000 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>> 10) & 0xf) << 4) | (((s3_inst
.instruction
>> 20) & 0xf) << 8);
2001 s3_inst
.relax_size
= 2;
2004 s3_inst
.relax_inst
= 0x8000;
2007 /* Handle cmp.c/cmp<cond>. */
2009 s3_do_rsrs (char *str
)
2011 s3_skip_whitespace (str
);
2013 if (s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
2014 || s3_skip_past_comma (&str
) == (int) s3_FAIL
2015 || s3_reg_required_here (&str
, 10, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
2016 || s3_end_of_line (str
) == (int) s3_FAIL
)
2019 if ((s3_inst
.relax_inst
!= 0x8000) && (((s3_inst
.instruction
>> 20) & 0x1f) == 3) )
2021 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>> 10) & 0x1f)) | (((s3_inst
.instruction
>> 15) & 0x1f) << 5);
2022 s3_inst
.relax_size
= 2;
2025 s3_inst
.relax_inst
= 0x8000;
2029 s3_do_ceinst (char *str
)
2034 s3_skip_whitespace (str
);
2036 if (s3_data_op2 (&str
, 20, _IMM5
) == (int) s3_FAIL
2037 || s3_skip_past_comma (&str
) == (int) s3_FAIL
2038 || s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
2039 || s3_skip_past_comma (&str
) == (int) s3_FAIL
2040 || s3_reg_required_here (&str
, 10, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
2041 || s3_skip_past_comma (&str
) == (int) s3_FAIL
2042 || s3_data_op2 (&str
, 5, _IMM5
) == (int) s3_FAIL
2043 || s3_skip_past_comma (&str
) == (int) s3_FAIL
2044 || s3_data_op2 (&str
, 0, _IMM5
) == (int) s3_FAIL
2045 || s3_end_of_line (str
) == (int) s3_FAIL
)
2052 if (s3_data_op2 (&str
, 0, _IMM25
) == (int) s3_FAIL
)
2058 s3_reglow_required_here (char **str
, int shift
)
2060 static char buff
[s3_MAX_LITERAL_POOL_SIZE
];
2064 if ((reg
= s3_score_reg_parse (str
, s3_all_reg_maps
[s3_REG_TYPE_SCORE
].htab
)) != (int) s3_FAIL
)
2066 if ((reg
== 1) && (s3_nor1
== 1) && (s3_inst
.bwarn
== 0))
2068 as_warn (_("Using temp register(r1)"));
2074 s3_inst
.instruction
|= (bfd_vma
) reg
<< shift
;
2080 /* Restore the start point, we may have got a reg of the wrong class. */
2082 sprintf (buff
, _("low register (r0-r15) expected, not '%.100s'"), start
);
2083 s3_inst
.error
= buff
;
2084 return (int) s3_FAIL
;
2087 /* Handle add!/and!/or!/sub!. */
2089 s3_do16_rdrs2 (char *str
)
2091 s3_skip_whitespace (str
);
2093 if (s3_reglow_required_here (&str
, 4) == (int) s3_FAIL
2094 || s3_skip_past_comma (&str
) == (int) s3_FAIL
2095 || s3_reglow_required_here (&str
, 0) == (int) s3_FAIL
2096 || s3_end_of_line (str
) == (int) s3_FAIL
)
2102 /* Handle br!/brl!. */
2104 s3_do16_br (char *str
)
2106 s3_skip_whitespace (str
);
2108 if (s3_reg_required_here (&str
, 0, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
2109 || s3_end_of_line (str
) == (int) s3_FAIL
)
2117 s3_do16_brr (char *str
)
2121 s3_skip_whitespace (str
);
2123 if ((rd
= s3_reg_required_here (&str
, 0,s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
2124 || s3_end_of_line (str
) == (int) s3_FAIL
)
2130 /*Handle ltbw / ltbh / ltbb */
2132 s3_do_ltb (char *str
)
2134 s3_skip_whitespace (str
);
2135 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
2136 || s3_skip_past_comma (&str
) == (int) s3_FAIL
)
2141 s3_skip_whitespace (str
);
2144 s3_inst
.error
= _("missing [");
2148 if (s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
2149 || s3_skip_past_comma (&str
) == (int) s3_FAIL
2150 || s3_reg_required_here (&str
, 10, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
)
2155 s3_skip_whitespace (str
);
2158 s3_inst
.error
= _("missing ]");
2163 /* We need to be able to fix up arbitrary expressions in some statements.
2164 This is so that we can handle symbols that are an arbitrary distance from
2165 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
2166 which returns part of an address in a form which will be valid for
2167 a data instruction. We do this by pushing the expression into a symbol
2168 in the expr_section, and creating a fix for that. */
2170 s3_fix_new_score (fragS
* frag
, int where
, short int size
, expressionS
* exp
, int pc_rel
, int reloc
)
2180 new_fix
= fix_new_exp (frag
, where
, size
, exp
, pc_rel
, reloc
);
2183 new_fix
= fix_new (frag
, where
, size
, make_expr_symbol (exp
), 0, pc_rel
, reloc
);
2190 s3_init_dependency_vector (void)
2194 for (i
= 0; i
< s3_vector_size
; i
++)
2195 memset (&s3_dependency_vector
[i
], '\0', sizeof (s3_dependency_vector
[i
]));
2200 static enum s3_insn_type_for_dependency
2201 s3_dependency_type_from_insn (char *insn_name
)
2203 char name
[s3_INSN_NAME_LEN
];
2204 const struct s3_insn_to_dependency
*tmp
;
2206 strcpy (name
, insn_name
);
2207 tmp
= (const struct s3_insn_to_dependency
*) hash_find (s3_dependency_insn_hsh
, name
);
2212 return s3_D_all_insn
;
2216 s3_check_dependency (char *pre_insn
, char *pre_reg
,
2217 char *cur_insn
, char *cur_reg
, int *warn_or_error
)
2221 enum s3_insn_type_for_dependency pre_insn_type
;
2222 enum s3_insn_type_for_dependency cur_insn_type
;
2224 pre_insn_type
= s3_dependency_type_from_insn (pre_insn
);
2225 cur_insn_type
= s3_dependency_type_from_insn (cur_insn
);
2227 for (i
= 0; i
< sizeof (s3_data_dependency_table
) / sizeof (s3_data_dependency_table
[0]); i
++)
2229 if ((pre_insn_type
== s3_data_dependency_table
[i
].pre_insn_type
)
2230 && (s3_D_all_insn
== s3_data_dependency_table
[i
].cur_insn_type
2231 || cur_insn_type
== s3_data_dependency_table
[i
].cur_insn_type
)
2232 && (strcmp (s3_data_dependency_table
[i
].pre_reg
, "") == 0
2233 || strcmp (s3_data_dependency_table
[i
].pre_reg
, pre_reg
) == 0)
2234 && (strcmp (s3_data_dependency_table
[i
].cur_reg
, "") == 0
2235 || strcmp (s3_data_dependency_table
[i
].cur_reg
, cur_reg
) == 0))
2237 bubbles
= s3_data_dependency_table
[i
].bubblenum_3
;
2238 *warn_or_error
= s3_data_dependency_table
[i
].warn_or_error
;
2247 s3_build_one_frag (struct s3_score_it one_inst
)
2250 int relaxable_p
= s3_g_opt
;
2253 /* Start a new frag if frag_now is not empty. */
2254 if (frag_now_fix () != 0)
2256 if (!frag_now
->tc_frag_data
.is_insn
)
2257 frag_wane (frag_now
);
2263 p
= frag_more (one_inst
.size
);
2264 s3_md_number_to_chars (p
, one_inst
.instruction
, one_inst
.size
);
2267 dwarf2_emit_insn (one_inst
.size
);
2270 relaxable_p
&= (one_inst
.relax_size
!= 0);
2271 relax_size
= relaxable_p
? one_inst
.relax_size
: 0;
2273 p
= frag_var (rs_machine_dependent
, relax_size
+ s3_RELAX_PAD_BYTE
, 0,
2274 s3_RELAX_ENCODE (one_inst
.size
, one_inst
.relax_size
,
2275 one_inst
.type
, 0, 0, relaxable_p
),
2279 s3_md_number_to_chars (p
, one_inst
.relax_inst
, relax_size
);
2283 s3_handle_dependency (struct s3_score_it
*theinst
)
2286 int warn_or_error
= 0; /* warn - 0; error - 1 */
2288 int remainder_bubbles
= 0;
2289 char cur_insn
[s3_INSN_NAME_LEN
];
2290 char pre_insn
[s3_INSN_NAME_LEN
];
2291 struct s3_score_it nop_inst
;
2292 struct s3_score_it pflush_inst
;
2294 nop_inst
.instruction
= 0x0000;
2296 nop_inst
.relax_inst
= 0x80008000;
2297 nop_inst
.relax_size
= 4;
2298 nop_inst
.type
= NO16_OPD
;
2300 pflush_inst
.instruction
= 0x8000800a;
2301 pflush_inst
.size
= 4;
2302 pflush_inst
.relax_inst
= 0x8000;
2303 pflush_inst
.relax_size
= 0;
2304 pflush_inst
.type
= NO_OPD
;
2306 /* pflush will clear all data dependency. */
2307 if (strcmp (theinst
->name
, "pflush") == 0)
2309 s3_init_dependency_vector ();
2313 /* Push current instruction to s3_dependency_vector[0]. */
2314 for (i
= s3_vector_size
- 1; i
> 0; i
--)
2315 memcpy (&s3_dependency_vector
[i
], &s3_dependency_vector
[i
- 1], sizeof (s3_dependency_vector
[i
]));
2317 memcpy (&s3_dependency_vector
[0], theinst
, sizeof (s3_dependency_vector
[i
]));
2319 /* There is no dependency between nop and any instruction. */
2320 if (strcmp (s3_dependency_vector
[0].name
, "nop") == 0
2321 || strcmp (s3_dependency_vector
[0].name
, "nop!") == 0)
2324 strcpy (cur_insn
, s3_dependency_vector
[0].name
);
2326 for (i
= 1; i
< s3_vector_size
; i
++)
2328 /* The element of s3_dependency_vector is NULL. */
2329 if (s3_dependency_vector
[i
].name
[0] == '\0')
2332 strcpy (pre_insn
, s3_dependency_vector
[i
].name
);
2334 bubbles
= s3_check_dependency (pre_insn
, s3_dependency_vector
[i
].reg
,
2335 cur_insn
, s3_dependency_vector
[0].reg
, &warn_or_error
);
2336 remainder_bubbles
= bubbles
- i
+ 1;
2338 if (remainder_bubbles
> 0)
2342 if (s3_fix_data_dependency
== 1)
2344 if (remainder_bubbles
<= 2)
2346 if (s3_warn_fix_data_dependency
)
2347 as_warn (_("Fix data dependency: %s %s -- %s %s (insert %d nop!/%d)"),
2348 s3_dependency_vector
[i
].name
, s3_dependency_vector
[i
].reg
,
2349 s3_dependency_vector
[0].name
, s3_dependency_vector
[0].reg
,
2350 remainder_bubbles
, bubbles
);
2352 for (j
= (s3_vector_size
- 1); (j
- remainder_bubbles
) > 0; j
--)
2353 memcpy (&s3_dependency_vector
[j
], &s3_dependency_vector
[j
- remainder_bubbles
],
2354 sizeof (s3_dependency_vector
[j
]));
2356 for (j
= 1; j
<= remainder_bubbles
; j
++)
2358 memset (&s3_dependency_vector
[j
], '\0', sizeof (s3_dependency_vector
[j
]));
2360 s3_build_one_frag (nop_inst
);
2365 if (s3_warn_fix_data_dependency
)
2366 as_warn (_("Fix data dependency: %s %s -- %s %s (insert 1 pflush/%d)"),
2367 s3_dependency_vector
[i
].name
, s3_dependency_vector
[i
].reg
,
2368 s3_dependency_vector
[0].name
, s3_dependency_vector
[0].reg
,
2371 for (j
= 1; j
< s3_vector_size
; j
++)
2372 memset (&s3_dependency_vector
[j
], '\0', sizeof (s3_dependency_vector
[j
]));
2374 /* Insert pflush. */
2375 s3_build_one_frag (pflush_inst
);
2382 as_bad (_("data dependency: %s %s -- %s %s (%d/%d bubble)"),
2383 s3_dependency_vector
[i
].name
, s3_dependency_vector
[i
].reg
,
2384 s3_dependency_vector
[0].name
, s3_dependency_vector
[0].reg
,
2385 remainder_bubbles
, bubbles
);
2389 as_warn (_("data dependency: %s %s -- %s %s (%d/%d bubble)"),
2390 s3_dependency_vector
[i
].name
, s3_dependency_vector
[i
].reg
,
2391 s3_dependency_vector
[0].name
, s3_dependency_vector
[0].reg
,
2392 remainder_bubbles
, bubbles
);
2399 static enum insn_class
2400 s3_get_insn_class_from_type (enum score_insn_type type
)
2402 enum insn_class retval
= (int) s3_FAIL
;
2408 case Rd_rvalueBP_I5
:
2409 case Rd_lvalueBP_I5
:
2422 retval
= INSN_CLASS_16
;
2431 case Rd_rvalueRs_SI10
:
2432 case Rd_lvalueRs_SI10
:
2433 case Rd_rvalueRs_preSI12
:
2434 case Rd_rvalueRs_postSI12
:
2435 case Rd_lvalueRs_preSI12
:
2436 case Rd_lvalueRs_postSI12
:
2438 case Rd_rvalueRs_SI15
:
2439 case Rd_lvalueRs_SI15
:
2448 case OP5_rvalueRs_SI15
:
2449 case I5_Rs_Rs_I5_OP5
:
2450 case x_rvalueRs_post4
:
2451 case Rd_rvalueRs_post4
:
2453 case Rd_lvalueRs_post4
:
2454 case x_lvalueRs_post4
:
2464 retval
= INSN_CLASS_32
;
2467 retval
= INSN_CLASS_PCE
;
2470 retval
= INSN_CLASS_SYN
;
2474 retval
= INSN_CLASS_48
;
2484 48-bit instruction: 1, 1, 0.
2485 32-bit instruction: 1, 0.
2486 16-bit instruction: 0. */
2488 s3_adjust_paritybit (bfd_vma m_code
, enum insn_class i_class
)
2491 bfd_vma m_code_high
= 0;
2492 unsigned long m_code_middle
= 0;
2493 unsigned long m_code_low
= 0;
2494 bfd_vma pb_high
= 0;
2495 unsigned long pb_middle
= 0;
2496 unsigned long pb_low
= 0;
2498 if (i_class
== INSN_CLASS_48
)
2500 pb_high
= 0x800000000000LL
;
2501 pb_middle
= 0x80000000;
2502 pb_low
= 0x00000000;
2503 m_code_high
= m_code
& 0x1fffc0000000LL
;
2504 m_code_middle
= m_code
& 0x3fff8000;
2505 m_code_low
= m_code
& 0x00007fff;
2506 result
= pb_high
| (m_code_high
<< 2) |
2507 pb_middle
| (m_code_middle
<< 1) |
2508 pb_low
| m_code_low
;
2510 else if (i_class
== INSN_CLASS_32
|| i_class
== INSN_CLASS_SYN
)
2512 pb_high
= 0x80000000;
2513 pb_low
= 0x00000000;
2514 m_code_high
= m_code
& 0x3fff8000;
2515 m_code_low
= m_code
& 0x00007fff;
2516 result
= pb_high
| (m_code_high
<< 1) | pb_low
| m_code_low
;
2518 else if (i_class
== INSN_CLASS_16
)
2522 m_code_high
= m_code
& 0x3fff8000;
2523 m_code_low
= m_code
& 0x00007fff;
2524 result
= pb_high
| (m_code_high
<< 1) | pb_low
| m_code_low
;
2526 else if (i_class
== INSN_CLASS_PCE
)
2528 /* Keep original. */
2530 pb_low
= 0x00008000;
2531 m_code_high
= m_code
& 0x3fff8000;
2532 m_code_low
= m_code
& 0x00007fff;
2533 result
= pb_high
| (m_code_high
<< 1) | pb_low
| m_code_low
;
2544 s3_gen_insn_frag (struct s3_score_it
*part_1
, struct s3_score_it
*part_2
)
2547 bfd_boolean pce_p
= FALSE
;
2548 int relaxable_p
= s3_g_opt
;
2550 struct s3_score_it
*inst1
= part_1
;
2551 struct s3_score_it
*inst2
= part_2
;
2552 struct s3_score_it backup_inst1
;
2554 pce_p
= (inst2
) ? TRUE
: FALSE
;
2555 memcpy (&backup_inst1
, inst1
, sizeof (struct s3_score_it
));
2557 /* Adjust instruction opcode and to be relaxed instruction opcode. */
2560 backup_inst1
.instruction
= ((backup_inst1
.instruction
& 0x7FFF) << 15)
2561 | (inst2
->instruction
& 0x7FFF);
2562 backup_inst1
.instruction
= s3_adjust_paritybit (backup_inst1
.instruction
, INSN_CLASS_PCE
);
2563 backup_inst1
.relax_inst
= 0x8000;
2564 backup_inst1
.size
= s3_INSN_SIZE
;
2565 backup_inst1
.relax_size
= 0;
2566 backup_inst1
.type
= Insn_Type_PCE
;
2570 backup_inst1
.instruction
= s3_adjust_paritybit (backup_inst1
.instruction
,
2571 s3_GET_INSN_CLASS (backup_inst1
.type
));
2574 if (backup_inst1
.relax_size
!= 0)
2576 enum insn_class tmp
;
2578 tmp
= (backup_inst1
.size
== s3_INSN_SIZE
) ? INSN_CLASS_16
: INSN_CLASS_32
;
2579 backup_inst1
.relax_inst
= s3_adjust_paritybit (backup_inst1
.relax_inst
, tmp
);
2582 /* Check data dependency. */
2583 s3_handle_dependency (&backup_inst1
);
2585 /* Start a new frag if frag_now is not empty and is not instruction frag, maybe it contains
2586 data produced by .ascii etc. Doing this is to make one instruction per frag. */
2587 if (frag_now_fix () != 0)
2589 if (!frag_now
->tc_frag_data
.is_insn
)
2590 frag_wane (frag_now
);
2595 /* Here, we must call frag_grow in order to keep the instruction frag type is
2596 rs_machine_dependent.
2597 For, frag_var may change frag_now->fr_type to rs_fill by calling frag_grow which
2598 actually will call frag_wane.
2599 Calling frag_grow first will create a new frag_now which free size is 20 that is enough
2603 p
= frag_more (backup_inst1
.size
);
2604 s3_md_number_to_chars (p
, backup_inst1
.instruction
, backup_inst1
.size
);
2607 dwarf2_emit_insn (backup_inst1
.size
);
2610 /* Generate fixup structure. */
2613 if (inst1
->reloc
.type
!= BFD_RELOC_NONE
)
2614 s3_fix_new_score (frag_now
, p
- frag_now
->fr_literal
,
2615 inst1
->size
, &inst1
->reloc
.exp
,
2616 inst1
->reloc
.pc_rel
, inst1
->reloc
.type
);
2618 if (inst2
->reloc
.type
!= BFD_RELOC_NONE
)
2619 s3_fix_new_score (frag_now
, p
- frag_now
->fr_literal
+ 2,
2620 inst2
->size
, &inst2
->reloc
.exp
, inst2
->reloc
.pc_rel
, inst2
->reloc
.type
);
2624 if (backup_inst1
.reloc
.type
!= BFD_RELOC_NONE
)
2625 s3_fix_new_score (frag_now
, p
- frag_now
->fr_literal
,
2626 backup_inst1
.size
, &backup_inst1
.reloc
.exp
,
2627 backup_inst1
.reloc
.pc_rel
, backup_inst1
.reloc
.type
);
2630 /* relax_size may be 2, 4, 12 or 0, 0 indicates no relaxation. */
2631 relaxable_p
&= (backup_inst1
.relax_size
!= 0);
2632 relax_size
= relaxable_p
? backup_inst1
.relax_size
: 0;
2634 p
= frag_var (rs_machine_dependent
, relax_size
+ s3_RELAX_PAD_BYTE
, 0,
2635 s3_RELAX_ENCODE (backup_inst1
.size
, backup_inst1
.relax_size
,
2636 backup_inst1
.type
, 0, 0, relaxable_p
),
2637 backup_inst1
.reloc
.exp
.X_add_symbol
, 0, NULL
);
2640 s3_md_number_to_chars (p
, backup_inst1
.relax_inst
, relax_size
);
2642 memcpy (inst1
, &backup_inst1
, sizeof (struct s3_score_it
));
2646 s3_parse_16_32_inst (char *insnstr
, bfd_boolean gen_frag_p
)
2650 char *operator = insnstr
;
2651 const struct s3_asm_opcode
*opcode
;
2653 /* Parse operator and operands. */
2654 s3_skip_whitespace (operator);
2656 for (p
= operator; *p
!= '\0'; p
++)
2657 if ((*p
== ' ') || (*p
== '!'))
2666 opcode
= (const struct s3_asm_opcode
*) hash_find (s3_score_ops_hsh
, operator);
2669 memset (&s3_inst
, '\0', sizeof (s3_inst
));
2670 sprintf (s3_inst
.str
, "%s", insnstr
);
2673 s3_inst
.instruction
= opcode
->value
;
2674 s3_inst
.relax_inst
= opcode
->relax_value
;
2675 s3_inst
.type
= opcode
->type
;
2676 s3_inst
.size
= s3_GET_INSN_SIZE (s3_inst
.type
);
2677 s3_inst
.relax_size
= 0;
2679 sprintf (s3_inst
.name
, "%s", opcode
->template_name
);
2680 strcpy (s3_inst
.reg
, "");
2681 s3_inst
.error
= NULL
;
2682 s3_inst
.reloc
.type
= BFD_RELOC_NONE
;
2684 (*opcode
->parms
) (p
);
2686 /* It indicates current instruction is a macro instruction if s3_inst.bwarn equals -1. */
2687 if ((s3_inst
.bwarn
!= -1) && (!s3_inst
.error
) && (gen_frag_p
))
2688 s3_gen_insn_frag (&s3_inst
, NULL
);
2691 s3_inst
.error
= _("unrecognized opcode");
2695 s3_parse_48_inst (char *insnstr
, bfd_boolean gen_frag_p
)
2699 char *operator = insnstr
;
2700 const struct s3_asm_opcode
*opcode
;
2702 /* Parse operator and operands. */
2703 s3_skip_whitespace (operator);
2705 for (p
= operator; *p
!= '\0'; p
++)
2712 opcode
= (const struct s3_asm_opcode
*) hash_find (s3_score_ops_hsh
, operator);
2715 memset (&s3_inst
, '\0', sizeof (s3_inst
));
2716 sprintf (s3_inst
.str
, "%s", insnstr
);
2719 s3_inst
.instruction
= opcode
->value
;
2720 s3_inst
.relax_inst
= opcode
->relax_value
;
2721 s3_inst
.type
= opcode
->type
;
2722 s3_inst
.size
= s3_GET_INSN_SIZE (s3_inst
.type
);
2723 s3_inst
.relax_size
= 0;
2725 sprintf (s3_inst
.name
, "%s", opcode
->template_name
);
2726 strcpy (s3_inst
.reg
, "");
2727 s3_inst
.error
= NULL
;
2728 s3_inst
.reloc
.type
= BFD_RELOC_NONE
;
2730 (*opcode
->parms
) (p
);
2732 /* It indicates current instruction is a macro instruction if s3_inst.bwarn equals -1. */
2733 if ((s3_inst
.bwarn
!= -1) && (!s3_inst
.error
) && (gen_frag_p
))
2734 s3_gen_insn_frag (&s3_inst
, NULL
);
2737 s3_inst
.error
= _("unrecognized opcode");
2741 s3_append_insn (char *str
, bfd_boolean gen_frag_p
)
2743 int retval
= s3_SUCCESS
;
2745 s3_parse_16_32_inst (str
, gen_frag_p
);
2749 retval
= (int) s3_FAIL
;
2750 as_bad (_("%s -- `%s'"), s3_inst
.error
, s3_inst
.str
);
2751 s3_inst
.error
= NULL
;
2758 s3_do16_mv_cmp (char *str
)
2760 s3_skip_whitespace (str
);
2762 if (s3_reg_required_here (&str
, 5, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
2763 || s3_skip_past_comma (&str
) == (int) s3_FAIL
2764 || s3_reg_required_here (&str
, 0, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
2765 || s3_end_of_line (str
) == (int) s3_FAIL
)
2772 s3_do16_cmpi (char *str
)
2774 s3_skip_whitespace (str
);
2776 if (s3_reg_required_here (&str
, 5, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
2777 || s3_skip_past_comma (&str
) == (int) s3_FAIL
2778 || s3_data_op2 (&str
, 0, _SIMM5
) == (int) s3_FAIL
2779 || s3_end_of_line (str
) == (int) s3_FAIL
)
2786 s3_do16_addi (char *str
)
2788 s3_skip_whitespace (str
);
2790 if (s3_reglow_required_here (&str
, 6) == (int) s3_FAIL
2791 || s3_skip_past_comma (&str
) == (int) s3_FAIL
2792 || s3_data_op2 (&str
, 0, _SIMM6
) == (int) s3_FAIL
2793 || s3_end_of_line (str
) == (int) s3_FAIL
)
2799 /* Handle bitclr! / bitset! / bittst! / bittgl! */
2801 s3_do16_rdi5 (char *str
)
2803 s3_skip_whitespace (str
);
2805 if (s3_reglow_required_here (&str
, 5) == (int) s3_FAIL
2806 || s3_skip_past_comma (&str
) == (int) s3_FAIL
2807 || s3_data_op2 (&str
, 0, _IMM5
) == (int) s3_FAIL
2808 || s3_end_of_line (str
) == (int) s3_FAIL
)
2812 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>>5) & 0xf) << 20)
2813 | (((s3_inst
.instruction
>> 5) & 0xf) << 15) | (((s3_inst
.instruction
) & 0x1f) << 10);
2814 s3_inst
.relax_size
= 4;
2819 /* Handle sdbbp!. */
2821 s3_do16_xi5 (char *str
)
2823 s3_skip_whitespace (str
);
2825 if (s3_data_op2 (&str
, 0, _IMM5
) == (int) s3_FAIL
|| s3_end_of_line (str
) == (int) s3_FAIL
)
2829 /* Check that an immediate is word alignment or half word alignment.
2830 If so, convert it to the right format. */
2832 s3_validate_immediate_align (int val
, unsigned int data_type
)
2834 if (data_type
== _IMM5_RSHIFT_1
)
2838 s3_inst
.error
= _("address offset must be half word alignment");
2839 return (int) s3_FAIL
;
2842 else if ((data_type
== _IMM5_RSHIFT_2
) || (data_type
== _IMM10_RSHIFT_2
))
2846 s3_inst
.error
= _("address offset must be word alignment");
2847 return (int) s3_FAIL
;
2855 s3_exp_ldst_offset (char **str
, int shift
, unsigned int data_type
)
2861 if ((*dataptr
== '0') && (*(dataptr
+ 1) == 'x')
2862 && (data_type
!= _SIMM16_LA
)
2863 && (data_type
!= _VALUE_HI16
)
2864 && (data_type
!= _VALUE_LO16
)
2865 && (data_type
!= _IMM16
)
2866 && (data_type
!= _IMM15
)
2867 && (data_type
!= _IMM14
)
2868 && (data_type
!= _IMM4
)
2869 && (data_type
!= _IMM5
)
2870 && (data_type
!= _IMM8
)
2871 && (data_type
!= _IMM5_RSHIFT_1
)
2872 && (data_type
!= _IMM5_RSHIFT_2
)
2873 && (data_type
!= _SIMM14_NEG
)
2874 && (data_type
!= _IMM10_RSHIFT_2
))
2879 if (s3_my_get_expression (&s3_inst
.reloc
.exp
, str
) == (int) s3_FAIL
)
2880 return (int) s3_FAIL
;
2882 if (s3_inst
.reloc
.exp
.X_op
== O_constant
)
2884 /* Need to check the immediate align. */
2885 int value
= s3_validate_immediate_align (s3_inst
.reloc
.exp
.X_add_number
, data_type
);
2887 if (value
== (int) s3_FAIL
)
2888 return (int) s3_FAIL
;
2890 value
= s3_validate_immediate (s3_inst
.reloc
.exp
.X_add_number
, data_type
, 0);
2891 if (value
== (int) s3_FAIL
)
2894 sprintf (s3_err_msg
,
2895 _("invalid constant: %d bit expression not in range %d..%d"),
2896 s3_score_df_range
[data_type
].bits
,
2897 s3_score_df_range
[data_type
].range
[0], s3_score_df_range
[data_type
].range
[1]);
2899 sprintf (s3_err_msg
,
2900 _("invalid constant: %d bit expression not in range %d..%d"),
2901 s3_score_df_range
[data_type
- 24].bits
,
2902 s3_score_df_range
[data_type
- 24].range
[0], s3_score_df_range
[data_type
- 24].range
[1]);
2903 s3_inst
.error
= s3_err_msg
;
2904 return (int) s3_FAIL
;
2907 if (data_type
== _IMM5_RSHIFT_1
)
2911 else if ((data_type
== _IMM5_RSHIFT_2
) || (data_type
== _IMM10_RSHIFT_2
))
2916 if (s3_score_df_range
[data_type
].range
[0] != 0)
2918 value
&= (1 << s3_score_df_range
[data_type
].bits
) - 1;
2921 s3_inst
.instruction
|= value
<< shift
;
2925 s3_inst
.reloc
.pc_rel
= 0;
2932 s3_do_ldst_insn (char *str
)
2942 s3_skip_whitespace (str
);
2944 if (((conflict_reg
= s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
)
2945 || (s3_skip_past_comma (&str
) == (int) s3_FAIL
))
2948 /* ld/sw rD, [rA, simm15] ld/sw rD, [rA]+, simm12 ld/sw rD, [rA, simm12]+. */
2952 s3_skip_whitespace (str
);
2954 if ((reg
= s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
)
2957 /* Conflicts can occur on stores as well as loads. */
2958 conflict_reg
= (conflict_reg
== reg
);
2959 s3_skip_whitespace (str
);
2960 temp
= str
+ 1; /* The latter will process decimal/hex expression. */
2962 /* ld/sw rD, [rA]+, simm12 ld/sw rD, [rA]+. */
2969 /* ld/sw rD, [rA]+, simm12. */
2970 if (s3_skip_past_comma (&str
) == s3_SUCCESS
)
2972 if ((s3_exp_ldst_offset (&str
, 3, _SIMM12
) == (int) s3_FAIL
)
2973 || (s3_end_of_line (str
) == (int) s3_FAIL
))
2978 unsigned int ldst_func
= s3_inst
.instruction
& OPC_PSEUDOLDST_MASK
;
2980 if ((ldst_func
== INSN_LH
)
2981 || (ldst_func
== INSN_LHU
)
2982 || (ldst_func
== INSN_LW
)
2983 || (ldst_func
== INSN_LB
)
2984 || (ldst_func
== INSN_LBU
))
2986 s3_inst
.error
= _("register same as write-back base");
2991 ldst_idx
= s3_inst
.instruction
& OPC_PSEUDOLDST_MASK
;
2992 s3_inst
.instruction
&= ~OPC_PSEUDOLDST_MASK
;
2993 s3_inst
.instruction
|= s3_score_ldst_insns
[ldst_idx
* 3 + LDST_POST
].value
;
2995 /* lw rD, [rA]+, 4 convert to pop rD, [rA]. */
2996 if ((s3_inst
.instruction
& 0x3e000007) == 0x0e000000)
2998 /* rs = r0, offset = 4 */
2999 if ((((s3_inst
.instruction
>> 15) & 0x1f) == 0)
3000 && (((s3_inst
.instruction
>> 3) & 0xfff) == 4))
3002 /* Relax to pop!. */
3003 s3_inst
.relax_inst
= 0x0040 | ((s3_inst
.instruction
>> 20) & 0x1f);
3004 s3_inst
.relax_size
= 2;
3009 /* ld/sw rD, [rA]+ convert to ld/sw rD, [rA, 0]+. */
3012 s3_SET_INSN_ERROR (NULL
);
3013 if (s3_end_of_line (str
) == (int) s3_FAIL
)
3019 value
= s3_validate_immediate (s3_inst
.reloc
.exp
.X_add_number
, _SIMM12
, 0);
3020 value
&= (1 << s3_score_df_range
[_SIMM12
].bits
) - 1;
3021 ldst_idx
= s3_inst
.instruction
& OPC_PSEUDOLDST_MASK
;
3022 s3_inst
.instruction
&= ~OPC_PSEUDOLDST_MASK
;
3023 s3_inst
.instruction
|= s3_score_ldst_insns
[ldst_idx
* 3 + pre_inc
].value
;
3024 s3_inst
.instruction
|= value
<< 3;
3025 s3_inst
.relax_inst
= 0x8000;
3029 /* ld/sw rD, [rA] convert to ld/sw rD, [rA, simm15]. */
3032 if (s3_end_of_line (str
) == (int) s3_FAIL
)
3035 ldst_idx
= s3_inst
.instruction
& OPC_PSEUDOLDST_MASK
;
3036 s3_inst
.instruction
&= ~OPC_PSEUDOLDST_MASK
;
3037 s3_inst
.instruction
|= s3_score_ldst_insns
[ldst_idx
* 3 + LDST_NOUPDATE
].value
;
3039 /* lbu rd, [rs] -> lbu! rd, [rs] */
3040 if (ldst_idx
== INSN_LBU
)
3042 s3_inst
.relax_inst
= INSN16_LBU
;
3044 else if (ldst_idx
== INSN_LH
)
3046 s3_inst
.relax_inst
= INSN16_LH
;
3048 else if (ldst_idx
== INSN_LW
)
3050 s3_inst
.relax_inst
= INSN16_LW
;
3052 else if (ldst_idx
== INSN_SB
)
3054 s3_inst
.relax_inst
= INSN16_SB
;
3056 else if (ldst_idx
== INSN_SH
)
3058 s3_inst
.relax_inst
= INSN16_SH
;
3060 else if (ldst_idx
== INSN_SW
)
3062 s3_inst
.relax_inst
= INSN16_SW
;
3066 s3_inst
.relax_inst
= 0x8000;
3069 /* lw/lh/lbu/sw/sh/sb, offset = 0, relax to 16 bit instruction. */
3070 /* if ((ldst_idx == INSN_LBU)
3071 || (ldst_idx == INSN_LH)
3072 || (ldst_idx == INSN_LW)
3073 || (ldst_idx == INSN_SB) || (ldst_idx == INSN_SH) || (ldst_idx == INSN_SW))*/
3074 if ( (ldst_idx
== INSN_LW
)|| (ldst_idx
== INSN_SW
))
3076 /* ra only 3 bit , rd only 4 bit for lw! and sw! */
3077 if ((((s3_inst
.instruction
>> 15) & 0x18) == 0) && (((s3_inst
.instruction
>> 20) & 0x10) == 0))
3079 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>> 20) & 0xf) << 8) |
3080 (((s3_inst
.instruction
>> 15) & 0x7) << 5);
3081 s3_inst
.relax_size
= 2;
3088 /* ld/sw rD, [rA, simm15] ld/sw rD, [rA, simm12]+. */
3091 if (s3_skip_past_comma (&str
) == (int) s3_FAIL
)
3093 s3_inst
.error
= _("pre-indexed expression expected");
3097 if (s3_my_get_expression (&s3_inst
.reloc
.exp
, &str
) == (int) s3_FAIL
)
3100 s3_skip_whitespace (str
);
3103 s3_inst
.error
= _("missing ]");
3107 s3_skip_whitespace (str
);
3108 /* ld/sw rD, [rA, simm12]+. */
3115 unsigned int ldst_func
= s3_inst
.instruction
& OPC_PSEUDOLDST_MASK
;
3117 if ((ldst_func
== INSN_LH
)
3118 || (ldst_func
== INSN_LHU
)
3119 || (ldst_func
== INSN_LW
)
3120 || (ldst_func
== INSN_LB
)
3121 || (ldst_func
== INSN_LBU
))
3123 s3_inst
.error
= _("register same as write-back base");
3129 if (s3_end_of_line (str
) == (int) s3_FAIL
)
3132 if (s3_inst
.reloc
.exp
.X_op
== O_constant
)
3134 unsigned int data_type
;
3137 data_type
= _SIMM12
;
3139 data_type
= _SIMM15
;
3142 if ((*dataptr
== '0') && (*(dataptr
+ 1) == 'x')
3143 && (data_type
!= _SIMM16_LA
)
3144 && (data_type
!= _VALUE_HI16
)
3145 && (data_type
!= _VALUE_LO16
)
3146 && (data_type
!= _IMM16
)
3147 && (data_type
!= _IMM15
)
3148 && (data_type
!= _IMM14
)
3149 && (data_type
!= _IMM4
)
3150 && (data_type
!= _IMM5
)
3151 && (data_type
!= _IMM8
)
3152 && (data_type
!= _IMM5_RSHIFT_1
)
3153 && (data_type
!= _IMM5_RSHIFT_2
)
3154 && (data_type
!= _SIMM14_NEG
)
3155 && (data_type
!= _IMM10_RSHIFT_2
))
3160 value
= s3_validate_immediate (s3_inst
.reloc
.exp
.X_add_number
, data_type
, 0);
3161 if (value
== (int) s3_FAIL
)
3164 sprintf (s3_err_msg
,
3165 _("invalid constant: %d bit expression not in range %d..%d"),
3166 s3_score_df_range
[data_type
].bits
,
3167 s3_score_df_range
[data_type
].range
[0], s3_score_df_range
[data_type
].range
[1]);
3169 sprintf (s3_err_msg
,
3170 _("invalid constant: %d bit expression not in range %d..%d"),
3171 s3_score_df_range
[data_type
- 24].bits
,
3172 s3_score_df_range
[data_type
- 24].range
[0],
3173 s3_score_df_range
[data_type
- 24].range
[1]);
3174 s3_inst
.error
= s3_err_msg
;
3178 value
&= (1 << s3_score_df_range
[data_type
].bits
) - 1;
3179 ldst_idx
= s3_inst
.instruction
& OPC_PSEUDOLDST_MASK
;
3180 s3_inst
.instruction
&= ~OPC_PSEUDOLDST_MASK
;
3181 s3_inst
.instruction
|= s3_score_ldst_insns
[ldst_idx
* 3 + pre_inc
].value
;
3183 s3_inst
.instruction
|= value
<< 3;
3185 s3_inst
.instruction
|= value
;
3187 /* lw rD, [rA, simm15] */
3188 if ((s3_inst
.instruction
& 0x3e000000) == 0x20000000)
3190 /* rD in [r0 - r15]. , ra in [r0-r7] */
3191 if ((((s3_inst
.instruction
>> 15) & 0x18) == 0)
3192 && (((s3_inst
.instruction
>> 20) & 0x10) == 0))
3194 /* simm = [bit 7], lw -> lw!. */
3195 if (((s3_inst
.instruction
& 0x7f80) == 0)&&((s3_inst
.instruction
&0x3)==0))
3197 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>> 15) & 0x7) << 5)
3198 | (((s3_inst
.instruction
>> 20) & 0xf) << 8)|(value
>>2);
3199 s3_inst
.relax_size
= 2;
3203 s3_inst
.relax_inst
= 0x8000;
3208 s3_inst
.relax_inst
= 0x8000;
3211 /* sw rD, [rA, simm15] */
3212 else if ((s3_inst
.instruction
& 0x3e000000) == 0x28000000)
3214 /* rD is in [r0 - r15] and ra in [r0-r7] */
3215 if ((((s3_inst
.instruction
>> 15) & 0x18) == 0) && (((s3_inst
.instruction
>> 20) & 0x10) == 0))
3217 /* simm15 =7 bit , sw -> sw!. */
3218 if (((s3_inst
.instruction
& 0x7f80) == 0)&&((s3_inst
.instruction
&0x3)==0))
3220 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>> 15) & 0xf) << 5)
3221 | (((s3_inst
.instruction
>> 20) & 0xf) << 8)|(value
>>2);
3222 s3_inst
.relax_size
= 2;
3224 /* rA = r2, sw -> swp!. */
3227 s3_inst
.relax_inst
= 0x8000;
3232 s3_inst
.relax_inst
= 0x8000;
3235 /* sw rD, [rA, simm15]+ sw pre. */
3236 else if ((s3_inst
.instruction
& 0x3e000007) == 0x06000004)
3238 /* simm15 = -4. and ra==r0 */
3239 if ((((s3_inst
.instruction
>> 15) & 0x1f) == 0)
3240 && (((s3_inst
.instruction
>> 3) & 0xfff) == 0xffc))
3243 s3_inst
.relax_inst
= 0x0060 | ((s3_inst
.instruction
>> 20) & 0x1f);
3244 s3_inst
.relax_size
= 2;
3248 s3_inst
.relax_inst
= 0x8000;
3253 s3_inst
.relax_inst
= 0x8000;
3260 /* FIXME: may set error, for there is no ld/sw rD, [rA, label] */
3261 s3_inst
.reloc
.pc_rel
= 0;
3267 s3_inst
.error
= s3_BAD_ARGS
;
3273 s3_do_cache (char *str
)
3275 s3_skip_whitespace (str
);
3277 if ((s3_data_op2 (&str
, 20, _IMM5
) == (int) s3_FAIL
) || (s3_skip_past_comma (&str
) == (int) s3_FAIL
))
3285 cache_op
= (s3_inst
.instruction
>> 20) & 0x1F;
3286 sprintf (s3_inst
.name
, "cache %d", cache_op
);
3292 s3_skip_whitespace (str
);
3294 if (s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
)
3297 s3_skip_whitespace (str
);
3299 /* cache op, [rA] */
3300 if (s3_skip_past_comma (&str
) == (int) s3_FAIL
)
3302 s3_SET_INSN_ERROR (NULL
);
3305 s3_inst
.error
= _("missing ]");
3310 /* cache op, [rA, simm15] */
3313 if (s3_exp_ldst_offset (&str
, 0, _SIMM15
) == (int) s3_FAIL
)
3318 s3_skip_whitespace (str
);
3321 s3_inst
.error
= _("missing ]");
3326 if (s3_end_of_line (str
) == (int) s3_FAIL
)
3331 s3_inst
.error
= s3_BAD_ARGS
;
3336 s3_do_crdcrscrsimm5 (char *str
)
3341 s3_skip_whitespace (str
);
3343 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE_CR
) == (int) s3_FAIL
3344 || s3_skip_past_comma (&str
) == (int) s3_FAIL
3345 || s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE_CR
) == (int) s3_FAIL
3346 || s3_skip_past_comma (&str
) == (int) s3_FAIL
3347 || s3_reg_required_here (&str
, 10, s3_REG_TYPE_SCORE_CR
) == (int) s3_FAIL
3348 || s3_skip_past_comma (&str
) == (int) s3_FAIL
)
3351 /* cop1 cop_code20. */
3352 if (s3_data_op2 (&str
, 5, _IMM20
) == (int) s3_FAIL
)
3357 if (s3_data_op2 (&str
, 5, _IMM5
) == (int) s3_FAIL
)
3361 s3_end_of_line (str
);
3364 /* Handle ldc/stc. */
3366 s3_do_ldst_cop (char *str
)
3368 s3_skip_whitespace (str
);
3370 if ((s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE_CR
) == (int) s3_FAIL
)
3371 || (s3_skip_past_comma (&str
) == (int) s3_FAIL
))
3377 s3_skip_whitespace (str
);
3379 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
)
3382 s3_skip_whitespace (str
);
3386 if (s3_exp_ldst_offset (&str
, 5, _IMM10_RSHIFT_2
) == (int) s3_FAIL
)
3389 s3_skip_whitespace (str
);
3392 s3_inst
.error
= _("missing ]");
3397 s3_end_of_line (str
);
3400 s3_inst
.error
= s3_BAD_ARGS
;
3404 s3_do16_ldst_insn (char *str
)
3406 int conflict_reg
= 0;
3407 s3_skip_whitespace (str
);
3409 if ((s3_reglow_required_here (&str
, 8) == (int) s3_FAIL
) || (s3_skip_past_comma (&str
) == (int) s3_FAIL
))
3416 s3_skip_whitespace (str
);
3418 if ((conflict_reg
= s3_reglow_required_here (&str
, 5)) == (int) s3_FAIL
)
3420 if (conflict_reg
&0x8)
3422 sprintf (s3_err_msg
, _("invalid register number: %d is not in [r0--r7]"),conflict_reg
);
3423 s3_inst
.error
= s3_err_msg
;
3427 s3_skip_whitespace (str
);
3432 if (s3_end_of_line (str
) == (int) s3_FAIL
)
3437 if (s3_skip_past_comma (&str
) == (int) s3_FAIL
)
3439 s3_inst
.error
= _("comma is expected");
3442 if (s3_my_get_expression (&s3_inst
.reloc
.exp
, &str
) == (int) s3_FAIL
)
3444 s3_skip_whitespace (str
);
3447 s3_inst
.error
= _("missing ]");
3450 if (s3_end_of_line (str
) == (int) s3_FAIL
)
3452 if (s3_inst
.reloc
.exp
.X_op
== O_constant
)
3455 unsigned int data_type
;
3456 data_type
= _IMM5_RSHIFT_2
;
3457 value
= s3_validate_immediate (s3_inst
.reloc
.exp
.X_add_number
, data_type
, 0);
3458 if (value
== (int) s3_FAIL
)
3461 sprintf (s3_err_msg
,
3462 _("invalid constant: %d bit expression not in range %d..%d"),
3463 s3_score_df_range
[data_type
].bits
,
3464 s3_score_df_range
[data_type
].range
[0], s3_score_df_range
[data_type
].range
[1]);
3465 s3_inst
.error
= s3_err_msg
;
3470 sprintf (s3_err_msg
, _("invalid constant: %d is not word align integer"),value
);
3471 s3_inst
.error
= s3_err_msg
;
3476 s3_inst
.instruction
|= value
;
3482 sprintf (s3_err_msg
, _("missing ["));
3483 s3_inst
.error
= s3_err_msg
;
3489 s3_do_lw48 (char *str
)
3491 bfd_signed_vma val
= 0;
3493 s3_skip_whitespace (str
);
3495 if ((s3_reg_required_here (&str
, 37, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
)
3496 || (s3_skip_past_comma (&str
) == (int) s3_FAIL
))
3499 if (s3_my_get_expression (&s3_inst
.reloc
.exp
, &str
) == (int) s3_FAIL
3500 || s3_end_of_line (str
) == (int) s3_FAIL
)
3505 /* Check word align for lw48 rd, value. */
3506 if ((s3_inst
.reloc
.exp
.X_add_symbol
== NULL
)
3507 && ((s3_inst
.reloc
.exp
.X_add_number
& 0x3) != 0))
3509 s3_inst
.error
= _("invalid constant: 32 bit expression not word align");
3513 /* Check and set offset. */
3514 val
= s3_inst
.reloc
.exp
.X_add_number
;
3515 if ((s3_inst
.reloc
.exp
.X_add_symbol
== NULL
)
3516 && (!(val
>= 0 && val
<= 0xffffffffLL
)))
3518 s3_inst
.error
= _("invalid constant: 32 bit expression not in range [0, 0xffffffff]");
3524 s3_inst
.instruction
|= (val
<< 7);
3526 /* Set reloc type. */
3527 s3_inst
.reloc
.type
= BFD_RELOC_SCORE_IMM30
;
3532 s3_do_sw48 (char *str
)
3534 bfd_signed_vma val
= 0;
3536 s3_skip_whitespace (str
);
3538 if ((s3_reg_required_here (&str
, 37, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
)
3539 || (s3_skip_past_comma (&str
) == (int) s3_FAIL
))
3542 if (s3_my_get_expression (&s3_inst
.reloc
.exp
, &str
) == (int) s3_FAIL
3543 || s3_end_of_line (str
) == (int) s3_FAIL
)
3548 /* Check word align for lw48 rd, value. */
3549 if ((s3_inst
.reloc
.exp
.X_add_symbol
== NULL
)
3550 && ((s3_inst
.reloc
.exp
.X_add_number
& 0x3) != 0))
3552 s3_inst
.error
= _("invalid constant: 32 bit expression not word align");
3556 /* Check and set offset. */
3557 val
= s3_inst
.reloc
.exp
.X_add_number
;
3558 if ((s3_inst
.reloc
.exp
.X_add_symbol
== NULL
)
3559 && (!(val
>= 0 && val
<= 0xffffffffLL
)))
3561 s3_inst
.error
= _("invalid constant: 32 bit expression not in range [0, 0xffffffff]");
3567 s3_inst
.instruction
|= (val
<< 7);
3569 /* Set reloc type. */
3570 s3_inst
.reloc
.type
= BFD_RELOC_SCORE_IMM30
;
3574 s3_do_ldi48 (char *str
)
3578 s3_skip_whitespace (str
);
3580 if (s3_reg_required_here (&str
, 37, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
3581 || s3_skip_past_comma (&str
) == (int) s3_FAIL
)
3584 if (s3_my_get_expression (&s3_inst
.reloc
.exp
, &str
) == (int) s3_FAIL
3585 || s3_end_of_line (str
) == (int) s3_FAIL
)
3590 /* Check and set offset. */
3591 val
= s3_inst
.reloc
.exp
.X_add_number
;
3592 if (!(val
>= -0xffffffffLL
&& val
<= 0xffffffffLL
))
3594 s3_inst
.error
= _("invalid constant: 32 bit expression not in range [-0x80000000, 0x7fffffff]");
3599 s3_inst
.instruction
|= (val
<< 5);
3601 /* Set reloc type. */
3602 s3_inst
.reloc
.type
= BFD_RELOC_SCORE_IMM32
;
3606 s3_do_sdbbp48 (char *str
)
3608 s3_skip_whitespace (str
);
3610 if (s3_data_op2 (&str
, 5, _IMM5
) == (int) s3_FAIL
|| s3_end_of_line (str
) == (int) s3_FAIL
)
3615 s3_do_and48 (char *str
)
3617 s3_skip_whitespace (str
);
3619 if (s3_reglow_required_here (&str
, 38) == (int) s3_FAIL
3620 || s3_skip_past_comma (&str
) == (int) s3_FAIL
3621 || s3_reglow_required_here (&str
, 34) == (int) s3_FAIL
3622 || s3_skip_past_comma (&str
) == (int) s3_FAIL
3623 || s3_data_op2 (&str
, 2, _IMM32
) == (int) s3_FAIL
3624 || s3_end_of_line (str
) == (int) s3_FAIL
)
3629 s3_do_or48 (char *str
)
3631 s3_skip_whitespace (str
);
3633 if (s3_reglow_required_here (&str
, 38) == (int) s3_FAIL
3634 || s3_skip_past_comma (&str
) == (int) s3_FAIL
3635 || s3_reglow_required_here (&str
, 34) == (int) s3_FAIL
3636 || s3_skip_past_comma (&str
) == (int) s3_FAIL
3637 || s3_data_op2 (&str
, 2, _IMM32
) == (int) s3_FAIL
3638 || s3_end_of_line (str
) == (int) s3_FAIL
)
3643 s3_do_mbitclr (char *str
)
3646 s3_skip_whitespace (str
);
3650 sprintf (s3_err_msg
, _("missing ["));
3651 s3_inst
.error
= s3_err_msg
;
3656 s3_inst
.instruction
&= 0x0;
3658 if ((s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
)
3659 || (s3_skip_past_comma (&str
) == (int) s3_FAIL
)
3660 || (s3_data_op2 (&str
, 0, _IMM11
) == (int) s3_FAIL
))
3663 /* Get imm11 and refill opcode. */
3664 val
= s3_inst
.instruction
& 0x7ff;
3666 s3_inst
.instruction
&= 0x000f8000;
3667 s3_inst
.instruction
|= 0x00000064;
3671 sprintf (s3_err_msg
, _("missing ]"));
3672 s3_inst
.error
= s3_err_msg
;
3677 if ((s3_skip_past_comma (&str
) == (int) s3_FAIL
)
3678 || (s3_data_op2 (&str
, 10, _IMM5
) == (int) s3_FAIL
))
3681 /* Set imm11 to opcode. */
3682 s3_inst
.instruction
|= (val
& 0x1)
3683 | (((val
>> 1 ) & 0x7) << 7)
3684 | (((val
>> 4 ) & 0x1f) << 20);
3688 s3_do_mbitset (char *str
)
3691 s3_skip_whitespace (str
);
3695 sprintf (s3_err_msg
, _("missing ["));
3696 s3_inst
.error
= s3_err_msg
;
3701 s3_inst
.instruction
&= 0x0;
3703 if ((s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
)
3704 || (s3_skip_past_comma (&str
) == (int) s3_FAIL
)
3705 || (s3_data_op2 (&str
, 0, _IMM11
) == (int) s3_FAIL
))
3708 /* Get imm11 and refill opcode. */
3709 val
= s3_inst
.instruction
& 0x7ff;
3711 s3_inst
.instruction
&= 0x000f8000;
3712 s3_inst
.instruction
|= 0x0000006c;
3716 sprintf (s3_err_msg
, _("missing ]"));
3717 s3_inst
.error
= s3_err_msg
;
3722 if ((s3_skip_past_comma (&str
) == (int) s3_FAIL
)
3723 || (s3_data_op2 (&str
, 10, _IMM5
) == (int) s3_FAIL
))
3726 /* Set imm11 to opcode. */
3727 s3_inst
.instruction
|= (val
& 0x1)
3728 | (((val
>> 1 ) & 0x7) << 7)
3729 | (((val
>> 4 ) & 0x1f) << 20);
3733 s3_do16_slli_srli (char *str
)
3735 s3_skip_whitespace (str
);
3737 if ((s3_reglow_required_here (&str
, 5) == (int) s3_FAIL
)
3738 || (s3_skip_past_comma (&str
) == (int) s3_FAIL
)
3739 || s3_data_op2 (&str
, 0, _IMM5
) == (int) s3_FAIL
3740 || s3_end_of_line (str
) == (int) s3_FAIL
)
3745 s3_do16_ldiu (char *str
)
3747 s3_skip_whitespace (str
);
3749 if ((s3_reg_required_here (&str
, 5,s3_REG_TYPE_SCORE
) == (int) s3_FAIL
)
3750 || (s3_skip_past_comma (&str
) == (int) s3_FAIL
)
3751 || s3_data_op2 (&str
, 0, _IMM5
) == (int) s3_FAIL
3752 || s3_end_of_line (str
) == (int) s3_FAIL
)
3757 s3_do16_push_pop (char *str
)
3759 s3_skip_whitespace (str
);
3760 if ((s3_reg_required_here (&str
, 0, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
3761 || s3_end_of_line (str
) == (int) s3_FAIL
)
3766 s3_do16_rpush (char *str
)
3770 s3_skip_whitespace (str
);
3771 if ((reg
= (s3_reg_required_here (&str
, 5, s3_REG_TYPE_SCORE
))) == (int) s3_FAIL
3772 || s3_skip_past_comma (&str
) == (int) s3_FAIL
3773 || s3_data_op2 (&str
, 0, _IMM5_MULTI_LOAD
) == (int) s3_FAIL
3774 || s3_end_of_line (str
) == (int) s3_FAIL
)
3779 2: to 31: normal value. */
3780 val
= s3_inst
.instruction
& 0x1f;
3783 s3_inst
.error
= _("imm5 should >= 2");
3788 s3_inst
.error
= _("reg should <= 31");
3794 s3_do16_rpop (char *str
)
3798 s3_skip_whitespace (str
);
3799 if ((reg
= (s3_reg_required_here (&str
, 5, s3_REG_TYPE_SCORE
))) == (int) s3_FAIL
3800 || s3_skip_past_comma (&str
) == (int) s3_FAIL
3801 || s3_data_op2 (&str
, 0, _IMM5_MULTI_LOAD
) == (int) s3_FAIL
3802 || s3_end_of_line (str
) == (int) s3_FAIL
)
3807 2: to 31: normal value. */
3808 val
= s3_inst
.instruction
& 0x1f;
3811 s3_inst
.error
= _("imm5 should >= 2");
3817 s3_inst
.error
= _("reg should <= 31");
3822 if ((reg
+ val
) <= 32)
3823 reg
= reg
+ val
- 1;
3825 reg
= reg
+ val
- 33;
3826 s3_inst
.instruction
&= 0x7c1f;
3827 s3_inst
.instruction
|= (reg
<< 5);
3832 /* Handle lcb/lcw/lce/scb/scw/sce. */
3834 s3_do_ldst_unalign (char *str
)
3838 if (s3_university_version
== 1)
3840 s3_inst
.error
= s3_ERR_FOR_SCORE5U_ATOMIC
;
3844 s3_skip_whitespace (str
);
3846 /* lcb/scb [rA]+. */
3850 s3_skip_whitespace (str
);
3852 if (s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
)
3859 s3_inst
.error
= _("missing +");
3865 s3_inst
.error
= _("missing ]");
3869 if (s3_end_of_line (str
) == (int) s3_FAIL
)
3872 /* lcw/lce/scb/sce rD, [rA]+. */
3875 if (((conflict_reg
= s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
)
3876 || (s3_skip_past_comma (&str
) == (int) s3_FAIL
))
3881 s3_skip_whitespace (str
);
3886 s3_skip_whitespace (str
);
3887 if ((reg
= s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
)
3892 /* Conflicts can occur on stores as well as loads. */
3893 conflict_reg
= (conflict_reg
== reg
);
3894 s3_skip_whitespace (str
);
3897 unsigned int ldst_func
= s3_inst
.instruction
& LDST_UNALIGN_MASK
;
3903 as_warn (_("%s register same as write-back base"),
3904 ((ldst_func
& UA_LCE
) || (ldst_func
& UA_LCW
)
3905 ? _("destination") : _("source")));
3910 s3_inst
.error
= _("missing +");
3914 if (s3_end_of_line (str
) == (int) s3_FAIL
)
3919 s3_inst
.error
= _("missing ]");
3925 s3_inst
.error
= s3_BAD_ARGS
;
3931 /* Handle alw/asw. */
3933 s3_do_ldst_atomic (char *str
)
3935 if (s3_university_version
== 1)
3937 s3_inst
.error
= s3_ERR_FOR_SCORE5U_ATOMIC
;
3941 s3_skip_whitespace (str
);
3943 if ((s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
)
3944 || (s3_skip_past_comma (&str
) == (int) s3_FAIL
))
3951 s3_skip_whitespace (str
);
3956 s3_skip_whitespace (str
);
3957 if ((reg
= s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
)
3962 s3_skip_whitespace (str
);
3965 s3_inst
.error
= _("missing ]");
3969 s3_end_of_line (str
);
3972 s3_inst
.error
= s3_BAD_ARGS
;
3977 s3_build_relax_frag (struct s3_score_it fix_insts
[s3_RELAX_INST_NUM
], int fix_num ATTRIBUTE_UNUSED
,
3978 struct s3_score_it var_insts
[s3_RELAX_INST_NUM
], int var_num
,
3979 symbolS
*add_symbol
)
3984 fixS
*cur_fixp
= NULL
;
3986 struct s3_score_it inst_main
;
3988 memcpy (&inst_main
, &fix_insts
[0], sizeof (struct s3_score_it
));
3990 /* Adjust instruction opcode and to be relaxed instruction opcode. */
3991 inst_main
.instruction
= s3_adjust_paritybit (inst_main
.instruction
, s3_GET_INSN_CLASS (inst_main
.type
));
3992 inst_main
.type
= Insn_PIC
;
3994 for (i
= 0; i
< var_num
; i
++)
3996 inst_main
.relax_size
+= var_insts
[i
].size
;
3997 var_insts
[i
].instruction
= s3_adjust_paritybit (var_insts
[i
].instruction
,
3998 s3_GET_INSN_CLASS (var_insts
[i
].type
));
4001 /* Check data dependency. */
4002 s3_handle_dependency (&inst_main
);
4004 /* Start a new frag if frag_now is not empty. */
4005 if (frag_now_fix () != 0)
4007 if (!frag_now
->tc_frag_data
.is_insn
)
4009 frag_wane (frag_now
);
4015 /* Write fr_fix part. */
4016 p
= frag_more (inst_main
.size
);
4017 s3_md_number_to_chars (p
, inst_main
.instruction
, inst_main
.size
);
4019 if (inst_main
.reloc
.type
!= BFD_RELOC_NONE
)
4020 fixp
= s3_fix_new_score (frag_now
, p
- frag_now
->fr_literal
, inst_main
.size
,
4021 &inst_main
.reloc
.exp
, inst_main
.reloc
.pc_rel
, inst_main
.reloc
.type
);
4023 frag_now
->tc_frag_data
.fixp
= fixp
;
4024 cur_fixp
= frag_now
->tc_frag_data
.fixp
;
4027 dwarf2_emit_insn (inst_main
.size
);
4030 where
= p
- frag_now
->fr_literal
+ inst_main
.size
;
4031 for (i
= 0; i
< var_num
; i
++)
4034 where
+= var_insts
[i
- 1].size
;
4036 if (var_insts
[i
].reloc
.type
!= BFD_RELOC_NONE
)
4038 fixp
= s3_fix_new_score (frag_now
, where
, var_insts
[i
].size
,
4039 &var_insts
[i
].reloc
.exp
, var_insts
[i
].reloc
.pc_rel
,
4040 var_insts
[i
].reloc
.type
);
4045 cur_fixp
->fx_next
= fixp
;
4046 cur_fixp
= cur_fixp
->fx_next
;
4050 frag_now
->tc_frag_data
.fixp
= fixp
;
4051 cur_fixp
= frag_now
->tc_frag_data
.fixp
;
4057 p
= frag_var (rs_machine_dependent
, inst_main
.relax_size
+ s3_RELAX_PAD_BYTE
, 0,
4058 s3_RELAX_ENCODE (inst_main
.size
, inst_main
.relax_size
, inst_main
.type
,
4059 0, inst_main
.size
, 0), add_symbol
, 0, NULL
);
4061 /* Write fr_var part.
4062 no calling s3_gen_insn_frag, no fixS will be generated. */
4063 for (i
= 0; i
< var_num
; i
++)
4065 s3_md_number_to_chars (p
, var_insts
[i
].instruction
, var_insts
[i
].size
);
4066 p
+= var_insts
[i
].size
;
4068 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4072 /* Build a relax frag for la instruction when generating s3_PIC,
4073 external symbol first and local symbol second. */
4075 s3_build_la_pic (int reg_rd
, expressionS exp
)
4077 symbolS
*add_symbol
= exp
.X_add_symbol
;
4078 offsetT add_number
= exp
.X_add_number
;
4079 struct s3_score_it fix_insts
[s3_RELAX_INST_NUM
];
4080 struct s3_score_it var_insts
[s3_RELAX_INST_NUM
];
4083 char tmp
[s3_MAX_LITERAL_POOL_SIZE
];
4089 if (add_number
== 0)
4094 /* For an external symbol, only one insn is generated;
4095 For a local symbol, two insns are generated. */
4097 For an external symbol: lw rD, <sym>($gp)
4098 (BFD_RELOC_SCORE_GOT15 or BFD_RELOC_SCORE_CALL15) */
4099 sprintf (tmp
, "lw_pic r%d, %s", reg_rd
, S_GET_NAME (add_symbol
));
4100 if (s3_append_insn (tmp
, FALSE
) == (int) s3_FAIL
)
4103 if (reg_rd
== s3_PIC_CALL_REG
)
4104 s3_inst
.reloc
.type
= BFD_RELOC_SCORE_CALL15
;
4105 memcpy (&fix_insts
[0], &s3_inst
, sizeof (struct s3_score_it
));
4108 For a local symbol :
4109 lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15)
4110 addi rD, <sym> (BFD_RELOC_GOT_LO16) */
4111 s3_inst
.reloc
.type
= BFD_RELOC_SCORE_GOT15
;
4112 memcpy (&var_insts
[0], &s3_inst
, sizeof (struct s3_score_it
));
4113 sprintf (tmp
, "addi_s_pic r%d, %s", reg_rd
, S_GET_NAME (add_symbol
));
4114 if (s3_append_insn (tmp
, FALSE
) == (int) s3_FAIL
)
4117 memcpy (&var_insts
[1], &s3_inst
, sizeof (struct s3_score_it
));
4118 s3_build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
4120 else if (add_number
>= -0x8000 && add_number
<= 0x7fff)
4122 /* Insn 1: lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15) */
4123 sprintf (tmp
, "lw_pic r%d, %s", reg_rd
, S_GET_NAME (add_symbol
));
4124 if (s3_append_insn (tmp
, TRUE
) == (int) s3_FAIL
)
4131 For an external symbol: addi rD, <constant> */
4132 sprintf (tmp
, "addi r%d, %d", reg_rd
, (int)add_number
);
4133 if (s3_append_insn (tmp
, FALSE
) == (int) s3_FAIL
)
4136 memcpy (&fix_insts
[0], &s3_inst
, sizeof (struct s3_score_it
));
4139 For a local symbol: addi rD, <sym>+<constant> (BFD_RELOC_GOT_LO16) */
4140 sprintf (tmp
, "addi_s_pic r%d, %s + %d", reg_rd
,
4141 S_GET_NAME (add_symbol
), (int) add_number
);
4142 if (s3_append_insn (tmp
, FALSE
) == (int) s3_FAIL
)
4145 memcpy (&var_insts
[0], &s3_inst
, sizeof (struct s3_score_it
));
4146 s3_build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
4150 int hi
= (add_number
>> 16) & 0x0000FFFF;
4151 int lo
= add_number
& 0x0000FFFF;
4153 /* Insn 1: lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15) */
4154 sprintf (tmp
, "lw_pic r%d, %s", reg_rd
, S_GET_NAME (add_symbol
));
4155 if (s3_append_insn (tmp
, TRUE
) == (int) s3_FAIL
)
4162 For an external symbol: ldis r1, HI%<constant> */
4163 sprintf (tmp
, "ldis r1, %d", hi
);
4164 if (s3_append_insn (tmp
, FALSE
) == (int) s3_FAIL
)
4167 memcpy (&fix_insts
[0], &s3_inst
, sizeof (struct s3_score_it
));
4170 For a local symbol: ldis r1, HI%<constant>
4171 but, if lo is out of 16 bit, make hi plus 1 */
4172 if ((lo
< -0x8000) || (lo
> 0x7fff))
4176 sprintf (tmp
, "ldis_pic r1, %d", hi
);
4177 if (s3_append_insn (tmp
, FALSE
) == (int) s3_FAIL
)
4180 memcpy (&var_insts
[0], &s3_inst
, sizeof (struct s3_score_it
));
4181 s3_build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
4187 For an external symbol: ori r1, LO%<constant> */
4188 sprintf (tmp
, "ori r1, %d", lo
);
4189 if (s3_append_insn (tmp
, FALSE
) == (int) s3_FAIL
)
4192 memcpy (&fix_insts
[0], &s3_inst
, sizeof (struct s3_score_it
));
4195 For a local symbol: addi r1, <sym>+LO%<constant> (BFD_RELOC_GOT_LO16) */
4196 sprintf (tmp
, "addi_u_pic r1, %s + %d", S_GET_NAME (add_symbol
), lo
);
4197 if (s3_append_insn (tmp
, FALSE
) == (int) s3_FAIL
)
4200 memcpy (&var_insts
[0], &s3_inst
, sizeof (struct s3_score_it
));
4201 s3_build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
4203 /* Insn 4: add rD, rD, r1 */
4204 sprintf (tmp
, "add r%d, r%d, r1", reg_rd
, reg_rd
);
4205 if (s3_append_insn (tmp
, TRUE
) == (int) s3_FAIL
)
4208 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4217 s3_do_macro_la_rdi32 (char *str
)
4221 s3_skip_whitespace (str
);
4222 if ((reg_rd
= s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
4223 || s3_skip_past_comma (&str
) == (int) s3_FAIL
)
4230 char *keep_data
= str
;
4231 char append_str
[s3_MAX_LITERAL_POOL_SIZE
];
4233 /* Check immediate value. */
4234 if (s3_my_get_expression (&s3_inst
.reloc
.exp
, &str
) == (int) s3_FAIL
)
4236 s3_inst
.error
= _("expression error");
4239 else if ((s3_inst
.reloc
.exp
.X_add_symbol
== NULL
)
4240 && (s3_validate_immediate (s3_inst
.reloc
.exp
.X_add_number
, _IMM32
, 0) == (int) s3_FAIL
))
4242 s3_inst
.error
= _("value not in range [0, 0xffffffff]");
4249 /* la rd, simm16. */
4250 if (s3_data_op2 (&str
, 1, _SIMM16_LA
) != (int) s3_FAIL
)
4252 s3_end_of_line (str
);
4255 /* la rd, imm32 or la rd, label. */
4258 s3_SET_INSN_ERROR (NULL
);
4261 if ((s3_data_op2 (&str
, 1, _VALUE_HI16
) == (int) s3_FAIL
)
4262 || (s3_end_of_line (str
) == (int) s3_FAIL
))
4268 if ((s3_score_pic
== s3_NO_PIC
) || (!s3_inst
.reloc
.exp
.X_add_symbol
))
4270 sprintf (append_str
, "ld_i32hi r%d, %s", reg_rd
, keep_data
);
4271 if (s3_append_insn (append_str
, TRUE
) == (int) s3_FAIL
)
4274 sprintf (append_str
, "ld_i32lo r%d, %s", reg_rd
, keep_data
);
4275 if (s3_append_insn (append_str
, TRUE
) == (int) s3_FAIL
)
4280 gas_assert (s3_inst
.reloc
.exp
.X_add_symbol
);
4281 s3_build_la_pic (reg_rd
, s3_inst
.reloc
.exp
);
4284 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4293 s3_do_macro_li_rdi32 (char *str
)
4298 s3_skip_whitespace (str
);
4299 if ((reg_rd
= s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
4300 || s3_skip_past_comma (&str
) == (int) s3_FAIL
)
4307 char *keep_data
= str
;
4309 /* Check immediate value. */
4310 if (s3_my_get_expression (&s3_inst
.reloc
.exp
, &str
) == (int) s3_FAIL
)
4312 s3_inst
.error
= _("expression error");
4315 else if (!(s3_inst
.reloc
.exp
.X_add_number
>= -0xffffffffLL
4316 && s3_inst
.reloc
.exp
.X_add_number
<= 0xffffffffLL
))
4318 s3_inst
.error
= _("value not in range [-0xffffffff, 0xffffffff]");
4325 /* li rd, simm16. */
4326 if (s3_data_op2 (&str
, 1, _SIMM16_LA
) != (int) s3_FAIL
)
4328 s3_end_of_line (str
);
4334 char append_str
[s3_MAX_LITERAL_POOL_SIZE
];
4339 if ((s3_data_op2 (&str
, 1, _VALUE_HI16
) == (int) s3_FAIL
)
4340 || (s3_end_of_line (str
) == (int) s3_FAIL
))
4344 else if (s3_inst
.reloc
.exp
.X_add_symbol
)
4346 s3_inst
.error
= _("li rd label isn't correct instruction form");
4351 sprintf (append_str
, "ld_i32hi r%d, %s", reg_rd
, keep_data
);
4353 if (s3_append_insn (append_str
, TRUE
) == (int) s3_FAIL
)
4357 sprintf (append_str
, "ld_i32lo r%d, %s", reg_rd
, keep_data
);
4358 if (s3_append_insn (append_str
, TRUE
) == (int) s3_FAIL
)
4361 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4369 /* Handle mul/mulu/div/divu/rem/remu. */
4371 s3_do_macro_mul_rdrsrs (char *str
)
4377 char append_str
[s3_MAX_LITERAL_POOL_SIZE
];
4379 if (s3_university_version
== 1)
4380 as_warn ("%s", s3_ERR_FOR_SCORE5U_MUL_DIV
);
4382 strcpy (append_str
, str
);
4383 backupstr
= append_str
;
4384 s3_skip_whitespace (backupstr
);
4385 if (((reg_rd
= s3_reg_required_here (&backupstr
, -1, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
)
4386 || (s3_skip_past_comma (&backupstr
) == (int) s3_FAIL
)
4387 || ((reg_rs1
= s3_reg_required_here (&backupstr
, -1, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
))
4389 s3_inst
.error
= s3_BAD_ARGS
;
4393 if (s3_skip_past_comma (&backupstr
) == (int) s3_FAIL
)
4395 /* rem/remu rA, rB is error format. */
4396 if (strcmp (s3_inst
.name
, "rem") == 0 || strcmp (s3_inst
.name
, "remu") == 0)
4398 s3_SET_INSN_ERROR (s3_BAD_ARGS
);
4402 s3_SET_INSN_ERROR (NULL
);
4409 s3_SET_INSN_ERROR (NULL
);
4410 if (((reg_rs2
= s3_reg_required_here (&backupstr
, -1, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
)
4411 || (s3_end_of_line (backupstr
) == (int) s3_FAIL
))
4417 char append_str1
[s3_MAX_LITERAL_POOL_SIZE
];
4419 if (strcmp (s3_inst
.name
, "rem") == 0)
4421 sprintf (append_str
, "mul r%d, r%d", reg_rs1
, reg_rs2
);
4422 sprintf (append_str1
, "mfceh r%d", reg_rd
);
4424 else if (strcmp (s3_inst
.name
, "remu") == 0)
4426 sprintf (append_str
, "mulu r%d, r%d", reg_rs1
, reg_rs2
);
4427 sprintf (append_str1
, "mfceh r%d", reg_rd
);
4431 sprintf (append_str
, "%s r%d, r%d", s3_inst
.name
, reg_rs1
, reg_rs2
);
4432 sprintf (append_str1
, "mfcel r%d", reg_rd
);
4435 /* Output mul/mulu or div/divu or rem/remu. */
4436 if (s3_append_insn (append_str
, TRUE
) == (int) s3_FAIL
)
4439 /* Output mfcel or mfceh. */
4440 if (s3_append_insn (append_str1
, TRUE
) == (int) s3_FAIL
)
4443 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4450 s3_exp_macro_ldst_abs (char *str
)
4453 char *backupstr
, *tmp
;
4454 char append_str
[s3_MAX_LITERAL_POOL_SIZE
];
4455 char verifystr
[s3_MAX_LITERAL_POOL_SIZE
];
4456 struct s3_score_it inst_backup
;
4461 memcpy (&inst_backup
, &s3_inst
, sizeof (struct s3_score_it
));
4463 strcpy (verifystr
, str
);
4464 backupstr
= verifystr
;
4465 s3_skip_whitespace (backupstr
);
4466 if ((reg_rd
= s3_reg_required_here (&backupstr
, -1, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
)
4470 if (s3_skip_past_comma (&backupstr
) == (int) s3_FAIL
)
4474 sprintf (append_str
, "li r1 %s", backupstr
);
4475 s3_append_insn (append_str
, TRUE
);
4477 memcpy (&s3_inst
, &inst_backup
, sizeof (struct s3_score_it
));
4478 sprintf (append_str
, " r%d, [r1,0]", reg_rd
);
4479 s3_do_ldst_insn (append_str
);
4484 /* Handle bcmpeq / bcmpne */
4486 s3_do_macro_bcmp (char *str
)
4490 size_t keep_data_size
;
4492 struct s3_score_it inst_expand
[2];
4493 struct s3_score_it inst_main
;
4495 memset (inst_expand
, 0, sizeof inst_expand
);
4496 s3_skip_whitespace (str
);
4497 if (( reg_a
= s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
4498 || s3_skip_past_comma (&str
) == (int) s3_FAIL
4499 ||(reg_b
= s3_reg_required_here (&str
, 10, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
4500 || s3_skip_past_comma (&str
) == (int) s3_FAIL
)
4503 keep_data_size
= strlen (str
) + 1;
4504 keep_data
= xmalloc (keep_data_size
* 2 + 14);
4505 memcpy (keep_data
, str
, keep_data_size
);
4507 if (s3_my_get_expression (&s3_inst
.reloc
.exp
, &str
) == (int) s3_FAIL
4509 || s3_end_of_line (str
) == (int) s3_FAIL
)
4511 else if (s3_inst
.reloc
.exp
.X_add_symbol
== 0)
4513 s3_inst
.error
= _("lacking label ");
4518 char *append_str
= keep_data
+ keep_data_size
;
4519 s3_SET_INSN_ERROR (NULL
);
4521 s3_inst
.reloc
.type
= BFD_RELOC_SCORE_BCMP
;
4522 s3_inst
.reloc
.pc_rel
= 1;
4523 bfd_signed_vma val
= s3_inst
.reloc
.exp
.X_add_number
;
4525 /* Branch 32 offset field : 20 bit, 16 bit branch offset field : 8 bit. */
4526 s3_inst
.instruction
|= ((s3_inst
.reloc
.exp
.X_add_number
>> 1) & 0x1)
4527 | ((s3_inst
.reloc
.exp
.X_add_number
>> 2) & 0x7) << 7
4528 | ((s3_inst
.reloc
.exp
.X_add_number
>> 5) & 0x1f) << 20;
4530 /* Check and set offset. */
4531 if (((val
& 0xfffffe00) != 0)
4532 && ((val
& 0xfffffe00) != 0xfffffe00))
4534 /* support bcmp --> cmp!+beq (bne) */
4535 if (s3_score_pic
== s3_NO_PIC
)
4537 sprintf (append_str
, "cmp! r%d, r%d", reg_a
, reg_b
);
4538 if (s3_append_insn (append_str
, TRUE
) == (int) s3_FAIL
)
4540 if ((inst_main
.instruction
& 0x3e00007e) == 0x0000004c)
4541 sprintf (append_str
, "beq %s", keep_data
);
4543 sprintf (append_str
, "bne %s", keep_data
);
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 sprintf (append_str
, "beq %s", keep_data
);
4576 sprintf (append_str
, "bne %s", keep_data
);
4577 if (s3_append_insn (append_str
, FALSE
) == (int) s3_FAIL
)
4579 memcpy (&inst_expand
[1], &s3_inst
, sizeof (struct s3_score_it
));
4583 gas_assert (s3_inst
.reloc
.exp
.X_add_symbol
);
4585 inst_main
.relax_size
= inst_expand
[0].size
+ inst_expand
[1].size
;
4586 inst_main
.type
= Insn_BCMP
;
4588 /* Adjust instruction opcode and to be relaxed instruction opcode. */
4589 inst_main
.instruction
= s3_adjust_paritybit (inst_main
.instruction
, s3_GET_INSN_CLASS (inst_main
.type
));
4591 for (i
= 0; i
< 2; i
++)
4592 inst_expand
[i
].instruction
= s3_adjust_paritybit (inst_expand
[i
].instruction
,
4593 s3_GET_INSN_CLASS (inst_expand
[i
].type
));
4594 /* Check data dependency. */
4595 s3_handle_dependency (&inst_main
);
4596 /* Start a new frag if frag_now is not empty. */
4597 if (frag_now_fix () != 0)
4599 if (!frag_now
->tc_frag_data
.is_insn
)
4600 frag_wane (frag_now
);
4605 /* Write fr_fix part. */
4607 p
= frag_more (inst_main
.size
);
4608 s3_md_number_to_chars (p
, inst_main
.instruction
, inst_main
.size
);
4610 if (inst_main
.reloc
.type
!= BFD_RELOC_NONE
)
4612 s3_fix_new_score (frag_now
, p
- frag_now
->fr_literal
, inst_main
.size
,
4613 &inst_main
.reloc
.exp
, inst_main
.reloc
.pc_rel
, inst_main
.reloc
.type
);
4616 dwarf2_emit_insn (inst_main
.size
);
4619 /* s3_GP instruction can not do optimization, only can do relax between
4620 1 instruction and 3 instructions. */
4621 p
= frag_var (rs_machine_dependent
, inst_main
.relax_size
+ s3_RELAX_PAD_BYTE
, 0,
4622 s3_RELAX_ENCODE (inst_main
.size
, inst_main
.relax_size
, inst_main
.type
, 0, 4, 1),
4623 inst_main
.reloc
.exp
.X_add_symbol
, 0, NULL
);
4625 /* Write fr_var part.
4626 no calling s3_gen_insn_frag, no fixS will be generated. */
4627 s3_md_number_to_chars (p
, inst_expand
[0].instruction
, inst_expand
[0].size
);
4628 p
+= inst_expand
[0].size
;
4629 s3_md_number_to_chars (p
, inst_expand
[1].instruction
, inst_expand
[1].size
);
4630 p
+= inst_expand
[1].size
;
4632 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4639 /* Handle bcmpeqz / bcmpnez */
4641 s3_do_macro_bcmpz (char *str
)
4645 size_t keep_data_size
;
4647 struct s3_score_it inst_expand
[2];
4648 struct s3_score_it inst_main
;
4650 memset (inst_expand
, 0, sizeof inst_expand
);
4651 s3_skip_whitespace (str
);
4652 if (( reg_a
= s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
4653 || s3_skip_past_comma (&str
) == (int) s3_FAIL
)
4656 keep_data_size
= strlen (str
) + 1;
4657 keep_data
= xmalloc (keep_data_size
* 2 + 13);
4658 memcpy (keep_data
, str
, keep_data_size
);
4660 if (s3_my_get_expression (&s3_inst
.reloc
.exp
, &str
) == (int) s3_FAIL
4661 || s3_end_of_line (str
) == (int) s3_FAIL
)
4663 else if (s3_inst
.reloc
.exp
.X_add_symbol
== 0)
4665 s3_inst
.error
= _("lacking label ");
4670 char *append_str
= keep_data
+ keep_data_size
;
4671 s3_SET_INSN_ERROR (NULL
);
4672 s3_inst
.reloc
.type
= BFD_RELOC_SCORE_BCMP
;
4673 s3_inst
.reloc
.pc_rel
= 1;
4674 bfd_signed_vma val
= s3_inst
.reloc
.exp
.X_add_number
;
4676 /* Branch 32 offset field : 20 bit, 16 bit branch offset field : 8 bit. */
4677 s3_inst
.instruction
|= ((s3_inst
.reloc
.exp
.X_add_number
>>1) & 0x1) | ((s3_inst
.reloc
.exp
.X_add_number
>>2) & 0x7)<<7 |((s3_inst
.reloc
.exp
.X_add_number
>>5) & 0x1f)<<20;
4679 /* Check and set offset. */
4680 if (((val
& 0xfffffe00) != 0)
4681 && ((val
& 0xfffffe00) != 0xfffffe00))
4683 if (s3_score_pic
== s3_NO_PIC
)
4685 sprintf (append_str
, "cmpi! r%d, 0", reg_a
);
4686 if (s3_append_insn (append_str
, TRUE
) == (int) s3_FAIL
)
4688 if ((inst_main
.instruction
& 0x3e00007e) == 0x0000004c)
4689 sprintf (append_str
, "beq %s", keep_data
);
4691 sprintf (append_str
, "bne %s", keep_data
);
4692 if (s3_append_insn (append_str
, TRUE
) == (int) s3_FAIL
)
4697 gas_assert (s3_inst
.reloc
.exp
.X_add_symbol
);
4699 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4706 s3_inst
.instruction
|= (val
& 0x1)
4707 | (((val
>> 1) & 0x7) << 7)
4708 | (((val
>> 4) & 0x1f) << 20);
4711 /* Backup s3_inst. */
4712 memcpy (&inst_main
, &s3_inst
, sizeof (struct s3_score_it
));
4714 if (s3_score_pic
== s3_NO_PIC
)
4716 sprintf (append_str
, "cmpi! r%d, 0", reg_a
);
4717 if (s3_append_insn (append_str
, FALSE
) == (int) s3_FAIL
)
4719 memcpy (&inst_expand
[0], &s3_inst
, sizeof (struct s3_score_it
));
4720 if ((inst_main
.instruction
& 0x3e00007e) == 0x0000004c)
4721 sprintf (append_str
, "beq %s", keep_data
);
4723 sprintf (append_str
, "bne %s", keep_data
);
4724 if (s3_append_insn (append_str
, FALSE
) == (int) s3_FAIL
)
4726 memcpy (&inst_expand
[1], &s3_inst
, sizeof (struct s3_score_it
));
4730 gas_assert (s3_inst
.reloc
.exp
.X_add_symbol
);
4732 inst_main
.relax_size
= inst_expand
[0].size
+ inst_expand
[1].size
;
4733 inst_main
.type
= Insn_BCMP
;
4735 /* Adjust instruction opcode and to be relaxed instruction opcode. */
4736 inst_main
.instruction
= s3_adjust_paritybit (inst_main
.instruction
, s3_GET_INSN_CLASS (inst_main
.type
));
4738 for (i
= 0; i
< 2; i
++)
4739 inst_expand
[i
].instruction
= s3_adjust_paritybit (inst_expand
[i
].instruction
,
4740 s3_GET_INSN_CLASS (inst_expand
[i
].type
));
4741 /* Check data dependency. */
4742 s3_handle_dependency (&inst_main
);
4743 /* Start a new frag if frag_now is not empty. */
4744 if (frag_now_fix () != 0)
4746 if (!frag_now
->tc_frag_data
.is_insn
)
4747 frag_wane (frag_now
);
4752 /* Write fr_fix part. */
4754 p
= frag_more (inst_main
.size
);
4755 s3_md_number_to_chars (p
, inst_main
.instruction
, inst_main
.size
);
4757 if (inst_main
.reloc
.type
!= BFD_RELOC_NONE
)
4759 s3_fix_new_score (frag_now
, p
- frag_now
->fr_literal
, inst_main
.size
,
4760 &inst_main
.reloc
.exp
, inst_main
.reloc
.pc_rel
, inst_main
.reloc
.type
);
4763 dwarf2_emit_insn (inst_main
.size
);
4766 /* s3_GP instruction can not do optimization, only can do relax between
4767 1 instruction and 3 instructions. */
4768 p
= frag_var (rs_machine_dependent
, inst_main
.relax_size
+ s3_RELAX_PAD_BYTE
, 0,
4769 s3_RELAX_ENCODE (inst_main
.size
, inst_main
.relax_size
, inst_main
.type
, 0, 4, 1),
4770 inst_main
.reloc
.exp
.X_add_symbol
, 0, NULL
);
4772 /* Write fr_var part.
4773 no calling s3_gen_insn_frag, no fixS will be generated. */
4774 s3_md_number_to_chars (p
, inst_expand
[0].instruction
, inst_expand
[0].size
);
4775 p
+= inst_expand
[0].size
;
4776 s3_md_number_to_chars (p
, inst_expand
[1].instruction
, inst_expand
[1].size
);
4777 p
+= inst_expand
[1].size
;
4779 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4787 s3_nopic_need_relax (symbolS
* sym
, int before_relaxing
)
4791 else if (s3_USE_GLOBAL_POINTER_OPT
&& s3_g_switch_value
> 0)
4793 const char *symname
;
4794 const char *segname
;
4796 /* Find out whether this symbol can be referenced off the $gp
4797 register. It can be if it is smaller than the -G size or if
4798 it is in the .sdata or .sbss section. Certain symbols can
4799 not be referenced off the $gp, although it appears as though
4801 symname
= S_GET_NAME (sym
);
4802 if (symname
!= (const char *)NULL
4803 && (strcmp (symname
, "eprol") == 0
4804 || strcmp (symname
, "etext") == 0
4805 || strcmp (symname
, "_gp") == 0
4806 || strcmp (symname
, "edata") == 0
4807 || strcmp (symname
, "_fbss") == 0
4808 || strcmp (symname
, "_fdata") == 0
4809 || strcmp (symname
, "_ftext") == 0
4810 || strcmp (symname
, "end") == 0
4811 || strcmp (symname
, GP_DISP_LABEL
) == 0))
4815 else if ((!S_IS_DEFINED (sym
) || S_IS_COMMON (sym
)) && (0
4816 /* We must defer this decision until after the whole file has been read,
4817 since there might be a .extern after the first use of this symbol. */
4819 && S_GET_VALUE (sym
) == 0)
4820 || (S_GET_VALUE (sym
) != 0
4821 && S_GET_VALUE (sym
) <= s3_g_switch_value
)))
4826 segname
= segment_name (S_GET_SEGMENT (sym
));
4827 return (strcmp (segname
, ".sdata") != 0
4828 && strcmp (segname
, ".sbss") != 0
4829 && strncmp (segname
, ".sdata.", 7) != 0
4830 && strncmp (segname
, ".gnu.linkonce.s.", 16) != 0);
4832 /* We are not optimizing for the $gp register. */
4837 /* Build a relax frag for lw/st instruction when generating s3_PIC,
4838 external symbol first and local symbol second. */
4840 s3_build_lwst_pic (int reg_rd
, expressionS exp
, const char *insn_name
)
4842 symbolS
*add_symbol
= exp
.X_add_symbol
;
4843 int add_number
= exp
.X_add_number
;
4844 struct s3_score_it fix_insts
[s3_RELAX_INST_NUM
];
4845 struct s3_score_it var_insts
[s3_RELAX_INST_NUM
];
4848 char tmp
[s3_MAX_LITERAL_POOL_SIZE
];
4854 if ((add_number
== 0) || (add_number
>= -0x8000 && add_number
<= 0x7fff))
4859 /* For an external symbol, two insns are generated;
4860 For a local symbol, three insns are generated. */
4862 For an external symbol: lw rD, <sym>($gp)
4863 (BFD_RELOC_SCORE_GOT15) */
4864 sprintf (tmp
, "lw_pic r1, %s", S_GET_NAME (add_symbol
));
4865 if (s3_append_insn (tmp
, FALSE
) == (int) s3_FAIL
)
4868 memcpy (&fix_insts
[0], &s3_inst
, sizeof (struct s3_score_it
));
4871 For a local symbol :
4872 lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15)
4873 addi rD, <sym> (BFD_RELOC_GOT_LO16) */
4874 s3_inst
.reloc
.type
= BFD_RELOC_SCORE_GOT15
;
4875 memcpy (&var_insts
[0], &s3_inst
, sizeof (struct s3_score_it
));
4876 sprintf (tmp
, "addi_s_pic r1, %s", S_GET_NAME (add_symbol
));
4877 if (s3_append_insn (tmp
, FALSE
) == (int) s3_FAIL
)
4880 memcpy (&var_insts
[1], &s3_inst
, sizeof (struct s3_score_it
));
4881 s3_build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
4883 /* Insn 2 or Insn 3: lw/st rD, [r1, constant] */
4884 sprintf (tmp
, "%s r%d, [r1, %d]", insn_name
, reg_rd
, add_number
);
4885 if (s3_append_insn (tmp
, TRUE
) == (int) s3_FAIL
)
4888 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4893 s3_inst
.error
= _("s3_PIC code offset overflow (max 16 signed bits)");
4901 s3_do_macro_ldst_label (char *str
)
4909 char *absolute_value
;
4910 char append_str
[3][s3_MAX_LITERAL_POOL_SIZE
];
4911 char verifystr
[s3_MAX_LITERAL_POOL_SIZE
];
4912 struct s3_score_it inst_backup
;
4913 struct s3_score_it inst_expand
[3];
4914 struct s3_score_it inst_main
;
4916 memcpy (&inst_backup
, &s3_inst
, sizeof (struct s3_score_it
));
4917 strcpy (verifystr
, str
);
4918 backup_str
= verifystr
;
4920 s3_skip_whitespace (backup_str
);
4921 if ((reg_rd
= s3_reg_required_here (&backup_str
, -1, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
)
4924 if (s3_skip_past_comma (&backup_str
) == (int) s3_FAIL
)
4927 label_str
= backup_str
;
4929 /* Ld/st rD, [rA, imm] ld/st rD, [rA]+, imm ld/st rD, [rA, imm]+. */
4930 if (*backup_str
== '[')
4932 s3_inst
.type
= Rd_rvalueRs_preSI12
;
4933 s3_do_ldst_insn (str
);
4937 /* Ld/st rD, imm. */
4938 absolute_value
= backup_str
;
4939 s3_inst
.type
= Rd_rvalueRs_SI15
;
4941 if (s3_my_get_expression (&s3_inst
.reloc
.exp
, &backup_str
) == (int) s3_FAIL
)
4943 s3_inst
.error
= _("expression error");
4946 else if ((s3_inst
.reloc
.exp
.X_add_symbol
== NULL
)
4947 && (s3_validate_immediate (s3_inst
.reloc
.exp
.X_add_number
, _VALUE
, 0) == (int) s3_FAIL
))
4949 s3_inst
.error
= _("value not in range [0, 0x7fffffff]");
4952 else if (s3_end_of_line (backup_str
) == (int) s3_FAIL
)
4954 s3_inst
.error
= _("end on line error");
4959 if (s3_inst
.reloc
.exp
.X_add_symbol
== 0)
4961 memcpy (&s3_inst
, &inst_backup
, sizeof (struct s3_score_it
));
4962 s3_exp_macro_ldst_abs (str
);
4967 /* Ld/st rD, label. */
4968 s3_inst
.type
= Rd_rvalueRs_SI15
;
4969 backup_str
= absolute_value
;
4970 if ((s3_data_op2 (&backup_str
, 1, _GP_IMM15
) == (int) s3_FAIL
)
4971 || (s3_end_of_line (backup_str
) == (int) s3_FAIL
))
4977 if (s3_inst
.reloc
.exp
.X_add_symbol
== 0)
4980 s3_inst
.error
= s3_BAD_ARGS
;
4985 if (s3_score_pic
== s3_PIC
)
4988 ldst_idx
= s3_inst
.instruction
& OPC_PSEUDOLDST_MASK
;
4989 s3_build_lwst_pic (reg_rd
, s3_inst
.reloc
.exp
,
4990 s3_score_ldst_insns
[ldst_idx
* 3 + 0].template_name
);
4995 if ((s3_inst
.reloc
.exp
.X_add_number
<= 0x3fff)
4996 && (s3_inst
.reloc
.exp
.X_add_number
>= -0x4000)
4997 && (!s3_nopic_need_relax (s3_inst
.reloc
.exp
.X_add_symbol
, 1)))
5001 /* Assign the real opcode. */
5002 ldst_idx
= s3_inst
.instruction
& OPC_PSEUDOLDST_MASK
;
5003 s3_inst
.instruction
&= ~OPC_PSEUDOLDST_MASK
;
5004 s3_inst
.instruction
|= s3_score_ldst_insns
[ldst_idx
* 3 + 0].value
;
5005 s3_inst
.instruction
|= reg_rd
<< 20;
5006 s3_inst
.instruction
|= s3_GP
<< 15;
5007 s3_inst
.relax_inst
= 0x8000;
5008 s3_inst
.relax_size
= 0;
5014 /* Backup s3_inst. */
5015 memcpy (&inst_main
, &s3_inst
, sizeof (struct s3_score_it
));
5019 /* Determine which instructions should be output. */
5020 sprintf (append_str
[0], "ld_i32hi r1, %s", label_str
);
5021 sprintf (append_str
[1], "ld_i32lo r1, %s", label_str
);
5022 sprintf (append_str
[2], "%s r%d, [r1, 0]", inst_backup
.name
, reg_rd
);
5024 /* Generate three instructions.
5026 ld/st rd, [r1, 0] */
5027 for (i
= 0; i
< 3; i
++)
5029 if (s3_append_insn (append_str
[i
], FALSE
) == (int) s3_FAIL
)
5032 memcpy (&inst_expand
[i
], &s3_inst
, sizeof (struct s3_score_it
));
5039 /* Adjust instruction opcode and to be relaxed instruction opcode. */
5040 inst_main
.instruction
= s3_adjust_paritybit (inst_main
.instruction
, s3_GET_INSN_CLASS (inst_main
.type
));
5042 /* relax lw rd, label -> ldis rs, imm16
5044 lw rd, [rs, imm15] or lw! rd, [rs, imm5]. */
5045 if (inst_expand
[2].relax_size
== 0)
5046 inst_main
.relax_size
= inst_expand
[0].size
+ inst_expand
[1].size
+ inst_expand
[2].size
;
5048 inst_main
.relax_size
= inst_expand
[0].size
+ inst_expand
[1].size
+ inst_expand
[2].relax_size
;
5050 inst_main
.type
= Insn_GP
;
5052 for (i
= 0; i
< 3; i
++)
5053 inst_expand
[i
].instruction
= s3_adjust_paritybit (inst_expand
[i
].instruction
,
5054 s3_GET_INSN_CLASS (inst_expand
[i
].type
));
5056 /* Check data dependency. */
5057 s3_handle_dependency (&inst_main
);
5059 /* Start a new frag if frag_now is not empty. */
5060 if (frag_now_fix () != 0)
5062 if (!frag_now
->tc_frag_data
.is_insn
)
5063 frag_wane (frag_now
);
5069 /* Write fr_fix part. */
5070 p
= frag_more (inst_main
.size
);
5071 s3_md_number_to_chars (p
, inst_main
.instruction
, inst_main
.size
);
5073 if (inst_main
.reloc
.type
!= BFD_RELOC_NONE
)
5075 s3_fix_new_score (frag_now
, p
- frag_now
->fr_literal
, inst_main
.size
,
5076 &inst_main
.reloc
.exp
, inst_main
.reloc
.pc_rel
, inst_main
.reloc
.type
);
5080 dwarf2_emit_insn (inst_main
.size
);
5083 /* s3_GP instruction can not do optimization, only can do relax between
5084 1 instruction and 3 instructions. */
5085 p
= frag_var (rs_machine_dependent
, inst_main
.relax_size
+ s3_RELAX_PAD_BYTE
, 0,
5086 s3_RELAX_ENCODE (inst_main
.size
, inst_main
.relax_size
, inst_main
.type
, 0, 4, 0),
5087 inst_main
.reloc
.exp
.X_add_symbol
, 0, NULL
);
5089 /* Write fr_var part.
5090 no calling s3_gen_insn_frag, no fixS will be generated. */
5091 s3_md_number_to_chars (p
, inst_expand
[0].instruction
, inst_expand
[0].size
);
5092 p
+= inst_expand
[0].size
;
5093 s3_md_number_to_chars (p
, inst_expand
[1].instruction
, inst_expand
[1].size
);
5094 p
+= inst_expand
[1].size
;
5096 /* relax lw rd, label -> ldis rs, imm16
5098 lw rd, [rs, imm15] or lw! rd, [rs, imm5]. */
5099 if (inst_expand
[2].relax_size
== 0)
5100 s3_md_number_to_chars (p
, inst_expand
[2].instruction
, inst_expand
[2].size
);
5102 s3_md_number_to_chars (p
, inst_expand
[2].relax_inst
, inst_expand
[2].relax_size
);
5106 s3_gen_insn_frag (&inst_expand
[0], NULL
);
5107 s3_gen_insn_frag (&inst_expand
[1], NULL
);
5108 s3_gen_insn_frag (&inst_expand
[2], NULL
);
5112 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
5117 s3_do_lw_pic (char *str
)
5121 s3_skip_whitespace (str
);
5122 if (((reg_rd
= s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
)
5123 || (s3_skip_past_comma (&str
) == (int) s3_FAIL
)
5124 || (s3_my_get_expression (&s3_inst
.reloc
.exp
, &str
) == (int) s3_FAIL
)
5125 || (s3_end_of_line (str
) == (int) s3_FAIL
))
5131 if (s3_inst
.reloc
.exp
.X_add_symbol
== 0)
5134 s3_inst
.error
= s3_BAD_ARGS
;
5139 s3_inst
.instruction
|= s3_GP
<< 15;
5140 s3_inst
.reloc
.type
= BFD_RELOC_SCORE_GOT15
;
5145 s3_do_empty (char *str
)
5148 if (s3_university_version
== 1)
5150 if (((s3_inst
.instruction
& 0x3e0003ff) == 0x0c000004)
5151 || ((s3_inst
.instruction
& 0x3e0003ff) == 0x0c000024)
5152 || ((s3_inst
.instruction
& 0x3e0003ff) == 0x0c000044)
5153 || ((s3_inst
.instruction
& 0x3e0003ff) == 0x0c000064))
5155 s3_inst
.error
= s3_ERR_FOR_SCORE5U_MMU
;
5159 if (s3_end_of_line (str
) == (int) s3_FAIL
)
5162 if (s3_inst
.relax_inst
!= 0x8000)
5164 if (s3_inst
.type
== NO_OPD
)
5166 s3_inst
.relax_size
= 2;
5170 s3_inst
.relax_size
= 4;
5176 s3_do16_int (char *str
)
5178 s3_skip_whitespace (str
);
5183 s3_do_jump (char *str
)
5187 s3_skip_whitespace (str
);
5188 if (s3_my_get_expression (&s3_inst
.reloc
.exp
, &str
) == (int) s3_FAIL
5189 || s3_end_of_line (str
) == (int) s3_FAIL
)
5192 if (s3_inst
.reloc
.exp
.X_add_symbol
== 0)
5194 s3_inst
.error
= _("lacking label ");
5198 if (!(s3_inst
.reloc
.exp
.X_add_number
>= -16777216
5199 && s3_inst
.reloc
.exp
.X_add_number
<= 16777215))
5201 s3_inst
.error
= _("invalid constant: 25 bit expression not in range [-16777216, 16777215]");
5205 save_in
= input_line_pointer
;
5206 input_line_pointer
= str
;
5207 s3_inst
.reloc
.type
= BFD_RELOC_SCORE_JMP
;
5208 s3_inst
.reloc
.pc_rel
= 1;
5209 input_line_pointer
= save_in
;
5213 s3_do_branch (char *str
)
5215 if (s3_my_get_expression (&s3_inst
.reloc
.exp
, &str
) == (int) s3_FAIL
5216 || s3_end_of_line (str
) == (int) s3_FAIL
)
5220 else if (s3_inst
.reloc
.exp
.X_add_symbol
== 0)
5222 s3_inst
.error
= _("lacking label ");
5225 else if (!(s3_inst
.reloc
.exp
.X_add_number
>= -524288
5226 && s3_inst
.reloc
.exp
.X_add_number
<= 524287))
5228 s3_inst
.error
= _("invalid constant: 20 bit expression not in range -2^19..2^19-1");
5232 s3_inst
.reloc
.type
= BFD_RELOC_SCORE_BRANCH
;
5233 s3_inst
.reloc
.pc_rel
= 1;
5235 /* Branch 32 offset field : 20 bit, 16 bit branch offset field : 8 bit. */
5236 s3_inst
.instruction
|= (s3_inst
.reloc
.exp
.X_add_number
& 0x3fe) | ((s3_inst
.reloc
.exp
.X_add_number
& 0xffc00) << 5);
5238 /* Compute 16 bit branch instruction. */
5239 if ((s3_inst
.relax_inst
!= 0x8000)
5240 && (s3_inst
.reloc
.exp
.X_add_number
>= -512 && s3_inst
.reloc
.exp
.X_add_number
<= 511))
5242 s3_inst
.relax_inst
|= ((s3_inst
.reloc
.exp
.X_add_number
>> 1) & 0x1ff);/*b! :disp 9 bit */
5243 s3_inst
.relax_size
= 2;
5247 s3_inst
.relax_inst
= 0x8000;
5252 s3_do16_branch (char *str
)
5254 if ((s3_my_get_expression (&s3_inst
.reloc
.exp
, &str
) == (int) s3_FAIL
5255 || s3_end_of_line (str
) == (int) s3_FAIL
))
5259 else if (s3_inst
.reloc
.exp
.X_add_symbol
== 0)
5261 s3_inst
.error
= _("lacking label");
5263 else if (!(s3_inst
.reloc
.exp
.X_add_number
>= -512
5264 && s3_inst
.reloc
.exp
.X_add_number
<= 511))
5266 s3_inst
.error
= _("invalid constant: 10 bit expression not in range [-2^9, 2^9-1]");
5270 s3_inst
.reloc
.type
= BFD_RELOC_SCORE16_BRANCH
;
5271 s3_inst
.reloc
.pc_rel
= 1;
5272 s3_inst
.instruction
|= ((s3_inst
.reloc
.exp
.X_add_number
>> 1) & 0x1ff);
5273 s3_inst
.relax_inst
|= ((s3_inst
.reloc
.exp
.X_add_number
) & 0x1ff);
5274 s3_inst
.relax_size
= 4;
5278 /* Return true if the given symbol should be considered local for s3_PIC. */
5280 s3_pic_need_relax (symbolS
*sym
, asection
*segtype
)
5283 bfd_boolean linkonce
;
5285 /* Handle the case of a symbol equated to another symbol. */
5286 while (symbol_equated_reloc_p (sym
))
5290 /* It's possible to get a loop here in a badly written
5292 n
= symbol_get_value_expression (sym
)->X_add_symbol
;
5298 symsec
= S_GET_SEGMENT (sym
);
5300 /* duplicate the test for LINK_ONCE sections as in adjust_reloc_syms */
5302 if (symsec
!= segtype
&& ! S_IS_LOCAL (sym
))
5304 if ((bfd_get_section_flags (stdoutput
, symsec
) & SEC_LINK_ONCE
) != 0)
5307 /* The GNU toolchain uses an extension for ELF: a section
5308 beginning with the magic string .gnu.linkonce is a linkonce
5310 if (strncmp (segment_name (symsec
), ".gnu.linkonce",
5311 sizeof ".gnu.linkonce" - 1) == 0)
5315 /* This must duplicate the test in adjust_reloc_syms. */
5316 return (!bfd_is_und_section (symsec
)
5317 && !bfd_is_abs_section (symsec
)
5318 && !bfd_is_com_section (symsec
)
5321 /* A global or weak symbol is treated as external. */
5322 && (OUTPUT_FLAVOR
!= bfd_target_elf_flavour
5323 || (! S_IS_WEAK (sym
) && ! S_IS_EXTERNAL (sym
)))
5329 s3_parse_pce_inst (char *insnstr
)
5333 char first
[s3_MAX_LITERAL_POOL_SIZE
];
5334 char second
[s3_MAX_LITERAL_POOL_SIZE
];
5335 struct s3_score_it pec_part_1
;
5337 /* Get first part string of PCE. */
5338 p
= strstr (insnstr
, "||");
5341 sprintf (first
, "%s", insnstr
);
5343 /* Get second part string of PCE. */
5346 sprintf (second
, "%s", p
);
5348 s3_parse_16_32_inst (first
, FALSE
);
5352 memcpy (&pec_part_1
, &s3_inst
, sizeof (s3_inst
));
5354 s3_parse_16_32_inst (second
, FALSE
);
5358 if ( ((pec_part_1
.size
== s3_INSN_SIZE
) && (s3_inst
.size
== s3_INSN_SIZE
))
5359 || ((pec_part_1
.size
== s3_INSN_SIZE
) && (s3_inst
.size
== s3_INSN16_SIZE
))
5360 || ((pec_part_1
.size
== s3_INSN16_SIZE
) && (s3_inst
.size
== s3_INSN_SIZE
)))
5362 s3_inst
.error
= _("pce instruction error (16 bit || 16 bit).");
5363 sprintf (s3_inst
.str
, "%s", insnstr
);
5368 s3_gen_insn_frag (&pec_part_1
, &s3_inst
);
5373 s3_do16_dsp (char *str
)
5378 if (s3_score3d
== 0)
5380 s3_inst
.error
= _("score3d instruction.");
5384 s3_skip_whitespace (str
);
5386 if ((rd
= s3_reglow_required_here (&str
, 0)) == (int) s3_FAIL
5387 || s3_end_of_line (str
) == (int) s3_FAIL
)
5393 s3_inst
.relax_inst
|= rd
<< 20;
5394 s3_inst
.relax_size
= 4;
5399 s3_do16_dsp2 (char *str
)
5402 if (s3_score3d
== 0)
5404 s3_inst
.error
= _("score3d instruction.");
5408 s3_skip_whitespace (str
);
5410 if (s3_reglow_required_here (&str
, 4) == (int) s3_FAIL
5411 || s3_skip_past_comma (&str
) == (int) s3_FAIL
5412 || s3_reglow_required_here (&str
, 0) == (int) s3_FAIL
5413 || s3_end_of_line (str
) == (int) s3_FAIL
)
5419 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>> 8) & 0xf) << 20)
5420 | (((s3_inst
.instruction
>> 8) & 0xf) << 15) | (((s3_inst
.instruction
>> 4) & 0xf) << 10);
5421 s3_inst
.relax_size
= 4;
5426 s3_do_dsp (char *str
)
5429 if (s3_score3d
== 0)
5431 s3_inst
.error
= _("score3d instruction.");
5435 s3_skip_whitespace (str
);
5437 if (s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
5438 || s3_skip_past_comma (&str
) == (int) s3_FAIL
5439 || s3_reg_required_here (&str
, 10, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
5440 || s3_end_of_line (str
) == (int) s3_FAIL
)
5443 if ((s3_inst
.relax_inst
!= 0x8000) && (((s3_inst
.instruction
>> 20) & 0x1f) == 3) )
5445 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>> 10) & 0x1f)) | (((s3_inst
.instruction
>> 15) & 0x1f) << 5);
5446 s3_inst
.relax_size
= 2;
5449 s3_inst
.relax_inst
= 0x8000;
5453 s3_do_dsp2 (char *str
)
5458 if (s3_score3d
== 0)
5460 s3_inst
.error
= _("score3d instruction.");
5464 s3_skip_whitespace (str
);
5466 if ((reg
= s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
5467 || s3_skip_past_comma (&str
) == (int) s3_FAIL
5468 || s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
5469 || s3_skip_past_comma (&str
) == (int) s3_FAIL
5470 || s3_reg_required_here (&str
, 10, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
5471 || s3_end_of_line (str
) == (int) s3_FAIL
)
5477 /* Check mulr, mulur rd is even number. */
5478 if (((s3_inst
.instruction
& 0x3e0003ff) == 0x00000340
5479 || (s3_inst
.instruction
& 0x3e0003ff) == 0x00000342)
5482 s3_inst
.error
= _("rd must be even number.");
5486 if ((((s3_inst
.instruction
>> 15) & 0x10) == 0)
5487 && (((s3_inst
.instruction
>> 10) & 0x10) == 0)
5488 && (((s3_inst
.instruction
>> 20) & 0x10) == 0)
5489 && (s3_inst
.relax_inst
!= 0x8000)
5490 && (((s3_inst
.instruction
>> 20) & 0xf) == ((s3_inst
.instruction
>> 15) & 0xf)))
5492 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>> 10) & 0xf) )
5493 | (((s3_inst
.instruction
>> 15) & 0xf) << 4);
5494 s3_inst
.relax_size
= 2;
5498 s3_inst
.relax_inst
= 0x8000;
5504 s3_do_dsp3 (char *str
)
5507 if (s3_score3d
== 0)
5509 s3_inst
.error
= _("score3d instruction.");
5513 s3_skip_whitespace (str
);
5515 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
5516 || s3_skip_past_comma (&str
) == (int) s3_FAIL
5517 || s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
5518 || s3_end_of_line (str
) == (int) s3_FAIL
)
5521 if ((s3_inst
.relax_inst
!= 0x8000) && (((s3_inst
.instruction
>> 20) & 0x1f) == 3) )
5523 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>> 10) & 0x1f)) | (((s3_inst
.instruction
>> 15) & 0x1f) << 5);
5524 s3_inst
.relax_size
= 2;
5527 s3_inst
.relax_inst
= 0x8000;
5531 /* If we change section we must dump the literal pool first. */
5533 s3_s_score_bss (int ignore ATTRIBUTE_UNUSED
)
5535 subseg_set (bss_section
, (subsegT
) get_absolute_expression ());
5536 demand_empty_rest_of_line ();
5540 s3_s_score_text (int ignore
)
5542 obj_elf_text (ignore
);
5543 record_alignment (now_seg
, 2);
5547 s3_score_s_section (int ignore
)
5549 obj_elf_section (ignore
);
5550 if ((bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
) != 0)
5551 record_alignment (now_seg
, 2);
5556 s3_s_change_sec (int sec
)
5561 /* The ELF backend needs to know that we are changing sections, so
5562 that .previous works correctly. We could do something like check
5563 for an obj_section_change_hook macro, but that might be confusing
5564 as it would not be appropriate to use it in the section changing
5565 functions in read.c, since obj-elf.c intercepts those. FIXME:
5566 This should be cleaner, somehow. */
5567 obj_elf_section_change_hook ();
5572 seg
= subseg_new (s3_RDATA_SECTION_NAME
, (subsegT
) get_absolute_expression ());
5573 bfd_set_section_flags (stdoutput
, seg
, (SEC_ALLOC
| SEC_LOAD
| SEC_READONLY
| SEC_RELOC
| SEC_DATA
));
5574 if (strcmp (TARGET_OS
, "elf") != 0)
5575 record_alignment (seg
, 4);
5576 demand_empty_rest_of_line ();
5579 seg
= subseg_new (".sdata", (subsegT
) get_absolute_expression ());
5580 bfd_set_section_flags (stdoutput
, seg
, SEC_ALLOC
| SEC_LOAD
| SEC_RELOC
| SEC_DATA
);
5581 if (strcmp (TARGET_OS
, "elf") != 0)
5582 record_alignment (seg
, 4);
5583 demand_empty_rest_of_line ();
5589 s3_s_score_mask (int reg_type ATTRIBUTE_UNUSED
)
5593 if (s3_cur_proc_ptr
== (s3_procS
*) NULL
)
5595 as_warn (_(".mask outside of .ent"));
5596 demand_empty_rest_of_line ();
5599 if (get_absolute_expression_and_terminator (&mask
) != ',')
5601 as_warn (_("Bad .mask directive"));
5602 --input_line_pointer
;
5603 demand_empty_rest_of_line ();
5606 off
= get_absolute_expression ();
5607 s3_cur_proc_ptr
->reg_mask
= mask
;
5608 s3_cur_proc_ptr
->reg_offset
= off
;
5609 demand_empty_rest_of_line ();
5613 s3_get_symbol (void)
5619 c
= get_symbol_name (&name
);
5620 p
= (symbolS
*) symbol_find_or_make (name
);
5621 (void) restore_line_pointer (c
);
5626 s3_get_number (void)
5631 if (*input_line_pointer
== '-')
5633 ++input_line_pointer
;
5636 if (!ISDIGIT (*input_line_pointer
))
5637 as_bad (_("expected simple number"));
5638 if (input_line_pointer
[0] == '0')
5640 if (input_line_pointer
[1] == 'x')
5642 input_line_pointer
+= 2;
5643 while (ISXDIGIT (*input_line_pointer
))
5646 val
|= hex_value (*input_line_pointer
++);
5648 return negative
? -val
: val
;
5652 ++input_line_pointer
;
5653 while (ISDIGIT (*input_line_pointer
))
5656 val
|= *input_line_pointer
++ - '0';
5658 return negative
? -val
: val
;
5661 if (!ISDIGIT (*input_line_pointer
))
5663 printf (_(" *input_line_pointer == '%c' 0x%02x\n"), *input_line_pointer
, *input_line_pointer
);
5664 as_warn (_("invalid number"));
5667 while (ISDIGIT (*input_line_pointer
))
5670 val
+= *input_line_pointer
++ - '0';
5672 return negative
? -val
: val
;
5675 /* The .aent and .ent directives. */
5677 s3_s_score_ent (int aent
)
5682 symbolP
= s3_get_symbol ();
5683 if (*input_line_pointer
== ',')
5684 ++input_line_pointer
;
5686 if (ISDIGIT (*input_line_pointer
) || *input_line_pointer
== '-')
5689 #ifdef BFD_ASSEMBLER
5690 if ((bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
) != 0)
5695 if (now_seg
!= data_section
&& now_seg
!= bss_section
)
5701 as_warn (_(".ent or .aent not in text section."));
5702 if (!aent
&& s3_cur_proc_ptr
)
5703 as_warn (_("missing .end"));
5706 s3_cur_proc_ptr
= &s3_cur_proc
;
5707 s3_cur_proc_ptr
->reg_mask
= 0xdeadbeaf;
5708 s3_cur_proc_ptr
->reg_offset
= 0xdeadbeaf;
5709 s3_cur_proc_ptr
->fpreg_mask
= 0xdeafbeaf;
5710 s3_cur_proc_ptr
->leaf
= 0xdeafbeaf;
5711 s3_cur_proc_ptr
->frame_offset
= 0xdeafbeaf;
5712 s3_cur_proc_ptr
->frame_reg
= 0xdeafbeaf;
5713 s3_cur_proc_ptr
->pc_reg
= 0xdeafbeaf;
5714 s3_cur_proc_ptr
->isym
= symbolP
;
5715 symbol_get_bfdsym (symbolP
)->flags
|= BSF_FUNCTION
;
5717 if (debug_type
== DEBUG_STABS
)
5718 stabs_generate_asm_func (S_GET_NAME (symbolP
), S_GET_NAME (symbolP
));
5720 demand_empty_rest_of_line ();
5724 s3_s_score_frame (int ignore ATTRIBUTE_UNUSED
)
5731 backupstr
= input_line_pointer
;
5734 if (s3_cur_proc_ptr
== (s3_procS
*) NULL
)
5736 as_warn (_(".frame outside of .ent"));
5737 demand_empty_rest_of_line ();
5740 s3_cur_proc_ptr
->frame_reg
= s3_reg_required_here ((&backupstr
), 0, s3_REG_TYPE_SCORE
);
5742 s3_skip_past_comma (&backupstr
);
5743 while (*backupstr
!= ',')
5745 str
[i
] = *backupstr
;
5753 s3_skip_past_comma (&backupstr
);
5754 s3_cur_proc_ptr
->frame_offset
= val
;
5755 s3_cur_proc_ptr
->pc_reg
= s3_reg_required_here ((&backupstr
), 0, s3_REG_TYPE_SCORE
);
5758 s3_skip_past_comma (&backupstr
);
5760 while (*backupstr
!= '\n')
5762 str
[i
] = *backupstr
;
5768 s3_cur_proc_ptr
->leaf
= val
;
5770 s3_skip_past_comma (&backupstr
);
5772 #endif /* OBJ_ELF */
5773 while (input_line_pointer
!= backupstr
)
5774 input_line_pointer
++;
5777 /* The .end directive. */
5779 s3_s_score_end (int x ATTRIBUTE_UNUSED
)
5784 /* Generate a .pdr section. */
5785 segT saved_seg
= now_seg
;
5786 subsegT saved_subseg
= now_subseg
;
5790 if (!is_end_of_line
[(unsigned char)*input_line_pointer
])
5792 p
= s3_get_symbol ();
5793 demand_empty_rest_of_line ();
5798 #ifdef BFD_ASSEMBLER
5799 if ((bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
) != 0)
5804 if (now_seg
!= data_section
&& now_seg
!= bss_section
)
5811 as_warn (_(".end not in text section"));
5812 if (!s3_cur_proc_ptr
)
5814 as_warn (_(".end directive without a preceding .ent directive."));
5815 demand_empty_rest_of_line ();
5820 gas_assert (S_GET_NAME (p
));
5821 if (strcmp (S_GET_NAME (p
), S_GET_NAME (s3_cur_proc_ptr
->isym
)))
5822 as_warn (_(".end symbol does not match .ent symbol."));
5823 if (debug_type
== DEBUG_STABS
)
5824 stabs_generate_asm_endfunc (S_GET_NAME (p
), S_GET_NAME (p
));
5827 as_warn (_(".end directive missing or unknown symbol"));
5829 if ((s3_cur_proc_ptr
->reg_mask
== 0xdeadbeaf) ||
5830 (s3_cur_proc_ptr
->reg_offset
== 0xdeadbeaf) ||
5831 (s3_cur_proc_ptr
->leaf
== 0xdeafbeaf) ||
5832 (s3_cur_proc_ptr
->frame_offset
== 0xdeafbeaf) ||
5833 (s3_cur_proc_ptr
->frame_reg
== 0xdeafbeaf) || (s3_cur_proc_ptr
->pc_reg
== 0xdeafbeaf));
5837 (void) frag_now_fix ();
5838 gas_assert (s3_pdr_seg
);
5839 subseg_set (s3_pdr_seg
, 0);
5840 /* Write the symbol. */
5841 exp
.X_op
= O_symbol
;
5842 exp
.X_add_symbol
= p
;
5843 exp
.X_add_number
= 0;
5844 emit_expr (&exp
, 4);
5845 fragp
= frag_more (7 * 4);
5846 md_number_to_chars (fragp
, (valueT
) s3_cur_proc_ptr
->reg_mask
, 4);
5847 md_number_to_chars (fragp
+ 4, (valueT
) s3_cur_proc_ptr
->reg_offset
, 4);
5848 md_number_to_chars (fragp
+ 8, (valueT
) s3_cur_proc_ptr
->fpreg_mask
, 4);
5849 md_number_to_chars (fragp
+ 12, (valueT
) s3_cur_proc_ptr
->leaf
, 4);
5850 md_number_to_chars (fragp
+ 16, (valueT
) s3_cur_proc_ptr
->frame_offset
, 4);
5851 md_number_to_chars (fragp
+ 20, (valueT
) s3_cur_proc_ptr
->frame_reg
, 4);
5852 md_number_to_chars (fragp
+ 24, (valueT
) s3_cur_proc_ptr
->pc_reg
, 4);
5853 subseg_set (saved_seg
, saved_subseg
);
5856 s3_cur_proc_ptr
= NULL
;
5859 /* Handle the .set pseudo-op. */
5861 s3_s_score_set (int x ATTRIBUTE_UNUSED
)
5864 char name
[s3_MAX_LITERAL_POOL_SIZE
];
5865 char * orig_ilp
= input_line_pointer
;
5867 while (!is_end_of_line
[(unsigned char)*input_line_pointer
])
5869 name
[i
] = (char) * input_line_pointer
;
5871 ++input_line_pointer
;
5876 if (strcmp (name
, "nwarn") == 0)
5878 s3_warn_fix_data_dependency
= 0;
5880 else if (strcmp (name
, "fixdd") == 0)
5882 s3_fix_data_dependency
= 1;
5884 else if (strcmp (name
, "nofixdd") == 0)
5886 s3_fix_data_dependency
= 0;
5888 else if (strcmp (name
, "r1") == 0)
5892 else if (strcmp (name
, "nor1") == 0)
5896 else if (strcmp (name
, "optimize") == 0)
5900 else if (strcmp (name
, "volatile") == 0)
5904 else if (strcmp (name
, "pic") == 0)
5906 s3_score_pic
= s3_PIC
;
5910 input_line_pointer
= orig_ilp
;
5915 /* Handle the .cpload pseudo-op. This is used when generating s3_PIC code. It sets the
5916 $gp register for the function based on the function address, which is in the register
5917 named in the argument. This uses a relocation against GP_DISP_LABEL, which is handled
5918 specially by the linker. The result is:
5919 ldis gp, %hi(GP_DISP_LABEL)
5920 ori gp, %low(GP_DISP_LABEL)
5921 add gp, gp, .cpload argument
5922 The .cpload argument is normally r29. */
5924 s3_s_score_cpload (int ignore ATTRIBUTE_UNUSED
)
5927 char insn_str
[s3_MAX_LITERAL_POOL_SIZE
];
5929 /* If we are not generating s3_PIC code, .cpload is ignored. */
5930 if (s3_score_pic
== s3_NO_PIC
)
5936 if ((reg
= s3_reg_required_here (&input_line_pointer
, -1, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
)
5939 demand_empty_rest_of_line ();
5941 sprintf (insn_str
, "ld_i32hi r%d, %s", s3_GP
, GP_DISP_LABEL
);
5942 if (s3_append_insn (insn_str
, TRUE
) == (int) s3_FAIL
)
5945 sprintf (insn_str
, "ld_i32lo r%d, %s", s3_GP
, GP_DISP_LABEL
);
5946 if (s3_append_insn (insn_str
, TRUE
) == (int) s3_FAIL
)
5949 sprintf (insn_str
, "add r%d, r%d, r%d", s3_GP
, s3_GP
, reg
);
5950 if (s3_append_insn (insn_str
, TRUE
) == (int) s3_FAIL
)
5954 /* Handle the .cprestore pseudo-op. This stores $gp into a given
5955 offset from $sp. The offset is remembered, and after making a s3_PIC
5956 call $gp is restored from that location. */
5958 s3_s_score_cprestore (int ignore ATTRIBUTE_UNUSED
)
5961 int cprestore_offset
;
5962 char insn_str
[s3_MAX_LITERAL_POOL_SIZE
];
5964 /* If we are not generating s3_PIC code, .cprestore is ignored. */
5965 if (s3_score_pic
== s3_NO_PIC
)
5971 if ((reg
= s3_reg_required_here (&input_line_pointer
, -1, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
5972 || s3_skip_past_comma (&input_line_pointer
) == (int) s3_FAIL
)
5977 cprestore_offset
= get_absolute_expression ();
5979 if (cprestore_offset
<= 0x3fff)
5981 sprintf (insn_str
, "sw r%d, [r%d, %d]", s3_GP
, reg
, cprestore_offset
);
5982 if (s3_append_insn (insn_str
, TRUE
) == (int) s3_FAIL
)
5992 sprintf (insn_str
, "li r1, %d", cprestore_offset
);
5993 if (s3_append_insn (insn_str
, TRUE
) == (int) s3_FAIL
)
5996 sprintf (insn_str
, "add r1, r1, r%d", reg
);
5997 if (s3_append_insn (insn_str
, TRUE
) == (int) s3_FAIL
)
6000 sprintf (insn_str
, "sw r%d, [r1]", s3_GP
);
6001 if (s3_append_insn (insn_str
, TRUE
) == (int) s3_FAIL
)
6007 demand_empty_rest_of_line ();
6010 /* Handle the .gpword pseudo-op. This is used when generating s3_PIC
6011 code. It generates a 32 bit s3_GP relative reloc. */
6013 s3_s_score_gpword (int ignore ATTRIBUTE_UNUSED
)
6018 /* When not generating s3_PIC code, this is treated as .word. */
6019 if (s3_score_pic
== s3_NO_PIC
)
6025 if (ex
.X_op
!= O_symbol
|| ex
.X_add_number
!= 0)
6027 as_bad (_("Unsupported use of .gpword"));
6028 ignore_rest_of_line ();
6031 s3_md_number_to_chars (p
, (valueT
) 0, 4);
6032 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 4, &ex
, FALSE
, BFD_RELOC_GPREL32
);
6033 demand_empty_rest_of_line ();
6036 /* Handle the .cpadd pseudo-op. This is used when dealing with switch
6037 tables in s3_PIC code. */
6039 s3_s_score_cpadd (int ignore ATTRIBUTE_UNUSED
)
6042 char insn_str
[s3_MAX_LITERAL_POOL_SIZE
];
6044 /* If we are not generating s3_PIC code, .cpload is ignored. */
6045 if (s3_score_pic
== s3_NO_PIC
)
6051 if ((reg
= s3_reg_required_here (&input_line_pointer
, -1, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
)
6055 demand_empty_rest_of_line ();
6057 /* Add $gp to the register named as an argument. */
6058 sprintf (insn_str
, "add r%d, r%d, r%d", reg
, reg
, s3_GP
);
6059 if (s3_append_insn (insn_str
, TRUE
) == (int) s3_FAIL
)
6063 #ifndef TC_IMPLICIT_LCOMM_ALIGNMENT
6064 #define TC_IMPLICIT_LCOMM_ALIGNMENT(SIZE, P2VAR) \
6069 else if ((SIZE) >= 4) \
6071 else if ((SIZE) >= 2) \
6080 s3_s_score_lcomm (int bytes_p
)
6087 segT current_seg
= now_seg
;
6088 subsegT current_subseg
= now_subseg
;
6089 const int max_alignment
= 15;
6091 segT bss_seg
= bss_section
;
6092 int needs_align
= 0;
6094 c
= get_symbol_name (&name
);
6095 p
= input_line_pointer
;
6096 (void) restore_line_pointer (c
);
6100 as_bad (_("expected symbol name"));
6101 discard_rest_of_line ();
6107 /* Accept an optional comma after the name. The comma used to be
6108 required, but Irix 5 cc does not generate it. */
6109 if (*input_line_pointer
== ',')
6111 ++input_line_pointer
;
6115 if (is_end_of_line
[(unsigned char)*input_line_pointer
])
6117 as_bad (_("missing size expression"));
6121 if ((temp
= get_absolute_expression ()) < 0)
6123 as_warn (_("BSS length (%d) < 0 ignored"), temp
);
6124 ignore_rest_of_line ();
6128 #if defined (TC_SCORE)
6129 if (OUTPUT_FLAVOR
== bfd_target_ecoff_flavour
|| OUTPUT_FLAVOR
== bfd_target_elf_flavour
)
6131 /* For Score and Alpha ECOFF or ELF, small objects are put in .sbss. */
6132 if ((unsigned)temp
<= bfd_get_gp_size (stdoutput
))
6134 bss_seg
= subseg_new (".sbss", 1);
6135 seg_info (bss_seg
)->bss
= 1;
6136 #ifdef BFD_ASSEMBLER
6137 if (!bfd_set_section_flags (stdoutput
, bss_seg
, SEC_ALLOC
))
6138 as_warn (_("error setting flags for \".sbss\": %s"), bfd_errmsg (bfd_get_error ()));
6145 if (*input_line_pointer
== ',')
6147 ++input_line_pointer
;
6150 if (is_end_of_line
[(unsigned char)*input_line_pointer
])
6152 as_bad (_("missing alignment"));
6157 align
= get_absolute_expression ();
6164 TC_IMPLICIT_LCOMM_ALIGNMENT (temp
, align
);
6166 /* Still zero unless TC_IMPLICIT_LCOMM_ALIGNMENT set it. */
6168 record_alignment (bss_seg
, align
);
6175 /* Convert to a power of 2. */
6180 for (i
= 0; align
!= 0; align
>>= 1, ++i
)
6186 if (align
> max_alignment
)
6188 align
= max_alignment
;
6189 as_warn (_("alignment too large; %d assumed"), align
);
6194 as_warn (_("alignment negative; 0 assumed"));
6197 record_alignment (bss_seg
, align
);
6201 /* Assume some objects may require alignment on some systems. */
6202 #if defined (TC_ALPHA) && ! defined (VMS)
6205 align
= ffs (temp
) - 1;
6206 if (temp
% (1 << align
))
6213 symbolP
= symbol_find_or_make (name
);
6217 #if (defined (OBJ_AOUT) || defined (OBJ_MAYBE_AOUT))
6218 #ifdef BFD_ASSEMBLER
6219 (OUTPUT_FLAVOR
!= bfd_target_aout_flavour
6220 || (S_GET_OTHER (symbolP
) == 0 && S_GET_DESC (symbolP
) == 0)) &&
6222 (S_GET_OTHER (symbolP
) == 0 && S_GET_DESC (symbolP
) == 0) &&
6225 (S_GET_SEGMENT (symbolP
) == bss_seg
|| (!S_IS_DEFINED (symbolP
) && S_GET_VALUE (symbolP
) == 0)))
6229 subseg_set (bss_seg
, 1);
6232 frag_align (align
, 0, 0);
6234 /* Detach from old frag. */
6235 if (S_GET_SEGMENT (symbolP
) == bss_seg
)
6236 symbol_get_frag (symbolP
)->fr_symbol
= NULL
;
6238 symbol_set_frag (symbolP
, frag_now
);
6239 pfrag
= frag_var (rs_org
, 1, 1, (relax_substateT
) 0, symbolP
, (offsetT
) temp
, NULL
);
6243 S_SET_SEGMENT (symbolP
, bss_seg
);
6246 /* The symbol may already have been created with a preceding
6247 ".globl" directive -- be careful not to step on storage class
6248 in that case. Otherwise, set it to static. */
6249 if (S_GET_STORAGE_CLASS (symbolP
) != C_EXT
)
6251 S_SET_STORAGE_CLASS (symbolP
, C_STAT
);
6253 #endif /* OBJ_COFF */
6256 S_SET_SIZE (symbolP
, temp
);
6260 as_bad (_("symbol `%s' is already defined"), S_GET_NAME (symbolP
));
6262 subseg_set (current_seg
, current_subseg
);
6264 demand_empty_rest_of_line ();
6268 s3_insert_reg (const struct s3_reg_entry
*r
, struct hash_control
*htab
)
6271 int len
= strlen (r
->name
) + 2;
6272 char *buf
= XNEWVEC (char, len
);
6273 char *buf2
= XNEWVEC (char, len
);
6275 strcpy (buf
+ i
, r
->name
);
6276 for (i
= 0; buf
[i
]; i
++)
6278 buf2
[i
] = TOUPPER (buf
[i
]);
6282 hash_insert (htab
, buf
, (void *) r
);
6283 hash_insert (htab
, buf2
, (void *) r
);
6287 s3_build_reg_hsh (struct s3_reg_map
*map
)
6289 const struct s3_reg_entry
*r
;
6291 if ((map
->htab
= hash_new ()) == NULL
)
6293 as_fatal (_("virtual memory exhausted"));
6295 for (r
= map
->names
; r
->name
!= NULL
; r
++)
6297 s3_insert_reg (r
, map
->htab
);
6301 /* Iterate over the base tables to create the instruction patterns. */
6303 s3_build_score_ops_hsh (void)
6306 static struct obstack insn_obstack
;
6308 obstack_begin (&insn_obstack
, 4000);
6309 for (i
= 0; i
< sizeof (s3_score_insns
) / sizeof (struct s3_asm_opcode
); i
++)
6311 const struct s3_asm_opcode
*insn
= s3_score_insns
+ i
;
6312 size_t len
= strlen (insn
->template_name
);
6313 struct s3_asm_opcode
*new_opcode
;
6314 char *template_name
;
6315 new_opcode
= (struct s3_asm_opcode
*)
6316 obstack_alloc (&insn_obstack
, sizeof (struct s3_asm_opcode
));
6317 template_name
= (char *) obstack_alloc (& insn_obstack
, len
+ 1);
6319 strcpy (template_name
, insn
->template_name
);
6320 new_opcode
->template_name
= template_name
;
6321 new_opcode
->parms
= insn
->parms
;
6322 new_opcode
->value
= insn
->value
;
6323 new_opcode
->relax_value
= insn
->relax_value
;
6324 new_opcode
->type
= insn
->type
;
6325 new_opcode
->bitmask
= insn
->bitmask
;
6326 hash_insert (s3_score_ops_hsh
, new_opcode
->template_name
,
6327 (void *) new_opcode
);
6332 s3_build_dependency_insn_hsh (void)
6335 static struct obstack dependency_obstack
;
6337 obstack_begin (&dependency_obstack
, 4000);
6338 for (i
= 0; i
< sizeof (s3_insn_to_dependency_table
) / sizeof (s3_insn_to_dependency_table
[0]); i
++)
6340 const struct s3_insn_to_dependency
*tmp
= s3_insn_to_dependency_table
+ i
;
6341 size_t len
= strlen (tmp
->insn_name
);
6342 struct s3_insn_to_dependency
*new_i2n
;
6345 new_i2n
= (struct s3_insn_to_dependency
*)
6346 obstack_alloc (&dependency_obstack
,
6347 sizeof (struct s3_insn_to_dependency
));
6348 buf
= (char *) obstack_alloc (&dependency_obstack
, len
+ 1);
6350 strcpy (buf
, tmp
->insn_name
);
6351 new_i2n
->insn_name
= buf
;
6352 new_i2n
->type
= tmp
->type
;
6353 hash_insert (s3_dependency_insn_hsh
, new_i2n
->insn_name
,
6359 s_score_bss (int ignore ATTRIBUTE_UNUSED
)
6362 return s3_s_score_bss (ignore
);
6364 return s7_s_score_bss (ignore
);
6368 s_score_text (int ignore
)
6371 return s3_s_score_text (ignore
);
6373 return s7_s_score_text (ignore
);
6377 s_section (int ignore
)
6380 return s3_score_s_section (ignore
);
6382 return s7_s_section (ignore
);
6386 s_change_sec (int sec
)
6389 return s3_s_change_sec (sec
);
6391 return s7_s_change_sec (sec
);
6395 s_score_mask (int reg_type ATTRIBUTE_UNUSED
)
6398 return s3_s_score_mask (reg_type
);
6400 return s7_s_score_mask (reg_type
);
6404 s_score_ent (int aent
)
6407 return s3_s_score_ent (aent
);
6409 return s7_s_score_ent (aent
);
6413 s_score_frame (int ignore ATTRIBUTE_UNUSED
)
6416 return s3_s_score_frame (ignore
);
6418 return s7_s_score_frame (ignore
);
6422 s_score_end (int x ATTRIBUTE_UNUSED
)
6425 return s3_s_score_end (x
);
6427 return s7_s_score_end (x
);
6431 s_score_set (int x ATTRIBUTE_UNUSED
)
6434 return s3_s_score_set (x
);
6436 return s7_s_score_set (x
);
6440 s_score_cpload (int ignore ATTRIBUTE_UNUSED
)
6443 return s3_s_score_cpload (ignore
);
6445 return s7_s_score_cpload (ignore
);
6449 s_score_cprestore (int ignore ATTRIBUTE_UNUSED
)
6452 return s3_s_score_cprestore (ignore
);
6454 return s7_s_score_cprestore (ignore
);
6458 s_score_gpword (int ignore ATTRIBUTE_UNUSED
)
6461 return s3_s_score_gpword (ignore
);
6463 return s7_s_score_gpword (ignore
);
6467 s_score_cpadd (int ignore ATTRIBUTE_UNUSED
)
6470 return s3_s_score_cpadd (ignore
);
6472 return s7_s_score_cpadd (ignore
);
6476 s_score_lcomm (int bytes_p
)
6479 return s3_s_score_lcomm (bytes_p
);
6481 return s7_s_score_lcomm (bytes_p
);
6485 s3_assemble (char *str
)
6488 know (strlen (str
) < s3_MAX_LITERAL_POOL_SIZE
);
6490 memset (&s3_inst
, '\0', sizeof (s3_inst
));
6491 if (s3_INSN_IS_PCE_P (str
))
6492 s3_parse_pce_inst (str
);
6493 else if (s3_INSN_IS_48_P (str
))
6494 s3_parse_48_inst (str
, TRUE
);
6496 s3_parse_16_32_inst (str
, TRUE
);
6499 as_bad (_("%s -- `%s'"), s3_inst
.error
, s3_inst
.str
);
6503 s3_operand (expressionS
* exp
)
6505 if (s3_in_my_get_expression
)
6507 exp
->X_op
= O_illegal
;
6508 if (s3_inst
.error
== NULL
)
6510 s3_inst
.error
= _("bad expression");
6522 if ((s3_score_ops_hsh
= hash_new ()) == NULL
)
6523 as_fatal (_("virtual memory exhausted"));
6525 s3_build_score_ops_hsh ();
6527 if ((s3_dependency_insn_hsh
= hash_new ()) == NULL
)
6528 as_fatal (_("virtual memory exhausted"));
6530 s3_build_dependency_insn_hsh ();
6532 for (i
= (int)s3_REG_TYPE_FIRST
; i
< (int)s3_REG_TYPE_MAX
; i
++)
6533 s3_build_reg_hsh (s3_all_reg_maps
+ i
);
6535 /* Initialize dependency vector. */
6536 s3_init_dependency_vector ();
6538 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
, 0);
6540 subseg
= now_subseg
;
6541 s3_pdr_seg
= subseg_new (".pdr", (subsegT
) 0);
6542 (void)bfd_set_section_flags (stdoutput
, s3_pdr_seg
, SEC_READONLY
| SEC_RELOC
| SEC_DEBUGGING
);
6543 (void)bfd_set_section_alignment (stdoutput
, s3_pdr_seg
, 2);
6544 subseg_set (seg
, subseg
);
6546 if (s3_USE_GLOBAL_POINTER_OPT
)
6547 bfd_set_gp_size (stdoutput
, s3_g_switch_value
);
6551 s3_number_to_chars (char *buf
, valueT val
, int n
)
6553 if (target_big_endian
)
6554 number_to_chars_bigendian (buf
, val
, n
);
6556 number_to_chars_littleendian (buf
, val
, n
);
6560 s3_normal_chars_to_number (char *buf
, int n
)
6563 unsigned char *where
= (unsigned char *)buf
;
6565 if (target_big_endian
)
6570 result
|= (*where
++ & 255);
6578 result
|= (where
[n
] & 255);
6586 s3_number_to_chars_littleendian (void *p
, valueT data
, int n
)
6588 char *buf
= (char *) p
;
6593 md_number_to_chars (buf
, data
>> 16, 2);
6594 md_number_to_chars (buf
+ 2, data
, 2);
6597 md_number_to_chars (buf
, data
>> 32, 2);
6598 md_number_to_chars (buf
+ 2, data
>> 16, 2);
6599 md_number_to_chars (buf
+ 4, data
, 2);
6602 /* Error routine. */
6603 as_bad_where (__FILE__
, __LINE__
, _("size is not 4 or 6"));
6609 s3_chars_to_number_littleendian (const void *p
, int n
)
6611 char *buf
= (char *) p
;
6617 result
= s3_normal_chars_to_number (buf
, 2) << 16;
6618 result
|= s3_normal_chars_to_number (buf
+ 2, 2);
6621 result
= s3_normal_chars_to_number (buf
, 2) << 32;
6622 result
|= s3_normal_chars_to_number (buf
+ 2, 2) << 16;
6623 result
|= s3_normal_chars_to_number (buf
+ 4, 2);
6626 /* Error routine. */
6627 as_bad_where (__FILE__
, __LINE__
, _("size is not 4 or 6"));
6635 s3_md_number_to_chars (char *buf
, valueT val
, int n
)
6637 if (!target_big_endian
&& n
>= 4)
6638 s3_number_to_chars_littleendian (buf
, val
, n
);
6640 md_number_to_chars (buf
, val
, n
);
6644 s3_md_chars_to_number (char *buf
, int n
)
6648 if (!target_big_endian
&& n
>= 4)
6649 result
= s3_chars_to_number_littleendian (buf
, n
);
6651 result
= s3_normal_chars_to_number (buf
, n
);
6657 s3_atof (int type
, char *litP
, int *sizeP
)
6660 LITTLENUM_TYPE words
[s3_MAX_LITTLENUMS
];
6686 return _("bad call to MD_ATOF()");
6689 t
= atof_ieee (input_line_pointer
, type
, words
);
6691 input_line_pointer
= t
;
6694 if (target_big_endian
)
6696 for (i
= 0; i
< prec
; i
++)
6698 s3_md_number_to_chars (litP
, (valueT
) words
[i
], 2);
6704 for (i
= 0; i
< prec
; i
+= 2)
6706 s3_md_number_to_chars (litP
, (valueT
) words
[i
+ 1], 2);
6707 s3_md_number_to_chars (litP
+ 2, (valueT
) words
[i
], 2);
6716 s3_frag_check (fragS
* fragp ATTRIBUTE_UNUSED
)
6718 know (fragp
->insn_addr
<= s3_RELAX_PAD_BYTE
);
6722 s3_validate_fix (fixS
*fixP
)
6724 fixP
->fx_where
+= fixP
->fx_frag
->insn_addr
;
6728 s3_force_relocation (struct fix
*fixp
)
6732 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
6733 || fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
6734 || fixp
->fx_r_type
== BFD_RELOC_SCORE_JMP
6735 || fixp
->fx_r_type
== BFD_RELOC_SCORE_BRANCH
6736 || fixp
->fx_r_type
== BFD_RELOC_SCORE16_JMP
6737 || fixp
->fx_r_type
== BFD_RELOC_SCORE16_BRANCH
6738 || fixp
->fx_r_type
== BFD_RELOC_SCORE_BCMP
)
6746 s3_fix_adjustable (fixS
* fixP
)
6748 if (fixP
->fx_addsy
== NULL
)
6752 else if (OUTPUT_FLAVOR
== bfd_target_elf_flavour
6753 && (S_IS_EXTERNAL (fixP
->fx_addsy
) || S_IS_WEAK (fixP
->fx_addsy
)))
6757 else if (fixP
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
6758 || fixP
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
6759 || fixP
->fx_r_type
== BFD_RELOC_SCORE_JMP
6760 || fixP
->fx_r_type
== BFD_RELOC_SCORE16_JMP
)
6769 s3_elf_final_processing (void)
6771 unsigned long val
= 0;
6774 val
= E_SCORE_MACH_SCORE3
;
6776 val
= E_SCORE_MACH_SCORE7
;
6778 elf_elfheader (stdoutput
)->e_machine
= EM_SCORE
;
6779 elf_elfheader (stdoutput
)->e_flags
&= ~EF_SCORE_MACH
;
6780 elf_elfheader (stdoutput
)->e_flags
|= val
;
6782 if (s3_fix_data_dependency
== 1)
6784 elf_elfheader (stdoutput
)->e_flags
|= EF_SCORE_FIXDEP
;
6786 if (s3_score_pic
== s3_PIC
)
6788 elf_elfheader (stdoutput
)->e_flags
|= EF_SCORE_PIC
;
6793 s3_judge_size_before_relax (fragS
* fragp
, asection
*sec
)
6797 if (s3_score_pic
== s3_NO_PIC
)
6798 change
= s3_nopic_need_relax (fragp
->fr_symbol
, 0);
6800 change
= s3_pic_need_relax (fragp
->fr_symbol
, sec
);
6804 /* Only at the first time determining whether s3_GP instruction relax should be done,
6805 return the difference between instruction size and instruction relax size. */
6806 if (fragp
->fr_opcode
== NULL
)
6808 fragp
->fr_fix
= s3_RELAX_NEW (fragp
->fr_subtype
);
6809 fragp
->fr_opcode
= fragp
->fr_literal
+ s3_RELAX_RELOC1 (fragp
->fr_subtype
);
6810 return s3_RELAX_NEW (fragp
->fr_subtype
) - s3_RELAX_OLD (fragp
->fr_subtype
);
6818 s3_estimate_size_before_relax (fragS
* fragp
, asection
* sec ATTRIBUTE_UNUSED
)
6820 if ((s3_RELAX_TYPE (fragp
->fr_subtype
) == Insn_GP
)
6821 || (s3_RELAX_TYPE (fragp
->fr_subtype
) == Insn_PIC
))
6822 return s3_judge_size_before_relax (fragp
, sec
);
6828 s3_relax_branch_inst32 (fragS
* fragp
)
6830 fragp
->fr_opcode
= NULL
;
6835 s3_relax_branch_inst16 (fragS
* fragp
)
6837 int relaxable_p
= 0;
6838 int frag_addr
= fragp
->fr_address
+ fragp
->insn_addr
;
6839 addressT symbol_address
= 0;
6843 unsigned long inst_value
;
6845 relaxable_p
= s3_RELAX_OPT (fragp
->fr_subtype
);
6847 s
= fragp
->fr_symbol
;
6851 symbol_address
= (addressT
) symbol_get_frag (s
)->fr_address
;
6853 inst_value
= s3_md_chars_to_number (fragp
->fr_literal
, s3_INSN16_SIZE
);
6854 offset
= (inst_value
& 0x1ff) << 1;
6855 if ((offset
& 0x200) == 0x200)
6856 offset
|= 0xfffffc00;
6858 value
= offset
+ symbol_address
- frag_addr
;
6861 && (!((value
& 0xfffffe00) == 0 || (value
& 0xfffffe00) == 0xfffffe00))
6862 && fragp
->fr_fix
== 2
6863 && (S_IS_DEFINED (s
)
6865 && !S_IS_EXTERNAL (s
)))
6867 /* Relax branch 32 to branch 16. */
6868 fragp
->fr_opcode
= fragp
->fr_literal
+ s3_RELAX_RELOC1 (fragp
->fr_subtype
);
6877 s3_relax_cmpbranch_inst32 (fragS
* fragp
)
6879 int relaxable_p
= 0;
6883 long frag_addr
= fragp
->fr_address
+ fragp
->insn_addr
;
6884 long symbol_address
= 0;
6886 unsigned long inst_value
;
6888 relaxable_p
= s3_RELAX_OPT (fragp
->fr_subtype
);
6890 s
= fragp
->fr_symbol
;
6894 symbol_address
= (addressT
) symbol_get_frag (s
)->fr_address
;
6896 inst_value
= s3_md_chars_to_number (fragp
->fr_literal
, s3_INSN_SIZE
);
6897 offset
= (inst_value
& 0x1)
6898 | (((inst_value
>> 7) & 0x7) << 1)
6899 | (((inst_value
>> 21) & 0x1f) << 4);
6901 if ((offset
& 0x200) == 0x200)
6902 offset
|= 0xfffffe00;
6904 value
= offset
+ symbol_address
- frag_addr
;
6905 /* change the order of judging rule is because
6906 1.not defined symbol or common symbol or external symbol will change
6907 bcmp to cmp!+beq/bne ,here need to record fragp->fr_opcode
6908 2.if the flow is as before : it will results to recursive loop
6910 if (fragp
->fr_fix
== 6)
6912 /* Have already relaxed! Just return 0 to terminate the loop. */
6915 /* need to translate when extern or not defined or common symbol */
6916 else if ((relaxable_p
6917 && (!((value
& 0xfffffe00) == 0 || (value
& 0xfffffe00) == 0xfffffe00))
6918 && fragp
->fr_fix
== 4)
6919 || !S_IS_DEFINED (s
)
6921 ||S_IS_EXTERNAL (s
))
6923 fragp
->fr_opcode
= fragp
->fr_literal
+ s3_RELAX_RELOC1 (fragp
->fr_subtype
);
6929 /* Never relax. Modify fr_opcode to NULL to verify it's value in
6931 fragp
->fr_opcode
= NULL
;
6938 s3_relax_other_inst32 (fragS
* fragp
)
6940 int relaxable_p
= s3_RELAX_OPT (fragp
->fr_subtype
);
6943 && fragp
->fr_fix
== 4)
6945 fragp
->fr_opcode
= fragp
->fr_literal
+ s3_RELAX_RELOC1 (fragp
->fr_subtype
);
6954 s3_relax_gp_and_pic_inst32 (void)
6956 /* md_estimate_size_before_relax has already relaxed s3_GP and s3_PIC
6957 instructions. We don't change relax size here. */
6962 s3_relax_frag (asection
* sec ATTRIBUTE_UNUSED
, fragS
* fragp
, long stretch ATTRIBUTE_UNUSED
)
6965 int adjust_align_p
= 0;
6967 /* If the instruction address is odd, make it half word align first. */
6968 if ((fragp
->fr_address
) % 2 != 0)
6970 if ((fragp
->fr_address
+ fragp
->insn_addr
) % 2 != 0)
6972 fragp
->insn_addr
= 1;
6978 switch (s3_RELAX_TYPE (fragp
->fr_subtype
))
6981 grows
+= s3_relax_branch_inst32 (fragp
);
6985 grows
+= s3_relax_branch_inst16 (fragp
);
6989 grows
+= s3_relax_cmpbranch_inst32 (fragp
);
6994 grows
+= s3_relax_gp_and_pic_inst32 ();
6998 grows
+= s3_relax_other_inst32 (fragp
);
7003 if (adjust_align_p
&& fragp
->insn_addr
)
7005 fragp
->fr_fix
+= fragp
->insn_addr
;
7012 s3_convert_frag (bfd
* abfd ATTRIBUTE_UNUSED
, segT sec ATTRIBUTE_UNUSED
, fragS
* fragp
)
7019 r_old
= s3_RELAX_OLD (fragp
->fr_subtype
);
7020 r_new
= s3_RELAX_NEW (fragp
->fr_subtype
);
7022 /* fragp->fr_opcode indicates whether this frag should be relaxed. */
7023 if (fragp
->fr_opcode
== NULL
)
7025 memcpy (backup
, fragp
->fr_literal
, r_old
);
7026 fragp
->fr_fix
= r_old
;
7030 memcpy (backup
, fragp
->fr_literal
+ r_old
, r_new
);
7031 fragp
->fr_fix
= r_new
;
7034 fixp
= fragp
->tc_frag_data
.fixp
;
7035 while (fixp
&& fixp
->fx_frag
== fragp
&& fixp
->fx_where
< r_old
)
7037 if (fragp
->fr_opcode
)
7039 fixp
= fixp
->fx_next
;
7041 while (fixp
&& fixp
->fx_frag
== fragp
)
7043 if (fragp
->fr_opcode
)
7044 fixp
->fx_where
-= r_old
+ fragp
->insn_addr
;
7047 fixp
= fixp
->fx_next
;
7050 if (fragp
->insn_addr
)
7052 s3_md_number_to_chars (fragp
->fr_literal
, 0x0, fragp
->insn_addr
);
7054 memcpy (fragp
->fr_literal
+ fragp
->insn_addr
, backup
, fragp
->fr_fix
);
7055 fragp
->fr_fix
+= fragp
->insn_addr
;
7059 s3_pcrel_from (fixS
* fixP
)
7064 && (S_GET_SEGMENT (fixP
->fx_addsy
) == undefined_section
)
7065 && (fixP
->fx_subsy
== NULL
))
7071 retval
= fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
7078 s3_section_align (segT segment ATTRIBUTE_UNUSED
, valueT size
)
7080 int align
= bfd_get_section_alignment (stdoutput
, segment
);
7081 return ((size
+ (1 << align
) - 1) & -(1 << align
));
7085 s3_apply_fix (fixS
*fixP
, valueT
*valP
, segT seg
)
7087 offsetT value
= *valP
;
7090 unsigned short HI
, LO
;
7092 char *buf
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
7094 gas_assert (fixP
->fx_r_type
< BFD_RELOC_UNUSED
);
7095 if (fixP
->fx_addsy
== 0 && !fixP
->fx_pcrel
)
7097 if (fixP
->fx_r_type
!= BFD_RELOC_SCORE_DUMMY_HI16
)
7101 /* If this symbol is in a different section then we need to leave it for
7102 the linker to deal with. Unfortunately, md_pcrel_from can't tell,
7103 so we have to undo it's effects here. */
7106 if (fixP
->fx_addsy
!= NULL
7107 && S_IS_DEFINED (fixP
->fx_addsy
)
7108 && S_GET_SEGMENT (fixP
->fx_addsy
) != seg
)
7109 value
+= md_pcrel_from (fixP
);
7112 /* Remember value for emit_reloc. */
7113 fixP
->fx_addnumber
= value
;
7115 switch (fixP
->fx_r_type
)
7117 case BFD_RELOC_HI16_S
:
7118 if (fixP
->fx_done
) /* For la rd, imm32. */
7120 newval
= s3_md_chars_to_number (buf
, s3_INSN_SIZE
);
7121 HI
= (value
) >> 16; /* mul to 2, then take the hi 16 bit. */
7122 newval
|= (HI
& 0x3fff) << 1;
7123 newval
|= ((HI
>> 14) & 0x3) << 16;
7124 s3_md_number_to_chars (buf
, newval
, s3_INSN_SIZE
);
7127 case BFD_RELOC_LO16
:
7128 if (fixP
->fx_done
) /* For la rd, imm32. */
7130 newval
= s3_md_chars_to_number (buf
, s3_INSN_SIZE
);
7131 LO
= (value
) & 0xffff;
7132 newval
|= (LO
& 0x3fff) << 1; /* 16 bit: imm -> 14 bit in lo, 2 bit in hi. */
7133 newval
|= ((LO
>> 14) & 0x3) << 16;
7134 s3_md_number_to_chars (buf
, newval
, s3_INSN_SIZE
);
7137 case BFD_RELOC_SCORE_JMP
:
7139 content
= s3_md_chars_to_number (buf
, s3_INSN_SIZE
);
7140 value
= fixP
->fx_offset
;
7141 content
= (content
& ~0x3ff7ffe) | ((value
<< 1) & 0x3ff0000) | (value
& 0x7fff);
7142 s3_md_number_to_chars (buf
, content
, s3_INSN_SIZE
);
7146 case BFD_RELOC_SCORE_IMM30
:
7148 content
= s3_md_chars_to_number (buf
, s3_INSN48_SIZE
);
7149 value
= fixP
->fx_offset
;
7151 content
= (content
& ~0x7f7fff7f80LL
)
7152 | (((value
& 0xff) >> 0) << 7)
7153 | (((value
& 0x7fff00) >> 8) << 16)
7154 | (((value
& 0x3f800000) >> 23) << 32);
7155 s3_md_number_to_chars (buf
, content
, s3_INSN48_SIZE
);
7159 case BFD_RELOC_SCORE_IMM32
:
7161 content
= s3_md_chars_to_number (buf
, s3_INSN48_SIZE
);
7162 value
= fixP
->fx_offset
;
7163 content
= (content
& ~0x7f7fff7fe0LL
)
7164 | ((value
& 0x3ff) << 5)
7165 | (((value
>> 10) & 0x7fff) << 16)
7166 | (((value
>> 25) & 0x7f) << 32);
7167 s3_md_number_to_chars (buf
, content
, s3_INSN48_SIZE
);
7171 case BFD_RELOC_SCORE_BRANCH
:
7172 if ((S_GET_SEGMENT (fixP
->fx_addsy
) != seg
) || (fixP
->fx_addsy
!= NULL
&& S_IS_EXTERNAL (fixP
->fx_addsy
)))
7173 value
= fixP
->fx_offset
;
7177 content
= s3_md_chars_to_number (buf
, s3_INSN_SIZE
);
7179 /* Don't check c-bit. */
7180 if (fixP
->fx_frag
->fr_opcode
!= 0)
7182 if ((value
& 0xfffffe00) != 0 && (value
& 0xfffffe00) != 0xfffffe00)
7184 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7185 _(" branch relocation truncate (0x%x) [-2^9 ~ 2^9-1]"), (unsigned int) value
);
7188 content
= s3_md_chars_to_number (buf
, s3_INSN16_SIZE
);
7190 content
= (content
& 0xfe00) | ((value
>> 1) & 0x1ff);
7191 s3_md_number_to_chars (buf
, content
, s3_INSN16_SIZE
);
7192 fixP
->fx_r_type
= BFD_RELOC_SCORE16_BRANCH
;
7197 if ((value
& 0xfff80000) != 0 && (value
& 0xfff80000) != 0xfff80000)
7199 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7200 _(" branch relocation truncate (0x%x) [-2^19 ~ 2^19-1]"), (unsigned int) value
);
7203 content
= s3_md_chars_to_number (buf
, s3_INSN_SIZE
);
7204 content
&= 0xfc00fc01;
7205 content
= (content
& 0xfc00fc01) | (value
& 0x3fe) | ((value
<< 6) & 0x3ff0000);
7206 s3_md_number_to_chars (buf
, content
, s3_INSN_SIZE
);
7209 case BFD_RELOC_SCORE16_JMP
:
7210 content
= s3_md_chars_to_number (buf
, s3_INSN16_SIZE
);
7212 value
= fixP
->fx_offset
& 0xfff;
7213 content
= (content
& 0xfc01) | (value
& 0xffe);
7214 s3_md_number_to_chars (buf
, content
, s3_INSN16_SIZE
);
7216 case BFD_RELOC_SCORE16_BRANCH
:
7217 content
= s3_md_chars_to_number (buf
, s3_INSN_SIZE
);
7218 /* Don't check c-bit. */
7219 if (fixP
->fx_frag
->fr_opcode
!= 0)
7221 if ((S_GET_SEGMENT (fixP
->fx_addsy
) != seg
) ||
7222 (fixP
->fx_addsy
!= NULL
&& S_IS_EXTERNAL (fixP
->fx_addsy
)))
7223 value
= fixP
->fx_offset
;
7226 if ((value
& 0xfff80000) != 0 && (value
& 0xfff80000) != 0xfff80000)
7228 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7229 _(" branch relocation truncate (0x%x) [-2^19 ~ 2^19-1]"), (unsigned int) value
);
7232 content
= s3_md_chars_to_number (buf
, s3_INSN_SIZE
);
7233 content
= (content
& 0xfc00fc01) | (value
& 0x3fe) | ((value
<< 6) & 0x3ff0000);
7234 s3_md_number_to_chars (buf
, content
, s3_INSN_SIZE
);
7235 fixP
->fx_r_type
= BFD_RELOC_SCORE_BRANCH
;
7241 /* In different section. */
7242 if ((S_GET_SEGMENT (fixP
->fx_addsy
) != seg
) ||
7243 (fixP
->fx_addsy
!= NULL
&& S_IS_EXTERNAL (fixP
->fx_addsy
)))
7244 value
= fixP
->fx_offset
;
7248 if ((value
& 0xfffffe00) != 0 && (value
& 0xfffffe00) != 0xfffffe00)
7250 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7251 _(" branch relocation truncate (0x%x) [-2^9 ~ 2^9-1]"), (unsigned int) value
);
7255 content
= s3_md_chars_to_number (buf
, s3_INSN16_SIZE
);
7256 content
= (content
& 0xfe00) | ((value
>> 1) & 0x1ff);
7257 s3_md_number_to_chars (buf
, content
, s3_INSN16_SIZE
);
7263 case BFD_RELOC_SCORE_BCMP
:
7264 if (fixP
->fx_frag
->fr_opcode
!= 0)
7266 char *buf_ptr
= buf
;
7269 if ((S_GET_SEGMENT (fixP
->fx_addsy
) != seg
) || (fixP
->fx_addsy
!= NULL
&& S_IS_EXTERNAL (fixP
->fx_addsy
)))
7270 value
= fixP
->fx_offset
;
7275 bcmp -> cmp! and branch, so value -= 2. */
7278 if ((value
& 0xfff80000) != 0 && (value
& 0xfff80000) != 0xfff80000)
7280 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7281 _(" branch relocation truncate (0x%x) [-2^19 ~ 2^19-1]"), (unsigned int) value
);
7285 content
= s3_md_chars_to_number (buf_ptr
, s3_INSN_SIZE
);
7286 content
&= 0xfc00fc01;
7287 content
= (content
& 0xfc00fc01) | (value
& 0x3fe) | ((value
<< 6) & 0x3ff0000);
7288 s3_md_number_to_chars (buf_ptr
, content
, s3_INSN_SIZE
);
7289 /* change relocation type to BFD_RELOC_SCORE_BRANCH */
7290 fixP
->fx_r_type
= BFD_RELOC_SCORE_BRANCH
;
7291 fixP
->fx_where
+=2; /* first insn is cmp! , the second insn is beq/bne */
7296 if ((S_GET_SEGMENT (fixP
->fx_addsy
) != seg
) || (fixP
->fx_addsy
!= NULL
&& S_IS_EXTERNAL (fixP
->fx_addsy
)))
7297 value
= fixP
->fx_offset
;
7301 content
= s3_md_chars_to_number (buf
, s3_INSN_SIZE
);
7303 if ((value
& 0xfffffe00) != 0 && (value
& 0xfffffe00) != 0xfffffe00)
7305 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7306 _(" branch relocation truncate (0x%x) [-2^9 ~ 2^9-1]"), (unsigned int) value
);
7311 content
&= ~0x03e00381;
7314 | (((value
& 0xe) >> 1) << 7)
7315 | (((value
& 0x1f0) >> 4) << 21);
7317 s3_md_number_to_chars (buf
, content
, s3_INSN_SIZE
);
7322 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
7323 s3_md_number_to_chars (buf
, value
, 1);
7327 value
= fixP
->fx_offset
;
7328 s3_md_number_to_chars (buf
, value
, 1);
7334 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
7335 s3_md_number_to_chars (buf
, value
, 2);
7339 value
= fixP
->fx_offset
;
7340 s3_md_number_to_chars (buf
, value
, 2);
7346 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
7347 md_number_to_chars (buf
, value
, 4);
7351 value
= fixP
->fx_offset
;
7352 md_number_to_chars (buf
, value
, 4);
7356 case BFD_RELOC_VTABLE_INHERIT
:
7358 if (fixP
->fx_addsy
&& !S_IS_DEFINED (fixP
->fx_addsy
) && !S_IS_WEAK (fixP
->fx_addsy
))
7359 S_SET_WEAK (fixP
->fx_addsy
);
7361 case BFD_RELOC_VTABLE_ENTRY
:
7364 case BFD_RELOC_SCORE_GPREL15
:
7365 content
= s3_md_chars_to_number (buf
, s3_INSN_SIZE
);
7367 if ((fixP
->fx_frag
->fr_opcode
!= 0) && ((content
& 0xfc1c8000) != 0x94180000))
7368 fixP
->fx_r_type
= BFD_RELOC_NONE
;
7371 case BFD_RELOC_SCORE_GOT15
:
7372 case BFD_RELOC_SCORE_DUMMY_HI16
:
7373 case BFD_RELOC_SCORE_GOT_LO16
:
7374 case BFD_RELOC_SCORE_CALL15
:
7375 case BFD_RELOC_GPREL32
:
7377 case BFD_RELOC_NONE
:
7379 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("bad relocation fixup type (%d)"), fixP
->fx_r_type
);
7384 s3_gen_reloc (asection
* section ATTRIBUTE_UNUSED
, fixS
* fixp
)
7386 static arelent
*retval
[MAX_RELOC_EXPANSION
+ 1]; /* MAX_RELOC_EXPANSION equals 2. */
7388 bfd_reloc_code_real_type code
;
7391 reloc
= retval
[0] = XNEW (arelent
);
7394 reloc
->sym_ptr_ptr
= XNEW (asymbol
*);
7395 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
7396 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
7397 reloc
->addend
= fixp
->fx_offset
;
7399 /* If this is a variant frag, we may need to adjust the existing
7400 reloc and generate a new one. */
7401 if (fixp
->fx_frag
->fr_opcode
!= NULL
&& (fixp
->fx_r_type
== BFD_RELOC_SCORE_GPREL15
))
7403 /* Update instruction imm bit. */
7408 buf
= fixp
->fx_frag
->fr_literal
+ fixp
->fx_frag
->insn_addr
;
7409 newval
= s3_md_chars_to_number (buf
, s3_INSN_SIZE
);
7410 off
= fixp
->fx_offset
>> 16;
7411 newval
|= (off
& 0x3fff) << 1;
7412 newval
|= ((off
>> 14) & 0x3) << 16;
7413 s3_md_number_to_chars (buf
, newval
, s3_INSN_SIZE
);
7415 buf
+= s3_INSN_SIZE
;
7416 newval
= s3_md_chars_to_number (buf
, s3_INSN_SIZE
);
7417 off
= fixp
->fx_offset
& 0xffff;
7418 newval
|= ((off
& 0x3fff) << 1);
7419 newval
|= (((off
>> 14) & 0x3) << 16);
7420 s3_md_number_to_chars (buf
, newval
, s3_INSN_SIZE
);
7422 retval
[1] = XNEW (arelent
);
7424 retval
[1]->sym_ptr_ptr
= XNEW (asymbol
*);
7425 *retval
[1]->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
7426 retval
[1]->address
= (reloc
->address
+ s3_RELAX_RELOC2 (fixp
->fx_frag
->fr_subtype
));
7428 retval
[1]->addend
= 0;
7429 retval
[1]->howto
= bfd_reloc_type_lookup (stdoutput
, BFD_RELOC_LO16
);
7430 gas_assert (retval
[1]->howto
!= NULL
);
7432 fixp
->fx_r_type
= BFD_RELOC_HI16_S
;
7435 code
= fixp
->fx_r_type
;
7436 switch (fixp
->fx_r_type
)
7441 code
= BFD_RELOC_32_PCREL
;
7445 case BFD_RELOC_HI16_S
:
7446 case BFD_RELOC_LO16
:
7447 case BFD_RELOC_SCORE_JMP
:
7448 case BFD_RELOC_SCORE_BRANCH
:
7449 case BFD_RELOC_SCORE16_JMP
:
7450 case BFD_RELOC_SCORE16_BRANCH
:
7451 case BFD_RELOC_SCORE_BCMP
:
7452 case BFD_RELOC_VTABLE_ENTRY
:
7453 case BFD_RELOC_VTABLE_INHERIT
:
7454 case BFD_RELOC_SCORE_GPREL15
:
7455 case BFD_RELOC_SCORE_GOT15
:
7456 case BFD_RELOC_SCORE_DUMMY_HI16
:
7457 case BFD_RELOC_SCORE_GOT_LO16
:
7458 case BFD_RELOC_SCORE_CALL15
:
7459 case BFD_RELOC_GPREL32
:
7460 case BFD_RELOC_NONE
:
7461 case BFD_RELOC_SCORE_IMM30
:
7462 case BFD_RELOC_SCORE_IMM32
:
7463 code
= fixp
->fx_r_type
;
7466 type
= _("<unknown>");
7467 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
7468 _("cannot represent %s relocation in this object file format"), type
);
7472 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
7473 if (reloc
->howto
== NULL
)
7475 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
7476 _("cannot represent %s relocation in this object file format1"),
7477 bfd_get_reloc_code_name (code
));
7480 /* HACK: Since arm ELF uses Rel instead of Rela, encode the
7481 vtable entry to be used in the relocation's section offset. */
7482 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
7483 reloc
->address
= fixp
->fx_offset
;
7489 md_assemble (char *str
)
7497 /* We handle all bad expressions here, so that we can report the faulty
7498 instruction in the error message. */
7500 md_operand (expressionS
* exp
)
7508 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
7509 for use in the a.out file, and stores them in the array pointed to by buf.
7510 This knows about the endian-ness of the target machine and does
7511 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
7512 2 (short) and 4 (long) Floating numbers are put out as a series of
7513 LITTLENUMS (shorts, here at least). */
7515 md_number_to_chars (char *buf
, valueT val
, int n
)
7518 s3_number_to_chars (buf
, val
, n
);
7520 s7_number_to_chars (buf
, val
, n
);
7523 /* Turn a string in input_line_pointer into a floating point constant
7524 of type TYPE, and store the appropriate bytes in *LITP. The number
7525 of LITTLENUMS emitted is stored in *SIZEP. An error message is
7526 returned, or NULL on OK.
7528 Note that fp constants aren't represent in the normal way on the ARM.
7529 In big endian mode, things are as expected. However, in little endian
7530 mode fp constants are big-endian word-wise, and little-endian byte-wise
7531 within the words. For example, (double) 1.1 in big endian mode is
7532 the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
7533 the byte sequence 99 99 f1 3f 9a 99 99 99. */
7535 md_atof (int type
, char *litP
, int *sizeP
)
7538 return s3_atof (type
, litP
, sizeP
);
7540 return s7_atof (type
, litP
, sizeP
);
7544 score_frag_check (fragS
* fragp ATTRIBUTE_UNUSED
)
7547 s3_frag_check (fragp
);
7549 s7_frag_check (fragp
);
7552 /* Implementation of TC_VALIDATE_FIX.
7553 Called before md_apply_fix() and after md_convert_frag(). */
7555 score_validate_fix (fixS
*fixP
)
7558 s3_validate_fix (fixP
);
7560 s7_validate_fix (fixP
);
7564 score_force_relocation (struct fix
*fixp
)
7567 return s3_force_relocation (fixp
);
7569 return s7_force_relocation (fixp
);
7572 /* Implementation of md_frag_check.
7573 Called after md_convert_frag(). */
7575 score_fix_adjustable (fixS
* fixP
)
7578 return s3_fix_adjustable (fixP
);
7580 return s7_fix_adjustable (fixP
);
7584 score_elf_final_processing (void)
7587 s3_elf_final_processing ();
7589 s7_elf_final_processing ();
7592 /* In this function, we determine whether s3_GP instruction should do relaxation,
7593 for the label being against was known now.
7594 Doing this here but not in md_relax_frag() can induce iteration times
7595 in stage of doing relax. */
7597 md_estimate_size_before_relax (fragS
* fragp
, asection
* sec ATTRIBUTE_UNUSED
)
7600 return s3_estimate_size_before_relax (fragp
, sec
);
7602 return s7_estimate_size_before_relax (fragp
, sec
);
7606 score_relax_frag (asection
* sec ATTRIBUTE_UNUSED
, fragS
* fragp
, long stretch ATTRIBUTE_UNUSED
)
7609 return s3_relax_frag (sec
, fragp
, stretch
);
7611 return s7_relax_frag (sec
, fragp
, stretch
);
7615 md_convert_frag (bfd
* abfd ATTRIBUTE_UNUSED
, segT sec ATTRIBUTE_UNUSED
, fragS
* fragp
)
7618 return s3_convert_frag (abfd
, sec
, fragp
);
7620 return s7_convert_frag (abfd
, sec
, fragp
);
7624 md_pcrel_from (fixS
* fixP
)
7627 return s3_pcrel_from (fixP
);
7629 return s7_pcrel_from (fixP
);
7632 /* Round up a section size to the appropriate boundary. */
7634 md_section_align (segT segment ATTRIBUTE_UNUSED
, valueT size
)
7637 return s3_section_align (segment
, size
);
7639 return s7_section_align (segment
, size
);
7643 md_apply_fix (fixS
*fixP
, valueT
*valP
, segT seg
)
7646 return s3_apply_fix (fixP
, valP
, seg
);
7648 return s7_apply_fix (fixP
, valP
, seg
);
7651 /* Translate internal representation of relocation info to BFD target format. */
7653 tc_gen_reloc (asection
* section ATTRIBUTE_UNUSED
, fixS
* fixp
)
7656 return s3_gen_reloc (section
, fixp
);
7658 return s7_gen_reloc (section
, fixp
);
7669 score_set_mach (const char *arg
)
7671 if (strcmp (arg
, MARCH_SCORE3
) == 0)
7677 else if (strcmp (arg
, MARCH_SCORE7
) == 0)
7682 s7_university_version
= 0;
7683 s7_vector_size
= s7_SCORE7_PIPELINE
;
7685 else if (strcmp (arg
, MARCH_SCORE5
) == 0)
7690 s7_university_version
= 0;
7691 s7_vector_size
= s7_SCORE5_PIPELINE
;
7693 else if (strcmp (arg
, MARCH_SCORE5U
) == 0)
7698 s7_university_version
= 1;
7699 s7_vector_size
= s7_SCORE5_PIPELINE
;
7703 as_bad (_("unknown architecture `%s'\n"), arg
);
7708 md_parse_option (int c
, const char *arg
)
7714 target_big_endian
= 1;
7719 target_big_endian
= 0;
7723 s3_fix_data_dependency
= 1;
7724 s7_fix_data_dependency
= 1;
7727 s3_warn_fix_data_dependency
= 0;
7728 s7_warn_fix_data_dependency
= 0;
7733 s7_university_version
= 0;
7734 s7_vector_size
= s7_SCORE5_PIPELINE
;
7736 case OPTION_SCORE5U
:
7739 s7_university_version
= 1;
7740 s7_vector_size
= s7_SCORE5_PIPELINE
;
7746 s7_university_version
= 0;
7747 s7_vector_size
= s7_SCORE7_PIPELINE
;
7759 s3_g_switch_value
= atoi (arg
);
7760 s7_g_switch_value
= atoi (arg
);
7766 case OPTION_SCORE_VERSION
:
7767 printf (_("Sunplus-v2-0-0-20060510\n"));
7770 s3_score_pic
= s3_NO_PIC
; /* Score3 doesn't support PIC now. */
7771 s7_score_pic
= s7_PIC
;
7772 s3_g_switch_value
= 0; /* Must set -G num as 0 to generate s3_PIC code. */
7773 s7_g_switch_value
= 0; /* Must set -G num as 0 to generate s7_PIC code. */
7776 score_set_mach (arg
);
7785 md_show_usage (FILE * fp
)
7787 fprintf (fp
, _(" Score-specific assembler options:\n"));
7790 -EB\t\tassemble code for a big-endian cpu\n"));
7795 -EL\t\tassemble code for a little-endian cpu\n"));
7799 -FIXDD\t\tfix data dependencies\n"));
7801 -NWARN\t\tdo not print warning message when fixing data dependencies\n"));
7803 -SCORE5\t\tassemble code for target SCORE5\n"));
7805 -SCORE5U\tassemble code for target SCORE5U\n"));
7807 -SCORE7\t\tassemble code for target SCORE7 [default]\n"));
7809 -SCORE3\t\tassemble code for target SCORE3\n"));
7811 -march=score7\tassemble code for target SCORE7 [default]\n"));
7813 -march=score3\tassemble code for target SCORE3\n"));
7815 -USE_R1\t\tassemble code for no warning message when using temp register r1\n"));
7817 -KPIC\t\tgenerate PIC\n"));
7819 -O0\t\tdo not perform any optimizations\n"));
7821 -G gpnum\tassemble code for setting gpsize, default is 8 bytes\n"));
7823 -V \t\tSunplus release version\n"));