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