tc-dlx.c revision 1.1.1.11 1 1.1.1.3 christos /* tc-dlx.c -- Assemble for the DLX
2 1.1.1.11 christos Copyright (C) 2002-2026 Free Software Foundation, Inc.
3 1.1 skrll
4 1.1 skrll This file is part of GAS, the GNU Assembler.
5 1.1 skrll
6 1.1 skrll GAS is free software; you can redistribute it and/or modify
7 1.1 skrll it under the terms of the GNU General Public License as published by
8 1.1 skrll the Free Software Foundation; either version 3, or (at your option)
9 1.1 skrll any later version.
10 1.1 skrll
11 1.1 skrll GAS is distributed in the hope that it will be useful,
12 1.1 skrll but WITHOUT ANY WARRANTY; without even the implied warranty of
13 1.1 skrll MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 1.1 skrll GNU General Public License for more details.
15 1.1 skrll
16 1.1 skrll You should have received a copy of the GNU General Public License
17 1.1 skrll along with GAS; see the file COPYING. If not, write to the Free
18 1.1 skrll Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
19 1.1 skrll 02110-1301, USA. */
20 1.1 skrll
21 1.1 skrll /* Initially created by Kuang Hwa Lin, 3/20/2002. */
22 1.1 skrll
23 1.1 skrll #include "as.h"
24 1.1.1.3 christos #include "safe-ctype.h"
25 1.1 skrll #include "tc-dlx.h"
26 1.1 skrll #include "opcode/dlx.h"
27 1.1.1.5 christos #include "elf/dlx.h"
28 1.1.1.5 christos #include "bfd/elf32-dlx.h"
29 1.1 skrll
30 1.1 skrll /* Make it easier to clone this machine desc into another one. */
31 1.1 skrll #define machine_opcode dlx_opcode
32 1.1 skrll #define machine_opcodes dlx_opcodes
33 1.1 skrll #define machine_ip dlx_ip
34 1.1 skrll #define machine_it dlx_it
35 1.1 skrll
36 1.1 skrll #define NO_RELOC BFD_RELOC_NONE
37 1.1 skrll #define RELOC_DLX_REL26 BFD_RELOC_DLX_JMP26
38 1.1 skrll #define RELOC_DLX_16 BFD_RELOC_16
39 1.1 skrll #define RELOC_DLX_REL16 BFD_RELOC_16_PCREL_S2
40 1.1 skrll #define RELOC_DLX_HI16 BFD_RELOC_HI16_S
41 1.1 skrll #define RELOC_DLX_LO16 BFD_RELOC_LO16
42 1.1 skrll #define RELOC_DLX_VTINHERIT BFD_RELOC_VTABLE_INHERIT
43 1.1 skrll #define RELOC_DLX_VTENTRY BFD_RELOC_VTABLE_ENTRY
44 1.1 skrll
45 1.1 skrll /* handle of the OPCODE hash table */
46 1.1.1.8 christos static htab_t op_hash = NULL;
47 1.1 skrll
48 1.1 skrll struct machine_it
49 1.1 skrll {
50 1.1 skrll char *error;
51 1.1 skrll unsigned long opcode;
52 1.1 skrll struct nlist *nlistp;
53 1.1 skrll expressionS exp;
54 1.1 skrll int pcrel;
55 1.1 skrll int size;
56 1.1 skrll int reloc_offset; /* Offset of reloc within insn. */
57 1.1.1.5 christos bfd_reloc_code_real_type reloc;
58 1.1 skrll int HI;
59 1.1 skrll int LO;
60 1.1 skrll }
61 1.1 skrll the_insn;
62 1.1 skrll
63 1.1 skrll /* This array holds the chars that always start a comment. If the
64 1.1 skrll pre-processor is disabled, these aren't very useful. */
65 1.1 skrll const char comment_chars[] = ";";
66 1.1 skrll
67 1.1 skrll /* This array holds the chars that only start a comment at the beginning of
68 1.1 skrll a line. If the line seems to have the form '# 123 filename'
69 1.1 skrll .line and .file directives will appear in the pre-processed output. */
70 1.1 skrll /* Note that input_file.c hand checks for '#' at the beginning of the
71 1.1 skrll first line of the input file. This is because the compiler outputs
72 1.1 skrll #NO_APP at the beginning of its output. */
73 1.1 skrll /* Also note that comments like this one will always work. */
74 1.1 skrll const char line_comment_chars[] = "#";
75 1.1 skrll
76 1.1 skrll /* We needed an unused char for line separation to work around the
77 1.1 skrll lack of macros, using sed and such. */
78 1.1 skrll const char line_separator_chars[] = "@";
79 1.1 skrll
80 1.1 skrll /* Chars that can be used to separate mant from exp in floating point nums. */
81 1.1 skrll const char EXP_CHARS[] = "eE";
82 1.1 skrll
83 1.1 skrll /* Chars that mean this number is a floating point constant.
84 1.1 skrll As in 0f12.456
85 1.1 skrll or 0d1.2345e12. */
86 1.1 skrll const char FLT_CHARS[] = "rRsSfFdDxXpP";
87 1.1 skrll
88 1.1 skrll static void
89 1.1.1.5 christos insert_sreg (const char *regname, int regnum)
90 1.1 skrll {
91 1.1 skrll /* Must be large enough to hold the names of the special registers. */
92 1.1 skrll char buf[80];
93 1.1 skrll int i;
94 1.1 skrll
95 1.1.1.8 christos symbol_table_insert (symbol_new (regname, reg_section,
96 1.1.1.8 christos &zero_address_frag, regnum));
97 1.1 skrll for (i = 0; regname[i]; i++)
98 1.1 skrll buf[i] = ISLOWER (regname[i]) ? TOUPPER (regname[i]) : regname[i];
99 1.1 skrll buf[i] = '\0';
100 1.1 skrll
101 1.1.1.8 christos symbol_table_insert (symbol_new (buf, reg_section,
102 1.1.1.8 christos &zero_address_frag, regnum));
103 1.1 skrll }
104 1.1 skrll
105 1.1 skrll /* Install symbol definitions for assorted special registers.
106 1.1 skrll See MIPS Assembly Language Programmer's Guide page 1-4 */
107 1.1 skrll
108 1.1 skrll static void
109 1.1 skrll define_some_regs (void)
110 1.1 skrll {
111 1.1 skrll /* Software representation. */
112 1.1 skrll insert_sreg ("zero", 0);
113 1.1 skrll insert_sreg ("at", 1);
114 1.1 skrll insert_sreg ("v0", 2);
115 1.1 skrll insert_sreg ("v1", 3);
116 1.1 skrll insert_sreg ("a0", 4);
117 1.1 skrll insert_sreg ("a1", 5);
118 1.1 skrll insert_sreg ("a2", 6);
119 1.1 skrll insert_sreg ("a3", 7);
120 1.1 skrll insert_sreg ("t0", 8);
121 1.1 skrll insert_sreg ("t1", 9);
122 1.1 skrll insert_sreg ("t2", 10);
123 1.1 skrll insert_sreg ("t3", 11);
124 1.1 skrll insert_sreg ("t4", 12);
125 1.1 skrll insert_sreg ("t5", 13);
126 1.1 skrll insert_sreg ("t6", 14);
127 1.1 skrll insert_sreg ("t7", 15);
128 1.1 skrll insert_sreg ("s0", 16);
129 1.1 skrll insert_sreg ("s1", 17);
130 1.1 skrll insert_sreg ("s2", 18);
131 1.1 skrll insert_sreg ("s3", 19);
132 1.1 skrll insert_sreg ("s4", 20);
133 1.1 skrll insert_sreg ("s5", 21);
134 1.1 skrll insert_sreg ("s6", 22);
135 1.1 skrll insert_sreg ("s7", 23);
136 1.1 skrll insert_sreg ("t8", 24);
137 1.1 skrll insert_sreg ("t9", 25);
138 1.1 skrll insert_sreg ("k0", 26);
139 1.1 skrll insert_sreg ("k1", 27);
140 1.1 skrll insert_sreg ("gp", 28);
141 1.1 skrll insert_sreg ("sp", 29);
142 1.1 skrll insert_sreg ("fp", 30);
143 1.1 skrll insert_sreg ("ra", 31);
144 1.1 skrll /* Special registers. */
145 1.1 skrll insert_sreg ("pc", 0);
146 1.1 skrll insert_sreg ("npc", 1);
147 1.1 skrll insert_sreg ("iad", 2);
148 1.1 skrll }
149 1.1 skrll
150 1.1 skrll /* Subroutine check the string to match an register. */
151 1.1 skrll
152 1.1 skrll static int
153 1.1 skrll match_sft_register (char *name)
154 1.1 skrll {
155 1.1 skrll #define MAX_REG_NO 35
156 1.1 skrll /* Currently we have 35 software registers defined -
157 1.1 skrll we borrowed from MIPS. */
158 1.1.1.5 christos static const char *soft_reg[] =
159 1.1 skrll {
160 1.1 skrll "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
161 1.1 skrll "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", "t8", "t9",
162 1.1 skrll "s0", "s1", "s2", "s3", "s4", "s5", "s7", "k0", "k1",
163 1.1 skrll "gp", "sp", "fp", "ra", "pc", "npc", "iad",
164 1.1 skrll "EndofTab" /* End of the Table indicator */
165 1.1 skrll };
166 1.1 skrll char low_name[21], *ptr;
167 1.1 skrll int idx;
168 1.1 skrll
169 1.1 skrll for (ptr = name,idx = 0; *ptr != '\0'; ptr++)
170 1.1 skrll low_name[idx++] = TOLOWER (*ptr);
171 1.1 skrll
172 1.1 skrll low_name[idx] = '\0';
173 1.1 skrll idx = 0;
174 1.1 skrll
175 1.1 skrll while (idx < MAX_REG_NO && strcmp (soft_reg[idx], & low_name [0]))
176 1.1 skrll idx += 1;
177 1.1 skrll
178 1.1 skrll return idx < MAX_REG_NO;
179 1.1 skrll }
180 1.1 skrll
181 1.1 skrll /* Subroutine check the string to match an register. */
182 1.1 skrll
183 1.1 skrll static int
184 1.1 skrll is_ldst_registers (char *name)
185 1.1 skrll {
186 1.1 skrll char *ptr = name;
187 1.1 skrll
188 1.1 skrll /* The first character of the register name got to be either %, $, r of R. */
189 1.1 skrll if ((ptr[0] == '%' || ptr[0] == '$' || ptr[0] == 'r' || ptr[0] == 'R')
190 1.1.1.10 christos && ISDIGIT (ptr[1]))
191 1.1 skrll return 1;
192 1.1 skrll
193 1.1 skrll /* Now check the software register representation. */
194 1.1 skrll return match_sft_register (ptr);
195 1.1 skrll }
196 1.1 skrll
197 1.1 skrll /* Subroutine of s_proc so targets can choose a different default prefix.
198 1.1 skrll If DEFAULT_PREFIX is NULL, use the target's "leading char". */
199 1.1 skrll
200 1.1 skrll static void
201 1.1 skrll s_proc (int end_p)
202 1.1 skrll {
203 1.1 skrll /* Record the current function so that we can issue an error message for
204 1.1 skrll misplaced .func,.endfunc, and also so that .endfunc needs no
205 1.1 skrll arguments. */
206 1.1 skrll static char *current_name;
207 1.1 skrll static char *current_label;
208 1.1 skrll
209 1.1 skrll if (end_p)
210 1.1 skrll {
211 1.1 skrll if (current_name == NULL)
212 1.1 skrll {
213 1.1 skrll as_bad (_("missing .proc"));
214 1.1 skrll ignore_rest_of_line ();
215 1.1 skrll return;
216 1.1 skrll }
217 1.1 skrll
218 1.1 skrll current_name = current_label = NULL;
219 1.1 skrll SKIP_WHITESPACE ();
220 1.1.1.10 christos while (!is_end_of_stmt (*input_line_pointer))
221 1.1 skrll input_line_pointer++;
222 1.1 skrll }
223 1.1 skrll else
224 1.1 skrll {
225 1.1 skrll char *name, *label;
226 1.1 skrll char delim1, delim2;
227 1.1 skrll
228 1.1 skrll if (current_name != NULL)
229 1.1 skrll {
230 1.1 skrll as_bad (_(".endfunc missing for previous .proc"));
231 1.1 skrll ignore_rest_of_line ();
232 1.1 skrll return;
233 1.1 skrll }
234 1.1 skrll
235 1.1.1.4 christos delim1 = get_symbol_name (&name);
236 1.1 skrll name = xstrdup (name);
237 1.1.1.10 christos restore_line_pointer (delim1);
238 1.1.1.10 christos SKIP_WHITESPACE ();
239 1.1 skrll
240 1.1 skrll if (*input_line_pointer != ',')
241 1.1 skrll {
242 1.1 skrll char leading_char = 0;
243 1.1 skrll
244 1.1 skrll leading_char = bfd_get_symbol_leading_char (stdoutput);
245 1.1 skrll /* Missing entry point, use function's name with the leading
246 1.1 skrll char prepended. */
247 1.1 skrll if (leading_char)
248 1.1.1.3 christos {
249 1.1.1.3 christos unsigned len = strlen (name) + 1;
250 1.1.1.5 christos label = XNEWVEC (char, len + 1);
251 1.1.1.3 christos label[0] = leading_char;
252 1.1.1.3 christos memcpy (label + 1, name, len);
253 1.1.1.3 christos }
254 1.1 skrll else
255 1.1 skrll label = name;
256 1.1 skrll }
257 1.1 skrll else
258 1.1 skrll {
259 1.1 skrll ++input_line_pointer;
260 1.1 skrll SKIP_WHITESPACE ();
261 1.1.1.4 christos delim2 = get_symbol_name (&label);
262 1.1 skrll label = xstrdup (label);
263 1.1.1.4 christos (void) restore_line_pointer (delim2);
264 1.1 skrll }
265 1.1 skrll
266 1.1 skrll current_name = name;
267 1.1 skrll current_label = label;
268 1.1 skrll }
269 1.1 skrll demand_empty_rest_of_line ();
270 1.1 skrll }
271 1.1 skrll
272 1.1 skrll /* This function is called once, at assembler startup time. It should
273 1.1 skrll set up all the tables, etc., that the MD part of the assembler will
274 1.1 skrll need. */
275 1.1 skrll
276 1.1 skrll void
277 1.1 skrll md_begin (void)
278 1.1 skrll {
279 1.1 skrll unsigned int i;
280 1.1 skrll
281 1.1 skrll /* Create a new hash table. */
282 1.1.1.8 christos op_hash = str_htab_create ();
283 1.1 skrll
284 1.1 skrll /* Hash up all the opcodes for fast use later. */
285 1.1 skrll for (i = 0; i < num_dlx_opcodes; i++)
286 1.1 skrll {
287 1.1 skrll const char *name = machine_opcodes[i].name;
288 1.1.1.8 christos if (str_hash_insert (op_hash, name, &machine_opcodes[i], 0) != NULL)
289 1.1.1.8 christos as_fatal (_("duplicate %s"), name);
290 1.1 skrll }
291 1.1 skrll
292 1.1 skrll define_some_regs ();
293 1.1 skrll }
294 1.1 skrll
295 1.1 skrll /* This function will check the opcode and return 1 if the opcode is one
296 1.1 skrll of the load/store instruction, and it will fix the operand string to
297 1.1 skrll the standard form so we can use the standard parse_operand routine. */
298 1.1 skrll
299 1.1 skrll #define READ_OP 0x100
300 1.1 skrll #define WRITE_OP 0x200
301 1.1 skrll static char iBuf[81];
302 1.1 skrll
303 1.1 skrll static char *
304 1.1 skrll dlx_parse_loadop (char * str)
305 1.1 skrll {
306 1.1 skrll char *ptr = str;
307 1.1 skrll int idx = 0;
308 1.1 skrll
309 1.1 skrll /* The last pair of ()/[] is the register, all other are the
310 1.1 skrll reloc displacement, and if there is a register then it ought
311 1.1 skrll to have a pair of ()/[]
312 1.1 skrll This is not necessarily true, what if the load instruction come
313 1.1 skrll without the register and with %hi/%lo modifier? */
314 1.1 skrll for (idx = 0; idx < 72 && ptr[idx] != '\0'; idx++)
315 1.1 skrll ;
316 1.1 skrll
317 1.1 skrll if (idx == 72)
318 1.1 skrll {
319 1.1 skrll badoperand_load:
320 1.1 skrll as_bad (_("Bad operand for a load instruction: <%s>"), str);
321 1.1 skrll return NULL;
322 1.1 skrll }
323 1.1 skrll else
324 1.1 skrll {
325 1.1 skrll int i, pb = 0;
326 1.1 skrll int m2 = 0;
327 1.1 skrll char rs1[7], rd[7], endm, match = '0';
328 1.1 skrll char imm[72];
329 1.1 skrll
330 1.1 skrll idx -= 1;
331 1.1 skrll switch (str[idx])
332 1.1 skrll {
333 1.1 skrll case ')':
334 1.1 skrll match = '(';
335 1.1 skrll endm = ')';
336 1.1 skrll break;
337 1.1 skrll case ']':
338 1.1 skrll match = '[';
339 1.1 skrll endm = ']';
340 1.1 skrll break;
341 1.1 skrll default:
342 1.1 skrll /* No register indicated, fill in zero. */
343 1.1 skrll rs1[0] = 'r';
344 1.1 skrll rs1[1] = '0';
345 1.1 skrll rs1[2] = '\0';
346 1.1 skrll match = 0;
347 1.1 skrll endm = 0;
348 1.1 skrll m2 = 1;
349 1.1 skrll }
350 1.1 skrll
351 1.1 skrll if (!m2)
352 1.1 skrll {
353 1.1 skrll /* Searching for (/[ which will match the ]/). */
354 1.1 skrll for (pb = idx - 1; str[pb] != match; pb -= 1)
355 1.1 skrll /* Match can only be either '[' or '(', if it is
356 1.1 skrll '(' then this can be a normal expression, we'll treat
357 1.1 skrll it as an operand. */
358 1.1 skrll if (str[pb] == endm || pb < (idx - 5))
359 1.1 skrll goto load_no_rs1;
360 1.1 skrll pb += 1;
361 1.1 skrll
362 1.1 skrll for (i = 0; (pb + i) < idx; i++)
363 1.1 skrll rs1[i] = str[pb+i];
364 1.1 skrll
365 1.1 skrll rs1[i] = '\0';
366 1.1 skrll
367 1.1 skrll if (is_ldst_registers (& rs1[0]))
368 1.1 skrll /* Point to the last character of the imm. */
369 1.1 skrll pb -= 1;
370 1.1 skrll else
371 1.1 skrll {
372 1.1 skrll load_no_rs1:
373 1.1 skrll if (match == '[')
374 1.1 skrll goto badoperand_load;
375 1.1 skrll /* No register indicated, fill in zero and restore the imm. */
376 1.1 skrll rs1[0] = 'r';
377 1.1 skrll rs1[1] = '0';
378 1.1 skrll rs1[2] = '\0';
379 1.1 skrll m2 = 1;
380 1.1 skrll }
381 1.1 skrll }
382 1.1 skrll
383 1.1 skrll /* Duplicate the first register. */
384 1.1 skrll for (i = 0; i < 7 && str[i] != ','; i++)
385 1.1 skrll rd[i] = ptr[i];
386 1.1 skrll
387 1.1 skrll if (str[i] != ',')
388 1.1 skrll goto badoperand_load;
389 1.1 skrll else
390 1.1 skrll rd[i] = '\0';
391 1.1 skrll
392 1.1 skrll /* Copy the immd. */
393 1.1 skrll if (m2)
394 1.1 skrll /* Put the '\0' back in. */
395 1.1 skrll pb = idx + 1;
396 1.1 skrll
397 1.1 skrll for (i++, m2 = 0; i < pb; m2++,i++)
398 1.1 skrll imm[m2] = ptr[i];
399 1.1 skrll
400 1.1 skrll imm[m2] = '\0';
401 1.1 skrll
402 1.1 skrll /* Assemble the instruction to gas internal format. */
403 1.1 skrll for (i = 0; rd[i] != '\0'; i++)
404 1.1 skrll iBuf[i] = rd[i];
405 1.1 skrll
406 1.1 skrll iBuf[i++] = ',';
407 1.1 skrll
408 1.1 skrll for (pb = 0 ; rs1[pb] != '\0'; i++, pb++)
409 1.1 skrll iBuf[i] = rs1[pb];
410 1.1 skrll
411 1.1 skrll iBuf[i++] = ',';
412 1.1 skrll
413 1.1 skrll for (pb = 0; imm[pb] != '\0'; i++, pb++)
414 1.1 skrll iBuf[i] = imm[pb];
415 1.1 skrll
416 1.1 skrll iBuf[i] = '\0';
417 1.1 skrll return iBuf;
418 1.1 skrll }
419 1.1 skrll }
420 1.1 skrll
421 1.1 skrll static char *
422 1.1 skrll dlx_parse_storeop (char * str)
423 1.1 skrll {
424 1.1 skrll char *ptr = str;
425 1.1 skrll int idx = 0;
426 1.1 skrll
427 1.1 skrll /* Search for the ','. */
428 1.1 skrll for (idx = 0; idx < 72 && ptr[idx] != ','; idx++)
429 1.1 skrll ;
430 1.1 skrll
431 1.1 skrll if (idx == 72)
432 1.1 skrll {
433 1.1 skrll badoperand_store:
434 1.1 skrll as_bad (_("Bad operand for a store instruction: <%s>"), str);
435 1.1 skrll return NULL;
436 1.1 skrll }
437 1.1 skrll else
438 1.1 skrll {
439 1.1 skrll /* idx now points to the ','. */
440 1.1 skrll int i, pb = 0;
441 1.1 skrll int comma = idx;
442 1.1 skrll int m2 = 0;
443 1.1 skrll char rs1[7], rd[7], endm, match = '0';
444 1.1 skrll char imm[72];
445 1.1 skrll
446 1.1 skrll /* Now parse the '(' and ')', and make idx point to ')'. */
447 1.1 skrll idx -= 1;
448 1.1 skrll switch (str[idx])
449 1.1 skrll {
450 1.1 skrll case ')':
451 1.1 skrll match = '(';
452 1.1 skrll endm = ')';
453 1.1 skrll break;
454 1.1 skrll case ']':
455 1.1 skrll match = '[';
456 1.1 skrll endm = ']';
457 1.1 skrll break;
458 1.1 skrll default:
459 1.1 skrll /* No register indicated, fill in zero. */
460 1.1 skrll rs1[0] = 'r';
461 1.1 skrll rs1[1] = '0';
462 1.1 skrll rs1[2] = '\0';
463 1.1 skrll match = 0;
464 1.1 skrll endm = 0;
465 1.1 skrll m2 = 1;
466 1.1 skrll }
467 1.1 skrll
468 1.1 skrll if (!m2)
469 1.1 skrll {
470 1.1 skrll /* Searching for (/[ which will match the ]/). */
471 1.1 skrll for (pb = idx - 1; str[pb] != match; pb -= 1)
472 1.1 skrll if (pb < (idx - 5) || str[pb] == endm)
473 1.1 skrll goto store_no_rs1;
474 1.1 skrll pb += 1;
475 1.1 skrll
476 1.1 skrll for (i = 0; (pb + i) < idx; i++)
477 1.1 skrll rs1[i] = str[pb + i];
478 1.1 skrll
479 1.1 skrll rs1[i] = '\0';
480 1.1 skrll
481 1.1 skrll if (is_ldst_registers (& rs1[0]))
482 1.1 skrll /* Point to the last character of the imm. */
483 1.1 skrll pb -= 1;
484 1.1 skrll else
485 1.1 skrll {
486 1.1 skrll store_no_rs1:
487 1.1 skrll if (match == '[')
488 1.1 skrll goto badoperand_store;
489 1.1 skrll
490 1.1 skrll /* No register indicated, fill in zero and restore the imm. */
491 1.1 skrll rs1[0] = 'r';
492 1.1 skrll rs1[1] = '0';
493 1.1 skrll rs1[2] = '\0';
494 1.1 skrll pb = comma;
495 1.1 skrll }
496 1.1 skrll }
497 1.1 skrll else
498 1.1 skrll /* No register was specified. */
499 1.1 skrll pb = comma;
500 1.1 skrll
501 1.1 skrll /* Duplicate the first register. */
502 1.1.1.10 christos for (i = comma + 1; is_whitespace (str[i]); i++)
503 1.1 skrll ;
504 1.1 skrll
505 1.1 skrll for (m2 = 0; (m2 < 7 && str[i] != '\0'); i++, m2++)
506 1.1 skrll {
507 1.1.1.10 christos if (!is_whitespace (str[i]))
508 1.1 skrll rd[m2] = str[i];
509 1.1 skrll else
510 1.1 skrll goto badoperand_store;
511 1.1 skrll }
512 1.1 skrll
513 1.1 skrll if (str[i] != '\0')
514 1.1 skrll goto badoperand_store;
515 1.1 skrll else
516 1.1 skrll rd[m2] = '\0';
517 1.1 skrll
518 1.1 skrll /* Copy the immd. */
519 1.1 skrll for (i = 0; i < pb; i++)
520 1.1 skrll imm[i] = ptr[i];
521 1.1 skrll
522 1.1 skrll imm[i] = '\0';
523 1.1 skrll
524 1.1 skrll /* Assemble the instruction to gas internal format. */
525 1.1 skrll for (i = 0; rd[i] != '\0'; i++)
526 1.1 skrll iBuf[i] = rd[i];
527 1.1 skrll iBuf[i++] = ',';
528 1.1 skrll for (pb = 0 ; rs1[pb] != '\0'; i++, pb++)
529 1.1 skrll iBuf[i] = rs1[pb];
530 1.1 skrll iBuf[i++] = ',';
531 1.1 skrll for (pb = 0; imm[pb] != '\0'; i++, pb++)
532 1.1 skrll iBuf[i] = imm[pb];
533 1.1 skrll iBuf[i] = '\0';
534 1.1 skrll return iBuf;
535 1.1 skrll }
536 1.1 skrll }
537 1.1 skrll
538 1.1 skrll static char *
539 1.1 skrll fix_ld_st_operand (unsigned long opcode, char* str)
540 1.1 skrll {
541 1.1 skrll /* Check the opcode. */
542 1.1.1.10 christos switch (opcode)
543 1.1 skrll {
544 1.1 skrll case LBOP:
545 1.1 skrll case LBUOP:
546 1.1 skrll case LSBUOP:
547 1.1 skrll case LHOP:
548 1.1 skrll case LHUOP:
549 1.1 skrll case LSHUOP:
550 1.1 skrll case LWOP:
551 1.1 skrll case LSWOP:
552 1.1 skrll return dlx_parse_loadop (str);
553 1.1 skrll case SBOP:
554 1.1 skrll case SHOP:
555 1.1 skrll case SWOP:
556 1.1 skrll return dlx_parse_storeop (str);
557 1.1 skrll default:
558 1.1 skrll return str;
559 1.1 skrll }
560 1.1 skrll }
561 1.1 skrll
562 1.1 skrll static int
563 1.1 skrll hilo_modifier_ok (char *s)
564 1.1 skrll {
565 1.1 skrll char *ptr = s;
566 1.1 skrll int idx, count = 1;
567 1.1 skrll
568 1.1 skrll if (*ptr != '(')
569 1.1 skrll return 1;
570 1.1 skrll
571 1.1 skrll for (idx = 1; ptr[idx] != '\0' && ptr[idx] != '[' && idx < 73; idx += 1)
572 1.1 skrll {
573 1.1 skrll if (count == 0)
574 1.1 skrll return count;
575 1.1 skrll
576 1.1 skrll if (ptr[idx] == '(')
577 1.1 skrll count += 1;
578 1.1 skrll
579 1.1 skrll if (ptr[idx] == ')')
580 1.1 skrll count -= 1;
581 1.1 skrll }
582 1.1 skrll
583 1.1 skrll return (count == 0) ? 1:0;
584 1.1 skrll }
585 1.1 skrll
586 1.1 skrll static char *
587 1.1 skrll parse_operand (char *s, expressionS *operandp)
588 1.1 skrll {
589 1.1 skrll char *save = input_line_pointer;
590 1.1.1.2 christos char *new_pos;
591 1.1 skrll
592 1.1 skrll the_insn.HI = the_insn.LO = 0;
593 1.1 skrll
594 1.1 skrll /* Search for %hi and %lo, make a mark and skip it. */
595 1.1.1.8 christos if (startswith (s, "%hi"))
596 1.1 skrll {
597 1.1 skrll s += 3;
598 1.1 skrll the_insn.HI = 1;
599 1.1 skrll }
600 1.1 skrll else
601 1.1 skrll {
602 1.1.1.8 christos if (startswith (s, "%lo"))
603 1.1 skrll {
604 1.1 skrll s += 3;
605 1.1 skrll the_insn.LO = 1;
606 1.1 skrll }
607 1.1 skrll else
608 1.1 skrll the_insn.LO = 0;
609 1.1 skrll }
610 1.1 skrll
611 1.1 skrll if (the_insn.HI || the_insn.LO)
612 1.1 skrll {
613 1.1 skrll if (!hilo_modifier_ok (s))
614 1.1 skrll as_bad (_("Expression Error for operand modifier %%hi/%%lo\n"));
615 1.1 skrll }
616 1.1 skrll
617 1.1 skrll /* Check for the % and $ register representation */
618 1.1 skrll if ((s[0] == '%' || s[0] == '$' || s[0] == 'r' || s[0] == 'R')
619 1.1.1.10 christos && ISDIGIT (s[1]))
620 1.1 skrll {
621 1.1 skrll /* We have a numeric register expression. No biggy. */
622 1.1 skrll s += 1;
623 1.1 skrll input_line_pointer = s;
624 1.1 skrll (void) expression (operandp);
625 1.1 skrll if (operandp->X_op != O_constant
626 1.1 skrll || operandp->X_add_number > 31)
627 1.1 skrll as_bad (_("Invalid expression after %%%%\n"));
628 1.1 skrll operandp->X_op = O_register;
629 1.1 skrll }
630 1.1 skrll else
631 1.1 skrll {
632 1.1 skrll /* Normal operand parsing. */
633 1.1 skrll input_line_pointer = s;
634 1.1 skrll (void) expression (operandp);
635 1.1.1.9 christos resolve_register (operandp);
636 1.1 skrll }
637 1.1 skrll
638 1.1.1.2 christos new_pos = input_line_pointer;
639 1.1 skrll input_line_pointer = save;
640 1.1.1.2 christos return new_pos;
641 1.1 skrll }
642 1.1 skrll
643 1.1 skrll /* Instruction parsing. Takes a string containing the opcode.
644 1.1 skrll Operands are at input_line_pointer. Output is in the_insn.
645 1.1 skrll Warnings or errors are generated. */
646 1.1 skrll
647 1.1 skrll static void
648 1.1 skrll machine_ip (char *str)
649 1.1 skrll {
650 1.1 skrll char *s;
651 1.1 skrll const char *args;
652 1.1 skrll struct machine_opcode *insn;
653 1.1 skrll unsigned long opcode;
654 1.1 skrll expressionS the_operand;
655 1.1 skrll expressionS *operand = &the_operand;
656 1.1 skrll unsigned int reg, reg_shift = 0;
657 1.1 skrll
658 1.1.1.4 christos memset (&the_insn, '\0', sizeof (the_insn));
659 1.1.1.4 christos the_insn.reloc = NO_RELOC;
660 1.1.1.4 christos
661 1.1 skrll /* Fixup the opcode string to all lower cases, and also
662 1.1 skrll allow numerical digits. */
663 1.1 skrll s = str;
664 1.1 skrll
665 1.1 skrll if (ISALPHA (*s))
666 1.1 skrll for (; ISALNUM (*s); ++s)
667 1.1 skrll if (ISUPPER (*s))
668 1.1 skrll *s = TOLOWER (*s);
669 1.1 skrll
670 1.1 skrll switch (*s)
671 1.1 skrll {
672 1.1 skrll case '\0':
673 1.1 skrll break;
674 1.1 skrll
675 1.1 skrll default:
676 1.1.1.10 christos if (is_whitespace (*s))
677 1.1.1.10 christos {
678 1.1.1.10 christos *s++ = '\0';
679 1.1.1.10 christos break;
680 1.1.1.10 christos }
681 1.1 skrll as_bad (_("Unknown opcode: `%s'"), str);
682 1.1 skrll return;
683 1.1 skrll }
684 1.1 skrll
685 1.1.1.4 christos /* Hash the opcode, insn will have the string from opcode table. */
686 1.1.1.10 christos if ((insn = str_hash_find (op_hash, str)) == NULL)
687 1.1 skrll {
688 1.1 skrll /* Handle the ret and return macro here. */
689 1.1 skrll if ((strcmp (str, "ret") == 0) || (strcmp (str, "return") == 0))
690 1.1.1.4 christos the_insn.opcode = JROP | 0x03e00000; /* 0x03e00000 = r31 << 21 */
691 1.1 skrll else
692 1.1 skrll as_bad (_("Unknown opcode `%s'."), str);
693 1.1 skrll
694 1.1 skrll return;
695 1.1 skrll }
696 1.1 skrll
697 1.1 skrll opcode = insn->opcode;
698 1.1 skrll
699 1.1 skrll /* Set the sip reloc HI16 flag. */
700 1.1 skrll if (!set_dlx_skip_hi16_flag (1))
701 1.1 skrll as_bad (_("Can not set dlx_skip_hi16_flag"));
702 1.1 skrll
703 1.1 skrll /* Fix the operand string if it is one of load store instructions. */
704 1.1 skrll s = fix_ld_st_operand (opcode, s);
705 1.1 skrll
706 1.1 skrll /* Build the opcode, checking as we go to make sure that the
707 1.1 skrll operands match.
708 1.1 skrll If an operand matches, we modify the_insn or opcode appropriately,
709 1.1 skrll and do a "continue". If an operand fails to match, we "break". */
710 1.1 skrll if (insn->args[0] != '\0' && insn->args[0] != 'N')
711 1.1 skrll {
712 1.1 skrll /* Prime the pump. */
713 1.1 skrll if (*s == '\0')
714 1.1 skrll {
715 1.1 skrll as_bad (_("Missing arguments for opcode <%s>."), str);
716 1.1 skrll return;
717 1.1 skrll }
718 1.1 skrll else
719 1.1 skrll s = parse_operand (s, operand);
720 1.1 skrll }
721 1.1 skrll else if (insn->args[0] == 'N')
722 1.1 skrll {
723 1.1 skrll /* Clean up the insn and done! */
724 1.1 skrll the_insn.opcode = opcode;
725 1.1 skrll return;
726 1.1 skrll }
727 1.1 skrll
728 1.1 skrll /* Parse through the args (this is from opcode table), *s point to
729 1.1 skrll the current character of the instruction stream. */
730 1.1 skrll for (args = insn->args;; ++args)
731 1.1 skrll {
732 1.1 skrll switch (*args)
733 1.1 skrll {
734 1.1 skrll /* End of Line. */
735 1.1 skrll case '\0':
736 1.1 skrll /* End of args. */
737 1.1 skrll if (*s == '\0')
738 1.1 skrll {
739 1.1 skrll /* We are truly done. */
740 1.1 skrll the_insn.opcode = opcode;
741 1.1 skrll /* Clean up the HI and LO mark. */
742 1.1 skrll the_insn.HI = 0;
743 1.1 skrll the_insn.LO = 0;
744 1.1 skrll return;
745 1.1 skrll }
746 1.1 skrll
747 1.1 skrll the_insn.HI = 0;
748 1.1 skrll the_insn.LO = 0;
749 1.1 skrll as_bad (_("Too many operands: %s"), s);
750 1.1 skrll break;
751 1.1 skrll
752 1.1 skrll /* ',' Args separator */
753 1.1 skrll case ',':
754 1.1 skrll /* Must match a comma. */
755 1.1 skrll if (*s++ == ',')
756 1.1 skrll {
757 1.1 skrll /* Parse next operand. */
758 1.1 skrll s = parse_operand (s, operand);
759 1.1 skrll continue;
760 1.1 skrll }
761 1.1 skrll break;
762 1.1 skrll
763 1.1 skrll /* It can be a 'a' register or 'i' operand. */
764 1.1 skrll case 'P':
765 1.1 skrll /* Macro move operand/reg. */
766 1.1 skrll if (operand->X_op == O_register)
767 1.1 skrll {
768 1.1.1.6 christos /* It's a register. */
769 1.1 skrll reg_shift = 21;
770 1.1 skrll goto general_reg;
771 1.1 skrll }
772 1.1.1.6 christos /* Fall through. */
773 1.1 skrll
774 1.1 skrll /* The immediate 16 bits literal, bit 0-15. */
775 1.1 skrll case 'i':
776 1.1 skrll /* offset, unsigned. */
777 1.1 skrll case 'I':
778 1.1 skrll /* offset, signed. */
779 1.1 skrll if (operand->X_op == O_constant)
780 1.1 skrll {
781 1.1 skrll if (the_insn.HI)
782 1.1 skrll operand->X_add_number >>= 16;
783 1.1 skrll
784 1.1 skrll opcode |= operand->X_add_number & 0xFFFF;
785 1.1 skrll
786 1.1 skrll if (the_insn.HI && the_insn.LO)
787 1.1 skrll as_bad (_("Both the_insn.HI and the_insn.LO are set : %s"), s);
788 1.1 skrll else
789 1.1 skrll {
790 1.1 skrll the_insn.HI = 0;
791 1.1 skrll the_insn.LO = 0;
792 1.1 skrll }
793 1.1 skrll continue;
794 1.1 skrll }
795 1.1 skrll
796 1.1.1.4 christos the_insn.reloc = (the_insn.HI) ? RELOC_DLX_HI16
797 1.1 skrll : (the_insn.LO ? RELOC_DLX_LO16 : RELOC_DLX_16);
798 1.1 skrll the_insn.reloc_offset = 2;
799 1.1 skrll the_insn.size = 2;
800 1.1 skrll the_insn.pcrel = 0;
801 1.1 skrll the_insn.exp = * operand;
802 1.1 skrll the_insn.HI = 0;
803 1.1 skrll the_insn.LO = 0;
804 1.1 skrll continue;
805 1.1 skrll
806 1.1 skrll case 'd':
807 1.1 skrll /* offset, signed. */
808 1.1 skrll if (operand->X_op == O_constant)
809 1.1 skrll {
810 1.1 skrll opcode |= operand->X_add_number & 0xFFFF;
811 1.1 skrll continue;
812 1.1 skrll }
813 1.1 skrll the_insn.reloc = RELOC_DLX_REL16;
814 1.1 skrll the_insn.reloc_offset = 0; /* BIG-ENDIAN Byte 3 of insn. */
815 1.1 skrll the_insn.size = 4;
816 1.1 skrll the_insn.pcrel = 1;
817 1.1 skrll the_insn.exp = *operand;
818 1.1 skrll continue;
819 1.1 skrll
820 1.1 skrll /* The immediate 26 bits literal, bit 0-25. */
821 1.1 skrll case 'D':
822 1.1 skrll /* offset, signed. */
823 1.1 skrll if (operand->X_op == O_constant)
824 1.1 skrll {
825 1.1 skrll opcode |= operand->X_add_number & 0x3FFFFFF;
826 1.1 skrll continue;
827 1.1 skrll }
828 1.1 skrll the_insn.reloc = RELOC_DLX_REL26;
829 1.1 skrll the_insn.reloc_offset = 0; /* BIG-ENDIAN Byte 3 of insn. */
830 1.1 skrll the_insn.size = 4;
831 1.1 skrll the_insn.pcrel = 1;
832 1.1 skrll the_insn.exp = *operand;
833 1.1 skrll continue;
834 1.1 skrll
835 1.1 skrll /* Type 'a' Register. */
836 1.1 skrll case 'a':
837 1.1 skrll /* A general register at bits 21-25, rs1. */
838 1.1 skrll reg_shift = 21;
839 1.1 skrll goto general_reg;
840 1.1 skrll
841 1.1 skrll /* Type 'b' Register. */
842 1.1 skrll case 'b':
843 1.1 skrll /* A general register at bits 16-20, rs2/rd. */
844 1.1 skrll reg_shift = 16;
845 1.1 skrll goto general_reg;
846 1.1 skrll
847 1.1 skrll /* Type 'c' Register. */
848 1.1 skrll case 'c':
849 1.1 skrll /* A general register at bits 11-15, rd. */
850 1.1 skrll reg_shift = 11;
851 1.1 skrll
852 1.1 skrll general_reg:
853 1.1 skrll know (operand->X_add_symbol == 0);
854 1.1 skrll know (operand->X_op_symbol == 0);
855 1.1 skrll reg = operand->X_add_number;
856 1.1 skrll if (reg & 0xffffffe0)
857 1.1 skrll as_fatal (_("failed regnum sanity check."));
858 1.1 skrll else
859 1.1 skrll /* Got the register, now figure out where it goes in the opcode. */
860 1.1 skrll opcode |= reg << reg_shift;
861 1.1 skrll
862 1.1 skrll switch (*args)
863 1.1 skrll {
864 1.1 skrll case 'a':
865 1.1 skrll case 'b':
866 1.1 skrll case 'c':
867 1.1 skrll case 'P':
868 1.1 skrll continue;
869 1.1 skrll }
870 1.1 skrll as_fatal (_("failed general register sanity check."));
871 1.1 skrll break;
872 1.1 skrll
873 1.1 skrll default:
874 1.1 skrll BAD_CASE (*args);
875 1.1 skrll }
876 1.1 skrll
877 1.1 skrll /* Types or values of args don't match. */
878 1.1 skrll as_bad (_("Invalid operands"));
879 1.1 skrll return;
880 1.1 skrll }
881 1.1 skrll }
882 1.1 skrll
883 1.1 skrll /* Assemble a single instruction. Its label has already been handled
884 1.1 skrll by the generic front end. We just parse opcode and operands, and
885 1.1 skrll produce the bytes of data and relocation. */
886 1.1 skrll
887 1.1 skrll void
888 1.1 skrll md_assemble (char *str)
889 1.1 skrll {
890 1.1 skrll char *toP;
891 1.1 skrll fixS *fixP;
892 1.1 skrll bit_fixS *bitP;
893 1.1 skrll
894 1.1 skrll know (str);
895 1.1 skrll machine_ip (str);
896 1.1 skrll toP = frag_more (4);
897 1.1.1.2 christos dwarf2_emit_insn (4);
898 1.1.1.2 christos
899 1.1 skrll /* Put out the opcode. */
900 1.1 skrll md_number_to_chars (toP, the_insn.opcode, 4);
901 1.1 skrll
902 1.1 skrll /* Put out the symbol-dependent stuff. */
903 1.1 skrll if (the_insn.reloc != NO_RELOC)
904 1.1 skrll {
905 1.1 skrll fixP = fix_new_exp (frag_now,
906 1.1 skrll (toP - frag_now->fr_literal + the_insn.reloc_offset),
907 1.1 skrll the_insn.size, & the_insn.exp, the_insn.pcrel,
908 1.1 skrll the_insn.reloc);
909 1.1 skrll
910 1.1 skrll /* Turn off complaints that the addend is
911 1.1 skrll too large for things like foo+100000@ha. */
912 1.1 skrll switch (the_insn.reloc)
913 1.1 skrll {
914 1.1 skrll case RELOC_DLX_HI16:
915 1.1 skrll case RELOC_DLX_LO16:
916 1.1 skrll fixP->fx_no_overflow = 1;
917 1.1 skrll break;
918 1.1 skrll default:
919 1.1 skrll break;
920 1.1 skrll }
921 1.1 skrll
922 1.1 skrll switch (fixP->fx_r_type)
923 1.1 skrll {
924 1.1 skrll case RELOC_DLX_REL26:
925 1.1.1.5 christos bitP = XNEW (bit_fixS);
926 1.1 skrll bitP->fx_bit_size = 26;
927 1.1 skrll bitP->fx_bit_offset = 25;
928 1.1 skrll bitP->fx_bit_base = the_insn.opcode & 0xFC000000;
929 1.1 skrll bitP->fx_bit_base_adj = 0;
930 1.1 skrll bitP->fx_bit_max = 0;
931 1.1 skrll bitP->fx_bit_min = 0;
932 1.1 skrll bitP->fx_bit_add = 0x03FFFFFF;
933 1.1 skrll fixP->fx_bit_fixP = bitP;
934 1.1 skrll break;
935 1.1 skrll case RELOC_DLX_LO16:
936 1.1 skrll case RELOC_DLX_REL16:
937 1.1.1.5 christos bitP = XNEW (bit_fixS);
938 1.1 skrll bitP->fx_bit_size = 16;
939 1.1 skrll bitP->fx_bit_offset = 15;
940 1.1 skrll bitP->fx_bit_base = the_insn.opcode & 0xFFFF0000;
941 1.1 skrll bitP->fx_bit_base_adj = 0;
942 1.1 skrll bitP->fx_bit_max = 0;
943 1.1 skrll bitP->fx_bit_min = 0;
944 1.1 skrll bitP->fx_bit_add = 0x0000FFFF;
945 1.1 skrll fixP->fx_bit_fixP = bitP;
946 1.1 skrll break;
947 1.1 skrll case RELOC_DLX_HI16:
948 1.1.1.5 christos bitP = XNEW (bit_fixS);
949 1.1 skrll bitP->fx_bit_size = 16;
950 1.1 skrll bitP->fx_bit_offset = 15;
951 1.1 skrll bitP->fx_bit_base = the_insn.opcode & 0xFFFF0000;
952 1.1 skrll bitP->fx_bit_base_adj = 0;
953 1.1 skrll bitP->fx_bit_max = 0;
954 1.1 skrll bitP->fx_bit_min = 0;
955 1.1 skrll bitP->fx_bit_add = 0x0000FFFF;
956 1.1 skrll fixP->fx_bit_fixP = bitP;
957 1.1 skrll break;
958 1.1 skrll default:
959 1.1 skrll fixP->fx_bit_fixP = NULL;
960 1.1 skrll break;
961 1.1 skrll }
962 1.1 skrll }
963 1.1 skrll }
964 1.1 skrll
965 1.1 skrll /* This is identical to the md_atof in m68k.c. I think this is right,
966 1.1 skrll but I'm not sure. Dlx will not use it anyway, so I just leave it
967 1.1 skrll here for now. */
968 1.1 skrll
969 1.1.1.5 christos const char *
970 1.1 skrll md_atof (int type, char *litP, int *sizeP)
971 1.1 skrll {
972 1.1.1.8 christos return ieee_md_atof (type, litP, sizeP, true);
973 1.1 skrll }
974 1.1 skrll
975 1.1 skrll /* Write out big-endian. */
976 1.1 skrll void
977 1.1 skrll md_number_to_chars (char *buf, valueT val, int n)
978 1.1 skrll {
979 1.1 skrll number_to_chars_bigendian (buf, val, n);
980 1.1 skrll }
981 1.1 skrll
982 1.1.1.8 christos bool
983 1.1 skrll md_dlx_fix_adjustable (fixS *fixP)
984 1.1 skrll {
985 1.1 skrll /* We need the symbol name for the VTABLE entries. */
986 1.1 skrll return (fixP->fx_r_type != BFD_RELOC_VTABLE_INHERIT
987 1.1 skrll && fixP->fx_r_type != BFD_RELOC_VTABLE_ENTRY);
988 1.1 skrll }
989 1.1 skrll
990 1.1 skrll void
991 1.1 skrll md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
992 1.1 skrll {
993 1.1 skrll long val = *valP;
994 1.1 skrll char *place = fixP->fx_where + fixP->fx_frag->fr_literal;
995 1.1 skrll
996 1.1 skrll switch (fixP->fx_r_type)
997 1.1 skrll {
998 1.1 skrll case RELOC_DLX_LO16:
999 1.1 skrll case RELOC_DLX_REL16:
1000 1.1 skrll if (fixP->fx_bit_fixP != NULL)
1001 1.1 skrll {
1002 1.1 skrll val = (val & 0x0000FFFF) | fixP->fx_bit_fixP->fx_bit_base;
1003 1.1 skrll free (fixP->fx_bit_fixP);
1004 1.1 skrll fixP->fx_bit_fixP = NULL;
1005 1.1 skrll }
1006 1.1 skrll break;
1007 1.1 skrll
1008 1.1 skrll case RELOC_DLX_HI16:
1009 1.1 skrll if (fixP->fx_bit_fixP != NULL)
1010 1.1 skrll {
1011 1.1 skrll val = (val >> 16) | fixP->fx_bit_fixP->fx_bit_base;
1012 1.1 skrll free (fixP->fx_bit_fixP);
1013 1.1 skrll fixP->fx_bit_fixP = NULL;
1014 1.1 skrll }
1015 1.1 skrll break;
1016 1.1 skrll
1017 1.1 skrll case RELOC_DLX_REL26:
1018 1.1 skrll if (fixP->fx_bit_fixP != NULL)
1019 1.1 skrll {
1020 1.1 skrll val = (val & 0x03FFFFFF) | fixP->fx_bit_fixP->fx_bit_base;
1021 1.1 skrll free (fixP->fx_bit_fixP);
1022 1.1 skrll fixP->fx_bit_fixP = NULL;
1023 1.1 skrll }
1024 1.1 skrll break;
1025 1.1 skrll
1026 1.1 skrll case BFD_RELOC_VTABLE_INHERIT:
1027 1.1 skrll /* This borrowed from tc-ppc.c on a whim. */
1028 1.1 skrll fixP->fx_done = 0;
1029 1.1 skrll if (fixP->fx_addsy
1030 1.1 skrll && !S_IS_DEFINED (fixP->fx_addsy)
1031 1.1 skrll && !S_IS_WEAK (fixP->fx_addsy))
1032 1.1 skrll S_SET_WEAK (fixP->fx_addsy);
1033 1.1 skrll return;
1034 1.1 skrll
1035 1.1 skrll case BFD_RELOC_VTABLE_ENTRY:
1036 1.1 skrll fixP->fx_done = 0;
1037 1.1 skrll return;
1038 1.1 skrll
1039 1.1 skrll default:
1040 1.1 skrll break;
1041 1.1 skrll }
1042 1.1 skrll
1043 1.1 skrll number_to_chars_bigendian (place, val, fixP->fx_size);
1044 1.1 skrll if (fixP->fx_addsy == NULL)
1045 1.1 skrll fixP->fx_done = 1;
1046 1.1.1.7 christos if (fixP->fx_bit_fixP != NULL)
1047 1.1.1.7 christos fixP->fx_no_overflow = 1;
1048 1.1 skrll }
1049 1.1 skrll
1050 1.1.1.10 christos const char md_shortopts[] = "";
1051 1.1 skrll
1052 1.1.1.10 christos const struct option md_longopts[] =
1053 1.1 skrll {
1054 1.1 skrll {NULL, no_argument, NULL, 0}
1055 1.1 skrll };
1056 1.1 skrll
1057 1.1.1.10 christos const size_t md_longopts_size = sizeof (md_longopts);
1058 1.1 skrll
1059 1.1 skrll int
1060 1.1 skrll md_parse_option (int c ATTRIBUTE_UNUSED,
1061 1.1.1.5 christos const char *arg ATTRIBUTE_UNUSED)
1062 1.1 skrll {
1063 1.1 skrll return 0;
1064 1.1 skrll }
1065 1.1 skrll
1066 1.1 skrll void
1067 1.1 skrll md_show_usage (FILE *stream ATTRIBUTE_UNUSED)
1068 1.1 skrll {
1069 1.1 skrll }
1070 1.1 skrll
1071 1.1 skrll /* This is called when a line is unrecognized. */
1072 1.1 skrll
1073 1.1 skrll int
1074 1.1 skrll dlx_unrecognized_line (int c)
1075 1.1 skrll {
1076 1.1 skrll int lab;
1077 1.1 skrll char *s;
1078 1.1 skrll
1079 1.1 skrll if (c != '$' || ! ISDIGIT ((unsigned char) input_line_pointer[0]))
1080 1.1 skrll return 0;
1081 1.1 skrll
1082 1.1 skrll s = input_line_pointer;
1083 1.1 skrll
1084 1.1 skrll lab = 0;
1085 1.1 skrll while (ISDIGIT ((unsigned char) *s))
1086 1.1 skrll {
1087 1.1 skrll lab = lab * 10 + *s - '0';
1088 1.1 skrll ++s;
1089 1.1 skrll }
1090 1.1 skrll
1091 1.1 skrll if (*s != ':')
1092 1.1 skrll /* Not a label definition. */
1093 1.1 skrll return 0;
1094 1.1 skrll
1095 1.1 skrll if (dollar_label_defined (lab))
1096 1.1 skrll {
1097 1.1 skrll as_bad (_("label \"$%d\" redefined"), lab);
1098 1.1 skrll return 0;
1099 1.1 skrll }
1100 1.1 skrll
1101 1.1 skrll define_dollar_label (lab);
1102 1.1 skrll colon (dollar_label_name (lab, 0));
1103 1.1 skrll input_line_pointer = s + 1;
1104 1.1 skrll
1105 1.1 skrll return 1;
1106 1.1 skrll }
1107 1.1 skrll
1108 1.1 skrll /* Default the values of symbols known that should be "predefined". We
1109 1.1 skrll don't bother to predefine them unless you actually use one, since there
1110 1.1 skrll are a lot of them. */
1111 1.1 skrll
1112 1.1 skrll symbolS *
1113 1.1 skrll md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
1114 1.1 skrll {
1115 1.1 skrll return NULL;
1116 1.1 skrll }
1117 1.1 skrll
1118 1.1 skrll /* Parse an operand that is machine-specific, the function was called
1119 1.1 skrll in expr.c by operand() function, when everything failed before it
1120 1.1 skrll call a quit. */
1121 1.1 skrll
1122 1.1 skrll void
1123 1.1 skrll md_operand (expressionS* expressionP)
1124 1.1 skrll {
1125 1.1 skrll /* Check for the #number representation */
1126 1.1 skrll if (input_line_pointer[0] == '#' &&
1127 1.1.1.10 christos ISDIGIT (input_line_pointer[1]))
1128 1.1 skrll {
1129 1.1 skrll /* We have a numeric number expression. No biggy. */
1130 1.1 skrll input_line_pointer += 1; /* Skip # */
1131 1.1 skrll
1132 1.1 skrll (void) expression (expressionP);
1133 1.1 skrll
1134 1.1 skrll if (expressionP->X_op != O_constant)
1135 1.1 skrll as_bad (_("Invalid expression after # number\n"));
1136 1.1 skrll }
1137 1.1 skrll
1138 1.1 skrll return;
1139 1.1 skrll }
1140 1.1 skrll
1141 1.1 skrll /* Round up a section size to the appropriate boundary. */
1142 1.1 skrll
1143 1.1 skrll valueT
1144 1.1 skrll md_section_align (segT segment ATTRIBUTE_UNUSED,
1145 1.1 skrll valueT size)
1146 1.1 skrll {
1147 1.1 skrll /* Byte alignment is fine. */
1148 1.1 skrll return size;
1149 1.1 skrll }
1150 1.1 skrll
1151 1.1 skrll /* Exactly what point is a PC-relative offset relative TO?
1152 1.1 skrll On the 29000, they're relative to the address of the instruction,
1153 1.1 skrll which we have set up as the address of the fixup too. */
1154 1.1 skrll
1155 1.1 skrll long
1156 1.1 skrll md_pcrel_from (fixS* fixP)
1157 1.1 skrll {
1158 1.1 skrll return 4 + fixP->fx_where + fixP->fx_frag->fr_address;
1159 1.1 skrll }
1160 1.1 skrll
1161 1.1 skrll /* Translate internal representation of relocation info to BFD target
1162 1.1 skrll format.
1163 1.1 skrll FIXME: To what extent can we get all relevant targets to use this?
1164 1.1 skrll The above FIXME is from a29k, but I think it is also needed here. */
1165 1.1 skrll
1166 1.1 skrll arelent *
1167 1.1 skrll tc_gen_reloc (asection *section ATTRIBUTE_UNUSED,
1168 1.1 skrll fixS *fixP)
1169 1.1 skrll {
1170 1.1 skrll arelent * reloc;
1171 1.1 skrll
1172 1.1.1.10 christos reloc = notes_alloc (sizeof (arelent));
1173 1.1.1.10 christos reloc->sym_ptr_ptr = notes_alloc (sizeof (asymbol *));
1174 1.1.1.10 christos *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
1175 1.1 skrll
1176 1.1.1.10 christos reloc->howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
1177 1.1 skrll if (reloc->howto == NULL)
1178 1.1 skrll {
1179 1.1 skrll as_bad_where (fixP->fx_file, fixP->fx_line,
1180 1.1 skrll _("internal error: can't export reloc type %d (`%s')"),
1181 1.1 skrll fixP->fx_r_type,
1182 1.1 skrll bfd_get_reloc_code_name (fixP->fx_r_type));
1183 1.1 skrll return NULL;
1184 1.1 skrll }
1185 1.1 skrll
1186 1.1.1.2 christos gas_assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);
1187 1.1 skrll
1188 1.1 skrll reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
1189 1.1 skrll
1190 1.1 skrll if (fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
1191 1.1 skrll reloc->address = fixP->fx_offset;
1192 1.1 skrll reloc->addend = 0;
1193 1.1 skrll
1194 1.1 skrll return reloc;
1195 1.1 skrll }
1196 1.1 skrll
1197 1.1 skrll const pseudo_typeS
1198 1.1 skrll dlx_pseudo_table[] =
1199 1.1 skrll {
1200 1.1 skrll /* Some additional ops that are used by gcc-dlx. */
1201 1.1 skrll {"asciiz", stringer, 8 + 1},
1202 1.1 skrll {"half", cons, 2},
1203 1.1 skrll {"dword", cons, 8},
1204 1.1 skrll {"word", cons, 4},
1205 1.1 skrll {"proc", s_proc, 0},
1206 1.1 skrll {"endproc", s_proc, 1},
1207 1.1 skrll {NULL, NULL, 0}
1208 1.1 skrll };
1209 1.1 skrll
1210 1.1 skrll void
1211 1.1 skrll dlx_pop_insert (void)
1212 1.1 skrll {
1213 1.1 skrll pop_insert (dlx_pseudo_table);
1214 1.1 skrll return ;
1215 1.1 skrll }
1216