]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gas/config/tc-csky.c
Update year range in copyright notice of binutils files
[thirdparty/binutils-gdb.git] / gas / config / tc-csky.c
1 /* tc-csky.c -- Assembler for C-SKY
2 Copyright (C) 1989-2023 Free Software Foundation, Inc.
3 Created by Lifang Xia (lifang_xia@c-sky.com)
4 Contributed by C-SKY Microsystems and Mentor Graphics.
5
6 This file is part of GAS, the GNU Assembler.
7
8 GAS is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
11 any later version.
12
13 GAS is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GAS; see the file COPYING. If not, write to the Free
20 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
21 02110-1301, USA. */
22
23 #include "as.h"
24 #include <limits.h>
25 #include <stdint.h>
26 #include <stdarg.h>
27 #include <ctype.h>
28 #include "safe-ctype.h"
29 #include "subsegs.h"
30 #include "obstack.h"
31 #include "libiberty.h"
32
33 #ifdef OBJ_ELF
34 #include "elf/csky.h"
35 #include "dw2gencfi.h"
36 #endif
37 #include "tc-csky.h"
38 #include "dwarf2dbg.h"
39
40 #define BUILD_AS 1
41
42 #define OPCODE_MAX_LEN 20
43 #define HAS_SUB_OPERAND 0xfffffffful
44
45 /* This value is just for lrw to distinguish "[]" label. */
46 #define NEED_OUTPUT_LITERAL 1
47
48 #define IS_EXTERNAL_SYM(sym, sec) (S_GET_SEGMENT (sym) != sec)
49 #define IS_SUPPORT_OPCODE16(opcode) (opcode->isa_flag16 | isa_flag)
50 #define IS_SUPPORT_OPCODE32(opcode) (opcode->isa_flag32 | isa_flag)
51
52
53 #define KB * 1024
54 #define MB KB * 1024
55 #define GB MB * 1024
56
57 /* Define DSP version flags. For different CPU, the version of DSP
58 instructions may be different. */
59 #define CSKY_DSP_FLAG_V1 (1 << 0) /* Normal DSP instructions. */
60 #define CSKY_DSP_FLAG_V2 (1 << 1) /* CK803S enhanced DSP. */
61
62 /* Literal pool related macros. */
63 /* 1024 - 1 entry - 2 byte rounding. */
64 #define v1_SPANPANIC (998)
65 #define v1_SPANCLOSE (900)
66 #define v1_SPANEXIT (600)
67 #define v2_SPANPANIC (1024 - 4)
68
69 /* 1024 is flrw offset.
70 24 is the biggest size for single instruction.
71 for lrw16 (3+7, 512 bytes). */
72 #define v2_SPANCLOSE (512 - 24)
73
74 /* For lrw16, 112 average size for a function. */
75 #define v2_SPANEXIT (512 - 112)
76
77 /* For lrw16 (3+7, 512 bytes). */
78 #define v2_SPANCLOSE_ELRW (1016 - 24)
79
80 /* For lrw16, 112 average size for a function. */
81 #define v2_SPANEXIT_ELRW (1016 - 112)
82 #define MAX_POOL_SIZE (1024 / 4)
83 #define POOL_END_LABEL ".LE"
84 #define POOL_START_LABEL ".LS"
85
86 /* Used in v1_relax_table. */
87 /* These are the two types of relaxable instruction. */
88 #define COND_JUMP 1
89 #define UNCD_JUMP 2
90 #define COND_JUMP_PIC 3
91 #define UNCD_JUMP_PIC 4
92
93 #define UNDEF_DISP 0
94 #define DISP12 1
95 #define DISP32 2
96 #define UNDEF_WORD_DISP 3
97
98 #define C12_LEN 2
99 /* Allow for align: bt/jmpi/.long + align. */
100 #define C32_LEN 10
101 /* Allow for align: bt/subi/stw/bsr/lrw/add/ld/addi/jmp/.long + align. */
102 #define C32_LEN_PIC 24
103 #define U12_LEN 2
104 /* Allow for align: jmpi/.long + align. */
105 #define U32_LEN 8
106 /* Allow for align: subi/stw/bsr/lrw/add/ld/addi/jmp/.long + align. */
107 #define U32_LEN_PIC 22
108
109 #define C(what,length) (((what) << 2) + (length))
110 #define UNCD_JUMP_S (do_pic ? UNCD_JUMP_PIC : UNCD_JUMP)
111 #define COND_JUMP_S (do_pic ? COND_JUMP_PIC : COND_JUMP)
112 #define U32_LEN_S (do_pic ? U32_LEN_PIC : U32_LEN)
113 #define C32_LEN_S (do_pic ? C32_LEN_PIC : C32_LEN)
114
115 /* Used in v2_relax_table. */
116 #define COND_DISP10_LEN 2 /* bt/bf_16. */
117 #define COND_DISP16_LEN 4 /* bt/bf_32. */
118
119 #define SCOND_DISP10_LEN 2 /* bt/bf_16, for CK801 only. */
120 #define SCOND_DISP16_LEN 6 /* !(bt/bf_16) + br_32. */
121
122 #define UNCD_DISP10_LEN 2 /* br_16. */
123 #define UNCD_DISP16_LEN 4 /* br_32. */
124 #define UNCD_DISP26_LEN 4 /* br32_old. */
125
126 #define JCOND_DISP10_LEN 2 /* bt/bf_16. */
127 #define JCOND_DISP16_LEN 4 /* bt/bf_32. */
128 #define JCOND_DISP32_LEN 12 /* !(bt/bf_16)/jmpi 32/.align 2/literal 4. */
129 #define JCOND_DISP26_LEN 8 /* bt/bf_32/br_32 old. */
130
131 #define JUNCD_DISP26_LEN 4 /* bt/bf_32 old. */
132 #define JUNCD_DISP10_LEN 2 /* br_16. */
133 #define JUNCD_DISP16_LEN 4 /* bt/bf_32. */
134 #define JUNCD_DISP32_LEN 10 /* jmpi_32/.align 2/literal 4/ CHANGED!. */
135 #define JCOMP_DISP26_LEN 8 /* bne_32/br_32 old. */
136
137 #define JCOMP_DISP16_LEN 4 /* bne_32 old. */
138 #define JCOMPZ_DISP16_LEN 4 /* bhlz_32. */
139 #define JCOMPZ_DISP32_LEN 14 /* bsz_32/jmpi 32/.align 2/literal 4. */
140 #define JCOMPZ_DISP26_LEN 8 /* bsz_32/br_32 old. */
141 #define JCOMP_DISP32_LEN 14 /* be_32/jmpi_32/.align 2/literal old. */
142
143 #define BSR_DISP10_LEN 2 /* bsr_16. */
144 #define BSR_DISP26_LEN 4 /* bsr_32. */
145 #define LRW_DISP7_LEN 2 /* lrw16. */
146 #define LRW_DISP16_LEN 4 /* lrw32. */
147
148 /* Declare worker functions. */
149 bool v1_work_lrw (void);
150 bool v1_work_jbsr (void);
151 bool v1_work_fpu_fo (void);
152 bool v1_work_fpu_fo_fc (void);
153 bool v1_work_fpu_write (void);
154 bool v1_work_fpu_read (void);
155 bool v1_work_fpu_writed (void);
156 bool v1_work_fpu_readd (void);
157 bool v2_work_istack (void);
158 bool v2_work_btsti (void);
159 bool v2_work_addi (void);
160 bool v2_work_subi (void);
161 bool v2_work_add_sub (void);
162 bool v2_work_rotlc (void);
163 bool v2_work_bgeni (void);
164 bool v2_work_not (void);
165 bool v2_work_jbtf (void);
166 bool v2_work_jbr (void);
167 bool v2_work_lrw (void);
168 bool v2_work_lrsrsw (void);
169 bool v2_work_jbsr (void);
170 bool v2_work_jsri (void);
171 bool v2_work_movih (void);
172 bool v2_work_ori (void);
173 bool float_work_fmovi (void);
174 bool dsp_work_bloop (void);
175 bool float_work_fpuv3_fmovi (void);
176 bool float_work_fpuv3_fstore (void);
177 bool v2_work_addc (void);
178
179 /* csky-opc.h must be included after workers are declared. */
180 #include "opcodes/csky-opc.h"
181 #include "opcode/csky.h"
182
183 enum
184 {
185 RELAX_NONE = 0,
186 RELAX_OVERFLOW,
187
188 COND_DISP10 = 20, /* bt/bf_16. */
189 COND_DISP16, /* bt/bf_32. */
190
191 SCOND_DISP10, /* br_16 */
192 SCOND_DISP16, /* !(bt/bf_32) + br_32. */
193
194 UNCD_DISP10, /* br_16. */
195 UNCD_DISP16, /* br_32. */
196
197 JCOND_DISP10, /* bt/bf_16. */
198 JCOND_DISP16, /* bt/bf_32. */
199 JCOND_DISP32, /* !(bt/bf_32)/jmpi + literal. */
200
201 JUNCD_DISP10, /* br_16. */
202 JUNCD_DISP16, /* br_32. */
203 JUNCD_DISP32, /* jmpi + literal. */
204
205 JCOMPZ_DISP16, /* bez/bnez/bhz/blsz/blz/bhsz. */
206 JCOMPZ_DISP32, /* !(jbez/jbnez/jblsz/jblz/jbhsz) + jmpi + literal. */
207
208 BSR_DISP26, /* bsr_32. */
209
210 LRW_DISP7, /* lrw16. */
211 LRW2_DISP8, /* lrw16, -mno-bsr16,8 bit offset. */
212 LRW_DISP16, /* lrw32. */
213 };
214
215 unsigned int mach_flag = 0;
216 unsigned int arch_flag = 0;
217 unsigned int other_flag = 0;
218 uint64_t isa_flag = 0;
219 unsigned int dsp_flag = 0;
220
221 typedef struct stack_size_entry
222 {
223 struct stack_size_entry *next;
224 symbolS *function;
225 unsigned int stack_size;
226 } stack_size_entry;
227
228 struct csky_arch_info
229 {
230 const char *name;
231 unsigned int arch_flag;
232 unsigned int bfd_mach_flag;
233 };
234
235 typedef enum
236 {
237 INSN_OPCODE,
238 INSN_OPCODE16F,
239 INSN_OPCODE32F,
240 } inst_flag;
241
242 /* Macro information. */
243 struct csky_macro_info
244 {
245 const char *name;
246 /* How many operands : if operands == 5, all of 1,2,3,4 are ok. */
247 long oprnd_num;
248 uint64_t isa_flag;
249 /* Do the work. */
250 void (*handle_func)(void);
251 };
252
253 struct csky_insn_info
254 {
255 /* Name of the opcode. */
256 char *name;
257 /* Output instruction. */
258 unsigned int inst;
259 /* Pointer for frag. */
260 char *output;
261 /* End of instruction. */
262 char *opcode_end;
263 /* CPU infomations. */
264 const struct csky_cpu_info *cpu;
265 /* Flag for INSN_OPCODE16F, INSN_OPCODE32F, INSN_OPCODE, INSN_MACRO. */
266 inst_flag flag_force;
267 /* Operand number. */
268 int number;
269 struct csky_opcode *opcode;
270 struct csky_macro_info *macro;
271 /* Insn size for check_literal. */
272 unsigned int isize;
273 unsigned int last_isize;
274 /* Max size of insn for relax frag_var. */
275 unsigned int max;
276 /* Indicates which element is in csky_opcode_info op[] array. */
277 int opcode_idx;
278 /* The value of each operand in instruction when layout. */
279 int idx;
280 int val[MAX_OPRND_NUM];
281 struct relax_info
282 {
283 int max;
284 int var;
285 int subtype;
286 } relax;
287 /* The following are used for constant expressions. */
288 expressionS e1;
289 expressionS e2;
290 };
291
292 /* Literal pool data structures. */
293 struct literal
294 {
295 unsigned short refcnt;
296 unsigned int offset;
297 unsigned char ispcrel;
298 unsigned char unused;
299 bfd_reloc_code_real_type r_type;
300 expressionS e;
301 struct tls_addend tls_addend;
302 unsigned char isdouble;
303 uint64_t dbnum;
304 LITTLENUM_TYPE bignum[SIZE_OF_LARGE_NUMBER + 6];
305 };
306
307 static void csky_idly (void);
308 static void csky_rolc (void);
309 static void csky_sxtrb (void);
310 static void csky_movtf (void);
311 static void csky_addc64 (void);
312 static void csky_subc64 (void);
313 static void csky_or64 (void);
314 static void csky_xor64 (void);
315 static void csky_neg (void);
316 static void csky_rsubi (void);
317 static void csky_arith (void);
318 static void csky_decne (void);
319 static void csky_lrw (void);
320
321 static enum bfd_reloc_code_real insn_reloc;
322
323 /* Assembler operand parse errors use these identifiers. */
324
325 enum error_number
326 {
327 /* The following are errors. */
328 ERROR_CREG_ILLEGAL = 0,
329 ERROR_REG_OVER_RANGE,
330 ERROR_FREG_OVER_RANGE,
331 ERROR_VREG_OVER_RANGE,
332 ERROR_GREG_ILLEGAL,
333 ERROR_802J_REG_OVER_RANGE,
334 ERROR_REG_FORMAT,
335 ERROR_REG_LIST,
336 ERROR_IMM_ILLEGAL,
337 ERROR_IMM_OVERFLOW, /* 5 */
338 ERROR_IMM_POWER,
339 ERROR_JMPIX_OVER_RANGE,
340 ERROR_EXP_CREG,
341 ERROR_EXP_GREG,
342 ERROR_EXP_CONSTANT,
343 ERROR_EXP_EVEN_FREG,
344 ERROR_RELOC_ILLEGAL,
345 ERROR_MISSING_OPERAND, /* 10 */
346 ERROR_MISSING_COMMA,
347 ERROR_MISSING_LBRACKET,
348 ERROR_MISSING_RBRACKET,
349 ERROR_MISSING_LSQUARE_BRACKETS,
350 ERROR_MISSING_RSQUARE_BRACKETS, /* 15 */
351 ERROR_MISSING_LANGLE_BRACKETS,
352 ERROR_MISSING_RANGLE_BRACKETS,
353 ERROR_OFFSET_UNALIGNED,
354 ERROR_BAD_END,
355 ERROR_UNDEFINE,
356 ERROR_CPREG_ILLEGAL, /* 20 */
357 ERROR_OPCODE_PSRBIT,
358 ERROR_OPERANDS_ILLEGAL,
359 ERROR_OPERANDS_NUMBER,
360 ERROR_OPCODE_ILLEGAL,
361
362 /* The following are warnings. */
363 WARNING_OPTIONS,
364 WARNING_IDLY,
365
366 /* Error and warning end. */
367 ERROR_NONE,
368 };
369
370 /* Global error state. ARG1 and ARG2 are opaque data interpreted
371 as appropriate for the error code. */
372
373 struct csky_error_state
374 {
375 enum error_number err_num;
376 int opnum;
377 int arg_int;
378 const void *arg1;
379 const void *arg2;
380 } error_state;
381
382 /* This macro is used to set error number and arg1 in the global state. */
383
384 #define SET_ERROR_STRING(err, msg) \
385 do { \
386 if (error_state.err_num > err) \
387 { \
388 error_state.err_num = err; \
389 error_state.arg1 = (void *)msg; \
390 } \
391 } while (0)
392
393 #define SET_ERROR_INTEGER(err, integer) \
394 do { \
395 if (error_state.err_num > err) \
396 { \
397 error_state.err_num = err; \
398 error_state.arg_int = integer; \
399 } \
400 } while (0)
401
402 /* Map error identifiers onto a format string, which will use
403 arg1 and arg2 from the global error state. */
404 struct csky_error_format_map
405 {
406 enum error_number num;
407 const char *fmt;
408 };
409
410 static const struct csky_error_format_map err_formats[] =
411 {
412 {ERROR_CREG_ILLEGAL, "Operand %d error: control register is illegal."},
413 {ERROR_REG_OVER_RANGE, "Operand %d error: r%d register is over range."},
414 {ERROR_FREG_OVER_RANGE, "Operand %d error: vr%d register is over range."},
415 {ERROR_VREG_OVER_RANGE, "Operand %d error: vr%d register is out of range."},
416 {ERROR_GREG_ILLEGAL, "Operand %d error: general register is illegal."},
417 {ERROR_802J_REG_OVER_RANGE, "Operand %d register %s out of range (802j only has registers:0-15,23,24,25,30)"},
418 {ERROR_REG_FORMAT, "Operand %d error: %s."},
419 {ERROR_REG_LIST, "Register list format is illegal."},
420 {ERROR_IMM_ILLEGAL, "Operand %d is not an immediate."},
421 {ERROR_IMM_OVERFLOW, "Operand %d immediate is overflow."},
422 {ERROR_IMM_POWER, "immediate %d is not a power of two"},
423 {ERROR_JMPIX_OVER_RANGE, "The second operand must be 16/24/32/40"},
424 {ERROR_EXP_CREG, "Operand %d error: control register is expected."},
425 {ERROR_EXP_GREG, "Operand %d error: general register is expected."},
426 {ERROR_EXP_CONSTANT, "Operand %d error: constant is expected."},
427 {ERROR_EXP_EVEN_FREG, "Operand %d error: even float register is expected."},
428 {ERROR_RELOC_ILLEGAL, "@%s reloc is not supported"},
429 {ERROR_MISSING_OPERAND, "Operand %d is missing."},
430 {ERROR_MISSING_COMMA, "Missing ','"},
431 {ERROR_MISSING_LBRACKET, "Missing '('"},
432 {ERROR_MISSING_RBRACKET, "Missing ')'"},
433 {ERROR_MISSING_LSQUARE_BRACKETS, "Missing '['"},
434 {ERROR_MISSING_RSQUARE_BRACKETS, "Missing ']'"},
435 {ERROR_MISSING_LANGLE_BRACKETS, "Missing '<'"},
436 {ERROR_MISSING_RANGLE_BRACKETS, "Missing '>'"},
437 {ERROR_OFFSET_UNALIGNED, "Operand %d is unaligned. It must be %d aligned!"},
438 {ERROR_BAD_END, "Operands mismatch, it has a bad end: %s"},
439 {ERROR_UNDEFINE, NULL},
440 {ERROR_CPREG_ILLEGAL, "Operand %d illegal, expect a cpreg(cpr0-cpr63)."},
441 {ERROR_OPCODE_PSRBIT, "The operands must be 'ie'/'ee'/'fe'."},
442 {ERROR_OPERANDS_ILLEGAL, "Operands mismatch: %s."},
443 {ERROR_OPERANDS_NUMBER, "Operands number mismatch, %d operands expected."},
444 {ERROR_OPCODE_ILLEGAL, "The instruction is not recognized."},
445 {WARNING_OPTIONS, "Option %s is not support in %s."},
446 {WARNING_IDLY, "idly %d is encoded to: idly 4 "},
447 {ERROR_NONE, "There is no error."},
448 };
449
450 static int do_pic = 0; /* for jbr/jbf/jbt relax jmpi reloc. */
451 static int do_pff = -1; /* for insert two br ahead of literals. */
452 static int do_force2bsr = -1; /* for jbsr->bsr. */
453 static int do_jsri2bsr = 1; /* for jsri->bsr. */
454 static int do_nolrw = 0; /* lrw to movih & ori, only for V2. */
455 static int do_long_jump = -1; /* control if jbf,jbt,jbr relax to jmpi. */
456 static int do_extend_lrw = -1; /* delete bsr16 in both two options,
457 add btesti16, lrw offset +1 in -melrw. */
458 static int do_func_dump = 0; /* dump literals after every function. */
459 static int do_br_dump = 1; /* work for -mabr/-mno-abr, control the literals dump. */
460 static int do_intr_stack = -1; /* control interrupt stack module, 801&802&803
461 default on, 807&810, default off. */
462 static int float_abi = 0;
463
464 #ifdef INCLUDE_BRANCH_STUB
465 static int do_use_branchstub = -1;
466 #else
467 static int do_use_branchstub = 0;
468 #endif
469
470 /* These are only used for options parsing. Values are bitmasks and are
471 OR'ed into the processor flag bits in md_begin. */
472 static int do_opt_mmp = 0;
473 static int do_opt_mcp = 0;
474 static int do_opt_mcache = 0;
475 static int do_opt_msecurity = 0;
476 static int do_opt_mhard_float = 0;
477 static int do_opt_mtrust = 0;
478 static int do_opt_mdsp = 0;
479 static int do_opt_medsp = 0;
480 static int do_opt_mvdsp = 0;
481
482 const relax_typeS *md_relax_table = NULL;
483 struct literal *literal_insn_offset;
484 static struct literal litpool[MAX_POOL_SIZE];
485 static unsigned poolsize = 0;
486 static unsigned poolnumber = 0;
487 static unsigned long poolspan = 0;
488 static unsigned int SPANPANIC;
489 static unsigned int SPANCLOSE;
490 static unsigned int SPANEXIT;
491
492 static stack_size_entry *all_stack_size_data = NULL;
493 static stack_size_entry **last_stack_size_data = &all_stack_size_data;
494
495 /* Control by ".no_literal_dump N"
496 * 1 : don't dump literal pool between insn1 and insnN+1
497 * 0 : do nothing. */
498 static int do_noliteraldump = 0;
499
500 /* Label for current pool. */
501 static symbolS * poolsym;
502 static char poolname[8];
503
504 static bool mov_r1_before;
505 static bool mov_r1_after;
506
507 const relax_typeS csky_relax_table [] =
508 {
509 /* C-SKY V1 relax table. */
510 {0, 0, 0, 0}, /* RELAX_NONE */
511 {0, 0, 0, 0}, /* RELAX_OVERFLOW */
512 {0, 0, 0, 0},
513 {0, 0, 0, 0},
514
515 /* COND_JUMP */
516 { 0, 0, 0, 0 }, /* UNDEF_DISP */
517 { 2048, -2046, C12_LEN, C (COND_JUMP, DISP32) }, /* DISP12 */
518 { 0, 0, C32_LEN, 0 }, /* DISP32 */
519 { 0, 0, C32_LEN, 0 }, /* UNDEF_WORD_DISP */
520
521 /* UNCD_JUMP */
522 { 0, 0, 0, 0 }, /* UNDEF_DISP */
523 { 2048, -2046, U12_LEN, C (UNCD_JUMP, DISP32) }, /* DISP12 */
524 { 0, 0, U32_LEN, 0 }, /* DISP32 */
525 { 0, 0, U32_LEN, 0 }, /* UNDEF_WORD_DISP */
526
527 /* COND_JUMP_PIC */
528 { 0, 0, 0, 0 }, /* UNDEF_DISP */
529 { 2048, -2046, C12_LEN, C (COND_JUMP_PIC, DISP32) }, /* DISP12 */
530 { 0, 0, C32_LEN_PIC, 0 }, /* DISP32 */
531 { 0, 0, C32_LEN_PIC, 0 }, /* UNDEF_WORD_DISP */
532
533 /* UNCD_JUMP_PIC */
534 { 0, 0, 0, 0 }, /* UNDEF_DISP */
535 { 2048, -2046, U12_LEN, C (UNCD_JUMP_PIC, DISP32) }, /* DISP12 */
536 { 0, 0, U32_LEN_PIC, 0 }, /* DISP32 */
537 { 0, 0, U32_LEN_PIC, 0 }, /* UNDEF_WORD_DISP */
538
539 /* C-SKY V2 relax table. */
540 /* forward backward length more */
541 { 1 KB - 2, -1 KB, COND_DISP10_LEN, COND_DISP16 }, /* COND_DISP10 */
542 { 64 KB - 2, -64 KB, COND_DISP16_LEN, RELAX_OVERFLOW }, /* COND_DISP16 */
543
544 { 1 KB - 2, -1 KB, SCOND_DISP10_LEN, SCOND_DISP16 }, /* SCOND_DISP10 */
545 { 64 KB - 2, -64 KB, SCOND_DISP16_LEN, RELAX_OVERFLOW }, /* SCOND_DISP16 */
546
547 { 1 KB - 2, -1 KB, UNCD_DISP10_LEN, UNCD_DISP16 }, /* UNCD_DISP10 */
548 { 64 KB - 2, -64 KB, UNCD_DISP16_LEN, RELAX_OVERFLOW }, /* UNCD_DISP16 */
549
550 { 1 KB - 2, -1 KB, JCOND_DISP10_LEN, JCOND_DISP16 }, /* JCOND_DISP10 */
551 { 64 KB - 2, -64 KB, JCOND_DISP16_LEN, JCOND_DISP32 }, /* JCOND_DISP16 */
552 { 0, 0, JCOND_DISP32_LEN, RELAX_NONE }, /* JCOND_DISP32 */
553
554 { 1 KB - 2, -1 KB, JUNCD_DISP10_LEN, JUNCD_DISP16 }, /* JUNCD_DISP10 */
555 { 64 KB - 2, -64 KB, JUNCD_DISP16_LEN, JUNCD_DISP32 }, /* JUNCD_DISP16 */
556 { 0, 0, JUNCD_DISP32_LEN, RELAX_NONE }, /* JUNCD_DISP32 */
557
558 { 64 KB - 2, -64 KB, JCOMPZ_DISP16_LEN, JCOMPZ_DISP32 }, /* JCOMPZ_DISP16 */
559 { 0, 0, JCOMPZ_DISP32_LEN, RELAX_NONE }, /* JCOMPZ_DISP32 */
560
561 { 64 MB - 2, -64 MB, BSR_DISP26_LEN, RELAX_OVERFLOW }, /* BSR_DISP26 */
562
563 { 508, 0, LRW_DISP7_LEN, LRW_DISP16 }, /* LRW_DISP7 */
564 { 1016, 0, LRW_DISP7_LEN, LRW_DISP16 }, /* LRW2_DISP8 */
565 { 64 KB, 0, LRW_DISP16_LEN, RELAX_OVERFLOW }, /* LRW_DISP16 */
566
567 };
568
569 static void csky_write_insn (char *ptr, valueT use, int nbytes);
570 void md_number_to_chars (char * buf, valueT val, int n);
571 long md_pcrel_from_section (fixS * fixP, segT seg);
572
573 /* C-SKY architecture table. */
574 const struct csky_arch_info csky_archs[] =
575 {
576 {"ck510", CSKY_ARCH_510, bfd_mach_ck510},
577 {"ck610", CSKY_ARCH_610, bfd_mach_ck610},
578 {"ck801", CSKY_ARCH_801, bfd_mach_ck801},
579 {"ck802", CSKY_ARCH_802, bfd_mach_ck802},
580 {"ck803", CSKY_ARCH_803, bfd_mach_ck803},
581 {"ck807", CSKY_ARCH_807, bfd_mach_ck807},
582 {"ck810", CSKY_ARCH_810, bfd_mach_ck810},
583 {"ck860", CSKY_ARCH_860, bfd_mach_ck860},
584 {NULL, 0, 0}
585 };
586
587 #define CSKY_ARCH_807_BASE CSKY_ARCH_807 | CSKY_ARCH_DSP
588 #define CSKY_ARCH_810_BASE CSKY_ARCH_810 | CSKY_ARCH_DSP
589
590 struct csky_cpu_feature
591 {
592 const char unique;
593 unsigned int arch_flag;
594 uint64_t isa_flag;
595 };
596
597 struct csky_cpu_version
598 {
599 int r;
600 int p;
601 uint64_t isa_flag;
602 };
603
604 #define CSKY_FEATURE_MAX 10
605 #define CSKY_CPU_REVERISON_MAX 10
606
607 struct csky_cpu_info
608 {
609 const char *name;
610 unsigned int arch_flag;
611 uint64_t isa_flag;
612 struct csky_cpu_feature features[CSKY_FEATURE_MAX];
613 struct csky_cpu_version ver[CSKY_CPU_REVERISON_MAX];
614 };
615
616 #define FEATURE_DSP_EXT(isa) \
617 {'e', CSKY_ARCH_DSP, isa}
618 #define FEATURE_DSP(isa) \
619 {'d', CSKY_ARCH_DSP, isa}
620 #define FEATURE_MMU() \
621 {'m', 0, 0}
622 #define FEATURE_VDSP(isa) \
623 {'v', CSKY_ARCH_DSP, isa}
624 #define FEATURE_FLOAT(isa) \
625 {'f', CSKY_ARCH_FLOAT, isa}
626 #define FEATURE_TRUST(isa) \
627 {'t', 0, isa}
628 #define FEATURE_JAVA(isa) \
629 {'j', CSKY_ARCH_JAVA, isa}
630 #define FEATURE_SHIELD(isa) \
631 {'h', 0, isa}
632
633
634 #define CSKY_FEATURES_DEF_NULL() \
635 {{0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}}
636
637 #define CSKY_FEATURES_DEF_e(isa_e) \
638 {FEATURE_DSP_EXT(isa_e), \
639 {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}}
640
641 #define CSKY_FEATURES_DEF_t(isa_t) \
642 {FEATURE_TRUST(isa_t), \
643 {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}}
644
645 #define CSKY_FEATURES_DEF_f(isa_f) \
646 {FEATURE_FLOAT(isa_f), \
647 {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}}
648
649 #define CSKY_FEATURES_DEF_v(isa_v) \
650 {FEATURE_VDSP(isa_v), \
651 {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}}
652
653 #define CSKY_FEATURES_DEF_ef(isa_e, isa_f) \
654 {FEATURE_DSP_EXT(isa_e), \
655 FEATURE_FLOAT(isa_f), \
656 {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}}
657
658 #define CSKY_FEATURES_DEF_jt(isa_j, isa_t) \
659 {FEATURE_JAVA(isa_j), \
660 FEATURE_TRUST(isa_t), \
661 {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}}
662
663 #define CSKY_FEATURES_DEF_efht(isa_e, isa_f, isa_h, isa_t) \
664 {FEATURE_DSP_EXT(isa_e), \
665 FEATURE_FLOAT(isa_f), \
666 FEATURE_SHIELD(isa_h), \
667 FEATURE_TRUST(isa_t), \
668 {0}, {0}, {0}, {0}, {0}, {0}}
669
670 #define CSKY_FEATURES_DEF_efv(isa_e, isa_f, isa_v) \
671 {FEATURE_DSP_EXT(isa_e), \
672 FEATURE_FLOAT(isa_f), \
673 FEATURE_VDSP(isa_v), \
674 {0}, {0}, {0}, {0}, {0}, {0}, {0}}
675
676 #define CSKY_FEATURES_DEF_eft(isa_e, isa_f, isa_t) \
677 {FEATURE_DSP_EXT(isa_e), \
678 FEATURE_FLOAT(isa_f), \
679 FEATURE_TRUST(isa_t), \
680 {0}, {0}, {0}, {0}, {0}, {0}, {0}}
681
682 #define CSKY_FEATURES_DEF_d(isa_d) \
683 {FEATURE_DSP(isa_d), \
684 {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}}
685
686 #define CSKY_FEATURES_DEF_df(isa_d, isa_f) \
687 {FEATURE_DSP(isa_d), \
688 FEATURE_FLOAT(isa_f), \
689 {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}}
690
691 #define CSKY_FEATURES_DEF_ft(isa_f, isa_t) \
692 {FEATURE_FLOAT(isa_f), \
693 FEATURE_TRUST(isa_t), \
694 {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}}
695
696 #define CSKY_FEATURES_DEF_tv(isa_t, isa_v) \
697 {FEATURE_TRUST(isa_t), \
698 FEATURE_VDSP(isa_v), \
699 {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}}
700
701 #define CSKY_FEATURES_DEF_fv(isa_f, isa_v) \
702 {FEATURE_FLOAT(isa_f), \
703 FEATURE_VDSP(isa_v), \
704 {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}}
705
706
707 #define CSKY_FEATURES_DEF_dft(isa_d, isa_f, isa_t) \
708 {FEATURE_DSP(isa_d), \
709 FEATURE_FLOAT(isa_f), \
710 FEATURE_TRUST(isa_t), \
711 {0}, {0}, {0}, {0}, {0}, {0}, {0}}
712
713 #define CSKY_FEATURES_DEF_dfv(isa_d, isa_f, isa_v) \
714 {FEATURE_DSP(isa_d), \
715 FEATURE_FLOAT(isa_f), \
716 FEATURE_VDSP(isa_v), \
717 {0}, {0}, {0}, {0}, {0}, {0}, {0}}
718
719 #define CSKY_FEATURES_DEF_ftv(isa_f, isa_t, isa_v) \
720 {FEATURE_FLOAT(isa_f), \
721 FEATURE_TRUST(isa_t), \
722 FEATURE_VDSP(isa_v), \
723 {0}, {0}, {0}, {0}, {0}, {0}, {0}}
724
725 #define CSKY_FEATURES_DEF_eftv(isa_e, isa_f, isa_t, isa_v) \
726 {FEATURE_DSP_EXT(isa_e), \
727 FEATURE_FLOAT(isa_f), \
728 FEATURE_TRUST(isa_t), \
729 FEATURE_VDSP(isa_v), \
730 {0}, {0}, {0}, {0}, {0}, {0}}
731
732
733 #define CSKY_CPU_REVERISON_r0p0(isa) \
734 {0, 0, 0}
735 #define CSKY_CPU_REVERISON_r1p0(isa) \
736 {1, 0, isa}
737 #define CSKY_CPU_REVERISON_r2p0(isa) \
738 {2, 0, isa}
739 #define CSKY_CPU_REVERISON_r3p0(isa) \
740 {3, 0, isa}
741
742 #define CSKY_CPU_REVERISON_RESERVED() \
743 {{0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}}
744
745 #define CSKY_CPU_REVERISON_R3(isa1, isa2, isa3) \
746 {CSKY_CPU_REVERISON_r1p0(isa1), \
747 CSKY_CPU_REVERISON_r2p0(isa2), \
748 CSKY_CPU_REVERISON_r3p0(isa3), \
749 {0}, {0}, {0}, {0}, {0}, {0}, {0}}
750
751 /* CSKY cpus table. */
752 const struct csky_cpu_info csky_cpus[] =
753 {
754 #define CSKYV1_ISA_DSP (CSKY_ISA_DSP | CSKY_ISA_MAC_DSP)
755 #define CSKY_ISA_510 (CSKYV1_ISA_E1)
756 #define CSKY_ISA_610 (CSKYV1_ISA_E1 | CSKY_ISA_CP)
757 {"ck510",
758 CSKY_ARCH_510,
759 CSKY_ISA_510,
760 CSKY_FEATURES_DEF_e(CSKYV1_ISA_DSP),
761 CSKY_CPU_REVERISON_RESERVED()},
762 {"ck520",
763 CSKY_ARCH_510 | CSKY_ARCH_MAC,
764 CSKY_ISA_510 | CSKY_ISA_MAC | CSKY_ISA_MAC_DSP,
765 CSKY_FEATURES_DEF_NULL(),
766 CSKY_CPU_REVERISON_RESERVED()},
767 {"ck610", CSKY_ARCH_610, CSKY_ISA_610,
768 CSKY_FEATURES_DEF_ef(CSKYV1_ISA_DSP, CSKY_ISA_FLOAT_E1),
769 CSKY_CPU_REVERISON_RESERVED()},
770 {"ck620",
771 CSKY_ARCH_610 | CSKY_ARCH_MAC,
772 CSKY_ISA_610 | CSKY_ISA_MAC | CSKY_ISA_MAC_DSP,
773 CSKY_FEATURES_DEF_NULL(),
774 CSKY_CPU_REVERISON_RESERVED()},
775
776 #define CSKY_ISA_801 (CSKYV2_ISA_E1 | CSKY_ISA_TRUST)
777 #define CSKYV2_ISA_DSP (CSKY_ISA_DSP | CSKY_ISA_DSP_1E2 | CSKY_ISA_DSPE60)
778 {"ck801",
779 CSKY_ARCH_801,
780 CSKY_ISA_801,
781 CSKY_FEATURES_DEF_t(0),
782 CSKY_CPU_REVERISON_RESERVED()},
783 #define CSKY_ISA_802 (CSKY_ISA_801 | CSKYV2_ISA_1E2 | CSKY_ISA_NVIC)
784 {"ck802",
785 CSKY_ARCH_802,
786 CSKY_ISA_802,
787 CSKY_FEATURES_DEF_jt(CSKY_ISA_JAVA, 0),
788 CSKY_CPU_REVERISON_RESERVED()},
789 #define CSKY_ISA_803 (CSKY_ISA_802 | CSKYV2_ISA_2E3 | CSKY_ISA_MP)
790 #define CSKY_ISA_803R1 (CSKYV2_ISA_3E3R1)
791 #define CSKY_ISA_803R2 (CSKYV2_ISA_3E3R1 | CSKYV2_ISA_3E3R2)
792 #define CSKY_ISA_803R3 (CSKYV2_ISA_3E3R1 | CSKYV2_ISA_3E3R2 | CSKYV2_ISA_3E3R3)
793 #define CSKY_ISA_FLOAT_803 (CSKY_ISA_FLOAT_E1 | CSKY_ISA_FLOAT_1E3)
794 #define CSKY_ISA_EDSP (CSKYV2_ISA_3E3R1 | CSKYV2_ISA_3E3R3 | CSKY_ISA_DSP_ENHANCE)
795 {"ck803s",
796 CSKY_ARCH_803,
797 CSKY_ISA_803 | CSKY_ISA_803R1,
798 CSKY_FEATURES_DEF_eft(CSKYV2_ISA_DSP, CSKY_ISA_FLOAT_803, 0),
799 CSKY_CPU_REVERISON_RESERVED()},
800 {"ck803",
801 CSKY_ARCH_803,
802 CSKY_ISA_803,
803 CSKY_FEATURES_DEF_efht(CSKYV2_ISA_DSP, CSKY_ISA_FLOAT_803, 0, 0),
804 CSKY_CPU_REVERISON_R3(CSKY_ISA_803R1, CSKY_ISA_803R2, CSKY_ISA_803R3)},
805 #define CSKY_ISA_804 (CSKY_ISA_803 | CSKY_ISA_803R3)
806 {"ck804",
807 CSKY_ARCH_804,
808 CSKY_ISA_804,
809 CSKY_FEATURES_DEF_efht(CSKY_ISA_EDSP, CSKY_ISA_FLOAT_803, 0, 0),
810 CSKY_CPU_REVERISON_RESERVED()},
811 #define CSKY_ISA_805 (CSKY_ISA_804 | CSKY_ISA_VDSP_2)
812 #define CSKY_ARCH_805V (CSKY_ARCH_805 | CSKY_ARCH_DSP)
813 #define CSKY_ISA_FLOAT_805 CSKY_ISA_FLOAT_803
814 {"ck805",
815 CSKY_ARCH_805,
816 CSKY_ISA_805,
817 CSKY_FEATURES_DEF_eft(CSKY_ISA_EDSP, CSKY_ISA_FLOAT_805, 0),
818 CSKY_CPU_REVERISON_RESERVED()},
819 #define CSKY_ISA_807 (CSKY_ISA_803 | CSKYV2_ISA_3E7 | CSKY_ISA_MP_1E2 | CSKY_ISA_CACHE | CSKYV2_ISA_DSP)
820 #define CSKY_ISA_FLOAT_807 (CSKY_ISA_FLOAT_803 | CSKY_ISA_FLOAT_3E4 | CSKY_ISA_FLOAT_1E2)
821 {"ck807",
822 CSKY_ARCH_807,
823 CSKY_ISA_807,
824 CSKY_FEATURES_DEF_ef(CSKYV2_ISA_DSP, CSKY_ISA_FLOAT_807),
825 CSKY_CPU_REVERISON_RESERVED()},
826 #define CSKY_ISA_810 (CSKY_ISA_807 | CSKYV2_ISA_7E10)
827 #define CSKY_ISA_FLOAT_810 (CSKY_ISA_FLOAT_E1 | CSKY_ISA_FLOAT_1E2)
828 {"ck810v",
829 CSKY_ARCH_810 | CSKY_ARCH_DSP,
830 CSKY_ISA_810 | CSKY_ISA_VDSP,
831 CSKY_FEATURES_DEF_NULL (),
832 CSKY_CPU_REVERISON_RESERVED()},
833 {"ck810",
834 CSKY_ARCH_810,
835 CSKY_ISA_810,
836 CSKY_FEATURES_DEF_eftv(0, CSKY_ISA_FLOAT_810, 0, CSKY_ISA_VDSP),
837 CSKY_CPU_REVERISON_RESERVED()},
838 #define CSKY_ISA_860 ((CSKY_ISA_810 & ~(CSKYV2_ISA_DSP)) | CSKYV2_ISA_10E60 | CSKY_ISA_803R3 | CSKY_ISA_DSPE60)
839 #define CSKY_ISA_860F (CSKY_ISA_860 | CSKY_ISA_FLOAT_7E60)
840 #define CSKY_ISA_VDSP_860 (CSKY_ISA_VDSP_2)
841 {"ck860v",
842 CSKY_ARCH_860 | CSKY_ARCH_DSP,
843 CSKY_ISA_860 | CSKY_ISA_VDSP_860,
844 CSKY_FEATURES_DEF_f(CSKY_ISA_FLOAT_7E60),
845 CSKY_CPU_REVERISON_RESERVED()},
846 {"ck860",
847 CSKY_ARCH_860,
848 CSKY_ISA_860,
849 CSKY_FEATURES_DEF_fv(CSKY_ISA_FLOAT_7E60, CSKY_ISA_VDSP_860),
850 CSKY_CPU_REVERISON_RESERVED()},
851
852 /* It is a special cpu, support all instructions. */
853 #define CSKY_ISA_800 (CSKY_ISA_860 | CSKY_ISA_810 | CSKY_ISA_807 | CSKY_ISA_803)
854 {"ck800",
855 CSKY_ARCH_800,
856 CSKY_ISA_800,
857 CSKY_FEATURES_DEF_NULL(),
858 CSKY_CPU_REVERISON_RESERVED()},
859
860
861 #define CSKY_ISA_E801 (CSKY_ISA_801)
862 #define CSKY_ISA_E802 (CSKY_ISA_E801 | CSKYV2_ISA_1E2 | CSKY_ISA_NVIC)
863 #define CSKY_ISA_E803 (CSKY_ISA_E802 | CSKYV2_ISA_2E3 | CSKY_ISA_MP | CSKYV2_ISA_3E3R1 | CSKYV2_ISA_3E3R2 | CSKYV2_ISA_3E3R3)
864 #define CSKY_ISA_E804 (CSKY_ISA_E803)
865 #define CSKY_ISA_FLOAT_V1 (CSKY_ISA_FLOAT_E1 | CSKY_ISA_FLOAT_1E3)
866 {"e801",
867 CSKY_ARCH_801,
868 CSKY_ISA_E801,
869 CSKY_FEATURES_DEF_NULL(),
870 CSKY_CPU_REVERISON_RESERVED()},
871 {"e802",
872 CSKY_ARCH_802,
873 CSKY_ISA_E802,
874 CSKY_FEATURES_DEF_t(0),
875 CSKY_CPU_REVERISON_RESERVED()},
876 {"e803",
877 CSKY_ARCH_803,
878 CSKY_ISA_E803,
879 CSKY_FEATURES_DEF_t(0),
880 CSKY_CPU_REVERISON_RESERVED()},
881 {"e804",
882 CSKY_ARCH_804,
883 CSKY_ISA_E804,
884 CSKY_FEATURES_DEF_dft(CSKY_ISA_EDSP, CSKY_ISA_FLOAT_V1, 0),
885 CSKY_CPU_REVERISON_RESERVED()},
886
887 #define CSKY_ISA_S802 (CSKY_ISA_E801 | CSKYV2_ISA_1E2 | CSKY_ISA_NVIC | CSKY_ISA_TRUST)
888 #define CSKY_ISA_S803 (CSKY_ISA_S802 | CSKYV2_ISA_2E3 | CSKY_ISA_MP | CSKYV2_ISA_3E3R1 | CSKYV2_ISA_3E3R2 | CSKYV2_ISA_3E3R3)
889 {"s802",
890 CSKY_ARCH_802,
891 CSKY_ISA_S802,
892 CSKY_FEATURES_DEF_t(0),
893 CSKY_CPU_REVERISON_RESERVED()},
894 {"s803",
895 CSKY_ARCH_803,
896 CSKY_ISA_S803,
897 CSKY_FEATURES_DEF_t(0),
898 CSKY_CPU_REVERISON_RESERVED()},
899 #define CSKY_ISA_I805 (CSKY_ISA_S803)
900 {"i805",
901 CSKY_ARCH_805 | CSKY_ARCH_DSP,
902 CSKY_ISA_I805 | CSKY_ISA_VDSP_2,
903 CSKY_FEATURES_DEF_ft(CSKY_ISA_FLOAT_V1, 0),
904 CSKY_CPU_REVERISON_RESERVED()},
905 #define CSKYV2_ISA_DSP (CSKY_ISA_DSP | CSKY_ISA_DSP_1E2 | CSKY_ISA_DSPE60)
906 #define CSKY_ISA_C807 (CSKY_ISA_E802 | CSKYV2_ISA_2E3 | CSKY_ISA_MP | CSKYV2_ISA_3E7 | CSKY_ISA_MP_1E2 | CSKY_ISA_CACHE | CSKYV2_ISA_DSP)
907 #define CSKY_ISA_FLOAT_C807 (CSKY_ISA_FLOAT_V1 | CSKY_ISA_FLOAT_3E4 | CSKY_ISA_FLOAT_1E2)
908 #define CSKY_ISA_FLOAT_C810 (CSKY_ISA_FLOAT_E1 | CSKY_ISA_FLOAT_1E2)
909 #define CSKY_ARCH_C810 (CSKY_ARCH_810 | CSKY_ARCH_FLOAT)
910 #define CSKY_ISA_C810 (CSKY_ISA_C807 | CSKYV2_ISA_7E10 | CSKY_ISA_FLOAT_C810)
911 #define CSKY_ARCH_C860 (CSKY_ARCH_860 | CSKY_ARCH_FLOAT)
912 #define CSKY_ISA_C860 (CSKY_ISA_860 | CSKY_ISA_FLOAT_7E60)
913 {"c807",
914 CSKY_ARCH_807,
915 CSKY_ISA_C807,
916 CSKY_FEATURES_DEF_fv(CSKY_ISA_FLOAT_C807, CSKY_ISA_VDSP),
917 CSKY_CPU_REVERISON_RESERVED()},
918 {"c810",
919 CSKY_ARCH_C810,
920 CSKY_ISA_C810,
921 CSKY_FEATURES_DEF_tv(0, CSKY_ISA_VDSP),
922 CSKY_CPU_REVERISON_RESERVED()},
923 {"c860",
924 CSKY_ARCH_C860,
925 CSKY_ISA_C860,
926 CSKY_FEATURES_DEF_v(CSKY_ISA_VDSP_2),
927 CSKY_CPU_REVERISON_RESERVED()},
928 #define CSKY_ISA_R807 (CSKY_ISA_E802 | CSKYV2_ISA_2E3 | CSKY_ISA_MP | CSKYV2_ISA_3E7 | CSKY_ISA_MP_1E2 | CSKY_ISA_CACHE | CSKYV2_ISA_DSP)
929 #define CSKY_ISA_FLOAT_R807 (CSKY_ISA_FLOAT_V1 | CSKY_ISA_FLOAT_3E4 | CSKY_ISA_FLOAT_1E2)
930 {"r807",
931 CSKY_ARCH_807,
932 CSKY_ISA_R807,
933 CSKY_FEATURES_DEF_f(CSKY_ISA_FLOAT_R807),
934 CSKY_CPU_REVERISON_RESERVED()},
935
936 /* Start of private CPUs. */
937 /* End of private CPUs. */
938
939 {NULL},
940 };
941
942 int md_short_jump_size = 2;
943 int md_long_jump_size = 4;
944
945 /* This array holds the chars that always start a comment. If the
946 pre-processor is disabled, these aren't very useful. */
947 const char comment_chars[] = "#";
948
949 /* This array holds the chars that only start a comment at the beginning of
950 a line. If the line seems to have the form '# 123 filename'
951 .line and .file directives will appear in the pre-processed output. */
952 /* Note that input_file.c hand checks for '#' at the beginning of the
953 first line of the input file. This is because the compiler outputs
954 #NO_APP at the beginning of its output. */
955 /* Also note that comments like this one will always work. */
956 const char line_comment_chars[] = "#";
957
958 const char line_separator_chars[] = ";";
959
960 /* Chars that can be used to separate mant
961 from exp in floating point numbers. */
962 const char EXP_CHARS[] = "eE";
963
964 /* Chars that mean this number is a floating point constant.
965 As in 0f12.456
966 or 0d1.2345e12 */
967
968 const char FLT_CHARS[] = "rRsSfFdDxXeEpP";
969
970 const char *md_shortopts = "";
971
972 struct option md_longopts[] = {
973 #define OPTION_MARCH (OPTION_MD_BASE + 0)
974 {"march", required_argument, NULL, OPTION_MARCH},
975 #define OPTION_MCPU (OPTION_MD_BASE + 1)
976 {"mcpu", required_argument, NULL, OPTION_MCPU},
977 #define OPTION_FLOAT_ABI (OPTION_MD_BASE + 2)
978 {"mfloat-abi", required_argument, NULL, OPTION_FLOAT_ABI},
979
980 /* Remaining options just set boolean flags. */
981 {"EL", no_argument, &target_big_endian, 0},
982 {"mlittle-endian", no_argument, &target_big_endian, 0},
983 {"EB", no_argument, &target_big_endian, 1},
984 {"mbig-endian", no_argument, &target_big_endian, 1},
985 {"fpic", no_argument, &do_pic, 1},
986 {"pic", no_argument, &do_pic, 1},
987 {"mljump", no_argument, &do_long_jump, 1},
988 {"mno-ljump", no_argument, &do_long_jump, 0},
989 {"force2bsr", no_argument, &do_force2bsr, 1},
990 {"mforce2bsr", no_argument, &do_force2bsr, 1},
991 {"no-force2bsr", no_argument, &do_force2bsr, 0},
992 {"mno-force2bsr", no_argument, &do_force2bsr, 0},
993 {"jsri2bsr", no_argument, &do_jsri2bsr, 1},
994 {"mjsri2bsr", no_argument, &do_jsri2bsr, 1},
995 {"no-jsri2bsr", no_argument, &do_jsri2bsr, 0},
996 {"mno-jsri2bsr", no_argument, &do_jsri2bsr, 0},
997 {"mnolrw", no_argument, &do_nolrw, 1},
998 {"mno-lrw", no_argument, &do_nolrw, 1},
999 {"melrw", no_argument, &do_extend_lrw, 1},
1000 {"mno-elrw", no_argument, &do_extend_lrw, 0},
1001 {"mlaf", no_argument, &do_func_dump, 1},
1002 {"mliterals-after-func", no_argument, &do_func_dump, 1},
1003 {"mno-laf", no_argument, &do_func_dump, 0},
1004 {"mno-literals-after-func", no_argument, &do_func_dump, 0},
1005 {"mlabr", no_argument, &do_br_dump, 1},
1006 {"mliterals-after-br", no_argument, &do_br_dump, 1},
1007 {"mno-labr", no_argument, &do_br_dump, 0},
1008 {"mnoliterals-after-br", no_argument, &do_br_dump, 0},
1009 {"mistack", no_argument, &do_intr_stack, 1},
1010 {"mno-istack", no_argument, &do_intr_stack, 0},
1011 #ifdef INCLUDE_BRANCH_STUB
1012 {"mbranch-stub", no_argument, &do_use_branchstub, 1},
1013 {"mno-branch-stub", no_argument, &do_use_branchstub, 0},
1014 #endif
1015 {"mhard-float", no_argument, &do_opt_mhard_float, CSKY_ARCH_FLOAT},
1016 {"mmp", no_argument, &do_opt_mmp, CSKY_ARCH_MP},
1017 {"mcp", no_argument, &do_opt_mcp, CSKY_ARCH_CP},
1018 {"mcache", no_argument, &do_opt_mcache, CSKY_ARCH_CACHE},
1019 {"msecurity", no_argument, &do_opt_msecurity, CSKY_ARCH_MAC},
1020 {"mtrust", no_argument, &do_opt_mtrust, CSKY_ISA_TRUST},
1021 {"mdsp", no_argument, &do_opt_mdsp, CSKY_DSP_FLAG_V1},
1022 {"medsp", no_argument, &do_opt_medsp, CSKY_DSP_FLAG_V2},
1023 {"mvdsp", no_argument, &do_opt_mvdsp, CSKY_ISA_VDSP},
1024 };
1025
1026 size_t md_longopts_size = sizeof (md_longopts);
1027
1028 static struct csky_insn_info csky_insn;
1029
1030 static htab_t csky_opcodes_hash;
1031 static htab_t csky_macros_hash;
1032
1033 static struct csky_macro_info v1_macros_table[] =
1034 {
1035 {"idly", 1, CSKYV1_ISA_E1, csky_idly},
1036 {"rolc", 2, CSKYV1_ISA_E1, csky_rolc},
1037 {"rotlc", 2, CSKYV1_ISA_E1, csky_rolc},
1038 {"sxtrb0", 2, CSKYV1_ISA_E1, csky_sxtrb},
1039 {"sxtrb1", 2, CSKYV1_ISA_E1, csky_sxtrb},
1040 {"sxtrb2", 2, CSKYV1_ISA_E1, csky_sxtrb},
1041 {"movtf", 3, CSKYV1_ISA_E1, csky_movtf},
1042 {"addc64", 3, CSKYV1_ISA_E1, csky_addc64},
1043 {"subc64", 3, CSKYV1_ISA_E1, csky_subc64},
1044 {"or64", 3, CSKYV1_ISA_E1, csky_or64},
1045 {"xor64", 3, CSKYV1_ISA_E1, csky_xor64},
1046 {NULL,0,0,0}
1047 };
1048
1049 static struct csky_macro_info v2_macros_table[] =
1050 {
1051 {"neg", 1, CSKYV2_ISA_E1, csky_neg},
1052 {"rsubi", 2, CSKYV2_ISA_1E2, csky_rsubi},
1053 {"incf", 1, CSKYV2_ISA_1E2, csky_arith},
1054 {"inct", 1, CSKYV2_ISA_1E2, csky_arith},
1055 {"decf", 1, CSKYV2_ISA_2E3, csky_arith},
1056 {"decgt", 1, CSKYV2_ISA_2E3, csky_arith},
1057 {"declt", 1, CSKYV2_ISA_2E3, csky_arith},
1058 {"decne", 1, CSKYV2_ISA_1E2, csky_decne},
1059 {"dect", 1, CSKYV2_ISA_1E2, csky_arith},
1060 {"lslc", 1, CSKYV2_ISA_1E2, csky_arith},
1061 {"lsrc", 1, CSKYV2_ISA_1E2, csky_arith},
1062 {"xsr", 1, CSKYV2_ISA_1E2, csky_arith},
1063 {NULL,0,0,0}
1064 };
1065
1066 /* For option -mnolrw, replace lrw by movih & ori. */
1067 static struct csky_macro_info v2_lrw_macro_opcode =
1068 {"lrw", 2, CSKYV2_ISA_1E2, csky_lrw};
1069
1070 /* This function is used to show errors or warnings. */
1071
1072 static void
1073 csky_show_error (enum error_number err, int idx, void *arg1, void *arg2)
1074 {
1075 if (err == ERROR_NONE)
1076 return;
1077
1078 switch (err)
1079 {
1080 case ERROR_REG_LIST:
1081 case ERROR_OPCODE_PSRBIT:
1082 case ERROR_OPCODE_ILLEGAL:
1083 case ERROR_JMPIX_OVER_RANGE:
1084 case ERROR_MISSING_COMMA:
1085 case ERROR_MISSING_LBRACKET:
1086 case ERROR_MISSING_RBRACKET:
1087 case ERROR_MISSING_LSQUARE_BRACKETS:
1088 case ERROR_MISSING_RSQUARE_BRACKETS:
1089 case ERROR_MISSING_LANGLE_BRACKETS:
1090 case ERROR_MISSING_RANGLE_BRACKETS:
1091 /* Add NULL to fix warnings. */
1092 as_bad (_(err_formats[err].fmt), NULL);
1093 break;
1094 case ERROR_CREG_ILLEGAL:
1095 case ERROR_GREG_ILLEGAL:
1096 case ERROR_IMM_ILLEGAL:
1097 case ERROR_IMM_OVERFLOW:
1098 case ERROR_EXP_CREG:
1099 case ERROR_EXP_GREG:
1100 case ERROR_EXP_CONSTANT:
1101 case ERROR_EXP_EVEN_FREG:
1102 case ERROR_MISSING_OPERAND:
1103 case ERROR_CPREG_ILLEGAL:
1104 as_bad (_(err_formats[err].fmt), idx);
1105 break;
1106 case ERROR_OPERANDS_NUMBER:
1107 case ERROR_IMM_POWER:
1108 as_bad (_(err_formats[err].fmt), error_state.arg_int);
1109 break;
1110
1111 case ERROR_OFFSET_UNALIGNED:
1112 as_bad (_(err_formats[err].fmt), idx, error_state.arg_int);
1113 break;
1114 case ERROR_RELOC_ILLEGAL:
1115 case ERROR_BAD_END:
1116 case ERROR_OPERANDS_ILLEGAL:
1117 as_bad (_(err_formats[err].fmt), (char *)arg1);
1118 break;
1119 case ERROR_REG_OVER_RANGE:
1120 case ERROR_FREG_OVER_RANGE:
1121 case ERROR_VREG_OVER_RANGE:
1122 as_bad (_(err_formats[err].fmt), idx, error_state.arg_int);
1123 break;
1124 case ERROR_802J_REG_OVER_RANGE:
1125 case ERROR_REG_FORMAT:
1126 as_bad (_(err_formats[err].fmt), idx, (char *)arg1);
1127 break;
1128 case ERROR_UNDEFINE:
1129 /* Add NULL to fix warnings. */
1130 as_bad ((char *)arg1, NULL);
1131 break;
1132 case WARNING_IDLY:
1133 as_warn (_(err_formats[err].fmt), (long)arg1);
1134 break;
1135 case WARNING_OPTIONS:
1136 as_warn (_(err_formats[err].fmt), (char *)arg1, (char *)arg2);
1137 break;
1138 default:
1139 break;
1140 }
1141 }
1142
1143 /* Handle errors in branch relaxation. */
1144
1145 static void
1146 csky_branch_report_error (const char* file, unsigned int line,
1147 symbolS* sym, offsetT val)
1148 {
1149 as_bad_where (file ? file : _("unknown"),
1150 line,
1151 _("pcrel offset for branch to %s too far (0x%lx)"),
1152 sym ? S_GET_NAME (sym) : _("<unknown>"),
1153 (long) val);
1154 }
1155
1156 /* Set appropriate flags for the cpu matching STR. */
1157
1158 static void
1159 parse_cpu (const char *str)
1160 {
1161 int i = 0;
1162
1163 for (; csky_cpus[i].name != NULL; i++)
1164 if (strncasecmp (str, csky_cpus[i].name, strlen (csky_cpus[i].name)) == 0)
1165 {
1166 csky_insn.cpu = &csky_cpus[i];
1167 mach_flag |= csky_cpus[i].arch_flag;
1168 isa_flag = csky_cpus[i].isa_flag;
1169 const char *s = str + strlen (csky_cpus[i].name);
1170 while (*s)
1171 {
1172 const struct csky_cpu_feature *feature = csky_cpus[i].features;
1173 const struct csky_cpu_version *version = csky_cpus[i].ver;
1174 char *next;
1175
1176 if (*s == 'r')
1177 {
1178 s++;
1179 while (version->r)
1180 {
1181 if (version->r == strtol (s, &next, 10))
1182 break;
1183 version++;
1184 }
1185 if (version->r)
1186 {
1187 isa_flag |= version->isa_flag;
1188 s = next;
1189 }
1190 else
1191 goto unknown_cpu;
1192 isa_flag = isa_flag & ~CSKYV2_ISA_DSP;
1193 isa_flag |= CSKY_ISA_EDSP;
1194 continue;
1195 }
1196
1197 /* Parse csky features. */
1198 while (feature->unique)
1199 {
1200 if (feature->unique == *s)
1201 break;
1202 feature++;
1203 }
1204 if (feature->unique)
1205 {
1206 isa_flag |= feature->isa_flag;
1207 mach_flag |= feature->arch_flag;
1208 }
1209 else
1210 goto unknown_cpu;
1211
1212 s++;
1213 }
1214 return;
1215 }
1216
1217 unknown_cpu:
1218 as_bad (_("unknown cpu `%s'"), str);
1219 }
1220
1221 /* Set appropriate flags for the arch matching STR. */
1222
1223 static void
1224 parse_arch (const char *str)
1225 {
1226 int i = 0;
1227 for (; csky_cpus[i].name != NULL; i++)
1228 if (strcasecmp (str, csky_cpus[i].name) == 0)
1229 {
1230 csky_insn.cpu = &csky_cpus[i];
1231 arch_flag |= csky_cpus[i].arch_flag;
1232 isa_flag |= csky_cpus[i].isa_flag;
1233 return;
1234 }
1235 as_bad (_("unknown architecture `%s'"), str);
1236 }
1237
1238 struct csky_option_value_table
1239 {
1240 const char *name;
1241 long value;
1242 };
1243
1244 static const struct csky_option_value_table csky_float_abis[] =
1245 {
1246 {"hard", VAL_CSKY_FPU_ABI_HARD},
1247 {"softfp", VAL_CSKY_FPU_ABI_SOFTFP},
1248 {"soft", VAL_CSKY_FPU_ABI_SOFT},
1249 {NULL, 0}
1250 };
1251
1252 static bool
1253 parse_float_abi (const char *str)
1254 {
1255 const struct csky_option_value_table * opt;
1256
1257 for (opt = csky_float_abis; opt->name != NULL; opt++)
1258 if (strcasecmp (opt->name, str) == 0)
1259 {
1260 float_abi = opt->value;
1261 return true;
1262 }
1263
1264 as_bad (_("unknown floating point abi `%s'\n"), str);
1265 return false;
1266 }
1267
1268 #ifdef OBJ_ELF
1269 /* Implement the TARGET_FORMAT macro. */
1270
1271 const char *
1272 elf32_csky_target_format (void)
1273 {
1274 return (target_big_endian
1275 ? "elf32-csky-big"
1276 : "elf32-csky-little");
1277 }
1278 #endif
1279
1280 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
1281 for use in the a.out file, and stores them in the array pointed to by buf.
1282 This knows about the endian-ness of the target machine and does
1283 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
1284 2 (short) and 4 (long) Floating numbers are put out as a series of
1285 LITTLENUMS (shorts, here at least). */
1286
1287 void
1288 md_number_to_chars (char * buf, valueT val, int n)
1289 {
1290 if (target_big_endian)
1291 number_to_chars_bigendian (buf, val, n);
1292 else
1293 number_to_chars_littleendian (buf, val, n);
1294 }
1295
1296 /* Get a log2(val). */
1297
1298 static int
1299 csky_log_2 (unsigned int val)
1300 {
1301 int log = -1;
1302 if ((val & (val - 1)) == 0)
1303 for (; val; val >>= 1)
1304 log ++;
1305 else
1306 csky_show_error (ERROR_IMM_POWER, 0, (void *)(long)val, NULL);
1307 return log;
1308 }
1309
1310 /* Output one instruction to the buffer at PTR. */
1311
1312 static void
1313 csky_write_insn (char *ptr, valueT use, int nbytes)
1314 {
1315 if (nbytes == 2)
1316 md_number_to_chars (ptr, use, nbytes);
1317 else /* 32-bit instruction. */
1318 {
1319 /* Significant figures are in low bits. */
1320 md_number_to_chars (ptr, use >> 16, 2);
1321 md_number_to_chars (ptr + 2, use & 0xFFFF, 2);
1322 }
1323 }
1324
1325 /* Read an NBYTES instruction from the buffer at PTR. NBYTES should
1326 be either 2 or 4. This function is used in branch relaxation. */
1327
1328 static valueT
1329 csky_read_insn (char *ptr, int nbytes)
1330 {
1331 unsigned char *uptr = (unsigned char *)ptr;
1332 valueT v = 0;
1333 int lo, hi; /* hi/lo byte index in binary stream. */
1334
1335 if (target_big_endian)
1336 {
1337 hi = 0;
1338 lo = 1;
1339 }
1340 else
1341 {
1342 hi = 1;
1343 lo = 0;
1344 }
1345 v = uptr[lo] | (uptr[hi] << 8);
1346 if (nbytes == 4)
1347 {
1348 v <<= 16;
1349 v |= uptr[lo + 2] | (uptr[hi + 2] << 8);
1350 }
1351 return v;
1352 }
1353
1354 /* Construct a label name into S from the 3-character prefix P and
1355 number N formatted as a 4-digit hex number. */
1356
1357 static void
1358 make_internal_label (char *s, const char *p, int n)
1359 {
1360 static const char hex[] = "0123456789ABCDEF";
1361
1362 s[0] = p[0];
1363 s[1] = p[1];
1364 s[2] = p[2];
1365 s[3] = hex[(n >> 12) & 0xF];
1366 s[4] = hex[(n >> 8) & 0xF];
1367 s[5] = hex[(n >> 4) & 0xF];
1368 s[6] = hex[(n) & 0xF];
1369 s[7] = 0;
1370 }
1371
1372 /* md_operand is a no-op on C-SKY; we do everything elsewhere. */
1373
1374 void
1375 md_operand (expressionS *expressionP ATTRIBUTE_UNUSED)
1376 {
1377 return;
1378 }
1379
1380 /* Under ELF we need to default _GLOBAL_OFFSET_TABLE.
1381 Otherwise we have no need to default values of symbols. */
1382
1383 symbolS *
1384 md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
1385 {
1386 #ifdef OBJ_ELF
1387 /* TODO: */
1388 #endif
1389 return NULL;
1390 }
1391
1392 /* Use IEEE format for floating-point constants. */
1393
1394 const char *
1395 md_atof (int type, char *litP, int *sizeP)
1396 {
1397 return ieee_md_atof (type, litP, sizeP, target_big_endian);
1398 }
1399
1400 /* Print option help to FP. */
1401
1402 void
1403 md_show_usage (FILE *fp)
1404 {
1405 int i, n;
1406 const int margin = 48;
1407
1408 fprintf (fp, _("C-SKY assembler options:\n"));
1409
1410 fprintf (fp, _("\
1411 -march=ARCH select architecture ARCH:"));
1412 for (i = 0, n = margin; csky_archs[i].name != NULL; i++)
1413 {
1414 int l = strlen (csky_archs[i].name);
1415 if (n + l >= margin)
1416 {
1417 fprintf (fp, "\n\t\t\t\t");
1418 n = l;
1419 }
1420 else
1421 {
1422 fprintf (fp, " ");
1423 n += l + 1;
1424 }
1425 fprintf (fp, "%s", csky_archs[i].name);
1426 }
1427 fprintf (fp, "\n");
1428
1429 fprintf (fp, _("\
1430 -mcpu=CPU select processor CPU:"));
1431 const struct csky_cpu_feature *feature = NULL;
1432 const struct csky_cpu_version *version = NULL;
1433 for (i = 0; csky_cpus[i].name != NULL; i++)
1434 {
1435 fprintf (fp, "\t\t\t\t%s", csky_cpus[i].name);
1436 feature = csky_cpus[i].features;
1437 version = csky_cpus[i].ver;
1438 while (feature->unique)
1439 {
1440 if ((feature + 1)->unique)
1441 fprintf (fp, "[%c]", feature->unique);
1442 feature++;
1443 }
1444 while (version->r)
1445 {
1446 if (csky_cpus[i].name[0] == 'c'
1447 && csky_cpus[i].name[1] == 'k')
1448 fprintf (fp, "[r%d]", version->r);
1449 else
1450 fprintf (fp, "[-r%dp%d]", version->r, version->p);
1451 version++;
1452 }
1453 }
1454 fprintf (fp, "\n");
1455
1456 fprintf (fp, _("\
1457 -mfloat-abi=ABI select float ABI:"));
1458 for (i = 0, n = margin; csky_float_abis[i].name != NULL; i++)
1459 {
1460 int l = strlen (csky_float_abis[i].name);
1461 if (n + l >= margin)
1462 {
1463 fprintf (fp, "\n\t\t\t\t");
1464 n = l;
1465 }
1466 else
1467 {
1468 fprintf (fp, " ");
1469 n += l + 1;
1470 }
1471 fprintf (fp, "%s", csky_float_abis[i].name);
1472 }
1473 fprintf (fp, "\n");
1474
1475 fprintf (fp, _("\
1476 -EL -mlittle-endian generate little-endian output\n"));
1477 fprintf (fp, _("\
1478 -EB -mbig-endian generate big-endian output\n"));
1479 fprintf (fp, _("\
1480 -fpic -pic generate position-independent code\n"));
1481
1482 fprintf (fp, _("\
1483 -mljump transform jbf, jbt, jbr to jmpi (CK800 only)\n"));
1484 fprintf (fp, _("\
1485 -mno-ljump\n"));
1486
1487 #ifdef INCLUDE_BRANCH_STUB
1488 fprintf (fp, _("\
1489 -mbranch-stub enable branch stubs for PC-relative calls\n"));
1490 fprintf (fp, _("\
1491 -mno-branch-stub\n"));
1492 #endif
1493
1494 fprintf (fp, _("\
1495 -force2bsr -mforce2bsr transform jbsr to bsr\n"));
1496 fprintf (fp, _("\
1497 -no-force2bsr -mno-force2bsr\n"));
1498 fprintf (fp, _("\
1499 -jsri2bsr -mjsri2bsr transform jsri to bsr\n"));
1500 fprintf (fp, _("\
1501 -no-jsri2bsr -mno-jsri2bsr\n"));
1502
1503 fprintf (fp, _("\
1504 -mnolrw -mno-lrw implement lrw as movih + ori\n"));
1505 fprintf (fp, _("\
1506 -melrw enable extended lrw (CK800 only)\n"));
1507 fprintf (fp, _("\
1508 -mno-elrw\n"));
1509
1510 fprintf (fp, _("\
1511 -mlaf -mliterals-after-func emit literals after each function\n"));
1512 fprintf (fp, _("\
1513 -mno-laf -mno-literals-after-func\n"));
1514 fprintf (fp, _("\
1515 -mlabr -mliterals-after-br emit literals after branch instructions\n"));
1516 fprintf (fp, _("\
1517 -mno-labr -mnoliterals-after-br\n"));
1518
1519 fprintf (fp, _("\
1520 -mistack enable interrupt stack instructions\n"));
1521 fprintf (fp, _("\
1522 -mno-istack\n"));
1523
1524 fprintf (fp, _("\
1525 -mhard-float enable hard float instructions\n"));
1526 fprintf (fp, _("\
1527 -mmp enable multiprocessor instructions\n"));
1528 fprintf (fp, _("\
1529 -mcp enable coprocessor instructions\n"));
1530 fprintf (fp, _("\
1531 -mcache enable cache prefetch instruction\n"));
1532 fprintf (fp, _("\
1533 -msecurity enable security instructions\n"));
1534 fprintf (fp, _("\
1535 -mtrust enable trust instructions\n"));
1536 fprintf (fp, _("\
1537 -mdsp enable DSP instructions\n"));
1538 fprintf (fp, _("\
1539 -medsp enable enhanced DSP instructions\n"));
1540 fprintf (fp, _("\
1541 -mvdsp enable vector DSP instructions\n"));
1542 }
1543
1544 static void set_csky_attribute (void)
1545 {
1546 if (mach_flag & CSKY_ARCH_DSP)
1547 {
1548 if (dsp_flag & CSKY_DSP_FLAG_V2)
1549 {
1550 /* Set DSPV2. */
1551 bfd_elf_add_obj_attr_int (stdoutput, OBJ_ATTR_PROC,
1552 Tag_CSKY_DSP_VERSION,
1553 VAL_CSKY_DSP_VERSION_2);
1554 }
1555 else if (isa_flag & CSKY_ISA_DSP)
1556 {
1557 /* Set DSP extension. */
1558 bfd_elf_add_obj_attr_int (stdoutput, OBJ_ATTR_PROC,
1559 Tag_CSKY_DSP_VERSION,
1560 VAL_CSKY_DSP_VERSION_EXTENSION);
1561 }
1562 /* Set VDSP attribute. */
1563 if (isa_flag & CSKY_ISA_VDSP)
1564 bfd_elf_add_obj_attr_int (stdoutput, OBJ_ATTR_PROC,
1565 Tag_CSKY_VDSP_VERSION,
1566 VAL_CSKY_VDSP_VERSION_1);
1567
1568 else if (isa_flag & CSKY_ISA_VDSP_2)
1569 bfd_elf_add_obj_attr_int (stdoutput, OBJ_ATTR_PROC,
1570 Tag_CSKY_VDSP_VERSION,
1571 VAL_CSKY_VDSP_VERSION_2);
1572
1573 }
1574
1575 if (mach_flag & CSKY_ARCH_FLOAT)
1576 {
1577 unsigned int val = VAL_CSKY_FPU_HARDFP_SINGLE;
1578 if (IS_CSKY_ARCH_V1 (mach_flag)) {
1579 bfd_elf_add_obj_attr_int (stdoutput, OBJ_ATTR_PROC,
1580 Tag_CSKY_FPU_VERSION,
1581 VAL_CSKY_FPU_VERSION_1);
1582 }
1583 else
1584 {
1585 if (isa_flag & CSKY_ISA_FLOAT_3E4)
1586 {
1587 bfd_elf_add_obj_attr_int (stdoutput, OBJ_ATTR_PROC,
1588 Tag_CSKY_FPU_VERSION,
1589 VAL_CSKY_FPU_VERSION_2);
1590 val |= VAL_CSKY_FPU_HARDFP_DOUBLE;
1591 }
1592 else
1593 {
1594 bfd_elf_add_obj_attr_int (stdoutput, OBJ_ATTR_PROC,
1595 Tag_CSKY_FPU_VERSION,
1596 VAL_CSKY_FPU_VERSION_2);
1597 }
1598
1599 bfd_elf_add_obj_attr_int (stdoutput, OBJ_ATTR_PROC,
1600 Tag_CSKY_FPU_HARDFP,
1601 val);
1602 bfd_elf_add_obj_attr_string (stdoutput, OBJ_ATTR_PROC,
1603 Tag_CSKY_FPU_NUMBER_MODULE,
1604 "IEEE 754");
1605 bfd_elf_add_obj_attr_int (stdoutput, OBJ_ATTR_PROC,
1606 Tag_CSKY_FPU_ABI,
1607 float_abi);
1608 }
1609 }
1610
1611
1612 bfd_elf_add_obj_attr_int (stdoutput, OBJ_ATTR_PROC,
1613 Tag_CSKY_ISA_FLAGS, isa_flag);
1614
1615 bfd_elf_add_obj_attr_int (stdoutput, OBJ_ATTR_PROC,
1616 Tag_CSKY_ISA_EXT_FLAGS, (isa_flag >> 32));
1617 }
1618
1619 /* Target-specific initialization and option handling. */
1620
1621 void
1622 md_begin (void)
1623 {
1624 unsigned int bfd_mach_flag = 0;
1625 struct csky_opcode const *opcode;
1626 struct csky_macro_info const *macro;
1627 struct csky_arch_info const *p_arch;
1628 struct csky_cpu_info const *p_cpu;
1629 other_flag = (do_opt_mmp | do_opt_mcp | do_opt_mcache
1630 | do_opt_msecurity | do_opt_mhard_float);
1631 dsp_flag |= do_opt_mdsp | do_opt_medsp;
1632 isa_flag |= do_opt_mtrust | do_opt_mvdsp;
1633
1634 if (dsp_flag)
1635 other_flag |= CSKY_ARCH_DSP;
1636
1637 if (mach_flag != 0)
1638 {
1639 if (((mach_flag & CSKY_ARCH_MASK)
1640 != (arch_flag & CSKY_ARCH_MASK))
1641 && arch_flag != 0)
1642 as_warn ("-mcpu conflict with -march option, actually use -mcpu");
1643 }
1644 else if (arch_flag != 0)
1645 mach_flag |= arch_flag | other_flag;
1646 else
1647 {
1648 #ifdef TARGET_WITH_CPU
1649 parse_cpu (TARGET_WITH_CPU);
1650 #else
1651 #if _CSKY_ABI==1
1652 parse_cpu ("ck610");
1653 #else
1654 parse_cpu ("ck810");
1655 #endif
1656 mach_flag |= other_flag;
1657 #endif
1658 }
1659
1660 if (IS_CSKY_ARCH_610 (mach_flag) || IS_CSKY_ARCH_510 (mach_flag))
1661 {
1662 if ((mach_flag & CSKY_ARCH_MP) && (mach_flag & CSKY_ARCH_MAC))
1663 as_fatal ("520/620 conflicts with -mmp option");
1664 else if ((mach_flag & CSKY_ARCH_MP) && (mach_flag & CSKY_ARCH_DSP))
1665 as_fatal ("510e/610e conflicts with -mmp option");
1666 else if ((mach_flag & CSKY_ARCH_DSP) && (mach_flag & CSKY_ARCH_MAC))
1667 as_fatal ("520/620 conflicts with 510e/610e or -mdsp option");
1668 }
1669 if (IS_CSKY_ARCH_510 (mach_flag) && (mach_flag & CSKY_ARCH_FLOAT))
1670 {
1671 mach_flag = (mach_flag & (~CSKY_ARCH_MASK));
1672 mach_flag |= CSKY_ARCH_610;
1673 }
1674
1675 /* Find bfd_mach_flag, it will set to bfd backend data. */
1676 for (p_arch = csky_archs; p_arch->arch_flag != 0; p_arch++)
1677 if ((mach_flag & CSKY_ARCH_MASK) == (p_arch->arch_flag & CSKY_ARCH_MASK))
1678 {
1679 bfd_elf_add_obj_attr_string (stdoutput, OBJ_ATTR_PROC,
1680 Tag_CSKY_ARCH_NAME, p_arch->name);
1681 bfd_mach_flag = p_arch->bfd_mach_flag;
1682 break;
1683 }
1684
1685 /* Find isa_flag. */
1686 for (p_cpu = csky_cpus; p_cpu->arch_flag != 0; p_cpu++)
1687 if ((mach_flag & CPU_ARCH_MASK) == p_cpu->arch_flag)
1688 {
1689 bfd_elf_add_obj_attr_string (stdoutput, OBJ_ATTR_PROC,
1690 Tag_CSKY_CPU_NAME, p_cpu->name);
1691 isa_flag |= p_cpu->isa_flag;
1692 break;
1693 }
1694
1695 /* Check if -mdsp and -medsp conflict. If cpu is ck803, we will
1696 use enhanced dsp instruction. Otherwise, we will use normal dsp. */
1697 if (dsp_flag)
1698 {
1699 if (IS_CSKY_ARCH_803 (mach_flag))
1700 {
1701 if ((dsp_flag & CSKY_DSP_FLAG_V1))
1702 {
1703 if (isa_flag & CSKY_ISA_DSP_ENHANCE)
1704 {
1705 /* Option -mdsp conflicts with -mcpu=ck803ern,
1706 CPU already indicates the dsp version. */
1707 as_warn ("Option -mdsp conflicts with -mcpu=ck803ern which "
1708 "has indicated DSP version, ignoring -mdsp.");
1709 isa_flag &= ~(CSKY_ISA_MAC_DSP | CSKY_ISA_DSP);
1710 isa_flag |= CSKY_ISA_DSP_ENHANCE;
1711 }
1712 else
1713 {
1714 isa_flag |= (CSKY_ISA_MAC_DSP | CSKY_ISA_DSP);
1715 isa_flag &= ~CSKY_ISA_DSP_ENHANCE;
1716 }
1717 }
1718
1719 if ((dsp_flag & CSKY_DSP_FLAG_V2))
1720 {
1721 isa_flag &= ~(CSKY_ISA_MAC_DSP | CSKY_ISA_DSP);
1722 isa_flag |= CSKY_ISA_DSP_ENHANCE;
1723 }
1724
1725 if ((dsp_flag & CSKY_DSP_FLAG_V1)
1726 && (dsp_flag & CSKY_DSP_FLAG_V2))
1727 {
1728 /* In 803, dspv1 is conflict with dspv2. We keep dspv2. */
1729 as_warn ("option -mdsp conflicts with -medsp, only enabling -medsp");
1730 dsp_flag &= ~CSKY_DSP_FLAG_V1;
1731 isa_flag &= ~(CSKY_ISA_MAC_DSP | CSKY_ISA_DSP);
1732 isa_flag |= CSKY_ISA_DSP_ENHANCE;
1733 }
1734 }
1735 else
1736 {
1737 if (dsp_flag & CSKY_DSP_FLAG_V2)
1738 {
1739 dsp_flag &= ~CSKY_DSP_FLAG_V2;
1740 isa_flag &= ~CSKY_ISA_DSP_ENHANCE;
1741 as_warn ("-medsp option is only supported by ck803s, ignoring -medsp");
1742 }
1743 }
1744 ;
1745 }
1746
1747 if (do_use_branchstub == -1)
1748 do_use_branchstub = !IS_CSKY_ARCH_V1 (mach_flag);
1749 else if (do_use_branchstub == 1)
1750 {
1751 if (IS_CSKY_ARCH_V1 (mach_flag))
1752 {
1753 as_warn (_("C-SKY ABI v1 (ck510/ck610) does not support -mbranch-stub"));
1754 do_use_branchstub = 0;
1755 }
1756 else if (do_force2bsr == 0)
1757 {
1758 as_warn (_("-mno-force2bsr is ignored with -mbranch-stub"));
1759 do_force2bsr = 1;
1760 }
1761 }
1762
1763 if (IS_CSKY_ARCH_801 (mach_flag) || IS_CSKY_ARCH_802 (mach_flag))
1764 {
1765 if (!do_force2bsr)
1766 as_warn (_("-mno-force2bsr is ignored for ck801/ck802"));
1767 do_force2bsr = 1;
1768 }
1769 else if (do_force2bsr == -1)
1770 do_force2bsr = do_use_branchstub;
1771
1772 if (do_pff == -1)
1773 {
1774 if (IS_CSKY_ARCH_V1 (mach_flag))
1775 do_pff = 1;
1776 else
1777 do_pff = 0;
1778 }
1779
1780 if (do_extend_lrw == -1)
1781 {
1782 if ((mach_flag & CSKY_ARCH_MASK) == CSKY_ARCH_801
1783 || (mach_flag & CSKY_ARCH_MASK) == CSKY_ARCH_802
1784 || (mach_flag & CSKY_ARCH_MASK) == CSKY_ARCH_803
1785 || (mach_flag & CSKY_ARCH_MASK) == CSKY_ARCH_860)
1786 do_extend_lrw = 1;
1787 else
1788 do_extend_lrw = 0;
1789 }
1790 if (IS_CSKY_ARCH_801 (mach_flag) || IS_CSKY_ARCH_802 (mach_flag))
1791 {
1792 if (do_long_jump > 0)
1793 as_warn (_("-mljump is ignored for ck801/ck802"));
1794 do_long_jump = 0;
1795 }
1796 else if (do_long_jump == -1)
1797 do_long_jump = 1;
1798 if (do_intr_stack == -1)
1799 {
1800 /* control interrupt stack module, 801&802&803 default on
1801 807&810, default off. */
1802 if (IS_CSKY_ARCH_807 (mach_flag) || IS_CSKY_ARCH_810 (mach_flag))
1803 do_intr_stack = 0;
1804 else
1805 do_intr_stack = 1;
1806 }
1807 /* Add isa_flag(SIMP/CACHE/APS). */
1808 isa_flag |= (mach_flag & CSKY_ARCH_MAC) ? CSKY_ISA_MAC : 0;
1809 isa_flag |= (mach_flag & CSKY_ARCH_MP) ? CSKY_ISA_MP : 0;
1810 isa_flag |= (mach_flag & CSKY_ARCH_CP) ? CSKY_ISA_CP : 0;
1811
1812 /* Set abi flag and get table address. */
1813 if (IS_CSKY_ARCH_V1 (mach_flag))
1814 {
1815 mach_flag = mach_flag | CSKY_ABI_V1;
1816 opcode = csky_v1_opcodes;
1817 macro = v1_macros_table;
1818 SPANPANIC = v1_SPANPANIC;
1819 SPANCLOSE = v1_SPANCLOSE;
1820 SPANEXIT = v1_SPANEXIT;
1821 md_relax_table = csky_relax_table;
1822 }
1823 else
1824 {
1825 mach_flag = mach_flag | CSKY_ABI_V2;
1826 opcode = csky_v2_opcodes;
1827 macro = v2_macros_table;
1828 SPANPANIC = v2_SPANPANIC;
1829 if (do_extend_lrw)
1830 {
1831 SPANCLOSE = v2_SPANCLOSE_ELRW;
1832 SPANEXIT = v2_SPANEXIT_ELRW;
1833 }
1834 else
1835 {
1836 SPANCLOSE = v2_SPANCLOSE;
1837 SPANEXIT = v2_SPANEXIT;
1838 }
1839 md_relax_table = csky_relax_table;
1840 }
1841
1842 /* Establish hash table for opcodes and macros. */
1843 csky_macros_hash = str_htab_create ();
1844 csky_opcodes_hash = str_htab_create ();
1845 for ( ; opcode->mnemonic != NULL; opcode++)
1846 if ((isa_flag & (opcode->isa_flag16 | opcode->isa_flag32)) != 0)
1847 str_hash_insert (csky_opcodes_hash, opcode->mnemonic, opcode, 0);
1848 for ( ; macro->name != NULL; macro++)
1849 if ((isa_flag & macro->isa_flag) != 0)
1850 str_hash_insert (csky_macros_hash, macro->name, macro, 0);
1851 if (do_nolrw && (isa_flag & CSKYV2_ISA_1E2) != 0)
1852 str_hash_insert (csky_macros_hash,
1853 v2_lrw_macro_opcode.name, &v2_lrw_macro_opcode, 0);
1854 /* Set e_flag to ELF Head. */
1855 bfd_set_private_flags (stdoutput, mach_flag | CSKY_VERSION_V1);
1856 /* Set bfd_mach to bfd backend data. */
1857 bfd_set_arch_mach (stdoutput, bfd_arch_csky, bfd_mach_flag);
1858
1859 set_csky_attribute ();
1860 }
1861
1862 /* The C-SKY assembler emits mapping symbols $t and $d to mark the
1863 beginning of a sequence of instructions and data (such as a constant pool),
1864 respectively. This is similar to what ARM does. */
1865
1866 static void
1867 make_mapping_symbol (map_state state, valueT value, fragS *frag)
1868 {
1869 symbolS * symbolP;
1870 const char * symname;
1871 int type;
1872 switch (state)
1873 {
1874 case MAP_DATA:
1875 symname = "$d";
1876 type = BSF_NO_FLAGS;
1877 break;
1878 case MAP_TEXT:
1879 symname = "$t";
1880 type = BSF_NO_FLAGS;
1881 break;
1882 default:
1883 abort ();
1884 }
1885
1886 symbolP = symbol_new (symname, now_seg, frag, value);
1887 symbol_get_bfdsym (symbolP)->flags |= type | BSF_LOCAL;
1888 }
1889
1890 /* We need to keep track of whether we are emitting code or data; this
1891 function switches state and emits a mapping symbol if necessary. */
1892
1893 static void
1894 mapping_state (map_state state)
1895 {
1896 map_state current_state
1897 = seg_info (now_seg)->tc_segment_info_data.current_state;
1898
1899 if (current_state == state)
1900 return;
1901 else if (current_state == MAP_UNDEFINED && state == MAP_DATA)
1902 return;
1903 else if (current_state == MAP_UNDEFINED && state == MAP_TEXT)
1904 {
1905 struct frag * const frag_first = seg_info (now_seg)->frchainP->frch_root;
1906 if (frag_now != frag_first || frag_now_fix () > 0)
1907 make_mapping_symbol (MAP_DATA, (valueT) 0, frag_first);
1908 }
1909
1910 seg_info (now_seg)->tc_segment_info_data.current_state = state;
1911 make_mapping_symbol (state, (valueT) frag_now_fix (), frag_now);
1912 }
1913
1914 /* Dump the literal pool. */
1915
1916 static void
1917 dump_literals (int isforce)
1918 {
1919 #define CSKYV1_BR_INSN 0xF000
1920 #define CSKYV2_BR_INSN 0x0400
1921 unsigned int i;
1922 struct literal * p;
1923 symbolS * brarsym = NULL;
1924
1925 /* V1 nop encoding: 0x1200 : mov r0, r0. */
1926 static char v1_nop_insn_big[2] = {0x12, 0x00};
1927 static char v1_nop_insn_little[2] = {0x00, 0x12};
1928
1929 if (poolsize == 0)
1930 return;
1931
1932 /* Must we branch around the literal table? */
1933 if (isforce)
1934 {
1935 char brarname[8];
1936 make_internal_label (brarname, POOL_END_LABEL, poolnumber);
1937 brarsym = symbol_make (brarname);
1938 symbol_table_insert (brarsym);
1939 mapping_state (MAP_TEXT);
1940 if (IS_CSKY_ARCH_V1 (mach_flag))
1941 {
1942 csky_insn.output
1943 = frag_var (rs_machine_dependent,
1944 csky_relax_table[C (UNCD_JUMP_S, DISP32)].rlx_length,
1945 csky_relax_table[C (UNCD_JUMP_S, DISP12)].rlx_length,
1946 C (UNCD_JUMP_S, 0), brarsym, 0, 0);
1947 md_number_to_chars (csky_insn.output, CSKYV1_BR_INSN, 2);
1948 }
1949 else
1950 {
1951 csky_insn.output
1952 = frag_var (rs_machine_dependent,
1953 UNCD_DISP16_LEN,
1954 UNCD_DISP10_LEN,
1955 UNCD_DISP10,
1956 brarsym, 0, 0);
1957 md_number_to_chars (csky_insn.output, CSKYV2_BR_INSN, 2);
1958 }
1959 }
1960 /* Make sure that the section is sufficiently aligned and that
1961 the literal table is aligned within it. */
1962 if (do_pff)
1963 {
1964 valueT br_self;
1965 csky_insn.output = frag_more (2);
1966 /* .Lxx: br .Lxx */
1967 if (IS_CSKY_V1 (mach_flag))
1968 br_self = CSKYV1_BR_INSN | 0x7ff;
1969 else
1970 br_self = CSKYV2_BR_INSN;
1971 md_number_to_chars (csky_insn.output, br_self, 2);
1972 if (!isforce)
1973 {
1974 csky_insn.output = frag_more (2);
1975 /* .Lxx: br .Lxx */
1976 md_number_to_chars (csky_insn.output, br_self, 2);
1977 }
1978 }
1979 mapping_state (MAP_DATA);
1980
1981 record_alignment (now_seg, 2);
1982 if (IS_CSKY_ARCH_V1 (mach_flag))
1983 frag_align_pattern (2,
1984 (target_big_endian
1985 ? v1_nop_insn_big : v1_nop_insn_little),
1986 2, 0);
1987 else
1988 frag_align (2, 0, 3);
1989
1990 colon (S_GET_NAME (poolsym));
1991
1992 for (i = 0, p = litpool; i < poolsize; p++)
1993 {
1994 insn_reloc = p->r_type;
1995 if (insn_reloc == BFD_RELOC_CKCORE_TLS_IE32
1996 || insn_reloc == BFD_RELOC_CKCORE_TLS_LDM32
1997 || insn_reloc == BFD_RELOC_CKCORE_TLS_GD32)
1998 literal_insn_offset = p;
1999 if (p->isdouble)
2000 {
2001 if (target_big_endian)
2002 {
2003 p->e.X_add_number = p->dbnum >> 32;
2004 emit_expr (& p->e, 4);
2005 p->e.X_add_number = p->dbnum & 0xffffffff;
2006 emit_expr (& p->e, 4);
2007 }
2008 else
2009 {
2010 p->e.X_add_number = p->dbnum & 0xffffffff;
2011 emit_expr (& p->e, 4);
2012 p->e.X_add_number = p->dbnum >> 32;
2013 emit_expr (& p->e, 4);
2014 }
2015 }
2016 else if (p->e.X_op == O_big)
2017 {
2018 memcpy (generic_bignum, p->bignum, sizeof (p->bignum));
2019 emit_expr (& p->e, p->e.X_add_number * CHARS_PER_LITTLENUM);
2020 }
2021 else
2022 emit_expr (& p->e, 4);
2023
2024 if (p->e.X_op == O_big)
2025 i += (p->e.X_add_number & 1) +
2026 ((p->e.X_add_number * CHARS_PER_LITTLENUM) >> 2);
2027 else
2028 i += (p->isdouble ? 2 : 1);
2029 }
2030
2031 if (isforce && IS_CSKY_ARCH_V2 (mach_flag))
2032 {
2033 /* Add one nop insn at end of literal for disassembler. */
2034 mapping_state (MAP_TEXT);
2035 csky_insn.output = frag_more (2);
2036 md_number_to_chars (csky_insn.output, CSKYV2_INST_NOP, 2);
2037 }
2038
2039 insn_reloc = BFD_RELOC_NONE;
2040
2041 if (brarsym != NULL)
2042 colon (S_GET_NAME (brarsym));
2043 poolsize = 0;
2044 }
2045
2046 static struct literal *
2047 enter_literal (expressionS *e,
2048 int ispcrel,
2049 unsigned char isdouble,
2050 uint64_t dbnum)
2051 {
2052 unsigned int i;
2053 struct literal * p;
2054 if (poolsize >= MAX_POOL_SIZE - 2)
2055 {
2056 /* The literal pool is as full as we can handle. We have
2057 to be 2 entries shy of the 1024/4=256 entries because we
2058 have to allow for the branch (2 bytes) and the alignment
2059 (2 bytes before the first insn referencing the pool and
2060 2 bytes before the pool itself) == 6 bytes, rounds up
2061 to 2 entries. */
2062
2063 /* Save the parsed symbol's reloc. */
2064 enum bfd_reloc_code_real last_reloc_before_dump = insn_reloc;
2065 dump_literals (1);
2066 insn_reloc = last_reloc_before_dump;
2067 }
2068
2069 if (poolsize == 0)
2070 {
2071 /* Create new literal pool. */
2072 if (++ poolnumber > 0xFFFF)
2073 as_fatal (_("more than 65K literal pools"));
2074
2075 make_internal_label (poolname, POOL_START_LABEL, poolnumber);
2076 poolsym = symbol_make (poolname);
2077 symbol_table_insert (poolsym);
2078 poolspan = 0;
2079 }
2080
2081 /* Search pool for value so we don't have duplicates. */
2082 for (p = litpool,i = 0; i < poolsize; p++)
2083 {
2084 if (e->X_op == p->e.X_op
2085 && e->X_add_symbol == p->e.X_add_symbol
2086 && e->X_add_number == p->e.X_add_number
2087 && ispcrel == p->ispcrel
2088 && insn_reloc == p->r_type
2089 && isdouble == p->isdouble
2090 && insn_reloc != BFD_RELOC_CKCORE_TLS_GD32
2091 && insn_reloc != BFD_RELOC_CKCORE_TLS_LDM32
2092 && insn_reloc != BFD_RELOC_CKCORE_TLS_LDO32
2093 && insn_reloc != BFD_RELOC_CKCORE_TLS_IE32
2094 && insn_reloc != BFD_RELOC_CKCORE_TLS_LE32
2095 && (e->X_op != O_big
2096 || (memcmp (generic_bignum, p->bignum,
2097 p->e.X_add_number * sizeof (LITTLENUM_TYPE)) == 0)))
2098 {
2099 p->refcnt ++;
2100 return p;
2101 }
2102 if (p->e.X_op == O_big)
2103 {
2104 i += (p->e.X_add_number >> 1);
2105 i += (p->e.X_add_number & 0x1);
2106 }
2107 else
2108 i += (p->isdouble ? 2 : 1);
2109 }
2110 p->refcnt = 1;
2111 p->ispcrel = ispcrel;
2112 p->e = *e;
2113 p->r_type = insn_reloc;
2114 p->isdouble = isdouble;
2115 p->offset = i;
2116 if (isdouble)
2117 p->dbnum = dbnum;
2118 if (e->X_op == O_big)
2119 memcpy (p->bignum, generic_bignum, sizeof (p->bignum));
2120
2121 if (insn_reloc == BFD_RELOC_CKCORE_TLS_GD32
2122 || insn_reloc == BFD_RELOC_CKCORE_TLS_LDM32
2123 || insn_reloc == BFD_RELOC_CKCORE_TLS_IE32)
2124 {
2125 p->tls_addend.frag = frag_now;
2126 p->tls_addend.offset = csky_insn.output - frag_now->fr_literal;
2127 literal_insn_offset = p;
2128 }
2129 if (p->e.X_op == O_big) {
2130 poolsize += (p->e.X_add_number >> 1);
2131 poolsize += (p->e.X_add_number & 0x1);
2132 } else
2133 poolsize += (p->isdouble ? 2 : 1);
2134
2135 return p;
2136 }
2137
2138 /* Check whether we must dump the literal pool here.
2139 kind == 0 is any old instruction.
2140 kind > 0 means we just had a control transfer instruction.
2141 kind == 1 means within a function.
2142 kind == 2 means we just left a function.
2143
2144 OFFSET is the length of the insn being processed.
2145
2146 SPANCLOSE and SPANEXIT are smaller numbers than SPANPANIC.
2147 SPANPANIC means that we must dump now.
2148 The dump_literals (1) call inserts a branch around the table, so
2149 we first look to see if its a situation where we won't have to
2150 insert a branch (e.g., the previous instruction was an unconditional
2151 branch).
2152
2153 SPANPANIC is the point where we must dump a single-entry pool.
2154 it accounts for alignments and an inserted branch.
2155 the 'poolsize*2' accounts for the scenario where we do:
2156 lrw r1,lit1; lrw r2,lit2; lrw r3,lit3
2157 Note that the 'lit2' reference is 2 bytes further along
2158 but the literal it references will be 4 bytes further along,
2159 so we must consider the poolsize into this equation.
2160 This is slightly over-cautious, but guarantees that we won't
2161 panic because a relocation is too distant. */
2162
2163 static void
2164 check_literals (int kind, int offset)
2165 {
2166 poolspan += offset;
2167
2168 if ((poolspan > SPANEXIT || do_func_dump)
2169 && kind > 1
2170 && (do_br_dump || do_func_dump))
2171 dump_literals (0);
2172 else if (poolspan > SPANCLOSE && (kind > 0) && do_br_dump)
2173 dump_literals (0);
2174 else if (poolspan
2175 >= (SPANPANIC - (IS_CSKY_ARCH_V1 (mach_flag) ? poolsize * 2 : 0)))
2176 dump_literals (1);
2177 /* We have not dumped literal pool before insn1,
2178 and will not dump literal pool between insn1 and insnN+1,
2179 so reset poolspan to original length. */
2180 else if (do_noliteraldump == 1)
2181 poolspan -= offset;
2182
2183 if (do_noliteraldump == 1)
2184 do_noliteraldump = 0;
2185 }
2186
2187 /* The next group of functions are helpers for parsing various kinds
2188 of instruction operand syntax. */
2189
2190 /* Parse operands of the form
2191 <symbol>@GOTOFF+<nnn>
2192 and similar .plt or .got references.
2193
2194 If we find one, set up the correct relocation in RELOC and copy the
2195 input string, minus the `@GOTOFF' into a malloc'd buffer for
2196 parsing by the calling routine. Return this buffer, and if ADJUST
2197 is non-null set it to the length of the string we removed from the
2198 input line. Otherwise return NULL. */
2199
2200 static char *
2201 lex_got (enum bfd_reloc_code_real *reloc,
2202 int *adjust)
2203 {
2204 struct _gotrel
2205 {
2206 const char *str;
2207 const enum bfd_reloc_code_real rel;
2208 };
2209 static const struct _gotrel gotrel[] =
2210 {
2211 { "GOTOFF", BFD_RELOC_CKCORE_GOTOFF },
2212 { "GOTPC", BFD_RELOC_CKCORE_GOTPC },
2213 { "GOTTPOFF", BFD_RELOC_CKCORE_TLS_IE32 },
2214 { "GOT", BFD_RELOC_CKCORE_GOT32 },
2215 { "PLT", BFD_RELOC_CKCORE_PLT32 },
2216 { "BTEXT", BFD_RELOC_CKCORE_TOFFSET_LO16},
2217 { "BDATA", BFD_RELOC_CKCORE_DOFFSET_LO16},
2218 { "TLSGD32", BFD_RELOC_CKCORE_TLS_GD32 },
2219 { "TLSLDM32", BFD_RELOC_CKCORE_TLS_LDM32 },
2220 { "TLSLDO32", BFD_RELOC_CKCORE_TLS_LDO32 },
2221 { "TPOFF", BFD_RELOC_CKCORE_TLS_LE32 }
2222 };
2223
2224 char *cp;
2225 unsigned int j;
2226
2227 for (cp = input_line_pointer; *cp != '@'; cp++)
2228 if (is_end_of_line[(unsigned char) *cp])
2229 return NULL;
2230
2231 for (j = 0; j < sizeof (gotrel) / sizeof (gotrel[0]); j++)
2232 {
2233 int len = strlen (gotrel[j].str);
2234
2235 if (strncasecmp (cp + 1, gotrel[j].str, len) == 0)
2236 {
2237 if (gotrel[j].rel != 0)
2238 {
2239 *reloc = gotrel[j].rel;
2240 if (adjust)
2241 *adjust = len;
2242
2243 /* input_line_pointer is the str pointer after relocation
2244 token like @GOTOFF. */
2245 input_line_pointer += len + 1;
2246 return input_line_pointer;
2247 }
2248
2249 csky_show_error (ERROR_RELOC_ILLEGAL, 0,
2250 (void *)gotrel[j].str, NULL);
2251 return NULL;
2252 }
2253 }
2254
2255 /* Might be a symbol version string. Don't as_bad here. */
2256 return NULL;
2257 }
2258
2259 /* Parse an expression, returning it in E. */
2260
2261 static char *
2262 parse_exp (char *s, expressionS *e)
2263 {
2264 char *save;
2265 char *new;
2266
2267 /* Skip whitespace. */
2268 while (ISSPACE (*s))
2269 ++s;
2270
2271 save = input_line_pointer;
2272 input_line_pointer = s;
2273
2274 insn_reloc = BFD_RELOC_NONE;
2275 expression (e);
2276 lex_got (&insn_reloc, NULL);
2277
2278 if (e->X_op == O_absent)
2279 SET_ERROR_STRING (ERROR_MISSING_OPERAND, NULL);
2280
2281 new = input_line_pointer;
2282 input_line_pointer = save;
2283
2284 return new;
2285 }
2286
2287 /* Parse a floating-point number from S into its target representation.
2288 If ISDOUBLE is true, return the result in *DBNUM; otherwise
2289 it's returned in E->X_add_number. Returns the result of advancing
2290 S past the constant. */
2291
2292 static char *
2293 parse_fexp (char *s, expressionS *e, unsigned char isdouble, uint64_t *dbnum)
2294 {
2295 int length; /* Number of chars in an object. */
2296 const char *err = NULL; /* Error from scanning float literal. */
2297 unsigned char temp[8];
2298
2299 /* input_line_pointer->1st char of a flonum (we hope!). */
2300 input_line_pointer = s;
2301
2302 if (input_line_pointer[0] == '0'
2303 && ISALPHA (input_line_pointer[1]))
2304 input_line_pointer += 2;
2305
2306 if (isdouble)
2307 err = md_atof ('d', (char *) temp, &length);
2308 else
2309 err = md_atof ('f', (char *) temp, &length);
2310 know (length <= 8);
2311 know (err != NULL || length > 0);
2312
2313 if (!is_end_of_line[(unsigned char) *input_line_pointer])
2314 as_bad (_("immediate operand required"));
2315 while (!is_end_of_line[(unsigned char) *input_line_pointer])
2316 input_line_pointer++;
2317
2318 if (err)
2319 {
2320 as_bad (_("bad floating literal: %s"), err);
2321 while (!is_end_of_line[(unsigned char) *input_line_pointer])
2322 input_line_pointer++;
2323 know (is_end_of_line[(unsigned char) input_line_pointer[-1]]);
2324 return input_line_pointer;
2325 }
2326
2327 e->X_add_symbol = 0x0;
2328 e->X_op_symbol = 0x0;
2329 e->X_op = O_constant;
2330 e->X_unsigned = 1;
2331 e->X_md = 0x0;
2332
2333 if (!isdouble)
2334 {
2335 uint32_t fnum;
2336 if (target_big_endian)
2337 fnum = (((uint32_t) temp[0] << 24)
2338 | (temp[1] << 16)
2339 | (temp[2] << 8)
2340 | temp[3]);
2341 else
2342 fnum = (((uint32_t) temp[3] << 24)
2343 | (temp[2] << 16)
2344 | (temp[1] << 8)
2345 | temp[0]);
2346 e->X_add_number = fnum;
2347 }
2348 else
2349 {
2350 if (target_big_endian)
2351 {
2352 *dbnum = (((uint32_t) temp[0] << 24)
2353 | (temp[1] << 16)
2354 | (temp[2] << 8)
2355 | temp[3]);
2356 *dbnum <<= 32;
2357 *dbnum |= (((uint32_t) temp[4] << 24)
2358 | (temp[5] << 16)
2359 | (temp[6] << 8)
2360 | temp[7]);
2361 }
2362 else
2363 {
2364 *dbnum = (((uint32_t) temp[7] << 24)
2365 | (temp[6] << 16)
2366 | (temp[5] << 8)
2367 | temp[4]);
2368 *dbnum <<= 32;
2369 *dbnum |= (((uint32_t) temp[3] << 24)
2370 | (temp[2] << 16)
2371 | (temp[1] << 8)
2372 | temp[0]);
2373 }
2374 }
2375 return input_line_pointer;
2376 }
2377
2378 static char *
2379 parse_rt (char *s,
2380 int ispcrel,
2381 expressionS *ep,
2382 long reg ATTRIBUTE_UNUSED)
2383 {
2384 expressionS e;
2385
2386 if (ep)
2387 /* Indicate nothing there. */
2388 ep->X_op = O_absent;
2389
2390 if (*s == '[')
2391 {
2392 s = parse_exp (s + 1, &e);
2393
2394 if (*s == ']')
2395 s++;
2396 else
2397 SET_ERROR_STRING (ERROR_MISSING_RSQUARE_BRACKETS, NULL);
2398
2399 if (ep)
2400 *ep = e;
2401 }
2402 else
2403 {
2404 s = parse_exp (s, &e);
2405 if (BFD_RELOC_CKCORE_DOFFSET_LO16 == insn_reloc
2406 || BFD_RELOC_CKCORE_TOFFSET_LO16 == insn_reloc)
2407 {
2408 if (ep)
2409 *ep = e;
2410 return s;
2411 }
2412 if (ep)
2413 *ep = e;
2414 /* If the instruction has work, literal handling is in the work. */
2415 if (!csky_insn.opcode->work)
2416 {
2417 struct literal *p = enter_literal (&e, ispcrel, 0, 0);
2418 if (ep)
2419 *ep = e;
2420
2421 /* Create a reference to pool entry. */
2422 ep->X_op = O_symbol;
2423 ep->X_add_symbol = poolsym;
2424 ep->X_add_number = p->offset << 2;
2425 }
2426 }
2427 return s;
2428 }
2429
2430 static int float_to_half (void *f, void *h)
2431 {
2432 int imm_e;
2433 int imm_f;
2434 unsigned int value_f = *(unsigned int *)f;
2435 unsigned short value_h;
2436
2437 imm_e = ((value_f >> 23) & 0xff);
2438 imm_f = ((value_f & 0x7fffff));
2439
2440 imm_e = ((imm_e - 127 + 15) << 10);
2441 imm_f = ((imm_f & 0x7fe000) >> 13);
2442
2443 value_h = (value_f & 0x80000000 ? 0x8000 : 0x0) | imm_e | imm_f;
2444
2445 if (h)
2446 *(unsigned short *)h = value_h;
2447
2448 return value_h;
2449 }
2450
2451 static char *
2452 parse_rtf (char *s, int ispcrel, expressionS *ep)
2453 {
2454 expressionS e;
2455 struct literal *p = NULL;
2456
2457 if (ep)
2458 /* Indicate nothing there. */
2459 ep->X_op = O_absent;
2460
2461 if (*s == '[')
2462 {
2463 s = parse_exp (s + 1, & e);
2464
2465 if (*s == ']')
2466 s++;
2467 else
2468 as_bad (_("missing ']'"));
2469
2470 if (ep)
2471 *ep = e;
2472 }
2473 else
2474 {
2475 uint64_t dbnum;
2476 if (strstr(csky_insn.opcode->mnemonic, "flrws")
2477 || strstr(csky_insn.opcode->mnemonic, "flrw.32"))
2478 {
2479 s = parse_fexp (s, &e, 0, &dbnum);
2480 p = enter_literal (& e, ispcrel, 0, dbnum);
2481 }
2482 else if (strstr(csky_insn.opcode->mnemonic, "flrwd")
2483 || strstr(csky_insn.opcode->mnemonic, "flrw.64"))
2484 {
2485 s = parse_fexp (s, &e, 1, &dbnum);
2486 p = enter_literal (& e, ispcrel, 1, dbnum);
2487 }
2488 else if (strstr(csky_insn.opcode->mnemonic, "flrwh")
2489 || strstr(csky_insn.opcode->mnemonic, "flrw.16"))
2490 {
2491 s = parse_fexp (s, &e, 0, NULL);
2492 e.X_add_number = float_to_half (&e.X_add_number, &e.X_add_number);
2493 p = enter_literal (& e, ispcrel, 0, 0);
2494 }
2495 else
2496 as_bad (_("unrecognized opcode"));
2497
2498 if (ep)
2499 *ep = e;
2500
2501 /* Create a reference to pool entry. */
2502 ep->X_op = O_symbol;
2503 ep->X_add_symbol = poolsym;
2504 ep->X_add_number = p->offset << 2;
2505 }
2506 return s;
2507 }
2508
2509 static bool
2510 parse_type_ctrlreg (char** oper)
2511 {
2512 int i = -1;
2513 int group = 0;
2514 int crx;
2515 int sel;
2516 char *s = *oper;
2517 expressionS e;
2518
2519 if (TOLOWER (*(*oper + 0)) == 'c'
2520 && TOLOWER (*(*oper + 1)) == 'r'
2521 && ISDIGIT (*(*oper + 2)))
2522 {
2523 /* The control registers are named crxx. */
2524 s = *oper+2;
2525 s = parse_exp (s, &e);
2526 if (e.X_op == O_constant)
2527 {
2528 i = e.X_add_number;
2529 *oper = s;
2530 }
2531 }
2532
2533 if (IS_CSKY_V2 (mach_flag))
2534 {
2535
2536 s = *oper;
2537 if (i != -1)
2538 {
2539 crx = i;
2540 sel = group;
2541 }
2542 else if (TOLOWER (*(*oper + 0)) == 'c'
2543 && TOLOWER (*(*oper + 1)) == 'r')
2544 {
2545 s += 2;
2546 if (*s != '<')
2547 {
2548 SET_ERROR_STRING (ERROR_CREG_ILLEGAL, s);
2549 return false;
2550 }
2551 s++;
2552 crx = strtol(s, &s, 10);
2553 if (crx < 0 || crx > 31 || *s != ',')
2554 {
2555 SET_ERROR_STRING (ERROR_CREG_ILLEGAL, s);
2556 return false;
2557 }
2558 s++;
2559 sel = strtol(s, &s, 10);
2560 if (sel < 0 || sel > 31 || *s != '>')
2561 {
2562 SET_ERROR_STRING (ERROR_CREG_ILLEGAL, s);
2563 return false;
2564 }
2565 s++;
2566 }
2567 else
2568 {
2569 crx = csky_get_control_regno (mach_flag, s, &s, &sel);
2570 if (crx < 0)
2571 {
2572 SET_ERROR_STRING (ERROR_CREG_ILLEGAL, s);
2573 return false;
2574 }
2575 }
2576 i = (sel << 5) | crx;
2577 }
2578 else if (i == -1)
2579 {
2580 i = csky_get_control_regno (mach_flag, s, &s, &sel);
2581 if (i < 0)
2582 {
2583 SET_ERROR_STRING (ERROR_CREG_ILLEGAL, s);
2584 return false;
2585 }
2586 }
2587 *oper = s;
2588 csky_insn.val[csky_insn.idx++] = i;
2589 return true;
2590 }
2591
2592 static int
2593 csky_get_reg_val (char *str, int *len)
2594 {
2595 int regno = 0;
2596 char *s = str;
2597 regno = csky_get_general_regno (mach_flag, str, &s);
2598 *len = (s - str);
2599 return regno;
2600 }
2601
2602 static bool
2603 is_reg_sp_with_bracket (char **oper)
2604 {
2605 int reg;
2606 int sp_idx;
2607 int len;
2608
2609 if (IS_CSKY_V1 (mach_flag))
2610 sp_idx = 0;
2611 else
2612 sp_idx = 14;
2613
2614 if (**oper != '(')
2615 return false;
2616 *oper += 1;
2617 reg = csky_get_reg_val (*oper, &len);
2618 *oper += len;
2619 if (reg == sp_idx)
2620 {
2621 if (**oper != ')')
2622 {
2623 SET_ERROR_STRING (ERROR_UNDEFINE,
2624 "Operand format is error. '(sp)' expected");
2625 return false;
2626 }
2627 *oper += 1;
2628 csky_insn.val[csky_insn.idx++] = sp_idx;
2629 return true;
2630 }
2631
2632 SET_ERROR_STRING (ERROR_UNDEFINE,
2633 "Operand format is error. '(sp)' expected");
2634 return false;
2635 }
2636
2637 static bool
2638 is_reg_sp (char **oper)
2639 {
2640 char sp_name[16];
2641 int sp_idx;
2642 int len;
2643 if (IS_CSKY_V1 (mach_flag))
2644 sp_idx = 0;
2645 else
2646 sp_idx = 14;
2647
2648 /* ABI names: "sp". */
2649 if (memcmp (*oper, "sp", 2) == 0)
2650 {
2651 *oper += 2;
2652 csky_insn.val[csky_insn.idx++] = sp_idx;
2653 return true;
2654 }
2655
2656 len = sprintf (sp_name, "r%d", sp_idx);
2657 if (memcmp (*oper, sp_name, len) == 0)
2658 {
2659 *oper += len;
2660 csky_insn.val[csky_insn.idx++] = sp_idx;
2661 return true;
2662 }
2663
2664 return false;
2665 }
2666
2667 static int
2668 csky_get_freg_val (char *str, int *len)
2669 {
2670 int reg = 0;
2671 char *s = NULL;
2672 if ((TOLOWER(str[0]) == 'v' || TOLOWER(str[0]) == 'f')
2673 && (TOLOWER(str[1]) == 'r'))
2674 {
2675 /* It is fpu register. */
2676 s = &str[2];
2677 while (ISDIGIT (*s))
2678 {
2679 reg = reg * 10 + (*s) - '0';
2680 s++;
2681 }
2682 if (reg > 31)
2683 return -1;
2684 }
2685 else
2686 return -1;
2687 *len = s - str;
2688 return reg;
2689 }
2690
2691 static bool
2692 is_reglist_legal (char **oper)
2693 {
2694 int reg1 = -1;
2695 int reg2 = -1;
2696 int len = 0;
2697 reg1 = csky_get_reg_val (*oper, &len);
2698 *oper += len;
2699
2700 if (reg1 == -1 || (IS_CSKY_V1 (mach_flag) && (reg1 == 0 || reg1 == 15)))
2701 {
2702 SET_ERROR_STRING (ERROR_REG_FORMAT,
2703 "The first reg must not be r0/r15");
2704 return false;
2705 }
2706
2707 if (**oper != '-')
2708 {
2709 SET_ERROR_STRING (ERROR_REG_FORMAT,
2710 "The operand format must be rx-ry");
2711 return false;
2712 }
2713 *oper += 1;
2714
2715 reg2 = csky_get_reg_val (*oper, &len);
2716 *oper += len;
2717
2718 if (reg2 == -1 || (IS_CSKY_V1 (mach_flag) && reg1 == 15))
2719 {
2720 SET_ERROR_STRING (ERROR_REG_FORMAT,
2721 "The operand format must be r15 in C-SKY V1");
2722 return false;
2723 }
2724 if (IS_CSKY_V2 (mach_flag))
2725 {
2726 if (reg2 < reg1)
2727 {
2728 SET_ERROR_STRING (ERROR_REG_FORMAT,
2729 "The operand format must be rx-ry (rx < ry)");
2730 return false;
2731 }
2732 reg2 = reg2 - reg1;
2733 reg1 <<= 5;
2734 reg1 |= reg2;
2735 }
2736 csky_insn.val[csky_insn.idx++] = reg1;
2737 return true;
2738 }
2739
2740 static bool
2741 is_freglist_legal (char **oper)
2742 {
2743 int reg1 = -1;
2744 int reg2 = -1;
2745 int len = 0;
2746 int shift = 0;
2747 reg1 = csky_get_freg_val (*oper, &len);
2748 *oper += len;
2749
2750 if (reg1 == -1)
2751 {
2752 SET_ERROR_STRING (ERROR_REG_FORMAT,
2753 "The fpu register format is not recognized.");
2754 return false;
2755 }
2756
2757 if (**oper != '-')
2758 {
2759 SET_ERROR_STRING (ERROR_REG_FORMAT,
2760 "The operand format must be vrx-vry/frx-fry.");
2761 return false;
2762 }
2763 *oper += 1;
2764
2765 reg2 = csky_get_freg_val (*oper, &len);
2766 *oper += len;
2767
2768 if (reg2 == -1)
2769 {
2770 SET_ERROR_STRING (ERROR_REG_FORMAT,
2771 "The fpu register format is not recognized.");
2772 return false;
2773 }
2774 if (reg2 < reg1)
2775 {
2776 SET_ERROR_STRING (ERROR_REG_FORMAT,
2777 "The operand format must be rx-ry(rx < ry)");
2778 return false;
2779 }
2780
2781 reg2 = reg2 - reg1;
2782 /* The fldm/fstm in CSKY_ISA_FLOAT_7E60 has 5 bits frz(reg1). */
2783 shift = 4;
2784 if (startswith (csky_insn.opcode->mnemonic, "fstm")
2785 || startswith (csky_insn.opcode->mnemonic, "fldm"))
2786 {
2787 if ((!(isa_flag & CSKY_ISA_FLOAT_7E60)
2788 && (reg2 > (int)15 || reg1 > 15))
2789 || ((isa_flag & CSKY_ISA_FLOAT_7E60)
2790 && (reg2 > (int)31 || reg1 > (int)31)))
2791 {
2792 /* ISA_FLOAT_E1 fstm/fldm fry-frx is within 15.
2793 ISA_FLOAT_7E60 fstm(u)/fldm(u) frx-fry is within 31. */
2794 SET_ERROR_STRING(ERROR_REG_FORMAT, (void *)"frx-fry is over range");
2795 return false;
2796 }
2797 if ((mach_flag & CSKY_ARCH_MASK) == CSKY_ARCH_860)
2798 {
2799 shift = 5;
2800 }
2801 }
2802 else
2803 {
2804 if (reg2 > (int)0x3) {
2805 SET_ERROR_STRING(ERROR_REG_FORMAT, (void *)"vry-vrx is over range");
2806 return false;
2807 }
2808 }
2809 reg2 <<= shift;
2810 reg1 |= reg2;
2811 csky_insn.val[csky_insn.idx++] = reg1;
2812 return true;
2813 }
2814
2815 static bool
2816 is_reglist_dash_comma_legal (char **oper, struct operand *oprnd)
2817 {
2818 int reg1 = -1;
2819 int reg2 = -1;
2820 int len = 0;
2821 int list = 0;
2822 int flag = 0;
2823 int temp = 0;
2824 while (**oper != '\n' && **oper != '\0')
2825 {
2826 reg1 = csky_get_reg_val (*oper, &len);
2827 if (reg1 == -1)
2828 {
2829 SET_ERROR_STRING (ERROR_REG_LIST, NULL);
2830 return false;
2831 }
2832 flag |= (1 << reg1);
2833 *oper += len;
2834 if (**oper == '-')
2835 {
2836 *oper += 1;
2837 reg2 = csky_get_reg_val (*oper, &len);
2838 if (reg2 == -1)
2839 {
2840 SET_ERROR_STRING (ERROR_REG_LIST, NULL);
2841 return false;
2842 }
2843 *oper += len;
2844 if (reg1 > reg2)
2845 {
2846 SET_ERROR_STRING (ERROR_REG_LIST, NULL);
2847 return false;
2848 }
2849 while (reg2 >= reg1)
2850 {
2851 flag |= (1 << reg2);
2852 reg2--;
2853 }
2854 }
2855 if (**oper == ',')
2856 *oper += 1;
2857 }
2858 /* The reglist: r4-r11, r15, r16-r17, r28. */
2859 #define REGLIST_BITS 0x10038ff0
2860 if (flag & ~(REGLIST_BITS))
2861 {
2862 SET_ERROR_STRING (ERROR_REG_LIST, NULL);
2863 return false;
2864 }
2865 /* Check r4-r11. */
2866 int i = 4;
2867 while (i <= 11)
2868 {
2869 if (flag & (1 << i))
2870 temp = i - 4 + 1;
2871 i++;
2872 }
2873 list |= temp;
2874
2875 /* Check r15. */
2876 if (flag & (1 << 15))
2877 list |= (1 << 4);
2878
2879 /* Check r16-r17. */
2880 i = 16;
2881 temp = 0;
2882 while (i <= 17)
2883 {
2884 if (flag & (1 << i))
2885 temp = i - 16 + 1;
2886 i++;
2887 }
2888 list |= (temp << 5);
2889
2890 /* Check r28. */
2891 if (flag & (1 << 28))
2892 list |= (1 << 8);
2893 if (oprnd->mask == OPRND_MASK_0_4 && (list & ~OPRND_MASK_0_4))
2894 {
2895 SET_ERROR_STRING (ERROR_REG_LIST, NULL);
2896 return false;
2897 }
2898 csky_insn.val[csky_insn.idx++] = list;
2899 return true;
2900 }
2901
2902 static bool
2903 is_reg_lshift_illegal (char **oper, int is_float)
2904 {
2905 int value;
2906 int len;
2907 int reg;
2908 reg = csky_get_reg_val (*oper, &len);
2909 if (reg == -1)
2910 {
2911 SET_ERROR_STRING (ERROR_REG_FORMAT, "The register must be r0-r31.");
2912 return false;
2913 }
2914
2915 *oper += len;
2916 if ((*oper)[0] != '<' || (*oper)[1] != '<')
2917 {
2918 SET_ERROR_STRING (ERROR_UNDEFINE,
2919 "Operand format error; should be (rx, ry << n)");
2920 return false;
2921 }
2922 *oper += 2;
2923
2924 expressionS e;
2925 char *new_oper = parse_exp (*oper, &e);
2926 if (e.X_op == O_constant)
2927 {
2928 *oper = new_oper;
2929 /* The immediate must be in [0, 3]. */
2930 if (e.X_add_number < 0 || e.X_add_number > 3)
2931 {
2932 SET_ERROR_STRING (ERROR_IMM_OVERFLOW, NULL);
2933 return false;
2934 }
2935 }
2936 else
2937 {
2938 SET_ERROR_STRING (ERROR_EXP_CONSTANT, NULL);
2939 return false;
2940 }
2941 if (is_float)
2942 value = (reg << 2) | e.X_add_number;
2943 else
2944 value = (reg << 5) | (1 << e.X_add_number);
2945 csky_insn.val[csky_insn.idx++] = value;
2946
2947 return true;
2948 }
2949
2950 static bool
2951 is_imm_within_range (char **oper, int min, int max)
2952 {
2953 expressionS e;
2954 bool ret = false;
2955 char *new_oper = parse_exp (*oper, &e);
2956 if (e.X_op == O_constant)
2957 {
2958 ret = true;
2959 *oper = new_oper;
2960 if (e.X_add_number < min || e.X_add_number > max)
2961 {
2962 ret = false;
2963 SET_ERROR_STRING (ERROR_IMM_OVERFLOW, NULL);
2964 }
2965 if (!e.X_unsigned)
2966 e.X_add_number |= 0x80000000;
2967 csky_insn.val[csky_insn.idx++] = e.X_add_number;
2968 }
2969 else
2970 SET_ERROR_STRING(ERROR_IMM_ILLEGAL, NULL);
2971
2972 return ret;
2973 }
2974
2975 static bool
2976 is_imm_within_range_ext (char **oper, int min, int max, int ext)
2977 {
2978 expressionS e;
2979 bool ret = false;
2980 char *new_oper = parse_exp (*oper, &e);
2981 if (e.X_op == O_constant)
2982 {
2983 ret = true;
2984 *oper = new_oper;
2985 if ((int)e.X_add_number != ext
2986 && (e.X_add_number < min || e.X_add_number > max))
2987 {
2988 ret = false;
2989 SET_ERROR_STRING (ERROR_IMM_OVERFLOW, NULL);
2990 }
2991 csky_insn.val[csky_insn.idx++] = e.X_add_number;
2992 }
2993
2994 else
2995 SET_ERROR_STRING(ERROR_IMM_ILLEGAL, NULL);
2996
2997 return ret;
2998 }
2999
3000 static bool
3001 is_oimm_within_range (char **oper, int min, int max)
3002 {
3003 expressionS e;
3004 bool ret = false;
3005 char *new_oper = parse_exp (*oper, &e);
3006 if (e.X_op == O_constant)
3007 {
3008 ret = true;
3009 *oper = new_oper;
3010 if (e.X_add_number < min || e.X_add_number > max)
3011 {
3012 ret = false;
3013 SET_ERROR_STRING (ERROR_IMM_OVERFLOW, NULL);
3014 }
3015 csky_insn.val[csky_insn.idx++] = e.X_add_number - 1;
3016 }
3017 else
3018 SET_ERROR_STRING (ERROR_IMM_ILLEGAL, NULL);
3019
3020 return ret;
3021 }
3022
3023 static bool
3024 is_psr_bit (char **oper)
3025 {
3026 const struct psrbit *bits;
3027 int i = 0;
3028
3029 if (IS_CSKY_V1 (mach_flag))
3030 bits = cskyv1_psr_bits;
3031 else
3032 bits = cskyv2_psr_bits;
3033
3034 while (bits[i].name != NULL)
3035 {
3036 if (bits[i].isa && !(bits[i].isa & isa_flag))
3037 {
3038 i++;
3039 continue;
3040 }
3041 if (strncasecmp (*oper, bits[i].name, strlen (bits[i].name)) == 0)
3042 {
3043 *oper += strlen (bits[i].name);
3044 csky_insn.val[csky_insn.idx] |= bits[i].value;
3045 return true;
3046 }
3047 i++;
3048 }
3049 SET_ERROR_STRING (ERROR_OPCODE_PSRBIT, NULL);
3050 return false;
3051 }
3052
3053 static bool
3054 parse_type_cpidx (char** oper)
3055 {
3056 char *s = *oper;
3057 int idx;
3058 if (s[0] == 'c' && s[1] == 'p')
3059 {
3060 if (ISDIGIT (s[2]) && ISDIGIT (s[3]) && ! ISDIGIT (s[4]))
3061 {
3062 idx = (s[2] - '0') * 10 + s[3] - '0';
3063 *oper += 4;
3064 }
3065 else if (ISDIGIT (s[2]) && !ISDIGIT (s[3]))
3066 {
3067 idx = s[2] - '0';
3068 *oper += 3;
3069 }
3070 else
3071 return false;
3072 }
3073 else
3074 {
3075 expressionS e;
3076 *oper = parse_exp (*oper, &e);
3077 if (e.X_op != O_constant)
3078 {
3079 /* Can not recognize the operand. */
3080 return false;
3081 }
3082 idx = e.X_add_number;
3083 }
3084
3085 csky_insn.val[csky_insn.idx++] = idx;
3086
3087 return true;
3088 }
3089
3090 static bool
3091 parse_type_cpreg (char** oper)
3092 {
3093 expressionS e;
3094
3095 if (strncasecmp (*oper, "cpr", 3) != 0)
3096 {
3097 SET_ERROR_STRING(ERROR_CPREG_ILLEGAL, *oper);
3098 return false;
3099 }
3100
3101 *oper += 3;
3102
3103 *oper = parse_exp (*oper, &e);
3104 if (e.X_op != O_constant)
3105 {
3106 SET_ERROR_STRING(ERROR_CPREG_ILLEGAL, *oper);
3107 return false;
3108 }
3109
3110 csky_insn.val[csky_insn.idx++] = e.X_add_number;
3111
3112 return true;
3113 }
3114
3115 static bool
3116 parse_type_cpcreg (char** oper)
3117 {
3118 expressionS e;
3119
3120 if (strncasecmp (*oper, "cpcr", 4) != 0)
3121 {
3122 SET_ERROR_STRING(ERROR_CPREG_ILLEGAL, *oper);
3123 return false;
3124 }
3125
3126 *oper += 4;
3127
3128 *oper = parse_exp (*oper, &e);
3129 if (e.X_op != O_constant)
3130 {
3131 SET_ERROR_STRING(ERROR_CPREG_ILLEGAL, *oper);
3132 return false;
3133 }
3134
3135 csky_insn.val[csky_insn.idx++] = e.X_add_number;
3136
3137 return true;
3138 }
3139
3140 static bool
3141 parse_type_areg (char** oper)
3142 {
3143 int i = 0;
3144 int len = 0;
3145 i = csky_get_reg_val (*oper, &len);
3146 if (i == -1)
3147 {
3148 SET_ERROR_STRING (ERROR_GREG_ILLEGAL, NULL);
3149 return false;
3150 }
3151 *oper += len;
3152 csky_insn.val[csky_insn.idx++] = i;
3153
3154 return true;
3155 }
3156
3157 static bool
3158 parse_type_freg (char** oper, int even)
3159 {
3160 int reg;
3161 int len;
3162 reg = csky_get_freg_val (*oper, &len);
3163 if (reg == -1)
3164 {
3165 SET_ERROR_STRING (ERROR_REG_FORMAT,
3166 (void *)"The fpu register format is not recognized.");
3167 return false;
3168 }
3169 *oper += len;
3170 csky_insn.opcode_end = *oper;
3171 if (even && reg & 0x1)
3172 {
3173 SET_ERROR_STRING (ERROR_EXP_EVEN_FREG, NULL);
3174 return false;
3175 }
3176
3177 if (IS_CSKY_V2 (mach_flag)
3178 && ((csky_insn.opcode->isa_flag32 & CSKY_ISA_VDSP_2)
3179 || !(csky_insn.opcode->isa_flag32 & CSKY_ISA_FLOAT_7E60))
3180 && reg > 15)
3181 {
3182 if ((csky_insn.opcode->isa_flag32 & CSKY_ISA_VDSP_2))
3183 {
3184 SET_ERROR_INTEGER (ERROR_VREG_OVER_RANGE, reg);
3185 }
3186 else
3187 {
3188 SET_ERROR_INTEGER (ERROR_FREG_OVER_RANGE, reg);
3189 }
3190 return false;
3191 }
3192 /* TODO: recognize vreg or freg. */
3193 if (reg > 31)
3194 {
3195 SET_ERROR_INTEGER (ERROR_VREG_OVER_RANGE, reg);
3196 }
3197 csky_insn.val[csky_insn.idx++] = reg;
3198 return true;
3199 }
3200
3201 static bool
3202 parse_ldst_imm (char **oper, struct csky_opcode_info *op ATTRIBUTE_UNUSED,
3203 struct operand *oprnd)
3204 {
3205 unsigned int mask = oprnd->mask;
3206 int max = 1;
3207 int shift = 0;
3208
3209 shift = oprnd->shift;
3210
3211 while (mask)
3212 {
3213 if (mask & 1)
3214 max <<= 1;
3215 mask >>= 1;
3216 }
3217 max = max << shift;
3218
3219 if (**oper == '\0' || **oper == ')')
3220 {
3221 csky_insn.val[csky_insn.idx++] = 0;
3222 return true;
3223 }
3224
3225 expressionS e;
3226 *oper = parse_exp (*oper, &e);
3227 if (e.X_op != O_constant)
3228 {
3229 /* Not a constant. */
3230 SET_ERROR_STRING(ERROR_UNDEFINE, (void *)"Operand format is error. eg. \"ld rz, (rx, n)\"");
3231 return false;
3232 }
3233 else if (e.X_add_number < 0 || e.X_add_number >= max)
3234 {
3235 /* Out of range. */
3236 SET_ERROR_STRING(ERROR_IMM_OVERFLOW, NULL);
3237 return false;
3238 }
3239 if ((e.X_add_number % (1 << shift)) != 0)
3240 {
3241 /* Not aligned. */
3242 SET_ERROR_INTEGER (ERROR_OFFSET_UNALIGNED, ((unsigned long)1 << shift));
3243 return false;
3244 }
3245
3246 csky_insn.val[csky_insn.idx++] = e.X_add_number >> shift;
3247
3248 return true;
3249
3250 }
3251
3252 static unsigned int
3253 csky_count_operands (char *str)
3254 {
3255 char *oper_end = str;
3256 unsigned int oprnd_num;
3257 int bracket_cnt = 0;
3258
3259 if (is_end_of_line[(unsigned char) *oper_end])
3260 oprnd_num = 0;
3261 else
3262 oprnd_num = 1;
3263
3264 /* Count how many operands. */
3265 if (oprnd_num)
3266 while (!is_end_of_line[(unsigned char) *oper_end])
3267 {
3268 if (*oper_end == '(' || *oper_end == '<')
3269 {
3270 bracket_cnt++;
3271 oper_end++;
3272 continue;
3273 }
3274 if (*oper_end == ')' || *oper_end == '>')
3275 {
3276 bracket_cnt--;
3277 oper_end++;
3278 continue;
3279 }
3280 if (!bracket_cnt && *oper_end == ',')
3281 oprnd_num++;
3282 oper_end++;
3283 }
3284 return oprnd_num;
3285 }
3286
3287 /* End of the operand parsing helper functions. */
3288
3289 /* Parse the opcode part of an instruction. Fill in the csky_insn
3290 state and return true on success, false otherwise. */
3291
3292 static bool
3293 parse_opcode (char *str)
3294 {
3295 #define IS_OPCODE32F(a) (*(a - 2) == '3' && *(a - 1) == '2')
3296 #define IS_OPCODE16F(a) (*(a - 2) == '1' && *(a - 1) == '6')
3297
3298 /* TRUE if this opcode has a suffix, like 'lrw.h'. */
3299 unsigned int has_suffix = false;
3300 unsigned int nlen = 0;
3301 char *opcode_end;
3302 char name[OPCODE_MAX_LEN + 1];
3303 char macro_name[OPCODE_MAX_LEN + 1];
3304
3305 /* Remove space ahead of string. */
3306 while (ISSPACE (*str))
3307 str++;
3308 opcode_end = str;
3309
3310 /* Find the opcode end. */
3311 while (nlen < OPCODE_MAX_LEN
3312 && !is_end_of_line [(unsigned char) *opcode_end]
3313 && *opcode_end != ' ')
3314 {
3315 /* Is csky force 32 or 16 instruction? */
3316 if (IS_CSKY_V2 (mach_flag)
3317 && *opcode_end == '.' && !has_suffix)
3318 {
3319 has_suffix = true;
3320 if (IS_OPCODE32F (opcode_end))
3321 {
3322 csky_insn.flag_force = INSN_OPCODE32F;
3323 nlen -= 2;
3324 }
3325 else if (IS_OPCODE16F (opcode_end))
3326 {
3327 csky_insn.flag_force = INSN_OPCODE16F;
3328 nlen -= 2;
3329 }
3330 }
3331 name[nlen] = *opcode_end;
3332 nlen++;
3333 opcode_end++;
3334 }
3335
3336 /* Is csky force 32 or 16 instruction? */
3337 if (!has_suffix)
3338 {
3339 if (IS_CSKY_V2 (mach_flag) && IS_OPCODE32F (opcode_end))
3340 {
3341 csky_insn.flag_force = INSN_OPCODE32F;
3342 nlen -= 2;
3343 }
3344 else if (IS_OPCODE16F (opcode_end))
3345 {
3346 csky_insn.flag_force = INSN_OPCODE16F;
3347 nlen -= 2;
3348 }
3349 }
3350 name[nlen] = '\0';
3351
3352 /* Generate macro_name for finding hash in macro hash_table. */
3353 if (has_suffix)
3354 nlen += 2;
3355 strncpy (macro_name, str, nlen);
3356 macro_name[nlen] = '\0';
3357
3358 /* Get csky_insn.opcode_end. */
3359 while (ISSPACE (*opcode_end))
3360 opcode_end++;
3361 csky_insn.opcode_end = opcode_end;
3362
3363 /* Count the operands. */
3364 csky_insn.number = csky_count_operands (opcode_end);
3365
3366 /* Find hash by name in csky_macros_hash and csky_opcodes_hash. */
3367 csky_insn.macro = (struct csky_macro_info *) str_hash_find (csky_macros_hash,
3368 macro_name);
3369 csky_insn.opcode = (struct csky_opcode *) str_hash_find (csky_opcodes_hash,
3370 name);
3371
3372 if (csky_insn.macro == NULL && csky_insn.opcode == NULL)
3373 return false;
3374 return true;
3375 }
3376
3377 /* Main dispatch routine to parse operand OPRND for opcode OP from string
3378 *OPER. */
3379
3380 static bool
3381 get_operand_value (struct csky_opcode_info *op,
3382 char **oper, struct operand *oprnd)
3383 {
3384 struct soperand *soprnd = NULL;
3385 if (oprnd->mask == HAS_SUB_OPERAND)
3386 {
3387 /* It has sub operand, it must be like:
3388 (oprnd1, oprnd2)
3389 or
3390 <oprnd1, oprnd2>
3391 We will check the format here. */
3392 soprnd = (struct soperand *) oprnd;
3393 char lc = 0;
3394 char rc = 0;
3395 char *s = *oper;
3396 int bracket_cnt = 0;
3397 if (oprnd->type == OPRND_TYPE_BRACKET)
3398 {
3399 lc = '(';
3400 rc = ')';
3401 }
3402 else if (oprnd->type == OPRND_TYPE_ABRACKET)
3403 {
3404 lc = '<';
3405 rc = '>';
3406 }
3407
3408 if (**oper == lc)
3409 {
3410 *oper += 1;
3411 s += 1;
3412 }
3413 else
3414 {
3415 SET_ERROR_STRING ((oprnd->type == OPRND_TYPE_BRACKET
3416 ? ERROR_MISSING_LBRACKET
3417 : ERROR_MISSING_LANGLE_BRACKETS), NULL);
3418 return false;
3419 }
3420
3421 /* If the oprnd2 is an immediate, it can not be parsed
3422 that end with ')'/'>'. Modify ')'/'>' to '\0'. */
3423 while ((*s != rc || bracket_cnt != 0) && (*s != '\n' && *s != '\0'))
3424 {
3425 if (*s == lc)
3426 bracket_cnt++;
3427 else if (*s == rc)
3428 bracket_cnt--;
3429 s++;
3430 }
3431
3432 if (*s == rc)
3433 *s = '\0';
3434 else
3435 {
3436 SET_ERROR_STRING ((oprnd->type == OPRND_TYPE_BRACKET
3437 ? ERROR_MISSING_RBRACKET
3438 : ERROR_MISSING_RANGLE_BRACKETS), NULL);
3439 return false;
3440 }
3441
3442 if (!get_operand_value (op, oper, &soprnd->subs[0]))
3443 {
3444 *s = rc;
3445 return false;
3446 }
3447 if (**oper == ',')
3448 *oper += 1;
3449 else if (**oper != '\0')
3450 {
3451 SET_ERROR_STRING (ERROR_MISSING_COMMA, NULL);
3452 return false;
3453 }
3454
3455 if (!get_operand_value (op, oper, &soprnd->subs[1]))
3456 {
3457 *s = rc;
3458 return false;
3459 }
3460
3461 *s = rc;
3462 *oper += 1;
3463 return true;
3464 }
3465
3466 switch (oprnd->type)
3467 {
3468 /* TODO: add opcode type here, log errors in the function.
3469 If REGLIST, then j = csky_insn.number - 1.
3470 If there is needed to parse expressions, it will be
3471 handled here. */
3472 case OPRND_TYPE_CTRLREG:
3473 /* some parse. */
3474 return parse_type_ctrlreg (oper);
3475 case OPRND_TYPE_AREG:
3476 return parse_type_areg (oper);
3477 case OPRND_TYPE_FREG:
3478 case OPRND_TYPE_VREG:
3479 return parse_type_freg (oper, 0);
3480 case OPRND_TYPE_FEREG:
3481 return parse_type_freg (oper, 1);
3482 case OPRND_TYPE_CPCREG:
3483 return parse_type_cpcreg (oper);
3484 case OPRND_TYPE_CPREG:
3485 return parse_type_cpreg (oper);
3486 case OPRND_TYPE_CPIDX:
3487 return parse_type_cpidx (oper);
3488 case OPRND_TYPE_GREG0_7:
3489 case OPRND_TYPE_GREG0_15:
3490 {
3491 int len;
3492 long reg;
3493 reg = csky_get_reg_val (*oper, &len);
3494
3495 if (reg == -1)
3496 {
3497 SET_ERROR_STRING (ERROR_GREG_ILLEGAL, NULL);
3498 return false;
3499 }
3500 else if ((oprnd->type == OPRND_TYPE_GREG0_7 && reg > 7)
3501 || (oprnd->type == OPRND_TYPE_GREG0_15 && reg > 15))
3502 {
3503 SET_ERROR_INTEGER (ERROR_REG_OVER_RANGE, reg);
3504 return false;
3505 }
3506 *oper += len;
3507 csky_insn.val[csky_insn.idx++] = reg;
3508 return true;
3509 }
3510 case OPRND_TYPE_REGnsplr:
3511 {
3512 int len;
3513 long reg;
3514 reg = csky_get_reg_val (*oper, &len);
3515
3516 if (reg == -1
3517 || (IS_CSKY_V1 (mach_flag)
3518 && (reg == V1_REG_SP || reg == V1_REG_LR)))
3519 {
3520 SET_ERROR_STRING (ERROR_REG_OVER_RANGE, reg);
3521 return false;
3522 }
3523 csky_insn.val[csky_insn.idx++] = reg;
3524 *oper += len;
3525 return true;;
3526 }
3527 case OPRND_TYPE_REGnr4_r7:
3528 {
3529 int len;
3530 int reg;
3531 if (**oper == '(')
3532 *oper += 1;
3533 reg = csky_get_reg_val (*oper, &len);
3534 if (reg == -1 || (reg <= 7 && reg >= 4))
3535 return false;
3536
3537 csky_insn.val[csky_insn.idx++] = reg;
3538 *oper += len;
3539
3540 if (**oper == ')')
3541 *oper += 1;
3542 return true;;
3543 }
3544 case OPRND_TYPE_REGr4_r7:
3545 if (memcmp (*oper, "r4-r7", sizeof ("r4-r7") - 1) == 0)
3546 {
3547 *oper += sizeof ("r4-r7") - 1;
3548 csky_insn.val[csky_insn.idx++] = 0;
3549 return true;
3550 }
3551 SET_ERROR_STRING (ERROR_OPCODE_ILLEGAL, NULL);
3552 return false;
3553 case OPRND_TYPE_IMM_LDST:
3554 return parse_ldst_imm (oper, op, oprnd);
3555 case OPRND_TYPE_IMM_FLDST:
3556 return parse_ldst_imm (oper, op, oprnd);
3557 case OPRND_TYPE_IMM1b:
3558 return is_imm_within_range (oper, 0, 1);
3559 case OPRND_TYPE_IMM2b:
3560 return is_imm_within_range (oper, 0, 3);
3561 case OPRND_TYPE_IMM2b_JMPIX:
3562 /* ck802j support jmpix16, but not support jmpix32. */
3563 if (IS_CSKY_ARCH_802 (mach_flag)
3564 && (op->opcode & 0xffff0000) != 0)
3565 {
3566 SET_ERROR_STRING (ERROR_OPCODE_ILLEGAL, NULL);
3567 return false;
3568 }
3569 *oper = parse_exp (*oper, &csky_insn.e1);
3570 if (csky_insn.e1.X_op == O_constant)
3571 {
3572 csky_insn.opcode_end = *oper;
3573 if (csky_insn.e1.X_add_number & 0x7)
3574 {
3575 SET_ERROR_STRING (ERROR_JMPIX_OVER_RANGE, NULL);
3576 return false;
3577 }
3578 csky_insn.val[csky_insn.idx++]
3579 = (csky_insn.e1.X_add_number >> 3) - 2;
3580 }
3581 return true;
3582 case OPRND_TYPE_IMM4b:
3583 return is_imm_within_range (oper, 0, 15);
3584 case OPRND_TYPE_IMM5b:
3585 return is_imm_within_range (oper, 0, 31);
3586 /* This type for "bgeni" in csky v1 ISA. */
3587 case OPRND_TYPE_IMM5b_7_31:
3588 if (is_imm_within_range (oper, 0, 31))
3589 {
3590 int val = csky_insn.val[csky_insn.idx - 1];
3591 /* immediate values of 0 -> 6 translate to movi. */
3592 if (val <= 6)
3593 {
3594 const char *name = "movi";
3595 csky_insn.opcode = (struct csky_opcode *)
3596 str_hash_find (csky_opcodes_hash, name);
3597 csky_insn.val[csky_insn.idx - 1] = 1 << val;
3598 }
3599 return true;
3600 }
3601 else
3602 return false;
3603
3604 case OPRND_TYPE_IMM5b_1_31:
3605 return is_imm_within_range (oper, 1, 31);
3606 case OPRND_TYPE_IMM5b_POWER:
3607 if (is_imm_within_range_ext (oper, 1, (1u << 31) - 1, 1u << 31))
3608 {
3609 int log;
3610 int val = csky_insn.val[csky_insn.idx - 1];
3611 log = csky_log_2 (val);
3612 csky_insn.val[csky_insn.idx - 1] = log;
3613 return log != -1;
3614 }
3615 else
3616 return false;
3617
3618 /* This type for "mgeni" in csky v1 ISA. */
3619 case OPRND_TYPE_IMM5b_7_31_POWER:
3620 if (is_imm_within_range_ext (oper, 1, (1u << 31) - 1, 1u << 31))
3621 {
3622 int log;
3623 int val = csky_insn.val[csky_insn.idx - 1];
3624 log = csky_log_2 (val);
3625 /* Immediate values of 0 -> 6 translate to movi. */
3626 if (log <= 6)
3627 {
3628 const char *name = "movi";
3629 csky_insn.opcode = (struct csky_opcode *)
3630 str_hash_find (csky_opcodes_hash, name);
3631 as_warn (_("translating mgeni to movi"));
3632 }
3633 else
3634 csky_insn.val[csky_insn.idx - 1] = log;
3635 return log != -1;
3636 }
3637 else
3638 return false;
3639
3640 case OPRND_TYPE_IMM5b_LS:
3641 return is_imm_within_range (oper,
3642 0,
3643 csky_insn.val[csky_insn.idx - 1]);
3644 case OPRND_TYPE_IMM5b_RORI:
3645 {
3646 unsigned max_shift = IS_CSKY_V1 (mach_flag) ? 31 : 32;
3647
3648 if (is_imm_within_range (oper, 1, max_shift))
3649 {
3650 int i = csky_insn.idx - 1;
3651 csky_insn.val[i] = 32 - csky_insn.val[i];
3652 return true;
3653 }
3654 else
3655 return false;
3656 }
3657
3658 case OPRND_TYPE_IMM5b_BMASKI:
3659 /* For csky v1 bmask inst. */
3660
3661 if (!is_imm_within_range_ext (oper, 8, 31, 0))
3662 {
3663 unsigned int mask_val = csky_insn.val[csky_insn.idx - 1];
3664 if (mask_val > 0 && mask_val < 8)
3665 {
3666 const char *op_movi = "movi";
3667 csky_insn.opcode = (struct csky_opcode *)
3668 str_hash_find (csky_opcodes_hash, op_movi);
3669 if (csky_insn.opcode == NULL)
3670 return false;
3671 csky_insn.val[csky_insn.idx - 1] = (1 << mask_val) - 1;
3672 return true;
3673 }
3674 }
3675 return true;
3676
3677 case OPRND_TYPE_IMM5b_VSH:
3678 /* For vshri.T and vshli.T. */
3679 if (is_imm_within_range (oper, 0, 31))
3680 {
3681 int val = csky_insn.val[csky_insn.idx - 1];
3682 val = (val << 1) | (val >> 4);
3683 val &= 0x1f;
3684 csky_insn.val[csky_insn.idx - 1] = val;
3685 return true;
3686 }
3687 return false;
3688 case OPRND_TYPE_IMM8b_BMASKI:
3689 /* For csky v2 bmask, which will transfer to 16bits movi. */
3690 if (is_imm_within_range (oper, 1, 8))
3691 {
3692 unsigned int mask_val = csky_insn.val[csky_insn.idx - 1];
3693 csky_insn.val[csky_insn.idx - 1] = (1 << mask_val) - 1;
3694 return true;
3695 }
3696 return false;
3697 case OPRND_TYPE_OIMM4b:
3698 return is_oimm_within_range (oper, 1, 16);
3699 case OPRND_TYPE_OIMM5b:
3700 return is_oimm_within_range (oper, 1, 32);
3701 case OPRND_TYPE_OIMM5b_IDLY:
3702 if (is_imm_within_range (oper, 0, 32))
3703 {
3704 /* imm5b for idly n: 0<=n<4, imm5b=3; 4<=n<=32, imm5b=n-1. */
3705 unsigned long imm = csky_insn.val[csky_insn.idx - 1];
3706 if (imm < 4)
3707 {
3708 csky_show_error (WARNING_IDLY, 0, (void *)imm, NULL);
3709 imm = 3;
3710 }
3711 else imm--;
3712 csky_insn.val[csky_insn.idx - 1] = imm;
3713 return true;
3714 }
3715 else
3716 return false;
3717
3718 /* For csky v2 bmask inst. */
3719 case OPRND_TYPE_OIMM5b_BMASKI:
3720 if (!is_oimm_within_range (oper, 17, 32))
3721 {
3722 int mask_val = csky_insn.val[csky_insn.idx - 1];
3723 if (mask_val + 1 == 0)
3724 return true;
3725 if (mask_val > 0 && mask_val < 16)
3726 {
3727 const char *op_movi = "movi";
3728 csky_insn.opcode = (struct csky_opcode *)
3729 str_hash_find (csky_opcodes_hash, op_movi);
3730 if (csky_insn.opcode == NULL)
3731 return false;
3732 csky_insn.val[csky_insn.idx - 1] = (1 << (mask_val + 1)) - 1;
3733 return true;
3734 }
3735 }
3736 return true;
3737 case OPRND_TYPE_IMM7b:
3738 return is_imm_within_range (oper, 0, 127);
3739 case OPRND_TYPE_IMM8b:
3740 return is_imm_within_range (oper, 0, 255);
3741 case OPRND_TYPE_IMM9b:
3742 return is_imm_within_range (oper, -256, 255);
3743 case OPRND_TYPE_IMM12b:
3744 return is_imm_within_range (oper, 0, 4095);
3745 case OPRND_TYPE_IMM15b:
3746 return is_imm_within_range (oper, 0, 0xfffff);
3747 case OPRND_TYPE_IMM16b:
3748 return is_imm_within_range (oper, 0, 65535);
3749 case OPRND_TYPE_OIMM16b:
3750 return is_oimm_within_range (oper, 1, 65536);
3751 case OPRND_TYPE_IMM32b:
3752 {
3753 expressionS e;
3754 char *new_oper = parse_exp (*oper, &e);
3755 if (e.X_op == O_constant)
3756 {
3757 *oper = new_oper;
3758 csky_insn.val[csky_insn.idx++] = e.X_add_number;
3759 return true;
3760 }
3761 return false;
3762 }
3763 case OPRND_TYPE_IMM16b_MOVIH:
3764 case OPRND_TYPE_IMM16b_ORI:
3765 {
3766 bfd_reloc_code_real_type r = BFD_RELOC_NONE;
3767 int len;
3768 char *curr = *oper;
3769 char * save = input_line_pointer;
3770 /* get the reloc type, and set "@GOTxxx" as ' ' */
3771 while (**oper != '@' && **oper != '\0')
3772 *oper += 1;
3773 if (**oper != '\0')
3774 {
3775 input_line_pointer = *oper;
3776 lex_got (&r, &len);
3777 while (*(*oper + len + 1) != '\0')
3778 {
3779 **oper = *(*oper + len + 1);
3780 *(*oper + len + 1) = '\0';
3781 *oper += 1;
3782 }
3783 **oper = '\0';
3784 }
3785 input_line_pointer = save;
3786 *oper = parse_exp (curr, &csky_insn.e1);
3787 return true;
3788 }
3789 case OPRND_TYPE_PSR_BITS_LIST:
3790 {
3791 int ret = true;
3792 if (csky_insn.number == 0)
3793 ret = false;
3794 else
3795 {
3796 csky_insn.val[csky_insn.idx] = 0;
3797 if (is_psr_bit (oper))
3798 while (**oper == ',')
3799 {
3800 *oper += 1;
3801 if (!is_psr_bit (oper))
3802 {
3803 ret = false;
3804 break;
3805 }
3806 }
3807 else
3808 ret = false;
3809 if (ret && IS_CSKY_V1 (mach_flag)
3810 && csky_insn.val[csky_insn.idx] > 8)
3811 ret = false;
3812 }
3813 if (!ret)
3814 SET_ERROR_STRING (ERROR_OPERANDS_ILLEGAL, csky_insn.opcode_end);
3815 return ret;
3816 }
3817 case OPRND_TYPE_RM:
3818 {
3819 /* FPU round mode. */
3820 static const char *round_mode[] =
3821 {
3822 "rm_nearest",
3823 "rm_zero",
3824 "rm_posinf",
3825 "rm_neginf",
3826 NULL
3827 };
3828 int i;
3829 for (i = 0; round_mode[i]; i++)
3830 if (strncasecmp (*oper, round_mode[i], strlen (round_mode[i])) == 0)
3831 {
3832 *oper += strlen (round_mode[i]);
3833 csky_insn.val[csky_insn.idx++] = i;
3834 return true;
3835 }
3836 return false;
3837 }
3838
3839 case OPRND_TYPE_REGLIST_COMMA:
3840 case OPRND_TYPE_BRACKET:
3841 /* TODO: using sub operand union. */
3842 case OPRND_TYPE_ABRACKET:
3843 /* TODO: using sub operand union. */
3844 case OPRND_TYPE_REGLIST_DASH:
3845 return is_reglist_legal (oper);
3846 case OPRND_TYPE_FREGLIST_DASH:
3847 return is_freglist_legal (oper);
3848 case OPRND_TYPE_AREG_WITH_BRACKET:
3849 {
3850 int len;
3851 int reg;
3852 if (**oper != '(')
3853 {
3854 SET_ERROR_STRING (ERROR_MISSING_LBRACKET, NULL);
3855 return false;
3856 }
3857 *oper += 1;
3858 reg = csky_get_reg_val (*oper, &len);
3859 if (reg == -1)
3860 {
3861 SET_ERROR_STRING (ERROR_EXP_GREG, NULL);
3862 return false;
3863 }
3864 *oper += len;
3865 if (**oper != ')')
3866 {
3867 SET_ERROR_STRING (ERROR_MISSING_RBRACKET, NULL);
3868 return false;
3869 }
3870 *oper += 1;
3871 csky_insn.val[csky_insn.idx++] = reg;
3872 return true;
3873 }
3874 case OPRND_TYPE_REGsp:
3875 return is_reg_sp (oper);
3876 case OPRND_TYPE_REGbsp:
3877 return is_reg_sp_with_bracket (oper);
3878 /* For jmpi. */
3879 case OPRND_TYPE_OFF8b:
3880 case OPRND_TYPE_OFF16b:
3881 *oper = parse_rt (*oper, 1, &csky_insn.e1, -1);
3882 csky_insn.val[csky_insn.idx++] = 0;
3883 return true;
3884 case OPRND_TYPE_LABEL_WITH_BRACKET:
3885 case OPRND_TYPE_CONSTANT:
3886 case OPRND_TYPE_ELRW_CONSTANT:
3887 if (**oper == '[')
3888 csky_insn.val[csky_insn.idx++] = 0;
3889 else
3890 csky_insn.val[csky_insn.idx++] = NEED_OUTPUT_LITERAL;
3891 *oper = parse_rt (*oper, 0, &csky_insn.e1, -1);
3892 return true;
3893 case OPRND_TYPE_FCONSTANT:
3894 *oper = parse_rtf (*oper, 0, &csky_insn.e1);
3895 return true;
3896
3897 case OPRND_TYPE_SFLOAT:
3898 case OPRND_TYPE_DFLOAT:
3899 /* For fmovis and fmovid, which accept a constant float with
3900 a limited range. */
3901 {
3902 uint64_t dbnum;
3903 int imm4, imm8;
3904
3905 *oper = parse_fexp (*oper, &csky_insn.e1, 1, &dbnum);
3906 if (csky_insn.e1.X_op == O_absent)
3907 return false;
3908
3909 /* Convert the representation from IEEE double to the 13-bit
3910 encoding used internally for fmovis and fmovid. */
3911 imm4 = 11 - (((dbnum & 0x7ff0000000000000ULL) >> 52) - 1023);
3912 /* Check float range. */
3913 if ((dbnum & 0x00000fffffffffffULL) || imm4 < 0 || imm4 > 15)
3914 {
3915 csky_show_error (ERROR_IMM_OVERFLOW, 2, NULL, NULL);
3916 return false;
3917 }
3918 imm8 = (dbnum & 0x000ff00000000000ULL) >> 44;
3919 csky_insn.e1.X_add_number
3920 = (((imm8 & 0xf) << 4)
3921 | ((imm8 & 0xf0) << 17)
3922 | ((imm4 & 0xf) << 16)
3923 | ((dbnum & 0x8000000000000000ULL) >> 43));
3924 return true;
3925 }
3926 case OPRND_TYPE_HFLOAT_FMOVI:
3927 case OPRND_TYPE_SFLOAT_FMOVI:
3928 case OPRND_TYPE_DFLOAT_FMOVI:
3929 /* For fpuv3 fmovis and fmovid, which accept a constant
3930 float with a limited range. */
3931 {
3932 uint64_t dbnum;
3933 int imm4, imm8, sign;
3934
3935 *oper = parse_fexp (*oper, &csky_insn.e1, 1, &dbnum);
3936 if (csky_insn.e1.X_op == O_absent)
3937 return false;
3938
3939 /* Convert the representation from IEEE double to the 13-bit
3940 encoding used internally for fmovis and fmovid. */
3941 imm4 = 11 - (((dbnum & 0x7ff0000000000000ULL) >> 52) - 1023);
3942 /* Check float range. */
3943 if ((dbnum & 0x00000fffffffffffULL) || imm4 < 0 || imm4 > 15)
3944 {
3945 csky_show_error (ERROR_IMM_OVERFLOW, 2, NULL, NULL);
3946 return true;
3947 }
3948 imm8 = (dbnum & 0x000ff00000000000ULL) >> 44;
3949 sign = (dbnum & 0x8000000000000000ULL) >> 58;
3950 csky_insn.e1.X_add_number
3951 = (((imm8 & 0x3) << 8)
3952 | ((imm8 & 0xfc) << 18)
3953 | ((imm4 & 0xf) << 16)
3954 | sign);
3955 return true;
3956 }
3957 /* For grs v2. */
3958 case OPRND_TYPE_IMM_OFF18b:
3959 *oper = parse_exp (*oper, &csky_insn.e1);
3960 return true;
3961
3962 case OPRND_TYPE_BLOOP_OFF4b:
3963 *oper = parse_exp (*oper, &csky_insn.e2);
3964 if (csky_insn.e2.X_op == O_symbol)
3965 {
3966 csky_insn.opcode_end = *oper;
3967 return true;
3968 }
3969 else
3970 return false;
3971
3972 case OPRND_TYPE_BLOOP_OFF12b:
3973 case OPRND_TYPE_OFF10b:
3974 case OPRND_TYPE_OFF11b:
3975 case OPRND_TYPE_OFF16b_LSL1:
3976 case OPRND_TYPE_OFF26b:
3977 *oper = parse_exp (*oper, &csky_insn.e1);
3978 if (csky_insn.e1.X_op == O_symbol)
3979 {
3980 csky_insn.opcode_end = *oper;
3981 return true;
3982 }
3983 else
3984 return false;
3985 /* For xtrb0(1)(2)(3) and div in csky v1 ISA. */
3986 case OPRND_TYPE_REG_r1a:
3987 {
3988 int reg = 0;
3989 int len = 0;
3990 reg = csky_get_reg_val (*oper, &len);
3991 if (reg == -1)
3992 {
3993 SET_ERROR_STRING (ERROR_REG_FORMAT,
3994 "The first operand must be register r1.");
3995 return false;
3996 }
3997 if (reg != 1)
3998 mov_r1_after = true;
3999 *oper += len;
4000 csky_insn.opcode_end = *oper;
4001 csky_insn.val[csky_insn.idx++] = reg;
4002 return true;
4003 }
4004 case OPRND_TYPE_REG_r1b:
4005 {
4006 int reg = 0;
4007 int len = 0;
4008 reg = csky_get_reg_val (*oper, &len);
4009 if (reg == -1)
4010 {
4011 SET_ERROR_STRING (ERROR_REG_FORMAT,
4012 "The second operand must be register r1.");
4013 return false;
4014 }
4015 if (reg != 1)
4016 {
4017 unsigned int mov_insn = CSKYV1_INST_MOV_R1_RX;
4018 mov_insn |= reg << 4;
4019 mov_r1_before = true;
4020 csky_insn.output = frag_more (2);
4021 dwarf2_emit_insn (0);
4022 md_number_to_chars (csky_insn.output, mov_insn, 2);
4023 }
4024 *oper += len;
4025 csky_insn.opcode_end = *oper;
4026 csky_insn.val[csky_insn.idx++] = reg;
4027 return true;
4028 }
4029 case OPRND_TYPE_DUMMY_REG:
4030 {
4031 int reg = 0;
4032 int len = 0;
4033 reg = csky_get_reg_val (*oper, &len);
4034 if (reg == -1)
4035 {
4036 SET_ERROR_STRING (ERROR_GREG_ILLEGAL, NULL);
4037 return false;
4038 }
4039 if (reg != csky_insn.val[0])
4040 {
4041 SET_ERROR_STRING (ERROR_REG_FORMAT,
4042 "The second register must be the same as the first.");
4043 return false;
4044 }
4045 *oper += len;
4046 csky_insn.opcode_end = *oper;
4047 csky_insn.val[csky_insn.idx++] = reg;
4048 return true;
4049 }
4050 case OPRND_TYPE_2IN1_DUMMY:
4051 {
4052 int reg = 0;
4053 int len = 0;
4054 int max = 0;
4055 int min = 0;
4056 reg = csky_get_reg_val (*oper, &len);
4057 if (reg == -1)
4058 {
4059 SET_ERROR_STRING (ERROR_GREG_ILLEGAL, NULL);
4060 return false;
4061 }
4062 /* dummy reg's real type should be same with first operand. */
4063 if (op->oprnd.oprnds[0].type == OPRND_TYPE_GREG0_15)
4064 max = 15;
4065 else if (op->oprnd.oprnds[0].type == OPRND_TYPE_GREG0_7)
4066 max = 7;
4067 else
4068 return false;
4069 if (reg < min || reg > max)
4070 return false;
4071 csky_insn.val[csky_insn.idx++] = reg;
4072 /* if it is the last operands. */
4073 if (csky_insn.idx > 2)
4074 {
4075 /* For "insn rz, rx, ry", if rx or ry is equal to rz,
4076 we can output the insn like "insn rz, rx". */
4077 if (csky_insn.val[0] == csky_insn.val[1])
4078 csky_insn.val[1] = 0;
4079 else if (csky_insn.val[0] == csky_insn.val[2])
4080 csky_insn.val[2] = 0;
4081 else
4082 return false;
4083 }
4084 *oper += len;
4085 csky_insn.opcode_end = *oper;
4086 return true;
4087 }
4088 case OPRND_TYPE_DUP_GREG0_7:
4089 case OPRND_TYPE_DUP_GREG0_15:
4090 case OPRND_TYPE_DUP_AREG:
4091 {
4092 long reg = 0;
4093 int len = 0;
4094 long max_reg;
4095 unsigned int shift_num;
4096 if (oprnd->type == OPRND_TYPE_DUP_GREG0_7)
4097 {
4098 max_reg = 7;
4099 shift_num = 3;
4100 }
4101 else if (oprnd->type == OPRND_TYPE_DUP_GREG0_15)
4102 {
4103 max_reg = 15;
4104 shift_num = 4;
4105 }
4106 else
4107 {
4108 max_reg = 31;
4109 shift_num = 5;
4110 }
4111 reg = csky_get_reg_val (*oper, &len);
4112 if (reg == -1)
4113 {
4114 if (max_reg == 31)
4115 SET_ERROR_STRING (ERROR_REG_FORMAT,
4116 "The register must be r0-r31");
4117 else
4118 SET_ERROR_STRING (ERROR_REG_FORMAT,
4119 "The register must be r0-r15");
4120 return false;
4121 }
4122 if (reg > max_reg)
4123 {
4124 SET_ERROR_STRING (ERROR_REG_OVER_RANGE, reg);
4125 return false;
4126 }
4127 reg |= reg << shift_num;
4128 *oper += len;
4129 csky_insn.opcode_end = *oper;
4130 csky_insn.val[csky_insn.idx++] = reg;
4131 return true;
4132 }
4133 case OPRND_TYPE_CONST1:
4134 *oper = parse_exp (*oper, &csky_insn.e1);
4135 if (csky_insn.e1.X_op == O_constant)
4136 {
4137 csky_insn.opcode_end = *oper;
4138 if (csky_insn.e1.X_add_number != 1)
4139 return false;
4140 csky_insn.val[csky_insn.idx++] = 1;
4141 return true;
4142 }
4143 return false;
4144 case OPRND_TYPE_UNCOND10b:
4145 case OPRND_TYPE_UNCOND16b:
4146 *oper = parse_exp (*oper, &csky_insn.e1);
4147 if (csky_insn.e1.X_op == O_constant)
4148 return false;
4149 input_line_pointer = *oper;
4150 csky_insn.opcode_end = *oper;
4151 csky_insn.relax.max = UNCD_DISP16_LEN;
4152 csky_insn.relax.var = UNCD_DISP10_LEN;
4153 csky_insn.relax.subtype = UNCD_DISP10;
4154 csky_insn.val[csky_insn.idx++] = 0;
4155 return true;
4156 case OPRND_TYPE_COND10b:
4157 case OPRND_TYPE_COND16b:
4158 *oper = parse_exp (*oper, &csky_insn.e1);
4159 if (csky_insn.e1.X_op == O_constant)
4160 return false;
4161 input_line_pointer = *oper;
4162 csky_insn.opcode_end = *oper;
4163 /* CK801 doesn't have 32-bit bt/bf insns; relax to a short
4164 jump around a 32-bit unconditional branch instead. */
4165 if (IS_CSKY_ARCH_801 (mach_flag))
4166 {
4167 csky_insn.relax.max = SCOND_DISP16_LEN;
4168 csky_insn.relax.var = SCOND_DISP10_LEN;
4169 csky_insn.relax.subtype = SCOND_DISP10;
4170 }
4171 else
4172 {
4173 csky_insn.relax.max = COND_DISP16_LEN;
4174 csky_insn.relax.var = COND_DISP10_LEN;
4175 csky_insn.relax.subtype = COND_DISP10;
4176 }
4177 csky_insn.val[csky_insn.idx++] = 0;
4178 return true;
4179 case OPRND_TYPE_JCOMPZ:
4180 *oper = parse_exp (*oper, &csky_insn.e1);
4181 if (csky_insn.e1.X_op == O_constant)
4182 return false;
4183 input_line_pointer = *oper;
4184 csky_insn.opcode_end = *oper;
4185 csky_insn.relax.max = JCOMPZ_DISP32_LEN;
4186 csky_insn.relax.var = JCOMPZ_DISP16_LEN;
4187 csky_insn.relax.subtype = JCOMPZ_DISP16;
4188 csky_insn.max = JCOMPZ_DISP32_LEN;
4189 csky_insn.val[csky_insn.idx++] = 0;
4190 return true;
4191 case OPRND_TYPE_JBTF:
4192 *oper = parse_exp (*oper, &csky_insn.e1);
4193 input_line_pointer = *oper;
4194 csky_insn.opcode_end = *oper;
4195 csky_insn.relax.max = csky_relax_table[C (COND_JUMP_S, DISP32)].rlx_length;
4196 csky_insn.relax.var = csky_relax_table[C (COND_JUMP_S, DISP12)].rlx_length;
4197 csky_insn.relax.subtype = C (COND_JUMP_S, 0);
4198 csky_insn.val[csky_insn.idx++] = 0;
4199 csky_insn.max = C32_LEN_S + 2;
4200 return true;
4201 case OPRND_TYPE_JBR:
4202 *oper = parse_exp (*oper, &csky_insn.e1);
4203 input_line_pointer = *oper;
4204 csky_insn.opcode_end = *oper;
4205 csky_insn.relax.max = csky_relax_table[C (UNCD_JUMP_S, DISP32)].rlx_length;
4206 csky_insn.relax.var = csky_relax_table[C (UNCD_JUMP_S, DISP12)].rlx_length;
4207 csky_insn.relax.subtype = C (UNCD_JUMP_S, 0);
4208 csky_insn.val[csky_insn.idx++] = 0;
4209 csky_insn.max = U32_LEN_S + 2;
4210 return true;
4211 case OPRND_TYPE_JBSR:
4212 if (do_force2bsr)
4213 *oper = parse_exp (*oper, &csky_insn.e1);
4214 else
4215 *oper = parse_rt (*oper, 1, &csky_insn.e1, -1);
4216 input_line_pointer = *oper;
4217 csky_insn.opcode_end = *oper;
4218 csky_insn.val[csky_insn.idx++] = 0;
4219 return true;
4220 case OPRND_TYPE_REGLIST_DASH_COMMA:
4221 return is_reglist_dash_comma_legal (oper, oprnd);
4222
4223 case OPRND_TYPE_MSB2SIZE:
4224 case OPRND_TYPE_LSB2SIZE:
4225 {
4226 expressionS e;
4227 char *new_oper = parse_exp (*oper, &e);
4228 if (e.X_op == O_constant)
4229 {
4230 *oper = new_oper;
4231 if (e.X_add_number > 31)
4232 {
4233 SET_ERROR_STRING (ERROR_IMM_OVERFLOW, NULL);
4234 return false;
4235 }
4236 csky_insn.val[csky_insn.idx++] = e.X_add_number;
4237 if (oprnd->type == OPRND_TYPE_LSB2SIZE)
4238 {
4239 if (csky_insn.val[csky_insn.idx - 1] > csky_insn.val[csky_insn.idx - 2])
4240 {
4241 SET_ERROR_STRING (ERROR_IMM_OVERFLOW, NULL);
4242 return false;
4243 }
4244 csky_insn.val[csky_insn.idx - 2] -= e.X_add_number;
4245 }
4246 return true;
4247 }
4248 return false;
4249 }
4250 case OPRND_TYPE_AREG_WITH_LSHIFT:
4251 return is_reg_lshift_illegal (oper, 0);
4252 case OPRND_TYPE_AREG_WITH_LSHIFT_FPU:
4253 return is_reg_lshift_illegal (oper, 1);
4254 case OPRND_TYPE_FREG_WITH_INDEX:
4255 case OPRND_TYPE_VREG_WITH_INDEX:
4256 if (parse_type_freg (oper, 0))
4257 {
4258 if (**oper == '[')
4259 {
4260 (*oper)++;
4261 if (is_imm_within_range (oper, 0, 0xf))
4262 {
4263 if (**oper == ']')
4264 {
4265 unsigned int idx = --csky_insn.idx;
4266 unsigned int val = csky_insn.val[idx];
4267 (*oper)++;
4268 csky_insn.val[idx - 1] |= val << 4;
4269 return true;
4270 }
4271 else
4272 SET_ERROR_STRING (ERROR_MISSING_RSQUARE_BRACKETS, NULL);
4273 }
4274 }
4275 else
4276 SET_ERROR_STRING (ERROR_MISSING_LSQUARE_BRACKETS, NULL);
4277 }
4278 return false;
4279
4280 default:
4281 break;
4282 /* error code. */
4283 }
4284 return false;
4285 }
4286
4287 /* Subroutine of parse_operands. */
4288
4289 static bool
4290 parse_operands_op (char *str, struct csky_opcode_info *op)
4291 {
4292 int i;
4293 int j;
4294 char *oper = str;
4295 int flag_pass;
4296
4297 for (i = 0; i < OP_TABLE_NUM && op[i].operand_num != -2; i++)
4298 {
4299 flag_pass = true;
4300 csky_insn.idx = 0;
4301 oper = str;
4302 /* if operand_num = -1, it is a insn with a REGLIST type operand.i. */
4303 if (!(op[i].operand_num == csky_insn.number
4304 || (op[i].operand_num == -1 && csky_insn.number != 0)))
4305 {
4306 /* The smaller err_num is more serious. */
4307 SET_ERROR_INTEGER (ERROR_OPERANDS_NUMBER, op[i].operand_num);
4308 flag_pass = false;
4309 continue;
4310 }
4311
4312 for (j = 0; j < csky_insn.number; j++)
4313 {
4314 while (ISSPACE (*oper))
4315 oper++;
4316 flag_pass = get_operand_value (&op[i], &oper,
4317 &op[i].oprnd.oprnds[j]);
4318 if (!flag_pass)
4319 break;
4320 while (ISSPACE (*oper))
4321 oper++;
4322 /* Skip the ','. */
4323 if (j < csky_insn.number - 1 && op[i].operand_num != -1)
4324 {
4325 if (*oper == ',')
4326 oper++;
4327 else
4328 {
4329 SET_ERROR_STRING (ERROR_MISSING_COMMA, NULL);
4330 flag_pass = false;
4331 break;
4332 }
4333 }
4334 else if (!is_end_of_line[(unsigned char) *oper])
4335 {
4336 SET_ERROR_STRING (ERROR_BAD_END, NULL);
4337 flag_pass = false;
4338 break;
4339 }
4340 else
4341 break;
4342 }
4343 /* Parse operands in one table end. */
4344
4345 if (flag_pass)
4346 {
4347 /* Parse operands success, set opcode_idx. */
4348 csky_insn.opcode_idx = i;
4349 return true;
4350 }
4351 else
4352 error_state.opnum = j + 1;
4353 }
4354 /* Parse operands in ALL tables end. */
4355 return false;
4356 }
4357
4358 /* Parse the operands according to operand type. */
4359
4360 static bool
4361 parse_operands (char *str)
4362 {
4363 char *oper = str;
4364
4365 /* Parse operands according to flag_force. */
4366 if (csky_insn.flag_force == INSN_OPCODE16F
4367 && (csky_insn.opcode->isa_flag16 & isa_flag) != 0)
4368 {
4369 if (parse_operands_op (oper, csky_insn.opcode->op16))
4370 {
4371 csky_insn.isize = 2;
4372 return true;
4373 }
4374 return false;
4375 }
4376 else if (csky_insn.flag_force == INSN_OPCODE32F
4377 && (csky_insn.opcode->isa_flag32 & isa_flag) != 0)
4378 {
4379 if (parse_operands_op (oper, csky_insn.opcode->op32))
4380 {
4381 csky_insn.isize = 4;
4382 return true;
4383 }
4384 return false;
4385 }
4386 else
4387 {
4388 if ((csky_insn.opcode->isa_flag16 & isa_flag) != 0
4389 && parse_operands_op (oper, csky_insn.opcode->op16))
4390 {
4391 csky_insn.isize = 2;
4392 return true;
4393 }
4394 if ((csky_insn.opcode->isa_flag32 & isa_flag) != 0
4395 && parse_operands_op (oper, csky_insn.opcode->op32))
4396 {
4397 csky_insn.isize = 4;
4398 return true;
4399 }
4400 return false;
4401 }
4402 }
4403
4404 static bool
4405 csky_generate_frags (void)
4406 {
4407 /* frag more relax reloc. */
4408 if (csky_insn.flag_force == INSN_OPCODE16F
4409 || !IS_SUPPORT_OPCODE32 (csky_insn.opcode))
4410 {
4411 csky_insn.output = frag_more (csky_insn.isize);
4412 if (csky_insn.opcode->reloc16)
4413 {
4414 /* 16 bits opcode force, should generate fixup. */
4415 reloc_howto_type *howto;
4416 howto = bfd_reloc_type_lookup (stdoutput,
4417 csky_insn.opcode->reloc16);
4418 fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
4419 2, &csky_insn.e1, howto->pc_relative,
4420 csky_insn.opcode->reloc16);
4421 }
4422 }
4423 else if (csky_insn.flag_force == INSN_OPCODE32F)
4424 {
4425 csky_insn.output = frag_more (csky_insn.isize);
4426 if (csky_insn.opcode->reloc32)
4427 {
4428 reloc_howto_type *howto;
4429 howto = bfd_reloc_type_lookup (stdoutput,
4430 csky_insn.opcode->reloc32);
4431 fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
4432 4, &csky_insn.e1, howto->pc_relative,
4433 csky_insn.opcode->reloc32);
4434 }
4435 }
4436 else if (csky_insn.opcode->relax)
4437 /* Generate the relax information. */
4438 csky_insn.output = frag_var (rs_machine_dependent,
4439 csky_insn.relax.max,
4440 csky_insn.relax.var,
4441 csky_insn.relax.subtype,
4442 csky_insn.e1.X_add_symbol,
4443 csky_insn.e1.X_add_number, 0);
4444 else
4445 {
4446 csky_insn.output = frag_more (csky_insn.isize);
4447 if (csky_insn.opcode->reloc16 && csky_insn.isize == 2)
4448 {
4449 reloc_howto_type *howto;
4450 howto = bfd_reloc_type_lookup (stdoutput,
4451 csky_insn.opcode->reloc16);
4452 fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
4453 2, &csky_insn.e1, howto->pc_relative,
4454 csky_insn.opcode->reloc16);
4455 }
4456 else if (csky_insn.opcode->reloc32 && csky_insn.isize == 4)
4457 {
4458 reloc_howto_type *howto;
4459 howto = bfd_reloc_type_lookup (stdoutput,
4460 csky_insn.opcode->reloc32);
4461 fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
4462 4, &csky_insn.e1, howto->pc_relative,
4463 csky_insn.opcode->reloc32);
4464 }
4465 }
4466 return true;
4467 }
4468
4469 /* Return the bits of VAL shifted according to MASK. The bits of MASK
4470 need not be contiguous. */
4471
4472 static int
4473 generate_masked_value (int mask, int val)
4474 {
4475 int ret = 0;
4476 int bit;
4477
4478 for (bit = 1; mask; bit = bit << 1)
4479 if (mask & bit)
4480 {
4481 if (val & 0x1)
4482 ret |= bit;
4483 val = val >> 1;
4484 mask &= ~bit;
4485 }
4486 return ret;
4487 }
4488
4489 /* Return the result of masking operand number OPRND_IDX into the
4490 instruction word according to the information in OPRND. */
4491
4492 static int
4493 generate_masked_operand (struct operand *oprnd, int *oprnd_idx)
4494 {
4495 struct soperand *soprnd = NULL;
4496 int mask;
4497 int val;
4498 if ((unsigned int)oprnd->mask == HAS_SUB_OPERAND)
4499 {
4500 soprnd = (struct soperand *) oprnd;
4501 generate_masked_operand (&soprnd->subs[0], oprnd_idx);
4502 generate_masked_operand (&soprnd->subs[1], oprnd_idx);
4503 return 0;
4504 }
4505 mask = oprnd->mask;
4506 val = csky_insn.val[*oprnd_idx];
4507 (*oprnd_idx)++;
4508 val = generate_masked_value (mask, val);
4509 csky_insn.inst |= val;
4510
4511 return 0;
4512 }
4513
4514 static bool
4515 csky_generate_insn (void)
4516 {
4517 int i = 0;
4518 struct csky_opcode_info *opinfo = NULL;
4519
4520 if (csky_insn.isize == 4)
4521 opinfo = &csky_insn.opcode->op32[csky_insn.opcode_idx];
4522 else if (csky_insn.isize == 2)
4523 opinfo = &csky_insn.opcode->op16[csky_insn.opcode_idx];
4524
4525 int sidx = 0;
4526 csky_insn.inst = opinfo->opcode;
4527 if (opinfo->operand_num == -1)
4528 {
4529 generate_masked_operand (&opinfo->oprnd.oprnds[i], &sidx);
4530 return 0;
4531 }
4532 else
4533 for (i = 0; i < opinfo->operand_num; i++)
4534 generate_masked_operand (&opinfo->oprnd.oprnds[i], &sidx);
4535 return 0;
4536 }
4537
4538 /* Main entry point for assembling a single instruction. */
4539
4540 void
4541 md_assemble (char *str)
4542 {
4543 bool must_check_literals = true;
4544 csky_insn.isize = 0;
4545 csky_insn.idx = 0;
4546 csky_insn.max = 0;
4547 csky_insn.flag_force = INSN_OPCODE;
4548 csky_insn.macro = NULL;
4549 csky_insn.opcode = NULL;
4550 memset (csky_insn.val, 0, sizeof (int) * MAX_OPRND_NUM);
4551 /* Initialize err_num. */
4552 error_state.err_num = ERROR_NONE;
4553 mov_r1_before = false;
4554 mov_r1_after = false;
4555
4556 mapping_state (MAP_TEXT);
4557 /* Tie dwarf2 debug info to every insn if set option --gdwarf2. */
4558 dwarf2_emit_insn (0);
4559 while (ISSPACE (* str))
4560 str++;
4561 /* Get opcode from str. */
4562 if (!parse_opcode (str))
4563 {
4564 csky_show_error (ERROR_OPCODE_ILLEGAL, 0, NULL, NULL);
4565 return;
4566 }
4567
4568 /* If it is a macro instruction, handle it. */
4569 if (csky_insn.macro != NULL)
4570 {
4571 if (csky_insn.number == csky_insn.macro->oprnd_num)
4572 {
4573 csky_insn.macro->handle_func ();
4574 return;
4575 }
4576 else if (error_state.err_num > ERROR_OPERANDS_NUMBER)
4577 SET_ERROR_STRING (ERROR_OPERANDS_NUMBER, csky_insn.macro->oprnd_num);
4578 }
4579
4580 if (csky_insn.opcode == NULL)
4581 {
4582 SET_ERROR_STRING (ERROR_OPCODE_ILLEGAL, NULL);
4583 csky_show_error (error_state.err_num, error_state.opnum,
4584 (void *)error_state.arg1, (void *)error_state.arg1);
4585 return;
4586 }
4587
4588 /* Parse the operands according to operand type. */
4589 if (!parse_operands (csky_insn.opcode_end))
4590 {
4591 csky_show_error (error_state.err_num, error_state.opnum,
4592 (void *)error_state.arg1, (void *)error_state.arg1);
4593 return;
4594 }
4595 error_state.err_num = ERROR_NONE;
4596
4597 /* if this insn has work in opcode table, then do it. */
4598 if (csky_insn.opcode->work != NULL)
4599 must_check_literals = csky_insn.opcode->work ();
4600 else
4601 {
4602 /* Generate relax or reloc if necessary. */
4603 csky_generate_frags ();
4604 /* Generate the insn by mask. */
4605 csky_generate_insn ();
4606 /* Write inst to frag. */
4607 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
4608 }
4609
4610 /* Adjust for xtrb0/xtrb1/xtrb2/xtrb3/divs/divu in csky v1 ISA. */
4611 if (mov_r1_after)
4612 {
4613 unsigned int mov_insn = CSKYV1_INST_MOV_RX_R1;
4614 mov_insn |= csky_insn.val[0];
4615 mov_r1_before = true;
4616 csky_insn.output = frag_more (2);
4617 dwarf2_emit_insn (0);
4618 md_number_to_chars (csky_insn.output, mov_insn, 2);
4619 csky_insn.isize += 2;
4620 }
4621 if (mov_r1_before)
4622 csky_insn.isize += 2;
4623
4624 /* Check literal. */
4625 if (must_check_literals)
4626 {
4627 if (csky_insn.max == 0)
4628 check_literals (csky_insn.opcode->transfer, csky_insn.isize);
4629 else
4630 check_literals (csky_insn.opcode->transfer, csky_insn.max);
4631 }
4632
4633 csky_insn.last_isize = csky_insn.isize;
4634 insn_reloc = BFD_RELOC_NONE;
4635 }
4636
4637 /* Attempt to handle option with value C, returning non-zero on success. */
4638
4639 int
4640 md_parse_option (int c, const char *arg)
4641 {
4642 switch (c)
4643 {
4644 case 0:
4645 break;
4646 case OPTION_MARCH:
4647 parse_arch (arg);
4648 break;
4649 case OPTION_MCPU:
4650 parse_cpu (arg);
4651 break;
4652 case OPTION_FLOAT_ABI:
4653 parse_float_abi (arg);
4654 break;
4655 default:
4656 return 0;
4657 }
4658 return 1;
4659 }
4660
4661 /* Convert a machine dependent frag. */
4662 #define PAD_LITERAL_LENGTH 6
4663 #define opposite_of_stored_comp(insn) (insn ^ 0x04000000)
4664 #define opposite_of_stored_compz(insn) (insn ^ 0x00200000)
4665 #define make_insn(total_length, opcode, operand, operand_length) \
4666 do { \
4667 if (total_length > 0) \
4668 { \
4669 csky_write_insn (buf, \
4670 opcode | (operand & ((1 << operand_length) - 1)), \
4671 total_length); \
4672 buf += total_length; \
4673 fragp->fr_fix += total_length; \
4674 } \
4675 } while (0)
4676
4677 #define make_literal(fragp, literal_offset) \
4678 do { \
4679 make_insn (literal_offset, PAD_FILL_CONTENT, 0, 0); \
4680 fix_new (fragp, fragp->fr_fix, 4, fragp->fr_symbol, \
4681 fragp->fr_offset, 0, BFD_RELOC_CKCORE_ADDR32); \
4682 make_insn (4, 0, 0, 0); \
4683 make_insn (2 - literal_offset, PAD_FILL_CONTENT, 0, 0); \
4684 } while (0)
4685
4686 void
4687 md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT asec, fragS *fragp)
4688 {
4689 offsetT disp;
4690 char *buf = fragp->fr_fix + &fragp->fr_literal[0];
4691
4692 gas_assert (fragp->fr_symbol);
4693 if (IS_EXTERNAL_SYM (fragp->fr_symbol, asec))
4694 disp = 0;
4695 else
4696 disp = (S_GET_VALUE (fragp->fr_symbol)
4697 + fragp->fr_offset
4698 - fragp->fr_address
4699 - fragp->fr_fix);
4700
4701 switch (fragp->fr_subtype)
4702 {
4703 /* generate new insn. */
4704 case C (COND_JUMP, DISP12):
4705 case C (UNCD_JUMP, DISP12):
4706 case C (COND_JUMP_PIC, DISP12):
4707 case C (UNCD_JUMP_PIC, DISP12):
4708 {
4709 #define CSKY_V1_B_MASK 0xf8
4710 unsigned char t0;
4711 disp -= 2;
4712 if (disp & 1)
4713 {
4714 /* Error. odd displacement at %x, next_inst-2. */
4715 ;
4716 }
4717 disp >>= 1;
4718
4719 if (!target_big_endian)
4720 {
4721 t0 = buf[1] & CSKY_V1_B_MASK;
4722 md_number_to_chars (buf, disp, 2);
4723 buf[1] = (buf[1] & ~CSKY_V1_B_MASK) | t0;
4724 }
4725 else
4726 {
4727 t0 = buf[0] & CSKY_V1_B_MASK;
4728 md_number_to_chars (buf, disp, 2);
4729 buf[0] = (buf[0] & ~CSKY_V1_B_MASK) | t0;
4730 }
4731 fragp->fr_fix += 2;
4732 break;
4733 }
4734 case C (COND_JUMP, DISP32):
4735 case C (COND_JUMP, UNDEF_WORD_DISP):
4736 {
4737 /* A conditional branch wont fit into 12 bits:
4738 b!cond 1f
4739 jmpi 0f
4740 .align 2
4741 0: .long disp
4742 1:
4743 */
4744 int first_inst = fragp->fr_fix + fragp->fr_address;
4745 int is_unaligned = (first_inst & 3);
4746
4747 if (!target_big_endian)
4748 {
4749 /* b!cond instruction. */
4750 buf[1] ^= 0x08;
4751 /* jmpi instruction. */
4752 buf[2] = CSKYV1_INST_JMPI & 0xff;
4753 buf[3] = CSKYV1_INST_JMPI >> 8;
4754 }
4755 else
4756 {
4757 /* b!cond instruction. */
4758 buf[0] ^= 0x08;
4759 /* jmpi instruction. */
4760 buf[2] = CSKYV1_INST_JMPI >> 8;
4761 buf[3] = CSKYV1_INST_JMPI & 0xff;
4762 }
4763
4764 if (is_unaligned)
4765 {
4766 if (!target_big_endian)
4767 {
4768 /* bt/bf: jump to pc + 2 + (4 << 1). */
4769 buf[0] = 4;
4770 /* jmpi: jump to MEM (pc + 2 + (1 << 2)). */
4771 buf[2] = 1;
4772 }
4773 else
4774 {
4775 /* bt/bf: jump to pc + 2 + (4 << 1). */
4776 buf[1] = 4;
4777 /* jmpi: jump to MEM (pc + 2 + (1 << 2)). */
4778 buf[3] = 1;
4779 }
4780 /* Aligned 4 bytes. */
4781 buf[4] = 0;
4782 buf[5] = 0;
4783 /* .long */
4784 buf[6] = 0;
4785 buf[7] = 0;
4786 buf[8] = 0;
4787 buf[9] = 0;
4788
4789 /* Make reloc for the long disp. */
4790 fix_new (fragp, fragp->fr_fix + 6, 4,
4791 fragp->fr_symbol, fragp->fr_offset, 0, BFD_RELOC_32);
4792 fragp->fr_fix += C32_LEN;
4793 }
4794 else
4795 {
4796 if (!target_big_endian)
4797 {
4798 /* bt/bf: jump to pc + 2 + (3 << 1). */
4799 buf[0] = 3;
4800 /* jmpi: jump to MEM (pc + 2 + (0 << 2)). */
4801 buf[2] = 0;
4802 }
4803 else
4804 {
4805 /* bt/bf: jump to pc + 2 + (3 << 1). */
4806 buf[1] = 3;
4807 /* jmpi: jump to MEM (pc + 2 + (0 << 2)). */
4808 buf[3] = 0;
4809 }
4810 /* .long */
4811 buf[4] = 0;
4812 buf[5] = 0;
4813 buf[6] = 0;
4814 buf[7] = 0;
4815
4816 /* Make reloc for the long disp. */
4817 fix_new (fragp, fragp->fr_fix + 4, 4,
4818 fragp->fr_symbol, fragp->fr_offset, 0, BFD_RELOC_32);
4819 fragp->fr_fix += C32_LEN;
4820
4821 /* Frag is actually shorter (see the other side of this ifdef)
4822 but gas isn't prepared for that. We have to re-adjust
4823 the branch displacement so that it goes beyond the
4824 full length of the fragment, not just what we actually
4825 filled in. */
4826 if (!target_big_endian)
4827 buf[0] = 4;
4828 else
4829 buf[1] = 4;
4830 }
4831 }
4832 break;
4833
4834 case C (COND_JUMP_PIC, DISP32):
4835 case C (COND_JUMP_PIC, UNDEF_WORD_DISP):
4836 {
4837 #define BYTE_1(a) (target_big_endian ? ((a) & 0xff) : ((a) >> 8))
4838 #define BYTE_0(a) (target_big_endian ? ((a) >> 8) : ((a) & 0xff))
4839 /* b!cond 1f
4840 subi sp, 8
4841 stw r15, (sp, 0)
4842 bsr .L0
4843 .L0:
4844 lrw r1, 0f
4845 add r1, r15
4846 addi sp, 8
4847 jmp r1
4848 .align 2
4849 0: .long (tar_addr - pc)
4850 1:
4851 */
4852 int first_inst = fragp->fr_fix + fragp->fr_address;
4853 int is_unaligned = (first_inst & 3);
4854 disp -= 8;
4855 /* Toggle T/F bit. */
4856 if (! target_big_endian)
4857 buf[1] ^= 0x08;
4858 else
4859 buf[0] ^= 0x08;
4860 buf[2] = BYTE_0 (CSKYV1_INST_SUBI | (7 << 4)); /* subi r0, 8. */
4861 buf[3] = BYTE_1 (CSKYV1_INST_SUBI | (7 << 4));
4862 buf[4] = BYTE_0 (CSKYV1_INST_STW | (15 << 8)); /* stw r15, r0. */
4863 buf[5] = BYTE_1 (CSKYV1_INST_STW | (15 << 8));
4864 buf[6] = BYTE_0 (CSKYV1_INST_BSR); /* bsr pc + 2. */
4865 buf[7] = BYTE_1 (CSKYV1_INST_BSR);
4866 buf[8] = BYTE_0 (CSKYV1_INST_LRW | (1 << 8)); /* lrw r1, (tar_addr - pc). */
4867 buf[9] = BYTE_1 (CSKYV1_INST_LRW | (1 << 8));
4868 buf[10] = BYTE_0 (CSKYV1_INST_ADDU | (15 << 4) | 1); /* add r1, r15. */
4869 buf[11] = BYTE_1 (CSKYV1_INST_ADDU | (15 << 4) | 1);
4870 buf[12] = BYTE_0 (CSKYV1_INST_LDW | (15 << 8)); /* ldw r15, r0. */
4871 buf[13] = BYTE_1 (CSKYV1_INST_LDW | (15 << 8));
4872 buf[14] = BYTE_0 (CSKYV1_INST_ADDI | (7 << 4)); /* addi r0, 8. */
4873 buf[15] = BYTE_1 (CSKYV1_INST_ADDI | (7 << 4));
4874 buf[16] = BYTE_0 (CSKYV1_INST_JMP | 1); /* jmp r1. */
4875 buf[17] = BYTE_1 (CSKYV1_INST_JMP | 1);
4876
4877 if (!is_unaligned)
4878 {
4879 if (!target_big_endian)
4880 {
4881 buf[0] = 11;
4882 buf[8] = 3;
4883 buf[20] = disp & 0xff;
4884 buf[21] = (disp >> 8) & 0xff;
4885 buf[22] = (disp >> 16) & 0xff;
4886 buf[23] = (disp >> 24) & 0xff;
4887 }
4888 else /* if !target_big_endian. */
4889 {
4890 buf[1] = 11;
4891 buf[9] = 3;
4892 buf[20] = (disp >> 24) & 0xff;
4893 buf[21] = (disp >> 16) & 0xff;
4894 buf[22] = (disp >> 8) & 0xff;
4895 buf[23] = disp & 0xff;
4896 }
4897 buf[18] = 0; /* alignment. */
4898 buf[19] = 0;
4899 fragp->fr_fix += C32_LEN_PIC;
4900 }
4901 else /* if !is_unaligned. */
4902 {
4903 if (!target_big_endian)
4904 {
4905 buf[0] = 11;
4906 buf[8] = 2;
4907 buf[18] = disp & 0xff;
4908 buf[19] = (disp >> 8) & 0xff;
4909 buf[20] = (disp >> 16) & 0xff;
4910 buf[21] = (disp >> 24) & 0xff;
4911 }
4912 else /* if !target_big_endian. */
4913 {
4914 buf[1] = 11;
4915 buf[9] = 2;
4916 buf[18] = (disp >> 24) & 0xff;
4917 buf[19] = (disp >> 16) & 0xff;
4918 buf[20] = (disp >> 8) & 0xff;
4919 buf[21] = disp & 0xff;
4920 }
4921 buf[22] = 0; /* initialise. */
4922 buf[23] = 0;
4923 fragp->fr_fix += C32_LEN_PIC;
4924
4925 } /* end if is_unaligned. */
4926 } /* end case C (COND_JUMP_PIC, DISP32)/C (COND_JUMP_PIC, UNDEF_WORD_DISP). */
4927 break;
4928 case C (UNCD_JUMP, DISP32):
4929 case C (UNCD_JUMP, UNDEF_WORD_DISP):
4930 {
4931 /* jmpi 0f
4932 .align 2
4933 0: .long disp. */
4934 int first_inst = fragp->fr_fix + fragp->fr_address;
4935 int is_unaligned = (first_inst & 3);
4936 /* Build jmpi. */
4937 buf[0] = BYTE_0 (CSKYV1_INST_JMPI);
4938 buf[1] = BYTE_1 (CSKYV1_INST_JMPI);
4939 if (!is_unaligned)
4940 {
4941 if (!target_big_endian)
4942 buf[0] = 1;
4943 else
4944 buf[1] = 1;
4945 /* Alignment. */
4946 buf[2] = 0;
4947 buf[3] = 0;
4948 /* .long */
4949 buf[4] = 0;
4950 buf[5] = 0;
4951 buf[6] = 0;
4952 buf[7] = 0;
4953 fix_new (fragp, fragp->fr_fix + 4, 4,
4954 fragp->fr_symbol, fragp->fr_offset, 0, BFD_RELOC_32);
4955 fragp->fr_fix += U32_LEN;
4956 }
4957 else /* if is_unaligned. */
4958 {
4959 if (!target_big_endian)
4960 buf[0] = 0;
4961 else
4962 buf[1] = 0;
4963 /* .long */
4964 buf[2] = 0;
4965 buf[3] = 0;
4966 buf[4] = 0;
4967 buf[5] = 0;
4968 fix_new (fragp, fragp->fr_fix + 2, 4,
4969 fragp->fr_symbol, fragp->fr_offset, 0, BFD_RELOC_32);
4970 fragp->fr_fix += U32_LEN;
4971
4972 }
4973 }
4974 break;
4975 case C (UNCD_JUMP_PIC, DISP32):
4976 case C (UNCD_JUMP_PIC, UNDEF_WORD_DISP):
4977 {
4978 /* subi sp, 8
4979 stw r15, (sp)
4980 bsr .L0
4981 .L0:
4982 lrw r1, 0f
4983 add r1, r15
4984 ldw r15, (sp)
4985 addi sp, 8
4986 jmp r1
4987 .align 2
4988 0: .long (tar_add - pc)
4989 1:
4990 */
4991 /* If the b!cond is 4 byte aligned, the literal which would
4992 go at x+4 will also be aligned. */
4993 int first_inst = fragp->fr_fix + fragp->fr_address;
4994 int is_unaligned = (first_inst & 3);
4995 disp -= 6;
4996
4997 buf[0] = BYTE_0 (CSKYV1_INST_SUBI | (7 << 4)); /* subi r0, 8. */
4998 buf[1] = BYTE_1 (CSKYV1_INST_SUBI | (7 << 4));
4999 buf[2] = BYTE_0 (CSKYV1_INST_STW | (15 << 8)); /* stw r15, r0. */
5000 buf[3] = BYTE_1 (CSKYV1_INST_STW | (15 << 8));
5001 buf[4] = BYTE_0 (CSKYV1_INST_BSR); /* bsr pc + 2. */
5002 buf[5] = BYTE_1 (CSKYV1_INST_BSR);
5003 buf[6] = BYTE_0 (CSKYV1_INST_LRW | (1 << 8)); /* lrw r1, (tar_addr - pc). */
5004 buf[7] = BYTE_1 (CSKYV1_INST_LRW | (1 << 8));
5005 buf[8] = BYTE_0 (CSKYV1_INST_ADDU | (15 << 4) | 1); /* add r1, r15. */
5006 buf[9] = BYTE_1 (CSKYV1_INST_ADDU | (15 << 4) | 1);
5007 buf[10] = BYTE_0 (CSKYV1_INST_LDW | (15 << 8)); /* ldw r15, r0. */
5008 buf[11] = BYTE_1 (CSKYV1_INST_LDW | (15 << 8));
5009 buf[12] = BYTE_0 (CSKYV1_INST_ADDI | (7 << 4)); /* addi r0, 8. */
5010 buf[13] = BYTE_1 (CSKYV1_INST_ADDI | (7 << 4));
5011 buf[14] = BYTE_0 (CSKYV1_INST_JMP | 1); /* jmp r1. */
5012 buf[15] = BYTE_1 (CSKYV1_INST_JMP | 1);
5013
5014 if (is_unaligned)
5015 {
5016 if (!target_big_endian)
5017 {
5018 buf[6] = 3;
5019 buf[18] = disp & 0xff;
5020 buf[19] = (disp >> 8) & 0xff;
5021 buf[20] = (disp >> 16) & 0xff;
5022 buf[21] = (disp >> 24) & 0xff;
5023 }
5024 else
5025 {
5026 buf[7] = 3;
5027 buf[18] = (disp >> 24) & 0xff;
5028 buf[19] = (disp >> 16) & 0xff;
5029 buf[20] = (disp >> 8) & 0xff;
5030 buf[21] = disp & 0xff;
5031 }
5032 buf[16] = 0;
5033 buf[17] = 0;
5034 fragp->fr_fix += U32_LEN_PIC;
5035 }
5036 else
5037 {
5038 if (!target_big_endian)
5039 {
5040 buf[6] = 2;
5041 buf[16] = disp & 0xff;
5042 buf[17] = (disp >> 8) & 0xff;
5043 buf[18] = (disp >> 16) & 0xff;
5044 buf[19] = (disp >> 24) & 0xff;
5045 }
5046 else
5047 {
5048 buf[7] = 2;
5049 buf[16] = (disp >> 24) & 0xff;
5050 buf[17] = (disp >> 16) & 0xff;
5051 buf[18] = (disp >> 8) & 0xff;
5052 buf[19] = disp & 0xff;
5053 }
5054 fragp->fr_fix += U32_LEN_PIC;
5055 }
5056 }
5057 break;
5058 case COND_DISP10:
5059 case SCOND_DISP10:
5060 case UNCD_DISP10:
5061 case JCOND_DISP10:
5062 case JUNCD_DISP10:
5063 {
5064 unsigned int inst = csky_read_insn (buf, 2);
5065 inst |= (disp >> 1) & ((1 << 10) - 1);
5066 csky_write_insn (buf, inst, 2);
5067 fragp->fr_fix += 2;
5068 break;
5069 }
5070 case SCOND_DISP16:
5071 {
5072 unsigned int inst = csky_read_insn (buf, 2);
5073
5074 if (inst == CSKYV2_INST_BT16)
5075 inst = CSKYV2_INST_BF16;
5076 else
5077 inst = CSKYV2_INST_BT16;
5078 make_insn (2, inst, (2 + 4) >> 1, 10);
5079 if (IS_EXTERNAL_SYM (fragp->fr_symbol, asec))
5080 fix_new (fragp, fragp->fr_fix, 4,
5081 fragp->fr_symbol, fragp->fr_offset, 1,
5082 BFD_RELOC_CKCORE_PCREL_IMM16BY2);
5083 disp -= 2;
5084 inst = CSKYV2_INST_BR32 | ((disp >> 1) & ((1 << 16) - 1));
5085 csky_write_insn (buf, inst, 4);
5086 fragp->fr_fix += 4;
5087 break;
5088 }
5089 case COND_DISP16:
5090 case JCOND_DISP16:
5091 {
5092 unsigned int inst = csky_read_insn (buf, 2);
5093
5094 if (inst == CSKYV2_INST_BT16)
5095 inst = CSKYV2_INST_BT32;
5096 else
5097 inst = CSKYV2_INST_BF32;
5098 if (IS_EXTERNAL_SYM (fragp->fr_symbol, asec))
5099 fix_new (fragp, fragp->fr_fix, 4,
5100 fragp->fr_symbol, fragp->fr_offset, 1,
5101 BFD_RELOC_CKCORE_PCREL_IMM16BY2);
5102 inst |= (disp >> 1) & ((1 << 16) - 1);
5103 csky_write_insn (buf, inst, 4);
5104 fragp->fr_fix += 4;
5105 break;
5106 }
5107 case LRW_DISP7:
5108 {
5109 unsigned int inst = csky_read_insn (buf, 2);
5110 int imm;
5111 imm = (disp + 2) >> 2;
5112 inst |= (imm >> 5) << 8;
5113 make_insn (2, inst, (imm & 0x1f), 5);
5114 break;
5115 }
5116 case LRW2_DISP8:
5117 {
5118 unsigned int inst = csky_read_insn (buf, 2);
5119 int imm = (disp + 2) >> 2;
5120 if (imm >= 0x80)
5121 {
5122 inst &= 0xe0;
5123 inst |= (~((imm >> 5) << 8)) & 0x300;
5124 make_insn (2, inst, (~imm & 0x1f), 5);
5125 }
5126 else
5127 {
5128 inst |= (imm >> 5) << 8;
5129 make_insn (2, inst, (imm & 0x1f), 5);
5130 }
5131 break;
5132 }
5133 case LRW_DISP16:
5134 {
5135 unsigned int inst = csky_read_insn (buf, 2);
5136 inst = CSKYV2_INST_LRW32 | (((inst & 0xe0) >> 5) << 16);
5137 if (IS_EXTERNAL_SYM (fragp->fr_symbol, asec))
5138 fix_new (fragp, fragp->fr_fix, 4,
5139 fragp->fr_symbol, fragp->fr_offset, 1,
5140 BFD_RELOC_CKCORE_PCREL_IMM16BY4);
5141 make_insn (4, inst, ((disp + 2) >> 2), 16);
5142 break;
5143 }
5144 case JCOMPZ_DISP16:
5145 {
5146 unsigned int inst = csky_read_insn (buf, 4);
5147 make_insn (4, inst, disp >> 1, 16);
5148 }
5149 break;
5150 case JCOMPZ_DISP32:
5151 {
5152 unsigned int inst = csky_read_insn (buf, 4);
5153 int literal_offset;
5154 make_insn (4, opposite_of_stored_compz (inst),
5155 (4 + 4 + PAD_LITERAL_LENGTH) >> 1, 16);
5156 literal_offset = ((fragp->fr_address + fragp->fr_fix) % 4 == 0
5157 ? 0 : 2);
5158 make_insn (4, CSKYV2_INST_JMPI32, (4 + literal_offset + 2) >> 2, 10);
5159 make_literal (fragp, literal_offset);
5160 }
5161 break;
5162 case JUNCD_DISP16:
5163 case UNCD_DISP16:
5164 {
5165 if (IS_EXTERNAL_SYM (fragp->fr_symbol, asec))
5166 fix_new (fragp, fragp->fr_fix, 4,
5167 fragp->fr_symbol, fragp->fr_offset, 1,
5168 BFD_RELOC_CKCORE_PCREL_IMM16BY2);
5169 make_insn (4, CSKYV2_INST_BR32, disp >> 1, 16);
5170 }
5171 break;
5172 case JCOND_DISP32:
5173 {
5174 /* 'jbt'/'jbf'-> <bf16/bt16>; jmpi32; [pad16]+literal32 */
5175 unsigned int inst = csky_read_insn (buf, 2);
5176 int literal_offset;
5177
5178 if (inst == CSKYV2_INST_BT16)
5179 inst = CSKYV2_INST_BF16;
5180 else
5181 inst = CSKYV2_INST_BT16;
5182 make_insn (2, inst, (2 + 4 + PAD_LITERAL_LENGTH) >> 1, 10);
5183 literal_offset = ((fragp->fr_address + fragp->fr_fix) % 4 == 0
5184 ? 0 : 2);
5185 make_insn (4, CSKYV2_INST_JMPI32, (4 + literal_offset + 2) >> 2, 10);
5186 make_literal (fragp, literal_offset);
5187 break;
5188 }
5189 case JUNCD_DISP32:
5190 {
5191 int literal_offset;
5192 literal_offset = ((fragp->fr_address + fragp->fr_fix) % 4 == 0
5193 ? 0 : 2);
5194 make_insn (4, CSKYV2_INST_JMPI32, (4 + literal_offset + 2) >> 2, 10);
5195 make_literal (fragp, literal_offset);
5196 }
5197 break;
5198 case RELAX_OVERFLOW:
5199 csky_branch_report_error (fragp->fr_file, fragp->fr_line,
5200 fragp->fr_symbol, disp);
5201 break;
5202 default:
5203 abort ();
5204 break;
5205 }
5206 }
5207
5208 /* Round up a section size to the appropriate boundary. */
5209
5210 valueT
5211 md_section_align (segT segment ATTRIBUTE_UNUSED,
5212 valueT size)
5213 {
5214 return size;
5215 }
5216
5217 /* MD interface: Symbol and relocation handling. */
5218
5219 void csky_md_finish (void)
5220 {
5221 dump_literals (0);
5222 }
5223
5224 /* Return the address within the segment that a PC-relative fixup is
5225 relative to. */
5226
5227 long
5228 md_pcrel_from_section (fixS * fixP, segT seg)
5229 {
5230 /* If the symbol is undefined or defined in another section
5231 we leave the add number alone for the linker to fix it later. */
5232 if (fixP->fx_addsy != (symbolS *) NULL
5233 && (! S_IS_DEFINED (fixP->fx_addsy)
5234 || S_GET_SEGMENT (fixP->fx_addsy) != seg))
5235 return fixP->fx_size;
5236
5237 /* The case where we are going to resolve things. */
5238 return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
5239 }
5240
5241 /* csky_cons_fix_new is called via the expression parsing code when a
5242 reloc is needed. We use this hook to get the correct .got reloc. */
5243
5244 void
5245 csky_cons_fix_new (fragS *frag,
5246 unsigned int off,
5247 unsigned int len,
5248 expressionS *exp,
5249 bfd_reloc_code_real_type reloc)
5250 {
5251 fixS *fixP;
5252
5253 if (BFD_RELOC_CKCORE_GOTOFF == insn_reloc
5254 || BFD_RELOC_CKCORE_GOTPC == insn_reloc
5255 || BFD_RELOC_CKCORE_GOT32 == insn_reloc
5256 || BFD_RELOC_CKCORE_PLT32 == insn_reloc
5257 || BFD_RELOC_CKCORE_TLS_LE32 == insn_reloc
5258 || BFD_RELOC_CKCORE_TLS_GD32 == insn_reloc
5259 || BFD_RELOC_CKCORE_TLS_LDM32 == insn_reloc
5260 || BFD_RELOC_CKCORE_TLS_LDO32 == insn_reloc
5261 || BFD_RELOC_CKCORE_TLS_IE32 == insn_reloc)
5262 reloc = insn_reloc;
5263 else
5264 switch (len)
5265 {
5266 case 1:
5267 reloc = BFD_RELOC_8;
5268 break;
5269 case 2:
5270 reloc = BFD_RELOC_16;
5271 break;
5272 case 4:
5273 reloc = BFD_RELOC_32;
5274 break;
5275 case 8:
5276 reloc = BFD_RELOC_64;
5277 break;
5278 default:
5279 as_bad (_("unsupported BFD relocation size %d"), len);
5280 reloc = BFD_RELOC_32;
5281 break;
5282 }
5283 fixP = fix_new_exp (frag, off, (int) len, exp, 0, reloc);
5284 if (BFD_RELOC_CKCORE_TLS_IE32 == insn_reloc
5285 || BFD_RELOC_CKCORE_TLS_GD32 == insn_reloc
5286 || BFD_RELOC_CKCORE_TLS_LDM32 == insn_reloc)
5287 {
5288 fixP->tc_fix_data.frag = literal_insn_offset->tls_addend.frag;
5289 fixP->tc_fix_data.offset = literal_insn_offset->tls_addend.offset;
5290 }
5291 }
5292
5293 /* See whether we need to force a relocation into the output file.
5294 This is used to force out switch and PC relative relocations when
5295 relaxing. */
5296
5297 int
5298 csky_force_relocation (fixS * fix)
5299 {
5300 if (fix->fx_r_type == BFD_RELOC_VTABLE_INHERIT
5301 || fix->fx_r_type == BFD_RELOC_VTABLE_ENTRY
5302 || fix->fx_r_type == BFD_RELOC_RVA
5303 || fix->fx_r_type == BFD_RELOC_CKCORE_ADDR_HI16
5304 || fix->fx_r_type == BFD_RELOC_CKCORE_ADDR_LO16
5305 || fix->fx_r_type == BFD_RELOC_CKCORE_TOFFSET_LO16
5306 || fix->fx_r_type == BFD_RELOC_CKCORE_DOFFSET_LO16)
5307 return 1;
5308
5309 if (fix->fx_addsy == NULL)
5310 return 0;
5311
5312 if (do_use_branchstub
5313 && fix->fx_r_type == BFD_RELOC_CKCORE_PCREL_IMM26BY2
5314 && (symbol_get_bfdsym (fix->fx_addsy)->flags & BSF_FUNCTION))
5315 return 1;
5316 return S_FORCE_RELOC (fix->fx_addsy, fix->fx_subsy == NULL);
5317 }
5318
5319 /* Return true if the fix can be handled by GAS, false if it must
5320 be passed through to the linker. */
5321
5322 bool
5323 csky_fix_adjustable (fixS * fixP)
5324 {
5325 if (fixP->fx_addsy == NULL)
5326 return 1;
5327
5328 /* We need the symbol name for the VTABLE entries. */
5329 if (fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
5330 || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY
5331 || fixP->fx_r_type == BFD_RELOC_CKCORE_PLT32
5332 || fixP->fx_r_type == BFD_RELOC_CKCORE_GOT32
5333 || fixP->fx_r_type == BFD_RELOC_CKCORE_PLT12
5334 || fixP->fx_r_type == BFD_RELOC_CKCORE_GOT12
5335 || fixP->fx_r_type == BFD_RELOC_CKCORE_GOT_HI16
5336 || fixP->fx_r_type == BFD_RELOC_CKCORE_GOT_LO16
5337 || fixP->fx_r_type == BFD_RELOC_CKCORE_PLT_HI16
5338 || fixP->fx_r_type == BFD_RELOC_CKCORE_PLT_LO16
5339 || fixP->fx_r_type == BFD_RELOC_CKCORE_GOTOFF
5340 || fixP->fx_r_type == BFD_RELOC_CKCORE_GOTOFF_HI16
5341 || fixP->fx_r_type == BFD_RELOC_CKCORE_GOTOFF_LO16
5342 || fixP->fx_r_type == BFD_RELOC_CKCORE_ADDR_HI16
5343 || fixP->fx_r_type == BFD_RELOC_CKCORE_ADDR_LO16
5344 || fixP->fx_r_type == BFD_RELOC_CKCORE_GOT_IMM18BY4
5345 || fixP->fx_r_type == BFD_RELOC_CKCORE_PLT_IMM18BY4
5346 || fixP->fx_r_type == BFD_RELOC_CKCORE_GOTOFF_IMM18
5347 || fixP->fx_r_type == BFD_RELOC_CKCORE_TLS_LE32
5348 || fixP->fx_r_type == BFD_RELOC_CKCORE_TLS_IE32
5349 || fixP->fx_r_type == BFD_RELOC_CKCORE_TLS_GD32
5350 || fixP->fx_r_type == BFD_RELOC_CKCORE_TLS_LDM32
5351 || fixP->fx_r_type == BFD_RELOC_CKCORE_TLS_LDO32)
5352 return 0;
5353
5354 if (do_use_branchstub
5355 && fixP->fx_r_type == BFD_RELOC_CKCORE_PCREL_IMM26BY2
5356 && (symbol_get_bfdsym (fixP->fx_addsy)->flags & BSF_FUNCTION))
5357 return 0;
5358
5359 return 1;
5360 }
5361
5362 void
5363 md_apply_fix (fixS *fixP,
5364 valueT *valP,
5365 segT seg)
5366 {
5367 reloc_howto_type *howto;
5368 /* Note: use offsetT because it is signed, valueT is unsigned. */
5369 offsetT val = *valP;
5370 char *buf = fixP->fx_frag->fr_literal + fixP->fx_where;
5371
5372 /* if fx_done = 0, fixup will also be processed in
5373 * tc_gen_reloc() after md_apply_fix(). */
5374 fixP->fx_done = 0;
5375
5376 /* If the fix is relative to a symbol which is not defined, or not
5377 in the same segment as the fix, we cannot resolve it here. */
5378 if (IS_CSKY_V1 (mach_flag) && fixP->fx_addsy != NULL
5379 && (! S_IS_DEFINED (fixP->fx_addsy)
5380 || S_GET_SEGMENT (fixP->fx_addsy) != seg))
5381 {
5382 switch (fixP->fx_r_type)
5383 {
5384 /* Data fx_addnumber is greater than 16 bits,
5385 so fx_addnumber is assigned zero. */
5386 case BFD_RELOC_CKCORE_PCREL_JSR_IMM11BY2:
5387 *valP = 0;
5388 break;
5389 case BFD_RELOC_CKCORE_TLS_IE32:
5390 case BFD_RELOC_CKCORE_TLS_LDM32:
5391 case BFD_RELOC_CKCORE_TLS_GD32:
5392 {
5393 struct tls_addend *ta = &(fixP->tc_fix_data);
5394 fixP->fx_offset = (fixP->fx_frag->fr_address + fixP->fx_where
5395 - (ta->frag->fr_address + ta->offset));
5396 *valP = fixP->fx_offset;
5397 }
5398 /* Fall through. */
5399 case BFD_RELOC_CKCORE_TLS_LE32:
5400 case BFD_RELOC_CKCORE_TLS_LDO32:
5401 S_SET_THREAD_LOCAL (fixP->fx_addsy);
5402 break;
5403 default:
5404 break;
5405 }
5406 #ifdef OBJ_ELF
5407 /* For ELF we can just return and let the reloc that will be generated
5408 take care of everything. For COFF we still have to insert 'val'
5409 into the insn since the addend field will be ignored. */
5410 return;
5411 #endif
5412 }
5413
5414 /* We can handle these relocs. */
5415 switch (fixP->fx_r_type)
5416 {
5417 case BFD_RELOC_32_PCREL:
5418 case BFD_RELOC_CKCORE_PCREL32:
5419 fixP->fx_r_type = BFD_RELOC_CKCORE_PCREL32;
5420 break;
5421 case BFD_RELOC_VTABLE_INHERIT:
5422 fixP->fx_r_type = BFD_RELOC_CKCORE_GNU_VTINHERIT;
5423 if (fixP->fx_addsy && !S_IS_DEFINED (fixP->fx_addsy)
5424 && !S_IS_WEAK (fixP->fx_addsy))
5425 S_SET_WEAK (fixP->fx_addsy);
5426 break;
5427 case BFD_RELOC_VTABLE_ENTRY:
5428 fixP->fx_r_type = BFD_RELOC_CKCORE_GNU_VTENTRY;
5429 break;
5430 case BFD_RELOC_CKCORE_GOT12:
5431 case BFD_RELOC_CKCORE_PLT12:
5432 case BFD_RELOC_CKCORE_ADDR_HI16:
5433 case BFD_RELOC_CKCORE_ADDR_LO16:
5434 case BFD_RELOC_CKCORE_TOFFSET_LO16:
5435 case BFD_RELOC_CKCORE_DOFFSET_LO16:
5436 case BFD_RELOC_CKCORE_GOT_HI16:
5437 case BFD_RELOC_CKCORE_GOT_LO16:
5438 case BFD_RELOC_CKCORE_PLT_HI16:
5439 case BFD_RELOC_CKCORE_PLT_LO16:
5440 case BFD_RELOC_CKCORE_GOTPC_HI16:
5441 case BFD_RELOC_CKCORE_GOTPC_LO16:
5442 case BFD_RELOC_CKCORE_GOTOFF_HI16:
5443 case BFD_RELOC_CKCORE_GOTOFF_LO16:
5444 case BFD_RELOC_CKCORE_DOFFSET_IMM18:
5445 case BFD_RELOC_CKCORE_DOFFSET_IMM18BY2:
5446 case BFD_RELOC_CKCORE_DOFFSET_IMM18BY4:
5447 case BFD_RELOC_CKCORE_GOTOFF_IMM18:
5448 case BFD_RELOC_CKCORE_GOT_IMM18BY4:
5449 case BFD_RELOC_CKCORE_PLT_IMM18BY4:
5450 break;
5451 case BFD_RELOC_CKCORE_TLS_IE32:
5452 case BFD_RELOC_CKCORE_TLS_LDM32:
5453 case BFD_RELOC_CKCORE_TLS_GD32:
5454 {
5455 struct tls_addend *ta = &(fixP->tc_fix_data);
5456 fixP->fx_offset = (fixP->fx_frag->fr_address + fixP->fx_where
5457 - (ta->frag->fr_address + ta->offset));
5458 *valP = fixP->fx_offset;
5459 }
5460 /* Fall through. */
5461 case BFD_RELOC_CKCORE_TLS_LE32:
5462 case BFD_RELOC_CKCORE_TLS_LDO32:
5463 S_SET_THREAD_LOCAL (fixP->fx_addsy);
5464 break;
5465 case BFD_RELOC_32:
5466 fixP->fx_r_type = BFD_RELOC_CKCORE_ADDR32;
5467 /* Fall through. */
5468 case BFD_RELOC_16:
5469 case BFD_RELOC_8:
5470 if (fixP->fx_addsy == NULL)
5471 {
5472 if (fixP->fx_size == 4)
5473 ;
5474 else if (fixP->fx_size == 2 && val >= -32768 && val <= 32767)
5475 ;
5476 else if (fixP->fx_size == 1 && val >= -256 && val <= 255)
5477 ;
5478 else
5479 break;
5480
5481 md_number_to_chars (buf, val, fixP->fx_size);
5482 fixP->fx_done = 1;
5483 }
5484 break;
5485 case BFD_RELOC_CKCORE_PCREL_JSR_IMM11BY2:
5486 if (fixP->fx_addsy == 0 && val > -2 KB && val < 2 KB)
5487 {
5488 long nval = (val >> 1) & 0x7ff;
5489 nval |= CSKYV1_INST_BSR;
5490 csky_write_insn (buf, nval, 2);
5491 fixP->fx_done = 1;
5492 }
5493 else
5494 *valP = 0;
5495 break;
5496 case BFD_RELOC_CKCORE_PCREL_JSR_IMM26BY2:
5497 if (fixP->fx_addsy == 0)
5498 {
5499 if (val >= -(1 << 26) && val < (1 << 26))
5500 {
5501 unsigned int nval = ((val + fixP->fx_size) >> 1) & 0x3ffffff;
5502 nval |= CSKYV2_INST_BSR32;
5503
5504 csky_write_insn (buf, nval, 4);
5505 }
5506 /* If bsr32 cannot reach,
5507 generate 'lrw r25,label;jsr r25' instead of 'jsri label'. */
5508 else if (IS_CSKY_ARCH_810 (mach_flag))
5509 {
5510 howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
5511 valueT opcode = csky_read_insn (buf, 4);
5512 opcode = (opcode & howto->dst_mask) | CSKYV2_INST_JSRI_TO_LRW;
5513 csky_write_insn (buf, opcode, 4);
5514 opcode = CSKYV2_INST_JSR_R26;
5515 csky_write_insn (buf + 4, opcode, 4);
5516 }
5517 fixP->fx_done = 1;
5518 }
5519 break;
5520
5521 default:
5522 {
5523 valueT opcode;
5524 offsetT min, max;
5525 unsigned int issigned = 0;
5526
5527 if (fixP->fx_addsy)
5528 break;
5529
5530 howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
5531 if (howto == NULL)
5532 {
5533 if (fixP->fx_size == 4
5534 || (fixP->fx_size == 2 && val >= -32768 && val <= 32767)
5535 || (fixP->fx_size == 1 && val >= -256 && val <= 255))
5536 {
5537 md_number_to_chars (buf, val, fixP->fx_size);
5538 fixP->fx_done = 1;
5539 break;
5540 }
5541 else
5542 abort ();
5543 }
5544
5545 if (IS_CSKY_V2 (mach_flag))
5546 val += fixP->fx_size;
5547
5548 if (howto->rightshift == 2)
5549 val += 2;
5550
5551 val >>= howto->rightshift;
5552
5553 switch (fixP->fx_r_type)
5554 {
5555 /* Offset is unsigned. */
5556 case BFD_RELOC_CKCORE_PCREL_IMM8BY4:
5557 case BFD_RELOC_CKCORE_PCREL_IMM10BY4:
5558 case BFD_RELOC_CKCORE_PCREL_IMM16BY4:
5559 max = (offsetT) howto->dst_mask;
5560 min = 0;
5561 break;
5562 /* lrw16. */
5563 case BFD_RELOC_CKCORE_PCREL_IMM7BY4:
5564 if (do_extend_lrw)
5565 max = (offsetT)((1 << (howto->bitsize + 1)) - 2);
5566 else
5567 max = (offsetT)((1 << howto->bitsize) - 1);
5568 min = 0;
5569 break;
5570 /* flrws, flrwd: the offset bits are divided in two parts. */
5571 case BFD_RELOC_CKCORE_PCREL_FLRW_IMM8BY4:
5572 max = (offsetT)((1 << howto->bitsize) - 1);
5573 min = 0;
5574 break;
5575 /* Offset is signed. */
5576 default:
5577 max = (offsetT)(howto->dst_mask >> 1);
5578 min = - max - 1;
5579 issigned = 1;
5580 }
5581 if (val < min || val > max)
5582 {
5583 csky_branch_report_error (fixP->fx_file, fixP->fx_line,
5584 fixP->fx_addsy, val);
5585 return;
5586 }
5587 opcode = csky_read_insn (buf, fixP->fx_size);
5588 /* Clear redundant bits brought from the last
5589 operation if there is any. */
5590 if (do_extend_lrw && (opcode & 0xfc00) == CSKYV2_INST_LRW16)
5591 val &= 0xff;
5592 else
5593 val &= issigned ? (offsetT)(howto->dst_mask) : max;
5594
5595 if (fixP->fx_r_type == BFD_RELOC_CKCORE_PCREL_BLOOP_IMM4BY4)
5596 val = (val & 0xf) << 12;
5597
5598 if (fixP->fx_size == 2 && (opcode & 0xfc00) == CSKYV2_INST_LRW16)
5599 {
5600 /* 8 bit offset lrw16. */
5601 if (val >= 0x80)
5602 csky_write_insn (buf,
5603 ((~val & 0x1f)
5604 | ((~val & 0x60) << 3) | (opcode & 0xe0)),
5605 fixP->fx_size);
5606 /* 7 bit offset lrw16. */
5607 else
5608 csky_write_insn (buf,
5609 (val & 0x1f) | ((val & 0x60) << 3) | opcode,
5610 fixP->fx_size);
5611 }
5612 else if (fixP->fx_size == 4
5613 && (opcode & 0xfe1ffe00) == CSKYV2_INST_FLRW)
5614 csky_write_insn (buf,
5615 ((val & 0xf) << 4) | ((val & 0xf0) << 17) | opcode,
5616 fixP->fx_size);
5617 else
5618 csky_write_insn (buf, val | opcode, fixP->fx_size);
5619 fixP->fx_done = 1;
5620 break;
5621 }
5622 }
5623 fixP->fx_addnumber = val;
5624 }
5625
5626 /* Translate internal representation of relocation info to BFD target
5627 format. */
5628
5629 arelent *
5630 tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixP)
5631 {
5632 arelent *rel;
5633
5634 if (fixP->fx_pcrel
5635 && fixP->fx_r_type == BFD_RELOC_CKCORE_ADDR32)
5636 fixP->fx_r_type = BFD_RELOC_CKCORE_PCREL32;
5637
5638 rel = xmalloc (sizeof (arelent));
5639 rel->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
5640 *rel->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
5641 rel->howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
5642 rel->addend = fixP->fx_offset;
5643 if (rel->howto == NULL)
5644 {
5645 as_bad_where (fixP->fx_file, fixP->fx_line,
5646 _("cannot represent `%s' relocation in object file"),
5647 bfd_get_reloc_code_name (fixP->fx_r_type));
5648
5649 /* Set howto to a garbage value so that we can keep going. */
5650 rel->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_32);
5651 }
5652 gas_assert (rel->howto != NULL);
5653 rel->address = fixP->fx_frag->fr_address + fixP->fx_where;
5654 return rel;
5655 }
5656
5657 /* Relax a fragment by scanning TC_GENERIC_RELAX_TABLE. */
5658
5659 long
5660 csky_relax_frag (segT segment, fragS *fragP, long stretch)
5661 {
5662 const relax_typeS *this_type;
5663 const relax_typeS *start_type;
5664 relax_substateT next_state;
5665 relax_substateT this_state;
5666 offsetT growth;
5667 offsetT aim;
5668 addressT target;
5669 addressT address;
5670 symbolS *symbolP;
5671 const relax_typeS *table;
5672
5673 target = fragP->fr_offset;
5674 address = fragP->fr_address;
5675 table = TC_GENERIC_RELAX_TABLE;
5676 this_state = fragP->fr_subtype;
5677 start_type = this_type = table + this_state;
5678 symbolP = fragP->fr_symbol;
5679
5680 if (symbolP)
5681 {
5682 fragS *sym_frag;
5683
5684 sym_frag = symbol_get_frag (symbolP);
5685
5686 #ifndef DIFF_EXPR_OK
5687 know (sym_frag != NULL);
5688 #endif
5689 know (S_GET_SEGMENT (symbolP) != absolute_section
5690 || sym_frag == &zero_address_frag);
5691 target += S_GET_VALUE (symbolP);
5692
5693 /* If SYM_FRAG has yet to be reached on this pass, assume it
5694 will move by STRETCH just as we did, unless there is an
5695 alignment frag between here and SYM_FRAG. An alignment may
5696 well absorb any STRETCH, and we don't want to choose a larger
5697 branch insn by overestimating the needed reach of this
5698 branch. It isn't critical to calculate TARGET exactly; We
5699 know we'll be doing another pass if STRETCH is non-zero. */
5700
5701 if (stretch != 0
5702 && sym_frag->relax_marker != fragP->relax_marker
5703 && S_GET_SEGMENT (symbolP) == segment)
5704 {
5705 fragS *f;
5706
5707 /* Adjust stretch for any alignment frag. Note that if have
5708 been expanding the earlier code, the symbol may be
5709 defined in what appears to be an earlier frag. FIXME:
5710 This doesn't handle the fr_subtype field, which specifies
5711 a maximum number of bytes to skip when doing an
5712 alignment. */
5713 for (f = fragP; f != NULL && f != sym_frag; f = f->fr_next)
5714 {
5715 if (f->fr_type == rs_align || f->fr_type == rs_align_code)
5716 {
5717 if (stretch < 0)
5718 stretch = -((-stretch)
5719 & ~((1 << (int) f->fr_offset) - 1));
5720 else
5721 stretch &= ~((1 << (int) f->fr_offset) - 1);
5722 }
5723 if (stretch == 0)
5724 break;
5725 }
5726 if (f != 0)
5727 target += stretch;
5728 }
5729 }
5730
5731 aim = target - address - fragP->fr_fix;
5732
5733 /* If the fragP->fr_symbol is extern symbol, aim should be 0. */
5734 if (fragP->fr_symbol && S_GET_SEGMENT (symbolP) != segment)
5735 aim = 0;
5736
5737 if (aim < 0)
5738 {
5739 /* Look backwards. */
5740 for (next_state = this_type->rlx_more; next_state;)
5741 if (aim >= this_type->rlx_backward)
5742 next_state = 0;
5743 else
5744 {
5745 /* Grow to next state. */
5746 this_state = next_state;
5747 this_type = table + this_state;
5748 next_state = this_type->rlx_more;
5749 }
5750 }
5751 else
5752 {
5753 /* Look forwards. */
5754 for (next_state = this_type->rlx_more; next_state;)
5755 if (aim <= this_type->rlx_forward)
5756 next_state = 0;
5757 else
5758 {
5759 /* Grow to next state. */
5760 this_state = next_state;
5761 this_type = table + this_state;
5762 next_state = this_type->rlx_more;
5763 }
5764 }
5765
5766 growth = this_type->rlx_length - start_type->rlx_length;
5767 if (growth != 0)
5768 fragP->fr_subtype = this_state;
5769 return growth;
5770 }
5771
5772 int
5773 md_estimate_size_before_relax (fragS * fragp,
5774 segT segtype)
5775 {
5776 switch (fragp->fr_subtype)
5777 {
5778 case COND_DISP10:
5779 case COND_DISP16:
5780 case SCOND_DISP10:
5781 case SCOND_DISP16:
5782 case UNCD_DISP10:
5783 case UNCD_DISP16:
5784 case JCOND_DISP10:
5785 case JCOND_DISP16:
5786 case JCOND_DISP32:
5787 case JUNCD_DISP10:
5788 case JUNCD_DISP16:
5789 case JUNCD_DISP32:
5790 case JCOMPZ_DISP16:
5791 case JCOMPZ_DISP32:
5792 case BSR_DISP26:
5793 case LRW_DISP7:
5794 case LRW2_DISP8:
5795 case LRW_DISP16:
5796 gas_assert (fragp->fr_symbol);
5797 if (IS_EXTERNAL_SYM (fragp->fr_symbol, segtype))
5798 while (csky_relax_table[fragp->fr_subtype].rlx_more > RELAX_OVERFLOW)
5799 fragp->fr_subtype = csky_relax_table[fragp->fr_subtype].rlx_more;
5800 return csky_relax_table[fragp->fr_subtype].rlx_length;
5801
5802 /* C-SKY V1 relaxes. */
5803 case C (UNCD_JUMP, UNDEF_DISP):
5804 case C (UNCD_JUMP_PIC, UNDEF_DISP):
5805 if (!fragp->fr_symbol)
5806 fragp->fr_subtype = C (UNCD_JUMP_S, DISP12);
5807 else if (S_GET_SEGMENT (fragp->fr_symbol) == segtype)
5808 fragp->fr_subtype = C (UNCD_JUMP_S, DISP12);
5809 else
5810 fragp->fr_subtype = C (UNCD_JUMP_S, UNDEF_WORD_DISP);
5811 break;
5812
5813 case C (COND_JUMP, UNDEF_DISP):
5814 case C (COND_JUMP_PIC, UNDEF_DISP):
5815 if (fragp->fr_symbol
5816 && S_GET_SEGMENT (fragp->fr_symbol) == segtype)
5817 /* Got a symbol and it's defined in this segment, become byte
5818 sized. Maybe it will fix up. */
5819 fragp->fr_subtype = C (COND_JUMP_S, DISP12);
5820 else if (fragp->fr_symbol)
5821 /* It's got a segment, but it's not ours, so it will always be
5822 long. */
5823 fragp->fr_subtype = C (COND_JUMP_S, UNDEF_WORD_DISP);
5824 else
5825 /* We know the abs value. */
5826 fragp->fr_subtype = C (COND_JUMP_S, DISP12);
5827 break;
5828
5829 case C (UNCD_JUMP, DISP12):
5830 case C (UNCD_JUMP, DISP32):
5831 case C (UNCD_JUMP, UNDEF_WORD_DISP):
5832 case C (COND_JUMP, DISP12):
5833 case C (COND_JUMP, DISP32):
5834 case C (COND_JUMP, UNDEF_WORD_DISP):
5835 case C (UNCD_JUMP_PIC, DISP12):
5836 case C (UNCD_JUMP_PIC, DISP32):
5837 case C (UNCD_JUMP_PIC, UNDEF_WORD_DISP):
5838 case C (COND_JUMP_PIC, DISP12):
5839 case C (COND_JUMP_PIC, DISP32):
5840 case C (COND_JUMP_PIC, UNDEF_WORD_DISP):
5841 case RELAX_OVERFLOW:
5842 break;
5843
5844 default:
5845 abort ();
5846 }
5847 return csky_relax_table[fragp->fr_subtype].rlx_length;
5848 }
5849
5850 /* Parse opcode like: "op oprnd1, oprnd2, oprnd3". */
5851
5852 static void
5853 csky_macro_md_assemble (const char *op,
5854 const char *oprnd1,
5855 const char *oprnd2,
5856 const char *oprnd3)
5857 {
5858 char str[80];
5859 str[0] = '\0';
5860 strcat (str, op);
5861 if (oprnd1 != NULL)
5862 {
5863 strcat (str, " ");
5864 strcat (str, oprnd1);
5865 if (oprnd2 != NULL)
5866 {
5867 strcat (str, ",");
5868 strcat (str, oprnd2);
5869 if (oprnd3 != NULL)
5870 {
5871 strcat (str, ",");
5872 strcat (str, oprnd3);
5873 }
5874 }
5875 }
5876 md_assemble (str);
5877 return;
5878 }
5879
5880 /* Get the string of operand. */
5881
5882 static int
5883 csky_get_macro_operand (char *src_s, char *dst_s, char end_sym)
5884 {
5885 int nlen = 0;
5886 while (ISSPACE (*src_s))
5887 ++src_s;
5888 while (*src_s != end_sym)
5889 dst_s[nlen++] = *(src_s++);
5890 dst_s[nlen] = '\0';
5891 return nlen;
5892 }
5893
5894 /* idly 4 -> idly4. */
5895
5896 static void
5897 csky_idly (void)
5898 {
5899 char *s = csky_insn.opcode_end;
5900 if (!is_imm_within_range (&s, 4, 4))
5901 {
5902 as_bad (_("second operand must be 4"));
5903 return;
5904 }
5905 csky_macro_md_assemble ("idly4", NULL, NULL, NULL);
5906 return;
5907 }
5908
5909 /* rolc rd, 1 or roltc rd, 1 -> addc rd, rd. */
5910
5911 static void
5912 csky_rolc (void)
5913 {
5914 char reg[10];
5915 char *s = csky_insn.opcode_end;
5916
5917 s += csky_get_macro_operand (s, reg, ',');
5918 ++s;
5919
5920 if (is_imm_within_range (&s, 1, 1))
5921 {
5922 csky_macro_md_assemble ("addc", reg, reg, NULL);
5923 return;
5924 }
5925 else
5926 as_bad (_("second operand must be 1"));
5927 }
5928
5929 /* sxtrb0(1)(2) r1, rx -> xtbr0(1)(2) r1,rx; sextb r1. */
5930
5931 static void
5932 csky_sxtrb (void)
5933 {
5934 char reg1[10];
5935 char reg2[10];
5936
5937 char *s = csky_insn.opcode_end;
5938 s += csky_get_macro_operand (s, reg1, ',');
5939 ++s;
5940 csky_get_macro_operand (s, reg2, '\0');
5941
5942 csky_macro_md_assemble (csky_insn.macro->name + 1, reg1, reg2, NULL);
5943 csky_macro_md_assemble ("sextb", reg1, NULL, NULL);
5944 return;
5945 }
5946
5947 static void
5948 csky_movtf (void)
5949 {
5950 char reg1[10];
5951 char reg2[10];
5952 char reg3[10];
5953
5954 char *s = csky_insn.opcode_end;
5955 s += csky_get_macro_operand (s, reg1, ',');
5956 ++s;
5957
5958 s += csky_get_macro_operand (s, reg2, ',');
5959 ++s;
5960
5961 s += csky_get_macro_operand (s, reg3, '\0');
5962 ++s;
5963 csky_macro_md_assemble ("movt", reg1, reg2, NULL);
5964 csky_macro_md_assemble ("movf", reg1, reg3, NULL);
5965 return;
5966 }
5967
5968 static bool
5969 get_macro_reg_vals (int *reg1, int *reg2, int *reg3)
5970 {
5971 int nlen;
5972 char *s = csky_insn.opcode_end;
5973
5974 *reg1 = csky_get_reg_val (s, &nlen);
5975 s += nlen;
5976 if (*s != ',')
5977 {
5978 csky_show_error (ERROR_MISSING_COMMA, 0, NULL, NULL);
5979 return false;
5980 }
5981 s++;
5982 *reg2 = csky_get_reg_val (s, &nlen);
5983 s += nlen;
5984 if (*s != ',')
5985 {
5986 csky_show_error (ERROR_MISSING_COMMA, 0, NULL, NULL);
5987 return false;
5988 }
5989 s++;
5990 *reg3 = csky_get_reg_val (s, &nlen);
5991 s += nlen;
5992 if (*s != '\0')
5993 {
5994 csky_show_error (ERROR_BAD_END, 0, s, NULL);
5995 return false;
5996 }
5997 if (*reg1 == -1 || *reg2 == -1 || *reg3 == -1)
5998 {
5999 as_bad (_("register number out of range"));
6000 return false;
6001 }
6002 if (*reg1 != *reg2)
6003 {
6004 as_bad (_("dest and source1 must be the same register"));
6005 return false;
6006 }
6007 if (*reg1 >= 15 || *reg3 >= 15)
6008 {
6009 as_bad (_("64-bit operator src/dst register must be less than 15"));
6010 return false;
6011 }
6012 return true;
6013 }
6014
6015 /* addc64 rx, rx, ry -> cmplt rx, rx, addc rx, ry, addc rx+1, ry+1. */
6016
6017 static void
6018 csky_addc64 (void)
6019 {
6020 int reg1;
6021 int reg2;
6022 int reg3;
6023 char reg1_name[16] = {0};
6024 char reg3_name[16] = {0};
6025
6026 if (!get_macro_reg_vals (&reg1, &reg2, &reg3))
6027 return;
6028
6029 sprintf (reg1_name, "r%d", reg1);
6030 csky_macro_md_assemble ("cmplt", reg1_name, reg1_name, NULL);
6031 if (error_state.err_num != ERROR_NONE)
6032 return;
6033
6034 sprintf (reg1_name, "r%d", reg1 + (target_big_endian ? 1 : 0));
6035 sprintf (reg3_name, "r%d", reg3 + (target_big_endian ? 1 : 0));
6036 csky_macro_md_assemble ("addc", reg1_name, reg3_name, NULL);
6037 if (error_state.err_num != ERROR_NONE)
6038 return;
6039
6040 sprintf (reg1_name, "r%d", reg1 + (target_big_endian ? 0 : 1));
6041 sprintf (reg3_name, "r%d", reg3 + (target_big_endian ? 0 : 1));
6042 csky_macro_md_assemble ("addc", reg1_name, reg3_name, NULL);
6043 return;
6044 }
6045
6046 /* subc64 rx, rx, ry -> cmphs rx, rx, subc rx, ry, subc rx+1, ry+1. */
6047
6048 static void
6049 csky_subc64 (void)
6050 {
6051 int reg1;
6052 int reg2;
6053 int reg3;
6054 char reg1_name[16] = {0};
6055 char reg3_name[16] = {0};
6056
6057 if (!get_macro_reg_vals (&reg1, &reg2, &reg3))
6058 return;
6059
6060 sprintf (reg1_name, "r%d", reg1);
6061 csky_macro_md_assemble ("cmphs", reg1_name, reg1_name, NULL);
6062 if (error_state.err_num != ERROR_NONE)
6063 return;
6064
6065 sprintf (reg1_name, "r%d", reg1 + (target_big_endian ? 1 : 0));
6066 sprintf (reg3_name, "r%d", reg3 + (target_big_endian ? 1 : 0));
6067 csky_macro_md_assemble ("subc", reg1_name, reg3_name, NULL);
6068 if (error_state.err_num != ERROR_NONE)
6069 return;
6070
6071 sprintf (reg1_name, "r%d", reg1 + (target_big_endian ? 0 : 1));
6072 sprintf (reg3_name, "r%d", reg3 + (target_big_endian ? 0 : 1));
6073 csky_macro_md_assemble ("subc", reg1_name, reg3_name, NULL);
6074 return;
6075 }
6076
6077 /* or64 rx, rx, ry -> or rx, ry, or rx+1, ry+1. */
6078
6079 static void
6080 csky_or64 (void)
6081 {
6082 int reg1;
6083 int reg2;
6084 int reg3;
6085 char reg1_name[16] = {0};
6086 char reg3_name[16] = {0};
6087
6088 if (!get_macro_reg_vals (&reg1, &reg2, &reg3))
6089 return;
6090 sprintf (reg1_name, "r%d", reg1 + (target_big_endian ? 1 : 0));
6091 sprintf (reg3_name, "r%d", reg3 + (target_big_endian ? 1 : 0));
6092 csky_macro_md_assemble ("or", reg1_name, reg3_name, NULL);
6093
6094 if (error_state.err_num != ERROR_NONE)
6095 return;
6096 sprintf (reg1_name, "r%d", reg1 + (target_big_endian ? 0 : 1));
6097 sprintf (reg3_name, "r%d", reg3 + (target_big_endian ? 0 : 1));
6098 csky_macro_md_assemble ("or", reg1_name, reg3_name, NULL);
6099 return;
6100 }
6101
6102 /* xor64 rx, rx, ry -> xor rx, ry, xor rx+1, ry+1. */
6103
6104 static void
6105 csky_xor64 (void)
6106 {
6107 int reg1;
6108 int reg2;
6109 int reg3;
6110 char reg1_name[16] = {0};
6111 char reg3_name[16] = {0};
6112
6113 if (!get_macro_reg_vals (&reg1, &reg2, &reg3))
6114 return;
6115
6116 sprintf (reg1_name, "r%d", reg1 + (target_big_endian ? 1 : 0));
6117 sprintf (reg3_name, "r%d", reg3 + (target_big_endian ? 1 : 0));
6118 csky_macro_md_assemble ("xor", reg1_name, reg3_name, NULL);
6119 if (error_state.err_num != ERROR_NONE)
6120 return;
6121
6122 sprintf (reg1_name, "r%d", reg1 + (target_big_endian ? 0 : 1));
6123 sprintf (reg3_name, "r%d", reg3 + (target_big_endian ? 0 : 1));
6124 csky_macro_md_assemble ("xor", reg1_name, reg3_name, NULL);
6125 return;
6126 }
6127
6128 /* The following are V2 macro instructions. */
6129
6130 /* neg rd -> not rd, rd; addi rd, 1. */
6131
6132 static void
6133 csky_neg (void)
6134 {
6135 char reg1[10];
6136
6137 char *s = csky_insn.opcode_end;
6138 s += csky_get_macro_operand (s, reg1, '\0');
6139 ++s;
6140
6141 csky_macro_md_assemble ("not", reg1, reg1, NULL);
6142 csky_macro_md_assemble ("addi", reg1, "1", NULL);
6143 return;
6144 }
6145
6146 /* rsubi rd, imm16 -> not rd; addi rd, imm16 + 1 */
6147
6148 static void
6149 csky_rsubi (void)
6150 {
6151 char reg1[10];
6152 char str_imm16[20];
6153 unsigned int imm16 = 0;
6154 expressionS e;
6155 char *s = csky_insn.opcode_end;
6156 s += csky_get_macro_operand (s, reg1, ',');
6157 ++s;
6158
6159 s = parse_exp (s, &e);
6160 if (e.X_op == O_constant)
6161 imm16 = e.X_add_number;
6162 else
6163 csky_show_error (ERROR_IMM_ILLEGAL, 2, NULL, NULL);
6164
6165 sprintf (str_imm16, "%d", imm16 + 1);
6166
6167 csky_macro_md_assemble ("not", reg1, reg1, NULL);
6168 csky_macro_md_assemble ("addi", reg1, str_imm16, NULL);
6169 return;
6170 }
6171
6172 /* Such as: asrc rd -> asrc rd, rd, 1. */
6173
6174 static void
6175 csky_arith (void)
6176 {
6177 char reg1[10];
6178 char *s = csky_insn.opcode_end;
6179 s += csky_get_macro_operand (s, reg1, '\0');
6180 ++s;
6181 csky_macro_md_assemble (csky_insn.macro->name, reg1, reg1, "1");
6182 return;
6183 }
6184
6185 /* decne rd -> if ck802: subi rd, 1; cmpnei rd, 0.
6186 else: decne rd, rd, 1 */
6187
6188 static void
6189 csky_decne (void)
6190 {
6191 char reg1[10];
6192 char *s = csky_insn.opcode_end;
6193 s += csky_get_macro_operand (s, reg1, '\0');
6194 ++s;
6195 if (IS_CSKY_ARCH_802 (mach_flag))
6196 {
6197 csky_macro_md_assemble ("subi", reg1, "1", NULL);
6198 csky_macro_md_assemble ("cmpnei", reg1, "0", NULL);
6199 }
6200 else
6201 csky_macro_md_assemble ("decne", reg1, reg1, "1");
6202 return;
6203 }
6204
6205 /* If -mnolrw, lrw rd, imm -> movih rd, imm_hi16; ori rd, imm_lo16. */
6206
6207 static void
6208 csky_lrw (void)
6209 {
6210 char reg1[10];
6211 char imm[40];
6212 char imm_hi16[40];
6213 char imm_lo16[40];
6214
6215 char *s = csky_insn.opcode_end;
6216 s += csky_get_macro_operand (s, reg1, ',');
6217 ++s;
6218 s += csky_get_macro_operand (s, imm, '\0');
6219 ++s;
6220
6221 imm_hi16[0] = '\0';
6222 strcat (imm_hi16, "(");
6223 strcat (imm_hi16, imm);
6224 strcat (imm_hi16, ") >> 16");
6225 imm_lo16[0] = '\0';
6226 strcat (imm_lo16, "(");
6227 strcat (imm_lo16, imm);
6228 strcat (imm_lo16, ") & 0xffff");
6229
6230 csky_macro_md_assemble ("movih", reg1, imm_hi16, NULL);
6231 csky_macro_md_assemble ("ori", reg1, reg1, imm_lo16);
6232
6233 return;
6234 }
6235
6236 /* The following are worker functions for C-SKY v1. */
6237
6238 bool
6239 v1_work_lrw (void)
6240 {
6241 int reg;
6242 int output_literal = csky_insn.val[1];
6243
6244 reg = csky_insn.val[0];
6245 csky_insn.isize = 2;
6246 csky_insn.output = frag_more (2);
6247 if (csky_insn.e1.X_op == O_constant
6248 && csky_insn.e1.X_add_number <= 0x7f
6249 && csky_insn.e1.X_add_number >= 0)
6250 /* lrw to movi. */
6251 csky_insn.inst = 0x6000 | reg | (csky_insn.e1.X_add_number << 4);
6252 else
6253 {
6254 csky_insn.inst = csky_insn.opcode->op16[0].opcode;
6255 csky_insn.inst |= reg << 8;
6256 if (output_literal)
6257 {
6258 struct literal *p = enter_literal (&csky_insn.e1, 0, 0, 0);
6259
6260 /* Create a reference to pool entry. */
6261 csky_insn.e1.X_op = O_symbol;
6262 csky_insn.e1.X_add_symbol = poolsym;
6263 csky_insn.e1.X_add_number = p->offset << 2;
6264 }
6265
6266 if (insn_reloc == BFD_RELOC_CKCORE_TLS_GD32
6267 || insn_reloc == BFD_RELOC_CKCORE_TLS_LDM32
6268 || insn_reloc == BFD_RELOC_CKCORE_TLS_IE32)
6269 {
6270 literal_insn_offset->tls_addend.frag = frag_now;
6271 literal_insn_offset->tls_addend.offset
6272 = (csky_insn.output
6273 - literal_insn_offset->tls_addend.frag->fr_literal);
6274 }
6275 fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal, 2,
6276 &csky_insn.e1, 1, BFD_RELOC_CKCORE_PCREL_IMM8BY4);
6277 }
6278 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
6279
6280 return true;
6281 }
6282
6283 bool
6284 v1_work_fpu_fo (void)
6285 {
6286 int i = 0;
6287 int inst;
6288 int greg = -1;
6289 char buff[50];
6290 struct csky_opcode_info *opinfo = NULL;
6291
6292 if (csky_insn.isize == 4)
6293 opinfo = &csky_insn.opcode->op32[csky_insn.opcode_idx];
6294 else if (csky_insn.isize == 2)
6295 opinfo = &csky_insn.opcode->op16[csky_insn.opcode_idx];
6296
6297 /* Firstly, get general reg. */
6298 for (i = 0;i < opinfo->operand_num; i++)
6299 if (opinfo->oprnd.oprnds[i].type == OPRND_TYPE_GREG0_15)
6300 greg = csky_insn.val[i];
6301 gas_assert (greg != -1);
6302
6303 /* Secondly, get float inst. */
6304 csky_generate_insn ();
6305 inst = csky_insn.inst;
6306
6307 /* Now get greg and inst, we can write instruction to floating unit. */
6308 sprintf (buff, "lrw r%d,0x%x", greg, inst);
6309 md_assemble (buff);
6310 sprintf (buff, "cpwir r%d", greg);
6311 md_assemble (buff);
6312 return false;
6313 }
6314
6315 bool
6316 v1_work_fpu_fo_fc (void)
6317 {
6318 int i = 0;
6319 int inst;
6320 int greg = -1;
6321 char buff[50];
6322 struct csky_opcode_info *opinfo = NULL;
6323
6324 if (csky_insn.isize == 4)
6325 opinfo = &csky_insn.opcode->op32[csky_insn.opcode_idx];
6326 else if (csky_insn.isize == 2)
6327 opinfo = &csky_insn.opcode->op16[csky_insn.opcode_idx];
6328
6329 /* Firstly, get general reg. */
6330 for (i = 0;i < opinfo->operand_num; i++)
6331 if (opinfo->oprnd.oprnds[i].type == OPRND_TYPE_GREG0_15)
6332 greg = csky_insn.val[i];
6333 gas_assert (greg != -1);
6334
6335 /* Secondly, get float inst. */
6336 csky_generate_insn ();
6337 inst = csky_insn.inst;
6338
6339 /* Now get greg and inst, we can write instruction to floating unit. */
6340 sprintf (buff, "lrw r%d,0x%x", greg, inst);
6341 md_assemble (buff);
6342 sprintf (buff, "cpwir r%d", greg);
6343 md_assemble (buff);
6344 sprintf (buff, "cprc");
6345 md_assemble (buff);
6346
6347 return false;
6348 }
6349
6350 bool
6351 v1_work_fpu_write (void)
6352 {
6353 int greg;
6354 int freg;
6355 char buff[50];
6356
6357 greg = csky_insn.val[0];
6358 freg = csky_insn.val[1];
6359
6360 /* Now get greg and freg, we can write instruction to floating unit. */
6361 sprintf (buff, "cpwgr r%d,cpr%d", greg, freg);
6362 md_assemble (buff);
6363
6364 return false;
6365 }
6366
6367 bool
6368 v1_work_fpu_read (void)
6369 {
6370 int greg;
6371 int freg;
6372 char buff[50];
6373
6374 greg = csky_insn.val[0];
6375 freg = csky_insn.val[1];
6376 /* Now get greg and freg, we can write instruction to floating unit. */
6377 sprintf (buff, "cprgr r%d,cpr%d", greg, freg);
6378 md_assemble (buff);
6379
6380 return false;
6381 }
6382
6383 bool
6384 v1_work_fpu_writed (void)
6385 {
6386 int greg;
6387 int freg;
6388 char buff[50];
6389
6390 greg = csky_insn.val[0];
6391 freg = csky_insn.val[1];
6392
6393 if (greg & 0x1)
6394 {
6395 as_bad (_("even register number required"));
6396 return false;
6397 }
6398 /* Now get greg and freg, we can write instruction to floating unit. */
6399 if (target_big_endian)
6400 sprintf (buff, "cpwgr r%d,cpr%d", greg + 1, freg);
6401 else
6402 sprintf (buff, "cpwgr r%d,cpr%d", greg, freg);
6403 md_assemble (buff);
6404 if (target_big_endian)
6405 sprintf (buff, "cpwgr r%d,cpr%d", greg, freg + 1);
6406 else
6407 sprintf (buff, "cpwgr r%d,cpr%d", greg+1, freg + 1);
6408 md_assemble (buff);
6409 return false;
6410 }
6411
6412 bool
6413 v1_work_fpu_readd (void)
6414 {
6415 int greg;
6416 int freg;
6417 char buff[50];
6418
6419 greg = csky_insn.val[0];
6420 freg = csky_insn.val[1];
6421
6422 if (greg & 0x1)
6423 {
6424 as_bad (_("even register number required"));
6425 return false;
6426 }
6427 /* Now get greg and freg, we can write instruction to floating unit. */
6428 if (target_big_endian)
6429 sprintf (buff, "cprgr r%d,cpr%d", greg+1, freg);
6430 else
6431 sprintf (buff, "cprgr r%d,cpr%d", greg, freg);
6432 md_assemble (buff);
6433 if (target_big_endian)
6434 sprintf (buff, "cprgr r%d,cpr%d", greg, freg + 1);
6435 else
6436 sprintf (buff, "cprgr r%d,cpr%d", greg+1, freg + 1);
6437 md_assemble (buff);
6438
6439 return false;
6440 }
6441
6442 /* The following are for csky pseudo handling. */
6443
6444 bool
6445 v1_work_jbsr (void)
6446 {
6447 csky_insn.output = frag_more (2);
6448 if (do_force2bsr)
6449 /* Generate fixup BFD_RELOC_CKCORE_PCREL_IMM11BY2. */
6450 fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
6451 2, & csky_insn.e1, 1, BFD_RELOC_CKCORE_PCREL_IMM11BY2);
6452 else
6453 {
6454 /* Using jsri instruction. */
6455 const char *name = "jsri";
6456 csky_insn.opcode = (struct csky_opcode *)
6457 str_hash_find (csky_opcodes_hash, name);
6458 csky_insn.opcode_idx = 0;
6459 csky_insn.isize = 2;
6460
6461 struct literal *p = enter_literal (&csky_insn.e1, 1, 0, 0);
6462
6463 /* Create a reference to pool entry. */
6464 csky_insn.e1.X_op = O_symbol;
6465 csky_insn.e1.X_add_symbol = poolsym;
6466 csky_insn.e1.X_add_number = p->offset << 2;
6467
6468 /* Generate fixup BFD_RELOC_CKCORE_PCREL_IMM8BY4. */
6469 fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
6470 2, & csky_insn.e1, 1, BFD_RELOC_CKCORE_PCREL_IMM8BY4);
6471
6472 if (csky_insn.e1.X_op != O_absent && do_jsri2bsr)
6473 /* Generate fixup BFD_RELOC_CKCORE_PCREL_JSR_IMM11BY2. */
6474 fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
6475 2, &p->e,
6476 1, BFD_RELOC_CKCORE_PCREL_JSR_IMM11BY2);
6477 }
6478 csky_generate_insn ();
6479
6480 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
6481
6482 return true;
6483 }
6484
6485 /* The following are worker functions for csky v2 instruction handling. */
6486
6487 /* For nie/nir/ipush/ipop. */
6488
6489 bool
6490 v2_work_istack (void)
6491 {
6492 if (!do_intr_stack)
6493 {
6494 csky_show_error (ERROR_OPCODE_ILLEGAL, 0, NULL, NULL);
6495 return false;
6496 }
6497 csky_insn.output = frag_more (csky_insn.isize);
6498 csky_insn.inst = csky_insn.opcode->op16[0].opcode;
6499 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
6500 return true;
6501 }
6502
6503 bool
6504 v2_work_btsti (void)
6505 {
6506 if (!do_extend_lrw
6507 && (csky_insn.flag_force == INSN_OPCODE16F
6508 || IS_CSKY_ARCH_801 (mach_flag)))
6509 {
6510 csky_show_error (ERROR_OPCODE_ILLEGAL, 0, NULL, NULL);
6511 return false;
6512 }
6513 if (!do_extend_lrw && csky_insn.isize == 2)
6514 csky_insn.isize = 4;
6515 /* Generate relax or reloc if necessary. */
6516 csky_generate_frags ();
6517 /* Generate the insn by mask. */
6518 csky_generate_insn ();
6519 /* Write inst to frag. */
6520 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
6521 return true;
6522 }
6523
6524 bool
6525 v2_work_addi (void)
6526 {
6527 csky_insn.isize = 2;
6528 if (csky_insn.number == 2)
6529 {
6530 if (csky_insn.val[0] == 14
6531 && csky_insn.val[1] >= 0 && csky_insn.val[1] <= 0x1fc
6532 && (csky_insn.val[1] & 0x3) == 0
6533 && csky_insn.flag_force != INSN_OPCODE32F)
6534 {
6535 /* addi sp, sp, imm. */
6536 csky_insn.inst = 0x1400 | ((csky_insn.val[1] >> 2) & 0x1f);
6537 csky_insn.inst |= (csky_insn.val[1] << 1) & 0x300;
6538 csky_insn.output = frag_more (2);
6539 }
6540 else if (csky_insn.val[0] < 8
6541 && csky_insn.val[1] >= 1 && csky_insn.val[1] <= 0x100
6542 && csky_insn.flag_force != INSN_OPCODE32F)
6543 {
6544 csky_insn.inst = 0x2000 | (csky_insn.val[0] << 8);
6545 csky_insn.inst |= (csky_insn.val[1] - 1);
6546 csky_insn.output = frag_more (2);
6547 }
6548 else if (csky_insn.val[1] >= 1 && csky_insn.val[1] <= 0x10000
6549 && csky_insn.flag_force != INSN_OPCODE16F
6550 && !IS_CSKY_ARCH_801 (mach_flag))
6551 {
6552 csky_insn.inst = 0xe4000000 | (csky_insn.val[0] << 21);
6553 csky_insn.inst |= csky_insn.val[0] << 16;
6554 csky_insn.inst |= (csky_insn.val[1] - 1);
6555 csky_insn.isize = 4;
6556 csky_insn.output = frag_more (4);
6557 }
6558 else
6559 {
6560 csky_show_error (ERROR_OPERANDS_ILLEGAL, 0,
6561 csky_insn.opcode_end, NULL);
6562 return false;
6563 }
6564 }
6565 else if (csky_insn.number == 3)
6566 {
6567 if (csky_insn.val[0] == 14
6568 && csky_insn.val[1] == 14
6569 && csky_insn.val[2] >= 0 && csky_insn.val[2] <= 0x1fc
6570 && (csky_insn.val[2] & 0x3) == 0
6571 && csky_insn.flag_force != INSN_OPCODE32F)
6572 {
6573 csky_insn.inst = 0x1400 | ((csky_insn.val[2] >> 2) & 0x1f);
6574 csky_insn.inst |= (csky_insn.val[2] << 1) & 0x300;
6575 csky_insn.output = frag_more (2);
6576 }
6577 else if (csky_insn.val[0] < 8
6578 && csky_insn.val[1] == 14
6579 && csky_insn.val[2] >= 0 && csky_insn.val[2] <= 0x3fc
6580 && (csky_insn.val[2] & 0x3) == 0
6581 && csky_insn.flag_force != INSN_OPCODE32F)
6582 {
6583 csky_insn.inst = 0x1800 | (csky_insn.val[0] << 8);
6584 csky_insn.inst |= csky_insn.val[2] >> 2;
6585 csky_insn.output = frag_more (2);
6586 }
6587 else if (csky_insn.val[0] < 8
6588 && csky_insn.val[0] == csky_insn.val[1]
6589 && csky_insn.val[2] >= 1 && csky_insn.val[2] <= 0x100
6590 && csky_insn.flag_force != INSN_OPCODE32F)
6591 {
6592 csky_insn.inst = 0x2000 | (csky_insn.val[0] << 8);
6593 csky_insn.inst |= (csky_insn.val[2] - 1);
6594 csky_insn.output = frag_more (2);
6595 }
6596 else if (csky_insn.val[0] < 8
6597 && csky_insn.val[1] < 8
6598 && csky_insn.val[2] >= 1 && csky_insn.val[2] <= 0x8
6599 && csky_insn.flag_force != INSN_OPCODE32F)
6600 {
6601 csky_insn.inst = 0x5802 | (csky_insn.val[0] << 5);
6602 csky_insn.inst |= csky_insn.val[1] << 8;
6603 csky_insn.inst |= (csky_insn.val[2] - 1) << 2;
6604 csky_insn.output = frag_more (2);
6605 }
6606 else if (csky_insn.val[1] == 28
6607 && csky_insn.val[2] >= 1 && csky_insn.val[2] <= 0x40000
6608 && csky_insn.flag_force != INSN_OPCODE16F
6609 && !IS_CSKY_ARCH_801 (mach_flag))
6610 {
6611 csky_insn.inst = 0xcc1c0000 | (csky_insn.val[0] << 21);
6612 csky_insn.isize = 4;
6613 csky_insn.output = frag_more (4);
6614 if (insn_reloc == BFD_RELOC_CKCORE_GOTOFF)
6615 {
6616 fix_new_exp (frag_now, csky_insn.output-frag_now->fr_literal,
6617 4, &csky_insn.e1, 0, BFD_RELOC_CKCORE_GOTOFF_IMM18);
6618 }
6619 else
6620 csky_insn.inst |= (csky_insn.val[2] - 1);
6621 }
6622 else if (csky_insn.val[2] >= 1 && csky_insn.val[2] <= 0x1000
6623 && csky_insn.flag_force != INSN_OPCODE16F
6624 && !IS_CSKY_ARCH_801 (mach_flag))
6625 {
6626 csky_insn.inst = 0xe4000000 | (csky_insn.val[0] << 21);
6627 csky_insn.inst |= csky_insn.val[1] << 16;
6628 csky_insn.inst |= (csky_insn.val[2] - 1);
6629 csky_insn.isize = 4;
6630 csky_insn.output = frag_more (4);
6631 }
6632 else
6633 {
6634 csky_show_error (ERROR_OPERANDS_ILLEGAL, 0,
6635 (char *)csky_insn.opcode_end, NULL);
6636 return false;
6637 }
6638 }
6639 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
6640
6641 return true;
6642 }
6643
6644 bool
6645 v2_work_subi (void)
6646 {
6647 csky_insn.isize = 2;
6648 if (csky_insn.number == 2)
6649 {
6650 if (csky_insn.val[0] == 14
6651 && csky_insn.val[1] >= 0 && csky_insn.val[2] <= 0x1fc
6652 && (csky_insn.val[1] & 0x3) == 0
6653 && csky_insn.flag_force != INSN_OPCODE32F)
6654 {
6655 csky_insn.inst = 0x1420 | ((csky_insn.val[1] >> 2) & 0x1f);
6656 csky_insn.inst |= (csky_insn.val[1] << 1) & 0x300;
6657 }
6658 else if (csky_insn.val[0] < 8
6659 && csky_insn.val[1] >= 1 && csky_insn.val[1] <= 0x100
6660 && csky_insn.flag_force != INSN_OPCODE32F)
6661 {
6662 csky_insn.inst = 0x2800 | (csky_insn.val[0] << 8);
6663 csky_insn.inst |= (csky_insn.val[1] - 1);
6664 }
6665 else if (csky_insn.val[1] >= 1 && csky_insn.val[1] <= 0x10000
6666 && csky_insn.flag_force != INSN_OPCODE16F
6667 && !IS_CSKY_ARCH_801 (mach_flag))
6668 {
6669 csky_insn.inst = 0xe4001000 | (csky_insn.val[0] << 21);
6670 csky_insn.inst |= csky_insn.val[0] << 16;
6671 csky_insn.inst |= (csky_insn.val[1] - 1);
6672 csky_insn.isize = 4;
6673 }
6674 else
6675 {
6676 csky_show_error (ERROR_OPERANDS_ILLEGAL, 0,
6677 (char *)csky_insn.opcode_end, NULL);
6678 return false;
6679 }
6680 }
6681 else if (csky_insn.number == 3)
6682 {
6683 if (csky_insn.val[0] == 14
6684 && csky_insn.val[1] == 14
6685 && csky_insn.val[2] >= 0 && csky_insn.val[2] <= 0x1fc
6686 && (csky_insn.val[2] & 0x3) == 0
6687 && csky_insn.flag_force != INSN_OPCODE32F)
6688 {
6689 csky_insn.inst = 0x1420 | ((csky_insn.val[2] >> 2) & 0x1f);
6690 csky_insn.inst |= (csky_insn.val[2] << 1) & 0x300;
6691 }
6692
6693 else if (csky_insn.val[0] < 8
6694 && csky_insn.val[0] == csky_insn.val[1]
6695 && csky_insn.val[2] >= 1 && csky_insn.val[2] <= 0x100
6696 && csky_insn.flag_force != INSN_OPCODE32F)
6697 {
6698 csky_insn.inst = 0x2800 | (csky_insn.val[0] << 8);
6699 csky_insn.inst |= (csky_insn.val[2] - 1);
6700 }
6701 else if (csky_insn.val[0] < 8
6702 && csky_insn.val[1] < 8
6703 && csky_insn.val[2] >= 1 && csky_insn.val[2] <= 0x8
6704 && csky_insn.flag_force != INSN_OPCODE32F)
6705 {
6706 csky_insn.inst = 0x5803 | (csky_insn.val[0] << 5);
6707 csky_insn.inst |= csky_insn.val[1] << 8;
6708 csky_insn.inst |= (csky_insn.val[2] - 1) << 2;
6709 }
6710 else if (csky_insn.val[2] >= 1 && csky_insn.val[2] <= 0x1000
6711 && csky_insn.flag_force != INSN_OPCODE16F
6712 && !IS_CSKY_ARCH_801 (mach_flag))
6713 {
6714 csky_insn.inst = 0xe4001000 | (csky_insn.val[0] << 21);
6715 csky_insn.inst |= csky_insn.val[1] << 16;
6716 csky_insn.inst |= (csky_insn.val[2] - 1);
6717 csky_insn.isize = 4;
6718 }
6719 else
6720 {
6721 csky_show_error (ERROR_OPERANDS_ILLEGAL, 0,
6722 (char *)csky_insn.opcode_end, NULL);
6723 return false;
6724 }
6725 }
6726 csky_insn.output = frag_more (csky_insn.isize);
6727 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
6728
6729 return true;
6730 }
6731
6732 bool
6733 v2_work_add_sub (void)
6734 {
6735 if (csky_insn.number == 3
6736 && (csky_insn.val[0] == csky_insn.val[1]
6737 || csky_insn.val[0] == csky_insn.val[2])
6738 && csky_insn.val[0] <= 15
6739 && csky_insn.val[1] <= 15
6740 && csky_insn.val[2] <= 15)
6741 {
6742 if (!strstr (csky_insn.opcode->mnemonic, "sub")
6743 || csky_insn.val[0] == csky_insn.val[1])
6744 {
6745 csky_insn.opcode_idx = 0;
6746 csky_insn.isize = 2;
6747 if (csky_insn.val[0] == csky_insn.val[1])
6748 csky_insn.val[1] = csky_insn.val[2];
6749
6750 csky_insn.number = 2;
6751
6752 }
6753 }
6754 if (csky_insn.isize == 4
6755 && IS_CSKY_ARCH_801 (mach_flag))
6756 {
6757 if (csky_insn.number == 3)
6758 {
6759 if (csky_insn.val[0] > 7)
6760 {
6761 SET_ERROR_INTEGER (ERROR_REG_OVER_RANGE, csky_insn.val[0]);
6762 csky_show_error (ERROR_REG_OVER_RANGE, 1, NULL, NULL);
6763 }
6764 if (csky_insn.val[1] > 7)
6765 {
6766 SET_ERROR_INTEGER (ERROR_REG_OVER_RANGE, csky_insn.val[1]);
6767 csky_show_error (ERROR_REG_OVER_RANGE, 2, NULL, NULL);
6768 }
6769 if (csky_insn.val[2] > 7)
6770 {
6771 SET_ERROR_INTEGER (ERROR_REG_OVER_RANGE, csky_insn.val[2]);
6772 csky_show_error (ERROR_REG_OVER_RANGE, 3, NULL, NULL);
6773 }
6774 }
6775 else
6776 {
6777 if (csky_insn.val[0] > 15)
6778 {
6779 SET_ERROR_INTEGER (ERROR_REG_OVER_RANGE, csky_insn.val[0]);
6780 csky_show_error (ERROR_REG_OVER_RANGE, 1, NULL, NULL);
6781 }
6782 if (csky_insn.val[1] > 15)
6783 {
6784 SET_ERROR_INTEGER (ERROR_REG_OVER_RANGE, csky_insn.val[1]);
6785 csky_show_error (ERROR_REG_OVER_RANGE, 2, NULL, NULL);
6786 }
6787 }
6788 return false;
6789 }
6790 /* sub rz, rx. */
6791 /* Generate relax or reloc if necessary. */
6792 csky_generate_frags ();
6793 /* Generate the insn by mask. */
6794 csky_generate_insn ();
6795 /* Write inst to frag. */
6796 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
6797 return true;
6798 }
6799
6800 bool
6801 v2_work_rotlc (void)
6802 {
6803 const char *name = "addc";
6804 csky_insn.opcode
6805 = (struct csky_opcode *) str_hash_find (csky_opcodes_hash, name);
6806 csky_insn.opcode_idx = 0;
6807 if (csky_insn.isize == 2)
6808 {
6809 /* addc rz, rx. */
6810 csky_insn.number = 2;
6811 csky_insn.val[1] = csky_insn.val[0];
6812 }
6813 else
6814 {
6815 csky_insn.number = 3;
6816 /* addc rz, rx, ry. */
6817 csky_insn.val[1] = csky_insn.val[0];
6818 csky_insn.val[2] = csky_insn.val[0];
6819 }
6820 /* Generate relax or reloc if necessary. */
6821 csky_generate_frags ();
6822 /* Generate the insn by mask. */
6823 csky_generate_insn ();
6824 /* Write inst to frag. */
6825 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
6826 return true;
6827 }
6828
6829 bool
6830 v2_work_bgeni (void)
6831 {
6832 const char *name = NULL;
6833 int imm = csky_insn.val[1];
6834 int val = 1 << imm;
6835 if (imm < 16)
6836 name = "movi";
6837 else
6838 {
6839 name = "movih";
6840 val >>= 16;
6841 }
6842 csky_insn.opcode
6843 = (struct csky_opcode *) str_hash_find (csky_opcodes_hash, name);
6844 csky_insn.opcode_idx = 0;
6845 csky_insn.val[1] = val;
6846
6847 /* Generate relax or reloc if necessary. */
6848 csky_generate_frags ();
6849 /* Generate the insn by mask. */
6850 csky_generate_insn ();
6851 /* Write inst to frag. */
6852 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
6853 return true;
6854 }
6855
6856 bool
6857 v2_work_not (void)
6858 {
6859 const char *name = "nor";
6860 csky_insn.opcode
6861 = (struct csky_opcode *) str_hash_find (csky_opcodes_hash, name);
6862 csky_insn.opcode_idx = 0;
6863 if (csky_insn.number == 1)
6864 {
6865 csky_insn.val[1] = csky_insn.val[0];
6866 if (csky_insn.val[0] < 16)
6867 {
6868 /* 16 bits nor rz, rz. */
6869 csky_insn.number = 2;
6870 csky_insn.isize = 2;
6871 }
6872 else
6873 {
6874 csky_insn.val[2] = csky_insn.val[0];
6875 csky_insn.number = 3;
6876 csky_insn.isize = 4;
6877 }
6878 }
6879 if (csky_insn.number == 2)
6880 {
6881 if (csky_insn.val[0] == csky_insn.val[1]
6882 && csky_insn.val[0] < 16)
6883 {
6884 /* 16 bits nor rz, rz. */
6885 csky_insn.number = 2;
6886 csky_insn.isize = 2;
6887 }
6888 else
6889 {
6890 csky_insn.val[2] = csky_insn.val[1];
6891 csky_insn.number = 3;
6892 csky_insn.isize = 4;
6893 }
6894 }
6895
6896 /* Generate relax or reloc if necessary. */
6897 csky_generate_frags ();
6898 /* Generate the insn by mask. */
6899 csky_generate_insn ();
6900 /* Write inst to frag. */
6901 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
6902 return true;
6903 }
6904
6905 bool
6906 v2_work_jbtf (void)
6907 {
6908 if (csky_insn.e1.X_add_symbol == NULL || csky_insn.e1.X_op == O_constant)
6909 {
6910 csky_show_error (ERROR_UNDEFINE, 0, (void *)"operand is invalid", NULL);
6911 return false;
6912 }
6913
6914 if (IS_CSKY_ARCH_801 (mach_flag))
6915 {
6916 /* CK801 doesn't have 32-bit bt/bf insns or a jump insn with a
6917 range larger than SCOND_DISP16. Relax to a short jump around
6918 an unconditional branch, and give up if that overflows too. */
6919 csky_insn.output = frag_var (rs_machine_dependent,
6920 SCOND_DISP16_LEN,
6921 SCOND_DISP10_LEN,
6922 SCOND_DISP10,
6923 csky_insn.e1.X_add_symbol,
6924 csky_insn.e1.X_add_number,
6925 0);
6926 csky_insn.isize = 2;
6927 csky_insn.max = SCOND_DISP16_LEN;
6928 csky_insn.inst = csky_insn.opcode->op16[0].opcode;
6929 }
6930 else if (do_long_jump && !IS_CSKY_ARCH_802 (mach_flag))
6931 {
6932 /* Generate relax with jcondition.
6933 Note that CK802 doesn't support the JMPI instruction so
6934 we cannot relax to a jump with a 32-bit offset. */
6935 csky_insn.output = frag_var (rs_machine_dependent,
6936 JCOND_DISP32_LEN,
6937 JCOND_DISP10_LEN,
6938 JCOND_DISP10,
6939 csky_insn.e1.X_add_symbol,
6940 csky_insn.e1.X_add_number,
6941 0);
6942 csky_insn.isize = 2;
6943 csky_insn.max = JCOND_DISP32_LEN;
6944 csky_insn.inst = csky_insn.opcode->op16[0].opcode;
6945 }
6946 else
6947 {
6948 /* Generate relax with condition. */
6949 csky_insn.output = frag_var (rs_machine_dependent,
6950 COND_DISP16_LEN,
6951 COND_DISP10_LEN,
6952 COND_DISP10,
6953 csky_insn.e1.X_add_symbol,
6954 csky_insn.e1.X_add_number,
6955 0);
6956 csky_insn.isize = 2;
6957 csky_insn.max = COND_DISP16_LEN;
6958 csky_insn.inst = csky_insn.opcode->op16[0].opcode;
6959 }
6960 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
6961
6962 return true;
6963 }
6964
6965 bool
6966 v2_work_jbr (void)
6967 {
6968 if (csky_insn.e1.X_add_symbol == NULL || csky_insn.e1.X_op == O_constant)
6969 {
6970 csky_show_error (ERROR_UNDEFINE, 0, (void *)"operand is invalid", NULL);
6971 return false;
6972 }
6973
6974 if (do_long_jump
6975 && !IS_CSKY_ARCH_801 (mach_flag)
6976 && !IS_CSKY_ARCH_802 (mach_flag))
6977 {
6978 csky_insn.output = frag_var (rs_machine_dependent,
6979 JUNCD_DISP32_LEN,
6980 JUNCD_DISP10_LEN,
6981 JUNCD_DISP10,
6982 csky_insn.e1.X_add_symbol,
6983 csky_insn.e1.X_add_number,
6984 0);
6985
6986 csky_insn.inst = csky_insn.opcode->op16[0].opcode;
6987 csky_insn.max = JUNCD_DISP32_LEN;
6988 csky_insn.isize = 2;
6989 }
6990 else
6991 {
6992 /* Generate relax with condition. */
6993 csky_insn.output = frag_var (rs_machine_dependent,
6994 UNCD_DISP16_LEN,
6995 UNCD_DISP10_LEN,
6996 UNCD_DISP10,
6997 csky_insn.e1.X_add_symbol,
6998 csky_insn.e1.X_add_number,
6999 0);
7000 csky_insn.isize = 2;
7001 csky_insn.max = UNCD_DISP16_LEN;
7002 csky_insn.inst = csky_insn.opcode->op16[0].opcode;
7003
7004 }
7005 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
7006 return true;
7007 }
7008
7009 #define SIZE_V2_MOVI16(x) ((addressT)x <= 0xff)
7010 #define SIZE_V2_MOVI32(x) ((addressT)x <= 0xffff)
7011 #define SIZE_V2_MOVIH(x) ((addressT)x <= 0xffffffff && (((addressT)x & 0xffff) == 0))
7012
7013 bool
7014 v2_work_lrw (void)
7015 {
7016 int reg = csky_insn.val[0];
7017 int output_literal = csky_insn.val[1];
7018 int is_done = 0;
7019
7020 /* If the second operand is O_constant, We can use movi/movih
7021 instead of lrw. */
7022 if (csky_insn.e1.X_op == O_constant)
7023 {
7024 /* 801 only has movi16. */
7025 if (SIZE_V2_MOVI16 (csky_insn.e1.X_add_number) && reg < 8)
7026 {
7027 /* movi16 instead. */
7028 csky_insn.output = frag_more (2);
7029 csky_insn.inst = (CSKYV2_INST_MOVI16 | (reg << 8)
7030 | (csky_insn.e1.X_add_number));
7031 csky_insn.isize = 2;
7032 is_done = 1;
7033 }
7034 else if (SIZE_V2_MOVI32 (csky_insn.e1.X_add_number)
7035 && !IS_CSKY_ARCH_801 (mach_flag))
7036 {
7037 /* movi32 instead. */
7038 csky_insn.output = frag_more (4);
7039 csky_insn.inst = (CSKYV2_INST_MOVI32 | (reg << 16)
7040 | (csky_insn.e1.X_add_number));
7041 csky_insn.isize = 4;
7042 is_done = 1;
7043 }
7044 else if (SIZE_V2_MOVIH (csky_insn.e1.X_add_number)
7045 && !IS_CSKY_ARCH_801 (mach_flag))
7046 {
7047 /* movih instead. */
7048 csky_insn.output = frag_more (4);
7049 csky_insn.inst = (CSKYV2_INST_MOVIH | (reg << 16)
7050 | ((csky_insn.e1.X_add_number >> 16) & 0xffff));
7051 csky_insn.isize = 4;
7052 is_done = 1;
7053 }
7054 }
7055
7056 if (is_done)
7057 {
7058 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
7059 return true;
7060 }
7061
7062 if (output_literal)
7063 {
7064 struct literal *p = enter_literal (&csky_insn.e1, 0, 0, 0);
7065 /* Create a reference to pool entry. */
7066 csky_insn.e1.X_op = O_symbol;
7067 csky_insn.e1.X_add_symbol = poolsym;
7068 csky_insn.e1.X_add_number = p->offset << 2;
7069 }
7070 /* If 16bit force. */
7071 if (csky_insn.flag_force == INSN_OPCODE16F)
7072 {
7073 /* Generate fixup. */
7074 if (reg > 7)
7075 {
7076 csky_show_error (ERROR_UNDEFINE, 0,
7077 (void *)"The register is out of range.", NULL);
7078 return false;
7079 }
7080 csky_insn.isize = 2;
7081 csky_insn.output = frag_more (2);
7082
7083 if (insn_reloc == BFD_RELOC_CKCORE_TLS_GD32
7084 || insn_reloc == BFD_RELOC_CKCORE_TLS_LDM32
7085 || insn_reloc == BFD_RELOC_CKCORE_TLS_IE32)
7086 {
7087 literal_insn_offset->tls_addend.frag = frag_now;
7088 literal_insn_offset->tls_addend.offset
7089 = csky_insn.output - frag_now->fr_literal;
7090 }
7091 csky_insn.inst = csky_insn.opcode->op16[0].opcode | (reg << 5);
7092 csky_insn.max = 4;
7093 fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
7094 2, &csky_insn.e1, 1, BFD_RELOC_CKCORE_PCREL_IMM7BY4);
7095 }
7096 else if (csky_insn.flag_force == INSN_OPCODE32F)
7097 {
7098 csky_insn.isize = 4;
7099 csky_insn.output = frag_more (4);
7100 if (insn_reloc == BFD_RELOC_CKCORE_TLS_GD32
7101 || insn_reloc == BFD_RELOC_CKCORE_TLS_LDM32
7102 || insn_reloc == BFD_RELOC_CKCORE_TLS_IE32)
7103 {
7104 literal_insn_offset->tls_addend.frag = frag_now;
7105 literal_insn_offset->tls_addend.offset
7106 = csky_insn.output - frag_now->fr_literal;
7107 }
7108 csky_insn.inst = csky_insn.opcode->op32[0].opcode | (reg << 16);
7109 fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
7110 4, &csky_insn.e1, 1, BFD_RELOC_CKCORE_PCREL_IMM16BY4);
7111 }
7112 else if (!is_done)
7113 {
7114 if (reg < 8)
7115 {
7116 csky_insn.isize = 2;
7117
7118 if (insn_reloc == BFD_RELOC_CKCORE_TLS_GD32
7119 || insn_reloc == BFD_RELOC_CKCORE_TLS_LDM32
7120 || insn_reloc == BFD_RELOC_CKCORE_TLS_IE32)
7121 literal_insn_offset->tls_addend.frag = frag_now;
7122
7123 csky_insn.output = frag_var (rs_machine_dependent,
7124 LRW_DISP16_LEN,
7125 LRW_DISP7_LEN,
7126 (do_extend_lrw
7127 ? LRW2_DISP8 : LRW_DISP7),
7128 csky_insn.e1.X_add_symbol,
7129 csky_insn.e1.X_add_number, 0);
7130 if (insn_reloc == BFD_RELOC_CKCORE_TLS_GD32
7131 || insn_reloc == BFD_RELOC_CKCORE_TLS_LDM32
7132 || insn_reloc == BFD_RELOC_CKCORE_TLS_IE32)
7133 {
7134 if (literal_insn_offset->tls_addend.frag->fr_next != frag_now)
7135 literal_insn_offset->tls_addend.frag
7136 = literal_insn_offset->tls_addend.frag->fr_next;
7137 literal_insn_offset->tls_addend.offset
7138 = (csky_insn.output
7139 - literal_insn_offset->tls_addend.frag->fr_literal);
7140 }
7141 csky_insn.inst = csky_insn.opcode->op16[0].opcode | (reg << 5);
7142 csky_insn.max = LRW_DISP16_LEN;
7143 csky_insn.isize = 2;
7144 }
7145 else
7146 {
7147 csky_insn.isize = 4;
7148 csky_insn.output = frag_more (4);
7149 if (insn_reloc == BFD_RELOC_CKCORE_TLS_GD32
7150 || insn_reloc == BFD_RELOC_CKCORE_TLS_LDM32
7151 || insn_reloc == BFD_RELOC_CKCORE_TLS_IE32)
7152 {
7153 literal_insn_offset->tls_addend.frag = frag_now;
7154 literal_insn_offset->tls_addend.offset
7155 = csky_insn.output - frag_now->fr_literal;
7156 }
7157 csky_insn.inst = csky_insn.opcode->op32[0].opcode | (reg << 16);
7158 fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
7159 4, &csky_insn.e1, 1, BFD_RELOC_CKCORE_PCREL_IMM16BY4);
7160 }
7161 }
7162
7163 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
7164 return true;
7165 }
7166
7167 bool
7168 v2_work_lrsrsw (void)
7169 {
7170 int reg = csky_insn.val[0];
7171 csky_insn.output = frag_more (4);
7172 csky_insn.inst = csky_insn.opcode->op32[0].opcode | (reg << 21);
7173 csky_insn.isize = 4;
7174
7175 switch (insn_reloc)
7176 {
7177 case BFD_RELOC_CKCORE_GOT32:
7178 fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
7179 4, &csky_insn.e1, 0, BFD_RELOC_CKCORE_GOT_IMM18BY4);
7180 break;
7181 case BFD_RELOC_CKCORE_PLT32:
7182 fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
7183 4, &csky_insn.e1, 0, BFD_RELOC_CKCORE_PLT_IMM18BY4);
7184 break;
7185 default:
7186 fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
7187 4, &csky_insn.e1, 1, BFD_RELOC_CKCORE_DOFFSET_IMM18BY4);
7188 break;
7189 }
7190 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
7191 return true;
7192 }
7193
7194 bool
7195 v2_work_jbsr (void)
7196 {
7197 if (do_force2bsr
7198 || IS_CSKY_ARCH_801 (mach_flag)
7199 || IS_CSKY_ARCH_802 (mach_flag))
7200 {
7201 csky_insn.output = frag_more (4);
7202 fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
7203 4, &csky_insn.e1, 1, BFD_RELOC_CKCORE_PCREL_IMM26BY2);
7204 csky_insn.isize = 4;
7205 csky_insn.inst = CSKYV2_INST_BSR32;
7206 }
7207 else
7208 {
7209 struct literal *p = enter_literal (&csky_insn.e1, 0, 0, 0);
7210 csky_insn.output = frag_more (4);
7211 csky_insn.e1.X_op = O_symbol;
7212 csky_insn.e1.X_add_symbol = poolsym;
7213 csky_insn.e1.X_add_number = p->offset << 2;
7214 fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
7215 4, &csky_insn.e1, 1, BFD_RELOC_CKCORE_PCREL_IMM16BY4);
7216 if (do_jsri2bsr || IS_CSKY_ARCH_810 (mach_flag))
7217 fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
7218 4,
7219 &(litpool + (csky_insn.e1.X_add_number >> 2))->e,
7220 1,
7221 BFD_RELOC_CKCORE_PCREL_JSR_IMM26BY2);
7222 csky_insn.inst = CSKYV2_INST_JSRI32;
7223 csky_insn.isize = 4;
7224 if (IS_CSKY_ARCH_810 (mach_flag))
7225 {
7226 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
7227 csky_insn.output = frag_more (4);
7228 dwarf2_emit_insn (0);
7229 /* Insert "mov r0, r0". */
7230 csky_insn.inst = CSKYV2_INST_MOV_R0_R0;
7231 csky_insn.max = 8;
7232 }
7233 }
7234 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
7235
7236 return true;
7237 }
7238
7239 bool
7240 v2_work_jsri (void)
7241 {
7242 /* dump literal. */
7243 struct literal *p = enter_literal (&csky_insn.e1, 1, 0, 0);
7244 csky_insn.e1.X_op = O_symbol;
7245 csky_insn.e1.X_add_symbol = poolsym;
7246 csky_insn.e1.X_add_number = p->offset << 2;
7247
7248 /* Generate relax or reloc if necessary. */
7249 csky_generate_frags ();
7250 /* Generate the insn by mask. */
7251 csky_generate_insn ();
7252 /* Write inst to frag. */
7253 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
7254 /* Control 810 not to generate jsri. */
7255 if (IS_CSKY_ARCH_810 (mach_flag))
7256 {
7257 /* Look at adding the R_PCREL_JSRIMM26BY2.
7258 For 'jbsr .L1', this reloc type's symbol
7259 is bound to '.L1', isn't bound to literal pool. */
7260 fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
7261 4, &p->e, 1,
7262 BFD_RELOC_CKCORE_PCREL_JSR_IMM26BY2);
7263 csky_insn.output = frag_more (4);
7264 dwarf2_emit_insn (0);
7265 /* The opcode of "mov32 r0,r0". */
7266 csky_insn.inst = CSKYV2_INST_MOV_R0_R0;
7267 /* The effect of this value is to check literal. */
7268 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
7269 csky_insn.max = 8;
7270 }
7271 return true;
7272 }
7273
7274 bool
7275 v2_work_movih (void)
7276 {
7277 int rz = csky_insn.val[0];
7278 csky_insn.output = frag_more (4);
7279 csky_insn.inst = csky_insn.opcode->op32[0].opcode | (rz << 16);
7280 if (csky_insn.e1.X_op == O_constant)
7281 {
7282 if (csky_insn.e1.X_unsigned == 1 && csky_insn.e1.X_add_number > 0xffff)
7283 {
7284 csky_show_error (ERROR_IMM_OVERFLOW, 2, NULL, NULL);
7285 return false;
7286 }
7287 else if (csky_insn.e1.X_unsigned == 0 && csky_insn.e1.X_add_number < 0)
7288 {
7289 csky_show_error (ERROR_IMM_OVERFLOW, 2, NULL, NULL);
7290 return false;
7291 }
7292 else
7293 csky_insn.inst |= (csky_insn.e1.X_add_number & 0xffff);
7294 }
7295 else if (csky_insn.e1.X_op == O_right_shift
7296 || (csky_insn.e1.X_op == O_symbol && insn_reloc != BFD_RELOC_NONE))
7297 {
7298 if (csky_insn.e1.X_op_symbol != 0
7299 && symbol_constant_p (csky_insn.e1.X_op_symbol)
7300 && S_GET_SEGMENT (csky_insn.e1.X_op_symbol) == absolute_section
7301 && 16 == S_GET_VALUE (csky_insn.e1.X_op_symbol))
7302 {
7303 csky_insn.e1.X_op = O_symbol;
7304 if (insn_reloc == BFD_RELOC_CKCORE_GOT32)
7305 insn_reloc = BFD_RELOC_CKCORE_GOT_HI16;
7306 else if (insn_reloc == BFD_RELOC_CKCORE_PLT32)
7307 insn_reloc = BFD_RELOC_CKCORE_PLT_HI16;
7308 else if (insn_reloc == BFD_RELOC_CKCORE_GOTPC)
7309 insn_reloc = BFD_RELOC_CKCORE_GOTPC_HI16;
7310 else if (insn_reloc == BFD_RELOC_CKCORE_GOTOFF)
7311 insn_reloc = BFD_RELOC_CKCORE_GOTOFF_HI16;
7312 else
7313 insn_reloc = BFD_RELOC_CKCORE_ADDR_HI16;
7314 fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
7315 4, &csky_insn.e1, 0, insn_reloc);
7316 }
7317 else
7318 {
7319 void *arg = (void *)"the second operand must be \"SYMBOL >> 16\"";
7320 csky_show_error (ERROR_UNDEFINE, 0, arg, NULL);
7321 return false;
7322 }
7323 }
7324 csky_insn.isize = 4;
7325 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
7326
7327 return true;
7328 }
7329
7330 bool
7331 v2_work_ori (void)
7332 {
7333 int rz = csky_insn.val[0];
7334 int rx = csky_insn.val[1];
7335 csky_insn.output = frag_more (4);
7336 csky_insn.inst = csky_insn.opcode->op32[0].opcode | (rz << 21) | (rx << 16);
7337 if (csky_insn.e1.X_op == O_constant)
7338 {
7339 if (csky_insn.e1.X_add_number <= 0xffff
7340 && csky_insn.e1.X_add_number >= 0)
7341 csky_insn.inst |= csky_insn.e1.X_add_number;
7342 else
7343 {
7344 csky_show_error (ERROR_IMM_OVERFLOW, 3, NULL, NULL);
7345 return false;
7346 }
7347 }
7348 else if (csky_insn.e1.X_op == O_bit_and)
7349 {
7350 if (symbol_constant_p (csky_insn.e1.X_op_symbol)
7351 && S_GET_SEGMENT (csky_insn.e1.X_op_symbol) == absolute_section
7352 && 0xffff == S_GET_VALUE (csky_insn.e1.X_op_symbol))
7353 {
7354 csky_insn.e1.X_op = O_symbol;
7355 if (insn_reloc == BFD_RELOC_CKCORE_GOT32)
7356 insn_reloc = BFD_RELOC_CKCORE_GOT_LO16;
7357 else if (insn_reloc == BFD_RELOC_CKCORE_PLT32)
7358 insn_reloc = BFD_RELOC_CKCORE_PLT_LO16;
7359 else if (insn_reloc == BFD_RELOC_CKCORE_GOTPC)
7360 insn_reloc = BFD_RELOC_CKCORE_GOTPC_LO16;
7361 else if (insn_reloc == BFD_RELOC_CKCORE_GOTOFF)
7362 insn_reloc = BFD_RELOC_CKCORE_GOTOFF_LO16;
7363 else
7364 insn_reloc = BFD_RELOC_CKCORE_ADDR_LO16;
7365 fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
7366 4, &csky_insn.e1, 0, insn_reloc);
7367 }
7368 else
7369 {
7370 void *arg = (void *)"the third operand must be \"SYMBOL & 0xffff\"";
7371 csky_show_error (ERROR_UNDEFINE, 0, arg, NULL);
7372 return false;
7373 }
7374 }
7375 csky_insn.isize = 4;
7376 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
7377 return true;
7378 }
7379
7380 /* Helper function to encode a single/double floating point constant
7381 into the instruction word for fmovis and fmovid instructions.
7382 The constant is in its IEEE single/double precision representation
7383 and is repacked into the internal 13-bit representation for these
7384 instructions with a diagnostic for overflow. Note that there is no
7385 rounding when converting to the smaller format, just an error if there
7386 is excess precision or the number is too small/large to be represented. */
7387
7388 bool
7389 float_work_fmovi (void)
7390 {
7391 int rx = csky_insn.val[0];
7392
7393 /* We already converted the float constant to the internal 13-bit
7394 representation so we just need to OR it in here. */
7395 csky_insn.inst = csky_insn.opcode->op32[0].opcode | rx;
7396 csky_insn.inst |= (uint32_t) csky_insn.e1.X_add_number;
7397
7398 csky_insn.output = frag_more (4);
7399 csky_insn.isize = 4;
7400 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
7401 return true;
7402 }
7403
7404 /* Like float_work_fmovi, but for FPUV3 fmovi.16, fmovi.32 and fmovi.64
7405 instructions. */
7406
7407 bool
7408 float_work_fpuv3_fmovi (void)
7409 {
7410 int rx = csky_insn.val[0];
7411 int idx = csky_insn.opcode_idx;
7412 int imm4 = 0;
7413 int imm8 = 0;
7414 int sign = 0;
7415
7416 csky_insn.inst = csky_insn.opcode->op32[idx].opcode | rx;
7417
7418 if (csky_insn.opcode->op32[idx].operand_num == 3)
7419 {
7420 /* fmovi.xx frz, imm9, imm4. */
7421 imm8 = csky_insn.val[1];
7422 imm4 = csky_insn.val[2];
7423 if (imm8 < 0 || (imm8 & 0x80000000))
7424 {
7425 sign = (1 << 5);
7426 imm8 = 0 - imm8;
7427 }
7428
7429 if (imm8 > 255)
7430 {
7431 csky_show_error (ERROR_IMM_OVERFLOW, 2, NULL, NULL);
7432 return false;
7433 }
7434
7435 /* imm8 store at bit [25:20] and [9:8]. */
7436 /* imm4 store at bit [19:16]. */
7437 /* sign store at bit [5]. */
7438 csky_insn.inst = csky_insn.inst
7439 | ((imm8 & 0x3) << 8)
7440 | ((imm8 & 0xfc) << 18)
7441 | ((imm4 & 0xf) << 16)
7442 | sign;
7443 }
7444 else
7445 {
7446 csky_insn.inst |= (uint32_t) csky_insn.e1.X_add_number;
7447 }
7448
7449 csky_insn.output = frag_more(4);
7450 csky_insn.isize = 4;
7451 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
7452 return true;
7453 }
7454
7455 bool
7456 dsp_work_bloop (void)
7457 {
7458 int reg = csky_insn.val[0];
7459 csky_insn.output = frag_more (4);
7460 csky_insn.inst = csky_insn.opcode->op32[0].opcode | (reg << 16);
7461 csky_insn.isize = 4;
7462
7463 if (csky_insn.number == 3
7464 && csky_insn.e1.X_op == O_symbol
7465 && csky_insn.e2.X_op == O_symbol)
7466 {
7467 fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
7468 4, &csky_insn.e1, 1,
7469 BFD_RELOC_CKCORE_PCREL_BLOOP_IMM12BY4);
7470 fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
7471 4, &csky_insn.e2, 1,
7472 BFD_RELOC_CKCORE_PCREL_BLOOP_IMM4BY4);
7473 }
7474 else if (csky_insn.number == 2
7475 && csky_insn.e1.X_op == O_symbol)
7476 {
7477 fix_new_exp (frag_now, csky_insn.output-frag_now->fr_literal,
7478 4, &csky_insn.e1, 1,
7479 BFD_RELOC_CKCORE_PCREL_BLOOP_IMM12BY4);
7480 if (csky_insn.last_isize == 2)
7481 csky_insn.inst |= (0xf << 12);
7482 else if (csky_insn.last_isize != 0)
7483 csky_insn.inst |= (0xe << 12);
7484 else
7485 {
7486 void *arg = (void *)"bloop can not be the first instruction"\
7487 "when the end label is not specified.\n";
7488 csky_show_error (ERROR_UNDEFINE, 0, arg, NULL);
7489 }
7490 }
7491
7492 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
7493 return true;
7494 }
7495
7496 bool
7497 float_work_fpuv3_fstore(void)
7498 {
7499 /* Generate relax or reloc if necessary. */
7500 csky_generate_frags ();
7501 /* Generate the insn by mask. */
7502 csky_generate_insn ();
7503 /* Write inst to frag. */
7504 csky_write_insn (csky_insn.output,
7505 csky_insn.inst,
7506 csky_insn.isize);
7507
7508
7509 return true;
7510 }
7511
7512 bool
7513 v2_work_addc (void)
7514 {
7515 int reg1;
7516 int reg2;
7517 int reg3 = 0;
7518 int is_16_bit = 0;
7519
7520 reg1 = csky_insn.val[0];
7521 reg2 = csky_insn.val[1];
7522 if (csky_insn.number == 2)
7523 {
7524 if (reg1 > 15 || reg2 > 15)
7525 {
7526 is_16_bit = 0;
7527 reg3 = reg1;
7528 }
7529 else
7530 is_16_bit = 1;
7531 }
7532 else
7533 {
7534 reg3 = csky_insn.val[2];
7535 if (reg1 > 15 || reg2 > 15 || reg3 > 15)
7536 is_16_bit = 0;
7537 else if (reg1 == reg2 || reg1 == reg3)
7538 {
7539 is_16_bit = 1;
7540 reg2 = (reg1 == reg2) ? reg3 : reg2;
7541 }
7542 else
7543 is_16_bit = 0;
7544 }
7545
7546 if (is_16_bit
7547 && csky_insn.flag_force != INSN_OPCODE32F)
7548 {
7549 csky_insn.isize = 2;
7550 csky_insn.inst = csky_insn.opcode->op16[0].opcode
7551 | (reg1 << 6) | (reg2 << 2);
7552 }
7553 else if (csky_insn.flag_force != INSN_OPCODE16F)
7554 {
7555 csky_insn.isize = 4;
7556 csky_insn.inst = csky_insn.opcode->op32[0].opcode
7557 | (reg1 << 0) | (reg2 << 16) | (reg3 << 21);
7558 }
7559 else
7560 {
7561 SET_ERROR_INTEGER (ERROR_REG_OVER_RANGE, reg1 > 15 ? reg1 : reg2);
7562 csky_show_error (ERROR_REG_OVER_RANGE, 0, 0, NULL);
7563 }
7564
7565 /* Generate relax or reloc if necessary. */
7566 csky_generate_frags ();
7567 /* Write inst to frag. */
7568 csky_write_insn (csky_insn.output,
7569 csky_insn.inst,
7570 csky_insn.isize);
7571
7572 return true;
7573 }
7574
7575 /* The following are for assembler directive handling. */
7576
7577 /* Helper function to adjust constant pool counts when we emit a
7578 data directive in the text section. FUNC is one of the standard
7579 gas functions to handle these directives, like "stringer" for the
7580 .string directive, and ARG is the argument to FUNC. csky_pool_count
7581 essentially wraps the call with the constant pool magic. */
7582
7583 static void
7584 csky_pool_count (void (*func) (int), int arg)
7585 {
7586 const fragS *curr_frag = frag_now;
7587 offsetT added = -frag_now_fix_octets ();
7588
7589 (*func) (arg);
7590
7591 while (curr_frag != frag_now)
7592 {
7593 added += curr_frag->fr_fix;
7594 curr_frag = curr_frag->fr_next;
7595 }
7596
7597 added += frag_now_fix_octets ();
7598 poolspan += added;
7599 }
7600
7601 /* Support the .literals directive. */
7602 static void
7603 csky_s_literals (int ignore ATTRIBUTE_UNUSED)
7604 {
7605 dump_literals (0);
7606 demand_empty_rest_of_line ();
7607 }
7608
7609 /* Support the .string, etc directives. */
7610 static void
7611 csky_stringer (int append_zero)
7612 {
7613 if (now_seg == text_section)
7614 csky_pool_count (stringer, append_zero);
7615 else
7616 stringer (append_zero);
7617
7618 /* We call check_literals here in case a large number of strings are
7619 being placed into the text section with a sequence of stringer
7620 directives. In theory we could be upsetting something if these
7621 strings are actually in an indexed table instead of referenced by
7622 individual labels. Let us hope that that never happens. */
7623 check_literals (2, 0);
7624 }
7625
7626 /* Support integer-mode constructors like .word, .byte, etc. */
7627
7628 static void
7629 csky_cons (int nbytes)
7630 {
7631 mapping_state (MAP_DATA);
7632 if (nbytes == 4) /* @GOT. */
7633 {
7634 do
7635 {
7636 bfd_reloc_code_real_type reloc;
7637 expressionS exp;
7638
7639 reloc = BFD_RELOC_NONE;
7640 expression (&exp);
7641 lex_got (&reloc, NULL);
7642
7643 if (exp.X_op == O_symbol && reloc != BFD_RELOC_NONE)
7644 {
7645 reloc_howto_type *howto
7646 = bfd_reloc_type_lookup (stdoutput, reloc);
7647 int size = bfd_get_reloc_size (howto);
7648
7649 if (size > nbytes)
7650 as_bad (ngettext ("%s relocations do not fit in %d byte",
7651 "%s relocations do not fit in %d bytes",
7652 nbytes),
7653 howto->name, nbytes);
7654 else
7655 {
7656 register char *p = frag_more ((int) nbytes);
7657 int offset = nbytes - size;
7658
7659 fix_new_exp (frag_now,
7660 p - frag_now->fr_literal + offset,
7661 size, &exp, 0, reloc);
7662 }
7663 }
7664 else
7665 emit_expr (&exp, (unsigned int) nbytes);
7666 if (now_seg == text_section)
7667 poolspan += nbytes;
7668 }
7669 while (*input_line_pointer++ == ',');
7670
7671 /* Put terminator back into stream. */
7672 input_line_pointer --;
7673 demand_empty_rest_of_line ();
7674
7675 return;
7676 }
7677
7678 if (now_seg == text_section)
7679 csky_pool_count (cons, nbytes);
7680 else
7681 cons (nbytes);
7682
7683 /* In theory we ought to call check_literals (2,0) here in case
7684 we need to dump the literal table. We cannot do this however,
7685 as the directives that we are intercepting may be being used
7686 to build a switch table, and we must not interfere with its
7687 contents. Instead we cross our fingers and pray... */
7688 }
7689
7690 /* Support floating-mode constant directives like .float and .double. */
7691
7692 static void
7693 csky_float_cons (int float_type)
7694 {
7695 mapping_state (MAP_DATA);
7696 if (now_seg == text_section)
7697 csky_pool_count (float_cons, float_type);
7698 else
7699 float_cons (float_type);
7700
7701 /* See the comment in csky_cons () about calling check_literals.
7702 It is unlikely that a switch table will be constructed using
7703 floating point values, but it is still likely that an indexed
7704 table of floating point constants is being created by these
7705 directives, so again we must not interfere with their placement. */
7706 }
7707
7708 /* Support the .fill directive. */
7709
7710 static void
7711 csky_fill (int ignore)
7712 {
7713 if (now_seg == text_section)
7714 csky_pool_count (s_fill, ignore);
7715 else
7716 s_fill (ignore);
7717
7718 check_literals (2, 0);
7719 }
7720
7721 /* Handle the section changing pseudo-ops. These call through to the
7722 normal implementations, but they dump the literal pool first. */
7723
7724 static void
7725 csky_s_text (int ignore)
7726 {
7727 dump_literals (0);
7728
7729 #ifdef OBJ_ELF
7730 obj_elf_text (ignore);
7731 #else
7732 s_text (ignore);
7733 #endif
7734 }
7735
7736 static void
7737 csky_s_data (int ignore)
7738 {
7739 dump_literals (0);
7740
7741 #ifdef OBJ_ELF
7742 obj_elf_data (ignore);
7743 #else
7744 s_data (ignore);
7745 #endif
7746 }
7747
7748 static void
7749 csky_s_section (int ignore)
7750 {
7751 /* Scan forwards to find the name of the section. If the section
7752 being switched to is ".line" then this is a DWARF1 debug section
7753 which is arbitrarily placed inside generated code. In this case
7754 do not dump the literal pool because it is a) inefficient and
7755 b) would require the generation of extra code to jump around the
7756 pool. */
7757 char * ilp = input_line_pointer;
7758
7759 while (*ilp != 0 && ISSPACE (*ilp))
7760 ++ ilp;
7761
7762 if (startswith (ilp, ".line")
7763 && (ISSPACE (ilp[5]) || *ilp == '\n' || *ilp == '\r'))
7764 ;
7765 else
7766 dump_literals (0);
7767
7768 #ifdef OBJ_ELF
7769 obj_elf_section (ignore);
7770 #endif
7771 #ifdef OBJ_COFF
7772 obj_coff_section (ignore);
7773 #endif
7774 }
7775
7776 static void
7777 csky_s_bss (int needs_align)
7778 {
7779 dump_literals (0);
7780 s_lcomm_bytes (needs_align);
7781 }
7782
7783 #ifdef OBJ_ELF
7784 static void
7785 csky_s_comm (int needs_align)
7786 {
7787 dump_literals (0);
7788 obj_elf_common (needs_align);
7789 }
7790 #endif
7791
7792 /* Handle the .no_literal_dump directive. */
7793
7794 static void
7795 csky_noliteraldump (int ignore ATTRIBUTE_UNUSED)
7796 {
7797 do_noliteraldump = 1;
7798 int insn_num = get_absolute_expression ();
7799 /* The insn after '.no_literal_dump insn_num' is insn1,
7800 Don't dump literal pool between insn1 and insn(insn_num+1)
7801 The insn cannot be the insn generate literal, like lrw & jsri. */
7802 check_literals (0, insn_num * 2);
7803 }
7804
7805 /* Handle the .align directive.
7806 We must check literals before doing alignment. For example, if
7807 '.align n', add (2^n-1) to poolspan and check literals. */
7808
7809 static void
7810 csky_s_align_ptwo (int arg)
7811 {
7812 /* Get the .align's first absolute number. */
7813 char * temp_pointer = input_line_pointer;
7814 int align = get_absolute_expression ();
7815 check_literals (0, (1 << align) - 1);
7816 input_line_pointer = temp_pointer;
7817
7818 /* Do alignment. */
7819 s_align_ptwo (arg);
7820 }
7821
7822 /* Handle the .stack_size directive. */
7823
7824 static void
7825 csky_stack_size (int arg ATTRIBUTE_UNUSED)
7826 {
7827 expressionS exp;
7828 stack_size_entry *sse
7829 = (stack_size_entry *) xcalloc (1, sizeof (stack_size_entry));
7830
7831 expression (&exp);
7832 if (exp.X_op == O_symbol)
7833 sse->function = exp.X_add_symbol;
7834 else
7835 {
7836 as_bad (_("the first operand must be a symbol"));
7837 ignore_rest_of_line ();
7838 free (sse);
7839 return;
7840 }
7841
7842 SKIP_WHITESPACE ();
7843 if (*input_line_pointer != ',')
7844 {
7845 as_bad (_("missing stack size"));
7846 ignore_rest_of_line ();
7847 free (sse);
7848 return;
7849 }
7850
7851 ++input_line_pointer;
7852 expression (&exp);
7853 if (exp.X_op == O_constant)
7854 {
7855 if (exp.X_add_number < 0 || exp.X_add_number > (offsetT)0xffffffff)
7856 {
7857
7858 as_bad (_("value not in range [0, 0xffffffff]"));
7859 ignore_rest_of_line ();
7860 free (sse);
7861 return;
7862 }
7863 else
7864 sse->stack_size = exp.X_add_number;
7865 }
7866 else
7867 {
7868 as_bad (_("operand must be a constant"));
7869 ignore_rest_of_line ();
7870 free (sse);
7871 return;
7872 }
7873
7874 if (*last_stack_size_data != NULL)
7875 last_stack_size_data = &((*last_stack_size_data)->next);
7876
7877 *last_stack_size_data = sse;
7878 }
7879
7880 /* This table describes all the machine specific pseudo-ops the assembler
7881 has to support. The fields are:
7882 pseudo-op name without dot
7883 function to call to execute this pseudo-op
7884 Integer arg to pass to the function. */
7885
7886 const pseudo_typeS md_pseudo_table[] =
7887 {
7888 { "export", s_globl, 0 },
7889 { "import", s_ignore, 0 },
7890 { "literals", csky_s_literals, 0 },
7891 { "page", listing_eject, 0 },
7892
7893 /* The following are to intercept the placement of data into the text
7894 section (eg addresses for a switch table), so that the space they
7895 occupy can be taken into account when deciding whether or not to
7896 dump the current literal pool.
7897 XXX - currently we do not cope with the .space and .dcb.d directives. */
7898 { "ascii", csky_stringer, 8 + 0 },
7899 { "asciz", csky_stringer, 8 + 1 },
7900 { "byte", csky_cons, 1 },
7901 { "dc", csky_cons, 2 },
7902 { "dc.b", csky_cons, 1 },
7903 { "dc.d", csky_float_cons, 'd'},
7904 { "dc.l", csky_cons, 4 },
7905 { "dc.s", csky_float_cons, 'f'},
7906 { "dc.w", csky_cons, 2 },
7907 { "dc.x", csky_float_cons, 'x'},
7908 { "double", csky_float_cons, 'd'},
7909 { "float", csky_float_cons, 'f'},
7910 { "hword", csky_cons, 2 },
7911 { "int", csky_cons, 4 },
7912 { "long", csky_cons, 4 },
7913 { "octa", csky_cons, 16 },
7914 { "quad", csky_cons, 8 },
7915 { "short", csky_cons, 2 },
7916 { "single", csky_float_cons, 'f'},
7917 { "string", csky_stringer, 8 + 1 },
7918 { "word", csky_cons, 4 },
7919 { "fill", csky_fill, 0 },
7920
7921 /* Allow for the effect of section changes. */
7922 { "text", csky_s_text, 0 },
7923 { "data", csky_s_data, 0 },
7924 { "bss", csky_s_bss, 1 },
7925 #ifdef OBJ_ELF
7926 { "comm", csky_s_comm, 0 },
7927 #endif
7928 { "section", csky_s_section, 0 },
7929 { "section.s", csky_s_section, 0 },
7930 { "sect", csky_s_section, 0 },
7931 { "sect.s", csky_s_section, 0 },
7932 /* When ".no_literal_dump N" is in front of insn1,
7933 and instruction sequence is:
7934 insn1
7935 insn2
7936 ......
7937 insnN+1
7938 it means literals will not dump between insn1 and insnN+1
7939 The insn cannot itself generate literal, like lrw & jsri. */
7940 { "no_literal_dump", csky_noliteraldump, 0 },
7941 { "align", csky_s_align_ptwo, 0 },
7942 { "stack_size", csky_stack_size, 0 },
7943 {0, 0, 0}
7944 };
7945
7946 /* Implement tc_cfi_frame_initial_instructions. */
7947
7948 void
7949 csky_cfi_frame_initial_instructions (void)
7950 {
7951 int sp_reg = IS_CSKY_V1 (mach_flag) ? 0 : 14;
7952 cfi_add_CFA_def_cfa_register (sp_reg);
7953 }
7954
7955 /* Implement tc_regname_to_dw2regnum. */
7956
7957 int
7958 tc_csky_regname_to_dw2regnum (char *regname)
7959 {
7960 int reg_num = -1;
7961 int len;
7962
7963 /* FIXME the reg should be parsed according to
7964 the abi version. */
7965 reg_num = csky_get_reg_val (regname, &len);
7966 return reg_num;
7967 }