forked from OSchip/llvm-project
ARM Assembly syntax support for arithmetic implied dest operand.
When the destination operand is the same as the first source register operand for arithmetic instructions, the destination operand may be omitted. For example, the following two instructions are equivalent: sub r2, r2, #6 sub r2, #6 rdar://9682597 llvm-svn: 133925
This commit is contained in:
parent
db1ab7dccf
commit
b5ee311602
|
@ -676,7 +676,7 @@ include "ARMInstrFormats.td"
|
|||
/// binop that produces a value.
|
||||
multiclass AsI1_bin_irs<bits<4> opcod, string opc,
|
||||
InstrItinClass iii, InstrItinClass iir, InstrItinClass iis,
|
||||
PatFrag opnode, bit Commutable = 0> {
|
||||
PatFrag opnode, string baseOpc, bit Commutable = 0> {
|
||||
// The register-immediate version is re-materializable. This is useful
|
||||
// in particular for taking the address of a local.
|
||||
let isReMaterializable = 1 in {
|
||||
|
@ -716,6 +716,24 @@ multiclass AsI1_bin_irs<bits<4> opcod, string opc,
|
|||
let Inst{15-12} = Rd;
|
||||
let Inst{11-0} = shift;
|
||||
}
|
||||
|
||||
// Assembly aliases for optional destination operand when it's the same
|
||||
// as the source operand.
|
||||
def : InstAlias<!strconcat(opc, "${s}${p} $Rdn, $imm"),
|
||||
(!cast<Instruction>(!strconcat(baseOpc, "ri")) GPR:$Rdn, GPR:$Rdn,
|
||||
so_imm:$imm, pred:$p,
|
||||
cc_out:$s)>,
|
||||
Requires<[IsARM]>;
|
||||
def : InstAlias<!strconcat(opc, "${s}${p} $Rdn, $Rm"),
|
||||
(!cast<Instruction>(!strconcat(baseOpc, "rr")) GPR:$Rdn, GPR:$Rdn,
|
||||
GPR:$Rm, pred:$p,
|
||||
cc_out:$s)>,
|
||||
Requires<[IsARM]>;
|
||||
def : InstAlias<!strconcat(opc, "${s}${p} $Rdn, $shift"),
|
||||
(!cast<Instruction>(!strconcat(baseOpc, "rs")) GPR:$Rdn, GPR:$Rdn,
|
||||
so_reg:$shift, pred:$p,
|
||||
cc_out:$s)>,
|
||||
Requires<[IsARM]>;
|
||||
}
|
||||
|
||||
/// AI1_bin_s_irs - Similar to AsI1_bin_irs except it sets the 's' bit so the
|
||||
|
@ -2205,10 +2223,10 @@ def UBFX : I<(outs GPR:$Rd),
|
|||
|
||||
defm ADD : AsI1_bin_irs<0b0100, "add",
|
||||
IIC_iALUi, IIC_iALUr, IIC_iALUsr,
|
||||
BinOpFrag<(add node:$LHS, node:$RHS)>, 1>;
|
||||
BinOpFrag<(add node:$LHS, node:$RHS)>, "ADD", 1>;
|
||||
defm SUB : AsI1_bin_irs<0b0010, "sub",
|
||||
IIC_iALUi, IIC_iALUr, IIC_iALUsr,
|
||||
BinOpFrag<(sub node:$LHS, node:$RHS)>>;
|
||||
BinOpFrag<(sub node:$LHS, node:$RHS)>, "SUB">;
|
||||
|
||||
// ADD and SUB with 's' bit set.
|
||||
defm ADDS : AI1_bin_s_irs<0b0100, "adds",
|
||||
|
@ -2531,16 +2549,16 @@ def : ARMV6Pat<(int_arm_usat GPR:$a, imm:$pos), (USAT imm:$pos, GPR:$a, 0)>;
|
|||
|
||||
defm AND : AsI1_bin_irs<0b0000, "and",
|
||||
IIC_iBITi, IIC_iBITr, IIC_iBITsr,
|
||||
BinOpFrag<(and node:$LHS, node:$RHS)>, 1>;
|
||||
BinOpFrag<(and node:$LHS, node:$RHS)>, "AND", 1>;
|
||||
defm ORR : AsI1_bin_irs<0b1100, "orr",
|
||||
IIC_iBITi, IIC_iBITr, IIC_iBITsr,
|
||||
BinOpFrag<(or node:$LHS, node:$RHS)>, 1>;
|
||||
BinOpFrag<(or node:$LHS, node:$RHS)>, "ORR", 1>;
|
||||
defm EOR : AsI1_bin_irs<0b0001, "eor",
|
||||
IIC_iBITi, IIC_iBITr, IIC_iBITsr,
|
||||
BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>;
|
||||
BinOpFrag<(xor node:$LHS, node:$RHS)>, "EOR", 1>;
|
||||
defm BIC : AsI1_bin_irs<0b1110, "bic",
|
||||
IIC_iBITi, IIC_iBITr, IIC_iBITsr,
|
||||
BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
|
||||
BinOpFrag<(and node:$LHS, (not node:$RHS))>, "BIC">;
|
||||
|
||||
def BFC : I<(outs GPR:$Rd), (ins GPR:$src, bf_inv_mask_imm:$imm),
|
||||
AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
|
||||
|
|
|
@ -0,0 +1,126 @@
|
|||
@ RUN: llvm-mc -triple arm-unknown-unknown -show-encoding < %s | FileCheck %s
|
||||
|
||||
foo:
|
||||
@ CHECK: foo
|
||||
|
||||
sub r2, r2, #6
|
||||
sub r2, #6
|
||||
sub r2, r2, r3
|
||||
sub r2, r3
|
||||
|
||||
@ CHECK: sub r2, r2, #6 @ encoding: [0x06,0x20,0x42,0xe2]
|
||||
@ CHECK: sub r2, r2, #6 @ encoding: [0x06,0x20,0x42,0xe2]
|
||||
@ CHECK: sub r2, r2, r3 @ encoding: [0x03,0x20,0x42,0xe0]
|
||||
@ CHECK: sub r2, r2, r3 @ encoding: [0x03,0x20,0x42,0xe0]
|
||||
|
||||
add r2, r2, #6
|
||||
add r2, #6
|
||||
add r2, r2, r3
|
||||
add r2, r3
|
||||
|
||||
@ CHECK: add r2, r2, #6 @ encoding: [0x06,0x20,0x82,0xe2]
|
||||
@ CHECK: add r2, r2, #6 @ encoding: [0x06,0x20,0x82,0xe2]
|
||||
@ CHECK: add r2, r2, r3 @ encoding: [0x03,0x20,0x82,0xe0]
|
||||
@ CHECK: add r2, r2, r3 @ encoding: [0x03,0x20,0x82,0xe0]
|
||||
|
||||
and r2, r2, #6
|
||||
and r2, #6
|
||||
and r2, r2, r3
|
||||
and r2, r3
|
||||
|
||||
@ CHECK: and r2, r2, #6 @ encoding: [0x06,0x20,0x02,0xe2]
|
||||
@ CHECK: and r2, r2, #6 @ encoding: [0x06,0x20,0x02,0xe2]
|
||||
@ CHECK: and r2, r2, r3 @ encoding: [0x03,0x20,0x02,0xe0]
|
||||
@ CHECK: and r2, r2, r3 @ encoding: [0x03,0x20,0x02,0xe0]
|
||||
|
||||
orr r2, r2, #6
|
||||
orr r2, #6
|
||||
orr r2, r2, r3
|
||||
orr r2, r3
|
||||
|
||||
@ CHECK: orr r2, r2, #6 @ encoding: [0x06,0x20,0x82,0xe3]
|
||||
@ CHECK: orr r2, r2, #6 @ encoding: [0x06,0x20,0x82,0xe3]
|
||||
@ CHECK: orr r2, r2, r3 @ encoding: [0x03,0x20,0x82,0xe1]
|
||||
@ CHECK: orr r2, r2, r3 @ encoding: [0x03,0x20,0x82,0xe1]
|
||||
|
||||
eor r2, r2, #6
|
||||
eor r2, #6
|
||||
eor r2, r2, r3
|
||||
eor r2, r3
|
||||
|
||||
@ CHECK: eor r2, r2, #6 @ encoding: [0x06,0x20,0x22,0xe2]
|
||||
@ CHECK: eor r2, r2, #6 @ encoding: [0x06,0x20,0x22,0xe2]
|
||||
@ CHECK: eor r2, r2, r3 @ encoding: [0x03,0x20,0x22,0xe0]
|
||||
@ CHECK: eor r2, r2, r3 @ encoding: [0x03,0x20,0x22,0xe0]
|
||||
|
||||
bic r2, r2, #6
|
||||
bic r2, #6
|
||||
bic r2, r2, r3
|
||||
bic r2, r3
|
||||
|
||||
@ CHECK: bic r2, r2, #6 @ encoding: [0x06,0x20,0xc2,0xe3]
|
||||
@ CHECK: bic r2, r2, #6 @ encoding: [0x06,0x20,0xc2,0xe3]
|
||||
@ CHECK: bic r2, r2, r3 @ encoding: [0x03,0x20,0xc2,0xe1]
|
||||
@ CHECK: bic r2, r2, r3 @ encoding: [0x03,0x20,0xc2,0xe1]
|
||||
|
||||
|
||||
@ Also check that we handle the predicate and cc_out operands.
|
||||
subseq r2, r2, #6
|
||||
subseq r2, #6
|
||||
subseq r2, r2, r3
|
||||
subseq r2, r3
|
||||
|
||||
@ CHECK: subseq r2, r2, #6 @ encoding: [0x06,0x20,0x52,0x02]
|
||||
@ CHECK: subseq r2, r2, #6 @ encoding: [0x06,0x20,0x52,0x02]
|
||||
@ CHECK: subseq r2, r2, r3 @ encoding: [0x03,0x20,0x52,0x00]
|
||||
@ CHECK: subseq r2, r2, r3 @ encoding: [0x03,0x20,0x52,0x00]
|
||||
|
||||
addseq r2, r2, #6
|
||||
addseq r2, #6
|
||||
addseq r2, r2, r3
|
||||
addseq r2, r3
|
||||
|
||||
@ CHECK: addseq r2, r2, #6 @ encoding: [0x06,0x20,0x92,0x02]
|
||||
@ CHECK: addseq r2, r2, #6 @ encoding: [0x06,0x20,0x92,0x02]
|
||||
@ CHECK: addseq r2, r2, r3 @ encoding: [0x03,0x20,0x92,0x00]
|
||||
@ CHECK: addseq r2, r2, r3 @ encoding: [0x03,0x20,0x92,0x00]
|
||||
|
||||
andseq r2, r2, #6
|
||||
andseq r2, #6
|
||||
andseq r2, r2, r3
|
||||
andseq r2, r3
|
||||
|
||||
@ CHECK: andseq r2, r2, #6 @ encoding: [0x06,0x20,0x12,0x02]
|
||||
@ CHECK: andseq r2, r2, #6 @ encoding: [0x06,0x20,0x12,0x02]
|
||||
@ CHECK: andseq r2, r2, r3 @ encoding: [0x03,0x20,0x12,0x00]
|
||||
@ CHECK: andseq r2, r2, r3 @ encoding: [0x03,0x20,0x12,0x00]
|
||||
|
||||
orrseq r2, r2, #6
|
||||
orrseq r2, #6
|
||||
orrseq r2, r2, r3
|
||||
orrseq r2, r3
|
||||
|
||||
@ CHECK: orrseq r2, r2, #6 @ encoding: [0x06,0x20,0x92,0x03]
|
||||
@ CHECK: orrseq r2, r2, #6 @ encoding: [0x06,0x20,0x92,0x03]
|
||||
@ CHECK: orrseq r2, r2, r3 @ encoding: [0x03,0x20,0x92,0x01]
|
||||
@ CHECK: orrseq r2, r2, r3 @ encoding: [0x03,0x20,0x92,0x01]
|
||||
|
||||
eorseq r2, r2, #6
|
||||
eorseq r2, #6
|
||||
eorseq r2, r2, r3
|
||||
eorseq r2, r3
|
||||
|
||||
@ CHECK: eorseq r2, r2, #6 @ encoding: [0x06,0x20,0x32,0x02]
|
||||
@ CHECK: eorseq r2, r2, #6 @ encoding: [0x06,0x20,0x32,0x02]
|
||||
@ CHECK: eorseq r2, r2, r3 @ encoding: [0x03,0x20,0x32,0x00]
|
||||
@ CHECK: eorseq r2, r2, r3 @ encoding: [0x03,0x20,0x32,0x00]
|
||||
|
||||
bicseq r2, r2, #6
|
||||
bicseq r2, #6
|
||||
bicseq r2, r2, r3
|
||||
bicseq r2, r3
|
||||
|
||||
@ CHECK: bicseq r2, r2, #6 @ encoding: [0x06,0x20,0xd2,0x03]
|
||||
@ CHECK: bicseq r2, r2, #6 @ encoding: [0x06,0x20,0xd2,0x03]
|
||||
@ CHECK: bicseq r2, r2, r3 @ encoding: [0x03,0x20,0xd2,0x01]
|
||||
@ CHECK: bicseq r2, r2, r3 @ encoding: [0x03,0x20,0xd2,0x01]
|
Loading…
Reference in New Issue