[binutils, Arm] Add support for conditional instructions in Armv8.1-M Mainline

This patch adds the following instructions which are part of the
Armv8.1-M Mainline:
CINC
CINV
CNEG
CSINC
CSINV
CSNEG
CSET
CSETM
CSEL

gas/ChangeLog:

2019-05-21  Sudakshina Das  <sudi.das@arm.com>

	* config/tc-arm.c (TOGGLE_BIT): New.
	(T16_32_TAB): New entries for cinc, cinv, cneg, csinc,
	csinv, csneg, cset, csetm and csel.
	(operand_parse_code): New OP_RR_ZR.
	(parse_operand): Handle case for OP_RR_ZR.
	(do_t_cond): New.
	(insns): New instructions for cinc, cinv, cneg, csinc,
	csinv, csneg, cset, csetm, csel.
	* testsuite/gas/arm/armv8_1-m-cond-bad.d: New test.
	* testsuite/gas/arm/armv8_1-m-cond-bad.l: New test.
	* testsuite/gas/arm/armv8_1-m-cond-bad.s: New test.
	* testsuite/gas/arm/armv8_1-m-cond.d: New test.
	* testsuite/gas/arm/armv8_1-m-cond.s: New test.

opcodes/ChangeLog:

2019-05-21  Sudakshina Das  <sudi.das@arm.com>

	* arm-dis.c (enum mve_instructions): New enum
	for csinc, csinv, csneg, csel, cset, csetm, cinv, cinv
	and cneg.
	(mve_opcodes): New instructions as above.
	(is_mve_encoding_conflict): Add cases for csinc, csinv,
	csneg and csel.
	(print_insn_mve): Accept new %<bitfield>c and %<bitfield>C.
This commit is contained in:
Sudakshina Das 2019-05-21 18:15:13 +01:00
parent 23d00a419f
commit e39c1607a2
9 changed files with 261 additions and 1 deletions

View File

@ -1,3 +1,19 @@
2019-05-21 Sudakshina Das <sudi.das@arm.com>
* config/tc-arm.c (TOGGLE_BIT): New.
(T16_32_TAB): New entries for cinc, cinv, cneg, csinc,
csinv, csneg, cset, csetm and csel.
(operand_parse_code): New OP_RR_ZR.
(parse_operand): Handle case for OP_RR_ZR.
(do_t_cond): New.
(insns): New instructions for cinc, cinv, cneg, csinc,
csinv, csneg, cset, csetm, csel.
* testsuite/gas/arm/armv8_1-m-cond-bad.d: New test.
* testsuite/gas/arm/armv8_1-m-cond-bad.l: New test.
* testsuite/gas/arm/armv8_1-m-cond-bad.s: New test.
* testsuite/gas/arm/armv8_1-m-cond.d: New test.
* testsuite/gas/arm/armv8_1-m-cond.s: New test.
2019-05-21 Sudakshina Das <sudi.das@arm.com>
* config/tc-arm.c (operand_parse_code): New entries for

View File

