Fix fallout from splitting ldbuildid.[ch] off elf32.em.
[deliverable/binutils-gdb.git] / gas / config / tc-pj.c
CommitLineData
ec2655a6 1/* tc-pj.c -- Assemble code for Pico Java
4b95cf5c 2 Copyright (C) 1999-2014 Free Software Foundation, Inc.
041dd5a9
ILT
3
4 This file is part of GAS, the GNU Assembler.
5
6 GAS is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
ec2655a6 8 the Free Software Foundation; either version 3, or (at your option)
041dd5a9
ILT
9 any later version.
10
11 GAS is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GAS; see the file COPYING. If not, write to
4b4da160
NC
18 the Free Software Foundation, 51 Franklin Street - Fifth Floor,
19 Boston, MA 02110-1301, USA. */
041dd5a9 20
a2429eb5 21/* Contributed by Steve Chamberlain of Transmeta <sac@pobox.com>. */
041dd5a9
ILT
22
23#include "as.h"
3882b010 24#include "safe-ctype.h"
041dd5a9
ILT
25#include "opcode/pj.h"
26
041dd5a9
ILT
27extern const pj_opc_info_t pj_opc_info[512];
28
ea1562b3 29const char comment_chars[] = "!/";
041dd5a9 30const char line_separator_chars[] = ";";
ea1562b3 31const char line_comment_chars[] = "/!#";
041dd5a9
ILT
32
33static int pending_reloc;
34static struct hash_control *opcode_hash_control;
041dd5a9
ILT
35
36static void
ea1562b3 37little (int ignore ATTRIBUTE_UNUSED)
041dd5a9
ILT
38{
39 target_big_endian = 0;
40}
41
42static void
ea1562b3 43big (int ignore ATTRIBUTE_UNUSED)
041dd5a9
ILT
44{
45 target_big_endian = 1;
46}
47
ea1562b3
NC
48const pseudo_typeS md_pseudo_table[] =
49{
041dd5a9
ILT
50 {"ml", little, 0},
51 {"mb", big, 0},
52 {0, 0, 0}
53};
54
041dd5a9
ILT
55const char FLT_CHARS[] = "rRsSfFdDxXpP";
56const char EXP_CHARS[] = "eE";
57
58void
ea1562b3 59md_operand (expressionS *op)
041dd5a9
ILT
60{
61 if (strncmp (input_line_pointer, "%hi16", 5) == 0)
62 {
63 if (pending_reloc)
a2429eb5 64 as_bad (_("confusing relocation expressions"));
041dd5a9
ILT
65 pending_reloc = BFD_RELOC_PJ_CODE_HI16;
66 input_line_pointer += 5;
67 expression (op);
68 }
ea1562b3 69
041dd5a9
ILT
70 if (strncmp (input_line_pointer, "%lo16", 5) == 0)
71 {
72 if (pending_reloc)
a2429eb5 73 as_bad (_("confusing relocation expressions"));
041dd5a9
ILT
74 pending_reloc = BFD_RELOC_PJ_CODE_LO16;
75 input_line_pointer += 5;
76 expression (op);
77 }
78}
79
a2429eb5 80/* Parse an expression and then restore the input line pointer. */
041dd5a9
ILT
81
82static char *
ea1562b3 83parse_exp_save_ilp (char *s, expressionS *op)
041dd5a9
ILT
84{
85 char *save = input_line_pointer;
ea1562b3 86
041dd5a9
ILT
87 input_line_pointer = s;
88 expression (op);
89 s = input_line_pointer;
90 input_line_pointer = save;
91 return s;
92}
93
94/* This is called by emit_expr via TC_CONS_FIX_NEW when creating a
95 reloc for a cons. We could use the definition there, except that
96 we want to handle magic pending reloc expressions specially. */
97
98void
ea1562b3 99pj_cons_fix_new_pj (fragS *frag, int where, int nbytes, expressionS *exp)
041dd5a9 100{
a2429eb5 101 static int rv[5][2] =
041dd5a9
ILT
102 { { 0, 0 },
103 { BFD_RELOC_8, BFD_RELOC_8 },
104 { BFD_RELOC_PJ_CODE_DIR16, BFD_RELOC_16 },
105 { 0, 0 },
106 { BFD_RELOC_PJ_CODE_DIR32, BFD_RELOC_32 }};
107
a2429eb5 108 fix_new_exp (frag, where, nbytes, exp, 0,
041dd5a9 109 pending_reloc ? pending_reloc
a2429eb5 110 : rv[nbytes][(now_seg->flags & SEC_CODE) ? 0 : 1]);
041dd5a9
ILT
111
112 pending_reloc = 0;
113}
114
041dd5a9 115/* Turn a reloc description character from the pj-opc.h table into
a2429eb5 116 code which BFD can handle. */
041dd5a9
ILT
117
118static int
ea1562b3 119c_to_r (int x)
041dd5a9
ILT
120{
121 switch (x)
122 {
123 case O_R8:
124 return BFD_RELOC_8_PCREL;
125 case O_U8:
126 case O_8:
127 return BFD_RELOC_8;
128 case O_R16:
129 return BFD_RELOC_PJ_CODE_REL16;
130 case O_U16:
131 case O_16:
132 return BFD_RELOC_PJ_CODE_DIR16;
133 case O_R32:
134 return BFD_RELOC_PJ_CODE_REL32;
135 case O_32:
136 return BFD_RELOC_PJ_CODE_DIR32;
137 }
138 abort ();
139 return 0;
140}
141
041dd5a9 142/* Handler for the ipush fake opcode,
a2429eb5 143 turns ipush <foo> into sipush lo16<foo>, sethi hi16<foo>. */
041dd5a9
ILT
144
145static void
ea1562b3 146ipush_code (pj_opc_info_t *opcode ATTRIBUTE_UNUSED, char *str)
041dd5a9 147{
041dd5a9
ILT
148 char *b = frag_more (6);
149 expressionS arg;
a2429eb5 150
041dd5a9
ILT
151 b[0] = 0x11;
152 b[3] = 0xed;
0e073f4c
AM
153 parse_exp_save_ilp (str + 1, &arg);
154 if (pending_reloc)
155 {
156 as_bad (_("can't have relocation for ipush"));
157 pending_reloc = 0;
158 }
041dd5a9 159
a2429eb5
NC
160 fix_new_exp (frag_now, b - frag_now->fr_literal + 1, 2,
161 &arg, 0, BFD_RELOC_PJ_CODE_DIR16);
041dd5a9 162 fix_new_exp (frag_now, b - frag_now->fr_literal + 4, 2,
a2429eb5 163 &arg, 0, BFD_RELOC_PJ_CODE_HI16);
041dd5a9
ILT
164}
165
166/* Insert names into the opcode table which are really mini macros,
67c1ffbe 167 not opcodes. The fakeness is indicated with an opcode of -1. */
041dd5a9
ILT
168
169static void
ea1562b3
NC
170fake_opcode (const char *name,
171 void (*func) (struct pj_opc_info_t *, char *))
041dd5a9 172{
ea1562b3 173 pj_opc_info_t * fake = xmalloc (sizeof (pj_opc_info_t));
041dd5a9
ILT
174
175 fake->opcode = -1;
176 fake->opcode_next = -1;
0e073f4c 177 fake->u.func = func;
041dd5a9
ILT
178 hash_insert (opcode_hash_control, name, (char *) fake);
179}
180
041dd5a9 181/* Enter another entry into the opcode hash table so the same opcode
a2429eb5
NC
182 can have another name. */
183
041dd5a9 184static void
d3ce72d0 185alias (const char *new_name, const char *old)
041dd5a9 186{
d3ce72d0 187 hash_insert (opcode_hash_control, new_name,
041dd5a9
ILT
188 (char *) hash_find (opcode_hash_control, old));
189}
190
041dd5a9
ILT
191/* This function is called once, at assembler startup time. It sets
192 up the hash table with all the opcodes in it, and also initializes
a2429eb5 193 some aliases for compatibility with other assemblers. */
041dd5a9
ILT
194
195void
ea1562b3 196md_begin (void)
041dd5a9
ILT
197{
198 const pj_opc_info_t *opcode;
199 opcode_hash_control = hash_new ();
200
a2429eb5 201 /* Insert names into hash table. */
0e073f4c
AM
202 for (opcode = pj_opc_info; opcode->u.name; opcode++)
203 hash_insert (opcode_hash_control, opcode->u.name, (char *) opcode);
041dd5a9 204
a2429eb5 205 /* Insert the only fake opcode. */
041dd5a9
ILT
206 fake_opcode ("ipush", ipush_code);
207
a2429eb5 208 /* Add some aliases for opcode names. */
041dd5a9
ILT
209 alias ("ifeq_s", "ifeq");
210 alias ("ifne_s", "ifne");
211 alias ("if_icmpge_s", "if_icmpge");
212 alias ("if_icmpne_s", "if_icmpne");
213 alias ("if_icmpeq_s", "if_icmpeq");
214 alias ("if_icmpgt_s", "if_icmpgt");
215 alias ("goto_s", "goto");
216
217 bfd_set_arch_mach (stdoutput, TARGET_ARCH, 0);
218}
219
a2429eb5
NC
220/* This is the guts of the machine-dependent assembler. STR points to
221 a machine dependent instruction. This function is supposed to emit
222 the frags/bytes it assembles to. */
041dd5a9
ILT
223
224void
ea1562b3 225md_assemble (char *str)
041dd5a9 226{
2132e3a3
AM
227 char *op_start;
228 char *op_end;
041dd5a9 229
041dd5a9
ILT
230 pj_opc_info_t *opcode;
231 char *output;
232 int idx = 0;
233 char pend;
234
235 int nlen = 0;
236
a2429eb5 237 /* Drop leading whitespace. */
041dd5a9
ILT
238 while (*str == ' ')
239 str++;
240
a2429eb5 241 /* Find the op code end. */
2132e3a3
AM
242 op_start = str;
243 for (op_end = str;
244 *op_end && !is_end_of_line[*op_end & 0xff] && *op_end != ' ';
a2429eb5 245 op_end++)
041dd5a9
ILT
246 nlen++;
247
248 pend = *op_end;
249 *op_end = 0;
250
251 if (nlen == 0)
a2429eb5 252 as_bad (_("can't find opcode "));
041dd5a9
ILT
253
254 opcode = (pj_opc_info_t *) hash_find (opcode_hash_control, op_start);
255 *op_end = pend;
256
257 if (opcode == NULL)
258 {
a2429eb5 259 as_bad (_("unknown opcode %s"), op_start);
041dd5a9
ILT
260 return;
261 }
262
d4f4f3fb 263 dwarf2_emit_insn (0);
041dd5a9
ILT
264 if (opcode->opcode == -1)
265 {
a2429eb5
NC
266 /* It's a fake opcode. Dig out the args and pretend that was
267 what we were passed. */
0e073f4c 268 (*opcode->u.func) (opcode, op_end);
041dd5a9
ILT
269 }
270 else
271 {
272 int an;
273
274 output = frag_more (opcode->len);
275 output[idx++] = opcode->opcode;
276
277 if (opcode->opcode_next != -1)
278 output[idx++] = opcode->opcode_next;
279
280 for (an = 0; opcode->arg[an]; an++)
281 {
282 expressionS arg;
283
284 if (*op_end == ',' && an != 0)
285 op_end++;
286
287 if (*op_end == 0)
9fd07943 288 as_bad (_("expected expression"));
041dd5a9
ILT
289
290 op_end = parse_exp_save_ilp (op_end, &arg);
291
a2429eb5 292 fix_new_exp (frag_now,
041dd5a9
ILT
293 output - frag_now->fr_literal + idx,
294 ASIZE (opcode->arg[an]),
295 &arg,
a2429eb5 296 PCREL (opcode->arg[an]),
041dd5a9
ILT
297 pending_reloc ? pending_reloc : c_to_r (opcode->arg[an]));
298
299 idx += ASIZE (opcode->arg[an]);
300 pending_reloc = 0;
301 }
302
3882b010 303 while (ISSPACE (*op_end))
041dd5a9
ILT
304 op_end++;
305
306 if (*op_end != 0)
20203fb9 307 as_warn (_("extra stuff on line ignored"));
041dd5a9
ILT
308
309 }
310
311 if (pending_reloc)
20203fb9 312 as_bad (_("Something forgot to clean up\n"));
041dd5a9
ILT
313}
314
041dd5a9 315char *
ea1562b3 316md_atof (int type, char *litP, int *sizeP)
041dd5a9 317{
499ac353 318 return ieee_md_atof (type, litP, sizeP, target_big_endian);
041dd5a9
ILT
319}
320\f
5a38dc70 321const char *md_shortopts = "";
041dd5a9 322
ea1562b3
NC
323struct option md_longopts[] =
324{
041dd5a9
ILT
325#define OPTION_LITTLE (OPTION_MD_BASE)
326#define OPTION_BIG (OPTION_LITTLE + 1)
327
328 {"little", no_argument, NULL, OPTION_LITTLE},
329 {"big", no_argument, NULL, OPTION_BIG},
330 {NULL, no_argument, NULL, 0}
331};
332size_t md_longopts_size = sizeof (md_longopts);
333
334int
ea1562b3 335md_parse_option (int c, char *arg ATTRIBUTE_UNUSED)
041dd5a9
ILT
336{
337 switch (c)
338 {
339 case OPTION_LITTLE:
0e073f4c 340 little (0);
041dd5a9
ILT
341 break;
342 case OPTION_BIG:
0e073f4c 343 big (0);
041dd5a9
ILT
344 break;
345 default:
346 return 0;
347 }
348 return 1;
349}
350
351void
ea1562b3 352md_show_usage (FILE *stream)
041dd5a9 353{
a2429eb5 354 fprintf (stream, _("\
041dd5a9
ILT
355PJ options:\n\
356-little generate little endian code\n\
357-big generate big endian code\n"));
358}
359
041dd5a9
ILT
360/* Apply a fixup to the object file. */
361
94f592af 362void
55cf6793 363md_apply_fix (fixS *fixP, valueT * valP, segT seg ATTRIBUTE_UNUSED)
041dd5a9
ILT
364{
365 char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
a161fe53 366 long val = *valP;
041dd5a9 367 long max, min;
041dd5a9 368
041dd5a9 369 max = min = 0;
041dd5a9
ILT
370 switch (fixP->fx_r_type)
371 {
372 case BFD_RELOC_VTABLE_INHERIT:
373 case BFD_RELOC_VTABLE_ENTRY:
374 fixP->fx_done = 0;
94f592af 375 return;
041dd5a9
ILT
376
377 case BFD_RELOC_PJ_CODE_REL16:
378 if (val < -0x8000 || val >= 0x7fff)
a2429eb5 379 as_bad_where (fixP->fx_file, fixP->fx_line, _("pcrel too far"));
041dd5a9
ILT
380 buf[0] |= (val >> 8) & 0xff;
381 buf[1] = val & 0xff;
382 break;
383
384 case BFD_RELOC_PJ_CODE_HI16:
385 *buf++ = val >> 24;
386 *buf++ = val >> 16;
387 fixP->fx_addnumber = val & 0xffff;
388 break;
389
390 case BFD_RELOC_PJ_CODE_DIR16:
391 case BFD_RELOC_PJ_CODE_LO16:
392 *buf++ = val >> 8;
393 *buf++ = val >> 0;
394
395 max = 0xffff;
396 min = -0xffff;
397 break;
398
399 case BFD_RELOC_8:
400 max = 0xff;
401 min = -0xff;
402 *buf++ = val;
403 break;
404
405 case BFD_RELOC_PJ_CODE_DIR32:
406 *buf++ = val >> 24;
407 *buf++ = val >> 16;
408 *buf++ = val >> 8;
409 *buf++ = val >> 0;
410 break;
411
412 case BFD_RELOC_32:
413 if (target_big_endian)
414 {
415 *buf++ = val >> 24;
416 *buf++ = val >> 16;
417 *buf++ = val >> 8;
418 *buf++ = val >> 0;
419 }
a2429eb5 420 else
041dd5a9
ILT
421 {
422 *buf++ = val >> 0;
423 *buf++ = val >> 8;
424 *buf++ = val >> 16;
425 *buf++ = val >> 24;
426 }
427 break;
428
429 case BFD_RELOC_16:
430 if (target_big_endian)
431 {
432 *buf++ = val >> 8;
433 *buf++ = val >> 0;
434 }
435 else
436 {
437 *buf++ = val >> 0;
438 *buf++ = val >> 8;
439 }
440 break;
441
041dd5a9
ILT
442 default:
443 abort ();
444 }
445
446 if (max != 0 && (val < min || val > max))
a2429eb5 447 as_bad_where (fixP->fx_file, fixP->fx_line, _("offset out of range"));
041dd5a9 448
94f592af
NC
449 if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
450 fixP->fx_done = 1;
041dd5a9
ILT
451}
452
453/* Put number into target byte order. Always put values in an
a2429eb5 454 executable section into big endian order. */
041dd5a9
ILT
455
456void
ea1562b3 457md_number_to_chars (char *ptr, valueT use, int nbytes)
041dd5a9
ILT
458{
459 if (target_big_endian || now_seg->flags & SEC_CODE)
460 number_to_chars_bigendian (ptr, use, nbytes);
461 else
462 number_to_chars_littleendian (ptr, use, nbytes);
463}
464
041dd5a9 465/* Translate internal representation of relocation info to BFD target
a2429eb5 466 format. */
041dd5a9
ILT
467
468arelent *
ea1562b3 469tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
041dd5a9
ILT
470{
471 arelent *rel;
472 bfd_reloc_code_real_type r_type;
473
ea1562b3
NC
474 rel = xmalloc (sizeof (arelent));
475 rel->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
041dd5a9
ILT
476 *rel->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
477 rel->address = fixp->fx_frag->fr_address + fixp->fx_where;
478
479 r_type = fixp->fx_r_type;
480 rel->addend = fixp->fx_addnumber;
481 rel->howto = bfd_reloc_type_lookup (stdoutput, r_type);
482
483 if (rel->howto == NULL)
484 {
485 as_bad_where (fixp->fx_file, fixp->fx_line,
a2429eb5 486 _("Cannot represent relocation type %s"),
041dd5a9
ILT
487 bfd_get_reloc_code_name (r_type));
488 /* Set howto to a garbage value so that we can keep going. */
489 rel->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_32);
9c2799c2 490 gas_assert (rel->howto != NULL);
041dd5a9
ILT
491 }
492
493 return rel;
494}
This page took 0.792367 seconds and 4 git commands to generate.