[PATCH 8/57][Arm][GAS] Add support for MVE instructions: vcvt
[binutils-gdb.git] / gas / config / tc-csky.c
blob970c72afaf00c258ffade268d5e9def287e1ff53
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)
11 any later version.
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
21 02110-1301, USA. */
23 #include "as.h"
24 #include <limits.h>
25 #include <stdint.h>
26 #include <stdarg.h>
27 #include <ctype.h>
28 #include "safe-ctype.h"
29 #include "subsegs.h"
30 #include "obstack.h"
31 #include "libiberty.h"
33 #ifdef OBJ_ELF
34 #include "elf/csky.h"
35 #include "dw2gencfi.h"
36 #endif
37 #include "tc-csky.h"
38 #include "dwarf2dbg.h"
40 #define BUILD_AS 1
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)
53 #define KB * 1024
54 #define MB KB * 1024
55 #define GB MB * 1024
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. */
88 #define COND_JUMP 1
89 #define UNCD_JUMP 2
90 #define COND_JUMP_PIC 3
91 #define UNCD_JUMP_PIC 4
93 #define UNDEF_DISP 0
94 #define DISP12 1
95 #define DISP32 2
96 #define UNDEF_WORD_DISP 3
98 #define C12_LEN 2
99 /* Allow for align: bt/jmpi/.long + align. */
100 #define C32_LEN 10
101 /* Allow for align: bt/subi/stw/bsr/lrw/add/ld/addi/jmp/.long + align. */
102 #define C32_LEN_PIC 24
103 #define U12_LEN 2
104 /* Allow for align: jmpi/.long + align. */
105 #define U32_LEN 8
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"
180 enum
182 RELAX_NONE = 0,
183 RELAX_OVERFLOW,
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;
221 symbolS *function;
222 unsigned int stack_size;
223 } stack_size_entry;
225 struct csky_arch_info
227 const char *name;
228 unsigned int arch_flag;
229 unsigned int bfd_mach_flag;
232 struct csky_cpu_info
234 const char *name;
235 unsigned int mach_flag;
236 unsigned int isa_flag;
239 typedef enum
241 INSN_OPCODE,
242 INSN_OPCODE16F,
243 INSN_OPCODE32F,
244 } inst_flag;
246 /* Macro information. */
247 struct csky_macro_info
249 const char *name;
250 /* How many operands : if operands == 5, all of 1,2,3,4 are ok. */
251 long oprnd_num;
252 int isa_flag;
253 /* Do the work. */
254 void (*handle_func)(void);
257 struct csky_insn_info
259 /* Name of the opcode. */
260 char *name;
261 /* Output instruction. */
262 unsigned int inst;
263 /* Pointer for frag. */
264 char *output;
265 /* End of instruction. */
266 char *opcode_end;
267 /* Flag for INSN_OPCODE16F, INSN_OPCODE32F, INSN_OPCODE, INSN_MACRO. */
268 inst_flag flag_force;
269 /* Operand number. */
270 int number;
271 struct csky_opcode *opcode;
272 struct csky_macro_info *macro;
273 /* Insn size for check_literal. */
274 unsigned int isize;
275 /* Max size of insn for relax frag_var. */
276 unsigned int max;
277 /* Indicates which element is in csky_opcode_info op[] array. */
278 int opcode_idx;
279 /* The value of each operand in instruction when layout. */
280 int idx;
281 int val[MAX_OPRND_NUM];
282 struct relax_info
284 int max;
285 int var;
286 int subtype;
287 } relax;
288 /* The following are used for constant expressions. */
289 expressionS e1;
290 expressionS e2;
293 /* Literal pool data structures. */
294 struct literal
296 unsigned short refcnt;
297 unsigned char ispcrel;
298 unsigned char unused;
299 bfd_reloc_code_real_type r_type;
300 expressionS e;
301 struct tls_addend tls_addend;
302 unsigned char isdouble;
303 uint64_t dbnum;
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. */
324 enum error_number
326 /* The following are errors. */
327 ERROR_CREG_ILLEGAL = 0,
328 ERROR_REG_OVER_RANGE,
329 ERROR_GREG_ILLEGAL,
330 ERROR_802J_REG_OVER_RANGE,
331 ERROR_REG_FORMAT,
332 ERROR_REG_LIST,
333 ERROR_IMM_ILLEGAL,
334 ERROR_IMM_OVERFLOW, /* 5 */
335 ERROR_IMM_POWER,
336 ERROR_JMPIX_OVER_RANGE,
337 ERROR_EXP_CREG,
338 ERROR_EXP_GREG,
339 ERROR_EXP_CONSTANT,
340 ERROR_EXP_EVEN_FREG,
341 ERROR_RELOC_ILLEGAL,
342 ERROR_MISSING_OPERAND, /* 10 */
343 ERROR_MISSING_COMMA,
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,
351 ERROR_BAD_END,
352 ERROR_UNDEFINE,
353 ERROR_CPREG_ILLEGAL, /* 20 */
354 ERROR_OPCODE_PSRBIT,
355 ERROR_OPERANDS_ILLEGAL,
356 ERROR_OPERANDS_NUMBER,
357 ERROR_OPCODE_ILLEGAL,
359 /* The following are warnings. */
360 WARNING_OPTIONS,
361 WARNING_IDLY,
363 /* Error and warning end. */
364 ERROR_NONE,
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;
373 int opnum;
374 const void *arg1;
375 const void *arg2;
376 } error_state;
378 /* This macro is used to set error number and arg1 in the global state. */
380 #define SET_ERROR_NUMBER(err, msg) \
381 do { \
382 if (error_state.err_num > err) \
384 error_state.err_num = err; \
385 error_state.arg1 = (void *)msg; \
387 } while (0)
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;
395 const char *fmt;
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;
451 #else
452 static int do_use_branchstub = 0;
453 #endif
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
482 * 0 : do nothing. */
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 */
497 {0, 0, 0, 0},
498 {0, 0, 0, 0},
500 /* COND_JUMP */
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 */
506 /* UNCD_JUMP */
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 */
512 /* COND_JUMP_PIC */
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 */
518 /* UNCD_JUMP_PIC */
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},
570 {NULL, 0, 0}
573 /* C-SKY cpus table. */
574 const struct csky_cpu_info csky_cpus[] =
576 /* CK510 series. */
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
583 /* CK610 series. */
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},
591 /* CK801 series. */
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},
597 /* CK802 series. */
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},
603 /* CK803 series. */
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},
645 /* CK807 series. */
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},
653 /* CK810 series. */
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},
668 {NULL, 0, 0}
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.
694 As in 0f12.456
695 or 0d1.2345e12 */
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},
741 #endif
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},
773 {NULL,0,0,0}
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},
790 {NULL,0,0,0}
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. */
799 static void
800 csky_show_error (enum error_number err, int idx, void *arg1, void *arg2)
802 if (err == ERROR_NONE)
803 return;
805 switch (err)
807 case ERROR_REG_LIST:
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);
820 break;
821 case ERROR_CREG_ILLEGAL:
822 case ERROR_GREG_ILLEGAL:
823 case ERROR_IMM_ILLEGAL:
824 case ERROR_IMM_OVERFLOW:
825 case ERROR_EXP_CREG:
826 case ERROR_EXP_GREG:
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);
832 break;
833 case ERROR_OPERANDS_NUMBER:
834 case ERROR_IMM_POWER:
835 as_bad (_(err_formats[err].fmt), (long)arg1);
836 break;
838 case ERROR_OFFSET_UNALIGNED:
839 as_bad (_(err_formats[err].fmt), idx, (long)arg1);
840 break;
841 case ERROR_RELOC_ILLEGAL:
842 case ERROR_BAD_END:
843 case ERROR_OPERANDS_ILLEGAL:
844 as_bad (_(err_formats[err].fmt), (char *)arg1);
845 break;
846 case ERROR_REG_OVER_RANGE:
847 as_bad (_(err_formats[err].fmt), idx, (long) arg1);
848 break;
849 case ERROR_802J_REG_OVER_RANGE:
850 case ERROR_REG_FORMAT:
851 as_bad (_(err_formats[err].fmt), idx, (char *)arg1);
852 break;
853 case ERROR_UNDEFINE:
854 /* Add NULL to fix warnings. */
855 as_bad ((char *)arg1, NULL);
856 break;
857 case WARNING_IDLY:
858 as_warn (_(err_formats[err].fmt), (long)arg1);
859 break;
860 case WARNING_OPTIONS:
861 as_warn (_(err_formats[err].fmt), (char *)arg1, (char *)arg2);
862 break;
863 default:
864 break;
868 /* Handle errors in branch relaxation. */
870 static void
871 csky_branch_report_error (const char* file, unsigned int line,
872 symbolS* sym, offsetT val)
874 as_bad_where (file ? file : _("unknown"),
875 line,
876 _("pcrel offset for branch to %s too far (0x%lx)"),
877 sym ? S_GET_NAME (sym) : _("<unknown>"),
878 (long) val);
881 /* Set appropriate flags for the cpu matching STR. */
883 static void
884 parse_cpu (const char *str)
886 int i = 0;
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);
894 return;
896 as_bad (_("unknown cpu `%s'"), str);
899 /* Set appropriate flags for the arch matching STR. */
901 static void
902 parse_arch (const char *str)
904 int i = 0;
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;
909 return;
911 as_bad (_("unknown architecture `%s'"), str);
915 #ifdef OBJ_ELF
916 /* Implement the TARGET_FORMAT macro. */
918 const char *
919 elf32_csky_target_format (void)
921 return (target_big_endian
922 ? "elf32-csky-big"
923 : "elf32-csky-little");
925 #endif
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). */
934 void
935 md_number_to_chars (char * buf, valueT val, int n)
937 if (target_big_endian)
938 number_to_chars_bigendian (buf, val, n);
939 else
940 number_to_chars_littleendian (buf, val, n);
943 /* Get a log2(val). */
945 static int
946 csky_log_2 (unsigned int val)
948 int log = -1;
949 if ((val & (val - 1)) == 0)
950 for (; val; val >>= 1)
951 log ++;
952 else
953 csky_show_error (ERROR_IMM_POWER, 0, (void *)(long)val, NULL);
954 return log;
957 /* Output one instruction to the buffer at PTR. */
959 static void
960 csky_write_insn (char *ptr, valueT use, int nbytes)
962 if (nbytes == 2)
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. */
975 static valueT
976 csky_read_insn (char *ptr, int nbytes)
978 unsigned char *uptr = (unsigned char *)ptr;
979 valueT v = 0;
980 int lo, hi; /* hi/lo byte index in binary stream. */
982 if (target_big_endian)
984 hi = 0;
985 lo = 1;
987 else
989 hi = 1;
990 lo = 0;
992 v = uptr[lo] | (uptr[hi] << 8);
993 if (nbytes == 4)
995 v <<= 16;
996 v |= uptr[lo + 2] | (uptr[hi + 2] << 8);
998 return v;
1001 /* Construct a label name into S from the 3-character prefix P and
1002 number N formatted as a 4-digit hex number. */
1004 static void
1005 make_internal_label (char *s, const char *p, int n)
1007 static const char hex[] = "0123456789ABCDEF";
1009 s[0] = p[0];
1010 s[1] = p[1];
1011 s[2] = p[2];
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];
1016 s[7] = 0;
1019 /* md_operand is a no-op on C-SKY; we do everything elsewhere. */
1021 void
1022 md_operand (expressionS *expressionP ATTRIBUTE_UNUSED)
1024 return;
1027 /* Under ELF we need to default _GLOBAL_OFFSET_TABLE.
1028 Otherwise we have no need to default values of symbols. */
1030 symbolS *
1031 md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
1033 #ifdef OBJ_ELF
1034 /* TODO: */
1035 #endif
1036 return NULL;
1039 /* Use IEEE format for floating-point constants. */
1041 const char *
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. */
1049 void
1050 md_show_usage (FILE *fp)
1052 int i, n;
1053 const int margin = 48;
1055 fprintf (fp, _("C-SKY assembler options:\n"));
1057 fprintf (fp, _("\
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");
1065 n = l;
1067 else
1069 fprintf (fp, " ");
1070 n += l + 1;
1072 fprintf (fp, "%s", csky_archs[i].name);
1074 fprintf (fp, "\n");
1076 fprintf (fp, _("\
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");
1084 n = l;
1086 else
1088 fprintf (fp, " ");
1089 n += l + 1;
1091 fprintf (fp, "%s", csky_cpus[i].name);
1093 fprintf (fp, "\n");
1095 fprintf (fp, _("\
1096 -EL -mlittle-endian generate little-endian output\n"));
1097 fprintf (fp, _("\
1098 -EB -mbig-endian generate big-endian output\n"));
1099 fprintf (fp, _("\
1100 -fpic -pic generate position-independent code\n"));
1102 fprintf (fp, _("\
1103 -mljump transform jbf, jbt, jbr to jmpi (CK800 only)\n"));
1104 fprintf (fp, _("\
1105 -mno-ljump\n"));
1107 #ifdef INCLUDE_BRANCH_STUB
1108 fprintf (fp, _("\
1109 -mbranch-stub enable branch stubs for PC-relative calls\n"));
1110 fprintf (fp, _("\
1111 -mno-branch-stub\n"));
1112 #endif
1114 fprintf (fp, _("\
1115 -force2bsr -mforce2bsr transform jbsr to bsr\n"));
1116 fprintf (fp, _("\
1117 -no-force2bsr -mno-force2bsr\n"));
1118 fprintf (fp, _("\
1119 -jsri2bsr -mjsri2bsr transform jsri to bsr\n"));
1120 fprintf (fp, _("\
1121 -no-jsri2bsr -mno-jsri2bsr\n"));
1123 fprintf (fp, _("\
1124 -mnolrw -mno-lrw implement lrw as movih + ori\n"));
1125 fprintf (fp, _("\
1126 -melrw enable extended lrw (CK800 only)\n"));
1127 fprintf (fp, _("\
1128 -mno-elrw\n"));
1130 fprintf (fp, _("\
1131 -mlaf -mliterals-after-func emit literals after each function\n"));
1132 fprintf (fp, _("\
1133 -mno-laf -mno-literals-after-func\n"));
1134 fprintf (fp, _("\
1135 -mlabr -mliterals-after-br emit literals after branch instructions\n"));
1136 fprintf (fp, _("\
1137 -mno-labr -mnoliterals-after-br\n"));
1139 fprintf (fp, _("\
1140 -mistack enable interrupt stack instructions\n"));
1141 fprintf (fp, _("\
1142 -mno-istack\n"));
1144 fprintf (fp, _("\
1145 -mhard-float enable hard float instructions\n"));
1146 fprintf (fp, _("\
1147 -mmp enable multiprocessor instructions\n"));
1148 fprintf (fp, _("\
1149 -mcp enable coprocessor instructions\n"));
1150 fprintf (fp, _("\
1151 -mcache enable cache prefetch instruction\n"));
1152 fprintf (fp, _("\
1153 -msecurity enable security instructions\n"));
1154 fprintf (fp, _("\
1155 -mtrust enable trust instructions\n"));
1156 fprintf (fp, _("\
1157 -mdsp enable DSP instructions\n"));
1158 fprintf (fp, _("\
1159 -medsp enable enhanced DSP instructions\n"));
1160 fprintf (fp, _("\
1161 -mvdsp enable vector DSP instructions\n"));
1164 /* Target-specific initialization and option handling. */
1166 void
1167 md_begin (void)
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;
1179 if (dsp_flag)
1180 flags |= CSKY_ARCH_DSP;
1182 if (mach_flag != 0)
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;
1191 else
1193 #ifdef TARGET_WITH_CPU
1194 int i = 0;
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;
1201 break;
1204 #else
1205 #if _CSKY_ABI==1
1206 mach_flag |= CSKY_ARCH_610 | flags;
1207 #else
1208 mach_flag |= CSKY_ARCH_810_BASE | flags;
1209 #endif
1210 #endif
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;
1233 break;
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;
1241 break;
1244 /* Check if -mdsp and -medsp conflict. If cpu is ck803, we will
1245 use enhanced dsp instruction. Otherwise, we will use normal dsp. */
1246 if (dsp_flag)
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;
1256 else
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"));
1276 do_force2bsr = 1;
1280 if (IS_CSKY_ARCH_801 (mach_flag) || IS_CSKY_ARCH_802 (mach_flag))
1282 if (!do_force2bsr)
1283 as_warn (_("-mno-force2bsr is ignored for ck801/ck802"));
1284 do_force2bsr = 1;
1286 else if (do_force2bsr == -1)
1287 do_force2bsr = do_use_branchstub;
1289 if (do_pff == -1)
1291 if (IS_CSKY_ARCH_V1 (mach_flag))
1292 do_pff = 1;
1293 else
1294 do_pff = 0;
1297 if (do_extend_lrw == -1)
1299 if (IS_CSKY_ARCH_801 (mach_flag))
1300 do_extend_lrw = 1;
1301 else
1302 do_extend_lrw = 0;
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"));
1308 do_long_jump = 0;
1310 else if (do_long_jump == -1)
1311 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))
1317 do_intr_stack = 0;
1318 else
1319 do_intr_stack = 1;
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;
1337 else
1339 mach_flag = mach_flag | CSKY_ABI_V2;
1340 opcode = csky_v2_opcodes;
1341 macro = v2_macros_table;
1342 SPANPANIC = v2_SPANPANIC;
1343 if (do_extend_lrw)
1345 SPANCLOSE = v2_SPANCLOSE_ELRW;
1346 SPANEXIT = v2_SPANEXIT_ELRW;
1348 else
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. */
1379 static void
1380 make_mapping_symbol (map_state state, valueT value, fragS *frag)
1382 symbolS * symbolP;
1383 const char * symname;
1384 int type;
1385 switch (state)
1387 case MAP_DATA:
1388 symname = "$d";
1389 type = BSF_NO_FLAGS;
1390 break;
1391 case MAP_TEXT:
1392 symname = "$t";
1393 type = BSF_NO_FLAGS;
1394 break;
1395 default:
1396 abort ();
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. */
1406 static void
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)
1413 return;
1414 else if (current_state == MAP_UNDEFINED && state == MAP_DATA)
1415 return;
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. */
1429 static void
1430 dump_literals (int isforce)
1432 #define CSKYV1_BR_INSN 0xF000
1433 #define CSKYV2_BR_INSN 0x0400
1434 unsigned int i;
1435 struct literal * p;
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};
1442 if (poolsize == 0)
1443 return;
1445 /* Must we branch around the literal table? */
1446 if (isforce)
1448 char brarname[8];
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))
1455 csky_insn.output
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);
1462 else
1464 csky_insn.output
1465 = frag_var (rs_machine_dependent,
1466 UNCD_DISP16_LEN,
1467 UNCD_DISP10_LEN,
1468 UNCD_DISP10,
1469 brarsym, 0, 0);
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. */
1475 if (do_pff)
1477 valueT br_self;
1478 csky_insn.output = frag_more (2);
1479 /* .Lxx: br .Lxx */
1480 if (IS_CSKY_V1 (mach_flag))
1481 br_self = CSKYV1_BR_INSN | 0x7ff;
1482 else
1483 br_self = CSKYV2_BR_INSN;
1484 md_number_to_chars (csky_insn.output, br_self, 2);
1485 if (!isforce)
1487 csky_insn.output = frag_more (2);
1488 /* .Lxx: br .Lxx */
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,
1497 (target_big_endian
1498 ? v1_nop_insn_big : v1_nop_insn_little),
1499 2, 0);
1500 else
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;
1512 if (p->isdouble)
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);
1521 else
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);
1529 else
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));
1545 poolsize = 0;
1548 static int
1549 enter_literal (expressionS *e,
1550 int ispcrel,
1551 unsigned char isdouble,
1552 uint64_t dbnum)
1554 unsigned int i;
1555 struct literal * p;
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
1563 to 2 entries. */
1565 /* Save the parsed symbol's reloc. */
1566 enum bfd_reloc_code_real last_reloc_before_dump = insn_reloc;
1567 dump_literals (1);
1568 insn_reloc = last_reloc_before_dump;
1571 if (poolsize == 0)
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);
1580 poolspan = 0;
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)
1598 p->refcnt ++;
1599 return i;
1602 p->refcnt = 1;
1603 p->ispcrel = ispcrel;
1604 p->e = *e;
1605 p->r_type = insn_reloc;
1606 p->isdouble = isdouble;
1607 if (isdouble)
1608 p->dbnum = dbnum;
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);
1619 return i;
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
1635 branch).
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. */
1647 static void
1648 check_literals (int kind, int offset)
1650 poolspan += offset;
1652 if ((poolspan > SPANEXIT || do_func_dump)
1653 && kind > 1
1654 && (do_br_dump || do_func_dump))
1655 dump_literals (0);
1656 else if (poolspan > SPANCLOSE && (kind > 0) && do_br_dump)
1657 dump_literals (0);
1658 else if (poolspan
1659 >= (SPANPANIC - (IS_CSKY_ARCH_V1 (mach_flag) ? poolsize * 2 : 0)))
1660 dump_literals (1);
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)
1665 poolspan -= offset;
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. */
1684 static char *
1685 lex_got (enum bfd_reloc_code_real *reloc,
1686 int *adjust)
1688 struct _gotrel
1690 const char *str;
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 }
1708 char *cp;
1709 unsigned int j;
1711 for (cp = input_line_pointer; *cp != '@'; cp++)
1712 if (is_end_of_line[(unsigned char) *cp])
1713 return NULL;
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;
1724 if (adjust)
1725 *adjust = len;
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);
1735 return NULL;
1739 /* Might be a symbol version string. Don't as_bad here. */
1740 return NULL;
1743 /* Parse an expression, returning it in E. */
1745 static char *
1746 parse_exp (char *s, expressionS *e)
1748 char *save;
1749 char *new;
1751 /* Skip whitespace. */
1752 while (ISSPACE (*s))
1753 ++s;
1755 save = input_line_pointer;
1756 input_line_pointer = s;
1758 insn_reloc = BFD_RELOC_NONE;
1759 expression (e);
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;
1768 return new;
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. */
1776 static char *
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. */
1781 char temp[8];
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;
1790 if (isdouble)
1791 err = md_atof ('d', temp, &length);
1792 else
1793 err = md_atof ('f', temp, &length);
1794 know (length <= 8);
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++;
1802 if (err)
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;
1814 e->X_unsigned = 1;
1815 e->X_md = 0x0;
1817 if (!isdouble)
1819 uint32_t fnum;
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));
1825 else
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; }
1831 else
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));
1839 *dbnum <<= 32;
1840 *dbnum |= (((temp[4] << 24) & 0xffffffff)
1841 | ((temp[5] << 16) & 0xffffff)
1842 | ((temp[6] << 8) & 0xffff)
1843 | (temp[7] & 0xff));
1845 else
1847 *dbnum = (((temp[7] << 24) & 0xffffffff)
1848 | ((temp[6] << 16) & 0xffffff)
1849 | ((temp[5] << 8) & 0xffff)
1850 | (temp[4] & 0xff));
1851 *dbnum <<= 32;
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;
1861 static char *
1862 parse_rt (char *s,
1863 int ispcrel,
1864 expressionS *ep,
1865 long reg ATTRIBUTE_UNUSED)
1867 expressionS e;
1868 int n;
1870 if (ep)
1871 /* Indicate nothing there. */
1872 ep->X_op = O_absent;
1874 if (*s == '[')
1876 s = parse_exp (s + 1, &e);
1878 if (*s == ']')
1879 s++;
1880 else
1881 SET_ERROR_NUMBER (ERROR_MISSING_RSQUARE_BRACKETS, NULL);
1883 if (ep)
1884 *ep = e;
1886 else
1888 s = parse_exp (s, &e);
1889 if (BFD_RELOC_CKCORE_DOFFSET_LO16 == insn_reloc
1890 || BFD_RELOC_CKCORE_TOFFSET_LO16 == insn_reloc)
1892 if (ep)
1893 *ep = e;
1894 return s;
1896 if (ep)
1897 *ep = e;
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);
1902 if (ep)
1903 *ep = e;
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;
1911 return s;
1914 static char *
1915 parse_rtf (char *s, int ispcrel, expressionS *ep)
1917 expressionS e;
1918 int n = 0;
1920 if (ep)
1921 /* Indicate nothing there. */
1922 ep->X_op = O_absent;
1924 if (*s == '[')
1926 s = parse_exp (s + 1, & e);
1928 if (*s == ']')
1929 s++;
1930 else
1931 as_bad (_("missing ']'"));
1933 if (ep)
1934 *ep = e;
1936 else
1938 uint64_t dbnum;
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);
1949 else
1950 as_bad (_("unrecognized opcode"));
1952 if (ep)
1953 *ep = e;
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;
1960 return s;
1963 static bfd_boolean
1964 parse_type_ctrlreg (char** oper)
1966 int i = -1;
1967 int len = 0;
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;
1977 *oper += len;
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];
1984 while (reg->name)
1986 if (memcmp (*oper, reg->name, strlen (reg->name)) == 0
1987 && (!reg->flag || (isa_flag & reg->flag)))
1989 i = reg->index;
1990 len = strlen (reg->name);
1991 *oper += len;
1992 break;
1994 reg++;
1998 if (IS_CSKY_V2 (mach_flag))
2000 char *s = *oper;
2001 int crx;
2002 int sel;
2003 if (i != -1)
2005 crx = i;
2006 sel = 0;
2008 else
2010 if (s[0] == 'c' && s[1] == 'r')
2012 s += 2;
2013 if (*s == '<')
2015 s++;
2016 if (s[0] == '3' && s[1] >= '0' && s[1] <= '1')
2018 crx = 30 + s[1] - '0';
2019 s += 2;
2021 else if (s[0] == '2' && s[1] >= '0' && s[1] <= '9')
2023 crx = 20 + s[1] - '0';
2024 s += 2;
2026 else if (s[0] == '1' && s[1] >= '0' && s[1] <= '9')
2028 crx = 10 + s[1] - '0';
2029 s += 2;
2031 else if (s[0] >= '0' && s[0] <= '9')
2033 crx = s[0] - '0';
2034 s += 1;
2036 else
2038 SET_ERROR_NUMBER (ERROR_REG_OVER_RANGE, "control");
2039 return FALSE;
2041 if (*s == ',')
2042 s++;
2043 else
2045 SET_ERROR_NUMBER (ERROR_CREG_ILLEGAL, NULL);
2046 return FALSE;
2048 char *pS = s;
2049 while (*pS != '>' && !is_end_of_line[(unsigned char) *pS])
2050 pS++;
2051 if (*pS == '>')
2052 *pS = '\0';
2053 else
2055 /* Error. Missing '>'. */
2056 SET_ERROR_NUMBER (ERROR_MISSING_RANGLE_BRACKETS, NULL);
2057 return FALSE;
2059 expressionS e;
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)
2065 *oper = s;
2066 sel = e.X_add_number;
2068 else
2069 return FALSE;
2071 else
2073 /* Error. Missing '<'. */
2074 SET_ERROR_NUMBER (ERROR_MISSING_LANGLE_BRACKETS, NULL);
2075 return FALSE;
2078 else
2080 SET_ERROR_NUMBER (ERROR_CREG_ILLEGAL, NULL);
2081 return FALSE;
2084 i = (sel << 5) | crx;
2086 csky_insn.val[csky_insn.idx++] = i;
2087 return TRUE;
2090 static bfd_boolean
2091 is_reg_sp_with_bracket (char **oper)
2093 const char **regs;
2094 int sp_idx;
2095 int len;
2097 if (IS_CSKY_V1 (mach_flag))
2098 sp_idx = 0;
2099 else
2100 sp_idx = 14;
2102 if (**oper != '(')
2103 return FALSE;
2104 *oper += 1;
2105 regs = csky_general_reg;
2106 len = strlen (regs[sp_idx]);
2107 if (memcmp (*oper, regs[sp_idx], len) == 0)
2109 *oper += len;
2110 if (**oper != ')')
2111 return FALSE;
2112 *oper += 1;
2113 csky_insn.val[csky_insn.idx++] = sp_idx;
2114 return TRUE;
2116 else
2118 if (IS_CSKY_V1 (mach_flag))
2119 regs = cskyv1_general_alias_reg;
2120 else
2121 regs = cskyv2_general_alias_reg;
2122 len = strlen (regs[sp_idx]);
2123 if (memcmp (*oper, regs[sp_idx], len) == 0)
2125 *oper += len;
2126 if (**oper != ')')
2127 return FALSE;
2128 *oper += 1;
2129 return TRUE;
2132 return FALSE;
2135 static bfd_boolean
2136 is_reg_sp (char **oper)
2138 const char **regs;
2139 int sp_idx;
2140 int len;
2141 if (IS_CSKY_V1 (mach_flag))
2142 sp_idx = 0;
2143 else
2144 sp_idx = 14;
2146 regs = csky_general_reg;
2147 len = strlen (regs[sp_idx]);
2148 if (memcmp (*oper, regs[sp_idx], len) == 0)
2150 *oper += len;
2151 csky_insn.val[csky_insn.idx++] = sp_idx;
2152 return TRUE;
2154 else
2156 if (IS_CSKY_V1 (mach_flag))
2157 regs = cskyv1_general_alias_reg;
2158 else
2159 regs = cskyv2_general_alias_reg;
2160 len = strlen (regs[sp_idx]);
2161 if (memcmp (*oper, regs[sp_idx], len) == 0)
2163 *oper += len;
2164 csky_insn.val[csky_insn.idx++] = sp_idx;
2165 return TRUE;
2168 return FALSE;
2171 static int
2172 csky_get_reg_val (char *str, int *len)
2174 long reg = 0;
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';
2180 *len = 3;
2182 else if (ISDIGIT (str[1]))
2184 reg = str[1] - '0';
2185 *len = 2;
2187 else
2188 return -1;
2190 else if (TOLOWER (str[0]) == 's' && TOLOWER (str[1]) == 'p'
2191 && !ISDIGIT (str[2]))
2193 /* sp. */
2194 if (IS_CSKY_V1 (mach_flag))
2195 reg = 0;
2196 else
2197 reg = 14;
2198 *len = 2;
2200 else if (TOLOWER (str[0]) == 'g' && TOLOWER (str[1]) == 'b'
2201 && !ISDIGIT (str[2]))
2203 /* gb. */
2204 if (IS_CSKY_V1 (mach_flag))
2205 reg = 14;
2206 else
2207 reg = 28;
2208 *len = 2;
2210 else if (TOLOWER (str[0]) == 'l' && TOLOWER (str[1]) == 'r'
2211 && !ISDIGIT (str[2]))
2213 /* lr. */
2214 reg = 15;
2215 *len = 2;
2217 else if (TOLOWER (str[0]) == 't' && TOLOWER (str[1]) == 'l'
2218 && TOLOWER (str[2]) == 's' && !ISDIGIT (str[3]))
2220 /* tls. */
2221 if (IS_CSKY_V2 (mach_flag))
2222 reg = 31;
2223 else
2224 return -1;
2225 *len = 3;
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))
2231 reg = 30;
2232 else
2233 return -1;
2234 *len = 4;
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)
2241 /* a0 - a5. */
2242 reg = 2 + str[1] - '0';
2243 else if (IS_CSKY_V2 (mach_flag) && (str[1] - '0') <= 3)
2244 /* a0 - a3. */
2245 reg = str[1] - '0';
2246 else
2247 return -1;
2248 *len = 2;
2251 else if (TOLOWER (str[0]) == 't')
2253 if (IS_CSKY_V2 (mach_flag))
2255 reg = atoi (str + 1);
2256 if (reg > 9)
2257 return -1;
2259 if (reg > 1)
2260 /* t2 - t9. */
2261 reg = reg + 16;
2262 else
2263 /* t0 - t1. */
2264 reg = reg + 12;
2265 *len = 2;
2268 else if (TOLOWER (str[0]) == 'l')
2270 if (str[1] < '0' || str[1] > '9')
2271 return -1;
2272 if (IS_CSKY_V2 (mach_flag))
2274 reg = atoi (str + 1);
2275 if (reg > 9)
2276 return -1;
2277 if (reg > 7)
2278 /* l8 - l9. */
2279 reg = reg + 8;
2280 else
2281 /* l0 - l7. */
2282 reg = reg + 4;
2284 else
2286 reg = atoi (str + 1);
2287 if (reg > 5)
2288 return -1;
2289 /* l0 - l6 -> r8 - r13. */
2290 reg = reg + 8;
2292 *len = 2;
2294 else
2295 return -1;
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);
2304 return -1;
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);
2313 return -1;
2316 else if (reg > 31 || reg < 0)
2318 SET_ERROR_NUMBER (ERROR_REG_OVER_RANGE, reg);
2319 return -1;
2322 return reg;
2325 static int
2326 csky_get_freg_val (char *str, int *len)
2328 int reg = 0;
2329 char *s = NULL;
2330 if ((str[0] == 'v' || str[0] == 'f') && (str[1] == 'r'))
2332 /* It is fpu register. */
2333 s = &str[2];
2334 while (ISDIGIT (*s))
2336 reg = reg * 10 + (*s) - '0';
2337 s++;
2339 if (reg > 31)
2340 return -1;
2342 else
2343 return -1;
2344 *len = s - str;
2345 return reg;
2348 static bfd_boolean
2349 is_reglist_legal (char **oper)
2351 int reg1 = -1;
2352 int reg2 = -1;
2353 int len = 0;
2354 reg1 = csky_get_reg_val (*oper, &len);
2355 *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");
2361 return FALSE;
2364 if (**oper != '-')
2366 SET_ERROR_NUMBER (ERROR_REG_FORMAT,
2367 "The operand format must be rx-ry");
2368 return FALSE;
2370 *oper += 1;
2372 reg2 = csky_get_reg_val (*oper, &len);
2373 *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");
2379 return FALSE;
2381 if (IS_CSKY_V2 (mach_flag))
2383 if (reg2 < reg1)
2385 SET_ERROR_NUMBER (ERROR_REG_FORMAT,
2386 "The operand format must be rx-ry (rx < ry)");
2387 return FALSE;
2389 reg2 = reg2 - reg1;
2390 reg1 <<= 5;
2391 reg1 |= reg2;
2393 csky_insn.val[csky_insn.idx++] = reg1;
2394 return TRUE;
2397 static bfd_boolean
2398 is_freglist_legal (char **oper)
2400 int reg1 = -1;
2401 int reg2 = -1;
2402 int len = 0;
2403 reg1 = csky_get_freg_val (*oper, &len);
2404 *oper += len;
2406 if (reg1 == -1)
2408 SET_ERROR_NUMBER (ERROR_REG_FORMAT,
2409 "The fpu register format is not recognized.");
2410 return FALSE;
2413 if (**oper != '-')
2415 SET_ERROR_NUMBER (ERROR_REG_FORMAT,
2416 "The operand format must be vrx-vry/frx-fry.");
2417 return FALSE;
2419 *oper += 1;
2421 reg2 = csky_get_freg_val (*oper, &len);
2422 *oper += len;
2424 if (reg2 == -1)
2426 SET_ERROR_NUMBER (ERROR_REG_FORMAT,
2427 "The fpu register format is not recognized.");
2428 return FALSE;
2430 if (reg2 < reg1)
2432 SET_ERROR_NUMBER (ERROR_REG_FORMAT,
2433 "The operand format must be rx-ry(rx < ry)");
2434 return FALSE;
2436 reg2 = reg2 - reg1;
2437 reg2 <<= 4;
2438 reg1 |= reg2;
2439 csky_insn.val[csky_insn.idx++] = reg1;
2440 return TRUE;
2443 static bfd_boolean
2444 is_reglist_dash_comma_legal (char **oper, struct operand *oprnd)
2446 int reg1 = -1;
2447 int reg2 = -1;
2448 int len = 0;
2449 int list = 0;
2450 int flag = 0;
2451 int temp = 0;
2452 while (**oper != '\n' && **oper != '\0')
2454 reg1 = csky_get_reg_val (*oper, &len);
2455 if (reg1 == -1)
2457 SET_ERROR_NUMBER (ERROR_REG_LIST, NULL);
2458 return FALSE;
2460 flag |= (1 << reg1);
2461 *oper += len;
2462 if (**oper == '-')
2464 *oper += 1;
2465 reg2 = csky_get_reg_val (*oper, &len);
2466 if (reg2 == -1)
2468 SET_ERROR_NUMBER (ERROR_REG_LIST, NULL);
2469 return FALSE;
2471 *oper += len;
2472 if (reg1 > reg2)
2474 SET_ERROR_NUMBER (ERROR_REG_LIST, NULL);
2475 return FALSE;
2477 while (reg2 >= reg1)
2479 flag |= (1 << reg2);
2480 reg2--;
2483 if (**oper == ',')
2484 *oper += 1;
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);
2491 return FALSE;
2493 /* Check r4-r11. */
2494 int i = 4;
2495 while (i <= 11)
2497 if (flag & (1 << i))
2498 temp = i - 4 + 1;
2499 i++;
2501 list |= temp;
2503 /* Check r15. */
2504 if (flag & (1 << 15))
2505 list |= (1 << 4);
2507 /* Check r16-r17. */
2508 i = 16;
2509 temp = 0;
2510 while (i <= 17)
2512 if (flag & (1 << i))
2513 temp = i - 16 + 1;
2514 i++;
2516 list |= (temp << 5);
2518 /* Check r28. */
2519 if (flag & (1 << 28))
2520 list |= (1 << 8);
2521 if (oprnd->mask == OPRND_MASK_0_4 && (list & ~OPRND_MASK_0_4))
2523 SET_ERROR_NUMBER (ERROR_REG_LIST, NULL);
2524 return FALSE;
2526 csky_insn.val[csky_insn.idx++] = list;
2527 return TRUE;
2530 static bfd_boolean
2531 is_reg_lshift_illegal (char **oper, int is_float)
2533 int value;
2534 int len;
2535 int reg;
2536 reg = csky_get_reg_val (*oper, &len);
2537 if (reg == -1)
2539 SET_ERROR_NUMBER (ERROR_REG_FORMAT, "The register must be r0-r31.");
2540 return FALSE;
2543 *oper += len;
2544 if ((*oper)[0] != '<' || (*oper)[1] != '<')
2546 SET_ERROR_NUMBER (ERROR_UNDEFINE,
2547 "Operand format error; should be (rx, ry << n)");
2548 return FALSE;
2550 *oper += 2;
2552 expressionS e;
2553 char *new_oper = parse_exp (*oper, &e);
2554 if (e.X_op == O_constant)
2556 *oper = new_oper;
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);
2561 return FALSE;
2564 else
2566 SET_ERROR_NUMBER (ERROR_EXP_CONSTANT, NULL);
2567 return FALSE;
2569 if (is_float)
2570 value = (reg << 2) | e.X_add_number;
2571 else
2572 value = (reg << 5) | (1 << e.X_add_number);
2573 csky_insn.val[csky_insn.idx++] = value;
2575 return TRUE;
2578 static bfd_boolean
2579 is_imm_over_range (char **oper, int min, int max, int ext)
2581 expressionS e;
2582 bfd_boolean ret = FALSE;
2583 char *new_oper = parse_exp (*oper, &e);
2584 if (e.X_op == O_constant)
2586 ret = TRUE;
2587 *oper = new_oper;
2588 if ((int)e.X_add_number != ext
2589 && (e.X_add_number < min || e.X_add_number > max))
2591 ret = FALSE;
2592 SET_ERROR_NUMBER (ERROR_IMM_OVERFLOW, NULL);
2594 csky_insn.val[csky_insn.idx++] = e.X_add_number;
2597 return ret;
2600 static bfd_boolean
2601 is_oimm_over_range (char **oper, int min, int max)
2603 expressionS e;
2604 bfd_boolean ret = FALSE;
2605 char *new_oper = parse_exp (*oper, &e);
2606 if (e.X_op == O_constant)
2608 ret = TRUE;
2609 *oper = new_oper;
2610 if (e.X_add_number < min || e.X_add_number > max)
2612 ret = FALSE;
2613 SET_ERROR_NUMBER (ERROR_IMM_OVERFLOW, NULL);
2615 csky_insn.val[csky_insn.idx++] = e.X_add_number - 1;
2618 return ret;
2621 static bfd_boolean
2622 is_psr_bit (char **oper)
2624 const struct psrbit *bits;
2625 int i = 0;
2627 if (IS_CSKY_V1 (mach_flag))
2628 bits = cskyv1_psr_bits;
2629 else
2630 bits = cskyv2_psr_bits;
2632 while (bits[i].name != NULL)
2634 if (bits[i].isa && !(bits[i].isa & isa_flag))
2636 i++;
2637 continue;
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;
2643 return TRUE;
2645 i++;
2647 SET_ERROR_NUMBER (ERROR_OPCODE_PSRBIT, NULL);
2648 return FALSE;
2651 static bfd_boolean
2652 parse_type_cpidx (char** oper)
2654 char *s = *oper;
2655 int idx;
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';
2661 *oper += 4;
2663 else if (ISDIGIT (s[2]) && !ISDIGIT (s[3]))
2665 idx = s[2] - '0';
2666 *oper += 3;
2668 else
2669 return FALSE;
2671 else
2673 expressionS e;
2674 *oper = parse_exp (*oper, &e);
2675 if (e.X_op != O_constant)
2677 /* Can not recognize the operand. */
2678 return FALSE;
2680 idx = e.X_add_number;
2683 csky_insn.val[csky_insn.idx++] = idx;
2685 return TRUE;
2688 static bfd_boolean
2689 parse_type_cpreg (char** oper)
2691 const char **regs = csky_cp_reg;
2692 int i;
2693 int len;
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)))
2700 *oper += len;
2701 csky_insn.val[csky_insn.idx++] = i;
2702 return TRUE;
2705 SET_ERROR_NUMBER (ERROR_CPREG_ILLEGAL, *oper);
2706 return FALSE;
2709 static bfd_boolean
2710 parse_type_cpcreg (char** oper)
2712 const char **regs;
2713 int i;
2714 int len;
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)))
2721 *oper += len;
2722 csky_insn.val[csky_insn.idx++] = i;
2723 return TRUE;
2726 SET_ERROR_NUMBER (ERROR_CPREG_ILLEGAL, *oper);
2727 return FALSE;
2730 static bfd_boolean
2731 parse_type_areg (char** oper)
2733 int i = 0;
2734 int len = 0;
2735 i = csky_get_reg_val (*oper, &len);
2736 if (i == -1)
2738 SET_ERROR_NUMBER (ERROR_GREG_ILLEGAL, NULL);
2739 return FALSE;
2741 *oper += len;
2742 csky_insn.val[csky_insn.idx++] = i;
2744 return TRUE;
2747 static bfd_boolean
2748 parse_type_freg (char** oper, int even)
2750 int reg;
2751 int len;
2752 reg = csky_get_freg_val (*oper, &len);
2753 if (reg == -1)
2755 SET_ERROR_NUMBER (ERROR_REG_FORMAT,
2756 "The fpu register format is not recognized.");
2757 return FALSE;
2759 *oper += len;
2760 csky_insn.opcode_end = *oper;
2761 if (even && reg & 0x1)
2763 SET_ERROR_NUMBER (ERROR_EXP_EVEN_FREG, NULL);
2764 return FALSE;
2766 csky_insn.val[csky_insn.idx++] = reg;
2767 return TRUE;
2770 static bfd_boolean
2771 parse_ldst_imm (char **oper, struct csky_opcode_info *op ATTRIBUTE_UNUSED,
2772 struct operand *oprnd)
2774 unsigned int mask = oprnd->mask;
2775 int max = 1;
2776 int shift = 0;
2778 shift = oprnd->shift;
2780 while (mask)
2782 if (mask & 1)
2783 max <<= 1;
2784 mask >>= 1;
2786 max = max << shift;
2788 if (**oper == '\0' || **oper == ')')
2790 csky_insn.val[csky_insn.idx++] = 0;
2791 return TRUE;
2794 expressionS e;
2795 *oper = parse_exp (*oper, &e);
2796 if (e.X_op != O_constant)
2797 /* Not a constant. */
2798 return FALSE;
2799 else if (e.X_add_number < 0 || e.X_add_number >= max)
2801 /* Out of range. */
2802 SET_ERROR_NUMBER (ERROR_IMM_OVERFLOW, NULL);
2803 return FALSE;
2805 if ((e.X_add_number % (1 << shift)) != 0)
2807 /* Not aligned. */
2808 SET_ERROR_NUMBER (ERROR_OFFSET_UNALIGNED, ((unsigned long)1 << shift));
2809 return FALSE;
2812 csky_insn.val[csky_insn.idx++] = e.X_add_number >> shift;
2814 return TRUE;
2818 static unsigned int
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])
2826 oprnd_num = 0;
2827 else
2828 oprnd_num = 1;
2830 /* Count how many operands. */
2831 if (oprnd_num)
2832 while (!is_end_of_line[(unsigned char) *oper_end])
2834 if (*oper_end == '(' || *oper_end == '<')
2836 bracket_cnt++;
2837 oper_end++;
2838 continue;
2840 if (*oper_end == ')' || *oper_end == '>')
2842 bracket_cnt--;
2843 oper_end++;
2844 continue;
2846 if (!bracket_cnt && *oper_end == ',')
2847 oprnd_num++;
2848 oper_end++;
2850 return oprnd_num;
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. */
2858 static bfd_boolean
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;
2867 char *opcode_end;
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))
2873 str++;
2874 opcode_end = 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)
2885 has_suffix = TRUE;
2886 if (IS_OPCODE32F (opcode_end))
2888 csky_insn.flag_force = INSN_OPCODE32F;
2889 nlen -= 2;
2891 else if (IS_OPCODE16F (opcode_end))
2893 csky_insn.flag_force = INSN_OPCODE16F;
2894 nlen -= 2;
2897 name[nlen] = *opcode_end;
2898 nlen++;
2899 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;
2908 nlen -= 2;
2910 else if (IS_OPCODE16F (opcode_end))
2912 csky_insn.flag_force = INSN_OPCODE16F;
2913 nlen -= 2;
2916 name[nlen] = '\0';
2918 /* Generate macro_name for finding hash in macro hash_table. */
2919 if (has_suffix == TRUE)
2920 nlen += 2;
2921 strncpy (macro_name, str, nlen);
2922 macro_name[nlen] = '\0';
2924 /* Get csky_insn.opcode_end. */
2925 while (ISSPACE (*opcode_end))
2926 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,
2934 macro_name);
2935 csky_insn.opcode = (struct csky_opcode *) hash_find (csky_opcodes_hash,
2936 name);
2938 if (csky_insn.macro == NULL && csky_insn.opcode == NULL)
2939 return FALSE;
2940 return TRUE;
2943 /* Main dispatch routine to parse operand OPRND for opcode OP from string
2944 *OPER. */
2946 static bfd_boolean
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:
2954 (oprnd1, oprnd2)
2956 <oprnd1, oprnd2>
2957 We will check the format here. */
2958 soprnd = (struct soperand *) oprnd;
2959 char lc = 0;
2960 char rc = 0;
2961 char *s = *oper;
2962 int bracket_cnt = 0;
2963 if (oprnd->type == OPRND_TYPE_BRACKET)
2965 lc = '(';
2966 rc = ')';
2968 else if (oprnd->type == OPRND_TYPE_ABRACKET)
2970 lc = '<';
2971 rc = '>';
2974 if (**oper == lc)
2976 *oper += 1;
2977 s += 1;
2979 else
2981 SET_ERROR_NUMBER ((oprnd->type == OPRND_TYPE_BRACKET
2982 ? ERROR_MISSING_LBRACKET
2983 : ERROR_MISSING_LANGLE_BRACKETS), NULL);
2984 return FALSE;
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'))
2991 if (*s == lc)
2992 bracket_cnt++;
2993 else if (*s == rc)
2994 bracket_cnt--;
2995 s++;
2998 if (*s == rc)
2999 *s = '\0';
3000 else
3002 SET_ERROR_NUMBER ((oprnd->type == OPRND_TYPE_BRACKET
3003 ? ERROR_MISSING_RBRACKET
3004 : ERROR_MISSING_RANGLE_BRACKETS), NULL);
3005 return FALSE;
3008 if (get_operand_value (op, oper, &soprnd->subs[0]) == FALSE)
3010 *s = rc;
3011 return FALSE;
3013 if (**oper == ',')
3014 *oper += 1;
3015 if (get_operand_value (op, oper, &soprnd->subs[1]) == FALSE)
3017 *s = rc;
3018 return FALSE;
3021 *s = rc;
3022 *oper += 1;
3023 return TRUE;
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
3031 handled here. */
3032 case OPRND_TYPE_CTRLREG:
3033 /* some parse. */
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:
3051 int len;
3052 long reg;
3053 reg = csky_get_reg_val (*oper, &len);
3055 if (reg == -1)
3057 SET_ERROR_NUMBER (ERROR_GREG_ILLEGAL, NULL);
3058 return FALSE;
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);
3064 return FALSE;
3066 *oper += len;
3067 csky_insn.val[csky_insn.idx++] = reg;
3068 return TRUE;
3070 case OPRND_TYPE_REGnsplr:
3072 int len;
3073 long reg;
3074 reg = csky_get_reg_val (*oper, &len);
3076 if (reg == -1
3077 || (IS_CSKY_V1 (mach_flag)
3078 && (reg == V1_REG_SP || reg == V1_REG_LR)))
3080 SET_ERROR_NUMBER (ERROR_REG_OVER_RANGE, reg);
3081 return FALSE;
3083 csky_insn.val[csky_insn.idx++] = reg;
3084 *oper += len;
3085 return TRUE;;
3087 case OPRND_TYPE_REGnr4_r7:
3089 int len;
3090 int reg;
3091 if (**oper == '(')
3092 *oper += 1;
3093 reg = csky_get_reg_val (*oper, &len);
3094 if (reg == -1 || (reg <= 7 && reg >= 4))
3095 return FALSE;
3097 csky_insn.val[csky_insn.idx++] = reg;
3098 *oper += len;
3100 if (**oper == ')')
3101 *oper += 1;
3102 return TRUE;;
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;
3109 return TRUE;
3111 SET_ERROR_NUMBER (ERROR_OPCODE_ILLEGAL, NULL);
3112 return FALSE;
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);
3127 return FALSE;
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);
3136 return FALSE;
3138 csky_insn.val[csky_insn.idx++]
3139 = (csky_insn.e1.X_add_number >> 3) - 2;
3141 return TRUE;
3142 case OPRND_TYPE_IMM4b:
3143 return is_imm_over_range (oper, 0, 15, -1);
3144 break;
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. */
3153 if (val <= 6)
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;
3160 return TRUE;
3162 else
3163 return FALSE;
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))
3170 int log;
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);
3176 else
3177 return FALSE;
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))
3183 int log;
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. */
3187 if (log <= 6)
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"));
3194 else
3195 csky_insn.val[csky_insn.idx - 1] = log;
3196 return (log == -1 ? FALSE : TRUE);
3198 else
3199 return FALSE;
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];
3209 return TRUE;
3211 else
3212 return FALSE;
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)
3227 return FALSE;
3228 csky_insn.val[csky_insn.idx - 1] = (1 << mask_val) - 1;
3229 return TRUE;
3232 return TRUE;
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;
3240 return TRUE;
3242 return FALSE;
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];
3252 if (imm < 4)
3254 csky_show_error (WARNING_IDLY, 0, (void *)imm, NULL);
3255 imm = 3;
3257 else imm--;
3258 csky_insn.val[csky_insn.idx - 1] = imm;
3259 return TRUE;
3261 else
3262 return FALSE;
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)
3270 return TRUE;
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)
3277 return FALSE;
3278 csky_insn.val[csky_insn.idx - 1] = (1 << (mask_val + 1)) - 1;
3279 return TRUE;
3282 return TRUE;
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:
3297 expressionS e;
3298 char *new_oper = parse_exp (*oper, &e);
3299 if (e.X_op == O_constant)
3301 *oper = new_oper;
3302 csky_insn.val[csky_insn.idx++] = e.X_add_number;
3303 return TRUE;
3305 return FALSE;
3307 case OPRND_TYPE_IMM16b_MOVIH:
3308 case OPRND_TYPE_IMM16b_ORI:
3310 bfd_reloc_code_real_type r = BFD_RELOC_NONE;
3311 int len;
3312 char *curr = *oper;
3313 char * save = input_line_pointer;
3314 /* get the reloc type, and set "@GOTxxx" as ' ' */
3315 while (**oper != '@' && **oper != '\0')
3316 *oper += 1;
3317 if (**oper != '\0')
3319 input_line_pointer = *oper;
3320 lex_got (&r, &len);
3321 while (*(*oper + len + 1) != '\0')
3323 **oper = *(*oper + len + 1);
3324 *(*oper + len + 1) = '\0';
3325 *oper += 1;
3327 **oper = '\0';
3329 input_line_pointer = save;
3330 *oper = parse_exp (curr, &csky_insn.e1);
3331 return TRUE;
3333 case OPRND_TYPE_PSR_BITS_LIST:
3335 int ret = TRUE;
3336 if (csky_insn.number == 0)
3337 ret = FALSE;
3338 else
3340 csky_insn.val[csky_insn.idx] = 0;
3341 if (is_psr_bit (oper) != FALSE)
3342 while (**oper == ',')
3344 *oper += 1;
3345 if (is_psr_bit (oper) == FALSE)
3347 ret = FALSE;
3348 break;
3351 else
3352 ret = FALSE;
3353 if (ret == TRUE && IS_CSKY_V1 (mach_flag)
3354 && csky_insn.val[csky_insn.idx] > 8)
3355 ret = FALSE;
3357 if (!ret)
3358 SET_ERROR_NUMBER (ERROR_OPERANDS_ILLEGAL, csky_insn.opcode_end);
3359 return ret;
3361 case OPRND_TYPE_RM:
3363 /* FPU round mode. */
3364 static const char *round_mode[] =
3366 "rm_nearest",
3367 "rm_zero",
3368 "rm_posinf",
3369 "rm_neginf",
3370 NULL
3372 int i;
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;
3378 return TRUE;
3380 return FALSE;
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:
3394 int len;
3395 int reg;
3396 if (**oper != '(')
3398 SET_ERROR_NUMBER (ERROR_MISSING_LBRACKET, NULL);
3399 return FALSE;
3401 *oper += 1;
3402 reg = csky_get_reg_val (*oper, &len);
3403 if (reg == -1)
3405 SET_ERROR_NUMBER (ERROR_EXP_GREG, NULL);
3406 return FALSE;
3408 *oper += len;
3409 if (**oper != ')')
3411 SET_ERROR_NUMBER (ERROR_MISSING_RBRACKET, NULL);
3412 return FALSE;
3414 *oper += 1;
3415 csky_insn.val[csky_insn.idx++] = reg;
3416 return TRUE;
3418 case OPRND_TYPE_REGsp:
3419 return is_reg_sp (oper);
3420 case OPRND_TYPE_REGbsp:
3421 return is_reg_sp_with_bracket (oper);
3422 /* For jmpi. */
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;
3427 return TRUE;
3428 case OPRND_TYPE_LABEL_WITH_BRACKET:
3429 case OPRND_TYPE_CONSTANT:
3430 case OPRND_TYPE_ELRW_CONSTANT:
3431 if (**oper == '[')
3432 csky_insn.val[csky_insn.idx++] = 0;
3433 else
3434 csky_insn.val[csky_insn.idx++] = NEED_OUTPUT_LITERAL;
3435 *oper = parse_rt (*oper, 0, &csky_insn.e1, -1);
3436 return TRUE;
3437 case OPRND_TYPE_FCONSTANT:
3438 *oper = parse_rtf (*oper, 0, &csky_insn.e1);
3439 return TRUE;
3441 case OPRND_TYPE_SFLOAT:
3442 case OPRND_TYPE_DFLOAT:
3443 /* For fmovis and fmovid, which accept a constant float with
3444 a limited range. */
3446 uint64_t dbnum;
3447 int imm4, imm8;
3449 *oper = parse_fexp (*oper, &csky_insn.e1, 1, &dbnum);
3450 if (csky_insn.e1.X_op == O_absent)
3451 return FALSE;
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);
3460 return FALSE;
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));
3468 return TRUE;
3471 /* For grs v2. */
3472 case OPRND_TYPE_IMM_OFF18b:
3473 *oper = parse_exp (*oper, &csky_insn.e1);
3474 return TRUE;
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;
3481 return TRUE;
3483 else
3484 return FALSE;
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;
3495 return TRUE;
3497 else
3498 return FALSE;
3499 /* For xtrb0(1)(2)(3) and div in csky v1 ISA. */
3500 case OPRND_TYPE_REG_r1a:
3502 int reg = 0;
3503 int len = 0;
3504 reg = csky_get_reg_val (*oper, &len);
3505 if (reg == -1)
3507 SET_ERROR_NUMBER (ERROR_REG_FORMAT,
3508 "The first operand must be register r1.");
3509 return FALSE;
3511 if (reg != 1)
3512 mov_r1_after = TRUE;
3513 *oper += len;
3514 csky_insn.opcode_end = *oper;
3515 csky_insn.val[csky_insn.idx++] = reg;
3516 return TRUE;
3518 case OPRND_TYPE_REG_r1b:
3520 int reg = 0;
3521 int len = 0;
3522 reg = csky_get_reg_val (*oper, &len);
3523 if (reg == -1)
3525 SET_ERROR_NUMBER (ERROR_REG_FORMAT,
3526 "The second operand must be register r1.");
3527 return FALSE;
3529 if (reg != 1)
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);
3538 *oper += len;
3539 csky_insn.opcode_end = *oper;
3540 csky_insn.val[csky_insn.idx++] = reg;
3541 return TRUE;
3543 case OPRND_TYPE_DUMMY_REG:
3545 int reg = 0;
3546 int len = 0;
3547 reg = csky_get_reg_val (*oper, &len);
3548 if (reg == -1)
3550 SET_ERROR_NUMBER (ERROR_GREG_ILLEGAL, NULL);
3551 return FALSE;
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.");
3557 return FALSE;
3559 *oper += len;
3560 csky_insn.opcode_end = *oper;
3561 csky_insn.val[csky_insn.idx++] = reg;
3562 return TRUE;
3564 case OPRND_TYPE_2IN1_DUMMY:
3566 int reg = 0;
3567 int len = 0;
3568 int max = 0;
3569 int min = 0;
3570 reg = csky_get_reg_val (*oper, &len);
3571 if (reg == -1)
3573 SET_ERROR_NUMBER (ERROR_GREG_ILLEGAL, NULL);
3574 return FALSE;
3576 /* dummy reg's real type should be same with first operand. */
3577 if (op->oprnd.oprnds[0].type == OPRND_TYPE_GREG0_15)
3578 max = 15;
3579 else if (op->oprnd.oprnds[0].type == OPRND_TYPE_GREG0_7)
3580 max = 7;
3581 else
3582 return FALSE;
3583 if (reg < min || reg > max)
3584 return FALSE;
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;
3595 else
3596 return FALSE;
3598 *oper += len;
3599 csky_insn.opcode_end = *oper;
3600 return TRUE;
3602 case OPRND_TYPE_DUP_GREG0_7:
3603 case OPRND_TYPE_DUP_GREG0_15:
3604 case OPRND_TYPE_DUP_AREG:
3606 long reg = 0;
3607 int len = 0;
3608 long max_reg;
3609 unsigned int shift_num;
3610 if (oprnd->type == OPRND_TYPE_DUP_GREG0_7)
3612 max_reg = 7;
3613 shift_num = 3;
3615 else if (oprnd->type == OPRND_TYPE_DUP_GREG0_15)
3617 max_reg = 15;
3618 shift_num = 4;
3620 else
3622 max_reg = 31;
3623 shift_num = 5;
3625 reg = csky_get_reg_val (*oper, &len);
3626 if (reg == -1)
3628 if (max_reg == 31)
3629 SET_ERROR_NUMBER (ERROR_REG_FORMAT,
3630 "The register must be r0-r31");
3631 else
3632 SET_ERROR_NUMBER (ERROR_REG_FORMAT,
3633 "The register must be r0-r15");
3634 return FALSE;
3636 if (reg > max_reg)
3638 SET_ERROR_NUMBER (ERROR_REG_OVER_RANGE, reg);
3639 return FALSE;
3641 reg |= reg << shift_num;
3642 *oper += len;
3643 csky_insn.opcode_end = *oper;
3644 csky_insn.val[csky_insn.idx++] = reg;
3645 return TRUE;
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)
3653 return FALSE;
3654 csky_insn.val[csky_insn.idx++] = 1;
3655 return TRUE;
3657 return FALSE;
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)
3662 return FALSE;
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;
3669 return TRUE;
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)
3674 return FALSE;
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;
3685 else
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;
3692 return TRUE;
3693 case OPRND_TYPE_JCOMPZ:
3694 *oper = parse_exp (*oper, &csky_insn.e1);
3695 if (csky_insn.e1.X_op == O_constant)
3696 return FALSE;
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;
3704 return TRUE;
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;
3714 return TRUE;
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;
3724 return TRUE;
3725 case OPRND_TYPE_JBSR:
3726 if (do_force2bsr)
3727 *oper = parse_exp (*oper, &csky_insn.e1);
3728 else
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;
3733 return TRUE;
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:
3740 expressionS e;
3741 char *new_oper = parse_exp (*oper, &e);
3742 if (e.X_op == O_constant)
3744 *oper = new_oper;
3745 if (e.X_add_number > 31)
3747 SET_ERROR_NUMBER (ERROR_IMM_OVERFLOW, NULL);
3748 return FALSE;
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);
3756 return FALSE;
3758 csky_insn.val[csky_insn.idx - 2] -= e.X_add_number;
3760 return TRUE;
3762 return FALSE;
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))
3771 if (**oper == '[')
3773 (*oper)++;
3774 if (is_imm_over_range (oper, 0, 0xf, -1))
3776 if (**oper == ']')
3778 unsigned int idx = --csky_insn.idx;
3779 unsigned int val = csky_insn.val[idx];
3780 (*oper)++;
3781 csky_insn.val[idx - 1] |= val << 4;
3782 return TRUE;
3784 else
3785 SET_ERROR_NUMBER (ERROR_MISSING_RSQUARE_BRACKETS, NULL);
3788 else
3789 SET_ERROR_NUMBER (ERROR_MISSING_LSQUARE_BRACKETS, NULL);
3791 return FALSE;
3793 default:
3794 break;
3795 /* error code. */
3797 return FALSE;
3800 /* Subroutine of parse_operands. */
3802 static bfd_boolean
3803 parse_operands_op (char *str, struct csky_opcode_info *op)
3805 int i;
3806 int j;
3807 char *oper = str;
3808 int flag_pass;
3810 for (i = 0; i < OP_TABLE_NUM && op[i].operand_num != -2; i++)
3812 flag_pass = TRUE;
3813 csky_insn.idx = 0;
3814 oper = str;
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);
3821 flag_pass = FALSE;
3822 continue;
3825 for (j = 0; j < csky_insn.number; j++)
3827 while (ISSPACE (*oper))
3828 oper++;
3829 flag_pass = get_operand_value (&op[i], &oper,
3830 &op[i].oprnd.oprnds[j]);
3831 if (flag_pass == FALSE)
3832 break;
3833 while (ISSPACE (*oper))
3834 oper++;
3835 /* Skip the ','. */
3836 if (j < csky_insn.number - 1 && op[i].operand_num != -1)
3838 if (*oper == ',')
3839 oper++;
3840 else
3842 SET_ERROR_NUMBER (ERROR_MISSING_COMMA, NULL);
3843 flag_pass = FALSE;
3844 break;
3847 else if (!is_end_of_line[(unsigned char) *oper])
3849 SET_ERROR_NUMBER (ERROR_BAD_END, NULL);
3850 flag_pass = FALSE;
3851 break;
3853 else
3854 break;
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;
3862 return TRUE;
3864 else
3865 error_state.opnum = j + 1;
3867 /* Parse operands in ALL tables end. */
3868 return FALSE;
3871 /* Parse the operands according to operand type. */
3873 static bfd_boolean
3874 parse_operands (char *str)
3876 char *oper = 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;
3885 return TRUE;
3887 return FALSE;
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;
3895 return TRUE;
3897 return FALSE;
3899 else
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;
3905 return TRUE;
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;
3911 return TRUE;
3913 return FALSE;
3917 static bfd_boolean
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);
3957 else
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);
3979 return TRUE;
3982 /* Return the bits of VAL shifted according to MASK. The bits of MASK
3983 need not be contiguous. */
3985 static int
3986 generate_masked_value (int mask, int val)
3988 int ret = 0;
3989 int bit;
3991 for (bit = 1; mask; bit = bit << 1)
3992 if (mask & bit)
3994 if (val & 0x1)
3995 ret |= bit;
3996 val = val >> 1;
3997 mask &= ~bit;
3999 return ret;
4002 /* Return the result of masking operand number OPRND_IDX into the
4003 instruction word according to the information in OPRND. */
4005 static int
4006 generate_masked_operand (struct operand *oprnd, int *oprnd_idx)
4008 struct soperand *soprnd = NULL;
4009 int mask;
4010 int val;
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);
4016 return 0;
4018 mask = oprnd->mask;
4019 val = csky_insn.val[*oprnd_idx];
4020 (*oprnd_idx)++;
4021 val = generate_masked_value (mask, val);
4022 csky_insn.inst |= val;
4024 return 0;
4027 static bfd_boolean
4028 csky_generate_insn (void)
4030 int i = 0;
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];
4038 int sidx = 0;
4039 csky_insn.inst = opinfo->opcode;
4040 if (opinfo->operand_num == -1)
4042 generate_masked_operand (&opinfo->oprnd.oprnds[i], &sidx);
4043 return 0;
4045 else
4046 for (i = 0; i < opinfo->operand_num; i++)
4047 generate_masked_operand (&opinfo->oprnd.oprnds[i], &sidx);
4048 return 0;
4051 /* Main entry point for assembling a single instruction. */
4053 void
4054 md_assemble (char *str)
4056 bfd_boolean must_check_literals = TRUE;
4057 csky_insn.isize = 0;
4058 csky_insn.idx = 0;
4059 csky_insn.max = 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))
4073 str++;
4074 /* Get opcode from str. */
4075 if (parse_opcode (str) == FALSE)
4077 csky_show_error (ERROR_OPCODE_ILLEGAL, 0, NULL, NULL);
4078 return;
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 ();
4087 return;
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);
4098 return;
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);
4106 return;
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 ();
4112 else
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);
4141 else
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)
4153 switch (c)
4155 case 0:
4156 break;
4157 case OPTION_MARCH:
4158 parse_arch (arg);
4159 break;
4160 case OPTION_MCPU:
4161 parse_cpu (arg);
4162 break;
4163 default:
4164 return 0;
4166 return 1;
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) \
4174 do { \
4175 if (total_length > 0) \
4177 csky_write_insn (buf, \
4178 opcode | (operand & ((1 << operand_length) - 1)), \
4179 total_length); \
4180 buf += total_length; \
4181 fragp->fr_fix += total_length; \
4183 } while (0)
4185 #define make_literal(fragp, literal_offset) \
4186 do { \
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); \
4192 } while (0)
4194 void
4195 md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT asec, fragS *fragp)
4197 offsetT disp;
4198 char *buf = fragp->fr_fix + fragp->fr_literal;
4200 gas_assert (fragp->fr_symbol);
4201 if (IS_EXTERNAL_SYM (fragp->fr_symbol, asec))
4202 disp = 0;
4203 else
4204 disp = (S_GET_VALUE (fragp->fr_symbol)
4205 + fragp->fr_offset
4206 - fragp->fr_address
4207 - fragp->fr_fix);
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
4218 unsigned char t0;
4219 disp -= 2;
4220 if (disp & 1)
4222 /* Error. odd displacement at %x, next_inst-2. */
4225 disp >>= 1;
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;
4233 else
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;
4239 fragp->fr_fix += 2;
4240 break;
4242 case C (COND_JUMP, DISP32):
4243 case C (COND_JUMP, UNDEF_WORD_DISP):
4245 /* A conditional branch wont fit into 12 bits:
4246 b!cond 1f
4247 jmpi 0f
4248 .align 2
4249 0: .long disp
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. */
4258 buf[1] ^= 0x08;
4259 /* jmpi instruction. */
4260 buf[2] = CSKYV1_INST_JMPI & 0xff;
4261 buf[3] = CSKYV1_INST_JMPI >> 8;
4263 else
4265 /* b!cond instruction. */
4266 buf[0] ^= 0x08;
4267 /* jmpi instruction. */
4268 buf[2] = CSKYV1_INST_JMPI >> 8;
4269 buf[3] = CSKYV1_INST_JMPI & 0xff;
4272 if (is_unaligned)
4274 if (!target_big_endian)
4276 /* bt/bf: jump to pc + 2 + (4 << 1). */
4277 buf[0] = 4;
4278 /* jmpi: jump to MEM (pc + 2 + (1 << 2)). */
4279 buf[2] = 1;
4281 else
4283 /* bt/bf: jump to pc + 2 + (4 << 1). */
4284 buf[1] = 4;
4285 /* jmpi: jump to MEM (pc + 2 + (1 << 2)). */
4286 buf[3] = 1;
4288 /* Aligned 4 bytes. */
4289 buf[4] = 0;
4290 buf[5] = 0;
4291 /* .long */
4292 buf[6] = 0;
4293 buf[7] = 0;
4294 buf[8] = 0;
4295 buf[9] = 0;
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;
4302 else
4304 if (!target_big_endian)
4306 /* bt/bf: jump to pc + 2 + (3 << 1). */
4307 buf[0] = 3;
4308 /* jmpi: jump to MEM (pc + 2 + (0 << 2)). */
4309 buf[2] = 0;
4311 else
4313 /* bt/bf: jump to pc + 2 + (3 << 1). */
4314 buf[1] = 3;
4315 /* jmpi: jump to MEM (pc + 2 + (0 << 2)). */
4316 buf[3] = 0;
4318 /* .long */
4319 buf[4] = 0;
4320 buf[5] = 0;
4321 buf[6] = 0;
4322 buf[7] = 0;
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
4333 filled in. */
4334 if (!target_big_endian)
4335 buf[0] = 4;
4336 else
4337 buf[1] = 4;
4340 break;
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))
4347 /* b!cond 1f
4348 subi sp, 8
4349 stw r15, (sp, 0)
4350 bsr .L0
4351 .L0:
4352 lrw r1, 0f
4353 add r1, r15
4354 addi sp, 8
4355 jmp r1
4356 .align 2
4357 0: .long (tar_addr - pc)
4360 int first_inst = fragp->fr_fix + fragp->fr_address;
4361 int is_unaligned = (first_inst & 3);
4362 disp -= 8;
4363 /* Toggle T/F bit. */
4364 if (! target_big_endian)
4365 buf[1] ^= 0x08;
4366 else
4367 buf[0] ^= 0x08;
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);
4385 if (!is_unaligned)
4387 if (!target_big_endian)
4389 buf[0] = 11;
4390 buf[8] = 3;
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. */
4398 buf[1] = 11;
4399 buf[9] = 3;
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. */
4406 buf[19] = 0;
4407 fragp->fr_fix += C32_LEN_PIC;
4409 else /* if !is_unaligned. */
4411 if (!target_big_endian)
4413 buf[0] = 11;
4414 buf[8] = 2;
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. */
4422 buf[1] = 11;
4423 buf[9] = 2;
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. */
4430 buf[23] = 0;
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). */
4435 break;
4436 case C (UNCD_JUMP, DISP32):
4437 case C (UNCD_JUMP, UNDEF_WORD_DISP):
4439 /* jmpi 0f
4440 .align 2
4441 0: .long disp. */
4442 int first_inst = fragp->fr_fix + fragp->fr_address;
4443 int is_unaligned = (first_inst & 3);
4444 /* Build jmpi. */
4445 buf[0] = BYTE_0 (CSKYV1_INST_JMPI);
4446 buf[1] = BYTE_1 (CSKYV1_INST_JMPI);
4447 if (!is_unaligned)
4449 if (!target_big_endian)
4450 buf[0] = 1;
4451 else
4452 buf[1] = 1;
4453 /* Alignment. */
4454 buf[2] = 0;
4455 buf[3] = 0;
4456 /* .long */
4457 buf[4] = 0;
4458 buf[5] = 0;
4459 buf[6] = 0;
4460 buf[7] = 0;
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)
4468 buf[0] = 0;
4469 else
4470 buf[1] = 0;
4471 /* .long */
4472 buf[2] = 0;
4473 buf[3] = 0;
4474 buf[4] = 0;
4475 buf[5] = 0;
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;
4482 break;
4483 case C (UNCD_JUMP_PIC, DISP32):
4484 case C (UNCD_JUMP_PIC, UNDEF_WORD_DISP):
4486 /* subi sp, 8
4487 stw r15, (sp)
4488 bsr .L0
4489 .L0:
4490 lrw r1, 0f
4491 add r1, r15
4492 ldw r15, (sp)
4493 addi sp, 8
4494 jmp r1
4495 .align 2
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);
4503 disp -= 6;
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);
4522 if (is_unaligned)
4524 if (!target_big_endian)
4526 buf[6] = 3;
4527 buf[18] = disp & 0xff;
4528 buf[19] = (disp >> 8) & 0xff;
4529 buf[20] = (disp >> 16) & 0xff;
4530 buf[21] = (disp >> 24) & 0xff;
4532 else
4534 buf[7] = 3;
4535 buf[18] = (disp >> 24) & 0xff;
4536 buf[19] = (disp >> 16) & 0xff;
4537 buf[20] = (disp >> 8) & 0xff;
4538 buf[21] = disp & 0xff;
4540 buf[16] = 0;
4541 buf[17] = 0;
4542 fragp->fr_fix += U32_LEN_PIC;
4544 else
4546 if (!target_big_endian)
4548 buf[6] = 2;
4549 buf[16] = disp & 0xff;
4550 buf[17] = (disp >> 8) & 0xff;
4551 buf[18] = (disp >> 16) & 0xff;
4552 buf[19] = (disp >> 24) & 0xff;
4554 else
4556 buf[7] = 2;
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;
4565 break;
4566 case COND_DISP10:
4567 case SCOND_DISP10:
4568 case UNCD_DISP10:
4569 case JCOND_DISP10:
4570 case JUNCD_DISP10:
4572 unsigned int inst = csky_read_insn (buf, 2);
4573 inst |= (disp >> 1) & ((1 << 10) - 1);
4574 csky_write_insn (buf, inst, 2);
4575 fragp->fr_fix += 2;
4576 break;
4578 case SCOND_DISP16:
4580 unsigned int inst = csky_read_insn (buf, 2);
4582 if (inst == CSKYV2_INST_BT16)
4583 inst = CSKYV2_INST_BF16;
4584 else
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);
4591 disp -= 2;
4592 inst = CSKYV2_INST_BR32 | ((disp >> 1) & ((1 << 16) - 1));
4593 csky_write_insn (buf, inst, 4);
4594 fragp->fr_fix += 4;
4595 break;
4597 case COND_DISP16:
4598 case JCOND_DISP16:
4600 unsigned int inst = csky_read_insn (buf, 2);
4602 if (inst == CSKYV2_INST_BT16)
4603 inst = CSKYV2_INST_BT32;
4604 else
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);
4612 fragp->fr_fix += 4;
4613 break;
4615 case LRW_DISP7:
4617 unsigned int inst = csky_read_insn (buf, 2);
4618 int imm;
4619 imm = (disp + 2) >> 2;
4620 inst |= (imm >> 5) << 8;
4621 make_insn (2, inst, (imm & 0x1f), 5);
4622 break;
4624 case LRW2_DISP8:
4626 unsigned int inst = csky_read_insn (buf, 2);
4627 int imm = (disp + 2) >> 2;
4628 if (imm >= 0x80)
4630 inst &= 0xe0;
4631 inst |= (~((imm >> 5) << 8)) & 0x300;
4632 make_insn (2, inst, (~imm & 0x1f), 5);
4634 else
4636 inst |= (imm >> 5) << 8;
4637 make_insn (2, inst, (imm & 0x1f), 5);
4639 break;
4641 case LRW_DISP16:
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);
4650 break;
4652 case JCOMPZ_DISP16:
4654 unsigned int inst = csky_read_insn (buf, 4);
4655 make_insn (4, inst, disp >> 1, 16);
4657 break;
4658 case JCOMPZ_DISP32:
4660 unsigned int inst = csky_read_insn (buf, 4);
4661 int literal_offset;
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
4665 ? 0 : 2);
4666 make_insn (4, CSKYV2_INST_JMPI32, (4 + literal_offset + 2) >> 2, 10);
4667 make_literal (fragp, literal_offset);
4669 break;
4670 case JUNCD_DISP16:
4671 case UNCD_DISP16:
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);
4679 break;
4680 case JCOND_DISP32:
4682 /* 'jbt'/'jbf'-> <bf16/bt16>; jmpi32; [pad16]+literal32 */
4683 unsigned int inst = csky_read_insn (buf, 2);
4684 int literal_offset;
4686 if (inst == CSKYV2_INST_BT16)
4687 inst = CSKYV2_INST_BF16;
4688 else
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
4692 ? 0 : 2);
4693 make_insn (4, CSKYV2_INST_JMPI32, (4 + literal_offset + 2) >> 2, 10);
4694 make_literal (fragp, literal_offset);
4695 break;
4697 case JUNCD_DISP32:
4699 int literal_offset;
4700 literal_offset = ((fragp->fr_address + fragp->fr_fix) % 4 == 0
4701 ? 0 : 2);
4702 make_insn (4, CSKYV2_INST_JMPI32, (4 + literal_offset + 2) >> 2, 10);
4703 make_literal (fragp, literal_offset);
4705 break;
4706 case RELAX_OVERFLOW:
4707 csky_branch_report_error (fragp->fr_file, fragp->fr_line,
4708 fragp->fr_symbol, disp);
4709 break;
4710 default:
4711 abort ();
4712 break;
4716 /* Round up a section size to the appropriate boundary. */
4718 valueT
4719 md_section_align (segT segment ATTRIBUTE_UNUSED,
4720 valueT size)
4722 return size;
4725 /* MD interface: Symbol and relocation handling. */
4727 void md_csky_end (void)
4729 dump_literals (0);
4732 /* Return the address within the segment that a PC-relative fixup is
4733 relative to. */
4735 long
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. */
4752 void
4753 csky_cons_fix_new (fragS *frag,
4754 unsigned int off,
4755 unsigned int len,
4756 expressionS *exp,
4757 bfd_reloc_code_real_type reloc)
4759 fixS *fixP;
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)
4770 reloc = insn_reloc;
4771 else
4772 switch (len)
4774 case 1:
4775 reloc = BFD_RELOC_8;
4776 break;
4777 case 2:
4778 reloc = BFD_RELOC_16;
4779 break;
4780 case 4:
4781 reloc = BFD_RELOC_32;
4782 break;
4783 case 8:
4784 reloc = BFD_RELOC_64;
4785 break;
4786 default:
4787 as_bad (_("unsupported BFD relocation size %d"), len);
4788 reloc = BFD_RELOC_32;
4789 break;
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
4803 relaxing. */
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)
4815 return 1;
4817 if (fix->fx_addsy == NULL)
4818 return 0;
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))
4823 return 1;
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. */
4830 bfd_boolean
4831 csky_fix_adjustable (fixS * fixP)
4833 if (fixP->fx_addsy == NULL)
4834 return 1;
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)
4860 return 0;
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))
4865 return 0;
4867 return 1;
4870 void
4871 md_apply_fix (fixS *fixP,
4872 valueT *valP,
4873 segT seg)
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(). */
4882 fixP->fx_done = 0;
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:
4895 *valP = 0;
4896 break;
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));
4905 /* Fall through. */
4906 case BFD_RELOC_CKCORE_TLS_LE32:
4907 case BFD_RELOC_CKCORE_TLS_LDO32:
4908 S_SET_THREAD_LOCAL (fixP->fx_addsy);
4909 break;
4910 default:
4911 break;
4913 #ifdef OBJ_ELF
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. */
4917 return;
4918 #endif
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;
4927 break;
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);
4933 break;
4934 case BFD_RELOC_VTABLE_ENTRY:
4935 fixP->fx_r_type = BFD_RELOC_CKCORE_GNU_VTENTRY;
4936 break;
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:
4957 break;
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));
4966 /* Fall through. */
4967 case BFD_RELOC_CKCORE_TLS_LE32:
4968 case BFD_RELOC_CKCORE_TLS_LDO32:
4969 S_SET_THREAD_LOCAL (fixP->fx_addsy);
4970 break;
4971 case BFD_RELOC_32:
4972 fixP->fx_r_type = BFD_RELOC_CKCORE_ADDR32;
4973 /* Fall through. */
4974 case BFD_RELOC_16:
4975 case BFD_RELOC_8:
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)
4984 else
4985 abort ();
4986 md_number_to_chars (buf, val, fixP->fx_size);
4987 fixP->fx_done = 1;
4989 break;
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);
4996 fixP->fx_done = 1;
4998 else
4999 *valP = 0;
5000 break;
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);
5022 fixP->fx_done = 1;
5024 break;
5026 default:
5028 valueT opcode;
5029 offsetT min, max;
5030 unsigned int issigned = 0;
5032 if (fixP->fx_addsy)
5033 break;
5035 howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
5036 if (howto == NULL)
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);
5043 fixP->fx_done = 1;
5044 break;
5046 else
5047 abort ();
5050 if (IS_CSKY_V2 (mach_flag))
5051 val += fixP->fx_size;
5053 if (howto->rightshift == 2)
5054 val += 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;
5065 min = 0;
5066 break;
5067 /* lrw16. */
5068 case BFD_RELOC_CKCORE_PCREL_IMM7BY4:
5069 if (do_extend_lrw)
5070 max = (offsetT)((1 << (howto->bitsize + 1)) - 2);
5071 else
5072 max = (offsetT)((1 << howto->bitsize) - 1);
5073 min = 0;
5074 break;
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);
5078 min = 0;
5079 break;
5080 /* Offset is signed. */
5081 default:
5082 max = (offsetT)(howto->dst_mask >> 1);
5083 min = - max - 1;
5084 issigned = 1;
5086 if (val < min || val > max)
5088 csky_branch_report_error (fixP->fx_file, fixP->fx_line,
5089 fixP->fx_addsy, val);
5090 return;
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)
5096 val &= 0xff;
5097 else
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. */
5106 if (val >= 0x80)
5107 csky_write_insn (buf,
5108 ((~val & 0x1f)
5109 | ((~val & 0x60) << 3) | (opcode & 0xe0)),
5110 fixP->fx_size);
5111 /* 7 bit offset lrw16. */
5112 else
5113 csky_write_insn (buf,
5114 (val & 0x1f) | ((val & 0x60) << 3) | opcode,
5115 fixP->fx_size);
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,
5121 fixP->fx_size);
5122 else
5123 csky_write_insn (buf, val | opcode, fixP->fx_size);
5124 fixP->fx_done = 1;
5125 break;
5128 fixP->fx_addnumber = val;
5131 /* Translate internal representation of relocation info to BFD target
5132 format. */
5134 arelent *
5135 tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixP)
5137 arelent *rel;
5139 if (fixP->fx_pcrel
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;
5159 return rel;
5162 /* Relax a fragment by scanning TC_GENERIC_RELAX_TABLE. */
5164 long
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;
5171 offsetT growth;
5172 offsetT aim;
5173 addressT target;
5174 addressT address;
5175 symbolS *symbolP;
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;
5185 if (symbolP)
5187 fragS *sym_frag;
5189 sym_frag = symbol_get_frag (symbolP);
5191 #ifndef DIFF_EXPR_OK
5192 know (sym_frag != NULL);
5193 #endif
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. */
5206 if (stretch != 0
5207 && sym_frag->relax_marker != fragP->relax_marker
5208 && S_GET_SEGMENT (symbolP) == segment)
5210 fragS *f;
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
5217 alignment. */
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)
5222 if (stretch < 0)
5223 stretch = -((-stretch)
5224 & ~((1 << (int) f->fr_offset) - 1));
5225 else
5226 stretch &= ~((1 << (int) f->fr_offset) - 1);
5228 if (stretch == 0)
5229 break;
5231 if (f != 0)
5232 target += stretch;
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)
5240 aim = 0;
5242 if (aim < 0)
5244 /* Look backwards. */
5245 for (next_state = this_type->rlx_more; next_state;)
5246 if (aim >= this_type->rlx_backward)
5247 next_state = 0;
5248 else
5250 /* Grow to next state. */
5251 this_state = next_state;
5252 this_type = table + this_state;
5253 next_state = this_type->rlx_more;
5256 else
5258 /* Look forwards. */
5259 for (next_state = this_type->rlx_more; next_state;)
5260 if (aim <= this_type->rlx_forward)
5261 next_state = 0;
5262 else
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;
5272 if (growth != 0)
5273 fragP->fr_subtype = this_state;
5274 return growth;
5278 md_estimate_size_before_relax (fragS * fragp,
5279 segT segtype)
5281 switch (fragp->fr_subtype)
5283 case COND_DISP10:
5284 case COND_DISP16:
5285 case SCOND_DISP10:
5286 case SCOND_DISP16:
5287 case UNCD_DISP10:
5288 case UNCD_DISP16:
5289 case JCOND_DISP10:
5290 case JCOND_DISP16:
5291 case JCOND_DISP32:
5292 case JUNCD_DISP10:
5293 case JUNCD_DISP16:
5294 case JUNCD_DISP32:
5295 case JCOMPZ_DISP16:
5296 case JCOMPZ_DISP32:
5297 case BSR_DISP26:
5298 case LRW_DISP7:
5299 case LRW2_DISP8:
5300 case LRW_DISP16:
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);
5314 else
5315 fragp->fr_subtype = C (UNCD_JUMP_S, UNDEF_WORD_DISP);
5316 break;
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
5327 long. */
5328 fragp->fr_subtype = C (COND_JUMP_S, UNDEF_WORD_DISP);
5329 else
5330 /* We know the abs value. */
5331 fragp->fr_subtype = C (COND_JUMP_S, DISP12);
5332 break;
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:
5347 break;
5349 default:
5350 abort ();
5352 return csky_relax_table[fragp->fr_subtype].rlx_length;
5355 /* Parse opcode like: "op oprnd1, oprnd2, oprnd3". */
5357 static void
5358 csky_macro_md_assemble (const char *op,
5359 const char *oprnd1,
5360 const char *oprnd2,
5361 const char *oprnd3)
5363 char str[80];
5364 str[0] = '\0';
5365 strcat (str, op);
5366 if (oprnd1 != NULL)
5368 strcat (str, " ");
5369 strcat (str, oprnd1);
5370 if (oprnd2 != NULL)
5372 strcat (str, ",");
5373 strcat (str, oprnd2);
5374 if (oprnd3 != NULL)
5376 strcat (str, ",");
5377 strcat (str, oprnd3);
5381 md_assemble (str);
5382 return;
5385 /* Get the string of operand. */
5387 static int
5388 csky_get_macro_operand (char *src_s, char *dst_s, char end_sym)
5390 int nlen = 0;
5391 while (ISSPACE (*src_s))
5392 ++src_s;
5393 while (*src_s != end_sym)
5394 dst_s[nlen++] = *(src_s++);
5395 dst_s[nlen] = '\0';
5396 return nlen;
5399 /* idly 4 -> idly4. */
5401 static void
5402 csky_idly (void)
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"));
5408 return;
5410 csky_macro_md_assemble ("idly4", NULL, NULL, NULL);
5411 return;
5414 /* rolc rd, 1 or roltc rd, 1 -> addc rd, rd. */
5416 static void
5417 csky_rolc (void)
5419 char reg[10];
5420 char *s = csky_insn.opcode_end;
5422 s += csky_get_macro_operand (s, reg, ',');
5423 ++s;
5425 if (is_imm_over_range (&s, 1, 1, -1))
5427 csky_macro_md_assemble ("addc", reg, reg, NULL);
5428 return;
5430 else
5431 as_bad (_("second operand must be 1"));
5434 /* sxtrb0(1)(2) r1, rx -> xtbr0(1)(2) r1,rx; sextb r1. */
5436 static void
5437 csky_sxtrb (void)
5439 char reg1[10];
5440 char reg2[10];
5442 char *s = csky_insn.opcode_end;
5443 s += csky_get_macro_operand (s, reg1, ',');
5444 ++s;
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);
5449 return;
5452 static void
5453 csky_movtf (void)
5455 char reg1[10];
5456 char reg2[10];
5457 char reg3[10];
5459 char *s = csky_insn.opcode_end;
5460 s += csky_get_macro_operand (s, reg1, ',');
5461 ++s;
5463 s += csky_get_macro_operand (s, reg2, ',');
5464 ++s;
5466 s += csky_get_macro_operand (s, reg3, '\0');
5467 ++s;
5468 csky_macro_md_assemble ("movt", reg1, reg2, NULL);
5469 csky_macro_md_assemble ("movf", reg1, reg3, NULL);
5470 return;
5473 static bfd_boolean
5474 get_macro_reg_vals (int *reg1, int *reg2, int *reg3)
5476 int nlen;
5477 char *s = csky_insn.opcode_end;
5479 *reg1 = csky_get_reg_val (s, &nlen);
5480 s += nlen;
5481 if (*s != ',')
5483 csky_show_error (ERROR_MISSING_COMMA, 0, NULL, NULL);
5484 return FALSE;
5486 s++;
5487 *reg2 = csky_get_reg_val (s, &nlen);
5488 s += nlen;
5489 if (*s != ',')
5491 csky_show_error (ERROR_MISSING_COMMA, 0, NULL, NULL);
5492 return FALSE;
5494 s++;
5495 *reg3 = csky_get_reg_val (s, &nlen);
5496 s += nlen;
5497 if (*s != '\0')
5499 csky_show_error (ERROR_BAD_END, 0, s, NULL);
5500 return FALSE;
5502 if (*reg1 == -1 || *reg2 == -1 || *reg3 == -1)
5504 as_bad (_("register number out of range"));
5505 return FALSE;
5507 if (*reg1 != *reg2)
5509 as_bad (_("dest and source1 must be the same register"));
5510 return FALSE;
5512 if (*reg1 >= 15 || *reg3 >= 15)
5514 as_bad (_("64-bit operator src/dst register must be less than 15"));
5515 return FALSE;
5517 return TRUE;
5520 /* addc64 rx, rx, ry -> cmplt rx, rx, addc rx, ry, addc rx+1, ry+1. */
5522 static void
5523 csky_addc64 (void)
5525 int reg1;
5526 int reg2;
5527 int reg3;
5529 if (!get_macro_reg_vals (&reg1, &reg2, &reg3))
5530 return;
5531 csky_macro_md_assemble ("cmplt",
5532 csky_general_reg[reg1],
5533 csky_general_reg[reg1],
5534 NULL);
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)],
5538 NULL);
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)],
5542 NULL);
5543 return;
5546 /* subc64 rx, rx, ry -> cmphs rx, rx, subc rx, ry, subc rx+1, ry+1. */
5548 static void
5549 csky_subc64 (void)
5551 int reg1;
5552 int reg2;
5553 int reg3;
5555 if (!get_macro_reg_vals (&reg1, &reg2, &reg3))
5556 return;
5557 csky_macro_md_assemble ("cmphs",
5558 csky_general_reg[reg1],
5559 csky_general_reg[reg1],
5560 NULL);
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)],
5564 NULL);
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)],
5568 NULL);
5569 return;
5572 /* or64 rx, rx, ry -> or rx, ry, or rx+1, ry+1. */
5574 static void
5575 csky_or64 (void)
5577 int reg1;
5578 int reg2;
5579 int reg3;
5581 if (!get_macro_reg_vals (&reg1, &reg2, &reg3))
5582 return;
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)],
5586 NULL);
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)],
5590 NULL);
5591 return;
5594 /* xor64 rx, rx, ry -> xor rx, ry, xor rx+1, ry+1. */
5596 static void
5597 csky_xor64 (void)
5599 int reg1;
5600 int reg2;
5601 int reg3;
5603 if (!get_macro_reg_vals (&reg1, &reg2, &reg3))
5604 return;
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)],
5608 NULL);
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)],
5612 NULL);
5613 return;
5616 /* The following are V2 macro instructions. */
5618 /* neg rd -> not rd, rd; addi rd, 1. */
5620 static void
5621 csky_neg (void)
5623 char reg1[10];
5625 char *s = csky_insn.opcode_end;
5626 s += csky_get_macro_operand (s, reg1, '\0');
5627 ++s;
5629 csky_macro_md_assemble ("not", reg1, reg1, NULL);
5630 csky_macro_md_assemble ("addi", reg1, "1", NULL);
5631 return;
5634 /* rsubi rd, imm16 -> not rd; addi rd, imm16 + 1 */
5636 static void
5637 csky_rsubi (void)
5639 char reg1[10];
5640 char str_imm16[20];
5641 unsigned int imm16 = 0;
5642 expressionS e;
5643 char *s = csky_insn.opcode_end;
5644 s += csky_get_macro_operand (s, reg1, ',');
5645 ++s;
5647 s = parse_exp (s, &e);
5648 if (e.X_op == O_constant)
5649 imm16 = e.X_add_number;
5650 else
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);
5657 return;
5660 /* Such as: asrc rd -> asrc rd, rd, 1. */
5662 static void
5663 csky_arith (void)
5665 char reg1[10];
5666 char *s = csky_insn.opcode_end;
5667 s += csky_get_macro_operand (s, reg1, '\0');
5668 ++s;
5669 csky_macro_md_assemble (csky_insn.macro->name, reg1, reg1, "1");
5670 return;
5673 /* decne rd -> if ck802: subi rd, 1; cmpnei rd, 0.
5674 else: decne rd, rd, 1 */
5676 static void
5677 csky_decne (void)
5679 char reg1[10];
5680 char *s = csky_insn.opcode_end;
5681 s += csky_get_macro_operand (s, reg1, '\0');
5682 ++s;
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);
5688 else
5689 csky_macro_md_assemble ("decne", reg1, reg1, "1");
5690 return;
5693 /* If -mnolrw, lrw rd, imm -> movih rd, imm_hi16; ori rd, imm_lo16. */
5695 static void
5696 csky_lrw (void)
5698 char reg1[10];
5699 char imm[40];
5700 char imm_hi16[40];
5701 char imm_lo16[40];
5703 char *s = csky_insn.opcode_end;
5704 s += csky_get_macro_operand (s, reg1, ',');
5705 ++s;
5706 s += csky_get_macro_operand (s, imm, '\0');
5707 ++s;
5709 imm_hi16[0] = '\0';
5710 strcat (imm_hi16, "(");
5711 strcat (imm_hi16, imm);
5712 strcat (imm_hi16, ") >> 16");
5713 imm_lo16[0] = '\0';
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);
5721 return;
5724 /* The following are worker functions for C-SKY v1. */
5726 bfd_boolean
5727 v1_work_lrw (void)
5729 int reg;
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)
5738 /* lrw to movi. */
5739 csky_insn.inst = 0x6000 | reg | (csky_insn.e1.X_add_number << 4);
5740 else
5742 csky_insn.inst = csky_insn.opcode->op16[0].opcode;
5743 csky_insn.inst |= reg << 8;
5744 if (output_literal)
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
5760 = (csky_insn.output
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);
5768 return TRUE;
5771 bfd_boolean
5772 v1_work_fpu_fo (void)
5774 int i = 0;
5775 int inst;
5776 int greg = -1;
5777 char buff[50];
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);
5797 md_assemble (buff);
5798 sprintf (buff, "cpwir %s", csky_general_reg[greg]);
5799 md_assemble (buff);
5801 return FALSE;
5804 bfd_boolean
5805 v1_work_fpu_fo_fc (void)
5807 int i = 0;
5808 int inst;
5809 int greg = -1;
5810 char buff[50];
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);
5830 md_assemble (buff);
5831 sprintf (buff, "cpwir %s", csky_general_reg[greg]);
5832 md_assemble (buff);
5833 sprintf (buff, "cprc");
5834 md_assemble (buff);
5836 return FALSE;
5839 bfd_boolean
5840 v1_work_fpu_write (void)
5842 int greg;
5843 int freg;
5844 char buff[50];
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]);
5851 md_assemble (buff);
5853 return FALSE;
5856 bfd_boolean
5857 v1_work_fpu_read (void)
5859 int greg;
5860 int freg;
5861 char buff[50];
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]);
5867 md_assemble (buff);
5869 return FALSE;
5872 bfd_boolean
5873 v1_work_fpu_writed (void)
5875 int greg;
5876 int freg;
5877 char buff[50];
5879 greg = csky_insn.val[0];
5880 freg = csky_insn.val[1];
5882 if (greg & 0x1)
5884 as_bad (_("even register number required"));
5885 return FALSE;
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]);
5891 else
5892 sprintf (buff, "cpwgr %s,%s",
5893 csky_general_reg[greg], csky_cp_reg[freg]);
5894 md_assemble (buff);
5895 if (target_big_endian)
5896 sprintf (buff, "cpwgr %s,%s",
5897 csky_general_reg[greg], csky_cp_reg[freg + 1]);
5898 else
5899 sprintf (buff, "cpwgr %s,%s",
5900 csky_general_reg[greg + 1], csky_cp_reg[freg + 1]);
5901 md_assemble (buff);
5903 return FALSE;
5906 bfd_boolean
5907 v1_work_fpu_readd (void)
5909 int greg;
5910 int freg;
5911 char buff[50];
5913 greg = csky_insn.val[0];
5914 freg = csky_insn.val[1];
5916 if (greg & 0x1)
5918 as_bad (_("even register number required"));
5919 return FALSE;
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]);
5925 else
5926 sprintf (buff, "cprgr %s,%s",
5927 csky_general_reg[greg], csky_cp_reg[freg]);
5928 md_assemble (buff);
5929 if (target_big_endian)
5930 sprintf (buff, "cprgr %s,%s",
5931 csky_general_reg[greg], csky_cp_reg[freg + 1]);
5932 else
5933 sprintf (buff, "cprgr %s,%s",
5934 csky_general_reg[greg + 1], csky_cp_reg[freg + 1]);
5935 md_assemble (buff);
5937 return FALSE;
5940 /* The following are for csky pseudo handling. */
5942 bfd_boolean
5943 v1_work_jbsr (void)
5945 csky_insn.output = frag_more (2);
5946 if (do_force2bsr)
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);
5950 else
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);
5980 return TRUE;
5983 /* The following are worker functions for csky v2 instruction handling. */
5985 /* For nie/nir/ipush/ipop. */
5987 bfd_boolean
5988 v2_work_istack (void)
5990 if (!do_intr_stack)
5992 csky_show_error (ERROR_OPCODE_ILLEGAL, 0, NULL, NULL);
5993 return FALSE;
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);
5998 return TRUE;
6001 bfd_boolean
6002 v2_work_btsti (void)
6004 if (!do_extend_lrw
6005 && (csky_insn.flag_force == INSN_OPCODE16F
6006 || IS_CSKY_ARCH_801 (mach_flag)))
6008 csky_show_error (ERROR_OPCODE_ILLEGAL, 0, NULL, NULL);
6009 return FALSE;
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);
6019 return TRUE;
6022 bfd_boolean
6023 v2_work_addi (void)
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);
6056 else
6058 csky_show_error (ERROR_OPERANDS_ILLEGAL, 0,
6059 csky_insn.opcode_end, NULL);
6060 return FALSE;
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);
6117 else
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);
6130 else
6132 csky_show_error (ERROR_OPERANDS_ILLEGAL, 0,
6133 (char *)csky_insn.opcode_end, NULL);
6134 return FALSE;
6137 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
6139 return TRUE;
6142 bfd_boolean
6143 v2_work_subi (void)
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;
6172 else
6174 csky_show_error (ERROR_OPERANDS_ILLEGAL, 0,
6175 (char *)csky_insn.opcode_end, NULL);
6176 return FALSE;
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;
6217 else
6219 csky_show_error (ERROR_OPERANDS_ILLEGAL, 0,
6220 (char *)csky_insn.opcode_end, NULL);
6221 return FALSE;
6224 csky_insn.output = frag_more (csky_insn.isize);
6225 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
6227 return TRUE;
6230 bfd_boolean
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);
6267 else
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);
6276 return FALSE;
6278 /* sub rz, rx. */
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);
6285 return TRUE;
6288 bfd_boolean
6289 v2_work_rotlc (void)
6291 const char *name = "addc";
6292 csky_insn.opcode
6293 = (struct csky_opcode *) hash_find (csky_opcodes_hash, name);
6294 csky_insn.opcode_idx = 0;
6295 if (csky_insn.isize == 2)
6297 /* addc rz, rx. */
6298 csky_insn.number = 2;
6299 csky_insn.val[1] = csky_insn.val[0];
6301 else
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);
6314 return TRUE;
6317 bfd_boolean
6318 v2_work_bgeni (void)
6320 const char *name = NULL;
6321 int imm = csky_insn.val[1];
6322 int val = 1 << imm;
6323 if (imm < 16)
6324 name = "movi";
6325 else
6327 name = "movih";
6328 val >>= 16;
6330 csky_insn.opcode
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);
6341 return TRUE;
6344 bfd_boolean
6345 v2_work_not (void)
6347 const char *name = "nor";
6348 csky_insn.opcode
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;
6360 else
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;
6376 else
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);
6390 return TRUE;
6393 bfd_boolean
6394 v2_work_jbtf (void)
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);
6399 return FALSE;
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,
6408 SCOND_DISP16_LEN,
6409 SCOND_DISP10_LEN,
6410 SCOND_DISP10,
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,
6424 JCOND_DISP32_LEN,
6425 JCOND_DISP10_LEN,
6426 JCOND_DISP10,
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;
6434 else
6436 /* Generate relax with condition. */
6437 csky_insn.output = frag_var (rs_machine_dependent,
6438 COND_DISP16_LEN,
6439 COND_DISP10_LEN,
6440 COND_DISP10,
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);
6450 return TRUE;
6453 bfd_boolean
6454 v2_work_jbr (void)
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);
6459 return FALSE;
6462 if (do_long_jump
6463 && !IS_CSKY_ARCH_801 (mach_flag)
6464 && !IS_CSKY_ARCH_802 (mach_flag))
6466 csky_insn.output = frag_var (rs_machine_dependent,
6467 JUNCD_DISP32_LEN,
6468 JUNCD_DISP10_LEN,
6469 JUNCD_DISP10,
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;
6478 else
6480 /* Generate relax with condition. */
6481 csky_insn.output = frag_var (rs_machine_dependent,
6482 UNCD_DISP16_LEN,
6483 UNCD_DISP10_LEN,
6484 UNCD_DISP10,
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);
6494 return TRUE;
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))
6501 bfd_boolean
6502 v2_work_lrw (void)
6504 int reg = csky_insn.val[0];
6505 int output_literal = csky_insn.val[1];
6506 int is_done = 0;
6508 /* If the second operand is O_constant, We can use movi/movih
6509 instead of lrw. */
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;
6520 is_done = 1;
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;
6530 is_done = 1;
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;
6540 is_done = 1;
6544 if (is_done)
6546 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
6547 return TRUE;
6550 if (output_literal)
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. */
6562 if (reg > 7)
6564 csky_show_error (ERROR_UNDEFINE, 0,
6565 (void *)"The register is out of range.", NULL);
6566 return FALSE;
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);
6580 csky_insn.max = 4;
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);
6600 else if (!is_done)
6602 if (reg < 8)
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,
6612 LRW_DISP16_LEN,
6613 LRW_DISP7_LEN,
6614 (do_extend_lrw
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
6626 = (csky_insn.output
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;
6633 else
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);
6652 return TRUE;
6655 bfd_boolean
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;
6663 switch (insn_reloc)
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);
6668 break;
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);
6672 break;
6673 default:
6674 fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
6675 4, &csky_insn.e1, 1, BFD_RELOC_CKCORE_DOFFSET_IMM18BY4);
6676 break;
6678 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
6679 return TRUE;
6682 bfd_boolean
6683 v2_work_jbsr (void)
6685 if (do_force2bsr
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;
6695 else
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;
6719 csky_insn.max = 8;
6722 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
6724 return TRUE;
6727 bfd_boolean
6728 v2_work_jsri (void)
6730 /* dump literal. */
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);
6757 csky_insn.max = 8;
6759 return TRUE;
6762 bfd_boolean
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);
6773 return FALSE;
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);
6778 return FALSE;
6780 else
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;
6800 else
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);
6805 else
6807 void *arg = (void *)"the second operand must be \"SYMBOL >> 16\"";
6808 csky_show_error (ERROR_UNDEFINE, 0, arg, NULL);
6809 return FALSE;
6812 csky_insn.isize = 4;
6813 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
6815 return TRUE;
6818 bfd_boolean
6819 v2_work_ori (void)
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;
6830 else
6832 csky_show_error (ERROR_IMM_OVERFLOW, 3, NULL, NULL);
6833 return FALSE;
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;
6851 else
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);
6856 else
6858 void *arg = (void *)"the third operand must be \"SYMBOL & 0xffff\"";
6859 csky_show_error (ERROR_UNDEFINE, 0, arg, NULL);
6860 return FALSE;
6863 csky_insn.isize = 4;
6864 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
6865 return TRUE;
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. */
6876 bfd_boolean
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);
6889 return TRUE;
6892 bfd_boolean
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);
6912 return TRUE;
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. */
6924 static void
6925 csky_pool_count (void (*func) (int), int arg)
6927 const fragS *curr_frag = frag_now;
6928 offsetT added = -frag_now_fix_octets ();
6930 (*func) (arg);
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 ();
6939 poolspan += added;
6942 /* Support the .literals directive. */
6943 static void
6944 csky_s_literals (int ignore ATTRIBUTE_UNUSED)
6946 dump_literals (0);
6947 demand_empty_rest_of_line ();
6950 /* Support the .string, etc directives. */
6951 static void
6952 csky_stringer (int append_zero)
6954 if (now_seg == text_section)
6955 csky_pool_count (stringer, append_zero);
6956 else
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. */
6969 static void
6970 csky_cons (int nbytes)
6972 mapping_state (MAP_DATA);
6973 if (nbytes == 4) /* @GOT. */
6977 bfd_reloc_code_real_type reloc;
6978 expressionS exp;
6980 reloc = BFD_RELOC_NONE;
6981 expression (&exp);
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);
6990 if (size > nbytes)
6991 as_bad (ngettext ("%s relocations do not fit in %d byte",
6992 "%s relocations do not fit in %d bytes",
6993 nbytes),
6994 howto->name, nbytes);
6995 else
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);
7005 else
7006 emit_expr (&exp, (unsigned int) nbytes);
7007 if (now_seg == text_section)
7008 poolspan += nbytes;
7010 while (*input_line_pointer++ == ',');
7012 /* Put terminator back into stream. */
7013 input_line_pointer --;
7014 demand_empty_rest_of_line ();
7016 return;
7019 if (now_seg == text_section)
7020 csky_pool_count (cons, nbytes);
7021 else
7022 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. */
7033 static void
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);
7039 else
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. */
7051 static void
7052 csky_fill (int ignore)
7054 if (now_seg == text_section)
7055 csky_pool_count (s_fill, ignore);
7056 else
7057 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. */
7065 static void
7066 csky_s_text (int ignore)
7068 dump_literals (0);
7070 #ifdef OBJ_ELF
7071 obj_elf_text (ignore);
7072 #else
7073 s_text (ignore);
7074 #endif
7077 static void
7078 csky_s_data (int ignore)
7080 dump_literals (0);
7082 #ifdef OBJ_ELF
7083 obj_elf_data (ignore);
7084 #else
7085 s_data (ignore);
7086 #endif
7089 static void
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
7097 pool. */
7098 char * ilp = input_line_pointer;
7100 while (*ilp != 0 && ISSPACE (*ilp))
7101 ++ ilp;
7103 if (strncmp (ilp, ".line", 5) == 0
7104 && (ISSPACE (ilp[5]) || *ilp == '\n' || *ilp == '\r'))
7106 else
7107 dump_literals (0);
7109 #ifdef OBJ_ELF
7110 obj_elf_section (ignore);
7111 #endif
7112 #ifdef OBJ_COFF
7113 obj_coff_section (ignore);
7114 #endif
7117 static void
7118 csky_s_bss (int needs_align)
7120 dump_literals (0);
7121 s_lcomm_bytes (needs_align);
7124 #ifdef OBJ_ELF
7125 static void
7126 csky_s_comm (int needs_align)
7128 dump_literals (0);
7129 obj_elf_common (needs_align);
7131 #endif
7133 /* Handle the .no_literal_dump directive. */
7135 static void
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. */
7150 static void
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;
7159 /* Do alignment. */
7160 s_align_ptwo (arg);
7163 /* Handle the .stack_size directive. */
7165 static void
7166 csky_stack_size (int arg ATTRIBUTE_UNUSED)
7168 expressionS exp;
7169 stack_size_entry *sse
7170 = (stack_size_entry *) xcalloc (1, sizeof (stack_size_entry));
7172 expression (&exp);
7173 if (exp.X_op == O_symbol)
7174 sse->function = exp.X_add_symbol;
7175 else
7177 as_bad (_("the first operand must be a symbol"));
7178 ignore_rest_of_line ();
7179 free (sse);
7180 return;
7183 SKIP_WHITESPACE ();
7184 if (*input_line_pointer != ',')
7186 as_bad (_("missing stack size"));
7187 ignore_rest_of_line ();
7188 free (sse);
7189 return;
7192 ++input_line_pointer;
7193 expression (&exp);
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 ();
7201 free (sse);
7202 return;
7204 else
7205 sse->stack_size = exp.X_add_number;
7207 else
7209 as_bad (_("operand must be a constant"));
7210 ignore_rest_of_line ();
7211 free (sse);
7212 return;
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 },
7266 #ifdef OBJ_ELF
7267 { "comm", csky_s_comm, 0 },
7268 #endif
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:
7275 insn1
7276 insn2
7277 ......
7278 insnN+1
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 },
7284 {0, 0, 0}
7287 /* Implement tc_cfi_frame_initial_instructions. */
7289 void
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)
7301 int reg_num = -1;
7302 int len;
7304 /* FIXME the reg should be parsed according to
7305 the abi version. */
7306 reg_num = csky_get_reg_val (regname, &len);
7307 return reg_num;