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