]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gas/config/tc-csky.c
Update year range in copyright notice of binutils files
[thirdparty/binutils-gdb.git] / gas / config / tc-csky.c
1 /* tc-csky.c -- Assembler for C-SKY
2 Copyright (C) 1989-2024 Free Software Foundation, Inc.
3 Created by Lifang Xia (lifang_xia@c-sky.com)
4 Contributed by C-SKY Microsystems and Mentor Graphics.
5
6 This file is part of GAS, the GNU Assembler.
7
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.
12
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.
17
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. */
22
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"
32
33 #ifdef OBJ_ELF
34 #include "elf/csky.h"
35 #include "dw2gencfi.h"
36 #endif
37 #include "tc-csky.h"
38 #include "dwarf2dbg.h"
39
40 #define BUILD_AS 1
41
42 #define OPCODE_MAX_LEN 20
43 #define HAS_SUB_OPERAND 0xfffffffful
44
45 /* This value is just for lrw to distinguish "[]" label. */
46 #define NEED_OUTPUT_LITERAL 1
47
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)
51
52
53 #define KB * 1024
54 #define MB KB * 1024
55 #define GB MB * 1024
56
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. */
61
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)
68
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)
73
74 /* For lrw16, 112 average size for a function. */
75 #define v2_SPANEXIT (512 - 112)
76
77 /* For lrw16 (3+7, 512 bytes). */
78 #define v2_SPANCLOSE_ELRW (1016 - 24)
79
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"
85
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
92
93 #define UNDEF_DISP 0
94 #define DISP12 1
95 #define DISP32 2
96 #define UNDEF_WORD_DISP 3
97
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
108
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)
114
115 /* Used in v2_relax_table. */
116 #define COND_DISP10_LEN 2 /* bt/bf_16. */
117 #define COND_DISP16_LEN 4 /* bt/bf_32. */
118
119 #define SCOND_DISP10_LEN 2 /* bt/bf_16, for CK801 only. */
120 #define SCOND_DISP16_LEN 6 /* !(bt/bf_16) + br_32. */
121
122 #define UNCD_DISP10_LEN 2 /* br_16. */
123 #define UNCD_DISP16_LEN 4 /* br_32. */
124 #define UNCD_DISP26_LEN 4 /* br32_old. */
125
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. */
130
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. */
136
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. */
142
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. */
147
148 /* Declare worker functions. */
149 bool v1_work_lrw (void);
150 bool v1_work_jbsr (void);
151 bool v1_work_fpu_fo (void);
152 bool v1_work_fpu_fo_fc (void);
153 bool v1_work_fpu_write (void);
154 bool v1_work_fpu_read (void);
155 bool v1_work_fpu_writed (void);
156 bool v1_work_fpu_readd (void);
157 bool v2_work_istack (void);
158 bool v2_work_btsti (void);
159 bool v2_work_addi (void);
160 bool v2_work_subi (void);
161 bool v2_work_add_sub (void);
162 bool v2_work_rotlc (void);
163 bool v2_work_bgeni (void);
164 bool v2_work_not (void);
165 bool v2_work_jbtf (void);
166 bool v2_work_jbr (void);
167 bool v2_work_lrw (void);
168 bool v2_work_lrsrsw (void);
169 bool v2_work_jbsr (void);
170 bool v2_work_jsri (void);
171 bool v2_work_movih (void);
172 bool v2_work_ori (void);
173 bool float_work_fmovi (void);
174 bool dsp_work_bloop (void);
175 bool float_work_fpuv3_fmovi (void);
176 bool float_work_fpuv3_fstore (void);
177 bool v2_work_addc (void);
178
179 /* csky-opc.h must be included after workers are declared. */
180 #include "opcodes/csky-opc.h"
181 #include "opcode/csky.h"
182
183 enum
184 {
185 RELAX_NONE = 0,
186 RELAX_OVERFLOW,
187
188 COND_DISP10 = 20, /* bt/bf_16. */
189 COND_DISP16, /* bt/bf_32. */
190
191 SCOND_DISP10, /* br_16 */
192 SCOND_DISP16, /* !(bt/bf_32) + br_32. */
193
194 UNCD_DISP10, /* br_16. */
195 UNCD_DISP16, /* br_32. */
196
197 JCOND_DISP10, /* bt/bf_16. */
198 JCOND_DISP16, /* bt/bf_32. */
199 JCOND_DISP32, /* !(bt/bf_32)/jmpi + literal. */
200
201 JUNCD_DISP10, /* br_16. */
202 JUNCD_DISP16, /* br_32. */
203 JUNCD_DISP32, /* jmpi + literal. */
204
205 JCOMPZ_DISP16, /* bez/bnez/bhz/blsz/blz/bhsz. */
206 JCOMPZ_DISP32, /* !(jbez/jbnez/jblsz/jblz/jbhsz) + jmpi + literal. */
207
208 BSR_DISP26, /* bsr_32. */
209
210 LRW_DISP7, /* lrw16. */
211 LRW2_DISP8, /* lrw16, -mno-bsr16,8 bit offset. */
212 LRW_DISP16, /* lrw32. */
213 };
214
215 unsigned int mach_flag = 0;
216 unsigned int arch_flag = 0;
217 unsigned int other_flag = 0;
218 uint64_t isa_flag = 0;
219 unsigned int dsp_flag = 0;
220
221 typedef struct stack_size_entry
222 {
223 struct stack_size_entry *next;
224 symbolS *function;
225 unsigned int stack_size;
226 } stack_size_entry;
227
228 struct csky_arch_info
229 {
230 const char *name;
231 unsigned int arch_flag;
232 unsigned int bfd_mach_flag;
233 };
234
235 typedef enum
236 {
237 INSN_OPCODE,
238 INSN_OPCODE16F,
239 INSN_OPCODE32F,
240 } inst_flag;
241
242 /* Macro information. */
243 struct csky_macro_info
244 {
245 const char *name;
246 /* How many operands : if operands == 5, all of 1,2,3,4 are ok. */
247 long oprnd_num;
248 uint64_t isa_flag;
249 /* Do the work. */
250 void (*handle_func)(void);
251 };
252
253 struct csky_insn_info
254 {
255 /* Name of the opcode. */
256 char *name;
257 /* Output instruction. */
258 unsigned int inst;
259 /* Pointer for frag. */
260 char *output;
261 /* End of instruction. */
262 char *opcode_end;
263 /* CPU infomations. */
264 const struct csky_cpu_info *cpu;
265 /* Flag for INSN_OPCODE16F, INSN_OPCODE32F, INSN_OPCODE, INSN_MACRO. */
266 inst_flag flag_force;
267 /* Operand number. */
268 int number;
269 struct csky_opcode *opcode;
270 struct csky_macro_info *macro;
271 /* Insn size for check_literal. */
272 unsigned int isize;
273 unsigned int last_isize;
274 /* Max size of insn for relax frag_var. */
275 unsigned int max;
276 /* Indicates which element is in csky_opcode_info op[] array. */
277 int opcode_idx;
278 /* The value of each operand in instruction when layout. */
279 int idx;
280 int val[MAX_OPRND_NUM];
281 struct relax_info
282 {
283 int max;
284 int var;
285 int subtype;
286 } relax;
287 /* The following are used for constant expressions. */
288 expressionS e1;
289 expressionS e2;
290 };
291
292 /* Literal pool data structures. */
293 struct literal
294 {
295 unsigned short refcnt;
296 unsigned int offset;
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;
304 LITTLENUM_TYPE bignum[SIZE_OF_LARGE_NUMBER + 6];
305 };
306
307 static void csky_idly (void);
308 static void csky_rolc (void);
309 static void csky_sxtrb (void);
310 static void csky_movtf (void);
311 static void csky_addc64 (void);
312 static void csky_subc64 (void);
313 static void csky_or64 (void);
314 static void csky_xor64 (void);
315 static void csky_neg (void);
316 static void csky_rsubi (void);
317 static void csky_arith (void);
318 static void csky_decne (void);
319 static void csky_lrw (void);
320
321 static enum bfd_reloc_code_real insn_reloc;
322
323 /* Assembler operand parse errors use these identifiers. */
324
325 enum error_number
326 {
327 /* The following are errors. */
328 ERROR_CREG_ILLEGAL = 0,
329 ERROR_REG_OVER_RANGE,
330 ERROR_FREG_OVER_RANGE,
331 ERROR_VREG_OVER_RANGE,
332 ERROR_GREG_ILLEGAL,
333 ERROR_802J_REG_OVER_RANGE,
334 ERROR_REG_FORMAT,
335 ERROR_REG_LIST,
336 ERROR_IMM_ILLEGAL,
337 ERROR_IMM_OVERFLOW, /* 5 */
338 ERROR_IMM_POWER,
339 ERROR_JMPIX_OVER_RANGE,
340 ERROR_EXP_CREG,
341 ERROR_EXP_GREG,
342 ERROR_EXP_CONSTANT,
343 ERROR_EXP_EVEN_FREG,
344 ERROR_RELOC_ILLEGAL,
345 ERROR_MISSING_OPERAND, /* 10 */
346 ERROR_MISSING_COMMA,
347 ERROR_MISSING_LBRACKET,
348 ERROR_MISSING_RBRACKET,
349 ERROR_MISSING_LSQUARE_BRACKETS,
350 ERROR_MISSING_RSQUARE_BRACKETS, /* 15 */
351 ERROR_MISSING_LANGLE_BRACKETS,
352 ERROR_MISSING_RANGLE_BRACKETS,
353 ERROR_OFFSET_UNALIGNED,
354 ERROR_BAD_END,
355 ERROR_UNDEFINE,
356 ERROR_CPREG_ILLEGAL, /* 20 */
357 ERROR_OPCODE_PSRBIT,
358 ERROR_OPERANDS_ILLEGAL,
359 ERROR_OPERANDS_NUMBER,
360 ERROR_OPCODE_ILLEGAL,
361
362 /* The following are warnings. */
363 WARNING_OPTIONS,
364 WARNING_IDLY,
365
366 /* Error and warning end. */
367 ERROR_NONE,
368 };
369
370 /* Global error state. ARG1 and ARG2 are opaque data interpreted
371 as appropriate for the error code. */
372
373 struct csky_error_state
374 {
375 enum error_number err_num;
376 int opnum;
377 int arg_int;
378 const void *arg1;
379 const void *arg2;
380 } error_state;
381
382 /* This macro is used to set error number and arg1 in the global state. */
383
384 #define SET_ERROR_STRING(err, msg) \
385 do { \
386 if (error_state.err_num > err) \
387 { \
388 error_state.err_num = err; \
389 error_state.arg1 = (void *)msg; \
390 } \
391 } while (0)
392
393 #define SET_ERROR_INTEGER(err, integer) \
394 do { \
395 if (error_state.err_num > err) \
396 { \
397 error_state.err_num = err; \
398 error_state.arg_int = integer; \
399 } \
400 } while (0)
401
402 /* Map error identifiers onto a format string, which will use
403 arg1 and arg2 from the global error state. */
404 struct csky_error_format_map
405 {
406 enum error_number num;
407 const char *fmt;
408 };
409
410 static const struct csky_error_format_map err_formats[] =
411 {
412 {ERROR_CREG_ILLEGAL, "Operand %d error: control register is illegal."},
413 {ERROR_REG_OVER_RANGE, "Operand %d error: r%d register is over range."},
414 {ERROR_FREG_OVER_RANGE, "Operand %d error: vr%d register is over range."},
415 {ERROR_VREG_OVER_RANGE, "Operand %d error: vr%d register is out of range."},
416 {ERROR_GREG_ILLEGAL, "Operand %d error: general register is illegal."},
417 {ERROR_802J_REG_OVER_RANGE, "Operand %d register %s out of range (802j only has registers:0-15,23,24,25,30)"},
418 {ERROR_REG_FORMAT, "Operand %d error: %s."},
419 {ERROR_REG_LIST, "Register list format is illegal."},
420 {ERROR_IMM_ILLEGAL, "Operand %d is not an immediate."},
421 {ERROR_IMM_OVERFLOW, "Operand %d immediate is overflow."},
422 {ERROR_IMM_POWER, "immediate %d is not a power of two"},
423 {ERROR_JMPIX_OVER_RANGE, "The second operand must be 16/24/32/40"},
424 {ERROR_EXP_CREG, "Operand %d error: control register is expected."},
425 {ERROR_EXP_GREG, "Operand %d error: general register is expected."},
426 {ERROR_EXP_CONSTANT, "Operand %d error: constant is expected."},
427 {ERROR_EXP_EVEN_FREG, "Operand %d error: even float register is expected."},
428 {ERROR_RELOC_ILLEGAL, "@%s reloc is not supported"},
429 {ERROR_MISSING_OPERAND, "Operand %d is missing."},
430 {ERROR_MISSING_COMMA, "Missing ','"},
431 {ERROR_MISSING_LBRACKET, "Missing '('"},
432 {ERROR_MISSING_RBRACKET, "Missing ')'"},
433 {ERROR_MISSING_LSQUARE_BRACKETS, "Missing '['"},
434 {ERROR_MISSING_RSQUARE_BRACKETS, "Missing ']'"},
435 {ERROR_MISSING_LANGLE_BRACKETS, "Missing '<'"},
436 {ERROR_MISSING_RANGLE_BRACKETS, "Missing '>'"},
437 {ERROR_OFFSET_UNALIGNED, "Operand %d is unaligned. It must be %d aligned!"},
438 {ERROR_BAD_END, "Operands mismatch, it has a bad end: %s"},
439 {ERROR_UNDEFINE, NULL},
440 {ERROR_CPREG_ILLEGAL, "Operand %d illegal, expect a cpreg(cpr0-cpr63)."},
441 {ERROR_OPCODE_PSRBIT, "The operands must be 'ie'/'ee'/'fe'."},
442 {ERROR_OPERANDS_ILLEGAL, "Operands mismatch: %s."},
443 {ERROR_OPERANDS_NUMBER, "Operands number mismatch, %d operands expected."},
444 {ERROR_OPCODE_ILLEGAL, "The instruction is not recognized."},
445 {WARNING_OPTIONS, "Option %s is not support in %s."},
446 {WARNING_IDLY, "idly %d is encoded to: idly 4 "},
447 {ERROR_NONE, "There is no error."},
448 };
449
450 static int do_pic = 0; /* for jbr/jbf/jbt relax jmpi reloc. */
451 static int do_pff = -1; /* for insert two br ahead of literals. */
452 static int do_force2bsr = -1; /* for jbsr->bsr. */
453 static int do_jsri2bsr = 1; /* for jsri->bsr. */
454 static int do_nolrw = 0; /* lrw to movih & ori, only for V2. */
455 static int do_long_jump = -1; /* control if jbf,jbt,jbr relax to jmpi. */
456 static int do_extend_lrw = -1; /* delete bsr16 in both two options,
457 add btesti16, lrw offset +1 in -melrw. */
458 static int do_func_dump = 0; /* dump literals after every function. */
459 static int do_br_dump = 1; /* work for -mabr/-mno-abr, control the literals dump. */
460 static int do_intr_stack = -1; /* control interrupt stack module, 801&802&803
461 default on, 807&810, default off. */
462 static int float_abi = 0;
463
464 #ifdef INCLUDE_BRANCH_STUB
465 static int do_use_branchstub = -1;
466 #else
467 static int do_use_branchstub = 0;
468 #endif
469
470 /* These are only used for options parsing. Values are bitmasks and are
471 OR'ed into the processor flag bits in md_begin. */
472 static int do_opt_mmp = 0;
473 static int do_opt_mcp = 0;
474 static int do_opt_mcache = 0;
475 static int do_opt_msecurity = 0;
476 static int do_opt_mhard_float = 0;
477 static int do_opt_mtrust = 0;
478 static int do_opt_mdsp = 0;
479 static int do_opt_medsp = 0;
480 static int do_opt_mvdsp = 0;
481
482 const relax_typeS *md_relax_table = NULL;
483 struct literal *literal_insn_offset;
484 static struct literal litpool[MAX_POOL_SIZE];
485 static unsigned poolsize = 0;
486 static unsigned poolnumber = 0;
487 static unsigned long poolspan = 0;
488 static unsigned int SPANPANIC;
489 static unsigned int SPANCLOSE;
490 static unsigned int SPANEXIT;
491
492 static stack_size_entry *all_stack_size_data = NULL;
493 static stack_size_entry **last_stack_size_data = &all_stack_size_data;
494
495 /* Control by ".no_literal_dump N"
496 * 1 : don't dump literal pool between insn1 and insnN+1
497 * 0 : do nothing. */
498 static int do_noliteraldump = 0;
499
500 /* Label for current pool. */
501 static symbolS * poolsym;
502 static char poolname[8];
503
504 static bool mov_r1_before;
505 static bool mov_r1_after;
506
507 const relax_typeS csky_relax_table [] =
508 {
509 /* C-SKY V1 relax table. */
510 {0, 0, 0, 0}, /* RELAX_NONE */
511 {0, 0, 0, 0}, /* RELAX_OVERFLOW */
512 {0, 0, 0, 0},
513 {0, 0, 0, 0},
514
515 /* COND_JUMP */
516 { 0, 0, 0, 0 }, /* UNDEF_DISP */
517 { 2048, -2046, C12_LEN, C (COND_JUMP, DISP32) }, /* DISP12 */
518 { 0, 0, C32_LEN, 0 }, /* DISP32 */
519 { 0, 0, C32_LEN, 0 }, /* UNDEF_WORD_DISP */
520
521 /* UNCD_JUMP */
522 { 0, 0, 0, 0 }, /* UNDEF_DISP */
523 { 2048, -2046, U12_LEN, C (UNCD_JUMP, DISP32) }, /* DISP12 */
524 { 0, 0, U32_LEN, 0 }, /* DISP32 */
525 { 0, 0, U32_LEN, 0 }, /* UNDEF_WORD_DISP */
526
527 /* COND_JUMP_PIC */
528 { 0, 0, 0, 0 }, /* UNDEF_DISP */
529 { 2048, -2046, C12_LEN, C (COND_JUMP_PIC, DISP32) }, /* DISP12 */
530 { 0, 0, C32_LEN_PIC, 0 }, /* DISP32 */
531 { 0, 0, C32_LEN_PIC, 0 }, /* UNDEF_WORD_DISP */
532
533 /* UNCD_JUMP_PIC */
534 { 0, 0, 0, 0 }, /* UNDEF_DISP */
535 { 2048, -2046, U12_LEN, C (UNCD_JUMP_PIC, DISP32) }, /* DISP12 */
536 { 0, 0, U32_LEN_PIC, 0 }, /* DISP32 */
537 { 0, 0, U32_LEN_PIC, 0 }, /* UNDEF_WORD_DISP */
538
539 /* C-SKY V2 relax table. */
540 /* forward backward length more */
541 { 1 KB - 2, -1 KB, COND_DISP10_LEN, COND_DISP16 }, /* COND_DISP10 */
542 { 64 KB - 2, -64 KB, COND_DISP16_LEN, RELAX_OVERFLOW }, /* COND_DISP16 */
543
544 { 1 KB - 2, -1 KB, SCOND_DISP10_LEN, SCOND_DISP16 }, /* SCOND_DISP10 */
545 { 64 KB - 2, -64 KB, SCOND_DISP16_LEN, RELAX_OVERFLOW }, /* SCOND_DISP16 */
546
547 { 1 KB - 2, -1 KB, UNCD_DISP10_LEN, UNCD_DISP16 }, /* UNCD_DISP10 */
548 { 64 KB - 2, -64 KB, UNCD_DISP16_LEN, RELAX_OVERFLOW }, /* UNCD_DISP16 */
549
550 { 1 KB - 2, -1 KB, JCOND_DISP10_LEN, JCOND_DISP16 }, /* JCOND_DISP10 */
551 { 64 KB - 2, -64 KB, JCOND_DISP16_LEN, JCOND_DISP32 }, /* JCOND_DISP16 */
552 { 0, 0, JCOND_DISP32_LEN, RELAX_NONE }, /* JCOND_DISP32 */
553
554 { 1 KB - 2, -1 KB, JUNCD_DISP10_LEN, JUNCD_DISP16 }, /* JUNCD_DISP10 */
555 { 64 KB - 2, -64 KB, JUNCD_DISP16_LEN, JUNCD_DISP32 }, /* JUNCD_DISP16 */
556 { 0, 0, JUNCD_DISP32_LEN, RELAX_NONE }, /* JUNCD_DISP32 */
557
558 { 64 KB - 2, -64 KB, JCOMPZ_DISP16_LEN, JCOMPZ_DISP32 }, /* JCOMPZ_DISP16 */
559 { 0, 0, JCOMPZ_DISP32_LEN, RELAX_NONE }, /* JCOMPZ_DISP32 */
560
561 { 64 MB - 2, -64 MB, BSR_DISP26_LEN, RELAX_OVERFLOW }, /* BSR_DISP26 */
562
563 { 508, 0, LRW_DISP7_LEN, LRW_DISP16 }, /* LRW_DISP7 */
564 { 1016, 0, LRW_DISP7_LEN, LRW_DISP16 }, /* LRW2_DISP8 */
565 { 64 KB, 0, LRW_DISP16_LEN, RELAX_OVERFLOW }, /* LRW_DISP16 */
566
567 };
568
569 static void csky_write_insn (char *ptr, valueT use, int nbytes);
570 void md_number_to_chars (char * buf, valueT val, int n);
571 long md_pcrel_from_section (fixS * fixP, segT seg);
572
573 /* C-SKY architecture table. */
574 const struct csky_arch_info csky_archs[] =
575 {
576 {"ck510", CSKY_ARCH_510, bfd_mach_ck510},
577 {"ck610", CSKY_ARCH_610, bfd_mach_ck610},
578 {"ck801", CSKY_ARCH_801, bfd_mach_ck801},
579 {"ck802", CSKY_ARCH_802, bfd_mach_ck802},
580 {"ck803", CSKY_ARCH_803, bfd_mach_ck803},
581 {"ck807", CSKY_ARCH_807, bfd_mach_ck807},
582 {"ck810", CSKY_ARCH_810, bfd_mach_ck810},
583 {"ck860", CSKY_ARCH_860, bfd_mach_ck860},
584 {NULL, 0, 0}
585 };
586
587 #define CSKY_ARCH_807_BASE CSKY_ARCH_807 | CSKY_ARCH_DSP
588 #define CSKY_ARCH_810_BASE CSKY_ARCH_810 | CSKY_ARCH_DSP
589
590 struct csky_cpu_feature
591 {
592 const char unique;
593 unsigned int arch_flag;
594 uint64_t isa_flag;
595 };
596
597 struct csky_cpu_version
598 {
599 int r;
600 int p;
601 uint64_t isa_flag;
602 };
603
604 #define CSKY_FEATURE_MAX 10
605 #define CSKY_CPU_REVERISON_MAX 10
606
607 struct csky_cpu_info
608 {
609 const char *name;
610 unsigned int arch_flag;
611 uint64_t isa_flag;
612 struct csky_cpu_feature features[CSKY_FEATURE_MAX];
613 struct csky_cpu_version ver[CSKY_CPU_REVERISON_MAX];
614 };
615
616 #define FEATURE_DSP_EXT(isa) \
617 {'e', CSKY_ARCH_DSP, isa}
618 #define FEATURE_DSP(isa) \
619 {'d', CSKY_ARCH_DSP, isa}
620 #define FEATURE_MMU() \
621 {'m', 0, 0}
622 #define FEATURE_VDSP(isa) \
623 {'v', CSKY_ARCH_DSP, isa}
624 #define FEATURE_FLOAT(isa) \
625 {'f', CSKY_ARCH_FLOAT, isa}
626 #define FEATURE_TRUST(isa) \
627 {'t', 0, isa}
628 #define FEATURE_JAVA(isa) \
629 {'j', CSKY_ARCH_JAVA, isa}
630 #define FEATURE_SHIELD(isa) \
631 {'h', 0, isa}
632
633
634 #define CSKY_FEATURES_DEF_NULL() \
635 {{0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}}
636
637 #define CSKY_FEATURES_DEF_e(isa_e) \
638 {FEATURE_DSP_EXT(isa_e), \
639 {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}}
640
641 #define CSKY_FEATURES_DEF_t(isa_t) \
642 {FEATURE_TRUST(isa_t), \
643 {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}}
644
645 #define CSKY_FEATURES_DEF_f(isa_f) \
646 {FEATURE_FLOAT(isa_f), \
647 {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}}
648
649 #define CSKY_FEATURES_DEF_v(isa_v) \
650 {FEATURE_VDSP(isa_v), \
651 {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}}
652
653 #define CSKY_FEATURES_DEF_ef(isa_e, isa_f) \
654 {FEATURE_DSP_EXT(isa_e), \
655 FEATURE_FLOAT(isa_f), \
656 {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}}
657
658 #define CSKY_FEATURES_DEF_jt(isa_j, isa_t) \
659 {FEATURE_JAVA(isa_j), \
660 FEATURE_TRUST(isa_t), \
661 {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}}
662
663 #define CSKY_FEATURES_DEF_efht(isa_e, isa_f, isa_h, isa_t) \
664 {FEATURE_DSP_EXT(isa_e), \
665 FEATURE_FLOAT(isa_f), \
666 FEATURE_SHIELD(isa_h), \
667 FEATURE_TRUST(isa_t), \
668 {0}, {0}, {0}, {0}, {0}, {0}}
669
670 #define CSKY_FEATURES_DEF_efv(isa_e, isa_f, isa_v) \
671 {FEATURE_DSP_EXT(isa_e), \
672 FEATURE_FLOAT(isa_f), \
673 FEATURE_VDSP(isa_v), \
674 {0}, {0}, {0}, {0}, {0}, {0}, {0}}
675
676 #define CSKY_FEATURES_DEF_eft(isa_e, isa_f, isa_t) \
677 {FEATURE_DSP_EXT(isa_e), \
678 FEATURE_FLOAT(isa_f), \
679 FEATURE_TRUST(isa_t), \
680 {0}, {0}, {0}, {0}, {0}, {0}, {0}}
681
682 #define CSKY_FEATURES_DEF_d(isa_d) \
683 {FEATURE_DSP(isa_d), \
684 {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}}
685
686 #define CSKY_FEATURES_DEF_df(isa_d, isa_f) \
687 {FEATURE_DSP(isa_d), \
688 FEATURE_FLOAT(isa_f), \
689 {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}}
690
691 #define CSKY_FEATURES_DEF_ft(isa_f, isa_t) \
692 {FEATURE_FLOAT(isa_f), \
693 FEATURE_TRUST(isa_t), \
694 {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}}
695
696 #define CSKY_FEATURES_DEF_tv(isa_t, isa_v) \
697 {FEATURE_TRUST(isa_t), \
698 FEATURE_VDSP(isa_v), \
699 {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}}
700
701 #define CSKY_FEATURES_DEF_fv(isa_f, isa_v) \
702 {FEATURE_FLOAT(isa_f), \
703 FEATURE_VDSP(isa_v), \
704 {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}}
705
706
707 #define CSKY_FEATURES_DEF_dft(isa_d, isa_f, isa_t) \
708 {FEATURE_DSP(isa_d), \
709 FEATURE_FLOAT(isa_f), \
710 FEATURE_TRUST(isa_t), \
711 {0}, {0}, {0}, {0}, {0}, {0}, {0}}
712
713 #define CSKY_FEATURES_DEF_dfv(isa_d, isa_f, isa_v) \
714 {FEATURE_DSP(isa_d), \
715 FEATURE_FLOAT(isa_f), \
716 FEATURE_VDSP(isa_v), \
717 {0}, {0}, {0}, {0}, {0}, {0}, {0}}
718
719 #define CSKY_FEATURES_DEF_ftv(isa_f, isa_t, isa_v) \
720 {FEATURE_FLOAT(isa_f), \
721 FEATURE_TRUST(isa_t), \
722 FEATURE_VDSP(isa_v), \
723 {0}, {0}, {0}, {0}, {0}, {0}, {0}}
724
725 #define CSKY_FEATURES_DEF_eftv(isa_e, isa_f, isa_t, isa_v) \
726 {FEATURE_DSP_EXT(isa_e), \
727 FEATURE_FLOAT(isa_f), \
728 FEATURE_TRUST(isa_t), \
729 FEATURE_VDSP(isa_v), \
730 {0}, {0}, {0}, {0}, {0}, {0}}
731
732
733 #define CSKY_CPU_REVERISON_r0p0(isa) \
734 {0, 0, 0}
735 #define CSKY_CPU_REVERISON_r1p0(isa) \
736 {1, 0, isa}
737 #define CSKY_CPU_REVERISON_r2p0(isa) \
738 {2, 0, isa}
739 #define CSKY_CPU_REVERISON_r3p0(isa) \
740 {3, 0, isa}
741
742 #define CSKY_CPU_REVERISON_RESERVED() \
743 {{0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}}
744
745 #define CSKY_CPU_REVERISON_R3(isa1, isa2, isa3) \
746 {CSKY_CPU_REVERISON_r1p0(isa1), \
747 CSKY_CPU_REVERISON_r2p0(isa2), \
748 CSKY_CPU_REVERISON_r3p0(isa3), \
749 {0}, {0}, {0}, {0}, {0}, {0}, {0}}
750
751 /* CSKY cpus table. */
752 const struct csky_cpu_info csky_cpus[] =
753 {
754 #define CSKYV1_ISA_DSP (CSKY_ISA_DSP | CSKY_ISA_MAC_DSP)
755 #define CSKY_ISA_510 (CSKYV1_ISA_E1)
756 #define CSKY_ISA_610 (CSKYV1_ISA_E1 | CSKY_ISA_CP)
757 {"ck510",
758 CSKY_ARCH_510,
759 CSKY_ISA_510,
760 CSKY_FEATURES_DEF_e(CSKYV1_ISA_DSP),
761 CSKY_CPU_REVERISON_RESERVED()},
762 {"ck520",
763 CSKY_ARCH_510 | CSKY_ARCH_MAC,
764 CSKY_ISA_510 | CSKY_ISA_MAC | CSKY_ISA_MAC_DSP,
765 CSKY_FEATURES_DEF_NULL(),
766 CSKY_CPU_REVERISON_RESERVED()},
767 {"ck610", CSKY_ARCH_610, CSKY_ISA_610,
768 CSKY_FEATURES_DEF_ef(CSKYV1_ISA_DSP, CSKY_ISA_FLOAT_E1),
769 CSKY_CPU_REVERISON_RESERVED()},
770 {"ck620",
771 CSKY_ARCH_610 | CSKY_ARCH_MAC,
772 CSKY_ISA_610 | CSKY_ISA_MAC | CSKY_ISA_MAC_DSP,
773 CSKY_FEATURES_DEF_NULL(),
774 CSKY_CPU_REVERISON_RESERVED()},
775
776 #define CSKY_ISA_801 (CSKYV2_ISA_E1 | CSKY_ISA_TRUST)
777 #define CSKYV2_ISA_DSP (CSKY_ISA_DSP | CSKY_ISA_DSP_1E2 | CSKY_ISA_DSPE60)
778 {"ck801",
779 CSKY_ARCH_801,
780 CSKY_ISA_801,
781 CSKY_FEATURES_DEF_t(0),
782 CSKY_CPU_REVERISON_RESERVED()},
783 #define CSKY_ISA_802 (CSKY_ISA_801 | CSKYV2_ISA_1E2 | CSKY_ISA_NVIC)
784 {"ck802",
785 CSKY_ARCH_802,
786 CSKY_ISA_802,
787 CSKY_FEATURES_DEF_jt(CSKY_ISA_JAVA, 0),
788 CSKY_CPU_REVERISON_RESERVED()},
789 #define CSKY_ISA_803 (CSKY_ISA_802 | CSKYV2_ISA_2E3 | CSKY_ISA_MP)
790 #define CSKY_ISA_803R1 (CSKYV2_ISA_3E3R1)
791 #define CSKY_ISA_803R2 (CSKYV2_ISA_3E3R1 | CSKYV2_ISA_3E3R2)
792 #define CSKY_ISA_803R3 (CSKYV2_ISA_3E3R1 | CSKYV2_ISA_3E3R2 | CSKYV2_ISA_3E3R3)
793 #define CSKY_ISA_FLOAT_803 (CSKY_ISA_FLOAT_E1 | CSKY_ISA_FLOAT_1E3)
794 #define CSKY_ISA_EDSP (CSKYV2_ISA_3E3R1 | CSKYV2_ISA_3E3R3 | CSKY_ISA_DSP_ENHANCE)
795 {"ck803s",
796 CSKY_ARCH_803,
797 CSKY_ISA_803 | CSKY_ISA_803R1,
798 CSKY_FEATURES_DEF_eft(CSKYV2_ISA_DSP, CSKY_ISA_FLOAT_803, 0),
799 CSKY_CPU_REVERISON_RESERVED()},
800 {"ck803",
801 CSKY_ARCH_803,
802 CSKY_ISA_803,
803 CSKY_FEATURES_DEF_efht(CSKYV2_ISA_DSP, CSKY_ISA_FLOAT_803, 0, 0),
804 CSKY_CPU_REVERISON_R3(CSKY_ISA_803R1, CSKY_ISA_803R2, CSKY_ISA_803R3)},
805 #define CSKY_ISA_804 (CSKY_ISA_803 | CSKY_ISA_803R3)
806 {"ck804",
807 CSKY_ARCH_804,
808 CSKY_ISA_804,
809 CSKY_FEATURES_DEF_efht(CSKY_ISA_EDSP, CSKY_ISA_FLOAT_803, 0, 0),
810 CSKY_CPU_REVERISON_RESERVED()},
811 #define CSKY_ISA_805 (CSKY_ISA_804 | CSKY_ISA_VDSP_2)
812 #define CSKY_ARCH_805V (CSKY_ARCH_805 | CSKY_ARCH_DSP)
813 #define CSKY_ISA_FLOAT_805 CSKY_ISA_FLOAT_803
814 {"ck805",
815 CSKY_ARCH_805,
816 CSKY_ISA_805,
817 CSKY_FEATURES_DEF_eft(CSKY_ISA_EDSP, CSKY_ISA_FLOAT_805, 0),
818 CSKY_CPU_REVERISON_RESERVED()},
819 #define CSKY_ISA_807 (CSKY_ISA_803 | CSKYV2_ISA_3E7 | CSKY_ISA_MP_1E2 | CSKY_ISA_CACHE | CSKYV2_ISA_DSP)
820 #define CSKY_ISA_FLOAT_807 (CSKY_ISA_FLOAT_803 | CSKY_ISA_FLOAT_3E4 | CSKY_ISA_FLOAT_1E2)
821 {"ck807",
822 CSKY_ARCH_807,
823 CSKY_ISA_807,
824 CSKY_FEATURES_DEF_ef(CSKYV2_ISA_DSP, CSKY_ISA_FLOAT_807),
825 CSKY_CPU_REVERISON_RESERVED()},
826 #define CSKY_ISA_810 (CSKY_ISA_807 | CSKYV2_ISA_7E10)
827 #define CSKY_ISA_FLOAT_810 (CSKY_ISA_FLOAT_E1 | CSKY_ISA_FLOAT_1E2)
828 {"ck810v",
829 CSKY_ARCH_810 | CSKY_ARCH_DSP,
830 CSKY_ISA_810 | CSKY_ISA_VDSP,
831 CSKY_FEATURES_DEF_NULL (),
832 CSKY_CPU_REVERISON_RESERVED()},
833 {"ck810",
834 CSKY_ARCH_810,
835 CSKY_ISA_810,
836 CSKY_FEATURES_DEF_eftv(0, CSKY_ISA_FLOAT_810, 0, CSKY_ISA_VDSP),
837 CSKY_CPU_REVERISON_RESERVED()},
838 #define CSKY_ISA_860 ((CSKY_ISA_810 & ~(CSKYV2_ISA_DSP)) | CSKYV2_ISA_10E60 | CSKY_ISA_803R3 | CSKY_ISA_DSPE60)
839 #define CSKY_ISA_860F (CSKY_ISA_860 | CSKY_ISA_FLOAT_7E60)
840 #define CSKY_ISA_VDSP_860 (CSKY_ISA_VDSP_2)
841 {"ck860v",
842 CSKY_ARCH_860 | CSKY_ARCH_DSP,
843 CSKY_ISA_860 | CSKY_ISA_VDSP_860,
844 CSKY_FEATURES_DEF_f(CSKY_ISA_FLOAT_7E60),
845 CSKY_CPU_REVERISON_RESERVED()},
846 {"ck860",
847 CSKY_ARCH_860,
848 CSKY_ISA_860,
849 CSKY_FEATURES_DEF_fv(CSKY_ISA_FLOAT_7E60, CSKY_ISA_VDSP_860),
850 CSKY_CPU_REVERISON_RESERVED()},
851
852 /* It is a special cpu, support all instructions. */
853 #define CSKY_ISA_800 (CSKY_ISA_860 | CSKY_ISA_810 | CSKY_ISA_807 | CSKY_ISA_803)
854 {"ck800",
855 CSKY_ARCH_800,
856 CSKY_ISA_800,
857 CSKY_FEATURES_DEF_NULL(),
858 CSKY_CPU_REVERISON_RESERVED()},
859
860
861 #define CSKY_ISA_E801 (CSKY_ISA_801)
862 #define CSKY_ISA_E802 (CSKY_ISA_E801 | CSKYV2_ISA_1E2 | CSKY_ISA_NVIC)
863 #define CSKY_ISA_E803 (CSKY_ISA_E802 | CSKYV2_ISA_2E3 | CSKY_ISA_MP | CSKYV2_ISA_3E3R1 | CSKYV2_ISA_3E3R2 | CSKYV2_ISA_3E3R3)
864 #define CSKY_ISA_E804 (CSKY_ISA_E803)
865 #define CSKY_ISA_FLOAT_V1 (CSKY_ISA_FLOAT_E1 | CSKY_ISA_FLOAT_1E3)
866 {"e801",
867 CSKY_ARCH_801,
868 CSKY_ISA_E801,
869 CSKY_FEATURES_DEF_NULL(),
870 CSKY_CPU_REVERISON_RESERVED()},
871 {"e802",
872 CSKY_ARCH_802,
873 CSKY_ISA_E802,
874 CSKY_FEATURES_DEF_t(0),
875 CSKY_CPU_REVERISON_RESERVED()},
876 {"e803",
877 CSKY_ARCH_803,
878 CSKY_ISA_E803,
879 CSKY_FEATURES_DEF_t(0),
880 CSKY_CPU_REVERISON_RESERVED()},
881 {"e804",
882 CSKY_ARCH_804,
883 CSKY_ISA_E804,
884 CSKY_FEATURES_DEF_dft(CSKY_ISA_EDSP, CSKY_ISA_FLOAT_V1, 0),
885 CSKY_CPU_REVERISON_RESERVED()},
886
887 #define CSKY_ISA_S802 (CSKY_ISA_E801 | CSKYV2_ISA_1E2 | CSKY_ISA_NVIC | CSKY_ISA_TRUST)
888 #define CSKY_ISA_S803 (CSKY_ISA_S802 | CSKYV2_ISA_2E3 | CSKY_ISA_MP | CSKYV2_ISA_3E3R1 | CSKYV2_ISA_3E3R2 | CSKYV2_ISA_3E3R3)
889 {"s802",
890 CSKY_ARCH_802,
891 CSKY_ISA_S802,
892 CSKY_FEATURES_DEF_t(0),
893 CSKY_CPU_REVERISON_RESERVED()},
894 {"s803",
895 CSKY_ARCH_803,
896 CSKY_ISA_S803,
897 CSKY_FEATURES_DEF_t(0),
898 CSKY_CPU_REVERISON_RESERVED()},
899 #define CSKY_ISA_I805 (CSKY_ISA_S803)
900 {"i805",
901 CSKY_ARCH_805 | CSKY_ARCH_DSP,
902 CSKY_ISA_I805 | CSKY_ISA_VDSP_2,
903 CSKY_FEATURES_DEF_ft(CSKY_ISA_FLOAT_V1, 0),
904 CSKY_CPU_REVERISON_RESERVED()},
905 #define CSKYV2_ISA_DSP (CSKY_ISA_DSP | CSKY_ISA_DSP_1E2 | CSKY_ISA_DSPE60)
906 #define CSKY_ISA_C807 (CSKY_ISA_E802 | CSKYV2_ISA_2E3 | CSKY_ISA_MP | CSKYV2_ISA_3E7 | CSKY_ISA_MP_1E2 | CSKY_ISA_CACHE | CSKYV2_ISA_DSP)
907 #define CSKY_ISA_FLOAT_C807 (CSKY_ISA_FLOAT_V1 | CSKY_ISA_FLOAT_3E4 | CSKY_ISA_FLOAT_1E2)
908 #define CSKY_ISA_FLOAT_C810 (CSKY_ISA_FLOAT_E1 | CSKY_ISA_FLOAT_1E2)
909 #define CSKY_ARCH_C810 (CSKY_ARCH_810 | CSKY_ARCH_FLOAT)
910 #define CSKY_ISA_C810 (CSKY_ISA_C807 | CSKYV2_ISA_7E10 | CSKY_ISA_FLOAT_C810)
911 #define CSKY_ARCH_C860 (CSKY_ARCH_860 | CSKY_ARCH_FLOAT)
912 #define CSKY_ISA_C860 (CSKY_ISA_860 | CSKY_ISA_FLOAT_7E60)
913 {"c807",
914 CSKY_ARCH_807,
915 CSKY_ISA_C807,
916 CSKY_FEATURES_DEF_fv(CSKY_ISA_FLOAT_C807, CSKY_ISA_VDSP),
917 CSKY_CPU_REVERISON_RESERVED()},
918 {"c810",
919 CSKY_ARCH_C810,
920 CSKY_ISA_C810,
921 CSKY_FEATURES_DEF_tv(0, CSKY_ISA_VDSP),
922 CSKY_CPU_REVERISON_RESERVED()},
923 {"c860",
924 CSKY_ARCH_C860,
925 CSKY_ISA_C860,
926 CSKY_FEATURES_DEF_v(CSKY_ISA_VDSP_2),
927 CSKY_CPU_REVERISON_RESERVED()},
928 #define CSKY_ISA_R807 (CSKY_ISA_E802 | CSKYV2_ISA_2E3 | CSKY_ISA_MP | CSKYV2_ISA_3E7 | CSKY_ISA_MP_1E2 | CSKY_ISA_CACHE | CSKYV2_ISA_DSP)
929 #define CSKY_ISA_FLOAT_R807 (CSKY_ISA_FLOAT_V1 | CSKY_ISA_FLOAT_3E4 | CSKY_ISA_FLOAT_1E2)
930 {"r807",
931 CSKY_ARCH_807,
932 CSKY_ISA_R807,
933 CSKY_FEATURES_DEF_f(CSKY_ISA_FLOAT_R807),
934 CSKY_CPU_REVERISON_RESERVED()},
935
936 /* Start of private CPUs. */
937 /* End of private CPUs. */
938
939 {NULL},
940 };
941
942 int md_short_jump_size = 2;
943 int md_long_jump_size = 4;
944
945 /* This array holds the chars that always start a comment. If the
946 pre-processor is disabled, these aren't very useful. */
947 const char comment_chars[] = "#";
948
949 /* This array holds the chars that only start a comment at the beginning of
950 a line. If the line seems to have the form '# 123 filename'
951 .line and .file directives will appear in the pre-processed output. */
952 /* Note that input_file.c hand checks for '#' at the beginning of the
953 first line of the input file. This is because the compiler outputs
954 #NO_APP at the beginning of its output. */
955 /* Also note that comments like this one will always work. */
956 const char line_comment_chars[] = "#";
957
958 const char line_separator_chars[] = ";";
959
960 /* Chars that can be used to separate mant
961 from exp in floating point numbers. */
962 const char EXP_CHARS[] = "eE";
963
964 /* Chars that mean this number is a floating point constant.
965 As in 0f12.456
966 or 0d1.2345e12 */
967
968 const char FLT_CHARS[] = "rRsSfFdDxXeEpP";
969
970 const char *md_shortopts = "";
971
972 struct option md_longopts[] = {
973 #define OPTION_MARCH (OPTION_MD_BASE + 0)
974 {"march", required_argument, NULL, OPTION_MARCH},
975 #define OPTION_MCPU (OPTION_MD_BASE + 1)
976 {"mcpu", required_argument, NULL, OPTION_MCPU},
977 #define OPTION_FLOAT_ABI (OPTION_MD_BASE + 2)
978 {"mfloat-abi", required_argument, NULL, OPTION_FLOAT_ABI},
979
980 /* Remaining options just set boolean flags. */
981 {"EL", no_argument, &target_big_endian, 0},
982 {"mlittle-endian", no_argument, &target_big_endian, 0},
983 {"EB", no_argument, &target_big_endian, 1},
984 {"mbig-endian", no_argument, &target_big_endian, 1},
985 {"fpic", no_argument, &do_pic, 1},
986 {"pic", no_argument, &do_pic, 1},
987 {"mljump", no_argument, &do_long_jump, 1},
988 {"mno-ljump", no_argument, &do_long_jump, 0},
989 {"force2bsr", no_argument, &do_force2bsr, 1},
990 {"mforce2bsr", no_argument, &do_force2bsr, 1},
991 {"no-force2bsr", no_argument, &do_force2bsr, 0},
992 {"mno-force2bsr", no_argument, &do_force2bsr, 0},
993 {"jsri2bsr", no_argument, &do_jsri2bsr, 1},
994 {"mjsri2bsr", no_argument, &do_jsri2bsr, 1},
995 {"no-jsri2bsr", no_argument, &do_jsri2bsr, 0},
996 {"mno-jsri2bsr", no_argument, &do_jsri2bsr, 0},
997 {"mnolrw", no_argument, &do_nolrw, 1},
998 {"mno-lrw", no_argument, &do_nolrw, 1},
999 {"melrw", no_argument, &do_extend_lrw, 1},
1000 {"mno-elrw", no_argument, &do_extend_lrw, 0},
1001 {"mlaf", no_argument, &do_func_dump, 1},
1002 {"mliterals-after-func", no_argument, &do_func_dump, 1},
1003 {"mno-laf", no_argument, &do_func_dump, 0},
1004 {"mno-literals-after-func", no_argument, &do_func_dump, 0},
1005 {"mlabr", no_argument, &do_br_dump, 1},
1006 {"mliterals-after-br", no_argument, &do_br_dump, 1},
1007 {"mno-labr", no_argument, &do_br_dump, 0},
1008 {"mnoliterals-after-br", no_argument, &do_br_dump, 0},
1009 {"mistack", no_argument, &do_intr_stack, 1},
1010 {"mno-istack", no_argument, &do_intr_stack, 0},
1011 #ifdef INCLUDE_BRANCH_STUB
1012 {"mbranch-stub", no_argument, &do_use_branchstub, 1},
1013 {"mno-branch-stub", no_argument, &do_use_branchstub, 0},
1014 #endif
1015 {"mhard-float", no_argument, &do_opt_mhard_float, CSKY_ARCH_FLOAT},
1016 {"mmp", no_argument, &do_opt_mmp, CSKY_ARCH_MP},
1017 {"mcp", no_argument, &do_opt_mcp, CSKY_ARCH_CP},
1018 {"mcache", no_argument, &do_opt_mcache, CSKY_ARCH_CACHE},
1019 {"msecurity", no_argument, &do_opt_msecurity, CSKY_ARCH_MAC},
1020 {"mtrust", no_argument, &do_opt_mtrust, CSKY_ISA_TRUST},
1021 {"mdsp", no_argument, &do_opt_mdsp, CSKY_DSP_FLAG_V1},
1022 {"medsp", no_argument, &do_opt_medsp, CSKY_DSP_FLAG_V2},
1023 {"mvdsp", no_argument, &do_opt_mvdsp, CSKY_ISA_VDSP},
1024 };
1025
1026 size_t md_longopts_size = sizeof (md_longopts);
1027
1028 static struct csky_insn_info csky_insn;
1029
1030 static htab_t csky_opcodes_hash;
1031 static htab_t csky_macros_hash;
1032
1033 static struct csky_macro_info v1_macros_table[] =
1034 {
1035 {"idly", 1, CSKYV1_ISA_E1, csky_idly},
1036 {"rolc", 2, CSKYV1_ISA_E1, csky_rolc},
1037 {"rotlc", 2, CSKYV1_ISA_E1, csky_rolc},
1038 {"sxtrb0", 2, CSKYV1_ISA_E1, csky_sxtrb},
1039 {"sxtrb1", 2, CSKYV1_ISA_E1, csky_sxtrb},
1040 {"sxtrb2", 2, CSKYV1_ISA_E1, csky_sxtrb},
1041 {"movtf", 3, CSKYV1_ISA_E1, csky_movtf},
1042 {"addc64", 3, CSKYV1_ISA_E1, csky_addc64},
1043 {"subc64", 3, CSKYV1_ISA_E1, csky_subc64},
1044 {"or64", 3, CSKYV1_ISA_E1, csky_or64},
1045 {"xor64", 3, CSKYV1_ISA_E1, csky_xor64},
1046 {NULL,0,0,0}
1047 };
1048
1049 static struct csky_macro_info v2_macros_table[] =
1050 {
1051 {"neg", 1, CSKYV2_ISA_E1, csky_neg},
1052 {"rsubi", 2, CSKYV2_ISA_1E2, csky_rsubi},
1053 {"incf", 1, CSKYV2_ISA_1E2, csky_arith},
1054 {"inct", 1, CSKYV2_ISA_1E2, csky_arith},
1055 {"decf", 1, CSKYV2_ISA_2E3, csky_arith},
1056 {"decgt", 1, CSKYV2_ISA_2E3, csky_arith},
1057 {"declt", 1, CSKYV2_ISA_2E3, csky_arith},
1058 {"decne", 1, CSKYV2_ISA_1E2, csky_decne},
1059 {"dect", 1, CSKYV2_ISA_1E2, csky_arith},
1060 {"lslc", 1, CSKYV2_ISA_1E2, csky_arith},
1061 {"lsrc", 1, CSKYV2_ISA_1E2, csky_arith},
1062 {"xsr", 1, CSKYV2_ISA_1E2, csky_arith},
1063 {NULL,0,0,0}
1064 };
1065
1066 /* For option -mnolrw, replace lrw by movih & ori. */
1067 static struct csky_macro_info v2_lrw_macro_opcode =
1068 {"lrw", 2, CSKYV2_ISA_1E2, csky_lrw};
1069
1070 /* This function is used to show errors or warnings. */
1071
1072 static void
1073 csky_show_error (enum error_number err, int idx, void *arg1, void *arg2)
1074 {
1075 if (err == ERROR_NONE)
1076 return;
1077
1078 switch (err)
1079 {
1080 case ERROR_REG_LIST:
1081 case ERROR_OPCODE_PSRBIT:
1082 case ERROR_OPCODE_ILLEGAL:
1083 case ERROR_JMPIX_OVER_RANGE:
1084 case ERROR_MISSING_COMMA:
1085 case ERROR_MISSING_LBRACKET:
1086 case ERROR_MISSING_RBRACKET:
1087 case ERROR_MISSING_LSQUARE_BRACKETS:
1088 case ERROR_MISSING_RSQUARE_BRACKETS:
1089 case ERROR_MISSING_LANGLE_BRACKETS:
1090 case ERROR_MISSING_RANGLE_BRACKETS:
1091 /* Add NULL to fix warnings. */
1092 as_bad (_(err_formats[err].fmt), NULL);
1093 break;
1094 case ERROR_CREG_ILLEGAL:
1095 case ERROR_GREG_ILLEGAL:
1096 case ERROR_IMM_ILLEGAL:
1097 case ERROR_IMM_OVERFLOW:
1098 case ERROR_EXP_CREG:
1099 case ERROR_EXP_GREG:
1100 case ERROR_EXP_CONSTANT:
1101 case ERROR_EXP_EVEN_FREG:
1102 case ERROR_MISSING_OPERAND:
1103 case ERROR_CPREG_ILLEGAL:
1104 as_bad (_(err_formats[err].fmt), idx);
1105 break;
1106 case ERROR_OPERANDS_NUMBER:
1107 case ERROR_IMM_POWER:
1108 as_bad (_(err_formats[err].fmt), error_state.arg_int);
1109 break;
1110
1111 case ERROR_OFFSET_UNALIGNED:
1112 as_bad (_(err_formats[err].fmt), idx, error_state.arg_int);
1113 break;
1114 case ERROR_RELOC_ILLEGAL:
1115 case ERROR_BAD_END:
1116 case ERROR_OPERANDS_ILLEGAL:
1117 as_bad (_(err_formats[err].fmt), (char *)arg1);
1118 break;
1119 case ERROR_REG_OVER_RANGE:
1120 case ERROR_FREG_OVER_RANGE:
1121 case ERROR_VREG_OVER_RANGE:
1122 as_bad (_(err_formats[err].fmt), idx, error_state.arg_int);
1123 break;
1124 case ERROR_802J_REG_OVER_RANGE:
1125 case ERROR_REG_FORMAT:
1126 as_bad (_(err_formats[err].fmt), idx, (char *)arg1);
1127 break;
1128 case ERROR_UNDEFINE:
1129 /* Add NULL to fix warnings. */
1130 as_bad ((char *)arg1, NULL);
1131 break;
1132 case WARNING_IDLY:
1133 as_warn (_(err_formats[err].fmt), (long)arg1);
1134 break;
1135 case WARNING_OPTIONS:
1136 as_warn (_(err_formats[err].fmt), (char *)arg1, (char *)arg2);
1137 break;
1138 default:
1139 break;
1140 }
1141 }
1142
1143 /* Handle errors in branch relaxation. */
1144
1145 static void
1146 csky_branch_report_error (const char* file, unsigned int line,
1147 symbolS* sym, offsetT val)
1148 {
1149 as_bad_where (file ? file : _("unknown"),
1150 line,
1151 _("pcrel offset for branch to %s too far (0x%lx)"),
1152 sym ? S_GET_NAME (sym) : _("<unknown>"),
1153 (long) val);
1154 }
1155
1156 /* Set appropriate flags for the cpu matching STR. */
1157
1158 static void
1159 parse_cpu (const char *str)
1160 {
1161 int i = 0;
1162
1163 for (; csky_cpus[i].name != NULL; i++)
1164 if (strncasecmp (str, csky_cpus[i].name, strlen (csky_cpus[i].name)) == 0)
1165 {
1166 csky_insn.cpu = &csky_cpus[i];
1167 mach_flag |= csky_cpus[i].arch_flag;
1168 isa_flag = csky_cpus[i].isa_flag;
1169 const char *s = str + strlen (csky_cpus[i].name);
1170 while (*s)
1171 {
1172 const struct csky_cpu_feature *feature = csky_cpus[i].features;
1173 const struct csky_cpu_version *version = csky_cpus[i].ver;
1174 char *next;
1175
1176 if (*s == 'r')
1177 {
1178 s++;
1179 while (version->r)
1180 {
1181 if (version->r == strtol (s, &next, 10))
1182 break;
1183 version++;
1184 }
1185 if (version->r)
1186 {
1187 isa_flag |= version->isa_flag;
1188 s = next;
1189 }
1190 else
1191 goto unknown_cpu;
1192 isa_flag = isa_flag & ~CSKYV2_ISA_DSP;
1193 isa_flag |= CSKY_ISA_EDSP;
1194 continue;
1195 }
1196
1197 /* Parse csky features. */
1198 while (feature->unique)
1199 {
1200 if (feature->unique == *s)
1201 break;
1202 feature++;
1203 }
1204 if (feature->unique)
1205 {
1206 isa_flag |= feature->isa_flag;
1207 mach_flag |= feature->arch_flag;
1208 }
1209 else
1210 goto unknown_cpu;
1211
1212 s++;
1213 }
1214 return;
1215 }
1216
1217 unknown_cpu:
1218 as_bad (_("unknown cpu `%s'"), str);
1219 }
1220
1221 /* Set appropriate flags for the arch matching STR. */
1222
1223 static void
1224 parse_arch (const char *str)
1225 {
1226 int i = 0;
1227 for (; csky_cpus[i].name != NULL; i++)
1228 if (strcasecmp (str, csky_cpus[i].name) == 0)
1229 {
1230 csky_insn.cpu = &csky_cpus[i];
1231 arch_flag |= csky_cpus[i].arch_flag;
1232 isa_flag |= csky_cpus[i].isa_flag;
1233 return;
1234 }
1235 as_bad (_("unknown architecture `%s'"), str);
1236 }
1237
1238 struct csky_option_value_table
1239 {
1240 const char *name;
1241 long value;
1242 };
1243
1244 static const struct csky_option_value_table csky_float_abis[] =
1245 {
1246 {"hard", VAL_CSKY_FPU_ABI_HARD},
1247 {"softfp", VAL_CSKY_FPU_ABI_SOFTFP},
1248 {"soft", VAL_CSKY_FPU_ABI_SOFT},
1249 {NULL, 0}
1250 };
1251
1252 static bool
1253 parse_float_abi (const char *str)
1254 {
1255 const struct csky_option_value_table * opt;
1256
1257 for (opt = csky_float_abis; opt->name != NULL; opt++)
1258 if (strcasecmp (opt->name, str) == 0)
1259 {
1260 float_abi = opt->value;
1261 return true;
1262 }
1263
1264 as_bad (_("unknown floating point abi `%s'\n"), str);
1265 return false;
1266 }
1267
1268 #ifdef OBJ_ELF
1269 /* Implement the TARGET_FORMAT macro. */
1270
1271 const char *
1272 elf32_csky_target_format (void)
1273 {
1274 return (target_big_endian
1275 ? "elf32-csky-big"
1276 : "elf32-csky-little");
1277 }
1278 #endif
1279
1280 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
1281 for use in the a.out file, and stores them in the array pointed to by buf.
1282 This knows about the endian-ness of the target machine and does
1283 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
1284 2 (short) and 4 (long) Floating numbers are put out as a series of
1285 LITTLENUMS (shorts, here at least). */
1286
1287 void
1288 md_number_to_chars (char * buf, valueT val, int n)
1289 {
1290 if (target_big_endian)
1291 number_to_chars_bigendian (buf, val, n);
1292 else
1293 number_to_chars_littleendian (buf, val, n);
1294 }
1295
1296 /* Get a log2(val). */
1297
1298 static int
1299 csky_log_2 (unsigned int val)
1300 {
1301 int log = -1;
1302 if ((val & (val - 1)) == 0)
1303 for (; val; val >>= 1)
1304 log ++;
1305 else
1306 csky_show_error (ERROR_IMM_POWER, 0, (void *)(long)val, NULL);
1307 return log;
1308 }
1309
1310 /* Output one instruction to the buffer at PTR. */
1311
1312 static void
1313 csky_write_insn (char *ptr, valueT use, int nbytes)
1314 {
1315 if (nbytes == 2)
1316 md_number_to_chars (ptr, use, nbytes);
1317 else /* 32-bit instruction. */
1318 {
1319 /* Significant figures are in low bits. */
1320 md_number_to_chars (ptr, use >> 16, 2);
1321 md_number_to_chars (ptr + 2, use & 0xFFFF, 2);
1322 }
1323 }
1324
1325 /* Read an NBYTES instruction from the buffer at PTR. NBYTES should
1326 be either 2 or 4. This function is used in branch relaxation. */
1327
1328 static valueT
1329 csky_read_insn (char *ptr, int nbytes)
1330 {
1331 unsigned char *uptr = (unsigned char *)ptr;
1332 valueT v = 0;
1333 int lo, hi; /* hi/lo byte index in binary stream. */
1334
1335 if (target_big_endian)
1336 {
1337 hi = 0;
1338 lo = 1;
1339 }
1340 else
1341 {
1342 hi = 1;
1343 lo = 0;
1344 }
1345 v = uptr[lo] | (uptr[hi] << 8);
1346 if (nbytes == 4)
1347 {
1348 v <<= 16;
1349 v |= uptr[lo + 2] | (uptr[hi + 2] << 8);
1350 }
1351 return v;
1352 }
1353
1354 /* Construct a label name into S from the 3-character prefix P and
1355 number N formatted as a 4-digit hex number. */
1356
1357 static void
1358 make_internal_label (char *s, const char *p, int n)
1359 {
1360 static const char hex[] = "0123456789ABCDEF";
1361
1362 s[0] = p[0];
1363 s[1] = p[1];
1364 s[2] = p[2];
1365 s[3] = hex[(n >> 12) & 0xF];
1366 s[4] = hex[(n >> 8) & 0xF];
1367 s[5] = hex[(n >> 4) & 0xF];
1368 s[6] = hex[(n) & 0xF];
1369 s[7] = 0;
1370 }
1371
1372 /* md_operand is a no-op on C-SKY; we do everything elsewhere. */
1373
1374 void
1375 md_operand (expressionS *expressionP ATTRIBUTE_UNUSED)
1376 {
1377 return;
1378 }
1379
1380 /* Under ELF we need to default _GLOBAL_OFFSET_TABLE.
1381 Otherwise we have no need to default values of symbols. */
1382
1383 symbolS *
1384 md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
1385 {
1386 #ifdef OBJ_ELF
1387 /* TODO: */
1388 #endif
1389 return NULL;
1390 }
1391
1392 /* Use IEEE format for floating-point constants. */
1393
1394 const char *
1395 md_atof (int type, char *litP, int *sizeP)
1396 {
1397 return ieee_md_atof (type, litP, sizeP, target_big_endian);
1398 }
1399
1400 /* Print option help to FP. */
1401
1402 void
1403 md_show_usage (FILE *fp)
1404 {
1405 int i, n;
1406 const int margin = 48;
1407
1408 fprintf (fp, _("C-SKY assembler options:\n"));
1409
1410 fprintf (fp, _("\
1411 -march=ARCH select architecture ARCH:"));
1412 for (i = 0, n = margin; csky_archs[i].name != NULL; i++)
1413 {
1414 int l = strlen (csky_archs[i].name);
1415 if (n + l >= margin)
1416 {
1417 fprintf (fp, "\n\t\t\t\t");
1418 n = l;
1419 }
1420 else
1421 {
1422 fprintf (fp, " ");
1423 n += l + 1;
1424 }
1425 fprintf (fp, "%s", csky_archs[i].name);
1426 }
1427 fprintf (fp, "\n");
1428
1429 fprintf (fp, _("\
1430 -mcpu=CPU select processor CPU:"));
1431 const struct csky_cpu_feature *feature = NULL;
1432 const struct csky_cpu_version *version = NULL;
1433 for (i = 0; csky_cpus[i].name != NULL; i++)
1434 {
1435 fprintf (fp, "\t\t\t\t%s", csky_cpus[i].name);
1436 feature = csky_cpus[i].features;
1437 version = csky_cpus[i].ver;
1438 while (feature->unique)
1439 {
1440 if ((feature + 1)->unique)
1441 fprintf (fp, "[%c]", feature->unique);
1442 feature++;
1443 }
1444 while (version->r)
1445 {
1446 if (csky_cpus[i].name[0] == 'c'
1447 && csky_cpus[i].name[1] == 'k')
1448 fprintf (fp, "[r%d]", version->r);
1449 else
1450 fprintf (fp, "[-r%dp%d]", version->r, version->p);
1451 version++;
1452 }
1453 }
1454 fprintf (fp, "\n");
1455
1456 fprintf (fp, _("\
1457 -mfloat-abi=ABI select float ABI:"));
1458 for (i = 0, n = margin; csky_float_abis[i].name != NULL; i++)
1459 {
1460 int l = strlen (csky_float_abis[i].name);
1461 if (n + l >= margin)
1462 {
1463 fprintf (fp, "\n\t\t\t\t");
1464 n = l;
1465 }
1466 else
1467 {
1468 fprintf (fp, " ");
1469 n += l + 1;
1470 }
1471 fprintf (fp, "%s", csky_float_abis[i].name);
1472 }
1473 fprintf (fp, "\n");
1474
1475 fprintf (fp, _("\
1476 -EL -mlittle-endian generate little-endian output\n"));
1477 fprintf (fp, _("\
1478 -EB -mbig-endian generate big-endian output\n"));
1479 fprintf (fp, _("\
1480 -fpic -pic generate position-independent code\n"));
1481
1482 fprintf (fp, _("\
1483 -mljump transform jbf, jbt, jbr to jmpi (CK800 only)\n"));
1484 fprintf (fp, _("\
1485 -mno-ljump\n"));
1486
1487 #ifdef INCLUDE_BRANCH_STUB
1488 fprintf (fp, _("\
1489 -mbranch-stub enable branch stubs for PC-relative calls\n"));
1490 fprintf (fp, _("\
1491 -mno-branch-stub\n"));
1492 #endif
1493
1494 fprintf (fp, _("\
1495 -force2bsr -mforce2bsr transform jbsr to bsr\n"));
1496 fprintf (fp, _("\
1497 -no-force2bsr -mno-force2bsr\n"));
1498 fprintf (fp, _("\
1499 -jsri2bsr -mjsri2bsr transform jsri to bsr\n"));
1500 fprintf (fp, _("\
1501 -no-jsri2bsr -mno-jsri2bsr\n"));
1502
1503 fprintf (fp, _("\
1504 -mnolrw -mno-lrw implement lrw as movih + ori\n"));
1505 fprintf (fp, _("\
1506 -melrw enable extended lrw (CK800 only)\n"));
1507 fprintf (fp, _("\
1508 -mno-elrw\n"));
1509
1510 fprintf (fp, _("\
1511 -mlaf -mliterals-after-func emit literals after each function\n"));
1512 fprintf (fp, _("\
1513 -mno-laf -mno-literals-after-func\n"));
1514 fprintf (fp, _("\
1515 -mlabr -mliterals-after-br emit literals after branch instructions\n"));
1516 fprintf (fp, _("\
1517 -mno-labr -mnoliterals-after-br\n"));
1518
1519 fprintf (fp, _("\
1520 -mistack enable interrupt stack instructions\n"));
1521 fprintf (fp, _("\
1522 -mno-istack\n"));
1523
1524 fprintf (fp, _("\
1525 -mhard-float enable hard float instructions\n"));
1526 fprintf (fp, _("\
1527 -mmp enable multiprocessor instructions\n"));
1528 fprintf (fp, _("\
1529 -mcp enable coprocessor instructions\n"));
1530 fprintf (fp, _("\
1531 -mcache enable cache prefetch instruction\n"));
1532 fprintf (fp, _("\
1533 -msecurity enable security instructions\n"));
1534 fprintf (fp, _("\
1535 -mtrust enable trust instructions\n"));
1536 fprintf (fp, _("\
1537 -mdsp enable DSP instructions\n"));
1538 fprintf (fp, _("\
1539 -medsp enable enhanced DSP instructions\n"));
1540 fprintf (fp, _("\
1541 -mvdsp enable vector DSP instructions\n"));
1542 }
1543
1544 static bool
1545 set_csky_attribute (void)
1546 {
1547 if (mach_flag & CSKY_ARCH_DSP)
1548 {
1549 if (dsp_flag & CSKY_DSP_FLAG_V2)
1550 {
1551 /* Set DSPV2. */
1552 if (!bfd_elf_add_obj_attr_int (stdoutput, OBJ_ATTR_PROC,
1553 Tag_CSKY_DSP_VERSION,
1554 VAL_CSKY_DSP_VERSION_2))
1555 return false;
1556 }
1557 else if (isa_flag & CSKY_ISA_DSP)
1558 {
1559 /* Set DSP extension. */
1560 if (!bfd_elf_add_obj_attr_int (stdoutput, OBJ_ATTR_PROC,
1561 Tag_CSKY_DSP_VERSION,
1562 VAL_CSKY_DSP_VERSION_EXTENSION))
1563 return false;
1564 }
1565 /* Set VDSP attribute. */
1566 if (isa_flag & CSKY_ISA_VDSP)
1567 {
1568 if (!bfd_elf_add_obj_attr_int (stdoutput, OBJ_ATTR_PROC,
1569 Tag_CSKY_VDSP_VERSION,
1570 VAL_CSKY_VDSP_VERSION_1))
1571 return false;
1572 }
1573 else if (isa_flag & CSKY_ISA_VDSP_2)
1574 {
1575 if (!bfd_elf_add_obj_attr_int (stdoutput, OBJ_ATTR_PROC,
1576 Tag_CSKY_VDSP_VERSION,
1577 VAL_CSKY_VDSP_VERSION_2))
1578 return false;
1579 }
1580 }
1581
1582 if (mach_flag & CSKY_ARCH_FLOAT)
1583 {
1584 unsigned int val = VAL_CSKY_FPU_HARDFP_SINGLE;
1585 if (IS_CSKY_ARCH_V1 (mach_flag))
1586 {
1587 if (!bfd_elf_add_obj_attr_int (stdoutput, OBJ_ATTR_PROC,
1588 Tag_CSKY_FPU_VERSION,
1589 VAL_CSKY_FPU_VERSION_1))
1590 return false;
1591 }
1592 else
1593 {
1594 if (isa_flag & CSKY_ISA_FLOAT_3E4)
1595 {
1596 if (!bfd_elf_add_obj_attr_int (stdoutput, OBJ_ATTR_PROC,
1597 Tag_CSKY_FPU_VERSION,
1598 VAL_CSKY_FPU_VERSION_2))
1599 return false;
1600 val |= VAL_CSKY_FPU_HARDFP_DOUBLE;
1601 }
1602 else
1603 {
1604 if (!bfd_elf_add_obj_attr_int (stdoutput, OBJ_ATTR_PROC,
1605 Tag_CSKY_FPU_VERSION,
1606 VAL_CSKY_FPU_VERSION_2))
1607 return false;
1608 }
1609
1610 if (!bfd_elf_add_obj_attr_int (stdoutput, OBJ_ATTR_PROC,
1611 Tag_CSKY_FPU_HARDFP, val))
1612 return false;
1613 if (!bfd_elf_add_obj_attr_string (stdoutput, OBJ_ATTR_PROC,
1614 Tag_CSKY_FPU_NUMBER_MODULE,
1615 "IEEE 754"))
1616 return false;
1617 if (!bfd_elf_add_obj_attr_int (stdoutput, OBJ_ATTR_PROC,
1618 Tag_CSKY_FPU_ABI,
1619 float_abi))
1620 return false;
1621 }
1622 }
1623
1624 if (!bfd_elf_add_obj_attr_int (stdoutput, OBJ_ATTR_PROC,
1625 Tag_CSKY_ISA_FLAGS, isa_flag))
1626 return false;
1627
1628 if (!bfd_elf_add_obj_attr_int (stdoutput, OBJ_ATTR_PROC,
1629 Tag_CSKY_ISA_EXT_FLAGS, (isa_flag >> 32)))
1630 return false;
1631
1632 return true;
1633 }
1634
1635 /* Target-specific initialization and option handling. */
1636
1637 void
1638 md_begin (void)
1639 {
1640 unsigned int bfd_mach_flag = 0;
1641 struct csky_opcode const *opcode;
1642 struct csky_macro_info const *macro;
1643 struct csky_arch_info const *p_arch;
1644 struct csky_cpu_info const *p_cpu;
1645 other_flag = (do_opt_mmp | do_opt_mcp | do_opt_mcache
1646 | do_opt_msecurity | do_opt_mhard_float);
1647 dsp_flag |= do_opt_mdsp | do_opt_medsp;
1648 isa_flag |= do_opt_mtrust | do_opt_mvdsp;
1649
1650 if (dsp_flag)
1651 other_flag |= CSKY_ARCH_DSP;
1652
1653 if (mach_flag != 0)
1654 {
1655 if (((mach_flag & CSKY_ARCH_MASK)
1656 != (arch_flag & CSKY_ARCH_MASK))
1657 && arch_flag != 0)
1658 as_warn ("-mcpu conflict with -march option, actually use -mcpu");
1659 }
1660 else if (arch_flag != 0)
1661 mach_flag |= arch_flag | other_flag;
1662 else
1663 {
1664 #ifdef TARGET_WITH_CPU
1665 parse_cpu (TARGET_WITH_CPU);
1666 #else
1667 #if _CSKY_ABI==1
1668 parse_cpu ("ck610");
1669 #else
1670 parse_cpu ("ck810");
1671 #endif
1672 mach_flag |= other_flag;
1673 #endif
1674 }
1675
1676 if (IS_CSKY_ARCH_610 (mach_flag) || IS_CSKY_ARCH_510 (mach_flag))
1677 {
1678 if ((mach_flag & CSKY_ARCH_MP) && (mach_flag & CSKY_ARCH_MAC))
1679 as_fatal ("520/620 conflicts with -mmp option");
1680 else if ((mach_flag & CSKY_ARCH_MP) && (mach_flag & CSKY_ARCH_DSP))
1681 as_fatal ("510e/610e conflicts with -mmp option");
1682 else if ((mach_flag & CSKY_ARCH_DSP) && (mach_flag & CSKY_ARCH_MAC))
1683 as_fatal ("520/620 conflicts with 510e/610e or -mdsp option");
1684 }
1685 if (IS_CSKY_ARCH_510 (mach_flag) && (mach_flag & CSKY_ARCH_FLOAT))
1686 {
1687 mach_flag = (mach_flag & (~CSKY_ARCH_MASK));
1688 mach_flag |= CSKY_ARCH_610;
1689 }
1690
1691 /* Find bfd_mach_flag, it will set to bfd backend data. */
1692 for (p_arch = csky_archs; p_arch->arch_flag != 0; p_arch++)
1693 if ((mach_flag & CSKY_ARCH_MASK) == (p_arch->arch_flag & CSKY_ARCH_MASK))
1694 {
1695 if (!bfd_elf_add_obj_attr_string (stdoutput, OBJ_ATTR_PROC,
1696 Tag_CSKY_ARCH_NAME, p_arch->name))
1697 as_fatal (_("error adding attribute: %s"),
1698 bfd_errmsg (bfd_get_error ()));
1699 bfd_mach_flag = p_arch->bfd_mach_flag;
1700 break;
1701 }
1702
1703 /* Find isa_flag. */
1704 for (p_cpu = csky_cpus; p_cpu->arch_flag != 0; p_cpu++)
1705 if ((mach_flag & CPU_ARCH_MASK) == p_cpu->arch_flag)
1706 {
1707 if (!bfd_elf_add_obj_attr_string (stdoutput, OBJ_ATTR_PROC,
1708 Tag_CSKY_CPU_NAME, p_cpu->name))
1709 as_fatal (_("error adding attribute: %s"),
1710 bfd_errmsg (bfd_get_error ()));
1711 isa_flag |= p_cpu->isa_flag;
1712 break;
1713 }
1714
1715 /* Check if -mdsp and -medsp conflict. If cpu is ck803, we will
1716 use enhanced dsp instruction. Otherwise, we will use normal dsp. */
1717 if (dsp_flag)
1718 {
1719 if (IS_CSKY_ARCH_803 (mach_flag))
1720 {
1721 if ((dsp_flag & CSKY_DSP_FLAG_V1))
1722 {
1723 if (isa_flag & CSKY_ISA_DSP_ENHANCE)
1724 {
1725 /* Option -mdsp conflicts with -mcpu=ck803ern,
1726 CPU already indicates the dsp version. */
1727 as_warn ("Option -mdsp conflicts with -mcpu=ck803ern which "
1728 "has indicated DSP version, ignoring -mdsp.");
1729 isa_flag &= ~(CSKY_ISA_MAC_DSP | CSKY_ISA_DSP);
1730 isa_flag |= CSKY_ISA_DSP_ENHANCE;
1731 }
1732 else
1733 {
1734 isa_flag |= (CSKY_ISA_MAC_DSP | CSKY_ISA_DSP);
1735 isa_flag &= ~CSKY_ISA_DSP_ENHANCE;
1736 }
1737 }
1738
1739 if ((dsp_flag & CSKY_DSP_FLAG_V2))
1740 {
1741 isa_flag &= ~(CSKY_ISA_MAC_DSP | CSKY_ISA_DSP);
1742 isa_flag |= CSKY_ISA_DSP_ENHANCE;
1743 }
1744
1745 if ((dsp_flag & CSKY_DSP_FLAG_V1)
1746 && (dsp_flag & CSKY_DSP_FLAG_V2))
1747 {
1748 /* In 803, dspv1 is conflict with dspv2. We keep dspv2. */
1749 as_warn ("option -mdsp conflicts with -medsp, only enabling -medsp");
1750 dsp_flag &= ~CSKY_DSP_FLAG_V1;
1751 isa_flag &= ~(CSKY_ISA_MAC_DSP | CSKY_ISA_DSP);
1752 isa_flag |= CSKY_ISA_DSP_ENHANCE;
1753 }
1754 }
1755 else
1756 {
1757 if (dsp_flag & CSKY_DSP_FLAG_V2)
1758 {
1759 dsp_flag &= ~CSKY_DSP_FLAG_V2;
1760 isa_flag &= ~CSKY_ISA_DSP_ENHANCE;
1761 as_warn ("-medsp option is only supported by ck803s, ignoring -medsp");
1762 }
1763 }
1764 ;
1765 }
1766
1767 if (do_use_branchstub == -1)
1768 do_use_branchstub = !IS_CSKY_ARCH_V1 (mach_flag);
1769 else if (do_use_branchstub == 1)
1770 {
1771 if (IS_CSKY_ARCH_V1 (mach_flag))
1772 {
1773 as_warn (_("C-SKY ABI v1 (ck510/ck610) does not support -mbranch-stub"));
1774 do_use_branchstub = 0;
1775 }
1776 else if (do_force2bsr == 0)
1777 {
1778 as_warn (_("-mno-force2bsr is ignored with -mbranch-stub"));
1779 do_force2bsr = 1;
1780 }
1781 }
1782
1783 if (IS_CSKY_ARCH_801 (mach_flag) || IS_CSKY_ARCH_802 (mach_flag))
1784 {
1785 if (!do_force2bsr)
1786 as_warn (_("-mno-force2bsr is ignored for ck801/ck802"));
1787 do_force2bsr = 1;
1788 }
1789 else if (do_force2bsr == -1)
1790 do_force2bsr = do_use_branchstub;
1791
1792 if (do_pff == -1)
1793 {
1794 if (IS_CSKY_ARCH_V1 (mach_flag))
1795 do_pff = 1;
1796 else
1797 do_pff = 0;
1798 }
1799
1800 if (do_extend_lrw == -1)
1801 {
1802 if ((mach_flag & CSKY_ARCH_MASK) == CSKY_ARCH_801
1803 || (mach_flag & CSKY_ARCH_MASK) == CSKY_ARCH_802
1804 || (mach_flag & CSKY_ARCH_MASK) == CSKY_ARCH_803
1805 || (mach_flag & CSKY_ARCH_MASK) == CSKY_ARCH_860)
1806 do_extend_lrw = 1;
1807 else
1808 do_extend_lrw = 0;
1809 }
1810 if (IS_CSKY_ARCH_801 (mach_flag) || IS_CSKY_ARCH_802 (mach_flag))
1811 {
1812 if (do_long_jump > 0)
1813 as_warn (_("-mljump is ignored for ck801/ck802"));
1814 do_long_jump = 0;
1815 }
1816 else if (do_long_jump == -1)
1817 do_long_jump = 1;
1818 if (do_intr_stack == -1)
1819 {
1820 /* control interrupt stack module, 801&802&803 default on
1821 807&810, default off. */
1822 if (IS_CSKY_ARCH_807 (mach_flag) || IS_CSKY_ARCH_810 (mach_flag))
1823 do_intr_stack = 0;
1824 else
1825 do_intr_stack = 1;
1826 }
1827 /* Add isa_flag(SIMP/CACHE/APS). */
1828 isa_flag |= (mach_flag & CSKY_ARCH_MAC) ? CSKY_ISA_MAC : 0;
1829 isa_flag |= (mach_flag & CSKY_ARCH_MP) ? CSKY_ISA_MP : 0;
1830 isa_flag |= (mach_flag & CSKY_ARCH_CP) ? CSKY_ISA_CP : 0;
1831
1832 /* Set abi flag and get table address. */
1833 if (IS_CSKY_ARCH_V1 (mach_flag))
1834 {
1835 mach_flag = mach_flag | CSKY_ABI_V1;
1836 opcode = csky_v1_opcodes;
1837 macro = v1_macros_table;
1838 SPANPANIC = v1_SPANPANIC;
1839 SPANCLOSE = v1_SPANCLOSE;
1840 SPANEXIT = v1_SPANEXIT;
1841 md_relax_table = csky_relax_table;
1842 }
1843 else
1844 {
1845 mach_flag = mach_flag | CSKY_ABI_V2;
1846 opcode = csky_v2_opcodes;
1847 macro = v2_macros_table;
1848 SPANPANIC = v2_SPANPANIC;
1849 if (do_extend_lrw)
1850 {
1851 SPANCLOSE = v2_SPANCLOSE_ELRW;
1852 SPANEXIT = v2_SPANEXIT_ELRW;
1853 }
1854 else
1855 {
1856 SPANCLOSE = v2_SPANCLOSE;
1857 SPANEXIT = v2_SPANEXIT;
1858 }
1859 md_relax_table = csky_relax_table;
1860 }
1861
1862 /* Establish hash table for opcodes and macros. */
1863 csky_macros_hash = str_htab_create ();
1864 csky_opcodes_hash = str_htab_create ();
1865 for ( ; opcode->mnemonic != NULL; opcode++)
1866 if ((isa_flag & (opcode->isa_flag16 | opcode->isa_flag32)) != 0)
1867 str_hash_insert (csky_opcodes_hash, opcode->mnemonic, opcode, 0);
1868 for ( ; macro->name != NULL; macro++)
1869 if ((isa_flag & macro->isa_flag) != 0)
1870 str_hash_insert (csky_macros_hash, macro->name, macro, 0);
1871 if (do_nolrw && (isa_flag & CSKYV2_ISA_1E2) != 0)
1872 str_hash_insert (csky_macros_hash,
1873 v2_lrw_macro_opcode.name, &v2_lrw_macro_opcode, 0);
1874 /* Set e_flag to ELF Head. */
1875 bfd_set_private_flags (stdoutput, mach_flag | CSKY_VERSION_V1);
1876 /* Set bfd_mach to bfd backend data. */
1877 bfd_set_arch_mach (stdoutput, bfd_arch_csky, bfd_mach_flag);
1878
1879 if (!set_csky_attribute ())
1880 as_fatal (_("error adding attribute: %s"),
1881 bfd_errmsg (bfd_get_error ()));
1882 }
1883
1884 /* The C-SKY assembler emits mapping symbols $t and $d to mark the
1885 beginning of a sequence of instructions and data (such as a constant pool),
1886 respectively. This is similar to what ARM does. */
1887
1888 static void
1889 make_mapping_symbol (map_state state, valueT value, fragS *frag)
1890 {
1891 symbolS * symbolP;
1892 const char * symname;
1893 int type;
1894 switch (state)
1895 {
1896 case MAP_DATA:
1897 symname = "$d";
1898 type = BSF_NO_FLAGS;
1899 break;
1900 case MAP_TEXT:
1901 symname = "$t";
1902 type = BSF_NO_FLAGS;
1903 break;
1904 default:
1905 abort ();
1906 }
1907
1908 symbolP = symbol_new (symname, now_seg, frag, value);
1909 symbol_get_bfdsym (symbolP)->flags |= type | BSF_LOCAL;
1910 }
1911
1912 /* We need to keep track of whether we are emitting code or data; this
1913 function switches state and emits a mapping symbol if necessary. */
1914
1915 static void
1916 mapping_state (map_state state)
1917 {
1918 map_state current_state
1919 = seg_info (now_seg)->tc_segment_info_data.current_state;
1920
1921 if (current_state == state)
1922 return;
1923 else if (current_state == MAP_UNDEFINED && state == MAP_DATA)
1924 return;
1925 else if (current_state == MAP_UNDEFINED && state == MAP_TEXT)
1926 {
1927 struct frag * const frag_first = seg_info (now_seg)->frchainP->frch_root;
1928 if (frag_now != frag_first || frag_now_fix () > 0)
1929 make_mapping_symbol (MAP_DATA, (valueT) 0, frag_first);
1930 }
1931
1932 seg_info (now_seg)->tc_segment_info_data.current_state = state;
1933 make_mapping_symbol (state, (valueT) frag_now_fix (), frag_now);
1934 }
1935
1936 /* Dump the literal pool. */
1937
1938 static void
1939 dump_literals (int isforce)
1940 {
1941 #define CSKYV1_BR_INSN 0xF000
1942 #define CSKYV2_BR_INSN 0x0400
1943 unsigned int i;
1944 struct literal * p;
1945 symbolS * brarsym = NULL;
1946
1947 /* V1 nop encoding: 0x1200 : mov r0, r0. */
1948 static char v1_nop_insn_big[2] = {0x12, 0x00};
1949 static char v1_nop_insn_little[2] = {0x00, 0x12};
1950
1951 if (poolsize == 0)
1952 return;
1953
1954 /* Must we branch around the literal table? */
1955 if (isforce)
1956 {
1957 char brarname[8];
1958 make_internal_label (brarname, POOL_END_LABEL, poolnumber);
1959 brarsym = symbol_make (brarname);
1960 symbol_table_insert (brarsym);
1961 mapping_state (MAP_TEXT);
1962 if (IS_CSKY_ARCH_V1 (mach_flag))
1963 {
1964 csky_insn.output
1965 = frag_var (rs_machine_dependent,
1966 csky_relax_table[C (UNCD_JUMP_S, DISP32)].rlx_length,
1967 csky_relax_table[C (UNCD_JUMP_S, DISP12)].rlx_length,
1968 C (UNCD_JUMP_S, 0), brarsym, 0, 0);
1969 md_number_to_chars (csky_insn.output, CSKYV1_BR_INSN, 2);
1970 }
1971 else
1972 {
1973 csky_insn.output
1974 = frag_var (rs_machine_dependent,
1975 UNCD_DISP16_LEN,
1976 UNCD_DISP10_LEN,
1977 UNCD_DISP10,
1978 brarsym, 0, 0);
1979 md_number_to_chars (csky_insn.output, CSKYV2_BR_INSN, 2);
1980 }
1981 }
1982 /* Make sure that the section is sufficiently aligned and that
1983 the literal table is aligned within it. */
1984 if (do_pff)
1985 {
1986 valueT br_self;
1987 csky_insn.output = frag_more (2);
1988 /* .Lxx: br .Lxx */
1989 if (IS_CSKY_V1 (mach_flag))
1990 br_self = CSKYV1_BR_INSN | 0x7ff;
1991 else
1992 br_self = CSKYV2_BR_INSN;
1993 md_number_to_chars (csky_insn.output, br_self, 2);
1994 if (!isforce)
1995 {
1996 csky_insn.output = frag_more (2);
1997 /* .Lxx: br .Lxx */
1998 md_number_to_chars (csky_insn.output, br_self, 2);
1999 }
2000 }
2001 mapping_state (MAP_DATA);
2002
2003 record_alignment (now_seg, 2);
2004 if (IS_CSKY_ARCH_V1 (mach_flag))
2005 frag_align_pattern (2,
2006 (target_big_endian
2007 ? v1_nop_insn_big : v1_nop_insn_little),
2008 2, 0);
2009 else
2010 frag_align (2, 0, 3);
2011
2012 colon (S_GET_NAME (poolsym));
2013
2014 for (i = 0, p = litpool; i < poolsize; p++)
2015 {
2016 insn_reloc = p->r_type;
2017 if (insn_reloc == BFD_RELOC_CKCORE_TLS_IE32
2018 || insn_reloc == BFD_RELOC_CKCORE_TLS_LDM32
2019 || insn_reloc == BFD_RELOC_CKCORE_TLS_GD32)
2020 literal_insn_offset = p;
2021 if (p->isdouble)
2022 {
2023 if (target_big_endian)
2024 {
2025 p->e.X_add_number = p->dbnum >> 32;
2026 emit_expr (& p->e, 4);
2027 p->e.X_add_number = p->dbnum & 0xffffffff;
2028 emit_expr (& p->e, 4);
2029 }
2030 else
2031 {
2032 p->e.X_add_number = p->dbnum & 0xffffffff;
2033 emit_expr (& p->e, 4);
2034 p->e.X_add_number = p->dbnum >> 32;
2035 emit_expr (& p->e, 4);
2036 }
2037 }
2038 else if (p->e.X_op == O_big)
2039 {
2040 memcpy (generic_bignum, p->bignum, sizeof (p->bignum));
2041 emit_expr (& p->e, p->e.X_add_number * CHARS_PER_LITTLENUM);
2042 }
2043 else
2044 emit_expr (& p->e, 4);
2045
2046 if (p->e.X_op == O_big)
2047 i += (p->e.X_add_number & 1) +
2048 ((p->e.X_add_number * CHARS_PER_LITTLENUM) >> 2);
2049 else
2050 i += (p->isdouble ? 2 : 1);
2051 }
2052
2053 if (isforce && IS_CSKY_ARCH_V2 (mach_flag))
2054 {
2055 /* Add one nop insn at end of literal for disassembler. */
2056 mapping_state (MAP_TEXT);
2057 csky_insn.output = frag_more (2);
2058 md_number_to_chars (csky_insn.output, CSKYV2_INST_NOP, 2);
2059 }
2060
2061 insn_reloc = BFD_RELOC_NONE;
2062
2063 if (brarsym != NULL)
2064 colon (S_GET_NAME (brarsym));
2065 poolsize = 0;
2066 }
2067
2068 static struct literal *
2069 enter_literal (expressionS *e,
2070 int ispcrel,
2071 unsigned char isdouble,
2072 uint64_t dbnum)
2073 {
2074 unsigned int i;
2075 struct literal * p;
2076 if (poolsize >= MAX_POOL_SIZE - 2)
2077 {
2078 /* The literal pool is as full as we can handle. We have
2079 to be 2 entries shy of the 1024/4=256 entries because we
2080 have to allow for the branch (2 bytes) and the alignment
2081 (2 bytes before the first insn referencing the pool and
2082 2 bytes before the pool itself) == 6 bytes, rounds up
2083 to 2 entries. */
2084
2085 /* Save the parsed symbol's reloc. */
2086 enum bfd_reloc_code_real last_reloc_before_dump = insn_reloc;
2087 dump_literals (1);
2088 insn_reloc = last_reloc_before_dump;
2089 }
2090
2091 if (poolsize == 0)
2092 {
2093 /* Create new literal pool. */
2094 if (++ poolnumber > 0xFFFF)
2095 as_fatal (_("more than 65K literal pools"));
2096
2097 make_internal_label (poolname, POOL_START_LABEL, poolnumber);
2098 poolsym = symbol_make (poolname);
2099 symbol_table_insert (poolsym);
2100 poolspan = 0;
2101 }
2102
2103 /* Search pool for value so we don't have duplicates. */
2104 for (p = litpool,i = 0; i < poolsize; p++)
2105 {
2106 if (e->X_op == p->e.X_op
2107 && e->X_add_symbol == p->e.X_add_symbol
2108 && e->X_add_number == p->e.X_add_number
2109 && ispcrel == p->ispcrel
2110 && insn_reloc == p->r_type
2111 && isdouble == p->isdouble
2112 && insn_reloc != BFD_RELOC_CKCORE_TLS_GD32
2113 && insn_reloc != BFD_RELOC_CKCORE_TLS_LDM32
2114 && insn_reloc != BFD_RELOC_CKCORE_TLS_LDO32
2115 && insn_reloc != BFD_RELOC_CKCORE_TLS_IE32
2116 && insn_reloc != BFD_RELOC_CKCORE_TLS_LE32
2117 && (e->X_op != O_big
2118 || (memcmp (generic_bignum, p->bignum,
2119 p->e.X_add_number * sizeof (LITTLENUM_TYPE)) == 0)))
2120 {
2121 p->refcnt ++;
2122 return p;
2123 }
2124 if (p->e.X_op == O_big)
2125 {
2126 i += (p->e.X_add_number >> 1);
2127 i += (p->e.X_add_number & 0x1);
2128 }
2129 else
2130 i += (p->isdouble ? 2 : 1);
2131 }
2132 p->refcnt = 1;
2133 p->ispcrel = ispcrel;
2134 p->e = *e;
2135 p->r_type = insn_reloc;
2136 p->isdouble = isdouble;
2137 p->offset = i;
2138 if (isdouble)
2139 p->dbnum = dbnum;
2140 if (e->X_op == O_big)
2141 memcpy (p->bignum, generic_bignum, sizeof (p->bignum));
2142
2143 if (insn_reloc == BFD_RELOC_CKCORE_TLS_GD32
2144 || insn_reloc == BFD_RELOC_CKCORE_TLS_LDM32
2145 || insn_reloc == BFD_RELOC_CKCORE_TLS_IE32)
2146 {
2147 p->tls_addend.frag = frag_now;
2148 p->tls_addend.offset = csky_insn.output - frag_now->fr_literal;
2149 literal_insn_offset = p;
2150 }
2151 if (p->e.X_op == O_big) {
2152 poolsize += (p->e.X_add_number >> 1);
2153 poolsize += (p->e.X_add_number & 0x1);
2154 } else
2155 poolsize += (p->isdouble ? 2 : 1);
2156
2157 return p;
2158 }
2159
2160 /* Check whether we must dump the literal pool here.
2161 kind == 0 is any old instruction.
2162 kind > 0 means we just had a control transfer instruction.
2163 kind == 1 means within a function.
2164 kind == 2 means we just left a function.
2165
2166 OFFSET is the length of the insn being processed.
2167
2168 SPANCLOSE and SPANEXIT are smaller numbers than SPANPANIC.
2169 SPANPANIC means that we must dump now.
2170 The dump_literals (1) call inserts a branch around the table, so
2171 we first look to see if its a situation where we won't have to
2172 insert a branch (e.g., the previous instruction was an unconditional
2173 branch).
2174
2175 SPANPANIC is the point where we must dump a single-entry pool.
2176 it accounts for alignments and an inserted branch.
2177 the 'poolsize*2' accounts for the scenario where we do:
2178 lrw r1,lit1; lrw r2,lit2; lrw r3,lit3
2179 Note that the 'lit2' reference is 2 bytes further along
2180 but the literal it references will be 4 bytes further along,
2181 so we must consider the poolsize into this equation.
2182 This is slightly over-cautious, but guarantees that we won't
2183 panic because a relocation is too distant. */
2184
2185 static void
2186 check_literals (int kind, int offset)
2187 {
2188 poolspan += offset;
2189
2190 if ((poolspan > SPANEXIT || do_func_dump)
2191 && kind > 1
2192 && (do_br_dump || do_func_dump))
2193 dump_literals (0);
2194 else if (poolspan > SPANCLOSE && (kind > 0) && do_br_dump)
2195 dump_literals (0);
2196 else if (poolspan
2197 >= (SPANPANIC - (IS_CSKY_ARCH_V1 (mach_flag) ? poolsize * 2 : 0)))
2198 dump_literals (1);
2199 /* We have not dumped literal pool before insn1,
2200 and will not dump literal pool between insn1 and insnN+1,
2201 so reset poolspan to original length. */
2202 else if (do_noliteraldump == 1)
2203 poolspan -= offset;
2204
2205 if (do_noliteraldump == 1)
2206 do_noliteraldump = 0;
2207 }
2208
2209 /* The next group of functions are helpers for parsing various kinds
2210 of instruction operand syntax. */
2211
2212 /* Parse operands of the form
2213 <symbol>@GOTOFF+<nnn>
2214 and similar .plt or .got references.
2215
2216 If we find one, set up the correct relocation in RELOC and copy the
2217 input string, minus the `@GOTOFF' into a malloc'd buffer for
2218 parsing by the calling routine. Return this buffer, and if ADJUST
2219 is non-null set it to the length of the string we removed from the
2220 input line. Otherwise return NULL. */
2221
2222 static char *
2223 lex_got (enum bfd_reloc_code_real *reloc,
2224 int *adjust)
2225 {
2226 struct _gotrel
2227 {
2228 const char *str;
2229 const enum bfd_reloc_code_real rel;
2230 };
2231 static const struct _gotrel gotrel[] =
2232 {
2233 { "GOTOFF", BFD_RELOC_CKCORE_GOTOFF },
2234 { "GOTPC", BFD_RELOC_CKCORE_GOTPC },
2235 { "GOTTPOFF", BFD_RELOC_CKCORE_TLS_IE32 },
2236 { "GOT", BFD_RELOC_CKCORE_GOT32 },
2237 { "PLT", BFD_RELOC_CKCORE_PLT32 },
2238 { "BTEXT", BFD_RELOC_CKCORE_TOFFSET_LO16},
2239 { "BDATA", BFD_RELOC_CKCORE_DOFFSET_LO16},
2240 { "TLSGD32", BFD_RELOC_CKCORE_TLS_GD32 },
2241 { "TLSLDM32", BFD_RELOC_CKCORE_TLS_LDM32 },
2242 { "TLSLDO32", BFD_RELOC_CKCORE_TLS_LDO32 },
2243 { "TPOFF", BFD_RELOC_CKCORE_TLS_LE32 }
2244 };
2245
2246 char *cp;
2247 unsigned int j;
2248
2249 for (cp = input_line_pointer; *cp != '@'; cp++)
2250 if (is_end_of_line[(unsigned char) *cp])
2251 return NULL;
2252
2253 for (j = 0; j < sizeof (gotrel) / sizeof (gotrel[0]); j++)
2254 {
2255 int len = strlen (gotrel[j].str);
2256
2257 if (strncasecmp (cp + 1, gotrel[j].str, len) == 0)
2258 {
2259 if (gotrel[j].rel != 0)
2260 {
2261 *reloc = gotrel[j].rel;
2262 if (adjust)
2263 *adjust = len;
2264
2265 /* input_line_pointer is the str pointer after relocation
2266 token like @GOTOFF. */
2267 input_line_pointer += len + 1;
2268 return input_line_pointer;
2269 }
2270
2271 csky_show_error (ERROR_RELOC_ILLEGAL, 0,
2272 (void *)gotrel[j].str, NULL);
2273 return NULL;
2274 }
2275 }
2276
2277 /* Might be a symbol version string. Don't as_bad here. */
2278 return NULL;
2279 }
2280
2281 /* Parse an expression, returning it in E. */
2282
2283 static char *
2284 parse_exp (char *s, expressionS *e)
2285 {
2286 char *save;
2287 char *new;
2288
2289 /* Skip whitespace. */
2290 while (ISSPACE (*s))
2291 ++s;
2292
2293 save = input_line_pointer;
2294 input_line_pointer = s;
2295
2296 insn_reloc = BFD_RELOC_NONE;
2297 expression (e);
2298 lex_got (&insn_reloc, NULL);
2299
2300 if (e->X_op == O_absent)
2301 SET_ERROR_STRING (ERROR_MISSING_OPERAND, NULL);
2302
2303 new = input_line_pointer;
2304 input_line_pointer = save;
2305
2306 return new;
2307 }
2308
2309 /* Parse a floating-point number from S into its target representation.
2310 If ISDOUBLE is true, return the result in *DBNUM; otherwise
2311 it's returned in E->X_add_number. Returns the result of advancing
2312 S past the constant. */
2313
2314 static char *
2315 parse_fexp (char *s, expressionS *e, unsigned char isdouble, uint64_t *dbnum)
2316 {
2317 int length; /* Number of chars in an object. */
2318 const char *err = NULL; /* Error from scanning float literal. */
2319 unsigned char temp[8];
2320
2321 /* input_line_pointer->1st char of a flonum (we hope!). */
2322 input_line_pointer = s;
2323
2324 if (input_line_pointer[0] == '0'
2325 && ISALPHA (input_line_pointer[1]))
2326 input_line_pointer += 2;
2327
2328 if (isdouble)
2329 err = md_atof ('d', (char *) temp, &length);
2330 else
2331 err = md_atof ('f', (char *) temp, &length);
2332 know (length <= 8);
2333 know (err != NULL || length > 0);
2334
2335 if (!is_end_of_line[(unsigned char) *input_line_pointer])
2336 as_bad (_("immediate operand required"));
2337 while (!is_end_of_line[(unsigned char) *input_line_pointer])
2338 input_line_pointer++;
2339
2340 if (err)
2341 {
2342 as_bad (_("bad floating literal: %s"), err);
2343 while (!is_end_of_line[(unsigned char) *input_line_pointer])
2344 input_line_pointer++;
2345 know (is_end_of_line[(unsigned char) input_line_pointer[-1]]);
2346 return input_line_pointer;
2347 }
2348
2349 e->X_add_symbol = 0x0;
2350 e->X_op_symbol = 0x0;
2351 e->X_op = O_constant;
2352 e->X_unsigned = 1;
2353 e->X_md = 0x0;
2354
2355 if (!isdouble)
2356 {
2357 uint32_t fnum;
2358 if (target_big_endian)
2359 fnum = (((uint32_t) temp[0] << 24)
2360 | (temp[1] << 16)
2361 | (temp[2] << 8)
2362 | temp[3]);
2363 else
2364 fnum = (((uint32_t) temp[3] << 24)
2365 | (temp[2] << 16)
2366 | (temp[1] << 8)
2367 | temp[0]);
2368 e->X_add_number = fnum;
2369 }
2370 else
2371 {
2372 if (target_big_endian)
2373 {
2374 *dbnum = (((uint32_t) temp[0] << 24)
2375 | (temp[1] << 16)
2376 | (temp[2] << 8)
2377 | temp[3]);
2378 *dbnum <<= 32;
2379 *dbnum |= (((uint32_t) temp[4] << 24)
2380 | (temp[5] << 16)
2381 | (temp[6] << 8)
2382 | temp[7]);
2383 }
2384 else
2385 {
2386 *dbnum = (((uint32_t) temp[7] << 24)
2387 | (temp[6] << 16)
2388 | (temp[5] << 8)
2389 | temp[4]);
2390 *dbnum <<= 32;
2391 *dbnum |= (((uint32_t) temp[3] << 24)
2392 | (temp[2] << 16)
2393 | (temp[1] << 8)
2394 | temp[0]);
2395 }
2396 }
2397 return input_line_pointer;
2398 }
2399
2400 static char *
2401 parse_rt (char *s,
2402 int ispcrel,
2403 expressionS *ep,
2404 long reg ATTRIBUTE_UNUSED)
2405 {
2406 expressionS e;
2407
2408 if (ep)
2409 /* Indicate nothing there. */
2410 ep->X_op = O_absent;
2411
2412 if (*s == '[')
2413 {
2414 s = parse_exp (s + 1, &e);
2415
2416 if (*s == ']')
2417 s++;
2418 else
2419 SET_ERROR_STRING (ERROR_MISSING_RSQUARE_BRACKETS, NULL);
2420
2421 if (ep)
2422 *ep = e;
2423 }
2424 else
2425 {
2426 s = parse_exp (s, &e);
2427 if (BFD_RELOC_CKCORE_DOFFSET_LO16 == insn_reloc
2428 || BFD_RELOC_CKCORE_TOFFSET_LO16 == insn_reloc)
2429 {
2430 if (ep)
2431 *ep = e;
2432 return s;
2433 }
2434 if (ep)
2435 *ep = e;
2436 /* If the instruction has work, literal handling is in the work. */
2437 if (!csky_insn.opcode->work)
2438 {
2439 struct literal *p = enter_literal (&e, ispcrel, 0, 0);
2440 if (ep)
2441 *ep = e;
2442
2443 /* Create a reference to pool entry. */
2444 ep->X_op = O_symbol;
2445 ep->X_add_symbol = poolsym;
2446 ep->X_add_number = p->offset << 2;
2447 }
2448 }
2449 return s;
2450 }
2451
2452 static int float_to_half (void *f, void *h)
2453 {
2454 int imm_e;
2455 int imm_f;
2456 unsigned int value_f = *(unsigned int *)f;
2457 unsigned short value_h;
2458
2459 imm_e = ((value_f >> 23) & 0xff);
2460 imm_f = ((value_f & 0x7fffff));
2461
2462 imm_e = ((imm_e - 127 + 15) << 10);
2463 imm_f = ((imm_f & 0x7fe000) >> 13);
2464
2465 value_h = (value_f & 0x80000000 ? 0x8000 : 0x0) | imm_e | imm_f;
2466
2467 if (h)
2468 *(unsigned short *)h = value_h;
2469
2470 return value_h;
2471 }
2472
2473 static char *
2474 parse_rtf (char *s, int ispcrel, expressionS *ep)
2475 {
2476 expressionS e;
2477 struct literal *p = NULL;
2478
2479 if (ep)
2480 /* Indicate nothing there. */
2481 ep->X_op = O_absent;
2482
2483 if (*s == '[')
2484 {
2485 s = parse_exp (s + 1, & e);
2486
2487 if (*s == ']')
2488 s++;
2489 else
2490 as_bad (_("missing ']'"));
2491
2492 if (ep)
2493 *ep = e;
2494 }
2495 else
2496 {
2497 uint64_t dbnum;
2498 if (strstr(csky_insn.opcode->mnemonic, "flrws")
2499 || strstr(csky_insn.opcode->mnemonic, "flrw.32"))
2500 {
2501 s = parse_fexp (s, &e, 0, &dbnum);
2502 p = enter_literal (& e, ispcrel, 0, dbnum);
2503 }
2504 else if (strstr(csky_insn.opcode->mnemonic, "flrwd")
2505 || strstr(csky_insn.opcode->mnemonic, "flrw.64"))
2506 {
2507 s = parse_fexp (s, &e, 1, &dbnum);
2508 p = enter_literal (& e, ispcrel, 1, dbnum);
2509 }
2510 else if (strstr(csky_insn.opcode->mnemonic, "flrwh")
2511 || strstr(csky_insn.opcode->mnemonic, "flrw.16"))
2512 {
2513 s = parse_fexp (s, &e, 0, NULL);
2514 e.X_add_number = float_to_half (&e.X_add_number, &e.X_add_number);
2515 p = enter_literal (& e, ispcrel, 0, 0);
2516 }
2517 else
2518 as_bad (_("unrecognized opcode"));
2519
2520 if (ep)
2521 *ep = e;
2522
2523 /* Create a reference to pool entry. */
2524 ep->X_op = O_symbol;
2525 ep->X_add_symbol = poolsym;
2526 ep->X_add_number = p->offset << 2;
2527 }
2528 return s;
2529 }
2530
2531 static bool
2532 parse_type_ctrlreg (char** oper)
2533 {
2534 int i = -1;
2535 int group = 0;
2536 int crx;
2537 int sel;
2538 char *s = *oper;
2539 expressionS e;
2540
2541 if (TOLOWER (*(*oper + 0)) == 'c'
2542 && TOLOWER (*(*oper + 1)) == 'r'
2543 && ISDIGIT (*(*oper + 2)))
2544 {
2545 /* The control registers are named crxx. */
2546 s = *oper+2;
2547 s = parse_exp (s, &e);
2548 if (e.X_op == O_constant)
2549 {
2550 i = e.X_add_number;
2551 *oper = s;
2552 }
2553 }
2554
2555 if (IS_CSKY_V2 (mach_flag))
2556 {
2557
2558 s = *oper;
2559 if (i != -1)
2560 {
2561 crx = i;
2562 sel = group;
2563 }
2564 else if (TOLOWER (*(*oper + 0)) == 'c'
2565 && TOLOWER (*(*oper + 1)) == 'r')
2566 {
2567 s += 2;
2568 if (*s != '<')
2569 {
2570 SET_ERROR_STRING (ERROR_CREG_ILLEGAL, s);
2571 return false;
2572 }
2573 s++;
2574 crx = strtol(s, &s, 10);
2575 if (crx < 0 || crx > 31 || *s != ',')
2576 {
2577 SET_ERROR_STRING (ERROR_CREG_ILLEGAL, s);
2578 return false;
2579 }
2580 s++;
2581 sel = strtol(s, &s, 10);
2582 if (sel < 0 || sel > 31 || *s != '>')
2583 {
2584 SET_ERROR_STRING (ERROR_CREG_ILLEGAL, s);
2585 return false;
2586 }
2587 s++;
2588 }
2589 else
2590 {
2591 crx = csky_get_control_regno (mach_flag, s, &s, &sel);
2592 if (crx < 0)
2593 {
2594 SET_ERROR_STRING (ERROR_CREG_ILLEGAL, s);
2595 return false;
2596 }
2597 }
2598 i = (sel << 5) | crx;
2599 }
2600 else if (i == -1)
2601 {
2602 i = csky_get_control_regno (mach_flag, s, &s, &sel);
2603 if (i < 0)
2604 {
2605 SET_ERROR_STRING (ERROR_CREG_ILLEGAL, s);
2606 return false;
2607 }
2608 }
2609 *oper = s;
2610 csky_insn.val[csky_insn.idx++] = i;
2611 return true;
2612 }
2613
2614 static int
2615 csky_get_reg_val (char *str, int *len)
2616 {
2617 int regno = 0;
2618 char *s = str;
2619 regno = csky_get_general_regno (mach_flag, str, &s);
2620 *len = (s - str);
2621 return regno;
2622 }
2623
2624 static bool
2625 is_reg_sp_with_bracket (char **oper)
2626 {
2627 int reg;
2628 int sp_idx;
2629 int len;
2630
2631 if (IS_CSKY_V1 (mach_flag))
2632 sp_idx = 0;
2633 else
2634 sp_idx = 14;
2635
2636 if (**oper != '(')
2637 return false;
2638 *oper += 1;
2639 reg = csky_get_reg_val (*oper, &len);
2640 *oper += len;
2641 if (reg == sp_idx)
2642 {
2643 if (**oper != ')')
2644 {
2645 SET_ERROR_STRING (ERROR_UNDEFINE,
2646 "Operand format is error. '(sp)' expected");
2647 return false;
2648 }
2649 *oper += 1;
2650 csky_insn.val[csky_insn.idx++] = sp_idx;
2651 return true;
2652 }
2653
2654 SET_ERROR_STRING (ERROR_UNDEFINE,
2655 "Operand format is error. '(sp)' expected");
2656 return false;
2657 }
2658
2659 static bool
2660 is_reg_sp (char **oper)
2661 {
2662 char sp_name[16];
2663 int sp_idx;
2664 int len;
2665 if (IS_CSKY_V1 (mach_flag))
2666 sp_idx = 0;
2667 else
2668 sp_idx = 14;
2669
2670 /* ABI names: "sp". */
2671 if (memcmp (*oper, "sp", 2) == 0)
2672 {
2673 *oper += 2;
2674 csky_insn.val[csky_insn.idx++] = sp_idx;
2675 return true;
2676 }
2677
2678 len = sprintf (sp_name, "r%d", sp_idx);
2679 if (memcmp (*oper, sp_name, len) == 0)
2680 {
2681 *oper += len;
2682 csky_insn.val[csky_insn.idx++] = sp_idx;
2683 return true;
2684 }
2685
2686 return false;
2687 }
2688
2689 static int
2690 csky_get_freg_val (char *str, int *len)
2691 {
2692 int reg = 0;
2693 char *s = NULL;
2694 if ((TOLOWER(str[0]) == 'v' || TOLOWER(str[0]) == 'f')
2695 && (TOLOWER(str[1]) == 'r'))
2696 {
2697 /* It is fpu register. */
2698 s = &str[2];
2699 while (ISDIGIT (*s))
2700 {
2701 reg = reg * 10 + (*s) - '0';
2702 s++;
2703 }
2704 if (reg > 31)
2705 return -1;
2706 }
2707 else
2708 return -1;
2709 *len = s - str;
2710 return reg;
2711 }
2712
2713 static bool
2714 is_reglist_legal (char **oper)
2715 {
2716 int reg1 = -1;
2717 int reg2 = -1;
2718 int len = 0;
2719 reg1 = csky_get_reg_val (*oper, &len);
2720 *oper += len;
2721
2722 if (reg1 == -1 || (IS_CSKY_V1 (mach_flag) && (reg1 == 0 || reg1 == 15)))
2723 {
2724 SET_ERROR_STRING (ERROR_REG_FORMAT,
2725 "The first reg must not be r0/r15");
2726 return false;
2727 }
2728
2729 if (**oper != '-')
2730 {
2731 SET_ERROR_STRING (ERROR_REG_FORMAT,
2732 "The operand format must be rx-ry");
2733 return false;
2734 }
2735 *oper += 1;
2736
2737 reg2 = csky_get_reg_val (*oper, &len);
2738 *oper += len;
2739
2740 if (reg2 == -1 || (IS_CSKY_V1 (mach_flag) && reg1 == 15))
2741 {
2742 SET_ERROR_STRING (ERROR_REG_FORMAT,
2743 "The operand format must be r15 in C-SKY V1");
2744 return false;
2745 }
2746 if (IS_CSKY_V2 (mach_flag))
2747 {
2748 if (reg2 < reg1)
2749 {
2750 SET_ERROR_STRING (ERROR_REG_FORMAT,
2751 "The operand format must be rx-ry (rx < ry)");
2752 return false;
2753 }
2754 reg2 = reg2 - reg1;
2755 reg1 <<= 5;
2756 reg1 |= reg2;
2757 }
2758 csky_insn.val[csky_insn.idx++] = reg1;
2759 return true;
2760 }
2761
2762 static bool
2763 is_freglist_legal (char **oper)
2764 {
2765 int reg1 = -1;
2766 int reg2 = -1;
2767 int len = 0;
2768 int shift = 0;
2769 reg1 = csky_get_freg_val (*oper, &len);
2770 *oper += len;
2771
2772 if (reg1 == -1)
2773 {
2774 SET_ERROR_STRING (ERROR_REG_FORMAT,
2775 "The fpu register format is not recognized.");
2776 return false;
2777 }
2778
2779 if (**oper != '-')
2780 {
2781 SET_ERROR_STRING (ERROR_REG_FORMAT,
2782 "The operand format must be vrx-vry/frx-fry.");
2783 return false;
2784 }
2785 *oper += 1;
2786
2787 reg2 = csky_get_freg_val (*oper, &len);
2788 *oper += len;
2789
2790 if (reg2 == -1)
2791 {
2792 SET_ERROR_STRING (ERROR_REG_FORMAT,
2793 "The fpu register format is not recognized.");
2794 return false;
2795 }
2796 if (reg2 < reg1)
2797 {
2798 SET_ERROR_STRING (ERROR_REG_FORMAT,
2799 "The operand format must be rx-ry(rx < ry)");
2800 return false;
2801 }
2802
2803 reg2 = reg2 - reg1;
2804 /* The fldm/fstm in CSKY_ISA_FLOAT_7E60 has 5 bits frz(reg1). */
2805 shift = 4;
2806 if (startswith (csky_insn.opcode->mnemonic, "fstm")
2807 || startswith (csky_insn.opcode->mnemonic, "fldm"))
2808 {
2809 if ((!(isa_flag & CSKY_ISA_FLOAT_7E60)
2810 && (reg2 > (int)15 || reg1 > 15))
2811 || ((isa_flag & CSKY_ISA_FLOAT_7E60)
2812 && (reg2 > (int)31 || reg1 > (int)31)))
2813 {
2814 /* ISA_FLOAT_E1 fstm/fldm fry-frx is within 15.
2815 ISA_FLOAT_7E60 fstm(u)/fldm(u) frx-fry is within 31. */
2816 SET_ERROR_STRING(ERROR_REG_FORMAT, (void *)"frx-fry is over range");
2817 return false;
2818 }
2819 if ((mach_flag & CSKY_ARCH_MASK) == CSKY_ARCH_860)
2820 {
2821 shift = 5;
2822 }
2823 }
2824 else
2825 {
2826 if (reg2 > (int)0x3) {
2827 SET_ERROR_STRING(ERROR_REG_FORMAT, (void *)"vry-vrx is over range");
2828 return false;
2829 }
2830 }
2831 reg2 <<= shift;
2832 reg1 |= reg2;
2833 csky_insn.val[csky_insn.idx++] = reg1;
2834 return true;
2835 }
2836
2837 static bool
2838 is_reglist_dash_comma_legal (char **oper, struct operand *oprnd)
2839 {
2840 int reg1 = -1;
2841 int reg2 = -1;
2842 int len = 0;
2843 int list = 0;
2844 int flag = 0;
2845 int temp = 0;
2846 while (**oper != '\n' && **oper != '\0')
2847 {
2848 reg1 = csky_get_reg_val (*oper, &len);
2849 if (reg1 == -1)
2850 {
2851 SET_ERROR_STRING (ERROR_REG_LIST, NULL);
2852 return false;
2853 }
2854 flag |= (1 << reg1);
2855 *oper += len;
2856 if (**oper == '-')
2857 {
2858 *oper += 1;
2859 reg2 = csky_get_reg_val (*oper, &len);
2860 if (reg2 == -1)
2861 {
2862 SET_ERROR_STRING (ERROR_REG_LIST, NULL);
2863 return false;
2864 }
2865 *oper += len;
2866 if (reg1 > reg2)
2867 {
2868 SET_ERROR_STRING (ERROR_REG_LIST, NULL);
2869 return false;
2870 }
2871 while (reg2 >= reg1)
2872 {
2873 flag |= (1 << reg2);
2874 reg2--;
2875 }
2876 }
2877 if (**oper == ',')
2878 *oper += 1;
2879 }
2880 /* The reglist: r4-r11, r15, r16-r17, r28. */
2881 #define REGLIST_BITS 0x10038ff0
2882 if (flag & ~(REGLIST_BITS))
2883 {
2884 SET_ERROR_STRING (ERROR_REG_LIST, NULL);
2885 return false;
2886 }
2887 /* Check r4-r11. */
2888 int i = 4;
2889 while (i <= 11)
2890 {
2891 if (flag & (1 << i))
2892 temp = i - 4 + 1;
2893 i++;
2894 }
2895 list |= temp;
2896
2897 /* Check r15. */
2898 if (flag & (1 << 15))
2899 list |= (1 << 4);
2900
2901 /* Check r16-r17. */
2902 i = 16;
2903 temp = 0;
2904 while (i <= 17)
2905 {
2906 if (flag & (1 << i))
2907 temp = i - 16 + 1;
2908 i++;
2909 }
2910 list |= (temp << 5);
2911
2912 /* Check r28. */
2913 if (flag & (1 << 28))
2914 list |= (1 << 8);
2915 if (oprnd->mask == OPRND_MASK_0_4 && (list & ~OPRND_MASK_0_4))
2916 {
2917 SET_ERROR_STRING (ERROR_REG_LIST, NULL);
2918 return false;
2919 }
2920 csky_insn.val[csky_insn.idx++] = list;
2921 return true;
2922 }
2923
2924 static bool
2925 is_reg_lshift_illegal (char **oper, int is_float)
2926 {
2927 int value;
2928 int len;
2929 int reg;
2930 reg = csky_get_reg_val (*oper, &len);
2931 if (reg == -1)
2932 {
2933 SET_ERROR_STRING (ERROR_REG_FORMAT, "The register must be r0-r31.");
2934 return false;
2935 }
2936
2937 *oper += len;
2938 if ((*oper)[0] != '<' || (*oper)[1] != '<')
2939 {
2940 SET_ERROR_STRING (ERROR_UNDEFINE,
2941 "Operand format error; should be (rx, ry << n)");
2942 return false;
2943 }
2944 *oper += 2;
2945
2946 expressionS e;
2947 char *new_oper = parse_exp (*oper, &e);
2948 if (e.X_op == O_constant)
2949 {
2950 *oper = new_oper;
2951 /* The immediate must be in [0, 3]. */
2952 if (e.X_add_number < 0 || e.X_add_number > 3)
2953 {
2954 SET_ERROR_STRING (ERROR_IMM_OVERFLOW, NULL);
2955 return false;
2956 }
2957 }
2958 else
2959 {
2960 SET_ERROR_STRING (ERROR_EXP_CONSTANT, NULL);
2961 return false;
2962 }
2963 if (is_float)
2964 value = (reg << 2) | e.X_add_number;
2965 else
2966 value = (reg << 5) | (1 << e.X_add_number);
2967 csky_insn.val[csky_insn.idx++] = value;
2968
2969 return true;
2970 }
2971
2972 static bool
2973 is_imm_within_range (char **oper, int min, int max)
2974 {
2975 expressionS e;
2976 bool ret = false;
2977 char *new_oper = parse_exp (*oper, &e);
2978 if (e.X_op == O_constant)
2979 {
2980 ret = true;
2981 *oper = new_oper;
2982 if (e.X_add_number < min || e.X_add_number > max)
2983 {
2984 ret = false;
2985 SET_ERROR_STRING (ERROR_IMM_OVERFLOW, NULL);
2986 }
2987 if (!e.X_unsigned)
2988 e.X_add_number |= 0x80000000;
2989 csky_insn.val[csky_insn.idx++] = e.X_add_number;
2990 }
2991 else
2992 SET_ERROR_STRING(ERROR_IMM_ILLEGAL, NULL);
2993
2994 return ret;
2995 }
2996
2997 static bool
2998 is_imm_within_range_ext (char **oper, int min, int max, int ext)
2999 {
3000 expressionS e;
3001 bool ret = false;
3002 char *new_oper = parse_exp (*oper, &e);
3003 if (e.X_op == O_constant)
3004 {
3005 ret = true;
3006 *oper = new_oper;
3007 if ((int)e.X_add_number != ext
3008 && (e.X_add_number < min || e.X_add_number > max))
3009 {
3010 ret = false;
3011 SET_ERROR_STRING (ERROR_IMM_OVERFLOW, NULL);
3012 }
3013 csky_insn.val[csky_insn.idx++] = e.X_add_number;
3014 }
3015
3016 else
3017 SET_ERROR_STRING(ERROR_IMM_ILLEGAL, NULL);
3018
3019 return ret;
3020 }
3021
3022 static bool
3023 is_oimm_within_range (char **oper, int min, int max)
3024 {
3025 expressionS e;
3026 bool ret = false;
3027 char *new_oper = parse_exp (*oper, &e);
3028 if (e.X_op == O_constant)
3029 {
3030 ret = true;
3031 *oper = new_oper;
3032 if (e.X_add_number < min || e.X_add_number > max)
3033 {
3034 ret = false;
3035 SET_ERROR_STRING (ERROR_IMM_OVERFLOW, NULL);
3036 }
3037 csky_insn.val[csky_insn.idx++] = e.X_add_number - 1;
3038 }
3039 else
3040 SET_ERROR_STRING (ERROR_IMM_ILLEGAL, NULL);
3041
3042 return ret;
3043 }
3044
3045 static bool
3046 is_psr_bit (char **oper)
3047 {
3048 const struct psrbit *bits;
3049 int i = 0;
3050
3051 if (IS_CSKY_V1 (mach_flag))
3052 bits = cskyv1_psr_bits;
3053 else
3054 bits = cskyv2_psr_bits;
3055
3056 while (bits[i].name != NULL)
3057 {
3058 if (bits[i].isa && !(bits[i].isa & isa_flag))
3059 {
3060 i++;
3061 continue;
3062 }
3063 if (strncasecmp (*oper, bits[i].name, strlen (bits[i].name)) == 0)
3064 {
3065 *oper += strlen (bits[i].name);
3066 csky_insn.val[csky_insn.idx] |= bits[i].value;
3067 return true;
3068 }
3069 i++;
3070 }
3071 SET_ERROR_STRING (ERROR_OPCODE_PSRBIT, NULL);
3072 return false;
3073 }
3074
3075 static bool
3076 parse_type_cpidx (char** oper)
3077 {
3078 char *s = *oper;
3079 int idx;
3080 if (s[0] == 'c' && s[1] == 'p')
3081 {
3082 if (ISDIGIT (s[2]) && ISDIGIT (s[3]) && ! ISDIGIT (s[4]))
3083 {
3084 idx = (s[2] - '0') * 10 + s[3] - '0';
3085 *oper += 4;
3086 }
3087 else if (ISDIGIT (s[2]) && !ISDIGIT (s[3]))
3088 {
3089 idx = s[2] - '0';
3090 *oper += 3;
3091 }
3092 else
3093 return false;
3094 }
3095 else
3096 {
3097 expressionS e;
3098 *oper = parse_exp (*oper, &e);
3099 if (e.X_op != O_constant)
3100 {
3101 /* Can not recognize the operand. */
3102 return false;
3103 }
3104 idx = e.X_add_number;
3105 }
3106
3107 csky_insn.val[csky_insn.idx++] = idx;
3108
3109 return true;
3110 }
3111
3112 static bool
3113 parse_type_cpreg (char** oper)
3114 {
3115 expressionS e;
3116
3117 if (strncasecmp (*oper, "cpr", 3) != 0)
3118 {
3119 SET_ERROR_STRING(ERROR_CPREG_ILLEGAL, *oper);
3120 return false;
3121 }
3122
3123 *oper += 3;
3124
3125 *oper = parse_exp (*oper, &e);
3126 if (e.X_op != O_constant)
3127 {
3128 SET_ERROR_STRING(ERROR_CPREG_ILLEGAL, *oper);
3129 return false;
3130 }
3131
3132 csky_insn.val[csky_insn.idx++] = e.X_add_number;
3133
3134 return true;
3135 }
3136
3137 static bool
3138 parse_type_cpcreg (char** oper)
3139 {
3140 expressionS e;
3141
3142 if (strncasecmp (*oper, "cpcr", 4) != 0)
3143 {
3144 SET_ERROR_STRING(ERROR_CPREG_ILLEGAL, *oper);
3145 return false;
3146 }
3147
3148 *oper += 4;
3149
3150 *oper = parse_exp (*oper, &e);
3151 if (e.X_op != O_constant)
3152 {
3153 SET_ERROR_STRING(ERROR_CPREG_ILLEGAL, *oper);
3154 return false;
3155 }
3156
3157 csky_insn.val[csky_insn.idx++] = e.X_add_number;
3158
3159 return true;
3160 }
3161
3162 static bool
3163 parse_type_areg (char** oper)
3164 {
3165 int i = 0;
3166 int len = 0;
3167 i = csky_get_reg_val (*oper, &len);
3168 if (i == -1)
3169 {
3170 SET_ERROR_STRING (ERROR_GREG_ILLEGAL, NULL);
3171 return false;
3172 }
3173 *oper += len;
3174 csky_insn.val[csky_insn.idx++] = i;
3175
3176 return true;
3177 }
3178
3179 static bool
3180 parse_type_freg (char** oper, int even)
3181 {
3182 int reg;
3183 int len;
3184 reg = csky_get_freg_val (*oper, &len);
3185 if (reg == -1)
3186 {
3187 SET_ERROR_STRING (ERROR_REG_FORMAT,
3188 (void *)"The fpu register format is not recognized.");
3189 return false;
3190 }
3191 *oper += len;
3192 csky_insn.opcode_end = *oper;
3193 if (even && reg & 0x1)
3194 {
3195 SET_ERROR_STRING (ERROR_EXP_EVEN_FREG, NULL);
3196 return false;
3197 }
3198
3199 if (IS_CSKY_V2 (mach_flag)
3200 && ((csky_insn.opcode->isa_flag32 & CSKY_ISA_VDSP_2)
3201 || !(csky_insn.opcode->isa_flag32 & CSKY_ISA_FLOAT_7E60))
3202 && reg > 15)
3203 {
3204 if ((csky_insn.opcode->isa_flag32 & CSKY_ISA_VDSP_2))
3205 {
3206 SET_ERROR_INTEGER (ERROR_VREG_OVER_RANGE, reg);
3207 }
3208 else
3209 {
3210 SET_ERROR_INTEGER (ERROR_FREG_OVER_RANGE, reg);
3211 }
3212 return false;
3213 }
3214 /* TODO: recognize vreg or freg. */
3215 if (reg > 31)
3216 {
3217 SET_ERROR_INTEGER (ERROR_VREG_OVER_RANGE, reg);
3218 }
3219 csky_insn.val[csky_insn.idx++] = reg;
3220 return true;
3221 }
3222
3223 static bool
3224 parse_ldst_imm (char **oper, struct csky_opcode_info *op ATTRIBUTE_UNUSED,
3225 struct operand *oprnd)
3226 {
3227 unsigned int mask = oprnd->mask;
3228 int max = 1;
3229 int shift = 0;
3230
3231 shift = oprnd->shift;
3232
3233 while (mask)
3234 {
3235 if (mask & 1)
3236 max <<= 1;
3237 mask >>= 1;
3238 }
3239 max = max << shift;
3240
3241 if (**oper == '\0' || **oper == ')')
3242 {
3243 csky_insn.val[csky_insn.idx++] = 0;
3244 return true;
3245 }
3246
3247 expressionS e;
3248 *oper = parse_exp (*oper, &e);
3249 if (e.X_op != O_constant)
3250 {
3251 /* Not a constant. */
3252 SET_ERROR_STRING(ERROR_UNDEFINE, (void *)"Operand format is error. eg. \"ld rz, (rx, n)\"");
3253 return false;
3254 }
3255 else if (e.X_add_number < 0 || e.X_add_number >= max)
3256 {
3257 /* Out of range. */
3258 SET_ERROR_STRING(ERROR_IMM_OVERFLOW, NULL);
3259 return false;
3260 }
3261 if ((e.X_add_number % (1 << shift)) != 0)
3262 {
3263 /* Not aligned. */
3264 SET_ERROR_INTEGER (ERROR_OFFSET_UNALIGNED, ((unsigned long)1 << shift));
3265 return false;
3266 }
3267
3268 csky_insn.val[csky_insn.idx++] = e.X_add_number >> shift;
3269
3270 return true;
3271
3272 }
3273
3274 static unsigned int
3275 csky_count_operands (char *str)
3276 {
3277 char *oper_end = str;
3278 unsigned int oprnd_num;
3279 int bracket_cnt = 0;
3280
3281 if (is_end_of_line[(unsigned char) *oper_end])
3282 oprnd_num = 0;
3283 else
3284 oprnd_num = 1;
3285
3286 /* Count how many operands. */
3287 if (oprnd_num)
3288 while (!is_end_of_line[(unsigned char) *oper_end])
3289 {
3290 if (*oper_end == '(' || *oper_end == '<')
3291 {
3292 bracket_cnt++;
3293 oper_end++;
3294 continue;
3295 }
3296 if (*oper_end == ')' || *oper_end == '>')
3297 {
3298 bracket_cnt--;
3299 oper_end++;
3300 continue;
3301 }
3302 if (!bracket_cnt && *oper_end == ',')
3303 oprnd_num++;
3304 oper_end++;
3305 }
3306 return oprnd_num;
3307 }
3308
3309 /* End of the operand parsing helper functions. */
3310
3311 /* Parse the opcode part of an instruction. Fill in the csky_insn
3312 state and return true on success, false otherwise. */
3313
3314 static bool
3315 parse_opcode (char *str)
3316 {
3317 #define IS_OPCODE32F(a) (*(a - 2) == '3' && *(a - 1) == '2')
3318 #define IS_OPCODE16F(a) (*(a - 2) == '1' && *(a - 1) == '6')
3319
3320 /* TRUE if this opcode has a suffix, like 'lrw.h'. */
3321 unsigned int has_suffix = false;
3322 unsigned int nlen = 0;
3323 char *opcode_end;
3324 char name[OPCODE_MAX_LEN + 1];
3325 char macro_name[OPCODE_MAX_LEN + 1];
3326
3327 /* Remove space ahead of string. */
3328 while (ISSPACE (*str))
3329 str++;
3330 opcode_end = str;
3331
3332 /* Find the opcode end. */
3333 while (nlen < OPCODE_MAX_LEN
3334 && !is_end_of_line [(unsigned char) *opcode_end]
3335 && *opcode_end != ' ')
3336 {
3337 /* Is csky force 32 or 16 instruction? */
3338 if (IS_CSKY_V2 (mach_flag)
3339 && *opcode_end == '.' && !has_suffix)
3340 {
3341 has_suffix = true;
3342 if (IS_OPCODE32F (opcode_end))
3343 {
3344 csky_insn.flag_force = INSN_OPCODE32F;
3345 nlen -= 2;
3346 }
3347 else if (IS_OPCODE16F (opcode_end))
3348 {
3349 csky_insn.flag_force = INSN_OPCODE16F;
3350 nlen -= 2;
3351 }
3352 }
3353 name[nlen] = *opcode_end;
3354 nlen++;
3355 opcode_end++;
3356 }
3357
3358 /* Is csky force 32 or 16 instruction? */
3359 if (!has_suffix)
3360 {
3361 if (IS_CSKY_V2 (mach_flag) && IS_OPCODE32F (opcode_end))
3362 {
3363 csky_insn.flag_force = INSN_OPCODE32F;
3364 nlen -= 2;
3365 }
3366 else if (IS_OPCODE16F (opcode_end))
3367 {
3368 csky_insn.flag_force = INSN_OPCODE16F;
3369 nlen -= 2;
3370 }
3371 }
3372 name[nlen] = '\0';
3373
3374 /* Generate macro_name for finding hash in macro hash_table. */
3375 if (has_suffix)
3376 nlen += 2;
3377 strncpy (macro_name, str, nlen);
3378 macro_name[nlen] = '\0';
3379
3380 /* Get csky_insn.opcode_end. */
3381 while (ISSPACE (*opcode_end))
3382 opcode_end++;
3383 csky_insn.opcode_end = opcode_end;
3384
3385 /* Count the operands. */
3386 csky_insn.number = csky_count_operands (opcode_end);
3387
3388 /* Find hash by name in csky_macros_hash and csky_opcodes_hash. */
3389 csky_insn.macro = (struct csky_macro_info *) str_hash_find (csky_macros_hash,
3390 macro_name);
3391 csky_insn.opcode = (struct csky_opcode *) str_hash_find (csky_opcodes_hash,
3392 name);
3393
3394 if (csky_insn.macro == NULL && csky_insn.opcode == NULL)
3395 return false;
3396 return true;
3397 }
3398
3399 /* Main dispatch routine to parse operand OPRND for opcode OP from string
3400 *OPER. */
3401
3402 static bool
3403 get_operand_value (struct csky_opcode_info *op,
3404 char **oper, struct operand *oprnd)
3405 {
3406 struct soperand *soprnd = NULL;
3407 if (oprnd->mask == HAS_SUB_OPERAND)
3408 {
3409 /* It has sub operand, it must be like:
3410 (oprnd1, oprnd2)
3411 or
3412 <oprnd1, oprnd2>
3413 We will check the format here. */
3414 soprnd = (struct soperand *) oprnd;
3415 char lc = 0;
3416 char rc = 0;
3417 char *s = *oper;
3418 int bracket_cnt = 0;
3419 if (oprnd->type == OPRND_TYPE_BRACKET)
3420 {
3421 lc = '(';
3422 rc = ')';
3423 }
3424 else if (oprnd->type == OPRND_TYPE_ABRACKET)
3425 {
3426 lc = '<';
3427 rc = '>';
3428 }
3429
3430 if (**oper == lc)
3431 {
3432 *oper += 1;
3433 s += 1;
3434 }
3435 else
3436 {
3437 SET_ERROR_STRING ((oprnd->type == OPRND_TYPE_BRACKET
3438 ? ERROR_MISSING_LBRACKET
3439 : ERROR_MISSING_LANGLE_BRACKETS), NULL);
3440 return false;
3441 }
3442
3443 /* If the oprnd2 is an immediate, it can not be parsed
3444 that end with ')'/'>'. Modify ')'/'>' to '\0'. */
3445 while ((*s != rc || bracket_cnt != 0) && (*s != '\n' && *s != '\0'))
3446 {
3447 if (*s == lc)
3448 bracket_cnt++;
3449 else if (*s == rc)
3450 bracket_cnt--;
3451 s++;
3452 }
3453
3454 if (*s == rc)
3455 *s = '\0';
3456 else
3457 {
3458 SET_ERROR_STRING ((oprnd->type == OPRND_TYPE_BRACKET
3459 ? ERROR_MISSING_RBRACKET
3460 : ERROR_MISSING_RANGLE_BRACKETS), NULL);
3461 return false;
3462 }
3463
3464 if (!get_operand_value (op, oper, &soprnd->subs[0]))
3465 {
3466 *s = rc;
3467 return false;
3468 }
3469 if (**oper == ',')
3470 *oper += 1;
3471 else if (**oper != '\0')
3472 {
3473 SET_ERROR_STRING (ERROR_MISSING_COMMA, NULL);
3474 return false;
3475 }
3476
3477 if (!get_operand_value (op, oper, &soprnd->subs[1]))
3478 {
3479 *s = rc;
3480 return false;
3481 }
3482
3483 *s = rc;
3484 *oper += 1;
3485 return true;
3486 }
3487
3488 switch (oprnd->type)
3489 {
3490 /* TODO: add opcode type here, log errors in the function.
3491 If REGLIST, then j = csky_insn.number - 1.
3492 If there is needed to parse expressions, it will be
3493 handled here. */
3494 case OPRND_TYPE_CTRLREG:
3495 /* some parse. */
3496 return parse_type_ctrlreg (oper);
3497 case OPRND_TYPE_AREG:
3498 return parse_type_areg (oper);
3499 case OPRND_TYPE_FREG:
3500 case OPRND_TYPE_VREG:
3501 return parse_type_freg (oper, 0);
3502 case OPRND_TYPE_FEREG:
3503 return parse_type_freg (oper, 1);
3504 case OPRND_TYPE_CPCREG:
3505 return parse_type_cpcreg (oper);
3506 case OPRND_TYPE_CPREG:
3507 return parse_type_cpreg (oper);
3508 case OPRND_TYPE_CPIDX:
3509 return parse_type_cpidx (oper);
3510 case OPRND_TYPE_GREG0_7:
3511 case OPRND_TYPE_GREG0_15:
3512 {
3513 int len;
3514 long reg;
3515 reg = csky_get_reg_val (*oper, &len);
3516
3517 if (reg == -1)
3518 {
3519 SET_ERROR_STRING (ERROR_GREG_ILLEGAL, NULL);
3520 return false;
3521 }
3522 else if ((oprnd->type == OPRND_TYPE_GREG0_7 && reg > 7)
3523 || (oprnd->type == OPRND_TYPE_GREG0_15 && reg > 15))
3524 {
3525 SET_ERROR_INTEGER (ERROR_REG_OVER_RANGE, reg);
3526 return false;
3527 }
3528 *oper += len;
3529 csky_insn.val[csky_insn.idx++] = reg;
3530 return true;
3531 }
3532 case OPRND_TYPE_REGnsplr:
3533 {
3534 int len;
3535 long reg;
3536 reg = csky_get_reg_val (*oper, &len);
3537
3538 if (reg == -1
3539 || (IS_CSKY_V1 (mach_flag)
3540 && (reg == V1_REG_SP || reg == V1_REG_LR)))
3541 {
3542 SET_ERROR_STRING (ERROR_REG_OVER_RANGE, reg);
3543 return false;
3544 }
3545 csky_insn.val[csky_insn.idx++] = reg;
3546 *oper += len;
3547 return true;;
3548 }
3549 case OPRND_TYPE_REGnr4_r7:
3550 {
3551 int len;
3552 int reg;
3553 if (**oper == '(')
3554 *oper += 1;
3555 reg = csky_get_reg_val (*oper, &len);
3556 if (reg == -1 || (reg <= 7 && reg >= 4))
3557 return false;
3558
3559 csky_insn.val[csky_insn.idx++] = reg;
3560 *oper += len;
3561
3562 if (**oper == ')')
3563 *oper += 1;
3564 return true;;
3565 }
3566 case OPRND_TYPE_REGr4_r7:
3567 if (memcmp (*oper, "r4-r7", sizeof ("r4-r7") - 1) == 0)
3568 {
3569 *oper += sizeof ("r4-r7") - 1;
3570 csky_insn.val[csky_insn.idx++] = 0;
3571 return true;
3572 }
3573 SET_ERROR_STRING (ERROR_OPCODE_ILLEGAL, NULL);
3574 return false;
3575 case OPRND_TYPE_IMM_LDST:
3576 return parse_ldst_imm (oper, op, oprnd);
3577 case OPRND_TYPE_IMM_FLDST:
3578 return parse_ldst_imm (oper, op, oprnd);
3579 case OPRND_TYPE_IMM1b:
3580 return is_imm_within_range (oper, 0, 1);
3581 case OPRND_TYPE_IMM2b:
3582 return is_imm_within_range (oper, 0, 3);
3583 case OPRND_TYPE_IMM2b_JMPIX:
3584 /* ck802j support jmpix16, but not support jmpix32. */
3585 if (IS_CSKY_ARCH_802 (mach_flag)
3586 && (op->opcode & 0xffff0000) != 0)
3587 {
3588 SET_ERROR_STRING (ERROR_OPCODE_ILLEGAL, NULL);
3589 return false;
3590 }
3591 *oper = parse_exp (*oper, &csky_insn.e1);
3592 if (csky_insn.e1.X_op == O_constant)
3593 {
3594 csky_insn.opcode_end = *oper;
3595 if (csky_insn.e1.X_add_number & 0x7)
3596 {
3597 SET_ERROR_STRING (ERROR_JMPIX_OVER_RANGE, NULL);
3598 return false;
3599 }
3600 csky_insn.val[csky_insn.idx++]
3601 = (csky_insn.e1.X_add_number >> 3) - 2;
3602 }
3603 return true;
3604 case OPRND_TYPE_IMM4b:
3605 return is_imm_within_range (oper, 0, 15);
3606 case OPRND_TYPE_IMM5b:
3607 return is_imm_within_range (oper, 0, 31);
3608 /* This type for "bgeni" in csky v1 ISA. */
3609 case OPRND_TYPE_IMM5b_7_31:
3610 if (is_imm_within_range (oper, 0, 31))
3611 {
3612 int val = csky_insn.val[csky_insn.idx - 1];
3613 /* immediate values of 0 -> 6 translate to movi. */
3614 if (val <= 6)
3615 {
3616 const char *name = "movi";
3617 csky_insn.opcode = (struct csky_opcode *)
3618 str_hash_find (csky_opcodes_hash, name);
3619 csky_insn.val[csky_insn.idx - 1] = 1 << val;
3620 }
3621 return true;
3622 }
3623 else
3624 return false;
3625
3626 case OPRND_TYPE_IMM5b_1_31:
3627 return is_imm_within_range (oper, 1, 31);
3628 case OPRND_TYPE_IMM5b_POWER:
3629 if (is_imm_within_range_ext (oper, 1, (1u << 31) - 1, 1u << 31))
3630 {
3631 int log;
3632 int val = csky_insn.val[csky_insn.idx - 1];
3633 log = csky_log_2 (val);
3634 csky_insn.val[csky_insn.idx - 1] = log;
3635 return log != -1;
3636 }
3637 else
3638 return false;
3639
3640 /* This type for "mgeni" in csky v1 ISA. */
3641 case OPRND_TYPE_IMM5b_7_31_POWER:
3642 if (is_imm_within_range_ext (oper, 1, (1u << 31) - 1, 1u << 31))
3643 {
3644 int log;
3645 int val = csky_insn.val[csky_insn.idx - 1];
3646 log = csky_log_2 (val);
3647 /* Immediate values of 0 -> 6 translate to movi. */
3648 if (log <= 6)
3649 {
3650 const char *name = "movi";
3651 csky_insn.opcode = (struct csky_opcode *)
3652 str_hash_find (csky_opcodes_hash, name);
3653 as_warn (_("translating mgeni to movi"));
3654 }
3655 else
3656 csky_insn.val[csky_insn.idx - 1] = log;
3657 return log != -1;
3658 }
3659 else
3660 return false;
3661
3662 case OPRND_TYPE_IMM5b_LS:
3663 return is_imm_within_range (oper,
3664 0,
3665 csky_insn.val[csky_insn.idx - 1]);
3666 case OPRND_TYPE_IMM5b_RORI:
3667 {
3668 unsigned max_shift = IS_CSKY_V1 (mach_flag) ? 31 : 32;
3669
3670 if (is_imm_within_range (oper, 1, max_shift))
3671 {
3672 int i = csky_insn.idx - 1;
3673 csky_insn.val[i] = 32 - csky_insn.val[i];
3674 return true;
3675 }
3676 else
3677 return false;
3678 }
3679
3680 case OPRND_TYPE_IMM5b_BMASKI:
3681 /* For csky v1 bmask inst. */
3682
3683 if (!is_imm_within_range_ext (oper, 8, 31, 0))
3684 {
3685 unsigned int mask_val = csky_insn.val[csky_insn.idx - 1];
3686 if (mask_val > 0 && mask_val < 8)
3687 {
3688 const char *op_movi = "movi";
3689 csky_insn.opcode = (struct csky_opcode *)
3690 str_hash_find (csky_opcodes_hash, op_movi);
3691 if (csky_insn.opcode == NULL)
3692 return false;
3693 csky_insn.val[csky_insn.idx - 1] = (1 << mask_val) - 1;
3694 return true;
3695 }
3696 }
3697 return true;
3698
3699 case OPRND_TYPE_IMM5b_VSH:
3700 /* For vshri.T and vshli.T. */
3701 if (is_imm_within_range (oper, 0, 31))
3702 {
3703 int val = csky_insn.val[csky_insn.idx - 1];
3704 val = (val << 1) | (val >> 4);
3705 val &= 0x1f;
3706 csky_insn.val[csky_insn.idx - 1] = val;
3707 return true;
3708 }
3709 return false;
3710 case OPRND_TYPE_IMM8b_BMASKI:
3711 /* For csky v2 bmask, which will transfer to 16bits movi. */
3712 if (is_imm_within_range (oper, 1, 8))
3713 {
3714 unsigned int mask_val = csky_insn.val[csky_insn.idx - 1];
3715 csky_insn.val[csky_insn.idx - 1] = (1 << mask_val) - 1;
3716 return true;
3717 }
3718 return false;
3719 case OPRND_TYPE_OIMM4b:
3720 return is_oimm_within_range (oper, 1, 16);
3721 case OPRND_TYPE_OIMM5b:
3722 return is_oimm_within_range (oper, 1, 32);
3723 case OPRND_TYPE_OIMM5b_IDLY:
3724 if (is_imm_within_range (oper, 0, 32))
3725 {
3726 /* imm5b for idly n: 0<=n<4, imm5b=3; 4<=n<=32, imm5b=n-1. */
3727 unsigned long imm = csky_insn.val[csky_insn.idx - 1];
3728 if (imm < 4)
3729 {
3730 csky_show_error (WARNING_IDLY, 0, (void *)imm, NULL);
3731 imm = 3;
3732 }
3733 else imm--;
3734 csky_insn.val[csky_insn.idx - 1] = imm;
3735 return true;
3736 }
3737 else
3738 return false;
3739
3740 /* For csky v2 bmask inst. */
3741 case OPRND_TYPE_OIMM5b_BMASKI:
3742 if (!is_oimm_within_range (oper, 17, 32))
3743 {
3744 int mask_val = csky_insn.val[csky_insn.idx - 1];
3745 if (mask_val + 1 == 0)
3746 return true;
3747 if (mask_val > 0 && mask_val < 16)
3748 {
3749 const char *op_movi = "movi";
3750 csky_insn.opcode = (struct csky_opcode *)
3751 str_hash_find (csky_opcodes_hash, op_movi);
3752 if (csky_insn.opcode == NULL)
3753 return false;
3754 csky_insn.val[csky_insn.idx - 1] = (1 << (mask_val + 1)) - 1;
3755 return true;
3756 }
3757 }
3758 return true;
3759 case OPRND_TYPE_IMM7b:
3760 return is_imm_within_range (oper, 0, 127);
3761 case OPRND_TYPE_IMM8b:
3762 return is_imm_within_range (oper, 0, 255);
3763 case OPRND_TYPE_IMM9b:
3764 return is_imm_within_range (oper, -256, 255);
3765 case OPRND_TYPE_IMM12b:
3766 return is_imm_within_range (oper, 0, 4095);
3767 case OPRND_TYPE_IMM15b:
3768 return is_imm_within_range (oper, 0, 0xfffff);
3769 case OPRND_TYPE_IMM16b:
3770 return is_imm_within_range (oper, 0, 65535);
3771 case OPRND_TYPE_OIMM16b:
3772 return is_oimm_within_range (oper, 1, 65536);
3773 case OPRND_TYPE_IMM32b:
3774 {
3775 expressionS e;
3776 char *new_oper = parse_exp (*oper, &e);
3777 if (e.X_op == O_constant)
3778 {
3779 *oper = new_oper;
3780 csky_insn.val[csky_insn.idx++] = e.X_add_number;
3781 return true;
3782 }
3783 return false;
3784 }
3785 case OPRND_TYPE_IMM16b_MOVIH:
3786 case OPRND_TYPE_IMM16b_ORI:
3787 {
3788 bfd_reloc_code_real_type r = BFD_RELOC_NONE;
3789 int len;
3790 char *curr = *oper;
3791 char * save = input_line_pointer;
3792 /* get the reloc type, and set "@GOTxxx" as ' ' */
3793 while (**oper != '@' && **oper != '\0')
3794 *oper += 1;
3795 if (**oper != '\0')
3796 {
3797 input_line_pointer = *oper;
3798 lex_got (&r, &len);
3799 while (*(*oper + len + 1) != '\0')
3800 {
3801 **oper = *(*oper + len + 1);
3802 *(*oper + len + 1) = '\0';
3803 *oper += 1;
3804 }
3805 **oper = '\0';
3806 }
3807 input_line_pointer = save;
3808 *oper = parse_exp (curr, &csky_insn.e1);
3809 return true;
3810 }
3811 case OPRND_TYPE_PSR_BITS_LIST:
3812 {
3813 int ret = true;
3814 if (csky_insn.number == 0)
3815 ret = false;
3816 else
3817 {
3818 csky_insn.val[csky_insn.idx] = 0;
3819 if (is_psr_bit (oper))
3820 while (**oper == ',')
3821 {
3822 *oper += 1;
3823 if (!is_psr_bit (oper))
3824 {
3825 ret = false;
3826 break;
3827 }
3828 }
3829 else
3830 ret = false;
3831 if (ret && IS_CSKY_V1 (mach_flag)
3832 && csky_insn.val[csky_insn.idx] > 8)
3833 ret = false;
3834 }
3835 if (!ret)
3836 SET_ERROR_STRING (ERROR_OPERANDS_ILLEGAL, csky_insn.opcode_end);
3837 return ret;
3838 }
3839 case OPRND_TYPE_RM:
3840 {
3841 /* FPU round mode. */
3842 static const char *round_mode[] =
3843 {
3844 "rm_nearest",
3845 "rm_zero",
3846 "rm_posinf",
3847 "rm_neginf",
3848 NULL
3849 };
3850 int i;
3851 for (i = 0; round_mode[i]; i++)
3852 if (strncasecmp (*oper, round_mode[i], strlen (round_mode[i])) == 0)
3853 {
3854 *oper += strlen (round_mode[i]);
3855 csky_insn.val[csky_insn.idx++] = i;
3856 return true;
3857 }
3858 return false;
3859 }
3860
3861 case OPRND_TYPE_REGLIST_COMMA:
3862 case OPRND_TYPE_BRACKET:
3863 /* TODO: using sub operand union. */
3864 case OPRND_TYPE_ABRACKET:
3865 /* TODO: using sub operand union. */
3866 case OPRND_TYPE_REGLIST_DASH:
3867 return is_reglist_legal (oper);
3868 case OPRND_TYPE_FREGLIST_DASH:
3869 return is_freglist_legal (oper);
3870 case OPRND_TYPE_AREG_WITH_BRACKET:
3871 {
3872 int len;
3873 int reg;
3874 if (**oper != '(')
3875 {
3876 SET_ERROR_STRING (ERROR_MISSING_LBRACKET, NULL);
3877 return false;
3878 }
3879 *oper += 1;
3880 reg = csky_get_reg_val (*oper, &len);
3881 if (reg == -1)
3882 {
3883 SET_ERROR_STRING (ERROR_EXP_GREG, NULL);
3884 return false;
3885 }
3886 *oper += len;
3887 if (**oper != ')')
3888 {
3889 SET_ERROR_STRING (ERROR_MISSING_RBRACKET, NULL);
3890 return false;
3891 }
3892 *oper += 1;
3893 csky_insn.val[csky_insn.idx++] = reg;
3894 return true;
3895 }
3896 case OPRND_TYPE_REGsp:
3897 return is_reg_sp (oper);
3898 case OPRND_TYPE_REGbsp:
3899 return is_reg_sp_with_bracket (oper);
3900 /* For jmpi. */
3901 case OPRND_TYPE_OFF8b:
3902 case OPRND_TYPE_OFF16b:
3903 *oper = parse_rt (*oper, 1, &csky_insn.e1, -1);
3904 csky_insn.val[csky_insn.idx++] = 0;
3905 return true;
3906 case OPRND_TYPE_LABEL_WITH_BRACKET:
3907 case OPRND_TYPE_CONSTANT:
3908 case OPRND_TYPE_ELRW_CONSTANT:
3909 if (**oper == '[')
3910 csky_insn.val[csky_insn.idx++] = 0;
3911 else
3912 csky_insn.val[csky_insn.idx++] = NEED_OUTPUT_LITERAL;
3913 *oper = parse_rt (*oper, 0, &csky_insn.e1, -1);
3914 return true;
3915 case OPRND_TYPE_FCONSTANT:
3916 *oper = parse_rtf (*oper, 0, &csky_insn.e1);
3917 return true;
3918
3919 case OPRND_TYPE_SFLOAT:
3920 case OPRND_TYPE_DFLOAT:
3921 /* For fmovis and fmovid, which accept a constant float with
3922 a limited range. */
3923 {
3924 uint64_t dbnum;
3925 int imm4, imm8;
3926
3927 *oper = parse_fexp (*oper, &csky_insn.e1, 1, &dbnum);
3928 if (csky_insn.e1.X_op == O_absent)
3929 return false;
3930
3931 /* Convert the representation from IEEE double to the 13-bit
3932 encoding used internally for fmovis and fmovid. */
3933 imm4 = 11 - (((dbnum & 0x7ff0000000000000ULL) >> 52) - 1023);
3934 /* Check float range. */
3935 if ((dbnum & 0x00000fffffffffffULL) || imm4 < 0 || imm4 > 15)
3936 {
3937 csky_show_error (ERROR_IMM_OVERFLOW, 2, NULL, NULL);
3938 return false;
3939 }
3940 imm8 = (dbnum & 0x000ff00000000000ULL) >> 44;
3941 csky_insn.e1.X_add_number
3942 = (((imm8 & 0xf) << 4)
3943 | ((imm8 & 0xf0) << 17)
3944 | ((imm4 & 0xf) << 16)
3945 | ((dbnum & 0x8000000000000000ULL) >> 43));
3946 return true;
3947 }
3948 case OPRND_TYPE_HFLOAT_FMOVI:
3949 case OPRND_TYPE_SFLOAT_FMOVI:
3950 case OPRND_TYPE_DFLOAT_FMOVI:
3951 /* For fpuv3 fmovis and fmovid, which accept a constant
3952 float with a limited range. */
3953 {
3954 uint64_t dbnum;
3955 int imm4, imm8, sign;
3956
3957 *oper = parse_fexp (*oper, &csky_insn.e1, 1, &dbnum);
3958 if (csky_insn.e1.X_op == O_absent)
3959 return false;
3960
3961 /* Convert the representation from IEEE double to the 13-bit
3962 encoding used internally for fmovis and fmovid. */
3963 imm4 = 11 - (((dbnum & 0x7ff0000000000000ULL) >> 52) - 1023);
3964 /* Check float range. */
3965 if ((dbnum & 0x00000fffffffffffULL) || imm4 < 0 || imm4 > 15)
3966 {
3967 csky_show_error (ERROR_IMM_OVERFLOW, 2, NULL, NULL);
3968 return true;
3969 }
3970 imm8 = (dbnum & 0x000ff00000000000ULL) >> 44;
3971 sign = (dbnum & 0x8000000000000000ULL) >> 58;
3972 csky_insn.e1.X_add_number
3973 = (((imm8 & 0x3) << 8)
3974 | ((imm8 & 0xfc) << 18)
3975 | ((imm4 & 0xf) << 16)
3976 | sign);
3977 return true;
3978 }
3979 /* For grs v2. */
3980 case OPRND_TYPE_IMM_OFF18b:
3981 *oper = parse_exp (*oper, &csky_insn.e1);
3982 return true;
3983
3984 case OPRND_TYPE_BLOOP_OFF4b:
3985 *oper = parse_exp (*oper, &csky_insn.e2);
3986 if (csky_insn.e2.X_op == O_symbol)
3987 {
3988 csky_insn.opcode_end = *oper;
3989 return true;
3990 }
3991 else
3992 return false;
3993
3994 case OPRND_TYPE_BLOOP_OFF12b:
3995 case OPRND_TYPE_OFF10b:
3996 case OPRND_TYPE_OFF11b:
3997 case OPRND_TYPE_OFF16b_LSL1:
3998 case OPRND_TYPE_OFF26b:
3999 *oper = parse_exp (*oper, &csky_insn.e1);
4000 if (csky_insn.e1.X_op == O_symbol)
4001 {
4002 csky_insn.opcode_end = *oper;
4003 return true;
4004 }
4005 else
4006 return false;
4007 /* For xtrb0(1)(2)(3) and div in csky v1 ISA. */
4008 case OPRND_TYPE_REG_r1a:
4009 {
4010 int reg = 0;
4011 int len = 0;
4012 reg = csky_get_reg_val (*oper, &len);
4013 if (reg == -1)
4014 {
4015 SET_ERROR_STRING (ERROR_REG_FORMAT,
4016 "The first operand must be register r1.");
4017 return false;
4018 }
4019 if (reg != 1)
4020 mov_r1_after = true;
4021 *oper += len;
4022 csky_insn.opcode_end = *oper;
4023 csky_insn.val[csky_insn.idx++] = reg;
4024 return true;
4025 }
4026 case OPRND_TYPE_REG_r1b:
4027 {
4028 int reg = 0;
4029 int len = 0;
4030 reg = csky_get_reg_val (*oper, &len);
4031 if (reg == -1)
4032 {
4033 SET_ERROR_STRING (ERROR_REG_FORMAT,
4034 "The second operand must be register r1.");
4035 return false;
4036 }
4037 if (reg != 1)
4038 {
4039 unsigned int mov_insn = CSKYV1_INST_MOV_R1_RX;
4040 mov_insn |= reg << 4;
4041 mov_r1_before = true;
4042 csky_insn.output = frag_more (2);
4043 dwarf2_emit_insn (0);
4044 md_number_to_chars (csky_insn.output, mov_insn, 2);
4045 }
4046 *oper += len;
4047 csky_insn.opcode_end = *oper;
4048 csky_insn.val[csky_insn.idx++] = reg;
4049 return true;
4050 }
4051 case OPRND_TYPE_DUMMY_REG:
4052 {
4053 int reg = 0;
4054 int len = 0;
4055 reg = csky_get_reg_val (*oper, &len);
4056 if (reg == -1)
4057 {
4058 SET_ERROR_STRING (ERROR_GREG_ILLEGAL, NULL);
4059 return false;
4060 }
4061 if (reg != csky_insn.val[0])
4062 {
4063 SET_ERROR_STRING (ERROR_REG_FORMAT,
4064 "The second register must be the same as the first.");
4065 return false;
4066 }
4067 *oper += len;
4068 csky_insn.opcode_end = *oper;
4069 csky_insn.val[csky_insn.idx++] = reg;
4070 return true;
4071 }
4072 case OPRND_TYPE_2IN1_DUMMY:
4073 {
4074 int reg = 0;
4075 int len = 0;
4076 int max = 0;
4077 int min = 0;
4078 reg = csky_get_reg_val (*oper, &len);
4079 if (reg == -1)
4080 {
4081 SET_ERROR_STRING (ERROR_GREG_ILLEGAL, NULL);
4082 return false;
4083 }
4084 /* dummy reg's real type should be same with first operand. */
4085 if (op->oprnd.oprnds[0].type == OPRND_TYPE_GREG0_15)
4086 max = 15;
4087 else if (op->oprnd.oprnds[0].type == OPRND_TYPE_GREG0_7)
4088 max = 7;
4089 else
4090 return false;
4091 if (reg < min || reg > max)
4092 return false;
4093 csky_insn.val[csky_insn.idx++] = reg;
4094 /* if it is the last operands. */
4095 if (csky_insn.idx > 2)
4096 {
4097 /* For "insn rz, rx, ry", if rx or ry is equal to rz,
4098 we can output the insn like "insn rz, rx". */
4099 if (csky_insn.val[0] == csky_insn.val[1])
4100 csky_insn.val[1] = 0;
4101 else if (csky_insn.val[0] == csky_insn.val[2])
4102 csky_insn.val[2] = 0;
4103 else
4104 return false;
4105 }
4106 *oper += len;
4107 csky_insn.opcode_end = *oper;
4108 return true;
4109 }
4110 case OPRND_TYPE_DUP_GREG0_7:
4111 case OPRND_TYPE_DUP_GREG0_15:
4112 case OPRND_TYPE_DUP_AREG:
4113 {
4114 long reg = 0;
4115 int len = 0;
4116 long max_reg;
4117 unsigned int shift_num;
4118 if (oprnd->type == OPRND_TYPE_DUP_GREG0_7)
4119 {
4120 max_reg = 7;
4121 shift_num = 3;
4122 }
4123 else if (oprnd->type == OPRND_TYPE_DUP_GREG0_15)
4124 {
4125 max_reg = 15;
4126 shift_num = 4;
4127 }
4128 else
4129 {
4130 max_reg = 31;
4131 shift_num = 5;
4132 }
4133 reg = csky_get_reg_val (*oper, &len);
4134 if (reg == -1)
4135 {
4136 if (max_reg == 31)
4137 SET_ERROR_STRING (ERROR_REG_FORMAT,
4138 "The register must be r0-r31");
4139 else
4140 SET_ERROR_STRING (ERROR_REG_FORMAT,
4141 "The register must be r0-r15");
4142 return false;
4143 }
4144 if (reg > max_reg)
4145 {
4146 SET_ERROR_STRING (ERROR_REG_OVER_RANGE, reg);
4147 return false;
4148 }
4149 reg |= reg << shift_num;
4150 *oper += len;
4151 csky_insn.opcode_end = *oper;
4152 csky_insn.val[csky_insn.idx++] = reg;
4153 return true;
4154 }
4155 case OPRND_TYPE_CONST1:
4156 *oper = parse_exp (*oper, &csky_insn.e1);
4157 if (csky_insn.e1.X_op == O_constant)
4158 {
4159 csky_insn.opcode_end = *oper;
4160 if (csky_insn.e1.X_add_number != 1)
4161 return false;
4162 csky_insn.val[csky_insn.idx++] = 1;
4163 return true;
4164 }
4165 return false;
4166 case OPRND_TYPE_UNCOND10b:
4167 case OPRND_TYPE_UNCOND16b:
4168 *oper = parse_exp (*oper, &csky_insn.e1);
4169 if (csky_insn.e1.X_op == O_constant)
4170 return false;
4171 input_line_pointer = *oper;
4172 csky_insn.opcode_end = *oper;
4173 csky_insn.relax.max = UNCD_DISP16_LEN;
4174 csky_insn.relax.var = UNCD_DISP10_LEN;
4175 csky_insn.relax.subtype = UNCD_DISP10;
4176 csky_insn.val[csky_insn.idx++] = 0;
4177 return true;
4178 case OPRND_TYPE_COND10b:
4179 case OPRND_TYPE_COND16b:
4180 *oper = parse_exp (*oper, &csky_insn.e1);
4181 if (csky_insn.e1.X_op == O_constant)
4182 return false;
4183 input_line_pointer = *oper;
4184 csky_insn.opcode_end = *oper;
4185 /* CK801 doesn't have 32-bit bt/bf insns; relax to a short
4186 jump around a 32-bit unconditional branch instead. */
4187 if (IS_CSKY_ARCH_801 (mach_flag))
4188 {
4189 csky_insn.relax.max = SCOND_DISP16_LEN;
4190 csky_insn.relax.var = SCOND_DISP10_LEN;
4191 csky_insn.relax.subtype = SCOND_DISP10;
4192 }
4193 else
4194 {
4195 csky_insn.relax.max = COND_DISP16_LEN;
4196 csky_insn.relax.var = COND_DISP10_LEN;
4197 csky_insn.relax.subtype = COND_DISP10;
4198 }
4199 csky_insn.val[csky_insn.idx++] = 0;
4200 return true;
4201 case OPRND_TYPE_JCOMPZ:
4202 *oper = parse_exp (*oper, &csky_insn.e1);
4203 if (csky_insn.e1.X_op == O_constant)
4204 return false;
4205 input_line_pointer = *oper;
4206 csky_insn.opcode_end = *oper;
4207 csky_insn.relax.max = JCOMPZ_DISP32_LEN;
4208 csky_insn.relax.var = JCOMPZ_DISP16_LEN;
4209 csky_insn.relax.subtype = JCOMPZ_DISP16;
4210 csky_insn.max = JCOMPZ_DISP32_LEN;
4211 csky_insn.val[csky_insn.idx++] = 0;
4212 return true;
4213 case OPRND_TYPE_JBTF:
4214 *oper = parse_exp (*oper, &csky_insn.e1);
4215 input_line_pointer = *oper;
4216 csky_insn.opcode_end = *oper;
4217 csky_insn.relax.max = csky_relax_table[C (COND_JUMP_S, DISP32)].rlx_length;
4218 csky_insn.relax.var = csky_relax_table[C (COND_JUMP_S, DISP12)].rlx_length;
4219 csky_insn.relax.subtype = C (COND_JUMP_S, 0);
4220 csky_insn.val[csky_insn.idx++] = 0;
4221 csky_insn.max = C32_LEN_S + 2;
4222 return true;
4223 case OPRND_TYPE_JBR:
4224 *oper = parse_exp (*oper, &csky_insn.e1);
4225 input_line_pointer = *oper;
4226 csky_insn.opcode_end = *oper;
4227 csky_insn.relax.max = csky_relax_table[C (UNCD_JUMP_S, DISP32)].rlx_length;
4228 csky_insn.relax.var = csky_relax_table[C (UNCD_JUMP_S, DISP12)].rlx_length;
4229 csky_insn.relax.subtype = C (UNCD_JUMP_S, 0);
4230 csky_insn.val[csky_insn.idx++] = 0;
4231 csky_insn.max = U32_LEN_S + 2;
4232 return true;
4233 case OPRND_TYPE_JBSR:
4234 if (do_force2bsr)
4235 *oper = parse_exp (*oper, &csky_insn.e1);
4236 else
4237 *oper = parse_rt (*oper, 1, &csky_insn.e1, -1);
4238 input_line_pointer = *oper;
4239 csky_insn.opcode_end = *oper;
4240 csky_insn.val[csky_insn.idx++] = 0;
4241 return true;
4242 case OPRND_TYPE_REGLIST_DASH_COMMA:
4243 return is_reglist_dash_comma_legal (oper, oprnd);
4244
4245 case OPRND_TYPE_MSB2SIZE:
4246 case OPRND_TYPE_LSB2SIZE:
4247 {
4248 expressionS e;
4249 char *new_oper = parse_exp (*oper, &e);
4250 if (e.X_op == O_constant)
4251 {
4252 *oper = new_oper;
4253 if (e.X_add_number > 31)
4254 {
4255 SET_ERROR_STRING (ERROR_IMM_OVERFLOW, NULL);
4256 return false;
4257 }
4258 csky_insn.val[csky_insn.idx++] = e.X_add_number;
4259 if (oprnd->type == OPRND_TYPE_LSB2SIZE)
4260 {
4261 if (csky_insn.val[csky_insn.idx - 1] > csky_insn.val[csky_insn.idx - 2])
4262 {
4263 SET_ERROR_STRING (ERROR_IMM_OVERFLOW, NULL);
4264 return false;
4265 }
4266 csky_insn.val[csky_insn.idx - 2] -= e.X_add_number;
4267 }
4268 return true;
4269 }
4270 return false;
4271 }
4272 case OPRND_TYPE_AREG_WITH_LSHIFT:
4273 return is_reg_lshift_illegal (oper, 0);
4274 case OPRND_TYPE_AREG_WITH_LSHIFT_FPU:
4275 return is_reg_lshift_illegal (oper, 1);
4276 case OPRND_TYPE_FREG_WITH_INDEX:
4277 case OPRND_TYPE_VREG_WITH_INDEX:
4278 if (parse_type_freg (oper, 0))
4279 {
4280 if (**oper == '[')
4281 {
4282 (*oper)++;
4283 if (is_imm_within_range (oper, 0, 0xf))
4284 {
4285 if (**oper == ']')
4286 {
4287 unsigned int idx = --csky_insn.idx;
4288 unsigned int val = csky_insn.val[idx];
4289 (*oper)++;
4290 csky_insn.val[idx - 1] |= val << 4;
4291 return true;
4292 }
4293 else
4294 SET_ERROR_STRING (ERROR_MISSING_RSQUARE_BRACKETS, NULL);
4295 }
4296 }
4297 else
4298 SET_ERROR_STRING (ERROR_MISSING_LSQUARE_BRACKETS, NULL);
4299 }
4300 return false;
4301
4302 default:
4303 break;
4304 /* error code. */
4305 }
4306 return false;
4307 }
4308
4309 /* Subroutine of parse_operands. */
4310
4311 static bool
4312 parse_operands_op (char *str, struct csky_opcode_info *op)
4313 {
4314 int i;
4315 int j;
4316 char *oper = str;
4317 int flag_pass;
4318
4319 for (i = 0; i < OP_TABLE_NUM && op[i].operand_num != -2; i++)
4320 {
4321 flag_pass = true;
4322 csky_insn.idx = 0;
4323 oper = str;
4324 /* if operand_num = -1, it is a insn with a REGLIST type operand.i. */
4325 if (!(op[i].operand_num == csky_insn.number
4326 || (op[i].operand_num == -1 && csky_insn.number != 0)))
4327 {
4328 /* The smaller err_num is more serious. */
4329 SET_ERROR_INTEGER (ERROR_OPERANDS_NUMBER, op[i].operand_num);
4330 flag_pass = false;
4331 continue;
4332 }
4333
4334 for (j = 0; j < csky_insn.number; j++)
4335 {
4336 while (ISSPACE (*oper))
4337 oper++;
4338 flag_pass = get_operand_value (&op[i], &oper,
4339 &op[i].oprnd.oprnds[j]);
4340 if (!flag_pass)
4341 break;
4342 while (ISSPACE (*oper))
4343 oper++;
4344 /* Skip the ','. */
4345 if (j < csky_insn.number - 1 && op[i].operand_num != -1)
4346 {
4347 if (*oper == ',')
4348 oper++;
4349 else
4350 {
4351 SET_ERROR_STRING (ERROR_MISSING_COMMA, NULL);
4352 flag_pass = false;
4353 break;
4354 }
4355 }
4356 else if (!is_end_of_line[(unsigned char) *oper])
4357 {
4358 SET_ERROR_STRING (ERROR_BAD_END, NULL);
4359 flag_pass = false;
4360 break;
4361 }
4362 else
4363 break;
4364 }
4365 /* Parse operands in one table end. */
4366
4367 if (flag_pass)
4368 {
4369 /* Parse operands success, set opcode_idx. */
4370 csky_insn.opcode_idx = i;
4371 return true;
4372 }
4373 else
4374 error_state.opnum = j + 1;
4375 }
4376 /* Parse operands in ALL tables end. */
4377 return false;
4378 }
4379
4380 /* Parse the operands according to operand type. */
4381
4382 static bool
4383 parse_operands (char *str)
4384 {
4385 char *oper = str;
4386
4387 /* Parse operands according to flag_force. */
4388 if (csky_insn.flag_force == INSN_OPCODE16F
4389 && (csky_insn.opcode->isa_flag16 & isa_flag) != 0)
4390 {
4391 if (parse_operands_op (oper, csky_insn.opcode->op16))
4392 {
4393 csky_insn.isize = 2;
4394 return true;
4395 }
4396 return false;
4397 }
4398 else if (csky_insn.flag_force == INSN_OPCODE32F
4399 && (csky_insn.opcode->isa_flag32 & isa_flag) != 0)
4400 {
4401 if (parse_operands_op (oper, csky_insn.opcode->op32))
4402 {
4403 csky_insn.isize = 4;
4404 return true;
4405 }
4406 return false;
4407 }
4408 else
4409 {
4410 if ((csky_insn.opcode->isa_flag16 & isa_flag) != 0
4411 && parse_operands_op (oper, csky_insn.opcode->op16))
4412 {
4413 csky_insn.isize = 2;
4414 return true;
4415 }
4416 if ((csky_insn.opcode->isa_flag32 & isa_flag) != 0
4417 && parse_operands_op (oper, csky_insn.opcode->op32))
4418 {
4419 csky_insn.isize = 4;
4420 return true;
4421 }
4422 return false;
4423 }
4424 }
4425
4426 static bool
4427 csky_generate_frags (void)
4428 {
4429 /* frag more relax reloc. */
4430 if (csky_insn.flag_force == INSN_OPCODE16F
4431 || !IS_SUPPORT_OPCODE32 (csky_insn.opcode))
4432 {
4433 csky_insn.output = frag_more (csky_insn.isize);
4434 if (csky_insn.opcode->reloc16)
4435 {
4436 /* 16 bits opcode force, should generate fixup. */
4437 reloc_howto_type *howto;
4438 howto = bfd_reloc_type_lookup (stdoutput,
4439 csky_insn.opcode->reloc16);
4440 fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
4441 2, &csky_insn.e1, howto->pc_relative,
4442 csky_insn.opcode->reloc16);
4443 }
4444 }
4445 else if (csky_insn.flag_force == INSN_OPCODE32F)
4446 {
4447 csky_insn.output = frag_more (csky_insn.isize);
4448 if (csky_insn.opcode->reloc32)
4449 {
4450 reloc_howto_type *howto;
4451 howto = bfd_reloc_type_lookup (stdoutput,
4452 csky_insn.opcode->reloc32);
4453 fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
4454 4, &csky_insn.e1, howto->pc_relative,
4455 csky_insn.opcode->reloc32);
4456 }
4457 }
4458 else if (csky_insn.opcode->relax)
4459 /* Generate the relax information. */
4460 csky_insn.output = frag_var (rs_machine_dependent,
4461 csky_insn.relax.max,
4462 csky_insn.relax.var,
4463 csky_insn.relax.subtype,
4464 csky_insn.e1.X_add_symbol,
4465 csky_insn.e1.X_add_number, 0);
4466 else
4467 {
4468 csky_insn.output = frag_more (csky_insn.isize);
4469 if (csky_insn.opcode->reloc16 && csky_insn.isize == 2)
4470 {
4471 reloc_howto_type *howto;
4472 howto = bfd_reloc_type_lookup (stdoutput,
4473 csky_insn.opcode->reloc16);
4474 fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
4475 2, &csky_insn.e1, howto->pc_relative,
4476 csky_insn.opcode->reloc16);
4477 }
4478 else if (csky_insn.opcode->reloc32 && csky_insn.isize == 4)
4479 {
4480 reloc_howto_type *howto;
4481 howto = bfd_reloc_type_lookup (stdoutput,
4482 csky_insn.opcode->reloc32);
4483 fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
4484 4, &csky_insn.e1, howto->pc_relative,
4485 csky_insn.opcode->reloc32);
4486 }
4487 }
4488 return true;
4489 }
4490
4491 /* Return the bits of VAL shifted according to MASK. The bits of MASK
4492 need not be contiguous. */
4493
4494 static int
4495 generate_masked_value (int mask, int val)
4496 {
4497 int ret = 0;
4498 int bit;
4499
4500 for (bit = 1; mask; bit = bit << 1)
4501 if (mask & bit)
4502 {
4503 if (val & 0x1)
4504 ret |= bit;
4505 val = val >> 1;
4506 mask &= ~bit;
4507 }
4508 return ret;
4509 }
4510
4511 /* Return the result of masking operand number OPRND_IDX into the
4512 instruction word according to the information in OPRND. */
4513
4514 static int
4515 generate_masked_operand (struct operand *oprnd, int *oprnd_idx)
4516 {
4517 struct soperand *soprnd = NULL;
4518 int mask;
4519 int val;
4520 if ((unsigned int)oprnd->mask == HAS_SUB_OPERAND)
4521 {
4522 soprnd = (struct soperand *) oprnd;
4523 generate_masked_operand (&soprnd->subs[0], oprnd_idx);
4524 generate_masked_operand (&soprnd->subs[1], oprnd_idx);
4525 return 0;
4526 }
4527 mask = oprnd->mask;
4528 val = csky_insn.val[*oprnd_idx];
4529 (*oprnd_idx)++;
4530 val = generate_masked_value (mask, val);
4531 csky_insn.inst |= val;
4532
4533 return 0;
4534 }
4535
4536 static bool
4537 csky_generate_insn (void)
4538 {
4539 int i = 0;
4540 struct csky_opcode_info *opinfo = NULL;
4541
4542 if (csky_insn.isize == 4)
4543 opinfo = &csky_insn.opcode->op32[csky_insn.opcode_idx];
4544 else if (csky_insn.isize == 2)
4545 opinfo = &csky_insn.opcode->op16[csky_insn.opcode_idx];
4546
4547 int sidx = 0;
4548 csky_insn.inst = opinfo->opcode;
4549 if (opinfo->operand_num == -1)
4550 {
4551 generate_masked_operand (&opinfo->oprnd.oprnds[i], &sidx);
4552 return 0;
4553 }
4554 else
4555 for (i = 0; i < opinfo->operand_num; i++)
4556 generate_masked_operand (&opinfo->oprnd.oprnds[i], &sidx);
4557 return 0;
4558 }
4559
4560 /* Main entry point for assembling a single instruction. */
4561
4562 void
4563 md_assemble (char *str)
4564 {
4565 bool must_check_literals = true;
4566 csky_insn.isize = 0;
4567 csky_insn.idx = 0;
4568 csky_insn.max = 0;
4569 csky_insn.flag_force = INSN_OPCODE;
4570 csky_insn.macro = NULL;
4571 csky_insn.opcode = NULL;
4572 memset (csky_insn.val, 0, sizeof (int) * MAX_OPRND_NUM);
4573 /* Initialize err_num. */
4574 error_state.err_num = ERROR_NONE;
4575 mov_r1_before = false;
4576 mov_r1_after = false;
4577
4578 mapping_state (MAP_TEXT);
4579 /* Tie dwarf2 debug info to every insn if set option --gdwarf2. */
4580 dwarf2_emit_insn (0);
4581 while (ISSPACE (* str))
4582 str++;
4583 /* Get opcode from str. */
4584 if (!parse_opcode (str))
4585 {
4586 csky_show_error (ERROR_OPCODE_ILLEGAL, 0, NULL, NULL);
4587 return;
4588 }
4589
4590 /* If it is a macro instruction, handle it. */
4591 if (csky_insn.macro != NULL)
4592 {
4593 if (csky_insn.number == csky_insn.macro->oprnd_num)
4594 {
4595 csky_insn.macro->handle_func ();
4596 return;
4597 }
4598 else if (error_state.err_num > ERROR_OPERANDS_NUMBER)
4599 SET_ERROR_STRING (ERROR_OPERANDS_NUMBER, csky_insn.macro->oprnd_num);
4600 }
4601
4602 if (csky_insn.opcode == NULL)
4603 {
4604 SET_ERROR_STRING (ERROR_OPCODE_ILLEGAL, NULL);
4605 csky_show_error (error_state.err_num, error_state.opnum,
4606 (void *)error_state.arg1, (void *)error_state.arg1);
4607 return;
4608 }
4609
4610 /* Parse the operands according to operand type. */
4611 if (!parse_operands (csky_insn.opcode_end))
4612 {
4613 csky_show_error (error_state.err_num, error_state.opnum,
4614 (void *)error_state.arg1, (void *)error_state.arg1);
4615 return;
4616 }
4617 error_state.err_num = ERROR_NONE;
4618
4619 /* if this insn has work in opcode table, then do it. */
4620 if (csky_insn.opcode->work != NULL)
4621 must_check_literals = csky_insn.opcode->work ();
4622 else
4623 {
4624 /* Generate relax or reloc if necessary. */
4625 csky_generate_frags ();
4626 /* Generate the insn by mask. */
4627 csky_generate_insn ();
4628 /* Write inst to frag. */
4629 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
4630 }
4631
4632 /* Adjust for xtrb0/xtrb1/xtrb2/xtrb3/divs/divu in csky v1 ISA. */
4633 if (mov_r1_after)
4634 {
4635 unsigned int mov_insn = CSKYV1_INST_MOV_RX_R1;
4636 mov_insn |= csky_insn.val[0];
4637 mov_r1_before = true;
4638 csky_insn.output = frag_more (2);
4639 dwarf2_emit_insn (0);
4640 md_number_to_chars (csky_insn.output, mov_insn, 2);
4641 csky_insn.isize += 2;
4642 }
4643 if (mov_r1_before)
4644 csky_insn.isize += 2;
4645
4646 /* Check literal. */
4647 if (must_check_literals)
4648 {
4649 if (csky_insn.max == 0)
4650 check_literals (csky_insn.opcode->transfer, csky_insn.isize);
4651 else
4652 check_literals (csky_insn.opcode->transfer, csky_insn.max);
4653 }
4654
4655 csky_insn.last_isize = csky_insn.isize;
4656 insn_reloc = BFD_RELOC_NONE;
4657 }
4658
4659 /* Attempt to handle option with value C, returning non-zero on success. */
4660
4661 int
4662 md_parse_option (int c, const char *arg)
4663 {
4664 switch (c)
4665 {
4666 case 0:
4667 break;
4668 case OPTION_MARCH:
4669 parse_arch (arg);
4670 break;
4671 case OPTION_MCPU:
4672 parse_cpu (arg);
4673 break;
4674 case OPTION_FLOAT_ABI:
4675 parse_float_abi (arg);
4676 break;
4677 default:
4678 return 0;
4679 }
4680 return 1;
4681 }
4682
4683 /* Convert a machine dependent frag. */
4684 #define PAD_LITERAL_LENGTH 6
4685 #define opposite_of_stored_comp(insn) (insn ^ 0x04000000)
4686 #define opposite_of_stored_compz(insn) (insn ^ 0x00200000)
4687 #define make_insn(total_length, opcode, operand, operand_length) \
4688 do { \
4689 if (total_length > 0) \
4690 { \
4691 csky_write_insn (buf, \
4692 opcode | (operand & ((1 << operand_length) - 1)), \
4693 total_length); \
4694 buf += total_length; \
4695 fragp->fr_fix += total_length; \
4696 } \
4697 } while (0)
4698
4699 #define make_literal(fragp, literal_offset) \
4700 do { \
4701 make_insn (literal_offset, PAD_FILL_CONTENT, 0, 0); \
4702 fix_new (fragp, fragp->fr_fix, 4, fragp->fr_symbol, \
4703 fragp->fr_offset, 0, BFD_RELOC_CKCORE_ADDR32); \
4704 make_insn (4, 0, 0, 0); \
4705 make_insn (2 - literal_offset, PAD_FILL_CONTENT, 0, 0); \
4706 } while (0)
4707
4708 void
4709 md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT asec, fragS *fragp)
4710 {
4711 offsetT disp;
4712 char *buf = fragp->fr_fix + &fragp->fr_literal[0];
4713
4714 gas_assert (fragp->fr_symbol);
4715 if (IS_EXTERNAL_SYM (fragp->fr_symbol, asec))
4716 disp = 0;
4717 else
4718 disp = (S_GET_VALUE (fragp->fr_symbol)
4719 + fragp->fr_offset
4720 - fragp->fr_address
4721 - fragp->fr_fix);
4722
4723 switch (fragp->fr_subtype)
4724 {
4725 /* generate new insn. */
4726 case C (COND_JUMP, DISP12):
4727 case C (UNCD_JUMP, DISP12):
4728 case C (COND_JUMP_PIC, DISP12):
4729 case C (UNCD_JUMP_PIC, DISP12):
4730 {
4731 #define CSKY_V1_B_MASK 0xf8
4732 unsigned char t0;
4733 disp -= 2;
4734 if (disp & 1)
4735 {
4736 /* Error. odd displacement at %x, next_inst-2. */
4737 ;
4738 }
4739 disp >>= 1;
4740
4741 if (!target_big_endian)
4742 {
4743 t0 = buf[1] & CSKY_V1_B_MASK;
4744 md_number_to_chars (buf, disp, 2);
4745 buf[1] = (buf[1] & ~CSKY_V1_B_MASK) | t0;
4746 }
4747 else
4748 {
4749 t0 = buf[0] & CSKY_V1_B_MASK;
4750 md_number_to_chars (buf, disp, 2);
4751 buf[0] = (buf[0] & ~CSKY_V1_B_MASK) | t0;
4752 }
4753 fragp->fr_fix += 2;
4754 break;
4755 }
4756 case C (COND_JUMP, DISP32):
4757 case C (COND_JUMP, UNDEF_WORD_DISP):
4758 {
4759 /* A conditional branch wont fit into 12 bits:
4760 b!cond 1f
4761 jmpi 0f
4762 .align 2
4763 0: .long disp
4764 1:
4765 */
4766 int first_inst = fragp->fr_fix + fragp->fr_address;
4767 int is_unaligned = (first_inst & 3);
4768
4769 if (!target_big_endian)
4770 {
4771 /* b!cond instruction. */
4772 buf[1] ^= 0x08;
4773 /* jmpi instruction. */
4774 buf[2] = CSKYV1_INST_JMPI & 0xff;
4775 buf[3] = CSKYV1_INST_JMPI >> 8;
4776 }
4777 else
4778 {
4779 /* b!cond instruction. */
4780 buf[0] ^= 0x08;
4781 /* jmpi instruction. */
4782 buf[2] = CSKYV1_INST_JMPI >> 8;
4783 buf[3] = CSKYV1_INST_JMPI & 0xff;
4784 }
4785
4786 if (is_unaligned)
4787 {
4788 if (!target_big_endian)
4789 {
4790 /* bt/bf: jump to pc + 2 + (4 << 1). */
4791 buf[0] = 4;
4792 /* jmpi: jump to MEM (pc + 2 + (1 << 2)). */
4793 buf[2] = 1;
4794 }
4795 else
4796 {
4797 /* bt/bf: jump to pc + 2 + (4 << 1). */
4798 buf[1] = 4;
4799 /* jmpi: jump to MEM (pc + 2 + (1 << 2)). */
4800 buf[3] = 1;
4801 }
4802 /* Aligned 4 bytes. */
4803 buf[4] = 0;
4804 buf[5] = 0;
4805 /* .long */
4806 buf[6] = 0;
4807 buf[7] = 0;
4808 buf[8] = 0;
4809 buf[9] = 0;
4810
4811 /* Make reloc for the long disp. */
4812 fix_new (fragp, fragp->fr_fix + 6, 4,
4813 fragp->fr_symbol, fragp->fr_offset, 0, BFD_RELOC_32);
4814 fragp->fr_fix += C32_LEN;
4815 }
4816 else
4817 {
4818 if (!target_big_endian)
4819 {
4820 /* bt/bf: jump to pc + 2 + (3 << 1). */
4821 buf[0] = 3;
4822 /* jmpi: jump to MEM (pc + 2 + (0 << 2)). */
4823 buf[2] = 0;
4824 }
4825 else
4826 {
4827 /* bt/bf: jump to pc + 2 + (3 << 1). */
4828 buf[1] = 3;
4829 /* jmpi: jump to MEM (pc + 2 + (0 << 2)). */
4830 buf[3] = 0;
4831 }
4832 /* .long */
4833 buf[4] = 0;
4834 buf[5] = 0;
4835 buf[6] = 0;
4836 buf[7] = 0;
4837
4838 /* Make reloc for the long disp. */
4839 fix_new (fragp, fragp->fr_fix + 4, 4,
4840 fragp->fr_symbol, fragp->fr_offset, 0, BFD_RELOC_32);
4841 fragp->fr_fix += C32_LEN;
4842
4843 /* Frag is actually shorter (see the other side of this ifdef)
4844 but gas isn't prepared for that. We have to re-adjust
4845 the branch displacement so that it goes beyond the
4846 full length of the fragment, not just what we actually
4847 filled in. */
4848 if (!target_big_endian)
4849 buf[0] = 4;
4850 else
4851 buf[1] = 4;
4852 }
4853 }
4854 break;
4855
4856 case C (COND_JUMP_PIC, DISP32):
4857 case C (COND_JUMP_PIC, UNDEF_WORD_DISP):
4858 {
4859 #define BYTE_1(a) (target_big_endian ? ((a) & 0xff) : ((a) >> 8))
4860 #define BYTE_0(a) (target_big_endian ? ((a) >> 8) : ((a) & 0xff))
4861 /* b!cond 1f
4862 subi sp, 8
4863 stw r15, (sp, 0)
4864 bsr .L0
4865 .L0:
4866 lrw r1, 0f
4867 add r1, r15
4868 addi sp, 8
4869 jmp r1
4870 .align 2
4871 0: .long (tar_addr - pc)
4872 1:
4873 */
4874 int first_inst = fragp->fr_fix + fragp->fr_address;
4875 int is_unaligned = (first_inst & 3);
4876 disp -= 8;
4877 /* Toggle T/F bit. */
4878 if (! target_big_endian)
4879 buf[1] ^= 0x08;
4880 else
4881 buf[0] ^= 0x08;
4882 buf[2] = BYTE_0 (CSKYV1_INST_SUBI | (7 << 4)); /* subi r0, 8. */
4883 buf[3] = BYTE_1 (CSKYV1_INST_SUBI | (7 << 4));
4884 buf[4] = BYTE_0 (CSKYV1_INST_STW | (15 << 8)); /* stw r15, r0. */
4885 buf[5] = BYTE_1 (CSKYV1_INST_STW | (15 << 8));
4886 buf[6] = BYTE_0 (CSKYV1_INST_BSR); /* bsr pc + 2. */
4887 buf[7] = BYTE_1 (CSKYV1_INST_BSR);
4888 buf[8] = BYTE_0 (CSKYV1_INST_LRW | (1 << 8)); /* lrw r1, (tar_addr - pc). */
4889 buf[9] = BYTE_1 (CSKYV1_INST_LRW | (1 << 8));
4890 buf[10] = BYTE_0 (CSKYV1_INST_ADDU | (15 << 4) | 1); /* add r1, r15. */
4891 buf[11] = BYTE_1 (CSKYV1_INST_ADDU | (15 << 4) | 1);
4892 buf[12] = BYTE_0 (CSKYV1_INST_LDW | (15 << 8)); /* ldw r15, r0. */
4893 buf[13] = BYTE_1 (CSKYV1_INST_LDW | (15 << 8));
4894 buf[14] = BYTE_0 (CSKYV1_INST_ADDI | (7 << 4)); /* addi r0, 8. */
4895 buf[15] = BYTE_1 (CSKYV1_INST_ADDI | (7 << 4));
4896 buf[16] = BYTE_0 (CSKYV1_INST_JMP | 1); /* jmp r1. */
4897 buf[17] = BYTE_1 (CSKYV1_INST_JMP | 1);
4898
4899 if (!is_unaligned)
4900 {
4901 if (!target_big_endian)
4902 {
4903 buf[0] = 11;
4904 buf[8] = 3;
4905 buf[20] = disp & 0xff;
4906 buf[21] = (disp >> 8) & 0xff;
4907 buf[22] = (disp >> 16) & 0xff;
4908 buf[23] = (disp >> 24) & 0xff;
4909 }
4910 else /* if !target_big_endian. */
4911 {
4912 buf[1] = 11;
4913 buf[9] = 3;
4914 buf[20] = (disp >> 24) & 0xff;
4915 buf[21] = (disp >> 16) & 0xff;
4916 buf[22] = (disp >> 8) & 0xff;
4917 buf[23] = disp & 0xff;
4918 }
4919 buf[18] = 0; /* alignment. */
4920 buf[19] = 0;
4921 fragp->fr_fix += C32_LEN_PIC;
4922 }
4923 else /* if !is_unaligned. */
4924 {
4925 if (!target_big_endian)
4926 {
4927 buf[0] = 11;
4928 buf[8] = 2;
4929 buf[18] = disp & 0xff;
4930 buf[19] = (disp >> 8) & 0xff;
4931 buf[20] = (disp >> 16) & 0xff;
4932 buf[21] = (disp >> 24) & 0xff;
4933 }
4934 else /* if !target_big_endian. */
4935 {
4936 buf[1] = 11;
4937 buf[9] = 2;
4938 buf[18] = (disp >> 24) & 0xff;
4939 buf[19] = (disp >> 16) & 0xff;
4940 buf[20] = (disp >> 8) & 0xff;
4941 buf[21] = disp & 0xff;
4942 }
4943 buf[22] = 0; /* initialise. */
4944 buf[23] = 0;
4945 fragp->fr_fix += C32_LEN_PIC;
4946
4947 } /* end if is_unaligned. */
4948 } /* end case C (COND_JUMP_PIC, DISP32)/C (COND_JUMP_PIC, UNDEF_WORD_DISP). */
4949 break;
4950 case C (UNCD_JUMP, DISP32):
4951 case C (UNCD_JUMP, UNDEF_WORD_DISP):
4952 {
4953 /* jmpi 0f
4954 .align 2
4955 0: .long disp. */
4956 int first_inst = fragp->fr_fix + fragp->fr_address;
4957 int is_unaligned = (first_inst & 3);
4958 /* Build jmpi. */
4959 buf[0] = BYTE_0 (CSKYV1_INST_JMPI);
4960 buf[1] = BYTE_1 (CSKYV1_INST_JMPI);
4961 if (!is_unaligned)
4962 {
4963 if (!target_big_endian)
4964 buf[0] = 1;
4965 else
4966 buf[1] = 1;
4967 /* Alignment. */
4968 buf[2] = 0;
4969 buf[3] = 0;
4970 /* .long */
4971 buf[4] = 0;
4972 buf[5] = 0;
4973 buf[6] = 0;
4974 buf[7] = 0;
4975 fix_new (fragp, fragp->fr_fix + 4, 4,
4976 fragp->fr_symbol, fragp->fr_offset, 0, BFD_RELOC_32);
4977 fragp->fr_fix += U32_LEN;
4978 }
4979 else /* if is_unaligned. */
4980 {
4981 if (!target_big_endian)
4982 buf[0] = 0;
4983 else
4984 buf[1] = 0;
4985 /* .long */
4986 buf[2] = 0;
4987 buf[3] = 0;
4988 buf[4] = 0;
4989 buf[5] = 0;
4990 fix_new (fragp, fragp->fr_fix + 2, 4,
4991 fragp->fr_symbol, fragp->fr_offset, 0, BFD_RELOC_32);
4992 fragp->fr_fix += U32_LEN;
4993
4994 }
4995 }
4996 break;
4997 case C (UNCD_JUMP_PIC, DISP32):
4998 case C (UNCD_JUMP_PIC, UNDEF_WORD_DISP):
4999 {
5000 /* subi sp, 8
5001 stw r15, (sp)
5002 bsr .L0
5003 .L0:
5004 lrw r1, 0f
5005 add r1, r15
5006 ldw r15, (sp)
5007 addi sp, 8
5008 jmp r1
5009 .align 2
5010 0: .long (tar_add - pc)
5011 1:
5012 */
5013 /* If the b!cond is 4 byte aligned, the literal which would
5014 go at x+4 will also be aligned. */
5015 int first_inst = fragp->fr_fix + fragp->fr_address;
5016 int is_unaligned = (first_inst & 3);
5017 disp -= 6;
5018
5019 buf[0] = BYTE_0 (CSKYV1_INST_SUBI | (7 << 4)); /* subi r0, 8. */
5020 buf[1] = BYTE_1 (CSKYV1_INST_SUBI | (7 << 4));
5021 buf[2] = BYTE_0 (CSKYV1_INST_STW | (15 << 8)); /* stw r15, r0. */
5022 buf[3] = BYTE_1 (CSKYV1_INST_STW | (15 << 8));
5023 buf[4] = BYTE_0 (CSKYV1_INST_BSR); /* bsr pc + 2. */
5024 buf[5] = BYTE_1 (CSKYV1_INST_BSR);
5025 buf[6] = BYTE_0 (CSKYV1_INST_LRW | (1 << 8)); /* lrw r1, (tar_addr - pc). */
5026 buf[7] = BYTE_1 (CSKYV1_INST_LRW | (1 << 8));
5027 buf[8] = BYTE_0 (CSKYV1_INST_ADDU | (15 << 4) | 1); /* add r1, r15. */
5028 buf[9] = BYTE_1 (CSKYV1_INST_ADDU | (15 << 4) | 1);
5029 buf[10] = BYTE_0 (CSKYV1_INST_LDW | (15 << 8)); /* ldw r15, r0. */
5030 buf[11] = BYTE_1 (CSKYV1_INST_LDW | (15 << 8));
5031 buf[12] = BYTE_0 (CSKYV1_INST_ADDI | (7 << 4)); /* addi r0, 8. */
5032 buf[13] = BYTE_1 (CSKYV1_INST_ADDI | (7 << 4));
5033 buf[14] = BYTE_0 (CSKYV1_INST_JMP | 1); /* jmp r1. */
5034 buf[15] = BYTE_1 (CSKYV1_INST_JMP | 1);
5035
5036 if (is_unaligned)
5037 {
5038 if (!target_big_endian)
5039 {
5040 buf[6] = 3;
5041 buf[18] = disp & 0xff;
5042 buf[19] = (disp >> 8) & 0xff;
5043 buf[20] = (disp >> 16) & 0xff;
5044 buf[21] = (disp >> 24) & 0xff;
5045 }
5046 else
5047 {
5048 buf[7] = 3;
5049 buf[18] = (disp >> 24) & 0xff;
5050 buf[19] = (disp >> 16) & 0xff;
5051 buf[20] = (disp >> 8) & 0xff;
5052 buf[21] = disp & 0xff;
5053 }
5054 buf[16] = 0;
5055 buf[17] = 0;
5056 fragp->fr_fix += U32_LEN_PIC;
5057 }
5058 else
5059 {
5060 if (!target_big_endian)
5061 {
5062 buf[6] = 2;
5063 buf[16] = disp & 0xff;
5064 buf[17] = (disp >> 8) & 0xff;
5065 buf[18] = (disp >> 16) & 0xff;
5066 buf[19] = (disp >> 24) & 0xff;
5067 }
5068 else
5069 {
5070 buf[7] = 2;
5071 buf[16] = (disp >> 24) & 0xff;
5072 buf[17] = (disp >> 16) & 0xff;
5073 buf[18] = (disp >> 8) & 0xff;
5074 buf[19] = disp & 0xff;
5075 }
5076 fragp->fr_fix += U32_LEN_PIC;
5077 }
5078 }
5079 break;
5080 case COND_DISP10:
5081 case SCOND_DISP10:
5082 case UNCD_DISP10:
5083 case JCOND_DISP10:
5084 case JUNCD_DISP10:
5085 {
5086 unsigned int inst = csky_read_insn (buf, 2);
5087 inst |= (disp >> 1) & ((1 << 10) - 1);
5088 csky_write_insn (buf, inst, 2);
5089 fragp->fr_fix += 2;
5090 break;
5091 }
5092 case SCOND_DISP16:
5093 {
5094 unsigned int inst = csky_read_insn (buf, 2);
5095
5096 if (inst == CSKYV2_INST_BT16)
5097 inst = CSKYV2_INST_BF16;
5098 else
5099 inst = CSKYV2_INST_BT16;
5100 make_insn (2, inst, (2 + 4) >> 1, 10);
5101 if (IS_EXTERNAL_SYM (fragp->fr_symbol, asec))
5102 fix_new (fragp, fragp->fr_fix, 4,
5103 fragp->fr_symbol, fragp->fr_offset, 1,
5104 BFD_RELOC_CKCORE_PCREL_IMM16BY2);
5105 disp -= 2;
5106 inst = CSKYV2_INST_BR32 | ((disp >> 1) & ((1 << 16) - 1));
5107 csky_write_insn (buf, inst, 4);
5108 fragp->fr_fix += 4;
5109 break;
5110 }
5111 case COND_DISP16:
5112 case JCOND_DISP16:
5113 {
5114 unsigned int inst = csky_read_insn (buf, 2);
5115
5116 if (inst == CSKYV2_INST_BT16)
5117 inst = CSKYV2_INST_BT32;
5118 else
5119 inst = CSKYV2_INST_BF32;
5120 if (IS_EXTERNAL_SYM (fragp->fr_symbol, asec))
5121 fix_new (fragp, fragp->fr_fix, 4,
5122 fragp->fr_symbol, fragp->fr_offset, 1,
5123 BFD_RELOC_CKCORE_PCREL_IMM16BY2);
5124 inst |= (disp >> 1) & ((1 << 16) - 1);
5125 csky_write_insn (buf, inst, 4);
5126 fragp->fr_fix += 4;
5127 break;
5128 }
5129 case LRW_DISP7:
5130 {
5131 unsigned int inst = csky_read_insn (buf, 2);
5132 int imm;
5133 imm = (disp + 2) >> 2;
5134 inst |= (imm >> 5) << 8;
5135 make_insn (2, inst, (imm & 0x1f), 5);
5136 break;
5137 }
5138 case LRW2_DISP8:
5139 {
5140 unsigned int inst = csky_read_insn (buf, 2);
5141 int imm = (disp + 2) >> 2;
5142 if (imm >= 0x80)
5143 {
5144 inst &= 0xe0;
5145 inst |= (~((imm >> 5) << 8)) & 0x300;
5146 make_insn (2, inst, (~imm & 0x1f), 5);
5147 }
5148 else
5149 {
5150 inst |= (imm >> 5) << 8;
5151 make_insn (2, inst, (imm & 0x1f), 5);
5152 }
5153 break;
5154 }
5155 case LRW_DISP16:
5156 {
5157 unsigned int inst = csky_read_insn (buf, 2);
5158 inst = CSKYV2_INST_LRW32 | (((inst & 0xe0) >> 5) << 16);
5159 if (IS_EXTERNAL_SYM (fragp->fr_symbol, asec))
5160 fix_new (fragp, fragp->fr_fix, 4,
5161 fragp->fr_symbol, fragp->fr_offset, 1,
5162 BFD_RELOC_CKCORE_PCREL_IMM16BY4);
5163 make_insn (4, inst, ((disp + 2) >> 2), 16);
5164 break;
5165 }
5166 case JCOMPZ_DISP16:
5167 {
5168 unsigned int inst = csky_read_insn (buf, 4);
5169 make_insn (4, inst, disp >> 1, 16);
5170 }
5171 break;
5172 case JCOMPZ_DISP32:
5173 {
5174 unsigned int inst = csky_read_insn (buf, 4);
5175 int literal_offset;
5176 make_insn (4, opposite_of_stored_compz (inst),
5177 (4 + 4 + PAD_LITERAL_LENGTH) >> 1, 16);
5178 literal_offset = ((fragp->fr_address + fragp->fr_fix) % 4 == 0
5179 ? 0 : 2);
5180 make_insn (4, CSKYV2_INST_JMPI32, (4 + literal_offset + 2) >> 2, 10);
5181 make_literal (fragp, literal_offset);
5182 }
5183 break;
5184 case JUNCD_DISP16:
5185 case UNCD_DISP16:
5186 {
5187 if (IS_EXTERNAL_SYM (fragp->fr_symbol, asec))
5188 fix_new (fragp, fragp->fr_fix, 4,
5189 fragp->fr_symbol, fragp->fr_offset, 1,
5190 BFD_RELOC_CKCORE_PCREL_IMM16BY2);
5191 make_insn (4, CSKYV2_INST_BR32, disp >> 1, 16);
5192 }
5193 break;
5194 case JCOND_DISP32:
5195 {
5196 /* 'jbt'/'jbf'-> <bf16/bt16>; jmpi32; [pad16]+literal32 */
5197 unsigned int inst = csky_read_insn (buf, 2);
5198 int literal_offset;
5199
5200 if (inst == CSKYV2_INST_BT16)
5201 inst = CSKYV2_INST_BF16;
5202 else
5203 inst = CSKYV2_INST_BT16;
5204 make_insn (2, inst, (2 + 4 + PAD_LITERAL_LENGTH) >> 1, 10);
5205 literal_offset = ((fragp->fr_address + fragp->fr_fix) % 4 == 0
5206 ? 0 : 2);
5207 make_insn (4, CSKYV2_INST_JMPI32, (4 + literal_offset + 2) >> 2, 10);
5208 make_literal (fragp, literal_offset);
5209 break;
5210 }
5211 case JUNCD_DISP32:
5212 {
5213 int literal_offset;
5214 literal_offset = ((fragp->fr_address + fragp->fr_fix) % 4 == 0
5215 ? 0 : 2);
5216 make_insn (4, CSKYV2_INST_JMPI32, (4 + literal_offset + 2) >> 2, 10);
5217 make_literal (fragp, literal_offset);
5218 }
5219 break;
5220 case RELAX_OVERFLOW:
5221 csky_branch_report_error (fragp->fr_file, fragp->fr_line,
5222 fragp->fr_symbol, disp);
5223 break;
5224 default:
5225 abort ();
5226 break;
5227 }
5228 }
5229
5230 /* Round up a section size to the appropriate boundary. */
5231
5232 valueT
5233 md_section_align (segT segment ATTRIBUTE_UNUSED,
5234 valueT size)
5235 {
5236 return size;
5237 }
5238
5239 /* MD interface: Symbol and relocation handling. */
5240
5241 void csky_md_finish (void)
5242 {
5243 dump_literals (0);
5244 }
5245
5246 /* Return the address within the segment that a PC-relative fixup is
5247 relative to. */
5248
5249 long
5250 md_pcrel_from_section (fixS * fixP, segT seg)
5251 {
5252 /* If the symbol is undefined or defined in another section
5253 we leave the add number alone for the linker to fix it later. */
5254 if (fixP->fx_addsy != (symbolS *) NULL
5255 && (! S_IS_DEFINED (fixP->fx_addsy)
5256 || S_GET_SEGMENT (fixP->fx_addsy) != seg))
5257 return fixP->fx_size;
5258
5259 /* The case where we are going to resolve things. */
5260 return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
5261 }
5262
5263 /* csky_cons_fix_new is called via the expression parsing code when a
5264 reloc is needed. We use this hook to get the correct .got reloc. */
5265
5266 void
5267 csky_cons_fix_new (fragS *frag,
5268 unsigned int off,
5269 unsigned int len,
5270 expressionS *exp,
5271 bfd_reloc_code_real_type reloc)
5272 {
5273 fixS *fixP;
5274
5275 if (BFD_RELOC_CKCORE_GOTOFF == insn_reloc
5276 || BFD_RELOC_CKCORE_GOTPC == insn_reloc
5277 || BFD_RELOC_CKCORE_GOT32 == insn_reloc
5278 || BFD_RELOC_CKCORE_PLT32 == insn_reloc
5279 || BFD_RELOC_CKCORE_TLS_LE32 == insn_reloc
5280 || BFD_RELOC_CKCORE_TLS_GD32 == insn_reloc
5281 || BFD_RELOC_CKCORE_TLS_LDM32 == insn_reloc
5282 || BFD_RELOC_CKCORE_TLS_LDO32 == insn_reloc
5283 || BFD_RELOC_CKCORE_TLS_IE32 == insn_reloc)
5284 reloc = insn_reloc;
5285 else
5286 switch (len)
5287 {
5288 case 1:
5289 reloc = BFD_RELOC_8;
5290 break;
5291 case 2:
5292 reloc = BFD_RELOC_16;
5293 break;
5294 case 4:
5295 reloc = BFD_RELOC_32;
5296 break;
5297 case 8:
5298 reloc = BFD_RELOC_64;
5299 break;
5300 default:
5301 as_bad (_("unsupported BFD relocation size %d"), len);
5302 reloc = BFD_RELOC_32;
5303 break;
5304 }
5305 fixP = fix_new_exp (frag, off, (int) len, exp, 0, reloc);
5306 if (BFD_RELOC_CKCORE_TLS_IE32 == insn_reloc
5307 || BFD_RELOC_CKCORE_TLS_GD32 == insn_reloc
5308 || BFD_RELOC_CKCORE_TLS_LDM32 == insn_reloc)
5309 {
5310 fixP->tc_fix_data.frag = literal_insn_offset->tls_addend.frag;
5311 fixP->tc_fix_data.offset = literal_insn_offset->tls_addend.offset;
5312 }
5313 }
5314
5315 /* See whether we need to force a relocation into the output file.
5316 This is used to force out switch and PC relative relocations when
5317 relaxing. */
5318
5319 int
5320 csky_force_relocation (fixS * fix)
5321 {
5322 if (fix->fx_r_type == BFD_RELOC_VTABLE_INHERIT
5323 || fix->fx_r_type == BFD_RELOC_VTABLE_ENTRY
5324 || fix->fx_r_type == BFD_RELOC_RVA
5325 || fix->fx_r_type == BFD_RELOC_CKCORE_ADDR_HI16
5326 || fix->fx_r_type == BFD_RELOC_CKCORE_ADDR_LO16
5327 || fix->fx_r_type == BFD_RELOC_CKCORE_TOFFSET_LO16
5328 || fix->fx_r_type == BFD_RELOC_CKCORE_DOFFSET_LO16)
5329 return 1;
5330
5331 if (fix->fx_addsy == NULL)
5332 return 0;
5333
5334 if (do_use_branchstub
5335 && fix->fx_r_type == BFD_RELOC_CKCORE_PCREL_IMM26BY2
5336 && (symbol_get_bfdsym (fix->fx_addsy)->flags & BSF_FUNCTION))
5337 return 1;
5338 return S_FORCE_RELOC (fix->fx_addsy, fix->fx_subsy == NULL);
5339 }
5340
5341 /* Return true if the fix can be handled by GAS, false if it must
5342 be passed through to the linker. */
5343
5344 bool
5345 csky_fix_adjustable (fixS * fixP)
5346 {
5347 if (fixP->fx_addsy == NULL)
5348 return 1;
5349
5350 /* We need the symbol name for the VTABLE entries. */
5351 if (fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
5352 || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY
5353 || fixP->fx_r_type == BFD_RELOC_CKCORE_PLT32
5354 || fixP->fx_r_type == BFD_RELOC_CKCORE_GOT32
5355 || fixP->fx_r_type == BFD_RELOC_CKCORE_PLT12
5356 || fixP->fx_r_type == BFD_RELOC_CKCORE_GOT12
5357 || fixP->fx_r_type == BFD_RELOC_CKCORE_GOT_HI16
5358 || fixP->fx_r_type == BFD_RELOC_CKCORE_GOT_LO16
5359 || fixP->fx_r_type == BFD_RELOC_CKCORE_PLT_HI16
5360 || fixP->fx_r_type == BFD_RELOC_CKCORE_PLT_LO16
5361 || fixP->fx_r_type == BFD_RELOC_CKCORE_GOTOFF
5362 || fixP->fx_r_type == BFD_RELOC_CKCORE_GOTOFF_HI16
5363 || fixP->fx_r_type == BFD_RELOC_CKCORE_GOTOFF_LO16
5364 || fixP->fx_r_type == BFD_RELOC_CKCORE_ADDR_HI16
5365 || fixP->fx_r_type == BFD_RELOC_CKCORE_ADDR_LO16
5366 || fixP->fx_r_type == BFD_RELOC_CKCORE_GOT_IMM18BY4
5367 || fixP->fx_r_type == BFD_RELOC_CKCORE_PLT_IMM18BY4
5368 || fixP->fx_r_type == BFD_RELOC_CKCORE_GOTOFF_IMM18
5369 || fixP->fx_r_type == BFD_RELOC_CKCORE_TLS_LE32
5370 || fixP->fx_r_type == BFD_RELOC_CKCORE_TLS_IE32
5371 || fixP->fx_r_type == BFD_RELOC_CKCORE_TLS_GD32
5372 || fixP->fx_r_type == BFD_RELOC_CKCORE_TLS_LDM32
5373 || fixP->fx_r_type == BFD_RELOC_CKCORE_TLS_LDO32)
5374 return 0;
5375
5376 if (do_use_branchstub
5377 && fixP->fx_r_type == BFD_RELOC_CKCORE_PCREL_IMM26BY2
5378 && (symbol_get_bfdsym (fixP->fx_addsy)->flags & BSF_FUNCTION))
5379 return 0;
5380
5381 return 1;
5382 }
5383
5384 void
5385 md_apply_fix (fixS *fixP,
5386 valueT *valP,
5387 segT seg)
5388 {
5389 reloc_howto_type *howto;
5390 /* Note: use offsetT because it is signed, valueT is unsigned. */
5391 offsetT val = *valP;
5392 char *buf = fixP->fx_frag->fr_literal + fixP->fx_where;
5393
5394 /* if fx_done = 0, fixup will also be processed in
5395 * tc_gen_reloc() after md_apply_fix(). */
5396 fixP->fx_done = 0;
5397
5398 /* If the fix is relative to a symbol which is not defined, or not
5399 in the same segment as the fix, we cannot resolve it here. */
5400 if (IS_CSKY_V1 (mach_flag) && fixP->fx_addsy != NULL
5401 && (! S_IS_DEFINED (fixP->fx_addsy)
5402 || S_GET_SEGMENT (fixP->fx_addsy) != seg))
5403 {
5404 switch (fixP->fx_r_type)
5405 {
5406 /* Data fx_addnumber is greater than 16 bits,
5407 so fx_addnumber is assigned zero. */
5408 case BFD_RELOC_CKCORE_PCREL_JSR_IMM11BY2:
5409 *valP = 0;
5410 break;
5411 case BFD_RELOC_CKCORE_TLS_IE32:
5412 case BFD_RELOC_CKCORE_TLS_LDM32:
5413 case BFD_RELOC_CKCORE_TLS_GD32:
5414 {
5415 struct tls_addend *ta = &(fixP->tc_fix_data);
5416 fixP->fx_offset = (fixP->fx_frag->fr_address + fixP->fx_where
5417 - (ta->frag->fr_address + ta->offset));
5418 *valP = fixP->fx_offset;
5419 }
5420 /* Fall through. */
5421 case BFD_RELOC_CKCORE_TLS_LE32:
5422 case BFD_RELOC_CKCORE_TLS_LDO32:
5423 S_SET_THREAD_LOCAL (fixP->fx_addsy);
5424 break;
5425 default:
5426 break;
5427 }
5428 #ifdef OBJ_ELF
5429 /* For ELF we can just return and let the reloc that will be generated
5430 take care of everything. For COFF we still have to insert 'val'
5431 into the insn since the addend field will be ignored. */
5432 return;
5433 #endif
5434 }
5435
5436 /* We can handle these relocs. */
5437 switch (fixP->fx_r_type)
5438 {
5439 case BFD_RELOC_32_PCREL:
5440 case BFD_RELOC_CKCORE_PCREL32:
5441 fixP->fx_r_type = BFD_RELOC_CKCORE_PCREL32;
5442 break;
5443 case BFD_RELOC_VTABLE_INHERIT:
5444 fixP->fx_r_type = BFD_RELOC_CKCORE_GNU_VTINHERIT;
5445 if (fixP->fx_addsy && !S_IS_DEFINED (fixP->fx_addsy)
5446 && !S_IS_WEAK (fixP->fx_addsy))
5447 S_SET_WEAK (fixP->fx_addsy);
5448 break;
5449 case BFD_RELOC_VTABLE_ENTRY:
5450 fixP->fx_r_type = BFD_RELOC_CKCORE_GNU_VTENTRY;
5451 break;
5452 case BFD_RELOC_CKCORE_GOT12:
5453 case BFD_RELOC_CKCORE_PLT12:
5454 case BFD_RELOC_CKCORE_ADDR_HI16:
5455 case BFD_RELOC_CKCORE_ADDR_LO16:
5456 case BFD_RELOC_CKCORE_TOFFSET_LO16:
5457 case BFD_RELOC_CKCORE_DOFFSET_LO16:
5458 case BFD_RELOC_CKCORE_GOT_HI16:
5459 case BFD_RELOC_CKCORE_GOT_LO16:
5460 case BFD_RELOC_CKCORE_PLT_HI16:
5461 case BFD_RELOC_CKCORE_PLT_LO16:
5462 case BFD_RELOC_CKCORE_GOTPC_HI16:
5463 case BFD_RELOC_CKCORE_GOTPC_LO16:
5464 case BFD_RELOC_CKCORE_GOTOFF_HI16:
5465 case BFD_RELOC_CKCORE_GOTOFF_LO16:
5466 case BFD_RELOC_CKCORE_DOFFSET_IMM18:
5467 case BFD_RELOC_CKCORE_DOFFSET_IMM18BY2:
5468 case BFD_RELOC_CKCORE_DOFFSET_IMM18BY4:
5469 case BFD_RELOC_CKCORE_GOTOFF_IMM18:
5470 case BFD_RELOC_CKCORE_GOT_IMM18BY4:
5471 case BFD_RELOC_CKCORE_PLT_IMM18BY4:
5472 break;
5473 case BFD_RELOC_CKCORE_TLS_IE32:
5474 case BFD_RELOC_CKCORE_TLS_LDM32:
5475 case BFD_RELOC_CKCORE_TLS_GD32:
5476 {
5477 struct tls_addend *ta = &(fixP->tc_fix_data);
5478 fixP->fx_offset = (fixP->fx_frag->fr_address + fixP->fx_where
5479 - (ta->frag->fr_address + ta->offset));
5480 *valP = fixP->fx_offset;
5481 }
5482 /* Fall through. */
5483 case BFD_RELOC_CKCORE_TLS_LE32:
5484 case BFD_RELOC_CKCORE_TLS_LDO32:
5485 S_SET_THREAD_LOCAL (fixP->fx_addsy);
5486 break;
5487 case BFD_RELOC_32:
5488 fixP->fx_r_type = BFD_RELOC_CKCORE_ADDR32;
5489 /* Fall through. */
5490 case BFD_RELOC_16:
5491 case BFD_RELOC_8:
5492 if (fixP->fx_addsy == NULL)
5493 {
5494 if (fixP->fx_size == 4)
5495 ;
5496 else if (fixP->fx_size == 2 && val >= -32768 && val <= 32767)
5497 ;
5498 else if (fixP->fx_size == 1 && val >= -256 && val <= 255)
5499 ;
5500 else
5501 break;
5502
5503 md_number_to_chars (buf, val, fixP->fx_size);
5504 fixP->fx_done = 1;
5505 }
5506 break;
5507 case BFD_RELOC_CKCORE_PCREL_JSR_IMM11BY2:
5508 if (fixP->fx_addsy == 0 && val > -2 KB && val < 2 KB)
5509 {
5510 long nval = (val >> 1) & 0x7ff;
5511 nval |= CSKYV1_INST_BSR;
5512 csky_write_insn (buf, nval, 2);
5513 fixP->fx_done = 1;
5514 }
5515 else
5516 *valP = 0;
5517 break;
5518 case BFD_RELOC_CKCORE_PCREL_JSR_IMM26BY2:
5519 if (fixP->fx_addsy == 0)
5520 {
5521 if (val >= -(1 << 26) && val < (1 << 26))
5522 {
5523 unsigned int nval = ((val + fixP->fx_size) >> 1) & 0x3ffffff;
5524 nval |= CSKYV2_INST_BSR32;
5525
5526 csky_write_insn (buf, nval, 4);
5527 }
5528 /* If bsr32 cannot reach,
5529 generate 'lrw r25,label;jsr r25' instead of 'jsri label'. */
5530 else if (IS_CSKY_ARCH_810 (mach_flag))
5531 {
5532 howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
5533 valueT opcode = csky_read_insn (buf, 4);
5534 opcode = (opcode & howto->dst_mask) | CSKYV2_INST_JSRI_TO_LRW;
5535 csky_write_insn (buf, opcode, 4);
5536 opcode = CSKYV2_INST_JSR_R26;
5537 csky_write_insn (buf + 4, opcode, 4);
5538 }
5539 fixP->fx_done = 1;
5540 }
5541 break;
5542
5543 default:
5544 {
5545 valueT opcode;
5546 offsetT min, max;
5547 unsigned int issigned = 0;
5548
5549 if (fixP->fx_addsy)
5550 break;
5551
5552 howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
5553 if (howto == NULL)
5554 {
5555 if (fixP->fx_size == 4
5556 || (fixP->fx_size == 2 && val >= -32768 && val <= 32767)
5557 || (fixP->fx_size == 1 && val >= -256 && val <= 255))
5558 {
5559 md_number_to_chars (buf, val, fixP->fx_size);
5560 fixP->fx_done = 1;
5561 break;
5562 }
5563 else
5564 abort ();
5565 }
5566
5567 if (IS_CSKY_V2 (mach_flag))
5568 val += fixP->fx_size;
5569
5570 if (howto->rightshift == 2)
5571 val += 2;
5572
5573 val >>= howto->rightshift;
5574
5575 switch (fixP->fx_r_type)
5576 {
5577 /* Offset is unsigned. */
5578 case BFD_RELOC_CKCORE_PCREL_IMM8BY4:
5579 case BFD_RELOC_CKCORE_PCREL_IMM10BY4:
5580 case BFD_RELOC_CKCORE_PCREL_IMM16BY4:
5581 max = (offsetT) howto->dst_mask;
5582 min = 0;
5583 break;
5584 /* lrw16. */
5585 case BFD_RELOC_CKCORE_PCREL_IMM7BY4:
5586 if (do_extend_lrw)
5587 max = (offsetT)((1 << (howto->bitsize + 1)) - 2);
5588 else
5589 max = (offsetT)((1 << howto->bitsize) - 1);
5590 min = 0;
5591 break;
5592 /* flrws, flrwd: the offset bits are divided in two parts. */
5593 case BFD_RELOC_CKCORE_PCREL_FLRW_IMM8BY4:
5594 max = (offsetT)((1 << howto->bitsize) - 1);
5595 min = 0;
5596 break;
5597 /* Offset is signed. */
5598 default:
5599 max = (offsetT)(howto->dst_mask >> 1);
5600 min = - max - 1;
5601 issigned = 1;
5602 }
5603 if (val < min || val > max)
5604 {
5605 csky_branch_report_error (fixP->fx_file, fixP->fx_line,
5606 fixP->fx_addsy, val);
5607 return;
5608 }
5609 opcode = csky_read_insn (buf, fixP->fx_size);
5610 /* Clear redundant bits brought from the last
5611 operation if there is any. */
5612 if (do_extend_lrw && (opcode & 0xfc00) == CSKYV2_INST_LRW16)
5613 val &= 0xff;
5614 else
5615 val &= issigned ? (offsetT)(howto->dst_mask) : max;
5616
5617 if (fixP->fx_r_type == BFD_RELOC_CKCORE_PCREL_BLOOP_IMM4BY4)
5618 val = (val & 0xf) << 12;
5619
5620 if (fixP->fx_size == 2 && (opcode & 0xfc00) == CSKYV2_INST_LRW16)
5621 {
5622 /* 8 bit offset lrw16. */
5623 if (val >= 0x80)
5624 csky_write_insn (buf,
5625 ((~val & 0x1f)
5626 | ((~val & 0x60) << 3) | (opcode & 0xe0)),
5627 fixP->fx_size);
5628 /* 7 bit offset lrw16. */
5629 else
5630 csky_write_insn (buf,
5631 (val & 0x1f) | ((val & 0x60) << 3) | opcode,
5632 fixP->fx_size);
5633 }
5634 else if (fixP->fx_size == 4
5635 && (opcode & 0xfe1ffe00) == CSKYV2_INST_FLRW)
5636 csky_write_insn (buf,
5637 ((val & 0xf) << 4) | ((val & 0xf0) << 17) | opcode,
5638 fixP->fx_size);
5639 else
5640 csky_write_insn (buf, val | opcode, fixP->fx_size);
5641 fixP->fx_done = 1;
5642 break;
5643 }
5644 }
5645 fixP->fx_addnumber = val;
5646 }
5647
5648 /* Translate internal representation of relocation info to BFD target
5649 format. */
5650
5651 arelent *
5652 tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixP)
5653 {
5654 arelent *rel;
5655
5656 if (fixP->fx_pcrel
5657 && fixP->fx_r_type == BFD_RELOC_CKCORE_ADDR32)
5658 fixP->fx_r_type = BFD_RELOC_CKCORE_PCREL32;
5659
5660 rel = xmalloc (sizeof (arelent));
5661 rel->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
5662 *rel->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
5663 rel->howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
5664 rel->addend = fixP->fx_offset;
5665 if (rel->howto == NULL)
5666 {
5667 as_bad_where (fixP->fx_file, fixP->fx_line,
5668 _("cannot represent `%s' relocation in object file"),
5669 bfd_get_reloc_code_name (fixP->fx_r_type));
5670
5671 /* Set howto to a garbage value so that we can keep going. */
5672 rel->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_32);
5673 }
5674 gas_assert (rel->howto != NULL);
5675 rel->address = fixP->fx_frag->fr_address + fixP->fx_where;
5676 return rel;
5677 }
5678
5679 /* Relax a fragment by scanning TC_GENERIC_RELAX_TABLE. */
5680
5681 long
5682 csky_relax_frag (segT segment, fragS *fragP, long stretch)
5683 {
5684 const relax_typeS *this_type;
5685 const relax_typeS *start_type;
5686 relax_substateT next_state;
5687 relax_substateT this_state;
5688 offsetT growth;
5689 offsetT aim;
5690 addressT target;
5691 addressT address;
5692 symbolS *symbolP;
5693 const relax_typeS *table;
5694
5695 target = fragP->fr_offset;
5696 address = fragP->fr_address;
5697 table = TC_GENERIC_RELAX_TABLE;
5698 this_state = fragP->fr_subtype;
5699 start_type = this_type = table + this_state;
5700 symbolP = fragP->fr_symbol;
5701
5702 if (symbolP)
5703 {
5704 fragS *sym_frag;
5705
5706 sym_frag = symbol_get_frag (symbolP);
5707
5708 #ifndef DIFF_EXPR_OK
5709 know (sym_frag != NULL);
5710 #endif
5711 know (S_GET_SEGMENT (symbolP) != absolute_section
5712 || sym_frag == &zero_address_frag);
5713 target += S_GET_VALUE (symbolP);
5714
5715 /* If SYM_FRAG has yet to be reached on this pass, assume it
5716 will move by STRETCH just as we did, unless there is an
5717 alignment frag between here and SYM_FRAG. An alignment may
5718 well absorb any STRETCH, and we don't want to choose a larger
5719 branch insn by overestimating the needed reach of this
5720 branch. It isn't critical to calculate TARGET exactly; We
5721 know we'll be doing another pass if STRETCH is non-zero. */
5722
5723 if (stretch != 0
5724 && sym_frag->relax_marker != fragP->relax_marker
5725 && S_GET_SEGMENT (symbolP) == segment)
5726 {
5727 fragS *f;
5728
5729 /* Adjust stretch for any alignment frag. Note that if have
5730 been expanding the earlier code, the symbol may be
5731 defined in what appears to be an earlier frag. FIXME:
5732 This doesn't handle the fr_subtype field, which specifies
5733 a maximum number of bytes to skip when doing an
5734 alignment. */
5735 for (f = fragP; f != NULL && f != sym_frag; f = f->fr_next)
5736 {
5737 if (f->fr_type == rs_align || f->fr_type == rs_align_code)
5738 {
5739 if (stretch < 0)
5740 stretch = -((-stretch)
5741 & ~((1 << (int) f->fr_offset) - 1));
5742 else
5743 stretch &= ~((1 << (int) f->fr_offset) - 1);
5744 }
5745 if (stretch == 0)
5746 break;
5747 }
5748 if (f != 0)
5749 target += stretch;
5750 }
5751 }
5752
5753 aim = target - address - fragP->fr_fix;
5754
5755 /* If the fragP->fr_symbol is extern symbol, aim should be 0. */
5756 if (fragP->fr_symbol && S_GET_SEGMENT (symbolP) != segment)
5757 aim = 0;
5758
5759 if (aim < 0)
5760 {
5761 /* Look backwards. */
5762 for (next_state = this_type->rlx_more; next_state;)
5763 if (aim >= this_type->rlx_backward)
5764 next_state = 0;
5765 else
5766 {
5767 /* Grow to next state. */
5768 this_state = next_state;
5769 this_type = table + this_state;
5770 next_state = this_type->rlx_more;
5771 }
5772 }
5773 else
5774 {
5775 /* Look forwards. */
5776 for (next_state = this_type->rlx_more; next_state;)
5777 if (aim <= this_type->rlx_forward)
5778 next_state = 0;
5779 else
5780 {
5781 /* Grow to next state. */
5782 this_state = next_state;
5783 this_type = table + this_state;
5784 next_state = this_type->rlx_more;
5785 }
5786 }
5787
5788 growth = this_type->rlx_length - start_type->rlx_length;
5789 if (growth != 0)
5790 fragP->fr_subtype = this_state;
5791 return growth;
5792 }
5793
5794 int
5795 md_estimate_size_before_relax (fragS * fragp,
5796 segT segtype)
5797 {
5798 switch (fragp->fr_subtype)
5799 {
5800 case COND_DISP10:
5801 case COND_DISP16:
5802 case SCOND_DISP10:
5803 case SCOND_DISP16:
5804 case UNCD_DISP10:
5805 case UNCD_DISP16:
5806 case JCOND_DISP10:
5807 case JCOND_DISP16:
5808 case JCOND_DISP32:
5809 case JUNCD_DISP10:
5810 case JUNCD_DISP16:
5811 case JUNCD_DISP32:
5812 case JCOMPZ_DISP16:
5813 case JCOMPZ_DISP32:
5814 case BSR_DISP26:
5815 case LRW_DISP7:
5816 case LRW2_DISP8:
5817 case LRW_DISP16:
5818 gas_assert (fragp->fr_symbol);
5819 if (IS_EXTERNAL_SYM (fragp->fr_symbol, segtype))
5820 while (csky_relax_table[fragp->fr_subtype].rlx_more > RELAX_OVERFLOW)
5821 fragp->fr_subtype = csky_relax_table[fragp->fr_subtype].rlx_more;
5822 return csky_relax_table[fragp->fr_subtype].rlx_length;
5823
5824 /* C-SKY V1 relaxes. */
5825 case C (UNCD_JUMP, UNDEF_DISP):
5826 case C (UNCD_JUMP_PIC, UNDEF_DISP):
5827 if (!fragp->fr_symbol)
5828 fragp->fr_subtype = C (UNCD_JUMP_S, DISP12);
5829 else if (S_GET_SEGMENT (fragp->fr_symbol) == segtype)
5830 fragp->fr_subtype = C (UNCD_JUMP_S, DISP12);
5831 else
5832 fragp->fr_subtype = C (UNCD_JUMP_S, UNDEF_WORD_DISP);
5833 break;
5834
5835 case C (COND_JUMP, UNDEF_DISP):
5836 case C (COND_JUMP_PIC, UNDEF_DISP):
5837 if (fragp->fr_symbol
5838 && S_GET_SEGMENT (fragp->fr_symbol) == segtype)
5839 /* Got a symbol and it's defined in this segment, become byte
5840 sized. Maybe it will fix up. */
5841 fragp->fr_subtype = C (COND_JUMP_S, DISP12);
5842 else if (fragp->fr_symbol)
5843 /* It's got a segment, but it's not ours, so it will always be
5844 long. */
5845 fragp->fr_subtype = C (COND_JUMP_S, UNDEF_WORD_DISP);
5846 else
5847 /* We know the abs value. */
5848 fragp->fr_subtype = C (COND_JUMP_S, DISP12);
5849 break;
5850
5851 case C (UNCD_JUMP, DISP12):
5852 case C (UNCD_JUMP, DISP32):
5853 case C (UNCD_JUMP, UNDEF_WORD_DISP):
5854 case C (COND_JUMP, DISP12):
5855 case C (COND_JUMP, DISP32):
5856 case C (COND_JUMP, UNDEF_WORD_DISP):
5857 case C (UNCD_JUMP_PIC, DISP12):
5858 case C (UNCD_JUMP_PIC, DISP32):
5859 case C (UNCD_JUMP_PIC, UNDEF_WORD_DISP):
5860 case C (COND_JUMP_PIC, DISP12):
5861 case C (COND_JUMP_PIC, DISP32):
5862 case C (COND_JUMP_PIC, UNDEF_WORD_DISP):
5863 case RELAX_OVERFLOW:
5864 break;
5865
5866 default:
5867 abort ();
5868 }
5869 return csky_relax_table[fragp->fr_subtype].rlx_length;
5870 }
5871
5872 /* Parse opcode like: "op oprnd1, oprnd2, oprnd3". */
5873
5874 static void
5875 csky_macro_md_assemble (const char *op,
5876 const char *oprnd1,
5877 const char *oprnd2,
5878 const char *oprnd3)
5879 {
5880 char str[80];
5881 str[0] = '\0';
5882 strcat (str, op);
5883 if (oprnd1 != NULL)
5884 {
5885 strcat (str, " ");
5886 strcat (str, oprnd1);
5887 if (oprnd2 != NULL)
5888 {
5889 strcat (str, ",");
5890 strcat (str, oprnd2);
5891 if (oprnd3 != NULL)
5892 {
5893 strcat (str, ",");
5894 strcat (str, oprnd3);
5895 }
5896 }
5897 }
5898 md_assemble (str);
5899 return;
5900 }
5901
5902 /* Get the string of operand. */
5903
5904 static int
5905 csky_get_macro_operand (char *src_s, char *dst_s, char end_sym)
5906 {
5907 int nlen = 0;
5908 while (ISSPACE (*src_s))
5909 ++src_s;
5910 while (*src_s != end_sym)
5911 dst_s[nlen++] = *(src_s++);
5912 dst_s[nlen] = '\0';
5913 return nlen;
5914 }
5915
5916 /* idly 4 -> idly4. */
5917
5918 static void
5919 csky_idly (void)
5920 {
5921 char *s = csky_insn.opcode_end;
5922 if (!is_imm_within_range (&s, 4, 4))
5923 {
5924 as_bad (_("second operand must be 4"));
5925 return;
5926 }
5927 csky_macro_md_assemble ("idly4", NULL, NULL, NULL);
5928 return;
5929 }
5930
5931 /* rolc rd, 1 or roltc rd, 1 -> addc rd, rd. */
5932
5933 static void
5934 csky_rolc (void)
5935 {
5936 char reg[10];
5937 char *s = csky_insn.opcode_end;
5938
5939 s += csky_get_macro_operand (s, reg, ',');
5940 ++s;
5941
5942 if (is_imm_within_range (&s, 1, 1))
5943 {
5944 csky_macro_md_assemble ("addc", reg, reg, NULL);
5945 return;
5946 }
5947 else
5948 as_bad (_("second operand must be 1"));
5949 }
5950
5951 /* sxtrb0(1)(2) r1, rx -> xtbr0(1)(2) r1,rx; sextb r1. */
5952
5953 static void
5954 csky_sxtrb (void)
5955 {
5956 char reg1[10];
5957 char reg2[10];
5958
5959 char *s = csky_insn.opcode_end;
5960 s += csky_get_macro_operand (s, reg1, ',');
5961 ++s;
5962 csky_get_macro_operand (s, reg2, '\0');
5963
5964 csky_macro_md_assemble (csky_insn.macro->name + 1, reg1, reg2, NULL);
5965 csky_macro_md_assemble ("sextb", reg1, NULL, NULL);
5966 return;
5967 }
5968
5969 static void
5970 csky_movtf (void)
5971 {
5972 char reg1[10];
5973 char reg2[10];
5974 char reg3[10];
5975
5976 char *s = csky_insn.opcode_end;
5977 s += csky_get_macro_operand (s, reg1, ',');
5978 ++s;
5979
5980 s += csky_get_macro_operand (s, reg2, ',');
5981 ++s;
5982
5983 s += csky_get_macro_operand (s, reg3, '\0');
5984 ++s;
5985 csky_macro_md_assemble ("movt", reg1, reg2, NULL);
5986 csky_macro_md_assemble ("movf", reg1, reg3, NULL);
5987 return;
5988 }
5989
5990 static bool
5991 get_macro_reg_vals (int *reg1, int *reg2, int *reg3)
5992 {
5993 int nlen;
5994 char *s = csky_insn.opcode_end;
5995
5996 *reg1 = csky_get_reg_val (s, &nlen);
5997 s += nlen;
5998 if (*s != ',')
5999 {
6000 csky_show_error (ERROR_MISSING_COMMA, 0, NULL, NULL);
6001 return false;
6002 }
6003 s++;
6004 *reg2 = csky_get_reg_val (s, &nlen);
6005 s += nlen;
6006 if (*s != ',')
6007 {
6008 csky_show_error (ERROR_MISSING_COMMA, 0, NULL, NULL);
6009 return false;
6010 }
6011 s++;
6012 *reg3 = csky_get_reg_val (s, &nlen);
6013 s += nlen;
6014 if (*s != '\0')
6015 {
6016 csky_show_error (ERROR_BAD_END, 0, s, NULL);
6017 return false;
6018 }
6019 if (*reg1 == -1 || *reg2 == -1 || *reg3 == -1)
6020 {
6021 as_bad (_("register number out of range"));
6022 return false;
6023 }
6024 if (*reg1 != *reg2)
6025 {
6026 as_bad (_("dest and source1 must be the same register"));
6027 return false;
6028 }
6029 if (*reg1 >= 15 || *reg3 >= 15)
6030 {
6031 as_bad (_("64-bit operator src/dst register must be less than 15"));
6032 return false;
6033 }
6034 return true;
6035 }
6036
6037 /* addc64 rx, rx, ry -> cmplt rx, rx, addc rx, ry, addc rx+1, ry+1. */
6038
6039 static void
6040 csky_addc64 (void)
6041 {
6042 int reg1;
6043 int reg2;
6044 int reg3;
6045 char reg1_name[16] = {0};
6046 char reg3_name[16] = {0};
6047
6048 if (!get_macro_reg_vals (&reg1, &reg2, &reg3))
6049 return;
6050
6051 sprintf (reg1_name, "r%d", reg1);
6052 csky_macro_md_assemble ("cmplt", reg1_name, reg1_name, NULL);
6053 if (error_state.err_num != ERROR_NONE)
6054 return;
6055
6056 sprintf (reg1_name, "r%d", reg1 + (target_big_endian ? 1 : 0));
6057 sprintf (reg3_name, "r%d", reg3 + (target_big_endian ? 1 : 0));
6058 csky_macro_md_assemble ("addc", reg1_name, reg3_name, NULL);
6059 if (error_state.err_num != ERROR_NONE)
6060 return;
6061
6062 sprintf (reg1_name, "r%d", reg1 + (target_big_endian ? 0 : 1));
6063 sprintf (reg3_name, "r%d", reg3 + (target_big_endian ? 0 : 1));
6064 csky_macro_md_assemble ("addc", reg1_name, reg3_name, NULL);
6065 return;
6066 }
6067
6068 /* subc64 rx, rx, ry -> cmphs rx, rx, subc rx, ry, subc rx+1, ry+1. */
6069
6070 static void
6071 csky_subc64 (void)
6072 {
6073 int reg1;
6074 int reg2;
6075 int reg3;
6076 char reg1_name[16] = {0};
6077 char reg3_name[16] = {0};
6078
6079 if (!get_macro_reg_vals (&reg1, &reg2, &reg3))
6080 return;
6081
6082 sprintf (reg1_name, "r%d", reg1);
6083 csky_macro_md_assemble ("cmphs", reg1_name, reg1_name, NULL);
6084 if (error_state.err_num != ERROR_NONE)
6085 return;
6086
6087 sprintf (reg1_name, "r%d", reg1 + (target_big_endian ? 1 : 0));
6088 sprintf (reg3_name, "r%d", reg3 + (target_big_endian ? 1 : 0));
6089 csky_macro_md_assemble ("subc", reg1_name, reg3_name, NULL);
6090 if (error_state.err_num != ERROR_NONE)
6091 return;
6092
6093 sprintf (reg1_name, "r%d", reg1 + (target_big_endian ? 0 : 1));
6094 sprintf (reg3_name, "r%d", reg3 + (target_big_endian ? 0 : 1));
6095 csky_macro_md_assemble ("subc", reg1_name, reg3_name, NULL);
6096 return;
6097 }
6098
6099 /* or64 rx, rx, ry -> or rx, ry, or rx+1, ry+1. */
6100
6101 static void
6102 csky_or64 (void)
6103 {
6104 int reg1;
6105 int reg2;
6106 int reg3;
6107 char reg1_name[16] = {0};
6108 char reg3_name[16] = {0};
6109
6110 if (!get_macro_reg_vals (&reg1, &reg2, &reg3))
6111 return;
6112 sprintf (reg1_name, "r%d", reg1 + (target_big_endian ? 1 : 0));
6113 sprintf (reg3_name, "r%d", reg3 + (target_big_endian ? 1 : 0));
6114 csky_macro_md_assemble ("or", reg1_name, reg3_name, NULL);
6115
6116 if (error_state.err_num != ERROR_NONE)
6117 return;
6118 sprintf (reg1_name, "r%d", reg1 + (target_big_endian ? 0 : 1));
6119 sprintf (reg3_name, "r%d", reg3 + (target_big_endian ? 0 : 1));
6120 csky_macro_md_assemble ("or", reg1_name, reg3_name, NULL);
6121 return;
6122 }
6123
6124 /* xor64 rx, rx, ry -> xor rx, ry, xor rx+1, ry+1. */
6125
6126 static void
6127 csky_xor64 (void)
6128 {
6129 int reg1;
6130 int reg2;
6131 int reg3;
6132 char reg1_name[16] = {0};
6133 char reg3_name[16] = {0};
6134
6135 if (!get_macro_reg_vals (&reg1, &reg2, &reg3))
6136 return;
6137
6138 sprintf (reg1_name, "r%d", reg1 + (target_big_endian ? 1 : 0));
6139 sprintf (reg3_name, "r%d", reg3 + (target_big_endian ? 1 : 0));
6140 csky_macro_md_assemble ("xor", reg1_name, reg3_name, NULL);
6141 if (error_state.err_num != ERROR_NONE)
6142 return;
6143
6144 sprintf (reg1_name, "r%d", reg1 + (target_big_endian ? 0 : 1));
6145 sprintf (reg3_name, "r%d", reg3 + (target_big_endian ? 0 : 1));
6146 csky_macro_md_assemble ("xor", reg1_name, reg3_name, NULL);
6147 return;
6148 }
6149
6150 /* The following are V2 macro instructions. */
6151
6152 /* neg rd -> not rd, rd; addi rd, 1. */
6153
6154 static void
6155 csky_neg (void)
6156 {
6157 char reg1[10];
6158
6159 char *s = csky_insn.opcode_end;
6160 s += csky_get_macro_operand (s, reg1, '\0');
6161 ++s;
6162
6163 csky_macro_md_assemble ("not", reg1, reg1, NULL);
6164 csky_macro_md_assemble ("addi", reg1, "1", NULL);
6165 return;
6166 }
6167
6168 /* rsubi rd, imm16 -> not rd; addi rd, imm16 + 1 */
6169
6170 static void
6171 csky_rsubi (void)
6172 {
6173 char reg1[10];
6174 char str_imm16[20];
6175 unsigned int imm16 = 0;
6176 expressionS e;
6177 char *s = csky_insn.opcode_end;
6178 s += csky_get_macro_operand (s, reg1, ',');
6179 ++s;
6180
6181 s = parse_exp (s, &e);
6182 if (e.X_op == O_constant)
6183 imm16 = e.X_add_number;
6184 else
6185 csky_show_error (ERROR_IMM_ILLEGAL, 2, NULL, NULL);
6186
6187 sprintf (str_imm16, "%d", imm16 + 1);
6188
6189 csky_macro_md_assemble ("not", reg1, reg1, NULL);
6190 csky_macro_md_assemble ("addi", reg1, str_imm16, NULL);
6191 return;
6192 }
6193
6194 /* Such as: asrc rd -> asrc rd, rd, 1. */
6195
6196 static void
6197 csky_arith (void)
6198 {
6199 char reg1[10];
6200 char *s = csky_insn.opcode_end;
6201 s += csky_get_macro_operand (s, reg1, '\0');
6202 ++s;
6203 csky_macro_md_assemble (csky_insn.macro->name, reg1, reg1, "1");
6204 return;
6205 }
6206
6207 /* decne rd -> if ck802: subi rd, 1; cmpnei rd, 0.
6208 else: decne rd, rd, 1 */
6209
6210 static void
6211 csky_decne (void)
6212 {
6213 char reg1[10];
6214 char *s = csky_insn.opcode_end;
6215 s += csky_get_macro_operand (s, reg1, '\0');
6216 ++s;
6217 if (IS_CSKY_ARCH_802 (mach_flag))
6218 {
6219 csky_macro_md_assemble ("subi", reg1, "1", NULL);
6220 csky_macro_md_assemble ("cmpnei", reg1, "0", NULL);
6221 }
6222 else
6223 csky_macro_md_assemble ("decne", reg1, reg1, "1");
6224 return;
6225 }
6226
6227 /* If -mnolrw, lrw rd, imm -> movih rd, imm_hi16; ori rd, imm_lo16. */
6228
6229 static void
6230 csky_lrw (void)
6231 {
6232 char reg1[10];
6233 char imm[40];
6234 char imm_hi16[40];
6235 char imm_lo16[40];
6236
6237 char *s = csky_insn.opcode_end;
6238 s += csky_get_macro_operand (s, reg1, ',');
6239 ++s;
6240 s += csky_get_macro_operand (s, imm, '\0');
6241 ++s;
6242
6243 imm_hi16[0] = '\0';
6244 strcat (imm_hi16, "(");
6245 strcat (imm_hi16, imm);
6246 strcat (imm_hi16, ") >> 16");
6247 imm_lo16[0] = '\0';
6248 strcat (imm_lo16, "(");
6249 strcat (imm_lo16, imm);
6250 strcat (imm_lo16, ") & 0xffff");
6251
6252 csky_macro_md_assemble ("movih", reg1, imm_hi16, NULL);
6253 csky_macro_md_assemble ("ori", reg1, reg1, imm_lo16);
6254
6255 return;
6256 }
6257
6258 /* The following are worker functions for C-SKY v1. */
6259
6260 bool
6261 v1_work_lrw (void)
6262 {
6263 int reg;
6264 int output_literal = csky_insn.val[1];
6265
6266 reg = csky_insn.val[0];
6267 csky_insn.isize = 2;
6268 csky_insn.output = frag_more (2);
6269 if (csky_insn.e1.X_op == O_constant
6270 && csky_insn.e1.X_add_number <= 0x7f
6271 && csky_insn.e1.X_add_number >= 0)
6272 /* lrw to movi. */
6273 csky_insn.inst = 0x6000 | reg | (csky_insn.e1.X_add_number << 4);
6274 else
6275 {
6276 csky_insn.inst = csky_insn.opcode->op16[0].opcode;
6277 csky_insn.inst |= reg << 8;
6278 if (output_literal)
6279 {
6280 struct literal *p = enter_literal (&csky_insn.e1, 0, 0, 0);
6281
6282 /* Create a reference to pool entry. */
6283 csky_insn.e1.X_op = O_symbol;
6284 csky_insn.e1.X_add_symbol = poolsym;
6285 csky_insn.e1.X_add_number = p->offset << 2;
6286 }
6287
6288 if (insn_reloc == BFD_RELOC_CKCORE_TLS_GD32
6289 || insn_reloc == BFD_RELOC_CKCORE_TLS_LDM32
6290 || insn_reloc == BFD_RELOC_CKCORE_TLS_IE32)
6291 {
6292 literal_insn_offset->tls_addend.frag = frag_now;
6293 literal_insn_offset->tls_addend.offset
6294 = (csky_insn.output
6295 - literal_insn_offset->tls_addend.frag->fr_literal);
6296 }
6297 fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal, 2,
6298 &csky_insn.e1, 1, BFD_RELOC_CKCORE_PCREL_IMM8BY4);
6299 }
6300 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
6301
6302 return true;
6303 }
6304
6305 bool
6306 v1_work_fpu_fo (void)
6307 {
6308 int i = 0;
6309 int inst;
6310 int greg = -1;
6311 char buff[50];
6312 struct csky_opcode_info *opinfo = NULL;
6313
6314 if (csky_insn.isize == 4)
6315 opinfo = &csky_insn.opcode->op32[csky_insn.opcode_idx];
6316 else if (csky_insn.isize == 2)
6317 opinfo = &csky_insn.opcode->op16[csky_insn.opcode_idx];
6318
6319 /* Firstly, get general reg. */
6320 for (i = 0;i < opinfo->operand_num; i++)
6321 if (opinfo->oprnd.oprnds[i].type == OPRND_TYPE_GREG0_15)
6322 greg = csky_insn.val[i];
6323 gas_assert (greg != -1);
6324
6325 /* Secondly, get float inst. */
6326 csky_generate_insn ();
6327 inst = csky_insn.inst;
6328
6329 /* Now get greg and inst, we can write instruction to floating unit. */
6330 sprintf (buff, "lrw r%d,0x%x", greg, inst);
6331 md_assemble (buff);
6332 sprintf (buff, "cpwir r%d", greg);
6333 md_assemble (buff);
6334 return false;
6335 }
6336
6337 bool
6338 v1_work_fpu_fo_fc (void)
6339 {
6340 int i = 0;
6341 int inst;
6342 int greg = -1;
6343 char buff[50];
6344 struct csky_opcode_info *opinfo = NULL;
6345
6346 if (csky_insn.isize == 4)
6347 opinfo = &csky_insn.opcode->op32[csky_insn.opcode_idx];
6348 else if (csky_insn.isize == 2)
6349 opinfo = &csky_insn.opcode->op16[csky_insn.opcode_idx];
6350
6351 /* Firstly, get general reg. */
6352 for (i = 0;i < opinfo->operand_num; i++)
6353 if (opinfo->oprnd.oprnds[i].type == OPRND_TYPE_GREG0_15)
6354 greg = csky_insn.val[i];
6355 gas_assert (greg != -1);
6356
6357 /* Secondly, get float inst. */
6358 csky_generate_insn ();
6359 inst = csky_insn.inst;
6360
6361 /* Now get greg and inst, we can write instruction to floating unit. */
6362 sprintf (buff, "lrw r%d,0x%x", greg, inst);
6363 md_assemble (buff);
6364 sprintf (buff, "cpwir r%d", greg);
6365 md_assemble (buff);
6366 sprintf (buff, "cprc");
6367 md_assemble (buff);
6368
6369 return false;
6370 }
6371
6372 bool
6373 v1_work_fpu_write (void)
6374 {
6375 int greg;
6376 int freg;
6377 char buff[50];
6378
6379 greg = csky_insn.val[0];
6380 freg = csky_insn.val[1];
6381
6382 /* Now get greg and freg, we can write instruction to floating unit. */
6383 sprintf (buff, "cpwgr r%d,cpr%d", greg, freg);
6384 md_assemble (buff);
6385
6386 return false;
6387 }
6388
6389 bool
6390 v1_work_fpu_read (void)
6391 {
6392 int greg;
6393 int freg;
6394 char buff[50];
6395
6396 greg = csky_insn.val[0];
6397 freg = csky_insn.val[1];
6398 /* Now get greg and freg, we can write instruction to floating unit. */
6399 sprintf (buff, "cprgr r%d,cpr%d", greg, freg);
6400 md_assemble (buff);
6401
6402 return false;
6403 }
6404
6405 bool
6406 v1_work_fpu_writed (void)
6407 {
6408 int greg;
6409 int freg;
6410 char buff[50];
6411
6412 greg = csky_insn.val[0];
6413 freg = csky_insn.val[1];
6414
6415 if (greg & 0x1)
6416 {
6417 as_bad (_("even register number required"));
6418 return false;
6419 }
6420 /* Now get greg and freg, we can write instruction to floating unit. */
6421 if (target_big_endian)
6422 sprintf (buff, "cpwgr r%d,cpr%d", greg + 1, freg);
6423 else
6424 sprintf (buff, "cpwgr r%d,cpr%d", greg, freg);
6425 md_assemble (buff);
6426 if (target_big_endian)
6427 sprintf (buff, "cpwgr r%d,cpr%d", greg, freg + 1);
6428 else
6429 sprintf (buff, "cpwgr r%d,cpr%d", greg+1, freg + 1);
6430 md_assemble (buff);
6431 return false;
6432 }
6433
6434 bool
6435 v1_work_fpu_readd (void)
6436 {
6437 int greg;
6438 int freg;
6439 char buff[50];
6440
6441 greg = csky_insn.val[0];
6442 freg = csky_insn.val[1];
6443
6444 if (greg & 0x1)
6445 {
6446 as_bad (_("even register number required"));
6447 return false;
6448 }
6449 /* Now get greg and freg, we can write instruction to floating unit. */
6450 if (target_big_endian)
6451 sprintf (buff, "cprgr r%d,cpr%d", greg+1, freg);
6452 else
6453 sprintf (buff, "cprgr r%d,cpr%d", greg, freg);
6454 md_assemble (buff);
6455 if (target_big_endian)
6456 sprintf (buff, "cprgr r%d,cpr%d", greg, freg + 1);
6457 else
6458 sprintf (buff, "cprgr r%d,cpr%d", greg+1, freg + 1);
6459 md_assemble (buff);
6460
6461 return false;
6462 }
6463
6464 /* The following are for csky pseudo handling. */
6465
6466 bool
6467 v1_work_jbsr (void)
6468 {
6469 csky_insn.output = frag_more (2);
6470 if (do_force2bsr)
6471 /* Generate fixup BFD_RELOC_CKCORE_PCREL_IMM11BY2. */
6472 fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
6473 2, & csky_insn.e1, 1, BFD_RELOC_CKCORE_PCREL_IMM11BY2);
6474 else
6475 {
6476 /* Using jsri instruction. */
6477 const char *name = "jsri";
6478 csky_insn.opcode = (struct csky_opcode *)
6479 str_hash_find (csky_opcodes_hash, name);
6480 csky_insn.opcode_idx = 0;
6481 csky_insn.isize = 2;
6482
6483 struct literal *p = enter_literal (&csky_insn.e1, 1, 0, 0);
6484
6485 /* Create a reference to pool entry. */
6486 csky_insn.e1.X_op = O_symbol;
6487 csky_insn.e1.X_add_symbol = poolsym;
6488 csky_insn.e1.X_add_number = p->offset << 2;
6489
6490 /* Generate fixup BFD_RELOC_CKCORE_PCREL_IMM8BY4. */
6491 fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
6492 2, & csky_insn.e1, 1, BFD_RELOC_CKCORE_PCREL_IMM8BY4);
6493
6494 if (csky_insn.e1.X_op != O_absent && do_jsri2bsr)
6495 /* Generate fixup BFD_RELOC_CKCORE_PCREL_JSR_IMM11BY2. */
6496 fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
6497 2, &p->e,
6498 1, BFD_RELOC_CKCORE_PCREL_JSR_IMM11BY2);
6499 }
6500 csky_generate_insn ();
6501
6502 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
6503
6504 return true;
6505 }
6506
6507 /* The following are worker functions for csky v2 instruction handling. */
6508
6509 /* For nie/nir/ipush/ipop. */
6510
6511 bool
6512 v2_work_istack (void)
6513 {
6514 if (!do_intr_stack)
6515 {
6516 csky_show_error (ERROR_OPCODE_ILLEGAL, 0, NULL, NULL);
6517 return false;
6518 }
6519 csky_insn.output = frag_more (csky_insn.isize);
6520 csky_insn.inst = csky_insn.opcode->op16[0].opcode;
6521 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
6522 return true;
6523 }
6524
6525 bool
6526 v2_work_btsti (void)
6527 {
6528 if (!do_extend_lrw
6529 && (csky_insn.flag_force == INSN_OPCODE16F
6530 || IS_CSKY_ARCH_801 (mach_flag)))
6531 {
6532 csky_show_error (ERROR_OPCODE_ILLEGAL, 0, NULL, NULL);
6533 return false;
6534 }
6535 if (!do_extend_lrw && csky_insn.isize == 2)
6536 csky_insn.isize = 4;
6537 /* Generate relax or reloc if necessary. */
6538 csky_generate_frags ();
6539 /* Generate the insn by mask. */
6540 csky_generate_insn ();
6541 /* Write inst to frag. */
6542 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
6543 return true;
6544 }
6545
6546 bool
6547 v2_work_addi (void)
6548 {
6549 csky_insn.isize = 2;
6550 if (csky_insn.number == 2)
6551 {
6552 if (csky_insn.val[0] == 14
6553 && csky_insn.val[1] >= 0 && csky_insn.val[1] <= 0x1fc
6554 && (csky_insn.val[1] & 0x3) == 0
6555 && csky_insn.flag_force != INSN_OPCODE32F)
6556 {
6557 /* addi sp, sp, imm. */
6558 csky_insn.inst = 0x1400 | ((csky_insn.val[1] >> 2) & 0x1f);
6559 csky_insn.inst |= (csky_insn.val[1] << 1) & 0x300;
6560 csky_insn.output = frag_more (2);
6561 }
6562 else if (csky_insn.val[0] < 8
6563 && csky_insn.val[1] >= 1 && csky_insn.val[1] <= 0x100
6564 && csky_insn.flag_force != INSN_OPCODE32F)
6565 {
6566 csky_insn.inst = 0x2000 | (csky_insn.val[0] << 8);
6567 csky_insn.inst |= (csky_insn.val[1] - 1);
6568 csky_insn.output = frag_more (2);
6569 }
6570 else if (csky_insn.val[1] >= 1 && csky_insn.val[1] <= 0x10000
6571 && csky_insn.flag_force != INSN_OPCODE16F
6572 && !IS_CSKY_ARCH_801 (mach_flag))
6573 {
6574 csky_insn.inst = 0xe4000000 | (csky_insn.val[0] << 21);
6575 csky_insn.inst |= csky_insn.val[0] << 16;
6576 csky_insn.inst |= (csky_insn.val[1] - 1);
6577 csky_insn.isize = 4;
6578 csky_insn.output = frag_more (4);
6579 }
6580 else
6581 {
6582 csky_show_error (ERROR_OPERANDS_ILLEGAL, 0,
6583 csky_insn.opcode_end, NULL);
6584 return false;
6585 }
6586 }
6587 else if (csky_insn.number == 3)
6588 {
6589 if (csky_insn.val[0] == 14
6590 && csky_insn.val[1] == 14
6591 && csky_insn.val[2] >= 0 && csky_insn.val[2] <= 0x1fc
6592 && (csky_insn.val[2] & 0x3) == 0
6593 && csky_insn.flag_force != INSN_OPCODE32F)
6594 {
6595 csky_insn.inst = 0x1400 | ((csky_insn.val[2] >> 2) & 0x1f);
6596 csky_insn.inst |= (csky_insn.val[2] << 1) & 0x300;
6597 csky_insn.output = frag_more (2);
6598 }
6599 else if (csky_insn.val[0] < 8
6600 && csky_insn.val[1] == 14
6601 && csky_insn.val[2] >= 0 && csky_insn.val[2] <= 0x3fc
6602 && (csky_insn.val[2] & 0x3) == 0
6603 && csky_insn.flag_force != INSN_OPCODE32F)
6604 {
6605 csky_insn.inst = 0x1800 | (csky_insn.val[0] << 8);
6606 csky_insn.inst |= csky_insn.val[2] >> 2;
6607 csky_insn.output = frag_more (2);
6608 }
6609 else if (csky_insn.val[0] < 8
6610 && csky_insn.val[0] == csky_insn.val[1]
6611 && csky_insn.val[2] >= 1 && csky_insn.val[2] <= 0x100
6612 && csky_insn.flag_force != INSN_OPCODE32F)
6613 {
6614 csky_insn.inst = 0x2000 | (csky_insn.val[0] << 8);
6615 csky_insn.inst |= (csky_insn.val[2] - 1);
6616 csky_insn.output = frag_more (2);
6617 }
6618 else if (csky_insn.val[0] < 8
6619 && csky_insn.val[1] < 8
6620 && csky_insn.val[2] >= 1 && csky_insn.val[2] <= 0x8
6621 && csky_insn.flag_force != INSN_OPCODE32F)
6622 {
6623 csky_insn.inst = 0x5802 | (csky_insn.val[0] << 5);
6624 csky_insn.inst |= csky_insn.val[1] << 8;
6625 csky_insn.inst |= (csky_insn.val[2] - 1) << 2;
6626 csky_insn.output = frag_more (2);
6627 }
6628 else if (csky_insn.val[1] == 28
6629 && csky_insn.val[2] >= 1 && csky_insn.val[2] <= 0x40000
6630 && csky_insn.flag_force != INSN_OPCODE16F
6631 && !IS_CSKY_ARCH_801 (mach_flag))
6632 {
6633 csky_insn.inst = 0xcc1c0000 | (csky_insn.val[0] << 21);
6634 csky_insn.isize = 4;
6635 csky_insn.output = frag_more (4);
6636 if (insn_reloc == BFD_RELOC_CKCORE_GOTOFF)
6637 {
6638 fix_new_exp (frag_now, csky_insn.output-frag_now->fr_literal,
6639 4, &csky_insn.e1, 0, BFD_RELOC_CKCORE_GOTOFF_IMM18);
6640 }
6641 else
6642 csky_insn.inst |= (csky_insn.val[2] - 1);
6643 }
6644 else if (csky_insn.val[2] >= 1 && csky_insn.val[2] <= 0x1000
6645 && csky_insn.flag_force != INSN_OPCODE16F
6646 && !IS_CSKY_ARCH_801 (mach_flag))
6647 {
6648 csky_insn.inst = 0xe4000000 | (csky_insn.val[0] << 21);
6649 csky_insn.inst |= csky_insn.val[1] << 16;
6650 csky_insn.inst |= (csky_insn.val[2] - 1);
6651 csky_insn.isize = 4;
6652 csky_insn.output = frag_more (4);
6653 }
6654 else
6655 {
6656 csky_show_error (ERROR_OPERANDS_ILLEGAL, 0,
6657 (char *)csky_insn.opcode_end, NULL);
6658 return false;
6659 }
6660 }
6661 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
6662
6663 return true;
6664 }
6665
6666 bool
6667 v2_work_subi (void)
6668 {
6669 csky_insn.isize = 2;
6670 if (csky_insn.number == 2)
6671 {
6672 if (csky_insn.val[0] == 14
6673 && csky_insn.val[1] >= 0 && csky_insn.val[2] <= 0x1fc
6674 && (csky_insn.val[1] & 0x3) == 0
6675 && csky_insn.flag_force != INSN_OPCODE32F)
6676 {
6677 csky_insn.inst = 0x1420 | ((csky_insn.val[1] >> 2) & 0x1f);
6678 csky_insn.inst |= (csky_insn.val[1] << 1) & 0x300;
6679 }
6680 else if (csky_insn.val[0] < 8
6681 && csky_insn.val[1] >= 1 && csky_insn.val[1] <= 0x100
6682 && csky_insn.flag_force != INSN_OPCODE32F)
6683 {
6684 csky_insn.inst = 0x2800 | (csky_insn.val[0] << 8);
6685 csky_insn.inst |= (csky_insn.val[1] - 1);
6686 }
6687 else if (csky_insn.val[1] >= 1 && csky_insn.val[1] <= 0x10000
6688 && csky_insn.flag_force != INSN_OPCODE16F
6689 && !IS_CSKY_ARCH_801 (mach_flag))
6690 {
6691 csky_insn.inst = 0xe4001000 | (csky_insn.val[0] << 21);
6692 csky_insn.inst |= csky_insn.val[0] << 16;
6693 csky_insn.inst |= (csky_insn.val[1] - 1);
6694 csky_insn.isize = 4;
6695 }
6696 else
6697 {
6698 csky_show_error (ERROR_OPERANDS_ILLEGAL, 0,
6699 (char *)csky_insn.opcode_end, NULL);
6700 return false;
6701 }
6702 }
6703 else if (csky_insn.number == 3)
6704 {
6705 if (csky_insn.val[0] == 14
6706 && csky_insn.val[1] == 14
6707 && csky_insn.val[2] >= 0 && csky_insn.val[2] <= 0x1fc
6708 && (csky_insn.val[2] & 0x3) == 0
6709 && csky_insn.flag_force != INSN_OPCODE32F)
6710 {
6711 csky_insn.inst = 0x1420 | ((csky_insn.val[2] >> 2) & 0x1f);
6712 csky_insn.inst |= (csky_insn.val[2] << 1) & 0x300;
6713 }
6714
6715 else if (csky_insn.val[0] < 8
6716 && csky_insn.val[0] == csky_insn.val[1]
6717 && csky_insn.val[2] >= 1 && csky_insn.val[2] <= 0x100
6718 && csky_insn.flag_force != INSN_OPCODE32F)
6719 {
6720 csky_insn.inst = 0x2800 | (csky_insn.val[0] << 8);
6721 csky_insn.inst |= (csky_insn.val[2] - 1);
6722 }
6723 else if (csky_insn.val[0] < 8
6724 && csky_insn.val[1] < 8
6725 && csky_insn.val[2] >= 1 && csky_insn.val[2] <= 0x8
6726 && csky_insn.flag_force != INSN_OPCODE32F)
6727 {
6728 csky_insn.inst = 0x5803 | (csky_insn.val[0] << 5);
6729 csky_insn.inst |= csky_insn.val[1] << 8;
6730 csky_insn.inst |= (csky_insn.val[2] - 1) << 2;
6731 }
6732 else if (csky_insn.val[2] >= 1 && csky_insn.val[2] <= 0x1000
6733 && csky_insn.flag_force != INSN_OPCODE16F
6734 && !IS_CSKY_ARCH_801 (mach_flag))
6735 {
6736 csky_insn.inst = 0xe4001000 | (csky_insn.val[0] << 21);
6737 csky_insn.inst |= csky_insn.val[1] << 16;
6738 csky_insn.inst |= (csky_insn.val[2] - 1);
6739 csky_insn.isize = 4;
6740 }
6741 else
6742 {
6743 csky_show_error (ERROR_OPERANDS_ILLEGAL, 0,
6744 (char *)csky_insn.opcode_end, NULL);
6745 return false;
6746 }
6747 }
6748 csky_insn.output = frag_more (csky_insn.isize);
6749 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
6750
6751 return true;
6752 }
6753
6754 bool
6755 v2_work_add_sub (void)
6756 {
6757 if (csky_insn.number == 3
6758 && (csky_insn.val[0] == csky_insn.val[1]
6759 || csky_insn.val[0] == csky_insn.val[2])
6760 && csky_insn.val[0] <= 15
6761 && csky_insn.val[1] <= 15
6762 && csky_insn.val[2] <= 15)
6763 {
6764 if (!strstr (csky_insn.opcode->mnemonic, "sub")
6765 || csky_insn.val[0] == csky_insn.val[1])
6766 {
6767 csky_insn.opcode_idx = 0;
6768 csky_insn.isize = 2;
6769 if (csky_insn.val[0] == csky_insn.val[1])
6770 csky_insn.val[1] = csky_insn.val[2];
6771
6772 csky_insn.number = 2;
6773
6774 }
6775 }
6776 if (csky_insn.isize == 4
6777 && IS_CSKY_ARCH_801 (mach_flag))
6778 {
6779 if (csky_insn.number == 3)
6780 {
6781 if (csky_insn.val[0] > 7)
6782 {
6783 SET_ERROR_INTEGER (ERROR_REG_OVER_RANGE, csky_insn.val[0]);
6784 csky_show_error (ERROR_REG_OVER_RANGE, 1, NULL, NULL);
6785 }
6786 if (csky_insn.val[1] > 7)
6787 {
6788 SET_ERROR_INTEGER (ERROR_REG_OVER_RANGE, csky_insn.val[1]);
6789 csky_show_error (ERROR_REG_OVER_RANGE, 2, NULL, NULL);
6790 }
6791 if (csky_insn.val[2] > 7)
6792 {
6793 SET_ERROR_INTEGER (ERROR_REG_OVER_RANGE, csky_insn.val[2]);
6794 csky_show_error (ERROR_REG_OVER_RANGE, 3, NULL, NULL);
6795 }
6796 }
6797 else
6798 {
6799 if (csky_insn.val[0] > 15)
6800 {
6801 SET_ERROR_INTEGER (ERROR_REG_OVER_RANGE, csky_insn.val[0]);
6802 csky_show_error (ERROR_REG_OVER_RANGE, 1, NULL, NULL);
6803 }
6804 if (csky_insn.val[1] > 15)
6805 {
6806 SET_ERROR_INTEGER (ERROR_REG_OVER_RANGE, csky_insn.val[1]);
6807 csky_show_error (ERROR_REG_OVER_RANGE, 2, NULL, NULL);
6808 }
6809 }
6810 return false;
6811 }
6812 /* sub rz, rx. */
6813 /* Generate relax or reloc if necessary. */
6814 csky_generate_frags ();
6815 /* Generate the insn by mask. */
6816 csky_generate_insn ();
6817 /* Write inst to frag. */
6818 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
6819 return true;
6820 }
6821
6822 bool
6823 v2_work_rotlc (void)
6824 {
6825 const char *name = "addc";
6826 csky_insn.opcode
6827 = (struct csky_opcode *) str_hash_find (csky_opcodes_hash, name);
6828 csky_insn.opcode_idx = 0;
6829 if (csky_insn.isize == 2)
6830 {
6831 /* addc rz, rx. */
6832 csky_insn.number = 2;
6833 csky_insn.val[1] = csky_insn.val[0];
6834 }
6835 else
6836 {
6837 csky_insn.number = 3;
6838 /* addc rz, rx, ry. */
6839 csky_insn.val[1] = csky_insn.val[0];
6840 csky_insn.val[2] = csky_insn.val[0];
6841 }
6842 /* Generate relax or reloc if necessary. */
6843 csky_generate_frags ();
6844 /* Generate the insn by mask. */
6845 csky_generate_insn ();
6846 /* Write inst to frag. */
6847 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
6848 return true;
6849 }
6850
6851 bool
6852 v2_work_bgeni (void)
6853 {
6854 const char *name = NULL;
6855 int imm = csky_insn.val[1];
6856 int val = 1 << imm;
6857 if (imm < 16)
6858 name = "movi";
6859 else
6860 {
6861 name = "movih";
6862 val >>= 16;
6863 }
6864 csky_insn.opcode
6865 = (struct csky_opcode *) str_hash_find (csky_opcodes_hash, name);
6866 csky_insn.opcode_idx = 0;
6867 csky_insn.val[1] = val;
6868
6869 /* Generate relax or reloc if necessary. */
6870 csky_generate_frags ();
6871 /* Generate the insn by mask. */
6872 csky_generate_insn ();
6873 /* Write inst to frag. */
6874 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
6875 return true;
6876 }
6877
6878 bool
6879 v2_work_not (void)
6880 {
6881 const char *name = "nor";
6882 csky_insn.opcode
6883 = (struct csky_opcode *) str_hash_find (csky_opcodes_hash, name);
6884 csky_insn.opcode_idx = 0;
6885 if (csky_insn.number == 1)
6886 {
6887 csky_insn.val[1] = csky_insn.val[0];
6888 if (csky_insn.val[0] < 16)
6889 {
6890 /* 16 bits nor rz, rz. */
6891 csky_insn.number = 2;
6892 csky_insn.isize = 2;
6893 }
6894 else
6895 {
6896 csky_insn.val[2] = csky_insn.val[0];
6897 csky_insn.number = 3;
6898 csky_insn.isize = 4;
6899 }
6900 }
6901 if (csky_insn.number == 2)
6902 {
6903 if (csky_insn.val[0] == csky_insn.val[1]
6904 && csky_insn.val[0] < 16)
6905 {
6906 /* 16 bits nor rz, rz. */
6907 csky_insn.number = 2;
6908 csky_insn.isize = 2;
6909 }
6910 else
6911 {
6912 csky_insn.val[2] = csky_insn.val[1];
6913 csky_insn.number = 3;
6914 csky_insn.isize = 4;
6915 }
6916 }
6917
6918 /* Generate relax or reloc if necessary. */
6919 csky_generate_frags ();
6920 /* Generate the insn by mask. */
6921 csky_generate_insn ();
6922 /* Write inst to frag. */
6923 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
6924 return true;
6925 }
6926
6927 bool
6928 v2_work_jbtf (void)
6929 {
6930 if (csky_insn.e1.X_add_symbol == NULL || csky_insn.e1.X_op == O_constant)
6931 {
6932 csky_show_error (ERROR_UNDEFINE, 0, (void *)"operand is invalid", NULL);
6933 return false;
6934 }
6935
6936 if (IS_CSKY_ARCH_801 (mach_flag))
6937 {
6938 /* CK801 doesn't have 32-bit bt/bf insns or a jump insn with a
6939 range larger than SCOND_DISP16. Relax to a short jump around
6940 an unconditional branch, and give up if that overflows too. */
6941 csky_insn.output = frag_var (rs_machine_dependent,
6942 SCOND_DISP16_LEN,
6943 SCOND_DISP10_LEN,
6944 SCOND_DISP10,
6945 csky_insn.e1.X_add_symbol,
6946 csky_insn.e1.X_add_number,
6947 0);
6948 csky_insn.isize = 2;
6949 csky_insn.max = SCOND_DISP16_LEN;
6950 csky_insn.inst = csky_insn.opcode->op16[0].opcode;
6951 }
6952 else if (do_long_jump && !IS_CSKY_ARCH_802 (mach_flag))
6953 {
6954 /* Generate relax with jcondition.
6955 Note that CK802 doesn't support the JMPI instruction so
6956 we cannot relax to a jump with a 32-bit offset. */
6957 csky_insn.output = frag_var (rs_machine_dependent,
6958 JCOND_DISP32_LEN,
6959 JCOND_DISP10_LEN,
6960 JCOND_DISP10,
6961 csky_insn.e1.X_add_symbol,
6962 csky_insn.e1.X_add_number,
6963 0);
6964 csky_insn.isize = 2;
6965 csky_insn.max = JCOND_DISP32_LEN;
6966 csky_insn.inst = csky_insn.opcode->op16[0].opcode;
6967 }
6968 else
6969 {
6970 /* Generate relax with condition. */
6971 csky_insn.output = frag_var (rs_machine_dependent,
6972 COND_DISP16_LEN,
6973 COND_DISP10_LEN,
6974 COND_DISP10,
6975 csky_insn.e1.X_add_symbol,
6976 csky_insn.e1.X_add_number,
6977 0);
6978 csky_insn.isize = 2;
6979 csky_insn.max = COND_DISP16_LEN;
6980 csky_insn.inst = csky_insn.opcode->op16[0].opcode;
6981 }
6982 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
6983
6984 return true;
6985 }
6986
6987 bool
6988 v2_work_jbr (void)
6989 {
6990 if (csky_insn.e1.X_add_symbol == NULL || csky_insn.e1.X_op == O_constant)
6991 {
6992 csky_show_error (ERROR_UNDEFINE, 0, (void *)"operand is invalid", NULL);
6993 return false;
6994 }
6995
6996 if (do_long_jump
6997 && !IS_CSKY_ARCH_801 (mach_flag)
6998 && !IS_CSKY_ARCH_802 (mach_flag))
6999 {
7000 csky_insn.output = frag_var (rs_machine_dependent,
7001 JUNCD_DISP32_LEN,
7002 JUNCD_DISP10_LEN,
7003 JUNCD_DISP10,
7004 csky_insn.e1.X_add_symbol,
7005 csky_insn.e1.X_add_number,
7006 0);
7007
7008 csky_insn.inst = csky_insn.opcode->op16[0].opcode;
7009 csky_insn.max = JUNCD_DISP32_LEN;
7010 csky_insn.isize = 2;
7011 }
7012 else
7013 {
7014 /* Generate relax with condition. */
7015 csky_insn.output = frag_var (rs_machine_dependent,
7016 UNCD_DISP16_LEN,
7017 UNCD_DISP10_LEN,
7018 UNCD_DISP10,
7019 csky_insn.e1.X_add_symbol,
7020 csky_insn.e1.X_add_number,
7021 0);
7022 csky_insn.isize = 2;
7023 csky_insn.max = UNCD_DISP16_LEN;
7024 csky_insn.inst = csky_insn.opcode->op16[0].opcode;
7025
7026 }
7027 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
7028 return true;
7029 }
7030
7031 #define SIZE_V2_MOVI16(x) ((addressT)x <= 0xff)
7032 #define SIZE_V2_MOVI32(x) ((addressT)x <= 0xffff)
7033 #define SIZE_V2_MOVIH(x) ((addressT)x <= 0xffffffff && (((addressT)x & 0xffff) == 0))
7034
7035 bool
7036 v2_work_lrw (void)
7037 {
7038 int reg = csky_insn.val[0];
7039 int output_literal = csky_insn.val[1];
7040 int is_done = 0;
7041
7042 /* If the second operand is O_constant, We can use movi/movih
7043 instead of lrw. */
7044 if (csky_insn.e1.X_op == O_constant)
7045 {
7046 /* 801 only has movi16. */
7047 if (SIZE_V2_MOVI16 (csky_insn.e1.X_add_number) && reg < 8)
7048 {
7049 /* movi16 instead. */
7050 csky_insn.output = frag_more (2);
7051 csky_insn.inst = (CSKYV2_INST_MOVI16 | (reg << 8)
7052 | (csky_insn.e1.X_add_number));
7053 csky_insn.isize = 2;
7054 is_done = 1;
7055 }
7056 else if (SIZE_V2_MOVI32 (csky_insn.e1.X_add_number)
7057 && !IS_CSKY_ARCH_801 (mach_flag))
7058 {
7059 /* movi32 instead. */
7060 csky_insn.output = frag_more (4);
7061 csky_insn.inst = (CSKYV2_INST_MOVI32 | (reg << 16)
7062 | (csky_insn.e1.X_add_number));
7063 csky_insn.isize = 4;
7064 is_done = 1;
7065 }
7066 else if (SIZE_V2_MOVIH (csky_insn.e1.X_add_number)
7067 && !IS_CSKY_ARCH_801 (mach_flag))
7068 {
7069 /* movih instead. */
7070 csky_insn.output = frag_more (4);
7071 csky_insn.inst = (CSKYV2_INST_MOVIH | (reg << 16)
7072 | ((csky_insn.e1.X_add_number >> 16) & 0xffff));
7073 csky_insn.isize = 4;
7074 is_done = 1;
7075 }
7076 }
7077
7078 if (is_done)
7079 {
7080 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
7081 return true;
7082 }
7083
7084 if (output_literal)
7085 {
7086 struct literal *p = enter_literal (&csky_insn.e1, 0, 0, 0);
7087 /* Create a reference to pool entry. */
7088 csky_insn.e1.X_op = O_symbol;
7089 csky_insn.e1.X_add_symbol = poolsym;
7090 csky_insn.e1.X_add_number = p->offset << 2;
7091 }
7092 /* If 16bit force. */
7093 if (csky_insn.flag_force == INSN_OPCODE16F)
7094 {
7095 /* Generate fixup. */
7096 if (reg > 7)
7097 {
7098 csky_show_error (ERROR_UNDEFINE, 0,
7099 (void *)"The register is out of range.", NULL);
7100 return false;
7101 }
7102 csky_insn.isize = 2;
7103 csky_insn.output = frag_more (2);
7104
7105 if (insn_reloc == BFD_RELOC_CKCORE_TLS_GD32
7106 || insn_reloc == BFD_RELOC_CKCORE_TLS_LDM32
7107 || insn_reloc == BFD_RELOC_CKCORE_TLS_IE32)
7108 {
7109 literal_insn_offset->tls_addend.frag = frag_now;
7110 literal_insn_offset->tls_addend.offset
7111 = csky_insn.output - frag_now->fr_literal;
7112 }
7113 csky_insn.inst = csky_insn.opcode->op16[0].opcode | (reg << 5);
7114 csky_insn.max = 4;
7115 fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
7116 2, &csky_insn.e1, 1, BFD_RELOC_CKCORE_PCREL_IMM7BY4);
7117 }
7118 else if (csky_insn.flag_force == INSN_OPCODE32F)
7119 {
7120 csky_insn.isize = 4;
7121 csky_insn.output = frag_more (4);
7122 if (insn_reloc == BFD_RELOC_CKCORE_TLS_GD32
7123 || insn_reloc == BFD_RELOC_CKCORE_TLS_LDM32
7124 || insn_reloc == BFD_RELOC_CKCORE_TLS_IE32)
7125 {
7126 literal_insn_offset->tls_addend.frag = frag_now;
7127 literal_insn_offset->tls_addend.offset
7128 = csky_insn.output - frag_now->fr_literal;
7129 }
7130 csky_insn.inst = csky_insn.opcode->op32[0].opcode | (reg << 16);
7131 fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
7132 4, &csky_insn.e1, 1, BFD_RELOC_CKCORE_PCREL_IMM16BY4);
7133 }
7134 else if (!is_done)
7135 {
7136 if (reg < 8)
7137 {
7138 csky_insn.isize = 2;
7139
7140 if (insn_reloc == BFD_RELOC_CKCORE_TLS_GD32
7141 || insn_reloc == BFD_RELOC_CKCORE_TLS_LDM32
7142 || insn_reloc == BFD_RELOC_CKCORE_TLS_IE32)
7143 literal_insn_offset->tls_addend.frag = frag_now;
7144
7145 csky_insn.output = frag_var (rs_machine_dependent,
7146 LRW_DISP16_LEN,
7147 LRW_DISP7_LEN,
7148 (do_extend_lrw
7149 ? LRW2_DISP8 : LRW_DISP7),
7150 csky_insn.e1.X_add_symbol,
7151 csky_insn.e1.X_add_number, 0);
7152 if (insn_reloc == BFD_RELOC_CKCORE_TLS_GD32
7153 || insn_reloc == BFD_RELOC_CKCORE_TLS_LDM32
7154 || insn_reloc == BFD_RELOC_CKCORE_TLS_IE32)
7155 {
7156 if (literal_insn_offset->tls_addend.frag->fr_next != frag_now)
7157 literal_insn_offset->tls_addend.frag
7158 = literal_insn_offset->tls_addend.frag->fr_next;
7159 literal_insn_offset->tls_addend.offset
7160 = (csky_insn.output
7161 - literal_insn_offset->tls_addend.frag->fr_literal);
7162 }
7163 csky_insn.inst = csky_insn.opcode->op16[0].opcode | (reg << 5);
7164 csky_insn.max = LRW_DISP16_LEN;
7165 csky_insn.isize = 2;
7166 }
7167 else
7168 {
7169 csky_insn.isize = 4;
7170 csky_insn.output = frag_more (4);
7171 if (insn_reloc == BFD_RELOC_CKCORE_TLS_GD32
7172 || insn_reloc == BFD_RELOC_CKCORE_TLS_LDM32
7173 || insn_reloc == BFD_RELOC_CKCORE_TLS_IE32)
7174 {
7175 literal_insn_offset->tls_addend.frag = frag_now;
7176 literal_insn_offset->tls_addend.offset
7177 = csky_insn.output - frag_now->fr_literal;
7178 }
7179 csky_insn.inst = csky_insn.opcode->op32[0].opcode | (reg << 16);
7180 fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
7181 4, &csky_insn.e1, 1, BFD_RELOC_CKCORE_PCREL_IMM16BY4);
7182 }
7183 }
7184
7185 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
7186 return true;
7187 }
7188
7189 bool
7190 v2_work_lrsrsw (void)
7191 {
7192 int reg = csky_insn.val[0];
7193 csky_insn.output = frag_more (4);
7194 csky_insn.inst = csky_insn.opcode->op32[0].opcode | (reg << 21);
7195 csky_insn.isize = 4;
7196
7197 switch (insn_reloc)
7198 {
7199 case BFD_RELOC_CKCORE_GOT32:
7200 fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
7201 4, &csky_insn.e1, 0, BFD_RELOC_CKCORE_GOT_IMM18BY4);
7202 break;
7203 case BFD_RELOC_CKCORE_PLT32:
7204 fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
7205 4, &csky_insn.e1, 0, BFD_RELOC_CKCORE_PLT_IMM18BY4);
7206 break;
7207 default:
7208 fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
7209 4, &csky_insn.e1, 1, BFD_RELOC_CKCORE_DOFFSET_IMM18BY4);
7210 break;
7211 }
7212 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
7213 return true;
7214 }
7215
7216 bool
7217 v2_work_jbsr (void)
7218 {
7219 if (do_force2bsr
7220 || IS_CSKY_ARCH_801 (mach_flag)
7221 || IS_CSKY_ARCH_802 (mach_flag))
7222 {
7223 csky_insn.output = frag_more (4);
7224 fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
7225 4, &csky_insn.e1, 1, BFD_RELOC_CKCORE_PCREL_IMM26BY2);
7226 csky_insn.isize = 4;
7227 csky_insn.inst = CSKYV2_INST_BSR32;
7228 }
7229 else
7230 {
7231 struct literal *p = enter_literal (&csky_insn.e1, 0, 0, 0);
7232 csky_insn.output = frag_more (4);
7233 csky_insn.e1.X_op = O_symbol;
7234 csky_insn.e1.X_add_symbol = poolsym;
7235 csky_insn.e1.X_add_number = p->offset << 2;
7236 fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
7237 4, &csky_insn.e1, 1, BFD_RELOC_CKCORE_PCREL_IMM16BY4);
7238 if (do_jsri2bsr || IS_CSKY_ARCH_810 (mach_flag))
7239 fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
7240 4,
7241 &(litpool + (csky_insn.e1.X_add_number >> 2))->e,
7242 1,
7243 BFD_RELOC_CKCORE_PCREL_JSR_IMM26BY2);
7244 csky_insn.inst = CSKYV2_INST_JSRI32;
7245 csky_insn.isize = 4;
7246 if (IS_CSKY_ARCH_810 (mach_flag))
7247 {
7248 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
7249 csky_insn.output = frag_more (4);
7250 dwarf2_emit_insn (0);
7251 /* Insert "mov r0, r0". */
7252 csky_insn.inst = CSKYV2_INST_MOV_R0_R0;
7253 csky_insn.max = 8;
7254 }
7255 }
7256 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
7257
7258 return true;
7259 }
7260
7261 bool
7262 v2_work_jsri (void)
7263 {
7264 /* dump literal. */
7265 struct literal *p = enter_literal (&csky_insn.e1, 1, 0, 0);
7266 csky_insn.e1.X_op = O_symbol;
7267 csky_insn.e1.X_add_symbol = poolsym;
7268 csky_insn.e1.X_add_number = p->offset << 2;
7269
7270 /* Generate relax or reloc if necessary. */
7271 csky_generate_frags ();
7272 /* Generate the insn by mask. */
7273 csky_generate_insn ();
7274 /* Write inst to frag. */
7275 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
7276 /* Control 810 not to generate jsri. */
7277 if (IS_CSKY_ARCH_810 (mach_flag))
7278 {
7279 /* Look at adding the R_PCREL_JSRIMM26BY2.
7280 For 'jbsr .L1', this reloc type's symbol
7281 is bound to '.L1', isn't bound to literal pool. */
7282 fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
7283 4, &p->e, 1,
7284 BFD_RELOC_CKCORE_PCREL_JSR_IMM26BY2);
7285 csky_insn.output = frag_more (4);
7286 dwarf2_emit_insn (0);
7287 /* The opcode of "mov32 r0,r0". */
7288 csky_insn.inst = CSKYV2_INST_MOV_R0_R0;
7289 /* The effect of this value is to check literal. */
7290 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
7291 csky_insn.max = 8;
7292 }
7293 return true;
7294 }
7295
7296 bool
7297 v2_work_movih (void)
7298 {
7299 int rz = csky_insn.val[0];
7300 csky_insn.output = frag_more (4);
7301 csky_insn.inst = csky_insn.opcode->op32[0].opcode | (rz << 16);
7302 if (csky_insn.e1.X_op == O_constant)
7303 {
7304 if (csky_insn.e1.X_unsigned == 1 && csky_insn.e1.X_add_number > 0xffff)
7305 {
7306 csky_show_error (ERROR_IMM_OVERFLOW, 2, NULL, NULL);
7307 return false;
7308 }
7309 else if (csky_insn.e1.X_unsigned == 0 && csky_insn.e1.X_add_number < 0)
7310 {
7311 csky_show_error (ERROR_IMM_OVERFLOW, 2, NULL, NULL);
7312 return false;
7313 }
7314 else
7315 csky_insn.inst |= (csky_insn.e1.X_add_number & 0xffff);
7316 }
7317 else if (csky_insn.e1.X_op == O_right_shift
7318 || (csky_insn.e1.X_op == O_symbol && insn_reloc != BFD_RELOC_NONE))
7319 {
7320 if (csky_insn.e1.X_op_symbol != 0
7321 && symbol_constant_p (csky_insn.e1.X_op_symbol)
7322 && S_GET_SEGMENT (csky_insn.e1.X_op_symbol) == absolute_section
7323 && 16 == S_GET_VALUE (csky_insn.e1.X_op_symbol))
7324 {
7325 csky_insn.e1.X_op = O_symbol;
7326 if (insn_reloc == BFD_RELOC_CKCORE_GOT32)
7327 insn_reloc = BFD_RELOC_CKCORE_GOT_HI16;
7328 else if (insn_reloc == BFD_RELOC_CKCORE_PLT32)
7329 insn_reloc = BFD_RELOC_CKCORE_PLT_HI16;
7330 else if (insn_reloc == BFD_RELOC_CKCORE_GOTPC)
7331 insn_reloc = BFD_RELOC_CKCORE_GOTPC_HI16;
7332 else if (insn_reloc == BFD_RELOC_CKCORE_GOTOFF)
7333 insn_reloc = BFD_RELOC_CKCORE_GOTOFF_HI16;
7334 else
7335 insn_reloc = BFD_RELOC_CKCORE_ADDR_HI16;
7336 fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
7337 4, &csky_insn.e1, 0, insn_reloc);
7338 }
7339 else
7340 {
7341 void *arg = (void *)"the second operand must be \"SYMBOL >> 16\"";
7342 csky_show_error (ERROR_UNDEFINE, 0, arg, NULL);
7343 return false;
7344 }
7345 }
7346 csky_insn.isize = 4;
7347 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
7348
7349 return true;
7350 }
7351
7352 bool
7353 v2_work_ori (void)
7354 {
7355 int rz = csky_insn.val[0];
7356 int rx = csky_insn.val[1];
7357 csky_insn.output = frag_more (4);
7358 csky_insn.inst = csky_insn.opcode->op32[0].opcode | (rz << 21) | (rx << 16);
7359 if (csky_insn.e1.X_op == O_constant)
7360 {
7361 if (csky_insn.e1.X_add_number <= 0xffff
7362 && csky_insn.e1.X_add_number >= 0)
7363 csky_insn.inst |= csky_insn.e1.X_add_number;
7364 else
7365 {
7366 csky_show_error (ERROR_IMM_OVERFLOW, 3, NULL, NULL);
7367 return false;
7368 }
7369 }
7370 else if (csky_insn.e1.X_op == O_bit_and)
7371 {
7372 if (symbol_constant_p (csky_insn.e1.X_op_symbol)
7373 && S_GET_SEGMENT (csky_insn.e1.X_op_symbol) == absolute_section
7374 && 0xffff == S_GET_VALUE (csky_insn.e1.X_op_symbol))
7375 {
7376 csky_insn.e1.X_op = O_symbol;
7377 if (insn_reloc == BFD_RELOC_CKCORE_GOT32)
7378 insn_reloc = BFD_RELOC_CKCORE_GOT_LO16;
7379 else if (insn_reloc == BFD_RELOC_CKCORE_PLT32)
7380 insn_reloc = BFD_RELOC_CKCORE_PLT_LO16;
7381 else if (insn_reloc == BFD_RELOC_CKCORE_GOTPC)
7382 insn_reloc = BFD_RELOC_CKCORE_GOTPC_LO16;
7383 else if (insn_reloc == BFD_RELOC_CKCORE_GOTOFF)
7384 insn_reloc = BFD_RELOC_CKCORE_GOTOFF_LO16;
7385 else
7386 insn_reloc = BFD_RELOC_CKCORE_ADDR_LO16;
7387 fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
7388 4, &csky_insn.e1, 0, insn_reloc);
7389 }
7390 else
7391 {
7392 void *arg = (void *)"the third operand must be \"SYMBOL & 0xffff\"";
7393 csky_show_error (ERROR_UNDEFINE, 0, arg, NULL);
7394 return false;
7395 }
7396 }
7397 csky_insn.isize = 4;
7398 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
7399 return true;
7400 }
7401
7402 /* Helper function to encode a single/double floating point constant
7403 into the instruction word for fmovis and fmovid instructions.
7404 The constant is in its IEEE single/double precision representation
7405 and is repacked into the internal 13-bit representation for these
7406 instructions with a diagnostic for overflow. Note that there is no
7407 rounding when converting to the smaller format, just an error if there
7408 is excess precision or the number is too small/large to be represented. */
7409
7410 bool
7411 float_work_fmovi (void)
7412 {
7413 int rx = csky_insn.val[0];
7414
7415 /* We already converted the float constant to the internal 13-bit
7416 representation so we just need to OR it in here. */
7417 csky_insn.inst = csky_insn.opcode->op32[0].opcode | rx;
7418 csky_insn.inst |= (uint32_t) csky_insn.e1.X_add_number;
7419
7420 csky_insn.output = frag_more (4);
7421 csky_insn.isize = 4;
7422 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
7423 return true;
7424 }
7425
7426 /* Like float_work_fmovi, but for FPUV3 fmovi.16, fmovi.32 and fmovi.64
7427 instructions. */
7428
7429 bool
7430 float_work_fpuv3_fmovi (void)
7431 {
7432 int rx = csky_insn.val[0];
7433 int idx = csky_insn.opcode_idx;
7434 int imm4 = 0;
7435 int imm8 = 0;
7436 int sign = 0;
7437
7438 csky_insn.inst = csky_insn.opcode->op32[idx].opcode | rx;
7439
7440 if (csky_insn.opcode->op32[idx].operand_num == 3)
7441 {
7442 /* fmovi.xx frz, imm9, imm4. */
7443 imm8 = csky_insn.val[1];
7444 imm4 = csky_insn.val[2];
7445 if (imm8 < 0 || (imm8 & 0x80000000))
7446 {
7447 sign = (1 << 5);
7448 imm8 = 0 - imm8;
7449 }
7450
7451 if (imm8 > 255)
7452 {
7453 csky_show_error (ERROR_IMM_OVERFLOW, 2, NULL, NULL);
7454 return false;
7455 }
7456
7457 /* imm8 store at bit [25:20] and [9:8]. */
7458 /* imm4 store at bit [19:16]. */
7459 /* sign store at bit [5]. */
7460 csky_insn.inst = csky_insn.inst
7461 | ((imm8 & 0x3) << 8)
7462 | ((imm8 & 0xfc) << 18)
7463 | ((imm4 & 0xf) << 16)
7464 | sign;
7465 }
7466 else
7467 {
7468 csky_insn.inst |= (uint32_t) csky_insn.e1.X_add_number;
7469 }
7470
7471 csky_insn.output = frag_more(4);
7472 csky_insn.isize = 4;
7473 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
7474 return true;
7475 }
7476
7477 bool
7478 dsp_work_bloop (void)
7479 {
7480 int reg = csky_insn.val[0];
7481 csky_insn.output = frag_more (4);
7482 csky_insn.inst = csky_insn.opcode->op32[0].opcode | (reg << 16);
7483 csky_insn.isize = 4;
7484
7485 if (csky_insn.number == 3
7486 && csky_insn.e1.X_op == O_symbol
7487 && csky_insn.e2.X_op == O_symbol)
7488 {
7489 fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
7490 4, &csky_insn.e1, 1,
7491 BFD_RELOC_CKCORE_PCREL_BLOOP_IMM12BY4);
7492 fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
7493 4, &csky_insn.e2, 1,
7494 BFD_RELOC_CKCORE_PCREL_BLOOP_IMM4BY4);
7495 }
7496 else if (csky_insn.number == 2
7497 && csky_insn.e1.X_op == O_symbol)
7498 {
7499 fix_new_exp (frag_now, csky_insn.output-frag_now->fr_literal,
7500 4, &csky_insn.e1, 1,
7501 BFD_RELOC_CKCORE_PCREL_BLOOP_IMM12BY4);
7502 if (csky_insn.last_isize == 2)
7503 csky_insn.inst |= (0xf << 12);
7504 else if (csky_insn.last_isize != 0)
7505 csky_insn.inst |= (0xe << 12);
7506 else
7507 {
7508 void *arg = (void *)"bloop can not be the first instruction"\
7509 "when the end label is not specified.\n";
7510 csky_show_error (ERROR_UNDEFINE, 0, arg, NULL);
7511 }
7512 }
7513
7514 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
7515 return true;
7516 }
7517
7518 bool
7519 float_work_fpuv3_fstore(void)
7520 {
7521 /* Generate relax or reloc if necessary. */
7522 csky_generate_frags ();
7523 /* Generate the insn by mask. */
7524 csky_generate_insn ();
7525 /* Write inst to frag. */
7526 csky_write_insn (csky_insn.output,
7527 csky_insn.inst,
7528 csky_insn.isize);
7529
7530
7531 return true;
7532 }
7533
7534 bool
7535 v2_work_addc (void)
7536 {
7537 int reg1;
7538 int reg2;
7539 int reg3 = 0;
7540 int is_16_bit = 0;
7541
7542 reg1 = csky_insn.val[0];
7543 reg2 = csky_insn.val[1];
7544 if (csky_insn.number == 2)
7545 {
7546 if (reg1 > 15 || reg2 > 15)
7547 {
7548 is_16_bit = 0;
7549 reg3 = reg1;
7550 }
7551 else
7552 is_16_bit = 1;
7553 }
7554 else
7555 {
7556 reg3 = csky_insn.val[2];
7557 if (reg1 > 15 || reg2 > 15 || reg3 > 15)
7558 is_16_bit = 0;
7559 else if (reg1 == reg2 || reg1 == reg3)
7560 {
7561 is_16_bit = 1;
7562 reg2 = (reg1 == reg2) ? reg3 : reg2;
7563 }
7564 else
7565 is_16_bit = 0;
7566 }
7567
7568 if (is_16_bit
7569 && csky_insn.flag_force != INSN_OPCODE32F)
7570 {
7571 csky_insn.isize = 2;
7572 csky_insn.inst = csky_insn.opcode->op16[0].opcode
7573 | (reg1 << 6) | (reg2 << 2);
7574 }
7575 else if (csky_insn.flag_force != INSN_OPCODE16F)
7576 {
7577 csky_insn.isize = 4;
7578 csky_insn.inst = csky_insn.opcode->op32[0].opcode
7579 | (reg1 << 0) | (reg2 << 16) | (reg3 << 21);
7580 }
7581 else
7582 {
7583 SET_ERROR_INTEGER (ERROR_REG_OVER_RANGE, reg1 > 15 ? reg1 : reg2);
7584 csky_show_error (ERROR_REG_OVER_RANGE, 0, 0, NULL);
7585 }
7586
7587 /* Generate relax or reloc if necessary. */
7588 csky_generate_frags ();
7589 /* Write inst to frag. */
7590 csky_write_insn (csky_insn.output,
7591 csky_insn.inst,
7592 csky_insn.isize);
7593
7594 return true;
7595 }
7596
7597 /* The following are for assembler directive handling. */
7598
7599 /* Helper function to adjust constant pool counts when we emit a
7600 data directive in the text section. FUNC is one of the standard
7601 gas functions to handle these directives, like "stringer" for the
7602 .string directive, and ARG is the argument to FUNC. csky_pool_count
7603 essentially wraps the call with the constant pool magic. */
7604
7605 static void
7606 csky_pool_count (void (*func) (int), int arg)
7607 {
7608 const fragS *curr_frag = frag_now;
7609 offsetT added = -frag_now_fix_octets ();
7610
7611 (*func) (arg);
7612
7613 while (curr_frag != frag_now)
7614 {
7615 added += curr_frag->fr_fix;
7616 curr_frag = curr_frag->fr_next;
7617 }
7618
7619 added += frag_now_fix_octets ();
7620 poolspan += added;
7621 }
7622
7623 /* Support the .literals directive. */
7624 static void
7625 csky_s_literals (int ignore ATTRIBUTE_UNUSED)
7626 {
7627 dump_literals (0);
7628 demand_empty_rest_of_line ();
7629 }
7630
7631 /* Support the .string, etc directives. */
7632 static void
7633 csky_stringer (int append_zero)
7634 {
7635 if (now_seg == text_section)
7636 csky_pool_count (stringer, append_zero);
7637 else
7638 stringer (append_zero);
7639
7640 /* We call check_literals here in case a large number of strings are
7641 being placed into the text section with a sequence of stringer
7642 directives. In theory we could be upsetting something if these
7643 strings are actually in an indexed table instead of referenced by
7644 individual labels. Let us hope that that never happens. */
7645 check_literals (2, 0);
7646 }
7647
7648 /* Support integer-mode constructors like .word, .byte, etc. */
7649
7650 static void
7651 csky_cons (int nbytes)
7652 {
7653 mapping_state (MAP_DATA);
7654 if (nbytes == 4) /* @GOT. */
7655 {
7656 do
7657 {
7658 bfd_reloc_code_real_type reloc;
7659 expressionS exp;
7660
7661 reloc = BFD_RELOC_NONE;
7662 expression (&exp);
7663 lex_got (&reloc, NULL);
7664
7665 if (exp.X_op == O_symbol && reloc != BFD_RELOC_NONE)
7666 {
7667 reloc_howto_type *howto
7668 = bfd_reloc_type_lookup (stdoutput, reloc);
7669 int size = bfd_get_reloc_size (howto);
7670
7671 if (size > nbytes)
7672 as_bad (ngettext ("%s relocations do not fit in %d byte",
7673 "%s relocations do not fit in %d bytes",
7674 nbytes),
7675 howto->name, nbytes);
7676 else
7677 {
7678 register char *p = frag_more ((int) nbytes);
7679 int offset = nbytes - size;
7680
7681 fix_new_exp (frag_now,
7682 p - frag_now->fr_literal + offset,
7683 size, &exp, 0, reloc);
7684 }
7685 }
7686 else
7687 emit_expr (&exp, (unsigned int) nbytes);
7688 if (now_seg == text_section)
7689 poolspan += nbytes;
7690 }
7691 while (*input_line_pointer++ == ',');
7692
7693 /* Put terminator back into stream. */
7694 input_line_pointer --;
7695 demand_empty_rest_of_line ();
7696
7697 return;
7698 }
7699
7700 if (now_seg == text_section)
7701 csky_pool_count (cons, nbytes);
7702 else
7703 cons (nbytes);
7704
7705 /* In theory we ought to call check_literals (2,0) here in case
7706 we need to dump the literal table. We cannot do this however,
7707 as the directives that we are intercepting may be being used
7708 to build a switch table, and we must not interfere with its
7709 contents. Instead we cross our fingers and pray... */
7710 }
7711
7712 /* Support floating-mode constant directives like .float and .double. */
7713
7714 static void
7715 csky_float_cons (int float_type)
7716 {
7717 mapping_state (MAP_DATA);
7718 if (now_seg == text_section)
7719 csky_pool_count (float_cons, float_type);
7720 else
7721 float_cons (float_type);
7722
7723 /* See the comment in csky_cons () about calling check_literals.
7724 It is unlikely that a switch table will be constructed using
7725 floating point values, but it is still likely that an indexed
7726 table of floating point constants is being created by these
7727 directives, so again we must not interfere with their placement. */
7728 }
7729
7730 /* Support the .fill directive. */
7731
7732 static void
7733 csky_fill (int ignore)
7734 {
7735 if (now_seg == text_section)
7736 csky_pool_count (s_fill, ignore);
7737 else
7738 s_fill (ignore);
7739
7740 check_literals (2, 0);
7741 }
7742
7743 /* Handle the section changing pseudo-ops. These call through to the
7744 normal implementations, but they dump the literal pool first. */
7745
7746 static void
7747 csky_s_text (int ignore)
7748 {
7749 dump_literals (0);
7750
7751 #ifdef OBJ_ELF
7752 obj_elf_text (ignore);
7753 #else
7754 s_text (ignore);
7755 #endif
7756 }
7757
7758 static void
7759 csky_s_data (int ignore)
7760 {
7761 dump_literals (0);
7762
7763 #ifdef OBJ_ELF
7764 obj_elf_data (ignore);
7765 #else
7766 s_data (ignore);
7767 #endif
7768 }
7769
7770 static void
7771 csky_s_section (int ignore)
7772 {
7773 /* Scan forwards to find the name of the section. If the section
7774 being switched to is ".line" then this is a DWARF1 debug section
7775 which is arbitrarily placed inside generated code. In this case
7776 do not dump the literal pool because it is a) inefficient and
7777 b) would require the generation of extra code to jump around the
7778 pool. */
7779 char * ilp = input_line_pointer;
7780
7781 while (*ilp != 0 && ISSPACE (*ilp))
7782 ++ ilp;
7783
7784 if (startswith (ilp, ".line")
7785 && (ISSPACE (ilp[5]) || *ilp == '\n' || *ilp == '\r'))
7786 ;
7787 else
7788 dump_literals (0);
7789
7790 #ifdef OBJ_ELF
7791 obj_elf_section (ignore);
7792 #endif
7793 #ifdef OBJ_COFF
7794 obj_coff_section (ignore);
7795 #endif
7796 }
7797
7798 static void
7799 csky_s_bss (int needs_align)
7800 {
7801 dump_literals (0);
7802 s_lcomm_bytes (needs_align);
7803 }
7804
7805 #ifdef OBJ_ELF
7806 static void
7807 csky_s_comm (int needs_align)
7808 {
7809 dump_literals (0);
7810 obj_elf_common (needs_align);
7811 }
7812 #endif
7813
7814 /* Handle the .no_literal_dump directive. */
7815
7816 static void
7817 csky_noliteraldump (int ignore ATTRIBUTE_UNUSED)
7818 {
7819 do_noliteraldump = 1;
7820 int insn_num = get_absolute_expression ();
7821 /* The insn after '.no_literal_dump insn_num' is insn1,
7822 Don't dump literal pool between insn1 and insn(insn_num+1)
7823 The insn cannot be the insn generate literal, like lrw & jsri. */
7824 check_literals (0, insn_num * 2);
7825 }
7826
7827 /* Handle the .align directive.
7828 We must check literals before doing alignment. For example, if
7829 '.align n', add (2^n-1) to poolspan and check literals. */
7830
7831 static void
7832 csky_s_align_ptwo (int arg)
7833 {
7834 /* Get the .align's first absolute number. */
7835 char * temp_pointer = input_line_pointer;
7836 int align = get_absolute_expression ();
7837 check_literals (0, (1 << align) - 1);
7838 input_line_pointer = temp_pointer;
7839
7840 /* Do alignment. */
7841 s_align_ptwo (arg);
7842 }
7843
7844 /* Handle the .stack_size directive. */
7845
7846 static void
7847 csky_stack_size (int arg ATTRIBUTE_UNUSED)
7848 {
7849 expressionS exp;
7850 stack_size_entry *sse
7851 = (stack_size_entry *) xcalloc (1, sizeof (stack_size_entry));
7852
7853 expression (&exp);
7854 if (exp.X_op == O_symbol)
7855 sse->function = exp.X_add_symbol;
7856 else
7857 {
7858 as_bad (_("the first operand must be a symbol"));
7859 ignore_rest_of_line ();
7860 free (sse);
7861 return;
7862 }
7863
7864 SKIP_WHITESPACE ();
7865 if (*input_line_pointer != ',')
7866 {
7867 as_bad (_("missing stack size"));
7868 ignore_rest_of_line ();
7869 free (sse);
7870 return;
7871 }
7872
7873 ++input_line_pointer;
7874 expression (&exp);
7875 if (exp.X_op == O_constant)
7876 {
7877 if (exp.X_add_number < 0 || exp.X_add_number > (offsetT)0xffffffff)
7878 {
7879
7880 as_bad (_("value not in range [0, 0xffffffff]"));
7881 ignore_rest_of_line ();
7882 free (sse);
7883 return;
7884 }
7885 else
7886 sse->stack_size = exp.X_add_number;
7887 }
7888 else
7889 {
7890 as_bad (_("operand must be a constant"));
7891 ignore_rest_of_line ();
7892 free (sse);
7893 return;
7894 }
7895
7896 if (*last_stack_size_data != NULL)
7897 last_stack_size_data = &((*last_stack_size_data)->next);
7898
7899 *last_stack_size_data = sse;
7900 }
7901
7902 /* This table describes all the machine specific pseudo-ops the assembler
7903 has to support. The fields are:
7904 pseudo-op name without dot
7905 function to call to execute this pseudo-op
7906 Integer arg to pass to the function. */
7907
7908 const pseudo_typeS md_pseudo_table[] =
7909 {
7910 { "export", s_globl, 0 },
7911 { "import", s_ignore, 0 },
7912 { "literals", csky_s_literals, 0 },
7913 { "page", listing_eject, 0 },
7914
7915 /* The following are to intercept the placement of data into the text
7916 section (eg addresses for a switch table), so that the space they
7917 occupy can be taken into account when deciding whether or not to
7918 dump the current literal pool.
7919 XXX - currently we do not cope with the .space and .dcb.d directives. */
7920 { "ascii", csky_stringer, 8 + 0 },
7921 { "asciz", csky_stringer, 8 + 1 },
7922 { "byte", csky_cons, 1 },
7923 { "dc", csky_cons, 2 },
7924 { "dc.b", csky_cons, 1 },
7925 { "dc.d", csky_float_cons, 'd'},
7926 { "dc.l", csky_cons, 4 },
7927 { "dc.s", csky_float_cons, 'f'},
7928 { "dc.w", csky_cons, 2 },
7929 { "dc.x", csky_float_cons, 'x'},
7930 { "double", csky_float_cons, 'd'},
7931 { "float", csky_float_cons, 'f'},
7932 { "hword", csky_cons, 2 },
7933 { "int", csky_cons, 4 },
7934 { "long", csky_cons, 4 },
7935 { "octa", csky_cons, 16 },
7936 { "quad", csky_cons, 8 },
7937 { "short", csky_cons, 2 },
7938 { "single", csky_float_cons, 'f'},
7939 { "string", csky_stringer, 8 + 1 },
7940 { "word", csky_cons, 4 },
7941 { "fill", csky_fill, 0 },
7942
7943 /* Allow for the effect of section changes. */
7944 { "text", csky_s_text, 0 },
7945 { "data", csky_s_data, 0 },
7946 { "bss", csky_s_bss, 1 },
7947 #ifdef OBJ_ELF
7948 { "comm", csky_s_comm, 0 },
7949 #endif
7950 { "section", csky_s_section, 0 },
7951 { "section.s", csky_s_section, 0 },
7952 { "sect", csky_s_section, 0 },
7953 { "sect.s", csky_s_section, 0 },
7954 /* When ".no_literal_dump N" is in front of insn1,
7955 and instruction sequence is:
7956 insn1
7957 insn2
7958 ......
7959 insnN+1
7960 it means literals will not dump between insn1 and insnN+1
7961 The insn cannot itself generate literal, like lrw & jsri. */
7962 { "no_literal_dump", csky_noliteraldump, 0 },
7963 { "align", csky_s_align_ptwo, 0 },
7964 { "stack_size", csky_stack_size, 0 },
7965 {0, 0, 0}
7966 };
7967
7968 /* Implement tc_cfi_frame_initial_instructions. */
7969
7970 void
7971 csky_cfi_frame_initial_instructions (void)
7972 {
7973 int sp_reg = IS_CSKY_V1 (mach_flag) ? 0 : 14;
7974 cfi_add_CFA_def_cfa_register (sp_reg);
7975 }
7976
7977 /* Implement tc_regname_to_dw2regnum. */
7978
7979 int
7980 tc_csky_regname_to_dw2regnum (char *regname)
7981 {
7982 int reg_num = -1;
7983 int len;
7984
7985 /* FIXME the reg should be parsed according to
7986 the abi version. */
7987 reg_num = csky_get_reg_val (regname, &len);
7988 return reg_num;
7989 }