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