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