diff options
author | Owen Anderson <resistor@mac.com> | 2011-08-11 20:21:46 +0000 |
---|---|---|
committer | Owen Anderson <resistor@mac.com> | 2011-08-11 20:21:46 +0000 |
commit | 26d2f0ac919f6ae868fe901fd4ad64af6f92da4d (patch) | |
tree | de83d75d66ddbd00de03a252656ce9cdf46d80b8 | |
parent | ade7d00f5afce5f79ca5c1eb1a854b777c8e0194 (diff) |
Continue to tighten decoding by performing more operand validation.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@137340 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Target/ARM/ARMInstrFormats.td | 1 | ||||
-rw-r--r-- | lib/Target/ARM/ARMInstrInfo.td | 66 | ||||
-rw-r--r-- | lib/Target/ARM/Disassembler/ARMDisassembler.cpp | 10 | ||||
-rw-r--r-- | test/MC/Disassembler/ARM/invalid-MSRi-arm.txt | 3 | ||||
-rw-r--r-- | test/MC/Disassembler/ARM/invalid-STMIA_UPD-thumb.txt | 5 | ||||
-rw-r--r-- | test/MC/Disassembler/ARM/invalid-STRBrs-arm.txt | 5 |
6 files changed, 80 insertions, 10 deletions
diff --git a/lib/Target/ARM/ARMInstrFormats.td b/lib/Target/ARM/ARMInstrFormats.td index d7446ffe1a..579f3835bc 100644 --- a/lib/Target/ARM/ARMInstrFormats.td +++ b/lib/Target/ARM/ARMInstrFormats.td @@ -189,6 +189,7 @@ def MSRMaskOperand : AsmOperandClass { } def msr_mask : Operand<i32> { let PrintMethod = "printMSRMaskOperand"; + let DecoderMethod = "DecodeMSRMask"; let ParserMatchClass = MSRMaskOperand; } diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index ae408ce9bc..c8eb025731 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -1259,6 +1259,37 @@ multiclass AI_ldr1<bit isByte, string opc, InstrItinClass iii, } } +let canFoldAsLoad = 1, isReMaterializable = 1 in { +multiclass AI_ldr1nopc<bit isByte, string opc, InstrItinClass iii, + InstrItinClass iir, PatFrag opnode> { + // Note: We use the complex addrmode_imm12 rather than just an input + // GPR and a constrained immediate so that we can use this to match + // frame index references and avoid matching constant pool references. + def i12: AI2ldst<0b010, 1, isByte, (outs GPRnopc:$Rt), (ins addrmode_imm12:$addr), + AddrMode_i12, LdFrm, iii, opc, "\t$Rt, $addr", + [(set GPRnopc:$Rt, (opnode addrmode_imm12:$addr))]> { + bits<4> Rt; + bits<17> addr; + let Inst{23} = addr{12}; // U (add = ('U' == 1)) + let Inst{19-16} = addr{16-13}; // Rn + let Inst{15-12} = Rt; + let Inst{11-0} = addr{11-0}; // imm12 + } + def rs : AI2ldst<0b011, 1, isByte, (outs GPRnopc:$Rt), (ins ldst_so_reg:$shift), + AddrModeNone, LdFrm, iir, opc, "\t$Rt, $shift", + [(set GPRnopc:$Rt, (opnode ldst_so_reg:$shift))]> { + bits<4> Rt; + bits<17> shift; + let shift{4} = 0; // Inst{4} = 0 + let Inst{23} = shift{12}; // U (add = ('U' == 1)) + let Inst{19-16} = shift{16-13}; // Rn + let Inst{15-12} = Rt; + let Inst{11-0} = shift{11-0}; + } +} +} + + multiclass AI_str1<bit isByte, string opc, InstrItinClass iii, InstrItinClass iir, PatFrag opnode> { // Note: We use the complex addrmode_imm12 rather than just an input @@ -1287,6 +1318,37 @@ multiclass AI_str1<bit isByte, string opc, InstrItinClass iii, let Inst{11-0} = shift{11-0}; } } + +multiclass AI_str1nopc<bit isByte, string opc, InstrItinClass iii, + InstrItinClass iir, PatFrag opnode> { + // Note: We use the complex addrmode_imm12 rather than just an input + // GPR and a constrained immediate so that we can use this to match + // frame index references and avoid matching constant pool references. + def i12 : AI2ldst<0b010, 0, isByte, (outs), + (ins GPRnopc:$Rt, addrmode_imm12:$addr), + AddrMode_i12, StFrm, iii, opc, "\t$Rt, $addr", + [(opnode GPRnopc:$Rt, addrmode_imm12:$addr)]> { + bits<4> Rt; + bits<17> addr; + let Inst{23} = addr{12}; // U (add = ('U' == 1)) + let Inst{19-16} = addr{16-13}; // Rn + let Inst{15-12} = Rt; + let Inst{11-0} = addr{11-0}; // imm12 + } + def rs : AI2ldst<0b011, 0, isByte, (outs), (ins GPRnopc:$Rt, ldst_so_reg:$shift), + AddrModeNone, StFrm, iir, opc, "\t$Rt, $shift", + [(opnode GPRnopc:$Rt, ldst_so_reg:$shift)]> { + bits<4> Rt; + bits<17> shift; + let shift{4} = 0; // Inst{4} = 0 + let Inst{23} = shift{12}; // U (add = ('U' == 1)) + let Inst{19-16} = shift{16-13}; // Rn + let Inst{15-12} = Rt; + let Inst{11-0} = shift{11-0}; + } +} + + //===----------------------------------------------------------------------===// // Instructions //===----------------------------------------------------------------------===// @@ -1894,11 +1956,11 @@ def RFEIB_UPD : RFEI<1, "rfeib\t$Rn!"> { defm LDR : AI_ldr1<0, "ldr", IIC_iLoad_r, IIC_iLoad_si, UnOpFrag<(load node:$Src)>>; -defm LDRB : AI_ldr1<1, "ldrb", IIC_iLoad_bh_r, IIC_iLoad_bh_si, +defm LDRB : AI_ldr1nopc<1, "ldrb", IIC_iLoad_bh_r, IIC_iLoad_bh_si, UnOpFrag<(zextloadi8 node:$Src)>>; defm STR : AI_str1<0, "str", IIC_iStore_r, IIC_iStore_si, BinOpFrag<(store node:$LHS, node:$RHS)>>; -defm STRB : AI_str1<1, "strb", IIC_iStore_bh_r, IIC_iStore_bh_si, +defm STRB : AI_str1nopc<1, "strb", IIC_iStore_bh_r, IIC_iStore_bh_si, BinOpFrag<(truncstorei8 node:$LHS, node:$RHS)>>; // Special LDR for loads from non-pc-relative constpools. diff --git a/lib/Target/ARM/Disassembler/ARMDisassembler.cpp b/lib/Target/ARM/Disassembler/ARMDisassembler.cpp index d5994220a0..8cfb21793e 100644 --- a/lib/Target/ARM/Disassembler/ARMDisassembler.cpp +++ b/lib/Target/ARM/Disassembler/ARMDisassembler.cpp @@ -133,6 +133,8 @@ static bool DecodeAddrMode3Offset(llvm::MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder); static bool DecodeMemBarrierOption(llvm::MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder); +static bool DecodeMSRMask(llvm::MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder); static bool DecodeThumbAddSpecialReg(llvm::MCInst &Inst, uint16_t Insn, @@ -759,6 +761,8 @@ static bool DecodeSORegRegOperand(llvm::MCInst &Inst, unsigned Val, static bool DecodeRegListOperand(llvm::MCInst &Inst, unsigned Val, uint64_t Address, const void *Decoder) { + // Empty register lists are not allowed. + if (CountPopulation_32(Val) == 0) return false; for (unsigned i = 0; i < 16; ++i) { if (Val & (1 << i)) { if (!DecodeGPRRegisterClass(Inst, i, Address, Decoder)) return false; @@ -2467,3 +2471,9 @@ static bool DecodeMemBarrierOption(llvm::MCInst &Inst, unsigned Val, return true; } +static bool DecodeMSRMask(llvm::MCInst &Inst, unsigned Val, + uint64_t Address, const void *Decoder) { + if (!Val) return false; + Inst.addOperand(MCOperand::CreateImm(Val)); + return true; +} diff --git a/test/MC/Disassembler/ARM/invalid-MSRi-arm.txt b/test/MC/Disassembler/ARM/invalid-MSRi-arm.txt index 66e74dba19..3765b1f5c0 100644 --- a/test/MC/Disassembler/ARM/invalid-MSRi-arm.txt +++ b/test/MC/Disassembler/ARM/invalid-MSRi-arm.txt @@ -1,8 +1,7 @@ # RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding} -# XFAIL: * # Opcode=206 Name=MSRi Format=ARM_FORMAT_BRFRM(2) -# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 # ------------------------------------------------------------------------------------------------- # | 0: 0: 0: 0| 0: 0: 1: 1| 0: 0: 1: 0| 0: 0: 0: 0| 1: 1: 1: 1| 0: 0: 0: 1| 1: 0: 1: 0| 0: 1: 1: 1| # ------------------------------------------------------------------------------------------------- diff --git a/test/MC/Disassembler/ARM/invalid-STMIA_UPD-thumb.txt b/test/MC/Disassembler/ARM/invalid-STMIA_UPD-thumb.txt index b92ce72833..ca16724c7a 100644 --- a/test/MC/Disassembler/ARM/invalid-STMIA_UPD-thumb.txt +++ b/test/MC/Disassembler/ARM/invalid-STMIA_UPD-thumb.txt @@ -1,11 +1,10 @@ # RUN: llvm-mc --disassemble %s -triple=thumb-apple-darwin9 |& grep {invalid instruction encoding} -# XFAIL: * # Opcode=2313 Name=tSTMIA_UPD Format=ARM_FORMAT_THUMBFRM(25) -# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 # ------------------------------------------------------------------------------------------------- # | 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 1: 1: 0: 0| 0: 1: 1: 1| 0: 0: 0: 0| 0: 0: 0: 0| # ------------------------------------------------------------------------------------------------- -# +# # if BitCount(registers) < 1 then UNPREDICTABLE 0x00 0xc7 diff --git a/test/MC/Disassembler/ARM/invalid-STRBrs-arm.txt b/test/MC/Disassembler/ARM/invalid-STRBrs-arm.txt index 6d570ee016..d3998bdc09 100644 --- a/test/MC/Disassembler/ARM/invalid-STRBrs-arm.txt +++ b/test/MC/Disassembler/ARM/invalid-STRBrs-arm.txt @@ -1,11 +1,10 @@ # RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding} -# XFAIL: * # Opcode=355 Name=STRBrs Format=ARM_FORMAT_STFRM(7) -# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 # ------------------------------------------------------------------------------------------------- # | 1: 1: 1: 0| 0: 1: 1: 1| 1: 1: 0: 0| 1: 1: 1: 1| 1: 1: 1: 1| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| # ------------------------------------------------------------------------------------------------- -# +# # if t == 15 then UNPREDICTABLE 0x00 0xf0 0xcf 0xe7 |