1 /* tc-csky.c -- Assembler for C-SKY
2 Copyright (C) 1989-2020 Free Software Foundation, Inc.
3 Created by Lifang Xia (lifang_xia@c-sky.com)
4 Contributed by C-SKY Microsystems and Mentor Graphics.
6 This file is part of GAS, the GNU Assembler.
8 GAS is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
13 GAS is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GAS; see the file COPYING. If not, write to the Free
20 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
28 #include "safe-ctype.h"
31 #include "libiberty.h"
35 #include "dw2gencfi.h"
38 #include "dwarf2dbg.h"
42 #define OPCODE_MAX_LEN 20
43 #define HAS_SUB_OPERAND 0xfffffffful
45 /* This value is just for lrw to distinguish "[]" label. */
46 #define NEED_OUTPUT_LITERAL 1
48 #define IS_EXTERNAL_SYM(sym, sec) (S_GET_SEGMENT (sym) != sec)
49 #define IS_SUPPORT_OPCODE16(opcode) (opcode->isa_flag16 | isa_flag)
50 #define IS_SUPPORT_OPCODE32(opcode) (opcode->isa_flag32 | isa_flag)
57 /* Define DSP version flags. For different CPU, the version of DSP
58 instructions may be different. */
59 #define CSKY_DSP_FLAG_V1 (1 << 0) /* Normal DSP instructions. */
60 #define CSKY_DSP_FLAG_V2 (1 << 1) /* CK803S enhanced DSP. */
62 /* Literal pool related macros. */
63 /* 1024 - 1 entry - 2 byte rounding. */
64 #define v1_SPANPANIC (998)
65 #define v1_SPANCLOSE (900)
66 #define v1_SPANEXIT (600)
67 #define v2_SPANPANIC (1024 - 4)
69 /* 1024 is flrw offset.
70 24 is the biggest size for single instruction.
71 for lrw16 (3+7, 512 bytes). */
72 #define v2_SPANCLOSE (512 - 24)
74 /* For lrw16, 112 average size for a function. */
75 #define v2_SPANEXIT (512 - 112)
77 /* For lrw16 (3+7, 512 bytes). */
78 #define v2_SPANCLOSE_ELRW (1016 - 24)
80 /* For lrw16, 112 average size for a function. */
81 #define v2_SPANEXIT_ELRW (1016 - 112)
82 #define MAX_POOL_SIZE (1024 / 4)
83 #define POOL_END_LABEL ".LE"
84 #define POOL_START_LABEL ".LS"
86 /* Used in v1_relax_table. */
87 /* These are the two types of relaxable instruction. */
90 #define COND_JUMP_PIC 3
91 #define UNCD_JUMP_PIC 4
96 #define UNDEF_WORD_DISP 3
99 /* Allow for align: bt/jmpi/.long + align. */
101 /* Allow for align: bt/subi/stw/bsr/lrw/add/ld/addi/jmp/.long + align. */
102 #define C32_LEN_PIC 24
104 /* Allow for align: jmpi/.long + align. */
106 /* Allow for align: subi/stw/bsr/lrw/add/ld/addi/jmp/.long + align. */
107 #define U32_LEN_PIC 22
109 #define C(what,length) (((what) << 2) + (length))
110 #define UNCD_JUMP_S (do_pic ? UNCD_JUMP_PIC : UNCD_JUMP)
111 #define COND_JUMP_S (do_pic ? COND_JUMP_PIC : COND_JUMP)
112 #define U32_LEN_S (do_pic ? U32_LEN_PIC : U32_LEN)
113 #define C32_LEN_S (do_pic ? C32_LEN_PIC : C32_LEN)
115 /* Used in v2_relax_table. */
116 #define COND_DISP10_LEN 2 /* bt/bf_16. */
117 #define COND_DISP16_LEN 4 /* bt/bf_32. */
119 #define SCOND_DISP10_LEN 2 /* bt/bf_16, for CK801 only. */
120 #define SCOND_DISP16_LEN 6 /* !(bt/bf_16) + br_32. */
122 #define UNCD_DISP10_LEN 2 /* br_16. */
123 #define UNCD_DISP16_LEN 4 /* br_32. */
124 #define UNCD_DISP26_LEN 4 /* br32_old. */
126 #define JCOND_DISP10_LEN 2 /* bt/bf_16. */
127 #define JCOND_DISP16_LEN 4 /* bt/bf_32. */
128 #define JCOND_DISP32_LEN 12 /* !(bt/bf_16)/jmpi 32/.align 2/literal 4. */
129 #define JCOND_DISP26_LEN 8 /* bt/bf_32/br_32 old. */
131 #define JUNCD_DISP26_LEN 4 /* bt/bf_32 old. */
132 #define JUNCD_DISP10_LEN 2 /* br_16. */
133 #define JUNCD_DISP16_LEN 4 /* bt/bf_32. */
134 #define JUNCD_DISP32_LEN 10 /* jmpi_32/.align 2/literal 4/ CHANGED!. */
135 #define JCOMP_DISP26_LEN 8 /* bne_32/br_32 old. */
137 #define JCOMP_DISP16_LEN 4 /* bne_32 old. */
138 #define JCOMPZ_DISP16_LEN 4 /* bhlz_32. */
139 #define JCOMPZ_DISP32_LEN 14 /* bsz_32/jmpi 32/.align 2/literal 4. */
140 #define JCOMPZ_DISP26_LEN 8 /* bsz_32/br_32 old. */
141 #define JCOMP_DISP32_LEN 14 /* be_32/jmpi_32/.align 2/literal old. */
143 #define BSR_DISP10_LEN 2 /* bsr_16. */
144 #define BSR_DISP26_LEN 4 /* bsr_32. */
145 #define LRW_DISP7_LEN 2 /* lrw16. */
146 #define LRW_DISP16_LEN 4 /* lrw32. */
148 /* Declare worker functions. */
149 bfd_boolean
v1_work_lrw (void);
150 bfd_boolean
v1_work_jbsr (void);
151 bfd_boolean
v1_work_fpu_fo (void);
152 bfd_boolean
v1_work_fpu_fo_fc (void);
153 bfd_boolean
v1_work_fpu_write (void);
154 bfd_boolean
v1_work_fpu_read (void);
155 bfd_boolean
v1_work_fpu_writed (void);
156 bfd_boolean
v1_work_fpu_readd (void);
157 bfd_boolean
v2_work_istack (void);
158 bfd_boolean
v2_work_btsti (void);
159 bfd_boolean
v2_work_addi (void);
160 bfd_boolean
v2_work_subi (void);
161 bfd_boolean
v2_work_add_sub (void);
162 bfd_boolean
v2_work_rotlc (void);
163 bfd_boolean
v2_work_bgeni (void);
164 bfd_boolean
v2_work_not (void);
165 bfd_boolean
v2_work_jbtf (void);
166 bfd_boolean
v2_work_jbr (void);
167 bfd_boolean
v2_work_lrw (void);
168 bfd_boolean
v2_work_lrsrsw (void);
169 bfd_boolean
v2_work_jbsr (void);
170 bfd_boolean
v2_work_jsri (void);
171 bfd_boolean
v2_work_movih (void);
172 bfd_boolean
v2_work_ori (void);
173 bfd_boolean
float_work_fmovi (void);
174 bfd_boolean
dsp_work_bloop (void);
176 /* csky-opc.h must be included after workers are declared. */
177 #include "opcodes/csky-opc.h"
178 #include "opcode/csky.h"
185 COND_DISP10
= 20, /* bt/bf_16. */
186 COND_DISP16
, /* bt/bf_32. */
188 SCOND_DISP10
, /* br_16 */
189 SCOND_DISP16
, /* !(bt/bf_32) + br_32. */
191 UNCD_DISP10
, /* br_16. */
192 UNCD_DISP16
, /* br_32. */
194 JCOND_DISP10
, /* bt/bf_16. */
195 JCOND_DISP16
, /* bt/bf_32. */
196 JCOND_DISP32
, /* !(bt/bf_32)/jmpi + literal. */
198 JUNCD_DISP10
, /* br_16. */
199 JUNCD_DISP16
, /* br_32. */
200 JUNCD_DISP32
, /* jmpi + literal. */
202 JCOMPZ_DISP16
, /* bez/bnez/bhz/blsz/blz/bhsz. */
203 JCOMPZ_DISP32
, /* !(jbez/jbnez/jblsz/jblz/jbhsz) + jmpi + literal. */
205 BSR_DISP26
, /* bsr_32. */
207 LRW_DISP7
, /* lrw16. */
208 LRW2_DISP8
, /* lrw16, -mno-bsr16,8 bit offset. */
209 LRW_DISP16
, /* lrw32. */
212 unsigned int mach_flag
= 0;
213 unsigned int arch_flag
= 0;
214 unsigned int other_flag
= 0;
215 unsigned int isa_flag
= 0;
216 unsigned int dsp_flag
= 0;
218 typedef struct stack_size_entry
220 struct stack_size_entry
*next
;
222 unsigned int stack_size
;
225 struct csky_arch_info
228 unsigned int arch_flag
;
229 unsigned int bfd_mach_flag
;
235 unsigned int mach_flag
;
236 unsigned int isa_flag
;
246 /* Macro information. */
247 struct csky_macro_info
250 /* How many operands : if operands == 5, all of 1,2,3,4 are ok. */
254 void (*handle_func
)(void);
257 struct csky_insn_info
259 /* Name of the opcode. */
261 /* Output instruction. */
263 /* Pointer for frag. */
265 /* End of instruction. */
267 /* Flag for INSN_OPCODE16F, INSN_OPCODE32F, INSN_OPCODE, INSN_MACRO. */
268 inst_flag flag_force
;
269 /* Operand number. */
271 struct csky_opcode
*opcode
;
272 struct csky_macro_info
*macro
;
273 /* Insn size for check_literal. */
275 /* Max size of insn for relax frag_var. */
277 /* Indicates which element is in csky_opcode_info op[] array. */
279 /* The value of each operand in instruction when layout. */
281 int val
[MAX_OPRND_NUM
];
288 /* The following are used for constant expressions. */
293 /* Literal pool data structures. */
296 unsigned short refcnt
;
297 unsigned char ispcrel
;
298 unsigned char unused
;
299 bfd_reloc_code_real_type r_type
;
301 struct tls_addend tls_addend
;
302 unsigned char isdouble
;
306 static void csky_idly (void);
307 static void csky_rolc (void);
308 static void csky_sxtrb (void);
309 static void csky_movtf (void);
310 static void csky_addc64 (void);
311 static void csky_subc64 (void);
312 static void csky_or64 (void);
313 static void csky_xor64 (void);
314 static void csky_neg (void);
315 static void csky_rsubi (void);
316 static void csky_arith (void);
317 static void csky_decne (void);
318 static void csky_lrw (void);
320 static enum bfd_reloc_code_real insn_reloc
;
322 /* Assembler operand parse errors use these identifiers. */
326 /* The following are errors. */
327 ERROR_CREG_ILLEGAL
= 0,
328 ERROR_REG_OVER_RANGE
,
330 ERROR_802J_REG_OVER_RANGE
,
334 ERROR_IMM_OVERFLOW
, /* 5 */
336 ERROR_JMPIX_OVER_RANGE
,
342 ERROR_MISSING_OPERAND
, /* 10 */
344 ERROR_MISSING_LBRACKET
,
345 ERROR_MISSING_RBRACKET
,
346 ERROR_MISSING_LSQUARE_BRACKETS
,
347 ERROR_MISSING_RSQUARE_BRACKETS
, /* 15 */
348 ERROR_MISSING_LANGLE_BRACKETS
,
349 ERROR_MISSING_RANGLE_BRACKETS
,
350 ERROR_OFFSET_UNALIGNED
,
353 ERROR_CPREG_ILLEGAL
, /* 20 */
355 ERROR_OPERANDS_ILLEGAL
,
356 ERROR_OPERANDS_NUMBER
,
357 ERROR_OPCODE_ILLEGAL
,
359 /* The following are warnings. */
363 /* Error and warning end. */
367 /* Global error state. ARG1 and ARG2 are opaque data interpreted
368 as appropriate for the error code. */
370 struct csky_error_state
372 enum error_number err_num
;
378 /* This macro is used to set error number and arg1 in the global state. */
380 #define SET_ERROR_NUMBER(err, msg) \
382 if (error_state.err_num > err) \
384 error_state.err_num = err; \
385 error_state.arg1 = (void *)msg; \
390 /* Map error identifiers onto a format string, which will use
391 arg1 and arg2 from the global error state. */
392 struct csky_error_format_map
394 enum error_number num
;
398 static const struct csky_error_format_map err_formats
[] =
400 {ERROR_CREG_ILLEGAL
, "Operand %d error: control register is illegal."},
401 {ERROR_REG_OVER_RANGE
, "Operand %d error: r%d register is over range."},
402 {ERROR_GREG_ILLEGAL
, "Operand %d error: general register is illegal."},
403 {ERROR_802J_REG_OVER_RANGE
, "Operand %d register %s out of range (802j only has registers:0-15,23,24,25,30)"},
404 {ERROR_REG_FORMAT
, "Operand %d error: %s."},
405 {ERROR_REG_LIST
, "Register list format is illegal."},
406 {ERROR_IMM_ILLEGAL
, "Operand %d is not an immediate."},
407 {ERROR_IMM_OVERFLOW
, "Operand %d immediate is overflow."},
408 {ERROR_IMM_POWER
, "immediate %d is not a power of two"},
409 {ERROR_JMPIX_OVER_RANGE
, "The second operand must be 16/24/32/40"},
410 {ERROR_EXP_CREG
, "Operand %d error: control register is expected."},
411 {ERROR_EXP_GREG
, "Operand %d error: general register is expected."},
412 {ERROR_EXP_CONSTANT
, "Operand %d error: constant is expected."},
413 {ERROR_EXP_EVEN_FREG
, "Operand %d error: even float register is expected."},
414 {ERROR_RELOC_ILLEGAL
, "@%s reloc is not supported"},
415 {ERROR_MISSING_OPERAND
, "Operand %d is missing."},
416 {ERROR_MISSING_COMMA
, "Missing ','"},
417 {ERROR_MISSING_LBRACKET
, "Missing '('"},
418 {ERROR_MISSING_RBRACKET
, "Missing ')'"},
419 {ERROR_MISSING_LSQUARE_BRACKETS
, "Missing '['"},
420 {ERROR_MISSING_RSQUARE_BRACKETS
, "Missing ']'"},
421 {ERROR_MISSING_LANGLE_BRACKETS
, "Missing '<'"},
422 {ERROR_MISSING_RANGLE_BRACKETS
, "Missing '>'"},
423 {ERROR_OFFSET_UNALIGNED
, "Operand %d is unaligned. It must be %d aligned!"},
424 {ERROR_BAD_END
, "Operands mismatch, it has a bad end: %s"},
425 {ERROR_UNDEFINE
, NULL
},
426 {ERROR_CPREG_ILLEGAL
, "Operand %d illegal, expect a cpreg(cpr0-cpr63)."},
427 {ERROR_OPCODE_PSRBIT
, "The operands must be 'ie'/'ee'/'fe'."},
428 {ERROR_OPERANDS_ILLEGAL
, "Operands mismatch: %s."},
429 {ERROR_OPERANDS_NUMBER
, "Operands number mismatch, %d operands expected."},
430 {ERROR_OPCODE_ILLEGAL
, "The instruction is not recognized."},
431 {WARNING_OPTIONS
, "Option %s is not support in %s."},
432 {WARNING_IDLY
, "idly %d is encoded to: idly 4 "},
433 {ERROR_NONE
, "There is no error."},
436 static int do_pic
= 0; /* for jbr/jbf/jbt relax jmpi reloc. */
437 static int do_pff
= -1; /* for insert two br ahead of literals. */
438 static int do_force2bsr
= -1; /* for jbsr->bsr. */
439 static int do_jsri2bsr
= 1; /* for jsri->bsr. */
440 static int do_nolrw
= 0; /* lrw to movih & ori, only for V2. */
441 static int do_long_jump
= -1; /* control if jbf,jbt,jbr relax to jmpi. */
442 static int do_extend_lrw
= -1; /* delete bsr16 in both two options,
443 add btesti16, lrw offset +1 in -melrw. */
444 static int do_func_dump
= 0; /* dump literals after every function. */
445 static int do_br_dump
= 1; /* work for -mabr/-mno-abr, control the literals dump. */
446 static int do_intr_stack
= -1; /* control interrupt stack module, 801&802&803
447 default on, 807&810, default off. */
449 #ifdef INCLUDE_BRANCH_STUB
450 static int do_use_branchstub
= -1;
452 static int do_use_branchstub
= 0;
455 /* These are only used for options parsing. Values are bitmasks and are
456 OR'ed into the processor flag bits in md_begin. */
457 static int do_opt_mmp
= 0;
458 static int do_opt_mcp
= 0;
459 static int do_opt_mcache
= 0;
460 static int do_opt_msecurity
= 0;
461 static int do_opt_mhard_float
= 0;
462 static int do_opt_mtrust
= 0;
463 static int do_opt_mdsp
= 0;
464 static int do_opt_medsp
= 0;
465 static int do_opt_mvdsp
= 0;
467 const relax_typeS
*md_relax_table
= NULL
;
468 struct literal
*literal_insn_offset
;
469 static struct literal litpool
[MAX_POOL_SIZE
];
470 static unsigned poolsize
= 0;
471 static unsigned poolnumber
= 0;
472 static unsigned long poolspan
= 0;
473 static unsigned int SPANPANIC
;
474 static unsigned int SPANCLOSE
;
475 static unsigned int SPANEXIT
;
477 static stack_size_entry
*all_stack_size_data
= NULL
;
478 static stack_size_entry
**last_stack_size_data
= &all_stack_size_data
;
480 /* Control by ".no_literal_dump N"
481 * 1 : don't dump literal pool between insn1 and insnN+1
483 static int do_noliteraldump
= 0;
485 /* Label for current pool. */
486 static symbolS
* poolsym
;
487 static char poolname
[8];
489 static bfd_boolean mov_r1_before
;
490 static bfd_boolean mov_r1_after
;
492 const relax_typeS csky_relax_table
[] =
494 /* C-SKY V1 relax table. */
495 {0, 0, 0, 0}, /* RELAX_NONE */
496 {0, 0, 0, 0}, /* RELAX_OVERFLOW */
501 { 0, 0, 0, 0 }, /* UNDEF_DISP */
502 { 2048, -2046, C12_LEN
, C (COND_JUMP
, DISP32
) }, /* DISP12 */
503 { 0, 0, C32_LEN
, 0 }, /* DISP32 */
504 { 0, 0, C32_LEN
, 0 }, /* UNDEF_WORD_DISP */
507 { 0, 0, 0, 0 }, /* UNDEF_DISP */
508 { 2048, -2046, U12_LEN
, C (UNCD_JUMP
, DISP32
) }, /* DISP12 */
509 { 0, 0, U32_LEN
, 0 }, /* DISP32 */
510 { 0, 0, U32_LEN
, 0 }, /* UNDEF_WORD_DISP */
513 { 0, 0, 0, 0 }, /* UNDEF_DISP */
514 { 2048, -2046, C12_LEN
, C (COND_JUMP_PIC
, DISP32
) }, /* DISP12 */
515 { 0, 0, C32_LEN_PIC
, 0 }, /* DISP32 */
516 { 0, 0, C32_LEN_PIC
, 0 }, /* UNDEF_WORD_DISP */
519 { 0, 0, 0, 0 }, /* UNDEF_DISP */
520 { 2048, -2046, U12_LEN
, C (UNCD_JUMP_PIC
, DISP32
) }, /* DISP12 */
521 { 0, 0, U32_LEN_PIC
, 0 }, /* DISP32 */
522 { 0, 0, U32_LEN_PIC
, 0 }, /* UNDEF_WORD_DISP */
524 /* C-SKY V2 relax table. */
525 /* forward backward length more */
526 { 1 KB
- 2, -1 KB
, COND_DISP10_LEN
, COND_DISP16
}, /* COND_DISP10 */
527 { 64 KB
- 2, -64 KB
, COND_DISP16_LEN
, RELAX_OVERFLOW
}, /* COND_DISP16 */
529 { 1 KB
- 2, -1 KB
, SCOND_DISP10_LEN
, SCOND_DISP16
}, /* SCOND_DISP10 */
530 { 64 KB
- 2, -64 KB
, SCOND_DISP16_LEN
, RELAX_OVERFLOW
}, /* SCOND_DISP16 */
532 { 1 KB
- 2, -1 KB
, UNCD_DISP10_LEN
, UNCD_DISP16
}, /* UNCD_DISP10 */
533 { 64 KB
- 2, -64 KB
, UNCD_DISP16_LEN
, RELAX_OVERFLOW
}, /* UNCD_DISP16 */
535 { 1 KB
- 2, -1 KB
, JCOND_DISP10_LEN
, JCOND_DISP16
}, /* JCOND_DISP10 */
536 { 64 KB
- 2, -64 KB
, JCOND_DISP16_LEN
, JCOND_DISP32
}, /* JCOND_DISP16 */
537 { 0, 0, JCOND_DISP32_LEN
, RELAX_NONE
}, /* JCOND_DISP32 */
539 { 1 KB
- 2, -1 KB
, JUNCD_DISP10_LEN
, JUNCD_DISP16
}, /* JUNCD_DISP10 */
540 { 64 KB
- 2, -64 KB
, JUNCD_DISP16_LEN
, JUNCD_DISP32
}, /* JUNCD_DISP16 */
541 { 0, 0, JUNCD_DISP32_LEN
, RELAX_NONE
}, /* JUNCD_DISP32 */
543 { 64 KB
- 2, -64 KB
, JCOMPZ_DISP16_LEN
, JCOMPZ_DISP32
}, /* JCOMPZ_DISP16 */
544 { 0, 0, JCOMPZ_DISP32_LEN
, RELAX_NONE
}, /* JCOMPZ_DISP32 */
546 { 64 MB
- 2, -64 MB
, BSR_DISP26_LEN
, RELAX_OVERFLOW
}, /* BSR_DISP26 */
548 { 508, 0, LRW_DISP7_LEN
, LRW_DISP16
}, /* LRW_DISP7 */
549 { 1016, 0, LRW_DISP7_LEN
, LRW_DISP16
}, /* LRW2_DISP8 */
550 { 64 KB
, 0, LRW_DISP16_LEN
, RELAX_OVERFLOW
}, /* LRW_DISP16 */
554 static void csky_write_insn (char *ptr
, valueT use
, int nbytes
);
555 void md_number_to_chars (char * buf
, valueT val
, int n
);
556 long md_pcrel_from_section (fixS
* fixP
, segT seg
);
558 /* C-SKY architecture table. */
559 const struct csky_arch_info csky_archs
[] =
561 {"ck510", CSKY_ARCH_510
, bfd_mach_ck510
},
562 {"ck610", CSKY_ARCH_610
, bfd_mach_ck610
},
563 {"ck801", CSKY_ARCH_801
, bfd_mach_ck801
},
564 {"ck802", CSKY_ARCH_802
, bfd_mach_ck802
},
565 {"ck803", CSKY_ARCH_803
, bfd_mach_ck803
},
566 #define CSKY_ARCH_807_BASE CSKY_ARCH_807 | CSKY_ARCH_DSP
567 #define CSKY_ARCH_810_BASE CSKY_ARCH_810 | CSKY_ARCH_DSP
568 {"ck807", CSKY_ARCH_807_BASE
, bfd_mach_ck807
},
569 {"ck810", CSKY_ARCH_810_BASE
, bfd_mach_ck810
},
573 /* C-SKY cpus table. */
574 const struct csky_cpu_info csky_cpus
[] =
577 #define CSKYV1_ISA_DSP CSKY_ISA_DSP | CSKY_ISA_MAC_DSP
578 {"ck510", CSKY_ARCH_510
, CSKYV1_ISA_E1
},
579 {"ck510e", CSKY_ARCH_510
| CSKY_ARCH_DSP
, CSKYV1_ISA_E1
| CSKYV1_ISA_DSP
},
580 {"ck520", CSKY_ARCH_510
| CSKY_ARCH_MAC
, CSKYV1_ISA_E1
| CSKY_ISA_MAC
| CSKY_ISA_MAC_DSP
},
582 #define CSKY_ISA_610 CSKYV1_ISA_E1 | CSKY_ISA_CP
584 {"ck610", CSKY_ARCH_610
, CSKY_ISA_610
},
585 {"ck610e", CSKY_ARCH_610
| CSKY_ARCH_DSP
, CSKY_ISA_610
| CSKYV1_ISA_DSP
},
586 {"ck610f", CSKY_ARCH_610
| CSKY_ARCH_FLOAT
, CSKY_ISA_610
| CSKY_ISA_FLOAT_E1
},
587 {"ck610ef", CSKY_ARCH_610
| CSKY_ARCH_FLOAT
| CSKY_ARCH_DSP
, CSKY_ISA_610
| CSKY_ISA_FLOAT_E1
| CSKYV1_ISA_DSP
},
588 {"ck610fe", CSKY_ARCH_610
| CSKY_ARCH_FLOAT
| CSKY_ARCH_DSP
, CSKY_ISA_610
| CSKY_ISA_FLOAT_E1
| CSKYV1_ISA_DSP
},
589 {"ck620", CSKY_ARCH_610
| CSKY_ARCH_MAC
, CSKY_ISA_610
| CSKY_ISA_MAC
| CSKY_ISA_MAC_DSP
},
592 #define CSKY_ISA_801 CSKYV2_ISA_E1
593 #define CSKYV2_ISA_DSP (CSKY_ISA_DSP | CSKY_ISA_DSP_1E2)
594 {"ck801", CSKY_ARCH_801
, CSKY_ISA_801
},
595 {"ck801t", CSKY_ARCH_801
, CSKY_ISA_801
| CSKY_ISA_TRUST
},
598 #define CSKY_ISA_802 (CSKY_ISA_801 | CSKYV2_ISA_1E2 | CSKY_ISA_NVIC)
599 {"ck802", CSKY_ARCH_802
, CSKY_ISA_802
},
600 {"ck802j", CSKY_ARCH_802
| CSKY_ARCH_JAVA
, CSKY_ISA_802
| CSKY_ISA_JAVA
},
601 {"ck802t", CSKY_ARCH_802
, CSKY_ISA_802
| CSKY_ISA_TRUST
},
604 #define CSKY_ISA_803 (CSKY_ISA_802 | CSKYV2_ISA_2E3 | CSKY_ISA_MP)
605 #define CSKY_ISA_803R1 (CSKY_ISA_803 | CSKYV2_ISA_3E3R1)
606 #define CSKY_ISA_FLOAT_803 (CSKY_ISA_FLOAT_E1 | CSKY_ISA_FLOAT_1E3)
607 {"ck803", CSKY_ARCH_803
, CSKY_ISA_803
},
608 {"ck803h", CSKY_ARCH_803
, CSKY_ISA_803
},
609 {"ck803t", CSKY_ARCH_803
, CSKY_ISA_803
| CSKY_ISA_TRUST
},
610 {"ck803ht", CSKY_ARCH_803
, CSKY_ISA_803
| CSKY_ISA_TRUST
},
611 {"ck803f", CSKY_ARCH_803
| CSKY_ARCH_FLOAT
, CSKY_ISA_803
| CSKY_ISA_FLOAT_803
},
612 {"ck803fh", CSKY_ARCH_803
| CSKY_ARCH_FLOAT
, CSKY_ISA_803
| CSKY_ISA_FLOAT_803
},
613 {"ck803e", CSKY_ARCH_803
| CSKY_ARCH_DSP
, CSKY_ISA_803
| CSKYV2_ISA_DSP
},
614 {"ck803eh", CSKY_ARCH_803
| CSKY_ARCH_DSP
, CSKY_ISA_803
| CSKYV2_ISA_DSP
},
615 {"ck803et", CSKY_ARCH_803
| CSKY_ARCH_DSP
, CSKY_ISA_803
| CSKYV2_ISA_DSP
| CSKY_ISA_TRUST
},
616 {"ck803eht", CSKY_ARCH_803
| CSKY_ARCH_DSP
, CSKY_ISA_803
| CSKYV2_ISA_DSP
| CSKY_ISA_TRUST
},
617 {"ck803ef", CSKY_ARCH_803
| CSKY_ARCH_DSP
| CSKY_ARCH_FLOAT
, CSKY_ISA_803
| CSKYV2_ISA_DSP
| CSKY_ISA_FLOAT_803
},
618 {"ck803efh", CSKY_ARCH_803
| CSKY_ARCH_DSP
| CSKY_ARCH_FLOAT
, CSKY_ISA_803
| CSKYV2_ISA_DSP
| CSKY_ISA_FLOAT_803
},
619 {"ck803ft", CSKY_ARCH_803
| CSKY_ARCH_FLOAT
, CSKY_ISA_803
| CSKY_ISA_FLOAT_803
| CSKY_ISA_TRUST
},
620 {"ck803eft", CSKY_ARCH_803
| CSKY_ARCH_DSP
| CSKY_ARCH_FLOAT
, CSKY_ISA_803
| CSKYV2_ISA_DSP
| CSKY_ISA_FLOAT_803
| CSKY_ISA_TRUST
},
621 {"ck803efht", CSKY_ARCH_803
| CSKY_ARCH_DSP
| CSKY_ARCH_FLOAT
, CSKY_ISA_803
| CSKYV2_ISA_DSP
| CSKY_ISA_FLOAT_803
| CSKY_ISA_TRUST
},
622 {"ck803r1", CSKY_ARCH_803
, CSKY_ISA_803R1
},
623 {"ck803hr1", CSKY_ARCH_803
, CSKY_ISA_803R1
},
624 {"ck803tr1", CSKY_ARCH_803
, CSKY_ISA_803R1
| CSKY_ISA_TRUST
},
625 {"ck803htr1", CSKY_ARCH_803
, CSKY_ISA_803R1
| CSKY_ISA_TRUST
},
626 {"ck803fr1", CSKY_ARCH_803
| CSKY_ARCH_FLOAT
, CSKY_ISA_803R1
| CSKY_ISA_FLOAT_803
},
627 {"ck803fhr1", CSKY_ARCH_803
| CSKY_ARCH_FLOAT
, CSKY_ISA_803R1
| CSKY_ISA_FLOAT_803
},
628 {"ck803er1", CSKY_ARCH_803
| CSKY_ARCH_DSP
, CSKY_ISA_803R1
| CSKY_ISA_DSP_ENHANCE
},
629 {"ck803ehr1", CSKY_ARCH_803
| CSKY_ARCH_DSP
, CSKY_ISA_803R1
| CSKY_ISA_DSP_ENHANCE
},
630 {"ck803etr1", CSKY_ARCH_803
| CSKY_ARCH_DSP
, CSKY_ISA_803R1
| CSKY_ISA_DSP_ENHANCE
| CSKY_ISA_TRUST
},
631 {"ck803ehtr1", CSKY_ARCH_803
| CSKY_ARCH_DSP
, CSKY_ISA_803R1
| CSKY_ISA_DSP_ENHANCE
| CSKY_ISA_TRUST
},
632 {"ck803efr1", CSKY_ARCH_803
| CSKY_ARCH_DSP
| CSKY_ARCH_FLOAT
, CSKY_ISA_803R1
| CSKY_ISA_DSP_ENHANCE
| CSKY_ISA_FLOAT_803
},
633 {"ck803efhr1", CSKY_ARCH_803
| CSKY_ARCH_DSP
| CSKY_ARCH_FLOAT
, CSKY_ISA_803R1
| CSKY_ISA_DSP_ENHANCE
| CSKY_ISA_FLOAT_803
},
634 {"ck803ftr1", CSKY_ARCH_803
| CSKY_ARCH_FLOAT
, CSKY_ISA_803R1
| CSKY_ISA_FLOAT_803
| CSKY_ISA_TRUST
},
635 {"ck803eftr1", CSKY_ARCH_803
| CSKY_ARCH_DSP
| CSKY_ARCH_FLOAT
, CSKY_ISA_803R1
| CSKY_ISA_DSP_ENHANCE
| CSKY_ISA_FLOAT_803
| CSKY_ISA_TRUST
},
636 {"ck803ehftr1", CSKY_ARCH_803
| CSKY_ARCH_DSP
| CSKY_ARCH_FLOAT
, CSKY_ISA_803R1
| CSKY_ISA_DSP_ENHANCE
| CSKY_ISA_FLOAT_803
| CSKY_ISA_TRUST
},
638 {"ck803s", CSKY_ARCH_803
, CSKY_ISA_803R1
},
639 {"ck803se", CSKY_ARCH_803
| CSKY_ARCH_DSP
, CSKY_ISA_803R1
| CSKYV2_ISA_DSP
},
640 {"ck803sj", CSKY_ARCH_803
| CSKY_ARCH_JAVA
, CSKY_ISA_803R1
| CSKY_ISA_JAVA
},
641 {"ck803sf", CSKY_ARCH_803
| CSKY_ARCH_FLOAT
, CSKY_ISA_803R1
| CSKY_ISA_FLOAT_803
},
642 {"ck803sef", CSKY_ARCH_803
| CSKY_ARCH_DSP
| CSKY_ARCH_FLOAT
, CSKY_ISA_803R1
| CSKYV2_ISA_DSP
| CSKY_ISA_FLOAT_803
},
643 {"ck803st", CSKY_ARCH_803
, CSKY_ISA_803R1
| CSKY_ISA_TRUST
},
646 #define CSKY_ISA_807 (CSKY_ISA_803 | CSKYV2_ISA_3E7 | CSKY_ISA_DSP | CSKY_ISA_MP_1E2 | CSKY_ISA_CACHE)
647 #define CSKY_ISA_FLOAT_807 (CSKY_ISA_FLOAT_803 | CSKY_ISA_FLOAT_3E4 | CSKY_ISA_FLOAT_1E2)
648 {"ck807e", CSKY_ARCH_807_BASE
, CSKY_ISA_807
| CSKYV2_ISA_DSP
},
649 {"ck807ef", CSKY_ARCH_807_BASE
| CSKY_ARCH_FLOAT
, CSKY_ISA_807
| CSKYV2_ISA_DSP
| CSKY_ISA_FLOAT_807
},
650 {"ck807", CSKY_ARCH_807_BASE
, CSKY_ISA_807
| CSKYV2_ISA_DSP
},
651 {"ck807f", CSKY_ARCH_807_BASE
| CSKY_ARCH_FLOAT
, CSKY_ISA_807
| CSKYV2_ISA_DSP
| CSKY_ISA_FLOAT_807
},
654 #define CSKY_ISA_810 (CSKY_ISA_807 | CSKYV2_ISA_7E10)
655 #define CSKY_ISA_FLOAT_810 (CSKY_ISA_FLOAT_E1 | CSKY_ISA_FLOAT_1E2)
656 {"ck810e", CSKY_ARCH_810_BASE
, CSKY_ISA_810
| CSKYV2_ISA_DSP
},
657 {"ck810et", CSKY_ARCH_810_BASE
, CSKY_ISA_810
| CSKYV2_ISA_DSP
| CSKY_ISA_TRUST
},
658 {"ck810ef", CSKY_ARCH_810_BASE
| CSKY_ARCH_FLOAT
, CSKY_ISA_810
| CSKYV2_ISA_DSP
| CSKY_ISA_FLOAT_810
},
659 {"ck810eft", CSKY_ARCH_810_BASE
| CSKY_ARCH_FLOAT
, CSKY_ISA_810
| CSKYV2_ISA_DSP
| CSKY_ISA_FLOAT_810
| CSKY_ISA_TRUST
},
660 {"ck810", CSKY_ARCH_810_BASE
, CSKY_ISA_810
| CSKYV2_ISA_DSP
},
661 {"ck810v", CSKY_ARCH_810_BASE
, CSKY_ISA_810
| CSKYV2_ISA_DSP
| CSKY_ISA_VDSP
},
662 {"ck810f", CSKY_ARCH_810_BASE
| CSKY_ARCH_FLOAT
, CSKY_ISA_810
| CSKYV2_ISA_DSP
| CSKY_ISA_FLOAT_810
},
663 {"ck810t", CSKY_ARCH_810_BASE
, CSKY_ISA_810
| CSKYV2_ISA_DSP
| CSKY_ISA_TRUST
},
664 {"ck810tv", CSKY_ARCH_810_BASE
, CSKY_ISA_810
| CSKYV2_ISA_DSP
| CSKY_ISA_TRUST
},
665 {"ck810ft", CSKY_ARCH_810_BASE
| CSKY_ARCH_FLOAT
, CSKY_ISA_810
| CSKYV2_ISA_DSP
| CSKY_ISA_VDSP
| CSKY_ISA_FLOAT_810
| CSKY_ISA_TRUST
},
666 {"ck810ftv", CSKY_ARCH_810_BASE
| CSKY_ARCH_FLOAT
, CSKY_ISA_810
| CSKYV2_ISA_DSP
| CSKY_ISA_VDSP
| CSKY_ISA_FLOAT_810
| CSKY_ISA_TRUST
},
671 int md_short_jump_size
= 2;
672 int md_long_jump_size
= 4;
674 /* This array holds the chars that always start a comment. If the
675 pre-processor is disabled, these aren't very useful. */
676 const char comment_chars
[] = "#";
678 /* This array holds the chars that only start a comment at the beginning of
679 a line. If the line seems to have the form '# 123 filename'
680 .line and .file directives will appear in the pre-processed output. */
681 /* Note that input_file.c hand checks for '#' at the beginning of the
682 first line of the input file. This is because the compiler outputs
683 #NO_APP at the beginning of its output. */
684 /* Also note that comments like this one will always work. */
685 const char line_comment_chars
[] = "#";
687 const char line_separator_chars
[] = ";";
689 /* Chars that can be used to separate mant
690 from exp in floating point numbers. */
691 const char EXP_CHARS
[] = "eE";
693 /* Chars that mean this number is a floating point constant.
697 const char FLT_CHARS
[] = "rRsSfFdDxXeEpP";
699 const char *md_shortopts
= "";
701 struct option md_longopts
[] = {
702 #define OPTION_MARCH (OPTION_MD_BASE + 0)
703 {"march", required_argument
, NULL
, OPTION_MARCH
},
704 #define OPTION_MCPU (OPTION_MD_BASE + 1)
705 {"mcpu", required_argument
, NULL
, OPTION_MCPU
},
707 /* Remaining options just set boolean flags. */
708 {"EL", no_argument
, &target_big_endian
, 0},
709 {"mlittle-endian", no_argument
, &target_big_endian
, 0},
710 {"EB", no_argument
, &target_big_endian
, 1},
711 {"mbig-endian", no_argument
, &target_big_endian
, 1},
712 {"fpic", no_argument
, &do_pic
, 1},
713 {"pic", no_argument
, &do_pic
, 1},
714 {"mljump", no_argument
, &do_long_jump
, 1},
715 {"mno-ljump", no_argument
, &do_long_jump
, 0},
716 {"force2bsr", no_argument
, &do_force2bsr
, 1},
717 {"mforce2bsr", no_argument
, &do_force2bsr
, 1},
718 {"no-force2bsr", no_argument
, &do_force2bsr
, 0},
719 {"mno-force2bsr", no_argument
, &do_force2bsr
, 0},
720 {"jsri2bsr", no_argument
, &do_jsri2bsr
, 1},
721 {"mjsri2bsr", no_argument
, &do_jsri2bsr
, 1},
722 {"no-jsri2bsr", no_argument
, &do_jsri2bsr
, 0},
723 {"mno-jsri2bsr", no_argument
, &do_jsri2bsr
, 0},
724 {"mnolrw", no_argument
, &do_nolrw
, 1},
725 {"mno-lrw", no_argument
, &do_nolrw
, 1},
726 {"melrw", no_argument
, &do_extend_lrw
, 1},
727 {"mno-elrw", no_argument
, &do_extend_lrw
, 0},
728 {"mlaf", no_argument
, &do_func_dump
, 1},
729 {"mliterals-after-func", no_argument
, &do_func_dump
, 1},
730 {"mno-laf", no_argument
, &do_func_dump
, 0},
731 {"mno-literals-after-func", no_argument
, &do_func_dump
, 0},
732 {"mlabr", no_argument
, &do_br_dump
, 1},
733 {"mliterals-after-br", no_argument
, &do_br_dump
, 1},
734 {"mno-labr", no_argument
, &do_br_dump
, 0},
735 {"mnoliterals-after-br", no_argument
, &do_br_dump
, 0},
736 {"mistack", no_argument
, &do_intr_stack
, 1},
737 {"mno-istack", no_argument
, &do_intr_stack
, 0},
738 #ifdef INCLUDE_BRANCH_STUB
739 {"mbranch-stub", no_argument
, &do_use_branchstub
, 1},
740 {"mno-branch-stub", no_argument
, &do_use_branchstub
, 0},
742 {"mhard-float", no_argument
, &do_opt_mhard_float
, CSKY_ARCH_FLOAT
},
743 {"mmp", no_argument
, &do_opt_mmp
, CSKY_ARCH_MP
},
744 {"mcp", no_argument
, &do_opt_mcp
, CSKY_ARCH_CP
},
745 {"mcache", no_argument
, &do_opt_mcache
, CSKY_ARCH_CACHE
},
746 {"msecurity", no_argument
, &do_opt_msecurity
, CSKY_ARCH_MAC
},
747 {"mtrust", no_argument
, &do_opt_mtrust
, CSKY_ISA_TRUST
},
748 {"mdsp", no_argument
, &do_opt_mdsp
, CSKY_DSP_FLAG_V1
},
749 {"medsp", no_argument
, &do_opt_medsp
, CSKY_DSP_FLAG_V2
},
750 {"mvdsp", no_argument
, &do_opt_mvdsp
, CSKY_ISA_VDSP
},
753 size_t md_longopts_size
= sizeof (md_longopts
);
755 static struct csky_insn_info csky_insn
;
757 static htab_t csky_opcodes_hash
;
758 static htab_t csky_macros_hash
;
760 static struct csky_macro_info v1_macros_table
[] =
762 {"idly", 1, CSKYV1_ISA_E1
, csky_idly
},
763 {"rolc", 2, CSKYV1_ISA_E1
, csky_rolc
},
764 {"rotlc", 2, CSKYV1_ISA_E1
, csky_rolc
},
765 {"sxtrb0", 2, CSKYV1_ISA_E1
, csky_sxtrb
},
766 {"sxtrb1", 2, CSKYV1_ISA_E1
, csky_sxtrb
},
767 {"sxtrb2", 2, CSKYV1_ISA_E1
, csky_sxtrb
},
768 {"movtf", 3, CSKYV1_ISA_E1
, csky_movtf
},
769 {"addc64", 3, CSKYV1_ISA_E1
, csky_addc64
},
770 {"subc64", 3, CSKYV1_ISA_E1
, csky_subc64
},
771 {"or64", 3, CSKYV1_ISA_E1
, csky_or64
},
772 {"xor64", 3, CSKYV1_ISA_E1
, csky_xor64
},
776 static struct csky_macro_info v2_macros_table
[] =
778 {"neg", 1, CSKYV2_ISA_E1
, csky_neg
},
779 {"rsubi", 2, CSKYV2_ISA_1E2
, csky_rsubi
},
780 {"incf", 1, CSKYV2_ISA_1E2
, csky_arith
},
781 {"inct", 1, CSKYV2_ISA_1E2
, csky_arith
},
782 {"decf", 1, CSKYV2_ISA_2E3
, csky_arith
},
783 {"decgt", 1, CSKYV2_ISA_2E3
, csky_arith
},
784 {"declt", 1, CSKYV2_ISA_2E3
, csky_arith
},
785 {"decne", 1, CSKYV2_ISA_1E2
, csky_decne
},
786 {"dect", 1, CSKYV2_ISA_1E2
, csky_arith
},
787 {"lslc", 1, CSKYV2_ISA_1E2
, csky_arith
},
788 {"lsrc", 1, CSKYV2_ISA_1E2
, csky_arith
},
789 {"xsr", 1, CSKYV2_ISA_1E2
, csky_arith
},
793 /* For option -mnolrw, replace lrw by movih & ori. */
794 static struct csky_macro_info v2_lrw_macro_opcode
=
795 {"lrw", 2, CSKYV2_ISA_1E2
, csky_lrw
};
797 /* This function is used to show errors or warnings. */
800 csky_show_error (enum error_number err
, int idx
, void *arg1
, void *arg2
)
802 if (err
== ERROR_NONE
)
808 case ERROR_OPCODE_PSRBIT
:
809 case ERROR_OPCODE_ILLEGAL
:
810 case ERROR_JMPIX_OVER_RANGE
:
811 case ERROR_MISSING_COMMA
:
812 case ERROR_MISSING_LBRACKET
:
813 case ERROR_MISSING_RBRACKET
:
814 case ERROR_MISSING_LSQUARE_BRACKETS
:
815 case ERROR_MISSING_RSQUARE_BRACKETS
:
816 case ERROR_MISSING_LANGLE_BRACKETS
:
817 case ERROR_MISSING_RANGLE_BRACKETS
:
818 /* Add NULL to fix warnings. */
819 as_bad (_(err_formats
[err
].fmt
), NULL
);
821 case ERROR_CREG_ILLEGAL
:
822 case ERROR_GREG_ILLEGAL
:
823 case ERROR_IMM_ILLEGAL
:
824 case ERROR_IMM_OVERFLOW
:
827 case ERROR_EXP_CONSTANT
:
828 case ERROR_EXP_EVEN_FREG
:
829 case ERROR_MISSING_OPERAND
:
830 case ERROR_CPREG_ILLEGAL
:
831 as_bad (_(err_formats
[err
].fmt
), idx
);
833 case ERROR_OPERANDS_NUMBER
:
834 case ERROR_IMM_POWER
:
835 as_bad (_(err_formats
[err
].fmt
), (long)arg1
);
838 case ERROR_OFFSET_UNALIGNED
:
839 as_bad (_(err_formats
[err
].fmt
), idx
, (long)arg1
);
841 case ERROR_RELOC_ILLEGAL
:
843 case ERROR_OPERANDS_ILLEGAL
:
844 as_bad (_(err_formats
[err
].fmt
), (char *)arg1
);
846 case ERROR_REG_OVER_RANGE
:
847 as_bad (_(err_formats
[err
].fmt
), idx
, (long) arg1
);
849 case ERROR_802J_REG_OVER_RANGE
:
850 case ERROR_REG_FORMAT
:
851 as_bad (_(err_formats
[err
].fmt
), idx
, (char *)arg1
);
854 /* Add NULL to fix warnings. */
855 as_bad ((char *)arg1
, NULL
);
858 as_warn (_(err_formats
[err
].fmt
), (long)arg1
);
860 case WARNING_OPTIONS
:
861 as_warn (_(err_formats
[err
].fmt
), (char *)arg1
, (char *)arg2
);
868 /* Handle errors in branch relaxation. */
871 csky_branch_report_error (const char* file
, unsigned int line
,
872 symbolS
* sym
, offsetT val
)
874 as_bad_where (file
? file
: _("unknown"),
876 _("pcrel offset for branch to %s too far (0x%lx)"),
877 sym
? S_GET_NAME (sym
) : _("<unknown>"),
881 /* Set appropriate flags for the cpu matching STR. */
884 parse_cpu (const char *str
)
888 for (; csky_cpus
[i
].name
!= NULL
; i
++)
889 if (strcasecmp (str
, csky_cpus
[i
].name
) == 0)
891 mach_flag
|= csky_cpus
[i
].mach_flag
;
892 isa_flag
= csky_cpus
[i
].isa_flag
;
893 other_flag
|= (csky_cpus
[i
].mach_flag
& ~CSKY_ARCH_MASK
);
896 as_bad (_("unknown cpu `%s'"), str
);
899 /* Set appropriate flags for the arch matching STR. */
902 parse_arch (const char *str
)
905 for (; csky_archs
[i
].name
!= NULL
; i
++)
906 if (strcasecmp (str
, csky_archs
[i
].name
) == 0)
908 arch_flag
|= csky_archs
[i
].arch_flag
;
911 as_bad (_("unknown architecture `%s'"), str
);
916 /* Implement the TARGET_FORMAT macro. */
919 elf32_csky_target_format (void)
921 return (target_big_endian
923 : "elf32-csky-little");
927 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
928 for use in the a.out file, and stores them in the array pointed to by buf.
929 This knows about the endian-ness of the target machine and does
930 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
931 2 (short) and 4 (long) Floating numbers are put out as a series of
932 LITTLENUMS (shorts, here at least). */
935 md_number_to_chars (char * buf
, valueT val
, int n
)
937 if (target_big_endian
)
938 number_to_chars_bigendian (buf
, val
, n
);
940 number_to_chars_littleendian (buf
, val
, n
);
943 /* Get a log2(val). */
946 csky_log_2 (unsigned int val
)
949 if ((val
& (val
- 1)) == 0)
950 for (; val
; val
>>= 1)
953 csky_show_error (ERROR_IMM_POWER
, 0, (void *)(long)val
, NULL
);
957 /* Output one instruction to the buffer at PTR. */
960 csky_write_insn (char *ptr
, valueT use
, int nbytes
)
963 md_number_to_chars (ptr
, use
, nbytes
);
964 else /* 32-bit instruction. */
966 /* Significant figures are in low bits. */
967 md_number_to_chars (ptr
, use
>> 16, 2);
968 md_number_to_chars (ptr
+ 2, use
& 0xFFFF, 2);
972 /* Read an NBYTES instruction from the buffer at PTR. NBYTES should
973 be either 2 or 4. This function is used in branch relaxation. */
976 csky_read_insn (char *ptr
, int nbytes
)
978 unsigned char *uptr
= (unsigned char *)ptr
;
980 int lo
, hi
; /* hi/lo byte index in binary stream. */
982 if (target_big_endian
)
992 v
= uptr
[lo
] | (uptr
[hi
] << 8);
996 v
|= uptr
[lo
+ 2] | (uptr
[hi
+ 2] << 8);
1001 /* Construct a label name into S from the 3-character prefix P and
1002 number N formatted as a 4-digit hex number. */
1005 make_internal_label (char *s
, const char *p
, int n
)
1007 static const char hex
[] = "0123456789ABCDEF";
1012 s
[3] = hex
[(n
>> 12) & 0xF];
1013 s
[4] = hex
[(n
>> 8) & 0xF];
1014 s
[5] = hex
[(n
>> 4) & 0xF];
1015 s
[6] = hex
[(n
) & 0xF];
1019 /* md_operand is a no-op on C-SKY; we do everything elsewhere. */
1022 md_operand (expressionS
*expressionP ATTRIBUTE_UNUSED
)
1027 /* Under ELF we need to default _GLOBAL_OFFSET_TABLE.
1028 Otherwise we have no need to default values of symbols. */
1031 md_undefined_symbol (char *name ATTRIBUTE_UNUSED
)
1039 /* Use IEEE format for floating-point constants. */
1042 md_atof (int type
, char *litP
, int *sizeP
)
1044 return ieee_md_atof (type
, litP
, sizeP
, target_big_endian
);
1047 /* Print option help to FP. */
1050 md_show_usage (FILE *fp
)
1053 const int margin
= 48;
1055 fprintf (fp
, _("C-SKY assembler options:\n"));
1058 -march=ARCH select architecture ARCH:"));
1059 for (i
= 0, n
= margin
; csky_archs
[i
].name
!= NULL
; i
++)
1061 int l
= strlen (csky_archs
[i
].name
);
1062 if (n
+ l
>= margin
)
1064 fprintf (fp
, "\n\t\t\t\t");
1072 fprintf (fp
, "%s", csky_archs
[i
].name
);
1077 -mcpu=CPU select processor CPU:"));
1078 for (i
= 0, n
= margin
; csky_cpus
[i
].name
!= NULL
; i
++)
1080 int l
= strlen (csky_cpus
[i
].name
);
1081 if (n
+ l
>= margin
)
1083 fprintf (fp
, "\n\t\t\t\t");
1091 fprintf (fp
, "%s", csky_cpus
[i
].name
);
1096 -EL -mlittle-endian generate little-endian output\n"));
1098 -EB -mbig-endian generate big-endian output\n"));
1100 -fpic -pic generate position-independent code\n"));
1103 -mljump transform jbf, jbt, jbr to jmpi (CK800 only)\n"));
1107 #ifdef INCLUDE_BRANCH_STUB
1109 -mbranch-stub enable branch stubs for PC-relative calls\n"));
1111 -mno-branch-stub\n"));
1115 -force2bsr -mforce2bsr transform jbsr to bsr\n"));
1117 -no-force2bsr -mno-force2bsr\n"));
1119 -jsri2bsr -mjsri2bsr transform jsri to bsr\n"));
1121 -no-jsri2bsr -mno-jsri2bsr\n"));
1124 -mnolrw -mno-lrw implement lrw as movih + ori\n"));
1126 -melrw enable extended lrw (CK800 only)\n"));
1131 -mlaf -mliterals-after-func emit literals after each function\n"));
1133 -mno-laf -mno-literals-after-func\n"));
1135 -mlabr -mliterals-after-br emit literals after branch instructions\n"));
1137 -mno-labr -mnoliterals-after-br\n"));
1140 -mistack enable interrupt stack instructions\n"));
1145 -mhard-float enable hard float instructions\n"));
1147 -mmp enable multiprocessor instructions\n"));
1149 -mcp enable coprocessor instructions\n"));
1151 -mcache enable cache prefetch instruction\n"));
1153 -msecurity enable security instructions\n"));
1155 -mtrust enable trust instructions\n"));
1157 -mdsp enable DSP instructions\n"));
1159 -medsp enable enhanced DSP instructions\n"));
1161 -mvdsp enable vector DSP instructions\n"));
1164 /* Target-specific initialization and option handling. */
1169 unsigned int bfd_mach_flag
= 0;
1170 struct csky_opcode
const *opcode
;
1171 struct csky_macro_info
const *macro
;
1172 struct csky_arch_info
const *p_arch
;
1173 struct csky_cpu_info
const *p_cpu
;
1174 unsigned int flags
= (other_flag
| do_opt_mmp
| do_opt_mcp
| do_opt_mcache
1175 | do_opt_msecurity
| do_opt_mhard_float
);
1176 dsp_flag
|= do_opt_mdsp
| do_opt_medsp
;
1177 isa_flag
|= do_opt_mtrust
| do_opt_mvdsp
;
1180 flags
|= CSKY_ARCH_DSP
;
1184 if (((mach_flag
& CSKY_ARCH_MASK
) != (arch_flag
& CSKY_ARCH_MASK
))
1186 as_warn (_("-mcpu conflict with -march option, using -mcpu"));
1187 if (((mach_flag
& ~CSKY_ARCH_MASK
) != (flags
& ~CSKY_ARCH_MASK
))
1189 as_warn (_("-mcpu conflict with other model parameters, using -mcpu"));
1191 else if (arch_flag
!= 0)
1192 mach_flag
|= arch_flag
| flags
;
1195 #ifdef TARGET_WITH_CPU
1197 for (; csky_cpus
[i
].name
!= NULL
; i
++)
1199 if (strcmp (TARGET_WITH_CPU
, csky_cpus
[i
].name
) == 0)
1201 mach_flag
|= csky_cpus
[i
].mach_flag
;
1202 isa_flag
= csky_cpus
[i
].isa_flag
;
1208 mach_flag
|= CSKY_ARCH_610
| flags
;
1210 mach_flag
|= CSKY_ARCH_810_BASE
| flags
;
1215 if (IS_CSKY_ARCH_610 (mach_flag
) || IS_CSKY_ARCH_510 (mach_flag
))
1217 if ((mach_flag
& CSKY_ARCH_MP
) && (mach_flag
& CSKY_ARCH_MAC
))
1218 as_fatal ("520/620 conflicts with -mmp option");
1219 else if ((mach_flag
& CSKY_ARCH_MP
) && (mach_flag
& CSKY_ARCH_DSP
))
1220 as_fatal ("510e/610e conflicts with -mmp option");
1221 else if ((mach_flag
& CSKY_ARCH_DSP
) && (mach_flag
& CSKY_ARCH_MAC
))
1222 as_fatal ("520/620 conflicts with 510e/610e or -mdsp option");
1224 if (IS_CSKY_ARCH_510 (mach_flag
) && (mach_flag
& CSKY_ARCH_FLOAT
))
1226 mach_flag
= (mach_flag
& (~CSKY_ARCH_MASK
));
1227 mach_flag
|= CSKY_ARCH_610
;
1230 /* Find bfd_mach_flag, it will set to bfd backend data. */
1231 for (p_arch
= csky_archs
; p_arch
->arch_flag
!= 0; p_arch
++)
1232 if ((mach_flag
& CSKY_ARCH_MASK
) == (p_arch
->arch_flag
& CSKY_ARCH_MASK
))
1234 bfd_mach_flag
= p_arch
->bfd_mach_flag
;
1238 /* Find isa_flag. */
1239 for (p_cpu
= csky_cpus
; p_cpu
->mach_flag
!= 0; p_cpu
++)
1240 if ((mach_flag
& CPU_ARCH_MASK
) == p_cpu
->mach_flag
)
1242 isa_flag
|= p_cpu
->isa_flag
;
1246 /* Check if -mdsp and -medsp conflict. If cpu is ck803, we will
1247 use enhanced dsp instruction. Otherwise, we will use normal dsp. */
1250 if (IS_CSKY_ARCH_803 (mach_flag
))
1252 /* In 803, dspv1 is conflict with dspv2. We keep dspv2. */
1253 if ((dsp_flag
& CSKY_DSP_FLAG_V1
) && (dsp_flag
& CSKY_DSP_FLAG_V2
))
1254 as_warn (_("option -mdsp conflicts with -medsp, only enabling -medsp"));
1255 isa_flag
&= ~(CSKY_ISA_MAC_DSP
| CSKY_ISA_DSP
);
1256 isa_flag
|= CSKY_ISA_DSP_ENHANCE
;
1260 isa_flag
&= ~CSKY_ISA_DSP_ENHANCE
;
1261 as_warn (_("-medsp option is only supported by ck803s, ignoring -medsp"));
1266 if (do_use_branchstub
== -1)
1267 do_use_branchstub
= !IS_CSKY_ARCH_V1 (mach_flag
);
1268 else if (do_use_branchstub
== 1)
1270 if (IS_CSKY_ARCH_V1 (mach_flag
))
1272 as_warn (_("C-SKY ABI v1 (ck510/ck610) does not support -mbranch-stub"));
1273 do_use_branchstub
= 0;
1275 else if (do_force2bsr
== 0)
1277 as_warn (_("-mno-force2bsr is ignored with -mbranch-stub"));
1282 if (IS_CSKY_ARCH_801 (mach_flag
) || IS_CSKY_ARCH_802 (mach_flag
))
1285 as_warn (_("-mno-force2bsr is ignored for ck801/ck802"));
1288 else if (do_force2bsr
== -1)
1289 do_force2bsr
= do_use_branchstub
;
1293 if (IS_CSKY_ARCH_V1 (mach_flag
))
1299 if (do_extend_lrw
== -1)
1301 if (IS_CSKY_ARCH_801 (mach_flag
))
1306 if (IS_CSKY_ARCH_801 (mach_flag
) || IS_CSKY_ARCH_802 (mach_flag
))
1308 if (do_long_jump
> 0)
1309 as_warn (_("-mljump is ignored for ck801/ck802"));
1312 else if (do_long_jump
== -1)
1314 if (do_intr_stack
== -1)
1316 /* control interrupt stack module, 801&802&803 default on
1317 807&810, default off. */
1318 if (IS_CSKY_ARCH_807 (mach_flag
) || IS_CSKY_ARCH_810 (mach_flag
))
1323 /* TODO: add isa_flag(SIMP/CACHE/APS). */
1324 isa_flag
|= (mach_flag
& CSKY_ARCH_MAC
) ? CSKY_ISA_MAC
: 0;
1325 isa_flag
|= (mach_flag
& CSKY_ARCH_MP
) ? CSKY_ISA_MP
: 0;
1326 isa_flag
|= (mach_flag
& CSKY_ARCH_CP
) ? CSKY_ISA_CP
: 0;
1328 /* Set abi flag and get table address. */
1329 if (IS_CSKY_ARCH_V1 (mach_flag
))
1331 mach_flag
= mach_flag
| CSKY_ABI_V1
;
1332 opcode
= csky_v1_opcodes
;
1333 macro
= v1_macros_table
;
1334 SPANPANIC
= v1_SPANPANIC
;
1335 SPANCLOSE
= v1_SPANCLOSE
;
1336 SPANEXIT
= v1_SPANEXIT
;
1337 md_relax_table
= csky_relax_table
;
1341 mach_flag
= mach_flag
| CSKY_ABI_V2
;
1342 opcode
= csky_v2_opcodes
;
1343 macro
= v2_macros_table
;
1344 SPANPANIC
= v2_SPANPANIC
;
1347 SPANCLOSE
= v2_SPANCLOSE_ELRW
;
1348 SPANEXIT
= v2_SPANEXIT_ELRW
;
1352 SPANCLOSE
= v2_SPANCLOSE
;
1353 SPANEXIT
= v2_SPANEXIT
;
1355 md_relax_table
= csky_relax_table
;
1358 /* Establish hash table for opcodes and macros. */
1359 csky_macros_hash
= str_htab_create ();
1360 csky_opcodes_hash
= str_htab_create ();
1361 for ( ; opcode
->mnemonic
!= NULL
; opcode
++)
1362 if ((isa_flag
& (opcode
->isa_flag16
| opcode
->isa_flag32
)) != 0)
1363 str_hash_insert (csky_opcodes_hash
, opcode
->mnemonic
, (char *)opcode
);
1364 for ( ; macro
->name
!= NULL
; macro
++)
1365 if ((isa_flag
& macro
->isa_flag
) != 0)
1366 str_hash_insert (csky_macros_hash
, macro
->name
, (char *)macro
);
1367 if (do_nolrw
&& (isa_flag
& CSKYV2_ISA_1E2
) != 0)
1368 str_hash_insert (csky_macros_hash
,
1369 v2_lrw_macro_opcode
.name
,
1370 (char *)&v2_lrw_macro_opcode
);
1371 /* Set e_flag to ELF Head. */
1372 bfd_set_private_flags (stdoutput
, mach_flag
);
1373 /* Set bfd_mach to bfd backend data. */
1374 bfd_set_arch_mach (stdoutput
, bfd_arch_csky
, bfd_mach_flag
);
1377 /* The C-SKY assembler emits mapping symbols $t and $d to mark the
1378 beginning of a sequence of instructions and data (such as a constant pool),
1379 respectively. This is similar to what ARM does. */
1382 make_mapping_symbol (map_state state
, valueT value
, fragS
*frag
)
1385 const char * symname
;
1391 type
= BSF_NO_FLAGS
;
1395 type
= BSF_NO_FLAGS
;
1401 symbolP
= symbol_new (symname
, now_seg
, value
, frag
);
1402 symbol_get_bfdsym (symbolP
)->flags
|= type
| BSF_LOCAL
;
1405 /* We need to keep track of whether we are emitting code or data; this
1406 function switches state and emits a mapping symbol if necessary. */
1409 mapping_state (map_state state
)
1411 map_state current_state
1412 = seg_info (now_seg
)->tc_segment_info_data
.current_state
;
1414 if (current_state
== state
)
1416 else if (current_state
== MAP_UNDEFINED
&& state
== MAP_DATA
)
1418 else if (current_state
== MAP_UNDEFINED
&& state
== MAP_TEXT
)
1420 struct frag
* const frag_first
= seg_info (now_seg
)->frchainP
->frch_root
;
1421 if (frag_now
!= frag_first
|| frag_now_fix () > 0)
1422 make_mapping_symbol (MAP_DATA
, (valueT
) 0, frag_first
);
1425 seg_info (now_seg
)->tc_segment_info_data
.current_state
= state
;
1426 make_mapping_symbol (state
, (valueT
) frag_now_fix (), frag_now
);
1429 /* Dump the literal pool. */
1432 dump_literals (int isforce
)
1434 #define CSKYV1_BR_INSN 0xF000
1435 #define CSKYV2_BR_INSN 0x0400
1438 symbolS
* brarsym
= NULL
;
1440 /* V1 nop encoding: 0x1200 : mov r0, r0. */
1441 static char v1_nop_insn_big
[2] = {0x12, 0x00};
1442 static char v1_nop_insn_little
[2] = {0x00, 0x12};
1447 /* Must we branch around the literal table? */
1451 make_internal_label (brarname
, POOL_END_LABEL
, poolnumber
);
1452 brarsym
= symbol_make (brarname
);
1453 symbol_table_insert (brarsym
);
1454 mapping_state (MAP_TEXT
);
1455 if (IS_CSKY_ARCH_V1 (mach_flag
))
1458 = frag_var (rs_machine_dependent
,
1459 csky_relax_table
[C (UNCD_JUMP_S
, DISP32
)].rlx_length
,
1460 csky_relax_table
[C (UNCD_JUMP_S
, DISP12
)].rlx_length
,
1461 C (UNCD_JUMP_S
, 0), brarsym
, 0, 0);
1462 md_number_to_chars (csky_insn
.output
, CSKYV1_BR_INSN
, 2);
1467 = frag_var (rs_machine_dependent
,
1472 md_number_to_chars (csky_insn
.output
, CSKYV2_BR_INSN
, 2);
1475 /* Make sure that the section is sufficiently aligned and that
1476 the literal table is aligned within it. */
1480 csky_insn
.output
= frag_more (2);
1482 if (IS_CSKY_V1 (mach_flag
))
1483 br_self
= CSKYV1_BR_INSN
| 0x7ff;
1485 br_self
= CSKYV2_BR_INSN
;
1486 md_number_to_chars (csky_insn
.output
, br_self
, 2);
1489 csky_insn
.output
= frag_more (2);
1491 md_number_to_chars (csky_insn
.output
, br_self
, 2);
1494 mapping_state (MAP_DATA
);
1496 record_alignment (now_seg
, 2);
1497 if (IS_CSKY_ARCH_V1 (mach_flag
))
1498 frag_align_pattern (2,
1500 ? v1_nop_insn_big
: v1_nop_insn_little
),
1503 frag_align (2, 0, 3);
1505 colon (S_GET_NAME (poolsym
));
1507 for (i
= 0, p
= litpool
; i
< poolsize
; i
+= (p
->isdouble
? 2 : 1), p
++)
1509 insn_reloc
= p
->r_type
;
1510 if (insn_reloc
== BFD_RELOC_CKCORE_TLS_IE32
1511 || insn_reloc
== BFD_RELOC_CKCORE_TLS_LDM32
1512 || insn_reloc
== BFD_RELOC_CKCORE_TLS_GD32
)
1513 literal_insn_offset
= p
;
1516 if (target_big_endian
)
1518 p
->e
.X_add_number
= p
->dbnum
>> 32;
1519 emit_expr (& p
->e
, 4);
1520 p
->e
.X_add_number
= p
->dbnum
& 0xffffffff;
1521 emit_expr (& p
->e
, 4);
1525 p
->e
.X_add_number
= p
->dbnum
& 0xffffffff;
1526 emit_expr (& p
->e
, 4);
1527 p
->e
.X_add_number
= p
->dbnum
>> 32;
1528 emit_expr (& p
->e
, 4);
1532 emit_expr (& p
->e
, 4);
1535 if (isforce
&& IS_CSKY_ARCH_V2 (mach_flag
))
1537 /* Add one nop insn at end of literal for disassembler. */
1538 mapping_state (MAP_TEXT
);
1539 csky_insn
.output
= frag_more (2);
1540 md_number_to_chars (csky_insn
.output
, CSKYV2_INST_NOP
, 2);
1543 insn_reloc
= BFD_RELOC_NONE
;
1545 if (brarsym
!= NULL
)
1546 colon (S_GET_NAME (brarsym
));
1551 enter_literal (expressionS
*e
,
1553 unsigned char isdouble
,
1558 if (poolsize
>= MAX_POOL_SIZE
- 2)
1560 /* The literal pool is as full as we can handle. We have
1561 to be 2 entries shy of the 1024/4=256 entries because we
1562 have to allow for the branch (2 bytes) and the alignment
1563 (2 bytes before the first insn referencing the pool and
1564 2 bytes before the pool itself) == 6 bytes, rounds up
1567 /* Save the parsed symbol's reloc. */
1568 enum bfd_reloc_code_real last_reloc_before_dump
= insn_reloc
;
1570 insn_reloc
= last_reloc_before_dump
;
1575 /* Create new literal pool. */
1576 if (++ poolnumber
> 0xFFFF)
1577 as_fatal (_("more than 65K literal pools"));
1579 make_internal_label (poolname
, POOL_START_LABEL
, poolnumber
);
1580 poolsym
= symbol_make (poolname
);
1581 symbol_table_insert (poolsym
);
1585 /* Search pool for value so we don't have duplicates. */
1586 for (p
= litpool
, i
= 0; i
< poolsize
; i
+= (p
->isdouble
? 2 : 1), p
++)
1588 if (e
->X_op
== p
->e
.X_op
1589 && e
->X_add_symbol
== p
->e
.X_add_symbol
1590 && e
->X_add_number
== p
->e
.X_add_number
1591 && ispcrel
== p
->ispcrel
1592 && insn_reloc
== p
->r_type
1593 && isdouble
== p
->isdouble
1594 && insn_reloc
!= BFD_RELOC_CKCORE_TLS_GD32
1595 && insn_reloc
!= BFD_RELOC_CKCORE_TLS_LDM32
1596 && insn_reloc
!= BFD_RELOC_CKCORE_TLS_LDO32
1597 && insn_reloc
!= BFD_RELOC_CKCORE_TLS_IE32
1598 && insn_reloc
!= BFD_RELOC_CKCORE_TLS_LE32
)
1605 p
->ispcrel
= ispcrel
;
1607 p
->r_type
= insn_reloc
;
1608 p
->isdouble
= isdouble
;
1612 if (insn_reloc
== BFD_RELOC_CKCORE_TLS_GD32
1613 || insn_reloc
== BFD_RELOC_CKCORE_TLS_LDM32
1614 || insn_reloc
== BFD_RELOC_CKCORE_TLS_IE32
)
1616 p
->tls_addend
.frag
= frag_now
;
1617 p
->tls_addend
.offset
= csky_insn
.output
- frag_now
->fr_literal
;
1618 literal_insn_offset
= p
;
1620 poolsize
+= (p
->isdouble
? 2 : 1);
1624 /* Check whether we must dump the literal pool here.
1625 kind == 0 is any old instruction.
1626 kind > 0 means we just had a control transfer instruction.
1627 kind == 1 means within a function.
1628 kind == 2 means we just left a function.
1630 OFFSET is the length of the insn being processed.
1632 SPANCLOSE and SPANEXIT are smaller numbers than SPANPANIC.
1633 SPANPANIC means that we must dump now.
1634 The dump_literals (1) call inserts a branch around the table, so
1635 we first look to see if its a situation where we won't have to
1636 insert a branch (e.g., the previous instruction was an unconditional
1639 SPANPANIC is the point where we must dump a single-entry pool.
1640 it accounts for alignments and an inserted branch.
1641 the 'poolsize*2' accounts for the scenario where we do:
1642 lrw r1,lit1; lrw r2,lit2; lrw r3,lit3
1643 Note that the 'lit2' reference is 2 bytes further along
1644 but the literal it references will be 4 bytes further along,
1645 so we must consider the poolsize into this equation.
1646 This is slightly over-cautious, but guarantees that we won't
1647 panic because a relocation is too distant. */
1650 check_literals (int kind
, int offset
)
1654 if ((poolspan
> SPANEXIT
|| do_func_dump
)
1656 && (do_br_dump
|| do_func_dump
))
1658 else if (poolspan
> SPANCLOSE
&& (kind
> 0) && do_br_dump
)
1661 >= (SPANPANIC
- (IS_CSKY_ARCH_V1 (mach_flag
) ? poolsize
* 2 : 0)))
1663 /* We have not dumped literal pool before insn1,
1664 and will not dump literal pool between insn1 and insnN+1,
1665 so reset poolspan to original length. */
1666 else if (do_noliteraldump
== 1)
1669 if (do_noliteraldump
== 1)
1670 do_noliteraldump
= 0;
1673 /* The next group of functions are helpers for parsing various kinds
1674 of instruction operand syntax. */
1676 /* Parse operands of the form
1677 <symbol>@GOTOFF+<nnn>
1678 and similar .plt or .got references.
1680 If we find one, set up the correct relocation in RELOC and copy the
1681 input string, minus the `@GOTOFF' into a malloc'd buffer for
1682 parsing by the calling routine. Return this buffer, and if ADJUST
1683 is non-null set it to the length of the string we removed from the
1684 input line. Otherwise return NULL. */
1687 lex_got (enum bfd_reloc_code_real
*reloc
,
1693 const enum bfd_reloc_code_real rel
;
1695 static const struct _gotrel gotrel
[] =
1697 { "GOTOFF", BFD_RELOC_CKCORE_GOTOFF
},
1698 { "GOTPC", BFD_RELOC_CKCORE_GOTPC
},
1699 { "GOTTPOFF", BFD_RELOC_CKCORE_TLS_IE32
},
1700 { "GOT", BFD_RELOC_CKCORE_GOT32
},
1701 { "PLT", BFD_RELOC_CKCORE_PLT32
},
1702 { "BTEXT", BFD_RELOC_CKCORE_TOFFSET_LO16
},
1703 { "BDATA", BFD_RELOC_CKCORE_DOFFSET_LO16
},
1704 { "TLSGD32", BFD_RELOC_CKCORE_TLS_GD32
},
1705 { "TLSLDM32", BFD_RELOC_CKCORE_TLS_LDM32
},
1706 { "TLSLDO32", BFD_RELOC_CKCORE_TLS_LDO32
},
1707 { "TPOFF", BFD_RELOC_CKCORE_TLS_LE32
}
1713 for (cp
= input_line_pointer
; *cp
!= '@'; cp
++)
1714 if (is_end_of_line
[(unsigned char) *cp
])
1717 for (j
= 0; j
< sizeof (gotrel
) / sizeof (gotrel
[0]); j
++)
1719 int len
= strlen (gotrel
[j
].str
);
1721 if (strncasecmp (cp
+ 1, gotrel
[j
].str
, len
) == 0)
1723 if (gotrel
[j
].rel
!= 0)
1725 *reloc
= gotrel
[j
].rel
;
1729 /* input_line_pointer is the str pointer after relocation
1730 token like @GOTOFF. */
1731 input_line_pointer
+= len
+ 1;
1732 return input_line_pointer
;
1735 csky_show_error (ERROR_RELOC_ILLEGAL
, 0,
1736 (void *)gotrel
[j
].str
, NULL
);
1741 /* Might be a symbol version string. Don't as_bad here. */
1745 /* Parse an expression, returning it in E. */
1748 parse_exp (char *s
, expressionS
*e
)
1753 /* Skip whitespace. */
1754 while (ISSPACE (*s
))
1757 save
= input_line_pointer
;
1758 input_line_pointer
= s
;
1760 insn_reloc
= BFD_RELOC_NONE
;
1762 lex_got (&insn_reloc
, NULL
);
1764 if (e
->X_op
== O_absent
)
1765 SET_ERROR_NUMBER (ERROR_MISSING_OPERAND
, NULL
);
1767 new = input_line_pointer
;
1768 input_line_pointer
= save
;
1773 /* Parse a floating-point number from S into its target representation.
1774 If ISDOUBLE is true, return the result in *DBNUM; otherwise
1775 it's returned in E->X_add_number. Returns the result of advancing
1776 S past the constant. */
1779 parse_fexp (char *s
, expressionS
*e
, unsigned char isdouble
, uint64_t *dbnum
)
1781 int length
; /* Number of chars in an object. */
1782 const char *err
= NULL
; /* Error from scanning float literal. */
1783 unsigned char temp
[8];
1785 /* input_line_pointer->1st char of a flonum (we hope!). */
1786 input_line_pointer
= s
;
1788 if (input_line_pointer
[0] == '0'
1789 && ISALPHA (input_line_pointer
[1]))
1790 input_line_pointer
+= 2;
1793 err
= md_atof ('d', (char *) temp
, &length
);
1795 err
= md_atof ('f', (char *) temp
, &length
);
1797 know (err
!= NULL
|| length
> 0);
1799 if (!is_end_of_line
[(unsigned char) *input_line_pointer
])
1800 as_bad (_("immediate operand required"));
1801 while (!is_end_of_line
[(unsigned char) *input_line_pointer
])
1802 input_line_pointer
++;
1806 as_bad (_("bad floating literal: %s"), err
);
1807 while (!is_end_of_line
[(unsigned char) *input_line_pointer
])
1808 input_line_pointer
++;
1809 know (is_end_of_line
[(unsigned char) input_line_pointer
[-1]]);
1810 return input_line_pointer
;
1813 e
->X_add_symbol
= 0x0;
1814 e
->X_op_symbol
= 0x0;
1815 e
->X_op
= O_constant
;
1822 if (target_big_endian
)
1823 fnum
= (((uint32_t) temp
[0] << 24)
1828 fnum
= (((uint32_t) temp
[3] << 24)
1832 e
->X_add_number
= fnum
;
1836 if (target_big_endian
)
1838 *dbnum
= (((uint32_t) temp
[0] << 24)
1843 *dbnum
|= (((uint32_t) temp
[4] << 24)
1850 *dbnum
= (((uint32_t) temp
[7] << 24)
1855 *dbnum
|= (((uint32_t) temp
[3] << 24)
1861 return input_line_pointer
;
1868 long reg ATTRIBUTE_UNUSED
)
1874 /* Indicate nothing there. */
1875 ep
->X_op
= O_absent
;
1879 s
= parse_exp (s
+ 1, &e
);
1884 SET_ERROR_NUMBER (ERROR_MISSING_RSQUARE_BRACKETS
, NULL
);
1891 s
= parse_exp (s
, &e
);
1892 if (BFD_RELOC_CKCORE_DOFFSET_LO16
== insn_reloc
1893 || BFD_RELOC_CKCORE_TOFFSET_LO16
== insn_reloc
)
1901 /* If the instruction has work, literal handling is in the work. */
1902 if (!csky_insn
.opcode
->work
)
1904 n
= enter_literal (&e
, ispcrel
, 0, 0);
1908 /* Create a reference to pool entry. */
1909 ep
->X_op
= O_symbol
;
1910 ep
->X_add_symbol
= poolsym
;
1911 ep
->X_add_number
= n
<< 2;
1918 parse_rtf (char *s
, int ispcrel
, expressionS
*ep
)
1924 /* Indicate nothing there. */
1925 ep
->X_op
= O_absent
;
1929 s
= parse_exp (s
+ 1, & e
);
1934 as_bad (_("missing ']'"));
1942 if (strstr (csky_insn
.opcode
->mnemonic
, "flrws"))
1944 s
= parse_fexp (s
, &e
, 0, &dbnum
);
1945 n
= enter_literal (&e
, ispcrel
, 0, dbnum
);
1947 else if (strstr (csky_insn
.opcode
->mnemonic
, "flrwd"))
1949 s
= parse_fexp (s
, &e
, 1, &dbnum
);
1950 n
= enter_literal (&e
, ispcrel
, 1, dbnum
);
1953 as_bad (_("unrecognized opcode"));
1958 /* Create a reference to pool entry. */
1959 ep
->X_op
= O_symbol
;
1960 ep
->X_add_symbol
= poolsym
;
1961 ep
->X_add_number
= n
<< 2;
1967 parse_type_ctrlreg (char** oper
)
1972 if (TOLOWER (*(*oper
+ 0)) == 'c'
1973 && TOLOWER (*(*oper
+ 1)) == 'r'
1974 && ISDIGIT (*(*oper
+ 2)))
1976 /* The control registers are named crxx. */
1977 i
= *(*oper
+ 2) - 0x30;
1978 i
= ISDIGIT (*(*oper
+ 3)) ? (*(*oper
+ 3) - 0x30) + 10 * i
: i
;
1979 len
= ISDIGIT (*(*oper
+ 3)) ? 4 : 3;
1982 else if (!(TOLOWER (*(*oper
+ 0)) == 'c'
1983 && TOLOWER (*(*oper
+ 1)) == 'r'))
1985 /* The control registers are aliased. */
1986 struct csky_reg
*reg
= &csky_ctrl_regs
[0];
1989 if (memcmp (*oper
, reg
->name
, strlen (reg
->name
)) == 0
1990 && (!reg
->flag
|| (isa_flag
& reg
->flag
)))
1993 len
= strlen (reg
->name
);
2001 if (IS_CSKY_V2 (mach_flag
))
2013 if (s
[0] == 'c' && s
[1] == 'r')
2019 if (s
[0] == '3' && s
[1] >= '0' && s
[1] <= '1')
2021 crx
= 30 + s
[1] - '0';
2024 else if (s
[0] == '2' && s
[1] >= '0' && s
[1] <= '9')
2026 crx
= 20 + s
[1] - '0';
2029 else if (s
[0] == '1' && s
[1] >= '0' && s
[1] <= '9')
2031 crx
= 10 + s
[1] - '0';
2034 else if (s
[0] >= '0' && s
[0] <= '9')
2041 SET_ERROR_NUMBER (ERROR_REG_OVER_RANGE
, "control");
2048 SET_ERROR_NUMBER (ERROR_CREG_ILLEGAL
, NULL
);
2052 while (*pS
!= '>' && !is_end_of_line
[(unsigned char) *pS
])
2058 /* Error. Missing '>'. */
2059 SET_ERROR_NUMBER (ERROR_MISSING_RANGLE_BRACKETS
, NULL
);
2063 s
= parse_exp (s
, &e
);
2064 if (e
.X_op
== O_constant
2065 && e
.X_add_number
>= 0
2066 && e
.X_add_number
<= 31)
2069 sel
= e
.X_add_number
;
2076 /* Error. Missing '<'. */
2077 SET_ERROR_NUMBER (ERROR_MISSING_LANGLE_BRACKETS
, NULL
);
2083 SET_ERROR_NUMBER (ERROR_CREG_ILLEGAL
, NULL
);
2087 i
= (sel
<< 5) | crx
;
2089 csky_insn
.val
[csky_insn
.idx
++] = i
;
2094 is_reg_sp_with_bracket (char **oper
)
2100 if (IS_CSKY_V1 (mach_flag
))
2108 regs
= csky_general_reg
;
2109 len
= strlen (regs
[sp_idx
]);
2110 if (memcmp (*oper
, regs
[sp_idx
], len
) == 0)
2116 csky_insn
.val
[csky_insn
.idx
++] = sp_idx
;
2121 if (IS_CSKY_V1 (mach_flag
))
2122 regs
= cskyv1_general_alias_reg
;
2124 regs
= cskyv2_general_alias_reg
;
2125 len
= strlen (regs
[sp_idx
]);
2126 if (memcmp (*oper
, regs
[sp_idx
], len
) == 0)
2139 is_reg_sp (char **oper
)
2144 if (IS_CSKY_V1 (mach_flag
))
2149 regs
= csky_general_reg
;
2150 len
= strlen (regs
[sp_idx
]);
2151 if (memcmp (*oper
, regs
[sp_idx
], len
) == 0)
2154 csky_insn
.val
[csky_insn
.idx
++] = sp_idx
;
2159 if (IS_CSKY_V1 (mach_flag
))
2160 regs
= cskyv1_general_alias_reg
;
2162 regs
= cskyv2_general_alias_reg
;
2163 len
= strlen (regs
[sp_idx
]);
2164 if (memcmp (*oper
, regs
[sp_idx
], len
) == 0)
2167 csky_insn
.val
[csky_insn
.idx
++] = sp_idx
;
2175 csky_get_reg_val (char *str
, int *len
)
2178 if (TOLOWER (str
[0]) == 'r' && ISDIGIT (str
[1]))
2180 if (ISDIGIT (str
[1]) && ISDIGIT (str
[2]))
2182 reg
= (str
[1] - '0') * 10 + str
[2] - '0';
2185 else if (ISDIGIT (str
[1]))
2193 else if (TOLOWER (str
[0]) == 's' && TOLOWER (str
[1]) == 'p'
2194 && !ISDIGIT (str
[2]))
2197 if (IS_CSKY_V1 (mach_flag
))
2203 else if (TOLOWER (str
[0]) == 'g' && TOLOWER (str
[1]) == 'b'
2204 && !ISDIGIT (str
[2]))
2207 if (IS_CSKY_V1 (mach_flag
))
2213 else if (TOLOWER (str
[0]) == 'l' && TOLOWER (str
[1]) == 'r'
2214 && !ISDIGIT (str
[2]))
2220 else if (TOLOWER (str
[0]) == 't' && TOLOWER (str
[1]) == 'l'
2221 && TOLOWER (str
[2]) == 's' && !ISDIGIT (str
[3]))
2224 if (IS_CSKY_V2 (mach_flag
))
2230 else if (TOLOWER (str
[0]) == 's' && TOLOWER (str
[1]) == 'v'
2231 && TOLOWER (str
[2]) == 'b' && TOLOWER (str
[3]) == 'r')
2233 if (IS_CSKY_V2 (mach_flag
))
2239 else if (TOLOWER (str
[0]) == 'a')
2241 if (ISDIGIT (str
[1]) && !ISDIGIT (str
[2]))
2243 if (IS_CSKY_V1 (mach_flag
) && (str
[1] - '0') <= 5)
2245 reg
= 2 + str
[1] - '0';
2246 else if (IS_CSKY_V2 (mach_flag
) && (str
[1] - '0') <= 3)
2254 else if (TOLOWER (str
[0]) == 't')
2256 if (IS_CSKY_V2 (mach_flag
))
2258 reg
= atoi (str
+ 1);
2271 else if (TOLOWER (str
[0]) == 'l')
2273 if (str
[1] < '0' || str
[1] > '9')
2275 if (IS_CSKY_V2 (mach_flag
))
2277 reg
= atoi (str
+ 1);
2289 reg
= atoi (str
+ 1);
2292 /* l0 - l6 -> r8 - r13. */
2300 /* Is register available? */
2301 if (IS_CSKY_ARCH_801 (mach_flag
))
2303 /* CK801 register range is r0-r8 & r13-r15. */
2304 if ((reg
> 8 && reg
< 13) || reg
> 15)
2306 SET_ERROR_NUMBER (ERROR_REG_OVER_RANGE
, reg
);
2310 else if (IS_CSKY_ARCH_802 (mach_flag
))
2312 /* CK802 register range is r0-r15 & r23-r25 & r30. */
2313 if ((reg
> 15 && reg
< 23) || (reg
> 25 && reg
!= 30))
2315 SET_ERROR_NUMBER (ERROR_REG_OVER_RANGE
, reg
);
2319 else if (reg
> 31 || reg
< 0)
2321 SET_ERROR_NUMBER (ERROR_REG_OVER_RANGE
, reg
);
2329 csky_get_freg_val (char *str
, int *len
)
2333 if ((str
[0] == 'v' || str
[0] == 'f') && (str
[1] == 'r'))
2335 /* It is fpu register. */
2337 while (ISDIGIT (*s
))
2339 reg
= reg
* 10 + (*s
) - '0';
2352 is_reglist_legal (char **oper
)
2357 reg1
= csky_get_reg_val (*oper
, &len
);
2360 if (reg1
== -1 || (IS_CSKY_V1 (mach_flag
) && (reg1
== 0 || reg1
== 15)))
2362 SET_ERROR_NUMBER (ERROR_REG_FORMAT
,
2363 "The first reg must not be r0/r15");
2369 SET_ERROR_NUMBER (ERROR_REG_FORMAT
,
2370 "The operand format must be rx-ry");
2375 reg2
= csky_get_reg_val (*oper
, &len
);
2378 if (reg2
== -1 || (IS_CSKY_V1 (mach_flag
) && reg1
== 15))
2380 SET_ERROR_NUMBER (ERROR_REG_FORMAT
,
2381 "The operand format must be r15 in C-SKY V1");
2384 if (IS_CSKY_V2 (mach_flag
))
2388 SET_ERROR_NUMBER (ERROR_REG_FORMAT
,
2389 "The operand format must be rx-ry (rx < ry)");
2396 csky_insn
.val
[csky_insn
.idx
++] = reg1
;
2401 is_freglist_legal (char **oper
)
2406 reg1
= csky_get_freg_val (*oper
, &len
);
2411 SET_ERROR_NUMBER (ERROR_REG_FORMAT
,
2412 "The fpu register format is not recognized.");
2418 SET_ERROR_NUMBER (ERROR_REG_FORMAT
,
2419 "The operand format must be vrx-vry/frx-fry.");
2424 reg2
= csky_get_freg_val (*oper
, &len
);
2429 SET_ERROR_NUMBER (ERROR_REG_FORMAT
,
2430 "The fpu register format is not recognized.");
2435 SET_ERROR_NUMBER (ERROR_REG_FORMAT
,
2436 "The operand format must be rx-ry(rx < ry)");
2442 csky_insn
.val
[csky_insn
.idx
++] = reg1
;
2447 is_reglist_dash_comma_legal (char **oper
, struct operand
*oprnd
)
2455 while (**oper
!= '\n' && **oper
!= '\0')
2457 reg1
= csky_get_reg_val (*oper
, &len
);
2460 SET_ERROR_NUMBER (ERROR_REG_LIST
, NULL
);
2463 flag
|= (1 << reg1
);
2468 reg2
= csky_get_reg_val (*oper
, &len
);
2471 SET_ERROR_NUMBER (ERROR_REG_LIST
, NULL
);
2477 SET_ERROR_NUMBER (ERROR_REG_LIST
, NULL
);
2480 while (reg2
>= reg1
)
2482 flag
|= (1 << reg2
);
2489 /* The reglist: r4-r11, r15, r16-r17, r28. */
2490 #define REGLIST_BITS 0x10038ff0
2491 if (flag
& ~(REGLIST_BITS
))
2493 SET_ERROR_NUMBER (ERROR_REG_LIST
, NULL
);
2500 if (flag
& (1 << i
))
2507 if (flag
& (1 << 15))
2510 /* Check r16-r17. */
2515 if (flag
& (1 << i
))
2519 list
|= (temp
<< 5);
2522 if (flag
& (1 << 28))
2524 if (oprnd
->mask
== OPRND_MASK_0_4
&& (list
& ~OPRND_MASK_0_4
))
2526 SET_ERROR_NUMBER (ERROR_REG_LIST
, NULL
);
2529 csky_insn
.val
[csky_insn
.idx
++] = list
;
2534 is_reg_lshift_illegal (char **oper
, int is_float
)
2539 reg
= csky_get_reg_val (*oper
, &len
);
2542 SET_ERROR_NUMBER (ERROR_REG_FORMAT
, "The register must be r0-r31.");
2547 if ((*oper
)[0] != '<' || (*oper
)[1] != '<')
2549 SET_ERROR_NUMBER (ERROR_UNDEFINE
,
2550 "Operand format error; should be (rx, ry << n)");
2556 char *new_oper
= parse_exp (*oper
, &e
);
2557 if (e
.X_op
== O_constant
)
2560 /* The immediate must be in [0, 3]. */
2561 if (e
.X_add_number
< 0 || e
.X_add_number
> 3)
2563 SET_ERROR_NUMBER (ERROR_IMM_OVERFLOW
, NULL
);
2569 SET_ERROR_NUMBER (ERROR_EXP_CONSTANT
, NULL
);
2573 value
= (reg
<< 2) | e
.X_add_number
;
2575 value
= (reg
<< 5) | (1 << e
.X_add_number
);
2576 csky_insn
.val
[csky_insn
.idx
++] = value
;
2582 is_imm_over_range (char **oper
, int min
, int max
, int ext
)
2585 bfd_boolean ret
= FALSE
;
2586 char *new_oper
= parse_exp (*oper
, &e
);
2587 if (e
.X_op
== O_constant
)
2591 if ((int)e
.X_add_number
!= ext
2592 && (e
.X_add_number
< min
|| e
.X_add_number
> max
))
2595 SET_ERROR_NUMBER (ERROR_IMM_OVERFLOW
, NULL
);
2597 csky_insn
.val
[csky_insn
.idx
++] = e
.X_add_number
;
2604 is_oimm_over_range (char **oper
, int min
, int max
)
2607 bfd_boolean ret
= FALSE
;
2608 char *new_oper
= parse_exp (*oper
, &e
);
2609 if (e
.X_op
== O_constant
)
2613 if (e
.X_add_number
< min
|| e
.X_add_number
> max
)
2616 SET_ERROR_NUMBER (ERROR_IMM_OVERFLOW
, NULL
);
2618 csky_insn
.val
[csky_insn
.idx
++] = e
.X_add_number
- 1;
2625 is_psr_bit (char **oper
)
2627 const struct psrbit
*bits
;
2630 if (IS_CSKY_V1 (mach_flag
))
2631 bits
= cskyv1_psr_bits
;
2633 bits
= cskyv2_psr_bits
;
2635 while (bits
[i
].name
!= NULL
)
2637 if (bits
[i
].isa
&& !(bits
[i
].isa
& isa_flag
))
2642 if (strncasecmp (*oper
, bits
[i
].name
, strlen (bits
[i
].name
)) == 0)
2644 *oper
+= strlen (bits
[i
].name
);
2645 csky_insn
.val
[csky_insn
.idx
] |= bits
[i
].value
;
2650 SET_ERROR_NUMBER (ERROR_OPCODE_PSRBIT
, NULL
);
2655 parse_type_cpidx (char** oper
)
2659 if (s
[0] == 'c' && s
[1] == 'p')
2661 if (ISDIGIT (s
[2]) && ISDIGIT (s
[3]) && ! ISDIGIT (s
[4]))
2663 idx
= (s
[2] - '0') * 10 + s
[3] - '0';
2666 else if (ISDIGIT (s
[2]) && !ISDIGIT (s
[3]))
2677 *oper
= parse_exp (*oper
, &e
);
2678 if (e
.X_op
!= O_constant
)
2680 /* Can not recognize the operand. */
2683 idx
= e
.X_add_number
;
2686 csky_insn
.val
[csky_insn
.idx
++] = idx
;
2692 parse_type_cpreg (char** oper
)
2694 const char **regs
= csky_cp_reg
;
2698 for (i
= 0; i
< (int)(sizeof (csky_cp_reg
) / sizeof (char *)); i
++)
2700 len
= strlen (regs
[i
]);
2701 if (memcmp (*oper
, regs
[i
], len
) == 0 && !ISDIGIT (*(*oper
+ len
)))
2704 csky_insn
.val
[csky_insn
.idx
++] = i
;
2708 SET_ERROR_NUMBER (ERROR_CPREG_ILLEGAL
, *oper
);
2713 parse_type_cpcreg (char** oper
)
2718 regs
= csky_cp_creg
;
2719 for (i
= 0; i
< (int)(sizeof (csky_cp_creg
) / sizeof (char *)); i
++)
2721 len
= strlen (regs
[i
]);
2722 if (memcmp (*oper
, regs
[i
], len
) == 0 && !ISDIGIT (*(*oper
+ len
)))
2725 csky_insn
.val
[csky_insn
.idx
++] = i
;
2729 SET_ERROR_NUMBER (ERROR_CPREG_ILLEGAL
, *oper
);
2734 parse_type_areg (char** oper
)
2738 i
= csky_get_reg_val (*oper
, &len
);
2741 SET_ERROR_NUMBER (ERROR_GREG_ILLEGAL
, NULL
);
2745 csky_insn
.val
[csky_insn
.idx
++] = i
;
2751 parse_type_freg (char** oper
, int even
)
2755 reg
= csky_get_freg_val (*oper
, &len
);
2758 SET_ERROR_NUMBER (ERROR_REG_FORMAT
,
2759 "The fpu register format is not recognized.");
2763 csky_insn
.opcode_end
= *oper
;
2764 if (even
&& reg
& 0x1)
2766 SET_ERROR_NUMBER (ERROR_EXP_EVEN_FREG
, NULL
);
2769 csky_insn
.val
[csky_insn
.idx
++] = reg
;
2774 parse_ldst_imm (char **oper
, struct csky_opcode_info
*op ATTRIBUTE_UNUSED
,
2775 struct operand
*oprnd
)
2777 unsigned int mask
= oprnd
->mask
;
2781 shift
= oprnd
->shift
;
2791 if (**oper
== '\0' || **oper
== ')')
2793 csky_insn
.val
[csky_insn
.idx
++] = 0;
2798 *oper
= parse_exp (*oper
, &e
);
2799 if (e
.X_op
!= O_constant
)
2800 /* Not a constant. */
2802 else if (e
.X_add_number
< 0 || e
.X_add_number
>= max
)
2805 SET_ERROR_NUMBER (ERROR_IMM_OVERFLOW
, NULL
);
2808 if ((e
.X_add_number
% (1 << shift
)) != 0)
2811 SET_ERROR_NUMBER (ERROR_OFFSET_UNALIGNED
, ((unsigned long)1 << shift
));
2815 csky_insn
.val
[csky_insn
.idx
++] = e
.X_add_number
>> shift
;
2822 csky_count_operands (char *str
)
2824 char *oper_end
= str
;
2825 unsigned int oprnd_num
;
2826 int bracket_cnt
= 0;
2828 if (is_end_of_line
[(unsigned char) *oper_end
])
2833 /* Count how many operands. */
2835 while (!is_end_of_line
[(unsigned char) *oper_end
])
2837 if (*oper_end
== '(' || *oper_end
== '<')
2843 if (*oper_end
== ')' || *oper_end
== '>')
2849 if (!bracket_cnt
&& *oper_end
== ',')
2856 /* End of the operand parsing helper functions. */
2858 /* Parse the opcode part of an instruction. Fill in the csky_insn
2859 state and return true on success, false otherwise. */
2862 parse_opcode (char *str
)
2864 #define IS_OPCODE32F(a) (*(a - 2) == '3' && *(a - 1) == '2')
2865 #define IS_OPCODE16F(a) (*(a - 2) == '1' && *(a - 1) == '6')
2867 /* TRUE if this opcode has a suffix, like 'lrw.h'. */
2868 unsigned int has_suffix
= FALSE
;
2869 unsigned int nlen
= 0;
2871 char name
[OPCODE_MAX_LEN
+ 1];
2872 char macro_name
[OPCODE_MAX_LEN
+ 1];
2874 /* Remove space ahead of string. */
2875 while (ISSPACE (*str
))
2879 /* Find the opcode end. */
2880 while (nlen
< OPCODE_MAX_LEN
2881 && !is_end_of_line
[(unsigned char) *opcode_end
]
2882 && *opcode_end
!= ' ')
2884 /* Is csky force 32 or 16 instruction? */
2885 if (IS_CSKY_V2 (mach_flag
)
2886 && *opcode_end
== '.' && has_suffix
== FALSE
)
2889 if (IS_OPCODE32F (opcode_end
))
2891 csky_insn
.flag_force
= INSN_OPCODE32F
;
2894 else if (IS_OPCODE16F (opcode_end
))
2896 csky_insn
.flag_force
= INSN_OPCODE16F
;
2900 name
[nlen
] = *opcode_end
;
2905 /* Is csky force 32 or 16 instruction? */
2906 if (has_suffix
== FALSE
)
2908 if (IS_CSKY_V2 (mach_flag
) && IS_OPCODE32F (opcode_end
))
2910 csky_insn
.flag_force
= INSN_OPCODE32F
;
2913 else if (IS_OPCODE16F (opcode_end
))
2915 csky_insn
.flag_force
= INSN_OPCODE16F
;
2921 /* Generate macro_name for finding hash in macro hash_table. */
2922 if (has_suffix
== TRUE
)
2924 strncpy (macro_name
, str
, nlen
);
2925 macro_name
[nlen
] = '\0';
2927 /* Get csky_insn.opcode_end. */
2928 while (ISSPACE (*opcode_end
))
2930 csky_insn
.opcode_end
= opcode_end
;
2932 /* Count the operands. */
2933 csky_insn
.number
= csky_count_operands (opcode_end
);
2935 /* Find hash by name in csky_macros_hash and csky_opcodes_hash. */
2936 csky_insn
.macro
= (struct csky_macro_info
*) str_hash_find (csky_macros_hash
,
2938 csky_insn
.opcode
= (struct csky_opcode
*) str_hash_find (csky_opcodes_hash
,
2941 if (csky_insn
.macro
== NULL
&& csky_insn
.opcode
== NULL
)
2946 /* Main dispatch routine to parse operand OPRND for opcode OP from string
2950 get_operand_value (struct csky_opcode_info
*op
,
2951 char **oper
, struct operand
*oprnd
)
2953 struct soperand
*soprnd
= NULL
;
2954 if (oprnd
->mask
== HAS_SUB_OPERAND
)
2956 /* It has sub operand, it must be like:
2960 We will check the format here. */
2961 soprnd
= (struct soperand
*) oprnd
;
2965 int bracket_cnt
= 0;
2966 if (oprnd
->type
== OPRND_TYPE_BRACKET
)
2971 else if (oprnd
->type
== OPRND_TYPE_ABRACKET
)
2984 SET_ERROR_NUMBER ((oprnd
->type
== OPRND_TYPE_BRACKET
2985 ? ERROR_MISSING_LBRACKET
2986 : ERROR_MISSING_LANGLE_BRACKETS
), NULL
);
2990 /* If the oprnd2 is an immediate, it can not be parsed
2991 that end with ')'/'>'. Modify ')'/'>' to '\0'. */
2992 while ((*s
!= rc
|| bracket_cnt
!= 0) && (*s
!= '\n' && *s
!= '\0'))
3005 SET_ERROR_NUMBER ((oprnd
->type
== OPRND_TYPE_BRACKET
3006 ? ERROR_MISSING_RBRACKET
3007 : ERROR_MISSING_RANGLE_BRACKETS
), NULL
);
3011 if (get_operand_value (op
, oper
, &soprnd
->subs
[0]) == FALSE
)
3018 if (get_operand_value (op
, oper
, &soprnd
->subs
[1]) == FALSE
)
3029 switch (oprnd
->type
)
3031 /* TODO: add opcode type here, log errors in the function.
3032 If REGLIST, then j = csky_insn.number - 1.
3033 If there is needed to parse expressions, it will be
3035 case OPRND_TYPE_CTRLREG
:
3037 return parse_type_ctrlreg (oper
);
3038 case OPRND_TYPE_AREG
:
3039 return parse_type_areg (oper
);
3040 case OPRND_TYPE_FREG
:
3041 case OPRND_TYPE_VREG
:
3042 return parse_type_freg (oper
, 0);
3043 case OPRND_TYPE_FEREG
:
3044 return parse_type_freg (oper
, 1);
3045 case OPRND_TYPE_CPCREG
:
3046 return parse_type_cpcreg (oper
);
3047 case OPRND_TYPE_CPREG
:
3048 return parse_type_cpreg (oper
);
3049 case OPRND_TYPE_CPIDX
:
3050 return parse_type_cpidx (oper
);
3051 case OPRND_TYPE_GREG0_7
:
3052 case OPRND_TYPE_GREG0_15
:
3056 reg
= csky_get_reg_val (*oper
, &len
);
3060 SET_ERROR_NUMBER (ERROR_GREG_ILLEGAL
, NULL
);
3063 else if ((oprnd
->type
== OPRND_TYPE_GREG0_7
&& reg
> 7)
3064 || (oprnd
->type
== OPRND_TYPE_GREG0_15
&& reg
> 15))
3066 SET_ERROR_NUMBER (ERROR_REG_OVER_RANGE
, reg
);
3070 csky_insn
.val
[csky_insn
.idx
++] = reg
;
3073 case OPRND_TYPE_REGnsplr
:
3077 reg
= csky_get_reg_val (*oper
, &len
);
3080 || (IS_CSKY_V1 (mach_flag
)
3081 && (reg
== V1_REG_SP
|| reg
== V1_REG_LR
)))
3083 SET_ERROR_NUMBER (ERROR_REG_OVER_RANGE
, reg
);
3086 csky_insn
.val
[csky_insn
.idx
++] = reg
;
3090 case OPRND_TYPE_REGnr4_r7
:
3096 reg
= csky_get_reg_val (*oper
, &len
);
3097 if (reg
== -1 || (reg
<= 7 && reg
>= 4))
3100 csky_insn
.val
[csky_insn
.idx
++] = reg
;
3107 case OPRND_TYPE_REGr4_r7
:
3108 if (memcmp (*oper
, "r4-r7", sizeof ("r4-r7") - 1) == 0)
3110 *oper
+= sizeof ("r4-r7") - 1;
3111 csky_insn
.val
[csky_insn
.idx
++] = 0;
3114 SET_ERROR_NUMBER (ERROR_OPCODE_ILLEGAL
, NULL
);
3116 case OPRND_TYPE_IMM_LDST
:
3117 return parse_ldst_imm (oper
, op
, oprnd
);
3118 case OPRND_TYPE_IMM_FLDST
:
3119 return parse_ldst_imm (oper
, op
, oprnd
);
3120 case OPRND_TYPE_IMM1b
:
3121 return is_imm_over_range (oper
, 0, 1, -1);
3122 case OPRND_TYPE_IMM2b
:
3123 return is_imm_over_range (oper
, 0, 3, -1);
3124 case OPRND_TYPE_IMM2b_JMPIX
:
3125 /* ck802j support jmpix16, but not support jmpix32. */
3126 if (IS_CSKY_ARCH_802 (mach_flag
)
3127 && (op
->opcode
& 0xffff0000) != 0)
3129 SET_ERROR_NUMBER (ERROR_OPCODE_ILLEGAL
, NULL
);
3132 *oper
= parse_exp (*oper
, &csky_insn
.e1
);
3133 if (csky_insn
.e1
.X_op
== O_constant
)
3135 csky_insn
.opcode_end
= *oper
;
3136 if (csky_insn
.e1
.X_add_number
& 0x7)
3138 SET_ERROR_NUMBER (ERROR_JMPIX_OVER_RANGE
, NULL
);
3141 csky_insn
.val
[csky_insn
.idx
++]
3142 = (csky_insn
.e1
.X_add_number
>> 3) - 2;
3145 case OPRND_TYPE_IMM4b
:
3146 return is_imm_over_range (oper
, 0, 15, -1);
3148 case OPRND_TYPE_IMM5b
:
3149 return is_imm_over_range (oper
, 0, 31, -1);
3150 /* This type for "bgeni" in csky v1 ISA. */
3151 case OPRND_TYPE_IMM5b_7_31
:
3152 if (is_imm_over_range (oper
, 0, 31, -1))
3154 int val
= csky_insn
.val
[csky_insn
.idx
- 1];
3155 /* immediate values of 0 -> 6 translate to movi. */
3158 const char *name
= "movi";
3159 csky_insn
.opcode
= (struct csky_opcode
*)
3160 str_hash_find (csky_opcodes_hash
, name
);
3161 csky_insn
.val
[csky_insn
.idx
- 1] = 1 << val
;
3168 case OPRND_TYPE_IMM5b_1_31
:
3169 return is_imm_over_range (oper
, 1, 31, -1);
3170 case OPRND_TYPE_IMM5b_POWER
:
3171 if (is_imm_over_range (oper
, 1, (1u << 31) - 1, 1u << 31))
3174 int val
= csky_insn
.val
[csky_insn
.idx
- 1];
3175 log
= csky_log_2 (val
);
3176 csky_insn
.val
[csky_insn
.idx
- 1] = log
;
3177 return (log
== -1 ? FALSE
: TRUE
);
3182 /* This type for "mgeni" in csky v1 ISA. */
3183 case OPRND_TYPE_IMM5b_7_31_POWER
:
3184 if (is_imm_over_range (oper
, 1, (1u << 31) - 1, 1u << 31))
3187 int val
= csky_insn
.val
[csky_insn
.idx
- 1];
3188 log
= csky_log_2 (val
);
3189 /* Immediate values of 0 -> 6 translate to movi. */
3192 const char *name
= "movi";
3193 csky_insn
.opcode
= (struct csky_opcode
*)
3194 str_hash_find (csky_opcodes_hash
, name
);
3195 as_warn (_("translating mgeni to movi"));
3198 csky_insn
.val
[csky_insn
.idx
- 1] = log
;
3199 return (log
== -1 ? FALSE
: TRUE
);
3204 case OPRND_TYPE_IMM5b_RORI
:
3206 unsigned max_shift
= IS_CSKY_V1 (mach_flag
) ? 31 : 32;
3208 if (is_imm_over_range (oper
, 1, max_shift
, -1))
3210 int i
= csky_insn
.idx
- 1;
3211 csky_insn
.val
[i
] = 32 - csky_insn
.val
[i
];
3218 case OPRND_TYPE_IMM5b_BMASKI
:
3219 /* For csky v1 bmask inst. */
3221 if (!is_imm_over_range (oper
, 8, 31, 0))
3223 unsigned int mask_val
= csky_insn
.val
[csky_insn
.idx
- 1];
3224 if (mask_val
> 0 && mask_val
< 8)
3226 const char *op_movi
= "movi";
3227 csky_insn
.opcode
= (struct csky_opcode
*)
3228 str_hash_find (csky_opcodes_hash
, op_movi
);
3229 if (csky_insn
.opcode
== NULL
)
3231 csky_insn
.val
[csky_insn
.idx
- 1] = (1 << mask_val
) - 1;
3237 case OPRND_TYPE_IMM8b_BMASKI
:
3238 /* For csky v2 bmask, which will transfer to 16bits movi. */
3239 if (is_imm_over_range (oper
, 1, 8, -1))
3241 unsigned int mask_val
= csky_insn
.val
[csky_insn
.idx
- 1];
3242 csky_insn
.val
[csky_insn
.idx
- 1] = (1 << mask_val
) - 1;
3246 case OPRND_TYPE_OIMM4b
:
3247 return is_oimm_over_range (oper
, 1, 16);
3248 case OPRND_TYPE_OIMM5b
:
3249 return is_oimm_over_range (oper
, 1, 32);
3250 case OPRND_TYPE_OIMM5b_IDLY
:
3251 if (is_imm_over_range (oper
, 0, 32, -1))
3253 /* imm5b for idly n: 0<=n<4, imm5b=3; 4<=n<=32, imm5b=n-1. */
3254 unsigned long imm
= csky_insn
.val
[csky_insn
.idx
- 1];
3257 csky_show_error (WARNING_IDLY
, 0, (void *)imm
, NULL
);
3261 csky_insn
.val
[csky_insn
.idx
- 1] = imm
;
3267 /* For csky v2 bmask inst. */
3268 case OPRND_TYPE_OIMM5b_BMASKI
:
3269 if (!is_oimm_over_range (oper
, 17, 32))
3271 int mask_val
= csky_insn
.val
[csky_insn
.idx
- 1];
3272 if (mask_val
+ 1 == 0)
3274 if (mask_val
> 0 && mask_val
< 16)
3276 const char *op_movi
= "movi";
3277 csky_insn
.opcode
= (struct csky_opcode
*)
3278 str_hash_find (csky_opcodes_hash
, op_movi
);
3279 if (csky_insn
.opcode
== NULL
)
3281 csky_insn
.val
[csky_insn
.idx
- 1] = (1 << (mask_val
+ 1)) - 1;
3286 case OPRND_TYPE_IMM7b
:
3287 return is_imm_over_range (oper
, 0, 127, -1);
3288 case OPRND_TYPE_IMM8b
:
3289 return is_imm_over_range (oper
, 0, 255, -1);
3290 case OPRND_TYPE_IMM12b
:
3291 return is_imm_over_range (oper
, 0, 4095, -1);
3292 case OPRND_TYPE_IMM15b
:
3293 return is_imm_over_range (oper
, 0, 0xfffff, -1);
3294 case OPRND_TYPE_IMM16b
:
3295 return is_imm_over_range (oper
, 0, 65535, -1);
3296 case OPRND_TYPE_OIMM16b
:
3297 return is_oimm_over_range (oper
, 1, 65536);
3298 case OPRND_TYPE_IMM32b
:
3301 char *new_oper
= parse_exp (*oper
, &e
);
3302 if (e
.X_op
== O_constant
)
3305 csky_insn
.val
[csky_insn
.idx
++] = e
.X_add_number
;
3310 case OPRND_TYPE_IMM16b_MOVIH
:
3311 case OPRND_TYPE_IMM16b_ORI
:
3313 bfd_reloc_code_real_type r
= BFD_RELOC_NONE
;
3316 char * save
= input_line_pointer
;
3317 /* get the reloc type, and set "@GOTxxx" as ' ' */
3318 while (**oper
!= '@' && **oper
!= '\0')
3322 input_line_pointer
= *oper
;
3324 while (*(*oper
+ len
+ 1) != '\0')
3326 **oper
= *(*oper
+ len
+ 1);
3327 *(*oper
+ len
+ 1) = '\0';
3332 input_line_pointer
= save
;
3333 *oper
= parse_exp (curr
, &csky_insn
.e1
);
3336 case OPRND_TYPE_PSR_BITS_LIST
:
3339 if (csky_insn
.number
== 0)
3343 csky_insn
.val
[csky_insn
.idx
] = 0;
3344 if (is_psr_bit (oper
) != FALSE
)
3345 while (**oper
== ',')
3348 if (is_psr_bit (oper
) == FALSE
)
3356 if (ret
== TRUE
&& IS_CSKY_V1 (mach_flag
)
3357 && csky_insn
.val
[csky_insn
.idx
] > 8)
3361 SET_ERROR_NUMBER (ERROR_OPERANDS_ILLEGAL
, csky_insn
.opcode_end
);
3366 /* FPU round mode. */
3367 static const char *round_mode
[] =
3376 for (i
= 0; round_mode
[i
]; i
++)
3377 if (strncasecmp (*oper
, round_mode
[i
], strlen (round_mode
[i
])) == 0)
3379 *oper
+= strlen (round_mode
[i
]);
3380 csky_insn
.val
[csky_insn
.idx
++] = i
;
3386 case OPRND_TYPE_REGLIST_COMMA
:
3387 case OPRND_TYPE_BRACKET
:
3388 /* TODO: using sub operand union. */
3389 case OPRND_TYPE_ABRACKET
:
3390 /* TODO: using sub operand union. */
3391 case OPRND_TYPE_REGLIST_DASH
:
3392 return is_reglist_legal (oper
);
3393 case OPRND_TYPE_FREGLIST_DASH
:
3394 return is_freglist_legal (oper
);
3395 case OPRND_TYPE_AREG_WITH_BRACKET
:
3401 SET_ERROR_NUMBER (ERROR_MISSING_LBRACKET
, NULL
);
3405 reg
= csky_get_reg_val (*oper
, &len
);
3408 SET_ERROR_NUMBER (ERROR_EXP_GREG
, NULL
);
3414 SET_ERROR_NUMBER (ERROR_MISSING_RBRACKET
, NULL
);
3418 csky_insn
.val
[csky_insn
.idx
++] = reg
;
3421 case OPRND_TYPE_REGsp
:
3422 return is_reg_sp (oper
);
3423 case OPRND_TYPE_REGbsp
:
3424 return is_reg_sp_with_bracket (oper
);
3426 case OPRND_TYPE_OFF8b
:
3427 case OPRND_TYPE_OFF16b
:
3428 *oper
= parse_rt (*oper
, 1, &csky_insn
.e1
, -1);
3429 csky_insn
.val
[csky_insn
.idx
++] = 0;
3431 case OPRND_TYPE_LABEL_WITH_BRACKET
:
3432 case OPRND_TYPE_CONSTANT
:
3433 case OPRND_TYPE_ELRW_CONSTANT
:
3435 csky_insn
.val
[csky_insn
.idx
++] = 0;
3437 csky_insn
.val
[csky_insn
.idx
++] = NEED_OUTPUT_LITERAL
;
3438 *oper
= parse_rt (*oper
, 0, &csky_insn
.e1
, -1);
3440 case OPRND_TYPE_FCONSTANT
:
3441 *oper
= parse_rtf (*oper
, 0, &csky_insn
.e1
);
3444 case OPRND_TYPE_SFLOAT
:
3445 case OPRND_TYPE_DFLOAT
:
3446 /* For fmovis and fmovid, which accept a constant float with
3452 *oper
= parse_fexp (*oper
, &csky_insn
.e1
, 1, &dbnum
);
3453 if (csky_insn
.e1
.X_op
== O_absent
)
3456 /* Convert the representation from IEEE double to the 13-bit
3457 encoding used internally for fmovis and fmovid. */
3458 imm4
= 11 - (((dbnum
& 0x7ff0000000000000ULL
) >> 52) - 1023);
3459 /* Check float range. */
3460 if ((dbnum
& 0x00000fffffffffffULL
) || imm4
< 0 || imm4
> 15)
3462 csky_show_error (ERROR_IMM_OVERFLOW
, 2, NULL
, NULL
);
3465 imm8
= (dbnum
& 0x000ff00000000000ULL
) >> 44;
3466 csky_insn
.e1
.X_add_number
3467 = (((imm8
& 0xf) << 4)
3468 | ((imm8
& 0xf0) << 17)
3469 | ((imm4
& 0xf) << 16)
3470 | ((dbnum
& 0x8000000000000000ULL
) >> 43));
3475 case OPRND_TYPE_IMM_OFF18b
:
3476 *oper
= parse_exp (*oper
, &csky_insn
.e1
);
3479 case OPRND_TYPE_BLOOP_OFF4b
:
3480 *oper
= parse_exp (*oper
, &csky_insn
.e2
);
3481 if (csky_insn
.e2
.X_op
== O_symbol
)
3483 csky_insn
.opcode_end
= *oper
;
3489 case OPRND_TYPE_BLOOP_OFF12b
:
3490 case OPRND_TYPE_OFF10b
:
3491 case OPRND_TYPE_OFF11b
:
3492 case OPRND_TYPE_OFF16b_LSL1
:
3493 case OPRND_TYPE_OFF26b
:
3494 *oper
= parse_exp (*oper
, &csky_insn
.e1
);
3495 if (csky_insn
.e1
.X_op
== O_symbol
)
3497 csky_insn
.opcode_end
= *oper
;
3502 /* For xtrb0(1)(2)(3) and div in csky v1 ISA. */
3503 case OPRND_TYPE_REG_r1a
:
3507 reg
= csky_get_reg_val (*oper
, &len
);
3510 SET_ERROR_NUMBER (ERROR_REG_FORMAT
,
3511 "The first operand must be register r1.");
3515 mov_r1_after
= TRUE
;
3517 csky_insn
.opcode_end
= *oper
;
3518 csky_insn
.val
[csky_insn
.idx
++] = reg
;
3521 case OPRND_TYPE_REG_r1b
:
3525 reg
= csky_get_reg_val (*oper
, &len
);
3528 SET_ERROR_NUMBER (ERROR_REG_FORMAT
,
3529 "The second operand must be register r1.");
3534 unsigned int mov_insn
= CSKYV1_INST_MOV_R1_RX
;
3535 mov_insn
|= reg
<< 4;
3536 mov_r1_before
= TRUE
;
3537 csky_insn
.output
= frag_more (2);
3538 dwarf2_emit_insn (0);
3539 md_number_to_chars (csky_insn
.output
, mov_insn
, 2);
3542 csky_insn
.opcode_end
= *oper
;
3543 csky_insn
.val
[csky_insn
.idx
++] = reg
;
3546 case OPRND_TYPE_DUMMY_REG
:
3550 reg
= csky_get_reg_val (*oper
, &len
);
3553 SET_ERROR_NUMBER (ERROR_GREG_ILLEGAL
, NULL
);
3556 if (reg
!= csky_insn
.val
[0])
3558 SET_ERROR_NUMBER (ERROR_REG_FORMAT
,
3559 "The second register must be the same as the first.");
3563 csky_insn
.opcode_end
= *oper
;
3564 csky_insn
.val
[csky_insn
.idx
++] = reg
;
3567 case OPRND_TYPE_2IN1_DUMMY
:
3573 reg
= csky_get_reg_val (*oper
, &len
);
3576 SET_ERROR_NUMBER (ERROR_GREG_ILLEGAL
, NULL
);
3579 /* dummy reg's real type should be same with first operand. */
3580 if (op
->oprnd
.oprnds
[0].type
== OPRND_TYPE_GREG0_15
)
3582 else if (op
->oprnd
.oprnds
[0].type
== OPRND_TYPE_GREG0_7
)
3586 if (reg
< min
|| reg
> max
)
3588 csky_insn
.val
[csky_insn
.idx
++] = reg
;
3589 /* if it is the last operands. */
3590 if (csky_insn
.idx
> 2)
3592 /* For "insn rz, rx, ry", if rx or ry is equal to rz,
3593 we can output the insn like "insn rz, rx". */
3594 if (csky_insn
.val
[0] == csky_insn
.val
[1])
3595 csky_insn
.val
[1] = 0;
3596 else if (csky_insn
.val
[0] == csky_insn
.val
[2])
3597 csky_insn
.val
[2] = 0;
3602 csky_insn
.opcode_end
= *oper
;
3605 case OPRND_TYPE_DUP_GREG0_7
:
3606 case OPRND_TYPE_DUP_GREG0_15
:
3607 case OPRND_TYPE_DUP_AREG
:
3612 unsigned int shift_num
;
3613 if (oprnd
->type
== OPRND_TYPE_DUP_GREG0_7
)
3618 else if (oprnd
->type
== OPRND_TYPE_DUP_GREG0_15
)
3628 reg
= csky_get_reg_val (*oper
, &len
);
3632 SET_ERROR_NUMBER (ERROR_REG_FORMAT
,
3633 "The register must be r0-r31");
3635 SET_ERROR_NUMBER (ERROR_REG_FORMAT
,
3636 "The register must be r0-r15");
3641 SET_ERROR_NUMBER (ERROR_REG_OVER_RANGE
, reg
);
3644 reg
|= reg
<< shift_num
;
3646 csky_insn
.opcode_end
= *oper
;
3647 csky_insn
.val
[csky_insn
.idx
++] = reg
;
3650 case OPRND_TYPE_CONST1
:
3651 *oper
= parse_exp (*oper
, &csky_insn
.e1
);
3652 if (csky_insn
.e1
.X_op
== O_constant
)
3654 csky_insn
.opcode_end
= *oper
;
3655 if (csky_insn
.e1
.X_add_number
!= 1)
3657 csky_insn
.val
[csky_insn
.idx
++] = 1;
3661 case OPRND_TYPE_UNCOND10b
:
3662 case OPRND_TYPE_UNCOND16b
:
3663 *oper
= parse_exp (*oper
, &csky_insn
.e1
);
3664 if (csky_insn
.e1
.X_op
== O_constant
)
3666 input_line_pointer
= *oper
;
3667 csky_insn
.opcode_end
= *oper
;
3668 csky_insn
.relax
.max
= UNCD_DISP16_LEN
;
3669 csky_insn
.relax
.var
= UNCD_DISP10_LEN
;
3670 csky_insn
.relax
.subtype
= UNCD_DISP10
;
3671 csky_insn
.val
[csky_insn
.idx
++] = 0;
3673 case OPRND_TYPE_COND10b
:
3674 case OPRND_TYPE_COND16b
:
3675 *oper
= parse_exp (*oper
, &csky_insn
.e1
);
3676 if (csky_insn
.e1
.X_op
== O_constant
)
3678 input_line_pointer
= *oper
;
3679 csky_insn
.opcode_end
= *oper
;
3680 /* CK801 doesn't have 32-bit bt/bf insns; relax to a short
3681 jump around a 32-bit unconditional branch instead. */
3682 if (IS_CSKY_ARCH_801 (mach_flag
))
3684 csky_insn
.relax
.max
= SCOND_DISP16_LEN
;
3685 csky_insn
.relax
.var
= SCOND_DISP10_LEN
;
3686 csky_insn
.relax
.subtype
= SCOND_DISP10
;
3690 csky_insn
.relax
.max
= COND_DISP16_LEN
;
3691 csky_insn
.relax
.var
= COND_DISP10_LEN
;
3692 csky_insn
.relax
.subtype
= COND_DISP10
;
3694 csky_insn
.val
[csky_insn
.idx
++] = 0;
3696 case OPRND_TYPE_JCOMPZ
:
3697 *oper
= parse_exp (*oper
, &csky_insn
.e1
);
3698 if (csky_insn
.e1
.X_op
== O_constant
)
3700 input_line_pointer
= *oper
;
3701 csky_insn
.opcode_end
= *oper
;
3702 csky_insn
.relax
.max
= JCOMPZ_DISP32_LEN
;
3703 csky_insn
.relax
.var
= JCOMPZ_DISP16_LEN
;
3704 csky_insn
.relax
.subtype
= JCOMPZ_DISP16
;
3705 csky_insn
.max
= JCOMPZ_DISP32_LEN
;
3706 csky_insn
.val
[csky_insn
.idx
++] = 0;
3708 case OPRND_TYPE_JBTF
:
3709 *oper
= parse_exp (*oper
, &csky_insn
.e1
);
3710 input_line_pointer
= *oper
;
3711 csky_insn
.opcode_end
= *oper
;
3712 csky_insn
.relax
.max
= csky_relax_table
[C (COND_JUMP_S
, DISP32
)].rlx_length
;
3713 csky_insn
.relax
.var
= csky_relax_table
[C (COND_JUMP_S
, DISP12
)].rlx_length
;
3714 csky_insn
.relax
.subtype
= C (COND_JUMP_S
, 0);
3715 csky_insn
.val
[csky_insn
.idx
++] = 0;
3716 csky_insn
.max
= C32_LEN_S
+ 2;
3718 case OPRND_TYPE_JBR
:
3719 *oper
= parse_exp (*oper
, &csky_insn
.e1
);
3720 input_line_pointer
= *oper
;
3721 csky_insn
.opcode_end
= *oper
;
3722 csky_insn
.relax
.max
= csky_relax_table
[C (UNCD_JUMP_S
, DISP32
)].rlx_length
;
3723 csky_insn
.relax
.var
= csky_relax_table
[C (UNCD_JUMP_S
, DISP12
)].rlx_length
;
3724 csky_insn
.relax
.subtype
= C (UNCD_JUMP_S
, 0);
3725 csky_insn
.val
[csky_insn
.idx
++] = 0;
3726 csky_insn
.max
= U32_LEN_S
+ 2;
3728 case OPRND_TYPE_JBSR
:
3730 *oper
= parse_exp (*oper
, &csky_insn
.e1
);
3732 *oper
= parse_rt (*oper
, 1, &csky_insn
.e1
, -1);
3733 input_line_pointer
= *oper
;
3734 csky_insn
.opcode_end
= *oper
;
3735 csky_insn
.val
[csky_insn
.idx
++] = 0;
3737 case OPRND_TYPE_REGLIST_DASH_COMMA
:
3738 return is_reglist_dash_comma_legal (oper
, oprnd
);
3740 case OPRND_TYPE_MSB2SIZE
:
3741 case OPRND_TYPE_LSB2SIZE
:
3744 char *new_oper
= parse_exp (*oper
, &e
);
3745 if (e
.X_op
== O_constant
)
3748 if (e
.X_add_number
> 31)
3750 SET_ERROR_NUMBER (ERROR_IMM_OVERFLOW
, NULL
);
3753 csky_insn
.val
[csky_insn
.idx
++] = e
.X_add_number
;
3754 if (oprnd
->type
== OPRND_TYPE_LSB2SIZE
)
3756 if (csky_insn
.val
[csky_insn
.idx
- 1] > csky_insn
.val
[csky_insn
.idx
- 2])
3758 SET_ERROR_NUMBER (ERROR_IMM_OVERFLOW
, NULL
);
3761 csky_insn
.val
[csky_insn
.idx
- 2] -= e
.X_add_number
;
3767 case OPRND_TYPE_AREG_WITH_LSHIFT
:
3768 return is_reg_lshift_illegal (oper
, 0);
3769 case OPRND_TYPE_AREG_WITH_LSHIFT_FPU
:
3770 return is_reg_lshift_illegal (oper
, 1);
3771 case OPRND_TYPE_FREG_WITH_INDEX
:
3772 if (parse_type_freg (oper
, 0))
3777 if (is_imm_over_range (oper
, 0, 0xf, -1))
3781 unsigned int idx
= --csky_insn
.idx
;
3782 unsigned int val
= csky_insn
.val
[idx
];
3784 csky_insn
.val
[idx
- 1] |= val
<< 4;
3788 SET_ERROR_NUMBER (ERROR_MISSING_RSQUARE_BRACKETS
, NULL
);
3792 SET_ERROR_NUMBER (ERROR_MISSING_LSQUARE_BRACKETS
, NULL
);
3803 /* Subroutine of parse_operands. */
3806 parse_operands_op (char *str
, struct csky_opcode_info
*op
)
3813 for (i
= 0; i
< OP_TABLE_NUM
&& op
[i
].operand_num
!= -2; i
++)
3818 /* if operand_num = -1, it is a insn with a REGLIST type operand.i. */
3819 if (!(op
[i
].operand_num
== csky_insn
.number
3820 || (op
[i
].operand_num
== -1 && csky_insn
.number
!= 0)))
3822 /* The smaller err_num is more serious. */
3823 SET_ERROR_NUMBER (ERROR_OPERANDS_NUMBER
, op
[i
].operand_num
);
3828 for (j
= 0; j
< csky_insn
.number
; j
++)
3830 while (ISSPACE (*oper
))
3832 flag_pass
= get_operand_value (&op
[i
], &oper
,
3833 &op
[i
].oprnd
.oprnds
[j
]);
3834 if (flag_pass
== FALSE
)
3836 while (ISSPACE (*oper
))
3839 if (j
< csky_insn
.number
- 1 && op
[i
].operand_num
!= -1)
3845 SET_ERROR_NUMBER (ERROR_MISSING_COMMA
, NULL
);
3850 else if (!is_end_of_line
[(unsigned char) *oper
])
3852 SET_ERROR_NUMBER (ERROR_BAD_END
, NULL
);
3859 /* Parse operands in one table end. */
3861 if (flag_pass
== TRUE
)
3863 /* Parse operands success, set opcode_idx. */
3864 csky_insn
.opcode_idx
= i
;
3868 error_state
.opnum
= j
+ 1;
3870 /* Parse operands in ALL tables end. */
3874 /* Parse the operands according to operand type. */
3877 parse_operands (char *str
)
3881 /* Parse operands according to flag_force. */
3882 if (csky_insn
.flag_force
== INSN_OPCODE16F
3883 && (csky_insn
.opcode
->isa_flag16
& isa_flag
) != 0)
3885 if (parse_operands_op (oper
, csky_insn
.opcode
->op16
) == TRUE
)
3887 csky_insn
.isize
= 2;
3892 else if (csky_insn
.flag_force
== INSN_OPCODE32F
3893 && (csky_insn
.opcode
->isa_flag32
& isa_flag
) != 0)
3895 if (parse_operands_op (oper
, csky_insn
.opcode
->op32
) == TRUE
)
3897 csky_insn
.isize
= 4;
3904 if ((csky_insn
.opcode
->isa_flag16
& isa_flag
) != 0
3905 && parse_operands_op (oper
, csky_insn
.opcode
->op16
) == TRUE
)
3907 csky_insn
.isize
= 2;
3910 if ((csky_insn
.opcode
->isa_flag32
& isa_flag
) != 0
3911 && parse_operands_op (oper
, csky_insn
.opcode
->op32
) == TRUE
)
3913 csky_insn
.isize
= 4;
3921 csky_generate_frags (void)
3923 /* frag more relax reloc. */
3924 if (csky_insn
.flag_force
== INSN_OPCODE16F
3925 || !IS_SUPPORT_OPCODE32 (csky_insn
.opcode
))
3927 csky_insn
.output
= frag_more (csky_insn
.isize
);
3928 if (csky_insn
.opcode
->reloc16
)
3930 /* 16 bits opcode force, should generate fixup. */
3931 reloc_howto_type
*howto
;
3932 howto
= bfd_reloc_type_lookup (stdoutput
,
3933 csky_insn
.opcode
->reloc16
);
3934 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
3935 2, &csky_insn
.e1
, howto
->pc_relative
,
3936 csky_insn
.opcode
->reloc16
);
3939 else if (csky_insn
.flag_force
== INSN_OPCODE32F
)
3941 csky_insn
.output
= frag_more (csky_insn
.isize
);
3942 if (csky_insn
.opcode
->reloc32
)
3944 reloc_howto_type
*howto
;
3945 howto
= bfd_reloc_type_lookup (stdoutput
,
3946 csky_insn
.opcode
->reloc32
);
3947 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
3948 4, &csky_insn
.e1
, howto
->pc_relative
,
3949 csky_insn
.opcode
->reloc32
);
3952 else if (csky_insn
.opcode
->relax
)
3953 /* Generate the relax information. */
3954 csky_insn
.output
= frag_var (rs_machine_dependent
,
3955 csky_insn
.relax
.max
,
3956 csky_insn
.relax
.var
,
3957 csky_insn
.relax
.subtype
,
3958 csky_insn
.e1
.X_add_symbol
,
3959 csky_insn
.e1
.X_add_number
, 0);
3962 csky_insn
.output
= frag_more (csky_insn
.isize
);
3963 if (csky_insn
.opcode
->reloc16
&& csky_insn
.isize
== 2)
3965 reloc_howto_type
*howto
;
3966 howto
= bfd_reloc_type_lookup (stdoutput
,
3967 csky_insn
.opcode
->reloc16
);
3968 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
3969 2, &csky_insn
.e1
, howto
->pc_relative
,
3970 csky_insn
.opcode
->reloc16
);
3972 else if (csky_insn
.opcode
->reloc32
&& csky_insn
.isize
== 4)
3974 reloc_howto_type
*howto
;
3975 howto
= bfd_reloc_type_lookup (stdoutput
,
3976 csky_insn
.opcode
->reloc32
);
3977 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
3978 4, &csky_insn
.e1
, howto
->pc_relative
,
3979 csky_insn
.opcode
->reloc32
);
3985 /* Return the bits of VAL shifted according to MASK. The bits of MASK
3986 need not be contiguous. */
3989 generate_masked_value (int mask
, int val
)
3994 for (bit
= 1; mask
; bit
= bit
<< 1)
4005 /* Return the result of masking operand number OPRND_IDX into the
4006 instruction word according to the information in OPRND. */
4009 generate_masked_operand (struct operand
*oprnd
, int *oprnd_idx
)
4011 struct soperand
*soprnd
= NULL
;
4014 if ((unsigned int)oprnd
->mask
== HAS_SUB_OPERAND
)
4016 soprnd
= (struct soperand
*) oprnd
;
4017 generate_masked_operand (&soprnd
->subs
[0], oprnd_idx
);
4018 generate_masked_operand (&soprnd
->subs
[1], oprnd_idx
);
4022 val
= csky_insn
.val
[*oprnd_idx
];
4024 val
= generate_masked_value (mask
, val
);
4025 csky_insn
.inst
|= val
;
4031 csky_generate_insn (void)
4034 struct csky_opcode_info
*opinfo
= NULL
;
4036 if (csky_insn
.isize
== 4)
4037 opinfo
= &csky_insn
.opcode
->op32
[csky_insn
.opcode_idx
];
4038 else if (csky_insn
.isize
== 2)
4039 opinfo
= &csky_insn
.opcode
->op16
[csky_insn
.opcode_idx
];
4042 csky_insn
.inst
= opinfo
->opcode
;
4043 if (opinfo
->operand_num
== -1)
4045 generate_masked_operand (&opinfo
->oprnd
.oprnds
[i
], &sidx
);
4049 for (i
= 0; i
< opinfo
->operand_num
; i
++)
4050 generate_masked_operand (&opinfo
->oprnd
.oprnds
[i
], &sidx
);
4054 /* Main entry point for assembling a single instruction. */
4057 md_assemble (char *str
)
4059 bfd_boolean must_check_literals
= TRUE
;
4060 csky_insn
.isize
= 0;
4063 csky_insn
.flag_force
= INSN_OPCODE
;
4064 csky_insn
.macro
= NULL
;
4065 csky_insn
.opcode
= NULL
;
4066 memset (csky_insn
.val
, 0, sizeof (int) * MAX_OPRND_NUM
);
4067 /* Initialize err_num. */
4068 error_state
.err_num
= ERROR_NONE
;
4069 mov_r1_before
= FALSE
;
4070 mov_r1_after
= FALSE
;
4072 mapping_state (MAP_TEXT
);
4073 /* Tie dwarf2 debug info to every insn if set option --gdwarf2. */
4074 dwarf2_emit_insn (0);
4075 while (ISSPACE (* str
))
4077 /* Get opcode from str. */
4078 if (parse_opcode (str
) == FALSE
)
4080 csky_show_error (ERROR_OPCODE_ILLEGAL
, 0, NULL
, NULL
);
4084 /* If it is a macro instruction, handle it. */
4085 if (csky_insn
.macro
!= NULL
)
4087 if (csky_insn
.number
== csky_insn
.macro
->oprnd_num
)
4089 csky_insn
.macro
->handle_func ();
4092 else if (error_state
.err_num
> ERROR_OPERANDS_NUMBER
)
4093 SET_ERROR_NUMBER (ERROR_OPERANDS_NUMBER
, csky_insn
.macro
->oprnd_num
);
4096 if (csky_insn
.opcode
== NULL
)
4098 SET_ERROR_NUMBER (ERROR_OPCODE_ILLEGAL
, NULL
);
4099 csky_show_error (error_state
.err_num
, error_state
.opnum
,
4100 (void *)error_state
.arg1
, (void *)error_state
.arg1
);
4104 /* Parse the operands according to operand type. */
4105 if (parse_operands (csky_insn
.opcode_end
) == FALSE
)
4107 csky_show_error (error_state
.err_num
, error_state
.opnum
,
4108 (void *)error_state
.arg1
, (void *)error_state
.arg1
);
4112 /* if this insn has work in opcode table, then do it. */
4113 if (csky_insn
.opcode
->work
!= NULL
)
4114 must_check_literals
= csky_insn
.opcode
->work ();
4117 /* Generate relax or reloc if necessary. */
4118 csky_generate_frags ();
4119 /* Generate the insn by mask. */
4120 csky_generate_insn ();
4121 /* Write inst to frag. */
4122 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
4125 /* Adjust for xtrb0/xtrb1/xtrb2/xtrb3/divs/divu in csky v1 ISA. */
4126 if (mov_r1_after
== TRUE
)
4128 unsigned int mov_insn
= CSKYV1_INST_MOV_RX_R1
;
4129 mov_insn
|= csky_insn
.val
[0];
4130 mov_r1_before
= TRUE
;
4131 csky_insn
.output
= frag_more (2);
4132 dwarf2_emit_insn (0);
4133 md_number_to_chars (csky_insn
.output
, mov_insn
, 2);
4134 csky_insn
.isize
+= 2;
4136 if (mov_r1_before
== TRUE
)
4137 csky_insn
.isize
+= 2;
4139 /* Check literal. */
4140 if (must_check_literals
)
4142 if (csky_insn
.max
== 0)
4143 check_literals (csky_insn
.opcode
->transfer
, csky_insn
.isize
);
4145 check_literals (csky_insn
.opcode
->transfer
, csky_insn
.max
);
4148 insn_reloc
= BFD_RELOC_NONE
;
4151 /* Attempt to handle option with value C, returning non-zero on success. */
4154 md_parse_option (int c
, const char *arg
)
4172 /* Convert a machine dependent frag. */
4173 #define PAD_LITERAL_LENGTH 6
4174 #define opposite_of_stored_comp(insn) (insn ^ 0x04000000)
4175 #define opposite_of_stored_compz(insn) (insn ^ 0x00200000)
4176 #define make_insn(total_length, opcode, operand, operand_length) \
4178 if (total_length > 0) \
4180 csky_write_insn (buf, \
4181 opcode | (operand & ((1 << operand_length) - 1)), \
4183 buf += total_length; \
4184 fragp->fr_fix += total_length; \
4188 #define make_literal(fragp, literal_offset) \
4190 make_insn (literal_offset, PAD_FILL_CONTENT, 0, 0); \
4191 fix_new (fragp, fragp->fr_fix, 4, fragp->fr_symbol, \
4192 fragp->fr_offset, 0, BFD_RELOC_CKCORE_ADDR32); \
4193 make_insn (4, 0, 0, 0); \
4194 make_insn (2 - literal_offset, PAD_FILL_CONTENT, 0, 0); \
4198 md_convert_frag (bfd
*abfd ATTRIBUTE_UNUSED
, segT asec
, fragS
*fragp
)
4201 char *buf
= fragp
->fr_fix
+ &fragp
->fr_literal
[0];
4203 gas_assert (fragp
->fr_symbol
);
4204 if (IS_EXTERNAL_SYM (fragp
->fr_symbol
, asec
))
4207 disp
= (S_GET_VALUE (fragp
->fr_symbol
)
4212 switch (fragp
->fr_subtype
)
4214 /* generate new insn. */
4215 case C (COND_JUMP
, DISP12
):
4216 case C (UNCD_JUMP
, DISP12
):
4217 case C (COND_JUMP_PIC
, DISP12
):
4218 case C (UNCD_JUMP_PIC
, DISP12
):
4220 #define CSKY_V1_B_MASK 0xf8
4225 /* Error. odd displacement at %x, next_inst-2. */
4230 if (!target_big_endian
)
4232 t0
= buf
[1] & CSKY_V1_B_MASK
;
4233 md_number_to_chars (buf
, disp
, 2);
4234 buf
[1] = (buf
[1] & ~CSKY_V1_B_MASK
) | t0
;
4238 t0
= buf
[0] & CSKY_V1_B_MASK
;
4239 md_number_to_chars (buf
, disp
, 2);
4240 buf
[0] = (buf
[0] & ~CSKY_V1_B_MASK
) | t0
;
4245 case C (COND_JUMP
, DISP32
):
4246 case C (COND_JUMP
, UNDEF_WORD_DISP
):
4248 /* A conditional branch wont fit into 12 bits:
4255 int first_inst
= fragp
->fr_fix
+ fragp
->fr_address
;
4256 int is_unaligned
= (first_inst
& 3);
4258 if (!target_big_endian
)
4260 /* b!cond instruction. */
4262 /* jmpi instruction. */
4263 buf
[2] = CSKYV1_INST_JMPI
& 0xff;
4264 buf
[3] = CSKYV1_INST_JMPI
>> 8;
4268 /* b!cond instruction. */
4270 /* jmpi instruction. */
4271 buf
[2] = CSKYV1_INST_JMPI
>> 8;
4272 buf
[3] = CSKYV1_INST_JMPI
& 0xff;
4277 if (!target_big_endian
)
4279 /* bt/bf: jump to pc + 2 + (4 << 1). */
4281 /* jmpi: jump to MEM (pc + 2 + (1 << 2)). */
4286 /* bt/bf: jump to pc + 2 + (4 << 1). */
4288 /* jmpi: jump to MEM (pc + 2 + (1 << 2)). */
4291 /* Aligned 4 bytes. */
4300 /* Make reloc for the long disp. */
4301 fix_new (fragp
, fragp
->fr_fix
+ 6, 4,
4302 fragp
->fr_symbol
, fragp
->fr_offset
, 0, BFD_RELOC_32
);
4303 fragp
->fr_fix
+= C32_LEN
;
4307 if (!target_big_endian
)
4309 /* bt/bf: jump to pc + 2 + (3 << 1). */
4311 /* jmpi: jump to MEM (pc + 2 + (0 << 2)). */
4316 /* bt/bf: jump to pc + 2 + (3 << 1). */
4318 /* jmpi: jump to MEM (pc + 2 + (0 << 2)). */
4327 /* Make reloc for the long disp. */
4328 fix_new (fragp
, fragp
->fr_fix
+ 4, 4,
4329 fragp
->fr_symbol
, fragp
->fr_offset
, 0, BFD_RELOC_32
);
4330 fragp
->fr_fix
+= C32_LEN
;
4332 /* Frag is actually shorter (see the other side of this ifdef)
4333 but gas isn't prepared for that. We have to re-adjust
4334 the branch displacement so that it goes beyond the
4335 full length of the fragment, not just what we actually
4337 if (!target_big_endian
)
4345 case C (COND_JUMP_PIC
, DISP32
):
4346 case C (COND_JUMP_PIC
, UNDEF_WORD_DISP
):
4348 #define BYTE_1(a) (target_big_endian ? ((a) & 0xff) : ((a) >> 8))
4349 #define BYTE_0(a) (target_big_endian ? ((a) >> 8) : ((a) & 0xff))
4360 0: .long (tar_addr - pc)
4363 int first_inst
= fragp
->fr_fix
+ fragp
->fr_address
;
4364 int is_unaligned
= (first_inst
& 3);
4366 /* Toggle T/F bit. */
4367 if (! target_big_endian
)
4371 buf
[2] = BYTE_0 (CSKYV1_INST_SUBI
| (7 << 4)); /* subi r0, 8. */
4372 buf
[3] = BYTE_1 (CSKYV1_INST_SUBI
| (7 << 4));
4373 buf
[4] = BYTE_0 (CSKYV1_INST_STW
| (15 << 8)); /* stw r15, r0. */
4374 buf
[5] = BYTE_1 (CSKYV1_INST_STW
| (15 << 8));
4375 buf
[6] = BYTE_0 (CSKYV1_INST_BSR
); /* bsr pc + 2. */
4376 buf
[7] = BYTE_1 (CSKYV1_INST_BSR
);
4377 buf
[8] = BYTE_0 (CSKYV1_INST_LRW
| (1 << 8)); /* lrw r1, (tar_addr - pc). */
4378 buf
[9] = BYTE_1 (CSKYV1_INST_LRW
| (1 << 8));
4379 buf
[10] = BYTE_0 (CSKYV1_INST_ADDU
| (15 << 4) | 1); /* add r1, r15. */
4380 buf
[11] = BYTE_1 (CSKYV1_INST_ADDU
| (15 << 4) | 1);
4381 buf
[12] = BYTE_0 (CSKYV1_INST_LDW
| (15 << 8)); /* ldw r15, r0. */
4382 buf
[13] = BYTE_1 (CSKYV1_INST_LDW
| (15 << 8));
4383 buf
[14] = BYTE_0 (CSKYV1_INST_ADDI
| (7 << 4)); /* addi r0, 8. */
4384 buf
[15] = BYTE_1 (CSKYV1_INST_ADDI
| (7 << 4));
4385 buf
[16] = BYTE_0 (CSKYV1_INST_JMP
| 1); /* jmp r1. */
4386 buf
[17] = BYTE_1 (CSKYV1_INST_JMP
| 1);
4390 if (!target_big_endian
)
4394 buf
[20] = disp
& 0xff;
4395 buf
[21] = (disp
>> 8) & 0xff;
4396 buf
[22] = (disp
>> 16) & 0xff;
4397 buf
[23] = (disp
>> 24) & 0xff;
4399 else /* if !target_big_endian. */
4403 buf
[20] = (disp
>> 24) & 0xff;
4404 buf
[21] = (disp
>> 16) & 0xff;
4405 buf
[22] = (disp
>> 8) & 0xff;
4406 buf
[23] = disp
& 0xff;
4408 buf
[18] = 0; /* alignment. */
4410 fragp
->fr_fix
+= C32_LEN_PIC
;
4412 else /* if !is_unaligned. */
4414 if (!target_big_endian
)
4418 buf
[18] = disp
& 0xff;
4419 buf
[19] = (disp
>> 8) & 0xff;
4420 buf
[20] = (disp
>> 16) & 0xff;
4421 buf
[21] = (disp
>> 24) & 0xff;
4423 else /* if !target_big_endian. */
4427 buf
[18] = (disp
>> 24) & 0xff;
4428 buf
[19] = (disp
>> 16) & 0xff;
4429 buf
[20] = (disp
>> 8) & 0xff;
4430 buf
[21] = disp
& 0xff;
4432 buf
[22] = 0; /* initialise. */
4434 fragp
->fr_fix
+= C32_LEN_PIC
;
4436 } /* end if is_unaligned. */
4437 } /* end case C (COND_JUMP_PIC, DISP32)/C (COND_JUMP_PIC, UNDEF_WORD_DISP). */
4439 case C (UNCD_JUMP
, DISP32
):
4440 case C (UNCD_JUMP
, UNDEF_WORD_DISP
):
4445 int first_inst
= fragp
->fr_fix
+ fragp
->fr_address
;
4446 int is_unaligned
= (first_inst
& 3);
4448 buf
[0] = BYTE_0 (CSKYV1_INST_JMPI
);
4449 buf
[1] = BYTE_1 (CSKYV1_INST_JMPI
);
4452 if (!target_big_endian
)
4464 fix_new (fragp
, fragp
->fr_fix
+ 4, 4,
4465 fragp
->fr_symbol
, fragp
->fr_offset
, 0, BFD_RELOC_32
);
4466 fragp
->fr_fix
+= U32_LEN
;
4468 else /* if is_unaligned. */
4470 if (!target_big_endian
)
4479 fix_new (fragp
, fragp
->fr_fix
+ 2, 4,
4480 fragp
->fr_symbol
, fragp
->fr_offset
, 0, BFD_RELOC_32
);
4481 fragp
->fr_fix
+= U32_LEN
;
4486 case C (UNCD_JUMP_PIC
, DISP32
):
4487 case C (UNCD_JUMP_PIC
, UNDEF_WORD_DISP
):
4499 0: .long (tar_add - pc)
4502 /* If the b!cond is 4 byte aligned, the literal which would
4503 go at x+4 will also be aligned. */
4504 int first_inst
= fragp
->fr_fix
+ fragp
->fr_address
;
4505 int is_unaligned
= (first_inst
& 3);
4508 buf
[0] = BYTE_0 (CSKYV1_INST_SUBI
| (7 << 4)); /* subi r0, 8. */
4509 buf
[1] = BYTE_1 (CSKYV1_INST_SUBI
| (7 << 4));
4510 buf
[2] = BYTE_0 (CSKYV1_INST_STW
| (15 << 8)); /* stw r15, r0. */
4511 buf
[3] = BYTE_1 (CSKYV1_INST_STW
| (15 << 8));
4512 buf
[4] = BYTE_0 (CSKYV1_INST_BSR
); /* bsr pc + 2. */
4513 buf
[5] = BYTE_1 (CSKYV1_INST_BSR
);
4514 buf
[6] = BYTE_0 (CSKYV1_INST_LRW
| (1 << 8)); /* lrw r1, (tar_addr - pc). */
4515 buf
[7] = BYTE_1 (CSKYV1_INST_LRW
| (1 << 8));
4516 buf
[8] = BYTE_0 (CSKYV1_INST_ADDU
| (15 << 4) | 1); /* add r1, r15. */
4517 buf
[9] = BYTE_1 (CSKYV1_INST_ADDU
| (15 << 4) | 1);
4518 buf
[10] = BYTE_0 (CSKYV1_INST_LDW
| (15 << 8)); /* ldw r15, r0. */
4519 buf
[11] = BYTE_1 (CSKYV1_INST_LDW
| (15 << 8));
4520 buf
[12] = BYTE_0 (CSKYV1_INST_ADDI
| (7 << 4)); /* addi r0, 8. */
4521 buf
[13] = BYTE_1 (CSKYV1_INST_ADDI
| (7 << 4));
4522 buf
[14] = BYTE_0 (CSKYV1_INST_JMP
| 1); /* jmp r1. */
4523 buf
[15] = BYTE_1 (CSKYV1_INST_JMP
| 1);
4527 if (!target_big_endian
)
4530 buf
[18] = disp
& 0xff;
4531 buf
[19] = (disp
>> 8) & 0xff;
4532 buf
[20] = (disp
>> 16) & 0xff;
4533 buf
[21] = (disp
>> 24) & 0xff;
4538 buf
[18] = (disp
>> 24) & 0xff;
4539 buf
[19] = (disp
>> 16) & 0xff;
4540 buf
[20] = (disp
>> 8) & 0xff;
4541 buf
[21] = disp
& 0xff;
4545 fragp
->fr_fix
+= U32_LEN_PIC
;
4549 if (!target_big_endian
)
4552 buf
[16] = disp
& 0xff;
4553 buf
[17] = (disp
>> 8) & 0xff;
4554 buf
[18] = (disp
>> 16) & 0xff;
4555 buf
[19] = (disp
>> 24) & 0xff;
4560 buf
[16] = (disp
>> 24) & 0xff;
4561 buf
[17] = (disp
>> 16) & 0xff;
4562 buf
[18] = (disp
>> 8) & 0xff;
4563 buf
[19] = disp
& 0xff;
4565 fragp
->fr_fix
+= U32_LEN_PIC
;
4575 unsigned int inst
= csky_read_insn (buf
, 2);
4576 inst
|= (disp
>> 1) & ((1 << 10) - 1);
4577 csky_write_insn (buf
, inst
, 2);
4583 unsigned int inst
= csky_read_insn (buf
, 2);
4585 if (inst
== CSKYV2_INST_BT16
)
4586 inst
= CSKYV2_INST_BF16
;
4588 inst
= CSKYV2_INST_BT16
;
4589 make_insn (2, inst
, (2 + 4) >> 1, 10);
4590 if (IS_EXTERNAL_SYM (fragp
->fr_symbol
, asec
))
4591 fix_new (fragp
, fragp
->fr_fix
, 4,
4592 fragp
->fr_symbol
, fragp
->fr_offset
, 1,
4593 BFD_RELOC_CKCORE_PCREL_IMM16BY2
);
4595 inst
= CSKYV2_INST_BR32
| ((disp
>> 1) & ((1 << 16) - 1));
4596 csky_write_insn (buf
, inst
, 4);
4603 unsigned int inst
= csky_read_insn (buf
, 2);
4605 if (inst
== CSKYV2_INST_BT16
)
4606 inst
= CSKYV2_INST_BT32
;
4608 inst
= CSKYV2_INST_BF32
;
4609 if (IS_EXTERNAL_SYM (fragp
->fr_symbol
, asec
))
4610 fix_new (fragp
, fragp
->fr_fix
, 4,
4611 fragp
->fr_symbol
, fragp
->fr_offset
, 1,
4612 BFD_RELOC_CKCORE_PCREL_IMM16BY2
);
4613 inst
|= (disp
>> 1) & ((1 << 16) - 1);
4614 csky_write_insn (buf
, inst
, 4);
4620 unsigned int inst
= csky_read_insn (buf
, 2);
4622 imm
= (disp
+ 2) >> 2;
4623 inst
|= (imm
>> 5) << 8;
4624 make_insn (2, inst
, (imm
& 0x1f), 5);
4629 unsigned int inst
= csky_read_insn (buf
, 2);
4630 int imm
= (disp
+ 2) >> 2;
4634 inst
|= (~((imm
>> 5) << 8)) & 0x300;
4635 make_insn (2, inst
, (~imm
& 0x1f), 5);
4639 inst
|= (imm
>> 5) << 8;
4640 make_insn (2, inst
, (imm
& 0x1f), 5);
4646 unsigned int inst
= csky_read_insn (buf
, 2);
4647 inst
= CSKYV2_INST_LRW32
| (((inst
& 0xe0) >> 5) << 16);
4648 if (IS_EXTERNAL_SYM (fragp
->fr_symbol
, asec
))
4649 fix_new (fragp
, fragp
->fr_fix
, 4,
4650 fragp
->fr_symbol
, fragp
->fr_offset
, 1,
4651 BFD_RELOC_CKCORE_PCREL_IMM16BY4
);
4652 make_insn (4, inst
, ((disp
+ 2) >> 2), 16);
4657 unsigned int inst
= csky_read_insn (buf
, 4);
4658 make_insn (4, inst
, disp
>> 1, 16);
4663 unsigned int inst
= csky_read_insn (buf
, 4);
4665 make_insn (4, opposite_of_stored_compz (inst
),
4666 (4 + 4 + PAD_LITERAL_LENGTH
) >> 1, 16);
4667 literal_offset
= ((fragp
->fr_address
+ fragp
->fr_fix
) % 4 == 0
4669 make_insn (4, CSKYV2_INST_JMPI32
, (4 + literal_offset
+ 2) >> 2, 10);
4670 make_literal (fragp
, literal_offset
);
4676 if (IS_EXTERNAL_SYM (fragp
->fr_symbol
, asec
))
4677 fix_new (fragp
, fragp
->fr_fix
, 4,
4678 fragp
->fr_symbol
, fragp
->fr_offset
, 1,
4679 BFD_RELOC_CKCORE_PCREL_IMM16BY2
);
4680 make_insn (4, CSKYV2_INST_BR32
, disp
>> 1, 16);
4685 /* 'jbt'/'jbf'-> <bf16/bt16>; jmpi32; [pad16]+literal32 */
4686 unsigned int inst
= csky_read_insn (buf
, 2);
4689 if (inst
== CSKYV2_INST_BT16
)
4690 inst
= CSKYV2_INST_BF16
;
4692 inst
= CSKYV2_INST_BT16
;
4693 make_insn (2, inst
, (2 + 4 + PAD_LITERAL_LENGTH
) >> 1, 10);
4694 literal_offset
= ((fragp
->fr_address
+ fragp
->fr_fix
) % 4 == 0
4696 make_insn (4, CSKYV2_INST_JMPI32
, (4 + literal_offset
+ 2) >> 2, 10);
4697 make_literal (fragp
, literal_offset
);
4703 literal_offset
= ((fragp
->fr_address
+ fragp
->fr_fix
) % 4 == 0
4705 make_insn (4, CSKYV2_INST_JMPI32
, (4 + literal_offset
+ 2) >> 2, 10);
4706 make_literal (fragp
, literal_offset
);
4709 case RELAX_OVERFLOW
:
4710 csky_branch_report_error (fragp
->fr_file
, fragp
->fr_line
,
4711 fragp
->fr_symbol
, disp
);
4719 /* Round up a section size to the appropriate boundary. */
4722 md_section_align (segT segment ATTRIBUTE_UNUSED
,
4728 /* MD interface: Symbol and relocation handling. */
4730 void md_csky_end (void)
4735 /* Return the address within the segment that a PC-relative fixup is
4739 md_pcrel_from_section (fixS
* fixP
, segT seg
)
4741 /* If the symbol is undefined or defined in another section
4742 we leave the add number alone for the linker to fix it later. */
4743 if (fixP
->fx_addsy
!= (symbolS
*) NULL
4744 && (! S_IS_DEFINED (fixP
->fx_addsy
)
4745 || S_GET_SEGMENT (fixP
->fx_addsy
) != seg
))
4746 return fixP
->fx_size
;
4748 /* The case where we are going to resolve things. */
4749 return fixP
->fx_size
+ fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
4752 /* csky_cons_fix_new is called via the expression parsing code when a
4753 reloc is needed. We use this hook to get the correct .got reloc. */
4756 csky_cons_fix_new (fragS
*frag
,
4760 bfd_reloc_code_real_type reloc
)
4764 if (BFD_RELOC_CKCORE_GOTOFF
== insn_reloc
4765 || BFD_RELOC_CKCORE_GOTPC
== insn_reloc
4766 || BFD_RELOC_CKCORE_GOT32
== insn_reloc
4767 || BFD_RELOC_CKCORE_PLT32
== insn_reloc
4768 || BFD_RELOC_CKCORE_TLS_LE32
== insn_reloc
4769 || BFD_RELOC_CKCORE_TLS_GD32
== insn_reloc
4770 || BFD_RELOC_CKCORE_TLS_LDM32
== insn_reloc
4771 || BFD_RELOC_CKCORE_TLS_LDO32
== insn_reloc
4772 || BFD_RELOC_CKCORE_TLS_IE32
== insn_reloc
)
4778 reloc
= BFD_RELOC_8
;
4781 reloc
= BFD_RELOC_16
;
4784 reloc
= BFD_RELOC_32
;
4787 reloc
= BFD_RELOC_64
;
4790 as_bad (_("unsupported BFD relocation size %d"), len
);
4791 reloc
= BFD_RELOC_32
;
4794 fixP
= fix_new_exp (frag
, off
, (int) len
, exp
, 0, reloc
);
4795 if (BFD_RELOC_CKCORE_TLS_IE32
== insn_reloc
4796 || BFD_RELOC_CKCORE_TLS_GD32
== insn_reloc
4797 || BFD_RELOC_CKCORE_TLS_LDM32
== insn_reloc
)
4799 fixP
->tc_fix_data
.frag
= literal_insn_offset
->tls_addend
.frag
;
4800 fixP
->tc_fix_data
.offset
= literal_insn_offset
->tls_addend
.offset
;
4804 /* See whether we need to force a relocation into the output file.
4805 This is used to force out switch and PC relative relocations when
4809 csky_force_relocation (fixS
* fix
)
4811 if (fix
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
4812 || fix
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
4813 || fix
->fx_r_type
== BFD_RELOC_RVA
4814 || fix
->fx_r_type
== BFD_RELOC_CKCORE_ADDR_HI16
4815 || fix
->fx_r_type
== BFD_RELOC_CKCORE_ADDR_LO16
4816 || fix
->fx_r_type
== BFD_RELOC_CKCORE_TOFFSET_LO16
4817 || fix
->fx_r_type
== BFD_RELOC_CKCORE_DOFFSET_LO16
)
4820 if (fix
->fx_addsy
== NULL
)
4823 if (do_use_branchstub
4824 && fix
->fx_r_type
== BFD_RELOC_CKCORE_PCREL_IMM26BY2
4825 && (symbol_get_bfdsym (fix
->fx_addsy
)->flags
& BSF_FUNCTION
))
4827 return S_FORCE_RELOC (fix
->fx_addsy
, fix
->fx_subsy
== NULL
);
4830 /* Return true if the fix can be handled by GAS, false if it must
4831 be passed through to the linker. */
4834 csky_fix_adjustable (fixS
* fixP
)
4836 if (fixP
->fx_addsy
== NULL
)
4839 /* We need the symbol name for the VTABLE entries. */
4840 if (fixP
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
4841 || fixP
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
4842 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_PLT32
4843 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_GOT32
4844 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_PLT12
4845 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_GOT12
4846 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_GOT_HI16
4847 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_GOT_LO16
4848 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_PLT_HI16
4849 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_PLT_LO16
4850 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_GOTOFF
4851 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_GOTOFF_HI16
4852 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_GOTOFF_LO16
4853 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_ADDR_HI16
4854 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_ADDR_LO16
4855 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_GOT_IMM18BY4
4856 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_PLT_IMM18BY4
4857 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_GOTOFF_IMM18
4858 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_TLS_LE32
4859 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_TLS_IE32
4860 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_TLS_GD32
4861 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_TLS_LDM32
4862 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_TLS_LDO32
)
4865 if (do_use_branchstub
4866 && fixP
->fx_r_type
== BFD_RELOC_CKCORE_PCREL_IMM26BY2
4867 && (symbol_get_bfdsym (fixP
->fx_addsy
)->flags
& BSF_FUNCTION
))
4874 md_apply_fix (fixS
*fixP
,
4878 reloc_howto_type
*howto
;
4879 /* Note: use offsetT because it is signed, valueT is unsigned. */
4880 offsetT val
= *valP
;
4881 char *buf
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
4883 /* if fx_done = 0, fixup will also be processed in
4884 * tc_gen_reloc() after md_apply_fix(). */
4887 /* If the fix is relative to a symbol which is not defined, or not
4888 in the same segment as the fix, we cannot resolve it here. */
4889 if (IS_CSKY_V1 (mach_flag
) && fixP
->fx_addsy
!= NULL
4890 && (! S_IS_DEFINED (fixP
->fx_addsy
)
4891 || S_GET_SEGMENT (fixP
->fx_addsy
) != seg
))
4893 switch (fixP
->fx_r_type
)
4895 /* Data fx_addnumber is greater than 16 bits,
4896 so fx_addnumber is assigned zero. */
4897 case BFD_RELOC_CKCORE_PCREL_JSR_IMM11BY2
:
4900 case BFD_RELOC_CKCORE_TLS_IE32
:
4901 case BFD_RELOC_CKCORE_TLS_LDM32
:
4902 case BFD_RELOC_CKCORE_TLS_GD32
:
4904 struct tls_addend
*ta
= &(fixP
->tc_fix_data
);
4905 fixP
->fx_offset
= (fixP
->fx_frag
->fr_address
+ fixP
->fx_where
4906 - (ta
->frag
->fr_address
+ ta
->offset
));
4909 case BFD_RELOC_CKCORE_TLS_LE32
:
4910 case BFD_RELOC_CKCORE_TLS_LDO32
:
4911 S_SET_THREAD_LOCAL (fixP
->fx_addsy
);
4917 /* For ELF we can just return and let the reloc that will be generated
4918 take care of everything. For COFF we still have to insert 'val'
4919 into the insn since the addend field will be ignored. */
4924 /* We can handle these relocs. */
4925 switch (fixP
->fx_r_type
)
4927 case BFD_RELOC_32_PCREL
:
4928 case BFD_RELOC_CKCORE_PCREL32
:
4929 fixP
->fx_r_type
= BFD_RELOC_CKCORE_PCREL32
;
4931 case BFD_RELOC_VTABLE_INHERIT
:
4932 fixP
->fx_r_type
= BFD_RELOC_CKCORE_GNU_VTINHERIT
;
4933 if (fixP
->fx_addsy
&& !S_IS_DEFINED (fixP
->fx_addsy
)
4934 && !S_IS_WEAK (fixP
->fx_addsy
))
4935 S_SET_WEAK (fixP
->fx_addsy
);
4937 case BFD_RELOC_VTABLE_ENTRY
:
4938 fixP
->fx_r_type
= BFD_RELOC_CKCORE_GNU_VTENTRY
;
4940 case BFD_RELOC_CKCORE_GOT12
:
4941 case BFD_RELOC_CKCORE_PLT12
:
4942 case BFD_RELOC_CKCORE_ADDR_HI16
:
4943 case BFD_RELOC_CKCORE_ADDR_LO16
:
4944 case BFD_RELOC_CKCORE_TOFFSET_LO16
:
4945 case BFD_RELOC_CKCORE_DOFFSET_LO16
:
4946 case BFD_RELOC_CKCORE_GOT_HI16
:
4947 case BFD_RELOC_CKCORE_GOT_LO16
:
4948 case BFD_RELOC_CKCORE_PLT_HI16
:
4949 case BFD_RELOC_CKCORE_PLT_LO16
:
4950 case BFD_RELOC_CKCORE_GOTPC_HI16
:
4951 case BFD_RELOC_CKCORE_GOTPC_LO16
:
4952 case BFD_RELOC_CKCORE_GOTOFF_HI16
:
4953 case BFD_RELOC_CKCORE_GOTOFF_LO16
:
4954 case BFD_RELOC_CKCORE_DOFFSET_IMM18
:
4955 case BFD_RELOC_CKCORE_DOFFSET_IMM18BY2
:
4956 case BFD_RELOC_CKCORE_DOFFSET_IMM18BY4
:
4957 case BFD_RELOC_CKCORE_GOTOFF_IMM18
:
4958 case BFD_RELOC_CKCORE_GOT_IMM18BY4
:
4959 case BFD_RELOC_CKCORE_PLT_IMM18BY4
:
4961 case BFD_RELOC_CKCORE_TLS_IE32
:
4962 case BFD_RELOC_CKCORE_TLS_LDM32
:
4963 case BFD_RELOC_CKCORE_TLS_GD32
:
4965 struct tls_addend
*ta
= &(fixP
->tc_fix_data
);
4966 fixP
->fx_offset
= (fixP
->fx_frag
->fr_address
+ fixP
->fx_where
4967 - (ta
->frag
->fr_address
+ ta
->offset
));
4970 case BFD_RELOC_CKCORE_TLS_LE32
:
4971 case BFD_RELOC_CKCORE_TLS_LDO32
:
4972 S_SET_THREAD_LOCAL (fixP
->fx_addsy
);
4975 fixP
->fx_r_type
= BFD_RELOC_CKCORE_ADDR32
;
4979 if (fixP
->fx_addsy
== NULL
)
4981 if (fixP
->fx_size
== 4)
4983 else if (fixP
->fx_size
== 2 && val
>= -32768 && val
<= 32767)
4985 else if (fixP
->fx_size
== 1 && val
>= -256 && val
<= 255)
4989 md_number_to_chars (buf
, val
, fixP
->fx_size
);
4993 case BFD_RELOC_CKCORE_PCREL_JSR_IMM11BY2
:
4994 if (fixP
->fx_addsy
== 0 && val
> -2 KB
&& val
< 2 KB
)
4996 long nval
= (val
>> 1) & 0x7ff;
4997 nval
|= CSKYV1_INST_BSR
;
4998 csky_write_insn (buf
, nval
, 2);
5004 case BFD_RELOC_CKCORE_PCREL_JSR_IMM26BY2
:
5005 if (fixP
->fx_addsy
== 0)
5007 if (val
>= -(1 << 26) && val
< (1 << 26))
5009 unsigned int nval
= ((val
+ fixP
->fx_size
) >> 1) & 0x3ffffff;
5010 nval
|= CSKYV2_INST_BSR32
;
5012 csky_write_insn (buf
, nval
, 4);
5014 /* If bsr32 cannot reach,
5015 generate 'lrw r25,label;jsr r25' instead of 'jsri label'. */
5016 else if (IS_CSKY_ARCH_810 (mach_flag
))
5018 howto
= bfd_reloc_type_lookup (stdoutput
, fixP
->fx_r_type
);
5019 valueT opcode
= csky_read_insn (buf
, 4);
5020 opcode
= (opcode
& howto
->dst_mask
) | CSKYV2_INST_JSRI_TO_LRW
;
5021 csky_write_insn (buf
, opcode
, 4);
5022 opcode
= CSKYV2_INST_JSR_R26
;
5023 csky_write_insn (buf
+ 4, opcode
, 4);
5033 unsigned int issigned
= 0;
5038 howto
= bfd_reloc_type_lookup (stdoutput
, fixP
->fx_r_type
);
5041 if (fixP
->fx_size
== 4
5042 || (fixP
->fx_size
== 2 && val
>= -32768 && val
<= 32767)
5043 || (fixP
->fx_size
== 1 && val
>= -256 && val
<= 255))
5045 md_number_to_chars (buf
, val
, fixP
->fx_size
);
5053 if (IS_CSKY_V2 (mach_flag
))
5054 val
+= fixP
->fx_size
;
5056 if (howto
->rightshift
== 2)
5059 val
>>= howto
->rightshift
;
5061 switch (fixP
->fx_r_type
)
5063 /* Offset is unsigned. */
5064 case BFD_RELOC_CKCORE_PCREL_IMM8BY4
:
5065 case BFD_RELOC_CKCORE_PCREL_IMM10BY4
:
5066 case BFD_RELOC_CKCORE_PCREL_IMM16BY4
:
5067 max
= (offsetT
) howto
->dst_mask
;
5071 case BFD_RELOC_CKCORE_PCREL_IMM7BY4
:
5073 max
= (offsetT
)((1 << (howto
->bitsize
+ 1)) - 2);
5075 max
= (offsetT
)((1 << howto
->bitsize
) - 1);
5078 /* flrws, flrwd: the offset bits are divided in two parts. */
5079 case BFD_RELOC_CKCORE_PCREL_FLRW_IMM8BY4
:
5080 max
= (offsetT
)((1 << howto
->bitsize
) - 1);
5083 /* Offset is signed. */
5085 max
= (offsetT
)(howto
->dst_mask
>> 1);
5089 if (val
< min
|| val
> max
)
5091 csky_branch_report_error (fixP
->fx_file
, fixP
->fx_line
,
5092 fixP
->fx_addsy
, val
);
5095 opcode
= csky_read_insn (buf
, fixP
->fx_size
);
5096 /* Clear redundant bits brought from the last
5097 operation if there is any. */
5098 if (do_extend_lrw
&& (opcode
& 0xfc00) == CSKYV2_INST_LRW16
)
5101 val
&= issigned
? (offsetT
)(howto
->dst_mask
) : max
;
5103 if (fixP
->fx_r_type
== BFD_RELOC_CKCORE_PCREL_BLOOP_IMM4BY4
)
5104 val
= (val
& 0xf) << 12;
5106 if (fixP
->fx_size
== 2 && (opcode
& 0xfc00) == CSKYV2_INST_LRW16
)
5108 /* 8 bit offset lrw16. */
5110 csky_write_insn (buf
,
5112 | ((~val
& 0x60) << 3) | (opcode
& 0xe0)),
5114 /* 7 bit offset lrw16. */
5116 csky_write_insn (buf
,
5117 (val
& 0x1f) | ((val
& 0x60) << 3) | opcode
,
5120 else if (fixP
->fx_size
== 4
5121 && (opcode
& 0xfe1ffe00) == CSKYV2_INST_FLRW
)
5122 csky_write_insn (buf
,
5123 ((val
& 0xf) << 4) | ((val
& 0xf0) << 17) | opcode
,
5126 csky_write_insn (buf
, val
| opcode
, fixP
->fx_size
);
5131 fixP
->fx_addnumber
= val
;
5134 /* Translate internal representation of relocation info to BFD target
5138 tc_gen_reloc (asection
*section ATTRIBUTE_UNUSED
, fixS
*fixP
)
5143 && fixP
->fx_r_type
== BFD_RELOC_CKCORE_ADDR32
)
5144 fixP
->fx_r_type
= BFD_RELOC_CKCORE_PCREL32
;
5146 rel
= xmalloc (sizeof (arelent
));
5147 rel
->sym_ptr_ptr
= xmalloc (sizeof (asymbol
*));
5148 *rel
->sym_ptr_ptr
= symbol_get_bfdsym (fixP
->fx_addsy
);
5149 rel
->howto
= bfd_reloc_type_lookup (stdoutput
, fixP
->fx_r_type
);
5150 rel
->addend
= fixP
->fx_offset
;
5151 if (rel
->howto
== NULL
)
5153 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5154 _("cannot represent `%s' relocation in object file"),
5155 bfd_get_reloc_code_name (fixP
->fx_r_type
));
5157 /* Set howto to a garbage value so that we can keep going. */
5158 rel
->howto
= bfd_reloc_type_lookup (stdoutput
, BFD_RELOC_32
);
5160 gas_assert (rel
->howto
!= NULL
);
5161 rel
->address
= fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
5165 /* Relax a fragment by scanning TC_GENERIC_RELAX_TABLE. */
5168 csky_relax_frag (segT segment
, fragS
*fragP
, long stretch
)
5170 const relax_typeS
*this_type
;
5171 const relax_typeS
*start_type
;
5172 relax_substateT next_state
;
5173 relax_substateT this_state
;
5179 const relax_typeS
*table
;
5181 target
= fragP
->fr_offset
;
5182 address
= fragP
->fr_address
;
5183 table
= TC_GENERIC_RELAX_TABLE
;
5184 this_state
= fragP
->fr_subtype
;
5185 start_type
= this_type
= table
+ this_state
;
5186 symbolP
= fragP
->fr_symbol
;
5192 sym_frag
= symbol_get_frag (symbolP
);
5194 #ifndef DIFF_EXPR_OK
5195 know (sym_frag
!= NULL
);
5197 know (S_GET_SEGMENT (symbolP
) != absolute_section
5198 || sym_frag
== &zero_address_frag
);
5199 target
+= S_GET_VALUE (symbolP
);
5201 /* If SYM_FRAG has yet to be reached on this pass, assume it
5202 will move by STRETCH just as we did, unless there is an
5203 alignment frag between here and SYM_FRAG. An alignment may
5204 well absorb any STRETCH, and we don't want to choose a larger
5205 branch insn by overestimating the needed reach of this
5206 branch. It isn't critical to calculate TARGET exactly; We
5207 know we'll be doing another pass if STRETCH is non-zero. */
5210 && sym_frag
->relax_marker
!= fragP
->relax_marker
5211 && S_GET_SEGMENT (symbolP
) == segment
)
5215 /* Adjust stretch for any alignment frag. Note that if have
5216 been expanding the earlier code, the symbol may be
5217 defined in what appears to be an earlier frag. FIXME:
5218 This doesn't handle the fr_subtype field, which specifies
5219 a maximum number of bytes to skip when doing an
5221 for (f
= fragP
; f
!= NULL
&& f
!= sym_frag
; f
= f
->fr_next
)
5223 if (f
->fr_type
== rs_align
|| f
->fr_type
== rs_align_code
)
5226 stretch
= -((-stretch
)
5227 & ~((1 << (int) f
->fr_offset
) - 1));
5229 stretch
&= ~((1 << (int) f
->fr_offset
) - 1);
5239 aim
= target
- address
- fragP
->fr_fix
;
5241 /* If the fragP->fr_symbol is extern symbol, aim should be 0. */
5242 if (fragP
->fr_symbol
&& S_GET_SEGMENT (symbolP
) != segment
)
5247 /* Look backwards. */
5248 for (next_state
= this_type
->rlx_more
; next_state
;)
5249 if (aim
>= this_type
->rlx_backward
)
5253 /* Grow to next state. */
5254 this_state
= next_state
;
5255 this_type
= table
+ this_state
;
5256 next_state
= this_type
->rlx_more
;
5261 /* Look forwards. */
5262 for (next_state
= this_type
->rlx_more
; next_state
;)
5263 if (aim
<= this_type
->rlx_forward
)
5267 /* Grow to next state. */
5268 this_state
= next_state
;
5269 this_type
= table
+ this_state
;
5270 next_state
= this_type
->rlx_more
;
5274 growth
= this_type
->rlx_length
- start_type
->rlx_length
;
5276 fragP
->fr_subtype
= this_state
;
5281 md_estimate_size_before_relax (fragS
* fragp
,
5284 switch (fragp
->fr_subtype
)
5304 gas_assert (fragp
->fr_symbol
);
5305 if (IS_EXTERNAL_SYM (fragp
->fr_symbol
, segtype
))
5306 while (csky_relax_table
[fragp
->fr_subtype
].rlx_more
> RELAX_OVERFLOW
)
5307 fragp
->fr_subtype
= csky_relax_table
[fragp
->fr_subtype
].rlx_more
;
5308 return csky_relax_table
[fragp
->fr_subtype
].rlx_length
;
5310 /* C-SKY V1 relaxes. */
5311 case C (UNCD_JUMP
, UNDEF_DISP
):
5312 case C (UNCD_JUMP_PIC
, UNDEF_DISP
):
5313 if (!fragp
->fr_symbol
)
5314 fragp
->fr_subtype
= C (UNCD_JUMP_S
, DISP12
);
5315 else if (S_GET_SEGMENT (fragp
->fr_symbol
) == segtype
)
5316 fragp
->fr_subtype
= C (UNCD_JUMP_S
, DISP12
);
5318 fragp
->fr_subtype
= C (UNCD_JUMP_S
, UNDEF_WORD_DISP
);
5321 case C (COND_JUMP
, UNDEF_DISP
):
5322 case C (COND_JUMP_PIC
, UNDEF_DISP
):
5323 if (fragp
->fr_symbol
5324 && S_GET_SEGMENT (fragp
->fr_symbol
) == segtype
)
5325 /* Got a symbol and it's defined in this segment, become byte
5326 sized. Maybe it will fix up. */
5327 fragp
->fr_subtype
= C (COND_JUMP_S
, DISP12
);
5328 else if (fragp
->fr_symbol
)
5329 /* It's got a segment, but it's not ours, so it will always be
5331 fragp
->fr_subtype
= C (COND_JUMP_S
, UNDEF_WORD_DISP
);
5333 /* We know the abs value. */
5334 fragp
->fr_subtype
= C (COND_JUMP_S
, DISP12
);
5337 case C (UNCD_JUMP
, DISP12
):
5338 case C (UNCD_JUMP
, DISP32
):
5339 case C (UNCD_JUMP
, UNDEF_WORD_DISP
):
5340 case C (COND_JUMP
, DISP12
):
5341 case C (COND_JUMP
, DISP32
):
5342 case C (COND_JUMP
, UNDEF_WORD_DISP
):
5343 case C (UNCD_JUMP_PIC
, DISP12
):
5344 case C (UNCD_JUMP_PIC
, DISP32
):
5345 case C (UNCD_JUMP_PIC
, UNDEF_WORD_DISP
):
5346 case C (COND_JUMP_PIC
, DISP12
):
5347 case C (COND_JUMP_PIC
, DISP32
):
5348 case C (COND_JUMP_PIC
, UNDEF_WORD_DISP
):
5349 case RELAX_OVERFLOW
:
5355 return csky_relax_table
[fragp
->fr_subtype
].rlx_length
;
5358 /* Parse opcode like: "op oprnd1, oprnd2, oprnd3". */
5361 csky_macro_md_assemble (const char *op
,
5372 strcat (str
, oprnd1
);
5376 strcat (str
, oprnd2
);
5380 strcat (str
, oprnd3
);
5388 /* Get the string of operand. */
5391 csky_get_macro_operand (char *src_s
, char *dst_s
, char end_sym
)
5394 while (ISSPACE (*src_s
))
5396 while (*src_s
!= end_sym
)
5397 dst_s
[nlen
++] = *(src_s
++);
5402 /* idly 4 -> idly4. */
5407 char *s
= csky_insn
.opcode_end
;
5408 if (!is_imm_over_range (&s
, 4, 4, -1))
5410 as_bad (_("second operand must be 4"));
5413 csky_macro_md_assemble ("idly4", NULL
, NULL
, NULL
);
5417 /* rolc rd, 1 or roltc rd, 1 -> addc rd, rd. */
5423 char *s
= csky_insn
.opcode_end
;
5425 s
+= csky_get_macro_operand (s
, reg
, ',');
5428 if (is_imm_over_range (&s
, 1, 1, -1))
5430 csky_macro_md_assemble ("addc", reg
, reg
, NULL
);
5434 as_bad (_("second operand must be 1"));
5437 /* sxtrb0(1)(2) r1, rx -> xtbr0(1)(2) r1,rx; sextb r1. */
5445 char *s
= csky_insn
.opcode_end
;
5446 s
+= csky_get_macro_operand (s
, reg1
, ',');
5448 csky_get_macro_operand (s
, reg2
, '\0');
5450 csky_macro_md_assemble (csky_insn
.macro
->name
+ 1, reg1
, reg2
, NULL
);
5451 csky_macro_md_assemble ("sextb", reg1
, NULL
, NULL
);
5462 char *s
= csky_insn
.opcode_end
;
5463 s
+= csky_get_macro_operand (s
, reg1
, ',');
5466 s
+= csky_get_macro_operand (s
, reg2
, ',');
5469 s
+= csky_get_macro_operand (s
, reg3
, '\0');
5471 csky_macro_md_assemble ("movt", reg1
, reg2
, NULL
);
5472 csky_macro_md_assemble ("movf", reg1
, reg3
, NULL
);
5477 get_macro_reg_vals (int *reg1
, int *reg2
, int *reg3
)
5480 char *s
= csky_insn
.opcode_end
;
5482 *reg1
= csky_get_reg_val (s
, &nlen
);
5486 csky_show_error (ERROR_MISSING_COMMA
, 0, NULL
, NULL
);
5490 *reg2
= csky_get_reg_val (s
, &nlen
);
5494 csky_show_error (ERROR_MISSING_COMMA
, 0, NULL
, NULL
);
5498 *reg3
= csky_get_reg_val (s
, &nlen
);
5502 csky_show_error (ERROR_BAD_END
, 0, s
, NULL
);
5505 if (*reg1
== -1 || *reg2
== -1 || *reg3
== -1)
5507 as_bad (_("register number out of range"));
5512 as_bad (_("dest and source1 must be the same register"));
5515 if (*reg1
>= 15 || *reg3
>= 15)
5517 as_bad (_("64-bit operator src/dst register must be less than 15"));
5523 /* addc64 rx, rx, ry -> cmplt rx, rx, addc rx, ry, addc rx+1, ry+1. */
5532 if (!get_macro_reg_vals (®1
, ®2
, ®3
))
5534 csky_macro_md_assemble ("cmplt",
5535 csky_general_reg
[reg1
],
5536 csky_general_reg
[reg1
],
5538 csky_macro_md_assemble ("addc",
5539 csky_general_reg
[reg1
+ (target_big_endian
? 1 : 0)],
5540 csky_general_reg
[reg3
+ (target_big_endian
? 1 : 0)],
5542 csky_macro_md_assemble ("addc",
5543 csky_general_reg
[reg1
+ (target_big_endian
? 0 : 1)],
5544 csky_general_reg
[reg3
+ (target_big_endian
? 0 : 1)],
5549 /* subc64 rx, rx, ry -> cmphs rx, rx, subc rx, ry, subc rx+1, ry+1. */
5558 if (!get_macro_reg_vals (®1
, ®2
, ®3
))
5560 csky_macro_md_assemble ("cmphs",
5561 csky_general_reg
[reg1
],
5562 csky_general_reg
[reg1
],
5564 csky_macro_md_assemble ("subc",
5565 csky_general_reg
[reg1
+ (target_big_endian
? 1 : 0)],
5566 csky_general_reg
[reg3
+ (target_big_endian
? 1 : 0)],
5568 csky_macro_md_assemble ("subc",
5569 csky_general_reg
[reg1
+ (target_big_endian
? 0 : 1)],
5570 csky_general_reg
[reg3
+ (target_big_endian
? 0 : 1)],
5575 /* or64 rx, rx, ry -> or rx, ry, or rx+1, ry+1. */
5584 if (!get_macro_reg_vals (®1
, ®2
, ®3
))
5586 csky_macro_md_assemble ("or",
5587 csky_general_reg
[reg1
+ (target_big_endian
? 1 : 0)],
5588 csky_general_reg
[reg3
+ (target_big_endian
? 1 : 0)],
5590 csky_macro_md_assemble ("or",
5591 csky_general_reg
[reg1
+ (target_big_endian
? 0 : 1)],
5592 csky_general_reg
[reg3
+ (target_big_endian
? 0 : 1)],
5597 /* xor64 rx, rx, ry -> xor rx, ry, xor rx+1, ry+1. */
5606 if (!get_macro_reg_vals (®1
, ®2
, ®3
))
5608 csky_macro_md_assemble ("xor",
5609 csky_general_reg
[reg1
+ (target_big_endian
? 1 : 0)],
5610 csky_general_reg
[reg3
+ (target_big_endian
? 1 : 0)],
5612 csky_macro_md_assemble ("xor",
5613 csky_general_reg
[reg1
+ (target_big_endian
? 0 : 1)],
5614 csky_general_reg
[reg3
+ (target_big_endian
? 0 : 1)],
5619 /* The following are V2 macro instructions. */
5621 /* neg rd -> not rd, rd; addi rd, 1. */
5628 char *s
= csky_insn
.opcode_end
;
5629 s
+= csky_get_macro_operand (s
, reg1
, '\0');
5632 csky_macro_md_assemble ("not", reg1
, reg1
, NULL
);
5633 csky_macro_md_assemble ("addi", reg1
, "1", NULL
);
5637 /* rsubi rd, imm16 -> not rd; addi rd, imm16 + 1 */
5644 unsigned int imm16
= 0;
5646 char *s
= csky_insn
.opcode_end
;
5647 s
+= csky_get_macro_operand (s
, reg1
, ',');
5650 s
= parse_exp (s
, &e
);
5651 if (e
.X_op
== O_constant
)
5652 imm16
= e
.X_add_number
;
5654 csky_show_error (ERROR_IMM_ILLEGAL
, 2, NULL
, NULL
);
5656 sprintf (str_imm16
, "%d", imm16
+ 1);
5658 csky_macro_md_assemble ("not", reg1
, reg1
, NULL
);
5659 csky_macro_md_assemble ("addi", reg1
, str_imm16
, NULL
);
5663 /* Such as: asrc rd -> asrc rd, rd, 1. */
5669 char *s
= csky_insn
.opcode_end
;
5670 s
+= csky_get_macro_operand (s
, reg1
, '\0');
5672 csky_macro_md_assemble (csky_insn
.macro
->name
, reg1
, reg1
, "1");
5676 /* decne rd -> if ck802: subi rd, 1; cmpnei rd, 0.
5677 else: decne rd, rd, 1 */
5683 char *s
= csky_insn
.opcode_end
;
5684 s
+= csky_get_macro_operand (s
, reg1
, '\0');
5686 if (IS_CSKY_ARCH_802 (mach_flag
))
5688 csky_macro_md_assemble ("subi", reg1
, "1", NULL
);
5689 csky_macro_md_assemble ("cmpnei", reg1
, "0", NULL
);
5692 csky_macro_md_assemble ("decne", reg1
, reg1
, "1");
5696 /* If -mnolrw, lrw rd, imm -> movih rd, imm_hi16; ori rd, imm_lo16. */
5706 char *s
= csky_insn
.opcode_end
;
5707 s
+= csky_get_macro_operand (s
, reg1
, ',');
5709 s
+= csky_get_macro_operand (s
, imm
, '\0');
5713 strcat (imm_hi16
, "(");
5714 strcat (imm_hi16
, imm
);
5715 strcat (imm_hi16
, ") >> 16");
5717 strcat (imm_lo16
, "(");
5718 strcat (imm_lo16
, imm
);
5719 strcat (imm_lo16
, ") & 0xffff");
5721 csky_macro_md_assemble ("movih", reg1
, imm_hi16
, NULL
);
5722 csky_macro_md_assemble ("ori", reg1
, reg1
, imm_lo16
);
5727 /* The following are worker functions for C-SKY v1. */
5733 int output_literal
= csky_insn
.val
[1];
5735 reg
= csky_insn
.val
[0];
5736 csky_insn
.isize
= 2;
5737 csky_insn
.output
= frag_more (2);
5738 if (csky_insn
.e1
.X_op
== O_constant
5739 && csky_insn
.e1
.X_add_number
<= 0x7f
5740 && csky_insn
.e1
.X_add_number
>= 0)
5742 csky_insn
.inst
= 0x6000 | reg
| (csky_insn
.e1
.X_add_number
<< 4);
5745 csky_insn
.inst
= csky_insn
.opcode
->op16
[0].opcode
;
5746 csky_insn
.inst
|= reg
<< 8;
5749 int n
= enter_literal (&csky_insn
.e1
, 0, 0, 0);
5751 /* Create a reference to pool entry. */
5752 csky_insn
.e1
.X_op
= O_symbol
;
5753 csky_insn
.e1
.X_add_symbol
= poolsym
;
5754 csky_insn
.e1
.X_add_number
= n
<< 2;
5757 if (insn_reloc
== BFD_RELOC_CKCORE_TLS_GD32
5758 || insn_reloc
== BFD_RELOC_CKCORE_TLS_LDM32
5759 || insn_reloc
== BFD_RELOC_CKCORE_TLS_IE32
)
5761 literal_insn_offset
->tls_addend
.frag
= frag_now
;
5762 literal_insn_offset
->tls_addend
.offset
5764 - literal_insn_offset
->tls_addend
.frag
->fr_literal
);
5766 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
, 2,
5767 &csky_insn
.e1
, 1, BFD_RELOC_CKCORE_PCREL_IMM8BY4
);
5769 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
5775 v1_work_fpu_fo (void)
5781 struct csky_opcode_info
*opinfo
= NULL
;
5783 if (csky_insn
.isize
== 4)
5784 opinfo
= &csky_insn
.opcode
->op32
[csky_insn
.opcode_idx
];
5785 else if (csky_insn
.isize
== 2)
5786 opinfo
= &csky_insn
.opcode
->op16
[csky_insn
.opcode_idx
];
5788 /* Firstly, get general reg. */
5789 for (i
= 0;i
< opinfo
->operand_num
; i
++)
5790 if (opinfo
->oprnd
.oprnds
[i
].type
== OPRND_TYPE_GREG0_15
)
5791 greg
= csky_insn
.val
[i
];
5792 gas_assert (greg
!= -1);
5794 /* Secondly, get float inst. */
5795 csky_generate_insn ();
5796 inst
= csky_insn
.inst
;
5798 /* Now get greg and inst, we can write instruction to floating unit. */
5799 sprintf (buff
, "lrw %s,0x%x", csky_general_reg
[greg
], inst
);
5801 sprintf (buff
, "cpwir %s", csky_general_reg
[greg
]);
5808 v1_work_fpu_fo_fc (void)
5814 struct csky_opcode_info
*opinfo
= NULL
;
5816 if (csky_insn
.isize
== 4)
5817 opinfo
= &csky_insn
.opcode
->op32
[csky_insn
.opcode_idx
];
5818 else if (csky_insn
.isize
== 2)
5819 opinfo
= &csky_insn
.opcode
->op16
[csky_insn
.opcode_idx
];
5821 /* Firstly, get general reg. */
5822 for (i
= 0;i
< opinfo
->operand_num
; i
++)
5823 if (opinfo
->oprnd
.oprnds
[i
].type
== OPRND_TYPE_GREG0_15
)
5824 greg
= csky_insn
.val
[i
];
5825 gas_assert (greg
!= -1);
5827 /* Secondly, get float inst. */
5828 csky_generate_insn ();
5829 inst
= csky_insn
.inst
;
5831 /* Now get greg and inst, we can write instruction to floating unit. */
5832 sprintf (buff
, "lrw %s,0x%x", csky_general_reg
[greg
], inst
);
5834 sprintf (buff
, "cpwir %s", csky_general_reg
[greg
]);
5836 sprintf (buff
, "cprc");
5843 v1_work_fpu_write (void)
5849 greg
= csky_insn
.val
[0];
5850 freg
= csky_insn
.val
[1];
5852 /* Now get greg and freg, we can write instruction to floating unit. */
5853 sprintf (buff
, "cpwgr %s,%s", csky_general_reg
[greg
], csky_cp_reg
[freg
]);
5860 v1_work_fpu_read (void)
5866 greg
= csky_insn
.val
[0];
5867 freg
= csky_insn
.val
[1];
5868 /* Now get greg and freg, we can write instruction to floating unit. */
5869 sprintf (buff
, "cprgr %s,%s", csky_general_reg
[greg
], csky_cp_reg
[freg
]);
5876 v1_work_fpu_writed (void)
5882 greg
= csky_insn
.val
[0];
5883 freg
= csky_insn
.val
[1];
5887 as_bad (_("even register number required"));
5890 /* Now get greg and freg, we can write instruction to floating unit. */
5891 if (target_big_endian
)
5892 sprintf (buff
, "cpwgr %s,%s",
5893 csky_general_reg
[greg
+ 1], csky_cp_reg
[freg
]);
5895 sprintf (buff
, "cpwgr %s,%s",
5896 csky_general_reg
[greg
], csky_cp_reg
[freg
]);
5898 if (target_big_endian
)
5899 sprintf (buff
, "cpwgr %s,%s",
5900 csky_general_reg
[greg
], csky_cp_reg
[freg
+ 1]);
5902 sprintf (buff
, "cpwgr %s,%s",
5903 csky_general_reg
[greg
+ 1], csky_cp_reg
[freg
+ 1]);
5910 v1_work_fpu_readd (void)
5916 greg
= csky_insn
.val
[0];
5917 freg
= csky_insn
.val
[1];
5921 as_bad (_("even register number required"));
5924 /* Now get greg and freg, we can write instruction to floating unit. */
5925 if (target_big_endian
)
5926 sprintf (buff
, "cprgr %s,%s",
5927 csky_general_reg
[greg
+ 1], csky_cp_reg
[freg
]);
5929 sprintf (buff
, "cprgr %s,%s",
5930 csky_general_reg
[greg
], csky_cp_reg
[freg
]);
5932 if (target_big_endian
)
5933 sprintf (buff
, "cprgr %s,%s",
5934 csky_general_reg
[greg
], csky_cp_reg
[freg
+ 1]);
5936 sprintf (buff
, "cprgr %s,%s",
5937 csky_general_reg
[greg
+ 1], csky_cp_reg
[freg
+ 1]);
5943 /* The following are for csky pseudo handling. */
5948 csky_insn
.output
= frag_more (2);
5950 /* Generate fixup BFD_RELOC_CKCORE_PCREL_IMM11BY2. */
5951 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
5952 2, & csky_insn
.e1
, 1, BFD_RELOC_CKCORE_PCREL_IMM11BY2
);
5955 /* Using jsri instruction. */
5956 const char *name
= "jsri";
5957 csky_insn
.opcode
= (struct csky_opcode
*)
5958 str_hash_find (csky_opcodes_hash
, name
);
5959 csky_insn
.opcode_idx
= 0;
5960 csky_insn
.isize
= 2;
5962 int n
= enter_literal (&csky_insn
.e1
, 1, 0, 0);
5964 /* Create a reference to pool entry. */
5965 csky_insn
.e1
.X_op
= O_symbol
;
5966 csky_insn
.e1
.X_add_symbol
= poolsym
;
5967 csky_insn
.e1
.X_add_number
= n
<< 2;
5969 /* Generate fixup BFD_RELOC_CKCORE_PCREL_IMM8BY4. */
5970 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
5971 2, & csky_insn
.e1
, 1, BFD_RELOC_CKCORE_PCREL_IMM8BY4
);
5973 if (csky_insn
.e1
.X_op
!= O_absent
&& do_jsri2bsr
)
5974 /* Generate fixup BFD_RELOC_CKCORE_PCREL_JSR_IMM11BY2. */
5975 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
5976 2, & (litpool
+ (csky_insn
.e1
.X_add_number
>> 2))->e
,
5977 1, BFD_RELOC_CKCORE_PCREL_JSR_IMM11BY2
);
5979 csky_generate_insn ();
5981 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
5986 /* The following are worker functions for csky v2 instruction handling. */
5988 /* For nie/nir/ipush/ipop. */
5991 v2_work_istack (void)
5995 csky_show_error (ERROR_OPCODE_ILLEGAL
, 0, NULL
, NULL
);
5998 csky_insn
.output
= frag_more (csky_insn
.isize
);
5999 csky_insn
.inst
= csky_insn
.opcode
->op16
[0].opcode
;
6000 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6005 v2_work_btsti (void)
6008 && (csky_insn
.flag_force
== INSN_OPCODE16F
6009 || IS_CSKY_ARCH_801 (mach_flag
)))
6011 csky_show_error (ERROR_OPCODE_ILLEGAL
, 0, NULL
, NULL
);
6014 if (!do_extend_lrw
&& csky_insn
.isize
== 2)
6015 csky_insn
.isize
= 4;
6016 /* Generate relax or reloc if necessary. */
6017 csky_generate_frags ();
6018 /* Generate the insn by mask. */
6019 csky_generate_insn ();
6020 /* Write inst to frag. */
6021 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6028 csky_insn
.isize
= 2;
6029 if (csky_insn
.number
== 2)
6031 if (csky_insn
.val
[0] == 14
6032 && csky_insn
.val
[1] >= 0 && csky_insn
.val
[1] <= 0x1fc
6033 && (csky_insn
.val
[1] & 0x3) == 0
6034 && csky_insn
.flag_force
!= INSN_OPCODE32F
)
6036 /* addi sp, sp, imm. */
6037 csky_insn
.inst
= 0x1400 | ((csky_insn
.val
[1] >> 2) & 0x1f);
6038 csky_insn
.inst
|= (csky_insn
.val
[1] << 1) & 0x300;
6039 csky_insn
.output
= frag_more (2);
6041 else if (csky_insn
.val
[0] < 8
6042 && csky_insn
.val
[1] >= 1 && csky_insn
.val
[1] <= 0x100
6043 && csky_insn
.flag_force
!= INSN_OPCODE32F
)
6045 csky_insn
.inst
= 0x2000 | (csky_insn
.val
[0] << 8);
6046 csky_insn
.inst
|= (csky_insn
.val
[1] - 1);
6047 csky_insn
.output
= frag_more (2);
6049 else if (csky_insn
.val
[1] >= 1 && csky_insn
.val
[1] <= 0x10000
6050 && csky_insn
.flag_force
!= INSN_OPCODE16F
6051 && !IS_CSKY_ARCH_801 (mach_flag
))
6053 csky_insn
.inst
= 0xe4000000 | (csky_insn
.val
[0] << 21);
6054 csky_insn
.inst
|= csky_insn
.val
[0] << 16;
6055 csky_insn
.inst
|= (csky_insn
.val
[1] - 1);
6056 csky_insn
.isize
= 4;
6057 csky_insn
.output
= frag_more (4);
6061 csky_show_error (ERROR_OPERANDS_ILLEGAL
, 0,
6062 csky_insn
.opcode_end
, NULL
);
6066 else if (csky_insn
.number
== 3)
6068 if (csky_insn
.val
[0] == 14
6069 && csky_insn
.val
[1] == 14
6070 && csky_insn
.val
[2] >= 0 && csky_insn
.val
[2] <= 0x1fc
6071 && (csky_insn
.val
[2] & 0x3) == 0
6072 && csky_insn
.flag_force
!= INSN_OPCODE32F
)
6074 csky_insn
.inst
= 0x1400 | ((csky_insn
.val
[2] >> 2) & 0x1f);
6075 csky_insn
.inst
|= (csky_insn
.val
[2] << 1) & 0x300;
6076 csky_insn
.output
= frag_more (2);
6078 else if (csky_insn
.val
[0] < 8
6079 && csky_insn
.val
[1] == 14
6080 && csky_insn
.val
[2] >= 0 && csky_insn
.val
[2] <= 0x3fc
6081 && (csky_insn
.val
[2] & 0x3) == 0
6082 && csky_insn
.flag_force
!= INSN_OPCODE32F
)
6084 csky_insn
.inst
= 0x1800 | (csky_insn
.val
[0] << 8);
6085 csky_insn
.inst
|= csky_insn
.val
[2] >> 2;
6086 csky_insn
.output
= frag_more (2);
6088 else if (csky_insn
.val
[0] < 8
6089 && csky_insn
.val
[0] == csky_insn
.val
[1]
6090 && csky_insn
.val
[2] >= 1 && csky_insn
.val
[2] <= 0x100
6091 && csky_insn
.flag_force
!= INSN_OPCODE32F
)
6093 csky_insn
.inst
= 0x2000 | (csky_insn
.val
[0] << 8);
6094 csky_insn
.inst
|= (csky_insn
.val
[2] - 1);
6095 csky_insn
.output
= frag_more (2);
6097 else if (csky_insn
.val
[0] < 8
6098 && csky_insn
.val
[1] < 8
6099 && csky_insn
.val
[2] >= 1 && csky_insn
.val
[2] <= 0x8
6100 && csky_insn
.flag_force
!= INSN_OPCODE32F
)
6102 csky_insn
.inst
= 0x5802 | (csky_insn
.val
[0] << 5);
6103 csky_insn
.inst
|= csky_insn
.val
[1] << 8;
6104 csky_insn
.inst
|= (csky_insn
.val
[2] - 1) << 2;
6105 csky_insn
.output
= frag_more (2);
6107 else if (csky_insn
.val
[1] == 28
6108 && csky_insn
.val
[2] >= 1 && csky_insn
.val
[2] <= 0x40000
6109 && csky_insn
.flag_force
!= INSN_OPCODE16F
6110 && !IS_CSKY_ARCH_801 (mach_flag
))
6112 csky_insn
.inst
= 0xcc1c0000 | (csky_insn
.val
[0] << 21);
6113 csky_insn
.isize
= 4;
6114 csky_insn
.output
= frag_more (4);
6115 if (insn_reloc
== BFD_RELOC_CKCORE_GOTOFF
)
6117 fix_new_exp (frag_now
, csky_insn
.output
-frag_now
->fr_literal
,
6118 4, &csky_insn
.e1
, 0, BFD_RELOC_CKCORE_GOTOFF_IMM18
);
6121 csky_insn
.inst
|= (csky_insn
.val
[2] - 1);
6123 else if (csky_insn
.val
[2] >= 1 && csky_insn
.val
[2] <= 0x1000
6124 && csky_insn
.flag_force
!= INSN_OPCODE16F
6125 && !IS_CSKY_ARCH_801 (mach_flag
))
6127 csky_insn
.inst
= 0xe4000000 | (csky_insn
.val
[0] << 21);
6128 csky_insn
.inst
|= csky_insn
.val
[1] << 16;
6129 csky_insn
.inst
|= (csky_insn
.val
[2] - 1);
6130 csky_insn
.isize
= 4;
6131 csky_insn
.output
= frag_more (4);
6135 csky_show_error (ERROR_OPERANDS_ILLEGAL
, 0,
6136 (char *)csky_insn
.opcode_end
, NULL
);
6140 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6148 csky_insn
.isize
= 2;
6149 if (csky_insn
.number
== 2)
6151 if (csky_insn
.val
[0] == 14
6152 && csky_insn
.val
[1] >= 0 && csky_insn
.val
[2] <= 0x1fc
6153 && (csky_insn
.val
[1] & 0x3) == 0
6154 && csky_insn
.flag_force
!= INSN_OPCODE32F
)
6156 csky_insn
.inst
= 0x1420 | ((csky_insn
.val
[1] >> 2) & 0x1f);
6157 csky_insn
.inst
|= (csky_insn
.val
[1] << 1) & 0x300;
6159 else if (csky_insn
.val
[0] < 8
6160 && csky_insn
.val
[1] >= 1 && csky_insn
.val
[1] <= 0x100
6161 && csky_insn
.flag_force
!= INSN_OPCODE32F
)
6163 csky_insn
.inst
= 0x2800 | (csky_insn
.val
[0] << 8);
6164 csky_insn
.inst
|= (csky_insn
.val
[1] - 1);
6166 else if (csky_insn
.val
[1] >= 1 && csky_insn
.val
[1] <= 0x10000
6167 && csky_insn
.flag_force
!= INSN_OPCODE16F
6168 && !IS_CSKY_ARCH_801 (mach_flag
))
6170 csky_insn
.inst
= 0xe4001000 | (csky_insn
.val
[0] << 21);
6171 csky_insn
.inst
|= csky_insn
.val
[0] << 16;
6172 csky_insn
.inst
|= (csky_insn
.val
[1] - 1);
6173 csky_insn
.isize
= 4;
6177 csky_show_error (ERROR_OPERANDS_ILLEGAL
, 0,
6178 (char *)csky_insn
.opcode_end
, NULL
);
6182 else if (csky_insn
.number
== 3)
6184 if (csky_insn
.val
[0] == 14
6185 && csky_insn
.val
[1] == 14
6186 && csky_insn
.val
[2] >= 0 && csky_insn
.val
[2] <= 0x1fc
6187 && (csky_insn
.val
[2] & 0x3) == 0
6188 && csky_insn
.flag_force
!= INSN_OPCODE32F
)
6190 csky_insn
.inst
= 0x1420 | ((csky_insn
.val
[2] >> 2) & 0x1f);
6191 csky_insn
.inst
|= (csky_insn
.val
[2] << 1) & 0x300;
6194 else if (csky_insn
.val
[0] < 8
6195 && csky_insn
.val
[0] == csky_insn
.val
[1]
6196 && csky_insn
.val
[2] >= 1 && csky_insn
.val
[2] <= 0x100
6197 && csky_insn
.flag_force
!= INSN_OPCODE32F
)
6199 csky_insn
.inst
= 0x2800 | (csky_insn
.val
[0] << 8);
6200 csky_insn
.inst
|= (csky_insn
.val
[2] - 1);
6202 else if (csky_insn
.val
[0] < 8
6203 && csky_insn
.val
[1] < 8
6204 && csky_insn
.val
[2] >= 1 && csky_insn
.val
[2] <= 0x8
6205 && csky_insn
.flag_force
!= INSN_OPCODE32F
)
6207 csky_insn
.inst
= 0x5803 | (csky_insn
.val
[0] << 5);
6208 csky_insn
.inst
|= csky_insn
.val
[1] << 8;
6209 csky_insn
.inst
|= (csky_insn
.val
[2] - 1) << 2;
6211 else if (csky_insn
.val
[2] >= 1 && csky_insn
.val
[2] <= 0x1000
6212 && csky_insn
.flag_force
!= INSN_OPCODE16F
6213 && !IS_CSKY_ARCH_801 (mach_flag
))
6215 csky_insn
.inst
= 0xe4001000 | (csky_insn
.val
[0] << 21);
6216 csky_insn
.inst
|= csky_insn
.val
[1] << 16;
6217 csky_insn
.inst
|= (csky_insn
.val
[2] - 1);
6218 csky_insn
.isize
= 4;
6222 csky_show_error (ERROR_OPERANDS_ILLEGAL
, 0,
6223 (char *)csky_insn
.opcode_end
, NULL
);
6227 csky_insn
.output
= frag_more (csky_insn
.isize
);
6228 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6234 v2_work_add_sub (void)
6236 if (csky_insn
.number
== 3
6237 && (csky_insn
.val
[0] == csky_insn
.val
[1]
6238 || csky_insn
.val
[0] == csky_insn
.val
[2])
6239 && csky_insn
.val
[0] <= 15
6240 && csky_insn
.val
[1] <= 15
6241 && csky_insn
.val
[2] <= 15)
6243 if (!strstr (csky_insn
.opcode
->mnemonic
, "sub")
6244 || csky_insn
.val
[0] == csky_insn
.val
[1])
6246 csky_insn
.opcode_idx
= 0;
6247 csky_insn
.isize
= 2;
6248 if (csky_insn
.val
[0] == csky_insn
.val
[1])
6249 csky_insn
.val
[1] = csky_insn
.val
[2];
6251 csky_insn
.number
= 2;
6255 if (csky_insn
.isize
== 4
6256 && IS_CSKY_ARCH_801 (mach_flag
))
6258 if (csky_insn
.number
== 3)
6260 if (csky_insn
.val
[0] > 7)
6261 csky_show_error (ERROR_REG_OVER_RANGE
, 1,
6262 (void *)(long)csky_insn
.val
[0], NULL
);
6263 if (csky_insn
.val
[1] > 7)
6264 csky_show_error (ERROR_REG_OVER_RANGE
, 2,
6265 (void *)(long)csky_insn
.val
[1], NULL
);
6266 if (csky_insn
.val
[2] > 7)
6267 csky_show_error (ERROR_REG_OVER_RANGE
, 3,
6268 (void *)(long)csky_insn
.val
[2], NULL
);
6272 if (csky_insn
.val
[0] > 15)
6273 csky_show_error (ERROR_REG_OVER_RANGE
, 1,
6274 (void *)(long)csky_insn
.val
[0], NULL
);
6275 if (csky_insn
.val
[1] > 15)
6276 csky_show_error (ERROR_REG_OVER_RANGE
, 2,
6277 (void *)(long)csky_insn
.val
[1], NULL
);
6282 /* Generate relax or reloc if necessary. */
6283 csky_generate_frags ();
6284 /* Generate the insn by mask. */
6285 csky_generate_insn ();
6286 /* Write inst to frag. */
6287 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6292 v2_work_rotlc (void)
6294 const char *name
= "addc";
6296 = (struct csky_opcode
*) str_hash_find (csky_opcodes_hash
, name
);
6297 csky_insn
.opcode_idx
= 0;
6298 if (csky_insn
.isize
== 2)
6301 csky_insn
.number
= 2;
6302 csky_insn
.val
[1] = csky_insn
.val
[0];
6306 csky_insn
.number
= 3;
6307 /* addc rz, rx, ry. */
6308 csky_insn
.val
[1] = csky_insn
.val
[0];
6309 csky_insn
.val
[2] = csky_insn
.val
[0];
6311 /* Generate relax or reloc if necessary. */
6312 csky_generate_frags ();
6313 /* Generate the insn by mask. */
6314 csky_generate_insn ();
6315 /* Write inst to frag. */
6316 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6321 v2_work_bgeni (void)
6323 const char *name
= NULL
;
6324 int imm
= csky_insn
.val
[1];
6334 = (struct csky_opcode
*) str_hash_find (csky_opcodes_hash
, name
);
6335 csky_insn
.opcode_idx
= 0;
6336 csky_insn
.val
[1] = val
;
6338 /* Generate relax or reloc if necessary. */
6339 csky_generate_frags ();
6340 /* Generate the insn by mask. */
6341 csky_generate_insn ();
6342 /* Write inst to frag. */
6343 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6350 const char *name
= "nor";
6352 = (struct csky_opcode
*) str_hash_find (csky_opcodes_hash
, name
);
6353 csky_insn
.opcode_idx
= 0;
6354 if (csky_insn
.number
== 1)
6356 csky_insn
.val
[1] = csky_insn
.val
[0];
6357 if (csky_insn
.val
[0] < 16)
6359 /* 16 bits nor rz, rz. */
6360 csky_insn
.number
= 2;
6361 csky_insn
.isize
= 2;
6365 csky_insn
.val
[2] = csky_insn
.val
[0];
6366 csky_insn
.number
= 3;
6367 csky_insn
.isize
= 4;
6370 if (csky_insn
.number
== 2)
6372 if (csky_insn
.val
[0] == csky_insn
.val
[1]
6373 && csky_insn
.val
[0] < 16)
6375 /* 16 bits nor rz, rz. */
6376 csky_insn
.number
= 2;
6377 csky_insn
.isize
= 2;
6381 csky_insn
.val
[2] = csky_insn
.val
[1];
6382 csky_insn
.number
= 3;
6383 csky_insn
.isize
= 4;
6387 /* Generate relax or reloc if necessary. */
6388 csky_generate_frags ();
6389 /* Generate the insn by mask. */
6390 csky_generate_insn ();
6391 /* Write inst to frag. */
6392 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6399 if (csky_insn
.e1
.X_add_symbol
== NULL
|| csky_insn
.e1
.X_op
== O_constant
)
6401 csky_show_error (ERROR_UNDEFINE
, 0, (void *)"operand is invalid", NULL
);
6405 if (IS_CSKY_ARCH_801 (mach_flag
))
6407 /* CK801 doesn't have 32-bit bt/bf insns or a jump insn with a
6408 range larger than SCOND_DISP16. Relax to a short jump around
6409 an unconditional branch, and give up if that overflows too. */
6410 csky_insn
.output
= frag_var (rs_machine_dependent
,
6414 csky_insn
.e1
.X_add_symbol
,
6415 csky_insn
.e1
.X_add_number
,
6417 csky_insn
.isize
= 2;
6418 csky_insn
.max
= SCOND_DISP16_LEN
;
6419 csky_insn
.inst
= csky_insn
.opcode
->op16
[0].opcode
;
6421 else if (do_long_jump
&& !IS_CSKY_ARCH_802 (mach_flag
))
6423 /* Generate relax with jcondition.
6424 Note that CK802 doesn't support the JMPI instruction so
6425 we cannot relax to a jump with a 32-bit offset. */
6426 csky_insn
.output
= frag_var (rs_machine_dependent
,
6430 csky_insn
.e1
.X_add_symbol
,
6431 csky_insn
.e1
.X_add_number
,
6433 csky_insn
.isize
= 2;
6434 csky_insn
.max
= JCOND_DISP32_LEN
;
6435 csky_insn
.inst
= csky_insn
.opcode
->op16
[0].opcode
;
6439 /* Generate relax with condition. */
6440 csky_insn
.output
= frag_var (rs_machine_dependent
,
6444 csky_insn
.e1
.X_add_symbol
,
6445 csky_insn
.e1
.X_add_number
,
6447 csky_insn
.isize
= 2;
6448 csky_insn
.max
= COND_DISP16_LEN
;
6449 csky_insn
.inst
= csky_insn
.opcode
->op16
[0].opcode
;
6451 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6459 if (csky_insn
.e1
.X_add_symbol
== NULL
|| csky_insn
.e1
.X_op
== O_constant
)
6461 csky_show_error (ERROR_UNDEFINE
, 0, (void *)"operand is invalid", NULL
);
6466 && !IS_CSKY_ARCH_801 (mach_flag
)
6467 && !IS_CSKY_ARCH_802 (mach_flag
))
6469 csky_insn
.output
= frag_var (rs_machine_dependent
,
6473 csky_insn
.e1
.X_add_symbol
,
6474 csky_insn
.e1
.X_add_number
,
6477 csky_insn
.inst
= csky_insn
.opcode
->op16
[0].opcode
;
6478 csky_insn
.max
= JUNCD_DISP32_LEN
;
6479 csky_insn
.isize
= 2;
6483 /* Generate relax with condition. */
6484 csky_insn
.output
= frag_var (rs_machine_dependent
,
6488 csky_insn
.e1
.X_add_symbol
,
6489 csky_insn
.e1
.X_add_number
,
6491 csky_insn
.isize
= 2;
6492 csky_insn
.max
= UNCD_DISP16_LEN
;
6493 csky_insn
.inst
= csky_insn
.opcode
->op16
[0].opcode
;
6496 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6500 #define SIZE_V2_MOVI16(x) ((addressT)x <= 0xff)
6501 #define SIZE_V2_MOVI32(x) ((addressT)x <= 0xffff)
6502 #define SIZE_V2_MOVIH(x) ((addressT)x <= 0xffffffff && (((addressT)x & 0xffff) == 0))
6507 int reg
= csky_insn
.val
[0];
6508 int output_literal
= csky_insn
.val
[1];
6511 /* If the second operand is O_constant, We can use movi/movih
6513 if (csky_insn
.e1
.X_op
== O_constant
)
6515 /* 801 only has movi16. */
6516 if (SIZE_V2_MOVI16 (csky_insn
.e1
.X_add_number
) && reg
< 8)
6518 /* movi16 instead. */
6519 csky_insn
.output
= frag_more (2);
6520 csky_insn
.inst
= (CSKYV2_INST_MOVI16
| (reg
<< 8)
6521 | (csky_insn
.e1
.X_add_number
));
6522 csky_insn
.isize
= 2;
6525 else if (SIZE_V2_MOVI32 (csky_insn
.e1
.X_add_number
)
6526 && !IS_CSKY_ARCH_801 (mach_flag
))
6528 /* movi32 instead. */
6529 csky_insn
.output
= frag_more (4);
6530 csky_insn
.inst
= (CSKYV2_INST_MOVI32
| (reg
<< 16)
6531 | (csky_insn
.e1
.X_add_number
));
6532 csky_insn
.isize
= 4;
6535 else if (SIZE_V2_MOVIH (csky_insn
.e1
.X_add_number
)
6536 && !IS_CSKY_ARCH_801 (mach_flag
))
6538 /* movih instead. */
6539 csky_insn
.output
= frag_more (4);
6540 csky_insn
.inst
= (CSKYV2_INST_MOVIH
| (reg
<< 16)
6541 | ((csky_insn
.e1
.X_add_number
>> 16) & 0xffff));
6542 csky_insn
.isize
= 4;
6549 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6555 int n
= enter_literal (&csky_insn
.e1
, 0, 0, 0);
6556 /* Create a reference to pool entry. */
6557 csky_insn
.e1
.X_op
= O_symbol
;
6558 csky_insn
.e1
.X_add_symbol
= poolsym
;
6559 csky_insn
.e1
.X_add_number
= n
<< 2;
6561 /* If 16bit force. */
6562 if (csky_insn
.flag_force
== INSN_OPCODE16F
)
6564 /* Generate fixup. */
6567 csky_show_error (ERROR_UNDEFINE
, 0,
6568 (void *)"The register is out of range.", NULL
);
6571 csky_insn
.isize
= 2;
6572 csky_insn
.output
= frag_more (2);
6574 if (insn_reloc
== BFD_RELOC_CKCORE_TLS_GD32
6575 || insn_reloc
== BFD_RELOC_CKCORE_TLS_LDM32
6576 || insn_reloc
== BFD_RELOC_CKCORE_TLS_IE32
)
6578 literal_insn_offset
->tls_addend
.frag
= frag_now
;
6579 literal_insn_offset
->tls_addend
.offset
6580 = csky_insn
.output
- frag_now
->fr_literal
;
6582 csky_insn
.inst
= csky_insn
.opcode
->op16
[0].opcode
| (reg
<< 5);
6584 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
6585 2, &csky_insn
.e1
, 1, BFD_RELOC_CKCORE_PCREL_IMM7BY4
);
6587 else if (csky_insn
.flag_force
== INSN_OPCODE32F
)
6589 csky_insn
.isize
= 4;
6590 csky_insn
.output
= frag_more (4);
6591 if (insn_reloc
== BFD_RELOC_CKCORE_TLS_GD32
6592 || insn_reloc
== BFD_RELOC_CKCORE_TLS_LDM32
6593 || insn_reloc
== BFD_RELOC_CKCORE_TLS_IE32
)
6595 literal_insn_offset
->tls_addend
.frag
= frag_now
;
6596 literal_insn_offset
->tls_addend
.offset
6597 = csky_insn
.output
- frag_now
->fr_literal
;
6599 csky_insn
.inst
= csky_insn
.opcode
->op32
[0].opcode
| (reg
<< 16);
6600 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
6601 4, &csky_insn
.e1
, 1, BFD_RELOC_CKCORE_PCREL_IMM16BY4
);
6607 csky_insn
.isize
= 2;
6609 if (insn_reloc
== BFD_RELOC_CKCORE_TLS_GD32
6610 || insn_reloc
== BFD_RELOC_CKCORE_TLS_LDM32
6611 || insn_reloc
== BFD_RELOC_CKCORE_TLS_IE32
)
6612 literal_insn_offset
->tls_addend
.frag
= frag_now
;
6614 csky_insn
.output
= frag_var (rs_machine_dependent
,
6618 ? LRW2_DISP8
: LRW_DISP7
),
6619 csky_insn
.e1
.X_add_symbol
,
6620 csky_insn
.e1
.X_add_number
, 0);
6621 if (insn_reloc
== BFD_RELOC_CKCORE_TLS_GD32
6622 || insn_reloc
== BFD_RELOC_CKCORE_TLS_LDM32
6623 || insn_reloc
== BFD_RELOC_CKCORE_TLS_IE32
)
6625 if (literal_insn_offset
->tls_addend
.frag
->fr_next
!= frag_now
)
6626 literal_insn_offset
->tls_addend
.frag
6627 = literal_insn_offset
->tls_addend
.frag
->fr_next
;
6628 literal_insn_offset
->tls_addend
.offset
6630 - literal_insn_offset
->tls_addend
.frag
->fr_literal
);
6632 csky_insn
.inst
= csky_insn
.opcode
->op16
[0].opcode
| (reg
<< 5);
6633 csky_insn
.max
= LRW_DISP16_LEN
;
6634 csky_insn
.isize
= 2;
6638 csky_insn
.isize
= 4;
6639 csky_insn
.output
= frag_more (4);
6640 if (insn_reloc
== BFD_RELOC_CKCORE_TLS_GD32
6641 || insn_reloc
== BFD_RELOC_CKCORE_TLS_LDM32
6642 || insn_reloc
== BFD_RELOC_CKCORE_TLS_IE32
)
6644 literal_insn_offset
->tls_addend
.frag
= frag_now
;
6645 literal_insn_offset
->tls_addend
.offset
6646 = csky_insn
.output
- frag_now
->fr_literal
;
6648 csky_insn
.inst
= csky_insn
.opcode
->op32
[0].opcode
| (reg
<< 16);
6649 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
6650 4, &csky_insn
.e1
, 1, BFD_RELOC_CKCORE_PCREL_IMM16BY4
);
6654 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6659 v2_work_lrsrsw (void)
6661 int reg
= csky_insn
.val
[0];
6662 csky_insn
.output
= frag_more (4);
6663 csky_insn
.inst
= csky_insn
.opcode
->op32
[0].opcode
| (reg
<< 21);
6664 csky_insn
.isize
= 4;
6668 case BFD_RELOC_CKCORE_GOT32
:
6669 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
6670 4, &csky_insn
.e1
, 0, BFD_RELOC_CKCORE_GOT_IMM18BY4
);
6672 case BFD_RELOC_CKCORE_PLT32
:
6673 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
6674 4, &csky_insn
.e1
, 0, BFD_RELOC_CKCORE_PLT_IMM18BY4
);
6677 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
6678 4, &csky_insn
.e1
, 1, BFD_RELOC_CKCORE_DOFFSET_IMM18BY4
);
6681 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6689 || IS_CSKY_ARCH_801 (mach_flag
)
6690 || IS_CSKY_ARCH_802 (mach_flag
))
6692 csky_insn
.output
= frag_more (4);
6693 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
6694 4, &csky_insn
.e1
, 1, BFD_RELOC_CKCORE_PCREL_IMM26BY2
);
6695 csky_insn
.isize
= 4;
6696 csky_insn
.inst
= CSKYV2_INST_BSR32
;
6700 int n
= enter_literal (&csky_insn
.e1
, 0, 0, 0);
6701 csky_insn
.output
= frag_more (4);
6702 csky_insn
.e1
.X_op
= O_symbol
;
6703 csky_insn
.e1
.X_add_symbol
= poolsym
;
6704 csky_insn
.e1
.X_add_number
= n
<< 2;
6705 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
6706 4, &csky_insn
.e1
, 1, BFD_RELOC_CKCORE_PCREL_IMM16BY4
);
6707 if (do_jsri2bsr
|| IS_CSKY_ARCH_810 (mach_flag
))
6708 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
6710 &(litpool
+ (csky_insn
.e1
.X_add_number
>> 2))->e
,
6712 BFD_RELOC_CKCORE_PCREL_JSR_IMM26BY2
);
6713 csky_insn
.inst
= CSKYV2_INST_JSRI32
;
6714 csky_insn
.isize
= 4;
6715 if (IS_CSKY_ARCH_810 (mach_flag
))
6717 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6718 csky_insn
.output
= frag_more (4);
6719 dwarf2_emit_insn (0);
6720 /* Insert "mov r0, r0". */
6721 csky_insn
.inst
= CSKYV2_INST_MOV_R0_R0
;
6725 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6734 int n
= enter_literal (&csky_insn
.e1
, 1, 0, 0);
6735 csky_insn
.e1
.X_op
= O_symbol
;
6736 csky_insn
.e1
.X_add_symbol
= poolsym
;
6737 csky_insn
.e1
.X_add_number
= n
<< 2;
6739 /* Generate relax or reloc if necessary. */
6740 csky_generate_frags ();
6741 /* Generate the insn by mask. */
6742 csky_generate_insn ();
6743 /* Write inst to frag. */
6744 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6745 /* Control 810 not to generate jsri. */
6746 if (IS_CSKY_ARCH_810 (mach_flag
))
6748 /* Look at adding the R_PCREL_JSRIMM26BY2.
6749 For 'jbsr .L1', this reloc type's symbol
6750 is bound to '.L1', isn't bound to literal pool. */
6751 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
6752 4, &(litpool
+ (csky_insn
.e1
.X_add_number
>> 2))->e
, 1,
6753 BFD_RELOC_CKCORE_PCREL_JSR_IMM26BY2
);
6754 csky_insn
.output
= frag_more (4);
6755 dwarf2_emit_insn (0);
6756 /* The opcode of "mov32 r0,r0". */
6757 csky_insn
.inst
= CSKYV2_INST_MOV_R0_R0
;
6758 /* The effect of this value is to check literal. */
6759 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6766 v2_work_movih (void)
6768 int rz
= csky_insn
.val
[0];
6769 csky_insn
.output
= frag_more (4);
6770 csky_insn
.inst
= csky_insn
.opcode
->op32
[0].opcode
| (rz
<< 16);
6771 if (csky_insn
.e1
.X_op
== O_constant
)
6773 if (csky_insn
.e1
.X_unsigned
== 1 && csky_insn
.e1
.X_add_number
> 0xffff)
6775 csky_show_error (ERROR_IMM_OVERFLOW
, 2, NULL
, NULL
);
6778 else if (csky_insn
.e1
.X_unsigned
== 0 && csky_insn
.e1
.X_add_number
< 0)
6780 csky_show_error (ERROR_IMM_OVERFLOW
, 2, NULL
, NULL
);
6784 csky_insn
.inst
|= (csky_insn
.e1
.X_add_number
& 0xffff);
6786 else if (csky_insn
.e1
.X_op
== O_right_shift
6787 || (csky_insn
.e1
.X_op
== O_symbol
&& insn_reloc
!= BFD_RELOC_NONE
))
6789 if (csky_insn
.e1
.X_op_symbol
!= 0
6790 && symbol_constant_p (csky_insn
.e1
.X_op_symbol
)
6791 && S_GET_SEGMENT (csky_insn
.e1
.X_op_symbol
) == absolute_section
6792 && 16 == S_GET_VALUE (csky_insn
.e1
.X_op_symbol
))
6794 csky_insn
.e1
.X_op
= O_symbol
;
6795 if (insn_reloc
== BFD_RELOC_CKCORE_GOT32
)
6796 insn_reloc
= BFD_RELOC_CKCORE_GOT_HI16
;
6797 else if (insn_reloc
== BFD_RELOC_CKCORE_PLT32
)
6798 insn_reloc
= BFD_RELOC_CKCORE_PLT_HI16
;
6799 else if (insn_reloc
== BFD_RELOC_CKCORE_GOTPC
)
6800 insn_reloc
= BFD_RELOC_CKCORE_GOTPC_HI16
;
6801 else if (insn_reloc
== BFD_RELOC_CKCORE_GOTOFF
)
6802 insn_reloc
= BFD_RELOC_CKCORE_GOTOFF_HI16
;
6804 insn_reloc
= BFD_RELOC_CKCORE_ADDR_HI16
;
6805 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
6806 4, &csky_insn
.e1
, 0, insn_reloc
);
6810 void *arg
= (void *)"the second operand must be \"SYMBOL >> 16\"";
6811 csky_show_error (ERROR_UNDEFINE
, 0, arg
, NULL
);
6815 csky_insn
.isize
= 4;
6816 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6824 int rz
= csky_insn
.val
[0];
6825 int rx
= csky_insn
.val
[1];
6826 csky_insn
.output
= frag_more (4);
6827 csky_insn
.inst
= csky_insn
.opcode
->op32
[0].opcode
| (rz
<< 21) | (rx
<< 16);
6828 if (csky_insn
.e1
.X_op
== O_constant
)
6830 if (csky_insn
.e1
.X_add_number
<= 0xffff
6831 && csky_insn
.e1
.X_add_number
>= 0)
6832 csky_insn
.inst
|= csky_insn
.e1
.X_add_number
;
6835 csky_show_error (ERROR_IMM_OVERFLOW
, 3, NULL
, NULL
);
6839 else if (csky_insn
.e1
.X_op
== O_bit_and
)
6841 if (symbol_constant_p (csky_insn
.e1
.X_op_symbol
)
6842 && S_GET_SEGMENT (csky_insn
.e1
.X_op_symbol
) == absolute_section
6843 && 0xffff == S_GET_VALUE (csky_insn
.e1
.X_op_symbol
))
6845 csky_insn
.e1
.X_op
= O_symbol
;
6846 if (insn_reloc
== BFD_RELOC_CKCORE_GOT32
)
6847 insn_reloc
= BFD_RELOC_CKCORE_GOT_LO16
;
6848 else if (insn_reloc
== BFD_RELOC_CKCORE_PLT32
)
6849 insn_reloc
= BFD_RELOC_CKCORE_PLT_LO16
;
6850 else if (insn_reloc
== BFD_RELOC_CKCORE_GOTPC
)
6851 insn_reloc
= BFD_RELOC_CKCORE_GOTPC_LO16
;
6852 else if (insn_reloc
== BFD_RELOC_CKCORE_GOTOFF
)
6853 insn_reloc
= BFD_RELOC_CKCORE_GOTOFF_LO16
;
6855 insn_reloc
= BFD_RELOC_CKCORE_ADDR_LO16
;
6856 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
6857 4, &csky_insn
.e1
, 0, insn_reloc
);
6861 void *arg
= (void *)"the third operand must be \"SYMBOL & 0xffff\"";
6862 csky_show_error (ERROR_UNDEFINE
, 0, arg
, NULL
);
6866 csky_insn
.isize
= 4;
6867 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6871 /* Helper function to encode a single/double floating point constant
6872 into the instruction word for fmovis and fmovid instructions.
6873 The constant is in its IEEE single/double precision representation
6874 and is repacked into the internal 13-bit representation for these
6875 instructions with a diagnostic for overflow. Note that there is no
6876 rounding when converting to the smaller format, just an error if there
6877 is excess precision or the number is too small/large to be represented. */
6880 float_work_fmovi (void)
6882 int rx
= csky_insn
.val
[0];
6884 /* We already converted the float constant to the internal 13-bit
6885 representation so we just need to OR it in here. */
6886 csky_insn
.inst
= csky_insn
.opcode
->op32
[0].opcode
| rx
;
6887 csky_insn
.inst
|= (uint32_t) csky_insn
.e1
.X_add_number
;
6889 csky_insn
.output
= frag_more (4);
6890 csky_insn
.isize
= 4;
6891 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6896 dsp_work_bloop (void)
6898 int reg
= csky_insn
.val
[0];
6899 csky_insn
.output
= frag_more (4);
6900 csky_insn
.inst
= csky_insn
.opcode
->op32
[0].opcode
| (reg
<< 16);
6901 csky_insn
.isize
= 4;
6903 if (csky_insn
.e1
.X_op
== O_symbol
6904 && csky_insn
.e2
.X_op
== O_symbol
)
6906 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
6907 4, &csky_insn
.e1
, 1,
6908 BFD_RELOC_CKCORE_PCREL_BLOOP_IMM12BY4
);
6909 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
6910 4, &csky_insn
.e2
, 1,
6911 BFD_RELOC_CKCORE_PCREL_BLOOP_IMM4BY4
);
6914 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6919 /* The following are for assembler directive handling. */
6921 /* Helper function to adjust constant pool counts when we emit a
6922 data directive in the text section. FUNC is one of the standard
6923 gas functions to handle these directives, like "stringer" for the
6924 .string directive, and ARG is the argument to FUNC. csky_pool_count
6925 essentially wraps the call with the constant pool magic. */
6928 csky_pool_count (void (*func
) (int), int arg
)
6930 const fragS
*curr_frag
= frag_now
;
6931 offsetT added
= -frag_now_fix_octets ();
6935 while (curr_frag
!= frag_now
)
6937 added
+= curr_frag
->fr_fix
;
6938 curr_frag
= curr_frag
->fr_next
;
6941 added
+= frag_now_fix_octets ();
6945 /* Support the .literals directive. */
6947 csky_s_literals (int ignore ATTRIBUTE_UNUSED
)
6950 demand_empty_rest_of_line ();
6953 /* Support the .string, etc directives. */
6955 csky_stringer (int append_zero
)
6957 if (now_seg
== text_section
)
6958 csky_pool_count (stringer
, append_zero
);
6960 stringer (append_zero
);
6962 /* We call check_literals here in case a large number of strings are
6963 being placed into the text section with a sequence of stringer
6964 directives. In theory we could be upsetting something if these
6965 strings are actually in an indexed table instead of referenced by
6966 individual labels. Let us hope that that never happens. */
6967 check_literals (2, 0);
6970 /* Support integer-mode constructors like .word, .byte, etc. */
6973 csky_cons (int nbytes
)
6975 mapping_state (MAP_DATA
);
6976 if (nbytes
== 4) /* @GOT. */
6980 bfd_reloc_code_real_type reloc
;
6983 reloc
= BFD_RELOC_NONE
;
6985 lex_got (&reloc
, NULL
);
6987 if (exp
.X_op
== O_symbol
&& reloc
!= BFD_RELOC_NONE
)
6989 reloc_howto_type
*howto
6990 = bfd_reloc_type_lookup (stdoutput
, reloc
);
6991 int size
= bfd_get_reloc_size (howto
);
6994 as_bad (ngettext ("%s relocations do not fit in %d byte",
6995 "%s relocations do not fit in %d bytes",
6997 howto
->name
, nbytes
);
7000 register char *p
= frag_more ((int) nbytes
);
7001 int offset
= nbytes
- size
;
7003 fix_new_exp (frag_now
,
7004 p
- frag_now
->fr_literal
+ offset
,
7005 size
, &exp
, 0, reloc
);
7009 emit_expr (&exp
, (unsigned int) nbytes
);
7010 if (now_seg
== text_section
)
7013 while (*input_line_pointer
++ == ',');
7015 /* Put terminator back into stream. */
7016 input_line_pointer
--;
7017 demand_empty_rest_of_line ();
7022 if (now_seg
== text_section
)
7023 csky_pool_count (cons
, nbytes
);
7027 /* In theory we ought to call check_literals (2,0) here in case
7028 we need to dump the literal table. We cannot do this however,
7029 as the directives that we are intercepting may be being used
7030 to build a switch table, and we must not interfere with its
7031 contents. Instead we cross our fingers and pray... */
7034 /* Support floating-mode constant directives like .float and .double. */
7037 csky_float_cons (int float_type
)
7039 mapping_state (MAP_DATA
);
7040 if (now_seg
== text_section
)
7041 csky_pool_count (float_cons
, float_type
);
7043 float_cons (float_type
);
7045 /* See the comment in csky_cons () about calling check_literals.
7046 It is unlikely that a switch table will be constructed using
7047 floating point values, but it is still likely that an indexed
7048 table of floating point constants is being created by these
7049 directives, so again we must not interfere with their placement. */
7052 /* Support the .fill directive. */
7055 csky_fill (int ignore
)
7057 if (now_seg
== text_section
)
7058 csky_pool_count (s_fill
, ignore
);
7062 check_literals (2, 0);
7065 /* Handle the section changing pseudo-ops. These call through to the
7066 normal implementations, but they dump the literal pool first. */
7069 csky_s_text (int ignore
)
7074 obj_elf_text (ignore
);
7081 csky_s_data (int ignore
)
7086 obj_elf_data (ignore
);
7093 csky_s_section (int ignore
)
7095 /* Scan forwards to find the name of the section. If the section
7096 being switched to is ".line" then this is a DWARF1 debug section
7097 which is arbitrarily placed inside generated code. In this case
7098 do not dump the literal pool because it is a) inefficient and
7099 b) would require the generation of extra code to jump around the
7101 char * ilp
= input_line_pointer
;
7103 while (*ilp
!= 0 && ISSPACE (*ilp
))
7106 if (strncmp (ilp
, ".line", 5) == 0
7107 && (ISSPACE (ilp
[5]) || *ilp
== '\n' || *ilp
== '\r'))
7113 obj_elf_section (ignore
);
7116 obj_coff_section (ignore
);
7121 csky_s_bss (int needs_align
)
7124 s_lcomm_bytes (needs_align
);
7129 csky_s_comm (int needs_align
)
7132 obj_elf_common (needs_align
);
7136 /* Handle the .no_literal_dump directive. */
7139 csky_noliteraldump (int ignore ATTRIBUTE_UNUSED
)
7141 do_noliteraldump
= 1;
7142 int insn_num
= get_absolute_expression ();
7143 /* The insn after '.no_literal_dump insn_num' is insn1,
7144 Don't dump literal pool between insn1 and insn(insn_num+1)
7145 The insn cannot be the insn generate literal, like lrw & jsri. */
7146 check_literals (0, insn_num
* 2);
7149 /* Handle the .align directive.
7150 We must check literals before doing alignment. For example, if
7151 '.align n', add (2^n-1) to poolspan and check literals. */
7154 csky_s_align_ptwo (int arg
)
7156 /* Get the .align's first absolute number. */
7157 char * temp_pointer
= input_line_pointer
;
7158 int align
= get_absolute_expression ();
7159 check_literals (0, (1 << align
) - 1);
7160 input_line_pointer
= temp_pointer
;
7166 /* Handle the .stack_size directive. */
7169 csky_stack_size (int arg ATTRIBUTE_UNUSED
)
7172 stack_size_entry
*sse
7173 = (stack_size_entry
*) xcalloc (1, sizeof (stack_size_entry
));
7176 if (exp
.X_op
== O_symbol
)
7177 sse
->function
= exp
.X_add_symbol
;
7180 as_bad (_("the first operand must be a symbol"));
7181 ignore_rest_of_line ();
7187 if (*input_line_pointer
!= ',')
7189 as_bad (_("missing stack size"));
7190 ignore_rest_of_line ();
7195 ++input_line_pointer
;
7197 if (exp
.X_op
== O_constant
)
7199 if (exp
.X_add_number
< 0 || exp
.X_add_number
> (offsetT
)0xffffffff)
7202 as_bad (_("value not in range [0, 0xffffffff]"));
7203 ignore_rest_of_line ();
7208 sse
->stack_size
= exp
.X_add_number
;
7212 as_bad (_("operand must be a constant"));
7213 ignore_rest_of_line ();
7218 if (*last_stack_size_data
!= NULL
)
7219 last_stack_size_data
= &((*last_stack_size_data
)->next
);
7221 *last_stack_size_data
= sse
;
7224 /* This table describes all the machine specific pseudo-ops the assembler
7225 has to support. The fields are:
7226 pseudo-op name without dot
7227 function to call to execute this pseudo-op
7228 Integer arg to pass to the function. */
7230 const pseudo_typeS md_pseudo_table
[] =
7232 { "export", s_globl
, 0 },
7233 { "import", s_ignore
, 0 },
7234 { "literals", csky_s_literals
, 0 },
7235 { "page", listing_eject
, 0 },
7237 /* The following are to intercept the placement of data into the text
7238 section (eg addresses for a switch table), so that the space they
7239 occupy can be taken into account when deciding whether or not to
7240 dump the current literal pool.
7241 XXX - currently we do not cope with the .space and .dcb.d directives. */
7242 { "ascii", csky_stringer
, 8 + 0 },
7243 { "asciz", csky_stringer
, 8 + 1 },
7244 { "byte", csky_cons
, 1 },
7245 { "dc", csky_cons
, 2 },
7246 { "dc.b", csky_cons
, 1 },
7247 { "dc.d", csky_float_cons
, 'd'},
7248 { "dc.l", csky_cons
, 4 },
7249 { "dc.s", csky_float_cons
, 'f'},
7250 { "dc.w", csky_cons
, 2 },
7251 { "dc.x", csky_float_cons
, 'x'},
7252 { "double", csky_float_cons
, 'd'},
7253 { "float", csky_float_cons
, 'f'},
7254 { "hword", csky_cons
, 2 },
7255 { "int", csky_cons
, 4 },
7256 { "long", csky_cons
, 4 },
7257 { "octa", csky_cons
, 16 },
7258 { "quad", csky_cons
, 8 },
7259 { "short", csky_cons
, 2 },
7260 { "single", csky_float_cons
, 'f'},
7261 { "string", csky_stringer
, 8 + 1 },
7262 { "word", csky_cons
, 4 },
7263 { "fill", csky_fill
, 0 },
7265 /* Allow for the effect of section changes. */
7266 { "text", csky_s_text
, 0 },
7267 { "data", csky_s_data
, 0 },
7268 { "bss", csky_s_bss
, 1 },
7270 { "comm", csky_s_comm
, 0 },
7272 { "section", csky_s_section
, 0 },
7273 { "section.s", csky_s_section
, 0 },
7274 { "sect", csky_s_section
, 0 },
7275 { "sect.s", csky_s_section
, 0 },
7276 /* When ".no_literal_dump N" is in front of insn1,
7277 and instruction sequence is:
7282 it means literals will not dump between insn1 and insnN+1
7283 The insn cannot itself generate literal, like lrw & jsri. */
7284 { "no_literal_dump", csky_noliteraldump
, 0 },
7285 { "align", csky_s_align_ptwo
, 0 },
7286 { "stack_size", csky_stack_size
, 0 },
7290 /* Implement tc_cfi_frame_initial_instructions. */
7293 csky_cfi_frame_initial_instructions (void)
7295 int sp_reg
= IS_CSKY_V1 (mach_flag
) ? 0 : 14;
7296 cfi_add_CFA_def_cfa_register (sp_reg
);
7299 /* Implement tc_regname_to_dw2regnum. */
7302 tc_csky_regname_to_dw2regnum (char *regname
)
7307 /* FIXME the reg should be parsed according to
7309 reg_num
= csky_get_reg_val (regname
, &len
);