]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gas/config/tc-csky.c
Update year range in copyright notice of binutils files
[thirdparty/binutils-gdb.git] / gas / config / tc-csky.c
CommitLineData
b8891f8d 1/* tc-csky.c -- Assembler for C-SKY
a2c58332 2 Copyright (C) 1989-2022 Free Software Foundation, Inc.
b8891f8d
AJ
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"
b8891f8d
AJ
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. */
5b7c81bd
AM
149bool v1_work_lrw (void);
150bool v1_work_jbsr (void);
151bool v1_work_fpu_fo (void);
152bool v1_work_fpu_fo_fc (void);
153bool v1_work_fpu_write (void);
154bool v1_work_fpu_read (void);
155bool v1_work_fpu_writed (void);
156bool v1_work_fpu_readd (void);
157bool v2_work_istack (void);
158bool v2_work_btsti (void);
159bool v2_work_addi (void);
160bool v2_work_subi (void);
161bool v2_work_add_sub (void);
162bool v2_work_rotlc (void);
163bool v2_work_bgeni (void);
164bool v2_work_not (void);
165bool v2_work_jbtf (void);
166bool v2_work_jbr (void);
167bool v2_work_lrw (void);
168bool v2_work_lrsrsw (void);
169bool v2_work_jbsr (void);
170bool v2_work_jsri (void);
171bool v2_work_movih (void);
172bool v2_work_ori (void);
173bool float_work_fmovi (void);
174bool dsp_work_bloop (void);
175bool float_work_fpuv3_fmovi (void);
176bool float_work_fpuv3_fstore (void);
177bool v2_work_addc (void);
b8891f8d
AJ
178
179/* csky-opc.h must be included after workers are declared. */
180#include "opcodes/csky-opc.h"
181#include "opcode/csky.h"
182
183enum
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
215unsigned int mach_flag = 0;
216unsigned int arch_flag = 0;
217unsigned int other_flag = 0;
0861f561 218BFD_HOST_U_64_BIT isa_flag = 0;
b8891f8d
AJ
219unsigned int dsp_flag = 0;
220
221typedef struct stack_size_entry
222{
223 struct stack_size_entry *next;
224 symbolS *function;
225 unsigned int stack_size;
226} stack_size_entry;
227
228struct csky_arch_info
229{
230 const char *name;
231 unsigned int arch_flag;
232 unsigned int bfd_mach_flag;
233};
234
b8891f8d
AJ
235typedef enum
236{
237 INSN_OPCODE,
238 INSN_OPCODE16F,
239 INSN_OPCODE32F,
240} inst_flag;
241
242/* Macro information. */
243struct 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;
0861f561 248 BFD_HOST_U_64_BIT isa_flag;
b8891f8d
AJ
249 /* Do the work. */
250 void (*handle_func)(void);
251};
252
253struct 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;
525a0aa3
CQ
263 /* CPU infomations. */
264 const struct csky_cpu_info *cpu;
b8891f8d
AJ
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;
d285ba8d 273 unsigned int last_isize;
b8891f8d
AJ
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. */
293struct literal
294{
295 unsigned short refcnt;
1feede9b 296 unsigned int offset;
b8891f8d
AJ
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;
e61ef79e 304 LITTLENUM_TYPE bignum[SIZE_OF_LARGE_NUMBER + 6];
b8891f8d
AJ
305};
306
307static void csky_idly (void);
308static void csky_rolc (void);
309static void csky_sxtrb (void);
310static void csky_movtf (void);
311static void csky_addc64 (void);
312static void csky_subc64 (void);
313static void csky_or64 (void);
314static void csky_xor64 (void);
315static void csky_neg (void);
316static void csky_rsubi (void);
317static void csky_arith (void);
318static void csky_decne (void);
319static void csky_lrw (void);
320
321static enum bfd_reloc_code_real insn_reloc;
322
323/* Assembler operand parse errors use these identifiers. */
324
325enum error_number
326{
327 /* The following are errors. */
328 ERROR_CREG_ILLEGAL = 0,
329 ERROR_REG_OVER_RANGE,
e2e82b11
CQ
330 ERROR_FREG_OVER_RANGE,
331 ERROR_VREG_OVER_RANGE,
b8891f8d
AJ
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
373struct csky_error_state
374{
375 enum error_number err_num;
376 int opnum;
e2e82b11 377 int arg_int;
b8891f8d
AJ
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
e2e82b11 384#define SET_ERROR_STRING(err, msg) \
b8891f8d
AJ
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
e2e82b11
CQ
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)
b8891f8d
AJ
401
402/* Map error identifiers onto a format string, which will use
403 arg1 and arg2 from the global error state. */
404struct csky_error_format_map
405{
406 enum error_number num;
407 const char *fmt;
408};
409
410static 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."},
e2e82b11
CQ
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."},
b8891f8d
AJ
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
450static int do_pic = 0; /* for jbr/jbf/jbt relax jmpi reloc. */
451static int do_pff = -1; /* for insert two br ahead of literals. */
452static int do_force2bsr = -1; /* for jbsr->bsr. */
453static int do_jsri2bsr = 1; /* for jsri->bsr. */
454static int do_nolrw = 0; /* lrw to movih & ori, only for V2. */
455static int do_long_jump = -1; /* control if jbf,jbt,jbr relax to jmpi. */
456static int do_extend_lrw = -1; /* delete bsr16 in both two options,
457 add btesti16, lrw offset +1 in -melrw. */
458static int do_func_dump = 0; /* dump literals after every function. */
459static int do_br_dump = 1; /* work for -mabr/-mno-abr, control the literals dump. */
460static int do_intr_stack = -1; /* control interrupt stack module, 801&802&803
461 default on, 807&810, default off. */
a2061b9f 462static int float_abi = 0;
b8891f8d
AJ
463
464#ifdef INCLUDE_BRANCH_STUB
465static int do_use_branchstub = -1;
466#else
467static 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. */
472static int do_opt_mmp = 0;
473static int do_opt_mcp = 0;
474static int do_opt_mcache = 0;
475static int do_opt_msecurity = 0;
476static int do_opt_mhard_float = 0;
477static int do_opt_mtrust = 0;
478static int do_opt_mdsp = 0;
479static int do_opt_medsp = 0;
480static int do_opt_mvdsp = 0;
481
482const relax_typeS *md_relax_table = NULL;
483struct literal *literal_insn_offset;
484static struct literal litpool[MAX_POOL_SIZE];
485static unsigned poolsize = 0;
486static unsigned poolnumber = 0;
487static unsigned long poolspan = 0;
488static unsigned int SPANPANIC;
489static unsigned int SPANCLOSE;
490static unsigned int SPANEXIT;
491
492static stack_size_entry *all_stack_size_data = NULL;
493static 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. */
498static int do_noliteraldump = 0;
499
500/* Label for current pool. */
501static symbolS * poolsym;
502static char poolname[8];
503
5b7c81bd
AM
504static bool mov_r1_before;
505static bool mov_r1_after;
b8891f8d
AJ
506
507const 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
569static void csky_write_insn (char *ptr, valueT use, int nbytes);
570void md_number_to_chars (char * buf, valueT val, int n);
571long md_pcrel_from_section (fixS * fixP, segT seg);
572
573/* C-SKY architecture table. */
574const 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},
531c73a3
CQ
581 {"ck807", CSKY_ARCH_807, bfd_mach_ck807},
582 {"ck810", CSKY_ARCH_810, bfd_mach_ck810},
583 {"ck860", CSKY_ARCH_860, bfd_mach_ck860},
b8891f8d
AJ
584 {NULL, 0, 0}
585};
586
531c73a3
CQ
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
525a0aa3
CQ
590struct csky_cpu_feature
591{
592 const char unique;
593 unsigned int arch_flag;
594 bfd_uint64_t isa_flag;
595};
596
597struct 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
607struct 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. */
b8891f8d
AJ
752const struct csky_cpu_info csky_cpus[] =
753{
525a0aa3
CQ
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)
6a1ed910 777#define CSKYV2_ISA_DSP (CSKY_ISA_DSP | CSKY_ISA_DSP_1E2 | CSKY_ISA_DSPE60)
525a0aa3
CQ
778 {"ck801",
779 CSKY_ARCH_801,
780 CSKY_ISA_801,
781 CSKY_FEATURES_DEF_t(0),
782 CSKY_CPU_REVERISON_RESERVED()},
b8891f8d 783#define CSKY_ISA_802 (CSKY_ISA_801 | CSKYV2_ISA_1E2 | CSKY_ISA_NVIC)
525a0aa3
CQ
784 {"ck802",
785 CSKY_ARCH_802,
786 CSKY_ISA_802,
787 CSKY_FEATURES_DEF_jt(CSKY_ISA_JAVA, 0),
788 CSKY_CPU_REVERISON_RESERVED()},
b8891f8d 789#define CSKY_ISA_803 (CSKY_ISA_802 | CSKYV2_ISA_2E3 | CSKY_ISA_MP)
525a0aa3
CQ
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)
b8891f8d 793#define CSKY_ISA_FLOAT_803 (CSKY_ISA_FLOAT_E1 | CSKY_ISA_FLOAT_1E3)
525a0aa3
CQ
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)
b8891f8d 820#define CSKY_ISA_FLOAT_807 (CSKY_ISA_FLOAT_803 | CSKY_ISA_FLOAT_3E4 | CSKY_ISA_FLOAT_1E2)
525a0aa3
CQ
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)
b8891f8d 827#define CSKY_ISA_FLOAT_810 (CSKY_ISA_FLOAT_E1 | CSKY_ISA_FLOAT_1E2)
525a0aa3
CQ
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},
b8891f8d
AJ
940};
941
942int md_short_jump_size = 2;
943int 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. */
947const 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. */
956const char line_comment_chars[] = "#";
957
958const char line_separator_chars[] = ";";
959
960/* Chars that can be used to separate mant
961 from exp in floating point numbers. */
962const 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
968const char FLT_CHARS[] = "rRsSfFdDxXeEpP";
969
970const char *md_shortopts = "";
971
972struct 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},
a2061b9f
CQ
977#define OPTION_FLOAT_ABI (OPTION_MD_BASE + 2)
978 {"mfloat-abi", required_argument, NULL, OPTION_FLOAT_ABI},
b8891f8d
AJ
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
1026size_t md_longopts_size = sizeof (md_longopts);
1027
1028static struct csky_insn_info csky_insn;
1029
629310ab
ML
1030static htab_t csky_opcodes_hash;
1031static htab_t csky_macros_hash;
b8891f8d
AJ
1032
1033static 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
1049static 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. */
1067static 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
1072static void
1073csky_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:
e2e82b11 1108 as_bad (_(err_formats[err].fmt), error_state.arg_int);
b8891f8d
AJ
1109 break;
1110
1111 case ERROR_OFFSET_UNALIGNED:
e2e82b11 1112 as_bad (_(err_formats[err].fmt), idx, error_state.arg_int);
b8891f8d
AJ
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:
e2e82b11
CQ
1120 case ERROR_FREG_OVER_RANGE:
1121 case ERROR_VREG_OVER_RANGE:
1122 as_bad (_(err_formats[err].fmt), idx, error_state.arg_int);
b8891f8d
AJ
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
1145static void
1146csky_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
1158static void
1159parse_cpu (const char *str)
1160{
1161 int i = 0;
1162
1163 for (; csky_cpus[i].name != NULL; i++)
525a0aa3 1164 if (strncasecmp (str, csky_cpus[i].name, strlen (csky_cpus[i].name)) == 0)
b8891f8d 1165 {
525a0aa3
CQ
1166 csky_insn.cpu = &csky_cpus[i];
1167 mach_flag |= csky_cpus[i].arch_flag;
b8891f8d 1168 isa_flag = csky_cpus[i].isa_flag;
525a0aa3
CQ
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 }
b8891f8d
AJ
1214 return;
1215 }
525a0aa3
CQ
1216
1217unknown_cpu:
b8891f8d
AJ
1218 as_bad (_("unknown cpu `%s'"), str);
1219}
1220
1221/* Set appropriate flags for the arch matching STR. */
1222
1223static void
1224parse_arch (const char *str)
1225{
1226 int i = 0;
525a0aa3
CQ
1227 for (; csky_cpus[i].name != NULL; i++)
1228 if (strcasecmp (str, csky_cpus[i].name) == 0)
b8891f8d 1229 {
525a0aa3
CQ
1230 csky_insn.cpu = &csky_cpus[i];
1231 arch_flag |= csky_cpus[i].arch_flag;
1232 isa_flag |= csky_cpus[i].isa_flag;
b8891f8d
AJ
1233 return;
1234 }
1235 as_bad (_("unknown architecture `%s'"), str);
1236}
1237
a2061b9f
CQ
1238struct csky_option_value_table
1239{
1240 const char *name;
1241 long value;
1242};
1243
1244static 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
5b7c81bd 1252static bool
a2061b9f
CQ
1253parse_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;
5b7c81bd 1261 return true;
a2061b9f
CQ
1262 }
1263
1264 as_bad (_("unknown floating point abi `%s'\n"), str);
5b7c81bd 1265 return false;
a2061b9f 1266}
b8891f8d
AJ
1267
1268#ifdef OBJ_ELF
1269/* Implement the TARGET_FORMAT macro. */
1270
1271const char *
1272elf32_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
1287void
1288md_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
1298static int
1299csky_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
1312static void
1313csky_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
1328static valueT
1329csky_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
1357static void
1358make_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
1374void
1375md_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
1383symbolS *
1384md_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
1394const char *
1395md_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
1402void
1403md_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:"));
525a0aa3
CQ
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++)
b8891f8d 1434 {
525a0aa3
CQ
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 }
b8891f8d
AJ
1453 }
1454 fprintf (fp, "\n");
1455
a2061b9f
CQ
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
b8891f8d
AJ
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
0861f561
CQ
1544static 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");
a2061b9f
CQ
1605 bfd_elf_add_obj_attr_int (stdoutput, OBJ_ATTR_PROC,
1606 Tag_CSKY_FPU_ABI,
1607 float_abi);
0861f561
CQ
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
b8891f8d
AJ
1619/* Target-specific initialization and option handling. */
1620
1621void
1622md_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;
525a0aa3
CQ
1629 other_flag = (do_opt_mmp | do_opt_mcp | do_opt_mcache
1630 | do_opt_msecurity | do_opt_mhard_float);
b8891f8d
AJ
1631 dsp_flag |= do_opt_mdsp | do_opt_medsp;
1632 isa_flag |= do_opt_mtrust | do_opt_mvdsp;
1633
1634 if (dsp_flag)
74fea55b 1635 other_flag |= CSKY_ARCH_DSP;
b8891f8d
AJ
1636
1637 if (mach_flag != 0)
1638 {
525a0aa3
CQ
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");
b8891f8d
AJ
1643 }
1644 else if (arch_flag != 0)
525a0aa3 1645 mach_flag |= arch_flag | other_flag;
b8891f8d
AJ
1646 else
1647 {
1648#ifdef TARGET_WITH_CPU
525a0aa3 1649 parse_cpu (TARGET_WITH_CPU);
b8891f8d
AJ
1650#else
1651#if _CSKY_ABI==1
525a0aa3 1652 parse_cpu ("ck610");
b8891f8d 1653#else
525a0aa3 1654 parse_cpu ("ck810");
b8891f8d 1655#endif
74fea55b 1656 mach_flag |= other_flag;
b8891f8d
AJ
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 {
0861f561
CQ
1679 bfd_elf_add_obj_attr_string (stdoutput, OBJ_ATTR_PROC,
1680 Tag_CSKY_ARCH_NAME, p_arch->name);
b8891f8d
AJ
1681 bfd_mach_flag = p_arch->bfd_mach_flag;
1682 break;
1683 }
1684
1685 /* Find isa_flag. */
525a0aa3
CQ
1686 for (p_cpu = csky_cpus; p_cpu->arch_flag != 0; p_cpu++)
1687 if ((mach_flag & CPU_ARCH_MASK) == p_cpu->arch_flag)
b8891f8d 1688 {
0861f561
CQ
1689 bfd_elf_add_obj_attr_string (stdoutput, OBJ_ATTR_PROC,
1690 Tag_CSKY_CPU_NAME, p_cpu->name);
b8891f8d
AJ
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 {
d04aee0f
CQ
1701 if ((dsp_flag & CSKY_DSP_FLAG_V1))
1702 {
dd221981
CQ
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 }
d04aee0f
CQ
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");
0861f561 1730 dsp_flag &= ~CSKY_DSP_FLAG_V1;
d04aee0f
CQ
1731 isa_flag &= ~(CSKY_ISA_MAC_DSP | CSKY_ISA_DSP);
1732 isa_flag |= CSKY_ISA_DSP_ENHANCE;
1733 }
b8891f8d
AJ
1734 }
1735 else
1736 {
d04aee0f
CQ
1737 if (dsp_flag & CSKY_DSP_FLAG_V2)
1738 {
0861f561 1739 dsp_flag &= ~CSKY_DSP_FLAG_V2;
d04aee0f
CQ
1740 isa_flag &= ~CSKY_ISA_DSP_ENHANCE;
1741 as_warn ("-medsp option is only supported by ck803s, ignoring -medsp");
1742 }
b8891f8d
AJ
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 {
89ce8eab
CQ
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)
b8891f8d
AJ
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 }
0861f561 1807 /* Add isa_flag(SIMP/CACHE/APS). */
b8891f8d
AJ
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. */
629310ab
ML
1843 csky_macros_hash = str_htab_create ();
1844 csky_opcodes_hash = str_htab_create ();
b8891f8d
AJ
1845 for ( ; opcode->mnemonic != NULL; opcode++)
1846 if ((isa_flag & (opcode->isa_flag16 | opcode->isa_flag32)) != 0)
fe0e921f 1847 str_hash_insert (csky_opcodes_hash, opcode->mnemonic, opcode, 0);
b8891f8d
AJ
1848 for ( ; macro->name != NULL; macro++)
1849 if ((isa_flag & macro->isa_flag) != 0)
fe0e921f 1850 str_hash_insert (csky_macros_hash, macro->name, macro, 0);
b8891f8d 1851 if (do_nolrw && (isa_flag & CSKYV2_ISA_1E2) != 0)
629310ab 1852 str_hash_insert (csky_macros_hash,
fe0e921f 1853 v2_lrw_macro_opcode.name, &v2_lrw_macro_opcode, 0);
b8891f8d 1854 /* Set e_flag to ELF Head. */
9d1ccf22 1855 bfd_set_private_flags (stdoutput, mach_flag | CSKY_VERSION_V1);
b8891f8d
AJ
1856 /* Set bfd_mach to bfd backend data. */
1857 bfd_set_arch_mach (stdoutput, bfd_arch_csky, bfd_mach_flag);
0861f561
CQ
1858
1859 set_csky_attribute ();
b8891f8d
AJ
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
1866static void
1867make_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
e01e1cee 1886 symbolP = symbol_new (symname, now_seg, frag, value);
b8891f8d
AJ
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
1893static void
1894mapping_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
1916static void
1917dump_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
e61ef79e 1992 for (i = 0, p = litpool; i < poolsize; p++)
b8891f8d
AJ
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 }
e61ef79e
CQ
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 }
b8891f8d
AJ
2021 else
2022 emit_expr (& p->e, 4);
e61ef79e
CQ
2023
2024 if (p->e.X_op == O_big)
2e58f392
CQ
2025 i += (p->e.X_add_number & 1) +
2026 ((p->e.X_add_number * CHARS_PER_LITTLENUM) >> 2);
e61ef79e
CQ
2027 else
2028 i += (p->isdouble ? 2 : 1);
b8891f8d
AJ
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
1feede9b 2046static struct literal *
b8891f8d
AJ
2047enter_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. */
e61ef79e 2082 for (p = litpool,i = 0; i < poolsize; p++)
b8891f8d
AJ
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
e61ef79e
CQ
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)))
b8891f8d
AJ
2098 {
2099 p->refcnt ++;
1feede9b 2100 return p;
b8891f8d 2101 }
e61ef79e
CQ
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);
b8891f8d
AJ
2109 }
2110 p->refcnt = 1;
2111 p->ispcrel = ispcrel;
2112 p->e = *e;
2113 p->r_type = insn_reloc;
2114 p->isdouble = isdouble;
1feede9b 2115 p->offset = i;
b8891f8d
AJ
2116 if (isdouble)
2117 p->dbnum = dbnum;
e61ef79e
CQ
2118 if (e->X_op == O_big)
2119 memcpy (p->bignum, generic_bignum, sizeof (p->bignum));
b8891f8d
AJ
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 }
e61ef79e
CQ
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
b8891f8d 2133 poolsize += (p->isdouble ? 2 : 1);
e61ef79e 2134
1feede9b 2135 return p;
b8891f8d
AJ
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
2163static void
2164check_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
2200static char *
2201lex_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
2261static char *
2262parse_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)
e2e82b11 2279 SET_ERROR_STRING (ERROR_MISSING_OPERAND, NULL);
b8891f8d
AJ
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
2292static char *
2293parse_fexp (char *s, expressionS *e, unsigned char isdouble, uint64_t *dbnum)
2294{
2295 int length; /* Number of chars in an object. */
4f7cc141
AM
2296 const char *err = NULL; /* Error from scanning float literal. */
2297 unsigned char temp[8];
b8891f8d
AJ
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)
4f7cc141 2307 err = md_atof ('d', (char *) temp, &length);
b8891f8d 2308 else
4f7cc141 2309 err = md_atof ('f', (char *) temp, &length);
b8891f8d
AJ
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)
4f7cc141
AM
2337 fnum = (((uint32_t) temp[0] << 24)
2338 | (temp[1] << 16)
2339 | (temp[2] << 8)
2340 | temp[3]);
b8891f8d 2341 else
4f7cc141
AM
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 }
b8891f8d
AJ
2348 else
2349 {
2350 if (target_big_endian)
2351 {
4f7cc141
AM
2352 *dbnum = (((uint32_t) temp[0] << 24)
2353 | (temp[1] << 16)
2354 | (temp[2] << 8)
2355 | temp[3]);
b8891f8d 2356 *dbnum <<= 32;
4f7cc141
AM
2357 *dbnum |= (((uint32_t) temp[4] << 24)
2358 | (temp[5] << 16)
2359 | (temp[6] << 8)
2360 | temp[7]);
b8891f8d
AJ
2361 }
2362 else
2363 {
4f7cc141
AM
2364 *dbnum = (((uint32_t) temp[7] << 24)
2365 | (temp[6] << 16)
2366 | (temp[5] << 8)
2367 | temp[4]);
b8891f8d 2368 *dbnum <<= 32;
4f7cc141
AM
2369 *dbnum |= (((uint32_t) temp[3] << 24)
2370 | (temp[2] << 16)
2371 | (temp[1] << 8)
2372 | temp[0]);
b8891f8d
AJ
2373 }
2374 }
2375 return input_line_pointer;
2376}
2377
2378static char *
2379parse_rt (char *s,
2380 int ispcrel,
2381 expressionS *ep,
2382 long reg ATTRIBUTE_UNUSED)
2383{
2384 expressionS e;
b8891f8d
AJ
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
e2e82b11 2397 SET_ERROR_STRING (ERROR_MISSING_RSQUARE_BRACKETS, NULL);
b8891f8d
AJ
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 {
1feede9b 2417 struct literal *p = enter_literal (&e, ispcrel, 0, 0);
b8891f8d
AJ
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;
1feede9b 2424 ep->X_add_number = p->offset << 2;
b8891f8d
AJ
2425 }
2426 }
2427 return s;
2428}
2429
1feede9b
CQ
2430static 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
b8891f8d
AJ
2451static char *
2452parse_rtf (char *s, int ispcrel, expressionS *ep)
2453{
2454 expressionS e;
1feede9b 2455 struct literal *p = NULL;
b8891f8d
AJ
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;
1feede9b
CQ
2476 if (strstr(csky_insn.opcode->mnemonic, "flrws")
2477 || strstr(csky_insn.opcode->mnemonic, "flrw.32"))
b8891f8d
AJ
2478 {
2479 s = parse_fexp (s, &e, 0, &dbnum);
1feede9b 2480 p = enter_literal (& e, ispcrel, 0, dbnum);
b8891f8d 2481 }
1feede9b
CQ
2482 else if (strstr(csky_insn.opcode->mnemonic, "flrwd")
2483 || strstr(csky_insn.opcode->mnemonic, "flrw.64"))
b8891f8d
AJ
2484 {
2485 s = parse_fexp (s, &e, 1, &dbnum);
1feede9b
CQ
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);
b8891f8d
AJ
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;
1feede9b 2504 ep->X_add_number = p->offset << 2;
b8891f8d
AJ
2505 }
2506 return s;
2507}
2508
5b7c81bd 2509static bool
b8891f8d
AJ
2510parse_type_ctrlreg (char** oper)
2511{
2512 int i = -1;
afdcafe8
CQ
2513 int group = 0;
2514 int crx;
2515 int sel;
2516 char *s = *oper;
2517 expressionS e;
b8891f8d
AJ
2518
2519 if (TOLOWER (*(*oper + 0)) == 'c'
2520 && TOLOWER (*(*oper + 1)) == 'r'
2521 && ISDIGIT (*(*oper + 2)))
2522 {
2523 /* The control registers are named crxx. */
afdcafe8
CQ
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;
b8891f8d
AJ
2530 }
2531 }
2532
2533 if (IS_CSKY_V2 (mach_flag))
2534 {
afdcafe8
CQ
2535
2536 s = *oper;
b8891f8d
AJ
2537 if (i != -1)
2538 {
2539 crx = i;
afdcafe8 2540 sel = group;
b8891f8d 2541 }
afdcafe8
CQ
2542 else if (TOLOWER (*(*oper + 0)) == 'c'
2543 && TOLOWER (*(*oper + 1)) == 'r')
b8891f8d 2544 {
afdcafe8
CQ
2545 s += 2;
2546 if (*s != '<')
b8891f8d 2547 {
afdcafe8 2548 SET_ERROR_STRING (ERROR_CREG_ILLEGAL, s);
5b7c81bd 2549 return false;
b8891f8d 2550 }
afdcafe8
CQ
2551 s++;
2552 crx = strtol(s, &s, 10);
2553 if (crx < 0 || crx > 31 || *s != ',')
2554 {
2555 SET_ERROR_STRING (ERROR_CREG_ILLEGAL, s);
5b7c81bd 2556 return false;
afdcafe8
CQ
2557 }
2558 s++;
2559 sel = strtol(s, &s, 10);
2560 if (sel < 0 || sel > 31 || *s != '>')
b8891f8d 2561 {
afdcafe8 2562 SET_ERROR_STRING (ERROR_CREG_ILLEGAL, s);
5b7c81bd 2563 return false;
afdcafe8
CQ
2564 }
2565 s++;
2566 }
2567 else
2568 {
0be2fe67 2569 crx = csky_get_control_regno (mach_flag, s, &s, &sel);
afdcafe8
CQ
2570 if (crx < 0)
2571 {
2572 SET_ERROR_STRING (ERROR_CREG_ILLEGAL, s);
5b7c81bd 2573 return false;
b8891f8d
AJ
2574 }
2575 }
2576 i = (sel << 5) | crx;
2577 }
afdcafe8
CQ
2578 else if (i == -1)
2579 {
0be2fe67 2580 i = csky_get_control_regno (mach_flag, s, &s, &sel);
afdcafe8
CQ
2581 if (i < 0)
2582 {
2583 SET_ERROR_STRING (ERROR_CREG_ILLEGAL, s);
5b7c81bd 2584 return false;
afdcafe8
CQ
2585 }
2586 }
2587 *oper = s;
b8891f8d 2588 csky_insn.val[csky_insn.idx++] = i;
5b7c81bd 2589 return true;
b8891f8d
AJ
2590}
2591
afdcafe8
CQ
2592static int
2593csky_get_reg_val (char *str, int *len)
2594{
2595 int regno = 0;
2596 char *s = str;
0be2fe67 2597 regno = csky_get_general_regno (mach_flag, str, &s);
afdcafe8
CQ
2598 *len = (s - str);
2599 return regno;
2600}
2601
5b7c81bd 2602static bool
b8891f8d
AJ
2603is_reg_sp_with_bracket (char **oper)
2604{
afdcafe8 2605 int reg;
b8891f8d
AJ
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 != '(')
5b7c81bd 2615 return false;
b8891f8d 2616 *oper += 1;
afdcafe8
CQ
2617 reg = csky_get_reg_val (*oper, &len);
2618 *oper += len;
2619 if (reg == sp_idx)
b8891f8d 2620 {
b8891f8d 2621 if (**oper != ')')
afdcafe8
CQ
2622 {
2623 SET_ERROR_STRING (ERROR_UNDEFINE,
2624 "Operand format is error. '(sp)' expected");
5b7c81bd 2625 return false;
afdcafe8 2626 }
b8891f8d
AJ
2627 *oper += 1;
2628 csky_insn.val[csky_insn.idx++] = sp_idx;
5b7c81bd 2629 return true;
b8891f8d 2630 }
afdcafe8
CQ
2631
2632 SET_ERROR_STRING (ERROR_UNDEFINE,
2633 "Operand format is error. '(sp)' expected");
5b7c81bd 2634 return false;
b8891f8d
AJ
2635}
2636
5b7c81bd 2637static bool
b8891f8d
AJ
2638is_reg_sp (char **oper)
2639{
afdcafe8 2640 char sp_name[16];
b8891f8d
AJ
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
afdcafe8
CQ
2648 /* ABI names: "sp". */
2649 if (memcmp (*oper, "sp", 2) == 0)
b8891f8d 2650 {
afdcafe8 2651 *oper += 2;
b8891f8d 2652 csky_insn.val[csky_insn.idx++] = sp_idx;
5b7c81bd 2653 return true;
b8891f8d 2654 }
b8891f8d 2655
afdcafe8
CQ
2656 len = sprintf (sp_name, "r%d", sp_idx);
2657 if (memcmp (*oper, sp_name, len) == 0)
b8891f8d 2658 {
afdcafe8
CQ
2659 *oper += len;
2660 csky_insn.val[csky_insn.idx++] = sp_idx;
5b7c81bd 2661 return true;
b8891f8d
AJ
2662 }
2663
5b7c81bd 2664 return false;
b8891f8d
AJ
2665}
2666
2667static int
2668csky_get_freg_val (char *str, int *len)
2669{
2670 int reg = 0;
2671 char *s = NULL;
d04aee0f
CQ
2672 if ((TOLOWER(str[0]) == 'v' || TOLOWER(str[0]) == 'f')
2673 && (TOLOWER(str[1]) == 'r'))
b8891f8d
AJ
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
5b7c81bd 2691static bool
b8891f8d
AJ
2692is_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 {
e2e82b11 2702 SET_ERROR_STRING (ERROR_REG_FORMAT,
b8891f8d 2703 "The first reg must not be r0/r15");
5b7c81bd 2704 return false;
b8891f8d
AJ
2705 }
2706
2707 if (**oper != '-')
2708 {
e2e82b11 2709 SET_ERROR_STRING (ERROR_REG_FORMAT,
b8891f8d 2710 "The operand format must be rx-ry");
5b7c81bd 2711 return false;
b8891f8d
AJ
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 {
e2e82b11 2720 SET_ERROR_STRING (ERROR_REG_FORMAT,
b8891f8d 2721 "The operand format must be r15 in C-SKY V1");
5b7c81bd 2722 return false;
b8891f8d
AJ
2723 }
2724 if (IS_CSKY_V2 (mach_flag))
2725 {
2726 if (reg2 < reg1)
2727 {
e2e82b11 2728 SET_ERROR_STRING (ERROR_REG_FORMAT,
b8891f8d 2729 "The operand format must be rx-ry (rx < ry)");
5b7c81bd 2730 return false;
b8891f8d
AJ
2731 }
2732 reg2 = reg2 - reg1;
2733 reg1 <<= 5;
2734 reg1 |= reg2;
2735 }
2736 csky_insn.val[csky_insn.idx++] = reg1;
5b7c81bd 2737 return true;
b8891f8d
AJ
2738}
2739
5b7c81bd 2740static bool
b8891f8d
AJ
2741is_freglist_legal (char **oper)
2742{
2743 int reg1 = -1;
2744 int reg2 = -1;
2745 int len = 0;
1feede9b 2746 int shift = 0;
b8891f8d
AJ
2747 reg1 = csky_get_freg_val (*oper, &len);
2748 *oper += len;
2749
2750 if (reg1 == -1)
2751 {
e2e82b11 2752 SET_ERROR_STRING (ERROR_REG_FORMAT,
b8891f8d 2753 "The fpu register format is not recognized.");
5b7c81bd 2754 return false;
b8891f8d
AJ
2755 }
2756
2757 if (**oper != '-')
2758 {
e2e82b11 2759 SET_ERROR_STRING (ERROR_REG_FORMAT,
b8891f8d 2760 "The operand format must be vrx-vry/frx-fry.");
5b7c81bd 2761 return false;
b8891f8d
AJ
2762 }
2763 *oper += 1;
2764
2765 reg2 = csky_get_freg_val (*oper, &len);
2766 *oper += len;
2767
2768 if (reg2 == -1)
2769 {
e2e82b11 2770 SET_ERROR_STRING (ERROR_REG_FORMAT,
b8891f8d 2771 "The fpu register format is not recognized.");
5b7c81bd 2772 return false;
b8891f8d
AJ
2773 }
2774 if (reg2 < reg1)
2775 {
e2e82b11 2776 SET_ERROR_STRING (ERROR_REG_FORMAT,
b8891f8d 2777 "The operand format must be rx-ry(rx < ry)");
5b7c81bd 2778 return false;
b8891f8d 2779 }
e2e82b11 2780
b8891f8d 2781 reg2 = reg2 - reg1;
1feede9b
CQ
2782 /* The fldm/fstm in CSKY_ISA_FLOAT_7E60 has 5 bits frz(reg1). */
2783 shift = 4;
d34049e8
ML
2784 if (startswith (csky_insn.opcode->mnemonic, "fstm")
2785 || startswith (csky_insn.opcode->mnemonic, "fldm"))
1feede9b
CQ
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");
5b7c81bd 2795 return false;
1feede9b
CQ
2796 }
2797 if ((mach_flag & CSKY_ARCH_MASK) == CSKY_ARCH_860)
2798 {
2799 shift = 5;
2800 }
2801 }
2802 else
e2e82b11 2803 {
1feede9b
CQ
2804 if (reg2 > (int)0x3) {
2805 SET_ERROR_STRING(ERROR_REG_FORMAT, (void *)"vry-vrx is over range");
5b7c81bd 2806 return false;
1feede9b 2807 }
e2e82b11 2808 }
1feede9b 2809 reg2 <<= shift;
b8891f8d
AJ
2810 reg1 |= reg2;
2811 csky_insn.val[csky_insn.idx++] = reg1;
5b7c81bd 2812 return true;
b8891f8d
AJ
2813}
2814
5b7c81bd 2815static bool
b8891f8d
AJ
2816is_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 {
e2e82b11 2829 SET_ERROR_STRING (ERROR_REG_LIST, NULL);
5b7c81bd 2830 return false;
b8891f8d
AJ
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 {
e2e82b11 2840 SET_ERROR_STRING (ERROR_REG_LIST, NULL);
5b7c81bd 2841 return false;
b8891f8d
AJ
2842 }
2843 *oper += len;
2844 if (reg1 > reg2)
2845 {
e2e82b11 2846 SET_ERROR_STRING (ERROR_REG_LIST, NULL);
5b7c81bd 2847 return false;
b8891f8d
AJ
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 {
e2e82b11 2862 SET_ERROR_STRING (ERROR_REG_LIST, NULL);
5b7c81bd 2863 return false;
b8891f8d
AJ
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 {
e2e82b11 2895 SET_ERROR_STRING (ERROR_REG_LIST, NULL);
5b7c81bd 2896 return false;
b8891f8d
AJ
2897 }
2898 csky_insn.val[csky_insn.idx++] = list;
5b7c81bd 2899 return true;
b8891f8d
AJ
2900}
2901
5b7c81bd 2902static bool
b8891f8d
AJ
2903is_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 {
e2e82b11 2911 SET_ERROR_STRING (ERROR_REG_FORMAT, "The register must be r0-r31.");
5b7c81bd 2912 return false;
b8891f8d
AJ
2913 }
2914
2915 *oper += len;
2916 if ((*oper)[0] != '<' || (*oper)[1] != '<')
2917 {
e2e82b11 2918 SET_ERROR_STRING (ERROR_UNDEFINE,
b8891f8d 2919 "Operand format error; should be (rx, ry << n)");
5b7c81bd 2920 return false;
b8891f8d
AJ
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 {
e2e82b11 2932 SET_ERROR_STRING (ERROR_IMM_OVERFLOW, NULL);
5b7c81bd 2933 return false;
b8891f8d
AJ
2934 }
2935 }
2936 else
2937 {
e2e82b11 2938 SET_ERROR_STRING (ERROR_EXP_CONSTANT, NULL);
5b7c81bd 2939 return false;
b8891f8d
AJ
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
5b7c81bd 2947 return true;
b8891f8d
AJ
2948}
2949
5b7c81bd 2950static bool
e2e82b11
CQ
2951is_imm_within_range (char **oper, int min, int max)
2952{
2953 expressionS e;
5b7c81bd 2954 bool ret = false;
e2e82b11
CQ
2955 char *new_oper = parse_exp (*oper, &e);
2956 if (e.X_op == O_constant)
2957 {
5b7c81bd 2958 ret = true;
e2e82b11
CQ
2959 *oper = new_oper;
2960 if (e.X_add_number < min || e.X_add_number > max)
2961 {
5b7c81bd 2962 ret = false;
e2e82b11
CQ
2963 SET_ERROR_STRING (ERROR_IMM_OVERFLOW, NULL);
2964 }
1feede9b
CQ
2965 if (!e.X_unsigned)
2966 e.X_add_number |= 0x80000000;
e2e82b11
CQ
2967 csky_insn.val[csky_insn.idx++] = e.X_add_number;
2968 }
e2e82b11
CQ
2969 else
2970 SET_ERROR_STRING(ERROR_IMM_ILLEGAL, NULL);
2971
2972 return ret;
2973}
2974
5b7c81bd 2975static bool
e2e82b11 2976is_imm_within_range_ext (char **oper, int min, int max, int ext)
b8891f8d
AJ
2977{
2978 expressionS e;
5b7c81bd 2979 bool ret = false;
b8891f8d
AJ
2980 char *new_oper = parse_exp (*oper, &e);
2981 if (e.X_op == O_constant)
2982 {
5b7c81bd 2983 ret = true;
b8891f8d
AJ
2984 *oper = new_oper;
2985 if ((int)e.X_add_number != ext
2986 && (e.X_add_number < min || e.X_add_number > max))
2987 {
5b7c81bd 2988 ret = false;
e2e82b11 2989 SET_ERROR_STRING (ERROR_IMM_OVERFLOW, NULL);
b8891f8d
AJ
2990 }
2991 csky_insn.val[csky_insn.idx++] = e.X_add_number;
2992 }
2993
e2e82b11
CQ
2994 else
2995 SET_ERROR_STRING(ERROR_IMM_ILLEGAL, NULL);
2996
b8891f8d
AJ
2997 return ret;
2998}
2999
5b7c81bd 3000static bool
e2e82b11 3001is_oimm_within_range (char **oper, int min, int max)
b8891f8d
AJ
3002{
3003 expressionS e;
5b7c81bd 3004 bool ret = false;
b8891f8d
AJ
3005 char *new_oper = parse_exp (*oper, &e);
3006 if (e.X_op == O_constant)
3007 {
5b7c81bd 3008 ret = true;
b8891f8d
AJ
3009 *oper = new_oper;
3010 if (e.X_add_number < min || e.X_add_number > max)
3011 {
5b7c81bd 3012 ret = false;
e2e82b11 3013 SET_ERROR_STRING (ERROR_IMM_OVERFLOW, NULL);
b8891f8d
AJ
3014 }
3015 csky_insn.val[csky_insn.idx++] = e.X_add_number - 1;
3016 }
afdcafe8
CQ
3017 else
3018 SET_ERROR_STRING (ERROR_IMM_ILLEGAL, NULL);
b8891f8d
AJ
3019
3020 return ret;
3021}
3022
5b7c81bd 3023static bool
b8891f8d
AJ
3024is_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;
5b7c81bd 3045 return true;
b8891f8d
AJ
3046 }
3047 i++;
3048 }
e2e82b11 3049 SET_ERROR_STRING (ERROR_OPCODE_PSRBIT, NULL);
5b7c81bd 3050 return false;
b8891f8d
AJ
3051}
3052
5b7c81bd 3053static bool
b8891f8d
AJ
3054parse_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
5b7c81bd 3071 return false;
b8891f8d
AJ
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. */
5b7c81bd 3080 return false;
b8891f8d
AJ
3081 }
3082 idx = e.X_add_number;
3083 }
3084
3085 csky_insn.val[csky_insn.idx++] = idx;
3086
5b7c81bd 3087 return true;
b8891f8d
AJ
3088}
3089
5b7c81bd 3090static bool
b8891f8d
AJ
3091parse_type_cpreg (char** oper)
3092{
afdcafe8 3093 expressionS e;
b8891f8d 3094
afdcafe8 3095 if (strncasecmp (*oper, "cpr", 3) != 0)
b8891f8d 3096 {
afdcafe8 3097 SET_ERROR_STRING(ERROR_CPREG_ILLEGAL, *oper);
5b7c81bd 3098 return false;
b8891f8d 3099 }
afdcafe8
CQ
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);
5b7c81bd 3107 return false;
afdcafe8
CQ
3108 }
3109
3110 csky_insn.val[csky_insn.idx++] = e.X_add_number;
3111
5b7c81bd 3112 return true;
b8891f8d
AJ
3113}
3114
5b7c81bd 3115static bool
b8891f8d
AJ
3116parse_type_cpcreg (char** oper)
3117{
afdcafe8
CQ
3118 expressionS e;
3119
3120 if (strncasecmp (*oper, "cpcr", 4) != 0)
b8891f8d 3121 {
afdcafe8 3122 SET_ERROR_STRING(ERROR_CPREG_ILLEGAL, *oper);
5b7c81bd 3123 return false;
b8891f8d 3124 }
afdcafe8
CQ
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);
5b7c81bd 3132 return false;
afdcafe8
CQ
3133 }
3134
3135 csky_insn.val[csky_insn.idx++] = e.X_add_number;
3136
5b7c81bd 3137 return true;
b8891f8d
AJ
3138}
3139
5b7c81bd 3140static bool
b8891f8d
AJ
3141parse_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 {
e2e82b11 3148 SET_ERROR_STRING (ERROR_GREG_ILLEGAL, NULL);
5b7c81bd 3149 return false;
b8891f8d
AJ
3150 }
3151 *oper += len;
3152 csky_insn.val[csky_insn.idx++] = i;
3153
5b7c81bd 3154 return true;
b8891f8d
AJ
3155}
3156
5b7c81bd 3157static bool
b8891f8d
AJ
3158parse_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 {
e2e82b11
CQ
3165 SET_ERROR_STRING (ERROR_REG_FORMAT,
3166 (void *)"The fpu register format is not recognized.");
5b7c81bd 3167 return false;
b8891f8d
AJ
3168 }
3169 *oper += len;
3170 csky_insn.opcode_end = *oper;
3171 if (even && reg & 0x1)
3172 {
e2e82b11 3173 SET_ERROR_STRING (ERROR_EXP_EVEN_FREG, NULL);
5b7c81bd 3174 return false;
b8891f8d 3175 }
e61ef79e
CQ
3176
3177 if (IS_CSKY_V2 (mach_flag)
1feede9b
CQ
3178 && ((csky_insn.opcode->isa_flag32 & CSKY_ISA_VDSP_2)
3179 || !(csky_insn.opcode->isa_flag32 & CSKY_ISA_FLOAT_7E60))
e61ef79e
CQ
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 }
5b7c81bd 3190 return false;
e61ef79e
CQ
3191 }
3192 /* TODO: recognize vreg or freg. */
3193 if (reg > 31)
3194 {
3195 SET_ERROR_INTEGER (ERROR_VREG_OVER_RANGE, reg);
3196 }
b8891f8d 3197 csky_insn.val[csky_insn.idx++] = reg;
5b7c81bd 3198 return true;
b8891f8d
AJ
3199}
3200
5b7c81bd 3201static bool
b8891f8d
AJ
3202parse_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;
5b7c81bd 3222 return true;
b8891f8d
AJ
3223 }
3224
3225 expressionS e;
3226 *oper = parse_exp (*oper, &e);
3227 if (e.X_op != O_constant)
e2e82b11 3228 {
b8891f8d 3229 /* Not a constant. */
e2e82b11 3230 SET_ERROR_STRING(ERROR_UNDEFINE, (void *)"Operand format is error. eg. \"ld rz, (rx, n)\"");
5b7c81bd 3231 return false;
e2e82b11 3232 }
b8891f8d
AJ
3233 else if (e.X_add_number < 0 || e.X_add_number >= max)
3234 {
3235 /* Out of range. */
e2e82b11 3236 SET_ERROR_STRING(ERROR_IMM_OVERFLOW, NULL);
5b7c81bd 3237 return false;
b8891f8d
AJ
3238 }
3239 if ((e.X_add_number % (1 << shift)) != 0)
3240 {
3241 /* Not aligned. */
e2e82b11 3242 SET_ERROR_INTEGER (ERROR_OFFSET_UNALIGNED, ((unsigned long)1 << shift));
5b7c81bd 3243 return false;
b8891f8d
AJ
3244 }
3245
3246 csky_insn.val[csky_insn.idx++] = e.X_add_number >> shift;
3247
5b7c81bd 3248 return true;
b8891f8d
AJ
3249
3250}
3251
3252static unsigned int
3253csky_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
5b7c81bd 3292static bool
b8891f8d
AJ
3293parse_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'. */
5b7c81bd 3299 unsigned int has_suffix = false;
b8891f8d
AJ
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)
63b4cc53 3317 && *opcode_end == '.' && !has_suffix)
b8891f8d 3318 {
5b7c81bd 3319 has_suffix = true;
b8891f8d
AJ
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? */
63b4cc53 3337 if (!has_suffix)
b8891f8d
AJ
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. */
63b4cc53 3353 if (has_suffix)
b8891f8d
AJ
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. */
629310ab 3367 csky_insn.macro = (struct csky_macro_info *) str_hash_find (csky_macros_hash,
fe0e921f 3368 macro_name);
629310ab 3369 csky_insn.opcode = (struct csky_opcode *) str_hash_find (csky_opcodes_hash,
fe0e921f 3370 name);
b8891f8d
AJ
3371
3372 if (csky_insn.macro == NULL && csky_insn.opcode == NULL)
5b7c81bd
AM
3373 return false;
3374 return true;
b8891f8d
AJ
3375}
3376
3377/* Main dispatch routine to parse operand OPRND for opcode OP from string
3378 *OPER. */
3379
5b7c81bd 3380static bool
b8891f8d
AJ
3381get_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 {
e2e82b11 3415 SET_ERROR_STRING ((oprnd->type == OPRND_TYPE_BRACKET
b8891f8d
AJ
3416 ? ERROR_MISSING_LBRACKET
3417 : ERROR_MISSING_LANGLE_BRACKETS), NULL);
5b7c81bd 3418 return false;
b8891f8d
AJ
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 {
e2e82b11 3436 SET_ERROR_STRING ((oprnd->type == OPRND_TYPE_BRACKET
b8891f8d
AJ
3437 ? ERROR_MISSING_RBRACKET
3438 : ERROR_MISSING_RANGLE_BRACKETS), NULL);
5b7c81bd 3439 return false;
b8891f8d
AJ
3440 }
3441
63b4cc53 3442 if (!get_operand_value (op, oper, &soprnd->subs[0]))
b8891f8d
AJ
3443 {
3444 *s = rc;
5b7c81bd 3445 return false;
b8891f8d
AJ
3446 }
3447 if (**oper == ',')
3448 *oper += 1;
e2e82b11
CQ
3449 else if (**oper != '\0')
3450 {
3451 SET_ERROR_STRING (ERROR_MISSING_COMMA, NULL);
5b7c81bd 3452 return false;
e2e82b11
CQ
3453 }
3454
63b4cc53 3455 if (!get_operand_value (op, oper, &soprnd->subs[1]))
b8891f8d
AJ
3456 {
3457 *s = rc;
5b7c81bd 3458 return false;
b8891f8d
AJ
3459 }
3460
3461 *s = rc;
3462 *oper += 1;
5b7c81bd 3463 return true;
b8891f8d
AJ
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 {
e2e82b11 3497 SET_ERROR_STRING (ERROR_GREG_ILLEGAL, NULL);
5b7c81bd 3498 return false;
b8891f8d
AJ
3499 }
3500 else if ((oprnd->type == OPRND_TYPE_GREG0_7 && reg > 7)
3501 || (oprnd->type == OPRND_TYPE_GREG0_15 && reg > 15))
3502 {
e2e82b11 3503 SET_ERROR_INTEGER (ERROR_REG_OVER_RANGE, reg);
5b7c81bd 3504 return false;
b8891f8d
AJ
3505 }
3506 *oper += len;
3507 csky_insn.val[csky_insn.idx++] = reg;
5b7c81bd 3508 return true;
b8891f8d
AJ
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 {
e2e82b11 3520 SET_ERROR_STRING (ERROR_REG_OVER_RANGE, reg);
5b7c81bd 3521 return false;
b8891f8d
AJ
3522 }
3523 csky_insn.val[csky_insn.idx++] = reg;
3524 *oper += len;
5b7c81bd 3525 return true;;
b8891f8d
AJ
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))
5b7c81bd 3535 return false;
b8891f8d
AJ
3536
3537 csky_insn.val[csky_insn.idx++] = reg;
3538 *oper += len;
3539
3540 if (**oper == ')')
3541 *oper += 1;
5b7c81bd 3542 return true;;
b8891f8d
AJ
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;
5b7c81bd 3549 return true;
b8891f8d 3550 }
e2e82b11 3551 SET_ERROR_STRING (ERROR_OPCODE_ILLEGAL, NULL);
5b7c81bd 3552 return false;
b8891f8d
AJ
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:
e2e82b11 3558 return is_imm_within_range (oper, 0, 1);
b8891f8d 3559 case OPRND_TYPE_IMM2b:
e2e82b11 3560 return is_imm_within_range (oper, 0, 3);
b8891f8d
AJ
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 {
e2e82b11 3566 SET_ERROR_STRING (ERROR_OPCODE_ILLEGAL, NULL);
5b7c81bd 3567 return false;
b8891f8d
AJ
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 {
e2e82b11 3575 SET_ERROR_STRING (ERROR_JMPIX_OVER_RANGE, NULL);
5b7c81bd 3576 return false;
b8891f8d
AJ
3577 }
3578 csky_insn.val[csky_insn.idx++]
3579 = (csky_insn.e1.X_add_number >> 3) - 2;
3580 }
5b7c81bd 3581 return true;
b8891f8d 3582 case OPRND_TYPE_IMM4b:
e2e82b11 3583 return is_imm_within_range (oper, 0, 15);
b8891f8d 3584 case OPRND_TYPE_IMM5b:
e2e82b11 3585 return is_imm_within_range (oper, 0, 31);
b8891f8d
AJ
3586 /* This type for "bgeni" in csky v1 ISA. */
3587 case OPRND_TYPE_IMM5b_7_31:
e2e82b11 3588 if (is_imm_within_range (oper, 0, 31))
b8891f8d
AJ
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 *)
629310ab 3596 str_hash_find (csky_opcodes_hash, name);
b8891f8d
AJ
3597 csky_insn.val[csky_insn.idx - 1] = 1 << val;
3598 }
5b7c81bd 3599 return true;
b8891f8d
AJ
3600 }
3601 else
5b7c81bd 3602 return false;
b8891f8d
AJ
3603
3604 case OPRND_TYPE_IMM5b_1_31:
e2e82b11 3605 return is_imm_within_range (oper, 1, 31);
b8891f8d 3606 case OPRND_TYPE_IMM5b_POWER:
e2e82b11 3607 if (is_imm_within_range_ext (oper, 1, (1u << 31) - 1, 1u << 31))
b8891f8d
AJ
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;
63b4cc53 3613 return log != -1;
b8891f8d
AJ
3614 }
3615 else
5b7c81bd 3616 return false;
b8891f8d
AJ
3617
3618 /* This type for "mgeni" in csky v1 ISA. */
3619 case OPRND_TYPE_IMM5b_7_31_POWER:
e2e82b11 3620 if (is_imm_within_range_ext (oper, 1, (1u << 31) - 1, 1u << 31))
b8891f8d
AJ
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 *)
629310ab 3630 str_hash_find (csky_opcodes_hash, name);
b8891f8d
AJ
3631 as_warn (_("translating mgeni to movi"));
3632 }
3633 else
3634 csky_insn.val[csky_insn.idx - 1] = log;
63b4cc53 3635 return log != -1;
b8891f8d
AJ
3636 }
3637 else
5b7c81bd 3638 return false;
b8891f8d 3639
afdcafe8
CQ
3640 case OPRND_TYPE_IMM5b_LS:
3641 return is_imm_within_range (oper,
3642 0,
3643 csky_insn.val[csky_insn.idx - 1]);
b8891f8d
AJ
3644 case OPRND_TYPE_IMM5b_RORI:
3645 {
3646 unsigned max_shift = IS_CSKY_V1 (mach_flag) ? 31 : 32;
3647
e2e82b11 3648 if (is_imm_within_range (oper, 1, max_shift))
b8891f8d
AJ
3649 {
3650 int i = csky_insn.idx - 1;
3651 csky_insn.val[i] = 32 - csky_insn.val[i];
5b7c81bd 3652 return true;
b8891f8d
AJ
3653 }
3654 else
5b7c81bd 3655 return false;
b8891f8d
AJ
3656 }
3657
3658 case OPRND_TYPE_IMM5b_BMASKI:
3659 /* For csky v1 bmask inst. */
3660
e2e82b11 3661 if (!is_imm_within_range_ext (oper, 8, 31, 0))
b8891f8d
AJ
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 *)
629310ab 3668 str_hash_find (csky_opcodes_hash, op_movi);
b8891f8d 3669 if (csky_insn.opcode == NULL)
5b7c81bd 3670 return false;
b8891f8d 3671 csky_insn.val[csky_insn.idx - 1] = (1 << mask_val) - 1;
5b7c81bd 3672 return true;
b8891f8d
AJ
3673 }
3674 }
5b7c81bd 3675 return true;
b8891f8d 3676
039dac29
CQ
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;
5b7c81bd 3685 return true;
039dac29 3686 }
5b7c81bd 3687 return false;
b8891f8d
AJ
3688 case OPRND_TYPE_IMM8b_BMASKI:
3689 /* For csky v2 bmask, which will transfer to 16bits movi. */
e2e82b11 3690 if (is_imm_within_range (oper, 1, 8))
b8891f8d
AJ
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;
5b7c81bd 3694 return true;
b8891f8d 3695 }
5b7c81bd 3696 return false;
b8891f8d 3697 case OPRND_TYPE_OIMM4b:
e2e82b11 3698 return is_oimm_within_range (oper, 1, 16);
b8891f8d 3699 case OPRND_TYPE_OIMM5b:
e2e82b11 3700 return is_oimm_within_range (oper, 1, 32);
b8891f8d 3701 case OPRND_TYPE_OIMM5b_IDLY:
e2e82b11 3702 if (is_imm_within_range (oper, 0, 32))
b8891f8d
AJ
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;
5b7c81bd 3713 return true;
b8891f8d
AJ
3714 }
3715 else
5b7c81bd 3716 return false;
b8891f8d
AJ
3717
3718 /* For csky v2 bmask inst. */
3719 case OPRND_TYPE_OIMM5b_BMASKI:
e2e82b11 3720 if (!is_oimm_within_range (oper, 17, 32))
b8891f8d
AJ
3721 {
3722 int mask_val = csky_insn.val[csky_insn.idx - 1];
3723 if (mask_val + 1 == 0)
5b7c81bd 3724 return true;
b8891f8d
AJ
3725 if (mask_val > 0 && mask_val < 16)
3726 {
3727 const char *op_movi = "movi";
3728 csky_insn.opcode = (struct csky_opcode *)
629310ab 3729 str_hash_find (csky_opcodes_hash, op_movi);
b8891f8d 3730 if (csky_insn.opcode == NULL)
5b7c81bd 3731 return false;
b8891f8d 3732 csky_insn.val[csky_insn.idx - 1] = (1 << (mask_val + 1)) - 1;
5b7c81bd 3733 return true;
b8891f8d
AJ
3734 }
3735 }
5b7c81bd 3736 return true;
b8891f8d 3737 case OPRND_TYPE_IMM7b:
e2e82b11 3738 return is_imm_within_range (oper, 0, 127);
b8891f8d 3739 case OPRND_TYPE_IMM8b:
e2e82b11 3740 return is_imm_within_range (oper, 0, 255);
1feede9b
CQ
3741 case OPRND_TYPE_IMM9b:
3742 return is_imm_within_range (oper, -256, 255);
b8891f8d 3743 case OPRND_TYPE_IMM12b:
e2e82b11 3744 return is_imm_within_range (oper, 0, 4095);
b8891f8d 3745 case OPRND_TYPE_IMM15b:
e2e82b11 3746 return is_imm_within_range (oper, 0, 0xfffff);
b8891f8d 3747 case OPRND_TYPE_IMM16b:
e2e82b11 3748 return is_imm_within_range (oper, 0, 65535);
b8891f8d 3749 case OPRND_TYPE_OIMM16b:
e2e82b11 3750 return is_oimm_within_range (oper, 1, 65536);
b8891f8d
AJ
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;
5b7c81bd 3759 return true;
b8891f8d 3760 }
5b7c81bd 3761 return false;
b8891f8d
AJ
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);
5b7c81bd 3787 return true;
b8891f8d
AJ
3788 }
3789 case OPRND_TYPE_PSR_BITS_LIST:
3790 {
5b7c81bd 3791 int ret = true;
b8891f8d 3792 if (csky_insn.number == 0)
5b7c81bd 3793 ret = false;
b8891f8d
AJ
3794 else
3795 {
3796 csky_insn.val[csky_insn.idx] = 0;
63b4cc53 3797 if (is_psr_bit (oper))
b8891f8d
AJ
3798 while (**oper == ',')
3799 {
3800 *oper += 1;
63b4cc53 3801 if (!is_psr_bit (oper))
b8891f8d 3802 {
5b7c81bd 3803 ret = false;
b8891f8d
AJ
3804 break;
3805 }
3806 }
3807 else
5b7c81bd 3808 ret = false;
63b4cc53 3809 if (ret && IS_CSKY_V1 (mach_flag)
b8891f8d 3810 && csky_insn.val[csky_insn.idx] > 8)
5b7c81bd 3811 ret = false;
b8891f8d
AJ
3812 }
3813 if (!ret)
e2e82b11 3814 SET_ERROR_STRING (ERROR_OPERANDS_ILLEGAL, csky_insn.opcode_end);
b8891f8d
AJ
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;
5b7c81bd 3834 return true;
b8891f8d 3835 }
5b7c81bd 3836 return false;
b8891f8d
AJ
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 {
e2e82b11 3854 SET_ERROR_STRING (ERROR_MISSING_LBRACKET, NULL);
5b7c81bd 3855 return false;
b8891f8d
AJ
3856 }
3857 *oper += 1;
3858 reg = csky_get_reg_val (*oper, &len);
3859 if (reg == -1)
3860 {
e2e82b11 3861 SET_ERROR_STRING (ERROR_EXP_GREG, NULL);
5b7c81bd 3862 return false;
b8891f8d
AJ
3863 }
3864 *oper += len;
3865 if (**oper != ')')
3866 {
e2e82b11 3867 SET_ERROR_STRING (ERROR_MISSING_RBRACKET, NULL);
5b7c81bd 3868 return false;
b8891f8d
AJ
3869 }
3870 *oper += 1;
3871 csky_insn.val[csky_insn.idx++] = reg;
5b7c81bd 3872 return true;
b8891f8d
AJ
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;
5b7c81bd 3883 return true;
b8891f8d
AJ
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);
5b7c81bd 3892 return true;
b8891f8d
AJ
3893 case OPRND_TYPE_FCONSTANT:
3894 *oper = parse_rtf (*oper, 0, &csky_insn.e1);
5b7c81bd 3895 return true;
b8891f8d
AJ
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)
5b7c81bd 3907 return false;
b8891f8d
AJ
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);
5b7c81bd 3916 return false;
b8891f8d
AJ
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));
5b7c81bd 3924 return true;
b8891f8d 3925 }
1feede9b
CQ
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)
5b7c81bd 3937 return false;
b8891f8d 3938
1feede9b
CQ
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);
5b7c81bd 3946 return true;
1feede9b
CQ
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);
5b7c81bd 3955 return true;
1feede9b 3956 }
b8891f8d
AJ
3957 /* For grs v2. */
3958 case OPRND_TYPE_IMM_OFF18b:
3959 *oper = parse_exp (*oper, &csky_insn.e1);
5b7c81bd 3960 return true;
b8891f8d
AJ
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;
5b7c81bd 3967 return true;
b8891f8d
AJ
3968 }
3969 else
5b7c81bd 3970 return false;
b8891f8d
AJ
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;
5b7c81bd 3981 return true;
b8891f8d
AJ
3982 }
3983 else
5b7c81bd 3984 return false;
b8891f8d
AJ
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 {
e2e82b11 3993 SET_ERROR_STRING (ERROR_REG_FORMAT,
b8891f8d 3994 "The first operand must be register r1.");
5b7c81bd 3995 return false;
b8891f8d
AJ
3996 }
3997 if (reg != 1)
5b7c81bd 3998 mov_r1_after = true;
b8891f8d
AJ
3999 *oper += len;
4000 csky_insn.opcode_end = *oper;
4001 csky_insn.val[csky_insn.idx++] = reg;
5b7c81bd 4002 return true;
b8891f8d
AJ
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 {
e2e82b11 4011 SET_ERROR_STRING (ERROR_REG_FORMAT,
b8891f8d 4012 "The second operand must be register r1.");
5b7c81bd 4013 return false;
b8891f8d
AJ
4014 }
4015 if (reg != 1)
4016 {
4017 unsigned int mov_insn = CSKYV1_INST_MOV_R1_RX;
4018 mov_insn |= reg << 4;
5b7c81bd 4019 mov_r1_before = true;
b8891f8d
AJ
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;
5b7c81bd 4027 return true;
b8891f8d
AJ
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 {
e2e82b11 4036 SET_ERROR_STRING (ERROR_GREG_ILLEGAL, NULL);
5b7c81bd 4037 return false;
b8891f8d
AJ
4038 }
4039 if (reg != csky_insn.val[0])
4040 {
e2e82b11 4041 SET_ERROR_STRING (ERROR_REG_FORMAT,
b8891f8d 4042 "The second register must be the same as the first.");
5b7c81bd 4043 return false;
b8891f8d
AJ
4044 }
4045 *oper += len;
4046 csky_insn.opcode_end = *oper;
4047 csky_insn.val[csky_insn.idx++] = reg;
5b7c81bd 4048 return true;
b8891f8d
AJ
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 {
e2e82b11 4059 SET_ERROR_STRING (ERROR_GREG_ILLEGAL, NULL);
5b7c81bd 4060 return false;
b8891f8d
AJ
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
5b7c81bd 4068 return false;
b8891f8d 4069 if (reg < min || reg > max)
5b7c81bd 4070 return false;
b8891f8d
AJ
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
5b7c81bd 4082 return false;
b8891f8d
AJ
4083 }
4084 *oper += len;
4085 csky_insn.opcode_end = *oper;
5b7c81bd 4086 return true;
b8891f8d
AJ
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)
e2e82b11 4115 SET_ERROR_STRING (ERROR_REG_FORMAT,
b8891f8d
AJ
4116 "The register must be r0-r31");
4117 else
e2e82b11 4118 SET_ERROR_STRING (ERROR_REG_FORMAT,
b8891f8d 4119 "The register must be r0-r15");
5b7c81bd 4120 return false;
b8891f8d
AJ
4121 }
4122 if (reg > max_reg)
4123 {
e2e82b11 4124 SET_ERROR_STRING (ERROR_REG_OVER_RANGE, reg);
5b7c81bd 4125 return false;
b8891f8d
AJ
4126 }
4127 reg |= reg << shift_num;
4128 *oper += len;
4129 csky_insn.opcode_end = *oper;
4130 csky_insn.val[csky_insn.idx++] = reg;
5b7c81bd 4131 return true;
b8891f8d
AJ
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)
5b7c81bd 4139 return false;
b8891f8d 4140 csky_insn.val[csky_insn.idx++] = 1;
5b7c81bd 4141 return true;
b8891f8d 4142 }
5b7c81bd 4143 return false;
b8891f8d
AJ
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)
5b7c81bd 4148 return false;
b8891f8d
AJ
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;
5b7c81bd 4155 return true;
b8891f8d
AJ
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)
5b7c81bd 4160 return false;
b8891f8d
AJ
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;
5b7c81bd 4178 return true;
b8891f8d
AJ
4179 case OPRND_TYPE_JCOMPZ:
4180 *oper = parse_exp (*oper, &csky_insn.e1);
4181 if (csky_insn.e1.X_op == O_constant)
5b7c81bd 4182 return false;
b8891f8d
AJ
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;
5b7c81bd 4190 return true;
b8891f8d
AJ
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;
5b7c81bd 4200 return true;
b8891f8d
AJ
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;
5b7c81bd 4210 return true;
b8891f8d
AJ
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;
5b7c81bd 4219 return true;
b8891f8d
AJ
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 {
e2e82b11 4233 SET_ERROR_STRING (ERROR_IMM_OVERFLOW, NULL);
5b7c81bd 4234 return false;
b8891f8d
AJ
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 {
e2e82b11 4241 SET_ERROR_STRING (ERROR_IMM_OVERFLOW, NULL);
5b7c81bd 4242 return false;
b8891f8d
AJ
4243 }
4244 csky_insn.val[csky_insn.idx - 2] -= e.X_add_number;
4245 }
5b7c81bd 4246 return true;
b8891f8d 4247 }
5b7c81bd 4248 return false;
b8891f8d
AJ
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:
039dac29 4255 case OPRND_TYPE_VREG_WITH_INDEX:
b8891f8d
AJ
4256 if (parse_type_freg (oper, 0))
4257 {
4258 if (**oper == '[')
4259 {
4260 (*oper)++;
e2e82b11 4261 if (is_imm_within_range (oper, 0, 0xf))
b8891f8d
AJ
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;
5b7c81bd 4269 return true;
b8891f8d
AJ
4270 }
4271 else
e2e82b11 4272 SET_ERROR_STRING (ERROR_MISSING_RSQUARE_BRACKETS, NULL);
b8891f8d
AJ
4273 }
4274 }
4275 else
e2e82b11 4276 SET_ERROR_STRING (ERROR_MISSING_LSQUARE_BRACKETS, NULL);
b8891f8d 4277 }
5b7c81bd 4278 return false;
b8891f8d
AJ
4279
4280 default:
4281 break;
4282 /* error code. */
4283 }
5b7c81bd 4284 return false;
b8891f8d
AJ
4285}
4286
4287/* Subroutine of parse_operands. */
4288
5b7c81bd 4289static bool
b8891f8d
AJ
4290parse_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 {
5b7c81bd 4299 flag_pass = true;
b8891f8d
AJ
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. */
e2e82b11 4307 SET_ERROR_INTEGER (ERROR_OPERANDS_NUMBER, op[i].operand_num);
5b7c81bd 4308 flag_pass = false;
b8891f8d
AJ
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]);
63b4cc53 4318 if (!flag_pass)
b8891f8d
AJ
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 {
e2e82b11 4329 SET_ERROR_STRING (ERROR_MISSING_COMMA, NULL);
5b7c81bd 4330 flag_pass = false;
b8891f8d
AJ
4331 break;
4332 }
4333 }
4334 else if (!is_end_of_line[(unsigned char) *oper])
4335 {
e2e82b11 4336 SET_ERROR_STRING (ERROR_BAD_END, NULL);
5b7c81bd 4337 flag_pass = false;
b8891f8d
AJ
4338 break;
4339 }
4340 else
4341 break;
4342 }
4343 /* Parse operands in one table end. */
4344
63b4cc53 4345 if (flag_pass)
b8891f8d
AJ
4346 {
4347 /* Parse operands success, set opcode_idx. */
4348 csky_insn.opcode_idx = i;
5b7c81bd 4349 return true;
b8891f8d
AJ
4350 }
4351 else
4352 error_state.opnum = j + 1;
4353 }
4354 /* Parse operands in ALL tables end. */
5b7c81bd 4355 return false;
b8891f8d
AJ
4356}
4357
4358/* Parse the operands according to operand type. */
4359
5b7c81bd 4360static bool
b8891f8d
AJ
4361parse_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 {
63b4cc53 4369 if (parse_operands_op (oper, csky_insn.opcode->op16))
b8891f8d
AJ
4370 {
4371 csky_insn.isize = 2;
5b7c81bd 4372 return true;
b8891f8d 4373 }
5b7c81bd 4374 return false;
b8891f8d
AJ
4375 }
4376 else if (csky_insn.flag_force == INSN_OPCODE32F
4377 && (csky_insn.opcode->isa_flag32 & isa_flag) != 0)
4378 {
63b4cc53 4379 if (parse_operands_op (oper, csky_insn.opcode->op32))
b8891f8d
AJ
4380 {
4381 csky_insn.isize = 4;
5b7c81bd 4382 return true;
b8891f8d 4383 }
5b7c81bd 4384 return false;
b8891f8d
AJ
4385 }
4386 else
4387 {
4388 if ((csky_insn.opcode->isa_flag16 & isa_flag) != 0
63b4cc53 4389 && parse_operands_op (oper, csky_insn.opcode->op16))
b8891f8d
AJ
4390 {
4391 csky_insn.isize = 2;
5b7c81bd 4392 return true;
b8891f8d
AJ
4393 }
4394 if ((csky_insn.opcode->isa_flag32 & isa_flag) != 0
63b4cc53 4395 && parse_operands_op (oper, csky_insn.opcode->op32))
b8891f8d
AJ
4396 {
4397 csky_insn.isize = 4;
5b7c81bd 4398 return true;
b8891f8d 4399 }
5b7c81bd 4400 return false;
b8891f8d
AJ
4401 }
4402}
4403
5b7c81bd 4404static bool
b8891f8d
AJ
4405csky_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 }
5b7c81bd 4466 return true;
b8891f8d
AJ
4467}
4468
4469/* Return the bits of VAL shifted according to MASK. The bits of MASK
4470 need not be contiguous. */
4471
4472static int
4473generate_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
4492static int
4493generate_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
5b7c81bd 4514static bool
b8891f8d
AJ
4515csky_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
4540void
4541md_assemble (char *str)
4542{
5b7c81bd 4543 bool must_check_literals = true;
b8891f8d
AJ
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;
5b7c81bd
AM
4553 mov_r1_before = false;
4554 mov_r1_after = false;
b8891f8d
AJ
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. */
63b4cc53 4562 if (!parse_opcode (str))
b8891f8d
AJ
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)
e2e82b11 4577 SET_ERROR_STRING (ERROR_OPERANDS_NUMBER, csky_insn.macro->oprnd_num);
b8891f8d
AJ
4578 }
4579
4580 if (csky_insn.opcode == NULL)
4581 {
e2e82b11 4582 SET_ERROR_STRING (ERROR_OPCODE_ILLEGAL, NULL);
b8891f8d
AJ
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. */
63b4cc53 4589 if (!parse_operands (csky_insn.opcode_end))
b8891f8d
AJ
4590 {
4591 csky_show_error (error_state.err_num, error_state.opnum,
4592 (void *)error_state.arg1, (void *)error_state.arg1);
4593 return;
4594 }
afdcafe8 4595 error_state.err_num = ERROR_NONE;
b8891f8d
AJ
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. */
63b4cc53 4611 if (mov_r1_after)
b8891f8d
AJ
4612 {
4613 unsigned int mov_insn = CSKYV1_INST_MOV_RX_R1;
4614 mov_insn |= csky_insn.val[0];
5b7c81bd 4615 mov_r1_before = true;
b8891f8d
AJ
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 }
63b4cc53 4621 if (mov_r1_before)
b8891f8d
AJ
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
d285ba8d 4633 csky_insn.last_isize = csky_insn.isize;
b8891f8d
AJ
4634 insn_reloc = BFD_RELOC_NONE;
4635}
4636
4637/* Attempt to handle option with value C, returning non-zero on success. */
4638
4639int
4640md_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;
a2061b9f
CQ
4652 case OPTION_FLOAT_ABI:
4653 parse_float_abi (arg);
4654 break;
b8891f8d
AJ
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
4686void
4687md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT asec, fragS *fragp)
4688{
4689 offsetT disp;
a39d29cd 4690 char *buf = fragp->fr_fix + &fragp->fr_literal[0];
b8891f8d
AJ
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 }
f6bd0b76
AM
4921 buf[22] = 0; /* initialise. */
4922 buf[23] = 0;
b8891f8d
AJ
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
5210valueT
5211md_section_align (segT segment ATTRIBUTE_UNUSED,
5212 valueT size)
5213{
5214 return size;
5215}
5216
5217/* MD interface: Symbol and relocation handling. */
5218
5219void 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
5227long
5228md_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
5244void
5245csky_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
5297int
5298csky_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
5b7c81bd 5322bool
b8891f8d
AJ
5323csky_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
5362void
5363md_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));
531c73a3 5396 *valP = fixP->fx_offset;
b8891f8d
AJ
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 {
fe75f42e 5417 case BFD_RELOC_32_PCREL:
b8891f8d 5418 case BFD_RELOC_CKCORE_PCREL32:
fe75f42e 5419 fixP->fx_r_type = BFD_RELOC_CKCORE_PCREL32;
b8891f8d
AJ
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));
531c73a3 5458 *valP = fixP->fx_offset;
b8891f8d
AJ
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
5393ca68
NC
5479 break;
5480
b8891f8d
AJ
5481 md_number_to_chars (buf, val, fixP->fx_size);
5482 fixP->fx_done = 1;
5483 }
5484 break;
5485 case BFD_RELOC_CKCORE_PCREL_JSR_IMM11BY2:
5486 if (fixP->fx_addsy == 0 && val > -2 KB && val < 2 KB)
5487 {
5488 long nval = (val >> 1) & 0x7ff;
5489 nval |= CSKYV1_INST_BSR;
5490 csky_write_insn (buf, nval, 2);
5491 fixP->fx_done = 1;
5492 }
5493 else
5494 *valP = 0;
5495 break;
5496 case BFD_RELOC_CKCORE_PCREL_JSR_IMM26BY2:
5497 if (fixP->fx_addsy == 0)
5498 {
5499 if (val >= -(1 << 26) && val < (1 << 26))
5500 {
5501 unsigned int nval = ((val + fixP->fx_size) >> 1) & 0x3ffffff;
5502 nval |= CSKYV2_INST_BSR32;
5503
5504 csky_write_insn (buf, nval, 4);
5505 }
5506 /* If bsr32 cannot reach,
5507 generate 'lrw r25,label;jsr r25' instead of 'jsri label'. */
5508 else if (IS_CSKY_ARCH_810 (mach_flag))
5509 {
5510 howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
5511 valueT opcode = csky_read_insn (buf, 4);
5512 opcode = (opcode & howto->dst_mask) | CSKYV2_INST_JSRI_TO_LRW;
5513 csky_write_insn (buf, opcode, 4);
5514 opcode = CSKYV2_INST_JSR_R26;
5515 csky_write_insn (buf + 4, opcode, 4);
5516 }
5517 fixP->fx_done = 1;
5518 }
5519 break;
5520
5521 default:
5522 {
5523 valueT opcode;
5524 offsetT min, max;
5525 unsigned int issigned = 0;
5526
5527 if (fixP->fx_addsy)
5528 break;
5529
5530 howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
5531 if (howto == NULL)
5532 {
5533 if (fixP->fx_size == 4
5534 || (fixP->fx_size == 2 && val >= -32768 && val <= 32767)
5535 || (fixP->fx_size == 1 && val >= -256 && val <= 255))
5536 {
5537 md_number_to_chars (buf, val, fixP->fx_size);
5538 fixP->fx_done = 1;
5539 break;
5540 }
5541 else
5542 abort ();
5543 }
5544
5545 if (IS_CSKY_V2 (mach_flag))
5546 val += fixP->fx_size;
5547
5548 if (howto->rightshift == 2)
5549 val += 2;
5550
5551 val >>= howto->rightshift;
5552
5553 switch (fixP->fx_r_type)
5554 {
5555 /* Offset is unsigned. */
5556 case BFD_RELOC_CKCORE_PCREL_IMM8BY4:
5557 case BFD_RELOC_CKCORE_PCREL_IMM10BY4:
5558 case BFD_RELOC_CKCORE_PCREL_IMM16BY4:
5559 max = (offsetT) howto->dst_mask;
5560 min = 0;
5561 break;
5562 /* lrw16. */
5563 case BFD_RELOC_CKCORE_PCREL_IMM7BY4:
5564 if (do_extend_lrw)
5565 max = (offsetT)((1 << (howto->bitsize + 1)) - 2);
5566 else
5567 max = (offsetT)((1 << howto->bitsize) - 1);
5568 min = 0;
5569 break;
5570 /* flrws, flrwd: the offset bits are divided in two parts. */
5571 case BFD_RELOC_CKCORE_PCREL_FLRW_IMM8BY4:
5572 max = (offsetT)((1 << howto->bitsize) - 1);
5573 min = 0;
5574 break;
5575 /* Offset is signed. */
5576 default:
5577 max = (offsetT)(howto->dst_mask >> 1);
5578 min = - max - 1;
5579 issigned = 1;
5580 }
5581 if (val < min || val > max)
5582 {
5583 csky_branch_report_error (fixP->fx_file, fixP->fx_line,
5584 fixP->fx_addsy, val);
5585 return;
5586 }
5587 opcode = csky_read_insn (buf, fixP->fx_size);
5588 /* Clear redundant bits brought from the last
5589 operation if there is any. */
5590 if (do_extend_lrw && (opcode & 0xfc00) == CSKYV2_INST_LRW16)
5591 val &= 0xff;
5592 else
5593 val &= issigned ? (offsetT)(howto->dst_mask) : max;
5594
5595 if (fixP->fx_r_type == BFD_RELOC_CKCORE_PCREL_BLOOP_IMM4BY4)
5596 val = (val & 0xf) << 12;
5597
5598 if (fixP->fx_size == 2 && (opcode & 0xfc00) == CSKYV2_INST_LRW16)
5599 {
5600 /* 8 bit offset lrw16. */
5601 if (val >= 0x80)
5602 csky_write_insn (buf,
5603 ((~val & 0x1f)
5604 | ((~val & 0x60) << 3) | (opcode & 0xe0)),
5605 fixP->fx_size);
5606 /* 7 bit offset lrw16. */
5607 else
5608 csky_write_insn (buf,
5609 (val & 0x1f) | ((val & 0x60) << 3) | opcode,
5610 fixP->fx_size);
5611 }
5612 else if (fixP->fx_size == 4
5613 && (opcode & 0xfe1ffe00) == CSKYV2_INST_FLRW)
5614 csky_write_insn (buf,
5615 ((val & 0xf) << 4) | ((val & 0xf0) << 17) | opcode,
5616 fixP->fx_size);
5617 else
5618 csky_write_insn (buf, val | opcode, fixP->fx_size);
5619 fixP->fx_done = 1;
5620 break;
5621 }
5622 }
5623 fixP->fx_addnumber = val;
5624}
5625
5626/* Translate internal representation of relocation info to BFD target
5627 format. */
5628
5629arelent *
5630tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixP)
5631{
5632 arelent *rel;
5633
fe75f42e
LX
5634 if (fixP->fx_pcrel
5635 && fixP->fx_r_type == BFD_RELOC_CKCORE_ADDR32)
5636 fixP->fx_r_type = BFD_RELOC_CKCORE_PCREL32;
5637
b8891f8d
AJ
5638 rel = xmalloc (sizeof (arelent));
5639 rel->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
5640 *rel->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
5641 rel->howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
5642 rel->addend = fixP->fx_offset;
5643 if (rel->howto == NULL)
5644 {
5645 as_bad_where (fixP->fx_file, fixP->fx_line,
5646 _("cannot represent `%s' relocation in object file"),
5647 bfd_get_reloc_code_name (fixP->fx_r_type));
5648
5649 /* Set howto to a garbage value so that we can keep going. */
5650 rel->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_32);
5651 }
5652 gas_assert (rel->howto != NULL);
5653 rel->address = fixP->fx_frag->fr_address + fixP->fx_where;
5654 return rel;
5655}
5656
5657/* Relax a fragment by scanning TC_GENERIC_RELAX_TABLE. */
5658
5659long
5660csky_relax_frag (segT segment, fragS *fragP, long stretch)
5661{
5662 const relax_typeS *this_type;
5663 const relax_typeS *start_type;
5664 relax_substateT next_state;
5665 relax_substateT this_state;
5666 offsetT growth;
5667 offsetT aim;
5668 addressT target;
5669 addressT address;
5670 symbolS *symbolP;
5671 const relax_typeS *table;
5672
5673 target = fragP->fr_offset;
5674 address = fragP->fr_address;
5675 table = TC_GENERIC_RELAX_TABLE;
5676 this_state = fragP->fr_subtype;
5677 start_type = this_type = table + this_state;
5678 symbolP = fragP->fr_symbol;
5679
5680 if (symbolP)
5681 {
5682 fragS *sym_frag;
5683
5684 sym_frag = symbol_get_frag (symbolP);
5685
5686#ifndef DIFF_EXPR_OK
5687 know (sym_frag != NULL);
5688#endif
5689 know (S_GET_SEGMENT (symbolP) != absolute_section
5690 || sym_frag == &zero_address_frag);
5691 target += S_GET_VALUE (symbolP);
5692
5693 /* If SYM_FRAG has yet to be reached on this pass, assume it
5694 will move by STRETCH just as we did, unless there is an
5695 alignment frag between here and SYM_FRAG. An alignment may
5696 well absorb any STRETCH, and we don't want to choose a larger
5697 branch insn by overestimating the needed reach of this
5698 branch. It isn't critical to calculate TARGET exactly; We
5699 know we'll be doing another pass if STRETCH is non-zero. */
5700
5701 if (stretch != 0
5702 && sym_frag->relax_marker != fragP->relax_marker
5703 && S_GET_SEGMENT (symbolP) == segment)
5704 {
5705 fragS *f;
5706
5707 /* Adjust stretch for any alignment frag. Note that if have
5708 been expanding the earlier code, the symbol may be
5709 defined in what appears to be an earlier frag. FIXME:
5710 This doesn't handle the fr_subtype field, which specifies
5711 a maximum number of bytes to skip when doing an
5712 alignment. */
5713 for (f = fragP; f != NULL && f != sym_frag; f = f->fr_next)
5714 {
5715 if (f->fr_type == rs_align || f->fr_type == rs_align_code)
5716 {
5717 if (stretch < 0)
5718 stretch = -((-stretch)
5719 & ~((1 << (int) f->fr_offset) - 1));
5720 else
5721 stretch &= ~((1 << (int) f->fr_offset) - 1);
5722 }
5723 if (stretch == 0)
5724 break;
5725 }
5726 if (f != 0)
5727 target += stretch;
5728 }
5729 }
5730
5731 aim = target - address - fragP->fr_fix;
5732
5733 /* If the fragP->fr_symbol is extern symbol, aim should be 0. */
5734 if (fragP->fr_symbol && S_GET_SEGMENT (symbolP) != segment)
5735 aim = 0;
5736
5737 if (aim < 0)
5738 {
5739 /* Look backwards. */
5740 for (next_state = this_type->rlx_more; next_state;)
5741 if (aim >= this_type->rlx_backward)
5742 next_state = 0;
5743 else
5744 {
5745 /* Grow to next state. */
5746 this_state = next_state;
5747 this_type = table + this_state;
5748 next_state = this_type->rlx_more;
5749 }
5750 }
5751 else
5752 {
5753 /* Look forwards. */
5754 for (next_state = this_type->rlx_more; next_state;)
5755 if (aim <= this_type->rlx_forward)
5756 next_state = 0;
5757 else
5758 {
5759 /* Grow to next state. */
5760 this_state = next_state;
5761 this_type = table + this_state;
5762 next_state = this_type->rlx_more;
5763 }
5764 }
5765
5766 growth = this_type->rlx_length - start_type->rlx_length;
5767 if (growth != 0)
5768 fragP->fr_subtype = this_state;
5769 return growth;
5770}
5771
5772int
5773md_estimate_size_before_relax (fragS * fragp,
5774 segT segtype)
5775{
5776 switch (fragp->fr_subtype)
5777 {
5778 case COND_DISP10:
5779 case COND_DISP16:
5780 case SCOND_DISP10:
5781 case SCOND_DISP16:
5782 case UNCD_DISP10:
5783 case UNCD_DISP16:
5784 case JCOND_DISP10:
5785 case JCOND_DISP16:
5786 case JCOND_DISP32:
5787 case JUNCD_DISP10:
5788 case JUNCD_DISP16:
5789 case JUNCD_DISP32:
5790 case JCOMPZ_DISP16:
5791 case JCOMPZ_DISP32:
5792 case BSR_DISP26:
5793 case LRW_DISP7:
5794 case LRW2_DISP8:
5795 case LRW_DISP16:
5796 gas_assert (fragp->fr_symbol);
5797 if (IS_EXTERNAL_SYM (fragp->fr_symbol, segtype))
5798 while (csky_relax_table[fragp->fr_subtype].rlx_more > RELAX_OVERFLOW)
5799 fragp->fr_subtype = csky_relax_table[fragp->fr_subtype].rlx_more;
5800 return csky_relax_table[fragp->fr_subtype].rlx_length;
5801
5802 /* C-SKY V1 relaxes. */
5803 case C (UNCD_JUMP, UNDEF_DISP):
5804 case C (UNCD_JUMP_PIC, UNDEF_DISP):
5805 if (!fragp->fr_symbol)
5806 fragp->fr_subtype = C (UNCD_JUMP_S, DISP12);
5807 else if (S_GET_SEGMENT (fragp->fr_symbol) == segtype)
5808 fragp->fr_subtype = C (UNCD_JUMP_S, DISP12);
5809 else
5810 fragp->fr_subtype = C (UNCD_JUMP_S, UNDEF_WORD_DISP);
5811 break;
5812
5813 case C (COND_JUMP, UNDEF_DISP):
5814 case C (COND_JUMP_PIC, UNDEF_DISP):
5815 if (fragp->fr_symbol
5816 && S_GET_SEGMENT (fragp->fr_symbol) == segtype)
5817 /* Got a symbol and it's defined in this segment, become byte
5818 sized. Maybe it will fix up. */
5819 fragp->fr_subtype = C (COND_JUMP_S, DISP12);
5820 else if (fragp->fr_symbol)
5821 /* It's got a segment, but it's not ours, so it will always be
5822 long. */
5823 fragp->fr_subtype = C (COND_JUMP_S, UNDEF_WORD_DISP);
5824 else
5825 /* We know the abs value. */
5826 fragp->fr_subtype = C (COND_JUMP_S, DISP12);
5827 break;
5828
5829 case C (UNCD_JUMP, DISP12):
5830 case C (UNCD_JUMP, DISP32):
5831 case C (UNCD_JUMP, UNDEF_WORD_DISP):
5832 case C (COND_JUMP, DISP12):
5833 case C (COND_JUMP, DISP32):
5834 case C (COND_JUMP, UNDEF_WORD_DISP):
5835 case C (UNCD_JUMP_PIC, DISP12):
5836 case C (UNCD_JUMP_PIC, DISP32):
5837 case C (UNCD_JUMP_PIC, UNDEF_WORD_DISP):
5838 case C (COND_JUMP_PIC, DISP12):
5839 case C (COND_JUMP_PIC, DISP32):
5840 case C (COND_JUMP_PIC, UNDEF_WORD_DISP):
5841 case RELAX_OVERFLOW:
5842 break;
5843
5844 default:
5845 abort ();
5846 }
5847 return csky_relax_table[fragp->fr_subtype].rlx_length;
5848}
5849
5850/* Parse opcode like: "op oprnd1, oprnd2, oprnd3". */
5851
5852static void
5853csky_macro_md_assemble (const char *op,
5854 const char *oprnd1,
5855 const char *oprnd2,
5856 const char *oprnd3)
5857{
5858 char str[80];
5859 str[0] = '\0';
5860 strcat (str, op);
5861 if (oprnd1 != NULL)
5862 {
5863 strcat (str, " ");
5864 strcat (str, oprnd1);
5865 if (oprnd2 != NULL)
5866 {
5867 strcat (str, ",");
5868 strcat (str, oprnd2);
5869 if (oprnd3 != NULL)
5870 {
5871 strcat (str, ",");
5872 strcat (str, oprnd3);
5873 }
5874 }
5875 }
5876 md_assemble (str);
5877 return;
5878}
5879
5880/* Get the string of operand. */
5881
5882static int
5883csky_get_macro_operand (char *src_s, char *dst_s, char end_sym)
5884{
5885 int nlen = 0;
5886 while (ISSPACE (*src_s))
5887 ++src_s;
5888 while (*src_s != end_sym)
5889 dst_s[nlen++] = *(src_s++);
5890 dst_s[nlen] = '\0';
5891 return nlen;
5892}
5893
5894/* idly 4 -> idly4. */
5895
5896static void
5897csky_idly (void)
5898{
5899 char *s = csky_insn.opcode_end;
e2e82b11 5900 if (!is_imm_within_range (&s, 4, 4))
b8891f8d
AJ
5901 {
5902 as_bad (_("second operand must be 4"));
5903 return;
5904 }
5905 csky_macro_md_assemble ("idly4", NULL, NULL, NULL);
5906 return;
5907}
5908
5909/* rolc rd, 1 or roltc rd, 1 -> addc rd, rd. */
5910
5911static void
5912csky_rolc (void)
5913{
5914 char reg[10];
5915 char *s = csky_insn.opcode_end;
5916
5917 s += csky_get_macro_operand (s, reg, ',');
5918 ++s;
5919
e2e82b11 5920 if (is_imm_within_range (&s, 1, 1))
b8891f8d
AJ
5921 {
5922 csky_macro_md_assemble ("addc", reg, reg, NULL);
5923 return;
5924 }
5925 else
5926 as_bad (_("second operand must be 1"));
5927}
5928
5929/* sxtrb0(1)(2) r1, rx -> xtbr0(1)(2) r1,rx; sextb r1. */
5930
5931static void
5932csky_sxtrb (void)
5933{
5934 char reg1[10];
5935 char reg2[10];
5936
5937 char *s = csky_insn.opcode_end;
5938 s += csky_get_macro_operand (s, reg1, ',');
5939 ++s;
5940 csky_get_macro_operand (s, reg2, '\0');
5941
5942 csky_macro_md_assemble (csky_insn.macro->name + 1, reg1, reg2, NULL);
5943 csky_macro_md_assemble ("sextb", reg1, NULL, NULL);
5944 return;
5945}
5946
5947static void
5948csky_movtf (void)
5949{
5950 char reg1[10];
5951 char reg2[10];
5952 char reg3[10];
5953
5954 char *s = csky_insn.opcode_end;
5955 s += csky_get_macro_operand (s, reg1, ',');
5956 ++s;
5957
5958 s += csky_get_macro_operand (s, reg2, ',');
5959 ++s;
5960
5961 s += csky_get_macro_operand (s, reg3, '\0');
5962 ++s;
5963 csky_macro_md_assemble ("movt", reg1, reg2, NULL);
5964 csky_macro_md_assemble ("movf", reg1, reg3, NULL);
5965 return;
5966}
5967
5b7c81bd 5968static bool
b8891f8d
AJ
5969get_macro_reg_vals (int *reg1, int *reg2, int *reg3)
5970{
5971 int nlen;
5972 char *s = csky_insn.opcode_end;
5973
5974 *reg1 = csky_get_reg_val (s, &nlen);
5975 s += nlen;
5976 if (*s != ',')
5977 {
5978 csky_show_error (ERROR_MISSING_COMMA, 0, NULL, NULL);
5b7c81bd 5979 return false;
b8891f8d
AJ
5980 }
5981 s++;
5982 *reg2 = csky_get_reg_val (s, &nlen);
5983 s += nlen;
5984 if (*s != ',')
5985 {
5986 csky_show_error (ERROR_MISSING_COMMA, 0, NULL, NULL);
5b7c81bd 5987 return false;
b8891f8d
AJ
5988 }
5989 s++;
5990 *reg3 = csky_get_reg_val (s, &nlen);
5991 s += nlen;
5992 if (*s != '\0')
5993 {
3ca4a8ec 5994 csky_show_error (ERROR_BAD_END, 0, s, NULL);
5b7c81bd 5995 return false;
b8891f8d
AJ
5996 }
5997 if (*reg1 == -1 || *reg2 == -1 || *reg3 == -1)
5998 {
5999 as_bad (_("register number out of range"));
5b7c81bd 6000 return false;
b8891f8d
AJ
6001 }
6002 if (*reg1 != *reg2)
6003 {
6004 as_bad (_("dest and source1 must be the same register"));
5b7c81bd 6005 return false;
b8891f8d
AJ
6006 }
6007 if (*reg1 >= 15 || *reg3 >= 15)
6008 {
6009 as_bad (_("64-bit operator src/dst register must be less than 15"));
5b7c81bd 6010 return false;
b8891f8d 6011 }
5b7c81bd 6012 return true;
b8891f8d
AJ
6013}
6014
6015/* addc64 rx, rx, ry -> cmplt rx, rx, addc rx, ry, addc rx+1, ry+1. */
6016
6017static void
6018csky_addc64 (void)
6019{
6020 int reg1;
6021 int reg2;
6022 int reg3;
afdcafe8
CQ
6023 char reg1_name[16] = {0};
6024 char reg3_name[16] = {0};
b8891f8d
AJ
6025
6026 if (!get_macro_reg_vals (&reg1, &reg2, &reg3))
6027 return;
afdcafe8
CQ
6028
6029 sprintf (reg1_name, "r%d", reg1);
6030 csky_macro_md_assemble ("cmplt", reg1_name, reg1_name, NULL);
6031 if (error_state.err_num != ERROR_NONE)
6032 return;
6033
6034 sprintf (reg1_name, "r%d", reg1 + (target_big_endian ? 1 : 0));
6035 sprintf (reg3_name, "r%d", reg3 + (target_big_endian ? 1 : 0));
6036 csky_macro_md_assemble ("addc", reg1_name, reg3_name, NULL);
6037 if (error_state.err_num != ERROR_NONE)
6038 return;
6039
6040 sprintf (reg1_name, "r%d", reg1 + (target_big_endian ? 0 : 1));
6041 sprintf (reg3_name, "r%d", reg3 + (target_big_endian ? 0 : 1));
6042 csky_macro_md_assemble ("addc", reg1_name, reg3_name, NULL);
b8891f8d
AJ
6043 return;
6044}
6045
6046/* subc64 rx, rx, ry -> cmphs rx, rx, subc rx, ry, subc rx+1, ry+1. */
6047
6048static void
6049csky_subc64 (void)
6050{
6051 int reg1;
6052 int reg2;
6053 int reg3;
afdcafe8
CQ
6054 char reg1_name[16] = {0};
6055 char reg3_name[16] = {0};
b8891f8d
AJ
6056
6057 if (!get_macro_reg_vals (&reg1, &reg2, &reg3))
6058 return;
afdcafe8
CQ
6059
6060 sprintf (reg1_name, "r%d", reg1);
6061 csky_macro_md_assemble ("cmphs", reg1_name, reg1_name, NULL);
6062 if (error_state.err_num != ERROR_NONE)
6063 return;
6064
6065 sprintf (reg1_name, "r%d", reg1 + (target_big_endian ? 1 : 0));
6066 sprintf (reg3_name, "r%d", reg3 + (target_big_endian ? 1 : 0));
6067 csky_macro_md_assemble ("subc", reg1_name, reg3_name, NULL);
6068 if (error_state.err_num != ERROR_NONE)
6069 return;
6070
6071 sprintf (reg1_name, "r%d", reg1 + (target_big_endian ? 0 : 1));
6072 sprintf (reg3_name, "r%d", reg3 + (target_big_endian ? 0 : 1));
6073 csky_macro_md_assemble ("subc", reg1_name, reg3_name, NULL);
b8891f8d
AJ
6074 return;
6075}
6076
6077/* or64 rx, rx, ry -> or rx, ry, or rx+1, ry+1. */
6078
6079static void
6080csky_or64 (void)
6081{
6082 int reg1;
6083 int reg2;
6084 int reg3;
afdcafe8
CQ
6085 char reg1_name[16] = {0};
6086 char reg3_name[16] = {0};
b8891f8d
AJ
6087
6088 if (!get_macro_reg_vals (&reg1, &reg2, &reg3))
6089 return;
afdcafe8
CQ
6090 sprintf (reg1_name, "r%d", reg1 + (target_big_endian ? 1 : 0));
6091 sprintf (reg3_name, "r%d", reg3 + (target_big_endian ? 1 : 0));
6092 csky_macro_md_assemble ("or", reg1_name, reg3_name, NULL);
6093
6094 if (error_state.err_num != ERROR_NONE)
6095 return;
6096 sprintf (reg1_name, "r%d", reg1 + (target_big_endian ? 0 : 1));
6097 sprintf (reg3_name, "r%d", reg3 + (target_big_endian ? 0 : 1));
6098 csky_macro_md_assemble ("or", reg1_name, reg3_name, NULL);
b8891f8d
AJ
6099 return;
6100}
6101
6102/* xor64 rx, rx, ry -> xor rx, ry, xor rx+1, ry+1. */
6103
6104static void
6105csky_xor64 (void)
6106{
6107 int reg1;
6108 int reg2;
6109 int reg3;
afdcafe8
CQ
6110 char reg1_name[16] = {0};
6111 char reg3_name[16] = {0};
b8891f8d
AJ
6112
6113 if (!get_macro_reg_vals (&reg1, &reg2, &reg3))
6114 return;
afdcafe8
CQ
6115
6116 sprintf (reg1_name, "r%d", reg1 + (target_big_endian ? 1 : 0));
6117 sprintf (reg3_name, "r%d", reg3 + (target_big_endian ? 1 : 0));
6118 csky_macro_md_assemble ("xor", reg1_name, reg3_name, NULL);
6119 if (error_state.err_num != ERROR_NONE)
6120 return;
6121
6122 sprintf (reg1_name, "r%d", reg1 + (target_big_endian ? 0 : 1));
6123 sprintf (reg3_name, "r%d", reg3 + (target_big_endian ? 0 : 1));
6124 csky_macro_md_assemble ("xor", reg1_name, reg3_name, NULL);
b8891f8d
AJ
6125 return;
6126}
6127
6128/* The following are V2 macro instructions. */
6129
6130/* neg rd -> not rd, rd; addi rd, 1. */
6131
6132static void
6133csky_neg (void)
6134{
6135 char reg1[10];
6136
6137 char *s = csky_insn.opcode_end;
6138 s += csky_get_macro_operand (s, reg1, '\0');
6139 ++s;
6140
6141 csky_macro_md_assemble ("not", reg1, reg1, NULL);
6142 csky_macro_md_assemble ("addi", reg1, "1", NULL);
6143 return;
6144}
6145
6146/* rsubi rd, imm16 -> not rd; addi rd, imm16 + 1 */
6147
6148static void
6149csky_rsubi (void)
6150{
6151 char reg1[10];
6152 char str_imm16[20];
6153 unsigned int imm16 = 0;
6154 expressionS e;
6155 char *s = csky_insn.opcode_end;
6156 s += csky_get_macro_operand (s, reg1, ',');
6157 ++s;
6158
6159 s = parse_exp (s, &e);
6160 if (e.X_op == O_constant)
6161 imm16 = e.X_add_number;
6162 else
6163 csky_show_error (ERROR_IMM_ILLEGAL, 2, NULL, NULL);
6164
6165 sprintf (str_imm16, "%d", imm16 + 1);
6166
6167 csky_macro_md_assemble ("not", reg1, reg1, NULL);
6168 csky_macro_md_assemble ("addi", reg1, str_imm16, NULL);
6169 return;
6170}
6171
6172/* Such as: asrc rd -> asrc rd, rd, 1. */
6173
6174static void
6175csky_arith (void)
6176{
6177 char reg1[10];
6178 char *s = csky_insn.opcode_end;
6179 s += csky_get_macro_operand (s, reg1, '\0');
6180 ++s;
6181 csky_macro_md_assemble (csky_insn.macro->name, reg1, reg1, "1");
6182 return;
6183}
6184
6185/* decne rd -> if ck802: subi rd, 1; cmpnei rd, 0.
6186 else: decne rd, rd, 1 */
6187
6188static void
6189csky_decne (void)
6190{
6191 char reg1[10];
6192 char *s = csky_insn.opcode_end;
6193 s += csky_get_macro_operand (s, reg1, '\0');
6194 ++s;
6195 if (IS_CSKY_ARCH_802 (mach_flag))
6196 {
6197 csky_macro_md_assemble ("subi", reg1, "1", NULL);
6198 csky_macro_md_assemble ("cmpnei", reg1, "0", NULL);
6199 }
6200 else
6201 csky_macro_md_assemble ("decne", reg1, reg1, "1");
6202 return;
6203}
6204
6205/* If -mnolrw, lrw rd, imm -> movih rd, imm_hi16; ori rd, imm_lo16. */
6206
6207static void
6208csky_lrw (void)
6209{
6210 char reg1[10];
6211 char imm[40];
6212 char imm_hi16[40];
6213 char imm_lo16[40];
6214
6215 char *s = csky_insn.opcode_end;
6216 s += csky_get_macro_operand (s, reg1, ',');
6217 ++s;
6218 s += csky_get_macro_operand (s, imm, '\0');
6219 ++s;
6220
6221 imm_hi16[0] = '\0';
6222 strcat (imm_hi16, "(");
6223 strcat (imm_hi16, imm);
6224 strcat (imm_hi16, ") >> 16");
6225 imm_lo16[0] = '\0';
6226 strcat (imm_lo16, "(");
6227 strcat (imm_lo16, imm);
6228 strcat (imm_lo16, ") & 0xffff");
6229
6230 csky_macro_md_assemble ("movih", reg1, imm_hi16, NULL);
6231 csky_macro_md_assemble ("ori", reg1, reg1, imm_lo16);
6232
6233 return;
6234}
6235
6236/* The following are worker functions for C-SKY v1. */
6237
5b7c81bd 6238bool
b8891f8d
AJ
6239v1_work_lrw (void)
6240{
6241 int reg;
6242 int output_literal = csky_insn.val[1];
6243
6244 reg = csky_insn.val[0];
6245 csky_insn.isize = 2;
6246 csky_insn.output = frag_more (2);
6247 if (csky_insn.e1.X_op == O_constant
6248 && csky_insn.e1.X_add_number <= 0x7f
6249 && csky_insn.e1.X_add_number >= 0)
6250 /* lrw to movi. */
6251 csky_insn.inst = 0x6000 | reg | (csky_insn.e1.X_add_number << 4);
6252 else
6253 {
6254 csky_insn.inst = csky_insn.opcode->op16[0].opcode;
6255 csky_insn.inst |= reg << 8;
6256 if (output_literal)
6257 {
1feede9b 6258 struct literal *p = enter_literal (&csky_insn.e1, 0, 0, 0);
b8891f8d
AJ
6259
6260 /* Create a reference to pool entry. */
6261 csky_insn.e1.X_op = O_symbol;
6262 csky_insn.e1.X_add_symbol = poolsym;
1feede9b 6263 csky_insn.e1.X_add_number = p->offset << 2;
b8891f8d
AJ
6264 }
6265
6266 if (insn_reloc == BFD_RELOC_CKCORE_TLS_GD32
6267 || insn_reloc == BFD_RELOC_CKCORE_TLS_LDM32
6268 || insn_reloc == BFD_RELOC_CKCORE_TLS_IE32)
6269 {
6270 literal_insn_offset->tls_addend.frag = frag_now;
6271 literal_insn_offset->tls_addend.offset
6272 = (csky_insn.output
6273 - literal_insn_offset->tls_addend.frag->fr_literal);
6274 }
6275 fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal, 2,
6276 &csky_insn.e1, 1, BFD_RELOC_CKCORE_PCREL_IMM8BY4);
6277 }
6278 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
6279
5b7c81bd 6280 return true;
b8891f8d
AJ
6281}
6282
5b7c81bd 6283bool
b8891f8d
AJ
6284v1_work_fpu_fo (void)
6285{
6286 int i = 0;
6287 int inst;
6288 int greg = -1;
6289 char buff[50];
6290 struct csky_opcode_info *opinfo = NULL;
6291
6292 if (csky_insn.isize == 4)
6293 opinfo = &csky_insn.opcode->op32[csky_insn.opcode_idx];
6294 else if (csky_insn.isize == 2)
6295 opinfo = &csky_insn.opcode->op16[csky_insn.opcode_idx];
6296
6297 /* Firstly, get general reg. */
6298 for (i = 0;i < opinfo->operand_num; i++)
6299 if (opinfo->oprnd.oprnds[i].type == OPRND_TYPE_GREG0_15)
6300 greg = csky_insn.val[i];
6301 gas_assert (greg != -1);
6302
6303 /* Secondly, get float inst. */
6304 csky_generate_insn ();
6305 inst = csky_insn.inst;
6306
6307 /* Now get greg and inst, we can write instruction to floating unit. */
afdcafe8 6308 sprintf (buff, "lrw r%d,0x%x", greg, inst);
b8891f8d 6309 md_assemble (buff);
afdcafe8 6310 sprintf (buff, "cpwir r%d", greg);
b8891f8d 6311 md_assemble (buff);
5b7c81bd 6312 return false;
b8891f8d
AJ
6313}
6314
5b7c81bd 6315bool
b8891f8d
AJ
6316v1_work_fpu_fo_fc (void)
6317{
6318 int i = 0;
6319 int inst;
6320 int greg = -1;
6321 char buff[50];
6322 struct csky_opcode_info *opinfo = NULL;
6323
6324 if (csky_insn.isize == 4)
6325 opinfo = &csky_insn.opcode->op32[csky_insn.opcode_idx];
6326 else if (csky_insn.isize == 2)
6327 opinfo = &csky_insn.opcode->op16[csky_insn.opcode_idx];
6328
6329 /* Firstly, get general reg. */
6330 for (i = 0;i < opinfo->operand_num; i++)
6331 if (opinfo->oprnd.oprnds[i].type == OPRND_TYPE_GREG0_15)
6332 greg = csky_insn.val[i];
6333 gas_assert (greg != -1);
6334
6335 /* Secondly, get float inst. */
6336 csky_generate_insn ();
6337 inst = csky_insn.inst;
6338
6339 /* Now get greg and inst, we can write instruction to floating unit. */
afdcafe8 6340 sprintf (buff, "lrw r%d,0x%x", greg, inst);
b8891f8d 6341 md_assemble (buff);
afdcafe8 6342 sprintf (buff, "cpwir r%d", greg);
b8891f8d
AJ
6343 md_assemble (buff);
6344 sprintf (buff, "cprc");
6345 md_assemble (buff);
6346
5b7c81bd 6347 return false;
b8891f8d
AJ
6348}
6349
5b7c81bd 6350bool
b8891f8d
AJ
6351v1_work_fpu_write (void)
6352{
6353 int greg;
6354 int freg;
6355 char buff[50];
6356
6357 greg = csky_insn.val[0];
6358 freg = csky_insn.val[1];
6359
6360 /* Now get greg and freg, we can write instruction to floating unit. */
afdcafe8 6361 sprintf (buff, "cpwgr r%d,cpr%d", greg, freg);
b8891f8d
AJ
6362 md_assemble (buff);
6363
5b7c81bd 6364 return false;
b8891f8d
AJ
6365}
6366
5b7c81bd 6367bool
b8891f8d
AJ
6368v1_work_fpu_read (void)
6369{
6370 int greg;
6371 int freg;
6372 char buff[50];
6373
6374 greg = csky_insn.val[0];
6375 freg = csky_insn.val[1];
6376 /* Now get greg and freg, we can write instruction to floating unit. */
afdcafe8 6377 sprintf (buff, "cprgr r%d,cpr%d", greg, freg);
b8891f8d
AJ
6378 md_assemble (buff);
6379
5b7c81bd 6380 return false;
b8891f8d
AJ
6381}
6382
5b7c81bd 6383bool
b8891f8d
AJ
6384v1_work_fpu_writed (void)
6385{
6386 int greg;
6387 int freg;
6388 char buff[50];
6389
6390 greg = csky_insn.val[0];
6391 freg = csky_insn.val[1];
6392
6393 if (greg & 0x1)
6394 {
6395 as_bad (_("even register number required"));
5b7c81bd 6396 return false;
b8891f8d
AJ
6397 }
6398 /* Now get greg and freg, we can write instruction to floating unit. */
6399 if (target_big_endian)
afdcafe8 6400 sprintf (buff, "cpwgr r%d,cpr%d", greg + 1, freg);
b8891f8d 6401 else
afdcafe8 6402 sprintf (buff, "cpwgr r%d,cpr%d", greg, freg);
b8891f8d
AJ
6403 md_assemble (buff);
6404 if (target_big_endian)
afdcafe8 6405 sprintf (buff, "cpwgr r%d,cpr%d", greg, freg + 1);
b8891f8d 6406 else
afdcafe8 6407 sprintf (buff, "cpwgr r%d,cpr%d", greg+1, freg + 1);
b8891f8d 6408 md_assemble (buff);
5b7c81bd 6409 return false;
b8891f8d
AJ
6410}
6411
5b7c81bd 6412bool
b8891f8d
AJ
6413v1_work_fpu_readd (void)
6414{
6415 int greg;
6416 int freg;
6417 char buff[50];
6418
6419 greg = csky_insn.val[0];
6420 freg = csky_insn.val[1];
6421
6422 if (greg & 0x1)
6423 {
6424 as_bad (_("even register number required"));
5b7c81bd 6425 return false;
b8891f8d
AJ
6426 }
6427 /* Now get greg and freg, we can write instruction to floating unit. */
6428 if (target_big_endian)
afdcafe8 6429 sprintf (buff, "cprgr r%d,cpr%d", greg+1, freg);
b8891f8d 6430 else
afdcafe8 6431 sprintf (buff, "cprgr r%d,cpr%d", greg, freg);
b8891f8d
AJ
6432 md_assemble (buff);
6433 if (target_big_endian)
afdcafe8 6434 sprintf (buff, "cprgr r%d,cpr%d", greg, freg + 1);
b8891f8d 6435 else
afdcafe8 6436 sprintf (buff, "cprgr r%d,cpr%d", greg+1, freg + 1);
b8891f8d
AJ
6437 md_assemble (buff);
6438
5b7c81bd 6439 return false;
b8891f8d
AJ
6440}
6441
6442/* The following are for csky pseudo handling. */
6443
5b7c81bd 6444bool
b8891f8d
AJ
6445v1_work_jbsr (void)
6446{
6447 csky_insn.output = frag_more (2);
6448 if (do_force2bsr)
6449 /* Generate fixup BFD_RELOC_CKCORE_PCREL_IMM11BY2. */
6450 fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
6451 2, & csky_insn.e1, 1, BFD_RELOC_CKCORE_PCREL_IMM11BY2);
6452 else
6453 {
6454 /* Using jsri instruction. */
6455 const char *name = "jsri";
6456 csky_insn.opcode = (struct csky_opcode *)
629310ab 6457 str_hash_find (csky_opcodes_hash, name);
b8891f8d
AJ
6458 csky_insn.opcode_idx = 0;
6459 csky_insn.isize = 2;
6460
1feede9b 6461 struct literal *p = enter_literal (&csky_insn.e1, 1, 0, 0);
b8891f8d
AJ
6462
6463 /* Create a reference to pool entry. */
6464 csky_insn.e1.X_op = O_symbol;
6465 csky_insn.e1.X_add_symbol = poolsym;
1feede9b 6466 csky_insn.e1.X_add_number = p->offset << 2;
b8891f8d
AJ
6467
6468 /* Generate fixup BFD_RELOC_CKCORE_PCREL_IMM8BY4. */
6469 fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
6470 2, & csky_insn.e1, 1, BFD_RELOC_CKCORE_PCREL_IMM8BY4);
6471
6472 if (csky_insn.e1.X_op != O_absent && do_jsri2bsr)
6473 /* Generate fixup BFD_RELOC_CKCORE_PCREL_JSR_IMM11BY2. */
6474 fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
1feede9b 6475 2, &p->e,
b8891f8d
AJ
6476 1, BFD_RELOC_CKCORE_PCREL_JSR_IMM11BY2);
6477 }
6478 csky_generate_insn ();
6479
6480 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
6481
5b7c81bd 6482 return true;
b8891f8d
AJ
6483}
6484
6485/* The following are worker functions for csky v2 instruction handling. */
6486
6487/* For nie/nir/ipush/ipop. */
6488
5b7c81bd 6489bool
b8891f8d
AJ
6490v2_work_istack (void)
6491{
6492 if (!do_intr_stack)
6493 {
6494 csky_show_error (ERROR_OPCODE_ILLEGAL, 0, NULL, NULL);
5b7c81bd 6495 return false;
b8891f8d
AJ
6496 }
6497 csky_insn.output = frag_more (csky_insn.isize);
6498 csky_insn.inst = csky_insn.opcode->op16[0].opcode;
6499 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
5b7c81bd 6500 return true;
b8891f8d
AJ
6501}
6502
5b7c81bd 6503bool
b8891f8d
AJ
6504v2_work_btsti (void)
6505{
6506 if (!do_extend_lrw
6507 && (csky_insn.flag_force == INSN_OPCODE16F
6508 || IS_CSKY_ARCH_801 (mach_flag)))
6509 {
6510 csky_show_error (ERROR_OPCODE_ILLEGAL, 0, NULL, NULL);
5b7c81bd 6511 return false;
b8891f8d
AJ
6512 }
6513 if (!do_extend_lrw && csky_insn.isize == 2)
6514 csky_insn.isize = 4;
6515 /* Generate relax or reloc if necessary. */
6516 csky_generate_frags ();
6517 /* Generate the insn by mask. */
6518 csky_generate_insn ();
6519 /* Write inst to frag. */
6520 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
5b7c81bd 6521 return true;
b8891f8d
AJ
6522}
6523
5b7c81bd 6524bool
b8891f8d
AJ
6525v2_work_addi (void)
6526{
6527 csky_insn.isize = 2;
6528 if (csky_insn.number == 2)
6529 {
6530 if (csky_insn.val[0] == 14
6531 && csky_insn.val[1] >= 0 && csky_insn.val[1] <= 0x1fc
6532 && (csky_insn.val[1] & 0x3) == 0
6533 && csky_insn.flag_force != INSN_OPCODE32F)
6534 {
6535 /* addi sp, sp, imm. */
6536 csky_insn.inst = 0x1400 | ((csky_insn.val[1] >> 2) & 0x1f);
6537 csky_insn.inst |= (csky_insn.val[1] << 1) & 0x300;
6538 csky_insn.output = frag_more (2);
6539 }
6540 else if (csky_insn.val[0] < 8
6541 && csky_insn.val[1] >= 1 && csky_insn.val[1] <= 0x100
6542 && csky_insn.flag_force != INSN_OPCODE32F)
6543 {
6544 csky_insn.inst = 0x2000 | (csky_insn.val[0] << 8);
6545 csky_insn.inst |= (csky_insn.val[1] - 1);
6546 csky_insn.output = frag_more (2);
6547 }
6548 else if (csky_insn.val[1] >= 1 && csky_insn.val[1] <= 0x10000
6549 && csky_insn.flag_force != INSN_OPCODE16F
6550 && !IS_CSKY_ARCH_801 (mach_flag))
6551 {
6552 csky_insn.inst = 0xe4000000 | (csky_insn.val[0] << 21);
6553 csky_insn.inst |= csky_insn.val[0] << 16;
6554 csky_insn.inst |= (csky_insn.val[1] - 1);
6555 csky_insn.isize = 4;
6556 csky_insn.output = frag_more (4);
6557 }
6558 else
6559 {
6560 csky_show_error (ERROR_OPERANDS_ILLEGAL, 0,
6561 csky_insn.opcode_end, NULL);
5b7c81bd 6562 return false;
b8891f8d
AJ
6563 }
6564 }
6565 else if (csky_insn.number == 3)
6566 {
6567 if (csky_insn.val[0] == 14
6568 && csky_insn.val[1] == 14
6569 && csky_insn.val[2] >= 0 && csky_insn.val[2] <= 0x1fc
6570 && (csky_insn.val[2] & 0x3) == 0
6571 && csky_insn.flag_force != INSN_OPCODE32F)
6572 {
6573 csky_insn.inst = 0x1400 | ((csky_insn.val[2] >> 2) & 0x1f);
6574 csky_insn.inst |= (csky_insn.val[2] << 1) & 0x300;
6575 csky_insn.output = frag_more (2);
6576 }
6577 else if (csky_insn.val[0] < 8
6578 && csky_insn.val[1] == 14
6579 && csky_insn.val[2] >= 0 && csky_insn.val[2] <= 0x3fc
6580 && (csky_insn.val[2] & 0x3) == 0
6581 && csky_insn.flag_force != INSN_OPCODE32F)
6582 {
6583 csky_insn.inst = 0x1800 | (csky_insn.val[0] << 8);
6584 csky_insn.inst |= csky_insn.val[2] >> 2;
6585 csky_insn.output = frag_more (2);
6586 }
6587 else if (csky_insn.val[0] < 8
6588 && csky_insn.val[0] == csky_insn.val[1]
6589 && csky_insn.val[2] >= 1 && csky_insn.val[2] <= 0x100
6590 && csky_insn.flag_force != INSN_OPCODE32F)
6591 {
6592 csky_insn.inst = 0x2000 | (csky_insn.val[0] << 8);
6593 csky_insn.inst |= (csky_insn.val[2] - 1);
6594 csky_insn.output = frag_more (2);
6595 }
6596 else if (csky_insn.val[0] < 8
6597 && csky_insn.val[1] < 8
6598 && csky_insn.val[2] >= 1 && csky_insn.val[2] <= 0x8
6599 && csky_insn.flag_force != INSN_OPCODE32F)
6600 {
6601 csky_insn.inst = 0x5802 | (csky_insn.val[0] << 5);
6602 csky_insn.inst |= csky_insn.val[1] << 8;
6603 csky_insn.inst |= (csky_insn.val[2] - 1) << 2;
6604 csky_insn.output = frag_more (2);
6605 }
6606 else if (csky_insn.val[1] == 28
6607 && csky_insn.val[2] >= 1 && csky_insn.val[2] <= 0x40000
6608 && csky_insn.flag_force != INSN_OPCODE16F
6609 && !IS_CSKY_ARCH_801 (mach_flag))
6610 {
6611 csky_insn.inst = 0xcc1c0000 | (csky_insn.val[0] << 21);
6612 csky_insn.isize = 4;
6613 csky_insn.output = frag_more (4);
6614 if (insn_reloc == BFD_RELOC_CKCORE_GOTOFF)
6615 {
6616 fix_new_exp (frag_now, csky_insn.output-frag_now->fr_literal,
6617 4, &csky_insn.e1, 0, BFD_RELOC_CKCORE_GOTOFF_IMM18);
6618 }
6619 else
6620 csky_insn.inst |= (csky_insn.val[2] - 1);
6621 }
6622 else if (csky_insn.val[2] >= 1 && csky_insn.val[2] <= 0x1000
6623 && csky_insn.flag_force != INSN_OPCODE16F
6624 && !IS_CSKY_ARCH_801 (mach_flag))
6625 {
6626 csky_insn.inst = 0xe4000000 | (csky_insn.val[0] << 21);
6627 csky_insn.inst |= csky_insn.val[1] << 16;
6628 csky_insn.inst |= (csky_insn.val[2] - 1);
6629 csky_insn.isize = 4;
6630 csky_insn.output = frag_more (4);
6631 }
6632 else
6633 {
6634 csky_show_error (ERROR_OPERANDS_ILLEGAL, 0,
6635 (char *)csky_insn.opcode_end, NULL);
5b7c81bd 6636 return false;
b8891f8d
AJ
6637 }
6638 }
6639 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
6640
5b7c81bd 6641 return true;
b8891f8d
AJ
6642}
6643
5b7c81bd 6644bool
b8891f8d
AJ
6645v2_work_subi (void)
6646{
6647 csky_insn.isize = 2;
6648 if (csky_insn.number == 2)
6649 {
6650 if (csky_insn.val[0] == 14
6651 && csky_insn.val[1] >= 0 && csky_insn.val[2] <= 0x1fc
6652 && (csky_insn.val[1] & 0x3) == 0
6653 && csky_insn.flag_force != INSN_OPCODE32F)
6654 {
6655 csky_insn.inst = 0x1420 | ((csky_insn.val[1] >> 2) & 0x1f);
6656 csky_insn.inst |= (csky_insn.val[1] << 1) & 0x300;
6657 }
6658 else if (csky_insn.val[0] < 8
6659 && csky_insn.val[1] >= 1 && csky_insn.val[1] <= 0x100
6660 && csky_insn.flag_force != INSN_OPCODE32F)
6661 {
6662 csky_insn.inst = 0x2800 | (csky_insn.val[0] << 8);
6663 csky_insn.inst |= (csky_insn.val[1] - 1);
6664 }
6665 else if (csky_insn.val[1] >= 1 && csky_insn.val[1] <= 0x10000
6666 && csky_insn.flag_force != INSN_OPCODE16F
6667 && !IS_CSKY_ARCH_801 (mach_flag))
6668 {
6669 csky_insn.inst = 0xe4001000 | (csky_insn.val[0] << 21);
6670 csky_insn.inst |= csky_insn.val[0] << 16;
6671 csky_insn.inst |= (csky_insn.val[1] - 1);
6672 csky_insn.isize = 4;
6673 }
6674 else
6675 {
6676 csky_show_error (ERROR_OPERANDS_ILLEGAL, 0,
6677 (char *)csky_insn.opcode_end, NULL);
5b7c81bd 6678 return false;
b8891f8d
AJ
6679 }
6680 }
6681 else if (csky_insn.number == 3)
6682 {
6683 if (csky_insn.val[0] == 14
6684 && csky_insn.val[1] == 14
6685 && csky_insn.val[2] >= 0 && csky_insn.val[2] <= 0x1fc
6686 && (csky_insn.val[2] & 0x3) == 0
6687 && csky_insn.flag_force != INSN_OPCODE32F)
6688 {
6689 csky_insn.inst = 0x1420 | ((csky_insn.val[2] >> 2) & 0x1f);
6690 csky_insn.inst |= (csky_insn.val[2] << 1) & 0x300;
6691 }
6692
6693 else if (csky_insn.val[0] < 8
6694 && csky_insn.val[0] == csky_insn.val[1]
6695 && csky_insn.val[2] >= 1 && csky_insn.val[2] <= 0x100
6696 && csky_insn.flag_force != INSN_OPCODE32F)
6697 {
6698 csky_insn.inst = 0x2800 | (csky_insn.val[0] << 8);
6699 csky_insn.inst |= (csky_insn.val[2] - 1);
6700 }
6701 else if (csky_insn.val[0] < 8
6702 && csky_insn.val[1] < 8
6703 && csky_insn.val[2] >= 1 && csky_insn.val[2] <= 0x8
6704 && csky_insn.flag_force != INSN_OPCODE32F)
6705 {
6706 csky_insn.inst = 0x5803 | (csky_insn.val[0] << 5);
6707 csky_insn.inst |= csky_insn.val[1] << 8;
6708 csky_insn.inst |= (csky_insn.val[2] - 1) << 2;
6709 }
6710 else if (csky_insn.val[2] >= 1 && csky_insn.val[2] <= 0x1000
6711 && csky_insn.flag_force != INSN_OPCODE16F
6712 && !IS_CSKY_ARCH_801 (mach_flag))
6713 {
6714 csky_insn.inst = 0xe4001000 | (csky_insn.val[0] << 21);
6715 csky_insn.inst |= csky_insn.val[1] << 16;
6716 csky_insn.inst |= (csky_insn.val[2] - 1);
6717 csky_insn.isize = 4;
6718 }
6719 else
6720 {
6721 csky_show_error (ERROR_OPERANDS_ILLEGAL, 0,
6722 (char *)csky_insn.opcode_end, NULL);
5b7c81bd 6723 return false;
b8891f8d
AJ
6724 }
6725 }
6726 csky_insn.output = frag_more (csky_insn.isize);
6727 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
6728
5b7c81bd 6729 return true;
b8891f8d
AJ
6730}
6731
5b7c81bd 6732bool
b8891f8d
AJ
6733v2_work_add_sub (void)
6734{
6735 if (csky_insn.number == 3
6736 && (csky_insn.val[0] == csky_insn.val[1]
6737 || csky_insn.val[0] == csky_insn.val[2])
6738 && csky_insn.val[0] <= 15
6739 && csky_insn.val[1] <= 15
6740 && csky_insn.val[2] <= 15)
6741 {
6742 if (!strstr (csky_insn.opcode->mnemonic, "sub")
6743 || csky_insn.val[0] == csky_insn.val[1])
6744 {
6745 csky_insn.opcode_idx = 0;
6746 csky_insn.isize = 2;
6747 if (csky_insn.val[0] == csky_insn.val[1])
6748 csky_insn.val[1] = csky_insn.val[2];
6749
6750 csky_insn.number = 2;
6751
6752 }
6753 }
6754 if (csky_insn.isize == 4
6755 && IS_CSKY_ARCH_801 (mach_flag))
6756 {
6757 if (csky_insn.number == 3)
6758 {
6759 if (csky_insn.val[0] > 7)
e2e82b11
CQ
6760 {
6761 SET_ERROR_INTEGER (ERROR_REG_OVER_RANGE, csky_insn.val[0]);
6762 csky_show_error (ERROR_REG_OVER_RANGE, 1, NULL, NULL);
6763 }
b8891f8d 6764 if (csky_insn.val[1] > 7)
e2e82b11
CQ
6765 {
6766 SET_ERROR_INTEGER (ERROR_REG_OVER_RANGE, csky_insn.val[1]);
6767 csky_show_error (ERROR_REG_OVER_RANGE, 2, NULL, NULL);
6768 }
b8891f8d 6769 if (csky_insn.val[2] > 7)
e2e82b11
CQ
6770 {
6771 SET_ERROR_INTEGER (ERROR_REG_OVER_RANGE, csky_insn.val[2]);
6772 csky_show_error (ERROR_REG_OVER_RANGE, 3, NULL, NULL);
6773 }
b8891f8d
AJ
6774 }
6775 else
6776 {
6777 if (csky_insn.val[0] > 15)
e2e82b11
CQ
6778 {
6779 SET_ERROR_INTEGER (ERROR_REG_OVER_RANGE, csky_insn.val[0]);
6780 csky_show_error (ERROR_REG_OVER_RANGE, 1, NULL, NULL);
6781 }
b8891f8d 6782 if (csky_insn.val[1] > 15)
e2e82b11
CQ
6783 {
6784 SET_ERROR_INTEGER (ERROR_REG_OVER_RANGE, csky_insn.val[1]);
6785 csky_show_error (ERROR_REG_OVER_RANGE, 2, NULL, NULL);
6786 }
b8891f8d 6787 }
5b7c81bd 6788 return false;
b8891f8d
AJ
6789 }
6790 /* sub rz, rx. */
6791 /* Generate relax or reloc if necessary. */
6792 csky_generate_frags ();
6793 /* Generate the insn by mask. */
6794 csky_generate_insn ();
6795 /* Write inst to frag. */
6796 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
5b7c81bd 6797 return true;
b8891f8d
AJ
6798}
6799
5b7c81bd 6800bool
b8891f8d
AJ
6801v2_work_rotlc (void)
6802{
6803 const char *name = "addc";
6804 csky_insn.opcode
629310ab 6805 = (struct csky_opcode *) str_hash_find (csky_opcodes_hash, name);
b8891f8d
AJ
6806 csky_insn.opcode_idx = 0;
6807 if (csky_insn.isize == 2)
6808 {
6809 /* addc rz, rx. */
6810 csky_insn.number = 2;
6811 csky_insn.val[1] = csky_insn.val[0];
6812 }
6813 else
6814 {
6815 csky_insn.number = 3;
6816 /* addc rz, rx, ry. */
6817 csky_insn.val[1] = csky_insn.val[0];
6818 csky_insn.val[2] = csky_insn.val[0];
6819 }
6820 /* Generate relax or reloc if necessary. */
6821 csky_generate_frags ();
6822 /* Generate the insn by mask. */
6823 csky_generate_insn ();
6824 /* Write inst to frag. */
6825 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
5b7c81bd 6826 return true;
b8891f8d
AJ
6827}
6828
5b7c81bd 6829bool
b8891f8d
AJ
6830v2_work_bgeni (void)
6831{
6832 const char *name = NULL;
6833 int imm = csky_insn.val[1];
6834 int val = 1 << imm;
6835 if (imm < 16)
6836 name = "movi";
6837 else
6838 {
6839 name = "movih";
6840 val >>= 16;
6841 }
6842 csky_insn.opcode
629310ab 6843 = (struct csky_opcode *) str_hash_find (csky_opcodes_hash, name);
b8891f8d
AJ
6844 csky_insn.opcode_idx = 0;
6845 csky_insn.val[1] = val;
6846
6847 /* Generate relax or reloc if necessary. */
6848 csky_generate_frags ();
6849 /* Generate the insn by mask. */
6850 csky_generate_insn ();
6851 /* Write inst to frag. */
6852 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
5b7c81bd 6853 return true;
b8891f8d
AJ
6854}
6855
5b7c81bd 6856bool
b8891f8d
AJ
6857v2_work_not (void)
6858{
6859 const char *name = "nor";
6860 csky_insn.opcode
629310ab 6861 = (struct csky_opcode *) str_hash_find (csky_opcodes_hash, name);
b8891f8d
AJ
6862 csky_insn.opcode_idx = 0;
6863 if (csky_insn.number == 1)
6864 {
6865 csky_insn.val[1] = csky_insn.val[0];
6866 if (csky_insn.val[0] < 16)
6867 {
6868 /* 16 bits nor rz, rz. */
6869 csky_insn.number = 2;
6870 csky_insn.isize = 2;
6871 }
6872 else
6873 {
6874 csky_insn.val[2] = csky_insn.val[0];
6875 csky_insn.number = 3;
6876 csky_insn.isize = 4;
6877 }
6878 }
6879 if (csky_insn.number == 2)
6880 {
6881 if (csky_insn.val[0] == csky_insn.val[1]
6882 && csky_insn.val[0] < 16)
6883 {
6884 /* 16 bits nor rz, rz. */
6885 csky_insn.number = 2;
6886 csky_insn.isize = 2;
6887 }
6888 else
6889 {
6890 csky_insn.val[2] = csky_insn.val[1];
6891 csky_insn.number = 3;
6892 csky_insn.isize = 4;
6893 }
6894 }
6895
6896 /* Generate relax or reloc if necessary. */
6897 csky_generate_frags ();
6898 /* Generate the insn by mask. */
6899 csky_generate_insn ();
6900 /* Write inst to frag. */
6901 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
5b7c81bd 6902 return true;
b8891f8d
AJ
6903}
6904
5b7c81bd 6905bool
b8891f8d
AJ
6906v2_work_jbtf (void)
6907{
6908 if (csky_insn.e1.X_add_symbol == NULL || csky_insn.e1.X_op == O_constant)
6909 {
6910 csky_show_error (ERROR_UNDEFINE, 0, (void *)"operand is invalid", NULL);
5b7c81bd 6911 return false;
b8891f8d
AJ
6912 }
6913
6914 if (IS_CSKY_ARCH_801 (mach_flag))
6915 {
6916 /* CK801 doesn't have 32-bit bt/bf insns or a jump insn with a
6917 range larger than SCOND_DISP16. Relax to a short jump around
6918 an unconditional branch, and give up if that overflows too. */
6919 csky_insn.output = frag_var (rs_machine_dependent,
6920 SCOND_DISP16_LEN,
6921 SCOND_DISP10_LEN,
6922 SCOND_DISP10,
6923 csky_insn.e1.X_add_symbol,
6924 csky_insn.e1.X_add_number,
6925 0);
6926 csky_insn.isize = 2;
6927 csky_insn.max = SCOND_DISP16_LEN;
6928 csky_insn.inst = csky_insn.opcode->op16[0].opcode;
6929 }
6930 else if (do_long_jump && !IS_CSKY_ARCH_802 (mach_flag))
6931 {
6932 /* Generate relax with jcondition.
6933 Note that CK802 doesn't support the JMPI instruction so
6934 we cannot relax to a jump with a 32-bit offset. */
6935 csky_insn.output = frag_var (rs_machine_dependent,
6936 JCOND_DISP32_LEN,
6937 JCOND_DISP10_LEN,
6938 JCOND_DISP10,
6939 csky_insn.e1.X_add_symbol,
6940 csky_insn.e1.X_add_number,
6941 0);
6942 csky_insn.isize = 2;
6943 csky_insn.max = JCOND_DISP32_LEN;
6944 csky_insn.inst = csky_insn.opcode->op16[0].opcode;
6945 }
6946 else
6947 {
6948 /* Generate relax with condition. */
6949 csky_insn.output = frag_var (rs_machine_dependent,
6950 COND_DISP16_LEN,
6951 COND_DISP10_LEN,
6952 COND_DISP10,
6953 csky_insn.e1.X_add_symbol,
6954 csky_insn.e1.X_add_number,
6955 0);
6956 csky_insn.isize = 2;
6957 csky_insn.max = COND_DISP16_LEN;
6958 csky_insn.inst = csky_insn.opcode->op16[0].opcode;
6959 }
6960 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
6961
5b7c81bd 6962 return true;
b8891f8d
AJ
6963}
6964
5b7c81bd 6965bool
b8891f8d
AJ
6966v2_work_jbr (void)
6967{
6968 if (csky_insn.e1.X_add_symbol == NULL || csky_insn.e1.X_op == O_constant)
6969 {
6970 csky_show_error (ERROR_UNDEFINE, 0, (void *)"operand is invalid", NULL);
5b7c81bd 6971 return false;
b8891f8d
AJ
6972 }
6973
6974 if (do_long_jump
6975 && !IS_CSKY_ARCH_801 (mach_flag)
6976 && !IS_CSKY_ARCH_802 (mach_flag))
6977 {
6978 csky_insn.output = frag_var (rs_machine_dependent,
6979 JUNCD_DISP32_LEN,
6980 JUNCD_DISP10_LEN,
6981 JUNCD_DISP10,
6982 csky_insn.e1.X_add_symbol,
6983 csky_insn.e1.X_add_number,
6984 0);
6985
6986 csky_insn.inst = csky_insn.opcode->op16[0].opcode;
6987 csky_insn.max = JUNCD_DISP32_LEN;
6988 csky_insn.isize = 2;
6989 }
6990 else
6991 {
6992 /* Generate relax with condition. */
6993 csky_insn.output = frag_var (rs_machine_dependent,
6994 UNCD_DISP16_LEN,
6995 UNCD_DISP10_LEN,
6996 UNCD_DISP10,
6997 csky_insn.e1.X_add_symbol,
6998 csky_insn.e1.X_add_number,
6999 0);
7000 csky_insn.isize = 2;
7001 csky_insn.max = UNCD_DISP16_LEN;
7002 csky_insn.inst = csky_insn.opcode->op16[0].opcode;
7003
7004 }
7005 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
5b7c81bd 7006 return true;
b8891f8d
AJ
7007}
7008
7009#define SIZE_V2_MOVI16(x) ((addressT)x <= 0xff)
7010#define SIZE_V2_MOVI32(x) ((addressT)x <= 0xffff)
7011#define SIZE_V2_MOVIH(x) ((addressT)x <= 0xffffffff && (((addressT)x & 0xffff) == 0))
7012
5b7c81bd 7013bool
b8891f8d
AJ
7014v2_work_lrw (void)
7015{
7016 int reg = csky_insn.val[0];
7017 int output_literal = csky_insn.val[1];
7018 int is_done = 0;
7019
7020 /* If the second operand is O_constant, We can use movi/movih
7021 instead of lrw. */
7022 if (csky_insn.e1.X_op == O_constant)
7023 {
7024 /* 801 only has movi16. */
7025 if (SIZE_V2_MOVI16 (csky_insn.e1.X_add_number) && reg < 8)
7026 {
7027 /* movi16 instead. */
7028 csky_insn.output = frag_more (2);
7029 csky_insn.inst = (CSKYV2_INST_MOVI16 | (reg << 8)
7030 | (csky_insn.e1.X_add_number));
7031 csky_insn.isize = 2;
7032 is_done = 1;
7033 }
7034 else if (SIZE_V2_MOVI32 (csky_insn.e1.X_add_number)
7035 && !IS_CSKY_ARCH_801 (mach_flag))
7036 {
7037 /* movi32 instead. */
7038 csky_insn.output = frag_more (4);
7039 csky_insn.inst = (CSKYV2_INST_MOVI32 | (reg << 16)
7040 | (csky_insn.e1.X_add_number));
7041 csky_insn.isize = 4;
7042 is_done = 1;
7043 }
7044 else if (SIZE_V2_MOVIH (csky_insn.e1.X_add_number)
7045 && !IS_CSKY_ARCH_801 (mach_flag))
7046 {
7047 /* movih instead. */
7048 csky_insn.output = frag_more (4);
7049 csky_insn.inst = (CSKYV2_INST_MOVIH | (reg << 16)
7050 | ((csky_insn.e1.X_add_number >> 16) & 0xffff));
7051 csky_insn.isize = 4;
7052 is_done = 1;
7053 }
7054 }
7055
7056 if (is_done)
7057 {
7058 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
5b7c81bd 7059 return true;
b8891f8d
AJ
7060 }
7061
7062 if (output_literal)
7063 {
1feede9b 7064 struct literal *p = enter_literal (&csky_insn.e1, 0, 0, 0);
b8891f8d
AJ
7065 /* Create a reference to pool entry. */
7066 csky_insn.e1.X_op = O_symbol;
7067 csky_insn.e1.X_add_symbol = poolsym;
1feede9b 7068 csky_insn.e1.X_add_number = p->offset << 2;
b8891f8d
AJ
7069 }
7070 /* If 16bit force. */
7071 if (csky_insn.flag_force == INSN_OPCODE16F)
7072 {
7073 /* Generate fixup. */
7074 if (reg > 7)
7075 {
7076 csky_show_error (ERROR_UNDEFINE, 0,
7077 (void *)"The register is out of range.", NULL);
5b7c81bd 7078 return false;
b8891f8d
AJ
7079 }
7080 csky_insn.isize = 2;
7081 csky_insn.output = frag_more (2);
7082
7083 if (insn_reloc == BFD_RELOC_CKCORE_TLS_GD32
7084 || insn_reloc == BFD_RELOC_CKCORE_TLS_LDM32
7085 || insn_reloc == BFD_RELOC_CKCORE_TLS_IE32)
7086 {
7087 literal_insn_offset->tls_addend.frag = frag_now;
7088 literal_insn_offset->tls_addend.offset
7089 = csky_insn.output - frag_now->fr_literal;
7090 }
7091 csky_insn.inst = csky_insn.opcode->op16[0].opcode | (reg << 5);
7092 csky_insn.max = 4;
7093 fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
7094 2, &csky_insn.e1, 1, BFD_RELOC_CKCORE_PCREL_IMM7BY4);
7095 }
7096 else if (csky_insn.flag_force == INSN_OPCODE32F)
7097 {
7098 csky_insn.isize = 4;
7099 csky_insn.output = frag_more (4);
7100 if (insn_reloc == BFD_RELOC_CKCORE_TLS_GD32
7101 || insn_reloc == BFD_RELOC_CKCORE_TLS_LDM32
7102 || insn_reloc == BFD_RELOC_CKCORE_TLS_IE32)
7103 {
7104 literal_insn_offset->tls_addend.frag = frag_now;
7105 literal_insn_offset->tls_addend.offset
7106 = csky_insn.output - frag_now->fr_literal;
7107 }
7108 csky_insn.inst = csky_insn.opcode->op32[0].opcode | (reg << 16);
7109 fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
7110 4, &csky_insn.e1, 1, BFD_RELOC_CKCORE_PCREL_IMM16BY4);
7111 }
7112 else if (!is_done)
7113 {
7114 if (reg < 8)
7115 {
7116 csky_insn.isize = 2;
7117
7118 if (insn_reloc == BFD_RELOC_CKCORE_TLS_GD32
7119 || insn_reloc == BFD_RELOC_CKCORE_TLS_LDM32
7120 || insn_reloc == BFD_RELOC_CKCORE_TLS_IE32)
7121 literal_insn_offset->tls_addend.frag = frag_now;
7122
7123 csky_insn.output = frag_var (rs_machine_dependent,
7124 LRW_DISP16_LEN,
7125 LRW_DISP7_LEN,
7126 (do_extend_lrw
7127 ? LRW2_DISP8 : LRW_DISP7),
7128 csky_insn.e1.X_add_symbol,
7129 csky_insn.e1.X_add_number, 0);
7130 if (insn_reloc == BFD_RELOC_CKCORE_TLS_GD32
7131 || insn_reloc == BFD_RELOC_CKCORE_TLS_LDM32
7132 || insn_reloc == BFD_RELOC_CKCORE_TLS_IE32)
7133 {
7134 if (literal_insn_offset->tls_addend.frag->fr_next != frag_now)
7135 literal_insn_offset->tls_addend.frag
7136 = literal_insn_offset->tls_addend.frag->fr_next;
7137 literal_insn_offset->tls_addend.offset
7138 = (csky_insn.output
7139 - literal_insn_offset->tls_addend.frag->fr_literal);
7140 }
7141 csky_insn.inst = csky_insn.opcode->op16[0].opcode | (reg << 5);
7142 csky_insn.max = LRW_DISP16_LEN;
7143 csky_insn.isize = 2;
7144 }
7145 else
7146 {
7147 csky_insn.isize = 4;
7148 csky_insn.output = frag_more (4);
7149 if (insn_reloc == BFD_RELOC_CKCORE_TLS_GD32
7150 || insn_reloc == BFD_RELOC_CKCORE_TLS_LDM32
7151 || insn_reloc == BFD_RELOC_CKCORE_TLS_IE32)
7152 {
7153 literal_insn_offset->tls_addend.frag = frag_now;
7154 literal_insn_offset->tls_addend.offset
7155 = csky_insn.output - frag_now->fr_literal;
7156 }
7157 csky_insn.inst = csky_insn.opcode->op32[0].opcode | (reg << 16);
7158 fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
7159 4, &csky_insn.e1, 1, BFD_RELOC_CKCORE_PCREL_IMM16BY4);
7160 }
7161 }
7162
7163 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
5b7c81bd 7164 return true;
b8891f8d
AJ
7165}
7166
5b7c81bd 7167bool
b8891f8d
AJ
7168v2_work_lrsrsw (void)
7169{
7170 int reg = csky_insn.val[0];
7171 csky_insn.output = frag_more (4);
7172 csky_insn.inst = csky_insn.opcode->op32[0].opcode | (reg << 21);
7173 csky_insn.isize = 4;
7174
7175 switch (insn_reloc)
7176 {
7177 case BFD_RELOC_CKCORE_GOT32:
7178 fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
7179 4, &csky_insn.e1, 0, BFD_RELOC_CKCORE_GOT_IMM18BY4);
7180 break;
7181 case BFD_RELOC_CKCORE_PLT32:
7182 fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
7183 4, &csky_insn.e1, 0, BFD_RELOC_CKCORE_PLT_IMM18BY4);
7184 break;
7185 default:
7186 fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
7187 4, &csky_insn.e1, 1, BFD_RELOC_CKCORE_DOFFSET_IMM18BY4);
7188 break;
7189 }
7190 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
5b7c81bd 7191 return true;
b8891f8d
AJ
7192}
7193
5b7c81bd 7194bool
b8891f8d
AJ
7195v2_work_jbsr (void)
7196{
7197 if (do_force2bsr
7198 || IS_CSKY_ARCH_801 (mach_flag)
7199 || IS_CSKY_ARCH_802 (mach_flag))
7200 {
7201 csky_insn.output = frag_more (4);
7202 fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
7203 4, &csky_insn.e1, 1, BFD_RELOC_CKCORE_PCREL_IMM26BY2);
7204 csky_insn.isize = 4;
7205 csky_insn.inst = CSKYV2_INST_BSR32;
7206 }
7207 else
7208 {
1feede9b 7209 struct literal *p = enter_literal (&csky_insn.e1, 0, 0, 0);
b8891f8d
AJ
7210 csky_insn.output = frag_more (4);
7211 csky_insn.e1.X_op = O_symbol;
7212 csky_insn.e1.X_add_symbol = poolsym;
1feede9b 7213 csky_insn.e1.X_add_number = p->offset << 2;
b8891f8d
AJ
7214 fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
7215 4, &csky_insn.e1, 1, BFD_RELOC_CKCORE_PCREL_IMM16BY4);
7216 if (do_jsri2bsr || IS_CSKY_ARCH_810 (mach_flag))
7217 fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
7218 4,
7219 &(litpool + (csky_insn.e1.X_add_number >> 2))->e,
7220 1,
7221 BFD_RELOC_CKCORE_PCREL_JSR_IMM26BY2);
7222 csky_insn.inst = CSKYV2_INST_JSRI32;
7223 csky_insn.isize = 4;
7224 if (IS_CSKY_ARCH_810 (mach_flag))
7225 {
7226 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
7227 csky_insn.output = frag_more (4);
7228 dwarf2_emit_insn (0);
7229 /* Insert "mov r0, r0". */
7230 csky_insn.inst = CSKYV2_INST_MOV_R0_R0;
7231 csky_insn.max = 8;
7232 }
7233 }
7234 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
7235
5b7c81bd 7236 return true;
b8891f8d
AJ
7237}
7238
5b7c81bd 7239bool
b8891f8d
AJ
7240v2_work_jsri (void)
7241{
7242 /* dump literal. */
1feede9b 7243 struct literal *p = enter_literal (&csky_insn.e1, 1, 0, 0);
b8891f8d
AJ
7244 csky_insn.e1.X_op = O_symbol;
7245 csky_insn.e1.X_add_symbol = poolsym;
1feede9b 7246 csky_insn.e1.X_add_number = p->offset << 2;
b8891f8d
AJ
7247
7248 /* Generate relax or reloc if necessary. */
7249 csky_generate_frags ();
7250 /* Generate the insn by mask. */
7251 csky_generate_insn ();
7252 /* Write inst to frag. */
7253 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
7254 /* Control 810 not to generate jsri. */
7255 if (IS_CSKY_ARCH_810 (mach_flag))
7256 {
7257 /* Look at adding the R_PCREL_JSRIMM26BY2.
7258 For 'jbsr .L1', this reloc type's symbol
7259 is bound to '.L1', isn't bound to literal pool. */
7260 fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
1feede9b 7261 4, &p->e, 1,
b8891f8d
AJ
7262 BFD_RELOC_CKCORE_PCREL_JSR_IMM26BY2);
7263 csky_insn.output = frag_more (4);
7264 dwarf2_emit_insn (0);
7265 /* The opcode of "mov32 r0,r0". */
7266 csky_insn.inst = CSKYV2_INST_MOV_R0_R0;
7267 /* The effect of this value is to check literal. */
7268 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
7269 csky_insn.max = 8;
7270 }
5b7c81bd 7271 return true;
b8891f8d
AJ
7272}
7273
5b7c81bd 7274bool
b8891f8d
AJ
7275v2_work_movih (void)
7276{
7277 int rz = csky_insn.val[0];
7278 csky_insn.output = frag_more (4);
7279 csky_insn.inst = csky_insn.opcode->op32[0].opcode | (rz << 16);
7280 if (csky_insn.e1.X_op == O_constant)
7281 {
7282 if (csky_insn.e1.X_unsigned == 1 && csky_insn.e1.X_add_number > 0xffff)
7283 {
7284 csky_show_error (ERROR_IMM_OVERFLOW, 2, NULL, NULL);
5b7c81bd 7285 return false;
b8891f8d
AJ
7286 }
7287 else if (csky_insn.e1.X_unsigned == 0 && csky_insn.e1.X_add_number < 0)
7288 {
7289 csky_show_error (ERROR_IMM_OVERFLOW, 2, NULL, NULL);
5b7c81bd 7290 return false;
b8891f8d
AJ
7291 }
7292 else
7293 csky_insn.inst |= (csky_insn.e1.X_add_number & 0xffff);
7294 }
7295 else if (csky_insn.e1.X_op == O_right_shift
7296 || (csky_insn.e1.X_op == O_symbol && insn_reloc != BFD_RELOC_NONE))
7297 {
7298 if (csky_insn.e1.X_op_symbol != 0
8d1015a8
AM
7299 && symbol_constant_p (csky_insn.e1.X_op_symbol)
7300 && S_GET_SEGMENT (csky_insn.e1.X_op_symbol) == absolute_section
7301 && 16 == S_GET_VALUE (csky_insn.e1.X_op_symbol))
b8891f8d
AJ
7302 {
7303 csky_insn.e1.X_op = O_symbol;
7304 if (insn_reloc == BFD_RELOC_CKCORE_GOT32)
7305 insn_reloc = BFD_RELOC_CKCORE_GOT_HI16;
7306 else if (insn_reloc == BFD_RELOC_CKCORE_PLT32)
7307 insn_reloc = BFD_RELOC_CKCORE_PLT_HI16;
7308 else if (insn_reloc == BFD_RELOC_CKCORE_GOTPC)
7309 insn_reloc = BFD_RELOC_CKCORE_GOTPC_HI16;
7310 else if (insn_reloc == BFD_RELOC_CKCORE_GOTOFF)
7311 insn_reloc = BFD_RELOC_CKCORE_GOTOFF_HI16;
7312 else
7313 insn_reloc = BFD_RELOC_CKCORE_ADDR_HI16;
7314 fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
7315 4, &csky_insn.e1, 0, insn_reloc);
7316 }
7317 else
7318 {
7319 void *arg = (void *)"the second operand must be \"SYMBOL >> 16\"";
7320 csky_show_error (ERROR_UNDEFINE, 0, arg, NULL);
5b7c81bd 7321 return false;
b8891f8d
AJ
7322 }
7323 }
7324 csky_insn.isize = 4;
7325 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
7326
5b7c81bd 7327 return true;
b8891f8d
AJ
7328}
7329
5b7c81bd 7330bool
b8891f8d
AJ
7331v2_work_ori (void)
7332{
7333 int rz = csky_insn.val[0];
7334 int rx = csky_insn.val[1];
7335 csky_insn.output = frag_more (4);
7336 csky_insn.inst = csky_insn.opcode->op32[0].opcode | (rz << 21) | (rx << 16);
7337 if (csky_insn.e1.X_op == O_constant)
7338 {
7339 if (csky_insn.e1.X_add_number <= 0xffff
7340 && csky_insn.e1.X_add_number >= 0)
7341 csky_insn.inst |= csky_insn.e1.X_add_number;
7342 else
7343 {
7344 csky_show_error (ERROR_IMM_OVERFLOW, 3, NULL, NULL);
5b7c81bd 7345 return false;
b8891f8d
AJ
7346 }
7347 }
7348 else if (csky_insn.e1.X_op == O_bit_and)
7349 {
8d1015a8
AM
7350 if (symbol_constant_p (csky_insn.e1.X_op_symbol)
7351 && S_GET_SEGMENT (csky_insn.e1.X_op_symbol) == absolute_section
7352 && 0xffff == S_GET_VALUE (csky_insn.e1.X_op_symbol))
b8891f8d
AJ
7353 {
7354 csky_insn.e1.X_op = O_symbol;
7355 if (insn_reloc == BFD_RELOC_CKCORE_GOT32)
7356 insn_reloc = BFD_RELOC_CKCORE_GOT_LO16;
7357 else if (insn_reloc == BFD_RELOC_CKCORE_PLT32)
7358 insn_reloc = BFD_RELOC_CKCORE_PLT_LO16;
7359 else if (insn_reloc == BFD_RELOC_CKCORE_GOTPC)
7360 insn_reloc = BFD_RELOC_CKCORE_GOTPC_LO16;
7361 else if (insn_reloc == BFD_RELOC_CKCORE_GOTOFF)
7362 insn_reloc = BFD_RELOC_CKCORE_GOTOFF_LO16;
7363 else
7364 insn_reloc = BFD_RELOC_CKCORE_ADDR_LO16;
7365 fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
7366 4, &csky_insn.e1, 0, insn_reloc);
7367 }
7368 else
7369 {
7370 void *arg = (void *)"the third operand must be \"SYMBOL & 0xffff\"";
7371 csky_show_error (ERROR_UNDEFINE, 0, arg, NULL);
5b7c81bd 7372 return false;
b8891f8d
AJ
7373 }
7374 }
7375 csky_insn.isize = 4;
7376 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
5b7c81bd 7377 return true;
b8891f8d
AJ
7378}
7379
7380/* Helper function to encode a single/double floating point constant
7381 into the instruction word for fmovis and fmovid instructions.
7382 The constant is in its IEEE single/double precision representation
7383 and is repacked into the internal 13-bit representation for these
7384 instructions with a diagnostic for overflow. Note that there is no
7385 rounding when converting to the smaller format, just an error if there
7386 is excess precision or the number is too small/large to be represented. */
7387
5b7c81bd 7388bool
b8891f8d
AJ
7389float_work_fmovi (void)
7390{
7391 int rx = csky_insn.val[0];
7392
7393 /* We already converted the float constant to the internal 13-bit
7394 representation so we just need to OR it in here. */
7395 csky_insn.inst = csky_insn.opcode->op32[0].opcode | rx;
7396 csky_insn.inst |= (uint32_t) csky_insn.e1.X_add_number;
7397
7398 csky_insn.output = frag_more (4);
7399 csky_insn.isize = 4;
7400 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
5b7c81bd 7401 return true;
b8891f8d
AJ
7402}
7403
1feede9b
CQ
7404/* Like float_work_fmovi, but for FPUV3 fmovi.16, fmovi.32 and fmovi.64
7405 instructions. */
7406
5b7c81bd 7407bool
1feede9b
CQ
7408float_work_fpuv3_fmovi (void)
7409{
7410 int rx = csky_insn.val[0];
7411 int idx = csky_insn.opcode_idx;
7412 int imm4 = 0;
7413 int imm8 = 0;
7414 int sign = 0;
7415
7416 csky_insn.inst = csky_insn.opcode->op32[idx].opcode | rx;
7417
7418 if (csky_insn.opcode->op32[idx].operand_num == 3)
7419 {
7420 /* fmovi.xx frz, imm9, imm4. */
7421 imm8 = csky_insn.val[1];
7422 imm4 = csky_insn.val[2];
7423 if (imm8 < 0 || (imm8 & 0x80000000))
7424 {
7425 sign = (1 << 5);
7426 imm8 = 0 - imm8;
7427 }
7428
7429 if (imm8 > 255)
7430 {
7431 csky_show_error (ERROR_IMM_OVERFLOW, 2, NULL, NULL);
5b7c81bd 7432 return false;
1feede9b
CQ
7433 }
7434
7435 /* imm8 store at bit [25:20] and [9:8]. */
7436 /* imm4 store at bit [19:16]. */
7437 /* sign store at bit [5]. */
7438 csky_insn.inst = csky_insn.inst
7439 | ((imm8 & 0x3) << 8)
7440 | ((imm8 & 0xfc) << 18)
7441 | ((imm4 & 0xf) << 16)
7442 | sign;
7443 }
7444 else
7445 {
7446 csky_insn.inst |= (uint32_t) csky_insn.e1.X_add_number;
7447 }
7448
7449 csky_insn.output = frag_more(4);
7450 csky_insn.isize = 4;
7451 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
5b7c81bd 7452 return true;
1feede9b
CQ
7453}
7454
5b7c81bd 7455bool
b8891f8d
AJ
7456dsp_work_bloop (void)
7457{
7458 int reg = csky_insn.val[0];
7459 csky_insn.output = frag_more (4);
7460 csky_insn.inst = csky_insn.opcode->op32[0].opcode | (reg << 16);
7461 csky_insn.isize = 4;
7462
d285ba8d
CQ
7463 if (csky_insn.number == 3
7464 && csky_insn.e1.X_op == O_symbol
b8891f8d
AJ
7465 && csky_insn.e2.X_op == O_symbol)
7466 {
7467 fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
7468 4, &csky_insn.e1, 1,
7469 BFD_RELOC_CKCORE_PCREL_BLOOP_IMM12BY4);
7470 fix_new_exp (frag_now, csky_insn.output - frag_now->fr_literal,
7471 4, &csky_insn.e2, 1,
7472 BFD_RELOC_CKCORE_PCREL_BLOOP_IMM4BY4);
7473 }
d285ba8d
CQ
7474 else if (csky_insn.number == 2
7475 && csky_insn.e1.X_op == O_symbol)
7476 {
7477 fix_new_exp (frag_now, csky_insn.output-frag_now->fr_literal,
7478 4, &csky_insn.e1, 1,
7479 BFD_RELOC_CKCORE_PCREL_BLOOP_IMM12BY4);
7480 if (csky_insn.last_isize == 2)
7481 csky_insn.inst |= (0xf << 12);
7482 else if (csky_insn.last_isize != 0)
7483 csky_insn.inst |= (0xe << 12);
7484 else
7485 {
7486 void *arg = (void *)"bloop can not be the first instruction"\
7487 "when the end label is not specified.\n";
7488 csky_show_error (ERROR_UNDEFINE, 0, arg, NULL);
7489 }
7490 }
b8891f8d
AJ
7491
7492 csky_write_insn (csky_insn.output, csky_insn.inst, csky_insn.isize);
5b7c81bd 7493 return true;
b8891f8d
AJ
7494}
7495
5b7c81bd 7496bool
1feede9b
CQ
7497float_work_fpuv3_fstore(void)
7498{
7499 /* Generate relax or reloc if necessary. */
7500 csky_generate_frags ();
7501 /* Generate the insn by mask. */
7502 csky_generate_insn ();
7503 /* Write inst to frag. */
7504 csky_write_insn (csky_insn.output,
7505 csky_insn.inst,
7506 csky_insn.isize);
7507
7508
5b7c81bd 7509 return true;
1feede9b 7510}
b8891f8d 7511
5b7c81bd 7512bool
afdcafe8
CQ
7513v2_work_addc (void)
7514{
7515 int reg1;
7516 int reg2;
7517 int reg3 = 0;
7518 int is_16_bit = 0;
7519
7520 reg1 = csky_insn.val[0];
7521 reg2 = csky_insn.val[1];
7522 if (csky_insn.number == 2)
7523 {
7524 if (reg1 > 15 || reg2 > 15)
7525 {
7526 is_16_bit = 0;
7527 reg3 = reg1;
7528 }
7529 else
7530 is_16_bit = 1;
7531 }
7532 else
7533 {
7534 reg3 = csky_insn.val[2];
7535 if (reg1 > 15 || reg2 > 15 || reg3 > 15)
7536 is_16_bit = 0;
7537 else if (reg1 == reg2 || reg1 == reg3)
7538 {
7539 is_16_bit = 1;
7540 reg2 = (reg1 == reg2) ? reg3 : reg2;
7541 }
7542 else
7543 is_16_bit = 0;
7544 }
7545
7546 if (is_16_bit
7547 && csky_insn.flag_force != INSN_OPCODE32F)
7548 {
7549 csky_insn.isize = 2;
7550 csky_insn.inst = csky_insn.opcode->op16[0].opcode
7551 | (reg1 << 6) | (reg2 << 2);
7552 }
7553 else if (csky_insn.flag_force != INSN_OPCODE16F)
7554 {
7555 csky_insn.isize = 4;
7556 csky_insn.inst = csky_insn.opcode->op32[0].opcode
7557 | (reg1 << 0) | (reg2 << 16) | (reg3 << 21);
7558 }
7559 else
7560 {
7561 SET_ERROR_INTEGER (ERROR_REG_OVER_RANGE, reg1 > 15 ? reg1 : reg2);
7562 csky_show_error (ERROR_REG_OVER_RANGE, 0, 0, NULL);
7563 }
7564
7565 /* Generate relax or reloc if necessary. */
7566 csky_generate_frags ();
7567 /* Write inst to frag. */
7568 csky_write_insn (csky_insn.output,
7569 csky_insn.inst,
7570 csky_insn.isize);
7571
5b7c81bd 7572 return true;
afdcafe8
CQ
7573}
7574
b8891f8d
AJ
7575/* The following are for assembler directive handling. */
7576
7577/* Helper function to adjust constant pool counts when we emit a
7578 data directive in the text section. FUNC is one of the standard
7579 gas functions to handle these directives, like "stringer" for the
7580 .string directive, and ARG is the argument to FUNC. csky_pool_count
7581 essentially wraps the call with the constant pool magic. */
7582
7583static void
7584csky_pool_count (void (*func) (int), int arg)
7585{
7586 const fragS *curr_frag = frag_now;
7587 offsetT added = -frag_now_fix_octets ();
7588
7589 (*func) (arg);
7590
7591 while (curr_frag != frag_now)
7592 {
7593 added += curr_frag->fr_fix;
7594 curr_frag = curr_frag->fr_next;
7595 }
7596
7597 added += frag_now_fix_octets ();
7598 poolspan += added;
7599}
7600
7601/* Support the .literals directive. */
7602static void
7603csky_s_literals (int ignore ATTRIBUTE_UNUSED)
7604{
7605 dump_literals (0);
7606 demand_empty_rest_of_line ();
7607}
7608
7609/* Support the .string, etc directives. */
7610static void
7611csky_stringer (int append_zero)
7612{
7613 if (now_seg == text_section)
7614 csky_pool_count (stringer, append_zero);
7615 else
7616 stringer (append_zero);
7617
7618 /* We call check_literals here in case a large number of strings are
7619 being placed into the text section with a sequence of stringer
7620 directives. In theory we could be upsetting something if these
7621 strings are actually in an indexed table instead of referenced by
7622 individual labels. Let us hope that that never happens. */
7623 check_literals (2, 0);
7624}
7625
7626/* Support integer-mode constructors like .word, .byte, etc. */
7627
7628static void
7629csky_cons (int nbytes)
7630{
7631 mapping_state (MAP_DATA);
7632 if (nbytes == 4) /* @GOT. */
7633 {
7634 do
7635 {
7636 bfd_reloc_code_real_type reloc;
7637 expressionS exp;
7638
7639 reloc = BFD_RELOC_NONE;
7640 expression (&exp);
7641 lex_got (&reloc, NULL);
7642
7643 if (exp.X_op == O_symbol && reloc != BFD_RELOC_NONE)
7644 {
7645 reloc_howto_type *howto
7646 = bfd_reloc_type_lookup (stdoutput, reloc);
7647 int size = bfd_get_reloc_size (howto);
7648
7649 if (size > nbytes)
7650 as_bad (ngettext ("%s relocations do not fit in %d byte",
7651 "%s relocations do not fit in %d bytes",
7652 nbytes),
7653 howto->name, nbytes);
7654 else
7655 {
7656 register char *p = frag_more ((int) nbytes);
7657 int offset = nbytes - size;
7658
7659 fix_new_exp (frag_now,
7660 p - frag_now->fr_literal + offset,
7661 size, &exp, 0, reloc);
7662 }
7663 }
7664 else
7665 emit_expr (&exp, (unsigned int) nbytes);
7666 if (now_seg == text_section)
7667 poolspan += nbytes;
7668 }
7669 while (*input_line_pointer++ == ',');
7670
7671 /* Put terminator back into stream. */
7672 input_line_pointer --;
7673 demand_empty_rest_of_line ();
7674
7675 return;
7676 }
7677
7678 if (now_seg == text_section)
7679 csky_pool_count (cons, nbytes);
7680 else
7681 cons (nbytes);
7682
7683 /* In theory we ought to call check_literals (2,0) here in case
7684 we need to dump the literal table. We cannot do this however,
7685 as the directives that we are intercepting may be being used
7686 to build a switch table, and we must not interfere with its
7687 contents. Instead we cross our fingers and pray... */
7688}
7689
7690/* Support floating-mode constant directives like .float and .double. */
7691
7692static void
7693csky_float_cons (int float_type)
7694{
7695 mapping_state (MAP_DATA);
7696 if (now_seg == text_section)
7697 csky_pool_count (float_cons, float_type);
7698 else
7699 float_cons (float_type);
7700
7701 /* See the comment in csky_cons () about calling check_literals.
7702 It is unlikely that a switch table will be constructed using
7703 floating point values, but it is still likely that an indexed
7704 table of floating point constants is being created by these
7705 directives, so again we must not interfere with their placement. */
7706}
7707
7708/* Support the .fill directive. */
7709
7710static void
7711csky_fill (int ignore)
7712{
7713 if (now_seg == text_section)
7714 csky_pool_count (s_fill, ignore);
7715 else
7716 s_fill (ignore);
7717
7718 check_literals (2, 0);
7719}
7720
7721/* Handle the section changing pseudo-ops. These call through to the
7722 normal implementations, but they dump the literal pool first. */
7723
7724static void
7725csky_s_text (int ignore)
7726{
7727 dump_literals (0);
7728
7729#ifdef OBJ_ELF
7730 obj_elf_text (ignore);
7731#else
7732 s_text (ignore);
7733#endif
7734}
7735
7736static void
7737csky_s_data (int ignore)
7738{
7739 dump_literals (0);
7740
7741#ifdef OBJ_ELF
7742 obj_elf_data (ignore);
7743#else
7744 s_data (ignore);
7745#endif
7746}
7747
7748static void
7749csky_s_section (int ignore)
7750{
7751 /* Scan forwards to find the name of the section. If the section
7752 being switched to is ".line" then this is a DWARF1 debug section
7753 which is arbitrarily placed inside generated code. In this case
7754 do not dump the literal pool because it is a) inefficient and
7755 b) would require the generation of extra code to jump around the
7756 pool. */
7757 char * ilp = input_line_pointer;
7758
7759 while (*ilp != 0 && ISSPACE (*ilp))
7760 ++ ilp;
7761
d34049e8 7762 if (startswith (ilp, ".line")
b8891f8d
AJ
7763 && (ISSPACE (ilp[5]) || *ilp == '\n' || *ilp == '\r'))
7764 ;
7765 else
7766 dump_literals (0);
7767
7768#ifdef OBJ_ELF
7769 obj_elf_section (ignore);
7770#endif
7771#ifdef OBJ_COFF
7772 obj_coff_section (ignore);
7773#endif
7774}
7775
7776static void
7777csky_s_bss (int needs_align)
7778{
7779 dump_literals (0);
7780 s_lcomm_bytes (needs_align);
7781}
7782
7783#ifdef OBJ_ELF
7784static void
7785csky_s_comm (int needs_align)
7786{
7787 dump_literals (0);
7788 obj_elf_common (needs_align);
7789}
7790#endif
7791
7792/* Handle the .no_literal_dump directive. */
7793
7794static void
7795csky_noliteraldump (int ignore ATTRIBUTE_UNUSED)
7796{
7797 do_noliteraldump = 1;
7798 int insn_num = get_absolute_expression ();
7799 /* The insn after '.no_literal_dump insn_num' is insn1,
7800 Don't dump literal pool between insn1 and insn(insn_num+1)
7801 The insn cannot be the insn generate literal, like lrw & jsri. */
7802 check_literals (0, insn_num * 2);
7803}
7804
7805/* Handle the .align directive.
7806 We must check literals before doing alignment. For example, if
7807 '.align n', add (2^n-1) to poolspan and check literals. */
7808
7809static void
7810csky_s_align_ptwo (int arg)
7811{
7812 /* Get the .align's first absolute number. */
7813 char * temp_pointer = input_line_pointer;
7814 int align = get_absolute_expression ();
7815 check_literals (0, (1 << align) - 1);
7816 input_line_pointer = temp_pointer;
7817
7818 /* Do alignment. */
7819 s_align_ptwo (arg);
7820}
7821
7822/* Handle the .stack_size directive. */
7823
7824static void
7825csky_stack_size (int arg ATTRIBUTE_UNUSED)
7826{
7827 expressionS exp;
7828 stack_size_entry *sse
7829 = (stack_size_entry *) xcalloc (1, sizeof (stack_size_entry));
7830
7831 expression (&exp);
7832 if (exp.X_op == O_symbol)
7833 sse->function = exp.X_add_symbol;
7834 else
7835 {
7836 as_bad (_("the first operand must be a symbol"));
7837 ignore_rest_of_line ();
7838 free (sse);
7839 return;
7840 }
7841
7842 SKIP_WHITESPACE ();
7843 if (*input_line_pointer != ',')
7844 {
7845 as_bad (_("missing stack size"));
7846 ignore_rest_of_line ();
7847 free (sse);
7848 return;
7849 }
7850
7851 ++input_line_pointer;
7852 expression (&exp);
7853 if (exp.X_op == O_constant)
7854 {
7855 if (exp.X_add_number < 0 || exp.X_add_number > (offsetT)0xffffffff)
7856 {
7857
7858 as_bad (_("value not in range [0, 0xffffffff]"));
7859 ignore_rest_of_line ();
7860 free (sse);
7861 return;
7862 }
7863 else
7864 sse->stack_size = exp.X_add_number;
7865 }
7866 else
7867 {
7868 as_bad (_("operand must be a constant"));
7869 ignore_rest_of_line ();
7870 free (sse);
7871 return;
7872 }
7873
7874 if (*last_stack_size_data != NULL)
7875 last_stack_size_data = &((*last_stack_size_data)->next);
7876
7877 *last_stack_size_data = sse;
7878}
7879
7880/* This table describes all the machine specific pseudo-ops the assembler
7881 has to support. The fields are:
7882 pseudo-op name without dot
7883 function to call to execute this pseudo-op
7884 Integer arg to pass to the function. */
7885
7886const pseudo_typeS md_pseudo_table[] =
7887{
7888 { "export", s_globl, 0 },
7889 { "import", s_ignore, 0 },
7890 { "literals", csky_s_literals, 0 },
7891 { "page", listing_eject, 0 },
7892
7893 /* The following are to intercept the placement of data into the text
7894 section (eg addresses for a switch table), so that the space they
7895 occupy can be taken into account when deciding whether or not to
7896 dump the current literal pool.
7897 XXX - currently we do not cope with the .space and .dcb.d directives. */
7898 { "ascii", csky_stringer, 8 + 0 },
7899 { "asciz", csky_stringer, 8 + 1 },
7900 { "byte", csky_cons, 1 },
7901 { "dc", csky_cons, 2 },
7902 { "dc.b", csky_cons, 1 },
7903 { "dc.d", csky_float_cons, 'd'},
7904 { "dc.l", csky_cons, 4 },
7905 { "dc.s", csky_float_cons, 'f'},
7906 { "dc.w", csky_cons, 2 },
7907 { "dc.x", csky_float_cons, 'x'},
7908 { "double", csky_float_cons, 'd'},
7909 { "float", csky_float_cons, 'f'},
7910 { "hword", csky_cons, 2 },
7911 { "int", csky_cons, 4 },
7912 { "long", csky_cons, 4 },
7913 { "octa", csky_cons, 16 },
7914 { "quad", csky_cons, 8 },
7915 { "short", csky_cons, 2 },
7916 { "single", csky_float_cons, 'f'},
7917 { "string", csky_stringer, 8 + 1 },
7918 { "word", csky_cons, 4 },
7919 { "fill", csky_fill, 0 },
7920
7921 /* Allow for the effect of section changes. */
7922 { "text", csky_s_text, 0 },
7923 { "data", csky_s_data, 0 },
7924 { "bss", csky_s_bss, 1 },
7925#ifdef OBJ_ELF
7926 { "comm", csky_s_comm, 0 },
7927#endif
7928 { "section", csky_s_section, 0 },
7929 { "section.s", csky_s_section, 0 },
7930 { "sect", csky_s_section, 0 },
7931 { "sect.s", csky_s_section, 0 },
7932 /* When ".no_literal_dump N" is in front of insn1,
7933 and instruction sequence is:
7934 insn1
7935 insn2
7936 ......
7937 insnN+1
7938 it means literals will not dump between insn1 and insnN+1
7939 The insn cannot itself generate literal, like lrw & jsri. */
7940 { "no_literal_dump", csky_noliteraldump, 0 },
7941 { "align", csky_s_align_ptwo, 0 },
7942 { "stack_size", csky_stack_size, 0 },
7943 {0, 0, 0}
7944};
7945
7946/* Implement tc_cfi_frame_initial_instructions. */
7947
7948void
7949csky_cfi_frame_initial_instructions (void)
7950{
7951 int sp_reg = IS_CSKY_V1 (mach_flag) ? 0 : 14;
7952 cfi_add_CFA_def_cfa_register (sp_reg);
7953}
7954
7955/* Implement tc_regname_to_dw2regnum. */
7956
7957int
7958tc_csky_regname_to_dw2regnum (char *regname)
7959{
7960 int reg_num = -1;
7961 int len;
7962
7963 /* FIXME the reg should be parsed according to
7964 the abi version. */
7965 reg_num = csky_get_reg_val (regname, &len);
7966 return reg_num;
7967}