Add support for ARC instruction relaxation in the assembler.

gas/
2016-01-26  Claudiu Zissulescu  <claziss@synopsys.com>
	    Janek van Oirschot <jvanoirs@synopsys.com>

        * config/tc-arc.h (TC_FRAG_TYPE, TC_PCREL_ADJUST, MAX_INSN_ARGS)
        (MAX_INSN_FLGS, MAX_FLAG_NAME_LENGHT, TC_GENERIC_RELAX_TABLE):
        Define.
        (arc_flags, arc_relax_type): New structure.
        * config/tc-arc.c (FRAG_MAX_GROWTH, RELAX_TABLE_ENTRY)
	(RELAX_TABLE_ENTRY_MAX): New define.
        (relaxation_state, md_relax_table, arc_relaxable_insns)
	(arc_num_relaxable_ins): New variable.
	(rlx_operand_type, arc_rlx_types): New enums.
	(arc_relaxable_ins): New structure.
        (OPTION_RELAX): New option.
        (arc_insn): New relax member.
        (arc_flags): Remove.
        (relax_insn_p): New function.
        (apply_fixups): Likewise.
        (relaxable_operand): Likewise.
        (may_relax_expr): Likewise.
        (relaxable_flag): Likewise.
        (arc_pcrel_adjust): Likewise.
        (md_estimate_size_before_relax): Implement.
        (md_convert_frag): Likewise.
        (md_parse_option): Handle new mrelax option.
        (md_show_usage): Likewise.
        (assemble_insn): Set relax member.
        (emit_insn0): New function.
        (emit_insn1): Likewise.
        (emit_insn): Handle relaxation case.
	* NEWS: Mention the new relaxation option.
	* doc/c-arc.texi (ARC Options): Document new mrelax option.

gas/testsuite
2016-01-26  Claudiu Zissulescu  <claziss@synopsys.com>

        * gas/arc/relax-avoid1.d: New file.
        * gas/arc/relax-avoid1.s: Likewise.
        * gas/arc/relax-avoid2.d: Likewise.
        * gas/arc/relax-avoid2.s: Likewise.
        * gas/arc/relax-avoid3.d: Likewise.
        * gas/arc/relax-avoid3.s: Likewise.
	* gas/arc/relax-b.d: Likewise.
        * gas/arc/relax-b.s: Likewise.

include/opcode/
2016-01-26  Claudiu Zissulescu  <claziss@synopsys.com>
	    Janek van Oirschot  <jvanoirs@synopsys.com>

        * arc.h (arc_opcode arc_relax_opcodes, arc_num_relax_opcodes):
        Declare.

opcodes/
2016-01-26  Claudiu Zissulescu  <claziss@synopsys.com>
	    Janek van Oirschot  <jvanoirs@synopsys.com>

        * arc-opc.c (arc_relax_opcodes, arc_num_relax_opcodes): New
        variable.
This commit is contained in:
Claudiu Zissulescu 2016-02-10 12:09:01 +00:00 committed by Nick Clifton
parent 83da6e748c
commit 4670103e86
18 changed files with 2262 additions and 1451 deletions

View File

@ -1,3 +1,45 @@
2016-02-10 Claudiu Zissulescu <claziss@synopsys.com>
Janek van Oirschot <jvanoirs@synopsys.com>
* config/tc-arc.h (TC_FRAG_TYPE, TC_PCREL_ADJUST, MAX_INSN_ARGS)
(MAX_INSN_FLGS, MAX_FLAG_NAME_LENGHT, TC_GENERIC_RELAX_TABLE):
Define.
(arc_flags, arc_relax_type): New structure.
* config/tc-arc.c (FRAG_MAX_GROWTH, RELAX_TABLE_ENTRY)
(RELAX_TABLE_ENTRY_MAX): New define.
(relaxation_state, md_relax_table, arc_relaxable_insns)
(arc_num_relaxable_ins): New variable.
(rlx_operand_type, arc_rlx_types): New enums.
(arc_relaxable_ins): New structure.
(OPTION_RELAX): New option.
(arc_insn): New relax member.
(arc_flags): Remove.
(relax_insn_p): New function.
(apply_fixups): Likewise.
(relaxable_operand): Likewise.
(may_relax_expr): Likewise.
(relaxable_flag): Likewise.
(arc_pcrel_adjust): Likewise.
(md_estimate_size_before_relax): Implement.
(md_convert_frag): Likewise.
(md_parse_option): Handle new mrelax option.
(md_show_usage): Likewise.
(assemble_insn): Set relax member.
(emit_insn0): New function.
(emit_insn1): Likewise.
(emit_insn): Handle relaxation case.
* NEWS: Mention the new relaxation option.
* doc/c-arc.texi (ARC Options): Document new mrelax option.
* doc/as.texinfo (Target ARC Options): Likewise.
* testsuite/gas/arc/relax-avoid1.d: New file.
* testsuite/gas/arc/relax-avoid1.s: Likewise.
* testsuite/gas/arc/relax-avoid2.d: Likewise.
* testsuite/gas/arc/relax-avoid2.s: Likewise.
* testsuite/gas/arc/relax-avoid3.d: Likewise.
* testsuite/gas/arc/relax-avoid3.s: Likewise.
* testsuite/gas/arc/relax-b.d: Likewise.
* testsuite/gas/arc/relax-b.s: Likewise.
2016-02-08 Nick Clifton <nickc@redhat.com>
* config/tc-ia64.c (dot_prologue): Fix formatting.

