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