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