View File

@ -10,6 +10,8 @@
* New command line option -mfence-as-lock-add=yes for x86 target to encode
lfence, mfence and sfence as "lock addl $0x0, (%[re]sp)".
* Add assembly-time relaxation option for ARC cpus.
Changes in 2.26:
* Add a configure option --enable-compressed-debug-sections={all,gas} to

File diff suppressed because it is too large Load Diff

View File

@ -177,6 +177,14 @@ extern long md_pcrel_from_section (struct fix *, segT);
/* This hook is required to parse register names as operands. */
#define md_parse_name(name, exp, m, c) arc_parse_name (name, exp)
/* Used within frags to pass some information to some relaxation
machine dependent values. */
#define TC_FRAG_TYPE struct arc_relax_type
/* Adjust non PC-rel values at relaxation time. */
#define TC_PCREL_ADJUST(F) arc_pcrel_adjust (F)
extern int arc_pcrel_adjust (fragS *);
extern bfd_boolean arc_parse_name (const char *, struct expressionS *);
extern int tc_arc_fix_adjustable (struct fix *);
extern void arc_handle_align (fragS *);
@ -193,3 +201,51 @@ extern void arc_frob_label (symbolS *);
#define NOP_OPCODE_S 0x000078E0
#define NOP_OPCODE_L 0x264A7000 /* mov 0,0. */
#define MAX_FLAG_NAME_LENGHT 3
struct arc_flags
{
/* Name of the parsed flag. */
char name[MAX_FLAG_NAME_LENGHT + 1];
/* The code of the parsed flag. Valid when is not zero. */
unsigned char code;
};
#ifndef MAX_INSN_ARGS
#define MAX_INSN_ARGS 6
#endif
#ifndef MAX_INSN_FLGS
#define MAX_INSN_FLGS 3
#endif
extern const relax_typeS md_relax_table[];
#define TC_GENERIC_RELAX_TABLE md_relax_table
/* Used to construct instructions at md_convert_frag stage of
relaxation. */
struct arc_relax_type
{
/* Dictates whether the pc-relativity should be kept in mind when
relax_frag is called or whether the pc-relativity should be
solved outside of relaxation. For clarification: BL(_S) and
B(_S) use pcrel == 1 and ADD with a solvable expression as 3rd
operand use pcrel == 0. */
unsigned char pcrel;
/* Expressions that dictate the operands. Used for re-assembling in
md_convert_frag. */
expressionS tok[MAX_INSN_ARGS];
/* Number of tok (i.e. number of operands). Used for re-assembling
in md_convert_frag. */
int ntok;
/* Flags of instruction. Used for re-assembling in
md_convert_frag. */
struct arc_flags pflags[MAX_INSN_FLGS];
/* Number of flags. Used for re-assembling in md_convert_frag. */
int nflg;
};

View File

@ -268,6 +268,7 @@ gcc(1), ld(1), and the Info entries for @file{binutils} and @file{ld}.
[@b{-mcpu=@var{cpu}}]
[@b{-mA6}|@b{-mARC600}|@b{-mARC601}|@b{-mA7}|@b{-mARC700}|@b{-mEM}|@b{-mHS}]
[@b{-mcode-density}]
[@b{-mrelax}]
[@b{-EB}|@b{-EL}]
@end ifset
@ifset ARM

View File

@ -85,6 +85,12 @@ default.
This option turns on Code Density instructions. Only valid for ARC EM
processors.
@cindex @code{-mrelax} command line option, ARC
@item -mrelax
Enable support for assembly-time relaxation. The assembler will
replace a longer version of an instruction with a shorter one,
whenever it is possible.
@end table
@node ARC Syntax

View File

