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