[llvm-commits] [llvm] r128632 - in /llvm/trunk: lib/Target/ARM/ARMAddressingModes.h lib/Target/ARM/ARMBaseInfo.h lib/Target/ARM/ARMBaseInstrInfo.h lib/Target/ARM/ARMInstrFormats.td lib/Target/ARM/ARMInstrInfo.td lib/Target/ARM/AsmParser/ARMAsmParser.cpp lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp lib/Target/ARM/InstPrinter/ARMInstPrinter.h test/MC/ARM/arm_addrmode2.s
Devang Patel
dpatel at apple.com
Thu Mar 31 08:34:56 PDT 2011
Bruno,
This is causing clang test failures.
LLVM :: CodeGen/ARM/ldr_post.ll
LLVM :: CodeGen/ARM/ldst-f32-2-i32.ll
LLVM :: CodeGen/ARM/str_pre-2.ll
Can you take a look ?
Thanks,
-
Devang
On Mar 31, 2011, at 7:52 AM, Bruno Cardoso Lopes wrote:
> Author: bruno
> Date: Thu Mar 31 09:52:28 2011
> New Revision: 128632
>
> URL: http://llvm.org/viewvc/llvm-project?rev=128632&view=rev
> Log:
> Reapply r128585 without generating a lib depedency cycle. An updated log:
>
> - Implement asm parsing support for LDRT, LDRBT, STRT, STRBT and
> {STR,LDC}{2}_{PRE,POST} fixing the encoding wherever is possible.
> - Move all instructions which use am2offset without a pattern to use
> addrmode2.
> - Add a new encoding bit to describe the index mode used and teach
> printAddrMode2Operand to check by the addressing mode which index
> mode to print.
> - Testcases
>
> Added:
> llvm/trunk/test/MC/ARM/arm_addrmode2.s
> Modified:
> llvm/trunk/lib/Target/ARM/ARMAddressingModes.h
> llvm/trunk/lib/Target/ARM/ARMBaseInfo.h
> llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h
> llvm/trunk/lib/Target/ARM/ARMInstrFormats.td
> llvm/trunk/lib/Target/ARM/ARMInstrInfo.td
> llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
> llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp
> llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp
> llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.h
>
> Modified: llvm/trunk/lib/Target/ARM/ARMAddressingModes.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMAddressingModes.h?rev=128632&r1=128631&r2=128632&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/ARM/ARMAddressingModes.h (original)
> +++ llvm/trunk/lib/Target/ARM/ARMAddressingModes.h Thu Mar 31 09:52:28 2011
> @@ -408,16 +408,18 @@
> //
> // The first operand is always a Reg. The second operand is a reg if in
> // reg/reg form, otherwise it's reg#0. The third field encodes the operation
> - // in bit 12, the immediate in bits 0-11, and the shift op in 13-15.
> + // in bit 12, the immediate in bits 0-11, and the shift op in 13-15. The
> + // forth operand 16-17 encodes the index mode.
> //
> // If this addressing mode is a frame index (before prolog/epilog insertion
> // and code rewriting), this operand will have the form: FI#, reg0, <offs>
> // with no shift amount for the frame offset.
> //
> - static inline unsigned getAM2Opc(AddrOpc Opc, unsigned Imm12, ShiftOpc SO) {
> + static inline unsigned getAM2Opc(AddrOpc Opc, unsigned Imm12, ShiftOpc SO,
> + unsigned IdxMode = 0) {
> assert(Imm12 < (1 << 12) && "Imm too large!");
> bool isSub = Opc == sub;
> - return Imm12 | ((int)isSub << 12) | (SO << 13);
> + return Imm12 | ((int)isSub << 12) | (SO << 13) | (IdxMode << 16) ;
> }
> static inline unsigned getAM2Offset(unsigned AM2Opc) {
> return AM2Opc & ((1 << 12)-1);
> @@ -426,7 +428,10 @@
> return ((AM2Opc >> 12) & 1) ? sub : add;
> }
> static inline ShiftOpc getAM2ShiftOpc(unsigned AM2Opc) {
> - return (ShiftOpc)(AM2Opc >> 13);
> + return (ShiftOpc)((AM2Opc >> 13) & 7);
> + }
> + static inline unsigned getAM2IdxMode(unsigned AM2Opc) {
> + return (AM2Opc >> 16);
> }
>
>
>
> Modified: llvm/trunk/lib/Target/ARM/ARMBaseInfo.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBaseInfo.h?rev=128632&r1=128631&r2=128632&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/ARM/ARMBaseInfo.h (original)
> +++ llvm/trunk/lib/Target/ARM/ARMBaseInfo.h Thu Mar 31 09:52:28 2011
> @@ -200,6 +200,59 @@
> }
>
> namespace ARMII {
> +
> + /// ARM Index Modes
> + enum IndexMode {
> + IndexModeNone = 0,
> + IndexModePre = 1,
> + IndexModePost = 2,
> + IndexModeUpd = 3
> + };
> +
> + /// ARM Addressing Modes
> + enum AddrMode {
> + AddrModeNone = 0,
> + AddrMode1 = 1,
> + AddrMode2 = 2,
> + AddrMode3 = 3,
> + AddrMode4 = 4,
> + AddrMode5 = 5,
> + AddrMode6 = 6,
> + AddrModeT1_1 = 7,
> + AddrModeT1_2 = 8,
> + AddrModeT1_4 = 9,
> + AddrModeT1_s = 10, // i8 * 4 for pc and sp relative data
> + AddrModeT2_i12 = 11,
> + AddrModeT2_i8 = 12,
> + AddrModeT2_so = 13,
> + AddrModeT2_pc = 14, // +/- i12 for pc relative data
> + AddrModeT2_i8s4 = 15, // i8 * 4
> + AddrMode_i12 = 16
> + };
> +
> + inline static const char *AddrModeToString(AddrMode addrmode) {
> + switch (addrmode) {
> + default: llvm_unreachable("Unknown memory operation");
> + case AddrModeNone: return "AddrModeNone";
> + case AddrMode1: return "AddrMode1";
> + case AddrMode2: return "AddrMode2";
> + case AddrMode3: return "AddrMode3";
> + case AddrMode4: return "AddrMode4";
> + case AddrMode5: return "AddrMode5";
> + case AddrMode6: return "AddrMode6";
> + case AddrModeT1_1: return "AddrModeT1_1";
> + case AddrModeT1_2: return "AddrModeT1_2";
> + case AddrModeT1_4: return "AddrModeT1_4";
> + case AddrModeT1_s: return "AddrModeT1_s";
> + case AddrModeT2_i12: return "AddrModeT2_i12";
> + case AddrModeT2_i8: return "AddrModeT2_i8";
> + case AddrModeT2_so: return "AddrModeT2_so";
> + case AddrModeT2_pc: return "AddrModeT2_pc";
> + case AddrModeT2_i8s4: return "AddrModeT2_i8s4";
> + case AddrMode_i12: return "AddrMode_i12";
> + }
> + }
> +
> /// Target Operand Flag enum.
> enum TOF {
> //===------------------------------------------------------------------===//
>
> Modified: llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h?rev=128632&r1=128631&r2=128632&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h (original)
> +++ llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h Thu Mar 31 09:52:28 2011
> @@ -34,25 +34,7 @@
>
> //===------------------------------------------------------------------===//
> // This four-bit field describes the addressing mode used.
> -
> - AddrModeMask = 0x1f,
> - AddrModeNone = 0,
> - AddrMode1 = 1,
> - AddrMode2 = 2,
> - AddrMode3 = 3,
> - AddrMode4 = 4,
> - AddrMode5 = 5,
> - AddrMode6 = 6,
> - AddrModeT1_1 = 7,
> - AddrModeT1_2 = 8,
> - AddrModeT1_4 = 9,
> - AddrModeT1_s = 10, // i8 * 4 for pc and sp relative data
> - AddrModeT2_i12 = 11,
> - AddrModeT2_i8 = 12,
> - AddrModeT2_so = 13,
> - AddrModeT2_pc = 14, // +/- i12 for pc relative data
> - AddrModeT2_i8s4 = 15, // i8 * 4
> - AddrMode_i12 = 16,
> + AddrModeMask = 0x1f, // The AddrMode enums are declared in ARMBaseInfo.h
>
> // Size* - Flags to keep track of the size of an instruction.
> SizeShift = 5,
> @@ -64,11 +46,9 @@
>
> // IndexMode - Unindex, pre-indexed, or post-indexed are valid for load
> // and store ops only. Generic "updating" flag is used for ld/st multiple.
> + // The index mode enums are declared in ARMBaseInfo.h
> IndexModeShift = 8,
> IndexModeMask = 3 << IndexModeShift,
> - IndexModePre = 1,
> - IndexModePost = 2,
> - IndexModeUpd = 3,
>
> //===------------------------------------------------------------------===//
> // Instruction encoding formats.
>
> Modified: llvm/trunk/lib/Target/ARM/ARMInstrFormats.td
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrFormats.td?rev=128632&r1=128631&r2=128632&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/ARM/ARMInstrFormats.td (original)
> +++ llvm/trunk/lib/Target/ARM/ARMInstrFormats.td Thu Mar 31 09:52:28 2011
> @@ -515,15 +515,15 @@
> : AI2ldstidx<0, isByte, isPre, oops, iops, im, f, itin, opc, asm, cstr,
> pattern> {
> // AM2 store w/ two operands: (GPR, am2offset)
> + // {17-14} Rn
> // {13} 1 == Rm, 0 == imm12
> // {12} isAdd
> // {11-0} imm12/Rm
> - bits<14> offset;
> - bits<4> Rn;
> - let Inst{25} = offset{13};
> - let Inst{23} = offset{12};
> - let Inst{19-16} = Rn;
> - let Inst{11-0} = offset{11-0};
> + bits<18> addr;
> + let Inst{25} = addr{13};
> + let Inst{23} = addr{12};
> + let Inst{19-16} = addr{17-14};
> + let Inst{11-0} = addr{11-0};
> }
>
> // addrmode3 instructions
>
> Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=128632&r1=128631&r2=128632&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original)
> +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Thu Mar 31 09:52:28 2011
> @@ -498,6 +498,12 @@
> let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
> }
>
> +def MemMode2AsmOperand : AsmOperandClass {
> + let Name = "MemMode2";
> + let SuperClasses = [];
> + let ParserMethod = "tryParseMemMode2Operand";
> +}
> +
> // addrmode2 := reg +/- imm12
> // := reg +/- reg shop imm
> //
> @@ -505,6 +511,7 @@
> ComplexPattern<i32, 3, "SelectAddrMode2", []> {
> let EncoderMethod = "getAddrMode2OpValue";
> let PrintMethod = "printAddrMode2Operand";
> + let ParserMatchClass = MemMode2AsmOperand;
> let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
> }
>
> @@ -1656,20 +1663,21 @@
> let Inst{23} = addr{12};
> let Inst{19-16} = addr{17-14};
> let Inst{11-0} = addr{11-0};
> + let AsmMatchConverter = "CvtLdWriteBackRegAddrMode2";
> }
> def _POST : AI2ldstidx<1, isByte, 0, (outs GPR:$Rt, GPR:$Rn_wb),
> - (ins GPR:$Rn, am2offset:$offset),
> - IndexModePost, LdFrm, itin,
> - opc, "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb", []> {
> + (ins addrmode2:$addr), IndexModePost, LdFrm, itin,
> + opc, "\t$Rt, $addr", "$addr.base = $Rn_wb", []> {
> + // {17-14} Rn
> // {13} 1 == Rm, 0 == imm12
> // {12} isAdd
> // {11-0} imm12/Rm
> - bits<14> offset;
> - bits<4> Rn;
> - let Inst{25} = offset{13};
> - let Inst{23} = offset{12};
> - let Inst{19-16} = Rn;
> - let Inst{11-0} = offset{11-0};
> + bits<18> addr;
> + let Inst{25} = addr{13};
> + let Inst{23} = addr{12};
> + let Inst{19-16} = addr{17-14};
> + let Inst{11-0} = addr{11-0};
> + let AsmMatchConverter = "CvtLdWriteBackRegAddrMode2";
> }
> }
>
> @@ -1714,17 +1722,35 @@
>
> // LDRT, LDRBT, LDRSBT, LDRHT, LDRSHT are for disassembly only.
> let mayLoad = 1, neverHasSideEffects = 1 in {
> -def LDRT : AI2ldstidx<1, 0, 0, (outs GPR:$dst, GPR:$base_wb),
> - (ins GPR:$base, am2offset:$offset), IndexModePost,
> - LdFrm, IIC_iLoad_ru,
> - "ldrt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
> +def LDRT : AI2ldstidx<1, 0, 0, (outs GPR:$Rt, GPR:$base_wb),
> + (ins addrmode2:$addr), IndexModePost, LdFrm, IIC_iLoad_ru,
> + "ldrt", "\t$Rt, $addr", "$addr.base = $base_wb", []> {
> + // {17-14} Rn
> + // {13} 1 == Rm, 0 == imm12
> + // {12} isAdd
> + // {11-0} imm12/Rm
> + bits<18> addr;
> + let Inst{25} = addr{13};
> + let Inst{23} = addr{12};
> let Inst{21} = 1; // overwrite
> -}
> -def LDRBT : AI2ldstidx<1, 1, 0, (outs GPR:$dst, GPR:$base_wb),
> - (ins GPR:$base, am2offset:$offset), IndexModePost,
> - LdFrm, IIC_iLoad_bh_ru,
> - "ldrbt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
> + let Inst{19-16} = addr{17-14};
> + let Inst{11-0} = addr{11-0};
> + let AsmMatchConverter = "CvtLdWriteBackRegAddrMode2";
> +}
> +def LDRBT : AI2ldstidx<1, 1, 0, (outs GPR:$Rt, GPR:$base_wb),
> + (ins addrmode2:$addr), IndexModePost, LdFrm, IIC_iLoad_bh_ru,
> + "ldrbt", "\t$Rt, $addr", "$addr.base = $base_wb", []> {
> + // {17-14} Rn
> + // {13} 1 == Rm, 0 == imm12
> + // {12} isAdd
> + // {11-0} imm12/Rm
> + bits<18> addr;
> + let Inst{25} = addr{13};
> + let Inst{23} = addr{12};
> let Inst{21} = 1; // overwrite
> + let Inst{19-16} = addr{17-14};
> + let Inst{11-0} = addr{11-0};
> + let AsmMatchConverter = "CvtLdWriteBackRegAddrMode2";
> }
> def LDRSBT : AI3ldstidx<0b1101, 1, 1, 0, (outs GPR:$dst, GPR:$base_wb),
> (ins GPR:$base, am3offset:$offset), IndexModePost,
> @@ -1818,20 +1844,20 @@
>
> // STRT, STRBT, and STRHT are for disassembly only.
>
> -def STRT : AI2stridx<0, 0, (outs GPR:$Rn_wb),
> - (ins GPR:$Rt, GPR:$Rn,am2offset:$offset),
> +def STRT : AI2stridx<0, 0, (outs GPR:$Rn_wb), (ins GPR:$Rt, addrmode2:$addr),
> IndexModePost, StFrm, IIC_iStore_ru,
> - "strt", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb",
> + "strt", "\t$Rt, $addr", "$addr.base = $Rn_wb",
> [/* For disassembly only; pattern left blank */]> {
> let Inst{21} = 1; // overwrite
> + let AsmMatchConverter = "CvtStWriteBackRegAddrMode2";
> }
>
> -def STRBT : AI2stridx<1, 0, (outs GPR:$Rn_wb),
> - (ins GPR:$Rt, GPR:$Rn, am2offset:$offset),
> +def STRBT : AI2stridx<1, 0, (outs GPR:$Rn_wb), (ins GPR:$Rt, addrmode2:$addr),
> IndexModePost, StFrm, IIC_iStore_bh_ru,
> - "strbt", "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb",
> + "strbt", "\t$Rt, $addr", "$addr.base = $Rn_wb",
> [/* For disassembly only; pattern left blank */]> {
> let Inst{21} = 1; // overwrite
> + let AsmMatchConverter = "CvtStWriteBackRegAddrMode2";
> }
>
> def STRHT: AI3sthpo<(outs GPR:$base_wb),
> @@ -3391,8 +3417,9 @@
> let Inst{23-20} = opc1;
> }
>
> -class ACI<dag oops, dag iops, string opc, string asm>
> - : I<oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, BrFrm, NoItinerary,
> +class ACI<dag oops, dag iops, string opc, string asm,
> + IndexMode im = IndexModeNone>
> + : I<oops, iops, AddrModeNone, Size4Bytes, im, BrFrm, NoItinerary,
> opc, asm, "", [/* For disassembly only; pattern left blank */]> {
> let Inst{27-25} = 0b110;
> }
> @@ -3411,7 +3438,7 @@
>
> def _PRE : ACI<(outs),
> (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
> - opc, "\tp$cop, cr$CRd, $addr!"> {
> + opc, "\tp$cop, cr$CRd, $addr!", IndexModePre> {
> let Inst{31-28} = op31_28;
> let Inst{24} = 1; // P = 1
> let Inst{21} = 1; // W = 1
> @@ -3420,8 +3447,8 @@
> }
>
> def _POST : ACI<(outs),
> - (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset),
> - opc, "\tp$cop, cr$CRd, [$base], $offset"> {
> + (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
> + opc, "\tp$cop, cr$CRd, $addr", IndexModePost> {
> let Inst{31-28} = op31_28;
> let Inst{24} = 0; // P = 0
> let Inst{21} = 1; // W = 1
> @@ -3452,7 +3479,7 @@
>
> def L_PRE : ACI<(outs),
> (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
> - !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr!"> {
> + !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr!", IndexModePre> {
> let Inst{31-28} = op31_28;
> let Inst{24} = 1; // P = 1
> let Inst{21} = 1; // W = 1
> @@ -3461,8 +3488,8 @@
> }
>
> def L_POST : ACI<(outs),
> - (ins nohash_imm:$cop, nohash_imm:$CRd, GPR:$base, am2offset:$offset),
> - !strconcat(opc, "l"), "\tp$cop, cr$CRd, [$base], $offset"> {
> + (ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr),
> + !strconcat(opc, "l"), "\tp$cop, cr$CRd, $addr", IndexModePost> {
> let Inst{31-28} = op31_28;
> let Inst{24} = 0; // P = 0
> let Inst{21} = 1; // W = 1
>
> Modified: llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp?rev=128632&r1=128631&r2=128632&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp (original)
> +++ llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp Thu Mar 31 09:52:28 2011
> @@ -48,7 +48,8 @@
> bool TryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &);
> bool TryParseShiftRegister(SmallVectorImpl<MCParsedAsmOperand*> &);
> bool ParseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &);
> - bool ParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &);
> + bool ParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &,
> + ARMII::AddrMode AddrMode);
> bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &, StringRef Mnemonic);
> bool ParsePrefix(ARMMCExpr::VariantKind &RefKind);
> const MCExpr *ApplyPrefixToExpr(const MCExpr *E,
> @@ -95,6 +96,14 @@
> SmallVectorImpl<MCParsedAsmOperand*>&);
> OperandMatchResultTy tryParseMSRMaskOperand(
> SmallVectorImpl<MCParsedAsmOperand*>&);
> + OperandMatchResultTy tryParseMemMode2Operand(
> + SmallVectorImpl<MCParsedAsmOperand*>&);
> +
> + // Asm Match Converter Methods
> + bool CvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
> + const SmallVectorImpl<MCParsedAsmOperand*> &);
> + bool CvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
> + const SmallVectorImpl<MCParsedAsmOperand*> &);
>
> public:
> ARMAsmParser(const Target &T, MCAsmParser &_Parser, TargetMachine &_TM)
> @@ -172,6 +181,7 @@
>
> /// Combined record for all forms of ARM address expressions.
> struct {
> + ARMII::AddrMode AddrMode;
> unsigned BaseRegNum;
> union {
> unsigned RegNum; ///< Offset register num, when OffsetIsReg.
> @@ -293,7 +303,9 @@
>
> /// @name Memory Operand Accessors
> /// @{
> -
> + ARMII::AddrMode getMemAddrMode() const {
> + return Mem.AddrMode;
> + }
> unsigned getMemBaseRegNum() const {
> return Mem.BaseRegNum;
> }
> @@ -338,6 +350,27 @@
> bool isMemBarrierOpt() const { return Kind == MemBarrierOpt; }
> bool isMemory() const { return Kind == Memory; }
> bool isShifter() const { return Kind == Shifter; }
> + bool isMemMode2() const {
> + if (getMemAddrMode() != ARMII::AddrMode2)
> + return false;
> +
> + if (getMemOffsetIsReg())
> + return true;
> +
> + if (getMemNegative() &&
> + !(getMemPostindexed() || getMemPreindexed()))
> + return false;
> +
> + const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
> + if (!CE) return false;
> + int64_t Value = CE->getValue();
> +
> + // The offset must be in the range 0-4095 (imm12).
> + if (Value > 4095 || Value < -4095)
> + return false;
> +
> + return true;
> + }
> bool isMemMode5() const {
> if (!isMemory() || getMemOffsetIsReg() || getMemWriteback() ||
> getMemNegative())
> @@ -465,6 +498,47 @@
> "No offset operand support in mode 7");
> }
>
> + void addMemMode2Operands(MCInst &Inst, unsigned N) const {
> + assert(isMemMode2() && "Invalid mode or number of operands!");
> + Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum()));
> + unsigned IdxMode = (getMemPreindexed() | getMemPostindexed() << 1);
> +
> + if (getMemOffsetIsReg()) {
> + Inst.addOperand(MCOperand::CreateReg(getMemOffsetRegNum()));
> +
> + ARM_AM::AddrOpc AMOpc = getMemNegative() ? ARM_AM::sub : ARM_AM::add;
> + ARM_AM::ShiftOpc ShOpc = ARM_AM::no_shift;
> + int64_t ShiftAmount = 0;
> +
> + if (getMemOffsetRegShifted()) {
> + ShOpc = getMemShiftType();
> + const MCConstantExpr *CE =
> + dyn_cast<MCConstantExpr>(getMemShiftAmount());
> + ShiftAmount = CE->getValue();
> + }
> +
> + Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(AMOpc, ShiftAmount,
> + ShOpc, IdxMode)));
> + return;
> + }
> +
> + // Create a operand placeholder to always yield the same number of operands.
> + Inst.addOperand(MCOperand::CreateReg(0));
> +
> + // FIXME: #-0 is encoded differently than #0. Does the parser preserve
> + // the difference?
> + const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
> + assert(CE && "Non-constant mode 2 offset operand!");
> + int64_t Offset = CE->getValue();
> +
> + if (Offset >= 0)
> + Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(ARM_AM::add,
> + Offset, ARM_AM::no_shift, IdxMode)));
> + else
> + Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(ARM_AM::sub,
> + -Offset, ARM_AM::no_shift, IdxMode)));
> + }
> +
> void addMemMode5Operands(MCInst &Inst, unsigned N) const {
> assert(N == 2 && isMemMode5() && "Invalid number of operands!");
>
> @@ -599,9 +673,9 @@
> return Op;
> }
>
> - static ARMOperand *CreateMem(unsigned BaseRegNum, bool OffsetIsReg,
> - const MCExpr *Offset, int OffsetRegNum,
> - bool OffsetRegShifted,
> + static ARMOperand *CreateMem(ARMII::AddrMode AddrMode, unsigned BaseRegNum,
> + bool OffsetIsReg, const MCExpr *Offset,
> + int OffsetRegNum, bool OffsetRegShifted,
> enum ARM_AM::ShiftOpc ShiftType,
> const MCExpr *ShiftAmount, bool Preindexed,
> bool Postindexed, bool Negative, bool Writeback,
> @@ -618,6 +692,7 @@
> "Cannot have expression offset and register offset!");
>
> ARMOperand *Op = new ARMOperand(Memory);
> + Op->Mem.AddrMode = AddrMode;
> Op->Mem.BaseRegNum = BaseRegNum;
> Op->Mem.OffsetIsReg = OffsetIsReg;
> if (OffsetIsReg)
> @@ -689,7 +764,8 @@
> break;
> case Memory:
> OS << "<memory "
> - << "base:" << getMemBaseRegNum();
> + << "am:" << ARMII::AddrModeToString(getMemAddrMode())
> + << " base:" << getMemBaseRegNum();
> if (getMemOffsetIsReg()) {
> OS << " offset:<register " << getMemOffsetRegNum();
> if (getMemOffsetRegShifted()) {
> @@ -1132,13 +1208,57 @@
> return MatchOperand_Success;
> }
>
> +/// tryParseMemMode2Operand - Try to parse memory addressing mode 2 operand.
> +ARMAsmParser::OperandMatchResultTy ARMAsmParser::
> +tryParseMemMode2Operand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
> + SMLoc S = Parser.getTok().getLoc();
> + const AsmToken &Tok = Parser.getTok();
> + assert(Tok.is(AsmToken::LBrac) && "Token is not a \"[\"");
> +
> + if (ParseMemory(Operands, ARMII::AddrMode2))
> + return MatchOperand_NoMatch;
> +
> + return MatchOperand_Success;
> +}
> +
> +/// CvtLdWriteBackRegAddrMode2 - Convert parsed operands to MCInst.
> +/// Needed here because the Asm Gen Matcher can't handle properly tied operands
> +/// when they refer multiple MIOperands inside a single one.
> +bool ARMAsmParser::
> +CvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
> + const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
> + ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
> +
> + // Create a writeback register dummy placeholder.
> + Inst.addOperand(MCOperand::CreateImm(0));
> +
> + ((ARMOperand*)Operands[3])->addMemMode2Operands(Inst, 3);
> + ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
> + return true;
> +}
> +
> +/// CvtStWriteBackRegAddrMode2 - Convert parsed operands to MCInst.
> +/// Needed here because the Asm Gen Matcher can't handle properly tied operands
> +/// when they refer multiple MIOperands inside a single one.
> +bool ARMAsmParser::
> +CvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
> + const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
> + // Create a writeback register dummy placeholder.
> + Inst.addOperand(MCOperand::CreateImm(0));
> + ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
> + ((ARMOperand*)Operands[3])->addMemMode2Operands(Inst, 3);
> + ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
> + return true;
> +}
> +
> /// Parse an ARM memory expression, return false if successful else return true
> /// or an error. The first token must be a '[' when called.
> ///
> /// TODO Only preindexing and postindexing addressing are started, unindexed
> /// with option, etc are still to do.
> bool ARMAsmParser::
> -ParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
> +ParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
> + ARMII::AddrMode AddrMode = ARMII::AddrModeNone) {
> SMLoc S, E;
> assert(Parser.getTok().is(AsmToken::LBrac) &&
> "Token is not a Left Bracket");
> @@ -1196,6 +1316,9 @@
> ExclaimTok.getLoc());
> Writeback = true;
> Parser.Lex(); // Eat exclaim token
> + } else { // In addressing mode 2, pre-indexed mode always end with "!"
> + if (AddrMode == ARMII::AddrMode2)
> + Preindexed = false;
> }
> } else {
> // The "[Rn" we have so far was not followed by a comma.
> @@ -1231,11 +1354,10 @@
> Offset = MCConstantExpr::Create(0, getContext());
> }
>
> - Operands.push_back(ARMOperand::CreateMem(BaseRegNum, OffsetIsReg, Offset,
> - OffsetRegNum, OffsetRegShifted,
> - ShiftType, ShiftAmount, Preindexed,
> - Postindexed, Negative, Writeback,
> - S, E));
> + Operands.push_back(ARMOperand::CreateMem(AddrMode, BaseRegNum, OffsetIsReg,
> + Offset, OffsetRegNum, OffsetRegShifted,
> + ShiftType, ShiftAmount, Preindexed,
> + Postindexed, Negative, Writeback, S, E));
> if (WBOp)
> Operands.push_back(WBOp);
>
>
> Modified: llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp?rev=128632&r1=128631&r2=128632&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp (original)
> +++ llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp Thu Mar 31 09:52:28 2011
> @@ -643,8 +643,11 @@
> if (PW) {
> MI.addOperand(MCOperand::CreateReg(0));
> ARM_AM::AddrOpc AddrOpcode = getUBit(insn) ? ARM_AM::add : ARM_AM::sub;
> + const TargetInstrDesc &TID = ARMInsts[Opcode];
> + unsigned IndexMode =
> + (TID.TSFlags & ARMII::IndexModeMask) >> ARMII::IndexModeShift;
> unsigned Offset = ARM_AM::getAM2Opc(AddrOpcode, slice(insn, 7, 0) << 2,
> - ARM_AM::no_shift);
> + ARM_AM::no_shift, IndexMode);
> MI.addOperand(MCOperand::CreateImm(Offset));
> OpIdx = 5;
> } else {
> @@ -1073,6 +1076,8 @@
> return false;
>
> ARM_AM::AddrOpc AddrOpcode = getUBit(insn) ? ARM_AM::add : ARM_AM::sub;
> + unsigned IndexMode =
> + (TID.TSFlags & ARMII::IndexModeMask) >> ARMII::IndexModeShift;
> if (getIBit(insn) == 0) {
> // For pre- and post-indexed case, add a reg0 operand (Addressing Mode #2).
> // Otherwise, skip the reg operand since for addrmode_imm12, Rn has already
> @@ -1084,7 +1089,8 @@
>
> // Disassemble the 12-bit immediate offset.
> unsigned Imm12 = slice(insn, 11, 0);
> - unsigned Offset = ARM_AM::getAM2Opc(AddrOpcode, Imm12, ARM_AM::no_shift);
> + unsigned Offset = ARM_AM::getAM2Opc(AddrOpcode, Imm12, ARM_AM::no_shift,
> + IndexMode);
> MI.addOperand(MCOperand::CreateImm(Offset));
> OpIdx += 1;
> } else {
> @@ -1099,7 +1105,7 @@
> // A8.4.1. Possible rrx or shift amount of 32...
> getImmShiftSE(ShOp, ShImm);
> MI.addOperand(MCOperand::CreateImm(
> - ARM_AM::getAM2Opc(AddrOpcode, ShImm, ShOp)));
> + ARM_AM::getAM2Opc(AddrOpcode, ShImm, ShOp, IndexMode)));
> OpIdx += 2;
> }
>
>
> Modified: llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp?rev=128632&r1=128631&r2=128632&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp (original)
> +++ llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp Thu Mar 31 09:52:28 2011
> @@ -181,18 +181,12 @@
> }
> }
>
> -
> -void ARMInstPrinter::printAddrMode2Operand(const MCInst *MI, unsigned Op,
> - raw_ostream &O) {
> +void ARMInstPrinter::printAM2PreOrOffsetIndexOp(const MCInst *MI, unsigned Op,
> + raw_ostream &O) {
> const MCOperand &MO1 = MI->getOperand(Op);
> const MCOperand &MO2 = MI->getOperand(Op+1);
> const MCOperand &MO3 = MI->getOperand(Op+2);
>
> - if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right.
> - printOperand(MI, Op, O);
> - return;
> - }
> -
> O << "[" << getRegisterName(MO1.getReg());
>
> if (!MO2.getReg()) {
> @@ -215,6 +209,50 @@
> O << "]";
> }
>
> +void ARMInstPrinter::printAM2PostIndexOp(const MCInst *MI, unsigned Op,
> + raw_ostream &O) {
> + const MCOperand &MO1 = MI->getOperand(Op);
> + const MCOperand &MO2 = MI->getOperand(Op+1);
> + const MCOperand &MO3 = MI->getOperand(Op+2);
> +
> + O << "[" << getRegisterName(MO1.getReg()) << "], ";
> +
> + if (!MO2.getReg()) {
> + unsigned ImmOffs = ARM_AM::getAM2Offset(MO3.getImm());
> + O << '#'
> + << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm()))
> + << ImmOffs;
> + return;
> + }
> +
> + O << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm()))
> + << getRegisterName(MO2.getReg());
> +
> + if (unsigned ShImm = ARM_AM::getAM2Offset(MO3.getImm()))
> + O << ", "
> + << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO3.getImm()))
> + << " #" << ShImm;
> +}
> +
> +void ARMInstPrinter::printAddrMode2Operand(const MCInst *MI, unsigned Op,
> + raw_ostream &O) {
> + const MCOperand &MO1 = MI->getOperand(Op);
> +
> + if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right.
> + printOperand(MI, Op, O);
> + return;
> + }
> +
> + const MCOperand &MO3 = MI->getOperand(Op+2);
> + unsigned IdxMode = ARM_AM::getAM2IdxMode(MO3.getImm());
> +
> + if (IdxMode == ARMII::IndexModePost) {
> + printAM2PostIndexOp(MI, Op, O);
> + return;
> + }
> + printAM2PreOrOffsetIndexOp(MI, Op, O);
> +}
> +
> void ARMInstPrinter::printAddrMode2OffsetOperand(const MCInst *MI,
> unsigned OpNum,
> raw_ostream &O) {
>
> Modified: llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.h?rev=128632&r1=128631&r2=128632&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.h (original)
> +++ llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.h Thu Mar 31 09:52:28 2011
> @@ -42,7 +42,11 @@
> void printSOImmOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
>
> void printSORegOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
> +
> void printAddrMode2Operand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
> + void printAM2PostIndexOp(const MCInst *MI, unsigned OpNum, raw_ostream &O);
> + void printAM2PreOrOffsetIndexOp(const MCInst *MI, unsigned OpNum,
> + raw_ostream &O);
> void printAddrMode2OffsetOperand(const MCInst *MI, unsigned OpNum,
> raw_ostream &O);
> void printAddrMode3Operand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
>
> Added: llvm/trunk/test/MC/ARM/arm_addrmode2.s
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/arm_addrmode2.s?rev=128632&view=auto
> ==============================================================================
> --- llvm/trunk/test/MC/ARM/arm_addrmode2.s (added)
> +++ llvm/trunk/test/MC/ARM/arm_addrmode2.s Thu Mar 31 09:52:28 2011
> @@ -0,0 +1,38 @@
> +@ RUN: llvm-mc -mcpu=cortex-a8 -triple arm-unknown-unknown -show-encoding %s | FileCheck %s
> +
> +@ Post-indexed
> +@ CHECK: ldrt r1, [r0], r2 @ encoding: [0x02,0x10,0xb0,0xe6]
> +@ CHECK: ldrt r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0xb0,0xe6]
> +@ CHECK: ldrt r1, [r0], #4 @ encoding: [0x04,0x10,0xb0,0xe4]
> +@ CHECK: ldrbt r1, [r0], r2 @ encoding: [0x02,0x10,0xf0,0xe6]
> +@ CHECK: ldrbt r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0xf0,0xe6]
> +@ CHECK: ldrbt r1, [r0], #4 @ encoding: [0x04,0x10,0xf0,0xe4]
> +@ CHECK: strt r1, [r0], r2 @ encoding: [0x02,0x10,0xa0,0xe6]
> +@ CHECK: strt r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0xa0,0xe6]
> +@ CHECK: strt r1, [r0], #4 @ encoding: [0x04,0x10,0xa0,0xe4]
> +@ CHECK: strbt r1, [r0], r2 @ encoding: [0x02,0x10,0xe0,0xe6]
> +@ CHECK: strbt r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0xe0,0xe6]
> +@ CHECK: strbt r1, [r0], #4 @ encoding: [0x04,0x10,0xe0,0xe4]
> +@ CHECK: ldr r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0x90,0xe6]
> +@ CHECK: ldrb r1, [r0], r2, lsr #3 @ encoding: [0xa2,0x11,0xd0,0xe6]
> + ldrt r1, [r0], r2
> + ldrt r1, [r0], r2, lsr #3
> + ldrt r1, [r0], #4
> + ldrbt r1, [r0], r2
> + ldrbt r1, [r0], r2, lsr #3
> + ldrbt r1, [r0], #4
> + strt r1, [r0], r2
> + strt r1, [r0], r2, lsr #3
> + strt r1, [r0], #4
> + strbt r1, [r0], r2
> + strbt r1, [r0], r2, lsr #3
> + strbt r1, [r0], #4
> + ldr r1, [r0], r2, lsr #3
> + ldrb r1, [r0], r2, lsr #3
> +
> +@ Pre-indexed
> +@ CHECK: ldr r1, [r0, r2, lsr #3]! @ encoding: [0xa2,0x11,0xb0,0xe7]
> +@ CHECK: ldrb r1, [r0, r2, lsr #3]! @ encoding: [0xa2,0x11,0xf0,0xe7]
> + ldr r1, [r0, r2, lsr #3]!
> + ldrb r1, [r0, r2, lsr #3]!
> +
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20110331/8848c14a/attachment.html>
More information about the llvm-commits
mailing list