@ -0,0 +1,13 @@
#as: -mcpu=archs -mrelax
#objdump: -dr
.*: +file format .*arc.*
Disassembly of section .text:
00000000 <.text>:
0: 78e0 nop_s
2: 240a 0f80 0000 0000 mov r4,0
6: R_ARC_32_ME .LC2
a: 78e0 nop_s

View File

@ -0,0 +1,11 @@
.section .rodata
.align 4
.LC2:
.word 0x01
.word 0x02
.word 0x03
.section .text
.align 4
nop_s
mov r4,@.LC2

View File

@ -0,0 +1,14 @@
#as: -mcpu=archs -mrelax
#objdump: -dr
.*: +file format .*arc.*
Disassembly of section .text:
00000000 <test>:
0: 2000 0000 add r0,r0,r0
00000004 <main>:
4: 0802 0000 bl 0 <test>
4: R_ARC_S25W_PCREL_PLT test

View File

@ -0,0 +1,4 @@
test:
add r0,r0,r0
main:
bl @test@plt

View File

@ -0,0 +1,14 @@
#as: -mcpu=archs -mrelax
#objdump: -dr
.*: +file format .*arc.*
Disassembly of section .text:
00000000 <test>:
0: 2000 0000 add r0,r0,r0
00000004 <main>:
4: 0001 0000 b 0 <test>
4: R_ARC_S25H_PCREL test

View File

@ -0,0 +1,5 @@
test:
add r0,r0,r0
.weak test
main:
b test

View File

@ -0,0 +1,19 @@
#as: -mcpu=archs -mrelax
#objdump: -dr
.*: +file format .*arc.*
Disassembly of section .text:
00000000 <foo-0x4>:
0: 78e0 nop_s
2: 78e0 nop_s
00000004 <foo>:
4: 2000 0000 add r0,r0,r0
00000008 <bar>:
8: ffff bl_s 4 <foo>
a: 2100 0041 add r1,r1,r1
e: f1fc b_s 4 <foo>

View File

@ -0,0 +1,11 @@
.text
nop_s
.align 4
foo:
add r0,r0,r0
.align 4
bar:
bl @foo
add r1,r1,r1
b @foo

View File

@ -1,3 +1,9 @@
2016-02-10 Claudiu Zissulescu <claziss@synopsys.com>
Janek van Oirschot <jvanoirs@synopsys.com>
* opcode/arc.h (arc_opcode arc_relax_opcodes, arc_num_relax_opcodes):
Declare.
2016-02-09 Nick Clifton <nickc@redhat.com>
* opcode/metag.h (metag_scondtab): Mark as possibly unused.

View File

@ -24,8 +24,13 @@
#ifndef OPCODE_ARC_H
#define OPCODE_ARC_H
#ifndef MAX_INSN_ARGS
#define MAX_INSN_ARGS 6
#endif
#ifndef MAX_INSN_FLGS
#define MAX_INSN_FLGS 3
#endif
/* Instruction Class. */
typedef enum
@ -410,4 +415,7 @@ struct arc_aux_reg
extern const struct arc_aux_reg arc_aux_regs[];
extern const unsigned arc_num_aux_regs;
extern const struct arc_opcode arc_relax_opcodes[];
extern const unsigned arc_num_relax_opcodes;
#endif /* OPCODE_ARC_H */

View File

@ -1,3 +1,9 @@
2016-02-10 Claudiu Zissulescu <claziss@synopsys.com>
Janek van Oirschot <jvanoirs@synopsys.com>
* arc-opc.c (arc_relax_opcodes, arc_num_relax_opcodes): New
variable.
2016-02-04 Nick Clifton <nickc@redhat.com>
PR target/19561

View File

