/* tc-cris.c -- Assembler code for the CRIS CPU core.
- Copyright 2000, 2001, 2002, 2003, 2004, 2006, 2007
- Free Software Foundation, Inc.
+ Copyright (C) 2000-2014 Free Software Foundation, Inc.
Contributed by Axis Communications AB, Lund, Sweden.
Originally written for GAS 1.38.1 by Mikael Asker.
/* Like in ":GOT", ":GOTOFF" etc. Other ports use '@', but that's in
line_separator_chars for CRIS, so we avoid it. */
-#define PIC_SUFFIX_CHAR ':'
+#define RELOC_SUFFIX_CHAR ':'
/* This might be CRIS_INSN_NONE if we're assembling a prefix-insn only.
Note that some prefix-insns might be assembled as CRIS_INSN_NORMAL. */
static void gen_cond_branch_32 (char *, char *, fragS *, symbolS *, symbolS *,
long int);
static void cris_number_to_imm (char *, long, int, fixS *, segT);
-static void cris_create_short_jump (char *, addressT, addressT, fragS *,
- symbolS *);
static void s_syntax (int);
static void s_cris_file (int);
static void s_cris_loc (int);
static void s_cris_arch (int);
+static void s_cris_dtpoff (int);
/* Get ":GOT", ":GOTOFF", ":PLT" etc. suffixes. */
-static void cris_get_pic_suffix (char **, bfd_reloc_code_real_type *,
- expressionS *);
-static unsigned int cris_get_pic_reloc_size (bfd_reloc_code_real_type);
+static void cris_get_reloc_suffix (char **, bfd_reloc_code_real_type *,
+ expressionS *);
+static unsigned int cris_get_specified_reloc_size (bfd_reloc_code_real_type);
/* All the .syntax functions. */
static void cris_force_reg_prefix (void);
/* Whether or not we allow PIC, and expand to PIC-friendly constructs. */
static bfd_boolean pic = FALSE;
+/* Whether or not we allow TLS suffixes. For the moment, we always do. */
+static const bfd_boolean tls = TRUE;
+
/* If we're configured for "cris", default to allow all v0..v10
instructions and register names. */
#ifndef DEFAULT_CRIS_ARCH
const pseudo_typeS md_pseudo_table[] =
{
{"dword", cons, 4},
+ {"dtpoffd", s_cris_dtpoff, 4},
{"syntax", s_syntax, 0},
{"file", s_cris_file, 0},
{"loc", s_cris_loc, 0},
because of the different reasons that they aren't relaxable. */
switch (fragP->fr_subtype)
{
+ case ENCODE_RELAX (STATE_COND_BRANCH_PIC, STATE_DWORD):
case ENCODE_RELAX (STATE_COND_BRANCH, STATE_DWORD):
case ENCODE_RELAX (STATE_COND_BRANCH_V32, STATE_DWORD):
case ENCODE_RELAX (STATE_COND_BRANCH_COMMON, STATE_DWORD):
/* Used to check integrity of the relaxation.
One of 2 = long, 1 = word, or 0 = byte. */
- int length_code;
+ int length_code ATTRIBUTE_UNUSED;
/* Size in bytes of variable-sized part of frag. */
int var_part_size = 0;
}
/* Generate a short jump around a secondary jump table.
- Used by md_create_long_jump.
+ Also called from md_create_long_jump, when sufficient. */
- This used to be md_create_short_jump, but is now called from
- md_create_long_jump instead, when sufficient, since the sizes of the
- jumps are the same for pre-v32. */
-
-static void
-cris_create_short_jump (char *storep, addressT from_addr, addressT to_addr,
+void
+md_create_short_jump (char *storep, addressT from_addr, addressT to_addr,
fragS *fragP ATTRIBUTE_UNUSED,
symbolS *to_symbol ATTRIBUTE_UNUSED)
{
/* See md_create_long_jump about the comment on the "+ 2". */
long int max_minimal_minus_distance;
long int max_minimal_plus_distance;
+ long int max_minus_distance;
+ long int max_plus_distance;
int nop_opcode;
if (cris_arch == arch_crisv32)
{
max_minimal_minus_distance = BRANCH_BB_V32 + 2;
max_minimal_plus_distance = BRANCH_BF_V32 + 2;
+ max_minus_distance = BRANCH_WB_V32 + 2;
+ max_plus_distance = BRANCH_WF_V32 + 2;
nop_opcode = NOP_OPCODE_V32;
}
+ else if (cris_arch == arch_cris_common_v10_v32)
+ /* Bail out for compatibility mode. (It seems it can be implemented,
+ perhaps with a 10-byte sequence: "move.d NNNN,$pc/$acr", "jump
+ $acr", "nop"; but doesn't seem worth it at the moment.) */
+ as_fatal (_("Out-of-range .word offset handling\
+ is not implemented for .arch common_v10_v32"));
else
{
max_minimal_minus_distance = BRANCH_BB + 2;
max_minimal_plus_distance = BRANCH_BF + 2;
+ max_minus_distance = BRANCH_WB + 2;
+ max_plus_distance = BRANCH_WF + 2;
nop_opcode = NOP_OPCODE;
}
a nop to keep disassembly sane. */
md_number_to_chars (storep + 4, nop_opcode, 2);
}
- else
+ else if (max_minus_distance <= distance
+ && distance <= max_plus_distance)
{
/* Make it a "long" short jump: "BA (PC+)". */
md_number_to_chars (storep, BA_PC_INCR_OPCODE, 2);
/* A nop for the delay slot. */
md_number_to_chars (storep + 4, nop_opcode, 2);
}
+ else
+ as_bad_where (fragP->fr_file, fragP->fr_line,
+ _(".word case-table handling failed: table too large"));
}
/* Generate a long jump in a secondary jump table.
long int max_short_plus_distance
= cris_arch != arch_crisv32 ? BRANCH_WF + 3 : BRANCH_WF_V32 + 3;
- /* Bail out for compatibility mode. (It seems it can be implemented,
- perhaps with a 10-byte sequence: "move.d NNNN,$pc/$acr", "jump
- $acr", "nop"; but doesn't seem worth it at the moment.) */
- if (cris_arch == arch_cris_common_v10_v32)
- as_fatal (_("Out-of-range .word offset handling\
- is not implemented for .arch common_v10_v32"));
-
distance = to_addr - from_addr;
if (max_short_minus_distance <= distance
&& distance <= max_short_plus_distance)
- /* Then make it a "short" long jump. */
- cris_create_short_jump (storep, from_addr, to_addr, fragP,
+ {
+ /* Then make it a "short" long jump. */
+ md_create_short_jump (storep, from_addr, to_addr, fragP,
to_symbol);
+ if (cris_arch == arch_crisv32)
+ md_number_to_chars (storep + 6, NOP_OPCODE_V32, 2);
+ else
+ md_number_to_chars (storep + 6, NOP_OPCODE, 2);
+ }
else
{
/* We have a "long" long jump: "JUMP [PC+]". If CRISv32, always
/* When the expression is unknown for a BDAP, it can need 0, 2 or 4
extra bytes, so we handle it separately. */
case PREFIX_BDAP_IMM:
- /* We only do it if the relocation is unspecified, i.e. not a PIC
+ /* We only do it if the relocation is unspecified, i.e. not a PIC or TLS
relocation. */
if (prefix.reloc == BFD_RELOC_NONE)
{
md_number_to_chars (opcodep, (long) prefix.opcode, 2);
/* Having a specified reloc only happens for DIP and for BDAP with
- PIC operands, but it is ok to drop through here for the other
+ PIC or TLS operands, but it is ok to drop through here for the other
prefixes as they can have no relocs specified. */
if (prefix.reloc != BFD_RELOC_NONE)
{
unsigned int relocsize
= (prefix.kind == PREFIX_DIP
- ? 4 : cris_get_pic_reloc_size (prefix.reloc));
+ ? 4 : cris_get_specified_reloc_size (prefix.reloc));
p = frag_more (relocsize);
fix_new_exp (frag_now, (p - frag_now->fr_literal), relocsize,
}
}
+/* Helper error-reporting function: calls as_bad for a format string
+ for a single value and zeroes the offending value (zero assumed
+ being a valid value) to avoid repeated error reports in later value
+ checking. */
+
+static void
+cris_bad (const char *format, offsetT *valp)
+{
+ /* We cast to long so the format string can assume that format. */
+ as_bad (format, (long) *valp);
+ *valp = 0;
+}
+
/* Low level text-to-bits assembly. */
static void
if (out_insnp->expr.X_op == O_constant
&& (out_insnp->expr.X_add_number < 0
|| out_insnp->expr.X_add_number > 31))
- as_bad (_("Immediate value not in 5 bit unsigned range: %ld"),
- out_insnp->expr.X_add_number);
+ cris_bad (_("Immediate value not in 5 bit unsigned range: %ld"),
+ &out_insnp->expr.X_add_number);
out_insnp->reloc = BFD_RELOC_CRIS_UNSIGNED_5;
continue;
if (out_insnp->expr.X_op == O_constant
&& (out_insnp->expr.X_add_number < 0
|| out_insnp->expr.X_add_number > 15))
- as_bad (_("Immediate value not in 4 bit unsigned range: %ld"),
- out_insnp->expr.X_add_number);
+ cris_bad (_("Immediate value not in 4 bit unsigned range: %ld"),
+ &out_insnp->expr.X_add_number);
out_insnp->reloc = BFD_RELOC_CRIS_UNSIGNED_4;
continue;
if (out_insnp->expr.X_op == O_constant
&& (out_insnp->expr.X_add_number < -32
|| out_insnp->expr.X_add_number > 31))
- as_bad (_("Immediate value not in 6 bit range: %ld"),
- out_insnp->expr.X_add_number);
+ cris_bad (_("Immediate value not in 6 bit range: %ld"),
+ &out_insnp->expr.X_add_number);
+
out_insnp->reloc = BFD_RELOC_CRIS_SIGNED_6;
continue;
}
if (out_insnp->expr.X_op == O_constant
&& (out_insnp->expr.X_add_number < 0
|| out_insnp->expr.X_add_number > 63))
- as_bad (_("Immediate value not in 6 bit unsigned range: %ld"),
- out_insnp->expr.X_add_number);
+ cris_bad (_("Immediate value not in 6 bit unsigned range: %ld"),
+ &out_insnp->expr.X_add_number);
+
out_insnp->reloc = BFD_RELOC_CRIS_UNSIGNED_6;
continue;
}
pseudo yet, so some of this is just unused
framework. */
if (out_insnp->spec_reg->warning)
- as_warn (out_insnp->spec_reg->warning);
+ as_warn ("%s", out_insnp->spec_reg->warning);
else if (out_insnp->spec_reg->applicable_version
== cris_ver_warning)
/* Others have a generic warning. */
whether or not this is autoincrement mode. */
out_insnp->opcode |= (mode << 10);
- /* If there was a PIC reloc specifier, then it was
+ /* If there was a reloc specifier, then it was
attached to the prefix. Note that we can't check
that the reloc size matches, since we don't have
all the operands yet in all cases. */
case 'N':
case 'Y':
- /* Like 's', but immediate operand only. Also does not
- modify insn. There are no insns where a PIC reloc
+ /* Like 's', but immediate operand only. Also do not
+ modify insn. There are no insns where an explicit reloc
specifier makes sense. */
if (cris_get_expression (&s, &out_insnp->expr))
{
relocation. */
out_insnp->expr.X_add_number += 6;
- if (pic && *s == PIC_SUFFIX_CHAR)
- cris_get_pic_suffix (&s, &out_insnp->reloc,
- &out_insnp->expr);
+ /* TLS specifiers do not make sense here. */
+ if (pic && *s == RELOC_SUFFIX_CHAR)
+ cris_get_reloc_suffix (&s, &out_insnp->reloc,
+ &out_insnp->expr);
continue;
}
if (out_insnp->expr.X_op == O_constant
&& (out_insnp->expr.X_add_number < -128
|| out_insnp->expr.X_add_number > 255))
- as_bad (_("Immediate value not in 8 bit range: %ld"),
- out_insnp->expr.X_add_number);
+ cris_bad (_("Immediate value not in 8 bit range: %ld"),
+ &out_insnp->expr.X_add_number);
/* Fall through. */
case 2:
/* FIXME: We need an indicator in the instruction
if (out_insnp->expr.X_op == O_constant
&& (out_insnp->expr.X_add_number < -32768
|| out_insnp->expr.X_add_number > 65535))
- as_bad (_("Immediate value not in 16 bit range: %ld"),
- out_insnp->expr.X_add_number);
+ cris_bad (_("Immediate value not in 16 bit range: %ld"),
+ &out_insnp->expr.X_add_number);
out_insnp->imm_oprnd_size = 2;
break;
if (instruction->imm_oprnd_size == SIZE_FIELD
&& (out_insnp->expr.X_add_number < -128
|| out_insnp->expr.X_add_number > 255))
- as_bad (_("Immediate value not in 8 bit range: %ld"),
- out_insnp->expr.X_add_number);
+ cris_bad (_("Immediate value not in 8 bit range: %ld"),
+ &out_insnp->expr.X_add_number);
else if (instruction->imm_oprnd_size == SIZE_FIELD_SIGNED
&& (out_insnp->expr.X_add_number < -128
|| out_insnp->expr.X_add_number > 127))
- as_bad (_("Immediate value not in 8 bit signed range: %ld"),
- out_insnp->expr.X_add_number);
+ cris_bad (_("Immediate value not in 8 bit signed range: %ld"),
+ &out_insnp->expr.X_add_number);
else if (instruction->imm_oprnd_size == SIZE_FIELD_UNSIGNED
&& (out_insnp->expr.X_add_number < 0
|| out_insnp->expr.X_add_number > 255))
- as_bad (_("Immediate value not in 8 bit unsigned range: %ld"),
- out_insnp->expr.X_add_number);
+ cris_bad (_("Immediate value not in 8 bit unsigned range: %ld"),
+ &out_insnp->expr.X_add_number);
}
/* Fall through. */
if (instruction->imm_oprnd_size == SIZE_FIELD
&& (out_insnp->expr.X_add_number < -32768
|| out_insnp->expr.X_add_number > 65535))
- as_bad (_("Immediate value not in 16 bit range: %ld"),
- out_insnp->expr.X_add_number);
+ cris_bad (_("Immediate value not in 16 bit range: %ld"),
+ &out_insnp->expr.X_add_number);
else if (instruction->imm_oprnd_size == SIZE_FIELD_SIGNED
&& (out_insnp->expr.X_add_number < -32768
|| out_insnp->expr.X_add_number > 32767))
- as_bad (_("Immediate value not in 16 bit signed range: %ld"),
- out_insnp->expr.X_add_number);
+ cris_bad (_("Immediate value not in 16 bit signed range: %ld"),
+ &out_insnp->expr.X_add_number);
else if (instruction->imm_oprnd_size == SIZE_FIELD_UNSIGNED
&& (out_insnp->expr.X_add_number < 0
|| out_insnp->expr.X_add_number > 65535))
- as_bad (_("Immediate value not in 16 bit unsigned range: %ld"),
- out_insnp->expr.X_add_number);
+ cris_bad (_("Immediate value not in 16 bit unsigned range: %ld"),
+ &out_insnp->expr.X_add_number);
}
out_insnp->imm_oprnd_size = 2;
break;
}
/* If there was a relocation specified for the immediate
- expression (i.e. it had a PIC modifier) check that the
- size of the PIC relocation matches the size specified by
+ expression (i.e. it had a PIC or TLS modifier) check that the
+ size of the relocation matches the size specified by
the opcode. */
if (out_insnp->reloc != BFD_RELOC_NONE
- && (cris_get_pic_reloc_size (out_insnp->reloc)
+ && (cris_get_specified_reloc_size (out_insnp->reloc)
!= (unsigned int) out_insnp->imm_oprnd_size))
- as_bad (_("PIC relocation size does not match operand size"));
+ as_bad (out_insnp->reloc == BFD_RELOC_CRIS_32_GD
+ || out_insnp->reloc == BFD_RELOC_CRIS_32_TPREL
+ || out_insnp->reloc == BFD_RELOC_CRIS_16_TPREL
+ || out_insnp->reloc == BFD_RELOC_CRIS_32_IE
+ ? _("TLS relocation size does not match operand size")
+ : _("PIC relocation size does not match operand size"));
}
else if (instruction->op == cris_muls_op
|| instruction->op == cris_mulu_op)
/* We tentatively put an opcode corresponding to
a 32-bit operand here, although it may be
- relaxed when there's no PIC specifier for the
- operand. */
+ relaxed when there's no relocation
+ specifier for the operand. */
prefixp->opcode
= (BDAP_INDIR_OPCODE
| (prefixp->base_reg_number << 12)
/* This can have a PIC suffix, specifying reloc
type to use. */
- if (pic && **cPP == PIC_SUFFIX_CHAR)
+ if ((pic || tls) && **cPP == RELOC_SUFFIX_CHAR)
{
unsigned int relocsize;
- cris_get_pic_suffix (cPP, &prefixp->reloc,
- &prefixp->expr);
+ cris_get_reloc_suffix (cPP, &prefixp->reloc,
+ &prefixp->expr);
/* Tweak the size of the immediate operand
in the prefix opcode if it isn't what we
set. */
relocsize
- = cris_get_pic_reloc_size (prefixp->reloc);
+ = cris_get_specified_reloc_size (prefixp->reloc);
if (relocsize != 4)
prefixp->opcode
= ((prefixp->opcode & ~(3 << 4))
in the blanks and break out to match the
final ']'.
- Note that we don't allow a PIC suffix for an
- operand with a minus sign. */
+ Note that we don't allow a relocation
+ suffix for an operand with a minus
+ sign. */
prefixp->kind = PREFIX_BDAP_IMM;
break;
}
/* This can have a PIC suffix, specifying reloc type to use. The
caller must check that the reloc size matches the operand size. */
- if (pic && **cPP == PIC_SUFFIX_CHAR)
- cris_get_pic_suffix (cPP, &prefixp->reloc, imm_exprP);
+ if ((pic || tls) && **cPP == RELOC_SUFFIX_CHAR)
+ cris_get_reloc_suffix (cPP, &prefixp->reloc, imm_exprP);
return 1;
}
| REG_PC /* << 0 */);
/* This can have a PIC suffix, specifying reloc type to use. */
- if (pic && **cPP == PIC_SUFFIX_CHAR)
+ if ((pic || tls) && **cPP == RELOC_SUFFIX_CHAR)
{
unsigned int relocsize;
- cris_get_pic_suffix (cPP, &prefixp->reloc, &prefixp->expr);
+ cris_get_reloc_suffix (cPP, &prefixp->reloc, &prefixp->expr);
/* Tweak the size of the immediate operand in the prefix
opcode if it isn't what we set. */
- relocsize = cris_get_pic_reloc_size (prefixp->reloc);
+ relocsize = cris_get_specified_reloc_size (prefixp->reloc);
if (relocsize != 4)
prefixp->opcode
= ((prefixp->opcode & ~(3 << 4))
prefixp->kind = PREFIX_DIP;
prefixp->opcode = DIP_OPCODE | (AUTOINCR_BIT << 8) | REG_PC;
prefixp->reloc = BFD_RELOC_32;
+
+ /* For :GD and :IE, it makes sense to have TLS specifiers here. */
+ if ((pic || tls) && **cPP == RELOC_SUFFIX_CHAR)
+ cris_get_reloc_suffix (cPP, &prefixp->reloc, &prefixp->expr);
}
else
/* Neither '[' nor register nor expression. We lose. */
cris_get_expression (char **cPP, expressionS *exprP)
{
char *saved_input_line_pointer;
- segT exp;
/* The "expression" function expects to find an expression at the
global variable input_line_pointer, so we have to save it to give
return 0;
}
- exp = expression (exprP);
+ expression (exprP);
if (exprP->X_op == O_illegal || exprP->X_op == O_absent)
{
input_line_pointer = saved_input_line_pointer;
md_number_to_chars (writep + 8, MOVE_PC_INCR_OPCODE_SUFFIX, 2);
}
-/* Get the size of an immediate-reloc in bytes. Only valid for PIC
- relocs. */
+/* Get the size of an immediate-reloc in bytes. Only valid for
+ specified relocs (TLS, PIC). */
static unsigned int
-cris_get_pic_reloc_size (bfd_reloc_code_real_type reloc)
+cris_get_specified_reloc_size (bfd_reloc_code_real_type reloc)
{
- return reloc == BFD_RELOC_CRIS_16_GOTPLT || reloc == BFD_RELOC_CRIS_16_GOT
+ return
+ reloc == BFD_RELOC_CRIS_16_GOTPLT
+ || reloc == BFD_RELOC_CRIS_16_GOT
+ || reloc == BFD_RELOC_CRIS_16_GOT_GD
+ || reloc == BFD_RELOC_CRIS_16_DTPREL
+ || reloc == BFD_RELOC_CRIS_16_GOT_TPREL
+ || reloc == BFD_RELOC_CRIS_16_TPREL
? 2 : 4;
}
Adjust *EXPRP with any addend found after the PIC suffix. */
static void
-cris_get_pic_suffix (char **cPP, bfd_reloc_code_real_type *relocp,
- expressionS *exprP)
+cris_get_reloc_suffix (char **cPP, bfd_reloc_code_real_type *relocp,
+ expressionS *exprP)
{
char *s = *cPP;
unsigned int i;
const char *const suffix;
unsigned int len;
bfd_reloc_code_real_type reloc;
+ bfd_boolean pic_p;
+ bfd_boolean tls_p;
} pic_suffixes[] =
{
#undef PICMAP
-#define PICMAP(s, r) {s, sizeof (s) - 1, r}
+#define PICMAP(s, r) {s, sizeof (s) - 1, r, TRUE, FALSE}
+#define PICTLSMAP(s, r) {s, sizeof (s) - 1, r, TRUE, TRUE}
+#define TLSMAP(s, r) {s, sizeof (s) - 1, r, FALSE, TRUE}
/* Keep this in order with longest unambiguous prefix first. */
PICMAP ("GOTPLT16", BFD_RELOC_CRIS_16_GOTPLT),
PICMAP ("GOTPLT", BFD_RELOC_CRIS_32_GOTPLT),
PICMAP ("PLT", BFD_RELOC_CRIS_32_PLT_PCREL),
PICMAP ("GOTOFF", BFD_RELOC_CRIS_32_GOTREL),
PICMAP ("GOT16", BFD_RELOC_CRIS_16_GOT),
- PICMAP ("GOT", BFD_RELOC_CRIS_32_GOT)
+ PICMAP ("GOT", BFD_RELOC_CRIS_32_GOT),
+ PICTLSMAP ("GDGOTREL16", BFD_RELOC_CRIS_16_GOT_GD),
+ PICTLSMAP ("GDGOTREL", BFD_RELOC_CRIS_32_GOT_GD),
+ TLSMAP ("GD", BFD_RELOC_CRIS_32_GD),
+ PICTLSMAP ("DTPREL16", BFD_RELOC_CRIS_16_DTPREL),
+ PICTLSMAP ("DTPREL", BFD_RELOC_CRIS_32_DTPREL),
+ TLSMAP ("IE", BFD_RELOC_CRIS_32_IE),
+ PICTLSMAP ("TPOFFGOT16", BFD_RELOC_CRIS_16_GOT_TPREL),
+ PICTLSMAP ("TPOFFGOT", BFD_RELOC_CRIS_32_GOT_TPREL),
+ TLSMAP ("TPOFF16", BFD_RELOC_CRIS_16_TPREL),
+ TLSMAP ("TPOFF", BFD_RELOC_CRIS_32_TPREL)
};
/* We've already seen the ':', so consume it. */
for (i = 0; i < sizeof (pic_suffixes)/sizeof (pic_suffixes[0]); i++)
{
if (strncmp (s, pic_suffixes[i].suffix, pic_suffixes[i].len) == 0
- && ! is_part_of_name (s[pic_suffixes[i].len]))
+ && ! is_part_of_name (s[pic_suffixes[i].len])
+ /* PIC and non-PIC relocations are exclusive. */
+ && (pic != 0) == (pic_suffixes[i].pic_p != 0)
+ /* But TLS can be active for non-TLS relocations too. */
+ && (pic_suffixes[i].tls_p == 0 || tls))
{
/* We have a match. Consume the suffix and set the relocation
type. */
;
}
- /* Only do this for old-arch binaries. */
+ /* Only use the computed value for old-arch binaries. For all
+ others, where we're going to output a relocation, put 0 in the
+ code. */
if (cris_arch != arch_cris_any_v0_v10
&& (fixP->fx_addsy != NULL || fixP->fx_pcrel))
- return;
+ val = 0;
switch (fixP->fx_r_type)
{
regression tests on the object file contents. FIXME: Seems
uninteresting now that we have a test suite. */
+ case BFD_RELOC_CRIS_32_GOT_GD:
+ case BFD_RELOC_CRIS_16_GOT_GD:
+ case BFD_RELOC_CRIS_32_GD:
+ case BFD_RELOC_CRIS_32_IE:
+ case BFD_RELOC_CRIS_32_DTPREL:
+ case BFD_RELOC_CRIS_16_DTPREL:
+ case BFD_RELOC_CRIS_32_GOT_TPREL:
+ case BFD_RELOC_CRIS_16_GOT_TPREL:
+ case BFD_RELOC_CRIS_32_TPREL:
+ case BFD_RELOC_CRIS_16_TPREL:
+#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
+ if (IS_ELF && fixP->fx_addsy != NULL)
+ S_SET_THREAD_LOCAL (fixP->fx_addsy);
+#endif
+ /* Fall through. */
+
case BFD_RELOC_CRIS_16_GOT:
case BFD_RELOC_CRIS_32_GOT:
case BFD_RELOC_CRIS_32_GOTREL:
case BFD_RELOC_CRIS_32_PLT_PCREL:
/* We don't want to put in any kind of non-zero bits in the data
being relocated for these. */
+ md_number_to_chars (bufp, 0, n);
break;
case BFD_RELOC_32_PCREL:
- /* If this one isn't fully resolved, we don't want to put anything
+ /* If this one isn't fully resolved, we don't want to put non-zero
in the object. */
if (fixP->fx_addsy != NULL || fixP->fx_pcrel)
- break;
+ val = 0;
/* Fall through. */
case BFD_RELOC_32:
if (val > 0xffff || val < -32768)
as_bad_where (fixP->fx_file, fixP->fx_line,
_("Value not in 16 bit range: %ld"), val);
- if (! fixP->fx_addsy)
- {
- bufp[1] = (val >> 8) & 0xFF;
- bufp[0] = val & 0xFF;
- }
+ bufp[1] = (val >> 8) & 0xFF;
+ bufp[0] = val & 0xFF;
break;
case BFD_RELOC_CRIS_SIGNED_16:
if (val > 32767 || val < -32768)
as_bad_where (fixP->fx_file, fixP->fx_line,
_("Value not in 16 bit signed range: %ld"), val);
- if (! fixP->fx_addsy)
- {
- bufp[1] = (val >> 8) & 0xFF;
- bufp[0] = val & 0xFF;
- }
+ bufp[1] = (val >> 8) & 0xFF;
+ bufp[0] = val & 0xFF;
break;
case BFD_RELOC_8:
case BFD_RELOC_8_PCREL:
if (val > 255 || val < -128)
as_bad_where (fixP->fx_file, fixP->fx_line, _("Value not in 8 bit range: %ld"), val);
- if (! fixP->fx_addsy)
- bufp[0] = val & 0xFF;
+ bufp[0] = val & 0xFF;
break;
case BFD_RELOC_CRIS_SIGNED_8:
if (val > 127 || val < -128)
as_bad_where (fixP->fx_file, fixP->fx_line,
_("Value not in 8 bit signed range: %ld"), val);
- if (! fixP->fx_addsy)
- bufp[0] = val & 0xFF;
+ bufp[0] = val & 0xFF;
break;
case BFD_RELOC_CRIS_LAPCQ_OFFSET:
if (val > 15 || val < 0)
as_bad_where (fixP->fx_file, fixP->fx_line,
_("Value not in 4 bit unsigned range: %ld"), val);
- if (! fixP->fx_addsy)
- bufp[0] |= val & 0x0F;
+ bufp[0] |= val & 0x0F;
break;
case BFD_RELOC_CRIS_UNSIGNED_5:
if (val > 31 || val < 0)
as_bad_where (fixP->fx_file, fixP->fx_line,
_("Value not in 5 bit unsigned range: %ld"), val);
- if (! fixP->fx_addsy)
- bufp[0] |= val & 0x1F;
+ bufp[0] |= val & 0x1F;
break;
case BFD_RELOC_CRIS_SIGNED_6:
if (val > 31 || val < -32)
as_bad_where (fixP->fx_file, fixP->fx_line,
_("Value not in 6 bit range: %ld"), val);
- if (! fixP->fx_addsy)
- bufp[0] |= val & 0x3F;
+ bufp[0] |= val & 0x3F;
break;
case BFD_RELOC_CRIS_UNSIGNED_6:
if (val > 63 || val < 0)
as_bad_where (fixP->fx_file, fixP->fx_line,
_("Value not in 6 bit unsigned range: %ld"), val);
- if (! fixP->fx_addsy)
- bufp[0] |= val & 0x3F;
+ bufp[0] |= val & 0x3F;
break;
case BFD_RELOC_CRIS_BDISP8:
- if (! fixP->fx_addsy)
- bufp[0] = branch_disp (val);
+ bufp[0] = branch_disp (val);
break;
case BFD_RELOC_NONE:
break;
case OPTION_PIC:
+ if (OUTPUT_FLAVOR != bfd_target_elf_flavour)
+ as_bad (_("--pic is invalid for this object format"));
pic = TRUE;
if (cris_arch != arch_crisv32)
md_long_jump_size = cris_any_v0_v10_long_jump_size_pic;
case BFD_RELOC_CRIS_UNSIGNED_8:
case BFD_RELOC_CRIS_UNSIGNED_16:
case BFD_RELOC_CRIS_LAPCQ_OFFSET:
+ case BFD_RELOC_CRIS_32_GOT_GD:
+ case BFD_RELOC_CRIS_16_GOT_GD:
+ case BFD_RELOC_CRIS_32_GD:
+ case BFD_RELOC_CRIS_32_IE:
+ case BFD_RELOC_CRIS_32_DTPREL:
+ case BFD_RELOC_CRIS_16_DTPREL:
+ case BFD_RELOC_CRIS_32_GOT_TPREL:
+ case BFD_RELOC_CRIS_16_GOT_TPREL:
+ case BFD_RELOC_CRIS_32_TPREL:
+ case BFD_RELOC_CRIS_16_TPREL:
code = fixP->fx_r_type;
break;
default:
}
relP = (arelent *) xmalloc (sizeof (arelent));
- assert (relP != 0);
+ gas_assert (relP != 0);
relP->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
*relP->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
relP->address = fixP->fx_frag->fr_address + fixP->fx_where;
_(" --no-underscore User symbols do not have any prefix.\n"));
fprintf (stream, "%s",
_(" Registers will require a `$'-prefix.\n"));
+#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
fprintf (stream, "%s",
_(" --pic Enable generation of position-independent code.\n"));
+#endif
fprintf (stream, "%s",
_(" --march=<arch> Generate code for <arch>. Valid choices for <arch>\n\
are v0_v10, v10, v32 and common_v10_v32.\n"));
dwarf2_directive_loc (dummy);
}
+/* Worker for .dtpoffd: generate a R_CRIS_32_DTPREL reloc, as for
+ expr:DTPREL but for use in debug info. */
+
+static void
+s_cris_dtpoff (int bytes)
+{
+ expressionS ex;
+ char *p;
+
+ if (bytes != 4)
+ as_fatal (_("internal inconsistency problem: %s called for %d bytes"),
+ __FUNCTION__, bytes);
+
+ expression (&ex);
+
+ p = frag_more (bytes);
+ md_number_to_chars (p, 0, bytes);
+ fix_new_exp (frag_now, p - frag_now->fr_literal, bytes, &ex, FALSE,
+ BFD_RELOC_CRIS_32_DTPREL);
+
+ demand_empty_rest_of_line ();
+}
+
+
/* Translate a <arch> string (as common to --march=<arch> and .arch <arch>)
into an enum. If the string *STR is recognized, *STR is updated to point
to the end of the string. If the string is not recognized,