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