binutils  2.23.2
About: GNU Binutils are a collection of binary tools. The main ones are "ld" the GNU linker and "(g)as" the GNU assembler.
  Fossies Dox: binutils-2.23.2.tar.gz  ("inofficial" and yet experimental doxygen-generated source code documentation)  

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