1
/* tc-score.c -- Assembler for Score
2
Copyright 2006, 2007, 2008, 2009, 2011, 2012 Free Software Foundation, Inc.
4
Brain.lin (brain.lin@sunplusct.com)
5
Mei Ligang (ligang@sunnorth.com.cn)
6
Pei-Lin Tsai (pltsai@sunplus.com)
8
This file is part of GAS, the GNU Assembler.
10
GAS is free software; you can redistribute it and/or modify
11
it under the terms of the GNU General Public License as published by
12
the Free Software Foundation; either version 3, or (at your option)
15
GAS is distributed in the hope that it will be useful,
16
but WITHOUT ANY WARRANTY; without even the implied warranty of
17
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
GNU General Public License for more details.
20
You should have received a copy of the GNU General Public License
21
along with GAS; see the file COPYING. If not, write to the Free
22
Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
25
#include "tc-score7.c"
27
static void s3_s_score_bss (int ignore ATTRIBUTE_UNUSED);
28
static void s3_s_score_text (int ignore);
29
static void s3_score_s_section (int ignore);
30
static void s3_s_change_sec (int sec);
31
static void s3_s_score_mask (int reg_type ATTRIBUTE_UNUSED);
32
static void s3_s_score_ent (int aent);
33
static void s3_s_score_frame (int ignore ATTRIBUTE_UNUSED);
34
static void s3_s_score_end (int x ATTRIBUTE_UNUSED);
35
static void s3_s_score_set (int x ATTRIBUTE_UNUSED);
36
static void s3_s_score_cpload (int ignore ATTRIBUTE_UNUSED);
37
static void s3_s_score_cprestore (int ignore ATTRIBUTE_UNUSED);
38
static void s3_s_score_gpword (int ignore ATTRIBUTE_UNUSED);
39
static void s3_s_score_cpadd (int ignore ATTRIBUTE_UNUSED);
40
static void s3_s_score_lcomm (int bytes_p);
42
static void s_score_bss (int ignore ATTRIBUTE_UNUSED);
43
static void s_score_text (int ignore);
44
static void s_section (int ignore);
45
static void s_change_sec (int sec);
46
static void s_score_mask (int reg_type ATTRIBUTE_UNUSED);
47
static void s_score_ent (int aent);
48
static void s_score_frame (int ignore ATTRIBUTE_UNUSED);
49
static void s_score_end (int x ATTRIBUTE_UNUSED);
50
static void s_score_set (int x ATTRIBUTE_UNUSED);
51
static void s_score_cpload (int ignore ATTRIBUTE_UNUSED);
52
static void s_score_cprestore (int ignore ATTRIBUTE_UNUSED);
53
static void s_score_gpword (int ignore ATTRIBUTE_UNUSED);
54
static void s_score_cpadd (int ignore ATTRIBUTE_UNUSED);
55
static void s_score_lcomm (int bytes_p);
58
static void s3_md_number_to_chars (char *buf, valueT val, int n);
59
static valueT s3_md_chars_to_number (char *buf, int n);
60
static void s3_assemble (char *str);
61
static void s3_operand (expressionS *);
62
static void s3_begin (void);
63
static void s3_number_to_chars (char *buf, valueT val, int n);
64
static 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_name;
544
/* Instruction Opcode. */
547
/* Instruction bit mask. */
550
/* Relax instruction opcode. 0x8000 imply no relaxation. */
553
/* Instruction type. */
554
enum score_insn_type type;
556
/* Function to call to parse args. */
557
void (*parms) (char *);
560
static const struct s3_asm_opcode s3_score_ldst_insns[] =
562
{"lw", 0x20000000, 0x3e000000, 0x1000, Rd_rvalueRs_SI15, s3_do_ldst_insn},
563
{"lw", 0x06000000, 0x3e000007, 0x8000, Rd_rvalueRs_preSI12, s3_do_ldst_insn},
564
{"lw", 0x0e000000, 0x3e000007, 0x0040, Rd_rvalueRs_postSI12, s3_do_ldst_insn},
565
{"lh", 0x22000000, 0x3e000000, 0x8000, Rd_rvalueRs_SI15, s3_do_ldst_insn},
566
{"lh", 0x06000001, 0x3e000007, 0x8000, Rd_rvalueRs_preSI12, s3_do_ldst_insn},
567
{"lh", 0x0e000001, 0x3e000007, 0x8000, Rd_rvalueRs_postSI12, s3_do_ldst_insn},
568
{"lhu", 0x24000000, 0x3e000000, 0x8000, Rd_rvalueRs_SI15, s3_do_ldst_insn},
569
{"lhu", 0x06000002, 0x3e000007, 0x8000, Rd_rvalueRs_preSI12, s3_do_ldst_insn},
570
{"lhu", 0x0e000002, 0x3e000007, 0x8000, Rd_rvalueRs_postSI12, s3_do_ldst_insn},
571
{"lb", 0x26000000, 0x3e000000, 0x8000, Rd_rvalueRs_SI15, s3_do_ldst_insn},
572
{"lb", 0x06000003, 0x3e000007, 0x8000, Rd_rvalueRs_preSI12, s3_do_ldst_insn},
573
{"lb", 0x0e000003, 0x3e000007, 0x8000, Rd_rvalueRs_postSI12, s3_do_ldst_insn},
574
{"sw", 0x28000000, 0x3e000000, 0x2000, Rd_lvalueRs_SI15, s3_do_ldst_insn},
575
{"sw", 0x06000004, 0x3e000007, 0x0060, Rd_lvalueRs_preSI12, s3_do_ldst_insn},
576
{"sw", 0x0e000004, 0x3e000007, 0x8000, Rd_lvalueRs_postSI12, s3_do_ldst_insn},
577
{"sh", 0x2a000000, 0x3e000000, 0x8000, Rd_lvalueRs_SI15, s3_do_ldst_insn},
578
{"sh", 0x06000005, 0x3e000007, 0x8000, Rd_lvalueRs_preSI12, s3_do_ldst_insn},
579
{"sh", 0x0e000005, 0x3e000007, 0x8000, Rd_lvalueRs_postSI12, s3_do_ldst_insn},
580
{"lbu", 0x2c000000, 0x3e000000, 0x8000, Rd_rvalueRs_SI15, s3_do_ldst_insn},
581
{"lbu", 0x06000006, 0x3e000007, 0x8000, Rd_rvalueRs_preSI12, s3_do_ldst_insn},
582
{"lbu", 0x0e000006, 0x3e000007, 0x8000, Rd_rvalueRs_postSI12, s3_do_ldst_insn},
583
{"sb", 0x2e000000, 0x3e000000, 0x8000, Rd_lvalueRs_SI15, s3_do_ldst_insn},
584
{"sb", 0x06000007, 0x3e000007, 0x8000, Rd_lvalueRs_preSI12, s3_do_ldst_insn},
585
{"sb", 0x0e000007, 0x3e000007, 0x8000, Rd_lvalueRs_postSI12, s3_do_ldst_insn},
588
static const struct s3_asm_opcode s3_score_insns[] =
590
{"abs", 0x3800000a, 0x3e007fff, 0x8000, Rd_Rs_x, s3_do_dsp3},
591
{"abs.s", 0x3800004b, 0x3e007fff, 0x8000, Rd_Rs_x, s3_do_dsp3},
592
{"add", 0x00000010, 0x3e0003ff, 0x4800, Rd_Rs_Rs, s3_do_rdrsrs},
593
{"add.c", 0x00000011, 0x3e0003ff, 0x8000, Rd_Rs_Rs, s3_do_rdrsrs},
594
{"add.s", 0x38000048, 0x3e0003ff, 0x8000, Rd_Rs_Rs, s3_do_dsp2},
595
{"addc", 0x00000012, 0x3e0003ff, 0x8000, Rd_Rs_Rs, s3_do_rdrsrs},
596
{"addc.c", 0x00000013, 0x3e0003ff, 0x8000, Rd_Rs_Rs, s3_do_rdrsrs},
597
{"addi", 0x02000000, 0x3e0e0001, 0x5c00, Rd_SI16, s3_do_rdsi16},
598
{"addi.c", 0x02000001, 0x3e0e0001, 0x8000, Rd_SI16, s3_do_rdsi16},
599
{"addis", 0x0a000000, 0x3e0e0001, 0x8000, Rd_SI16, s3_do_rdi16},
600
{"addis.c", 0x0a000001, 0x3e0e0001, 0x8000, Rd_SI16, s3_do_rdi16},
601
{"addi!", 0x5c00, 0x7c00, 0x8000, Rd_SI6, s3_do16_addi},
602
{"addri", 0x10000000, 0x3e000001, 0x8000, Rd_Rs_SI14, s3_do_rdrssi14},
603
{"addri.c", 0x10000001, 0x3e000001, 0x8000, Rd_Rs_SI14, s3_do_rdrssi14},
605
/* add.c <-> add!. */
606
{"add!", 0x4800, 0x7f00, 0x8000, Rd_Rs, s3_do16_rdrs2},
607
{"subi", 0x02000000, 0x3e0e0001, 0x8000, Rd_SI16, s3_do_sub_rdsi16},
608
{"subi.c", 0x02000001, 0x3e0e0001, 0x8000, Rd_SI16, s3_do_sub_rdsi16},
609
{"subis", 0x0a000000, 0x3e0e0001, 0x8000, Rd_SI16, s3_do_sub_rdi16},
610
{"subis.c", 0x0a000001, 0x3e0e0001, 0x8000, Rd_SI16, s3_do_sub_rdi16},
611
{"subri", 0x10000000, 0x3e000001, 0x8000, Rd_Rs_SI14, s3_do_sub_rdrssi14},
612
{"subri.c", 0x10000001, 0x3e000001, 0x8000, Rd_Rs_SI14, s3_do_sub_rdrssi14},
613
{"and", 0x00000020, 0x3e0003ff, 0x4b00, Rd_Rs_Rs, s3_do_rdrsrs},
614
{"and.c", 0x00000021, 0x3e0003ff, 0x8000, Rd_Rs_Rs, s3_do_rdrsrs},
615
{"andi", 0x02080000, 0x3e0e0001, 0x8000, Rd_I16, s3_do_rdi16},
616
{"andi.c", 0x02080001, 0x3e0e0001, 0x8000, Rd_I16, s3_do_rdi16},
617
{"andis", 0x0a080000, 0x3e0e0001, 0x8000, Rd_I16, s3_do_rdi16},
618
{"andis.c", 0x0a080001, 0x3e0e0001, 0x8000, Rd_I16, s3_do_rdi16},
619
{"andri", 0x18000000, 0x3e000001, 0x8000, Rd_Rs_I14, s3_do_rdrsi14},
620
{"andri.c", 0x18000001, 0x3e000001, 0x8000, Rd_Rs_I14, s3_do_rdrsi14},
622
/* and.c <-> and!. */
623
{"and!", 0x4b00, 0x7f00, 0x8000, Rd_Rs, s3_do16_rdrs2},
624
{"bcs", 0x08000000, 0x3e007c01, 0x8000, PC_DISP19div2, s3_do_branch},
625
{"bcc", 0x08000400, 0x3e007c01, 0x8000, PC_DISP19div2, s3_do_branch},
626
{"bcnz", 0x08003800, 0x3e007c01, 0x3200, PC_DISP19div2, s3_do_branch},
627
{"bcsl", 0x08000001, 0x3e007c01, 0x8000, PC_DISP19div2, s3_do_branch},
628
{"bccl", 0x08000401, 0x3e007c01, 0x8000, PC_DISP19div2, s3_do_branch},
629
{"bcnzl", 0x08003801, 0x3e007c01, 0x8000, PC_DISP19div2, s3_do_branch},
630
{"bcnz!", 0x3200, 0x7f00, 0x08003800, PC_DISP8div2, s3_do16_branch},
631
{"beq", 0x08001000, 0x3e007c01, 0x3800, PC_DISP19div2, s3_do_branch},
632
{"beql", 0x08001001, 0x3e007c01, 0x8000, PC_DISP19div2, s3_do_branch},
633
{"beq!", 0x3800, 0x7e00, 0x08001000, PC_DISP8div2, s3_do16_branch},
634
{"bgtu", 0x08000800, 0x3e007c01, 0x3400, PC_DISP19div2, s3_do_branch},
635
{"bgt", 0x08001800, 0x3e007c01, 0x3c00, PC_DISP19div2, s3_do_branch},
636
{"bge", 0x08002000, 0x3e007c01, 0x8000, PC_DISP19div2, s3_do_branch},
637
{"bgtul", 0x08000801, 0x3e007c01, 0x8000, PC_DISP19div2, s3_do_branch},
638
{"bgtl", 0x08001801, 0x3e007c01, 0x8000, PC_DISP19div2, s3_do_branch},
639
{"bgel", 0x08002001, 0x3e007c01, 0x8000, PC_DISP19div2, s3_do_branch},
640
{"bgtu!", 0x3400, 0x7e00, 0x08000800, PC_DISP8div2, s3_do16_branch},
641
{"bgt!", 0x3c00, 0x7e00, 0x08001800, PC_DISP8div2, s3_do16_branch},
642
{"bitclr", 0x00000028, 0x3e0003ff, 0x5000, Rd_Rs_I5, s3_do_rdrsi5},
643
{"bitclr.c", 0x00000029, 0x3e0003ff, 0x8000, Rd_Rs_I5, s3_do_rdrsi5},
645
{"mbitclr", 0x00000064, 0x3e00007e, 0x8000, Ra_I9_I5, s3_do_mbitclr},
646
{"mbitset", 0x0000006c, 0x3e00007e, 0x8000, Ra_I9_I5, s3_do_mbitset},
648
{"bitrev", 0x3800000c, 0x3e0003ff, 0x8000, Rd_Rs_Rs, s3_do_dsp2},
649
{"bitset", 0x0000002a, 0x3e0003ff, 0x5200, Rd_Rs_I5, s3_do_rdrsi5},
650
{"bitset.c", 0x0000002b, 0x3e0003ff, 0x8000, Rd_Rs_I5, s3_do_rdrsi5},
651
{"bittst.c", 0x0000002d, 0x3e0003ff, 0x5400, x_Rs_I5, s3_do_xrsi5},
652
{"bittgl", 0x0000002e, 0x3e0003ff, 0x5600, Rd_Rs_I5, s3_do_rdrsi5},
653
{"bittgl.c", 0x0000002f, 0x3e0003ff, 0x8000, Rd_Rs_I5, s3_do_rdrsi5},
654
{"bitclr!", 0x5000, 0x7e00, 0x8000, Rd_I5, s3_do16_rdi5},
655
{"bitset!", 0x5200, 0x7e00, 0x8000, Rd_I5, s3_do16_rdi5},
656
{"bittst!", 0x5400, 0x7e00, 0x8000, Rd_I5, s3_do16_rdi5},
657
{"bittgl!", 0x5600, 0x7e00, 0x8000, Rd_I5, s3_do16_rdi5},
658
{"bleu", 0x08000c00, 0x3e007c01, 0x3600, PC_DISP19div2, s3_do_branch},
659
{"ble", 0x08001c00, 0x3e007c01, 0x3e00, PC_DISP19div2, s3_do_branch},
660
{"blt", 0x08002400, 0x3e007c01, 0x8000, PC_DISP19div2, s3_do_branch},
661
{"bleul", 0x08000c01, 0x3e007c01, 0x8000, PC_DISP19div2, s3_do_branch},
662
{"blel", 0x08001c01, 0x3e007c01, 0x8000, PC_DISP19div2, s3_do_branch},
663
{"bltl", 0x08002401, 0x3e007c01, 0x8000, PC_DISP19div2, s3_do_branch},
664
{"bl", 0x08003c01, 0x3e007c01, 0x8000, PC_DISP19div2, s3_do_branch},
665
{"bleu!", 0x3600, 0x7e00, 0x08000c00, PC_DISP8div2, s3_do16_branch},
666
{"ble!", 0x3e00, 0x7e00, 0x08001c00, PC_DISP8div2, s3_do16_branch},
667
{"bmi", 0x08002800, 0x3e007c01, 0x8000, PC_DISP19div2, s3_do_branch},
668
{"bmil", 0x08002801, 0x3e007c01, 0x8000, PC_DISP19div2, s3_do_branch},
669
{"bne", 0x08001400, 0x3e007c01, 0x3a00, PC_DISP19div2, s3_do_branch},
670
{"bnel", 0x08001401, 0x3e007c01, 0x8000, PC_DISP19div2, s3_do_branch},
671
{"bne!", 0x3a00, 0x7e00, 0x08001400, PC_DISP8div2, s3_do16_branch},
672
{"bpl", 0x08002c00, 0x3e007c01, 0x8000, PC_DISP19div2, s3_do_branch},
673
{"bpll", 0x08002c01, 0x3e007c01, 0x8000, PC_DISP19div2, s3_do_branch},
674
{"brcs", 0x00000008, 0x3e007fff, 0x8000, x_Rs_x, s3_do_rs},
675
{"brcc", 0x00000408, 0x3e007fff, 0x8000, x_Rs_x, s3_do_rs},
676
{"brgtu", 0x00000808, 0x3e007fff, 0x8000, x_Rs_x, s3_do_rs},
677
{"brleu", 0x00000c08, 0x3e007fff, 0x8000, x_Rs_x, s3_do_rs},
678
{"breq", 0x00001008, 0x3e007fff, 0x8000, x_Rs_x, s3_do_rs},
679
{"brne", 0x00001408, 0x3e007fff, 0x8000, x_Rs_x, s3_do_rs},
680
{"brgt", 0x00001808, 0x3e007fff, 0x8000, x_Rs_x, s3_do_rs},
681
{"brle", 0x00001c08, 0x3e007fff, 0x8000, x_Rs_x, s3_do_rs},
682
{"brge", 0x00002008, 0x3e007fff, 0x8000, x_Rs_x, s3_do_rs},
683
{"brlt", 0x00002408, 0x3e007fff, 0x8000, x_Rs_x, s3_do_rs},
684
{"brmi", 0x00002808, 0x3e007fff, 0x8000, x_Rs_x, s3_do_rs},
685
{"brpl", 0x00002c08, 0x3e007fff, 0x8000, x_Rs_x, s3_do_rs},
686
{"brvs", 0x00003008, 0x3e007fff, 0x8000, x_Rs_x, s3_do_rs},
687
{"brvc", 0x00003408, 0x3e007fff, 0x8000, x_Rs_x, s3_do_rs},
688
{"brcnz", 0x00003808, 0x3e007fff, 0x8000, x_Rs_x, s3_do_rs},
689
{"br", 0x00003c08, 0x3e007fff, 0x0080, x_Rs_x, s3_do_rs},
690
{"brcsl", 0x00000009, 0x3e007fff, 0x8000, x_Rs_x, s3_do_rs},
691
{"brccl", 0x00000409, 0x3e007fff, 0x8000, x_Rs_x, s3_do_rs},
692
{"brgtul", 0x00000809, 0x3e007fff, 0x8000, x_Rs_x, s3_do_rs},
693
{"brleul", 0x00000c09, 0x3e007fff, 0x8000, x_Rs_x, s3_do_rs},
694
{"breql", 0x00001009, 0x3e007fff, 0x8000, x_Rs_x, s3_do_rs},
695
{"brnel", 0x00001409, 0x3e007fff, 0x8000, x_Rs_x, s3_do_rs},
696
{"brgtl", 0x00001809, 0x3e007fff, 0x8000, x_Rs_x, s3_do_rs},
697
{"brlel", 0x00001c09, 0x3e007fff, 0x8000, x_Rs_x, s3_do_rs},
698
{"brgel", 0x00002009, 0x3e007fff, 0x8000, x_Rs_x, s3_do_rs},
699
{"brltl", 0x00002409, 0x3e007fff, 0x8000, x_Rs_x, s3_do_rs},
700
{"brmil", 0x00002809, 0x3e007fff, 0x8000, x_Rs_x, s3_do_rs},
701
{"brpll", 0x00002c09, 0x3e007fff, 0x8000, x_Rs_x, s3_do_rs},
702
{"brvsl", 0x00003009, 0x3e007fff, 0x8000, x_Rs_x, s3_do_rs},
703
{"brvcl", 0x00003409, 0x3e007fff, 0x8000, x_Rs_x, s3_do_rs},
704
{"brcnzl", 0x00003809, 0x3e007fff, 0x8000, x_Rs_x, s3_do_rs},
705
{"brl", 0x00003c09, 0x3e007fff, 0x00a0, x_Rs_x, s3_do_rs},
706
{"br!", 0x0080, 0x7fe0, 0x8000, x_Rs, s3_do16_br},
707
{"brl!", 0x00a0, 0x7fe0, 0x8000, x_Rs, s3_do16_br},
708
{"brr!", 0x00c0, 0x7fe0, 0x8000, x_Rs, s3_do16_brr},
709
{"bvs", 0x08003000, 0x3e007c01, 0x8000, PC_DISP19div2, s3_do_branch},
710
{"bvc", 0x08003400, 0x3e007c01, 0x8000, PC_DISP19div2, s3_do_branch},
711
{"bvsl", 0x08003001, 0x3e007c01, 0x8000, PC_DISP19div2, s3_do_branch},
712
{"bvcl", 0x08003401, 0x3e007c01, 0x8000, PC_DISP19div2, s3_do_branch},
713
{"b!", 0x3000, 0x7e00, 0x08003c00, PC_DISP8div2, s3_do16_branch},
714
{"b", 0x08003c00, 0x3e007c01, 0x3000, PC_DISP19div2, s3_do_branch},
715
{"cache", 0x30000000, 0x3ff00000, 0x8000, OP5_rvalueRs_SI15, s3_do_cache},
716
{"ceinst", 0x38000000, 0x3e000000, 0x8000, I5_Rs_Rs_I5_OP5, s3_do_ceinst},
717
{"clz", 0x0000001c, 0x3e007fff, 0x8000, Rd_Rs_x, s3_do_rdrs},
718
{"cmp.c", 0x00300019, 0x3ff003ff, 0x4400, x_Rs_Rs, s3_do_rsrs},
719
{"cmpz.c", 0x0030001b, 0x3ff07fff, 0x8000, x_Rs_x, s3_do_rs},
720
{"cmpi.c", 0x02040001, 0x3e0e0001, 0x6000, Rd_SI16, s3_do_rdsi16},
722
/* cmp.c <-> cmp!. */
723
{"cmp!", 0x4400, 0x7c00, 0x8000, Rd_Rs, s3_do16_mv_cmp},
724
{"cmpi!", 0x6000, 0x7c00, 0x8000, Rd_SI5, s3_do16_cmpi},
725
{"cop1", 0x0c00000c, 0x3e00001f, 0x8000, Rd_Rs_Rs_imm, s3_do_crdcrscrsimm5},
726
{"cop2", 0x0c000014, 0x3e00001f, 0x8000, Rd_Rs_Rs_imm, s3_do_crdcrscrsimm5},
727
{"cop3", 0x0c00001c, 0x3e00001f, 0x8000, Rd_Rs_Rs_imm, s3_do_crdcrscrsimm5},
728
{"drte", 0x0c0000a4, 0x3e0003ff, 0x8000, NO_OPD, s3_do_empty},
729
{"disint!", 0x00e0, 0xffe1, 0x8000, NO16_OPD, s3_do16_int},
730
{"enint!", 0x00e1, 0xffe1, 0x8000, NO16_OPD, s3_do16_int},
731
{"extsb", 0x00000058, 0x3e0003ff, 0x8000, Rd_Rs_x, s3_do_rdrs},
732
{"extsb.c", 0x00000059, 0x3e0003ff, 0x8000, Rd_Rs_x, s3_do_rdrs},
733
{"extsh", 0x0000005a, 0x3e0003ff, 0x8000, Rd_Rs_x, s3_do_rdrs},
734
{"extsh.c", 0x0000005b, 0x3e0003ff, 0x8000, Rd_Rs_x, s3_do_rdrs},
735
{"extzb", 0x0000005c, 0x3e0003ff, 0x8000, Rd_Rs_x, s3_do_rdrs},
736
{"extzb.c", 0x0000005d, 0x3e0003ff, 0x8000, Rd_Rs_x, s3_do_rdrs},
737
{"extzh", 0x0000005e, 0x3e0003ff, 0x8000, Rd_Rs_x, s3_do_rdrs},
738
{"extzh.c", 0x0000005f, 0x3e0003ff, 0x8000, Rd_Rs_x, s3_do_rdrs},
739
{"jl", 0x04000001, 0x3e000001, 0x8000, PC_DISP24div2, s3_do_jump},
740
{"j", 0x04000000, 0x3e000001, 0x8000, PC_DISP24div2, s3_do_jump},
741
{"alw", 0x0000000c, 0x3e0003ff, 0x8000, Rd_rvalue32Rs, s3_do_ldst_atomic},
742
{"lcb", 0x00000060, 0x3e0003ff, 0x8000, x_rvalueRs_post4, s3_do_ldst_unalign},
743
{"lcw", 0x00000062, 0x3e0003ff, 0x8000, Rd_rvalueRs_post4, s3_do_ldst_unalign},
744
{"lce", 0x00000066, 0x3e0003ff, 0x8000, Rd_rvalueRs_post4, s3_do_ldst_unalign},
745
{"ldc1", 0x0c00000a, 0x3e00001f, 0x8000, Rd_rvalueRs_SI10, s3_do_ldst_cop},
746
{"ldc2", 0x0c000012, 0x3e00001f, 0x8000, Rd_rvalueRs_SI10, s3_do_ldst_cop},
747
{"ldc3", 0x0c00001a, 0x3e00001f, 0x8000, Rd_rvalueRs_SI10, s3_do_ldst_cop},
750
{"ldi", 0x020c0000, 0x3e0e0000, 0x6400, Rd_SI16, s3_do_rdsi16},
751
{"ldis", 0x0a0c0000, 0x3e0e0000, 0x8000, Rd_I16, s3_do_ldis},
754
{"ldiu!", 0x6400, 0x7c00, 0x8000, Rd_I5, s3_do16_ldiu},
756
/*ltbb! , ltbh! ltbw! */
757
{"ltbw", 0x00000032, 0x03ff, 0x8000, Rd_Rs_Rs, s3_do_ltb},
758
{"ltbh", 0x00000132, 0x03ff, 0x8000, Rd_Rs_Rs, s3_do_ltb},
759
{"ltbb", 0x00000332, 0x03ff, 0x8000, Rd_Rs_Rs, s3_do_ltb},
760
{"lw!", 0x1000, 0x7000, 0x8000, Rd_rvalueRs, s3_do16_ldst_insn},
761
{"mfcel", 0x00000448, 0x3e007fff, 0x8000, Rd_x_x, s3_do_rd},
762
{"mfcel!", 0x7100, 0x7ff0, 0x00000448, x_Rs, s3_do16_dsp},
763
{"mad", 0x38000000, 0x3ff003ff, 0x8000, x_Rs_Rs, s3_do_dsp},
764
{"mad.f!", 0x7400, 0x7f00, 0x38000080, Rd_Rs, s3_do16_dsp2},
765
{"madh", 0x38000203, 0x3ff003ff, 0x8000, x_Rs_Rs, s3_do_dsp},
766
{"madh.fs", 0x380002c3, 0x3ff003ff, 0x8000, x_Rs_Rs, s3_do_dsp},
767
{"madh.fs!", 0x7b00, 0x7f00, 0x380002c3, Rd_Rs, s3_do16_dsp2},
768
{"madl", 0x38000002, 0x3ff003ff, 0x8000, x_Rs_Rs, s3_do_dsp},
769
{"madl.fs", 0x380000c2, 0x3ff003ff, 0x8000, x_Rs_Rs, s3_do_dsp},
770
{"madl.fs!", 0x7a00, 0x7f00, 0x380000c2, Rd_Rs, s3_do16_dsp2},
771
{"madu", 0x38000020, 0x3ff003ff, 0x8000, x_Rs_Rs, s3_do_dsp},
772
{"madu!", 0x7500, 0x7f00, 0x38000020, Rd_Rs, s3_do16_dsp2},
773
{"mad.f", 0x38000080, 0x3ff003ff, 0x8000, x_Rs_Rs, s3_do_dsp},
774
{"max", 0x38000007, 0x3e0003ff, 0x8000, Rd_Rs_Rs, s3_do_dsp2},
775
{"mazh", 0x38000303, 0x3ff003ff, 0x8000, x_Rs_Rs, s3_do_dsp},
776
{"mazh.f", 0x38000383, 0x3ff003ff, 0x8000, x_Rs_Rs, s3_do_dsp},
777
{"mazh.f!", 0x7900, 0x7f00, 0x3800038c, Rd_Rs, s3_do16_dsp2},
778
{"mazl", 0x38000102, 0x3ff003ff, 0x8000, x_Rs_Rs, s3_do_dsp},
779
{"mazl.f", 0x38000182, 0x3ff003ff, 0x8000, x_Rs_Rs, s3_do_dsp},
780
{"mazl.f!", 0x7800, 0x7f00, 0x38000182, Rd_Rs, s3_do16_dsp2},
781
{"mfceh", 0x00000848, 0x3e007fff, 0x8000, Rd_x_x, s3_do_rd},
782
{"mfceh!", 0x7110, 0x7ff0, 0x00000848, x_Rs, s3_do16_dsp},
783
{"mfcehl", 0x00000c48, 0x3e007fff, 0x8000, Rd_Rs_x, s3_do_rdrs},
784
{"mfsr", 0x00000050, 0x3e0003ff, 0x8000, Rd_x_I5, s3_do_rdsrs},
785
{"mfcr", 0x0c000001, 0x3e00001f, 0x8000, Rd_Rs_x, s3_do_rdcrs},
786
{"mfc1", 0x0c000009, 0x3e00001f, 0x8000, Rd_Rs_x, s3_do_rdcrs},
787
{"mfc2", 0x0c000011, 0x3e00001f, 0x8000, Rd_Rs_x, s3_do_rdcrs},
788
{"mfc3", 0x0c000019, 0x3e00001f, 0x8000, Rd_Rs_x, s3_do_rdcrs},
789
{"mfcc1", 0x0c00000f, 0x3e00001f, 0x8000, Rd_Rs_x, s3_do_rdcrs},
790
{"mfcc2", 0x0c000017, 0x3e00001f, 0x8000, Rd_Rs_x, s3_do_rdcrs},
791
{"mfcc3", 0x0c00001f, 0x3e00001f, 0x8000, Rd_Rs_x, s3_do_rdcrs},
792
{"min", 0x38000006, 0x3e0003ff, 0x8000, Rd_Rs_Rs, s3_do_dsp2},
793
{"msb", 0x38000001, 0x3ff003ff, 0x8000, x_Rs_Rs, s3_do_dsp},
794
{"msb.f!", 0x7600, 0x7f00, 0x38000081, Rd_Rs, s3_do16_dsp2},
795
{"msbh", 0x38000205, 0x3ff003ff, 0x8000, x_Rs_Rs, s3_do_dsp},
796
{"msbh.fs", 0x380002c5, 0x3ff003ff, 0x8000, x_Rs_Rs, s3_do_dsp},
797
{"msbh.fs!", 0x7f00, 0x7f00, 0x380002c5, Rd_Rs, s3_do16_dsp2},
798
{"msbl", 0x38000004, 0x3ff003ff, 0x8000, x_Rs_Rs, s3_do_dsp},
799
{"msbl.fs", 0x380000c4, 0x3ff003ff, 0x8000, x_Rs_Rs, s3_do_dsp},
800
{"msbl.fs!", 0x7e00, 0x7f00, 0x380000c4, Rd_Rs, s3_do16_dsp2},
801
{"msbu", 0x38000021, 0x3ff003ff, 0x8000, x_Rs_Rs, s3_do_dsp},
802
{"msbu!", 0x7700, 0x7f00, 0x38000021, Rd_Rs, s3_do16_dsp2},
803
{"msb.f", 0x38000081, 0x3ff003ff, 0x8000, x_Rs_Rs, s3_do_dsp},
804
{"mszh", 0x38000305, 0x3ff003ff, 0x8000, x_Rs_Rs, s3_do_dsp},
805
{"mszh.f", 0x38000385, 0x3ff003ff, 0x8000, x_Rs_Rs, s3_do_dsp},
806
{"mszh.f!", 0x7d00, 0x7f00, 0x38000385, Rd_Rs, s3_do16_dsp2},
807
{"mszl", 0x38000104, 0x3ff003ff, 0x8000, x_Rs_Rs, s3_do_dsp},
808
{"mszl.f", 0x38000184, 0x3ff003ff, 0x8000, x_Rs_Rs, s3_do_dsp},
809
{"mszl.f!", 0x7c00, 0x7f00, 0x38000184, Rd_Rs, s3_do16_dsp2},
810
{"mtcel!", 0x7000, 0x7ff0, 0x0000044a, x_Rs, s3_do16_dsp},
811
{"mtcel", 0x0000044a, 0x3e007fff, 0x8000, Rd_x_x, s3_do_rd},
812
{"mtceh", 0x0000084a, 0x3e007fff, 0x8000, Rd_x_x, s3_do_rd},
813
{"mtceh!", 0x7010, 0x7ff0, 0x0000084a, x_Rs, s3_do16_dsp},
814
{"mtcehl", 0x00000c4a, 0x3e007fff, 0x8000, Rd_Rs_x, s3_do_rdrs},
815
{"mtsr", 0x00000052, 0x3e0003ff, 0x8000, x_Rs_I5, s3_do_rdsrs},
816
{"mtcr", 0x0c000000, 0x3e00001f, 0x8000, Rd_Rs_x, s3_do_rdcrs},
817
{"mtc1", 0x0c000008, 0x3e00001f, 0x8000, Rd_Rs_x, s3_do_rdcrs},
818
{"mtc2", 0x0c000010, 0x3e00001f, 0x8000, Rd_Rs_x, s3_do_rdcrs},
819
{"mtc3", 0x0c000018, 0x3e00001f, 0x8000, Rd_Rs_x, s3_do_rdcrs},
820
{"mtcc1", 0x0c00000e, 0x3e00001f, 0x8000, Rd_Rs_x, s3_do_rdcrs},
821
{"mtcc2", 0x0c000016, 0x3e00001f, 0x8000, Rd_Rs_x, s3_do_rdcrs},
822
{"mtcc3", 0x0c00001e, 0x3e00001f, 0x8000, Rd_Rs_x, s3_do_rdcrs},
823
{"mul.f!", 0x7200, 0x7f00, 0x00000041, Rd_Rs, s3_do16_dsp2},
824
{"mulu!", 0x7300, 0x7f00, 0x00000042, Rd_Rs, s3_do16_dsp2},
825
{"mulr.l", 0x00000140, 0x3e0003ff, 0x8000, Insn_Type_SYN, s3_do_rdrsrs},
826
{"mulr.h", 0x00000240, 0x3e0003ff, 0x8000, Insn_Type_SYN, s3_do_rdrsrs},
827
{"mulr", 0x00000340, 0x3e0003ff, 0x8000, Insn_Type_SYN, s3_do_rdrsrs},
828
{"mulr.lf", 0x00000141, 0x3e0003ff, 0x8000, Insn_Type_SYN, s3_do_rdrsrs},
829
{"mulr.hf", 0x00000241, 0x3e0003ff, 0x8000, Insn_Type_SYN, s3_do_rdrsrs},
830
{"mulr.f", 0x00000341, 0x3e0003ff, 0x8000, Insn_Type_SYN, s3_do_rdrsrs},
831
{"mulur.l", 0x00000142, 0x3e0003ff, 0x8000, Insn_Type_SYN, s3_do_rdrsrs},
832
{"mulur.h", 0x00000242, 0x3e0003ff, 0x8000, Insn_Type_SYN, s3_do_rdrsrs},
833
{"mulur", 0x00000342, 0x3e0003ff, 0x8000, Insn_Type_SYN, s3_do_rdrsrs},
834
{"divr.q", 0x00000144, 0x3e0003ff, 0x8000, Insn_Type_SYN, s3_do_rdrsrs},
835
{"divr.r", 0x00000244, 0x3e0003ff, 0x8000, Insn_Type_SYN, s3_do_rdrsrs},
836
{"divr", 0x00000344, 0x3e0003ff, 0x8000, Insn_Type_SYN, s3_do_rdrsrs},
837
{"divur.q", 0x00000146, 0x3e0003ff, 0x8000, Insn_Type_SYN, s3_do_rdrsrs},
838
{"divur.r", 0x00000246, 0x3e0003ff, 0x8000, Insn_Type_SYN, s3_do_rdrsrs},
839
{"divur", 0x00000346, 0x3e0003ff, 0x8000, Insn_Type_SYN, s3_do_rdrsrs},
840
{"mvcs", 0x00000056, 0x3e007fff, 0x8000, Rd_Rs_x, s3_do_rdrs},
841
{"mvcc", 0x00000456, 0x3e007fff, 0x8000, Rd_Rs_x, s3_do_rdrs},
842
{"mvgtu", 0x00000856, 0x3e007fff, 0x8000, Rd_Rs_x, s3_do_rdrs},
843
{"mvleu", 0x00000c56, 0x3e007fff, 0x8000, Rd_Rs_x, s3_do_rdrs},
844
{"mveq", 0x00001056, 0x3e007fff, 0x8000, Rd_Rs_x, s3_do_rdrs},
845
{"mvne", 0x00001456, 0x3e007fff, 0x8000, Rd_Rs_x, s3_do_rdrs},
846
{"mvgt", 0x00001856, 0x3e007fff, 0x8000, Rd_Rs_x, s3_do_rdrs},
847
{"mvle", 0x00001c56, 0x3e007fff, 0x8000, Rd_Rs_x, s3_do_rdrs},
848
{"mvge", 0x00002056, 0x3e007fff, 0x8000, Rd_Rs_x, s3_do_rdrs},
849
{"mvlt", 0x00002456, 0x3e007fff, 0x8000, Rd_Rs_x, s3_do_rdrs},
850
{"mvmi", 0x00002856, 0x3e007fff, 0x8000, Rd_Rs_x, s3_do_rdrs},
851
{"mvpl", 0x00002c56, 0x3e007fff, 0x8000, Rd_Rs_x, s3_do_rdrs},
852
{"mvvs", 0x00003056, 0x3e007fff, 0x8000, Rd_Rs_x, s3_do_rdrs},
853
{"mvvc", 0x00003456, 0x3e007fff, 0x8000, Rd_Rs_x, s3_do_rdrs},
856
{"mv", 0x00003c56, 0x3e007fff, 0x4000, Rd_Rs_x, s3_do_rdrs},
857
{"mv!", 0x4000, 0x7c00, 0x8000, Rd_Rs, s3_do16_mv_cmp},
858
{"neg", 0x0000001e, 0x3e0003ff, 0x8000, Rd_x_Rs, s3_do_rdxrs},
859
{"neg.c", 0x0000001f, 0x3e0003ff, 0x8000, Rd_x_Rs, s3_do_rdxrs},
860
{"nop", 0x00000000, 0x3e0003ff, 0x0000, NO_OPD, s3_do_empty},
861
{"not", 0x00000024, 0x3e0003ff, 0x8000, Rd_Rs_x, s3_do_rdrs},
862
{"not.c", 0x00000025, 0x3e0003ff, 0x8000, Rd_Rs_x, s3_do_rdrs},
863
{"nop!", 0x0000, 0x7fff, 0x8000, NO16_OPD, s3_do_empty},
864
{"or", 0x00000022, 0x3e0003ff, 0x4a00, Rd_Rs_Rs, s3_do_rdrsrs},
865
{"or.c", 0x00000023, 0x3e0003ff, 0x8000, Rd_Rs_Rs, s3_do_rdrsrs},
866
{"ori", 0x020a0000, 0x3e0e0001, 0x8000, Rd_I16, s3_do_rdi16},
867
{"ori.c", 0x020a0001, 0x3e0e0001, 0x8000, Rd_I16, s3_do_rdi16},
868
{"oris", 0x0a0a0000, 0x3e0e0001, 0x8000, Rd_I16, s3_do_rdi16},
869
{"oris.c", 0x0a0a0001, 0x3e0e0001, 0x8000, Rd_I16, s3_do_rdi16},
870
{"orri", 0x1a000000, 0x3e000001, 0x8000, Rd_Rs_I14, s3_do_rdrsi14},
871
{"orri.c", 0x1a000001, 0x3e000001, 0x8000, Rd_Rs_I14, s3_do_rdrsi14},
874
{"or!", 0x4a00, 0x7f00, 0x8000, Rd_Rs, s3_do16_rdrs2},
875
{"pflush", 0x0000000a, 0x3e0003ff, 0x8000, NO_OPD, s3_do_empty},
876
{"pop!", 0x0040, 0x7fe0, 0x8000, Rd_rvalueRs, s3_do16_push_pop},
877
{"push!", 0x0060, 0x7fe0, 0x8000, Rd_lvalueRs, s3_do16_push_pop},
879
{"rpop!", 0x6800, 0x7c00, 0x8000, Rd_I5, s3_do16_rpop},
880
{"rpush!", 0x6c00, 0x7c00, 0x8000, Rd_I5, s3_do16_rpush},
882
{"ror", 0x00000038, 0x3e0003ff, 0x8000, Rd_Rs_Rs, s3_do_rdrsrs},
883
{"ror.c", 0x00000039, 0x3e0003ff, 0x8000, Rd_Rs_Rs, s3_do_rdrsrs},
884
{"rorc.c", 0x0000003b, 0x3e0003ff, 0x8000, Rd_Rs_Rs, s3_do_rdrsrs},
885
{"rol", 0x0000003c, 0x3e0003ff, 0x8000, Rd_Rs_Rs, s3_do_rdrsrs},
886
{"rol.c", 0x0000003d, 0x3e0003ff, 0x8000, Rd_Rs_Rs, s3_do_rdrsrs},
887
{"rolc.c", 0x0000003f, 0x3e0003ff, 0x8000, Rd_Rs_Rs, s3_do_rdrsrs},
888
{"rori", 0x00000078, 0x3e0003ff, 0x8000, Rd_Rs_I5, s3_do_rdrsi5},
889
{"rori.c", 0x00000079, 0x3e0003ff, 0x8000, Rd_Rs_I5, s3_do_rdrsi5},
890
{"roric.c", 0x0000007b, 0x3e0003ff, 0x8000, Rd_Rs_I5, s3_do_rdrsi5},
891
{"roli", 0x0000007c, 0x3e0003ff, 0x8000, Rd_Rs_I5, s3_do_rdrsi5},
892
{"roli.c", 0x0000007d, 0x3e0003ff, 0x8000, Rd_Rs_I5, s3_do_rdrsi5},
893
{"rolic.c", 0x0000007f, 0x3e0003ff, 0x8000, Rd_Rs_I5, s3_do_rdrsi5},
894
{"rte", 0x0c000084, 0x3e0003ff, 0x8000, NO_OPD, s3_do_empty},
895
{"asw", 0x0000000e, 0x3e0003ff, 0x8000, Rd_lvalue32Rs, s3_do_ldst_atomic},
896
{"scb", 0x00000068, 0x3e0003ff, 0x8000, Rd_lvalueRs_post4, s3_do_ldst_unalign},
897
{"scw", 0x0000006a, 0x3e0003ff, 0x8000, Rd_lvalueRs_post4, s3_do_ldst_unalign},
898
{"sce", 0x0000006e, 0x3e0003ff, 0x8000, x_lvalueRs_post4, s3_do_ldst_unalign},
899
{"sdbbp", 0x00000006, 0x3e0003ff, 0x0020, x_I5_x, s3_do_xi5x},
900
{"sdbbp!", 0x0020, 0x7fe0, 0x8000, Rd_I5, s3_do16_xi5},
901
{"sleep", 0x0c0000c4, 0x3e0003ff, 0x8000, NO_OPD, s3_do_empty},
902
{"rti", 0x0c0000e4, 0x3e0003ff, 0x8000, NO_OPD, s3_do_empty},
903
{"sll", 0x00000030, 0x3e0003ff, 0x8000, Rd_Rs_Rs, s3_do_rdrsrs},
904
{"sll.c", 0x00000031, 0x3e0003ff, 0x8000, Rd_Rs_Rs, s3_do_rdrsrs},
905
{"sll.s", 0x3800004e, 0x3e0003ff, 0x8000, Rd_Rs_Rs, s3_do_dsp2},
906
{"slli", 0x00000070, 0x3e0003ff, 0x5800, Rd_Rs_I5, s3_do_rdrsi5},
907
{"slli.c", 0x00000071, 0x3e0003ff, 0x8000, Rd_Rs_I5, s3_do_rdrsi5},
909
/* slli.c <-> slli!. */
910
{"slli!", 0x5800, 0x7e00, 0x8000, Rd_I5, s3_do16_slli_srli},
911
{"srl", 0x00000034, 0x3e0003ff, 0x8000, Rd_Rs_Rs, s3_do_rdrsrs},
912
{"srl.c", 0x00000035, 0x3e0003ff, 0x8000, Rd_Rs_Rs, s3_do_rdrsrs},
913
{"sra", 0x00000036, 0x3e0003ff, 0x8000, Rd_Rs_Rs, s3_do_rdrsrs},
914
{"sra.c", 0x00000037, 0x3e0003ff, 0x8000, Rd_Rs_Rs, s3_do_rdrsrs},
915
{"srli", 0x00000074, 0x3e0003ff, 0x5a00, Rd_Rs_I5, s3_do_rdrsi5},
916
{"srli.c", 0x00000075, 0x3e0003ff, 0x8000, Rd_Rs_I5, s3_do_rdrsi5},
917
{"srai", 0x00000076, 0x3e0003ff, 0x8000, Rd_Rs_I5, s3_do_rdrsi5},
918
{"srai.c", 0x00000077, 0x3e0003ff, 0x8000, Rd_Rs_I5, s3_do_rdrsi5},
920
/* srli.c <-> srli!. */
921
{"srli!", 0x5a00, 0x7e00, 0x8000, Rd_Rs, s3_do16_slli_srli},
922
{"stc1", 0x0c00000b, 0x3e00001f, 0x8000, Rd_lvalueRs_SI10, s3_do_ldst_cop},
923
{"stc2", 0x0c000013, 0x3e00001f, 0x8000, Rd_lvalueRs_SI10, s3_do_ldst_cop},
924
{"stc3", 0x0c00001b, 0x3e00001f, 0x8000, Rd_lvalueRs_SI10, s3_do_ldst_cop},
925
{"sub", 0x00000014, 0x3e0003ff, 0x4900, Rd_Rs_Rs, s3_do_rdrsrs},
926
{"sub.c", 0x00000015, 0x3e0003ff, 0x8000, Rd_Rs_Rs, s3_do_rdrsrs},
927
{"sub.s", 0x38000049, 0x3e0003ff, 0x8000, Rd_Rs_Rs, s3_do_dsp2},
928
{"subc", 0x00000016, 0x3e0003ff, 0x8000, Rd_Rs_Rs, s3_do_rdrsrs},
929
{"subc.c", 0x00000017, 0x3e0003ff, 0x8000, Rd_Rs_Rs, s3_do_rdrsrs},
931
/* sub.c <-> sub!. */
932
{"sub!", 0x4900, 0x7f00, 0x8000, Rd_Rs, s3_do16_rdrs2},
933
{"sw!", 0x2000, 0x7000, 0x8000, Rd_lvalueRs, s3_do16_ldst_insn},
934
{"syscall", 0x00000002, 0x3e0003ff, 0x8000, I15, s3_do_i15},
935
{"trapcs", 0x00000004, 0x3e007fff, 0x8000, x_I5_x, s3_do_xi5x},
936
{"trapcc", 0x00000404, 0x3e007fff, 0x8000, x_I5_x, s3_do_xi5x},
937
{"trapgtu", 0x00000804, 0x3e007fff, 0x8000, x_I5_x, s3_do_xi5x},
938
{"trapleu", 0x00000c04, 0x3e007fff, 0x8000, x_I5_x, s3_do_xi5x},
939
{"trapeq", 0x00001004, 0x3e007fff, 0x8000, x_I5_x, s3_do_xi5x},
940
{"trapne", 0x00001404, 0x3e007fff, 0x8000, x_I5_x, s3_do_xi5x},
941
{"trapgt", 0x00001804, 0x3e007fff, 0x8000, x_I5_x, s3_do_xi5x},
942
{"traple", 0x00001c04, 0x3e007fff, 0x8000, x_I5_x, s3_do_xi5x},
943
{"trapge", 0x00002004, 0x3e007fff, 0x8000, x_I5_x, s3_do_xi5x},
944
{"traplt", 0x00002404, 0x3e007fff, 0x8000, x_I5_x, s3_do_xi5x},
945
{"trapmi", 0x00002804, 0x3e007fff, 0x8000, x_I5_x, s3_do_xi5x},
946
{"trappl", 0x00002c04, 0x3e007fff, 0x8000, x_I5_x, s3_do_xi5x},
947
{"trapvs", 0x00003004, 0x3e007fff, 0x8000, x_I5_x, s3_do_xi5x},
948
{"trapvc", 0x00003404, 0x3e007fff, 0x8000, x_I5_x, s3_do_xi5x},
949
{"trap", 0x00003c04, 0x3e007fff, 0x8000, x_I5_x, s3_do_xi5x},
950
{"xor", 0x00000026, 0x3e0003ff, 0x8000, Rd_Rs_Rs, s3_do_rdrsrs},
951
{"xor.c", 0x00000027, 0x3e0003ff, 0x8000, Rd_Rs_Rs, s3_do_rdrsrs},
953
/* Macro instruction. */
954
{"li", 0x020c0000, 0x3e0e0000, 0x8000, Insn_Type_SYN, s3_do_macro_li_rdi32},
956
/* la reg, imm32 -->(1) ldi reg, simm16
957
(2) ldis reg, %HI(imm32)
960
la reg, symbol -->(1) lis reg, %HI(imm32)
961
ori reg, %LO(imm32) */
962
{"la", 0x020c0000, 0x3e0e0000, 0x8000, Insn_Type_SYN, s3_do_macro_la_rdi32},
963
{"bcmpeqz", 0x0000004c, 0x3e00007e, 0x8000, Insn_BCMP, s3_do_macro_bcmpz},
964
{"bcmpeq", 0x0000004c, 0x3e00007e, 0x8000, Insn_BCMP, s3_do_macro_bcmp},
965
{"bcmpnez", 0x0000004e, 0x3e00007e, 0x8000, Insn_BCMP, s3_do_macro_bcmpz},
966
{"bcmpne", 0x0000004e, 0x3e00007e, 0x8000, Insn_BCMP, s3_do_macro_bcmp},
967
{"div", 0x00000044, 0x3e0003ff, 0x8000, Insn_Type_SYN, s3_do_macro_mul_rdrsrs},
968
{"divu", 0x00000046, 0x3e0003ff, 0x8000, Insn_Type_SYN, s3_do_macro_mul_rdrsrs},
969
{"rem", 0x00000044, 0x3e0003ff, 0x8000, Insn_Type_SYN, s3_do_macro_mul_rdrsrs},
970
{"remu", 0x00000046, 0x3e0003ff, 0x8000, Insn_Type_SYN, s3_do_macro_mul_rdrsrs},
971
{"mul", 0x00000040, 0x3e0003ff, 0x8000, Insn_Type_SYN, s3_do_macro_mul_rdrsrs},
972
{"mulu", 0x00000042, 0x3e0003ff, 0x8000, Insn_Type_SYN, s3_do_macro_mul_rdrsrs},
973
{"maz", 0x00000040, 0x3e0003ff, 0x8000, Insn_Type_SYN, s3_do_macro_mul_rdrsrs},
974
{"mazu", 0x00000042, 0x3e0003ff, 0x8000, Insn_Type_SYN, s3_do_macro_mul_rdrsrs},
975
{"mul.f", 0x00000041, 0x3e0003ff, 0x8000, Insn_Type_SYN, s3_do_macro_mul_rdrsrs},
976
{"maz.f", 0x00000041, 0x3e0003ff, 0x8000, Insn_Type_SYN, s3_do_macro_mul_rdrsrs},
977
{"lb", INSN_LB, 0x00000000, 0x8000, Insn_Type_SYN, s3_do_macro_ldst_label},
978
{"lbu", INSN_LBU, 0x00000000, 0x8000, Insn_Type_SYN, s3_do_macro_ldst_label},
979
{"lh", INSN_LH, 0x00000000, 0x8000, Insn_Type_SYN, s3_do_macro_ldst_label},
980
{"lhu", INSN_LHU, 0x00000000, 0x8000, Insn_Type_SYN, s3_do_macro_ldst_label},
981
{"lw", INSN_LW, 0x00000000, 0x1000, Insn_Type_SYN, s3_do_macro_ldst_label},
982
{"sb", INSN_SB, 0x00000000, 0x8000, Insn_Type_SYN, s3_do_macro_ldst_label},
983
{"sh", INSN_SH, 0x00000000, 0x8000, Insn_Type_SYN, s3_do_macro_ldst_label},
984
{"sw", INSN_SW, 0x00000000, 0x2000, Insn_Type_SYN, s3_do_macro_ldst_label},
986
/* Assembler use internal. */
987
{"ld_i32hi", 0x0a0c0000, 0x3e0e0000, 0x8000, Insn_internal, s3_do_macro_rdi32hi},
988
{"ld_i32lo", 0x020a0000, 0x3e0e0001, 0x8000, Insn_internal, s3_do_macro_rdi32lo},
989
{"ldis_pic", 0x0a0c0000, 0x3e0e0000, 0x8000, Insn_internal, s3_do_rdi16_pic},
990
{"addi_s_pic",0x02000000, 0x3e0e0001, 0x8000, Insn_internal, s3_do_addi_s_pic},
991
{"addi_u_pic",0x02000000, 0x3e0e0001, 0x8000, Insn_internal, s3_do_addi_u_pic},
992
{"lw_pic", 0x20000000, 0x3e000000, 0x8000, Insn_internal, s3_do_lw_pic},
994
/* 48-bit instructions. */
995
{"sdbbp48", 0x000000000000LL, 0x1c000000001fLL, 0x8000, Rd_I32, s3_do_sdbbp48},
996
{"ldi48", 0x000000000001LL, 0x1c000000001fLL, 0x8000, Rd_I32, s3_do_ldi48},
997
{"lw48", 0x000000000002LL, 0x1c000000001fLL, 0x8000, Rd_I30, s3_do_lw48},
998
{"sw48", 0x000000000003LL, 0x1c000000001fLL, 0x8000, Rd_I30, s3_do_sw48},
999
{"andri48", 0x040000000000LL, 0x1c0000000003LL, 0x8000, Rd_I32, s3_do_and48},
1000
{"andri48.c", 0x040000000001LL, 0x1c0000000003LL, 0x8000, Rd_I32, s3_do_and48},
1001
{"orri48", 0x040000000002LL, 0x1c0000000003LL, 0x8000, Rd_I32, s3_do_or48},
1002
{"orri48.c", 0x040000000003LL, 0x1c0000000003LL, 0x8000, Rd_I32, s3_do_or48},
1005
#define s3_SCORE3_PIPELINE 3
1007
static int s3_university_version = 0;
1008
static int s3_vector_size = s3_SCORE3_PIPELINE;
1009
static struct s3_score_it s3_dependency_vector[s3_SCORE3_PIPELINE];
1011
static int s3_score3d = 1;
1014
s3_end_of_line (char *str)
1016
int retval = s3_SUCCESS;
1018
s3_skip_whitespace (str);
1021
retval = (int) s3_FAIL;
1024
s3_inst.error = s3_BAD_GARBAGE;
1031
s3_score_reg_parse (char **ccp, struct hash_control *htab)
1036
struct s3_reg_entry *reg;
1039
if (!ISALPHA (*p) || !is_name_beginner (*p))
1040
return (int) s3_FAIL;
1044
while (ISALPHA (c) || ISDIGIT (c) || c == '_')
1048
reg = (struct s3_reg_entry *) hash_find (htab, start);
1056
return (int) s3_FAIL;
1059
/* If shift <= 0, only return reg. */
1062
s3_reg_required_here (char **str, int shift, enum s3_score_reg_type reg_type)
1064
static char buff[s3_MAX_LITERAL_POOL_SIZE];
1065
int reg = (int) s3_FAIL;
1068
if ((reg = s3_score_reg_parse (str, s3_all_reg_maps[reg_type].htab)) != (int) s3_FAIL)
1070
if (reg_type == s3_REG_TYPE_SCORE)
1072
if ((reg == 1) && (s3_nor1 == 1) && (s3_inst.bwarn == 0))
1074
as_warn (_("Using temp register(r1)"));
1080
if (reg_type == s3_REG_TYPE_SCORE_CR)
1081
strcpy (s3_inst.reg, s3_score_crn_table[reg].name);
1082
else if (reg_type == s3_REG_TYPE_SCORE_SR)
1083
strcpy (s3_inst.reg, s3_score_srn_table[reg].name);
1085
strcpy (s3_inst.reg, "");
1087
s3_inst.instruction |= (bfd_vma) reg << shift;
1093
sprintf (buff, _("register expected, not '%.100s'"), start);
1094
s3_inst.error = buff;
1101
s3_skip_past_comma (char **str)
1107
while ((c = *p) == ' ' || c == ',')
1110
if (c == ',' && comma++)
1112
s3_inst.error = s3_BAD_SKIP_COMMA;
1113
return (int) s3_FAIL;
1117
if ((c == '\0') || (comma == 0))
1119
s3_inst.error = s3_BAD_SKIP_COMMA;
1120
return (int) s3_FAIL;
1124
return comma ? s3_SUCCESS : (int) s3_FAIL;
1128
s3_do_rdrsrs (char *str)
1131
s3_skip_whitespace (str);
1133
if ((reg = s3_reg_required_here (&str, 20, s3_REG_TYPE_SCORE)) == (int) s3_FAIL
1134
|| s3_skip_past_comma (&str) == (int) s3_FAIL
1135
|| s3_reg_required_here (&str, 15, s3_REG_TYPE_SCORE) == (int) s3_FAIL
1136
|| s3_skip_past_comma (&str) == (int) s3_FAIL
1137
|| s3_reg_required_here (&str, 10, s3_REG_TYPE_SCORE) == (int) s3_FAIL
1138
|| s3_end_of_line (str) == (int) s3_FAIL)
1144
/* Check mulr, mulur rd is even number. */
1145
if (((s3_inst.instruction & 0x3e0003ff) == 0x00000340
1146
|| (s3_inst.instruction & 0x3e0003ff) == 0x00000342)
1149
s3_inst.error = _("rd must be even number.");
1153
if ((((s3_inst.instruction >> 15) & 0x10) == 0)
1154
&& (((s3_inst.instruction >> 10) & 0x10) == 0)
1155
&& (((s3_inst.instruction >> 20) & 0x10) == 0)
1156
&& (s3_inst.relax_inst != 0x8000)
1157
&& (((s3_inst.instruction >> 20) & 0xf) == ((s3_inst.instruction >> 15) & 0xf)))
1159
s3_inst.relax_inst |= (((s3_inst.instruction >> 10) & 0xf) )
1160
| (((s3_inst.instruction >> 15) & 0xf) << 4);
1161
s3_inst.relax_size = 2;
1165
s3_inst.relax_inst = 0x8000;
1171
s3_walk_no_bignums (symbolS * sp)
1173
if (symbol_get_value_expression (sp)->X_op == O_big)
1176
if (symbol_get_value_expression (sp)->X_add_symbol)
1177
return (s3_walk_no_bignums (symbol_get_value_expression (sp)->X_add_symbol)
1178
|| (symbol_get_value_expression (sp)->X_op_symbol
1179
&& s3_walk_no_bignums (symbol_get_value_expression (sp)->X_op_symbol)));
1185
s3_my_get_expression (expressionS * ep, char **str)
1189
save_in = input_line_pointer;
1190
input_line_pointer = *str;
1191
s3_in_my_get_expression = 1;
1192
(void) expression (ep);
1193
s3_in_my_get_expression = 0;
1195
if (ep->X_op == O_illegal)
1197
*str = input_line_pointer;
1198
input_line_pointer = save_in;
1199
s3_inst.error = _("illegal expression");
1200
return (int) s3_FAIL;
1202
/* Get rid of any bignums now, so that we don't generate an error for which
1203
we can't establish a line number later on. Big numbers are never valid
1204
in instructions, which is where this routine is always called. */
1205
if (ep->X_op == O_big
1206
|| (ep->X_add_symbol
1207
&& (s3_walk_no_bignums (ep->X_add_symbol)
1208
|| (ep->X_op_symbol && s3_walk_no_bignums (ep->X_op_symbol)))))
1210
s3_inst.error = _("invalid constant");
1211
*str = input_line_pointer;
1212
input_line_pointer = save_in;
1213
return (int) s3_FAIL;
1216
if ((ep->X_add_symbol != NULL)
1217
&& (s3_inst.type != PC_DISP19div2)
1218
&& (s3_inst.type != PC_DISP8div2)
1219
&& (s3_inst.type != PC_DISP24div2)
1220
&& (s3_inst.type != PC_DISP11div2)
1221
&& (s3_inst.type != Insn_Type_SYN)
1222
&& (s3_inst.type != Rd_rvalueRs_SI15)
1223
&& (s3_inst.type != Rd_lvalueRs_SI15)
1224
&& (s3_inst.type != Insn_internal)
1225
&& (s3_inst.type != Rd_I30)
1226
&& (s3_inst.type != Rd_I32)
1227
&& (s3_inst.type != Insn_BCMP))
1229
s3_inst.error = s3_BAD_ARGS;
1230
*str = input_line_pointer;
1231
input_line_pointer = save_in;
1232
return (int) s3_FAIL;
1235
*str = input_line_pointer;
1236
input_line_pointer = save_in;
1240
/* Check if an immediate is valid. If so, convert it to the right format. */
1241
static bfd_signed_vma
1242
s3_validate_immediate (bfd_signed_vma val, unsigned int data_type, int hex_p)
1248
bfd_signed_vma val_hi = ((val & 0xffff0000) >> 16);
1250
if (s3_score_df_range[data_type].range[0] <= val_hi
1251
&& val_hi <= s3_score_df_range[data_type].range[1])
1258
bfd_signed_vma val_lo = (val & 0xffff);
1260
if (s3_score_df_range[data_type].range[0] <= val_lo
1261
&& val_lo <= s3_score_df_range[data_type].range[1])
1269
if (!(val >= -0x2000 && val <= 0x3fff))
1271
return (int) s3_FAIL;
1276
if (!(val >= -8192 && val <= 8191))
1278
return (int) s3_FAIL;
1288
if (!(val >= -0x7fff && val <= 0xffff && val != 0x8000))
1290
return (int) s3_FAIL;
1295
if (!(val >= -32767 && val <= 32768))
1297
return (int) s3_FAIL;
1305
case _IMM5_MULTI_LOAD:
1306
if (val >= 2 && val <= 32)
1312
return (int) s3_FAIL;
1315
if (val >= 0 && val <= 0xffffffff)
1321
return (int) s3_FAIL;
1325
if (data_type == _SIMM14_NEG || data_type == _IMM16_NEG)
1328
if (s3_score_df_range[data_type].range[0] <= val
1329
&& val <= s3_score_df_range[data_type].range[1])
1335
return (int) s3_FAIL;
1339
s3_data_op2 (char **str, int shift, enum score_data_type data_type)
1341
bfd_signed_vma value;
1342
char data_exp[s3_MAX_LITERAL_POOL_SIZE];
1347
s3_skip_whitespace (*str);
1348
s3_inst.error = NULL;
1351
/* Set hex_p to zero. */
1354
while ((*dataptr != '\0') && (*dataptr != '|') && (cnt <= s3_MAX_LITERAL_POOL_SIZE)) /* 0x7c = ='|' */
1356
data_exp[cnt] = *dataptr;
1361
data_exp[cnt] = '\0';
1362
pp = (char *)&data_exp;
1364
if (*dataptr == '|') /* process PCE */
1366
if (s3_my_get_expression (&s3_inst.reloc.exp, &pp) == (int) s3_FAIL)
1367
return (int) s3_FAIL;
1368
s3_end_of_line (pp);
1369
if (s3_inst.error != 0)
1370
return (int) s3_FAIL; /* to ouptut_inst to printf out the error */
1373
else /* process 16 bit */
1375
if (s3_my_get_expression (&s3_inst.reloc.exp, str) == (int) s3_FAIL)
1377
return (int) s3_FAIL;
1380
dataptr = (char *)data_exp;
1381
for (; *dataptr != '\0'; dataptr++)
1383
*dataptr = TOLOWER (*dataptr);
1384
if (*dataptr == '!' || *dataptr == ' ')
1387
dataptr = (char *)data_exp;
1389
if ((dataptr != NULL)
1390
&& (((strstr (dataptr, "0x")) != NULL)
1391
|| ((strstr (dataptr, "0X")) != NULL)))
1394
if ((data_type != _SIMM16_LA)
1395
&& (data_type != _VALUE_HI16)
1396
&& (data_type != _VALUE_LO16)
1397
&& (data_type != _IMM16)
1398
&& (data_type != _IMM15)
1399
&& (data_type != _IMM14)
1400
&& (data_type != _IMM4)
1401
&& (data_type != _IMM5)
1402
&& (data_type != _IMM5_MULTI_LOAD)
1403
&& (data_type != _IMM11)
1404
&& (data_type != _IMM8)
1405
&& (data_type != _IMM5_RSHIFT_1)
1406
&& (data_type != _IMM5_RSHIFT_2)
1407
&& (data_type != _SIMM14)
1408
&& (data_type != _SIMM14_NEG)
1409
&& (data_type != _SIMM16_NEG)
1410
&& (data_type != _IMM10_RSHIFT_2)
1411
&& (data_type != _GP_IMM15)
1412
&& (data_type != _SIMM5)
1413
&& (data_type != _SIMM6)
1414
&& (data_type != _IMM32)
1415
&& (data_type != _SIMM32))
1421
if ((s3_inst.reloc.exp.X_add_number == 0)
1422
&& (s3_inst.type != Insn_Type_SYN)
1423
&& (s3_inst.type != Rd_rvalueRs_SI15)
1424
&& (s3_inst.type != Rd_lvalueRs_SI15)
1425
&& (s3_inst.type != Insn_internal)
1426
&& (((*dataptr >= 'a') && (*dataptr <= 'z'))
1427
|| ((*dataptr == '0') && (*(dataptr + 1) == 'x') && (*(dataptr + 2) != '0'))
1428
|| ((*dataptr == '+') && (*(dataptr + 1) != '0'))
1429
|| ((*dataptr == '-') && (*(dataptr + 1) != '0'))))
1431
s3_inst.error = s3_BAD_ARGS;
1432
return (int) s3_FAIL;
1436
if ((s3_inst.reloc.exp.X_add_symbol)
1437
&& ((data_type == _SIMM16)
1438
|| (data_type == _SIMM16_NEG)
1439
|| (data_type == _IMM16_NEG)
1440
|| (data_type == _SIMM14)
1441
|| (data_type == _SIMM14_NEG)
1442
|| (data_type == _IMM5)
1443
|| (data_type == _IMM5_MULTI_LOAD)
1444
|| (data_type == _IMM11)
1445
|| (data_type == _IMM14)
1446
|| (data_type == _IMM20)
1447
|| (data_type == _IMM16)
1448
|| (data_type == _IMM15)
1449
|| (data_type == _IMM4)))
1451
s3_inst.error = s3_BAD_ARGS;
1452
return (int) s3_FAIL;
1455
if (s3_inst.reloc.exp.X_add_symbol)
1460
return (int) s3_FAIL;
1462
s3_inst.reloc.type = BFD_RELOC_HI16_S;
1463
s3_inst.reloc.pc_rel = 0;
1466
s3_inst.reloc.type = BFD_RELOC_LO16;
1467
s3_inst.reloc.pc_rel = 0;
1470
s3_inst.reloc.type = BFD_RELOC_SCORE_GPREL15;
1471
s3_inst.reloc.pc_rel = 0;
1474
case _IMM16_LO16_pic:
1475
s3_inst.reloc.type = BFD_RELOC_SCORE_GOT_LO16;
1476
s3_inst.reloc.pc_rel = 0;
1479
s3_inst.reloc.type = BFD_RELOC_32;
1480
s3_inst.reloc.pc_rel = 0;
1486
if (data_type == _IMM16_pic)
1488
s3_inst.reloc.type = BFD_RELOC_SCORE_DUMMY_HI16;
1489
s3_inst.reloc.pc_rel = 0;
1492
if (data_type == _SIMM16_LA && s3_inst.reloc.exp.X_unsigned == 1)
1494
value = s3_validate_immediate (s3_inst.reloc.exp.X_add_number, _SIMM16_LA_POS, hex_p);
1495
if (value == (int) s3_FAIL) /* for advance to check if this is ldis */
1496
if ((s3_inst.reloc.exp.X_add_number & 0xffff) == 0)
1498
s3_inst.instruction |= 0x8000000;
1499
s3_inst.instruction |= ((s3_inst.reloc.exp.X_add_number >> 16) << 1) & 0x1fffe;
1505
value = s3_validate_immediate (s3_inst.reloc.exp.X_add_number, data_type, hex_p);
1508
if (value == (int) s3_FAIL)
1510
if (data_type == _IMM32)
1512
sprintf (s3_err_msg,
1513
_("invalid constant: %d bit expression not in range %u..%u"),
1514
s3_score_df_range[data_type].bits,
1515
0, (unsigned)0xffffffff);
1517
else if (data_type == _IMM5_MULTI_LOAD)
1519
sprintf (s3_err_msg,
1520
_("invalid constant: %d bit expression not in range %u..%u"),
1523
else if ((data_type != _SIMM14_NEG) && (data_type != _SIMM16_NEG) && (data_type != _IMM16_NEG))
1525
sprintf (s3_err_msg,
1526
_("invalid constant: %d bit expression not in range %d..%d"),
1527
s3_score_df_range[data_type].bits,
1528
s3_score_df_range[data_type].range[0], s3_score_df_range[data_type].range[1]);
1532
sprintf (s3_err_msg,
1533
_("invalid constant: %d bit expression not in range %d..%d"),
1534
s3_score_df_range[data_type].bits,
1535
-s3_score_df_range[data_type].range[1], -s3_score_df_range[data_type].range[0]);
1538
s3_inst.error = s3_err_msg;
1539
return (int) s3_FAIL;
1542
if (((s3_score_df_range[data_type].range[0] != 0) || (data_type == _IMM5_RANGE_8_31))
1543
&& data_type != _IMM5_MULTI_LOAD)
1545
value &= (1 << s3_score_df_range[data_type].bits) - 1;
1548
s3_inst.instruction |= value << shift;
1551
if ((s3_inst.instruction & 0x3e000000) == 0x30000000)
1553
if ((((s3_inst.instruction >> 20) & 0x1F) != 0)
1554
&& (((s3_inst.instruction >> 20) & 0x1F) != 1)
1555
&& (((s3_inst.instruction >> 20) & 0x1F) != 2)
1556
&& (((s3_inst.instruction >> 20) & 0x1F) != 0x10))
1558
s3_inst.error = _("invalid constant: bit expression not defined");
1559
return (int) s3_FAIL;
1566
/* Handle addi/addi.c/addis.c/cmpi.c/addis.c/ldi. */
1568
s3_do_rdsi16 (char *str)
1570
s3_skip_whitespace (str);
1572
if (s3_reg_required_here (&str, 20, s3_REG_TYPE_SCORE) == (int) s3_FAIL
1573
|| s3_skip_past_comma (&str) == (int) s3_FAIL
1574
|| s3_data_op2 (&str, 1, _SIMM16) == (int) s3_FAIL
1575
|| s3_end_of_line (str) == (int) s3_FAIL)
1578
/* ldi.->ldiu! only for imm5 */
1579
if ((s3_inst.instruction & 0x20c0000) == 0x20c0000)
1581
if ((s3_inst.instruction & 0x1ffc0) != 0)
1583
s3_inst.relax_inst = 0x8000;
1587
s3_inst.relax_inst |= (s3_inst.instruction >> 1) & 0x1f;
1588
s3_inst.relax_inst |= (((s3_inst.instruction >> 20)& 0x1f) <<5);
1589
s3_inst.relax_size = 2;
1593
else if ((s3_inst.instruction & 0x02040001) == 0x02040001)
1595
/* imm <=0x3f (5 bit<<1)*/
1596
if (((s3_inst.instruction & 0x1ffe0) == 0)
1597
|| (((s3_inst.instruction & 0x1ffe0) == 0x1ffe0)
1598
&& (s3_inst.instruction & 0x003e) != 0))
1600
s3_inst.relax_inst |= (s3_inst.instruction >> 1) & 0x1f;
1601
s3_inst.relax_inst |= (((s3_inst.instruction >> 20) & 0x1f) << 5);
1602
s3_inst.relax_size = 2;
1606
s3_inst.relax_inst =0x8000;
1611
else if (((s3_inst.instruction & 0x2000000) == 0x02000000) && (s3_inst.relax_inst!=0x8000))
1613
/* rd : 0-16 ; imm <=0x7f (6 bit<<1)*/
1614
if ((((s3_inst.instruction >> 20) & 0x10) != 0x10)
1615
&& (((s3_inst.instruction & 0x1ffc0) == 0)
1616
|| (((s3_inst.instruction & 0x1ffc0) == 0x1ffc0)
1617
&& (s3_inst.instruction & 0x007e) != 0)))
1619
s3_inst.relax_inst |= (s3_inst.instruction >> 1) & 0x3f;
1620
s3_inst.relax_inst |= (((s3_inst.instruction >> 20) & 0xf) << 6);
1621
s3_inst.relax_size = 2;
1625
s3_inst.relax_inst =0x8000;
1629
else if (((s3_inst.instruction >> 20) & 0x10) == 0x10)
1631
s3_inst.relax_inst = 0x8000;
1636
s3_do_ldis (char *str)
1638
s3_skip_whitespace (str);
1640
if (s3_reg_required_here (&str, 20, s3_REG_TYPE_SCORE) == (int) s3_FAIL
1641
|| s3_skip_past_comma (&str) == (int) s3_FAIL
1642
|| s3_data_op2 (&str, 1, _IMM16) == (int) s3_FAIL
1643
|| s3_end_of_line (str) == (int) s3_FAIL)
1647
/* Handle subi/subi.c. */
1649
s3_do_sub_rdsi16 (char *str)
1651
s3_skip_whitespace (str);
1653
if (s3_reg_required_here (&str, 20, s3_REG_TYPE_SCORE) != (int) s3_FAIL
1654
&& s3_skip_past_comma (&str) != (int) s3_FAIL
1655
&& s3_data_op2 (&str, 1, _SIMM16_NEG) != (int) s3_FAIL)
1656
s3_end_of_line (str);
1659
/* Handle subis/subis.c. */
1661
s3_do_sub_rdi16 (char *str)
1663
s3_skip_whitespace (str);
1665
if (s3_reg_required_here (&str, 20, s3_REG_TYPE_SCORE) != (int) s3_FAIL
1666
&& s3_skip_past_comma (&str) != (int) s3_FAIL
1667
&& s3_data_op2 (&str, 1, _IMM16_NEG) != (int) s3_FAIL)
1668
s3_end_of_line (str);
1671
/* Handle addri/addri.c. */
1673
s3_do_rdrssi14 (char *str) /* -(2^13)~((2^13)-1) */
1675
s3_skip_whitespace (str);
1677
if (s3_reg_required_here (&str, 20, s3_REG_TYPE_SCORE) != (int) s3_FAIL
1678
&& s3_skip_past_comma (&str) != (int) s3_FAIL
1679
&& s3_reg_required_here (&str, 15, s3_REG_TYPE_SCORE) != (int) s3_FAIL
1680
&& s3_skip_past_comma (&str) != (int) s3_FAIL)
1681
s3_data_op2 (&str, 1, _SIMM14);
1684
/* Handle subri.c/subri. */
1686
s3_do_sub_rdrssi14 (char *str) /* -(2^13)~((2^13)-1) */
1688
s3_skip_whitespace (str);
1690
if (s3_reg_required_here (&str, 20, s3_REG_TYPE_SCORE) != (int) s3_FAIL
1691
&& s3_skip_past_comma (&str) != (int) s3_FAIL
1692
&& s3_reg_required_here (&str, 15, s3_REG_TYPE_SCORE) != (int) s3_FAIL
1693
&& s3_skip_past_comma (&str) != (int) s3_FAIL
1694
&& s3_data_op2 (&str, 1, _SIMM14_NEG) != (int) s3_FAIL)
1695
s3_end_of_line (str);
1698
/* Handle bitclr.c/bitset.c/bittgl.c/slli.c/srai.c/srli.c/roli.c/rori.c/rolic.c.
1701
s3_do_rdrsi5 (char *str)
1703
s3_skip_whitespace (str);
1705
if (s3_reg_required_here (&str, 20, s3_REG_TYPE_SCORE) == (int) s3_FAIL
1706
|| s3_skip_past_comma (&str) == (int) s3_FAIL
1707
|| s3_reg_required_here (&str, 15, s3_REG_TYPE_SCORE) == (int) s3_FAIL
1708
|| s3_skip_past_comma (&str) == (int) s3_FAIL
1709
|| s3_data_op2 (&str, 10, _IMM5) == (int) s3_FAIL
1710
|| s3_end_of_line (str) == (int) s3_FAIL)
1713
if ((((s3_inst.instruction >> 20) & 0x1f) == ((s3_inst.instruction >> 15) & 0x1f))
1714
&& (s3_inst.relax_inst != 0x8000) && (((s3_inst.instruction >> 15) & 0x10) == 0))
1716
s3_inst.relax_inst |= (((s3_inst.instruction >> 10) & 0x1f) ) | (((s3_inst.instruction >> 15) & 0xf) << 5);
1717
s3_inst.relax_size = 2;
1720
s3_inst.relax_inst = 0x8000;
1723
/* Handle andri/orri/andri.c/orri.c.
1726
s3_do_rdrsi14 (char *str)
1728
s3_skip_whitespace (str);
1730
if (s3_reg_required_here (&str, 20, s3_REG_TYPE_SCORE) != (int) s3_FAIL
1731
&& s3_skip_past_comma (&str) != (int) s3_FAIL
1732
&& s3_reg_required_here (&str, 15, s3_REG_TYPE_SCORE) != (int) s3_FAIL
1733
&& s3_skip_past_comma (&str) != (int) s3_FAIL
1734
&& s3_data_op2 (&str, 1, _IMM14) != (int) s3_FAIL)
1735
s3_end_of_line (str);
1738
/* Handle bittst.c. */
1740
s3_do_xrsi5 (char *str)
1742
s3_skip_whitespace (str);
1744
if (s3_reg_required_here (&str, 15, s3_REG_TYPE_SCORE) == (int) s3_FAIL
1745
|| s3_skip_past_comma (&str) == (int) s3_FAIL
1746
|| s3_data_op2 (&str, 10, _IMM5) == (int) s3_FAIL
1747
|| s3_end_of_line (str) == (int) s3_FAIL)
1750
if ((s3_inst.relax_inst != 0x8000) && (((s3_inst.instruction >> 15) & 0x10) == 0))
1752
s3_inst.relax_inst |= ((s3_inst.instruction >> 10) & 0x1f) | (((s3_inst.instruction >> 15) & 0xf) << 5);
1753
s3_inst.relax_size = 2;
1756
s3_inst.relax_inst = 0x8000;
1759
/* Handle addis/andi/ori/andis/oris/ldis. */
1761
s3_do_rdi16 (char *str)
1763
s3_skip_whitespace (str);
1765
if (s3_reg_required_here (&str, 20, s3_REG_TYPE_SCORE) == (int) s3_FAIL
1766
|| s3_skip_past_comma (&str) == (int) s3_FAIL
1767
|| s3_data_op2 (&str, 1, _IMM16) == (int) s3_FAIL
1768
|| s3_end_of_line (str) == (int) s3_FAIL)
1772
if ((s3_inst.instruction & 0x3e0e0000) == 0x0a0c0000)
1774
/* rd : 0-16 ;imm =0 -> can transform to addi!*/
1775
if ((((s3_inst.instruction >> 20) & 0x10) != 0x10) && ((s3_inst.instruction & 0x1ffff)==0))
1777
s3_inst.relax_inst =0x5400; /* ldiu! */
1778
s3_inst.relax_inst |= (s3_inst.instruction >> 1) & 0x1f;
1779
s3_inst.relax_inst |= (((s3_inst.instruction >> 20) & 0xf) << 5);
1780
s3_inst.relax_size = 2;
1784
s3_inst.relax_inst =0x8000;
1790
else if ((s3_inst.instruction & 0x3e0e0001) == 0x0a000000)
1792
/* rd : 0-16 ;imm =0 -> can transform to addi!*/
1793
if ((((s3_inst.instruction >> 20) & 0x10) != 0x10) && ((s3_inst.instruction & 0x1ffff)==0))
1795
s3_inst.relax_inst =0x5c00; /* addi! */
1796
s3_inst.relax_inst |= (s3_inst.instruction >> 1) & 0x3f;
1797
s3_inst.relax_inst |= (((s3_inst.instruction >> 20) & 0xf) << 6);
1798
s3_inst.relax_size = 2;
1802
s3_inst.relax_inst =0x8000;
1809
s3_do_macro_rdi32hi (char *str)
1811
s3_skip_whitespace (str);
1813
/* Do not handle s3_end_of_line(). */
1814
if (s3_reg_required_here (&str, 20, s3_REG_TYPE_SCORE) != (int) s3_FAIL
1815
&& s3_skip_past_comma (&str) != (int) s3_FAIL)
1816
s3_data_op2 (&str, 1, _VALUE_HI16);
1820
s3_do_macro_rdi32lo (char *str)
1822
s3_skip_whitespace (str);
1824
/* Do not handle s3_end_of_line(). */
1825
if (s3_reg_required_here (&str, 20, s3_REG_TYPE_SCORE) != (int) s3_FAIL
1826
&& s3_skip_past_comma (&str) != (int) s3_FAIL)
1827
s3_data_op2 (&str, 1, _VALUE_LO16);
1830
/* Handle ldis_pic. */
1832
s3_do_rdi16_pic (char *str)
1834
s3_skip_whitespace (str);
1836
if (s3_reg_required_here (&str, 20, s3_REG_TYPE_SCORE) != (int) s3_FAIL
1837
&& s3_skip_past_comma (&str) != (int) s3_FAIL
1838
&& s3_data_op2 (&str, 1, _IMM16_pic) != (int) s3_FAIL)
1839
s3_end_of_line (str);
1842
/* Handle addi_s_pic to generate R_SCORE_GOT_LO16 . */
1844
s3_do_addi_s_pic (char *str)
1846
s3_skip_whitespace (str);
1848
if (s3_reg_required_here (&str, 20, s3_REG_TYPE_SCORE) != (int) s3_FAIL
1849
&& s3_skip_past_comma (&str) != (int) s3_FAIL
1850
&& s3_data_op2 (&str, 1, _SIMM16_pic) != (int) s3_FAIL)
1851
s3_end_of_line (str);
1854
/* Handle addi_u_pic to generate R_SCORE_GOT_LO16 . */
1856
s3_do_addi_u_pic (char *str)
1858
s3_skip_whitespace (str);
1860
if (s3_reg_required_here (&str, 20, s3_REG_TYPE_SCORE) != (int) s3_FAIL
1861
&& s3_skip_past_comma (&str) != (int) s3_FAIL
1862
&& s3_data_op2 (&str, 1, _IMM16_LO16_pic) != (int) s3_FAIL)
1863
s3_end_of_line (str);
1866
/* Handle mfceh/mfcel/mtceh/mtchl. */
1868
s3_do_rd (char *str)
1870
s3_skip_whitespace (str);
1872
if (s3_reg_required_here (&str, 20, s3_REG_TYPE_SCORE) != (int) s3_FAIL)
1873
s3_end_of_line (str);
1876
/* Handle br{cond},cmpzteq.c ,cmpztmi.c ,cmpz.c */
1878
s3_do_rs (char *str)
1880
s3_skip_whitespace (str);
1882
if (s3_reg_required_here (&str, 15, s3_REG_TYPE_SCORE) == (int) s3_FAIL
1883
|| s3_end_of_line (str) == (int) s3_FAIL)
1886
if ((s3_inst.relax_inst != 0x8000) )
1888
s3_inst.relax_inst |= ((s3_inst.instruction >> 15) &0x1f);
1889
s3_inst.relax_size = 2;
1892
s3_inst.relax_inst = 0x8000;
1896
s3_do_i15 (char *str)
1898
s3_skip_whitespace (str);
1900
if (s3_data_op2 (&str, 10, _IMM15) != (int) s3_FAIL)
1901
s3_end_of_line (str);
1905
s3_do_xi5x (char *str)
1907
s3_skip_whitespace (str);
1909
if (s3_data_op2 (&str, 15, _IMM5) == (int) s3_FAIL || s3_end_of_line (str) == (int) s3_FAIL)
1912
if (s3_inst.relax_inst != 0x8000)
1914
s3_inst.relax_inst |= ((s3_inst.instruction >> 15) & 0x1f);
1915
s3_inst.relax_size = 2;
1920
s3_do_rdrs (char *str)
1922
s3_skip_whitespace (str);
1924
if (s3_reg_required_here (&str, 20, s3_REG_TYPE_SCORE) == (int) s3_FAIL
1925
|| s3_skip_past_comma (&str) == (int) s3_FAIL
1926
|| s3_reg_required_here (&str, 15, s3_REG_TYPE_SCORE) == (int) s3_FAIL
1927
|| s3_end_of_line (str) == (int) s3_FAIL)
1930
if (s3_inst.relax_inst != 0x8000)
1932
if (((s3_inst.instruction & 0x7f) == 0x56)) /* adjust mv -> mv!*/
1934
/* mv! rd : 5bit , ra : 5bit */
1935
s3_inst.relax_inst |= ((s3_inst.instruction >> 15) & 0x1f) | (((s3_inst.instruction >> 20) & 0x1f) << 5);
1936
s3_inst.relax_size = 2;
1938
else if ((((s3_inst.instruction >> 15) & 0x10) == 0x0) && (((s3_inst.instruction >> 20) & 0x10) == 0))
1940
s3_inst.relax_inst |= (((s3_inst.instruction >> 15) & 0xf) << 4)
1941
| (((s3_inst.instruction >> 20) & 0xf) << 8);
1942
s3_inst.relax_size = 2;
1946
s3_inst.relax_inst = 0x8000;
1951
/* Handle mfcr/mtcr. */
1953
s3_do_rdcrs (char *str)
1955
s3_skip_whitespace (str);
1957
if (s3_reg_required_here (&str, 20, s3_REG_TYPE_SCORE) != (int) s3_FAIL
1958
&& s3_skip_past_comma (&str) != (int) s3_FAIL
1959
&& s3_reg_required_here (&str, 15, s3_REG_TYPE_SCORE_CR) != (int) s3_FAIL)
1960
s3_end_of_line (str);
1963
/* Handle mfsr/mtsr. */
1965
s3_do_rdsrs (char *str)
1967
s3_skip_whitespace (str);
1970
if ((s3_inst.instruction & 0xff) == 0x50)
1972
if (s3_reg_required_here (&str, 20, s3_REG_TYPE_SCORE) != (int) s3_FAIL
1973
&& s3_skip_past_comma (&str) != (int) s3_FAIL
1974
&& s3_reg_required_here (&str, 10, s3_REG_TYPE_SCORE_SR) != (int) s3_FAIL)
1975
s3_end_of_line (str);
1979
if (s3_reg_required_here (&str, 15, s3_REG_TYPE_SCORE) != (int) s3_FAIL
1980
&& s3_skip_past_comma (&str) != (int) s3_FAIL)
1981
s3_reg_required_here (&str, 10, s3_REG_TYPE_SCORE_SR);
1987
s3_do_rdxrs (char *str)
1989
s3_skip_whitespace (str);
1991
if (s3_reg_required_here (&str, 20, s3_REG_TYPE_SCORE) == (int) s3_FAIL
1992
|| s3_skip_past_comma (&str) == (int) s3_FAIL
1993
|| s3_reg_required_here (&str, 10, s3_REG_TYPE_SCORE) == (int) s3_FAIL
1994
|| s3_end_of_line (str) == (int) s3_FAIL)
1997
if ((s3_inst.relax_inst != 0x8000) && (((s3_inst.instruction >> 10) & 0x10) == 0)
1998
&& (((s3_inst.instruction >> 20) & 0x10) == 0))
2000
s3_inst.relax_inst |= (((s3_inst.instruction >> 10) & 0xf) << 4) | (((s3_inst.instruction >> 20) & 0xf) << 8);
2001
s3_inst.relax_size = 2;
2004
s3_inst.relax_inst = 0x8000;
2007
/* Handle cmp.c/cmp<cond>. */
2009
s3_do_rsrs (char *str)
2011
s3_skip_whitespace (str);
2013
if (s3_reg_required_here (&str, 15, s3_REG_TYPE_SCORE) == (int) s3_FAIL
2014
|| s3_skip_past_comma (&str) == (int) s3_FAIL
2015
|| s3_reg_required_here (&str, 10, s3_REG_TYPE_SCORE) == (int) s3_FAIL
2016
|| s3_end_of_line (str) == (int) s3_FAIL)
2019
if ((s3_inst.relax_inst != 0x8000) && (((s3_inst.instruction >> 20) & 0x1f) == 3) )
2021
s3_inst.relax_inst |= (((s3_inst.instruction >> 10) & 0x1f)) | (((s3_inst.instruction >> 15) & 0x1f) << 5);
2022
s3_inst.relax_size = 2;
2025
s3_inst.relax_inst = 0x8000;
2029
s3_do_ceinst (char *str)
2034
s3_skip_whitespace (str);
2036
if (s3_data_op2 (&str, 20, _IMM5) == (int) s3_FAIL
2037
|| s3_skip_past_comma (&str) == (int) s3_FAIL
2038
|| s3_reg_required_here (&str, 15, s3_REG_TYPE_SCORE) == (int) s3_FAIL
2039
|| s3_skip_past_comma (&str) == (int) s3_FAIL
2040
|| s3_reg_required_here (&str, 10, s3_REG_TYPE_SCORE) == (int) s3_FAIL
2041
|| s3_skip_past_comma (&str) == (int) s3_FAIL
2042
|| s3_data_op2 (&str, 5, _IMM5) == (int) s3_FAIL
2043
|| s3_skip_past_comma (&str) == (int) s3_FAIL
2044
|| s3_data_op2 (&str, 0, _IMM5) == (int) s3_FAIL
2045
|| s3_end_of_line (str) == (int) s3_FAIL)
2052
if (s3_data_op2 (&str, 0, _IMM25) == (int) s3_FAIL)
2058
s3_reglow_required_here (char **str, int shift)
2060
static char buff[s3_MAX_LITERAL_POOL_SIZE];
2064
if ((reg = s3_score_reg_parse (str, s3_all_reg_maps[s3_REG_TYPE_SCORE].htab)) != (int) s3_FAIL)
2066
if ((reg == 1) && (s3_nor1 == 1) && (s3_inst.bwarn == 0))
2068
as_warn (_("Using temp register(r1)"));
2074
s3_inst.instruction |= (bfd_vma) reg << shift;
2080
/* Restore the start point, we may have got a reg of the wrong class. */
2082
sprintf (buff, _("low register(r0-r15)expected, not '%.100s'"), start);
2083
s3_inst.error = buff;
2084
return (int) s3_FAIL;
2087
/* Handle add!/and!/or!/sub!. */
2089
s3_do16_rdrs2 (char *str)
2091
s3_skip_whitespace (str);
2093
if (s3_reglow_required_here (&str, 4) == (int) s3_FAIL
2094
|| s3_skip_past_comma (&str) == (int) s3_FAIL
2095
|| s3_reglow_required_here (&str, 0) == (int) s3_FAIL
2096
|| s3_end_of_line (str) == (int) s3_FAIL)
2102
/* Handle br!/brl!. */
2104
s3_do16_br (char *str)
2106
s3_skip_whitespace (str);
2108
if (s3_reg_required_here (&str, 0, s3_REG_TYPE_SCORE) == (int) s3_FAIL
2109
|| s3_end_of_line (str) == (int) s3_FAIL)
2117
s3_do16_brr (char *str)
2121
s3_skip_whitespace (str);
2123
if ((rd = s3_reg_required_here (&str, 0,s3_REG_TYPE_SCORE)) == (int) s3_FAIL
2124
|| s3_end_of_line (str) == (int) s3_FAIL)
2130
/*Handle ltbw / ltbh / ltbb */
2132
s3_do_ltb (char *str)
2134
s3_skip_whitespace (str);
2135
if (s3_reg_required_here (&str, 20, s3_REG_TYPE_SCORE) == (int) s3_FAIL
2136
|| s3_skip_past_comma (&str) == (int) s3_FAIL)
2141
s3_skip_whitespace (str);
2144
s3_inst.error = _("missing [");
2148
if (s3_reg_required_here (&str, 15, s3_REG_TYPE_SCORE) == (int) s3_FAIL
2149
|| s3_skip_past_comma (&str) == (int) s3_FAIL
2150
|| s3_reg_required_here (&str, 10, s3_REG_TYPE_SCORE) == (int) s3_FAIL)
2155
s3_skip_whitespace (str);
2158
s3_inst.error = _("missing ]");
2163
/* We need to be able to fix up arbitrary expressions in some statements.
2164
This is so that we can handle symbols that are an arbitrary distance from
2165
the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
2166
which returns part of an address in a form which will be valid for
2167
a data instruction. We do this by pushing the expression into a symbol
2168
in the expr_section, and creating a fix for that. */
2170
s3_fix_new_score (fragS * frag, int where, short int size, expressionS * exp, int pc_rel, int reloc)
2180
new_fix = fix_new_exp (frag, where, size, exp, pc_rel, reloc);
2183
new_fix = fix_new (frag, where, size, make_expr_symbol (exp), 0, pc_rel, reloc);
2190
s3_init_dependency_vector (void)
2194
for (i = 0; i < s3_vector_size; i++)
2195
memset (&s3_dependency_vector[i], '\0', sizeof (s3_dependency_vector[i]));
2200
static enum s3_insn_type_for_dependency
2201
s3_dependency_type_from_insn (char *insn_name)
2203
char name[s3_INSN_NAME_LEN];
2204
const struct s3_insn_to_dependency *tmp;
2206
strcpy (name, insn_name);
2207
tmp = (const struct s3_insn_to_dependency *) hash_find (s3_dependency_insn_hsh, name);
2212
return s3_D_all_insn;
2216
s3_check_dependency (char *pre_insn, char *pre_reg,
2217
char *cur_insn, char *cur_reg, int *warn_or_error)
2221
enum s3_insn_type_for_dependency pre_insn_type;
2222
enum s3_insn_type_for_dependency cur_insn_type;
2224
pre_insn_type = s3_dependency_type_from_insn (pre_insn);
2225
cur_insn_type = s3_dependency_type_from_insn (cur_insn);
2227
for (i = 0; i < sizeof (s3_data_dependency_table) / sizeof (s3_data_dependency_table[0]); i++)
2229
if ((pre_insn_type == s3_data_dependency_table[i].pre_insn_type)
2230
&& (s3_D_all_insn == s3_data_dependency_table[i].cur_insn_type
2231
|| cur_insn_type == s3_data_dependency_table[i].cur_insn_type)
2232
&& (strcmp (s3_data_dependency_table[i].pre_reg, "") == 0
2233
|| strcmp (s3_data_dependency_table[i].pre_reg, pre_reg) == 0)
2234
&& (strcmp (s3_data_dependency_table[i].cur_reg, "") == 0
2235
|| strcmp (s3_data_dependency_table[i].cur_reg, cur_reg) == 0))
2237
bubbles = s3_data_dependency_table[i].bubblenum_3;
2238
*warn_or_error = s3_data_dependency_table[i].warn_or_error;
2247
s3_build_one_frag (struct s3_score_it one_inst)
2250
int relaxable_p = s3_g_opt;
2253
/* Start a new frag if frag_now is not empty. */
2254
if (frag_now_fix () != 0)
2256
if (!frag_now->tc_frag_data.is_insn)
2257
frag_wane (frag_now);
2263
p = frag_more (one_inst.size);
2264
s3_md_number_to_chars (p, one_inst.instruction, one_inst.size);
2267
dwarf2_emit_insn (one_inst.size);
2270
relaxable_p &= (one_inst.relax_size != 0);
2271
relax_size = relaxable_p ? one_inst.relax_size : 0;
2273
p = frag_var (rs_machine_dependent, relax_size + s3_RELAX_PAD_BYTE, 0,
2274
s3_RELAX_ENCODE (one_inst.size, one_inst.relax_size,
2275
one_inst.type, 0, 0, relaxable_p),
2279
s3_md_number_to_chars (p, one_inst.relax_inst, relax_size);
2283
s3_handle_dependency (struct s3_score_it *theinst)
2286
int warn_or_error = 0; /* warn - 0; error - 1 */
2288
int remainder_bubbles = 0;
2289
char cur_insn[s3_INSN_NAME_LEN];
2290
char pre_insn[s3_INSN_NAME_LEN];
2291
struct s3_score_it nop_inst;
2292
struct s3_score_it pflush_inst;
2294
nop_inst.instruction = 0x0000;
2296
nop_inst.relax_inst = 0x80008000;
2297
nop_inst.relax_size = 4;
2298
nop_inst.type = NO16_OPD;
2300
pflush_inst.instruction = 0x8000800a;
2301
pflush_inst.size = 4;
2302
pflush_inst.relax_inst = 0x8000;
2303
pflush_inst.relax_size = 0;
2304
pflush_inst.type = NO_OPD;
2306
/* pflush will clear all data dependency. */
2307
if (strcmp (theinst->name, "pflush") == 0)
2309
s3_init_dependency_vector ();
2313
/* Push current instruction to s3_dependency_vector[0]. */
2314
for (i = s3_vector_size - 1; i > 0; i--)
2315
memcpy (&s3_dependency_vector[i], &s3_dependency_vector[i - 1], sizeof (s3_dependency_vector[i]));
2317
memcpy (&s3_dependency_vector[0], theinst, sizeof (s3_dependency_vector[i]));
2319
/* There is no dependency between nop and any instruction. */
2320
if (strcmp (s3_dependency_vector[0].name, "nop") == 0
2321
|| strcmp (s3_dependency_vector[0].name, "nop!") == 0)
2324
strcpy (cur_insn, s3_dependency_vector[0].name);
2326
for (i = 1; i < s3_vector_size; i++)
2328
/* The element of s3_dependency_vector is NULL. */
2329
if (s3_dependency_vector[i].name[0] == '\0')
2332
strcpy (pre_insn, s3_dependency_vector[i].name);
2334
bubbles = s3_check_dependency (pre_insn, s3_dependency_vector[i].reg,
2335
cur_insn, s3_dependency_vector[0].reg, &warn_or_error);
2336
remainder_bubbles = bubbles - i + 1;
2338
if (remainder_bubbles > 0)
2342
if (s3_fix_data_dependency == 1)
2344
if (remainder_bubbles <= 2)
2346
if (s3_warn_fix_data_dependency)
2347
as_warn (_("Fix data dependency: %s %s -- %s %s (insert %d nop!/%d)"),
2348
s3_dependency_vector[i].name, s3_dependency_vector[i].reg,
2349
s3_dependency_vector[0].name, s3_dependency_vector[0].reg,
2350
remainder_bubbles, bubbles);
2352
for (j = (s3_vector_size - 1); (j - remainder_bubbles) > 0; j--)
2353
memcpy (&s3_dependency_vector[j], &s3_dependency_vector[j - remainder_bubbles],
2354
sizeof (s3_dependency_vector[j]));
2356
for (j = 1; j <= remainder_bubbles; j++)
2358
memset (&s3_dependency_vector[j], '\0', sizeof (s3_dependency_vector[j]));
2360
s3_build_one_frag (nop_inst);
2365
if (s3_warn_fix_data_dependency)
2366
as_warn (_("Fix data dependency: %s %s -- %s %s (insert 1 pflush/%d)"),
2367
s3_dependency_vector[i].name, s3_dependency_vector[i].reg,
2368
s3_dependency_vector[0].name, s3_dependency_vector[0].reg,
2371
for (j = 1; j < s3_vector_size; j++)
2372
memset (&s3_dependency_vector[j], '\0', sizeof (s3_dependency_vector[j]));
2374
/* Insert pflush. */
2375
s3_build_one_frag (pflush_inst);
2382
as_bad (_("data dependency: %s %s -- %s %s (%d/%d bubble)"),
2383
s3_dependency_vector[i].name, s3_dependency_vector[i].reg,
2384
s3_dependency_vector[0].name, s3_dependency_vector[0].reg,
2385
remainder_bubbles, bubbles);
2389
as_warn (_("data dependency: %s %s -- %s %s (%d/%d bubble)"),
2390
s3_dependency_vector[i].name, s3_dependency_vector[i].reg,
2391
s3_dependency_vector[0].name, s3_dependency_vector[0].reg,
2392
remainder_bubbles, bubbles);
2399
static enum insn_class
2400
s3_get_insn_class_from_type (enum score_insn_type type)
2402
enum insn_class retval = (int) s3_FAIL;
2408
case Rd_rvalueBP_I5:
2409
case Rd_lvalueBP_I5:
2422
retval = INSN_CLASS_16;
2431
case Rd_rvalueRs_SI10:
2432
case Rd_lvalueRs_SI10:
2433
case Rd_rvalueRs_preSI12:
2434
case Rd_rvalueRs_postSI12:
2435
case Rd_lvalueRs_preSI12:
2436
case Rd_lvalueRs_postSI12:
2438
case Rd_rvalueRs_SI15:
2439
case Rd_lvalueRs_SI15:
2448
case OP5_rvalueRs_SI15:
2449
case I5_Rs_Rs_I5_OP5:
2450
case x_rvalueRs_post4:
2451
case Rd_rvalueRs_post4:
2453
case Rd_lvalueRs_post4:
2454
case x_lvalueRs_post4:
2464
retval = INSN_CLASS_32;
2467
retval = INSN_CLASS_PCE;
2470
retval = INSN_CLASS_SYN;
2474
retval = INSN_CLASS_48;
2484
48-bit instruction: 1, 1, 0.
2485
32-bit instruction: 1, 0.
2486
16-bit instruction: 0. */
2488
s3_adjust_paritybit (bfd_vma m_code, enum insn_class i_class)
2491
bfd_vma m_code_high = 0;
2492
unsigned long m_code_middle = 0;
2493
unsigned long m_code_low = 0;
2494
bfd_vma pb_high = 0;
2495
unsigned long pb_middle = 0;
2496
unsigned long pb_low = 0;
2498
if (i_class == INSN_CLASS_48)
2500
pb_high = 0x800000000000LL;
2501
pb_middle = 0x80000000;
2502
pb_low = 0x00000000;
2503
m_code_high = m_code & 0x1fffc0000000LL;
2504
m_code_middle = m_code & 0x3fff8000;
2505
m_code_low = m_code & 0x00007fff;
2506
result = pb_high | (m_code_high << 2) |
2507
pb_middle | (m_code_middle << 1) |
2508
pb_low | m_code_low;
2510
else if (i_class == INSN_CLASS_32 || i_class == INSN_CLASS_SYN)
2512
pb_high = 0x80000000;
2513
pb_low = 0x00000000;
2514
m_code_high = m_code & 0x3fff8000;
2515
m_code_low = m_code & 0x00007fff;
2516
result = pb_high | (m_code_high << 1) | pb_low | m_code_low;
2518
else if (i_class == INSN_CLASS_16)
2522
m_code_high = m_code & 0x3fff8000;
2523
m_code_low = m_code & 0x00007fff;
2524
result = pb_high | (m_code_high << 1) | pb_low | m_code_low;
2526
else if (i_class == INSN_CLASS_PCE)
2528
/* Keep original. */
2530
pb_low = 0x00008000;
2531
m_code_high = m_code & 0x3fff8000;
2532
m_code_low = m_code & 0x00007fff;
2533
result = pb_high | (m_code_high << 1) | pb_low | m_code_low;
2544
s3_gen_insn_frag (struct s3_score_it *part_1, struct s3_score_it *part_2)
2547
bfd_boolean pce_p = FALSE;
2548
int relaxable_p = s3_g_opt;
2550
struct s3_score_it *inst1 = part_1;
2551
struct s3_score_it *inst2 = part_2;
2552
struct s3_score_it backup_inst1;
2554
pce_p = (inst2) ? TRUE : FALSE;
2555
memcpy (&backup_inst1, inst1, sizeof (struct s3_score_it));
2557
/* Adjust instruction opcode and to be relaxed instruction opcode. */
2560
backup_inst1.instruction = ((backup_inst1.instruction & 0x7FFF) << 15)
2561
| (inst2->instruction & 0x7FFF);
2562
backup_inst1.instruction = s3_adjust_paritybit (backup_inst1.instruction, INSN_CLASS_PCE);
2563
backup_inst1.relax_inst = 0x8000;
2564
backup_inst1.size = s3_INSN_SIZE;
2565
backup_inst1.relax_size = 0;
2566
backup_inst1.type = Insn_Type_PCE;
2570
backup_inst1.instruction = s3_adjust_paritybit (backup_inst1.instruction,
2571
s3_GET_INSN_CLASS (backup_inst1.type));
2574
if (backup_inst1.relax_size != 0)
2576
enum insn_class tmp;
2578
tmp = (backup_inst1.size == s3_INSN_SIZE) ? INSN_CLASS_16 : INSN_CLASS_32;
2579
backup_inst1.relax_inst = s3_adjust_paritybit (backup_inst1.relax_inst, tmp);
2582
/* Check data dependency. */
2583
s3_handle_dependency (&backup_inst1);
2585
/* Start a new frag if frag_now is not empty and is not instruction frag, maybe it contains
2586
data produced by .ascii etc. Doing this is to make one instruction per frag. */
2587
if (frag_now_fix () != 0)
2589
if (!frag_now->tc_frag_data.is_insn)
2590
frag_wane (frag_now);
2595
/* Here, we must call frag_grow in order to keep the instruction frag type is
2596
rs_machine_dependent.
2597
For, frag_var may change frag_now->fr_type to rs_fill by calling frag_grow which
2598
acturally will call frag_wane.
2599
Calling frag_grow first will create a new frag_now which free size is 20 that is enough
2603
p = frag_more (backup_inst1.size);
2604
s3_md_number_to_chars (p, backup_inst1.instruction, backup_inst1.size);
2607
dwarf2_emit_insn (backup_inst1.size);
2610
/* Generate fixup structure. */
2613
if (inst1->reloc.type != BFD_RELOC_NONE)
2614
s3_fix_new_score (frag_now, p - frag_now->fr_literal,
2615
inst1->size, &inst1->reloc.exp,
2616
inst1->reloc.pc_rel, inst1->reloc.type);
2618
if (inst2->reloc.type != BFD_RELOC_NONE)
2619
s3_fix_new_score (frag_now, p - frag_now->fr_literal + 2,
2620
inst2->size, &inst2->reloc.exp, inst2->reloc.pc_rel, inst2->reloc.type);
2624
if (backup_inst1.reloc.type != BFD_RELOC_NONE)
2625
s3_fix_new_score (frag_now, p - frag_now->fr_literal,
2626
backup_inst1.size, &backup_inst1.reloc.exp,
2627
backup_inst1.reloc.pc_rel, backup_inst1.reloc.type);
2630
/* relax_size may be 2, 4, 12 or 0, 0 indicates no relaxation. */
2631
relaxable_p &= (backup_inst1.relax_size != 0);
2632
relax_size = relaxable_p ? backup_inst1.relax_size : 0;
2634
p = frag_var (rs_machine_dependent, relax_size + s3_RELAX_PAD_BYTE, 0,
2635
s3_RELAX_ENCODE (backup_inst1.size, backup_inst1.relax_size,
2636
backup_inst1.type, 0, 0, relaxable_p),
2637
backup_inst1.reloc.exp.X_add_symbol, 0, NULL);
2640
s3_md_number_to_chars (p, backup_inst1.relax_inst, relax_size);
2642
memcpy (inst1, &backup_inst1, sizeof (struct s3_score_it));
2646
s3_parse_16_32_inst (char *insnstr, bfd_boolean gen_frag_p)
2650
char *operator = insnstr;
2651
const struct s3_asm_opcode *opcode;
2653
/* Parse operator and operands. */
2654
s3_skip_whitespace (operator);
2656
for (p = operator; *p != '\0'; p++)
2657
if ((*p == ' ') || (*p == '!'))
2666
opcode = (const struct s3_asm_opcode *) hash_find (s3_score_ops_hsh, operator);
2669
memset (&s3_inst, '\0', sizeof (s3_inst));
2670
sprintf (s3_inst.str, "%s", insnstr);
2673
s3_inst.instruction = opcode->value;
2674
s3_inst.relax_inst = opcode->relax_value;
2675
s3_inst.type = opcode->type;
2676
s3_inst.size = s3_GET_INSN_SIZE (s3_inst.type);
2677
s3_inst.relax_size = 0;
2679
sprintf (s3_inst.name, "%s", opcode->template_name);
2680
strcpy (s3_inst.reg, "");
2681
s3_inst.error = NULL;
2682
s3_inst.reloc.type = BFD_RELOC_NONE;
2684
(*opcode->parms) (p);
2686
/* It indicates current instruction is a macro instruction if s3_inst.bwarn equals -1. */
2687
if ((s3_inst.bwarn != -1) && (!s3_inst.error) && (gen_frag_p))
2688
s3_gen_insn_frag (&s3_inst, NULL);
2691
s3_inst.error = _("unrecognized opcode");
2695
s3_parse_48_inst (char *insnstr, bfd_boolean gen_frag_p)
2699
char *operator = insnstr;
2700
const struct s3_asm_opcode *opcode;
2702
/* Parse operator and operands. */
2703
s3_skip_whitespace (operator);
2705
for (p = operator; *p != '\0'; p++)
2712
opcode = (const struct s3_asm_opcode *) hash_find (s3_score_ops_hsh, operator);
2715
memset (&s3_inst, '\0', sizeof (s3_inst));
2716
sprintf (s3_inst.str, "%s", insnstr);
2719
s3_inst.instruction = opcode->value;
2720
s3_inst.relax_inst = opcode->relax_value;
2721
s3_inst.type = opcode->type;
2722
s3_inst.size = s3_GET_INSN_SIZE (s3_inst.type);
2723
s3_inst.relax_size = 0;
2725
sprintf (s3_inst.name, "%s", opcode->template_name);
2726
strcpy (s3_inst.reg, "");
2727
s3_inst.error = NULL;
2728
s3_inst.reloc.type = BFD_RELOC_NONE;
2730
(*opcode->parms) (p);
2732
/* It indicates current instruction is a macro instruction if s3_inst.bwarn equals -1. */
2733
if ((s3_inst.bwarn != -1) && (!s3_inst.error) && (gen_frag_p))
2734
s3_gen_insn_frag (&s3_inst, NULL);
2737
s3_inst.error = _("unrecognized opcode");
2741
s3_append_insn (char *str, bfd_boolean gen_frag_p)
2743
int retval = s3_SUCCESS;
2745
s3_parse_16_32_inst (str, gen_frag_p);
2749
retval = (int) s3_FAIL;
2750
as_bad (_("%s -- `%s'"), s3_inst.error, s3_inst.str);
2751
s3_inst.error = NULL;
2758
s3_do16_mv_cmp (char *str)
2760
s3_skip_whitespace (str);
2762
if (s3_reg_required_here (&str, 5, s3_REG_TYPE_SCORE) == (int) s3_FAIL
2763
|| s3_skip_past_comma (&str) == (int) s3_FAIL
2764
|| s3_reg_required_here (&str, 0, s3_REG_TYPE_SCORE) == (int) s3_FAIL
2765
|| s3_end_of_line (str) == (int) s3_FAIL)
2772
s3_do16_cmpi (char *str)
2774
s3_skip_whitespace (str);
2776
if (s3_reg_required_here (&str, 5, s3_REG_TYPE_SCORE) == (int) s3_FAIL
2777
|| s3_skip_past_comma (&str) == (int) s3_FAIL
2778
|| s3_data_op2 (&str, 0, _SIMM5) == (int) s3_FAIL
2779
|| s3_end_of_line (str) == (int) s3_FAIL)
2786
s3_do16_addi (char *str)
2788
s3_skip_whitespace (str);
2790
if (s3_reglow_required_here (&str, 6) == (int) s3_FAIL
2791
|| s3_skip_past_comma (&str) == (int) s3_FAIL
2792
|| s3_data_op2 (&str, 0, _SIMM6) == (int) s3_FAIL
2793
|| s3_end_of_line (str) == (int) s3_FAIL)
2799
/* Handle bitclr! / bitset! / bittst! / bittgl! */
2801
s3_do16_rdi5 (char *str)
2803
s3_skip_whitespace (str);
2805
if (s3_reglow_required_here (&str, 5) == (int) s3_FAIL
2806
|| s3_skip_past_comma (&str) == (int) s3_FAIL
2807
|| s3_data_op2 (&str, 0, _IMM5) == (int) s3_FAIL
2808
|| s3_end_of_line (str) == (int) s3_FAIL)
2812
s3_inst.relax_inst |= (((s3_inst.instruction >>5) & 0xf) << 20)
2813
| (((s3_inst.instruction >> 5) & 0xf) << 15) | (((s3_inst.instruction ) & 0x1f) << 10);
2814
s3_inst.relax_size = 4;
2819
/* Handle sdbbp!. */
2821
s3_do16_xi5 (char *str)
2823
s3_skip_whitespace (str);
2825
if (s3_data_op2 (&str, 0, _IMM5) == (int) s3_FAIL || s3_end_of_line (str) == (int) s3_FAIL)
2829
/* Check that an immediate is word alignment or half word alignment.
2830
If so, convert it to the right format. */
2832
s3_validate_immediate_align (int val, unsigned int data_type)
2834
if (data_type == _IMM5_RSHIFT_1)
2838
s3_inst.error = _("address offset must be half word alignment");
2839
return (int) s3_FAIL;
2842
else if ((data_type == _IMM5_RSHIFT_2) || (data_type == _IMM10_RSHIFT_2))
2846
s3_inst.error = _("address offset must be word alignment");
2847
return (int) s3_FAIL;
2855
s3_exp_ldst_offset (char **str, int shift, unsigned int data_type)
2861
if ((*dataptr == '0') && (*(dataptr + 1) == 'x')
2862
&& (data_type != _SIMM16_LA)
2863
&& (data_type != _VALUE_HI16)
2864
&& (data_type != _VALUE_LO16)
2865
&& (data_type != _IMM16)
2866
&& (data_type != _IMM15)
2867
&& (data_type != _IMM14)
2868
&& (data_type != _IMM4)
2869
&& (data_type != _IMM5)
2870
&& (data_type != _IMM8)
2871
&& (data_type != _IMM5_RSHIFT_1)
2872
&& (data_type != _IMM5_RSHIFT_2)
2873
&& (data_type != _SIMM14_NEG)
2874
&& (data_type != _IMM10_RSHIFT_2))
2879
if (s3_my_get_expression (&s3_inst.reloc.exp, str) == (int) s3_FAIL)
2880
return (int) s3_FAIL;
2882
if (s3_inst.reloc.exp.X_op == O_constant)
2884
/* Need to check the immediate align. */
2885
int value = s3_validate_immediate_align (s3_inst.reloc.exp.X_add_number, data_type);
2887
if (value == (int) s3_FAIL)
2888
return (int) s3_FAIL;
2890
value = s3_validate_immediate (s3_inst.reloc.exp.X_add_number, data_type, 0);
2891
if (value == (int) s3_FAIL)
2894
sprintf (s3_err_msg,
2895
_("invalid constant: %d bit expression not in range %d..%d"),
2896
s3_score_df_range[data_type].bits,
2897
s3_score_df_range[data_type].range[0], s3_score_df_range[data_type].range[1]);
2899
sprintf (s3_err_msg,
2900
_("invalid constant: %d bit expression not in range %d..%d"),
2901
s3_score_df_range[data_type - 24].bits,
2902
s3_score_df_range[data_type - 24].range[0], s3_score_df_range[data_type - 24].range[1]);
2903
s3_inst.error = s3_err_msg;
2904
return (int) s3_FAIL;
2907
if (data_type == _IMM5_RSHIFT_1)
2911
else if ((data_type == _IMM5_RSHIFT_2) || (data_type == _IMM10_RSHIFT_2))
2916
if (s3_score_df_range[data_type].range[0] != 0)
2918
value &= (1 << s3_score_df_range[data_type].bits) - 1;
2921
s3_inst.instruction |= value << shift;
2925
s3_inst.reloc.pc_rel = 0;
2932
s3_do_ldst_insn (char *str)
2942
s3_skip_whitespace (str);
2944
if (((conflict_reg = s3_reg_required_here (&str, 20, s3_REG_TYPE_SCORE)) == (int) s3_FAIL)
2945
|| (s3_skip_past_comma (&str) == (int) s3_FAIL))
2948
/* ld/sw rD, [rA, simm15] ld/sw rD, [rA]+, simm12 ld/sw rD, [rA, simm12]+. */
2952
s3_skip_whitespace (str);
2954
if ((reg = s3_reg_required_here (&str, 15, s3_REG_TYPE_SCORE)) == (int) s3_FAIL)
2957
/* Conflicts can occur on stores as well as loads. */
2958
conflict_reg = (conflict_reg == reg);
2959
s3_skip_whitespace (str);
2960
temp = str + 1; /* The latter will process decimal/hex expression. */
2962
/* ld/sw rD, [rA]+, simm12 ld/sw rD, [rA]+. */
2969
/* ld/sw rD, [rA]+, simm12. */
2970
if (s3_skip_past_comma (&str) == s3_SUCCESS)
2972
if ((s3_exp_ldst_offset (&str, 3, _SIMM12) == (int) s3_FAIL)
2973
|| (s3_end_of_line (str) == (int) s3_FAIL))
2978
unsigned int ldst_func = s3_inst.instruction & OPC_PSEUDOLDST_MASK;
2980
if ((ldst_func == INSN_LH)
2981
|| (ldst_func == INSN_LHU)
2982
|| (ldst_func == INSN_LW)
2983
|| (ldst_func == INSN_LB)
2984
|| (ldst_func == INSN_LBU))
2986
s3_inst.error = _("register same as write-back base");
2991
ldst_idx = s3_inst.instruction & OPC_PSEUDOLDST_MASK;
2992
s3_inst.instruction &= ~OPC_PSEUDOLDST_MASK;
2993
s3_inst.instruction |= s3_score_ldst_insns[ldst_idx * 3 + LDST_POST].value;
2995
/* lw rD, [rA]+, 4 convert to pop rD, [rA]. */
2996
if ((s3_inst.instruction & 0x3e000007) == 0x0e000000)
2998
/* rs = r0, offset = 4 */
2999
if ((((s3_inst.instruction >> 15) & 0x1f) == 0)
3000
&& (((s3_inst.instruction >> 3) & 0xfff) == 4))
3002
/* Relax to pop!. */
3003
s3_inst.relax_inst = 0x0040 | ((s3_inst.instruction >> 20) & 0x1f);
3004
s3_inst.relax_size = 2;
3009
/* ld/sw rD, [rA]+ convert to ld/sw rD, [rA, 0]+. */
3012
s3_SET_INSN_ERROR (NULL);
3013
if (s3_end_of_line (str) == (int) s3_FAIL)
3019
value = s3_validate_immediate (s3_inst.reloc.exp.X_add_number, _SIMM12, 0);
3020
value &= (1 << s3_score_df_range[_SIMM12].bits) - 1;
3021
ldst_idx = s3_inst.instruction & OPC_PSEUDOLDST_MASK;
3022
s3_inst.instruction &= ~OPC_PSEUDOLDST_MASK;
3023
s3_inst.instruction |= s3_score_ldst_insns[ldst_idx * 3 + pre_inc].value;
3024
s3_inst.instruction |= value << 3;
3025
s3_inst.relax_inst = 0x8000;
3029
/* ld/sw rD, [rA] convert to ld/sw rD, [rA, simm15]. */
3032
if (s3_end_of_line (str) == (int) s3_FAIL)
3035
ldst_idx = s3_inst.instruction & OPC_PSEUDOLDST_MASK;
3036
s3_inst.instruction &= ~OPC_PSEUDOLDST_MASK;
3037
s3_inst.instruction |= s3_score_ldst_insns[ldst_idx * 3 + LDST_NOUPDATE].value;
3039
/* lbu rd, [rs] -> lbu! rd, [rs] */
3040
if (ldst_idx == INSN_LBU)
3042
s3_inst.relax_inst = INSN16_LBU;
3044
else if (ldst_idx == INSN_LH)
3046
s3_inst.relax_inst = INSN16_LH;
3048
else if (ldst_idx == INSN_LW)
3050
s3_inst.relax_inst = INSN16_LW;
3052
else if (ldst_idx == INSN_SB)
3054
s3_inst.relax_inst = INSN16_SB;
3056
else if (ldst_idx == INSN_SH)
3058
s3_inst.relax_inst = INSN16_SH;
3060
else if (ldst_idx == INSN_SW)
3062
s3_inst.relax_inst = INSN16_SW;
3066
s3_inst.relax_inst = 0x8000;
3069
/* lw/lh/lbu/sw/sh/sb, offset = 0, relax to 16 bit instruction. */
3070
/* if ((ldst_idx == INSN_LBU)
3071
|| (ldst_idx == INSN_LH)
3072
|| (ldst_idx == INSN_LW)
3073
|| (ldst_idx == INSN_SB) || (ldst_idx == INSN_SH) || (ldst_idx == INSN_SW))*/
3074
if ( (ldst_idx == INSN_LW)|| (ldst_idx == INSN_SW))
3076
/* ra only 3 bit , rd only 4 bit for lw! and sw! */
3077
if ((((s3_inst.instruction >> 15) & 0x18) == 0) && (((s3_inst.instruction >> 20) & 0x10) == 0))
3079
s3_inst.relax_inst |= (((s3_inst.instruction >> 20) & 0xf) << 8) |
3080
(((s3_inst.instruction >> 15) & 0x7) << 5);
3081
s3_inst.relax_size = 2;
3088
/* ld/sw rD, [rA, simm15] ld/sw rD, [rA, simm12]+. */
3091
if (s3_skip_past_comma (&str) == (int) s3_FAIL)
3093
s3_inst.error = _("pre-indexed expression expected");
3097
if (s3_my_get_expression (&s3_inst.reloc.exp, &str) == (int) s3_FAIL)
3100
s3_skip_whitespace (str);
3103
s3_inst.error = _("missing ]");
3107
s3_skip_whitespace (str);
3108
/* ld/sw rD, [rA, simm12]+. */
3115
unsigned int ldst_func = s3_inst.instruction & OPC_PSEUDOLDST_MASK;
3117
if ((ldst_func == INSN_LH)
3118
|| (ldst_func == INSN_LHU)
3119
|| (ldst_func == INSN_LW)
3120
|| (ldst_func == INSN_LB)
3121
|| (ldst_func == INSN_LBU))
3123
s3_inst.error = _("register same as write-back base");
3129
if (s3_end_of_line (str) == (int) s3_FAIL)
3132
if (s3_inst.reloc.exp.X_op == O_constant)
3134
unsigned int data_type;
3137
data_type = _SIMM12;
3139
data_type = _SIMM15;
3142
if ((*dataptr == '0') && (*(dataptr + 1) == 'x')
3143
&& (data_type != _SIMM16_LA)
3144
&& (data_type != _VALUE_HI16)
3145
&& (data_type != _VALUE_LO16)
3146
&& (data_type != _IMM16)
3147
&& (data_type != _IMM15)
3148
&& (data_type != _IMM14)
3149
&& (data_type != _IMM4)
3150
&& (data_type != _IMM5)
3151
&& (data_type != _IMM8)
3152
&& (data_type != _IMM5_RSHIFT_1)
3153
&& (data_type != _IMM5_RSHIFT_2)
3154
&& (data_type != _SIMM14_NEG)
3155
&& (data_type != _IMM10_RSHIFT_2))
3160
value = s3_validate_immediate (s3_inst.reloc.exp.X_add_number, data_type, 0);
3161
if (value == (int) s3_FAIL)
3164
sprintf (s3_err_msg,
3165
_("invalid constant: %d bit expression not in range %d..%d"),
3166
s3_score_df_range[data_type].bits,
3167
s3_score_df_range[data_type].range[0], s3_score_df_range[data_type].range[1]);
3169
sprintf (s3_err_msg,
3170
_("invalid constant: %d bit expression not in range %d..%d"),
3171
s3_score_df_range[data_type - 24].bits,
3172
s3_score_df_range[data_type - 24].range[0],
3173
s3_score_df_range[data_type - 24].range[1]);
3174
s3_inst.error = s3_err_msg;
3178
value &= (1 << s3_score_df_range[data_type].bits) - 1;
3179
ldst_idx = s3_inst.instruction & OPC_PSEUDOLDST_MASK;
3180
s3_inst.instruction &= ~OPC_PSEUDOLDST_MASK;
3181
s3_inst.instruction |= s3_score_ldst_insns[ldst_idx * 3 + pre_inc].value;
3183
s3_inst.instruction |= value << 3;
3185
s3_inst.instruction |= value;
3187
/* lw rD, [rA, simm15] */
3188
if ((s3_inst.instruction & 0x3e000000) == 0x20000000)
3190
/* rD in [r0 - r15]. , ra in [r0-r7] */
3191
if ((((s3_inst.instruction >> 15) & 0x18) == 0)
3192
&& (((s3_inst.instruction >> 20) & 0x10) == 0))
3194
/* simm = [bit 7], lw -> lw!. */
3195
if (((s3_inst.instruction & 0x7f80) == 0)&&((s3_inst.instruction &0x3)==0))
3197
s3_inst.relax_inst |= (((s3_inst.instruction >> 15) & 0x7) << 5)
3198
| (((s3_inst.instruction >> 20) & 0xf) << 8)|(value>>2);
3199
s3_inst.relax_size = 2;
3203
s3_inst.relax_inst = 0x8000;
3208
s3_inst.relax_inst = 0x8000;
3211
/* sw rD, [rA, simm15] */
3212
else if ((s3_inst.instruction & 0x3e000000) == 0x28000000)
3214
/* rD is in [r0 - r15] and ra in [r0-r7] */
3215
if ((((s3_inst.instruction >> 15) & 0x18) == 0) && (((s3_inst.instruction >> 20) & 0x10) == 0))
3217
/* simm15 =7 bit , sw -> sw!. */
3218
if (((s3_inst.instruction & 0x7f80) == 0)&&((s3_inst.instruction &0x3)==0))
3220
s3_inst.relax_inst |= (((s3_inst.instruction >> 15) & 0xf) << 5)
3221
| (((s3_inst.instruction >> 20) & 0xf) << 8)|(value>>2);
3222
s3_inst.relax_size = 2;
3224
/* rA = r2, sw -> swp!. */
3227
s3_inst.relax_inst = 0x8000;
3232
s3_inst.relax_inst = 0x8000;
3235
/* sw rD, [rA, simm15]+ sw pre. */
3236
else if ((s3_inst.instruction & 0x3e000007) == 0x06000004)
3238
/* simm15 = -4. and ra==r0 */
3239
if ((((s3_inst.instruction >> 15) & 0x1f) == 0)
3240
&& (((s3_inst.instruction >> 3) & 0xfff) == 0xffc))
3243
s3_inst.relax_inst = 0x0060 | ((s3_inst.instruction >> 20) & 0x1f);
3244
s3_inst.relax_size = 2;
3248
s3_inst.relax_inst = 0x8000;
3253
s3_inst.relax_inst = 0x8000;
3260
/* FIXME: may set error, for there is no ld/sw rD, [rA, label] */
3261
s3_inst.reloc.pc_rel = 0;
3267
s3_inst.error = s3_BAD_ARGS;
3273
s3_do_cache (char *str)
3275
s3_skip_whitespace (str);
3277
if ((s3_data_op2 (&str, 20, _IMM5) == (int) s3_FAIL) || (s3_skip_past_comma (&str) == (int) s3_FAIL))
3285
cache_op = (s3_inst.instruction >> 20) & 0x1F;
3286
sprintf (s3_inst.name, "cache %d", cache_op);
3292
s3_skip_whitespace (str);
3294
if (s3_reg_required_here (&str, 15, s3_REG_TYPE_SCORE) == (int) s3_FAIL)
3297
s3_skip_whitespace (str);
3299
/* cache op, [rA] */
3300
if (s3_skip_past_comma (&str) == (int) s3_FAIL)
3302
s3_SET_INSN_ERROR (NULL);
3305
s3_inst.error = _("missing ]");
3310
/* cache op, [rA, simm15] */
3313
if (s3_exp_ldst_offset (&str, 0, _SIMM15) == (int) s3_FAIL)
3318
s3_skip_whitespace (str);
3321
s3_inst.error = _("missing ]");
3326
if (s3_end_of_line (str) == (int) s3_FAIL)
3331
s3_inst.error = s3_BAD_ARGS;
3336
s3_do_crdcrscrsimm5 (char *str)
3341
s3_skip_whitespace (str);
3343
if (s3_reg_required_here (&str, 20, s3_REG_TYPE_SCORE_CR) == (int) s3_FAIL
3344
|| s3_skip_past_comma (&str) == (int) s3_FAIL
3345
|| s3_reg_required_here (&str, 15, s3_REG_TYPE_SCORE_CR) == (int) s3_FAIL
3346
|| s3_skip_past_comma (&str) == (int) s3_FAIL
3347
|| s3_reg_required_here (&str, 10, s3_REG_TYPE_SCORE_CR) == (int) s3_FAIL
3348
|| s3_skip_past_comma (&str) == (int) s3_FAIL)
3351
/* cop1 cop_code20. */
3352
if (s3_data_op2 (&str, 5, _IMM20) == (int) s3_FAIL)
3357
if (s3_data_op2 (&str, 5, _IMM5) == (int) s3_FAIL)
3361
s3_end_of_line (str);
3364
/* Handle ldc/stc. */
3366
s3_do_ldst_cop (char *str)
3368
s3_skip_whitespace (str);
3370
if ((s3_reg_required_here (&str, 15, s3_REG_TYPE_SCORE_CR) == (int) s3_FAIL)
3371
|| (s3_skip_past_comma (&str) == (int) s3_FAIL))
3377
s3_skip_whitespace (str);
3379
if (s3_reg_required_here (&str, 20, s3_REG_TYPE_SCORE) == (int) s3_FAIL)
3382
s3_skip_whitespace (str);
3386
if (s3_exp_ldst_offset (&str, 5, _IMM10_RSHIFT_2) == (int) s3_FAIL)
3389
s3_skip_whitespace (str);
3392
s3_inst.error = _("missing ]");
3397
s3_end_of_line (str);
3400
s3_inst.error = s3_BAD_ARGS;
3404
s3_do16_ldst_insn (char *str)
3406
int conflict_reg = 0;
3407
s3_skip_whitespace (str);
3409
if ((s3_reglow_required_here (&str, 8) == (int) s3_FAIL) || (s3_skip_past_comma (&str) == (int) s3_FAIL))
3416
s3_skip_whitespace (str);
3418
if ((conflict_reg = s3_reglow_required_here (&str, 5)) == (int) s3_FAIL)
3420
if (conflict_reg&0x8)
3422
sprintf (s3_err_msg, _("invalid register number: %d is not in [r0--r7]"),conflict_reg);
3423
s3_inst.error = s3_err_msg;
3427
s3_skip_whitespace (str);
3432
if (s3_end_of_line (str) == (int) s3_FAIL)
3437
if (s3_skip_past_comma (&str) == (int) s3_FAIL)
3439
s3_inst.error = _("comma is expected");
3442
if (s3_my_get_expression (&s3_inst.reloc.exp, &str) == (int) s3_FAIL)
3444
s3_skip_whitespace (str);
3447
s3_inst.error = _("missing ]");
3450
if (s3_end_of_line (str) == (int) s3_FAIL)
3452
if (s3_inst.reloc.exp.X_op == O_constant)
3455
unsigned int data_type;
3456
data_type = _IMM5_RSHIFT_2;
3457
value = s3_validate_immediate (s3_inst.reloc.exp.X_add_number, data_type, 0);
3458
if (value == (int) s3_FAIL)
3461
sprintf (s3_err_msg,
3462
_("invalid constant: %d bit expression not in range %d..%d"),
3463
s3_score_df_range[data_type].bits,
3464
s3_score_df_range[data_type].range[0], s3_score_df_range[data_type].range[1]);
3465
s3_inst.error = s3_err_msg;
3470
sprintf (s3_err_msg, _("invalid constant: %d is not word align integer"),value);
3471
s3_inst.error = s3_err_msg;
3476
s3_inst.instruction |= value;
3482
sprintf (s3_err_msg, _("missing ["));
3483
s3_inst.error = s3_err_msg;
3489
s3_do_lw48 (char *str)
3491
bfd_signed_vma val = 0;
3493
s3_skip_whitespace (str);
3495
if ((s3_reg_required_here (&str, 37, s3_REG_TYPE_SCORE) == (int) s3_FAIL)
3496
|| (s3_skip_past_comma (&str) == (int) s3_FAIL))
3499
if (s3_my_get_expression (&s3_inst.reloc.exp, &str) == (int) s3_FAIL
3500
|| s3_end_of_line (str) == (int) s3_FAIL)
3505
/* Check word align for lw48 rd, value. */
3506
if ((s3_inst.reloc.exp.X_add_symbol == NULL)
3507
&& ((s3_inst.reloc.exp.X_add_number & 0x3) != 0))
3509
s3_inst.error = _("invalid constant: 32 bit expression not word align");
3513
/* Check and set offset. */
3514
val = s3_inst.reloc.exp.X_add_number;
3515
if ((s3_inst.reloc.exp.X_add_symbol == NULL)
3516
&& (!(val >= 0 && val <= 0xffffffffLL)))
3518
s3_inst.error = _("invalid constant: 32 bit expression not in range [0, 0xffffffff]");
3524
s3_inst.instruction |= (val << 7);
3526
/* Set reloc type. */
3527
s3_inst.reloc.type = BFD_RELOC_SCORE_IMM30;
3532
s3_do_sw48 (char *str)
3534
bfd_signed_vma val = 0;
3536
s3_skip_whitespace (str);
3538
if ((s3_reg_required_here (&str, 37, s3_REG_TYPE_SCORE) == (int) s3_FAIL)
3539
|| (s3_skip_past_comma (&str) == (int) s3_FAIL))
3542
if (s3_my_get_expression (&s3_inst.reloc.exp, &str) == (int) s3_FAIL
3543
|| s3_end_of_line (str) == (int) s3_FAIL)
3548
/* Check word align for lw48 rd, value. */
3549
if ((s3_inst.reloc.exp.X_add_symbol == NULL)
3550
&& ((s3_inst.reloc.exp.X_add_number & 0x3) != 0))
3552
s3_inst.error = _("invalid constant: 32 bit expression not word align");
3556
/* Check and set offset. */
3557
val = s3_inst.reloc.exp.X_add_number;
3558
if ((s3_inst.reloc.exp.X_add_symbol == NULL)
3559
&& (!(val >= 0 && val <= 0xffffffffLL)))
3561
s3_inst.error = _("invalid constant: 32 bit expression not in range [0, 0xffffffff]");
3567
s3_inst.instruction |= (val << 7);
3569
/* Set reloc type. */
3570
s3_inst.reloc.type = BFD_RELOC_SCORE_IMM30;
3574
s3_do_ldi48 (char *str)
3578
s3_skip_whitespace (str);
3580
if (s3_reg_required_here (&str, 37, s3_REG_TYPE_SCORE) == (int) s3_FAIL
3581
|| s3_skip_past_comma (&str) == (int) s3_FAIL)
3584
if (s3_my_get_expression (&s3_inst.reloc.exp, &str) == (int) s3_FAIL
3585
|| s3_end_of_line (str) == (int) s3_FAIL)
3590
/* Check and set offset. */
3591
val = s3_inst.reloc.exp.X_add_number;
3592
if (!(val >= -0xffffffffLL && val <= 0xffffffffLL))
3594
s3_inst.error = _("invalid constant: 32 bit expression not in range [-0x80000000, 0x7fffffff]");
3599
s3_inst.instruction |= (val << 5);
3601
/* Set reloc type. */
3602
s3_inst.reloc.type = BFD_RELOC_SCORE_IMM32;
3606
s3_do_sdbbp48 (char *str)
3608
s3_skip_whitespace (str);
3610
if (s3_data_op2 (&str, 5, _IMM5) == (int) s3_FAIL || s3_end_of_line (str) == (int) s3_FAIL)
3615
s3_do_and48 (char *str)
3617
s3_skip_whitespace (str);
3619
if (s3_reglow_required_here (&str, 38) == (int) s3_FAIL
3620
|| s3_skip_past_comma (&str) == (int) s3_FAIL
3621
|| s3_reglow_required_here (&str, 34) == (int) s3_FAIL
3622
|| s3_skip_past_comma (&str) == (int) s3_FAIL
3623
|| s3_data_op2 (&str, 2, _IMM32) == (int) s3_FAIL
3624
|| s3_end_of_line (str) == (int) s3_FAIL)
3629
s3_do_or48 (char *str)
3631
s3_skip_whitespace (str);
3633
if (s3_reglow_required_here (&str, 38) == (int) s3_FAIL
3634
|| s3_skip_past_comma (&str) == (int) s3_FAIL
3635
|| s3_reglow_required_here (&str, 34) == (int) s3_FAIL
3636
|| s3_skip_past_comma (&str) == (int) s3_FAIL
3637
|| s3_data_op2 (&str, 2, _IMM32) == (int) s3_FAIL
3638
|| s3_end_of_line (str) == (int) s3_FAIL)
3643
s3_do_mbitclr (char *str)
3646
s3_skip_whitespace (str);
3650
sprintf (s3_err_msg, _("missing ["));
3651
s3_inst.error = s3_err_msg;
3656
s3_inst.instruction &= 0x0;
3658
if ((s3_reg_required_here (&str, 15, s3_REG_TYPE_SCORE) == (int) s3_FAIL)
3659
|| (s3_skip_past_comma (&str) == (int) s3_FAIL)
3660
|| (s3_data_op2 (&str, 0, _IMM11) == (int) s3_FAIL))
3663
/* Get imm11 and refill opcode. */
3664
val = s3_inst.instruction & 0x7ff;
3666
s3_inst.instruction &= 0x000f8000;
3667
s3_inst.instruction |= 0x00000064;
3671
sprintf (s3_err_msg, _("missing ]"));
3672
s3_inst.error = s3_err_msg;
3677
if ((s3_skip_past_comma (&str) == (int) s3_FAIL)
3678
|| (s3_data_op2 (&str, 10, _IMM5) == (int) s3_FAIL))
3681
/* Set imm11 to opcode. */
3682
s3_inst.instruction |= (val & 0x1)
3683
| (((val >> 1 ) & 0x7) << 7)
3684
| (((val >> 4 ) & 0x1f) << 20);
3688
s3_do_mbitset (char *str)
3691
s3_skip_whitespace (str);
3695
sprintf (s3_err_msg, _("missing ["));
3696
s3_inst.error = s3_err_msg;
3701
s3_inst.instruction &= 0x0;
3703
if ((s3_reg_required_here (&str, 15, s3_REG_TYPE_SCORE) == (int) s3_FAIL)
3704
|| (s3_skip_past_comma (&str) == (int) s3_FAIL)
3705
|| (s3_data_op2 (&str, 0, _IMM11) == (int) s3_FAIL))
3708
/* Get imm11 and refill opcode. */
3709
val = s3_inst.instruction & 0x7ff;
3711
s3_inst.instruction &= 0x000f8000;
3712
s3_inst.instruction |= 0x0000006c;
3716
sprintf (s3_err_msg, _("missing ]"));
3717
s3_inst.error = s3_err_msg;
3722
if ((s3_skip_past_comma (&str) == (int) s3_FAIL)
3723
|| (s3_data_op2 (&str, 10, _IMM5) == (int) s3_FAIL))
3726
/* Set imm11 to opcode. */
3727
s3_inst.instruction |= (val & 0x1)
3728
| (((val >> 1 ) & 0x7) << 7)
3729
| (((val >> 4 ) & 0x1f) << 20);
3733
s3_do16_slli_srli (char *str)
3735
s3_skip_whitespace (str);
3737
if ((s3_reglow_required_here (&str, 5) == (int) s3_FAIL)
3738
|| (s3_skip_past_comma (&str) == (int) s3_FAIL)
3739
|| s3_data_op2 (&str, 0, _IMM5) == (int) s3_FAIL
3740
|| s3_end_of_line (str) == (int) s3_FAIL)
3745
s3_do16_ldiu (char *str)
3747
s3_skip_whitespace (str);
3749
if ((s3_reg_required_here (&str, 5,s3_REG_TYPE_SCORE) == (int) s3_FAIL)
3750
|| (s3_skip_past_comma (&str) == (int) s3_FAIL)
3751
|| s3_data_op2 (&str, 0, _IMM5) == (int) s3_FAIL
3752
|| s3_end_of_line (str) == (int) s3_FAIL)
3757
s3_do16_push_pop (char *str)
3759
s3_skip_whitespace (str);
3760
if ((s3_reg_required_here (&str, 0, s3_REG_TYPE_SCORE)) == (int) s3_FAIL
3761
|| s3_end_of_line (str) == (int) s3_FAIL)
3766
s3_do16_rpush (char *str)
3770
s3_skip_whitespace (str);
3771
if ((reg = (s3_reg_required_here (&str, 5, s3_REG_TYPE_SCORE))) == (int) s3_FAIL
3772
|| s3_skip_past_comma (&str) == (int) s3_FAIL
3773
|| s3_data_op2 (&str, 0, _IMM5_MULTI_LOAD) == (int) s3_FAIL
3774
|| s3_end_of_line (str) == (int) s3_FAIL)
3779
2: to 31: normal value. */
3780
val = s3_inst.instruction & 0x1f;
3783
s3_inst.error = _("imm5 should >= 2");
3788
s3_inst.error = _("reg should <= 31");
3794
s3_do16_rpop (char *str)
3798
s3_skip_whitespace (str);
3799
if ((reg = (s3_reg_required_here (&str, 5, s3_REG_TYPE_SCORE))) == (int) s3_FAIL
3800
|| s3_skip_past_comma (&str) == (int) s3_FAIL
3801
|| s3_data_op2 (&str, 0, _IMM5_MULTI_LOAD) == (int) s3_FAIL
3802
|| s3_end_of_line (str) == (int) s3_FAIL)
3807
2: to 31: normal value. */
3808
val = s3_inst.instruction & 0x1f;
3811
s3_inst.error = _("imm5 should >= 2");
3817
s3_inst.error = _("reg should <= 31");
3822
if ((reg + val) <= 32)
3823
reg = reg + val - 1;
3825
reg = reg + val - 33;
3826
s3_inst.instruction &= 0x7c1f;
3827
s3_inst.instruction |= (reg << 5);
3832
/* Handle lcb/lcw/lce/scb/scw/sce. */
3834
s3_do_ldst_unalign (char *str)
3838
if (s3_university_version == 1)
3840
s3_inst.error = s3_ERR_FOR_SCORE5U_ATOMIC;
3844
s3_skip_whitespace (str);
3846
/* lcb/scb [rA]+. */
3850
s3_skip_whitespace (str);
3852
if (s3_reg_required_here (&str, 15, s3_REG_TYPE_SCORE) == (int) s3_FAIL)
3859
s3_inst.error = _("missing +");
3865
s3_inst.error = _("missing ]");
3869
if (s3_end_of_line (str) == (int) s3_FAIL)
3872
/* lcw/lce/scb/sce rD, [rA]+. */
3875
if (((conflict_reg = s3_reg_required_here (&str, 20, s3_REG_TYPE_SCORE)) == (int) s3_FAIL)
3876
|| (s3_skip_past_comma (&str) == (int) s3_FAIL))
3881
s3_skip_whitespace (str);
3886
s3_skip_whitespace (str);
3887
if ((reg = s3_reg_required_here (&str, 15, s3_REG_TYPE_SCORE)) == (int) s3_FAIL)
3892
/* Conflicts can occur on stores as well as loads. */
3893
conflict_reg = (conflict_reg == reg);
3894
s3_skip_whitespace (str);
3897
unsigned int ldst_func = s3_inst.instruction & LDST_UNALIGN_MASK;
3903
as_warn (_("%s register same as write-back base"),
3904
((ldst_func & UA_LCE) || (ldst_func & UA_LCW)
3905
? _("destination") : _("source")));
3910
s3_inst.error = _("missing +");
3914
if (s3_end_of_line (str) == (int) s3_FAIL)
3919
s3_inst.error = _("missing ]");
3925
s3_inst.error = s3_BAD_ARGS;
3931
/* Handle alw/asw. */
3933
s3_do_ldst_atomic (char *str)
3935
if (s3_university_version == 1)
3937
s3_inst.error = s3_ERR_FOR_SCORE5U_ATOMIC;
3941
s3_skip_whitespace (str);
3943
if ((s3_reg_required_here (&str, 20, s3_REG_TYPE_SCORE) == (int) s3_FAIL)
3944
|| (s3_skip_past_comma (&str) == (int) s3_FAIL))
3951
s3_skip_whitespace (str);
3956
s3_skip_whitespace (str);
3957
if ((reg = s3_reg_required_here (&str, 15, s3_REG_TYPE_SCORE)) == (int) s3_FAIL)
3962
s3_skip_whitespace (str);
3965
s3_inst.error = _("missing ]");
3969
s3_end_of_line (str);
3972
s3_inst.error = s3_BAD_ARGS;
3977
s3_build_relax_frag (struct s3_score_it fix_insts[s3_RELAX_INST_NUM], int fix_num ATTRIBUTE_UNUSED,
3978
struct s3_score_it var_insts[s3_RELAX_INST_NUM], int var_num,
3979
symbolS *add_symbol)
3984
fixS *cur_fixp = NULL;
3986
struct s3_score_it inst_main;
3988
memcpy (&inst_main, &fix_insts[0], sizeof (struct s3_score_it));
3990
/* Adjust instruction opcode and to be relaxed instruction opcode. */
3991
inst_main.instruction = s3_adjust_paritybit (inst_main.instruction, s3_GET_INSN_CLASS (inst_main.type));
3992
inst_main.type = Insn_PIC;
3994
for (i = 0; i < var_num; i++)
3996
inst_main.relax_size += var_insts[i].size;
3997
var_insts[i].instruction = s3_adjust_paritybit (var_insts[i].instruction,
3998
s3_GET_INSN_CLASS (var_insts[i].type));
4001
/* Check data dependency. */
4002
s3_handle_dependency (&inst_main);
4004
/* Start a new frag if frag_now is not empty. */
4005
if (frag_now_fix () != 0)
4007
if (!frag_now->tc_frag_data.is_insn)
4009
frag_wane (frag_now);
4015
/* Write fr_fix part. */
4016
p = frag_more (inst_main.size);
4017
s3_md_number_to_chars (p, inst_main.instruction, inst_main.size);
4019
if (inst_main.reloc.type != BFD_RELOC_NONE)
4020
fixp = s3_fix_new_score (frag_now, p - frag_now->fr_literal, inst_main.size,
4021
&inst_main.reloc.exp, inst_main.reloc.pc_rel, inst_main.reloc.type);
4023
frag_now->tc_frag_data.fixp = fixp;
4024
cur_fixp = frag_now->tc_frag_data.fixp;
4027
dwarf2_emit_insn (inst_main.size);
4030
where = p - frag_now->fr_literal + inst_main.size;
4031
for (i = 0; i < var_num; i++)
4034
where += var_insts[i - 1].size;
4036
if (var_insts[i].reloc.type != BFD_RELOC_NONE)
4038
fixp = s3_fix_new_score (frag_now, where, var_insts[i].size,
4039
&var_insts[i].reloc.exp, var_insts[i].reloc.pc_rel,
4040
var_insts[i].reloc.type);
4045
cur_fixp->fx_next = fixp;
4046
cur_fixp = cur_fixp->fx_next;
4050
frag_now->tc_frag_data.fixp = fixp;
4051
cur_fixp = frag_now->tc_frag_data.fixp;
4057
p = frag_var (rs_machine_dependent, inst_main.relax_size + s3_RELAX_PAD_BYTE, 0,
4058
s3_RELAX_ENCODE (inst_main.size, inst_main.relax_size, inst_main.type,
4059
0, inst_main.size, 0), add_symbol, 0, NULL);
4061
/* Write fr_var part.
4062
no calling s3_gen_insn_frag, no fixS will be generated. */
4063
for (i = 0; i < var_num; i++)
4065
s3_md_number_to_chars (p, var_insts[i].instruction, var_insts[i].size);
4066
p += var_insts[i].size;
4068
/* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4072
/* Build a relax frag for la instruction when generating s3_PIC,
4073
external symbol first and local symbol second. */
4075
s3_build_la_pic (int reg_rd, expressionS exp)
4077
symbolS *add_symbol = exp.X_add_symbol;
4078
offsetT add_number = exp.X_add_number;
4079
struct s3_score_it fix_insts[s3_RELAX_INST_NUM];
4080
struct s3_score_it var_insts[s3_RELAX_INST_NUM];
4083
char tmp[s3_MAX_LITERAL_POOL_SIZE];
4089
if (add_number == 0)
4094
/* For an external symbol, only one insn is generated;
4095
For a local symbol, two insns are generated. */
4097
For an external symbol: lw rD, <sym>($gp)
4098
(BFD_RELOC_SCORE_GOT15 or BFD_RELOC_SCORE_CALL15) */
4099
sprintf (tmp, "lw_pic r%d, %s", reg_rd, add_symbol->bsym->name);
4100
if (s3_append_insn (tmp, FALSE) == (int) s3_FAIL)
4103
if (reg_rd == s3_PIC_CALL_REG)
4104
s3_inst.reloc.type = BFD_RELOC_SCORE_CALL15;
4105
memcpy (&fix_insts[0], &s3_inst, sizeof (struct s3_score_it));
4108
For a local symbol :
4109
lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15)
4110
addi rD, <sym> (BFD_RELOC_GOT_LO16) */
4111
s3_inst.reloc.type = BFD_RELOC_SCORE_GOT15;
4112
memcpy (&var_insts[0], &s3_inst, sizeof (struct s3_score_it));
4113
sprintf (tmp, "addi_s_pic r%d, %s", reg_rd, add_symbol->bsym->name);
4114
if (s3_append_insn (tmp, FALSE) == (int) s3_FAIL)
4117
memcpy (&var_insts[1], &s3_inst, sizeof (struct s3_score_it));
4118
s3_build_relax_frag (fix_insts, fix_num, var_insts, var_num, add_symbol);
4120
else if (add_number >= -0x8000 && add_number <= 0x7fff)
4122
/* Insn 1: lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15) */
4123
sprintf (tmp, "lw_pic r%d, %s", reg_rd, add_symbol->bsym->name);
4124
if (s3_append_insn (tmp, TRUE) == (int) s3_FAIL)
4131
For an external symbol: addi rD, <constant> */
4132
sprintf (tmp, "addi r%d, %d", reg_rd, (int)add_number);
4133
if (s3_append_insn (tmp, FALSE) == (int) s3_FAIL)
4136
memcpy (&fix_insts[0], &s3_inst, sizeof (struct s3_score_it));
4139
For a local symbol: addi rD, <sym>+<constant> (BFD_RELOC_GOT_LO16) */
4140
sprintf (tmp, "addi_s_pic r%d, %s + %d", reg_rd, add_symbol->bsym->name, (int)add_number);
4141
if (s3_append_insn (tmp, FALSE) == (int) s3_FAIL)
4144
memcpy (&var_insts[0], &s3_inst, sizeof (struct s3_score_it));
4145
s3_build_relax_frag (fix_insts, fix_num, var_insts, var_num, add_symbol);
4149
int hi = (add_number >> 16) & 0x0000FFFF;
4150
int lo = add_number & 0x0000FFFF;
4152
/* Insn 1: lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15) */
4153
sprintf (tmp, "lw_pic r%d, %s", reg_rd, add_symbol->bsym->name);
4154
if (s3_append_insn (tmp, TRUE) == (int) s3_FAIL)
4161
For an external symbol: ldis r1, HI%<constant> */
4162
sprintf (tmp, "ldis r1, %d", hi);
4163
if (s3_append_insn (tmp, FALSE) == (int) s3_FAIL)
4166
memcpy (&fix_insts[0], &s3_inst, sizeof (struct s3_score_it));
4169
For a local symbol: ldis r1, HI%<constant>
4170
but, if lo is outof 16 bit, make hi plus 1 */
4171
if ((lo < -0x8000) || (lo > 0x7fff))
4175
sprintf (tmp, "ldis_pic r1, %d", hi);
4176
if (s3_append_insn (tmp, FALSE) == (int) s3_FAIL)
4179
memcpy (&var_insts[0], &s3_inst, sizeof (struct s3_score_it));
4180
s3_build_relax_frag (fix_insts, fix_num, var_insts, var_num, add_symbol);
4186
For an external symbol: ori r1, LO%<constant> */
4187
sprintf (tmp, "ori r1, %d", lo);
4188
if (s3_append_insn (tmp, FALSE) == (int) s3_FAIL)
4191
memcpy (&fix_insts[0], &s3_inst, sizeof (struct s3_score_it));
4194
For a local symbol: addi r1, <sym>+LO%<constant> (BFD_RELOC_GOT_LO16) */
4195
sprintf (tmp, "addi_u_pic r1, %s + %d", add_symbol->bsym->name, lo);
4196
if (s3_append_insn (tmp, FALSE) == (int) s3_FAIL)
4199
memcpy (&var_insts[0], &s3_inst, sizeof (struct s3_score_it));
4200
s3_build_relax_frag (fix_insts, fix_num, var_insts, var_num, add_symbol);
4202
/* Insn 4: add rD, rD, r1 */
4203
sprintf (tmp, "add r%d, r%d, r1", reg_rd, reg_rd);
4204
if (s3_append_insn (tmp, TRUE) == (int) s3_FAIL)
4207
/* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4216
s3_do_macro_la_rdi32 (char *str)
4220
s3_skip_whitespace (str);
4221
if ((reg_rd = s3_reg_required_here (&str, 20, s3_REG_TYPE_SCORE)) == (int) s3_FAIL
4222
|| s3_skip_past_comma (&str) == (int) s3_FAIL)
4229
char *keep_data = str;
4230
char append_str[s3_MAX_LITERAL_POOL_SIZE];
4232
/* Check immediate value. */
4233
if (s3_my_get_expression (&s3_inst.reloc.exp, &str) == (int) s3_FAIL)
4235
s3_inst.error = _("expression error");
4238
else if ((s3_inst.reloc.exp.X_add_symbol == NULL)
4239
&& (s3_validate_immediate (s3_inst.reloc.exp.X_add_number, _IMM32, 0) == (int) s3_FAIL))
4241
s3_inst.error = _("value not in range [0, 0xffffffff]");
4248
/* la rd, simm16. */
4249
if (s3_data_op2 (&str, 1, _SIMM16_LA) != (int) s3_FAIL)
4251
s3_end_of_line (str);
4254
/* la rd, imm32 or la rd, label. */
4257
s3_SET_INSN_ERROR (NULL);
4260
if ((s3_data_op2 (&str, 1, _VALUE_HI16) == (int) s3_FAIL)
4261
|| (s3_end_of_line (str) == (int) s3_FAIL))
4267
if ((s3_score_pic == s3_NO_PIC) || (!s3_inst.reloc.exp.X_add_symbol))
4269
sprintf (append_str, "ld_i32hi r%d, %s", reg_rd, keep_data);
4270
if (s3_append_insn (append_str, TRUE) == (int) s3_FAIL)
4273
sprintf (append_str, "ld_i32lo r%d, %s", reg_rd, keep_data);
4274
if (s3_append_insn (append_str, TRUE) == (int) s3_FAIL)
4279
gas_assert (s3_inst.reloc.exp.X_add_symbol);
4280
s3_build_la_pic (reg_rd, s3_inst.reloc.exp);
4283
/* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4292
s3_do_macro_li_rdi32 (char *str)
4297
s3_skip_whitespace (str);
4298
if ((reg_rd = s3_reg_required_here (&str, 20, s3_REG_TYPE_SCORE)) == (int) s3_FAIL
4299
|| s3_skip_past_comma (&str) == (int) s3_FAIL)
4306
char *keep_data = str;
4308
/* Check immediate value. */
4309
if (s3_my_get_expression (&s3_inst.reloc.exp, &str) == (int) s3_FAIL)
4311
s3_inst.error = _("expression error");
4314
else if (!(s3_inst.reloc.exp.X_add_number >= -0xffffffffLL
4315
&& s3_inst.reloc.exp.X_add_number <= 0xffffffffLL))
4317
s3_inst.error = _("value not in range [-0xffffffff, 0xffffffff]");
4324
/* li rd, simm16. */
4325
if (s3_data_op2 (&str, 1, _SIMM16_LA) != (int) s3_FAIL)
4327
s3_end_of_line (str);
4333
char append_str[s3_MAX_LITERAL_POOL_SIZE];
4338
if ((s3_data_op2 (&str, 1, _VALUE_HI16) == (int) s3_FAIL)
4339
|| (s3_end_of_line (str) == (int) s3_FAIL))
4343
else if (s3_inst.reloc.exp.X_add_symbol)
4345
s3_inst.error = _("li rd label isn't correct instruction form");
4350
sprintf (append_str, "ld_i32hi r%d, %s", reg_rd, keep_data);
4352
if (s3_append_insn (append_str, TRUE) == (int) s3_FAIL)
4356
sprintf (append_str, "ld_i32lo r%d, %s", reg_rd, keep_data);
4357
if (s3_append_insn (append_str, TRUE) == (int) s3_FAIL)
4360
/* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4368
/* Handle mul/mulu/div/divu/rem/remu. */
4370
s3_do_macro_mul_rdrsrs (char *str)
4376
char append_str[s3_MAX_LITERAL_POOL_SIZE];
4378
if (s3_university_version == 1)
4379
as_warn ("%s", s3_ERR_FOR_SCORE5U_MUL_DIV);
4381
strcpy (append_str, str);
4382
backupstr = append_str;
4383
s3_skip_whitespace (backupstr);
4384
if (((reg_rd = s3_reg_required_here (&backupstr, -1, s3_REG_TYPE_SCORE)) == (int) s3_FAIL)
4385
|| (s3_skip_past_comma (&backupstr) == (int) s3_FAIL)
4386
|| ((reg_rs1 = s3_reg_required_here (&backupstr, -1, s3_REG_TYPE_SCORE)) == (int) s3_FAIL))
4388
s3_inst.error = s3_BAD_ARGS;
4392
if (s3_skip_past_comma (&backupstr) == (int) s3_FAIL)
4394
/* rem/remu rA, rB is error format. */
4395
if (strcmp (s3_inst.name, "rem") == 0 || strcmp (s3_inst.name, "remu") == 0)
4397
s3_SET_INSN_ERROR (s3_BAD_ARGS);
4401
s3_SET_INSN_ERROR (NULL);
4408
s3_SET_INSN_ERROR (NULL);
4409
if (((reg_rs2 = s3_reg_required_here (&backupstr, -1, s3_REG_TYPE_SCORE)) == (int) s3_FAIL)
4410
|| (s3_end_of_line (backupstr) == (int) s3_FAIL))
4416
char append_str1[s3_MAX_LITERAL_POOL_SIZE];
4418
if (strcmp (s3_inst.name, "rem") == 0)
4420
sprintf (append_str, "mul r%d, r%d", reg_rs1, reg_rs2);
4421
sprintf (append_str1, "mfceh r%d", reg_rd);
4423
else if (strcmp (s3_inst.name, "remu") == 0)
4425
sprintf (append_str, "mulu r%d, r%d", reg_rs1, reg_rs2);
4426
sprintf (append_str1, "mfceh r%d", reg_rd);
4430
sprintf (append_str, "%s r%d, r%d", s3_inst.name, reg_rs1, reg_rs2);
4431
sprintf (append_str1, "mfcel r%d", reg_rd);
4434
/* Output mul/mulu or div/divu or rem/remu. */
4435
if (s3_append_insn (append_str, TRUE) == (int) s3_FAIL)
4438
/* Output mfcel or mfceh. */
4439
if (s3_append_insn (append_str1, TRUE) == (int) s3_FAIL)
4442
/* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4449
s3_exp_macro_ldst_abs (char *str)
4452
char *backupstr, *tmp;
4453
char append_str[s3_MAX_LITERAL_POOL_SIZE];
4454
char verifystr[s3_MAX_LITERAL_POOL_SIZE];
4455
struct s3_score_it inst_backup;
4460
memcpy (&inst_backup, &s3_inst, sizeof (struct s3_score_it));
4462
strcpy (verifystr, str);
4463
backupstr = verifystr;
4464
s3_skip_whitespace (backupstr);
4465
if ((reg_rd = s3_reg_required_here (&backupstr, -1, s3_REG_TYPE_SCORE)) == (int) s3_FAIL)
4469
if (s3_skip_past_comma (&backupstr) == (int) s3_FAIL)
4473
sprintf (append_str, "li r1 %s", backupstr);
4474
s3_append_insn (append_str, TRUE);
4476
memcpy (&s3_inst, &inst_backup, sizeof (struct s3_score_it));
4477
sprintf (append_str, " r%d, [r1,0]", reg_rd);
4478
s3_do_ldst_insn (append_str);
4483
/* Handle bcmpeq / bcmpne */
4485
s3_do_macro_bcmp (char *str)
4488
char keep_data[s3_MAX_LITERAL_POOL_SIZE];
4491
struct s3_score_it inst_expand[2];
4492
struct s3_score_it inst_main;
4494
memset (inst_expand, 0, sizeof inst_expand);
4495
s3_skip_whitespace (str);
4496
if (( reg_a = s3_reg_required_here (&str, 15, s3_REG_TYPE_SCORE)) == (int) s3_FAIL
4497
|| s3_skip_past_comma (&str) == (int) s3_FAIL
4498
||(reg_b = s3_reg_required_here (&str, 10, s3_REG_TYPE_SCORE)) == (int) s3_FAIL
4499
|| s3_skip_past_comma (&str) == (int) s3_FAIL)
4504
keep_data[i] = *ptemp;
4509
if (s3_my_get_expression (&s3_inst.reloc.exp, &str) == (int) s3_FAIL
4511
|| s3_end_of_line (str) == (int) s3_FAIL)
4513
else if (s3_inst.reloc.exp.X_add_symbol == 0)
4515
s3_inst.error = _("lacking label ");
4520
char append_str[s3_MAX_LITERAL_POOL_SIZE];
4521
s3_SET_INSN_ERROR (NULL);
4523
s3_inst.reloc.type = BFD_RELOC_SCORE_BCMP;
4524
s3_inst.reloc.pc_rel = 1;
4525
bfd_signed_vma val = s3_inst.reloc.exp.X_add_number;
4527
/* Branch 32 offset field : 20 bit, 16 bit branch offset field : 8 bit. */
4528
s3_inst.instruction |= ((s3_inst.reloc.exp.X_add_number >> 1) & 0x1)
4529
| ((s3_inst.reloc.exp.X_add_number >> 2) & 0x7) << 7
4530
| ((s3_inst.reloc.exp.X_add_number >> 5) & 0x1f) << 20;
4532
/* Check and set offset. */
4533
if (((val & 0xfffffe00) != 0)
4534
&& ((val & 0xfffffe00) != 0xfffffe00))
4536
/* support bcmp --> cmp!+beq (bne) */
4537
if (s3_score_pic == s3_NO_PIC)
4539
sprintf (&append_str[0], "cmp! r%d, r%d", reg_a, reg_b);
4540
if (s3_append_insn (&append_str[0], TRUE) == (int) s3_FAIL)
4542
if ((inst_main.instruction & 0x3e00007e) == 0x0000004c)
4543
sprintf (&append_str[1], "beq %s", keep_data);
4545
sprintf (&append_str[1], "bne %s", keep_data);
4546
if (s3_append_insn (&append_str[1], TRUE) == (int) s3_FAIL)
4551
gas_assert (s3_inst.reloc.exp.X_add_symbol);
4553
/* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4560
s3_inst.instruction |= (val & 0x1)
4561
| (((val >> 1) & 0x7) << 7)
4562
| (((val >> 4) & 0x1f) << 20);
4565
/* Backup s3_inst. */
4566
memcpy (&inst_main, &s3_inst, sizeof (struct s3_score_it));
4568
if (s3_score_pic == s3_NO_PIC)
4570
sprintf (&append_str[0], "cmp! r%d, r%d", reg_a, reg_b);
4571
if (s3_append_insn (&append_str[0], FALSE) == (int) s3_FAIL)
4573
memcpy (&inst_expand[0], &s3_inst, sizeof (struct s3_score_it));
4575
if ((inst_main.instruction & 0x3e00007e) == 0x0000004c)
4576
sprintf (&append_str[1], "beq %s", keep_data);
4578
sprintf (&append_str[1], "bne %s", keep_data);
4579
if (s3_append_insn (&append_str[1], FALSE) == (int) s3_FAIL)
4581
memcpy (&inst_expand[1], &s3_inst, sizeof (struct s3_score_it));
4585
gas_assert (s3_inst.reloc.exp.X_add_symbol);
4587
inst_main.relax_size = inst_expand[0].size + inst_expand[1].size;
4588
inst_main.type = Insn_BCMP;
4590
/* Adjust instruction opcode and to be relaxed instruction opcode. */
4591
inst_main.instruction = s3_adjust_paritybit (inst_main.instruction, s3_GET_INSN_CLASS (inst_main.type));
4593
for (i = 0; i < 2; i++)
4594
inst_expand[i].instruction = s3_adjust_paritybit (inst_expand[i].instruction,
4595
s3_GET_INSN_CLASS (inst_expand[i].type));
4596
/* Check data dependency. */
4597
s3_handle_dependency (&inst_main);
4598
/* Start a new frag if frag_now is not empty. */
4599
if (frag_now_fix () != 0)
4601
if (!frag_now->tc_frag_data.is_insn)
4602
frag_wane (frag_now);
4607
/* Write fr_fix part. */
4609
p = frag_more (inst_main.size);
4610
s3_md_number_to_chars (p, inst_main.instruction, inst_main.size);
4612
if (inst_main.reloc.type != BFD_RELOC_NONE)
4614
s3_fix_new_score (frag_now, p - frag_now->fr_literal, inst_main.size,
4615
&inst_main.reloc.exp, inst_main.reloc.pc_rel, inst_main.reloc.type);
4618
dwarf2_emit_insn (inst_main.size);
4621
/* s3_GP instruction can not do optimization, only can do relax between
4622
1 instruction and 3 instructions. */
4623
p = frag_var (rs_machine_dependent, inst_main.relax_size + s3_RELAX_PAD_BYTE, 0,
4624
s3_RELAX_ENCODE (inst_main.size, inst_main.relax_size, inst_main.type, 0, 4, 1),
4625
inst_main.reloc.exp.X_add_symbol, 0, NULL);
4627
/* Write fr_var part.
4628
no calling s3_gen_insn_frag, no fixS will be generated. */
4629
s3_md_number_to_chars (p, inst_expand[0].instruction, inst_expand[0].size);
4630
p += inst_expand[0].size;
4631
s3_md_number_to_chars (p, inst_expand[1].instruction, inst_expand[1].size);
4632
p += inst_expand[1].size;
4634
/* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4639
/* Handle bcmpeqz / bcmpnez */
4641
s3_do_macro_bcmpz (char *str)
4644
char keep_data[s3_MAX_LITERAL_POOL_SIZE];
4647
struct s3_score_it inst_expand[2];
4648
struct s3_score_it inst_main;
4650
memset (inst_expand, 0, sizeof inst_expand);
4651
s3_skip_whitespace (str);
4652
if (( reg_a = s3_reg_required_here (&str, 15, s3_REG_TYPE_SCORE)) == (int) s3_FAIL
4653
|| s3_skip_past_comma (&str) == (int) s3_FAIL)
4658
keep_data[i] = *ptemp;
4665
if (s3_my_get_expression (&s3_inst.reloc.exp, &str) == (int) s3_FAIL
4666
|| s3_end_of_line (str) == (int) s3_FAIL)
4668
else if (s3_inst.reloc.exp.X_add_symbol == 0)
4670
s3_inst.error = _("lacking label ");
4675
char append_str[s3_MAX_LITERAL_POOL_SIZE];
4676
s3_SET_INSN_ERROR (NULL);
4677
s3_inst.reloc.type = BFD_RELOC_SCORE_BCMP;
4678
s3_inst.reloc.pc_rel = 1;
4679
bfd_signed_vma val = s3_inst.reloc.exp.X_add_number;
4681
/* Branch 32 offset field : 20 bit, 16 bit branch offset field : 8 bit. */
4682
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;
4684
/* Check and set offset. */
4685
if (((val & 0xfffffe00) != 0)
4686
&& ((val & 0xfffffe00) != 0xfffffe00))
4688
if (s3_score_pic == s3_NO_PIC)
4690
sprintf (&append_str[0], "cmpi! r%d,0", reg_a);
4691
if (s3_append_insn (&append_str[0], TRUE) == (int) s3_FAIL)
4693
if ((inst_main.instruction & 0x3e00007e) == 0x0000004c)
4694
sprintf (&append_str[1], "beq %s", keep_data);
4696
sprintf (&append_str[1], "bne %s", keep_data);
4697
if (s3_append_insn (&append_str[1], TRUE) == (int) s3_FAIL)
4702
gas_assert (s3_inst.reloc.exp.X_add_symbol);
4704
/* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4711
s3_inst.instruction |= (val & 0x1)
4712
| (((val >> 1) & 0x7) << 7)
4713
| (((val >> 4) & 0x1f) << 20);
4716
/* Backup s3_inst. */
4717
memcpy (&inst_main, &s3_inst, sizeof (struct s3_score_it));
4719
if (s3_score_pic == s3_NO_PIC)
4721
sprintf (&append_str[0], "cmpi! r%d, 0", reg_a);
4722
if (s3_append_insn (&append_str[0], FALSE) == (int) s3_FAIL)
4724
memcpy (&inst_expand[0], &s3_inst, sizeof (struct s3_score_it));
4725
if ((inst_main.instruction & 0x3e00007e) == 0x0000004c)
4726
sprintf (&append_str[1], "beq %s", keep_data);
4728
sprintf (&append_str[1], "bne %s", keep_data);
4729
if (s3_append_insn (&append_str[1], FALSE) == (int) s3_FAIL)
4731
memcpy (&inst_expand[1], &s3_inst, sizeof (struct s3_score_it));
4735
gas_assert (s3_inst.reloc.exp.X_add_symbol);
4737
inst_main.relax_size = inst_expand[0].size + inst_expand[1].size;
4738
inst_main.type = Insn_BCMP;
4740
/* Adjust instruction opcode and to be relaxed instruction opcode. */
4741
inst_main.instruction = s3_adjust_paritybit (inst_main.instruction, s3_GET_INSN_CLASS (inst_main.type));
4743
for (i = 0; i < 2; i++)
4744
inst_expand[i].instruction = s3_adjust_paritybit (inst_expand[i].instruction ,
4745
s3_GET_INSN_CLASS (inst_expand[i].type));
4746
/* Check data dependency. */
4747
s3_handle_dependency (&inst_main);
4748
/* Start a new frag if frag_now is not empty. */
4749
if (frag_now_fix () != 0)
4751
if (!frag_now->tc_frag_data.is_insn)
4752
frag_wane (frag_now);
4757
/* Write fr_fix part. */
4759
p = frag_more (inst_main.size);
4760
s3_md_number_to_chars (p, inst_main.instruction, inst_main.size);
4762
if (inst_main.reloc.type != BFD_RELOC_NONE)
4764
s3_fix_new_score (frag_now, p - frag_now->fr_literal, inst_main.size,
4765
&inst_main.reloc.exp, inst_main.reloc.pc_rel, inst_main.reloc.type);
4768
dwarf2_emit_insn (inst_main.size);
4771
/* s3_GP instruction can not do optimization, only can do relax between
4772
1 instruction and 3 instructions. */
4773
p = frag_var (rs_machine_dependent, inst_main.relax_size + s3_RELAX_PAD_BYTE, 0,
4774
s3_RELAX_ENCODE (inst_main.size, inst_main.relax_size, inst_main.type, 0, 4, 1),
4775
inst_main.reloc.exp.X_add_symbol, 0, NULL);
4777
/* Write fr_var part.
4778
no calling s3_gen_insn_frag, no fixS will be generated. */
4779
s3_md_number_to_chars (p, inst_expand[0].instruction, inst_expand[0].size);
4780
p += inst_expand[0].size;
4781
s3_md_number_to_chars (p, inst_expand[1].instruction, inst_expand[1].size);
4782
p += inst_expand[1].size;
4784
/* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4790
s3_nopic_need_relax (symbolS * sym, int before_relaxing)
4794
else if (s3_USE_GLOBAL_POINTER_OPT && s3_g_switch_value > 0)
4796
const char *symname;
4797
const char *segname;
4799
/* Find out whether this symbol can be referenced off the $gp
4800
register. It can be if it is smaller than the -G size or if
4801
it is in the .sdata or .sbss section. Certain symbols can
4802
not be referenced off the $gp, although it appears as though
4804
symname = S_GET_NAME (sym);
4805
if (symname != (const char *)NULL
4806
&& (strcmp (symname, "eprol") == 0
4807
|| strcmp (symname, "etext") == 0
4808
|| strcmp (symname, "_gp") == 0
4809
|| strcmp (symname, "edata") == 0
4810
|| strcmp (symname, "_fbss") == 0
4811
|| strcmp (symname, "_fdata") == 0
4812
|| strcmp (symname, "_ftext") == 0
4813
|| strcmp (symname, "end") == 0
4814
|| strcmp (symname, GP_DISP_LABEL) == 0))
4818
else if ((!S_IS_DEFINED (sym) || S_IS_COMMON (sym)) && (0
4819
/* We must defer this decision until after the whole file has been read,
4820
since there might be a .extern after the first use of this symbol. */
4822
&& S_GET_VALUE (sym) == 0)
4823
|| (S_GET_VALUE (sym) != 0
4824
&& S_GET_VALUE (sym) <= s3_g_switch_value)))
4829
segname = segment_name (S_GET_SEGMENT (sym));
4830
return (strcmp (segname, ".sdata") != 0
4831
&& strcmp (segname, ".sbss") != 0
4832
&& strncmp (segname, ".sdata.", 7) != 0
4833
&& strncmp (segname, ".gnu.linkonce.s.", 16) != 0);
4835
/* We are not optimizing for the $gp register. */
4840
/* Build a relax frag for lw/st instruction when generating s3_PIC,
4841
external symbol first and local symbol second. */
4843
s3_build_lwst_pic (int reg_rd, expressionS exp, const char *insn_name)
4845
symbolS *add_symbol = exp.X_add_symbol;
4846
int add_number = exp.X_add_number;
4847
struct s3_score_it fix_insts[s3_RELAX_INST_NUM];
4848
struct s3_score_it var_insts[s3_RELAX_INST_NUM];
4851
char tmp[s3_MAX_LITERAL_POOL_SIZE];
4857
if ((add_number == 0) || (add_number >= -0x8000 && add_number <= 0x7fff))
4862
/* For an external symbol, two insns are generated;
4863
For a local symbol, three insns are generated. */
4865
For an external symbol: lw rD, <sym>($gp)
4866
(BFD_RELOC_SCORE_GOT15) */
4867
sprintf (tmp, "lw_pic r1, %s", add_symbol->bsym->name);
4868
if (s3_append_insn (tmp, FALSE) == (int) s3_FAIL)
4871
memcpy (&fix_insts[0], &s3_inst, sizeof (struct s3_score_it));
4874
For a local symbol :
4875
lw rD, <sym>($gp) (BFD_RELOC_SCORE_GOT15)
4876
addi rD, <sym> (BFD_RELOC_GOT_LO16) */
4877
s3_inst.reloc.type = BFD_RELOC_SCORE_GOT15;
4878
memcpy (&var_insts[0], &s3_inst, sizeof (struct s3_score_it));
4879
sprintf (tmp, "addi_s_pic r1, %s", add_symbol->bsym->name);
4880
if (s3_append_insn (tmp, FALSE) == (int) s3_FAIL)
4883
memcpy (&var_insts[1], &s3_inst, sizeof (struct s3_score_it));
4884
s3_build_relax_frag (fix_insts, fix_num, var_insts, var_num, add_symbol);
4886
/* Insn 2 or Insn 3: lw/st rD, [r1, constant] */
4887
sprintf (tmp, "%s r%d, [r1, %d]", insn_name, reg_rd, add_number);
4888
if (s3_append_insn (tmp, TRUE) == (int) s3_FAIL)
4891
/* Set bwarn as -1, so macro instruction itself will not be generated frag. */
4896
s3_inst.error = _("s3_PIC code offset overflow (max 16 signed bits)");
4904
s3_do_macro_ldst_label (char *str)
4912
char *absolute_value;
4913
char append_str[3][s3_MAX_LITERAL_POOL_SIZE];
4914
char verifystr[s3_MAX_LITERAL_POOL_SIZE];
4915
struct s3_score_it inst_backup;
4916
struct s3_score_it inst_expand[3];
4917
struct s3_score_it inst_main;
4919
memcpy (&inst_backup, &s3_inst, sizeof (struct s3_score_it));
4920
strcpy (verifystr, str);
4921
backup_str = verifystr;
4923
s3_skip_whitespace (backup_str);
4924
if ((reg_rd = s3_reg_required_here (&backup_str, -1, s3_REG_TYPE_SCORE)) == (int) s3_FAIL)
4927
if (s3_skip_past_comma (&backup_str) == (int) s3_FAIL)
4930
label_str = backup_str;
4932
/* Ld/st rD, [rA, imm] ld/st rD, [rA]+, imm ld/st rD, [rA, imm]+. */
4933
if (*backup_str == '[')
4935
s3_inst.type = Rd_rvalueRs_preSI12;
4936
s3_do_ldst_insn (str);
4940
/* Ld/st rD, imm. */
4941
absolute_value = backup_str;
4942
s3_inst.type = Rd_rvalueRs_SI15;
4944
if (s3_my_get_expression (&s3_inst.reloc.exp, &backup_str) == (int) s3_FAIL)
4946
s3_inst.error = _("expression error");
4949
else if ((s3_inst.reloc.exp.X_add_symbol == NULL)
4950
&& (s3_validate_immediate (s3_inst.reloc.exp.X_add_number, _VALUE, 0) == (int) s3_FAIL))
4952
s3_inst.error = _("value not in range [0, 0x7fffffff]");
4955
else if (s3_end_of_line (backup_str) == (int) s3_FAIL)
4957
s3_inst.error = _("end on line error");
4962
if (s3_inst.reloc.exp.X_add_symbol == 0)
4964
memcpy (&s3_inst, &inst_backup, sizeof (struct s3_score_it));
4965
s3_exp_macro_ldst_abs (str);
4970
/* Ld/st rD, label. */
4971
s3_inst.type = Rd_rvalueRs_SI15;
4972
backup_str = absolute_value;
4973
if ((s3_data_op2 (&backup_str, 1, _GP_IMM15) == (int) s3_FAIL)
4974
|| (s3_end_of_line (backup_str) == (int) s3_FAIL))
4980
if (s3_inst.reloc.exp.X_add_symbol == 0)
4983
s3_inst.error = s3_BAD_ARGS;
4988
if (s3_score_pic == s3_PIC)
4991
ldst_idx = s3_inst.instruction & OPC_PSEUDOLDST_MASK;
4992
s3_build_lwst_pic (reg_rd, s3_inst.reloc.exp,
4993
s3_score_ldst_insns[ldst_idx * 3 + 0].template_name);
4998
if ((s3_inst.reloc.exp.X_add_number <= 0x3fff)
4999
&& (s3_inst.reloc.exp.X_add_number >= -0x4000)
5000
&& (!s3_nopic_need_relax (s3_inst.reloc.exp.X_add_symbol, 1)))
5004
/* Assign the real opcode. */
5005
ldst_idx = s3_inst.instruction & OPC_PSEUDOLDST_MASK;
5006
s3_inst.instruction &= ~OPC_PSEUDOLDST_MASK;
5007
s3_inst.instruction |= s3_score_ldst_insns[ldst_idx * 3 + 0].value;
5008
s3_inst.instruction |= reg_rd << 20;
5009
s3_inst.instruction |= s3_GP << 15;
5010
s3_inst.relax_inst = 0x8000;
5011
s3_inst.relax_size = 0;
5017
/* Backup s3_inst. */
5018
memcpy (&inst_main, &s3_inst, sizeof (struct s3_score_it));
5022
/* Determine which instructions should be output. */
5023
sprintf (append_str[0], "ld_i32hi r1, %s", label_str);
5024
sprintf (append_str[1], "ld_i32lo r1, %s", label_str);
5025
sprintf (append_str[2], "%s r%d, [r1, 0]", inst_backup.name, reg_rd);
5027
/* Generate three instructions.
5029
ld/st rd, [r1, 0] */
5030
for (i = 0; i < 3; i++)
5032
if (s3_append_insn (append_str[i], FALSE) == (int) s3_FAIL)
5035
memcpy (&inst_expand[i], &s3_inst, sizeof (struct s3_score_it));
5042
/* Adjust instruction opcode and to be relaxed instruction opcode. */
5043
inst_main.instruction = s3_adjust_paritybit (inst_main.instruction, s3_GET_INSN_CLASS (inst_main.type));
5045
/* relax lw rd, label -> ldis rs, imm16
5047
lw rd, [rs, imm15] or lw! rd, [rs, imm5]. */
5048
if (inst_expand[2].relax_size == 0)
5049
inst_main.relax_size = inst_expand[0].size + inst_expand[1].size + inst_expand[2].size;
5051
inst_main.relax_size = inst_expand[0].size + inst_expand[1].size + inst_expand[2].relax_size;
5053
inst_main.type = Insn_GP;
5055
for (i = 0; i < 3; i++)
5056
inst_expand[i].instruction = s3_adjust_paritybit (inst_expand[i].instruction,
5057
s3_GET_INSN_CLASS (inst_expand[i].type));
5059
/* Check data dependency. */
5060
s3_handle_dependency (&inst_main);
5062
/* Start a new frag if frag_now is not empty. */
5063
if (frag_now_fix () != 0)
5065
if (!frag_now->tc_frag_data.is_insn)
5066
frag_wane (frag_now);
5072
/* Write fr_fix part. */
5073
p = frag_more (inst_main.size);
5074
s3_md_number_to_chars (p, inst_main.instruction, inst_main.size);
5076
if (inst_main.reloc.type != BFD_RELOC_NONE)
5078
s3_fix_new_score (frag_now, p - frag_now->fr_literal, inst_main.size,
5079
&inst_main.reloc.exp, inst_main.reloc.pc_rel, inst_main.reloc.type);
5083
dwarf2_emit_insn (inst_main.size);
5086
/* s3_GP instruction can not do optimization, only can do relax between
5087
1 instruction and 3 instructions. */
5088
p = frag_var (rs_machine_dependent, inst_main.relax_size + s3_RELAX_PAD_BYTE, 0,
5089
s3_RELAX_ENCODE (inst_main.size, inst_main.relax_size, inst_main.type, 0, 4, 0),
5090
inst_main.reloc.exp.X_add_symbol, 0, NULL);
5092
/* Write fr_var part.
5093
no calling s3_gen_insn_frag, no fixS will be generated. */
5094
s3_md_number_to_chars (p, inst_expand[0].instruction, inst_expand[0].size);
5095
p += inst_expand[0].size;
5096
s3_md_number_to_chars (p, inst_expand[1].instruction, inst_expand[1].size);
5097
p += inst_expand[1].size;
5099
/* relax lw rd, label -> ldis rs, imm16
5101
lw rd, [rs, imm15] or lw! rd, [rs, imm5]. */
5102
if (inst_expand[2].relax_size == 0)
5103
s3_md_number_to_chars (p, inst_expand[2].instruction, inst_expand[2].size);
5105
s3_md_number_to_chars (p, inst_expand[2].relax_inst, inst_expand[2].relax_size);
5109
s3_gen_insn_frag (&inst_expand[0], NULL);
5110
s3_gen_insn_frag (&inst_expand[1], NULL);
5111
s3_gen_insn_frag (&inst_expand[2], NULL);
5115
/* Set bwarn as -1, so macro instruction itself will not be generated frag. */
5120
s3_do_lw_pic (char *str)
5124
s3_skip_whitespace (str);
5125
if (((reg_rd = s3_reg_required_here (&str, 20, s3_REG_TYPE_SCORE)) == (int) s3_FAIL)
5126
|| (s3_skip_past_comma (&str) == (int) s3_FAIL)
5127
|| (s3_my_get_expression (&s3_inst.reloc.exp, &str) == (int) s3_FAIL)
5128
|| (s3_end_of_line (str) == (int) s3_FAIL))
5134
if (s3_inst.reloc.exp.X_add_symbol == 0)
5137
s3_inst.error = s3_BAD_ARGS;
5142
s3_inst.instruction |= s3_GP << 15;
5143
s3_inst.reloc.type = BFD_RELOC_SCORE_GOT15;
5148
s3_do_empty (char *str)
5151
if (s3_university_version == 1)
5153
if (((s3_inst.instruction & 0x3e0003ff) == 0x0c000004)
5154
|| ((s3_inst.instruction & 0x3e0003ff) == 0x0c000024)
5155
|| ((s3_inst.instruction & 0x3e0003ff) == 0x0c000044)
5156
|| ((s3_inst.instruction & 0x3e0003ff) == 0x0c000064))
5158
s3_inst.error = s3_ERR_FOR_SCORE5U_MMU;
5162
if (s3_end_of_line (str) == (int) s3_FAIL)
5165
if (s3_inst.relax_inst != 0x8000)
5167
if (s3_inst.type == NO_OPD)
5169
s3_inst.relax_size = 2;
5173
s3_inst.relax_size = 4;
5179
s3_do16_int (char *str)
5181
s3_skip_whitespace (str);
5186
s3_do_jump (char *str)
5190
s3_skip_whitespace (str);
5191
if (s3_my_get_expression (&s3_inst.reloc.exp, &str) == (int) s3_FAIL
5192
|| s3_end_of_line (str) == (int) s3_FAIL)
5195
if (s3_inst.reloc.exp.X_add_symbol == 0)
5197
s3_inst.error = _("lacking label ");
5201
if (!(s3_inst.reloc.exp.X_add_number >= -16777216
5202
&& s3_inst.reloc.exp.X_add_number <= 16777215))
5204
s3_inst.error = _("invalid constant: 25 bit expression not in range [-16777216, 16777215]");
5208
save_in = input_line_pointer;
5209
input_line_pointer = str;
5210
s3_inst.reloc.type = BFD_RELOC_SCORE_JMP;
5211
s3_inst.reloc.pc_rel = 1;
5212
input_line_pointer = save_in;
5216
s3_do_branch (char *str)
5218
if (s3_my_get_expression (&s3_inst.reloc.exp, &str) == (int) s3_FAIL
5219
|| s3_end_of_line (str) == (int) s3_FAIL)
5223
else if (s3_inst.reloc.exp.X_add_symbol == 0)
5225
s3_inst.error = _("lacking label ");
5228
else if (!(s3_inst.reloc.exp.X_add_number >= -524288
5229
&& s3_inst.reloc.exp.X_add_number <= 524287))
5231
s3_inst.error = _("invalid constant: 20 bit expression not in range -2^19..2^19");
5235
s3_inst.reloc.type = BFD_RELOC_SCORE_BRANCH;
5236
s3_inst.reloc.pc_rel = 1;
5238
/* Branch 32 offset field : 20 bit, 16 bit branch offset field : 8 bit. */
5239
s3_inst.instruction |= (s3_inst.reloc.exp.X_add_number & 0x3fe) | ((s3_inst.reloc.exp.X_add_number & 0xffc00) << 5);
5241
/* Compute 16 bit branch instruction. */
5242
if ((s3_inst.relax_inst != 0x8000)
5243
&& (s3_inst.reloc.exp.X_add_number >= -512 && s3_inst.reloc.exp.X_add_number <= 511))
5245
s3_inst.relax_inst |= ((s3_inst.reloc.exp.X_add_number >> 1) & 0x1ff);/*b! :disp 9 bit */
5246
s3_inst.relax_size = 2;
5250
s3_inst.relax_inst = 0x8000;
5255
s3_do16_branch (char *str)
5257
if ((s3_my_get_expression (&s3_inst.reloc.exp, &str) == (int) s3_FAIL
5258
|| s3_end_of_line (str) == (int) s3_FAIL))
5262
else if (s3_inst.reloc.exp.X_add_symbol == 0)
5264
s3_inst.error = _("lacking label");
5266
else if (!(s3_inst.reloc.exp.X_add_number >= -512
5267
&& s3_inst.reloc.exp.X_add_number <= 511))
5269
s3_inst.error = _("invalid constant: 10 bit expression not in range [-2^9, 2^9-1]");
5273
s3_inst.reloc.type = BFD_RELOC_SCORE16_BRANCH;
5274
s3_inst.reloc.pc_rel = 1;
5275
s3_inst.instruction |= ((s3_inst.reloc.exp.X_add_number >> 1) & 0x1ff);
5276
s3_inst.relax_inst |= ((s3_inst.reloc.exp.X_add_number ) & 0x1ff);
5277
s3_inst.relax_size = 4;
5281
/* Return true if the given symbol should be considered local for s3_PIC. */
5283
s3_pic_need_relax (symbolS *sym, asection *segtype)
5286
bfd_boolean linkonce;
5288
/* Handle the case of a symbol equated to another symbol. */
5289
while (symbol_equated_reloc_p (sym))
5293
/* It's possible to get a loop here in a badly written
5295
n = symbol_get_value_expression (sym)->X_add_symbol;
5301
symsec = S_GET_SEGMENT (sym);
5303
/* duplicate the test for LINK_ONCE sections as in adjust_reloc_syms */
5305
if (symsec != segtype && ! S_IS_LOCAL (sym))
5307
if ((bfd_get_section_flags (stdoutput, symsec) & SEC_LINK_ONCE) != 0)
5310
/* The GNU toolchain uses an extension for ELF: a section
5311
beginning with the magic string .gnu.linkonce is a linkonce
5313
if (strncmp (segment_name (symsec), ".gnu.linkonce",
5314
sizeof ".gnu.linkonce" - 1) == 0)
5318
/* This must duplicate the test in adjust_reloc_syms. */
5319
return (!bfd_is_und_section (symsec)
5320
&& !bfd_is_abs_section (symsec)
5321
&& !bfd_is_com_section (symsec)
5324
/* A global or weak symbol is treated as external. */
5325
&& (OUTPUT_FLAVOR != bfd_target_elf_flavour
5326
|| (! S_IS_WEAK (sym) && ! S_IS_EXTERNAL (sym)))
5332
s3_parse_pce_inst (char *insnstr)
5336
char first[s3_MAX_LITERAL_POOL_SIZE];
5337
char second[s3_MAX_LITERAL_POOL_SIZE];
5338
struct s3_score_it pec_part_1;
5340
/* Get first part string of PCE. */
5341
p = strstr (insnstr, "||");
5344
sprintf (first, "%s", insnstr);
5346
/* Get second part string of PCE. */
5349
sprintf (second, "%s", p);
5351
s3_parse_16_32_inst (first, FALSE);
5355
memcpy (&pec_part_1, &s3_inst, sizeof (s3_inst));
5357
s3_parse_16_32_inst (second, FALSE);
5361
if ( ((pec_part_1.size == s3_INSN_SIZE) && (s3_inst.size == s3_INSN_SIZE))
5362
|| ((pec_part_1.size == s3_INSN_SIZE) && (s3_inst.size == s3_INSN16_SIZE))
5363
|| ((pec_part_1.size == s3_INSN16_SIZE) && (s3_inst.size == s3_INSN_SIZE)))
5365
s3_inst.error = _("pce instruction error (16 bit || 16 bit)'");
5366
sprintf (s3_inst.str, insnstr);
5371
s3_gen_insn_frag (&pec_part_1, &s3_inst);
5376
s3_do16_dsp (char *str)
5381
if (s3_score3d == 0)
5383
s3_inst.error = _("score3d instruction.");
5387
s3_skip_whitespace (str);
5389
if ((rd = s3_reglow_required_here (&str, 0)) == (int) s3_FAIL
5390
|| s3_end_of_line (str) == (int) s3_FAIL)
5396
s3_inst.relax_inst |= rd << 20;
5397
s3_inst.relax_size = 4;
5402
s3_do16_dsp2 (char *str)
5405
if (s3_score3d == 0)
5407
s3_inst.error = _("score3d instruction.");
5411
s3_skip_whitespace (str);
5413
if (s3_reglow_required_here (&str, 4) == (int) s3_FAIL
5414
|| s3_skip_past_comma (&str) == (int) s3_FAIL
5415
|| s3_reglow_required_here (&str, 0) == (int) s3_FAIL
5416
|| s3_end_of_line (str) == (int) s3_FAIL)
5422
s3_inst.relax_inst |= (((s3_inst.instruction >> 8) & 0xf) << 20)
5423
| (((s3_inst.instruction >> 8) & 0xf) << 15) | (((s3_inst.instruction >> 4) & 0xf) << 10);
5424
s3_inst.relax_size = 4;
5429
s3_do_dsp (char *str)
5432
if (s3_score3d == 0)
5434
s3_inst.error = _("score3d instruction.");
5438
s3_skip_whitespace (str);
5440
if (s3_reg_required_here (&str, 15, s3_REG_TYPE_SCORE) == (int) s3_FAIL
5441
|| s3_skip_past_comma (&str) == (int) s3_FAIL
5442
|| s3_reg_required_here (&str, 10, s3_REG_TYPE_SCORE) == (int) s3_FAIL
5443
|| s3_end_of_line (str) == (int) s3_FAIL)
5446
if ((s3_inst.relax_inst != 0x8000) && (((s3_inst.instruction >> 20) & 0x1f) == 3) )
5448
s3_inst.relax_inst |= (((s3_inst.instruction >> 10) & 0x1f)) | (((s3_inst.instruction >> 15) & 0x1f) << 5);
5449
s3_inst.relax_size = 2;
5452
s3_inst.relax_inst = 0x8000;
5456
s3_do_dsp2 (char *str)
5461
if (s3_score3d == 0)
5463
s3_inst.error = _("score3d instruction.");
5467
s3_skip_whitespace (str);
5469
if ((reg = s3_reg_required_here (&str, 20, s3_REG_TYPE_SCORE)) == (int) s3_FAIL
5470
|| s3_skip_past_comma (&str) == (int) s3_FAIL
5471
|| s3_reg_required_here (&str, 15, s3_REG_TYPE_SCORE) == (int) s3_FAIL
5472
|| s3_skip_past_comma (&str) == (int) s3_FAIL
5473
|| s3_reg_required_here (&str, 10, s3_REG_TYPE_SCORE) == (int) s3_FAIL
5474
|| s3_end_of_line (str) == (int) s3_FAIL)
5480
/* Check mulr, mulur rd is even number. */
5481
if (((s3_inst.instruction & 0x3e0003ff) == 0x00000340
5482
|| (s3_inst.instruction & 0x3e0003ff) == 0x00000342)
5485
s3_inst.error = _("rd must be even number.");
5489
if ((((s3_inst.instruction >> 15) & 0x10) == 0)
5490
&& (((s3_inst.instruction >> 10) & 0x10) == 0)
5491
&& (((s3_inst.instruction >> 20) & 0x10) == 0)
5492
&& (s3_inst.relax_inst != 0x8000)
5493
&& (((s3_inst.instruction >> 20) & 0xf) == ((s3_inst.instruction >> 15) & 0xf)))
5495
s3_inst.relax_inst |= (((s3_inst.instruction >> 10) & 0xf) )
5496
| (((s3_inst.instruction >> 15) & 0xf) << 4);
5497
s3_inst.relax_size = 2;
5501
s3_inst.relax_inst = 0x8000;
5507
s3_do_dsp3 (char *str)
5510
if (s3_score3d == 0)
5512
s3_inst.error = _("score3d instruction.");
5516
s3_skip_whitespace (str);
5518
if (s3_reg_required_here (&str, 20, s3_REG_TYPE_SCORE) == (int) s3_FAIL
5519
|| s3_skip_past_comma (&str) == (int) s3_FAIL
5520
|| s3_reg_required_here (&str, 15, s3_REG_TYPE_SCORE) == (int) s3_FAIL
5521
|| s3_end_of_line (str) == (int) s3_FAIL)
5524
if ((s3_inst.relax_inst != 0x8000) && (((s3_inst.instruction >> 20) & 0x1f) == 3) )
5526
s3_inst.relax_inst |= (((s3_inst.instruction >> 10) & 0x1f)) | (((s3_inst.instruction >> 15) & 0x1f) << 5);
5527
s3_inst.relax_size = 2;
5530
s3_inst.relax_inst = 0x8000;
5534
/* If we change section we must dump the literal pool first. */
5536
s3_s_score_bss (int ignore ATTRIBUTE_UNUSED)
5538
subseg_set (bss_section, (subsegT) get_absolute_expression ());
5539
demand_empty_rest_of_line ();
5543
s3_s_score_text (int ignore)
5545
obj_elf_text (ignore);
5546
record_alignment (now_seg, 2);
5550
s3_score_s_section (int ignore)
5552
obj_elf_section (ignore);
5553
if ((bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) != 0)
5554
record_alignment (now_seg, 2);
5559
s3_s_change_sec (int sec)
5564
/* The ELF backend needs to know that we are changing sections, so
5565
that .previous works correctly. We could do something like check
5566
for an obj_section_change_hook macro, but that might be confusing
5567
as it would not be appropriate to use it in the section changing
5568
functions in read.c, since obj-elf.c intercepts those. FIXME:
5569
This should be cleaner, somehow. */
5570
obj_elf_section_change_hook ();
5575
seg = subseg_new (s3_RDATA_SECTION_NAME, (subsegT) get_absolute_expression ());
5576
bfd_set_section_flags (stdoutput, seg, (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_RELOC | SEC_DATA));
5577
if (strcmp (TARGET_OS, "elf") != 0)
5578
record_alignment (seg, 4);
5579
demand_empty_rest_of_line ();
5582
seg = subseg_new (".sdata", (subsegT) get_absolute_expression ());
5583
bfd_set_section_flags (stdoutput, seg, SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA);
5584
if (strcmp (TARGET_OS, "elf") != 0)
5585
record_alignment (seg, 4);
5586
demand_empty_rest_of_line ();
5592
s3_s_score_mask (int reg_type ATTRIBUTE_UNUSED)
5596
if (s3_cur_proc_ptr == (s3_procS *) NULL)
5598
as_warn (_(".mask outside of .ent"));
5599
demand_empty_rest_of_line ();
5602
if (get_absolute_expression_and_terminator (&mask) != ',')
5604
as_warn (_("Bad .mask directive"));
5605
--input_line_pointer;
5606
demand_empty_rest_of_line ();
5609
off = get_absolute_expression ();
5610
s3_cur_proc_ptr->reg_mask = mask;
5611
s3_cur_proc_ptr->reg_offset = off;
5612
demand_empty_rest_of_line ();
5616
s3_get_symbol (void)
5622
name = input_line_pointer;
5623
c = get_symbol_end ();
5624
p = (symbolS *) symbol_find_or_make (name);
5625
*input_line_pointer = c;
5630
s3_get_number (void)
5635
if (*input_line_pointer == '-')
5637
++input_line_pointer;
5640
if (!ISDIGIT (*input_line_pointer))
5641
as_bad (_("expected simple number"));
5642
if (input_line_pointer[0] == '0')
5644
if (input_line_pointer[1] == 'x')
5646
input_line_pointer += 2;
5647
while (ISXDIGIT (*input_line_pointer))
5650
val |= hex_value (*input_line_pointer++);
5652
return negative ? -val : val;
5656
++input_line_pointer;
5657
while (ISDIGIT (*input_line_pointer))
5660
val |= *input_line_pointer++ - '0';
5662
return negative ? -val : val;
5665
if (!ISDIGIT (*input_line_pointer))
5667
printf (_(" *input_line_pointer == '%c' 0x%02x\n"), *input_line_pointer, *input_line_pointer);
5668
as_warn (_("invalid number"));
5671
while (ISDIGIT (*input_line_pointer))
5674
val += *input_line_pointer++ - '0';
5676
return negative ? -val : val;
5679
/* The .aent and .ent directives. */
5681
s3_s_score_ent (int aent)
5686
symbolP = s3_get_symbol ();
5687
if (*input_line_pointer == ',')
5688
++input_line_pointer;
5690
if (ISDIGIT (*input_line_pointer) || *input_line_pointer == '-')
5693
#ifdef BFD_ASSEMBLER
5694
if ((bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) != 0)
5699
if (now_seg != data_section && now_seg != bss_section)
5705
as_warn (_(".ent or .aent not in text section."));
5706
if (!aent && s3_cur_proc_ptr)
5707
as_warn (_("missing .end"));
5710
s3_cur_proc_ptr = &s3_cur_proc;
5711
s3_cur_proc_ptr->reg_mask = 0xdeadbeaf;
5712
s3_cur_proc_ptr->reg_offset = 0xdeadbeaf;
5713
s3_cur_proc_ptr->fpreg_mask = 0xdeafbeaf;
5714
s3_cur_proc_ptr->leaf = 0xdeafbeaf;
5715
s3_cur_proc_ptr->frame_offset = 0xdeafbeaf;
5716
s3_cur_proc_ptr->frame_reg = 0xdeafbeaf;
5717
s3_cur_proc_ptr->pc_reg = 0xdeafbeaf;
5718
s3_cur_proc_ptr->isym = symbolP;
5719
symbol_get_bfdsym (symbolP)->flags |= BSF_FUNCTION;
5721
if (debug_type == DEBUG_STABS)
5722
stabs_generate_asm_func (S_GET_NAME (symbolP), S_GET_NAME (symbolP));
5724
demand_empty_rest_of_line ();
5728
s3_s_score_frame (int ignore ATTRIBUTE_UNUSED)
5735
backupstr = input_line_pointer;
5738
if (s3_cur_proc_ptr == (s3_procS *) NULL)
5740
as_warn (_(".frame outside of .ent"));
5741
demand_empty_rest_of_line ();
5744
s3_cur_proc_ptr->frame_reg = s3_reg_required_here ((&backupstr), 0, s3_REG_TYPE_SCORE);
5746
s3_skip_past_comma (&backupstr);
5747
while (*backupstr != ',')
5749
str[i] = *backupstr;
5757
s3_skip_past_comma (&backupstr);
5758
s3_cur_proc_ptr->frame_offset = val;
5759
s3_cur_proc_ptr->pc_reg = s3_reg_required_here ((&backupstr), 0, s3_REG_TYPE_SCORE);
5762
s3_skip_past_comma (&backupstr);
5764
while (*backupstr != '\n')
5766
str[i] = *backupstr;
5772
s3_cur_proc_ptr->leaf = val;
5774
s3_skip_past_comma (&backupstr);
5776
#endif /* OBJ_ELF */
5777
while (input_line_pointer != backupstr)
5778
input_line_pointer++;
5781
/* The .end directive. */
5783
s3_s_score_end (int x ATTRIBUTE_UNUSED)
5788
/* Generate a .pdr section. */
5789
segT saved_seg = now_seg;
5790
subsegT saved_subseg = now_subseg;
5794
if (!is_end_of_line[(unsigned char)*input_line_pointer])
5796
p = s3_get_symbol ();
5797
demand_empty_rest_of_line ();
5802
#ifdef BFD_ASSEMBLER
5803
if ((bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) != 0)
5808
if (now_seg != data_section && now_seg != bss_section)
5815
as_warn (_(".end not in text section"));
5816
if (!s3_cur_proc_ptr)
5818
as_warn (_(".end directive without a preceding .ent directive."));
5819
demand_empty_rest_of_line ();
5824
gas_assert (S_GET_NAME (p));
5825
if (strcmp (S_GET_NAME (p), S_GET_NAME (s3_cur_proc_ptr->isym)))
5826
as_warn (_(".end symbol does not match .ent symbol."));
5827
if (debug_type == DEBUG_STABS)
5828
stabs_generate_asm_endfunc (S_GET_NAME (p), S_GET_NAME (p));
5831
as_warn (_(".end directive missing or unknown symbol"));
5833
if ((s3_cur_proc_ptr->reg_mask == 0xdeadbeaf) ||
5834
(s3_cur_proc_ptr->reg_offset == 0xdeadbeaf) ||
5835
(s3_cur_proc_ptr->leaf == 0xdeafbeaf) ||
5836
(s3_cur_proc_ptr->frame_offset == 0xdeafbeaf) ||
5837
(s3_cur_proc_ptr->frame_reg == 0xdeafbeaf) || (s3_cur_proc_ptr->pc_reg == 0xdeafbeaf));
5841
(void) frag_now_fix ();
5842
gas_assert (s3_pdr_seg);
5843
subseg_set (s3_pdr_seg, 0);
5844
/* Write the symbol. */
5845
exp.X_op = O_symbol;
5846
exp.X_add_symbol = p;
5847
exp.X_add_number = 0;
5848
emit_expr (&exp, 4);
5849
fragp = frag_more (7 * 4);
5850
md_number_to_chars (fragp, (valueT) s3_cur_proc_ptr->reg_mask, 4);
5851
md_number_to_chars (fragp + 4, (valueT) s3_cur_proc_ptr->reg_offset, 4);
5852
md_number_to_chars (fragp + 8, (valueT) s3_cur_proc_ptr->fpreg_mask, 4);
5853
md_number_to_chars (fragp + 12, (valueT) s3_cur_proc_ptr->leaf, 4);
5854
md_number_to_chars (fragp + 16, (valueT) s3_cur_proc_ptr->frame_offset, 4);
5855
md_number_to_chars (fragp + 20, (valueT) s3_cur_proc_ptr->frame_reg, 4);
5856
md_number_to_chars (fragp + 24, (valueT) s3_cur_proc_ptr->pc_reg, 4);
5857
subseg_set (saved_seg, saved_subseg);
5860
s3_cur_proc_ptr = NULL;
5863
/* Handle the .set pseudo-op. */
5865
s3_s_score_set (int x ATTRIBUTE_UNUSED)
5868
char name[s3_MAX_LITERAL_POOL_SIZE];
5869
char * orig_ilp = input_line_pointer;
5871
while (!is_end_of_line[(unsigned char)*input_line_pointer])
5873
name[i] = (char) * input_line_pointer;
5875
++input_line_pointer;
5880
if (strcmp (name, "nwarn") == 0)
5882
s3_warn_fix_data_dependency = 0;
5884
else if (strcmp (name, "fixdd") == 0)
5886
s3_fix_data_dependency = 1;
5888
else if (strcmp (name, "nofixdd") == 0)
5890
s3_fix_data_dependency = 0;
5892
else if (strcmp (name, "r1") == 0)
5896
else if (strcmp (name, "nor1") == 0)
5900
else if (strcmp (name, "optimize") == 0)
5904
else if (strcmp (name, "volatile") == 0)
5908
else if (strcmp (name, "pic") == 0)
5910
s3_score_pic = s3_PIC;
5914
input_line_pointer = orig_ilp;
5919
/* Handle the .cpload pseudo-op. This is used when generating s3_PIC code. It sets the
5920
$gp register for the function based on the function address, which is in the register
5921
named in the argument. This uses a relocation against GP_DISP_LABEL, which is handled
5922
specially by the linker. The result is:
5923
ldis gp, %hi(GP_DISP_LABEL)
5924
ori gp, %low(GP_DISP_LABEL)
5925
add gp, gp, .cpload argument
5926
The .cpload argument is normally r29. */
5928
s3_s_score_cpload (int ignore ATTRIBUTE_UNUSED)
5931
char insn_str[s3_MAX_LITERAL_POOL_SIZE];
5933
/* If we are not generating s3_PIC code, .cpload is ignored. */
5934
if (s3_score_pic == s3_NO_PIC)
5940
if ((reg = s3_reg_required_here (&input_line_pointer, -1, s3_REG_TYPE_SCORE)) == (int) s3_FAIL)
5943
demand_empty_rest_of_line ();
5945
sprintf (insn_str, "ld_i32hi r%d, %s", s3_GP, GP_DISP_LABEL);
5946
if (s3_append_insn (insn_str, TRUE) == (int) s3_FAIL)
5949
sprintf (insn_str, "ld_i32lo r%d, %s", s3_GP, GP_DISP_LABEL);
5950
if (s3_append_insn (insn_str, TRUE) == (int) s3_FAIL)
5953
sprintf (insn_str, "add r%d, r%d, r%d", s3_GP, s3_GP, reg);
5954
if (s3_append_insn (insn_str, TRUE) == (int) s3_FAIL)
5958
/* Handle the .cprestore pseudo-op. This stores $gp into a given
5959
offset from $sp. The offset is remembered, and after making a s3_PIC
5960
call $gp is restored from that location. */
5962
s3_s_score_cprestore (int ignore ATTRIBUTE_UNUSED)
5965
int cprestore_offset;
5966
char insn_str[s3_MAX_LITERAL_POOL_SIZE];
5968
/* If we are not generating s3_PIC code, .cprestore is ignored. */
5969
if (s3_score_pic == s3_NO_PIC)
5975
if ((reg = s3_reg_required_here (&input_line_pointer, -1, s3_REG_TYPE_SCORE)) == (int) s3_FAIL
5976
|| s3_skip_past_comma (&input_line_pointer) == (int) s3_FAIL)
5981
cprestore_offset = get_absolute_expression ();
5983
if (cprestore_offset <= 0x3fff)
5985
sprintf (insn_str, "sw r%d, [r%d, %d]", s3_GP, reg, cprestore_offset);
5986
if (s3_append_insn (insn_str, TRUE) == (int) s3_FAIL)
5996
sprintf (insn_str, "li r1, %d", cprestore_offset);
5997
if (s3_append_insn (insn_str, TRUE) == (int) s3_FAIL)
6000
sprintf (insn_str, "add r1, r1, r%d", reg);
6001
if (s3_append_insn (insn_str, TRUE) == (int) s3_FAIL)
6004
sprintf (insn_str, "sw r%d, [r1]", s3_GP);
6005
if (s3_append_insn (insn_str, TRUE) == (int) s3_FAIL)
6011
demand_empty_rest_of_line ();
6014
/* Handle the .gpword pseudo-op. This is used when generating s3_PIC
6015
code. It generates a 32 bit s3_GP relative reloc. */
6017
s3_s_score_gpword (int ignore ATTRIBUTE_UNUSED)
6022
/* When not generating s3_PIC code, this is treated as .word. */
6023
if (s3_score_pic == s3_NO_PIC)
6029
if (ex.X_op != O_symbol || ex.X_add_number != 0)
6031
as_bad (_("Unsupported use of .gpword"));
6032
ignore_rest_of_line ();
6035
s3_md_number_to_chars (p, (valueT) 0, 4);
6036
fix_new_exp (frag_now, p - frag_now->fr_literal, 4, &ex, FALSE, BFD_RELOC_GPREL32);
6037
demand_empty_rest_of_line ();
6040
/* Handle the .cpadd pseudo-op. This is used when dealing with switch
6041
tables in s3_PIC code. */
6043
s3_s_score_cpadd (int ignore ATTRIBUTE_UNUSED)
6046
char insn_str[s3_MAX_LITERAL_POOL_SIZE];
6048
/* If we are not generating s3_PIC code, .cpload is ignored. */
6049
if (s3_score_pic == s3_NO_PIC)
6055
if ((reg = s3_reg_required_here (&input_line_pointer, -1, s3_REG_TYPE_SCORE)) == (int) s3_FAIL)
6059
demand_empty_rest_of_line ();
6061
/* Add $gp to the register named as an argument. */
6062
sprintf (insn_str, "add r%d, r%d, r%d", reg, reg, s3_GP);
6063
if (s3_append_insn (insn_str, TRUE) == (int) s3_FAIL)
6067
#ifndef TC_IMPLICIT_LCOMM_ALIGNMENT
6068
#define TC_IMPLICIT_LCOMM_ALIGNMENT(SIZE, P2VAR) \
6073
else if ((SIZE) >= 4) \
6075
else if ((SIZE) >= 2) \
6084
s3_s_score_lcomm (int bytes_p)
6091
segT current_seg = now_seg;
6092
subsegT current_subseg = now_subseg;
6093
const int max_alignment = 15;
6095
segT bss_seg = bss_section;
6096
int needs_align = 0;
6098
name = input_line_pointer;
6099
c = get_symbol_end ();
6100
p = input_line_pointer;
6105
as_bad (_("expected symbol name"));
6106
discard_rest_of_line ();
6112
/* Accept an optional comma after the name. The comma used to be
6113
required, but Irix 5 cc does not generate it. */
6114
if (*input_line_pointer == ',')
6116
++input_line_pointer;
6120
if (is_end_of_line[(unsigned char)*input_line_pointer])
6122
as_bad (_("missing size expression"));
6126
if ((temp = get_absolute_expression ()) < 0)
6128
as_warn (_("BSS length (%d) < 0 ignored"), temp);
6129
ignore_rest_of_line ();
6133
#if defined (TC_SCORE)
6134
if (OUTPUT_FLAVOR == bfd_target_ecoff_flavour || OUTPUT_FLAVOR == bfd_target_elf_flavour)
6136
/* For Score and Alpha ECOFF or ELF, small objects are put in .sbss. */
6137
if ((unsigned)temp <= bfd_get_gp_size (stdoutput))
6139
bss_seg = subseg_new (".sbss", 1);
6140
seg_info (bss_seg)->bss = 1;
6141
#ifdef BFD_ASSEMBLER
6142
if (!bfd_set_section_flags (stdoutput, bss_seg, SEC_ALLOC))
6143
as_warn (_("error setting flags for \".sbss\": %s"), bfd_errmsg (bfd_get_error ()));
6150
if (*input_line_pointer == ',')
6152
++input_line_pointer;
6155
if (is_end_of_line[(unsigned char)*input_line_pointer])
6157
as_bad (_("missing alignment"));
6162
align = get_absolute_expression ();
6169
TC_IMPLICIT_LCOMM_ALIGNMENT (temp, align);
6171
/* Still zero unless TC_IMPLICIT_LCOMM_ALIGNMENT set it. */
6173
record_alignment (bss_seg, align);
6180
/* Convert to a power of 2. */
6185
for (i = 0; align != 0; align >>= 1, ++i)
6191
if (align > max_alignment)
6193
align = max_alignment;
6194
as_warn (_("alignment too large; %d assumed"), align);
6199
as_warn (_("alignment negative; 0 assumed"));
6202
record_alignment (bss_seg, align);
6206
/* Assume some objects may require alignment on some systems. */
6207
#if defined (TC_ALPHA) && ! defined (VMS)
6210
align = ffs (temp) - 1;
6211
if (temp % (1 << align))
6218
symbolP = symbol_find_or_make (name);
6222
#if (defined (OBJ_AOUT) || defined (OBJ_MAYBE_AOUT) \
6223
|| defined (OBJ_BOUT) || defined (OBJ_MAYBE_BOUT))
6224
#ifdef BFD_ASSEMBLER
6225
(OUTPUT_FLAVOR != bfd_target_aout_flavour
6226
|| (S_GET_OTHER (symbolP) == 0 && S_GET_DESC (symbolP) == 0)) &&
6228
(S_GET_OTHER (symbolP) == 0 && S_GET_DESC (symbolP) == 0) &&
6231
(S_GET_SEGMENT (symbolP) == bss_seg || (!S_IS_DEFINED (symbolP) && S_GET_VALUE (symbolP) == 0)))
6235
subseg_set (bss_seg, 1);
6238
frag_align (align, 0, 0);
6240
/* Detach from old frag. */
6241
if (S_GET_SEGMENT (symbolP) == bss_seg)
6242
symbol_get_frag (symbolP)->fr_symbol = NULL;
6244
symbol_set_frag (symbolP, frag_now);
6245
pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP, (offsetT) temp, NULL);
6249
S_SET_SEGMENT (symbolP, bss_seg);
6252
/* The symbol may already have been created with a preceding
6253
".globl" directive -- be careful not to step on storage class
6254
in that case. Otherwise, set it to static. */
6255
if (S_GET_STORAGE_CLASS (symbolP) != C_EXT)
6257
S_SET_STORAGE_CLASS (symbolP, C_STAT);
6259
#endif /* OBJ_COFF */
6262
S_SET_SIZE (symbolP, temp);
6266
as_bad (_("symbol `%s' is already defined"), S_GET_NAME (symbolP));
6268
subseg_set (current_seg, current_subseg);
6270
demand_empty_rest_of_line ();
6274
s3_insert_reg (const struct s3_reg_entry *r, struct hash_control *htab)
6277
int len = strlen (r->name) + 2;
6278
char *buf = xmalloc (len);
6279
char *buf2 = xmalloc (len);
6281
strcpy (buf + i, r->name);
6282
for (i = 0; buf[i]; i++)
6284
buf2[i] = TOUPPER (buf[i]);
6288
hash_insert (htab, buf, (void *) r);
6289
hash_insert (htab, buf2, (void *) r);
6293
s3_build_reg_hsh (struct s3_reg_map *map)
6295
const struct s3_reg_entry *r;
6297
if ((map->htab = hash_new ()) == NULL)
6299
as_fatal (_("virtual memory exhausted"));
6301
for (r = map->names; r->name != NULL; r++)
6303
s3_insert_reg (r, map->htab);
6307
/* Iterate over the base tables to create the instruction patterns. */
6309
s3_build_score_ops_hsh (void)
6312
static struct obstack insn_obstack;
6314
obstack_begin (&insn_obstack, 4000);
6315
for (i = 0; i < sizeof (s3_score_insns) / sizeof (struct s3_asm_opcode); i++)
6317
const struct s3_asm_opcode *insn = s3_score_insns + i;
6318
unsigned len = strlen (insn->template_name);
6319
struct s3_asm_opcode *new_opcode;
6320
char *template_name;
6321
new_opcode = (struct s3_asm_opcode *)
6322
obstack_alloc (&insn_obstack, sizeof (struct s3_asm_opcode));
6323
template_name = (char *) obstack_alloc (& insn_obstack, len + 1);
6325
strcpy (template_name, insn->template_name);
6326
new_opcode->template_name = template_name;
6327
new_opcode->parms = insn->parms;
6328
new_opcode->value = insn->value;
6329
new_opcode->relax_value = insn->relax_value;
6330
new_opcode->type = insn->type;
6331
new_opcode->bitmask = insn->bitmask;
6332
hash_insert (s3_score_ops_hsh, new_opcode->template_name,
6333
(void *) new_opcode);
6338
s3_build_dependency_insn_hsh (void)
6341
static struct obstack dependency_obstack;
6343
obstack_begin (&dependency_obstack, 4000);
6344
for (i = 0; i < sizeof (s3_insn_to_dependency_table) / sizeof (s3_insn_to_dependency_table[0]); i++)
6346
const struct s3_insn_to_dependency *tmp = s3_insn_to_dependency_table + i;
6347
unsigned len = strlen (tmp->insn_name);
6348
struct s3_insn_to_dependency *new_i2n;
6350
new_i2n = (struct s3_insn_to_dependency *)
6351
obstack_alloc (&dependency_obstack,
6352
sizeof (struct s3_insn_to_dependency));
6353
new_i2n->insn_name = (char *) obstack_alloc (&dependency_obstack,
6356
strcpy (new_i2n->insn_name, tmp->insn_name);
6357
new_i2n->type = tmp->type;
6358
hash_insert (s3_dependency_insn_hsh, new_i2n->insn_name,
6364
s_score_bss (int ignore ATTRIBUTE_UNUSED)
6367
return s3_s_score_bss (ignore);
6369
return s7_s_score_bss (ignore);
6373
s_score_text (int ignore)
6376
return s3_s_score_text (ignore);
6378
return s7_s_score_text (ignore);
6382
s_section (int ignore)
6385
return s3_score_s_section (ignore);
6387
return s7_s_section (ignore);
6391
s_change_sec (int sec)
6394
return s3_s_change_sec (sec);
6396
return s7_s_change_sec (sec);
6400
s_score_mask (int reg_type ATTRIBUTE_UNUSED)
6403
return s3_s_score_mask (reg_type);
6405
return s7_s_score_mask (reg_type);
6409
s_score_ent (int aent)
6412
return s3_s_score_ent (aent);
6414
return s7_s_score_ent (aent);
6418
s_score_frame (int ignore ATTRIBUTE_UNUSED)
6421
return s3_s_score_frame (ignore);
6423
return s7_s_score_frame (ignore);
6427
s_score_end (int x ATTRIBUTE_UNUSED)
6430
return s3_s_score_end (x);
6432
return s7_s_score_end (x);
6436
s_score_set (int x ATTRIBUTE_UNUSED)
6439
return s3_s_score_set (x);
6441
return s7_s_score_set (x);
6445
s_score_cpload (int ignore ATTRIBUTE_UNUSED)
6448
return s3_s_score_cpload (ignore);
6450
return s7_s_score_cpload (ignore);
6454
s_score_cprestore (int ignore ATTRIBUTE_UNUSED)
6457
return s3_s_score_cprestore (ignore);
6459
return s7_s_score_cprestore (ignore);
6463
s_score_gpword (int ignore ATTRIBUTE_UNUSED)
6466
return s3_s_score_gpword (ignore);
6468
return s7_s_score_gpword (ignore);
6472
s_score_cpadd (int ignore ATTRIBUTE_UNUSED)
6475
return s3_s_score_cpadd (ignore);
6477
return s7_s_score_cpadd (ignore);
6481
s_score_lcomm (int bytes_p)
6484
return s3_s_score_lcomm (bytes_p);
6486
return s7_s_score_lcomm (bytes_p);
6490
s3_assemble (char *str)
6493
know (strlen (str) < s3_MAX_LITERAL_POOL_SIZE);
6495
memset (&s3_inst, '\0', sizeof (s3_inst));
6496
if (s3_INSN_IS_PCE_P (str))
6497
s3_parse_pce_inst (str);
6498
else if (s3_INSN_IS_48_P (str))
6499
s3_parse_48_inst (str, TRUE);
6501
s3_parse_16_32_inst (str, TRUE);
6504
as_bad (_("%s -- `%s'"), s3_inst.error, s3_inst.str);
6508
s3_operand (expressionS * exp)
6510
if (s3_in_my_get_expression)
6512
exp->X_op = O_illegal;
6513
if (s3_inst.error == NULL)
6515
s3_inst.error = _("bad expression");
6527
if ((s3_score_ops_hsh = hash_new ()) == NULL)
6528
as_fatal (_("virtual memory exhausted"));
6530
s3_build_score_ops_hsh ();
6532
if ((s3_dependency_insn_hsh = hash_new ()) == NULL)
6533
as_fatal (_("virtual memory exhausted"));
6535
s3_build_dependency_insn_hsh ();
6537
for (i = (int)s3_REG_TYPE_FIRST; i < (int)s3_REG_TYPE_MAX; i++)
6538
s3_build_reg_hsh (s3_all_reg_maps + i);
6540
/* Initialize dependency vector. */
6541
s3_init_dependency_vector ();
6543
bfd_set_arch_mach (stdoutput, TARGET_ARCH, 0);
6545
subseg = now_subseg;
6546
s3_pdr_seg = subseg_new (".pdr", (subsegT) 0);
6547
(void)bfd_set_section_flags (stdoutput, s3_pdr_seg, SEC_READONLY | SEC_RELOC | SEC_DEBUGGING);
6548
(void)bfd_set_section_alignment (stdoutput, s3_pdr_seg, 2);
6549
subseg_set (seg, subseg);
6551
if (s3_USE_GLOBAL_POINTER_OPT)
6552
bfd_set_gp_size (stdoutput, s3_g_switch_value);
6556
s3_number_to_chars (char *buf, valueT val, int n)
6558
if (target_big_endian)
6559
number_to_chars_bigendian (buf, val, n);
6561
number_to_chars_littleendian (buf, val, n);
6565
s3_normal_chars_to_number (char *buf, int n)
6568
unsigned char *where = (unsigned char *)buf;
6570
if (target_big_endian)
6575
result |= (*where++ & 255);
6583
result |= (where[n] & 255);
6591
s3_number_to_chars_littleendian (void *p, valueT data, int n)
6593
char *buf = (char *) p;
6598
md_number_to_chars (buf, data >> 16, 2);
6599
md_number_to_chars (buf + 2, data, 2);
6602
md_number_to_chars (buf, data >> 32, 2);
6603
md_number_to_chars (buf + 2, data >> 16, 2);
6604
md_number_to_chars (buf + 4, data, 2);
6607
/* Error routine. */
6608
as_bad_where (__FILE__, __LINE__, _("size is not 4 or 6"));
6614
s3_chars_to_number_littleendian (const void *p, int n)
6616
char *buf = (char *) p;
6622
result = s3_normal_chars_to_number (buf, 2) << 16;
6623
result |= s3_normal_chars_to_number (buf + 2, 2);
6626
result = s3_normal_chars_to_number (buf, 2) << 32;
6627
result |= s3_normal_chars_to_number (buf + 2, 2) << 16;
6628
result |= s3_normal_chars_to_number (buf + 4, 2);
6631
/* Error routine. */
6632
as_bad_where (__FILE__, __LINE__, _("size is not 4 or 6"));
6640
s3_md_number_to_chars (char *buf, valueT val, int n)
6642
if (!target_big_endian && n >= 4)
6643
s3_number_to_chars_littleendian (buf, val, n);
6645
md_number_to_chars (buf, val, n);
6649
s3_md_chars_to_number (char *buf, int n)
6653
if (!target_big_endian && n >= 4)
6654
result = s3_chars_to_number_littleendian (buf, n);
6656
result = s3_normal_chars_to_number (buf, n);
6662
s3_atof (int type, char *litP, int *sizeP)
6665
LITTLENUM_TYPE words[s3_MAX_LITTLENUMS];
6691
return _("bad call to MD_ATOF()");
6694
t = atof_ieee (input_line_pointer, type, words);
6696
input_line_pointer = t;
6699
if (target_big_endian)
6701
for (i = 0; i < prec; i++)
6703
s3_md_number_to_chars (litP, (valueT) words[i], 2);
6709
for (i = 0; i < prec; i += 2)
6711
s3_md_number_to_chars (litP, (valueT) words[i + 1], 2);
6712
s3_md_number_to_chars (litP + 2, (valueT) words[i], 2);
6721
s3_frag_check (fragS * fragp ATTRIBUTE_UNUSED)
6723
know (fragp->insn_addr <= s3_RELAX_PAD_BYTE);
6727
s3_validate_fix (fixS *fixP)
6729
fixP->fx_where += fixP->fx_frag->insn_addr;
6733
s3_force_relocation (struct fix *fixp)
6737
if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
6738
|| fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY
6739
|| fixp->fx_r_type == BFD_RELOC_SCORE_JMP
6740
|| fixp->fx_r_type == BFD_RELOC_SCORE_BRANCH
6741
|| fixp->fx_r_type == BFD_RELOC_SCORE16_JMP
6742
|| fixp->fx_r_type == BFD_RELOC_SCORE16_BRANCH
6743
|| fixp->fx_r_type == BFD_RELOC_SCORE_BCMP)
6751
s3_fix_adjustable (fixS * fixP)
6753
if (fixP->fx_addsy == NULL)
6757
else if (OUTPUT_FLAVOR == bfd_target_elf_flavour
6758
&& (S_IS_EXTERNAL (fixP->fx_addsy) || S_IS_WEAK (fixP->fx_addsy)))
6762
else if (fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
6763
|| fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY
6764
|| fixP->fx_r_type == BFD_RELOC_SCORE_JMP
6765
|| fixP->fx_r_type == BFD_RELOC_SCORE16_JMP)
6774
s3_elf_final_processing (void)
6776
unsigned long val = 0;
6779
val = E_SCORE_MACH_SCORE3;
6781
val = E_SCORE_MACH_SCORE7;
6783
elf_elfheader (stdoutput)->e_machine = EM_SCORE;
6784
elf_elfheader (stdoutput)->e_flags &= ~EF_SCORE_MACH;
6785
elf_elfheader (stdoutput)->e_flags |= val;
6787
if (s3_fix_data_dependency == 1)
6789
elf_elfheader (stdoutput)->e_flags |= EF_SCORE_FIXDEP;
6791
if (s3_score_pic == s3_PIC)
6793
elf_elfheader (stdoutput)->e_flags |= EF_SCORE_PIC;
6798
s3_judge_size_before_relax (fragS * fragp, asection *sec)
6802
if (s3_score_pic == s3_NO_PIC)
6803
change = s3_nopic_need_relax (fragp->fr_symbol, 0);
6805
change = s3_pic_need_relax (fragp->fr_symbol, sec);
6809
/* Only at the first time determining whether s3_GP instruction relax should be done,
6810
return the difference between insntruction size and instruction relax size. */
6811
if (fragp->fr_opcode == NULL)
6813
fragp->fr_fix = s3_RELAX_NEW (fragp->fr_subtype);
6814
fragp->fr_opcode = fragp->fr_literal + s3_RELAX_RELOC1 (fragp->fr_subtype);
6815
return s3_RELAX_NEW (fragp->fr_subtype) - s3_RELAX_OLD (fragp->fr_subtype);
6823
s3_estimate_size_before_relax (fragS * fragp, asection * sec ATTRIBUTE_UNUSED)
6825
if ((s3_RELAX_TYPE (fragp->fr_subtype) == Insn_GP)
6826
|| (s3_RELAX_TYPE (fragp->fr_subtype) == Insn_PIC))
6827
return s3_judge_size_before_relax (fragp, sec);
6833
s3_relax_branch_inst32 (fragS * fragp)
6835
fragp->fr_opcode = NULL;
6840
s3_relax_branch_inst16 (fragS * fragp)
6842
int relaxable_p = 0;
6843
int frag_addr = fragp->fr_address + fragp->insn_addr;
6844
addressT symbol_address = 0;
6848
unsigned long inst_value;
6850
relaxable_p = s3_RELAX_OPT (fragp->fr_subtype);
6852
s = fragp->fr_symbol;
6858
symbol_address = (addressT) s->sy_frag->fr_address;
6861
inst_value = s3_md_chars_to_number (fragp->fr_literal, s3_INSN16_SIZE);
6862
offset = (inst_value & 0x1ff) << 1;
6863
if ((offset & 0x200) == 0x200)
6864
offset |= 0xfffffc00;
6866
value = offset + symbol_address - frag_addr;
6869
&& (!((value & 0xfffffe00) == 0 || (value & 0xfffffe00) == 0xfffffe00))
6870
&& fragp->fr_fix == 2
6871
&& (s->bsym != NULL)
6872
&& (S_IS_DEFINED (s)
6874
&& !S_IS_EXTERNAL (s)))
6876
/* Relax branch 32 to branch 16. */
6877
fragp->fr_opcode = fragp->fr_literal + s3_RELAX_RELOC1 (fragp->fr_subtype);
6886
s3_relax_cmpbranch_inst32 (fragS * fragp)
6888
int relaxable_p = 0;
6892
long frag_addr = fragp->fr_address + fragp->insn_addr;
6893
long symbol_address = 0;
6895
unsigned long inst_value;
6897
relaxable_p = s3_RELAX_OPT (fragp->fr_subtype);
6899
s = fragp->fr_symbol;
6905
symbol_address = (addressT) s->sy_frag->fr_address;
6908
inst_value = s3_md_chars_to_number (fragp->fr_literal, s3_INSN_SIZE);
6909
offset = (inst_value & 0x1)
6910
| (((inst_value >> 7) & 0x7) << 1)
6911
| (((inst_value >> 21) & 0x1f) << 4);
6913
if ((offset & 0x200) == 0x200)
6914
offset |= 0xfffffe00;
6916
value = offset + symbol_address - frag_addr;
6917
/* change the order of judging rule is because
6918
1.not defined symbol or common sysbol or external symbol will change
6919
bcmp to cmp!+beq/bne ,here need to record fragp->fr_opcode
6920
2.if the flow is as before : it will results to recursive loop
6922
if (fragp->fr_fix == 6)
6924
/* Have already relaxed! Just return 0 to terminate the loop. */
6927
/* need to translate when extern or not defind or common sysbol */
6928
else if ((relaxable_p
6929
&& (!((value & 0xfffffe00) == 0 || (value & 0xfffffe00) == 0xfffffe00))
6930
&& fragp->fr_fix == 4
6931
&& (s->bsym != NULL))
6932
|| !S_IS_DEFINED (s)
6934
||S_IS_EXTERNAL (s))
6936
fragp->fr_opcode = fragp->fr_literal + s3_RELAX_RELOC1 (fragp->fr_subtype);
6942
/* Never relax. Modify fr_opcode to NULL to verify it's value in
6944
fragp->fr_opcode = NULL;
6951
s3_relax_other_inst32 (fragS * fragp)
6953
int relaxable_p = s3_RELAX_OPT (fragp->fr_subtype);
6956
&& fragp->fr_fix == 4)
6958
fragp->fr_opcode = fragp->fr_literal + s3_RELAX_RELOC1 (fragp->fr_subtype);
6967
s3_relax_gp_and_pic_inst32 (void)
6969
/* md_estimate_size_before_relax has already relaxed s3_GP and s3_PIC
6970
instructions. We don't change relax size here. */
6975
s3_relax_frag (asection * sec ATTRIBUTE_UNUSED, fragS * fragp, long stretch ATTRIBUTE_UNUSED)
6978
int adjust_align_p = 0;
6980
/* If the instruction address is odd, make it half word align first. */
6981
if ((fragp->fr_address) % 2 != 0)
6983
if ((fragp->fr_address + fragp->insn_addr) % 2 != 0)
6985
fragp->insn_addr = 1;
6991
switch (s3_RELAX_TYPE (fragp->fr_subtype))
6994
grows += s3_relax_branch_inst32 (fragp);
6998
grows += s3_relax_branch_inst16 (fragp);
7002
grows += s3_relax_cmpbranch_inst32 (fragp);
7007
grows += s3_relax_gp_and_pic_inst32 ();
7011
grows += s3_relax_other_inst32 (fragp);
7016
if (adjust_align_p && fragp->insn_addr)
7018
fragp->fr_fix += fragp->insn_addr;
7025
s3_convert_frag (bfd * abfd ATTRIBUTE_UNUSED, segT sec ATTRIBUTE_UNUSED, fragS * fragp)
7032
r_old = s3_RELAX_OLD (fragp->fr_subtype);
7033
r_new = s3_RELAX_NEW (fragp->fr_subtype);
7035
/* fragp->fr_opcode indicates whether this frag should be relaxed. */
7036
if (fragp->fr_opcode == NULL)
7038
memcpy (backup, fragp->fr_literal, r_old);
7039
fragp->fr_fix = r_old;
7043
memcpy (backup, fragp->fr_literal + r_old, r_new);
7044
fragp->fr_fix = r_new;
7047
fixp = fragp->tc_frag_data.fixp;
7048
while (fixp && fixp->fx_frag == fragp && fixp->fx_where < r_old)
7050
if (fragp->fr_opcode)
7052
fixp = fixp->fx_next;
7054
while (fixp && fixp->fx_frag == fragp)
7056
if (fragp->fr_opcode)
7057
fixp->fx_where -= r_old + fragp->insn_addr;
7060
fixp = fixp->fx_next;
7063
if (fragp->insn_addr)
7065
s3_md_number_to_chars (fragp->fr_literal, 0x0, fragp->insn_addr);
7067
memcpy (fragp->fr_literal + fragp->insn_addr, backup, fragp->fr_fix);
7068
fragp->fr_fix += fragp->insn_addr;
7072
s3_pcrel_from (fixS * fixP)
7077
&& (S_GET_SEGMENT (fixP->fx_addsy) == undefined_section)
7078
&& (fixP->fx_subsy == NULL))
7084
retval = fixP->fx_where + fixP->fx_frag->fr_address;
7091
s3_section_align (segT segment ATTRIBUTE_UNUSED, valueT size)
7093
int align = bfd_get_section_alignment (stdoutput, segment);
7094
return ((size + (1 << align) - 1) & (-1 << align));
7098
s3_apply_fix (fixS *fixP, valueT *valP, segT seg)
7100
offsetT value = *valP;
7103
unsigned short HI, LO;
7105
char *buf = fixP->fx_frag->fr_literal + fixP->fx_where;
7107
gas_assert (fixP->fx_r_type < BFD_RELOC_UNUSED);
7108
if (fixP->fx_addsy == 0 && !fixP->fx_pcrel)
7110
if (fixP->fx_r_type != BFD_RELOC_SCORE_DUMMY_HI16)
7114
/* If this symbol is in a different section then we need to leave it for
7115
the linker to deal with. Unfortunately, md_pcrel_from can't tell,
7116
so we have to undo it's effects here. */
7119
if (fixP->fx_addsy != NULL
7120
&& S_IS_DEFINED (fixP->fx_addsy)
7121
&& S_GET_SEGMENT (fixP->fx_addsy) != seg)
7122
value += md_pcrel_from (fixP);
7125
/* Remember value for emit_reloc. */
7126
fixP->fx_addnumber = value;
7128
switch (fixP->fx_r_type)
7130
case BFD_RELOC_HI16_S:
7131
if (fixP->fx_done) /* For la rd, imm32. */
7133
newval = s3_md_chars_to_number (buf, s3_INSN_SIZE);
7134
HI = (value) >> 16; /* mul to 2, then take the hi 16 bit. */
7135
newval |= (HI & 0x3fff) << 1;
7136
newval |= ((HI >> 14) & 0x3) << 16;
7137
s3_md_number_to_chars (buf, newval, s3_INSN_SIZE);
7140
case BFD_RELOC_LO16:
7141
if (fixP->fx_done) /* For la rd, imm32. */
7143
newval = s3_md_chars_to_number (buf, s3_INSN_SIZE);
7144
LO = (value) & 0xffff;
7145
newval |= (LO & 0x3fff) << 1; /* 16 bit: imm -> 14 bit in lo, 2 bit in hi. */
7146
newval |= ((LO >> 14) & 0x3) << 16;
7147
s3_md_number_to_chars (buf, newval, s3_INSN_SIZE);
7150
case BFD_RELOC_SCORE_JMP:
7152
content = s3_md_chars_to_number (buf, s3_INSN_SIZE);
7153
value = fixP->fx_offset;
7154
content = (content & ~0x3ff7ffe) | ((value << 1) & 0x3ff0000) | (value & 0x7fff);
7155
s3_md_number_to_chars (buf, content, s3_INSN_SIZE);
7159
case BFD_RELOC_SCORE_IMM30:
7161
content = s3_md_chars_to_number (buf, s3_INSN48_SIZE);
7162
value = fixP->fx_offset;
7164
content = (content & ~0x7f7fff7f80LL)
7165
| (((value & 0xff) >> 0) << 7)
7166
| (((value & 0x7fff00) >> 8) << 16)
7167
| (((value & 0x3f800000) >> 23) << 32);
7168
s3_md_number_to_chars (buf, content, s3_INSN48_SIZE);
7172
case BFD_RELOC_SCORE_IMM32:
7174
content = s3_md_chars_to_number (buf, s3_INSN48_SIZE);
7175
value = fixP->fx_offset;
7176
content = (content & ~0x7f7fff7fe0LL)
7177
| ((value & 0x3ff) << 5)
7178
| (((value >> 10) & 0x7fff) << 16)
7179
| (((value >> 25) & 0x7f) << 32);
7180
s3_md_number_to_chars (buf, content, s3_INSN48_SIZE);
7184
case BFD_RELOC_SCORE_BRANCH:
7185
if ((S_GET_SEGMENT (fixP->fx_addsy) != seg) || (fixP->fx_addsy != NULL && S_IS_EXTERNAL (fixP->fx_addsy)))
7186
value = fixP->fx_offset;
7190
content = s3_md_chars_to_number (buf, s3_INSN_SIZE);
7192
/* Don't check c-bit. */
7193
if (fixP->fx_frag->fr_opcode != 0)
7195
if ((value & 0xfffffe00) != 0 && (value & 0xfffffe00) != 0xfffffe00)
7197
as_bad_where (fixP->fx_file, fixP->fx_line,
7198
_(" branch relocation truncate (0x%x) [-2^9 ~ 2^9]"), (unsigned int)value);
7201
content = s3_md_chars_to_number (buf, s3_INSN16_SIZE);
7203
content = (content & 0xfe00) | ((value >> 1) & 0x1ff);
7204
s3_md_number_to_chars (buf, content, s3_INSN16_SIZE);
7205
fixP->fx_r_type = BFD_RELOC_SCORE16_BRANCH;
7210
if ((value & 0xfff80000) != 0 && (value & 0xfff80000) != 0xfff80000)
7212
as_bad_where (fixP->fx_file, fixP->fx_line,
7213
_(" branch relocation truncate (0x%x) [-2^19 ~ 2^19]"), (unsigned int)value);
7216
content = s3_md_chars_to_number (buf, s3_INSN_SIZE);
7217
content &= 0xfc00fc01;
7218
content = (content & 0xfc00fc01) | (value & 0x3fe) | ((value << 6) & 0x3ff0000);
7219
s3_md_number_to_chars (buf, content, s3_INSN_SIZE);
7222
case BFD_RELOC_SCORE16_JMP:
7223
content = s3_md_chars_to_number (buf, s3_INSN16_SIZE);
7225
value = fixP->fx_offset & 0xfff;
7226
content = (content & 0xfc01) | (value & 0xffe);
7227
s3_md_number_to_chars (buf, content, s3_INSN16_SIZE);
7229
case BFD_RELOC_SCORE16_BRANCH:
7230
content = s3_md_chars_to_number (buf, s3_INSN_SIZE);
7231
/* Don't check c-bit. */
7232
if (fixP->fx_frag->fr_opcode != 0)
7234
if ((S_GET_SEGMENT (fixP->fx_addsy) != seg) ||
7235
(fixP->fx_addsy != NULL && S_IS_EXTERNAL (fixP->fx_addsy)))
7236
value = fixP->fx_offset;
7239
if ((value & 0xfff80000) != 0 && (value & 0xfff80000) != 0xfff80000)
7241
as_bad_where (fixP->fx_file, fixP->fx_line,
7242
_(" branch relocation truncate (0x%x) [-2^19 ~ 2^19]"), (unsigned int)value);
7245
content = s3_md_chars_to_number (buf, s3_INSN_SIZE);
7246
content = (content & 0xfc00fc01) | (value & 0x3fe) | ((value << 6) & 0x3ff0000);
7247
s3_md_number_to_chars (buf, content, s3_INSN_SIZE);
7248
fixP->fx_r_type = BFD_RELOC_SCORE_BRANCH;
7254
/* In differnt section. */
7255
if ((S_GET_SEGMENT (fixP->fx_addsy) != seg) ||
7256
(fixP->fx_addsy != NULL && S_IS_EXTERNAL (fixP->fx_addsy)))
7257
value = fixP->fx_offset;
7261
if ((value & 0xfffffe00) != 0 && (value & 0xfffffe00) != 0xfffffe00)
7263
as_bad_where (fixP->fx_file, fixP->fx_line,
7264
_(" branch relocation truncate (0x%x) [-2^9 ~ 2^9]"), (unsigned int)value);
7268
content = s3_md_chars_to_number (buf, s3_INSN16_SIZE);
7269
content = (content & 0xfe00) | ((value >> 1) & 0x1ff);
7270
s3_md_number_to_chars (buf, content, s3_INSN16_SIZE);
7276
case BFD_RELOC_SCORE_BCMP:
7277
if (fixP->fx_frag->fr_opcode != 0)
7279
char *buf_ptr = buf;
7282
if ((S_GET_SEGMENT (fixP->fx_addsy) != seg) || (fixP->fx_addsy != NULL && S_IS_EXTERNAL (fixP->fx_addsy)))
7283
value = fixP->fx_offset;
7288
bcmp -> cmp! and branch, so value -= 2. */
7291
if ((value & 0xfff80000) != 0 && (value & 0xfff80000) != 0xfff80000)
7293
as_bad_where (fixP->fx_file, fixP->fx_line,
7294
_(" branch relocation truncate (0x%x) [-2^19 ~ 2^19]"), (unsigned int)value);
7298
content = s3_md_chars_to_number (buf_ptr, s3_INSN_SIZE);
7299
content &= 0xfc00fc01;
7300
content = (content & 0xfc00fc01) | (value & 0x3fe) | ((value << 6) & 0x3ff0000);
7301
s3_md_number_to_chars (buf_ptr, content, s3_INSN_SIZE);
7302
/* change relocation type to BFD_RELOC_SCORE_BRANCH */
7303
fixP->fx_r_type = BFD_RELOC_SCORE_BRANCH;
7304
fixP->fx_where+=2; /* first insn is cmp! , the second insn is beq/bne */
7309
if ((S_GET_SEGMENT (fixP->fx_addsy) != seg) || (fixP->fx_addsy != NULL && S_IS_EXTERNAL (fixP->fx_addsy)))
7310
value = fixP->fx_offset;
7314
content = s3_md_chars_to_number (buf, s3_INSN_SIZE);
7316
if ((value & 0xfffffe00) != 0 && (value & 0xfffffe00) != 0xfffffe00)
7318
as_bad_where (fixP->fx_file, fixP->fx_line,
7319
_(" branch relocation truncate (0x%x) [-2^9 ~ 2^9]"), (unsigned int)value);
7324
content &= ~0x03e00381;
7327
| (((value & 0xe) >> 1) << 7)
7328
| (((value & 0x1f0) >> 4) << 21);
7330
s3_md_number_to_chars (buf, content, s3_INSN_SIZE);
7335
if (fixP->fx_done || fixP->fx_pcrel)
7336
s3_md_number_to_chars (buf, value, 1);
7340
value = fixP->fx_offset;
7341
s3_md_number_to_chars (buf, value, 1);
7347
if (fixP->fx_done || fixP->fx_pcrel)
7348
s3_md_number_to_chars (buf, value, 2);
7352
value = fixP->fx_offset;
7353
s3_md_number_to_chars (buf, value, 2);
7359
if (fixP->fx_done || fixP->fx_pcrel)
7360
md_number_to_chars (buf, value, 4);
7364
value = fixP->fx_offset;
7365
md_number_to_chars (buf, value, 4);
7369
case BFD_RELOC_VTABLE_INHERIT:
7371
if (fixP->fx_addsy && !S_IS_DEFINED (fixP->fx_addsy) && !S_IS_WEAK (fixP->fx_addsy))
7372
S_SET_WEAK (fixP->fx_addsy);
7374
case BFD_RELOC_VTABLE_ENTRY:
7377
case BFD_RELOC_SCORE_GPREL15:
7378
content = s3_md_chars_to_number (buf, s3_INSN_SIZE);
7380
if ((fixP->fx_frag->fr_opcode != 0) && ((content & 0xfc1c8000) != 0x94180000))
7381
fixP->fx_r_type = BFD_RELOC_NONE;
7384
case BFD_RELOC_SCORE_GOT15:
7385
case BFD_RELOC_SCORE_DUMMY_HI16:
7386
case BFD_RELOC_SCORE_GOT_LO16:
7387
case BFD_RELOC_SCORE_CALL15:
7388
case BFD_RELOC_GPREL32:
7390
case BFD_RELOC_NONE:
7392
as_bad_where (fixP->fx_file, fixP->fx_line, _("bad relocation fixup type (%d)"), fixP->fx_r_type);
7397
s3_gen_reloc (asection * section ATTRIBUTE_UNUSED, fixS * fixp)
7399
static arelent *retval[MAX_RELOC_EXPANSION + 1]; /* MAX_RELOC_EXPANSION equals 2. */
7401
bfd_reloc_code_real_type code;
7404
reloc = retval[0] = xmalloc (sizeof (arelent));
7407
reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
7408
*reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
7409
reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
7410
reloc->addend = fixp->fx_offset;
7412
/* If this is a variant frag, we may need to adjust the existing
7413
reloc and generate a new one. */
7414
if (fixp->fx_frag->fr_opcode != NULL && (fixp->fx_r_type == BFD_RELOC_SCORE_GPREL15))
7416
/* Update instruction imm bit. */
7421
buf = fixp->fx_frag->fr_literal + fixp->fx_frag->insn_addr;
7422
newval = s3_md_chars_to_number (buf, s3_INSN_SIZE);
7423
off = fixp->fx_offset >> 16;
7424
newval |= (off & 0x3fff) << 1;
7425
newval |= ((off >> 14) & 0x3) << 16;
7426
s3_md_number_to_chars (buf, newval, s3_INSN_SIZE);
7428
buf += s3_INSN_SIZE;
7429
newval = s3_md_chars_to_number (buf, s3_INSN_SIZE);
7430
off = fixp->fx_offset & 0xffff;
7431
newval |= ((off & 0x3fff) << 1);
7432
newval |= (((off >> 14) & 0x3) << 16);
7433
s3_md_number_to_chars (buf, newval, s3_INSN_SIZE);
7435
retval[1] = xmalloc (sizeof (arelent));
7437
retval[1]->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
7438
*retval[1]->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
7439
retval[1]->address = (reloc->address + s3_RELAX_RELOC2 (fixp->fx_frag->fr_subtype));
7441
retval[1]->addend = 0;
7442
retval[1]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_LO16);
7443
gas_assert (retval[1]->howto != NULL);
7445
fixp->fx_r_type = BFD_RELOC_HI16_S;
7448
code = fixp->fx_r_type;
7449
switch (fixp->fx_r_type)
7454
code = BFD_RELOC_32_PCREL;
7457
case BFD_RELOC_HI16_S:
7458
case BFD_RELOC_LO16:
7459
case BFD_RELOC_SCORE_JMP:
7460
case BFD_RELOC_SCORE_BRANCH:
7461
case BFD_RELOC_SCORE16_JMP:
7462
case BFD_RELOC_SCORE16_BRANCH:
7463
case BFD_RELOC_SCORE_BCMP:
7464
case BFD_RELOC_VTABLE_ENTRY:
7465
case BFD_RELOC_VTABLE_INHERIT:
7466
case BFD_RELOC_SCORE_GPREL15:
7467
case BFD_RELOC_SCORE_GOT15:
7468
case BFD_RELOC_SCORE_DUMMY_HI16:
7469
case BFD_RELOC_SCORE_GOT_LO16:
7470
case BFD_RELOC_SCORE_CALL15:
7471
case BFD_RELOC_GPREL32:
7472
case BFD_RELOC_NONE:
7473
case BFD_RELOC_SCORE_IMM30:
7474
case BFD_RELOC_SCORE_IMM32:
7475
code = fixp->fx_r_type;
7478
type = _("<unknown>");
7479
as_bad_where (fixp->fx_file, fixp->fx_line,
7480
_("cannot represent %s relocation in this object file format"), type);
7484
reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
7485
if (reloc->howto == NULL)
7487
as_bad_where (fixp->fx_file, fixp->fx_line,
7488
_("cannot represent %s relocation in this object file format1"),
7489
bfd_get_reloc_code_name (code));
7492
/* HACK: Since arm ELF uses Rel instead of Rela, encode the
7493
vtable entry to be used in the relocation's section offset. */
7494
if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
7495
reloc->address = fixp->fx_offset;
7501
md_assemble (char *str)
7509
/* We handle all bad expressions here, so that we can report the faulty
7510
instruction in the error message. */
7512
md_operand (expressionS * exp)
7520
/* Turn an integer of n bytes (in val) into a stream of bytes appropriate
7521
for use in the a.out file, and stores them in the array pointed to by buf.
7522
This knows about the endian-ness of the target machine and does
7523
THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
7524
2 (short) and 4 (long) Floating numbers are put out as a series of
7525
LITTLENUMS (shorts, here at least). */
7527
md_number_to_chars (char *buf, valueT val, int n)
7530
s3_number_to_chars (buf, val, n);
7532
s7_number_to_chars (buf, val, n);
7535
/* Turn a string in input_line_pointer into a floating point constant
7536
of type TYPE, and store the appropriate bytes in *LITP. The number
7537
of LITTLENUMS emitted is stored in *SIZEP. An error message is
7538
returned, or NULL on OK.
7540
Note that fp constants aren't represent in the normal way on the ARM.
7541
In big endian mode, things are as expected. However, in little endian
7542
mode fp constants are big-endian word-wise, and little-endian byte-wise
7543
within the words. For example, (double) 1.1 in big endian mode is
7544
the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
7545
the byte sequence 99 99 f1 3f 9a 99 99 99. */
7547
md_atof (int type, char *litP, int *sizeP)
7550
return s3_atof (type, litP, sizeP);
7552
return s7_atof (type, litP, sizeP);
7556
score_frag_check (fragS * fragp ATTRIBUTE_UNUSED)
7559
s3_frag_check (fragp);
7561
s7_frag_check (fragp);
7564
/* Implementation of TC_VALIDATE_FIX.
7565
Called before md_apply_fix() and after md_convert_frag(). */
7567
score_validate_fix (fixS *fixP)
7570
s3_validate_fix (fixP);
7572
s7_validate_fix (fixP);
7576
score_force_relocation (struct fix *fixp)
7579
return s3_force_relocation (fixp);
7581
return s7_force_relocation (fixp);
7584
/* Implementation of md_frag_check.
7585
Called after md_convert_frag(). */
7587
score_fix_adjustable (fixS * fixP)
7590
return s3_fix_adjustable (fixP);
7592
return s7_fix_adjustable (fixP);
7596
score_elf_final_processing (void)
7599
s3_elf_final_processing ();
7601
s7_elf_final_processing ();
7604
/* In this function, we determine whether s3_GP instruction should do relaxation,
7605
for the label being against was known now.
7606
Doing this here but not in md_relax_frag() can induce iteration times
7607
in stage of doing relax. */
7609
md_estimate_size_before_relax (fragS * fragp, asection * sec ATTRIBUTE_UNUSED)
7612
return s3_estimate_size_before_relax (fragp, sec);
7614
return s7_estimate_size_before_relax (fragp, sec);
7618
score_relax_frag (asection * sec ATTRIBUTE_UNUSED, fragS * fragp, long stretch ATTRIBUTE_UNUSED)
7621
return s3_relax_frag (sec, fragp, stretch);
7623
return s7_relax_frag (sec, fragp, stretch);
7627
md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED, segT sec ATTRIBUTE_UNUSED, fragS * fragp)
7630
return s3_convert_frag (abfd, sec, fragp);
7632
return s7_convert_frag (abfd, sec, fragp);
7636
md_pcrel_from (fixS * fixP)
7639
return s3_pcrel_from (fixP);
7641
return s7_pcrel_from (fixP);
7644
/* Round up a section size to the appropriate boundary. */
7646
md_section_align (segT segment ATTRIBUTE_UNUSED, valueT size)
7649
return s3_section_align (segment, size);
7651
return s7_section_align (segment, size);
7655
md_apply_fix (fixS *fixP, valueT *valP, segT seg)
7658
return s3_apply_fix (fixP, valP, seg);
7660
return s7_apply_fix (fixP, valP, seg);
7663
/* Translate internal representation of relocation info to BFD target format. */
7665
tc_gen_reloc (asection * section ATTRIBUTE_UNUSED, fixS * fixp)
7668
return s3_gen_reloc (section, fixp);
7670
return s7_gen_reloc (section, fixp);
7681
score_set_mach (const char *arg)
7683
if (strcmp (arg, MARCH_SCORE3) == 0)
7689
else if (strcmp (arg, MARCH_SCORE7) == 0)
7694
s7_university_version = 0;
7695
s7_vector_size = s7_SCORE7_PIPELINE;
7697
else if (strcmp (arg, MARCH_SCORE5) == 0)
7702
s7_university_version = 0;
7703
s7_vector_size = s7_SCORE5_PIPELINE;
7705
else if (strcmp (arg, MARCH_SCORE5U) == 0)
7710
s7_university_version = 1;
7711
s7_vector_size = s7_SCORE5_PIPELINE;
7715
as_bad (_("unknown architecture `%s'\n"), arg);
7720
md_parse_option (int c, char *arg)
7726
target_big_endian = 1;
7731
target_big_endian = 0;
7735
s3_fix_data_dependency = 1;
7736
s7_fix_data_dependency = 1;
7739
s3_warn_fix_data_dependency = 0;
7740
s7_warn_fix_data_dependency = 0;
7745
s7_university_version = 0;
7746
s7_vector_size = s7_SCORE5_PIPELINE;
7748
case OPTION_SCORE5U:
7751
s7_university_version = 1;
7752
s7_vector_size = s7_SCORE5_PIPELINE;
7758
s7_university_version = 0;
7759
s7_vector_size = s7_SCORE7_PIPELINE;
7771
s3_g_switch_value = atoi (arg);
7772
s7_g_switch_value = atoi (arg);
7778
case OPTION_SCORE_VERSION:
7779
printf (_("Sunplus-v2-0-0-20060510\n"));
7782
s3_score_pic = s3_NO_PIC; /* Score3 doesn't support PIC now. */
7783
s7_score_pic = s7_PIC;
7784
s3_g_switch_value = 0; /* Must set -G num as 0 to generate s3_PIC code. */
7785
s7_g_switch_value = 0; /* Must set -G num as 0 to generate s7_PIC code. */
7788
score_set_mach (arg);
7797
md_show_usage (FILE * fp)
7799
fprintf (fp, _(" Score-specific assembler options:\n"));
7802
-EB\t\tassemble code for a big-endian cpu\n"));
7807
-EL\t\tassemble code for a little-endian cpu\n"));
7811
-FIXDD\t\tassemble code for fix data dependency\n"));
7813
-NWARN\t\tassemble code for no warning message for fix data dependency\n"));
7815
-SCORE5\t\tassemble code for target is SCORE5\n"));
7817
-SCORE5U\tassemble code for target is SCORE5U\n"));
7819
-SCORE7\t\tassemble code for target is SCORE7, this is default setting\n"));
7821
-SCORE3\t\tassemble code for target is SCORE3\n"));
7823
-march=score7\tassemble code for target is SCORE7, this is default setting\n"));
7825
-march=score3\tassemble code for target is SCORE3\n"));
7827
-USE_R1\t\tassemble code for no warning message when using temp register r1\n"));
7829
-KPIC\t\tassemble code for PIC\n"));
7831
-O0\t\tassembler will not perform any optimizations\n"));
7833
-G gpnum\tassemble code for setting gpsize and default is 8 byte\n"));
7835
-V \t\tSunplus release version \n"));