1 /* tc-csky.c -- Assembler for C-SKY
2 Copyright (C) 1989-2019 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 buf
[22] = 0; /* initialise. */
4431 fragp
->fr_fix
+= C32_LEN_PIC
;
4433 } /* end if is_unaligned. */
4434 } /* end case C (COND_JUMP_PIC, DISP32)/C (COND_JUMP_PIC, UNDEF_WORD_DISP). */
4436 case C (UNCD_JUMP
, DISP32
):
4437 case C (UNCD_JUMP
, UNDEF_WORD_DISP
):
4442 int first_inst
= fragp
->fr_fix
+ fragp
->fr_address
;
4443 int is_unaligned
= (first_inst
& 3);
4445 buf
[0] = BYTE_0 (CSKYV1_INST_JMPI
);
4446 buf
[1] = BYTE_1 (CSKYV1_INST_JMPI
);
4449 if (!target_big_endian
)
4461 fix_new (fragp
, fragp
->fr_fix
+ 4, 4,
4462 fragp
->fr_symbol
, fragp
->fr_offset
, 0, BFD_RELOC_32
);
4463 fragp
->fr_fix
+= U32_LEN
;
4465 else /* if is_unaligned. */
4467 if (!target_big_endian
)
4476 fix_new (fragp
, fragp
->fr_fix
+ 2, 4,
4477 fragp
->fr_symbol
, fragp
->fr_offset
, 0, BFD_RELOC_32
);
4478 fragp
->fr_fix
+= U32_LEN
;
4483 case C (UNCD_JUMP_PIC
, DISP32
):
4484 case C (UNCD_JUMP_PIC
, UNDEF_WORD_DISP
):
4496 0: .long (tar_add - pc)
4499 /* If the b!cond is 4 byte aligned, the literal which would
4500 go at x+4 will also be aligned. */
4501 int first_inst
= fragp
->fr_fix
+ fragp
->fr_address
;
4502 int is_unaligned
= (first_inst
& 3);
4505 buf
[0] = BYTE_0 (CSKYV1_INST_SUBI
| (7 << 4)); /* subi r0, 8. */
4506 buf
[1] = BYTE_1 (CSKYV1_INST_SUBI
| (7 << 4));
4507 buf
[2] = BYTE_0 (CSKYV1_INST_STW
| (15 << 8)); /* stw r15, r0. */
4508 buf
[3] = BYTE_1 (CSKYV1_INST_STW
| (15 << 8));
4509 buf
[4] = BYTE_0 (CSKYV1_INST_BSR
); /* bsr pc + 2. */
4510 buf
[5] = BYTE_1 (CSKYV1_INST_BSR
);
4511 buf
[6] = BYTE_0 (CSKYV1_INST_LRW
| (1 << 8)); /* lrw r1, (tar_addr - pc). */
4512 buf
[7] = BYTE_1 (CSKYV1_INST_LRW
| (1 << 8));
4513 buf
[8] = BYTE_0 (CSKYV1_INST_ADDU
| (15 << 4) | 1); /* add r1, r15. */
4514 buf
[9] = BYTE_1 (CSKYV1_INST_ADDU
| (15 << 4) | 1);
4515 buf
[10] = BYTE_0 (CSKYV1_INST_LDW
| (15 << 8)); /* ldw r15, r0. */
4516 buf
[11] = BYTE_1 (CSKYV1_INST_LDW
| (15 << 8));
4517 buf
[12] = BYTE_0 (CSKYV1_INST_ADDI
| (7 << 4)); /* addi r0, 8. */
4518 buf
[13] = BYTE_1 (CSKYV1_INST_ADDI
| (7 << 4));
4519 buf
[14] = BYTE_0 (CSKYV1_INST_JMP
| 1); /* jmp r1. */
4520 buf
[15] = BYTE_1 (CSKYV1_INST_JMP
| 1);
4524 if (!target_big_endian
)
4527 buf
[18] = disp
& 0xff;
4528 buf
[19] = (disp
>> 8) & 0xff;
4529 buf
[20] = (disp
>> 16) & 0xff;
4530 buf
[21] = (disp
>> 24) & 0xff;
4535 buf
[18] = (disp
>> 24) & 0xff;
4536 buf
[19] = (disp
>> 16) & 0xff;
4537 buf
[20] = (disp
>> 8) & 0xff;
4538 buf
[21] = disp
& 0xff;
4542 fragp
->fr_fix
+= U32_LEN_PIC
;
4546 if (!target_big_endian
)
4549 buf
[16] = disp
& 0xff;
4550 buf
[17] = (disp
>> 8) & 0xff;
4551 buf
[18] = (disp
>> 16) & 0xff;
4552 buf
[19] = (disp
>> 24) & 0xff;
4557 buf
[16] = (disp
>> 24) & 0xff;
4558 buf
[17] = (disp
>> 16) & 0xff;
4559 buf
[18] = (disp
>> 8) & 0xff;
4560 buf
[19] = disp
& 0xff;
4562 fragp
->fr_fix
+= U32_LEN_PIC
;
4572 unsigned int inst
= csky_read_insn (buf
, 2);
4573 inst
|= (disp
>> 1) & ((1 << 10) - 1);
4574 csky_write_insn (buf
, inst
, 2);
4580 unsigned int inst
= csky_read_insn (buf
, 2);
4582 if (inst
== CSKYV2_INST_BT16
)
4583 inst
= CSKYV2_INST_BF16
;
4585 inst
= CSKYV2_INST_BT16
;
4586 make_insn (2, inst
, (2 + 4) >> 1, 10);
4587 if (IS_EXTERNAL_SYM (fragp
->fr_symbol
, asec
))
4588 fix_new (fragp
, fragp
->fr_fix
, 4,
4589 fragp
->fr_symbol
, fragp
->fr_offset
, 1,
4590 BFD_RELOC_CKCORE_PCREL_IMM16BY2
);
4592 inst
= CSKYV2_INST_BR32
| ((disp
>> 1) & ((1 << 16) - 1));
4593 csky_write_insn (buf
, inst
, 4);
4600 unsigned int inst
= csky_read_insn (buf
, 2);
4602 if (inst
== CSKYV2_INST_BT16
)
4603 inst
= CSKYV2_INST_BT32
;
4605 inst
= CSKYV2_INST_BF32
;
4606 if (IS_EXTERNAL_SYM (fragp
->fr_symbol
, asec
))
4607 fix_new (fragp
, fragp
->fr_fix
, 4,
4608 fragp
->fr_symbol
, fragp
->fr_offset
, 1,
4609 BFD_RELOC_CKCORE_PCREL_IMM16BY2
);
4610 inst
|= (disp
>> 1) & ((1 << 16) - 1);
4611 csky_write_insn (buf
, inst
, 4);
4617 unsigned int inst
= csky_read_insn (buf
, 2);
4619 imm
= (disp
+ 2) >> 2;
4620 inst
|= (imm
>> 5) << 8;
4621 make_insn (2, inst
, (imm
& 0x1f), 5);
4626 unsigned int inst
= csky_read_insn (buf
, 2);
4627 int imm
= (disp
+ 2) >> 2;
4631 inst
|= (~((imm
>> 5) << 8)) & 0x300;
4632 make_insn (2, inst
, (~imm
& 0x1f), 5);
4636 inst
|= (imm
>> 5) << 8;
4637 make_insn (2, inst
, (imm
& 0x1f), 5);
4643 unsigned int inst
= csky_read_insn (buf
, 2);
4644 inst
= CSKYV2_INST_LRW32
| (((inst
& 0xe0) >> 5) << 16);
4645 if (IS_EXTERNAL_SYM (fragp
->fr_symbol
, asec
))
4646 fix_new (fragp
, fragp
->fr_fix
, 4,
4647 fragp
->fr_symbol
, fragp
->fr_offset
, 1,
4648 BFD_RELOC_CKCORE_PCREL_IMM16BY4
);
4649 make_insn (4, inst
, ((disp
+ 2) >> 2), 16);
4654 unsigned int inst
= csky_read_insn (buf
, 4);
4655 make_insn (4, inst
, disp
>> 1, 16);
4660 unsigned int inst
= csky_read_insn (buf
, 4);
4662 make_insn (4, opposite_of_stored_compz (inst
),
4663 (4 + 4 + PAD_LITERAL_LENGTH
) >> 1, 16);
4664 literal_offset
= ((fragp
->fr_address
+ fragp
->fr_fix
) % 4 == 0
4666 make_insn (4, CSKYV2_INST_JMPI32
, (4 + literal_offset
+ 2) >> 2, 10);
4667 make_literal (fragp
, literal_offset
);
4673 if (IS_EXTERNAL_SYM (fragp
->fr_symbol
, asec
))
4674 fix_new (fragp
, fragp
->fr_fix
, 4,
4675 fragp
->fr_symbol
, fragp
->fr_offset
, 1,
4676 BFD_RELOC_CKCORE_PCREL_IMM16BY2
);
4677 make_insn (4, CSKYV2_INST_BR32
, disp
>> 1, 16);
4682 /* 'jbt'/'jbf'-> <bf16/bt16>; jmpi32; [pad16]+literal32 */
4683 unsigned int inst
= csky_read_insn (buf
, 2);
4686 if (inst
== CSKYV2_INST_BT16
)
4687 inst
= CSKYV2_INST_BF16
;
4689 inst
= CSKYV2_INST_BT16
;
4690 make_insn (2, inst
, (2 + 4 + PAD_LITERAL_LENGTH
) >> 1, 10);
4691 literal_offset
= ((fragp
->fr_address
+ fragp
->fr_fix
) % 4 == 0
4693 make_insn (4, CSKYV2_INST_JMPI32
, (4 + literal_offset
+ 2) >> 2, 10);
4694 make_literal (fragp
, literal_offset
);
4700 literal_offset
= ((fragp
->fr_address
+ fragp
->fr_fix
) % 4 == 0
4702 make_insn (4, CSKYV2_INST_JMPI32
, (4 + literal_offset
+ 2) >> 2, 10);
4703 make_literal (fragp
, literal_offset
);
4706 case RELAX_OVERFLOW
:
4707 csky_branch_report_error (fragp
->fr_file
, fragp
->fr_line
,
4708 fragp
->fr_symbol
, disp
);
4716 /* Round up a section size to the appropriate boundary. */
4719 md_section_align (segT segment ATTRIBUTE_UNUSED
,
4725 /* MD interface: Symbol and relocation handling. */
4727 void md_csky_end (void)
4732 /* Return the address within the segment that a PC-relative fixup is
4736 md_pcrel_from_section (fixS
* fixP
, segT seg
)
4738 /* If the symbol is undefined or defined in another section
4739 we leave the add number alone for the linker to fix it later. */
4740 if (fixP
->fx_addsy
!= (symbolS
*) NULL
4741 && (! S_IS_DEFINED (fixP
->fx_addsy
)
4742 || S_GET_SEGMENT (fixP
->fx_addsy
) != seg
))
4743 return fixP
->fx_size
;
4745 /* The case where we are going to resolve things. */
4746 return fixP
->fx_size
+ fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
4749 /* csky_cons_fix_new is called via the expression parsing code when a
4750 reloc is needed. We use this hook to get the correct .got reloc. */
4753 csky_cons_fix_new (fragS
*frag
,
4757 bfd_reloc_code_real_type reloc
)
4761 if (BFD_RELOC_CKCORE_GOTOFF
== insn_reloc
4762 || BFD_RELOC_CKCORE_GOTPC
== insn_reloc
4763 || BFD_RELOC_CKCORE_GOT32
== insn_reloc
4764 || BFD_RELOC_CKCORE_PLT32
== insn_reloc
4765 || BFD_RELOC_CKCORE_TLS_LE32
== insn_reloc
4766 || BFD_RELOC_CKCORE_TLS_GD32
== insn_reloc
4767 || BFD_RELOC_CKCORE_TLS_LDM32
== insn_reloc
4768 || BFD_RELOC_CKCORE_TLS_LDO32
== insn_reloc
4769 || BFD_RELOC_CKCORE_TLS_IE32
== insn_reloc
)
4775 reloc
= BFD_RELOC_8
;
4778 reloc
= BFD_RELOC_16
;
4781 reloc
= BFD_RELOC_32
;
4784 reloc
= BFD_RELOC_64
;
4787 as_bad (_("unsupported BFD relocation size %d"), len
);
4788 reloc
= BFD_RELOC_32
;
4791 fixP
= fix_new_exp (frag
, off
, (int) len
, exp
, 0, reloc
);
4792 if (BFD_RELOC_CKCORE_TLS_IE32
== insn_reloc
4793 || BFD_RELOC_CKCORE_TLS_GD32
== insn_reloc
4794 || BFD_RELOC_CKCORE_TLS_LDM32
== insn_reloc
)
4796 fixP
->tc_fix_data
.frag
= literal_insn_offset
->tls_addend
.frag
;
4797 fixP
->tc_fix_data
.offset
= literal_insn_offset
->tls_addend
.offset
;
4801 /* See whether we need to force a relocation into the output file.
4802 This is used to force out switch and PC relative relocations when
4806 csky_force_relocation (fixS
* fix
)
4808 if (fix
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
4809 || fix
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
4810 || fix
->fx_r_type
== BFD_RELOC_RVA
4811 || fix
->fx_r_type
== BFD_RELOC_CKCORE_ADDR_HI16
4812 || fix
->fx_r_type
== BFD_RELOC_CKCORE_ADDR_LO16
4813 || fix
->fx_r_type
== BFD_RELOC_CKCORE_TOFFSET_LO16
4814 || fix
->fx_r_type
== BFD_RELOC_CKCORE_DOFFSET_LO16
)
4817 if (fix
->fx_addsy
== NULL
)
4820 if (do_use_branchstub
4821 && fix
->fx_r_type
== BFD_RELOC_CKCORE_PCREL_IMM26BY2
4822 && (symbol_get_bfdsym (fix
->fx_addsy
)->flags
& BSF_FUNCTION
))
4824 return S_FORCE_RELOC (fix
->fx_addsy
, fix
->fx_subsy
== NULL
);
4827 /* Return true if the fix can be handled by GAS, false if it must
4828 be passed through to the linker. */
4831 csky_fix_adjustable (fixS
* fixP
)
4833 if (fixP
->fx_addsy
== NULL
)
4836 /* We need the symbol name for the VTABLE entries. */
4837 if (fixP
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
4838 || fixP
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
4839 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_PLT32
4840 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_GOT32
4841 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_PLT12
4842 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_GOT12
4843 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_GOT_HI16
4844 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_GOT_LO16
4845 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_PLT_HI16
4846 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_PLT_LO16
4847 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_GOTOFF
4848 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_GOTOFF_HI16
4849 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_GOTOFF_LO16
4850 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_ADDR_HI16
4851 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_ADDR_LO16
4852 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_GOT_IMM18BY4
4853 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_PLT_IMM18BY4
4854 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_GOTOFF_IMM18
4855 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_TLS_LE32
4856 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_TLS_IE32
4857 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_TLS_GD32
4858 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_TLS_LDM32
4859 || fixP
->fx_r_type
== BFD_RELOC_CKCORE_TLS_LDO32
)
4862 if (do_use_branchstub
4863 && fixP
->fx_r_type
== BFD_RELOC_CKCORE_PCREL_IMM26BY2
4864 && (symbol_get_bfdsym (fixP
->fx_addsy
)->flags
& BSF_FUNCTION
))
4871 md_apply_fix (fixS
*fixP
,
4875 reloc_howto_type
*howto
;
4876 /* Note: use offsetT because it is signed, valueT is unsigned. */
4877 offsetT val
= *valP
;
4878 char *buf
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
4880 /* if fx_done = 0, fixup will also be processed in
4881 * tc_gen_reloc() after md_apply_fix(). */
4884 /* If the fix is relative to a symbol which is not defined, or not
4885 in the same segment as the fix, we cannot resolve it here. */
4886 if (IS_CSKY_V1 (mach_flag
) && fixP
->fx_addsy
!= NULL
4887 && (! S_IS_DEFINED (fixP
->fx_addsy
)
4888 || S_GET_SEGMENT (fixP
->fx_addsy
) != seg
))
4890 switch (fixP
->fx_r_type
)
4892 /* Data fx_addnumber is greater than 16 bits,
4893 so fx_addnumber is assigned zero. */
4894 case BFD_RELOC_CKCORE_PCREL_JSR_IMM11BY2
:
4897 case BFD_RELOC_CKCORE_TLS_IE32
:
4898 case BFD_RELOC_CKCORE_TLS_LDM32
:
4899 case BFD_RELOC_CKCORE_TLS_GD32
:
4901 struct tls_addend
*ta
= &(fixP
->tc_fix_data
);
4902 fixP
->fx_offset
= (fixP
->fx_frag
->fr_address
+ fixP
->fx_where
4903 - (ta
->frag
->fr_address
+ ta
->offset
));
4906 case BFD_RELOC_CKCORE_TLS_LE32
:
4907 case BFD_RELOC_CKCORE_TLS_LDO32
:
4908 S_SET_THREAD_LOCAL (fixP
->fx_addsy
);
4914 /* For ELF we can just return and let the reloc that will be generated
4915 take care of everything. For COFF we still have to insert 'val'
4916 into the insn since the addend field will be ignored. */
4921 /* We can handle these relocs. */
4922 switch (fixP
->fx_r_type
)
4924 case BFD_RELOC_32_PCREL
:
4925 case BFD_RELOC_CKCORE_PCREL32
:
4926 fixP
->fx_r_type
= BFD_RELOC_CKCORE_PCREL32
;
4928 case BFD_RELOC_VTABLE_INHERIT
:
4929 fixP
->fx_r_type
= BFD_RELOC_CKCORE_GNU_VTINHERIT
;
4930 if (fixP
->fx_addsy
&& !S_IS_DEFINED (fixP
->fx_addsy
)
4931 && !S_IS_WEAK (fixP
->fx_addsy
))
4932 S_SET_WEAK (fixP
->fx_addsy
);
4934 case BFD_RELOC_VTABLE_ENTRY
:
4935 fixP
->fx_r_type
= BFD_RELOC_CKCORE_GNU_VTENTRY
;
4937 case BFD_RELOC_CKCORE_GOT12
:
4938 case BFD_RELOC_CKCORE_PLT12
:
4939 case BFD_RELOC_CKCORE_ADDR_HI16
:
4940 case BFD_RELOC_CKCORE_ADDR_LO16
:
4941 case BFD_RELOC_CKCORE_TOFFSET_LO16
:
4942 case BFD_RELOC_CKCORE_DOFFSET_LO16
:
4943 case BFD_RELOC_CKCORE_GOT_HI16
:
4944 case BFD_RELOC_CKCORE_GOT_LO16
:
4945 case BFD_RELOC_CKCORE_PLT_HI16
:
4946 case BFD_RELOC_CKCORE_PLT_LO16
:
4947 case BFD_RELOC_CKCORE_GOTPC_HI16
:
4948 case BFD_RELOC_CKCORE_GOTPC_LO16
:
4949 case BFD_RELOC_CKCORE_GOTOFF_HI16
:
4950 case BFD_RELOC_CKCORE_GOTOFF_LO16
:
4951 case BFD_RELOC_CKCORE_DOFFSET_IMM18
:
4952 case BFD_RELOC_CKCORE_DOFFSET_IMM18BY2
:
4953 case BFD_RELOC_CKCORE_DOFFSET_IMM18BY4
:
4954 case BFD_RELOC_CKCORE_GOTOFF_IMM18
:
4955 case BFD_RELOC_CKCORE_GOT_IMM18BY4
:
4956 case BFD_RELOC_CKCORE_PLT_IMM18BY4
:
4958 case BFD_RELOC_CKCORE_TLS_IE32
:
4959 case BFD_RELOC_CKCORE_TLS_LDM32
:
4960 case BFD_RELOC_CKCORE_TLS_GD32
:
4962 struct tls_addend
*ta
= &(fixP
->tc_fix_data
);
4963 fixP
->fx_offset
= (fixP
->fx_frag
->fr_address
+ fixP
->fx_where
4964 - (ta
->frag
->fr_address
+ ta
->offset
));
4967 case BFD_RELOC_CKCORE_TLS_LE32
:
4968 case BFD_RELOC_CKCORE_TLS_LDO32
:
4969 S_SET_THREAD_LOCAL (fixP
->fx_addsy
);
4972 fixP
->fx_r_type
= BFD_RELOC_CKCORE_ADDR32
;
4976 if (fixP
->fx_addsy
== NULL
)
4978 if (fixP
->fx_size
== 4)
4980 else if (fixP
->fx_size
== 2 && val
>= -32768 && val
<= 32767)
4982 else if (fixP
->fx_size
== 1 && val
>= -256 && val
<= 255)
4986 md_number_to_chars (buf
, val
, fixP
->fx_size
);
4990 case BFD_RELOC_CKCORE_PCREL_JSR_IMM11BY2
:
4991 if (fixP
->fx_addsy
== 0 && val
> -2 KB
&& val
< 2 KB
)
4993 long nval
= (val
>> 1) & 0x7ff;
4994 nval
|= CSKYV1_INST_BSR
;
4995 csky_write_insn (buf
, nval
, 2);
5001 case BFD_RELOC_CKCORE_PCREL_JSR_IMM26BY2
:
5002 if (fixP
->fx_addsy
== 0)
5004 if (val
>= -(1 << 26) && val
< (1 << 26))
5006 unsigned int nval
= ((val
+ fixP
->fx_size
) >> 1) & 0x3ffffff;
5007 nval
|= CSKYV2_INST_BSR32
;
5009 csky_write_insn (buf
, nval
, 4);
5011 /* If bsr32 cannot reach,
5012 generate 'lrw r25,label;jsr r25' instead of 'jsri label'. */
5013 else if (IS_CSKY_ARCH_810 (mach_flag
))
5015 howto
= bfd_reloc_type_lookup (stdoutput
, fixP
->fx_r_type
);
5016 valueT opcode
= csky_read_insn (buf
, 4);
5017 opcode
= (opcode
& howto
->dst_mask
) | CSKYV2_INST_JSRI_TO_LRW
;
5018 csky_write_insn (buf
, opcode
, 4);
5019 opcode
= CSKYV2_INST_JSR_R26
;
5020 csky_write_insn (buf
+ 4, opcode
, 4);
5030 unsigned int issigned
= 0;
5035 howto
= bfd_reloc_type_lookup (stdoutput
, fixP
->fx_r_type
);
5038 if (fixP
->fx_size
== 4
5039 || (fixP
->fx_size
== 2 && val
>= -32768 && val
<= 32767)
5040 || (fixP
->fx_size
== 1 && val
>= -256 && val
<= 255))
5042 md_number_to_chars (buf
, val
, fixP
->fx_size
);
5050 if (IS_CSKY_V2 (mach_flag
))
5051 val
+= fixP
->fx_size
;
5053 if (howto
->rightshift
== 2)
5056 val
>>= howto
->rightshift
;
5058 switch (fixP
->fx_r_type
)
5060 /* Offset is unsigned. */
5061 case BFD_RELOC_CKCORE_PCREL_IMM8BY4
:
5062 case BFD_RELOC_CKCORE_PCREL_IMM10BY4
:
5063 case BFD_RELOC_CKCORE_PCREL_IMM16BY4
:
5064 max
= (offsetT
) howto
->dst_mask
;
5068 case BFD_RELOC_CKCORE_PCREL_IMM7BY4
:
5070 max
= (offsetT
)((1 << (howto
->bitsize
+ 1)) - 2);
5072 max
= (offsetT
)((1 << howto
->bitsize
) - 1);
5075 /* flrws, flrwd: the offset bits are divided in two parts. */
5076 case BFD_RELOC_CKCORE_PCREL_FLRW_IMM8BY4
:
5077 max
= (offsetT
)((1 << howto
->bitsize
) - 1);
5080 /* Offset is signed. */
5082 max
= (offsetT
)(howto
->dst_mask
>> 1);
5086 if (val
< min
|| val
> max
)
5088 csky_branch_report_error (fixP
->fx_file
, fixP
->fx_line
,
5089 fixP
->fx_addsy
, val
);
5092 opcode
= csky_read_insn (buf
, fixP
->fx_size
);
5093 /* Clear redundant bits brought from the last
5094 operation if there is any. */
5095 if (do_extend_lrw
&& (opcode
& 0xfc00) == CSKYV2_INST_LRW16
)
5098 val
&= issigned
? (offsetT
)(howto
->dst_mask
) : max
;
5100 if (fixP
->fx_r_type
== BFD_RELOC_CKCORE_PCREL_BLOOP_IMM4BY4
)
5101 val
= (val
& 0xf) << 12;
5103 if (fixP
->fx_size
== 2 && (opcode
& 0xfc00) == CSKYV2_INST_LRW16
)
5105 /* 8 bit offset lrw16. */
5107 csky_write_insn (buf
,
5109 | ((~val
& 0x60) << 3) | (opcode
& 0xe0)),
5111 /* 7 bit offset lrw16. */
5113 csky_write_insn (buf
,
5114 (val
& 0x1f) | ((val
& 0x60) << 3) | opcode
,
5117 else if (fixP
->fx_size
== 4
5118 && (opcode
& 0xfe1ffe00) == CSKYV2_INST_FLRW
)
5119 csky_write_insn (buf
,
5120 ((val
& 0xf) << 4) | ((val
& 0xf0) << 17) | opcode
,
5123 csky_write_insn (buf
, val
| opcode
, fixP
->fx_size
);
5128 fixP
->fx_addnumber
= val
;
5131 /* Translate internal representation of relocation info to BFD target
5135 tc_gen_reloc (asection
*section ATTRIBUTE_UNUSED
, fixS
*fixP
)
5140 && fixP
->fx_r_type
== BFD_RELOC_CKCORE_ADDR32
)
5141 fixP
->fx_r_type
= BFD_RELOC_CKCORE_PCREL32
;
5143 rel
= xmalloc (sizeof (arelent
));
5144 rel
->sym_ptr_ptr
= xmalloc (sizeof (asymbol
*));
5145 *rel
->sym_ptr_ptr
= symbol_get_bfdsym (fixP
->fx_addsy
);
5146 rel
->howto
= bfd_reloc_type_lookup (stdoutput
, fixP
->fx_r_type
);
5147 rel
->addend
= fixP
->fx_offset
;
5148 if (rel
->howto
== NULL
)
5150 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5151 _("cannot represent `%s' relocation in object file"),
5152 bfd_get_reloc_code_name (fixP
->fx_r_type
));
5154 /* Set howto to a garbage value so that we can keep going. */
5155 rel
->howto
= bfd_reloc_type_lookup (stdoutput
, BFD_RELOC_32
);
5157 gas_assert (rel
->howto
!= NULL
);
5158 rel
->address
= fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
5162 /* Relax a fragment by scanning TC_GENERIC_RELAX_TABLE. */
5165 csky_relax_frag (segT segment
, fragS
*fragP
, long stretch
)
5167 const relax_typeS
*this_type
;
5168 const relax_typeS
*start_type
;
5169 relax_substateT next_state
;
5170 relax_substateT this_state
;
5176 const relax_typeS
*table
;
5178 target
= fragP
->fr_offset
;
5179 address
= fragP
->fr_address
;
5180 table
= TC_GENERIC_RELAX_TABLE
;
5181 this_state
= fragP
->fr_subtype
;
5182 start_type
= this_type
= table
+ this_state
;
5183 symbolP
= fragP
->fr_symbol
;
5189 sym_frag
= symbol_get_frag (symbolP
);
5191 #ifndef DIFF_EXPR_OK
5192 know (sym_frag
!= NULL
);
5194 know (S_GET_SEGMENT (symbolP
) != absolute_section
5195 || sym_frag
== &zero_address_frag
);
5196 target
+= S_GET_VALUE (symbolP
);
5198 /* If SYM_FRAG has yet to be reached on this pass, assume it
5199 will move by STRETCH just as we did, unless there is an
5200 alignment frag between here and SYM_FRAG. An alignment may
5201 well absorb any STRETCH, and we don't want to choose a larger
5202 branch insn by overestimating the needed reach of this
5203 branch. It isn't critical to calculate TARGET exactly; We
5204 know we'll be doing another pass if STRETCH is non-zero. */
5207 && sym_frag
->relax_marker
!= fragP
->relax_marker
5208 && S_GET_SEGMENT (symbolP
) == segment
)
5212 /* Adjust stretch for any alignment frag. Note that if have
5213 been expanding the earlier code, the symbol may be
5214 defined in what appears to be an earlier frag. FIXME:
5215 This doesn't handle the fr_subtype field, which specifies
5216 a maximum number of bytes to skip when doing an
5218 for (f
= fragP
; f
!= NULL
&& f
!= sym_frag
; f
= f
->fr_next
)
5220 if (f
->fr_type
== rs_align
|| f
->fr_type
== rs_align_code
)
5223 stretch
= -((-stretch
)
5224 & ~((1 << (int) f
->fr_offset
) - 1));
5226 stretch
&= ~((1 << (int) f
->fr_offset
) - 1);
5236 aim
= target
- address
- fragP
->fr_fix
;
5238 /* If the fragP->fr_symbol is extern symbol, aim should be 0. */
5239 if (fragP
->fr_symbol
&& S_GET_SEGMENT (symbolP
) != segment
)
5244 /* Look backwards. */
5245 for (next_state
= this_type
->rlx_more
; next_state
;)
5246 if (aim
>= this_type
->rlx_backward
)
5250 /* Grow to next state. */
5251 this_state
= next_state
;
5252 this_type
= table
+ this_state
;
5253 next_state
= this_type
->rlx_more
;
5258 /* Look forwards. */
5259 for (next_state
= this_type
->rlx_more
; next_state
;)
5260 if (aim
<= this_type
->rlx_forward
)
5264 /* Grow to next state. */
5265 this_state
= next_state
;
5266 this_type
= table
+ this_state
;
5267 next_state
= this_type
->rlx_more
;
5271 growth
= this_type
->rlx_length
- start_type
->rlx_length
;
5273 fragP
->fr_subtype
= this_state
;
5278 md_estimate_size_before_relax (fragS
* fragp
,
5281 switch (fragp
->fr_subtype
)
5301 gas_assert (fragp
->fr_symbol
);
5302 if (IS_EXTERNAL_SYM (fragp
->fr_symbol
, segtype
))
5303 while (csky_relax_table
[fragp
->fr_subtype
].rlx_more
> RELAX_OVERFLOW
)
5304 fragp
->fr_subtype
= csky_relax_table
[fragp
->fr_subtype
].rlx_more
;
5305 return csky_relax_table
[fragp
->fr_subtype
].rlx_length
;
5307 /* C-SKY V1 relaxes. */
5308 case C (UNCD_JUMP
, UNDEF_DISP
):
5309 case C (UNCD_JUMP_PIC
, UNDEF_DISP
):
5310 if (!fragp
->fr_symbol
)
5311 fragp
->fr_subtype
= C (UNCD_JUMP_S
, DISP12
);
5312 else if (S_GET_SEGMENT (fragp
->fr_symbol
) == segtype
)
5313 fragp
->fr_subtype
= C (UNCD_JUMP_S
, DISP12
);
5315 fragp
->fr_subtype
= C (UNCD_JUMP_S
, UNDEF_WORD_DISP
);
5318 case C (COND_JUMP
, UNDEF_DISP
):
5319 case C (COND_JUMP_PIC
, UNDEF_DISP
):
5320 if (fragp
->fr_symbol
5321 && S_GET_SEGMENT (fragp
->fr_symbol
) == segtype
)
5322 /* Got a symbol and it's defined in this segment, become byte
5323 sized. Maybe it will fix up. */
5324 fragp
->fr_subtype
= C (COND_JUMP_S
, DISP12
);
5325 else if (fragp
->fr_symbol
)
5326 /* It's got a segment, but it's not ours, so it will always be
5328 fragp
->fr_subtype
= C (COND_JUMP_S
, UNDEF_WORD_DISP
);
5330 /* We know the abs value. */
5331 fragp
->fr_subtype
= C (COND_JUMP_S
, DISP12
);
5334 case C (UNCD_JUMP
, DISP12
):
5335 case C (UNCD_JUMP
, DISP32
):
5336 case C (UNCD_JUMP
, UNDEF_WORD_DISP
):
5337 case C (COND_JUMP
, DISP12
):
5338 case C (COND_JUMP
, DISP32
):
5339 case C (COND_JUMP
, UNDEF_WORD_DISP
):
5340 case C (UNCD_JUMP_PIC
, DISP12
):
5341 case C (UNCD_JUMP_PIC
, DISP32
):
5342 case C (UNCD_JUMP_PIC
, UNDEF_WORD_DISP
):
5343 case C (COND_JUMP_PIC
, DISP12
):
5344 case C (COND_JUMP_PIC
, DISP32
):
5345 case C (COND_JUMP_PIC
, UNDEF_WORD_DISP
):
5346 case RELAX_OVERFLOW
:
5352 return csky_relax_table
[fragp
->fr_subtype
].rlx_length
;
5355 /* Parse opcode like: "op oprnd1, oprnd2, oprnd3". */
5358 csky_macro_md_assemble (const char *op
,
5369 strcat (str
, oprnd1
);
5373 strcat (str
, oprnd2
);
5377 strcat (str
, oprnd3
);
5385 /* Get the string of operand. */
5388 csky_get_macro_operand (char *src_s
, char *dst_s
, char end_sym
)
5391 while (ISSPACE (*src_s
))
5393 while (*src_s
!= end_sym
)
5394 dst_s
[nlen
++] = *(src_s
++);
5399 /* idly 4 -> idly4. */
5404 char *s
= csky_insn
.opcode_end
;
5405 if (!is_imm_over_range (&s
, 4, 4, -1))
5407 as_bad (_("second operand must be 4"));
5410 csky_macro_md_assemble ("idly4", NULL
, NULL
, NULL
);
5414 /* rolc rd, 1 or roltc rd, 1 -> addc rd, rd. */
5420 char *s
= csky_insn
.opcode_end
;
5422 s
+= csky_get_macro_operand (s
, reg
, ',');
5425 if (is_imm_over_range (&s
, 1, 1, -1))
5427 csky_macro_md_assemble ("addc", reg
, reg
, NULL
);
5431 as_bad (_("second operand must be 1"));
5434 /* sxtrb0(1)(2) r1, rx -> xtbr0(1)(2) r1,rx; sextb r1. */
5442 char *s
= csky_insn
.opcode_end
;
5443 s
+= csky_get_macro_operand (s
, reg1
, ',');
5445 csky_get_macro_operand (s
, reg2
, '\0');
5447 csky_macro_md_assemble (csky_insn
.macro
->name
+ 1, reg1
, reg2
, NULL
);
5448 csky_macro_md_assemble ("sextb", reg1
, NULL
, NULL
);
5459 char *s
= csky_insn
.opcode_end
;
5460 s
+= csky_get_macro_operand (s
, reg1
, ',');
5463 s
+= csky_get_macro_operand (s
, reg2
, ',');
5466 s
+= csky_get_macro_operand (s
, reg3
, '\0');
5468 csky_macro_md_assemble ("movt", reg1
, reg2
, NULL
);
5469 csky_macro_md_assemble ("movf", reg1
, reg3
, NULL
);
5474 get_macro_reg_vals (int *reg1
, int *reg2
, int *reg3
)
5477 char *s
= csky_insn
.opcode_end
;
5479 *reg1
= csky_get_reg_val (s
, &nlen
);
5483 csky_show_error (ERROR_MISSING_COMMA
, 0, NULL
, NULL
);
5487 *reg2
= csky_get_reg_val (s
, &nlen
);
5491 csky_show_error (ERROR_MISSING_COMMA
, 0, NULL
, NULL
);
5495 *reg3
= csky_get_reg_val (s
, &nlen
);
5499 csky_show_error (ERROR_BAD_END
, 0, s
, NULL
);
5502 if (*reg1
== -1 || *reg2
== -1 || *reg3
== -1)
5504 as_bad (_("register number out of range"));
5509 as_bad (_("dest and source1 must be the same register"));
5512 if (*reg1
>= 15 || *reg3
>= 15)
5514 as_bad (_("64-bit operator src/dst register must be less than 15"));
5520 /* addc64 rx, rx, ry -> cmplt rx, rx, addc rx, ry, addc rx+1, ry+1. */
5529 if (!get_macro_reg_vals (®1
, ®2
, ®3
))
5531 csky_macro_md_assemble ("cmplt",
5532 csky_general_reg
[reg1
],
5533 csky_general_reg
[reg1
],
5535 csky_macro_md_assemble ("addc",
5536 csky_general_reg
[reg1
+ (target_big_endian
? 1 : 0)],
5537 csky_general_reg
[reg3
+ (target_big_endian
? 1 : 0)],
5539 csky_macro_md_assemble ("addc",
5540 csky_general_reg
[reg1
+ (target_big_endian
? 0 : 1)],
5541 csky_general_reg
[reg3
+ (target_big_endian
? 0 : 1)],
5546 /* subc64 rx, rx, ry -> cmphs rx, rx, subc rx, ry, subc rx+1, ry+1. */
5555 if (!get_macro_reg_vals (®1
, ®2
, ®3
))
5557 csky_macro_md_assemble ("cmphs",
5558 csky_general_reg
[reg1
],
5559 csky_general_reg
[reg1
],
5561 csky_macro_md_assemble ("subc",
5562 csky_general_reg
[reg1
+ (target_big_endian
? 1 : 0)],
5563 csky_general_reg
[reg3
+ (target_big_endian
? 1 : 0)],
5565 csky_macro_md_assemble ("subc",
5566 csky_general_reg
[reg1
+ (target_big_endian
? 0 : 1)],
5567 csky_general_reg
[reg3
+ (target_big_endian
? 0 : 1)],
5572 /* or64 rx, rx, ry -> or rx, ry, or rx+1, ry+1. */
5581 if (!get_macro_reg_vals (®1
, ®2
, ®3
))
5583 csky_macro_md_assemble ("or",
5584 csky_general_reg
[reg1
+ (target_big_endian
? 1 : 0)],
5585 csky_general_reg
[reg3
+ (target_big_endian
? 1 : 0)],
5587 csky_macro_md_assemble ("or",
5588 csky_general_reg
[reg1
+ (target_big_endian
? 0 : 1)],
5589 csky_general_reg
[reg3
+ (target_big_endian
? 0 : 1)],
5594 /* xor64 rx, rx, ry -> xor rx, ry, xor rx+1, ry+1. */
5603 if (!get_macro_reg_vals (®1
, ®2
, ®3
))
5605 csky_macro_md_assemble ("xor",
5606 csky_general_reg
[reg1
+ (target_big_endian
? 1 : 0)],
5607 csky_general_reg
[reg3
+ (target_big_endian
? 1 : 0)],
5609 csky_macro_md_assemble ("xor",
5610 csky_general_reg
[reg1
+ (target_big_endian
? 0 : 1)],
5611 csky_general_reg
[reg3
+ (target_big_endian
? 0 : 1)],
5616 /* The following are V2 macro instructions. */
5618 /* neg rd -> not rd, rd; addi rd, 1. */
5625 char *s
= csky_insn
.opcode_end
;
5626 s
+= csky_get_macro_operand (s
, reg1
, '\0');
5629 csky_macro_md_assemble ("not", reg1
, reg1
, NULL
);
5630 csky_macro_md_assemble ("addi", reg1
, "1", NULL
);
5634 /* rsubi rd, imm16 -> not rd; addi rd, imm16 + 1 */
5641 unsigned int imm16
= 0;
5643 char *s
= csky_insn
.opcode_end
;
5644 s
+= csky_get_macro_operand (s
, reg1
, ',');
5647 s
= parse_exp (s
, &e
);
5648 if (e
.X_op
== O_constant
)
5649 imm16
= e
.X_add_number
;
5651 csky_show_error (ERROR_IMM_ILLEGAL
, 2, NULL
, NULL
);
5653 sprintf (str_imm16
, "%d", imm16
+ 1);
5655 csky_macro_md_assemble ("not", reg1
, reg1
, NULL
);
5656 csky_macro_md_assemble ("addi", reg1
, str_imm16
, NULL
);
5660 /* Such as: asrc rd -> asrc rd, rd, 1. */
5666 char *s
= csky_insn
.opcode_end
;
5667 s
+= csky_get_macro_operand (s
, reg1
, '\0');
5669 csky_macro_md_assemble (csky_insn
.macro
->name
, reg1
, reg1
, "1");
5673 /* decne rd -> if ck802: subi rd, 1; cmpnei rd, 0.
5674 else: decne rd, rd, 1 */
5680 char *s
= csky_insn
.opcode_end
;
5681 s
+= csky_get_macro_operand (s
, reg1
, '\0');
5683 if (IS_CSKY_ARCH_802 (mach_flag
))
5685 csky_macro_md_assemble ("subi", reg1
, "1", NULL
);
5686 csky_macro_md_assemble ("cmpnei", reg1
, "0", NULL
);
5689 csky_macro_md_assemble ("decne", reg1
, reg1
, "1");
5693 /* If -mnolrw, lrw rd, imm -> movih rd, imm_hi16; ori rd, imm_lo16. */
5703 char *s
= csky_insn
.opcode_end
;
5704 s
+= csky_get_macro_operand (s
, reg1
, ',');
5706 s
+= csky_get_macro_operand (s
, imm
, '\0');
5710 strcat (imm_hi16
, "(");
5711 strcat (imm_hi16
, imm
);
5712 strcat (imm_hi16
, ") >> 16");
5714 strcat (imm_lo16
, "(");
5715 strcat (imm_lo16
, imm
);
5716 strcat (imm_lo16
, ") & 0xffff");
5718 csky_macro_md_assemble ("movih", reg1
, imm_hi16
, NULL
);
5719 csky_macro_md_assemble ("ori", reg1
, reg1
, imm_lo16
);
5724 /* The following are worker functions for C-SKY v1. */
5730 int output_literal
= csky_insn
.val
[1];
5732 reg
= csky_insn
.val
[0];
5733 csky_insn
.isize
= 2;
5734 csky_insn
.output
= frag_more (2);
5735 if (csky_insn
.e1
.X_op
== O_constant
5736 && csky_insn
.e1
.X_add_number
<= 0x7f
5737 && csky_insn
.e1
.X_add_number
>= 0)
5739 csky_insn
.inst
= 0x6000 | reg
| (csky_insn
.e1
.X_add_number
<< 4);
5742 csky_insn
.inst
= csky_insn
.opcode
->op16
[0].opcode
;
5743 csky_insn
.inst
|= reg
<< 8;
5746 int n
= enter_literal (&csky_insn
.e1
, 0, 0, 0);
5748 /* Create a reference to pool entry. */
5749 csky_insn
.e1
.X_op
= O_symbol
;
5750 csky_insn
.e1
.X_add_symbol
= poolsym
;
5751 csky_insn
.e1
.X_add_number
= n
<< 2;
5754 if (insn_reloc
== BFD_RELOC_CKCORE_TLS_GD32
5755 || insn_reloc
== BFD_RELOC_CKCORE_TLS_LDM32
5756 || insn_reloc
== BFD_RELOC_CKCORE_TLS_IE32
)
5758 literal_insn_offset
->tls_addend
.frag
= frag_now
;
5759 literal_insn_offset
->tls_addend
.offset
5761 - literal_insn_offset
->tls_addend
.frag
->fr_literal
);
5763 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
, 2,
5764 &csky_insn
.e1
, 1, BFD_RELOC_CKCORE_PCREL_IMM8BY4
);
5766 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
5772 v1_work_fpu_fo (void)
5778 struct csky_opcode_info
*opinfo
= NULL
;
5780 if (csky_insn
.isize
== 4)
5781 opinfo
= &csky_insn
.opcode
->op32
[csky_insn
.opcode_idx
];
5782 else if (csky_insn
.isize
== 2)
5783 opinfo
= &csky_insn
.opcode
->op16
[csky_insn
.opcode_idx
];
5785 /* Firstly, get general reg. */
5786 for (i
= 0;i
< opinfo
->operand_num
; i
++)
5787 if (opinfo
->oprnd
.oprnds
[i
].type
== OPRND_TYPE_GREG0_15
)
5788 greg
= csky_insn
.val
[i
];
5789 gas_assert (greg
!= -1);
5791 /* Secondly, get float inst. */
5792 csky_generate_insn ();
5793 inst
= csky_insn
.inst
;
5795 /* Now get greg and inst, we can write instruction to floating unit. */
5796 sprintf (buff
, "lrw %s,0x%x", csky_general_reg
[greg
], inst
);
5798 sprintf (buff
, "cpwir %s", csky_general_reg
[greg
]);
5805 v1_work_fpu_fo_fc (void)
5811 struct csky_opcode_info
*opinfo
= NULL
;
5813 if (csky_insn
.isize
== 4)
5814 opinfo
= &csky_insn
.opcode
->op32
[csky_insn
.opcode_idx
];
5815 else if (csky_insn
.isize
== 2)
5816 opinfo
= &csky_insn
.opcode
->op16
[csky_insn
.opcode_idx
];
5818 /* Firstly, get general reg. */
5819 for (i
= 0;i
< opinfo
->operand_num
; i
++)
5820 if (opinfo
->oprnd
.oprnds
[i
].type
== OPRND_TYPE_GREG0_15
)
5821 greg
= csky_insn
.val
[i
];
5822 gas_assert (greg
!= -1);
5824 /* Secondly, get float inst. */
5825 csky_generate_insn ();
5826 inst
= csky_insn
.inst
;
5828 /* Now get greg and inst, we can write instruction to floating unit. */
5829 sprintf (buff
, "lrw %s,0x%x", csky_general_reg
[greg
], inst
);
5831 sprintf (buff
, "cpwir %s", csky_general_reg
[greg
]);
5833 sprintf (buff
, "cprc");
5840 v1_work_fpu_write (void)
5846 greg
= csky_insn
.val
[0];
5847 freg
= csky_insn
.val
[1];
5849 /* Now get greg and freg, we can write instruction to floating unit. */
5850 sprintf (buff
, "cpwgr %s,%s", csky_general_reg
[greg
], csky_cp_reg
[freg
]);
5857 v1_work_fpu_read (void)
5863 greg
= csky_insn
.val
[0];
5864 freg
= csky_insn
.val
[1];
5865 /* Now get greg and freg, we can write instruction to floating unit. */
5866 sprintf (buff
, "cprgr %s,%s", csky_general_reg
[greg
], csky_cp_reg
[freg
]);
5873 v1_work_fpu_writed (void)
5879 greg
= csky_insn
.val
[0];
5880 freg
= csky_insn
.val
[1];
5884 as_bad (_("even register number required"));
5887 /* Now get greg and freg, we can write instruction to floating unit. */
5888 if (target_big_endian
)
5889 sprintf (buff
, "cpwgr %s,%s",
5890 csky_general_reg
[greg
+ 1], csky_cp_reg
[freg
]);
5892 sprintf (buff
, "cpwgr %s,%s",
5893 csky_general_reg
[greg
], csky_cp_reg
[freg
]);
5895 if (target_big_endian
)
5896 sprintf (buff
, "cpwgr %s,%s",
5897 csky_general_reg
[greg
], csky_cp_reg
[freg
+ 1]);
5899 sprintf (buff
, "cpwgr %s,%s",
5900 csky_general_reg
[greg
+ 1], csky_cp_reg
[freg
+ 1]);
5907 v1_work_fpu_readd (void)
5913 greg
= csky_insn
.val
[0];
5914 freg
= csky_insn
.val
[1];
5918 as_bad (_("even register number required"));
5921 /* Now get greg and freg, we can write instruction to floating unit. */
5922 if (target_big_endian
)
5923 sprintf (buff
, "cprgr %s,%s",
5924 csky_general_reg
[greg
+ 1], csky_cp_reg
[freg
]);
5926 sprintf (buff
, "cprgr %s,%s",
5927 csky_general_reg
[greg
], csky_cp_reg
[freg
]);
5929 if (target_big_endian
)
5930 sprintf (buff
, "cprgr %s,%s",
5931 csky_general_reg
[greg
], csky_cp_reg
[freg
+ 1]);
5933 sprintf (buff
, "cprgr %s,%s",
5934 csky_general_reg
[greg
+ 1], csky_cp_reg
[freg
+ 1]);
5940 /* The following are for csky pseudo handling. */
5945 csky_insn
.output
= frag_more (2);
5947 /* Generate fixup BFD_RELOC_CKCORE_PCREL_IMM11BY2. */
5948 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
5949 2, & csky_insn
.e1
, 1, BFD_RELOC_CKCORE_PCREL_IMM11BY2
);
5952 /* Using jsri instruction. */
5953 const char *name
= "jsri";
5954 csky_insn
.opcode
= (struct csky_opcode
*)
5955 hash_find (csky_opcodes_hash
, name
);
5956 csky_insn
.opcode_idx
= 0;
5957 csky_insn
.isize
= 2;
5959 int n
= enter_literal (&csky_insn
.e1
, 1, 0, 0);
5961 /* Create a reference to pool entry. */
5962 csky_insn
.e1
.X_op
= O_symbol
;
5963 csky_insn
.e1
.X_add_symbol
= poolsym
;
5964 csky_insn
.e1
.X_add_number
= n
<< 2;
5966 /* Generate fixup BFD_RELOC_CKCORE_PCREL_IMM8BY4. */
5967 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
5968 2, & csky_insn
.e1
, 1, BFD_RELOC_CKCORE_PCREL_IMM8BY4
);
5970 if (csky_insn
.e1
.X_op
!= O_absent
&& do_jsri2bsr
)
5971 /* Generate fixup BFD_RELOC_CKCORE_PCREL_JSR_IMM11BY2. */
5972 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
5973 2, & (litpool
+ (csky_insn
.e1
.X_add_number
>> 2))->e
,
5974 1, BFD_RELOC_CKCORE_PCREL_JSR_IMM11BY2
);
5976 csky_generate_insn ();
5978 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
5983 /* The following are worker functions for csky v2 instruction handling. */
5985 /* For nie/nir/ipush/ipop. */
5988 v2_work_istack (void)
5992 csky_show_error (ERROR_OPCODE_ILLEGAL
, 0, NULL
, NULL
);
5995 csky_insn
.output
= frag_more (csky_insn
.isize
);
5996 csky_insn
.inst
= csky_insn
.opcode
->op16
[0].opcode
;
5997 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6002 v2_work_btsti (void)
6005 && (csky_insn
.flag_force
== INSN_OPCODE16F
6006 || IS_CSKY_ARCH_801 (mach_flag
)))
6008 csky_show_error (ERROR_OPCODE_ILLEGAL
, 0, NULL
, NULL
);
6011 if (!do_extend_lrw
&& csky_insn
.isize
== 2)
6012 csky_insn
.isize
= 4;
6013 /* Generate relax or reloc if necessary. */
6014 csky_generate_frags ();
6015 /* Generate the insn by mask. */
6016 csky_generate_insn ();
6017 /* Write inst to frag. */
6018 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6025 csky_insn
.isize
= 2;
6026 if (csky_insn
.number
== 2)
6028 if (csky_insn
.val
[0] == 14
6029 && csky_insn
.val
[1] >= 0 && csky_insn
.val
[1] <= 0x1fc
6030 && (csky_insn
.val
[1] & 0x3) == 0
6031 && csky_insn
.flag_force
!= INSN_OPCODE32F
)
6033 /* addi sp, sp, imm. */
6034 csky_insn
.inst
= 0x1400 | ((csky_insn
.val
[1] >> 2) & 0x1f);
6035 csky_insn
.inst
|= (csky_insn
.val
[1] << 1) & 0x300;
6036 csky_insn
.output
= frag_more (2);
6038 else if (csky_insn
.val
[0] < 8
6039 && csky_insn
.val
[1] >= 1 && csky_insn
.val
[1] <= 0x100
6040 && csky_insn
.flag_force
!= INSN_OPCODE32F
)
6042 csky_insn
.inst
= 0x2000 | (csky_insn
.val
[0] << 8);
6043 csky_insn
.inst
|= (csky_insn
.val
[1] - 1);
6044 csky_insn
.output
= frag_more (2);
6046 else if (csky_insn
.val
[1] >= 1 && csky_insn
.val
[1] <= 0x10000
6047 && csky_insn
.flag_force
!= INSN_OPCODE16F
6048 && !IS_CSKY_ARCH_801 (mach_flag
))
6050 csky_insn
.inst
= 0xe4000000 | (csky_insn
.val
[0] << 21);
6051 csky_insn
.inst
|= csky_insn
.val
[0] << 16;
6052 csky_insn
.inst
|= (csky_insn
.val
[1] - 1);
6053 csky_insn
.isize
= 4;
6054 csky_insn
.output
= frag_more (4);
6058 csky_show_error (ERROR_OPERANDS_ILLEGAL
, 0,
6059 csky_insn
.opcode_end
, NULL
);
6063 else if (csky_insn
.number
== 3)
6065 if (csky_insn
.val
[0] == 14
6066 && csky_insn
.val
[1] == 14
6067 && csky_insn
.val
[2] >= 0 && csky_insn
.val
[2] <= 0x1fc
6068 && (csky_insn
.val
[2] & 0x3) == 0
6069 && csky_insn
.flag_force
!= INSN_OPCODE32F
)
6071 csky_insn
.inst
= 0x1400 | ((csky_insn
.val
[2] >> 2) & 0x1f);
6072 csky_insn
.inst
|= (csky_insn
.val
[2] << 1) & 0x300;
6073 csky_insn
.output
= frag_more (2);
6075 else if (csky_insn
.val
[0] < 8
6076 && csky_insn
.val
[1] == 14
6077 && csky_insn
.val
[2] >= 0 && csky_insn
.val
[2] <= 0x3fc
6078 && (csky_insn
.val
[2] & 0x3) == 0
6079 && csky_insn
.flag_force
!= INSN_OPCODE32F
)
6081 csky_insn
.inst
= 0x1800 | (csky_insn
.val
[0] << 8);
6082 csky_insn
.inst
|= csky_insn
.val
[2] >> 2;
6083 csky_insn
.output
= frag_more (2);
6085 else if (csky_insn
.val
[0] < 8
6086 && csky_insn
.val
[0] == csky_insn
.val
[1]
6087 && csky_insn
.val
[2] >= 1 && csky_insn
.val
[2] <= 0x100
6088 && csky_insn
.flag_force
!= INSN_OPCODE32F
)
6090 csky_insn
.inst
= 0x2000 | (csky_insn
.val
[0] << 8);
6091 csky_insn
.inst
|= (csky_insn
.val
[2] - 1);
6092 csky_insn
.output
= frag_more (2);
6094 else if (csky_insn
.val
[0] < 8
6095 && csky_insn
.val
[1] < 8
6096 && csky_insn
.val
[2] >= 1 && csky_insn
.val
[2] <= 0x8
6097 && csky_insn
.flag_force
!= INSN_OPCODE32F
)
6099 csky_insn
.inst
= 0x5802 | (csky_insn
.val
[0] << 5);
6100 csky_insn
.inst
|= csky_insn
.val
[1] << 8;
6101 csky_insn
.inst
|= (csky_insn
.val
[2] - 1) << 2;
6102 csky_insn
.output
= frag_more (2);
6104 else if (csky_insn
.val
[1] == 28
6105 && csky_insn
.val
[2] >= 1 && csky_insn
.val
[2] <= 0x40000
6106 && csky_insn
.flag_force
!= INSN_OPCODE16F
6107 && !IS_CSKY_ARCH_801 (mach_flag
))
6109 csky_insn
.inst
= 0xcc1c0000 | (csky_insn
.val
[0] << 21);
6110 csky_insn
.isize
= 4;
6111 csky_insn
.output
= frag_more (4);
6112 if (insn_reloc
== BFD_RELOC_CKCORE_GOTOFF
)
6114 fix_new_exp (frag_now
, csky_insn
.output
-frag_now
->fr_literal
,
6115 4, &csky_insn
.e1
, 0, BFD_RELOC_CKCORE_GOTOFF_IMM18
);
6118 csky_insn
.inst
|= (csky_insn
.val
[2] - 1);
6120 else if (csky_insn
.val
[2] >= 1 && csky_insn
.val
[2] <= 0x1000
6121 && csky_insn
.flag_force
!= INSN_OPCODE16F
6122 && !IS_CSKY_ARCH_801 (mach_flag
))
6124 csky_insn
.inst
= 0xe4000000 | (csky_insn
.val
[0] << 21);
6125 csky_insn
.inst
|= csky_insn
.val
[1] << 16;
6126 csky_insn
.inst
|= (csky_insn
.val
[2] - 1);
6127 csky_insn
.isize
= 4;
6128 csky_insn
.output
= frag_more (4);
6132 csky_show_error (ERROR_OPERANDS_ILLEGAL
, 0,
6133 (char *)csky_insn
.opcode_end
, NULL
);
6137 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6145 csky_insn
.isize
= 2;
6146 if (csky_insn
.number
== 2)
6148 if (csky_insn
.val
[0] == 14
6149 && csky_insn
.val
[1] >= 0 && csky_insn
.val
[2] <= 0x1fc
6150 && (csky_insn
.val
[1] & 0x3) == 0
6151 && csky_insn
.flag_force
!= INSN_OPCODE32F
)
6153 csky_insn
.inst
= 0x1420 | ((csky_insn
.val
[1] >> 2) & 0x1f);
6154 csky_insn
.inst
|= (csky_insn
.val
[1] << 1) & 0x300;
6156 else if (csky_insn
.val
[0] < 8
6157 && csky_insn
.val
[1] >= 1 && csky_insn
.val
[1] <= 0x100
6158 && csky_insn
.flag_force
!= INSN_OPCODE32F
)
6160 csky_insn
.inst
= 0x2800 | (csky_insn
.val
[0] << 8);
6161 csky_insn
.inst
|= (csky_insn
.val
[1] - 1);
6163 else if (csky_insn
.val
[1] >= 1 && csky_insn
.val
[1] <= 0x10000
6164 && csky_insn
.flag_force
!= INSN_OPCODE16F
6165 && !IS_CSKY_ARCH_801 (mach_flag
))
6167 csky_insn
.inst
= 0xe4001000 | (csky_insn
.val
[0] << 21);
6168 csky_insn
.inst
|= csky_insn
.val
[0] << 16;
6169 csky_insn
.inst
|= (csky_insn
.val
[1] - 1);
6170 csky_insn
.isize
= 4;
6174 csky_show_error (ERROR_OPERANDS_ILLEGAL
, 0,
6175 (char *)csky_insn
.opcode_end
, NULL
);
6179 else if (csky_insn
.number
== 3)
6181 if (csky_insn
.val
[0] == 14
6182 && csky_insn
.val
[1] == 14
6183 && csky_insn
.val
[2] >= 0 && csky_insn
.val
[2] <= 0x1fc
6184 && (csky_insn
.val
[2] & 0x3) == 0
6185 && csky_insn
.flag_force
!= INSN_OPCODE32F
)
6187 csky_insn
.inst
= 0x1420 | ((csky_insn
.val
[2] >> 2) & 0x1f);
6188 csky_insn
.inst
|= (csky_insn
.val
[2] << 1) & 0x300;
6191 else if (csky_insn
.val
[0] < 8
6192 && csky_insn
.val
[0] == csky_insn
.val
[1]
6193 && csky_insn
.val
[2] >= 1 && csky_insn
.val
[2] <= 0x100
6194 && csky_insn
.flag_force
!= INSN_OPCODE32F
)
6196 csky_insn
.inst
= 0x2800 | (csky_insn
.val
[0] << 8);
6197 csky_insn
.inst
|= (csky_insn
.val
[2] - 1);
6199 else if (csky_insn
.val
[0] < 8
6200 && csky_insn
.val
[1] < 8
6201 && csky_insn
.val
[2] >= 1 && csky_insn
.val
[2] <= 0x8
6202 && csky_insn
.flag_force
!= INSN_OPCODE32F
)
6204 csky_insn
.inst
= 0x5803 | (csky_insn
.val
[0] << 5);
6205 csky_insn
.inst
|= csky_insn
.val
[1] << 8;
6206 csky_insn
.inst
|= (csky_insn
.val
[2] - 1) << 2;
6208 else if (csky_insn
.val
[2] >= 1 && csky_insn
.val
[2] <= 0x1000
6209 && csky_insn
.flag_force
!= INSN_OPCODE16F
6210 && !IS_CSKY_ARCH_801 (mach_flag
))
6212 csky_insn
.inst
= 0xe4001000 | (csky_insn
.val
[0] << 21);
6213 csky_insn
.inst
|= csky_insn
.val
[1] << 16;
6214 csky_insn
.inst
|= (csky_insn
.val
[2] - 1);
6215 csky_insn
.isize
= 4;
6219 csky_show_error (ERROR_OPERANDS_ILLEGAL
, 0,
6220 (char *)csky_insn
.opcode_end
, NULL
);
6224 csky_insn
.output
= frag_more (csky_insn
.isize
);
6225 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6231 v2_work_add_sub (void)
6233 if (csky_insn
.number
== 3
6234 && (csky_insn
.val
[0] == csky_insn
.val
[1]
6235 || csky_insn
.val
[0] == csky_insn
.val
[2])
6236 && csky_insn
.val
[0] <= 15
6237 && csky_insn
.val
[1] <= 15
6238 && csky_insn
.val
[2] <= 15)
6240 if (!strstr (csky_insn
.opcode
->mnemonic
, "sub")
6241 || csky_insn
.val
[0] == csky_insn
.val
[1])
6243 csky_insn
.opcode_idx
= 0;
6244 csky_insn
.isize
= 2;
6245 if (csky_insn
.val
[0] == csky_insn
.val
[1])
6246 csky_insn
.val
[1] = csky_insn
.val
[2];
6248 csky_insn
.number
= 2;
6252 if (csky_insn
.isize
== 4
6253 && IS_CSKY_ARCH_801 (mach_flag
))
6255 if (csky_insn
.number
== 3)
6257 if (csky_insn
.val
[0] > 7)
6258 csky_show_error (ERROR_REG_OVER_RANGE
, 1,
6259 (void *)(long)csky_insn
.val
[0], NULL
);
6260 if (csky_insn
.val
[1] > 7)
6261 csky_show_error (ERROR_REG_OVER_RANGE
, 2,
6262 (void *)(long)csky_insn
.val
[1], NULL
);
6263 if (csky_insn
.val
[2] > 7)
6264 csky_show_error (ERROR_REG_OVER_RANGE
, 3,
6265 (void *)(long)csky_insn
.val
[2], NULL
);
6269 if (csky_insn
.val
[0] > 15)
6270 csky_show_error (ERROR_REG_OVER_RANGE
, 1,
6271 (void *)(long)csky_insn
.val
[0], NULL
);
6272 if (csky_insn
.val
[1] > 15)
6273 csky_show_error (ERROR_REG_OVER_RANGE
, 2,
6274 (void *)(long)csky_insn
.val
[1], NULL
);
6279 /* Generate relax or reloc if necessary. */
6280 csky_generate_frags ();
6281 /* Generate the insn by mask. */
6282 csky_generate_insn ();
6283 /* Write inst to frag. */
6284 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6289 v2_work_rotlc (void)
6291 const char *name
= "addc";
6293 = (struct csky_opcode
*) hash_find (csky_opcodes_hash
, name
);
6294 csky_insn
.opcode_idx
= 0;
6295 if (csky_insn
.isize
== 2)
6298 csky_insn
.number
= 2;
6299 csky_insn
.val
[1] = csky_insn
.val
[0];
6303 csky_insn
.number
= 3;
6304 /* addc rz, rx, ry. */
6305 csky_insn
.val
[1] = csky_insn
.val
[0];
6306 csky_insn
.val
[2] = csky_insn
.val
[0];
6308 /* Generate relax or reloc if necessary. */
6309 csky_generate_frags ();
6310 /* Generate the insn by mask. */
6311 csky_generate_insn ();
6312 /* Write inst to frag. */
6313 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6318 v2_work_bgeni (void)
6320 const char *name
= NULL
;
6321 int imm
= csky_insn
.val
[1];
6331 = (struct csky_opcode
*) hash_find (csky_opcodes_hash
, name
);
6332 csky_insn
.opcode_idx
= 0;
6333 csky_insn
.val
[1] = val
;
6335 /* Generate relax or reloc if necessary. */
6336 csky_generate_frags ();
6337 /* Generate the insn by mask. */
6338 csky_generate_insn ();
6339 /* Write inst to frag. */
6340 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6347 const char *name
= "nor";
6349 = (struct csky_opcode
*) hash_find (csky_opcodes_hash
, name
);
6350 csky_insn
.opcode_idx
= 0;
6351 if (csky_insn
.number
== 1)
6353 csky_insn
.val
[1] = csky_insn
.val
[0];
6354 if (csky_insn
.val
[0] < 16)
6356 /* 16 bits nor rz, rz. */
6357 csky_insn
.number
= 2;
6358 csky_insn
.isize
= 2;
6362 csky_insn
.val
[2] = csky_insn
.val
[0];
6363 csky_insn
.number
= 3;
6364 csky_insn
.isize
= 4;
6367 if (csky_insn
.number
== 2)
6369 if (csky_insn
.val
[0] == csky_insn
.val
[1]
6370 && csky_insn
.val
[0] < 16)
6372 /* 16 bits nor rz, rz. */
6373 csky_insn
.number
= 2;
6374 csky_insn
.isize
= 2;
6378 csky_insn
.val
[2] = csky_insn
.val
[1];
6379 csky_insn
.number
= 3;
6380 csky_insn
.isize
= 4;
6384 /* Generate relax or reloc if necessary. */
6385 csky_generate_frags ();
6386 /* Generate the insn by mask. */
6387 csky_generate_insn ();
6388 /* Write inst to frag. */
6389 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6396 if (csky_insn
.e1
.X_add_symbol
== NULL
|| csky_insn
.e1
.X_op
== O_constant
)
6398 csky_show_error (ERROR_UNDEFINE
, 0, (void *)"operand is invalid", NULL
);
6402 if (IS_CSKY_ARCH_801 (mach_flag
))
6404 /* CK801 doesn't have 32-bit bt/bf insns or a jump insn with a
6405 range larger than SCOND_DISP16. Relax to a short jump around
6406 an unconditional branch, and give up if that overflows too. */
6407 csky_insn
.output
= frag_var (rs_machine_dependent
,
6411 csky_insn
.e1
.X_add_symbol
,
6412 csky_insn
.e1
.X_add_number
,
6414 csky_insn
.isize
= 2;
6415 csky_insn
.max
= SCOND_DISP16_LEN
;
6416 csky_insn
.inst
= csky_insn
.opcode
->op16
[0].opcode
;
6418 else if (do_long_jump
&& !IS_CSKY_ARCH_802 (mach_flag
))
6420 /* Generate relax with jcondition.
6421 Note that CK802 doesn't support the JMPI instruction so
6422 we cannot relax to a jump with a 32-bit offset. */
6423 csky_insn
.output
= frag_var (rs_machine_dependent
,
6427 csky_insn
.e1
.X_add_symbol
,
6428 csky_insn
.e1
.X_add_number
,
6430 csky_insn
.isize
= 2;
6431 csky_insn
.max
= JCOND_DISP32_LEN
;
6432 csky_insn
.inst
= csky_insn
.opcode
->op16
[0].opcode
;
6436 /* Generate relax with condition. */
6437 csky_insn
.output
= frag_var (rs_machine_dependent
,
6441 csky_insn
.e1
.X_add_symbol
,
6442 csky_insn
.e1
.X_add_number
,
6444 csky_insn
.isize
= 2;
6445 csky_insn
.max
= COND_DISP16_LEN
;
6446 csky_insn
.inst
= csky_insn
.opcode
->op16
[0].opcode
;
6448 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6456 if (csky_insn
.e1
.X_add_symbol
== NULL
|| csky_insn
.e1
.X_op
== O_constant
)
6458 csky_show_error (ERROR_UNDEFINE
, 0, (void *)"operand is invalid", NULL
);
6463 && !IS_CSKY_ARCH_801 (mach_flag
)
6464 && !IS_CSKY_ARCH_802 (mach_flag
))
6466 csky_insn
.output
= frag_var (rs_machine_dependent
,
6470 csky_insn
.e1
.X_add_symbol
,
6471 csky_insn
.e1
.X_add_number
,
6474 csky_insn
.inst
= csky_insn
.opcode
->op16
[0].opcode
;
6475 csky_insn
.max
= JUNCD_DISP32_LEN
;
6476 csky_insn
.isize
= 2;
6480 /* Generate relax with condition. */
6481 csky_insn
.output
= frag_var (rs_machine_dependent
,
6485 csky_insn
.e1
.X_add_symbol
,
6486 csky_insn
.e1
.X_add_number
,
6488 csky_insn
.isize
= 2;
6489 csky_insn
.max
= UNCD_DISP16_LEN
;
6490 csky_insn
.inst
= csky_insn
.opcode
->op16
[0].opcode
;
6493 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6497 #define SIZE_V2_MOVI16(x) ((addressT)x <= 0xff)
6498 #define SIZE_V2_MOVI32(x) ((addressT)x <= 0xffff)
6499 #define SIZE_V2_MOVIH(x) ((addressT)x <= 0xffffffff && (((addressT)x & 0xffff) == 0))
6504 int reg
= csky_insn
.val
[0];
6505 int output_literal
= csky_insn
.val
[1];
6508 /* If the second operand is O_constant, We can use movi/movih
6510 if (csky_insn
.e1
.X_op
== O_constant
)
6512 /* 801 only has movi16. */
6513 if (SIZE_V2_MOVI16 (csky_insn
.e1
.X_add_number
) && reg
< 8)
6515 /* movi16 instead. */
6516 csky_insn
.output
= frag_more (2);
6517 csky_insn
.inst
= (CSKYV2_INST_MOVI16
| (reg
<< 8)
6518 | (csky_insn
.e1
.X_add_number
));
6519 csky_insn
.isize
= 2;
6522 else if (SIZE_V2_MOVI32 (csky_insn
.e1
.X_add_number
)
6523 && !IS_CSKY_ARCH_801 (mach_flag
))
6525 /* movi32 instead. */
6526 csky_insn
.output
= frag_more (4);
6527 csky_insn
.inst
= (CSKYV2_INST_MOVI32
| (reg
<< 16)
6528 | (csky_insn
.e1
.X_add_number
));
6529 csky_insn
.isize
= 4;
6532 else if (SIZE_V2_MOVIH (csky_insn
.e1
.X_add_number
)
6533 && !IS_CSKY_ARCH_801 (mach_flag
))
6535 /* movih instead. */
6536 csky_insn
.output
= frag_more (4);
6537 csky_insn
.inst
= (CSKYV2_INST_MOVIH
| (reg
<< 16)
6538 | ((csky_insn
.e1
.X_add_number
>> 16) & 0xffff));
6539 csky_insn
.isize
= 4;
6546 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6552 int n
= enter_literal (&csky_insn
.e1
, 0, 0, 0);
6553 /* Create a reference to pool entry. */
6554 csky_insn
.e1
.X_op
= O_symbol
;
6555 csky_insn
.e1
.X_add_symbol
= poolsym
;
6556 csky_insn
.e1
.X_add_number
= n
<< 2;
6558 /* If 16bit force. */
6559 if (csky_insn
.flag_force
== INSN_OPCODE16F
)
6561 /* Generate fixup. */
6564 csky_show_error (ERROR_UNDEFINE
, 0,
6565 (void *)"The register is out of range.", NULL
);
6568 csky_insn
.isize
= 2;
6569 csky_insn
.output
= frag_more (2);
6571 if (insn_reloc
== BFD_RELOC_CKCORE_TLS_GD32
6572 || insn_reloc
== BFD_RELOC_CKCORE_TLS_LDM32
6573 || insn_reloc
== BFD_RELOC_CKCORE_TLS_IE32
)
6575 literal_insn_offset
->tls_addend
.frag
= frag_now
;
6576 literal_insn_offset
->tls_addend
.offset
6577 = csky_insn
.output
- frag_now
->fr_literal
;
6579 csky_insn
.inst
= csky_insn
.opcode
->op16
[0].opcode
| (reg
<< 5);
6581 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
6582 2, &csky_insn
.e1
, 1, BFD_RELOC_CKCORE_PCREL_IMM7BY4
);
6584 else if (csky_insn
.flag_force
== INSN_OPCODE32F
)
6586 csky_insn
.isize
= 4;
6587 csky_insn
.output
= frag_more (4);
6588 if (insn_reloc
== BFD_RELOC_CKCORE_TLS_GD32
6589 || insn_reloc
== BFD_RELOC_CKCORE_TLS_LDM32
6590 || insn_reloc
== BFD_RELOC_CKCORE_TLS_IE32
)
6592 literal_insn_offset
->tls_addend
.frag
= frag_now
;
6593 literal_insn_offset
->tls_addend
.offset
6594 = csky_insn
.output
- frag_now
->fr_literal
;
6596 csky_insn
.inst
= csky_insn
.opcode
->op32
[0].opcode
| (reg
<< 16);
6597 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
6598 4, &csky_insn
.e1
, 1, BFD_RELOC_CKCORE_PCREL_IMM16BY4
);
6604 csky_insn
.isize
= 2;
6606 if (insn_reloc
== BFD_RELOC_CKCORE_TLS_GD32
6607 || insn_reloc
== BFD_RELOC_CKCORE_TLS_LDM32
6608 || insn_reloc
== BFD_RELOC_CKCORE_TLS_IE32
)
6609 literal_insn_offset
->tls_addend
.frag
= frag_now
;
6611 csky_insn
.output
= frag_var (rs_machine_dependent
,
6615 ? LRW2_DISP8
: LRW_DISP7
),
6616 csky_insn
.e1
.X_add_symbol
,
6617 csky_insn
.e1
.X_add_number
, 0);
6618 if (insn_reloc
== BFD_RELOC_CKCORE_TLS_GD32
6619 || insn_reloc
== BFD_RELOC_CKCORE_TLS_LDM32
6620 || insn_reloc
== BFD_RELOC_CKCORE_TLS_IE32
)
6622 if (literal_insn_offset
->tls_addend
.frag
->fr_next
!= frag_now
)
6623 literal_insn_offset
->tls_addend
.frag
6624 = literal_insn_offset
->tls_addend
.frag
->fr_next
;
6625 literal_insn_offset
->tls_addend
.offset
6627 - literal_insn_offset
->tls_addend
.frag
->fr_literal
);
6629 csky_insn
.inst
= csky_insn
.opcode
->op16
[0].opcode
| (reg
<< 5);
6630 csky_insn
.max
= LRW_DISP16_LEN
;
6631 csky_insn
.isize
= 2;
6635 csky_insn
.isize
= 4;
6636 csky_insn
.output
= frag_more (4);
6637 if (insn_reloc
== BFD_RELOC_CKCORE_TLS_GD32
6638 || insn_reloc
== BFD_RELOC_CKCORE_TLS_LDM32
6639 || insn_reloc
== BFD_RELOC_CKCORE_TLS_IE32
)
6641 literal_insn_offset
->tls_addend
.frag
= frag_now
;
6642 literal_insn_offset
->tls_addend
.offset
6643 = csky_insn
.output
- frag_now
->fr_literal
;
6645 csky_insn
.inst
= csky_insn
.opcode
->op32
[0].opcode
| (reg
<< 16);
6646 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
6647 4, &csky_insn
.e1
, 1, BFD_RELOC_CKCORE_PCREL_IMM16BY4
);
6651 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6656 v2_work_lrsrsw (void)
6658 int reg
= csky_insn
.val
[0];
6659 csky_insn
.output
= frag_more (4);
6660 csky_insn
.inst
= csky_insn
.opcode
->op32
[0].opcode
| (reg
<< 21);
6661 csky_insn
.isize
= 4;
6665 case BFD_RELOC_CKCORE_GOT32
:
6666 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
6667 4, &csky_insn
.e1
, 0, BFD_RELOC_CKCORE_GOT_IMM18BY4
);
6669 case BFD_RELOC_CKCORE_PLT32
:
6670 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
6671 4, &csky_insn
.e1
, 0, BFD_RELOC_CKCORE_PLT_IMM18BY4
);
6674 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
6675 4, &csky_insn
.e1
, 1, BFD_RELOC_CKCORE_DOFFSET_IMM18BY4
);
6678 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6686 || IS_CSKY_ARCH_801 (mach_flag
)
6687 || IS_CSKY_ARCH_802 (mach_flag
))
6689 csky_insn
.output
= frag_more (4);
6690 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
6691 4, &csky_insn
.e1
, 1, BFD_RELOC_CKCORE_PCREL_IMM26BY2
);
6692 csky_insn
.isize
= 4;
6693 csky_insn
.inst
= CSKYV2_INST_BSR32
;
6697 int n
= enter_literal (&csky_insn
.e1
, 0, 0, 0);
6698 csky_insn
.output
= frag_more (4);
6699 csky_insn
.e1
.X_op
= O_symbol
;
6700 csky_insn
.e1
.X_add_symbol
= poolsym
;
6701 csky_insn
.e1
.X_add_number
= n
<< 2;
6702 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
6703 4, &csky_insn
.e1
, 1, BFD_RELOC_CKCORE_PCREL_IMM16BY4
);
6704 if (do_jsri2bsr
|| IS_CSKY_ARCH_810 (mach_flag
))
6705 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
6707 &(litpool
+ (csky_insn
.e1
.X_add_number
>> 2))->e
,
6709 BFD_RELOC_CKCORE_PCREL_JSR_IMM26BY2
);
6710 csky_insn
.inst
= CSKYV2_INST_JSRI32
;
6711 csky_insn
.isize
= 4;
6712 if (IS_CSKY_ARCH_810 (mach_flag
))
6714 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6715 csky_insn
.output
= frag_more (4);
6716 dwarf2_emit_insn (0);
6717 /* Insert "mov r0, r0". */
6718 csky_insn
.inst
= CSKYV2_INST_MOV_R0_R0
;
6722 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6731 int n
= enter_literal (&csky_insn
.e1
, 1, 0, 0);
6732 csky_insn
.e1
.X_op
= O_symbol
;
6733 csky_insn
.e1
.X_add_symbol
= poolsym
;
6734 csky_insn
.e1
.X_add_number
= n
<< 2;
6736 /* Generate relax or reloc if necessary. */
6737 csky_generate_frags ();
6738 /* Generate the insn by mask. */
6739 csky_generate_insn ();
6740 /* Write inst to frag. */
6741 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6742 /* Control 810 not to generate jsri. */
6743 if (IS_CSKY_ARCH_810 (mach_flag
))
6745 /* Look at adding the R_PCREL_JSRIMM26BY2.
6746 For 'jbsr .L1', this reloc type's symbol
6747 is bound to '.L1', isn't bound to literal pool. */
6748 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
6749 4, &(litpool
+ (csky_insn
.e1
.X_add_number
>> 2))->e
, 1,
6750 BFD_RELOC_CKCORE_PCREL_JSR_IMM26BY2
);
6751 csky_insn
.output
= frag_more (4);
6752 dwarf2_emit_insn (0);
6753 /* The opcode of "mov32 r0,r0". */
6754 csky_insn
.inst
= CSKYV2_INST_MOV_R0_R0
;
6755 /* The effect of this value is to check literal. */
6756 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6763 v2_work_movih (void)
6765 int rz
= csky_insn
.val
[0];
6766 csky_insn
.output
= frag_more (4);
6767 csky_insn
.inst
= csky_insn
.opcode
->op32
[0].opcode
| (rz
<< 16);
6768 if (csky_insn
.e1
.X_op
== O_constant
)
6770 if (csky_insn
.e1
.X_unsigned
== 1 && csky_insn
.e1
.X_add_number
> 0xffff)
6772 csky_show_error (ERROR_IMM_OVERFLOW
, 2, NULL
, NULL
);
6775 else if (csky_insn
.e1
.X_unsigned
== 0 && csky_insn
.e1
.X_add_number
< 0)
6777 csky_show_error (ERROR_IMM_OVERFLOW
, 2, NULL
, NULL
);
6781 csky_insn
.inst
|= (csky_insn
.e1
.X_add_number
& 0xffff);
6783 else if (csky_insn
.e1
.X_op
== O_right_shift
6784 || (csky_insn
.e1
.X_op
== O_symbol
&& insn_reloc
!= BFD_RELOC_NONE
))
6786 if (csky_insn
.e1
.X_op_symbol
!= 0
6787 && symbol_constant_p (csky_insn
.e1
.X_op_symbol
)
6788 && S_GET_SEGMENT (csky_insn
.e1
.X_op_symbol
) == absolute_section
6789 && 16 == S_GET_VALUE (csky_insn
.e1
.X_op_symbol
))
6791 csky_insn
.e1
.X_op
= O_symbol
;
6792 if (insn_reloc
== BFD_RELOC_CKCORE_GOT32
)
6793 insn_reloc
= BFD_RELOC_CKCORE_GOT_HI16
;
6794 else if (insn_reloc
== BFD_RELOC_CKCORE_PLT32
)
6795 insn_reloc
= BFD_RELOC_CKCORE_PLT_HI16
;
6796 else if (insn_reloc
== BFD_RELOC_CKCORE_GOTPC
)
6797 insn_reloc
= BFD_RELOC_CKCORE_GOTPC_HI16
;
6798 else if (insn_reloc
== BFD_RELOC_CKCORE_GOTOFF
)
6799 insn_reloc
= BFD_RELOC_CKCORE_GOTOFF_HI16
;
6801 insn_reloc
= BFD_RELOC_CKCORE_ADDR_HI16
;
6802 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
6803 4, &csky_insn
.e1
, 0, insn_reloc
);
6807 void *arg
= (void *)"the second operand must be \"SYMBOL >> 16\"";
6808 csky_show_error (ERROR_UNDEFINE
, 0, arg
, NULL
);
6812 csky_insn
.isize
= 4;
6813 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6821 int rz
= csky_insn
.val
[0];
6822 int rx
= csky_insn
.val
[1];
6823 csky_insn
.output
= frag_more (4);
6824 csky_insn
.inst
= csky_insn
.opcode
->op32
[0].opcode
| (rz
<< 21) | (rx
<< 16);
6825 if (csky_insn
.e1
.X_op
== O_constant
)
6827 if (csky_insn
.e1
.X_add_number
<= 0xffff
6828 && csky_insn
.e1
.X_add_number
>= 0)
6829 csky_insn
.inst
|= csky_insn
.e1
.X_add_number
;
6832 csky_show_error (ERROR_IMM_OVERFLOW
, 3, NULL
, NULL
);
6836 else if (csky_insn
.e1
.X_op
== O_bit_and
)
6838 if (symbol_constant_p (csky_insn
.e1
.X_op_symbol
)
6839 && S_GET_SEGMENT (csky_insn
.e1
.X_op_symbol
) == absolute_section
6840 && 0xffff == S_GET_VALUE (csky_insn
.e1
.X_op_symbol
))
6842 csky_insn
.e1
.X_op
= O_symbol
;
6843 if (insn_reloc
== BFD_RELOC_CKCORE_GOT32
)
6844 insn_reloc
= BFD_RELOC_CKCORE_GOT_LO16
;
6845 else if (insn_reloc
== BFD_RELOC_CKCORE_PLT32
)
6846 insn_reloc
= BFD_RELOC_CKCORE_PLT_LO16
;
6847 else if (insn_reloc
== BFD_RELOC_CKCORE_GOTPC
)
6848 insn_reloc
= BFD_RELOC_CKCORE_GOTPC_LO16
;
6849 else if (insn_reloc
== BFD_RELOC_CKCORE_GOTOFF
)
6850 insn_reloc
= BFD_RELOC_CKCORE_GOTOFF_LO16
;
6852 insn_reloc
= BFD_RELOC_CKCORE_ADDR_LO16
;
6853 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
6854 4, &csky_insn
.e1
, 0, insn_reloc
);
6858 void *arg
= (void *)"the third operand must be \"SYMBOL & 0xffff\"";
6859 csky_show_error (ERROR_UNDEFINE
, 0, arg
, NULL
);
6863 csky_insn
.isize
= 4;
6864 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6868 /* Helper function to encode a single/double floating point constant
6869 into the instruction word for fmovis and fmovid instructions.
6870 The constant is in its IEEE single/double precision representation
6871 and is repacked into the internal 13-bit representation for these
6872 instructions with a diagnostic for overflow. Note that there is no
6873 rounding when converting to the smaller format, just an error if there
6874 is excess precision or the number is too small/large to be represented. */
6877 float_work_fmovi (void)
6879 int rx
= csky_insn
.val
[0];
6881 /* We already converted the float constant to the internal 13-bit
6882 representation so we just need to OR it in here. */
6883 csky_insn
.inst
= csky_insn
.opcode
->op32
[0].opcode
| rx
;
6884 csky_insn
.inst
|= (uint32_t) csky_insn
.e1
.X_add_number
;
6886 csky_insn
.output
= frag_more (4);
6887 csky_insn
.isize
= 4;
6888 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6893 dsp_work_bloop (void)
6895 int reg
= csky_insn
.val
[0];
6896 csky_insn
.output
= frag_more (4);
6897 csky_insn
.inst
= csky_insn
.opcode
->op32
[0].opcode
| (reg
<< 16);
6898 csky_insn
.isize
= 4;
6900 if (csky_insn
.e1
.X_op
== O_symbol
6901 && csky_insn
.e2
.X_op
== O_symbol
)
6903 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
6904 4, &csky_insn
.e1
, 1,
6905 BFD_RELOC_CKCORE_PCREL_BLOOP_IMM12BY4
);
6906 fix_new_exp (frag_now
, csky_insn
.output
- frag_now
->fr_literal
,
6907 4, &csky_insn
.e2
, 1,
6908 BFD_RELOC_CKCORE_PCREL_BLOOP_IMM4BY4
);
6911 csky_write_insn (csky_insn
.output
, csky_insn
.inst
, csky_insn
.isize
);
6916 /* The following are for assembler directive handling. */
6918 /* Helper function to adjust constant pool counts when we emit a
6919 data directive in the text section. FUNC is one of the standard
6920 gas functions to handle these directives, like "stringer" for the
6921 .string directive, and ARG is the argument to FUNC. csky_pool_count
6922 essentially wraps the call with the constant pool magic. */
6925 csky_pool_count (void (*func
) (int), int arg
)
6927 const fragS
*curr_frag
= frag_now
;
6928 offsetT added
= -frag_now_fix_octets ();
6932 while (curr_frag
!= frag_now
)
6934 added
+= curr_frag
->fr_fix
;
6935 curr_frag
= curr_frag
->fr_next
;
6938 added
+= frag_now_fix_octets ();
6942 /* Support the .literals directive. */
6944 csky_s_literals (int ignore ATTRIBUTE_UNUSED
)
6947 demand_empty_rest_of_line ();
6950 /* Support the .string, etc directives. */
6952 csky_stringer (int append_zero
)
6954 if (now_seg
== text_section
)
6955 csky_pool_count (stringer
, append_zero
);
6957 stringer (append_zero
);
6959 /* We call check_literals here in case a large number of strings are
6960 being placed into the text section with a sequence of stringer
6961 directives. In theory we could be upsetting something if these
6962 strings are actually in an indexed table instead of referenced by
6963 individual labels. Let us hope that that never happens. */
6964 check_literals (2, 0);
6967 /* Support integer-mode constructors like .word, .byte, etc. */
6970 csky_cons (int nbytes
)
6972 mapping_state (MAP_DATA
);
6973 if (nbytes
== 4) /* @GOT. */
6977 bfd_reloc_code_real_type reloc
;
6980 reloc
= BFD_RELOC_NONE
;
6982 lex_got (&reloc
, NULL
);
6984 if (exp
.X_op
== O_symbol
&& reloc
!= BFD_RELOC_NONE
)
6986 reloc_howto_type
*howto
6987 = bfd_reloc_type_lookup (stdoutput
, reloc
);
6988 int size
= bfd_get_reloc_size (howto
);
6991 as_bad (ngettext ("%s relocations do not fit in %d byte",
6992 "%s relocations do not fit in %d bytes",
6994 howto
->name
, nbytes
);
6997 register char *p
= frag_more ((int) nbytes
);
6998 int offset
= nbytes
- size
;
7000 fix_new_exp (frag_now
,
7001 p
- frag_now
->fr_literal
+ offset
,
7002 size
, &exp
, 0, reloc
);
7006 emit_expr (&exp
, (unsigned int) nbytes
);
7007 if (now_seg
== text_section
)
7010 while (*input_line_pointer
++ == ',');
7012 /* Put terminator back into stream. */
7013 input_line_pointer
--;
7014 demand_empty_rest_of_line ();
7019 if (now_seg
== text_section
)
7020 csky_pool_count (cons
, nbytes
);
7024 /* In theory we ought to call check_literals (2,0) here in case
7025 we need to dump the literal table. We cannot do this however,
7026 as the directives that we are intercepting may be being used
7027 to build a switch table, and we must not interfere with its
7028 contents. Instead we cross our fingers and pray... */
7031 /* Support floating-mode constant directives like .float and .double. */
7034 csky_float_cons (int float_type
)
7036 mapping_state (MAP_DATA
);
7037 if (now_seg
== text_section
)
7038 csky_pool_count (float_cons
, float_type
);
7040 float_cons (float_type
);
7042 /* See the comment in csky_cons () about calling check_literals.
7043 It is unlikely that a switch table will be constructed using
7044 floating point values, but it is still likely that an indexed
7045 table of floating point constants is being created by these
7046 directives, so again we must not interfere with their placement. */
7049 /* Support the .fill directive. */
7052 csky_fill (int ignore
)
7054 if (now_seg
== text_section
)
7055 csky_pool_count (s_fill
, ignore
);
7059 check_literals (2, 0);
7062 /* Handle the section changing pseudo-ops. These call through to the
7063 normal implementations, but they dump the literal pool first. */
7066 csky_s_text (int ignore
)
7071 obj_elf_text (ignore
);
7078 csky_s_data (int ignore
)
7083 obj_elf_data (ignore
);
7090 csky_s_section (int ignore
)
7092 /* Scan forwards to find the name of the section. If the section
7093 being switched to is ".line" then this is a DWARF1 debug section
7094 which is arbitrarily placed inside generated code. In this case
7095 do not dump the literal pool because it is a) inefficient and
7096 b) would require the generation of extra code to jump around the
7098 char * ilp
= input_line_pointer
;
7100 while (*ilp
!= 0 && ISSPACE (*ilp
))
7103 if (strncmp (ilp
, ".line", 5) == 0
7104 && (ISSPACE (ilp
[5]) || *ilp
== '\n' || *ilp
== '\r'))
7110 obj_elf_section (ignore
);
7113 obj_coff_section (ignore
);
7118 csky_s_bss (int needs_align
)
7121 s_lcomm_bytes (needs_align
);
7126 csky_s_comm (int needs_align
)
7129 obj_elf_common (needs_align
);
7133 /* Handle the .no_literal_dump directive. */
7136 csky_noliteraldump (int ignore ATTRIBUTE_UNUSED
)
7138 do_noliteraldump
= 1;
7139 int insn_num
= get_absolute_expression ();
7140 /* The insn after '.no_literal_dump insn_num' is insn1,
7141 Don't dump literal pool between insn1 and insn(insn_num+1)
7142 The insn cannot be the insn generate literal, like lrw & jsri. */
7143 check_literals (0, insn_num
* 2);
7146 /* Handle the .align directive.
7147 We must check literals before doing alignment. For example, if
7148 '.align n', add (2^n-1) to poolspan and check literals. */
7151 csky_s_align_ptwo (int arg
)
7153 /* Get the .align's first absolute number. */
7154 char * temp_pointer
= input_line_pointer
;
7155 int align
= get_absolute_expression ();
7156 check_literals (0, (1 << align
) - 1);
7157 input_line_pointer
= temp_pointer
;
7163 /* Handle the .stack_size directive. */
7166 csky_stack_size (int arg ATTRIBUTE_UNUSED
)
7169 stack_size_entry
*sse
7170 = (stack_size_entry
*) xcalloc (1, sizeof (stack_size_entry
));
7173 if (exp
.X_op
== O_symbol
)
7174 sse
->function
= exp
.X_add_symbol
;
7177 as_bad (_("the first operand must be a symbol"));
7178 ignore_rest_of_line ();
7184 if (*input_line_pointer
!= ',')
7186 as_bad (_("missing stack size"));
7187 ignore_rest_of_line ();
7192 ++input_line_pointer
;
7194 if (exp
.X_op
== O_constant
)
7196 if (exp
.X_add_number
< 0 || exp
.X_add_number
> (offsetT
)0xffffffff)
7199 as_bad (_("value not in range [0, 0xffffffff]"));
7200 ignore_rest_of_line ();
7205 sse
->stack_size
= exp
.X_add_number
;
7209 as_bad (_("operand must be a constant"));
7210 ignore_rest_of_line ();
7215 if (*last_stack_size_data
!= NULL
)
7216 last_stack_size_data
= &((*last_stack_size_data
)->next
);
7218 *last_stack_size_data
= sse
;
7221 /* This table describes all the machine specific pseudo-ops the assembler
7222 has to support. The fields are:
7223 pseudo-op name without dot
7224 function to call to execute this pseudo-op
7225 Integer arg to pass to the function. */
7227 const pseudo_typeS md_pseudo_table
[] =
7229 { "export", s_globl
, 0 },
7230 { "import", s_ignore
, 0 },
7231 { "literals", csky_s_literals
, 0 },
7232 { "page", listing_eject
, 0 },
7234 /* The following are to intercept the placement of data into the text
7235 section (eg addresses for a switch table), so that the space they
7236 occupy can be taken into account when deciding whether or not to
7237 dump the current literal pool.
7238 XXX - currently we do not cope with the .space and .dcb.d directives. */
7239 { "ascii", csky_stringer
, 8 + 0 },
7240 { "asciz", csky_stringer
, 8 + 1 },
7241 { "byte", csky_cons
, 1 },
7242 { "dc", csky_cons
, 2 },
7243 { "dc.b", csky_cons
, 1 },
7244 { "dc.d", csky_float_cons
, 'd'},
7245 { "dc.l", csky_cons
, 4 },
7246 { "dc.s", csky_float_cons
, 'f'},
7247 { "dc.w", csky_cons
, 2 },
7248 { "dc.x", csky_float_cons
, 'x'},
7249 { "double", csky_float_cons
, 'd'},
7250 { "float", csky_float_cons
, 'f'},
7251 { "hword", csky_cons
, 2 },
7252 { "int", csky_cons
, 4 },
7253 { "long", csky_cons
, 4 },
7254 { "octa", csky_cons
, 16 },
7255 { "quad", csky_cons
, 8 },
7256 { "short", csky_cons
, 2 },
7257 { "single", csky_float_cons
, 'f'},
7258 { "string", csky_stringer
, 8 + 1 },
7259 { "word", csky_cons
, 4 },
7260 { "fill", csky_fill
, 0 },
7262 /* Allow for the effect of section changes. */
7263 { "text", csky_s_text
, 0 },
7264 { "data", csky_s_data
, 0 },
7265 { "bss", csky_s_bss
, 1 },
7267 { "comm", csky_s_comm
, 0 },
7269 { "section", csky_s_section
, 0 },
7270 { "section.s", csky_s_section
, 0 },
7271 { "sect", csky_s_section
, 0 },
7272 { "sect.s", csky_s_section
, 0 },
7273 /* When ".no_literal_dump N" is in front of insn1,
7274 and instruction sequence is:
7279 it means literals will not dump between insn1 and insnN+1
7280 The insn cannot itself generate literal, like lrw & jsri. */
7281 { "no_literal_dump", csky_noliteraldump
, 0 },
7282 { "align", csky_s_align_ptwo
, 0 },
7283 { "stack_size", csky_stack_size
, 0 },
7287 /* Implement tc_cfi_frame_initial_instructions. */
7290 csky_cfi_frame_initial_instructions (void)
7292 int sp_reg
= IS_CSKY_V1 (mach_flag
) ? 0 : 14;
7293 cfi_add_CFA_def_cfa_register (sp_reg
);
7296 /* Implement tc_regname_to_dw2regnum. */
7299 tc_csky_regname_to_dw2regnum (char *regname
)
7304 /* FIXME the reg should be parsed according to
7306 reg_num
= csky_get_reg_val (regname
, &len
);