1/* tc-ft32.c -- Assemble code for ft32
2   Copyright (C) 2008-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,
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
18   the Free Software Foundation, 51 Franklin Street - Fifth Floor,
19   Boston, MA 02110-1301, USA.  */
20
21/* Contributed by Anthony Green <green@spindazzle.org>.  */
22
23#include "as.h"
24#include "safe-ctype.h"
25#include "opcode/ft32.h"
26
27extern const ft32_opc_info_t ft32_opc_info[128];
28
29/* See md_parse_option() for meanings of these options.  */
30static char norelax;			/* True if -norelax switch seen.  */
31
32const char comment_chars[]        = "#";
33const char line_separator_chars[] = ";";
34const char line_comment_chars[]   = "#";
35
36static int pending_reloc;
37static htab_t opcode_hash_control;
38
39static valueT md_chars_to_number (char * buf, int n);
40
41const pseudo_typeS md_pseudo_table[] =
42{
43  {0, 0, 0}
44};
45
46const char FLT_CHARS[] = "rRsSfFdDxXpP";
47const char EXP_CHARS[] = "eE";
48
49/* This function is called once, at assembler startup time.  It sets
50   up the hash table with all the opcodes in it, and also initializes
51   some aliases for compatibility with other assemblers.  */
52
53void
54md_begin (void)
55{
56  const ft32_opc_info_t *opcode;
57  opcode_hash_control = str_htab_create ();
58
59  /* Insert names into hash table.  */
60  for (opcode = ft32_opc_info; opcode->name; opcode++)
61    str_hash_insert (opcode_hash_control, opcode->name, opcode, 0);
62
63  bfd_set_arch_mach (stdoutput, TARGET_ARCH, 0);
64  if (!norelax)
65    linkrelax = 1;
66}
67
68/* Parse an expression and then restore the input line pointer.  */
69
70static char *
71parse_exp_save_ilp (char *s, expressionS *op)
72{
73  char *save = input_line_pointer;
74
75  input_line_pointer = s;
76  expression (op);
77  s = input_line_pointer;
78  input_line_pointer = save;
79  return s;
80}
81
82static int
83parse_condition (char **ptr)
84{
85  char *s = *ptr;
86  static const struct
87  {
88    const char *name;
89    int bits;
90  }
91  ccs[] =
92  {
93    { "gt,"   , (2 << FT32_FLD_CR_BIT) | (5 << FT32_FLD_CB_BIT) | (1 << FT32_FLD_CV_BIT)},
94    { "gte,"  , (2 << FT32_FLD_CR_BIT) | (4 << FT32_FLD_CB_BIT) | (1 << FT32_FLD_CV_BIT)},
95    { "lt,"   , (2 << FT32_FLD_CR_BIT) | (4 << FT32_FLD_CB_BIT) | (0 << FT32_FLD_CV_BIT)},
96    { "lte,"  , (2 << FT32_FLD_CR_BIT) | (5 << FT32_FLD_CB_BIT) | (0 << FT32_FLD_CV_BIT)},
97    { "a,"    , (2 << FT32_FLD_CR_BIT) | (6 << FT32_FLD_CB_BIT) | (1 << FT32_FLD_CV_BIT)},
98    { "ae,"   , (2 << FT32_FLD_CR_BIT) | (1 << FT32_FLD_CB_BIT) | (0 << FT32_FLD_CV_BIT)},
99    { "be,"   , (2 << FT32_FLD_CR_BIT) | (6 << FT32_FLD_CB_BIT) | (0 << FT32_FLD_CV_BIT)},
100    { "b,"    , (2 << FT32_FLD_CR_BIT) | (1 << FT32_FLD_CB_BIT) | (1 << FT32_FLD_CV_BIT)},
101    { "nz,"   , (2 << FT32_FLD_CR_BIT) | (0 << FT32_FLD_CB_BIT) | (0 << FT32_FLD_CV_BIT)},
102    { "z,"    , (2 << FT32_FLD_CR_BIT) | (0 << FT32_FLD_CB_BIT) | (1 << FT32_FLD_CV_BIT)},
103    { "nc,"   , (2 << FT32_FLD_CR_BIT) | (1 << FT32_FLD_CB_BIT) | (0 << FT32_FLD_CV_BIT)},
104    { "c,"    , (2 << FT32_FLD_CR_BIT) | (1 << FT32_FLD_CB_BIT) | (1 << FT32_FLD_CV_BIT)},
105    { "no,"   , (2 << FT32_FLD_CR_BIT) | (2 << FT32_FLD_CB_BIT) | (0 << FT32_FLD_CV_BIT)},
106    { "o,"    , (2 << FT32_FLD_CR_BIT) | (2 << FT32_FLD_CB_BIT) | (1 << FT32_FLD_CV_BIT)},
107    { "ns,"   , (2 << FT32_FLD_CR_BIT) | (3 << FT32_FLD_CB_BIT) | (0 << FT32_FLD_CV_BIT)},
108    { "s,"    , (2 << FT32_FLD_CR_BIT) | (3 << FT32_FLD_CB_BIT) | (1 << FT32_FLD_CV_BIT)},
109    { NULL, 0}
110  }, *pc;
111
112  for (pc = ccs; pc->name; pc++)
113    {
114      if (memcmp(pc->name, s, strlen(pc->name)) == 0)
115        {
116          *ptr += strlen(pc->name) - 1;
117          return pc->bits;
118        }
119    }
120  return -1;
121}
122
123static int
124parse_decimal (char **ptr)
125{
126  int r = 0;
127  char *s = *ptr;
128
129  while (('0' <= *s) && (*s <= '9'))
130    {
131      r *= 10;
132      r += (*s++ - '0');
133    }
134  *ptr = s;
135  return r;
136}
137
138static int
139parse_register_operand (char **ptr)
140{
141  int reg;
142  char *s = *ptr;
143
144  if (*s != '$')
145    {
146      as_bad (_("expecting register"));
147      ignore_rest_of_line ();
148      return -1;
149    }
150  if ((s[1] == 's') && (s[2] == 'p'))
151    {
152      reg = 31;
153    }
154  else if ((s[1] == 'c') && (s[2] == 'c'))
155    {
156      reg = 30;
157    }
158  else if ((s[1] == 'f') && (s[2] == 'p'))
159    {
160      reg = 29;
161    }
162  else if (s[1] == 'r')
163    {
164      reg = s[2] - '0';
165      if ((reg < 0) || (reg > 9))
166	{
167	  as_bad (_("illegal register number"));
168	  ignore_rest_of_line ();
169	  return -1;
170	}
171      if ((reg == 1) || (reg == 2) || (reg == 3))
172	{
173	  int r2 = s[3] - '0';
174	  if ((r2 >= 0) && (r2 <= 9))
175	    {
176	      reg = (reg * 10) + r2;
177	      *ptr += 1;
178	    }
179	}
180    }
181  else
182    {
183      as_bad (_("illegal register number"));
184      ignore_rest_of_line ();
185      return -1;
186    }
187
188  *ptr += 3;
189
190  return reg;
191}
192
193/* This is the guts of the machine-dependent assembler.  STR points to
194   a machine dependent instruction.  This function is supposed to emit
195   the frags/bytes it assembles to.  */
196
197void
198md_assemble (char *str)
199{
200  char *op_start;
201  char *op_end;
202  ft32_opc_info_t *opcode;
203  char *output;
204  int idx = 0;
205  char pend;
206  int nlen = 0;
207  unsigned int b;
208  int f;
209  expressionS arg;
210  bool fixed = false;
211  unsigned int sc;
212  bool can_sc;
213
214  /* Drop leading whitespace.  */
215  while (*str == ' ')
216    str++;
217
218  /* Find the op code end.  */
219  op_start = str;
220  for (op_end = str;
221       *op_end
222       && !is_end_of_line[*op_end & 0xff]
223       && *op_end != ' '
224       && *op_end != '.';
225       op_end++)
226    nlen++;
227
228  pend = *op_end;
229  *op_end = 0;
230
231  if (nlen == 0)
232    as_bad (_("can't find opcode "));
233
234  opcode = (ft32_opc_info_t *) str_hash_find (opcode_hash_control, op_start);
235  *op_end = pend;
236
237  if (opcode == NULL)
238    {
239      as_bad (_("unknown opcode %s"), op_start);
240      return;
241    }
242
243  b = opcode->bits;
244  f = opcode->fields;
245
246  if (opcode->dw)
247    {
248      int dw;
249
250      if (*op_end == '.')
251        {
252          switch (op_end[1])
253            {
254              case 'b':
255                dw = 0;
256                break;
257              case 's':
258                dw = 1;
259                break;
260              case 'l':
261                dw = 2;
262                break;
263              default:
264                as_bad (_("unknown width specifier '.%c'"), op_end[1]);
265                return;
266            }
267          op_end += 2;
268        }
269      else
270        {
271          dw = 2; /* default is ".l" */
272        }
273      b |= dw << FT32_FLD_DW_BIT;
274    }
275
276  while (ISSPACE (*op_end))
277    op_end++;
278
279  output = frag_more (4);
280
281  while (f)
282    {
283      int lobit = f & -f;
284
285      if (f & lobit)
286        {
287          switch (lobit)
288	    {
289	    case  FT32_FLD_CBCRCV:
290	      b |= parse_condition( &op_end);
291	      break;
292	    case  FT32_FLD_CB:
293	      b |= parse_decimal (&op_end) << FT32_FLD_CB_BIT;
294	      break;
295	    case  FT32_FLD_R_D:
296	      b |= parse_register_operand (&op_end) << FT32_FLD_R_D_BIT;
297	      break;
298	    case  FT32_FLD_CR:
299	      b |= (parse_register_operand (&op_end) - 28) << FT32_FLD_CR_BIT;
300	      break;
301	    case  FT32_FLD_CV:
302	      b |= parse_decimal (&op_end) << FT32_FLD_CV_BIT;
303	      break;
304	    case  FT32_FLD_R_1:
305	      b |= parse_register_operand (&op_end) << FT32_FLD_R_1_BIT;
306	      break;
307	    case  FT32_FLD_RIMM:
308	      if (*op_end == '$')
309		{
310		  b |= parse_register_operand (&op_end) << FT32_FLD_RIMM_BIT;
311		}
312	      else
313		{
314		  b |= 0x400 << FT32_FLD_RIMM_BIT;
315		  op_end = parse_exp_save_ilp (op_end, &arg);
316		  fixed = true;
317		  fix_new_exp (frag_now,
318			       (output - frag_now->fr_literal),
319			       2,
320			       &arg,
321			       0,
322			       BFD_RELOC_FT32_10);
323		}
324	      break;
325	    case  FT32_FLD_R_2:
326	      b |= parse_register_operand (&op_end) << FT32_FLD_R_2_BIT;
327	      break;
328	    case  FT32_FLD_K20:
329	      op_end = parse_exp_save_ilp (op_end, &arg);
330	      fixed = true;
331	      fix_new_exp (frag_now,
332			   (output - frag_now->fr_literal),
333			   3,
334			   &arg,
335			   0,
336			   BFD_RELOC_FT32_20);
337	      break;
338	    case  FT32_FLD_PA:
339	      op_end = parse_exp_save_ilp (op_end, &arg);
340	      fixed = true;
341	      fix_new_exp (frag_now,
342			   (output - frag_now->fr_literal),
343			   3,
344			   &arg,
345			   0,
346			   BFD_RELOC_FT32_18);
347	      break;
348	    case  FT32_FLD_AA:
349	      op_end = parse_exp_save_ilp (op_end, &arg);
350	      fixed = true;
351	      fix_new_exp (frag_now,
352			   (output - frag_now->fr_literal),
353			   3,
354			   &arg,
355			   0,
356			   BFD_RELOC_FT32_17);
357	      break;
358	    case  FT32_FLD_K16:
359	      op_end = parse_exp_save_ilp (op_end, &arg);
360	      fixed = true;
361	      fix_new_exp (frag_now,
362			   (output - frag_now->fr_literal),
363			   2,
364			   &arg,
365			   0,
366			   BFD_RELOC_16);
367	      break;
368	    case  FT32_FLD_K15:
369	      op_end = parse_exp_save_ilp (op_end, &arg);
370	      if (arg.X_add_number & 0x80)
371		arg.X_add_number ^= 0x7f00;
372	      fixed = true;
373	      fix_new_exp (frag_now,
374			   (output - frag_now->fr_literal),
375			   2,
376			   &arg,
377			   0,
378			   BFD_RELOC_FT32_15);
379	      break;
380	    case  FT32_FLD_R_D_POST:
381	      b |= parse_register_operand (&op_end) << FT32_FLD_R_D_BIT;
382	      break;
383	    case  FT32_FLD_R_1_POST:
384	      b |= parse_register_operand (&op_end) << FT32_FLD_R_1_BIT;
385	      break;
386	    default:
387	      as_bad (_("internal error in argument parsing"));
388	      break;
389	    }
390
391          f &= ~lobit;
392
393          if (f)
394            {
395              while (ISSPACE (*op_end))
396                op_end++;
397
398              if (*op_end != ',')
399                {
400                  as_bad (_("expected comma separator"));
401                  ignore_rest_of_line ();
402                }
403
404              op_end++;
405              while (ISSPACE (*op_end))
406                op_end++;
407            }
408        }
409    }
410
411  if (*op_end != 0)
412    as_warn (_("extra stuff on line ignored"));
413
414  can_sc = ft32_shortcode (b, &sc);
415
416  if (!fixed && can_sc)
417    {
418      arg.X_op = O_constant;
419      arg.X_add_number = 0;
420      arg.X_add_symbol = NULL;
421      arg.X_op_symbol = NULL;
422      fix_new_exp (frag_now,
423                   (output - frag_now->fr_literal),
424                   2,
425                   &arg,
426                   0,
427                   BFD_RELOC_FT32_RELAX);
428    }
429
430  output[idx++] = 0xff & (b >> 0);
431  output[idx++] = 0xff & (b >> 8);
432  output[idx++] = 0xff & (b >> 16);
433  output[idx++] = 0xff & (b >> 24);
434
435  dwarf2_emit_insn (4);
436
437  while (ISSPACE (*op_end))
438    op_end++;
439
440  if (*op_end != 0)
441    as_warn ("extra stuff on line ignored");
442
443  if (pending_reloc)
444    as_bad ("Something forgot to clean up\n");
445}
446
447/* Turn a string in input_line_pointer into a floating point constant
448   of type type, and store the appropriate bytes in *LITP.  The number
449   of LITTLENUMS emitted is stored in *SIZEP .  An error message is
450   returned, or NULL on OK.  */
451
452const char *
453md_atof (int type, char *litP, int *sizeP)
454{
455  int prec;
456  LITTLENUM_TYPE words[4];
457  char *t;
458  int i;
459
460  switch (type)
461    {
462    case 'f':
463      prec = 2;
464      break;
465
466    case 'd':
467      prec = 4;
468      break;
469
470    default:
471      *sizeP = 0;
472      return _("bad call to md_atof");
473    }
474
475  t = atof_ieee (input_line_pointer, type, words);
476  if (t)
477    input_line_pointer = t;
478
479  *sizeP = prec * 2;
480
481  for (i = prec - 1; i >= 0; i--)
482    {
483      md_number_to_chars (litP, (valueT) words[i], 2);
484      litP += 2;
485    }
486
487  return NULL;
488}
489
490const char *md_shortopts = "";
491
492struct option md_longopts[] =
493{
494#define OPTION_NORELAX (OPTION_MD_BASE)
495  {"norelax", no_argument, NULL, OPTION_NORELAX},
496  {"no-relax", no_argument, NULL, OPTION_NORELAX},
497  {NULL, no_argument, NULL, 0}
498};
499size_t md_longopts_size = sizeof (md_longopts);
500
501/* We have no target specific options yet, so these next
502   two functions are empty.  */
503int
504md_parse_option (int c ATTRIBUTE_UNUSED, const char *arg ATTRIBUTE_UNUSED)
505{
506  switch (c)
507    {
508    case OPTION_NORELAX:
509      norelax = 1;
510      break;
511
512    default:
513      return 0;
514    }
515
516  return 1;
517}
518
519void
520md_show_usage (FILE *stream ATTRIBUTE_UNUSED)
521{
522  fprintf (stream, _("FT32 options:\n"));
523  fprintf (stream, _("\n\
524-no-relax		don't relax relocations\n\
525			\n"));
526}
527
528/* Convert from target byte order to host byte order.  */
529
530static valueT
531md_chars_to_number (char * buf, int n)
532{
533  valueT result = 0;
534  unsigned char * where = (unsigned char *) buf;
535
536  while (n--)
537    {
538      result <<= 8;
539      result |= (where[n] & 255);
540    }
541
542  return result;
543}
544
545/* Apply a fixup to the object file.  */
546
547void
548md_apply_fix (fixS *fixP ATTRIBUTE_UNUSED,
549	      valueT * valP ATTRIBUTE_UNUSED, segT seg ATTRIBUTE_UNUSED)
550{
551  char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
552  long val = *valP;
553  long newval;
554
555  if (linkrelax && fixP->fx_subsy)
556    {
557      /* For a subtraction relocation expression, generate one
558         of the DIFF relocs, with the value being the difference.
559         Note that a sym1 - sym2 expression is adjusted into a
560         section_start_sym + sym4_offset_from_section_start - sym1
561         expression. fixP->fx_addsy holds the section start symbol,
562         fixP->fx_offset holds sym2's offset, and fixP->fx_subsy
563         holds sym1. Calculate the current difference and write value,
564         but leave fx_offset as is - during relaxation,
565         fx_offset - value gives sym1's value.  */
566
567       switch (fixP->fx_r_type)
568         {
569           case BFD_RELOC_32:
570             fixP->fx_r_type = BFD_RELOC_FT32_DIFF32;
571             break;
572           default:
573             as_bad_subtract (fixP);
574             break;
575         }
576
577      val = S_GET_VALUE (fixP->fx_addsy) +
578          fixP->fx_offset - S_GET_VALUE (fixP->fx_subsy);
579      *valP = val;
580
581      fixP->fx_subsy = NULL;
582  }
583
584  /* We don't actually support subtracting a symbol.  */
585  if (fixP->fx_subsy != (symbolS *) NULL)
586    as_bad_subtract (fixP);
587
588  switch (fixP->fx_r_type)
589    {
590    case BFD_RELOC_FT32_DIFF32:
591    case BFD_RELOC_32:
592      buf[3] = val >> 24;
593      buf[2] = val >> 16;
594      buf[1] = val >> 8;
595      buf[0] = val >> 0;
596      break;
597
598    case BFD_RELOC_16:
599      buf[1] = val >> 8;
600      buf[0] = val >> 0;
601      break;
602
603    case BFD_RELOC_8:
604      *buf = val;
605      break;
606
607    case BFD_RELOC_FT32_10:
608      if (!val)
609	break;
610      newval = md_chars_to_number (buf, 2);
611      newval |= (val & ((1 << 10) - 1)) << FT32_FLD_RIMM_BIT;
612      md_number_to_chars (buf, newval, 2);
613      break;
614
615    case BFD_RELOC_FT32_20:
616      if (!val)
617	break;
618      newval = md_chars_to_number (buf, 3);
619      newval |= val & ((1 << 20) - 1);
620      md_number_to_chars (buf, newval, 3);
621      break;
622
623    case BFD_RELOC_FT32_15:
624      if (!val)
625	break;
626      newval = md_chars_to_number (buf, 2);
627      newval |= val & ((1 << 15) - 1);
628      md_number_to_chars (buf, newval, 2);
629      break;
630
631    case BFD_RELOC_FT32_17:
632      if (!val)
633	break;
634      newval = md_chars_to_number (buf, 3);
635      newval |= val & ((1 << 17) - 1);
636      md_number_to_chars (buf, newval, 3);
637      break;
638
639    case BFD_RELOC_FT32_18:
640      if (!val)
641	break;
642      newval = md_chars_to_number (buf, 4);
643      newval |= (val >> 2) & ((1 << 18) - 1);
644      md_number_to_chars (buf, newval, 4);
645      break;
646
647    case BFD_RELOC_FT32_RELAX:
648      break;
649
650    default:
651      abort ();
652    }
653
654  if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
655    fixP->fx_done = 1;
656}
657
658void
659md_number_to_chars (char *ptr, valueT use, int nbytes)
660{
661  number_to_chars_littleendian (ptr, use, nbytes);
662}
663
664/* Generate a machine-dependent relocation.  */
665
666arelent *
667tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixP)
668{
669  arelent *relP;
670  bfd_reloc_code_real_type code;
671
672  switch (fixP->fx_r_type)
673    {
674    case BFD_RELOC_32:
675    case BFD_RELOC_16:
676    case BFD_RELOC_8:
677    case BFD_RELOC_FT32_10:
678    case BFD_RELOC_FT32_20:
679    case BFD_RELOC_FT32_15:
680    case BFD_RELOC_FT32_17:
681    case BFD_RELOC_FT32_18:
682    case BFD_RELOC_FT32_RELAX:
683    case BFD_RELOC_FT32_DIFF32:
684      code = fixP->fx_r_type;
685      break;
686    default:
687      as_bad_where (fixP->fx_file, fixP->fx_line,
688		    _("Semantics error.  This type of operand can not be "
689                      "relocated, it must be an assembly-time constant"));
690      return NULL;
691    }
692
693  relP = XNEW (arelent);
694  gas_assert (relP != 0);
695  relP->sym_ptr_ptr = XNEW (asymbol *);
696  *relP->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
697  relP->address = fixP->fx_frag->fr_address + fixP->fx_where;
698
699  relP->addend = fixP->fx_offset;
700
701  relP->howto = bfd_reloc_type_lookup (stdoutput, code);
702  if (! relP->howto)
703    {
704      const char *name;
705
706      name = S_GET_NAME (fixP->fx_addsy);
707      if (name == NULL)
708	name = _("<unknown>");
709      as_fatal (_("Cannot generate relocation type for symbol %s, code %s"),
710		name, bfd_get_reloc_code_name (code));
711    }
712
713  return relP;
714}
715
716/* TC_FORCE_RELOCATION hook */
717
718static bool
719relaxable_section (asection *sec)
720{
721  return ((sec->flags & SEC_DEBUGGING) == 0
722          && (sec->flags & SEC_CODE) != 0
723          && (sec->flags & SEC_ALLOC) != 0);
724}
725
726/* Does whatever the xtensa port does.  */
727
728int
729ft32_validate_fix_sub (fixS *fix)
730{
731  segT add_symbol_segment, sub_symbol_segment;
732
733  /* The difference of two symbols should be resolved by the assembler when
734     linkrelax is not set.  If the linker may relax the section containing
735     the symbols, then an Xtensa DIFF relocation must be generated so that
736     the linker knows to adjust the difference value.  */
737  if (!linkrelax || fix->fx_addsy == NULL)
738    return 0;
739
740  /* Make sure both symbols are in the same segment, and that segment is
741     "normal" and relaxable.  If the segment is not "normal", then the
742     fix is not valid.  If the segment is not "relaxable", then the fix
743     should have been handled earlier.  */
744  add_symbol_segment = S_GET_SEGMENT (fix->fx_addsy);
745  if (! SEG_NORMAL (add_symbol_segment) ||
746      ! relaxable_section (add_symbol_segment))
747    return 0;
748
749  sub_symbol_segment = S_GET_SEGMENT (fix->fx_subsy);
750  return (sub_symbol_segment == add_symbol_segment);
751}
752
753/* TC_FORCE_RELOCATION hook */
754
755/* If linkrelax is turned on, and the symbol to relocate
756   against is in a relaxable segment, don't compute the value -
757   generate a relocation instead.  */
758
759int
760ft32_force_relocation (fixS *fix)
761{
762  if (linkrelax && fix->fx_addsy
763      && relaxable_section (S_GET_SEGMENT (fix->fx_addsy)))
764    {
765      return 1;
766    }
767
768  return generic_force_reloc (fix);
769}
770
771bool
772ft32_allow_local_subtract (expressionS * left,
773			   expressionS * right,
774			   segT section)
775{
776  /* If we are not in relaxation mode, subtraction is OK.  */
777  if (!linkrelax)
778    return true;
779
780  /* If the symbols are not in a code section then they are OK.  */
781  if ((section->flags & SEC_CODE) == 0)
782    return true;
783
784  if (left->X_add_symbol == right->X_add_symbol)
785    return true;
786
787  /* We have to assume that there may be instructions between the
788     two symbols and that relaxation may increase the distance between
789     them.  */
790  return false;
791}
792