@ -1009,6 +1009,9 @@ static void it_fsm_post_encode (void);
} \
while (0)
/* Toggle value[pos]. */
#define TOGGLE_BIT(value, pos) (value ^ (1 << pos))
/* Pure syntax. */
/* This array holds the chars that always start a comment. If the
@ -6930,6 +6933,7 @@ enum operand_parse_code
OP_RRe, /* ARM register, only even numbered. */
OP_RRo, /* ARM register, only odd numbered, not r13 or r15. */
OP_RRnpcsp_I32, /* ARM register (no BadReg) or literal 1 .. 32 */
OP_RR_ZR, /* ARM register or ZR but no PC */
OP_REGLST, /* ARM register list */
OP_CLRMLST, /* CLRM register list */
@ -7793,6 +7797,8 @@ parse_operands (char *str, const unsigned int *pattern, bfd_boolean thumb)
case OP_oRMQRZ:
po_reg_or_goto (REG_TYPE_MQ, try_rr_zr);
break;
case OP_RR_ZR:
try_rr_zr:
po_reg_or_goto (REG_TYPE_RN, ZR);
break;
@ -7880,6 +7886,7 @@ parse_operands (char *str, const unsigned int *pattern, bfd_boolean thumb)
case OP_RMQRZ:
case OP_oRMQRZ:
case OP_RR_ZR:
if (!inst.operands[i].iszr && inst.operands[i].reg == REG_PC)
inst.error = BAD_PC;
break;
@ -11107,7 +11114,7 @@ encode_thumb32_addr_mode (int i, bfd_boolean is_t, bfd_boolean is_d)
inst.error = _("instruction does not accept unindexed addressing");
}
/* Table of Thumb instructions which exist in both 16- and 32-bit
/* Table of Thumb instructions which exist in 16- and/or 32-bit
encodings (the latter only in post-V6T2 cores). The index is the
value used in the insns table below. When there is more than one
possible 16-bit encoding for the instruction, this table always
@ -11136,11 +11143,20 @@ encode_thumb32_addr_mode (int i, bfd_boolean is_t, bfd_boolean is_d)
X(_bflx, 0000, f070e001), \
X(_bic, 4380, ea200000), \
X(_bics, 4380, ea300000), \
X(_cinc, 0000, ea509000), \
X(_cinv, 0000, ea50a000), \
X(_cmn, 42c0, eb100f00), \
X(_cmp, 2800, ebb00f00), \
X(_cneg, 0000, ea50b000), \
X(_cpsie, b660, f3af8400), \
X(_cpsid, b670, f3af8600), \
X(_cpy, 4600, ea4f0000), \
X(_csel, 0000, ea508000), \
X(_cset, 0000, ea5f900f), \
X(_csetm, 0000, ea5fa00f), \
X(_csinc, 0000, ea509000), \
X(_csinv, 0000, ea50a000), \
X(_csneg, 0000, ea50b000), \
X(_dec_sp,80dd, f1ad0d00), \
X(_dls, 0000, f040e001), \
X(_dlstp, 0000, f000e001), \
@ -11955,6 +11971,60 @@ do_t_clz (void)
inst.instruction |= Rm;
}
/* For the Armv8.1-M conditional instructions. */
static void
do_t_cond (void)
{
unsigned Rd, Rn, Rm;
signed int cond;
constraint (inst.cond != COND_ALWAYS, BAD_COND);
Rd = inst.operands[0].reg;
switch (inst.instruction)
{
case T_MNEM_csinc:
case T_MNEM_csinv:
case T_MNEM_csneg:
case T_MNEM_csel:
Rn = inst.operands[1].reg;
Rm = inst.operands[2].reg;
cond = inst.operands[3].imm;
constraint (Rn == REG_SP, BAD_SP);
constraint (Rm == REG_SP, BAD_SP);
break;
case T_MNEM_cinc:
case T_MNEM_cinv:
case T_MNEM_cneg:
Rn = inst.operands[1].reg;
cond = inst.operands[2].imm;
/* Invert the last bit to invert the cond. */
cond = TOGGLE_BIT (cond, 0);
constraint (Rn == REG_SP, BAD_SP);
Rm = Rn;
break;
case T_MNEM_csetm:
case T_MNEM_cset:
cond = inst.operands[1].imm;
/* Invert the last bit to invert the cond. */
cond = TOGGLE_BIT (cond, 0);
Rn = REG_PC;
Rm = REG_PC;
break;
default: abort ();
}
set_pred_insn_type (OUTSIDE_PRED_INSN);
inst.instruction = THUMB_OP32 (inst.instruction);
inst.instruction |= Rd << 8;
inst.instruction |= Rn << 16;
inst.instruction |= Rm;
inst.instruction |= cond << 4;
}
static void
do_t_csdb (void)
{
@ -25157,6 +25227,16 @@ static const struct asm_opcode insns[] =
/* Armv8.1-M Mainline instructions. */
#undef THUMB_VARIANT
#define THUMB_VARIANT & arm_ext_v8_1m_main
toU("cinc", _cinc, 3, (RRnpcsp, RR_ZR, COND), t_cond),
toU("cinv", _cinv, 3, (RRnpcsp, RR_ZR, COND), t_cond),
toU("cneg", _cneg, 3, (RRnpcsp, RR_ZR, COND), t_cond),
toU("csel", _csel, 4, (RRnpcsp, RR_ZR, RR_ZR, COND), t_cond),
toU("csetm", _csetm, 2, (RRnpcsp, COND), t_cond),
toU("cset", _cset, 2, (RRnpcsp, COND), t_cond),
toU("csinc", _csinc, 4, (RRnpcsp, RR_ZR, RR_ZR, COND), t_cond),
toU("csinv", _csinv, 4, (RRnpcsp, RR_ZR, RR_ZR, COND), t_cond),
toU("csneg", _csneg, 4, (RRnpcsp, RR_ZR, RR_ZR, COND), t_cond),
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),

