/* tc-sparc.c -- Assemble for the SPARC
- Copyright (C) 1989-2016 Free Software Foundation, Inc.
+ Copyright (C) 1989-2020 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
GAS is free software; you can redistribute it and/or modify
#include "opcode/sparc.h"
#include "dw2gencfi.h"
-#ifdef OBJ_ELF
#include "elf/sparc.h"
#include "dwarf2dbg.h"
-#endif
/* Some ancient Sun C compilers would not take such hex constants as
unsigned, and would end up sign-extending them to form an offsetT,
#define U0x80000000 ((((unsigned long) 1 << 16) << 15))
static int sparc_ip (char *, const struct sparc_opcode **);
+static int parse_sparc_asi (char **, const sparc_asi **);
static int parse_keyword_arg (int (*) (const char *), char **, int *);
static int parse_const_expr_arg (char **, int *);
static int get_expression (char *);
changes the value before md_show_usage is called. */
static int default_arch_size;
-#ifdef OBJ_ELF
/* The currently selected v9 memory model. Currently only used for
ELF. */
static enum { MM_TSO, MM_PSO, MM_RMO } sparc_memory_model = MM_RMO;
GNU attributes section with hwcap information. */
static bfd_uint64_t hwcap_seen;
#endif
-#endif
static bfd_uint64_t hwcap_allowed;
static void s_empty (int);
static void s_uacons (int);
static void s_ncons (int);
-#ifdef OBJ_ELF
static void s_register (int);
-#endif
const pseudo_typeS md_pseudo_table[] =
{
{"uahalf", s_uacons, 2},
{"uaword", s_uacons, 4},
{"uaxword", s_uacons, 8},
-#ifdef OBJ_ELF
/* These are specific to sparc/svr4. */
{"2byte", s_uacons, 2},
{"4byte", s_uacons, 4},
{"8byte", s_uacons, 8},
{"register", s_register, 0},
-#endif
{NULL, 0, 0},
};
{ "sparc4", "v9v", v9, 0, 1, 0, 0 },
{ "sparc5", "v9m", v9, 0, 1, 0, 0 },
+ { "sparc6", "m8", v9, 0, 1, 0, 0 },
{ "leon", "leon", leon, 32, 1, 0, 0 },
{ "sparclet", "sparclet", sparclet, 32, 1, 0, 0 },
{ "v8pluse", "v9e", v9, 0, 1, HWCAP_V8PLUS, 0 },
{ "v8plusv", "v9v", v9, 0, 1, HWCAP_V8PLUS, 0 },
{ "v8plusm", "v9m", v9, 0, 1, HWCAP_V8PLUS, 0 },
-
+ { "v8plusm8", "m8", v9, 0, 1, HWCAP_V8PLUS, 0 },
+
{ "v9", "v9", v9, 0, 1, 0, 0 },
{ "v9a", "v9a", v9, 0, 1, 0, 0 },
{ "v9b", "v9b", v9, 0, 1, 0, 0 },
{ "v9e", "v9e", v9, 0, 1, 0, 0 },
{ "v9v", "v9v", v9, 0, 1, 0, 0 },
{ "v9m", "v9m", v9, 0, 1, 0, 0 },
+ { "v9m8", "m8", v9, 0, 1, 0, 0 },
/* This exists to allow configure.tgt to pass one
value to specify both the default machine and default word size. */
default_arch_type = sa->arch_type;
}
-/* Called by TARGET_FORMAT. */
+/* Called by TARGET_MACH. */
-const char *
-sparc_target_format (void)
+unsigned long
+sparc_mach (void)
{
/* We don't get a chance to initialize anything before we're called,
so handle that now. */
if (! default_init_p)
init_default_arch ();
-#ifdef OBJ_AOUT
-#ifdef TE_NetBSD
- return "a.out-sparc-netbsd";
-#else
-#ifdef TE_SPARCAOUT
- if (target_big_endian)
- return "a.out-sunos-big";
- else if (default_arch_type == sparc86x && target_little_endian_data)
- return "a.out-sunos-big";
- else
- return "a.out-sparc-little";
-#else
- return "a.out-sunos-big";
-#endif
-#endif
-#endif
+ return sparc_arch_size == 64 ? bfd_mach_sparc_v9 : bfd_mach_sparc;
+}
-#ifdef OBJ_BOUT
- return "b.out.big";
-#endif
+/* Called by TARGET_FORMAT. */
-#ifdef OBJ_COFF
-#ifdef TE_LYNX
- return "coff-sparc-lynx";
-#else
- return "coff-sparc";
-#endif
-#endif
+const char *
+sparc_target_format (void)
+{
+ /* We don't get a chance to initialize anything before we're called,
+ so handle that now. */
+ if (! default_init_p)
+ init_default_arch ();
#ifdef TE_VXWORKS
return "elf32-sparc-vxworks";
#endif
-#ifdef OBJ_ELF
return sparc_arch_size == 64 ? ELF64_TARGET_FORMAT : ELF_TARGET_FORMAT;
-#endif
-
- abort ();
}
\f
/* md_parse_option
* error. For example, from sparclite to v9.
*/
-#ifdef OBJ_ELF
const char *md_shortopts = "A:K:VQ:sq";
-#else
-#ifdef OBJ_AOUT
-const char *md_shortopts = "A:k";
-#else
-const char *md_shortopts = "A:";
-#endif
-#endif
struct option md_longopts[] = {
#define OPTION_BUMP (OPTION_MD_BASE)
{"bump", no_argument, NULL, OPTION_BUMP},
{"sparc", no_argument, NULL, OPTION_SPARC},
#define OPTION_XARCH (OPTION_MD_BASE + 2)
{"xarch", required_argument, NULL, OPTION_XARCH},
-#ifdef OBJ_ELF
#define OPTION_32 (OPTION_MD_BASE + 3)
{"32", no_argument, NULL, OPTION_32},
#define OPTION_64 (OPTION_MD_BASE + 4)
{"PSO", no_argument, NULL, OPTION_PSO},
#define OPTION_RMO (OPTION_MD_BASE + 7)
{"RMO", no_argument, NULL, OPTION_RMO},
-#endif
#ifdef SPARC_BIENDIAN
#define OPTION_LITTLE_ENDIAN (OPTION_MD_BASE + 8)
{"EL", no_argument, NULL, OPTION_LITTLE_ENDIAN},
{"enforce-aligned-data", no_argument, NULL, OPTION_ENFORCE_ALIGNED_DATA},
#define OPTION_LITTLE_ENDIAN_DATA (OPTION_MD_BASE + 11)
{"little-endian-data", no_argument, NULL, OPTION_LITTLE_ENDIAN_DATA},
-#ifdef OBJ_ELF
#define OPTION_NO_UNDECLARED_REGS (OPTION_MD_BASE + 12)
{"no-undeclared-regs", no_argument, NULL, OPTION_NO_UNDECLARED_REGS},
#define OPTION_UNDECLARED_REGS (OPTION_MD_BASE + 13)
{"undeclared-regs", no_argument, NULL, OPTION_UNDECLARED_REGS},
-#endif
#define OPTION_RELAX (OPTION_MD_BASE + 14)
{"relax", no_argument, NULL, OPTION_RELAX},
#define OPTION_NO_RELAX (OPTION_MD_BASE + 15)
break;
case OPTION_XARCH:
-#ifdef OBJ_ELF
if (!strncmp (arg, "v9", 2))
md_parse_option (OPTION_64, NULL);
else
|| !strcmp (arg, "sparc86x"))
md_parse_option (OPTION_32, NULL);
}
-#endif
/* Fall through. */
case 'A':
break;
#endif
-#ifdef OBJ_AOUT
- case 'k':
- sparc_pic_code = 1;
- break;
-#endif
-
-#ifdef OBJ_ELF
case OPTION_32:
case OPTION_64:
{
case OPTION_UNDECLARED_REGS:
no_undeclared_regs = 0;
break;
-#endif
case OPTION_RELAX:
sparc_relax = 1;
--enforce-aligned-data force .long, etc., to be aligned correctly\n\
-relax relax jumps and branches (default)\n\
-no-relax avoid changing any jumps and branches\n"));
-#ifdef OBJ_AOUT
- fprintf (stream, _("\
--k generate PIC\n"));
-#endif
-#ifdef OBJ_ELF
fprintf (stream, _("\
-32 create 32 bit object file\n\
-64 create 64 bit object file\n"));
-q ignored\n\
-Qy, -Qn ignored\n\
-s ignored\n"));
-#endif
#ifdef SPARC_BIENDIAN
fprintf (stream, _("\
-EL generate code for a little endian machine\n\
p->pop = &pop_table[i];
}
- /* Last entry is the centinel. */
+ /* Last entry is the sentinel. */
perc_table[entry].type = perc_entry_none;
qsort (perc_table, sizeof (perc_table) / sizeof (perc_table[0]),
void
sparc_md_end (void)
{
- unsigned long mach = bfd_mach_sparc;
-#if defined(OBJ_ELF) && !defined(TE_SOLARIS)
+ unsigned long mach;
+#ifndef TE_SOLARIS
int hwcaps, hwcaps2;
#endif
case SPARC_OPCODE_ARCH_V9E: mach = bfd_mach_sparc_v9e; break;
case SPARC_OPCODE_ARCH_V9V: mach = bfd_mach_sparc_v9v; break;
case SPARC_OPCODE_ARCH_V9M: mach = bfd_mach_sparc_v9m; break;
+ case SPARC_OPCODE_ARCH_M8: mach = bfd_mach_sparc_v9m8; break;
default: mach = bfd_mach_sparc_v9; break;
}
else
case SPARC_OPCODE_ARCH_V9E: mach = bfd_mach_sparc_v8pluse; break;
case SPARC_OPCODE_ARCH_V9V: mach = bfd_mach_sparc_v8plusv; break;
case SPARC_OPCODE_ARCH_V9M: mach = bfd_mach_sparc_v8plusm; break;
+ case SPARC_OPCODE_ARCH_M8: mach = bfd_mach_sparc_v8plusm8; break;
/* The sparclite is treated like a normal sparc. Perhaps it shouldn't
be but for now it is (since that's the way it's always been
treated). */
- default: break;
+ default: mach = bfd_mach_sparc; break;
}
bfd_set_arch_mach (stdoutput, bfd_arch_sparc, mach);
-#if defined(OBJ_ELF) && !defined(TE_SOLARIS)
+#ifndef TE_SOLARIS
hwcaps = hwcap_seen & U0xffffffff;
hwcaps2 = hwcap_seen >> 32;
static char *expr_end;
/* Values for `special_case'.
- Instructions that require wierd handling because they're longer than
+ Instructions that require weird handling because they're longer than
4 bytes. */
#define SPECIAL_CASE_NONE 0
#define SPECIAL_CASE_SET 1
as_warn (_("FP branch in delay slot"));
}
- /* SPARC before v9 requires a nop instruction between a floating
- point instruction and a floating point branch. We insert one
- automatically, with a warning. */
+ /* SPARC before v9 does not allow a floating point compare
+ directly before a floating point branch. Insert a nop
+ instruction if needed, with a warning. */
if (max_architecture < SPARC_OPCODE_ARCH_V9
&& last_insn != NULL
&& (insn->flags & F_FBR) != 0
- && (last_insn->flags & F_FLOAT) != 0)
+ && (last_insn->flags & F_FLOAT) != 0
+ && (last_insn->match & OP3 (0x35)) == OP3 (0x35))
{
struct sparc_it nop_insn;
nop_insn.opcode = NOP_INSN;
nop_insn.reloc = BFD_RELOC_NONE;
output_insn (insn, &nop_insn);
- as_warn (_("FP branch preceded by FP instruction; NOP inserted"));
+ as_warn (_("FP branch preceded by FP compare; NOP inserted"));
}
switch (special_case)
return "xmont";
if (mask & HWCAP2_NSEC)
return "nsec";
+ if (mask & HWCAP2_SPARC6)
+ return "sparc6";
+ if (mask & HWCAP2_ONADDSUB)
+ return "onaddsub";
+ if (mask & HWCAP2_ONMUL)
+ return "onmul";
+ if (mask & HWCAP2_ONDIV)
+ return "ondiv";
+ if (mask & HWCAP2_DICTUNP)
+ return "dictunp";
+ if (mask & HWCAP2_FPCMPSHL)
+ return "fpcmpshl";
+ if (mask & HWCAP2_RLE)
+ return "rle";
+ if (mask & HWCAP2_SHA3)
+ return "sha3";
return "UNKNOWN";
}
int comma = 0;
int v9_arg_p;
int special_case = SPECIAL_CASE_NONE;
+ const sparc_asi *sasi = NULL;
s = str;
if (ISLOWER (*s))
case 'e': /* next operand is a floating point register */
case 'v':
case 'V':
+ case ';':
case 'f':
case 'B':
case 'R':
+ case ':':
+ case '\'':
case '4':
case '5':
case 'H':
case 'J':
case '}':
+ case '^':
{
char format;
|| *args == 'B'
|| *args == '5'
|| *args == 'H'
+ || *args == '\''
|| format == 'd')
&& (mask & 1))
{
break;
}
+ if ((*args == ':'
+ || *args == ';'
+ || *args == '^')
+ && (mask & 7))
+ {
+ /* register must be multiple of 8 */
+ break;
+ }
+
+ if (*args == '\'' && mask < 48)
+ {
+ /* register must be higher or equal than %f48 */
+ break;
+ }
+
if (mask >= 64)
{
if (SPARC_OPCODE_ARCH_V9_P (max_architecture))
case 'v':
case 'V':
case 'e':
+ case ';':
opcode |= RS1 (mask);
continue;
case 'f':
case 'B':
case 'R':
+ case ':':
opcode |= RS2 (mask);
continue;
+ case '\'':
+ opcode |= RS2 (mask & 0xe);
+ continue;
+
case '4':
case '5':
opcode |= RS3 (mask);
case 'H':
case 'J':
case '}':
+ case '^':
opcode |= RD (mask);
continue;
} /* Pack it in. */
/* Parse an asi. */
if (*s == '#')
{
- if (! parse_keyword_arg (sparc_encode_asi, &s, &asi))
+ if (! parse_sparc_asi (&s, &sasi))
{
error_message = _(": invalid ASI name");
goto error;
}
+ asi = sasi->value;
}
else
{
s += 7;
continue;
+ case '&':
+ if (strncmp (s, "%entropy", 8) != 0)
+ break;
+ s += 8;
+ continue;
+
case 'E':
if (strncmp (s, "%ccr", 4) != 0)
break;
s += 4;
continue;
+ case '|':
+ {
+ int imm2 = 0;
+
+ /* Parse a 2-bit immediate. */
+ if (! parse_const_expr_arg (&s, &imm2))
+ {
+ error_message = _(": non-immdiate imm2 operand");
+ goto error;
+ }
+ if ((imm2 & ~0x3) != 0)
+ {
+ error_message = _(": imm2 immediate operand out of range (0-3)");
+ goto error;
+ }
+
+ opcode |= ((imm2 & 0x2) << 3) | (imm2 & 0x1);
+ continue;
+ }
+
case 'x':
{
char *push = input_line_pointer;
else
{
/* We have a match. Now see if the architecture is OK. */
+ /* String to use in case of architecture warning. */
+ const char *msg_str = str;
int needed_arch_mask = insn->architecture;
- bfd_uint64_t hwcaps
+
+ /* Include the ASI architecture needed as well */
+ if (sasi && needed_arch_mask > sasi->architecture)
+ {
+ needed_arch_mask = sasi->architecture;
+ msg_str = sasi->name;
+ }
+
+ bfd_uint64_t hwcaps
= (((bfd_uint64_t) insn->hwcaps2) << 32) | insn->hwcaps;
-#if defined(OBJ_ELF) && !defined(TE_SOLARIS)
+#ifndef TE_SOLARIS
if (hwcaps)
hwcap_seen |= hwcaps;
#endif
as_warn (_("architecture bumped from \"%s\" to \"%s\" on \"%s\""),
sparc_opcode_archs[current_architecture].name,
sparc_opcode_archs[needed_architecture].name,
- str);
+ msg_str);
warn_after_architecture = needed_architecture;
}
current_architecture = needed_architecture;
}
as_bad (_("Architecture mismatch on \"%s %s\"."), str, argsStart);
- as_tsktsk (_(" (Requires %s; requested architecture is %s.)"),
+ as_tsktsk (_("(Requires %s; requested architecture is %s.)"),
required_archs,
sparc_opcode_archs[max_architecture].name);
return special_case;
return special_case;
}
+static char *
+skip_over_keyword (char *q)
+{
+ for (q = q + (*q == '#' || *q == '%');
+ ISALNUM (*q) || *q == '_';
+ ++q)
+ continue;
+ return q;
+}
+
+static int
+parse_sparc_asi (char **input_pointer_p, const sparc_asi **value_p)
+{
+ const sparc_asi *value;
+ char c, *p, *q;
+
+ p = *input_pointer_p;
+ q = skip_over_keyword(p);
+ c = *q;
+ *q = 0;
+ value = sparc_encode_asi (p);
+ *q = c;
+ if (value == NULL)
+ return 0;
+ *value_p = value;
+ *input_pointer_p = q;
+ return 1;
+}
+
/* Parse an argument that can be expressed as a keyword.
(eg: #StoreStore or %ccfr).
The result is a boolean indicating success.
char c, *p, *q;
p = *input_pointerP;
- for (q = p + (*p == '#' || *p == '%');
- ISALNUM (*q) || *q == '_';
- ++q)
- continue;
+ q = skip_over_keyword(p);
c = *q;
*q = 0;
value = (*lookup_fn) (p);
last_insn = insn;
last_opcode = theinsn->opcode;
-#ifdef OBJ_ELF
dwarf2_emit_insn (4);
-#endif
}
\f
const char *
fixP->fx_addnumber = val; /* Remember value for emit_reloc. */
-#ifdef OBJ_ELF
/* SPARC ELF relocations don't use an addend in the data field. */
if (fixP->fx_addsy != NULL)
{
return;
}
-#endif
/* This is a hack. There should be a better way to
handle this. Probably in terms of howto fields, once
if (fixP->fx_r_type == BFD_RELOC_32_PCREL_S2 && fixP->fx_addsy)
val += fixP->fx_where + fixP->fx_frag->fr_address;
-#ifdef OBJ_AOUT
- /* FIXME: More ridiculous gas reloc hacking. If we are going to
- generate a reloc, then we just want to let the reloc addend set
- the value. We do not want to also stuff the addend into the
- object file. Including the addend in the object file works when
- doing a static link, because the linker will ignore the object
- file contents. However, the dynamic linker does not ignore the
- object file contents. */
- if (fixP->fx_addsy != NULL
- && fixP->fx_r_type != BFD_RELOC_32_PCREL_S2)
- val = 0;
-
- /* When generating PIC code, we do not want an addend for a reloc
- against a local symbol. We adjust fx_addnumber to cancel out the
- value already included in val, and to also cancel out the
- adjustment which bfd_install_relocation will create. */
- if (sparc_pic_code
- && fixP->fx_r_type != BFD_RELOC_32_PCREL_S2
- && fixP->fx_addsy != NULL
- && ! S_IS_COMMON (fixP->fx_addsy)
- && symbol_section_p (fixP->fx_addsy))
- fixP->fx_addnumber -= 2 * S_GET_VALUE (fixP->fx_addsy);
-
- /* When generating PIC code, we need to fiddle to get
- bfd_install_relocation to do the right thing for a PC relative
- reloc against a local symbol which we are going to keep. */
- if (sparc_pic_code
- && fixP->fx_r_type == BFD_RELOC_32_PCREL_S2
- && fixP->fx_addsy != NULL
- && (S_IS_EXTERNAL (fixP->fx_addsy)
- || S_IS_WEAK (fixP->fx_addsy))
- && S_IS_DEFINED (fixP->fx_addsy)
- && ! S_IS_COMMON (fixP->fx_addsy))
- {
- val = 0;
- fixP->fx_addnumber -= 2 * S_GET_VALUE (fixP->fx_addsy);
- }
-#endif
-
/* If this is a data relocation, just output VAL. */
if (fixP->fx_r_type == BFD_RELOC_8)
insn |= val & 0x3fffffff;
- /* See if we have a delay slot. */
- if (sparc_relax && fixP->fx_where + 8 <= fixP->fx_frag->fr_fix)
+ /* See if we have a delay slot. In that case we attempt to
+ optimize several cases transforming CALL instructions
+ into branches. But we can only do that if the relocation
+ can be completely resolved here, i.e. if no undefined
+ symbol is associated with it. */
+ if (sparc_relax && fixP->fx_addsy == NULL
+ && fixP->fx_where + 8 <= fixP->fx_frag->fr_fix)
{
#define G0 0
#define O7 15
switch (fixp->fx_r_type)
{
+ case BFD_RELOC_8:
case BFD_RELOC_16:
case BFD_RELOC_32:
+ case BFD_RELOC_64:
+ if (fixp->fx_pcrel)
+ {
+ switch (fixp->fx_size)
+ {
+ default:
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ _("can not do %d byte pc-relative relocation"),
+ fixp->fx_size);
+ code = fixp->fx_r_type;
+ fixp->fx_pcrel = 0;
+ break;
+ case 1: code = BFD_RELOC_8_PCREL; break;
+ case 2: code = BFD_RELOC_16_PCREL; break;
+ case 4: code = BFD_RELOC_32_PCREL; break;
+#ifdef BFD64
+ case 8: code = BFD_RELOC_64_PCREL; break;
+#endif
+ }
+ if (fixp->fx_pcrel)
+ fixp->fx_addnumber = fixp->fx_offset;
+ break;
+ }
+ /* Fall through. */
case BFD_RELOC_HI22:
case BFD_RELOC_LO10:
case BFD_RELOC_32_PCREL_S2:
case BFD_RELOC_SPARC_WDISP16:
case BFD_RELOC_SPARC_WDISP19:
case BFD_RELOC_SPARC_WDISP22:
- case BFD_RELOC_64:
case BFD_RELOC_SPARC_5:
case BFD_RELOC_SPARC_6:
case BFD_RELOC_SPARC_7:
return NULL;
}
-#if defined (OBJ_ELF) || defined (OBJ_AOUT)
/* If we are generating PIC code, we need to generate a different
set of relocs. */
-#ifdef OBJ_ELF
#define GOT_NAME "_GLOBAL_OFFSET_TABLE_"
-#else
-#define GOT_NAME "__GLOBAL_OFFSET_TABLE_"
-#endif
#ifdef TE_VXWORKS
#define GOTT_BASE "__GOTT_BASE__"
#define GOTT_INDEX "__GOTT_INDEX__"
#endif
- /* This code must be parallel to the OBJ_ELF tc_fix_adjustable. */
+ /* This code must be parallel to tc_fix_adjustable. */
if (sparc_pic_code)
{
break;
}
}
-#endif /* defined (OBJ_ELF) || defined (OBJ_AOUT) */
/* Nothing is aligned in DWARF debugging sections. */
- if (bfd_get_section_flags (stdoutput, section) & SEC_DEBUGGING)
+ if (bfd_section_flags (section) & SEC_DEBUGGING)
switch (code)
{
case BFD_RELOC_16: code = BFD_RELOC_SPARC_UA16; break;
}
/* @@ Why fx_addnumber sometimes and fx_offset other times? */
-#ifdef OBJ_AOUT
-
- if (reloc->howto->pc_relative == 0
- || code == BFD_RELOC_SPARC_PC10
- || code == BFD_RELOC_SPARC_PC22)
- reloc->addend = fixp->fx_addnumber;
- else if (sparc_pic_code
- && fixp->fx_r_type == BFD_RELOC_32_PCREL_S2
- && fixp->fx_addsy != NULL
- && (S_IS_EXTERNAL (fixp->fx_addsy)
- || S_IS_WEAK (fixp->fx_addsy))
- && S_IS_DEFINED (fixp->fx_addsy)
- && ! S_IS_COMMON (fixp->fx_addsy))
- reloc->addend = fixp->fx_addnumber;
- else
- reloc->addend = fixp->fx_offset - reloc->address;
-
-#else /* elf or coff */
-
if (code != BFD_RELOC_32_PCREL_S2
&& code != BFD_RELOC_SPARC_WDISP22
&& code != BFD_RELOC_SPARC_WDISP16
+ md_pcrel_from (fixp));
else
reloc->addend = fixp->fx_offset;
-#endif
/* We expand R_SPARC_OLO10 to R_SPARC_LO10 and R_SPARC_13
on the same location. */
valueT
md_section_align (segT segment ATTRIBUTE_UNUSED, valueT size)
{
-#ifndef OBJ_ELF
- /* This is not right for ELF; a.out wants it, and COFF will force
- the alignment anyways. */
- valueT align = ((valueT) 1
- << (valueT) bfd_get_section_alignment (stdoutput, segment));
- valueT newsize;
-
- /* Turn alignment value into a mask. */
- align--;
- newsize = (size + align) & ~align;
- return newsize;
-#else
return size;
-#endif
}
/* Exactly what point is a PC-relative offset relative TO?
/* Sort of like s_lcomm. */
-#ifndef OBJ_ELF
-static int max_alignment = 15;
-#endif
-
static void
s_reserve (int ignore ATTRIBUTE_UNUSED)
{
align = (int) get_absolute_expression ();
-#ifndef OBJ_ELF
- if (align > max_alignment)
- {
- align = max_alignment;
- as_warn (_("alignment too large; assuming %d"), align);
- }
-#endif
-
if (align < 0)
{
as_bad (_("negative alignment"));
else
align = 0;
- if (!S_IS_DEFINED (symbolP)
-#ifdef OBJ_AOUT
- && S_GET_OTHER (symbolP) == 0
- && S_GET_DESC (symbolP) == 0
-#endif
- )
+ if (!S_IS_DEFINED (symbolP))
{
if (! need_pass_2)
{
subseg_set (current_seg, current_subseg);
-#ifdef OBJ_ELF
S_SET_SIZE (symbolP, size);
-#endif
}
}
else
S_GET_NAME (symbolP), (long) S_GET_VALUE (symbolP), (long) size);
}
}
- else
- {
-#ifndef OBJ_ELF
- S_SET_VALUE (symbolP, (valueT) size);
- S_SET_EXTERNAL (symbolP);
-#endif
- }
know (symbol_get_frag (symbolP) == &zero_address_frag);
if (*input_line_pointer != ',')
{
{
temp = get_absolute_expression ();
-#ifndef OBJ_ELF
- if (temp > max_alignment)
- {
- temp = max_alignment;
- as_warn (_("alignment too large; assuming %ld"), (long) temp);
- }
-#endif
-
if (temp < 0)
{
as_bad (_("negative alignment"));
return;
}
-#ifdef OBJ_ELF
if (symbol_get_obj (symbolP)->local)
{
segT old_sec;
subseg_set (old_sec, old_subsec);
}
else
-#endif /* OBJ_ELF */
{
allocate_common:
S_SET_VALUE (symbolP, (valueT) size);
-#ifdef OBJ_ELF
S_SET_ALIGN (symbolP, temp);
S_SET_SIZE (symbolP, size);
-#endif
S_SET_EXTERNAL (symbolP);
S_SET_SEGMENT (symbolP, bfd_com_section_ptr);
}
cons (sparc_arch_size == 32 ? 4 : 8);
}
-#ifdef OBJ_ELF
/* Handle the SPARC ELF .register pseudo-op. This sets the binding of a
global register.
The syntax is:
S_SET_SEGMENT (sym, undefined_section);
}
}
-#endif
/* If the --enforce-aligned-data option is used, we require .word,
et. al., to be aligned correctly. We do it by setting up an
}
}
-#ifdef OBJ_ELF
/* Some special processing for a Sparc ELF file. */
void
return sparc_cons_special_reloc;
}
-#endif
-
/* This is called by emit_expr via TC_CONS_FIX_NEW when creating a
reloc for a cons. We could use the definition there, except that
we want to handle little endian relocs specially. */