1 /* tc-score.c -- Assembler for Score
2 Copyright 2006, 2007, 2008, 2009 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
* expr
);
62 static void s3_begin (void);
63 static void s3_number_to_chars (char *buf
, valueT val
, int n
);
64 static 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
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 spectial instruction. */
358 static const struct s3_data_dependency s3_data_dependency_table
[] =
360 /* Status regiser. */
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;
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
)
1190 save_in
= input_line_pointer
;
1191 input_line_pointer
= *str
;
1192 s3_in_my_get_expression
= 1;
1193 seg
= expression (ep
);
1194 s3_in_my_get_expression
= 0;
1196 if (ep
->X_op
== O_illegal
)
1198 *str
= input_line_pointer
;
1199 input_line_pointer
= save_in
;
1200 s3_inst
.error
= _("illegal expression");
1201 return (int) s3_FAIL
;
1203 /* Get rid of any bignums now, so that we don't generate an error for which
1204 we can't establish a line number later on. Big numbers are never valid
1205 in instructions, which is where this routine is always called. */
1206 if (ep
->X_op
== O_big
1207 || (ep
->X_add_symbol
1208 && (s3_walk_no_bignums (ep
->X_add_symbol
)
1209 || (ep
->X_op_symbol
&& s3_walk_no_bignums (ep
->X_op_symbol
)))))
1211 s3_inst
.error
= _("invalid constant");
1212 *str
= input_line_pointer
;
1213 input_line_pointer
= save_in
;
1214 return (int) s3_FAIL
;
1217 if ((ep
->X_add_symbol
!= NULL
)
1218 && (s3_inst
.type
!= PC_DISP19div2
)
1219 && (s3_inst
.type
!= PC_DISP8div2
)
1220 && (s3_inst
.type
!= PC_DISP24div2
)
1221 && (s3_inst
.type
!= PC_DISP11div2
)
1222 && (s3_inst
.type
!= Insn_Type_SYN
)
1223 && (s3_inst
.type
!= Rd_rvalueRs_SI15
)
1224 && (s3_inst
.type
!= Rd_lvalueRs_SI15
)
1225 && (s3_inst
.type
!= Insn_internal
)
1226 && (s3_inst
.type
!= Rd_I30
)
1227 && (s3_inst
.type
!= Rd_I32
)
1228 && (s3_inst
.type
!= Insn_BCMP
))
1230 s3_inst
.error
= s3_BAD_ARGS
;
1231 *str
= input_line_pointer
;
1232 input_line_pointer
= save_in
;
1233 return (int) s3_FAIL
;
1236 *str
= input_line_pointer
;
1237 input_line_pointer
= save_in
;
1241 /* Check if an immediate is valid. If so, convert it to the right format. */
1242 static bfd_signed_vma
1243 s3_validate_immediate (bfd_signed_vma val
, unsigned int data_type
, int hex_p
)
1249 bfd_signed_vma val_hi
= ((val
& 0xffff0000) >> 16);
1251 if (s3_score_df_range
[data_type
].range
[0] <= val_hi
1252 && val_hi
<= s3_score_df_range
[data_type
].range
[1])
1259 bfd_signed_vma val_lo
= (val
& 0xffff);
1261 if (s3_score_df_range
[data_type
].range
[0] <= val_lo
1262 && val_lo
<= s3_score_df_range
[data_type
].range
[1])
1270 if (!(val
>= -0x2000 && val
<= 0x3fff))
1272 return (int) s3_FAIL
;
1277 if (!(val
>= -8192 && val
<= 8191))
1279 return (int) s3_FAIL
;
1289 if (!(val
>= -0x7fff && val
<= 0xffff && val
!= 0x8000))
1291 return (int) s3_FAIL
;
1296 if (!(val
>= -32767 && val
<= 32768))
1298 return (int) s3_FAIL
;
1306 case _IMM5_MULTI_LOAD
:
1307 if (val
>= 2 && val
<= 32)
1317 return (int) s3_FAIL
;
1322 if (val
>= 0 && val
<= 0xffffffff)
1328 return (int) s3_FAIL
;
1332 if (data_type
== _SIMM14_NEG
|| data_type
== _IMM16_NEG
)
1335 if (s3_score_df_range
[data_type
].range
[0] <= val
1336 && val
<= s3_score_df_range
[data_type
].range
[1])
1342 return (int) s3_FAIL
;
1346 s3_data_op2 (char **str
, int shift
, enum score_data_type data_type
)
1348 bfd_signed_vma value
;
1349 char data_exp
[s3_MAX_LITERAL_POOL_SIZE
];
1354 s3_skip_whitespace (*str
);
1355 s3_inst
.error
= NULL
;
1358 /* Set hex_p to zero. */
1361 while ((*dataptr
!= '\0') && (*dataptr
!= '|') && (cnt
<= s3_MAX_LITERAL_POOL_SIZE
)) /* 0x7c = ='|' */
1363 data_exp
[cnt
] = *dataptr
;
1368 data_exp
[cnt
] = '\0';
1369 pp
= (char *)&data_exp
;
1371 if (*dataptr
== '|') /* process PCE */
1373 if (s3_my_get_expression (&s3_inst
.reloc
.exp
, &pp
) == (int) s3_FAIL
)
1374 return (int) s3_FAIL
;
1375 s3_end_of_line (pp
);
1376 if (s3_inst
.error
!= 0)
1377 return (int) s3_FAIL
; /* to ouptut_inst to printf out the error */
1380 else /* process 16 bit */
1382 if (s3_my_get_expression (&s3_inst
.reloc
.exp
, str
) == (int) s3_FAIL
)
1384 return (int) s3_FAIL
;
1387 dataptr
= (char *)data_exp
;
1388 for (; *dataptr
!= '\0'; dataptr
++)
1390 *dataptr
= TOLOWER (*dataptr
);
1391 if (*dataptr
== '!' || *dataptr
== ' ')
1394 dataptr
= (char *)data_exp
;
1396 if ((dataptr
!= NULL
)
1397 && (((strstr (dataptr
, "0x")) != NULL
)
1398 || ((strstr (dataptr
, "0X")) != NULL
)))
1401 if ((data_type
!= _SIMM16_LA
)
1402 && (data_type
!= _VALUE_HI16
)
1403 && (data_type
!= _VALUE_LO16
)
1404 && (data_type
!= _IMM16
)
1405 && (data_type
!= _IMM15
)
1406 && (data_type
!= _IMM14
)
1407 && (data_type
!= _IMM4
)
1408 && (data_type
!= _IMM5
)
1409 && (data_type
!= _IMM5_MULTI_LOAD
)
1410 && (data_type
!= _IMM11
)
1411 && (data_type
!= _IMM8
)
1412 && (data_type
!= _IMM5_RSHIFT_1
)
1413 && (data_type
!= _IMM5_RSHIFT_2
)
1414 && (data_type
!= _SIMM14
)
1415 && (data_type
!= _SIMM14_NEG
)
1416 && (data_type
!= _SIMM16_NEG
)
1417 && (data_type
!= _IMM10_RSHIFT_2
)
1418 && (data_type
!= _GP_IMM15
)
1419 && (data_type
!= _SIMM5
)
1420 && (data_type
!= _SIMM6
)
1421 && (data_type
!= _IMM32
)
1422 && (data_type
!= _SIMM32
))
1428 if ((s3_inst
.reloc
.exp
.X_add_number
== 0)
1429 && (s3_inst
.type
!= Insn_Type_SYN
)
1430 && (s3_inst
.type
!= Rd_rvalueRs_SI15
)
1431 && (s3_inst
.type
!= Rd_lvalueRs_SI15
)
1432 && (s3_inst
.type
!= Insn_internal
)
1433 && (((*dataptr
>= 'a') && (*dataptr
<= 'z'))
1434 || ((*dataptr
== '0') && (*(dataptr
+ 1) == 'x') && (*(dataptr
+ 2) != '0'))
1435 || ((*dataptr
== '+') && (*(dataptr
+ 1) != '0'))
1436 || ((*dataptr
== '-') && (*(dataptr
+ 1) != '0'))))
1438 s3_inst
.error
= s3_BAD_ARGS
;
1439 return (int) s3_FAIL
;
1443 if ((s3_inst
.reloc
.exp
.X_add_symbol
)
1444 && ((data_type
== _SIMM16
)
1445 || (data_type
== _SIMM16_NEG
)
1446 || (data_type
== _IMM16_NEG
)
1447 || (data_type
== _SIMM14
)
1448 || (data_type
== _SIMM14_NEG
)
1449 || (data_type
== _IMM5
)
1450 || (data_type
== _IMM5_MULTI_LOAD
)
1451 || (data_type
== _IMM11
)
1452 || (data_type
== _IMM14
)
1453 || (data_type
== _IMM20
)
1454 || (data_type
== _IMM16
)
1455 || (data_type
== _IMM15
)
1456 || (data_type
== _IMM4
)))
1458 s3_inst
.error
= s3_BAD_ARGS
;
1459 return (int) s3_FAIL
;
1462 if (s3_inst
.reloc
.exp
.X_add_symbol
)
1467 return (int) s3_FAIL
;
1469 s3_inst
.reloc
.type
= BFD_RELOC_HI16_S
;
1470 s3_inst
.reloc
.pc_rel
= 0;
1473 s3_inst
.reloc
.type
= BFD_RELOC_LO16
;
1474 s3_inst
.reloc
.pc_rel
= 0;
1477 s3_inst
.reloc
.type
= BFD_RELOC_SCORE_GPREL15
;
1478 s3_inst
.reloc
.pc_rel
= 0;
1481 case _IMM16_LO16_pic
:
1482 s3_inst
.reloc
.type
= BFD_RELOC_SCORE_GOT_LO16
;
1483 s3_inst
.reloc
.pc_rel
= 0;
1486 s3_inst
.reloc
.type
= BFD_RELOC_32
;
1487 s3_inst
.reloc
.pc_rel
= 0;
1493 if (data_type
== _IMM16_pic
)
1495 s3_inst
.reloc
.type
= BFD_RELOC_SCORE_DUMMY_HI16
;
1496 s3_inst
.reloc
.pc_rel
= 0;
1499 if (data_type
== _SIMM16_LA
&& s3_inst
.reloc
.exp
.X_unsigned
== 1)
1501 value
= s3_validate_immediate (s3_inst
.reloc
.exp
.X_add_number
, _SIMM16_LA_POS
, hex_p
);
1502 if (value
== (int) s3_FAIL
) /* for advance to check if this is ldis */
1503 if ((s3_inst
.reloc
.exp
.X_add_number
& 0xffff) == 0)
1505 s3_inst
.instruction
|= 0x8000000;
1506 s3_inst
.instruction
|= ((s3_inst
.reloc
.exp
.X_add_number
>> 16) << 1) & 0x1fffe;
1512 value
= s3_validate_immediate (s3_inst
.reloc
.exp
.X_add_number
, data_type
, hex_p
);
1515 if (value
== (int) s3_FAIL
)
1517 if (data_type
== _IMM32
)
1519 sprintf (s3_err_msg
,
1520 _("invalid constant: %d bit expression not in range %u..%u"),
1521 s3_score_df_range
[data_type
].bits
,
1522 0, (unsigned)0xffffffff);
1524 else if (data_type
== _IMM5_MULTI_LOAD
)
1526 sprintf (s3_err_msg
,
1527 _("invalid constant: %d bit expression not in range %u..%u"),
1530 else if ((data_type
!= _SIMM14_NEG
) && (data_type
!= _SIMM16_NEG
) && (data_type
!= _IMM16_NEG
))
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
[0], s3_score_df_range
[data_type
].range
[1]);
1539 sprintf (s3_err_msg
,
1540 _("invalid constant: %d bit expression not in range %d..%d"),
1541 s3_score_df_range
[data_type
].bits
,
1542 -s3_score_df_range
[data_type
].range
[1], -s3_score_df_range
[data_type
].range
[0]);
1545 s3_inst
.error
= s3_err_msg
;
1546 return (int) s3_FAIL
;
1549 if (((s3_score_df_range
[data_type
].range
[0] != 0) || (data_type
== _IMM5_RANGE_8_31
))
1550 && data_type
!= _IMM5_MULTI_LOAD
)
1552 value
&= (1 << s3_score_df_range
[data_type
].bits
) - 1;
1555 s3_inst
.instruction
|= value
<< shift
;
1558 if ((s3_inst
.instruction
& 0x3e000000) == 0x30000000)
1560 if ((((s3_inst
.instruction
>> 20) & 0x1F) != 0)
1561 && (((s3_inst
.instruction
>> 20) & 0x1F) != 1)
1562 && (((s3_inst
.instruction
>> 20) & 0x1F) != 2)
1563 && (((s3_inst
.instruction
>> 20) & 0x1F) != 0x10))
1565 s3_inst
.error
= _("invalid constant: bit expression not defined");
1566 return (int) s3_FAIL
;
1573 /* Handle addi/addi.c/addis.c/cmpi.c/addis.c/ldi. */
1575 s3_do_rdsi16 (char *str
)
1577 s3_skip_whitespace (str
);
1579 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
1580 || s3_skip_past_comma (&str
) == (int) s3_FAIL
1581 || s3_data_op2 (&str
, 1, _SIMM16
) == (int) s3_FAIL
1582 || s3_end_of_line (str
) == (int) s3_FAIL
)
1585 /* ldi.->ldiu! only for imm5 */
1586 if ((s3_inst
.instruction
& 0x20c0000) == 0x20c0000)
1588 if ((s3_inst
.instruction
& 0x1ffc0) != 0)
1590 s3_inst
.relax_inst
= 0x8000;
1594 s3_inst
.relax_inst
|= (s3_inst
.instruction
>> 1) & 0x1f;
1595 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>> 20)& 0x1f) <<5);
1596 s3_inst
.relax_size
= 2;
1600 else if ((s3_inst
.instruction
& 0x02040001) == 0x02040001)
1602 /* imm <=0x3f (5 bit<<1)*/
1603 if (((s3_inst
.instruction
& 0x1ffe0)==0)||(((s3_inst
.instruction
& 0x1ffe0) == 0x1ffe0)&&(s3_inst
.instruction
& 0x003e) !=0))
1605 s3_inst
.relax_inst
|= (s3_inst
.instruction
>> 1) & 0x1f;
1606 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>> 20) & 0x1f) << 5);
1607 s3_inst
.relax_size
= 2;
1611 s3_inst
.relax_inst
=0x8000;
1616 else if (((s3_inst
.instruction
& 0x2000000) == 0x02000000)&& (s3_inst
.relax_inst
!=0x8000))
1618 /* rd : 0-16 ; imm <=0x7f (6 bit<<1)*/
1619 if ((((s3_inst
.instruction
>> 20) & 0x10) != 0x10) &&
1620 (((s3_inst
.instruction
& 0x1ffc0)==0)||(((s3_inst
.instruction
& 0x1ffc0) == 0x1ffc0)&&(s3_inst
.instruction
& 0x007e) !=0)))
1622 s3_inst
.relax_inst
|= (s3_inst
.instruction
>> 1) & 0x3f;
1623 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>> 20) & 0xf) << 6);
1624 s3_inst
.relax_size
= 2;
1628 s3_inst
.relax_inst
=0x8000;
1633 else if (((s3_inst
.instruction
>> 20) & 0x10) == 0x10)
1635 s3_inst
.relax_inst
= 0x8000;
1640 s3_do_ldis (char *str
)
1642 s3_skip_whitespace (str
);
1644 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
1645 || s3_skip_past_comma (&str
) == (int) s3_FAIL
1646 || s3_data_op2 (&str
, 1, _IMM16
) == (int) s3_FAIL
1647 || s3_end_of_line (str
) == (int) s3_FAIL
)
1651 /* Handle subi/subi.c. */
1653 s3_do_sub_rdsi16 (char *str
)
1655 s3_skip_whitespace (str
);
1657 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) != (int) s3_FAIL
1658 && s3_skip_past_comma (&str
) != (int) s3_FAIL
1659 && s3_data_op2 (&str
, 1, _SIMM16_NEG
) != (int) s3_FAIL
)
1660 s3_end_of_line (str
);
1663 /* Handle subis/subis.c. */
1665 s3_do_sub_rdi16 (char *str
)
1667 s3_skip_whitespace (str
);
1669 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) != (int) s3_FAIL
1670 && s3_skip_past_comma (&str
) != (int) s3_FAIL
1671 && s3_data_op2 (&str
, 1, _IMM16_NEG
) != (int) s3_FAIL
)
1672 s3_end_of_line (str
);
1675 /* Handle addri/addri.c. */
1677 s3_do_rdrssi14 (char *str
) /* -(2^13)~((2^13)-1) */
1679 s3_skip_whitespace (str
);
1681 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) != (int) s3_FAIL
1682 && s3_skip_past_comma (&str
) != (int) s3_FAIL
1683 && s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) != (int) s3_FAIL
1684 && s3_skip_past_comma (&str
) != (int) s3_FAIL
)
1685 s3_data_op2 (&str
, 1, _SIMM14
);
1688 /* Handle subri.c/subri. */
1690 s3_do_sub_rdrssi14 (char *str
) /* -(2^13)~((2^13)-1) */
1692 s3_skip_whitespace (str
);
1694 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) != (int) s3_FAIL
1695 && s3_skip_past_comma (&str
) != (int) s3_FAIL
1696 && s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) != (int) s3_FAIL
1697 && s3_skip_past_comma (&str
) != (int) s3_FAIL
1698 && s3_data_op2 (&str
, 1, _SIMM14_NEG
) != (int) s3_FAIL
)
1699 s3_end_of_line (str
);
1702 /* Handle bitclr.c/bitset.c/bittgl.c/slli.c/srai.c/srli.c/roli.c/rori.c/rolic.c.
1705 s3_do_rdrsi5 (char *str
)
1707 s3_skip_whitespace (str
);
1709 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
1710 || s3_skip_past_comma (&str
) == (int) s3_FAIL
1711 || s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
1712 || s3_skip_past_comma (&str
) == (int) s3_FAIL
1713 || s3_data_op2 (&str
, 10, _IMM5
) == (int) s3_FAIL
1714 || s3_end_of_line (str
) == (int) s3_FAIL
)
1717 if ((((s3_inst
.instruction
>> 20) & 0x1f) == ((s3_inst
.instruction
>> 15) & 0x1f))
1718 && (s3_inst
.relax_inst
!= 0x8000) && (((s3_inst
.instruction
>> 15) & 0x10) == 0))
1720 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>> 10) & 0x1f) ) | (((s3_inst
.instruction
>> 15) & 0xf) << 5);
1721 s3_inst
.relax_size
= 2;
1724 s3_inst
.relax_inst
= 0x8000;
1727 /* Handle andri/orri/andri.c/orri.c.
1730 s3_do_rdrsi14 (char *str
)
1732 s3_skip_whitespace (str
);
1734 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) != (int) s3_FAIL
1735 && s3_skip_past_comma (&str
) != (int) s3_FAIL
1736 && s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) != (int) s3_FAIL
1737 && s3_skip_past_comma (&str
) != (int) s3_FAIL
1738 && s3_data_op2 (&str
, 1, _IMM14
) != (int) s3_FAIL
)
1739 s3_end_of_line (str
);
1742 /* Handle bittst.c. */
1744 s3_do_xrsi5 (char *str
)
1746 s3_skip_whitespace (str
);
1748 if (s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
1749 || s3_skip_past_comma (&str
) == (int) s3_FAIL
1750 || s3_data_op2 (&str
, 10, _IMM5
) == (int) s3_FAIL
1751 || s3_end_of_line (str
) == (int) s3_FAIL
)
1754 if ((s3_inst
.relax_inst
!= 0x8000) && (((s3_inst
.instruction
>> 15) & 0x10) == 0))
1756 s3_inst
.relax_inst
|= ((s3_inst
.instruction
>> 10) & 0x1f) | (((s3_inst
.instruction
>> 15) & 0xf) << 5);
1757 s3_inst
.relax_size
= 2;
1760 s3_inst
.relax_inst
= 0x8000;
1763 /* Handle addis/andi/ori/andis/oris/ldis. */
1765 s3_do_rdi16 (char *str
)
1767 s3_skip_whitespace (str
);
1769 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
1770 || s3_skip_past_comma (&str
) == (int) s3_FAIL
1771 || s3_data_op2 (&str
, 1, _IMM16
) == (int) s3_FAIL
1772 || s3_end_of_line (str
) == (int) s3_FAIL
)
1776 if ((s3_inst
.instruction
& 0x3e0e0000) == 0x0a0c0000)
1778 /* rd : 0-16 ;imm =0 -> can transform to addi!*/
1779 if ((((s3_inst
.instruction
>> 20) & 0x10) != 0x10) && ((s3_inst
.instruction
& 0x1ffff)==0))
1781 s3_inst
.relax_inst
=0x5400; /* ldiu! */
1782 s3_inst
.relax_inst
|= (s3_inst
.instruction
>> 1) & 0x1f;
1783 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>> 20) & 0xf) << 5);
1784 s3_inst
.relax_size
= 2;
1788 s3_inst
.relax_inst
=0x8000;
1794 else if ((s3_inst
.instruction
& 0x3e0e0001) == 0x0a000000)
1796 /* rd : 0-16 ;imm =0 -> can transform to addi!*/
1797 if ((((s3_inst
.instruction
>> 20) & 0x10) != 0x10) && ((s3_inst
.instruction
& 0x1ffff)==0))
1799 s3_inst
.relax_inst
=0x5c00; /* addi! */
1800 s3_inst
.relax_inst
|= (s3_inst
.instruction
>> 1) & 0x3f;
1801 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>> 20) & 0xf) << 6);
1802 s3_inst
.relax_size
= 2;
1806 s3_inst
.relax_inst
=0x8000;
1813 s3_do_macro_rdi32hi (char *str
)
1815 s3_skip_whitespace (str
);
1817 /* Do not handle s3_end_of_line(). */
1818 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) != (int) s3_FAIL
1819 && s3_skip_past_comma (&str
) != (int) s3_FAIL
)
1820 s3_data_op2 (&str
, 1, _VALUE_HI16
);
1824 s3_do_macro_rdi32lo (char *str
)
1826 s3_skip_whitespace (str
);
1828 /* Do not handle s3_end_of_line(). */
1829 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) != (int) s3_FAIL
1830 && s3_skip_past_comma (&str
) != (int) s3_FAIL
)
1831 s3_data_op2 (&str
, 1, _VALUE_LO16
);
1834 /* Handle ldis_pic. */
1836 s3_do_rdi16_pic (char *str
)
1838 s3_skip_whitespace (str
);
1840 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) != (int) s3_FAIL
1841 && s3_skip_past_comma (&str
) != (int) s3_FAIL
1842 && s3_data_op2 (&str
, 1, _IMM16_pic
) != (int) s3_FAIL
)
1843 s3_end_of_line (str
);
1846 /* Handle addi_s_pic to generate R_SCORE_GOT_LO16 . */
1848 s3_do_addi_s_pic (char *str
)
1850 s3_skip_whitespace (str
);
1852 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) != (int) s3_FAIL
1853 && s3_skip_past_comma (&str
) != (int) s3_FAIL
1854 && s3_data_op2 (&str
, 1, _SIMM16_pic
) != (int) s3_FAIL
)
1855 s3_end_of_line (str
);
1858 /* Handle addi_u_pic to generate R_SCORE_GOT_LO16 . */
1860 s3_do_addi_u_pic (char *str
)
1862 s3_skip_whitespace (str
);
1864 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) != (int) s3_FAIL
1865 && s3_skip_past_comma (&str
) != (int) s3_FAIL
1866 && s3_data_op2 (&str
, 1, _IMM16_LO16_pic
) != (int) s3_FAIL
)
1867 s3_end_of_line (str
);
1870 /* Handle mfceh/mfcel/mtceh/mtchl. */
1872 s3_do_rd (char *str
)
1874 s3_skip_whitespace (str
);
1876 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) != (int) s3_FAIL
)
1877 s3_end_of_line (str
);
1880 /* Handle br{cond},cmpzteq.c ,cmpztmi.c ,cmpz.c */
1882 s3_do_rs (char *str
)
1884 s3_skip_whitespace (str
);
1886 if (s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
1887 || s3_end_of_line (str
) == (int) s3_FAIL
)
1890 if ((s3_inst
.relax_inst
!= 0x8000) )
1892 s3_inst
.relax_inst
|= ((s3_inst
.instruction
>> 15) &0x1f);
1893 s3_inst
.relax_size
= 2;
1896 s3_inst
.relax_inst
= 0x8000;
1900 s3_do_i15 (char *str
)
1902 s3_skip_whitespace (str
);
1904 if (s3_data_op2 (&str
, 10, _IMM15
) != (int) s3_FAIL
)
1905 s3_end_of_line (str
);
1909 s3_do_xi5x (char *str
)
1911 s3_skip_whitespace (str
);
1913 if (s3_data_op2 (&str
, 15, _IMM5
) == (int) s3_FAIL
|| s3_end_of_line (str
) == (int) s3_FAIL
)
1916 if (s3_inst
.relax_inst
!= 0x8000)
1918 s3_inst
.relax_inst
|= ((s3_inst
.instruction
>> 15) & 0x1f) ;
1919 s3_inst
.relax_size
= 2;
1924 s3_do_rdrs (char *str
)
1926 s3_skip_whitespace (str
);
1928 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
1929 || s3_skip_past_comma (&str
) == (int) s3_FAIL
1930 || s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
1931 || s3_end_of_line (str
) == (int) s3_FAIL
)
1934 if (s3_inst
.relax_inst
!= 0x8000)
1936 if (((s3_inst
.instruction
& 0x7f) == 0x56)) /* adjust mv -> mv!*/
1938 /* mv! rd : 5bit , ra : 5bit */
1939 s3_inst
.relax_inst
|= ((s3_inst
.instruction
>> 15) & 0x1f) | (((s3_inst
.instruction
>> 20) & 0x1f) << 5);
1940 s3_inst
.relax_size
= 2;
1943 else if ((((s3_inst
.instruction
>> 15) & 0x10) == 0x0) && (((s3_inst
.instruction
>> 20) & 0x10) == 0))
1945 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>> 15) & 0xf) << 4)
1946 | (((s3_inst
.instruction
>> 20) & 0xf) << 8);
1947 s3_inst
.relax_size
= 2;
1951 s3_inst
.relax_inst
= 0x8000;
1956 /* Handle mfcr/mtcr. */
1958 s3_do_rdcrs (char *str
)
1960 s3_skip_whitespace (str
);
1962 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) != (int) s3_FAIL
1963 && s3_skip_past_comma (&str
) != (int) s3_FAIL
1964 && s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE_CR
) != (int) s3_FAIL
)
1965 s3_end_of_line (str
);
1968 /* Handle mfsr/mtsr. */
1970 s3_do_rdsrs (char *str
)
1972 s3_skip_whitespace (str
);
1975 if ((s3_inst
.instruction
& 0xff) == 0x50)
1977 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) != (int) s3_FAIL
1978 && s3_skip_past_comma (&str
) != (int) s3_FAIL
1979 && s3_reg_required_here (&str
, 10, s3_REG_TYPE_SCORE_SR
) != (int) s3_FAIL
)
1980 s3_end_of_line (str
);
1984 if (s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) != (int) s3_FAIL
1985 && s3_skip_past_comma (&str
) != (int) s3_FAIL
)
1986 s3_reg_required_here (&str
, 10, s3_REG_TYPE_SCORE_SR
);
1992 s3_do_rdxrs (char *str
)
1994 s3_skip_whitespace (str
);
1996 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
1997 || s3_skip_past_comma (&str
) == (int) s3_FAIL
1998 || s3_reg_required_here (&str
, 10, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
1999 || s3_end_of_line (str
) == (int) s3_FAIL
)
2002 if ((s3_inst
.relax_inst
!= 0x8000) && (((s3_inst
.instruction
>> 10) & 0x10) == 0)
2003 && (((s3_inst
.instruction
>> 20) & 0x10) == 0))
2005 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>> 10) & 0xf) << 4) | (((s3_inst
.instruction
>> 20) & 0xf) << 8);
2006 s3_inst
.relax_size
= 2;
2009 s3_inst
.relax_inst
= 0x8000;
2012 /* Handle cmp.c/cmp<cond>. */
2014 s3_do_rsrs (char *str
)
2016 s3_skip_whitespace (str
);
2018 if (s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
2019 || s3_skip_past_comma (&str
) == (int) s3_FAIL
2020 || s3_reg_required_here (&str
, 10, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
2021 || s3_end_of_line (str
) == (int) s3_FAIL
)
2024 if ((s3_inst
.relax_inst
!= 0x8000) && (((s3_inst
.instruction
>> 20) & 0x1f) == 3) )
2026 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>> 10) & 0x1f)) | (((s3_inst
.instruction
>> 15) & 0x1f) << 5);
2027 s3_inst
.relax_size
= 2;
2030 s3_inst
.relax_inst
= 0x8000;
2034 s3_do_ceinst (char *str
)
2039 s3_skip_whitespace (str
);
2041 if (s3_data_op2 (&str
, 20, _IMM5
) == (int) s3_FAIL
2042 || s3_skip_past_comma (&str
) == (int) s3_FAIL
2043 || s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
2044 || s3_skip_past_comma (&str
) == (int) s3_FAIL
2045 || s3_reg_required_here (&str
, 10, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
2046 || s3_skip_past_comma (&str
) == (int) s3_FAIL
2047 || s3_data_op2 (&str
, 5, _IMM5
) == (int) s3_FAIL
2048 || s3_skip_past_comma (&str
) == (int) s3_FAIL
2049 || s3_data_op2 (&str
, 0, _IMM5
) == (int) s3_FAIL
2050 || s3_end_of_line (str
) == (int) s3_FAIL
)
2057 if (s3_data_op2 (&str
, 0, _IMM25
) == (int) s3_FAIL
)
2063 s3_reglow_required_here (char **str
, int shift
)
2065 static char buff
[s3_MAX_LITERAL_POOL_SIZE
];
2069 if ((reg
= s3_score_reg_parse (str
, s3_all_reg_maps
[s3_REG_TYPE_SCORE
].htab
)) != (int) s3_FAIL
)
2071 if ((reg
== 1) && (s3_nor1
== 1) && (s3_inst
.bwarn
== 0))
2073 as_warn (_("Using temp register(r1)"));
2079 s3_inst
.instruction
|= (bfd_vma
) reg
<< shift
;
2085 /* Restore the start point, we may have got a reg of the wrong class. */
2087 sprintf (buff
, _("low register(r0-r15)expected, not '%.100s'"), start
);
2088 s3_inst
.error
= buff
;
2089 return (int) s3_FAIL
;
2092 /* Handle add!/and!/or!/sub!. */
2094 s3_do16_rdrs2 (char *str
)
2096 s3_skip_whitespace (str
);
2098 if (s3_reglow_required_here (&str
, 4) == (int) s3_FAIL
2099 || s3_skip_past_comma (&str
) == (int) s3_FAIL
2100 || s3_reglow_required_here (&str
, 0) == (int) s3_FAIL
2101 || s3_end_of_line (str
) == (int) s3_FAIL
)
2107 /* Handle br!/brl!. */
2109 s3_do16_br (char *str
)
2111 s3_skip_whitespace (str
);
2113 if (s3_reg_required_here (&str
, 0, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
2114 || s3_end_of_line (str
) == (int) s3_FAIL
)
2122 s3_do16_brr (char *str
)
2126 s3_skip_whitespace (str
);
2128 if ((rd
= s3_reg_required_here (&str
, 0,s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
2129 || s3_end_of_line (str
) == (int) s3_FAIL
)
2135 /*Handle ltbw / ltbh / ltbb */
2137 s3_do_ltb (char *str
)
2139 s3_skip_whitespace (str
);
2140 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
2141 || s3_skip_past_comma (&str
) == (int) s3_FAIL
)
2146 s3_skip_whitespace (str
);
2149 s3_inst
.error
= _("missing [");
2153 if (s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
2154 || s3_skip_past_comma (&str
) == (int) s3_FAIL
2155 || s3_reg_required_here (&str
, 10, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
)
2160 s3_skip_whitespace (str
);
2163 s3_inst
.error
= _("missing ]");
2168 /* We need to be able to fix up arbitrary expressions in some statements.
2169 This is so that we can handle symbols that are an arbitrary distance from
2170 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
2171 which returns part of an address in a form which will be valid for
2172 a data instruction. We do this by pushing the expression into a symbol
2173 in the expr_section, and creating a fix for that. */
2175 s3_fix_new_score (fragS
* frag
, int where
, short int size
, expressionS
* exp
, int pc_rel
, int reloc
)
2185 new_fix
= fix_new_exp (frag
, where
, size
, exp
, pc_rel
, reloc
);
2188 new_fix
= fix_new (frag
, where
, size
, make_expr_symbol (exp
), 0, pc_rel
, reloc
);
2195 s3_init_dependency_vector (void)
2199 for (i
= 0; i
< s3_vector_size
; i
++)
2200 memset (&s3_dependency_vector
[i
], '\0', sizeof (s3_dependency_vector
[i
]));
2205 static enum s3_insn_type_for_dependency
2206 s3_dependency_type_from_insn (char *insn_name
)
2208 char name
[s3_INSN_NAME_LEN
];
2209 const struct s3_insn_to_dependency
*tmp
;
2211 strcpy (name
, insn_name
);
2212 tmp
= (const struct s3_insn_to_dependency
*) hash_find (s3_dependency_insn_hsh
, name
);
2217 return s3_D_all_insn
;
2221 s3_check_dependency (char *pre_insn
, char *pre_reg
,
2222 char *cur_insn
, char *cur_reg
, int *warn_or_error
)
2226 enum s3_insn_type_for_dependency pre_insn_type
;
2227 enum s3_insn_type_for_dependency cur_insn_type
;
2229 pre_insn_type
= s3_dependency_type_from_insn (pre_insn
);
2230 cur_insn_type
= s3_dependency_type_from_insn (cur_insn
);
2232 for (i
= 0; i
< sizeof (s3_data_dependency_table
) / sizeof (s3_data_dependency_table
[0]); i
++)
2234 if ((pre_insn_type
== s3_data_dependency_table
[i
].pre_insn_type
)
2235 && (s3_D_all_insn
== s3_data_dependency_table
[i
].cur_insn_type
2236 || cur_insn_type
== s3_data_dependency_table
[i
].cur_insn_type
)
2237 && (strcmp (s3_data_dependency_table
[i
].pre_reg
, "") == 0
2238 || strcmp (s3_data_dependency_table
[i
].pre_reg
, pre_reg
) == 0)
2239 && (strcmp (s3_data_dependency_table
[i
].cur_reg
, "") == 0
2240 || strcmp (s3_data_dependency_table
[i
].cur_reg
, cur_reg
) == 0))
2242 bubbles
= s3_data_dependency_table
[i
].bubblenum_3
;
2243 *warn_or_error
= s3_data_dependency_table
[i
].warn_or_error
;
2252 s3_build_one_frag (struct s3_score_it one_inst
)
2255 int relaxable_p
= s3_g_opt
;
2258 /* Start a new frag if frag_now is not empty. */
2259 if (frag_now_fix () != 0)
2261 if (!frag_now
->tc_frag_data
.is_insn
)
2262 frag_wane (frag_now
);
2268 p
= frag_more (one_inst
.size
);
2269 s3_md_number_to_chars (p
, one_inst
.instruction
, one_inst
.size
);
2272 dwarf2_emit_insn (one_inst
.size
);
2275 relaxable_p
&= (one_inst
.relax_size
!= 0);
2276 relax_size
= relaxable_p
? one_inst
.relax_size
: 0;
2278 p
= frag_var (rs_machine_dependent
, relax_size
+ s3_RELAX_PAD_BYTE
, 0,
2279 s3_RELAX_ENCODE (one_inst
.size
, one_inst
.relax_size
,
2280 one_inst
.type
, 0, 0, relaxable_p
),
2284 s3_md_number_to_chars (p
, one_inst
.relax_inst
, relax_size
);
2288 s3_handle_dependency (struct s3_score_it
*theinst
)
2291 int warn_or_error
= 0; /* warn - 0; error - 1 */
2293 int remainder_bubbles
= 0;
2294 char cur_insn
[s3_INSN_NAME_LEN
];
2295 char pre_insn
[s3_INSN_NAME_LEN
];
2296 struct s3_score_it nop_inst
;
2297 struct s3_score_it pflush_inst
;
2299 nop_inst
.instruction
= 0x0000;
2301 nop_inst
.relax_inst
= 0x80008000;
2302 nop_inst
.relax_size
= 4;
2303 nop_inst
.type
= NO16_OPD
;
2305 pflush_inst
.instruction
= 0x8000800a;
2306 pflush_inst
.size
= 4;
2307 pflush_inst
.relax_inst
= 0x8000;
2308 pflush_inst
.relax_size
= 0;
2309 pflush_inst
.type
= NO_OPD
;
2311 /* pflush will clear all data dependency. */
2312 if (strcmp (theinst
->name
, "pflush") == 0)
2314 s3_init_dependency_vector ();
2318 /* Push current instruction to s3_dependency_vector[0]. */
2319 for (i
= s3_vector_size
- 1; i
> 0; i
--)
2320 memcpy (&s3_dependency_vector
[i
], &s3_dependency_vector
[i
- 1], sizeof (s3_dependency_vector
[i
]));
2322 memcpy (&s3_dependency_vector
[0], theinst
, sizeof (s3_dependency_vector
[i
]));
2324 /* There is no dependency between nop and any instruction. */
2325 if (strcmp (s3_dependency_vector
[0].name
, "nop") == 0
2326 || strcmp (s3_dependency_vector
[0].name
, "nop!") == 0)
2329 strcpy (cur_insn
, s3_dependency_vector
[0].name
);
2331 for (i
= 1; i
< s3_vector_size
; i
++)
2333 /* The element of s3_dependency_vector is NULL. */
2334 if (s3_dependency_vector
[i
].name
[0] == '\0')
2337 strcpy (pre_insn
, s3_dependency_vector
[i
].name
);
2339 bubbles
= s3_check_dependency (pre_insn
, s3_dependency_vector
[i
].reg
,
2340 cur_insn
, s3_dependency_vector
[0].reg
, &warn_or_error
);
2341 remainder_bubbles
= bubbles
- i
+ 1;
2343 if (remainder_bubbles
> 0)
2347 if (s3_fix_data_dependency
== 1)
2349 if (remainder_bubbles
<= 2)
2351 if (s3_warn_fix_data_dependency
)
2352 as_warn (_("Fix data dependency: %s %s -- %s %s (insert %d nop!/%d)"),
2353 s3_dependency_vector
[i
].name
, s3_dependency_vector
[i
].reg
,
2354 s3_dependency_vector
[0].name
, s3_dependency_vector
[0].reg
,
2355 remainder_bubbles
, bubbles
);
2357 for (j
= (s3_vector_size
- 1); (j
- remainder_bubbles
) > 0; j
--)
2358 memcpy (&s3_dependency_vector
[j
], &s3_dependency_vector
[j
- remainder_bubbles
],
2359 sizeof (s3_dependency_vector
[j
]));
2361 for (j
= 1; j
<= remainder_bubbles
; j
++)
2363 memset (&s3_dependency_vector
[j
], '\0', sizeof (s3_dependency_vector
[j
]));
2365 s3_build_one_frag (nop_inst
);
2370 if (s3_warn_fix_data_dependency
)
2371 as_warn (_("Fix data dependency: %s %s -- %s %s (insert 1 pflush/%d)"),
2372 s3_dependency_vector
[i
].name
, s3_dependency_vector
[i
].reg
,
2373 s3_dependency_vector
[0].name
, s3_dependency_vector
[0].reg
,
2376 for (j
= 1; j
< s3_vector_size
; j
++)
2377 memset (&s3_dependency_vector
[j
], '\0', sizeof (s3_dependency_vector
[j
]));
2379 /* Insert pflush. */
2380 s3_build_one_frag (pflush_inst
);
2387 as_bad (_("data dependency: %s %s -- %s %s (%d/%d bubble)"),
2388 s3_dependency_vector
[i
].name
, s3_dependency_vector
[i
].reg
,
2389 s3_dependency_vector
[0].name
, s3_dependency_vector
[0].reg
,
2390 remainder_bubbles
, bubbles
);
2394 as_warn (_("data dependency: %s %s -- %s %s (%d/%d bubble)"),
2395 s3_dependency_vector
[i
].name
, s3_dependency_vector
[i
].reg
,
2396 s3_dependency_vector
[0].name
, s3_dependency_vector
[0].reg
,
2397 remainder_bubbles
, bubbles
);
2404 static enum insn_class
2405 s3_get_insn_class_from_type (enum score_insn_type type
)
2407 enum insn_class retval
= (int) s3_FAIL
;
2413 case Rd_rvalueBP_I5
:
2414 case Rd_lvalueBP_I5
:
2427 retval
= INSN_CLASS_16
;
2436 case Rd_rvalueRs_SI10
:
2437 case Rd_lvalueRs_SI10
:
2438 case Rd_rvalueRs_preSI12
:
2439 case Rd_rvalueRs_postSI12
:
2440 case Rd_lvalueRs_preSI12
:
2441 case Rd_lvalueRs_postSI12
:
2443 case Rd_rvalueRs_SI15
:
2444 case Rd_lvalueRs_SI15
:
2453 case OP5_rvalueRs_SI15
:
2454 case I5_Rs_Rs_I5_OP5
:
2455 case x_rvalueRs_post4
:
2456 case Rd_rvalueRs_post4
:
2458 case Rd_lvalueRs_post4
:
2459 case x_lvalueRs_post4
:
2469 retval
= INSN_CLASS_32
;
2472 retval
= INSN_CLASS_PCE
;
2475 retval
= INSN_CLASS_SYN
;
2479 retval
= INSN_CLASS_48
;
2489 48-bit instruction: 1, 1, 0.
2490 32-bit instruction: 1, 0.
2491 16-bit instruction: 0. */
2493 s3_adjust_paritybit (bfd_vma m_code
, enum insn_class
class)
2496 bfd_vma m_code_high
= 0;
2497 unsigned long m_code_middle
= 0;
2498 unsigned long m_code_low
= 0;
2499 bfd_vma pb_high
= 0;
2500 unsigned long pb_middle
= 0;
2501 unsigned long pb_low
= 0;
2503 if (class == INSN_CLASS_48
)
2505 pb_high
= 0x800000000000LL
;
2506 pb_middle
= 0x80000000;
2507 pb_low
= 0x00000000;
2508 m_code_high
= m_code
& 0x1fffc0000000LL
;
2509 m_code_middle
= m_code
& 0x3fff8000;
2510 m_code_low
= m_code
& 0x00007fff;
2511 result
= pb_high
| (m_code_high
<< 2) |
2512 pb_middle
| (m_code_middle
<< 1) |
2513 pb_low
| m_code_low
;
2515 else if (class == INSN_CLASS_32
|| class == INSN_CLASS_SYN
)
2517 pb_high
= 0x80000000;
2518 pb_low
= 0x00000000;
2519 m_code_high
= m_code
& 0x3fff8000;
2520 m_code_low
= m_code
& 0x00007fff;
2521 result
= pb_high
| (m_code_high
<< 1) | pb_low
| m_code_low
;
2523 else if (class == INSN_CLASS_16
)
2527 m_code_high
= m_code
& 0x3fff8000;
2528 m_code_low
= m_code
& 0x00007fff;
2529 result
= pb_high
| (m_code_high
<< 1) | pb_low
| m_code_low
;
2531 else if (class == INSN_CLASS_PCE
)
2533 /* Keep original. */
2535 pb_low
= 0x00008000;
2536 m_code_high
= m_code
& 0x3fff8000;
2537 m_code_low
= m_code
& 0x00007fff;
2538 result
= pb_high
| (m_code_high
<< 1) | pb_low
| m_code_low
;
2549 s3_gen_insn_frag (struct s3_score_it
*part_1
, struct s3_score_it
*part_2
)
2552 bfd_boolean pce_p
= FALSE
;
2553 int relaxable_p
= s3_g_opt
;
2555 struct s3_score_it
*inst1
= part_1
;
2556 struct s3_score_it
*inst2
= part_2
;
2557 struct s3_score_it backup_inst1
;
2559 pce_p
= (inst2
) ? TRUE
: FALSE
;
2560 memcpy (&backup_inst1
, inst1
, sizeof (struct s3_score_it
));
2562 /* Adjust instruction opcode and to be relaxed instruction opcode. */
2565 backup_inst1
.instruction
= ((backup_inst1
.instruction
& 0x7FFF) << 15)
2566 | (inst2
->instruction
& 0x7FFF);
2567 backup_inst1
.instruction
= s3_adjust_paritybit (backup_inst1
.instruction
, INSN_CLASS_PCE
);
2568 backup_inst1
.relax_inst
= 0x8000;
2569 backup_inst1
.size
= s3_INSN_SIZE
;
2570 backup_inst1
.relax_size
= 0;
2571 backup_inst1
.type
= Insn_Type_PCE
;
2575 backup_inst1
.instruction
= s3_adjust_paritybit (backup_inst1
.instruction
,
2576 s3_GET_INSN_CLASS (backup_inst1
.type
));
2579 if (backup_inst1
.relax_size
!= 0)
2581 enum insn_class tmp
;
2583 tmp
= (backup_inst1
.size
== s3_INSN_SIZE
) ? INSN_CLASS_16
: INSN_CLASS_32
;
2584 backup_inst1
.relax_inst
= s3_adjust_paritybit (backup_inst1
.relax_inst
, tmp
);
2587 /* Check data dependency. */
2588 s3_handle_dependency (&backup_inst1
);
2590 /* Start a new frag if frag_now is not empty and is not instruction frag, maybe it contains
2591 data produced by .ascii etc. Doing this is to make one instruction per frag. */
2592 if (frag_now_fix () != 0)
2594 if (!frag_now
->tc_frag_data
.is_insn
)
2595 frag_wane (frag_now
);
2600 /* Here, we must call frag_grow in order to keep the instruction frag type is
2601 rs_machine_dependent.
2602 For, frag_var may change frag_now->fr_type to rs_fill by calling frag_grow which
2603 acturally will call frag_wane.
2604 Calling frag_grow first will create a new frag_now which free size is 20 that is enough
2608 p
= frag_more (backup_inst1
.size
);
2609 s3_md_number_to_chars (p
, backup_inst1
.instruction
, backup_inst1
.size
);
2612 dwarf2_emit_insn (backup_inst1
.size
);
2615 /* Generate fixup structure. */
2618 if (inst1
->reloc
.type
!= BFD_RELOC_NONE
)
2619 s3_fix_new_score (frag_now
, p
- frag_now
->fr_literal
,
2620 inst1
->size
, &inst1
->reloc
.exp
,
2621 inst1
->reloc
.pc_rel
, inst1
->reloc
.type
);
2623 if (inst2
->reloc
.type
!= BFD_RELOC_NONE
)
2624 s3_fix_new_score (frag_now
, p
- frag_now
->fr_literal
+ 2,
2625 inst2
->size
, &inst2
->reloc
.exp
, inst2
->reloc
.pc_rel
, inst2
->reloc
.type
);
2629 if (backup_inst1
.reloc
.type
!= BFD_RELOC_NONE
)
2630 s3_fix_new_score (frag_now
, p
- frag_now
->fr_literal
,
2631 backup_inst1
.size
, &backup_inst1
.reloc
.exp
,
2632 backup_inst1
.reloc
.pc_rel
, backup_inst1
.reloc
.type
);
2635 /* relax_size may be 2, 4, 12 or 0, 0 indicates no relaxation. */
2636 relaxable_p
&= (backup_inst1
.relax_size
!= 0);
2637 relax_size
= relaxable_p
? backup_inst1
.relax_size
: 0;
2639 p
= frag_var (rs_machine_dependent
, relax_size
+ s3_RELAX_PAD_BYTE
, 0,
2640 s3_RELAX_ENCODE (backup_inst1
.size
, backup_inst1
.relax_size
,
2641 backup_inst1
.type
, 0, 0, relaxable_p
),
2642 backup_inst1
.reloc
.exp
.X_add_symbol
, 0, NULL
);
2645 s3_md_number_to_chars (p
, backup_inst1
.relax_inst
, relax_size
);
2647 memcpy (inst1
, &backup_inst1
, sizeof (struct s3_score_it
));
2651 s3_parse_16_32_inst (char *insnstr
, bfd_boolean gen_frag_p
)
2655 char *operator = insnstr
;
2656 const struct s3_asm_opcode
*opcode
;
2658 /* Parse operator and operands. */
2659 s3_skip_whitespace (operator);
2661 for (p
= operator; *p
!= '\0'; p
++)
2662 if ((*p
== ' ') || (*p
== '!'))
2671 opcode
= (const struct s3_asm_opcode
*) hash_find (s3_score_ops_hsh
, operator);
2674 memset (&s3_inst
, '\0', sizeof (s3_inst
));
2675 sprintf (s3_inst
.str
, "%s", insnstr
);
2678 s3_inst
.instruction
= opcode
->value
;
2679 s3_inst
.relax_inst
= opcode
->relax_value
;
2680 s3_inst
.type
= opcode
->type
;
2681 s3_inst
.size
= s3_GET_INSN_SIZE (s3_inst
.type
);
2682 s3_inst
.relax_size
= 0;
2684 sprintf (s3_inst
.name
, "%s", opcode
->template);
2685 strcpy (s3_inst
.reg
, "");
2686 s3_inst
.error
= NULL
;
2687 s3_inst
.reloc
.type
= BFD_RELOC_NONE
;
2689 (*opcode
->parms
) (p
);
2691 /* It indicates current instruction is a macro instruction if s3_inst.bwarn equals -1. */
2692 if ((s3_inst
.bwarn
!= -1) && (!s3_inst
.error
) && (gen_frag_p
))
2693 s3_gen_insn_frag (&s3_inst
, NULL
);
2696 s3_inst
.error
= _("unrecognized opcode");
2700 s3_parse_48_inst (char *insnstr
, bfd_boolean gen_frag_p
)
2704 char *operator = insnstr
;
2705 const struct s3_asm_opcode
*opcode
;
2707 /* Parse operator and operands. */
2708 s3_skip_whitespace (operator);
2710 for (p
= operator; *p
!= '\0'; p
++)
2717 opcode
= (const struct s3_asm_opcode
*) hash_find (s3_score_ops_hsh
, operator);
2720 memset (&s3_inst
, '\0', sizeof (s3_inst
));
2721 sprintf (s3_inst
.str
, "%s", insnstr
);
2724 s3_inst
.instruction
= opcode
->value
;
2725 s3_inst
.relax_inst
= opcode
->relax_value
;
2726 s3_inst
.type
= opcode
->type
;
2727 s3_inst
.size
= s3_GET_INSN_SIZE (s3_inst
.type
);
2728 s3_inst
.relax_size
= 0;
2730 sprintf (s3_inst
.name
, "%s", opcode
->template);
2731 strcpy (s3_inst
.reg
, "");
2732 s3_inst
.error
= NULL
;
2733 s3_inst
.reloc
.type
= BFD_RELOC_NONE
;
2735 (*opcode
->parms
) (p
);
2737 /* It indicates current instruction is a macro instruction if s3_inst.bwarn equals -1. */
2738 if ((s3_inst
.bwarn
!= -1) && (!s3_inst
.error
) && (gen_frag_p
))
2739 s3_gen_insn_frag (&s3_inst
, NULL
);
2742 s3_inst
.error
= _("unrecognized opcode");
2746 s3_append_insn (char *str
, bfd_boolean gen_frag_p
)
2748 int retval
= s3_SUCCESS
;
2750 s3_parse_16_32_inst (str
, gen_frag_p
);
2754 retval
= (int) s3_FAIL
;
2755 as_bad (_("%s -- `%s'"), s3_inst
.error
, s3_inst
.str
);
2756 s3_inst
.error
= NULL
;
2763 s3_do16_mv_cmp (char *str
)
2765 s3_skip_whitespace (str
);
2767 if (s3_reg_required_here (&str
, 5, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
2768 || s3_skip_past_comma (&str
) == (int) s3_FAIL
2769 || s3_reg_required_here (&str
, 0, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
2770 || s3_end_of_line (str
) == (int) s3_FAIL
)
2777 s3_do16_cmpi (char *str
)
2779 s3_skip_whitespace (str
);
2781 if (s3_reg_required_here (&str
, 5, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
2782 || s3_skip_past_comma (&str
) == (int) s3_FAIL
2783 || s3_data_op2 (&str
, 0, _SIMM5
) == (int) s3_FAIL
2784 || s3_end_of_line (str
) == (int) s3_FAIL
)
2791 s3_do16_addi (char *str
)
2793 s3_skip_whitespace (str
);
2795 if (s3_reglow_required_here (&str
, 6) == (int) s3_FAIL
2796 || s3_skip_past_comma (&str
) == (int) s3_FAIL
2797 || s3_data_op2 (&str
, 0, _SIMM6
) == (int) s3_FAIL
2798 || s3_end_of_line (str
) == (int) s3_FAIL
)
2804 /* Handle bitclr! / bitset! / bittst! / bittgl! */
2806 s3_do16_rdi5 (char *str
)
2808 s3_skip_whitespace (str
);
2810 if (s3_reglow_required_here (&str
, 5) == (int) s3_FAIL
2811 || s3_skip_past_comma (&str
) == (int) s3_FAIL
2812 || s3_data_op2 (&str
, 0, _IMM5
) == (int) s3_FAIL
2813 || s3_end_of_line (str
) == (int) s3_FAIL
)
2817 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>>5) & 0xf) << 20)
2818 | (((s3_inst
.instruction
>> 5) & 0xf) << 15) | (((s3_inst
.instruction
) & 0x1f) << 10);
2819 s3_inst
.relax_size
= 4;
2824 /* Handle sdbbp!. */
2826 s3_do16_xi5 (char *str
)
2828 s3_skip_whitespace (str
);
2830 if (s3_data_op2 (&str
, 0, _IMM5
) == (int) s3_FAIL
|| s3_end_of_line (str
) == (int) s3_FAIL
)
2834 /* Check that an immediate is word alignment or half word alignment.
2835 If so, convert it to the right format. */
2837 s3_validate_immediate_align (int val
, unsigned int data_type
)
2839 if (data_type
== _IMM5_RSHIFT_1
)
2843 s3_inst
.error
= _("address offset must be half word alignment");
2844 return (int) s3_FAIL
;
2847 else if ((data_type
== _IMM5_RSHIFT_2
) || (data_type
== _IMM10_RSHIFT_2
))
2851 s3_inst
.error
= _("address offset must be word alignment");
2852 return (int) s3_FAIL
;
2860 s3_exp_ldst_offset (char **str
, int shift
, unsigned int data_type
)
2866 if ((*dataptr
== '0') && (*(dataptr
+ 1) == 'x')
2867 && (data_type
!= _SIMM16_LA
)
2868 && (data_type
!= _VALUE_HI16
)
2869 && (data_type
!= _VALUE_LO16
)
2870 && (data_type
!= _IMM16
)
2871 && (data_type
!= _IMM15
)
2872 && (data_type
!= _IMM14
)
2873 && (data_type
!= _IMM4
)
2874 && (data_type
!= _IMM5
)
2875 && (data_type
!= _IMM8
)
2876 && (data_type
!= _IMM5_RSHIFT_1
)
2877 && (data_type
!= _IMM5_RSHIFT_2
)
2878 && (data_type
!= _SIMM14_NEG
)
2879 && (data_type
!= _IMM10_RSHIFT_2
))
2884 if (s3_my_get_expression (&s3_inst
.reloc
.exp
, str
) == (int) s3_FAIL
)
2885 return (int) s3_FAIL
;
2887 if (s3_inst
.reloc
.exp
.X_op
== O_constant
)
2889 /* Need to check the immediate align. */
2890 int value
= s3_validate_immediate_align (s3_inst
.reloc
.exp
.X_add_number
, data_type
);
2892 if (value
== (int) s3_FAIL
)
2893 return (int) s3_FAIL
;
2895 value
= s3_validate_immediate (s3_inst
.reloc
.exp
.X_add_number
, data_type
, 0);
2896 if (value
== (int) s3_FAIL
)
2899 sprintf (s3_err_msg
,
2900 _("invalid constant: %d bit expression not in range %d..%d"),
2901 s3_score_df_range
[data_type
].bits
,
2902 s3_score_df_range
[data_type
].range
[0], s3_score_df_range
[data_type
].range
[1]);
2904 sprintf (s3_err_msg
,
2905 _("invalid constant: %d bit expression not in range %d..%d"),
2906 s3_score_df_range
[data_type
- 24].bits
,
2907 s3_score_df_range
[data_type
- 24].range
[0], s3_score_df_range
[data_type
- 24].range
[1]);
2908 s3_inst
.error
= s3_err_msg
;
2909 return (int) s3_FAIL
;
2912 if (data_type
== _IMM5_RSHIFT_1
)
2916 else if ((data_type
== _IMM5_RSHIFT_2
) || (data_type
== _IMM10_RSHIFT_2
))
2921 if (s3_score_df_range
[data_type
].range
[0] != 0)
2923 value
&= (1 << s3_score_df_range
[data_type
].bits
) - 1;
2926 s3_inst
.instruction
|= value
<< shift
;
2930 s3_inst
.reloc
.pc_rel
= 0;
2937 s3_do_ldst_insn (char *str
)
2949 s3_skip_whitespace (str
);
2951 if (((conflict_reg
= s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
)
2952 || (s3_skip_past_comma (&str
) == (int) s3_FAIL
))
2955 /* ld/sw rD, [rA, simm15] ld/sw rD, [rA]+, simm12 ld/sw rD, [rA, simm12]+. */
2959 s3_skip_whitespace (str
);
2961 if ((reg
= s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
)
2964 /* Conflicts can occur on stores as well as loads. */
2965 conflict_reg
= (conflict_reg
== reg
);
2966 s3_skip_whitespace (str
);
2967 temp
= str
+ 1; /* The latter will process decimal/hex expression. */
2969 /* ld/sw rD, [rA]+, simm12 ld/sw rD, [rA]+. */
2976 /* ld/sw rD, [rA]+, simm12. */
2977 if (s3_skip_past_comma (&str
) == s3_SUCCESS
)
2979 if ((s3_exp_ldst_offset (&str
, 3, _SIMM12
) == (int) s3_FAIL
)
2980 || (s3_end_of_line (str
) == (int) s3_FAIL
))
2985 unsigned int ldst_func
= s3_inst
.instruction
& OPC_PSEUDOLDST_MASK
;
2987 if ((ldst_func
== INSN_LH
)
2988 || (ldst_func
== INSN_LHU
)
2989 || (ldst_func
== INSN_LW
)
2990 || (ldst_func
== INSN_LB
)
2991 || (ldst_func
== INSN_LBU
))
2993 s3_inst
.error
= _("register same as write-back base");
2998 ldst_idx
= s3_inst
.instruction
& OPC_PSEUDOLDST_MASK
;
2999 s3_inst
.instruction
&= ~OPC_PSEUDOLDST_MASK
;
3000 s3_inst
.instruction
|= s3_score_ldst_insns
[ldst_idx
* 3 + LDST_POST
].value
;
3002 /* lw rD, [rA]+, 4 convert to pop rD, [rA]. */
3003 if ((s3_inst
.instruction
& 0x3e000007) == 0x0e000000)
3005 /* rs = r0, offset = 4 */
3006 if ((((s3_inst
.instruction
>> 15) & 0x1f) == 0)
3007 && (((s3_inst
.instruction
>> 3) & 0xfff) == 4))
3009 /* Relax to pop!. */
3010 s3_inst
.relax_inst
= 0x0040 | ((s3_inst
.instruction
>> 20) & 0x1f);
3011 s3_inst
.relax_size
= 2;
3016 /* ld/sw rD, [rA]+ convert to ld/sw rD, [rA, 0]+. */
3019 s3_SET_INSN_ERROR (NULL
);
3020 if (s3_end_of_line (str
) == (int) s3_FAIL
)
3026 value
= s3_validate_immediate (s3_inst
.reloc
.exp
.X_add_number
, _SIMM12
, 0);
3027 value
&= (1 << s3_score_df_range
[_SIMM12
].bits
) - 1;
3028 ldst_idx
= s3_inst
.instruction
& OPC_PSEUDOLDST_MASK
;
3029 s3_inst
.instruction
&= ~OPC_PSEUDOLDST_MASK
;
3030 s3_inst
.instruction
|= s3_score_ldst_insns
[ldst_idx
* 3 + pre_inc
].value
;
3031 s3_inst
.instruction
|= value
<< 3;
3032 s3_inst
.relax_inst
= 0x8000;
3036 /* ld/sw rD, [rA] convert to ld/sw rD, [rA, simm15]. */
3039 if (s3_end_of_line (str
) == (int) s3_FAIL
)
3042 ldst_idx
= s3_inst
.instruction
& OPC_PSEUDOLDST_MASK
;
3043 s3_inst
.instruction
&= ~OPC_PSEUDOLDST_MASK
;
3044 s3_inst
.instruction
|= s3_score_ldst_insns
[ldst_idx
* 3 + LDST_NOUPDATE
].value
;
3046 /* lbu rd, [rs] -> lbu! rd, [rs] */
3047 if (ldst_idx
== INSN_LBU
)
3049 s3_inst
.relax_inst
= INSN16_LBU
;
3051 else if (ldst_idx
== INSN_LH
)
3053 s3_inst
.relax_inst
= INSN16_LH
;
3055 else if (ldst_idx
== INSN_LW
)
3057 s3_inst
.relax_inst
= INSN16_LW
;
3059 else if (ldst_idx
== INSN_SB
)
3061 s3_inst
.relax_inst
= INSN16_SB
;
3063 else if (ldst_idx
== INSN_SH
)
3065 s3_inst
.relax_inst
= INSN16_SH
;
3067 else if (ldst_idx
== INSN_SW
)
3069 s3_inst
.relax_inst
= INSN16_SW
;
3073 s3_inst
.relax_inst
= 0x8000;
3076 /* lw/lh/lbu/sw/sh/sb, offset = 0, relax to 16 bit instruction. */
3077 /* if ((ldst_idx == INSN_LBU)
3078 || (ldst_idx == INSN_LH)
3079 || (ldst_idx == INSN_LW)
3080 || (ldst_idx == INSN_SB) || (ldst_idx == INSN_SH) || (ldst_idx == INSN_SW))*/
3081 if ( (ldst_idx
== INSN_LW
)|| (ldst_idx
== INSN_SW
))
3083 /* ra only 3 bit , rd only 4 bit for lw! and sw! */
3084 if ((((s3_inst
.instruction
>> 15) & 0x18) == 0) && (((s3_inst
.instruction
>> 20) & 0x10) == 0))
3086 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>> 20) & 0xf) << 8) |
3087 (((s3_inst
.instruction
>> 15) & 0x7) << 5);
3088 s3_inst
.relax_size
= 2;
3095 /* ld/sw rD, [rA, simm15] ld/sw rD, [rA, simm12]+. */
3098 if (s3_skip_past_comma (&str
) == (int) s3_FAIL
)
3100 s3_inst
.error
= _("pre-indexed expression expected");
3104 if (s3_my_get_expression (&s3_inst
.reloc
.exp
, &str
) == (int) s3_FAIL
)
3107 s3_skip_whitespace (str
);
3110 s3_inst
.error
= _("missing ]");
3114 s3_skip_whitespace (str
);
3115 /* ld/sw rD, [rA, simm12]+. */
3122 unsigned int ldst_func
= s3_inst
.instruction
& OPC_PSEUDOLDST_MASK
;
3124 if ((ldst_func
== INSN_LH
)
3125 || (ldst_func
== INSN_LHU
)
3126 || (ldst_func
== INSN_LW
)
3127 || (ldst_func
== INSN_LB
)
3128 || (ldst_func
== INSN_LBU
))
3130 s3_inst
.error
= _("register same as write-back base");
3136 if (s3_end_of_line (str
) == (int) s3_FAIL
)
3139 if (s3_inst
.reloc
.exp
.X_op
== O_constant
)
3142 unsigned int data_type
;
3145 data_type
= _SIMM12
;
3147 data_type
= _SIMM15
;
3150 if ((*dataptr
== '0') && (*(dataptr
+ 1) == 'x')
3151 && (data_type
!= _SIMM16_LA
)
3152 && (data_type
!= _VALUE_HI16
)
3153 && (data_type
!= _VALUE_LO16
)
3154 && (data_type
!= _IMM16
)
3155 && (data_type
!= _IMM15
)
3156 && (data_type
!= _IMM14
)
3157 && (data_type
!= _IMM4
)
3158 && (data_type
!= _IMM5
)
3159 && (data_type
!= _IMM8
)
3160 && (data_type
!= _IMM5_RSHIFT_1
)
3161 && (data_type
!= _IMM5_RSHIFT_2
)
3162 && (data_type
!= _SIMM14_NEG
)
3163 && (data_type
!= _IMM10_RSHIFT_2
))
3168 value
= s3_validate_immediate (s3_inst
.reloc
.exp
.X_add_number
, data_type
, 0);
3169 if (value
== (int) s3_FAIL
)
3172 sprintf (s3_err_msg
,
3173 _("invalid constant: %d bit expression not in range %d..%d"),
3174 s3_score_df_range
[data_type
].bits
,
3175 s3_score_df_range
[data_type
].range
[0], s3_score_df_range
[data_type
].range
[1]);
3177 sprintf (s3_err_msg
,
3178 _("invalid constant: %d bit expression not in range %d..%d"),
3179 s3_score_df_range
[data_type
- 24].bits
,
3180 s3_score_df_range
[data_type
- 24].range
[0],
3181 s3_score_df_range
[data_type
- 24].range
[1]);
3182 s3_inst
.error
= s3_err_msg
;
3186 value
&= (1 << s3_score_df_range
[data_type
].bits
) - 1;
3187 ldst_idx
= s3_inst
.instruction
& OPC_PSEUDOLDST_MASK
;
3188 s3_inst
.instruction
&= ~OPC_PSEUDOLDST_MASK
;
3189 s3_inst
.instruction
|= s3_score_ldst_insns
[ldst_idx
* 3 + pre_inc
].value
;
3191 s3_inst
.instruction
|= value
<< 3;
3193 s3_inst
.instruction
|= value
;
3195 /* lw rD, [rA, simm15] */
3196 if ((s3_inst
.instruction
& 0x3e000000) == 0x20000000)
3198 /* rD in [r0 - r15]. , ra in [r0-r7] */
3199 if ((((s3_inst
.instruction
>> 15) & 0x18) == 0)
3200 && (((s3_inst
.instruction
>> 20) & 0x10) == 0))
3202 /* simm = [bit 7], lw -> lw!. */
3203 if (((s3_inst
.instruction
& 0x7f80) == 0)&&((s3_inst
.instruction
&0x3)==0))
3205 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>> 15) & 0x7) << 5)
3206 | (((s3_inst
.instruction
>> 20) & 0xf) << 8)|(value
>>2);
3207 s3_inst
.relax_size
= 2;
3211 s3_inst
.relax_inst
= 0x8000;
3216 s3_inst
.relax_inst
= 0x8000;
3219 /* sw rD, [rA, simm15] */
3220 else if ((s3_inst
.instruction
& 0x3e000000) == 0x28000000)
3222 /* rD is in [r0 - r15] and ra in [r0-r7] */
3223 if ((((s3_inst
.instruction
>> 15) & 0x18) == 0) && (((s3_inst
.instruction
>> 20) & 0x10) == 0))
3225 /* simm15 =7 bit , sw -> sw!. */
3226 if (((s3_inst
.instruction
& 0x7f80) == 0)&&((s3_inst
.instruction
&0x3)==0))
3228 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>> 15) & 0xf) << 5)
3229 | (((s3_inst
.instruction
>> 20) & 0xf) << 8)|(value
>>2);
3230 s3_inst
.relax_size
= 2;
3232 /* rA = r2, sw -> swp!. */
3235 s3_inst
.relax_inst
= 0x8000;
3240 s3_inst
.relax_inst
= 0x8000;
3243 /* sw rD, [rA, simm15]+ sw pre. */
3244 else if ((s3_inst
.instruction
& 0x3e000007) == 0x06000004)
3246 /* simm15 = -4. and ra==r0 */
3247 if ((((s3_inst
.instruction
>> 15) & 0x1f) == 0)
3248 && (((s3_inst
.instruction
>> 3) & 0xfff) == 0xffc))
3251 s3_inst
.relax_inst
= 0x0060 | ((s3_inst
.instruction
>> 20) & 0x1f);
3252 s3_inst
.relax_size
= 2;
3256 s3_inst
.relax_inst
= 0x8000;
3261 s3_inst
.relax_inst
= 0x8000;
3268 /* FIXME: may set error, for there is no ld/sw rD, [rA, label] */
3269 s3_inst
.reloc
.pc_rel
= 0;
3275 s3_inst
.error
= s3_BAD_ARGS
;
3281 s3_do_cache (char *str
)
3283 s3_skip_whitespace (str
);
3285 if ((s3_data_op2 (&str
, 20, _IMM5
) == (int) s3_FAIL
) || (s3_skip_past_comma (&str
) == (int) s3_FAIL
))
3293 cache_op
= (s3_inst
.instruction
>> 20) & 0x1F;
3294 sprintf (s3_inst
.name
, "cache %d", cache_op
);
3300 s3_skip_whitespace (str
);
3302 if (s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
)
3305 s3_skip_whitespace (str
);
3307 /* cache op, [rA] */
3308 if (s3_skip_past_comma (&str
) == (int) s3_FAIL
)
3310 s3_SET_INSN_ERROR (NULL
);
3313 s3_inst
.error
= _("missing ]");
3318 /* cache op, [rA, simm15] */
3321 if (s3_exp_ldst_offset (&str
, 0, _SIMM15
) == (int) s3_FAIL
)
3326 s3_skip_whitespace (str
);
3329 s3_inst
.error
= _("missing ]");
3334 if (s3_end_of_line (str
) == (int) s3_FAIL
)
3339 s3_inst
.error
= s3_BAD_ARGS
;
3344 s3_do_crdcrscrsimm5 (char *str
)
3349 s3_skip_whitespace (str
);
3351 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE_CR
) == (int) s3_FAIL
3352 || s3_skip_past_comma (&str
) == (int) s3_FAIL
3353 || s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE_CR
) == (int) s3_FAIL
3354 || s3_skip_past_comma (&str
) == (int) s3_FAIL
3355 || s3_reg_required_here (&str
, 10, s3_REG_TYPE_SCORE_CR
) == (int) s3_FAIL
3356 || s3_skip_past_comma (&str
) == (int) s3_FAIL
)
3359 /* cop1 cop_code20. */
3360 if (s3_data_op2 (&str
, 5, _IMM20
) == (int) s3_FAIL
)
3365 if (s3_data_op2 (&str
, 5, _IMM5
) == (int) s3_FAIL
)
3369 s3_end_of_line (str
);
3372 /* Handle ldc/stc. */
3374 s3_do_ldst_cop (char *str
)
3376 s3_skip_whitespace (str
);
3378 if ((s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE_CR
) == (int) s3_FAIL
)
3379 || (s3_skip_past_comma (&str
) == (int) s3_FAIL
))
3385 s3_skip_whitespace (str
);
3387 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
)
3390 s3_skip_whitespace (str
);
3394 if (s3_exp_ldst_offset (&str
, 5, _IMM10_RSHIFT_2
) == (int) s3_FAIL
)
3397 s3_skip_whitespace (str
);
3400 s3_inst
.error
= _("missing ]");
3405 s3_end_of_line (str
);
3408 s3_inst
.error
= s3_BAD_ARGS
;
3412 s3_do16_ldst_insn (char *str
)
3416 s3_skip_whitespace (str
);
3418 if ((s3_reglow_required_here (&str
, 8) == (int) s3_FAIL
) || (s3_skip_past_comma (&str
) == (int) s3_FAIL
))
3425 s3_skip_whitespace (str
);
3427 if ((conflict_reg
= s3_reglow_required_here (&str
, 5)) == (int) s3_FAIL
)
3429 if (conflict_reg
&0x8)
3431 sprintf (s3_err_msg
, _("invalid register number: %d is not in [r0--r7]"),conflict_reg
);
3432 s3_inst
.error
=s3_err_msg
;
3436 s3_skip_whitespace (str
);
3437 temp
= str
+ 1; /* The latter will process decimal/hex expression. */
3441 if (s3_end_of_line (str
) == (int) s3_FAIL
)
3446 if (s3_skip_past_comma (&str
) == (int) s3_FAIL
)
3448 s3_inst
.error
= _("comma is expected");
3451 if (s3_my_get_expression (&s3_inst
.reloc
.exp
, &str
) == (int) s3_FAIL
)
3453 s3_skip_whitespace (str
);
3456 s3_inst
.error
= _("missing ]");
3459 if (s3_end_of_line (str
) == (int) s3_FAIL
)
3461 if (s3_inst
.reloc
.exp
.X_op
== O_constant
)
3464 unsigned int data_type
;
3465 data_type
= _IMM5_RSHIFT_2
;
3466 value
= s3_validate_immediate (s3_inst
.reloc
.exp
.X_add_number
, data_type
, 0);
3467 if (value
== (int) s3_FAIL
)
3470 sprintf (s3_err_msg
,
3471 _("invalid constant: %d bit expression not in range %d..%d"),
3472 s3_score_df_range
[data_type
].bits
,
3473 s3_score_df_range
[data_type
].range
[0], s3_score_df_range
[data_type
].range
[1]);
3474 s3_inst
.error
= s3_err_msg
;
3479 sprintf (s3_err_msg
, _("invalid constant: %d is not word align integer"),value
);
3480 s3_inst
.error
=s3_err_msg
;
3485 s3_inst
.instruction
|= value
;
3492 sprintf (s3_err_msg
, _("missing ["));
3493 s3_inst
.error
=s3_err_msg
;
3499 s3_do_lw48 (char *str
)
3501 bfd_signed_vma val
= 0;
3503 s3_skip_whitespace (str
);
3505 if ((s3_reg_required_here (&str
, 37, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
)
3506 || (s3_skip_past_comma (&str
) == (int) s3_FAIL
))
3509 if (s3_my_get_expression (&s3_inst
.reloc
.exp
, &str
) == (int) s3_FAIL
3510 || s3_end_of_line (str
) == (int) s3_FAIL
)
3515 /* Check word align for lw48 rd, value. */
3516 if ((s3_inst
.reloc
.exp
.X_add_symbol
== NULL
)
3517 && ((s3_inst
.reloc
.exp
.X_add_number
& 0x3) != 0))
3519 s3_inst
.error
= _("invalid constant: 32 bit expression not word align");
3523 /* Check and set offset. */
3524 val
= s3_inst
.reloc
.exp
.X_add_number
;
3525 if ((s3_inst
.reloc
.exp
.X_add_symbol
== NULL
)
3526 && (!(val
>= 0 && val
<= 0xffffffffLL
)))
3528 s3_inst
.error
= _("invalid constant: 32 bit expression not in range [0, 0xffffffff]");
3534 s3_inst
.instruction
|= (val
<< 7);
3536 /* Set reloc type. */
3537 s3_inst
.reloc
.type
= BFD_RELOC_SCORE_IMM30
;
3542 s3_do_sw48 (char *str
)
3544 bfd_signed_vma val
= 0;
3546 s3_skip_whitespace (str
);
3548 if ((s3_reg_required_here (&str
, 37, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
)
3549 || (s3_skip_past_comma (&str
) == (int) s3_FAIL
))
3552 if (s3_my_get_expression (&s3_inst
.reloc
.exp
, &str
) == (int) s3_FAIL
3553 || s3_end_of_line (str
) == (int) s3_FAIL
)
3558 /* Check word align for lw48 rd, value. */
3559 if ((s3_inst
.reloc
.exp
.X_add_symbol
== NULL
)
3560 && ((s3_inst
.reloc
.exp
.X_add_number
& 0x3) != 0))
3562 s3_inst
.error
= _("invalid constant: 32 bit expression not word align");
3566 /* Check and set offset. */
3567 val
= s3_inst
.reloc
.exp
.X_add_number
;
3568 if ((s3_inst
.reloc
.exp
.X_add_symbol
== NULL
)
3569 && (!(val
>= 0 && val
<= 0xffffffffLL
)))
3571 s3_inst
.error
= _("invalid constant: 32 bit expression not in range [0, 0xffffffff]");
3577 s3_inst
.instruction
|= (val
<< 7);
3579 /* Set reloc type. */
3580 s3_inst
.reloc
.type
= BFD_RELOC_SCORE_IMM30
;
3584 s3_do_ldi48 (char *str
)
3588 s3_skip_whitespace (str
);
3590 if (s3_reg_required_here (&str
, 37, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
3591 || s3_skip_past_comma (&str
) == (int) s3_FAIL
)
3594 if (s3_my_get_expression (&s3_inst
.reloc
.exp
, &str
) == (int) s3_FAIL
3595 || s3_end_of_line (str
) == (int) s3_FAIL
)
3600 /* Check and set offset. */
3601 val
= s3_inst
.reloc
.exp
.X_add_number
;
3602 if (!(val
>= -0xffffffffLL
&& val
<= 0xffffffffLL
))
3604 s3_inst
.error
= _("invalid constant: 32 bit expression not in range [-0x80000000, 0x7fffffff]");
3609 s3_inst
.instruction
|= (val
<< 5);
3611 /* Set reloc type. */
3612 s3_inst
.reloc
.type
= BFD_RELOC_SCORE_IMM32
;
3616 s3_do_sdbbp48 (char *str
)
3618 s3_skip_whitespace (str
);
3620 if (s3_data_op2 (&str
, 5, _IMM5
) == (int) s3_FAIL
|| s3_end_of_line (str
) == (int) s3_FAIL
)
3625 s3_do_and48 (char *str
)
3627 s3_skip_whitespace (str
);
3629 if (s3_reglow_required_here (&str
, 38) == (int) s3_FAIL
3630 || s3_skip_past_comma (&str
) == (int) s3_FAIL
3631 || s3_reglow_required_here (&str
, 34) == (int) s3_FAIL
3632 || s3_skip_past_comma (&str
) == (int) s3_FAIL
3633 || s3_data_op2 (&str
, 2, _IMM32
) == (int) s3_FAIL
3634 || s3_end_of_line (str
) == (int) s3_FAIL
)
3639 s3_do_or48 (char *str
)
3641 s3_skip_whitespace (str
);
3643 if (s3_reglow_required_here (&str
, 38) == (int) s3_FAIL
3644 || s3_skip_past_comma (&str
) == (int) s3_FAIL
3645 || s3_reglow_required_here (&str
, 34) == (int) s3_FAIL
3646 || s3_skip_past_comma (&str
) == (int) s3_FAIL
3647 || s3_data_op2 (&str
, 2, _IMM32
) == (int) s3_FAIL
3648 || s3_end_of_line (str
) == (int) s3_FAIL
)
3653 s3_do_mbitclr (char *str
)
3656 s3_skip_whitespace (str
);
3660 sprintf (s3_err_msg
, _("missing ["));
3661 s3_inst
.error
=s3_err_msg
;
3666 s3_inst
.instruction
&= 0x0;
3668 if ((s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
)
3669 || (s3_skip_past_comma (&str
) == (int) s3_FAIL
)
3670 || (s3_data_op2 (&str
, 0, _IMM11
) == (int) s3_FAIL
))
3673 /* Get imm11 and refill opcode. */
3674 val
= s3_inst
.instruction
& 0x7ff;
3676 s3_inst
.instruction
&= 0x000f8000;
3677 s3_inst
.instruction
|= 0x00000064;
3681 sprintf (s3_err_msg
, _("missing ]"));
3682 s3_inst
.error
=s3_err_msg
;
3687 if ((s3_skip_past_comma (&str
) == (int) s3_FAIL
)
3688 || (s3_data_op2 (&str
, 10, _IMM5
) == (int) s3_FAIL
))
3691 /* Set imm11 to opcode. */
3692 s3_inst
.instruction
|= (val
& 0x1)
3693 | (((val
>> 1 ) & 0x7) << 7)
3694 | (((val
>> 4 ) & 0x1f) << 20);
3698 s3_do_mbitset (char *str
)
3701 s3_skip_whitespace (str
);
3705 sprintf (s3_err_msg
, _("missing ["));
3706 s3_inst
.error
=s3_err_msg
;
3711 s3_inst
.instruction
&= 0x0;
3713 if ((s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
)
3714 || (s3_skip_past_comma (&str
) == (int) s3_FAIL
)
3715 || (s3_data_op2 (&str
, 0, _IMM11
) == (int) s3_FAIL
))
3718 /* Get imm11 and refill opcode. */
3719 val
= s3_inst
.instruction
& 0x7ff;
3721 s3_inst
.instruction
&= 0x000f8000;
3722 s3_inst
.instruction
|= 0x0000006c;
3726 sprintf (s3_err_msg
, _("missing ]"));
3727 s3_inst
.error
=s3_err_msg
;
3732 if ((s3_skip_past_comma (&str
) == (int) s3_FAIL
)
3733 || (s3_data_op2 (&str
, 10, _IMM5
) == (int) s3_FAIL
))
3736 /* Set imm11 to opcode. */
3737 s3_inst
.instruction
|= (val
& 0x1)
3738 | (((val
>> 1 ) & 0x7) << 7)
3739 | (((val
>> 4 ) & 0x1f) << 20);
3743 s3_do16_slli_srli (char *str
)
3745 s3_skip_whitespace (str
);
3747 if ((s3_reglow_required_here (&str
, 5) == (int) s3_FAIL
)
3748 || (s3_skip_past_comma (&str
) == (int) s3_FAIL
)
3749 || s3_data_op2 (&str
, 0, _IMM5
) == (int) s3_FAIL
3750 || s3_end_of_line (str
) == (int) s3_FAIL
)
3755 s3_do16_ldiu (char *str
)
3757 s3_skip_whitespace (str
);
3759 if ((s3_reg_required_here (&str
, 5,s3_REG_TYPE_SCORE
) == (int) s3_FAIL
)
3760 || (s3_skip_past_comma (&str
) == (int) s3_FAIL
)
3761 || s3_data_op2 (&str
, 0, _IMM5
) == (int) s3_FAIL
3762 || s3_end_of_line (str
) == (int) s3_FAIL
)
3767 s3_do16_push_pop (char *str
)
3769 s3_skip_whitespace (str
);
3770 if ((s3_reg_required_here (&str
, 0, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
3771 || s3_end_of_line (str
) == (int) s3_FAIL
)
3776 s3_do16_rpush (char *str
)
3780 s3_skip_whitespace (str
);
3781 if ((reg
= (s3_reg_required_here (&str
, 5, s3_REG_TYPE_SCORE
))) == (int) s3_FAIL
3782 || s3_skip_past_comma (&str
) == (int) s3_FAIL
3783 || s3_data_op2 (&str
, 0, _IMM5_MULTI_LOAD
) == (int) s3_FAIL
3784 || s3_end_of_line (str
) == (int) s3_FAIL
)
3789 2: to 31: normal value. */
3790 val
= s3_inst
.instruction
& 0x1f;
3793 s3_inst
.error
= _("imm5 should >= 2");
3798 s3_inst
.error
= _("reg should <= 31");
3804 s3_do16_rpop (char *str
)
3808 s3_skip_whitespace (str
);
3809 if ((reg
= (s3_reg_required_here (&str
, 5, s3_REG_TYPE_SCORE
))) == (int) s3_FAIL
3810 || s3_skip_past_comma (&str
) == (int) s3_FAIL
3811 || s3_data_op2 (&str
, 0, _IMM5_MULTI_LOAD
) == (int) s3_FAIL
3812 || s3_end_of_line (str
) == (int) s3_FAIL
)
3817 2: to 31: normal value. */
3818 val
= s3_inst
.instruction
& 0x1f;
3821 s3_inst
.error
= _("imm5 should >= 2");
3827 s3_inst
.error
= _("reg should <= 31");
3832 if ((reg
+ val
) <= 32)
3833 reg
= reg
+ val
- 1;
3835 reg
= reg
+ val
- 33;
3836 s3_inst
.instruction
&= 0x7c1f;
3837 s3_inst
.instruction
|= (reg
<< 5);
3842 /* Handle lcb/lcw/lce/scb/scw/sce. */
3844 s3_do_ldst_unalign (char *str
)
3848 if (s3_university_version
== 1)
3850 s3_inst
.error
= s3_ERR_FOR_SCORE5U_ATOMIC
;
3854 s3_skip_whitespace (str
);
3856 /* lcb/scb [rA]+. */
3860 s3_skip_whitespace (str
);
3862 if (s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
)
3869 s3_inst
.error
= _("missing +");
3875 s3_inst
.error
= _("missing ]");
3879 if (s3_end_of_line (str
) == (int) s3_FAIL
)
3882 /* lcw/lce/scb/sce rD, [rA]+. */
3885 if (((conflict_reg
= s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
)
3886 || (s3_skip_past_comma (&str
) == (int) s3_FAIL
))
3891 s3_skip_whitespace (str
);
3896 s3_skip_whitespace (str
);
3897 if ((reg
= s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
)
3902 /* Conflicts can occur on stores as well as loads. */
3903 conflict_reg
= (conflict_reg
== reg
);
3904 s3_skip_whitespace (str
);
3907 unsigned int ldst_func
= s3_inst
.instruction
& LDST_UNALIGN_MASK
;
3913 as_warn (_("%s register same as write-back base"),
3914 ((ldst_func
& UA_LCE
) || (ldst_func
& UA_LCW
)
3915 ? _("destination") : _("source")));
3920 s3_inst
.error
= _("missing +");
3924 if (s3_end_of_line (str
) == (int) s3_FAIL
)
3929 s3_inst
.error
= _("missing ]");
3935 s3_inst
.error
= s3_BAD_ARGS
;
3941 /* Handle alw/asw. */
3943 s3_do_ldst_atomic (char *str
)
3945 if (s3_university_version
== 1)
3947 s3_inst
.error
= s3_ERR_FOR_SCORE5U_ATOMIC
;
3951 s3_skip_whitespace (str
);
3953 if ((s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
)
3954 || (s3_skip_past_comma (&str
) == (int) s3_FAIL
))
3961 s3_skip_whitespace (str
);
3966 s3_skip_whitespace (str
);
3967 if ((reg
= s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
)
3972 s3_skip_whitespace (str
);
3975 s3_inst
.error
= _("missing ]");
3979 s3_end_of_line (str
);
3982 s3_inst
.error
= s3_BAD_ARGS
;
3987 s3_build_relax_frag (struct s3_score_it fix_insts
[s3_RELAX_INST_NUM
], int fix_num ATTRIBUTE_UNUSED
,
3988 struct s3_score_it var_insts
[s3_RELAX_INST_NUM
], int var_num
,
3989 symbolS
*add_symbol
)
3994 fixS
*cur_fixp
= NULL
;
3996 struct s3_score_it inst_main
;
3998 memcpy (&inst_main
, &fix_insts
[0], sizeof (struct s3_score_it
));
4000 /* Adjust instruction opcode and to be relaxed instruction opcode. */
4001 inst_main
.instruction
= s3_adjust_paritybit (inst_main
.instruction
, s3_GET_INSN_CLASS (inst_main
.type
));
4002 inst_main
.type
= Insn_PIC
;
4004 for (i
= 0; i
< var_num
; i
++)
4006 inst_main
.relax_size
+= var_insts
[i
].size
;
4007 var_insts
[i
].instruction
= s3_adjust_paritybit (var_insts
[i
].instruction
,
4008 s3_GET_INSN_CLASS (var_insts
[i
].type
));
4011 /* Check data dependency. */
4012 s3_handle_dependency (&inst_main
);
4014 /* Start a new frag if frag_now is not empty. */
4015 if (frag_now_fix () != 0)
4017 if (!frag_now
->tc_frag_data
.is_insn
)
4019 frag_wane (frag_now
);
4025 /* Write fr_fix part. */
4026 p
= frag_more (inst_main
.size
);
4027 s3_md_number_to_chars (p
, inst_main
.instruction
, inst_main
.size
);
4029 if (inst_main
.reloc
.type
!= BFD_RELOC_NONE
)
4030 fixp
= s3_fix_new_score (frag_now
, p
- frag_now
->fr_literal
, inst_main
.size
,
4031 &inst_main
.reloc
.exp
, inst_main
.reloc
.pc_rel
, inst_main
.reloc
.type
);
4033 frag_now
->tc_frag_data
.fixp
= fixp
;
4034 cur_fixp
= frag_now
->tc_frag_data
.fixp
;
4037 dwarf2_emit_insn (inst_main
.size
);
4040 where
= p
- frag_now
->fr_literal
+ inst_main
.size
;
4041 for (i
= 0; i
< var_num
; i
++)
4044 where
+= var_insts
[i
- 1].size
;
4046 if (var_insts
[i
].reloc
.type
!= BFD_RELOC_NONE
)
4048 fixp
= s3_fix_new_score (frag_now
, where
, var_insts
[i
].size
,
4049 &var_insts
[i
].reloc
.exp
, var_insts
[i
].reloc
.pc_rel
,
4050 var_insts
[i
].reloc
.type
);
4055 cur_fixp
->fx_next
= fixp
;
4056 cur_fixp
= cur_fixp
->fx_next
;
4060 frag_now
->tc_frag_data
.fixp
= fixp
;
4061 cur_fixp
= frag_now
->tc_frag_data
.fixp
;
4067 p
= frag_var (rs_machine_dependent
, inst_main
.relax_size
+ s3_RELAX_PAD_BYTE
, 0,
4068 s3_RELAX_ENCODE (inst_main
.size
, inst_main
.relax_size
, inst_main
.type
,
4069 0, inst_main
.size
, 0), add_symbol
, 0, NULL
);
4071 /* Write fr_var part.
4072 no calling s3_gen_insn_frag, no fixS will be generated. */
4073 for (i
= 0; i
< var_num
; i
++)
4075 s3_md_number_to_chars (p
, var_insts
[i
].instruction
, var_insts
[i
].size
);
4076 p
+= var_insts
[i
].size
;
4078 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4082 /* Build a relax frag for la instruction when generating s3_PIC,
4083 external symbol first and local symbol second. */
4085 s3_build_la_pic (int reg_rd
, expressionS exp
)
4087 symbolS
*add_symbol
= exp
.X_add_symbol
;
4088 offsetT add_number
= exp
.X_add_number
;
4089 struct s3_score_it fix_insts
[s3_RELAX_INST_NUM
];
4090 struct s3_score_it var_insts
[s3_RELAX_INST_NUM
];
4093 char tmp
[s3_MAX_LITERAL_POOL_SIZE
];
4099 if (add_number
== 0)
4104 /* For an external symbol, only one insn is generated;
4105 For a local symbol, two insns are generated. */
4107 For an external symbol: lw rD, <sym>($gp)
4108 (BFD_RELOC_SCORE_GOT15 or BFD_RELOC_SCORE_CALL15) */
4109 sprintf (tmp
, "lw_pic r%d, %s", reg_rd
, add_symbol
->bsym
->name
);
4110 if (s3_append_insn (tmp
, FALSE
) == (int) s3_FAIL
)
4113 if (reg_rd
== s3_PIC_CALL_REG
)
4114 s3_inst
.reloc
.type
= BFD_RELOC_SCORE_CALL15
;
4115 memcpy (&fix_insts
[0], &s3_inst
, sizeof (struct s3_score_it
));
4118 For a local symbol :
4119 lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15)
4120 addi rD, <sym> (BFD_RELOC_GOT_LO16) */
4121 s3_inst
.reloc
.type
= BFD_RELOC_SCORE_GOT15
;
4122 memcpy (&var_insts
[0], &s3_inst
, sizeof (struct s3_score_it
));
4123 sprintf (tmp
, "addi_s_pic r%d, %s", reg_rd
, add_symbol
->bsym
->name
);
4124 if (s3_append_insn (tmp
, FALSE
) == (int) s3_FAIL
)
4127 memcpy (&var_insts
[1], &s3_inst
, sizeof (struct s3_score_it
));
4128 s3_build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
4130 else if (add_number
>= -0x8000 && add_number
<= 0x7fff)
4132 /* Insn 1: lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15) */
4133 sprintf (tmp
, "lw_pic r%d, %s", reg_rd
, add_symbol
->bsym
->name
);
4134 if (s3_append_insn (tmp
, TRUE
) == (int) s3_FAIL
)
4141 For an external symbol: addi rD, <constant> */
4142 sprintf (tmp
, "addi r%d, %d", reg_rd
, (int)add_number
);
4143 if (s3_append_insn (tmp
, FALSE
) == (int) s3_FAIL
)
4146 memcpy (&fix_insts
[0], &s3_inst
, sizeof (struct s3_score_it
));
4149 For a local symbol: addi rD, <sym>+<constant> (BFD_RELOC_GOT_LO16) */
4150 sprintf (tmp
, "addi_s_pic r%d, %s + %d", reg_rd
, add_symbol
->bsym
->name
, (int)add_number
);
4151 if (s3_append_insn (tmp
, FALSE
) == (int) s3_FAIL
)
4154 memcpy (&var_insts
[0], &s3_inst
, sizeof (struct s3_score_it
));
4155 s3_build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
4159 int hi
= (add_number
>> 16) & 0x0000FFFF;
4160 int lo
= add_number
& 0x0000FFFF;
4162 /* Insn 1: lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15) */
4163 sprintf (tmp
, "lw_pic r%d, %s", reg_rd
, add_symbol
->bsym
->name
);
4164 if (s3_append_insn (tmp
, TRUE
) == (int) s3_FAIL
)
4171 For an external symbol: ldis r1, HI%<constant> */
4172 sprintf (tmp
, "ldis r1, %d", hi
);
4173 if (s3_append_insn (tmp
, FALSE
) == (int) s3_FAIL
)
4176 memcpy (&fix_insts
[0], &s3_inst
, sizeof (struct s3_score_it
));
4179 For a local symbol: ldis r1, HI%<constant>
4180 but, if lo is outof 16 bit, make hi plus 1 */
4181 if ((lo
< -0x8000) || (lo
> 0x7fff))
4185 sprintf (tmp
, "ldis_pic r1, %d", hi
);
4186 if (s3_append_insn (tmp
, FALSE
) == (int) s3_FAIL
)
4189 memcpy (&var_insts
[0], &s3_inst
, sizeof (struct s3_score_it
));
4190 s3_build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
4196 For an external symbol: ori r1, LO%<constant> */
4197 sprintf (tmp
, "ori r1, %d", lo
);
4198 if (s3_append_insn (tmp
, FALSE
) == (int) s3_FAIL
)
4201 memcpy (&fix_insts
[0], &s3_inst
, sizeof (struct s3_score_it
));
4204 For a local symbol: addi r1, <sym>+LO%<constant> (BFD_RELOC_GOT_LO16) */
4205 sprintf (tmp
, "addi_u_pic r1, %s + %d", add_symbol
->bsym
->name
, lo
);
4206 if (s3_append_insn (tmp
, FALSE
) == (int) s3_FAIL
)
4209 memcpy (&var_insts
[0], &s3_inst
, sizeof (struct s3_score_it
));
4210 s3_build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
4212 /* Insn 4: add rD, rD, r1 */
4213 sprintf (tmp
, "add r%d, r%d, r1", reg_rd
, reg_rd
);
4214 if (s3_append_insn (tmp
, TRUE
) == (int) s3_FAIL
)
4217 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4226 s3_do_macro_la_rdi32 (char *str
)
4230 s3_skip_whitespace (str
);
4231 if ((reg_rd
= s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
4232 || s3_skip_past_comma (&str
) == (int) s3_FAIL
)
4239 char *keep_data
= str
;
4240 char append_str
[s3_MAX_LITERAL_POOL_SIZE
];
4242 /* Check immediate value. */
4243 if (s3_my_get_expression (&s3_inst
.reloc
.exp
, &str
) == (int) s3_FAIL
)
4245 s3_inst
.error
= _("expression error");
4248 else if ((s3_inst
.reloc
.exp
.X_add_symbol
== NULL
)
4249 && (s3_validate_immediate (s3_inst
.reloc
.exp
.X_add_number
, _IMM32
, 0) == (int) s3_FAIL
))
4251 s3_inst
.error
= _("value not in range [0, 0xffffffff]");
4258 /* la rd, simm16. */
4259 if (s3_data_op2 (&str
, 1, _SIMM16_LA
) != (int) s3_FAIL
)
4261 s3_end_of_line (str
);
4264 /* la rd, imm32 or la rd, label. */
4267 s3_SET_INSN_ERROR (NULL
);
4270 if ((s3_data_op2 (&str
, 1, _VALUE_HI16
) == (int) s3_FAIL
)
4271 || (s3_end_of_line (str
) == (int) s3_FAIL
))
4277 if ((s3_score_pic
== s3_NO_PIC
) || (!s3_inst
.reloc
.exp
.X_add_symbol
))
4279 sprintf (append_str
, "ld_i32hi r%d, %s", reg_rd
, keep_data
);
4280 if (s3_append_insn (append_str
, TRUE
) == (int) s3_FAIL
)
4283 sprintf (append_str
, "ld_i32lo r%d, %s", reg_rd
, keep_data
);
4284 if (s3_append_insn (append_str
, TRUE
) == (int) s3_FAIL
)
4289 gas_assert (s3_inst
.reloc
.exp
.X_add_symbol
);
4290 s3_build_la_pic (reg_rd
, s3_inst
.reloc
.exp
);
4293 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4302 s3_do_macro_li_rdi32 (char *str
)
4307 s3_skip_whitespace (str
);
4308 if ((reg_rd
= s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
4309 || s3_skip_past_comma (&str
) == (int) s3_FAIL
)
4316 char *keep_data
= str
;
4318 /* Check immediate value. */
4319 if (s3_my_get_expression (&s3_inst
.reloc
.exp
, &str
) == (int) s3_FAIL
)
4321 s3_inst
.error
= _("expression error");
4324 else if (!(s3_inst
.reloc
.exp
.X_add_number
>= -0xffffffffLL
4325 && s3_inst
.reloc
.exp
.X_add_number
<= 0xffffffffLL
))
4327 s3_inst
.error
= _("value not in range [-0xffffffff, 0xffffffff]");
4334 /* li rd, simm16. */
4335 if (s3_data_op2 (&str
, 1, _SIMM16_LA
) != (int) s3_FAIL
)
4337 s3_end_of_line (str
);
4343 char append_str
[s3_MAX_LITERAL_POOL_SIZE
];
4348 if ((s3_data_op2 (&str
, 1, _VALUE_HI16
) == (int) s3_FAIL
)
4349 || (s3_end_of_line (str
) == (int) s3_FAIL
))
4353 else if (s3_inst
.reloc
.exp
.X_add_symbol
)
4355 s3_inst
.error
= _("li rd label isn't correct instruction form");
4360 sprintf (append_str
, "ld_i32hi r%d, %s", reg_rd
, keep_data
);
4362 if (s3_append_insn (append_str
, TRUE
) == (int) s3_FAIL
)
4366 sprintf (append_str
, "ld_i32lo r%d, %s", reg_rd
, keep_data
);
4367 if (s3_append_insn (append_str
, TRUE
) == (int) s3_FAIL
)
4370 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4378 /* Handle mul/mulu/div/divu/rem/remu. */
4380 s3_do_macro_mul_rdrsrs (char *str
)
4386 char append_str
[s3_MAX_LITERAL_POOL_SIZE
];
4388 if (s3_university_version
== 1)
4389 as_warn ("%s", s3_ERR_FOR_SCORE5U_MUL_DIV
);
4391 strcpy (append_str
, str
);
4392 backupstr
= append_str
;
4393 s3_skip_whitespace (backupstr
);
4394 if (((reg_rd
= s3_reg_required_here (&backupstr
, -1, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
)
4395 || (s3_skip_past_comma (&backupstr
) == (int) s3_FAIL
)
4396 || ((reg_rs1
= s3_reg_required_here (&backupstr
, -1, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
))
4398 s3_inst
.error
= s3_BAD_ARGS
;
4402 if (s3_skip_past_comma (&backupstr
) == (int) s3_FAIL
)
4404 /* rem/remu rA, rB is error format. */
4405 if (strcmp (s3_inst
.name
, "rem") == 0 || strcmp (s3_inst
.name
, "remu") == 0)
4407 s3_SET_INSN_ERROR (s3_BAD_ARGS
);
4411 s3_SET_INSN_ERROR (NULL
);
4418 s3_SET_INSN_ERROR (NULL
);
4419 if (((reg_rs2
= s3_reg_required_here (&backupstr
, -1, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
)
4420 || (s3_end_of_line (backupstr
) == (int) s3_FAIL
))
4426 char append_str1
[s3_MAX_LITERAL_POOL_SIZE
];
4428 if (strcmp (s3_inst
.name
, "rem") == 0)
4430 sprintf (append_str
, "mul r%d, r%d", reg_rs1
, reg_rs2
);
4431 sprintf (append_str1
, "mfceh r%d", reg_rd
);
4433 else if (strcmp (s3_inst
.name
, "remu") == 0)
4435 sprintf (append_str
, "mulu r%d, r%d", reg_rs1
, reg_rs2
);
4436 sprintf (append_str1
, "mfceh r%d", reg_rd
);
4440 sprintf (append_str
, "%s r%d, r%d", s3_inst
.name
, reg_rs1
, reg_rs2
);
4441 sprintf (append_str1
, "mfcel r%d", reg_rd
);
4444 /* Output mul/mulu or div/divu or rem/remu. */
4445 if (s3_append_insn (append_str
, TRUE
) == (int) s3_FAIL
)
4448 /* Output mfcel or mfceh. */
4449 if (s3_append_insn (append_str1
, TRUE
) == (int) s3_FAIL
)
4452 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4459 s3_exp_macro_ldst_abs (char *str
)
4462 char *backupstr
, *tmp
;
4463 char append_str
[s3_MAX_LITERAL_POOL_SIZE
];
4464 char verifystr
[s3_MAX_LITERAL_POOL_SIZE
];
4465 struct s3_score_it inst_backup
;
4470 memcpy (&inst_backup
, &s3_inst
, sizeof (struct s3_score_it
));
4472 strcpy (verifystr
, str
);
4473 backupstr
= verifystr
;
4474 s3_skip_whitespace (backupstr
);
4475 if ((reg_rd
= s3_reg_required_here (&backupstr
, -1, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
)
4479 if (s3_skip_past_comma (&backupstr
) == (int) s3_FAIL
)
4483 sprintf (append_str
, "li r1 %s", backupstr
);
4484 s3_append_insn (append_str
, TRUE
);
4486 memcpy (&s3_inst
, &inst_backup
, sizeof (struct s3_score_it
));
4487 sprintf (append_str
, " r%d, [r1,0]", reg_rd
);
4488 s3_do_ldst_insn (append_str
);
4492 /* Handle bcmpeq / bcmpne */
4494 s3_do_macro_bcmp (char *str
)
4497 char keep_data
[s3_MAX_LITERAL_POOL_SIZE
];
4500 struct s3_score_it inst_expand
[2];
4501 struct s3_score_it inst_main
;
4504 s3_skip_whitespace (str
);
4505 if (( reg_a
= s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
4506 || s3_skip_past_comma (&str
) == (int) s3_FAIL
4507 ||(reg_b
= s3_reg_required_here (&str
, 10, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
4508 || s3_skip_past_comma (&str
) == (int) s3_FAIL
)
4513 keep_data
[i
]=*ptemp
;
4518 if (s3_my_get_expression (&s3_inst
.reloc
.exp
, &str
) == (int) s3_FAIL
4520 || s3_end_of_line (str
) == (int) s3_FAIL
)
4522 else if (s3_inst
.reloc
.exp
.X_add_symbol
== 0)
4524 s3_inst
.error
= _("lacking label ");
4529 char append_str
[s3_MAX_LITERAL_POOL_SIZE
];
4530 s3_SET_INSN_ERROR (NULL
);
4532 s3_inst
.reloc
.type
= BFD_RELOC_SCORE_BCMP
;
4533 s3_inst
.reloc
.pc_rel
= 1;
4534 bfd_signed_vma val
= s3_inst
.reloc
.exp
.X_add_number
;
4536 /* Branch 32 offset field : 20 bit, 16 bit branch offset field : 8 bit. */
4537 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;
4539 /* Check and set offset. */
4540 if (((val
& 0xfffffe00) != 0)
4541 && ((val
& 0xfffffe00) != 0xfffffe00))
4543 /* support bcmp --> cmp!+beq (bne) */
4544 if (s3_score_pic
== s3_NO_PIC
)
4546 sprintf (&append_str
[0], "cmp! r%d, r%d", reg_a
, reg_b
);
4547 if (s3_append_insn (&append_str
[0], TRUE
) == (int) s3_FAIL
)
4549 if ((inst_main
.instruction
& 0x3e00007e) == 0x0000004c)
4550 sprintf (&append_str
[1], "beq %s", keep_data
);
4552 sprintf (&append_str
[1], "bne %s", keep_data
);
4553 if (s3_append_insn (&append_str
[1], TRUE
) == (int) s3_FAIL
)
4558 gas_assert (s3_inst
.reloc
.exp
.X_add_symbol
);
4560 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4567 s3_inst
.instruction
|= (val
& 0x1)
4568 | (((val
>> 1) & 0x7) << 7)
4569 | (((val
>> 4) & 0x1f) << 20);
4572 /* Backup s3_inst. */
4573 memcpy (&inst_main
, &s3_inst
, sizeof (struct s3_score_it
));
4575 if (s3_score_pic
== s3_NO_PIC
)
4577 sprintf (&append_str
[0], "cmp! r%d, r%d", reg_a
, reg_b
);
4578 if (s3_append_insn (&append_str
[0], FALSE
) == (int) s3_FAIL
)
4580 memcpy (&inst_expand
[0], &s3_inst
, sizeof (struct s3_score_it
));
4582 if ((inst_main
.instruction
& 0x3e00007e) == 0x0000004c)
4583 sprintf (&append_str
[1], "beq %s", keep_data
);
4585 sprintf (&append_str
[1], "bne %s", keep_data
);
4586 if (s3_append_insn (&append_str
[1], FALSE
) == (int) s3_FAIL
)
4588 memcpy (&inst_expand
[1], &s3_inst
, sizeof (struct s3_score_it
));
4592 gas_assert (s3_inst
.reloc
.exp
.X_add_symbol
);
4594 inst_main
.relax_size
= inst_expand
[0].size
+ inst_expand
[1].size
;
4595 inst_main
.type
= Insn_BCMP
;
4597 /* Adjust instruction opcode and to be relaxed instruction opcode. */
4598 inst_main
.instruction
= s3_adjust_paritybit (inst_main
.instruction
, s3_GET_INSN_CLASS (inst_main
.type
));
4600 for (i
= 0; i
< 2; i
++)
4601 inst_expand
[i
].instruction
= s3_adjust_paritybit (inst_expand
[i
].instruction
,
4602 s3_GET_INSN_CLASS (inst_expand
[i
].type
));
4603 /* Check data dependency. */
4604 s3_handle_dependency (&inst_main
);
4605 /* Start a new frag if frag_now is not empty. */
4606 if (frag_now_fix () != 0)
4608 if (!frag_now
->tc_frag_data
.is_insn
)
4609 frag_wane (frag_now
);
4614 /* Write fr_fix part. */
4616 p
= frag_more (inst_main
.size
);
4617 s3_md_number_to_chars (p
, inst_main
.instruction
, inst_main
.size
);
4619 if (inst_main
.reloc
.type
!= BFD_RELOC_NONE
)
4621 s3_fix_new_score (frag_now
, p
- frag_now
->fr_literal
, inst_main
.size
,
4622 &inst_main
.reloc
.exp
, inst_main
.reloc
.pc_rel
, inst_main
.reloc
.type
);
4625 dwarf2_emit_insn (inst_main
.size
);
4628 /* s3_GP instruction can not do optimization, only can do relax between
4629 1 instruction and 3 instructions. */
4630 p
= frag_var (rs_machine_dependent
, inst_main
.relax_size
+ s3_RELAX_PAD_BYTE
, 0,
4631 s3_RELAX_ENCODE (inst_main
.size
, inst_main
.relax_size
, inst_main
.type
, 0, 4, 1),
4632 inst_main
.reloc
.exp
.X_add_symbol
, 0, NULL
);
4634 /* Write fr_var part.
4635 no calling s3_gen_insn_frag, no fixS will be generated. */
4636 s3_md_number_to_chars (p
, inst_expand
[0].instruction
, inst_expand
[0].size
);
4637 p
+= inst_expand
[0].size
;
4638 s3_md_number_to_chars (p
, inst_expand
[1].instruction
, inst_expand
[1].size
);
4639 p
+= inst_expand
[1].size
;
4641 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4646 /* Handle bcmpeqz / bcmpnez */
4648 s3_do_macro_bcmpz (char *str
)
4651 char keep_data
[s3_MAX_LITERAL_POOL_SIZE
];
4654 struct s3_score_it inst_expand
[2];
4655 struct s3_score_it inst_main
;
4657 s3_skip_whitespace (str
);
4658 if (( reg_a
= s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
4659 || s3_skip_past_comma (&str
) == (int) s3_FAIL
)
4664 keep_data
[i
]=*ptemp
;
4669 if ( s3_my_get_expression (&s3_inst
.reloc
.exp
, &str
) == (int) s3_FAIL
4670 || s3_end_of_line (str
) == (int) s3_FAIL
)
4673 else if (s3_inst
.reloc
.exp
.X_add_symbol
== 0)
4675 s3_inst
.error
= _("lacking label ");
4680 char append_str
[s3_MAX_LITERAL_POOL_SIZE
];
4681 s3_SET_INSN_ERROR (NULL
);
4682 s3_inst
.reloc
.type
= BFD_RELOC_SCORE_BCMP
;
4683 s3_inst
.reloc
.pc_rel
= 1;
4684 bfd_signed_vma val
= s3_inst
.reloc
.exp
.X_add_number
;
4686 /* Branch 32 offset field : 20 bit, 16 bit branch offset field : 8 bit. */
4687 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;
4689 /* Check and set offset. */
4690 if (((val
& 0xfffffe00) != 0)
4691 && ((val
& 0xfffffe00) != 0xfffffe00))
4693 if (s3_score_pic
== s3_NO_PIC
)
4695 sprintf (&append_str
[0], "cmpi! r%d,0", reg_a
);
4696 if (s3_append_insn (&append_str
[0], TRUE
) == (int) s3_FAIL
)
4698 if ((inst_main
.instruction
& 0x3e00007e) == 0x0000004c)
4699 sprintf (&append_str
[1], "beq %s", keep_data
);
4701 sprintf (&append_str
[1], "bne %s", keep_data
);
4702 if (s3_append_insn (&append_str
[1], TRUE
) == (int) s3_FAIL
)
4707 gas_assert (s3_inst
.reloc
.exp
.X_add_symbol
);
4709 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4716 s3_inst
.instruction
|= (val
& 0x1)
4717 | (((val
>> 1) & 0x7) << 7)
4718 | (((val
>> 4) & 0x1f) << 20);
4721 /* Backup s3_inst. */
4722 memcpy (&inst_main
, &s3_inst
, sizeof (struct s3_score_it
));
4724 if (s3_score_pic
== s3_NO_PIC
)
4726 sprintf (&append_str
[0], "cmpi! r%d, 0", reg_a
);
4727 if (s3_append_insn (&append_str
[0], FALSE
) == (int) s3_FAIL
)
4729 memcpy (&inst_expand
[0], &s3_inst
, sizeof (struct s3_score_it
));
4730 if ((inst_main
.instruction
& 0x3e00007e) == 0x0000004c)
4731 sprintf (&append_str
[1], "beq %s", keep_data
);
4733 sprintf (&append_str
[1], "bne %s", keep_data
);
4734 if (s3_append_insn (&append_str
[1], FALSE
) == (int) s3_FAIL
)
4736 memcpy (&inst_expand
[1], &s3_inst
, sizeof (struct s3_score_it
));
4740 gas_assert (s3_inst
.reloc
.exp
.X_add_symbol
);
4742 inst_main
.relax_size
= inst_expand
[0].size
+ inst_expand
[1].size
;
4743 inst_main
.type
= Insn_BCMP
;
4745 /* Adjust instruction opcode and to be relaxed instruction opcode. */
4746 inst_main
.instruction
= s3_adjust_paritybit (inst_main
.instruction
, s3_GET_INSN_CLASS (inst_main
.type
));
4748 for (i
= 0; i
< 2; i
++)
4749 inst_expand
[i
].instruction
= s3_adjust_paritybit (inst_expand
[i
].instruction
, s3_GET_INSN_CLASS (inst_expand
[i
].type
));
4750 /* Check data dependency. */
4751 s3_handle_dependency (&inst_main
);
4752 /* Start a new frag if frag_now is not empty. */
4753 if (frag_now_fix () != 0)
4755 if (!frag_now
->tc_frag_data
.is_insn
)
4756 frag_wane (frag_now
);
4761 /* Write fr_fix part. */
4763 p
= frag_more (inst_main
.size
);
4764 s3_md_number_to_chars (p
, inst_main
.instruction
, inst_main
.size
);
4766 if (inst_main
.reloc
.type
!= BFD_RELOC_NONE
)
4768 s3_fix_new_score (frag_now
, p
- frag_now
->fr_literal
, inst_main
.size
,
4769 &inst_main
.reloc
.exp
, inst_main
.reloc
.pc_rel
, inst_main
.reloc
.type
);
4772 dwarf2_emit_insn (inst_main
.size
);
4775 /* s3_GP instruction can not do optimization, only can do relax between
4776 1 instruction and 3 instructions. */
4777 p
= frag_var (rs_machine_dependent
, inst_main
.relax_size
+ s3_RELAX_PAD_BYTE
, 0,
4778 s3_RELAX_ENCODE (inst_main
.size
, inst_main
.relax_size
, inst_main
.type
, 0, 4, 1),
4779 inst_main
.reloc
.exp
.X_add_symbol
, 0, NULL
);
4781 /* Write fr_var part.
4782 no calling s3_gen_insn_frag, no fixS will be generated. */
4783 s3_md_number_to_chars (p
, inst_expand
[0].instruction
, inst_expand
[0].size
);
4784 p
+= inst_expand
[0].size
;
4785 s3_md_number_to_chars (p
, inst_expand
[1].instruction
, inst_expand
[1].size
);
4786 p
+= inst_expand
[1].size
;
4788 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4794 s3_nopic_need_relax (symbolS
* sym
, int before_relaxing
)
4798 else if (s3_USE_GLOBAL_POINTER_OPT
&& s3_g_switch_value
> 0)
4800 const char *symname
;
4801 const char *segname
;
4803 /* Find out whether this symbol can be referenced off the $gp
4804 register. It can be if it is smaller than the -G size or if
4805 it is in the .sdata or .sbss section. Certain symbols can
4806 not be referenced off the $gp, although it appears as though
4808 symname
= S_GET_NAME (sym
);
4809 if (symname
!= (const char *)NULL
4810 && (strcmp (symname
, "eprol") == 0
4811 || strcmp (symname
, "etext") == 0
4812 || strcmp (symname
, "_gp") == 0
4813 || strcmp (symname
, "edata") == 0
4814 || strcmp (symname
, "_fbss") == 0
4815 || strcmp (symname
, "_fdata") == 0
4816 || strcmp (symname
, "_ftext") == 0
4817 || strcmp (symname
, "end") == 0
4818 || strcmp (symname
, GP_DISP_LABEL
) == 0))
4822 else if ((!S_IS_DEFINED (sym
) || S_IS_COMMON (sym
)) && (0
4823 /* We must defer this decision until after the whole file has been read,
4824 since there might be a .extern after the first use of this symbol. */
4826 && S_GET_VALUE (sym
) == 0)
4827 || (S_GET_VALUE (sym
) != 0
4828 && S_GET_VALUE (sym
) <= s3_g_switch_value
)))
4833 segname
= segment_name (S_GET_SEGMENT (sym
));
4834 return (strcmp (segname
, ".sdata") != 0
4835 && strcmp (segname
, ".sbss") != 0
4836 && strncmp (segname
, ".sdata.", 7) != 0
4837 && strncmp (segname
, ".gnu.linkonce.s.", 16) != 0);
4839 /* We are not optimizing for the $gp register. */
4844 /* Build a relax frag for lw/st instruction when generating s3_PIC,
4845 external symbol first and local symbol second. */
4847 s3_build_lwst_pic (int reg_rd
, expressionS exp
, const char *insn_name
)
4849 symbolS
*add_symbol
= exp
.X_add_symbol
;
4850 int add_number
= exp
.X_add_number
;
4851 struct s3_score_it fix_insts
[s3_RELAX_INST_NUM
];
4852 struct s3_score_it var_insts
[s3_RELAX_INST_NUM
];
4855 char tmp
[s3_MAX_LITERAL_POOL_SIZE
];
4861 if ((add_number
== 0) || (add_number
>= -0x8000 && add_number
<= 0x7fff))
4866 /* For an external symbol, two insns are generated;
4867 For a local symbol, three insns are generated. */
4869 For an external symbol: lw rD, <sym>($gp)
4870 (BFD_RELOC_SCORE_GOT15) */
4871 sprintf (tmp
, "lw_pic r1, %s", add_symbol
->bsym
->name
);
4872 if (s3_append_insn (tmp
, FALSE
) == (int) s3_FAIL
)
4875 memcpy (&fix_insts
[0], &s3_inst
, sizeof (struct s3_score_it
));
4878 For a local symbol :
4879 lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15)
4880 addi rD, <sym> (BFD_RELOC_GOT_LO16) */
4881 s3_inst
.reloc
.type
= BFD_RELOC_SCORE_GOT15
;
4882 memcpy (&var_insts
[0], &s3_inst
, sizeof (struct s3_score_it
));
4883 sprintf (tmp
, "addi_s_pic r1, %s", add_symbol
->bsym
->name
);
4884 if (s3_append_insn (tmp
, FALSE
) == (int) s3_FAIL
)
4887 memcpy (&var_insts
[1], &s3_inst
, sizeof (struct s3_score_it
));
4888 s3_build_relax_frag (fix_insts
, fix_num
, var_insts
, var_num
, add_symbol
);
4890 /* Insn 2 or Insn 3: lw/st rD, [r1, constant] */
4891 sprintf (tmp
, "%s r%d, [r1, %d]", insn_name
, reg_rd
, add_number
);
4892 if (s3_append_insn (tmp
, TRUE
) == (int) s3_FAIL
)
4895 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4900 s3_inst
.error
= _("s3_PIC code offset overflow (max 16 signed bits)");
4908 s3_do_macro_ldst_label (char *str
)
4916 char *absolute_value
;
4917 char append_str
[3][s3_MAX_LITERAL_POOL_SIZE
];
4918 char verifystr
[s3_MAX_LITERAL_POOL_SIZE
];
4919 struct s3_score_it inst_backup
;
4920 struct s3_score_it inst_expand
[3];
4921 struct s3_score_it inst_main
;
4923 memcpy (&inst_backup
, &s3_inst
, sizeof (struct s3_score_it
));
4924 strcpy (verifystr
, str
);
4925 backup_str
= verifystr
;
4927 s3_skip_whitespace (backup_str
);
4928 if ((reg_rd
= s3_reg_required_here (&backup_str
, -1, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
)
4931 if (s3_skip_past_comma (&backup_str
) == (int) s3_FAIL
)
4934 label_str
= backup_str
;
4936 /* Ld/st rD, [rA, imm] ld/st rD, [rA]+, imm ld/st rD, [rA, imm]+. */
4937 if (*backup_str
== '[')
4939 s3_inst
.type
= Rd_rvalueRs_preSI12
;
4940 s3_do_ldst_insn (str
);
4944 /* Ld/st rD, imm. */
4945 absolute_value
= backup_str
;
4946 s3_inst
.type
= Rd_rvalueRs_SI15
;
4948 if (s3_my_get_expression (&s3_inst
.reloc
.exp
, &backup_str
) == (int) s3_FAIL
)
4950 s3_inst
.error
= _("expression error");
4953 else if ((s3_inst
.reloc
.exp
.X_add_symbol
== NULL
)
4954 && (s3_validate_immediate (s3_inst
.reloc
.exp
.X_add_number
, _VALUE
, 0) == (int) s3_FAIL
))
4956 s3_inst
.error
= _("value not in range [0, 0x7fffffff]");
4959 else if (s3_end_of_line (backup_str
) == (int) s3_FAIL
)
4961 s3_inst
.error
= _("end on line error");
4966 if (s3_inst
.reloc
.exp
.X_add_symbol
== 0)
4968 memcpy (&s3_inst
, &inst_backup
, sizeof (struct s3_score_it
));
4969 s3_exp_macro_ldst_abs (str
);
4974 /* Ld/st rD, label. */
4975 s3_inst
.type
= Rd_rvalueRs_SI15
;
4976 backup_str
= absolute_value
;
4977 if ((s3_data_op2 (&backup_str
, 1, _GP_IMM15
) == (int) s3_FAIL
)
4978 || (s3_end_of_line (backup_str
) == (int) s3_FAIL
))
4984 if (s3_inst
.reloc
.exp
.X_add_symbol
== 0)
4987 s3_inst
.error
= s3_BAD_ARGS
;
4992 if (s3_score_pic
== s3_PIC
)
4995 ldst_idx
= s3_inst
.instruction
& OPC_PSEUDOLDST_MASK
;
4996 s3_build_lwst_pic (reg_rd
, s3_inst
.reloc
.exp
, s3_score_ldst_insns
[ldst_idx
* 3 + 0].template);
5001 if ((s3_inst
.reloc
.exp
.X_add_number
<= 0x3fff)
5002 && (s3_inst
.reloc
.exp
.X_add_number
>= -0x4000)
5003 && (!s3_nopic_need_relax (s3_inst
.reloc
.exp
.X_add_symbol
, 1)))
5007 /* Assign the real opcode. */
5008 ldst_idx
= s3_inst
.instruction
& OPC_PSEUDOLDST_MASK
;
5009 s3_inst
.instruction
&= ~OPC_PSEUDOLDST_MASK
;
5010 s3_inst
.instruction
|= s3_score_ldst_insns
[ldst_idx
* 3 + 0].value
;
5011 s3_inst
.instruction
|= reg_rd
<< 20;
5012 s3_inst
.instruction
|= s3_GP
<< 15;
5013 s3_inst
.relax_inst
= 0x8000;
5014 s3_inst
.relax_size
= 0;
5020 /* Backup s3_inst. */
5021 memcpy (&inst_main
, &s3_inst
, sizeof (struct s3_score_it
));
5025 /* Determine which instructions should be output. */
5026 sprintf (append_str
[0], "ld_i32hi r1, %s", label_str
);
5027 sprintf (append_str
[1], "ld_i32lo r1, %s", label_str
);
5028 sprintf (append_str
[2], "%s r%d, [r1, 0]", inst_backup
.name
, reg_rd
);
5030 /* Generate three instructions.
5032 ld/st rd, [r1, 0] */
5033 for (i
= 0; i
< 3; i
++)
5035 if (s3_append_insn (append_str
[i
], FALSE
) == (int) s3_FAIL
)
5038 memcpy (&inst_expand
[i
], &s3_inst
, sizeof (struct s3_score_it
));
5045 /* Adjust instruction opcode and to be relaxed instruction opcode. */
5046 inst_main
.instruction
= s3_adjust_paritybit (inst_main
.instruction
, s3_GET_INSN_CLASS (inst_main
.type
));
5048 /* relax lw rd, label -> ldis rs, imm16
5050 lw rd, [rs, imm15] or lw! rd, [rs, imm5]. */
5051 if (inst_expand
[2].relax_size
== 0)
5052 inst_main
.relax_size
= inst_expand
[0].size
+ inst_expand
[1].size
+ inst_expand
[2].size
;
5054 inst_main
.relax_size
= inst_expand
[0].size
+ inst_expand
[1].size
+ inst_expand
[2].relax_size
;
5056 inst_main
.type
= Insn_GP
;
5058 for (i
= 0; i
< 3; i
++)
5059 inst_expand
[i
].instruction
= s3_adjust_paritybit (inst_expand
[i
].instruction
,
5060 s3_GET_INSN_CLASS (inst_expand
[i
].type
));
5062 /* Check data dependency. */
5063 s3_handle_dependency (&inst_main
);
5065 /* Start a new frag if frag_now is not empty. */
5066 if (frag_now_fix () != 0)
5068 if (!frag_now
->tc_frag_data
.is_insn
)
5069 frag_wane (frag_now
);
5075 /* Write fr_fix part. */
5076 p
= frag_more (inst_main
.size
);
5077 s3_md_number_to_chars (p
, inst_main
.instruction
, inst_main
.size
);
5079 if (inst_main
.reloc
.type
!= BFD_RELOC_NONE
)
5081 s3_fix_new_score (frag_now
, p
- frag_now
->fr_literal
, inst_main
.size
,
5082 &inst_main
.reloc
.exp
, inst_main
.reloc
.pc_rel
, inst_main
.reloc
.type
);
5086 dwarf2_emit_insn (inst_main
.size
);
5089 /* s3_GP instruction can not do optimization, only can do relax between
5090 1 instruction and 3 instructions. */
5091 p
= frag_var (rs_machine_dependent
, inst_main
.relax_size
+ s3_RELAX_PAD_BYTE
, 0,
5092 s3_RELAX_ENCODE (inst_main
.size
, inst_main
.relax_size
, inst_main
.type
, 0, 4, 0),
5093 inst_main
.reloc
.exp
.X_add_symbol
, 0, NULL
);
5095 /* Write fr_var part.
5096 no calling s3_gen_insn_frag, no fixS will be generated. */
5097 s3_md_number_to_chars (p
, inst_expand
[0].instruction
, inst_expand
[0].size
);
5098 p
+= inst_expand
[0].size
;
5099 s3_md_number_to_chars (p
, inst_expand
[1].instruction
, inst_expand
[1].size
);
5100 p
+= inst_expand
[1].size
;
5102 /* relax lw rd, label -> ldis rs, imm16
5104 lw rd, [rs, imm15] or lw! rd, [rs, imm5]. */
5105 if (inst_expand
[2].relax_size
== 0)
5106 s3_md_number_to_chars (p
, inst_expand
[2].instruction
, inst_expand
[2].size
);
5108 s3_md_number_to_chars (p
, inst_expand
[2].relax_inst
, inst_expand
[2].relax_size
);
5112 s3_gen_insn_frag (&inst_expand
[0], NULL
);
5113 s3_gen_insn_frag (&inst_expand
[1], NULL
);
5114 s3_gen_insn_frag (&inst_expand
[2], NULL
);
5118 /* Set bwarn as -1, so macro instruction itself will not be generated frag. */
5123 s3_do_lw_pic (char *str
)
5127 s3_skip_whitespace (str
);
5128 if (((reg_rd
= s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
)
5129 || (s3_skip_past_comma (&str
) == (int) s3_FAIL
)
5130 || (s3_my_get_expression (&s3_inst
.reloc
.exp
, &str
) == (int) s3_FAIL
)
5131 || (s3_end_of_line (str
) == (int) s3_FAIL
))
5137 if (s3_inst
.reloc
.exp
.X_add_symbol
== 0)
5140 s3_inst
.error
= s3_BAD_ARGS
;
5145 s3_inst
.instruction
|= s3_GP
<< 15;
5146 s3_inst
.reloc
.type
= BFD_RELOC_SCORE_GOT15
;
5151 s3_do_empty (char *str
)
5154 if (s3_university_version
== 1)
5156 if (((s3_inst
.instruction
& 0x3e0003ff) == 0x0c000004)
5157 || ((s3_inst
.instruction
& 0x3e0003ff) == 0x0c000024)
5158 || ((s3_inst
.instruction
& 0x3e0003ff) == 0x0c000044)
5159 || ((s3_inst
.instruction
& 0x3e0003ff) == 0x0c000064))
5161 s3_inst
.error
= s3_ERR_FOR_SCORE5U_MMU
;
5165 if (s3_end_of_line (str
) == (int) s3_FAIL
)
5168 if (s3_inst
.relax_inst
!= 0x8000)
5170 if (s3_inst
.type
== NO_OPD
)
5172 s3_inst
.relax_size
= 2;
5176 s3_inst
.relax_size
= 4;
5182 s3_do16_int (char *str
)
5184 s3_skip_whitespace (str
);
5189 s3_do_jump (char *str
)
5193 s3_skip_whitespace (str
);
5194 if (s3_my_get_expression (&s3_inst
.reloc
.exp
, &str
) == (int) s3_FAIL
5195 || s3_end_of_line (str
) == (int) s3_FAIL
)
5198 if (s3_inst
.reloc
.exp
.X_add_symbol
== 0)
5200 s3_inst
.error
= _("lacking label ");
5204 if (!(s3_inst
.reloc
.exp
.X_add_number
>= -16777216
5205 && s3_inst
.reloc
.exp
.X_add_number
<= 16777215))
5207 s3_inst
.error
= _("invalid constant: 25 bit expression not in range [-16777216, 16777215]");
5211 save_in
= input_line_pointer
;
5212 input_line_pointer
= str
;
5213 s3_inst
.reloc
.type
= BFD_RELOC_SCORE_JMP
;
5214 s3_inst
.reloc
.pc_rel
= 1;
5215 input_line_pointer
= save_in
;
5219 s3_do_branch (char *str
)
5221 if (s3_my_get_expression (&s3_inst
.reloc
.exp
, &str
) == (int) s3_FAIL
5222 || s3_end_of_line (str
) == (int) s3_FAIL
)
5226 else if (s3_inst
.reloc
.exp
.X_add_symbol
== 0)
5228 s3_inst
.error
= _("lacking label ");
5231 else if (!(s3_inst
.reloc
.exp
.X_add_number
>= -524288
5232 && s3_inst
.reloc
.exp
.X_add_number
<= 524287))
5234 s3_inst
.error
= _("invalid constant: 20 bit expression not in range -2^19..2^19");
5238 s3_inst
.reloc
.type
= BFD_RELOC_SCORE_BRANCH
;
5239 s3_inst
.reloc
.pc_rel
= 1;
5241 /* Branch 32 offset field : 20 bit, 16 bit branch offset field : 8 bit. */
5242 s3_inst
.instruction
|= (s3_inst
.reloc
.exp
.X_add_number
& 0x3fe) | ((s3_inst
.reloc
.exp
.X_add_number
& 0xffc00) << 5);
5244 /* Compute 16 bit branch instruction. */
5245 if ((s3_inst
.relax_inst
!= 0x8000)
5246 && (s3_inst
.reloc
.exp
.X_add_number
>= -512 && s3_inst
.reloc
.exp
.X_add_number
<= 511))
5248 s3_inst
.relax_inst
|= ((s3_inst
.reloc
.exp
.X_add_number
>> 1) & 0x1ff);/*b! :disp 9 bit */
5249 s3_inst
.relax_size
= 2;
5253 s3_inst
.relax_inst
= 0x8000;
5258 s3_do16_branch (char *str
)
5260 if ((s3_my_get_expression (&s3_inst
.reloc
.exp
, &str
) == (int) s3_FAIL
5261 || s3_end_of_line (str
) == (int) s3_FAIL
))
5265 else if (s3_inst
.reloc
.exp
.X_add_symbol
== 0)
5267 s3_inst
.error
= _("lacking label");
5269 else if (!(s3_inst
.reloc
.exp
.X_add_number
>= -512
5270 && s3_inst
.reloc
.exp
.X_add_number
<= 511))
5272 s3_inst
.error
= _("invalid constant: 10 bit expression not in range [-2^9, 2^9-1]");
5276 s3_inst
.reloc
.type
= BFD_RELOC_SCORE16_BRANCH
;
5277 s3_inst
.reloc
.pc_rel
= 1;
5278 s3_inst
.instruction
|= ((s3_inst
.reloc
.exp
.X_add_number
>> 1) & 0x1ff);
5279 s3_inst
.relax_inst
|= ((s3_inst
.reloc
.exp
.X_add_number
) & 0x1ff);
5280 s3_inst
.relax_size
= 4;
5284 /* Return true if the given symbol should be considered local for s3_PIC. */
5286 s3_pic_need_relax (symbolS
*sym
, asection
*segtype
)
5289 bfd_boolean linkonce
;
5291 /* Handle the case of a symbol equated to another symbol. */
5292 while (symbol_equated_reloc_p (sym
))
5296 /* It's possible to get a loop here in a badly written
5298 n
= symbol_get_value_expression (sym
)->X_add_symbol
;
5304 symsec
= S_GET_SEGMENT (sym
);
5306 /* duplicate the test for LINK_ONCE sections as in adjust_reloc_syms */
5308 if (symsec
!= segtype
&& ! S_IS_LOCAL (sym
))
5310 if ((bfd_get_section_flags (stdoutput
, symsec
) & SEC_LINK_ONCE
) != 0)
5313 /* The GNU toolchain uses an extension for ELF: a section
5314 beginning with the magic string .gnu.linkonce is a linkonce
5316 if (strncmp (segment_name (symsec
), ".gnu.linkonce",
5317 sizeof ".gnu.linkonce" - 1) == 0)
5321 /* This must duplicate the test in adjust_reloc_syms. */
5322 return (symsec
!= &bfd_und_section
5323 && symsec
!= &bfd_abs_section
5324 && ! bfd_is_com_section (symsec
)
5327 /* A global or weak symbol is treated as external. */
5328 && (OUTPUT_FLAVOR
!= bfd_target_elf_flavour
5329 || (! S_IS_WEAK (sym
) && ! S_IS_EXTERNAL (sym
)))
5335 s3_parse_pce_inst (char *insnstr
)
5339 char first
[s3_MAX_LITERAL_POOL_SIZE
];
5340 char second
[s3_MAX_LITERAL_POOL_SIZE
];
5341 struct s3_score_it pec_part_1
;
5343 /* Get first part string of PCE. */
5344 p
= strstr (insnstr
, "||");
5347 sprintf (first
, "%s", insnstr
);
5349 /* Get second part string of PCE. */
5352 sprintf (second
, "%s", p
);
5354 s3_parse_16_32_inst (first
, FALSE
);
5358 memcpy (&pec_part_1
, &s3_inst
, sizeof (s3_inst
));
5360 s3_parse_16_32_inst (second
, FALSE
);
5364 if ( ((pec_part_1
.size
== s3_INSN_SIZE
) && (s3_inst
.size
== s3_INSN_SIZE
))
5365 || ((pec_part_1
.size
== s3_INSN_SIZE
) && (s3_inst
.size
== s3_INSN16_SIZE
))
5366 || ((pec_part_1
.size
== s3_INSN16_SIZE
) && (s3_inst
.size
== s3_INSN_SIZE
)))
5368 s3_inst
.error
= _("pce instruction error (16 bit || 16 bit)'");
5369 sprintf (s3_inst
.str
, insnstr
);
5374 s3_gen_insn_frag (&pec_part_1
, &s3_inst
);
5379 s3_do16_dsp (char *str
)
5384 if (s3_score3d
== 0)
5386 s3_inst
.error
= _("score3d instruction.");
5390 s3_skip_whitespace (str
);
5392 if ((rd
= s3_reglow_required_here (&str
, 0)) == (int) s3_FAIL
5393 || s3_end_of_line (str
) == (int) s3_FAIL
)
5399 s3_inst
.relax_inst
|= rd
<< 20;
5400 s3_inst
.relax_size
= 4;
5405 s3_do16_dsp2 (char *str
)
5408 if (s3_score3d
== 0)
5410 s3_inst
.error
= _("score3d instruction.");
5414 s3_skip_whitespace (str
);
5416 if (s3_reglow_required_here (&str
, 4) == (int) s3_FAIL
5417 || s3_skip_past_comma (&str
) == (int) s3_FAIL
5418 || s3_reglow_required_here (&str
, 0) == (int) s3_FAIL
5419 || s3_end_of_line (str
) == (int) s3_FAIL
)
5425 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>> 8) & 0xf) << 20)
5426 | (((s3_inst
.instruction
>> 8) & 0xf) << 15) | (((s3_inst
.instruction
>> 4) & 0xf) << 10);
5427 s3_inst
.relax_size
= 4;
5432 s3_do_dsp (char *str
)
5435 if (s3_score3d
== 0)
5437 s3_inst
.error
= _("score3d instruction.");
5441 s3_skip_whitespace (str
);
5443 if (s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
5444 || s3_skip_past_comma (&str
) == (int) s3_FAIL
5445 || s3_reg_required_here (&str
, 10, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
5446 || s3_end_of_line (str
) == (int) s3_FAIL
)
5449 if ((s3_inst
.relax_inst
!= 0x8000) && (((s3_inst
.instruction
>> 20) & 0x1f) == 3) )
5451 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>> 10) & 0x1f)) | (((s3_inst
.instruction
>> 15) & 0x1f) << 5);
5452 s3_inst
.relax_size
= 2;
5455 s3_inst
.relax_inst
= 0x8000;
5459 s3_do_dsp2 (char *str
)
5464 if (s3_score3d
== 0)
5466 s3_inst
.error
= _("score3d instruction.");
5470 s3_skip_whitespace (str
);
5472 if ((reg
= s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
5473 || s3_skip_past_comma (&str
) == (int) s3_FAIL
5474 || s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
5475 || s3_skip_past_comma (&str
) == (int) s3_FAIL
5476 || s3_reg_required_here (&str
, 10, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
5477 || s3_end_of_line (str
) == (int) s3_FAIL
)
5483 /* Check mulr, mulur rd is even number. */
5484 if (((s3_inst
.instruction
& 0x3e0003ff) == 0x00000340
5485 || (s3_inst
.instruction
& 0x3e0003ff) == 0x00000342)
5488 s3_inst
.error
= _("rd must be even number.");
5492 if ((((s3_inst
.instruction
>> 15) & 0x10) == 0)
5493 && (((s3_inst
.instruction
>> 10) & 0x10) == 0)
5494 && (((s3_inst
.instruction
>> 20) & 0x10) == 0)
5495 && (s3_inst
.relax_inst
!= 0x8000)
5496 && (((s3_inst
.instruction
>> 20) & 0xf) == ((s3_inst
.instruction
>> 15) & 0xf)))
5498 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>> 10) & 0xf) )
5499 | (((s3_inst
.instruction
>> 15) & 0xf) << 4);
5500 s3_inst
.relax_size
= 2;
5504 s3_inst
.relax_inst
= 0x8000;
5510 s3_do_dsp3 (char *str
)
5513 if (s3_score3d
== 0)
5515 s3_inst
.error
= _("score3d instruction.");
5519 s3_skip_whitespace (str
);
5521 if (s3_reg_required_here (&str
, 20, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
5522 || s3_skip_past_comma (&str
) == (int) s3_FAIL
5523 || s3_reg_required_here (&str
, 15, s3_REG_TYPE_SCORE
) == (int) s3_FAIL
5524 || s3_end_of_line (str
) == (int) s3_FAIL
)
5527 if ((s3_inst
.relax_inst
!= 0x8000) && (((s3_inst
.instruction
>> 20) & 0x1f) == 3) )
5529 s3_inst
.relax_inst
|= (((s3_inst
.instruction
>> 10) & 0x1f)) | (((s3_inst
.instruction
>> 15) & 0x1f) << 5);
5530 s3_inst
.relax_size
= 2;
5533 s3_inst
.relax_inst
= 0x8000;
5537 /* If we change section we must dump the literal pool first. */
5539 s3_s_score_bss (int ignore ATTRIBUTE_UNUSED
)
5541 subseg_set (bss_section
, (subsegT
) get_absolute_expression ());
5542 demand_empty_rest_of_line ();
5546 s3_s_score_text (int ignore
)
5548 obj_elf_text (ignore
);
5549 record_alignment (now_seg
, 2);
5553 s3_score_s_section (int ignore
)
5555 obj_elf_section (ignore
);
5556 if ((bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
) != 0)
5557 record_alignment (now_seg
, 2);
5562 s3_s_change_sec (int sec
)
5567 /* The ELF backend needs to know that we are changing sections, so
5568 that .previous works correctly. We could do something like check
5569 for an obj_section_change_hook macro, but that might be confusing
5570 as it would not be appropriate to use it in the section changing
5571 functions in read.c, since obj-elf.c intercepts those. FIXME:
5572 This should be cleaner, somehow. */
5573 obj_elf_section_change_hook ();
5578 seg
= subseg_new (s3_RDATA_SECTION_NAME
, (subsegT
) get_absolute_expression ());
5579 bfd_set_section_flags (stdoutput
, seg
, (SEC_ALLOC
| SEC_LOAD
| SEC_READONLY
| SEC_RELOC
| SEC_DATA
));
5580 if (strcmp (TARGET_OS
, "elf") != 0)
5581 record_alignment (seg
, 4);
5582 demand_empty_rest_of_line ();
5585 seg
= subseg_new (".sdata", (subsegT
) get_absolute_expression ());
5586 bfd_set_section_flags (stdoutput
, seg
, SEC_ALLOC
| SEC_LOAD
| SEC_RELOC
| SEC_DATA
);
5587 if (strcmp (TARGET_OS
, "elf") != 0)
5588 record_alignment (seg
, 4);
5589 demand_empty_rest_of_line ();
5595 s3_s_score_mask (int reg_type ATTRIBUTE_UNUSED
)
5599 if (s3_cur_proc_ptr
== (s3_procS
*) NULL
)
5601 as_warn (_(".mask outside of .ent"));
5602 demand_empty_rest_of_line ();
5605 if (get_absolute_expression_and_terminator (&mask
) != ',')
5607 as_warn (_("Bad .mask directive"));
5608 --input_line_pointer
;
5609 demand_empty_rest_of_line ();
5612 off
= get_absolute_expression ();
5613 s3_cur_proc_ptr
->reg_mask
= mask
;
5614 s3_cur_proc_ptr
->reg_offset
= off
;
5615 demand_empty_rest_of_line ();
5619 s3_get_symbol (void)
5625 name
= input_line_pointer
;
5626 c
= get_symbol_end ();
5627 p
= (symbolS
*) symbol_find_or_make (name
);
5628 *input_line_pointer
= c
;
5633 s3_get_number (void)
5638 if (*input_line_pointer
== '-')
5640 ++input_line_pointer
;
5643 if (!ISDIGIT (*input_line_pointer
))
5644 as_bad (_("expected simple number"));
5645 if (input_line_pointer
[0] == '0')
5647 if (input_line_pointer
[1] == 'x')
5649 input_line_pointer
+= 2;
5650 while (ISXDIGIT (*input_line_pointer
))
5653 val
|= hex_value (*input_line_pointer
++);
5655 return negative
? -val
: val
;
5659 ++input_line_pointer
;
5660 while (ISDIGIT (*input_line_pointer
))
5663 val
|= *input_line_pointer
++ - '0';
5665 return negative
? -val
: val
;
5668 if (!ISDIGIT (*input_line_pointer
))
5670 printf (_(" *input_line_pointer == '%c' 0x%02x\n"), *input_line_pointer
, *input_line_pointer
);
5671 as_warn (_("invalid number"));
5674 while (ISDIGIT (*input_line_pointer
))
5677 val
+= *input_line_pointer
++ - '0';
5679 return negative
? -val
: val
;
5682 /* The .aent and .ent directives. */
5684 s3_s_score_ent (int aent
)
5689 symbolP
= s3_get_symbol ();
5690 if (*input_line_pointer
== ',')
5691 ++input_line_pointer
;
5693 if (ISDIGIT (*input_line_pointer
) || *input_line_pointer
== '-')
5696 #ifdef BFD_ASSEMBLER
5697 if ((bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
) != 0)
5702 if (now_seg
!= data_section
&& now_seg
!= bss_section
)
5708 as_warn (_(".ent or .aent not in text section."));
5709 if (!aent
&& s3_cur_proc_ptr
)
5710 as_warn (_("missing .end"));
5713 s3_cur_proc_ptr
= &s3_cur_proc
;
5714 s3_cur_proc_ptr
->reg_mask
= 0xdeadbeaf;
5715 s3_cur_proc_ptr
->reg_offset
= 0xdeadbeaf;
5716 s3_cur_proc_ptr
->fpreg_mask
= 0xdeafbeaf;
5717 s3_cur_proc_ptr
->leaf
= 0xdeafbeaf;
5718 s3_cur_proc_ptr
->frame_offset
= 0xdeafbeaf;
5719 s3_cur_proc_ptr
->frame_reg
= 0xdeafbeaf;
5720 s3_cur_proc_ptr
->pc_reg
= 0xdeafbeaf;
5721 s3_cur_proc_ptr
->isym
= symbolP
;
5722 symbol_get_bfdsym (symbolP
)->flags
|= BSF_FUNCTION
;
5724 if (debug_type
== DEBUG_STABS
)
5725 stabs_generate_asm_func (S_GET_NAME (symbolP
), S_GET_NAME (symbolP
));
5727 demand_empty_rest_of_line ();
5731 s3_s_score_frame (int ignore ATTRIBUTE_UNUSED
)
5738 backupstr
= input_line_pointer
;
5741 if (s3_cur_proc_ptr
== (s3_procS
*) NULL
)
5743 as_warn (_(".frame outside of .ent"));
5744 demand_empty_rest_of_line ();
5747 s3_cur_proc_ptr
->frame_reg
= s3_reg_required_here ((&backupstr
), 0, s3_REG_TYPE_SCORE
);
5749 s3_skip_past_comma (&backupstr
);
5750 while (*backupstr
!= ',')
5752 str
[i
] = *backupstr
;
5760 s3_skip_past_comma (&backupstr
);
5761 s3_cur_proc_ptr
->frame_offset
= val
;
5762 s3_cur_proc_ptr
->pc_reg
= s3_reg_required_here ((&backupstr
), 0, s3_REG_TYPE_SCORE
);
5765 s3_skip_past_comma (&backupstr
);
5767 while (*backupstr
!= '\n')
5769 str
[i
] = *backupstr
;
5775 s3_cur_proc_ptr
->leaf
= val
;
5777 s3_skip_past_comma (&backupstr
);
5779 #endif /* OBJ_ELF */
5780 while (input_line_pointer
!= backupstr
)
5781 input_line_pointer
++;
5784 /* The .end directive. */
5786 s3_s_score_end (int x ATTRIBUTE_UNUSED
)
5791 /* Generate a .pdr section. */
5792 segT saved_seg
= now_seg
;
5793 subsegT saved_subseg
= now_subseg
;
5798 if (!is_end_of_line
[(unsigned char)*input_line_pointer
])
5800 p
= s3_get_symbol ();
5801 demand_empty_rest_of_line ();
5806 #ifdef BFD_ASSEMBLER
5807 if ((bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
) != 0)
5812 if (now_seg
!= data_section
&& now_seg
!= bss_section
)
5819 as_warn (_(".end not in text section"));
5820 if (!s3_cur_proc_ptr
)
5822 as_warn (_(".end directive without a preceding .ent directive."));
5823 demand_empty_rest_of_line ();
5828 gas_assert (S_GET_NAME (p
));
5829 if (strcmp (S_GET_NAME (p
), S_GET_NAME (s3_cur_proc_ptr
->isym
)))
5830 as_warn (_(".end symbol does not match .ent symbol."));
5831 if (debug_type
== DEBUG_STABS
)
5832 stabs_generate_asm_endfunc (S_GET_NAME (p
), S_GET_NAME (p
));
5835 as_warn (_(".end directive missing or unknown symbol"));
5837 if ((s3_cur_proc_ptr
->reg_mask
== 0xdeadbeaf) ||
5838 (s3_cur_proc_ptr
->reg_offset
== 0xdeadbeaf) ||
5839 (s3_cur_proc_ptr
->leaf
== 0xdeafbeaf) ||
5840 (s3_cur_proc_ptr
->frame_offset
== 0xdeafbeaf) ||
5841 (s3_cur_proc_ptr
->frame_reg
== 0xdeafbeaf) || (s3_cur_proc_ptr
->pc_reg
== 0xdeafbeaf));
5845 dot
= frag_now_fix ();
5846 gas_assert (s3_pdr_seg
);
5847 subseg_set (s3_pdr_seg
, 0);
5848 /* Write the symbol. */
5849 exp
.X_op
= O_symbol
;
5850 exp
.X_add_symbol
= p
;
5851 exp
.X_add_number
= 0;
5852 emit_expr (&exp
, 4);
5853 fragp
= frag_more (7 * 4);
5854 md_number_to_chars (fragp
, (valueT
) s3_cur_proc_ptr
->reg_mask
, 4);
5855 md_number_to_chars (fragp
+ 4, (valueT
) s3_cur_proc_ptr
->reg_offset
, 4);
5856 md_number_to_chars (fragp
+ 8, (valueT
) s3_cur_proc_ptr
->fpreg_mask
, 4);
5857 md_number_to_chars (fragp
+ 12, (valueT
) s3_cur_proc_ptr
->leaf
, 4);
5858 md_number_to_chars (fragp
+ 16, (valueT
) s3_cur_proc_ptr
->frame_offset
, 4);
5859 md_number_to_chars (fragp
+ 20, (valueT
) s3_cur_proc_ptr
->frame_reg
, 4);
5860 md_number_to_chars (fragp
+ 24, (valueT
) s3_cur_proc_ptr
->pc_reg
, 4);
5861 subseg_set (saved_seg
, saved_subseg
);
5864 s3_cur_proc_ptr
= NULL
;
5867 /* Handle the .set pseudo-op. */
5869 s3_s_score_set (int x ATTRIBUTE_UNUSED
)
5872 char name
[s3_MAX_LITERAL_POOL_SIZE
];
5873 char * orig_ilp
= input_line_pointer
;
5875 while (!is_end_of_line
[(unsigned char)*input_line_pointer
])
5877 name
[i
] = (char) * input_line_pointer
;
5879 ++input_line_pointer
;
5884 if (strcmp (name
, "nwarn") == 0)
5886 s3_warn_fix_data_dependency
= 0;
5888 else if (strcmp (name
, "fixdd") == 0)
5890 s3_fix_data_dependency
= 1;
5892 else if (strcmp (name
, "nofixdd") == 0)
5894 s3_fix_data_dependency
= 0;
5896 else if (strcmp (name
, "r1") == 0)
5900 else if (strcmp (name
, "nor1") == 0)
5904 else if (strcmp (name
, "optimize") == 0)
5908 else if (strcmp (name
, "volatile") == 0)
5912 else if (strcmp (name
, "pic") == 0)
5914 s3_score_pic
= s3_PIC
;
5918 input_line_pointer
= orig_ilp
;
5923 /* Handle the .cpload pseudo-op. This is used when generating s3_PIC code. It sets the
5924 $gp register for the function based on the function address, which is in the register
5925 named in the argument. This uses a relocation against GP_DISP_LABEL, which is handled
5926 specially by the linker. The result is:
5927 ldis gp, %hi(GP_DISP_LABEL)
5928 ori gp, %low(GP_DISP_LABEL)
5929 add gp, gp, .cpload argument
5930 The .cpload argument is normally r29. */
5932 s3_s_score_cpload (int ignore ATTRIBUTE_UNUSED
)
5935 char insn_str
[s3_MAX_LITERAL_POOL_SIZE
];
5937 /* If we are not generating s3_PIC code, .cpload is ignored. */
5938 if (s3_score_pic
== s3_NO_PIC
)
5944 if ((reg
= s3_reg_required_here (&input_line_pointer
, -1, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
)
5947 demand_empty_rest_of_line ();
5949 sprintf (insn_str
, "ld_i32hi r%d, %s", s3_GP
, GP_DISP_LABEL
);
5950 if (s3_append_insn (insn_str
, TRUE
) == (int) s3_FAIL
)
5953 sprintf (insn_str
, "ld_i32lo r%d, %s", s3_GP
, GP_DISP_LABEL
);
5954 if (s3_append_insn (insn_str
, TRUE
) == (int) s3_FAIL
)
5957 sprintf (insn_str
, "add r%d, r%d, r%d", s3_GP
, s3_GP
, reg
);
5958 if (s3_append_insn (insn_str
, TRUE
) == (int) s3_FAIL
)
5962 /* Handle the .cprestore pseudo-op. This stores $gp into a given
5963 offset from $sp. The offset is remembered, and after making a s3_PIC
5964 call $gp is restored from that location. */
5966 s3_s_score_cprestore (int ignore ATTRIBUTE_UNUSED
)
5969 int cprestore_offset
;
5970 char insn_str
[s3_MAX_LITERAL_POOL_SIZE
];
5972 /* If we are not generating s3_PIC code, .cprestore is ignored. */
5973 if (s3_score_pic
== s3_NO_PIC
)
5979 if ((reg
= s3_reg_required_here (&input_line_pointer
, -1, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
5980 || s3_skip_past_comma (&input_line_pointer
) == (int) s3_FAIL
)
5985 cprestore_offset
= get_absolute_expression ();
5987 if (cprestore_offset
<= 0x3fff)
5989 sprintf (insn_str
, "sw r%d, [r%d, %d]", s3_GP
, reg
, cprestore_offset
);
5990 if (s3_append_insn (insn_str
, TRUE
) == (int) s3_FAIL
)
6000 sprintf (insn_str
, "li r1, %d", cprestore_offset
);
6001 if (s3_append_insn (insn_str
, TRUE
) == (int) s3_FAIL
)
6004 sprintf (insn_str
, "add r1, r1, r%d", reg
);
6005 if (s3_append_insn (insn_str
, TRUE
) == (int) s3_FAIL
)
6008 sprintf (insn_str
, "sw r%d, [r1]", s3_GP
);
6009 if (s3_append_insn (insn_str
, TRUE
) == (int) s3_FAIL
)
6015 demand_empty_rest_of_line ();
6018 /* Handle the .gpword pseudo-op. This is used when generating s3_PIC
6019 code. It generates a 32 bit s3_GP relative reloc. */
6021 s3_s_score_gpword (int ignore ATTRIBUTE_UNUSED
)
6026 /* When not generating s3_PIC code, this is treated as .word. */
6027 if (s3_score_pic
== s3_NO_PIC
)
6033 if (ex
.X_op
!= O_symbol
|| ex
.X_add_number
!= 0)
6035 as_bad (_("Unsupported use of .gpword"));
6036 ignore_rest_of_line ();
6039 s3_md_number_to_chars (p
, (valueT
) 0, 4);
6040 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 4, &ex
, FALSE
, BFD_RELOC_GPREL32
);
6041 demand_empty_rest_of_line ();
6044 /* Handle the .cpadd pseudo-op. This is used when dealing with switch
6045 tables in s3_PIC code. */
6047 s3_s_score_cpadd (int ignore ATTRIBUTE_UNUSED
)
6050 char insn_str
[s3_MAX_LITERAL_POOL_SIZE
];
6052 /* If we are not generating s3_PIC code, .cpload is ignored. */
6053 if (s3_score_pic
== s3_NO_PIC
)
6059 if ((reg
= s3_reg_required_here (&input_line_pointer
, -1, s3_REG_TYPE_SCORE
)) == (int) s3_FAIL
)
6063 demand_empty_rest_of_line ();
6065 /* Add $gp to the register named as an argument. */
6066 sprintf (insn_str
, "add r%d, r%d, r%d", reg
, reg
, s3_GP
);
6067 if (s3_append_insn (insn_str
, TRUE
) == (int) s3_FAIL
)
6071 #ifndef TC_IMPLICIT_LCOMM_ALIGNMENT
6072 #define TC_IMPLICIT_LCOMM_ALIGNMENT(SIZE, P2VAR) \
6077 else if ((SIZE) >= 4) \
6079 else if ((SIZE) >= 2) \
6088 s3_s_score_lcomm (int bytes_p
)
6095 segT current_seg
= now_seg
;
6096 subsegT current_subseg
= now_subseg
;
6097 const int max_alignment
= 15;
6099 segT bss_seg
= bss_section
;
6100 int needs_align
= 0;
6102 name
= input_line_pointer
;
6103 c
= get_symbol_end ();
6104 p
= input_line_pointer
;
6109 as_bad (_("expected symbol name"));
6110 discard_rest_of_line ();
6116 /* Accept an optional comma after the name. The comma used to be
6117 required, but Irix 5 cc does not generate it. */
6118 if (*input_line_pointer
== ',')
6120 ++input_line_pointer
;
6124 if (is_end_of_line
[(unsigned char)*input_line_pointer
])
6126 as_bad (_("missing size expression"));
6130 if ((temp
= get_absolute_expression ()) < 0)
6132 as_warn (_("BSS length (%d) < 0 ignored"), temp
);
6133 ignore_rest_of_line ();
6137 #if defined (TC_SCORE)
6138 if (OUTPUT_FLAVOR
== bfd_target_ecoff_flavour
|| OUTPUT_FLAVOR
== bfd_target_elf_flavour
)
6140 /* For Score and Alpha ECOFF or ELF, small objects are put in .sbss. */
6141 if ((unsigned)temp
<= bfd_get_gp_size (stdoutput
))
6143 bss_seg
= subseg_new (".sbss", 1);
6144 seg_info (bss_seg
)->bss
= 1;
6145 #ifdef BFD_ASSEMBLER
6146 if (!bfd_set_section_flags (stdoutput
, bss_seg
, SEC_ALLOC
))
6147 as_warn (_("error setting flags for \".sbss\": %s"), bfd_errmsg (bfd_get_error ()));
6154 if (*input_line_pointer
== ',')
6156 ++input_line_pointer
;
6159 if (is_end_of_line
[(unsigned char)*input_line_pointer
])
6161 as_bad (_("missing alignment"));
6166 align
= get_absolute_expression ();
6173 TC_IMPLICIT_LCOMM_ALIGNMENT (temp
, align
);
6175 /* Still zero unless TC_IMPLICIT_LCOMM_ALIGNMENT set it. */
6177 record_alignment (bss_seg
, align
);
6184 /* Convert to a power of 2. */
6189 for (i
= 0; align
!= 0; align
>>= 1, ++i
)
6195 if (align
> max_alignment
)
6197 align
= max_alignment
;
6198 as_warn (_("alignment too large; %d assumed"), align
);
6203 as_warn (_("alignment negative; 0 assumed"));
6206 record_alignment (bss_seg
, align
);
6210 /* Assume some objects may require alignment on some systems. */
6211 #if defined (TC_ALPHA) && ! defined (VMS)
6214 align
= ffs (temp
) - 1;
6215 if (temp
% (1 << align
))
6222 symbolP
= symbol_find_or_make (name
);
6226 #if (defined (OBJ_AOUT) || defined (OBJ_MAYBE_AOUT) \
6227 || defined (OBJ_BOUT) || defined (OBJ_MAYBE_BOUT))
6228 #ifdef BFD_ASSEMBLER
6229 (OUTPUT_FLAVOR
!= bfd_target_aout_flavour
6230 || (S_GET_OTHER (symbolP
) == 0 && S_GET_DESC (symbolP
) == 0)) &&
6232 (S_GET_OTHER (symbolP
) == 0 && S_GET_DESC (symbolP
) == 0) &&
6235 (S_GET_SEGMENT (symbolP
) == bss_seg
|| (!S_IS_DEFINED (symbolP
) && S_GET_VALUE (symbolP
) == 0)))
6239 subseg_set (bss_seg
, 1);
6242 frag_align (align
, 0, 0);
6244 /* Detach from old frag. */
6245 if (S_GET_SEGMENT (symbolP
) == bss_seg
)
6246 symbol_get_frag (symbolP
)->fr_symbol
= NULL
;
6248 symbol_set_frag (symbolP
, frag_now
);
6249 pfrag
= frag_var (rs_org
, 1, 1, (relax_substateT
) 0, symbolP
, (offsetT
) temp
, NULL
);
6253 S_SET_SEGMENT (symbolP
, bss_seg
);
6256 /* The symbol may already have been created with a preceding
6257 ".globl" directive -- be careful not to step on storage class
6258 in that case. Otherwise, set it to static. */
6259 if (S_GET_STORAGE_CLASS (symbolP
) != C_EXT
)
6261 S_SET_STORAGE_CLASS (symbolP
, C_STAT
);
6263 #endif /* OBJ_COFF */
6266 S_SET_SIZE (symbolP
, temp
);
6270 as_bad (_("symbol `%s' is already defined"), S_GET_NAME (symbolP
));
6272 subseg_set (current_seg
, current_subseg
);
6274 demand_empty_rest_of_line ();
6278 s3_insert_reg (const struct s3_reg_entry
*r
, struct hash_control
*htab
)
6281 int len
= strlen (r
->name
) + 2;
6282 char *buf
= xmalloc (len
);
6283 char *buf2
= xmalloc (len
);
6285 strcpy (buf
+ i
, r
->name
);
6286 for (i
= 0; buf
[i
]; i
++)
6288 buf2
[i
] = TOUPPER (buf
[i
]);
6292 hash_insert (htab
, buf
, (void *) r
);
6293 hash_insert (htab
, buf2
, (void *) r
);
6297 s3_build_reg_hsh (struct s3_reg_map
*map
)
6299 const struct s3_reg_entry
*r
;
6301 if ((map
->htab
= hash_new ()) == NULL
)
6303 as_fatal (_("virtual memory exhausted"));
6305 for (r
= map
->names
; r
->name
!= NULL
; r
++)
6307 s3_insert_reg (r
, map
->htab
);
6311 /* Iterate over the base tables to create the instruction patterns. */
6313 s3_build_score_ops_hsh (void)
6316 static struct obstack insn_obstack
;
6318 obstack_begin (&insn_obstack
, 4000);
6319 for (i
= 0; i
< sizeof (s3_score_insns
) / sizeof (struct s3_asm_opcode
); i
++)
6321 const struct s3_asm_opcode
*insn
= s3_score_insns
+ i
;
6322 unsigned len
= strlen (insn
->template);
6323 struct s3_asm_opcode
*new;
6325 new = obstack_alloc (&insn_obstack
, sizeof (struct s3_asm_opcode
));
6326 template = obstack_alloc (&insn_obstack
, len
+ 1);
6328 strcpy (template, insn
->template);
6329 new->template = template;
6330 new->parms
= insn
->parms
;
6331 new->value
= insn
->value
;
6332 new->relax_value
= insn
->relax_value
;
6333 new->type
= insn
->type
;
6334 new->bitmask
= insn
->bitmask
;
6335 hash_insert (s3_score_ops_hsh
, new->template, (void *) new);
6340 s3_build_dependency_insn_hsh (void)
6343 static struct obstack dependency_obstack
;
6345 obstack_begin (&dependency_obstack
, 4000);
6346 for (i
= 0; i
< sizeof (s3_insn_to_dependency_table
) / sizeof (s3_insn_to_dependency_table
[0]); i
++)
6348 const struct s3_insn_to_dependency
*tmp
= s3_insn_to_dependency_table
+ i
;
6349 unsigned len
= strlen (tmp
->insn_name
);
6350 struct s3_insn_to_dependency
*new;
6352 new = obstack_alloc (&dependency_obstack
, sizeof (struct s3_insn_to_dependency
));
6353 new->insn_name
= obstack_alloc (&dependency_obstack
, len
+ 1);
6355 strcpy (new->insn_name
, tmp
->insn_name
);
6356 new->type
= tmp
->type
;
6357 hash_insert (s3_dependency_insn_hsh
, new->insn_name
, (void *) new);
6362 s_score_bss (int ignore ATTRIBUTE_UNUSED
)
6365 return s3_s_score_bss (ignore
);
6367 return s7_s_score_bss (ignore
);
6371 s_score_text (int ignore
)
6374 return s3_s_score_text (ignore
);
6376 return s7_s_score_text (ignore
);
6380 s_section (int ignore
)
6383 return s3_score_s_section (ignore
);
6385 return s7_s_section (ignore
);
6389 s_change_sec (int sec
)
6392 return s3_s_change_sec (sec
);
6394 return s7_s_change_sec (sec
);
6398 s_score_mask (int reg_type ATTRIBUTE_UNUSED
)
6401 return s3_s_score_mask (reg_type
);
6403 return s7_s_score_mask (reg_type
);
6407 s_score_ent (int aent
)
6410 return s3_s_score_ent (aent
);
6412 return s7_s_score_ent (aent
);
6416 s_score_frame (int ignore ATTRIBUTE_UNUSED
)
6419 return s3_s_score_frame (ignore
);
6421 return s7_s_score_frame (ignore
);
6425 s_score_end (int x ATTRIBUTE_UNUSED
)
6428 return s3_s_score_end (x
);
6430 return s7_s_score_end (x
);
6434 s_score_set (int x ATTRIBUTE_UNUSED
)
6437 return s3_s_score_set (x
);
6439 return s7_s_score_set (x
);
6443 s_score_cpload (int ignore ATTRIBUTE_UNUSED
)
6446 return s3_s_score_cpload (ignore
);
6448 return s7_s_score_cpload (ignore
);
6452 s_score_cprestore (int ignore ATTRIBUTE_UNUSED
)
6455 return s3_s_score_cprestore (ignore
);
6457 return s7_s_score_cprestore (ignore
);
6461 s_score_gpword (int ignore ATTRIBUTE_UNUSED
)
6464 return s3_s_score_gpword (ignore
);
6466 return s7_s_score_gpword (ignore
);
6470 s_score_cpadd (int ignore ATTRIBUTE_UNUSED
)
6473 return s3_s_score_cpadd (ignore
);
6475 return s7_s_score_cpadd (ignore
);
6479 s_score_lcomm (int bytes_p
)
6482 return s3_s_score_lcomm (bytes_p
);
6484 return s7_s_score_lcomm (bytes_p
);
6488 s3_assemble (char *str
)
6491 know (strlen (str
) < s3_MAX_LITERAL_POOL_SIZE
);
6493 memset (&s3_inst
, '\0', sizeof (s3_inst
));
6494 if (s3_INSN_IS_PCE_P (str
))
6495 s3_parse_pce_inst (str
);
6496 else if (s3_INSN_IS_48_P (str
))
6497 s3_parse_48_inst (str
, TRUE
);
6499 s3_parse_16_32_inst (str
, TRUE
);
6502 as_bad (_("%s -- `%s'"), s3_inst
.error
, s3_inst
.str
);
6506 s3_operand (expressionS
* expr
)
6508 if (s3_in_my_get_expression
)
6510 expr
->X_op
= O_illegal
;
6511 if (s3_inst
.error
== NULL
)
6513 s3_inst
.error
= _("bad expression");
6525 if ((s3_score_ops_hsh
= hash_new ()) == NULL
)
6526 as_fatal (_("virtual memory exhausted"));
6528 s3_build_score_ops_hsh ();
6530 if ((s3_dependency_insn_hsh
= hash_new ()) == NULL
)
6531 as_fatal (_("virtual memory exhausted"));
6533 s3_build_dependency_insn_hsh ();
6535 for (i
= (int)s3_REG_TYPE_FIRST
; i
< (int)s3_REG_TYPE_MAX
; i
++)
6536 s3_build_reg_hsh (s3_all_reg_maps
+ i
);
6538 /* Initialize dependency vector. */
6539 s3_init_dependency_vector ();
6541 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
, 0);
6543 subseg
= now_subseg
;
6544 s3_pdr_seg
= subseg_new (".pdr", (subsegT
) 0);
6545 (void)bfd_set_section_flags (stdoutput
, s3_pdr_seg
, SEC_READONLY
| SEC_RELOC
| SEC_DEBUGGING
);
6546 (void)bfd_set_section_alignment (stdoutput
, s3_pdr_seg
, 2);
6547 subseg_set (seg
, subseg
);
6549 if (s3_USE_GLOBAL_POINTER_OPT
)
6550 bfd_set_gp_size (stdoutput
, s3_g_switch_value
);
6554 s3_number_to_chars (char *buf
, valueT val
, int n
)
6556 if (target_big_endian
)
6557 number_to_chars_bigendian (buf
, val
, n
);
6559 number_to_chars_littleendian (buf
, val
, n
);
6563 s3_normal_chars_to_number (char *buf
, int n
)
6566 unsigned char *where
= (unsigned char *)buf
;
6568 if (target_big_endian
)
6573 result
|= (*where
++ & 255);
6581 result
|= (where
[n
] & 255);
6589 s3_number_to_chars_littleendian (void *p
, valueT data
, int n
)
6591 char *buf
= (char *) p
;
6596 md_number_to_chars (buf
, data
>> 16, 2);
6597 md_number_to_chars (buf
+ 2, data
, 2);
6600 md_number_to_chars (buf
, data
>> 32, 2);
6601 md_number_to_chars (buf
+ 2, data
>> 16, 2);
6602 md_number_to_chars (buf
+ 4, data
, 2);
6605 /* Error routine. */
6606 as_bad_where (__FILE__
, __LINE__
, _("size is not 4 or 6"));
6612 s3_chars_to_number_littleendian (const void *p
, int n
)
6614 char *buf
= (char *) p
;
6620 result
= s3_normal_chars_to_number (buf
, 2) << 16;
6621 result
|= s3_normal_chars_to_number (buf
+ 2, 2);
6624 result
= s3_normal_chars_to_number (buf
, 2) << 32;
6625 result
|= s3_normal_chars_to_number (buf
+ 2, 2) << 16;
6626 result
|= s3_normal_chars_to_number (buf
+ 4, 2);
6629 /* Error routine. */
6630 as_bad_where (__FILE__
, __LINE__
, _("size is not 4 or 6"));
6638 s3_md_number_to_chars (char *buf
, valueT val
, int n
)
6640 if (!target_big_endian
&& n
>= 4)
6641 s3_number_to_chars_littleendian (buf
, val
, n
);
6643 md_number_to_chars (buf
, val
, n
);
6647 s3_md_chars_to_number (char *buf
, int n
)
6651 if (!target_big_endian
&& n
>= 4)
6652 result
= s3_chars_to_number_littleendian (buf
, n
);
6654 result
= s3_normal_chars_to_number (buf
, n
);
6660 s3_atof (int type
, char *litP
, int *sizeP
)
6663 LITTLENUM_TYPE words
[s3_MAX_LITTLENUMS
];
6689 return _("bad call to MD_ATOF()");
6692 t
= atof_ieee (input_line_pointer
, type
, words
);
6694 input_line_pointer
= t
;
6697 if (target_big_endian
)
6699 for (i
= 0; i
< prec
; i
++)
6701 s3_md_number_to_chars (litP
, (valueT
) words
[i
], 2);
6707 for (i
= 0; i
< prec
; i
+= 2)
6709 s3_md_number_to_chars (litP
, (valueT
) words
[i
+ 1], 2);
6710 s3_md_number_to_chars (litP
+ 2, (valueT
) words
[i
], 2);
6719 s3_frag_check (fragS
* fragp ATTRIBUTE_UNUSED
)
6721 know (fragp
->insn_addr
<= s3_RELAX_PAD_BYTE
);
6725 s3_validate_fix (fixS
*fixP
)
6727 fixP
->fx_where
+= fixP
->fx_frag
->insn_addr
;
6731 s3_force_relocation (struct fix
*fixp
)
6735 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
6736 || fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
6737 || fixp
->fx_r_type
== BFD_RELOC_SCORE_JMP
6738 || fixp
->fx_r_type
== BFD_RELOC_SCORE_BRANCH
6739 || fixp
->fx_r_type
== BFD_RELOC_SCORE16_JMP
6740 || fixp
->fx_r_type
== BFD_RELOC_SCORE16_BRANCH
6741 || fixp
->fx_r_type
== BFD_RELOC_SCORE_BCMP
)
6749 s3_fix_adjustable (fixS
* fixP
)
6751 if (fixP
->fx_addsy
== NULL
)
6755 else if (OUTPUT_FLAVOR
== bfd_target_elf_flavour
6756 && (S_IS_EXTERNAL (fixP
->fx_addsy
) || S_IS_WEAK (fixP
->fx_addsy
)))
6760 else if (fixP
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
6761 || fixP
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
6762 || fixP
->fx_r_type
== BFD_RELOC_SCORE_JMP
6763 || fixP
->fx_r_type
== BFD_RELOC_SCORE16_JMP
)
6772 s3_elf_final_processing (void)
6774 unsigned long val
= 0;
6777 val
= E_SCORE_MACH_SCORE3
;
6779 val
= E_SCORE_MACH_SCORE7
;
6781 elf_elfheader (stdoutput
)->e_machine
= EM_SCORE
;
6782 elf_elfheader (stdoutput
)->e_flags
&= ~EF_SCORE_MACH
;
6783 elf_elfheader (stdoutput
)->e_flags
|= val
;
6785 if (s3_fix_data_dependency
== 1)
6787 elf_elfheader (stdoutput
)->e_flags
|= EF_SCORE_FIXDEP
;
6789 if (s3_score_pic
== s3_PIC
)
6791 elf_elfheader (stdoutput
)->e_flags
|= EF_SCORE_PIC
;
6796 s3_judge_size_before_relax (fragS
* fragp
, asection
*sec
)
6800 if (s3_score_pic
== s3_NO_PIC
)
6801 change
= s3_nopic_need_relax (fragp
->fr_symbol
, 0);
6803 change
= s3_pic_need_relax (fragp
->fr_symbol
, sec
);
6807 /* Only at the first time determining whether s3_GP instruction relax should be done,
6808 return the difference between insntruction size and instruction relax size. */
6809 if (fragp
->fr_opcode
== NULL
)
6811 fragp
->fr_fix
= s3_RELAX_NEW (fragp
->fr_subtype
);
6812 fragp
->fr_opcode
= fragp
->fr_literal
+ s3_RELAX_RELOC1 (fragp
->fr_subtype
);
6813 return s3_RELAX_NEW (fragp
->fr_subtype
) - s3_RELAX_OLD (fragp
->fr_subtype
);
6821 s3_estimate_size_before_relax (fragS
* fragp
, asection
* sec ATTRIBUTE_UNUSED
)
6823 if ((s3_RELAX_TYPE (fragp
->fr_subtype
) == Insn_GP
)
6824 || (s3_RELAX_TYPE (fragp
->fr_subtype
) == Insn_PIC
))
6825 return s3_judge_size_before_relax (fragp
, sec
);
6831 s3_relax_branch_inst32 (fragS
* fragp
)
6833 fragp
->fr_opcode
= NULL
;
6838 s3_relax_branch_inst16 (fragS
* fragp
)
6840 int relaxable_p
= 0;
6841 int frag_addr
= fragp
->fr_address
+ fragp
->insn_addr
;
6842 addressT symbol_address
= 0;
6846 unsigned long inst_value
;
6848 relaxable_p
= s3_RELAX_OPT (fragp
->fr_subtype
);
6850 s
= fragp
->fr_symbol
;
6856 symbol_address
= (addressT
) s
->sy_frag
->fr_address
;
6859 inst_value
= s3_md_chars_to_number (fragp
->fr_literal
, s3_INSN16_SIZE
);
6860 offset
= (inst_value
& 0x1ff) << 1;
6861 if ((offset
& 0x200) == 0x200)
6862 offset
|= 0xfffffc00;
6864 value
= offset
+ symbol_address
- frag_addr
;
6867 && (!((value
& 0xfffffe00) == 0 || (value
& 0xfffffe00) == 0xfffffe00))
6868 && fragp
->fr_fix
== 2
6869 && (s
->bsym
!= NULL
)
6870 && (S_IS_DEFINED (s
)
6872 && !S_IS_EXTERNAL (s
)))
6874 /* Relax branch 32 to branch 16. */
6875 fragp
->fr_opcode
= fragp
->fr_literal
+ s3_RELAX_RELOC1 (fragp
->fr_subtype
);
6884 s3_relax_cmpbranch_inst32 (fragS
* fragp
)
6886 int relaxable_p
= 0;
6890 long frag_addr
= fragp
->fr_address
+ fragp
->insn_addr
;
6891 long symbol_address
= 0;
6893 unsigned long inst_value
;
6895 relaxable_p
= s3_RELAX_OPT (fragp
->fr_subtype
);
6897 s
= fragp
->fr_symbol
;
6903 symbol_address
= (addressT
) s
->sy_frag
->fr_address
;
6906 inst_value
= s3_md_chars_to_number (fragp
->fr_literal
, s3_INSN_SIZE
);
6907 offset
= (inst_value
& 0x1)
6908 | (((inst_value
>> 7) & 0x7) << 1)
6909 | (((inst_value
>> 21) & 0x1f) << 4);
6911 if ((offset
& 0x200) == 0x200)
6912 offset
|= 0xfffffe00;
6914 value
= offset
+ symbol_address
- frag_addr
;
6915 /* change the order of judging rule is because
6916 1.not defined symbol or common sysbol or external symbol will change
6917 bcmp to cmp!+beq/bne ,here need to record fragp->fr_opcode
6918 2.if the flow is as before : it will results to recursive loop
6920 if (fragp
->fr_fix
== 6)
6922 /* Have already relaxed! Just return 0 to terminate the loop. */
6925 /* need to translate when extern or not defind or common sysbol */
6926 else if ((relaxable_p
6927 && (!((value
& 0xfffffe00) == 0 || (value
& 0xfffffe00) == 0xfffffe00))
6928 && fragp
->fr_fix
== 4
6929 && (s
->bsym
!= NULL
))
6930 || !S_IS_DEFINED (s
)
6932 ||S_IS_EXTERNAL (s
))
6934 fragp
->fr_opcode
= fragp
->fr_literal
+ s3_RELAX_RELOC1 (fragp
->fr_subtype
);
6941 /* Never relax. Modify fr_opcode to NULL to verify it's value in
6943 fragp
->fr_opcode
= NULL
;
6950 s3_relax_other_inst32 (fragS
* fragp
)
6952 int relaxable_p
= s3_RELAX_OPT (fragp
->fr_subtype
);
6955 && fragp
->fr_fix
== 4)
6957 fragp
->fr_opcode
= fragp
->fr_literal
+ s3_RELAX_RELOC1 (fragp
->fr_subtype
);
6966 s3_relax_gp_and_pic_inst32 (void)
6968 /* md_estimate_size_before_relax has already relaxed s3_GP and s3_PIC
6969 instructions. We don't change relax size here. */
6974 s3_relax_frag (asection
* sec ATTRIBUTE_UNUSED
, fragS
* fragp
, long stretch ATTRIBUTE_UNUSED
)
6977 int adjust_align_p
= 0;
6979 /* If the instruction address is odd, make it half word align first. */
6980 if ((fragp
->fr_address
) % 2 != 0)
6982 if ((fragp
->fr_address
+ fragp
->insn_addr
) % 2 != 0)
6984 fragp
->insn_addr
= 1;
6990 switch (s3_RELAX_TYPE (fragp
->fr_subtype
))
6993 grows
+= s3_relax_branch_inst32 (fragp
);
6997 grows
+= s3_relax_branch_inst16 (fragp
);
7001 grows
+= s3_relax_cmpbranch_inst32 (fragp
);
7006 grows
+= s3_relax_gp_and_pic_inst32 ();
7010 grows
+= s3_relax_other_inst32 (fragp
);
7015 if (adjust_align_p
&& fragp
->insn_addr
)
7017 fragp
->fr_fix
+= fragp
->insn_addr
;
7024 s3_convert_frag (bfd
* abfd ATTRIBUTE_UNUSED
, segT sec ATTRIBUTE_UNUSED
, fragS
* fragp
)
7031 old
= s3_RELAX_OLD (fragp
->fr_subtype
);
7032 new = s3_RELAX_NEW (fragp
->fr_subtype
);
7034 /* fragp->fr_opcode indicates whether this frag should be relaxed. */
7035 if (fragp
->fr_opcode
== NULL
)
7037 memcpy (backup
, fragp
->fr_literal
, old
);
7038 fragp
->fr_fix
= old
;
7042 memcpy (backup
, fragp
->fr_literal
+ old
, new);
7043 fragp
->fr_fix
= new;
7046 fixp
= fragp
->tc_frag_data
.fixp
;
7047 while (fixp
&& fixp
->fx_frag
== fragp
&& fixp
->fx_where
< old
)
7049 if (fragp
->fr_opcode
)
7051 fixp
= fixp
->fx_next
;
7053 while (fixp
&& fixp
->fx_frag
== fragp
)
7055 if (fragp
->fr_opcode
)
7056 fixp
->fx_where
-= old
+ fragp
->insn_addr
;
7059 fixp
= fixp
->fx_next
;
7062 if (fragp
->insn_addr
)
7064 s3_md_number_to_chars (fragp
->fr_literal
, 0x0, fragp
->insn_addr
);
7066 memcpy (fragp
->fr_literal
+ fragp
->insn_addr
, backup
, fragp
->fr_fix
);
7067 fragp
->fr_fix
+= fragp
->insn_addr
;
7071 s3_pcrel_from (fixS
* fixP
)
7076 && (S_GET_SEGMENT (fixP
->fx_addsy
) == undefined_section
)
7077 && (fixP
->fx_subsy
== NULL
))
7083 retval
= fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
7090 s3_section_align (segT segment ATTRIBUTE_UNUSED
, valueT size
)
7092 int align
= bfd_get_section_alignment (stdoutput
, segment
);
7093 return ((size
+ (1 << align
) - 1) & (-1 << align
));
7097 s3_apply_fix (fixS
*fixP
, valueT
*valP
, segT seg
)
7099 offsetT value
= *valP
;
7102 unsigned short HI
, LO
;
7104 char *buf
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
7106 gas_assert (fixP
->fx_r_type
< BFD_RELOC_UNUSED
);
7107 if (fixP
->fx_addsy
== 0 && !fixP
->fx_pcrel
)
7109 if (fixP
->fx_r_type
!= BFD_RELOC_SCORE_DUMMY_HI16
)
7113 /* If this symbol is in a different section then we need to leave it for
7114 the linker to deal with. Unfortunately, md_pcrel_from can't tell,
7115 so we have to undo it's effects here. */
7118 if (fixP
->fx_addsy
!= NULL
7119 && S_IS_DEFINED (fixP
->fx_addsy
)
7120 && S_GET_SEGMENT (fixP
->fx_addsy
) != seg
)
7121 value
+= md_pcrel_from (fixP
);
7124 /* Remember value for emit_reloc. */
7125 fixP
->fx_addnumber
= value
;
7127 switch (fixP
->fx_r_type
)
7129 case BFD_RELOC_HI16_S
:
7130 if (fixP
->fx_done
) /* For la rd, imm32. */
7132 newval
= s3_md_chars_to_number (buf
, s3_INSN_SIZE
);
7133 HI
= (value
) >> 16; /* mul to 2, then take the hi 16 bit. */
7134 newval
|= (HI
& 0x3fff) << 1;
7135 newval
|= ((HI
>> 14) & 0x3) << 16;
7136 s3_md_number_to_chars (buf
, newval
, s3_INSN_SIZE
);
7139 case BFD_RELOC_LO16
:
7140 if (fixP
->fx_done
) /* For la rd, imm32. */
7142 newval
= s3_md_chars_to_number (buf
, s3_INSN_SIZE
);
7143 LO
= (value
) & 0xffff;
7144 newval
|= (LO
& 0x3fff) << 1; /* 16 bit: imm -> 14 bit in lo, 2 bit in hi. */
7145 newval
|= ((LO
>> 14) & 0x3) << 16;
7146 s3_md_number_to_chars (buf
, newval
, s3_INSN_SIZE
);
7149 case BFD_RELOC_SCORE_JMP
:
7151 content
= s3_md_chars_to_number (buf
, s3_INSN_SIZE
);
7152 value
= fixP
->fx_offset
;
7153 content
= (content
& ~0x3ff7ffe) | ((value
<< 1) & 0x3ff0000) | (value
& 0x7fff);
7154 s3_md_number_to_chars (buf
, content
, s3_INSN_SIZE
);
7158 case BFD_RELOC_SCORE_IMM30
:
7160 content
= s3_md_chars_to_number (buf
, s3_INSN48_SIZE
);
7161 value
= fixP
->fx_offset
;
7163 content
= (content
& ~0x7f7fff7f80LL
)
7164 | (((value
& 0xff) >> 0) << 7)
7165 | (((value
& 0x7fff00) >> 8) << 16)
7166 | (((value
& 0x3f800000) >> 23) << 32);
7167 s3_md_number_to_chars (buf
, content
, s3_INSN48_SIZE
);
7171 case BFD_RELOC_SCORE_IMM32
:
7173 content
= s3_md_chars_to_number (buf
, s3_INSN48_SIZE
);
7174 value
= fixP
->fx_offset
;
7175 content
= (content
& ~0x7f7fff7fe0LL
)
7176 | ((value
& 0x3ff) << 5)
7177 | (((value
>> 10) & 0x7fff) << 16)
7178 | (((value
>> 25) & 0x7f) << 32);
7179 s3_md_number_to_chars (buf
, content
, s3_INSN48_SIZE
);
7183 case BFD_RELOC_SCORE_BRANCH
:
7184 if ((S_GET_SEGMENT (fixP
->fx_addsy
) != seg
) || (fixP
->fx_addsy
!= NULL
&& S_IS_EXTERNAL (fixP
->fx_addsy
)))
7185 value
= fixP
->fx_offset
;
7189 content
= s3_md_chars_to_number (buf
, s3_INSN_SIZE
);
7191 /* Don't check c-bit. */
7192 if (fixP
->fx_frag
->fr_opcode
!= 0)
7194 if ((value
& 0xfffffe00) != 0 && (value
& 0xfffffe00) != 0xfffffe00)
7196 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7197 _(" branch relocation truncate (0x%x) [-2^9 ~ 2^9]"), (unsigned int)value
);
7200 content
= s3_md_chars_to_number (buf
, s3_INSN16_SIZE
);
7202 content
= (content
& 0xfe00) | ((value
>> 1) & 0x1ff);
7203 s3_md_number_to_chars (buf
, content
, s3_INSN16_SIZE
);
7204 fixP
->fx_r_type
= BFD_RELOC_SCORE16_BRANCH
;
7209 if ((value
& 0xfff80000) != 0 && (value
& 0xfff80000) != 0xfff80000)
7211 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7212 _(" branch relocation truncate (0x%x) [-2^19 ~ 2^19]"), (unsigned int)value
);
7215 content
= s3_md_chars_to_number (buf
, s3_INSN_SIZE
);
7216 content
&= 0xfc00fc01;
7217 content
= (content
& 0xfc00fc01) | (value
& 0x3fe) | ((value
<< 6) & 0x3ff0000);
7218 s3_md_number_to_chars (buf
, content
, s3_INSN_SIZE
);
7221 case BFD_RELOC_SCORE16_JMP
:
7222 content
= s3_md_chars_to_number (buf
, s3_INSN16_SIZE
);
7224 value
= fixP
->fx_offset
& 0xfff;
7225 content
= (content
& 0xfc01) | (value
& 0xffe);
7226 s3_md_number_to_chars (buf
, content
, s3_INSN16_SIZE
);
7228 case BFD_RELOC_SCORE16_BRANCH
:
7229 content
= s3_md_chars_to_number (buf
, s3_INSN_SIZE
);
7230 /* Don't check c-bit. */
7231 if (fixP
->fx_frag
->fr_opcode
!= 0)
7233 if ((S_GET_SEGMENT (fixP
->fx_addsy
) != seg
) ||
7234 (fixP
->fx_addsy
!= NULL
&& S_IS_EXTERNAL (fixP
->fx_addsy
)))
7235 value
= fixP
->fx_offset
;
7238 if ((value
& 0xfff80000) != 0 && (value
& 0xfff80000) != 0xfff80000)
7240 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7241 _(" branch relocation truncate (0x%x) [-2^19 ~ 2^19]"), (unsigned int)value
);
7244 content
= s3_md_chars_to_number (buf
, s3_INSN_SIZE
);
7245 content
= (content
& 0xfc00fc01) | (value
& 0x3fe) | ((value
<< 6) & 0x3ff0000);
7246 s3_md_number_to_chars (buf
, content
, s3_INSN_SIZE
);
7247 fixP
->fx_r_type
= BFD_RELOC_SCORE_BRANCH
;
7253 /* In differnt section. */
7254 if ((S_GET_SEGMENT (fixP
->fx_addsy
) != seg
) ||
7255 (fixP
->fx_addsy
!= NULL
&& S_IS_EXTERNAL (fixP
->fx_addsy
)))
7256 value
= fixP
->fx_offset
;
7260 if ((value
& 0xfffffe00) != 0 && (value
& 0xfffffe00) != 0xfffffe00)
7262 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7263 _(" branch relocation truncate (0x%x) [-2^9 ~ 2^9]"), (unsigned int)value
);
7267 content
= s3_md_chars_to_number (buf
, s3_INSN16_SIZE
);
7268 content
= (content
& 0xfe00) | ((value
>> 1) & 0x1ff);
7269 s3_md_number_to_chars (buf
, content
, s3_INSN16_SIZE
);
7275 case BFD_RELOC_SCORE_BCMP
:
7276 if (fixP
->fx_frag
->fr_opcode
!= 0)
7278 char *buf_ptr
= buf
;
7281 if ((S_GET_SEGMENT (fixP
->fx_addsy
) != seg
) || (fixP
->fx_addsy
!= NULL
&& S_IS_EXTERNAL (fixP
->fx_addsy
)))
7282 value
= fixP
->fx_offset
;
7287 bcmp -> cmp! and branch, so value -= 2. */
7290 if ((value
& 0xfff80000) != 0 && (value
& 0xfff80000) != 0xfff80000)
7292 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7293 _(" branch relocation truncate (0x%x) [-2^19 ~ 2^19]"), (unsigned int)value
);
7297 content
= s3_md_chars_to_number (buf_ptr
, s3_INSN_SIZE
);
7298 content
&= 0xfc00fc01;
7299 content
= (content
& 0xfc00fc01) | (value
& 0x3fe) | ((value
<< 6) & 0x3ff0000);
7300 s3_md_number_to_chars (buf_ptr
, content
, s3_INSN_SIZE
);
7301 /* change relocation type to BFD_RELOC_SCORE_BRANCH */
7302 fixP
->fx_r_type
= BFD_RELOC_SCORE_BRANCH
;
7303 fixP
->fx_where
+=2; /* first insn is cmp! , the second insn is beq/bne */
7308 if ((S_GET_SEGMENT (fixP
->fx_addsy
) != seg
) || (fixP
->fx_addsy
!= NULL
&& S_IS_EXTERNAL (fixP
->fx_addsy
)))
7309 value
= fixP
->fx_offset
;
7313 content
= s3_md_chars_to_number (buf
, s3_INSN_SIZE
);
7315 if ((value
& 0xfffffe00) != 0 && (value
& 0xfffffe00) != 0xfffffe00)
7317 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7318 _(" branch relocation truncate (0x%x) [-2^9 ~ 2^9]"), (unsigned int)value
);
7323 content
&= ~0x03e00381;
7326 | (((value
& 0xe) >> 1) << 7)
7327 | (((value
& 0x1f0) >> 4) << 21);
7329 s3_md_number_to_chars (buf
, content
, s3_INSN_SIZE
);
7334 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
7335 s3_md_number_to_chars (buf
, value
, 1);
7339 value
= fixP
->fx_offset
;
7340 s3_md_number_to_chars (buf
, value
, 1);
7346 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
7347 s3_md_number_to_chars (buf
, value
, 2);
7351 value
= fixP
->fx_offset
;
7352 s3_md_number_to_chars (buf
, value
, 2);
7358 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
7359 md_number_to_chars (buf
, value
, 4);
7363 value
= fixP
->fx_offset
;
7364 md_number_to_chars (buf
, value
, 4);
7368 case BFD_RELOC_VTABLE_INHERIT
:
7370 if (fixP
->fx_addsy
&& !S_IS_DEFINED (fixP
->fx_addsy
) && !S_IS_WEAK (fixP
->fx_addsy
))
7371 S_SET_WEAK (fixP
->fx_addsy
);
7373 case BFD_RELOC_VTABLE_ENTRY
:
7376 case BFD_RELOC_SCORE_GPREL15
:
7377 content
= s3_md_chars_to_number (buf
, s3_INSN_SIZE
);
7379 if ((fixP
->fx_frag
->fr_opcode
!= 0) && ((content
& 0xfc1c8000) != 0x94180000))
7380 fixP
->fx_r_type
= BFD_RELOC_NONE
;
7383 case BFD_RELOC_SCORE_GOT15
:
7384 case BFD_RELOC_SCORE_DUMMY_HI16
:
7385 case BFD_RELOC_SCORE_GOT_LO16
:
7386 case BFD_RELOC_SCORE_CALL15
:
7387 case BFD_RELOC_GPREL32
:
7389 case BFD_RELOC_NONE
:
7391 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("bad relocation fixup type (%d)"), fixP
->fx_r_type
);
7396 s3_gen_reloc (asection
* section ATTRIBUTE_UNUSED
, fixS
* fixp
)
7398 static arelent
*retval
[MAX_RELOC_EXPANSION
+ 1]; /* MAX_RELOC_EXPANSION equals 2. */
7400 bfd_reloc_code_real_type code
;
7406 reloc
= retval
[0] = xmalloc (sizeof (arelent
));
7409 reloc
->sym_ptr_ptr
= xmalloc (sizeof (asymbol
*));
7410 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
7411 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
7412 reloc
->addend
= fixp
->fx_offset
;
7414 /* If this is a variant frag, we may need to adjust the existing
7415 reloc and generate a new one. */
7416 if (fixp
->fx_frag
->fr_opcode
!= NULL
&& (fixp
->fx_r_type
== BFD_RELOC_SCORE_GPREL15
))
7418 /* Update instruction imm bit. */
7423 buf
= fixp
->fx_frag
->fr_literal
+ fixp
->fx_frag
->insn_addr
;
7424 newval
= s3_md_chars_to_number (buf
, s3_INSN_SIZE
);
7425 off
= fixp
->fx_offset
>> 16;
7426 newval
|= (off
& 0x3fff) << 1;
7427 newval
|= ((off
>> 14) & 0x3) << 16;
7428 s3_md_number_to_chars (buf
, newval
, s3_INSN_SIZE
);
7430 buf
+= s3_INSN_SIZE
;
7431 newval
= s3_md_chars_to_number (buf
, s3_INSN_SIZE
);
7432 off
= fixp
->fx_offset
& 0xffff;
7433 newval
|= ((off
& 0x3fff) << 1);
7434 newval
|= (((off
>> 14) & 0x3) << 16);
7435 s3_md_number_to_chars (buf
, newval
, s3_INSN_SIZE
);
7437 retval
[1] = xmalloc (sizeof (arelent
));
7439 retval
[1]->sym_ptr_ptr
= xmalloc (sizeof (asymbol
*));
7440 *retval
[1]->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
7441 retval
[1]->address
= (reloc
->address
+ s3_RELAX_RELOC2 (fixp
->fx_frag
->fr_subtype
));
7447 retval
[1]->addend
= 0;
7448 retval
[1]->howto
= bfd_reloc_type_lookup (stdoutput
, BFD_RELOC_LO16
);
7449 gas_assert (retval
[1]->howto
!= NULL
);
7451 fixp
->fx_r_type
= BFD_RELOC_HI16_S
;
7454 code
= fixp
->fx_r_type
;
7455 switch (fixp
->fx_r_type
)
7460 code
= BFD_RELOC_32_PCREL
;
7463 case BFD_RELOC_HI16_S
:
7464 case BFD_RELOC_LO16
:
7465 case BFD_RELOC_SCORE_JMP
:
7466 case BFD_RELOC_SCORE_BRANCH
:
7467 case BFD_RELOC_SCORE16_JMP
:
7468 case BFD_RELOC_SCORE16_BRANCH
:
7469 case BFD_RELOC_SCORE_BCMP
:
7470 case BFD_RELOC_VTABLE_ENTRY
:
7471 case BFD_RELOC_VTABLE_INHERIT
:
7472 case BFD_RELOC_SCORE_GPREL15
:
7473 case BFD_RELOC_SCORE_GOT15
:
7474 case BFD_RELOC_SCORE_DUMMY_HI16
:
7475 case BFD_RELOC_SCORE_GOT_LO16
:
7476 case BFD_RELOC_SCORE_CALL15
:
7477 case BFD_RELOC_GPREL32
:
7478 case BFD_RELOC_NONE
:
7479 case BFD_RELOC_SCORE_IMM30
:
7480 case BFD_RELOC_SCORE_IMM32
:
7481 code
= fixp
->fx_r_type
;
7484 type
= _("<unknown>");
7485 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
7486 _("cannot represent %s relocation in this object file format"), type
);
7490 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
7491 if (reloc
->howto
== NULL
)
7493 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
7494 _("cannot represent %s relocation in this object file format1"),
7495 bfd_get_reloc_code_name (code
));
7498 /* HACK: Since arm ELF uses Rel instead of Rela, encode the
7499 vtable entry to be used in the relocation's section offset. */
7500 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
7501 reloc
->address
= fixp
->fx_offset
;
7507 md_assemble (char *str
)
7515 /* We handle all bad expressions here, so that we can report the faulty
7516 instruction in the error message. */
7518 md_operand (expressionS
* expr
)
7526 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
7527 for use in the a.out file, and stores them in the array pointed to by buf.
7528 This knows about the endian-ness of the target machine and does
7529 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
7530 2 (short) and 4 (long) Floating numbers are put out as a series of
7531 LITTLENUMS (shorts, here at least). */
7533 md_number_to_chars (char *buf
, valueT val
, int n
)
7536 s3_number_to_chars (buf
, val
, n
);
7538 s7_number_to_chars (buf
, val
, n
);
7541 /* Turn a string in input_line_pointer into a floating point constant
7542 of type TYPE, and store the appropriate bytes in *LITP. The number
7543 of LITTLENUMS emitted is stored in *SIZEP. An error message is
7544 returned, or NULL on OK.
7546 Note that fp constants aren't represent in the normal way on the ARM.
7547 In big endian mode, things are as expected. However, in little endian
7548 mode fp constants are big-endian word-wise, and little-endian byte-wise
7549 within the words. For example, (double) 1.1 in big endian mode is
7550 the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
7551 the byte sequence 99 99 f1 3f 9a 99 99 99. */
7553 md_atof (int type
, char *litP
, int *sizeP
)
7556 return s3_atof (type
, litP
, sizeP
);
7558 return s7_atof (type
, litP
, sizeP
);
7562 score_frag_check (fragS
* fragp ATTRIBUTE_UNUSED
)
7565 s3_frag_check (fragp
);
7567 s7_frag_check (fragp
);
7570 /* Implementation of TC_VALIDATE_FIX.
7571 Called before md_apply_fix() and after md_convert_frag(). */
7573 score_validate_fix (fixS
*fixP
)
7576 s3_validate_fix (fixP
);
7578 s7_validate_fix (fixP
);
7582 score_force_relocation (struct fix
*fixp
)
7585 return s3_force_relocation (fixp
);
7587 return s7_force_relocation (fixp
);
7590 /* Implementation of md_frag_check.
7591 Called after md_convert_frag(). */
7593 score_fix_adjustable (fixS
* fixP
)
7596 return s3_fix_adjustable (fixP
);
7598 return s7_fix_adjustable (fixP
);
7602 score_elf_final_processing (void)
7605 s3_elf_final_processing ();
7607 s7_elf_final_processing ();
7610 /* In this function, we determine whether s3_GP instruction should do relaxation,
7611 for the label being against was known now.
7612 Doing this here but not in md_relax_frag() can induce iteration times
7613 in stage of doing relax. */
7615 md_estimate_size_before_relax (fragS
* fragp
, asection
* sec ATTRIBUTE_UNUSED
)
7618 return s3_estimate_size_before_relax (fragp
, sec
);
7620 return s7_estimate_size_before_relax (fragp
, sec
);
7624 score_relax_frag (asection
* sec ATTRIBUTE_UNUSED
, fragS
* fragp
, long stretch ATTRIBUTE_UNUSED
)
7627 return s3_relax_frag (sec
, fragp
, stretch
);
7629 return s7_relax_frag (sec
, fragp
, stretch
);
7633 md_convert_frag (bfd
* abfd ATTRIBUTE_UNUSED
, segT sec ATTRIBUTE_UNUSED
, fragS
* fragp
)
7636 return s3_convert_frag (abfd
, sec
, fragp
);
7638 return s7_convert_frag (abfd
, sec
, fragp
);
7642 md_pcrel_from (fixS
* fixP
)
7645 return s3_pcrel_from (fixP
);
7647 return s7_pcrel_from (fixP
);
7650 /* Round up a section size to the appropriate boundary. */
7652 md_section_align (segT segment ATTRIBUTE_UNUSED
, valueT size
)
7655 return s3_section_align (segment
, size
);
7657 return s7_section_align (segment
, size
);
7661 md_apply_fix (fixS
*fixP
, valueT
*valP
, segT seg
)
7664 return s3_apply_fix (fixP
, valP
, seg
);
7666 return s7_apply_fix (fixP
, valP
, seg
);
7669 /* Translate internal representation of relocation info to BFD target format. */
7671 tc_gen_reloc (asection
* section ATTRIBUTE_UNUSED
, fixS
* fixp
)
7674 return s3_gen_reloc (section
, fixp
);
7676 return s7_gen_reloc (section
, fixp
);
7687 score_set_mach (const char *arg
)
7689 if (strcmp (arg
, MARCH_SCORE3
) == 0)
7695 else if (strcmp (arg
, MARCH_SCORE7
) == 0)
7700 s7_university_version
= 0;
7701 s7_vector_size
= s7_SCORE7_PIPELINE
;
7703 else if (strcmp (arg
, MARCH_SCORE5
) == 0)
7708 s7_university_version
= 0;
7709 s7_vector_size
= s7_SCORE5_PIPELINE
;
7711 else if (strcmp (arg
, MARCH_SCORE5U
) == 0)
7716 s7_university_version
= 1;
7717 s7_vector_size
= s7_SCORE5_PIPELINE
;
7721 as_bad (_("unknown architecture `%s'\n"), arg
);
7726 md_parse_option (int c
, char *arg
)
7732 target_big_endian
= 1;
7737 target_big_endian
= 0;
7741 s3_fix_data_dependency
= 1;
7742 s7_fix_data_dependency
= 1;
7745 s3_warn_fix_data_dependency
= 0;
7746 s7_warn_fix_data_dependency
= 0;
7751 s7_university_version
= 0;
7752 s7_vector_size
= s7_SCORE5_PIPELINE
;
7754 case OPTION_SCORE5U
:
7757 s7_university_version
= 1;
7758 s7_vector_size
= s7_SCORE5_PIPELINE
;
7764 s7_university_version
= 0;
7765 s7_vector_size
= s7_SCORE7_PIPELINE
;
7777 s3_g_switch_value
= atoi (arg
);
7778 s7_g_switch_value
= atoi (arg
);
7784 case OPTION_SCORE_VERSION
:
7785 printf (_("Sunplus-v2-0-0-20060510\n"));
7788 s3_score_pic
= s3_NO_PIC
; /* Score3 doesn't support PIC now. */
7789 s7_score_pic
= s7_PIC
;
7790 s3_g_switch_value
= 0; /* Must set -G num as 0 to generate s3_PIC code. */
7791 s7_g_switch_value
= 0; /* Must set -G num as 0 to generate s7_PIC code. */
7794 score_set_mach (arg
);
7803 md_show_usage (FILE * fp
)
7805 fprintf (fp
, _(" Score-specific assembler options:\n"));
7808 -EB\t\tassemble code for a big-endian cpu\n"));
7813 -EL\t\tassemble code for a little-endian cpu\n"));
7817 -FIXDD\t\tassemble code for fix data dependency\n"));
7819 -NWARN\t\tassemble code for no warning message for fix data dependency\n"));
7821 -SCORE5\t\tassemble code for target is SCORE5\n"));
7823 -SCORE5U\tassemble code for target is SCORE5U\n"));
7825 -SCORE7\t\tassemble code for target is SCORE7, this is default setting\n"));
7827 -SCORE3\t\tassemble code for target is SCORE3\n"));
7829 -march=score7\tassemble code for target is SCORE7, this is default setting\n"));
7831 -march=score3\tassemble code for target is SCORE3\n"));
7833 -USE_R1\t\tassemble code for no warning message when using temp register r1\n"));
7835 -KPIC\t\tassemble code for PIC\n"));
7837 -O0\t\tassembler will not perform any optimizations\n"));
7839 -G gpnum\tassemble code for setting gpsize and default is 8 byte\n"));
7841 -V \t\tSunplus release version \n"));