@ -1359,3 +1359,129 @@ const struct arc_aux_reg arc_aux_regs[] =
};
const unsigned arc_num_aux_regs = ARRAY_SIZE (arc_aux_regs);
/* NOTE: The order of this array MUST be consistent with 'enum
arc_rlx_types' located in tc-arc.h! */
const struct arc_opcode arc_relax_opcodes[] =
{
{ NULL, 0x0, 0x0, 0x0, ARITH, NONE, { UNUSED }, { 0 } },
/* bl_s s13 11111sssssssssss. */
{ "bl_s", 0x0000F800, 0x0000F800, ARC_OPCODE_ARC600 | ARC_OPCODE_ARC700
| ARC_OPCODE_ARCv2EM | ARC_OPCODE_ARCv2HS, BRANCH, NONE,
{ SIMM13_A32_5_S }, { 0 }},
/* bl<.d> s25 00001sssssssss10SSSSSSSSSSNRtttt. */
{ "bl", 0x08020000, 0xF8030000, ARC_OPCODE_ARC600 | ARC_OPCODE_ARC700
| ARC_OPCODE_ARCv2EM | ARC_OPCODE_ARCv2HS, BRANCH, NONE,
{ SIMM25_A32_5 }, { C_D }},
/* b_s s10 1111000sssssssss. */
{ "b_s", 0x0000F000, 0x0000FE00, ARC_OPCODE_ARC600 | ARC_OPCODE_ARC700
| ARC_OPCODE_ARCv2EM | ARC_OPCODE_ARCv2HS, BRANCH, NONE,
{ SIMM10_A16_7_S }, { 0 }},
/* b<.d> s25 00000ssssssssss1SSSSSSSSSSNRtttt. */
{ "b", 0x00010000, 0xF8010000, ARC_OPCODE_ARC600 | ARC_OPCODE_ARC700
| ARC_OPCODE_ARCv2EM | ARC_OPCODE_ARCv2HS, BRANCH, NONE,
{ SIMM25_A16_5 }, { C_D }},
/* add_s c,b,u3 01101bbbccc00uuu. Wants UIMM3_13_S_PCREL. */
{ "add_s", 0x00006800, 0x0000F818, ARC_OPCODE_ARC600 | ARC_OPCODE_ARC700
| ARC_OPCODE_ARCv2EM | ARC_OPCODE_ARCv2HS, ARITH, NONE,
{ RC_S, RB_S, UIMM3_13_S }, { 0 }},
/* add<.f> a,b,u6 00100bbb01000000FBBBuuuuuuAAAAAA. Wants
UIMM6_20_PCREL. */
{ "add", 0x20400000, 0xF8FF0000, ARC_OPCODE_ARC600 | ARC_OPCODE_ARC700
| ARC_OPCODE_ARCv2EM | ARC_OPCODE_ARCv2HS, ARITH, NONE,
{ RA, RB, UIMM6_20 }, { C_F }},
/* add<.f> a,b,limm 00100bbb00000000FBBB111110AAAAAA. */
{ "add", 0x20000F80, 0xF8FF0FC0, ARC_OPCODE_ARC600 | ARC_OPCODE_ARC700
| ARC_OPCODE_ARCv2EM | ARC_OPCODE_ARCv2HS, ARITH, NONE,
{ RA, RB, LIMM }, { C_F }},
/* ld_s c,b,u7 10000bbbcccuuuuu. Wants UIMM7_A32_11_S_PCREL. */
{ "ld_s", 0x00008000, 0x0000F800, ARC_OPCODE_ARC600 | ARC_OPCODE_ARC700
| ARC_OPCODE_ARCv2EM | ARC_OPCODE_ARCv2HS, MEMORY, NONE,
{ RC_S, BRAKET, RB_S, UIMM7_A32_11_S, BRAKETdup }, { 0 }},
/* ld<.di><.aa><.x><zz> a,b,s9
00010bbbssssssssSBBBDaaZZXAAAAAA. Wants SIMM9_8_PCREL. */
{ "ld", 0x10000000, 0xF8000000, ARC_OPCODE_ARC600 | ARC_OPCODE_ARC700
| ARC_OPCODE_ARCv2EM | ARC_OPCODE_ARCv2HS, MEMORY, NONE,
{ RA, BRAKET, RB, SIMM9_8, BRAKETdup },
{ C_ZZ23, C_DI20, C_AA21, C_X25 }},
/* ld<.di><.aa><.x><zz> a,b,limm 00100bbbaa110ZZXDBBB111110AAAAAA. */
{ "ld", 0x20300F80, 0xF8380FC0, ARC_OPCODE_ARC600 | ARC_OPCODE_ARC700
| ARC_OPCODE_ARCv2EM | ARC_OPCODE_ARCv2HS, MEMORY, NONE,
{ RA, BRAKET, RB, LIMM, BRAKETdup },
{ C_ZZ13, C_DI16, C_AA8, C_X15 }},
/* mov_s b,u8 11011bbbuuuuuuuu. Wants UIMM8_8_S_PCREL. */
{ "mov_s", 0x0000D800, 0x0000F800, ARC_OPCODE_ARC600 | ARC_OPCODE_ARC700
| ARC_OPCODE_ARCv2EM | ARC_OPCODE_ARCv2HS, MEMORY, NONE,
{ RB_S, UIMM8_8_S }, { 0 }},
/* mov<.f> b,s12 00100bbb10001010FBBBssssssSSSSSS. Wants
SIMM12_20_PCREL. */
{ "mov", 0x208A0000, 0xF8FF0000, ARC_OPCODE_ARC600 | ARC_OPCODE_ARC700
| ARC_OPCODE_ARCv2EM | ARC_OPCODE_ARCv2HS, MEMORY, NONE,
{ RB, SIMM12_20 }, { C_F }},
/* mov<.f> b,limm 00100bbb00001010FBBB111110RRRRRR. */
{ "mov", 0x200A0F80, 0xF8FF0FC0, ARC_OPCODE_ARC600 | ARC_OPCODE_ARC700
| ARC_OPCODE_ARCv2EM | ARC_OPCODE_ARCv2HS, MEMORY, NONE,
{ RB, LIMM }, { C_F }},
/* sub_s c,b,u3 01101bbbccc01uuu. UIMM3_13_S_PCREL. */
{ "sub_s", 0x00006808, 0x0000F818, ARC_OPCODE_ARC600 | ARC_OPCODE_ARC700
| ARC_OPCODE_ARCv2EM | ARC_OPCODE_ARCv2HS, ARITH, NONE,
{ RC_S, RB_S, UIMM3_13_S }, { 0 }},
/* sub<.f> a,b,u6 00100bbb01000010FBBBuuuuuuAAAAAA.
UIMM6_20_PCREL. */
{ "sub", 0x20420000, 0xF8FF0000, ARC_OPCODE_ARC600 | ARC_OPCODE_ARC700
| ARC_OPCODE_ARCv2EM | ARC_OPCODE_ARCv2HS, ARITH, NONE,
{ RA, RB, UIMM6_20 }, { C_F }},
/* sub<.f> a,b,limm 00100bbb00000010FBBB111110AAAAAA. */
{ "sub", 0x20020F80, 0xF8FF0FC0, ARC_OPCODE_ARC600 | ARC_OPCODE_ARC700
| ARC_OPCODE_ARCv2EM | ARC_OPCODE_ARCv2HS, ARITH, NONE,
{ RA, RB, LIMM }, { C_F }},
/* mpy<.f> a,b,u6 00100bbb01011010FBBBuuuuuuAAAAAA.
UIMM6_20_PCREL. */
{ "mpy", 0x205A0000, 0xF8FF0000, ARC_OPCODE_ARC700 | ARC_OPCODE_ARCv2EM
| ARC_OPCODE_ARCv2HS, ARITH, MPY6E, { RA, RB, UIMM6_20 }, { C_F }},
/* mpy<.f> a,b,limm 00100bbb00011010FBBB111110AAAAAA. */
{ "mpy", 0x201A0F80, 0xF8FF0FC0, ARC_OPCODE_ARC700 | ARC_OPCODE_ARCv2EM
| ARC_OPCODE_ARCv2HS, ARITH, MPY6E, { RA, RB, LIMM }, { C_F }},
/* mov<.f><.cc> b,u6 00100bbb11001010FBBBuuuuuu1QQQQQ.
UIMM6_20_PCREL. */
{ "mov", 0x20CA0020, 0xF8FF0020, ARC_OPCODE_ARC600 | ARC_OPCODE_ARC700
| ARC_OPCODE_ARCv2EM | ARC_OPCODE_ARCv2HS, MEMORY, NONE,
{ RB, UIMM6_20 }, { C_F, C_CC }},
/* mov<.f><.cc> b,limm 00100bbb11001010FBBB1111100QQQQQ. */
{ "mov", 0x20CA0F80, 0xF8FF0FE0, ARC_OPCODE_ARC600 | ARC_OPCODE_ARC700
| ARC_OPCODE_ARCv2EM | ARC_OPCODE_ARCv2HS, MEMORY, NONE,
{ RB, LIMM }, { C_F, C_CC }},
/* add<.f><.cc> b,b,u6 00100bbb11000000FBBBuuuuuu1QQQQQ.
UIMM6_20_PCREL. */
{ "add", 0x20C00020, 0xF8FF0020, ARC_OPCODE_ARC600 | ARC_OPCODE_ARC700
| ARC_OPCODE_ARCv2EM | ARC_OPCODE_ARCv2HS, ARITH, NONE,
{ RB, RBdup, UIMM6_20 }, { C_F, C_CC }},
/* add<.f><.cc> b,b,limm 00100bbb11000000FBBB1111100QQQQQ. */
{ "add", 0x20C00F80, 0xF8FF0FE0, ARC_OPCODE_ARC600 | ARC_OPCODE_ARC700
| ARC_OPCODE_ARCv2EM | ARC_OPCODE_ARCv2HS, ARITH, NONE,
{ RB, RBdup, LIMM }, { C_F, C_CC }}
};
const unsigned arc_num_relax_opcodes = ARRAY_SIZE (arc_relax_opcodes);