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