tc-crx.c revision 1.1.1.3 1 1.1 skrll /* tc-crx.c -- Assembler code for the CRX CPU core.
2 1.1.1.3 christos Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012
3 1.1.1.2 christos Free Software Foundation, Inc.
4 1.1 skrll
5 1.1 skrll Contributed by Tomer Levi, NSC, Israel.
6 1.1 skrll Originally written for GAS 2.12 by Tomer Levi, NSC, Israel.
7 1.1 skrll Updates, BFDizing, GNUifying and ELF support by Tomer Levi.
8 1.1 skrll
9 1.1 skrll This file is part of GAS, the GNU Assembler.
10 1.1 skrll
11 1.1 skrll GAS is free software; you can redistribute it and/or modify
12 1.1 skrll it under the terms of the GNU General Public License as published by
13 1.1 skrll the Free Software Foundation; either version 3, or (at your option)
14 1.1 skrll any later version.
15 1.1 skrll
16 1.1 skrll GAS is distributed in the hope that it will be useful,
17 1.1 skrll but WITHOUT ANY WARRANTY; without even the implied warranty of
18 1.1 skrll MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 1.1 skrll GNU General Public License for more details.
20 1.1 skrll
21 1.1 skrll You should have received a copy of the GNU General Public License
22 1.1 skrll along with GAS; see the file COPYING. If not, write to the
23 1.1 skrll Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston,
24 1.1 skrll MA 02110-1301, USA. */
25 1.1 skrll
26 1.1 skrll #include "as.h"
27 1.1.1.3 christos #include "bfd_stdint.h"
28 1.1 skrll #include "safe-ctype.h"
29 1.1 skrll #include "dwarf2dbg.h"
30 1.1 skrll #include "opcode/crx.h"
31 1.1 skrll #include "elf/crx.h"
32 1.1 skrll
33 1.1 skrll /* Word is considered here as a 16-bit unsigned short int. */
34 1.1 skrll #define WORD_SHIFT 16
35 1.1 skrll
36 1.1 skrll /* Register is 4-bit size. */
37 1.1 skrll #define REG_SIZE 4
38 1.1 skrll
39 1.1 skrll /* Maximum size of a single instruction (in words). */
40 1.1 skrll #define INSN_MAX_SIZE 3
41 1.1 skrll
42 1.1 skrll /* Maximum bits which may be set in a `mask16' operand. */
43 1.1 skrll #define MAX_REGS_IN_MASK16 8
44 1.1 skrll
45 1.1 skrll /* Utility macros for string comparison. */
46 1.1 skrll #define streq(a, b) (strcmp (a, b) == 0)
47 1.1 skrll #define strneq(a, b, c) (strncmp (a, b, c) == 0)
48 1.1 skrll
49 1.1 skrll /* Assign a number NUM, shifted by SHIFT bytes, into a location
50 1.1 skrll pointed by index BYTE of array 'output_opcode'. */
51 1.1 skrll #define CRX_PRINT(BYTE, NUM, SHIFT) output_opcode[BYTE] |= (NUM << SHIFT)
52 1.1 skrll
53 1.1 skrll /* Operand errors. */
54 1.1 skrll typedef enum
55 1.1 skrll {
56 1.1 skrll OP_LEGAL = 0, /* Legal operand. */
57 1.1 skrll OP_OUT_OF_RANGE, /* Operand not within permitted range. */
58 1.1 skrll OP_NOT_EVEN, /* Operand is Odd number, should be even. */
59 1.1 skrll OP_ILLEGAL_DISPU4, /* Operand is not within DISPU4 range. */
60 1.1 skrll OP_ILLEGAL_CST4, /* Operand is not within CST4 range. */
61 1.1 skrll OP_NOT_UPPER_64KB /* Operand is not within the upper 64KB
62 1.1 skrll (0xFFFF0000-0xFFFFFFFF). */
63 1.1 skrll }
64 1.1 skrll op_err;
65 1.1 skrll
66 1.1 skrll /* Opcode mnemonics hash table. */
67 1.1 skrll static struct hash_control *crx_inst_hash;
68 1.1 skrll /* CRX registers hash table. */
69 1.1 skrll static struct hash_control *reg_hash;
70 1.1 skrll /* CRX coprocessor registers hash table. */
71 1.1 skrll static struct hash_control *copreg_hash;
72 1.1 skrll /* Current instruction we're assembling. */
73 1.1 skrll const inst *instruction;
74 1.1 skrll
75 1.1 skrll /* Global variables. */
76 1.1 skrll
77 1.1 skrll /* Array to hold an instruction encoding. */
78 1.1 skrll long output_opcode[2];
79 1.1 skrll
80 1.1 skrll /* Nonzero means a relocatable symbol. */
81 1.1 skrll int relocatable;
82 1.1 skrll
83 1.1 skrll /* A copy of the original instruction (used in error messages). */
84 1.1 skrll char ins_parse[MAX_INST_LEN];
85 1.1 skrll
86 1.1 skrll /* The current processed argument number. */
87 1.1 skrll int cur_arg_num;
88 1.1 skrll
89 1.1 skrll /* Generic assembler global variables which must be defined by all targets. */
90 1.1 skrll
91 1.1 skrll /* Characters which always start a comment. */
92 1.1 skrll const char comment_chars[] = "#";
93 1.1 skrll
94 1.1 skrll /* Characters which start a comment at the beginning of a line. */
95 1.1 skrll const char line_comment_chars[] = "#";
96 1.1 skrll
97 1.1 skrll /* This array holds machine specific line separator characters. */
98 1.1 skrll const char line_separator_chars[] = ";";
99 1.1 skrll
100 1.1 skrll /* Chars that can be used to separate mant from exp in floating point nums. */
101 1.1 skrll const char EXP_CHARS[] = "eE";
102 1.1 skrll
103 1.1 skrll /* Chars that mean this number is a floating point constant as in 0f12.456 */
104 1.1 skrll const char FLT_CHARS[] = "f'";
105 1.1 skrll
106 1.1 skrll /* Target-specific multicharacter options, not const-declared at usage. */
107 1.1 skrll const char *md_shortopts = "";
108 1.1 skrll struct option md_longopts[] =
109 1.1 skrll {
110 1.1 skrll {NULL, no_argument, NULL, 0}
111 1.1 skrll };
112 1.1 skrll size_t md_longopts_size = sizeof (md_longopts);
113 1.1 skrll
114 1.1 skrll /* This table describes all the machine specific pseudo-ops
115 1.1 skrll the assembler has to support. The fields are:
116 1.1 skrll *** Pseudo-op name without dot.
117 1.1 skrll *** Function to call to execute this pseudo-op.
118 1.1 skrll *** Integer arg to pass to the function. */
119 1.1 skrll
120 1.1 skrll const pseudo_typeS md_pseudo_table[] =
121 1.1 skrll {
122 1.1 skrll /* In CRX machine, align is in bytes (not a ptwo boundary). */
123 1.1 skrll {"align", s_align_bytes, 0},
124 1.1 skrll {0, 0, 0}
125 1.1 skrll };
126 1.1 skrll
127 1.1 skrll /* CRX relaxation table. */
128 1.1 skrll const relax_typeS md_relax_table[] =
129 1.1 skrll {
130 1.1 skrll /* bCC */
131 1.1 skrll {0xfa, -0x100, 2, 1}, /* 8 */
132 1.1 skrll {0xfffe, -0x10000, 4, 2}, /* 16 */
133 1.1 skrll {0xfffffffe, -0xfffffffe, 6, 0}, /* 32 */
134 1.1 skrll
135 1.1 skrll /* bal */
136 1.1 skrll {0xfffe, -0x10000, 4, 4}, /* 16 */
137 1.1 skrll {0xfffffffe, -0xfffffffe, 6, 0}, /* 32 */
138 1.1 skrll
139 1.1 skrll /* cmpbr/bcop */
140 1.1 skrll {0xfe, -0x100, 4, 6}, /* 8 */
141 1.1 skrll {0xfffffe, -0x1000000, 6, 0} /* 24 */
142 1.1 skrll };
143 1.1 skrll
144 1.1 skrll static void reset_vars (char *);
145 1.1 skrll static reg get_register (char *);
146 1.1 skrll static copreg get_copregister (char *);
147 1.1 skrll static argtype get_optype (operand_type);
148 1.1 skrll static int get_opbits (operand_type);
149 1.1 skrll static int get_opflags (operand_type);
150 1.1 skrll static int get_number_of_operands (void);
151 1.1 skrll static void parse_operand (char *, ins *);
152 1.1.1.2 christos static int gettrap (const char *);
153 1.1.1.2 christos static void handle_LoadStor (const char *);
154 1.1.1.2 christos static int get_cinv_parameters (const char *);
155 1.1 skrll static long getconstant (long, int);
156 1.1 skrll static op_err check_range (long *, int, unsigned int, int);
157 1.1 skrll static int getreg_image (reg);
158 1.1 skrll static void parse_operands (ins *, char *);
159 1.1 skrll static void parse_insn (ins *, char *);
160 1.1 skrll static void print_operand (int, int, argument *);
161 1.1 skrll static void print_constant (int, int, argument *);
162 1.1 skrll static int exponent2scale (int);
163 1.1 skrll static void mask_reg (int, unsigned short *);
164 1.1 skrll static void process_label_constant (char *, ins *);
165 1.1 skrll static void set_operand (char *, ins *);
166 1.1 skrll static char * preprocess_reglist (char *, int *);
167 1.1 skrll static int assemble_insn (char *, ins *);
168 1.1 skrll static void print_insn (ins *);
169 1.1 skrll static void warn_if_needed (ins *);
170 1.1 skrll static int adjust_if_needed (ins *);
171 1.1 skrll
172 1.1 skrll /* Return the bit size for a given operand. */
173 1.1 skrll
174 1.1 skrll static int
175 1.1 skrll get_opbits (operand_type op)
176 1.1 skrll {
177 1.1 skrll if (op < MAX_OPRD)
178 1.1 skrll return crx_optab[op].bit_size;
179 1.1 skrll else
180 1.1 skrll return 0;
181 1.1 skrll }
182 1.1 skrll
183 1.1 skrll /* Return the argument type of a given operand. */
184 1.1 skrll
185 1.1 skrll static argtype
186 1.1 skrll get_optype (operand_type op)
187 1.1 skrll {
188 1.1 skrll if (op < MAX_OPRD)
189 1.1 skrll return crx_optab[op].arg_type;
190 1.1 skrll else
191 1.1 skrll return nullargs;
192 1.1 skrll }
193 1.1 skrll
194 1.1 skrll /* Return the flags of a given operand. */
195 1.1 skrll
196 1.1 skrll static int
197 1.1 skrll get_opflags (operand_type op)
198 1.1 skrll {
199 1.1 skrll if (op < MAX_OPRD)
200 1.1 skrll return crx_optab[op].flags;
201 1.1 skrll else
202 1.1 skrll return 0;
203 1.1 skrll }
204 1.1 skrll
205 1.1 skrll /* Get the core processor register 'reg_name'. */
206 1.1 skrll
207 1.1 skrll static reg
208 1.1 skrll get_register (char *reg_name)
209 1.1 skrll {
210 1.1.1.2 christos const reg_entry *rreg;
211 1.1 skrll
212 1.1.1.2 christos rreg = (const reg_entry *) hash_find (reg_hash, reg_name);
213 1.1 skrll
214 1.1.1.2 christos if (rreg != NULL)
215 1.1.1.2 christos return rreg->value.reg_val;
216 1.1 skrll else
217 1.1 skrll return nullregister;
218 1.1 skrll }
219 1.1 skrll
220 1.1 skrll /* Get the coprocessor register 'copreg_name'. */
221 1.1 skrll
222 1.1 skrll static copreg
223 1.1 skrll get_copregister (char *copreg_name)
224 1.1 skrll {
225 1.1.1.2 christos const reg_entry *coreg;
226 1.1 skrll
227 1.1.1.2 christos coreg = (const reg_entry *) hash_find (copreg_hash, copreg_name);
228 1.1 skrll
229 1.1.1.2 christos if (coreg != NULL)
230 1.1.1.2 christos return coreg->value.copreg_val;
231 1.1 skrll else
232 1.1 skrll return nullcopregister;
233 1.1 skrll }
234 1.1 skrll
235 1.1 skrll /* Round up a section size to the appropriate boundary. */
236 1.1 skrll
237 1.1 skrll valueT
238 1.1 skrll md_section_align (segT seg, valueT val)
239 1.1 skrll {
240 1.1 skrll /* Round .text section to a multiple of 2. */
241 1.1 skrll if (seg == text_section)
242 1.1 skrll return (val + 1) & ~1;
243 1.1 skrll return val;
244 1.1 skrll }
245 1.1 skrll
246 1.1 skrll /* Parse an operand that is machine-specific (remove '*'). */
247 1.1 skrll
248 1.1 skrll void
249 1.1 skrll md_operand (expressionS * exp)
250 1.1 skrll {
251 1.1 skrll char c = *input_line_pointer;
252 1.1 skrll
253 1.1 skrll switch (c)
254 1.1 skrll {
255 1.1 skrll case '*':
256 1.1 skrll input_line_pointer++;
257 1.1 skrll expression (exp);
258 1.1 skrll break;
259 1.1 skrll default:
260 1.1 skrll break;
261 1.1 skrll }
262 1.1 skrll }
263 1.1 skrll
264 1.1 skrll /* Reset global variables before parsing a new instruction. */
265 1.1 skrll
266 1.1 skrll static void
267 1.1 skrll reset_vars (char *op)
268 1.1 skrll {
269 1.1 skrll cur_arg_num = relocatable = 0;
270 1.1 skrll memset (& output_opcode, '\0', sizeof (output_opcode));
271 1.1 skrll
272 1.1 skrll /* Save a copy of the original OP (used in error messages). */
273 1.1 skrll strncpy (ins_parse, op, sizeof ins_parse - 1);
274 1.1 skrll ins_parse [sizeof ins_parse - 1] = 0;
275 1.1 skrll }
276 1.1 skrll
277 1.1 skrll /* This macro decides whether a particular reloc is an entry in a
278 1.1 skrll switch table. It is used when relaxing, because the linker needs
279 1.1 skrll to know about all such entries so that it can adjust them if
280 1.1 skrll necessary. */
281 1.1 skrll
282 1.1 skrll #define SWITCH_TABLE(fix) \
283 1.1 skrll ( (fix)->fx_addsy != NULL \
284 1.1 skrll && (fix)->fx_subsy != NULL \
285 1.1 skrll && S_GET_SEGMENT ((fix)->fx_addsy) == \
286 1.1 skrll S_GET_SEGMENT ((fix)->fx_subsy) \
287 1.1 skrll && S_GET_SEGMENT (fix->fx_addsy) != undefined_section \
288 1.1 skrll && ( (fix)->fx_r_type == BFD_RELOC_CRX_NUM8 \
289 1.1 skrll || (fix)->fx_r_type == BFD_RELOC_CRX_NUM16 \
290 1.1 skrll || (fix)->fx_r_type == BFD_RELOC_CRX_NUM32))
291 1.1 skrll
292 1.1 skrll /* See whether we need to force a relocation into the output file.
293 1.1 skrll This is used to force out switch and PC relative relocations when
294 1.1 skrll relaxing. */
295 1.1 skrll
296 1.1 skrll int
297 1.1 skrll crx_force_relocation (fixS *fix)
298 1.1 skrll {
299 1.1 skrll if (generic_force_reloc (fix) || SWITCH_TABLE (fix))
300 1.1 skrll return 1;
301 1.1 skrll
302 1.1 skrll return 0;
303 1.1 skrll }
304 1.1 skrll
305 1.1 skrll /* Generate a relocation entry for a fixup. */
306 1.1 skrll
307 1.1 skrll arelent *
308 1.1 skrll tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS * fixP)
309 1.1 skrll {
310 1.1 skrll arelent * reloc;
311 1.1 skrll
312 1.1 skrll reloc = xmalloc (sizeof (arelent));
313 1.1 skrll reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
314 1.1 skrll *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
315 1.1 skrll reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
316 1.1 skrll reloc->addend = fixP->fx_offset;
317 1.1 skrll
318 1.1 skrll if (fixP->fx_subsy != NULL)
319 1.1 skrll {
320 1.1 skrll if (SWITCH_TABLE (fixP))
321 1.1 skrll {
322 1.1 skrll /* Keep the current difference in the addend. */
323 1.1 skrll reloc->addend = (S_GET_VALUE (fixP->fx_addsy)
324 1.1 skrll - S_GET_VALUE (fixP->fx_subsy) + fixP->fx_offset);
325 1.1 skrll
326 1.1 skrll switch (fixP->fx_r_type)
327 1.1 skrll {
328 1.1 skrll case BFD_RELOC_CRX_NUM8:
329 1.1 skrll fixP->fx_r_type = BFD_RELOC_CRX_SWITCH8;
330 1.1 skrll break;
331 1.1 skrll case BFD_RELOC_CRX_NUM16:
332 1.1 skrll fixP->fx_r_type = BFD_RELOC_CRX_SWITCH16;
333 1.1 skrll break;
334 1.1 skrll case BFD_RELOC_CRX_NUM32:
335 1.1 skrll fixP->fx_r_type = BFD_RELOC_CRX_SWITCH32;
336 1.1 skrll break;
337 1.1 skrll default:
338 1.1 skrll abort ();
339 1.1 skrll break;
340 1.1 skrll }
341 1.1 skrll }
342 1.1 skrll else
343 1.1 skrll {
344 1.1 skrll /* We only resolve difference expressions in the same section. */
345 1.1 skrll as_bad_where (fixP->fx_file, fixP->fx_line,
346 1.1 skrll _("can't resolve `%s' {%s section} - `%s' {%s section}"),
347 1.1 skrll fixP->fx_addsy ? S_GET_NAME (fixP->fx_addsy) : "0",
348 1.1 skrll segment_name (fixP->fx_addsy
349 1.1 skrll ? S_GET_SEGMENT (fixP->fx_addsy)
350 1.1 skrll : absolute_section),
351 1.1 skrll S_GET_NAME (fixP->fx_subsy),
352 1.1 skrll segment_name (S_GET_SEGMENT (fixP->fx_addsy)));
353 1.1 skrll }
354 1.1 skrll }
355 1.1 skrll
356 1.1.1.2 christos gas_assert ((int) fixP->fx_r_type > 0);
357 1.1 skrll reloc->howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
358 1.1 skrll
359 1.1 skrll if (reloc->howto == (reloc_howto_type *) NULL)
360 1.1 skrll {
361 1.1 skrll as_bad_where (fixP->fx_file, fixP->fx_line,
362 1.1 skrll _("internal error: reloc %d (`%s') not supported by object file format"),
363 1.1 skrll fixP->fx_r_type,
364 1.1 skrll bfd_get_reloc_code_name (fixP->fx_r_type));
365 1.1 skrll return NULL;
366 1.1 skrll }
367 1.1.1.2 christos gas_assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);
368 1.1 skrll
369 1.1 skrll return reloc;
370 1.1 skrll }
371 1.1 skrll
372 1.1 skrll /* Prepare machine-dependent frags for relaxation. */
373 1.1 skrll
374 1.1 skrll int
375 1.1 skrll md_estimate_size_before_relax (fragS *fragp, asection *seg)
376 1.1 skrll {
377 1.1 skrll /* If symbol is undefined or located in a different section,
378 1.1 skrll select the largest supported relocation. */
379 1.1 skrll relax_substateT subtype;
380 1.1 skrll relax_substateT rlx_state[] = {0, 2,
381 1.1 skrll 3, 4,
382 1.1 skrll 5, 6};
383 1.1 skrll
384 1.1 skrll for (subtype = 0; subtype < ARRAY_SIZE (rlx_state); subtype += 2)
385 1.1 skrll {
386 1.1 skrll if (fragp->fr_subtype == rlx_state[subtype]
387 1.1 skrll && (!S_IS_DEFINED (fragp->fr_symbol)
388 1.1 skrll || seg != S_GET_SEGMENT (fragp->fr_symbol)))
389 1.1 skrll {
390 1.1 skrll fragp->fr_subtype = rlx_state[subtype + 1];
391 1.1 skrll break;
392 1.1 skrll }
393 1.1 skrll }
394 1.1 skrll
395 1.1 skrll if (fragp->fr_subtype >= ARRAY_SIZE (md_relax_table))
396 1.1 skrll abort ();
397 1.1 skrll
398 1.1 skrll return md_relax_table[fragp->fr_subtype].rlx_length;
399 1.1 skrll }
400 1.1 skrll
401 1.1 skrll void
402 1.1 skrll md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, fragS *fragP)
403 1.1 skrll {
404 1.1 skrll /* 'opcode' points to the start of the instruction, whether
405 1.1 skrll we need to change the instruction's fixed encoding. */
406 1.1 skrll char *opcode = fragP->fr_literal + fragP->fr_fix;
407 1.1 skrll bfd_reloc_code_real_type reloc;
408 1.1 skrll
409 1.1 skrll subseg_change (sec, 0);
410 1.1 skrll
411 1.1 skrll switch (fragP->fr_subtype)
412 1.1 skrll {
413 1.1 skrll case 0:
414 1.1 skrll reloc = BFD_RELOC_CRX_REL8;
415 1.1 skrll break;
416 1.1 skrll case 1:
417 1.1 skrll *opcode = 0x7e;
418 1.1 skrll reloc = BFD_RELOC_CRX_REL16;
419 1.1 skrll break;
420 1.1 skrll case 2:
421 1.1 skrll *opcode = 0x7f;
422 1.1 skrll reloc = BFD_RELOC_CRX_REL32;
423 1.1 skrll break;
424 1.1 skrll case 3:
425 1.1 skrll reloc = BFD_RELOC_CRX_REL16;
426 1.1 skrll break;
427 1.1 skrll case 4:
428 1.1 skrll *++opcode = 0x31;
429 1.1 skrll reloc = BFD_RELOC_CRX_REL32;
430 1.1 skrll break;
431 1.1 skrll case 5:
432 1.1 skrll reloc = BFD_RELOC_CRX_REL8_CMP;
433 1.1 skrll break;
434 1.1 skrll case 6:
435 1.1 skrll *++opcode = 0x31;
436 1.1 skrll reloc = BFD_RELOC_CRX_REL24;
437 1.1 skrll break;
438 1.1 skrll default:
439 1.1 skrll abort ();
440 1.1 skrll break;
441 1.1 skrll }
442 1.1 skrll
443 1.1 skrll fix_new (fragP, fragP->fr_fix,
444 1.1 skrll bfd_get_reloc_size (bfd_reloc_type_lookup (stdoutput, reloc)),
445 1.1 skrll fragP->fr_symbol, fragP->fr_offset, 1, reloc);
446 1.1 skrll fragP->fr_var = 0;
447 1.1 skrll fragP->fr_fix += md_relax_table[fragP->fr_subtype].rlx_length;
448 1.1 skrll }
449 1.1 skrll
450 1.1 skrll /* Process machine-dependent command line options. Called once for
451 1.1 skrll each option on the command line that the machine-independent part of
452 1.1 skrll GAS does not understand. */
453 1.1 skrll
454 1.1 skrll int
455 1.1 skrll md_parse_option (int c ATTRIBUTE_UNUSED, char *arg ATTRIBUTE_UNUSED)
456 1.1 skrll {
457 1.1 skrll return 0;
458 1.1 skrll }
459 1.1 skrll
460 1.1 skrll /* Machine-dependent usage-output. */
461 1.1 skrll
462 1.1 skrll void
463 1.1 skrll md_show_usage (FILE *stream ATTRIBUTE_UNUSED)
464 1.1 skrll {
465 1.1 skrll return;
466 1.1 skrll }
467 1.1 skrll
468 1.1 skrll char *
469 1.1 skrll md_atof (int type, char *litP, int *sizeP)
470 1.1 skrll {
471 1.1 skrll return ieee_md_atof (type, litP, sizeP, target_big_endian);
472 1.1 skrll }
473 1.1 skrll
474 1.1 skrll /* Apply a fixS (fixup of an instruction or data that we didn't have
475 1.1 skrll enough info to complete immediately) to the data in a frag.
476 1.1 skrll Since linkrelax is nonzero and TC_LINKRELAX_FIXUP is defined to disable
477 1.1 skrll relaxation of debug sections, this function is called only when
478 1.1 skrll fixuping relocations of debug sections. */
479 1.1 skrll
480 1.1 skrll void
481 1.1 skrll md_apply_fix (fixS *fixP, valueT *valP, segT seg)
482 1.1 skrll {
483 1.1 skrll valueT val = * valP;
484 1.1 skrll char *buf = fixP->fx_frag->fr_literal + fixP->fx_where;
485 1.1 skrll fixP->fx_offset = 0;
486 1.1 skrll
487 1.1 skrll switch (fixP->fx_r_type)
488 1.1 skrll {
489 1.1 skrll case BFD_RELOC_CRX_NUM8:
490 1.1 skrll bfd_put_8 (stdoutput, (unsigned char) val, buf);
491 1.1 skrll break;
492 1.1 skrll case BFD_RELOC_CRX_NUM16:
493 1.1 skrll bfd_put_16 (stdoutput, val, buf);
494 1.1 skrll break;
495 1.1 skrll case BFD_RELOC_CRX_NUM32:
496 1.1 skrll bfd_put_32 (stdoutput, val, buf);
497 1.1 skrll break;
498 1.1 skrll default:
499 1.1 skrll /* We shouldn't ever get here because linkrelax is nonzero. */
500 1.1 skrll abort ();
501 1.1 skrll break;
502 1.1 skrll }
503 1.1 skrll
504 1.1 skrll fixP->fx_done = 0;
505 1.1 skrll
506 1.1 skrll if (fixP->fx_addsy == NULL
507 1.1 skrll && fixP->fx_pcrel == 0)
508 1.1 skrll fixP->fx_done = 1;
509 1.1 skrll
510 1.1 skrll if (fixP->fx_pcrel == 1
511 1.1 skrll && fixP->fx_addsy != NULL
512 1.1 skrll && S_GET_SEGMENT (fixP->fx_addsy) == seg)
513 1.1 skrll fixP->fx_done = 1;
514 1.1 skrll }
515 1.1 skrll
516 1.1 skrll /* The location from which a PC relative jump should be calculated,
517 1.1 skrll given a PC relative reloc. */
518 1.1 skrll
519 1.1 skrll long
520 1.1 skrll md_pcrel_from (fixS *fixp)
521 1.1 skrll {
522 1.1 skrll return fixp->fx_frag->fr_address + fixp->fx_where;
523 1.1 skrll }
524 1.1 skrll
525 1.1 skrll /* This function is called once, at assembler startup time. This should
526 1.1 skrll set up all the tables, etc that the MD part of the assembler needs. */
527 1.1 skrll
528 1.1 skrll void
529 1.1 skrll md_begin (void)
530 1.1 skrll {
531 1.1 skrll const char *hashret = NULL;
532 1.1 skrll int i = 0;
533 1.1 skrll
534 1.1 skrll /* Set up a hash table for the instructions. */
535 1.1 skrll if ((crx_inst_hash = hash_new ()) == NULL)
536 1.1 skrll as_fatal (_("Virtual memory exhausted"));
537 1.1 skrll
538 1.1 skrll while (crx_instruction[i].mnemonic != NULL)
539 1.1 skrll {
540 1.1 skrll const char *mnemonic = crx_instruction[i].mnemonic;
541 1.1 skrll
542 1.1 skrll hashret = hash_insert (crx_inst_hash, mnemonic,
543 1.1 skrll (void *) &crx_instruction[i]);
544 1.1 skrll
545 1.1 skrll if (hashret != NULL && *hashret != '\0')
546 1.1 skrll as_fatal (_("Can't hash `%s': %s\n"), crx_instruction[i].mnemonic,
547 1.1 skrll *hashret == 0 ? _("(unknown reason)") : hashret);
548 1.1 skrll
549 1.1 skrll /* Insert unique names into hash table. The CRX instruction set
550 1.1 skrll has many identical opcode names that have different opcodes based
551 1.1 skrll on the operands. This hash table then provides a quick index to
552 1.1 skrll the first opcode with a particular name in the opcode table. */
553 1.1 skrll do
554 1.1 skrll {
555 1.1 skrll ++i;
556 1.1 skrll }
557 1.1 skrll while (crx_instruction[i].mnemonic != NULL
558 1.1 skrll && streq (crx_instruction[i].mnemonic, mnemonic));
559 1.1 skrll }
560 1.1 skrll
561 1.1 skrll /* Initialize reg_hash hash table. */
562 1.1 skrll if ((reg_hash = hash_new ()) == NULL)
563 1.1 skrll as_fatal (_("Virtual memory exhausted"));
564 1.1 skrll
565 1.1 skrll {
566 1.1 skrll const reg_entry *regtab;
567 1.1 skrll
568 1.1 skrll for (regtab = crx_regtab;
569 1.1 skrll regtab < (crx_regtab + NUMREGS); regtab++)
570 1.1 skrll {
571 1.1 skrll hashret = hash_insert (reg_hash, regtab->name, (void *) regtab);
572 1.1 skrll if (hashret)
573 1.1 skrll as_fatal (_("Internal Error: Can't hash %s: %s"),
574 1.1 skrll regtab->name,
575 1.1 skrll hashret);
576 1.1 skrll }
577 1.1 skrll }
578 1.1 skrll
579 1.1 skrll /* Initialize copreg_hash hash table. */
580 1.1 skrll if ((copreg_hash = hash_new ()) == NULL)
581 1.1 skrll as_fatal (_("Virtual memory exhausted"));
582 1.1 skrll
583 1.1 skrll {
584 1.1 skrll const reg_entry *copregtab;
585 1.1 skrll
586 1.1 skrll for (copregtab = crx_copregtab; copregtab < (crx_copregtab + NUMCOPREGS);
587 1.1 skrll copregtab++)
588 1.1 skrll {
589 1.1 skrll hashret = hash_insert (copreg_hash, copregtab->name,
590 1.1 skrll (void *) copregtab);
591 1.1 skrll if (hashret)
592 1.1 skrll as_fatal (_("Internal Error: Can't hash %s: %s"),
593 1.1 skrll copregtab->name,
594 1.1 skrll hashret);
595 1.1 skrll }
596 1.1 skrll }
597 1.1 skrll /* Set linkrelax here to avoid fixups in most sections. */
598 1.1 skrll linkrelax = 1;
599 1.1 skrll }
600 1.1 skrll
601 1.1 skrll /* Process constants (immediate/absolute)
602 1.1 skrll and labels (jump targets/Memory locations). */
603 1.1 skrll
604 1.1 skrll static void
605 1.1 skrll process_label_constant (char *str, ins * crx_ins)
606 1.1 skrll {
607 1.1 skrll char *saved_input_line_pointer;
608 1.1 skrll argument *cur_arg = &crx_ins->arg[cur_arg_num]; /* Current argument. */
609 1.1 skrll
610 1.1 skrll saved_input_line_pointer = input_line_pointer;
611 1.1 skrll input_line_pointer = str;
612 1.1 skrll
613 1.1 skrll expression (&crx_ins->exp);
614 1.1 skrll
615 1.1 skrll switch (crx_ins->exp.X_op)
616 1.1 skrll {
617 1.1 skrll case O_big:
618 1.1 skrll case O_absent:
619 1.1 skrll /* Missing or bad expr becomes absolute 0. */
620 1.1 skrll as_bad (_("missing or invalid displacement expression `%s' taken as 0"),
621 1.1 skrll str);
622 1.1 skrll crx_ins->exp.X_op = O_constant;
623 1.1 skrll crx_ins->exp.X_add_number = 0;
624 1.1 skrll crx_ins->exp.X_add_symbol = (symbolS *) 0;
625 1.1 skrll crx_ins->exp.X_op_symbol = (symbolS *) 0;
626 1.1 skrll /* Fall through. */
627 1.1 skrll
628 1.1 skrll case O_constant:
629 1.1 skrll cur_arg->X_op = O_constant;
630 1.1 skrll cur_arg->constant = crx_ins->exp.X_add_number;
631 1.1 skrll break;
632 1.1 skrll
633 1.1 skrll case O_symbol:
634 1.1 skrll case O_subtract:
635 1.1 skrll case O_add:
636 1.1 skrll cur_arg->X_op = O_symbol;
637 1.1 skrll crx_ins->rtype = BFD_RELOC_NONE;
638 1.1 skrll relocatable = 1;
639 1.1 skrll
640 1.1 skrll switch (cur_arg->type)
641 1.1 skrll {
642 1.1 skrll case arg_cr:
643 1.1 skrll if (IS_INSN_TYPE (LD_STOR_INS_INC))
644 1.1 skrll crx_ins->rtype = BFD_RELOC_CRX_REGREL12;
645 1.1 skrll else if (IS_INSN_TYPE (CSTBIT_INS)
646 1.1 skrll || IS_INSN_TYPE (STOR_IMM_INS))
647 1.1 skrll crx_ins->rtype = BFD_RELOC_CRX_REGREL28;
648 1.1 skrll else
649 1.1 skrll crx_ins->rtype = BFD_RELOC_CRX_REGREL32;
650 1.1 skrll break;
651 1.1 skrll
652 1.1 skrll case arg_idxr:
653 1.1 skrll crx_ins->rtype = BFD_RELOC_CRX_REGREL22;
654 1.1 skrll break;
655 1.1 skrll
656 1.1 skrll case arg_c:
657 1.1 skrll if (IS_INSN_MNEMONIC ("bal") || IS_INSN_TYPE (DCR_BRANCH_INS))
658 1.1 skrll crx_ins->rtype = BFD_RELOC_CRX_REL16;
659 1.1 skrll else if (IS_INSN_TYPE (BRANCH_INS))
660 1.1 skrll crx_ins->rtype = BFD_RELOC_CRX_REL8;
661 1.1 skrll else if (IS_INSN_TYPE (LD_STOR_INS) || IS_INSN_TYPE (STOR_IMM_INS)
662 1.1 skrll || IS_INSN_TYPE (CSTBIT_INS))
663 1.1 skrll crx_ins->rtype = BFD_RELOC_CRX_ABS32;
664 1.1 skrll else if (IS_INSN_TYPE (BRANCH_NEQ_INS))
665 1.1 skrll crx_ins->rtype = BFD_RELOC_CRX_REL4;
666 1.1 skrll else if (IS_INSN_TYPE (CMPBR_INS) || IS_INSN_TYPE (COP_BRANCH_INS))
667 1.1 skrll crx_ins->rtype = BFD_RELOC_CRX_REL8_CMP;
668 1.1 skrll break;
669 1.1 skrll
670 1.1 skrll case arg_ic:
671 1.1 skrll if (IS_INSN_TYPE (ARITH_INS))
672 1.1 skrll crx_ins->rtype = BFD_RELOC_CRX_IMM32;
673 1.1 skrll else if (IS_INSN_TYPE (ARITH_BYTE_INS))
674 1.1 skrll crx_ins->rtype = BFD_RELOC_CRX_IMM16;
675 1.1 skrll break;
676 1.1 skrll default:
677 1.1 skrll break;
678 1.1 skrll }
679 1.1 skrll break;
680 1.1 skrll
681 1.1 skrll default:
682 1.1 skrll cur_arg->X_op = crx_ins->exp.X_op;
683 1.1 skrll break;
684 1.1 skrll }
685 1.1 skrll
686 1.1 skrll input_line_pointer = saved_input_line_pointer;
687 1.1 skrll return;
688 1.1 skrll }
689 1.1 skrll
690 1.1 skrll /* Get the values of the scale to be encoded -
691 1.1 skrll used for the scaled index mode of addressing. */
692 1.1 skrll
693 1.1 skrll static int
694 1.1 skrll exponent2scale (int val)
695 1.1 skrll {
696 1.1 skrll int exponent;
697 1.1 skrll
698 1.1 skrll /* If 'val' is 0, the following 'for' will be an endless loop. */
699 1.1 skrll if (val == 0)
700 1.1 skrll return 0;
701 1.1 skrll
702 1.1 skrll for (exponent = 0; (val != 1); val >>= 1, exponent++)
703 1.1 skrll ;
704 1.1 skrll
705 1.1 skrll return exponent;
706 1.1 skrll }
707 1.1 skrll
708 1.1 skrll /* Parsing different types of operands
709 1.1 skrll -> constants Immediate/Absolute/Relative numbers
710 1.1 skrll -> Labels Relocatable symbols
711 1.1 skrll -> (rbase) Register base
712 1.1 skrll -> disp(rbase) Register relative
713 1.1 skrll -> disp(rbase)+ Post-increment mode
714 1.1 skrll -> disp(rbase,ridx,scl) Register index mode */
715 1.1 skrll
716 1.1 skrll static void
717 1.1 skrll set_operand (char *operand, ins * crx_ins)
718 1.1 skrll {
719 1.1 skrll char *operandS; /* Pointer to start of sub-opearand. */
720 1.1 skrll char *operandE; /* Pointer to end of sub-opearand. */
721 1.1 skrll expressionS scale;
722 1.1 skrll int scale_val;
723 1.1 skrll char *input_save, c;
724 1.1 skrll argument *cur_arg = &crx_ins->arg[cur_arg_num]; /* Current argument. */
725 1.1 skrll
726 1.1 skrll /* Initialize pointers. */
727 1.1 skrll operandS = operandE = operand;
728 1.1 skrll
729 1.1 skrll switch (cur_arg->type)
730 1.1 skrll {
731 1.1 skrll case arg_sc: /* Case *+0x18. */
732 1.1 skrll case arg_ic: /* Case $0x18. */
733 1.1 skrll operandS++;
734 1.1 skrll case arg_c: /* Case 0x18. */
735 1.1 skrll /* Set constant. */
736 1.1 skrll process_label_constant (operandS, crx_ins);
737 1.1 skrll
738 1.1 skrll if (cur_arg->type != arg_ic)
739 1.1 skrll cur_arg->type = arg_c;
740 1.1 skrll break;
741 1.1 skrll
742 1.1 skrll case arg_icr: /* Case $0x18(r1). */
743 1.1 skrll operandS++;
744 1.1 skrll case arg_cr: /* Case 0x18(r1). */
745 1.1 skrll /* Set displacement constant. */
746 1.1 skrll while (*operandE != '(')
747 1.1 skrll operandE++;
748 1.1 skrll *operandE = '\0';
749 1.1 skrll process_label_constant (operandS, crx_ins);
750 1.1 skrll operandS = operandE;
751 1.1 skrll case arg_rbase: /* Case (r1). */
752 1.1 skrll operandS++;
753 1.1 skrll /* Set register base. */
754 1.1 skrll while (*operandE != ')')
755 1.1 skrll operandE++;
756 1.1 skrll *operandE = '\0';
757 1.1 skrll if ((cur_arg->r = get_register (operandS)) == nullregister)
758 1.1 skrll as_bad (_("Illegal register `%s' in Instruction `%s'"),
759 1.1 skrll operandS, ins_parse);
760 1.1 skrll
761 1.1 skrll if (cur_arg->type != arg_rbase)
762 1.1 skrll cur_arg->type = arg_cr;
763 1.1 skrll break;
764 1.1 skrll
765 1.1 skrll case arg_idxr:
766 1.1 skrll /* Set displacement constant. */
767 1.1 skrll while (*operandE != '(')
768 1.1 skrll operandE++;
769 1.1 skrll *operandE = '\0';
770 1.1 skrll process_label_constant (operandS, crx_ins);
771 1.1 skrll operandS = ++operandE;
772 1.1 skrll
773 1.1 skrll /* Set register base. */
774 1.1 skrll while ((*operandE != ',') && (! ISSPACE (*operandE)))
775 1.1 skrll operandE++;
776 1.1 skrll *operandE++ = '\0';
777 1.1 skrll if ((cur_arg->r = get_register (operandS)) == nullregister)
778 1.1 skrll as_bad (_("Illegal register `%s' in Instruction `%s'"),
779 1.1 skrll operandS, ins_parse);
780 1.1 skrll
781 1.1 skrll /* Skip leading white space. */
782 1.1 skrll while (ISSPACE (*operandE))
783 1.1 skrll operandE++;
784 1.1 skrll operandS = operandE;
785 1.1 skrll
786 1.1 skrll /* Set register index. */
787 1.1 skrll while ((*operandE != ')') && (*operandE != ','))
788 1.1 skrll operandE++;
789 1.1 skrll c = *operandE;
790 1.1 skrll *operandE++ = '\0';
791 1.1 skrll
792 1.1 skrll if ((cur_arg->i_r = get_register (operandS)) == nullregister)
793 1.1 skrll as_bad (_("Illegal register `%s' in Instruction `%s'"),
794 1.1 skrll operandS, ins_parse);
795 1.1 skrll
796 1.1 skrll /* Skip leading white space. */
797 1.1 skrll while (ISSPACE (*operandE))
798 1.1 skrll operandE++;
799 1.1 skrll operandS = operandE;
800 1.1 skrll
801 1.1 skrll /* Set the scale. */
802 1.1 skrll if (c == ')')
803 1.1 skrll cur_arg->scale = 0;
804 1.1 skrll else
805 1.1 skrll {
806 1.1 skrll while (*operandE != ')')
807 1.1 skrll operandE++;
808 1.1 skrll *operandE = '\0';
809 1.1 skrll
810 1.1 skrll /* Preprocess the scale string. */
811 1.1 skrll input_save = input_line_pointer;
812 1.1 skrll input_line_pointer = operandS;
813 1.1 skrll expression (&scale);
814 1.1 skrll input_line_pointer = input_save;
815 1.1 skrll
816 1.1 skrll scale_val = scale.X_add_number;
817 1.1 skrll
818 1.1 skrll /* Check if the scale value is legal. */
819 1.1 skrll if (scale_val != 1 && scale_val != 2
820 1.1 skrll && scale_val != 4 && scale_val != 8)
821 1.1 skrll as_bad (_("Illegal Scale - `%d'"), scale_val);
822 1.1 skrll
823 1.1 skrll cur_arg->scale = exponent2scale (scale_val);
824 1.1 skrll }
825 1.1 skrll break;
826 1.1 skrll
827 1.1 skrll default:
828 1.1 skrll break;
829 1.1 skrll }
830 1.1 skrll }
831 1.1 skrll
832 1.1 skrll /* Parse a single operand.
833 1.1 skrll operand - Current operand to parse.
834 1.1 skrll crx_ins - Current assembled instruction. */
835 1.1 skrll
836 1.1 skrll static void
837 1.1 skrll parse_operand (char *operand, ins * crx_ins)
838 1.1 skrll {
839 1.1 skrll int ret_val;
840 1.1 skrll argument *cur_arg = &crx_ins->arg[cur_arg_num]; /* Current argument. */
841 1.1 skrll
842 1.1 skrll /* Initialize the type to NULL before parsing. */
843 1.1 skrll cur_arg->type = nullargs;
844 1.1 skrll
845 1.1 skrll /* Check whether this is a general processor register. */
846 1.1 skrll if ((ret_val = get_register (operand)) != nullregister)
847 1.1 skrll {
848 1.1 skrll cur_arg->type = arg_r;
849 1.1 skrll cur_arg->r = ret_val;
850 1.1 skrll cur_arg->X_op = O_register;
851 1.1 skrll return;
852 1.1 skrll }
853 1.1 skrll
854 1.1 skrll /* Check whether this is a core [special] coprocessor register. */
855 1.1 skrll if ((ret_val = get_copregister (operand)) != nullcopregister)
856 1.1 skrll {
857 1.1 skrll cur_arg->type = arg_copr;
858 1.1 skrll if (ret_val >= cs0)
859 1.1 skrll cur_arg->type = arg_copsr;
860 1.1 skrll cur_arg->cr = ret_val;
861 1.1 skrll cur_arg->X_op = O_register;
862 1.1 skrll return;
863 1.1 skrll }
864 1.1 skrll
865 1.1 skrll /* Deal with special characters. */
866 1.1 skrll switch (operand[0])
867 1.1 skrll {
868 1.1 skrll case '$':
869 1.1 skrll if (strchr (operand, '(') != NULL)
870 1.1 skrll cur_arg->type = arg_icr;
871 1.1 skrll else
872 1.1 skrll cur_arg->type = arg_ic;
873 1.1 skrll goto set_params;
874 1.1 skrll break;
875 1.1 skrll
876 1.1 skrll case '*':
877 1.1 skrll cur_arg->type = arg_sc;
878 1.1 skrll goto set_params;
879 1.1 skrll break;
880 1.1 skrll
881 1.1 skrll case '(':
882 1.1 skrll cur_arg->type = arg_rbase;
883 1.1 skrll goto set_params;
884 1.1 skrll break;
885 1.1 skrll
886 1.1 skrll default:
887 1.1 skrll break;
888 1.1 skrll }
889 1.1 skrll
890 1.1 skrll if (strchr (operand, '(') != NULL)
891 1.1 skrll {
892 1.1 skrll if (strchr (operand, ',') != NULL
893 1.1 skrll && (strchr (operand, ',') > strchr (operand, '(')))
894 1.1 skrll cur_arg->type = arg_idxr;
895 1.1 skrll else
896 1.1 skrll cur_arg->type = arg_cr;
897 1.1 skrll }
898 1.1 skrll else
899 1.1 skrll cur_arg->type = arg_c;
900 1.1 skrll goto set_params;
901 1.1 skrll
902 1.1 skrll /* Parse an operand according to its type. */
903 1.1 skrll set_params:
904 1.1 skrll cur_arg->constant = 0;
905 1.1 skrll set_operand (operand, crx_ins);
906 1.1 skrll }
907 1.1 skrll
908 1.1 skrll /* Parse the various operands. Each operand is then analyzed to fillup
909 1.1 skrll the fields in the crx_ins data structure. */
910 1.1 skrll
911 1.1 skrll static void
912 1.1 skrll parse_operands (ins * crx_ins, char *operands)
913 1.1 skrll {
914 1.1 skrll char *operandS; /* Operands string. */
915 1.1 skrll char *operandH, *operandT; /* Single operand head/tail pointers. */
916 1.1 skrll int allocated = 0; /* Indicates a new operands string was allocated. */
917 1.1 skrll char *operand[MAX_OPERANDS]; /* Separating the operands. */
918 1.1 skrll int op_num = 0; /* Current operand number we are parsing. */
919 1.1 skrll int bracket_flag = 0; /* Indicates a bracket '(' was found. */
920 1.1 skrll int sq_bracket_flag = 0; /* Indicates a square bracket '[' was found. */
921 1.1 skrll
922 1.1 skrll /* Preprocess the list of registers, if necessary. */
923 1.1 skrll operandS = operandH = operandT = (INST_HAS_REG_LIST) ?
924 1.1 skrll preprocess_reglist (operands, &allocated) : operands;
925 1.1 skrll
926 1.1 skrll while (*operandT != '\0')
927 1.1 skrll {
928 1.1 skrll if (*operandT == ',' && bracket_flag != 1 && sq_bracket_flag != 1)
929 1.1 skrll {
930 1.1 skrll *operandT++ = '\0';
931 1.1 skrll operand[op_num++] = strdup (operandH);
932 1.1 skrll operandH = operandT;
933 1.1 skrll continue;
934 1.1 skrll }
935 1.1 skrll
936 1.1 skrll if (*operandT == ' ')
937 1.1 skrll as_bad (_("Illegal operands (whitespace): `%s'"), ins_parse);
938 1.1 skrll
939 1.1 skrll if (*operandT == '(')
940 1.1 skrll bracket_flag = 1;
941 1.1 skrll else if (*operandT == '[')
942 1.1 skrll sq_bracket_flag = 1;
943 1.1 skrll
944 1.1 skrll if (*operandT == ')')
945 1.1 skrll {
946 1.1 skrll if (bracket_flag)
947 1.1 skrll bracket_flag = 0;
948 1.1 skrll else
949 1.1 skrll as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
950 1.1 skrll }
951 1.1 skrll else if (*operandT == ']')
952 1.1 skrll {
953 1.1 skrll if (sq_bracket_flag)
954 1.1 skrll sq_bracket_flag = 0;
955 1.1 skrll else
956 1.1 skrll as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
957 1.1 skrll }
958 1.1 skrll
959 1.1 skrll if (bracket_flag == 1 && *operandT == ')')
960 1.1 skrll bracket_flag = 0;
961 1.1 skrll else if (sq_bracket_flag == 1 && *operandT == ']')
962 1.1 skrll sq_bracket_flag = 0;
963 1.1 skrll
964 1.1 skrll operandT++;
965 1.1 skrll }
966 1.1 skrll
967 1.1 skrll /* Adding the last operand. */
968 1.1 skrll operand[op_num++] = strdup (operandH);
969 1.1 skrll crx_ins->nargs = op_num;
970 1.1 skrll
971 1.1 skrll /* Verifying correct syntax of operands (all brackets should be closed). */
972 1.1 skrll if (bracket_flag || sq_bracket_flag)
973 1.1 skrll as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
974 1.1 skrll
975 1.1 skrll /* Now we parse each operand separately. */
976 1.1 skrll for (op_num = 0; op_num < crx_ins->nargs; op_num++)
977 1.1 skrll {
978 1.1 skrll cur_arg_num = op_num;
979 1.1 skrll parse_operand (operand[op_num], crx_ins);
980 1.1 skrll free (operand[op_num]);
981 1.1 skrll }
982 1.1 skrll
983 1.1 skrll if (allocated)
984 1.1 skrll free (operandS);
985 1.1 skrll }
986 1.1 skrll
987 1.1 skrll /* Get the trap index in dispatch table, given its name.
988 1.1 skrll This routine is used by assembling the 'excp' instruction. */
989 1.1 skrll
990 1.1 skrll static int
991 1.1.1.2 christos gettrap (const char *s)
992 1.1 skrll {
993 1.1 skrll const trap_entry *trap;
994 1.1 skrll
995 1.1 skrll for (trap = crx_traps; trap < (crx_traps + NUMTRAPS); trap++)
996 1.1 skrll if (strcasecmp (trap->name, s) == 0)
997 1.1 skrll return trap->entry;
998 1.1 skrll
999 1.1 skrll as_bad (_("Unknown exception: `%s'"), s);
1000 1.1 skrll return 0;
1001 1.1 skrll }
1002 1.1 skrll
1003 1.1 skrll /* Post-Increment instructions, as well as Store-Immediate instructions, are a
1004 1.1 skrll sub-group within load/stor instruction groups.
1005 1.1 skrll Therefore, when parsing a Post-Increment/Store-Immediate insn, we have to
1006 1.1 skrll advance the instruction pointer to the start of that sub-group (that is, up
1007 1.1 skrll to the first instruction of that type).
1008 1.1 skrll Otherwise, the insn will be mistakenly identified as of type LD_STOR_INS. */
1009 1.1 skrll
1010 1.1 skrll static void
1011 1.1.1.2 christos handle_LoadStor (const char *operands)
1012 1.1 skrll {
1013 1.1 skrll /* Post-Increment instructions precede Store-Immediate instructions in
1014 1.1 skrll CRX instruction table, hence they are handled before.
1015 1.1 skrll This synchronization should be kept. */
1016 1.1 skrll
1017 1.1 skrll /* Assuming Post-Increment insn has the following format :
1018 1.1 skrll 'MNEMONIC DISP(REG)+, REG' (e.g. 'loadw 12(r5)+, r6').
1019 1.1 skrll LD_STOR_INS_INC are the only store insns containing a plus sign (+). */
1020 1.1 skrll if (strstr (operands, ")+") != NULL)
1021 1.1 skrll {
1022 1.1 skrll while (! IS_INSN_TYPE (LD_STOR_INS_INC))
1023 1.1 skrll instruction++;
1024 1.1 skrll return;
1025 1.1 skrll }
1026 1.1 skrll
1027 1.1 skrll /* Assuming Store-Immediate insn has the following format :
1028 1.1 skrll 'MNEMONIC $DISP, ...' (e.g. 'storb $1, 12(r5)').
1029 1.1 skrll STOR_IMM_INS are the only store insns containing a dollar sign ($). */
1030 1.1 skrll if (strstr (operands, "$") != NULL)
1031 1.1 skrll while (! IS_INSN_TYPE (STOR_IMM_INS))
1032 1.1 skrll instruction++;
1033 1.1 skrll }
1034 1.1 skrll
1035 1.1 skrll /* Top level module where instruction parsing starts.
1036 1.1 skrll crx_ins - data structure holds some information.
1037 1.1 skrll operands - holds the operands part of the whole instruction. */
1038 1.1 skrll
1039 1.1 skrll static void
1040 1.1 skrll parse_insn (ins *insn, char *operands)
1041 1.1 skrll {
1042 1.1 skrll int i;
1043 1.1 skrll
1044 1.1 skrll /* Handle instructions with no operands. */
1045 1.1 skrll for (i = 0; no_op_insn[i] != NULL; i++)
1046 1.1 skrll {
1047 1.1 skrll if (streq (no_op_insn[i], instruction->mnemonic))
1048 1.1 skrll {
1049 1.1 skrll insn->nargs = 0;
1050 1.1 skrll return;
1051 1.1 skrll }
1052 1.1 skrll }
1053 1.1 skrll
1054 1.1 skrll /* Handle 'excp'/'cinv' instructions. */
1055 1.1 skrll if (IS_INSN_MNEMONIC ("excp") || IS_INSN_MNEMONIC ("cinv"))
1056 1.1 skrll {
1057 1.1 skrll insn->nargs = 1;
1058 1.1 skrll insn->arg[0].type = arg_ic;
1059 1.1 skrll insn->arg[0].constant = IS_INSN_MNEMONIC ("excp") ?
1060 1.1 skrll gettrap (operands) : get_cinv_parameters (operands);
1061 1.1 skrll insn->arg[0].X_op = O_constant;
1062 1.1 skrll return;
1063 1.1 skrll }
1064 1.1 skrll
1065 1.1 skrll /* Handle load/stor unique instructions before parsing. */
1066 1.1 skrll if (IS_INSN_TYPE (LD_STOR_INS))
1067 1.1 skrll handle_LoadStor (operands);
1068 1.1 skrll
1069 1.1 skrll if (operands != NULL)
1070 1.1 skrll parse_operands (insn, operands);
1071 1.1 skrll }
1072 1.1 skrll
1073 1.1 skrll /* Cinv instruction requires special handling. */
1074 1.1 skrll
1075 1.1 skrll static int
1076 1.1.1.2 christos get_cinv_parameters (const char *operand)
1077 1.1 skrll {
1078 1.1.1.2 christos const char *p = operand;
1079 1.1 skrll int d_used = 0, i_used = 0, u_used = 0, b_used = 0;
1080 1.1 skrll
1081 1.1 skrll while (*++p != ']')
1082 1.1 skrll {
1083 1.1 skrll if (*p == ',' || *p == ' ')
1084 1.1 skrll continue;
1085 1.1 skrll
1086 1.1 skrll if (*p == 'd')
1087 1.1 skrll d_used = 1;
1088 1.1 skrll else if (*p == 'i')
1089 1.1 skrll i_used = 1;
1090 1.1 skrll else if (*p == 'u')
1091 1.1 skrll u_used = 1;
1092 1.1 skrll else if (*p == 'b')
1093 1.1 skrll b_used = 1;
1094 1.1 skrll else
1095 1.1 skrll as_bad (_("Illegal `cinv' parameter: `%c'"), *p);
1096 1.1 skrll }
1097 1.1 skrll
1098 1.1 skrll return ((b_used ? 8 : 0)
1099 1.1 skrll + (d_used ? 4 : 0)
1100 1.1 skrll + (i_used ? 2 : 0)
1101 1.1 skrll + (u_used ? 1 : 0));
1102 1.1 skrll }
1103 1.1 skrll
1104 1.1 skrll /* Retrieve the opcode image of a given register.
1105 1.1 skrll If the register is illegal for the current instruction,
1106 1.1 skrll issue an error. */
1107 1.1 skrll
1108 1.1 skrll static int
1109 1.1 skrll getreg_image (reg r)
1110 1.1 skrll {
1111 1.1.1.2 christos const reg_entry *rreg;
1112 1.1 skrll char *reg_name;
1113 1.1 skrll int is_procreg = 0; /* Nonzero means argument should be processor reg. */
1114 1.1 skrll
1115 1.1 skrll if (((IS_INSN_MNEMONIC ("mtpr")) && (cur_arg_num == 1))
1116 1.1 skrll || ((IS_INSN_MNEMONIC ("mfpr")) && (cur_arg_num == 0)) )
1117 1.1 skrll is_procreg = 1;
1118 1.1 skrll
1119 1.1 skrll /* Check whether the register is in registers table. */
1120 1.1 skrll if (r < MAX_REG)
1121 1.1.1.2 christos rreg = &crx_regtab[r];
1122 1.1 skrll /* Check whether the register is in coprocessor registers table. */
1123 1.1.1.2 christos else if (r < (int) MAX_COPREG)
1124 1.1.1.2 christos rreg = &crx_copregtab[r-MAX_REG];
1125 1.1 skrll /* Register not found. */
1126 1.1 skrll else
1127 1.1 skrll {
1128 1.1 skrll as_bad (_("Unknown register: `%d'"), r);
1129 1.1 skrll return 0;
1130 1.1 skrll }
1131 1.1 skrll
1132 1.1.1.2 christos reg_name = rreg->name;
1133 1.1 skrll
1134 1.1 skrll /* Issue a error message when register is illegal. */
1135 1.1 skrll #define IMAGE_ERR \
1136 1.1 skrll as_bad (_("Illegal register (`%s') in Instruction: `%s'"), \
1137 1.1 skrll reg_name, ins_parse); \
1138 1.1 skrll break;
1139 1.1 skrll
1140 1.1.1.2 christos switch (rreg->type)
1141 1.1 skrll {
1142 1.1 skrll case CRX_U_REGTYPE:
1143 1.1 skrll if (is_procreg || (instruction->flags & USER_REG))
1144 1.1.1.2 christos return rreg->image;
1145 1.1 skrll else
1146 1.1 skrll IMAGE_ERR;
1147 1.1 skrll
1148 1.1 skrll case CRX_CFG_REGTYPE:
1149 1.1 skrll if (is_procreg)
1150 1.1.1.2 christos return rreg->image;
1151 1.1 skrll else
1152 1.1 skrll IMAGE_ERR;
1153 1.1 skrll
1154 1.1 skrll case CRX_R_REGTYPE:
1155 1.1 skrll if (! is_procreg)
1156 1.1.1.2 christos return rreg->image;
1157 1.1 skrll else
1158 1.1 skrll IMAGE_ERR;
1159 1.1 skrll
1160 1.1 skrll case CRX_C_REGTYPE:
1161 1.1 skrll case CRX_CS_REGTYPE:
1162 1.1.1.2 christos return rreg->image;
1163 1.1 skrll break;
1164 1.1 skrll
1165 1.1 skrll default:
1166 1.1 skrll IMAGE_ERR;
1167 1.1 skrll }
1168 1.1 skrll
1169 1.1 skrll return 0;
1170 1.1 skrll }
1171 1.1 skrll
1172 1.1 skrll /* Routine used to represent integer X using NBITS bits. */
1173 1.1 skrll
1174 1.1 skrll static long
1175 1.1 skrll getconstant (long x, int nbits)
1176 1.1 skrll {
1177 1.1.1.3 christos return x & ((((1U << (nbits - 1)) - 1) << 1) | 1);
1178 1.1 skrll }
1179 1.1 skrll
1180 1.1 skrll /* Print a constant value to 'output_opcode':
1181 1.1 skrll ARG holds the operand's type and value.
1182 1.1 skrll SHIFT represents the location of the operand to be print into.
1183 1.1 skrll NBITS determines the size (in bits) of the constant. */
1184 1.1 skrll
1185 1.1 skrll static void
1186 1.1 skrll print_constant (int nbits, int shift, argument *arg)
1187 1.1 skrll {
1188 1.1 skrll unsigned long mask = 0;
1189 1.1 skrll
1190 1.1 skrll long constant = getconstant (arg->constant, nbits);
1191 1.1 skrll
1192 1.1 skrll switch (nbits)
1193 1.1 skrll {
1194 1.1 skrll case 32:
1195 1.1 skrll case 28:
1196 1.1 skrll case 24:
1197 1.1 skrll case 22:
1198 1.1 skrll /* mask the upper part of the constant, that is, the bits
1199 1.1 skrll going to the lowest byte of output_opcode[0].
1200 1.1 skrll The upper part of output_opcode[1] is always filled,
1201 1.1 skrll therefore it is always masked with 0xFFFF. */
1202 1.1 skrll mask = (1 << (nbits - 16)) - 1;
1203 1.1 skrll /* Divide the constant between two consecutive words :
1204 1.1 skrll 0 1 2 3
1205 1.1 skrll +---------+---------+---------+---------+
1206 1.1 skrll | | X X X X | X X X X | |
1207 1.1 skrll +---------+---------+---------+---------+
1208 1.1 skrll output_opcode[0] output_opcode[1] */
1209 1.1 skrll
1210 1.1 skrll CRX_PRINT (0, (constant >> WORD_SHIFT) & mask, 0);
1211 1.1 skrll CRX_PRINT (1, (constant & 0xFFFF), WORD_SHIFT);
1212 1.1 skrll break;
1213 1.1 skrll
1214 1.1 skrll case 16:
1215 1.1 skrll case 12:
1216 1.1 skrll /* Special case - in arg_cr, the SHIFT represents the location
1217 1.1 skrll of the REGISTER, not the constant, which is itself not shifted. */
1218 1.1 skrll if (arg->type == arg_cr)
1219 1.1 skrll {
1220 1.1 skrll CRX_PRINT (0, constant, 0);
1221 1.1 skrll break;
1222 1.1 skrll }
1223 1.1 skrll
1224 1.1 skrll /* When instruction size is 3 and 'shift' is 16, a 16-bit constant is
1225 1.1 skrll always filling the upper part of output_opcode[1]. If we mistakenly
1226 1.1 skrll write it to output_opcode[0], the constant prefix (that is, 'match')
1227 1.1 skrll will be overridden.
1228 1.1 skrll 0 1 2 3
1229 1.1 skrll +---------+---------+---------+---------+
1230 1.1 skrll | 'match' | | X X X X | |
1231 1.1 skrll +---------+---------+---------+---------+
1232 1.1 skrll output_opcode[0] output_opcode[1] */
1233 1.1 skrll
1234 1.1 skrll if ((instruction->size > 2) && (shift == WORD_SHIFT))
1235 1.1 skrll CRX_PRINT (1, constant, WORD_SHIFT);
1236 1.1 skrll else
1237 1.1 skrll CRX_PRINT (0, constant, shift);
1238 1.1 skrll break;
1239 1.1 skrll
1240 1.1 skrll default:
1241 1.1 skrll CRX_PRINT (0, constant, shift);
1242 1.1 skrll break;
1243 1.1 skrll }
1244 1.1 skrll }
1245 1.1 skrll
1246 1.1 skrll /* Print an operand to 'output_opcode', which later on will be
1247 1.1 skrll printed to the object file:
1248 1.1 skrll ARG holds the operand's type, size and value.
1249 1.1 skrll SHIFT represents the printing location of operand.
1250 1.1 skrll NBITS determines the size (in bits) of a constant operand. */
1251 1.1 skrll
1252 1.1 skrll static void
1253 1.1 skrll print_operand (int nbits, int shift, argument *arg)
1254 1.1 skrll {
1255 1.1 skrll switch (arg->type)
1256 1.1 skrll {
1257 1.1 skrll case arg_r:
1258 1.1 skrll CRX_PRINT (0, getreg_image (arg->r), shift);
1259 1.1 skrll break;
1260 1.1 skrll
1261 1.1 skrll case arg_copr:
1262 1.1 skrll if (arg->cr < c0 || arg->cr > c15)
1263 1.1 skrll as_bad (_("Illegal Co-processor register in Instruction `%s' "),
1264 1.1 skrll ins_parse);
1265 1.1 skrll CRX_PRINT (0, getreg_image (arg->cr), shift);
1266 1.1 skrll break;
1267 1.1 skrll
1268 1.1 skrll case arg_copsr:
1269 1.1 skrll if (arg->cr < cs0 || arg->cr > cs15)
1270 1.1 skrll as_bad (_("Illegal Co-processor special register in Instruction `%s' "),
1271 1.1 skrll ins_parse);
1272 1.1 skrll CRX_PRINT (0, getreg_image (arg->cr), shift);
1273 1.1 skrll break;
1274 1.1 skrll
1275 1.1 skrll case arg_idxr:
1276 1.1 skrll /* 16 12 8 6 0
1277 1.1 skrll +--------------------------------+
1278 1.1 skrll | r_base | r_idx | scl| disp |
1279 1.1 skrll +--------------------------------+ */
1280 1.1 skrll CRX_PRINT (0, getreg_image (arg->r), 12);
1281 1.1 skrll CRX_PRINT (0, getreg_image (arg->i_r), 8);
1282 1.1 skrll CRX_PRINT (0, arg->scale, 6);
1283 1.1 skrll case arg_ic:
1284 1.1 skrll case arg_c:
1285 1.1 skrll print_constant (nbits, shift, arg);
1286 1.1 skrll break;
1287 1.1 skrll
1288 1.1 skrll case arg_rbase:
1289 1.1 skrll CRX_PRINT (0, getreg_image (arg->r), shift);
1290 1.1 skrll break;
1291 1.1 skrll
1292 1.1 skrll case arg_cr:
1293 1.1 skrll /* case base_cst4. */
1294 1.1 skrll if (instruction->flags & DISPU4MAP)
1295 1.1 skrll print_constant (nbits, shift + REG_SIZE, arg);
1296 1.1 skrll else
1297 1.1 skrll /* rbase_disps<NN> and other such cases. */
1298 1.1 skrll print_constant (nbits, shift, arg);
1299 1.1 skrll /* Add the register argument to the output_opcode. */
1300 1.1 skrll CRX_PRINT (0, getreg_image (arg->r), shift);
1301 1.1 skrll break;
1302 1.1 skrll
1303 1.1 skrll default:
1304 1.1 skrll break;
1305 1.1 skrll }
1306 1.1 skrll }
1307 1.1 skrll
1308 1.1 skrll /* Retrieve the number of operands for the current assembled instruction. */
1309 1.1 skrll
1310 1.1 skrll static int
1311 1.1 skrll get_number_of_operands (void)
1312 1.1 skrll {
1313 1.1 skrll int i;
1314 1.1 skrll
1315 1.1 skrll for (i = 0; instruction->operands[i].op_type && i < MAX_OPERANDS; i++)
1316 1.1 skrll ;
1317 1.1 skrll return i;
1318 1.1 skrll }
1319 1.1 skrll
1320 1.1 skrll /* Verify that the number NUM can be represented in BITS bits (that is,
1321 1.1 skrll within its permitted range), based on the instruction's FLAGS.
1322 1.1 skrll If UPDATE is nonzero, update the value of NUM if necessary.
1323 1.1 skrll Return OP_LEGAL upon success, actual error type upon failure. */
1324 1.1 skrll
1325 1.1 skrll static op_err
1326 1.1 skrll check_range (long *num, int bits, int unsigned flags, int update)
1327 1.1 skrll {
1328 1.1.1.3 christos uint32_t max;
1329 1.1 skrll int retval = OP_LEGAL;
1330 1.1 skrll int bin;
1331 1.1.1.3 christos uint32_t upper_64kb = 0xffff0000;
1332 1.1.1.3 christos uint32_t value = *num;
1333 1.1 skrll
1334 1.1 skrll /* Verify operand value is even. */
1335 1.1 skrll if (flags & OP_EVEN)
1336 1.1 skrll {
1337 1.1 skrll if (value % 2)
1338 1.1 skrll return OP_NOT_EVEN;
1339 1.1 skrll }
1340 1.1 skrll
1341 1.1 skrll if (flags & OP_UPPER_64KB)
1342 1.1 skrll {
1343 1.1 skrll /* Check if value is to be mapped to upper 64 KB memory area. */
1344 1.1 skrll if ((value & upper_64kb) == upper_64kb)
1345 1.1 skrll {
1346 1.1 skrll value -= upper_64kb;
1347 1.1 skrll if (update)
1348 1.1 skrll *num = value;
1349 1.1 skrll }
1350 1.1 skrll else
1351 1.1 skrll return OP_NOT_UPPER_64KB;
1352 1.1 skrll }
1353 1.1 skrll
1354 1.1 skrll if (flags & OP_SHIFT)
1355 1.1 skrll {
1356 1.1.1.3 christos /* All OP_SHIFT args are also OP_SIGNED, so we want to keep the
1357 1.1.1.3 christos sign. However, right shift of a signed type with a negative
1358 1.1.1.3 christos value is implementation defined. See ISO C 6.5.7. So we use
1359 1.1.1.3 christos an unsigned type and sign extend afterwards. */
1360 1.1 skrll value >>= 1;
1361 1.1.1.3 christos value = (value ^ 0x40000000) - 0x40000000;
1362 1.1 skrll if (update)
1363 1.1 skrll *num = value;
1364 1.1 skrll }
1365 1.1 skrll else if (flags & OP_SHIFT_DEC)
1366 1.1 skrll {
1367 1.1 skrll value = (value >> 1) - 1;
1368 1.1 skrll if (update)
1369 1.1 skrll *num = value;
1370 1.1 skrll }
1371 1.1 skrll
1372 1.1 skrll if (flags & OP_ESC)
1373 1.1 skrll {
1374 1.1 skrll /* 0x7e and 0x7f are reserved escape sequences of dispe9. */
1375 1.1 skrll if (value == 0x7e || value == 0x7f)
1376 1.1 skrll return OP_OUT_OF_RANGE;
1377 1.1 skrll }
1378 1.1 skrll
1379 1.1 skrll if (flags & OP_DISPU4)
1380 1.1 skrll {
1381 1.1 skrll int is_dispu4 = 0;
1382 1.1 skrll
1383 1.1.1.3 christos uint32_t mul = (instruction->flags & DISPUB4 ? 1
1384 1.1.1.3 christos : instruction->flags & DISPUW4 ? 2
1385 1.1.1.3 christos : instruction->flags & DISPUD4 ? 4
1386 1.1.1.3 christos : 0);
1387 1.1 skrll
1388 1.1 skrll for (bin = 0; bin < cst4_maps; bin++)
1389 1.1 skrll {
1390 1.1.1.3 christos if (value == mul * bin)
1391 1.1 skrll {
1392 1.1 skrll is_dispu4 = 1;
1393 1.1 skrll if (update)
1394 1.1 skrll *num = bin;
1395 1.1 skrll break;
1396 1.1 skrll }
1397 1.1 skrll }
1398 1.1 skrll if (!is_dispu4)
1399 1.1 skrll retval = OP_ILLEGAL_DISPU4;
1400 1.1 skrll }
1401 1.1 skrll else if (flags & OP_CST4)
1402 1.1 skrll {
1403 1.1 skrll int is_cst4 = 0;
1404 1.1 skrll
1405 1.1 skrll for (bin = 0; bin < cst4_maps; bin++)
1406 1.1 skrll {
1407 1.1.1.3 christos if (value == (uint32_t) cst4_map[bin])
1408 1.1 skrll {
1409 1.1 skrll is_cst4 = 1;
1410 1.1 skrll if (update)
1411 1.1 skrll *num = bin;
1412 1.1 skrll break;
1413 1.1 skrll }
1414 1.1 skrll }
1415 1.1 skrll if (!is_cst4)
1416 1.1 skrll retval = OP_ILLEGAL_CST4;
1417 1.1 skrll }
1418 1.1 skrll else if (flags & OP_SIGNED)
1419 1.1 skrll {
1420 1.1.1.3 christos max = 1;
1421 1.1.1.3 christos max = max << (bits - 1);
1422 1.1.1.3 christos value += max;
1423 1.1.1.3 christos max = ((max - 1) << 1) | 1;
1424 1.1.1.3 christos if (value > max)
1425 1.1 skrll retval = OP_OUT_OF_RANGE;
1426 1.1 skrll }
1427 1.1 skrll else if (flags & OP_UNSIGNED)
1428 1.1 skrll {
1429 1.1.1.3 christos max = 1;
1430 1.1.1.3 christos max = max << (bits - 1);
1431 1.1.1.3 christos max = ((max - 1) << 1) | 1;
1432 1.1.1.3 christos if (value > max)
1433 1.1 skrll retval = OP_OUT_OF_RANGE;
1434 1.1 skrll }
1435 1.1 skrll return retval;
1436 1.1 skrll }
1437 1.1 skrll
1438 1.1 skrll /* Assemble a single instruction:
1439 1.1 skrll INSN is already parsed (that is, all operand values and types are set).
1440 1.1 skrll For instruction to be assembled, we need to find an appropriate template in
1441 1.1 skrll the instruction table, meeting the following conditions:
1442 1.1 skrll 1: Has the same number of operands.
1443 1.1 skrll 2: Has the same operand types.
1444 1.1 skrll 3: Each operand size is sufficient to represent the instruction's values.
1445 1.1 skrll Returns 1 upon success, 0 upon failure. */
1446 1.1 skrll
1447 1.1 skrll static int
1448 1.1 skrll assemble_insn (char *mnemonic, ins *insn)
1449 1.1 skrll {
1450 1.1 skrll /* Type of each operand in the current template. */
1451 1.1 skrll argtype cur_type[MAX_OPERANDS];
1452 1.1 skrll /* Size (in bits) of each operand in the current template. */
1453 1.1 skrll unsigned int cur_size[MAX_OPERANDS];
1454 1.1 skrll /* Flags of each operand in the current template. */
1455 1.1 skrll unsigned int cur_flags[MAX_OPERANDS];
1456 1.1 skrll /* Instruction type to match. */
1457 1.1 skrll unsigned int ins_type;
1458 1.1 skrll /* Boolean flag to mark whether a match was found. */
1459 1.1 skrll int match = 0;
1460 1.1 skrll int i;
1461 1.1 skrll /* Nonzero if an instruction with same number of operands was found. */
1462 1.1 skrll int found_same_number_of_operands = 0;
1463 1.1 skrll /* Nonzero if an instruction with same argument types was found. */
1464 1.1 skrll int found_same_argument_types = 0;
1465 1.1 skrll /* Nonzero if a constant was found within the required range. */
1466 1.1 skrll int found_const_within_range = 0;
1467 1.1 skrll /* Argument number of an operand with invalid type. */
1468 1.1 skrll int invalid_optype = -1;
1469 1.1 skrll /* Argument number of an operand with invalid constant value. */
1470 1.1 skrll int invalid_const = -1;
1471 1.1 skrll /* Operand error (used for issuing various constant error messages). */
1472 1.1 skrll op_err op_error, const_err = OP_LEGAL;
1473 1.1 skrll
1474 1.1 skrll /* Retrieve data (based on FUNC) for each operand of a given instruction. */
1475 1.1 skrll #define GET_CURRENT_DATA(FUNC, ARRAY) \
1476 1.1 skrll for (i = 0; i < insn->nargs; i++) \
1477 1.1 skrll ARRAY[i] = FUNC (instruction->operands[i].op_type)
1478 1.1 skrll
1479 1.1 skrll #define GET_CURRENT_TYPE GET_CURRENT_DATA(get_optype, cur_type)
1480 1.1 skrll #define GET_CURRENT_SIZE GET_CURRENT_DATA(get_opbits, cur_size)
1481 1.1 skrll #define GET_CURRENT_FLAGS GET_CURRENT_DATA(get_opflags, cur_flags)
1482 1.1 skrll
1483 1.1 skrll /* Instruction has no operands -> only copy the constant opcode. */
1484 1.1 skrll if (insn->nargs == 0)
1485 1.1 skrll {
1486 1.1 skrll output_opcode[0] = BIN (instruction->match, instruction->match_bits);
1487 1.1 skrll return 1;
1488 1.1 skrll }
1489 1.1 skrll
1490 1.1 skrll /* In some case, same mnemonic can appear with different instruction types.
1491 1.1 skrll For example, 'storb' is supported with 3 different types :
1492 1.1 skrll LD_STOR_INS, LD_STOR_INS_INC, STOR_IMM_INS.
1493 1.1 skrll We assume that when reaching this point, the instruction type was
1494 1.1 skrll pre-determined. We need to make sure that the type stays the same
1495 1.1 skrll during a search for matching instruction. */
1496 1.1 skrll ins_type = CRX_INS_TYPE(instruction->flags);
1497 1.1 skrll
1498 1.1 skrll while (/* Check that match is still not found. */
1499 1.1 skrll match != 1
1500 1.1 skrll /* Check we didn't get to end of table. */
1501 1.1 skrll && instruction->mnemonic != NULL
1502 1.1 skrll /* Check that the actual mnemonic is still available. */
1503 1.1 skrll && IS_INSN_MNEMONIC (mnemonic)
1504 1.1 skrll /* Check that the instruction type wasn't changed. */
1505 1.1 skrll && IS_INSN_TYPE(ins_type))
1506 1.1 skrll {
1507 1.1 skrll /* Check whether number of arguments is legal. */
1508 1.1 skrll if (get_number_of_operands () != insn->nargs)
1509 1.1 skrll goto next_insn;
1510 1.1 skrll found_same_number_of_operands = 1;
1511 1.1 skrll
1512 1.1 skrll /* Initialize arrays with data of each operand in current template. */
1513 1.1 skrll GET_CURRENT_TYPE;
1514 1.1 skrll GET_CURRENT_SIZE;
1515 1.1 skrll GET_CURRENT_FLAGS;
1516 1.1 skrll
1517 1.1 skrll /* Check for type compatibility. */
1518 1.1 skrll for (i = 0; i < insn->nargs; i++)
1519 1.1 skrll {
1520 1.1 skrll if (cur_type[i] != insn->arg[i].type)
1521 1.1 skrll {
1522 1.1 skrll if (invalid_optype == -1)
1523 1.1 skrll invalid_optype = i + 1;
1524 1.1 skrll goto next_insn;
1525 1.1 skrll }
1526 1.1 skrll }
1527 1.1 skrll found_same_argument_types = 1;
1528 1.1 skrll
1529 1.1 skrll for (i = 0; i < insn->nargs; i++)
1530 1.1 skrll {
1531 1.1 skrll /* Reverse the operand indices for certain opcodes:
1532 1.1 skrll Index 0 -->> 1
1533 1.1 skrll Index 1 -->> 0
1534 1.1 skrll Other index -->> stays the same. */
1535 1.1 skrll int j = instruction->flags & REVERSE_MATCH ?
1536 1.1 skrll i == 0 ? 1 :
1537 1.1 skrll i == 1 ? 0 : i :
1538 1.1 skrll i;
1539 1.1 skrll
1540 1.1 skrll /* Only check range - don't update the constant's value, since the
1541 1.1 skrll current instruction may not be the last we try to match.
1542 1.1 skrll The constant's value will be updated later, right before printing
1543 1.1 skrll it to the object file. */
1544 1.1 skrll if ((insn->arg[j].X_op == O_constant)
1545 1.1 skrll && (op_error = check_range (&insn->arg[j].constant, cur_size[j],
1546 1.1 skrll cur_flags[j], 0)))
1547 1.1 skrll {
1548 1.1 skrll if (invalid_const == -1)
1549 1.1 skrll {
1550 1.1 skrll invalid_const = j + 1;
1551 1.1 skrll const_err = op_error;
1552 1.1 skrll }
1553 1.1 skrll goto next_insn;
1554 1.1 skrll }
1555 1.1 skrll /* For symbols, we make sure the relocation size (which was already
1556 1.1 skrll determined) is sufficient. */
1557 1.1 skrll else if ((insn->arg[j].X_op == O_symbol)
1558 1.1 skrll && ((bfd_reloc_type_lookup (stdoutput, insn->rtype))->bitsize
1559 1.1 skrll > cur_size[j]))
1560 1.1 skrll goto next_insn;
1561 1.1 skrll }
1562 1.1 skrll found_const_within_range = 1;
1563 1.1 skrll
1564 1.1 skrll /* If we got till here -> Full match is found. */
1565 1.1 skrll match = 1;
1566 1.1 skrll break;
1567 1.1 skrll
1568 1.1 skrll /* Try again with next instruction. */
1569 1.1 skrll next_insn:
1570 1.1 skrll instruction++;
1571 1.1 skrll }
1572 1.1 skrll
1573 1.1 skrll if (!match)
1574 1.1 skrll {
1575 1.1 skrll /* We haven't found a match - instruction can't be assembled. */
1576 1.1 skrll if (!found_same_number_of_operands)
1577 1.1 skrll as_bad (_("Incorrect number of operands"));
1578 1.1 skrll else if (!found_same_argument_types)
1579 1.1 skrll as_bad (_("Illegal type of operand (arg %d)"), invalid_optype);
1580 1.1 skrll else if (!found_const_within_range)
1581 1.1 skrll {
1582 1.1 skrll switch (const_err)
1583 1.1 skrll {
1584 1.1 skrll case OP_OUT_OF_RANGE:
1585 1.1 skrll as_bad (_("Operand out of range (arg %d)"), invalid_const);
1586 1.1 skrll break;
1587 1.1 skrll case OP_NOT_EVEN:
1588 1.1 skrll as_bad (_("Operand has odd displacement (arg %d)"), invalid_const);
1589 1.1 skrll break;
1590 1.1 skrll case OP_ILLEGAL_DISPU4:
1591 1.1 skrll as_bad (_("Invalid DISPU4 operand value (arg %d)"), invalid_const);
1592 1.1 skrll break;
1593 1.1 skrll case OP_ILLEGAL_CST4:
1594 1.1 skrll as_bad (_("Invalid CST4 operand value (arg %d)"), invalid_const);
1595 1.1 skrll break;
1596 1.1 skrll case OP_NOT_UPPER_64KB:
1597 1.1 skrll as_bad (_("Operand value is not within upper 64 KB (arg %d)"),
1598 1.1 skrll invalid_const);
1599 1.1 skrll break;
1600 1.1 skrll default:
1601 1.1 skrll as_bad (_("Illegal operand (arg %d)"), invalid_const);
1602 1.1 skrll break;
1603 1.1 skrll }
1604 1.1 skrll }
1605 1.1 skrll
1606 1.1 skrll return 0;
1607 1.1 skrll }
1608 1.1 skrll else
1609 1.1 skrll /* Full match - print the encoding to output file. */
1610 1.1 skrll {
1611 1.1 skrll /* Make further checkings (such that couldn't be made earlier).
1612 1.1 skrll Warn the user if necessary. */
1613 1.1 skrll warn_if_needed (insn);
1614 1.1 skrll
1615 1.1 skrll /* Check whether we need to adjust the instruction pointer. */
1616 1.1 skrll if (adjust_if_needed (insn))
1617 1.1 skrll /* If instruction pointer was adjusted, we need to update
1618 1.1 skrll the size of the current template operands. */
1619 1.1 skrll GET_CURRENT_SIZE;
1620 1.1 skrll
1621 1.1 skrll for (i = 0; i < insn->nargs; i++)
1622 1.1 skrll {
1623 1.1 skrll int j = instruction->flags & REVERSE_MATCH ?
1624 1.1 skrll i == 0 ? 1 :
1625 1.1 skrll i == 1 ? 0 : i :
1626 1.1 skrll i;
1627 1.1 skrll
1628 1.1 skrll /* This time, update constant value before printing it. */
1629 1.1 skrll if ((insn->arg[j].X_op == O_constant)
1630 1.1 skrll && (check_range (&insn->arg[j].constant, cur_size[j],
1631 1.1 skrll cur_flags[j], 1) != OP_LEGAL))
1632 1.1 skrll as_fatal (_("Illegal operand (arg %d)"), j+1);
1633 1.1 skrll }
1634 1.1 skrll
1635 1.1 skrll /* First, copy the instruction's opcode. */
1636 1.1 skrll output_opcode[0] = BIN (instruction->match, instruction->match_bits);
1637 1.1 skrll
1638 1.1 skrll for (i = 0; i < insn->nargs; i++)
1639 1.1 skrll {
1640 1.1 skrll cur_arg_num = i;
1641 1.1 skrll print_operand (cur_size[i], instruction->operands[i].shift,
1642 1.1 skrll &insn->arg[i]);
1643 1.1 skrll }
1644 1.1 skrll }
1645 1.1 skrll
1646 1.1 skrll return 1;
1647 1.1 skrll }
1648 1.1 skrll
1649 1.1 skrll /* Bunch of error checkings.
1650 1.1 skrll The checks are made after a matching instruction was found. */
1651 1.1 skrll
1652 1.1 skrll void
1653 1.1 skrll warn_if_needed (ins *insn)
1654 1.1 skrll {
1655 1.1 skrll /* If the post-increment address mode is used and the load/store
1656 1.1 skrll source register is the same as rbase, the result of the
1657 1.1 skrll instruction is undefined. */
1658 1.1 skrll if (IS_INSN_TYPE (LD_STOR_INS_INC))
1659 1.1 skrll {
1660 1.1 skrll /* Enough to verify that one of the arguments is a simple reg. */
1661 1.1 skrll if ((insn->arg[0].type == arg_r) || (insn->arg[1].type == arg_r))
1662 1.1 skrll if (insn->arg[0].r == insn->arg[1].r)
1663 1.1 skrll as_bad (_("Same src/dest register is used (`r%d'), result is undefined"),
1664 1.1 skrll insn->arg[0].r);
1665 1.1 skrll }
1666 1.1 skrll
1667 1.1 skrll /* Some instruction assume the stack pointer as rptr operand.
1668 1.1 skrll Issue an error when the register to be loaded is also SP. */
1669 1.1 skrll if (instruction->flags & NO_SP)
1670 1.1 skrll {
1671 1.1 skrll if (getreg_image (insn->arg[0].r) == getreg_image (sp))
1672 1.1 skrll as_bad (_("`%s' has undefined result"), ins_parse);
1673 1.1 skrll }
1674 1.1 skrll
1675 1.1 skrll /* If the rptr register is specified as one of the registers to be loaded,
1676 1.1 skrll the final contents of rptr are undefined. Thus, we issue an error. */
1677 1.1 skrll if (instruction->flags & NO_RPTR)
1678 1.1 skrll {
1679 1.1 skrll if ((1 << getreg_image (insn->arg[0].r)) & insn->arg[1].constant)
1680 1.1 skrll as_bad (_("Same src/dest register is used (`r%d'), result is undefined"),
1681 1.1 skrll getreg_image (insn->arg[0].r));
1682 1.1 skrll }
1683 1.1 skrll }
1684 1.1 skrll
1685 1.1 skrll /* In some cases, we need to adjust the instruction pointer although a
1686 1.1 skrll match was already found. Here, we gather all these cases.
1687 1.1 skrll Returns 1 if instruction pointer was adjusted, otherwise 0. */
1688 1.1 skrll
1689 1.1 skrll int
1690 1.1 skrll adjust_if_needed (ins *insn)
1691 1.1 skrll {
1692 1.1 skrll int ret_value = 0;
1693 1.1 skrll
1694 1.1 skrll /* Special check for 'addub $0, r0' instruction -
1695 1.1 skrll The opcode '0000 0000 0000 0000' is not allowed. */
1696 1.1 skrll if (IS_INSN_MNEMONIC ("addub"))
1697 1.1 skrll {
1698 1.1 skrll if ((instruction->operands[0].op_type == cst4)
1699 1.1 skrll && instruction->operands[1].op_type == regr)
1700 1.1 skrll {
1701 1.1 skrll if (insn->arg[0].constant == 0 && insn->arg[1].r == r0)
1702 1.1 skrll {
1703 1.1 skrll instruction++;
1704 1.1 skrll ret_value = 1;
1705 1.1 skrll }
1706 1.1 skrll }
1707 1.1 skrll }
1708 1.1 skrll
1709 1.1 skrll /* Optimization: Omit a zero displacement in bit operations,
1710 1.1 skrll saving 2-byte encoding space (e.g., 'cbitw $8, 0(r1)'). */
1711 1.1 skrll if (IS_INSN_TYPE (CSTBIT_INS))
1712 1.1 skrll {
1713 1.1 skrll if ((instruction->operands[1].op_type == rbase_disps12)
1714 1.1 skrll && (insn->arg[1].X_op == O_constant)
1715 1.1 skrll && (insn->arg[1].constant == 0))
1716 1.1 skrll {
1717 1.1 skrll instruction--;
1718 1.1 skrll ret_value = 1;
1719 1.1 skrll }
1720 1.1 skrll }
1721 1.1 skrll
1722 1.1 skrll return ret_value;
1723 1.1 skrll }
1724 1.1 skrll
1725 1.1 skrll /* Set the appropriate bit for register 'r' in 'mask'.
1726 1.1 skrll This indicates that this register is loaded or stored by
1727 1.1 skrll the instruction. */
1728 1.1 skrll
1729 1.1 skrll static void
1730 1.1 skrll mask_reg (int r, unsigned short int *mask)
1731 1.1 skrll {
1732 1.1 skrll if ((reg)r > (reg)sp)
1733 1.1 skrll {
1734 1.1 skrll as_bad (_("Invalid Register in Register List"));
1735 1.1 skrll return;
1736 1.1 skrll }
1737 1.1 skrll
1738 1.1 skrll *mask |= (1 << r);
1739 1.1 skrll }
1740 1.1 skrll
1741 1.1 skrll /* Preprocess register list - create a 16-bit mask with one bit for each
1742 1.1 skrll of the 16 general purpose registers. If a bit is set, it indicates
1743 1.1 skrll that this register is loaded or stored by the instruction. */
1744 1.1 skrll
1745 1.1 skrll static char *
1746 1.1 skrll preprocess_reglist (char *param, int *allocated)
1747 1.1 skrll {
1748 1.1 skrll char reg_name[MAX_REGNAME_LEN]; /* Current parsed register name. */
1749 1.1 skrll char *regP; /* Pointer to 'reg_name' string. */
1750 1.1 skrll int reg_counter = 0; /* Count number of parsed registers. */
1751 1.1 skrll unsigned short int mask = 0; /* Mask for 16 general purpose registers. */
1752 1.1 skrll char *new_param; /* New created operands string. */
1753 1.1 skrll char *paramP = param; /* Pointer to original opearands string. */
1754 1.1 skrll char maskstring[10]; /* Array to print the mask as a string. */
1755 1.1 skrll int hi_found = 0, lo_found = 0; /* Boolean flags for hi/lo registers. */
1756 1.1 skrll reg r;
1757 1.1 skrll copreg cr;
1758 1.1 skrll
1759 1.1 skrll /* If 'param' is already in form of a number, no need to preprocess. */
1760 1.1 skrll if (strchr (paramP, '{') == NULL)
1761 1.1 skrll return param;
1762 1.1 skrll
1763 1.1 skrll /* Verifying correct syntax of operand. */
1764 1.1 skrll if (strchr (paramP, '}') == NULL)
1765 1.1 skrll as_fatal (_("Missing matching brackets : `%s'"), ins_parse);
1766 1.1 skrll
1767 1.1 skrll while (*paramP++ != '{');
1768 1.1 skrll
1769 1.1 skrll new_param = (char *)xcalloc (MAX_INST_LEN, sizeof (char));
1770 1.1 skrll *allocated = 1;
1771 1.1 skrll strncpy (new_param, param, paramP - param - 1);
1772 1.1 skrll
1773 1.1 skrll while (*paramP != '}')
1774 1.1 skrll {
1775 1.1 skrll regP = paramP;
1776 1.1 skrll memset (®_name, '\0', sizeof (reg_name));
1777 1.1 skrll
1778 1.1 skrll while (ISALNUM (*paramP))
1779 1.1 skrll paramP++;
1780 1.1 skrll
1781 1.1 skrll strncpy (reg_name, regP, paramP - regP);
1782 1.1 skrll
1783 1.1 skrll /* Coprocessor register c<N>. */
1784 1.1 skrll if (IS_INSN_TYPE (COP_REG_INS))
1785 1.1 skrll {
1786 1.1 skrll if (((cr = get_copregister (reg_name)) == nullcopregister)
1787 1.1 skrll || (crx_copregtab[cr-MAX_REG].type != CRX_C_REGTYPE))
1788 1.1 skrll as_fatal (_("Illegal register `%s' in cop-register list"), reg_name);
1789 1.1 skrll mask_reg (getreg_image (cr - c0), &mask);
1790 1.1 skrll }
1791 1.1 skrll /* Coprocessor Special register cs<N>. */
1792 1.1 skrll else if (IS_INSN_TYPE (COPS_REG_INS))
1793 1.1 skrll {
1794 1.1 skrll if (((cr = get_copregister (reg_name)) == nullcopregister)
1795 1.1 skrll || (crx_copregtab[cr-MAX_REG].type != CRX_CS_REGTYPE))
1796 1.1 skrll as_fatal (_("Illegal register `%s' in cop-special-register list"),
1797 1.1 skrll reg_name);
1798 1.1 skrll mask_reg (getreg_image (cr - cs0), &mask);
1799 1.1 skrll }
1800 1.1 skrll /* User register u<N>. */
1801 1.1 skrll else if (instruction->flags & USER_REG)
1802 1.1 skrll {
1803 1.1 skrll if (streq(reg_name, "uhi"))
1804 1.1 skrll {
1805 1.1 skrll hi_found = 1;
1806 1.1 skrll goto next_inst;
1807 1.1 skrll }
1808 1.1 skrll else if (streq(reg_name, "ulo"))
1809 1.1 skrll {
1810 1.1 skrll lo_found = 1;
1811 1.1 skrll goto next_inst;
1812 1.1 skrll }
1813 1.1 skrll else if (((r = get_register (reg_name)) == nullregister)
1814 1.1 skrll || (crx_regtab[r].type != CRX_U_REGTYPE))
1815 1.1 skrll as_fatal (_("Illegal register `%s' in user register list"), reg_name);
1816 1.1 skrll
1817 1.1 skrll mask_reg (getreg_image (r - u0), &mask);
1818 1.1 skrll }
1819 1.1 skrll /* General purpose register r<N>. */
1820 1.1 skrll else
1821 1.1 skrll {
1822 1.1 skrll if (streq(reg_name, "hi"))
1823 1.1 skrll {
1824 1.1 skrll hi_found = 1;
1825 1.1 skrll goto next_inst;
1826 1.1 skrll }
1827 1.1 skrll else if (streq(reg_name, "lo"))
1828 1.1 skrll {
1829 1.1 skrll lo_found = 1;
1830 1.1 skrll goto next_inst;
1831 1.1 skrll }
1832 1.1 skrll else if (((r = get_register (reg_name)) == nullregister)
1833 1.1 skrll || (crx_regtab[r].type != CRX_R_REGTYPE))
1834 1.1 skrll as_fatal (_("Illegal register `%s' in register list"), reg_name);
1835 1.1 skrll
1836 1.1 skrll mask_reg (getreg_image (r - r0), &mask);
1837 1.1 skrll }
1838 1.1 skrll
1839 1.1 skrll if (++reg_counter > MAX_REGS_IN_MASK16)
1840 1.1 skrll as_bad (_("Maximum %d bits may be set in `mask16' operand"),
1841 1.1 skrll MAX_REGS_IN_MASK16);
1842 1.1 skrll
1843 1.1 skrll next_inst:
1844 1.1 skrll while (!ISALNUM (*paramP) && *paramP != '}')
1845 1.1 skrll paramP++;
1846 1.1 skrll }
1847 1.1 skrll
1848 1.1 skrll if (*++paramP != '\0')
1849 1.1 skrll as_warn (_("rest of line ignored; first ignored character is `%c'"),
1850 1.1 skrll *paramP);
1851 1.1 skrll
1852 1.1 skrll switch (hi_found + lo_found)
1853 1.1 skrll {
1854 1.1 skrll case 0:
1855 1.1 skrll /* At least one register should be specified. */
1856 1.1 skrll if (mask == 0)
1857 1.1 skrll as_bad (_("Illegal `mask16' operand, operation is undefined - `%s'"),
1858 1.1 skrll ins_parse);
1859 1.1 skrll break;
1860 1.1 skrll
1861 1.1 skrll case 1:
1862 1.1 skrll /* HI can't be specified without LO (and vise-versa). */
1863 1.1 skrll as_bad (_("HI/LO registers should be specified together"));
1864 1.1 skrll break;
1865 1.1 skrll
1866 1.1 skrll case 2:
1867 1.1 skrll /* HI/LO registers mustn't be masked with additional registers. */
1868 1.1 skrll if (mask != 0)
1869 1.1 skrll as_bad (_("HI/LO registers should be specified without additional registers"));
1870 1.1 skrll
1871 1.1 skrll default:
1872 1.1 skrll break;
1873 1.1 skrll }
1874 1.1 skrll
1875 1.1 skrll sprintf (maskstring, "$0x%x", mask);
1876 1.1 skrll strcat (new_param, maskstring);
1877 1.1 skrll return new_param;
1878 1.1 skrll }
1879 1.1 skrll
1880 1.1 skrll /* Print the instruction.
1881 1.1 skrll Handle also cases where the instruction is relaxable/relocatable. */
1882 1.1 skrll
1883 1.1 skrll void
1884 1.1 skrll print_insn (ins *insn)
1885 1.1 skrll {
1886 1.1 skrll unsigned int i, j, insn_size;
1887 1.1 skrll char *this_frag;
1888 1.1 skrll unsigned short words[4];
1889 1.1 skrll int addr_mod;
1890 1.1 skrll
1891 1.1 skrll /* Arrange the insn encodings in a WORD size array. */
1892 1.1 skrll for (i = 0, j = 0; i < 2; i++)
1893 1.1 skrll {
1894 1.1 skrll words[j++] = (output_opcode[i] >> 16) & 0xFFFF;
1895 1.1 skrll words[j++] = output_opcode[i] & 0xFFFF;
1896 1.1 skrll }
1897 1.1 skrll
1898 1.1 skrll /* Handle relaxtion. */
1899 1.1 skrll if ((instruction->flags & RELAXABLE) && relocatable)
1900 1.1 skrll {
1901 1.1 skrll int relax_subtype;
1902 1.1 skrll
1903 1.1 skrll /* Write the maximal instruction size supported. */
1904 1.1 skrll insn_size = INSN_MAX_SIZE;
1905 1.1 skrll
1906 1.1 skrll /* bCC */
1907 1.1 skrll if (IS_INSN_TYPE (BRANCH_INS))
1908 1.1 skrll relax_subtype = 0;
1909 1.1 skrll /* bal */
1910 1.1 skrll else if (IS_INSN_TYPE (DCR_BRANCH_INS) || IS_INSN_MNEMONIC ("bal"))
1911 1.1 skrll relax_subtype = 3;
1912 1.1 skrll /* cmpbr/bcop */
1913 1.1 skrll else if (IS_INSN_TYPE (CMPBR_INS) || IS_INSN_TYPE (COP_BRANCH_INS))
1914 1.1 skrll relax_subtype = 5;
1915 1.1 skrll else
1916 1.1 skrll abort ();
1917 1.1 skrll
1918 1.1 skrll this_frag = frag_var (rs_machine_dependent, insn_size * 2,
1919 1.1 skrll 4, relax_subtype,
1920 1.1 skrll insn->exp.X_add_symbol,
1921 1.1 skrll insn->exp.X_add_number,
1922 1.1 skrll 0);
1923 1.1 skrll }
1924 1.1 skrll else
1925 1.1 skrll {
1926 1.1 skrll insn_size = instruction->size;
1927 1.1 skrll this_frag = frag_more (insn_size * 2);
1928 1.1 skrll
1929 1.1 skrll /* Handle relocation. */
1930 1.1 skrll if ((relocatable) && (insn->rtype != BFD_RELOC_NONE))
1931 1.1 skrll {
1932 1.1 skrll reloc_howto_type *reloc_howto;
1933 1.1 skrll int size;
1934 1.1 skrll
1935 1.1 skrll reloc_howto = bfd_reloc_type_lookup (stdoutput, insn->rtype);
1936 1.1 skrll
1937 1.1 skrll if (!reloc_howto)
1938 1.1 skrll abort ();
1939 1.1 skrll
1940 1.1 skrll size = bfd_get_reloc_size (reloc_howto);
1941 1.1 skrll
1942 1.1 skrll if (size < 1 || size > 4)
1943 1.1 skrll abort ();
1944 1.1 skrll
1945 1.1 skrll fix_new_exp (frag_now, this_frag - frag_now->fr_literal,
1946 1.1 skrll size, &insn->exp, reloc_howto->pc_relative,
1947 1.1 skrll insn->rtype);
1948 1.1 skrll }
1949 1.1 skrll }
1950 1.1 skrll
1951 1.1 skrll /* Verify a 2-byte code alignment. */
1952 1.1 skrll addr_mod = frag_now_fix () & 1;
1953 1.1 skrll if (frag_now->has_code && frag_now->insn_addr != addr_mod)
1954 1.1 skrll as_bad (_("instruction address is not a multiple of 2"));
1955 1.1 skrll frag_now->insn_addr = addr_mod;
1956 1.1 skrll frag_now->has_code = 1;
1957 1.1 skrll
1958 1.1 skrll /* Write the instruction encoding to frag. */
1959 1.1 skrll for (i = 0; i < insn_size; i++)
1960 1.1 skrll {
1961 1.1 skrll md_number_to_chars (this_frag, (valueT) words[i], 2);
1962 1.1 skrll this_frag += 2;
1963 1.1 skrll }
1964 1.1 skrll }
1965 1.1 skrll
1966 1.1 skrll /* This is the guts of the machine-dependent assembler. OP points to a
1967 1.1 skrll machine dependent instruction. This function is supposed to emit
1968 1.1 skrll the frags/bytes it assembles to. */
1969 1.1 skrll
1970 1.1 skrll void
1971 1.1 skrll md_assemble (char *op)
1972 1.1 skrll {
1973 1.1 skrll ins crx_ins;
1974 1.1 skrll char *param;
1975 1.1 skrll char c;
1976 1.1 skrll
1977 1.1 skrll /* Reset global variables for a new instruction. */
1978 1.1 skrll reset_vars (op);
1979 1.1 skrll
1980 1.1 skrll /* Strip the mnemonic. */
1981 1.1 skrll for (param = op; *param != 0 && !ISSPACE (*param); param++)
1982 1.1 skrll ;
1983 1.1 skrll c = *param;
1984 1.1 skrll *param++ = '\0';
1985 1.1 skrll
1986 1.1 skrll /* Find the instruction. */
1987 1.1 skrll instruction = (const inst *) hash_find (crx_inst_hash, op);
1988 1.1 skrll if (instruction == NULL)
1989 1.1 skrll {
1990 1.1 skrll as_bad (_("Unknown opcode: `%s'"), op);
1991 1.1.1.2 christos param[-1] = c;
1992 1.1 skrll return;
1993 1.1 skrll }
1994 1.1 skrll
1995 1.1 skrll /* Tie dwarf2 debug info to the address at the start of the insn. */
1996 1.1 skrll dwarf2_emit_insn (0);
1997 1.1 skrll
1998 1.1 skrll /* Parse the instruction's operands. */
1999 1.1 skrll parse_insn (&crx_ins, param);
2000 1.1 skrll
2001 1.1 skrll /* Assemble the instruction - return upon failure. */
2002 1.1 skrll if (assemble_insn (op, &crx_ins) == 0)
2003 1.1.1.2 christos {
2004 1.1.1.2 christos param[-1] = c;
2005 1.1.1.2 christos return;
2006 1.1.1.2 christos }
2007 1.1 skrll
2008 1.1 skrll /* Print the instruction. */
2009 1.1.1.2 christos param[-1] = c;
2010 1.1 skrll print_insn (&crx_ins);
2011 1.1 skrll }
2012