1 /* tc-csky.c -- Assembler for C-SKY
2 Copyright (C) 1989-2020 Free Software Foundation, Inc.
3 Created by Lifang Xia (lifang_xia@c-sky.com)
4 Contributed by C-SKY Microsystems and Mentor Graphics.
6 This file is part of GAS, the GNU Assembler.
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)
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.
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
28 #include "safe-ctype.h"
31 #include "libiberty.h"
35 #include "dw2gencfi.h"
38 #include "dwarf2dbg.h"
42 #define OPCODE_MAX_LEN 20
43 #define HAS_SUB_OPERAND 0xfffffffful
45 /* This value is just for lrw to distinguish "[]" label. */
46 #define NEED_OUTPUT_LITERAL 1
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)
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. */
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)
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)
74 /* For lrw16, 112 average size for a function. */
75 #define v2_SPANEXIT (512 - 112)
77 /* For lrw16 (3+7, 512 bytes). */
78 #define v2_SPANCLOSE_ELRW (1016 - 24)
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"
86 /* Used in v1_relax_table. */
87 /* These are the two types of relaxable instruction. */
90 #define COND_JUMP_PIC 3
91 #define UNCD_JUMP_PIC 4
96 #define UNDEF_WORD_DISP 3
99 /* Allow for align: bt/jmpi/.long + align. */
101 /* Allow for align: bt/subi/stw/bsr/lrw/add/ld/addi/jmp/.long + align. */
102 #define C32_LEN_PIC 24
104 /* Allow for align: jmpi/.long + align. */
106 /* Allow for align: subi/stw/bsr/lrw/add/ld/addi/jmp/.long + align. */
107 #define U32_LEN_PIC 22
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)
115 /* Used in v2_relax_table. */
116 #define COND_DISP10_LEN 2 /* bt/bf_16. */
117 #define COND_DISP16_LEN 4 /* bt/bf_32. */
119 #define SCOND_DISP10_LEN 2 /* bt/bf_16, for CK801 only. */
120 #define SCOND_DISP16_LEN 6 /* !(bt/bf_16) + br_32. */
122 #define UNCD_DISP10_LEN 2 /* br_16. */
123 #define UNCD_DISP16_LEN 4 /* br_32. */
124 #define UNCD_DISP26_LEN 4 /* br32_old. */
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. */
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. */
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. */
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. */
148 /* Declare worker functions. */
149 bfd_boolean
v1_work_lrw (void);
150 bfd_boolean
v1_work_jbsr (void);
151 bfd_boolean
v1_work_fpu_fo (void);
152 bfd_boolean
v1_work_fpu_fo_fc (void);
153 bfd_boolean
v1_work_fpu_write (void);
154 bfd_boolean
v1_work_fpu_read (void);
155 bfd_boolean
v1_work_fpu_writed (void);
156 bfd_boolean
v1_work_fpu_readd (void);
157 bfd_boolean
v2_work_istack (void);
158 bfd_boolean
v2_work_btsti (void);
159 bfd_boolean
v2_work_addi (void);
160 bfd_boolean
v2_work_subi (void);
161 bfd_boolean
v2_work_add_sub (void);
162 bfd_boolean
v2_work_rotlc (void);
163 bfd_boolean
v2_work_bgeni (void);
164 bfd_boolean
v2_work_not (void);
165 bfd_boolean
v2_work_jbtf (void);
166 bfd_boolean
v2_work_jbr (void);
167 bfd_boolean
v2_work_lrw (void);
168 bfd_boolean
v2_work_lrsrsw (void);
169 bfd_boolean
v2_work_jbsr (void);
170 bfd_boolean
v2_work_jsri (void);
171 bfd_boolean
v2_work_movih (void);
172 bfd_boolean
v2_work_ori (void);
173 bfd_boolean
float_work_fmovi (void);
174 bfd_boolean
dsp_work_bloop (void);
175 bfd_boolean
float_work_fpuv3_fmovi (void);
176 bfd_boolean
float_work_fpuv3_fstore (void);
178 /* csky-opc.h must be included after workers are declared. */
179 #include "opcodes/csky-opc.h"
180 #include "opcode/csky.h"
187 COND_DISP10
= 20, /* bt/bf_16. */
188 COND_DISP16
, /* bt/bf_32. */
190 SCOND_DISP10
, /* br_16 */
191 SCOND_DISP16
, /* !(bt/bf_32) + br_32. */
193 UNCD_DISP10
, /* br_16. */
194 UNCD_DISP16
, /* br_32. */
196 JCOND_DISP10
, /* bt/bf_16. */
197 JCOND_DISP16
, /* bt/bf_32. */
198 JCOND_DISP32
, /* !(bt/bf_32)/jmpi + literal. */
200 JUNCD_DISP10
, /* br_16. */
201 JUNCD_DISP16
, /* br_32. */
202 JUNCD_DISP32
, /* jmpi + literal. */
204 JCOMPZ_DISP16
, /* bez/bnez/bhz/blsz/blz/bhsz. */
205 JCOMPZ_DISP32
, /* !(jbez/jbnez/jblsz/jblz/jbhsz) + jmpi + literal. */
207 BSR_DISP26
, /* bsr_32. */
209 LRW_DISP7
, /* lrw16. */
210 LRW2_DISP8
, /* lrw16, -mno-bsr16,8 bit offset. */
211 LRW_DISP16
, /* lrw32. */
214 unsigned int mach_flag
= 0;
215 unsigned int arch_flag
= 0;
216 unsigned int other_flag
= 0;
217 BFD_HOST_U_64_BIT isa_flag
= 0;
218 unsigned int dsp_flag
= 0;
220 typedef struct stack_size_entry
222 struct stack_size_entry
*next
;
224 unsigned int stack_size
;
227 struct csky_arch_info
230 unsigned int arch_flag
;
231 unsigned int bfd_mach_flag
;
237 unsigned int mach_flag
;
238 BFD_HOST_U_64_BIT isa_flag
;
248 /* Macro information. */
249 struct csky_macro_info
252 /* How many operands : if operands == 5, all of 1,2,3,4 are ok. */
254 BFD_HOST_U_64_BIT isa_flag
;
256 void (*handle_func
)(void);
259 struct csky_insn_info
261 /* Name of the opcode. */
263 /* Output instruction. */
265 /* Pointer for frag. */
267 /* End of instruction. */
269 /* Flag for INSN_OPCODE16F, INSN_OPCODE32F, INSN_OPCODE, INSN_MACRO. */
270 inst_flag flag_force
;
271 /* Operand number. */
273 struct csky_opcode
*opcode
;
274 struct csky_macro_info
*macro
;
275 /* Insn size for check_literal. */
277 unsigned int last_isize
;
278 /* Max size of insn for relax frag_var. */
280 /* Indicates which element is in csky_opcode_info op[] array. */
282 /* The value of each operand in instruction when layout. */
284 int val
[MAX_OPRND_NUM
];
291 /* The following are used for constant expressions. */
296 /* Literal pool data structures. */
299 unsigned short refcnt
;
301 unsigned char ispcrel
;
302 unsigned char unused
;
303 bfd_reloc_code_real_type r_type
;
305 struct tls_addend tls_addend
;
306 unsigned char isdouble
;
308 LITTLENUM_TYPE bignum
[SIZE_OF_LARGE_NUMBER
+ 6];
311 static void csky_idly (void);
312 static void csky_rolc (void);
313 static void csky_sxtrb (void);
314 static void csky_movtf (void);
315 static void csky_addc64 (void);
316 static void csky_subc64 (void);
317 static void csky_or64 (void);
318 static void csky_xor64 (void);
319 static void csky_neg (void);
320 static void csky_rsubi (void);
321 static void csky_arith (void);
322 static void csky_decne (void);
323 static void csky_lrw (void);
325 static enum bfd_reloc_code_real insn_reloc
;
327 /* Assembler operand parse errors use these identifiers. */
331 /* The following are errors. */
332 ERROR_CREG_ILLEGAL
= 0,
333 ERROR_REG_OVER_RANGE
,
334 ERROR_FREG_OVER_RANGE
,
335 ERROR_VREG_OVER_RANGE
,
337 ERROR_802J_REG_OVER_RANGE
,
341 ERROR_IMM_OVERFLOW
, /* 5 */
343 ERROR_JMPIX_OVER_RANGE
,
349 ERROR_MISSING_OPERAND
, /* 10 */
351 ERROR_MISSING_LBRACKET
,
352 ERROR_MISSING_RBRACKET
,
353 ERROR_MISSING_LSQUARE_BRACKETS
,
354 ERROR_MISSING_RSQUARE_BRACKETS
, /* 15 */
355 ERROR_MISSING_LANGLE_BRACKETS
,
356 ERROR_MISSING_RANGLE_BRACKETS
,
357 ERROR_OFFSET_UNALIGNED
,
360 ERROR_CPREG_ILLEGAL
, /* 20 */
362 ERROR_OPERANDS_ILLEGAL
,
363 ERROR_OPERANDS_NUMBER
,
364 ERROR_OPCODE_ILLEGAL
,
366 /* The following are warnings. */
370 /* Error and warning end. */
374 /* Global error state. ARG1 and ARG2 are opaque data interpreted
375 as appropriate for the error code. */
377 struct csky_error_state
379 enum error_number err_num
;
386 /* This macro is used to set error number and arg1 in the global state. */
388 #define SET_ERROR_STRING(err, msg) \
390 if (error_state.err_num > err) \
392 error_state.err_num = err; \
393 error_state.arg1 = (void *)msg; \
397 #define SET_ERROR_INTEGER(err, integer) \
399 if (error_state.err_num > err) \
401 error_state.err_num = err; \
402 error_state.arg_int = integer; \
406 /* Map error identifiers onto a format string, which will use
407 arg1 and arg2 from the global error state. */
408 struct csky_error_format_map
410 enum error_number num
;
414 static const struct csky_error_format_map err_formats
[] =
416 {ERROR_CREG_ILLEGAL
, "Operand %d error: control register is illegal."},
417 {ERROR_REG_OVER_RANGE
, "Operand %d error: r%d register is over range."},
418 {ERROR_FREG_OVER_RANGE
, "Operand %d error: vr%d register is over range."},
419 {ERROR_VREG_OVER_RANGE
, "Operand %d error: vr%d register is out of range."},
420 {ERROR_GREG_ILLEGAL
, "Operand %d error: general register is illegal."},
421 {ERROR_802J_REG_OVER_RANGE
, "Operand %d register %s out of range (802j only has registers:0-15,23,24,25,30)"},
422 {ERROR_REG_FORMAT
, "Operand %d error: %s."},
423 {ERROR_REG_LIST
, "Register list format is illegal."},
424 {ERROR_IMM_ILLEGAL
, "Operand %d is not an immediate."},
425 {ERROR_IMM_OVERFLOW
, "Operand %d immediate is overflow."},
426 {ERROR_IMM_POWER
, "immediate %d is not a power of two"},
427 {ERROR_JMPIX_OVER_RANGE
, "The second operand must be 16/24/32/40"},
428 {ERROR_EXP_CREG
, "Operand %d error: control register is expected."},
429 {ERROR_EXP_GREG
, "Operand %d error: general register is expected."},
430 {ERROR_EXP_CONSTANT
, "Operand %d error: constant is expected."},
431 {ERROR_EXP_EVEN_FREG
, "Operand %d error: even float register is expected."},
432 {ERROR_RELOC_ILLEGAL
, "@%s reloc is not supported"},
433 {ERROR_MISSING_OPERAND
, "Operand %d is missing."},
434 {ERROR_MISSING_COMMA
, "Missing ','"},
435 {ERROR_MISSING_LBRACKET
, "Missing '('"},
436 {ERROR_MISSING_RBRACKET
, "Missing ')'"},
437 {ERROR_MISSING_LSQUARE_BRACKETS
, "Missing '['"},
438 {ERROR_MISSING_RSQUARE_BRACKETS
, "Missing ']'"},
439 {ERROR_MISSING_LANGLE_BRACKETS
, "Missing '<'"},
440 {ERROR_MISSING_RANGLE_BRACKETS
, "Missing '>'"},
441 {ERROR_OFFSET_UNALIGNED
, "Operand %d is unaligned. It must be %d aligned!"},
442 {ERROR_BAD_END
, "Operands mismatch, it has a bad end: %s"},
443 {ERROR_UNDEFINE
, NULL
},
444 {ERROR_CPREG_ILLEGAL
, "Operand %d illegal, expect a cpreg(cpr0-cpr63)."},
445 {ERROR_OPCODE_PSRBIT
, "The operands must be 'ie'/'ee'/'fe'."},
446 {ERROR_OPERANDS_ILLEGAL
, "Operands mismatch: %s."},
447 {ERROR_OPERANDS_NUMBER
, "Operands number mismatch, %d operands expected."},
448 {ERROR_OPCODE_ILLEGAL
, "The instruction is not recognized."},
449 {WARNING_OPTIONS
, "Option %s is not support in %s."},
450 {WARNING_IDLY
, "idly %d is encoded to: idly 4 "},
451 {ERROR_NONE
, "There is no error."},
454 static int do_pic
= 0; /* for jbr/jbf/jbt relax jmpi reloc. */
455 static int do_pff
= -1; /* for insert two br ahead of literals. */
456 static int do_force2bsr
= -1; /* for jbsr->bsr. */
457 static int do_jsri2bsr
= 1; /* for jsri->bsr. */
458 static int do_nolrw
= 0; /* lrw to movih & ori, only for V2. */
459 static int do_long_jump
= -1; /* control if jbf,jbt,jbr relax to jmpi. */
460 static int do_extend_lrw
= -1; /* delete bsr16 in both two options,
461 add btesti16, lrw offset +1 in -melrw. */
462 static int do_func_dump
= 0; /* dump literals after every function. */
463 static int do_br_dump
= 1; /* work for -mabr/-mno-abr, control the literals dump. */
464 static int do_intr_stack
= -1; /* control interrupt stack module, 801&802&803
465 default on, 807&810, default off. */
466 static int float_abi
= 0;
468 #ifdef INCLUDE_BRANCH_STUB
469 static int do_use_branchstub
= -1;
471 static int do_use_branchstub
= 0;
474 /* These are only used for options parsing. Values are bitmasks and are
475 OR'ed into the processor flag bits in md_begin. */
476 static int do_opt_mmp
= 0;
477 static int do_opt_mcp
= 0;
478 static int do_opt_mcache
= 0;
479 static int do_opt_msecurity
= 0;
480 static int do_opt_mhard_float
= 0;
481 static int do_opt_mtrust
= 0;
482 static int do_opt_mdsp
= 0;
483 static int do_opt_medsp
= 0;
484 static int do_opt_mvdsp
= 0;
486 const relax_typeS
*md_relax_table
= NULL
;
487 struct literal
*literal_insn_offset
;
488 static struct literal litpool
[MAX_POOL_SIZE
];
489 static unsigned poolsize
= 0;
490 static unsigned poolnumber
= 0;
491 static unsigned long poolspan
= 0;
492 static unsigned int SPANPANIC
;
493 static unsigned int SPANCLOSE
;
494 static unsigned int SPANEXIT
;
496 static stack_size_entry
*all_stack_size_data
= NULL
;
497 static stack_size_entry
**last_stack_size_data
= &all_stack_size_data
;
499 /* Control by ".no_literal_dump N"
500 * 1 : don't dump literal pool between insn1 and insnN+1
502 static int do_noliteraldump
= 0;
504 /* Label for current pool. */
505 static symbolS
* poolsym
;
506 static char poolname
[8];
508 static bfd_boolean mov_r1_before
;
509 static bfd_boolean mov_r1_after
;
511 const relax_typeS csky_relax_table
[] =
513 /* C-SKY V1 relax table. */
514 {0, 0, 0, 0}, /* RELAX_NONE */
515 {0, 0, 0, 0}, /* RELAX_OVERFLOW */
520 { 0, 0, 0, 0 }, /* UNDEF_DISP */
521 { 2048, -2046, C12_LEN
, C (COND_JUMP
, DISP32
) }, /* DISP12 */
522 { 0, 0, C32_LEN
, 0 }, /* DISP32 */
523 { 0, 0, C32_LEN
, 0 }, /* UNDEF_WORD_DISP */
526 { 0, 0, 0, 0 }, /* UNDEF_DISP */
527 { 2048, -2046, U12_LEN
, C (UNCD_JUMP
, DISP32
) }, /* DISP12 */
528 { 0, 0, U32_LEN
, 0 }, /* DISP32 */
529 { 0, 0, U32_LEN
, 0 }, /* UNDEF_WORD_DISP */
532 { 0, 0, 0, 0 }, /* UNDEF_DISP */
533 { 2048, -2046, C12_LEN
, C (COND_JUMP_PIC
, DISP32
) }, /* DISP12 */
534 { 0, 0, C32_LEN_PIC
, 0 }, /* DISP32 */
535 { 0, 0, C32_LEN_PIC
, 0 }, /* UNDEF_WORD_DISP */
538 { 0, 0, 0, 0 }, /* UNDEF_DISP */
539 { 2048, -2046, U12_LEN
, C (UNCD_JUMP_PIC
, DISP32
) }, /* DISP12 */
540 { 0, 0, U32_LEN_PIC
, 0 }, /* DISP32 */
541 { 0, 0, U32_LEN_PIC
, 0 }, /* UNDEF_WORD_DISP */
543 /* C-SKY V2 relax table. */
544 /* forward backward length more */
545 { 1 KB
- 2, -1 KB
, COND_DISP10_LEN
, COND_DISP16
}, /* COND_DISP10 */
546 { 64 KB
- 2, -64 KB
, COND_DISP16_LEN
, RELAX_OVERFLOW
}, /* COND_DISP16 */
548 { 1 KB
- 2, -1 KB
, SCOND_DISP10_LEN
, SCOND_DISP16
}, /* SCOND_DISP10 */
549 { 64 KB
- 2, -64 KB
, SCOND_DISP16_LEN
, RELAX_OVERFLOW
}, /* SCOND_DISP16 */
551 { 1 KB
- 2, -1 KB
, UNCD_DISP10_LEN
, UNCD_DISP16
}, /* UNCD_DISP10 */
552 { 64 KB
- 2, -64 KB
, UNCD_DISP16_LEN
, RELAX_OVERFLOW
}, /* UNCD_DISP16 */
554 { 1 KB
- 2, -1 KB
, JCOND_DISP10_LEN
, JCOND_DISP16
}, /* JCOND_DISP10 */
555 { 64 KB
- 2, -64 KB
, JCOND_DISP16_LEN
, JCOND_DISP32
}, /* JCOND_DISP16 */
556 { 0, 0, JCOND_DISP32_LEN
, RELAX_NONE
}, /* JCOND_DISP32 */
558 { 1 KB
- 2, -1 KB
, JUNCD_DISP10_LEN
, JUNCD_DISP16
}, /* JUNCD_DISP10 */
559 { 64 KB
- 2, -64 KB
, JUNCD_DISP16_LEN
, JUNCD_DISP32
}, /* JUNCD_DISP16 */
560 { 0, 0, JUNCD_DISP32_LEN
, RELAX_NONE
}, /* JUNCD_DISP32 */
562 { 64 KB
- 2, -64 KB
, JCOMPZ_DISP16_LEN
, JCOMPZ_DISP32
}, /* JCOMPZ_DISP16 */
563 { 0, 0, JCOMPZ_DISP32_LEN
, RELAX_NONE
}, /* JCOMPZ_DISP32 */
565 { 64 MB
- 2, -64 MB
, BSR_DISP26_LEN
, RELAX_OVERFLOW
}, /* BSR_DISP26 */
567 { 508, 0, LRW_DISP7_LEN
, LRW_DISP16
}, /* LRW_DISP7 */
568 { 1016, 0, LRW_DISP7_LEN
, LRW_DISP16
}, /* LRW2_DISP8 */
569 { 64 KB
, 0, LRW_DISP16_LEN
, RELAX_OVERFLOW
}, /* LRW_DISP16 */
573 static void csky_write_insn (char *ptr
, valueT use
, int nbytes
);
574 void md_number_to_chars (char * buf
, valueT val
, int n
);
575 long md_pcrel_from_section (fixS
* fixP
, segT seg
);
577 /* C-SKY architecture table. */
578 const struct csky_arch_info csky_archs
[] =
580 {"ck510", CSKY_ARCH_510
, bfd_mach_ck510
},
581 {"ck610", CSKY_ARCH_610
, bfd_mach_ck610
},
582 {"ck801", CSKY_ARCH_801
, bfd_mach_ck801
},
583 {"ck802", CSKY_ARCH_802
, bfd_mach_ck802
},
584 {"ck803", CSKY_ARCH_803
, bfd_mach_ck803
},
585 {"ck807", CSKY_ARCH_807
, bfd_mach_ck807
},
586 {"ck810", CSKY_ARCH_810
, bfd_mach_ck810
},
587 {"ck860", CSKY_ARCH_860
, bfd_mach_ck860
},
591 #define CSKY_ARCH_807_BASE CSKY_ARCH_807 | CSKY_ARCH_DSP
592 #define CSKY_ARCH_810_BASE CSKY_ARCH_810 | CSKY_ARCH_DSP
594 /* C-SKY cpus table. */
595 const struct csky_cpu_info csky_cpus
[] =
598 #define CSKYV1_ISA_DSP CSKY_ISA_DSP | CSKY_ISA_MAC_DSP
599 {"ck510", CSKY_ARCH_510
, CSKYV1_ISA_E1
},
600 {"ck510e", CSKY_ARCH_510
| CSKY_ARCH_DSP
, CSKYV1_ISA_E1
| CSKYV1_ISA_DSP
},
601 {"ck520", CSKY_ARCH_510
| CSKY_ARCH_MAC
, CSKYV1_ISA_E1
| CSKY_ISA_MAC
| CSKY_ISA_MAC_DSP
},
603 #define CSKY_ISA_610 CSKYV1_ISA_E1 | CSKY_ISA_CP
605 {"ck610", CSKY_ARCH_610
, CSKY_ISA_610
},
606 {"ck610e", CSKY_ARCH_610
| CSKY_ARCH_DSP
, CSKY_ISA_610
| CSKYV1_ISA_DSP
},
607 {"ck610f", CSKY_ARCH_610
| CSKY_ARCH_FLOAT
, CSKY_ISA_610
| CSKY_ISA_FLOAT_E1
},
608 {"ck610ef", CSKY_ARCH_610
| CSKY_ARCH_FLOAT
| CSKY_ARCH_DSP
, CSKY_ISA_610
| CSKY_ISA_FLOAT_E1
| CSKYV1_ISA_DSP
},
609 {"ck610fe", CSKY_ARCH_610
| CSKY_ARCH_FLOAT
| CSKY_ARCH_DSP
, CSKY_ISA_610
| CSKY_ISA_FLOAT_E1
| CSKYV1_ISA_DSP
},
610 {"ck620", CSKY_ARCH_610
| CSKY_ARCH_MAC
, CSKY_ISA_610
| CSKY_ISA_MAC
| CSKY_ISA_MAC_DSP
},
613 #define CSKY_ISA_801 CSKYV2_ISA_E1
614 #define CSKYV2_ISA_DSP (CSKY_ISA_DSP | CSKY_ISA_DSP_1E2)
615 {"ck801", CSKY_ARCH_801
, CSKY_ISA_801
},
616 {"ck801t", CSKY_ARCH_801
, CSKY_ISA_801
| CSKY_ISA_TRUST
},
619 #define CSKY_ISA_802 (CSKY_ISA_801 | CSKYV2_ISA_1E2 | CSKY_ISA_NVIC)
620 {"ck802", CSKY_ARCH_802
, CSKY_ISA_802
},
621 {"ck802j", CSKY_ARCH_802
| CSKY_ARCH_JAVA
, CSKY_ISA_802
| CSKY_ISA_JAVA
},
622 {"ck802t", CSKY_ARCH_802
, CSKY_ISA_802
| CSKY_ISA_TRUST
},
625 #define CSKY_ISA_803 (CSKY_ISA_802 | CSKYV2_ISA_2E3 | CSKY_ISA_MP)
626 #define CSKY_ISA_803R1 (CSKY_ISA_803 | CSKYV2_ISA_3E3R1)
627 #define CSKY_ISA_FLOAT_803 (CSKY_ISA_FLOAT_E1 | CSKY_ISA_FLOAT_1E3)
628 #define CSKY_ISA_EDSP (CSKYV2_ISA_3E3R3 | CSKY_ISA_DSP_ENHANCE)
629 {"ck803", CSKY_ARCH_803
, CSKY_ISA_803
},
630 {"ck803h", CSKY_ARCH_803
, CSKY_ISA_803
},
631 {"ck803t", CSKY_ARCH_803
, CSKY_ISA_803
| CSKY_ISA_TRUST
},
632 {"ck803ht", CSKY_ARCH_803
, CSKY_ISA_803
| CSKY_ISA_TRUST
},
633 {"ck803f", CSKY_ARCH_803
| CSKY_ARCH_FLOAT
, CSKY_ISA_803
| CSKY_ISA_FLOAT_803
},
634 {"ck803fh", CSKY_ARCH_803
| CSKY_ARCH_FLOAT
, CSKY_ISA_803
| CSKY_ISA_FLOAT_803
},
635 {"ck803e", CSKY_ARCH_803
| CSKY_ARCH_DSP
, CSKY_ISA_803
| CSKYV2_ISA_DSP
},
636 {"ck803eh", CSKY_ARCH_803
| CSKY_ARCH_DSP
, CSKY_ISA_803
| CSKYV2_ISA_DSP
},
637 {"ck803et", CSKY_ARCH_803
| CSKY_ARCH_DSP
, CSKY_ISA_803
| CSKYV2_ISA_DSP
| CSKY_ISA_TRUST
},
638 {"ck803eht", CSKY_ARCH_803
| CSKY_ARCH_DSP
, CSKY_ISA_803
| CSKYV2_ISA_DSP
| CSKY_ISA_TRUST
},
639 {"ck803ef", CSKY_ARCH_803
| CSKY_ARCH_DSP
| CSKY_ARCH_FLOAT
, CSKY_ISA_803
| CSKYV2_ISA_DSP
| CSKY_ISA_FLOAT_803
},
640 {"ck803efh", CSKY_ARCH_803
| CSKY_ARCH_DSP
| CSKY_ARCH_FLOAT
, CSKY_ISA_803
| CSKYV2_ISA_DSP
| CSKY_ISA_FLOAT_803
},
641 {"ck803ft", CSKY_ARCH_803
| CSKY_ARCH_FLOAT
, CSKY_ISA_803
| CSKY_ISA_FLOAT_803
| CSKY_ISA_TRUST
},
642 {"ck803eft", CSKY_ARCH_803
| CSKY_ARCH_DSP
| CSKY_ARCH_FLOAT
, CSKY_ISA_803
| CSKYV2_ISA_DSP
| CSKY_ISA_FLOAT_803
| CSKY_ISA_TRUST
},
643 {"ck803efht", CSKY_ARCH_803
| CSKY_ARCH_DSP
| CSKY_ARCH_FLOAT
, CSKY_ISA_803
| CSKYV2_ISA_DSP
| CSKY_ISA_FLOAT_803
| CSKY_ISA_TRUST
},
644 {"ck803r1", CSKY_ARCH_803
, CSKY_ISA_803R1
},
645 {"ck803hr1", CSKY_ARCH_803
, CSKY_ISA_803R1
},
646 {"ck803tr1", CSKY_ARCH_803
, CSKY_ISA_803R1
| CSKY_ISA_TRUST
},
647 {"ck803htr1", CSKY_ARCH_803
, CSKY_ISA_803R1
| CSKY_ISA_TRUST
},
648 {"ck803fr1", CSKY_ARCH_803
| CSKY_ARCH_FLOAT
, CSKY_ISA_803R1
| CSKY_ISA_FLOAT_803
},
649 {"ck803fhr1", CSKY_ARCH_803
| CSKY_ARCH_FLOAT
, CSKY_ISA_803R1
| CSKY_ISA_FLOAT_803
},
650 {"ck803er1", CSKY_ARCH_803
| CSKY_ARCH_DSP
, CSKY_ISA_803R1
| CSKY_ISA_EDSP
},
651 {"ck803ehr1", CSKY_ARCH_803
| CSKY_ARCH_DSP
, CSKY_ISA_803R1
| CSKY_ISA_EDSP
},
652 {"ck803etr1", CSKY_ARCH_803
| CSKY_ARCH_DSP
, CSKY_ISA_803R1
| CSKY_ISA_EDSP
| CSKY_ISA_TRUST
},
653 {"ck803ehtr1", CSKY_ARCH_803
| CSKY_ARCH_DSP
, CSKY_ISA_803R1
| CSKY_ISA_EDSP
| CSKY_ISA_TRUST
},
654 {"ck803efr1", CSKY_ARCH_803
| CSKY_ARCH_DSP
| CSKY_ARCH_FLOAT
, CSKY_ISA_803R1
| CSKY_ISA_EDSP
| CSKY_ISA_FLOAT_803
},
655 {"ck803efhr1", CSKY_ARCH_803
| CSKY_ARCH_DSP
| CSKY_ARCH_FLOAT
, CSKY_ISA_803R1
| CSKY_ISA_EDSP
| CSKY_ISA_FLOAT_803
},
656 {"ck803ftr1", CSKY_ARCH_803
| CSKY_ARCH_FLOAT
, CSKY_ISA_803R1
| CSKY_ISA_FLOAT_803
| CSKY_ISA_TRUST
},
657 {"ck803eftr1", CSKY_ARCH_803
| CSKY_ARCH_DSP
| CSKY_ARCH_FLOAT
, CSKY_ISA_803R1
| CSKY_ISA_EDSP
| CSKY_ISA_FLOAT_803
| CSKY_ISA_TRUST
},
658 {"ck803ehftr1", CSKY_ARCH_803
| CSKY_ARCH_DSP
| CSKY_ARCH_FLOAT
, CSKY_ISA_803R1
| CSKY_ISA_EDSP
| CSKY_ISA_FLOAT_803
| CSKY_ISA_TRUST
},
660 #define CSKY_ISA_803R2 (CSKY_ISA_803R1 | CSKYV2_ISA_3E3R2)
661 {"ck803r2", CSKY_ARCH_803
, CSKY_ISA_803R2
},
662 {"ck803hr2", CSKY_ARCH_803
, CSKY_ISA_803R2
},
663 {"ck803tr2", CSKY_ARCH_803
, CSKY_ISA_803R2
| CSKY_ISA_TRUST
},
664 {"ck803htr2", CSKY_ARCH_803
, CSKY_ISA_803R2
| CSKY_ISA_TRUST
},
665 {"ck803fr2", CSKY_ARCH_803
| CSKY_ARCH_FLOAT
, CSKY_ISA_803R2
| CSKY_ISA_FLOAT_803
},
666 {"ck803fhr2", CSKY_ARCH_803
| CSKY_ARCH_FLOAT
, CSKY_ISA_803R2
| CSKY_ISA_FLOAT_803
},
667 {"ck803er2", CSKY_ARCH_803
| CSKY_ARCH_DSP
, CSKY_ISA_803R2
| CSKY_ISA_EDSP
},
668 {"ck803ehr2", CSKY_ARCH_803
| CSKY_ARCH_DSP
, CSKY_ISA_803R2
| CSKY_ISA_EDSP
},
669 {"ck803etr2", CSKY_ARCH_803
| CSKY_ARCH_DSP
, CSKY_ISA_803R2
| CSKY_ISA_EDSP
| CSKY_ISA_TRUST
},
670 {"ck803ehtr2", CSKY_ARCH_803
| CSKY_ARCH_DSP
, CSKY_ISA_803R2
| CSKY_ISA_EDSP
| CSKY_ISA_TRUST
},
671 {"ck803efr2", CSKY_ARCH_803
| CSKY_ARCH_DSP
| CSKY_ARCH_FLOAT
, CSKY_ISA_803R2
| CSKY_ISA_EDSP
| CSKY_ISA_FLOAT_803
},
672 {"ck803efhr2", CSKY_ARCH_803
| CSKY_ARCH_DSP
| CSKY_ARCH_FLOAT
, CSKY_ISA_803R2
| CSKY_ISA_EDSP
| CSKY_ISA_FLOAT_803
},
673 {"ck803ftr2", CSKY_ARCH_803
| CSKY_ARCH_FLOAT
, CSKY_ISA_803R2
| CSKY_ISA_FLOAT_803
| CSKY_ISA_TRUST
},
674 {"ck803eftr2", CSKY_ARCH_803
| CSKY_ARCH_DSP
| CSKY_ARCH_FLOAT
, CSKY_ISA_803R2
| CSKY_ISA_EDSP
| CSKY_ISA_FLOAT_803
| CSKY_ISA_TRUST
},
675 {"ck803efhtr2", CSKY_ARCH_803
| CSKY_ARCH_DSP
| CSKY_ARCH_FLOAT
, CSKY_ISA_803R2
| CSKY_ISA_EDSP
| CSKY_ISA_FLOAT_803
| CSKY_ISA_TRUST
},
677 #define CSKY_ISA_803R3 (CSKY_ISA_803R2 | CSKYV2_ISA_3E3R3)
678 {"ck803r3", CSKY_ARCH_803
, CSKY_ISA_803R3
},
680 {"ck803s", CSKY_ARCH_803
, CSKY_ISA_803R1
},
681 {"ck803se", CSKY_ARCH_803
| CSKY_ARCH_DSP
, CSKY_ISA_803R1
| CSKYV2_ISA_DSP
},
682 {"ck803sj", CSKY_ARCH_803
| CSKY_ARCH_JAVA
, CSKY_ISA_803R1
| CSKY_ISA_JAVA
},
683 {"ck803sf", CSKY_ARCH_803
| CSKY_ARCH_FLOAT
, CSKY_ISA_803R1
| CSKY_ISA_FLOAT_803
},
684 {"ck803sef", CSKY_ARCH_803
| CSKY_ARCH_DSP
| CSKY_ARCH_FLOAT
, CSKY_ISA_803R1
| CSKYV2_ISA_DSP
| CSKY_ISA_FLOAT_803
},
685 {"ck803st", CSKY_ARCH_803
, CSKY_ISA_803R1
| CSKY_ISA_TRUST
},
688 #define CSKY_ISA_807 (CSKY_ISA_803 | CSKYV2_ISA_3E7 | CSKY_ISA_DSP | CSKY_ISA_MP_1E2 | CSKY_ISA_CACHE)
689 #define CSKY_ISA_FLOAT_807 (CSKY_ISA_FLOAT_803 | CSKY_ISA_FLOAT_3E4 | CSKY_ISA_FLOAT_1E2)
690 {"ck807e", CSKY_ARCH_807_BASE
, CSKY_ISA_807
| CSKYV2_ISA_DSP
},
691 {"ck807ef", CSKY_ARCH_807_BASE
| CSKY_ARCH_FLOAT
, CSKY_ISA_807
| CSKYV2_ISA_DSP
| CSKY_ISA_FLOAT_807
},
692 {"ck807", CSKY_ARCH_807_BASE
, CSKY_ISA_807
| CSKYV2_ISA_DSP
},
693 {"ck807f", CSKY_ARCH_807_BASE
| CSKY_ARCH_FLOAT
, CSKY_ISA_807
| CSKYV2_ISA_DSP
| CSKY_ISA_FLOAT_807
},
696 #define CSKY_ISA_810 (CSKY_ISA_807 | CSKYV2_ISA_7E10)
697 #define CSKY_ISA_FLOAT_810 (CSKY_ISA_FLOAT_E1 | CSKY_ISA_FLOAT_1E2)
698 {"ck810e", CSKY_ARCH_810_BASE
, CSKY_ISA_810
| CSKYV2_ISA_DSP
},
699 {"ck810et", CSKY_ARCH_810_BASE
, CSKY_ISA_810
| CSKYV2_ISA_DSP
| CSKY_ISA_TRUST
},
700 {"ck810ef", CSKY_ARCH_810_BASE
| CSKY_ARCH_FLOAT
, CSKY_ISA_810
| CSKYV2_ISA_DSP
| CSKY_ISA_FLOAT_810
},
701 {"ck810eft", CSKY_ARCH_810_BASE
| CSKY_ARCH_FLOAT
, CSKY_ISA_810
| CSKYV2_ISA_DSP
| CSKY_ISA_FLOAT_810
| CSKY_ISA_TRUST
},
702 {"ck810", CSKY_ARCH_810_BASE
, CSKY_ISA_810
| CSKYV2_ISA_DSP
},
703 {"ck810v", CSKY_ARCH_810_BASE
, CSKY_ISA_810
| CSKYV2_ISA_DSP
| CSKY_ISA_VDSP
},
704 {"ck810f", CSKY_ARCH_810_BASE
| CSKY_ARCH_FLOAT
, CSKY_ISA_810
| CSKYV2_ISA_DSP
| CSKY_ISA_FLOAT_810
},
705 {"ck810t", CSKY_ARCH_810_BASE
, CSKY_ISA_810
| CSKYV2_ISA_DSP
| CSKY_ISA_TRUST
},
706 {"ck810tv", CSKY_ARCH_810_BASE
, CSKY_ISA_810
| CSKYV2_ISA_DSP
| CSKY_ISA_TRUST
},
707 {"ck810ft", CSKY_ARCH_810_BASE
| CSKY_ARCH_FLOAT
, CSKY_ISA_810
| CSKYV2_ISA_DSP
| CSKY_ISA_VDSP
| CSKY_ISA_FLOAT_810
| CSKY_ISA_TRUST
},
708 {"ck810ftv", CSKY_ARCH_810_BASE
| CSKY_ARCH_FLOAT
, CSKY_ISA_810
| CSKYV2_ISA_DSP
| CSKY_ISA_VDSP
| CSKY_ISA_FLOAT_810
| CSKY_ISA_TRUST
},
711 #define CSKY_ISA_860 (CSKY_ISA_810 | CSKYV2_ISA_10E60 | CSKYV2_ISA_3E3R3)
712 #define CSKY_ISA_860F (CSKY_ISA_860 | CSKY_ISA_FLOAT_7E60)
713 {"ck860", CSKY_ARCH_860
, CSKY_ISA_860
},
714 {"ck860f", CSKY_ARCH_860
, CSKY_ISA_860F
},
719 int md_short_jump_size
= 2;
720 int md_long_jump_size
= 4;
722 /* This array holds the chars that always start a comment. If the
723 pre-processor is disabled, these aren't very useful. */
724 const char comment_chars
[] = "#";
726 /* This array holds the chars that only start a comment at the beginning of
727 a line. If the line seems to have the form '# 123 filename'
728 .line and .file directives will appear in the pre-processed output. */
729 /* Note that input_file.c hand checks for '#' at the beginning of the
730 first line of the input file. This is because the compiler outputs
731 #NO_APP at the beginning of its output. */
732 /* Also note that comments like this one will always work. */
733 const char line_comment_chars
[] = "#";
735 const char line_separator_chars
[] = ";";
737 /* Chars that can be used to separate mant
738 from exp in floating point numbers. */
739 const char EXP_CHARS
[] = "eE";
741 /* Chars that mean this number is a floating point constant.
745 const char FLT_CHARS
[] = "rRsSfFdDxXeEpP";
747 const char *md_shortopts
= "";
749 struct option md_longopts
[] = {
750 #define OPTION_MARCH (OPTION_MD_BASE + 0)
751 {"march", required_argument
, NULL
, OPTION_MARCH
},
752 #define OPTION_MCPU (OPTION_MD_BASE + 1)
753 {"mcpu", required_argument
, NULL
, OPTION_MCPU
},
754 #define OPTION_FLOAT_ABI (OPTION_MD_BASE + 2)
755 {"mfloat-abi", required_argument
, NULL
, OPTION_FLOAT_ABI
},
757 /* Remaining options just set boolean flags. */
758 {"EL", no_argument
, &target_big_endian
, 0},
759 {"mlittle-endian", no_argument
, &target_big_endian
, 0},
760 {"EB", no_argument
, &target_big_endian
, 1},
761 {"mbig-endian", no_argument
, &target_big_endian
, 1},
762 {"fpic", no_argument
, &do_pic
, 1},
763 {"pic", no_argument
, &do_pic
, 1},
764 {"mljump", no_argument
, &do_long_jump
, 1},
765 {"mno-ljump", no_argument
, &do_long_jump
, 0},
766 {"force2bsr", no_argument
, &do_force2bsr
, 1},
767 {"mforce2bsr", no_argument
, &do_force2bsr
, 1},
768 {"no-force2bsr", no_argument
, &do_force2bsr
, 0},
769 {"mno-force2bsr", no_argument
, &do_force2bsr
, 0},
770 {"jsri2bsr", no_argument
, &do_jsri2bsr
, 1},
771 {"mjsri2bsr", no_argument
, &do_jsri2bsr
, 1},
772 {"no-jsri2bsr", no_argument
, &do_jsri2bsr
, 0},
773 {"mno-jsri2bsr", no_argument
, &do_jsri2bsr
, 0},
774 {"mnolrw", no_argument
, &do_nolrw
, 1},
775 {"mno-lrw", no_argument
, &do_nolrw
, 1},
776 {"melrw", no_argument
, &do_extend_lrw
, 1},
777 {"mno-elrw", no_argument
, &do_extend_lrw
, 0},
778 {"mlaf", no_argument
, &do_func_dump
, 1},
779 {"mliterals-after-func", no_argument
, &do_func_dump
, 1},
780 {"mno-laf", no_argument
, &do_func_dump
, 0},
781 {"mno-literals-after-func", no_argument
, &do_func_dump
, 0},
782 {"mlabr", no_argument
, &do_br_dump
, 1},
783 {"mliterals-after-br", no_argument
, &do_br_dump
, 1},
784 {"mno-labr", no_argument
, &do_br_dump
, 0},
785 {"mnoliterals-after-br", no_argument
, &do_br_dump
, 0},
786 {"mistack", no_argument
, &do_intr_stack
, 1},
787 {"mno-istack", no_argument
, &do_intr_stack
, 0},
788 #ifdef INCLUDE_BRANCH_STUB
789 {"mbranch-stub", no_argument
, &do_use_branchstub
, 1},
790 {"mno-branch-stub", no_argument
, &do_use_branchstub
, 0},
792 {"mhard-float", no_argument
, &do_opt_mhard_float
, CSKY_ARCH_FLOAT
},
793 {"mmp", no_argument
, &do_opt_mmp
, CSKY_ARCH_MP
},
794 {"mcp", no_argument
, &do_opt_mcp
, CSKY_ARCH_CP
},
795 {"mcache", no_argument
, &do_opt_mcache
, CSKY_ARCH_CACHE
},
796 {"msecurity", no_argument
, &do_opt_msecurity
, CSKY_ARCH_MAC
},
797 {"mtrust", no_argument
, &do_opt_mtrust
, CSKY_ISA_TRUST
},
798 {"mdsp", no_argument
, &do_opt_mdsp
, CSKY_DSP_FLAG_V1
},
799 {"medsp", no_argument
, &do_opt_medsp
, CSKY_DSP_FLAG_V2
},
800 {"mvdsp", no_argument
, &do_opt_mvdsp
, CSKY_ISA_VDSP
},
803 size_t md_longopts_size
= sizeof (md_longopts
);
805 static struct csky_insn_info csky_insn
;
807 static htab_t csky_opcodes_hash
;
808 static htab_t csky_macros_hash
;
810 static struct csky_macro_info v1_macros_table
[] =
812 {"idly", 1, CSKYV1_ISA_E1
, csky_idly
},
813 {"rolc", 2, CSKYV1_ISA_E1
, csky_rolc
},
814 {"rotlc", 2, CSKYV1_ISA_E1
, csky_rolc
},
815 {"sxtrb0", 2, CSKYV1_ISA_E1
, csky_sxtrb
},
816 {"sxtrb1", 2, CSKYV1_ISA_E1
, csky_sxtrb
},
817 {"sxtrb2", 2, CSKYV1_ISA_E1
, csky_sxtrb
},
818 {"movtf", 3, CSKYV1_ISA_E1
, csky_movtf
},
819 {"addc64", 3, CSKYV1_ISA_E1
, csky_addc64
},
820 {"subc64", 3, CSKYV1_ISA_E1
, csky_subc64
},
821 {"or64", 3, CSKYV1_ISA_E1
, csky_or64
},
822 {"xor64", 3, CSKYV1_ISA_E1
, csky_xor64
},
826 static struct csky_macro_info v2_macros_table
[] =
828 {"neg", 1, CSKYV2_ISA_E1
, csky_neg
},
829 {"rsubi", 2, CSKYV2_ISA_1E2
, csky_rsubi
},
830 {"incf", 1, CSKYV2_ISA_1E2
, csky_arith
},
831 {"inct", 1, CSKYV2_ISA_1E2
, csky_arith
},
832 {"decf", 1, CSKYV2_ISA_2E3
, csky_arith
},
833 {"decgt", 1, CSKYV2_ISA_2E3
, csky_arith
},
834 {"declt", 1, CSKYV2_ISA_2E3
, csky_arith
},
835 {"decne", 1, CSKYV2_ISA_1E2
, csky_decne
},
836 {"dect", 1, CSKYV2_ISA_1E2
, csky_arith
},
837 {"lslc", 1, CSKYV2_ISA_1E2
, csky_arith
},
838 {"lsrc", 1, CSKYV2_ISA_1E2
, csky_arith
},
839 {"xsr", 1, CSKYV2_ISA_1E2
, csky_arith
},
843 /* For option -mnolrw, replace lrw by movih & ori. */
844 static struct csky_macro_info v2_lrw_macro_opcode
=
845 {"lrw", 2, CSKYV2_ISA_1E2
, csky_lrw
};
847 /* This function is used to show errors or warnings. */
850 csky_show_error (enum error_number err
, int idx
, void *arg1
, void *arg2
)
852 if (err
== ERROR_NONE
)
858 case ERROR_OPCODE_PSRBIT
:
859 case ERROR_OPCODE_ILLEGAL
:
860 case ERROR_JMPIX_OVER_RANGE
:
861 case ERROR_MISSING_COMMA
:
862 case ERROR_MISSING_LBRACKET
:
863 case ERROR_MISSING_RBRACKET
:
864 case ERROR_MISSING_LSQUARE_BRACKETS
:
865 case ERROR_MISSING_RSQUARE_BRACKETS
:
866 case ERROR_MISSING_LANGLE_BRACKETS
:
867 case ERROR_MISSING_RANGLE_BRACKETS
:
868 /* Add NULL to fix warnings. */
869 as_bad (_(err_formats
[err
].fmt
), NULL
);
871 case ERROR_CREG_ILLEGAL
:
872 case ERROR_GREG_ILLEGAL
:
873 case ERROR_IMM_ILLEGAL
:
874 case ERROR_IMM_OVERFLOW
:
877 case ERROR_EXP_CONSTANT
:
878 case ERROR_EXP_EVEN_FREG
:
879 case ERROR_MISSING_OPERAND
:
880 case ERROR_CPREG_ILLEGAL
:
881 as_bad (_(err_formats
[err
].fmt
), idx
);
883 case ERROR_OPERANDS_NUMBER
:
884 case ERROR_IMM_POWER
:
885 as_bad (_(err_formats
[err
].fmt
), error_state
.arg_int
);
888 case ERROR_OFFSET_UNALIGNED
:
889 as_bad (_(err_formats
[err
].fmt
), idx
, error_state
.arg_int
);
891 case ERROR_RELOC_ILLEGAL
:
893 case ERROR_OPERANDS_ILLEGAL
:
894 as_bad (_(err_formats
[err
].fmt
), (char *)arg1
);
896 case ERROR_REG_OVER_RANGE
:
897 case ERROR_FREG_OVER_RANGE
:
898 case ERROR_VREG_OVER_RANGE
:
899 as_bad (_(err_formats
[err
].fmt
), idx
, error_state
.arg_int
);
901 case ERROR_802J_REG_OVER_RANGE
:
902 case ERROR_REG_FORMAT
:
903 as_bad (_(err_formats
[err
].fmt
), idx
, (char *)arg1
);
906 /* Add NULL to fix warnings. */
907 as_bad ((char *)arg1
, NULL
);
910 as_warn (_(err_formats
[err
].fmt
), (long)arg1
);
912 case WARNING_OPTIONS
:
913 as_warn (_(err_formats
[err
].fmt
), (char *)arg1
, (char *)arg2
);
920 /* Handle errors in branch relaxation. */
923 csky_branch_report_error (const char* file
, unsigned int line
,
924 symbolS
* sym
, offsetT val
)
926 as_bad_where (file
? file
: _("unknown"),
928 _("pcrel offset for branch to %s too far (0x%lx)"),
929 sym
? S_GET_NAME (sym
) : _("<unknown>"),
933 /* Set appropriate flags for the cpu matching STR. */
936 parse_cpu (const char *str
)
940 for (; csky_cpus
[i
].name
!= NULL
; i
++)
941 if (strcasecmp (str
, csky_cpus
[i
].name
) == 0)
943 mach_flag
|= csky_cpus
[i
].mach_flag
;
944 isa_flag
= csky_cpus
[i
].isa_flag
;
945 other_flag
|= (csky_cpus
[i
].mach_flag
& ~CSKY_ARCH_MASK
);
948 as_bad (_("unknown cpu `%s'"), str
);
951 /* Set appropriate flags for the arch matching STR. */
954 parse_arch (const char *str
)
957 for (; csky_archs
[i
].name
!= NULL
; i
++)
958 if (strcasecmp (str
, csky_archs
[i
].name
) == 0)
960 arch_flag
|= csky_archs
[i
].arch_flag
;
963 as_bad (_("unknown architecture `%s'"), str
);
966 struct csky_option_value_table
972 static const struct csky_option_value_table csky_float_abis
[] =
974 {"hard", VAL_CSKY_FPU_ABI_HARD
},
975 {"softfp", VAL_CSKY_FPU_ABI_SOFTFP
},
976 {"soft", VAL_CSKY_FPU_ABI_SOFT
},
981 parse_float_abi (const char *str
)
983 const struct csky_option_value_table
* opt
;
985 for (opt
= csky_float_abis
; opt
->name
!= NULL
; opt
++)
986 if (strcasecmp (opt
->name
, str
) == 0)
988 float_abi
= opt
->value
;
992 as_bad (_("unknown floating point abi `%s'\n"), str
);
997 /* Implement the TARGET_FORMAT macro. */
1000 elf32_csky_target_format (void)
1002 return (target_big_endian
1004 : "elf32-csky-little");
1008 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
1009 for use in the a.out file, and stores them in the array pointed to by buf.
1010 This knows about the endian-ness of the target machine and does
1011 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
1012 2 (short) and 4 (long) Floating numbers are put out as a series of
1013 LITTLENUMS (shorts, here at least). */
1016 md_number_to_chars (char * buf
, valueT val
, int n
)
1018 if (target_big_endian
)
1019 number_to_chars_bigendian (buf
, val
, n
);
1021 number_to_chars_littleendian (buf
, val
, n
);
1024 /* Get a log2(val). */
1027 csky_log_2 (unsigned int val
)
1030 if ((val
& (val
- 1)) == 0)
1031 for (; val
; val
>>= 1)
1034 csky_show_error (ERROR_IMM_POWER
, 0, (void *)(long)val
, NULL
);
1038 /* Output one instruction to the buffer at PTR. */
1041 csky_write_insn (char *ptr
, valueT use
, int nbytes
)
1044 md_number_to_chars (ptr
, use
, nbytes
);
1045 else /* 32-bit instruction. */
1047 /* Significant figures are in low bits. */
1048 md_number_to_chars (ptr
, use
>> 16, 2);
1049 md_number_to_chars (ptr
+ 2, use
& 0xFFFF, 2);
1053 /* Read an NBYTES instruction from the buffer at PTR. NBYTES should
1054 be either 2 or 4. This function is used in branch relaxation. */
1057 csky_read_insn (char *ptr
, int nbytes
)
1059 unsigned char *uptr
= (unsigned char *)ptr
;
1061 int lo
, hi
; /* hi/lo byte index in binary stream. */
1063 if (target_big_endian
)
1073 v
= uptr
[lo
] | (uptr
[hi
] << 8);
1077 v
|= uptr
[lo
+ 2] | (uptr
[hi
+ 2] << 8);
1082 /* Construct a label name into S from the 3-character prefix P and
1083 number N formatted as a 4-digit hex number. */
1086 make_internal_label (char *s
, const char *p
, int n
)
1088 static const char hex
[] = "0123456789ABCDEF";
1093 s
[3] = hex
[(n
>> 12) & 0xF];
1094 s
[4] = hex
[(n
>> 8) & 0xF];
1095 s
[5] = hex
[(n
>> 4) & 0xF];
1096 s
[6] = hex
[(n
) & 0xF];
1100 /* md_operand is a no-op on C-SKY; we do everything elsewhere. */
1103 md_operand (expressionS
*expressionP ATTRIBUTE_UNUSED
)
1108 /* Under ELF we need to default _GLOBAL_OFFSET_TABLE.
1109 Otherwise we have no need to default values of symbols. */
1112 md_undefined_symbol (char *name ATTRIBUTE_UNUSED
)
1120 /* Use IEEE format for floating-point constants. */
1123 md_atof (int type
, char *litP
, int *sizeP
)
1125 return ieee_md_atof (type
, litP
, sizeP
, target_big_endian
);
1128 /* Print option help to FP. */
1131 md_show_usage (FILE *fp
)
1134 const int margin
= 48;
1136 fprintf (fp
, _("C-SKY assembler options:\n"));
1139 -march=ARCH select architecture ARCH:"));
1140 for (i
= 0, n
= margin
; csky_archs
[i
].name
!= NULL
; i
++)
1142 int l
= strlen (csky_archs
[i
].name
);
1143 if (n
+ l
>= margin
)
1145 fprintf (fp
, "\n\t\t\t\t");
1153 fprintf (fp
, "%s", csky_archs
[i
].name
);
1158 -mcpu=CPU select processor CPU:"));
1159 for (i
= 0, n
= margin
; csky_cpus
[i
].name
!= NULL
; i
++)
1161 int l
= strlen (csky_cpus
[i
].name
);
1162 if (n
+ l
>= margin
)
1164 fprintf (fp
, "\n\t\t\t\t");
1172 fprintf (fp
, "%s", csky_cpus
[i
].name
);
1177 -mfloat-abi=ABI select float ABI:"));
1178 for (i
= 0, n
= margin
; csky_float_abis
[i
].name
!= NULL
; i
++)
1180 int l
= strlen (csky_float_abis
[i
].name
);
1181 if (n
+ l
>= margin
)
1183 fprintf (fp
, "\n\t\t\t\t");
1191 fprintf (fp
, "%s", csky_float_abis
[i
].name
);
1196 -EL -mlittle-endian generate little-endian output\n"));
1198 -EB -mbig-endian generate big-endian output\n"));
1200 -fpic -pic generate position-independent code\n"));
1203 -mljump transform jbf, jbt, jbr to jmpi (CK800 only)\n"));
1207 #ifdef INCLUDE_BRANCH_STUB
1209 -mbranch-stub enable branch stubs for PC-relative calls\n"));
1211 -mno-branch-stub\n"));
1215 -force2bsr -mforce2bsr transform jbsr to bsr\n"));
1217 -no-force2bsr -mno-force2bsr\n"));
1219 -jsri2bsr -mjsri2bsr transform jsri to bsr\n"));
1221 -no-jsri2bsr -mno-jsri2bsr\n"));
1224 -mnolrw -mno-lrw implement lrw as movih + ori\n"));
1226 -melrw enable extended lrw (CK800 only)\n"));
1231 -mlaf -mliterals-after-func emit literals after each function\n"));
1233 -mno-laf -mno-literals-after-func\n"));
1235 -mlabr -mliterals-after-br emit literals after branch instructions\n"));
1237 -mno-labr -mnoliterals-after-br\n"));
1240 -mistack enable interrupt stack instructions\n"));
1245 -mhard-float enable hard float instructions\n"));
1247 -mmp enable multiprocessor instructions\n"));
1249 -mcp enable coprocessor instructions\n"));
1251 -mcache enable cache prefetch instruction\n"));
1253 -msecurity enable security instructions\n"));
1255 -mtrust enable trust instructions\n"));
1257 -mdsp enable DSP instructions\n"));
1259 -medsp enable enhanced DSP instructions\n"));
1261 -mvdsp enable vector DSP instructions\n"));
1264 static void set_csky_attribute (void)
1266 if (mach_flag
& CSKY_ARCH_DSP
)
1268 if (dsp_flag
& CSKY_DSP_FLAG_V2
)
1271 bfd_elf_add_obj_attr_int (stdoutput
, OBJ_ATTR_PROC
,
1272 Tag_CSKY_DSP_VERSION
,
1273 VAL_CSKY_DSP_VERSION_2
);
1275 else if (isa_flag
& CSKY_ISA_DSP
)
1277 /* Set DSP extension. */
1278 bfd_elf_add_obj_attr_int (stdoutput
, OBJ_ATTR_PROC
,
1279 Tag_CSKY_DSP_VERSION
,
1280 VAL_CSKY_DSP_VERSION_EXTENSION
);
1282 /* Set VDSP attribute. */
1283 if (isa_flag
& CSKY_ISA_VDSP
)
1284 bfd_elf_add_obj_attr_int (stdoutput
, OBJ_ATTR_PROC
,
1285 Tag_CSKY_VDSP_VERSION
,
1286 VAL_CSKY_VDSP_VERSION_1
);
1288 else if (isa_flag
& CSKY_ISA_VDSP_2
)
1289 bfd_elf_add_obj_attr_int (stdoutput
, OBJ_ATTR_PROC
,
1290 Tag_CSKY_VDSP_VERSION
,
1291 VAL_CSKY_VDSP_VERSION_2
);
1295 if (mach_flag
& CSKY_ARCH_FLOAT
)
1297 unsigned int val
= VAL_CSKY_FPU_HARDFP_SINGLE
;
1298 if (IS_CSKY_ARCH_V1 (mach_flag
)) {
1299 bfd_elf_add_obj_attr_int (stdoutput
, OBJ_ATTR_PROC
,
1300 Tag_CSKY_FPU_VERSION
,
1301 VAL_CSKY_FPU_VERSION_1
);
1305 if (isa_flag
& CSKY_ISA_FLOAT_3E4
)
1307 bfd_elf_add_obj_attr_int (stdoutput
, OBJ_ATTR_PROC
,
1308 Tag_CSKY_FPU_VERSION
,
1309 VAL_CSKY_FPU_VERSION_2
);
1310 val
|= VAL_CSKY_FPU_HARDFP_DOUBLE
;
1314 bfd_elf_add_obj_attr_int (stdoutput
, OBJ_ATTR_PROC
,
1315 Tag_CSKY_FPU_VERSION
,
1316 VAL_CSKY_FPU_VERSION_2
);
1319 bfd_elf_add_obj_attr_int (stdoutput
, OBJ_ATTR_PROC
,
1320 Tag_CSKY_FPU_HARDFP
,
1322 bfd_elf_add_obj_attr_string (stdoutput
, OBJ_ATTR_PROC
,
1323 Tag_CSKY_FPU_NUMBER_MODULE
,
1325 bfd_elf_add_obj_attr_int (stdoutput
, OBJ_ATTR_PROC
,
1332 bfd_elf_add_obj_attr_int (stdoutput
, OBJ_ATTR_PROC
,
1333 Tag_CSKY_ISA_FLAGS
, isa_flag
);
1335 bfd_elf_add_obj_attr_int (stdoutput
, OBJ_ATTR_PROC
,
1336 Tag_CSKY_ISA_EXT_FLAGS
, (isa_flag
>> 32));
1339 /* Target-specific initialization and option handling. */
1344 unsigned int bfd_mach_flag
= 0;
1345 struct csky_opcode
const *opcode
;
1346 struct csky_macro_info
const *macro
;
1347 struct csky_arch_info
const *p_arch
;
1348 struct csky_cpu_info
const *p_cpu
;
1349 unsigned int flags
= (other_flag
| do_opt_mmp
| do_opt_mcp
| do_opt_mcache
1350 | do_opt_msecurity
| do_opt_mhard_float
);
1351 dsp_flag
|= do_opt_mdsp
| do_opt_medsp
;
1352 isa_flag
|= do_opt_mtrust
| do_opt_mvdsp
;
1355 flags
|= CSKY_ARCH_DSP
;
1359 if (((mach_flag
& CSKY_ARCH_MASK
) != (arch_flag
& CSKY_ARCH_MASK
))
1361 as_warn (_("-mcpu conflict with -march option, using -mcpu"));
1362 if (((mach_flag
& ~CSKY_ARCH_MASK
) != (flags
& ~CSKY_ARCH_MASK
))
1364 as_warn (_("-mcpu conflict with other model parameters, using -mcpu"));
1366 else if (arch_flag
!= 0)
1368 if ((arch_flag
& CSKY_ARCH_MASK
) == CSKY_ARCH_810
1369 || ((arch_flag
& CSKY_ARCH_MASK
) == CSKY_ARCH_807
)) {
1370 /* CK807 and CK810 have DSP instruction by default. */
1371 mach_flag
|= CSKY_ARCH_DSP
;
1373 mach_flag
|= arch_flag
| flags
;
1377 #ifdef TARGET_WITH_CPU
1379 for (; csky_cpus
[i
].name
!= NULL
; i
++)
1381 if (strcmp (TARGET_WITH_CPU
, csky_cpus
[i
].name
) == 0)
1383 mach_flag
|= csky_cpus
[i
].mach_flag
;
1384 isa_flag
= csky_cpus
[i
].isa_flag
;
1390 mach_flag
|= CSKY_ARCH_610
| flags
;
1392 mach_flag
|= CSKY_ARCH_810_BASE
| flags
;
1397 if (IS_CSKY_ARCH_610 (mach_flag
) || IS_CSKY_ARCH_510 (mach_flag
))
1399 if ((mach_flag
& CSKY_ARCH_MP
) && (mach_flag
& CSKY_ARCH_MAC
))
1400 as_fatal ("520/620 conflicts with -mmp option");
1401 else if ((mach_flag
& CSKY_ARCH_MP
) && (mach_flag
& CSKY_ARCH_DSP
))
1402 as_fatal ("510e/610e conflicts with -mmp option");
1403 else if ((mach_flag
& CSKY_ARCH_DSP
) && (mach_flag
& CSKY_ARCH_MAC
))
1404 as_fatal ("520/620 conflicts with 510e/610e or -mdsp option");
1406 if (IS_CSKY_ARCH_510 (mach_flag
) && (mach_flag
& CSKY_ARCH_FLOAT
))
1408 mach_flag
= (mach_flag
& (~CSKY_ARCH_MASK
));
1409 mach_flag
|= CSKY_ARCH_610
;
1412 /* Find bfd_mach_flag, it will set to bfd backend data. */
1413 for (p_arch
= csky_archs
; p_arch
->arch_flag
!= 0; p_arch
++)
1414 if ((mach_flag
& CSKY_ARCH_MASK
) == (p_arch
->arch_flag
& CSKY_ARCH_MASK
))
1416 bfd_elf_add_obj_attr_string (stdoutput
, OBJ_ATTR_PROC
,
1417 Tag_CSKY_ARCH_NAME
, p_arch
->name
);
1418 bfd_mach_flag
= p_arch
->bfd_mach_flag
;
1422 /* Find isa_flag. */
1423 for (p_cpu
= csky_cpus
; p_cpu
->mach_flag
!= 0; p_cpu
++)
1424 if ((mach_flag
& CPU_ARCH_MASK
) == p_cpu
->mach_flag
)
1426 bfd_elf_add_obj_attr_string (stdoutput
, OBJ_ATTR_PROC
,
1427 Tag_CSKY_CPU_NAME
, p_cpu
->name
);
1428 isa_flag
|= p_cpu
->isa_flag
;
1432 /* Check if -mdsp and -medsp conflict. If cpu is ck803, we will
1433 use enhanced dsp instruction. Otherwise, we will use normal dsp. */
1436 if (IS_CSKY_ARCH_803 (mach_flag
))
1438 if ((dsp_flag
& CSKY_DSP_FLAG_V1
))
1440 if (isa_flag
& CSKY_ISA_DSP_ENHANCE
)
1442 /* Option -mdsp conflicts with -mcpu=ck803ern,
1443 CPU already indicates the dsp version. */
1444 as_warn ("Option -mdsp conflicts with -mcpu=ck803ern which "
1445 "has indicated DSP version, ignoring -mdsp.");
1446 isa_flag
&= ~(CSKY_ISA_MAC_DSP
| CSKY_ISA_DSP
);
1447 isa_flag
|= CSKY_ISA_DSP_ENHANCE
;
1451 isa_flag
|= (CSKY_ISA_MAC_DSP
| CSKY_ISA_DSP
);
1452 isa_flag
&= ~CSKY_ISA_DSP_ENHANCE
;
1456 if ((dsp_flag
& CSKY_DSP_FLAG_V2
))
1458 isa_flag
&= ~(CSKY_ISA_MAC_DSP
| CSKY_ISA_DSP
);
1459 isa_flag
|= CSKY_ISA_DSP_ENHANCE
;
1462 if ((dsp_flag
& CSKY_DSP_FLAG_V1
)
1463 && (dsp_flag
& CSKY_DSP_FLAG_V2
))
1465 /* In 803, dspv1 is conflict with dspv2. We keep dspv2. */
1466 as_warn ("option -mdsp conflicts with -medsp, only enabling -medsp");
1467 dsp_flag
&= ~CSKY_DSP_FLAG_V1
;
1468 isa_flag
&= ~(CSKY_ISA_MAC_DSP
| CSKY_ISA_DSP
);
1469 isa_flag
|= CSKY_ISA_DSP_ENHANCE
;
1474 if (dsp_flag
& CSKY_DSP_FLAG_V2
)
1476 dsp_flag
&= ~CSKY_DSP_FLAG_V2
;
1477 isa_flag
&= ~CSKY_ISA_DSP_ENHANCE
;
1478 as_warn ("-medsp option is only supported by ck803s, ignoring -medsp");
1484 if (do_use_branchstub
== -1)
1485 do_use_branchstub
= !IS_CSKY_ARCH_V1 (mach_flag
);
1486 else if (do_use_branchstub
== 1)
1488 if (IS_CSKY_ARCH_V1 (mach_flag
))
1490 as_warn (_("C-SKY ABI v1 (ck510/ck610) does not support -mbranch-stub"));
1491 do_use_branchstub
= 0;
1493 else if (do_force2bsr
== 0)
1495 as_warn (_("-mno-force2bsr is ignored with -mbranch-stub"));
1500 if (IS_CSKY_ARCH_801 (mach_flag
) || IS_CSKY_ARCH_802 (mach_flag
))
1503 as_warn (_("-mno-force2bsr is ignored for ck801/ck802"));
1506 else if (do_force2bsr
== -1)
1507 do_force2bsr
= do_use_branchstub
;
1511 if (IS_CSKY_ARCH_V1 (mach_flag
))
1517 if (do_extend_lrw
== -1)
1519 if (IS_CSKY_ARCH_801 (mach_flag
))
1524 if (IS_CSKY_ARCH_801 (mach_flag
) || IS_CSKY_ARCH_802 (mach_flag
))
1526 if (do_long_jump
> 0)
1527 as_warn (_("-mljump is ignored for ck801/ck802"));
1530 else if (do_long_jump
== -1)
1532 if (do_intr_stack
== -1)
1534 /* control interrupt stack module, 801&802&803 default on
1535 807&810, default off. */
1536 if (IS_CSKY_ARCH_807 (mach_flag
) || IS_CSKY_ARCH_810 (mach_flag
))
1541 /* Add isa_flag(SIMP/CACHE/APS). */
1542 isa_flag
|= (mach_flag
& CSKY_ARCH_MAC
) ? CSKY_ISA_MAC
: 0;
1543 isa_flag
|= (mach_flag
& CSKY_ARCH_MP
) ? CSKY_ISA_MP
: 0;
1544 isa_flag
|= (mach_flag
& CSKY_ARCH_CP
) ? CSKY_ISA_CP
: 0;
1546 /* Set abi flag and get table address. */
1547 if (IS_CSKY_ARCH_V1 (mach_flag
))
1549 mach_flag
= mach_flag
| CSKY_ABI_V1
;
1550 opcode
= csky_v1_opcodes
;
1551 macro
= v1_macros_table
;
1552 SPANPANIC
= v1_SPANPANIC
;
1553 SPANCLOSE
= v1_SPANCLOSE
;
1554 SPANEXIT
= v1_SPANEXIT
;
1555 md_relax_table
= csky_relax_table
;
1559 mach_flag
= mach_flag
| CSKY_ABI_V2
;
1560 opcode
= csky_v2_opcodes
;
1561 macro
= v2_macros_table
;
1562 SPANPANIC
= v2_SPANPANIC
;
1565 SPANCLOSE
= v2_SPANCLOSE_ELRW
;
1566 SPANEXIT
= v2_SPANEXIT_ELRW
;
1570 SPANCLOSE
= v2_SPANCLOSE
;
1571 SPANEXIT
= v2_SPANEXIT
;
1573 md_relax_table
= csky_relax_table
;
1576 /* Establish hash table for opcodes and macros. */
1577 csky_macros_hash
= str_htab_create ();
1578 csky_opcodes_hash
= str_htab_create ();
1579 for ( ; opcode
->mnemonic
!= NULL
; opcode
++)
1580 if ((isa_flag
& (opcode
->isa_flag16
| opcode
->isa_flag32
)) != 0)
1581 str_hash_insert (csky_opcodes_hash
, opcode
->mnemonic
, opcode
, 0);
1582 for ( ; macro
->name
!= NULL
; macro
++)
1583 if ((isa_flag
& macro
->isa_flag
) != 0)
1584 str_hash_insert (csky_macros_hash
, macro
->name
, macro
, 0);
1585 if (do_nolrw
&& (isa_flag
& CSKYV2_ISA_1E2
) != 0)
1586 str_hash_insert (csky_macros_hash
,
1587 v2_lrw_macro_opcode
.name
, &v2_lrw_macro_opcode
, 0);
1588 /* Set e_flag to ELF Head. */
1589 bfd_set_private_flags (stdoutput
, mach_flag
& ~(0xffff));
1590 /* Set bfd_mach to bfd backend data. */
1591 bfd_set_arch_mach (stdoutput
, bfd_arch_csky
, bfd_mach_flag
);
1593 set_csky_attribute ();
1596 /* The C-SKY assembler emits mapping symbols $t and $d to mark the
1597 beginning of a sequence of instructions and data (such as a constant pool),
1598 respectively. This is similar to what ARM does. */
1601 make_mapping_symbol (map_state state
, valueT value
, fragS
*frag
)
1604 const char * symname
;
1610 type
= BSF_NO_FLAGS
;
1614 type
= BSF_NO_FLAGS
;
1620 symbolP
= symbol_new (symname
, now_seg
, frag
, value
);
1621 symbol_get_bfdsym (symbolP
)->flags
|= type
| BSF_LOCAL
;
1624 /* We need to keep track of whether we are emitting code or data; this
1625 function switches state and emits a mapping symbol if necessary. */
1628 mapping_state (map_state state
)
1630 map_state current_state
1631 = seg_info (now_seg
)->tc_segment_info_data
.current_state
;
1633 if (current_state
== state
)
1635 else if (current_state
== MAP_UNDEFINED
&& state
== MAP_DATA
)
1637 else if (current_state
== MAP_UNDEFINED
&& state
== MAP_TEXT
)
1639 struct frag
* const frag_first
= seg_info (now_seg
)->frchainP
->frch_root
;
1640 if (frag_now
!= frag_first
|| frag_now_fix () > 0)
1641 make_mapping_symbol (MAP_DATA
, (valueT
) 0, frag_first
);
1644 seg_info (now_seg
)->tc_segment_info_data
.current_state
= state
;
1645 make_mapping_symbol (state
, (valueT
) frag_now_fix (), frag_now
);
1648 /* Dump the literal pool. */
1651 dump_literals (int isforce
)
1653 #define CSKYV1_BR_INSN 0xF000
1654 #define CSKYV2_BR_INSN 0x0400
1657 symbolS
* brarsym
= NULL
;
1659 /* V1 nop encoding: 0x1200 : mov r0, r0. */
1660 static char v1_nop_insn_big
[2] = {0x12, 0x00};
1661 static char v1_nop_insn_little
[2] = {0x00, 0x12};
1666 /* Must we branch around the literal table? */
1670 make_internal_label (brarname
, POOL_END_LABEL
, poolnumber
);
1671 brarsym
= symbol_make (brarname
);
1672 symbol_table_insert (brarsym
);
1673 mapping_state (MAP_TEXT
);
1674 if (IS_CSKY_ARCH_V1 (mach_flag
))
1677 = frag_var (rs_machine_dependent
,
1678 csky_relax_table
[C (UNCD_JUMP_S
, DISP32
)].rlx_length
,
1679 csky_relax_table
[C (UNCD_JUMP_S
, DISP12
)].rlx_length
,
1680 C (UNCD_JUMP_S
, 0), brarsym
, 0, 0);
1681 md_number_to_chars (csky_insn
.output
, CSKYV1_BR_INSN
, 2);
1686 = frag_var (rs_machine_dependent
,
1691 md_number_to_chars (csky_insn
.output
, CSKYV2_BR_INSN
, 2);
1694 /* Make sure that the section is sufficiently aligned and that
1695 the literal table is aligned within it. */
1699 csky_insn
.output
= frag_more (2);
1701 if (IS_CSKY_V1 (mach_flag
))
1702 br_self
= CSKYV1_BR_INSN
| 0x7ff;
1704 br_self
= CSKYV2_BR_INSN
;
1705 md_number_to_chars (csky_insn
.output
, br_self
, 2);
1708 csky_insn
.output
= frag_more (2);
1710 md_number_to_chars (csky_insn
.output
, br_self
, 2);
1713 mapping_state (MAP_DATA
);
1715 record_alignment (now_seg
, 2);
1716 if (IS_CSKY_ARCH_V1 (mach_flag
))
1717 frag_align_pattern (2,
1719 ? v1_nop_insn_big
: v1_nop_insn_little
),
1722 frag_align (2, 0, 3);
1724 colon (S_GET_NAME (poolsym
));
1726 for (i
= 0, p
= litpool
; i
< poolsize
; p
++)
1728 insn_reloc
= p
->r_type
;
1729 if (insn_reloc
== BFD_RELOC_CKCORE_TLS_IE32
1730 || insn_reloc
== BFD_RELOC_CKCORE_TLS_LDM32
1731 || insn_reloc
== BFD_RELOC_CKCORE_TLS_GD32
)
1732 literal_insn_offset
= p
;
1735 if (target_big_endian
)
1737 p
->e
.X_add_number
= p
->dbnum
>> 32;
1738 emit_expr (& p
->e
, 4);
1739 p
->e
.X_add_number
= p
->dbnum
& 0xffffffff;
1740 emit_expr (& p
->e
, 4);
1744 p
->e
.X_add_number
= p
->dbnum
& 0xffffffff;
1745 emit_expr (& p
->e
, 4);
1746 p
->e
.X_add_number
= p
->dbnum
>> 32;
1747 emit_expr (& p
->e
, 4);
1750 else if (p
->e
.X_op
== O_big
)
1752 memcpy (generic_bignum
, p
->bignum
, sizeof (p
->bignum
));
1753 emit_expr (& p
->e
, p
->e
.X_add_number
* CHARS_PER_LITTLENUM
);
1756 emit_expr (& p
->e
, 4);
1758 if (p
->e
.X_op
== O_big
)
1759 i
+= ((p
->e
.X_add_number
* CHARS_PER_LITTLENUM
) >> 2);
1761 i
+= (p
->isdouble
? 2 : 1);
1764 if (isforce
&& IS_CSKY_ARCH_V2 (mach_flag
))
1766 /* Add one nop insn at end of literal for disassembler. */
1767 mapping_state (MAP_TEXT
);
1768 csky_insn
.output
= frag_more (2);
1769 md_number_to_chars (csky_insn
.output
, CSKYV2_INST_NOP
, 2);
1772 insn_reloc
= BFD_RELOC_NONE
;
1774 if (brarsym
!= NULL
)
1775 colon (S_GET_NAME (brarsym
));
1779 static struct literal
*
1780 enter_literal (expressionS
*e
,
1782 unsigned char isdouble
,
1787 if (poolsize
>= MAX_POOL_SIZE
- 2)
1789 /* The literal pool is as full as we can handle. We have
1790 to be 2 entries shy of the 1024/4=256 entries because we
1791 have to allow for the branch (2 bytes) and the alignment
1792 (2 bytes before the first insn referencing the pool and
1793 2 bytes before the pool itself) == 6 bytes, rounds up
1796 /* Save the parsed symbol's reloc. */
1797 enum bfd_reloc_code_real last_reloc_before_dump
= insn_reloc
;
1799 insn_reloc
= last_reloc_before_dump
;
1804 /* Create new literal pool. */
1805 if (++ poolnumber
> 0xFFFF)
1806 as_fatal (_("more than 65K literal pools"));
1808 make_internal_label (poolname
, POOL_START_LABEL
, poolnumber
);
1809 poolsym
= symbol_make (poolname
);
1810 symbol_table_insert (poolsym
);
1814 /* Search pool for value so we don't have duplicates. */
1815 for (p
= litpool
,i
= 0; i
< poolsize
; p
++)
1817 if (e
->X_op
== p
->e
.X_op
1818 && e
->X_add_symbol
== p
->e
.X_add_symbol
1819 && e
->X_add_number
== p
->e
.X_add_number
1820 && ispcrel
== p
->ispcrel
1821 && insn_reloc
== p
->r_type
1822 && isdouble
== p
->isdouble
1823 && insn_reloc
!= BFD_RELOC_CKCORE_TLS_GD32
1824 && insn_reloc
!= BFD_RELOC_CKCORE_TLS_LDM32
1825 && insn_reloc
!= BFD_RELOC_CKCORE_TLS_LDO32
1826 && insn_reloc
!= BFD_RELOC_CKCORE_TLS_IE32
1827 && insn_reloc
!= BFD_RELOC_CKCORE_TLS_LE32
1828 && (e
->X_op
!= O_big
1829 || (memcmp (generic_bignum
, p
->bignum
,
1830 p
->e
.X_add_number
* sizeof (LITTLENUM_TYPE
)) == 0)))
1835 if (p
->e
.X_op
== O_big
)
1837 i
+= (p
->e
.X_add_number
>> 1);
1838 i
+= (p
->e
.X_add_number
& 0x1);
1841 i
+= (p
->isdouble
? 2 : 1);
1844 p
->ispcrel
= ispcrel
;
1846 p
->r_type
= insn_reloc
;
1847 p
->isdouble
= isdouble
;
1851 if (e
->X_op
== O_big
)
1852 memcpy (p
->bignum
, generic_bignum
, sizeof (p
->bignum
));
1854 if (insn_reloc
== BFD_RELOC_CKCORE_TLS_GD32
1855 || insn_reloc
== BFD_RELOC_CKCORE_TLS_LDM32
1856 || insn_reloc
== BFD_RELOC_CKCORE_TLS_IE32
)
1858 p
->tls_addend
.frag
= frag_now
;
1859 p
->tls_addend
.offset
= csky_insn
.output
- frag_now
->fr_literal
;
1860 literal_insn_offset
= p
;
1862 if (p
->e
.X_op
== O_big
) {
1863 poolsize
+= (p
->e
.X_add_number
>> 1);
1864 poolsize
+= (p
->e
.X_add_number
& 0x1);
1866 poolsize
+= (p
->isdouble
? 2 : 1);
1871 /* Check whether we must dump the literal pool here.
1872 kind == 0 is any old instruction.
1873 kind > 0 means we just had a control transfer instruction.
1874 kind == 1 means within a function.
1875 kind == 2 means we just left a function.
1877 OFFSET is the length of the insn being processed.
1879 SPANCLOSE and SPANEXIT are smaller numbers than SPANPANIC.
1880 SPANPANIC means that we must dump now.
1881 The dump_literals (1) call inserts a branch around the table, so
1882 we first look to see if its a situation where we won't have to
1883 insert a branch (e.g., the previous instruction was an unconditional
1886 SPANPANIC is the point where we must dump a single-entry pool.
1887 it accounts for alignments and an inserted branch.
1888 the 'poolsize*2' accounts for the scenario where we do:
1889 lrw r1,lit1; lrw r2,lit2; lrw r3,lit3
1890 Note that the 'lit2' reference is 2 bytes further along
1891 but the literal it references will be 4 bytes further along,
1892 so we must consider the poolsize into this equation.
1893 This is slightly over-cautious, but guarantees that we won't
1894 panic because a relocation is too distant. */
1897 check_literals (int kind
, int offset
)
1901 if ((poolspan
> SPANEXIT
|| do_func_dump
)
1903 && (do_br_dump
|| do_func_dump
))
1905 else if (poolspan
> SPANCLOSE
&& (kind
> 0) && do_br_dump
)
1908 >= (SPANPANIC
- (IS_CSKY_ARCH_V1 (mach_flag
) ? poolsize
* 2 : 0)))
1910 /* We have not dumped literal pool before insn1,
1911 and will not dump literal pool between insn1 and insnN+1,
1912 so reset poolspan to original length. */
1913 else if (do_noliteraldump
== 1)
1916 if (do_noliteraldump
== 1)
1917 do_noliteraldump
= 0;
1920 /* The next group of functions are helpers for parsing various kinds
1921 of instruction operand syntax. */
1923 /* Parse operands of the form
1924 <symbol>@GOTOFF+<nnn>
1925 and similar .plt or .got references.
1927 If we find one, set up the correct relocation in RELOC and copy the
1928 input string, minus the `@GOTOFF' into a malloc'd buffer for
1929 parsing by the calling routine. Return this buffer, and if ADJUST
1930 is non-null set it to the length of the string we removed from the
1931 input line. Otherwise return NULL. */
1934 lex_got (enum bfd_reloc_code_real
*reloc
,
1940 const enum bfd_reloc_code_real rel
;
1942 static const struct _gotrel gotrel
[] =
1944 { "GOTOFF", BFD_RELOC_CKCORE_GOTOFF
},
1945 { "GOTPC", BFD_RELOC_CKCORE_GOTPC
},
1946 { "GOTTPOFF", BFD_RELOC_CKCORE_TLS_IE32
},
1947 { "GOT", BFD_RELOC_CKCORE_GOT32
},
1948 { "PLT", BFD_RELOC_CKCORE_PLT32
},
1949 { "BTEXT", BFD_RELOC_CKCORE_TOFFSET_LO16
},
1950 { "BDATA", BFD_RELOC_CKCORE_DOFFSET_LO16
},
1951 { "TLSGD32", BFD_RELOC_CKCORE_TLS_GD32
},
1952 { "TLSLDM32", BFD_RELOC_CKCORE_TLS_LDM32
},
1953 { "TLSLDO32", BFD_RELOC_CKCORE_TLS_LDO32
},
1954 { "TPOFF", BFD_RELOC_CKCORE_TLS_LE32
}
1960 for (cp
= input_line_pointer
; *cp
!= '@'; cp
++)
1961 if (is_end_of_line
[(unsigned char) *cp
])
1964 for (j
= 0; j
< sizeof (gotrel
) / sizeof (gotrel
[0]); j
++)
1966 int len
= strlen (gotrel
[j
].str
);
1968 if (strncasecmp (cp
+ 1, gotrel
[j
].str
, len
) == 0)
1970 if (gotrel
[j
].rel
!= 0)
1972 *reloc
= gotrel
[j
].rel
;
1976 /* input_line_pointer is the str pointer after relocation
1977 token like @GOTOFF. */
1978 input_line_pointer
+= len
+ 1;
1979 return input_line_pointer
;
1982 csky_show_error (ERROR_RELOC_ILLEGAL
, 0,
1983 (void *)gotrel
[j
].str
, NULL
);
1988 /* Might be a symbol version string. Don't as_bad here. */
1992 /* Parse an expression, returning it in E. */
1995 parse_exp (char *s
, expressionS
*e
)
2000 /* Skip whitespace. */
2001 while (ISSPACE (*s
))
2004 save
= input_line_pointer
;
2005 input_line_pointer
= s
;
2007 insn_reloc
= BFD_RELOC_NONE
;
2009 lex_got (&insn_reloc
, NULL
);
2011 if (e
->X_op
== O_absent
)
2012 SET_ERROR_STRING (ERROR_MISSING_OPERAND
, NULL
);
2014 new = input_line_pointer
;
2015 input_line_pointer
= save
;
2020 /* Parse a floating-point number from S into its target representation.
2021 If ISDOUBLE is true, return the result in *DBNUM; otherwise
2022 it's returned in E->X_add_number. Returns the result of advancing
2023 S past the constant. */
2026 parse_fexp (char *s
, expressionS
*e
, unsigned char isdouble
, uint64_t *dbnum
)
2028 int length
; /* Number of chars in an object. */
2029 const char *err
= NULL
; /* Error from scanning float literal. */
2030 unsigned char temp
[8];
2032 /* input_line_pointer->1st char of a flonum (we hope!). */
2033 input_line_pointer
= s
;
2035 if (input_line_pointer
[0] == '0'
2036 && ISALPHA (input_line_pointer
[1]))
2037 input_line_pointer
+= 2;
2040 err
= md_atof ('d', (char *) temp
, &length
);
2042 err
= md_atof ('f', (char *) temp
, &length
);
2044 know (err
!= NULL
|| length
> 0);
2046 if (!is_end_of_line
[(unsigned char) *input_line_pointer
])
2047 as_bad (_("immediate operand required"));
2048 while (!is_end_of_line
[(unsigned char) *input_line_pointer
])
2049 input_line_pointer
++;
2053 as_bad (_("bad floating literal: %s"), err
);
2054 while (!is_end_of_line
[(unsigned char) *input_line_pointer
])
2055 input_line_pointer
++;
2056 know (is_end_of_line
[(unsigned char) input_line_pointer
[-1]]);
2057 return input_line_pointer
;
2060 e
->X_add_symbol
= 0x0;
2061 e
->X_op_symbol
= 0x0;
2062 e
->X_op
= O_constant
;
2069 if (target_big_endian
)
2070 fnum
= (((uint32_t) temp
[0] << 24)
2075 fnum
= (((uint32_t) temp
[3] << 24)
2079 e
->X_add_number
= fnum
;
2083 if (target_big_endian
)
2085 *dbnum
= (((uint32_t) temp
[0] << 24)
2090 *dbnum
|= (((uint32_t) temp
[4] << 24)
2097 *dbnum
= (((uint32_t) temp
[7] << 24)
2102 *dbnum
|= (((uint32_t) temp
[3] << 24)
2108 return input_line_pointer
;
2115 long reg ATTRIBUTE_UNUSED
)
2120 /* Indicate nothing there. */
2121 ep
->X_op
= O_absent
;
2125 s
= parse_exp (s
+ 1, &e
);
2130 SET_ERROR_STRING (ERROR_MISSING_RSQUARE_BRACKETS
, NULL
);
2137 s
= parse_exp (s
, &e
);
2138 if (BFD_RELOC_CKCORE_DOFFSET_LO16
== insn_reloc
2139 || BFD_RELOC_CKCORE_TOFFSET_LO16
== insn_reloc
)
2147 /* If the instruction has work, literal handling is in the work. */
2148 if (!csky_insn
.opcode
->work
)
2150 struct literal
*p
= enter_literal (&e
, ispcrel
, 0, 0);
2154 /* Create a reference to pool entry. */
2155 ep
->X_op
= O_symbol
;
2156 ep
->X_add_symbol
= poolsym
;
2157 ep
->X_add_number
= p
->offset
<< 2;
2163 static int float_to_half (void *f
, void *h
)
2167 unsigned int value_f
= *(unsigned int *)f
;
2168 unsigned short value_h
;
2170 imm_e
= ((value_f
>> 23) & 0xff);
2171 imm_f
= ((value_f
& 0x7fffff));
2173 imm_e
= ((imm_e
- 127 + 15) << 10);
2174 imm_f
= ((imm_f
& 0x7fe000) >> 13);
2176 value_h
= (value_f
& 0x80000000 ? 0x8000 : 0x0) | imm_e
| imm_f
;
2179 *(unsigned short *)h
= value_h
;
2185 parse_rtf (char *s
, int ispcrel
, expressionS
*ep
)
2188 struct literal
*p
= NULL
;
2191 /* Indicate nothing there. */
2192 ep
->X_op
= O_absent
;
2196 s
= parse_exp (s
+ 1, & e
);
2201 as_bad (_("missing ']'"));
2209 if (strstr(csky_insn
.opcode
->mnemonic
, "flrws")
2210 || strstr(csky_insn
.opcode
->mnemonic
, "flrw.32"))
2212 s
= parse_fexp (s
, &e
, 0, &dbnum
);
2213 p
= enter_literal (& e
, ispcrel
, 0, dbnum
);
2215 else if (strstr(csky_insn
.opcode
->mnemonic
, "flrwd")
2216 || strstr(csky_insn
.opcode
->mnemonic
, "flrw.64"))
2218 s
= parse_fexp (s
, &e
, 1, &dbnum
);
2219 p
= enter_literal (& e
, ispcrel
, 1, dbnum
);
2221 else if (strstr(csky_insn
.opcode
->mnemonic
, "flrwh")
2222 || strstr(csky_insn
.opcode
->mnemonic
, "flrw.16"))
2224 s
= parse_fexp (s
, &e
, 0, NULL
);
2225 e
.X_add_number
= float_to_half (&e
.X_add_number
, &e
.X_add_number
);
2226 p
= enter_literal (& e
, ispcrel
, 0, 0);
2229 as_bad (_("unrecognized opcode"));
2234 /* Create a reference to pool entry. */
2235 ep
->X_op
= O_symbol
;
2236 ep
->X_add_symbol
= poolsym
;
2237 ep
->X_add_number
= p
->offset
<< 2;
2243 parse_type_ctrlreg (char** oper
)
2248 if (TOLOWER (*(*oper
+ 0)) == 'c'
2249 && TOLOWER (*(*oper
+ 1)) == 'r'
2250 && ISDIGIT (*(*oper
+ 2)))
2252 /* The control registers are named crxx. */
2253 i
= *(*oper
+ 2) - 0x30;
2254 i
= ISDIGIT (*(*oper
+ 3)) ? (*(*oper
+ 3) - 0x30) + 10 * i
: i
;
2255 len
= ISDIGIT (*(*oper
+ 3)) ? 4 : 3;
2258 else if (!(TOLOWER (*(*oper
+ 0)) == 'c'
2259 && TOLOWER (*(*oper
+ 1)) == 'r'))
2261 /* The control registers are aliased. */
2262 struct csky_reg
*reg
= &csky_ctrl_regs
[0];
2265 if (memcmp (*oper
, reg
->name
, strlen (reg
->name
)) == 0
2266 && (!reg
->flag
|| (isa_flag
& reg
->flag
)))
2269 len
= strlen (reg
->name
);
2277 if (IS_CSKY_V2 (mach_flag
))
2289 if (s
[0] == 'c' && s
[1] == 'r')
2295 if (s
[0] == '3' && s
[1] >= '0' && s
[1] <= '1')
2297 crx
= 30 + s
[1] - '0';
2300 else if (s
[0] == '2' && s
[1] >= '0' && s
[1] <= '9')
2302 crx
= 20 + s
[1] - '0';
2305 else if (s
[0] == '1' && s
[1] >= '0' && s
[1] <= '9')
2307 crx
= 10 + s
[1] - '0';
2310 else if (s
[0] >= '0' && s
[0] <= '9')
2317 SET_ERROR_STRING (ERROR_REG_OVER_RANGE
, "control");
2324 SET_ERROR_STRING (ERROR_CREG_ILLEGAL
, NULL
);
2328 while (*pS
!= '>' && !is_end_of_line
[(unsigned char) *pS
])
2334 /* Error. Missing '>'. */
2335 SET_ERROR_STRING (ERROR_MISSING_RANGLE_BRACKETS
, NULL
);
2339 s
= parse_exp (s
, &e
);
2340 if (e
.X_op
== O_constant
2341 && e
.X_add_number
>= 0
2342 && e
.X_add_number
<= 31)
2345 sel
= e
.X_add_number
;
2352 /* Error. Missing '<'. */
2353 SET_ERROR_STRING (ERROR_MISSING_LANGLE_BRACKETS
, NULL
);
2359 SET_ERROR_STRING (ERROR_CREG_ILLEGAL
, NULL
);
2363 i
= (sel
<< 5) | crx
;
2365 csky_insn
.val
[csky_insn
.idx
++] = i
;
2370 is_reg_sp_with_bracket (char **oper
)
2376 if (IS_CSKY_V1 (mach_flag
))
2384 regs
= csky_general_reg
;
2385 len
= strlen (regs
[sp_idx
]);
2386 if (memcmp (*oper
, regs
[sp_idx
], len
) == 0)
2392 csky_insn
.val
[csky_insn
.idx
++] = sp_idx
;
2397 if (IS_CSKY_V1 (mach_flag
))
2398 regs
= cskyv1_general_alias_reg
;
2400 regs
= cskyv2_general_alias_reg
;
2401 len
= strlen (regs
[sp_idx
]);
2402 if (memcmp (*oper
, regs
[sp_idx
], len
) == 0)
2415 is_reg_sp (char **oper
)
2420 if (IS_CSKY_V1 (mach_flag
))
2425 regs
= csky_general_reg
;
2426 len
= strlen (regs
[sp_idx
]);
2427 if (memcmp (*oper
, regs
[sp_idx
], len
) == 0)
2430 csky_insn
.val
[csky_insn
.idx
++] = sp_idx
;
2435 if (IS_CSKY_V1 (mach_flag
))
2436 regs
= cskyv1_general_alias_reg
;
2438 regs
= cskyv2_general_alias_reg
;
2439 len
= strlen (regs
[sp_idx
]);
2440 if (memcmp (*oper
, regs
[sp_idx
], len
) == 0)
2443 csky_insn
.val
[csky_insn
.idx
++] = sp_idx
;
2451 csky_get_reg_val (char *str
, int *len
)
2454 if (TOLOWER (str
[0]) == 'r' && ISDIGIT (str
[1]))
2456 if (ISDIGIT (str
[1]) && ISDIGIT (str
[2]))
2458 reg
= (str
[1] - '0') * 10 + str
[2] - '0';
2461 else if (ISDIGIT (str
[1]))
2469 else if (TOLOWER (str
[0]) == 's' && TOLOWER (str
[1]) == 'p'
2470 && !ISDIGIT (str
[2]))
2473 if (IS_CSKY_V1 (mach_flag
))
2479 else if (TOLOWER (str
[0]) == 'g' && TOLOWER (str
[1]) == 'b'
2480 && !ISDIGIT (str
[2]))
2483 if (IS_CSKY_V1 (mach_flag
))
2489 else if (TOLOWER (str
[0]) == 'l' && TOLOWER (str
[1]) == 'r'
2490 && !ISDIGIT (str
[2]))
2496 else if (TOLOWER (str
[0]) == 't' && TOLOWER (str
[1]) == 'l'
2497 && TOLOWER (str
[2]) == 's' && !ISDIGIT (str
[3]))
2500 if (IS_CSKY_V2 (mach_flag
))
2506 else if (TOLOWER (str
[0]) == 's' && TOLOWER (str
[1]) == 'v'
2507 && TOLOWER (str
[2]) == 'b' && TOLOWER (str
[3]) == 'r')
2509 if (IS_CSKY_V2 (mach_flag
))
2515 else if (TOLOWER (str
[0]) == 'a')
2517 if (ISDIGIT (str
[1]) && !ISDIGIT (str
[2]))
2519 if (IS_CSKY_V1 (mach_flag
) && (str
[1] - '0') <= 5)
2521 reg
= 2 + str
[1] - '0';
2522 else if (IS_CSKY_V2 (mach_flag
) && (str
[1] - '0') <= 3)
2530 else if (TOLOWER (str
[0]) == 't')
2532 if (IS_CSKY_V2 (mach_flag
))
2534 reg
= atoi (str
+ 1);
2547 else if (TOLOWER (str
[0]) == 'l')
2549 if (str
[1] < '0' || str
[1] > '9')
2551 if (IS_CSKY_V2 (mach_flag
))
2553 reg
= atoi (str
+ 1);
2565 reg
= atoi (str
+ 1);
2568 /* l0 - l6 -> r8 - r13. */
2576 /* Is register available? */
2577 if (IS_CSKY_ARCH_801 (mach_flag
))
2579 /* CK801 register range is r0-r8 & r13-r15. */
2580 if ((reg
> 8 && reg
< 13) || reg
> 15)
2582 SET_ERROR_STRING (ERROR_REG_OVER_RANGE
, reg
);
2586 else if (IS_CSKY_ARCH_802 (mach_flag
))
2588 /* CK802 register range is r0-r15 & r23-r25 & r30. */
2589 if ((reg
> 15 && reg
< 23) || (reg
> 25 && reg
!= 30))
2591 SET_ERROR_STRING (ERROR_REG_OVER_RANGE
, reg
);
2595 else if (reg
> 31 || reg
< 0)
2597 SET_ERROR_STRING (ERROR_REG_OVER_RANGE
, reg
);
2605 csky_get_freg_val (char *str
, int *len
)
2609 if ((TOLOWER(str
[0]) == 'v' || TOLOWER(str
[0]) == 'f')
2610 && (TOLOWER(str
[1]) == 'r'))
2612 /* It is fpu register. */
2614 while (ISDIGIT (*s
))
2616 reg
= reg
* 10 + (*s
) - '0';
2629 is_reglist_legal (char **oper
)
2634 reg1
= csky_get_reg_val (*oper
, &len
);
2637 if (reg1
== -1 || (IS_CSKY_V1 (mach_flag
) && (reg1
== 0 || reg1
== 15)))
2639 SET_ERROR_STRING (ERROR_REG_FORMAT
,
2640 "The first reg must not be r0/r15");
2646 SET_ERROR_STRING (ERROR_REG_FORMAT
,
2647 "The operand format must be rx-ry");
2652 reg2
= csky_get_reg_val (*oper
, &len
);
2655 if (reg2
== -1 || (IS_CSKY_V1 (mach_flag
) && reg1
== 15))
2657 SET_ERROR_STRING (ERROR_REG_FORMAT
,
2658 "The operand format must be r15 in C-SKY V1");
2661 if (IS_CSKY_V2 (mach_flag
))
2665 SET_ERROR_STRING (ERROR_REG_FORMAT
,
2666 "The operand format must be rx-ry (rx < ry)");
2673 csky_insn
.val
[csky_insn
.idx
++] = reg1
;
2678 is_freglist_legal (char **oper
)
2684 reg1
= csky_get_freg_val (*oper
, &len
);
2689 SET_ERROR_STRING (ERROR_REG_FORMAT
,
2690 "The fpu register format is not recognized.");
2696 SET_ERROR_STRING (ERROR_REG_FORMAT
,
2697 "The operand format must be vrx-vry/frx-fry.");
2702 reg2
= csky_get_freg_val (*oper
, &len
);
2707 SET_ERROR_STRING (ERROR_REG_FORMAT
,
2708 "The fpu register format is not recognized.");
2713 SET_ERROR_STRING (ERROR_REG_FORMAT
,
2714 "The operand format must be rx-ry(rx < ry)");
2719 /* The fldm/fstm in CSKY_ISA_FLOAT_7E60 has 5 bits frz(reg1). */
2721 if (strncmp (csky_insn
.opcode
->mnemonic
, "fstm", 4) == 0
2722 || strncmp (csky_insn
.opcode
->mnemonic
, "fldm", 4) == 0)
2724 if ((!(isa_flag
& CSKY_ISA_FLOAT_7E60
)
2725 && (reg2
> (int)15 || reg1
> 15))
2726 || ((isa_flag
& CSKY_ISA_FLOAT_7E60
)
2727 && (reg2
> (int)31 || reg1
> (int)31)))
2729 /* ISA_FLOAT_E1 fstm/fldm fry-frx is within 15.
2730 ISA_FLOAT_7E60 fstm(u)/fldm(u) frx-fry is within 31. */
2731 SET_ERROR_STRING(ERROR_REG_FORMAT
, (void *)"frx-fry is over range");
2734 if ((mach_flag
& CSKY_ARCH_MASK
) == CSKY_ARCH_860
)
2741 if (reg2
> (int)0x3) {
2742 SET_ERROR_STRING(ERROR_REG_FORMAT
, (void *)"vry-vrx is over range");
2748 csky_insn
.val
[csky_insn
.idx
++] = reg1
;
2753 is_reglist_dash_comma_legal (char **oper
, struct operand
*oprnd
)
2761 while (**oper
!= '\n' && **oper
!= '\0')
2763 reg1
= csky_get_reg_val (*oper
, &len
);
2766 SET_ERROR_STRING (ERROR_REG_LIST
, NULL
);
2769 flag
|= (1 << reg1
);
2774 reg2
= csky_get_reg_val (*oper
, &len
);
2777 SET_ERROR_STRING (ERROR_REG_LIST
, NULL
);
2783 SET_ERROR_STRING (ERROR_REG_LIST
, NULL
);
2786 while (reg2
>= reg1
)
2788 flag
|= (1 << reg2
);
2795 /* The reglist: r4-r11, r15, r16-r17, r28. */
2796 #define REGLIST_BITS 0x10038ff0
2797 if (flag
& ~(REGLIST_BITS
))
2799 SET_ERROR_STRING (ERROR_REG_LIST
, NULL
);
2806 if (flag
& (1 << i
))
2813 if (flag
& (1 << 15))
2816 /* Check r16-r17. */
2821 if (flag
& (1 << i
))
2825 list
|= (temp
<< 5);
2828 if (flag
& (1 << 28))
2830 if (oprnd
->mask
== OPRND_MASK_0_4
&& (list
& ~OPRND_MASK_0_4
))
2832 SET_ERROR_STRING (ERROR_REG_LIST
, NULL
);
2835 csky_insn
.val
[csky_insn
.idx
++] = list
;
2840 is_reg_lshift_illegal (char **oper
, int is_float
)
2845 reg
= csky_get_reg_val (*oper
, &len
);
2848 SET_ERROR_STRING (ERROR_REG_FORMAT
, "The register must be r0-r31.");
2853 if ((*oper
)[0] != '<' || (*oper
)[1] != '<')
2855 SET_ERROR_STRING (ERROR_UNDEFINE
,
2856 "Operand format error; should be (rx, ry << n)");
2862 char *new_oper
= parse_exp (*oper
, &e
);
2863 if (e
.X_op
== O_constant
)
2866 /* The immediate must be in [0, 3]. */
2867 if (e
.X_add_number
< 0 || e
.X_add_number
> 3)
2869 SET_ERROR_STRING (ERROR_IMM_OVERFLOW
, NULL
);
2875 SET_ERROR_STRING (ERROR_EXP_CONSTANT
, NULL
);
2879 value
= (reg
<< 2) | e
.X_add_number
;
2881 value
= (reg
<< 5) | (1 << e
.X_add_number
);
2882 csky_insn
.val
[csky_insn
.idx
++] = value
;
2888 is_imm_within_range (char **oper
, int min
, int max
)
2891 bfd_boolean ret
= FALSE
;
2892 char *new_oper
= parse_exp (*oper
, &e
);
2893 if (e
.X_op
== O_constant
)
2897 if (e
.X_add_number
< min
|| e
.X_add_number
> max
)
2900 SET_ERROR_STRING (ERROR_IMM_OVERFLOW
, NULL
);
2903 e
.X_add_number
|= 0x80000000;
2904 csky_insn
.val
[csky_insn
.idx
++] = e
.X_add_number
;
2908 SET_ERROR_STRING(ERROR_IMM_ILLEGAL
, NULL
);
2914 is_imm_within_range_ext (char **oper
, int min
, int max
, int ext
)
2917 bfd_boolean ret
= FALSE
;
2918 char *new_oper
= parse_exp (*oper
, &e
);
2919 if (e
.X_op
== O_constant
)
2923 if ((int)e
.X_add_number
!= ext
2924 && (e
.X_add_number
< min
|| e
.X_add_number
> max
))
2927 SET_ERROR_STRING (ERROR_IMM_OVERFLOW
, NULL
);
2929 csky_insn
.val
[csky_insn
.idx
++] = e
.X_add_number
;
2933 SET_ERROR_STRING(ERROR_IMM_ILLEGAL
, NULL
);
2939 is_oimm_within_range (char **oper
, int min
, int max
)
2942 bfd_boolean ret
= FALSE
;
2943 char *new_oper
= parse_exp (*oper
, &e
);
2944 if (e
.X_op
== O_constant
)
2948 if (e
.X_add_number
< min
|| e
.X_add_number
> max
)
2951 SET_ERROR_STRING (ERROR_IMM_OVERFLOW
, NULL
);
2953 csky_insn
.val
[csky_insn
.idx
++] = e
.X_add_number
- 1;
2960 is_psr_bit (char **oper
)
2962 const struct psrbit
*bits
;
2965 if (IS_CSKY_V1 (mach_flag
))
2966 bits
= cskyv1_psr_bits
;
2968 bits
= cskyv2_psr_bits
;
2970 while (bits
[i
].name
!= NULL
)
2972 if (bits
[i
].isa
&& !(bits
[i
].isa
& isa_flag
))
2977 if (strncasecmp (*oper
, bits
[i
].name
, strlen (bits
[i
].name
)) == 0)
2979 *oper
+= strlen (bits
[i
].name
);
2980 csky_insn
.val
[csky_insn
.idx
] |= bits
[i
].value
;
2985 SET_ERROR_STRING (ERROR_OPCODE_PSRBIT
, NULL
);
2990 parse_type_cpidx (char** oper
)
2994 if (s
[0] == 'c' && s
[1] == 'p')
2996 if (ISDIGIT (s
[2]) && ISDIGIT (s
[3]) && ! ISDIGIT (s
[4]))
2998 idx
= (s
[2] - '0') * 10 + s
[3] - '0';
3001 else if (ISDIGIT (s
[2]) && !ISDIGIT (s
[3]))
3012 *oper
= parse_exp (*oper
, &e
);
3013 if (e
.X_op
!= O_constant
)
3015 /* Can not recognize the operand. */
3018 idx
= e
.X_add_number
;
3021 csky_insn
.val
[csky_insn
.idx
++] = idx
;
3027 parse_type_cpreg (char** oper
)
3029 const char **regs
= csky_cp_reg
;
3033 for (i
= 0; i
< (int)(sizeof (csky_cp_reg
) / sizeof (char *)); i
++)
3035 len
= strlen (regs
[i
]);
3036 if (memcmp (*oper
, regs
[i
], len
) == 0 && !ISDIGIT (*(*oper
+ len
)))
3039 csky_insn
.val
[csky_insn
.idx
++] = i
;
3043 SET_ERROR_STRING (ERROR_CPREG_ILLEGAL
, *oper
);
3048 parse_type_cpcreg (char** oper
)
3053 regs
= csky_cp_creg
;
3054 for (i
= 0; i
< (int)(sizeof (csky_cp_creg
) / sizeof (char *)); i
++)
3056 len
= strlen (regs
[i
]);
3057 if (memcmp (*oper
, regs
[i
], len
) == 0 && !ISDIGIT (*(*oper
+ len
)))
3060 csky_insn
.val
[csky_insn
.idx
++] = i
;
3064 SET_ERROR_STRING (ERROR_CPREG_ILLEGAL
, *oper
);
3069 parse_type_areg (char** oper
)
3073 i
= csky_get_reg_val (*oper
, &len
);
3076 SET_ERROR_STRING (ERROR_GREG_ILLEGAL
, NULL
);
3080 csky_insn
.val
[csky_insn
.idx
++] = i
;
3086 parse_type_freg (char** oper
, int even
)
3090 reg
= csky_get_freg_val (*oper
, &len
);
3093 SET_ERROR_STRING (ERROR_REG_FORMAT
,
3094 (void *)"The fpu register format is not recognized.");
3098 csky_insn
.opcode_end
= *oper
;
3099 if (even
&& reg
& 0x1)
3101 SET_ERROR_STRING (ERROR_EXP_EVEN_FREG
, NULL
);
3105 if (IS_CSKY_V2 (mach_flag
)
3106 && ((csky_insn
.opcode
->isa_flag32
& CSKY_ISA_VDSP_2
)
3107 || !(csky_insn
.opcode
->isa_flag32
& CSKY_ISA_FLOAT_7E60
))
3110 if ((csky_insn
.opcode
->isa_flag32
& CSKY_ISA_VDSP_2
))
3112 SET_ERROR_INTEGER (ERROR_VREG_OVER_RANGE
, reg
);
3116 SET_ERROR_INTEGER (ERROR_FREG_OVER_RANGE
, reg
);
3120 /* TODO: recognize vreg or freg. */
3123 SET_ERROR_INTEGER (ERROR_VREG_OVER_RANGE
, reg
);
3125 csky_insn
.val
[csky_insn
.idx
++] = reg
;
3130 parse_ldst_imm (char **oper
, struct csky_opcode_info
*op ATTRIBUTE_UNUSED
,
3131 struct operand
*oprnd
)
3133 unsigned int mask
= oprnd
->mask
;
3137 shift
= oprnd
->shift
;
3147 if (**oper
== '\0' || **oper
== ')')
3149 csky_insn
.val
[csky_insn
.idx
++] = 0;
3154 *oper
= parse_exp (*oper
, &e
);
3155 if (e
.X_op
!= O_constant
)
3157 /* Not a constant. */
3158 SET_ERROR_STRING(ERROR_UNDEFINE
, (void *)"Operand format is error. eg. \"ld rz, (rx, n)\"");
3161 else if (e
.X_add_number
< 0 || e
.X_add_number
>= max
)
3164 SET_ERROR_STRING(ERROR_IMM_OVERFLOW
, NULL
);
3167 if ((e
.X_add_number
% (1 << shift
)) != 0)
3170 SET_ERROR_INTEGER (ERROR_OFFSET_UNALIGNED
, ((unsigned long)1 << shift
));
3174 csky_insn
.val
[csky_insn
.idx
++] = e
.X_add_number
>> shift
;
3181 csky_count_operands (char *str
)
3183 char *oper_end
= str
;
3184 unsigned int oprnd_num
;
3185 int bracket_cnt
= 0;
3187 if (is_end_of_line
[(unsigned char) *oper_end
])
3192 /* Count how many operands. */
3194 while (!is_end_of_line
[(unsigned char) *oper_end
])
3196 if (*oper_end
== '(' || *oper_end
== '<')
3202 if (*oper_end
== ')' || *oper_end
== '>')
3208 if (!bracket_cnt
&& *oper_end
== ',')
3215 /* End of the operand parsing helper functions. */
3217 /* Parse the opcode part of an instruction. Fill in the csky_insn
3218 state and return true on success, false otherwise. */
3221 parse_opcode (char *str
)
3223 #define IS_OPCODE32F(a) (*(a - 2) == '3' && *(a - 1) == '2')
3224 #define IS_OPCODE16F(a) (*(a - 2) == '1' && *(a - 1) == '6')
3226 /* TRUE if this opcode has a suffix, like 'lrw.h'. */
3227 unsigned int has_suffix
= FALSE
;
3228 unsigned int nlen
= 0;
3230 char name
[OPCODE_MAX_LEN
+ 1];
3231 char macro_name
[OPCODE_MAX_LEN
+ 1];
3233 /* Remove space ahead of string. */
3234 while (ISSPACE (*str
))
3238 /* Find the opcode end. */
3239 while (nlen
< OPCODE_MAX_LEN
3240 && !is_end_of_line
[(unsigned char) *opcode_end
]
3241 && *opcode_end
!= ' ')
3243 /* Is csky force 32 or 16 instruction? */
3244 if (IS_CSKY_V2 (mach_flag
)
3245 && *opcode_end
== '.' && has_suffix
== FALSE
)
3248 if (IS_OPCODE32F (opcode_end
))
3250 csky_insn
.flag_force
= INSN_OPCODE32F
;
3253 else if (IS_OPCODE16F (opcode_end
))
3255 csky_insn
.flag_force
= INSN_OPCODE16F
;
3259 name
[nlen
] = *opcode_end
;
3264 /* Is csky force 32 or 16 instruction? */
3265 if (has_suffix
== FALSE
)
3267 if (IS_CSKY_V2 (mach_flag
) && IS_OPCODE32F (opcode_end
))
3269 csky_insn
.flag_force
= INSN_OPCODE32F
;
3272 else if (IS_OPCODE16F (opcode_end
))
3274 csky_insn
.flag_force
= INSN_OPCODE16F
;
3280 /* Generate macro_name for finding hash in macro hash_table. */
3281 if (has_suffix
== TRUE
)
3283 strncpy (macro_name
, str
, nlen
);
3284 macro_name
[nlen
] = '\0';
3286 /* Get csky_insn.opcode_end. */
3287 while (ISSPACE (*opcode_end
))
3289 csky_insn
.opcode_end
= opcode_end
;
3291 /* Count the operands. */
3292 csky_insn
.number
= csky_count_operands (opcode_end
);
3294 /* Find hash by name in csky_macros_hash and csky_opcodes_hash. */
3295 csky_insn
.macro
= (struct csky_macro_info
*) str_hash_find (csky_macros_hash
,
3297 csky_insn
.opcode
= (struct csky_opcode
*) str_hash_find (csky_opcodes_hash
,
3300 if (csky_insn
.macro
== NULL
&& csky_insn
.opcode
== NULL
)
3305 /* Main dispatch routine to parse operand OPRND for opcode OP from string
3309 get_operand_value (struct csky_opcode_info
*op
,
3310 char **oper
, struct operand
*oprnd
)
3312 struct soperand
*soprnd
= NULL
;
3313 if (oprnd
->mask
== HAS_SUB_OPERAND
)
3315 /* It has sub operand, it must be like:
3319 We will check the format here. */
3320 soprnd
= (struct soperand
*) oprnd
;
3324 int bracket_cnt
= 0;
3325 if (oprnd
->type
== OPRND_TYPE_BRACKET
)
3330 else if (oprnd
->type
== OPRND_TYPE_ABRACKET
)
3343 SET_ERROR_STRING ((oprnd
->type
== OPRND_TYPE_BRACKET
3344 ? ERROR_MISSING_LBRACKET
3345 : ERROR_MISSING_LANGLE_BRACKETS
), NULL
);
3349 /* If the oprnd2 is an immediate, it can not be parsed
3350 that end with ')'/'>'. Modify ')'/'>' to '\0'. */
3351 while ((*s
!= rc
|| bracket_cnt
!= 0) && (*s
!= '\n' && *s
!= '\0'))
3364 SET_ERROR_STRING ((oprnd
->type
== OPRND_TYPE_BRACKET
3365 ? ERROR_MISSING_RBRACKET
3366 : ERROR_MISSING_RANGLE_BRACKETS
), NULL
);
3370 if (get_operand_value (op
, oper
, &soprnd
->subs
[0]) == FALSE
)
3377 else if (**oper
!= '\0')
3379 SET_ERROR_STRING (ERROR_MISSING_COMMA
, NULL
);
3383 if (get_operand_value (op
, oper
, &soprnd
->subs
[1]) == FALSE
)
3394 switch (oprnd
->type
)
3396 /* TODO: add opcode type here, log errors in the function.
3397 If REGLIST, then j = csky_insn.number - 1.
3398 If there is needed to parse expressions, it will be
3400 case OPRND_TYPE_CTRLREG
:
3402 return parse_type_ctrlreg (oper
);
3403 case OPRND_TYPE_AREG
:
3404 return parse_type_areg (oper
);
3405 case OPRND_TYPE_FREG
:
3406 case OPRND_TYPE_VREG
:
3407 return parse_type_freg (oper
, 0);
3408 case OPRND_TYPE_FEREG
:
3409 return parse_type_freg (oper
, 1);
3410 case OPRND_TYPE_CPCREG
:
3411 return parse_type_cpcreg (oper
);
3412 case OPRND_TYPE_CPREG
:
3413 return parse_type_cpreg (oper
);
3414 case OPRND_TYPE_CPIDX
:
3415 return parse_type_cpidx (oper
);
3416 case OPRND_TYPE_GREG0_7
:
3417 case OPRND_TYPE_GREG0_15
:
3421 reg
= csky_get_reg_val (*oper
, &len
);
3425 SET_ERROR_STRING (ERROR_GREG_ILLEGAL
, NULL
);
3428 else if ((oprnd
->type
== OPRND_TYPE_GREG0_7
&& reg
> 7)
3429 || (oprnd
->type
== OPRND_TYPE_GREG0_15
&& reg
> 15))
3431 SET_ERROR_INTEGER (ERROR_REG_OVER_RANGE
, reg
);
3435 csky_insn
.val
[csky_insn
.idx
++] = reg
;
3438 case OPRND_TYPE_REGnsplr
:
3442 reg
= csky_get_reg_val (*oper
, &len
);
3445 || (IS_CSKY_V1 (mach_flag
)
3446 && (reg
== V1_REG_SP
|| reg
== V1_REG_LR
)))
3448 SET_ERROR_STRING (ERROR_REG_OVER_RANGE
, reg
);
3451 csky_insn
.val
[csky_insn
.idx
++] = reg
;
3455 case OPRND_TYPE_REGnr4_r7
:
3461 reg
= csky_get_reg_val (*oper
, &len
);
3462 if (reg
== -1 || (reg
<= 7 && reg
>= 4))
3465 csky_insn
.val
[csky_insn
.idx
++] = reg
;
3472 case OPRND_TYPE_REGr4_r7
:
3473 if (memcmp (*oper
, "r4-r7", sizeof ("r4-r7") - 1) == 0)
3475 *oper
+= sizeof ("r4-r7") - 1;
3476 csky_insn
.val
[csky_insn
.idx
++] = 0;
3479 SET_ERROR_STRING (ERROR_OPCODE_ILLEGAL
, NULL
);
3481 case OPRND_TYPE_IMM_LDST
:
3482 return parse_ldst_imm (oper
, op
, oprnd
);
3483 case OPRND_TYPE_IMM_FLDST
:
3484 return parse_ldst_imm (oper
, op
, oprnd
);
3485 case OPRND_TYPE_IMM1b
:
3486 return is_imm_within_range (oper
, 0, 1);
3487 case OPRND_TYPE_IMM2b
:
3488 return is_imm_within_range (oper
, 0, 3);
3489 case OPRND_TYPE_IMM2b_JMPIX
:
3490 /* ck802j support jmpix16, but not support jmpix32. */
3491 if (IS_CSKY_ARCH_802 (mach_flag
)
3492 && (op
->opcode
& 0xffff0000) != 0)
3494 SET_ERROR_STRING (ERROR_OPCODE_ILLEGAL
, NULL
);
3497 *oper
= parse_exp (*oper
, &csky_insn
.e1
);
3498 if (csky_insn
.e1
.X_op
== O_constant
)
3500 csky_insn
.opcode_end
= *oper
;
3501 if (csky_insn
.e1
.X_add_number
& 0x7)
3503 SET_ERROR_STRING (ERROR_JMPIX_OVER_RANGE
, NULL
);
3506 csky_insn
.val
[csky_insn
.idx
++]
3507 = (csky_insn
.e1
.X_add_number
>> 3) - 2;
3510 case OPRND_TYPE_IMM4b
:
3511 return is_imm_within_range (oper
, 0, 15);
3512 case OPRND_TYPE_IMM5b
:
3513 return is_imm_within_range (oper
, 0, 31);
3514 /* This type for "bgeni" in csky v1 ISA. */
3515 case OPRND_TYPE_IMM5b_7_31
:
3516 if (is_imm_within_range (oper
, 0, 31))
3518 int val
= csky_insn
.val
[csky_insn
.idx
- 1];
3519 /* immediate values of 0 -> 6 translate to movi. */
3522 const char *name
= "movi";
3523 csky_insn
.opcode
= (struct csky_opcode
*)
3524 str_hash_find (csky_opcodes_hash
, name
);
3525 csky_insn
.val
[csky_insn
.idx
- 1] = 1 << val
;
3532 case OPRND_TYPE_IMM5b_1_31
:
3533 return is_imm_within_range (oper
, 1, 31);
3534 case OPRND_TYPE_IMM5b_POWER
:
3535 if (is_imm_within_range_ext (oper
, 1, (1u << 31) - 1, 1u << 31))
3538 int val
= csky_insn
.val
[csky_insn
.idx
- 1];
3539 log
= csky_log_2 (val
);
3540 csky_insn
.val
[csky_insn
.idx
- 1] = log
;
3541 return (log
== -1 ? FALSE
: TRUE
);
3546 /* This type for "mgeni" in csky v1 ISA. */
3547 case OPRND_TYPE_IMM5b_7_31_POWER
:
3548 if (is_imm_within_range_ext (oper
, 1, (1u << 31) - 1, 1u << 31))
3551 int val
= csky_insn
.val
[csky_insn
.idx
- 1];
3552 log
= csky_log_2 (val
);
3553 /* Immediate values of 0 -> 6 translate to movi. */
3556 const char *name
= "movi";
3557 csky_insn
.opcode
= (struct csky_opcode
*)
3558 str_hash_find (csky_opcodes_hash
, name
);
3559 as_warn (_("translating mgeni to movi"));
3562 csky_insn
.val
[csky_insn
.idx
- 1] = log
;
3563 return (log
== -1 ? FALSE
: TRUE
);
3568 case OPRND_TYPE_IMM5b_RORI
:
3570 unsigned max_shift
= IS_CSKY_V1 (mach_flag
) ? 31 : 32;
3572 if (is_imm_within_range (oper
, 1, max_shift
))
3574 int i
= csky_insn
.idx
- 1;
3575 csky_insn
.val
[i
] = 32 - csky_insn
.val
[i
];
3582 case OPRND_TYPE_IMM5b_BMASKI
:
3583 /* For csky v1 bmask inst. */
3585 if (!is_imm_within_range_ext (oper
, 8, 31, 0))
3587 unsigned int mask_val
= csky_insn
.val
[csky_insn
.idx
- 1];
3588 if (mask_val
> 0 && mask_val
< 8)
3590 const char *op_movi
= "movi";
3591 csky_insn
.opcode
= (struct csky_opcode
*)
3592 str_hash_find (csky_opcodes_hash
, op_movi
);
3593 if (csky_insn
.opcode
== NULL
)
3595 csky_insn
.val
[csky_insn
.idx
- 1] = (1 << mask_val
) - 1;
3601 case OPRND_TYPE_IMM8b_BMASKI
:
3602 /* For csky v2 bmask, which will transfer to 16bits movi. */
3603 if (is_imm_within_range (oper
, 1, 8))
3605 unsigned int mask_val
= csky_insn
.val
[csky_insn
.idx
- 1];
3606 csky_insn
.val
[csky_insn
.idx
- 1] = (1 << mask_val
) - 1;
3610 case OPRND_TYPE_OIMM4b
:
3611 return is_oimm_within_range (oper
, 1, 16);
3612 case OPRND_TYPE_OIMM5b
:
3613 return is_oimm_within_range (oper
, 1, 32);
3614 case OPRND_TYPE_OIMM5b_IDLY
:
3615 if (is_imm_within_range (oper
, 0, 32))
3617 /* imm5b for idly n: 0<=n<4, imm5b=3; 4<=n<=32, imm5b=n-1. */
3618 unsigned long imm
= csky_insn
.val
[csky_insn
.idx
- 1];
3621 csky_show_error (WARNING_IDLY
, 0, (void *)imm
, NULL
);
3625 csky_insn
.val
[csky_insn
.idx
- 1] = imm
;
3631 /* For csky v2 bmask inst. */
3632 case OPRND_TYPE_OIMM5b_BMASKI
:
3633 if (!is_oimm_within_range (oper
, 17, 32))
3635 int mask_val
= csky_insn
.val
[csky_insn
.idx
- 1];
3636 if (mask_val
+ 1 == 0)
3638 if (mask_val
> 0 && mask_val
< 16)
3640 const char *op_movi
= "movi";
3641 csky_insn
.opcode
= (struct csky_opcode
*)
3642 str_hash_find (csky_opcodes_hash
, op_movi
);
3643 if (csky_insn
.opcode
== NULL
)
3645 csky_insn
.val
[csky_insn
.idx
- 1] = (1 << (mask_val
+ 1)) - 1;
3650 case OPRND_TYPE_IMM7b
:
3651 return is_imm_within_range (oper
, 0, 127);
3652 case OPRND_TYPE_IMM8b
:
3653 return is_imm_within_range (oper
, 0, 255);
3654 case OPRND_TYPE_IMM9b
:
3655 return is_imm_within_range (oper
, -256, 255);
3656 case OPRND_TYPE_IMM12b
:
3657 return is_imm_within_range (oper
, 0, 4095);
3658 case OPRND_TYPE_IMM15b
:
3659 return is_imm_within_range (oper
, 0, 0xfffff);
3660 case OPRND_TYPE_IMM16b
:
3661 return is_imm_within_range (oper
, 0, 65535);
3662 case OPRND_TYPE_OIMM16b
:
3663 return is_oimm_within_range (oper
, 1, 65536);
3664 case OPRND_TYPE_IMM32b
:
3667 char *new_oper
= parse_exp (*oper
, &e
);
3668 if (e
.X_op
== O_constant
)
3671 csky_insn
.val
[csky_insn
.idx
++] = e
.X_add_number
;
3676 case OPRND_TYPE_IMM16b_MOVIH
:
3677 case OPRND_TYPE_IMM16b_ORI
:
3679 bfd_reloc_code_real_type r
= BFD_RELOC_NONE
;
3682 char * save
= input_line_pointer
;
3683 /* get the reloc type, and set "@GOTxxx" as ' ' */
3684 while (**oper
!= '@' && **oper
!= '\0')
3688 input_line_pointer
= *oper
;
3690 while (*(*oper
+ len
+ 1) != '\0')
3692 **oper
= *(*oper
+ len
+ 1);
3693 *(*oper
+ len
+ 1) = '\0';
3698 input_line_pointer
= save
;
3699 *oper
= parse_exp (curr
, &csky_insn
.e1
);
3702 case OPRND_TYPE_PSR_BITS_LIST
:
3705 if (csky_insn
.number
== 0)
3709 csky_insn
.val
[csky_insn
.idx
] = 0;
3710 if (is_psr_bit (oper
) != FALSE
)
3711 while (**oper
== ',')
3714 if (is_psr_bit (oper
) == FALSE
)
3722 if (ret
== TRUE
&& IS_CSKY_V1 (mach_flag
)
3723 && csky_insn
.val
[csky_insn
.idx
] > 8)
3727 SET_ERROR_STRING (ERROR_OPERANDS_ILLEGAL
, csky_insn
.opcode_end
);
3732 /* FPU round mode. */
3733 static const char *round_mode
[] =
3742 for (i
= 0; round_mode
[i
]; i
++)
3743 if (strncasecmp (*oper
, round_mode
[i
], strlen (round_mode
[i
])) == 0)
3745 *oper
+= strlen (round_mode
[i
]);
3746 csky_insn
.val
[csky_insn
.idx
++] = i
;
3752 case OPRND_TYPE_REGLIST_COMMA
:
3753 case OPRND_TYPE_BRACKET
:
3754 /* TODO: using sub operand union. */
3755 case OPRND_TYPE_ABRACKET
:
3756 /* TODO: using sub operand union. */
3757 case OPRND_TYPE_REGLIST_DASH
:
3758 return is_reglist_legal (oper
);
3759 case OPRND_TYPE_FREGLIST_DASH
:
3760 return is_freglist_legal (oper
);
3761 case OPRND_TYPE_AREG_WITH_BRACKET
:
3767 SET_ERROR_STRING (ERROR_MISSING_LBRACKET
, NULL
);
3771 reg
= csky_get_reg_val (*oper
, &len
);
3774 SET_ERROR_STRING (ERROR_EXP_GREG
, NULL
);
3780 SET_ERROR_STRING (ERROR_MISSING_RBRACKET
, NULL
);
3784 csky_insn
.val
[csky_insn
.idx
++] = reg
;
3787 case OPRND_TYPE_REGsp
:
3788 return is_reg_sp (oper
);
3789 case OPRND_TYPE_REGbsp
:
3790 return is_reg_sp_with_bracket (oper
);
3792 case OPRND_TYPE_OFF8b
:
3793 case OPRND_TYPE_OFF16b
:
3794 *oper
= parse_rt (*oper
, 1, &csky_insn
.e1
, -1);
3795 csky_insn
.val
[csky_insn
.idx
++] = 0;
3797 case OPRND_TYPE_LABEL_WITH_BRACKET
:
3798 case OPRND_TYPE_CONSTANT
:
3799 case OPRND_TYPE_ELRW_CONSTANT
:
3801 csky_insn
.val
[csky_insn
.idx
++] = 0;
3803 csky_insn
.val
[csky_insn
.idx
++] = NEED_OUTPUT_LITERAL
;
3804 *oper
= parse_rt (*oper
, 0, &csky_insn
.e1
, -1);
3806 case OPRND_TYPE_FCONSTANT
:
3807 *oper
= parse_rtf (*oper
, 0, &csky_insn
.e1
);
3810 case OPRND_TYPE_SFLOAT
:
3811 case OPRND_TYPE_DFLOAT
:
3812 /* For fmovis and fmovid, which accept a constant float with
3818 *oper
= parse_fexp (*oper
, &csky_insn
.e1
, 1, &dbnum
);
3819 if (csky_insn
.e1
.X_op
== O_absent
)
3822 /* Convert the representation from IEEE double to the 13-bit
3823 encoding used internally for fmovis and fmovid. */
3824 imm4
= 11 - (((dbnum
& 0x7ff0000000000000ULL
) >> 52) - 1023);
3825 /* Check float range. */
3826 if ((dbnum
& 0x00000fffffffffffULL
) || imm4
< 0 || imm4
> 15)
3828 csky_show_error (ERROR_IMM_OVERFLOW
, 2, NULL
, NULL
);
3831 imm8
= (dbnum
& 0x000ff00000000000ULL
) >> 44;
3832 csky_insn
.e1
.X_add_number
3833 = (((imm8
& 0xf) << 4)
3834 | ((imm8
& 0xf0) << 17)
3835 | ((imm4
& 0xf) << 16)
3836 | ((dbnum
& 0x8000000000000000ULL
) >> 43));
3839 case OPRND_TYPE_HFLOAT_FMOVI
:
3840 case OPRND_TYPE_SFLOAT_FMOVI
:
3841 case OPRND_TYPE_DFLOAT_FMOVI
:
3842 /* For fpuv3 fmovis and fmovid, which accept a constant
3843 float with a limited range. */
3846 int imm4
, imm8
, sign
;
3848 *oper
= parse_fexp (*oper
, &csky_insn
.e1
, 1, &dbnum
);
3849 if (csky_insn
.e1
.X_op
== O_absent
)
3852 /* Convert the representation from IEEE double to the 13-bit
3853 encoding used internally for fmovis and fmovid. */
3854 imm4
= 11 - (((dbnum
& 0x7ff0000000000000ULL
) >> 52) - 1023);
3855 /* Check float range. */
3856 if ((dbnum
& 0x00000fffffffffffULL
) || imm4
< 0 || imm4
> 15)
3858 csky_show_error (ERROR_IMM_OVERFLOW
, 2, NULL
, NULL
);
3861 imm8
= (dbnum
& 0x000ff00000000000ULL
) >> 44;
3862 sign
= (dbnum
& 0x8000000000000000ULL
) >> 58;
3863 csky_insn
.e1
.X_add_number
3864 = (((imm8
& 0x3) << 8)
3865 | ((imm8
& 0xfc) << 18)
3866 | ((imm4
& 0xf) << 16)
3871 case OPRND_TYPE_IMM_OFF18b
:
3872 *oper
= parse_exp (*oper
, &csky_insn
.e1
);
3875 case OPRND_TYPE_BLOOP_OFF4b
:
3876 *oper
= parse_exp (*oper
, &csky_insn
.e2
);
3877 if (csky_insn
.e2
.X_op
== O_symbol
)
3879 csky_insn
.opcode_end
= *oper
;
3885 case OPRND_TYPE_BLOOP_OFF12b
:
3886 case OPRND_TYPE_OFF10b
:
3887 case OPRND_TYPE_OFF11b
:
3888 case OPRND_TYPE_OFF16b_LSL1
:
3889 case OPRND_TYPE_OFF26b
:
3890 *oper
= parse_exp (*oper
, &csky_insn
.e1
);
3891 if (csky_insn
.e1
.X_op
== O_symbol
)
3893 csky_insn
.opcode_end
= *oper
;
3898 /* For xtrb0(1)(2)(3) and div in csky v1 ISA. */
3899 case OPRND_TYPE_REG_r1a
:
3903 reg
= csky_get_reg_val (*oper
, &len
);
3906 SET_ERROR_STRING (ERROR_REG_FORMAT
,
3907 "The first operand must be register r1.");
3911 mov_r1_after
= TRUE
;
3913 csky_insn
.opcode_end
= *oper
;
3914 csky_insn
.val
[csky_insn
.idx
++] = reg
;
3917 case OPRND_TYPE_REG_r1b
:
3921 reg
= csky_get_reg_val (*oper
, &len
);
3924 SET_ERROR_STRING (ERROR_REG_FORMAT
,
3925 "The second operand must be register r1.");
3930 unsigned int mov_insn
= CSKYV1_INST_MOV_R1_RX
;
3931 mov_insn
|= reg
<< 4;
3932 mov_r1_before
= TRUE
;
3933 csky_insn
.output
= frag_more (2);
3934 dwarf2_emit_insn (0);
3935 md_number_to_chars (csky_insn
.output
, mov_insn
, 2);
3938 csky_insn
.opcode_end
= *oper
;
3939 csky_insn
.val
[csky_insn
.idx
++] = reg
;
3942 case OPRND_TYPE_DUMMY_REG
:
3946 reg
= csky_get_reg_val (*oper
, &len
);
3949 SET_ERROR_STRING (ERROR_GREG_ILLEGAL
, NULL
);
3952 if (reg
!= csky_insn
.val
[0])
3954 SET_ERROR_STRING (ERROR_REG_FORMAT
,
3955 "The second register must be the same as the first.");
3959 csky_insn
.opcode_end
= *oper
;
3960 csky_insn
.val
[csky_insn
.idx
++] = reg
;
3963 case OPRND_TYPE_2IN1_DUMMY
:
3969 reg
= csky_get_reg_val (*oper
, &len
);
3972 SET_ERROR_STRING (ERROR_GREG_ILLEGAL
, NULL
);
3975 /* dummy reg's real type should be same with first operand. */
3976 if (op
->oprnd
.oprnds
[0].type
== OPRND_TYPE_GREG0_15
)
3978 else if (op
->oprnd
.oprnds
[0].type
== OPRND_TYPE_GREG0_7
)
3982 if (reg
< min
|| reg
> max
)
3984 csky_insn
.val
[csky_insn
.idx
++] = reg
;
3985 /* if it is the last operands. */
3986 if (csky_insn
.idx
> 2)
3988 /* For "insn rz, rx, ry", if rx or ry is equal to rz,
3989 we can output the insn like "insn rz, rx". */
3990 if (csky_insn
.val
[0] == csky_insn
.val
[1])
3991 csky_insn
.val
[1] = 0;
3992 else if (csky_insn
.val
[0] == csky_insn
.val
[2])
3993 csky_insn
.val
[2] = 0;
3998 csky_insn
.opcode_end
= *oper
;
4001 case OPRND_TYPE_DUP_GREG0_7
:
4002 case OPRND_TYPE_DUP_GREG0_15
:
4003 case OPRND_TYPE_DUP_AREG
:
4008 unsigned int shift_num
;
4009 if (oprnd
->type
== OPRND_TYPE_DUP_GREG0_7
)
4014 else if (oprnd
->type
== OPRND_TYPE_DUP_GREG0_15
)
4024 reg
= csky_get_reg_val (*oper
, &len
);
4028 SET_ERROR_STRING (ERROR_REG_FORMAT
,
4029 "The register must be r0-r31");
4031 SET_ERROR_STRING (ERROR_REG_FORMAT
,
4032 "The register must be r0-r15");
4037 SET_ERROR_STRING (ERROR_REG_OVER_RANGE
, reg
);
4040 reg
|= reg
<< shift_num
;
4042 csky_insn
.opcode_end
= *oper
;
4043 csky_insn
.val
[csky_insn
.idx
++] = reg
;
4046 case OPRND_TYPE_CONST1
:
4047 *oper
= parse_exp (*oper
, &csky_insn
.e1
);
4048 if (csky_insn
.e1
.X_op
== O_constant
)
4050 csky_insn
.opcode_end
= *oper
;
4051 if (csky_insn
.e1
.X_add_number
!= 1)
4053 csky_insn
.val
[csky_insn
.idx
++] = 1;
4057 case OPRND_TYPE_UNCOND10b
:
4058 case OPRND_TYPE_UNCOND16b
:
4059 *oper
= parse_exp (*oper
, &csky_insn
.e1
);
4060 if (csky_insn
.e1
.X_op
== O_constant
)
4062 input_line_pointer
= *oper
;
4063 csky_insn
.opcode_end
= *oper
;
4064 csky_insn
.relax
.max
= UNCD_DISP16_LEN
;
4065 csky_insn
.relax
.var
= UNCD_DISP10_LEN
;
4066 csky_insn
.relax
.subtype
= UNCD_DISP10
;
4067 csky_insn
.val
[csky_insn
.idx
++] = 0;
4069 case OPRND_TYPE_COND10b
:
4070 case OPRND_TYPE_COND16b
:
4071 *oper
= parse_exp (*oper
, &csky_insn
.e1
);
4072 if (csky_insn
.e1
.X_op
== O_constant
)
4074 input_line_pointer
= *oper
;
4075 csky_insn
.opcode_end
= *oper
;
4076 /* CK801 doesn't have 32-bit bt/bf insns; relax to a short
4077 jump around a 32-bit unconditional branch instead. */
4078 if (IS_CSKY_ARCH_801 (mach_flag
))
4080 csky_insn
.relax
.max
= SCOND_DISP16_LEN
;
4081 csky_insn
.relax
.var
= SCOND_DISP10_LEN
;
4082 csky_insn
.relax
.subtype
= SCOND_DISP10
;
4086 csky_insn
.relax
.max
= COND_DISP16_LEN
;
4087 csky_insn
.relax
.var
= COND_DISP10_LEN
;
4088 csky_insn
.relax
.subtype
= COND_DISP10
;
4090 csky_insn
.val
[csky_insn
.idx
++] = 0;
4092 case OPRND_TYPE_JCOMPZ
:
4093 *oper
= parse_exp (*oper
, &csky_insn
.e1
);
4094 if (csky_insn
.e1
.X_op
== O_constant
)
4096 input_line_pointer
= *oper
;
4097 csky_insn
.opcode_end
= *oper
;
4098 csky_insn
.relax
.max
= JCOMPZ_DISP32_LEN
;
4099 csky_insn
.relax
.var
= JCOMPZ_DISP16_LEN
;
4100 csky_insn
.relax
.subtype
= JCOMPZ_DISP16
;
4101 csky_insn
.max
= JCOMPZ_DISP32_LEN
;
4102 csky_insn
.val
[csky_insn
.idx
++] = 0;
4104 case OPRND_TYPE_JBTF
:
4105 *oper
= parse_exp (*oper
, &csky_insn
.e1
);
4106 input_line_pointer
= *oper
;
4107 csky_insn
.opcode_end
= *oper
;
4108 csky_insn
.relax
.max
= csky_relax_table
[C (COND_JUMP_S
, DISP32
)].rlx_length
;
4109 csky_insn
.relax
.var
= csky_relax_table
[C (COND_JUMP_S
, DISP12
)].rlx_length
;
4110 csky_insn
.relax
.subtype
= C (COND_JUMP_S
, 0);
4111 csky_insn
.val
[csky_insn
.idx
++] = 0;
4112 csky_insn
.max
= C32_LEN_S
+ 2;
4114 case OPRND_TYPE_JBR
:
4115 *oper
= parse_exp (*oper
, &csky_insn
.e1
);
4116 input_line_pointer
= *oper
;
4117 csky_insn
.opcode_end
= *oper
;
4118 csky_insn
.relax
.max
= csky_relax_table
[C (UNCD_JUMP_S
, DISP32
)].rlx_length
;
4119 csky_insn
.relax
.var
= csky_relax_table
[C (UNCD_JUMP_S
, DISP12
)].rlx_length
;
4120 csky_insn
.relax
.subtype
= C (UNCD_JUMP_S
, 0);
4121 csky_insn
.val
[csky_insn
.idx
++] = 0;
4122 csky_insn
.max
= U32_LEN_S
+ 2;
4124 case OPRND_TYPE_JBSR
:
4126 *oper
= parse_exp (*oper
, &csky_insn
.e1
);
4128 *oper
= parse_rt (*oper
, 1, &csky_insn
.e1
, -1);
4129 input_line_pointer
= *oper
;
4130 csky_insn
.opcode_end
= *oper
;
4131 csky_insn
.val
[csky_insn
.idx
++] = 0;
4133 case OPRND_TYPE_REGLIST_DASH_COMMA
:
4134 return is_reglist_dash_comma_legal (oper
, oprnd
);
4136 case OPRND_TYPE_MSB2SIZE
:
4137 case OPRND_TYPE_LSB2SIZE
:
4140 char *new_oper
= parse_exp (*oper
, &e
);
4141 if (e
.X_op
== O_constant
)
4144 if (e
.X_add_number
> 31)
4146 SET_ERROR_STRING (ERROR_IMM_OVERFLOW
, NULL
);
4149 csky_insn
.val
[csky_insn
.idx
++] = e
.X_add_number
;
4150 if (oprnd
->type
== OPRND_TYPE_LSB2SIZE
)
4152 if (csky_insn
.val
[csky_insn
.idx
- 1] > csky_insn
.val
[csky_insn
.idx
- 2])
4154 SET_ERROR_STRING (ERROR_IMM_OVERFLOW
, NULL
);
4157 csky_insn
.val
[csky_insn
.idx
- 2] -= e
.X_add_number
;
4163 case OPRND_TYPE_AREG_WITH_LSHIFT
:
4164 return is_reg_lshift_illegal (oper
, 0);
4165 case OPRND_TYPE_AREG_WITH_LSHIFT_FPU
:
4166 return is_reg_lshift_illegal (oper
, 1);
4167 case OPRND_TYPE_FREG_WITH_INDEX
:
4168 if (parse_type_freg (oper
, 0))
4173 if (is_imm_within_range (oper
, 0, 0xf))
4177 unsigned int idx
= --csky_insn
.idx
;
4178 unsigned int val
= csky_insn
.val
[idx
];
4180 csky_insn
.val
[idx
- 1] |= val
<< 4;
4184 SET_ERROR_STRING (ERROR_MISSING_RSQUARE_BRACKETS
, NULL
);
4188 SET_ERROR_STRING (ERROR_MISSING_LSQUARE_BRACKETS
, NULL
);
4199 /* Subroutine of parse_operands. */
4202 parse_operands_op (char *str
, struct csky_opcode_info
*op
)
4209 for (i
= 0; i
< OP_TABLE_NUM
&& op
[i
].operand_num
!= -2; i
++)
4214 /* if operand_num = -1, it is a insn with a REGLIST type operand.i. */
4215 if (!(op
[i
].operand_num
== csky_insn
.number
4216 || (op
[i
].operand_num
== -1 && csky_insn
.number
!= 0)))
4218 /* The smaller err_num is more serious. */
4219 SET_ERROR_INTEGER (ERROR_OPERANDS_NUMBER
, op
[i
].operand_num
);
4224 for (j
= 0; j
< csky_insn
.number
; j
++)
4226 while (ISSPACE (*oper
))
4228 flag_pass
= get_operand_value (&op
[i
], &oper
,
4229 &op
[i
].oprnd
.oprnds
[j
]);
4230 if (flag_pass
== FALSE
)
4232 while (ISSPACE (*oper
))
4235 if (j
< csky_insn
.number
- 1 && op
[i
].operand_num
!= -1)
4241 SET_ERROR_STRING (ERROR_MISSING_COMMA
, NULL
);
4246 else if (!is_end_of_line
[(unsigned char) *oper
])
4248 SET_ERROR_STRING (ERROR_BAD_END
, NULL
);
4255 /* Parse operands in one table end. */
4257 if (flag_pass
== TRUE
)
4259 /* Parse operands success, set opcode_idx. */
4260 csky_insn
.opcode_idx
= i
;
4264 error_state
.opnum
= j
+ 1;
4266 /* Parse operands in ALL tables end. */
4270 /* Parse the operands according to operand type. */
4273 parse_operands (char *str
)
4277 /* Parse operands according to flag_force. */
4278 if (csky_insn
.flag_force
== INSN_OPCODE16F
4279 && (csky_insn
.opcode
->isa_flag16
& isa_flag
) != 0)
4281 if (parse_operands_op (oper
, csky_insn
.opcode
->op16
) == TRUE
)
4283 csky_insn
.isize
= 2;
4288 else if (csky_insn
.flag_force
== INSN_OPCODE32F
4289 && (csky_insn
.opcode
->isa_flag32
& isa_flag
) != 0)
4291 if (parse_operands_op (oper
, csky_insn
.opcode
->op32
) == TRUE
)
4293 csky_insn
.isize
= 4;
4300 if ((csky_insn
.opcode
->isa_flag16
& isa_flag
) != 0
4301 && parse_operands_op (oper
, csky_insn
.opcode
->op16
) == TRUE
)
4303 csky_insn
.isize
= 2;
4306 if ((csky_insn
.opcode
->isa_flag32
& isa_flag
) != 0
4307 && parse_operands_op (oper
, csky_insn
.opcode
->op32
) == TRUE
)
4309 csky_insn
.isize
= 4;
4317 csky_generate_frags (void)
4319 /* frag more relax reloc. */
4320 if (csky_insn
.flag_force
== INSN_OPCODE16F
4321 || !IS_SUPPORT_OPCODE32 (csky_insn
.opcode
))
4323 csky_insn
.output
= frag_more (csky_insn
.isize
);
4324 if (csky_insn
.opcode
->reloc16
)
4326 /* 16 bits opcode force, should generate fixup. */
4327 reloc_howto_type
*howto
;
4328 howto
= bfd_reloc_type_lookup (stdoutput
,
4329 csky_insn
.opcode
->reloc16
);
4330 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
4331 2, &csky_insn
.e1
, howto
->pc_relative
,
4332 csky_insn
.opcode
->reloc16
);
4335 else if (csky_insn
.flag_force
== INSN_OPCODE32F
)
4337 csky_insn
.output
= frag_more (csky_insn
.isize
);
4338 if (csky_insn
.opcode
->reloc32
)
4340 reloc_howto_type
*howto
;
4341 howto
= bfd_reloc_type_lookup (stdoutput
,
4342 csky_insn
.opcode
->reloc32
);
4343 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
4344 4, &csky_insn
.e1
, howto
->pc_relative
,
4345 csky_insn
.opcode
->reloc32
);
4348 else if (csky_insn
.opcode
->relax
)
4349 /* Generate the relax information. */
4350 csky_insn
.output
= frag_var (rs_machine_dependent
,
4351 csky_insn
.relax
.max
,
4352 csky_insn
.relax
.var
,
4353 csky_insn
.relax
.subtype
,
4354 csky_insn
.e1
.X_add_symbol
,
4355 csky_insn
.e1
.X_add_number
, 0);
4358 csky_insn
.output
= frag_more (csky_insn
.isize
);
4359 if (csky_insn
.opcode
->reloc16
&& csky_insn
.isize
== 2)
4361 reloc_howto_type
*howto
;
4362 howto
= bfd_reloc_type_lookup (stdoutput
,
4363 csky_insn
.opcode
->reloc16
);
4364 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
4365 2, &csky_insn
.e1
, howto
->pc_relative
,
4366 csky_insn
.opcode
->reloc16
);
4368 else if (csky_insn
.opcode
->reloc32
&& csky_insn
.isize
== 4)
4370 reloc_howto_type
*howto
;
4371 howto
= bfd_reloc_type_lookup (stdoutput
,
4372 csky_insn
.opcode
->reloc32
);
4373 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
4374 4, &csky_insn
.e1
, howto
->pc_relative
,
4375 csky_insn
.opcode
->reloc32
);
4381 /* Return the bits of VAL shifted according to MASK. The bits of MASK
4382 need not be contiguous. */
4385 generate_masked_value (int mask
, int val
)
4390 for (bit
= 1; mask
; bit
= bit
<< 1)
4401 /* Return the result of masking operand number OPRND_IDX into the
4402 instruction word according to the information in OPRND. */
4405 generate_masked_operand (struct operand
*oprnd
, int *oprnd_idx
)
4407 struct soperand
*soprnd
= NULL
;
4410 if ((unsigned int)oprnd
->mask
== HAS_SUB_OPERAND
)
4412 soprnd
= (struct soperand
*) oprnd
;
4413 generate_masked_operand (&soprnd
->subs
[0], oprnd_idx
);
4414 generate_masked_operand (&soprnd
->subs
[1], oprnd_idx
);
4418 val
= csky_insn
.val
[*oprnd_idx
];
4420 val
= generate_masked_value (mask
, val
);
4421 csky_insn
.inst
|= val
;
4427 csky_generate_insn (void)
4430 struct csky_opcode_info
*opinfo
= NULL
;
4432 if (csky_insn
.isize
== 4)
4433 opinfo
= &csky_insn
.opcode
->op32
[csky_insn
.opcode_idx
];
4434 else if (csky_insn
.isize
== 2)
4435 opinfo
= &csky_insn
.opcode
->op16
[csky_insn
.opcode_idx
];
4438 csky_insn
.inst
= opinfo
->opcode
;
4439 if (opinfo
->operand_num
== -1)
4441 generate_masked_operand (&opinfo
->oprnd
.oprnds
[i
], &sidx
);
4445 for (i
= 0; i
< opinfo
->operand_num
; i
++)
4446 generate_masked_operand (&opinfo
->oprnd
.oprnds
[i
], &sidx
);
4450 /* Main entry point for assembling a single instruction. */
4453 md_assemble (char *str
)
4455 bfd_boolean must_check_literals
= TRUE
;
4456 csky_insn
.isize
= 0;
4459 csky_insn
.flag_force
= INSN_OPCODE
;
4460 csky_insn
.macro
= NULL
;
4461 csky_insn
.opcode
= NULL
;
4462 memset (csky_insn
.val
, 0, sizeof (int) * MAX_OPRND_NUM
);
4463 /* Initialize err_num. */
4464 error_state
.err_num
= ERROR_NONE
;
4465 mov_r1_before
= FALSE
;
4466 mov_r1_after
= FALSE
;
4468 mapping_state (MAP_TEXT
);
4469 /* Tie dwarf2 debug info to every insn if set option --gdwarf2. */
4470 dwarf2_emit_insn (0);
4471 while (ISSPACE (* str
))
4473 /* Get opcode from str. */
4474 if (parse_opcode (str
) == FALSE
)
4476 csky_show_error (ERROR_OPCODE_ILLEGAL
, 0, NULL
, NULL
);
4480 /* If it is a macro instruction, handle it. */
4481 if (csky_insn
.macro
!= NULL
)
4483 if (csky_insn
.number
== csky_insn
.macro
->oprnd_num
)
4485 csky_insn
.macro
->handle_func ();
4488 else if (error_state
.err_num
> ERROR_OPERANDS_NUMBER
)
4489 SET_ERROR_STRING (ERROR_OPERANDS_NUMBER
, csky_insn
.macro
->oprnd_num
);
4492 if (csky_insn
.opcode
== NULL
)
4494 SET_ERROR_STRING (ERROR_OPCODE_ILLEGAL
, NULL
);
4495 csky_show_error (error_state
.err_num
, error_state
.opnum
,
4496 (void *)error_state
.arg1
, (void *)error_state
.arg1
);
4500 /* Parse the operands according to operand type. */
4501 if (parse_operands (csky_insn
.opcode_end
) == FALSE
)
4503 csky_show_error (error_state
.err_num
, error_state
.opnum
,
4504 (void *)error_state
.arg1
, (void *)error_state
.arg1
);
4508 /* if this insn has work in opcode table, then do it. */
4509 if (csky_insn
.opcode
->work
!= NULL
)
4510 must_check_literals
= csky_insn
.opcode
->work ();
4513 /* Generate relax or reloc if necessary. */
4514 csky_generate_frags ();
4515 /* Generate the insn by mask. */
4516 csky_generate_insn ();
4517 /* Write inst to frag. */
4518 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
4521 /* Adjust for xtrb0/xtrb1/xtrb2/xtrb3/divs/divu in csky v1 ISA. */
4522 if (mov_r1_after
== TRUE
)
4524 unsigned int mov_insn
= CSKYV1_INST_MOV_RX_R1
;
4525 mov_insn
|= csky_insn
.val
[0];
4526 mov_r1_before
= TRUE
;
4527 csky_insn
.output
= frag_more (2);
4528 dwarf2_emit_insn (0);
4529 md_number_to_chars (csky_insn
.output
, mov_insn
, 2);
4530 csky_insn
.isize
+= 2;
4532 if (mov_r1_before
== TRUE
)
4533 csky_insn
.isize
+= 2;
4535 /* Check literal. */
4536 if (must_check_literals
)
4538 if (csky_insn
.max
== 0)
4539 check_literals (csky_insn
.opcode
->transfer
, csky_insn
.isize
);
4541 check_literals (csky_insn
.opcode
->transfer
, csky_insn
.max
);
4544 csky_insn
.last_isize
= csky_insn
.isize
;
4545 insn_reloc
= BFD_RELOC_NONE
;
4548 /* Attempt to handle option with value C, returning non-zero on success. */
4551 md_parse_option (int c
, const char *arg
)
4563 case OPTION_FLOAT_ABI
:
4564 parse_float_abi (arg
);
4572 /* Convert a machine dependent frag. */
4573 #define PAD_LITERAL_LENGTH 6
4574 #define opposite_of_stored_comp(insn) (insn ^ 0x04000000)
4575 #define opposite_of_stored_compz(insn) (insn ^ 0x00200000)
4576 #define make_insn(total_length, opcode, operand, operand_length) \
4578 if (total_length > 0) \
4580 csky_write_insn (buf, \
4581 opcode | (operand & ((1 << operand_length) - 1)), \
4583 buf += total_length; \
4584 fragp->fr_fix += total_length; \
4588 #define make_literal(fragp, literal_offset) \
4590 make_insn (literal_offset, PAD_FILL_CONTENT, 0, 0); \
4591 fix_new (fragp, fragp->fr_fix, 4, fragp->fr_symbol, \
4592 fragp->fr_offset, 0, BFD_RELOC_CKCORE_ADDR32); \
4593 make_insn (4, 0, 0, 0); \
4594 make_insn (2 - literal_offset, PAD_FILL_CONTENT, 0, 0); \
4598 md_convert_frag (bfd
*abfd ATTRIBUTE_UNUSED
, segT asec
, fragS
*fragp
)
4601 char *buf
= fragp
->fr_fix
+ &fragp
->fr_literal
[0];
4603 gas_assert (fragp
->fr_symbol
);
4604 if (IS_EXTERNAL_SYM (fragp
->fr_symbol
, asec
))
4607 disp
= (S_GET_VALUE (fragp
->fr_symbol
)
4612 switch (fragp
->fr_subtype
)
4614 /* generate new insn. */
4615 case C (COND_JUMP
, DISP12
):
4616 case C (UNCD_JUMP
, DISP12
):
4617 case C (COND_JUMP_PIC
, DISP12
):
4618 case C (UNCD_JUMP_PIC
, DISP12
):
4620 #define CSKY_V1_B_MASK 0xf8
4625 /* Error. odd displacement at %x, next_inst-2. */
4630 if (!target_big_endian
)
4632 t0
= buf
[1] & CSKY_V1_B_MASK
;
4633 md_number_to_chars (buf
, disp
, 2);
4634 buf
[1] = (buf
[1] & ~CSKY_V1_B_MASK
) | t0
;
4638 t0
= buf
[0] & CSKY_V1_B_MASK
;
4639 md_number_to_chars (buf
, disp
, 2);
4640 buf
[0] = (buf
[0] & ~CSKY_V1_B_MASK
) | t0
;
4645 case C (COND_JUMP
, DISP32
):
4646 case C (COND_JUMP
, UNDEF_WORD_DISP
):
4648 /* A conditional branch wont fit into 12 bits:
4655 int first_inst
= fragp
->fr_fix
+ fragp
->fr_address
;
4656 int is_unaligned
= (first_inst
& 3);
4658 if (!target_big_endian
)
4660 /* b!cond instruction. */
4662 /* jmpi instruction. */
4663 buf
[2] = CSKYV1_INST_JMPI
& 0xff;
4664 buf
[3] = CSKYV1_INST_JMPI
>> 8;
4668 /* b!cond instruction. */
4670 /* jmpi instruction. */
4671 buf
[2] = CSKYV1_INST_JMPI
>> 8;
4672 buf
[3] = CSKYV1_INST_JMPI
& 0xff;
4677 if (!target_big_endian
)
4679 /* bt/bf: jump to pc + 2 + (4 << 1). */
4681 /* jmpi: jump to MEM (pc + 2 + (1 << 2)). */
4686 /* bt/bf: jump to pc + 2 + (4 << 1). */
4688 /* jmpi: jump to MEM (pc + 2 + (1 << 2)). */
4691 /* Aligned 4 bytes. */
4700 /* Make reloc for the long disp. */
4701 fix_new (fragp
, fragp
->fr_fix
+ 6, 4,
4702 fragp
->fr_symbol
, fragp
->fr_offset
, 0, BFD_RELOC_32
);
4703 fragp
->fr_fix
+= C32_LEN
;
4707 if (!target_big_endian
)
4709 /* bt/bf: jump to pc + 2 + (3 << 1). */
4711 /* jmpi: jump to MEM (pc + 2 + (0 << 2)). */
4716 /* bt/bf: jump to pc + 2 + (3 << 1). */
4718 /* jmpi: jump to MEM (pc + 2 + (0 << 2)). */
4727 /* Make reloc for the long disp. */
4728 fix_new (fragp
, fragp
->fr_fix
+ 4, 4,
4729 fragp
->fr_symbol
, fragp
->fr_offset
, 0, BFD_RELOC_32
);
4730 fragp
->fr_fix
+= C32_LEN
;
4732 /* Frag is actually shorter (see the other side of this ifdef)
4733 but gas isn't prepared for that. We have to re-adjust
4734 the branch displacement so that it goes beyond the
4735 full length of the fragment, not just what we actually
4737 if (!target_big_endian
)
4745 case C (COND_JUMP_PIC
, DISP32
):
4746 case C (COND_JUMP_PIC
, UNDEF_WORD_DISP
):
4748 #define BYTE_1(a) (target_big_endian ? ((a) & 0xff) : ((a) >> 8))
4749 #define BYTE_0(a) (target_big_endian ? ((a) >> 8) : ((a) & 0xff))
4760 0: .long (tar_addr - pc)
4763 int first_inst
= fragp
->fr_fix
+ fragp
->fr_address
;
4764 int is_unaligned
= (first_inst
& 3);
4766 /* Toggle T/F bit. */
4767 if (! target_big_endian
)
4771 buf
[2] = BYTE_0 (CSKYV1_INST_SUBI
| (7 << 4)); /* subi r0, 8. */
4772 buf
[3] = BYTE_1 (CSKYV1_INST_SUBI
| (7 << 4));
4773 buf
[4] = BYTE_0 (CSKYV1_INST_STW
| (15 << 8)); /* stw r15, r0. */
4774 buf
[5] = BYTE_1 (CSKYV1_INST_STW
| (15 << 8));
4775 buf
[6] = BYTE_0 (CSKYV1_INST_BSR
); /* bsr pc + 2. */
4776 buf
[7] = BYTE_1 (CSKYV1_INST_BSR
);
4777 buf
[8] = BYTE_0 (CSKYV1_INST_LRW
| (1 << 8)); /* lrw r1, (tar_addr - pc). */
4778 buf
[9] = BYTE_1 (CSKYV1_INST_LRW
| (1 << 8));
4779 buf
[10] = BYTE_0 (CSKYV1_INST_ADDU
| (15 << 4) | 1); /* add r1, r15. */
4780 buf
[11] = BYTE_1 (CSKYV1_INST_ADDU
| (15 << 4) | 1);
4781 buf
[12] = BYTE_0 (CSKYV1_INST_LDW
| (15 << 8)); /* ldw r15, r0. */
4782 buf
[13] = BYTE_1 (CSKYV1_INST_LDW
| (15 << 8));
4783 buf
[14] = BYTE_0 (CSKYV1_INST_ADDI
| (7 << 4)); /* addi r0, 8. */
4784 buf
[15] = BYTE_1 (CSKYV1_INST_ADDI
| (7 << 4));
4785 buf
[16] = BYTE_0 (CSKYV1_INST_JMP
| 1); /* jmp r1. */
4786 buf
[17] = BYTE_1 (CSKYV1_INST_JMP
| 1);
4790 if (!target_big_endian
)
4794 buf
[20] = disp
& 0xff;
4795 buf
[21] = (disp
>> 8) & 0xff;
4796 buf
[22] = (disp
>> 16) & 0xff;
4797 buf
[23] = (disp
>> 24) & 0xff;
4799 else /* if !target_big_endian. */
4803 buf
[20] = (disp
>> 24) & 0xff;
4804 buf
[21] = (disp
>> 16) & 0xff;
4805 buf
[22] = (disp
>> 8) & 0xff;
4806 buf
[23] = disp
& 0xff;
4808 buf
[18] = 0; /* alignment. */
4810 fragp
->fr_fix
+= C32_LEN_PIC
;
4812 else /* if !is_unaligned. */
4814 if (!target_big_endian
)
4818 buf
[18] = disp
& 0xff;
4819 buf
[19] = (disp
>> 8) & 0xff;
4820 buf
[20] = (disp
>> 16) & 0xff;
4821 buf
[21] = (disp
>> 24) & 0xff;
4823 else /* if !target_big_endian. */
4827 buf
[18] = (disp
>> 24) & 0xff;
4828 buf
[19] = (disp
>> 16) & 0xff;
4829 buf
[20] = (disp
>> 8) & 0xff;
4830 buf
[21] = disp
& 0xff;
4832 buf
[22] = 0; /* initialise. */
4834 fragp
->fr_fix
+= C32_LEN_PIC
;
4836 } /* end if is_unaligned. */
4837 } /* end case C (COND_JUMP_PIC, DISP32)/C (COND_JUMP_PIC, UNDEF_WORD_DISP). */
4839 case C (UNCD_JUMP
, DISP32
):
4840 case C (UNCD_JUMP
, UNDEF_WORD_DISP
):
4845 int first_inst
= fragp
->fr_fix
+ fragp
->fr_address
;
4846 int is_unaligned
= (first_inst
& 3);
4848 buf
[0] = BYTE_0 (CSKYV1_INST_JMPI
);
4849 buf
[1] = BYTE_1 (CSKYV1_INST_JMPI
);
4852 if (!target_big_endian
)
4864 fix_new (fragp
, fragp
->fr_fix
+ 4, 4,
4865 fragp
->fr_symbol
, fragp
->fr_offset
, 0, BFD_RELOC_32
);
4866 fragp
->fr_fix
+= U32_LEN
;
4868 else /* if is_unaligned. */
4870 if (!target_big_endian
)
4879 fix_new (fragp
, fragp
->fr_fix
+ 2, 4,
4880 fragp
->fr_symbol
, fragp
->fr_offset
, 0, BFD_RELOC_32
);
4881 fragp
->fr_fix
+= U32_LEN
;
4886 case C (UNCD_JUMP_PIC
, DISP32
):
4887 case C (UNCD_JUMP_PIC
, UNDEF_WORD_DISP
):
4899 0: .long (tar_add - pc)
4902 /* If the b!cond is 4 byte aligned, the literal which would
4903 go at x+4 will also be aligned. */
4904 int first_inst
= fragp
->fr_fix
+ fragp
->fr_address
;
4905 int is_unaligned
= (first_inst
& 3);
4908 buf
[0] = BYTE_0 (CSKYV1_INST_SUBI
| (7 << 4)); /* subi r0, 8. */
4909 buf
[1] = BYTE_1 (CSKYV1_INST_SUBI
| (7 << 4));
4910 buf
[2] = BYTE_0 (CSKYV1_INST_STW
| (15 << 8)); /* stw r15, r0. */
4911 buf
[3] = BYTE_1 (CSKYV1_INST_STW
| (15 << 8));
4912 buf
[4] = BYTE_0 (CSKYV1_INST_BSR
); /* bsr pc + 2. */
4913 buf
[5] = BYTE_1 (CSKYV1_INST_BSR
);
4914 buf
[6] = BYTE_0 (CSKYV1_INST_LRW
| (1 << 8)); /* lrw r1, (tar_addr - pc). */
4915 buf
[7] = BYTE_1 (CSKYV1_INST_LRW
| (1 << 8));
4916 buf
[8] = BYTE_0 (CSKYV1_INST_ADDU
| (15 << 4) | 1); /* add r1, r15. */
4917 buf
[9] = BYTE_1 (CSKYV1_INST_ADDU
| (15 << 4) | 1);
4918 buf
[10] = BYTE_0 (CSKYV1_INST_LDW
| (15 << 8)); /* ldw r15, r0. */
4919 buf
[11] = BYTE_1 (CSKYV1_INST_LDW
| (15 << 8));
4920 buf
[12] = BYTE_0 (CSKYV1_INST_ADDI
| (7 << 4)); /* addi r0, 8. */
4921 buf
[13] = BYTE_1 (CSKYV1_INST_ADDI
| (7 << 4));
4922 buf
[14] = BYTE_0 (CSKYV1_INST_JMP
| 1); /* jmp r1. */
4923 buf
[15] = BYTE_1 (CSKYV1_INST_JMP
| 1);
4927 if (!target_big_endian
)
4930 buf
[18] = disp
& 0xff;
4931 buf
[19] = (disp
>> 8) & 0xff;
4932 buf
[20] = (disp
>> 16) & 0xff;
4933 buf
[21] = (disp
>> 24) & 0xff;
4938 buf
[18] = (disp
>> 24) & 0xff;
4939 buf
[19] = (disp
>> 16) & 0xff;
4940 buf
[20] = (disp
>> 8) & 0xff;
4941 buf
[21] = disp
& 0xff;
4945 fragp
->fr_fix
+= U32_LEN_PIC
;
4949 if (!target_big_endian
)
4952 buf
[16] = disp
& 0xff;
4953 buf
[17] = (disp
>> 8) & 0xff;
4954 buf
[18] = (disp
>> 16) & 0xff;
4955 buf
[19] = (disp
>> 24) & 0xff;
4960 buf
[16] = (disp
>> 24) & 0xff;
4961 buf
[17] = (disp
>> 16) & 0xff;
4962 buf
[18] = (disp
>> 8) & 0xff;
4963 buf
[19] = disp
& 0xff;
4965 fragp
->fr_fix
+= U32_LEN_PIC
;
4975 unsigned int inst
= csky_read_insn (buf
, 2);
4976 inst
|= (disp
>> 1) & ((1 << 10) - 1);
4977 csky_write_insn (buf
, inst
, 2);
4983 unsigned int inst
= csky_read_insn (buf
, 2);
4985 if (inst
== CSKYV2_INST_BT16
)
4986 inst
= CSKYV2_INST_BF16
;
4988 inst
= CSKYV2_INST_BT16
;
4989 make_insn (2, inst
, (2 + 4) >> 1, 10);
4990 if (IS_EXTERNAL_SYM (fragp
->fr_symbol
, asec
))
4991 fix_new (fragp
, fragp
->fr_fix
, 4,
4992 fragp
->fr_symbol
, fragp
->fr_offset
, 1,
4993 BFD_RELOC_CKCORE_PCREL_IMM16BY2
);
4995 inst
= CSKYV2_INST_BR32
| ((disp
>> 1) & ((1 << 16) - 1));
4996 csky_write_insn (buf
, inst
, 4);
5003 unsigned int inst
= csky_read_insn (buf
, 2);
5005 if (inst
== CSKYV2_INST_BT16
)
5006 inst
= CSKYV2_INST_BT32
;
5008 inst
= CSKYV2_INST_BF32
;
5009 if (IS_EXTERNAL_SYM (fragp
->fr_symbol
, asec
))
5010 fix_new (fragp
, fragp
->fr_fix
, 4,
5011 fragp
->fr_symbol
, fragp
->fr_offset
, 1,
5012 BFD_RELOC_CKCORE_PCREL_IMM16BY2
);
5013 inst
|= (disp
>> 1) & ((1 << 16) - 1);
5014 csky_write_insn (buf
, inst
, 4);
5020 unsigned int inst
= csky_read_insn (buf
, 2);
5022 imm
= (disp
+ 2) >> 2;
5023 inst
|= (imm
>> 5) << 8;
5024 make_insn (2, inst
, (imm
& 0x1f), 5);
5029 unsigned int inst
= csky_read_insn (buf
, 2);
5030 int imm
= (disp
+ 2) >> 2;
5034 inst
|= (~((imm
>> 5) << 8)) & 0x300;
5035 make_insn (2, inst
, (~imm
& 0x1f), 5);
5039 inst
|= (imm
>> 5) << 8;
5040 make_insn (2, inst
, (imm
& 0x1f), 5);
5046 unsigned int inst
= csky_read_insn (buf
, 2);
5047 inst
= CSKYV2_INST_LRW32
| (((inst
& 0xe0) >> 5) << 16);
5048 if (IS_EXTERNAL_SYM (fragp
->fr_symbol
, asec
))
5049 fix_new (fragp
, fragp
->fr_fix
, 4,
5050 fragp
->fr_symbol
, fragp
->fr_offset
, 1,
5051 BFD_RELOC_CKCORE_PCREL_IMM16BY4
);
5052 make_insn (4, inst
, ((disp
+ 2) >> 2), 16);
5057 unsigned int inst
= csky_read_insn (buf
, 4);
5058 make_insn (4, inst
, disp
>> 1, 16);
5063 unsigned int inst
= csky_read_insn (buf
, 4);
5065 make_insn (4, opposite_of_stored_compz (inst
),
5066 (4 + 4 + PAD_LITERAL_LENGTH
) >> 1, 16);
5067 literal_offset
= ((fragp
->fr_address
+ fragp
->fr_fix
) % 4 == 0
5069 make_insn (4, CSKYV2_INST_JMPI32
, (4 + literal_offset
+ 2) >> 2, 10);
5070 make_literal (fragp
, literal_offset
);
5076 if (IS_EXTERNAL_SYM (fragp
->fr_symbol
, asec
))
5077 fix_new (fragp
, fragp
->fr_fix
, 4,
5078 fragp
->fr_symbol
, fragp
->fr_offset
, 1,
5079 BFD_RELOC_CKCORE_PCREL_IMM16BY2
);
5080 make_insn (4, CSKYV2_INST_BR32
, disp
>> 1, 16);
5085 /* 'jbt'/'jbf'-> <bf16/bt16>; jmpi32; [pad16]+literal32 */
5086 unsigned int inst
= csky_read_insn (buf
, 2);
5089 if (inst
== CSKYV2_INST_BT16
)
5090 inst
= CSKYV2_INST_BF16
;
5092 inst
= CSKYV2_INST_BT16
;
5093 make_insn (2, inst
, (2 + 4 + PAD_LITERAL_LENGTH
) >> 1, 10);
5094 literal_offset
= ((fragp
->fr_address
+ fragp
->fr_fix
) % 4 == 0
5096 make_insn (4, CSKYV2_INST_JMPI32
, (4 + literal_offset
+ 2) >> 2, 10);
5097 make_literal (fragp
, literal_offset
);
5103 literal_offset
= ((fragp
->fr_address
+ fragp
->fr_fix
) % 4 == 0
5105 make_insn (4, CSKYV2_INST_JMPI32
, (4 + literal_offset
+ 2) >> 2, 10);
5106 make_literal (fragp
, literal_offset
);
5109 case RELAX_OVERFLOW
:
5110 csky_branch_report_error (fragp
->fr_file
, fragp
->fr_line
,
5111 fragp
->fr_symbol
, disp
);
5119 /* Round up a section size to the appropriate boundary. */
5122 md_section_align (segT segment ATTRIBUTE_UNUSED
,
5128 /* MD interface: Symbol and relocation handling. */
5130 void md_csky_end (void)
5135 /* Return the address within the segment that a PC-relative fixup is
5139 md_pcrel_from_section (fixS
* fixP
, segT seg
)
5141 /* If the symbol is undefined or defined in another section
5142 we leave the add number alone for the linker to fix it later. */
5143 if (fixP
->fx_addsy
!= (symbolS
*) NULL
5144 && (! S_IS_DEFINED (fixP
->fx_addsy
)
5145 || S_GET_SEGMENT (fixP
->fx_addsy
) != seg
))
5146 return fixP
->fx_size
;
5148 /* The case where we are going to resolve things. */
5149 return fixP
->fx_size
+ fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
5152 /* csky_cons_fix_new is called via the expression parsing code when a
5153 reloc is needed. We use this hook to get the correct .got reloc. */
5156 csky_cons_fix_new (fragS
*frag
,
5160 bfd_reloc_code_real_type reloc
)
5164 if (BFD_RELOC_CKCORE_GOTOFF
== insn_reloc
5165 || BFD_RELOC_CKCORE_GOTPC
== insn_reloc
5166 || BFD_RELOC_CKCORE_GOT32
== insn_reloc
5167 || BFD_RELOC_CKCORE_PLT32
== insn_reloc
5168 || BFD_RELOC_CKCORE_TLS_LE32
== insn_reloc
5169 || BFD_RELOC_CKCORE_TLS_GD32
== insn_reloc
5170 || BFD_RELOC_CKCORE_TLS_LDM32
== insn_reloc
5171 || BFD_RELOC_CKCORE_TLS_LDO32
== insn_reloc
5172 || BFD_RELOC_CKCORE_TLS_IE32
== insn_reloc
)
5178 reloc
= BFD_RELOC_8
;
5181 reloc
= BFD_RELOC_16
;
5184 reloc
= BFD_RELOC_32
;
5187 reloc
= BFD_RELOC_64
;
5190 as_bad (_("unsupported BFD relocation size %d"), len
);
5191 reloc
= BFD_RELOC_32
;
5194 fixP
= fix_new_exp (frag
, off
, (int) len
, exp
, 0, reloc
);
5195 if (BFD_RELOC_CKCORE_TLS_IE32
== insn_reloc
5196 || BFD_RELOC_CKCORE_TLS_GD32
== insn_reloc
5197 || BFD_RELOC_CKCORE_TLS_LDM32
== insn_reloc
)
5199 fixP
->tc_fix_data
.frag
= literal_insn_offset
->tls_addend
.frag
;
5200 fixP
->tc_fix_data
.offset
= literal_insn_offset
->tls_addend
.offset
;
5204 /* See whether we need to force a relocation into the output file.
5205 This is used to force out switch and PC relative relocations when
5209 csky_force_relocation (fixS
* fix
)
5211 if (fix
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
5212 || fix
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
5213 || fix
->fx_r_type
== BFD_RELOC_RVA
5214 || fix
->fx_r_type
== BFD_RELOC_CKCORE_ADDR_HI16
5215 || fix
->fx_r_type
== BFD_RELOC_CKCORE_ADDR_LO16
5216 || fix
->fx_r_type
== BFD_RELOC_CKCORE_TOFFSET_LO16
5217 || fix
->fx_r_type
== BFD_RELOC_CKCORE_DOFFSET_LO16
)
5220 if (fix
->fx_addsy
== NULL
)
5223 if (do_use_branchstub
5224 && fix
->fx_r_type
== BFD_RELOC_CKCORE_PCREL_IMM26BY2
5225 && (symbol_get_bfdsym (fix
->fx_addsy
)->flags
& BSF_FUNCTION
))
5227 return S_FORCE_RELOC (fix
->fx_addsy
, fix
->fx_subsy
== NULL
);
5230 /* Return true if the fix can be handled by GAS, false if it must
5231 be passed through to the linker. */
5234 csky_fix_adjustable (fixS
* fixP
)
5236 if (fixP
->fx_addsy
== NULL
)
5239 /* We need the symbol name for the VTABLE entries. */
5240 if (fixP
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
5241 || fixP
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
5242 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_PLT32
5243 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_GOT32
5244 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_PLT12
5245 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_GOT12
5246 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_GOT_HI16
5247 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_GOT_LO16
5248 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_PLT_HI16
5249 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_PLT_LO16
5250 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_GOTOFF
5251 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_GOTOFF_HI16
5252 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_GOTOFF_LO16
5253 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_ADDR_HI16
5254 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_ADDR_LO16
5255 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_GOT_IMM18BY4
5256 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_PLT_IMM18BY4
5257 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_GOTOFF_IMM18
5258 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_TLS_LE32
5259 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_TLS_IE32
5260 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_TLS_GD32
5261 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_TLS_LDM32
5262 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_TLS_LDO32
)
5265 if (do_use_branchstub
5266 && fixP
->fx_r_type
== BFD_RELOC_CKCORE_PCREL_IMM26BY2
5267 && (symbol_get_bfdsym (fixP
->fx_addsy
)->flags
& BSF_FUNCTION
))
5274 md_apply_fix (fixS
*fixP
,
5278 reloc_howto_type
*howto
;
5279 /* Note: use offsetT because it is signed, valueT is unsigned. */
5280 offsetT val
= *valP
;
5281 char *buf
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
5283 /* if fx_done = 0, fixup will also be processed in
5284 * tc_gen_reloc() after md_apply_fix(). */
5287 /* If the fix is relative to a symbol which is not defined, or not
5288 in the same segment as the fix, we cannot resolve it here. */
5289 if (IS_CSKY_V1 (mach_flag
) && fixP
->fx_addsy
!= NULL
5290 && (! S_IS_DEFINED (fixP
->fx_addsy
)
5291 || S_GET_SEGMENT (fixP
->fx_addsy
) != seg
))
5293 switch (fixP
->fx_r_type
)
5295 /* Data fx_addnumber is greater than 16 bits,
5296 so fx_addnumber is assigned zero. */
5297 case BFD_RELOC_CKCORE_PCREL_JSR_IMM11BY2
:
5300 case BFD_RELOC_CKCORE_TLS_IE32
:
5301 case BFD_RELOC_CKCORE_TLS_LDM32
:
5302 case BFD_RELOC_CKCORE_TLS_GD32
:
5304 struct tls_addend
*ta
= &(fixP
->tc_fix_data
);
5305 fixP
->fx_offset
= (fixP
->fx_frag
->fr_address
+ fixP
->fx_where
5306 - (ta
->frag
->fr_address
+ ta
->offset
));
5307 *valP
= fixP
->fx_offset
;
5310 case BFD_RELOC_CKCORE_TLS_LE32
:
5311 case BFD_RELOC_CKCORE_TLS_LDO32
:
5312 S_SET_THREAD_LOCAL (fixP
->fx_addsy
);
5318 /* For ELF we can just return and let the reloc that will be generated
5319 take care of everything. For COFF we still have to insert 'val'
5320 into the insn since the addend field will be ignored. */
5325 /* We can handle these relocs. */
5326 switch (fixP
->fx_r_type
)
5328 case BFD_RELOC_32_PCREL
:
5329 case BFD_RELOC_CKCORE_PCREL32
:
5330 fixP
->fx_r_type
= BFD_RELOC_CKCORE_PCREL32
;
5332 case BFD_RELOC_VTABLE_INHERIT
:
5333 fixP
->fx_r_type
= BFD_RELOC_CKCORE_GNU_VTINHERIT
;
5334 if (fixP
->fx_addsy
&& !S_IS_DEFINED (fixP
->fx_addsy
)
5335 && !S_IS_WEAK (fixP
->fx_addsy
))
5336 S_SET_WEAK (fixP
->fx_addsy
);
5338 case BFD_RELOC_VTABLE_ENTRY
:
5339 fixP
->fx_r_type
= BFD_RELOC_CKCORE_GNU_VTENTRY
;
5341 case BFD_RELOC_CKCORE_GOT12
:
5342 case BFD_RELOC_CKCORE_PLT12
:
5343 case BFD_RELOC_CKCORE_ADDR_HI16
:
5344 case BFD_RELOC_CKCORE_ADDR_LO16
:
5345 case BFD_RELOC_CKCORE_TOFFSET_LO16
:
5346 case BFD_RELOC_CKCORE_DOFFSET_LO16
:
5347 case BFD_RELOC_CKCORE_GOT_HI16
:
5348 case BFD_RELOC_CKCORE_GOT_LO16
:
5349 case BFD_RELOC_CKCORE_PLT_HI16
:
5350 case BFD_RELOC_CKCORE_PLT_LO16
:
5351 case BFD_RELOC_CKCORE_GOTPC_HI16
:
5352 case BFD_RELOC_CKCORE_GOTPC_LO16
:
5353 case BFD_RELOC_CKCORE_GOTOFF_HI16
:
5354 case BFD_RELOC_CKCORE_GOTOFF_LO16
:
5355 case BFD_RELOC_CKCORE_DOFFSET_IMM18
:
5356 case BFD_RELOC_CKCORE_DOFFSET_IMM18BY2
:
5357 case BFD_RELOC_CKCORE_DOFFSET_IMM18BY4
:
5358 case BFD_RELOC_CKCORE_GOTOFF_IMM18
:
5359 case BFD_RELOC_CKCORE_GOT_IMM18BY4
:
5360 case BFD_RELOC_CKCORE_PLT_IMM18BY4
:
5362 case BFD_RELOC_CKCORE_TLS_IE32
:
5363 case BFD_RELOC_CKCORE_TLS_LDM32
:
5364 case BFD_RELOC_CKCORE_TLS_GD32
:
5366 struct tls_addend
*ta
= &(fixP
->tc_fix_data
);
5367 fixP
->fx_offset
= (fixP
->fx_frag
->fr_address
+ fixP
->fx_where
5368 - (ta
->frag
->fr_address
+ ta
->offset
));
5369 *valP
= fixP
->fx_offset
;
5372 case BFD_RELOC_CKCORE_TLS_LE32
:
5373 case BFD_RELOC_CKCORE_TLS_LDO32
:
5374 S_SET_THREAD_LOCAL (fixP
->fx_addsy
);
5377 fixP
->fx_r_type
= BFD_RELOC_CKCORE_ADDR32
;
5381 if (fixP
->fx_addsy
== NULL
)
5383 if (fixP
->fx_size
== 4)
5385 else if (fixP
->fx_size
== 2 && val
>= -32768 && val
<= 32767)
5387 else if (fixP
->fx_size
== 1 && val
>= -256 && val
<= 255)
5391 md_number_to_chars (buf
, val
, fixP
->fx_size
);
5395 case BFD_RELOC_CKCORE_PCREL_JSR_IMM11BY2
:
5396 if (fixP
->fx_addsy
== 0 && val
> -2 KB
&& val
< 2 KB
)
5398 long nval
= (val
>> 1) & 0x7ff;
5399 nval
|= CSKYV1_INST_BSR
;
5400 csky_write_insn (buf
, nval
, 2);
5406 case BFD_RELOC_CKCORE_PCREL_JSR_IMM26BY2
:
5407 if (fixP
->fx_addsy
== 0)
5409 if (val
>= -(1 << 26) && val
< (1 << 26))
5411 unsigned int nval
= ((val
+ fixP
->fx_size
) >> 1) & 0x3ffffff;
5412 nval
|= CSKYV2_INST_BSR32
;
5414 csky_write_insn (buf
, nval
, 4);
5416 /* If bsr32 cannot reach,
5417 generate 'lrw r25,label;jsr r25' instead of 'jsri label'. */
5418 else if (IS_CSKY_ARCH_810 (mach_flag
))
5420 howto
= bfd_reloc_type_lookup (stdoutput
, fixP
->fx_r_type
);
5421 valueT opcode
= csky_read_insn (buf
, 4);
5422 opcode
= (opcode
& howto
->dst_mask
) | CSKYV2_INST_JSRI_TO_LRW
;
5423 csky_write_insn (buf
, opcode
, 4);
5424 opcode
= CSKYV2_INST_JSR_R26
;
5425 csky_write_insn (buf
+ 4, opcode
, 4);
5435 unsigned int issigned
= 0;
5440 howto
= bfd_reloc_type_lookup (stdoutput
, fixP
->fx_r_type
);
5443 if (fixP
->fx_size
== 4
5444 || (fixP
->fx_size
== 2 && val
>= -32768 && val
<= 32767)
5445 || (fixP
->fx_size
== 1 && val
>= -256 && val
<= 255))
5447 md_number_to_chars (buf
, val
, fixP
->fx_size
);
5455 if (IS_CSKY_V2 (mach_flag
))
5456 val
+= fixP
->fx_size
;
5458 if (howto
->rightshift
== 2)
5461 val
>>= howto
->rightshift
;
5463 switch (fixP
->fx_r_type
)
5465 /* Offset is unsigned. */
5466 case BFD_RELOC_CKCORE_PCREL_IMM8BY4
:
5467 case BFD_RELOC_CKCORE_PCREL_IMM10BY4
:
5468 case BFD_RELOC_CKCORE_PCREL_IMM16BY4
:
5469 max
= (offsetT
) howto
->dst_mask
;
5473 case BFD_RELOC_CKCORE_PCREL_IMM7BY4
:
5475 max
= (offsetT
)((1 << (howto
->bitsize
+ 1)) - 2);
5477 max
= (offsetT
)((1 << howto
->bitsize
) - 1);
5480 /* flrws, flrwd: the offset bits are divided in two parts. */
5481 case BFD_RELOC_CKCORE_PCREL_FLRW_IMM8BY4
:
5482 max
= (offsetT
)((1 << howto
->bitsize
) - 1);
5485 /* Offset is signed. */
5487 max
= (offsetT
)(howto
->dst_mask
>> 1);
5491 if (val
< min
|| val
> max
)
5493 csky_branch_report_error (fixP
->fx_file
, fixP
->fx_line
,
5494 fixP
->fx_addsy
, val
);
5497 opcode
= csky_read_insn (buf
, fixP
->fx_size
);
5498 /* Clear redundant bits brought from the last
5499 operation if there is any. */
5500 if (do_extend_lrw
&& (opcode
& 0xfc00) == CSKYV2_INST_LRW16
)
5503 val
&= issigned
? (offsetT
)(howto
->dst_mask
) : max
;
5505 if (fixP
->fx_r_type
== BFD_RELOC_CKCORE_PCREL_BLOOP_IMM4BY4
)
5506 val
= (val
& 0xf) << 12;
5508 if (fixP
->fx_size
== 2 && (opcode
& 0xfc00) == CSKYV2_INST_LRW16
)
5510 /* 8 bit offset lrw16. */
5512 csky_write_insn (buf
,
5514 | ((~val
& 0x60) << 3) | (opcode
& 0xe0)),
5516 /* 7 bit offset lrw16. */
5518 csky_write_insn (buf
,
5519 (val
& 0x1f) | ((val
& 0x60) << 3) | opcode
,
5522 else if (fixP
->fx_size
== 4
5523 && (opcode
& 0xfe1ffe00) == CSKYV2_INST_FLRW
)
5524 csky_write_insn (buf
,
5525 ((val
& 0xf) << 4) | ((val
& 0xf0) << 17) | opcode
,
5528 csky_write_insn (buf
, val
| opcode
, fixP
->fx_size
);
5533 fixP
->fx_addnumber
= val
;
5536 /* Translate internal representation of relocation info to BFD target
5540 tc_gen_reloc (asection
*section ATTRIBUTE_UNUSED
, fixS
*fixP
)
5545 && fixP
->fx_r_type
== BFD_RELOC_CKCORE_ADDR32
)
5546 fixP
->fx_r_type
= BFD_RELOC_CKCORE_PCREL32
;
5548 rel
= xmalloc (sizeof (arelent
));
5549 rel
->sym_ptr_ptr
= xmalloc (sizeof (asymbol
*));
5550 *rel
->sym_ptr_ptr
= symbol_get_bfdsym (fixP
->fx_addsy
);
5551 rel
->howto
= bfd_reloc_type_lookup (stdoutput
, fixP
->fx_r_type
);
5552 rel
->addend
= fixP
->fx_offset
;
5553 if (rel
->howto
== NULL
)
5555 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5556 _("cannot represent `%s' relocation in object file"),
5557 bfd_get_reloc_code_name (fixP
->fx_r_type
));
5559 /* Set howto to a garbage value so that we can keep going. */
5560 rel
->howto
= bfd_reloc_type_lookup (stdoutput
, BFD_RELOC_32
);
5562 gas_assert (rel
->howto
!= NULL
);
5563 rel
->address
= fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
5567 /* Relax a fragment by scanning TC_GENERIC_RELAX_TABLE. */
5570 csky_relax_frag (segT segment
, fragS
*fragP
, long stretch
)
5572 const relax_typeS
*this_type
;
5573 const relax_typeS
*start_type
;
5574 relax_substateT next_state
;
5575 relax_substateT this_state
;
5581 const relax_typeS
*table
;
5583 target
= fragP
->fr_offset
;
5584 address
= fragP
->fr_address
;
5585 table
= TC_GENERIC_RELAX_TABLE
;
5586 this_state
= fragP
->fr_subtype
;
5587 start_type
= this_type
= table
+ this_state
;
5588 symbolP
= fragP
->fr_symbol
;
5594 sym_frag
= symbol_get_frag (symbolP
);
5596 #ifndef DIFF_EXPR_OK
5597 know (sym_frag
!= NULL
);
5599 know (S_GET_SEGMENT (symbolP
) != absolute_section
5600 || sym_frag
== &zero_address_frag
);
5601 target
+= S_GET_VALUE (symbolP
);
5603 /* If SYM_FRAG has yet to be reached on this pass, assume it
5604 will move by STRETCH just as we did, unless there is an
5605 alignment frag between here and SYM_FRAG. An alignment may
5606 well absorb any STRETCH, and we don't want to choose a larger
5607 branch insn by overestimating the needed reach of this
5608 branch. It isn't critical to calculate TARGET exactly; We
5609 know we'll be doing another pass if STRETCH is non-zero. */
5612 && sym_frag
->relax_marker
!= fragP
->relax_marker
5613 && S_GET_SEGMENT (symbolP
) == segment
)
5617 /* Adjust stretch for any alignment frag. Note that if have
5618 been expanding the earlier code, the symbol may be
5619 defined in what appears to be an earlier frag. FIXME:
5620 This doesn't handle the fr_subtype field, which specifies
5621 a maximum number of bytes to skip when doing an
5623 for (f
= fragP
; f
!= NULL
&& f
!= sym_frag
; f
= f
->fr_next
)
5625 if (f
->fr_type
== rs_align
|| f
->fr_type
== rs_align_code
)
5628 stretch
= -((-stretch
)
5629 & ~((1 << (int) f
->fr_offset
) - 1));
5631 stretch
&= ~((1 << (int) f
->fr_offset
) - 1);
5641 aim
= target
- address
- fragP
->fr_fix
;
5643 /* If the fragP->fr_symbol is extern symbol, aim should be 0. */
5644 if (fragP
->fr_symbol
&& S_GET_SEGMENT (symbolP
) != segment
)
5649 /* Look backwards. */
5650 for (next_state
= this_type
->rlx_more
; next_state
;)
5651 if (aim
>= this_type
->rlx_backward
)
5655 /* Grow to next state. */
5656 this_state
= next_state
;
5657 this_type
= table
+ this_state
;
5658 next_state
= this_type
->rlx_more
;
5663 /* Look forwards. */
5664 for (next_state
= this_type
->rlx_more
; next_state
;)
5665 if (aim
<= this_type
->rlx_forward
)
5669 /* Grow to next state. */
5670 this_state
= next_state
;
5671 this_type
= table
+ this_state
;
5672 next_state
= this_type
->rlx_more
;
5676 growth
= this_type
->rlx_length
- start_type
->rlx_length
;
5678 fragP
->fr_subtype
= this_state
;
5683 md_estimate_size_before_relax (fragS
* fragp
,
5686 switch (fragp
->fr_subtype
)
5706 gas_assert (fragp
->fr_symbol
);
5707 if (IS_EXTERNAL_SYM (fragp
->fr_symbol
, segtype
))
5708 while (csky_relax_table
[fragp
->fr_subtype
].rlx_more
> RELAX_OVERFLOW
)
5709 fragp
->fr_subtype
= csky_relax_table
[fragp
->fr_subtype
].rlx_more
;
5710 return csky_relax_table
[fragp
->fr_subtype
].rlx_length
;
5712 /* C-SKY V1 relaxes. */
5713 case C (UNCD_JUMP
, UNDEF_DISP
):
5714 case C (UNCD_JUMP_PIC
, UNDEF_DISP
):
5715 if (!fragp
->fr_symbol
)
5716 fragp
->fr_subtype
= C (UNCD_JUMP_S
, DISP12
);
5717 else if (S_GET_SEGMENT (fragp
->fr_symbol
) == segtype
)
5718 fragp
->fr_subtype
= C (UNCD_JUMP_S
, DISP12
);
5720 fragp
->fr_subtype
= C (UNCD_JUMP_S
, UNDEF_WORD_DISP
);
5723 case C (COND_JUMP
, UNDEF_DISP
):
5724 case C (COND_JUMP_PIC
, UNDEF_DISP
):
5725 if (fragp
->fr_symbol
5726 && S_GET_SEGMENT (fragp
->fr_symbol
) == segtype
)
5727 /* Got a symbol and it's defined in this segment, become byte
5728 sized. Maybe it will fix up. */
5729 fragp
->fr_subtype
= C (COND_JUMP_S
, DISP12
);
5730 else if (fragp
->fr_symbol
)
5731 /* It's got a segment, but it's not ours, so it will always be
5733 fragp
->fr_subtype
= C (COND_JUMP_S
, UNDEF_WORD_DISP
);
5735 /* We know the abs value. */
5736 fragp
->fr_subtype
= C (COND_JUMP_S
, DISP12
);
5739 case C (UNCD_JUMP
, DISP12
):
5740 case C (UNCD_JUMP
, DISP32
):
5741 case C (UNCD_JUMP
, UNDEF_WORD_DISP
):
5742 case C (COND_JUMP
, DISP12
):
5743 case C (COND_JUMP
, DISP32
):
5744 case C (COND_JUMP
, UNDEF_WORD_DISP
):
5745 case C (UNCD_JUMP_PIC
, DISP12
):
5746 case C (UNCD_JUMP_PIC
, DISP32
):
5747 case C (UNCD_JUMP_PIC
, UNDEF_WORD_DISP
):
5748 case C (COND_JUMP_PIC
, DISP12
):
5749 case C (COND_JUMP_PIC
, DISP32
):
5750 case C (COND_JUMP_PIC
, UNDEF_WORD_DISP
):
5751 case RELAX_OVERFLOW
:
5757 return csky_relax_table
[fragp
->fr_subtype
].rlx_length
;
5760 /* Parse opcode like: "op oprnd1, oprnd2, oprnd3". */
5763 csky_macro_md_assemble (const char *op
,
5774 strcat (str
, oprnd1
);
5778 strcat (str
, oprnd2
);
5782 strcat (str
, oprnd3
);
5790 /* Get the string of operand. */
5793 csky_get_macro_operand (char *src_s
, char *dst_s
, char end_sym
)
5796 while (ISSPACE (*src_s
))
5798 while (*src_s
!= end_sym
)
5799 dst_s
[nlen
++] = *(src_s
++);
5804 /* idly 4 -> idly4. */
5809 char *s
= csky_insn
.opcode_end
;
5810 if (!is_imm_within_range (&s
, 4, 4))
5812 as_bad (_("second operand must be 4"));
5815 csky_macro_md_assemble ("idly4", NULL
, NULL
, NULL
);
5819 /* rolc rd, 1 or roltc rd, 1 -> addc rd, rd. */
5825 char *s
= csky_insn
.opcode_end
;
5827 s
+= csky_get_macro_operand (s
, reg
, ',');
5830 if (is_imm_within_range (&s
, 1, 1))
5832 csky_macro_md_assemble ("addc", reg
, reg
, NULL
);
5836 as_bad (_("second operand must be 1"));
5839 /* sxtrb0(1)(2) r1, rx -> xtbr0(1)(2) r1,rx; sextb r1. */
5847 char *s
= csky_insn
.opcode_end
;
5848 s
+= csky_get_macro_operand (s
, reg1
, ',');
5850 csky_get_macro_operand (s
, reg2
, '\0');
5852 csky_macro_md_assemble (csky_insn
.macro
->name
+ 1, reg1
, reg2
, NULL
);
5853 csky_macro_md_assemble ("sextb", reg1
, NULL
, NULL
);
5864 char *s
= csky_insn
.opcode_end
;
5865 s
+= csky_get_macro_operand (s
, reg1
, ',');
5868 s
+= csky_get_macro_operand (s
, reg2
, ',');
5871 s
+= csky_get_macro_operand (s
, reg3
, '\0');
5873 csky_macro_md_assemble ("movt", reg1
, reg2
, NULL
);
5874 csky_macro_md_assemble ("movf", reg1
, reg3
, NULL
);
5879 get_macro_reg_vals (int *reg1
, int *reg2
, int *reg3
)
5882 char *s
= csky_insn
.opcode_end
;
5884 *reg1
= csky_get_reg_val (s
, &nlen
);
5888 csky_show_error (ERROR_MISSING_COMMA
, 0, NULL
, NULL
);
5892 *reg2
= csky_get_reg_val (s
, &nlen
);
5896 csky_show_error (ERROR_MISSING_COMMA
, 0, NULL
, NULL
);
5900 *reg3
= csky_get_reg_val (s
, &nlen
);
5904 csky_show_error (ERROR_BAD_END
, 0, s
, NULL
);
5907 if (*reg1
== -1 || *reg2
== -1 || *reg3
== -1)
5909 as_bad (_("register number out of range"));
5914 as_bad (_("dest and source1 must be the same register"));
5917 if (*reg1
>= 15 || *reg3
>= 15)
5919 as_bad (_("64-bit operator src/dst register must be less than 15"));
5925 /* addc64 rx, rx, ry -> cmplt rx, rx, addc rx, ry, addc rx+1, ry+1. */
5934 if (!get_macro_reg_vals (®1
, ®2
, ®3
))
5936 csky_macro_md_assemble ("cmplt",
5937 csky_general_reg
[reg1
],
5938 csky_general_reg
[reg1
],
5940 csky_macro_md_assemble ("addc",
5941 csky_general_reg
[reg1
+ (target_big_endian
? 1 : 0)],
5942 csky_general_reg
[reg3
+ (target_big_endian
? 1 : 0)],
5944 csky_macro_md_assemble ("addc",
5945 csky_general_reg
[reg1
+ (target_big_endian
? 0 : 1)],
5946 csky_general_reg
[reg3
+ (target_big_endian
? 0 : 1)],
5951 /* subc64 rx, rx, ry -> cmphs rx, rx, subc rx, ry, subc rx+1, ry+1. */
5960 if (!get_macro_reg_vals (®1
, ®2
, ®3
))
5962 csky_macro_md_assemble ("cmphs",
5963 csky_general_reg
[reg1
],
5964 csky_general_reg
[reg1
],
5966 csky_macro_md_assemble ("subc",
5967 csky_general_reg
[reg1
+ (target_big_endian
? 1 : 0)],
5968 csky_general_reg
[reg3
+ (target_big_endian
? 1 : 0)],
5970 csky_macro_md_assemble ("subc",
5971 csky_general_reg
[reg1
+ (target_big_endian
? 0 : 1)],
5972 csky_general_reg
[reg3
+ (target_big_endian
? 0 : 1)],
5977 /* or64 rx, rx, ry -> or rx, ry, or rx+1, ry+1. */
5986 if (!get_macro_reg_vals (®1
, ®2
, ®3
))
5988 csky_macro_md_assemble ("or",
5989 csky_general_reg
[reg1
+ (target_big_endian
? 1 : 0)],
5990 csky_general_reg
[reg3
+ (target_big_endian
? 1 : 0)],
5992 csky_macro_md_assemble ("or",
5993 csky_general_reg
[reg1
+ (target_big_endian
? 0 : 1)],
5994 csky_general_reg
[reg3
+ (target_big_endian
? 0 : 1)],
5999 /* xor64 rx, rx, ry -> xor rx, ry, xor rx+1, ry+1. */
6008 if (!get_macro_reg_vals (®1
, ®2
, ®3
))
6010 csky_macro_md_assemble ("xor",
6011 csky_general_reg
[reg1
+ (target_big_endian
? 1 : 0)],
6012 csky_general_reg
[reg3
+ (target_big_endian
? 1 : 0)],
6014 csky_macro_md_assemble ("xor",
6015 csky_general_reg
[reg1
+ (target_big_endian
? 0 : 1)],
6016 csky_general_reg
[reg3
+ (target_big_endian
? 0 : 1)],
6021 /* The following are V2 macro instructions. */
6023 /* neg rd -> not rd, rd; addi rd, 1. */
6030 char *s
= csky_insn
.opcode_end
;
6031 s
+= csky_get_macro_operand (s
, reg1
, '\0');
6034 csky_macro_md_assemble ("not", reg1
, reg1
, NULL
);
6035 csky_macro_md_assemble ("addi", reg1
, "1", NULL
);
6039 /* rsubi rd, imm16 -> not rd; addi rd, imm16 + 1 */
6046 unsigned int imm16
= 0;
6048 char *s
= csky_insn
.opcode_end
;
6049 s
+= csky_get_macro_operand (s
, reg1
, ',');
6052 s
= parse_exp (s
, &e
);
6053 if (e
.X_op
== O_constant
)
6054 imm16
= e
.X_add_number
;
6056 csky_show_error (ERROR_IMM_ILLEGAL
, 2, NULL
, NULL
);
6058 sprintf (str_imm16
, "%d", imm16
+ 1);
6060 csky_macro_md_assemble ("not", reg1
, reg1
, NULL
);
6061 csky_macro_md_assemble ("addi", reg1
, str_imm16
, NULL
);
6065 /* Such as: asrc rd -> asrc rd, rd, 1. */
6071 char *s
= csky_insn
.opcode_end
;
6072 s
+= csky_get_macro_operand (s
, reg1
, '\0');
6074 csky_macro_md_assemble (csky_insn
.macro
->name
, reg1
, reg1
, "1");
6078 /* decne rd -> if ck802: subi rd, 1; cmpnei rd, 0.
6079 else: decne rd, rd, 1 */
6085 char *s
= csky_insn
.opcode_end
;
6086 s
+= csky_get_macro_operand (s
, reg1
, '\0');
6088 if (IS_CSKY_ARCH_802 (mach_flag
))
6090 csky_macro_md_assemble ("subi", reg1
, "1", NULL
);
6091 csky_macro_md_assemble ("cmpnei", reg1
, "0", NULL
);
6094 csky_macro_md_assemble ("decne", reg1
, reg1
, "1");
6098 /* If -mnolrw, lrw rd, imm -> movih rd, imm_hi16; ori rd, imm_lo16. */
6108 char *s
= csky_insn
.opcode_end
;
6109 s
+= csky_get_macro_operand (s
, reg1
, ',');
6111 s
+= csky_get_macro_operand (s
, imm
, '\0');
6115 strcat (imm_hi16
, "(");
6116 strcat (imm_hi16
, imm
);
6117 strcat (imm_hi16
, ") >> 16");
6119 strcat (imm_lo16
, "(");
6120 strcat (imm_lo16
, imm
);
6121 strcat (imm_lo16
, ") & 0xffff");
6123 csky_macro_md_assemble ("movih", reg1
, imm_hi16
, NULL
);
6124 csky_macro_md_assemble ("ori", reg1
, reg1
, imm_lo16
);
6129 /* The following are worker functions for C-SKY v1. */
6135 int output_literal
= csky_insn
.val
[1];
6137 reg
= csky_insn
.val
[0];
6138 csky_insn
.isize
= 2;
6139 csky_insn
.output
= frag_more (2);
6140 if (csky_insn
.e1
.X_op
== O_constant
6141 && csky_insn
.e1
.X_add_number
<= 0x7f
6142 && csky_insn
.e1
.X_add_number
>= 0)
6144 csky_insn
.inst
= 0x6000 | reg
| (csky_insn
.e1
.X_add_number
<< 4);
6147 csky_insn
.inst
= csky_insn
.opcode
->op16
[0].opcode
;
6148 csky_insn
.inst
|= reg
<< 8;
6151 struct literal
*p
= enter_literal (&csky_insn
.e1
, 0, 0, 0);
6153 /* Create a reference to pool entry. */
6154 csky_insn
.e1
.X_op
= O_symbol
;
6155 csky_insn
.e1
.X_add_symbol
= poolsym
;
6156 csky_insn
.e1
.X_add_number
= p
->offset
<< 2;
6159 if (insn_reloc
== BFD_RELOC_CKCORE_TLS_GD32
6160 || insn_reloc
== BFD_RELOC_CKCORE_TLS_LDM32
6161 || insn_reloc
== BFD_RELOC_CKCORE_TLS_IE32
)
6163 literal_insn_offset
->tls_addend
.frag
= frag_now
;
6164 literal_insn_offset
->tls_addend
.offset
6166 - literal_insn_offset
->tls_addend
.frag
->fr_literal
);
6168 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
, 2,
6169 &csky_insn
.e1
, 1, BFD_RELOC_CKCORE_PCREL_IMM8BY4
);
6171 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6177 v1_work_fpu_fo (void)
6183 struct csky_opcode_info
*opinfo
= NULL
;
6185 if (csky_insn
.isize
== 4)
6186 opinfo
= &csky_insn
.opcode
->op32
[csky_insn
.opcode_idx
];
6187 else if (csky_insn
.isize
== 2)
6188 opinfo
= &csky_insn
.opcode
->op16
[csky_insn
.opcode_idx
];
6190 /* Firstly, get general reg. */
6191 for (i
= 0;i
< opinfo
->operand_num
; i
++)
6192 if (opinfo
->oprnd
.oprnds
[i
].type
== OPRND_TYPE_GREG0_15
)
6193 greg
= csky_insn
.val
[i
];
6194 gas_assert (greg
!= -1);
6196 /* Secondly, get float inst. */
6197 csky_generate_insn ();
6198 inst
= csky_insn
.inst
;
6200 /* Now get greg and inst, we can write instruction to floating unit. */
6201 sprintf (buff
, "lrw %s,0x%x", csky_general_reg
[greg
], inst
);
6203 sprintf (buff
, "cpwir %s", csky_general_reg
[greg
]);
6210 v1_work_fpu_fo_fc (void)
6216 struct csky_opcode_info
*opinfo
= NULL
;
6218 if (csky_insn
.isize
== 4)
6219 opinfo
= &csky_insn
.opcode
->op32
[csky_insn
.opcode_idx
];
6220 else if (csky_insn
.isize
== 2)
6221 opinfo
= &csky_insn
.opcode
->op16
[csky_insn
.opcode_idx
];
6223 /* Firstly, get general reg. */
6224 for (i
= 0;i
< opinfo
->operand_num
; i
++)
6225 if (opinfo
->oprnd
.oprnds
[i
].type
== OPRND_TYPE_GREG0_15
)
6226 greg
= csky_insn
.val
[i
];
6227 gas_assert (greg
!= -1);
6229 /* Secondly, get float inst. */
6230 csky_generate_insn ();
6231 inst
= csky_insn
.inst
;
6233 /* Now get greg and inst, we can write instruction to floating unit. */
6234 sprintf (buff
, "lrw %s,0x%x", csky_general_reg
[greg
], inst
);
6236 sprintf (buff
, "cpwir %s", csky_general_reg
[greg
]);
6238 sprintf (buff
, "cprc");
6245 v1_work_fpu_write (void)
6251 greg
= csky_insn
.val
[0];
6252 freg
= csky_insn
.val
[1];
6254 /* Now get greg and freg, we can write instruction to floating unit. */
6255 sprintf (buff
, "cpwgr %s,%s", csky_general_reg
[greg
], csky_cp_reg
[freg
]);
6262 v1_work_fpu_read (void)
6268 greg
= csky_insn
.val
[0];
6269 freg
= csky_insn
.val
[1];
6270 /* Now get greg and freg, we can write instruction to floating unit. */
6271 sprintf (buff
, "cprgr %s,%s", csky_general_reg
[greg
], csky_cp_reg
[freg
]);
6278 v1_work_fpu_writed (void)
6284 greg
= csky_insn
.val
[0];
6285 freg
= csky_insn
.val
[1];
6289 as_bad (_("even register number required"));
6292 /* Now get greg and freg, we can write instruction to floating unit. */
6293 if (target_big_endian
)
6294 sprintf (buff
, "cpwgr %s,%s",
6295 csky_general_reg
[greg
+ 1], csky_cp_reg
[freg
]);
6297 sprintf (buff
, "cpwgr %s,%s",
6298 csky_general_reg
[greg
], csky_cp_reg
[freg
]);
6300 if (target_big_endian
)
6301 sprintf (buff
, "cpwgr %s,%s",
6302 csky_general_reg
[greg
], csky_cp_reg
[freg
+ 1]);
6304 sprintf (buff
, "cpwgr %s,%s",
6305 csky_general_reg
[greg
+ 1], csky_cp_reg
[freg
+ 1]);
6312 v1_work_fpu_readd (void)
6318 greg
= csky_insn
.val
[0];
6319 freg
= csky_insn
.val
[1];
6323 as_bad (_("even register number required"));
6326 /* Now get greg and freg, we can write instruction to floating unit. */
6327 if (target_big_endian
)
6328 sprintf (buff
, "cprgr %s,%s",
6329 csky_general_reg
[greg
+ 1], csky_cp_reg
[freg
]);
6331 sprintf (buff
, "cprgr %s,%s",
6332 csky_general_reg
[greg
], csky_cp_reg
[freg
]);
6334 if (target_big_endian
)
6335 sprintf (buff
, "cprgr %s,%s",
6336 csky_general_reg
[greg
], csky_cp_reg
[freg
+ 1]);
6338 sprintf (buff
, "cprgr %s,%s",
6339 csky_general_reg
[greg
+ 1], csky_cp_reg
[freg
+ 1]);
6345 /* The following are for csky pseudo handling. */
6350 csky_insn
.output
= frag_more (2);
6352 /* Generate fixup BFD_RELOC_CKCORE_PCREL_IMM11BY2. */
6353 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
6354 2, & csky_insn
.e1
, 1, BFD_RELOC_CKCORE_PCREL_IMM11BY2
);
6357 /* Using jsri instruction. */
6358 const char *name
= "jsri";
6359 csky_insn
.opcode
= (struct csky_opcode
*)
6360 str_hash_find (csky_opcodes_hash
, name
);
6361 csky_insn
.opcode_idx
= 0;
6362 csky_insn
.isize
= 2;
6364 struct literal
*p
= enter_literal (&csky_insn
.e1
, 1, 0, 0);
6366 /* Create a reference to pool entry. */
6367 csky_insn
.e1
.X_op
= O_symbol
;
6368 csky_insn
.e1
.X_add_symbol
= poolsym
;
6369 csky_insn
.e1
.X_add_number
= p
->offset
<< 2;
6371 /* Generate fixup BFD_RELOC_CKCORE_PCREL_IMM8BY4. */
6372 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
6373 2, & csky_insn
.e1
, 1, BFD_RELOC_CKCORE_PCREL_IMM8BY4
);
6375 if (csky_insn
.e1
.X_op
!= O_absent
&& do_jsri2bsr
)
6376 /* Generate fixup BFD_RELOC_CKCORE_PCREL_JSR_IMM11BY2. */
6377 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
6379 1, BFD_RELOC_CKCORE_PCREL_JSR_IMM11BY2
);
6381 csky_generate_insn ();
6383 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6388 /* The following are worker functions for csky v2 instruction handling. */
6390 /* For nie/nir/ipush/ipop. */
6393 v2_work_istack (void)
6397 csky_show_error (ERROR_OPCODE_ILLEGAL
, 0, NULL
, NULL
);
6400 csky_insn
.output
= frag_more (csky_insn
.isize
);
6401 csky_insn
.inst
= csky_insn
.opcode
->op16
[0].opcode
;
6402 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6407 v2_work_btsti (void)
6410 && (csky_insn
.flag_force
== INSN_OPCODE16F
6411 || IS_CSKY_ARCH_801 (mach_flag
)))
6413 csky_show_error (ERROR_OPCODE_ILLEGAL
, 0, NULL
, NULL
);
6416 if (!do_extend_lrw
&& csky_insn
.isize
== 2)
6417 csky_insn
.isize
= 4;
6418 /* Generate relax or reloc if necessary. */
6419 csky_generate_frags ();
6420 /* Generate the insn by mask. */
6421 csky_generate_insn ();
6422 /* Write inst to frag. */
6423 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6430 csky_insn
.isize
= 2;
6431 if (csky_insn
.number
== 2)
6433 if (csky_insn
.val
[0] == 14
6434 && csky_insn
.val
[1] >= 0 && csky_insn
.val
[1] <= 0x1fc
6435 && (csky_insn
.val
[1] & 0x3) == 0
6436 && csky_insn
.flag_force
!= INSN_OPCODE32F
)
6438 /* addi sp, sp, imm. */
6439 csky_insn
.inst
= 0x1400 | ((csky_insn
.val
[1] >> 2) & 0x1f);
6440 csky_insn
.inst
|= (csky_insn
.val
[1] << 1) & 0x300;
6441 csky_insn
.output
= frag_more (2);
6443 else if (csky_insn
.val
[0] < 8
6444 && csky_insn
.val
[1] >= 1 && csky_insn
.val
[1] <= 0x100
6445 && csky_insn
.flag_force
!= INSN_OPCODE32F
)
6447 csky_insn
.inst
= 0x2000 | (csky_insn
.val
[0] << 8);
6448 csky_insn
.inst
|= (csky_insn
.val
[1] - 1);
6449 csky_insn
.output
= frag_more (2);
6451 else if (csky_insn
.val
[1] >= 1 && csky_insn
.val
[1] <= 0x10000
6452 && csky_insn
.flag_force
!= INSN_OPCODE16F
6453 && !IS_CSKY_ARCH_801 (mach_flag
))
6455 csky_insn
.inst
= 0xe4000000 | (csky_insn
.val
[0] << 21);
6456 csky_insn
.inst
|= csky_insn
.val
[0] << 16;
6457 csky_insn
.inst
|= (csky_insn
.val
[1] - 1);
6458 csky_insn
.isize
= 4;
6459 csky_insn
.output
= frag_more (4);
6463 csky_show_error (ERROR_OPERANDS_ILLEGAL
, 0,
6464 csky_insn
.opcode_end
, NULL
);
6468 else if (csky_insn
.number
== 3)
6470 if (csky_insn
.val
[0] == 14
6471 && csky_insn
.val
[1] == 14
6472 && csky_insn
.val
[2] >= 0 && csky_insn
.val
[2] <= 0x1fc
6473 && (csky_insn
.val
[2] & 0x3) == 0
6474 && csky_insn
.flag_force
!= INSN_OPCODE32F
)
6476 csky_insn
.inst
= 0x1400 | ((csky_insn
.val
[2] >> 2) & 0x1f);
6477 csky_insn
.inst
|= (csky_insn
.val
[2] << 1) & 0x300;
6478 csky_insn
.output
= frag_more (2);
6480 else if (csky_insn
.val
[0] < 8
6481 && csky_insn
.val
[1] == 14
6482 && csky_insn
.val
[2] >= 0 && csky_insn
.val
[2] <= 0x3fc
6483 && (csky_insn
.val
[2] & 0x3) == 0
6484 && csky_insn
.flag_force
!= INSN_OPCODE32F
)
6486 csky_insn
.inst
= 0x1800 | (csky_insn
.val
[0] << 8);
6487 csky_insn
.inst
|= csky_insn
.val
[2] >> 2;
6488 csky_insn
.output
= frag_more (2);
6490 else if (csky_insn
.val
[0] < 8
6491 && csky_insn
.val
[0] == csky_insn
.val
[1]
6492 && csky_insn
.val
[2] >= 1 && csky_insn
.val
[2] <= 0x100
6493 && csky_insn
.flag_force
!= INSN_OPCODE32F
)
6495 csky_insn
.inst
= 0x2000 | (csky_insn
.val
[0] << 8);
6496 csky_insn
.inst
|= (csky_insn
.val
[2] - 1);
6497 csky_insn
.output
= frag_more (2);
6499 else if (csky_insn
.val
[0] < 8
6500 && csky_insn
.val
[1] < 8
6501 && csky_insn
.val
[2] >= 1 && csky_insn
.val
[2] <= 0x8
6502 && csky_insn
.flag_force
!= INSN_OPCODE32F
)
6504 csky_insn
.inst
= 0x5802 | (csky_insn
.val
[0] << 5);
6505 csky_insn
.inst
|= csky_insn
.val
[1] << 8;
6506 csky_insn
.inst
|= (csky_insn
.val
[2] - 1) << 2;
6507 csky_insn
.output
= frag_more (2);
6509 else if (csky_insn
.val
[1] == 28
6510 && csky_insn
.val
[2] >= 1 && csky_insn
.val
[2] <= 0x40000
6511 && csky_insn
.flag_force
!= INSN_OPCODE16F
6512 && !IS_CSKY_ARCH_801 (mach_flag
))
6514 csky_insn
.inst
= 0xcc1c0000 | (csky_insn
.val
[0] << 21);
6515 csky_insn
.isize
= 4;
6516 csky_insn
.output
= frag_more (4);
6517 if (insn_reloc
== BFD_RELOC_CKCORE_GOTOFF
)
6519 fix_new_exp (frag_now
, csky_insn
.output
-frag_now
->fr_literal
,
6520 4, &csky_insn
.e1
, 0, BFD_RELOC_CKCORE_GOTOFF_IMM18
);
6523 csky_insn
.inst
|= (csky_insn
.val
[2] - 1);
6525 else if (csky_insn
.val
[2] >= 1 && csky_insn
.val
[2] <= 0x1000
6526 && csky_insn
.flag_force
!= INSN_OPCODE16F
6527 && !IS_CSKY_ARCH_801 (mach_flag
))
6529 csky_insn
.inst
= 0xe4000000 | (csky_insn
.val
[0] << 21);
6530 csky_insn
.inst
|= csky_insn
.val
[1] << 16;
6531 csky_insn
.inst
|= (csky_insn
.val
[2] - 1);
6532 csky_insn
.isize
= 4;
6533 csky_insn
.output
= frag_more (4);
6537 csky_show_error (ERROR_OPERANDS_ILLEGAL
, 0,
6538 (char *)csky_insn
.opcode_end
, NULL
);
6542 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6550 csky_insn
.isize
= 2;
6551 if (csky_insn
.number
== 2)
6553 if (csky_insn
.val
[0] == 14
6554 && csky_insn
.val
[1] >= 0 && csky_insn
.val
[2] <= 0x1fc
6555 && (csky_insn
.val
[1] & 0x3) == 0
6556 && csky_insn
.flag_force
!= INSN_OPCODE32F
)
6558 csky_insn
.inst
= 0x1420 | ((csky_insn
.val
[1] >> 2) & 0x1f);
6559 csky_insn
.inst
|= (csky_insn
.val
[1] << 1) & 0x300;
6561 else if (csky_insn
.val
[0] < 8
6562 && csky_insn
.val
[1] >= 1 && csky_insn
.val
[1] <= 0x100
6563 && csky_insn
.flag_force
!= INSN_OPCODE32F
)
6565 csky_insn
.inst
= 0x2800 | (csky_insn
.val
[0] << 8);
6566 csky_insn
.inst
|= (csky_insn
.val
[1] - 1);
6568 else if (csky_insn
.val
[1] >= 1 && csky_insn
.val
[1] <= 0x10000
6569 && csky_insn
.flag_force
!= INSN_OPCODE16F
6570 && !IS_CSKY_ARCH_801 (mach_flag
))
6572 csky_insn
.inst
= 0xe4001000 | (csky_insn
.val
[0] << 21);
6573 csky_insn
.inst
|= csky_insn
.val
[0] << 16;
6574 csky_insn
.inst
|= (csky_insn
.val
[1] - 1);
6575 csky_insn
.isize
= 4;
6579 csky_show_error (ERROR_OPERANDS_ILLEGAL
, 0,
6580 (char *)csky_insn
.opcode_end
, NULL
);
6584 else if (csky_insn
.number
== 3)
6586 if (csky_insn
.val
[0] == 14
6587 && csky_insn
.val
[1] == 14
6588 && csky_insn
.val
[2] >= 0 && csky_insn
.val
[2] <= 0x1fc
6589 && (csky_insn
.val
[2] & 0x3) == 0
6590 && csky_insn
.flag_force
!= INSN_OPCODE32F
)
6592 csky_insn
.inst
= 0x1420 | ((csky_insn
.val
[2] >> 2) & 0x1f);
6593 csky_insn
.inst
|= (csky_insn
.val
[2] << 1) & 0x300;
6596 else if (csky_insn
.val
[0] < 8
6597 && csky_insn
.val
[0] == csky_insn
.val
[1]
6598 && csky_insn
.val
[2] >= 1 && csky_insn
.val
[2] <= 0x100
6599 && csky_insn
.flag_force
!= INSN_OPCODE32F
)
6601 csky_insn
.inst
= 0x2800 | (csky_insn
.val
[0] << 8);
6602 csky_insn
.inst
|= (csky_insn
.val
[2] - 1);
6604 else if (csky_insn
.val
[0] < 8
6605 && csky_insn
.val
[1] < 8
6606 && csky_insn
.val
[2] >= 1 && csky_insn
.val
[2] <= 0x8
6607 && csky_insn
.flag_force
!= INSN_OPCODE32F
)
6609 csky_insn
.inst
= 0x5803 | (csky_insn
.val
[0] << 5);
6610 csky_insn
.inst
|= csky_insn
.val
[1] << 8;
6611 csky_insn
.inst
|= (csky_insn
.val
[2] - 1) << 2;
6613 else if (csky_insn
.val
[2] >= 1 && csky_insn
.val
[2] <= 0x1000
6614 && csky_insn
.flag_force
!= INSN_OPCODE16F
6615 && !IS_CSKY_ARCH_801 (mach_flag
))
6617 csky_insn
.inst
= 0xe4001000 | (csky_insn
.val
[0] << 21);
6618 csky_insn
.inst
|= csky_insn
.val
[1] << 16;
6619 csky_insn
.inst
|= (csky_insn
.val
[2] - 1);
6620 csky_insn
.isize
= 4;
6624 csky_show_error (ERROR_OPERANDS_ILLEGAL
, 0,
6625 (char *)csky_insn
.opcode_end
, NULL
);
6629 csky_insn
.output
= frag_more (csky_insn
.isize
);
6630 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6636 v2_work_add_sub (void)
6638 if (csky_insn
.number
== 3
6639 && (csky_insn
.val
[0] == csky_insn
.val
[1]
6640 || csky_insn
.val
[0] == csky_insn
.val
[2])
6641 && csky_insn
.val
[0] <= 15
6642 && csky_insn
.val
[1] <= 15
6643 && csky_insn
.val
[2] <= 15)
6645 if (!strstr (csky_insn
.opcode
->mnemonic
, "sub")
6646 || csky_insn
.val
[0] == csky_insn
.val
[1])
6648 csky_insn
.opcode_idx
= 0;
6649 csky_insn
.isize
= 2;
6650 if (csky_insn
.val
[0] == csky_insn
.val
[1])
6651 csky_insn
.val
[1] = csky_insn
.val
[2];
6653 csky_insn
.number
= 2;
6657 if (csky_insn
.isize
== 4
6658 && IS_CSKY_ARCH_801 (mach_flag
))
6660 if (csky_insn
.number
== 3)
6662 if (csky_insn
.val
[0] > 7)
6664 SET_ERROR_INTEGER (ERROR_REG_OVER_RANGE
, csky_insn
.val
[0]);
6665 csky_show_error (ERROR_REG_OVER_RANGE
, 1, NULL
, NULL
);
6667 if (csky_insn
.val
[1] > 7)
6669 SET_ERROR_INTEGER (ERROR_REG_OVER_RANGE
, csky_insn
.val
[1]);
6670 csky_show_error (ERROR_REG_OVER_RANGE
, 2, NULL
, NULL
);
6672 if (csky_insn
.val
[2] > 7)
6674 SET_ERROR_INTEGER (ERROR_REG_OVER_RANGE
, csky_insn
.val
[2]);
6675 csky_show_error (ERROR_REG_OVER_RANGE
, 3, NULL
, NULL
);
6680 if (csky_insn
.val
[0] > 15)
6682 SET_ERROR_INTEGER (ERROR_REG_OVER_RANGE
, csky_insn
.val
[0]);
6683 csky_show_error (ERROR_REG_OVER_RANGE
, 1, NULL
, NULL
);
6685 if (csky_insn
.val
[1] > 15)
6687 SET_ERROR_INTEGER (ERROR_REG_OVER_RANGE
, csky_insn
.val
[1]);
6688 csky_show_error (ERROR_REG_OVER_RANGE
, 2, NULL
, NULL
);
6694 /* Generate relax or reloc if necessary. */
6695 csky_generate_frags ();
6696 /* Generate the insn by mask. */
6697 csky_generate_insn ();
6698 /* Write inst to frag. */
6699 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6704 v2_work_rotlc (void)
6706 const char *name
= "addc";
6708 = (struct csky_opcode
*) str_hash_find (csky_opcodes_hash
, name
);
6709 csky_insn
.opcode_idx
= 0;
6710 if (csky_insn
.isize
== 2)
6713 csky_insn
.number
= 2;
6714 csky_insn
.val
[1] = csky_insn
.val
[0];
6718 csky_insn
.number
= 3;
6719 /* addc rz, rx, ry. */
6720 csky_insn
.val
[1] = csky_insn
.val
[0];
6721 csky_insn
.val
[2] = csky_insn
.val
[0];
6723 /* Generate relax or reloc if necessary. */
6724 csky_generate_frags ();
6725 /* Generate the insn by mask. */
6726 csky_generate_insn ();
6727 /* Write inst to frag. */
6728 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6733 v2_work_bgeni (void)
6735 const char *name
= NULL
;
6736 int imm
= csky_insn
.val
[1];
6746 = (struct csky_opcode
*) str_hash_find (csky_opcodes_hash
, name
);
6747 csky_insn
.opcode_idx
= 0;
6748 csky_insn
.val
[1] = val
;
6750 /* Generate relax or reloc if necessary. */
6751 csky_generate_frags ();
6752 /* Generate the insn by mask. */
6753 csky_generate_insn ();
6754 /* Write inst to frag. */
6755 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6762 const char *name
= "nor";
6764 = (struct csky_opcode
*) str_hash_find (csky_opcodes_hash
, name
);
6765 csky_insn
.opcode_idx
= 0;
6766 if (csky_insn
.number
== 1)
6768 csky_insn
.val
[1] = csky_insn
.val
[0];
6769 if (csky_insn
.val
[0] < 16)
6771 /* 16 bits nor rz, rz. */
6772 csky_insn
.number
= 2;
6773 csky_insn
.isize
= 2;
6777 csky_insn
.val
[2] = csky_insn
.val
[0];
6778 csky_insn
.number
= 3;
6779 csky_insn
.isize
= 4;
6782 if (csky_insn
.number
== 2)
6784 if (csky_insn
.val
[0] == csky_insn
.val
[1]
6785 && csky_insn
.val
[0] < 16)
6787 /* 16 bits nor rz, rz. */
6788 csky_insn
.number
= 2;
6789 csky_insn
.isize
= 2;
6793 csky_insn
.val
[2] = csky_insn
.val
[1];
6794 csky_insn
.number
= 3;
6795 csky_insn
.isize
= 4;
6799 /* Generate relax or reloc if necessary. */
6800 csky_generate_frags ();
6801 /* Generate the insn by mask. */
6802 csky_generate_insn ();
6803 /* Write inst to frag. */
6804 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6811 if (csky_insn
.e1
.X_add_symbol
== NULL
|| csky_insn
.e1
.X_op
== O_constant
)
6813 csky_show_error (ERROR_UNDEFINE
, 0, (void *)"operand is invalid", NULL
);
6817 if (IS_CSKY_ARCH_801 (mach_flag
))
6819 /* CK801 doesn't have 32-bit bt/bf insns or a jump insn with a
6820 range larger than SCOND_DISP16. Relax to a short jump around
6821 an unconditional branch, and give up if that overflows too. */
6822 csky_insn
.output
= frag_var (rs_machine_dependent
,
6826 csky_insn
.e1
.X_add_symbol
,
6827 csky_insn
.e1
.X_add_number
,
6829 csky_insn
.isize
= 2;
6830 csky_insn
.max
= SCOND_DISP16_LEN
;
6831 csky_insn
.inst
= csky_insn
.opcode
->op16
[0].opcode
;
6833 else if (do_long_jump
&& !IS_CSKY_ARCH_802 (mach_flag
))
6835 /* Generate relax with jcondition.
6836 Note that CK802 doesn't support the JMPI instruction so
6837 we cannot relax to a jump with a 32-bit offset. */
6838 csky_insn
.output
= frag_var (rs_machine_dependent
,
6842 csky_insn
.e1
.X_add_symbol
,
6843 csky_insn
.e1
.X_add_number
,
6845 csky_insn
.isize
= 2;
6846 csky_insn
.max
= JCOND_DISP32_LEN
;
6847 csky_insn
.inst
= csky_insn
.opcode
->op16
[0].opcode
;
6851 /* Generate relax with condition. */
6852 csky_insn
.output
= frag_var (rs_machine_dependent
,
6856 csky_insn
.e1
.X_add_symbol
,
6857 csky_insn
.e1
.X_add_number
,
6859 csky_insn
.isize
= 2;
6860 csky_insn
.max
= COND_DISP16_LEN
;
6861 csky_insn
.inst
= csky_insn
.opcode
->op16
[0].opcode
;
6863 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6871 if (csky_insn
.e1
.X_add_symbol
== NULL
|| csky_insn
.e1
.X_op
== O_constant
)
6873 csky_show_error (ERROR_UNDEFINE
, 0, (void *)"operand is invalid", NULL
);
6878 && !IS_CSKY_ARCH_801 (mach_flag
)
6879 && !IS_CSKY_ARCH_802 (mach_flag
))
6881 csky_insn
.output
= frag_var (rs_machine_dependent
,
6885 csky_insn
.e1
.X_add_symbol
,
6886 csky_insn
.e1
.X_add_number
,
6889 csky_insn
.inst
= csky_insn
.opcode
->op16
[0].opcode
;
6890 csky_insn
.max
= JUNCD_DISP32_LEN
;
6891 csky_insn
.isize
= 2;
6895 /* Generate relax with condition. */
6896 csky_insn
.output
= frag_var (rs_machine_dependent
,
6900 csky_insn
.e1
.X_add_symbol
,
6901 csky_insn
.e1
.X_add_number
,
6903 csky_insn
.isize
= 2;
6904 csky_insn
.max
= UNCD_DISP16_LEN
;
6905 csky_insn
.inst
= csky_insn
.opcode
->op16
[0].opcode
;
6908 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6912 #define SIZE_V2_MOVI16(x) ((addressT)x <= 0xff)
6913 #define SIZE_V2_MOVI32(x) ((addressT)x <= 0xffff)
6914 #define SIZE_V2_MOVIH(x) ((addressT)x <= 0xffffffff && (((addressT)x & 0xffff) == 0))
6919 int reg
= csky_insn
.val
[0];
6920 int output_literal
= csky_insn
.val
[1];
6923 /* If the second operand is O_constant, We can use movi/movih
6925 if (csky_insn
.e1
.X_op
== O_constant
)
6927 /* 801 only has movi16. */
6928 if (SIZE_V2_MOVI16 (csky_insn
.e1
.X_add_number
) && reg
< 8)
6930 /* movi16 instead. */
6931 csky_insn
.output
= frag_more (2);
6932 csky_insn
.inst
= (CSKYV2_INST_MOVI16
| (reg
<< 8)
6933 | (csky_insn
.e1
.X_add_number
));
6934 csky_insn
.isize
= 2;
6937 else if (SIZE_V2_MOVI32 (csky_insn
.e1
.X_add_number
)
6938 && !IS_CSKY_ARCH_801 (mach_flag
))
6940 /* movi32 instead. */
6941 csky_insn
.output
= frag_more (4);
6942 csky_insn
.inst
= (CSKYV2_INST_MOVI32
| (reg
<< 16)
6943 | (csky_insn
.e1
.X_add_number
));
6944 csky_insn
.isize
= 4;
6947 else if (SIZE_V2_MOVIH (csky_insn
.e1
.X_add_number
)
6948 && !IS_CSKY_ARCH_801 (mach_flag
))
6950 /* movih instead. */
6951 csky_insn
.output
= frag_more (4);
6952 csky_insn
.inst
= (CSKYV2_INST_MOVIH
| (reg
<< 16)
6953 | ((csky_insn
.e1
.X_add_number
>> 16) & 0xffff));
6954 csky_insn
.isize
= 4;
6961 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6967 struct literal
*p
= enter_literal (&csky_insn
.e1
, 0, 0, 0);
6968 /* Create a reference to pool entry. */
6969 csky_insn
.e1
.X_op
= O_symbol
;
6970 csky_insn
.e1
.X_add_symbol
= poolsym
;
6971 csky_insn
.e1
.X_add_number
= p
->offset
<< 2;
6973 /* If 16bit force. */
6974 if (csky_insn
.flag_force
== INSN_OPCODE16F
)
6976 /* Generate fixup. */
6979 csky_show_error (ERROR_UNDEFINE
, 0,
6980 (void *)"The register is out of range.", NULL
);
6983 csky_insn
.isize
= 2;
6984 csky_insn
.output
= frag_more (2);
6986 if (insn_reloc
== BFD_RELOC_CKCORE_TLS_GD32
6987 || insn_reloc
== BFD_RELOC_CKCORE_TLS_LDM32
6988 || insn_reloc
== BFD_RELOC_CKCORE_TLS_IE32
)
6990 literal_insn_offset
->tls_addend
.frag
= frag_now
;
6991 literal_insn_offset
->tls_addend
.offset
6992 = csky_insn
.output
- frag_now
->fr_literal
;
6994 csky_insn
.inst
= csky_insn
.opcode
->op16
[0].opcode
| (reg
<< 5);
6996 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
6997 2, &csky_insn
.e1
, 1, BFD_RELOC_CKCORE_PCREL_IMM7BY4
);
6999 else if (csky_insn
.flag_force
== INSN_OPCODE32F
)
7001 csky_insn
.isize
= 4;
7002 csky_insn
.output
= frag_more (4);
7003 if (insn_reloc
== BFD_RELOC_CKCORE_TLS_GD32
7004 || insn_reloc
== BFD_RELOC_CKCORE_TLS_LDM32
7005 || insn_reloc
== BFD_RELOC_CKCORE_TLS_IE32
)
7007 literal_insn_offset
->tls_addend
.frag
= frag_now
;
7008 literal_insn_offset
->tls_addend
.offset
7009 = csky_insn
.output
- frag_now
->fr_literal
;
7011 csky_insn
.inst
= csky_insn
.opcode
->op32
[0].opcode
| (reg
<< 16);
7012 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
7013 4, &csky_insn
.e1
, 1, BFD_RELOC_CKCORE_PCREL_IMM16BY4
);
7019 csky_insn
.isize
= 2;
7021 if (insn_reloc
== BFD_RELOC_CKCORE_TLS_GD32
7022 || insn_reloc
== BFD_RELOC_CKCORE_TLS_LDM32
7023 || insn_reloc
== BFD_RELOC_CKCORE_TLS_IE32
)
7024 literal_insn_offset
->tls_addend
.frag
= frag_now
;
7026 csky_insn
.output
= frag_var (rs_machine_dependent
,
7030 ? LRW2_DISP8
: LRW_DISP7
),
7031 csky_insn
.e1
.X_add_symbol
,
7032 csky_insn
.e1
.X_add_number
, 0);
7033 if (insn_reloc
== BFD_RELOC_CKCORE_TLS_GD32
7034 || insn_reloc
== BFD_RELOC_CKCORE_TLS_LDM32
7035 || insn_reloc
== BFD_RELOC_CKCORE_TLS_IE32
)
7037 if (literal_insn_offset
->tls_addend
.frag
->fr_next
!= frag_now
)
7038 literal_insn_offset
->tls_addend
.frag
7039 = literal_insn_offset
->tls_addend
.frag
->fr_next
;
7040 literal_insn_offset
->tls_addend
.offset
7042 - literal_insn_offset
->tls_addend
.frag
->fr_literal
);
7044 csky_insn
.inst
= csky_insn
.opcode
->op16
[0].opcode
| (reg
<< 5);
7045 csky_insn
.max
= LRW_DISP16_LEN
;
7046 csky_insn
.isize
= 2;
7050 csky_insn
.isize
= 4;
7051 csky_insn
.output
= frag_more (4);
7052 if (insn_reloc
== BFD_RELOC_CKCORE_TLS_GD32
7053 || insn_reloc
== BFD_RELOC_CKCORE_TLS_LDM32
7054 || insn_reloc
== BFD_RELOC_CKCORE_TLS_IE32
)
7056 literal_insn_offset
->tls_addend
.frag
= frag_now
;
7057 literal_insn_offset
->tls_addend
.offset
7058 = csky_insn
.output
- frag_now
->fr_literal
;
7060 csky_insn
.inst
= csky_insn
.opcode
->op32
[0].opcode
| (reg
<< 16);
7061 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
7062 4, &csky_insn
.e1
, 1, BFD_RELOC_CKCORE_PCREL_IMM16BY4
);
7066 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
7071 v2_work_lrsrsw (void)
7073 int reg
= csky_insn
.val
[0];
7074 csky_insn
.output
= frag_more (4);
7075 csky_insn
.inst
= csky_insn
.opcode
->op32
[0].opcode
| (reg
<< 21);
7076 csky_insn
.isize
= 4;
7080 case BFD_RELOC_CKCORE_GOT32
:
7081 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
7082 4, &csky_insn
.e1
, 0, BFD_RELOC_CKCORE_GOT_IMM18BY4
);
7084 case BFD_RELOC_CKCORE_PLT32
:
7085 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
7086 4, &csky_insn
.e1
, 0, BFD_RELOC_CKCORE_PLT_IMM18BY4
);
7089 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
7090 4, &csky_insn
.e1
, 1, BFD_RELOC_CKCORE_DOFFSET_IMM18BY4
);
7093 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
7101 || IS_CSKY_ARCH_801 (mach_flag
)
7102 || IS_CSKY_ARCH_802 (mach_flag
))
7104 csky_insn
.output
= frag_more (4);
7105 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
7106 4, &csky_insn
.e1
, 1, BFD_RELOC_CKCORE_PCREL_IMM26BY2
);
7107 csky_insn
.isize
= 4;
7108 csky_insn
.inst
= CSKYV2_INST_BSR32
;
7112 struct literal
*p
= enter_literal (&csky_insn
.e1
, 0, 0, 0);
7113 csky_insn
.output
= frag_more (4);
7114 csky_insn
.e1
.X_op
= O_symbol
;
7115 csky_insn
.e1
.X_add_symbol
= poolsym
;
7116 csky_insn
.e1
.X_add_number
= p
->offset
<< 2;
7117 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
7118 4, &csky_insn
.e1
, 1, BFD_RELOC_CKCORE_PCREL_IMM16BY4
);
7119 if (do_jsri2bsr
|| IS_CSKY_ARCH_810 (mach_flag
))
7120 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
7122 &(litpool
+ (csky_insn
.e1
.X_add_number
>> 2))->e
,
7124 BFD_RELOC_CKCORE_PCREL_JSR_IMM26BY2
);
7125 csky_insn
.inst
= CSKYV2_INST_JSRI32
;
7126 csky_insn
.isize
= 4;
7127 if (IS_CSKY_ARCH_810 (mach_flag
))
7129 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
7130 csky_insn
.output
= frag_more (4);
7131 dwarf2_emit_insn (0);
7132 /* Insert "mov r0, r0". */
7133 csky_insn
.inst
= CSKYV2_INST_MOV_R0_R0
;
7137 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
7146 struct literal
*p
= enter_literal (&csky_insn
.e1
, 1, 0, 0);
7147 csky_insn
.e1
.X_op
= O_symbol
;
7148 csky_insn
.e1
.X_add_symbol
= poolsym
;
7149 csky_insn
.e1
.X_add_number
= p
->offset
<< 2;
7151 /* Generate relax or reloc if necessary. */
7152 csky_generate_frags ();
7153 /* Generate the insn by mask. */
7154 csky_generate_insn ();
7155 /* Write inst to frag. */
7156 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
7157 /* Control 810 not to generate jsri. */
7158 if (IS_CSKY_ARCH_810 (mach_flag
))
7160 /* Look at adding the R_PCREL_JSRIMM26BY2.
7161 For 'jbsr .L1', this reloc type's symbol
7162 is bound to '.L1', isn't bound to literal pool. */
7163 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
7165 BFD_RELOC_CKCORE_PCREL_JSR_IMM26BY2
);
7166 csky_insn
.output
= frag_more (4);
7167 dwarf2_emit_insn (0);
7168 /* The opcode of "mov32 r0,r0". */
7169 csky_insn
.inst
= CSKYV2_INST_MOV_R0_R0
;
7170 /* The effect of this value is to check literal. */
7171 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
7178 v2_work_movih (void)
7180 int rz
= csky_insn
.val
[0];
7181 csky_insn
.output
= frag_more (4);
7182 csky_insn
.inst
= csky_insn
.opcode
->op32
[0].opcode
| (rz
<< 16);
7183 if (csky_insn
.e1
.X_op
== O_constant
)
7185 if (csky_insn
.e1
.X_unsigned
== 1 && csky_insn
.e1
.X_add_number
> 0xffff)
7187 csky_show_error (ERROR_IMM_OVERFLOW
, 2, NULL
, NULL
);
7190 else if (csky_insn
.e1
.X_unsigned
== 0 && csky_insn
.e1
.X_add_number
< 0)
7192 csky_show_error (ERROR_IMM_OVERFLOW
, 2, NULL
, NULL
);
7196 csky_insn
.inst
|= (csky_insn
.e1
.X_add_number
& 0xffff);
7198 else if (csky_insn
.e1
.X_op
== O_right_shift
7199 || (csky_insn
.e1
.X_op
== O_symbol
&& insn_reloc
!= BFD_RELOC_NONE
))
7201 if (csky_insn
.e1
.X_op_symbol
!= 0
7202 && symbol_constant_p (csky_insn
.e1
.X_op_symbol
)
7203 && S_GET_SEGMENT (csky_insn
.e1
.X_op_symbol
) == absolute_section
7204 && 16 == S_GET_VALUE (csky_insn
.e1
.X_op_symbol
))
7206 csky_insn
.e1
.X_op
= O_symbol
;
7207 if (insn_reloc
== BFD_RELOC_CKCORE_GOT32
)
7208 insn_reloc
= BFD_RELOC_CKCORE_GOT_HI16
;
7209 else if (insn_reloc
== BFD_RELOC_CKCORE_PLT32
)
7210 insn_reloc
= BFD_RELOC_CKCORE_PLT_HI16
;
7211 else if (insn_reloc
== BFD_RELOC_CKCORE_GOTPC
)
7212 insn_reloc
= BFD_RELOC_CKCORE_GOTPC_HI16
;
7213 else if (insn_reloc
== BFD_RELOC_CKCORE_GOTOFF
)
7214 insn_reloc
= BFD_RELOC_CKCORE_GOTOFF_HI16
;
7216 insn_reloc
= BFD_RELOC_CKCORE_ADDR_HI16
;
7217 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
7218 4, &csky_insn
.e1
, 0, insn_reloc
);
7222 void *arg
= (void *)"the second operand must be \"SYMBOL >> 16\"";
7223 csky_show_error (ERROR_UNDEFINE
, 0, arg
, NULL
);
7227 csky_insn
.isize
= 4;
7228 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
7236 int rz
= csky_insn
.val
[0];
7237 int rx
= csky_insn
.val
[1];
7238 csky_insn
.output
= frag_more (4);
7239 csky_insn
.inst
= csky_insn
.opcode
->op32
[0].opcode
| (rz
<< 21) | (rx
<< 16);
7240 if (csky_insn
.e1
.X_op
== O_constant
)
7242 if (csky_insn
.e1
.X_add_number
<= 0xffff
7243 && csky_insn
.e1
.X_add_number
>= 0)
7244 csky_insn
.inst
|= csky_insn
.e1
.X_add_number
;
7247 csky_show_error (ERROR_IMM_OVERFLOW
, 3, NULL
, NULL
);
7251 else if (csky_insn
.e1
.X_op
== O_bit_and
)
7253 if (symbol_constant_p (csky_insn
.e1
.X_op_symbol
)
7254 && S_GET_SEGMENT (csky_insn
.e1
.X_op_symbol
) == absolute_section
7255 && 0xffff == S_GET_VALUE (csky_insn
.e1
.X_op_symbol
))
7257 csky_insn
.e1
.X_op
= O_symbol
;
7258 if (insn_reloc
== BFD_RELOC_CKCORE_GOT32
)
7259 insn_reloc
= BFD_RELOC_CKCORE_GOT_LO16
;
7260 else if (insn_reloc
== BFD_RELOC_CKCORE_PLT32
)
7261 insn_reloc
= BFD_RELOC_CKCORE_PLT_LO16
;
7262 else if (insn_reloc
== BFD_RELOC_CKCORE_GOTPC
)
7263 insn_reloc
= BFD_RELOC_CKCORE_GOTPC_LO16
;
7264 else if (insn_reloc
== BFD_RELOC_CKCORE_GOTOFF
)
7265 insn_reloc
= BFD_RELOC_CKCORE_GOTOFF_LO16
;
7267 insn_reloc
= BFD_RELOC_CKCORE_ADDR_LO16
;
7268 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
7269 4, &csky_insn
.e1
, 0, insn_reloc
);
7273 void *arg
= (void *)"the third operand must be \"SYMBOL & 0xffff\"";
7274 csky_show_error (ERROR_UNDEFINE
, 0, arg
, NULL
);
7278 csky_insn
.isize
= 4;
7279 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
7283 /* Helper function to encode a single/double floating point constant
7284 into the instruction word for fmovis and fmovid instructions.
7285 The constant is in its IEEE single/double precision representation
7286 and is repacked into the internal 13-bit representation for these
7287 instructions with a diagnostic for overflow. Note that there is no
7288 rounding when converting to the smaller format, just an error if there
7289 is excess precision or the number is too small/large to be represented. */
7292 float_work_fmovi (void)
7294 int rx
= csky_insn
.val
[0];
7296 /* We already converted the float constant to the internal 13-bit
7297 representation so we just need to OR it in here. */
7298 csky_insn
.inst
= csky_insn
.opcode
->op32
[0].opcode
| rx
;
7299 csky_insn
.inst
|= (uint32_t) csky_insn
.e1
.X_add_number
;
7301 csky_insn
.output
= frag_more (4);
7302 csky_insn
.isize
= 4;
7303 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
7307 /* Like float_work_fmovi, but for FPUV3 fmovi.16, fmovi.32 and fmovi.64
7311 float_work_fpuv3_fmovi (void)
7313 int rx
= csky_insn
.val
[0];
7314 int idx
= csky_insn
.opcode_idx
;
7319 csky_insn
.inst
= csky_insn
.opcode
->op32
[idx
].opcode
| rx
;
7321 if (csky_insn
.opcode
->op32
[idx
].operand_num
== 3)
7323 /* fmovi.xx frz, imm9, imm4. */
7324 imm8
= csky_insn
.val
[1];
7325 imm4
= csky_insn
.val
[2];
7326 if (imm8
< 0 || (imm8
& 0x80000000))
7334 csky_show_error (ERROR_IMM_OVERFLOW
, 2, NULL
, NULL
);
7338 /* imm8 store at bit [25:20] and [9:8]. */
7339 /* imm4 store at bit [19:16]. */
7340 /* sign store at bit [5]. */
7341 csky_insn
.inst
= csky_insn
.inst
7342 | ((imm8
& 0x3) << 8)
7343 | ((imm8
& 0xfc) << 18)
7344 | ((imm4
& 0xf) << 16)
7349 csky_insn
.inst
|= (uint32_t) csky_insn
.e1
.X_add_number
;
7352 csky_insn
.output
= frag_more(4);
7353 csky_insn
.isize
= 4;
7354 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
7359 dsp_work_bloop (void)
7361 int reg
= csky_insn
.val
[0];
7362 csky_insn
.output
= frag_more (4);
7363 csky_insn
.inst
= csky_insn
.opcode
->op32
[0].opcode
| (reg
<< 16);
7364 csky_insn
.isize
= 4;
7366 if (csky_insn
.number
== 3
7367 && csky_insn
.e1
.X_op
== O_symbol
7368 && csky_insn
.e2
.X_op
== O_symbol
)
7370 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
7371 4, &csky_insn
.e1
, 1,
7372 BFD_RELOC_CKCORE_PCREL_BLOOP_IMM12BY4
);
7373 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
7374 4, &csky_insn
.e2
, 1,
7375 BFD_RELOC_CKCORE_PCREL_BLOOP_IMM4BY4
);
7377 else if (csky_insn
.number
== 2
7378 && csky_insn
.e1
.X_op
== O_symbol
)
7380 fix_new_exp (frag_now
, csky_insn
.output
-frag_now
->fr_literal
,
7381 4, &csky_insn
.e1
, 1,
7382 BFD_RELOC_CKCORE_PCREL_BLOOP_IMM12BY4
);
7383 if (csky_insn
.last_isize
== 2)
7384 csky_insn
.inst
|= (0xf << 12);
7385 else if (csky_insn
.last_isize
!= 0)
7386 csky_insn
.inst
|= (0xe << 12);
7389 void *arg
= (void *)"bloop can not be the first instruction"\
7390 "when the end label is not specified.\n";
7391 csky_show_error (ERROR_UNDEFINE
, 0, arg
, NULL
);
7395 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
7400 float_work_fpuv3_fstore(void)
7402 /* Generate relax or reloc if necessary. */
7403 csky_generate_frags ();
7404 /* Generate the insn by mask. */
7405 csky_generate_insn ();
7406 /* Write inst to frag. */
7407 csky_write_insn (csky_insn
.output
,
7415 /* The following are for assembler directive handling. */
7417 /* Helper function to adjust constant pool counts when we emit a
7418 data directive in the text section. FUNC is one of the standard
7419 gas functions to handle these directives, like "stringer" for the
7420 .string directive, and ARG is the argument to FUNC. csky_pool_count
7421 essentially wraps the call with the constant pool magic. */
7424 csky_pool_count (void (*func
) (int), int arg
)
7426 const fragS
*curr_frag
= frag_now
;
7427 offsetT added
= -frag_now_fix_octets ();
7431 while (curr_frag
!= frag_now
)
7433 added
+= curr_frag
->fr_fix
;
7434 curr_frag
= curr_frag
->fr_next
;
7437 added
+= frag_now_fix_octets ();
7441 /* Support the .literals directive. */
7443 csky_s_literals (int ignore ATTRIBUTE_UNUSED
)
7446 demand_empty_rest_of_line ();
7449 /* Support the .string, etc directives. */
7451 csky_stringer (int append_zero
)
7453 if (now_seg
== text_section
)
7454 csky_pool_count (stringer
, append_zero
);
7456 stringer (append_zero
);
7458 /* We call check_literals here in case a large number of strings are
7459 being placed into the text section with a sequence of stringer
7460 directives. In theory we could be upsetting something if these
7461 strings are actually in an indexed table instead of referenced by
7462 individual labels. Let us hope that that never happens. */
7463 check_literals (2, 0);
7466 /* Support integer-mode constructors like .word, .byte, etc. */
7469 csky_cons (int nbytes
)
7471 mapping_state (MAP_DATA
);
7472 if (nbytes
== 4) /* @GOT. */
7476 bfd_reloc_code_real_type reloc
;
7479 reloc
= BFD_RELOC_NONE
;
7481 lex_got (&reloc
, NULL
);
7483 if (exp
.X_op
== O_symbol
&& reloc
!= BFD_RELOC_NONE
)
7485 reloc_howto_type
*howto
7486 = bfd_reloc_type_lookup (stdoutput
, reloc
);
7487 int size
= bfd_get_reloc_size (howto
);
7490 as_bad (ngettext ("%s relocations do not fit in %d byte",
7491 "%s relocations do not fit in %d bytes",
7493 howto
->name
, nbytes
);
7496 register char *p
= frag_more ((int) nbytes
);
7497 int offset
= nbytes
- size
;
7499 fix_new_exp (frag_now
,
7500 p
- frag_now
->fr_literal
+ offset
,
7501 size
, &exp
, 0, reloc
);
7505 emit_expr (&exp
, (unsigned int) nbytes
);
7506 if (now_seg
== text_section
)
7509 while (*input_line_pointer
++ == ',');
7511 /* Put terminator back into stream. */
7512 input_line_pointer
--;
7513 demand_empty_rest_of_line ();
7518 if (now_seg
== text_section
)
7519 csky_pool_count (cons
, nbytes
);
7523 /* In theory we ought to call check_literals (2,0) here in case
7524 we need to dump the literal table. We cannot do this however,
7525 as the directives that we are intercepting may be being used
7526 to build a switch table, and we must not interfere with its
7527 contents. Instead we cross our fingers and pray... */
7530 /* Support floating-mode constant directives like .float and .double. */
7533 csky_float_cons (int float_type
)
7535 mapping_state (MAP_DATA
);
7536 if (now_seg
== text_section
)
7537 csky_pool_count (float_cons
, float_type
);
7539 float_cons (float_type
);
7541 /* See the comment in csky_cons () about calling check_literals.
7542 It is unlikely that a switch table will be constructed using
7543 floating point values, but it is still likely that an indexed
7544 table of floating point constants is being created by these
7545 directives, so again we must not interfere with their placement. */
7548 /* Support the .fill directive. */
7551 csky_fill (int ignore
)
7553 if (now_seg
== text_section
)
7554 csky_pool_count (s_fill
, ignore
);
7558 check_literals (2, 0);
7561 /* Handle the section changing pseudo-ops. These call through to the
7562 normal implementations, but they dump the literal pool first. */
7565 csky_s_text (int ignore
)
7570 obj_elf_text (ignore
);
7577 csky_s_data (int ignore
)
7582 obj_elf_data (ignore
);
7589 csky_s_section (int ignore
)
7591 /* Scan forwards to find the name of the section. If the section
7592 being switched to is ".line" then this is a DWARF1 debug section
7593 which is arbitrarily placed inside generated code. In this case
7594 do not dump the literal pool because it is a) inefficient and
7595 b) would require the generation of extra code to jump around the
7597 char * ilp
= input_line_pointer
;
7599 while (*ilp
!= 0 && ISSPACE (*ilp
))
7602 if (strncmp (ilp
, ".line", 5) == 0
7603 && (ISSPACE (ilp
[5]) || *ilp
== '\n' || *ilp
== '\r'))
7609 obj_elf_section (ignore
);
7612 obj_coff_section (ignore
);
7617 csky_s_bss (int needs_align
)
7620 s_lcomm_bytes (needs_align
);
7625 csky_s_comm (int needs_align
)
7628 obj_elf_common (needs_align
);
7632 /* Handle the .no_literal_dump directive. */
7635 csky_noliteraldump (int ignore ATTRIBUTE_UNUSED
)
7637 do_noliteraldump
= 1;
7638 int insn_num
= get_absolute_expression ();
7639 /* The insn after '.no_literal_dump insn_num' is insn1,
7640 Don't dump literal pool between insn1 and insn(insn_num+1)
7641 The insn cannot be the insn generate literal, like lrw & jsri. */
7642 check_literals (0, insn_num
* 2);
7645 /* Handle the .align directive.
7646 We must check literals before doing alignment. For example, if
7647 '.align n', add (2^n-1) to poolspan and check literals. */
7650 csky_s_align_ptwo (int arg
)
7652 /* Get the .align's first absolute number. */
7653 char * temp_pointer
= input_line_pointer
;
7654 int align
= get_absolute_expression ();
7655 check_literals (0, (1 << align
) - 1);
7656 input_line_pointer
= temp_pointer
;
7662 /* Handle the .stack_size directive. */
7665 csky_stack_size (int arg ATTRIBUTE_UNUSED
)
7668 stack_size_entry
*sse
7669 = (stack_size_entry
*) xcalloc (1, sizeof (stack_size_entry
));
7672 if (exp
.X_op
== O_symbol
)
7673 sse
->function
= exp
.X_add_symbol
;
7676 as_bad (_("the first operand must be a symbol"));
7677 ignore_rest_of_line ();
7683 if (*input_line_pointer
!= ',')
7685 as_bad (_("missing stack size"));
7686 ignore_rest_of_line ();
7691 ++input_line_pointer
;
7693 if (exp
.X_op
== O_constant
)
7695 if (exp
.X_add_number
< 0 || exp
.X_add_number
> (offsetT
)0xffffffff)
7698 as_bad (_("value not in range [0, 0xffffffff]"));
7699 ignore_rest_of_line ();
7704 sse
->stack_size
= exp
.X_add_number
;
7708 as_bad (_("operand must be a constant"));
7709 ignore_rest_of_line ();
7714 if (*last_stack_size_data
!= NULL
)
7715 last_stack_size_data
= &((*last_stack_size_data
)->next
);
7717 *last_stack_size_data
= sse
;
7720 /* This table describes all the machine specific pseudo-ops the assembler
7721 has to support. The fields are:
7722 pseudo-op name without dot
7723 function to call to execute this pseudo-op
7724 Integer arg to pass to the function. */
7726 const pseudo_typeS md_pseudo_table
[] =
7728 { "export", s_globl
, 0 },
7729 { "import", s_ignore
, 0 },
7730 { "literals", csky_s_literals
, 0 },
7731 { "page", listing_eject
, 0 },
7733 /* The following are to intercept the placement of data into the text
7734 section (eg addresses for a switch table), so that the space they
7735 occupy can be taken into account when deciding whether or not to
7736 dump the current literal pool.
7737 XXX - currently we do not cope with the .space and .dcb.d directives. */
7738 { "ascii", csky_stringer
, 8 + 0 },
7739 { "asciz", csky_stringer
, 8 + 1 },
7740 { "byte", csky_cons
, 1 },
7741 { "dc", csky_cons
, 2 },
7742 { "dc.b", csky_cons
, 1 },
7743 { "dc.d", csky_float_cons
, 'd'},
7744 { "dc.l", csky_cons
, 4 },
7745 { "dc.s", csky_float_cons
, 'f'},
7746 { "dc.w", csky_cons
, 2 },
7747 { "dc.x", csky_float_cons
, 'x'},
7748 { "double", csky_float_cons
, 'd'},
7749 { "float", csky_float_cons
, 'f'},
7750 { "hword", csky_cons
, 2 },
7751 { "int", csky_cons
, 4 },
7752 { "long", csky_cons
, 4 },
7753 { "octa", csky_cons
, 16 },
7754 { "quad", csky_cons
, 8 },
7755 { "short", csky_cons
, 2 },
7756 { "single", csky_float_cons
, 'f'},
7757 { "string", csky_stringer
, 8 + 1 },
7758 { "word", csky_cons
, 4 },
7759 { "fill", csky_fill
, 0 },
7761 /* Allow for the effect of section changes. */
7762 { "text", csky_s_text
, 0 },
7763 { "data", csky_s_data
, 0 },
7764 { "bss", csky_s_bss
, 1 },
7766 { "comm", csky_s_comm
, 0 },
7768 { "section", csky_s_section
, 0 },
7769 { "section.s", csky_s_section
, 0 },
7770 { "sect", csky_s_section
, 0 },
7771 { "sect.s", csky_s_section
, 0 },
7772 /* When ".no_literal_dump N" is in front of insn1,
7773 and instruction sequence is:
7778 it means literals will not dump between insn1 and insnN+1
7779 The insn cannot itself generate literal, like lrw & jsri. */
7780 { "no_literal_dump", csky_noliteraldump
, 0 },
7781 { "align", csky_s_align_ptwo
, 0 },
7782 { "stack_size", csky_stack_size
, 0 },
7786 /* Implement tc_cfi_frame_initial_instructions. */
7789 csky_cfi_frame_initial_instructions (void)
7791 int sp_reg
= IS_CSKY_V1 (mach_flag
) ? 0 : 14;
7792 cfi_add_CFA_def_cfa_register (sp_reg
);
7795 /* Implement tc_regname_to_dw2regnum. */
7798 tc_csky_regname_to_dw2regnum (char *regname
)
7803 /* FIXME the reg should be parsed according to
7805 reg_num
= csky_get_reg_val (regname
, &len
);