aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Target/ARM/ARMCodeEmitter.cpp2
-rw-r--r--lib/Target/ARM/ARMISelDAGToDAG.cpp6
-rw-r--r--lib/Target/ARM/ARMInstrInfo.td12
-rw-r--r--lib/Target/ARM/ARMInstrThumb2.td4
-rw-r--r--lib/Target/ARM/AsmParser/ARMAsmParser.cpp9
-rw-r--r--lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp2
-rw-r--r--lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h2
-rw-r--r--lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp5
-rw-r--r--test/MC/ARM/basic-arm-instructions.s18
-rw-r--r--test/MC/ARM/diagnostics.s11
10 files changed, 48 insertions, 23 deletions
diff --git a/lib/Target/ARM/ARMCodeEmitter.cpp b/lib/Target/ARM/ARMCodeEmitter.cpp
index 6c10a431d9..e0720b3da8 100644
--- a/lib/Target/ARM/ARMCodeEmitter.cpp
+++ b/lib/Target/ARM/ARMCodeEmitter.cpp
@@ -215,8 +215,6 @@ namespace {
const { return 0; }
unsigned getT2SORegOpValue(const MachineInstr &MI, unsigned Op)
const { return 0; }
- unsigned getImmMinusOneOpValue(const MachineInstr &MI, unsigned Op)
- const { return 0; }
unsigned getT2AdrLabelOpValue(const MachineInstr &MI, unsigned Op)
const { return 0; }
unsigned getAddrMode6AddressOpValue(const MachineInstr &MI, unsigned Op)
diff --git a/lib/Target/ARM/ARMISelDAGToDAG.cpp b/lib/Target/ARM/ARMISelDAGToDAG.cpp
index 928e2efa72..74d877a27f 100644
--- a/lib/Target/ARM/ARMISelDAGToDAG.cpp
+++ b/lib/Target/ARM/ARMISelDAGToDAG.cpp
@@ -2024,7 +2024,8 @@ SDNode *ARMDAGToDAGISel::SelectV6T2BitfieldExtractOp(SDNode *N,
Srl_imm)) {
assert(Srl_imm > 0 && Srl_imm < 32 && "bad amount in shift node!");
- unsigned Width = CountTrailingOnes_32(And_imm);
+ // Note: The width operand is encoded as width-1.
+ unsigned Width = CountTrailingOnes_32(And_imm) - 1;
unsigned LSB = Srl_imm;
SDValue Reg0 = CurDAG->getRegister(0, MVT::i32);
SDValue Ops[] = { N->getOperand(0).getOperand(0),
@@ -2044,7 +2045,8 @@ SDNode *ARMDAGToDAGISel::SelectV6T2BitfieldExtractOp(SDNode *N,
unsigned Srl_imm = 0;
if (isInt32Immediate(N->getOperand(1), Srl_imm)) {
assert(Srl_imm > 0 && Srl_imm < 32 && "bad amount in shift node!");
- unsigned Width = 32 - Srl_imm;
+ // Note: The width operand is encoded as width-1.
+ unsigned Width = 32 - Srl_imm - 1;
int LSB = Srl_imm - Shl_imm;
if (LSB < 0)
return NULL;
diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td
index 4c6bace639..7e9687a7cf 100644
--- a/lib/Target/ARM/ARMInstrInfo.td
+++ b/lib/Target/ARM/ARMInstrInfo.td
@@ -513,14 +513,6 @@ def imm0_31 : Operand<i32>, ImmLeaf<i32, [{
let ParserMatchClass = Imm0_31AsmOperand;
}
-/// imm0_31_m1 - Matches and prints like imm0_31, but encodes as 'value - 1'.
-def imm0_31_m1 : Operand<i32>, ImmLeaf<i32, [{
- return Imm >= 0 && Imm < 32;
-}]> {
- let EncoderMethod = "getImmMinusOneOpValue";
- let DecoderMethod = "DecodeImmMinusOneOperand";
-}
-
// imm0_65535_expr - For movt/movw - 16-bit immediate that can also reference
// a relocatable expression.
//
@@ -2423,7 +2415,7 @@ def UXTAB16 : AI_exta_rrot_np<0b01101100, "uxtab16">;
def SBFX : I<(outs GPR:$Rd),
- (ins GPR:$Rn, imm0_31:$lsb, imm0_31_m1:$width),
+ (ins GPR:$Rn, imm0_31:$lsb, imm1_32:$width),
AddrMode1, 4, IndexModeNone, DPFrm, IIC_iUNAsi,
"sbfx", "\t$Rd, $Rn, $lsb, $width", "", []>,
Requires<[IsARM, HasV6T2]> {
@@ -2440,7 +2432,7 @@ def SBFX : I<(outs GPR:$Rd),
}
def UBFX : I<(outs GPR:$Rd),
- (ins GPR:$Rn, imm0_31:$lsb, imm0_31_m1:$width),
+ (ins GPR:$Rn, imm0_31:$lsb, imm1_32:$width),
AddrMode1, 4, IndexModeNone, DPFrm, IIC_iUNAsi,
"ubfx", "\t$Rd, $Rn, $lsb, $width", "", []>,
Requires<[IsARM, HasV6T2]> {
diff --git a/lib/Target/ARM/ARMInstrThumb2.td b/lib/Target/ARM/ARMInstrThumb2.td
index 7e516b2ce7..b4ca828b26 100644
--- a/lib/Target/ARM/ARMInstrThumb2.td
+++ b/lib/Target/ARM/ARMInstrThumb2.td
@@ -2024,7 +2024,7 @@ def t2BFC : T2BitFI<(outs rGPR:$Rd), (ins rGPR:$src, bf_inv_mask_imm:$imm),
}
def t2SBFX: T2TwoRegBitFI<
- (outs rGPR:$Rd), (ins rGPR:$Rn, imm0_31:$lsb, imm0_31_m1:$msb),
+ (outs rGPR:$Rd), (ins rGPR:$Rn, imm0_31:$lsb, imm1_32:$msb),
IIC_iUNAsi, "sbfx", "\t$Rd, $Rn, $lsb, $msb", []> {
let Inst{31-27} = 0b11110;
let Inst{25} = 1;
@@ -2033,7 +2033,7 @@ def t2SBFX: T2TwoRegBitFI<
}
def t2UBFX: T2TwoRegBitFI<
- (outs rGPR:$Rd), (ins rGPR:$Rn, imm0_31:$lsb, imm0_31_m1:$msb),
+ (outs rGPR:$Rd), (ins rGPR:$Rn, imm0_31:$lsb, imm1_32:$msb),
IIC_iUNAsi, "ubfx", "\t$Rd, $Rn, $lsb, $msb", []> {
let Inst{31-27} = 0b11110;
let Inst{25} = 1;
diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
index a2df19f8f4..352e902009 100644
--- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -2605,6 +2605,15 @@ validateInstruction(MCInst &Inst,
"source operands must be sequential");
return false;
}
+ case ARM::SBFX:
+ case ARM::UBFX: {
+ // width must be in range [1, 32-lsb]
+ unsigned lsb = Inst.getOperand(2).getImm();
+ unsigned widthm1 = Inst.getOperand(3).getImm();
+ if (widthm1 >= 32 - lsb)
+ return Error(Operands[5]->getStartLoc(),
+ "bitfield width must be in range [1,32-lsb]");
+ }
}
return false;
diff --git a/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp b/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp
index f16870054e..1f3920bd8c 100644
--- a/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp
+++ b/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp
@@ -1026,7 +1026,7 @@ static bool DisassembleDPFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRm(insn))));
MI.addOperand(MCOperand::CreateImm(slice(insn, 11, 7)));
- MI.addOperand(MCOperand::CreateImm(slice(insn, 20, 16) + 1));
+ MI.addOperand(MCOperand::CreateImm(slice(insn, 20, 16)));
OpIdx += 3;
return true;
}
diff --git a/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h b/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h
index e534e21375..66a62ef5a5 100644
--- a/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h
+++ b/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h
@@ -1698,7 +1698,7 @@ static bool DisassembleThumb2DPBinImm(MCInst &MI, unsigned Opcode,
assert((Opcode == ARM::t2SBFX || Opcode == ARM::t2UBFX)
&& "Unexpected opcode");
MI.addOperand(MCOperand::CreateImm(getLsb(insn)));
- MI.addOperand(MCOperand::CreateImm(getWidthMinus1(insn) + 1));
+ MI.addOperand(MCOperand::CreateImm(getWidthMinus1(insn)));
++OpIdx;
}
diff --git a/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp b/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp
index 9482a6db1a..4c5e994513 100644
--- a/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp
+++ b/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp
@@ -259,11 +259,6 @@ public:
unsigned getT2SORegOpValue(const MCInst &MI, unsigned Op,
SmallVectorImpl<MCFixup> &Fixups) const;
- unsigned getImmMinusOneOpValue(const MCInst &MI, unsigned Op,
- SmallVectorImpl<MCFixup> &Fixups) const {
- return MI.getOperand(Op).getImm() - 1;
- }
-
unsigned getNEONVcvtImm32OpValue(const MCInst &MI, unsigned Op,
SmallVectorImpl<MCFixup> &Fixups) const {
return 64 - MI.getOperand(Op).getImm();
diff --git a/test/MC/ARM/basic-arm-instructions.s b/test/MC/ARM/basic-arm-instructions.s
index 02ccb9deb0..c08bb83c09 100644
--- a/test/MC/ARM/basic-arm-instructions.s
+++ b/test/MC/ARM/basic-arm-instructions.s
@@ -1309,6 +1309,16 @@ _func:
@------------------------------------------------------------------------------
+@ SBFX
+@------------------------------------------------------------------------------
+ sbfx r4, r5, #16, #1
+ sbfxgt r4, r5, #16, #16
+
+@ CHECK: sbfx r4, r5, #16, #1 @ encoding: [0x55,0x48,0xa0,0xe7]
+@ CHECK: sbfxgt r4, r5, #16, #16 @ encoding: [0x55,0x48,0xaf,0xc7]
+
+
+@------------------------------------------------------------------------------
@ SEL
@------------------------------------------------------------------------------
sel r9, r2, r1
@@ -2001,3 +2011,11 @@ _func:
@ CHECK: uasxeq r9, r12, r0 @ encoding: [0x30,0x9f,0x5c,0x06]
+@------------------------------------------------------------------------------
+@ UBFX
+@------------------------------------------------------------------------------
+ ubfx r4, r5, #16, #1
+ ubfxgt r4, r5, #16, #16
+
+@ CHECK: ubfx r4, r5, #16, #1 @ encoding: [0x55,0x48,0xe0,0xe7]
+@ CHECK: ubfxgt r4, r5, #16, #16 @ encoding: [0x55,0x48,0xef,0xc7]
diff --git a/test/MC/ARM/diagnostics.s b/test/MC/ARM/diagnostics.s
index e086128f42..cc244164a4 100644
--- a/test/MC/ARM/diagnostics.s
+++ b/test/MC/ARM/diagnostics.s
@@ -272,3 +272,14 @@
@ CHECK-ERRORS: error: rotate operator 'ror' expected
@ CHECK-ERRORS: sxtb16ge r2, r3, lsr #24
@ CHECK-ERRORS: ^
+
+ @ Out of range width for SBFX/UBFX
+ sbfx r4, r5, #31, #2
+ ubfxgt r4, r5, #16, #17
+
+@ CHECK-ERRORS: error: bitfield width must be in range [1,32-lsb]
+@ CHECK-ERRORS: sbfx r4, r5, #31, #2
+@ CHECK-ERRORS: ^
+@ CHECK-ERRORS: error: bitfield width must be in range [1,32-lsb]
+@ CHECK-ERRORS: ubfxgt r4, r5, #16, #17
+@ CHECK-ERRORS: ^