arc/nps400 : New cmem instructions and associated relocation

Add support for arc/nps400 cmem instructions, these load and store
instructions are hard-wired to access "0x57f00000 + 16-bit-offset".

Supporting this relocation required some additions to the arc relocation
handling in the bfd library, as well as the standard changes required to
add a new relocation type.

There's a test of the new instructions in the assembler, and a test of
the relocation in the linker.

bfd/ChangeLog:

	* reloc.c: Add BFD_RELOC_ARC_NPS_CMEM16 entry.
	* bfd-in2.h: Regenerate.
	* libbfd.h: Regenerate.
	* elf32-arc.c: Add 'opcode/arc.h' include.
	(struct arc_relocation_data): Add symbol_name.
	(arc_special_overflow_checks): New function.
	(arc_do_relocation): Use arc_special_overflow_checks, reindent as
	required, add an extra comment.
	(elf_arc_relocate_section): Setup symbol_name in reloc_data.

gas/ChangeLog:

	* testsuite/gas/arc/nps400-3.d: New file.
	* testsuite/gas/arc/nps400-3.s: New file.

include/ChangeLog:

	* elf/arc-reloc.def: Add ARC_NPS_CMEM16 reloc.
	* opcode/arc.h (NPS_CMEM_HIGH_VALUE): Define.

ld/ChangeLog:

	* testsuite/ld-arc/arc.exp: New file.
	* testsuite/ld-arc/nps-1.s: New file.
	* testsuite/ld-arc/nps-1a.d: New file.
	* testsuite/ld-arc/nps-1b.d: New file.
	* testsuite/ld-arc/nps-1b.err: New file.

opcodes/ChangeLog:

	* arc-nps400-tbl.h: Add xldb, xldw, xld, xstb, xstw, and xst
	instructions.
	* arc-opc.c (insert_nps_cmem_uimm16): New function.
	(extract_nps_cmem_uimm16): New function.
	(arc_operands): Add NPS_XLDST_UIMM16 operand.
This commit is contained in:
Andrew Burgess
2016-03-30 00:02:19 +01:00
parent 33cbe6c07e
commit 4b0c052e45
20 changed files with 300 additions and 19 deletions

View File

@ -1,3 +1,15 @@
2016-04-14 Andrew Burgess <andrew.burgess@embecosm.com>
* reloc.c: Add BFD_RELOC_ARC_NPS_CMEM16 entry.
* bfd-in2.h: Regenerate.
* libbfd.h: Regenerate.
* elf32-arc.c: Add 'opcode/arc.h' include.
(struct arc_relocation_data): Add symbol_name.
(arc_special_overflow_checks): New function.
(arc_do_relocation): Use arc_special_overflow_checks, reindent as
required, add an extra comment.
(elf_arc_relocate_section): Setup symbol_name in reloc_data.
2016-04-14 Andrew Burgess <andrew.burgess@embecosm.com> 2016-04-14 Andrew Burgess <andrew.burgess@embecosm.com>
* elf32-arc.c (tls_got_entries): Add 'TLS_GOT_' prefix to all * elf32-arc.c (tls_got_entries): Add 'TLS_GOT_' prefix to all

View File

@ -3721,6 +3721,7 @@ pc-relative or some form of GOT-indirect relocation. */
BFD_RELOC_ARC_TLS_LE_32, BFD_RELOC_ARC_TLS_LE_32,
BFD_RELOC_ARC_S25W_PCREL_PLT, BFD_RELOC_ARC_S25W_PCREL_PLT,
BFD_RELOC_ARC_S21H_PCREL_PLT, BFD_RELOC_ARC_S21H_PCREL_PLT,
BFD_RELOC_ARC_NPS_CMEM16,
/* ADI Blackfin 16 bit immediate absolute reloc. */ /* ADI Blackfin 16 bit immediate absolute reloc. */
BFD_RELOC_BFIN_16_IMM, BFD_RELOC_BFIN_16_IMM,

View File

