diff options
Diffstat (limited to 'lib/Target')
-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 |
3 files changed, 75 insertions, 2 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; +} |