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