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