1 /* tc-csky.c -- Assembler for C-SKY
2 Copyright (C) 1989-2018 Free Software Foundation, Inc.
3 Created by Lifang Xia (lifang_xia@c-sky.com)
4 Contributed by C-SKY Microsystems and Mentor Graphics.
6 This file is part of GAS, the GNU Assembler.
8 GAS is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
13 GAS is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GAS; see the file COPYING. If not, write to the Free
20 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
28 #include "safe-ctype.h"
31 #include "libiberty.h"
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 struct hash_control
*csky_opcodes_hash
;
758 static struct hash_control
*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
&& arch_flag
!= 0)
1185 as_warn (_("-mcpu conflict with -march option, using -mcpu"));
1186 if ((mach_flag
& ~CSKY_ARCH_MASK
) != flags
&& flags
!= 0)
1187 as_warn (_("-mcpu conflict with other model parameters, using -mcpu"));
1189 else if (arch_flag
!= 0)
1190 mach_flag
|= arch_flag
| flags
;
1193 #ifdef TARGET_WITH_CPU
1195 for (; csky_cpus
[i
].name
!= NULL
; i
++)
1197 if (strcmp (TARGET_WITH_CPU
, csky_cpus
[i
].name
) == 0)
1199 mach_flag
|= csky_cpus
[i
].mach_flag
;
1200 isa_flag
= csky_cpus
[i
].isa_flag
;
1206 mach_flag
|= CSKY_ARCH_610
| flags
;
1208 mach_flag
|= CSKY_ARCH_810_BASE
| flags
;
1213 if (IS_CSKY_ARCH_610 (mach_flag
) || IS_CSKY_ARCH_510 (mach_flag
))
1215 if ((mach_flag
& CSKY_ARCH_MP
) && (mach_flag
& CSKY_ARCH_MAC
))
1216 as_fatal ("520/620 conflicts with -mmp option");
1217 else if ((mach_flag
& CSKY_ARCH_MP
) && (mach_flag
& CSKY_ARCH_DSP
))
1218 as_fatal ("510e/610e conflicts with -mmp option");
1219 else if ((mach_flag
& CSKY_ARCH_DSP
) && (mach_flag
& CSKY_ARCH_MAC
))
1220 as_fatal ("520/620 conflicts with 510e/610e or -mdsp option");
1222 if (IS_CSKY_ARCH_510 (mach_flag
) && (mach_flag
& CSKY_ARCH_FLOAT
))
1224 mach_flag
= (mach_flag
& (~CSKY_ARCH_MASK
));
1225 mach_flag
|= CSKY_ARCH_610
;
1228 /* Find bfd_mach_flag, it will set to bfd backend data. */
1229 for (p_arch
= csky_archs
; p_arch
->arch_flag
!= 0; p_arch
++)
1230 if ((mach_flag
& CSKY_ARCH_MASK
) == (p_arch
->arch_flag
& CSKY_ARCH_MASK
))
1232 bfd_mach_flag
= p_arch
->bfd_mach_flag
;
1236 /* Find isa_flag. */
1237 for (p_cpu
= csky_cpus
; p_cpu
->mach_flag
!= 0; p_cpu
++)
1238 if ((mach_flag
& CPU_ARCH_MASK
) == p_cpu
->mach_flag
)
1240 isa_flag
|= p_cpu
->isa_flag
;
1244 /* Check if -mdsp and -medsp conflict. If cpu is ck803, we will
1245 use enhanced dsp instruction. Otherwise, we will use normal dsp. */
1248 if (IS_CSKY_ARCH_803 (mach_flag
))
1250 /* In 803, dspv1 is conflict with dspv2. We keep dspv2. */
1251 if ((dsp_flag
& CSKY_DSP_FLAG_V1
) && (dsp_flag
& CSKY_DSP_FLAG_V2
))
1252 as_warn (_("option -mdsp conflicts with -medsp, only enabling -medsp"));
1253 isa_flag
&= ~(CSKY_ISA_MAC_DSP
| CSKY_ISA_DSP
);
1254 isa_flag
|= CSKY_ISA_DSP_ENHANCE
;
1258 isa_flag
&= ~CSKY_ISA_DSP_ENHANCE
;
1259 as_warn (_("-medsp option is only supported by ck803s, ignoring -medsp"));
1264 if (do_use_branchstub
== -1)
1265 do_use_branchstub
= !IS_CSKY_ARCH_V1 (mach_flag
);
1266 else if (do_use_branchstub
== 1)
1268 if (IS_CSKY_ARCH_V1 (mach_flag
))
1270 as_warn (_("C-SKY ABI v1 (ck510/ck610) does not support -mbranch-stub"));
1271 do_use_branchstub
= 0;
1273 else if (do_force2bsr
== 0)
1275 as_warn (_("-mno-force2bsr is ignored with -mbranch-stub"));
1280 if (IS_CSKY_ARCH_801 (mach_flag
) || IS_CSKY_ARCH_802 (mach_flag
))
1283 as_warn (_("-mno-force2bsr is ignored for ck801/ck802"));
1286 else if (do_force2bsr
== -1)
1287 do_force2bsr
= do_use_branchstub
;
1291 if (IS_CSKY_ARCH_V1 (mach_flag
))
1297 if (do_extend_lrw
== -1)
1299 if (IS_CSKY_ARCH_801 (mach_flag
))
1304 if (IS_CSKY_ARCH_801 (mach_flag
) || IS_CSKY_ARCH_802 (mach_flag
))
1306 if (do_long_jump
> 0)
1307 as_warn (_("-mljump is ignored for ck801/ck802"));
1310 else if (do_long_jump
== -1)
1312 if (do_intr_stack
== -1)
1314 /* control interrupt stack module, 801&802&803 default on
1315 807&810, default off. */
1316 if (IS_CSKY_ARCH_807 (mach_flag
) || IS_CSKY_ARCH_810 (mach_flag
))
1321 /* TODO: add isa_flag(SIMP/CACHE/APS). */
1322 isa_flag
|= (mach_flag
& CSKY_ARCH_MAC
) ? CSKY_ISA_MAC
: 0;
1323 isa_flag
|= (mach_flag
& CSKY_ARCH_MP
) ? CSKY_ISA_MP
: 0;
1324 isa_flag
|= (mach_flag
& CSKY_ARCH_CP
) ? CSKY_ISA_CP
: 0;
1326 /* Set abi flag and get table address. */
1327 if (IS_CSKY_ARCH_V1 (mach_flag
))
1329 mach_flag
= mach_flag
| CSKY_ABI_V1
;
1330 opcode
= csky_v1_opcodes
;
1331 macro
= v1_macros_table
;
1332 SPANPANIC
= v1_SPANPANIC
;
1333 SPANCLOSE
= v1_SPANCLOSE
;
1334 SPANEXIT
= v1_SPANEXIT
;
1335 md_relax_table
= csky_relax_table
;
1339 mach_flag
= mach_flag
| CSKY_ABI_V2
;
1340 opcode
= csky_v2_opcodes
;
1341 macro
= v2_macros_table
;
1342 SPANPANIC
= v2_SPANPANIC
;
1345 SPANCLOSE
= v2_SPANCLOSE_ELRW
;
1346 SPANEXIT
= v2_SPANEXIT_ELRW
;
1350 SPANCLOSE
= v2_SPANCLOSE
;
1351 SPANEXIT
= v2_SPANEXIT
;
1353 md_relax_table
= csky_relax_table
;
1356 /* Establish hash table for opcodes and macros. */
1357 csky_macros_hash
= hash_new ();
1358 csky_opcodes_hash
= hash_new ();
1359 for ( ; opcode
->mnemonic
!= NULL
; opcode
++)
1360 if ((isa_flag
& (opcode
->isa_flag16
| opcode
->isa_flag32
)) != 0)
1361 hash_insert (csky_opcodes_hash
, opcode
->mnemonic
, (char *)opcode
);
1362 for ( ; macro
->name
!= NULL
; macro
++)
1363 if ((isa_flag
& macro
->isa_flag
) != 0)
1364 hash_insert (csky_macros_hash
, macro
->name
, (char *)macro
);
1365 if (do_nolrw
&& (isa_flag
& CSKYV2_ISA_1E2
) != 0)
1366 hash_insert (csky_macros_hash
,
1367 v2_lrw_macro_opcode
.name
,
1368 (char *)&v2_lrw_macro_opcode
);
1369 /* Set e_flag to ELF Head. */
1370 bfd_set_private_flags (stdoutput
, mach_flag
);
1371 /* Set bfd_mach to bfd backend data. */
1372 bfd_set_arch_mach (stdoutput
, bfd_arch_csky
, bfd_mach_flag
);
1375 /* The C-SKY assembler emits mapping symbols $t and $d to mark the
1376 beginning of a sequence of instructions and data (such as a constant pool),
1377 respectively. This is similar to what ARM does. */
1380 make_mapping_symbol (map_state state
, valueT value
, fragS
*frag
)
1383 const char * symname
;
1389 type
= BSF_NO_FLAGS
;
1393 type
= BSF_NO_FLAGS
;
1399 symbolP
= symbol_new (symname
, now_seg
, value
, frag
);
1400 symbol_get_bfdsym (symbolP
)->flags
|= type
| BSF_LOCAL
;
1403 /* We need to keep track of whether we are emitting code or data; this
1404 function switches state and emits a mapping symbol if necessary. */
1407 mapping_state (map_state state
)
1409 map_state current_state
1410 = seg_info (now_seg
)->tc_segment_info_data
.current_state
;
1412 if (current_state
== state
)
1414 else if (current_state
== MAP_UNDEFINED
&& state
== MAP_DATA
)
1416 else if (current_state
== MAP_UNDEFINED
&& state
== MAP_TEXT
)
1418 struct frag
* const frag_first
= seg_info (now_seg
)->frchainP
->frch_root
;
1419 if (frag_now
!= frag_first
|| frag_now_fix () > 0)
1420 make_mapping_symbol (MAP_DATA
, (valueT
) 0, frag_first
);
1423 seg_info (now_seg
)->tc_segment_info_data
.current_state
= state
;
1424 make_mapping_symbol (state
, (valueT
) frag_now_fix (), frag_now
);
1427 /* Dump the literal pool. */
1430 dump_literals (int isforce
)
1432 #define CSKYV1_BR_INSN 0xF000
1433 #define CSKYV2_BR_INSN 0x0400
1436 symbolS
* brarsym
= NULL
;
1438 /* V1 nop encoding: 0x1200 : mov r0, r0. */
1439 static char v1_nop_insn_big
[2] = {0x12, 0x00};
1440 static char v1_nop_insn_little
[2] = {0x00, 0x12};
1445 /* Must we branch around the literal table? */
1449 make_internal_label (brarname
, POOL_END_LABEL
, poolnumber
);
1450 brarsym
= symbol_make (brarname
);
1451 symbol_table_insert (brarsym
);
1452 mapping_state (MAP_TEXT
);
1453 if (IS_CSKY_ARCH_V1 (mach_flag
))
1456 = frag_var (rs_machine_dependent
,
1457 csky_relax_table
[C (UNCD_JUMP_S
, DISP32
)].rlx_length
,
1458 csky_relax_table
[C (UNCD_JUMP_S
, DISP12
)].rlx_length
,
1459 C (UNCD_JUMP_S
, 0), brarsym
, 0, 0);
1460 md_number_to_chars (csky_insn
.output
, CSKYV1_BR_INSN
, 2);
1465 = frag_var (rs_machine_dependent
,
1470 md_number_to_chars (csky_insn
.output
, CSKYV2_BR_INSN
, 2);
1473 /* Make sure that the section is sufficiently aligned and that
1474 the literal table is aligned within it. */
1478 csky_insn
.output
= frag_more (2);
1480 if (IS_CSKY_V1 (mach_flag
))
1481 br_self
= CSKYV1_BR_INSN
| 0x7ff;
1483 br_self
= CSKYV2_BR_INSN
;
1484 md_number_to_chars (csky_insn
.output
, br_self
, 2);
1487 csky_insn
.output
= frag_more (2);
1489 md_number_to_chars (csky_insn
.output
, br_self
, 2);
1492 mapping_state (MAP_DATA
);
1494 record_alignment (now_seg
, 2);
1495 if (IS_CSKY_ARCH_V1 (mach_flag
))
1496 frag_align_pattern (2,
1498 ? v1_nop_insn_big
: v1_nop_insn_little
),
1501 frag_align (2, 0, 3);
1503 colon (S_GET_NAME (poolsym
));
1505 for (i
= 0, p
= litpool
; i
< poolsize
; i
+= (p
->isdouble
? 2 : 1), p
++)
1507 insn_reloc
= p
->r_type
;
1508 if (insn_reloc
== BFD_RELOC_CKCORE_TLS_IE32
1509 || insn_reloc
== BFD_RELOC_CKCORE_TLS_LDM32
1510 || insn_reloc
== BFD_RELOC_CKCORE_TLS_GD32
)
1511 literal_insn_offset
= p
;
1514 if (target_big_endian
)
1516 p
->e
.X_add_number
= p
->dbnum
>> 32;
1517 emit_expr (& p
->e
, 4);
1518 p
->e
.X_add_number
= p
->dbnum
& 0xffffffff;
1519 emit_expr (& p
->e
, 4);
1523 p
->e
.X_add_number
= p
->dbnum
& 0xffffffff;
1524 emit_expr (& p
->e
, 4);
1525 p
->e
.X_add_number
= p
->dbnum
>> 32;
1526 emit_expr (& p
->e
, 4);
1530 emit_expr (& p
->e
, 4);
1533 if (isforce
&& IS_CSKY_ARCH_V2 (mach_flag
))
1535 /* Add one nop insn at end of literal for disassembler. */
1536 mapping_state (MAP_TEXT
);
1537 csky_insn
.output
= frag_more (2);
1538 md_number_to_chars (csky_insn
.output
, CSKYV2_INST_NOP
, 2);
1541 insn_reloc
= BFD_RELOC_NONE
;
1543 if (brarsym
!= NULL
)
1544 colon (S_GET_NAME (brarsym
));
1549 enter_literal (expressionS
*e
,
1551 unsigned char isdouble
,
1556 if (poolsize
>= MAX_POOL_SIZE
- 2)
1558 /* The literal pool is as full as we can handle. We have
1559 to be 2 entries shy of the 1024/4=256 entries because we
1560 have to allow for the branch (2 bytes) and the alignment
1561 (2 bytes before the first insn referencing the pool and
1562 2 bytes before the pool itself) == 6 bytes, rounds up
1565 /* Save the parsed symbol's reloc. */
1566 enum bfd_reloc_code_real last_reloc_before_dump
= insn_reloc
;
1568 insn_reloc
= last_reloc_before_dump
;
1573 /* Create new literal pool. */
1574 if (++ poolnumber
> 0xFFFF)
1575 as_fatal (_("more than 65K literal pools"));
1577 make_internal_label (poolname
, POOL_START_LABEL
, poolnumber
);
1578 poolsym
= symbol_make (poolname
);
1579 symbol_table_insert (poolsym
);
1583 /* Search pool for value so we don't have duplicates. */
1584 for (p
= litpool
, i
= 0; i
< poolsize
; i
+= (p
->isdouble
? 2 : 1), p
++)
1586 if (e
->X_op
== p
->e
.X_op
1587 && e
->X_add_symbol
== p
->e
.X_add_symbol
1588 && e
->X_add_number
== p
->e
.X_add_number
1589 && ispcrel
== p
->ispcrel
1590 && insn_reloc
== p
->r_type
1591 && isdouble
== p
->isdouble
1592 && insn_reloc
!= BFD_RELOC_CKCORE_TLS_GD32
1593 && insn_reloc
!= BFD_RELOC_CKCORE_TLS_LDM32
1594 && insn_reloc
!= BFD_RELOC_CKCORE_TLS_LDO32
1595 && insn_reloc
!= BFD_RELOC_CKCORE_TLS_IE32
1596 && insn_reloc
!= BFD_RELOC_CKCORE_TLS_LE32
)
1603 p
->ispcrel
= ispcrel
;
1605 p
->r_type
= insn_reloc
;
1606 p
->isdouble
= isdouble
;
1610 if (insn_reloc
== BFD_RELOC_CKCORE_TLS_GD32
1611 || insn_reloc
== BFD_RELOC_CKCORE_TLS_LDM32
1612 || insn_reloc
== BFD_RELOC_CKCORE_TLS_IE32
)
1614 p
->tls_addend
.frag
= frag_now
;
1615 p
->tls_addend
.offset
= csky_insn
.output
- frag_now
->fr_literal
;
1616 literal_insn_offset
= p
;
1618 poolsize
+= (p
->isdouble
? 2 : 1);
1622 /* Check whether we must dump the literal pool here.
1623 kind == 0 is any old instruction.
1624 kind > 0 means we just had a control transfer instruction.
1625 kind == 1 means within a function.
1626 kind == 2 means we just left a function.
1628 OFFSET is the length of the insn being processed.
1630 SPANCLOSE and SPANEXIT are smaller numbers than SPANPANIC.
1631 SPANPANIC means that we must dump now.
1632 The dump_literals (1) call inserts a branch around the table, so
1633 we first look to see if its a situation where we won't have to
1634 insert a branch (e.g., the previous instruction was an unconditional
1637 SPANPANIC is the point where we must dump a single-entry pool.
1638 it accounts for alignments and an inserted branch.
1639 the 'poolsize*2' accounts for the scenario where we do:
1640 lrw r1,lit1; lrw r2,lit2; lrw r3,lit3
1641 Note that the 'lit2' reference is 2 bytes further along
1642 but the literal it references will be 4 bytes further along,
1643 so we must consider the poolsize into this equation.
1644 This is slightly over-cautious, but guarantees that we won't
1645 panic because a relocation is too distant. */
1648 check_literals (int kind
, int offset
)
1652 if ((poolspan
> SPANEXIT
|| do_func_dump
)
1654 && (do_br_dump
|| do_func_dump
))
1656 else if (poolspan
> SPANCLOSE
&& (kind
> 0) && do_br_dump
)
1659 >= (SPANPANIC
- (IS_CSKY_ARCH_V1 (mach_flag
) ? poolsize
* 2 : 0)))
1661 /* We have not dumped literal pool before insn1,
1662 and will not dump literal pool between insn1 and insnN+1,
1663 so reset poolspan to original length. */
1664 else if (do_noliteraldump
== 1)
1667 if (do_noliteraldump
== 1)
1668 do_noliteraldump
= 0;
1671 /* The next group of functions are helpers for parsing various kinds
1672 of instruction operand syntax. */
1674 /* Parse operands of the form
1675 <symbol>@GOTOFF+<nnn>
1676 and similar .plt or .got references.
1678 If we find one, set up the correct relocation in RELOC and copy the
1679 input string, minus the `@GOTOFF' into a malloc'd buffer for
1680 parsing by the calling routine. Return this buffer, and if ADJUST
1681 is non-null set it to the length of the string we removed from the
1682 input line. Otherwise return NULL. */
1685 lex_got (enum bfd_reloc_code_real
*reloc
,
1691 const enum bfd_reloc_code_real rel
;
1693 static const struct _gotrel gotrel
[] =
1695 { "GOTOFF", BFD_RELOC_CKCORE_GOTOFF
},
1696 { "GOTPC", BFD_RELOC_CKCORE_GOTPC
},
1697 { "GOTTPOFF", BFD_RELOC_CKCORE_TLS_IE32
},
1698 { "GOT", BFD_RELOC_CKCORE_GOT32
},
1699 { "PLT", BFD_RELOC_CKCORE_PLT32
},
1700 { "BTEXT", BFD_RELOC_CKCORE_TOFFSET_LO16
},
1701 { "BDATA", BFD_RELOC_CKCORE_DOFFSET_LO16
},
1702 { "TLSGD32", BFD_RELOC_CKCORE_TLS_GD32
},
1703 { "TLSLDM32", BFD_RELOC_CKCORE_TLS_LDM32
},
1704 { "TLSLDO32", BFD_RELOC_CKCORE_TLS_LDO32
},
1705 { "TPOFF", BFD_RELOC_CKCORE_TLS_LE32
}
1711 for (cp
= input_line_pointer
; *cp
!= '@'; cp
++)
1712 if (is_end_of_line
[(unsigned char) *cp
])
1715 for (j
= 0; j
< sizeof (gotrel
) / sizeof (gotrel
[0]); j
++)
1717 int len
= strlen (gotrel
[j
].str
);
1719 if (strncasecmp (cp
+ 1, gotrel
[j
].str
, len
) == 0)
1721 if (gotrel
[j
].rel
!= 0)
1723 *reloc
= gotrel
[j
].rel
;
1727 /* input_line_pointer is the str pointer after relocation
1728 token like @GOTOFF. */
1729 input_line_pointer
+= len
+ 1;
1730 return input_line_pointer
;
1733 csky_show_error (ERROR_RELOC_ILLEGAL
, 0,
1734 (void *)gotrel
[j
].str
, NULL
);
1739 /* Might be a symbol version string. Don't as_bad here. */
1743 /* Parse an expression, returning it in E. */
1746 parse_exp (char *s
, expressionS
*e
)
1751 /* Skip whitespace. */
1752 while (ISSPACE (*s
))
1755 save
= input_line_pointer
;
1756 input_line_pointer
= s
;
1758 insn_reloc
= BFD_RELOC_NONE
;
1760 lex_got (&insn_reloc
, NULL
);
1762 if (e
->X_op
== O_absent
)
1763 SET_ERROR_NUMBER (ERROR_MISSING_OPERAND
, NULL
);
1765 new = input_line_pointer
;
1766 input_line_pointer
= save
;
1771 /* Parse a floating-point number from S into its target representation.
1772 If ISDOUBLE is true, return the result in *DBNUM; otherwise
1773 it's returned in E->X_add_number. Returns the result of advancing
1774 S past the constant. */
1777 parse_fexp (char *s
, expressionS
*e
, unsigned char isdouble
, uint64_t *dbnum
)
1779 int length
; /* Number of chars in an object. */
1780 register char const *err
= NULL
; /* Error from scanning float literal. */
1783 /* input_line_pointer->1st char of a flonum (we hope!). */
1784 input_line_pointer
= s
;
1786 if (input_line_pointer
[0] == '0'
1787 && ISALPHA (input_line_pointer
[1]))
1788 input_line_pointer
+= 2;
1791 err
= md_atof ('d', temp
, &length
);
1793 err
= md_atof ('f', temp
, &length
);
1795 know (err
!= NULL
|| length
> 0);
1797 if (!is_end_of_line
[(unsigned char) *input_line_pointer
])
1798 as_bad (_("immediate operand required"));
1799 while (!is_end_of_line
[(unsigned char) *input_line_pointer
])
1800 input_line_pointer
++;
1804 as_bad (_("bad floating literal: %s"), err
);
1805 while (!is_end_of_line
[(unsigned char) *input_line_pointer
])
1806 input_line_pointer
++;
1807 know (is_end_of_line
[(unsigned char) input_line_pointer
[-1]]);
1808 return input_line_pointer
;
1811 e
->X_add_symbol
= 0x0;
1812 e
->X_op_symbol
= 0x0;
1813 e
->X_op
= O_constant
;
1820 if (target_big_endian
)
1821 fnum
= (((temp
[0] << 24) & 0xffffffff)
1822 | ((temp
[1] << 16) & 0xffffff)
1823 | ((temp
[2] << 8) & 0xffff)
1824 | (temp
[3] & 0xff));
1826 fnum
= (((temp
[3] << 24) & 0xffffffff)
1827 | ((temp
[2] << 16) & 0xffffff)
1828 | ((temp
[1] << 8) & 0xffff)
1829 | (temp
[0] & 0xff));
1830 e
->X_add_number
= fnum
; }
1833 if (target_big_endian
)
1835 *dbnum
= (((temp
[0] << 24) & 0xffffffff)
1836 | ((temp
[1] << 16) & 0xffffff)
1837 | ((temp
[2] << 8) & 0xffff)
1838 | (temp
[3] & 0xff));
1840 *dbnum
|= (((temp
[4] << 24) & 0xffffffff)
1841 | ((temp
[5] << 16) & 0xffffff)
1842 | ((temp
[6] << 8) & 0xffff)
1843 | (temp
[7] & 0xff));
1847 *dbnum
= (((temp
[7] << 24) & 0xffffffff)
1848 | ((temp
[6] << 16) & 0xffffff)
1849 | ((temp
[5] << 8) & 0xffff)
1850 | (temp
[4] & 0xff));
1852 *dbnum
|= (((temp
[3] << 24) & 0xffffffff)
1853 | ((temp
[2] << 16) & 0xffffff)
1854 | ((temp
[1] << 8) & 0xffff)
1855 | (temp
[0] & 0xff));
1858 return input_line_pointer
;
1865 long reg ATTRIBUTE_UNUSED
)
1871 /* Indicate nothing there. */
1872 ep
->X_op
= O_absent
;
1876 s
= parse_exp (s
+ 1, &e
);
1881 SET_ERROR_NUMBER (ERROR_MISSING_RSQUARE_BRACKETS
, NULL
);
1888 s
= parse_exp (s
, &e
);
1889 if (BFD_RELOC_CKCORE_DOFFSET_LO16
== insn_reloc
1890 || BFD_RELOC_CKCORE_TOFFSET_LO16
== insn_reloc
)
1898 /* If the instruction has work, literal handling is in the work. */
1899 if (!csky_insn
.opcode
->work
)
1901 n
= enter_literal (&e
, ispcrel
, 0, 0);
1905 /* Create a reference to pool entry. */
1906 ep
->X_op
= O_symbol
;
1907 ep
->X_add_symbol
= poolsym
;
1908 ep
->X_add_number
= n
<< 2;
1915 parse_rtf (char *s
, int ispcrel
, expressionS
*ep
)
1921 /* Indicate nothing there. */
1922 ep
->X_op
= O_absent
;
1926 s
= parse_exp (s
+ 1, & e
);
1931 as_bad (_("missing ']'"));
1939 if (strstr (csky_insn
.opcode
->mnemonic
, "flrws"))
1941 s
= parse_fexp (s
, &e
, 0, &dbnum
);
1942 n
= enter_literal (&e
, ispcrel
, 0, dbnum
);
1944 else if (strstr (csky_insn
.opcode
->mnemonic
, "flrwd"))
1946 s
= parse_fexp (s
, &e
, 1, &dbnum
);
1947 n
= enter_literal (&e
, ispcrel
, 1, dbnum
);
1950 as_bad (_("unrecognized opcode"));
1955 /* Create a reference to pool entry. */
1956 ep
->X_op
= O_symbol
;
1957 ep
->X_add_symbol
= poolsym
;
1958 ep
->X_add_number
= n
<< 2;
1964 parse_type_ctrlreg (char** oper
)
1969 if (TOLOWER (*(*oper
+ 0)) == 'c'
1970 && TOLOWER (*(*oper
+ 1)) == 'r'
1971 && ISDIGIT (*(*oper
+ 2)))
1973 /* The control registers are named crxx. */
1974 i
= *(*oper
+ 2) - 0x30;
1975 i
= ISDIGIT (*(*oper
+ 3)) ? (*(*oper
+ 3) - 0x30) + 10 * i
: i
;
1976 len
= ISDIGIT (*(*oper
+ 3)) ? 4 : 3;
1979 else if (!(TOLOWER (*(*oper
+ 0)) == 'c'
1980 && TOLOWER (*(*oper
+ 1)) == 'r'))
1982 /* The control registers are aliased. */
1983 struct csky_reg
*reg
= &csky_ctrl_regs
[0];
1986 if (memcmp (*oper
, reg
->name
, strlen (reg
->name
)) == 0
1987 && (!reg
->flag
|| (isa_flag
& reg
->flag
)))
1990 len
= strlen (reg
->name
);
1998 if (IS_CSKY_V2 (mach_flag
))
2010 if (s
[0] == 'c' && s
[1] == 'r')
2016 if (s
[0] == '3' && s
[1] >= '0' && s
[1] <= '1')
2018 crx
= 30 + s
[1] - '0';
2021 else if (s
[0] == '2' && s
[1] >= '0' && s
[1] <= '9')
2023 crx
= 20 + s
[1] - '0';
2026 else if (s
[0] == '1' && s
[1] >= '0' && s
[1] <= '9')
2028 crx
= 10 + s
[1] - '0';
2031 else if (s
[0] >= '0' && s
[0] <= '9')
2038 SET_ERROR_NUMBER (ERROR_REG_OVER_RANGE
, "control");
2045 SET_ERROR_NUMBER (ERROR_CREG_ILLEGAL
, NULL
);
2049 while (*pS
!= '>' && !is_end_of_line
[(unsigned char) *pS
])
2055 /* Error. Missing '>'. */
2056 SET_ERROR_NUMBER (ERROR_MISSING_RANGLE_BRACKETS
, NULL
);
2060 s
= parse_exp (s
, &e
);
2061 if (e
.X_op
== O_constant
2062 && e
.X_add_number
>= 0
2063 && e
.X_add_number
<= 31)
2066 sel
= e
.X_add_number
;
2073 /* Error. Missing '<'. */
2074 SET_ERROR_NUMBER (ERROR_MISSING_LANGLE_BRACKETS
, NULL
);
2080 SET_ERROR_NUMBER (ERROR_CREG_ILLEGAL
, NULL
);
2084 i
= (sel
<< 5) | crx
;
2086 csky_insn
.val
[csky_insn
.idx
++] = i
;
2091 is_reg_sp_with_bracket (char **oper
)
2097 if (IS_CSKY_V1 (mach_flag
))
2105 regs
= csky_general_reg
;
2106 len
= strlen (regs
[sp_idx
]);
2107 if (memcmp (*oper
, regs
[sp_idx
], len
) == 0)
2113 csky_insn
.val
[csky_insn
.idx
++] = sp_idx
;
2118 if (IS_CSKY_V1 (mach_flag
))
2119 regs
= cskyv1_general_alias_reg
;
2121 regs
= cskyv2_general_alias_reg
;
2122 len
= strlen (regs
[sp_idx
]);
2123 if (memcmp (*oper
, regs
[sp_idx
], len
) == 0)
2136 is_reg_sp (char **oper
)
2141 if (IS_CSKY_V1 (mach_flag
))
2146 regs
= csky_general_reg
;
2147 len
= strlen (regs
[sp_idx
]);
2148 if (memcmp (*oper
, regs
[sp_idx
], len
) == 0)
2151 csky_insn
.val
[csky_insn
.idx
++] = sp_idx
;
2156 if (IS_CSKY_V1 (mach_flag
))
2157 regs
= cskyv1_general_alias_reg
;
2159 regs
= cskyv2_general_alias_reg
;
2160 len
= strlen (regs
[sp_idx
]);
2161 if (memcmp (*oper
, regs
[sp_idx
], len
) == 0)
2164 csky_insn
.val
[csky_insn
.idx
++] = sp_idx
;
2172 csky_get_reg_val (char *str
, int *len
)
2175 if (TOLOWER (str
[0]) == 'r' && ISDIGIT (str
[1]))
2177 if (ISDIGIT (str
[1]) && ISDIGIT (str
[2]))
2179 reg
= (str
[1] - '0') * 10 + str
[2] - '0';
2182 else if (ISDIGIT (str
[1]))
2190 else if (TOLOWER (str
[0]) == 's' && TOLOWER (str
[1]) == 'p'
2191 && !ISDIGIT (str
[2]))
2194 if (IS_CSKY_V1 (mach_flag
))
2200 else if (TOLOWER (str
[0]) == 'g' && TOLOWER (str
[1]) == 'b'
2201 && !ISDIGIT (str
[2]))
2204 if (IS_CSKY_V1 (mach_flag
))
2210 else if (TOLOWER (str
[0]) == 'l' && TOLOWER (str
[1]) == 'r'
2211 && !ISDIGIT (str
[2]))
2217 else if (TOLOWER (str
[0]) == 't' && TOLOWER (str
[1]) == 'l'
2218 && TOLOWER (str
[2]) == 's' && !ISDIGIT (str
[3]))
2221 if (IS_CSKY_V2 (mach_flag
))
2227 else if (TOLOWER (str
[0]) == 's' && TOLOWER (str
[1]) == 'v'
2228 && TOLOWER (str
[2]) == 'b' && TOLOWER (str
[3]) == 'r')
2230 if (IS_CSKY_V2 (mach_flag
))
2236 else if (TOLOWER (str
[0]) == 'a')
2238 if (ISDIGIT (str
[1]) && !ISDIGIT (str
[2]))
2240 if (IS_CSKY_V1 (mach_flag
) && (str
[1] - '0') <= 5)
2242 reg
= 2 + str
[1] - '0';
2243 else if (IS_CSKY_V2 (mach_flag
) && (str
[1] - '0') <= 3)
2251 else if (TOLOWER (str
[0]) == 't')
2253 if (IS_CSKY_V2 (mach_flag
))
2255 reg
= atoi (str
+ 1);
2268 else if (TOLOWER (str
[0]) == 'l')
2270 if (str
[1] < '0' || str
[1] > '9')
2272 if (IS_CSKY_V2 (mach_flag
))
2274 reg
= atoi (str
+ 1);
2286 reg
= atoi (str
+ 1);
2289 /* l0 - l6 -> r8 - r13. */
2297 /* Is register available? */
2298 if (IS_CSKY_ARCH_801 (mach_flag
))
2300 /* CK801 register range is r0-r8 & r13-r15. */
2301 if ((reg
> 8 && reg
< 13) || reg
> 15)
2303 SET_ERROR_NUMBER (ERROR_REG_OVER_RANGE
, reg
);
2307 else if (IS_CSKY_ARCH_802 (mach_flag
))
2309 /* CK802 register range is r0-r15 & r23-r25 & r30. */
2310 if ((reg
> 15 && reg
< 23) || (reg
> 25 && reg
!= 30))
2312 SET_ERROR_NUMBER (ERROR_REG_OVER_RANGE
, reg
);
2316 else if (reg
> 31 || reg
< 0)
2318 SET_ERROR_NUMBER (ERROR_REG_OVER_RANGE
, reg
);
2326 csky_get_freg_val (char *str
, int *len
)
2330 if ((str
[0] == 'v' || str
[0] == 'f') && (str
[1] == 'r'))
2332 /* It is fpu register. */
2334 while (ISDIGIT (*s
))
2336 reg
= reg
* 10 + (*s
) - '0';
2349 is_reglist_legal (char **oper
)
2354 reg1
= csky_get_reg_val (*oper
, &len
);
2357 if (reg1
== -1 || (IS_CSKY_V1 (mach_flag
) && (reg1
== 0 || reg1
== 15)))
2359 SET_ERROR_NUMBER (ERROR_REG_FORMAT
,
2360 "The first reg must not be r0/r15");
2366 SET_ERROR_NUMBER (ERROR_REG_FORMAT
,
2367 "The operand format must be rx-ry");
2372 reg2
= csky_get_reg_val (*oper
, &len
);
2375 if (reg2
== -1 || (IS_CSKY_V1 (mach_flag
) && reg1
== 15))
2377 SET_ERROR_NUMBER (ERROR_REG_FORMAT
,
2378 "The operand format must be r15 in C-SKY V1");
2381 if (IS_CSKY_V2 (mach_flag
))
2385 SET_ERROR_NUMBER (ERROR_REG_FORMAT
,
2386 "The operand format must be rx-ry (rx < ry)");
2393 csky_insn
.val
[csky_insn
.idx
++] = reg1
;
2398 is_freglist_legal (char **oper
)
2403 reg1
= csky_get_freg_val (*oper
, &len
);
2408 SET_ERROR_NUMBER (ERROR_REG_FORMAT
,
2409 "The fpu register format is not recognized.");
2415 SET_ERROR_NUMBER (ERROR_REG_FORMAT
,
2416 "The operand format must be vrx-vry/frx-fry.");
2421 reg2
= csky_get_freg_val (*oper
, &len
);
2426 SET_ERROR_NUMBER (ERROR_REG_FORMAT
,
2427 "The fpu register format is not recognized.");
2432 SET_ERROR_NUMBER (ERROR_REG_FORMAT
,
2433 "The operand format must be rx-ry(rx < ry)");
2439 csky_insn
.val
[csky_insn
.idx
++] = reg1
;
2444 is_reglist_dash_comma_legal (char **oper
, struct operand
*oprnd
)
2452 while (**oper
!= '\n' && **oper
!= '\0')
2454 reg1
= csky_get_reg_val (*oper
, &len
);
2457 SET_ERROR_NUMBER (ERROR_REG_LIST
, NULL
);
2460 flag
|= (1 << reg1
);
2465 reg2
= csky_get_reg_val (*oper
, &len
);
2468 SET_ERROR_NUMBER (ERROR_REG_LIST
, NULL
);
2474 SET_ERROR_NUMBER (ERROR_REG_LIST
, NULL
);
2477 while (reg2
>= reg1
)
2479 flag
|= (1 << reg2
);
2486 /* The reglist: r4-r11, r15, r16-r17, r28. */
2487 #define REGLIST_BITS 0x10038ff0
2488 if (flag
& ~(REGLIST_BITS
))
2490 SET_ERROR_NUMBER (ERROR_REG_LIST
, NULL
);
2497 if (flag
& (1 << i
))
2504 if (flag
& (1 << 15))
2507 /* Check r16-r17. */
2512 if (flag
& (1 << i
))
2516 list
|= (temp
<< 5);
2519 if (flag
& (1 << 28))
2521 if (oprnd
->mask
== OPRND_MASK_0_4
&& (list
& ~OPRND_MASK_0_4
))
2523 SET_ERROR_NUMBER (ERROR_REG_LIST
, NULL
);
2526 csky_insn
.val
[csky_insn
.idx
++] = list
;
2531 is_reg_lshift_illegal (char **oper
, int is_float
)
2536 reg
= csky_get_reg_val (*oper
, &len
);
2539 SET_ERROR_NUMBER (ERROR_REG_FORMAT
, "The register must be r0-r31.");
2544 if ((*oper
)[0] != '<' || (*oper
)[1] != '<')
2546 SET_ERROR_NUMBER (ERROR_UNDEFINE
,
2547 "Operand format error; should be (rx, ry << n)");
2553 char *new_oper
= parse_exp (*oper
, &e
);
2554 if (e
.X_op
== O_constant
)
2557 /* The immediate must be in [0, 3]. */
2558 if (e
.X_add_number
< 0 || e
.X_add_number
> 3)
2560 SET_ERROR_NUMBER (ERROR_IMM_OVERFLOW
, NULL
);
2566 SET_ERROR_NUMBER (ERROR_EXP_CONSTANT
, NULL
);
2570 value
= (reg
<< 2) | e
.X_add_number
;
2572 value
= (reg
<< 5) | (1 << e
.X_add_number
);
2573 csky_insn
.val
[csky_insn
.idx
++] = value
;
2579 is_imm_over_range (char **oper
, int min
, int max
, int ext
)
2582 bfd_boolean ret
= FALSE
;
2583 char *new_oper
= parse_exp (*oper
, &e
);
2584 if (e
.X_op
== O_constant
)
2588 if ((int)e
.X_add_number
!= ext
2589 && (e
.X_add_number
< min
|| e
.X_add_number
> max
))
2592 SET_ERROR_NUMBER (ERROR_IMM_OVERFLOW
, NULL
);
2594 csky_insn
.val
[csky_insn
.idx
++] = e
.X_add_number
;
2601 is_oimm_over_range (char **oper
, int min
, int max
)
2604 bfd_boolean ret
= FALSE
;
2605 char *new_oper
= parse_exp (*oper
, &e
);
2606 if (e
.X_op
== O_constant
)
2610 if (e
.X_add_number
< min
|| e
.X_add_number
> max
)
2613 SET_ERROR_NUMBER (ERROR_IMM_OVERFLOW
, NULL
);
2615 csky_insn
.val
[csky_insn
.idx
++] = e
.X_add_number
- 1;
2622 is_psr_bit (char **oper
)
2624 const struct psrbit
*bits
;
2627 if (IS_CSKY_V1 (mach_flag
))
2628 bits
= cskyv1_psr_bits
;
2630 bits
= cskyv2_psr_bits
;
2632 while (bits
[i
].name
!= NULL
)
2634 if (bits
[i
].isa
&& !(bits
[i
].isa
& isa_flag
))
2639 if (strncasecmp (*oper
, bits
[i
].name
, strlen (bits
[i
].name
)) == 0)
2641 *oper
+= strlen (bits
[i
].name
);
2642 csky_insn
.val
[csky_insn
.idx
] |= bits
[i
].value
;
2647 SET_ERROR_NUMBER (ERROR_OPCODE_PSRBIT
, NULL
);
2652 parse_type_cpidx (char** oper
)
2656 if (s
[0] == 'c' && s
[1] == 'p')
2658 if (ISDIGIT (s
[2]) && ISDIGIT (s
[3]) && ! ISDIGIT (s
[4]))
2660 idx
= (s
[2] - '0') * 10 + s
[3] - '0';
2663 else if (ISDIGIT (s
[2]) && !ISDIGIT (s
[3]))
2674 *oper
= parse_exp (*oper
, &e
);
2675 if (e
.X_op
!= O_constant
)
2677 /* Can not recognize the operand. */
2680 idx
= e
.X_add_number
;
2683 csky_insn
.val
[csky_insn
.idx
++] = idx
;
2689 parse_type_cpreg (char** oper
)
2691 const char **regs
= csky_cp_reg
;
2695 for (i
= 0; i
< (int)(sizeof (csky_cp_reg
) / sizeof (char *)); i
++)
2697 len
= strlen (regs
[i
]);
2698 if (memcmp (*oper
, regs
[i
], len
) == 0 && !ISDIGIT (*(*oper
+ len
)))
2701 csky_insn
.val
[csky_insn
.idx
++] = i
;
2705 SET_ERROR_NUMBER (ERROR_CPREG_ILLEGAL
, *oper
);
2710 parse_type_cpcreg (char** oper
)
2715 regs
= csky_cp_creg
;
2716 for (i
= 0; i
< (int)(sizeof (csky_cp_creg
) / sizeof (char *)); i
++)
2718 len
= strlen (regs
[i
]);
2719 if (memcmp (*oper
, regs
[i
], len
) == 0 && !ISDIGIT (*(*oper
+ len
)))
2722 csky_insn
.val
[csky_insn
.idx
++] = i
;
2726 SET_ERROR_NUMBER (ERROR_CPREG_ILLEGAL
, *oper
);
2731 parse_type_areg (char** oper
)
2735 i
= csky_get_reg_val (*oper
, &len
);
2738 SET_ERROR_NUMBER (ERROR_GREG_ILLEGAL
, NULL
);
2742 csky_insn
.val
[csky_insn
.idx
++] = i
;
2748 parse_type_freg (char** oper
, int even
)
2752 reg
= csky_get_freg_val (*oper
, &len
);
2755 SET_ERROR_NUMBER (ERROR_REG_FORMAT
,
2756 "The fpu register format is not recognized.");
2760 csky_insn
.opcode_end
= *oper
;
2761 if (even
&& reg
& 0x1)
2763 SET_ERROR_NUMBER (ERROR_EXP_EVEN_FREG
, NULL
);
2766 csky_insn
.val
[csky_insn
.idx
++] = reg
;
2771 parse_ldst_imm (char **oper
, struct csky_opcode_info
*op ATTRIBUTE_UNUSED
,
2772 struct operand
*oprnd
)
2774 unsigned int mask
= oprnd
->mask
;
2778 shift
= oprnd
->shift
;
2788 if (**oper
== '\0' || **oper
== ')')
2790 csky_insn
.val
[csky_insn
.idx
++] = 0;
2795 *oper
= parse_exp (*oper
, &e
);
2796 if (e
.X_op
!= O_constant
)
2797 /* Not a constant. */
2799 else if (e
.X_add_number
< 0 || e
.X_add_number
>= max
)
2802 SET_ERROR_NUMBER (ERROR_IMM_OVERFLOW
, NULL
);
2805 if ((e
.X_add_number
% (1 << shift
)) != 0)
2808 SET_ERROR_NUMBER (ERROR_OFFSET_UNALIGNED
, ((unsigned long)1 << shift
));
2812 csky_insn
.val
[csky_insn
.idx
++] = e
.X_add_number
>> shift
;
2819 csky_count_operands (char *str
)
2821 char *oper_end
= str
;
2822 unsigned int oprnd_num
;
2823 int bracket_cnt
= 0;
2825 if (is_end_of_line
[(unsigned char) *oper_end
])
2830 /* Count how many operands. */
2832 while (!is_end_of_line
[(unsigned char) *oper_end
])
2834 if (*oper_end
== '(' || *oper_end
== '<')
2840 if (*oper_end
== ')' || *oper_end
== '>')
2846 if (!bracket_cnt
&& *oper_end
== ',')
2853 /* End of the operand parsing helper functions. */
2855 /* Parse the opcode part of an instruction. Fill in the csky_insn
2856 state and return true on success, false otherwise. */
2859 parse_opcode (char *str
)
2861 #define IS_OPCODE32F(a) (*(a - 2) == '3' && *(a - 1) == '2')
2862 #define IS_OPCODE16F(a) (*(a - 2) == '1' && *(a - 1) == '6')
2864 /* TRUE if this opcode has a suffix, like 'lrw.h'. */
2865 unsigned int has_suffix
= FALSE
;
2866 unsigned int nlen
= 0;
2868 char name
[OPCODE_MAX_LEN
+ 1];
2869 char macro_name
[OPCODE_MAX_LEN
+ 1];
2871 /* Remove space ahead of string. */
2872 while (ISSPACE (*str
))
2876 /* Find the opcode end. */
2877 while (nlen
< OPCODE_MAX_LEN
2878 && !is_end_of_line
[(unsigned char) *opcode_end
]
2879 && *opcode_end
!= ' ')
2881 /* Is csky force 32 or 16 instruction? */
2882 if (IS_CSKY_V2 (mach_flag
)
2883 && *opcode_end
== '.' && has_suffix
== FALSE
)
2886 if (IS_OPCODE32F (opcode_end
))
2888 csky_insn
.flag_force
= INSN_OPCODE32F
;
2891 else if (IS_OPCODE16F (opcode_end
))
2893 csky_insn
.flag_force
= INSN_OPCODE16F
;
2897 name
[nlen
] = *opcode_end
;
2902 /* Is csky force 32 or 16 instruction? */
2903 if (has_suffix
== FALSE
)
2905 if (IS_CSKY_V2 (mach_flag
) && IS_OPCODE32F (opcode_end
))
2907 csky_insn
.flag_force
= INSN_OPCODE32F
;
2910 else if (IS_OPCODE16F (opcode_end
))
2912 csky_insn
.flag_force
= INSN_OPCODE16F
;
2918 /* Generate macro_name for finding hash in macro hash_table. */
2919 if (has_suffix
== TRUE
)
2921 strncpy (macro_name
, str
, nlen
);
2922 macro_name
[nlen
] = '\0';
2924 /* Get csky_insn.opcode_end. */
2925 while (ISSPACE (*opcode_end
))
2927 csky_insn
.opcode_end
= opcode_end
;
2929 /* Count the operands. */
2930 csky_insn
.number
= csky_count_operands (opcode_end
);
2932 /* Find hash by name in csky_macros_hash and csky_opcodes_hash. */
2933 csky_insn
.macro
= (struct csky_macro_info
*) hash_find (csky_macros_hash
,
2935 csky_insn
.opcode
= (struct csky_opcode
*) hash_find (csky_opcodes_hash
,
2938 if (csky_insn
.macro
== NULL
&& csky_insn
.opcode
== NULL
)
2943 /* Main dispatch routine to parse operand OPRND for opcode OP from string
2947 get_operand_value (struct csky_opcode_info
*op
,
2948 char **oper
, struct operand
*oprnd
)
2950 struct soperand
*soprnd
= NULL
;
2951 if (oprnd
->mask
== HAS_SUB_OPERAND
)
2953 /* It has sub operand, it must be like:
2957 We will check the format here. */
2958 soprnd
= (struct soperand
*) oprnd
;
2962 int bracket_cnt
= 0;
2963 if (oprnd
->type
== OPRND_TYPE_BRACKET
)
2968 else if (oprnd
->type
== OPRND_TYPE_ABRACKET
)
2981 SET_ERROR_NUMBER ((oprnd
->type
== OPRND_TYPE_BRACKET
2982 ? ERROR_MISSING_LBRACKET
2983 : ERROR_MISSING_LANGLE_BRACKETS
), NULL
);
2987 /* If the oprnd2 is an immediate, it can not be parsed
2988 that end with ')'/'>'. Modify ')'/'>' to '\0'. */
2989 while ((*s
!= rc
|| bracket_cnt
!= 0) && (*s
!= '\n' && *s
!= '\0'))
3002 SET_ERROR_NUMBER ((oprnd
->type
== OPRND_TYPE_BRACKET
3003 ? ERROR_MISSING_RBRACKET
3004 : ERROR_MISSING_RANGLE_BRACKETS
), NULL
);
3008 if (get_operand_value (op
, oper
, &soprnd
->subs
[0]) == FALSE
)
3015 if (get_operand_value (op
, oper
, &soprnd
->subs
[1]) == FALSE
)
3026 switch (oprnd
->type
)
3028 /* TODO: add opcode type here, log errors in the function.
3029 If REGLIST, then j = csky_insn.number - 1.
3030 If there is needed to parse expressions, it will be
3032 case OPRND_TYPE_CTRLREG
:
3034 return parse_type_ctrlreg (oper
);
3035 case OPRND_TYPE_AREG
:
3036 return parse_type_areg (oper
);
3037 case OPRND_TYPE_FREG
:
3038 case OPRND_TYPE_VREG
:
3039 return parse_type_freg (oper
, 0);
3040 case OPRND_TYPE_FEREG
:
3041 return parse_type_freg (oper
, 1);
3042 case OPRND_TYPE_CPCREG
:
3043 return parse_type_cpcreg (oper
);
3044 case OPRND_TYPE_CPREG
:
3045 return parse_type_cpreg (oper
);
3046 case OPRND_TYPE_CPIDX
:
3047 return parse_type_cpidx (oper
);
3048 case OPRND_TYPE_GREG0_7
:
3049 case OPRND_TYPE_GREG0_15
:
3053 reg
= csky_get_reg_val (*oper
, &len
);
3057 SET_ERROR_NUMBER (ERROR_GREG_ILLEGAL
, NULL
);
3060 else if ((oprnd
->type
== OPRND_TYPE_GREG0_7
&& reg
> 7)
3061 || (oprnd
->type
== OPRND_TYPE_GREG0_15
&& reg
> 15))
3063 SET_ERROR_NUMBER (ERROR_REG_OVER_RANGE
, reg
);
3067 csky_insn
.val
[csky_insn
.idx
++] = reg
;
3070 case OPRND_TYPE_REGnsplr
:
3074 reg
= csky_get_reg_val (*oper
, &len
);
3077 || (IS_CSKY_V1 (mach_flag
)
3078 && (reg
== V1_REG_SP
|| reg
== V1_REG_LR
)))
3080 SET_ERROR_NUMBER (ERROR_REG_OVER_RANGE
, reg
);
3083 csky_insn
.val
[csky_insn
.idx
++] = reg
;
3087 case OPRND_TYPE_REGnr4_r7
:
3093 reg
= csky_get_reg_val (*oper
, &len
);
3094 if (reg
== -1 || (reg
<= 7 && reg
>= 4))
3097 csky_insn
.val
[csky_insn
.idx
++] = reg
;
3104 case OPRND_TYPE_REGr4_r7
:
3105 if (memcmp (*oper
, "r4-r7", sizeof ("r4-r7") - 1) == 0)
3107 *oper
+= sizeof ("r4-r7") - 1;
3108 csky_insn
.val
[csky_insn
.idx
++] = 0;
3111 SET_ERROR_NUMBER (ERROR_OPCODE_ILLEGAL
, NULL
);
3113 case OPRND_TYPE_IMM_LDST
:
3114 return parse_ldst_imm (oper
, op
, oprnd
);
3115 case OPRND_TYPE_IMM_FLDST
:
3116 return parse_ldst_imm (oper
, op
, oprnd
);
3117 case OPRND_TYPE_IMM1b
:
3118 return is_imm_over_range (oper
, 0, 1, -1);
3119 case OPRND_TYPE_IMM2b
:
3120 return is_imm_over_range (oper
, 0, 3, -1);
3121 case OPRND_TYPE_IMM2b_JMPIX
:
3122 /* ck802j support jmpix16, but not support jmpix32. */
3123 if (IS_CSKY_ARCH_802 (mach_flag
)
3124 && (op
->opcode
& 0xffff0000) != 0)
3126 SET_ERROR_NUMBER (ERROR_OPCODE_ILLEGAL
, NULL
);
3129 *oper
= parse_exp (*oper
, &csky_insn
.e1
);
3130 if (csky_insn
.e1
.X_op
== O_constant
)
3132 csky_insn
.opcode_end
= *oper
;
3133 if (csky_insn
.e1
.X_add_number
& 0x7)
3135 SET_ERROR_NUMBER (ERROR_JMPIX_OVER_RANGE
, NULL
);
3138 csky_insn
.val
[csky_insn
.idx
++]
3139 = (csky_insn
.e1
.X_add_number
>> 3) - 2;
3142 case OPRND_TYPE_IMM4b
:
3143 return is_imm_over_range (oper
, 0, 15, -1);
3145 case OPRND_TYPE_IMM5b
:
3146 return is_imm_over_range (oper
, 0, 31, -1);
3147 /* This type for "bgeni" in csky v1 ISA. */
3148 case OPRND_TYPE_IMM5b_7_31
:
3149 if (is_imm_over_range (oper
, 0, 31, -1))
3151 int val
= csky_insn
.val
[csky_insn
.idx
- 1];
3152 /* immediate values of 0 -> 6 translate to movi. */
3155 const char *name
= "movi";
3156 csky_insn
.opcode
= (struct csky_opcode
*)
3157 hash_find (csky_opcodes_hash
, name
);
3158 csky_insn
.val
[csky_insn
.idx
- 1] = 1 << val
;
3165 case OPRND_TYPE_IMM5b_1_31
:
3166 return is_imm_over_range (oper
, 1, 31, -1);
3167 case OPRND_TYPE_IMM5b_POWER
:
3168 if (is_imm_over_range (oper
, 1, ~(1 << 31), 1 << 31))
3171 int val
= csky_insn
.val
[csky_insn
.idx
- 1];
3172 log
= csky_log_2 (val
);
3173 csky_insn
.val
[csky_insn
.idx
- 1] = log
;
3174 return (log
== -1 ? FALSE
: TRUE
);
3179 /* This type for "mgeni" in csky v1 ISA. */
3180 case OPRND_TYPE_IMM5b_7_31_POWER
:
3181 if (is_imm_over_range (oper
, 1, ~(1 << 31), 1 << 31))
3184 int val
= csky_insn
.val
[csky_insn
.idx
- 1];
3185 log
= csky_log_2 (val
);
3186 /* Immediate values of 0 -> 6 translate to movi. */
3189 const char *name
= "movi";
3190 csky_insn
.opcode
= (struct csky_opcode
*)
3191 hash_find (csky_opcodes_hash
, name
);
3192 as_warn (_("translating mgeni to movi"));
3195 csky_insn
.val
[csky_insn
.idx
- 1] = log
;
3196 return (log
== -1 ? FALSE
: TRUE
);
3201 case OPRND_TYPE_IMM5b_RORI
:
3203 unsigned max_shift
= IS_CSKY_V1 (mach_flag
) ? 31 : 32;
3205 if (is_imm_over_range (oper
, 1, max_shift
, -1))
3207 int i
= csky_insn
.idx
- 1;
3208 csky_insn
.val
[i
] = 32 - csky_insn
.val
[i
];
3215 case OPRND_TYPE_IMM5b_BMASKI
:
3216 /* For csky v1 bmask inst. */
3218 if (!is_imm_over_range (oper
, 8, 31, 0))
3220 unsigned int mask_val
= csky_insn
.val
[csky_insn
.idx
- 1];
3221 if (mask_val
> 0 && mask_val
< 8)
3223 const char *op_movi
= "movi";
3224 csky_insn
.opcode
= (struct csky_opcode
*)
3225 hash_find (csky_opcodes_hash
, op_movi
);
3226 if (csky_insn
.opcode
== NULL
)
3228 csky_insn
.val
[csky_insn
.idx
- 1] = (1 << mask_val
) - 1;
3234 case OPRND_TYPE_IMM8b_BMASKI
:
3235 /* For csky v2 bmask, which will transfer to 16bits movi. */
3236 if (is_imm_over_range (oper
, 1, 8, -1))
3238 unsigned int mask_val
= csky_insn
.val
[csky_insn
.idx
- 1];
3239 csky_insn
.val
[csky_insn
.idx
- 1] = (1 << mask_val
) - 1;
3243 case OPRND_TYPE_OIMM4b
:
3244 return is_oimm_over_range (oper
, 1, 16);
3245 case OPRND_TYPE_OIMM5b
:
3246 return is_oimm_over_range (oper
, 1, 32);
3247 case OPRND_TYPE_OIMM5b_IDLY
:
3248 if (is_imm_over_range (oper
, 0, 32, -1))
3250 /* imm5b for idly n: 0<=n<4, imm5b=3; 4<=n<=32, imm5b=n-1. */
3251 unsigned long imm
= csky_insn
.val
[csky_insn
.idx
- 1];
3254 csky_show_error (WARNING_IDLY
, 0, (void *)imm
, NULL
);
3258 csky_insn
.val
[csky_insn
.idx
- 1] = imm
;
3264 /* For csky v2 bmask inst. */
3265 case OPRND_TYPE_OIMM5b_BMASKI
:
3266 if (!is_oimm_over_range (oper
, 17, 32))
3268 int mask_val
= csky_insn
.val
[csky_insn
.idx
- 1];
3269 if (mask_val
+ 1 == 0)
3271 if (mask_val
> 0 && mask_val
< 16)
3273 const char *op_movi
= "movi";
3274 csky_insn
.opcode
= (struct csky_opcode
*)
3275 hash_find (csky_opcodes_hash
, op_movi
);
3276 if (csky_insn
.opcode
== NULL
)
3278 csky_insn
.val
[csky_insn
.idx
- 1] = (1 << (mask_val
+ 1)) - 1;
3283 case OPRND_TYPE_IMM7b
:
3284 return is_imm_over_range (oper
, 0, 127, -1);
3285 case OPRND_TYPE_IMM8b
:
3286 return is_imm_over_range (oper
, 0, 255, -1);
3287 case OPRND_TYPE_IMM12b
:
3288 return is_imm_over_range (oper
, 0, 4095, -1);
3289 case OPRND_TYPE_IMM15b
:
3290 return is_imm_over_range (oper
, 0, 0xfffff, -1);
3291 case OPRND_TYPE_IMM16b
:
3292 return is_imm_over_range (oper
, 0, 65535, -1);
3293 case OPRND_TYPE_OIMM16b
:
3294 return is_oimm_over_range (oper
, 1, 65536);
3295 case OPRND_TYPE_IMM32b
:
3298 char *new_oper
= parse_exp (*oper
, &e
);
3299 if (e
.X_op
== O_constant
)
3302 csky_insn
.val
[csky_insn
.idx
++] = e
.X_add_number
;
3307 case OPRND_TYPE_IMM16b_MOVIH
:
3308 case OPRND_TYPE_IMM16b_ORI
:
3310 bfd_reloc_code_real_type r
= BFD_RELOC_NONE
;
3313 char * save
= input_line_pointer
;
3314 /* get the reloc type, and set "@GOTxxx" as ' ' */
3315 while (**oper
!= '@' && **oper
!= '\0')
3319 input_line_pointer
= *oper
;
3321 while (*(*oper
+ len
+ 1) != '\0')
3323 **oper
= *(*oper
+ len
+ 1);
3324 *(*oper
+ len
+ 1) = '\0';
3329 input_line_pointer
= save
;
3330 *oper
= parse_exp (curr
, &csky_insn
.e1
);
3333 case OPRND_TYPE_PSR_BITS_LIST
:
3336 if (csky_insn
.number
== 0)
3340 csky_insn
.val
[csky_insn
.idx
] = 0;
3341 if (is_psr_bit (oper
) != FALSE
)
3342 while (**oper
== ',')
3345 if (is_psr_bit (oper
) == FALSE
)
3353 if (ret
== TRUE
&& IS_CSKY_V1 (mach_flag
)
3354 && csky_insn
.val
[csky_insn
.idx
] > 8)
3358 SET_ERROR_NUMBER (ERROR_OPERANDS_ILLEGAL
, csky_insn
.opcode_end
);
3363 /* FPU round mode. */
3364 static const char *round_mode
[] =
3373 for (i
= 0; round_mode
[i
]; i
++)
3374 if (strncasecmp (*oper
, round_mode
[i
], strlen (round_mode
[i
])) == 0)
3376 *oper
+= strlen (round_mode
[i
]);
3377 csky_insn
.val
[csky_insn
.idx
++] = i
;
3383 case OPRND_TYPE_REGLIST_COMMA
:
3384 case OPRND_TYPE_BRACKET
:
3385 /* TODO: using sub operand union. */
3386 case OPRND_TYPE_ABRACKET
:
3387 /* TODO: using sub operand union. */
3388 case OPRND_TYPE_REGLIST_DASH
:
3389 return is_reglist_legal (oper
);
3390 case OPRND_TYPE_FREGLIST_DASH
:
3391 return is_freglist_legal (oper
);
3392 case OPRND_TYPE_AREG_WITH_BRACKET
:
3398 SET_ERROR_NUMBER (ERROR_MISSING_LBRACKET
, NULL
);
3402 reg
= csky_get_reg_val (*oper
, &len
);
3405 SET_ERROR_NUMBER (ERROR_EXP_GREG
, NULL
);
3411 SET_ERROR_NUMBER (ERROR_MISSING_RBRACKET
, NULL
);
3415 csky_insn
.val
[csky_insn
.idx
++] = reg
;
3418 case OPRND_TYPE_REGsp
:
3419 return is_reg_sp (oper
);
3420 case OPRND_TYPE_REGbsp
:
3421 return is_reg_sp_with_bracket (oper
);
3423 case OPRND_TYPE_OFF8b
:
3424 case OPRND_TYPE_OFF16b
:
3425 *oper
= parse_rt (*oper
, 1, &csky_insn
.e1
, -1);
3426 csky_insn
.val
[csky_insn
.idx
++] = 0;
3428 case OPRND_TYPE_LABEL_WITH_BRACKET
:
3429 case OPRND_TYPE_CONSTANT
:
3430 case OPRND_TYPE_ELRW_CONSTANT
:
3432 csky_insn
.val
[csky_insn
.idx
++] = 0;
3434 csky_insn
.val
[csky_insn
.idx
++] = NEED_OUTPUT_LITERAL
;
3435 *oper
= parse_rt (*oper
, 0, &csky_insn
.e1
, -1);
3437 case OPRND_TYPE_FCONSTANT
:
3438 *oper
= parse_rtf (*oper
, 0, &csky_insn
.e1
);
3441 case OPRND_TYPE_SFLOAT
:
3442 case OPRND_TYPE_DFLOAT
:
3443 /* For fmovis and fmovid, which accept a constant float with
3449 *oper
= parse_fexp (*oper
, &csky_insn
.e1
, 1, &dbnum
);
3450 if (csky_insn
.e1
.X_op
== O_absent
)
3453 /* Convert the representation from IEEE double to the 13-bit
3454 encoding used internally for fmovis and fmovid. */
3455 imm4
= 11 - (((dbnum
& 0x7ff0000000000000ULL
) >> 52) - 1023);
3456 /* Check float range. */
3457 if ((dbnum
& 0x00000fffffffffffULL
) || imm4
< 0 || imm4
> 15)
3459 csky_show_error (ERROR_IMM_OVERFLOW
, 2, NULL
, NULL
);
3462 imm8
= (dbnum
& 0x000ff00000000000ULL
) >> 44;
3463 csky_insn
.e1
.X_add_number
3464 = (((imm8
& 0xf) << 4)
3465 | ((imm8
& 0xf0) << 17)
3466 | ((imm4
& 0xf) << 16)
3467 | ((dbnum
& 0x8000000000000000ULL
) >> 43));
3472 case OPRND_TYPE_IMM_OFF18b
:
3473 *oper
= parse_exp (*oper
, &csky_insn
.e1
);
3476 case OPRND_TYPE_BLOOP_OFF4b
:
3477 *oper
= parse_exp (*oper
, &csky_insn
.e2
);
3478 if (csky_insn
.e2
.X_op
== O_symbol
)
3480 csky_insn
.opcode_end
= *oper
;
3486 case OPRND_TYPE_BLOOP_OFF12b
:
3487 case OPRND_TYPE_OFF10b
:
3488 case OPRND_TYPE_OFF11b
:
3489 case OPRND_TYPE_OFF16b_LSL1
:
3490 case OPRND_TYPE_OFF26b
:
3491 *oper
= parse_exp (*oper
, &csky_insn
.e1
);
3492 if (csky_insn
.e1
.X_op
== O_symbol
)
3494 csky_insn
.opcode_end
= *oper
;
3499 /* For xtrb0(1)(2)(3) and div in csky v1 ISA. */
3500 case OPRND_TYPE_REG_r1a
:
3504 reg
= csky_get_reg_val (*oper
, &len
);
3507 SET_ERROR_NUMBER (ERROR_REG_FORMAT
,
3508 "The first operand must be register r1.");
3512 mov_r1_after
= TRUE
;
3514 csky_insn
.opcode_end
= *oper
;
3515 csky_insn
.val
[csky_insn
.idx
++] = reg
;
3518 case OPRND_TYPE_REG_r1b
:
3522 reg
= csky_get_reg_val (*oper
, &len
);
3525 SET_ERROR_NUMBER (ERROR_REG_FORMAT
,
3526 "The second operand must be register r1.");
3531 unsigned int mov_insn
= CSKYV1_INST_MOV_R1_RX
;
3532 mov_insn
|= reg
<< 4;
3533 mov_r1_before
= TRUE
;
3534 csky_insn
.output
= frag_more (2);
3535 dwarf2_emit_insn (0);
3536 md_number_to_chars (csky_insn
.output
, mov_insn
, 2);
3539 csky_insn
.opcode_end
= *oper
;
3540 csky_insn
.val
[csky_insn
.idx
++] = reg
;
3543 case OPRND_TYPE_DUMMY_REG
:
3547 reg
= csky_get_reg_val (*oper
, &len
);
3550 SET_ERROR_NUMBER (ERROR_GREG_ILLEGAL
, NULL
);
3553 if (reg
!= csky_insn
.val
[0])
3555 SET_ERROR_NUMBER (ERROR_REG_FORMAT
,
3556 "The second register must be the same as the first.");
3560 csky_insn
.opcode_end
= *oper
;
3561 csky_insn
.val
[csky_insn
.idx
++] = reg
;
3564 case OPRND_TYPE_2IN1_DUMMY
:
3570 reg
= csky_get_reg_val (*oper
, &len
);
3573 SET_ERROR_NUMBER (ERROR_GREG_ILLEGAL
, NULL
);
3576 /* dummy reg's real type should be same with first operand. */
3577 if (op
->oprnd
.oprnds
[0].type
== OPRND_TYPE_GREG0_15
)
3579 else if (op
->oprnd
.oprnds
[0].type
== OPRND_TYPE_GREG0_7
)
3583 if (reg
< min
|| reg
> max
)
3585 csky_insn
.val
[csky_insn
.idx
++] = reg
;
3586 /* if it is the last operands. */
3587 if (csky_insn
.idx
> 2)
3589 /* For "insn rz, rx, ry", if rx or ry is equal to rz,
3590 we can output the insn like "insn rz, rx". */
3591 if (csky_insn
.val
[0] == csky_insn
.val
[1])
3592 csky_insn
.val
[1] = 0;
3593 else if (csky_insn
.val
[0] == csky_insn
.val
[2])
3594 csky_insn
.val
[2] = 0;
3599 csky_insn
.opcode_end
= *oper
;
3602 case OPRND_TYPE_DUP_GREG0_7
:
3603 case OPRND_TYPE_DUP_GREG0_15
:
3604 case OPRND_TYPE_DUP_AREG
:
3609 unsigned int shift_num
;
3610 if (oprnd
->type
== OPRND_TYPE_DUP_GREG0_7
)
3615 else if (oprnd
->type
== OPRND_TYPE_DUP_GREG0_15
)
3625 reg
= csky_get_reg_val (*oper
, &len
);
3629 SET_ERROR_NUMBER (ERROR_REG_FORMAT
,
3630 "The register must be r0-r31");
3632 SET_ERROR_NUMBER (ERROR_REG_FORMAT
,
3633 "The register must be r0-r15");
3638 SET_ERROR_NUMBER (ERROR_REG_OVER_RANGE
, reg
);
3641 reg
|= reg
<< shift_num
;
3643 csky_insn
.opcode_end
= *oper
;
3644 csky_insn
.val
[csky_insn
.idx
++] = reg
;
3647 case OPRND_TYPE_CONST1
:
3648 *oper
= parse_exp (*oper
, &csky_insn
.e1
);
3649 if (csky_insn
.e1
.X_op
== O_constant
)
3651 csky_insn
.opcode_end
= *oper
;
3652 if (csky_insn
.e1
.X_add_number
!= 1)
3654 csky_insn
.val
[csky_insn
.idx
++] = 1;
3658 case OPRND_TYPE_UNCOND10b
:
3659 case OPRND_TYPE_UNCOND16b
:
3660 *oper
= parse_exp (*oper
, &csky_insn
.e1
);
3661 if (csky_insn
.e1
.X_op
== O_constant
)
3663 input_line_pointer
= *oper
;
3664 csky_insn
.opcode_end
= *oper
;
3665 csky_insn
.relax
.max
= UNCD_DISP16_LEN
;
3666 csky_insn
.relax
.var
= UNCD_DISP10_LEN
;
3667 csky_insn
.relax
.subtype
= UNCD_DISP10
;
3668 csky_insn
.val
[csky_insn
.idx
++] = 0;
3670 case OPRND_TYPE_COND10b
:
3671 case OPRND_TYPE_COND16b
:
3672 *oper
= parse_exp (*oper
, &csky_insn
.e1
);
3673 if (csky_insn
.e1
.X_op
== O_constant
)
3675 input_line_pointer
= *oper
;
3676 csky_insn
.opcode_end
= *oper
;
3677 /* CK801 doesn't have 32-bit bt/bf insns; relax to a short
3678 jump around a 32-bit unconditional branch instead. */
3679 if (IS_CSKY_ARCH_801 (mach_flag
))
3681 csky_insn
.relax
.max
= SCOND_DISP16_LEN
;
3682 csky_insn
.relax
.var
= SCOND_DISP10_LEN
;
3683 csky_insn
.relax
.subtype
= SCOND_DISP10
;
3687 csky_insn
.relax
.max
= COND_DISP16_LEN
;
3688 csky_insn
.relax
.var
= COND_DISP10_LEN
;
3689 csky_insn
.relax
.subtype
= COND_DISP10
;
3691 csky_insn
.val
[csky_insn
.idx
++] = 0;
3693 case OPRND_TYPE_JCOMPZ
:
3694 *oper
= parse_exp (*oper
, &csky_insn
.e1
);
3695 if (csky_insn
.e1
.X_op
== O_constant
)
3697 input_line_pointer
= *oper
;
3698 csky_insn
.opcode_end
= *oper
;
3699 csky_insn
.relax
.max
= JCOMPZ_DISP32_LEN
;
3700 csky_insn
.relax
.var
= JCOMPZ_DISP16_LEN
;
3701 csky_insn
.relax
.subtype
= JCOMPZ_DISP16
;
3702 csky_insn
.max
= JCOMPZ_DISP32_LEN
;
3703 csky_insn
.val
[csky_insn
.idx
++] = 0;
3705 case OPRND_TYPE_JBTF
:
3706 *oper
= parse_exp (*oper
, &csky_insn
.e1
);
3707 input_line_pointer
= *oper
;
3708 csky_insn
.opcode_end
= *oper
;
3709 csky_insn
.relax
.max
= csky_relax_table
[C (COND_JUMP_S
, DISP32
)].rlx_length
;
3710 csky_insn
.relax
.var
= csky_relax_table
[C (COND_JUMP_S
, DISP12
)].rlx_length
;
3711 csky_insn
.relax
.subtype
= C (COND_JUMP_S
, 0);
3712 csky_insn
.val
[csky_insn
.idx
++] = 0;
3713 csky_insn
.max
= C32_LEN_S
+ 2;
3715 case OPRND_TYPE_JBR
:
3716 *oper
= parse_exp (*oper
, &csky_insn
.e1
);
3717 input_line_pointer
= *oper
;
3718 csky_insn
.opcode_end
= *oper
;
3719 csky_insn
.relax
.max
= csky_relax_table
[C (UNCD_JUMP_S
, DISP32
)].rlx_length
;
3720 csky_insn
.relax
.var
= csky_relax_table
[C (UNCD_JUMP_S
, DISP12
)].rlx_length
;
3721 csky_insn
.relax
.subtype
= C (UNCD_JUMP_S
, 0);
3722 csky_insn
.val
[csky_insn
.idx
++] = 0;
3723 csky_insn
.max
= U32_LEN_S
+ 2;
3725 case OPRND_TYPE_JBSR
:
3727 *oper
= parse_exp (*oper
, &csky_insn
.e1
);
3729 *oper
= parse_rt (*oper
, 1, &csky_insn
.e1
, -1);
3730 input_line_pointer
= *oper
;
3731 csky_insn
.opcode_end
= *oper
;
3732 csky_insn
.val
[csky_insn
.idx
++] = 0;
3734 case OPRND_TYPE_REGLIST_DASH_COMMA
:
3735 return is_reglist_dash_comma_legal (oper
, oprnd
);
3737 case OPRND_TYPE_MSB2SIZE
:
3738 case OPRND_TYPE_LSB2SIZE
:
3741 char *new_oper
= parse_exp (*oper
, &e
);
3742 if (e
.X_op
== O_constant
)
3745 if (e
.X_add_number
> 31)
3747 SET_ERROR_NUMBER (ERROR_IMM_OVERFLOW
, NULL
);
3750 csky_insn
.val
[csky_insn
.idx
++] = e
.X_add_number
;
3751 if (oprnd
->type
== OPRND_TYPE_LSB2SIZE
)
3753 if (csky_insn
.val
[csky_insn
.idx
- 1] > csky_insn
.val
[csky_insn
.idx
- 2])
3755 SET_ERROR_NUMBER (ERROR_IMM_OVERFLOW
, NULL
);
3758 csky_insn
.val
[csky_insn
.idx
- 2] -= e
.X_add_number
;
3764 case OPRND_TYPE_AREG_WITH_LSHIFT
:
3765 return is_reg_lshift_illegal (oper
, 0);
3766 case OPRND_TYPE_AREG_WITH_LSHIFT_FPU
:
3767 return is_reg_lshift_illegal (oper
, 1);
3768 case OPRND_TYPE_FREG_WITH_INDEX
:
3769 if (parse_type_freg (oper
, 0))
3774 if (is_imm_over_range (oper
, 0, 0xf, -1))
3778 unsigned int idx
= --csky_insn
.idx
;
3779 unsigned int val
= csky_insn
.val
[idx
];
3781 csky_insn
.val
[idx
- 1] |= val
<< 4;
3785 SET_ERROR_NUMBER (ERROR_MISSING_RSQUARE_BRACKETS
, NULL
);
3789 SET_ERROR_NUMBER (ERROR_MISSING_LSQUARE_BRACKETS
, NULL
);
3800 /* Subroutine of parse_operands. */
3803 parse_operands_op (char *str
, struct csky_opcode_info
*op
)
3810 for (i
= 0; i
< OP_TABLE_NUM
&& op
[i
].operand_num
!= -2; i
++)
3815 /* if operand_num = -1, it is a insn with a REGLIST type operand.i. */
3816 if (!(op
[i
].operand_num
== csky_insn
.number
3817 || (op
[i
].operand_num
== -1 && csky_insn
.number
!= 0)))
3819 /* The smaller err_num is more serious. */
3820 SET_ERROR_NUMBER (ERROR_OPERANDS_NUMBER
, op
[i
].operand_num
);
3825 for (j
= 0; j
< csky_insn
.number
; j
++)
3827 while (ISSPACE (*oper
))
3829 flag_pass
= get_operand_value (&op
[i
], &oper
,
3830 &op
[i
].oprnd
.oprnds
[j
]);
3831 if (flag_pass
== FALSE
)
3833 while (ISSPACE (*oper
))
3836 if (j
< csky_insn
.number
- 1 && op
[i
].operand_num
!= -1)
3842 SET_ERROR_NUMBER (ERROR_MISSING_COMMA
, NULL
);
3847 else if (!is_end_of_line
[(unsigned char) *oper
])
3849 SET_ERROR_NUMBER (ERROR_BAD_END
, NULL
);
3856 /* Parse operands in one table end. */
3858 if (flag_pass
== TRUE
)
3860 /* Parse operands success, set opcode_idx. */
3861 csky_insn
.opcode_idx
= i
;
3865 error_state
.opnum
= j
+ 1;
3867 /* Parse operands in ALL tables end. */
3871 /* Parse the operands according to operand type. */
3874 parse_operands (char *str
)
3878 /* Parse operands according to flag_force. */
3879 if (csky_insn
.flag_force
== INSN_OPCODE16F
3880 && (csky_insn
.opcode
->isa_flag16
& isa_flag
) != 0)
3882 if (parse_operands_op (oper
, csky_insn
.opcode
->op16
) == TRUE
)
3884 csky_insn
.isize
= 2;
3889 else if (csky_insn
.flag_force
== INSN_OPCODE32F
3890 && (csky_insn
.opcode
->isa_flag32
& isa_flag
) != 0)
3892 if (parse_operands_op (oper
, csky_insn
.opcode
->op32
) == TRUE
)
3894 csky_insn
.isize
= 4;
3901 if ((csky_insn
.opcode
->isa_flag16
& isa_flag
) != 0
3902 && parse_operands_op (oper
, csky_insn
.opcode
->op16
) == TRUE
)
3904 csky_insn
.isize
= 2;
3907 if ((csky_insn
.opcode
->isa_flag32
& isa_flag
) != 0
3908 && parse_operands_op (oper
, csky_insn
.opcode
->op32
) == TRUE
)
3910 csky_insn
.isize
= 4;
3918 csky_generate_frags (void)
3920 /* frag more relax reloc. */
3921 if (csky_insn
.flag_force
== INSN_OPCODE16F
3922 || !IS_SUPPORT_OPCODE32 (csky_insn
.opcode
))
3924 csky_insn
.output
= frag_more (csky_insn
.isize
);
3925 if (csky_insn
.opcode
->reloc16
)
3927 /* 16 bits opcode force, should generate fixup. */
3928 reloc_howto_type
*howto
;
3929 howto
= bfd_reloc_type_lookup (stdoutput
,
3930 csky_insn
.opcode
->reloc16
);
3931 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
3932 2, &csky_insn
.e1
, howto
->pc_relative
,
3933 csky_insn
.opcode
->reloc16
);
3936 else if (csky_insn
.flag_force
== INSN_OPCODE32F
)
3938 csky_insn
.output
= frag_more (csky_insn
.isize
);
3939 if (csky_insn
.opcode
->reloc32
)
3941 reloc_howto_type
*howto
;
3942 howto
= bfd_reloc_type_lookup (stdoutput
,
3943 csky_insn
.opcode
->reloc32
);
3944 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
3945 4, &csky_insn
.e1
, howto
->pc_relative
,
3946 csky_insn
.opcode
->reloc32
);
3949 else if (csky_insn
.opcode
->relax
)
3950 /* Generate the relax information. */
3951 csky_insn
.output
= frag_var (rs_machine_dependent
,
3952 csky_insn
.relax
.max
,
3953 csky_insn
.relax
.var
,
3954 csky_insn
.relax
.subtype
,
3955 csky_insn
.e1
.X_add_symbol
,
3956 csky_insn
.e1
.X_add_number
, 0);
3959 csky_insn
.output
= frag_more (csky_insn
.isize
);
3960 if (csky_insn
.opcode
->reloc16
&& csky_insn
.isize
== 2)
3962 reloc_howto_type
*howto
;
3963 howto
= bfd_reloc_type_lookup (stdoutput
,
3964 csky_insn
.opcode
->reloc16
);
3965 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
3966 2, &csky_insn
.e1
, howto
->pc_relative
,
3967 csky_insn
.opcode
->reloc16
);
3969 else if (csky_insn
.opcode
->reloc32
&& csky_insn
.isize
== 4)
3971 reloc_howto_type
*howto
;
3972 howto
= bfd_reloc_type_lookup (stdoutput
,
3973 csky_insn
.opcode
->reloc32
);
3974 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
3975 4, &csky_insn
.e1
, howto
->pc_relative
,
3976 csky_insn
.opcode
->reloc32
);
3982 /* Return the bits of VAL shifted according to MASK. The bits of MASK
3983 need not be contiguous. */
3986 generate_masked_value (int mask
, int val
)
3991 for (bit
= 1; mask
; bit
= bit
<< 1)
4002 /* Return the result of masking operand number OPRND_IDX into the
4003 instruction word according to the information in OPRND. */
4006 generate_masked_operand (struct operand
*oprnd
, int *oprnd_idx
)
4008 struct soperand
*soprnd
= NULL
;
4011 if ((unsigned int)oprnd
->mask
== HAS_SUB_OPERAND
)
4013 soprnd
= (struct soperand
*) oprnd
;
4014 generate_masked_operand (&soprnd
->subs
[0], oprnd_idx
);
4015 generate_masked_operand (&soprnd
->subs
[1], oprnd_idx
);
4019 val
= csky_insn
.val
[*oprnd_idx
];
4021 val
= generate_masked_value (mask
, val
);
4022 csky_insn
.inst
|= val
;
4028 csky_generate_insn (void)
4031 struct csky_opcode_info
*opinfo
= NULL
;
4033 if (csky_insn
.isize
== 4)
4034 opinfo
= &csky_insn
.opcode
->op32
[csky_insn
.opcode_idx
];
4035 else if (csky_insn
.isize
== 2)
4036 opinfo
= &csky_insn
.opcode
->op16
[csky_insn
.opcode_idx
];
4039 csky_insn
.inst
= opinfo
->opcode
;
4040 if (opinfo
->operand_num
== -1)
4042 generate_masked_operand (&opinfo
->oprnd
.oprnds
[i
], &sidx
);
4046 for (i
= 0; i
< opinfo
->operand_num
; i
++)
4047 generate_masked_operand (&opinfo
->oprnd
.oprnds
[i
], &sidx
);
4051 /* Main entry point for assembling a single instruction. */
4054 md_assemble (char *str
)
4056 bfd_boolean must_check_literals
= TRUE
;
4057 csky_insn
.isize
= 0;
4060 csky_insn
.flag_force
= INSN_OPCODE
;
4061 csky_insn
.macro
= NULL
;
4062 csky_insn
.opcode
= NULL
;
4063 memset (csky_insn
.val
, 0, sizeof (int) * MAX_OPRND_NUM
);
4064 /* Initialize err_num. */
4065 error_state
.err_num
= ERROR_NONE
;
4066 mov_r1_before
= FALSE
;
4067 mov_r1_after
= FALSE
;
4069 mapping_state (MAP_TEXT
);
4070 /* Tie dwarf2 debug info to every insn if set option --gdwarf2. */
4071 dwarf2_emit_insn (0);
4072 while (ISSPACE (* str
))
4074 /* Get opcode from str. */
4075 if (parse_opcode (str
) == FALSE
)
4077 csky_show_error (ERROR_OPCODE_ILLEGAL
, 0, NULL
, NULL
);
4081 /* If it is a macro instruction, handle it. */
4082 if (csky_insn
.macro
!= NULL
)
4084 if (csky_insn
.number
== csky_insn
.macro
->oprnd_num
)
4086 csky_insn
.macro
->handle_func ();
4089 else if (error_state
.err_num
> ERROR_OPERANDS_NUMBER
)
4090 SET_ERROR_NUMBER (ERROR_OPERANDS_NUMBER
, csky_insn
.macro
->oprnd_num
);
4093 if (csky_insn
.opcode
== NULL
)
4095 SET_ERROR_NUMBER (ERROR_OPCODE_ILLEGAL
, NULL
);
4096 csky_show_error (error_state
.err_num
, error_state
.opnum
,
4097 (void *)error_state
.arg1
, (void *)error_state
.arg1
);
4101 /* Parse the operands according to operand type. */
4102 if (parse_operands (csky_insn
.opcode_end
) == FALSE
)
4104 csky_show_error (error_state
.err_num
, error_state
.opnum
,
4105 (void *)error_state
.arg1
, (void *)error_state
.arg1
);
4109 /* if this insn has work in opcode table, then do it. */
4110 if (csky_insn
.opcode
->work
!= NULL
)
4111 must_check_literals
= csky_insn
.opcode
->work ();
4114 /* Generate relax or reloc if necessary. */
4115 csky_generate_frags ();
4116 /* Generate the insn by mask. */
4117 csky_generate_insn ();
4118 /* Write inst to frag. */
4119 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
4122 /* Adjust for xtrb0/xtrb1/xtrb2/xtrb3/divs/divu in csky v1 ISA. */
4123 if (mov_r1_after
== TRUE
)
4125 unsigned int mov_insn
= CSKYV1_INST_MOV_RX_R1
;
4126 mov_insn
|= csky_insn
.val
[0];
4127 mov_r1_before
= TRUE
;
4128 csky_insn
.output
= frag_more (2);
4129 dwarf2_emit_insn (0);
4130 md_number_to_chars (csky_insn
.output
, mov_insn
, 2);
4131 csky_insn
.isize
+= 2;
4133 if (mov_r1_before
== TRUE
)
4134 csky_insn
.isize
+= 2;
4136 /* Check literal. */
4137 if (must_check_literals
)
4139 if (csky_insn
.max
== 0)
4140 check_literals (csky_insn
.opcode
->transfer
, csky_insn
.isize
);
4142 check_literals (csky_insn
.opcode
->transfer
, csky_insn
.max
);
4145 insn_reloc
= BFD_RELOC_NONE
;
4148 /* Attempt to handle option with value C, returning non-zero on success. */
4151 md_parse_option (int c
, const char *arg
)
4169 /* Convert a machine dependent frag. */
4170 #define PAD_LITERAL_LENGTH 6
4171 #define opposite_of_stored_comp(insn) (insn ^ 0x04000000)
4172 #define opposite_of_stored_compz(insn) (insn ^ 0x00200000)
4173 #define make_insn(total_length, opcode, operand, operand_length) \
4175 if (total_length > 0) \
4177 csky_write_insn (buf, \
4178 opcode | (operand & ((1 << operand_length) - 1)), \
4180 buf += total_length; \
4181 fragp->fr_fix += total_length; \
4185 #define make_literal(fragp, literal_offset) \
4187 make_insn (literal_offset, PAD_FILL_CONTENT, 0, 0); \
4188 fix_new (fragp, fragp->fr_fix, 4, fragp->fr_symbol, \
4189 fragp->fr_offset, 0, BFD_RELOC_CKCORE_ADDR32); \
4190 make_insn (4, 0, 0, 0); \
4191 make_insn (2 - literal_offset, PAD_FILL_CONTENT, 0, 0); \
4195 md_convert_frag (bfd
*abfd ATTRIBUTE_UNUSED
, segT asec
, fragS
*fragp
)
4198 char *buf
= fragp
->fr_fix
+ fragp
->fr_literal
;
4200 gas_assert (fragp
->fr_symbol
);
4201 if (IS_EXTERNAL_SYM (fragp
->fr_symbol
, asec
))
4204 disp
= (S_GET_VALUE (fragp
->fr_symbol
)
4209 switch (fragp
->fr_subtype
)
4211 /* generate new insn. */
4212 case C (COND_JUMP
, DISP12
):
4213 case C (UNCD_JUMP
, DISP12
):
4214 case C (COND_JUMP_PIC
, DISP12
):
4215 case C (UNCD_JUMP_PIC
, DISP12
):
4217 #define CSKY_V1_B_MASK 0xf8
4222 /* Error. odd displacement at %x, next_inst-2. */
4227 if (!target_big_endian
)
4229 t0
= buf
[1] & CSKY_V1_B_MASK
;
4230 md_number_to_chars (buf
, disp
, 2);
4231 buf
[1] = (buf
[1] & ~CSKY_V1_B_MASK
) | t0
;
4235 t0
= buf
[0] & CSKY_V1_B_MASK
;
4236 md_number_to_chars (buf
, disp
, 2);
4237 buf
[0] = (buf
[0] & ~CSKY_V1_B_MASK
) | t0
;
4242 case C (COND_JUMP
, DISP32
):
4243 case C (COND_JUMP
, UNDEF_WORD_DISP
):
4245 /* A conditional branch wont fit into 12 bits:
4252 int first_inst
= fragp
->fr_fix
+ fragp
->fr_address
;
4253 int is_unaligned
= (first_inst
& 3);
4255 if (!target_big_endian
)
4257 /* b!cond instruction. */
4259 /* jmpi instruction. */
4260 buf
[2] = CSKYV1_INST_JMPI
& 0xff;
4261 buf
[3] = CSKYV1_INST_JMPI
>> 8;
4265 /* b!cond instruction. */
4267 /* jmpi instruction. */
4268 buf
[2] = CSKYV1_INST_JMPI
>> 8;
4269 buf
[3] = CSKYV1_INST_JMPI
& 0xff;
4274 if (!target_big_endian
)
4276 /* bt/bf: jump to pc + 2 + (4 << 1). */
4278 /* jmpi: jump to MEM (pc + 2 + (1 << 2)). */
4283 /* bt/bf: jump to pc + 2 + (4 << 1). */
4285 /* jmpi: jump to MEM (pc + 2 + (1 << 2)). */
4288 /* Aligned 4 bytes. */
4297 /* Make reloc for the long disp. */
4298 fix_new (fragp
, fragp
->fr_fix
+ 6, 4,
4299 fragp
->fr_symbol
, fragp
->fr_offset
, 0, BFD_RELOC_32
);
4300 fragp
->fr_fix
+= C32_LEN
;
4304 if (!target_big_endian
)
4306 /* bt/bf: jump to pc + 2 + (3 << 1). */
4308 /* jmpi: jump to MEM (pc + 2 + (0 << 2)). */
4313 /* bt/bf: jump to pc + 2 + (3 << 1). */
4315 /* jmpi: jump to MEM (pc + 2 + (0 << 2)). */
4324 /* Make reloc for the long disp. */
4325 fix_new (fragp
, fragp
->fr_fix
+ 4, 4,
4326 fragp
->fr_symbol
, fragp
->fr_offset
, 0, BFD_RELOC_32
);
4327 fragp
->fr_fix
+= C32_LEN
;
4329 /* Frag is actually shorter (see the other side of this ifdef)
4330 but gas isn't prepared for that. We have to re-adjust
4331 the branch displacement so that it goes beyond the
4332 full length of the fragment, not just what we actually
4334 if (!target_big_endian
)
4342 case C (COND_JUMP_PIC
, DISP32
):
4343 case C (COND_JUMP_PIC
, UNDEF_WORD_DISP
):
4345 #define BYTE_1(a) (target_big_endian ? ((a) & 0xff) : ((a) >> 8))
4346 #define BYTE_0(a) (target_big_endian ? ((a) >> 8) : ((a) & 0xff))
4357 0: .long (tar_addr - pc)
4360 int first_inst
= fragp
->fr_fix
+ fragp
->fr_address
;
4361 int is_unaligned
= (first_inst
& 3);
4363 /* Toggle T/F bit. */
4364 if (! target_big_endian
)
4368 buf
[2] = BYTE_0 (CSKYV1_INST_SUBI
| (7 << 4)); /* subi r0, 8. */
4369 buf
[3] = BYTE_1 (CSKYV1_INST_SUBI
| (7 << 4));
4370 buf
[4] = BYTE_0 (CSKYV1_INST_STW
| (15 << 8)); /* stw r15, r0. */
4371 buf
[5] = BYTE_1 (CSKYV1_INST_STW
| (15 << 8));
4372 buf
[6] = BYTE_0 (CSKYV1_INST_BSR
); /* bsr pc + 2. */
4373 buf
[7] = BYTE_1 (CSKYV1_INST_BSR
);
4374 buf
[8] = BYTE_0 (CSKYV1_INST_LRW
| (1 << 8)); /* lrw r1, (tar_addr - pc). */
4375 buf
[9] = BYTE_1 (CSKYV1_INST_LRW
| (1 << 8));
4376 buf
[10] = BYTE_0 (CSKYV1_INST_ADDU
| (15 << 4) | 1); /* add r1, r15. */
4377 buf
[11] = BYTE_1 (CSKYV1_INST_ADDU
| (15 << 4) | 1);
4378 buf
[12] = BYTE_0 (CSKYV1_INST_LDW
| (15 << 8)); /* ldw r15, r0. */
4379 buf
[13] = BYTE_1 (CSKYV1_INST_LDW
| (15 << 8));
4380 buf
[14] = BYTE_0 (CSKYV1_INST_ADDI
| (7 << 4)); /* addi r0, 8. */
4381 buf
[15] = BYTE_1 (CSKYV1_INST_ADDI
| (7 << 4));
4382 buf
[16] = BYTE_0 (CSKYV1_INST_JMP
| 1); /* jmp r1. */
4383 buf
[17] = BYTE_1 (CSKYV1_INST_JMP
| 1);
4387 if (!target_big_endian
)
4391 buf
[20] = disp
& 0xff;
4392 buf
[21] = (disp
>> 8) & 0xff;
4393 buf
[22] = (disp
>> 16) & 0xff;
4394 buf
[23] = (disp
>> 24) & 0xff;
4396 else /* if !target_big_endian. */
4400 buf
[20] = (disp
>> 24) & 0xff;
4401 buf
[21] = (disp
>> 16) & 0xff;
4402 buf
[22] = (disp
>> 8) & 0xff;
4403 buf
[23] = disp
& 0xff;
4405 buf
[18] = 0; /* alignment. */
4407 fragp
->fr_fix
+= C32_LEN_PIC
;
4409 else /* if !is_unaligned. */
4411 if (!target_big_endian
)
4415 buf
[18] = disp
& 0xff;
4416 buf
[19] = (disp
>> 8) & 0xff;
4417 buf
[20] = (disp
>> 16) & 0xff;
4418 buf
[21] = (disp
>> 24) & 0xff;
4420 else /* if !target_big_endian. */
4424 buf
[18] = (disp
>> 24) & 0xff;
4425 buf
[19] = (disp
>> 16) & 0xff;
4426 buf
[20] = (disp
>> 8) & 0xff;
4427 buf
[21] = disp
& 0xff;
4429 fragp
->fr_fix
+= C32_LEN_PIC
;
4431 } /* end if is_unaligned. */
4432 } /* end case C (COND_JUMP_PIC, DISP32)/C (COND_JUMP_PIC, UNDEF_WORD_DISP). */
4434 case C (UNCD_JUMP
, DISP32
):
4435 case C (UNCD_JUMP
, UNDEF_WORD_DISP
):
4440 int first_inst
= fragp
->fr_fix
+ fragp
->fr_address
;
4441 int is_unaligned
= (first_inst
& 3);
4443 buf
[0] = BYTE_0 (CSKYV1_INST_JMPI
);
4444 buf
[1] = BYTE_1 (CSKYV1_INST_JMPI
);
4447 if (!target_big_endian
)
4459 fix_new (fragp
, fragp
->fr_fix
+ 4, 4,
4460 fragp
->fr_symbol
, fragp
->fr_offset
, 0, BFD_RELOC_32
);
4461 fragp
->fr_fix
+= U32_LEN
;
4463 else /* if is_unaligned. */
4465 if (!target_big_endian
)
4474 fix_new (fragp
, fragp
->fr_fix
+ 2, 4,
4475 fragp
->fr_symbol
, fragp
->fr_offset
, 0, BFD_RELOC_32
);
4476 fragp
->fr_fix
+= U32_LEN
;
4481 case C (UNCD_JUMP_PIC
, DISP32
):
4482 case C (UNCD_JUMP_PIC
, UNDEF_WORD_DISP
):
4494 0: .long (tar_add - pc)
4497 /* If the b!cond is 4 byte aligned, the literal which would
4498 go at x+4 will also be aligned. */
4499 int first_inst
= fragp
->fr_fix
+ fragp
->fr_address
;
4500 int is_unaligned
= (first_inst
& 3);
4503 buf
[0] = BYTE_0 (CSKYV1_INST_SUBI
| (7 << 4)); /* subi r0, 8. */
4504 buf
[1] = BYTE_1 (CSKYV1_INST_SUBI
| (7 << 4));
4505 buf
[2] = BYTE_0 (CSKYV1_INST_STW
| (15 << 8)); /* stw r15, r0. */
4506 buf
[3] = BYTE_1 (CSKYV1_INST_STW
| (15 << 8));
4507 buf
[4] = BYTE_0 (CSKYV1_INST_BSR
); /* bsr pc + 2. */
4508 buf
[5] = BYTE_1 (CSKYV1_INST_BSR
);
4509 buf
[6] = BYTE_0 (CSKYV1_INST_LRW
| (1 << 8)); /* lrw r1, (tar_addr - pc). */
4510 buf
[7] = BYTE_1 (CSKYV1_INST_LRW
| (1 << 8));
4511 buf
[8] = BYTE_0 (CSKYV1_INST_ADDU
| (15 << 4) | 1); /* add r1, r15. */
4512 buf
[9] = BYTE_1 (CSKYV1_INST_ADDU
| (15 << 4) | 1);
4513 buf
[10] = BYTE_0 (CSKYV1_INST_LDW
| (15 << 8)); /* ldw r15, r0. */
4514 buf
[11] = BYTE_1 (CSKYV1_INST_LDW
| (15 << 8));
4515 buf
[12] = BYTE_0 (CSKYV1_INST_ADDI
| (7 << 4)); /* addi r0, 8. */
4516 buf
[13] = BYTE_1 (CSKYV1_INST_ADDI
| (7 << 4));
4517 buf
[14] = BYTE_0 (CSKYV1_INST_JMP
| 1); /* jmp r1. */
4518 buf
[15] = BYTE_1 (CSKYV1_INST_JMP
| 1);
4522 if (!target_big_endian
)
4525 buf
[18] = disp
& 0xff;
4526 buf
[19] = (disp
>> 8) & 0xff;
4527 buf
[20] = (disp
>> 16) & 0xff;
4528 buf
[21] = (disp
>> 24) & 0xff;
4533 buf
[18] = (disp
>> 24) & 0xff;
4534 buf
[19] = (disp
>> 16) & 0xff;
4535 buf
[20] = (disp
>> 8) & 0xff;
4536 buf
[21] = disp
& 0xff;
4540 fragp
->fr_fix
+= U32_LEN_PIC
;
4544 if (!target_big_endian
)
4547 buf
[16] = disp
& 0xff;
4548 buf
[17] = (disp
>> 8) & 0xff;
4549 buf
[18] = (disp
>> 16) & 0xff;
4550 buf
[19] = (disp
>> 24) & 0xff;
4555 buf
[16] = (disp
>> 24) & 0xff;
4556 buf
[17] = (disp
>> 16) & 0xff;
4557 buf
[18] = (disp
>> 8) & 0xff;
4558 buf
[19] = disp
& 0xff;
4560 fragp
->fr_fix
+= U32_LEN_PIC
;
4570 unsigned int inst
= csky_read_insn (buf
, 2);
4571 inst
|= (disp
>> 1) & ((1 << 10) - 1);
4572 csky_write_insn (buf
, inst
, 2);
4578 unsigned int inst
= csky_read_insn (buf
, 2);
4580 if (inst
== CSKYV2_INST_BT16
)
4581 inst
= CSKYV2_INST_BF16
;
4583 inst
= CSKYV2_INST_BT16
;
4584 make_insn (2, inst
, (2 + 4) >> 1, 10);
4585 if (IS_EXTERNAL_SYM (fragp
->fr_symbol
, asec
))
4586 fix_new (fragp
, fragp
->fr_fix
, 4,
4587 fragp
->fr_symbol
, fragp
->fr_offset
, 1,
4588 BFD_RELOC_CKCORE_PCREL_IMM16BY2
);
4590 inst
= CSKYV2_INST_BR32
| ((disp
>> 1) & ((1 << 16) - 1));
4591 csky_write_insn (buf
, inst
, 4);
4598 unsigned int inst
= csky_read_insn (buf
, 2);
4600 if (inst
== CSKYV2_INST_BT16
)
4601 inst
= CSKYV2_INST_BT32
;
4603 inst
= CSKYV2_INST_BF32
;
4604 if (IS_EXTERNAL_SYM (fragp
->fr_symbol
, asec
))
4605 fix_new (fragp
, fragp
->fr_fix
, 4,
4606 fragp
->fr_symbol
, fragp
->fr_offset
, 1,
4607 BFD_RELOC_CKCORE_PCREL_IMM16BY2
);
4608 inst
|= (disp
>> 1) & ((1 << 16) - 1);
4609 csky_write_insn (buf
, inst
, 4);
4615 unsigned int inst
= csky_read_insn (buf
, 2);
4617 imm
= (disp
+ 2) >> 2;
4618 inst
|= (imm
>> 5) << 8;
4619 make_insn (2, inst
, (imm
& 0x1f), 5);
4624 unsigned int inst
= csky_read_insn (buf
, 2);
4625 int imm
= (disp
+ 2) >> 2;
4629 inst
|= (~((imm
>> 5) << 8)) & 0x300;
4630 make_insn (2, inst
, (~imm
& 0x1f), 5);
4634 inst
|= (imm
>> 5) << 8;
4635 make_insn (2, inst
, (imm
& 0x1f), 5);
4641 unsigned int inst
= csky_read_insn (buf
, 2);
4642 inst
= CSKYV2_INST_LRW32
| (((inst
& 0xe0) >> 5) << 16);
4643 if (IS_EXTERNAL_SYM (fragp
->fr_symbol
, asec
))
4644 fix_new (fragp
, fragp
->fr_fix
, 4,
4645 fragp
->fr_symbol
, fragp
->fr_offset
, 1,
4646 BFD_RELOC_CKCORE_PCREL_IMM16BY4
);
4647 make_insn (4, inst
, ((disp
+ 2) >> 2), 16);
4652 unsigned int inst
= csky_read_insn (buf
, 4);
4653 make_insn (4, inst
, disp
>> 1, 16);
4658 unsigned int inst
= csky_read_insn (buf
, 4);
4660 make_insn (4, opposite_of_stored_compz (inst
),
4661 (4 + 4 + PAD_LITERAL_LENGTH
) >> 1, 16);
4662 literal_offset
= ((fragp
->fr_address
+ fragp
->fr_fix
) % 4 == 0
4664 make_insn (4, CSKYV2_INST_JMPI32
, (4 + literal_offset
+ 2) >> 2, 10);
4665 make_literal (fragp
, literal_offset
);
4671 if (IS_EXTERNAL_SYM (fragp
->fr_symbol
, asec
))
4672 fix_new (fragp
, fragp
->fr_fix
, 4,
4673 fragp
->fr_symbol
, fragp
->fr_offset
, 1,
4674 BFD_RELOC_CKCORE_PCREL_IMM16BY2
);
4675 make_insn (4, CSKYV2_INST_BR32
, disp
>> 1, 16);
4680 /* 'jbt'/'jbf'-> <bf16/bt16>; jmpi32; [pad16]+literal32 */
4681 unsigned int inst
= csky_read_insn (buf
, 2);
4684 if (inst
== CSKYV2_INST_BT16
)
4685 inst
= CSKYV2_INST_BF16
;
4687 inst
= CSKYV2_INST_BT16
;
4688 make_insn (2, inst
, (2 + 4 + PAD_LITERAL_LENGTH
) >> 1, 10);
4689 literal_offset
= ((fragp
->fr_address
+ fragp
->fr_fix
) % 4 == 0
4691 make_insn (4, CSKYV2_INST_JMPI32
, (4 + literal_offset
+ 2) >> 2, 10);
4692 make_literal (fragp
, literal_offset
);
4698 literal_offset
= ((fragp
->fr_address
+ fragp
->fr_fix
) % 4 == 0
4700 make_insn (4, CSKYV2_INST_JMPI32
, (4 + literal_offset
+ 2) >> 2, 10);
4701 make_literal (fragp
, literal_offset
);
4704 case RELAX_OVERFLOW
:
4705 csky_branch_report_error (fragp
->fr_file
, fragp
->fr_line
,
4706 fragp
->fr_symbol
, disp
);
4714 /* Round up a section size to the appropriate boundary. */
4717 md_section_align (segT segment ATTRIBUTE_UNUSED
,
4723 /* MD interface: Symbol and relocation handling. */
4725 void md_csky_end (void)
4730 /* Return the address within the segment that a PC-relative fixup is
4734 md_pcrel_from_section (fixS
* fixP
, segT seg
)
4736 /* If the symbol is undefined or defined in another section
4737 we leave the add number alone for the linker to fix it later. */
4738 if (fixP
->fx_addsy
!= (symbolS
*) NULL
4739 && (! S_IS_DEFINED (fixP
->fx_addsy
)
4740 || S_GET_SEGMENT (fixP
->fx_addsy
) != seg
))
4741 return fixP
->fx_size
;
4743 /* The case where we are going to resolve things. */
4744 return fixP
->fx_size
+ fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
4747 /* csky_cons_fix_new is called via the expression parsing code when a
4748 reloc is needed. We use this hook to get the correct .got reloc. */
4751 csky_cons_fix_new (fragS
*frag
,
4755 bfd_reloc_code_real_type reloc
)
4759 if (BFD_RELOC_CKCORE_GOTOFF
== insn_reloc
4760 || BFD_RELOC_CKCORE_GOTPC
== insn_reloc
4761 || BFD_RELOC_CKCORE_GOT32
== insn_reloc
4762 || BFD_RELOC_CKCORE_PLT32
== insn_reloc
4763 || BFD_RELOC_CKCORE_TLS_LE32
== insn_reloc
4764 || BFD_RELOC_CKCORE_TLS_GD32
== insn_reloc
4765 || BFD_RELOC_CKCORE_TLS_LDM32
== insn_reloc
4766 || BFD_RELOC_CKCORE_TLS_LDO32
== insn_reloc
4767 || BFD_RELOC_CKCORE_TLS_IE32
== insn_reloc
)
4773 reloc
= BFD_RELOC_8
;
4776 reloc
= BFD_RELOC_16
;
4779 reloc
= BFD_RELOC_32
;
4782 reloc
= BFD_RELOC_64
;
4785 as_bad (_("unsupported BFD relocation size %d"), len
);
4786 reloc
= BFD_RELOC_32
;
4789 fixP
= fix_new_exp (frag
, off
, (int) len
, exp
, 0, reloc
);
4790 if (BFD_RELOC_CKCORE_TLS_IE32
== insn_reloc
4791 || BFD_RELOC_CKCORE_TLS_GD32
== insn_reloc
4792 || BFD_RELOC_CKCORE_TLS_LDM32
== insn_reloc
)
4794 fixP
->tc_fix_data
.frag
= literal_insn_offset
->tls_addend
.frag
;
4795 fixP
->tc_fix_data
.offset
= literal_insn_offset
->tls_addend
.offset
;
4799 /* See whether we need to force a relocation into the output file.
4800 This is used to force out switch and PC relative relocations when
4804 csky_force_relocation (fixS
* fix
)
4806 if (fix
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
4807 || fix
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
4808 || fix
->fx_r_type
== BFD_RELOC_RVA
4809 || fix
->fx_r_type
== BFD_RELOC_CKCORE_ADDR_HI16
4810 || fix
->fx_r_type
== BFD_RELOC_CKCORE_ADDR_LO16
4811 || fix
->fx_r_type
== BFD_RELOC_CKCORE_TOFFSET_LO16
4812 || fix
->fx_r_type
== BFD_RELOC_CKCORE_DOFFSET_LO16
)
4815 if (fix
->fx_addsy
== NULL
)
4818 if (do_use_branchstub
4819 && fix
->fx_r_type
== BFD_RELOC_CKCORE_PCREL_IMM26BY2
4820 && (symbol_get_bfdsym (fix
->fx_addsy
)->flags
& BSF_FUNCTION
))
4822 return S_FORCE_RELOC (fix
->fx_addsy
, fix
->fx_subsy
== NULL
);
4825 /* Return true if the fix can be handled by GAS, false if it must
4826 be passed through to the linker. */
4829 csky_fix_adjustable (fixS
* fixP
)
4831 if (fixP
->fx_addsy
== NULL
)
4834 /* We need the symbol name for the VTABLE entries. */
4835 if (fixP
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
4836 || fixP
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
4837 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_PLT32
4838 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_GOT32
4839 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_PLT12
4840 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_GOT12
4841 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_GOT_HI16
4842 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_GOT_LO16
4843 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_PLT_HI16
4844 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_PLT_LO16
4845 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_GOTOFF
4846 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_GOTOFF_HI16
4847 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_GOTOFF_LO16
4848 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_ADDR_HI16
4849 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_ADDR_LO16
4850 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_GOT_IMM18BY4
4851 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_PLT_IMM18BY4
4852 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_GOTOFF_IMM18
4853 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_TLS_LE32
4854 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_TLS_IE32
4855 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_TLS_GD32
4856 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_TLS_LDM32
4857 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_TLS_LDO32
)
4860 if (do_use_branchstub
4861 && fixP
->fx_r_type
== BFD_RELOC_CKCORE_PCREL_IMM26BY2
4862 && (symbol_get_bfdsym (fixP
->fx_addsy
)->flags
& BSF_FUNCTION
))
4869 md_apply_fix (fixS
*fixP
,
4873 reloc_howto_type
*howto
;
4874 /* Note: use offsetT because it is signed, valueT is unsigned. */
4875 offsetT val
= *valP
;
4876 char *buf
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
4878 /* if fx_done = 0, fixup will also be processed in
4879 * tc_gen_reloc() after md_apply_fix(). */
4882 /* If the fix is relative to a symbol which is not defined, or not
4883 in the same segment as the fix, we cannot resolve it here. */
4884 if (IS_CSKY_V1 (mach_flag
) && fixP
->fx_addsy
!= NULL
4885 && (! S_IS_DEFINED (fixP
->fx_addsy
)
4886 || S_GET_SEGMENT (fixP
->fx_addsy
) != seg
))
4888 switch (fixP
->fx_r_type
)
4890 /* Data fx_addnumber is greater than 16 bits,
4891 so fx_addnumber is assigned zero. */
4892 case BFD_RELOC_CKCORE_PCREL_JSR_IMM11BY2
:
4895 case BFD_RELOC_CKCORE_TLS_IE32
:
4896 case BFD_RELOC_CKCORE_TLS_LDM32
:
4897 case BFD_RELOC_CKCORE_TLS_GD32
:
4899 struct tls_addend
*ta
= &(fixP
->tc_fix_data
);
4900 fixP
->fx_offset
= (fixP
->fx_frag
->fr_address
+ fixP
->fx_where
4901 - (ta
->frag
->fr_address
+ ta
->offset
));
4904 case BFD_RELOC_CKCORE_TLS_LE32
:
4905 case BFD_RELOC_CKCORE_TLS_LDO32
:
4906 S_SET_THREAD_LOCAL (fixP
->fx_addsy
);
4912 /* For ELF we can just return and let the reloc that will be generated
4913 take care of everything. For COFF we still have to insert 'val'
4914 into the insn since the addend field will be ignored. */
4919 /* We can handle these relocs. */
4920 switch (fixP
->fx_r_type
)
4922 case BFD_RELOC_32_PCREL
:
4923 case BFD_RELOC_CKCORE_PCREL32
:
4924 fixP
->fx_r_type
= BFD_RELOC_CKCORE_PCREL32
;
4926 case BFD_RELOC_VTABLE_INHERIT
:
4927 fixP
->fx_r_type
= BFD_RELOC_CKCORE_GNU_VTINHERIT
;
4928 if (fixP
->fx_addsy
&& !S_IS_DEFINED (fixP
->fx_addsy
)
4929 && !S_IS_WEAK (fixP
->fx_addsy
))
4930 S_SET_WEAK (fixP
->fx_addsy
);
4932 case BFD_RELOC_VTABLE_ENTRY
:
4933 fixP
->fx_r_type
= BFD_RELOC_CKCORE_GNU_VTENTRY
;
4935 case BFD_RELOC_CKCORE_GOT12
:
4936 case BFD_RELOC_CKCORE_PLT12
:
4937 case BFD_RELOC_CKCORE_ADDR_HI16
:
4938 case BFD_RELOC_CKCORE_ADDR_LO16
:
4939 case BFD_RELOC_CKCORE_TOFFSET_LO16
:
4940 case BFD_RELOC_CKCORE_DOFFSET_LO16
:
4941 case BFD_RELOC_CKCORE_GOT_HI16
:
4942 case BFD_RELOC_CKCORE_GOT_LO16
:
4943 case BFD_RELOC_CKCORE_PLT_HI16
:
4944 case BFD_RELOC_CKCORE_PLT_LO16
:
4945 case BFD_RELOC_CKCORE_GOTPC_HI16
:
4946 case BFD_RELOC_CKCORE_GOTPC_LO16
:
4947 case BFD_RELOC_CKCORE_GOTOFF_HI16
:
4948 case BFD_RELOC_CKCORE_GOTOFF_LO16
:
4949 case BFD_RELOC_CKCORE_DOFFSET_IMM18
:
4950 case BFD_RELOC_CKCORE_DOFFSET_IMM18BY2
:
4951 case BFD_RELOC_CKCORE_DOFFSET_IMM18BY4
:
4952 case BFD_RELOC_CKCORE_GOTOFF_IMM18
:
4953 case BFD_RELOC_CKCORE_GOT_IMM18BY4
:
4954 case BFD_RELOC_CKCORE_PLT_IMM18BY4
:
4956 case BFD_RELOC_CKCORE_TLS_IE32
:
4957 case BFD_RELOC_CKCORE_TLS_LDM32
:
4958 case BFD_RELOC_CKCORE_TLS_GD32
:
4960 struct tls_addend
*ta
= &(fixP
->tc_fix_data
);
4961 fixP
->fx_offset
= (fixP
->fx_frag
->fr_address
+ fixP
->fx_where
4962 - (ta
->frag
->fr_address
+ ta
->offset
));
4965 case BFD_RELOC_CKCORE_TLS_LE32
:
4966 case BFD_RELOC_CKCORE_TLS_LDO32
:
4967 S_SET_THREAD_LOCAL (fixP
->fx_addsy
);
4970 fixP
->fx_r_type
= BFD_RELOC_CKCORE_ADDR32
;
4974 if (fixP
->fx_addsy
== NULL
)
4976 if (fixP
->fx_size
== 4)
4978 else if (fixP
->fx_size
== 2 && val
>= -32768 && val
<= 32767)
4980 else if (fixP
->fx_size
== 1 && val
>= -256 && val
<= 255)
4984 md_number_to_chars (buf
, val
, fixP
->fx_size
);
4988 case BFD_RELOC_CKCORE_PCREL_JSR_IMM11BY2
:
4989 if (fixP
->fx_addsy
== 0 && val
> -2 KB
&& val
< 2 KB
)
4991 long nval
= (val
>> 1) & 0x7ff;
4992 nval
|= CSKYV1_INST_BSR
;
4993 csky_write_insn (buf
, nval
, 2);
4999 case BFD_RELOC_CKCORE_PCREL_JSR_IMM26BY2
:
5000 if (fixP
->fx_addsy
== 0)
5002 if (val
>= -(1 << 26) && val
< (1 << 26))
5004 unsigned int nval
= ((val
+ fixP
->fx_size
) >> 1) & 0x3ffffff;
5005 nval
|= CSKYV2_INST_BSR32
;
5007 csky_write_insn (buf
, nval
, 4);
5009 /* If bsr32 cannot reach,
5010 generate 'lrw r25,label;jsr r25' instead of 'jsri label'. */
5011 else if (IS_CSKY_ARCH_810 (mach_flag
))
5013 howto
= bfd_reloc_type_lookup (stdoutput
, fixP
->fx_r_type
);
5014 valueT opcode
= csky_read_insn (buf
, 4);
5015 opcode
= (opcode
& howto
->dst_mask
) | CSKYV2_INST_JSRI_TO_LRW
;
5016 csky_write_insn (buf
, opcode
, 4);
5017 opcode
= CSKYV2_INST_JSR_R26
;
5018 csky_write_insn (buf
+ 4, opcode
, 4);
5028 unsigned int issigned
= 0;
5033 howto
= bfd_reloc_type_lookup (stdoutput
, fixP
->fx_r_type
);
5036 if (fixP
->fx_size
== 4
5037 || (fixP
->fx_size
== 2 && val
>= -32768 && val
<= 32767)
5038 || (fixP
->fx_size
== 1 && val
>= -256 && val
<= 255))
5040 md_number_to_chars (buf
, val
, fixP
->fx_size
);
5048 if (IS_CSKY_V2 (mach_flag
))
5049 val
+= fixP
->fx_size
;
5051 if (howto
->rightshift
== 2)
5054 val
>>= howto
->rightshift
;
5056 switch (fixP
->fx_r_type
)
5058 /* Offset is unsigned. */
5059 case BFD_RELOC_CKCORE_PCREL_IMM8BY4
:
5060 case BFD_RELOC_CKCORE_PCREL_IMM10BY4
:
5061 case BFD_RELOC_CKCORE_PCREL_IMM16BY4
:
5062 max
= (offsetT
) howto
->dst_mask
;
5066 case BFD_RELOC_CKCORE_PCREL_IMM7BY4
:
5068 max
= (offsetT
)((1 << (howto
->bitsize
+ 1)) - 2);
5070 max
= (offsetT
)((1 << howto
->bitsize
) - 1);
5073 /* flrws, flrwd: the offset bits are divided in two parts. */
5074 case BFD_RELOC_CKCORE_PCREL_FLRW_IMM8BY4
:
5075 max
= (offsetT
)((1 << howto
->bitsize
) - 1);
5078 /* Offset is signed. */
5080 max
= (offsetT
)(howto
->dst_mask
>> 1);
5084 if (val
< min
|| val
> max
)
5086 csky_branch_report_error (fixP
->fx_file
, fixP
->fx_line
,
5087 fixP
->fx_addsy
, val
);
5090 opcode
= csky_read_insn (buf
, fixP
->fx_size
);
5091 /* Clear redundant bits brought from the last
5092 operation if there is any. */
5093 if (do_extend_lrw
&& (opcode
& 0xfc00) == CSKYV2_INST_LRW16
)
5096 val
&= issigned
? (offsetT
)(howto
->dst_mask
) : max
;
5098 if (fixP
->fx_r_type
== BFD_RELOC_CKCORE_PCREL_BLOOP_IMM4BY4
)
5099 val
= (val
& 0xf) << 12;
5101 if (fixP
->fx_size
== 2 && (opcode
& 0xfc00) == CSKYV2_INST_LRW16
)
5103 /* 8 bit offset lrw16. */
5105 csky_write_insn (buf
,
5107 | ((~val
& 0x60) << 3) | (opcode
& 0xe0)),
5109 /* 7 bit offset lrw16. */
5111 csky_write_insn (buf
,
5112 (val
& 0x1f) | ((val
& 0x60) << 3) | opcode
,
5115 else if (fixP
->fx_size
== 4
5116 && (opcode
& 0xfe1ffe00) == CSKYV2_INST_FLRW
)
5117 csky_write_insn (buf
,
5118 ((val
& 0xf) << 4) | ((val
& 0xf0) << 17) | opcode
,
5121 csky_write_insn (buf
, val
| opcode
, fixP
->fx_size
);
5126 fixP
->fx_addnumber
= val
;
5129 /* Translate internal representation of relocation info to BFD target
5133 tc_gen_reloc (asection
*section ATTRIBUTE_UNUSED
, fixS
*fixP
)
5138 && fixP
->fx_r_type
== BFD_RELOC_CKCORE_ADDR32
)
5139 fixP
->fx_r_type
= BFD_RELOC_CKCORE_PCREL32
;
5141 rel
= xmalloc (sizeof (arelent
));
5142 rel
->sym_ptr_ptr
= xmalloc (sizeof (asymbol
*));
5143 *rel
->sym_ptr_ptr
= symbol_get_bfdsym (fixP
->fx_addsy
);
5144 rel
->howto
= bfd_reloc_type_lookup (stdoutput
, fixP
->fx_r_type
);
5145 rel
->addend
= fixP
->fx_offset
;
5146 if (rel
->howto
== NULL
)
5148 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5149 _("cannot represent `%s' relocation in object file"),
5150 bfd_get_reloc_code_name (fixP
->fx_r_type
));
5152 /* Set howto to a garbage value so that we can keep going. */
5153 rel
->howto
= bfd_reloc_type_lookup (stdoutput
, BFD_RELOC_32
);
5155 gas_assert (rel
->howto
!= NULL
);
5156 rel
->address
= fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
5160 /* Relax a fragment by scanning TC_GENERIC_RELAX_TABLE. */
5163 csky_relax_frag (segT segment
, fragS
*fragP
, long stretch
)
5165 const relax_typeS
*this_type
;
5166 const relax_typeS
*start_type
;
5167 relax_substateT next_state
;
5168 relax_substateT this_state
;
5174 const relax_typeS
*table
;
5176 target
= fragP
->fr_offset
;
5177 address
= fragP
->fr_address
;
5178 table
= TC_GENERIC_RELAX_TABLE
;
5179 this_state
= fragP
->fr_subtype
;
5180 start_type
= this_type
= table
+ this_state
;
5181 symbolP
= fragP
->fr_symbol
;
5187 sym_frag
= symbol_get_frag (symbolP
);
5189 #ifndef DIFF_EXPR_OK
5190 know (sym_frag
!= NULL
);
5192 know (S_GET_SEGMENT (symbolP
) != absolute_section
5193 || sym_frag
== &zero_address_frag
);
5194 target
+= S_GET_VALUE (symbolP
);
5196 /* If SYM_FRAG has yet to be reached on this pass, assume it
5197 will move by STRETCH just as we did, unless there is an
5198 alignment frag between here and SYM_FRAG. An alignment may
5199 well absorb any STRETCH, and we don't want to choose a larger
5200 branch insn by overestimating the needed reach of this
5201 branch. It isn't critical to calculate TARGET exactly; We
5202 know we'll be doing another pass if STRETCH is non-zero. */
5205 && sym_frag
->relax_marker
!= fragP
->relax_marker
5206 && S_GET_SEGMENT (symbolP
) == segment
)
5210 /* Adjust stretch for any alignment frag. Note that if have
5211 been expanding the earlier code, the symbol may be
5212 defined in what appears to be an earlier frag. FIXME:
5213 This doesn't handle the fr_subtype field, which specifies
5214 a maximum number of bytes to skip when doing an
5216 for (f
= fragP
; f
!= NULL
&& f
!= sym_frag
; f
= f
->fr_next
)
5218 if (f
->fr_type
== rs_align
|| f
->fr_type
== rs_align_code
)
5221 stretch
= -((-stretch
)
5222 & ~((1 << (int) f
->fr_offset
) - 1));
5224 stretch
&= ~((1 << (int) f
->fr_offset
) - 1);
5234 aim
= target
- address
- fragP
->fr_fix
;
5236 /* If the fragP->fr_symbol is extern symbol, aim should be 0. */
5237 if (fragP
->fr_symbol
&& S_GET_SEGMENT (symbolP
) != segment
)
5242 /* Look backwards. */
5243 for (next_state
= this_type
->rlx_more
; next_state
;)
5244 if (aim
>= this_type
->rlx_backward
)
5248 /* Grow to next state. */
5249 this_state
= next_state
;
5250 this_type
= table
+ this_state
;
5251 next_state
= this_type
->rlx_more
;
5256 /* Look forwards. */
5257 for (next_state
= this_type
->rlx_more
; next_state
;)
5258 if (aim
<= this_type
->rlx_forward
)
5262 /* Grow to next state. */
5263 this_state
= next_state
;
5264 this_type
= table
+ this_state
;
5265 next_state
= this_type
->rlx_more
;
5269 growth
= this_type
->rlx_length
- start_type
->rlx_length
;
5271 fragP
->fr_subtype
= this_state
;
5276 md_estimate_size_before_relax (fragS
* fragp
,
5279 switch (fragp
->fr_subtype
)
5299 gas_assert (fragp
->fr_symbol
);
5300 if (IS_EXTERNAL_SYM (fragp
->fr_symbol
, segtype
))
5301 while (csky_relax_table
[fragp
->fr_subtype
].rlx_more
> RELAX_OVERFLOW
)
5302 fragp
->fr_subtype
= csky_relax_table
[fragp
->fr_subtype
].rlx_more
;
5303 return csky_relax_table
[fragp
->fr_subtype
].rlx_length
;
5305 /* C-SKY V1 relaxes. */
5306 case C (UNCD_JUMP
, UNDEF_DISP
):
5307 case C (UNCD_JUMP_PIC
, UNDEF_DISP
):
5308 if (!fragp
->fr_symbol
)
5309 fragp
->fr_subtype
= C (UNCD_JUMP_S
, DISP12
);
5310 else if (S_GET_SEGMENT (fragp
->fr_symbol
) == segtype
)
5311 fragp
->fr_subtype
= C (UNCD_JUMP_S
, DISP12
);
5313 fragp
->fr_subtype
= C (UNCD_JUMP_S
, UNDEF_WORD_DISP
);
5316 case C (COND_JUMP
, UNDEF_DISP
):
5317 case C (COND_JUMP_PIC
, UNDEF_DISP
):
5318 if (fragp
->fr_symbol
5319 && S_GET_SEGMENT (fragp
->fr_symbol
) == segtype
)
5320 /* Got a symbol and it's defined in this segment, become byte
5321 sized. Maybe it will fix up. */
5322 fragp
->fr_subtype
= C (COND_JUMP_S
, DISP12
);
5323 else if (fragp
->fr_symbol
)
5324 /* It's got a segment, but it's not ours, so it will always be
5326 fragp
->fr_subtype
= C (COND_JUMP_S
, UNDEF_WORD_DISP
);
5328 /* We know the abs value. */
5329 fragp
->fr_subtype
= C (COND_JUMP_S
, DISP12
);
5332 case C (UNCD_JUMP
, DISP12
):
5333 case C (UNCD_JUMP
, DISP32
):
5334 case C (UNCD_JUMP
, UNDEF_WORD_DISP
):
5335 case C (COND_JUMP
, DISP12
):
5336 case C (COND_JUMP
, DISP32
):
5337 case C (COND_JUMP
, UNDEF_WORD_DISP
):
5338 case C (UNCD_JUMP_PIC
, DISP12
):
5339 case C (UNCD_JUMP_PIC
, DISP32
):
5340 case C (UNCD_JUMP_PIC
, UNDEF_WORD_DISP
):
5341 case C (COND_JUMP_PIC
, DISP12
):
5342 case C (COND_JUMP_PIC
, DISP32
):
5343 case C (COND_JUMP_PIC
, UNDEF_WORD_DISP
):
5344 case RELAX_OVERFLOW
:
5350 return csky_relax_table
[fragp
->fr_subtype
].rlx_length
;
5353 /* Parse opcode like: "op oprnd1, oprnd2, oprnd3". */
5356 csky_macro_md_assemble (const char *op
,
5367 strcat (str
, oprnd1
);
5371 strcat (str
, oprnd2
);
5375 strcat (str
, oprnd3
);
5383 /* Get the string of operand. */
5386 csky_get_macro_operand (char *src_s
, char *dst_s
, char end_sym
)
5389 while (ISSPACE (*src_s
))
5391 while (*src_s
!= end_sym
)
5392 dst_s
[nlen
++] = *(src_s
++);
5397 /* idly 4 -> idly4. */
5402 char *s
= csky_insn
.opcode_end
;
5403 if (!is_imm_over_range (&s
, 4, 4, -1))
5405 as_bad (_("second operand must be 4"));
5408 csky_macro_md_assemble ("idly4", NULL
, NULL
, NULL
);
5412 /* rolc rd, 1 or roltc rd, 1 -> addc rd, rd. */
5418 char *s
= csky_insn
.opcode_end
;
5420 s
+= csky_get_macro_operand (s
, reg
, ',');
5423 if (is_imm_over_range (&s
, 1, 1, -1))
5425 csky_macro_md_assemble ("addc", reg
, reg
, NULL
);
5429 as_bad (_("second operand must be 1"));
5432 /* sxtrb0(1)(2) r1, rx -> xtbr0(1)(2) r1,rx; sextb r1. */
5440 char *s
= csky_insn
.opcode_end
;
5441 s
+= csky_get_macro_operand (s
, reg1
, ',');
5443 csky_get_macro_operand (s
, reg2
, '\0');
5445 csky_macro_md_assemble (csky_insn
.macro
->name
+ 1, reg1
, reg2
, NULL
);
5446 csky_macro_md_assemble ("sextb", reg1
, NULL
, NULL
);
5457 char *s
= csky_insn
.opcode_end
;
5458 s
+= csky_get_macro_operand (s
, reg1
, ',');
5461 s
+= csky_get_macro_operand (s
, reg2
, ',');
5464 s
+= csky_get_macro_operand (s
, reg3
, '\0');
5466 csky_macro_md_assemble ("movt", reg1
, reg2
, NULL
);
5467 csky_macro_md_assemble ("movf", reg1
, reg3
, NULL
);
5472 get_macro_reg_vals (int *reg1
, int *reg2
, int *reg3
)
5475 char *s
= csky_insn
.opcode_end
;
5477 *reg1
= csky_get_reg_val (s
, &nlen
);
5481 csky_show_error (ERROR_MISSING_COMMA
, 0, NULL
, NULL
);
5485 *reg2
= csky_get_reg_val (s
, &nlen
);
5489 csky_show_error (ERROR_MISSING_COMMA
, 0, NULL
, NULL
);
5493 *reg3
= csky_get_reg_val (s
, &nlen
);
5497 csky_show_error (ERROR_BAD_END
, 0, NULL
, NULL
);
5500 if (*reg1
== -1 || *reg2
== -1 || *reg3
== -1)
5502 as_bad (_("register number out of range"));
5507 as_bad (_("dest and source1 must be the same register"));
5510 if (*reg1
>= 15 || *reg3
>= 15)
5512 as_bad (_("64-bit operator src/dst register must be less than 15"));
5518 /* addc64 rx, rx, ry -> cmplt rx, rx, addc rx, ry, addc rx+1, ry+1. */
5527 if (!get_macro_reg_vals (®1
, ®2
, ®3
))
5529 csky_macro_md_assemble ("cmplt",
5530 csky_general_reg
[reg1
],
5531 csky_general_reg
[reg1
],
5533 csky_macro_md_assemble ("addc",
5534 csky_general_reg
[reg1
+ (target_big_endian
? 1 : 0)],
5535 csky_general_reg
[reg3
+ (target_big_endian
? 1 : 0)],
5537 csky_macro_md_assemble ("addc",
5538 csky_general_reg
[reg1
+ (target_big_endian
? 0 : 1)],
5539 csky_general_reg
[reg3
+ (target_big_endian
? 0 : 1)],
5544 /* subc64 rx, rx, ry -> cmphs rx, rx, subc rx, ry, subc rx+1, ry+1. */
5553 if (!get_macro_reg_vals (®1
, ®2
, ®3
))
5555 csky_macro_md_assemble ("cmphs",
5556 csky_general_reg
[reg1
],
5557 csky_general_reg
[reg1
],
5559 csky_macro_md_assemble ("subc",
5560 csky_general_reg
[reg1
+ (target_big_endian
? 1 : 0)],
5561 csky_general_reg
[reg3
+ (target_big_endian
? 1 : 0)],
5563 csky_macro_md_assemble ("subc",
5564 csky_general_reg
[reg1
+ (target_big_endian
? 0 : 1)],
5565 csky_general_reg
[reg3
+ (target_big_endian
? 0 : 1)],
5570 /* or64 rx, rx, ry -> or rx, ry, or rx+1, ry+1. */
5579 if (!get_macro_reg_vals (®1
, ®2
, ®3
))
5581 csky_macro_md_assemble ("or",
5582 csky_general_reg
[reg1
+ (target_big_endian
? 1 : 0)],
5583 csky_general_reg
[reg3
+ (target_big_endian
? 1 : 0)],
5585 csky_macro_md_assemble ("or",
5586 csky_general_reg
[reg1
+ (target_big_endian
? 0 : 1)],
5587 csky_general_reg
[reg3
+ (target_big_endian
? 0 : 1)],
5592 /* xor64 rx, rx, ry -> xor rx, ry, xor rx+1, ry+1. */
5601 if (!get_macro_reg_vals (®1
, ®2
, ®3
))
5603 csky_macro_md_assemble ("xor",
5604 csky_general_reg
[reg1
+ (target_big_endian
? 1 : 0)],
5605 csky_general_reg
[reg3
+ (target_big_endian
? 1 : 0)],
5607 csky_macro_md_assemble ("xor",
5608 csky_general_reg
[reg1
+ (target_big_endian
? 0 : 1)],
5609 csky_general_reg
[reg3
+ (target_big_endian
? 0 : 1)],
5614 /* The following are V2 macro instructions. */
5616 /* neg rd -> not rd, rd; addi rd, 1. */
5623 char *s
= csky_insn
.opcode_end
;
5624 s
+= csky_get_macro_operand (s
, reg1
, '\0');
5627 csky_macro_md_assemble ("not", reg1
, reg1
, NULL
);
5628 csky_macro_md_assemble ("addi", reg1
, "1", NULL
);
5632 /* rsubi rd, imm16 -> not rd; addi rd, imm16 + 1 */
5639 unsigned int imm16
= 0;
5641 char *s
= csky_insn
.opcode_end
;
5642 s
+= csky_get_macro_operand (s
, reg1
, ',');
5645 s
= parse_exp (s
, &e
);
5646 if (e
.X_op
== O_constant
)
5647 imm16
= e
.X_add_number
;
5649 csky_show_error (ERROR_IMM_ILLEGAL
, 2, NULL
, NULL
);
5651 sprintf (str_imm16
, "%d", imm16
+ 1);
5653 csky_macro_md_assemble ("not", reg1
, reg1
, NULL
);
5654 csky_macro_md_assemble ("addi", reg1
, str_imm16
, NULL
);
5658 /* Such as: asrc rd -> asrc rd, rd, 1. */
5664 char *s
= csky_insn
.opcode_end
;
5665 s
+= csky_get_macro_operand (s
, reg1
, '\0');
5667 csky_macro_md_assemble (csky_insn
.macro
->name
, reg1
, reg1
, "1");
5671 /* decne rd -> if ck802: subi rd, 1; cmpnei rd, 0.
5672 else: decne rd, rd, 1 */
5678 char *s
= csky_insn
.opcode_end
;
5679 s
+= csky_get_macro_operand (s
, reg1
, '\0');
5681 if (IS_CSKY_ARCH_802 (mach_flag
))
5683 csky_macro_md_assemble ("subi", reg1
, "1", NULL
);
5684 csky_macro_md_assemble ("cmpnei", reg1
, "0", NULL
);
5687 csky_macro_md_assemble ("decne", reg1
, reg1
, "1");
5691 /* If -mnolrw, lrw rd, imm -> movih rd, imm_hi16; ori rd, imm_lo16. */
5701 char *s
= csky_insn
.opcode_end
;
5702 s
+= csky_get_macro_operand (s
, reg1
, ',');
5704 s
+= csky_get_macro_operand (s
, imm
, '\0');
5708 strcat (imm_hi16
, "(");
5709 strcat (imm_hi16
, imm
);
5710 strcat (imm_hi16
, ") >> 16");
5712 strcat (imm_lo16
, "(");
5713 strcat (imm_lo16
, imm
);
5714 strcat (imm_lo16
, ") & 0xffff");
5716 csky_macro_md_assemble ("movih", reg1
, imm_hi16
, NULL
);
5717 csky_macro_md_assemble ("ori", reg1
, reg1
, imm_lo16
);
5722 /* The following are worker functions for C-SKY v1. */
5728 int output_literal
= csky_insn
.val
[1];
5730 reg
= csky_insn
.val
[0];
5731 csky_insn
.isize
= 2;
5732 csky_insn
.output
= frag_more (2);
5733 if (csky_insn
.e1
.X_op
== O_constant
5734 && csky_insn
.e1
.X_add_number
<= 0x7f
5735 && csky_insn
.e1
.X_add_number
>= 0)
5737 csky_insn
.inst
= 0x6000 | reg
| (csky_insn
.e1
.X_add_number
<< 4);
5740 csky_insn
.inst
= csky_insn
.opcode
->op16
[0].opcode
;
5741 csky_insn
.inst
|= reg
<< 8;
5744 int n
= enter_literal (&csky_insn
.e1
, 0, 0, 0);
5746 /* Create a reference to pool entry. */
5747 csky_insn
.e1
.X_op
= O_symbol
;
5748 csky_insn
.e1
.X_add_symbol
= poolsym
;
5749 csky_insn
.e1
.X_add_number
= n
<< 2;
5752 if (insn_reloc
== BFD_RELOC_CKCORE_TLS_GD32
5753 || insn_reloc
== BFD_RELOC_CKCORE_TLS_LDM32
5754 || insn_reloc
== BFD_RELOC_CKCORE_TLS_IE32
)
5756 literal_insn_offset
->tls_addend
.frag
= frag_now
;
5757 literal_insn_offset
->tls_addend
.offset
5759 - literal_insn_offset
->tls_addend
.frag
->fr_literal
);
5761 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
, 2,
5762 &csky_insn
.e1
, 1, BFD_RELOC_CKCORE_PCREL_IMM8BY4
);
5764 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
5770 v1_work_fpu_fo (void)
5776 struct csky_opcode_info
*opinfo
= NULL
;
5778 if (csky_insn
.isize
== 4)
5779 opinfo
= &csky_insn
.opcode
->op32
[csky_insn
.opcode_idx
];
5780 else if (csky_insn
.isize
== 2)
5781 opinfo
= &csky_insn
.opcode
->op16
[csky_insn
.opcode_idx
];
5783 /* Firstly, get general reg. */
5784 for (i
= 0;i
< opinfo
->operand_num
; i
++)
5785 if (opinfo
->oprnd
.oprnds
[i
].type
== OPRND_TYPE_GREG0_15
)
5786 greg
= csky_insn
.val
[i
];
5787 gas_assert (greg
!= -1);
5789 /* Secondly, get float inst. */
5790 csky_generate_insn ();
5791 inst
= csky_insn
.inst
;
5793 /* Now get greg and inst, we can write instruction to floating unit. */
5794 sprintf (buff
, "lrw %s,0x%x", csky_general_reg
[greg
], inst
);
5796 sprintf (buff
, "cpwir %s", csky_general_reg
[greg
]);
5803 v1_work_fpu_fo_fc (void)
5809 struct csky_opcode_info
*opinfo
= NULL
;
5811 if (csky_insn
.isize
== 4)
5812 opinfo
= &csky_insn
.opcode
->op32
[csky_insn
.opcode_idx
];
5813 else if (csky_insn
.isize
== 2)
5814 opinfo
= &csky_insn
.opcode
->op16
[csky_insn
.opcode_idx
];
5816 /* Firstly, get general reg. */
5817 for (i
= 0;i
< opinfo
->operand_num
; i
++)
5818 if (opinfo
->oprnd
.oprnds
[i
].type
== OPRND_TYPE_GREG0_15
)
5819 greg
= csky_insn
.val
[i
];
5820 gas_assert (greg
!= -1);
5822 /* Secondly, get float inst. */
5823 csky_generate_insn ();
5824 inst
= csky_insn
.inst
;
5826 /* Now get greg and inst, we can write instruction to floating unit. */
5827 sprintf (buff
, "lrw %s,0x%x", csky_general_reg
[greg
], inst
);
5829 sprintf (buff
, "cpwir %s", csky_general_reg
[greg
]);
5831 sprintf (buff
, "cprc");
5838 v1_work_fpu_write (void)
5844 greg
= csky_insn
.val
[0];
5845 freg
= csky_insn
.val
[1];
5847 /* Now get greg and freg, we can write instruction to floating unit. */
5848 sprintf (buff
, "cpwgr %s,%s", csky_general_reg
[greg
], csky_cp_reg
[freg
]);
5855 v1_work_fpu_read (void)
5861 greg
= csky_insn
.val
[0];
5862 freg
= csky_insn
.val
[1];
5863 /* Now get greg and freg, we can write instruction to floating unit. */
5864 sprintf (buff
, "cprgr %s,%s", csky_general_reg
[greg
], csky_cp_reg
[freg
]);
5871 v1_work_fpu_writed (void)
5877 greg
= csky_insn
.val
[0];
5878 freg
= csky_insn
.val
[1];
5882 as_bad (_("even register number required"));
5885 /* Now get greg and freg, we can write instruction to floating unit. */
5886 if (target_big_endian
)
5887 sprintf (buff
, "cpwgr %s,%s",
5888 csky_general_reg
[greg
+ 1], csky_cp_reg
[freg
]);
5890 sprintf (buff
, "cpwgr %s,%s",
5891 csky_general_reg
[greg
], csky_cp_reg
[freg
]);
5893 if (target_big_endian
)
5894 sprintf (buff
, "cpwgr %s,%s",
5895 csky_general_reg
[greg
], csky_cp_reg
[freg
+ 1]);
5897 sprintf (buff
, "cpwgr %s,%s",
5898 csky_general_reg
[greg
+ 1], csky_cp_reg
[freg
+ 1]);
5905 v1_work_fpu_readd (void)
5911 greg
= csky_insn
.val
[0];
5912 freg
= csky_insn
.val
[1];
5916 as_bad (_("even register number required"));
5919 /* Now get greg and freg, we can write instruction to floating unit. */
5920 if (target_big_endian
)
5921 sprintf (buff
, "cprgr %s,%s",
5922 csky_general_reg
[greg
+ 1], csky_cp_reg
[freg
]);
5924 sprintf (buff
, "cprgr %s,%s",
5925 csky_general_reg
[greg
], csky_cp_reg
[freg
]);
5927 if (target_big_endian
)
5928 sprintf (buff
, "cprgr %s,%s",
5929 csky_general_reg
[greg
], csky_cp_reg
[freg
+ 1]);
5931 sprintf (buff
, "cprgr %s,%s",
5932 csky_general_reg
[greg
+ 1], csky_cp_reg
[freg
+ 1]);
5938 /* The following are for csky pseudo handling. */
5943 csky_insn
.output
= frag_more (2);
5945 /* Generate fixup BFD_RELOC_CKCORE_PCREL_IMM11BY2. */
5946 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
5947 2, & csky_insn
.e1
, 1, BFD_RELOC_CKCORE_PCREL_IMM11BY2
);
5950 /* Using jsri instruction. */
5951 const char *name
= "jsri";
5952 csky_insn
.opcode
= (struct csky_opcode
*)
5953 hash_find (csky_opcodes_hash
, name
);
5954 csky_insn
.opcode_idx
= 0;
5955 csky_insn
.isize
= 2;
5957 int n
= enter_literal (&csky_insn
.e1
, 1, 0, 0);
5959 /* Create a reference to pool entry. */
5960 csky_insn
.e1
.X_op
= O_symbol
;
5961 csky_insn
.e1
.X_add_symbol
= poolsym
;
5962 csky_insn
.e1
.X_add_number
= n
<< 2;
5964 /* Generate fixup BFD_RELOC_CKCORE_PCREL_IMM8BY4. */
5965 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
5966 2, & csky_insn
.e1
, 1, BFD_RELOC_CKCORE_PCREL_IMM8BY4
);
5968 if (csky_insn
.e1
.X_op
!= O_absent
&& do_jsri2bsr
)
5969 /* Generate fixup BFD_RELOC_CKCORE_PCREL_JSR_IMM11BY2. */
5970 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
5971 2, & (litpool
+ (csky_insn
.e1
.X_add_number
>> 2))->e
,
5972 1, BFD_RELOC_CKCORE_PCREL_JSR_IMM11BY2
);
5974 csky_generate_insn ();
5976 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
5981 /* The following are worker functions for csky v2 instruction handling. */
5983 /* For nie/nir/ipush/ipop. */
5986 v2_work_istack (void)
5990 csky_show_error (ERROR_OPCODE_ILLEGAL
, 0, NULL
, NULL
);
5993 csky_insn
.output
= frag_more (csky_insn
.isize
);
5994 csky_insn
.inst
= csky_insn
.opcode
->op16
[0].opcode
;
5995 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6000 v2_work_btsti (void)
6003 && (csky_insn
.flag_force
== INSN_OPCODE16F
6004 || IS_CSKY_ARCH_801 (mach_flag
)))
6006 csky_show_error (ERROR_OPCODE_ILLEGAL
, 0, NULL
, NULL
);
6009 if (!do_extend_lrw
&& csky_insn
.isize
== 2)
6010 csky_insn
.isize
= 4;
6011 /* Generate relax or reloc if necessary. */
6012 csky_generate_frags ();
6013 /* Generate the insn by mask. */
6014 csky_generate_insn ();
6015 /* Write inst to frag. */
6016 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6023 csky_insn
.isize
= 2;
6024 if (csky_insn
.number
== 2)
6026 if (csky_insn
.val
[0] == 14
6027 && csky_insn
.val
[1] >= 0 && csky_insn
.val
[1] <= 0x1fc
6028 && (csky_insn
.val
[1] & 0x3) == 0
6029 && csky_insn
.flag_force
!= INSN_OPCODE32F
)
6031 /* addi sp, sp, imm. */
6032 csky_insn
.inst
= 0x1400 | ((csky_insn
.val
[1] >> 2) & 0x1f);
6033 csky_insn
.inst
|= (csky_insn
.val
[1] << 1) & 0x300;
6034 csky_insn
.output
= frag_more (2);
6036 else if (csky_insn
.val
[0] < 8
6037 && csky_insn
.val
[1] >= 1 && csky_insn
.val
[1] <= 0x100
6038 && csky_insn
.flag_force
!= INSN_OPCODE32F
)
6040 csky_insn
.inst
= 0x2000 | (csky_insn
.val
[0] << 8);
6041 csky_insn
.inst
|= (csky_insn
.val
[1] - 1);
6042 csky_insn
.output
= frag_more (2);
6044 else if (csky_insn
.val
[1] >= 1 && csky_insn
.val
[1] <= 0x10000
6045 && csky_insn
.flag_force
!= INSN_OPCODE16F
6046 && !IS_CSKY_ARCH_801 (mach_flag
))
6048 csky_insn
.inst
= 0xe4000000 | (csky_insn
.val
[0] << 21);
6049 csky_insn
.inst
|= csky_insn
.val
[0] << 16;
6050 csky_insn
.inst
|= (csky_insn
.val
[1] - 1);
6051 csky_insn
.isize
= 4;
6052 csky_insn
.output
= frag_more (4);
6056 csky_show_error (ERROR_OPERANDS_ILLEGAL
, 0,
6057 csky_insn
.opcode_end
, NULL
);
6061 else if (csky_insn
.number
== 3)
6063 if (csky_insn
.val
[0] == 14
6064 && csky_insn
.val
[1] == 14
6065 && csky_insn
.val
[2] >= 0 && csky_insn
.val
[2] <= 0x1fc
6066 && (csky_insn
.val
[2] & 0x3) == 0
6067 && csky_insn
.flag_force
!= INSN_OPCODE32F
)
6069 csky_insn
.inst
= 0x1400 | ((csky_insn
.val
[2] >> 2) & 0x1f);
6070 csky_insn
.inst
|= (csky_insn
.val
[2] << 1) & 0x300;
6071 csky_insn
.output
= frag_more (2);
6073 else if (csky_insn
.val
[0] < 8
6074 && csky_insn
.val
[1] == 14
6075 && csky_insn
.val
[2] >= 0 && csky_insn
.val
[2] <= 0x3fc
6076 && (csky_insn
.val
[2] & 0x3) == 0
6077 && csky_insn
.flag_force
!= INSN_OPCODE32F
)
6079 csky_insn
.inst
= 0x1800 | (csky_insn
.val
[0] << 8);
6080 csky_insn
.inst
|= csky_insn
.val
[2] >> 2;
6081 csky_insn
.output
= frag_more (2);
6083 else if (csky_insn
.val
[0] < 8
6084 && csky_insn
.val
[0] == csky_insn
.val
[1]
6085 && csky_insn
.val
[2] >= 1 && csky_insn
.val
[2] <= 0x100
6086 && csky_insn
.flag_force
!= INSN_OPCODE32F
)
6088 csky_insn
.inst
= 0x2000 | (csky_insn
.val
[0] << 8);
6089 csky_insn
.inst
|= (csky_insn
.val
[2] - 1);
6090 csky_insn
.output
= frag_more (2);
6092 else if (csky_insn
.val
[0] < 8
6093 && csky_insn
.val
[1] < 8
6094 && csky_insn
.val
[2] >= 1 && csky_insn
.val
[2] <= 0x8
6095 && csky_insn
.flag_force
!= INSN_OPCODE32F
)
6097 csky_insn
.inst
= 0x5802 | (csky_insn
.val
[0] << 5);
6098 csky_insn
.inst
|= csky_insn
.val
[1] << 8;
6099 csky_insn
.inst
|= (csky_insn
.val
[2] - 1) << 2;
6100 csky_insn
.output
= frag_more (2);
6102 else if (csky_insn
.val
[1] == 28
6103 && csky_insn
.val
[2] >= 1 && csky_insn
.val
[2] <= 0x40000
6104 && csky_insn
.flag_force
!= INSN_OPCODE16F
6105 && !IS_CSKY_ARCH_801 (mach_flag
))
6107 csky_insn
.inst
= 0xcc1c0000 | (csky_insn
.val
[0] << 21);
6108 csky_insn
.isize
= 4;
6109 csky_insn
.output
= frag_more (4);
6110 if (insn_reloc
== BFD_RELOC_CKCORE_GOTOFF
)
6112 fix_new_exp (frag_now
, csky_insn
.output
-frag_now
->fr_literal
,
6113 4, &csky_insn
.e1
, 0, BFD_RELOC_CKCORE_GOTOFF_IMM18
);
6116 csky_insn
.inst
|= (csky_insn
.val
[2] - 1);
6118 else if (csky_insn
.val
[2] >= 1 && csky_insn
.val
[2] <= 0x1000
6119 && csky_insn
.flag_force
!= INSN_OPCODE16F
6120 && !IS_CSKY_ARCH_801 (mach_flag
))
6122 csky_insn
.inst
= 0xe4000000 | (csky_insn
.val
[0] << 21);
6123 csky_insn
.inst
|= csky_insn
.val
[1] << 16;
6124 csky_insn
.inst
|= (csky_insn
.val
[2] - 1);
6125 csky_insn
.isize
= 4;
6126 csky_insn
.output
= frag_more (4);
6130 csky_show_error (ERROR_OPERANDS_ILLEGAL
, 0,
6131 (char *)csky_insn
.opcode_end
, NULL
);
6135 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6143 csky_insn
.isize
= 2;
6144 if (csky_insn
.number
== 2)
6146 if (csky_insn
.val
[0] == 14
6147 && csky_insn
.val
[1] >= 0 && csky_insn
.val
[2] <= 0x1fc
6148 && (csky_insn
.val
[1] & 0x3) == 0
6149 && csky_insn
.flag_force
!= INSN_OPCODE32F
)
6151 csky_insn
.inst
= 0x1420 | ((csky_insn
.val
[1] >> 2) & 0x1f);
6152 csky_insn
.inst
|= (csky_insn
.val
[1] << 1) & 0x300;
6154 else if (csky_insn
.val
[0] < 8
6155 && csky_insn
.val
[1] >= 1 && csky_insn
.val
[1] <= 0x100
6156 && csky_insn
.flag_force
!= INSN_OPCODE32F
)
6158 csky_insn
.inst
= 0x2800 | (csky_insn
.val
[0] << 8);
6159 csky_insn
.inst
|= (csky_insn
.val
[1] - 1);
6161 else if (csky_insn
.val
[1] >= 1 && csky_insn
.val
[1] <= 0x10000
6162 && csky_insn
.flag_force
!= INSN_OPCODE16F
6163 && !IS_CSKY_ARCH_801 (mach_flag
))
6165 csky_insn
.inst
= 0xe4001000 | (csky_insn
.val
[0] << 21);
6166 csky_insn
.inst
|= csky_insn
.val
[0] << 16;
6167 csky_insn
.inst
|= (csky_insn
.val
[1] - 1);
6168 csky_insn
.isize
= 4;
6172 csky_show_error (ERROR_OPERANDS_ILLEGAL
, 0,
6173 (char *)csky_insn
.opcode_end
, NULL
);
6177 else if (csky_insn
.number
== 3)
6179 if (csky_insn
.val
[0] == 14
6180 && csky_insn
.val
[1] == 14
6181 && csky_insn
.val
[2] >= 0 && csky_insn
.val
[2] <= 0x1fc
6182 && (csky_insn
.val
[2] & 0x3) == 0
6183 && csky_insn
.flag_force
!= INSN_OPCODE32F
)
6185 csky_insn
.inst
= 0x1420 | ((csky_insn
.val
[2] >> 2) & 0x1f);
6186 csky_insn
.inst
|= (csky_insn
.val
[2] << 1) & 0x300;
6189 else if (csky_insn
.val
[0] < 8
6190 && csky_insn
.val
[0] == csky_insn
.val
[1]
6191 && csky_insn
.val
[2] >= 1 && csky_insn
.val
[2] <= 0x100
6192 && csky_insn
.flag_force
!= INSN_OPCODE32F
)
6194 csky_insn
.inst
= 0x2800 | (csky_insn
.val
[0] << 8);
6195 csky_insn
.inst
|= (csky_insn
.val
[2] - 1);
6197 else if (csky_insn
.val
[0] < 8
6198 && csky_insn
.val
[1] < 8
6199 && csky_insn
.val
[2] >= 1 && csky_insn
.val
[2] <= 0x8
6200 && csky_insn
.flag_force
!= INSN_OPCODE32F
)
6202 csky_insn
.inst
= 0x5803 | (csky_insn
.val
[0] << 5);
6203 csky_insn
.inst
|= csky_insn
.val
[1] << 8;
6204 csky_insn
.inst
|= (csky_insn
.val
[2] - 1) << 2;
6206 else if (csky_insn
.val
[2] >= 1 && csky_insn
.val
[2] <= 0x1000
6207 && csky_insn
.flag_force
!= INSN_OPCODE16F
6208 && !IS_CSKY_ARCH_801 (mach_flag
))
6210 csky_insn
.inst
= 0xe4001000 | (csky_insn
.val
[0] << 21);
6211 csky_insn
.inst
|= csky_insn
.val
[1] << 16;
6212 csky_insn
.inst
|= (csky_insn
.val
[2] - 1);
6213 csky_insn
.isize
= 4;
6217 csky_show_error (ERROR_OPERANDS_ILLEGAL
, 0,
6218 (char *)csky_insn
.opcode_end
, NULL
);
6222 csky_insn
.output
= frag_more (csky_insn
.isize
);
6223 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6229 v2_work_add_sub (void)
6231 if (csky_insn
.number
== 3
6232 && (csky_insn
.val
[0] == csky_insn
.val
[1]
6233 || csky_insn
.val
[0] == csky_insn
.val
[2])
6234 && csky_insn
.val
[0] <= 15
6235 && csky_insn
.val
[1] <= 15
6236 && csky_insn
.val
[2] <= 15)
6238 if (!strstr (csky_insn
.opcode
->mnemonic
, "sub")
6239 || csky_insn
.val
[0] == csky_insn
.val
[1])
6241 csky_insn
.opcode_idx
= 0;
6242 csky_insn
.isize
= 2;
6243 if (csky_insn
.val
[0] == csky_insn
.val
[1])
6244 csky_insn
.val
[1] = csky_insn
.val
[2];
6246 csky_insn
.number
= 2;
6250 if (csky_insn
.isize
== 4
6251 && IS_CSKY_ARCH_801 (mach_flag
))
6253 if (csky_insn
.number
== 3)
6255 if (csky_insn
.val
[0] > 7)
6256 csky_show_error (ERROR_REG_OVER_RANGE
, 1,
6257 (void *)(long)csky_insn
.val
[0], NULL
);
6258 if (csky_insn
.val
[1] > 7)
6259 csky_show_error (ERROR_REG_OVER_RANGE
, 2,
6260 (void *)(long)csky_insn
.val
[1], NULL
);
6261 if (csky_insn
.val
[2] > 7)
6262 csky_show_error (ERROR_REG_OVER_RANGE
, 3,
6263 (void *)(long)csky_insn
.val
[2], NULL
);
6267 if (csky_insn
.val
[0] > 15)
6268 csky_show_error (ERROR_REG_OVER_RANGE
, 1,
6269 (void *)(long)csky_insn
.val
[0], NULL
);
6270 if (csky_insn
.val
[1] > 15)
6271 csky_show_error (ERROR_REG_OVER_RANGE
, 2,
6272 (void *)(long)csky_insn
.val
[1], NULL
);
6277 /* Generate relax or reloc if necessary. */
6278 csky_generate_frags ();
6279 /* Generate the insn by mask. */
6280 csky_generate_insn ();
6281 /* Write inst to frag. */
6282 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6287 v2_work_rotlc (void)
6289 const char *name
= "addc";
6291 = (struct csky_opcode
*) hash_find (csky_opcodes_hash
, name
);
6292 csky_insn
.opcode_idx
= 0;
6293 if (csky_insn
.isize
== 2)
6296 csky_insn
.number
= 2;
6297 csky_insn
.val
[1] = csky_insn
.val
[0];
6301 csky_insn
.number
= 3;
6302 /* addc rz, rx, ry. */
6303 csky_insn
.val
[1] = csky_insn
.val
[0];
6304 csky_insn
.val
[2] = csky_insn
.val
[0];
6306 /* Generate relax or reloc if necessary. */
6307 csky_generate_frags ();
6308 /* Generate the insn by mask. */
6309 csky_generate_insn ();
6310 /* Write inst to frag. */
6311 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6316 v2_work_bgeni (void)
6318 const char *name
= NULL
;
6319 int imm
= csky_insn
.val
[1];
6329 = (struct csky_opcode
*) hash_find (csky_opcodes_hash
, name
);
6330 csky_insn
.opcode_idx
= 0;
6331 csky_insn
.val
[1] = val
;
6333 /* Generate relax or reloc if necessary. */
6334 csky_generate_frags ();
6335 /* Generate the insn by mask. */
6336 csky_generate_insn ();
6337 /* Write inst to frag. */
6338 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6345 const char *name
= "nor";
6347 = (struct csky_opcode
*) hash_find (csky_opcodes_hash
, name
);
6348 csky_insn
.opcode_idx
= 0;
6349 if (csky_insn
.number
== 1)
6351 csky_insn
.val
[1] = csky_insn
.val
[0];
6352 if (csky_insn
.val
[0] < 16)
6354 /* 16 bits nor rz, rz. */
6355 csky_insn
.number
= 2;
6356 csky_insn
.isize
= 2;
6360 csky_insn
.val
[2] = csky_insn
.val
[0];
6361 csky_insn
.number
= 3;
6362 csky_insn
.isize
= 4;
6365 if (csky_insn
.number
== 2)
6367 if (csky_insn
.val
[0] == csky_insn
.val
[1]
6368 && csky_insn
.val
[0] < 16)
6370 /* 16 bits nor rz, rz. */
6371 csky_insn
.number
= 2;
6372 csky_insn
.isize
= 2;
6376 csky_insn
.val
[2] = csky_insn
.val
[1];
6377 csky_insn
.number
= 3;
6378 csky_insn
.isize
= 4;
6382 /* Generate relax or reloc if necessary. */
6383 csky_generate_frags ();
6384 /* Generate the insn by mask. */
6385 csky_generate_insn ();
6386 /* Write inst to frag. */
6387 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6394 if (csky_insn
.e1
.X_add_symbol
== NULL
|| csky_insn
.e1
.X_op
== O_constant
)
6396 csky_show_error (ERROR_UNDEFINE
, 0, (void *)"operand is invalid", NULL
);
6400 if (IS_CSKY_ARCH_801 (mach_flag
))
6402 /* CK801 doesn't have 32-bit bt/bf insns or a jump insn with a
6403 range larger than SCOND_DISP16. Relax to a short jump around
6404 an unconditional branch, and give up if that overflows too. */
6405 csky_insn
.output
= frag_var (rs_machine_dependent
,
6409 csky_insn
.e1
.X_add_symbol
,
6410 csky_insn
.e1
.X_add_number
,
6412 csky_insn
.isize
= 2;
6413 csky_insn
.max
= SCOND_DISP16_LEN
;
6414 csky_insn
.inst
= csky_insn
.opcode
->op16
[0].opcode
;
6416 else if (do_long_jump
&& !IS_CSKY_ARCH_802 (mach_flag
))
6418 /* Generate relax with jcondition.
6419 Note that CK802 doesn't support the JMPI instruction so
6420 we cannot relax to a jump with a 32-bit offset. */
6421 csky_insn
.output
= frag_var (rs_machine_dependent
,
6425 csky_insn
.e1
.X_add_symbol
,
6426 csky_insn
.e1
.X_add_number
,
6428 csky_insn
.isize
= 2;
6429 csky_insn
.max
= JCOND_DISP32_LEN
;
6430 csky_insn
.inst
= csky_insn
.opcode
->op16
[0].opcode
;
6434 /* Generate relax with condition. */
6435 csky_insn
.output
= frag_var (rs_machine_dependent
,
6439 csky_insn
.e1
.X_add_symbol
,
6440 csky_insn
.e1
.X_add_number
,
6442 csky_insn
.isize
= 2;
6443 csky_insn
.max
= COND_DISP16_LEN
;
6444 csky_insn
.inst
= csky_insn
.opcode
->op16
[0].opcode
;
6446 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6454 if (csky_insn
.e1
.X_add_symbol
== NULL
|| csky_insn
.e1
.X_op
== O_constant
)
6456 csky_show_error (ERROR_UNDEFINE
, 0, (void *)"operand is invalid", NULL
);
6461 && !IS_CSKY_ARCH_801 (mach_flag
)
6462 && !IS_CSKY_ARCH_802 (mach_flag
))
6464 csky_insn
.output
= frag_var (rs_machine_dependent
,
6468 csky_insn
.e1
.X_add_symbol
,
6469 csky_insn
.e1
.X_add_number
,
6472 csky_insn
.inst
= csky_insn
.opcode
->op16
[0].opcode
;
6473 csky_insn
.max
= JUNCD_DISP32_LEN
;
6474 csky_insn
.isize
= 2;
6478 /* Generate relax with condition. */
6479 csky_insn
.output
= frag_var (rs_machine_dependent
,
6483 csky_insn
.e1
.X_add_symbol
,
6484 csky_insn
.e1
.X_add_number
,
6486 csky_insn
.isize
= 2;
6487 csky_insn
.max
= UNCD_DISP16_LEN
;
6488 csky_insn
.inst
= csky_insn
.opcode
->op16
[0].opcode
;
6491 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6495 #define SIZE_V2_MOVI16(x) ((addressT)x <= 0xff)
6496 #define SIZE_V2_MOVI32(x) ((addressT)x <= 0xffff)
6497 #define SIZE_V2_MOVIH(x) ((addressT)x <= 0xffffffff && (((addressT)x & 0xffff) == 0))
6502 int reg
= csky_insn
.val
[0];
6503 int output_literal
= csky_insn
.val
[1];
6506 /* If the second operand is O_constant, We can use movi/movih
6508 if (csky_insn
.e1
.X_op
== O_constant
)
6510 /* 801 only has movi16. */
6511 if (SIZE_V2_MOVI16 (csky_insn
.e1
.X_add_number
) && reg
< 8)
6513 /* movi16 instead. */
6514 csky_insn
.output
= frag_more (2);
6515 csky_insn
.inst
= (CSKYV2_INST_MOVI16
| (reg
<< 8)
6516 | (csky_insn
.e1
.X_add_number
));
6517 csky_insn
.isize
= 2;
6520 else if (SIZE_V2_MOVI32 (csky_insn
.e1
.X_add_number
)
6521 && !IS_CSKY_ARCH_801 (mach_flag
))
6523 /* movi32 instead. */
6524 csky_insn
.output
= frag_more (4);
6525 csky_insn
.inst
= (CSKYV2_INST_MOVI32
| (reg
<< 16)
6526 | (csky_insn
.e1
.X_add_number
));
6527 csky_insn
.isize
= 4;
6530 else if (SIZE_V2_MOVIH (csky_insn
.e1
.X_add_number
)
6531 && !IS_CSKY_ARCH_801 (mach_flag
))
6533 /* movih instead. */
6534 csky_insn
.output
= frag_more (4);
6535 csky_insn
.inst
= (CSKYV2_INST_MOVIH
| (reg
<< 16)
6536 | ((csky_insn
.e1
.X_add_number
>> 16) & 0xffff));
6537 csky_insn
.isize
= 4;
6544 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6550 int n
= enter_literal (&csky_insn
.e1
, 0, 0, 0);
6551 /* Create a reference to pool entry. */
6552 csky_insn
.e1
.X_op
= O_symbol
;
6553 csky_insn
.e1
.X_add_symbol
= poolsym
;
6554 csky_insn
.e1
.X_add_number
= n
<< 2;
6556 /* If 16bit force. */
6557 if (csky_insn
.flag_force
== INSN_OPCODE16F
)
6559 /* Generate fixup. */
6562 csky_show_error (ERROR_UNDEFINE
, 0,
6563 (void *)"The register is out of range.", NULL
);
6566 csky_insn
.isize
= 2;
6567 csky_insn
.output
= frag_more (2);
6569 if (insn_reloc
== BFD_RELOC_CKCORE_TLS_GD32
6570 || insn_reloc
== BFD_RELOC_CKCORE_TLS_LDM32
6571 || insn_reloc
== BFD_RELOC_CKCORE_TLS_IE32
)
6573 literal_insn_offset
->tls_addend
.frag
= frag_now
;
6574 literal_insn_offset
->tls_addend
.offset
6575 = csky_insn
.output
- frag_now
->fr_literal
;
6577 csky_insn
.inst
= csky_insn
.opcode
->op16
[0].opcode
| (reg
<< 5);
6579 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
6580 2, &csky_insn
.e1
, 1, BFD_RELOC_CKCORE_PCREL_IMM7BY4
);
6582 else if (csky_insn
.flag_force
== INSN_OPCODE32F
)
6584 csky_insn
.isize
= 4;
6585 csky_insn
.output
= frag_more (4);
6586 if (insn_reloc
== BFD_RELOC_CKCORE_TLS_GD32
6587 || insn_reloc
== BFD_RELOC_CKCORE_TLS_LDM32
6588 || insn_reloc
== BFD_RELOC_CKCORE_TLS_IE32
)
6590 literal_insn_offset
->tls_addend
.frag
= frag_now
;
6591 literal_insn_offset
->tls_addend
.offset
6592 = csky_insn
.output
- frag_now
->fr_literal
;
6594 csky_insn
.inst
= csky_insn
.opcode
->op32
[0].opcode
| (reg
<< 16);
6595 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
6596 4, &csky_insn
.e1
, 1, BFD_RELOC_CKCORE_PCREL_IMM16BY4
);
6602 csky_insn
.isize
= 2;
6604 if (insn_reloc
== BFD_RELOC_CKCORE_TLS_GD32
6605 || insn_reloc
== BFD_RELOC_CKCORE_TLS_LDM32
6606 || insn_reloc
== BFD_RELOC_CKCORE_TLS_IE32
)
6607 literal_insn_offset
->tls_addend
.frag
= frag_now
;
6609 csky_insn
.output
= frag_var (rs_machine_dependent
,
6613 ? LRW2_DISP8
: LRW_DISP7
),
6614 csky_insn
.e1
.X_add_symbol
,
6615 csky_insn
.e1
.X_add_number
, 0);
6616 if (insn_reloc
== BFD_RELOC_CKCORE_TLS_GD32
6617 || insn_reloc
== BFD_RELOC_CKCORE_TLS_LDM32
6618 || insn_reloc
== BFD_RELOC_CKCORE_TLS_IE32
)
6620 if (literal_insn_offset
->tls_addend
.frag
->fr_next
!= frag_now
)
6621 literal_insn_offset
->tls_addend
.frag
6622 = literal_insn_offset
->tls_addend
.frag
->fr_next
;
6623 literal_insn_offset
->tls_addend
.offset
6625 - literal_insn_offset
->tls_addend
.frag
->fr_literal
);
6627 csky_insn
.inst
= csky_insn
.opcode
->op16
[0].opcode
| (reg
<< 5);
6628 csky_insn
.max
= LRW_DISP16_LEN
;
6629 csky_insn
.isize
= 2;
6633 csky_insn
.isize
= 4;
6634 csky_insn
.output
= frag_more (4);
6635 if (insn_reloc
== BFD_RELOC_CKCORE_TLS_GD32
6636 || insn_reloc
== BFD_RELOC_CKCORE_TLS_LDM32
6637 || insn_reloc
== BFD_RELOC_CKCORE_TLS_IE32
)
6639 literal_insn_offset
->tls_addend
.frag
= frag_now
;
6640 literal_insn_offset
->tls_addend
.offset
6641 = csky_insn
.output
- frag_now
->fr_literal
;
6643 csky_insn
.inst
= csky_insn
.opcode
->op32
[0].opcode
| (reg
<< 16);
6644 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
6645 4, &csky_insn
.e1
, 1, BFD_RELOC_CKCORE_PCREL_IMM16BY4
);
6649 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6654 v2_work_lrsrsw (void)
6656 int reg
= csky_insn
.val
[0];
6657 csky_insn
.output
= frag_more (4);
6658 csky_insn
.inst
= csky_insn
.opcode
->op32
[0].opcode
| (reg
<< 21);
6659 csky_insn
.isize
= 4;
6663 case BFD_RELOC_CKCORE_GOT32
:
6664 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
6665 4, &csky_insn
.e1
, 0, BFD_RELOC_CKCORE_GOT_IMM18BY4
);
6667 case BFD_RELOC_CKCORE_PLT32
:
6668 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
6669 4, &csky_insn
.e1
, 0, BFD_RELOC_CKCORE_PLT_IMM18BY4
);
6672 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
6673 4, &csky_insn
.e1
, 1, BFD_RELOC_CKCORE_DOFFSET_IMM18BY4
);
6676 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6684 || IS_CSKY_ARCH_801 (mach_flag
)
6685 || IS_CSKY_ARCH_802 (mach_flag
))
6687 csky_insn
.output
= frag_more (4);
6688 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
6689 4, &csky_insn
.e1
, 1, BFD_RELOC_CKCORE_PCREL_IMM26BY2
);
6690 csky_insn
.isize
= 4;
6691 csky_insn
.inst
= CSKYV2_INST_BSR32
;
6695 int n
= enter_literal (&csky_insn
.e1
, 0, 0, 0);
6696 csky_insn
.output
= frag_more (4);
6697 csky_insn
.e1
.X_op
= O_symbol
;
6698 csky_insn
.e1
.X_add_symbol
= poolsym
;
6699 csky_insn
.e1
.X_add_number
= n
<< 2;
6700 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
6701 4, &csky_insn
.e1
, 1, BFD_RELOC_CKCORE_PCREL_IMM16BY4
);
6702 if (do_jsri2bsr
|| IS_CSKY_ARCH_810 (mach_flag
))
6703 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
6705 &(litpool
+ (csky_insn
.e1
.X_add_number
>> 2))->e
,
6707 BFD_RELOC_CKCORE_PCREL_JSR_IMM26BY2
);
6708 csky_insn
.inst
= CSKYV2_INST_JSRI32
;
6709 csky_insn
.isize
= 4;
6710 if (IS_CSKY_ARCH_810 (mach_flag
))
6712 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6713 csky_insn
.output
= frag_more (4);
6714 dwarf2_emit_insn (0);
6715 /* Insert "mov r0, r0". */
6716 csky_insn
.inst
= CSKYV2_INST_MOV_R0_R0
;
6720 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6729 int n
= enter_literal (&csky_insn
.e1
, 1, 0, 0);
6730 csky_insn
.e1
.X_op
= O_symbol
;
6731 csky_insn
.e1
.X_add_symbol
= poolsym
;
6732 csky_insn
.e1
.X_add_number
= n
<< 2;
6734 /* Generate relax or reloc if necessary. */
6735 csky_generate_frags ();
6736 /* Generate the insn by mask. */
6737 csky_generate_insn ();
6738 /* Write inst to frag. */
6739 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6740 /* Control 810 not to generate jsri. */
6741 if (IS_CSKY_ARCH_810 (mach_flag
))
6743 /* Look at adding the R_PCREL_JSRIMM26BY2.
6744 For 'jbsr .L1', this reloc type's symbol
6745 is bound to '.L1', isn't bound to literal pool. */
6746 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
6747 4, &(litpool
+ (csky_insn
.e1
.X_add_number
>> 2))->e
, 1,
6748 BFD_RELOC_CKCORE_PCREL_JSR_IMM26BY2
);
6749 csky_insn
.output
= frag_more (4);
6750 dwarf2_emit_insn (0);
6751 /* The opcode of "mov32 r0,r0". */
6752 csky_insn
.inst
= CSKYV2_INST_MOV_R0_R0
;
6753 /* The effect of this value is to check literal. */
6754 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6761 v2_work_movih (void)
6763 int rz
= csky_insn
.val
[0];
6764 csky_insn
.output
= frag_more (4);
6765 csky_insn
.inst
= csky_insn
.opcode
->op32
[0].opcode
| (rz
<< 16);
6766 if (csky_insn
.e1
.X_op
== O_constant
)
6768 if (csky_insn
.e1
.X_unsigned
== 1 && csky_insn
.e1
.X_add_number
> 0xffff)
6770 csky_show_error (ERROR_IMM_OVERFLOW
, 2, NULL
, NULL
);
6773 else if (csky_insn
.e1
.X_unsigned
== 0 && csky_insn
.e1
.X_add_number
< 0)
6775 csky_show_error (ERROR_IMM_OVERFLOW
, 2, NULL
, NULL
);
6779 csky_insn
.inst
|= (csky_insn
.e1
.X_add_number
& 0xffff);
6781 else if (csky_insn
.e1
.X_op
== O_right_shift
6782 || (csky_insn
.e1
.X_op
== O_symbol
&& insn_reloc
!= BFD_RELOC_NONE
))
6784 if (csky_insn
.e1
.X_op_symbol
!= 0
6785 && symbol_constant_p (csky_insn
.e1
.X_op_symbol
)
6786 && S_GET_SEGMENT (csky_insn
.e1
.X_op_symbol
) == absolute_section
6787 && 16 == S_GET_VALUE (csky_insn
.e1
.X_op_symbol
))
6789 csky_insn
.e1
.X_op
= O_symbol
;
6790 if (insn_reloc
== BFD_RELOC_CKCORE_GOT32
)
6791 insn_reloc
= BFD_RELOC_CKCORE_GOT_HI16
;
6792 else if (insn_reloc
== BFD_RELOC_CKCORE_PLT32
)
6793 insn_reloc
= BFD_RELOC_CKCORE_PLT_HI16
;
6794 else if (insn_reloc
== BFD_RELOC_CKCORE_GOTPC
)
6795 insn_reloc
= BFD_RELOC_CKCORE_GOTPC_HI16
;
6796 else if (insn_reloc
== BFD_RELOC_CKCORE_GOTOFF
)
6797 insn_reloc
= BFD_RELOC_CKCORE_GOTOFF_HI16
;
6799 insn_reloc
= BFD_RELOC_CKCORE_ADDR_HI16
;
6800 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
6801 4, &csky_insn
.e1
, 0, insn_reloc
);
6805 void *arg
= (void *)"the second operand must be \"SYMBOL >> 16\"";
6806 csky_show_error (ERROR_UNDEFINE
, 0, arg
, NULL
);
6810 csky_insn
.isize
= 4;
6811 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6819 int rz
= csky_insn
.val
[0];
6820 int rx
= csky_insn
.val
[1];
6821 csky_insn
.output
= frag_more (4);
6822 csky_insn
.inst
= csky_insn
.opcode
->op32
[0].opcode
| (rz
<< 21) | (rx
<< 16);
6823 if (csky_insn
.e1
.X_op
== O_constant
)
6825 if (csky_insn
.e1
.X_add_number
<= 0xffff
6826 && csky_insn
.e1
.X_add_number
>= 0)
6827 csky_insn
.inst
|= csky_insn
.e1
.X_add_number
;
6830 csky_show_error (ERROR_IMM_OVERFLOW
, 3, NULL
, NULL
);
6834 else if (csky_insn
.e1
.X_op
== O_bit_and
)
6836 if (symbol_constant_p (csky_insn
.e1
.X_op_symbol
)
6837 && S_GET_SEGMENT (csky_insn
.e1
.X_op_symbol
) == absolute_section
6838 && 0xffff == S_GET_VALUE (csky_insn
.e1
.X_op_symbol
))
6840 csky_insn
.e1
.X_op
= O_symbol
;
6841 if (insn_reloc
== BFD_RELOC_CKCORE_GOT32
)
6842 insn_reloc
= BFD_RELOC_CKCORE_GOT_LO16
;
6843 else if (insn_reloc
== BFD_RELOC_CKCORE_PLT32
)
6844 insn_reloc
= BFD_RELOC_CKCORE_PLT_LO16
;
6845 else if (insn_reloc
== BFD_RELOC_CKCORE_GOTPC
)
6846 insn_reloc
= BFD_RELOC_CKCORE_GOTPC_LO16
;
6847 else if (insn_reloc
== BFD_RELOC_CKCORE_GOTOFF
)
6848 insn_reloc
= BFD_RELOC_CKCORE_GOTOFF_LO16
;
6850 insn_reloc
= BFD_RELOC_CKCORE_ADDR_LO16
;
6851 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
6852 4, &csky_insn
.e1
, 0, insn_reloc
);
6856 void *arg
= (void *)"the third operand must be \"SYMBOL & 0xffff\"";
6857 csky_show_error (ERROR_UNDEFINE
, 0, arg
, NULL
);
6861 csky_insn
.isize
= 4;
6862 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6866 /* Helper function to encode a single/double floating point constant
6867 into the instruction word for fmovis and fmovid instructions.
6868 The constant is in its IEEE single/double precision representation
6869 and is repacked into the internal 13-bit representation for these
6870 instructions with a diagnostic for overflow. Note that there is no
6871 rounding when converting to the smaller format, just an error if there
6872 is excess precision or the number is too small/large to be represented. */
6875 float_work_fmovi (void)
6877 int rx
= csky_insn
.val
[0];
6879 /* We already converted the float constant to the internal 13-bit
6880 representation so we just need to OR it in here. */
6881 csky_insn
.inst
= csky_insn
.opcode
->op32
[0].opcode
| rx
;
6882 csky_insn
.inst
|= (uint32_t) csky_insn
.e1
.X_add_number
;
6884 csky_insn
.output
= frag_more (4);
6885 csky_insn
.isize
= 4;
6886 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6891 dsp_work_bloop (void)
6893 int reg
= csky_insn
.val
[0];
6894 csky_insn
.output
= frag_more (4);
6895 csky_insn
.inst
= csky_insn
.opcode
->op32
[0].opcode
| (reg
<< 16);
6896 csky_insn
.isize
= 4;
6898 if (csky_insn
.e1
.X_op
== O_symbol
6899 && csky_insn
.e2
.X_op
== O_symbol
)
6901 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
6902 4, &csky_insn
.e1
, 1,
6903 BFD_RELOC_CKCORE_PCREL_BLOOP_IMM12BY4
);
6904 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
6905 4, &csky_insn
.e2
, 1,
6906 BFD_RELOC_CKCORE_PCREL_BLOOP_IMM4BY4
);
6909 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6914 /* The following are for assembler directive handling. */
6916 /* Helper function to adjust constant pool counts when we emit a
6917 data directive in the text section. FUNC is one of the standard
6918 gas functions to handle these directives, like "stringer" for the
6919 .string directive, and ARG is the argument to FUNC. csky_pool_count
6920 essentially wraps the call with the constant pool magic. */
6923 csky_pool_count (void (*func
) (int), int arg
)
6925 const fragS
*curr_frag
= frag_now
;
6926 offsetT added
= -frag_now_fix_octets ();
6930 while (curr_frag
!= frag_now
)
6932 added
+= curr_frag
->fr_fix
;
6933 curr_frag
= curr_frag
->fr_next
;
6936 added
+= frag_now_fix_octets ();
6940 /* Support the .literals directive. */
6942 csky_s_literals (int ignore ATTRIBUTE_UNUSED
)
6945 demand_empty_rest_of_line ();
6948 /* Support the .string, etc directives. */
6950 csky_stringer (int append_zero
)
6952 if (now_seg
== text_section
)
6953 csky_pool_count (stringer
, append_zero
);
6955 stringer (append_zero
);
6957 /* We call check_literals here in case a large number of strings are
6958 being placed into the text section with a sequence of stringer
6959 directives. In theory we could be upsetting something if these
6960 strings are actually in an indexed table instead of referenced by
6961 individual labels. Let us hope that that never happens. */
6962 check_literals (2, 0);
6965 /* Support integer-mode constructors like .word, .byte, etc. */
6968 csky_cons (int nbytes
)
6970 mapping_state (MAP_DATA
);
6971 if (nbytes
== 4) /* @GOT. */
6975 bfd_reloc_code_real_type reloc
;
6978 reloc
= BFD_RELOC_NONE
;
6980 lex_got (&reloc
, NULL
);
6982 if (exp
.X_op
== O_symbol
&& reloc
!= BFD_RELOC_NONE
)
6984 reloc_howto_type
*howto
6985 = bfd_reloc_type_lookup (stdoutput
, reloc
);
6986 int size
= bfd_get_reloc_size (howto
);
6989 as_bad (ngettext ("%s relocations do not fit in %d byte",
6990 "%s relocations do not fit in %d bytes",
6992 howto
->name
, nbytes
);
6995 register char *p
= frag_more ((int) nbytes
);
6996 int offset
= nbytes
- size
;
6998 fix_new_exp (frag_now
,
6999 p
- frag_now
->fr_literal
+ offset
,
7000 size
, &exp
, 0, reloc
);
7004 emit_expr (&exp
, (unsigned int) nbytes
);
7005 if (now_seg
== text_section
)
7008 while (*input_line_pointer
++ == ',');
7010 /* Put terminator back into stream. */
7011 input_line_pointer
--;
7012 demand_empty_rest_of_line ();
7017 if (now_seg
== text_section
)
7018 csky_pool_count (cons
, nbytes
);
7022 /* In theory we ought to call check_literals (2,0) here in case
7023 we need to dump the literal table. We cannot do this however,
7024 as the directives that we are intercepting may be being used
7025 to build a switch table, and we must not interfere with its
7026 contents. Instead we cross our fingers and pray... */
7029 /* Support floating-mode constant directives like .float and .double. */
7032 csky_float_cons (int float_type
)
7034 mapping_state (MAP_DATA
);
7035 if (now_seg
== text_section
)
7036 csky_pool_count (float_cons
, float_type
);
7038 float_cons (float_type
);
7040 /* See the comment in csky_cons () about calling check_literals.
7041 It is unlikely that a switch table will be constructed using
7042 floating point values, but it is still likely that an indexed
7043 table of floating point constants is being created by these
7044 directives, so again we must not interfere with their placement. */
7047 /* Support the .fill directive. */
7050 csky_fill (int ignore
)
7052 if (now_seg
== text_section
)
7053 csky_pool_count (s_fill
, ignore
);
7057 check_literals (2, 0);
7060 /* Handle the section changing pseudo-ops. These call through to the
7061 normal implementations, but they dump the literal pool first. */
7064 csky_s_text (int ignore
)
7069 obj_elf_text (ignore
);
7076 csky_s_data (int ignore
)
7081 obj_elf_data (ignore
);
7088 csky_s_section (int ignore
)
7090 /* Scan forwards to find the name of the section. If the section
7091 being switched to is ".line" then this is a DWARF1 debug section
7092 which is arbitrarily placed inside generated code. In this case
7093 do not dump the literal pool because it is a) inefficient and
7094 b) would require the generation of extra code to jump around the
7096 char * ilp
= input_line_pointer
;
7098 while (*ilp
!= 0 && ISSPACE (*ilp
))
7101 if (strncmp (ilp
, ".line", 5) == 0
7102 && (ISSPACE (ilp
[5]) || *ilp
== '\n' || *ilp
== '\r'))
7108 obj_elf_section (ignore
);
7111 obj_coff_section (ignore
);
7116 csky_s_bss (int needs_align
)
7119 s_lcomm_bytes (needs_align
);
7124 csky_s_comm (int needs_align
)
7127 obj_elf_common (needs_align
);
7131 /* Handle the .no_literal_dump directive. */
7134 csky_noliteraldump (int ignore ATTRIBUTE_UNUSED
)
7136 do_noliteraldump
= 1;
7137 int insn_num
= get_absolute_expression ();
7138 /* The insn after '.no_literal_dump insn_num' is insn1,
7139 Don't dump literal pool between insn1 and insn(insn_num+1)
7140 The insn cannot be the insn generate literal, like lrw & jsri. */
7141 check_literals (0, insn_num
* 2);
7144 /* Handle the .align directive.
7145 We must check literals before doing alignment. For example, if
7146 '.align n', add (2^n-1) to poolspan and check literals. */
7149 csky_s_align_ptwo (int arg
)
7151 /* Get the .align's first absolute number. */
7152 char * temp_pointer
= input_line_pointer
;
7153 int align
= get_absolute_expression ();
7154 check_literals (0, (1 << align
) - 1);
7155 input_line_pointer
= temp_pointer
;
7161 /* Handle the .stack_size directive. */
7164 csky_stack_size (int arg ATTRIBUTE_UNUSED
)
7167 stack_size_entry
*sse
7168 = (stack_size_entry
*) xcalloc (1, sizeof (stack_size_entry
));
7171 if (exp
.X_op
== O_symbol
)
7172 sse
->function
= exp
.X_add_symbol
;
7175 as_bad (_("the first operand must be a symbol"));
7176 ignore_rest_of_line ();
7182 if (*input_line_pointer
!= ',')
7184 as_bad (_("missing stack size"));
7185 ignore_rest_of_line ();
7190 ++input_line_pointer
;
7192 if (exp
.X_op
== O_constant
)
7194 if (exp
.X_add_number
< 0 || exp
.X_add_number
> (offsetT
)0xffffffff)
7197 as_bad (_("value not in range [0, 0xffffffff]"));
7198 ignore_rest_of_line ();
7203 sse
->stack_size
= exp
.X_add_number
;
7207 as_bad (_("operand must be a constant"));
7208 ignore_rest_of_line ();
7213 if (*last_stack_size_data
!= NULL
)
7214 last_stack_size_data
= &((*last_stack_size_data
)->next
);
7216 *last_stack_size_data
= sse
;
7219 /* This table describes all the machine specific pseudo-ops the assembler
7220 has to support. The fields are:
7221 pseudo-op name without dot
7222 function to call to execute this pseudo-op
7223 Integer arg to pass to the function. */
7225 const pseudo_typeS md_pseudo_table
[] =
7227 { "export", s_globl
, 0 },
7228 { "import", s_ignore
, 0 },
7229 { "literals", csky_s_literals
, 0 },
7230 { "page", listing_eject
, 0 },
7232 /* The following are to intercept the placement of data into the text
7233 section (eg addresses for a switch table), so that the space they
7234 occupy can be taken into account when deciding whether or not to
7235 dump the current literal pool.
7236 XXX - currently we do not cope with the .space and .dcb.d directives. */
7237 { "ascii", csky_stringer
, 8 + 0 },
7238 { "asciz", csky_stringer
, 8 + 1 },
7239 { "byte", csky_cons
, 1 },
7240 { "dc", csky_cons
, 2 },
7241 { "dc.b", csky_cons
, 1 },
7242 { "dc.d", csky_float_cons
, 'd'},
7243 { "dc.l", csky_cons
, 4 },
7244 { "dc.s", csky_float_cons
, 'f'},
7245 { "dc.w", csky_cons
, 2 },
7246 { "dc.x", csky_float_cons
, 'x'},
7247 { "double", csky_float_cons
, 'd'},
7248 { "float", csky_float_cons
, 'f'},
7249 { "hword", csky_cons
, 2 },
7250 { "int", csky_cons
, 4 },
7251 { "long", csky_cons
, 4 },
7252 { "octa", csky_cons
, 16 },
7253 { "quad", csky_cons
, 8 },
7254 { "short", csky_cons
, 2 },
7255 { "single", csky_float_cons
, 'f'},
7256 { "string", csky_stringer
, 8 + 1 },
7257 { "word", csky_cons
, 4 },
7258 { "fill", csky_fill
, 0 },
7260 /* Allow for the effect of section changes. */
7261 { "text", csky_s_text
, 0 },
7262 { "data", csky_s_data
, 0 },
7263 { "bss", csky_s_bss
, 1 },
7265 { "comm", csky_s_comm
, 0 },
7267 { "section", csky_s_section
, 0 },
7268 { "section.s", csky_s_section
, 0 },
7269 { "sect", csky_s_section
, 0 },
7270 { "sect.s", csky_s_section
, 0 },
7271 /* When ".no_literal_dump N" is in front of insn1,
7272 and instruction sequence is:
7277 it means literals will not dump between insn1 and insnN+1
7278 The insn cannot itself generate literal, like lrw & jsri. */
7279 { "no_literal_dump", csky_noliteraldump
, 0 },
7280 { "align", csky_s_align_ptwo
, 0 },
7281 { "stack_size", csky_stack_size
, 0 },
7285 /* Implement tc_cfi_frame_initial_instructions. */
7288 csky_cfi_frame_initial_instructions (void)
7290 int sp_reg
= IS_CSKY_V1 (mach_flag
) ? 0 : 14;
7291 cfi_add_CFA_def_cfa_register (sp_reg
);
7294 /* Implement tc_regname_to_dw2regnum. */
7297 tc_csky_regname_to_dw2regnum (char *regname
)
7302 /* FIXME the reg should be parsed according to
7304 reg_num
= csky_get_reg_val (regname
, &len
);