From f6b2b12db82f7b76c30ec389a67fbce5d2805323 Mon Sep 17 00:00:00 2001 From: Andre Vieira Date: Mon, 15 Apr 2019 11:53:25 +0100 Subject: [PATCH] [binutils, ARM, 11/16] New BFCSEL instruction for Armv8.1-M Mainline s patch is part of a series of patches to add support for Armv8.1-M Mainline instructions to binutils. This patch adds the BFCSEL instruction. It also adds a local relocation with a new bfd_reloc_code_real enum. ChangeLog entries are as follows: 2019-04-15 Sudakshina Das * reloc.c (BFD_RELOC_THUMB_PCREL_BFCSEL): New relocation. * bfd-in2.h: Regenerated. * libbfd.h: Likewise. *** gas/ChangeLog *** 2019-04-15 Sudakshina Das Andre Vieira * config/tc-arm.c (T16_32_TAB): New entriy for bfcsel. (do_t_v8_1_branch): New switch case for bfcsel. (toU): Define. (insns): New instruction for bfcsel. (md_pcrel_from_section): New switch case for BFD_RELOC_THUMB_PCREL_BFCSEL. (md_appdy_fix): Likewise (tc_gen_reloc): Likewise. * testsuite/gas/arm/armv8_1-m-bfcsel.d: New. * testsuite/gas/arm/armv8_1-m-bfcsel.s: New. *** ld/ChangeLog *** 2019-04-15 Sudakshina Das * testsuite/ld-arm/bfcsel.s: New. * testsuite/ld-arm/bfcsel.d: New. * testsuite/ld-arm/arm-elf.exp: Add above test. *** opcodes/ChangeLog *** 2019-04-15 Sudakshina Das * arm-dis.c (thumb32_opcodes): New instruction bfcsel. (print_insn_thumb32): Edit the switch case for %Z. --- bfd/ChangeLog | 6 ++ bfd/bfd-in2.h | 3 + bfd/libbfd.h | 1 + bfd/reloc.c | 5 ++ gas/ChangeLog | 14 ++++ gas/config/tc-arm.c | 83 ++++++++++++++++++++++++ gas/testsuite/gas/arm/armv8_1-m-bfcsel.d | 12 ++++ gas/testsuite/gas/arm/armv8_1-m-bfcsel.s | 12 ++++ ld/ChangeLog | 6 ++ ld/testsuite/ld-arm/arm-elf.exp | 3 + ld/testsuite/ld-arm/bfcsel.d | 18 +++++ ld/testsuite/ld-arm/bfcsel.s | 25 +++++++ opcodes/ChangeLog | 5 ++ opcodes/arm-dis.c | 8 +++ 14 files changed, 201 insertions(+) create mode 100644 gas/testsuite/gas/arm/armv8_1-m-bfcsel.d create mode 100644 gas/testsuite/gas/arm/armv8_1-m-bfcsel.s create mode 100644 ld/testsuite/ld-arm/bfcsel.d create mode 100644 ld/testsuite/ld-arm/bfcsel.s diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 88ca61e413b..01539647b66 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,9 @@ +2019-04-15 Sudakshina Das + + * reloc.c (BFD_RELOC_THUMB_PCREL_BFCSEL): New relocation. + * bfd-in2.h: Regenerated. + * libbfd.h: Likewise. + 2019-04-15 Sudakshina Das * reloc.c (BFD_RELOC_ARM_THUMB_BF13): New. diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index 95d66b586d6..4a3fa75867c 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -3567,6 +3567,9 @@ field in the instruction. */ /* ARM 5-bit pc-relative branch for Branch Future instructions. */ BFD_RELOC_THUMB_PCREL_BRANCH5, +/* ARM 6-bit pc-relative branch for BFCSEL instruction. */ + BFD_RELOC_THUMB_PCREL_BFCSEL, + /* ARM 17-bit pc-relative branch for Branch Future instructions. */ BFD_RELOC_ARM_THUMB_BF17, diff --git a/bfd/libbfd.h b/bfd/libbfd.h index b3d71d976a4..32080db8c3f 100644 --- a/bfd/libbfd.h +++ b/bfd/libbfd.h @@ -1530,6 +1530,7 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@", "BFD_RELOC_ARM_PCREL_CALL", "BFD_RELOC_ARM_PCREL_JUMP", "BFD_RELOC_THUMB_PCREL_BRANCH5", + "BFD_RELOC_THUMB_PCREL_BFCSEL", "BFD_RELOC_ARM_THUMB_BF17", "BFD_RELOC_ARM_THUMB_BF13", "BFD_RELOC_ARM_THUMB_BF19", diff --git a/bfd/reloc.c b/bfd/reloc.c index c41b2fe75d1..c0e413cd19d 100644 --- a/bfd/reloc.c +++ b/bfd/reloc.c @@ -3019,6 +3019,11 @@ ENUM ENUMDOC ARM 5-bit pc-relative branch for Branch Future instructions. +ENUM + BFD_RELOC_THUMB_PCREL_BFCSEL +ENUMDOC + ARM 6-bit pc-relative branch for BFCSEL instruction. + ENUM BFD_RELOC_ARM_THUMB_BF17 ENUMDOC diff --git a/gas/ChangeLog b/gas/ChangeLog index 6af144fc486..fe9856ad97f 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,17 @@ +2019-04-15 Sudakshina Das + Andre Vieira + + * config/tc-arm.c (T16_32_TAB): New entriy for bfcsel. + (do_t_v8_1_branch): New switch case for bfcsel. + (toU): Define. + (insns): New instruction for bfcsel. + (md_pcrel_from_section): New switch case + for BFD_RELOC_THUMB_PCREL_BFCSEL. + (md_appdy_fix): Likewise + (tc_gen_reloc): Likewise. + * testsuite/gas/arm/armv8_1-m-bfcsel.d: New. + * testsuite/gas/arm/armv8_1-m-bfcsel.s: New. + 2019-04-15 Sudakshina Das * config/tc-arm.c (md_pcrel_from_section): New switch case for diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c index 5d7f2c0a6d4..5e590788907 100644 --- a/gas/config/tc-arm.c +++ b/gas/config/tc-arm.c @@ -10506,6 +10506,7 @@ encode_thumb32_addr_mode (int i, bfd_boolean is_t, bfd_boolean is_d) X(_b, e000, f000b000), \ X(_bcond, d000, f0008000), \ X(_bf, 0000, f040e001), \ + X(_bfcsel,0000, f000e001), \ X(_bfx, 0000, f060e001), \ X(_bfl, 0000, f000c001), \ X(_bflx, 0000, f070e001), \ @@ -13384,6 +13385,46 @@ do_t_branch_future (void) } break; + case T_MNEM_bfcsel: + /* Operand 1. */ + if (inst.operands[1].hasreloc == 0) + { + int val = inst.operands[1].imm; + int immA = (val & 0x00001000) >> 12; + int immB = (val & 0x00000ffc) >> 2; + int immC = (val & 0x00000002) >> 1; + inst.instruction |= (immA << 16) | (immB << 1) | (immC << 11); + } + else + { + inst.relocs[1].type = BFD_RELOC_ARM_THUMB_BF13; + inst.relocs[1].pc_rel = 1; + } + + /* Operand 2. */ + if (inst.operands[2].hasreloc == 0) + { + constraint ((inst.operands[0].hasreloc != 0), BAD_ARGS); + int val2 = inst.operands[2].imm; + int val0 = inst.operands[0].imm & 0x1f; + int diff = val2 - val0; + if (diff == 4) + inst.instruction |= 1 << 17; /* T bit. */ + else if (diff != 2) + as_bad (_("out of range label-relative fixup value")); + } + else + { + constraint ((inst.operands[0].hasreloc == 0), BAD_ARGS); + inst.relocs[2].type = BFD_RELOC_THUMB_PCREL_BFCSEL; + inst.relocs[2].pc_rel = 1; + } + + /* Operand 3. */ + constraint (inst.cond != COND_ALWAYS, BAD_COND); + inst.instruction |= (inst.operands[3].imm & 0xf) << 18; + break; + case T_MNEM_bfx: case T_MNEM_bflx: inst.instruction |= inst.operands[1].reg << 16; @@ -19616,6 +19657,11 @@ static struct asm_barrier_opt barrier_opt_names[] = { mnem, OPS##nops ops, OT_csuffix, 0x0, T_MNEM##top, 0, THUMB_VARIANT, NULL, \ do_##te } +/* T_MNEM_xyz enumerator variants of ToU. */ +#define toU(mnem, top, nops, ops, te) \ + { mnem, OPS##nops ops, OT_unconditional, 0x0, T_MNEM##top, 0, THUMB_VARIANT, \ + NULL, do_##te } + /* Legacy mnemonics that always have conditional infix after the third character. */ #define CL(mnem, op, nops, ops, ae) \ @@ -21706,6 +21752,7 @@ static const struct asm_opcode insns[] = #undef THUMB_VARIANT #define THUMB_VARIANT & arm_ext_v8_1m_main toC("bf", _bf, 2, (EXPs, EXPs), t_branch_future), + toU("bfcsel", _bfcsel, 4, (EXPs, EXPs, EXPs, COND), t_branch_future), toC("bfx", _bfx, 2, (EXPs, RRnpcsp), t_branch_future), toC("bfl", _bfl, 2, (EXPs, EXPs), t_branch_future), toC("bflx", _bflx, 2, (EXPs, RRnpcsp), t_branch_future), @@ -21741,6 +21788,7 @@ static const struct asm_opcode insns[] = #undef ToC #undef toC #undef ToU +#undef toU /* MD interface: bits in the object file. */ @@ -22944,6 +22992,7 @@ md_pcrel_from_section (fixS * fixP, segT seg) case BFD_RELOC_THUMB_PCREL_BRANCH12: case BFD_RELOC_THUMB_PCREL_BRANCH20: case BFD_RELOC_THUMB_PCREL_BRANCH25: + case BFD_RELOC_THUMB_PCREL_BFCSEL: case BFD_RELOC_ARM_THUMB_BF17: case BFD_RELOC_ARM_THUMB_BF19: case BFD_RELOC_ARM_THUMB_BF13: @@ -24844,6 +24893,39 @@ md_apply_fix (fixS * fixP, } break; + case BFD_RELOC_THUMB_PCREL_BFCSEL: + if (fixP->fx_addsy + && (S_GET_SEGMENT (fixP->fx_addsy) == seg) + && !S_FORCE_RELOC (fixP->fx_addsy, TRUE) + && ARM_IS_FUNC (fixP->fx_addsy) + && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v8_1m_main)) + { + fixP->fx_done = 0; + } + if ((value & ~0x7f) && ((value & ~0x3f) != ~0x3f)) + as_bad_where (fixP->fx_file, fixP->fx_line, + _("branch out of range")); + + if (fixP->fx_done || !seg->use_rela_p) + { + newval = md_chars_to_number (buf, THUMB_SIZE); + + addressT boff = ((newval & 0x0780) >> 7) << 1; + addressT diff = value - boff; + + if (diff == 4) + { + newval |= 1 << 1; /* T bit. */ + } + else if (diff != 2) + { + as_bad_where (fixP->fx_file, fixP->fx_line, + _("out of range label-relative fixup value")); + } + md_number_to_chars (buf, newval, THUMB_SIZE); + } + break; + case BFD_RELOC_ARM_THUMB_BF17: if (fixP->fx_addsy && (S_GET_SEGMENT (fixP->fx_addsy) == seg) @@ -25158,6 +25240,7 @@ tc_gen_reloc (asection *section, fixS *fixp) return NULL; case BFD_RELOC_THUMB_PCREL_BRANCH5: + case BFD_RELOC_THUMB_PCREL_BFCSEL: as_bad_where (fixp->fx_file, fixp->fx_line, _("%s used for a symbol not defined in the same file"), bfd_get_reloc_code_name (fixp->fx_r_type)); diff --git a/gas/testsuite/gas/arm/armv8_1-m-bfcsel.d b/gas/testsuite/gas/arm/armv8_1-m-bfcsel.d new file mode 100644 index 00000000000..a498f06cd3e --- /dev/null +++ b/gas/testsuite/gas/arm/armv8_1-m-bfcsel.d @@ -0,0 +1,12 @@ +#name: Valid Armv8.1-M Mainline BFCSEL instruction +#as: -march=armv8.1-m.main +#objdump: -dr --prefix-addresses --show-raw-insn + +.*: +file format .*arm.* + +Disassembly of section .text: +0[0-9a-f]+ <[^>]+> f080 e803 bfcsel 2, 0000000a , 4, eq +0[0-9a-f]+ <[^>]+> 4609 mov r1, r1 +0[0-9a-f]+ <[^>]+> d000 beq.n 0000000a +0[0-9a-f]+ <[^>]+> 4613 mov r3, r2 +0[0-9a-f]+ <[^>]+> 4614 mov r4, r2 diff --git a/gas/testsuite/gas/arm/armv8_1-m-bfcsel.s b/gas/testsuite/gas/arm/armv8_1-m-bfcsel.s new file mode 100644 index 00000000000..07903ba5f0d --- /dev/null +++ b/gas/testsuite/gas/arm/armv8_1-m-bfcsel.s @@ -0,0 +1,12 @@ + .syntax unified + .text + .thumb +foo: + bfcsel .LB1, .LBranch, .LB2, eq + mov r1, r1 +.LB1: + beq .LBranch +.LB2: + mov r3, r2 +.LBranch: + mov r4, r2 diff --git a/ld/ChangeLog b/ld/ChangeLog index 1e3ee3963ab..869d8e352cc 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,9 @@ +2019-04-15 Sudakshina Das + + * testsuite/ld-arm/bfcsel.s: New. + * testsuite/ld-arm/bfcsel.d: New. + * testsuite/ld-arm/arm-elf.exp: Add above test. + 2019-04-15 Sudakshina Das * testsuite/ld-arm/bfl.s: New. diff --git a/ld/testsuite/ld-arm/arm-elf.exp b/ld/testsuite/ld-arm/arm-elf.exp index 528565e97be..5471895e63a 100644 --- a/ld/testsuite/ld-arm/arm-elf.exp +++ b/ld/testsuite/ld-arm/arm-elf.exp @@ -673,6 +673,9 @@ set armeabitests_nonacl { {"Armv8.1-M Mainline BFL" "-r -Ttext 0x1000 --section-start .foo=0x1001000" "" "-march=armv8.1-m.main" {bfl.s} {{objdump -dr bfl.d}} "bfl"} + {"Armv8.1-M Mainline BFCSEL" "-r -Ttext 0x1000 --section-start .foo=0x1001000" "" "-march=armv8.1-m.main" {bfcsel.s} + {{objdump -dr bfcsel.d}} + "bfcsel"} {"R_ARM_THM_JUMP24 Relocation veneers: Short 1" "--no-fix-arm1176 --section-start destsect=0x00009000 --section-start .text=0x8000" "" diff --git a/ld/testsuite/ld-arm/bfcsel.d b/ld/testsuite/ld-arm/bfcsel.d new file mode 100644 index 00000000000..914ea93cec4 --- /dev/null +++ b/ld/testsuite/ld-arm/bfcsel.d @@ -0,0 +1,18 @@ + +.*: file format elf32-.*arm + + +Disassembly of section .text: + +00001000 <_start>: + 1000: f101 e7ff bfcsel 4, 1001000 , 6, eq + 1000: R_ARM_THM_BF12 bar + 1004: 4623 mov r3, r4 + 1006: 4611 mov r1, r2 + 1008: d0ff beq.n 100a <_start\+0xa> + 100a: 4613 mov r3, r2 + +Disassembly of section .foo: + +01001000 : + 1001000: 4770 bx lr diff --git a/ld/testsuite/ld-arm/bfcsel.s b/ld/testsuite/ld-arm/bfcsel.s new file mode 100644 index 00000000000..675e2ea1ae2 --- /dev/null +++ b/ld/testsuite/ld-arm/bfcsel.s @@ -0,0 +1,25 @@ + .global _start + .syntax unified + +@ We will place the section .text at 0x1000. + + .text + .thumb_func + +_start: + bfcsel .LB1, bar, .LB2, eq + mov r3, r4 + mov r1, r2 +.LB1: + beq .LB2 +.LB2: + mov r3, r2 + +@ We will place the section .foo at 0x1001000. + + .section .foo, "xa" + .thumb_func + +bar: + bx lr + diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index 69a191abf70..594e7aeab54 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,3 +1,8 @@ +2019-04-15 Sudakshina Das + + * arm-dis.c (thumb32_opcodes): New instruction bfcsel. + (print_insn_thumb32): Edit the switch case for %Z. + 2019-04-15 Sudakshina Das * arm-dis.c (print_insn_thumb32): Updated to accept new %Z pattern. diff --git a/opcodes/arm-dis.c b/opcodes/arm-dis.c index 93e1efed8fb..988699668dd 100644 --- a/opcodes/arm-dis.c +++ b/opcodes/arm-dis.c @@ -2758,6 +2758,8 @@ static const struct opcode32 thumb32_opcodes[] = 0xf000c001, 0xf800f001, "bfl%c\t%G, %Y"}, {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_1M_MAIN), 0xf070e001, 0xf8f0f001, "bflx%c\t%G, %16-19S"}, + {ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_1M_MAIN), + 0xf000e001, 0xf840f001, "bfcsel\t%G, %Z, %18-21c"}, /* ARMv8-M and ARMv8-M Security Extensions instructions. */ @@ -5933,6 +5935,12 @@ print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given) offset = (offset & 0x1000) ? offset - (1 << 13) : offset; info->print_address_func (pc + 4 + offset, info); + + unsigned int T = (given & 0x00020000u) >> 17; + unsigned int endoffset = (((given & 0x07800000) >> 23) << 1); + unsigned int boffset = (T == 1) ? 4 : 2; + func (stream, ", "); + func (stream, "%x", endoffset + boffset); } break; -- 2.30.2