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