1 /* tc-csky.c -- Assembler for C-SKY
2 Copyright (C) 1989-2024 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 bool v1_work_lrw (void);
150 bool v1_work_jbsr (void);
151 bool v1_work_fpu_fo (void);
152 bool v1_work_fpu_fo_fc (void);
153 bool v1_work_fpu_write (void);
154 bool v1_work_fpu_read (void);
155 bool v1_work_fpu_writed (void);
156 bool v1_work_fpu_readd (void);
157 bool v2_work_istack (void);
158 bool v2_work_btsti (void);
159 bool v2_work_addi (void);
160 bool v2_work_subi (void);
161 bool v2_work_add_sub (void);
162 bool v2_work_rotlc (void);
163 bool v2_work_bgeni (void);
164 bool v2_work_not (void);
165 bool v2_work_jbtf (void);
166 bool v2_work_jbr (void);
167 bool v2_work_lrw (void);
168 bool v2_work_lrsrsw (void);
169 bool v2_work_jbsr (void);
170 bool v2_work_jsri (void);
171 bool v2_work_movih (void);
172 bool v2_work_ori (void);
173 bool float_work_fmovi (void);
174 bool dsp_work_bloop (void);
175 bool float_work_fpuv3_fmovi (void);
176 bool float_work_fpuv3_fstore (void);
177 bool v2_work_addc (void);
179 /* csky-opc.h must be included after workers are declared. */
180 #include "opcodes/csky-opc.h"
181 #include "opcode/csky.h"
188 COND_DISP10
= 20, /* bt/bf_16. */
189 COND_DISP16
, /* bt/bf_32. */
191 SCOND_DISP10
, /* br_16 */
192 SCOND_DISP16
, /* !(bt/bf_32) + br_32. */
194 UNCD_DISP10
, /* br_16. */
195 UNCD_DISP16
, /* br_32. */
197 JCOND_DISP10
, /* bt/bf_16. */
198 JCOND_DISP16
, /* bt/bf_32. */
199 JCOND_DISP32
, /* !(bt/bf_32)/jmpi + literal. */
201 JUNCD_DISP10
, /* br_16. */
202 JUNCD_DISP16
, /* br_32. */
203 JUNCD_DISP32
, /* jmpi + literal. */
205 JCOMPZ_DISP16
, /* bez/bnez/bhz/blsz/blz/bhsz. */
206 JCOMPZ_DISP32
, /* !(jbez/jbnez/jblsz/jblz/jbhsz) + jmpi + literal. */
208 BSR_DISP26
, /* bsr_32. */
210 LRW_DISP7
, /* lrw16. */
211 LRW2_DISP8
, /* lrw16, -mno-bsr16,8 bit offset. */
212 LRW_DISP16
, /* lrw32. */
215 unsigned int mach_flag
= 0;
216 unsigned int arch_flag
= 0;
217 unsigned int other_flag
= 0;
218 uint64_t isa_flag
= 0;
219 unsigned int dsp_flag
= 0;
221 typedef struct stack_size_entry
223 struct stack_size_entry
*next
;
225 unsigned int stack_size
;
228 struct csky_arch_info
231 unsigned int arch_flag
;
232 unsigned int bfd_mach_flag
;
242 /* Macro information. */
243 struct csky_macro_info
246 /* How many operands : if operands == 5, all of 1,2,3,4 are ok. */
250 void (*handle_func
)(void);
253 struct csky_insn_info
255 /* Name of the opcode. */
257 /* Output instruction. */
259 /* Pointer for frag. */
261 /* End of instruction. */
263 /* CPU infomations. */
264 const struct csky_cpu_info
*cpu
;
265 /* Flag for INSN_OPCODE16F, INSN_OPCODE32F, INSN_OPCODE, INSN_MACRO. */
266 inst_flag flag_force
;
267 /* Operand number. */
269 struct csky_opcode
*opcode
;
270 struct csky_macro_info
*macro
;
271 /* Insn size for check_literal. */
273 unsigned int last_isize
;
274 /* Max size of insn for relax frag_var. */
276 /* Indicates which element is in csky_opcode_info op[] array. */
278 /* The value of each operand in instruction when layout. */
280 int val
[MAX_OPRND_NUM
];
287 /* The following are used for constant expressions. */
292 /* Literal pool data structures. */
295 unsigned short refcnt
;
297 unsigned char ispcrel
;
298 unsigned char unused
;
299 bfd_reloc_code_real_type r_type
;
301 struct tls_addend tls_addend
;
302 unsigned char isdouble
;
304 LITTLENUM_TYPE bignum
[SIZE_OF_LARGE_NUMBER
+ 6];
307 static void csky_idly (void);
308 static void csky_rolc (void);
309 static void csky_sxtrb (void);
310 static void csky_movtf (void);
311 static void csky_addc64 (void);
312 static void csky_subc64 (void);
313 static void csky_or64 (void);
314 static void csky_xor64 (void);
315 static void csky_neg (void);
316 static void csky_rsubi (void);
317 static void csky_arith (void);
318 static void csky_decne (void);
319 static void csky_lrw (void);
321 static enum bfd_reloc_code_real insn_reloc
;
323 /* Assembler operand parse errors use these identifiers. */
327 /* The following are errors. */
328 ERROR_CREG_ILLEGAL
= 0,
329 ERROR_REG_OVER_RANGE
,
330 ERROR_FREG_OVER_RANGE
,
331 ERROR_VREG_OVER_RANGE
,
333 ERROR_802J_REG_OVER_RANGE
,
337 ERROR_IMM_OVERFLOW
, /* 5 */
339 ERROR_JMPIX_OVER_RANGE
,
345 ERROR_MISSING_OPERAND
, /* 10 */
347 ERROR_MISSING_LBRACKET
,
348 ERROR_MISSING_RBRACKET
,
349 ERROR_MISSING_LSQUARE_BRACKETS
,
350 ERROR_MISSING_RSQUARE_BRACKETS
, /* 15 */
351 ERROR_MISSING_LANGLE_BRACKETS
,
352 ERROR_MISSING_RANGLE_BRACKETS
,
353 ERROR_OFFSET_UNALIGNED
,
356 ERROR_CPREG_ILLEGAL
, /* 20 */
358 ERROR_OPERANDS_ILLEGAL
,
359 ERROR_OPERANDS_NUMBER
,
360 ERROR_OPCODE_ILLEGAL
,
362 /* The following are warnings. */
366 /* Error and warning end. */
370 /* Global error state. ARG1 and ARG2 are opaque data interpreted
371 as appropriate for the error code. */
373 struct csky_error_state
375 enum error_number err_num
;
382 /* This macro is used to set error number and arg1 in the global state. */
384 #define SET_ERROR_STRING(err, msg) \
386 if (error_state.err_num > err) \
388 error_state.err_num = err; \
389 error_state.arg1 = (void *)msg; \
393 #define SET_ERROR_INTEGER(err, integer) \
395 if (error_state.err_num > err) \
397 error_state.err_num = err; \
398 error_state.arg_int = integer; \
402 /* Map error identifiers onto a format string, which will use
403 arg1 and arg2 from the global error state. */
404 struct csky_error_format_map
406 enum error_number num
;
410 static const struct csky_error_format_map err_formats
[] =
412 {ERROR_CREG_ILLEGAL
, "Operand %d error: control register is illegal."},
413 {ERROR_REG_OVER_RANGE
, "Operand %d error: r%d register is over range."},
414 {ERROR_FREG_OVER_RANGE
, "Operand %d error: vr%d register is over range."},
415 {ERROR_VREG_OVER_RANGE
, "Operand %d error: vr%d register is out of range."},
416 {ERROR_GREG_ILLEGAL
, "Operand %d error: general register is illegal."},
417 {ERROR_802J_REG_OVER_RANGE
, "Operand %d register %s out of range (802j only has registers:0-15,23,24,25,30)"},
418 {ERROR_REG_FORMAT
, "Operand %d error: %s."},
419 {ERROR_REG_LIST
, "Register list format is illegal."},
420 {ERROR_IMM_ILLEGAL
, "Operand %d is not an immediate."},
421 {ERROR_IMM_OVERFLOW
, "Operand %d immediate is overflow."},
422 {ERROR_IMM_POWER
, "immediate %d is not a power of two"},
423 {ERROR_JMPIX_OVER_RANGE
, "The second operand must be 16/24/32/40"},
424 {ERROR_EXP_CREG
, "Operand %d error: control register is expected."},
425 {ERROR_EXP_GREG
, "Operand %d error: general register is expected."},
426 {ERROR_EXP_CONSTANT
, "Operand %d error: constant is expected."},
427 {ERROR_EXP_EVEN_FREG
, "Operand %d error: even float register is expected."},
428 {ERROR_RELOC_ILLEGAL
, "@%s reloc is not supported"},
429 {ERROR_MISSING_OPERAND
, "Operand %d is missing."},
430 {ERROR_MISSING_COMMA
, "Missing ','"},
431 {ERROR_MISSING_LBRACKET
, "Missing '('"},
432 {ERROR_MISSING_RBRACKET
, "Missing ')'"},
433 {ERROR_MISSING_LSQUARE_BRACKETS
, "Missing '['"},
434 {ERROR_MISSING_RSQUARE_BRACKETS
, "Missing ']'"},
435 {ERROR_MISSING_LANGLE_BRACKETS
, "Missing '<'"},
436 {ERROR_MISSING_RANGLE_BRACKETS
, "Missing '>'"},
437 {ERROR_OFFSET_UNALIGNED
, "Operand %d is unaligned. It must be %d aligned!"},
438 {ERROR_BAD_END
, "Operands mismatch, it has a bad end: %s"},
439 {ERROR_UNDEFINE
, NULL
},
440 {ERROR_CPREG_ILLEGAL
, "Operand %d illegal, expect a cpreg(cpr0-cpr63)."},
441 {ERROR_OPCODE_PSRBIT
, "The operands must be 'ie'/'ee'/'fe'."},
442 {ERROR_OPERANDS_ILLEGAL
, "Operands mismatch: %s."},
443 {ERROR_OPERANDS_NUMBER
, "Operands number mismatch, %d operands expected."},
444 {ERROR_OPCODE_ILLEGAL
, "The instruction is not recognized."},
445 {WARNING_OPTIONS
, "Option %s is not support in %s."},
446 {WARNING_IDLY
, "idly %d is encoded to: idly 4 "},
447 {ERROR_NONE
, "There is no error."},
450 static int do_pic
= 0; /* for jbr/jbf/jbt relax jmpi reloc. */
451 static int do_pff
= -1; /* for insert two br ahead of literals. */
452 static int do_force2bsr
= -1; /* for jbsr->bsr. */
453 static int do_jsri2bsr
= 1; /* for jsri->bsr. */
454 static int do_nolrw
= 0; /* lrw to movih & ori, only for V2. */
455 static int do_long_jump
= -1; /* control if jbf,jbt,jbr relax to jmpi. */
456 static int do_extend_lrw
= -1; /* delete bsr16 in both two options,
457 add btesti16, lrw offset +1 in -melrw. */
458 static int do_func_dump
= 0; /* dump literals after every function. */
459 static int do_br_dump
= 1; /* work for -mabr/-mno-abr, control the literals dump. */
460 static int do_intr_stack
= -1; /* control interrupt stack module, 801&802&803
461 default on, 807&810, default off. */
462 static int float_abi
= 0;
464 #ifdef INCLUDE_BRANCH_STUB
465 static int do_use_branchstub
= -1;
467 static int do_use_branchstub
= 0;
470 /* These are only used for options parsing. Values are bitmasks and are
471 OR'ed into the processor flag bits in md_begin. */
472 static int do_opt_mmp
= 0;
473 static int do_opt_mcp
= 0;
474 static int do_opt_mcache
= 0;
475 static int do_opt_msecurity
= 0;
476 static int do_opt_mhard_float
= 0;
477 static int do_opt_mtrust
= 0;
478 static int do_opt_mdsp
= 0;
479 static int do_opt_medsp
= 0;
480 static int do_opt_mvdsp
= 0;
482 const relax_typeS
*md_relax_table
= NULL
;
483 struct literal
*literal_insn_offset
;
484 static struct literal litpool
[MAX_POOL_SIZE
];
485 static unsigned poolsize
= 0;
486 static unsigned poolnumber
= 0;
487 static unsigned long poolspan
= 0;
488 static unsigned int SPANPANIC
;
489 static unsigned int SPANCLOSE
;
490 static unsigned int SPANEXIT
;
492 static stack_size_entry
*all_stack_size_data
= NULL
;
493 static stack_size_entry
**last_stack_size_data
= &all_stack_size_data
;
495 /* Control by ".no_literal_dump N"
496 * 1 : don't dump literal pool between insn1 and insnN+1
498 static int do_noliteraldump
= 0;
500 /* Label for current pool. */
501 static symbolS
* poolsym
;
502 static char poolname
[8];
504 static bool mov_r1_before
;
505 static bool mov_r1_after
;
507 const relax_typeS csky_relax_table
[] =
509 /* C-SKY V1 relax table. */
510 {0, 0, 0, 0}, /* RELAX_NONE */
511 {0, 0, 0, 0}, /* RELAX_OVERFLOW */
516 { 0, 0, 0, 0 }, /* UNDEF_DISP */
517 { 2048, -2046, C12_LEN
, C (COND_JUMP
, DISP32
) }, /* DISP12 */
518 { 0, 0, C32_LEN
, 0 }, /* DISP32 */
519 { 0, 0, C32_LEN
, 0 }, /* UNDEF_WORD_DISP */
522 { 0, 0, 0, 0 }, /* UNDEF_DISP */
523 { 2048, -2046, U12_LEN
, C (UNCD_JUMP
, DISP32
) }, /* DISP12 */
524 { 0, 0, U32_LEN
, 0 }, /* DISP32 */
525 { 0, 0, U32_LEN
, 0 }, /* UNDEF_WORD_DISP */
528 { 0, 0, 0, 0 }, /* UNDEF_DISP */
529 { 2048, -2046, C12_LEN
, C (COND_JUMP_PIC
, DISP32
) }, /* DISP12 */
530 { 0, 0, C32_LEN_PIC
, 0 }, /* DISP32 */
531 { 0, 0, C32_LEN_PIC
, 0 }, /* UNDEF_WORD_DISP */
534 { 0, 0, 0, 0 }, /* UNDEF_DISP */
535 { 2048, -2046, U12_LEN
, C (UNCD_JUMP_PIC
, DISP32
) }, /* DISP12 */
536 { 0, 0, U32_LEN_PIC
, 0 }, /* DISP32 */
537 { 0, 0, U32_LEN_PIC
, 0 }, /* UNDEF_WORD_DISP */
539 /* C-SKY V2 relax table. */
540 /* forward backward length more */
541 { 1 KB
- 2, -1 KB
, COND_DISP10_LEN
, COND_DISP16
}, /* COND_DISP10 */
542 { 64 KB
- 2, -64 KB
, COND_DISP16_LEN
, RELAX_OVERFLOW
}, /* COND_DISP16 */
544 { 1 KB
- 2, -1 KB
, SCOND_DISP10_LEN
, SCOND_DISP16
}, /* SCOND_DISP10 */
545 { 64 KB
- 2, -64 KB
, SCOND_DISP16_LEN
, RELAX_OVERFLOW
}, /* SCOND_DISP16 */
547 { 1 KB
- 2, -1 KB
, UNCD_DISP10_LEN
, UNCD_DISP16
}, /* UNCD_DISP10 */
548 { 64 KB
- 2, -64 KB
, UNCD_DISP16_LEN
, RELAX_OVERFLOW
}, /* UNCD_DISP16 */
550 { 1 KB
- 2, -1 KB
, JCOND_DISP10_LEN
, JCOND_DISP16
}, /* JCOND_DISP10 */
551 { 64 KB
- 2, -64 KB
, JCOND_DISP16_LEN
, JCOND_DISP32
}, /* JCOND_DISP16 */
552 { 0, 0, JCOND_DISP32_LEN
, RELAX_NONE
}, /* JCOND_DISP32 */
554 { 1 KB
- 2, -1 KB
, JUNCD_DISP10_LEN
, JUNCD_DISP16
}, /* JUNCD_DISP10 */
555 { 64 KB
- 2, -64 KB
, JUNCD_DISP16_LEN
, JUNCD_DISP32
}, /* JUNCD_DISP16 */
556 { 0, 0, JUNCD_DISP32_LEN
, RELAX_NONE
}, /* JUNCD_DISP32 */
558 { 64 KB
- 2, -64 KB
, JCOMPZ_DISP16_LEN
, JCOMPZ_DISP32
}, /* JCOMPZ_DISP16 */
559 { 0, 0, JCOMPZ_DISP32_LEN
, RELAX_NONE
}, /* JCOMPZ_DISP32 */
561 { 64 MB
- 2, -64 MB
, BSR_DISP26_LEN
, RELAX_OVERFLOW
}, /* BSR_DISP26 */
563 { 508, 0, LRW_DISP7_LEN
, LRW_DISP16
}, /* LRW_DISP7 */
564 { 1016, 0, LRW_DISP7_LEN
, LRW_DISP16
}, /* LRW2_DISP8 */
565 { 64 KB
, 0, LRW_DISP16_LEN
, RELAX_OVERFLOW
}, /* LRW_DISP16 */
569 static void csky_write_insn (char *ptr
, valueT use
, int nbytes
);
570 void md_number_to_chars (char * buf
, valueT val
, int n
);
571 long md_pcrel_from_section (fixS
* fixP
, segT seg
);
573 /* C-SKY architecture table. */
574 const struct csky_arch_info csky_archs
[] =
576 {"ck510", CSKY_ARCH_510
, bfd_mach_ck510
},
577 {"ck610", CSKY_ARCH_610
, bfd_mach_ck610
},
578 {"ck801", CSKY_ARCH_801
, bfd_mach_ck801
},
579 {"ck802", CSKY_ARCH_802
, bfd_mach_ck802
},
580 {"ck803", CSKY_ARCH_803
, bfd_mach_ck803
},
581 {"ck807", CSKY_ARCH_807
, bfd_mach_ck807
},
582 {"ck810", CSKY_ARCH_810
, bfd_mach_ck810
},
583 {"ck860", CSKY_ARCH_860
, bfd_mach_ck860
},
587 #define CSKY_ARCH_807_BASE CSKY_ARCH_807 | CSKY_ARCH_DSP
588 #define CSKY_ARCH_810_BASE CSKY_ARCH_810 | CSKY_ARCH_DSP
590 struct csky_cpu_feature
593 unsigned int arch_flag
;
597 struct csky_cpu_version
604 #define CSKY_FEATURE_MAX 10
605 #define CSKY_CPU_REVERISON_MAX 10
610 unsigned int arch_flag
;
612 struct csky_cpu_feature features
[CSKY_FEATURE_MAX
];
613 struct csky_cpu_version ver
[CSKY_CPU_REVERISON_MAX
];
616 #define FEATURE_DSP_EXT(isa) \
617 {'e', CSKY_ARCH_DSP, isa}
618 #define FEATURE_DSP(isa) \
619 {'d', CSKY_ARCH_DSP, isa}
620 #define FEATURE_MMU() \
622 #define FEATURE_VDSP(isa) \
623 {'v', CSKY_ARCH_DSP, isa}
624 #define FEATURE_FLOAT(isa) \
625 {'f', CSKY_ARCH_FLOAT, isa}
626 #define FEATURE_TRUST(isa) \
628 #define FEATURE_JAVA(isa) \
629 {'j', CSKY_ARCH_JAVA, isa}
630 #define FEATURE_SHIELD(isa) \
634 #define CSKY_FEATURES_DEF_NULL() \
635 {{0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}}
637 #define CSKY_FEATURES_DEF_e(isa_e) \
638 {FEATURE_DSP_EXT(isa_e), \
639 {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}}
641 #define CSKY_FEATURES_DEF_t(isa_t) \
642 {FEATURE_TRUST(isa_t), \
643 {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}}
645 #define CSKY_FEATURES_DEF_f(isa_f) \
646 {FEATURE_FLOAT(isa_f), \
647 {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}}
649 #define CSKY_FEATURES_DEF_v(isa_v) \
650 {FEATURE_VDSP(isa_v), \
651 {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}}
653 #define CSKY_FEATURES_DEF_ef(isa_e, isa_f) \
654 {FEATURE_DSP_EXT(isa_e), \
655 FEATURE_FLOAT(isa_f), \
656 {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}}
658 #define CSKY_FEATURES_DEF_jt(isa_j, isa_t) \
659 {FEATURE_JAVA(isa_j), \
660 FEATURE_TRUST(isa_t), \
661 {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}}
663 #define CSKY_FEATURES_DEF_efht(isa_e, isa_f, isa_h, isa_t) \
664 {FEATURE_DSP_EXT(isa_e), \
665 FEATURE_FLOAT(isa_f), \
666 FEATURE_SHIELD(isa_h), \
667 FEATURE_TRUST(isa_t), \
668 {0}, {0}, {0}, {0}, {0}, {0}}
670 #define CSKY_FEATURES_DEF_efv(isa_e, isa_f, isa_v) \
671 {FEATURE_DSP_EXT(isa_e), \
672 FEATURE_FLOAT(isa_f), \
673 FEATURE_VDSP(isa_v), \
674 {0}, {0}, {0}, {0}, {0}, {0}, {0}}
676 #define CSKY_FEATURES_DEF_eft(isa_e, isa_f, isa_t) \
677 {FEATURE_DSP_EXT(isa_e), \
678 FEATURE_FLOAT(isa_f), \
679 FEATURE_TRUST(isa_t), \
680 {0}, {0}, {0}, {0}, {0}, {0}, {0}}
682 #define CSKY_FEATURES_DEF_d(isa_d) \
683 {FEATURE_DSP(isa_d), \
684 {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}}
686 #define CSKY_FEATURES_DEF_df(isa_d, isa_f) \
687 {FEATURE_DSP(isa_d), \
688 FEATURE_FLOAT(isa_f), \
689 {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}}
691 #define CSKY_FEATURES_DEF_ft(isa_f, isa_t) \
692 {FEATURE_FLOAT(isa_f), \
693 FEATURE_TRUST(isa_t), \
694 {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}}
696 #define CSKY_FEATURES_DEF_tv(isa_t, isa_v) \
697 {FEATURE_TRUST(isa_t), \
698 FEATURE_VDSP(isa_v), \
699 {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}}
701 #define CSKY_FEATURES_DEF_fv(isa_f, isa_v) \
702 {FEATURE_FLOAT(isa_f), \
703 FEATURE_VDSP(isa_v), \
704 {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}}
707 #define CSKY_FEATURES_DEF_dft(isa_d, isa_f, isa_t) \
708 {FEATURE_DSP(isa_d), \
709 FEATURE_FLOAT(isa_f), \
710 FEATURE_TRUST(isa_t), \
711 {0}, {0}, {0}, {0}, {0}, {0}, {0}}
713 #define CSKY_FEATURES_DEF_dfv(isa_d, isa_f, isa_v) \
714 {FEATURE_DSP(isa_d), \
715 FEATURE_FLOAT(isa_f), \
716 FEATURE_VDSP(isa_v), \
717 {0}, {0}, {0}, {0}, {0}, {0}, {0}}
719 #define CSKY_FEATURES_DEF_ftv(isa_f, isa_t, isa_v) \
720 {FEATURE_FLOAT(isa_f), \
721 FEATURE_TRUST(isa_t), \
722 FEATURE_VDSP(isa_v), \
723 {0}, {0}, {0}, {0}, {0}, {0}, {0}}
725 #define CSKY_FEATURES_DEF_eftv(isa_e, isa_f, isa_t, isa_v) \
726 {FEATURE_DSP_EXT(isa_e), \
727 FEATURE_FLOAT(isa_f), \
728 FEATURE_TRUST(isa_t), \
729 FEATURE_VDSP(isa_v), \
730 {0}, {0}, {0}, {0}, {0}, {0}}
733 #define CSKY_CPU_REVERISON_r0p0(isa) \
735 #define CSKY_CPU_REVERISON_r1p0(isa) \
737 #define CSKY_CPU_REVERISON_r2p0(isa) \
739 #define CSKY_CPU_REVERISON_r3p0(isa) \
742 #define CSKY_CPU_REVERISON_RESERVED() \
743 {{0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}}
745 #define CSKY_CPU_REVERISON_R3(isa1, isa2, isa3) \
746 {CSKY_CPU_REVERISON_r1p0(isa1), \
747 CSKY_CPU_REVERISON_r2p0(isa2), \
748 CSKY_CPU_REVERISON_r3p0(isa3), \
749 {0}, {0}, {0}, {0}, {0}, {0}, {0}}
751 /* CSKY cpus table. */
752 const struct csky_cpu_info csky_cpus
[] =
754 #define CSKYV1_ISA_DSP (CSKY_ISA_DSP | CSKY_ISA_MAC_DSP)
755 #define CSKY_ISA_510 (CSKYV1_ISA_E1)
756 #define CSKY_ISA_610 (CSKYV1_ISA_E1 | CSKY_ISA_CP)
760 CSKY_FEATURES_DEF_e(CSKYV1_ISA_DSP
),
761 CSKY_CPU_REVERISON_RESERVED()},
763 CSKY_ARCH_510
| CSKY_ARCH_MAC
,
764 CSKY_ISA_510
| CSKY_ISA_MAC
| CSKY_ISA_MAC_DSP
,
765 CSKY_FEATURES_DEF_NULL(),
766 CSKY_CPU_REVERISON_RESERVED()},
767 {"ck610", CSKY_ARCH_610
, CSKY_ISA_610
,
768 CSKY_FEATURES_DEF_ef(CSKYV1_ISA_DSP
, CSKY_ISA_FLOAT_E1
),
769 CSKY_CPU_REVERISON_RESERVED()},
771 CSKY_ARCH_610
| CSKY_ARCH_MAC
,
772 CSKY_ISA_610
| CSKY_ISA_MAC
| CSKY_ISA_MAC_DSP
,
773 CSKY_FEATURES_DEF_NULL(),
774 CSKY_CPU_REVERISON_RESERVED()},
776 #define CSKY_ISA_801 (CSKYV2_ISA_E1 | CSKY_ISA_TRUST)
777 #define CSKYV2_ISA_DSP (CSKY_ISA_DSP | CSKY_ISA_DSP_1E2 | CSKY_ISA_DSPE60)
781 CSKY_FEATURES_DEF_t(0),
782 CSKY_CPU_REVERISON_RESERVED()},
783 #define CSKY_ISA_802 (CSKY_ISA_801 | CSKYV2_ISA_1E2 | CSKY_ISA_NVIC)
787 CSKY_FEATURES_DEF_jt(CSKY_ISA_JAVA
, 0),
788 CSKY_CPU_REVERISON_RESERVED()},
789 #define CSKY_ISA_803 (CSKY_ISA_802 | CSKYV2_ISA_2E3 | CSKY_ISA_MP)
790 #define CSKY_ISA_803R1 (CSKYV2_ISA_3E3R1)
791 #define CSKY_ISA_803R2 (CSKYV2_ISA_3E3R1 | CSKYV2_ISA_3E3R2)
792 #define CSKY_ISA_803R3 (CSKYV2_ISA_3E3R1 | CSKYV2_ISA_3E3R2 | CSKYV2_ISA_3E3R3)
793 #define CSKY_ISA_FLOAT_803 (CSKY_ISA_FLOAT_E1 | CSKY_ISA_FLOAT_1E3)
794 #define CSKY_ISA_EDSP (CSKYV2_ISA_3E3R1 | CSKYV2_ISA_3E3R3 | CSKY_ISA_DSP_ENHANCE)
797 CSKY_ISA_803
| CSKY_ISA_803R1
,
798 CSKY_FEATURES_DEF_eft(CSKYV2_ISA_DSP
, CSKY_ISA_FLOAT_803
, 0),
799 CSKY_CPU_REVERISON_RESERVED()},
803 CSKY_FEATURES_DEF_efht(CSKYV2_ISA_DSP
, CSKY_ISA_FLOAT_803
, 0, 0),
804 CSKY_CPU_REVERISON_R3(CSKY_ISA_803R1
, CSKY_ISA_803R2
, CSKY_ISA_803R3
)},
805 #define CSKY_ISA_804 (CSKY_ISA_803 | CSKY_ISA_803R3)
809 CSKY_FEATURES_DEF_efht(CSKY_ISA_EDSP
, CSKY_ISA_FLOAT_803
, 0, 0),
810 CSKY_CPU_REVERISON_RESERVED()},
811 #define CSKY_ISA_805 (CSKY_ISA_804 | CSKY_ISA_VDSP_2)
812 #define CSKY_ARCH_805V (CSKY_ARCH_805 | CSKY_ARCH_DSP)
813 #define CSKY_ISA_FLOAT_805 CSKY_ISA_FLOAT_803
817 CSKY_FEATURES_DEF_eft(CSKY_ISA_EDSP
, CSKY_ISA_FLOAT_805
, 0),
818 CSKY_CPU_REVERISON_RESERVED()},
819 #define CSKY_ISA_807 (CSKY_ISA_803 | CSKYV2_ISA_3E7 | CSKY_ISA_MP_1E2 | CSKY_ISA_CACHE | CSKYV2_ISA_DSP)
820 #define CSKY_ISA_FLOAT_807 (CSKY_ISA_FLOAT_803 | CSKY_ISA_FLOAT_3E4 | CSKY_ISA_FLOAT_1E2)
824 CSKY_FEATURES_DEF_ef(CSKYV2_ISA_DSP
, CSKY_ISA_FLOAT_807
),
825 CSKY_CPU_REVERISON_RESERVED()},
826 #define CSKY_ISA_810 (CSKY_ISA_807 | CSKYV2_ISA_7E10)
827 #define CSKY_ISA_FLOAT_810 (CSKY_ISA_FLOAT_E1 | CSKY_ISA_FLOAT_1E2)
829 CSKY_ARCH_810
| CSKY_ARCH_DSP
,
830 CSKY_ISA_810
| CSKY_ISA_VDSP
,
831 CSKY_FEATURES_DEF_NULL (),
832 CSKY_CPU_REVERISON_RESERVED()},
836 CSKY_FEATURES_DEF_eftv(0, CSKY_ISA_FLOAT_810
, 0, CSKY_ISA_VDSP
),
837 CSKY_CPU_REVERISON_RESERVED()},
838 #define CSKY_ISA_860 ((CSKY_ISA_810 & ~(CSKYV2_ISA_DSP)) | CSKYV2_ISA_10E60 | CSKY_ISA_803R3 | CSKY_ISA_DSPE60)
839 #define CSKY_ISA_860F (CSKY_ISA_860 | CSKY_ISA_FLOAT_7E60)
840 #define CSKY_ISA_VDSP_860 (CSKY_ISA_VDSP_2)
842 CSKY_ARCH_860
| CSKY_ARCH_DSP
,
843 CSKY_ISA_860
| CSKY_ISA_VDSP_860
,
844 CSKY_FEATURES_DEF_f(CSKY_ISA_FLOAT_7E60
),
845 CSKY_CPU_REVERISON_RESERVED()},
849 CSKY_FEATURES_DEF_fv(CSKY_ISA_FLOAT_7E60
, CSKY_ISA_VDSP_860
),
850 CSKY_CPU_REVERISON_RESERVED()},
852 /* It is a special cpu, support all instructions. */
853 #define CSKY_ISA_800 (CSKY_ISA_860 | CSKY_ISA_810 | CSKY_ISA_807 | CSKY_ISA_803)
857 CSKY_FEATURES_DEF_NULL(),
858 CSKY_CPU_REVERISON_RESERVED()},
861 #define CSKY_ISA_E801 (CSKY_ISA_801)
862 #define CSKY_ISA_E802 (CSKY_ISA_E801 | CSKYV2_ISA_1E2 | CSKY_ISA_NVIC)
863 #define CSKY_ISA_E803 (CSKY_ISA_E802 | CSKYV2_ISA_2E3 | CSKY_ISA_MP | CSKYV2_ISA_3E3R1 | CSKYV2_ISA_3E3R2 | CSKYV2_ISA_3E3R3)
864 #define CSKY_ISA_E804 (CSKY_ISA_E803)
865 #define CSKY_ISA_FLOAT_V1 (CSKY_ISA_FLOAT_E1 | CSKY_ISA_FLOAT_1E3)
869 CSKY_FEATURES_DEF_NULL(),
870 CSKY_CPU_REVERISON_RESERVED()},
874 CSKY_FEATURES_DEF_t(0),
875 CSKY_CPU_REVERISON_RESERVED()},
879 CSKY_FEATURES_DEF_t(0),
880 CSKY_CPU_REVERISON_RESERVED()},
884 CSKY_FEATURES_DEF_dft(CSKY_ISA_EDSP
, CSKY_ISA_FLOAT_V1
, 0),
885 CSKY_CPU_REVERISON_RESERVED()},
887 #define CSKY_ISA_S802 (CSKY_ISA_E801 | CSKYV2_ISA_1E2 | CSKY_ISA_NVIC | CSKY_ISA_TRUST)
888 #define CSKY_ISA_S803 (CSKY_ISA_S802 | CSKYV2_ISA_2E3 | CSKY_ISA_MP | CSKYV2_ISA_3E3R1 | CSKYV2_ISA_3E3R2 | CSKYV2_ISA_3E3R3)
892 CSKY_FEATURES_DEF_t(0),
893 CSKY_CPU_REVERISON_RESERVED()},
897 CSKY_FEATURES_DEF_t(0),
898 CSKY_CPU_REVERISON_RESERVED()},
899 #define CSKY_ISA_I805 (CSKY_ISA_S803)
901 CSKY_ARCH_805
| CSKY_ARCH_DSP
,
902 CSKY_ISA_I805
| CSKY_ISA_VDSP_2
,
903 CSKY_FEATURES_DEF_ft(CSKY_ISA_FLOAT_V1
, 0),
904 CSKY_CPU_REVERISON_RESERVED()},
905 #define CSKYV2_ISA_DSP (CSKY_ISA_DSP | CSKY_ISA_DSP_1E2 | CSKY_ISA_DSPE60)
906 #define CSKY_ISA_C807 (CSKY_ISA_E802 | CSKYV2_ISA_2E3 | CSKY_ISA_MP | CSKYV2_ISA_3E7 | CSKY_ISA_MP_1E2 | CSKY_ISA_CACHE | CSKYV2_ISA_DSP)
907 #define CSKY_ISA_FLOAT_C807 (CSKY_ISA_FLOAT_V1 | CSKY_ISA_FLOAT_3E4 | CSKY_ISA_FLOAT_1E2)
908 #define CSKY_ISA_FLOAT_C810 (CSKY_ISA_FLOAT_E1 | CSKY_ISA_FLOAT_1E2)
909 #define CSKY_ARCH_C810 (CSKY_ARCH_810 | CSKY_ARCH_FLOAT)
910 #define CSKY_ISA_C810 (CSKY_ISA_C807 | CSKYV2_ISA_7E10 | CSKY_ISA_FLOAT_C810)
911 #define CSKY_ARCH_C860 (CSKY_ARCH_860 | CSKY_ARCH_FLOAT)
912 #define CSKY_ISA_C860 (CSKY_ISA_860 | CSKY_ISA_FLOAT_7E60)
916 CSKY_FEATURES_DEF_fv(CSKY_ISA_FLOAT_C807
, CSKY_ISA_VDSP
),
917 CSKY_CPU_REVERISON_RESERVED()},
921 CSKY_FEATURES_DEF_tv(0, CSKY_ISA_VDSP
),
922 CSKY_CPU_REVERISON_RESERVED()},
926 CSKY_FEATURES_DEF_v(CSKY_ISA_VDSP_2
),
927 CSKY_CPU_REVERISON_RESERVED()},
928 #define CSKY_ISA_R807 (CSKY_ISA_E802 | CSKYV2_ISA_2E3 | CSKY_ISA_MP | CSKYV2_ISA_3E7 | CSKY_ISA_MP_1E2 | CSKY_ISA_CACHE | CSKYV2_ISA_DSP)
929 #define CSKY_ISA_FLOAT_R807 (CSKY_ISA_FLOAT_V1 | CSKY_ISA_FLOAT_3E4 | CSKY_ISA_FLOAT_1E2)
933 CSKY_FEATURES_DEF_f(CSKY_ISA_FLOAT_R807
),
934 CSKY_CPU_REVERISON_RESERVED()},
936 /* Start of private CPUs. */
937 /* End of private CPUs. */
942 int md_short_jump_size
= 2;
943 int md_long_jump_size
= 4;
945 /* This array holds the chars that always start a comment. If the
946 pre-processor is disabled, these aren't very useful. */
947 const char comment_chars
[] = "#";
949 /* This array holds the chars that only start a comment at the beginning of
950 a line. If the line seems to have the form '# 123 filename'
951 .line and .file directives will appear in the pre-processed output. */
952 /* Note that input_file.c hand checks for '#' at the beginning of the
953 first line of the input file. This is because the compiler outputs
954 #NO_APP at the beginning of its output. */
955 /* Also note that comments like this one will always work. */
956 const char line_comment_chars
[] = "#";
958 const char line_separator_chars
[] = ";";
960 /* Chars that can be used to separate mant
961 from exp in floating point numbers. */
962 const char EXP_CHARS
[] = "eE";
964 /* Chars that mean this number is a floating point constant.
968 const char FLT_CHARS
[] = "rRsSfFdDxXeEpP";
970 const char *md_shortopts
= "";
972 struct option md_longopts
[] = {
973 #define OPTION_MARCH (OPTION_MD_BASE + 0)
974 {"march", required_argument
, NULL
, OPTION_MARCH
},
975 #define OPTION_MCPU (OPTION_MD_BASE + 1)
976 {"mcpu", required_argument
, NULL
, OPTION_MCPU
},
977 #define OPTION_FLOAT_ABI (OPTION_MD_BASE + 2)
978 {"mfloat-abi", required_argument
, NULL
, OPTION_FLOAT_ABI
},
980 /* Remaining options just set boolean flags. */
981 {"EL", no_argument
, &target_big_endian
, 0},
982 {"mlittle-endian", no_argument
, &target_big_endian
, 0},
983 {"EB", no_argument
, &target_big_endian
, 1},
984 {"mbig-endian", no_argument
, &target_big_endian
, 1},
985 {"fpic", no_argument
, &do_pic
, 1},
986 {"pic", no_argument
, &do_pic
, 1},
987 {"mljump", no_argument
, &do_long_jump
, 1},
988 {"mno-ljump", no_argument
, &do_long_jump
, 0},
989 {"force2bsr", no_argument
, &do_force2bsr
, 1},
990 {"mforce2bsr", no_argument
, &do_force2bsr
, 1},
991 {"no-force2bsr", no_argument
, &do_force2bsr
, 0},
992 {"mno-force2bsr", no_argument
, &do_force2bsr
, 0},
993 {"jsri2bsr", no_argument
, &do_jsri2bsr
, 1},
994 {"mjsri2bsr", no_argument
, &do_jsri2bsr
, 1},
995 {"no-jsri2bsr", no_argument
, &do_jsri2bsr
, 0},
996 {"mno-jsri2bsr", no_argument
, &do_jsri2bsr
, 0},
997 {"mnolrw", no_argument
, &do_nolrw
, 1},
998 {"mno-lrw", no_argument
, &do_nolrw
, 1},
999 {"melrw", no_argument
, &do_extend_lrw
, 1},
1000 {"mno-elrw", no_argument
, &do_extend_lrw
, 0},
1001 {"mlaf", no_argument
, &do_func_dump
, 1},
1002 {"mliterals-after-func", no_argument
, &do_func_dump
, 1},
1003 {"mno-laf", no_argument
, &do_func_dump
, 0},
1004 {"mno-literals-after-func", no_argument
, &do_func_dump
, 0},
1005 {"mlabr", no_argument
, &do_br_dump
, 1},
1006 {"mliterals-after-br", no_argument
, &do_br_dump
, 1},
1007 {"mno-labr", no_argument
, &do_br_dump
, 0},
1008 {"mnoliterals-after-br", no_argument
, &do_br_dump
, 0},
1009 {"mistack", no_argument
, &do_intr_stack
, 1},
1010 {"mno-istack", no_argument
, &do_intr_stack
, 0},
1011 #ifdef INCLUDE_BRANCH_STUB
1012 {"mbranch-stub", no_argument
, &do_use_branchstub
, 1},
1013 {"mno-branch-stub", no_argument
, &do_use_branchstub
, 0},
1015 {"mhard-float", no_argument
, &do_opt_mhard_float
, CSKY_ARCH_FLOAT
},
1016 {"mmp", no_argument
, &do_opt_mmp
, CSKY_ARCH_MP
},
1017 {"mcp", no_argument
, &do_opt_mcp
, CSKY_ARCH_CP
},
1018 {"mcache", no_argument
, &do_opt_mcache
, CSKY_ARCH_CACHE
},
1019 {"msecurity", no_argument
, &do_opt_msecurity
, CSKY_ARCH_MAC
},
1020 {"mtrust", no_argument
, &do_opt_mtrust
, CSKY_ISA_TRUST
},
1021 {"mdsp", no_argument
, &do_opt_mdsp
, CSKY_DSP_FLAG_V1
},
1022 {"medsp", no_argument
, &do_opt_medsp
, CSKY_DSP_FLAG_V2
},
1023 {"mvdsp", no_argument
, &do_opt_mvdsp
, CSKY_ISA_VDSP
},
1026 size_t md_longopts_size
= sizeof (md_longopts
);
1028 static struct csky_insn_info csky_insn
;
1030 static htab_t csky_opcodes_hash
;
1031 static htab_t csky_macros_hash
;
1033 static struct csky_macro_info v1_macros_table
[] =
1035 {"idly", 1, CSKYV1_ISA_E1
, csky_idly
},
1036 {"rolc", 2, CSKYV1_ISA_E1
, csky_rolc
},
1037 {"rotlc", 2, CSKYV1_ISA_E1
, csky_rolc
},
1038 {"sxtrb0", 2, CSKYV1_ISA_E1
, csky_sxtrb
},
1039 {"sxtrb1", 2, CSKYV1_ISA_E1
, csky_sxtrb
},
1040 {"sxtrb2", 2, CSKYV1_ISA_E1
, csky_sxtrb
},
1041 {"movtf", 3, CSKYV1_ISA_E1
, csky_movtf
},
1042 {"addc64", 3, CSKYV1_ISA_E1
, csky_addc64
},
1043 {"subc64", 3, CSKYV1_ISA_E1
, csky_subc64
},
1044 {"or64", 3, CSKYV1_ISA_E1
, csky_or64
},
1045 {"xor64", 3, CSKYV1_ISA_E1
, csky_xor64
},
1049 static struct csky_macro_info v2_macros_table
[] =
1051 {"neg", 1, CSKYV2_ISA_E1
, csky_neg
},
1052 {"rsubi", 2, CSKYV2_ISA_1E2
, csky_rsubi
},
1053 {"incf", 1, CSKYV2_ISA_1E2
, csky_arith
},
1054 {"inct", 1, CSKYV2_ISA_1E2
, csky_arith
},
1055 {"decf", 1, CSKYV2_ISA_2E3
, csky_arith
},
1056 {"decgt", 1, CSKYV2_ISA_2E3
, csky_arith
},
1057 {"declt", 1, CSKYV2_ISA_2E3
, csky_arith
},
1058 {"decne", 1, CSKYV2_ISA_1E2
, csky_decne
},
1059 {"dect", 1, CSKYV2_ISA_1E2
, csky_arith
},
1060 {"lslc", 1, CSKYV2_ISA_1E2
, csky_arith
},
1061 {"lsrc", 1, CSKYV2_ISA_1E2
, csky_arith
},
1062 {"xsr", 1, CSKYV2_ISA_1E2
, csky_arith
},
1066 /* For option -mnolrw, replace lrw by movih & ori. */
1067 static struct csky_macro_info v2_lrw_macro_opcode
=
1068 {"lrw", 2, CSKYV2_ISA_1E2
, csky_lrw
};
1070 /* This function is used to show errors or warnings. */
1073 csky_show_error (enum error_number err
, int idx
, void *arg1
, void *arg2
)
1075 if (err
== ERROR_NONE
)
1080 case ERROR_REG_LIST
:
1081 case ERROR_OPCODE_PSRBIT
:
1082 case ERROR_OPCODE_ILLEGAL
:
1083 case ERROR_JMPIX_OVER_RANGE
:
1084 case ERROR_MISSING_COMMA
:
1085 case ERROR_MISSING_LBRACKET
:
1086 case ERROR_MISSING_RBRACKET
:
1087 case ERROR_MISSING_LSQUARE_BRACKETS
:
1088 case ERROR_MISSING_RSQUARE_BRACKETS
:
1089 case ERROR_MISSING_LANGLE_BRACKETS
:
1090 case ERROR_MISSING_RANGLE_BRACKETS
:
1091 /* Add NULL to fix warnings. */
1092 as_bad (_(err_formats
[err
].fmt
), NULL
);
1094 case ERROR_CREG_ILLEGAL
:
1095 case ERROR_GREG_ILLEGAL
:
1096 case ERROR_IMM_ILLEGAL
:
1097 case ERROR_IMM_OVERFLOW
:
1098 case ERROR_EXP_CREG
:
1099 case ERROR_EXP_GREG
:
1100 case ERROR_EXP_CONSTANT
:
1101 case ERROR_EXP_EVEN_FREG
:
1102 case ERROR_MISSING_OPERAND
:
1103 case ERROR_CPREG_ILLEGAL
:
1104 as_bad (_(err_formats
[err
].fmt
), idx
);
1106 case ERROR_OPERANDS_NUMBER
:
1107 case ERROR_IMM_POWER
:
1108 as_bad (_(err_formats
[err
].fmt
), error_state
.arg_int
);
1111 case ERROR_OFFSET_UNALIGNED
:
1112 as_bad (_(err_formats
[err
].fmt
), idx
, error_state
.arg_int
);
1114 case ERROR_RELOC_ILLEGAL
:
1116 case ERROR_OPERANDS_ILLEGAL
:
1117 as_bad (_(err_formats
[err
].fmt
), (char *)arg1
);
1119 case ERROR_REG_OVER_RANGE
:
1120 case ERROR_FREG_OVER_RANGE
:
1121 case ERROR_VREG_OVER_RANGE
:
1122 as_bad (_(err_formats
[err
].fmt
), idx
, error_state
.arg_int
);
1124 case ERROR_802J_REG_OVER_RANGE
:
1125 case ERROR_REG_FORMAT
:
1126 as_bad (_(err_formats
[err
].fmt
), idx
, (char *)arg1
);
1128 case ERROR_UNDEFINE
:
1129 /* Add NULL to fix warnings. */
1130 as_bad ((char *)arg1
, NULL
);
1133 as_warn (_(err_formats
[err
].fmt
), (long)arg1
);
1135 case WARNING_OPTIONS
:
1136 as_warn (_(err_formats
[err
].fmt
), (char *)arg1
, (char *)arg2
);
1143 /* Handle errors in branch relaxation. */
1146 csky_branch_report_error (const char* file
, unsigned int line
,
1147 symbolS
* sym
, offsetT val
)
1149 as_bad_where (file
? file
: _("unknown"),
1151 _("pcrel offset for branch to %s too far (0x%lx)"),
1152 sym
? S_GET_NAME (sym
) : _("<unknown>"),
1156 /* Set appropriate flags for the cpu matching STR. */
1159 parse_cpu (const char *str
)
1163 for (; csky_cpus
[i
].name
!= NULL
; i
++)
1164 if (strncasecmp (str
, csky_cpus
[i
].name
, strlen (csky_cpus
[i
].name
)) == 0)
1166 csky_insn
.cpu
= &csky_cpus
[i
];
1167 mach_flag
|= csky_cpus
[i
].arch_flag
;
1168 isa_flag
= csky_cpus
[i
].isa_flag
;
1169 const char *s
= str
+ strlen (csky_cpus
[i
].name
);
1172 const struct csky_cpu_feature
*feature
= csky_cpus
[i
].features
;
1173 const struct csky_cpu_version
*version
= csky_cpus
[i
].ver
;
1181 if (version
->r
== strtol (s
, &next
, 10))
1187 isa_flag
|= version
->isa_flag
;
1192 isa_flag
= isa_flag
& ~CSKYV2_ISA_DSP
;
1193 isa_flag
|= CSKY_ISA_EDSP
;
1197 /* Parse csky features. */
1198 while (feature
->unique
)
1200 if (feature
->unique
== *s
)
1204 if (feature
->unique
)
1206 isa_flag
|= feature
->isa_flag
;
1207 mach_flag
|= feature
->arch_flag
;
1218 as_bad (_("unknown cpu `%s'"), str
);
1221 /* Set appropriate flags for the arch matching STR. */
1224 parse_arch (const char *str
)
1227 for (; csky_cpus
[i
].name
!= NULL
; i
++)
1228 if (strcasecmp (str
, csky_cpus
[i
].name
) == 0)
1230 csky_insn
.cpu
= &csky_cpus
[i
];
1231 arch_flag
|= csky_cpus
[i
].arch_flag
;
1232 isa_flag
|= csky_cpus
[i
].isa_flag
;
1235 as_bad (_("unknown architecture `%s'"), str
);
1238 struct csky_option_value_table
1244 static const struct csky_option_value_table csky_float_abis
[] =
1246 {"hard", VAL_CSKY_FPU_ABI_HARD
},
1247 {"softfp", VAL_CSKY_FPU_ABI_SOFTFP
},
1248 {"soft", VAL_CSKY_FPU_ABI_SOFT
},
1253 parse_float_abi (const char *str
)
1255 const struct csky_option_value_table
* opt
;
1257 for (opt
= csky_float_abis
; opt
->name
!= NULL
; opt
++)
1258 if (strcasecmp (opt
->name
, str
) == 0)
1260 float_abi
= opt
->value
;
1264 as_bad (_("unknown floating point abi `%s'\n"), str
);
1269 /* Implement the TARGET_FORMAT macro. */
1272 elf32_csky_target_format (void)
1274 return (target_big_endian
1276 : "elf32-csky-little");
1280 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
1281 for use in the a.out file, and stores them in the array pointed to by buf.
1282 This knows about the endian-ness of the target machine and does
1283 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
1284 2 (short) and 4 (long) Floating numbers are put out as a series of
1285 LITTLENUMS (shorts, here at least). */
1288 md_number_to_chars (char * buf
, valueT val
, int n
)
1290 if (target_big_endian
)
1291 number_to_chars_bigendian (buf
, val
, n
);
1293 number_to_chars_littleendian (buf
, val
, n
);
1296 /* Get a log2(val). */
1299 csky_log_2 (unsigned int val
)
1302 if ((val
& (val
- 1)) == 0)
1303 for (; val
; val
>>= 1)
1306 csky_show_error (ERROR_IMM_POWER
, 0, (void *)(long)val
, NULL
);
1310 /* Output one instruction to the buffer at PTR. */
1313 csky_write_insn (char *ptr
, valueT use
, int nbytes
)
1316 md_number_to_chars (ptr
, use
, nbytes
);
1317 else /* 32-bit instruction. */
1319 /* Significant figures are in low bits. */
1320 md_number_to_chars (ptr
, use
>> 16, 2);
1321 md_number_to_chars (ptr
+ 2, use
& 0xFFFF, 2);
1325 /* Read an NBYTES instruction from the buffer at PTR. NBYTES should
1326 be either 2 or 4. This function is used in branch relaxation. */
1329 csky_read_insn (char *ptr
, int nbytes
)
1331 unsigned char *uptr
= (unsigned char *)ptr
;
1333 int lo
, hi
; /* hi/lo byte index in binary stream. */
1335 if (target_big_endian
)
1345 v
= uptr
[lo
] | (uptr
[hi
] << 8);
1349 v
|= uptr
[lo
+ 2] | (uptr
[hi
+ 2] << 8);
1354 /* Construct a label name into S from the 3-character prefix P and
1355 number N formatted as a 4-digit hex number. */
1358 make_internal_label (char *s
, const char *p
, int n
)
1360 static const char hex
[] = "0123456789ABCDEF";
1365 s
[3] = hex
[(n
>> 12) & 0xF];
1366 s
[4] = hex
[(n
>> 8) & 0xF];
1367 s
[5] = hex
[(n
>> 4) & 0xF];
1368 s
[6] = hex
[(n
) & 0xF];
1372 /* md_operand is a no-op on C-SKY; we do everything elsewhere. */
1375 md_operand (expressionS
*expressionP ATTRIBUTE_UNUSED
)
1380 /* Under ELF we need to default _GLOBAL_OFFSET_TABLE.
1381 Otherwise we have no need to default values of symbols. */
1384 md_undefined_symbol (char *name ATTRIBUTE_UNUSED
)
1392 /* Use IEEE format for floating-point constants. */
1395 md_atof (int type
, char *litP
, int *sizeP
)
1397 return ieee_md_atof (type
, litP
, sizeP
, target_big_endian
);
1400 /* Print option help to FP. */
1403 md_show_usage (FILE *fp
)
1406 const int margin
= 48;
1408 fprintf (fp
, _("C-SKY assembler options:\n"));
1411 -march=ARCH select architecture ARCH:"));
1412 for (i
= 0, n
= margin
; csky_archs
[i
].name
!= NULL
; i
++)
1414 int l
= strlen (csky_archs
[i
].name
);
1415 if (n
+ l
>= margin
)
1417 fprintf (fp
, "\n\t\t\t\t");
1425 fprintf (fp
, "%s", csky_archs
[i
].name
);
1430 -mcpu=CPU select processor CPU:"));
1431 const struct csky_cpu_feature
*feature
= NULL
;
1432 const struct csky_cpu_version
*version
= NULL
;
1433 for (i
= 0; csky_cpus
[i
].name
!= NULL
; i
++)
1435 fprintf (fp
, "\t\t\t\t%s", csky_cpus
[i
].name
);
1436 feature
= csky_cpus
[i
].features
;
1437 version
= csky_cpus
[i
].ver
;
1438 while (feature
->unique
)
1440 if ((feature
+ 1)->unique
)
1441 fprintf (fp
, "[%c]", feature
->unique
);
1446 if (csky_cpus
[i
].name
[0] == 'c'
1447 && csky_cpus
[i
].name
[1] == 'k')
1448 fprintf (fp
, "[r%d]", version
->r
);
1450 fprintf (fp
, "[-r%dp%d]", version
->r
, version
->p
);
1457 -mfloat-abi=ABI select float ABI:"));
1458 for (i
= 0, n
= margin
; csky_float_abis
[i
].name
!= NULL
; i
++)
1460 int l
= strlen (csky_float_abis
[i
].name
);
1461 if (n
+ l
>= margin
)
1463 fprintf (fp
, "\n\t\t\t\t");
1471 fprintf (fp
, "%s", csky_float_abis
[i
].name
);
1476 -EL -mlittle-endian generate little-endian output\n"));
1478 -EB -mbig-endian generate big-endian output\n"));
1480 -fpic -pic generate position-independent code\n"));
1483 -mljump transform jbf, jbt, jbr to jmpi (CK800 only)\n"));
1487 #ifdef INCLUDE_BRANCH_STUB
1489 -mbranch-stub enable branch stubs for PC-relative calls\n"));
1491 -mno-branch-stub\n"));
1495 -force2bsr -mforce2bsr transform jbsr to bsr\n"));
1497 -no-force2bsr -mno-force2bsr\n"));
1499 -jsri2bsr -mjsri2bsr transform jsri to bsr\n"));
1501 -no-jsri2bsr -mno-jsri2bsr\n"));
1504 -mnolrw -mno-lrw implement lrw as movih + ori\n"));
1506 -melrw enable extended lrw (CK800 only)\n"));
1511 -mlaf -mliterals-after-func emit literals after each function\n"));
1513 -mno-laf -mno-literals-after-func\n"));
1515 -mlabr -mliterals-after-br emit literals after branch instructions\n"));
1517 -mno-labr -mnoliterals-after-br\n"));
1520 -mistack enable interrupt stack instructions\n"));
1525 -mhard-float enable hard float instructions\n"));
1527 -mmp enable multiprocessor instructions\n"));
1529 -mcp enable coprocessor instructions\n"));
1531 -mcache enable cache prefetch instruction\n"));
1533 -msecurity enable security instructions\n"));
1535 -mtrust enable trust instructions\n"));
1537 -mdsp enable DSP instructions\n"));
1539 -medsp enable enhanced DSP instructions\n"));
1541 -mvdsp enable vector DSP instructions\n"));
1545 set_csky_attribute (void)
1547 if (mach_flag
& CSKY_ARCH_DSP
)
1549 if (dsp_flag
& CSKY_DSP_FLAG_V2
)
1552 if (!bfd_elf_add_obj_attr_int (stdoutput
, OBJ_ATTR_PROC
,
1553 Tag_CSKY_DSP_VERSION
,
1554 VAL_CSKY_DSP_VERSION_2
))
1557 else if (isa_flag
& CSKY_ISA_DSP
)
1559 /* Set DSP extension. */
1560 if (!bfd_elf_add_obj_attr_int (stdoutput
, OBJ_ATTR_PROC
,
1561 Tag_CSKY_DSP_VERSION
,
1562 VAL_CSKY_DSP_VERSION_EXTENSION
))
1565 /* Set VDSP attribute. */
1566 if (isa_flag
& CSKY_ISA_VDSP
)
1568 if (!bfd_elf_add_obj_attr_int (stdoutput
, OBJ_ATTR_PROC
,
1569 Tag_CSKY_VDSP_VERSION
,
1570 VAL_CSKY_VDSP_VERSION_1
))
1573 else if (isa_flag
& CSKY_ISA_VDSP_2
)
1575 if (!bfd_elf_add_obj_attr_int (stdoutput
, OBJ_ATTR_PROC
,
1576 Tag_CSKY_VDSP_VERSION
,
1577 VAL_CSKY_VDSP_VERSION_2
))
1582 if (mach_flag
& CSKY_ARCH_FLOAT
)
1584 unsigned int val
= VAL_CSKY_FPU_HARDFP_SINGLE
;
1585 if (IS_CSKY_ARCH_V1 (mach_flag
))
1587 if (!bfd_elf_add_obj_attr_int (stdoutput
, OBJ_ATTR_PROC
,
1588 Tag_CSKY_FPU_VERSION
,
1589 VAL_CSKY_FPU_VERSION_1
))
1594 if (isa_flag
& CSKY_ISA_FLOAT_3E4
)
1596 if (!bfd_elf_add_obj_attr_int (stdoutput
, OBJ_ATTR_PROC
,
1597 Tag_CSKY_FPU_VERSION
,
1598 VAL_CSKY_FPU_VERSION_2
))
1600 val
|= VAL_CSKY_FPU_HARDFP_DOUBLE
;
1604 if (!bfd_elf_add_obj_attr_int (stdoutput
, OBJ_ATTR_PROC
,
1605 Tag_CSKY_FPU_VERSION
,
1606 VAL_CSKY_FPU_VERSION_2
))
1610 if (!bfd_elf_add_obj_attr_int (stdoutput
, OBJ_ATTR_PROC
,
1611 Tag_CSKY_FPU_HARDFP
, val
))
1613 if (!bfd_elf_add_obj_attr_string (stdoutput
, OBJ_ATTR_PROC
,
1614 Tag_CSKY_FPU_NUMBER_MODULE
,
1617 if (!bfd_elf_add_obj_attr_int (stdoutput
, OBJ_ATTR_PROC
,
1624 if (!bfd_elf_add_obj_attr_int (stdoutput
, OBJ_ATTR_PROC
,
1625 Tag_CSKY_ISA_FLAGS
, isa_flag
))
1628 if (!bfd_elf_add_obj_attr_int (stdoutput
, OBJ_ATTR_PROC
,
1629 Tag_CSKY_ISA_EXT_FLAGS
, (isa_flag
>> 32)))
1635 /* Target-specific initialization and option handling. */
1640 unsigned int bfd_mach_flag
= 0;
1641 struct csky_opcode
const *opcode
;
1642 struct csky_macro_info
const *macro
;
1643 struct csky_arch_info
const *p_arch
;
1644 struct csky_cpu_info
const *p_cpu
;
1645 other_flag
= (do_opt_mmp
| do_opt_mcp
| do_opt_mcache
1646 | do_opt_msecurity
| do_opt_mhard_float
);
1647 dsp_flag
|= do_opt_mdsp
| do_opt_medsp
;
1648 isa_flag
|= do_opt_mtrust
| do_opt_mvdsp
;
1651 other_flag
|= CSKY_ARCH_DSP
;
1655 if (((mach_flag
& CSKY_ARCH_MASK
)
1656 != (arch_flag
& CSKY_ARCH_MASK
))
1658 as_warn ("-mcpu conflict with -march option, actually use -mcpu");
1660 else if (arch_flag
!= 0)
1661 mach_flag
|= arch_flag
| other_flag
;
1664 #ifdef TARGET_WITH_CPU
1665 parse_cpu (TARGET_WITH_CPU
);
1668 parse_cpu ("ck610");
1670 parse_cpu ("ck810");
1672 mach_flag
|= other_flag
;
1676 if (IS_CSKY_ARCH_610 (mach_flag
) || IS_CSKY_ARCH_510 (mach_flag
))
1678 if ((mach_flag
& CSKY_ARCH_MP
) && (mach_flag
& CSKY_ARCH_MAC
))
1679 as_fatal ("520/620 conflicts with -mmp option");
1680 else if ((mach_flag
& CSKY_ARCH_MP
) && (mach_flag
& CSKY_ARCH_DSP
))
1681 as_fatal ("510e/610e conflicts with -mmp option");
1682 else if ((mach_flag
& CSKY_ARCH_DSP
) && (mach_flag
& CSKY_ARCH_MAC
))
1683 as_fatal ("520/620 conflicts with 510e/610e or -mdsp option");
1685 if (IS_CSKY_ARCH_510 (mach_flag
) && (mach_flag
& CSKY_ARCH_FLOAT
))
1687 mach_flag
= (mach_flag
& (~CSKY_ARCH_MASK
));
1688 mach_flag
|= CSKY_ARCH_610
;
1691 /* Find bfd_mach_flag, it will set to bfd backend data. */
1692 for (p_arch
= csky_archs
; p_arch
->arch_flag
!= 0; p_arch
++)
1693 if ((mach_flag
& CSKY_ARCH_MASK
) == (p_arch
->arch_flag
& CSKY_ARCH_MASK
))
1695 if (!bfd_elf_add_obj_attr_string (stdoutput
, OBJ_ATTR_PROC
,
1696 Tag_CSKY_ARCH_NAME
, p_arch
->name
))
1697 as_fatal (_("error adding attribute: %s"),
1698 bfd_errmsg (bfd_get_error ()));
1699 bfd_mach_flag
= p_arch
->bfd_mach_flag
;
1703 /* Find isa_flag. */
1704 for (p_cpu
= csky_cpus
; p_cpu
->arch_flag
!= 0; p_cpu
++)
1705 if ((mach_flag
& CPU_ARCH_MASK
) == p_cpu
->arch_flag
)
1707 if (!bfd_elf_add_obj_attr_string (stdoutput
, OBJ_ATTR_PROC
,
1708 Tag_CSKY_CPU_NAME
, p_cpu
->name
))
1709 as_fatal (_("error adding attribute: %s"),
1710 bfd_errmsg (bfd_get_error ()));
1711 isa_flag
|= p_cpu
->isa_flag
;
1715 /* Check if -mdsp and -medsp conflict. If cpu is ck803, we will
1716 use enhanced dsp instruction. Otherwise, we will use normal dsp. */
1719 if (IS_CSKY_ARCH_803 (mach_flag
))
1721 if ((dsp_flag
& CSKY_DSP_FLAG_V1
))
1723 if (isa_flag
& CSKY_ISA_DSP_ENHANCE
)
1725 /* Option -mdsp conflicts with -mcpu=ck803ern,
1726 CPU already indicates the dsp version. */
1727 as_warn ("Option -mdsp conflicts with -mcpu=ck803ern which "
1728 "has indicated DSP version, ignoring -mdsp.");
1729 isa_flag
&= ~(CSKY_ISA_MAC_DSP
| CSKY_ISA_DSP
);
1730 isa_flag
|= CSKY_ISA_DSP_ENHANCE
;
1734 isa_flag
|= (CSKY_ISA_MAC_DSP
| CSKY_ISA_DSP
);
1735 isa_flag
&= ~CSKY_ISA_DSP_ENHANCE
;
1739 if ((dsp_flag
& CSKY_DSP_FLAG_V2
))
1741 isa_flag
&= ~(CSKY_ISA_MAC_DSP
| CSKY_ISA_DSP
);
1742 isa_flag
|= CSKY_ISA_DSP_ENHANCE
;
1745 if ((dsp_flag
& CSKY_DSP_FLAG_V1
)
1746 && (dsp_flag
& CSKY_DSP_FLAG_V2
))
1748 /* In 803, dspv1 is conflict with dspv2. We keep dspv2. */
1749 as_warn ("option -mdsp conflicts with -medsp, only enabling -medsp");
1750 dsp_flag
&= ~CSKY_DSP_FLAG_V1
;
1751 isa_flag
&= ~(CSKY_ISA_MAC_DSP
| CSKY_ISA_DSP
);
1752 isa_flag
|= CSKY_ISA_DSP_ENHANCE
;
1757 if (dsp_flag
& CSKY_DSP_FLAG_V2
)
1759 dsp_flag
&= ~CSKY_DSP_FLAG_V2
;
1760 isa_flag
&= ~CSKY_ISA_DSP_ENHANCE
;
1761 as_warn ("-medsp option is only supported by ck803s, ignoring -medsp");
1767 if (do_use_branchstub
== -1)
1768 do_use_branchstub
= !IS_CSKY_ARCH_V1 (mach_flag
);
1769 else if (do_use_branchstub
== 1)
1771 if (IS_CSKY_ARCH_V1 (mach_flag
))
1773 as_warn (_("C-SKY ABI v1 (ck510/ck610) does not support -mbranch-stub"));
1774 do_use_branchstub
= 0;
1776 else if (do_force2bsr
== 0)
1778 as_warn (_("-mno-force2bsr is ignored with -mbranch-stub"));
1783 if (IS_CSKY_ARCH_801 (mach_flag
) || IS_CSKY_ARCH_802 (mach_flag
))
1786 as_warn (_("-mno-force2bsr is ignored for ck801/ck802"));
1789 else if (do_force2bsr
== -1)
1790 do_force2bsr
= do_use_branchstub
;
1794 if (IS_CSKY_ARCH_V1 (mach_flag
))
1800 if (do_extend_lrw
== -1)
1802 if ((mach_flag
& CSKY_ARCH_MASK
) == CSKY_ARCH_801
1803 || (mach_flag
& CSKY_ARCH_MASK
) == CSKY_ARCH_802
1804 || (mach_flag
& CSKY_ARCH_MASK
) == CSKY_ARCH_803
1805 || (mach_flag
& CSKY_ARCH_MASK
) == CSKY_ARCH_860
)
1810 if (IS_CSKY_ARCH_801 (mach_flag
) || IS_CSKY_ARCH_802 (mach_flag
))
1812 if (do_long_jump
> 0)
1813 as_warn (_("-mljump is ignored for ck801/ck802"));
1816 else if (do_long_jump
== -1)
1818 if (do_intr_stack
== -1)
1820 /* control interrupt stack module, 801&802&803 default on
1821 807&810, default off. */
1822 if (IS_CSKY_ARCH_807 (mach_flag
) || IS_CSKY_ARCH_810 (mach_flag
))
1827 /* Add isa_flag(SIMP/CACHE/APS). */
1828 isa_flag
|= (mach_flag
& CSKY_ARCH_MAC
) ? CSKY_ISA_MAC
: 0;
1829 isa_flag
|= (mach_flag
& CSKY_ARCH_MP
) ? CSKY_ISA_MP
: 0;
1830 isa_flag
|= (mach_flag
& CSKY_ARCH_CP
) ? CSKY_ISA_CP
: 0;
1832 /* Set abi flag and get table address. */
1833 if (IS_CSKY_ARCH_V1 (mach_flag
))
1835 mach_flag
= mach_flag
| CSKY_ABI_V1
;
1836 opcode
= csky_v1_opcodes
;
1837 macro
= v1_macros_table
;
1838 SPANPANIC
= v1_SPANPANIC
;
1839 SPANCLOSE
= v1_SPANCLOSE
;
1840 SPANEXIT
= v1_SPANEXIT
;
1841 md_relax_table
= csky_relax_table
;
1845 mach_flag
= mach_flag
| CSKY_ABI_V2
;
1846 opcode
= csky_v2_opcodes
;
1847 macro
= v2_macros_table
;
1848 SPANPANIC
= v2_SPANPANIC
;
1851 SPANCLOSE
= v2_SPANCLOSE_ELRW
;
1852 SPANEXIT
= v2_SPANEXIT_ELRW
;
1856 SPANCLOSE
= v2_SPANCLOSE
;
1857 SPANEXIT
= v2_SPANEXIT
;
1859 md_relax_table
= csky_relax_table
;
1862 /* Establish hash table for opcodes and macros. */
1863 csky_macros_hash
= str_htab_create ();
1864 csky_opcodes_hash
= str_htab_create ();
1865 for ( ; opcode
->mnemonic
!= NULL
; opcode
++)
1866 if ((isa_flag
& (opcode
->isa_flag16
| opcode
->isa_flag32
)) != 0)
1867 str_hash_insert (csky_opcodes_hash
, opcode
->mnemonic
, opcode
, 0);
1868 for ( ; macro
->name
!= NULL
; macro
++)
1869 if ((isa_flag
& macro
->isa_flag
) != 0)
1870 str_hash_insert (csky_macros_hash
, macro
->name
, macro
, 0);
1871 if (do_nolrw
&& (isa_flag
& CSKYV2_ISA_1E2
) != 0)
1872 str_hash_insert (csky_macros_hash
,
1873 v2_lrw_macro_opcode
.name
, &v2_lrw_macro_opcode
, 0);
1874 /* Set e_flag to ELF Head. */
1875 bfd_set_private_flags (stdoutput
, mach_flag
| CSKY_VERSION_V1
);
1876 /* Set bfd_mach to bfd backend data. */
1877 bfd_set_arch_mach (stdoutput
, bfd_arch_csky
, bfd_mach_flag
);
1879 if (!set_csky_attribute ())
1880 as_fatal (_("error adding attribute: %s"),
1881 bfd_errmsg (bfd_get_error ()));
1884 /* The C-SKY assembler emits mapping symbols $t and $d to mark the
1885 beginning of a sequence of instructions and data (such as a constant pool),
1886 respectively. This is similar to what ARM does. */
1889 make_mapping_symbol (map_state state
, valueT value
, fragS
*frag
)
1892 const char * symname
;
1898 type
= BSF_NO_FLAGS
;
1902 type
= BSF_NO_FLAGS
;
1908 symbolP
= symbol_new (symname
, now_seg
, frag
, value
);
1909 symbol_get_bfdsym (symbolP
)->flags
|= type
| BSF_LOCAL
;
1912 /* We need to keep track of whether we are emitting code or data; this
1913 function switches state and emits a mapping symbol if necessary. */
1916 mapping_state (map_state state
)
1918 map_state current_state
1919 = seg_info (now_seg
)->tc_segment_info_data
.current_state
;
1921 if (current_state
== state
)
1923 else if (current_state
== MAP_UNDEFINED
&& state
== MAP_DATA
)
1925 else if (current_state
== MAP_UNDEFINED
&& state
== MAP_TEXT
)
1927 struct frag
* const frag_first
= seg_info (now_seg
)->frchainP
->frch_root
;
1928 if (frag_now
!= frag_first
|| frag_now_fix () > 0)
1929 make_mapping_symbol (MAP_DATA
, (valueT
) 0, frag_first
);
1932 seg_info (now_seg
)->tc_segment_info_data
.current_state
= state
;
1933 make_mapping_symbol (state
, (valueT
) frag_now_fix (), frag_now
);
1936 /* Dump the literal pool. */
1939 dump_literals (int isforce
)
1941 #define CSKYV1_BR_INSN 0xF000
1942 #define CSKYV2_BR_INSN 0x0400
1945 symbolS
* brarsym
= NULL
;
1947 /* V1 nop encoding: 0x1200 : mov r0, r0. */
1948 static char v1_nop_insn_big
[2] = {0x12, 0x00};
1949 static char v1_nop_insn_little
[2] = {0x00, 0x12};
1954 /* Must we branch around the literal table? */
1958 make_internal_label (brarname
, POOL_END_LABEL
, poolnumber
);
1959 brarsym
= symbol_make (brarname
);
1960 symbol_table_insert (brarsym
);
1961 mapping_state (MAP_TEXT
);
1962 if (IS_CSKY_ARCH_V1 (mach_flag
))
1965 = frag_var (rs_machine_dependent
,
1966 csky_relax_table
[C (UNCD_JUMP_S
, DISP32
)].rlx_length
,
1967 csky_relax_table
[C (UNCD_JUMP_S
, DISP12
)].rlx_length
,
1968 C (UNCD_JUMP_S
, 0), brarsym
, 0, 0);
1969 md_number_to_chars (csky_insn
.output
, CSKYV1_BR_INSN
, 2);
1974 = frag_var (rs_machine_dependent
,
1979 md_number_to_chars (csky_insn
.output
, CSKYV2_BR_INSN
, 2);
1982 /* Make sure that the section is sufficiently aligned and that
1983 the literal table is aligned within it. */
1987 csky_insn
.output
= frag_more (2);
1989 if (IS_CSKY_V1 (mach_flag
))
1990 br_self
= CSKYV1_BR_INSN
| 0x7ff;
1992 br_self
= CSKYV2_BR_INSN
;
1993 md_number_to_chars (csky_insn
.output
, br_self
, 2);
1996 csky_insn
.output
= frag_more (2);
1998 md_number_to_chars (csky_insn
.output
, br_self
, 2);
2001 mapping_state (MAP_DATA
);
2003 record_alignment (now_seg
, 2);
2004 if (IS_CSKY_ARCH_V1 (mach_flag
))
2005 frag_align_pattern (2,
2007 ? v1_nop_insn_big
: v1_nop_insn_little
),
2010 frag_align (2, 0, 3);
2012 colon (S_GET_NAME (poolsym
));
2014 for (i
= 0, p
= litpool
; i
< poolsize
; p
++)
2016 insn_reloc
= p
->r_type
;
2017 if (insn_reloc
== BFD_RELOC_CKCORE_TLS_IE32
2018 || insn_reloc
== BFD_RELOC_CKCORE_TLS_LDM32
2019 || insn_reloc
== BFD_RELOC_CKCORE_TLS_GD32
)
2020 literal_insn_offset
= p
;
2023 if (target_big_endian
)
2025 p
->e
.X_add_number
= p
->dbnum
>> 32;
2026 emit_expr (& p
->e
, 4);
2027 p
->e
.X_add_number
= p
->dbnum
& 0xffffffff;
2028 emit_expr (& p
->e
, 4);
2032 p
->e
.X_add_number
= p
->dbnum
& 0xffffffff;
2033 emit_expr (& p
->e
, 4);
2034 p
->e
.X_add_number
= p
->dbnum
>> 32;
2035 emit_expr (& p
->e
, 4);
2038 else if (p
->e
.X_op
== O_big
)
2040 memcpy (generic_bignum
, p
->bignum
, sizeof (p
->bignum
));
2041 emit_expr (& p
->e
, p
->e
.X_add_number
* CHARS_PER_LITTLENUM
);
2044 emit_expr (& p
->e
, 4);
2046 if (p
->e
.X_op
== O_big
)
2047 i
+= (p
->e
.X_add_number
& 1) +
2048 ((p
->e
.X_add_number
* CHARS_PER_LITTLENUM
) >> 2);
2050 i
+= (p
->isdouble
? 2 : 1);
2053 if (isforce
&& IS_CSKY_ARCH_V2 (mach_flag
))
2055 /* Add one nop insn at end of literal for disassembler. */
2056 mapping_state (MAP_TEXT
);
2057 csky_insn
.output
= frag_more (2);
2058 md_number_to_chars (csky_insn
.output
, CSKYV2_INST_NOP
, 2);
2061 insn_reloc
= BFD_RELOC_NONE
;
2063 if (brarsym
!= NULL
)
2064 colon (S_GET_NAME (brarsym
));
2068 static struct literal
*
2069 enter_literal (expressionS
*e
,
2071 unsigned char isdouble
,
2076 if (poolsize
>= MAX_POOL_SIZE
- 2)
2078 /* The literal pool is as full as we can handle. We have
2079 to be 2 entries shy of the 1024/4=256 entries because we
2080 have to allow for the branch (2 bytes) and the alignment
2081 (2 bytes before the first insn referencing the pool and
2082 2 bytes before the pool itself) == 6 bytes, rounds up
2085 /* Save the parsed symbol's reloc. */
2086 enum bfd_reloc_code_real last_reloc_before_dump
= insn_reloc
;
2088 insn_reloc
= last_reloc_before_dump
;
2093 /* Create new literal pool. */
2094 if (++ poolnumber
> 0xFFFF)
2095 as_fatal (_("more than 65K literal pools"));
2097 make_internal_label (poolname
, POOL_START_LABEL
, poolnumber
);
2098 poolsym
= symbol_make (poolname
);
2099 symbol_table_insert (poolsym
);
2103 /* Search pool for value so we don't have duplicates. */
2104 for (p
= litpool
,i
= 0; i
< poolsize
; p
++)
2106 if (e
->X_op
== p
->e
.X_op
2107 && e
->X_add_symbol
== p
->e
.X_add_symbol
2108 && e
->X_add_number
== p
->e
.X_add_number
2109 && ispcrel
== p
->ispcrel
2110 && insn_reloc
== p
->r_type
2111 && isdouble
== p
->isdouble
2112 && insn_reloc
!= BFD_RELOC_CKCORE_TLS_GD32
2113 && insn_reloc
!= BFD_RELOC_CKCORE_TLS_LDM32
2114 && insn_reloc
!= BFD_RELOC_CKCORE_TLS_LDO32
2115 && insn_reloc
!= BFD_RELOC_CKCORE_TLS_IE32
2116 && insn_reloc
!= BFD_RELOC_CKCORE_TLS_LE32
2117 && (e
->X_op
!= O_big
2118 || (memcmp (generic_bignum
, p
->bignum
,
2119 p
->e
.X_add_number
* sizeof (LITTLENUM_TYPE
)) == 0)))
2124 if (p
->e
.X_op
== O_big
)
2126 i
+= (p
->e
.X_add_number
>> 1);
2127 i
+= (p
->e
.X_add_number
& 0x1);
2130 i
+= (p
->isdouble
? 2 : 1);
2133 p
->ispcrel
= ispcrel
;
2135 p
->r_type
= insn_reloc
;
2136 p
->isdouble
= isdouble
;
2140 if (e
->X_op
== O_big
)
2141 memcpy (p
->bignum
, generic_bignum
, sizeof (p
->bignum
));
2143 if (insn_reloc
== BFD_RELOC_CKCORE_TLS_GD32
2144 || insn_reloc
== BFD_RELOC_CKCORE_TLS_LDM32
2145 || insn_reloc
== BFD_RELOC_CKCORE_TLS_IE32
)
2147 p
->tls_addend
.frag
= frag_now
;
2148 p
->tls_addend
.offset
= csky_insn
.output
- frag_now
->fr_literal
;
2149 literal_insn_offset
= p
;
2151 if (p
->e
.X_op
== O_big
) {
2152 poolsize
+= (p
->e
.X_add_number
>> 1);
2153 poolsize
+= (p
->e
.X_add_number
& 0x1);
2155 poolsize
+= (p
->isdouble
? 2 : 1);
2160 /* Check whether we must dump the literal pool here.
2161 kind == 0 is any old instruction.
2162 kind > 0 means we just had a control transfer instruction.
2163 kind == 1 means within a function.
2164 kind == 2 means we just left a function.
2166 OFFSET is the length of the insn being processed.
2168 SPANCLOSE and SPANEXIT are smaller numbers than SPANPANIC.
2169 SPANPANIC means that we must dump now.
2170 The dump_literals (1) call inserts a branch around the table, so
2171 we first look to see if its a situation where we won't have to
2172 insert a branch (e.g., the previous instruction was an unconditional
2175 SPANPANIC is the point where we must dump a single-entry pool.
2176 it accounts for alignments and an inserted branch.
2177 the 'poolsize*2' accounts for the scenario where we do:
2178 lrw r1,lit1; lrw r2,lit2; lrw r3,lit3
2179 Note that the 'lit2' reference is 2 bytes further along
2180 but the literal it references will be 4 bytes further along,
2181 so we must consider the poolsize into this equation.
2182 This is slightly over-cautious, but guarantees that we won't
2183 panic because a relocation is too distant. */
2186 check_literals (int kind
, int offset
)
2190 if ((poolspan
> SPANEXIT
|| do_func_dump
)
2192 && (do_br_dump
|| do_func_dump
))
2194 else if (poolspan
> SPANCLOSE
&& (kind
> 0) && do_br_dump
)
2197 >= (SPANPANIC
- (IS_CSKY_ARCH_V1 (mach_flag
) ? poolsize
* 2 : 0)))
2199 /* We have not dumped literal pool before insn1,
2200 and will not dump literal pool between insn1 and insnN+1,
2201 so reset poolspan to original length. */
2202 else if (do_noliteraldump
== 1)
2205 if (do_noliteraldump
== 1)
2206 do_noliteraldump
= 0;
2209 /* The next group of functions are helpers for parsing various kinds
2210 of instruction operand syntax. */
2212 /* Parse operands of the form
2213 <symbol>@GOTOFF+<nnn>
2214 and similar .plt or .got references.
2216 If we find one, set up the correct relocation in RELOC and copy the
2217 input string, minus the `@GOTOFF' into a malloc'd buffer for
2218 parsing by the calling routine. Return this buffer, and if ADJUST
2219 is non-null set it to the length of the string we removed from the
2220 input line. Otherwise return NULL. */
2223 lex_got (enum bfd_reloc_code_real
*reloc
,
2229 const enum bfd_reloc_code_real rel
;
2231 static const struct _gotrel gotrel
[] =
2233 { "GOTOFF", BFD_RELOC_CKCORE_GOTOFF
},
2234 { "GOTPC", BFD_RELOC_CKCORE_GOTPC
},
2235 { "GOTTPOFF", BFD_RELOC_CKCORE_TLS_IE32
},
2236 { "GOT", BFD_RELOC_CKCORE_GOT32
},
2237 { "PLT", BFD_RELOC_CKCORE_PLT32
},
2238 { "BTEXT", BFD_RELOC_CKCORE_TOFFSET_LO16
},
2239 { "BDATA", BFD_RELOC_CKCORE_DOFFSET_LO16
},
2240 { "TLSGD32", BFD_RELOC_CKCORE_TLS_GD32
},
2241 { "TLSLDM32", BFD_RELOC_CKCORE_TLS_LDM32
},
2242 { "TLSLDO32", BFD_RELOC_CKCORE_TLS_LDO32
},
2243 { "TPOFF", BFD_RELOC_CKCORE_TLS_LE32
}
2249 for (cp
= input_line_pointer
; *cp
!= '@'; cp
++)
2250 if (is_end_of_line
[(unsigned char) *cp
])
2253 for (j
= 0; j
< sizeof (gotrel
) / sizeof (gotrel
[0]); j
++)
2255 int len
= strlen (gotrel
[j
].str
);
2257 if (strncasecmp (cp
+ 1, gotrel
[j
].str
, len
) == 0)
2259 if (gotrel
[j
].rel
!= 0)
2261 *reloc
= gotrel
[j
].rel
;
2265 /* input_line_pointer is the str pointer after relocation
2266 token like @GOTOFF. */
2267 input_line_pointer
+= len
+ 1;
2268 return input_line_pointer
;
2271 csky_show_error (ERROR_RELOC_ILLEGAL
, 0,
2272 (void *)gotrel
[j
].str
, NULL
);
2277 /* Might be a symbol version string. Don't as_bad here. */
2281 /* Parse an expression, returning it in E. */
2284 parse_exp (char *s
, expressionS
*e
)
2289 /* Skip whitespace. */
2290 while (ISSPACE (*s
))
2293 save
= input_line_pointer
;
2294 input_line_pointer
= s
;
2296 insn_reloc
= BFD_RELOC_NONE
;
2298 lex_got (&insn_reloc
, NULL
);
2300 if (e
->X_op
== O_absent
)
2301 SET_ERROR_STRING (ERROR_MISSING_OPERAND
, NULL
);
2303 new = input_line_pointer
;
2304 input_line_pointer
= save
;
2309 /* Parse a floating-point number from S into its target representation.
2310 If ISDOUBLE is true, return the result in *DBNUM; otherwise
2311 it's returned in E->X_add_number. Returns the result of advancing
2312 S past the constant. */
2315 parse_fexp (char *s
, expressionS
*e
, unsigned char isdouble
, uint64_t *dbnum
)
2317 int length
; /* Number of chars in an object. */
2318 const char *err
= NULL
; /* Error from scanning float literal. */
2319 unsigned char temp
[8];
2321 /* input_line_pointer->1st char of a flonum (we hope!). */
2322 input_line_pointer
= s
;
2324 if (input_line_pointer
[0] == '0'
2325 && ISALPHA (input_line_pointer
[1]))
2326 input_line_pointer
+= 2;
2329 err
= md_atof ('d', (char *) temp
, &length
);
2331 err
= md_atof ('f', (char *) temp
, &length
);
2333 know (err
!= NULL
|| length
> 0);
2335 if (!is_end_of_line
[(unsigned char) *input_line_pointer
])
2336 as_bad (_("immediate operand required"));
2337 while (!is_end_of_line
[(unsigned char) *input_line_pointer
])
2338 input_line_pointer
++;
2342 as_bad (_("bad floating literal: %s"), err
);
2343 while (!is_end_of_line
[(unsigned char) *input_line_pointer
])
2344 input_line_pointer
++;
2345 know (is_end_of_line
[(unsigned char) input_line_pointer
[-1]]);
2346 return input_line_pointer
;
2349 e
->X_add_symbol
= 0x0;
2350 e
->X_op_symbol
= 0x0;
2351 e
->X_op
= O_constant
;
2358 if (target_big_endian
)
2359 fnum
= (((uint32_t) temp
[0] << 24)
2364 fnum
= (((uint32_t) temp
[3] << 24)
2368 e
->X_add_number
= fnum
;
2372 if (target_big_endian
)
2374 *dbnum
= (((uint32_t) temp
[0] << 24)
2379 *dbnum
|= (((uint32_t) temp
[4] << 24)
2386 *dbnum
= (((uint32_t) temp
[7] << 24)
2391 *dbnum
|= (((uint32_t) temp
[3] << 24)
2397 return input_line_pointer
;
2404 long reg ATTRIBUTE_UNUSED
)
2409 /* Indicate nothing there. */
2410 ep
->X_op
= O_absent
;
2414 s
= parse_exp (s
+ 1, &e
);
2419 SET_ERROR_STRING (ERROR_MISSING_RSQUARE_BRACKETS
, NULL
);
2426 s
= parse_exp (s
, &e
);
2427 if (BFD_RELOC_CKCORE_DOFFSET_LO16
== insn_reloc
2428 || BFD_RELOC_CKCORE_TOFFSET_LO16
== insn_reloc
)
2436 /* If the instruction has work, literal handling is in the work. */
2437 if (!csky_insn
.opcode
->work
)
2439 struct literal
*p
= enter_literal (&e
, ispcrel
, 0, 0);
2443 /* Create a reference to pool entry. */
2444 ep
->X_op
= O_symbol
;
2445 ep
->X_add_symbol
= poolsym
;
2446 ep
->X_add_number
= p
->offset
<< 2;
2452 static int float_to_half (void *f
, void *h
)
2456 unsigned int value_f
= *(unsigned int *)f
;
2457 unsigned short value_h
;
2459 imm_e
= ((value_f
>> 23) & 0xff);
2460 imm_f
= ((value_f
& 0x7fffff));
2462 imm_e
= ((imm_e
- 127 + 15) << 10);
2463 imm_f
= ((imm_f
& 0x7fe000) >> 13);
2465 value_h
= (value_f
& 0x80000000 ? 0x8000 : 0x0) | imm_e
| imm_f
;
2468 *(unsigned short *)h
= value_h
;
2474 parse_rtf (char *s
, int ispcrel
, expressionS
*ep
)
2477 struct literal
*p
= NULL
;
2480 /* Indicate nothing there. */
2481 ep
->X_op
= O_absent
;
2485 s
= parse_exp (s
+ 1, & e
);
2490 as_bad (_("missing ']'"));
2498 if (strstr(csky_insn
.opcode
->mnemonic
, "flrws")
2499 || strstr(csky_insn
.opcode
->mnemonic
, "flrw.32"))
2501 s
= parse_fexp (s
, &e
, 0, &dbnum
);
2502 p
= enter_literal (& e
, ispcrel
, 0, dbnum
);
2504 else if (strstr(csky_insn
.opcode
->mnemonic
, "flrwd")
2505 || strstr(csky_insn
.opcode
->mnemonic
, "flrw.64"))
2507 s
= parse_fexp (s
, &e
, 1, &dbnum
);
2508 p
= enter_literal (& e
, ispcrel
, 1, dbnum
);
2510 else if (strstr(csky_insn
.opcode
->mnemonic
, "flrwh")
2511 || strstr(csky_insn
.opcode
->mnemonic
, "flrw.16"))
2513 s
= parse_fexp (s
, &e
, 0, NULL
);
2514 e
.X_add_number
= float_to_half (&e
.X_add_number
, &e
.X_add_number
);
2515 p
= enter_literal (& e
, ispcrel
, 0, 0);
2518 as_bad (_("unrecognized opcode"));
2523 /* Create a reference to pool entry. */
2524 ep
->X_op
= O_symbol
;
2525 ep
->X_add_symbol
= poolsym
;
2526 ep
->X_add_number
= p
->offset
<< 2;
2532 parse_type_ctrlreg (char** oper
)
2541 if (TOLOWER (*(*oper
+ 0)) == 'c'
2542 && TOLOWER (*(*oper
+ 1)) == 'r'
2543 && ISDIGIT (*(*oper
+ 2)))
2545 /* The control registers are named crxx. */
2547 s
= parse_exp (s
, &e
);
2548 if (e
.X_op
== O_constant
)
2555 if (IS_CSKY_V2 (mach_flag
))
2564 else if (TOLOWER (*(*oper
+ 0)) == 'c'
2565 && TOLOWER (*(*oper
+ 1)) == 'r')
2570 SET_ERROR_STRING (ERROR_CREG_ILLEGAL
, s
);
2574 crx
= strtol(s
, &s
, 10);
2575 if (crx
< 0 || crx
> 31 || *s
!= ',')
2577 SET_ERROR_STRING (ERROR_CREG_ILLEGAL
, s
);
2581 sel
= strtol(s
, &s
, 10);
2582 if (sel
< 0 || sel
> 31 || *s
!= '>')
2584 SET_ERROR_STRING (ERROR_CREG_ILLEGAL
, s
);
2591 crx
= csky_get_control_regno (mach_flag
, s
, &s
, &sel
);
2594 SET_ERROR_STRING (ERROR_CREG_ILLEGAL
, s
);
2598 i
= (sel
<< 5) | crx
;
2602 i
= csky_get_control_regno (mach_flag
, s
, &s
, &sel
);
2605 SET_ERROR_STRING (ERROR_CREG_ILLEGAL
, s
);
2610 csky_insn
.val
[csky_insn
.idx
++] = i
;
2615 csky_get_reg_val (char *str
, int *len
)
2619 regno
= csky_get_general_regno (mach_flag
, str
, &s
);
2625 is_reg_sp_with_bracket (char **oper
)
2631 if (IS_CSKY_V1 (mach_flag
))
2639 reg
= csky_get_reg_val (*oper
, &len
);
2645 SET_ERROR_STRING (ERROR_UNDEFINE
,
2646 "Operand format is error. '(sp)' expected");
2650 csky_insn
.val
[csky_insn
.idx
++] = sp_idx
;
2654 SET_ERROR_STRING (ERROR_UNDEFINE
,
2655 "Operand format is error. '(sp)' expected");
2660 is_reg_sp (char **oper
)
2665 if (IS_CSKY_V1 (mach_flag
))
2670 /* ABI names: "sp". */
2671 if (memcmp (*oper
, "sp", 2) == 0)
2674 csky_insn
.val
[csky_insn
.idx
++] = sp_idx
;
2678 len
= sprintf (sp_name
, "r%d", sp_idx
);
2679 if (memcmp (*oper
, sp_name
, len
) == 0)
2682 csky_insn
.val
[csky_insn
.idx
++] = sp_idx
;
2690 csky_get_freg_val (char *str
, int *len
)
2694 if ((TOLOWER(str
[0]) == 'v' || TOLOWER(str
[0]) == 'f')
2695 && (TOLOWER(str
[1]) == 'r'))
2697 /* It is fpu register. */
2699 while (ISDIGIT (*s
))
2701 reg
= reg
* 10 + (*s
) - '0';
2714 is_reglist_legal (char **oper
)
2719 reg1
= csky_get_reg_val (*oper
, &len
);
2722 if (reg1
== -1 || (IS_CSKY_V1 (mach_flag
) && (reg1
== 0 || reg1
== 15)))
2724 SET_ERROR_STRING (ERROR_REG_FORMAT
,
2725 "The first reg must not be r0/r15");
2731 SET_ERROR_STRING (ERROR_REG_FORMAT
,
2732 "The operand format must be rx-ry");
2737 reg2
= csky_get_reg_val (*oper
, &len
);
2740 if (reg2
== -1 || (IS_CSKY_V1 (mach_flag
) && reg1
== 15))
2742 SET_ERROR_STRING (ERROR_REG_FORMAT
,
2743 "The operand format must be r15 in C-SKY V1");
2746 if (IS_CSKY_V2 (mach_flag
))
2750 SET_ERROR_STRING (ERROR_REG_FORMAT
,
2751 "The operand format must be rx-ry (rx < ry)");
2758 csky_insn
.val
[csky_insn
.idx
++] = reg1
;
2763 is_freglist_legal (char **oper
)
2769 reg1
= csky_get_freg_val (*oper
, &len
);
2774 SET_ERROR_STRING (ERROR_REG_FORMAT
,
2775 "The fpu register format is not recognized.");
2781 SET_ERROR_STRING (ERROR_REG_FORMAT
,
2782 "The operand format must be vrx-vry/frx-fry.");
2787 reg2
= csky_get_freg_val (*oper
, &len
);
2792 SET_ERROR_STRING (ERROR_REG_FORMAT
,
2793 "The fpu register format is not recognized.");
2798 SET_ERROR_STRING (ERROR_REG_FORMAT
,
2799 "The operand format must be rx-ry(rx < ry)");
2804 /* The fldm/fstm in CSKY_ISA_FLOAT_7E60 has 5 bits frz(reg1). */
2806 if (startswith (csky_insn
.opcode
->mnemonic
, "fstm")
2807 || startswith (csky_insn
.opcode
->mnemonic
, "fldm"))
2809 if ((!(isa_flag
& CSKY_ISA_FLOAT_7E60
)
2810 && (reg2
> (int)15 || reg1
> 15))
2811 || ((isa_flag
& CSKY_ISA_FLOAT_7E60
)
2812 && (reg2
> (int)31 || reg1
> (int)31)))
2814 /* ISA_FLOAT_E1 fstm/fldm fry-frx is within 15.
2815 ISA_FLOAT_7E60 fstm(u)/fldm(u) frx-fry is within 31. */
2816 SET_ERROR_STRING(ERROR_REG_FORMAT
, (void *)"frx-fry is over range");
2819 if ((mach_flag
& CSKY_ARCH_MASK
) == CSKY_ARCH_860
)
2826 if (reg2
> (int)0x3) {
2827 SET_ERROR_STRING(ERROR_REG_FORMAT
, (void *)"vry-vrx is over range");
2833 csky_insn
.val
[csky_insn
.idx
++] = reg1
;
2838 is_reglist_dash_comma_legal (char **oper
, struct operand
*oprnd
)
2846 while (**oper
!= '\n' && **oper
!= '\0')
2848 reg1
= csky_get_reg_val (*oper
, &len
);
2851 SET_ERROR_STRING (ERROR_REG_LIST
, NULL
);
2854 flag
|= (1 << reg1
);
2859 reg2
= csky_get_reg_val (*oper
, &len
);
2862 SET_ERROR_STRING (ERROR_REG_LIST
, NULL
);
2868 SET_ERROR_STRING (ERROR_REG_LIST
, NULL
);
2871 while (reg2
>= reg1
)
2873 flag
|= (1 << reg2
);
2880 /* The reglist: r4-r11, r15, r16-r17, r28. */
2881 #define REGLIST_BITS 0x10038ff0
2882 if (flag
& ~(REGLIST_BITS
))
2884 SET_ERROR_STRING (ERROR_REG_LIST
, NULL
);
2891 if (flag
& (1 << i
))
2898 if (flag
& (1 << 15))
2901 /* Check r16-r17. */
2906 if (flag
& (1 << i
))
2910 list
|= (temp
<< 5);
2913 if (flag
& (1 << 28))
2915 if (oprnd
->mask
== OPRND_MASK_0_4
&& (list
& ~OPRND_MASK_0_4
))
2917 SET_ERROR_STRING (ERROR_REG_LIST
, NULL
);
2920 csky_insn
.val
[csky_insn
.idx
++] = list
;
2925 is_reg_lshift_illegal (char **oper
, int is_float
)
2930 reg
= csky_get_reg_val (*oper
, &len
);
2933 SET_ERROR_STRING (ERROR_REG_FORMAT
, "The register must be r0-r31.");
2938 if ((*oper
)[0] != '<' || (*oper
)[1] != '<')
2940 SET_ERROR_STRING (ERROR_UNDEFINE
,
2941 "Operand format error; should be (rx, ry << n)");
2947 char *new_oper
= parse_exp (*oper
, &e
);
2948 if (e
.X_op
== O_constant
)
2951 /* The immediate must be in [0, 3]. */
2952 if (e
.X_add_number
< 0 || e
.X_add_number
> 3)
2954 SET_ERROR_STRING (ERROR_IMM_OVERFLOW
, NULL
);
2960 SET_ERROR_STRING (ERROR_EXP_CONSTANT
, NULL
);
2964 value
= (reg
<< 2) | e
.X_add_number
;
2966 value
= (reg
<< 5) | (1 << e
.X_add_number
);
2967 csky_insn
.val
[csky_insn
.idx
++] = value
;
2973 is_imm_within_range (char **oper
, int min
, int max
)
2977 char *new_oper
= parse_exp (*oper
, &e
);
2978 if (e
.X_op
== O_constant
)
2982 if (e
.X_add_number
< min
|| e
.X_add_number
> max
)
2985 SET_ERROR_STRING (ERROR_IMM_OVERFLOW
, NULL
);
2988 e
.X_add_number
|= 0x80000000;
2989 csky_insn
.val
[csky_insn
.idx
++] = e
.X_add_number
;
2992 SET_ERROR_STRING(ERROR_IMM_ILLEGAL
, NULL
);
2998 is_imm_within_range_ext (char **oper
, int min
, int max
, int ext
)
3002 char *new_oper
= parse_exp (*oper
, &e
);
3003 if (e
.X_op
== O_constant
)
3007 if ((int)e
.X_add_number
!= ext
3008 && (e
.X_add_number
< min
|| e
.X_add_number
> max
))
3011 SET_ERROR_STRING (ERROR_IMM_OVERFLOW
, NULL
);
3013 csky_insn
.val
[csky_insn
.idx
++] = e
.X_add_number
;
3017 SET_ERROR_STRING(ERROR_IMM_ILLEGAL
, NULL
);
3023 is_oimm_within_range (char **oper
, int min
, int max
)
3027 char *new_oper
= parse_exp (*oper
, &e
);
3028 if (e
.X_op
== O_constant
)
3032 if (e
.X_add_number
< min
|| e
.X_add_number
> max
)
3035 SET_ERROR_STRING (ERROR_IMM_OVERFLOW
, NULL
);
3037 csky_insn
.val
[csky_insn
.idx
++] = e
.X_add_number
- 1;
3040 SET_ERROR_STRING (ERROR_IMM_ILLEGAL
, NULL
);
3046 is_psr_bit (char **oper
)
3048 const struct psrbit
*bits
;
3051 if (IS_CSKY_V1 (mach_flag
))
3052 bits
= cskyv1_psr_bits
;
3054 bits
= cskyv2_psr_bits
;
3056 while (bits
[i
].name
!= NULL
)
3058 if (bits
[i
].isa
&& !(bits
[i
].isa
& isa_flag
))
3063 if (strncasecmp (*oper
, bits
[i
].name
, strlen (bits
[i
].name
)) == 0)
3065 *oper
+= strlen (bits
[i
].name
);
3066 csky_insn
.val
[csky_insn
.idx
] |= bits
[i
].value
;
3071 SET_ERROR_STRING (ERROR_OPCODE_PSRBIT
, NULL
);
3076 parse_type_cpidx (char** oper
)
3080 if (s
[0] == 'c' && s
[1] == 'p')
3082 if (ISDIGIT (s
[2]) && ISDIGIT (s
[3]) && ! ISDIGIT (s
[4]))
3084 idx
= (s
[2] - '0') * 10 + s
[3] - '0';
3087 else if (ISDIGIT (s
[2]) && !ISDIGIT (s
[3]))
3098 *oper
= parse_exp (*oper
, &e
);
3099 if (e
.X_op
!= O_constant
)
3101 /* Can not recognize the operand. */
3104 idx
= e
.X_add_number
;
3107 csky_insn
.val
[csky_insn
.idx
++] = idx
;
3113 parse_type_cpreg (char** oper
)
3117 if (strncasecmp (*oper
, "cpr", 3) != 0)
3119 SET_ERROR_STRING(ERROR_CPREG_ILLEGAL
, *oper
);
3125 *oper
= parse_exp (*oper
, &e
);
3126 if (e
.X_op
!= O_constant
)
3128 SET_ERROR_STRING(ERROR_CPREG_ILLEGAL
, *oper
);
3132 csky_insn
.val
[csky_insn
.idx
++] = e
.X_add_number
;
3138 parse_type_cpcreg (char** oper
)
3142 if (strncasecmp (*oper
, "cpcr", 4) != 0)
3144 SET_ERROR_STRING(ERROR_CPREG_ILLEGAL
, *oper
);
3150 *oper
= parse_exp (*oper
, &e
);
3151 if (e
.X_op
!= O_constant
)
3153 SET_ERROR_STRING(ERROR_CPREG_ILLEGAL
, *oper
);
3157 csky_insn
.val
[csky_insn
.idx
++] = e
.X_add_number
;
3163 parse_type_areg (char** oper
)
3167 i
= csky_get_reg_val (*oper
, &len
);
3170 SET_ERROR_STRING (ERROR_GREG_ILLEGAL
, NULL
);
3174 csky_insn
.val
[csky_insn
.idx
++] = i
;
3180 parse_type_freg (char** oper
, int even
)
3184 reg
= csky_get_freg_val (*oper
, &len
);
3187 SET_ERROR_STRING (ERROR_REG_FORMAT
,
3188 (void *)"The fpu register format is not recognized.");
3192 csky_insn
.opcode_end
= *oper
;
3193 if (even
&& reg
& 0x1)
3195 SET_ERROR_STRING (ERROR_EXP_EVEN_FREG
, NULL
);
3199 if (IS_CSKY_V2 (mach_flag
)
3200 && ((csky_insn
.opcode
->isa_flag32
& CSKY_ISA_VDSP_2
)
3201 || !(csky_insn
.opcode
->isa_flag32
& CSKY_ISA_FLOAT_7E60
))
3204 if ((csky_insn
.opcode
->isa_flag32
& CSKY_ISA_VDSP_2
))
3206 SET_ERROR_INTEGER (ERROR_VREG_OVER_RANGE
, reg
);
3210 SET_ERROR_INTEGER (ERROR_FREG_OVER_RANGE
, reg
);
3214 /* TODO: recognize vreg or freg. */
3217 SET_ERROR_INTEGER (ERROR_VREG_OVER_RANGE
, reg
);
3219 csky_insn
.val
[csky_insn
.idx
++] = reg
;
3224 parse_ldst_imm (char **oper
, struct csky_opcode_info
*op ATTRIBUTE_UNUSED
,
3225 struct operand
*oprnd
)
3227 unsigned int mask
= oprnd
->mask
;
3231 shift
= oprnd
->shift
;
3241 if (**oper
== '\0' || **oper
== ')')
3243 csky_insn
.val
[csky_insn
.idx
++] = 0;
3248 *oper
= parse_exp (*oper
, &e
);
3249 if (e
.X_op
!= O_constant
)
3251 /* Not a constant. */
3252 SET_ERROR_STRING(ERROR_UNDEFINE
, (void *)"Operand format is error. eg. \"ld rz, (rx, n)\"");
3255 else if (e
.X_add_number
< 0 || e
.X_add_number
>= max
)
3258 SET_ERROR_STRING(ERROR_IMM_OVERFLOW
, NULL
);
3261 if ((e
.X_add_number
% (1 << shift
)) != 0)
3264 SET_ERROR_INTEGER (ERROR_OFFSET_UNALIGNED
, ((unsigned long)1 << shift
));
3268 csky_insn
.val
[csky_insn
.idx
++] = e
.X_add_number
>> shift
;
3275 csky_count_operands (char *str
)
3277 char *oper_end
= str
;
3278 unsigned int oprnd_num
;
3279 int bracket_cnt
= 0;
3281 if (is_end_of_line
[(unsigned char) *oper_end
])
3286 /* Count how many operands. */
3288 while (!is_end_of_line
[(unsigned char) *oper_end
])
3290 if (*oper_end
== '(' || *oper_end
== '<')
3296 if (*oper_end
== ')' || *oper_end
== '>')
3302 if (!bracket_cnt
&& *oper_end
== ',')
3309 /* End of the operand parsing helper functions. */
3311 /* Parse the opcode part of an instruction. Fill in the csky_insn
3312 state and return true on success, false otherwise. */
3315 parse_opcode (char *str
)
3317 #define IS_OPCODE32F(a) (*(a - 2) == '3' && *(a - 1) == '2')
3318 #define IS_OPCODE16F(a) (*(a - 2) == '1' && *(a - 1) == '6')
3320 /* TRUE if this opcode has a suffix, like 'lrw.h'. */
3321 unsigned int has_suffix
= false;
3322 unsigned int nlen
= 0;
3324 char name
[OPCODE_MAX_LEN
+ 1];
3325 char macro_name
[OPCODE_MAX_LEN
+ 1];
3327 /* Remove space ahead of string. */
3328 while (ISSPACE (*str
))
3332 /* Find the opcode end. */
3333 while (nlen
< OPCODE_MAX_LEN
3334 && !is_end_of_line
[(unsigned char) *opcode_end
]
3335 && *opcode_end
!= ' ')
3337 /* Is csky force 32 or 16 instruction? */
3338 if (IS_CSKY_V2 (mach_flag
)
3339 && *opcode_end
== '.' && !has_suffix
)
3342 if (IS_OPCODE32F (opcode_end
))
3344 csky_insn
.flag_force
= INSN_OPCODE32F
;
3347 else if (IS_OPCODE16F (opcode_end
))
3349 csky_insn
.flag_force
= INSN_OPCODE16F
;
3353 name
[nlen
] = *opcode_end
;
3358 /* Is csky force 32 or 16 instruction? */
3361 if (IS_CSKY_V2 (mach_flag
) && IS_OPCODE32F (opcode_end
))
3363 csky_insn
.flag_force
= INSN_OPCODE32F
;
3366 else if (IS_OPCODE16F (opcode_end
))
3368 csky_insn
.flag_force
= INSN_OPCODE16F
;
3374 /* Generate macro_name for finding hash in macro hash_table. */
3377 strncpy (macro_name
, str
, nlen
);
3378 macro_name
[nlen
] = '\0';
3380 /* Get csky_insn.opcode_end. */
3381 while (ISSPACE (*opcode_end
))
3383 csky_insn
.opcode_end
= opcode_end
;
3385 /* Count the operands. */
3386 csky_insn
.number
= csky_count_operands (opcode_end
);
3388 /* Find hash by name in csky_macros_hash and csky_opcodes_hash. */
3389 csky_insn
.macro
= (struct csky_macro_info
*) str_hash_find (csky_macros_hash
,
3391 csky_insn
.opcode
= (struct csky_opcode
*) str_hash_find (csky_opcodes_hash
,
3394 if (csky_insn
.macro
== NULL
&& csky_insn
.opcode
== NULL
)
3399 /* Main dispatch routine to parse operand OPRND for opcode OP from string
3403 get_operand_value (struct csky_opcode_info
*op
,
3404 char **oper
, struct operand
*oprnd
)
3406 struct soperand
*soprnd
= NULL
;
3407 if (oprnd
->mask
== HAS_SUB_OPERAND
)
3409 /* It has sub operand, it must be like:
3413 We will check the format here. */
3414 soprnd
= (struct soperand
*) oprnd
;
3418 int bracket_cnt
= 0;
3419 if (oprnd
->type
== OPRND_TYPE_BRACKET
)
3424 else if (oprnd
->type
== OPRND_TYPE_ABRACKET
)
3437 SET_ERROR_STRING ((oprnd
->type
== OPRND_TYPE_BRACKET
3438 ? ERROR_MISSING_LBRACKET
3439 : ERROR_MISSING_LANGLE_BRACKETS
), NULL
);
3443 /* If the oprnd2 is an immediate, it can not be parsed
3444 that end with ')'/'>'. Modify ')'/'>' to '\0'. */
3445 while ((*s
!= rc
|| bracket_cnt
!= 0) && (*s
!= '\n' && *s
!= '\0'))
3458 SET_ERROR_STRING ((oprnd
->type
== OPRND_TYPE_BRACKET
3459 ? ERROR_MISSING_RBRACKET
3460 : ERROR_MISSING_RANGLE_BRACKETS
), NULL
);
3464 if (!get_operand_value (op
, oper
, &soprnd
->subs
[0]))
3471 else if (**oper
!= '\0')
3473 SET_ERROR_STRING (ERROR_MISSING_COMMA
, NULL
);
3477 if (!get_operand_value (op
, oper
, &soprnd
->subs
[1]))
3488 switch (oprnd
->type
)
3490 /* TODO: add opcode type here, log errors in the function.
3491 If REGLIST, then j = csky_insn.number - 1.
3492 If there is needed to parse expressions, it will be
3494 case OPRND_TYPE_CTRLREG
:
3496 return parse_type_ctrlreg (oper
);
3497 case OPRND_TYPE_AREG
:
3498 return parse_type_areg (oper
);
3499 case OPRND_TYPE_FREG
:
3500 case OPRND_TYPE_VREG
:
3501 return parse_type_freg (oper
, 0);
3502 case OPRND_TYPE_FEREG
:
3503 return parse_type_freg (oper
, 1);
3504 case OPRND_TYPE_CPCREG
:
3505 return parse_type_cpcreg (oper
);
3506 case OPRND_TYPE_CPREG
:
3507 return parse_type_cpreg (oper
);
3508 case OPRND_TYPE_CPIDX
:
3509 return parse_type_cpidx (oper
);
3510 case OPRND_TYPE_GREG0_7
:
3511 case OPRND_TYPE_GREG0_15
:
3515 reg
= csky_get_reg_val (*oper
, &len
);
3519 SET_ERROR_STRING (ERROR_GREG_ILLEGAL
, NULL
);
3522 else if ((oprnd
->type
== OPRND_TYPE_GREG0_7
&& reg
> 7)
3523 || (oprnd
->type
== OPRND_TYPE_GREG0_15
&& reg
> 15))
3525 SET_ERROR_INTEGER (ERROR_REG_OVER_RANGE
, reg
);
3529 csky_insn
.val
[csky_insn
.idx
++] = reg
;
3532 case OPRND_TYPE_REGnsplr
:
3536 reg
= csky_get_reg_val (*oper
, &len
);
3539 || (IS_CSKY_V1 (mach_flag
)
3540 && (reg
== V1_REG_SP
|| reg
== V1_REG_LR
)))
3542 SET_ERROR_STRING (ERROR_REG_OVER_RANGE
, reg
);
3545 csky_insn
.val
[csky_insn
.idx
++] = reg
;
3549 case OPRND_TYPE_REGnr4_r7
:
3555 reg
= csky_get_reg_val (*oper
, &len
);
3556 if (reg
== -1 || (reg
<= 7 && reg
>= 4))
3559 csky_insn
.val
[csky_insn
.idx
++] = reg
;
3566 case OPRND_TYPE_REGr4_r7
:
3567 if (memcmp (*oper
, "r4-r7", sizeof ("r4-r7") - 1) == 0)
3569 *oper
+= sizeof ("r4-r7") - 1;
3570 csky_insn
.val
[csky_insn
.idx
++] = 0;
3573 SET_ERROR_STRING (ERROR_OPCODE_ILLEGAL
, NULL
);
3575 case OPRND_TYPE_IMM_LDST
:
3576 return parse_ldst_imm (oper
, op
, oprnd
);
3577 case OPRND_TYPE_IMM_FLDST
:
3578 return parse_ldst_imm (oper
, op
, oprnd
);
3579 case OPRND_TYPE_IMM1b
:
3580 return is_imm_within_range (oper
, 0, 1);
3581 case OPRND_TYPE_IMM2b
:
3582 return is_imm_within_range (oper
, 0, 3);
3583 case OPRND_TYPE_IMM2b_JMPIX
:
3584 /* ck802j support jmpix16, but not support jmpix32. */
3585 if (IS_CSKY_ARCH_802 (mach_flag
)
3586 && (op
->opcode
& 0xffff0000) != 0)
3588 SET_ERROR_STRING (ERROR_OPCODE_ILLEGAL
, NULL
);
3591 *oper
= parse_exp (*oper
, &csky_insn
.e1
);
3592 if (csky_insn
.e1
.X_op
== O_constant
)
3594 csky_insn
.opcode_end
= *oper
;
3595 if (csky_insn
.e1
.X_add_number
& 0x7)
3597 SET_ERROR_STRING (ERROR_JMPIX_OVER_RANGE
, NULL
);
3600 csky_insn
.val
[csky_insn
.idx
++]
3601 = (csky_insn
.e1
.X_add_number
>> 3) - 2;
3604 case OPRND_TYPE_IMM4b
:
3605 return is_imm_within_range (oper
, 0, 15);
3606 case OPRND_TYPE_IMM5b
:
3607 return is_imm_within_range (oper
, 0, 31);
3608 /* This type for "bgeni" in csky v1 ISA. */
3609 case OPRND_TYPE_IMM5b_7_31
:
3610 if (is_imm_within_range (oper
, 0, 31))
3612 int val
= csky_insn
.val
[csky_insn
.idx
- 1];
3613 /* immediate values of 0 -> 6 translate to movi. */
3616 const char *name
= "movi";
3617 csky_insn
.opcode
= (struct csky_opcode
*)
3618 str_hash_find (csky_opcodes_hash
, name
);
3619 csky_insn
.val
[csky_insn
.idx
- 1] = 1 << val
;
3626 case OPRND_TYPE_IMM5b_1_31
:
3627 return is_imm_within_range (oper
, 1, 31);
3628 case OPRND_TYPE_IMM5b_POWER
:
3629 if (is_imm_within_range_ext (oper
, 1, (1u << 31) - 1, 1u << 31))
3632 int val
= csky_insn
.val
[csky_insn
.idx
- 1];
3633 log
= csky_log_2 (val
);
3634 csky_insn
.val
[csky_insn
.idx
- 1] = log
;
3640 /* This type for "mgeni" in csky v1 ISA. */
3641 case OPRND_TYPE_IMM5b_7_31_POWER
:
3642 if (is_imm_within_range_ext (oper
, 1, (1u << 31) - 1, 1u << 31))
3645 int val
= csky_insn
.val
[csky_insn
.idx
- 1];
3646 log
= csky_log_2 (val
);
3647 /* Immediate values of 0 -> 6 translate to movi. */
3650 const char *name
= "movi";
3651 csky_insn
.opcode
= (struct csky_opcode
*)
3652 str_hash_find (csky_opcodes_hash
, name
);
3653 as_warn (_("translating mgeni to movi"));
3656 csky_insn
.val
[csky_insn
.idx
- 1] = log
;
3662 case OPRND_TYPE_IMM5b_LS
:
3663 return is_imm_within_range (oper
,
3665 csky_insn
.val
[csky_insn
.idx
- 1]);
3666 case OPRND_TYPE_IMM5b_RORI
:
3668 unsigned max_shift
= IS_CSKY_V1 (mach_flag
) ? 31 : 32;
3670 if (is_imm_within_range (oper
, 1, max_shift
))
3672 int i
= csky_insn
.idx
- 1;
3673 csky_insn
.val
[i
] = 32 - csky_insn
.val
[i
];
3680 case OPRND_TYPE_IMM5b_BMASKI
:
3681 /* For csky v1 bmask inst. */
3683 if (!is_imm_within_range_ext (oper
, 8, 31, 0))
3685 unsigned int mask_val
= csky_insn
.val
[csky_insn
.idx
- 1];
3686 if (mask_val
> 0 && mask_val
< 8)
3688 const char *op_movi
= "movi";
3689 csky_insn
.opcode
= (struct csky_opcode
*)
3690 str_hash_find (csky_opcodes_hash
, op_movi
);
3691 if (csky_insn
.opcode
== NULL
)
3693 csky_insn
.val
[csky_insn
.idx
- 1] = (1 << mask_val
) - 1;
3699 case OPRND_TYPE_IMM5b_VSH
:
3700 /* For vshri.T and vshli.T. */
3701 if (is_imm_within_range (oper
, 0, 31))
3703 int val
= csky_insn
.val
[csky_insn
.idx
- 1];
3704 val
= (val
<< 1) | (val
>> 4);
3706 csky_insn
.val
[csky_insn
.idx
- 1] = val
;
3710 case OPRND_TYPE_IMM8b_BMASKI
:
3711 /* For csky v2 bmask, which will transfer to 16bits movi. */
3712 if (is_imm_within_range (oper
, 1, 8))
3714 unsigned int mask_val
= csky_insn
.val
[csky_insn
.idx
- 1];
3715 csky_insn
.val
[csky_insn
.idx
- 1] = (1 << mask_val
) - 1;
3719 case OPRND_TYPE_OIMM4b
:
3720 return is_oimm_within_range (oper
, 1, 16);
3721 case OPRND_TYPE_OIMM5b
:
3722 return is_oimm_within_range (oper
, 1, 32);
3723 case OPRND_TYPE_OIMM5b_IDLY
:
3724 if (is_imm_within_range (oper
, 0, 32))
3726 /* imm5b for idly n: 0<=n<4, imm5b=3; 4<=n<=32, imm5b=n-1. */
3727 unsigned long imm
= csky_insn
.val
[csky_insn
.idx
- 1];
3730 csky_show_error (WARNING_IDLY
, 0, (void *)imm
, NULL
);
3734 csky_insn
.val
[csky_insn
.idx
- 1] = imm
;
3740 /* For csky v2 bmask inst. */
3741 case OPRND_TYPE_OIMM5b_BMASKI
:
3742 if (!is_oimm_within_range (oper
, 17, 32))
3744 int mask_val
= csky_insn
.val
[csky_insn
.idx
- 1];
3745 if (mask_val
+ 1 == 0)
3747 if (mask_val
> 0 && mask_val
< 16)
3749 const char *op_movi
= "movi";
3750 csky_insn
.opcode
= (struct csky_opcode
*)
3751 str_hash_find (csky_opcodes_hash
, op_movi
);
3752 if (csky_insn
.opcode
== NULL
)
3754 csky_insn
.val
[csky_insn
.idx
- 1] = (1 << (mask_val
+ 1)) - 1;
3759 case OPRND_TYPE_IMM7b
:
3760 return is_imm_within_range (oper
, 0, 127);
3761 case OPRND_TYPE_IMM8b
:
3762 return is_imm_within_range (oper
, 0, 255);
3763 case OPRND_TYPE_IMM9b
:
3764 return is_imm_within_range (oper
, -256, 255);
3765 case OPRND_TYPE_IMM12b
:
3766 return is_imm_within_range (oper
, 0, 4095);
3767 case OPRND_TYPE_IMM15b
:
3768 return is_imm_within_range (oper
, 0, 0xfffff);
3769 case OPRND_TYPE_IMM16b
:
3770 return is_imm_within_range (oper
, 0, 65535);
3771 case OPRND_TYPE_OIMM16b
:
3772 return is_oimm_within_range (oper
, 1, 65536);
3773 case OPRND_TYPE_IMM32b
:
3776 char *new_oper
= parse_exp (*oper
, &e
);
3777 if (e
.X_op
== O_constant
)
3780 csky_insn
.val
[csky_insn
.idx
++] = e
.X_add_number
;
3785 case OPRND_TYPE_IMM16b_MOVIH
:
3786 case OPRND_TYPE_IMM16b_ORI
:
3788 bfd_reloc_code_real_type r
= BFD_RELOC_NONE
;
3791 char * save
= input_line_pointer
;
3792 /* get the reloc type, and set "@GOTxxx" as ' ' */
3793 while (**oper
!= '@' && **oper
!= '\0')
3797 input_line_pointer
= *oper
;
3799 while (*(*oper
+ len
+ 1) != '\0')
3801 **oper
= *(*oper
+ len
+ 1);
3802 *(*oper
+ len
+ 1) = '\0';
3807 input_line_pointer
= save
;
3808 *oper
= parse_exp (curr
, &csky_insn
.e1
);
3811 case OPRND_TYPE_PSR_BITS_LIST
:
3814 if (csky_insn
.number
== 0)
3818 csky_insn
.val
[csky_insn
.idx
] = 0;
3819 if (is_psr_bit (oper
))
3820 while (**oper
== ',')
3823 if (!is_psr_bit (oper
))
3831 if (ret
&& IS_CSKY_V1 (mach_flag
)
3832 && csky_insn
.val
[csky_insn
.idx
] > 8)
3836 SET_ERROR_STRING (ERROR_OPERANDS_ILLEGAL
, csky_insn
.opcode_end
);
3841 /* FPU round mode. */
3842 static const char *round_mode
[] =
3851 for (i
= 0; round_mode
[i
]; i
++)
3852 if (strncasecmp (*oper
, round_mode
[i
], strlen (round_mode
[i
])) == 0)
3854 *oper
+= strlen (round_mode
[i
]);
3855 csky_insn
.val
[csky_insn
.idx
++] = i
;
3861 case OPRND_TYPE_REGLIST_COMMA
:
3862 case OPRND_TYPE_BRACKET
:
3863 /* TODO: using sub operand union. */
3864 case OPRND_TYPE_ABRACKET
:
3865 /* TODO: using sub operand union. */
3866 case OPRND_TYPE_REGLIST_DASH
:
3867 return is_reglist_legal (oper
);
3868 case OPRND_TYPE_FREGLIST_DASH
:
3869 return is_freglist_legal (oper
);
3870 case OPRND_TYPE_AREG_WITH_BRACKET
:
3876 SET_ERROR_STRING (ERROR_MISSING_LBRACKET
, NULL
);
3880 reg
= csky_get_reg_val (*oper
, &len
);
3883 SET_ERROR_STRING (ERROR_EXP_GREG
, NULL
);
3889 SET_ERROR_STRING (ERROR_MISSING_RBRACKET
, NULL
);
3893 csky_insn
.val
[csky_insn
.idx
++] = reg
;
3896 case OPRND_TYPE_REGsp
:
3897 return is_reg_sp (oper
);
3898 case OPRND_TYPE_REGbsp
:
3899 return is_reg_sp_with_bracket (oper
);
3901 case OPRND_TYPE_OFF8b
:
3902 case OPRND_TYPE_OFF16b
:
3903 *oper
= parse_rt (*oper
, 1, &csky_insn
.e1
, -1);
3904 csky_insn
.val
[csky_insn
.idx
++] = 0;
3906 case OPRND_TYPE_LABEL_WITH_BRACKET
:
3907 case OPRND_TYPE_CONSTANT
:
3908 case OPRND_TYPE_ELRW_CONSTANT
:
3910 csky_insn
.val
[csky_insn
.idx
++] = 0;
3912 csky_insn
.val
[csky_insn
.idx
++] = NEED_OUTPUT_LITERAL
;
3913 *oper
= parse_rt (*oper
, 0, &csky_insn
.e1
, -1);
3915 case OPRND_TYPE_FCONSTANT
:
3916 *oper
= parse_rtf (*oper
, 0, &csky_insn
.e1
);
3919 case OPRND_TYPE_SFLOAT
:
3920 case OPRND_TYPE_DFLOAT
:
3921 /* For fmovis and fmovid, which accept a constant float with
3927 *oper
= parse_fexp (*oper
, &csky_insn
.e1
, 1, &dbnum
);
3928 if (csky_insn
.e1
.X_op
== O_absent
)
3931 /* Convert the representation from IEEE double to the 13-bit
3932 encoding used internally for fmovis and fmovid. */
3933 imm4
= 11 - (((dbnum
& 0x7ff0000000000000ULL
) >> 52) - 1023);
3934 /* Check float range. */
3935 if ((dbnum
& 0x00000fffffffffffULL
) || imm4
< 0 || imm4
> 15)
3937 csky_show_error (ERROR_IMM_OVERFLOW
, 2, NULL
, NULL
);
3940 imm8
= (dbnum
& 0x000ff00000000000ULL
) >> 44;
3941 csky_insn
.e1
.X_add_number
3942 = (((imm8
& 0xf) << 4)
3943 | ((imm8
& 0xf0) << 17)
3944 | ((imm4
& 0xf) << 16)
3945 | ((dbnum
& 0x8000000000000000ULL
) >> 43));
3948 case OPRND_TYPE_HFLOAT_FMOVI
:
3949 case OPRND_TYPE_SFLOAT_FMOVI
:
3950 case OPRND_TYPE_DFLOAT_FMOVI
:
3951 /* For fpuv3 fmovis and fmovid, which accept a constant
3952 float with a limited range. */
3955 int imm4
, imm8
, sign
;
3957 *oper
= parse_fexp (*oper
, &csky_insn
.e1
, 1, &dbnum
);
3958 if (csky_insn
.e1
.X_op
== O_absent
)
3961 /* Convert the representation from IEEE double to the 13-bit
3962 encoding used internally for fmovis and fmovid. */
3963 imm4
= 11 - (((dbnum
& 0x7ff0000000000000ULL
) >> 52) - 1023);
3964 /* Check float range. */
3965 if ((dbnum
& 0x00000fffffffffffULL
) || imm4
< 0 || imm4
> 15)
3967 csky_show_error (ERROR_IMM_OVERFLOW
, 2, NULL
, NULL
);
3970 imm8
= (dbnum
& 0x000ff00000000000ULL
) >> 44;
3971 sign
= (dbnum
& 0x8000000000000000ULL
) >> 58;
3972 csky_insn
.e1
.X_add_number
3973 = (((imm8
& 0x3) << 8)
3974 | ((imm8
& 0xfc) << 18)
3975 | ((imm4
& 0xf) << 16)
3980 case OPRND_TYPE_IMM_OFF18b
:
3981 *oper
= parse_exp (*oper
, &csky_insn
.e1
);
3984 case OPRND_TYPE_BLOOP_OFF4b
:
3985 *oper
= parse_exp (*oper
, &csky_insn
.e2
);
3986 if (csky_insn
.e2
.X_op
== O_symbol
)
3988 csky_insn
.opcode_end
= *oper
;
3994 case OPRND_TYPE_BLOOP_OFF12b
:
3995 case OPRND_TYPE_OFF10b
:
3996 case OPRND_TYPE_OFF11b
:
3997 case OPRND_TYPE_OFF16b_LSL1
:
3998 case OPRND_TYPE_OFF26b
:
3999 *oper
= parse_exp (*oper
, &csky_insn
.e1
);
4000 if (csky_insn
.e1
.X_op
== O_symbol
)
4002 csky_insn
.opcode_end
= *oper
;
4007 /* For xtrb0(1)(2)(3) and div in csky v1 ISA. */
4008 case OPRND_TYPE_REG_r1a
:
4012 reg
= csky_get_reg_val (*oper
, &len
);
4015 SET_ERROR_STRING (ERROR_REG_FORMAT
,
4016 "The first operand must be register r1.");
4020 mov_r1_after
= true;
4022 csky_insn
.opcode_end
= *oper
;
4023 csky_insn
.val
[csky_insn
.idx
++] = reg
;
4026 case OPRND_TYPE_REG_r1b
:
4030 reg
= csky_get_reg_val (*oper
, &len
);
4033 SET_ERROR_STRING (ERROR_REG_FORMAT
,
4034 "The second operand must be register r1.");
4039 unsigned int mov_insn
= CSKYV1_INST_MOV_R1_RX
;
4040 mov_insn
|= reg
<< 4;
4041 mov_r1_before
= true;
4042 csky_insn
.output
= frag_more (2);
4043 dwarf2_emit_insn (0);
4044 md_number_to_chars (csky_insn
.output
, mov_insn
, 2);
4047 csky_insn
.opcode_end
= *oper
;
4048 csky_insn
.val
[csky_insn
.idx
++] = reg
;
4051 case OPRND_TYPE_DUMMY_REG
:
4055 reg
= csky_get_reg_val (*oper
, &len
);
4058 SET_ERROR_STRING (ERROR_GREG_ILLEGAL
, NULL
);
4061 if (reg
!= csky_insn
.val
[0])
4063 SET_ERROR_STRING (ERROR_REG_FORMAT
,
4064 "The second register must be the same as the first.");
4068 csky_insn
.opcode_end
= *oper
;
4069 csky_insn
.val
[csky_insn
.idx
++] = reg
;
4072 case OPRND_TYPE_2IN1_DUMMY
:
4078 reg
= csky_get_reg_val (*oper
, &len
);
4081 SET_ERROR_STRING (ERROR_GREG_ILLEGAL
, NULL
);
4084 /* dummy reg's real type should be same with first operand. */
4085 if (op
->oprnd
.oprnds
[0].type
== OPRND_TYPE_GREG0_15
)
4087 else if (op
->oprnd
.oprnds
[0].type
== OPRND_TYPE_GREG0_7
)
4091 if (reg
< min
|| reg
> max
)
4093 csky_insn
.val
[csky_insn
.idx
++] = reg
;
4094 /* if it is the last operands. */
4095 if (csky_insn
.idx
> 2)
4097 /* For "insn rz, rx, ry", if rx or ry is equal to rz,
4098 we can output the insn like "insn rz, rx". */
4099 if (csky_insn
.val
[0] == csky_insn
.val
[1])
4100 csky_insn
.val
[1] = 0;
4101 else if (csky_insn
.val
[0] == csky_insn
.val
[2])
4102 csky_insn
.val
[2] = 0;
4107 csky_insn
.opcode_end
= *oper
;
4110 case OPRND_TYPE_DUP_GREG0_7
:
4111 case OPRND_TYPE_DUP_GREG0_15
:
4112 case OPRND_TYPE_DUP_AREG
:
4117 unsigned int shift_num
;
4118 if (oprnd
->type
== OPRND_TYPE_DUP_GREG0_7
)
4123 else if (oprnd
->type
== OPRND_TYPE_DUP_GREG0_15
)
4133 reg
= csky_get_reg_val (*oper
, &len
);
4137 SET_ERROR_STRING (ERROR_REG_FORMAT
,
4138 "The register must be r0-r31");
4140 SET_ERROR_STRING (ERROR_REG_FORMAT
,
4141 "The register must be r0-r15");
4146 SET_ERROR_STRING (ERROR_REG_OVER_RANGE
, reg
);
4149 reg
|= reg
<< shift_num
;
4151 csky_insn
.opcode_end
= *oper
;
4152 csky_insn
.val
[csky_insn
.idx
++] = reg
;
4155 case OPRND_TYPE_CONST1
:
4156 *oper
= parse_exp (*oper
, &csky_insn
.e1
);
4157 if (csky_insn
.e1
.X_op
== O_constant
)
4159 csky_insn
.opcode_end
= *oper
;
4160 if (csky_insn
.e1
.X_add_number
!= 1)
4162 csky_insn
.val
[csky_insn
.idx
++] = 1;
4166 case OPRND_TYPE_UNCOND10b
:
4167 case OPRND_TYPE_UNCOND16b
:
4168 *oper
= parse_exp (*oper
, &csky_insn
.e1
);
4169 if (csky_insn
.e1
.X_op
== O_constant
)
4171 input_line_pointer
= *oper
;
4172 csky_insn
.opcode_end
= *oper
;
4173 csky_insn
.relax
.max
= UNCD_DISP16_LEN
;
4174 csky_insn
.relax
.var
= UNCD_DISP10_LEN
;
4175 csky_insn
.relax
.subtype
= UNCD_DISP10
;
4176 csky_insn
.val
[csky_insn
.idx
++] = 0;
4178 case OPRND_TYPE_COND10b
:
4179 case OPRND_TYPE_COND16b
:
4180 *oper
= parse_exp (*oper
, &csky_insn
.e1
);
4181 if (csky_insn
.e1
.X_op
== O_constant
)
4183 input_line_pointer
= *oper
;
4184 csky_insn
.opcode_end
= *oper
;
4185 /* CK801 doesn't have 32-bit bt/bf insns; relax to a short
4186 jump around a 32-bit unconditional branch instead. */
4187 if (IS_CSKY_ARCH_801 (mach_flag
))
4189 csky_insn
.relax
.max
= SCOND_DISP16_LEN
;
4190 csky_insn
.relax
.var
= SCOND_DISP10_LEN
;
4191 csky_insn
.relax
.subtype
= SCOND_DISP10
;
4195 csky_insn
.relax
.max
= COND_DISP16_LEN
;
4196 csky_insn
.relax
.var
= COND_DISP10_LEN
;
4197 csky_insn
.relax
.subtype
= COND_DISP10
;
4199 csky_insn
.val
[csky_insn
.idx
++] = 0;
4201 case OPRND_TYPE_JCOMPZ
:
4202 *oper
= parse_exp (*oper
, &csky_insn
.e1
);
4203 if (csky_insn
.e1
.X_op
== O_constant
)
4205 input_line_pointer
= *oper
;
4206 csky_insn
.opcode_end
= *oper
;
4207 csky_insn
.relax
.max
= JCOMPZ_DISP32_LEN
;
4208 csky_insn
.relax
.var
= JCOMPZ_DISP16_LEN
;
4209 csky_insn
.relax
.subtype
= JCOMPZ_DISP16
;
4210 csky_insn
.max
= JCOMPZ_DISP32_LEN
;
4211 csky_insn
.val
[csky_insn
.idx
++] = 0;
4213 case OPRND_TYPE_JBTF
:
4214 *oper
= parse_exp (*oper
, &csky_insn
.e1
);
4215 input_line_pointer
= *oper
;
4216 csky_insn
.opcode_end
= *oper
;
4217 csky_insn
.relax
.max
= csky_relax_table
[C (COND_JUMP_S
, DISP32
)].rlx_length
;
4218 csky_insn
.relax
.var
= csky_relax_table
[C (COND_JUMP_S
, DISP12
)].rlx_length
;
4219 csky_insn
.relax
.subtype
= C (COND_JUMP_S
, 0);
4220 csky_insn
.val
[csky_insn
.idx
++] = 0;
4221 csky_insn
.max
= C32_LEN_S
+ 2;
4223 case OPRND_TYPE_JBR
:
4224 *oper
= parse_exp (*oper
, &csky_insn
.e1
);
4225 input_line_pointer
= *oper
;
4226 csky_insn
.opcode_end
= *oper
;
4227 csky_insn
.relax
.max
= csky_relax_table
[C (UNCD_JUMP_S
, DISP32
)].rlx_length
;
4228 csky_insn
.relax
.var
= csky_relax_table
[C (UNCD_JUMP_S
, DISP12
)].rlx_length
;
4229 csky_insn
.relax
.subtype
= C (UNCD_JUMP_S
, 0);
4230 csky_insn
.val
[csky_insn
.idx
++] = 0;
4231 csky_insn
.max
= U32_LEN_S
+ 2;
4233 case OPRND_TYPE_JBSR
:
4235 *oper
= parse_exp (*oper
, &csky_insn
.e1
);
4237 *oper
= parse_rt (*oper
, 1, &csky_insn
.e1
, -1);
4238 input_line_pointer
= *oper
;
4239 csky_insn
.opcode_end
= *oper
;
4240 csky_insn
.val
[csky_insn
.idx
++] = 0;
4242 case OPRND_TYPE_REGLIST_DASH_COMMA
:
4243 return is_reglist_dash_comma_legal (oper
, oprnd
);
4245 case OPRND_TYPE_MSB2SIZE
:
4246 case OPRND_TYPE_LSB2SIZE
:
4249 char *new_oper
= parse_exp (*oper
, &e
);
4250 if (e
.X_op
== O_constant
)
4253 if (e
.X_add_number
> 31)
4255 SET_ERROR_STRING (ERROR_IMM_OVERFLOW
, NULL
);
4258 csky_insn
.val
[csky_insn
.idx
++] = e
.X_add_number
;
4259 if (oprnd
->type
== OPRND_TYPE_LSB2SIZE
)
4261 if (csky_insn
.val
[csky_insn
.idx
- 1] > csky_insn
.val
[csky_insn
.idx
- 2])
4263 SET_ERROR_STRING (ERROR_IMM_OVERFLOW
, NULL
);
4266 csky_insn
.val
[csky_insn
.idx
- 2] -= e
.X_add_number
;
4272 case OPRND_TYPE_AREG_WITH_LSHIFT
:
4273 return is_reg_lshift_illegal (oper
, 0);
4274 case OPRND_TYPE_AREG_WITH_LSHIFT_FPU
:
4275 return is_reg_lshift_illegal (oper
, 1);
4276 case OPRND_TYPE_FREG_WITH_INDEX
:
4277 case OPRND_TYPE_VREG_WITH_INDEX
:
4278 if (parse_type_freg (oper
, 0))
4283 if (is_imm_within_range (oper
, 0, 0xf))
4287 unsigned int idx
= --csky_insn
.idx
;
4288 unsigned int val
= csky_insn
.val
[idx
];
4290 csky_insn
.val
[idx
- 1] |= val
<< 4;
4294 SET_ERROR_STRING (ERROR_MISSING_RSQUARE_BRACKETS
, NULL
);
4298 SET_ERROR_STRING (ERROR_MISSING_LSQUARE_BRACKETS
, NULL
);
4309 /* Subroutine of parse_operands. */
4312 parse_operands_op (char *str
, struct csky_opcode_info
*op
)
4319 for (i
= 0; i
< OP_TABLE_NUM
&& op
[i
].operand_num
!= -2; i
++)
4324 /* if operand_num = -1, it is a insn with a REGLIST type operand.i. */
4325 if (!(op
[i
].operand_num
== csky_insn
.number
4326 || (op
[i
].operand_num
== -1 && csky_insn
.number
!= 0)))
4328 /* The smaller err_num is more serious. */
4329 SET_ERROR_INTEGER (ERROR_OPERANDS_NUMBER
, op
[i
].operand_num
);
4334 for (j
= 0; j
< csky_insn
.number
; j
++)
4336 while (ISSPACE (*oper
))
4338 flag_pass
= get_operand_value (&op
[i
], &oper
,
4339 &op
[i
].oprnd
.oprnds
[j
]);
4342 while (ISSPACE (*oper
))
4345 if (j
< csky_insn
.number
- 1 && op
[i
].operand_num
!= -1)
4351 SET_ERROR_STRING (ERROR_MISSING_COMMA
, NULL
);
4356 else if (!is_end_of_line
[(unsigned char) *oper
])
4358 SET_ERROR_STRING (ERROR_BAD_END
, NULL
);
4365 /* Parse operands in one table end. */
4369 /* Parse operands success, set opcode_idx. */
4370 csky_insn
.opcode_idx
= i
;
4374 error_state
.opnum
= j
+ 1;
4376 /* Parse operands in ALL tables end. */
4380 /* Parse the operands according to operand type. */
4383 parse_operands (char *str
)
4387 /* Parse operands according to flag_force. */
4388 if (csky_insn
.flag_force
== INSN_OPCODE16F
4389 && (csky_insn
.opcode
->isa_flag16
& isa_flag
) != 0)
4391 if (parse_operands_op (oper
, csky_insn
.opcode
->op16
))
4393 csky_insn
.isize
= 2;
4398 else if (csky_insn
.flag_force
== INSN_OPCODE32F
4399 && (csky_insn
.opcode
->isa_flag32
& isa_flag
) != 0)
4401 if (parse_operands_op (oper
, csky_insn
.opcode
->op32
))
4403 csky_insn
.isize
= 4;
4410 if ((csky_insn
.opcode
->isa_flag16
& isa_flag
) != 0
4411 && parse_operands_op (oper
, csky_insn
.opcode
->op16
))
4413 csky_insn
.isize
= 2;
4416 if ((csky_insn
.opcode
->isa_flag32
& isa_flag
) != 0
4417 && parse_operands_op (oper
, csky_insn
.opcode
->op32
))
4419 csky_insn
.isize
= 4;
4427 csky_generate_frags (void)
4429 /* frag more relax reloc. */
4430 if (csky_insn
.flag_force
== INSN_OPCODE16F
4431 || !IS_SUPPORT_OPCODE32 (csky_insn
.opcode
))
4433 csky_insn
.output
= frag_more (csky_insn
.isize
);
4434 if (csky_insn
.opcode
->reloc16
)
4436 /* 16 bits opcode force, should generate fixup. */
4437 reloc_howto_type
*howto
;
4438 howto
= bfd_reloc_type_lookup (stdoutput
,
4439 csky_insn
.opcode
->reloc16
);
4440 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
4441 2, &csky_insn
.e1
, howto
->pc_relative
,
4442 csky_insn
.opcode
->reloc16
);
4445 else if (csky_insn
.flag_force
== INSN_OPCODE32F
)
4447 csky_insn
.output
= frag_more (csky_insn
.isize
);
4448 if (csky_insn
.opcode
->reloc32
)
4450 reloc_howto_type
*howto
;
4451 howto
= bfd_reloc_type_lookup (stdoutput
,
4452 csky_insn
.opcode
->reloc32
);
4453 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
4454 4, &csky_insn
.e1
, howto
->pc_relative
,
4455 csky_insn
.opcode
->reloc32
);
4458 else if (csky_insn
.opcode
->relax
)
4459 /* Generate the relax information. */
4460 csky_insn
.output
= frag_var (rs_machine_dependent
,
4461 csky_insn
.relax
.max
,
4462 csky_insn
.relax
.var
,
4463 csky_insn
.relax
.subtype
,
4464 csky_insn
.e1
.X_add_symbol
,
4465 csky_insn
.e1
.X_add_number
, 0);
4468 csky_insn
.output
= frag_more (csky_insn
.isize
);
4469 if (csky_insn
.opcode
->reloc16
&& csky_insn
.isize
== 2)
4471 reloc_howto_type
*howto
;
4472 howto
= bfd_reloc_type_lookup (stdoutput
,
4473 csky_insn
.opcode
->reloc16
);
4474 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
4475 2, &csky_insn
.e1
, howto
->pc_relative
,
4476 csky_insn
.opcode
->reloc16
);
4478 else if (csky_insn
.opcode
->reloc32
&& csky_insn
.isize
== 4)
4480 reloc_howto_type
*howto
;
4481 howto
= bfd_reloc_type_lookup (stdoutput
,
4482 csky_insn
.opcode
->reloc32
);
4483 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
4484 4, &csky_insn
.e1
, howto
->pc_relative
,
4485 csky_insn
.opcode
->reloc32
);
4491 /* Return the bits of VAL shifted according to MASK. The bits of MASK
4492 need not be contiguous. */
4495 generate_masked_value (int mask
, int val
)
4500 for (bit
= 1; mask
; bit
= bit
<< 1)
4511 /* Return the result of masking operand number OPRND_IDX into the
4512 instruction word according to the information in OPRND. */
4515 generate_masked_operand (struct operand
*oprnd
, int *oprnd_idx
)
4517 struct soperand
*soprnd
= NULL
;
4520 if ((unsigned int)oprnd
->mask
== HAS_SUB_OPERAND
)
4522 soprnd
= (struct soperand
*) oprnd
;
4523 generate_masked_operand (&soprnd
->subs
[0], oprnd_idx
);
4524 generate_masked_operand (&soprnd
->subs
[1], oprnd_idx
);
4528 val
= csky_insn
.val
[*oprnd_idx
];
4530 val
= generate_masked_value (mask
, val
);
4531 csky_insn
.inst
|= val
;
4537 csky_generate_insn (void)
4540 struct csky_opcode_info
*opinfo
= NULL
;
4542 if (csky_insn
.isize
== 4)
4543 opinfo
= &csky_insn
.opcode
->op32
[csky_insn
.opcode_idx
];
4544 else if (csky_insn
.isize
== 2)
4545 opinfo
= &csky_insn
.opcode
->op16
[csky_insn
.opcode_idx
];
4548 csky_insn
.inst
= opinfo
->opcode
;
4549 if (opinfo
->operand_num
== -1)
4551 generate_masked_operand (&opinfo
->oprnd
.oprnds
[i
], &sidx
);
4555 for (i
= 0; i
< opinfo
->operand_num
; i
++)
4556 generate_masked_operand (&opinfo
->oprnd
.oprnds
[i
], &sidx
);
4560 /* Main entry point for assembling a single instruction. */
4563 md_assemble (char *str
)
4565 bool must_check_literals
= true;
4566 csky_insn
.isize
= 0;
4569 csky_insn
.flag_force
= INSN_OPCODE
;
4570 csky_insn
.macro
= NULL
;
4571 csky_insn
.opcode
= NULL
;
4572 memset (csky_insn
.val
, 0, sizeof (int) * MAX_OPRND_NUM
);
4573 /* Initialize err_num. */
4574 error_state
.err_num
= ERROR_NONE
;
4575 mov_r1_before
= false;
4576 mov_r1_after
= false;
4578 mapping_state (MAP_TEXT
);
4579 /* Tie dwarf2 debug info to every insn if set option --gdwarf2. */
4580 dwarf2_emit_insn (0);
4581 while (ISSPACE (* str
))
4583 /* Get opcode from str. */
4584 if (!parse_opcode (str
))
4586 csky_show_error (ERROR_OPCODE_ILLEGAL
, 0, NULL
, NULL
);
4590 /* If it is a macro instruction, handle it. */
4591 if (csky_insn
.macro
!= NULL
)
4593 if (csky_insn
.number
== csky_insn
.macro
->oprnd_num
)
4595 csky_insn
.macro
->handle_func ();
4598 else if (error_state
.err_num
> ERROR_OPERANDS_NUMBER
)
4599 SET_ERROR_STRING (ERROR_OPERANDS_NUMBER
, csky_insn
.macro
->oprnd_num
);
4602 if (csky_insn
.opcode
== NULL
)
4604 SET_ERROR_STRING (ERROR_OPCODE_ILLEGAL
, NULL
);
4605 csky_show_error (error_state
.err_num
, error_state
.opnum
,
4606 (void *)error_state
.arg1
, (void *)error_state
.arg1
);
4610 /* Parse the operands according to operand type. */
4611 if (!parse_operands (csky_insn
.opcode_end
))
4613 csky_show_error (error_state
.err_num
, error_state
.opnum
,
4614 (void *)error_state
.arg1
, (void *)error_state
.arg1
);
4617 error_state
.err_num
= ERROR_NONE
;
4619 /* if this insn has work in opcode table, then do it. */
4620 if (csky_insn
.opcode
->work
!= NULL
)
4621 must_check_literals
= csky_insn
.opcode
->work ();
4624 /* Generate relax or reloc if necessary. */
4625 csky_generate_frags ();
4626 /* Generate the insn by mask. */
4627 csky_generate_insn ();
4628 /* Write inst to frag. */
4629 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
4632 /* Adjust for xtrb0/xtrb1/xtrb2/xtrb3/divs/divu in csky v1 ISA. */
4635 unsigned int mov_insn
= CSKYV1_INST_MOV_RX_R1
;
4636 mov_insn
|= csky_insn
.val
[0];
4637 mov_r1_before
= true;
4638 csky_insn
.output
= frag_more (2);
4639 dwarf2_emit_insn (0);
4640 md_number_to_chars (csky_insn
.output
, mov_insn
, 2);
4641 csky_insn
.isize
+= 2;
4644 csky_insn
.isize
+= 2;
4646 /* Check literal. */
4647 if (must_check_literals
)
4649 if (csky_insn
.max
== 0)
4650 check_literals (csky_insn
.opcode
->transfer
, csky_insn
.isize
);
4652 check_literals (csky_insn
.opcode
->transfer
, csky_insn
.max
);
4655 csky_insn
.last_isize
= csky_insn
.isize
;
4656 insn_reloc
= BFD_RELOC_NONE
;
4659 /* Attempt to handle option with value C, returning non-zero on success. */
4662 md_parse_option (int c
, const char *arg
)
4674 case OPTION_FLOAT_ABI
:
4675 parse_float_abi (arg
);
4683 /* Convert a machine dependent frag. */
4684 #define PAD_LITERAL_LENGTH 6
4685 #define opposite_of_stored_comp(insn) (insn ^ 0x04000000)
4686 #define opposite_of_stored_compz(insn) (insn ^ 0x00200000)
4687 #define make_insn(total_length, opcode, operand, operand_length) \
4689 if (total_length > 0) \
4691 csky_write_insn (buf, \
4692 opcode | (operand & ((1 << operand_length) - 1)), \
4694 buf += total_length; \
4695 fragp->fr_fix += total_length; \
4699 #define make_literal(fragp, literal_offset) \
4701 make_insn (literal_offset, PAD_FILL_CONTENT, 0, 0); \
4702 fix_new (fragp, fragp->fr_fix, 4, fragp->fr_symbol, \
4703 fragp->fr_offset, 0, BFD_RELOC_CKCORE_ADDR32); \
4704 make_insn (4, 0, 0, 0); \
4705 make_insn (2 - literal_offset, PAD_FILL_CONTENT, 0, 0); \
4709 md_convert_frag (bfd
*abfd ATTRIBUTE_UNUSED
, segT asec
, fragS
*fragp
)
4712 char *buf
= fragp
->fr_fix
+ &fragp
->fr_literal
[0];
4714 gas_assert (fragp
->fr_symbol
);
4715 if (IS_EXTERNAL_SYM (fragp
->fr_symbol
, asec
))
4718 disp
= (S_GET_VALUE (fragp
->fr_symbol
)
4723 switch (fragp
->fr_subtype
)
4725 /* generate new insn. */
4726 case C (COND_JUMP
, DISP12
):
4727 case C (UNCD_JUMP
, DISP12
):
4728 case C (COND_JUMP_PIC
, DISP12
):
4729 case C (UNCD_JUMP_PIC
, DISP12
):
4731 #define CSKY_V1_B_MASK 0xf8
4736 /* Error. odd displacement at %x, next_inst-2. */
4741 if (!target_big_endian
)
4743 t0
= buf
[1] & CSKY_V1_B_MASK
;
4744 md_number_to_chars (buf
, disp
, 2);
4745 buf
[1] = (buf
[1] & ~CSKY_V1_B_MASK
) | t0
;
4749 t0
= buf
[0] & CSKY_V1_B_MASK
;
4750 md_number_to_chars (buf
, disp
, 2);
4751 buf
[0] = (buf
[0] & ~CSKY_V1_B_MASK
) | t0
;
4756 case C (COND_JUMP
, DISP32
):
4757 case C (COND_JUMP
, UNDEF_WORD_DISP
):
4759 /* A conditional branch wont fit into 12 bits:
4766 int first_inst
= fragp
->fr_fix
+ fragp
->fr_address
;
4767 int is_unaligned
= (first_inst
& 3);
4769 if (!target_big_endian
)
4771 /* b!cond instruction. */
4773 /* jmpi instruction. */
4774 buf
[2] = CSKYV1_INST_JMPI
& 0xff;
4775 buf
[3] = CSKYV1_INST_JMPI
>> 8;
4779 /* b!cond instruction. */
4781 /* jmpi instruction. */
4782 buf
[2] = CSKYV1_INST_JMPI
>> 8;
4783 buf
[3] = CSKYV1_INST_JMPI
& 0xff;
4788 if (!target_big_endian
)
4790 /* bt/bf: jump to pc + 2 + (4 << 1). */
4792 /* jmpi: jump to MEM (pc + 2 + (1 << 2)). */
4797 /* bt/bf: jump to pc + 2 + (4 << 1). */
4799 /* jmpi: jump to MEM (pc + 2 + (1 << 2)). */
4802 /* Aligned 4 bytes. */
4811 /* Make reloc for the long disp. */
4812 fix_new (fragp
, fragp
->fr_fix
+ 6, 4,
4813 fragp
->fr_symbol
, fragp
->fr_offset
, 0, BFD_RELOC_32
);
4814 fragp
->fr_fix
+= C32_LEN
;
4818 if (!target_big_endian
)
4820 /* bt/bf: jump to pc + 2 + (3 << 1). */
4822 /* jmpi: jump to MEM (pc + 2 + (0 << 2)). */
4827 /* bt/bf: jump to pc + 2 + (3 << 1). */
4829 /* jmpi: jump to MEM (pc + 2 + (0 << 2)). */
4838 /* Make reloc for the long disp. */
4839 fix_new (fragp
, fragp
->fr_fix
+ 4, 4,
4840 fragp
->fr_symbol
, fragp
->fr_offset
, 0, BFD_RELOC_32
);
4841 fragp
->fr_fix
+= C32_LEN
;
4843 /* Frag is actually shorter (see the other side of this ifdef)
4844 but gas isn't prepared for that. We have to re-adjust
4845 the branch displacement so that it goes beyond the
4846 full length of the fragment, not just what we actually
4848 if (!target_big_endian
)
4856 case C (COND_JUMP_PIC
, DISP32
):
4857 case C (COND_JUMP_PIC
, UNDEF_WORD_DISP
):
4859 #define BYTE_1(a) (target_big_endian ? ((a) & 0xff) : ((a) >> 8))
4860 #define BYTE_0(a) (target_big_endian ? ((a) >> 8) : ((a) & 0xff))
4871 0: .long (tar_addr - pc)
4874 int first_inst
= fragp
->fr_fix
+ fragp
->fr_address
;
4875 int is_unaligned
= (first_inst
& 3);
4877 /* Toggle T/F bit. */
4878 if (! target_big_endian
)
4882 buf
[2] = BYTE_0 (CSKYV1_INST_SUBI
| (7 << 4)); /* subi r0, 8. */
4883 buf
[3] = BYTE_1 (CSKYV1_INST_SUBI
| (7 << 4));
4884 buf
[4] = BYTE_0 (CSKYV1_INST_STW
| (15 << 8)); /* stw r15, r0. */
4885 buf
[5] = BYTE_1 (CSKYV1_INST_STW
| (15 << 8));
4886 buf
[6] = BYTE_0 (CSKYV1_INST_BSR
); /* bsr pc + 2. */
4887 buf
[7] = BYTE_1 (CSKYV1_INST_BSR
);
4888 buf
[8] = BYTE_0 (CSKYV1_INST_LRW
| (1 << 8)); /* lrw r1, (tar_addr - pc). */
4889 buf
[9] = BYTE_1 (CSKYV1_INST_LRW
| (1 << 8));
4890 buf
[10] = BYTE_0 (CSKYV1_INST_ADDU
| (15 << 4) | 1); /* add r1, r15. */
4891 buf
[11] = BYTE_1 (CSKYV1_INST_ADDU
| (15 << 4) | 1);
4892 buf
[12] = BYTE_0 (CSKYV1_INST_LDW
| (15 << 8)); /* ldw r15, r0. */
4893 buf
[13] = BYTE_1 (CSKYV1_INST_LDW
| (15 << 8));
4894 buf
[14] = BYTE_0 (CSKYV1_INST_ADDI
| (7 << 4)); /* addi r0, 8. */
4895 buf
[15] = BYTE_1 (CSKYV1_INST_ADDI
| (7 << 4));
4896 buf
[16] = BYTE_0 (CSKYV1_INST_JMP
| 1); /* jmp r1. */
4897 buf
[17] = BYTE_1 (CSKYV1_INST_JMP
| 1);
4901 if (!target_big_endian
)
4905 buf
[20] = disp
& 0xff;
4906 buf
[21] = (disp
>> 8) & 0xff;
4907 buf
[22] = (disp
>> 16) & 0xff;
4908 buf
[23] = (disp
>> 24) & 0xff;
4910 else /* if !target_big_endian. */
4914 buf
[20] = (disp
>> 24) & 0xff;
4915 buf
[21] = (disp
>> 16) & 0xff;
4916 buf
[22] = (disp
>> 8) & 0xff;
4917 buf
[23] = disp
& 0xff;
4919 buf
[18] = 0; /* alignment. */
4921 fragp
->fr_fix
+= C32_LEN_PIC
;
4923 else /* if !is_unaligned. */
4925 if (!target_big_endian
)
4929 buf
[18] = disp
& 0xff;
4930 buf
[19] = (disp
>> 8) & 0xff;
4931 buf
[20] = (disp
>> 16) & 0xff;
4932 buf
[21] = (disp
>> 24) & 0xff;
4934 else /* if !target_big_endian. */
4938 buf
[18] = (disp
>> 24) & 0xff;
4939 buf
[19] = (disp
>> 16) & 0xff;
4940 buf
[20] = (disp
>> 8) & 0xff;
4941 buf
[21] = disp
& 0xff;
4943 buf
[22] = 0; /* initialise. */
4945 fragp
->fr_fix
+= C32_LEN_PIC
;
4947 } /* end if is_unaligned. */
4948 } /* end case C (COND_JUMP_PIC, DISP32)/C (COND_JUMP_PIC, UNDEF_WORD_DISP). */
4950 case C (UNCD_JUMP
, DISP32
):
4951 case C (UNCD_JUMP
, UNDEF_WORD_DISP
):
4956 int first_inst
= fragp
->fr_fix
+ fragp
->fr_address
;
4957 int is_unaligned
= (first_inst
& 3);
4959 buf
[0] = BYTE_0 (CSKYV1_INST_JMPI
);
4960 buf
[1] = BYTE_1 (CSKYV1_INST_JMPI
);
4963 if (!target_big_endian
)
4975 fix_new (fragp
, fragp
->fr_fix
+ 4, 4,
4976 fragp
->fr_symbol
, fragp
->fr_offset
, 0, BFD_RELOC_32
);
4977 fragp
->fr_fix
+= U32_LEN
;
4979 else /* if is_unaligned. */
4981 if (!target_big_endian
)
4990 fix_new (fragp
, fragp
->fr_fix
+ 2, 4,
4991 fragp
->fr_symbol
, fragp
->fr_offset
, 0, BFD_RELOC_32
);
4992 fragp
->fr_fix
+= U32_LEN
;
4997 case C (UNCD_JUMP_PIC
, DISP32
):
4998 case C (UNCD_JUMP_PIC
, UNDEF_WORD_DISP
):
5010 0: .long (tar_add - pc)
5013 /* If the b!cond is 4 byte aligned, the literal which would
5014 go at x+4 will also be aligned. */
5015 int first_inst
= fragp
->fr_fix
+ fragp
->fr_address
;
5016 int is_unaligned
= (first_inst
& 3);
5019 buf
[0] = BYTE_0 (CSKYV1_INST_SUBI
| (7 << 4)); /* subi r0, 8. */
5020 buf
[1] = BYTE_1 (CSKYV1_INST_SUBI
| (7 << 4));
5021 buf
[2] = BYTE_0 (CSKYV1_INST_STW
| (15 << 8)); /* stw r15, r0. */
5022 buf
[3] = BYTE_1 (CSKYV1_INST_STW
| (15 << 8));
5023 buf
[4] = BYTE_0 (CSKYV1_INST_BSR
); /* bsr pc + 2. */
5024 buf
[5] = BYTE_1 (CSKYV1_INST_BSR
);
5025 buf
[6] = BYTE_0 (CSKYV1_INST_LRW
| (1 << 8)); /* lrw r1, (tar_addr - pc). */
5026 buf
[7] = BYTE_1 (CSKYV1_INST_LRW
| (1 << 8));
5027 buf
[8] = BYTE_0 (CSKYV1_INST_ADDU
| (15 << 4) | 1); /* add r1, r15. */
5028 buf
[9] = BYTE_1 (CSKYV1_INST_ADDU
| (15 << 4) | 1);
5029 buf
[10] = BYTE_0 (CSKYV1_INST_LDW
| (15 << 8)); /* ldw r15, r0. */
5030 buf
[11] = BYTE_1 (CSKYV1_INST_LDW
| (15 << 8));
5031 buf
[12] = BYTE_0 (CSKYV1_INST_ADDI
| (7 << 4)); /* addi r0, 8. */
5032 buf
[13] = BYTE_1 (CSKYV1_INST_ADDI
| (7 << 4));
5033 buf
[14] = BYTE_0 (CSKYV1_INST_JMP
| 1); /* jmp r1. */
5034 buf
[15] = BYTE_1 (CSKYV1_INST_JMP
| 1);
5038 if (!target_big_endian
)
5041 buf
[18] = disp
& 0xff;
5042 buf
[19] = (disp
>> 8) & 0xff;
5043 buf
[20] = (disp
>> 16) & 0xff;
5044 buf
[21] = (disp
>> 24) & 0xff;
5049 buf
[18] = (disp
>> 24) & 0xff;
5050 buf
[19] = (disp
>> 16) & 0xff;
5051 buf
[20] = (disp
>> 8) & 0xff;
5052 buf
[21] = disp
& 0xff;
5056 fragp
->fr_fix
+= U32_LEN_PIC
;
5060 if (!target_big_endian
)
5063 buf
[16] = disp
& 0xff;
5064 buf
[17] = (disp
>> 8) & 0xff;
5065 buf
[18] = (disp
>> 16) & 0xff;
5066 buf
[19] = (disp
>> 24) & 0xff;
5071 buf
[16] = (disp
>> 24) & 0xff;
5072 buf
[17] = (disp
>> 16) & 0xff;
5073 buf
[18] = (disp
>> 8) & 0xff;
5074 buf
[19] = disp
& 0xff;
5076 fragp
->fr_fix
+= U32_LEN_PIC
;
5086 unsigned int inst
= csky_read_insn (buf
, 2);
5087 inst
|= (disp
>> 1) & ((1 << 10) - 1);
5088 csky_write_insn (buf
, inst
, 2);
5094 unsigned int inst
= csky_read_insn (buf
, 2);
5096 if (inst
== CSKYV2_INST_BT16
)
5097 inst
= CSKYV2_INST_BF16
;
5099 inst
= CSKYV2_INST_BT16
;
5100 make_insn (2, inst
, (2 + 4) >> 1, 10);
5101 if (IS_EXTERNAL_SYM (fragp
->fr_symbol
, asec
))
5102 fix_new (fragp
, fragp
->fr_fix
, 4,
5103 fragp
->fr_symbol
, fragp
->fr_offset
, 1,
5104 BFD_RELOC_CKCORE_PCREL_IMM16BY2
);
5106 inst
= CSKYV2_INST_BR32
| ((disp
>> 1) & ((1 << 16) - 1));
5107 csky_write_insn (buf
, inst
, 4);
5114 unsigned int inst
= csky_read_insn (buf
, 2);
5116 if (inst
== CSKYV2_INST_BT16
)
5117 inst
= CSKYV2_INST_BT32
;
5119 inst
= CSKYV2_INST_BF32
;
5120 if (IS_EXTERNAL_SYM (fragp
->fr_symbol
, asec
))
5121 fix_new (fragp
, fragp
->fr_fix
, 4,
5122 fragp
->fr_symbol
, fragp
->fr_offset
, 1,
5123 BFD_RELOC_CKCORE_PCREL_IMM16BY2
);
5124 inst
|= (disp
>> 1) & ((1 << 16) - 1);
5125 csky_write_insn (buf
, inst
, 4);
5131 unsigned int inst
= csky_read_insn (buf
, 2);
5133 imm
= (disp
+ 2) >> 2;
5134 inst
|= (imm
>> 5) << 8;
5135 make_insn (2, inst
, (imm
& 0x1f), 5);
5140 unsigned int inst
= csky_read_insn (buf
, 2);
5141 int imm
= (disp
+ 2) >> 2;
5145 inst
|= (~((imm
>> 5) << 8)) & 0x300;
5146 make_insn (2, inst
, (~imm
& 0x1f), 5);
5150 inst
|= (imm
>> 5) << 8;
5151 make_insn (2, inst
, (imm
& 0x1f), 5);
5157 unsigned int inst
= csky_read_insn (buf
, 2);
5158 inst
= CSKYV2_INST_LRW32
| (((inst
& 0xe0) >> 5) << 16);
5159 if (IS_EXTERNAL_SYM (fragp
->fr_symbol
, asec
))
5160 fix_new (fragp
, fragp
->fr_fix
, 4,
5161 fragp
->fr_symbol
, fragp
->fr_offset
, 1,
5162 BFD_RELOC_CKCORE_PCREL_IMM16BY4
);
5163 make_insn (4, inst
, ((disp
+ 2) >> 2), 16);
5168 unsigned int inst
= csky_read_insn (buf
, 4);
5169 make_insn (4, inst
, disp
>> 1, 16);
5174 unsigned int inst
= csky_read_insn (buf
, 4);
5176 make_insn (4, opposite_of_stored_compz (inst
),
5177 (4 + 4 + PAD_LITERAL_LENGTH
) >> 1, 16);
5178 literal_offset
= ((fragp
->fr_address
+ fragp
->fr_fix
) % 4 == 0
5180 make_insn (4, CSKYV2_INST_JMPI32
, (4 + literal_offset
+ 2) >> 2, 10);
5181 make_literal (fragp
, literal_offset
);
5187 if (IS_EXTERNAL_SYM (fragp
->fr_symbol
, asec
))
5188 fix_new (fragp
, fragp
->fr_fix
, 4,
5189 fragp
->fr_symbol
, fragp
->fr_offset
, 1,
5190 BFD_RELOC_CKCORE_PCREL_IMM16BY2
);
5191 make_insn (4, CSKYV2_INST_BR32
, disp
>> 1, 16);
5196 /* 'jbt'/'jbf'-> <bf16/bt16>; jmpi32; [pad16]+literal32 */
5197 unsigned int inst
= csky_read_insn (buf
, 2);
5200 if (inst
== CSKYV2_INST_BT16
)
5201 inst
= CSKYV2_INST_BF16
;
5203 inst
= CSKYV2_INST_BT16
;
5204 make_insn (2, inst
, (2 + 4 + PAD_LITERAL_LENGTH
) >> 1, 10);
5205 literal_offset
= ((fragp
->fr_address
+ fragp
->fr_fix
) % 4 == 0
5207 make_insn (4, CSKYV2_INST_JMPI32
, (4 + literal_offset
+ 2) >> 2, 10);
5208 make_literal (fragp
, literal_offset
);
5214 literal_offset
= ((fragp
->fr_address
+ fragp
->fr_fix
) % 4 == 0
5216 make_insn (4, CSKYV2_INST_JMPI32
, (4 + literal_offset
+ 2) >> 2, 10);
5217 make_literal (fragp
, literal_offset
);
5220 case RELAX_OVERFLOW
:
5221 csky_branch_report_error (fragp
->fr_file
, fragp
->fr_line
,
5222 fragp
->fr_symbol
, disp
);
5230 /* Round up a section size to the appropriate boundary. */
5233 md_section_align (segT segment ATTRIBUTE_UNUSED
,
5239 /* MD interface: Symbol and relocation handling. */
5241 void csky_md_finish (void)
5246 /* Return the address within the segment that a PC-relative fixup is
5250 md_pcrel_from_section (fixS
* fixP
, segT seg
)
5252 /* If the symbol is undefined or defined in another section
5253 we leave the add number alone for the linker to fix it later. */
5254 if (fixP
->fx_addsy
!= (symbolS
*) NULL
5255 && (! S_IS_DEFINED (fixP
->fx_addsy
)
5256 || S_GET_SEGMENT (fixP
->fx_addsy
) != seg
))
5257 return fixP
->fx_size
;
5259 /* The case where we are going to resolve things. */
5260 return fixP
->fx_size
+ fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
5263 /* csky_cons_fix_new is called via the expression parsing code when a
5264 reloc is needed. We use this hook to get the correct .got reloc. */
5267 csky_cons_fix_new (fragS
*frag
,
5271 bfd_reloc_code_real_type reloc
)
5275 if (BFD_RELOC_CKCORE_GOTOFF
== insn_reloc
5276 || BFD_RELOC_CKCORE_GOTPC
== insn_reloc
5277 || BFD_RELOC_CKCORE_GOT32
== insn_reloc
5278 || BFD_RELOC_CKCORE_PLT32
== insn_reloc
5279 || BFD_RELOC_CKCORE_TLS_LE32
== insn_reloc
5280 || BFD_RELOC_CKCORE_TLS_GD32
== insn_reloc
5281 || BFD_RELOC_CKCORE_TLS_LDM32
== insn_reloc
5282 || BFD_RELOC_CKCORE_TLS_LDO32
== insn_reloc
5283 || BFD_RELOC_CKCORE_TLS_IE32
== insn_reloc
)
5289 reloc
= BFD_RELOC_8
;
5292 reloc
= BFD_RELOC_16
;
5295 reloc
= BFD_RELOC_32
;
5298 reloc
= BFD_RELOC_64
;
5301 as_bad (_("unsupported BFD relocation size %d"), len
);
5302 reloc
= BFD_RELOC_32
;
5305 fixP
= fix_new_exp (frag
, off
, (int) len
, exp
, 0, reloc
);
5306 if (BFD_RELOC_CKCORE_TLS_IE32
== insn_reloc
5307 || BFD_RELOC_CKCORE_TLS_GD32
== insn_reloc
5308 || BFD_RELOC_CKCORE_TLS_LDM32
== insn_reloc
)
5310 fixP
->tc_fix_data
.frag
= literal_insn_offset
->tls_addend
.frag
;
5311 fixP
->tc_fix_data
.offset
= literal_insn_offset
->tls_addend
.offset
;
5315 /* See whether we need to force a relocation into the output file.
5316 This is used to force out switch and PC relative relocations when
5320 csky_force_relocation (fixS
* fix
)
5322 if (fix
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
5323 || fix
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
5324 || fix
->fx_r_type
== BFD_RELOC_RVA
5325 || fix
->fx_r_type
== BFD_RELOC_CKCORE_ADDR_HI16
5326 || fix
->fx_r_type
== BFD_RELOC_CKCORE_ADDR_LO16
5327 || fix
->fx_r_type
== BFD_RELOC_CKCORE_TOFFSET_LO16
5328 || fix
->fx_r_type
== BFD_RELOC_CKCORE_DOFFSET_LO16
)
5331 if (fix
->fx_addsy
== NULL
)
5334 if (do_use_branchstub
5335 && fix
->fx_r_type
== BFD_RELOC_CKCORE_PCREL_IMM26BY2
5336 && (symbol_get_bfdsym (fix
->fx_addsy
)->flags
& BSF_FUNCTION
))
5338 return S_FORCE_RELOC (fix
->fx_addsy
, fix
->fx_subsy
== NULL
);
5341 /* Return true if the fix can be handled by GAS, false if it must
5342 be passed through to the linker. */
5345 csky_fix_adjustable (fixS
* fixP
)
5347 if (fixP
->fx_addsy
== NULL
)
5350 /* We need the symbol name for the VTABLE entries. */
5351 if (fixP
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
5352 || fixP
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
5353 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_PLT32
5354 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_GOT32
5355 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_PLT12
5356 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_GOT12
5357 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_GOT_HI16
5358 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_GOT_LO16
5359 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_PLT_HI16
5360 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_PLT_LO16
5361 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_GOTOFF
5362 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_GOTOFF_HI16
5363 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_GOTOFF_LO16
5364 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_ADDR_HI16
5365 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_ADDR_LO16
5366 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_GOT_IMM18BY4
5367 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_PLT_IMM18BY4
5368 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_GOTOFF_IMM18
5369 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_TLS_LE32
5370 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_TLS_IE32
5371 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_TLS_GD32
5372 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_TLS_LDM32
5373 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_TLS_LDO32
)
5376 if (do_use_branchstub
5377 && fixP
->fx_r_type
== BFD_RELOC_CKCORE_PCREL_IMM26BY2
5378 && (symbol_get_bfdsym (fixP
->fx_addsy
)->flags
& BSF_FUNCTION
))
5385 md_apply_fix (fixS
*fixP
,
5389 reloc_howto_type
*howto
;
5390 /* Note: use offsetT because it is signed, valueT is unsigned. */
5391 offsetT val
= *valP
;
5392 char *buf
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
5394 /* if fx_done = 0, fixup will also be processed in
5395 * tc_gen_reloc() after md_apply_fix(). */
5398 /* If the fix is relative to a symbol which is not defined, or not
5399 in the same segment as the fix, we cannot resolve it here. */
5400 if (IS_CSKY_V1 (mach_flag
) && fixP
->fx_addsy
!= NULL
5401 && (! S_IS_DEFINED (fixP
->fx_addsy
)
5402 || S_GET_SEGMENT (fixP
->fx_addsy
) != seg
))
5404 switch (fixP
->fx_r_type
)
5406 /* Data fx_addnumber is greater than 16 bits,
5407 so fx_addnumber is assigned zero. */
5408 case BFD_RELOC_CKCORE_PCREL_JSR_IMM11BY2
:
5411 case BFD_RELOC_CKCORE_TLS_IE32
:
5412 case BFD_RELOC_CKCORE_TLS_LDM32
:
5413 case BFD_RELOC_CKCORE_TLS_GD32
:
5415 struct tls_addend
*ta
= &(fixP
->tc_fix_data
);
5416 fixP
->fx_offset
= (fixP
->fx_frag
->fr_address
+ fixP
->fx_where
5417 - (ta
->frag
->fr_address
+ ta
->offset
));
5418 *valP
= fixP
->fx_offset
;
5421 case BFD_RELOC_CKCORE_TLS_LE32
:
5422 case BFD_RELOC_CKCORE_TLS_LDO32
:
5423 S_SET_THREAD_LOCAL (fixP
->fx_addsy
);
5429 /* For ELF we can just return and let the reloc that will be generated
5430 take care of everything. For COFF we still have to insert 'val'
5431 into the insn since the addend field will be ignored. */
5436 /* We can handle these relocs. */
5437 switch (fixP
->fx_r_type
)
5439 case BFD_RELOC_32_PCREL
:
5440 case BFD_RELOC_CKCORE_PCREL32
:
5441 fixP
->fx_r_type
= BFD_RELOC_CKCORE_PCREL32
;
5443 case BFD_RELOC_VTABLE_INHERIT
:
5444 fixP
->fx_r_type
= BFD_RELOC_CKCORE_GNU_VTINHERIT
;
5445 if (fixP
->fx_addsy
&& !S_IS_DEFINED (fixP
->fx_addsy
)
5446 && !S_IS_WEAK (fixP
->fx_addsy
))
5447 S_SET_WEAK (fixP
->fx_addsy
);
5449 case BFD_RELOC_VTABLE_ENTRY
:
5450 fixP
->fx_r_type
= BFD_RELOC_CKCORE_GNU_VTENTRY
;
5452 case BFD_RELOC_CKCORE_GOT12
:
5453 case BFD_RELOC_CKCORE_PLT12
:
5454 case BFD_RELOC_CKCORE_ADDR_HI16
:
5455 case BFD_RELOC_CKCORE_ADDR_LO16
:
5456 case BFD_RELOC_CKCORE_TOFFSET_LO16
:
5457 case BFD_RELOC_CKCORE_DOFFSET_LO16
:
5458 case BFD_RELOC_CKCORE_GOT_HI16
:
5459 case BFD_RELOC_CKCORE_GOT_LO16
:
5460 case BFD_RELOC_CKCORE_PLT_HI16
:
5461 case BFD_RELOC_CKCORE_PLT_LO16
:
5462 case BFD_RELOC_CKCORE_GOTPC_HI16
:
5463 case BFD_RELOC_CKCORE_GOTPC_LO16
:
5464 case BFD_RELOC_CKCORE_GOTOFF_HI16
:
5465 case BFD_RELOC_CKCORE_GOTOFF_LO16
:
5466 case BFD_RELOC_CKCORE_DOFFSET_IMM18
:
5467 case BFD_RELOC_CKCORE_DOFFSET_IMM18BY2
:
5468 case BFD_RELOC_CKCORE_DOFFSET_IMM18BY4
:
5469 case BFD_RELOC_CKCORE_GOTOFF_IMM18
:
5470 case BFD_RELOC_CKCORE_GOT_IMM18BY4
:
5471 case BFD_RELOC_CKCORE_PLT_IMM18BY4
:
5473 case BFD_RELOC_CKCORE_TLS_IE32
:
5474 case BFD_RELOC_CKCORE_TLS_LDM32
:
5475 case BFD_RELOC_CKCORE_TLS_GD32
:
5477 struct tls_addend
*ta
= &(fixP
->tc_fix_data
);
5478 fixP
->fx_offset
= (fixP
->fx_frag
->fr_address
+ fixP
->fx_where
5479 - (ta
->frag
->fr_address
+ ta
->offset
));
5480 *valP
= fixP
->fx_offset
;
5483 case BFD_RELOC_CKCORE_TLS_LE32
:
5484 case BFD_RELOC_CKCORE_TLS_LDO32
:
5485 S_SET_THREAD_LOCAL (fixP
->fx_addsy
);
5488 fixP
->fx_r_type
= BFD_RELOC_CKCORE_ADDR32
;
5492 if (fixP
->fx_addsy
== NULL
)
5494 if (fixP
->fx_size
== 4)
5496 else if (fixP
->fx_size
== 2 && val
>= -32768 && val
<= 32767)
5498 else if (fixP
->fx_size
== 1 && val
>= -256 && val
<= 255)
5503 md_number_to_chars (buf
, val
, fixP
->fx_size
);
5507 case BFD_RELOC_CKCORE_PCREL_JSR_IMM11BY2
:
5508 if (fixP
->fx_addsy
== 0 && val
> -2 KB
&& val
< 2 KB
)
5510 long nval
= (val
>> 1) & 0x7ff;
5511 nval
|= CSKYV1_INST_BSR
;
5512 csky_write_insn (buf
, nval
, 2);
5518 case BFD_RELOC_CKCORE_PCREL_JSR_IMM26BY2
:
5519 if (fixP
->fx_addsy
== 0)
5521 if (val
>= -(1 << 26) && val
< (1 << 26))
5523 unsigned int nval
= ((val
+ fixP
->fx_size
) >> 1) & 0x3ffffff;
5524 nval
|= CSKYV2_INST_BSR32
;
5526 csky_write_insn (buf
, nval
, 4);
5528 /* If bsr32 cannot reach,
5529 generate 'lrw r25,label;jsr r25' instead of 'jsri label'. */
5530 else if (IS_CSKY_ARCH_810 (mach_flag
))
5532 howto
= bfd_reloc_type_lookup (stdoutput
, fixP
->fx_r_type
);
5533 valueT opcode
= csky_read_insn (buf
, 4);
5534 opcode
= (opcode
& howto
->dst_mask
) | CSKYV2_INST_JSRI_TO_LRW
;
5535 csky_write_insn (buf
, opcode
, 4);
5536 opcode
= CSKYV2_INST_JSR_R26
;
5537 csky_write_insn (buf
+ 4, opcode
, 4);
5547 unsigned int issigned
= 0;
5552 howto
= bfd_reloc_type_lookup (stdoutput
, fixP
->fx_r_type
);
5555 if (fixP
->fx_size
== 4
5556 || (fixP
->fx_size
== 2 && val
>= -32768 && val
<= 32767)
5557 || (fixP
->fx_size
== 1 && val
>= -256 && val
<= 255))
5559 md_number_to_chars (buf
, val
, fixP
->fx_size
);
5567 if (IS_CSKY_V2 (mach_flag
))
5568 val
+= fixP
->fx_size
;
5570 if (howto
->rightshift
== 2)
5573 val
>>= howto
->rightshift
;
5575 switch (fixP
->fx_r_type
)
5577 /* Offset is unsigned. */
5578 case BFD_RELOC_CKCORE_PCREL_IMM8BY4
:
5579 case BFD_RELOC_CKCORE_PCREL_IMM10BY4
:
5580 case BFD_RELOC_CKCORE_PCREL_IMM16BY4
:
5581 max
= (offsetT
) howto
->dst_mask
;
5585 case BFD_RELOC_CKCORE_PCREL_IMM7BY4
:
5587 max
= (offsetT
)((1 << (howto
->bitsize
+ 1)) - 2);
5589 max
= (offsetT
)((1 << howto
->bitsize
) - 1);
5592 /* flrws, flrwd: the offset bits are divided in two parts. */
5593 case BFD_RELOC_CKCORE_PCREL_FLRW_IMM8BY4
:
5594 max
= (offsetT
)((1 << howto
->bitsize
) - 1);
5597 /* Offset is signed. */
5599 max
= (offsetT
)(howto
->dst_mask
>> 1);
5603 if (val
< min
|| val
> max
)
5605 csky_branch_report_error (fixP
->fx_file
, fixP
->fx_line
,
5606 fixP
->fx_addsy
, val
);
5609 opcode
= csky_read_insn (buf
, fixP
->fx_size
);
5610 /* Clear redundant bits brought from the last
5611 operation if there is any. */
5612 if (do_extend_lrw
&& (opcode
& 0xfc00) == CSKYV2_INST_LRW16
)
5615 val
&= issigned
? (offsetT
)(howto
->dst_mask
) : max
;
5617 if (fixP
->fx_r_type
== BFD_RELOC_CKCORE_PCREL_BLOOP_IMM4BY4
)
5618 val
= (val
& 0xf) << 12;
5620 if (fixP
->fx_size
== 2 && (opcode
& 0xfc00) == CSKYV2_INST_LRW16
)
5622 /* 8 bit offset lrw16. */
5624 csky_write_insn (buf
,
5626 | ((~val
& 0x60) << 3) | (opcode
& 0xe0)),
5628 /* 7 bit offset lrw16. */
5630 csky_write_insn (buf
,
5631 (val
& 0x1f) | ((val
& 0x60) << 3) | opcode
,
5634 else if (fixP
->fx_size
== 4
5635 && (opcode
& 0xfe1ffe00) == CSKYV2_INST_FLRW
)
5636 csky_write_insn (buf
,
5637 ((val
& 0xf) << 4) | ((val
& 0xf0) << 17) | opcode
,
5640 csky_write_insn (buf
, val
| opcode
, fixP
->fx_size
);
5645 fixP
->fx_addnumber
= val
;
5648 /* Translate internal representation of relocation info to BFD target
5652 tc_gen_reloc (asection
*section ATTRIBUTE_UNUSED
, fixS
*fixP
)
5657 && fixP
->fx_r_type
== BFD_RELOC_CKCORE_ADDR32
)
5658 fixP
->fx_r_type
= BFD_RELOC_CKCORE_PCREL32
;
5660 rel
= xmalloc (sizeof (arelent
));
5661 rel
->sym_ptr_ptr
= xmalloc (sizeof (asymbol
*));
5662 *rel
->sym_ptr_ptr
= symbol_get_bfdsym (fixP
->fx_addsy
);
5663 rel
->howto
= bfd_reloc_type_lookup (stdoutput
, fixP
->fx_r_type
);
5664 rel
->addend
= fixP
->fx_offset
;
5665 if (rel
->howto
== NULL
)
5667 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5668 _("cannot represent `%s' relocation in object file"),
5669 bfd_get_reloc_code_name (fixP
->fx_r_type
));
5671 /* Set howto to a garbage value so that we can keep going. */
5672 rel
->howto
= bfd_reloc_type_lookup (stdoutput
, BFD_RELOC_32
);
5674 gas_assert (rel
->howto
!= NULL
);
5675 rel
->address
= fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
5679 /* Relax a fragment by scanning TC_GENERIC_RELAX_TABLE. */
5682 csky_relax_frag (segT segment
, fragS
*fragP
, long stretch
)
5684 const relax_typeS
*this_type
;
5685 const relax_typeS
*start_type
;
5686 relax_substateT next_state
;
5687 relax_substateT this_state
;
5693 const relax_typeS
*table
;
5695 target
= fragP
->fr_offset
;
5696 address
= fragP
->fr_address
;
5697 table
= TC_GENERIC_RELAX_TABLE
;
5698 this_state
= fragP
->fr_subtype
;
5699 start_type
= this_type
= table
+ this_state
;
5700 symbolP
= fragP
->fr_symbol
;
5706 sym_frag
= symbol_get_frag (symbolP
);
5708 #ifndef DIFF_EXPR_OK
5709 know (sym_frag
!= NULL
);
5711 know (S_GET_SEGMENT (symbolP
) != absolute_section
5712 || sym_frag
== &zero_address_frag
);
5713 target
+= S_GET_VALUE (symbolP
);
5715 /* If SYM_FRAG has yet to be reached on this pass, assume it
5716 will move by STRETCH just as we did, unless there is an
5717 alignment frag between here and SYM_FRAG. An alignment may
5718 well absorb any STRETCH, and we don't want to choose a larger
5719 branch insn by overestimating the needed reach of this
5720 branch. It isn't critical to calculate TARGET exactly; We
5721 know we'll be doing another pass if STRETCH is non-zero. */
5724 && sym_frag
->relax_marker
!= fragP
->relax_marker
5725 && S_GET_SEGMENT (symbolP
) == segment
)
5729 /* Adjust stretch for any alignment frag. Note that if have
5730 been expanding the earlier code, the symbol may be
5731 defined in what appears to be an earlier frag. FIXME:
5732 This doesn't handle the fr_subtype field, which specifies
5733 a maximum number of bytes to skip when doing an
5735 for (f
= fragP
; f
!= NULL
&& f
!= sym_frag
; f
= f
->fr_next
)
5737 if (f
->fr_type
== rs_align
|| f
->fr_type
== rs_align_code
)
5740 stretch
= -((-stretch
)
5741 & ~((1 << (int) f
->fr_offset
) - 1));
5743 stretch
&= ~((1 << (int) f
->fr_offset
) - 1);
5753 aim
= target
- address
- fragP
->fr_fix
;
5755 /* If the fragP->fr_symbol is extern symbol, aim should be 0. */
5756 if (fragP
->fr_symbol
&& S_GET_SEGMENT (symbolP
) != segment
)
5761 /* Look backwards. */
5762 for (next_state
= this_type
->rlx_more
; next_state
;)
5763 if (aim
>= this_type
->rlx_backward
)
5767 /* Grow to next state. */
5768 this_state
= next_state
;
5769 this_type
= table
+ this_state
;
5770 next_state
= this_type
->rlx_more
;
5775 /* Look forwards. */
5776 for (next_state
= this_type
->rlx_more
; next_state
;)
5777 if (aim
<= this_type
->rlx_forward
)
5781 /* Grow to next state. */
5782 this_state
= next_state
;
5783 this_type
= table
+ this_state
;
5784 next_state
= this_type
->rlx_more
;
5788 growth
= this_type
->rlx_length
- start_type
->rlx_length
;
5790 fragP
->fr_subtype
= this_state
;
5795 md_estimate_size_before_relax (fragS
* fragp
,
5798 switch (fragp
->fr_subtype
)
5818 gas_assert (fragp
->fr_symbol
);
5819 if (IS_EXTERNAL_SYM (fragp
->fr_symbol
, segtype
))
5820 while (csky_relax_table
[fragp
->fr_subtype
].rlx_more
> RELAX_OVERFLOW
)
5821 fragp
->fr_subtype
= csky_relax_table
[fragp
->fr_subtype
].rlx_more
;
5822 return csky_relax_table
[fragp
->fr_subtype
].rlx_length
;
5824 /* C-SKY V1 relaxes. */
5825 case C (UNCD_JUMP
, UNDEF_DISP
):
5826 case C (UNCD_JUMP_PIC
, UNDEF_DISP
):
5827 if (!fragp
->fr_symbol
)
5828 fragp
->fr_subtype
= C (UNCD_JUMP_S
, DISP12
);
5829 else if (S_GET_SEGMENT (fragp
->fr_symbol
) == segtype
)
5830 fragp
->fr_subtype
= C (UNCD_JUMP_S
, DISP12
);
5832 fragp
->fr_subtype
= C (UNCD_JUMP_S
, UNDEF_WORD_DISP
);
5835 case C (COND_JUMP
, UNDEF_DISP
):
5836 case C (COND_JUMP_PIC
, UNDEF_DISP
):
5837 if (fragp
->fr_symbol
5838 && S_GET_SEGMENT (fragp
->fr_symbol
) == segtype
)
5839 /* Got a symbol and it's defined in this segment, become byte
5840 sized. Maybe it will fix up. */
5841 fragp
->fr_subtype
= C (COND_JUMP_S
, DISP12
);
5842 else if (fragp
->fr_symbol
)
5843 /* It's got a segment, but it's not ours, so it will always be
5845 fragp
->fr_subtype
= C (COND_JUMP_S
, UNDEF_WORD_DISP
);
5847 /* We know the abs value. */
5848 fragp
->fr_subtype
= C (COND_JUMP_S
, DISP12
);
5851 case C (UNCD_JUMP
, DISP12
):
5852 case C (UNCD_JUMP
, DISP32
):
5853 case C (UNCD_JUMP
, UNDEF_WORD_DISP
):
5854 case C (COND_JUMP
, DISP12
):
5855 case C (COND_JUMP
, DISP32
):
5856 case C (COND_JUMP
, UNDEF_WORD_DISP
):
5857 case C (UNCD_JUMP_PIC
, DISP12
):
5858 case C (UNCD_JUMP_PIC
, DISP32
):
5859 case C (UNCD_JUMP_PIC
, UNDEF_WORD_DISP
):
5860 case C (COND_JUMP_PIC
, DISP12
):
5861 case C (COND_JUMP_PIC
, DISP32
):
5862 case C (COND_JUMP_PIC
, UNDEF_WORD_DISP
):
5863 case RELAX_OVERFLOW
:
5869 return csky_relax_table
[fragp
->fr_subtype
].rlx_length
;
5872 /* Parse opcode like: "op oprnd1, oprnd2, oprnd3". */
5875 csky_macro_md_assemble (const char *op
,
5886 strcat (str
, oprnd1
);
5890 strcat (str
, oprnd2
);
5894 strcat (str
, oprnd3
);
5902 /* Get the string of operand. */
5905 csky_get_macro_operand (char *src_s
, char *dst_s
, char end_sym
)
5908 while (ISSPACE (*src_s
))
5910 while (*src_s
!= end_sym
)
5911 dst_s
[nlen
++] = *(src_s
++);
5916 /* idly 4 -> idly4. */
5921 char *s
= csky_insn
.opcode_end
;
5922 if (!is_imm_within_range (&s
, 4, 4))
5924 as_bad (_("second operand must be 4"));
5927 csky_macro_md_assemble ("idly4", NULL
, NULL
, NULL
);
5931 /* rolc rd, 1 or roltc rd, 1 -> addc rd, rd. */
5937 char *s
= csky_insn
.opcode_end
;
5939 s
+= csky_get_macro_operand (s
, reg
, ',');
5942 if (is_imm_within_range (&s
, 1, 1))
5944 csky_macro_md_assemble ("addc", reg
, reg
, NULL
);
5948 as_bad (_("second operand must be 1"));
5951 /* sxtrb0(1)(2) r1, rx -> xtbr0(1)(2) r1,rx; sextb r1. */
5959 char *s
= csky_insn
.opcode_end
;
5960 s
+= csky_get_macro_operand (s
, reg1
, ',');
5962 csky_get_macro_operand (s
, reg2
, '\0');
5964 csky_macro_md_assemble (csky_insn
.macro
->name
+ 1, reg1
, reg2
, NULL
);
5965 csky_macro_md_assemble ("sextb", reg1
, NULL
, NULL
);
5976 char *s
= csky_insn
.opcode_end
;
5977 s
+= csky_get_macro_operand (s
, reg1
, ',');
5980 s
+= csky_get_macro_operand (s
, reg2
, ',');
5983 s
+= csky_get_macro_operand (s
, reg3
, '\0');
5985 csky_macro_md_assemble ("movt", reg1
, reg2
, NULL
);
5986 csky_macro_md_assemble ("movf", reg1
, reg3
, NULL
);
5991 get_macro_reg_vals (int *reg1
, int *reg2
, int *reg3
)
5994 char *s
= csky_insn
.opcode_end
;
5996 *reg1
= csky_get_reg_val (s
, &nlen
);
6000 csky_show_error (ERROR_MISSING_COMMA
, 0, NULL
, NULL
);
6004 *reg2
= csky_get_reg_val (s
, &nlen
);
6008 csky_show_error (ERROR_MISSING_COMMA
, 0, NULL
, NULL
);
6012 *reg3
= csky_get_reg_val (s
, &nlen
);
6016 csky_show_error (ERROR_BAD_END
, 0, s
, NULL
);
6019 if (*reg1
== -1 || *reg2
== -1 || *reg3
== -1)
6021 as_bad (_("register number out of range"));
6026 as_bad (_("dest and source1 must be the same register"));
6029 if (*reg1
>= 15 || *reg3
>= 15)
6031 as_bad (_("64-bit operator src/dst register must be less than 15"));
6037 /* addc64 rx, rx, ry -> cmplt rx, rx, addc rx, ry, addc rx+1, ry+1. */
6045 char reg1_name
[16] = {0};
6046 char reg3_name
[16] = {0};
6048 if (!get_macro_reg_vals (®1
, ®2
, ®3
))
6051 sprintf (reg1_name
, "r%d", reg1
);
6052 csky_macro_md_assemble ("cmplt", reg1_name
, reg1_name
, NULL
);
6053 if (error_state
.err_num
!= ERROR_NONE
)
6056 sprintf (reg1_name
, "r%d", reg1
+ (target_big_endian
? 1 : 0));
6057 sprintf (reg3_name
, "r%d", reg3
+ (target_big_endian
? 1 : 0));
6058 csky_macro_md_assemble ("addc", reg1_name
, reg3_name
, NULL
);
6059 if (error_state
.err_num
!= ERROR_NONE
)
6062 sprintf (reg1_name
, "r%d", reg1
+ (target_big_endian
? 0 : 1));
6063 sprintf (reg3_name
, "r%d", reg3
+ (target_big_endian
? 0 : 1));
6064 csky_macro_md_assemble ("addc", reg1_name
, reg3_name
, NULL
);
6068 /* subc64 rx, rx, ry -> cmphs rx, rx, subc rx, ry, subc rx+1, ry+1. */
6076 char reg1_name
[16] = {0};
6077 char reg3_name
[16] = {0};
6079 if (!get_macro_reg_vals (®1
, ®2
, ®3
))
6082 sprintf (reg1_name
, "r%d", reg1
);
6083 csky_macro_md_assemble ("cmphs", reg1_name
, reg1_name
, NULL
);
6084 if (error_state
.err_num
!= ERROR_NONE
)
6087 sprintf (reg1_name
, "r%d", reg1
+ (target_big_endian
? 1 : 0));
6088 sprintf (reg3_name
, "r%d", reg3
+ (target_big_endian
? 1 : 0));
6089 csky_macro_md_assemble ("subc", reg1_name
, reg3_name
, NULL
);
6090 if (error_state
.err_num
!= ERROR_NONE
)
6093 sprintf (reg1_name
, "r%d", reg1
+ (target_big_endian
? 0 : 1));
6094 sprintf (reg3_name
, "r%d", reg3
+ (target_big_endian
? 0 : 1));
6095 csky_macro_md_assemble ("subc", reg1_name
, reg3_name
, NULL
);
6099 /* or64 rx, rx, ry -> or rx, ry, or rx+1, ry+1. */
6107 char reg1_name
[16] = {0};
6108 char reg3_name
[16] = {0};
6110 if (!get_macro_reg_vals (®1
, ®2
, ®3
))
6112 sprintf (reg1_name
, "r%d", reg1
+ (target_big_endian
? 1 : 0));
6113 sprintf (reg3_name
, "r%d", reg3
+ (target_big_endian
? 1 : 0));
6114 csky_macro_md_assemble ("or", reg1_name
, reg3_name
, NULL
);
6116 if (error_state
.err_num
!= ERROR_NONE
)
6118 sprintf (reg1_name
, "r%d", reg1
+ (target_big_endian
? 0 : 1));
6119 sprintf (reg3_name
, "r%d", reg3
+ (target_big_endian
? 0 : 1));
6120 csky_macro_md_assemble ("or", reg1_name
, reg3_name
, NULL
);
6124 /* xor64 rx, rx, ry -> xor rx, ry, xor rx+1, ry+1. */
6132 char reg1_name
[16] = {0};
6133 char reg3_name
[16] = {0};
6135 if (!get_macro_reg_vals (®1
, ®2
, ®3
))
6138 sprintf (reg1_name
, "r%d", reg1
+ (target_big_endian
? 1 : 0));
6139 sprintf (reg3_name
, "r%d", reg3
+ (target_big_endian
? 1 : 0));
6140 csky_macro_md_assemble ("xor", reg1_name
, reg3_name
, NULL
);
6141 if (error_state
.err_num
!= ERROR_NONE
)
6144 sprintf (reg1_name
, "r%d", reg1
+ (target_big_endian
? 0 : 1));
6145 sprintf (reg3_name
, "r%d", reg3
+ (target_big_endian
? 0 : 1));
6146 csky_macro_md_assemble ("xor", reg1_name
, reg3_name
, NULL
);
6150 /* The following are V2 macro instructions. */
6152 /* neg rd -> not rd, rd; addi rd, 1. */
6159 char *s
= csky_insn
.opcode_end
;
6160 s
+= csky_get_macro_operand (s
, reg1
, '\0');
6163 csky_macro_md_assemble ("not", reg1
, reg1
, NULL
);
6164 csky_macro_md_assemble ("addi", reg1
, "1", NULL
);
6168 /* rsubi rd, imm16 -> not rd; addi rd, imm16 + 1 */
6175 unsigned int imm16
= 0;
6177 char *s
= csky_insn
.opcode_end
;
6178 s
+= csky_get_macro_operand (s
, reg1
, ',');
6181 s
= parse_exp (s
, &e
);
6182 if (e
.X_op
== O_constant
)
6183 imm16
= e
.X_add_number
;
6185 csky_show_error (ERROR_IMM_ILLEGAL
, 2, NULL
, NULL
);
6187 sprintf (str_imm16
, "%d", imm16
+ 1);
6189 csky_macro_md_assemble ("not", reg1
, reg1
, NULL
);
6190 csky_macro_md_assemble ("addi", reg1
, str_imm16
, NULL
);
6194 /* Such as: asrc rd -> asrc rd, rd, 1. */
6200 char *s
= csky_insn
.opcode_end
;
6201 s
+= csky_get_macro_operand (s
, reg1
, '\0');
6203 csky_macro_md_assemble (csky_insn
.macro
->name
, reg1
, reg1
, "1");
6207 /* decne rd -> if ck802: subi rd, 1; cmpnei rd, 0.
6208 else: decne rd, rd, 1 */
6214 char *s
= csky_insn
.opcode_end
;
6215 s
+= csky_get_macro_operand (s
, reg1
, '\0');
6217 if (IS_CSKY_ARCH_802 (mach_flag
))
6219 csky_macro_md_assemble ("subi", reg1
, "1", NULL
);
6220 csky_macro_md_assemble ("cmpnei", reg1
, "0", NULL
);
6223 csky_macro_md_assemble ("decne", reg1
, reg1
, "1");
6227 /* If -mnolrw, lrw rd, imm -> movih rd, imm_hi16; ori rd, imm_lo16. */
6237 char *s
= csky_insn
.opcode_end
;
6238 s
+= csky_get_macro_operand (s
, reg1
, ',');
6240 s
+= csky_get_macro_operand (s
, imm
, '\0');
6244 strcat (imm_hi16
, "(");
6245 strcat (imm_hi16
, imm
);
6246 strcat (imm_hi16
, ") >> 16");
6248 strcat (imm_lo16
, "(");
6249 strcat (imm_lo16
, imm
);
6250 strcat (imm_lo16
, ") & 0xffff");
6252 csky_macro_md_assemble ("movih", reg1
, imm_hi16
, NULL
);
6253 csky_macro_md_assemble ("ori", reg1
, reg1
, imm_lo16
);
6258 /* The following are worker functions for C-SKY v1. */
6264 int output_literal
= csky_insn
.val
[1];
6266 reg
= csky_insn
.val
[0];
6267 csky_insn
.isize
= 2;
6268 csky_insn
.output
= frag_more (2);
6269 if (csky_insn
.e1
.X_op
== O_constant
6270 && csky_insn
.e1
.X_add_number
<= 0x7f
6271 && csky_insn
.e1
.X_add_number
>= 0)
6273 csky_insn
.inst
= 0x6000 | reg
| (csky_insn
.e1
.X_add_number
<< 4);
6276 csky_insn
.inst
= csky_insn
.opcode
->op16
[0].opcode
;
6277 csky_insn
.inst
|= reg
<< 8;
6280 struct literal
*p
= enter_literal (&csky_insn
.e1
, 0, 0, 0);
6282 /* Create a reference to pool entry. */
6283 csky_insn
.e1
.X_op
= O_symbol
;
6284 csky_insn
.e1
.X_add_symbol
= poolsym
;
6285 csky_insn
.e1
.X_add_number
= p
->offset
<< 2;
6288 if (insn_reloc
== BFD_RELOC_CKCORE_TLS_GD32
6289 || insn_reloc
== BFD_RELOC_CKCORE_TLS_LDM32
6290 || insn_reloc
== BFD_RELOC_CKCORE_TLS_IE32
)
6292 literal_insn_offset
->tls_addend
.frag
= frag_now
;
6293 literal_insn_offset
->tls_addend
.offset
6295 - literal_insn_offset
->tls_addend
.frag
->fr_literal
);
6297 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
, 2,
6298 &csky_insn
.e1
, 1, BFD_RELOC_CKCORE_PCREL_IMM8BY4
);
6300 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6306 v1_work_fpu_fo (void)
6312 struct csky_opcode_info
*opinfo
= NULL
;
6314 if (csky_insn
.isize
== 4)
6315 opinfo
= &csky_insn
.opcode
->op32
[csky_insn
.opcode_idx
];
6316 else if (csky_insn
.isize
== 2)
6317 opinfo
= &csky_insn
.opcode
->op16
[csky_insn
.opcode_idx
];
6319 /* Firstly, get general reg. */
6320 for (i
= 0;i
< opinfo
->operand_num
; i
++)
6321 if (opinfo
->oprnd
.oprnds
[i
].type
== OPRND_TYPE_GREG0_15
)
6322 greg
= csky_insn
.val
[i
];
6323 gas_assert (greg
!= -1);
6325 /* Secondly, get float inst. */
6326 csky_generate_insn ();
6327 inst
= csky_insn
.inst
;
6329 /* Now get greg and inst, we can write instruction to floating unit. */
6330 sprintf (buff
, "lrw r%d,0x%x", greg
, inst
);
6332 sprintf (buff
, "cpwir r%d", greg
);
6338 v1_work_fpu_fo_fc (void)
6344 struct csky_opcode_info
*opinfo
= NULL
;
6346 if (csky_insn
.isize
== 4)
6347 opinfo
= &csky_insn
.opcode
->op32
[csky_insn
.opcode_idx
];
6348 else if (csky_insn
.isize
== 2)
6349 opinfo
= &csky_insn
.opcode
->op16
[csky_insn
.opcode_idx
];
6351 /* Firstly, get general reg. */
6352 for (i
= 0;i
< opinfo
->operand_num
; i
++)
6353 if (opinfo
->oprnd
.oprnds
[i
].type
== OPRND_TYPE_GREG0_15
)
6354 greg
= csky_insn
.val
[i
];
6355 gas_assert (greg
!= -1);
6357 /* Secondly, get float inst. */
6358 csky_generate_insn ();
6359 inst
= csky_insn
.inst
;
6361 /* Now get greg and inst, we can write instruction to floating unit. */
6362 sprintf (buff
, "lrw r%d,0x%x", greg
, inst
);
6364 sprintf (buff
, "cpwir r%d", greg
);
6366 sprintf (buff
, "cprc");
6373 v1_work_fpu_write (void)
6379 greg
= csky_insn
.val
[0];
6380 freg
= csky_insn
.val
[1];
6382 /* Now get greg and freg, we can write instruction to floating unit. */
6383 sprintf (buff
, "cpwgr r%d,cpr%d", greg
, freg
);
6390 v1_work_fpu_read (void)
6396 greg
= csky_insn
.val
[0];
6397 freg
= csky_insn
.val
[1];
6398 /* Now get greg and freg, we can write instruction to floating unit. */
6399 sprintf (buff
, "cprgr r%d,cpr%d", greg
, freg
);
6406 v1_work_fpu_writed (void)
6412 greg
= csky_insn
.val
[0];
6413 freg
= csky_insn
.val
[1];
6417 as_bad (_("even register number required"));
6420 /* Now get greg and freg, we can write instruction to floating unit. */
6421 if (target_big_endian
)
6422 sprintf (buff
, "cpwgr r%d,cpr%d", greg
+ 1, freg
);
6424 sprintf (buff
, "cpwgr r%d,cpr%d", greg
, freg
);
6426 if (target_big_endian
)
6427 sprintf (buff
, "cpwgr r%d,cpr%d", greg
, freg
+ 1);
6429 sprintf (buff
, "cpwgr r%d,cpr%d", greg
+1, freg
+ 1);
6435 v1_work_fpu_readd (void)
6441 greg
= csky_insn
.val
[0];
6442 freg
= csky_insn
.val
[1];
6446 as_bad (_("even register number required"));
6449 /* Now get greg and freg, we can write instruction to floating unit. */
6450 if (target_big_endian
)
6451 sprintf (buff
, "cprgr r%d,cpr%d", greg
+1, freg
);
6453 sprintf (buff
, "cprgr r%d,cpr%d", greg
, freg
);
6455 if (target_big_endian
)
6456 sprintf (buff
, "cprgr r%d,cpr%d", greg
, freg
+ 1);
6458 sprintf (buff
, "cprgr r%d,cpr%d", greg
+1, freg
+ 1);
6464 /* The following are for csky pseudo handling. */
6469 csky_insn
.output
= frag_more (2);
6471 /* Generate fixup BFD_RELOC_CKCORE_PCREL_IMM11BY2. */
6472 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
6473 2, & csky_insn
.e1
, 1, BFD_RELOC_CKCORE_PCREL_IMM11BY2
);
6476 /* Using jsri instruction. */
6477 const char *name
= "jsri";
6478 csky_insn
.opcode
= (struct csky_opcode
*)
6479 str_hash_find (csky_opcodes_hash
, name
);
6480 csky_insn
.opcode_idx
= 0;
6481 csky_insn
.isize
= 2;
6483 struct literal
*p
= enter_literal (&csky_insn
.e1
, 1, 0, 0);
6485 /* Create a reference to pool entry. */
6486 csky_insn
.e1
.X_op
= O_symbol
;
6487 csky_insn
.e1
.X_add_symbol
= poolsym
;
6488 csky_insn
.e1
.X_add_number
= p
->offset
<< 2;
6490 /* Generate fixup BFD_RELOC_CKCORE_PCREL_IMM8BY4. */
6491 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
6492 2, & csky_insn
.e1
, 1, BFD_RELOC_CKCORE_PCREL_IMM8BY4
);
6494 if (csky_insn
.e1
.X_op
!= O_absent
&& do_jsri2bsr
)
6495 /* Generate fixup BFD_RELOC_CKCORE_PCREL_JSR_IMM11BY2. */
6496 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
6498 1, BFD_RELOC_CKCORE_PCREL_JSR_IMM11BY2
);
6500 csky_generate_insn ();
6502 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6507 /* The following are worker functions for csky v2 instruction handling. */
6509 /* For nie/nir/ipush/ipop. */
6512 v2_work_istack (void)
6516 csky_show_error (ERROR_OPCODE_ILLEGAL
, 0, NULL
, NULL
);
6519 csky_insn
.output
= frag_more (csky_insn
.isize
);
6520 csky_insn
.inst
= csky_insn
.opcode
->op16
[0].opcode
;
6521 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6526 v2_work_btsti (void)
6529 && (csky_insn
.flag_force
== INSN_OPCODE16F
6530 || IS_CSKY_ARCH_801 (mach_flag
)))
6532 csky_show_error (ERROR_OPCODE_ILLEGAL
, 0, NULL
, NULL
);
6535 if (!do_extend_lrw
&& csky_insn
.isize
== 2)
6536 csky_insn
.isize
= 4;
6537 /* Generate relax or reloc if necessary. */
6538 csky_generate_frags ();
6539 /* Generate the insn by mask. */
6540 csky_generate_insn ();
6541 /* Write inst to frag. */
6542 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6549 csky_insn
.isize
= 2;
6550 if (csky_insn
.number
== 2)
6552 if (csky_insn
.val
[0] == 14
6553 && csky_insn
.val
[1] >= 0 && csky_insn
.val
[1] <= 0x1fc
6554 && (csky_insn
.val
[1] & 0x3) == 0
6555 && csky_insn
.flag_force
!= INSN_OPCODE32F
)
6557 /* addi sp, sp, imm. */
6558 csky_insn
.inst
= 0x1400 | ((csky_insn
.val
[1] >> 2) & 0x1f);
6559 csky_insn
.inst
|= (csky_insn
.val
[1] << 1) & 0x300;
6560 csky_insn
.output
= frag_more (2);
6562 else if (csky_insn
.val
[0] < 8
6563 && csky_insn
.val
[1] >= 1 && csky_insn
.val
[1] <= 0x100
6564 && csky_insn
.flag_force
!= INSN_OPCODE32F
)
6566 csky_insn
.inst
= 0x2000 | (csky_insn
.val
[0] << 8);
6567 csky_insn
.inst
|= (csky_insn
.val
[1] - 1);
6568 csky_insn
.output
= frag_more (2);
6570 else if (csky_insn
.val
[1] >= 1 && csky_insn
.val
[1] <= 0x10000
6571 && csky_insn
.flag_force
!= INSN_OPCODE16F
6572 && !IS_CSKY_ARCH_801 (mach_flag
))
6574 csky_insn
.inst
= 0xe4000000 | (csky_insn
.val
[0] << 21);
6575 csky_insn
.inst
|= csky_insn
.val
[0] << 16;
6576 csky_insn
.inst
|= (csky_insn
.val
[1] - 1);
6577 csky_insn
.isize
= 4;
6578 csky_insn
.output
= frag_more (4);
6582 csky_show_error (ERROR_OPERANDS_ILLEGAL
, 0,
6583 csky_insn
.opcode_end
, NULL
);
6587 else if (csky_insn
.number
== 3)
6589 if (csky_insn
.val
[0] == 14
6590 && csky_insn
.val
[1] == 14
6591 && csky_insn
.val
[2] >= 0 && csky_insn
.val
[2] <= 0x1fc
6592 && (csky_insn
.val
[2] & 0x3) == 0
6593 && csky_insn
.flag_force
!= INSN_OPCODE32F
)
6595 csky_insn
.inst
= 0x1400 | ((csky_insn
.val
[2] >> 2) & 0x1f);
6596 csky_insn
.inst
|= (csky_insn
.val
[2] << 1) & 0x300;
6597 csky_insn
.output
= frag_more (2);
6599 else if (csky_insn
.val
[0] < 8
6600 && csky_insn
.val
[1] == 14
6601 && csky_insn
.val
[2] >= 0 && csky_insn
.val
[2] <= 0x3fc
6602 && (csky_insn
.val
[2] & 0x3) == 0
6603 && csky_insn
.flag_force
!= INSN_OPCODE32F
)
6605 csky_insn
.inst
= 0x1800 | (csky_insn
.val
[0] << 8);
6606 csky_insn
.inst
|= csky_insn
.val
[2] >> 2;
6607 csky_insn
.output
= frag_more (2);
6609 else if (csky_insn
.val
[0] < 8
6610 && csky_insn
.val
[0] == csky_insn
.val
[1]
6611 && csky_insn
.val
[2] >= 1 && csky_insn
.val
[2] <= 0x100
6612 && csky_insn
.flag_force
!= INSN_OPCODE32F
)
6614 csky_insn
.inst
= 0x2000 | (csky_insn
.val
[0] << 8);
6615 csky_insn
.inst
|= (csky_insn
.val
[2] - 1);
6616 csky_insn
.output
= frag_more (2);
6618 else if (csky_insn
.val
[0] < 8
6619 && csky_insn
.val
[1] < 8
6620 && csky_insn
.val
[2] >= 1 && csky_insn
.val
[2] <= 0x8
6621 && csky_insn
.flag_force
!= INSN_OPCODE32F
)
6623 csky_insn
.inst
= 0x5802 | (csky_insn
.val
[0] << 5);
6624 csky_insn
.inst
|= csky_insn
.val
[1] << 8;
6625 csky_insn
.inst
|= (csky_insn
.val
[2] - 1) << 2;
6626 csky_insn
.output
= frag_more (2);
6628 else if (csky_insn
.val
[1] == 28
6629 && csky_insn
.val
[2] >= 1 && csky_insn
.val
[2] <= 0x40000
6630 && csky_insn
.flag_force
!= INSN_OPCODE16F
6631 && !IS_CSKY_ARCH_801 (mach_flag
))
6633 csky_insn
.inst
= 0xcc1c0000 | (csky_insn
.val
[0] << 21);
6634 csky_insn
.isize
= 4;
6635 csky_insn
.output
= frag_more (4);
6636 if (insn_reloc
== BFD_RELOC_CKCORE_GOTOFF
)
6638 fix_new_exp (frag_now
, csky_insn
.output
-frag_now
->fr_literal
,
6639 4, &csky_insn
.e1
, 0, BFD_RELOC_CKCORE_GOTOFF_IMM18
);
6642 csky_insn
.inst
|= (csky_insn
.val
[2] - 1);
6644 else if (csky_insn
.val
[2] >= 1 && csky_insn
.val
[2] <= 0x1000
6645 && csky_insn
.flag_force
!= INSN_OPCODE16F
6646 && !IS_CSKY_ARCH_801 (mach_flag
))
6648 csky_insn
.inst
= 0xe4000000 | (csky_insn
.val
[0] << 21);
6649 csky_insn
.inst
|= csky_insn
.val
[1] << 16;
6650 csky_insn
.inst
|= (csky_insn
.val
[2] - 1);
6651 csky_insn
.isize
= 4;
6652 csky_insn
.output
= frag_more (4);
6656 csky_show_error (ERROR_OPERANDS_ILLEGAL
, 0,
6657 (char *)csky_insn
.opcode_end
, NULL
);
6661 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6669 csky_insn
.isize
= 2;
6670 if (csky_insn
.number
== 2)
6672 if (csky_insn
.val
[0] == 14
6673 && csky_insn
.val
[1] >= 0 && csky_insn
.val
[2] <= 0x1fc
6674 && (csky_insn
.val
[1] & 0x3) == 0
6675 && csky_insn
.flag_force
!= INSN_OPCODE32F
)
6677 csky_insn
.inst
= 0x1420 | ((csky_insn
.val
[1] >> 2) & 0x1f);
6678 csky_insn
.inst
|= (csky_insn
.val
[1] << 1) & 0x300;
6680 else if (csky_insn
.val
[0] < 8
6681 && csky_insn
.val
[1] >= 1 && csky_insn
.val
[1] <= 0x100
6682 && csky_insn
.flag_force
!= INSN_OPCODE32F
)
6684 csky_insn
.inst
= 0x2800 | (csky_insn
.val
[0] << 8);
6685 csky_insn
.inst
|= (csky_insn
.val
[1] - 1);
6687 else if (csky_insn
.val
[1] >= 1 && csky_insn
.val
[1] <= 0x10000
6688 && csky_insn
.flag_force
!= INSN_OPCODE16F
6689 && !IS_CSKY_ARCH_801 (mach_flag
))
6691 csky_insn
.inst
= 0xe4001000 | (csky_insn
.val
[0] << 21);
6692 csky_insn
.inst
|= csky_insn
.val
[0] << 16;
6693 csky_insn
.inst
|= (csky_insn
.val
[1] - 1);
6694 csky_insn
.isize
= 4;
6698 csky_show_error (ERROR_OPERANDS_ILLEGAL
, 0,
6699 (char *)csky_insn
.opcode_end
, NULL
);
6703 else if (csky_insn
.number
== 3)
6705 if (csky_insn
.val
[0] == 14
6706 && csky_insn
.val
[1] == 14
6707 && csky_insn
.val
[2] >= 0 && csky_insn
.val
[2] <= 0x1fc
6708 && (csky_insn
.val
[2] & 0x3) == 0
6709 && csky_insn
.flag_force
!= INSN_OPCODE32F
)
6711 csky_insn
.inst
= 0x1420 | ((csky_insn
.val
[2] >> 2) & 0x1f);
6712 csky_insn
.inst
|= (csky_insn
.val
[2] << 1) & 0x300;
6715 else if (csky_insn
.val
[0] < 8
6716 && csky_insn
.val
[0] == csky_insn
.val
[1]
6717 && csky_insn
.val
[2] >= 1 && csky_insn
.val
[2] <= 0x100
6718 && csky_insn
.flag_force
!= INSN_OPCODE32F
)
6720 csky_insn
.inst
= 0x2800 | (csky_insn
.val
[0] << 8);
6721 csky_insn
.inst
|= (csky_insn
.val
[2] - 1);
6723 else if (csky_insn
.val
[0] < 8
6724 && csky_insn
.val
[1] < 8
6725 && csky_insn
.val
[2] >= 1 && csky_insn
.val
[2] <= 0x8
6726 && csky_insn
.flag_force
!= INSN_OPCODE32F
)
6728 csky_insn
.inst
= 0x5803 | (csky_insn
.val
[0] << 5);
6729 csky_insn
.inst
|= csky_insn
.val
[1] << 8;
6730 csky_insn
.inst
|= (csky_insn
.val
[2] - 1) << 2;
6732 else if (csky_insn
.val
[2] >= 1 && csky_insn
.val
[2] <= 0x1000
6733 && csky_insn
.flag_force
!= INSN_OPCODE16F
6734 && !IS_CSKY_ARCH_801 (mach_flag
))
6736 csky_insn
.inst
= 0xe4001000 | (csky_insn
.val
[0] << 21);
6737 csky_insn
.inst
|= csky_insn
.val
[1] << 16;
6738 csky_insn
.inst
|= (csky_insn
.val
[2] - 1);
6739 csky_insn
.isize
= 4;
6743 csky_show_error (ERROR_OPERANDS_ILLEGAL
, 0,
6744 (char *)csky_insn
.opcode_end
, NULL
);
6748 csky_insn
.output
= frag_more (csky_insn
.isize
);
6749 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6755 v2_work_add_sub (void)
6757 if (csky_insn
.number
== 3
6758 && (csky_insn
.val
[0] == csky_insn
.val
[1]
6759 || csky_insn
.val
[0] == csky_insn
.val
[2])
6760 && csky_insn
.val
[0] <= 15
6761 && csky_insn
.val
[1] <= 15
6762 && csky_insn
.val
[2] <= 15)
6764 if (!strstr (csky_insn
.opcode
->mnemonic
, "sub")
6765 || csky_insn
.val
[0] == csky_insn
.val
[1])
6767 csky_insn
.opcode_idx
= 0;
6768 csky_insn
.isize
= 2;
6769 if (csky_insn
.val
[0] == csky_insn
.val
[1])
6770 csky_insn
.val
[1] = csky_insn
.val
[2];
6772 csky_insn
.number
= 2;
6776 if (csky_insn
.isize
== 4
6777 && IS_CSKY_ARCH_801 (mach_flag
))
6779 if (csky_insn
.number
== 3)
6781 if (csky_insn
.val
[0] > 7)
6783 SET_ERROR_INTEGER (ERROR_REG_OVER_RANGE
, csky_insn
.val
[0]);
6784 csky_show_error (ERROR_REG_OVER_RANGE
, 1, NULL
, NULL
);
6786 if (csky_insn
.val
[1] > 7)
6788 SET_ERROR_INTEGER (ERROR_REG_OVER_RANGE
, csky_insn
.val
[1]);
6789 csky_show_error (ERROR_REG_OVER_RANGE
, 2, NULL
, NULL
);
6791 if (csky_insn
.val
[2] > 7)
6793 SET_ERROR_INTEGER (ERROR_REG_OVER_RANGE
, csky_insn
.val
[2]);
6794 csky_show_error (ERROR_REG_OVER_RANGE
, 3, NULL
, NULL
);
6799 if (csky_insn
.val
[0] > 15)
6801 SET_ERROR_INTEGER (ERROR_REG_OVER_RANGE
, csky_insn
.val
[0]);
6802 csky_show_error (ERROR_REG_OVER_RANGE
, 1, NULL
, NULL
);
6804 if (csky_insn
.val
[1] > 15)
6806 SET_ERROR_INTEGER (ERROR_REG_OVER_RANGE
, csky_insn
.val
[1]);
6807 csky_show_error (ERROR_REG_OVER_RANGE
, 2, NULL
, NULL
);
6813 /* Generate relax or reloc if necessary. */
6814 csky_generate_frags ();
6815 /* Generate the insn by mask. */
6816 csky_generate_insn ();
6817 /* Write inst to frag. */
6818 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6823 v2_work_rotlc (void)
6825 const char *name
= "addc";
6827 = (struct csky_opcode
*) str_hash_find (csky_opcodes_hash
, name
);
6828 csky_insn
.opcode_idx
= 0;
6829 if (csky_insn
.isize
== 2)
6832 csky_insn
.number
= 2;
6833 csky_insn
.val
[1] = csky_insn
.val
[0];
6837 csky_insn
.number
= 3;
6838 /* addc rz, rx, ry. */
6839 csky_insn
.val
[1] = csky_insn
.val
[0];
6840 csky_insn
.val
[2] = csky_insn
.val
[0];
6842 /* Generate relax or reloc if necessary. */
6843 csky_generate_frags ();
6844 /* Generate the insn by mask. */
6845 csky_generate_insn ();
6846 /* Write inst to frag. */
6847 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6852 v2_work_bgeni (void)
6854 const char *name
= NULL
;
6855 int imm
= csky_insn
.val
[1];
6865 = (struct csky_opcode
*) str_hash_find (csky_opcodes_hash
, name
);
6866 csky_insn
.opcode_idx
= 0;
6867 csky_insn
.val
[1] = val
;
6869 /* Generate relax or reloc if necessary. */
6870 csky_generate_frags ();
6871 /* Generate the insn by mask. */
6872 csky_generate_insn ();
6873 /* Write inst to frag. */
6874 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6881 const char *name
= "nor";
6883 = (struct csky_opcode
*) str_hash_find (csky_opcodes_hash
, name
);
6884 csky_insn
.opcode_idx
= 0;
6885 if (csky_insn
.number
== 1)
6887 csky_insn
.val
[1] = csky_insn
.val
[0];
6888 if (csky_insn
.val
[0] < 16)
6890 /* 16 bits nor rz, rz. */
6891 csky_insn
.number
= 2;
6892 csky_insn
.isize
= 2;
6896 csky_insn
.val
[2] = csky_insn
.val
[0];
6897 csky_insn
.number
= 3;
6898 csky_insn
.isize
= 4;
6901 if (csky_insn
.number
== 2)
6903 if (csky_insn
.val
[0] == csky_insn
.val
[1]
6904 && csky_insn
.val
[0] < 16)
6906 /* 16 bits nor rz, rz. */
6907 csky_insn
.number
= 2;
6908 csky_insn
.isize
= 2;
6912 csky_insn
.val
[2] = csky_insn
.val
[1];
6913 csky_insn
.number
= 3;
6914 csky_insn
.isize
= 4;
6918 /* Generate relax or reloc if necessary. */
6919 csky_generate_frags ();
6920 /* Generate the insn by mask. */
6921 csky_generate_insn ();
6922 /* Write inst to frag. */
6923 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6930 if (csky_insn
.e1
.X_add_symbol
== NULL
|| csky_insn
.e1
.X_op
== O_constant
)
6932 csky_show_error (ERROR_UNDEFINE
, 0, (void *)"operand is invalid", NULL
);
6936 if (IS_CSKY_ARCH_801 (mach_flag
))
6938 /* CK801 doesn't have 32-bit bt/bf insns or a jump insn with a
6939 range larger than SCOND_DISP16. Relax to a short jump around
6940 an unconditional branch, and give up if that overflows too. */
6941 csky_insn
.output
= frag_var (rs_machine_dependent
,
6945 csky_insn
.e1
.X_add_symbol
,
6946 csky_insn
.e1
.X_add_number
,
6948 csky_insn
.isize
= 2;
6949 csky_insn
.max
= SCOND_DISP16_LEN
;
6950 csky_insn
.inst
= csky_insn
.opcode
->op16
[0].opcode
;
6952 else if (do_long_jump
&& !IS_CSKY_ARCH_802 (mach_flag
))
6954 /* Generate relax with jcondition.
6955 Note that CK802 doesn't support the JMPI instruction so
6956 we cannot relax to a jump with a 32-bit offset. */
6957 csky_insn
.output
= frag_var (rs_machine_dependent
,
6961 csky_insn
.e1
.X_add_symbol
,
6962 csky_insn
.e1
.X_add_number
,
6964 csky_insn
.isize
= 2;
6965 csky_insn
.max
= JCOND_DISP32_LEN
;
6966 csky_insn
.inst
= csky_insn
.opcode
->op16
[0].opcode
;
6970 /* Generate relax with condition. */
6971 csky_insn
.output
= frag_var (rs_machine_dependent
,
6975 csky_insn
.e1
.X_add_symbol
,
6976 csky_insn
.e1
.X_add_number
,
6978 csky_insn
.isize
= 2;
6979 csky_insn
.max
= COND_DISP16_LEN
;
6980 csky_insn
.inst
= csky_insn
.opcode
->op16
[0].opcode
;
6982 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6990 if (csky_insn
.e1
.X_add_symbol
== NULL
|| csky_insn
.e1
.X_op
== O_constant
)
6992 csky_show_error (ERROR_UNDEFINE
, 0, (void *)"operand is invalid", NULL
);
6997 && !IS_CSKY_ARCH_801 (mach_flag
)
6998 && !IS_CSKY_ARCH_802 (mach_flag
))
7000 csky_insn
.output
= frag_var (rs_machine_dependent
,
7004 csky_insn
.e1
.X_add_symbol
,
7005 csky_insn
.e1
.X_add_number
,
7008 csky_insn
.inst
= csky_insn
.opcode
->op16
[0].opcode
;
7009 csky_insn
.max
= JUNCD_DISP32_LEN
;
7010 csky_insn
.isize
= 2;
7014 /* Generate relax with condition. */
7015 csky_insn
.output
= frag_var (rs_machine_dependent
,
7019 csky_insn
.e1
.X_add_symbol
,
7020 csky_insn
.e1
.X_add_number
,
7022 csky_insn
.isize
= 2;
7023 csky_insn
.max
= UNCD_DISP16_LEN
;
7024 csky_insn
.inst
= csky_insn
.opcode
->op16
[0].opcode
;
7027 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
7031 #define SIZE_V2_MOVI16(x) ((addressT)x <= 0xff)
7032 #define SIZE_V2_MOVI32(x) ((addressT)x <= 0xffff)
7033 #define SIZE_V2_MOVIH(x) ((addressT)x <= 0xffffffff && (((addressT)x & 0xffff) == 0))
7038 int reg
= csky_insn
.val
[0];
7039 int output_literal
= csky_insn
.val
[1];
7042 /* If the second operand is O_constant, We can use movi/movih
7044 if (csky_insn
.e1
.X_op
== O_constant
)
7046 /* 801 only has movi16. */
7047 if (SIZE_V2_MOVI16 (csky_insn
.e1
.X_add_number
) && reg
< 8)
7049 /* movi16 instead. */
7050 csky_insn
.output
= frag_more (2);
7051 csky_insn
.inst
= (CSKYV2_INST_MOVI16
| (reg
<< 8)
7052 | (csky_insn
.e1
.X_add_number
));
7053 csky_insn
.isize
= 2;
7056 else if (SIZE_V2_MOVI32 (csky_insn
.e1
.X_add_number
)
7057 && !IS_CSKY_ARCH_801 (mach_flag
))
7059 /* movi32 instead. */
7060 csky_insn
.output
= frag_more (4);
7061 csky_insn
.inst
= (CSKYV2_INST_MOVI32
| (reg
<< 16)
7062 | (csky_insn
.e1
.X_add_number
));
7063 csky_insn
.isize
= 4;
7066 else if (SIZE_V2_MOVIH (csky_insn
.e1
.X_add_number
)
7067 && !IS_CSKY_ARCH_801 (mach_flag
))
7069 /* movih instead. */
7070 csky_insn
.output
= frag_more (4);
7071 csky_insn
.inst
= (CSKYV2_INST_MOVIH
| (reg
<< 16)
7072 | ((csky_insn
.e1
.X_add_number
>> 16) & 0xffff));
7073 csky_insn
.isize
= 4;
7080 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
7086 struct literal
*p
= enter_literal (&csky_insn
.e1
, 0, 0, 0);
7087 /* Create a reference to pool entry. */
7088 csky_insn
.e1
.X_op
= O_symbol
;
7089 csky_insn
.e1
.X_add_symbol
= poolsym
;
7090 csky_insn
.e1
.X_add_number
= p
->offset
<< 2;
7092 /* If 16bit force. */
7093 if (csky_insn
.flag_force
== INSN_OPCODE16F
)
7095 /* Generate fixup. */
7098 csky_show_error (ERROR_UNDEFINE
, 0,
7099 (void *)"The register is out of range.", NULL
);
7102 csky_insn
.isize
= 2;
7103 csky_insn
.output
= frag_more (2);
7105 if (insn_reloc
== BFD_RELOC_CKCORE_TLS_GD32
7106 || insn_reloc
== BFD_RELOC_CKCORE_TLS_LDM32
7107 || insn_reloc
== BFD_RELOC_CKCORE_TLS_IE32
)
7109 literal_insn_offset
->tls_addend
.frag
= frag_now
;
7110 literal_insn_offset
->tls_addend
.offset
7111 = csky_insn
.output
- frag_now
->fr_literal
;
7113 csky_insn
.inst
= csky_insn
.opcode
->op16
[0].opcode
| (reg
<< 5);
7115 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
7116 2, &csky_insn
.e1
, 1, BFD_RELOC_CKCORE_PCREL_IMM7BY4
);
7118 else if (csky_insn
.flag_force
== INSN_OPCODE32F
)
7120 csky_insn
.isize
= 4;
7121 csky_insn
.output
= frag_more (4);
7122 if (insn_reloc
== BFD_RELOC_CKCORE_TLS_GD32
7123 || insn_reloc
== BFD_RELOC_CKCORE_TLS_LDM32
7124 || insn_reloc
== BFD_RELOC_CKCORE_TLS_IE32
)
7126 literal_insn_offset
->tls_addend
.frag
= frag_now
;
7127 literal_insn_offset
->tls_addend
.offset
7128 = csky_insn
.output
- frag_now
->fr_literal
;
7130 csky_insn
.inst
= csky_insn
.opcode
->op32
[0].opcode
| (reg
<< 16);
7131 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
7132 4, &csky_insn
.e1
, 1, BFD_RELOC_CKCORE_PCREL_IMM16BY4
);
7138 csky_insn
.isize
= 2;
7140 if (insn_reloc
== BFD_RELOC_CKCORE_TLS_GD32
7141 || insn_reloc
== BFD_RELOC_CKCORE_TLS_LDM32
7142 || insn_reloc
== BFD_RELOC_CKCORE_TLS_IE32
)
7143 literal_insn_offset
->tls_addend
.frag
= frag_now
;
7145 csky_insn
.output
= frag_var (rs_machine_dependent
,
7149 ? LRW2_DISP8
: LRW_DISP7
),
7150 csky_insn
.e1
.X_add_symbol
,
7151 csky_insn
.e1
.X_add_number
, 0);
7152 if (insn_reloc
== BFD_RELOC_CKCORE_TLS_GD32
7153 || insn_reloc
== BFD_RELOC_CKCORE_TLS_LDM32
7154 || insn_reloc
== BFD_RELOC_CKCORE_TLS_IE32
)
7156 if (literal_insn_offset
->tls_addend
.frag
->fr_next
!= frag_now
)
7157 literal_insn_offset
->tls_addend
.frag
7158 = literal_insn_offset
->tls_addend
.frag
->fr_next
;
7159 literal_insn_offset
->tls_addend
.offset
7161 - literal_insn_offset
->tls_addend
.frag
->fr_literal
);
7163 csky_insn
.inst
= csky_insn
.opcode
->op16
[0].opcode
| (reg
<< 5);
7164 csky_insn
.max
= LRW_DISP16_LEN
;
7165 csky_insn
.isize
= 2;
7169 csky_insn
.isize
= 4;
7170 csky_insn
.output
= frag_more (4);
7171 if (insn_reloc
== BFD_RELOC_CKCORE_TLS_GD32
7172 || insn_reloc
== BFD_RELOC_CKCORE_TLS_LDM32
7173 || insn_reloc
== BFD_RELOC_CKCORE_TLS_IE32
)
7175 literal_insn_offset
->tls_addend
.frag
= frag_now
;
7176 literal_insn_offset
->tls_addend
.offset
7177 = csky_insn
.output
- frag_now
->fr_literal
;
7179 csky_insn
.inst
= csky_insn
.opcode
->op32
[0].opcode
| (reg
<< 16);
7180 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
7181 4, &csky_insn
.e1
, 1, BFD_RELOC_CKCORE_PCREL_IMM16BY4
);
7185 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
7190 v2_work_lrsrsw (void)
7192 int reg
= csky_insn
.val
[0];
7193 csky_insn
.output
= frag_more (4);
7194 csky_insn
.inst
= csky_insn
.opcode
->op32
[0].opcode
| (reg
<< 21);
7195 csky_insn
.isize
= 4;
7199 case BFD_RELOC_CKCORE_GOT32
:
7200 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
7201 4, &csky_insn
.e1
, 0, BFD_RELOC_CKCORE_GOT_IMM18BY4
);
7203 case BFD_RELOC_CKCORE_PLT32
:
7204 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
7205 4, &csky_insn
.e1
, 0, BFD_RELOC_CKCORE_PLT_IMM18BY4
);
7208 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
7209 4, &csky_insn
.e1
, 1, BFD_RELOC_CKCORE_DOFFSET_IMM18BY4
);
7212 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
7220 || IS_CSKY_ARCH_801 (mach_flag
)
7221 || IS_CSKY_ARCH_802 (mach_flag
))
7223 csky_insn
.output
= frag_more (4);
7224 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
7225 4, &csky_insn
.e1
, 1, BFD_RELOC_CKCORE_PCREL_IMM26BY2
);
7226 csky_insn
.isize
= 4;
7227 csky_insn
.inst
= CSKYV2_INST_BSR32
;
7231 struct literal
*p
= enter_literal (&csky_insn
.e1
, 0, 0, 0);
7232 csky_insn
.output
= frag_more (4);
7233 csky_insn
.e1
.X_op
= O_symbol
;
7234 csky_insn
.e1
.X_add_symbol
= poolsym
;
7235 csky_insn
.e1
.X_add_number
= p
->offset
<< 2;
7236 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
7237 4, &csky_insn
.e1
, 1, BFD_RELOC_CKCORE_PCREL_IMM16BY4
);
7238 if (do_jsri2bsr
|| IS_CSKY_ARCH_810 (mach_flag
))
7239 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
7241 &(litpool
+ (csky_insn
.e1
.X_add_number
>> 2))->e
,
7243 BFD_RELOC_CKCORE_PCREL_JSR_IMM26BY2
);
7244 csky_insn
.inst
= CSKYV2_INST_JSRI32
;
7245 csky_insn
.isize
= 4;
7246 if (IS_CSKY_ARCH_810 (mach_flag
))
7248 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
7249 csky_insn
.output
= frag_more (4);
7250 dwarf2_emit_insn (0);
7251 /* Insert "mov r0, r0". */
7252 csky_insn
.inst
= CSKYV2_INST_MOV_R0_R0
;
7256 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
7265 struct literal
*p
= enter_literal (&csky_insn
.e1
, 1, 0, 0);
7266 csky_insn
.e1
.X_op
= O_symbol
;
7267 csky_insn
.e1
.X_add_symbol
= poolsym
;
7268 csky_insn
.e1
.X_add_number
= p
->offset
<< 2;
7270 /* Generate relax or reloc if necessary. */
7271 csky_generate_frags ();
7272 /* Generate the insn by mask. */
7273 csky_generate_insn ();
7274 /* Write inst to frag. */
7275 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
7276 /* Control 810 not to generate jsri. */
7277 if (IS_CSKY_ARCH_810 (mach_flag
))
7279 /* Look at adding the R_PCREL_JSRIMM26BY2.
7280 For 'jbsr .L1', this reloc type's symbol
7281 is bound to '.L1', isn't bound to literal pool. */
7282 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
7284 BFD_RELOC_CKCORE_PCREL_JSR_IMM26BY2
);
7285 csky_insn
.output
= frag_more (4);
7286 dwarf2_emit_insn (0);
7287 /* The opcode of "mov32 r0,r0". */
7288 csky_insn
.inst
= CSKYV2_INST_MOV_R0_R0
;
7289 /* The effect of this value is to check literal. */
7290 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
7297 v2_work_movih (void)
7299 int rz
= csky_insn
.val
[0];
7300 csky_insn
.output
= frag_more (4);
7301 csky_insn
.inst
= csky_insn
.opcode
->op32
[0].opcode
| (rz
<< 16);
7302 if (csky_insn
.e1
.X_op
== O_constant
)
7304 if (csky_insn
.e1
.X_unsigned
== 1 && csky_insn
.e1
.X_add_number
> 0xffff)
7306 csky_show_error (ERROR_IMM_OVERFLOW
, 2, NULL
, NULL
);
7309 else if (csky_insn
.e1
.X_unsigned
== 0 && csky_insn
.e1
.X_add_number
< 0)
7311 csky_show_error (ERROR_IMM_OVERFLOW
, 2, NULL
, NULL
);
7315 csky_insn
.inst
|= (csky_insn
.e1
.X_add_number
& 0xffff);
7317 else if (csky_insn
.e1
.X_op
== O_right_shift
7318 || (csky_insn
.e1
.X_op
== O_symbol
&& insn_reloc
!= BFD_RELOC_NONE
))
7320 if (csky_insn
.e1
.X_op_symbol
!= 0
7321 && symbol_constant_p (csky_insn
.e1
.X_op_symbol
)
7322 && S_GET_SEGMENT (csky_insn
.e1
.X_op_symbol
) == absolute_section
7323 && 16 == S_GET_VALUE (csky_insn
.e1
.X_op_symbol
))
7325 csky_insn
.e1
.X_op
= O_symbol
;
7326 if (insn_reloc
== BFD_RELOC_CKCORE_GOT32
)
7327 insn_reloc
= BFD_RELOC_CKCORE_GOT_HI16
;
7328 else if (insn_reloc
== BFD_RELOC_CKCORE_PLT32
)
7329 insn_reloc
= BFD_RELOC_CKCORE_PLT_HI16
;
7330 else if (insn_reloc
== BFD_RELOC_CKCORE_GOTPC
)
7331 insn_reloc
= BFD_RELOC_CKCORE_GOTPC_HI16
;
7332 else if (insn_reloc
== BFD_RELOC_CKCORE_GOTOFF
)
7333 insn_reloc
= BFD_RELOC_CKCORE_GOTOFF_HI16
;
7335 insn_reloc
= BFD_RELOC_CKCORE_ADDR_HI16
;
7336 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
7337 4, &csky_insn
.e1
, 0, insn_reloc
);
7341 void *arg
= (void *)"the second operand must be \"SYMBOL >> 16\"";
7342 csky_show_error (ERROR_UNDEFINE
, 0, arg
, NULL
);
7346 csky_insn
.isize
= 4;
7347 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
7355 int rz
= csky_insn
.val
[0];
7356 int rx
= csky_insn
.val
[1];
7357 csky_insn
.output
= frag_more (4);
7358 csky_insn
.inst
= csky_insn
.opcode
->op32
[0].opcode
| (rz
<< 21) | (rx
<< 16);
7359 if (csky_insn
.e1
.X_op
== O_constant
)
7361 if (csky_insn
.e1
.X_add_number
<= 0xffff
7362 && csky_insn
.e1
.X_add_number
>= 0)
7363 csky_insn
.inst
|= csky_insn
.e1
.X_add_number
;
7366 csky_show_error (ERROR_IMM_OVERFLOW
, 3, NULL
, NULL
);
7370 else if (csky_insn
.e1
.X_op
== O_bit_and
)
7372 if (symbol_constant_p (csky_insn
.e1
.X_op_symbol
)
7373 && S_GET_SEGMENT (csky_insn
.e1
.X_op_symbol
) == absolute_section
7374 && 0xffff == S_GET_VALUE (csky_insn
.e1
.X_op_symbol
))
7376 csky_insn
.e1
.X_op
= O_symbol
;
7377 if (insn_reloc
== BFD_RELOC_CKCORE_GOT32
)
7378 insn_reloc
= BFD_RELOC_CKCORE_GOT_LO16
;
7379 else if (insn_reloc
== BFD_RELOC_CKCORE_PLT32
)
7380 insn_reloc
= BFD_RELOC_CKCORE_PLT_LO16
;
7381 else if (insn_reloc
== BFD_RELOC_CKCORE_GOTPC
)
7382 insn_reloc
= BFD_RELOC_CKCORE_GOTPC_LO16
;
7383 else if (insn_reloc
== BFD_RELOC_CKCORE_GOTOFF
)
7384 insn_reloc
= BFD_RELOC_CKCORE_GOTOFF_LO16
;
7386 insn_reloc
= BFD_RELOC_CKCORE_ADDR_LO16
;
7387 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
7388 4, &csky_insn
.e1
, 0, insn_reloc
);
7392 void *arg
= (void *)"the third operand must be \"SYMBOL & 0xffff\"";
7393 csky_show_error (ERROR_UNDEFINE
, 0, arg
, NULL
);
7397 csky_insn
.isize
= 4;
7398 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
7402 /* Helper function to encode a single/double floating point constant
7403 into the instruction word for fmovis and fmovid instructions.
7404 The constant is in its IEEE single/double precision representation
7405 and is repacked into the internal 13-bit representation for these
7406 instructions with a diagnostic for overflow. Note that there is no
7407 rounding when converting to the smaller format, just an error if there
7408 is excess precision or the number is too small/large to be represented. */
7411 float_work_fmovi (void)
7413 int rx
= csky_insn
.val
[0];
7415 /* We already converted the float constant to the internal 13-bit
7416 representation so we just need to OR it in here. */
7417 csky_insn
.inst
= csky_insn
.opcode
->op32
[0].opcode
| rx
;
7418 csky_insn
.inst
|= (uint32_t) csky_insn
.e1
.X_add_number
;
7420 csky_insn
.output
= frag_more (4);
7421 csky_insn
.isize
= 4;
7422 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
7426 /* Like float_work_fmovi, but for FPUV3 fmovi.16, fmovi.32 and fmovi.64
7430 float_work_fpuv3_fmovi (void)
7432 int rx
= csky_insn
.val
[0];
7433 int idx
= csky_insn
.opcode_idx
;
7438 csky_insn
.inst
= csky_insn
.opcode
->op32
[idx
].opcode
| rx
;
7440 if (csky_insn
.opcode
->op32
[idx
].operand_num
== 3)
7442 /* fmovi.xx frz, imm9, imm4. */
7443 imm8
= csky_insn
.val
[1];
7444 imm4
= csky_insn
.val
[2];
7445 if (imm8
< 0 || (imm8
& 0x80000000))
7453 csky_show_error (ERROR_IMM_OVERFLOW
, 2, NULL
, NULL
);
7457 /* imm8 store at bit [25:20] and [9:8]. */
7458 /* imm4 store at bit [19:16]. */
7459 /* sign store at bit [5]. */
7460 csky_insn
.inst
= csky_insn
.inst
7461 | ((imm8
& 0x3) << 8)
7462 | ((imm8
& 0xfc) << 18)
7463 | ((imm4
& 0xf) << 16)
7468 csky_insn
.inst
|= (uint32_t) csky_insn
.e1
.X_add_number
;
7471 csky_insn
.output
= frag_more(4);
7472 csky_insn
.isize
= 4;
7473 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
7478 dsp_work_bloop (void)
7480 int reg
= csky_insn
.val
[0];
7481 csky_insn
.output
= frag_more (4);
7482 csky_insn
.inst
= csky_insn
.opcode
->op32
[0].opcode
| (reg
<< 16);
7483 csky_insn
.isize
= 4;
7485 if (csky_insn
.number
== 3
7486 && csky_insn
.e1
.X_op
== O_symbol
7487 && csky_insn
.e2
.X_op
== O_symbol
)
7489 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
7490 4, &csky_insn
.e1
, 1,
7491 BFD_RELOC_CKCORE_PCREL_BLOOP_IMM12BY4
);
7492 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
7493 4, &csky_insn
.e2
, 1,
7494 BFD_RELOC_CKCORE_PCREL_BLOOP_IMM4BY4
);
7496 else if (csky_insn
.number
== 2
7497 && csky_insn
.e1
.X_op
== O_symbol
)
7499 fix_new_exp (frag_now
, csky_insn
.output
-frag_now
->fr_literal
,
7500 4, &csky_insn
.e1
, 1,
7501 BFD_RELOC_CKCORE_PCREL_BLOOP_IMM12BY4
);
7502 if (csky_insn
.last_isize
== 2)
7503 csky_insn
.inst
|= (0xf << 12);
7504 else if (csky_insn
.last_isize
!= 0)
7505 csky_insn
.inst
|= (0xe << 12);
7508 void *arg
= (void *)"bloop can not be the first instruction"\
7509 "when the end label is not specified.\n";
7510 csky_show_error (ERROR_UNDEFINE
, 0, arg
, NULL
);
7514 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
7519 float_work_fpuv3_fstore(void)
7521 /* Generate relax or reloc if necessary. */
7522 csky_generate_frags ();
7523 /* Generate the insn by mask. */
7524 csky_generate_insn ();
7525 /* Write inst to frag. */
7526 csky_write_insn (csky_insn
.output
,
7542 reg1
= csky_insn
.val
[0];
7543 reg2
= csky_insn
.val
[1];
7544 if (csky_insn
.number
== 2)
7546 if (reg1
> 15 || reg2
> 15)
7556 reg3
= csky_insn
.val
[2];
7557 if (reg1
> 15 || reg2
> 15 || reg3
> 15)
7559 else if (reg1
== reg2
|| reg1
== reg3
)
7562 reg2
= (reg1
== reg2
) ? reg3
: reg2
;
7569 && csky_insn
.flag_force
!= INSN_OPCODE32F
)
7571 csky_insn
.isize
= 2;
7572 csky_insn
.inst
= csky_insn
.opcode
->op16
[0].opcode
7573 | (reg1
<< 6) | (reg2
<< 2);
7575 else if (csky_insn
.flag_force
!= INSN_OPCODE16F
)
7577 csky_insn
.isize
= 4;
7578 csky_insn
.inst
= csky_insn
.opcode
->op32
[0].opcode
7579 | (reg1
<< 0) | (reg2
<< 16) | (reg3
<< 21);
7583 SET_ERROR_INTEGER (ERROR_REG_OVER_RANGE
, reg1
> 15 ? reg1
: reg2
);
7584 csky_show_error (ERROR_REG_OVER_RANGE
, 0, 0, NULL
);
7587 /* Generate relax or reloc if necessary. */
7588 csky_generate_frags ();
7589 /* Write inst to frag. */
7590 csky_write_insn (csky_insn
.output
,
7597 /* The following are for assembler directive handling. */
7599 /* Helper function to adjust constant pool counts when we emit a
7600 data directive in the text section. FUNC is one of the standard
7601 gas functions to handle these directives, like "stringer" for the
7602 .string directive, and ARG is the argument to FUNC. csky_pool_count
7603 essentially wraps the call with the constant pool magic. */
7606 csky_pool_count (void (*func
) (int), int arg
)
7608 const fragS
*curr_frag
= frag_now
;
7609 offsetT added
= -frag_now_fix_octets ();
7613 while (curr_frag
!= frag_now
)
7615 added
+= curr_frag
->fr_fix
;
7616 curr_frag
= curr_frag
->fr_next
;
7619 added
+= frag_now_fix_octets ();
7623 /* Support the .literals directive. */
7625 csky_s_literals (int ignore ATTRIBUTE_UNUSED
)
7628 demand_empty_rest_of_line ();
7631 /* Support the .string, etc directives. */
7633 csky_stringer (int append_zero
)
7635 if (now_seg
== text_section
)
7636 csky_pool_count (stringer
, append_zero
);
7638 stringer (append_zero
);
7640 /* We call check_literals here in case a large number of strings are
7641 being placed into the text section with a sequence of stringer
7642 directives. In theory we could be upsetting something if these
7643 strings are actually in an indexed table instead of referenced by
7644 individual labels. Let us hope that that never happens. */
7645 check_literals (2, 0);
7648 /* Support integer-mode constructors like .word, .byte, etc. */
7651 csky_cons (int nbytes
)
7653 mapping_state (MAP_DATA
);
7654 if (nbytes
== 4) /* @GOT. */
7658 bfd_reloc_code_real_type reloc
;
7661 reloc
= BFD_RELOC_NONE
;
7663 lex_got (&reloc
, NULL
);
7665 if (exp
.X_op
== O_symbol
&& reloc
!= BFD_RELOC_NONE
)
7667 reloc_howto_type
*howto
7668 = bfd_reloc_type_lookup (stdoutput
, reloc
);
7669 int size
= bfd_get_reloc_size (howto
);
7672 as_bad (ngettext ("%s relocations do not fit in %d byte",
7673 "%s relocations do not fit in %d bytes",
7675 howto
->name
, nbytes
);
7678 register char *p
= frag_more ((int) nbytes
);
7679 int offset
= nbytes
- size
;
7681 fix_new_exp (frag_now
,
7682 p
- frag_now
->fr_literal
+ offset
,
7683 size
, &exp
, 0, reloc
);
7687 emit_expr (&exp
, (unsigned int) nbytes
);
7688 if (now_seg
== text_section
)
7691 while (*input_line_pointer
++ == ',');
7693 /* Put terminator back into stream. */
7694 input_line_pointer
--;
7695 demand_empty_rest_of_line ();
7700 if (now_seg
== text_section
)
7701 csky_pool_count (cons
, nbytes
);
7705 /* In theory we ought to call check_literals (2,0) here in case
7706 we need to dump the literal table. We cannot do this however,
7707 as the directives that we are intercepting may be being used
7708 to build a switch table, and we must not interfere with its
7709 contents. Instead we cross our fingers and pray... */
7712 /* Support floating-mode constant directives like .float and .double. */
7715 csky_float_cons (int float_type
)
7717 mapping_state (MAP_DATA
);
7718 if (now_seg
== text_section
)
7719 csky_pool_count (float_cons
, float_type
);
7721 float_cons (float_type
);
7723 /* See the comment in csky_cons () about calling check_literals.
7724 It is unlikely that a switch table will be constructed using
7725 floating point values, but it is still likely that an indexed
7726 table of floating point constants is being created by these
7727 directives, so again we must not interfere with their placement. */
7730 /* Support the .fill directive. */
7733 csky_fill (int ignore
)
7735 if (now_seg
== text_section
)
7736 csky_pool_count (s_fill
, ignore
);
7740 check_literals (2, 0);
7743 /* Handle the section changing pseudo-ops. These call through to the
7744 normal implementations, but they dump the literal pool first. */
7747 csky_s_text (int ignore
)
7752 obj_elf_text (ignore
);
7759 csky_s_data (int ignore
)
7764 obj_elf_data (ignore
);
7771 csky_s_section (int ignore
)
7773 /* Scan forwards to find the name of the section. If the section
7774 being switched to is ".line" then this is a DWARF1 debug section
7775 which is arbitrarily placed inside generated code. In this case
7776 do not dump the literal pool because it is a) inefficient and
7777 b) would require the generation of extra code to jump around the
7779 char * ilp
= input_line_pointer
;
7781 while (*ilp
!= 0 && ISSPACE (*ilp
))
7784 if (startswith (ilp
, ".line")
7785 && (ISSPACE (ilp
[5]) || *ilp
== '\n' || *ilp
== '\r'))
7791 obj_elf_section (ignore
);
7794 obj_coff_section (ignore
);
7799 csky_s_bss (int needs_align
)
7802 s_lcomm_bytes (needs_align
);
7807 csky_s_comm (int needs_align
)
7810 obj_elf_common (needs_align
);
7814 /* Handle the .no_literal_dump directive. */
7817 csky_noliteraldump (int ignore ATTRIBUTE_UNUSED
)
7819 do_noliteraldump
= 1;
7820 int insn_num
= get_absolute_expression ();
7821 /* The insn after '.no_literal_dump insn_num' is insn1,
7822 Don't dump literal pool between insn1 and insn(insn_num+1)
7823 The insn cannot be the insn generate literal, like lrw & jsri. */
7824 check_literals (0, insn_num
* 2);
7827 /* Handle the .align directive.
7828 We must check literals before doing alignment. For example, if
7829 '.align n', add (2^n-1) to poolspan and check literals. */
7832 csky_s_align_ptwo (int arg
)
7834 /* Get the .align's first absolute number. */
7835 char * temp_pointer
= input_line_pointer
;
7836 int align
= get_absolute_expression ();
7837 check_literals (0, (1 << align
) - 1);
7838 input_line_pointer
= temp_pointer
;
7844 /* Handle the .stack_size directive. */
7847 csky_stack_size (int arg ATTRIBUTE_UNUSED
)
7850 stack_size_entry
*sse
7851 = (stack_size_entry
*) xcalloc (1, sizeof (stack_size_entry
));
7854 if (exp
.X_op
== O_symbol
)
7855 sse
->function
= exp
.X_add_symbol
;
7858 as_bad (_("the first operand must be a symbol"));
7859 ignore_rest_of_line ();
7865 if (*input_line_pointer
!= ',')
7867 as_bad (_("missing stack size"));
7868 ignore_rest_of_line ();
7873 ++input_line_pointer
;
7875 if (exp
.X_op
== O_constant
)
7877 if (exp
.X_add_number
< 0 || exp
.X_add_number
> (offsetT
)0xffffffff)
7880 as_bad (_("value not in range [0, 0xffffffff]"));
7881 ignore_rest_of_line ();
7886 sse
->stack_size
= exp
.X_add_number
;
7890 as_bad (_("operand must be a constant"));
7891 ignore_rest_of_line ();
7896 if (*last_stack_size_data
!= NULL
)
7897 last_stack_size_data
= &((*last_stack_size_data
)->next
);
7899 *last_stack_size_data
= sse
;
7902 /* This table describes all the machine specific pseudo-ops the assembler
7903 has to support. The fields are:
7904 pseudo-op name without dot
7905 function to call to execute this pseudo-op
7906 Integer arg to pass to the function. */
7908 const pseudo_typeS md_pseudo_table
[] =
7910 { "export", s_globl
, 0 },
7911 { "import", s_ignore
, 0 },
7912 { "literals", csky_s_literals
, 0 },
7913 { "page", listing_eject
, 0 },
7915 /* The following are to intercept the placement of data into the text
7916 section (eg addresses for a switch table), so that the space they
7917 occupy can be taken into account when deciding whether or not to
7918 dump the current literal pool.
7919 XXX - currently we do not cope with the .space and .dcb.d directives. */
7920 { "ascii", csky_stringer
, 8 + 0 },
7921 { "asciz", csky_stringer
, 8 + 1 },
7922 { "byte", csky_cons
, 1 },
7923 { "dc", csky_cons
, 2 },
7924 { "dc.b", csky_cons
, 1 },
7925 { "dc.d", csky_float_cons
, 'd'},
7926 { "dc.l", csky_cons
, 4 },
7927 { "dc.s", csky_float_cons
, 'f'},
7928 { "dc.w", csky_cons
, 2 },
7929 { "dc.x", csky_float_cons
, 'x'},
7930 { "double", csky_float_cons
, 'd'},
7931 { "float", csky_float_cons
, 'f'},
7932 { "hword", csky_cons
, 2 },
7933 { "int", csky_cons
, 4 },
7934 { "long", csky_cons
, 4 },
7935 { "octa", csky_cons
, 16 },
7936 { "quad", csky_cons
, 8 },
7937 { "short", csky_cons
, 2 },
7938 { "single", csky_float_cons
, 'f'},
7939 { "string", csky_stringer
, 8 + 1 },
7940 { "word", csky_cons
, 4 },
7941 { "fill", csky_fill
, 0 },
7943 /* Allow for the effect of section changes. */
7944 { "text", csky_s_text
, 0 },
7945 { "data", csky_s_data
, 0 },
7946 { "bss", csky_s_bss
, 1 },
7948 { "comm", csky_s_comm
, 0 },
7950 { "section", csky_s_section
, 0 },
7951 { "section.s", csky_s_section
, 0 },
7952 { "sect", csky_s_section
, 0 },
7953 { "sect.s", csky_s_section
, 0 },
7954 /* When ".no_literal_dump N" is in front of insn1,
7955 and instruction sequence is:
7960 it means literals will not dump between insn1 and insnN+1
7961 The insn cannot itself generate literal, like lrw & jsri. */
7962 { "no_literal_dump", csky_noliteraldump
, 0 },
7963 { "align", csky_s_align_ptwo
, 0 },
7964 { "stack_size", csky_stack_size
, 0 },
7968 /* Implement tc_cfi_frame_initial_instructions. */
7971 csky_cfi_frame_initial_instructions (void)
7973 int sp_reg
= IS_CSKY_V1 (mach_flag
) ? 0 : 14;
7974 cfi_add_CFA_def_cfa_register (sp_reg
);
7977 /* Implement tc_regname_to_dw2regnum. */
7980 tc_csky_regname_to_dw2regnum (char *regname
)
7985 /* FIXME the reg should be parsed according to
7987 reg_num
= csky_get_reg_val (regname
, &len
);