@ -26,6 +26,7 @@
#include "elf/arc.h" #include "elf/arc.h"
#include "libiberty.h" #include "libiberty.h"
#include "opcode/arc-func.h" #include "opcode/arc-func.h"
#include "opcode/arc.h"
#include "arc-plt.h" #include "arc-plt.h"
#ifdef DEBUG #ifdef DEBUG
@ -722,6 +723,8 @@ struct arc_relocation_data
bfd_signed_vma got_symbol_vma; bfd_signed_vma got_symbol_vma;
bfd_boolean should_relocate; bfd_boolean should_relocate;
const char * symbol_name;
}; };
static void static void
@ -788,6 +791,52 @@ middle_endian_convert (bfd_vma insn, bfd_boolean do_it)
return insn; return insn;
} }
/* This function is called for relocations that are otherwise marked as NOT
requiring overflow checks. In here we perform non-standard checks of
the relocation value. */
static inline bfd_reloc_status_type
arc_special_overflow_checks (const struct arc_relocation_data reloc_data,
bfd_signed_vma relocation,
struct bfd_link_info *info ATTRIBUTE_UNUSED)
{
switch (reloc_data.howto->type)
{
case R_ARC_NPS_CMEM16:
if (((relocation >> 16) & 0xffff) != NPS_CMEM_HIGH_VALUE)
{
if (reloc_data.reloc_addend == 0)
(*_bfd_error_handler)
(_("%B(%A+0x%lx): CMEM relocation to `%s' is invalid, "
"16 MSB should be 0x%04x (value is 0x%lx)"),
reloc_data.input_section->owner,
reloc_data.input_section,
reloc_data.reloc_offset,
reloc_data.symbol_name,
NPS_CMEM_HIGH_VALUE,
(relocation));
else
(*_bfd_error_handler)
(_("%B(%A+0x%lx): CMEM relocation to `%s+0x%lx' is invalid, "
"16 MSB should be 0x%04x (value is 0x%lx)"),
reloc_data.input_section->owner,
reloc_data.input_section,
reloc_data.reloc_offset,
reloc_data.symbol_name,
reloc_data.reloc_addend,
NPS_CMEM_HIGH_VALUE,
(relocation));
return bfd_reloc_overflow;
}
break;
default:
break;
}
return bfd_reloc_ok;
}
#define ME(reloc) (reloc) #define ME(reloc) (reloc)
#define IS_ME(FORMULA,BFD) ((strstr (FORMULA, "ME") != NULL) \ #define IS_ME(FORMULA,BFD) ((strstr (FORMULA, "ME") != NULL) \
@ -896,6 +945,7 @@ arc_do_relocation (bfd_byte * contents,
bfd_vma orig_insn ATTRIBUTE_UNUSED; bfd_vma orig_insn ATTRIBUTE_UNUSED;
bfd * abfd = reloc_data.input_section->owner; bfd * abfd = reloc_data.input_section->owner;
struct elf_link_hash_table *htab ATTRIBUTE_UNUSED = elf_hash_table (info); struct elf_link_hash_table *htab ATTRIBUTE_UNUSED = elf_hash_table (info);
bfd_reloc_status_type flag;
if (reloc_data.should_relocate == FALSE) if (reloc_data.should_relocate == FALSE)
return bfd_reloc_ok; return bfd_reloc_ok;
@ -936,13 +986,13 @@ arc_do_relocation (bfd_byte * contents,
/* Check for relocation overflow. */ /* Check for relocation overflow. */
if (reloc_data.howto->complain_on_overflow != complain_overflow_dont) if (reloc_data.howto->complain_on_overflow != complain_overflow_dont)
{
bfd_reloc_status_type flag;
flag = bfd_check_overflow (reloc_data.howto->complain_on_overflow, flag = bfd_check_overflow (reloc_data.howto->complain_on_overflow,
reloc_data.howto->bitsize, reloc_data.howto->bitsize,
reloc_data.howto->rightshift, reloc_data.howto->rightshift,
bfd_arch_bits_per_address (abfd), bfd_arch_bits_per_address (abfd),
relocation); relocation);
else
flag = arc_special_overflow_checks (reloc_data, relocation, info);
#undef DEBUG_ARC_RELOC #undef DEBUG_ARC_RELOC
#define DEBUG_ARC_RELOC(A) debug_arc_reloc (A) #define DEBUG_ARC_RELOC(A) debug_arc_reloc (A)
@ -960,10 +1010,10 @@ arc_do_relocation (bfd_byte * contents,
(unsigned int) relocation); (unsigned int) relocation);
return flag; return flag;
} }
}
#undef DEBUG_ARC_RELOC #undef DEBUG_ARC_RELOC
#define DEBUG_ARC_RELOC(A) #define DEBUG_ARC_RELOC(A)
/* Write updated instruction back to memory. */
switch (reloc_data.howto->size) switch (reloc_data.howto->size)
{ {
case 2: case 2:
@ -1168,6 +1218,10 @@ elf_arc_relocate_section (bfd * output_bfd,
reloc_data.sym_value = sym->st_value; reloc_data.sym_value = sym->st_value;
reloc_data.sym_section = sec; reloc_data.sym_section = sec;
reloc_data.symbol_name =
bfd_elf_string_from_elf_section (input_bfd,
symtab_hdr->sh_link,
sym->st_name);
/* Mergeable section handling. */ /* Mergeable section handling. */
if ((sec->flags & SEC_MERGE) if ((sec->flags & SEC_MERGE)
@ -1284,6 +1338,7 @@ elf_arc_relocate_section (bfd * output_bfd,
h = (struct elf_link_hash_entry *) h->root.u.i.link; h = (struct elf_link_hash_entry *) h->root.u.i.link;
BFD_ASSERT ((h->dynindx == -1) >= (h->forced_local != 0)); BFD_ASSERT ((h->dynindx == -1) >= (h->forced_local != 0));
reloc_data.symbol_name = h->root.root.string;
/* If we have encountered a definition for this symbol. */ /* If we have encountered a definition for this symbol. */
if (h->root.type == bfd_link_hash_defined if (h->root.type == bfd_link_hash_defined
|| h->root.type == bfd_link_hash_defweak) || h->root.type == bfd_link_hash_defweak)

View File

@ -1738,6 +1738,7 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
"BFD_RELOC_ARC_TLS_LE_32", "BFD_RELOC_ARC_TLS_LE_32",
"BFD_RELOC_ARC_S25W_PCREL_PLT", "BFD_RELOC_ARC_S25W_PCREL_PLT",
"BFD_RELOC_ARC_S21H_PCREL_PLT", "BFD_RELOC_ARC_S21H_PCREL_PLT",
"BFD_RELOC_ARC_NPS_CMEM16",
"BFD_RELOC_BFIN_16_IMM", "BFD_RELOC_BFIN_16_IMM",
"BFD_RELOC_BFIN_16_HIGH", "BFD_RELOC_BFIN_16_HIGH",
"BFD_RELOC_BFIN_4_PCREL", "BFD_RELOC_BFIN_4_PCREL",

View File

@ -3668,6 +3668,8 @@ ENUMX
BFD_RELOC_ARC_S25W_PCREL_PLT BFD_RELOC_ARC_S25W_PCREL_PLT
ENUMX ENUMX
BFD_RELOC_ARC_S21H_PCREL_PLT BFD_RELOC_ARC_S21H_PCREL_PLT
ENUMX
BFD_RELOC_ARC_NPS_CMEM16
ENUMDOC ENUMDOC
ARC relocs. ARC relocs.

View File

@ -1,3 +1,8 @@
2016-04-14 Andrew Burgess <andrew.burgess@embecosm.com>
* testsuite/gas/arc/nps400-3.d: New file.
* testsuite/gas/arc/nps400-3.s: New file.
2016-04-14 Andrew Burgess <andrew.burgess@embecosm.com> 2016-04-14 Andrew Burgess <andrew.burgess@embecosm.com>
* testsuite/gas/arc/add_s-err.s: Update target pattern. * testsuite/gas/arc/add_s-err.s: Update target pattern.

View File

@ -0,0 +1,56 @@
#as: -mcpu=nps400
#objdump: -dr
.*: +file format .*arc.*
Disassembly of section .text:
[0-9a-f]+ <.*>:
0: 5988 0000 xldb r12,\[0x57f00000\]
4: 5ae8 ffff xldb r23,\[0x57f0ffff\]
8: 5868 0000 xldb r3,\[0x57f00000\]
c: 5968 ffff xldb r11,\[0x57f0ffff\]
10: 5a88 0000 xldb r20,\[0x57f00000\]
10: R_ARC_NPS_CMEM16 foo
14: 5828 0000 xldb r1,\[0x57f00000\]
14: R_ARC_NPS_CMEM16 foo\+0x20
18: 5989 0000 xldw r12,\[0x57f00000\]
1c: 5ae9 ffff xldw r23,\[0x57f0ffff\]
20: 5869 0000 xldw r3,\[0x57f00000\]
24: 5969 ffff xldw r11,\[0x57f0ffff\]
28: 5a89 0000 xldw r20,\[0x57f00000\]
28: R_ARC_NPS_CMEM16 foo
2c: 5829 0000 xldw r1,\[0x57f00000\]
2c: R_ARC_NPS_CMEM16 foo\+0x20
30: 598a 0000 xld r12,\[0x57f00000\]
34: 5aea ffff xld r23,\[0x57f0ffff\]
38: 586a 0000 xld r3,\[0x57f00000\]
3c: 596a ffff xld r11,\[0x57f0ffff\]
40: 5a8a 0000 xld r20,\[0x57f00000\]
40: R_ARC_NPS_CMEM16 foo
44: 582a 0000 xld r1,\[0x57f00000\]
44: R_ARC_NPS_CMEM16 foo\+0x20
48: 598c 0000 xstb r12,\[0x57f00000\]
4c: 5aec ffff xstb r23,\[0x57f0ffff\]
50: 586c 0000 xstb r3,\[0x57f00000\]
54: 596c ffff xstb r11,\[0x57f0ffff\]
58: 5a8c 0000 xstb r20,\[0x57f00000\]
58: R_ARC_NPS_CMEM16 foo
5c: 582c 0000 xstb r1,\[0x57f00000\]
5c: R_ARC_NPS_CMEM16 foo\+0x20
60: 598d 0000 xstw r12,\[0x57f00000\]
64: 5aed ffff xstw r23,\[0x57f0ffff\]
68: 586d 0000 xstw r3,\[0x57f00000\]
6c: 596d ffff xstw r11,\[0x57f0ffff\]
70: 5a8d 0000 xstw r20,\[0x57f00000\]
70: R_ARC_NPS_CMEM16 foo
74: 582d 0000 xstw r1,\[0x57f00000\]
74: R_ARC_NPS_CMEM16 foo\+0x20
78: 598e 0000 xst r12,\[0x57f00000\]
7c: 5aee ffff xst r23,\[0x57f0ffff\]
80: 586e 0000 xst r3,\[0x57f00000\]
84: 596e ffff xst r11,\[0x57f0ffff\]
88: 5a8e 0000 xst r20,\[0x57f00000\]
88: R_ARC_NPS_CMEM16 foo
8c: 582e 0000 xst r1,\[0x57f00000\]
8c: R_ARC_NPS_CMEM16 foo\+0x20

View File

@ -0,0 +1,23 @@
.macro xldst_test mnem
\mnem r12, [ 0x0 ]
\mnem r23, [ 0xffff ]
\mnem r3, [ 0x57f00000 ]
\mnem r11, [ 0x57f0ffff ]
\mnem r20, [ foo ]
\mnem r1, [ foo + 0x20 ]
.endm
.text
;; xldb
xldst_test xldb
;; xldw
xldst_test xldw
;; xld
xldst_test xld
;; xstb
xldst_test xstb
;; xstw
xldst_test xstw
;; xst
xldst_test xst

View File

@ -1,3 +1,8 @@
2016-04-14 Andrew Burgess <andrew.burgess@embecosm.com>
* elf/arc-reloc.def: Add ARC_NPS_CMEM16 reloc.
* opcode/arc.h (NPS_CMEM_HIGH_VALUE): Define.
2016-04-12 Claudiu Zissulescu <claziss@synopsys.com> 2016-04-12 Claudiu Zissulescu <claziss@synopsys.com>
* opcode/arc.h (flag_class_t): Update. * opcode/arc.h (flag_class_t): Update.

View File

@ -490,3 +490,10 @@ ARC_RELOC_HOWTO(ARC_S21H_PCREL_PLT, 77, \
replace_disp21h, \ replace_disp21h, \
signed, \ signed, \
( ME ( ( ( ( L + A ) - P ) >> 1 ) ) )) ( ME ( ( ( ( L + A ) - P ) >> 1 ) ) ))
ARC_RELOC_HOWTO(ARC_NPS_CMEM16, 78, \
2, \
16, \
replace_bits16, \
dont, \
( S + A ))

View File

@ -437,6 +437,9 @@ extern const unsigned arc_num_aux_regs;
extern const struct arc_opcode arc_relax_opcodes[]; extern const struct arc_opcode arc_relax_opcodes[];
extern const unsigned arc_num_relax_opcodes; extern const unsigned arc_num_relax_opcodes;
/* Macro used for generating one class of NPS instructions. */
#define NPS_CMEM_HIGH_VALUE 0x57f0
/* Macros to help generating regular pattern instructions. */ /* Macros to help generating regular pattern instructions. */
#define FIELDA(word) (word & 0x3F) #define FIELDA(word) (word & 0x3F)
#define FIELDB(word) (((word & 0x07) << 24) | (((word >> 3) & 0x07) << 12)) #define FIELDB(word) (((word & 0x07) << 24) | (((word >> 3) & 0x07) << 12))

View File

@ -1,3 +1,11 @@
2016-04-14 Andrew Burgess <andrew.burgess@embecosm.com>
* testsuite/ld-arc/arc.exp: New file.
* testsuite/ld-arc/nps-1.s: New file.
* testsuite/ld-arc/nps-1a.d: New file.
* testsuite/ld-arc/nps-1b.d: New file.
* testsuite/ld-arc/nps-1b.err: New file.
2016-04-14 Nick Clifton <nickc@redhat.com> 2016-04-14 Nick Clifton <nickc@redhat.com>
PR 19457 PR 19457

View File

@ -0,0 +1,30 @@
# Copyright (C) 2016 Free Software Foundation, Inc.
#
# This file is part of the GNU Binutils.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
# MA 02110-1301, USA.
#
if { ![istarget arc*-*-*] } {
return
}
set arc_test_list [lsort [glob -nocomplain $srcdir/$subdir/*.d]]
foreach arc_test $arc_test_list {
verbose [file rootname $arc_test]
run_dump_test [file rootname $arc_test]
}

View File

@ -0,0 +1,10 @@
.text
.global __start
__start:
xldb r10, [ foo ]
xldw r10, [ foo ]
xld r10, [ foo ]
xstb r10, [ foo ]
xstw r10, [ foo ]
xst r10, [ foo ]

View File

@ -0,0 +1,16 @@
#source: nps-1.s
#as: -mcpu=nps400
#ld: -defsym=foo=0x57f03000
#objdump: -d
.*: +file format .*arc.*
Disassembly of section .text:
[0-9a-f]+ <.*>:
*[0-9a-f]+: 5948 3000 xldb r10,\[0x57f03000\]
*[0-9a-f]+: 5949 3000 xldw r10,\[0x57f03000\]
*[0-9a-f]+: 594a 3000 xld r10,\[0x57f03000\]
*[0-9a-f]+: 594c 3000 xstb r10,\[0x57f03000\]
*[0-9a-f]+: 594d 3000 xstw r10,\[0x57f03000\]
*[0-9a-f]+: 594e 3000 xst r10,\[0x57f03000\]

View File

@ -0,0 +1,4 @@
#source: nps-1.s
#as: -mcpu=nps400
#ld: -defsym=foo=0x56f03000
#error_output: nps-1b.err

View File

@ -0,0 +1 @@
.*\.o\(\.text\+0x0\): CMEM relocation to `foo' is invalid, 16 MSB should be 0x57f0 \(value is 0x56f03000\)

View File

@ -1,3 +1,11 @@
2016-04-14 Andrew Burgess <andrew.burgess@embecosm.com>
* arc-nps400-tbl.h: Add xldb, xldw, xld, xstb, xstw, and xst
instructions.
* arc-opc.c (insert_nps_cmem_uimm16): New function.
(extract_nps_cmem_uimm16): New function.
(arc_operands): Add NPS_XLDST_UIMM16 operand.
2016-04-14 Andrew Burgess <andrew.burgess@embecosm.com> 2016-04-14 Andrew Burgess <andrew.burgess@embecosm.com>
* arc-dis.c (arc_insn_length): New function. * arc-dis.c (arc_insn_length): New function.

View File

@ -140,3 +140,15 @@
/* hwscd.restore 0,C */ /* hwscd.restore 0,C */
{ "hwschd", 0x3e6f7003, 0xfffff03f, ARC_OPCODE_NPS400, CONTROL, NONE, { ZA, RC }, { C_NPS_HWS_RESTORE }}, { "hwschd", 0x3e6f7003, 0xfffff03f, ARC_OPCODE_NPS400, CONTROL, NONE, { ZA, RC }, { C_NPS_HWS_RESTORE }},
/**** Load / Store From (0x57f00000 + Offset) Instructions ****/
#define XLDST_LIKE(NAME,SUBOP2) \
{ NAME, (0x58000000 | (SUBOP2 << 16)), 0xf81f0000, ARC_OPCODE_NPS400, MEMORY, NONE, { NPS_R_DST, BRAKET, NPS_XLDST_UIMM16, BRAKETdup }, { 0 }},
XLDST_LIKE("xldb", 0x8)
XLDST_LIKE("xldw", 0x9)
XLDST_LIKE("xld", 0xa)
XLDST_LIKE("xstb", 0xc)
XLDST_LIKE("xstw", 0xd)
XLDST_LIKE("xst", 0xe)

View File

@ -838,6 +838,25 @@ extract_nps_dst_pos_and_size (unsigned insn ATTRIBUTE_UNUSED,
return (insn & 0x1f); return (insn & 0x1f);
} }
static unsigned
insert_nps_cmem_uimm16 (unsigned insn ATTRIBUTE_UNUSED,
int value ATTRIBUTE_UNUSED,
const char **errmsg ATTRIBUTE_UNUSED)
{
int top = (value >> 16) & 0xffff;
if (top != 0x0 && top != NPS_CMEM_HIGH_VALUE)
*errmsg = _("invalid value for CMEM ld/st immediate");
insn |= (value & 0xffff);
return insn;
}
static int
extract_nps_cmem_uimm16 (unsigned insn ATTRIBUTE_UNUSED,
bfd_boolean * invalid ATTRIBUTE_UNUSED)
{
return (NPS_CMEM_HIGH_VALUE << 16) | (insn & 0xffff);
}
/* Include the generic extract/insert functions. Order is important /* Include the generic extract/insert functions. Order is important
as some of the functions present in the .h may be disabled via as some of the functions present in the .h may be disabled via
defines. */ defines. */
@ -1498,6 +1517,9 @@ const struct arc_operand arc_operands[] =
#define NPS_RFLT_UIMM6 (NPS_UIMM16 + 1) #define NPS_RFLT_UIMM6 (NPS_UIMM16 + 1)
{ 6, 6, 0, ARC_OPERAND_UNSIGNED | ARC_OPERAND_NCHK, insert_nps_rflt_uimm6, extract_nps_rflt_uimm6 }, { 6, 6, 0, ARC_OPERAND_UNSIGNED | ARC_OPERAND_NCHK, insert_nps_rflt_uimm6, extract_nps_rflt_uimm6 },
#define NPS_XLDST_UIMM16 (NPS_RFLT_UIMM6 + 1)
{ 16, 0, BFD_RELOC_ARC_NPS_CMEM16, ARC_OPERAND_UNSIGNED | ARC_OPERAND_NCHK, insert_nps_cmem_uimm16, extract_nps_cmem_uimm16 },
}; };
const unsigned arc_num_operands = ARRAY_SIZE (arc_operands); const unsigned arc_num_operands = ARRAY_SIZE (arc_operands);