1 /* tc-csky.c -- Assembler for C-SKY
2 Copyright (C) 1989-2018 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"
32 #include "struc-symbol.h"
36 #include "dw2gencfi.h"
39 #include "dwarf2dbg.h"
43 #define OPCODE_MAX_LEN 20
44 #define HAS_SUB_OPERAND 0xfffffffful
46 /* This value is just for lrw to distinguish "[]" label. */
47 #define NEED_OUTPUT_LITERAL 1
49 #define IS_EXTERNAL_SYM(sym, sec) (S_GET_SEGMENT (sym) != sec)
50 #define IS_SUPPORT_OPCODE16(opcode) (opcode->isa_flag16 | isa_flag)
51 #define IS_SUPPORT_OPCODE32(opcode) (opcode->isa_flag32 | isa_flag)
58 /* Define DSP version flags. For different CPU, the version of DSP
59 instructions may be different. */
60 #define CSKY_DSP_FLAG_V1 (1 << 0) /* Normal DSP instructions. */
61 #define CSKY_DSP_FLAG_V2 (1 << 1) /* CK803S enhanced DSP. */
63 /* Literal pool related macros. */
64 /* 1024 - 1 entry - 2 byte rounding. */
65 #define v1_SPANPANIC (998)
66 #define v1_SPANCLOSE (900)
67 #define v1_SPANEXIT (600)
68 #define v2_SPANPANIC (1024 - 4)
70 /* 1024 is flrw offset.
71 24 is the biggest size for single instruction.
72 for lrw16 (3+7, 512 bytes). */
73 #define v2_SPANCLOSE (512 - 24)
75 /* For lrw16, 112 average size for a function. */
76 #define v2_SPANEXIT (512 - 112)
78 /* For lrw16 (3+7, 512 bytes). */
79 #define v2_SPANCLOSE_ELRW (1016 - 24)
81 /* For lrw16, 112 average size for a function. */
82 #define v2_SPANEXIT_ELRW (1016 - 112)
83 #define MAX_POOL_SIZE (1024 / 4)
84 #define POOL_END_LABEL ".LE"
85 #define POOL_START_LABEL ".LS"
87 /* Used in v1_relax_table. */
88 /* These are the two types of relaxable instruction. */
91 #define COND_JUMP_PIC 3
92 #define UNCD_JUMP_PIC 4
97 #define UNDEF_WORD_DISP 3
100 /* Allow for align: bt/jmpi/.long + align. */
102 /* Allow for align: bt/subi/stw/bsr/lrw/add/ld/addi/jmp/.long + align. */
103 #define C32_LEN_PIC 24
105 /* Allow for align: jmpi/.long + align. */
107 /* Allow for align: subi/stw/bsr/lrw/add/ld/addi/jmp/.long + align. */
108 #define U32_LEN_PIC 22
110 #define C(what,length) (((what) << 2) + (length))
111 #define UNCD_JUMP_S (do_pic ? UNCD_JUMP_PIC : UNCD_JUMP)
112 #define COND_JUMP_S (do_pic ? COND_JUMP_PIC : COND_JUMP)
113 #define U32_LEN_S (do_pic ? U32_LEN_PIC : U32_LEN)
114 #define C32_LEN_S (do_pic ? C32_LEN_PIC : C32_LEN)
116 /* Used in v2_relax_table. */
117 #define COND_DISP10_LEN 2 /* bt/bf_16. */
118 #define COND_DISP16_LEN 4 /* bt/bf_32. */
120 #define SCOND_DISP10_LEN 2 /* bt/bf_16, for CK801 only. */
121 #define SCOND_DISP16_LEN 6 /* !(bt/bf_16) + br_32. */
123 #define UNCD_DISP10_LEN 2 /* br_16. */
124 #define UNCD_DISP16_LEN 4 /* br_32. */
125 #define UNCD_DISP26_LEN 4 /* br32_old. */
127 #define JCOND_DISP10_LEN 2 /* bt/bf_16. */
128 #define JCOND_DISP16_LEN 4 /* bt/bf_32. */
129 #define JCOND_DISP32_LEN 12 /* !(bt/bf_16)/jmpi 32/.align 2/literal 4. */
130 #define JCOND_DISP26_LEN 8 /* bt/bf_32/br_32 old. */
132 #define JUNCD_DISP26_LEN 4 /* bt/bf_32 old. */
133 #define JUNCD_DISP10_LEN 2 /* br_16. */
134 #define JUNCD_DISP16_LEN 4 /* bt/bf_32. */
135 #define JUNCD_DISP32_LEN 10 /* jmpi_32/.align 2/literal 4/ CHANGED!. */
136 #define JCOMP_DISP26_LEN 8 /* bne_32/br_32 old. */
138 #define JCOMP_DISP16_LEN 4 /* bne_32 old. */
139 #define JCOMPZ_DISP16_LEN 4 /* bhlz_32. */
140 #define JCOMPZ_DISP32_LEN 14 /* bsz_32/jmpi 32/.align 2/literal 4. */
141 #define JCOMPZ_DISP26_LEN 8 /* bsz_32/br_32 old. */
142 #define JCOMP_DISP32_LEN 14 /* be_32/jmpi_32/.align 2/literal old. */
144 #define BSR_DISP10_LEN 2 /* bsr_16. */
145 #define BSR_DISP26_LEN 4 /* bsr_32. */
146 #define LRW_DISP7_LEN 2 /* lrw16. */
147 #define LRW_DISP16_LEN 4 /* lrw32. */
149 /* Declare worker functions. */
150 bfd_boolean
v1_work_lrw (void);
151 bfd_boolean
v1_work_jbsr (void);
152 bfd_boolean
v1_work_fpu_fo (void);
153 bfd_boolean
v1_work_fpu_fo_fc (void);
154 bfd_boolean
v1_work_fpu_write (void);
155 bfd_boolean
v1_work_fpu_read (void);
156 bfd_boolean
v1_work_fpu_writed (void);
157 bfd_boolean
v1_work_fpu_readd (void);
158 bfd_boolean
v2_work_istack (void);
159 bfd_boolean
v2_work_btsti (void);
160 bfd_boolean
v2_work_addi (void);
161 bfd_boolean
v2_work_subi (void);
162 bfd_boolean
v2_work_add_sub (void);
163 bfd_boolean
v2_work_rotlc (void);
164 bfd_boolean
v2_work_bgeni (void);
165 bfd_boolean
v2_work_not (void);
166 bfd_boolean
v2_work_jbtf (void);
167 bfd_boolean
v2_work_jbr (void);
168 bfd_boolean
v2_work_lrw (void);
169 bfd_boolean
v2_work_lrsrsw (void);
170 bfd_boolean
v2_work_jbsr (void);
171 bfd_boolean
v2_work_jsri (void);
172 bfd_boolean
v2_work_movih (void);
173 bfd_boolean
v2_work_ori (void);
174 bfd_boolean
float_work_fmovi (void);
175 bfd_boolean
dsp_work_bloop (void);
177 /* csky-opc.h must be included after workers are declared. */
178 #include "opcodes/csky-opc.h"
179 #include "opcode/csky.h"
186 COND_DISP10
= 20, /* bt/bf_16. */
187 COND_DISP16
, /* bt/bf_32. */
189 SCOND_DISP10
, /* br_16 */
190 SCOND_DISP16
, /* !(bt/bf_32) + br_32. */
192 UNCD_DISP10
, /* br_16. */
193 UNCD_DISP16
, /* br_32. */
195 JCOND_DISP10
, /* bt/bf_16. */
196 JCOND_DISP16
, /* bt/bf_32. */
197 JCOND_DISP32
, /* !(bt/bf_32)/jmpi + literal. */
199 JUNCD_DISP10
, /* br_16. */
200 JUNCD_DISP16
, /* br_32. */
201 JUNCD_DISP32
, /* jmpi + literal. */
203 JCOMPZ_DISP16
, /* bez/bnez/bhz/blsz/blz/bhsz. */
204 JCOMPZ_DISP32
, /* !(jbez/jbnez/jblsz/jblz/jbhsz) + jmpi + literal. */
206 BSR_DISP26
, /* bsr_32. */
208 LRW_DISP7
, /* lrw16. */
209 LRW2_DISP8
, /* lrw16, -mno-bsr16,8 bit offset. */
210 LRW_DISP16
, /* lrw32. */
213 unsigned int mach_flag
= 0;
214 unsigned int arch_flag
= 0;
215 unsigned int other_flag
= 0;
216 unsigned int isa_flag
= 0;
217 unsigned int dsp_flag
= 0;
219 typedef struct stack_size_entry
221 struct stack_size_entry
*next
;
223 unsigned int stack_size
;
226 struct csky_arch_info
229 unsigned int arch_flag
;
230 unsigned int bfd_mach_flag
;
236 unsigned int mach_flag
;
237 unsigned int isa_flag
;
247 /* Macro information. */
248 struct csky_macro_info
251 /* How many operands : if operands == 5, all of 1,2,3,4 are ok. */
255 void (*handle_func
)(void);
258 struct csky_insn_info
260 /* Name of the opcode. */
262 /* Output instruction. */
264 /* Pointer for frag. */
266 /* End of instruction. */
268 /* Flag for INSN_OPCODE16F, INSN_OPCODE32F, INSN_OPCODE, INSN_MACRO. */
269 inst_flag flag_force
;
270 /* Operand number. */
272 struct csky_opcode
*opcode
;
273 struct csky_macro_info
*macro
;
274 /* Insn size for check_literal. */
276 /* Max size of insn for relax frag_var. */
278 /* Indicates which element is in csky_opcode_info op[] array. */
280 /* The value of each operand in instruction when layout. */
282 int val
[MAX_OPRND_NUM
];
289 /* The following are used for constant expressions. */
294 /* Literal pool data structures. */
297 unsigned short refcnt
;
298 unsigned char ispcrel
;
299 unsigned char unused
;
300 bfd_reloc_code_real_type r_type
;
302 struct tls_addend tls_addend
;
303 unsigned char isdouble
;
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
,
331 ERROR_802J_REG_OVER_RANGE
,
335 ERROR_IMM_OVERFLOW
, /* 5 */
337 ERROR_JMPIX_OVER_RANGE
,
343 ERROR_MISSING_OPERAND
, /* 10 */
345 ERROR_MISSING_LBRACKET
,
346 ERROR_MISSING_RBRACKET
,
347 ERROR_MISSING_LSQUARE_BRACKETS
,
348 ERROR_MISSING_RSQUARE_BRACKETS
, /* 15 */
349 ERROR_MISSING_LANGLE_BRACKETS
,
350 ERROR_MISSING_RANGLE_BRACKETS
,
351 ERROR_OFFSET_UNALIGNED
,
354 ERROR_CPREG_ILLEGAL
, /* 20 */
356 ERROR_OPERANDS_ILLEGAL
,
357 ERROR_OPERANDS_NUMBER
,
358 ERROR_OPCODE_ILLEGAL
,
360 /* The following are warnings. */
364 /* Error and warning end. */
368 /* Global error state. ARG1 and ARG2 are opaque data interpreted
369 as appropriate for the error code. */
371 struct csky_error_state
373 enum error_number err_num
;
379 /* This macro is used to set error number and arg1 in the global state. */
381 #define SET_ERROR_NUMBER(err, msg) \
383 if (error_state.err_num > err) \
385 error_state.err_num = err; \
386 error_state.arg1 = (void *)msg; \
391 /* Map error identifiers onto a format string, which will use
392 arg1 and arg2 from the global error state. */
393 struct csky_error_format_map
395 enum error_number num
;
399 static const struct csky_error_format_map err_formats
[] =
401 {ERROR_CREG_ILLEGAL
, "Operand %d error: control register is illegal."},
402 {ERROR_REG_OVER_RANGE
, "Operand %d error: r%d register is over range."},
403 {ERROR_GREG_ILLEGAL
, "Operand %d error: general register is illegal."},
404 {ERROR_802J_REG_OVER_RANGE
, "Operand %d register %s out of range (802j only has registers:0-15,23,24,25,30)"},
405 {ERROR_REG_FORMAT
, "Operand %d error: %s."},
406 {ERROR_REG_LIST
, "Register list format is illegal."},
407 {ERROR_IMM_ILLEGAL
, "Operand %d is not an immediate."},
408 {ERROR_IMM_OVERFLOW
, "Operand %d immediate is overflow."},
409 {ERROR_IMM_POWER
, "immediate %d is not a power of two"},
410 {ERROR_JMPIX_OVER_RANGE
, "The second operand must be 16/24/32/40"},
411 {ERROR_EXP_CREG
, "Operand %d error: control register is expected."},
412 {ERROR_EXP_GREG
, "Operand %d error: general register is expected."},
413 {ERROR_EXP_CONSTANT
, "Operand %d error: constant is expected."},
414 {ERROR_EXP_EVEN_FREG
, "Operand %d error: even float register is expected."},
415 {ERROR_RELOC_ILLEGAL
, "@%s reloc is not supported"},
416 {ERROR_MISSING_OPERAND
, "Operand %d is missing."},
417 {ERROR_MISSING_COMMA
, "Missing ','"},
418 {ERROR_MISSING_LBRACKET
, "Missing '('"},
419 {ERROR_MISSING_RBRACKET
, "Missing ')'"},
420 {ERROR_MISSING_LSQUARE_BRACKETS
, "Missing '['"},
421 {ERROR_MISSING_RSQUARE_BRACKETS
, "Missing ']'"},
422 {ERROR_MISSING_LANGLE_BRACKETS
, "Missing '<'"},
423 {ERROR_MISSING_RANGLE_BRACKETS
, "Missing '>'"},
424 {ERROR_OFFSET_UNALIGNED
, "Operand %d is unaligned. It must be %d aligned!"},
425 {ERROR_BAD_END
, "Operands mismatch, it has a bad end: %s"},
426 {ERROR_UNDEFINE
, NULL
},
427 {ERROR_CPREG_ILLEGAL
, "Operand %d illegal, expect a cpreg(cpr0-cpr63)."},
428 {ERROR_OPCODE_PSRBIT
, "The operands must be 'ie'/'ee'/'fe'."},
429 {ERROR_OPERANDS_ILLEGAL
, "Operands mismatch: %s."},
430 {ERROR_OPERANDS_NUMBER
, "Operands number mismatch, %d operands expected."},
431 {ERROR_OPCODE_ILLEGAL
, "The instruction is not recognized."},
432 {WARNING_OPTIONS
, "Option %s is not support in %s."},
433 {WARNING_IDLY
, "idly %d is encoded to: idly 4 "},
434 {ERROR_NONE
, "There is no error."},
437 static int do_pic
= 0; /* for jbr/jbf/jbt relax jmpi reloc. */
438 static int do_pff
= -1; /* for insert two br ahead of literals. */
439 static int do_force2bsr
= -1; /* for jbsr->bsr. */
440 static int do_jsri2bsr
= 1; /* for jsri->bsr. */
441 static int do_nolrw
= 0; /* lrw to movih & ori, only for V2. */
442 static int do_long_jump
= -1; /* control if jbf,jbt,jbr relax to jmpi. */
443 static int do_extend_lrw
= -1; /* delete bsr16 in both two options,
444 add btesti16, lrw offset +1 in -melrw. */
445 static int do_func_dump
= 0; /* dump literals after every function. */
446 static int do_br_dump
= 1; /* work for -mabr/-mno-abr, control the literals dump. */
447 static int do_intr_stack
= -1; /* control interrupt stack module, 801&802&803
448 default on, 807&810, default off. */
450 #ifdef INCLUDE_BRANCH_STUB
451 static int do_use_branchstub
= -1;
453 static int do_use_branchstub
= 0;
456 /* These are only used for options parsing. Values are bitmasks and are
457 OR'ed into the processor flag bits in md_begin. */
458 static int do_opt_mmp
= 0;
459 static int do_opt_mcp
= 0;
460 static int do_opt_mcache
= 0;
461 static int do_opt_msecurity
= 0;
462 static int do_opt_mhard_float
= 0;
463 static int do_opt_mtrust
= 0;
464 static int do_opt_mdsp
= 0;
465 static int do_opt_medsp
= 0;
466 static int do_opt_mvdsp
= 0;
468 const relax_typeS
*md_relax_table
= NULL
;
469 struct literal
*literal_insn_offset
;
470 static struct literal litpool
[MAX_POOL_SIZE
];
471 static unsigned poolsize
= 0;
472 static unsigned poolnumber
= 0;
473 static unsigned long poolspan
= 0;
474 static unsigned int SPANPANIC
;
475 static unsigned int SPANCLOSE
;
476 static unsigned int SPANEXIT
;
478 static stack_size_entry
*all_stack_size_data
= NULL
;
479 static stack_size_entry
**last_stack_size_data
= &all_stack_size_data
;
481 /* Control by ".no_literal_dump N"
482 * 1 : don't dump literal pool between insn1 and insnN+1
484 static int do_noliteraldump
= 0;
486 /* Label for current pool. */
487 static symbolS
* poolsym
;
488 static char poolname
[8];
490 static bfd_boolean mov_r1_before
;
491 static bfd_boolean mov_r1_after
;
493 const relax_typeS csky_relax_table
[] =
495 /* C-SKY V1 relax table. */
496 {0, 0, 0, 0}, /* RELAX_NONE */
497 {0, 0, 0, 0}, /* RELAX_OVERFLOW */
502 { 0, 0, 0, 0 }, /* UNDEF_DISP */
503 { 2048, -2046, C12_LEN
, C (COND_JUMP
, DISP32
) }, /* DISP12 */
504 { 0, 0, C32_LEN
, 0 }, /* DISP32 */
505 { 0, 0, C32_LEN
, 0 }, /* UNDEF_WORD_DISP */
508 { 0, 0, 0, 0 }, /* UNDEF_DISP */
509 { 2048, -2046, U12_LEN
, C (UNCD_JUMP
, DISP32
) }, /* DISP12 */
510 { 0, 0, U32_LEN
, 0 }, /* DISP32 */
511 { 0, 0, U32_LEN
, 0 }, /* UNDEF_WORD_DISP */
514 { 0, 0, 0, 0 }, /* UNDEF_DISP */
515 { 2048, -2046, C12_LEN
, C (COND_JUMP_PIC
, DISP32
) }, /* DISP12 */
516 { 0, 0, C32_LEN_PIC
, 0 }, /* DISP32 */
517 { 0, 0, C32_LEN_PIC
, 0 }, /* UNDEF_WORD_DISP */
520 { 0, 0, 0, 0 }, /* UNDEF_DISP */
521 { 2048, -2046, U12_LEN
, C (UNCD_JUMP_PIC
, DISP32
) }, /* DISP12 */
522 { 0, 0, U32_LEN_PIC
, 0 }, /* DISP32 */
523 { 0, 0, U32_LEN_PIC
, 0 }, /* UNDEF_WORD_DISP */
525 /* C-SKY V2 relax table. */
526 /* forward backward length more */
527 { 1 KB
- 2, -1 KB
, COND_DISP10_LEN
, COND_DISP16
}, /* COND_DISP10 */
528 { 64 KB
- 2, -64 KB
, COND_DISP16_LEN
, RELAX_OVERFLOW
}, /* COND_DISP16 */
530 { 1 KB
- 2, -1 KB
, SCOND_DISP10_LEN
, SCOND_DISP16
}, /* SCOND_DISP10 */
531 { 64 KB
- 2, -64 KB
, SCOND_DISP16_LEN
, RELAX_OVERFLOW
}, /* SCOND_DISP16 */
533 { 1 KB
- 2, -1 KB
, UNCD_DISP10_LEN
, UNCD_DISP16
}, /* UNCD_DISP10 */
534 { 64 KB
- 2, -64 KB
, UNCD_DISP16_LEN
, RELAX_OVERFLOW
}, /* UNCD_DISP16 */
536 { 1 KB
- 2, -1 KB
, JCOND_DISP10_LEN
, JCOND_DISP16
}, /* JCOND_DISP10 */
537 { 64 KB
- 2, -64 KB
, JCOND_DISP16_LEN
, JCOND_DISP32
}, /* JCOND_DISP16 */
538 { 0, 0, JCOND_DISP32_LEN
, RELAX_NONE
}, /* JCOND_DISP32 */
540 { 1 KB
- 2, -1 KB
, JUNCD_DISP10_LEN
, JUNCD_DISP16
}, /* JUNCD_DISP10 */
541 { 64 KB
- 2, -64 KB
, JUNCD_DISP16_LEN
, JUNCD_DISP32
}, /* JUNCD_DISP16 */
542 { 0, 0, JUNCD_DISP32_LEN
, RELAX_NONE
}, /* JUNCD_DISP32 */
544 { 64 KB
- 2, -64 KB
, JCOMPZ_DISP16_LEN
, JCOMPZ_DISP32
}, /* JCOMPZ_DISP16 */
545 { 0, 0, JCOMPZ_DISP32_LEN
, RELAX_NONE
}, /* JCOMPZ_DISP32 */
547 { 64 MB
- 2, -64 MB
, BSR_DISP26_LEN
, RELAX_OVERFLOW
}, /* BSR_DISP26 */
549 { 508, 0, LRW_DISP7_LEN
, LRW_DISP16
}, /* LRW_DISP7 */
550 { 1016, 0, LRW_DISP7_LEN
, LRW_DISP16
}, /* LRW2_DISP8 */
551 { 64 KB
, 0, LRW_DISP16_LEN
, RELAX_OVERFLOW
}, /* LRW_DISP16 */
555 static void csky_write_insn (char *ptr
, valueT use
, int nbytes
);
556 void md_number_to_chars (char * buf
, valueT val
, int n
);
557 long md_pcrel_from_section (fixS
* fixP
, segT seg
);
559 /* C-SKY architecture table. */
560 const struct csky_arch_info csky_archs
[] =
562 {"ck510", CSKY_ARCH_510
, bfd_mach_ck510
},
563 {"ck610", CSKY_ARCH_610
, bfd_mach_ck610
},
564 {"ck801", CSKY_ARCH_801
, bfd_mach_ck801
},
565 {"ck802", CSKY_ARCH_802
, bfd_mach_ck802
},
566 {"ck803", CSKY_ARCH_803
, bfd_mach_ck803
},
567 #define CSKY_ARCH_807_BASE CSKY_ARCH_807 | CSKY_ARCH_DSP
568 #define CSKY_ARCH_810_BASE CSKY_ARCH_810 | CSKY_ARCH_DSP
569 {"ck807", CSKY_ARCH_807_BASE
, bfd_mach_ck807
},
570 {"ck810", CSKY_ARCH_810_BASE
, bfd_mach_ck810
},
574 /* C-SKY cpus table. */
575 const struct csky_cpu_info csky_cpus
[] =
578 #define CSKYV1_ISA_DSP CSKY_ISA_DSP | CSKY_ISA_MAC_DSP
579 {"ck510", CSKY_ARCH_510
, CSKYV1_ISA_E1
},
580 {"ck510e", CSKY_ARCH_510
| CSKY_ARCH_DSP
, CSKYV1_ISA_E1
| CSKYV1_ISA_DSP
},
581 {"ck520", CSKY_ARCH_510
| CSKY_ARCH_MAC
, CSKYV1_ISA_E1
| CSKY_ISA_MAC
| CSKY_ISA_MAC_DSP
},
583 #define CSKY_ISA_610 CSKYV1_ISA_E1 | CSKY_ISA_CP
585 {"ck610", CSKY_ARCH_610
, CSKY_ISA_610
},
586 {"ck610e", CSKY_ARCH_610
| CSKY_ARCH_DSP
, CSKY_ISA_610
| CSKYV1_ISA_DSP
},
587 {"ck610f", CSKY_ARCH_610
| CSKY_ARCH_FLOAT
, CSKY_ISA_610
| CSKY_ISA_FLOAT_E1
},
588 {"ck610ef", CSKY_ARCH_610
| CSKY_ARCH_FLOAT
| CSKY_ARCH_DSP
, CSKY_ISA_610
| CSKY_ISA_FLOAT_E1
| CSKYV1_ISA_DSP
},
589 {"ck610fe", CSKY_ARCH_610
| CSKY_ARCH_FLOAT
| CSKY_ARCH_DSP
, CSKY_ISA_610
| CSKY_ISA_FLOAT_E1
| CSKYV1_ISA_DSP
},
590 {"ck620", CSKY_ARCH_610
| CSKY_ARCH_MAC
, CSKY_ISA_610
| CSKY_ISA_MAC
| CSKY_ISA_MAC_DSP
},
593 #define CSKY_ISA_801 CSKYV2_ISA_E1
594 #define CSKYV2_ISA_DSP (CSKY_ISA_DSP | CSKY_ISA_DSP_1E2)
595 {"ck801", CSKY_ARCH_801
, CSKY_ISA_801
},
596 {"ck801t", CSKY_ARCH_801
, CSKY_ISA_801
| CSKY_ISA_TRUST
},
599 #define CSKY_ISA_802 (CSKY_ISA_801 | CSKYV2_ISA_1E2 | CSKY_ISA_NVIC)
600 {"ck802", CSKY_ARCH_802
, CSKY_ISA_802
},
601 {"ck802j", CSKY_ARCH_802
| CSKY_ARCH_JAVA
, CSKY_ISA_802
| CSKY_ISA_JAVA
},
602 {"ck802t", CSKY_ARCH_802
, CSKY_ISA_802
| CSKY_ISA_TRUST
},
605 #define CSKY_ISA_803 (CSKY_ISA_802 | CSKYV2_ISA_2E3 | CSKY_ISA_MP)
606 #define CSKY_ISA_803R1 (CSKY_ISA_803 | CSKYV2_ISA_3E3R1)
607 #define CSKY_ISA_FLOAT_803 (CSKY_ISA_FLOAT_E1 | CSKY_ISA_FLOAT_1E3)
608 {"ck803", CSKY_ARCH_803
, CSKY_ISA_803
},
609 {"ck803h", CSKY_ARCH_803
, CSKY_ISA_803
},
610 {"ck803t", CSKY_ARCH_803
, CSKY_ISA_803
| CSKY_ISA_TRUST
},
611 {"ck803ht", CSKY_ARCH_803
, CSKY_ISA_803
| CSKY_ISA_TRUST
},
612 {"ck803f", CSKY_ARCH_803
| CSKY_ARCH_FLOAT
, CSKY_ISA_803
| CSKY_ISA_FLOAT_803
},
613 {"ck803fh", CSKY_ARCH_803
| CSKY_ARCH_FLOAT
, CSKY_ISA_803
| CSKY_ISA_FLOAT_803
},
614 {"ck803e", CSKY_ARCH_803
| CSKY_ARCH_DSP
, CSKY_ISA_803
| CSKYV2_ISA_DSP
},
615 {"ck803eh", CSKY_ARCH_803
| CSKY_ARCH_DSP
, CSKY_ISA_803
| CSKYV2_ISA_DSP
},
616 {"ck803et", CSKY_ARCH_803
| CSKY_ARCH_DSP
, CSKY_ISA_803
| CSKYV2_ISA_DSP
| CSKY_ISA_TRUST
},
617 {"ck803eht", CSKY_ARCH_803
| CSKY_ARCH_DSP
, CSKY_ISA_803
| CSKYV2_ISA_DSP
| CSKY_ISA_TRUST
},
618 {"ck803ef", CSKY_ARCH_803
| CSKY_ARCH_DSP
| CSKY_ARCH_FLOAT
, CSKY_ISA_803
| CSKYV2_ISA_DSP
| CSKY_ISA_FLOAT_803
},
619 {"ck803efh", CSKY_ARCH_803
| CSKY_ARCH_DSP
| CSKY_ARCH_FLOAT
, CSKY_ISA_803
| CSKYV2_ISA_DSP
| CSKY_ISA_FLOAT_803
},
620 {"ck803ft", CSKY_ARCH_803
| CSKY_ARCH_FLOAT
, CSKY_ISA_803
| CSKY_ISA_FLOAT_803
| CSKY_ISA_TRUST
},
621 {"ck803eft", CSKY_ARCH_803
| CSKY_ARCH_DSP
| CSKY_ARCH_FLOAT
, CSKY_ISA_803
| CSKYV2_ISA_DSP
| CSKY_ISA_FLOAT_803
| CSKY_ISA_TRUST
},
622 {"ck803efht", CSKY_ARCH_803
| CSKY_ARCH_DSP
| CSKY_ARCH_FLOAT
, CSKY_ISA_803
| CSKYV2_ISA_DSP
| CSKY_ISA_FLOAT_803
| CSKY_ISA_TRUST
},
623 {"ck803r1", CSKY_ARCH_803
, CSKY_ISA_803R1
},
624 {"ck803hr1", CSKY_ARCH_803
, CSKY_ISA_803R1
},
625 {"ck803tr1", CSKY_ARCH_803
, CSKY_ISA_803R1
| CSKY_ISA_TRUST
},
626 {"ck803htr1", CSKY_ARCH_803
, CSKY_ISA_803R1
| CSKY_ISA_TRUST
},
627 {"ck803fr1", CSKY_ARCH_803
| CSKY_ARCH_FLOAT
, CSKY_ISA_803R1
| CSKY_ISA_FLOAT_803
},
628 {"ck803fhr1", CSKY_ARCH_803
| CSKY_ARCH_FLOAT
, CSKY_ISA_803R1
| CSKY_ISA_FLOAT_803
},
629 {"ck803er1", CSKY_ARCH_803
| CSKY_ARCH_DSP
, CSKY_ISA_803R1
| CSKY_ISA_DSP_ENHANCE
},
630 {"ck803ehr1", CSKY_ARCH_803
| CSKY_ARCH_DSP
, CSKY_ISA_803R1
| CSKY_ISA_DSP_ENHANCE
},
631 {"ck803etr1", CSKY_ARCH_803
| CSKY_ARCH_DSP
, CSKY_ISA_803R1
| CSKY_ISA_DSP_ENHANCE
| CSKY_ISA_TRUST
},
632 {"ck803ehtr1", CSKY_ARCH_803
| CSKY_ARCH_DSP
, CSKY_ISA_803R1
| CSKY_ISA_DSP_ENHANCE
| CSKY_ISA_TRUST
},
633 {"ck803efr1", CSKY_ARCH_803
| CSKY_ARCH_DSP
| CSKY_ARCH_FLOAT
, CSKY_ISA_803R1
| CSKY_ISA_DSP_ENHANCE
| CSKY_ISA_FLOAT_803
},
634 {"ck803efhr1", CSKY_ARCH_803
| CSKY_ARCH_DSP
| CSKY_ARCH_FLOAT
, CSKY_ISA_803R1
| CSKY_ISA_DSP_ENHANCE
| CSKY_ISA_FLOAT_803
},
635 {"ck803ftr1", CSKY_ARCH_803
| CSKY_ARCH_FLOAT
, CSKY_ISA_803R1
| CSKY_ISA_FLOAT_803
| CSKY_ISA_TRUST
},
636 {"ck803eftr1", CSKY_ARCH_803
| CSKY_ARCH_DSP
| CSKY_ARCH_FLOAT
, CSKY_ISA_803R1
| CSKY_ISA_DSP_ENHANCE
| CSKY_ISA_FLOAT_803
| CSKY_ISA_TRUST
},
637 {"ck803ehftr1", CSKY_ARCH_803
| CSKY_ARCH_DSP
| CSKY_ARCH_FLOAT
, CSKY_ISA_803R1
| CSKY_ISA_DSP_ENHANCE
| CSKY_ISA_FLOAT_803
| CSKY_ISA_TRUST
},
639 {"ck803s", CSKY_ARCH_803
, CSKY_ISA_803R1
},
640 {"ck803se", CSKY_ARCH_803
| CSKY_ARCH_DSP
, CSKY_ISA_803R1
| CSKYV2_ISA_DSP
},
641 {"ck803sj", CSKY_ARCH_803
| CSKY_ARCH_JAVA
, CSKY_ISA_803R1
| CSKY_ISA_JAVA
},
642 {"ck803sf", CSKY_ARCH_803
| CSKY_ARCH_FLOAT
, CSKY_ISA_803R1
| CSKY_ISA_FLOAT_803
},
643 {"ck803sef", CSKY_ARCH_803
| CSKY_ARCH_DSP
| CSKY_ARCH_FLOAT
, CSKY_ISA_803R1
| CSKYV2_ISA_DSP
| CSKY_ISA_FLOAT_803
},
644 {"ck803st", CSKY_ARCH_803
, CSKY_ISA_803R1
| CSKY_ISA_TRUST
},
647 #define CSKY_ISA_807 (CSKY_ISA_803 | CSKYV2_ISA_3E7 | CSKY_ISA_DSP | CSKY_ISA_MP_1E2 | CSKY_ISA_CACHE)
648 #define CSKY_ISA_FLOAT_807 (CSKY_ISA_FLOAT_803 | CSKY_ISA_FLOAT_3E4 | CSKY_ISA_FLOAT_1E2)
649 {"ck807e", CSKY_ARCH_807_BASE
, CSKY_ISA_807
| CSKYV2_ISA_DSP
},
650 {"ck807ef", CSKY_ARCH_807_BASE
| CSKY_ARCH_FLOAT
, CSKY_ISA_807
| CSKYV2_ISA_DSP
| CSKY_ISA_FLOAT_807
},
651 {"ck807", CSKY_ARCH_807_BASE
, CSKY_ISA_807
| CSKYV2_ISA_DSP
},
652 {"ck807f", CSKY_ARCH_807_BASE
| CSKY_ARCH_FLOAT
, CSKY_ISA_807
| CSKYV2_ISA_DSP
| CSKY_ISA_FLOAT_807
},
655 #define CSKY_ISA_810 (CSKY_ISA_807 | CSKYV2_ISA_7E10)
656 #define CSKY_ISA_FLOAT_810 (CSKY_ISA_FLOAT_E1 | CSKY_ISA_FLOAT_1E2)
657 {"ck810e", CSKY_ARCH_810_BASE
, CSKY_ISA_810
| CSKYV2_ISA_DSP
},
658 {"ck810et", CSKY_ARCH_810_BASE
, CSKY_ISA_810
| CSKYV2_ISA_DSP
| CSKY_ISA_TRUST
},
659 {"ck810ef", CSKY_ARCH_810_BASE
| CSKY_ARCH_FLOAT
, CSKY_ISA_810
| CSKYV2_ISA_DSP
| CSKY_ISA_FLOAT_810
},
660 {"ck810eft", CSKY_ARCH_810_BASE
| CSKY_ARCH_FLOAT
, CSKY_ISA_810
| CSKYV2_ISA_DSP
| CSKY_ISA_FLOAT_810
| CSKY_ISA_TRUST
},
661 {"ck810", CSKY_ARCH_810_BASE
, CSKY_ISA_810
| CSKYV2_ISA_DSP
},
662 {"ck810v", CSKY_ARCH_810_BASE
, CSKY_ISA_810
| CSKYV2_ISA_DSP
| CSKY_ISA_VDSP
},
663 {"ck810f", CSKY_ARCH_810_BASE
| CSKY_ARCH_FLOAT
, CSKY_ISA_810
| CSKYV2_ISA_DSP
| CSKY_ISA_FLOAT_810
},
664 {"ck810t", CSKY_ARCH_810_BASE
, CSKY_ISA_810
| CSKYV2_ISA_DSP
| CSKY_ISA_TRUST
},
665 {"ck810tv", CSKY_ARCH_810_BASE
, CSKY_ISA_810
| CSKYV2_ISA_DSP
| CSKY_ISA_TRUST
},
666 {"ck810ft", CSKY_ARCH_810_BASE
| CSKY_ARCH_FLOAT
, CSKY_ISA_810
| CSKYV2_ISA_DSP
| CSKY_ISA_VDSP
| CSKY_ISA_FLOAT_810
| CSKY_ISA_TRUST
},
667 {"ck810ftv", CSKY_ARCH_810_BASE
| CSKY_ARCH_FLOAT
, CSKY_ISA_810
| CSKYV2_ISA_DSP
| CSKY_ISA_VDSP
| CSKY_ISA_FLOAT_810
| CSKY_ISA_TRUST
},
672 int md_short_jump_size
= 2;
673 int md_long_jump_size
= 4;
675 /* This array holds the chars that always start a comment. If the
676 pre-processor is disabled, these aren't very useful. */
677 const char comment_chars
[] = "#";
679 /* This array holds the chars that only start a comment at the beginning of
680 a line. If the line seems to have the form '# 123 filename'
681 .line and .file directives will appear in the pre-processed output. */
682 /* Note that input_file.c hand checks for '#' at the beginning of the
683 first line of the input file. This is because the compiler outputs
684 #NO_APP at the beginning of its output. */
685 /* Also note that comments like this one will always work. */
686 const char line_comment_chars
[] = "#";
688 const char line_separator_chars
[] = ";";
690 /* Chars that can be used to separate mant
691 from exp in floating point numbers. */
692 const char EXP_CHARS
[] = "eE";
694 /* Chars that mean this number is a floating point constant.
698 const char FLT_CHARS
[] = "rRsSfFdDxXeEpP";
700 const char *md_shortopts
= "";
702 struct option md_longopts
[] = {
703 #define OPTION_MARCH (OPTION_MD_BASE + 0)
704 {"march", required_argument
, NULL
, OPTION_MARCH
},
705 #define OPTION_MCPU (OPTION_MD_BASE + 1)
706 {"mcpu", required_argument
, NULL
, OPTION_MCPU
},
708 /* Remaining options just set boolean flags. */
709 {"EL", no_argument
, &target_big_endian
, 0},
710 {"mlittle-endian", no_argument
, &target_big_endian
, 0},
711 {"EB", no_argument
, &target_big_endian
, 1},
712 {"mbig-endian", no_argument
, &target_big_endian
, 1},
713 {"fpic", no_argument
, &do_pic
, 1},
714 {"pic", no_argument
, &do_pic
, 1},
715 {"mljump", no_argument
, &do_long_jump
, 1},
716 {"mno-ljump", no_argument
, &do_long_jump
, 0},
717 {"force2bsr", no_argument
, &do_force2bsr
, 1},
718 {"mforce2bsr", no_argument
, &do_force2bsr
, 1},
719 {"no-force2bsr", no_argument
, &do_force2bsr
, 0},
720 {"mno-force2bsr", no_argument
, &do_force2bsr
, 0},
721 {"jsri2bsr", no_argument
, &do_jsri2bsr
, 1},
722 {"mjsri2bsr", no_argument
, &do_jsri2bsr
, 1},
723 {"no-jsri2bsr", no_argument
, &do_jsri2bsr
, 0},
724 {"mno-jsri2bsr", no_argument
, &do_jsri2bsr
, 0},
725 {"mnolrw", no_argument
, &do_nolrw
, 1},
726 {"mno-lrw", no_argument
, &do_nolrw
, 1},
727 {"melrw", no_argument
, &do_extend_lrw
, 1},
728 {"mno-elrw", no_argument
, &do_extend_lrw
, 0},
729 {"mlaf", no_argument
, &do_func_dump
, 1},
730 {"mliterals-after-func", no_argument
, &do_func_dump
, 1},
731 {"mno-laf", no_argument
, &do_func_dump
, 0},
732 {"mno-literals-after-func", no_argument
, &do_func_dump
, 0},
733 {"mlabr", no_argument
, &do_br_dump
, 1},
734 {"mliterals-after-br", no_argument
, &do_br_dump
, 1},
735 {"mno-labr", no_argument
, &do_br_dump
, 0},
736 {"mnoliterals-after-br", no_argument
, &do_br_dump
, 0},
737 {"mistack", no_argument
, &do_intr_stack
, 1},
738 {"mno-istack", no_argument
, &do_intr_stack
, 0},
739 #ifdef INCLUDE_BRANCH_STUB
740 {"mbranch-stub", no_argument
, &do_use_branchstub
, 1},
741 {"mno-branch-stub", no_argument
, &do_use_branchstub
, 0},
743 {"mhard-float", no_argument
, &do_opt_mhard_float
, CSKY_ARCH_FLOAT
},
744 {"mmp", no_argument
, &do_opt_mmp
, CSKY_ARCH_MP
},
745 {"mcp", no_argument
, &do_opt_mcp
, CSKY_ARCH_CP
},
746 {"mcache", no_argument
, &do_opt_mcache
, CSKY_ARCH_CACHE
},
747 {"msecurity", no_argument
, &do_opt_msecurity
, CSKY_ARCH_MAC
},
748 {"mtrust", no_argument
, &do_opt_mtrust
, CSKY_ISA_TRUST
},
749 {"mdsp", no_argument
, &do_opt_mdsp
, CSKY_DSP_FLAG_V1
},
750 {"medsp", no_argument
, &do_opt_medsp
, CSKY_DSP_FLAG_V2
},
751 {"mvdsp", no_argument
, &do_opt_mvdsp
, CSKY_ISA_VDSP
},
754 size_t md_longopts_size
= sizeof (md_longopts
);
756 static struct csky_insn_info csky_insn
;
758 static struct hash_control
*csky_opcodes_hash
;
759 static struct hash_control
*csky_macros_hash
;
761 static struct csky_macro_info v1_macros_table
[] =
763 {"idly", 1, CSKYV1_ISA_E1
, csky_idly
},
764 {"rolc", 2, CSKYV1_ISA_E1
, csky_rolc
},
765 {"rotlc", 2, CSKYV1_ISA_E1
, csky_rolc
},
766 {"sxtrb0", 2, CSKYV1_ISA_E1
, csky_sxtrb
},
767 {"sxtrb1", 2, CSKYV1_ISA_E1
, csky_sxtrb
},
768 {"sxtrb2", 2, CSKYV1_ISA_E1
, csky_sxtrb
},
769 {"movtf", 3, CSKYV1_ISA_E1
, csky_movtf
},
770 {"addc64", 3, CSKYV1_ISA_E1
, csky_addc64
},
771 {"subc64", 3, CSKYV1_ISA_E1
, csky_subc64
},
772 {"or64", 3, CSKYV1_ISA_E1
, csky_or64
},
773 {"xor64", 3, CSKYV1_ISA_E1
, csky_xor64
},
777 static struct csky_macro_info v2_macros_table
[] =
779 {"neg", 1, CSKYV2_ISA_E1
, csky_neg
},
780 {"rsubi", 2, CSKYV2_ISA_1E2
, csky_rsubi
},
781 {"incf", 1, CSKYV2_ISA_1E2
, csky_arith
},
782 {"inct", 1, CSKYV2_ISA_1E2
, csky_arith
},
783 {"decf", 1, CSKYV2_ISA_2E3
, csky_arith
},
784 {"decgt", 1, CSKYV2_ISA_2E3
, csky_arith
},
785 {"declt", 1, CSKYV2_ISA_2E3
, csky_arith
},
786 {"decne", 1, CSKYV2_ISA_1E2
, csky_decne
},
787 {"dect", 1, CSKYV2_ISA_1E2
, csky_arith
},
788 {"lslc", 1, CSKYV2_ISA_1E2
, csky_arith
},
789 {"lsrc", 1, CSKYV2_ISA_1E2
, csky_arith
},
790 {"xsr", 1, CSKYV2_ISA_1E2
, csky_arith
},
794 /* For option -mnolrw, replace lrw by movih & ori. */
795 static struct csky_macro_info v2_lrw_macro_opcode
=
796 {"lrw", 2, CSKYV2_ISA_1E2
, csky_lrw
};
798 /* This function is used to show errors or warnings. */
801 csky_show_error (enum error_number err
, int idx
, void *arg1
, void *arg2
)
803 if (err
== ERROR_NONE
)
809 case ERROR_OPCODE_PSRBIT
:
810 case ERROR_OPCODE_ILLEGAL
:
811 case ERROR_JMPIX_OVER_RANGE
:
812 case ERROR_MISSING_COMMA
:
813 case ERROR_MISSING_LBRACKET
:
814 case ERROR_MISSING_RBRACKET
:
815 case ERROR_MISSING_LSQUARE_BRACKETS
:
816 case ERROR_MISSING_RSQUARE_BRACKETS
:
817 case ERROR_MISSING_LANGLE_BRACKETS
:
818 case ERROR_MISSING_RANGLE_BRACKETS
:
819 /* Add NULL to fix warnings. */
820 as_bad (_(err_formats
[err
].fmt
), NULL
);
822 case ERROR_CREG_ILLEGAL
:
823 case ERROR_GREG_ILLEGAL
:
824 case ERROR_IMM_ILLEGAL
:
825 case ERROR_IMM_OVERFLOW
:
828 case ERROR_EXP_CONSTANT
:
829 case ERROR_EXP_EVEN_FREG
:
830 case ERROR_MISSING_OPERAND
:
831 case ERROR_CPREG_ILLEGAL
:
832 as_bad (_(err_formats
[err
].fmt
), idx
);
834 case ERROR_OPERANDS_NUMBER
:
835 case ERROR_IMM_POWER
:
836 as_bad (_(err_formats
[err
].fmt
), (long)arg1
);
839 case ERROR_OFFSET_UNALIGNED
:
840 as_bad (_(err_formats
[err
].fmt
), idx
, (long)arg1
);
842 case ERROR_RELOC_ILLEGAL
:
844 case ERROR_OPERANDS_ILLEGAL
:
845 as_bad (_(err_formats
[err
].fmt
), (char *)arg1
);
847 case ERROR_REG_OVER_RANGE
:
848 as_bad (_(err_formats
[err
].fmt
), idx
, (long) arg1
);
850 case ERROR_802J_REG_OVER_RANGE
:
851 case ERROR_REG_FORMAT
:
852 as_bad (_(err_formats
[err
].fmt
), idx
, (char *)arg1
);
855 /* Add NULL to fix warnings. */
856 as_bad ((char *)arg1
, NULL
);
859 as_warn (_(err_formats
[err
].fmt
), (long)arg1
);
861 case WARNING_OPTIONS
:
862 as_warn (_(err_formats
[err
].fmt
), (char *)arg1
, (char *)arg2
);
869 /* Handle errors in branch relaxation. */
872 csky_branch_report_error (const char* file
, unsigned int line
,
873 symbolS
* sym
, offsetT val
)
875 as_bad_where (file
? file
: _("unknown"),
877 _("pcrel offset for branch to %s too far (0x%lx)"),
878 sym
? S_GET_NAME (sym
) : _("<unknown>"),
882 /* Set appropriate flags for the cpu matching STR. */
885 parse_cpu (const char *str
)
889 for (; csky_cpus
[i
].name
!= NULL
; i
++)
890 if (strcasecmp (str
, csky_cpus
[i
].name
) == 0)
892 mach_flag
|= csky_cpus
[i
].mach_flag
;
893 isa_flag
= csky_cpus
[i
].isa_flag
;
894 other_flag
|= (csky_cpus
[i
].mach_flag
& ~CSKY_ARCH_MASK
);
897 as_bad (_("unknown cpu `%s'"), str
);
900 /* Set appropriate flags for the arch matching STR. */
903 parse_arch (const char *str
)
906 for (; csky_archs
[i
].name
!= NULL
; i
++)
907 if (strcasecmp (str
, csky_archs
[i
].name
) == 0)
909 arch_flag
|= csky_archs
[i
].arch_flag
;
912 as_bad (_("unknown architecture `%s'"), str
);
917 /* Implement the TARGET_FORMAT macro. */
920 elf32_csky_target_format (void)
922 return (target_big_endian
924 : "elf32-csky-little");
928 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
929 for use in the a.out file, and stores them in the array pointed to by buf.
930 This knows about the endian-ness of the target machine and does
931 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
932 2 (short) and 4 (long) Floating numbers are put out as a series of
933 LITTLENUMS (shorts, here at least). */
936 md_number_to_chars (char * buf
, valueT val
, int n
)
938 if (target_big_endian
)
939 number_to_chars_bigendian (buf
, val
, n
);
941 number_to_chars_littleendian (buf
, val
, n
);
944 /* Get a log2(val). */
947 csky_log_2 (unsigned int val
)
950 if ((val
& (val
- 1)) == 0)
951 for (; val
; val
>>= 1)
954 csky_show_error (ERROR_IMM_POWER
, 0, (void *)(long)val
, NULL
);
958 /* Output one instruction to the buffer at PTR. */
961 csky_write_insn (char *ptr
, valueT use
, int nbytes
)
964 md_number_to_chars (ptr
, use
, nbytes
);
965 else /* 32-bit instruction. */
967 /* Significant figures are in low bits. */
968 md_number_to_chars (ptr
, use
>> 16, 2);
969 md_number_to_chars (ptr
+ 2, use
& 0xFFFF, 2);
973 /* Read an NBYTES instruction from the buffer at PTR. NBYTES should
974 be either 2 or 4. This function is used in branch relaxation. */
977 csky_read_insn (char *ptr
, int nbytes
)
979 unsigned char *uptr
= (unsigned char *)ptr
;
981 int lo
, hi
; /* hi/lo byte index in binary stream. */
983 if (target_big_endian
)
993 v
= uptr
[lo
] | (uptr
[hi
] << 8);
997 v
|= uptr
[lo
+ 2] | (uptr
[hi
+ 2] << 8);
1002 /* Construct a label name into S from the 3-character prefix P and
1003 number N formatted as a 4-digit hex number. */
1006 make_internal_label (char *s
, const char *p
, int n
)
1008 static const char hex
[] = "0123456789ABCDEF";
1013 s
[3] = hex
[(n
>> 12) & 0xF];
1014 s
[4] = hex
[(n
>> 8) & 0xF];
1015 s
[5] = hex
[(n
>> 4) & 0xF];
1016 s
[6] = hex
[(n
) & 0xF];
1020 /* md_operand is a no-op on C-SKY; we do everything elsewhere. */
1023 md_operand (expressionS
*expressionP ATTRIBUTE_UNUSED
)
1028 /* Under ELF we need to default _GLOBAL_OFFSET_TABLE.
1029 Otherwise we have no need to default values of symbols. */
1032 md_undefined_symbol (char *name ATTRIBUTE_UNUSED
)
1040 /* Use IEEE format for floating-point constants. */
1043 md_atof (int type
, char *litP
, int *sizeP
)
1045 return ieee_md_atof (type
, litP
, sizeP
, target_big_endian
);
1048 /* Print option help to FP. */
1051 md_show_usage (FILE *fp
)
1054 const int margin
= 48;
1056 fprintf (fp
, _("C-SKY assembler options:\n"));
1059 -march=ARCH select architecture ARCH:"));
1060 for (i
= 0, n
= margin
; csky_archs
[i
].name
!= NULL
; i
++)
1062 int l
= strlen (csky_archs
[i
].name
);
1063 if (n
+ l
>= margin
)
1065 fprintf (fp
, "\n\t\t\t\t");
1073 fprintf (fp
, "%s", csky_archs
[i
].name
);
1078 -mcpu=CPU select processor CPU:"));
1079 for (i
= 0, n
= margin
; csky_cpus
[i
].name
!= NULL
; i
++)
1081 int l
= strlen (csky_cpus
[i
].name
);
1082 if (n
+ l
>= margin
)
1084 fprintf (fp
, "\n\t\t\t\t");
1092 fprintf (fp
, "%s", csky_cpus
[i
].name
);
1097 -EL -mlittle-endian generate little-endian output\n"));
1099 -EB -mbig-endian generate big-endian output\n"));
1101 -fpic -pic generate position-independent code\n"));
1104 -mljump transform jbf, jbt, jbr to jmpi (CK800 only)\n"));
1108 #ifdef INCLUDE_BRANCH_STUB
1110 -mbranch-stub enable branch stubs for PC-relative calls\n"));
1112 -mno-branch-stub\n"));
1116 -force2bsr -mforce2bsr transform jbsr to bsr\n"));
1118 -no-force2bsr -mno-force2bsr\n"));
1120 -jsri2bsr -mjsri2bsr transform jsri to bsr\n"));
1122 -no-jsri2bsr -mno-jsri2bsr\n"));
1125 -mnolrw -mno-lrw implement lrw as movih + ori\n"));
1127 -melrw enable extended lrw (CK800 only)\n"));
1132 -mlaf -mliterals-after-func emit literals after each function\n"));
1134 -mno-laf -mno-literals-after-func\n"));
1136 -mlabr -mliterals-after-br emit literals after branch instructions\n"));
1138 -mno-labr -mnoliterals-after-br\n"));
1141 -mistack enable interrupt stack instructions\n"));
1146 -mhard-float enable hard float instructions\n"));
1148 -mmp enable multiprocessor instructions\n"));
1150 -mcp enable coprocessor instructions\n"));
1152 -mcache enable cache prefetch instruction\n"));
1154 -msecurity enable security instructions\n"));
1156 -mtrust enable trust instructions\n"));
1158 -mdsp enable DSP instructions\n"));
1160 -medsp enable enhanced DSP instructions\n"));
1162 -mvdsp enable vector DSP instructions\n"));
1165 /* Target-specific initialization and option handling. */
1170 unsigned int bfd_mach_flag
= 0;
1171 struct csky_opcode
const *opcode
;
1172 struct csky_macro_info
const *macro
;
1173 struct csky_arch_info
const *p_arch
;
1174 struct csky_cpu_info
const *p_cpu
;
1175 unsigned int flags
= (other_flag
| do_opt_mmp
| do_opt_mcp
| do_opt_mcache
1176 | do_opt_msecurity
| do_opt_mhard_float
);
1177 dsp_flag
|= do_opt_mdsp
| do_opt_medsp
;
1178 isa_flag
|= do_opt_mtrust
| do_opt_mvdsp
;
1181 flags
|= CSKY_ARCH_DSP
;
1185 if ((mach_flag
& CSKY_ARCH_MASK
) != arch_flag
&& arch_flag
!= 0)
1186 as_warn (_("-mcpu conflict with -march option, using -mcpu"));
1187 if ((mach_flag
& ~CSKY_ARCH_MASK
) != flags
&& flags
!= 0)
1188 as_warn (_("-mcpu conflict with other model parameters, using -mcpu"));
1190 else if (arch_flag
!= 0)
1191 mach_flag
|= arch_flag
| flags
;
1194 #ifdef TARGET_WITH_CPU
1196 for (; csky_cpus
[i
].name
!= NULL
; i
++)
1198 if (strcmp (TARGET_WITH_CPU
, csky_cpus
[i
].name
) == 0)
1200 mach_flag
|= csky_cpus
[i
].mach_flag
;
1201 isa_flag
= csky_cpus
[i
].isa_flag
;
1207 mach_flag
|= CSKY_ARCH_610
| flags
;
1209 mach_flag
|= CSKY_ARCH_810_BASE
| flags
;
1214 if (IS_CSKY_ARCH_610 (mach_flag
) || IS_CSKY_ARCH_510 (mach_flag
))
1216 if ((mach_flag
& CSKY_ARCH_MP
) && (mach_flag
& CSKY_ARCH_MAC
))
1217 as_fatal ("520/620 conflicts with -mmp option");
1218 else if ((mach_flag
& CSKY_ARCH_MP
) && (mach_flag
& CSKY_ARCH_DSP
))
1219 as_fatal ("510e/610e conflicts with -mmp option");
1220 else if ((mach_flag
& CSKY_ARCH_DSP
) && (mach_flag
& CSKY_ARCH_MAC
))
1221 as_fatal ("520/620 conflicts with 510e/610e or -mdsp option");
1223 if (IS_CSKY_ARCH_510 (mach_flag
) && (mach_flag
& CSKY_ARCH_FLOAT
))
1225 mach_flag
= (mach_flag
& (~CSKY_ARCH_MASK
));
1226 mach_flag
|= CSKY_ARCH_610
;
1229 /* Find bfd_mach_flag, it will set to bfd backend data. */
1230 for (p_arch
= csky_archs
; p_arch
->arch_flag
!= 0; p_arch
++)
1231 if ((mach_flag
& CSKY_ARCH_MASK
) == (p_arch
->arch_flag
& CSKY_ARCH_MASK
))
1233 bfd_mach_flag
= p_arch
->bfd_mach_flag
;
1237 /* Find isa_flag. */
1238 for (p_cpu
= csky_cpus
; p_cpu
->mach_flag
!= 0; p_cpu
++)
1239 if ((mach_flag
& CPU_ARCH_MASK
) == p_cpu
->mach_flag
)
1241 isa_flag
|= p_cpu
->isa_flag
;
1245 /* Check if -mdsp and -medsp conflict. If cpu is ck803, we will
1246 use enhanced dsp instruction. Otherwise, we will use normal dsp. */
1249 if (IS_CSKY_ARCH_803 (mach_flag
))
1251 /* In 803, dspv1 is conflict with dspv2. We keep dspv2. */
1252 if ((dsp_flag
& CSKY_DSP_FLAG_V1
) && (dsp_flag
& CSKY_DSP_FLAG_V2
))
1253 as_warn (_("option -mdsp conflicts with -medsp, only enabling -medsp"));
1254 isa_flag
&= ~(CSKY_ISA_MAC_DSP
| CSKY_ISA_DSP
);
1255 isa_flag
|= CSKY_ISA_DSP_ENHANCE
;
1259 isa_flag
&= ~CSKY_ISA_DSP_ENHANCE
;
1260 as_warn (_("-medsp option is only supported by ck803s, ignoring -medsp"));
1265 if (do_use_branchstub
== -1)
1266 do_use_branchstub
= !IS_CSKY_ARCH_V1 (mach_flag
);
1267 else if (do_use_branchstub
== 1)
1269 if (IS_CSKY_ARCH_V1 (mach_flag
))
1271 as_warn (_("C-SKY ABI v1 (ck510/ck610) does not support -mbranch-stub"));
1272 do_use_branchstub
= 0;
1274 else if (do_force2bsr
== 0)
1276 as_warn (_("-mno-force2bsr is ignored with -mbranch-stub"));
1281 if (IS_CSKY_ARCH_801 (mach_flag
) || IS_CSKY_ARCH_802 (mach_flag
))
1284 as_warn (_("-mno-force2bsr is ignored for ck801/ck802"));
1287 else if (do_force2bsr
== -1)
1288 do_force2bsr
= do_use_branchstub
;
1292 if (IS_CSKY_ARCH_V1 (mach_flag
))
1298 if (do_extend_lrw
== -1)
1300 if (IS_CSKY_ARCH_801 (mach_flag
))
1305 if (IS_CSKY_ARCH_801 (mach_flag
) || IS_CSKY_ARCH_802 (mach_flag
))
1307 if (do_long_jump
> 0)
1308 as_warn (_("-mljump is ignored for ck801/ck802"));
1311 else if (do_long_jump
== -1)
1313 if (do_intr_stack
== -1)
1315 /* control interrupt stack module, 801&802&803 default on
1316 807&810, default off. */
1317 if (IS_CSKY_ARCH_807 (mach_flag
) || IS_CSKY_ARCH_810 (mach_flag
))
1322 /* TODO: add isa_flag(SIMP/CACHE/APS). */
1323 isa_flag
|= (mach_flag
& CSKY_ARCH_MAC
) ? CSKY_ISA_MAC
: 0;
1324 isa_flag
|= (mach_flag
& CSKY_ARCH_MP
) ? CSKY_ISA_MP
: 0;
1325 isa_flag
|= (mach_flag
& CSKY_ARCH_CP
) ? CSKY_ISA_CP
: 0;
1327 /* Set abi flag and get table address. */
1328 if (IS_CSKY_ARCH_V1 (mach_flag
))
1330 mach_flag
= mach_flag
| CSKY_ABI_V1
;
1331 opcode
= csky_v1_opcodes
;
1332 macro
= v1_macros_table
;
1333 SPANPANIC
= v1_SPANPANIC
;
1334 SPANCLOSE
= v1_SPANCLOSE
;
1335 SPANEXIT
= v1_SPANEXIT
;
1336 md_relax_table
= csky_relax_table
;
1340 mach_flag
= mach_flag
| CSKY_ABI_V2
;
1341 opcode
= csky_v2_opcodes
;
1342 macro
= v2_macros_table
;
1343 SPANPANIC
= v2_SPANPANIC
;
1346 SPANCLOSE
= v2_SPANCLOSE_ELRW
;
1347 SPANEXIT
= v2_SPANEXIT_ELRW
;
1351 SPANCLOSE
= v2_SPANCLOSE
;
1352 SPANEXIT
= v2_SPANEXIT
;
1354 md_relax_table
= csky_relax_table
;
1357 /* Establish hash table for opcodes and macros. */
1358 csky_macros_hash
= hash_new ();
1359 csky_opcodes_hash
= hash_new ();
1360 for ( ; opcode
->mnemonic
!= NULL
; opcode
++)
1361 if ((isa_flag
& (opcode
->isa_flag16
| opcode
->isa_flag32
)) != 0)
1362 hash_insert (csky_opcodes_hash
, opcode
->mnemonic
, (char *)opcode
);
1363 for ( ; macro
->name
!= NULL
; macro
++)
1364 if ((isa_flag
& macro
->isa_flag
) != 0)
1365 hash_insert (csky_macros_hash
, macro
->name
, (char *)macro
);
1366 if (do_nolrw
&& (isa_flag
& CSKYV2_ISA_1E2
) != 0)
1367 hash_insert (csky_macros_hash
,
1368 v2_lrw_macro_opcode
.name
,
1369 (char *)&v2_lrw_macro_opcode
);
1370 /* Set e_flag to ELF Head. */
1371 bfd_set_private_flags (stdoutput
, mach_flag
);
1372 /* Set bfd_mach to bfd backend data. */
1373 bfd_set_arch_mach (stdoutput
, bfd_arch_csky
, bfd_mach_flag
);
1376 /* The C-SKY assembler emits mapping symbols $t and $d to mark the
1377 beginning of a sequence of instructions and data (such as a constant pool),
1378 respectively. This is similar to what ARM does. */
1381 make_mapping_symbol (map_state state
, valueT value
, fragS
*frag
)
1384 const char * symname
;
1390 type
= BSF_NO_FLAGS
;
1394 type
= BSF_NO_FLAGS
;
1400 symbolP
= symbol_new (symname
, now_seg
, value
, frag
);
1401 symbol_get_bfdsym (symbolP
)->flags
|= type
| BSF_LOCAL
;
1404 /* We need to keep track of whether we are emitting code or data; this
1405 function switches state and emits a mapping symbol if necessary. */
1408 mapping_state (map_state state
)
1410 map_state current_state
1411 = seg_info (now_seg
)->tc_segment_info_data
.current_state
;
1413 if (current_state
== state
)
1415 else if (current_state
== MAP_UNDEFINED
&& state
== MAP_DATA
)
1417 else if (current_state
== MAP_UNDEFINED
&& state
== MAP_TEXT
)
1419 struct frag
* const frag_first
= seg_info (now_seg
)->frchainP
->frch_root
;
1420 if (frag_now
!= frag_first
|| frag_now_fix () > 0)
1421 make_mapping_symbol (MAP_DATA
, (valueT
) 0, frag_first
);
1424 seg_info (now_seg
)->tc_segment_info_data
.current_state
= state
;
1425 make_mapping_symbol (state
, (valueT
) frag_now_fix (), frag_now
);
1428 /* Dump the literal pool. */
1431 dump_literals (int isforce
)
1433 #define CSKYV1_BR_INSN 0xF000
1434 #define CSKYV2_BR_INSN 0x0400
1437 symbolS
* brarsym
= NULL
;
1439 /* V1 nop encoding: 0x1200 : mov r0, r0. */
1440 static char v1_nop_insn_big
[2] = {0x12, 0x00};
1441 static char v1_nop_insn_little
[2] = {0x00, 0x12};
1446 /* Must we branch around the literal table? */
1450 make_internal_label (brarname
, POOL_END_LABEL
, poolnumber
);
1451 brarsym
= symbol_make (brarname
);
1452 symbol_table_insert (brarsym
);
1453 mapping_state (MAP_TEXT
);
1454 if (IS_CSKY_ARCH_V1 (mach_flag
))
1457 = frag_var (rs_machine_dependent
,
1458 csky_relax_table
[C (UNCD_JUMP_S
, DISP32
)].rlx_length
,
1459 csky_relax_table
[C (UNCD_JUMP_S
, DISP12
)].rlx_length
,
1460 C (UNCD_JUMP_S
, 0), brarsym
, 0, 0);
1461 md_number_to_chars (csky_insn
.output
, CSKYV1_BR_INSN
, 2);
1466 = frag_var (rs_machine_dependent
,
1471 md_number_to_chars (csky_insn
.output
, CSKYV2_BR_INSN
, 2);
1474 /* Make sure that the section is sufficiently aligned and that
1475 the literal table is aligned within it. */
1479 csky_insn
.output
= frag_more (2);
1481 if (IS_CSKY_V1 (mach_flag
))
1482 br_self
= CSKYV1_BR_INSN
| 0x7ff;
1484 br_self
= CSKYV2_BR_INSN
;
1485 md_number_to_chars (csky_insn
.output
, br_self
, 2);
1488 csky_insn
.output
= frag_more (2);
1490 md_number_to_chars (csky_insn
.output
, br_self
, 2);
1493 mapping_state (MAP_DATA
);
1495 record_alignment (now_seg
, 2);
1496 if (IS_CSKY_ARCH_V1 (mach_flag
))
1497 frag_align_pattern (2,
1499 ? v1_nop_insn_big
: v1_nop_insn_little
),
1502 frag_align (2, 0, 3);
1504 colon (S_GET_NAME (poolsym
));
1506 for (i
= 0, p
= litpool
; i
< poolsize
; i
+= (p
->isdouble
? 2 : 1), p
++)
1508 insn_reloc
= p
->r_type
;
1509 if (insn_reloc
== BFD_RELOC_CKCORE_TLS_IE32
1510 || insn_reloc
== BFD_RELOC_CKCORE_TLS_LDM32
1511 || insn_reloc
== BFD_RELOC_CKCORE_TLS_GD32
)
1512 literal_insn_offset
= p
;
1515 if (target_big_endian
)
1517 p
->e
.X_add_number
= p
->dbnum
>> 32;
1518 emit_expr (& p
->e
, 4);
1519 p
->e
.X_add_number
= p
->dbnum
& 0xffffffff;
1520 emit_expr (& p
->e
, 4);
1524 p
->e
.X_add_number
= p
->dbnum
& 0xffffffff;
1525 emit_expr (& p
->e
, 4);
1526 p
->e
.X_add_number
= p
->dbnum
>> 32;
1527 emit_expr (& p
->e
, 4);
1531 emit_expr (& p
->e
, 4);
1534 if (isforce
&& IS_CSKY_ARCH_V2 (mach_flag
))
1536 /* Add one nop insn at end of literal for disassembler. */
1537 mapping_state (MAP_TEXT
);
1538 csky_insn
.output
= frag_more (2);
1539 md_number_to_chars (csky_insn
.output
, CSKYV2_INST_NOP
, 2);
1542 insn_reloc
= BFD_RELOC_NONE
;
1544 if (brarsym
!= NULL
)
1545 colon (S_GET_NAME (brarsym
));
1550 enter_literal (expressionS
*e
,
1552 unsigned char isdouble
,
1557 if (poolsize
>= MAX_POOL_SIZE
- 2)
1559 /* The literal pool is as full as we can handle. We have
1560 to be 2 entries shy of the 1024/4=256 entries because we
1561 have to allow for the branch (2 bytes) and the alignment
1562 (2 bytes before the first insn referencing the pool and
1563 2 bytes before the pool itself) == 6 bytes, rounds up
1566 /* Save the parsed symbol's reloc. */
1567 enum bfd_reloc_code_real last_reloc_before_dump
= insn_reloc
;
1569 insn_reloc
= last_reloc_before_dump
;
1574 /* Create new literal pool. */
1575 if (++ poolnumber
> 0xFFFF)
1576 as_fatal (_("more than 65K literal pools"));
1578 make_internal_label (poolname
, POOL_START_LABEL
, poolnumber
);
1579 poolsym
= symbol_make (poolname
);
1580 symbol_table_insert (poolsym
);
1584 /* Search pool for value so we don't have duplicates. */
1585 for (p
= litpool
, i
= 0; i
< poolsize
; i
+= (p
->isdouble
? 2 : 1), p
++)
1587 if (e
->X_op
== p
->e
.X_op
1588 && e
->X_add_symbol
== p
->e
.X_add_symbol
1589 && e
->X_add_number
== p
->e
.X_add_number
1590 && ispcrel
== p
->ispcrel
1591 && insn_reloc
== p
->r_type
1592 && isdouble
== p
->isdouble
1593 && insn_reloc
!= BFD_RELOC_CKCORE_TLS_GD32
1594 && insn_reloc
!= BFD_RELOC_CKCORE_TLS_LDM32
1595 && insn_reloc
!= BFD_RELOC_CKCORE_TLS_LDO32
1596 && insn_reloc
!= BFD_RELOC_CKCORE_TLS_IE32
1597 && insn_reloc
!= BFD_RELOC_CKCORE_TLS_LE32
)
1604 p
->ispcrel
= ispcrel
;
1606 p
->r_type
= insn_reloc
;
1607 p
->isdouble
= isdouble
;
1611 if (insn_reloc
== BFD_RELOC_CKCORE_TLS_GD32
1612 || insn_reloc
== BFD_RELOC_CKCORE_TLS_LDM32
1613 || insn_reloc
== BFD_RELOC_CKCORE_TLS_IE32
)
1615 p
->tls_addend
.frag
= frag_now
;
1616 p
->tls_addend
.offset
= csky_insn
.output
- frag_now
->fr_literal
;
1617 literal_insn_offset
= p
;
1619 poolsize
+= (p
->isdouble
? 2 : 1);
1623 /* Check whether we must dump the literal pool here.
1624 kind == 0 is any old instruction.
1625 kind > 0 means we just had a control transfer instruction.
1626 kind == 1 means within a function.
1627 kind == 2 means we just left a function.
1629 OFFSET is the length of the insn being processed.
1631 SPANCLOSE and SPANEXIT are smaller numbers than SPANPANIC.
1632 SPANPANIC means that we must dump now.
1633 The dump_literals (1) call inserts a branch around the table, so
1634 we first look to see if its a situation where we won't have to
1635 insert a branch (e.g., the previous instruction was an unconditional
1638 SPANPANIC is the point where we must dump a single-entry pool.
1639 it accounts for alignments and an inserted branch.
1640 the 'poolsize*2' accounts for the scenario where we do:
1641 lrw r1,lit1; lrw r2,lit2; lrw r3,lit3
1642 Note that the 'lit2' reference is 2 bytes further along
1643 but the literal it references will be 4 bytes further along,
1644 so we must consider the poolsize into this equation.
1645 This is slightly over-cautious, but guarantees that we won't
1646 panic because a relocation is too distant. */
1649 check_literals (int kind
, int offset
)
1653 if ((poolspan
> SPANEXIT
|| do_func_dump
)
1655 && (do_br_dump
|| do_func_dump
))
1657 else if (poolspan
> SPANCLOSE
&& (kind
> 0) && do_br_dump
)
1660 >= (SPANPANIC
- (IS_CSKY_ARCH_V1 (mach_flag
) ? poolsize
* 2 : 0)))
1662 /* We have not dumped literal pool before insn1,
1663 and will not dump literal pool between insn1 and insnN+1,
1664 so reset poolspan to original length. */
1665 else if (do_noliteraldump
== 1)
1668 if (do_noliteraldump
== 1)
1669 do_noliteraldump
= 0;
1672 /* The next group of functions are helpers for parsing various kinds
1673 of instruction operand syntax. */
1675 /* Parse operands of the form
1676 <symbol>@GOTOFF+<nnn>
1677 and similar .plt or .got references.
1679 If we find one, set up the correct relocation in RELOC and copy the
1680 input string, minus the `@GOTOFF' into a malloc'd buffer for
1681 parsing by the calling routine. Return this buffer, and if ADJUST
1682 is non-null set it to the length of the string we removed from the
1683 input line. Otherwise return NULL. */
1686 lex_got (enum bfd_reloc_code_real
*reloc
,
1692 const enum bfd_reloc_code_real rel
;
1694 static const struct _gotrel gotrel
[] =
1696 { "GOTOFF", BFD_RELOC_CKCORE_GOTOFF
},
1697 { "GOTPC", BFD_RELOC_CKCORE_GOTPC
},
1698 { "GOTTPOFF", BFD_RELOC_CKCORE_TLS_IE32
},
1699 { "GOT", BFD_RELOC_CKCORE_GOT32
},
1700 { "PLT", BFD_RELOC_CKCORE_PLT32
},
1701 { "BTEXT", BFD_RELOC_CKCORE_TOFFSET_LO16
},
1702 { "BDATA", BFD_RELOC_CKCORE_DOFFSET_LO16
},
1703 { "TLSGD32", BFD_RELOC_CKCORE_TLS_GD32
},
1704 { "TLSLDM32", BFD_RELOC_CKCORE_TLS_LDM32
},
1705 { "TLSLDO32", BFD_RELOC_CKCORE_TLS_LDO32
},
1706 { "TPOFF", BFD_RELOC_CKCORE_TLS_LE32
}
1712 for (cp
= input_line_pointer
; *cp
!= '@'; cp
++)
1713 if (is_end_of_line
[(unsigned char) *cp
])
1716 for (j
= 0; j
< sizeof (gotrel
) / sizeof (gotrel
[0]); j
++)
1718 int len
= strlen (gotrel
[j
].str
);
1720 if (strncasecmp (cp
+ 1, gotrel
[j
].str
, len
) == 0)
1722 if (gotrel
[j
].rel
!= 0)
1724 *reloc
= gotrel
[j
].rel
;
1728 /* input_line_pointer is the str pointer after relocation
1729 token like @GOTOFF. */
1730 input_line_pointer
+= len
+ 1;
1731 return input_line_pointer
;
1734 csky_show_error (ERROR_RELOC_ILLEGAL
, 0,
1735 (void *)gotrel
[j
].str
, NULL
);
1740 /* Might be a symbol version string. Don't as_bad here. */
1744 /* Parse an expression, returning it in E. */
1747 parse_exp (char *s
, expressionS
*e
)
1752 /* Skip whitespace. */
1753 while (ISSPACE (*s
))
1756 save
= input_line_pointer
;
1757 input_line_pointer
= s
;
1759 insn_reloc
= BFD_RELOC_NONE
;
1761 lex_got (&insn_reloc
, NULL
);
1763 if (e
->X_op
== O_absent
)
1764 SET_ERROR_NUMBER (ERROR_MISSING_OPERAND
, NULL
);
1766 new = input_line_pointer
;
1767 input_line_pointer
= save
;
1772 /* Parse a floating-point number from S into its target representation.
1773 If ISDOUBLE is true, return the result in *DBNUM; otherwise
1774 it's returned in E->X_add_number. Returns the result of advancing
1775 S past the constant. */
1778 parse_fexp (char *s
, expressionS
*e
, unsigned char isdouble
, uint64_t *dbnum
)
1780 int length
; /* Number of chars in an object. */
1781 register char const *err
= NULL
; /* Error from scanning float literal. */
1784 /* input_line_pointer->1st char of a flonum (we hope!). */
1785 input_line_pointer
= s
;
1787 if (input_line_pointer
[0] == '0'
1788 && ISALPHA (input_line_pointer
[1]))
1789 input_line_pointer
+= 2;
1792 err
= md_atof ('d', temp
, &length
);
1794 err
= md_atof ('f', temp
, &length
);
1796 know (err
!= NULL
|| length
> 0);
1798 if (!is_end_of_line
[(unsigned char) *input_line_pointer
])
1799 as_bad (_("immediate operand required"));
1800 while (!is_end_of_line
[(unsigned char) *input_line_pointer
])
1801 input_line_pointer
++;
1805 as_bad (_("bad floating literal: %s"), err
);
1806 while (!is_end_of_line
[(unsigned char) *input_line_pointer
])
1807 input_line_pointer
++;
1808 know (is_end_of_line
[(unsigned char) input_line_pointer
[-1]]);
1809 return input_line_pointer
;
1812 e
->X_add_symbol
= 0x0;
1813 e
->X_op_symbol
= 0x0;
1814 e
->X_op
= O_constant
;
1821 if (target_big_endian
)
1822 fnum
= (((temp
[0] << 24) & 0xffffffff)
1823 | ((temp
[1] << 16) & 0xffffff)
1824 | ((temp
[2] << 8) & 0xffff)
1825 | (temp
[3] & 0xff));
1827 fnum
= (((temp
[3] << 24) & 0xffffffff)
1828 | ((temp
[2] << 16) & 0xffffff)
1829 | ((temp
[1] << 8) & 0xffff)
1830 | (temp
[0] & 0xff));
1831 e
->X_add_number
= fnum
; }
1834 if (target_big_endian
)
1836 *dbnum
= (((temp
[0] << 24) & 0xffffffff)
1837 | ((temp
[1] << 16) & 0xffffff)
1838 | ((temp
[2] << 8) & 0xffff)
1839 | (temp
[3] & 0xff));
1841 *dbnum
|= (((temp
[4] << 24) & 0xffffffff)
1842 | ((temp
[5] << 16) & 0xffffff)
1843 | ((temp
[6] << 8) & 0xffff)
1844 | (temp
[7] & 0xff));
1848 *dbnum
= (((temp
[7] << 24) & 0xffffffff)
1849 | ((temp
[6] << 16) & 0xffffff)
1850 | ((temp
[5] << 8) & 0xffff)
1851 | (temp
[4] & 0xff));
1853 *dbnum
|= (((temp
[3] << 24) & 0xffffffff)
1854 | ((temp
[2] << 16) & 0xffffff)
1855 | ((temp
[1] << 8) & 0xffff)
1856 | (temp
[0] & 0xff));
1859 return input_line_pointer
;
1866 long reg ATTRIBUTE_UNUSED
)
1872 /* Indicate nothing there. */
1873 ep
->X_op
= O_absent
;
1877 s
= parse_exp (s
+ 1, &e
);
1882 SET_ERROR_NUMBER (ERROR_MISSING_RSQUARE_BRACKETS
, NULL
);
1889 s
= parse_exp (s
, &e
);
1890 if (BFD_RELOC_CKCORE_DOFFSET_LO16
== insn_reloc
1891 || BFD_RELOC_CKCORE_TOFFSET_LO16
== insn_reloc
)
1899 /* If the instruction has work, literal handling is in the work. */
1900 if (!csky_insn
.opcode
->work
)
1902 n
= enter_literal (&e
, ispcrel
, 0, 0);
1906 /* Create a reference to pool entry. */
1907 ep
->X_op
= O_symbol
;
1908 ep
->X_add_symbol
= poolsym
;
1909 ep
->X_add_number
= n
<< 2;
1916 parse_rtf (char *s
, int ispcrel
, expressionS
*ep
)
1922 /* Indicate nothing there. */
1923 ep
->X_op
= O_absent
;
1927 s
= parse_exp (s
+ 1, & e
);
1932 as_bad (_("missing ']'"));
1940 if (strstr (csky_insn
.opcode
->mnemonic
, "flrws"))
1942 s
= parse_fexp (s
, &e
, 0, &dbnum
);
1943 n
= enter_literal (&e
, ispcrel
, 0, dbnum
);
1945 else if (strstr (csky_insn
.opcode
->mnemonic
, "flrwd"))
1947 s
= parse_fexp (s
, &e
, 1, &dbnum
);
1948 n
= enter_literal (&e
, ispcrel
, 1, dbnum
);
1951 as_bad (_("unrecognized opcode"));
1956 /* Create a reference to pool entry. */
1957 ep
->X_op
= O_symbol
;
1958 ep
->X_add_symbol
= poolsym
;
1959 ep
->X_add_number
= n
<< 2;
1965 parse_type_ctrlreg (char** oper
)
1970 if (TOLOWER (*(*oper
+ 0)) == 'c'
1971 && TOLOWER (*(*oper
+ 1)) == 'r'
1972 && ISDIGIT (*(*oper
+ 2)))
1974 /* The control registers are named crxx. */
1975 i
= *(*oper
+ 2) - 0x30;
1976 i
= ISDIGIT (*(*oper
+ 3)) ? (*(*oper
+ 3) - 0x30) + 10 * i
: i
;
1977 len
= ISDIGIT (*(*oper
+ 3)) ? 4 : 3;
1980 else if (!(TOLOWER (*(*oper
+ 0)) == 'c'
1981 && TOLOWER (*(*oper
+ 1)) == 'r'))
1983 /* The control registers are aliased. */
1984 struct csky_reg
*reg
= &csky_ctrl_regs
[0];
1987 if (memcmp (*oper
, reg
->name
, strlen (reg
->name
)) == 0
1988 && (!reg
->flag
|| (isa_flag
& reg
->flag
)))
1991 len
= strlen (reg
->name
);
1999 if (IS_CSKY_V2 (mach_flag
))
2011 if (s
[0] == 'c' && s
[1] == 'r')
2017 if (s
[0] == '3' && s
[1] >= '0' && s
[1] <= '1')
2019 crx
= 30 + s
[1] - '0';
2022 else if (s
[0] == '2' && s
[1] >= '0' && s
[1] <= '9')
2024 crx
= 20 + s
[1] - '0';
2027 else if (s
[0] == '1' && s
[1] >= '0' && s
[1] <= '9')
2029 crx
= 10 + s
[1] - '0';
2032 else if (s
[0] >= '0' && s
[0] <= '9')
2039 SET_ERROR_NUMBER (ERROR_REG_OVER_RANGE
, "control");
2046 SET_ERROR_NUMBER (ERROR_CREG_ILLEGAL
, NULL
);
2050 while (*pS
!= '>' && !is_end_of_line
[(unsigned char) *pS
])
2056 /* Error. Missing '>'. */
2057 SET_ERROR_NUMBER (ERROR_MISSING_RANGLE_BRACKETS
, NULL
);
2061 s
= parse_exp (s
, &e
);
2062 if (e
.X_op
== O_constant
2063 && e
.X_add_number
>= 0
2064 && e
.X_add_number
<= 31)
2067 sel
= e
.X_add_number
;
2074 /* Error. Missing '<'. */
2075 SET_ERROR_NUMBER (ERROR_MISSING_LANGLE_BRACKETS
, NULL
);
2081 SET_ERROR_NUMBER (ERROR_CREG_ILLEGAL
, NULL
);
2085 i
= (sel
<< 5) | crx
;
2087 csky_insn
.val
[csky_insn
.idx
++] = i
;
2092 is_reg_sp_with_bracket (char **oper
)
2098 if (IS_CSKY_V1 (mach_flag
))
2106 regs
= csky_general_reg
;
2107 len
= strlen (regs
[sp_idx
]);
2108 if (memcmp (*oper
, regs
[sp_idx
], len
) == 0)
2114 csky_insn
.val
[csky_insn
.idx
++] = sp_idx
;
2119 if (IS_CSKY_V1 (mach_flag
))
2120 regs
= cskyv1_general_alias_reg
;
2122 regs
= cskyv2_general_alias_reg
;
2123 len
= strlen (regs
[sp_idx
]);
2124 if (memcmp (*oper
, regs
[sp_idx
], len
) == 0)
2137 is_reg_sp (char **oper
)
2142 if (IS_CSKY_V1 (mach_flag
))
2147 regs
= csky_general_reg
;
2148 len
= strlen (regs
[sp_idx
]);
2149 if (memcmp (*oper
, regs
[sp_idx
], len
) == 0)
2152 csky_insn
.val
[csky_insn
.idx
++] = sp_idx
;
2157 if (IS_CSKY_V1 (mach_flag
))
2158 regs
= cskyv1_general_alias_reg
;
2160 regs
= cskyv2_general_alias_reg
;
2161 len
= strlen (regs
[sp_idx
]);
2162 if (memcmp (*oper
, regs
[sp_idx
], len
) == 0)
2165 csky_insn
.val
[csky_insn
.idx
++] = sp_idx
;
2173 csky_get_reg_val (char *str
, int *len
)
2176 if (TOLOWER (str
[0]) == 'r' && ISDIGIT (str
[1]))
2178 if (ISDIGIT (str
[1]) && ISDIGIT (str
[2]))
2180 reg
= (str
[1] - '0') * 10 + str
[2] - '0';
2183 else if (ISDIGIT (str
[1]))
2191 else if (TOLOWER (str
[0]) == 's' && TOLOWER (str
[1]) == 'p'
2192 && !ISDIGIT (str
[2]))
2195 if (IS_CSKY_V1 (mach_flag
))
2201 else if (TOLOWER (str
[0]) == 'g' && TOLOWER (str
[1]) == 'b'
2202 && !ISDIGIT (str
[2]))
2205 if (IS_CSKY_V1 (mach_flag
))
2211 else if (TOLOWER (str
[0]) == 'l' && TOLOWER (str
[1]) == 'r'
2212 && !ISDIGIT (str
[2]))
2218 else if (TOLOWER (str
[0]) == 't' && TOLOWER (str
[1]) == 'l'
2219 && TOLOWER (str
[2]) == 's' && !ISDIGIT (str
[3]))
2222 if (IS_CSKY_V2 (mach_flag
))
2228 else if (TOLOWER (str
[0]) == 's' && TOLOWER (str
[1]) == 'v'
2229 && TOLOWER (str
[2]) == 'b' && TOLOWER (str
[3]) == 'r')
2231 if (IS_CSKY_V2 (mach_flag
))
2237 else if (TOLOWER (str
[0]) == 'a')
2239 if (ISDIGIT (str
[1]) && !ISDIGIT (str
[2]))
2241 if (IS_CSKY_V1 (mach_flag
) && (str
[1] - '0') <= 5)
2243 reg
= 2 + str
[1] - '0';
2244 else if (IS_CSKY_V2 (mach_flag
) && (str
[1] - '0') <= 3)
2252 else if (TOLOWER (str
[0]) == 't')
2254 if (IS_CSKY_V2 (mach_flag
))
2256 reg
= atoi (str
+ 1);
2269 else if (TOLOWER (str
[0]) == 'l')
2271 if (str
[1] < '0' || str
[1] > '9')
2273 if (IS_CSKY_V2 (mach_flag
))
2275 reg
= atoi (str
+ 1);
2287 reg
= atoi (str
+ 1);
2290 /* l0 - l6 -> r8 - r13. */
2298 /* Is register available? */
2299 if (IS_CSKY_ARCH_801 (mach_flag
))
2301 /* CK801 register range is r0-r8 & r13-r15. */
2302 if ((reg
> 8 && reg
< 13) || reg
> 15)
2304 SET_ERROR_NUMBER (ERROR_REG_OVER_RANGE
, reg
);
2308 else if (IS_CSKY_ARCH_802 (mach_flag
))
2310 /* CK802 register range is r0-r15 & r23-r25 & r30. */
2311 if ((reg
> 15 && reg
< 23) || (reg
> 25 && reg
!= 30))
2313 SET_ERROR_NUMBER (ERROR_REG_OVER_RANGE
, reg
);
2317 else if (reg
> 31 || reg
< 0)
2319 SET_ERROR_NUMBER (ERROR_REG_OVER_RANGE
, reg
);
2327 csky_get_freg_val (char *str
, int *len
)
2331 if ((str
[0] == 'v' || str
[0] == 'f') && (str
[1] == 'r'))
2333 /* It is fpu register. */
2335 while (ISDIGIT (*s
))
2337 reg
= reg
* 10 + (*s
) - '0';
2350 is_reglist_legal (char **oper
)
2355 reg1
= csky_get_reg_val (*oper
, &len
);
2358 if (reg1
== -1 || (IS_CSKY_V1 (mach_flag
) && (reg1
== 0 || reg1
== 15)))
2360 SET_ERROR_NUMBER (ERROR_REG_FORMAT
,
2361 "The first reg must not be r0/r15");
2367 SET_ERROR_NUMBER (ERROR_REG_FORMAT
,
2368 "The operand format must be rx-ry");
2373 reg2
= csky_get_reg_val (*oper
, &len
);
2376 if (reg2
== -1 || (IS_CSKY_V1 (mach_flag
) && reg1
== 15))
2378 SET_ERROR_NUMBER (ERROR_REG_FORMAT
,
2379 "The operand format must be r15 in C-SKY V1");
2382 if (IS_CSKY_V2 (mach_flag
))
2386 SET_ERROR_NUMBER (ERROR_REG_FORMAT
,
2387 "The operand format must be rx-ry (rx < ry)");
2394 csky_insn
.val
[csky_insn
.idx
++] = reg1
;
2399 is_freglist_legal (char **oper
)
2404 reg1
= csky_get_freg_val (*oper
, &len
);
2409 SET_ERROR_NUMBER (ERROR_REG_FORMAT
,
2410 "The fpu register format is not recognized.");
2416 SET_ERROR_NUMBER (ERROR_REG_FORMAT
,
2417 "The operand format must be vrx-vry/frx-fry.");
2422 reg2
= csky_get_freg_val (*oper
, &len
);
2427 SET_ERROR_NUMBER (ERROR_REG_FORMAT
,
2428 "The fpu register format is not recognized.");
2433 SET_ERROR_NUMBER (ERROR_REG_FORMAT
,
2434 "The operand format must be rx-ry(rx < ry)");
2440 csky_insn
.val
[csky_insn
.idx
++] = reg1
;
2445 is_reglist_dash_comma_legal (char **oper
, struct operand
*oprnd
)
2453 while (**oper
!= '\n' && **oper
!= '\0')
2455 reg1
= csky_get_reg_val (*oper
, &len
);
2458 SET_ERROR_NUMBER (ERROR_REG_LIST
, NULL
);
2461 flag
|= (1 << reg1
);
2466 reg2
= csky_get_reg_val (*oper
, &len
);
2469 SET_ERROR_NUMBER (ERROR_REG_LIST
, NULL
);
2475 SET_ERROR_NUMBER (ERROR_REG_LIST
, NULL
);
2478 while (reg2
>= reg1
)
2480 flag
|= (1 << reg2
);
2487 /* The reglist: r4-r11, r15, r16-r17, r28. */
2488 #define REGLIST_BITS 0x10038ff0
2489 if (flag
& ~(REGLIST_BITS
))
2491 SET_ERROR_NUMBER (ERROR_REG_LIST
, NULL
);
2498 if (flag
& (1 << i
))
2505 if (flag
& (1 << 15))
2508 /* Check r16-r17. */
2513 if (flag
& (1 << i
))
2517 list
|= (temp
<< 5);
2520 if (flag
& (1 << 28))
2522 if (oprnd
->mask
== OPRND_MASK_0_4
&& (list
& ~OPRND_MASK_0_4
))
2524 SET_ERROR_NUMBER (ERROR_REG_LIST
, NULL
);
2527 csky_insn
.val
[csky_insn
.idx
++] = list
;
2532 is_reg_lshift_illegal (char **oper
, int is_float
)
2537 reg
= csky_get_reg_val (*oper
, &len
);
2540 SET_ERROR_NUMBER (ERROR_REG_FORMAT
, "The register must be r0-r31.");
2545 if ((*oper
)[0] != '<' || (*oper
)[1] != '<')
2547 SET_ERROR_NUMBER (ERROR_UNDEFINE
,
2548 "Operand format error; should be (rx, ry << n)");
2554 char *new_oper
= parse_exp (*oper
, &e
);
2555 if (e
.X_op
== O_constant
)
2558 /* The immediate must be in [0, 3]. */
2559 if (e
.X_add_number
< 0 || e
.X_add_number
> 3)
2561 SET_ERROR_NUMBER (ERROR_IMM_OVERFLOW
, NULL
);
2567 SET_ERROR_NUMBER (ERROR_EXP_CONSTANT
, NULL
);
2571 value
= (reg
<< 2) | e
.X_add_number
;
2573 value
= (reg
<< 5) | (1 << e
.X_add_number
);
2574 csky_insn
.val
[csky_insn
.idx
++] = value
;
2580 is_imm_over_range (char **oper
, int min
, int max
, int ext
)
2583 bfd_boolean ret
= FALSE
;
2584 char *new_oper
= parse_exp (*oper
, &e
);
2585 if (e
.X_op
== O_constant
)
2589 if ((int)e
.X_add_number
!= ext
2590 && (e
.X_add_number
< min
|| e
.X_add_number
> max
))
2593 SET_ERROR_NUMBER (ERROR_IMM_OVERFLOW
, NULL
);
2595 csky_insn
.val
[csky_insn
.idx
++] = e
.X_add_number
;
2602 is_oimm_over_range (char **oper
, int min
, int max
)
2605 bfd_boolean ret
= FALSE
;
2606 char *new_oper
= parse_exp (*oper
, &e
);
2607 if (e
.X_op
== O_constant
)
2611 if (e
.X_add_number
< min
|| e
.X_add_number
> max
)
2614 SET_ERROR_NUMBER (ERROR_IMM_OVERFLOW
, NULL
);
2616 csky_insn
.val
[csky_insn
.idx
++] = e
.X_add_number
- 1;
2623 is_psr_bit (char **oper
)
2625 const struct psrbit
*bits
;
2628 if (IS_CSKY_V1 (mach_flag
))
2629 bits
= cskyv1_psr_bits
;
2631 bits
= cskyv2_psr_bits
;
2633 while (bits
[i
].name
!= NULL
)
2635 if (bits
[i
].isa
&& !(bits
[i
].isa
& isa_flag
))
2640 if (strncasecmp (*oper
, bits
[i
].name
, strlen (bits
[i
].name
)) == 0)
2642 *oper
+= strlen (bits
[i
].name
);
2643 csky_insn
.val
[csky_insn
.idx
] |= bits
[i
].value
;
2648 SET_ERROR_NUMBER (ERROR_OPCODE_PSRBIT
, NULL
);
2653 parse_type_cpidx (char** oper
)
2657 if (s
[0] == 'c' && s
[1] == 'p')
2659 if (ISDIGIT (s
[2]) && ISDIGIT (s
[3]) && ! ISDIGIT (s
[4]))
2661 idx
= (s
[2] - '0') * 10 + s
[3] - '0';
2664 else if (ISDIGIT (s
[2]) && !ISDIGIT (s
[3]))
2675 *oper
= parse_exp (*oper
, &e
);
2676 if (e
.X_op
!= O_constant
)
2678 /* Can not recognize the operand. */
2681 idx
= e
.X_add_number
;
2684 csky_insn
.val
[csky_insn
.idx
++] = idx
;
2690 parse_type_cpreg (char** oper
)
2692 const char **regs
= csky_cp_reg
;
2696 for (i
= 0; i
< (int)(sizeof (csky_cp_reg
) / sizeof (char *)); i
++)
2698 len
= strlen (regs
[i
]);
2699 if (memcmp (*oper
, regs
[i
], len
) == 0 && !ISDIGIT (*(*oper
+ len
)))
2702 csky_insn
.val
[csky_insn
.idx
++] = i
;
2706 SET_ERROR_NUMBER (ERROR_CPREG_ILLEGAL
, *oper
);
2711 parse_type_cpcreg (char** oper
)
2716 regs
= csky_cp_creg
;
2717 for (i
= 0; i
< (int)(sizeof (csky_cp_creg
) / sizeof (char *)); i
++)
2719 len
= strlen (regs
[i
]);
2720 if (memcmp (*oper
, regs
[i
], len
) == 0 && !ISDIGIT (*(*oper
+ len
)))
2723 csky_insn
.val
[csky_insn
.idx
++] = i
;
2727 SET_ERROR_NUMBER (ERROR_CPREG_ILLEGAL
, *oper
);
2732 parse_type_areg (char** oper
)
2736 i
= csky_get_reg_val (*oper
, &len
);
2739 SET_ERROR_NUMBER (ERROR_GREG_ILLEGAL
, NULL
);
2743 csky_insn
.val
[csky_insn
.idx
++] = i
;
2749 parse_type_freg (char** oper
, int even
)
2753 reg
= csky_get_freg_val (*oper
, &len
);
2756 SET_ERROR_NUMBER (ERROR_REG_FORMAT
,
2757 "The fpu register format is not recognized.");
2761 csky_insn
.opcode_end
= *oper
;
2762 if (even
&& reg
& 0x1)
2764 SET_ERROR_NUMBER (ERROR_EXP_EVEN_FREG
, NULL
);
2767 csky_insn
.val
[csky_insn
.idx
++] = reg
;
2772 parse_ldst_imm (char **oper
, struct csky_opcode_info
*op ATTRIBUTE_UNUSED
,
2773 struct operand
*oprnd
)
2775 unsigned int mask
= oprnd
->mask
;
2779 shift
= oprnd
->shift
;
2789 if (**oper
== '\0' || **oper
== ')')
2791 csky_insn
.val
[csky_insn
.idx
++] = 0;
2796 *oper
= parse_exp (*oper
, &e
);
2797 if (e
.X_op
!= O_constant
)
2798 /* Not a constant. */
2800 else if (e
.X_add_number
< 0 || e
.X_add_number
>= max
)
2803 SET_ERROR_NUMBER (ERROR_IMM_OVERFLOW
, NULL
);
2806 if ((e
.X_add_number
% (1 << shift
)) != 0)
2809 SET_ERROR_NUMBER (ERROR_OFFSET_UNALIGNED
, ((unsigned long)1 << shift
));
2813 csky_insn
.val
[csky_insn
.idx
++] = e
.X_add_number
>> shift
;
2820 csky_count_operands (char *str
)
2822 char *oper_end
= str
;
2823 unsigned int oprnd_num
;
2824 int bracket_cnt
= 0;
2826 if (is_end_of_line
[(unsigned char) *oper_end
])
2831 /* Count how many operands. */
2833 while (!is_end_of_line
[(unsigned char) *oper_end
])
2835 if (*oper_end
== '(' || *oper_end
== '<')
2841 if (*oper_end
== ')' || *oper_end
== '>')
2847 if (!bracket_cnt
&& *oper_end
== ',')
2854 /* End of the operand parsing helper functions. */
2856 /* Parse the opcode part of an instruction. Fill in the csky_insn
2857 state and return true on success, false otherwise. */
2860 parse_opcode (char *str
)
2862 #define IS_OPCODE32F(a) (*(a - 2) == '3' && *(a - 1) == '2')
2863 #define IS_OPCODE16F(a) (*(a - 2) == '1' && *(a - 1) == '6')
2865 /* TRUE if this opcode has a suffix, like 'lrw.h'. */
2866 unsigned int has_suffix
= FALSE
;
2867 unsigned int nlen
= 0;
2869 char name
[OPCODE_MAX_LEN
+ 1];
2870 char macro_name
[OPCODE_MAX_LEN
+ 1];
2872 /* Remove space ahead of string. */
2873 while (ISSPACE (*str
))
2877 /* Find the opcode end. */
2878 while (nlen
< OPCODE_MAX_LEN
2879 && !is_end_of_line
[(unsigned char) *opcode_end
]
2880 && *opcode_end
!= ' ')
2882 /* Is csky force 32 or 16 instruction? */
2883 if (IS_CSKY_V2 (mach_flag
)
2884 && *opcode_end
== '.' && has_suffix
== FALSE
)
2887 if (IS_OPCODE32F (opcode_end
))
2889 csky_insn
.flag_force
= INSN_OPCODE32F
;
2892 else if (IS_OPCODE16F (opcode_end
))
2894 csky_insn
.flag_force
= INSN_OPCODE16F
;
2898 name
[nlen
] = *opcode_end
;
2903 /* Is csky force 32 or 16 instruction? */
2904 if (has_suffix
== FALSE
)
2906 if (IS_CSKY_V2 (mach_flag
) && IS_OPCODE32F (opcode_end
))
2908 csky_insn
.flag_force
= INSN_OPCODE32F
;
2911 else if (IS_OPCODE16F (opcode_end
))
2913 csky_insn
.flag_force
= INSN_OPCODE16F
;
2919 /* Generate macro_name for finding hash in macro hash_table. */
2920 if (has_suffix
== TRUE
)
2922 strncpy (macro_name
, str
, nlen
);
2923 macro_name
[nlen
] = '\0';
2925 /* Get csky_insn.opcode_end. */
2926 while (ISSPACE (*opcode_end
))
2928 csky_insn
.opcode_end
= opcode_end
;
2930 /* Count the operands. */
2931 csky_insn
.number
= csky_count_operands (opcode_end
);
2933 /* Find hash by name in csky_macros_hash and csky_opcodes_hash. */
2934 csky_insn
.macro
= (struct csky_macro_info
*) hash_find (csky_macros_hash
,
2936 csky_insn
.opcode
= (struct csky_opcode
*) hash_find (csky_opcodes_hash
,
2939 if (csky_insn
.macro
== NULL
&& csky_insn
.opcode
== NULL
)
2944 /* Main dispatch routine to parse operand OPRND for opcode OP from string
2948 get_operand_value (struct csky_opcode_info
*op
,
2949 char **oper
, struct operand
*oprnd
)
2951 struct soperand
*soprnd
= NULL
;
2952 if (oprnd
->mask
== HAS_SUB_OPERAND
)
2954 /* It has sub operand, it must be like:
2958 We will check the format here. */
2959 soprnd
= (struct soperand
*) oprnd
;
2963 int bracket_cnt
= 0;
2964 if (oprnd
->type
== OPRND_TYPE_BRACKET
)
2969 else if (oprnd
->type
== OPRND_TYPE_ABRACKET
)
2982 SET_ERROR_NUMBER ((oprnd
->type
== OPRND_TYPE_BRACKET
2983 ? ERROR_MISSING_LBRACKET
2984 : ERROR_MISSING_LANGLE_BRACKETS
), NULL
);
2988 /* If the oprnd2 is an immediate, it can not be parsed
2989 that end with ')'/'>'. Modify ')'/'>' to '\0'. */
2990 while ((*s
!= rc
|| bracket_cnt
!= 0) && (*s
!= '\n' && *s
!= '\0'))
3003 SET_ERROR_NUMBER ((oprnd
->type
== OPRND_TYPE_BRACKET
3004 ? ERROR_MISSING_RBRACKET
3005 : ERROR_MISSING_RANGLE_BRACKETS
), NULL
);
3009 if (get_operand_value (op
, oper
, &soprnd
->subs
[0]) == FALSE
)
3016 if (get_operand_value (op
, oper
, &soprnd
->subs
[1]) == FALSE
)
3027 switch (oprnd
->type
)
3029 /* TODO: add opcode type here, log errors in the function.
3030 If REGLIST, then j = csky_insn.number - 1.
3031 If there is needed to parse expressions, it will be
3033 case OPRND_TYPE_CTRLREG
:
3035 return parse_type_ctrlreg (oper
);
3036 case OPRND_TYPE_AREG
:
3037 return parse_type_areg (oper
);
3038 case OPRND_TYPE_FREG
:
3039 case OPRND_TYPE_VREG
:
3040 return parse_type_freg (oper
, 0);
3041 case OPRND_TYPE_FEREG
:
3042 return parse_type_freg (oper
, 1);
3043 case OPRND_TYPE_CPCREG
:
3044 return parse_type_cpcreg (oper
);
3045 case OPRND_TYPE_CPREG
:
3046 return parse_type_cpreg (oper
);
3047 case OPRND_TYPE_CPIDX
:
3048 return parse_type_cpidx (oper
);
3049 case OPRND_TYPE_GREG0_7
:
3050 case OPRND_TYPE_GREG0_15
:
3054 reg
= csky_get_reg_val (*oper
, &len
);
3058 SET_ERROR_NUMBER (ERROR_GREG_ILLEGAL
, NULL
);
3061 else if ((oprnd
->type
== OPRND_TYPE_GREG0_7
&& reg
> 7)
3062 || (oprnd
->type
== OPRND_TYPE_GREG0_15
&& reg
> 15))
3064 SET_ERROR_NUMBER (ERROR_REG_OVER_RANGE
, reg
);
3068 csky_insn
.val
[csky_insn
.idx
++] = reg
;
3071 case OPRND_TYPE_REGnsplr
:
3075 reg
= csky_get_reg_val (*oper
, &len
);
3078 || (IS_CSKY_V1 (mach_flag
)
3079 && (reg
== V1_REG_SP
|| reg
== V1_REG_LR
)))
3081 SET_ERROR_NUMBER (ERROR_REG_OVER_RANGE
, reg
);
3084 csky_insn
.val
[csky_insn
.idx
++] = reg
;
3088 case OPRND_TYPE_REGnr4_r7
:
3094 reg
= csky_get_reg_val (*oper
, &len
);
3095 if (reg
== -1 || (reg
<= 7 && reg
>= 4))
3098 csky_insn
.val
[csky_insn
.idx
++] = reg
;
3105 case OPRND_TYPE_REGr4_r7
:
3106 if (memcmp (*oper
, "r4-r7", sizeof ("r4-r7") - 1) == 0)
3108 *oper
+= sizeof ("r4-r7") - 1;
3109 csky_insn
.val
[csky_insn
.idx
++] = 0;
3112 SET_ERROR_NUMBER (ERROR_OPCODE_ILLEGAL
, NULL
);
3114 case OPRND_TYPE_IMM_LDST
:
3115 return parse_ldst_imm (oper
, op
, oprnd
);
3116 case OPRND_TYPE_IMM_FLDST
:
3117 return parse_ldst_imm (oper
, op
, oprnd
);
3118 case OPRND_TYPE_IMM1b
:
3119 return is_imm_over_range (oper
, 0, 1, -1);
3120 case OPRND_TYPE_IMM2b
:
3121 return is_imm_over_range (oper
, 0, 3, -1);
3122 case OPRND_TYPE_IMM2b_JMPIX
:
3123 /* ck802j support jmpix16, but not support jmpix32. */
3124 if (IS_CSKY_ARCH_802 (mach_flag
)
3125 && (op
->opcode
& 0xffff0000) != 0)
3127 SET_ERROR_NUMBER (ERROR_OPCODE_ILLEGAL
, NULL
);
3130 *oper
= parse_exp (*oper
, &csky_insn
.e1
);
3131 if (csky_insn
.e1
.X_op
== O_constant
)
3133 csky_insn
.opcode_end
= *oper
;
3134 if (csky_insn
.e1
.X_add_number
& 0x7)
3136 SET_ERROR_NUMBER (ERROR_JMPIX_OVER_RANGE
, NULL
);
3139 csky_insn
.val
[csky_insn
.idx
++]
3140 = (csky_insn
.e1
.X_add_number
>> 3) - 2;
3143 case OPRND_TYPE_IMM4b
:
3144 return is_imm_over_range (oper
, 0, 15, -1);
3146 case OPRND_TYPE_IMM5b
:
3147 return is_imm_over_range (oper
, 0, 31, -1);
3148 /* This type for "bgeni" in csky v1 ISA. */
3149 case OPRND_TYPE_IMM5b_7_31
:
3150 if (is_imm_over_range (oper
, 0, 31, -1))
3152 int val
= csky_insn
.val
[csky_insn
.idx
- 1];
3153 /* immediate values of 0 -> 6 translate to movi. */
3156 const char *name
= "movi";
3157 csky_insn
.opcode
= (struct csky_opcode
*)
3158 hash_find (csky_opcodes_hash
, name
);
3159 csky_insn
.val
[csky_insn
.idx
- 1] = 1 << val
;
3166 case OPRND_TYPE_IMM5b_1_31
:
3167 return is_imm_over_range (oper
, 1, 31, -1);
3168 case OPRND_TYPE_IMM5b_POWER
:
3169 if (is_imm_over_range (oper
, 1, ~(1 << 31), 1 << 31))
3172 int val
= csky_insn
.val
[csky_insn
.idx
- 1];
3173 log
= csky_log_2 (val
);
3174 csky_insn
.val
[csky_insn
.idx
- 1] = log
;
3175 return (log
== -1 ? FALSE
: TRUE
);
3180 /* This type for "mgeni" in csky v1 ISA. */
3181 case OPRND_TYPE_IMM5b_7_31_POWER
:
3182 if (is_imm_over_range (oper
, 1, ~(1 << 31), 1 << 31))
3185 int val
= csky_insn
.val
[csky_insn
.idx
- 1];
3186 log
= csky_log_2 (val
);
3187 /* Immediate values of 0 -> 6 translate to movi. */
3190 const char *name
= "movi";
3191 csky_insn
.opcode
= (struct csky_opcode
*)
3192 hash_find (csky_opcodes_hash
, name
);
3193 as_warn (_("translating mgeni to movi"));
3196 csky_insn
.val
[csky_insn
.idx
- 1] = log
;
3197 return (log
== -1 ? FALSE
: TRUE
);
3202 case OPRND_TYPE_IMM5b_RORI
:
3204 unsigned max_shift
= IS_CSKY_V1 (mach_flag
) ? 31 : 32;
3206 if (is_imm_over_range (oper
, 1, max_shift
, -1))
3208 int i
= csky_insn
.idx
- 1;
3209 csky_insn
.val
[i
] = 32 - csky_insn
.val
[i
];
3216 case OPRND_TYPE_IMM5b_BMASKI
:
3217 /* For csky v1 bmask inst. */
3219 if (!is_imm_over_range (oper
, 8, 31, 0))
3221 unsigned int mask_val
= csky_insn
.val
[csky_insn
.idx
- 1];
3222 if (mask_val
> 0 && mask_val
< 8)
3224 const char *op_movi
= "movi";
3225 csky_insn
.opcode
= (struct csky_opcode
*)
3226 hash_find (csky_opcodes_hash
, op_movi
);
3227 if (csky_insn
.opcode
== NULL
)
3229 csky_insn
.val
[csky_insn
.idx
- 1] = (1 << mask_val
) - 1;
3235 case OPRND_TYPE_IMM8b_BMASKI
:
3236 /* For csky v2 bmask, which will transfer to 16bits movi. */
3237 if (is_imm_over_range (oper
, 1, 8, -1))
3239 unsigned int mask_val
= csky_insn
.val
[csky_insn
.idx
- 1];
3240 csky_insn
.val
[csky_insn
.idx
- 1] = (1 << mask_val
) - 1;
3244 case OPRND_TYPE_OIMM4b
:
3245 return is_oimm_over_range (oper
, 1, 16);
3246 case OPRND_TYPE_OIMM5b
:
3247 return is_oimm_over_range (oper
, 1, 32);
3248 case OPRND_TYPE_OIMM5b_IDLY
:
3249 if (is_imm_over_range (oper
, 0, 32, -1))
3251 /* imm5b for idly n: 0<=n<4, imm5b=3; 4<=n<=32, imm5b=n-1. */
3252 unsigned long imm
= csky_insn
.val
[csky_insn
.idx
- 1];
3255 csky_show_error (WARNING_IDLY
, 0, (void *)imm
, NULL
);
3259 csky_insn
.val
[csky_insn
.idx
- 1] = imm
;
3265 /* For csky v2 bmask inst. */
3266 case OPRND_TYPE_OIMM5b_BMASKI
:
3267 if (!is_oimm_over_range (oper
, 17, 32))
3269 int mask_val
= csky_insn
.val
[csky_insn
.idx
- 1];
3270 if (mask_val
+ 1 == 0)
3272 if (mask_val
> 0 && mask_val
< 16)
3274 const char *op_movi
= "movi";
3275 csky_insn
.opcode
= (struct csky_opcode
*)
3276 hash_find (csky_opcodes_hash
, op_movi
);
3277 if (csky_insn
.opcode
== NULL
)
3279 csky_insn
.val
[csky_insn
.idx
- 1] = (1 << (mask_val
+ 1)) - 1;
3284 case OPRND_TYPE_IMM7b
:
3285 return is_imm_over_range (oper
, 0, 127, -1);
3286 case OPRND_TYPE_IMM8b
:
3287 return is_imm_over_range (oper
, 0, 255, -1);
3288 case OPRND_TYPE_IMM12b
:
3289 return is_imm_over_range (oper
, 0, 4095, -1);
3290 case OPRND_TYPE_IMM15b
:
3291 return is_imm_over_range (oper
, 0, 0xfffff, -1);
3292 case OPRND_TYPE_IMM16b
:
3293 return is_imm_over_range (oper
, 0, 65535, -1);
3294 case OPRND_TYPE_OIMM16b
:
3295 return is_oimm_over_range (oper
, 1, 65536);
3296 case OPRND_TYPE_IMM32b
:
3299 char *new_oper
= parse_exp (*oper
, &e
);
3300 if (e
.X_op
== O_constant
)
3303 csky_insn
.val
[csky_insn
.idx
++] = e
.X_add_number
;
3308 case OPRND_TYPE_IMM16b_MOVIH
:
3309 case OPRND_TYPE_IMM16b_ORI
:
3311 bfd_reloc_code_real_type r
= BFD_RELOC_NONE
;
3314 char * save
= input_line_pointer
;
3315 /* get the reloc type, and set "@GOTxxx" as ' ' */
3316 while (**oper
!= '@' && **oper
!= '\0')
3320 input_line_pointer
= *oper
;
3322 while (*(*oper
+ len
+ 1) != '\0')
3324 **oper
= *(*oper
+ len
+ 1);
3325 *(*oper
+ len
+ 1) = '\0';
3330 input_line_pointer
= save
;
3331 *oper
= parse_exp (curr
, &csky_insn
.e1
);
3334 case OPRND_TYPE_PSR_BITS_LIST
:
3337 if (csky_insn
.number
== 0)
3341 csky_insn
.val
[csky_insn
.idx
] = 0;
3342 if (is_psr_bit (oper
) != FALSE
)
3343 while (**oper
== ',')
3346 if (is_psr_bit (oper
) == FALSE
)
3354 if (ret
== TRUE
&& IS_CSKY_V1 (mach_flag
)
3355 && csky_insn
.val
[csky_insn
.idx
] > 8)
3359 SET_ERROR_NUMBER (ERROR_OPERANDS_ILLEGAL
, csky_insn
.opcode_end
);
3364 /* FPU round mode. */
3365 static const char *round_mode
[] =
3374 for (i
= 0; round_mode
[i
]; i
++)
3375 if (strncasecmp (*oper
, round_mode
[i
], strlen (round_mode
[i
])) == 0)
3377 *oper
+= strlen (round_mode
[i
]);
3378 csky_insn
.val
[csky_insn
.idx
++] = i
;
3384 case OPRND_TYPE_REGLIST_COMMA
:
3385 case OPRND_TYPE_BRACKET
:
3386 /* TODO: using sub operand union. */
3387 case OPRND_TYPE_ABRACKET
:
3388 /* TODO: using sub operand union. */
3389 case OPRND_TYPE_REGLIST_DASH
:
3390 return is_reglist_legal (oper
);
3391 case OPRND_TYPE_FREGLIST_DASH
:
3392 return is_freglist_legal (oper
);
3393 case OPRND_TYPE_AREG_WITH_BRACKET
:
3399 SET_ERROR_NUMBER (ERROR_MISSING_LBRACKET
, NULL
);
3403 reg
= csky_get_reg_val (*oper
, &len
);
3406 SET_ERROR_NUMBER (ERROR_EXP_GREG
, NULL
);
3412 SET_ERROR_NUMBER (ERROR_MISSING_RBRACKET
, NULL
);
3416 csky_insn
.val
[csky_insn
.idx
++] = reg
;
3419 case OPRND_TYPE_REGsp
:
3420 return is_reg_sp (oper
);
3421 case OPRND_TYPE_REGbsp
:
3422 return is_reg_sp_with_bracket (oper
);
3424 case OPRND_TYPE_OFF8b
:
3425 case OPRND_TYPE_OFF16b
:
3426 *oper
= parse_rt (*oper
, 1, &csky_insn
.e1
, -1);
3427 csky_insn
.val
[csky_insn
.idx
++] = 0;
3429 case OPRND_TYPE_LABEL_WITH_BRACKET
:
3430 case OPRND_TYPE_CONSTANT
:
3431 case OPRND_TYPE_ELRW_CONSTANT
:
3433 csky_insn
.val
[csky_insn
.idx
++] = 0;
3435 csky_insn
.val
[csky_insn
.idx
++] = NEED_OUTPUT_LITERAL
;
3436 *oper
= parse_rt (*oper
, 0, &csky_insn
.e1
, -1);
3438 case OPRND_TYPE_FCONSTANT
:
3439 *oper
= parse_rtf (*oper
, 0, &csky_insn
.e1
);
3442 case OPRND_TYPE_SFLOAT
:
3443 case OPRND_TYPE_DFLOAT
:
3444 /* For fmovis and fmovid, which accept a constant float with
3450 *oper
= parse_fexp (*oper
, &csky_insn
.e1
, 1, &dbnum
);
3451 if (csky_insn
.e1
.X_op
== O_absent
)
3454 /* Convert the representation from IEEE double to the 13-bit
3455 encoding used internally for fmovis and fmovid. */
3456 imm4
= 11 - (((dbnum
& 0x7ff0000000000000ULL
) >> 52) - 1023);
3457 /* Check float range. */
3458 if ((dbnum
& 0x00000fffffffffffULL
) || imm4
< 0 || imm4
> 15)
3460 csky_show_error (ERROR_IMM_OVERFLOW
, 2, NULL
, NULL
);
3463 imm8
= (dbnum
& 0x000ff00000000000ULL
) >> 44;
3464 csky_insn
.e1
.X_add_number
3465 = (((imm8
& 0xf) << 4)
3466 | ((imm8
& 0xf0) << 17)
3467 | ((imm4
& 0xf) << 16)
3468 | ((dbnum
& 0x8000000000000000ULL
) >> 43));
3473 case OPRND_TYPE_IMM_OFF18b
:
3474 *oper
= parse_exp (*oper
, &csky_insn
.e1
);
3477 case OPRND_TYPE_BLOOP_OFF4b
:
3478 *oper
= parse_exp (*oper
, &csky_insn
.e2
);
3479 if (csky_insn
.e2
.X_op
== O_symbol
)
3481 csky_insn
.opcode_end
= *oper
;
3487 case OPRND_TYPE_BLOOP_OFF12b
:
3488 case OPRND_TYPE_OFF10b
:
3489 case OPRND_TYPE_OFF11b
:
3490 case OPRND_TYPE_OFF16b_LSL1
:
3491 case OPRND_TYPE_OFF26b
:
3492 *oper
= parse_exp (*oper
, &csky_insn
.e1
);
3493 if (csky_insn
.e1
.X_op
== O_symbol
)
3495 csky_insn
.opcode_end
= *oper
;
3500 /* For xtrb0(1)(2)(3) and div in csky v1 ISA. */
3501 case OPRND_TYPE_REG_r1a
:
3505 reg
= csky_get_reg_val (*oper
, &len
);
3508 SET_ERROR_NUMBER (ERROR_REG_FORMAT
,
3509 "The first operand must be register r1.");
3513 mov_r1_after
= TRUE
;
3515 csky_insn
.opcode_end
= *oper
;
3516 csky_insn
.val
[csky_insn
.idx
++] = reg
;
3519 case OPRND_TYPE_REG_r1b
:
3523 reg
= csky_get_reg_val (*oper
, &len
);
3526 SET_ERROR_NUMBER (ERROR_REG_FORMAT
,
3527 "The second operand must be register r1.");
3532 unsigned int mov_insn
= CSKYV1_INST_MOV_R1_RX
;
3533 mov_insn
|= reg
<< 4;
3534 mov_r1_before
= TRUE
;
3535 csky_insn
.output
= frag_more (2);
3536 dwarf2_emit_insn (0);
3537 md_number_to_chars (csky_insn
.output
, mov_insn
, 2);
3540 csky_insn
.opcode_end
= *oper
;
3541 csky_insn
.val
[csky_insn
.idx
++] = reg
;
3544 case OPRND_TYPE_DUMMY_REG
:
3548 reg
= csky_get_reg_val (*oper
, &len
);
3551 SET_ERROR_NUMBER (ERROR_GREG_ILLEGAL
, NULL
);
3554 if (reg
!= csky_insn
.val
[0])
3556 SET_ERROR_NUMBER (ERROR_REG_FORMAT
,
3557 "The second register must be the same as the first.");
3561 csky_insn
.opcode_end
= *oper
;
3562 csky_insn
.val
[csky_insn
.idx
++] = reg
;
3565 case OPRND_TYPE_2IN1_DUMMY
:
3571 reg
= csky_get_reg_val (*oper
, &len
);
3574 SET_ERROR_NUMBER (ERROR_GREG_ILLEGAL
, NULL
);
3577 /* dummy reg's real type should be same with first operand. */
3578 if (op
->oprnd
.oprnds
[0].type
== OPRND_TYPE_GREG0_15
)
3580 else if (op
->oprnd
.oprnds
[0].type
== OPRND_TYPE_GREG0_7
)
3584 if (reg
< min
|| reg
> max
)
3586 csky_insn
.val
[csky_insn
.idx
++] = reg
;
3587 /* if it is the last operands. */
3588 if (csky_insn
.idx
> 2)
3590 /* For "insn rz, rx, ry", if rx or ry is equal to rz,
3591 we can output the insn like "insn rz, rx". */
3592 if (csky_insn
.val
[0] == csky_insn
.val
[1])
3593 csky_insn
.val
[1] = 0;
3594 else if (csky_insn
.val
[0] == csky_insn
.val
[2])
3595 csky_insn
.val
[2] = 0;
3600 csky_insn
.opcode_end
= *oper
;
3603 case OPRND_TYPE_DUP_GREG0_7
:
3604 case OPRND_TYPE_DUP_GREG0_15
:
3605 case OPRND_TYPE_DUP_AREG
:
3610 unsigned int shift_num
;
3611 if (oprnd
->type
== OPRND_TYPE_DUP_GREG0_7
)
3616 else if (oprnd
->type
== OPRND_TYPE_DUP_GREG0_15
)
3626 reg
= csky_get_reg_val (*oper
, &len
);
3630 SET_ERROR_NUMBER (ERROR_REG_FORMAT
,
3631 "The register must be r0-r31");
3633 SET_ERROR_NUMBER (ERROR_REG_FORMAT
,
3634 "The register must be r0-r15");
3639 SET_ERROR_NUMBER (ERROR_REG_OVER_RANGE
, reg
);
3642 reg
|= reg
<< shift_num
;
3644 csky_insn
.opcode_end
= *oper
;
3645 csky_insn
.val
[csky_insn
.idx
++] = reg
;
3648 case OPRND_TYPE_CONST1
:
3649 *oper
= parse_exp (*oper
, &csky_insn
.e1
);
3650 if (csky_insn
.e1
.X_op
== O_constant
)
3652 csky_insn
.opcode_end
= *oper
;
3653 if (csky_insn
.e1
.X_add_number
!= 1)
3655 csky_insn
.val
[csky_insn
.idx
++] = 1;
3659 case OPRND_TYPE_UNCOND10b
:
3660 case OPRND_TYPE_UNCOND16b
:
3661 *oper
= parse_exp (*oper
, &csky_insn
.e1
);
3662 if (csky_insn
.e1
.X_op
== O_constant
)
3664 input_line_pointer
= *oper
;
3665 csky_insn
.opcode_end
= *oper
;
3666 csky_insn
.relax
.max
= UNCD_DISP16_LEN
;
3667 csky_insn
.relax
.var
= UNCD_DISP10_LEN
;
3668 csky_insn
.relax
.subtype
= UNCD_DISP10
;
3669 csky_insn
.val
[csky_insn
.idx
++] = 0;
3671 case OPRND_TYPE_COND10b
:
3672 case OPRND_TYPE_COND16b
:
3673 *oper
= parse_exp (*oper
, &csky_insn
.e1
);
3674 if (csky_insn
.e1
.X_op
== O_constant
)
3676 input_line_pointer
= *oper
;
3677 csky_insn
.opcode_end
= *oper
;
3678 /* CK801 doesn't have 32-bit bt/bf insns; relax to a short
3679 jump around a 32-bit unconditional branch instead. */
3680 if (IS_CSKY_ARCH_801 (mach_flag
))
3682 csky_insn
.relax
.max
= SCOND_DISP16_LEN
;
3683 csky_insn
.relax
.var
= SCOND_DISP10_LEN
;
3684 csky_insn
.relax
.subtype
= SCOND_DISP10
;
3688 csky_insn
.relax
.max
= COND_DISP16_LEN
;
3689 csky_insn
.relax
.var
= COND_DISP10_LEN
;
3690 csky_insn
.relax
.subtype
= COND_DISP10
;
3692 csky_insn
.val
[csky_insn
.idx
++] = 0;
3694 case OPRND_TYPE_JCOMPZ
:
3695 *oper
= parse_exp (*oper
, &csky_insn
.e1
);
3696 if (csky_insn
.e1
.X_op
== O_constant
)
3698 input_line_pointer
= *oper
;
3699 csky_insn
.opcode_end
= *oper
;
3700 csky_insn
.relax
.max
= JCOMPZ_DISP32_LEN
;
3701 csky_insn
.relax
.var
= JCOMPZ_DISP16_LEN
;
3702 csky_insn
.relax
.subtype
= JCOMPZ_DISP16
;
3703 csky_insn
.max
= JCOMPZ_DISP32_LEN
;
3704 csky_insn
.val
[csky_insn
.idx
++] = 0;
3706 case OPRND_TYPE_JBTF
:
3707 *oper
= parse_exp (*oper
, &csky_insn
.e1
);
3708 input_line_pointer
= *oper
;
3709 csky_insn
.opcode_end
= *oper
;
3710 csky_insn
.relax
.max
= csky_relax_table
[C (COND_JUMP_S
, DISP32
)].rlx_length
;
3711 csky_insn
.relax
.var
= csky_relax_table
[C (COND_JUMP_S
, DISP12
)].rlx_length
;
3712 csky_insn
.relax
.subtype
= C (COND_JUMP_S
, 0);
3713 csky_insn
.val
[csky_insn
.idx
++] = 0;
3714 csky_insn
.max
= C32_LEN_S
+ 2;
3716 case OPRND_TYPE_JBR
:
3717 *oper
= parse_exp (*oper
, &csky_insn
.e1
);
3718 input_line_pointer
= *oper
;
3719 csky_insn
.opcode_end
= *oper
;
3720 csky_insn
.relax
.max
= csky_relax_table
[C (UNCD_JUMP_S
, DISP32
)].rlx_length
;
3721 csky_insn
.relax
.var
= csky_relax_table
[C (UNCD_JUMP_S
, DISP12
)].rlx_length
;
3722 csky_insn
.relax
.subtype
= C (UNCD_JUMP_S
, 0);
3723 csky_insn
.val
[csky_insn
.idx
++] = 0;
3724 csky_insn
.max
= U32_LEN_S
+ 2;
3726 case OPRND_TYPE_JBSR
:
3728 *oper
= parse_exp (*oper
, &csky_insn
.e1
);
3730 *oper
= parse_rt (*oper
, 1, &csky_insn
.e1
, -1);
3731 input_line_pointer
= *oper
;
3732 csky_insn
.opcode_end
= *oper
;
3733 csky_insn
.val
[csky_insn
.idx
++] = 0;
3735 case OPRND_TYPE_REGLIST_DASH_COMMA
:
3736 return is_reglist_dash_comma_legal (oper
, oprnd
);
3738 case OPRND_TYPE_MSB2SIZE
:
3739 case OPRND_TYPE_LSB2SIZE
:
3742 char *new_oper
= parse_exp (*oper
, &e
);
3743 if (e
.X_op
== O_constant
)
3746 if (e
.X_add_number
> 31)
3748 SET_ERROR_NUMBER (ERROR_IMM_OVERFLOW
, NULL
);
3751 csky_insn
.val
[csky_insn
.idx
++] = e
.X_add_number
;
3752 if (oprnd
->type
== OPRND_TYPE_LSB2SIZE
)
3754 if (csky_insn
.val
[csky_insn
.idx
- 1] > csky_insn
.val
[csky_insn
.idx
- 2])
3756 SET_ERROR_NUMBER (ERROR_IMM_OVERFLOW
, NULL
);
3759 csky_insn
.val
[csky_insn
.idx
- 2] -= e
.X_add_number
;
3765 case OPRND_TYPE_AREG_WITH_LSHIFT
:
3766 return is_reg_lshift_illegal (oper
, 0);
3767 case OPRND_TYPE_AREG_WITH_LSHIFT_FPU
:
3768 return is_reg_lshift_illegal (oper
, 1);
3769 case OPRND_TYPE_FREG_WITH_INDEX
:
3770 if (parse_type_freg (oper
, 0))
3775 if (is_imm_over_range (oper
, 0, 0xf, -1))
3779 unsigned int idx
= --csky_insn
.idx
;
3780 unsigned int val
= csky_insn
.val
[idx
];
3782 csky_insn
.val
[idx
- 1] |= val
<< 4;
3786 SET_ERROR_NUMBER (ERROR_MISSING_RSQUARE_BRACKETS
, NULL
);
3790 SET_ERROR_NUMBER (ERROR_MISSING_LSQUARE_BRACKETS
, NULL
);
3801 /* Subroutine of parse_operands. */
3804 parse_operands_op (char *str
, struct csky_opcode_info
*op
)
3811 for (i
= 0; i
< OP_TABLE_NUM
&& op
[i
].operand_num
!= -2; i
++)
3816 /* if operand_num = -1, it is a insn with a REGLIST type operand.i. */
3817 if (!(op
[i
].operand_num
== csky_insn
.number
3818 || (op
[i
].operand_num
== -1 && csky_insn
.number
!= 0)))
3820 /* The smaller err_num is more serious. */
3821 SET_ERROR_NUMBER (ERROR_OPERANDS_NUMBER
, op
[i
].operand_num
);
3826 for (j
= 0; j
< csky_insn
.number
; j
++)
3828 while (ISSPACE (*oper
))
3830 flag_pass
= get_operand_value (&op
[i
], &oper
,
3831 &op
[i
].oprnd
.oprnds
[j
]);
3832 if (flag_pass
== FALSE
)
3834 while (ISSPACE (*oper
))
3837 if (j
< csky_insn
.number
- 1 && op
[i
].operand_num
!= -1)
3843 SET_ERROR_NUMBER (ERROR_MISSING_COMMA
, NULL
);
3848 else if (!is_end_of_line
[(unsigned char) *oper
])
3850 SET_ERROR_NUMBER (ERROR_BAD_END
, NULL
);
3857 /* Parse operands in one table end. */
3859 if (flag_pass
== TRUE
)
3861 /* Parse operands success, set opcode_idx. */
3862 csky_insn
.opcode_idx
= i
;
3866 error_state
.opnum
= j
+ 1;
3868 /* Parse operands in ALL tables end. */
3872 /* Parse the operands according to operand type. */
3875 parse_operands (char *str
)
3879 /* Parse operands according to flag_force. */
3880 if (csky_insn
.flag_force
== INSN_OPCODE16F
3881 && (csky_insn
.opcode
->isa_flag16
& isa_flag
) != 0)
3883 if (parse_operands_op (oper
, csky_insn
.opcode
->op16
) == TRUE
)
3885 csky_insn
.isize
= 2;
3890 else if (csky_insn
.flag_force
== INSN_OPCODE32F
3891 && (csky_insn
.opcode
->isa_flag32
& isa_flag
) != 0)
3893 if (parse_operands_op (oper
, csky_insn
.opcode
->op32
) == TRUE
)
3895 csky_insn
.isize
= 4;
3902 if ((csky_insn
.opcode
->isa_flag16
& isa_flag
) != 0
3903 && parse_operands_op (oper
, csky_insn
.opcode
->op16
) == TRUE
)
3905 csky_insn
.isize
= 2;
3908 if ((csky_insn
.opcode
->isa_flag32
& isa_flag
) != 0
3909 && parse_operands_op (oper
, csky_insn
.opcode
->op32
) == TRUE
)
3911 csky_insn
.isize
= 4;
3919 csky_generate_frags (void)
3921 /* frag more relax reloc. */
3922 if (csky_insn
.flag_force
== INSN_OPCODE16F
3923 || !IS_SUPPORT_OPCODE32 (csky_insn
.opcode
))
3925 csky_insn
.output
= frag_more (csky_insn
.isize
);
3926 if (csky_insn
.opcode
->reloc16
)
3928 /* 16 bits opcode force, should generate fixup. */
3929 reloc_howto_type
*howto
;
3930 howto
= bfd_reloc_type_lookup (stdoutput
,
3931 csky_insn
.opcode
->reloc16
);
3932 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
3933 2, &csky_insn
.e1
, howto
->pc_relative
,
3934 csky_insn
.opcode
->reloc16
);
3937 else if (csky_insn
.flag_force
== INSN_OPCODE32F
)
3939 csky_insn
.output
= frag_more (csky_insn
.isize
);
3940 if (csky_insn
.opcode
->reloc32
)
3942 reloc_howto_type
*howto
;
3943 howto
= bfd_reloc_type_lookup (stdoutput
,
3944 csky_insn
.opcode
->reloc32
);
3945 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
3946 4, &csky_insn
.e1
, howto
->pc_relative
,
3947 csky_insn
.opcode
->reloc32
);
3950 else if (csky_insn
.opcode
->relax
)
3951 /* Generate the relax information. */
3952 csky_insn
.output
= frag_var (rs_machine_dependent
,
3953 csky_insn
.relax
.max
,
3954 csky_insn
.relax
.var
,
3955 csky_insn
.relax
.subtype
,
3956 csky_insn
.e1
.X_add_symbol
,
3957 csky_insn
.e1
.X_add_number
, 0);
3960 csky_insn
.output
= frag_more (csky_insn
.isize
);
3961 if (csky_insn
.opcode
->reloc16
&& csky_insn
.isize
== 2)
3963 reloc_howto_type
*howto
;
3964 howto
= bfd_reloc_type_lookup (stdoutput
,
3965 csky_insn
.opcode
->reloc16
);
3966 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
3967 2, &csky_insn
.e1
, howto
->pc_relative
,
3968 csky_insn
.opcode
->reloc16
);
3970 else if (csky_insn
.opcode
->reloc32
&& csky_insn
.isize
== 4)
3972 reloc_howto_type
*howto
;
3973 howto
= bfd_reloc_type_lookup (stdoutput
,
3974 csky_insn
.opcode
->reloc32
);
3975 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
3976 4, &csky_insn
.e1
, howto
->pc_relative
,
3977 csky_insn
.opcode
->reloc32
);
3983 /* Return the bits of VAL shifted according to MASK. The bits of MASK
3984 need not be contiguous. */
3987 generate_masked_value (int mask
, int val
)
3992 for (bit
= 1; mask
; bit
= bit
<< 1)
4003 /* Return the result of masking operand number OPRND_IDX into the
4004 instruction word according to the information in OPRND. */
4007 generate_masked_operand (struct operand
*oprnd
, int *oprnd_idx
)
4009 struct soperand
*soprnd
= NULL
;
4012 if ((unsigned int)oprnd
->mask
== HAS_SUB_OPERAND
)
4014 soprnd
= (struct soperand
*) oprnd
;
4015 generate_masked_operand (&soprnd
->subs
[0], oprnd_idx
);
4016 generate_masked_operand (&soprnd
->subs
[1], oprnd_idx
);
4020 val
= csky_insn
.val
[*oprnd_idx
];
4022 val
= generate_masked_value (mask
, val
);
4023 csky_insn
.inst
|= val
;
4029 csky_generate_insn (void)
4032 struct csky_opcode_info
*opinfo
= NULL
;
4034 if (csky_insn
.isize
== 4)
4035 opinfo
= &csky_insn
.opcode
->op32
[csky_insn
.opcode_idx
];
4036 else if (csky_insn
.isize
== 2)
4037 opinfo
= &csky_insn
.opcode
->op16
[csky_insn
.opcode_idx
];
4040 csky_insn
.inst
= opinfo
->opcode
;
4041 if (opinfo
->operand_num
== -1)
4043 generate_masked_operand (&opinfo
->oprnd
.oprnds
[i
], &sidx
);
4047 for (i
= 0; i
< opinfo
->operand_num
; i
++)
4048 generate_masked_operand (&opinfo
->oprnd
.oprnds
[i
], &sidx
);
4052 /* Main entry point for assembling a single instruction. */
4055 md_assemble (char *str
)
4057 bfd_boolean must_check_literals
= TRUE
;
4058 csky_insn
.isize
= 0;
4061 csky_insn
.flag_force
= INSN_OPCODE
;
4062 csky_insn
.macro
= NULL
;
4063 csky_insn
.opcode
= NULL
;
4064 memset (csky_insn
.val
, 0, sizeof (int) * MAX_OPRND_NUM
);
4065 /* Initialize err_num. */
4066 error_state
.err_num
= ERROR_NONE
;
4067 mov_r1_before
= FALSE
;
4068 mov_r1_after
= FALSE
;
4070 mapping_state (MAP_TEXT
);
4071 /* Tie dwarf2 debug info to every insn if set option --gdwarf2. */
4072 dwarf2_emit_insn (0);
4073 while (ISSPACE (* str
))
4075 /* Get opcode from str. */
4076 if (parse_opcode (str
) == FALSE
)
4078 csky_show_error (ERROR_OPCODE_ILLEGAL
, 0, NULL
, NULL
);
4082 /* If it is a macro instruction, handle it. */
4083 if (csky_insn
.macro
!= NULL
)
4085 if (csky_insn
.number
== csky_insn
.macro
->oprnd_num
)
4087 csky_insn
.macro
->handle_func ();
4090 else if (error_state
.err_num
> ERROR_OPERANDS_NUMBER
)
4091 SET_ERROR_NUMBER (ERROR_OPERANDS_NUMBER
, csky_insn
.macro
->oprnd_num
);
4094 if (csky_insn
.opcode
== NULL
)
4096 SET_ERROR_NUMBER (ERROR_OPCODE_ILLEGAL
, NULL
);
4097 csky_show_error (error_state
.err_num
, error_state
.opnum
,
4098 (void *)error_state
.arg1
, (void *)error_state
.arg1
);
4102 /* Parse the operands according to operand type. */
4103 if (parse_operands (csky_insn
.opcode_end
) == FALSE
)
4105 csky_show_error (error_state
.err_num
, error_state
.opnum
,
4106 (void *)error_state
.arg1
, (void *)error_state
.arg1
);
4110 /* if this insn has work in opcode table, then do it. */
4111 if (csky_insn
.opcode
->work
!= NULL
)
4112 must_check_literals
= csky_insn
.opcode
->work ();
4115 /* Generate relax or reloc if necessary. */
4116 csky_generate_frags ();
4117 /* Generate the insn by mask. */
4118 csky_generate_insn ();
4119 /* Write inst to frag. */
4120 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
4123 /* Adjust for xtrb0/xtrb1/xtrb2/xtrb3/divs/divu in csky v1 ISA. */
4124 if (mov_r1_after
== TRUE
)
4126 unsigned int mov_insn
= CSKYV1_INST_MOV_RX_R1
;
4127 mov_insn
|= csky_insn
.val
[0];
4128 mov_r1_before
= TRUE
;
4129 csky_insn
.output
= frag_more (2);
4130 dwarf2_emit_insn (0);
4131 md_number_to_chars (csky_insn
.output
, mov_insn
, 2);
4132 csky_insn
.isize
+= 2;
4134 if (mov_r1_before
== TRUE
)
4135 csky_insn
.isize
+= 2;
4137 /* Check literal. */
4138 if (must_check_literals
)
4140 if (csky_insn
.max
== 0)
4141 check_literals (csky_insn
.opcode
->transfer
, csky_insn
.isize
);
4143 check_literals (csky_insn
.opcode
->transfer
, csky_insn
.max
);
4146 insn_reloc
= BFD_RELOC_NONE
;
4149 /* Attempt to handle option with value C, returning non-zero on success. */
4152 md_parse_option (int c
, const char *arg
)
4170 /* Convert a machine dependent frag. */
4171 #define PAD_LITERAL_LENGTH 6
4172 #define opposite_of_stored_comp(insn) (insn ^ 0x04000000)
4173 #define opposite_of_stored_compz(insn) (insn ^ 0x00200000)
4174 #define make_insn(total_length, opcode, operand, operand_length) \
4176 if (total_length > 0) \
4178 csky_write_insn (buf, \
4179 opcode | (operand & ((1 << operand_length) - 1)), \
4181 buf += total_length; \
4182 fragp->fr_fix += total_length; \
4186 #define make_literal(fragp, literal_offset) \
4188 make_insn (literal_offset, PAD_FILL_CONTENT, 0, 0); \
4189 fix_new (fragp, fragp->fr_fix, 4, fragp->fr_symbol, \
4190 fragp->fr_offset, 0, BFD_RELOC_CKCORE_ADDR32); \
4191 make_insn (4, 0, 0, 0); \
4192 make_insn (2 - literal_offset, PAD_FILL_CONTENT, 0, 0); \
4196 md_convert_frag (bfd
*abfd ATTRIBUTE_UNUSED
, segT asec
, fragS
*fragp
)
4199 char *buf
= fragp
->fr_fix
+ fragp
->fr_literal
;
4201 gas_assert (fragp
->fr_symbol
);
4202 if (IS_EXTERNAL_SYM (fragp
->fr_symbol
, asec
))
4205 disp
= (S_GET_VALUE (fragp
->fr_symbol
)
4210 switch (fragp
->fr_subtype
)
4212 /* generate new insn. */
4213 case C (COND_JUMP
, DISP12
):
4214 case C (UNCD_JUMP
, DISP12
):
4215 case C (COND_JUMP_PIC
, DISP12
):
4216 case C (UNCD_JUMP_PIC
, DISP12
):
4218 #define CSKY_V1_B_MASK 0xf8
4223 /* Error. odd displacement at %x, next_inst-2. */
4228 if (!target_big_endian
)
4230 t0
= buf
[1] & CSKY_V1_B_MASK
;
4231 md_number_to_chars (buf
, disp
, 2);
4232 buf
[1] = (buf
[1] & ~CSKY_V1_B_MASK
) | t0
;
4236 t0
= buf
[0] & CSKY_V1_B_MASK
;
4237 md_number_to_chars (buf
, disp
, 2);
4238 buf
[0] = (buf
[0] & ~CSKY_V1_B_MASK
) | t0
;
4243 case C (COND_JUMP
, DISP32
):
4244 case C (COND_JUMP
, UNDEF_WORD_DISP
):
4246 /* A conditional branch wont fit into 12 bits:
4253 int first_inst
= fragp
->fr_fix
+ fragp
->fr_address
;
4254 int is_unaligned
= (first_inst
& 3);
4256 if (!target_big_endian
)
4258 /* b!cond instruction. */
4260 /* jmpi instruction. */
4261 buf
[2] = CSKYV1_INST_JMPI
& 0xff;
4262 buf
[3] = CSKYV1_INST_JMPI
>> 8;
4266 /* b!cond instruction. */
4268 /* jmpi instruction. */
4269 buf
[2] = CSKYV1_INST_JMPI
>> 8;
4270 buf
[3] = CSKYV1_INST_JMPI
& 0xff;
4275 if (!target_big_endian
)
4277 /* bt/bf: jump to pc + 2 + (4 << 1). */
4279 /* jmpi: jump to MEM (pc + 2 + (1 << 2)). */
4284 /* bt/bf: jump to pc + 2 + (4 << 1). */
4286 /* jmpi: jump to MEM (pc + 2 + (1 << 2)). */
4289 /* Aligned 4 bytes. */
4298 /* Make reloc for the long disp. */
4299 fix_new (fragp
, fragp
->fr_fix
+ 6, 4,
4300 fragp
->fr_symbol
, fragp
->fr_offset
, 0, BFD_RELOC_32
);
4301 fragp
->fr_fix
+= C32_LEN
;
4305 if (!target_big_endian
)
4307 /* bt/bf: jump to pc + 2 + (3 << 1). */
4309 /* jmpi: jump to MEM (pc + 2 + (0 << 2)). */
4314 /* bt/bf: jump to pc + 2 + (3 << 1). */
4316 /* jmpi: jump to MEM (pc + 2 + (0 << 2)). */
4325 /* Make reloc for the long disp. */
4326 fix_new (fragp
, fragp
->fr_fix
+ 4, 4,
4327 fragp
->fr_symbol
, fragp
->fr_offset
, 0, BFD_RELOC_32
);
4328 fragp
->fr_fix
+= C32_LEN
;
4330 /* Frag is actually shorter (see the other side of this ifdef)
4331 but gas isn't prepared for that. We have to re-adjust
4332 the branch displacement so that it goes beyond the
4333 full length of the fragment, not just what we actually
4335 if (!target_big_endian
)
4343 case C (COND_JUMP_PIC
, DISP32
):
4344 case C (COND_JUMP_PIC
, UNDEF_WORD_DISP
):
4346 #define BYTE_1(a) (target_big_endian ? ((a) & 0xff) : ((a) >> 8))
4347 #define BYTE_0(a) (target_big_endian ? ((a) >> 8) : ((a) & 0xff))
4358 0: .long (tar_addr - pc)
4361 int first_inst
= fragp
->fr_fix
+ fragp
->fr_address
;
4362 int is_unaligned
= (first_inst
& 3);
4364 /* Toggle T/F bit. */
4365 if (! target_big_endian
)
4369 buf
[2] = BYTE_0 (CSKYV1_INST_SUBI
| (7 << 4)); /* subi r0, 8. */
4370 buf
[3] = BYTE_1 (CSKYV1_INST_SUBI
| (7 << 4));
4371 buf
[4] = BYTE_0 (CSKYV1_INST_STW
| (15 << 8)); /* stw r15, r0. */
4372 buf
[5] = BYTE_1 (CSKYV1_INST_STW
| (15 << 8));
4373 buf
[6] = BYTE_0 (CSKYV1_INST_BSR
); /* bsr pc + 2. */
4374 buf
[7] = BYTE_1 (CSKYV1_INST_BSR
);
4375 buf
[8] = BYTE_0 (CSKYV1_INST_LRW
| (1 << 8)); /* lrw r1, (tar_addr - pc). */
4376 buf
[9] = BYTE_1 (CSKYV1_INST_LRW
| (1 << 8));
4377 buf
[10] = BYTE_0 (CSKYV1_INST_ADDU
| (15 << 4) | 1); /* add r1, r15. */
4378 buf
[11] = BYTE_1 (CSKYV1_INST_ADDU
| (15 << 4) | 1);
4379 buf
[12] = BYTE_0 (CSKYV1_INST_LDW
| (15 << 8)); /* ldw r15, r0. */
4380 buf
[13] = BYTE_1 (CSKYV1_INST_LDW
| (15 << 8));
4381 buf
[14] = BYTE_0 (CSKYV1_INST_ADDI
| (7 << 4)); /* addi r0, 8. */
4382 buf
[15] = BYTE_1 (CSKYV1_INST_ADDI
| (7 << 4));
4383 buf
[16] = BYTE_0 (CSKYV1_INST_JMP
| 1); /* jmp r1. */
4384 buf
[17] = BYTE_1 (CSKYV1_INST_JMP
| 1);
4388 if (!target_big_endian
)
4392 buf
[20] = disp
& 0xff;
4393 buf
[21] = (disp
>> 8) & 0xff;
4394 buf
[22] = (disp
>> 16) & 0xff;
4395 buf
[23] = (disp
>> 24) & 0xff;
4397 else /* if !target_big_endian. */
4401 buf
[20] = (disp
>> 24) & 0xff;
4402 buf
[21] = (disp
>> 16) & 0xff;
4403 buf
[22] = (disp
>> 8) & 0xff;
4404 buf
[23] = disp
& 0xff;
4406 buf
[18] = 0; /* alignment. */
4408 fragp
->fr_fix
+= C32_LEN_PIC
;
4410 else /* if !is_unaligned. */
4412 if (!target_big_endian
)
4416 buf
[18] = disp
& 0xff;
4417 buf
[19] = (disp
>> 8) & 0xff;
4418 buf
[20] = (disp
>> 16) & 0xff;
4419 buf
[21] = (disp
>> 24) & 0xff;
4421 else /* if !target_big_endian. */
4425 buf
[18] = (disp
>> 24) & 0xff;
4426 buf
[19] = (disp
>> 16) & 0xff;
4427 buf
[20] = (disp
>> 8) & 0xff;
4428 buf
[21] = disp
& 0xff;
4430 fragp
->fr_fix
+= C32_LEN_PIC
;
4432 } /* end if is_unaligned. */
4433 } /* end case C (COND_JUMP_PIC, DISP32)/C (COND_JUMP_PIC, UNDEF_WORD_DISP). */
4435 case C (UNCD_JUMP
, DISP32
):
4436 case C (UNCD_JUMP
, UNDEF_WORD_DISP
):
4441 int first_inst
= fragp
->fr_fix
+ fragp
->fr_address
;
4442 int is_unaligned
= (first_inst
& 3);
4444 buf
[0] = BYTE_0 (CSKYV1_INST_JMPI
);
4445 buf
[1] = BYTE_1 (CSKYV1_INST_JMPI
);
4448 if (!target_big_endian
)
4460 fix_new (fragp
, fragp
->fr_fix
+ 4, 4,
4461 fragp
->fr_symbol
, fragp
->fr_offset
, 0, BFD_RELOC_32
);
4462 fragp
->fr_fix
+= U32_LEN
;
4464 else /* if is_unaligned. */
4466 if (!target_big_endian
)
4475 fix_new (fragp
, fragp
->fr_fix
+ 2, 4,
4476 fragp
->fr_symbol
, fragp
->fr_offset
, 0, BFD_RELOC_32
);
4477 fragp
->fr_fix
+= U32_LEN
;
4482 case C (UNCD_JUMP_PIC
, DISP32
):
4483 case C (UNCD_JUMP_PIC
, UNDEF_WORD_DISP
):
4495 0: .long (tar_add - pc)
4498 /* If the b!cond is 4 byte aligned, the literal which would
4499 go at x+4 will also be aligned. */
4500 int first_inst
= fragp
->fr_fix
+ fragp
->fr_address
;
4501 int is_unaligned
= (first_inst
& 3);
4504 buf
[0] = BYTE_0 (CSKYV1_INST_SUBI
| (7 << 4)); /* subi r0, 8. */
4505 buf
[1] = BYTE_1 (CSKYV1_INST_SUBI
| (7 << 4));
4506 buf
[2] = BYTE_0 (CSKYV1_INST_STW
| (15 << 8)); /* stw r15, r0. */
4507 buf
[3] = BYTE_1 (CSKYV1_INST_STW
| (15 << 8));
4508 buf
[4] = BYTE_0 (CSKYV1_INST_BSR
); /* bsr pc + 2. */
4509 buf
[5] = BYTE_1 (CSKYV1_INST_BSR
);
4510 buf
[6] = BYTE_0 (CSKYV1_INST_LRW
| (1 << 8)); /* lrw r1, (tar_addr - pc). */
4511 buf
[7] = BYTE_1 (CSKYV1_INST_LRW
| (1 << 8));
4512 buf
[8] = BYTE_0 (CSKYV1_INST_ADDU
| (15 << 4) | 1); /* add r1, r15. */
4513 buf
[9] = BYTE_1 (CSKYV1_INST_ADDU
| (15 << 4) | 1);
4514 buf
[10] = BYTE_0 (CSKYV1_INST_LDW
| (15 << 8)); /* ldw r15, r0. */
4515 buf
[11] = BYTE_1 (CSKYV1_INST_LDW
| (15 << 8));
4516 buf
[12] = BYTE_0 (CSKYV1_INST_ADDI
| (7 << 4)); /* addi r0, 8. */
4517 buf
[13] = BYTE_1 (CSKYV1_INST_ADDI
| (7 << 4));
4518 buf
[14] = BYTE_0 (CSKYV1_INST_JMP
| 1); /* jmp r1. */
4519 buf
[15] = BYTE_1 (CSKYV1_INST_JMP
| 1);
4523 if (!target_big_endian
)
4526 buf
[18] = disp
& 0xff;
4527 buf
[19] = (disp
>> 8) & 0xff;
4528 buf
[20] = (disp
>> 16) & 0xff;
4529 buf
[21] = (disp
>> 24) & 0xff;
4534 buf
[18] = (disp
>> 24) & 0xff;
4535 buf
[19] = (disp
>> 16) & 0xff;
4536 buf
[20] = (disp
>> 8) & 0xff;
4537 buf
[21] = disp
& 0xff;
4541 fragp
->fr_fix
+= U32_LEN_PIC
;
4545 if (!target_big_endian
)
4548 buf
[16] = disp
& 0xff;
4549 buf
[17] = (disp
>> 8) & 0xff;
4550 buf
[18] = (disp
>> 16) & 0xff;
4551 buf
[19] = (disp
>> 24) & 0xff;
4556 buf
[16] = (disp
>> 24) & 0xff;
4557 buf
[17] = (disp
>> 16) & 0xff;
4558 buf
[18] = (disp
>> 8) & 0xff;
4559 buf
[19] = disp
& 0xff;
4561 fragp
->fr_fix
+= U32_LEN_PIC
;
4571 unsigned int inst
= csky_read_insn (buf
, 2);
4572 inst
|= (disp
>> 1) & ((1 << 10) - 1);
4573 csky_write_insn (buf
, inst
, 2);
4579 unsigned int inst
= csky_read_insn (buf
, 2);
4581 if (inst
== CSKYV2_INST_BT16
)
4582 inst
= CSKYV2_INST_BF16
;
4584 inst
= CSKYV2_INST_BT16
;
4585 make_insn (2, inst
, (2 + 4) >> 1, 10);
4586 if (IS_EXTERNAL_SYM (fragp
->fr_symbol
, asec
))
4587 fix_new (fragp
, fragp
->fr_fix
, 4,
4588 fragp
->fr_symbol
, fragp
->fr_offset
, 1,
4589 BFD_RELOC_CKCORE_PCREL_IMM16BY2
);
4591 inst
= CSKYV2_INST_BR32
| ((disp
>> 1) & ((1 << 16) - 1));
4592 csky_write_insn (buf
, inst
, 4);
4599 unsigned int inst
= csky_read_insn (buf
, 2);
4601 if (inst
== CSKYV2_INST_BT16
)
4602 inst
= CSKYV2_INST_BT32
;
4604 inst
= CSKYV2_INST_BF32
;
4605 if (IS_EXTERNAL_SYM (fragp
->fr_symbol
, asec
))
4606 fix_new (fragp
, fragp
->fr_fix
, 4,
4607 fragp
->fr_symbol
, fragp
->fr_offset
, 1,
4608 BFD_RELOC_CKCORE_PCREL_IMM16BY2
);
4609 inst
|= (disp
>> 1) & ((1 << 16) - 1);
4610 csky_write_insn (buf
, inst
, 4);
4616 unsigned int inst
= csky_read_insn (buf
, 2);
4618 imm
= (disp
+ 2) >> 2;
4619 inst
|= (imm
>> 5) << 8;
4620 make_insn (2, inst
, (imm
& 0x1f), 5);
4625 unsigned int inst
= csky_read_insn (buf
, 2);
4626 int imm
= (disp
+ 2) >> 2;
4630 inst
|= (~((imm
>> 5) << 8)) & 0x300;
4631 make_insn (2, inst
, (~imm
& 0x1f), 5);
4635 inst
|= (imm
>> 5) << 8;
4636 make_insn (2, inst
, (imm
& 0x1f), 5);
4642 unsigned int inst
= csky_read_insn (buf
, 2);
4643 inst
= CSKYV2_INST_LRW32
| (((inst
& 0xe0) >> 5) << 16);
4644 if (IS_EXTERNAL_SYM (fragp
->fr_symbol
, asec
))
4645 fix_new (fragp
, fragp
->fr_fix
, 4,
4646 fragp
->fr_symbol
, fragp
->fr_offset
, 1,
4647 BFD_RELOC_CKCORE_PCREL_IMM16BY4
);
4648 make_insn (4, inst
, ((disp
+ 2) >> 2), 16);
4653 unsigned int inst
= csky_read_insn (buf
, 4);
4654 make_insn (4, inst
, disp
>> 1, 16);
4659 unsigned int inst
= csky_read_insn (buf
, 4);
4661 make_insn (4, opposite_of_stored_compz (inst
),
4662 (4 + 4 + PAD_LITERAL_LENGTH
) >> 1, 16);
4663 literal_offset
= ((fragp
->fr_address
+ fragp
->fr_fix
) % 4 == 0
4665 make_insn (4, CSKYV2_INST_JMPI32
, (4 + literal_offset
+ 2) >> 2, 10);
4666 make_literal (fragp
, literal_offset
);
4672 if (IS_EXTERNAL_SYM (fragp
->fr_symbol
, asec
))
4673 fix_new (fragp
, fragp
->fr_fix
, 4,
4674 fragp
->fr_symbol
, fragp
->fr_offset
, 1,
4675 BFD_RELOC_CKCORE_PCREL_IMM16BY2
);
4676 make_insn (4, CSKYV2_INST_BR32
, disp
>> 1, 16);
4681 /* 'jbt'/'jbf'-> <bf16/bt16>; jmpi32; [pad16]+literal32 */
4682 unsigned int inst
= csky_read_insn (buf
, 2);
4685 if (inst
== CSKYV2_INST_BT16
)
4686 inst
= CSKYV2_INST_BF16
;
4688 inst
= CSKYV2_INST_BT16
;
4689 make_insn (2, inst
, (2 + 4 + PAD_LITERAL_LENGTH
) >> 1, 10);
4690 literal_offset
= ((fragp
->fr_address
+ fragp
->fr_fix
) % 4 == 0
4692 make_insn (4, CSKYV2_INST_JMPI32
, (4 + literal_offset
+ 2) >> 2, 10);
4693 make_literal (fragp
, literal_offset
);
4699 literal_offset
= ((fragp
->fr_address
+ fragp
->fr_fix
) % 4 == 0
4701 make_insn (4, CSKYV2_INST_JMPI32
, (4 + literal_offset
+ 2) >> 2, 10);
4702 make_literal (fragp
, literal_offset
);
4705 case RELAX_OVERFLOW
:
4706 csky_branch_report_error (fragp
->fr_file
, fragp
->fr_line
,
4707 fragp
->fr_symbol
, disp
);
4715 /* Round up a section size to the appropriate boundary. */
4718 md_section_align (segT segment ATTRIBUTE_UNUSED
,
4724 /* MD interface: Symbol and relocation handling. */
4726 void md_csky_end (void)
4731 /* Return the address within the segment that a PC-relative fixup is
4735 md_pcrel_from_section (fixS
* fixP
, segT seg
)
4737 /* If the symbol is undefined or defined in another section
4738 we leave the add number alone for the linker to fix it later. */
4739 if (fixP
->fx_addsy
!= (symbolS
*) NULL
4740 && (! S_IS_DEFINED (fixP
->fx_addsy
)
4741 || S_GET_SEGMENT (fixP
->fx_addsy
) != seg
))
4742 return fixP
->fx_size
;
4744 /* The case where we are going to resolve things. */
4745 return fixP
->fx_size
+ fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
4748 /* csky_cons_fix_new is called via the expression parsing code when a
4749 reloc is needed. We use this hook to get the correct .got reloc. */
4752 csky_cons_fix_new (fragS
*frag
,
4756 bfd_reloc_code_real_type reloc
)
4760 if (BFD_RELOC_CKCORE_GOTOFF
== insn_reloc
4761 || BFD_RELOC_CKCORE_GOTPC
== insn_reloc
4762 || BFD_RELOC_CKCORE_GOT32
== insn_reloc
4763 || BFD_RELOC_CKCORE_PLT32
== insn_reloc
4764 || BFD_RELOC_CKCORE_TLS_LE32
== insn_reloc
4765 || BFD_RELOC_CKCORE_TLS_GD32
== insn_reloc
4766 || BFD_RELOC_CKCORE_TLS_LDM32
== insn_reloc
4767 || BFD_RELOC_CKCORE_TLS_LDO32
== insn_reloc
4768 || BFD_RELOC_CKCORE_TLS_IE32
== insn_reloc
)
4774 reloc
= BFD_RELOC_8
;
4777 reloc
= BFD_RELOC_16
;
4780 reloc
= BFD_RELOC_32
;
4783 reloc
= BFD_RELOC_64
;
4786 as_bad (_("unsupported BFD relocation size %d"), len
);
4787 reloc
= BFD_RELOC_32
;
4790 fixP
= fix_new_exp (frag
, off
, (int) len
, exp
, 0, reloc
);
4791 if (BFD_RELOC_CKCORE_TLS_IE32
== insn_reloc
4792 || BFD_RELOC_CKCORE_TLS_GD32
== insn_reloc
4793 || BFD_RELOC_CKCORE_TLS_LDM32
== insn_reloc
)
4795 fixP
->tc_fix_data
.frag
= literal_insn_offset
->tls_addend
.frag
;
4796 fixP
->tc_fix_data
.offset
= literal_insn_offset
->tls_addend
.offset
;
4800 /* See whether we need to force a relocation into the output file.
4801 This is used to force out switch and PC relative relocations when
4805 csky_force_relocation (fixS
* fix
)
4807 if (fix
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
4808 || fix
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
4809 || fix
->fx_r_type
== BFD_RELOC_RVA
4810 || fix
->fx_r_type
== BFD_RELOC_CKCORE_ADDR_HI16
4811 || fix
->fx_r_type
== BFD_RELOC_CKCORE_ADDR_LO16
4812 || fix
->fx_r_type
== BFD_RELOC_CKCORE_TOFFSET_LO16
4813 || fix
->fx_r_type
== BFD_RELOC_CKCORE_DOFFSET_LO16
)
4816 if (fix
->fx_addsy
== NULL
)
4819 if (do_use_branchstub
4820 && fix
->fx_r_type
== BFD_RELOC_CKCORE_PCREL_IMM26BY2
4821 && (symbol_get_bfdsym (fix
->fx_addsy
)->flags
& BSF_FUNCTION
))
4823 return S_FORCE_RELOC (fix
->fx_addsy
, fix
->fx_subsy
== NULL
);
4826 /* Return true if the fix can be handled by GAS, false if it must
4827 be passed through to the linker. */
4830 csky_fix_adjustable (fixS
* fixP
)
4832 if (fixP
->fx_addsy
== NULL
)
4835 /* We need the symbol name for the VTABLE entries. */
4836 if (fixP
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
4837 || fixP
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
4838 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_PLT32
4839 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_GOT32
4840 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_PLT12
4841 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_GOT12
4842 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_GOT_HI16
4843 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_GOT_LO16
4844 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_PLT_HI16
4845 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_PLT_LO16
4846 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_GOTOFF
4847 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_GOTOFF_HI16
4848 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_GOTOFF_LO16
4849 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_ADDR_HI16
4850 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_ADDR_LO16
4851 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_GOT_IMM18BY4
4852 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_PLT_IMM18BY4
4853 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_GOTOFF_IMM18
4854 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_TLS_LE32
4855 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_TLS_IE32
4856 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_TLS_GD32
4857 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_TLS_LDM32
4858 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_TLS_LDO32
)
4861 if (do_use_branchstub
4862 && fixP
->fx_r_type
== BFD_RELOC_CKCORE_PCREL_IMM26BY2
4863 && (symbol_get_bfdsym (fixP
->fx_addsy
)->flags
& BSF_FUNCTION
))
4870 md_apply_fix (fixS
*fixP
,
4874 reloc_howto_type
*howto
;
4875 /* Note: use offsetT because it is signed, valueT is unsigned. */
4876 offsetT val
= *valP
;
4877 char *buf
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
4879 /* if fx_done = 0, fixup will also be processed in
4880 * tc_gen_reloc() after md_apply_fix(). */
4883 /* If the fix is relative to a symbol which is not defined, or not
4884 in the same segment as the fix, we cannot resolve it here. */
4885 if (IS_CSKY_V1 (mach_flag
) && fixP
->fx_addsy
!= NULL
4886 && (! S_IS_DEFINED (fixP
->fx_addsy
)
4887 || S_GET_SEGMENT (fixP
->fx_addsy
) != seg
))
4889 switch (fixP
->fx_r_type
)
4891 /* Data fx_addnumber is greater than 16 bits,
4892 so fx_addnumber is assigned zero. */
4893 case BFD_RELOC_CKCORE_PCREL_JSR_IMM11BY2
:
4896 case BFD_RELOC_CKCORE_TLS_IE32
:
4897 case BFD_RELOC_CKCORE_TLS_LDM32
:
4898 case BFD_RELOC_CKCORE_TLS_GD32
:
4900 struct tls_addend
*ta
= &(fixP
->tc_fix_data
);
4901 fixP
->fx_offset
= (fixP
->fx_frag
->fr_address
+ fixP
->fx_where
4902 - (ta
->frag
->fr_address
+ ta
->offset
));
4905 case BFD_RELOC_CKCORE_TLS_LE32
:
4906 case BFD_RELOC_CKCORE_TLS_LDO32
:
4907 S_SET_THREAD_LOCAL (fixP
->fx_addsy
);
4913 /* For ELF we can just return and let the reloc that will be generated
4914 take care of everything. For COFF we still have to insert 'val'
4915 into the insn since the addend field will be ignored. */
4920 /* We can handle these relocs. */
4921 switch (fixP
->fx_r_type
)
4923 case BFD_RELOC_CKCORE_PCREL32
:
4925 case BFD_RELOC_VTABLE_INHERIT
:
4926 fixP
->fx_r_type
= BFD_RELOC_CKCORE_GNU_VTINHERIT
;
4927 if (fixP
->fx_addsy
&& !S_IS_DEFINED (fixP
->fx_addsy
)
4928 && !S_IS_WEAK (fixP
->fx_addsy
))
4929 S_SET_WEAK (fixP
->fx_addsy
);
4931 case BFD_RELOC_VTABLE_ENTRY
:
4932 fixP
->fx_r_type
= BFD_RELOC_CKCORE_GNU_VTENTRY
;
4934 case BFD_RELOC_CKCORE_GOT12
:
4935 case BFD_RELOC_CKCORE_PLT12
:
4936 case BFD_RELOC_CKCORE_ADDR_HI16
:
4937 case BFD_RELOC_CKCORE_ADDR_LO16
:
4938 case BFD_RELOC_CKCORE_TOFFSET_LO16
:
4939 case BFD_RELOC_CKCORE_DOFFSET_LO16
:
4940 case BFD_RELOC_CKCORE_GOT_HI16
:
4941 case BFD_RELOC_CKCORE_GOT_LO16
:
4942 case BFD_RELOC_CKCORE_PLT_HI16
:
4943 case BFD_RELOC_CKCORE_PLT_LO16
:
4944 case BFD_RELOC_CKCORE_GOTPC_HI16
:
4945 case BFD_RELOC_CKCORE_GOTPC_LO16
:
4946 case BFD_RELOC_CKCORE_GOTOFF_HI16
:
4947 case BFD_RELOC_CKCORE_GOTOFF_LO16
:
4948 case BFD_RELOC_CKCORE_DOFFSET_IMM18
:
4949 case BFD_RELOC_CKCORE_DOFFSET_IMM18BY2
:
4950 case BFD_RELOC_CKCORE_DOFFSET_IMM18BY4
:
4951 case BFD_RELOC_CKCORE_GOTOFF_IMM18
:
4952 case BFD_RELOC_CKCORE_GOT_IMM18BY4
:
4953 case BFD_RELOC_CKCORE_PLT_IMM18BY4
:
4955 case BFD_RELOC_CKCORE_TLS_IE32
:
4956 case BFD_RELOC_CKCORE_TLS_LDM32
:
4957 case BFD_RELOC_CKCORE_TLS_GD32
:
4959 struct tls_addend
*ta
= &(fixP
->tc_fix_data
);
4960 fixP
->fx_offset
= (fixP
->fx_frag
->fr_address
+ fixP
->fx_where
4961 - (ta
->frag
->fr_address
+ ta
->offset
));
4964 case BFD_RELOC_CKCORE_TLS_LE32
:
4965 case BFD_RELOC_CKCORE_TLS_LDO32
:
4966 S_SET_THREAD_LOCAL (fixP
->fx_addsy
);
4969 fixP
->fx_r_type
= BFD_RELOC_CKCORE_ADDR32
;
4973 if (fixP
->fx_addsy
== NULL
)
4975 if (fixP
->fx_size
== 4)
4977 else if (fixP
->fx_size
== 2 && val
>= -32768 && val
<= 32767)
4979 else if (fixP
->fx_size
== 1 && val
>= -256 && val
<= 255)
4983 md_number_to_chars (buf
, val
, fixP
->fx_size
);
4987 case BFD_RELOC_CKCORE_PCREL_JSR_IMM11BY2
:
4988 if (fixP
->fx_addsy
== 0 && val
> -2 KB
&& val
< 2 KB
)
4990 long nval
= (val
>> 1) & 0x7ff;
4991 nval
|= CSKYV1_INST_BSR
;
4992 csky_write_insn (buf
, nval
, 2);
4998 case BFD_RELOC_CKCORE_PCREL_JSR_IMM26BY2
:
4999 if (fixP
->fx_addsy
== 0)
5001 if (val
>= -(1 << 26) && val
< (1 << 26))
5003 unsigned int nval
= ((val
+ fixP
->fx_size
) >> 1) & 0x3ffffff;
5004 nval
|= CSKYV2_INST_BSR32
;
5006 csky_write_insn (buf
, nval
, 4);
5008 /* If bsr32 cannot reach,
5009 generate 'lrw r25,label;jsr r25' instead of 'jsri label'. */
5010 else if (IS_CSKY_ARCH_810 (mach_flag
))
5012 howto
= bfd_reloc_type_lookup (stdoutput
, fixP
->fx_r_type
);
5013 valueT opcode
= csky_read_insn (buf
, 4);
5014 opcode
= (opcode
& howto
->dst_mask
) | CSKYV2_INST_JSRI_TO_LRW
;
5015 csky_write_insn (buf
, opcode
, 4);
5016 opcode
= CSKYV2_INST_JSR_R26
;
5017 csky_write_insn (buf
+ 4, opcode
, 4);
5027 unsigned int issigned
= 0;
5032 howto
= bfd_reloc_type_lookup (stdoutput
, fixP
->fx_r_type
);
5035 if (fixP
->fx_size
== 4
5036 || (fixP
->fx_size
== 2 && val
>= -32768 && val
<= 32767)
5037 || (fixP
->fx_size
== 1 && val
>= -256 && val
<= 255))
5039 md_number_to_chars (buf
, val
, fixP
->fx_size
);
5047 if (IS_CSKY_V2 (mach_flag
))
5048 val
+= fixP
->fx_size
;
5050 if (howto
->rightshift
== 2)
5053 val
>>= howto
->rightshift
;
5055 switch (fixP
->fx_r_type
)
5057 /* Offset is unsigned. */
5058 case BFD_RELOC_CKCORE_PCREL_IMM8BY4
:
5059 case BFD_RELOC_CKCORE_PCREL_IMM10BY4
:
5060 case BFD_RELOC_CKCORE_PCREL_IMM16BY4
:
5061 max
= (offsetT
) howto
->dst_mask
;
5065 case BFD_RELOC_CKCORE_PCREL_IMM7BY4
:
5067 max
= (offsetT
)((1 << (howto
->bitsize
+ 1)) - 2);
5069 max
= (offsetT
)((1 << howto
->bitsize
) - 1);
5072 /* flrws, flrwd: the offset bits are divided in two parts. */
5073 case BFD_RELOC_CKCORE_PCREL_FLRW_IMM8BY4
:
5074 max
= (offsetT
)((1 << howto
->bitsize
) - 1);
5077 /* Offset is signed. */
5079 max
= (offsetT
)(howto
->dst_mask
>> 1);
5083 if (val
< min
|| val
> max
)
5085 csky_branch_report_error (fixP
->fx_file
, fixP
->fx_line
,
5086 fixP
->fx_addsy
, val
);
5089 opcode
= csky_read_insn (buf
, fixP
->fx_size
);
5090 /* Clear redundant bits brought from the last
5091 operation if there is any. */
5092 if (do_extend_lrw
&& (opcode
& 0xfc00) == CSKYV2_INST_LRW16
)
5095 val
&= issigned
? (offsetT
)(howto
->dst_mask
) : max
;
5097 if (fixP
->fx_r_type
== BFD_RELOC_CKCORE_PCREL_BLOOP_IMM4BY4
)
5098 val
= (val
& 0xf) << 12;
5100 if (fixP
->fx_size
== 2 && (opcode
& 0xfc00) == CSKYV2_INST_LRW16
)
5102 /* 8 bit offset lrw16. */
5104 csky_write_insn (buf
,
5106 | ((~val
& 0x60) << 3) | (opcode
& 0xe0)),
5108 /* 7 bit offset lrw16. */
5110 csky_write_insn (buf
,
5111 (val
& 0x1f) | ((val
& 0x60) << 3) | opcode
,
5114 else if (fixP
->fx_size
== 4
5115 && (opcode
& 0xfe1ffe00) == CSKYV2_INST_FLRW
)
5116 csky_write_insn (buf
,
5117 ((val
& 0xf) << 4) | ((val
& 0xf0) << 17) | opcode
,
5120 csky_write_insn (buf
, val
| opcode
, fixP
->fx_size
);
5125 fixP
->fx_addnumber
= val
;
5128 /* Translate internal representation of relocation info to BFD target
5132 tc_gen_reloc (asection
*section ATTRIBUTE_UNUSED
, fixS
*fixP
)
5136 rel
= xmalloc (sizeof (arelent
));
5137 rel
->sym_ptr_ptr
= xmalloc (sizeof (asymbol
*));
5138 *rel
->sym_ptr_ptr
= symbol_get_bfdsym (fixP
->fx_addsy
);
5139 rel
->howto
= bfd_reloc_type_lookup (stdoutput
, fixP
->fx_r_type
);
5140 rel
->addend
= fixP
->fx_offset
;
5141 if (rel
->howto
== NULL
)
5143 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5144 _("cannot represent `%s' relocation in object file"),
5145 bfd_get_reloc_code_name (fixP
->fx_r_type
));
5147 /* Set howto to a garbage value so that we can keep going. */
5148 rel
->howto
= bfd_reloc_type_lookup (stdoutput
, BFD_RELOC_32
);
5150 gas_assert (rel
->howto
!= NULL
);
5151 rel
->address
= fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
5155 /* Relax a fragment by scanning TC_GENERIC_RELAX_TABLE. */
5158 csky_relax_frag (segT segment
, fragS
*fragP
, long stretch
)
5160 const relax_typeS
*this_type
;
5161 const relax_typeS
*start_type
;
5162 relax_substateT next_state
;
5163 relax_substateT this_state
;
5169 const relax_typeS
*table
;
5171 target
= fragP
->fr_offset
;
5172 address
= fragP
->fr_address
;
5173 table
= TC_GENERIC_RELAX_TABLE
;
5174 this_state
= fragP
->fr_subtype
;
5175 start_type
= this_type
= table
+ this_state
;
5176 symbolP
= fragP
->fr_symbol
;
5182 sym_frag
= symbol_get_frag (symbolP
);
5184 #ifndef DIFF_EXPR_OK
5185 know (sym_frag
!= NULL
);
5187 know (S_GET_SEGMENT (symbolP
) != absolute_section
5188 || sym_frag
== &zero_address_frag
);
5189 target
+= S_GET_VALUE (symbolP
);
5191 /* If SYM_FRAG has yet to be reached on this pass, assume it
5192 will move by STRETCH just as we did, unless there is an
5193 alignment frag between here and SYM_FRAG. An alignment may
5194 well absorb any STRETCH, and we don't want to choose a larger
5195 branch insn by overestimating the needed reach of this
5196 branch. It isn't critical to calculate TARGET exactly; We
5197 know we'll be doing another pass if STRETCH is non-zero. */
5200 && sym_frag
->relax_marker
!= fragP
->relax_marker
5201 && S_GET_SEGMENT (symbolP
) == segment
)
5205 /* Adjust stretch for any alignment frag. Note that if have
5206 been expanding the earlier code, the symbol may be
5207 defined in what appears to be an earlier frag. FIXME:
5208 This doesn't handle the fr_subtype field, which specifies
5209 a maximum number of bytes to skip when doing an
5211 for (f
= fragP
; f
!= NULL
&& f
!= sym_frag
; f
= f
->fr_next
)
5213 if (f
->fr_type
== rs_align
|| f
->fr_type
== rs_align_code
)
5216 stretch
= -((-stretch
)
5217 & ~((1 << (int) f
->fr_offset
) - 1));
5219 stretch
&= ~((1 << (int) f
->fr_offset
) - 1);
5229 aim
= target
- address
- fragP
->fr_fix
;
5231 /* If the fragP->fr_symbol is extern symbol, aim should be 0. */
5232 if (fragP
->fr_symbol
&& S_GET_SEGMENT (symbolP
) != segment
)
5237 /* Look backwards. */
5238 for (next_state
= this_type
->rlx_more
; next_state
;)
5239 if (aim
>= this_type
->rlx_backward
)
5243 /* Grow to next state. */
5244 this_state
= next_state
;
5245 this_type
= table
+ this_state
;
5246 next_state
= this_type
->rlx_more
;
5251 /* Look forwards. */
5252 for (next_state
= this_type
->rlx_more
; next_state
;)
5253 if (aim
<= this_type
->rlx_forward
)
5257 /* Grow to next state. */
5258 this_state
= next_state
;
5259 this_type
= table
+ this_state
;
5260 next_state
= this_type
->rlx_more
;
5264 growth
= this_type
->rlx_length
- start_type
->rlx_length
;
5266 fragP
->fr_subtype
= this_state
;
5271 md_estimate_size_before_relax (fragS
* fragp
,
5274 switch (fragp
->fr_subtype
)
5294 gas_assert (fragp
->fr_symbol
);
5295 if (IS_EXTERNAL_SYM (fragp
->fr_symbol
, segtype
))
5296 while (csky_relax_table
[fragp
->fr_subtype
].rlx_more
> RELAX_OVERFLOW
)
5297 fragp
->fr_subtype
= csky_relax_table
[fragp
->fr_subtype
].rlx_more
;
5298 return csky_relax_table
[fragp
->fr_subtype
].rlx_length
;
5300 /* C-SKY V1 relaxes. */
5301 case C (UNCD_JUMP
, UNDEF_DISP
):
5302 case C (UNCD_JUMP_PIC
, UNDEF_DISP
):
5303 if (!fragp
->fr_symbol
)
5304 fragp
->fr_subtype
= C (UNCD_JUMP_S
, DISP12
);
5305 else if (S_GET_SEGMENT (fragp
->fr_symbol
) == segtype
)
5306 fragp
->fr_subtype
= C (UNCD_JUMP_S
, DISP12
);
5308 fragp
->fr_subtype
= C (UNCD_JUMP_S
, UNDEF_WORD_DISP
);
5311 case C (COND_JUMP
, UNDEF_DISP
):
5312 case C (COND_JUMP_PIC
, UNDEF_DISP
):
5313 if (fragp
->fr_symbol
5314 && S_GET_SEGMENT (fragp
->fr_symbol
) == segtype
)
5315 /* Got a symbol and it's defined in this segment, become byte
5316 sized. Maybe it will fix up. */
5317 fragp
->fr_subtype
= C (COND_JUMP_S
, DISP12
);
5318 else if (fragp
->fr_symbol
)
5319 /* It's got a segment, but it's not ours, so it will always be
5321 fragp
->fr_subtype
= C (COND_JUMP_S
, UNDEF_WORD_DISP
);
5323 /* We know the abs value. */
5324 fragp
->fr_subtype
= C (COND_JUMP_S
, DISP12
);
5327 case C (UNCD_JUMP
, DISP12
):
5328 case C (UNCD_JUMP
, DISP32
):
5329 case C (UNCD_JUMP
, UNDEF_WORD_DISP
):
5330 case C (COND_JUMP
, DISP12
):
5331 case C (COND_JUMP
, DISP32
):
5332 case C (COND_JUMP
, UNDEF_WORD_DISP
):
5333 case C (UNCD_JUMP_PIC
, DISP12
):
5334 case C (UNCD_JUMP_PIC
, DISP32
):
5335 case C (UNCD_JUMP_PIC
, UNDEF_WORD_DISP
):
5336 case C (COND_JUMP_PIC
, DISP12
):
5337 case C (COND_JUMP_PIC
, DISP32
):
5338 case C (COND_JUMP_PIC
, UNDEF_WORD_DISP
):
5339 case RELAX_OVERFLOW
:
5345 return csky_relax_table
[fragp
->fr_subtype
].rlx_length
;
5348 /* Parse opcode like: "op oprnd1, oprnd2, oprnd3". */
5351 csky_macro_md_assemble (const char *op
,
5362 strcat (str
, oprnd1
);
5366 strcat (str
, oprnd2
);
5370 strcat (str
, oprnd3
);
5378 /* Get the string of operand. */
5381 csky_get_macro_operand (char *src_s
, char *dst_s
, char end_sym
)
5384 while (ISSPACE (*src_s
))
5386 while (*src_s
!= end_sym
)
5387 dst_s
[nlen
++] = *(src_s
++);
5392 /* idly 4 -> idly4. */
5397 char *s
= csky_insn
.opcode_end
;
5398 if (!is_imm_over_range (&s
, 4, 4, -1))
5400 as_bad (_("second operand must be 4"));
5403 csky_macro_md_assemble ("idly4", NULL
, NULL
, NULL
);
5407 /* rolc rd, 1 or roltc rd, 1 -> addc rd, rd. */
5413 char *s
= csky_insn
.opcode_end
;
5415 s
+= csky_get_macro_operand (s
, reg
, ',');
5418 if (is_imm_over_range (&s
, 1, 1, -1))
5420 csky_macro_md_assemble ("addc", reg
, reg
, NULL
);
5424 as_bad (_("second operand must be 1"));
5427 /* sxtrb0(1)(2) r1, rx -> xtbr0(1)(2) r1,rx; sextb r1. */
5435 char *s
= csky_insn
.opcode_end
;
5436 s
+= csky_get_macro_operand (s
, reg1
, ',');
5438 csky_get_macro_operand (s
, reg2
, '\0');
5440 csky_macro_md_assemble (csky_insn
.macro
->name
+ 1, reg1
, reg2
, NULL
);
5441 csky_macro_md_assemble ("sextb", reg1
, NULL
, NULL
);
5452 char *s
= csky_insn
.opcode_end
;
5453 s
+= csky_get_macro_operand (s
, reg1
, ',');
5456 s
+= csky_get_macro_operand (s
, reg2
, ',');
5459 s
+= csky_get_macro_operand (s
, reg3
, '\0');
5461 csky_macro_md_assemble ("movt", reg1
, reg2
, NULL
);
5462 csky_macro_md_assemble ("movf", reg1
, reg3
, NULL
);
5467 get_macro_reg_vals (int *reg1
, int *reg2
, int *reg3
)
5470 char *s
= csky_insn
.opcode_end
;
5472 *reg1
= csky_get_reg_val (s
, &nlen
);
5476 csky_show_error (ERROR_MISSING_COMMA
, 0, NULL
, NULL
);
5480 *reg2
= csky_get_reg_val (s
, &nlen
);
5484 csky_show_error (ERROR_MISSING_COMMA
, 0, NULL
, NULL
);
5488 *reg3
= csky_get_reg_val (s
, &nlen
);
5492 csky_show_error (ERROR_BAD_END
, 0, NULL
, NULL
);
5495 if (*reg1
== -1 || *reg2
== -1 || *reg3
== -1)
5497 as_bad (_("register number out of range"));
5502 as_bad (_("dest and source1 must be the same register"));
5505 if (*reg1
>= 15 || *reg3
>= 15)
5507 as_bad (_("64-bit operator src/dst register must be less than 15"));
5513 /* addc64 rx, rx, ry -> cmplt rx, rx, addc rx, ry, addc rx+1, ry+1. */
5522 if (!get_macro_reg_vals (®1
, ®2
, ®3
))
5524 csky_macro_md_assemble ("cmplt",
5525 csky_general_reg
[reg1
],
5526 csky_general_reg
[reg1
],
5528 csky_macro_md_assemble ("addc",
5529 csky_general_reg
[reg1
+ (target_big_endian
? 1 : 0)],
5530 csky_general_reg
[reg3
+ (target_big_endian
? 1 : 0)],
5532 csky_macro_md_assemble ("addc",
5533 csky_general_reg
[reg1
+ (target_big_endian
? 0 : 1)],
5534 csky_general_reg
[reg3
+ (target_big_endian
? 0 : 1)],
5539 /* subc64 rx, rx, ry -> cmphs rx, rx, subc rx, ry, subc rx+1, ry+1. */
5548 if (!get_macro_reg_vals (®1
, ®2
, ®3
))
5550 csky_macro_md_assemble ("cmphs",
5551 csky_general_reg
[reg1
],
5552 csky_general_reg
[reg1
],
5554 csky_macro_md_assemble ("subc",
5555 csky_general_reg
[reg1
+ (target_big_endian
? 1 : 0)],
5556 csky_general_reg
[reg3
+ (target_big_endian
? 1 : 0)],
5558 csky_macro_md_assemble ("subc",
5559 csky_general_reg
[reg1
+ (target_big_endian
? 0 : 1)],
5560 csky_general_reg
[reg3
+ (target_big_endian
? 0 : 1)],
5565 /* or64 rx, rx, ry -> or rx, ry, or rx+1, ry+1. */
5574 if (!get_macro_reg_vals (®1
, ®2
, ®3
))
5576 csky_macro_md_assemble ("or",
5577 csky_general_reg
[reg1
+ (target_big_endian
? 1 : 0)],
5578 csky_general_reg
[reg3
+ (target_big_endian
? 1 : 0)],
5580 csky_macro_md_assemble ("or",
5581 csky_general_reg
[reg1
+ (target_big_endian
? 0 : 1)],
5582 csky_general_reg
[reg3
+ (target_big_endian
? 0 : 1)],
5587 /* xor64 rx, rx, ry -> xor rx, ry, xor rx+1, ry+1. */
5596 if (!get_macro_reg_vals (®1
, ®2
, ®3
))
5598 csky_macro_md_assemble ("xor",
5599 csky_general_reg
[reg1
+ (target_big_endian
? 1 : 0)],
5600 csky_general_reg
[reg3
+ (target_big_endian
? 1 : 0)],
5602 csky_macro_md_assemble ("xor",
5603 csky_general_reg
[reg1
+ (target_big_endian
? 0 : 1)],
5604 csky_general_reg
[reg3
+ (target_big_endian
? 0 : 1)],
5609 /* The following are V2 macro instructions. */
5611 /* neg rd -> not rd, rd; addi rd, 1. */
5618 char *s
= csky_insn
.opcode_end
;
5619 s
+= csky_get_macro_operand (s
, reg1
, '\0');
5622 csky_macro_md_assemble ("not", reg1
, reg1
, NULL
);
5623 csky_macro_md_assemble ("addi", reg1
, "1", NULL
);
5627 /* rsubi rd, imm16 -> not rd; addi rd, imm16 + 1 */
5634 unsigned int imm16
= 0;
5636 char *s
= csky_insn
.opcode_end
;
5637 s
+= csky_get_macro_operand (s
, reg1
, ',');
5640 s
= parse_exp (s
, &e
);
5641 if (e
.X_op
== O_constant
)
5642 imm16
= e
.X_add_number
;
5644 csky_show_error (ERROR_IMM_ILLEGAL
, 2, NULL
, NULL
);
5646 sprintf (str_imm16
, "%d", imm16
+ 1);
5648 csky_macro_md_assemble ("not", reg1
, reg1
, NULL
);
5649 csky_macro_md_assemble ("addi", reg1
, str_imm16
, NULL
);
5653 /* Such as: asrc rd -> asrc rd, rd, 1. */
5659 char *s
= csky_insn
.opcode_end
;
5660 s
+= csky_get_macro_operand (s
, reg1
, '\0');
5662 csky_macro_md_assemble (csky_insn
.macro
->name
, reg1
, reg1
, "1");
5666 /* decne rd -> if ck802: subi rd, 1; cmpnei rd, 0.
5667 else: decne rd, rd, 1 */
5673 char *s
= csky_insn
.opcode_end
;
5674 s
+= csky_get_macro_operand (s
, reg1
, '\0');
5676 if (IS_CSKY_ARCH_802 (mach_flag
))
5678 csky_macro_md_assemble ("subi", reg1
, "1", NULL
);
5679 csky_macro_md_assemble ("cmpnei", reg1
, "0", NULL
);
5682 csky_macro_md_assemble ("decne", reg1
, reg1
, "1");
5686 /* If -mnolrw, lrw rd, imm -> movih rd, imm_hi16; ori rd, imm_lo16. */
5696 char *s
= csky_insn
.opcode_end
;
5697 s
+= csky_get_macro_operand (s
, reg1
, ',');
5699 s
+= csky_get_macro_operand (s
, imm
, '\0');
5703 strcat (imm_hi16
, "(");
5704 strcat (imm_hi16
, imm
);
5705 strcat (imm_hi16
, ") >> 16");
5707 strcat (imm_lo16
, "(");
5708 strcat (imm_lo16
, imm
);
5709 strcat (imm_lo16
, ") & 0xffff");
5711 csky_macro_md_assemble ("movih", reg1
, imm_hi16
, NULL
);
5712 csky_macro_md_assemble ("ori", reg1
, reg1
, imm_lo16
);
5717 /* The following are worker functions for C-SKY v1. */
5723 int output_literal
= csky_insn
.val
[1];
5725 reg
= csky_insn
.val
[0];
5726 csky_insn
.isize
= 2;
5727 csky_insn
.output
= frag_more (2);
5728 if (csky_insn
.e1
.X_op
== O_constant
5729 && csky_insn
.e1
.X_add_number
<= 0x7f
5730 && csky_insn
.e1
.X_add_number
>= 0)
5732 csky_insn
.inst
= 0x6000 | reg
| (csky_insn
.e1
.X_add_number
<< 4);
5735 csky_insn
.inst
= csky_insn
.opcode
->op16
[0].opcode
;
5736 csky_insn
.inst
|= reg
<< 8;
5739 int n
= enter_literal (&csky_insn
.e1
, 0, 0, 0);
5741 /* Create a reference to pool entry. */
5742 csky_insn
.e1
.X_op
= O_symbol
;
5743 csky_insn
.e1
.X_add_symbol
= poolsym
;
5744 csky_insn
.e1
.X_add_number
= n
<< 2;
5747 if (insn_reloc
== BFD_RELOC_CKCORE_TLS_GD32
5748 || insn_reloc
== BFD_RELOC_CKCORE_TLS_LDM32
5749 || insn_reloc
== BFD_RELOC_CKCORE_TLS_IE32
)
5751 literal_insn_offset
->tls_addend
.frag
= frag_now
;
5752 literal_insn_offset
->tls_addend
.offset
5754 - literal_insn_offset
->tls_addend
.frag
->fr_literal
);
5756 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
, 2,
5757 &csky_insn
.e1
, 1, BFD_RELOC_CKCORE_PCREL_IMM8BY4
);
5759 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
5765 v1_work_fpu_fo (void)
5771 struct csky_opcode_info
*opinfo
= NULL
;
5773 if (csky_insn
.isize
== 4)
5774 opinfo
= &csky_insn
.opcode
->op32
[csky_insn
.opcode_idx
];
5775 else if (csky_insn
.isize
== 2)
5776 opinfo
= &csky_insn
.opcode
->op16
[csky_insn
.opcode_idx
];
5778 /* Firstly, get general reg. */
5779 for (i
= 0;i
< opinfo
->operand_num
; i
++)
5780 if (opinfo
->oprnd
.oprnds
[i
].type
== OPRND_TYPE_GREG0_15
)
5781 greg
= csky_insn
.val
[i
];
5782 gas_assert (greg
!= -1);
5784 /* Secondly, get float inst. */
5785 csky_generate_insn ();
5786 inst
= csky_insn
.inst
;
5788 /* Now get greg and inst, we can write instruction to floating unit. */
5789 sprintf (buff
, "lrw %s,0x%x", csky_general_reg
[greg
], inst
);
5791 sprintf (buff
, "cpwir %s", csky_general_reg
[greg
]);
5798 v1_work_fpu_fo_fc (void)
5804 struct csky_opcode_info
*opinfo
= NULL
;
5806 if (csky_insn
.isize
== 4)
5807 opinfo
= &csky_insn
.opcode
->op32
[csky_insn
.opcode_idx
];
5808 else if (csky_insn
.isize
== 2)
5809 opinfo
= &csky_insn
.opcode
->op16
[csky_insn
.opcode_idx
];
5811 /* Firstly, get general reg. */
5812 for (i
= 0;i
< opinfo
->operand_num
; i
++)
5813 if (opinfo
->oprnd
.oprnds
[i
].type
== OPRND_TYPE_GREG0_15
)
5814 greg
= csky_insn
.val
[i
];
5815 gas_assert (greg
!= -1);
5817 /* Secondly, get float inst. */
5818 csky_generate_insn ();
5819 inst
= csky_insn
.inst
;
5821 /* Now get greg and inst, we can write instruction to floating unit. */
5822 sprintf (buff
, "lrw %s,0x%x", csky_general_reg
[greg
], inst
);
5824 sprintf (buff
, "cpwir %s", csky_general_reg
[greg
]);
5826 sprintf (buff
, "cprc");
5833 v1_work_fpu_write (void)
5839 greg
= csky_insn
.val
[0];
5840 freg
= csky_insn
.val
[1];
5842 /* Now get greg and freg, we can write instruction to floating unit. */
5843 sprintf (buff
, "cpwgr %s,%s", csky_general_reg
[greg
], csky_cp_reg
[freg
]);
5850 v1_work_fpu_read (void)
5856 greg
= csky_insn
.val
[0];
5857 freg
= csky_insn
.val
[1];
5858 /* Now get greg and freg, we can write instruction to floating unit. */
5859 sprintf (buff
, "cprgr %s,%s", csky_general_reg
[greg
], csky_cp_reg
[freg
]);
5866 v1_work_fpu_writed (void)
5872 greg
= csky_insn
.val
[0];
5873 freg
= csky_insn
.val
[1];
5877 as_bad (_("even register number required"));
5880 /* Now get greg and freg, we can write instruction to floating unit. */
5881 if (target_big_endian
)
5882 sprintf (buff
, "cpwgr %s,%s",
5883 csky_general_reg
[greg
+ 1], csky_cp_reg
[freg
]);
5885 sprintf (buff
, "cpwgr %s,%s",
5886 csky_general_reg
[greg
], csky_cp_reg
[freg
]);
5888 if (target_big_endian
)
5889 sprintf (buff
, "cpwgr %s,%s",
5890 csky_general_reg
[greg
], csky_cp_reg
[freg
+ 1]);
5892 sprintf (buff
, "cpwgr %s,%s",
5893 csky_general_reg
[greg
+ 1], csky_cp_reg
[freg
+ 1]);
5900 v1_work_fpu_readd (void)
5906 greg
= csky_insn
.val
[0];
5907 freg
= csky_insn
.val
[1];
5911 as_bad (_("even register number required"));
5914 /* Now get greg and freg, we can write instruction to floating unit. */
5915 if (target_big_endian
)
5916 sprintf (buff
, "cprgr %s,%s",
5917 csky_general_reg
[greg
+ 1], csky_cp_reg
[freg
]);
5919 sprintf (buff
, "cprgr %s,%s",
5920 csky_general_reg
[greg
], csky_cp_reg
[freg
]);
5922 if (target_big_endian
)
5923 sprintf (buff
, "cprgr %s,%s",
5924 csky_general_reg
[greg
], csky_cp_reg
[freg
+ 1]);
5926 sprintf (buff
, "cprgr %s,%s",
5927 csky_general_reg
[greg
+ 1], csky_cp_reg
[freg
+ 1]);
5933 /* The following are for csky pseudo handling. */
5938 csky_insn
.output
= frag_more (2);
5940 /* Generate fixup BFD_RELOC_CKCORE_PCREL_IMM11BY2. */
5941 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
5942 2, & csky_insn
.e1
, 1, BFD_RELOC_CKCORE_PCREL_IMM11BY2
);
5945 /* Using jsri instruction. */
5946 const char *name
= "jsri";
5947 csky_insn
.opcode
= (struct csky_opcode
*)
5948 hash_find (csky_opcodes_hash
, name
);
5949 csky_insn
.opcode_idx
= 0;
5950 csky_insn
.isize
= 2;
5952 int n
= enter_literal (&csky_insn
.e1
, 1, 0, 0);
5954 /* Create a reference to pool entry. */
5955 csky_insn
.e1
.X_op
= O_symbol
;
5956 csky_insn
.e1
.X_add_symbol
= poolsym
;
5957 csky_insn
.e1
.X_add_number
= n
<< 2;
5959 /* Generate fixup BFD_RELOC_CKCORE_PCREL_IMM8BY4. */
5960 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
5961 2, & csky_insn
.e1
, 1, BFD_RELOC_CKCORE_PCREL_IMM8BY4
);
5963 if (csky_insn
.e1
.X_op
!= O_absent
&& do_jsri2bsr
)
5964 /* Generate fixup BFD_RELOC_CKCORE_PCREL_JSR_IMM11BY2. */
5965 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
5966 2, & (litpool
+ (csky_insn
.e1
.X_add_number
>> 2))->e
,
5967 1, BFD_RELOC_CKCORE_PCREL_JSR_IMM11BY2
);
5969 csky_generate_insn ();
5971 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
5976 /* The following are worker functions for csky v2 instruction handling. */
5978 /* For nie/nir/ipush/ipop. */
5981 v2_work_istack (void)
5985 csky_show_error (ERROR_OPCODE_ILLEGAL
, 0, NULL
, NULL
);
5988 csky_insn
.output
= frag_more (csky_insn
.isize
);
5989 csky_insn
.inst
= csky_insn
.opcode
->op16
[0].opcode
;
5990 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
5995 v2_work_btsti (void)
5998 && (csky_insn
.flag_force
== INSN_OPCODE16F
5999 || IS_CSKY_ARCH_801 (mach_flag
)))
6001 csky_show_error (ERROR_OPCODE_ILLEGAL
, 0, NULL
, NULL
);
6004 if (!do_extend_lrw
&& csky_insn
.isize
== 2)
6005 csky_insn
.isize
= 4;
6006 /* Generate relax or reloc if necessary. */
6007 csky_generate_frags ();
6008 /* Generate the insn by mask. */
6009 csky_generate_insn ();
6010 /* Write inst to frag. */
6011 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6018 csky_insn
.isize
= 2;
6019 if (csky_insn
.number
== 2)
6021 if (csky_insn
.val
[0] == 14
6022 && csky_insn
.val
[1] >= 0 && csky_insn
.val
[1] <= 0x1fc
6023 && (csky_insn
.val
[1] & 0x3) == 0
6024 && csky_insn
.flag_force
!= INSN_OPCODE32F
)
6026 /* addi sp, sp, imm. */
6027 csky_insn
.inst
= 0x1400 | ((csky_insn
.val
[1] >> 2) & 0x1f);
6028 csky_insn
.inst
|= (csky_insn
.val
[1] << 1) & 0x300;
6029 csky_insn
.output
= frag_more (2);
6031 else if (csky_insn
.val
[0] < 8
6032 && csky_insn
.val
[1] >= 1 && csky_insn
.val
[1] <= 0x100
6033 && csky_insn
.flag_force
!= INSN_OPCODE32F
)
6035 csky_insn
.inst
= 0x2000 | (csky_insn
.val
[0] << 8);
6036 csky_insn
.inst
|= (csky_insn
.val
[1] - 1);
6037 csky_insn
.output
= frag_more (2);
6039 else if (csky_insn
.val
[1] >= 1 && csky_insn
.val
[1] <= 0x10000
6040 && csky_insn
.flag_force
!= INSN_OPCODE16F
6041 && !IS_CSKY_ARCH_801 (mach_flag
))
6043 csky_insn
.inst
= 0xe4000000 | (csky_insn
.val
[0] << 21);
6044 csky_insn
.inst
|= csky_insn
.val
[0] << 16;
6045 csky_insn
.inst
|= (csky_insn
.val
[1] - 1);
6046 csky_insn
.isize
= 4;
6047 csky_insn
.output
= frag_more (4);
6051 csky_show_error (ERROR_OPERANDS_ILLEGAL
, 0,
6052 csky_insn
.opcode_end
, NULL
);
6056 else if (csky_insn
.number
== 3)
6058 if (csky_insn
.val
[0] == 14
6059 && csky_insn
.val
[1] == 14
6060 && csky_insn
.val
[2] >= 0 && csky_insn
.val
[2] <= 0x1fc
6061 && (csky_insn
.val
[2] & 0x3) == 0
6062 && csky_insn
.flag_force
!= INSN_OPCODE32F
)
6064 csky_insn
.inst
= 0x1400 | ((csky_insn
.val
[2] >> 2) & 0x1f);
6065 csky_insn
.inst
|= (csky_insn
.val
[2] << 1) & 0x300;
6066 csky_insn
.output
= frag_more (2);
6068 else if (csky_insn
.val
[0] < 8
6069 && csky_insn
.val
[1] == 14
6070 && csky_insn
.val
[2] >= 0 && csky_insn
.val
[2] <= 0x3fc
6071 && (csky_insn
.val
[2] & 0x3) == 0
6072 && csky_insn
.flag_force
!= INSN_OPCODE32F
)
6074 csky_insn
.inst
= 0x1800 | (csky_insn
.val
[0] << 8);
6075 csky_insn
.inst
|= csky_insn
.val
[2] >> 2;
6076 csky_insn
.output
= frag_more (2);
6078 else if (csky_insn
.val
[0] < 8
6079 && csky_insn
.val
[0] == csky_insn
.val
[1]
6080 && csky_insn
.val
[2] >= 1 && csky_insn
.val
[2] <= 0x100
6081 && csky_insn
.flag_force
!= INSN_OPCODE32F
)
6083 csky_insn
.inst
= 0x2000 | (csky_insn
.val
[0] << 8);
6084 csky_insn
.inst
|= (csky_insn
.val
[2] - 1);
6085 csky_insn
.output
= frag_more (2);
6087 else if (csky_insn
.val
[0] < 8
6088 && csky_insn
.val
[1] < 8
6089 && csky_insn
.val
[2] >= 1 && csky_insn
.val
[2] <= 0x8
6090 && csky_insn
.flag_force
!= INSN_OPCODE32F
)
6092 csky_insn
.inst
= 0x5802 | (csky_insn
.val
[0] << 5);
6093 csky_insn
.inst
|= csky_insn
.val
[1] << 8;
6094 csky_insn
.inst
|= (csky_insn
.val
[2] - 1) << 2;
6095 csky_insn
.output
= frag_more (2);
6097 else if (csky_insn
.val
[1] == 28
6098 && csky_insn
.val
[2] >= 1 && csky_insn
.val
[2] <= 0x40000
6099 && csky_insn
.flag_force
!= INSN_OPCODE16F
6100 && !IS_CSKY_ARCH_801 (mach_flag
))
6102 csky_insn
.inst
= 0xcc1c0000 | (csky_insn
.val
[0] << 21);
6103 csky_insn
.isize
= 4;
6104 csky_insn
.output
= frag_more (4);
6105 if (insn_reloc
== BFD_RELOC_CKCORE_GOTOFF
)
6107 fix_new_exp (frag_now
, csky_insn
.output
-frag_now
->fr_literal
,
6108 4, &csky_insn
.e1
, 0, BFD_RELOC_CKCORE_GOTOFF_IMM18
);
6111 csky_insn
.inst
|= (csky_insn
.val
[2] - 1);
6113 else if (csky_insn
.val
[2] >= 1 && csky_insn
.val
[2] <= 0x1000
6114 && csky_insn
.flag_force
!= INSN_OPCODE16F
6115 && !IS_CSKY_ARCH_801 (mach_flag
))
6117 csky_insn
.inst
= 0xe4000000 | (csky_insn
.val
[0] << 21);
6118 csky_insn
.inst
|= csky_insn
.val
[1] << 16;
6119 csky_insn
.inst
|= (csky_insn
.val
[2] - 1);
6120 csky_insn
.isize
= 4;
6121 csky_insn
.output
= frag_more (4);
6125 csky_show_error (ERROR_OPERANDS_ILLEGAL
, 0,
6126 (char *)csky_insn
.opcode_end
, NULL
);
6130 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6138 csky_insn
.isize
= 2;
6139 if (csky_insn
.number
== 2)
6141 if (csky_insn
.val
[0] == 14
6142 && csky_insn
.val
[1] >= 0 && csky_insn
.val
[2] <= 0x1fc
6143 && (csky_insn
.val
[1] & 0x3) == 0
6144 && csky_insn
.flag_force
!= INSN_OPCODE32F
)
6146 csky_insn
.inst
= 0x1420 | ((csky_insn
.val
[1] >> 2) & 0x1f);
6147 csky_insn
.inst
|= (csky_insn
.val
[1] << 1) & 0x300;
6149 else if (csky_insn
.val
[0] < 8
6150 && csky_insn
.val
[1] >= 1 && csky_insn
.val
[1] <= 0x100
6151 && csky_insn
.flag_force
!= INSN_OPCODE32F
)
6153 csky_insn
.inst
= 0x2800 | (csky_insn
.val
[0] << 8);
6154 csky_insn
.inst
|= (csky_insn
.val
[1] - 1);
6156 else if (csky_insn
.val
[1] >= 1 && csky_insn
.val
[1] <= 0x10000
6157 && csky_insn
.flag_force
!= INSN_OPCODE16F
6158 && !IS_CSKY_ARCH_801 (mach_flag
))
6160 csky_insn
.inst
= 0xe4001000 | (csky_insn
.val
[0] << 21);
6161 csky_insn
.inst
|= csky_insn
.val
[0] << 16;
6162 csky_insn
.inst
|= (csky_insn
.val
[1] - 1);
6163 csky_insn
.isize
= 4;
6167 csky_show_error (ERROR_OPERANDS_ILLEGAL
, 0,
6168 (char *)csky_insn
.opcode_end
, NULL
);
6172 else if (csky_insn
.number
== 3)
6174 if (csky_insn
.val
[0] == 14
6175 && csky_insn
.val
[1] == 14
6176 && csky_insn
.val
[2] >= 0 && csky_insn
.val
[2] <= 0x1fc
6177 && (csky_insn
.val
[2] & 0x3) == 0
6178 && csky_insn
.flag_force
!= INSN_OPCODE32F
)
6180 csky_insn
.inst
= 0x1420 | ((csky_insn
.val
[2] >> 2) & 0x1f);
6181 csky_insn
.inst
|= (csky_insn
.val
[2] << 1) & 0x300;
6184 else if (csky_insn
.val
[0] < 8
6185 && csky_insn
.val
[0] == csky_insn
.val
[1]
6186 && csky_insn
.val
[2] >= 1 && csky_insn
.val
[2] <= 0x100
6187 && csky_insn
.flag_force
!= INSN_OPCODE32F
)
6189 csky_insn
.inst
= 0x2800 | (csky_insn
.val
[0] << 8);
6190 csky_insn
.inst
|= (csky_insn
.val
[2] - 1);
6192 else if (csky_insn
.val
[0] < 8
6193 && csky_insn
.val
[1] < 8
6194 && csky_insn
.val
[2] >= 1 && csky_insn
.val
[2] <= 0x8
6195 && csky_insn
.flag_force
!= INSN_OPCODE32F
)
6197 csky_insn
.inst
= 0x5803 | (csky_insn
.val
[0] << 5);
6198 csky_insn
.inst
|= csky_insn
.val
[1] << 8;
6199 csky_insn
.inst
|= (csky_insn
.val
[2] - 1) << 2;
6201 else if (csky_insn
.val
[2] >= 1 && csky_insn
.val
[2] <= 0x1000
6202 && csky_insn
.flag_force
!= INSN_OPCODE16F
6203 && !IS_CSKY_ARCH_801 (mach_flag
))
6205 csky_insn
.inst
= 0xe4001000 | (csky_insn
.val
[0] << 21);
6206 csky_insn
.inst
|= csky_insn
.val
[1] << 16;
6207 csky_insn
.inst
|= (csky_insn
.val
[2] - 1);
6208 csky_insn
.isize
= 4;
6212 csky_show_error (ERROR_OPERANDS_ILLEGAL
, 0,
6213 (char *)csky_insn
.opcode_end
, NULL
);
6217 csky_insn
.output
= frag_more (csky_insn
.isize
);
6218 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6224 v2_work_add_sub (void)
6226 if (csky_insn
.number
== 3
6227 && (csky_insn
.val
[0] == csky_insn
.val
[1]
6228 || csky_insn
.val
[0] == csky_insn
.val
[2])
6229 && csky_insn
.val
[0] <= 15
6230 && csky_insn
.val
[1] <= 15
6231 && csky_insn
.val
[2] <= 15)
6233 if (!strstr (csky_insn
.opcode
->mnemonic
, "sub")
6234 || csky_insn
.val
[0] == csky_insn
.val
[1])
6236 csky_insn
.opcode_idx
= 0;
6237 csky_insn
.isize
= 2;
6238 if (csky_insn
.val
[0] == csky_insn
.val
[1])
6239 csky_insn
.val
[1] = csky_insn
.val
[2];
6241 csky_insn
.number
= 2;
6245 if (csky_insn
.isize
== 4
6246 && IS_CSKY_ARCH_801 (mach_flag
))
6248 if (csky_insn
.number
== 3)
6250 if (csky_insn
.val
[0] > 7)
6251 csky_show_error (ERROR_REG_OVER_RANGE
, 1,
6252 (void *)(long)csky_insn
.val
[0], NULL
);
6253 if (csky_insn
.val
[1] > 7)
6254 csky_show_error (ERROR_REG_OVER_RANGE
, 2,
6255 (void *)(long)csky_insn
.val
[1], NULL
);
6256 if (csky_insn
.val
[2] > 7)
6257 csky_show_error (ERROR_REG_OVER_RANGE
, 3,
6258 (void *)(long)csky_insn
.val
[2], NULL
);
6262 if (csky_insn
.val
[0] > 15)
6263 csky_show_error (ERROR_REG_OVER_RANGE
, 1,
6264 (void *)(long)csky_insn
.val
[0], NULL
);
6265 if (csky_insn
.val
[1] > 15)
6266 csky_show_error (ERROR_REG_OVER_RANGE
, 2,
6267 (void *)(long)csky_insn
.val
[1], NULL
);
6272 /* Generate relax or reloc if necessary. */
6273 csky_generate_frags ();
6274 /* Generate the insn by mask. */
6275 csky_generate_insn ();
6276 /* Write inst to frag. */
6277 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6282 v2_work_rotlc (void)
6284 const char *name
= "addc";
6286 = (struct csky_opcode
*) hash_find (csky_opcodes_hash
, name
);
6287 csky_insn
.opcode_idx
= 0;
6288 if (csky_insn
.isize
== 2)
6291 csky_insn
.number
= 2;
6292 csky_insn
.val
[1] = csky_insn
.val
[0];
6296 csky_insn
.number
= 3;
6297 /* addc rz, rx, ry. */
6298 csky_insn
.val
[1] = csky_insn
.val
[0];
6299 csky_insn
.val
[2] = csky_insn
.val
[0];
6301 /* Generate relax or reloc if necessary. */
6302 csky_generate_frags ();
6303 /* Generate the insn by mask. */
6304 csky_generate_insn ();
6305 /* Write inst to frag. */
6306 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6311 v2_work_bgeni (void)
6313 const char *name
= NULL
;
6314 int imm
= csky_insn
.val
[1];
6324 = (struct csky_opcode
*) hash_find (csky_opcodes_hash
, name
);
6325 csky_insn
.opcode_idx
= 0;
6326 csky_insn
.val
[1] = val
;
6328 /* Generate relax or reloc if necessary. */
6329 csky_generate_frags ();
6330 /* Generate the insn by mask. */
6331 csky_generate_insn ();
6332 /* Write inst to frag. */
6333 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6340 const char *name
= "nor";
6342 = (struct csky_opcode
*) hash_find (csky_opcodes_hash
, name
);
6343 csky_insn
.opcode_idx
= 0;
6344 if (csky_insn
.number
== 1)
6346 csky_insn
.val
[1] = csky_insn
.val
[0];
6347 if (csky_insn
.val
[0] < 16)
6349 /* 16 bits nor rz, rz. */
6350 csky_insn
.number
= 2;
6351 csky_insn
.isize
= 2;
6355 csky_insn
.val
[2] = csky_insn
.val
[0];
6356 csky_insn
.number
= 3;
6357 csky_insn
.isize
= 4;
6360 if (csky_insn
.number
== 2)
6362 if (csky_insn
.val
[0] == csky_insn
.val
[1]
6363 && csky_insn
.val
[0] < 16)
6365 /* 16 bits nor rz, rz. */
6366 csky_insn
.number
= 2;
6367 csky_insn
.isize
= 2;
6371 csky_insn
.val
[2] = csky_insn
.val
[1];
6372 csky_insn
.number
= 3;
6373 csky_insn
.isize
= 4;
6377 /* Generate relax or reloc if necessary. */
6378 csky_generate_frags ();
6379 /* Generate the insn by mask. */
6380 csky_generate_insn ();
6381 /* Write inst to frag. */
6382 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6389 if (csky_insn
.e1
.X_add_symbol
== NULL
|| csky_insn
.e1
.X_op
== O_constant
)
6391 csky_show_error (ERROR_UNDEFINE
, 0, (void *)"operand is invalid", NULL
);
6395 if (IS_CSKY_ARCH_801 (mach_flag
))
6397 /* CK801 doesn't have 32-bit bt/bf insns or a jump insn with a
6398 range larger than SCOND_DISP16. Relax to a short jump around
6399 an unconditional branch, and give up if that overflows too. */
6400 csky_insn
.output
= frag_var (rs_machine_dependent
,
6404 csky_insn
.e1
.X_add_symbol
,
6405 csky_insn
.e1
.X_add_number
,
6407 csky_insn
.isize
= 2;
6408 csky_insn
.max
= SCOND_DISP16_LEN
;
6409 csky_insn
.inst
= csky_insn
.opcode
->op16
[0].opcode
;
6411 else if (do_long_jump
&& !IS_CSKY_ARCH_802 (mach_flag
))
6413 /* Generate relax with jcondition.
6414 Note that CK802 doesn't support the JMPI instruction so
6415 we cannot relax to a jump with a 32-bit offset. */
6416 csky_insn
.output
= frag_var (rs_machine_dependent
,
6420 csky_insn
.e1
.X_add_symbol
,
6421 csky_insn
.e1
.X_add_number
,
6423 csky_insn
.isize
= 2;
6424 csky_insn
.max
= JCOND_DISP32_LEN
;
6425 csky_insn
.inst
= csky_insn
.opcode
->op16
[0].opcode
;
6429 /* Generate relax with condition. */
6430 csky_insn
.output
= frag_var (rs_machine_dependent
,
6434 csky_insn
.e1
.X_add_symbol
,
6435 csky_insn
.e1
.X_add_number
,
6437 csky_insn
.isize
= 2;
6438 csky_insn
.max
= COND_DISP16_LEN
;
6439 csky_insn
.inst
= csky_insn
.opcode
->op16
[0].opcode
;
6441 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6449 if (csky_insn
.e1
.X_add_symbol
== NULL
|| csky_insn
.e1
.X_op
== O_constant
)
6451 csky_show_error (ERROR_UNDEFINE
, 0, (void *)"operand is invalid", NULL
);
6456 && !IS_CSKY_ARCH_801 (mach_flag
)
6457 && !IS_CSKY_ARCH_802 (mach_flag
))
6459 csky_insn
.output
= frag_var (rs_machine_dependent
,
6463 csky_insn
.e1
.X_add_symbol
,
6464 csky_insn
.e1
.X_add_number
,
6467 csky_insn
.inst
= csky_insn
.opcode
->op16
[0].opcode
;
6468 csky_insn
.max
= JUNCD_DISP32_LEN
;
6469 csky_insn
.isize
= 2;
6473 /* Generate relax with condition. */
6474 csky_insn
.output
= frag_var (rs_machine_dependent
,
6478 csky_insn
.e1
.X_add_symbol
,
6479 csky_insn
.e1
.X_add_number
,
6481 csky_insn
.isize
= 2;
6482 csky_insn
.max
= UNCD_DISP16_LEN
;
6483 csky_insn
.inst
= csky_insn
.opcode
->op16
[0].opcode
;
6486 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6490 #define SIZE_V2_MOVI16(x) ((addressT)x <= 0xff)
6491 #define SIZE_V2_MOVI32(x) ((addressT)x <= 0xffff)
6492 #define SIZE_V2_MOVIH(x) ((addressT)x <= 0xffffffff && (((addressT)x & 0xffff) == 0))
6497 int reg
= csky_insn
.val
[0];
6498 int output_literal
= csky_insn
.val
[1];
6501 /* If the second operand is O_constant, We can use movi/movih
6503 if (csky_insn
.e1
.X_op
== O_constant
)
6505 /* 801 only has movi16. */
6506 if (SIZE_V2_MOVI16 (csky_insn
.e1
.X_add_number
) && reg
< 8)
6508 /* movi16 instead. */
6509 csky_insn
.output
= frag_more (2);
6510 csky_insn
.inst
= (CSKYV2_INST_MOVI16
| (reg
<< 8)
6511 | (csky_insn
.e1
.X_add_number
));
6512 csky_insn
.isize
= 2;
6515 else if (SIZE_V2_MOVI32 (csky_insn
.e1
.X_add_number
)
6516 && !IS_CSKY_ARCH_801 (mach_flag
))
6518 /* movi32 instead. */
6519 csky_insn
.output
= frag_more (4);
6520 csky_insn
.inst
= (CSKYV2_INST_MOVI32
| (reg
<< 16)
6521 | (csky_insn
.e1
.X_add_number
));
6522 csky_insn
.isize
= 4;
6525 else if (SIZE_V2_MOVIH (csky_insn
.e1
.X_add_number
)
6526 && !IS_CSKY_ARCH_801 (mach_flag
))
6528 /* movih instead. */
6529 csky_insn
.output
= frag_more (4);
6530 csky_insn
.inst
= (CSKYV2_INST_MOVIH
| (reg
<< 16)
6531 | ((csky_insn
.e1
.X_add_number
>> 16) & 0xffff));
6532 csky_insn
.isize
= 4;
6539 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6545 int n
= enter_literal (&csky_insn
.e1
, 0, 0, 0);
6546 /* Create a reference to pool entry. */
6547 csky_insn
.e1
.X_op
= O_symbol
;
6548 csky_insn
.e1
.X_add_symbol
= poolsym
;
6549 csky_insn
.e1
.X_add_number
= n
<< 2;
6551 /* If 16bit force. */
6552 if (csky_insn
.flag_force
== INSN_OPCODE16F
)
6554 /* Generate fixup. */
6557 csky_show_error (ERROR_UNDEFINE
, 0,
6558 (void *)"The register is out of range.", NULL
);
6561 csky_insn
.isize
= 2;
6562 csky_insn
.output
= frag_more (2);
6564 if (insn_reloc
== BFD_RELOC_CKCORE_TLS_GD32
6565 || insn_reloc
== BFD_RELOC_CKCORE_TLS_LDM32
6566 || insn_reloc
== BFD_RELOC_CKCORE_TLS_IE32
)
6568 literal_insn_offset
->tls_addend
.frag
= frag_now
;
6569 literal_insn_offset
->tls_addend
.offset
6570 = csky_insn
.output
- frag_now
->fr_literal
;
6572 csky_insn
.inst
= csky_insn
.opcode
->op16
[0].opcode
| (reg
<< 5);
6574 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
6575 2, &csky_insn
.e1
, 1, BFD_RELOC_CKCORE_PCREL_IMM7BY4
);
6577 else if (csky_insn
.flag_force
== INSN_OPCODE32F
)
6579 csky_insn
.isize
= 4;
6580 csky_insn
.output
= frag_more (4);
6581 if (insn_reloc
== BFD_RELOC_CKCORE_TLS_GD32
6582 || insn_reloc
== BFD_RELOC_CKCORE_TLS_LDM32
6583 || insn_reloc
== BFD_RELOC_CKCORE_TLS_IE32
)
6585 literal_insn_offset
->tls_addend
.frag
= frag_now
;
6586 literal_insn_offset
->tls_addend
.offset
6587 = csky_insn
.output
- frag_now
->fr_literal
;
6589 csky_insn
.inst
= csky_insn
.opcode
->op32
[0].opcode
| (reg
<< 16);
6590 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
6591 4, &csky_insn
.e1
, 1, BFD_RELOC_CKCORE_PCREL_IMM16BY4
);
6597 csky_insn
.isize
= 2;
6599 if (insn_reloc
== BFD_RELOC_CKCORE_TLS_GD32
6600 || insn_reloc
== BFD_RELOC_CKCORE_TLS_LDM32
6601 || insn_reloc
== BFD_RELOC_CKCORE_TLS_IE32
)
6602 literal_insn_offset
->tls_addend
.frag
= frag_now
;
6604 csky_insn
.output
= frag_var (rs_machine_dependent
,
6608 ? LRW2_DISP8
: LRW_DISP7
),
6609 csky_insn
.e1
.X_add_symbol
,
6610 csky_insn
.e1
.X_add_number
, 0);
6611 if (insn_reloc
== BFD_RELOC_CKCORE_TLS_GD32
6612 || insn_reloc
== BFD_RELOC_CKCORE_TLS_LDM32
6613 || insn_reloc
== BFD_RELOC_CKCORE_TLS_IE32
)
6615 if (literal_insn_offset
->tls_addend
.frag
->fr_next
!= frag_now
)
6616 literal_insn_offset
->tls_addend
.frag
6617 = literal_insn_offset
->tls_addend
.frag
->fr_next
;
6618 literal_insn_offset
->tls_addend
.offset
6620 - literal_insn_offset
->tls_addend
.frag
->fr_literal
);
6622 csky_insn
.inst
= csky_insn
.opcode
->op16
[0].opcode
| (reg
<< 5);
6623 csky_insn
.max
= LRW_DISP16_LEN
;
6624 csky_insn
.isize
= 2;
6628 csky_insn
.isize
= 4;
6629 csky_insn
.output
= frag_more (4);
6630 if (insn_reloc
== BFD_RELOC_CKCORE_TLS_GD32
6631 || insn_reloc
== BFD_RELOC_CKCORE_TLS_LDM32
6632 || insn_reloc
== BFD_RELOC_CKCORE_TLS_IE32
)
6634 literal_insn_offset
->tls_addend
.frag
= frag_now
;
6635 literal_insn_offset
->tls_addend
.offset
6636 = csky_insn
.output
- frag_now
->fr_literal
;
6638 csky_insn
.inst
= csky_insn
.opcode
->op32
[0].opcode
| (reg
<< 16);
6639 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
6640 4, &csky_insn
.e1
, 1, BFD_RELOC_CKCORE_PCREL_IMM16BY4
);
6644 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6649 v2_work_lrsrsw (void)
6651 int reg
= csky_insn
.val
[0];
6652 csky_insn
.output
= frag_more (4);
6653 csky_insn
.inst
= csky_insn
.opcode
->op32
[0].opcode
| (reg
<< 21);
6654 csky_insn
.isize
= 4;
6658 case BFD_RELOC_CKCORE_GOT32
:
6659 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
6660 4, &csky_insn
.e1
, 0, BFD_RELOC_CKCORE_GOT_IMM18BY4
);
6662 case BFD_RELOC_CKCORE_PLT32
:
6663 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
6664 4, &csky_insn
.e1
, 0, BFD_RELOC_CKCORE_PLT_IMM18BY4
);
6667 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
6668 4, &csky_insn
.e1
, 1, BFD_RELOC_CKCORE_DOFFSET_IMM18BY4
);
6671 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6679 || IS_CSKY_ARCH_801 (mach_flag
)
6680 || IS_CSKY_ARCH_802 (mach_flag
))
6682 csky_insn
.output
= frag_more (4);
6683 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
6684 4, &csky_insn
.e1
, 1, BFD_RELOC_CKCORE_PCREL_IMM26BY2
);
6685 csky_insn
.isize
= 4;
6686 csky_insn
.inst
= CSKYV2_INST_BSR32
;
6690 int n
= enter_literal (&csky_insn
.e1
, 0, 0, 0);
6691 csky_insn
.output
= frag_more (4);
6692 csky_insn
.e1
.X_op
= O_symbol
;
6693 csky_insn
.e1
.X_add_symbol
= poolsym
;
6694 csky_insn
.e1
.X_add_number
= n
<< 2;
6695 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
6696 4, &csky_insn
.e1
, 1, BFD_RELOC_CKCORE_PCREL_IMM16BY4
);
6697 if (do_jsri2bsr
|| IS_CSKY_ARCH_810 (mach_flag
))
6698 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
6700 &(litpool
+ (csky_insn
.e1
.X_add_number
>> 2))->e
,
6702 BFD_RELOC_CKCORE_PCREL_JSR_IMM26BY2
);
6703 csky_insn
.inst
= CSKYV2_INST_JSRI32
;
6704 csky_insn
.isize
= 4;
6705 if (IS_CSKY_ARCH_810 (mach_flag
))
6707 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6708 csky_insn
.output
= frag_more (4);
6709 dwarf2_emit_insn (0);
6710 /* Insert "mov r0, r0". */
6711 csky_insn
.inst
= CSKYV2_INST_MOV_R0_R0
;
6715 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6724 int n
= enter_literal (&csky_insn
.e1
, 1, 0, 0);
6725 csky_insn
.e1
.X_op
= O_symbol
;
6726 csky_insn
.e1
.X_add_symbol
= poolsym
;
6727 csky_insn
.e1
.X_add_number
= n
<< 2;
6729 /* Generate relax or reloc if necessary. */
6730 csky_generate_frags ();
6731 /* Generate the insn by mask. */
6732 csky_generate_insn ();
6733 /* Write inst to frag. */
6734 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6735 /* Control 810 not to generate jsri. */
6736 if (IS_CSKY_ARCH_810 (mach_flag
))
6738 /* Look at adding the R_PCREL_JSRIMM26BY2.
6739 For 'jbsr .L1', this reloc type's symbol
6740 is bound to '.L1', isn't bound to literal pool. */
6741 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
6742 4, &(litpool
+ (csky_insn
.e1
.X_add_number
>> 2))->e
, 1,
6743 BFD_RELOC_CKCORE_PCREL_JSR_IMM26BY2
);
6744 csky_insn
.output
= frag_more (4);
6745 dwarf2_emit_insn (0);
6746 /* The opcode of "mov32 r0,r0". */
6747 csky_insn
.inst
= CSKYV2_INST_MOV_R0_R0
;
6748 /* The effect of this value is to check literal. */
6749 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6756 v2_work_movih (void)
6758 int rz
= csky_insn
.val
[0];
6759 csky_insn
.output
= frag_more (4);
6760 csky_insn
.inst
= csky_insn
.opcode
->op32
[0].opcode
| (rz
<< 16);
6761 if (csky_insn
.e1
.X_op
== O_constant
)
6763 if (csky_insn
.e1
.X_unsigned
== 1 && csky_insn
.e1
.X_add_number
> 0xffff)
6765 csky_show_error (ERROR_IMM_OVERFLOW
, 2, NULL
, NULL
);
6768 else if (csky_insn
.e1
.X_unsigned
== 0 && csky_insn
.e1
.X_add_number
< 0)
6770 csky_show_error (ERROR_IMM_OVERFLOW
, 2, NULL
, NULL
);
6774 csky_insn
.inst
|= (csky_insn
.e1
.X_add_number
& 0xffff);
6776 else if (csky_insn
.e1
.X_op
== O_right_shift
6777 || (csky_insn
.e1
.X_op
== O_symbol
&& insn_reloc
!= BFD_RELOC_NONE
))
6779 if (csky_insn
.e1
.X_op_symbol
!= 0
6780 && csky_insn
.e1
.X_op_symbol
->sy_value
.X_op
== O_constant
6781 && 16 == csky_insn
.e1
.X_op_symbol
->sy_value
.X_add_number
)
6783 csky_insn
.e1
.X_op
= O_symbol
;
6784 if (insn_reloc
== BFD_RELOC_CKCORE_GOT32
)
6785 insn_reloc
= BFD_RELOC_CKCORE_GOT_HI16
;
6786 else if (insn_reloc
== BFD_RELOC_CKCORE_PLT32
)
6787 insn_reloc
= BFD_RELOC_CKCORE_PLT_HI16
;
6788 else if (insn_reloc
== BFD_RELOC_CKCORE_GOTPC
)
6789 insn_reloc
= BFD_RELOC_CKCORE_GOTPC_HI16
;
6790 else if (insn_reloc
== BFD_RELOC_CKCORE_GOTOFF
)
6791 insn_reloc
= BFD_RELOC_CKCORE_GOTOFF_HI16
;
6793 insn_reloc
= BFD_RELOC_CKCORE_ADDR_HI16
;
6794 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
6795 4, &csky_insn
.e1
, 0, insn_reloc
);
6799 void *arg
= (void *)"the second operand must be \"SYMBOL >> 16\"";
6800 csky_show_error (ERROR_UNDEFINE
, 0, arg
, NULL
);
6804 csky_insn
.isize
= 4;
6805 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6813 int rz
= csky_insn
.val
[0];
6814 int rx
= csky_insn
.val
[1];
6815 csky_insn
.output
= frag_more (4);
6816 csky_insn
.inst
= csky_insn
.opcode
->op32
[0].opcode
| (rz
<< 21) | (rx
<< 16);
6817 if (csky_insn
.e1
.X_op
== O_constant
)
6819 if (csky_insn
.e1
.X_add_number
<= 0xffff
6820 && csky_insn
.e1
.X_add_number
>= 0)
6821 csky_insn
.inst
|= csky_insn
.e1
.X_add_number
;
6824 csky_show_error (ERROR_IMM_OVERFLOW
, 3, NULL
, NULL
);
6828 else if (csky_insn
.e1
.X_op
== O_bit_and
)
6830 if (csky_insn
.e1
.X_op_symbol
->sy_value
.X_op
== O_constant
6831 && 0xffff == csky_insn
.e1
.X_op_symbol
->sy_value
.X_add_number
)
6833 csky_insn
.e1
.X_op
= O_symbol
;
6834 if (insn_reloc
== BFD_RELOC_CKCORE_GOT32
)
6835 insn_reloc
= BFD_RELOC_CKCORE_GOT_LO16
;
6836 else if (insn_reloc
== BFD_RELOC_CKCORE_PLT32
)
6837 insn_reloc
= BFD_RELOC_CKCORE_PLT_LO16
;
6838 else if (insn_reloc
== BFD_RELOC_CKCORE_GOTPC
)
6839 insn_reloc
= BFD_RELOC_CKCORE_GOTPC_LO16
;
6840 else if (insn_reloc
== BFD_RELOC_CKCORE_GOTOFF
)
6841 insn_reloc
= BFD_RELOC_CKCORE_GOTOFF_LO16
;
6843 insn_reloc
= BFD_RELOC_CKCORE_ADDR_LO16
;
6844 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
6845 4, &csky_insn
.e1
, 0, insn_reloc
);
6849 void *arg
= (void *)"the third operand must be \"SYMBOL & 0xffff\"";
6850 csky_show_error (ERROR_UNDEFINE
, 0, arg
, NULL
);
6854 csky_insn
.isize
= 4;
6855 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6859 /* Helper function to encode a single/double floating point constant
6860 into the instruction word for fmovis and fmovid instructions.
6861 The constant is in its IEEE single/double precision representation
6862 and is repacked into the internal 13-bit representation for these
6863 instructions with a diagnostic for overflow. Note that there is no
6864 rounding when converting to the smaller format, just an error if there
6865 is excess precision or the number is too small/large to be represented. */
6868 float_work_fmovi (void)
6870 int rx
= csky_insn
.val
[0];
6872 /* We already converted the float constant to the internal 13-bit
6873 representation so we just need to OR it in here. */
6874 csky_insn
.inst
= csky_insn
.opcode
->op32
[0].opcode
| rx
;
6875 csky_insn
.inst
|= (uint32_t) csky_insn
.e1
.X_add_number
;
6877 csky_insn
.output
= frag_more (4);
6878 csky_insn
.isize
= 4;
6879 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6884 dsp_work_bloop (void)
6886 int reg
= csky_insn
.val
[0];
6887 csky_insn
.output
= frag_more (4);
6888 csky_insn
.inst
= csky_insn
.opcode
->op32
[0].opcode
| (reg
<< 16);
6889 csky_insn
.isize
= 4;
6891 if (csky_insn
.e1
.X_op
== O_symbol
6892 && csky_insn
.e2
.X_op
== O_symbol
)
6894 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
6895 4, &csky_insn
.e1
, 1,
6896 BFD_RELOC_CKCORE_PCREL_BLOOP_IMM12BY4
);
6897 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
6898 4, &csky_insn
.e2
, 1,
6899 BFD_RELOC_CKCORE_PCREL_BLOOP_IMM4BY4
);
6902 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6907 /* The following are for assembler directive handling. */
6909 /* Helper function to adjust constant pool counts when we emit a
6910 data directive in the text section. FUNC is one of the standard
6911 gas functions to handle these directives, like "stringer" for the
6912 .string directive, and ARG is the argument to FUNC. csky_pool_count
6913 essentially wraps the call with the constant pool magic. */
6916 csky_pool_count (void (*func
) (int), int arg
)
6918 const fragS
*curr_frag
= frag_now
;
6919 offsetT added
= -frag_now_fix_octets ();
6923 while (curr_frag
!= frag_now
)
6925 added
+= curr_frag
->fr_fix
;
6926 curr_frag
= curr_frag
->fr_next
;
6929 added
+= frag_now_fix_octets ();
6933 /* Support the .literals directive. */
6935 csky_s_literals (int ignore ATTRIBUTE_UNUSED
)
6938 demand_empty_rest_of_line ();
6941 /* Support the .string, etc directives. */
6943 csky_stringer (int append_zero
)
6945 if (now_seg
== text_section
)
6946 csky_pool_count (stringer
, append_zero
);
6948 stringer (append_zero
);
6950 /* We call check_literals here in case a large number of strings are
6951 being placed into the text section with a sequence of stringer
6952 directives. In theory we could be upsetting something if these
6953 strings are actually in an indexed table instead of referenced by
6954 individual labels. Let us hope that that never happens. */
6955 check_literals (2, 0);
6958 /* Support integer-mode constructors like .word, .byte, etc. */
6961 csky_cons (int nbytes
)
6963 mapping_state (MAP_DATA
);
6964 if (nbytes
== 4) /* @GOT. */
6968 bfd_reloc_code_real_type reloc
;
6971 reloc
= BFD_RELOC_NONE
;
6973 lex_got (&reloc
, NULL
);
6975 if (exp
.X_op
== O_symbol
&& reloc
!= BFD_RELOC_NONE
)
6977 reloc_howto_type
*howto
6978 = bfd_reloc_type_lookup (stdoutput
, reloc
);
6979 int size
= bfd_get_reloc_size (howto
);
6982 as_bad (ngettext ("%s relocations do not fit in %d byte",
6983 "%s relocations do not fit in %d bytes",
6985 howto
->name
, nbytes
);
6988 register char *p
= frag_more ((int) nbytes
);
6989 int offset
= nbytes
- size
;
6991 fix_new_exp (frag_now
,
6992 p
- frag_now
->fr_literal
+ offset
,
6993 size
, &exp
, 0, reloc
);
6997 emit_expr (&exp
, (unsigned int) nbytes
);
6998 if (now_seg
== text_section
)
7001 while (*input_line_pointer
++ == ',');
7003 /* Put terminator back into stream. */
7004 input_line_pointer
--;
7005 demand_empty_rest_of_line ();
7010 if (now_seg
== text_section
)
7011 csky_pool_count (cons
, nbytes
);
7015 /* In theory we ought to call check_literals (2,0) here in case
7016 we need to dump the literal table. We cannot do this however,
7017 as the directives that we are intercepting may be being used
7018 to build a switch table, and we must not interfere with its
7019 contents. Instead we cross our fingers and pray... */
7022 /* Support floating-mode constant directives like .float and .double. */
7025 csky_float_cons (int float_type
)
7027 mapping_state (MAP_DATA
);
7028 if (now_seg
== text_section
)
7029 csky_pool_count (float_cons
, float_type
);
7031 float_cons (float_type
);
7033 /* See the comment in csky_cons () about calling check_literals.
7034 It is unlikely that a switch table will be constructed using
7035 floating point values, but it is still likely that an indexed
7036 table of floating point constants is being created by these
7037 directives, so again we must not interfere with their placement. */
7040 /* Support the .fill directive. */
7043 csky_fill (int ignore
)
7045 if (now_seg
== text_section
)
7046 csky_pool_count (s_fill
, ignore
);
7050 check_literals (2, 0);
7053 /* Handle the section changing pseudo-ops. These call through to the
7054 normal implementations, but they dump the literal pool first. */
7057 csky_s_text (int ignore
)
7062 obj_elf_text (ignore
);
7069 csky_s_data (int ignore
)
7074 obj_elf_data (ignore
);
7081 csky_s_section (int ignore
)
7083 /* Scan forwards to find the name of the section. If the section
7084 being switched to is ".line" then this is a DWARF1 debug section
7085 which is arbitrarily placed inside generated code. In this case
7086 do not dump the literal pool because it is a) inefficient and
7087 b) would require the generation of extra code to jump around the
7089 char * ilp
= input_line_pointer
;
7091 while (*ilp
!= 0 && ISSPACE (*ilp
))
7094 if (strncmp (ilp
, ".line", 5) == 0
7095 && (ISSPACE (ilp
[5]) || *ilp
== '\n' || *ilp
== '\r'))
7101 obj_elf_section (ignore
);
7104 obj_coff_section (ignore
);
7109 csky_s_bss (int needs_align
)
7112 s_lcomm_bytes (needs_align
);
7117 csky_s_comm (int needs_align
)
7120 obj_elf_common (needs_align
);
7124 /* Handle the .no_literal_dump directive. */
7127 csky_noliteraldump (int ignore ATTRIBUTE_UNUSED
)
7129 do_noliteraldump
= 1;
7130 int insn_num
= get_absolute_expression ();
7131 /* The insn after '.no_literal_dump insn_num' is insn1,
7132 Don't dump literal pool between insn1 and insn(insn_num+1)
7133 The insn cannot be the insn generate literal, like lrw & jsri. */
7134 check_literals (0, insn_num
* 2);
7137 /* Handle the .align directive.
7138 We must check literals before doing alignment. For example, if
7139 '.align n', add (2^n-1) to poolspan and check literals. */
7142 csky_s_align_ptwo (int arg
)
7144 /* Get the .align's first absolute number. */
7145 char * temp_pointer
= input_line_pointer
;
7146 int align
= get_absolute_expression ();
7147 check_literals (0, (1 << align
) - 1);
7148 input_line_pointer
= temp_pointer
;
7154 /* Handle the .stack_size directive. */
7157 csky_stack_size (int arg ATTRIBUTE_UNUSED
)
7160 stack_size_entry
*sse
7161 = (stack_size_entry
*) xcalloc (1, sizeof (stack_size_entry
));
7164 if (exp
.X_op
== O_symbol
)
7165 sse
->function
= exp
.X_add_symbol
;
7168 as_bad (_("the first operand must be a symbol"));
7169 ignore_rest_of_line ();
7175 if (*input_line_pointer
!= ',')
7177 as_bad (_("missing stack size"));
7178 ignore_rest_of_line ();
7183 ++input_line_pointer
;
7185 if (exp
.X_op
== O_constant
)
7187 if (exp
.X_add_number
< 0 || exp
.X_add_number
> (offsetT
)0xffffffff)
7190 as_bad (_("value not in range [0, 0xffffffff]"));
7191 ignore_rest_of_line ();
7196 sse
->stack_size
= exp
.X_add_number
;
7200 as_bad (_("operand must be a constant"));
7201 ignore_rest_of_line ();
7206 if (*last_stack_size_data
!= NULL
)
7207 last_stack_size_data
= &((*last_stack_size_data
)->next
);
7209 *last_stack_size_data
= sse
;
7212 /* This table describes all the machine specific pseudo-ops the assembler
7213 has to support. The fields are:
7214 pseudo-op name without dot
7215 function to call to execute this pseudo-op
7216 Integer arg to pass to the function. */
7218 const pseudo_typeS md_pseudo_table
[] =
7220 { "export", s_globl
, 0 },
7221 { "import", s_ignore
, 0 },
7222 { "literals", csky_s_literals
, 0 },
7223 { "page", listing_eject
, 0 },
7225 /* The following are to intercept the placement of data into the text
7226 section (eg addresses for a switch table), so that the space they
7227 occupy can be taken into account when deciding whether or not to
7228 dump the current literal pool.
7229 XXX - currently we do not cope with the .space and .dcb.d directives. */
7230 { "ascii", csky_stringer
, 8 + 0 },
7231 { "asciz", csky_stringer
, 8 + 1 },
7232 { "byte", csky_cons
, 1 },
7233 { "dc", csky_cons
, 2 },
7234 { "dc.b", csky_cons
, 1 },
7235 { "dc.d", csky_float_cons
, 'd'},
7236 { "dc.l", csky_cons
, 4 },
7237 { "dc.s", csky_float_cons
, 'f'},
7238 { "dc.w", csky_cons
, 2 },
7239 { "dc.x", csky_float_cons
, 'x'},
7240 { "double", csky_float_cons
, 'd'},
7241 { "float", csky_float_cons
, 'f'},
7242 { "hword", csky_cons
, 2 },
7243 { "int", csky_cons
, 4 },
7244 { "long", csky_cons
, 4 },
7245 { "octa", csky_cons
, 16 },
7246 { "quad", csky_cons
, 8 },
7247 { "short", csky_cons
, 2 },
7248 { "single", csky_float_cons
, 'f'},
7249 { "string", csky_stringer
, 8 + 1 },
7250 { "word", csky_cons
, 4 },
7251 { "fill", csky_fill
, 0 },
7253 /* Allow for the effect of section changes. */
7254 { "text", csky_s_text
, 0 },
7255 { "data", csky_s_data
, 0 },
7256 { "bss", csky_s_bss
, 1 },
7258 { "comm", csky_s_comm
, 0 },
7260 { "section", csky_s_section
, 0 },
7261 { "section.s", csky_s_section
, 0 },
7262 { "sect", csky_s_section
, 0 },
7263 { "sect.s", csky_s_section
, 0 },
7264 /* When ".no_literal_dump N" is in front of insn1,
7265 and instruction sequence is:
7270 it means literals will not dump between insn1 and insnN+1
7271 The insn cannot itself generate literal, like lrw & jsri. */
7272 { "no_literal_dump", csky_noliteraldump
, 0 },
7273 { "align", csky_s_align_ptwo
, 0 },
7274 { "stack_size", csky_stack_size
, 0 },
7278 /* Implement tc_cfi_frame_initial_instructions. */
7281 csky_cfi_frame_initial_instructions (void)
7283 int sp_reg
= IS_CSKY_V1 (mach_flag
) ? 0 : 14;
7284 cfi_add_CFA_def_cfa_register (sp_reg
);
7287 /* Implement tc_regname_to_dw2regnum. */
7290 tc_csky_regname_to_dw2regnum (char *regname
)
7295 /* FIXME the reg should be parsed according to
7297 reg_num
= csky_get_reg_val (regname
, &len
);