View File

@ -0,0 +1,4 @@
#name: Invalid Armv8.1-M Mainline conditional instructions
#source: armv8_1-m-cond-bad.s
#as: -march=armv8.1-m.main
#error_output: armv8_1-m-cond-bad.l

View File

@ -0,0 +1,8 @@
.*: Assembler messages:
.*: Error: condition required -- `cset r4,r2,ne'
.*: Error: r13 not allowed here -- `csetm sp,ne'
.*: Error: r15 not allowed here -- `cinc r3,pc,lt'
.*: Error: r15 not allowed here -- `cinv pc,r2,lt'
.*: Error: r13 not allowed here -- `cneg r3,sp,lt'
.*: Error: instruction not allowed in IT block -- `csinc r3,r2,r4,lt'
.*: Error: instruction cannot be conditional -- `csnegne r3,r2,r4,lt'

View File

@ -0,0 +1,15 @@
.syntax unified
.text
foo:
cset r4, r2, ne
csetm sp, ne
cinc r3, pc, lt
cinv pc, r2, lt
cneg r3, sp, lt
it eq
csinc r3, r2, r4, lt
csinv r3, r4, r4, lt
it ne
csnegne r3, r2, r4, lt
csinv r3, r4, r4, lt

View File

@ -0,0 +1,21 @@
#name: Valid Armv8.1-M Mainline conditional instructions
#source: armv8_1-m-cond.s
#as: -march=armv8.1-m.main
#objdump: -dr --prefix-addresses --show-raw-insn -marmv8.1-m.main
.*: +file format .*arm.*
Disassembly of section .text:
0[0-9a-f]+ <[^>]+> ea5f 940f cset r4, ne
0[0-9a-f]+ <[^>]+> ea5f a40f csetm r4, ne
0[0-9a-f]+ <[^>]+> ea52 93a2 cinc r3, r2, lt
0[0-9a-f]+ <[^>]+> ea52 a3a2 cinv r3, r2, lt
0[0-9a-f]+ <[^>]+> ea52 b3a2 cneg r3, r2, lt
0[0-9a-f]+ <[^>]+> ea52 93b4 csinc r3, r2, r4, lt
0[0-9a-f]+ <[^>]+> ea54 93b4 cinc r3, r4, ge
0[0-9a-f]+ <[^>]+> ea5f 93bf cset r3, ge
0[0-9a-f]+ <[^>]+> ea52 a3b4 csinv r3, r2, r4, lt
0[0-9a-f]+ <[^>]+> ea54 a3b4 cinv r3, r4, ge
0[0-9a-f]+ <[^>]+> ea5f a3bf csetm r3, ge
0[0-9a-f]+ <[^>]+> ea52 b3b4 csneg r3, r2, r4, lt
0[0-9a-f]+ <[^>]+> ea54 b3b4 cneg r3, r4, ge

View File

@ -0,0 +1,17 @@
.syntax unified
.text
foo:
cset r4, ne
csetm r4, ne
cinc r3, r2, lt
cinv r3, r2, lt
cneg r3, r2, lt
csinc r3, r2, r4, lt
csinc r3, r4, r4, lt
csinc r3, zr, zr, lt
csinv r3, r2, r4, lt
csinv r3, r4, r4, lt
csinv r3, zr, zr, lt
csneg r3, r2, r4, lt
csneg r3, r4, r4, lt

View File

@ -1,3 +1,13 @@
2019-05-21 Sudakshina Das <sudi.das@arm.com>
* arm-dis.c (enum mve_instructions): New enum
for csinc, csinv, csneg, csel, cset, csetm, cinv, cinv
and cneg.
(mve_opcodes): New instructions as above.
(is_mve_encoding_conflict): Add cases for csinc, csinv,
csneg and csel.
(print_insn_mve): Accept new %<bitfield>c and %<bitfield>C.
2019-05-21 Sudakshina Das <sudi.das@arm.com>
* arm-dis.c (emun mve_instructions): Updated for new instructions.

View File

@ -281,6 +281,15 @@ enum mve_instructions
MVE_SRSHR,
MVE_SQSHLL,
MVE_SQSHL,
MVE_CINC,
MVE_CINV,
MVE_CNEG,
MVE_CSINC,
MVE_CSINV,
MVE_CSET,
MVE_CSETM,
MVE_CSNEG,
MVE_CSEL,
MVE_NONE
};
@ -2060,6 +2069,8 @@ static const struct opcode32 neon_opcodes[] =
%<bitfield>r print as an ARM register
%<bitfield>d print the bitfield in decimal
%<bitfield>A print accumulate or not
%<bitfield>c print bitfield as a condition code
%<bitfield>C print bitfield as an inverted condition code
%<bitfield>Q print as a MVE Q register
%<bitfield>F print as a MVE S register
%<bitfield>Z as %<>r but r15 is ZR instead of PC and r13 is
@ -3400,6 +3411,51 @@ static const struct mopcode32 mve_opcodes[] =
0xea500f1f, 0xfff08f3f,
"urshr%c\t%16-19S, %j"},
{ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_1M_MAIN),
MVE_CSINC,
0xea509000, 0xfff0f000,
"csinc\t%8-11S, %16-19Z, %0-3Z, %4-7c"},
{ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_1M_MAIN),
MVE_CSINV,
0xea50a000, 0xfff0f000,
"csinv\t%8-11S, %16-19Z, %0-3Z, %4-7c"},
{ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_1M_MAIN),
MVE_CSET,
0xea5f900f, 0xfffff00f,
"cset\t%8-11S, %4-7C"},
{ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_1M_MAIN),
MVE_CSETM,
0xea5fa00f, 0xfffff00f,
"csetm\t%8-11S, %4-7C"},
{ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_1M_MAIN),
MVE_CSEL,
0xea508000, 0xfff0f000,
"csel\t%8-11S, %16-19Z, %0-3Z, %4-7c"},
{ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_1M_MAIN),
MVE_CSNEG,
0xea50b000, 0xfff0f000,
"csneg\t%8-11S, %16-19Z, %0-3Z, %4-7c"},
{ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_1M_MAIN),
MVE_CINC,
0xea509000, 0xfff0f000,
"cinc\t%8-11S, %16-19Z, %4-7C"},
{ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_1M_MAIN),
MVE_CINV,
0xea50a000, 0xfff0f000,
"cinv\t%8-11S, %16-19Z, %4-7C"},
{ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_1M_MAIN),
MVE_CNEG,
0xea50b000, 0xfff0f000,
"cneg\t%8-11S, %16-19Z, %4-7C"},
{ARM_FEATURE_CORE_LOW (0),
MVE_NONE,
0x00000000, 0x00000000, 0}
@ -5653,6 +5709,30 @@ is_mve_encoding_conflict (unsigned long given,
else
return FALSE;
case MVE_CSINC:
case MVE_CSINV:
{
unsigned long rm, rn;
rm = arm_decode_field (given, 0, 3);
rn = arm_decode_field (given, 16, 19);
/* CSET/CSETM. */
if (rm == 0xf && rn == 0xf)
return TRUE;
/* CINC/CINV. */
else if (rn == rm && rn != 0xf)
return TRUE;
}
/* Fall through. */
case MVE_CSEL:
case MVE_CSNEG:
if (arm_decode_field (given, 0, 3) == 0xd)
return TRUE;
/* CNEG. */
else if (matched_insn == MVE_CSNEG)
if (arm_decode_field (given, 0, 3) == arm_decode_field (given, 16, 19))
return TRUE;
return FALSE;
default:
case MVE_VADD_FP_T1:
case MVE_VADD_FP_T2:
@ -9264,6 +9344,15 @@ print_insn_mve (struct disassemble_info *info, long given)
func (stream, "%s", arm_regnames[value]);
break;
case 'c':
func (stream, "%s", arm_conditional[value]);
break;
case 'C':
value ^= 1;
func (stream, "%s", arm_conditional[value]);
break;
case 'S':
if (value == 13 || value == 15)
is_unpredictable = TRUE;