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