1/* GAS interface for targets using CGEN: Cpu tools GENerator.
2   Copyright (C) 1996-2022 Free Software Foundation, Inc.
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
8   the Free Software Foundation; either version 3, or (at your option)
9   any later version.
10
11   GAS is distributed in the hope that it will be useful, but WITHOUT
12   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
14   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 the Free Software
18   Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
19
20#include "as.h"
21#include <setjmp.h>
22#include "symcat.h"
23#include "cgen-desc.h"
24#include "subsegs.h"
25#include "cgen.h"
26#include "dwarf2dbg.h"
27
28#include "symbols.h"
29
30#ifdef OBJ_COMPLEX_RELC
31static expressionS * make_right_shifted_expr
32  (expressionS *, const int, const int);
33
34static unsigned long gas_cgen_encode_addend
35  (const unsigned long, const unsigned long, const unsigned long, \
36   const unsigned long, const unsigned long, const unsigned long, \
37   const unsigned long);
38
39static const char * weak_operand_overflow_check
40  (const expressionS *, const CGEN_OPERAND *);
41
42static void queue_fixup_recursively
43  (const int, const int, expressionS *, \
44   const CGEN_MAYBE_MULTI_IFLD *, const int, const int);
45
46static int rightshift = 0;
47#endif
48static void queue_fixup (int, int, expressionS *);
49
50/* Opcode table descriptor, must be set by md_begin.  */
51
52CGEN_CPU_DESC gas_cgen_cpu_desc;
53
54/* Callback to insert a register into the symbol table.
55   A target may choose to let GAS parse the registers.
56   ??? Not currently used.  */
57
58void
59cgen_asm_record_register (char *name, int number)
60{
61  /* Use symbol_create here instead of symbol_new so we don't try to
62     output registers into the object file's symbol table.  */
63  symbol_table_insert (symbol_create (name, reg_section,
64				      &zero_address_frag, number));
65}
66
67/* We need to keep a list of fixups.  We can't simply generate them as
68   we go, because that would require us to first create the frag, and
69   that would screw up references to ``.''.
70
71   This is used by cpu's with simple operands.  It keeps knowledge of what
72   an `expressionS' is and what a `fixup' is out of CGEN which for the time
73   being is preferable.
74
75   OPINDEX is the index in the operand table.
76   OPINFO is something the caller chooses to help in reloc determination.  */
77
78struct fixup
79{
80  int opindex;
81  int opinfo;
82  expressionS exp;
83  struct cgen_maybe_multi_ifield * field;
84  int msb_field_p;
85};
86
87static struct fixup fixups[GAS_CGEN_MAX_FIXUPS];
88static int num_fixups;
89
90/* Prepare to parse an instruction.
91   ??? May wish to make this static and delete calls in md_assemble.  */
92
93void
94gas_cgen_init_parse (void)
95{
96  num_fixups = 0;
97}
98
99/* Queue a fixup.  */
100
101static void
102queue_fixup (int opindex, int opinfo, expressionS *expP)
103{
104  /* We need to generate a fixup for this expression.  */
105  if (num_fixups >= GAS_CGEN_MAX_FIXUPS)
106    as_fatal (_("too many fixups"));
107  fixups[num_fixups].exp     = *expP;
108  fixups[num_fixups].opindex = opindex;
109  fixups[num_fixups].opinfo  = opinfo;
110  ++ num_fixups;
111}
112
113/* The following functions allow fixup chains to be stored, retrieved,
114   and swapped.  They are a generalization of a pre-existing scheme
115   for storing, restoring and swapping fixup chains that was used by
116   the m32r port.  The functionality is essentially the same, only
117   instead of only being able to store a single fixup chain, an entire
118   array of fixup chains can be stored.  It is the user's responsibility
119   to keep track of how many fixup chains have been stored and which
120   elements of the array they are in.
121
122   The algorithms used are the same as in the old scheme.  Other than the
123   "array-ness" of the whole thing, the functionality is identical to the
124   old scheme.
125
126   gas_cgen_initialize_saved_fixups_array():
127      Sets num_fixups_in_chain to 0 for each element. Call this from
128      md_begin() if you plan to use these functions and you want the
129      fixup count in each element to be set to 0 initially.  This is
130      not necessary, but it's included just in case.  It performs
131      the same function for each element in the array of fixup chains
132      that gas_init_parse() performs for the current fixups.
133
134   gas_cgen_save_fixups (element):
135      element - element number of the array you wish to store the fixups
136                to.  No mechanism is built in for tracking what element
137                was last stored to.
138
139   gas_cgen_restore_fixups (element):
140      element - element number of the array you wish to restore the fixups
141                from.
142
143   gas_cgen_swap_fixups(int element):
144       element - swap the current fixups with those in this element number.
145*/
146
147struct saved_fixups
148{
149  struct fixup fixup_chain[GAS_CGEN_MAX_FIXUPS];
150  int num_fixups_in_chain;
151};
152
153static struct saved_fixups stored_fixups[MAX_SAVED_FIXUP_CHAINS];
154
155void
156gas_cgen_initialize_saved_fixups_array (void)
157{
158  int i = 0;
159
160  while (i < MAX_SAVED_FIXUP_CHAINS)
161    stored_fixups[i++].num_fixups_in_chain = 0;
162}
163
164void
165gas_cgen_save_fixups (int i)
166{
167  if (i < 0 || i >= MAX_SAVED_FIXUP_CHAINS)
168    {
169      as_fatal ("index into stored_fixups[] out of bounds");
170      return;
171    }
172
173  stored_fixups[i].num_fixups_in_chain = num_fixups;
174  memcpy (stored_fixups[i].fixup_chain, fixups,
175	  sizeof (fixups[0]) * num_fixups);
176  num_fixups = 0;
177}
178
179void
180gas_cgen_restore_fixups (int i)
181{
182  if (i < 0 || i >= MAX_SAVED_FIXUP_CHAINS)
183    {
184      as_fatal ("index into stored_fixups[] out of bounds");
185      return;
186    }
187
188  num_fixups = stored_fixups[i].num_fixups_in_chain;
189  memcpy (fixups, stored_fixups[i].fixup_chain,
190	  (sizeof (stored_fixups[i].fixup_chain[0])) * num_fixups);
191  stored_fixups[i].num_fixups_in_chain = 0;
192}
193
194void
195gas_cgen_swap_fixups (int i)
196{
197  if (i < 0 || i >= MAX_SAVED_FIXUP_CHAINS)
198    {
199      as_fatal ("index into stored_fixups[] out of bounds");
200      return;
201    }
202
203  if (num_fixups == 0)
204    gas_cgen_restore_fixups (i);
205
206  else if (stored_fixups[i].num_fixups_in_chain == 0)
207    gas_cgen_save_fixups (i);
208
209  else
210    {
211      int tmp;
212      struct fixup tmp_fixup;
213
214      tmp = stored_fixups[i].num_fixups_in_chain;
215      stored_fixups[i].num_fixups_in_chain = num_fixups;
216      num_fixups = tmp;
217
218      for (tmp = GAS_CGEN_MAX_FIXUPS; tmp--;)
219	{
220	  tmp_fixup = stored_fixups[i].fixup_chain [tmp];
221	  stored_fixups[i].fixup_chain[tmp] = fixups [tmp];
222	  fixups [tmp] = tmp_fixup;
223	}
224    }
225}
226
227/* Default routine to record a fixup.
228   This is a cover function to fix_new.
229   It exists because we record INSN with the fixup.
230
231   FRAG and WHERE are their respective arguments to fix_new_exp.
232   LENGTH is in bits.
233   OPINFO is something the caller chooses to help in reloc determination.
234
235   At this point we do not use a bfd_reloc_code_real_type for
236   operands residing in the insn, but instead just use the
237   operand index.  This lets us easily handle fixups for any
238   operand type.  We pick a BFD reloc type in md_apply_fix.  */
239
240fixS *
241gas_cgen_record_fixup (fragS *frag, int where, const CGEN_INSN *insn,
242		       int length, const CGEN_OPERAND *operand, int opinfo,
243		       symbolS *symbol, offsetT offset)
244{
245  fixS *fixP;
246
247  /* It may seem strange to use operand->attrs and not insn->attrs here,
248     but it is the operand that has a pc relative relocation.  */
249  fixP = fix_new (frag, where, length / 8, symbol, offset,
250		  CGEN_OPERAND_ATTR_VALUE (operand, CGEN_OPERAND_PCREL_ADDR),
251		  (bfd_reloc_code_real_type)
252		    ((int) BFD_RELOC_UNUSED
253		     + (int) operand->type));
254  fixP->fx_cgen.insn = insn;
255  fixP->fx_cgen.opinfo = opinfo;
256  fixP->fx_cgen.field = NULL;
257  fixP->fx_cgen.msb_field_p = 0;
258
259  return fixP;
260}
261
262/* Default routine to record a fixup given an expression.
263   This is a cover function to fix_new_exp.
264   It exists because we record INSN with the fixup.
265
266   FRAG and WHERE are their respective arguments to fix_new_exp.
267   LENGTH is in bits.
268   OPINFO is something the caller chooses to help in reloc determination.
269
270   At this point we do not use a bfd_reloc_code_real_type for
271   operands residing in the insn, but instead just use the
272   operand index.  This lets us easily handle fixups for any
273   operand type.  We pick a BFD reloc type in md_apply_fix.  */
274
275fixS *
276gas_cgen_record_fixup_exp (fragS *frag, int where, const CGEN_INSN *insn,
277			   int length, const CGEN_OPERAND *operand, int opinfo,
278			   expressionS *exp)
279{
280  fixS *fixP;
281
282  /* It may seem strange to use operand->attrs and not insn->attrs here,
283     but it is the operand that has a pc relative relocation.  */
284  fixP = fix_new_exp (frag, where, length / 8, exp,
285		      CGEN_OPERAND_ATTR_VALUE (operand, CGEN_OPERAND_PCREL_ADDR),
286		      (bfd_reloc_code_real_type)
287		        ((int) BFD_RELOC_UNUSED
288			 + (int) operand->type));
289  fixP->fx_cgen.insn = insn;
290  fixP->fx_cgen.opinfo = opinfo;
291  fixP->fx_cgen.field = NULL;
292  fixP->fx_cgen.msb_field_p = 0;
293
294  return fixP;
295}
296
297#ifdef OBJ_COMPLEX_RELC
298static symbolS *
299expr_build_binary (operatorT op, symbolS * s1, symbolS * s2)
300{
301  expressionS e;
302
303  e.X_op = op;
304  e.X_add_symbol = s1;
305  e.X_op_symbol = s2;
306  e.X_add_number = 0;
307  return make_expr_symbol (& e);
308}
309#endif
310
311/* Used for communication between the next two procedures.  */
312static jmp_buf expr_jmp_buf;
313static int expr_jmp_buf_p;
314
315/* Callback for cgen interface.  Parse the expression at *STRP.
316   The result is an error message or NULL for success (in which case
317   *STRP is advanced past the parsed text).
318   WANT is an indication of what the caller is looking for.
319   If WANT == CGEN_ASM_PARSE_INIT the caller is beginning to try to match
320   a table entry with the insn, reset the queued fixups counter.
321   An enum cgen_parse_operand_result is stored in RESULTP.
322   OPINDEX is the operand's table entry index.
323   OPINFO is something the caller chooses to help in reloc determination.
324   The resulting value is stored in VALUEP.  */
325
326const char *
327gas_cgen_parse_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
328		       	enum cgen_parse_operand_type want, const char **strP,
329		       	int opindex, int opinfo,
330		       	enum cgen_parse_operand_result *resultP,
331		       	bfd_vma *valueP)
332{
333#ifdef __STDC__
334  /* These are volatile to survive the setjmp.  */
335  char * volatile hold;
336  enum cgen_parse_operand_result * volatile resultP_1;
337  volatile int opinfo_1;
338#else
339  static char *hold;
340  static enum cgen_parse_operand_result *resultP_1;
341  int opinfo_1;
342#endif
343  const char *errmsg;
344  expressionS exp;
345
346#ifdef OBJ_COMPLEX_RELC
347  volatile int              signed_p = 0;
348  symbolS *                 stmp = NULL;
349  bfd_reloc_code_real_type  reloc_type;
350  const CGEN_OPERAND *      operand;
351  fixS                      dummy_fixup;
352#endif
353  if (want == CGEN_PARSE_OPERAND_INIT)
354    {
355      gas_cgen_init_parse ();
356      return NULL;
357    }
358
359  resultP_1 = resultP;
360  hold = input_line_pointer;
361  input_line_pointer = (char *) *strP;
362  opinfo_1 = opinfo;
363
364  /* We rely on md_operand to longjmp back to us.
365     This is done via gas_cgen_md_operand.  */
366  if (setjmp (expr_jmp_buf) != 0)
367    {
368      expr_jmp_buf_p = 0;
369      input_line_pointer = (char *) hold;
370      *resultP_1 = CGEN_PARSE_OPERAND_RESULT_ERROR;
371      return _("illegal operand");
372    }
373
374  expr_jmp_buf_p = 1;
375  expression (&exp);
376  expr_jmp_buf_p = 0;
377  errmsg = NULL;
378
379  *strP = input_line_pointer;
380  input_line_pointer = hold;
381
382#ifdef TC_CGEN_PARSE_FIX_EXP
383  opinfo_1 = TC_CGEN_PARSE_FIX_EXP (opinfo_1, & exp);
384#endif
385
386  /* FIXME: Need to check `want'.  */
387
388  switch (exp.X_op)
389    {
390    case O_illegal:
391      errmsg = _("illegal operand");
392      *resultP = CGEN_PARSE_OPERAND_RESULT_ERROR;
393      break;
394    case O_absent:
395      errmsg = _("missing operand");
396      *resultP = CGEN_PARSE_OPERAND_RESULT_ERROR;
397      break;
398    case O_constant:
399      if (want == CGEN_PARSE_OPERAND_SYMBOLIC)
400	goto de_fault;
401      *valueP = exp.X_add_number;
402      *resultP = CGEN_PARSE_OPERAND_RESULT_NUMBER;
403      break;
404    case O_register:
405      *valueP = exp.X_add_number;
406      *resultP = CGEN_PARSE_OPERAND_RESULT_REGISTER;
407      break;
408    de_fault:
409    default:
410#ifdef OBJ_COMPLEX_RELC
411      /* Look up operand, check to see if there's an obvious
412	 overflow (this helps disambiguate some insn parses).  */
413      operand = cgen_operand_lookup_by_num (cd, opindex);
414      errmsg = weak_operand_overflow_check (& exp, operand);
415
416      if (! errmsg)
417	{
418	  asymbol *bsym;
419
420	  /* Fragment the expression as necessary, and queue a reloc.  */
421	  memset (& dummy_fixup, 0, sizeof (fixS));
422
423	  reloc_type = md_cgen_lookup_reloc (0, operand, & dummy_fixup);
424
425	  if (exp.X_op == O_symbol
426	      && reloc_type == BFD_RELOC_RELC
427	      && symbol_constant_p (exp.X_add_symbol)
428	      && (!symbol_symbolS (exp.X_add_symbol)
429		  || (bsym = symbol_get_bfdsym (exp.X_add_symbol)) == NULL
430		  || (bsym->section != expr_section
431		      && bsym->section != absolute_section
432		      && bsym->section != undefined_section)))
433	    {
434	      /* Local labels will have been (eagerly) turned into constants
435		 by now, due to the inappropriately deep insight of the
436		 expression parser.  Unfortunately make_expr_symbol
437		 prematurely dives into the symbol evaluator, and in this
438		 case it gets a bad answer, so we manually create the
439		 expression symbol we want here.  */
440	      stmp = symbol_create (FAKE_LABEL_NAME, expr_section,
441				    &zero_address_frag, 0);
442	      symbol_set_value_expression (stmp, & exp);
443	    }
444	  else
445	    stmp = make_expr_symbol (& exp);
446
447	  /* If this is a pc-relative RELC operand, we
448	     need to subtract "." from the expression.  */
449 	  if (reloc_type == BFD_RELOC_RELC
450	      && CGEN_OPERAND_ATTR_VALUE (operand, CGEN_OPERAND_PCREL_ADDR))
451 	    stmp = expr_build_binary (O_subtract, stmp, expr_build_dot ());
452
453	  /* FIXME: this is not a perfect heuristic for figuring out
454	     whether an operand is signed: it only works when the operand
455	     is an immediate. it's not terribly likely that any other
456	     values will be signed relocs, but it's possible. */
457	  if (operand && (operand->hw_type == HW_H_SINT))
458	    signed_p = 1;
459
460	  if (symbol_symbolS (stmp)
461	      && (bsym = symbol_get_bfdsym (stmp)) != NULL
462	      && bsym->section == expr_section
463	      && ! S_IS_LOCAL (stmp))
464	    {
465	      if (signed_p)
466		bsym->flags |= BSF_SRELC;
467	      else
468		bsym->flags |= BSF_RELC;
469	    }
470
471	  /* Now package it all up for the fixup emitter.  */
472	  exp.X_op = O_symbol;
473	  exp.X_op_symbol = 0;
474	  exp.X_add_symbol = stmp;
475	  exp.X_add_number = 0;
476
477	  /* Re-init rightshift quantity, just in case.  */
478	  rightshift = operand->length;
479	  queue_fixup_recursively (opindex, opinfo_1, & exp,
480				   (reloc_type == BFD_RELOC_RELC) ?
481				   & (operand->index_fields) : 0,
482				   signed_p, -1);
483	}
484      * resultP = errmsg
485	? CGEN_PARSE_OPERAND_RESULT_ERROR
486	: CGEN_PARSE_OPERAND_RESULT_QUEUED;
487      *valueP = 0;
488#else
489      queue_fixup (opindex, opinfo_1, &exp);
490      *valueP = 0;
491      *resultP = CGEN_PARSE_OPERAND_RESULT_QUEUED;
492#endif
493      break;
494    }
495
496  return errmsg;
497}
498
499/* md_operand handler to catch unrecognized expressions and halt the
500   parsing process so the next entry can be tried.
501
502   ??? This could be done differently by adding code to `expression'.  */
503
504void
505gas_cgen_md_operand (expressionS *expressionP ATTRIBUTE_UNUSED)
506{
507  /* Don't longjmp if we're not called from within cgen_parse_operand().  */
508  if (expr_jmp_buf_p)
509    longjmp (expr_jmp_buf, 1);
510}
511
512/* Finish assembling instruction INSN.
513   BUF contains what we've built up so far.
514   LENGTH is the size of the insn in bits.
515   RELAX_P is non-zero if relaxable insns should be emitted as such.
516   Otherwise they're emitted in non-relaxable forms.
517   The "result" is stored in RESULT if non-NULL.  */
518
519void
520gas_cgen_finish_insn (const CGEN_INSN *insn, CGEN_INSN_BYTES_PTR buf,
521		      unsigned int length, int relax_p, finished_insnS *result)
522{
523  int i;
524  int relax_operand;
525  char *f;
526  unsigned int byte_len = length / 8;
527
528  /* ??? Target foo issues various warnings here, so one might want to provide
529     a hook here.  However, our caller is defined in tc-foo.c so there
530     shouldn't be a need for a hook.  */
531
532  /* Write out the instruction.
533     It is important to fetch enough space in one call to `frag_more'.
534     We use (f - frag_now->fr_literal) to compute where we are and we
535     don't want frag_now to change between calls.
536
537     Relaxable instructions: We need to ensure we allocate enough
538     space for the largest insn.  */
539
540  if (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAXED))
541    /* These currently shouldn't get here.  */
542    abort ();
543
544  /* Is there a relaxable insn with the relaxable operand needing a fixup?  */
545
546  relax_operand = -1;
547  if (relax_p && CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAXABLE))
548    {
549      /* Scan the fixups for the operand affected by relaxing
550	 (i.e. the branch address).  */
551
552      for (i = 0; i < num_fixups; ++i)
553	{
554	  if (CGEN_OPERAND_ATTR_VALUE (cgen_operand_lookup_by_num (gas_cgen_cpu_desc, fixups[i].opindex),
555				       CGEN_OPERAND_RELAX))
556	    {
557	      relax_operand = i;
558	      break;
559	    }
560	}
561    }
562
563  if (relax_operand != -1)
564    {
565      int max_len;
566      fragS *old_frag;
567      expressionS *exp;
568      symbolS *sym;
569      offsetT off;
570
571#ifdef TC_CGEN_MAX_RELAX
572      max_len = TC_CGEN_MAX_RELAX (insn, byte_len);
573#else
574      max_len = CGEN_MAX_INSN_SIZE;
575#endif
576      /* Ensure variable part and fixed part are in same fragment.  */
577      /* FIXME: Having to do this seems like a hack.  */
578      frag_grow (max_len);
579
580      /* Allocate space for the fixed part.  */
581      f = frag_more (byte_len);
582
583      /* Create a relaxable fragment for this instruction.  */
584      old_frag = frag_now;
585
586      exp = &fixups[relax_operand].exp;
587      sym = exp->X_add_symbol;
588      off = exp->X_add_number;
589      if (exp->X_op != O_constant && exp->X_op != O_symbol)
590	{
591	  /* Handle complex expressions.  */
592	  sym = make_expr_symbol (exp);
593	  off = 0;
594	}
595
596      frag_var (rs_machine_dependent,
597		max_len - byte_len /* max chars */,
598		0 /* variable part already allocated */,
599		/* FIXME: When we machine generate the relax table,
600		   machine generate a macro to compute subtype.  */
601		1 /* subtype */,
602		sym,
603		off,
604		f);
605
606      /* Record the operand number with the fragment so md_convert_frag
607	 can use gas_cgen_md_record_fixup to record the appropriate reloc.  */
608      old_frag->fr_cgen.insn    = insn;
609      old_frag->fr_cgen.opindex = fixups[relax_operand].opindex;
610      old_frag->fr_cgen.opinfo  = fixups[relax_operand].opinfo;
611      if (result)
612	result->frag = old_frag;
613    }
614  else
615    {
616      f = frag_more (byte_len);
617      if (result)
618	result->frag = frag_now;
619    }
620
621  /* If we're recording insns as numbers (rather than a string of bytes),
622     target byte order handling is deferred until now.  */
623#if CGEN_INT_INSN_P
624  cgen_put_insn_value (gas_cgen_cpu_desc, (unsigned char *) f, length, *buf,
625                       gas_cgen_cpu_desc->insn_endian);
626#else
627  memcpy (f, buf, byte_len);
628#endif
629
630  /* Emit DWARF2 debugging information.  */
631  dwarf2_emit_insn (byte_len);
632
633  /* Create any fixups.  */
634  for (i = 0; i < num_fixups; ++i)
635    {
636      fixS *fixP;
637      const CGEN_OPERAND *operand =
638	cgen_operand_lookup_by_num (gas_cgen_cpu_desc, fixups[i].opindex);
639
640      /* Don't create fixups for these.  That's done during relaxation.
641	 We don't need to test for CGEN_INSN_RELAXED as they can't get here
642	 (see above).  */
643      if (relax_p
644	  && CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAXABLE)
645	  && CGEN_OPERAND_ATTR_VALUE (operand, CGEN_OPERAND_RELAX))
646	continue;
647
648#ifndef md_cgen_record_fixup_exp
649#define md_cgen_record_fixup_exp gas_cgen_record_fixup_exp
650#endif
651
652      fixP = md_cgen_record_fixup_exp (frag_now, f - frag_now->fr_literal,
653				       insn, length, operand,
654				       fixups[i].opinfo,
655				       &fixups[i].exp);
656      fixP->fx_cgen.field = fixups[i].field;
657      fixP->fx_cgen.msb_field_p = fixups[i].msb_field_p;
658      if (result)
659	result->fixups[i] = fixP;
660    }
661
662  if (result)
663    {
664      result->num_fixups = num_fixups;
665      result->addr = f;
666    }
667}
668
669#ifdef OBJ_COMPLEX_RELC
670/* Queue many fixups, recursively. If the field is a multi-ifield,
671   repeatedly queue its sub-parts, right shifted to fit into the field (we
672   assume here multi-fields represent a left-to-right, MSB0-LSB0
673   reading). */
674
675static void
676queue_fixup_recursively (const int                      opindex,
677			 const int                      opinfo,
678			 expressionS *                  expP,
679			 const CGEN_MAYBE_MULTI_IFLD *  field,
680			 const int                      signed_p,
681			 const int                      part_of_multi)
682{
683  if (field && field->count)
684    {
685      int i;
686
687      for (i = 0; i < field->count; ++ i)
688	queue_fixup_recursively (opindex, opinfo, expP,
689				 & (field->val.multi[i]), signed_p, i);
690    }
691  else
692    {
693      expressionS * new_exp = expP;
694
695#ifdef DEBUG
696      printf ("queueing fixup for field %s\n",
697	      (field ? field->val.leaf->name : "??"));
698      print_symbol_value (expP->X_add_symbol);
699#endif
700      if (field && part_of_multi != -1)
701	{
702	  rightshift -= field->val.leaf->length;
703
704	  /* Shift reloc value by number of bits remaining after this
705	     field.  */
706	  if (rightshift)
707	    new_exp = make_right_shifted_expr (expP, rightshift, signed_p);
708	}
709
710      /* Truncate reloc values to length, *after* leftmost one.  */
711      fixups[num_fixups].msb_field_p = (part_of_multi <= 0);
712      fixups[num_fixups].field = (CGEN_MAYBE_MULTI_IFLD *) field;
713
714      queue_fixup (opindex, opinfo, new_exp);
715    }
716}
717
718/* Encode the self-describing RELC reloc format's addend.  */
719
720static unsigned long
721gas_cgen_encode_addend (const unsigned long start,    /* in bits */
722			const unsigned long len,      /* in bits */
723			const unsigned long oplen,    /* in bits */
724			const unsigned long wordsz,   /* in bytes */
725			const unsigned long chunksz,  /* in bytes */
726			const unsigned long signed_p,
727			const unsigned long trunc_p)
728{
729  unsigned long res = 0L;
730
731  res |= start    & 0x3F;
732  res |= (oplen   & 0x3F) << 6;
733  res |= (len     & 0x3F) << 12;
734  res |= (wordsz  & 0xF)  << 18;
735  res |= (chunksz & 0xF)  << 22;
736  res |= (CGEN_INSN_LSB0_P ? 1 : 0) << 27;
737  res |= signed_p << 28;
738  res |= trunc_p << 29;
739
740  return res;
741}
742
743/* Purpose: make a weak check that the expression doesn't overflow the
744   operand it's to be inserted into.
745
746   Rationale: some insns used to use %operators to disambiguate during a
747   parse. when these %operators are translated to expressions by the macro
748   expander, the ambiguity returns. we attempt to disambiguate by field
749   size.
750
751   Method: check to see if the expression's top node is an O_and operator,
752   and the mask is larger than the operand length. This would be an
753   overflow, so signal it by returning an error string. Any other case is
754   ambiguous, so we assume it's OK and return NULL.  */
755
756static const char *
757weak_operand_overflow_check (const expressionS *  exp,
758			     const CGEN_OPERAND * operand)
759{
760  const unsigned long len = operand->length;
761  unsigned long mask;
762  unsigned long opmask = len == 0 ? 0 : (1UL << (len - 1) << 1) - 1;
763
764  if (!exp)
765    return NULL;
766
767  if (exp->X_op != O_bit_and)
768    {
769      /* Check for implicit overflow flag.  */
770      if (CGEN_OPERAND_ATTR_VALUE
771	  (operand, CGEN_OPERAND_RELOC_IMPLIES_OVERFLOW))
772	return _("a reloc on this operand implies an overflow");
773      return NULL;
774    }
775
776  mask = exp->X_add_number;
777
778  if (exp->X_add_symbol
779      && symbol_constant_p (exp->X_add_symbol))
780    mask |= *symbol_X_add_number (exp->X_add_symbol);
781
782  if (exp->X_op_symbol
783      && symbol_constant_p (exp->X_op_symbol))
784    mask |= *symbol_X_add_number (exp->X_op_symbol);
785
786  /* Want to know if mask covers more bits than opmask.
787     this is the same as asking if mask has any bits not in opmask,
788     or whether (mask & ~opmask) is nonzero.  */
789  if (mask && (mask & ~opmask))
790    {
791#ifdef DEBUG
792      printf ("overflow: (mask = %8.8x, ~opmask = %8.8x, AND = %8.8x)\n",
793	      mask, ~opmask, (mask & ~opmask));
794#endif
795      return _("operand mask overflow");
796    }
797
798  return NULL;
799}
800
801static expressionS *
802make_right_shifted_expr (expressionS * exp,
803			 const int     amount,
804			 const int     signed_p)
805{
806  symbolS * stmp = 0;
807  expressionS * new_exp;
808  asymbol *bsym;
809
810  stmp = expr_build_binary (O_right_shift,
811			    make_expr_symbol (exp),
812			    expr_build_uconstant (amount));
813  bsym = symbol_get_bfdsym (stmp);
814
815  if (signed_p)
816    bsym->flags |= BSF_SRELC;
817  else
818    bsym->flags |= BSF_RELC;
819
820  /* Then wrap that in a "symbol expr" for good measure.  */
821  new_exp = XNEW (expressionS);
822  memset (new_exp, 0, sizeof (expressionS));
823  new_exp->X_op = O_symbol;
824  new_exp->X_op_symbol = 0;
825  new_exp->X_add_symbol = stmp;
826  new_exp->X_add_number = 0;
827
828  return new_exp;
829}
830
831#endif
832
833/* Apply a fixup to the object code.  This is called for all the
834   fixups we generated by the call to fix_new_exp, above.  In the call
835   above we used a reloc code which was the largest legal reloc code
836   plus the operand index.  Here we undo that to recover the operand
837   index.  At this point all symbol values should be fully resolved,
838   and we attempt to completely resolve the reloc.  If we can not do
839   that, we determine the correct reloc code and put it back in the fixup.  */
840
841/* FIXME: This function handles some of the fixups and bfd_install_relocation
842   handles the rest.  bfd_install_relocation (or some other bfd function)
843   should handle them all.  */
844
845void
846gas_cgen_md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
847{
848  char *where = fixP->fx_frag->fr_literal + fixP->fx_where;
849  valueT value = * valP;
850  /* Canonical name, since used a lot.  */
851  CGEN_CPU_DESC cd = gas_cgen_cpu_desc;
852
853  if (fixP->fx_addsy == (symbolS *) NULL)
854    fixP->fx_done = 1;
855
856  /* We don't actually support subtracting a symbol.  */
857  if (fixP->fx_subsy != (symbolS *) NULL)
858    as_bad_where (fixP->fx_file, fixP->fx_line, _("expression too complex"));
859
860  if ((int) fixP->fx_r_type >= (int) BFD_RELOC_UNUSED)
861    {
862      int opindex = (int) fixP->fx_r_type - (int) BFD_RELOC_UNUSED;
863      const CGEN_OPERAND *operand = cgen_operand_lookup_by_num (cd, opindex);
864      const char *errmsg;
865      bfd_reloc_code_real_type reloc_type;
866      const CGEN_INSN *insn = fixP->fx_cgen.insn;
867#ifdef OBJ_COMPLEX_RELC
868      int start;
869      int length;
870      int signed_p = 0;
871
872      if (fixP->fx_cgen.field)
873	{
874	  /* Use the twisty little pointer path
875	     back to the ifield if it exists.  */
876	  start = fixP->fx_cgen.field->val.leaf->start;
877	  length = fixP->fx_cgen.field->val.leaf->length;
878	}
879      else
880	{
881	  /* Or the far less useful operand-size guesstimate.  */
882	  start = operand->start;
883	  length = operand->length;
884	}
885
886      /* FIXME: this is not a perfect heuristic for figuring out
887         whether an operand is signed: it only works when the operand
888         is an immediate. it's not terribly likely that any other
889         values will be signed relocs, but it's possible. */
890      if (operand && (operand->hw_type == HW_H_SINT))
891        signed_p = 1;
892#endif
893
894      /* If the reloc has been fully resolved finish the operand here.  */
895      /* FIXME: This duplicates the capabilities of code in BFD.  */
896      if (fixP->fx_done
897	  /* FIXME: If partial_inplace isn't set bfd_install_relocation won't
898	     finish the job.  Testing for pcrel is a temporary hack.  */
899	  || fixP->fx_pcrel)
900	{
901	  CGEN_FIELDS *fields = xmalloc (CGEN_CPU_SIZEOF_FIELDS (cd));
902
903	  CGEN_CPU_SET_FIELDS_BITSIZE (cd) (fields, CGEN_INSN_BITSIZE (insn));
904	  CGEN_CPU_SET_VMA_OPERAND (cd) (cd, opindex, fields, (bfd_vma) value);
905
906#if CGEN_INT_INSN_P
907	  {
908	    CGEN_INSN_INT insn_value =
909	      cgen_get_insn_value (cd, (unsigned char *) where,
910				   CGEN_INSN_BITSIZE (insn),
911                                   cd->insn_endian);
912
913	    /* ??? 0 is passed for `pc'.  */
914	    errmsg = CGEN_CPU_INSERT_OPERAND (cd) (cd, opindex, fields,
915						   &insn_value, (bfd_vma) 0);
916	    cgen_put_insn_value (cd, (unsigned char *) where,
917				 CGEN_INSN_BITSIZE (insn), insn_value,
918                                 cd->insn_endian);
919	  }
920#else
921	  /* ??? 0 is passed for `pc'.  */
922	  errmsg = CGEN_CPU_INSERT_OPERAND (cd) (cd, opindex, fields,
923						 (unsigned char *) where,
924						 (bfd_vma) 0);
925#endif
926	  if (errmsg)
927	    as_bad_where (fixP->fx_file, fixP->fx_line, "%s", errmsg);
928
929	  free (fields);
930	}
931
932      if (fixP->fx_done)
933	return;
934
935      /* The operand isn't fully resolved.  Determine a BFD reloc value
936	 based on the operand information and leave it to
937	 bfd_install_relocation.  Note that this doesn't work when
938	 partial_inplace == false.  */
939
940      reloc_type = md_cgen_lookup_reloc (insn, operand, fixP);
941#ifdef OBJ_COMPLEX_RELC
942      if (reloc_type == BFD_RELOC_RELC)
943	{
944	  /* Change addend to "self-describing" form,
945	     for BFD to handle in the linker.  */
946	  value = gas_cgen_encode_addend (start, operand->length,
947					  length, fixP->fx_size,
948					  cd->insn_chunk_bitsize / 8,
949					  signed_p,
950					  ! (fixP->fx_cgen.msb_field_p));
951	}
952#endif
953
954      if (reloc_type != BFD_RELOC_NONE)
955	fixP->fx_r_type = reloc_type;
956      else
957	{
958	  as_bad_where (fixP->fx_file, fixP->fx_line,
959			_("unresolved expression that must be resolved"));
960	  fixP->fx_done = 1;
961	  return;
962	}
963    }
964  else if (fixP->fx_done)
965    {
966      /* We're finished with this fixup.  Install it because
967	 bfd_install_relocation won't be called to do it.  */
968      switch (fixP->fx_r_type)
969	{
970	case BFD_RELOC_8:
971	  md_number_to_chars (where, value, 1);
972	  break;
973	case BFD_RELOC_16:
974	  md_number_to_chars (where, value, 2);
975	  break;
976	case BFD_RELOC_32:
977	  md_number_to_chars (where, value, 4);
978	  break;
979	case BFD_RELOC_64:
980	  md_number_to_chars (where, value, 8);
981	  break;
982	default:
983	  as_bad_where (fixP->fx_file, fixP->fx_line,
984			_("internal error: can't install fix for reloc type %d (`%s')"),
985			fixP->fx_r_type, bfd_get_reloc_code_name (fixP->fx_r_type));
986	  break;
987	}
988    }
989  /* else
990     bfd_install_relocation will be called to finish things up.  */
991
992  /* Tuck `value' away for use by tc_gen_reloc.
993     See the comment describing fx_addnumber in write.h.
994     This field is misnamed (or misused :-).  */
995  fixP->fx_addnumber = value;
996}
997
998bfd_reloc_code_real_type
999gas_cgen_pcrel_r_type (bfd_reloc_code_real_type r)
1000{
1001  switch (r)
1002    {
1003    case BFD_RELOC_8:  r = BFD_RELOC_8_PCREL;  break;
1004    case BFD_RELOC_16: r = BFD_RELOC_16_PCREL; break;
1005    case BFD_RELOC_24: r = BFD_RELOC_24_PCREL; break;
1006    case BFD_RELOC_32: r = BFD_RELOC_32_PCREL; break;
1007    case BFD_RELOC_64: r = BFD_RELOC_64_PCREL; break;
1008    default:
1009      break;
1010    }
1011  return r;
1012}
1013
1014/* Translate internal representation of relocation info to BFD target format.
1015
1016   FIXME: To what extent can we get all relevant targets to use this?  */
1017
1018arelent *
1019gas_cgen_tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixP)
1020{
1021  bfd_reloc_code_real_type r_type = fixP->fx_r_type;
1022  arelent *reloc;
1023
1024  reloc = XNEW (arelent);
1025
1026#ifdef GAS_CGEN_PCREL_R_TYPE
1027  if (fixP->fx_pcrel)
1028    r_type = GAS_CGEN_PCREL_R_TYPE (r_type);
1029#endif
1030  reloc->howto = bfd_reloc_type_lookup (stdoutput, r_type);
1031
1032  if (reloc->howto == (reloc_howto_type *) NULL)
1033    {
1034      as_bad_where (fixP->fx_file, fixP->fx_line,
1035		    _("relocation is not supported"));
1036      return NULL;
1037    }
1038
1039  gas_assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);
1040
1041  reloc->sym_ptr_ptr = XNEW (asymbol *);
1042  *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
1043
1044  /* Use fx_offset for these cases.  */
1045  if (fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY
1046      || fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT)
1047    reloc->addend = fixP->fx_offset;
1048  else
1049    reloc->addend = fixP->fx_addnumber;
1050
1051  reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
1052  return reloc;
1053}
1054
1055/* Perform any cgen specific initialisation.
1056   Called after gas_cgen_cpu_desc has been created.  */
1057
1058void
1059gas_cgen_begin (void)
1060{
1061  if (flag_signed_overflow_ok)
1062    cgen_set_signed_overflow_ok (gas_cgen_cpu_desc);
1063  else
1064    cgen_clear_signed_overflow_ok (gas_cgen_cpu_desc);
1065}
1066