diff options
26 files changed, 514 insertions, 826 deletions
diff --git a/cmake/modules/LLVMLibDeps.cmake b/cmake/modules/LLVMLibDeps.cmake index 78ad19dc9b..1530b42ce8 100644 --- a/cmake/modules/LLVMLibDeps.cmake +++ b/cmake/modules/LLVMLibDeps.cmake @@ -2,10 +2,10 @@ set(MSVC_LIB_DEPS_LLVMARMAsmParser LLVMARMInfo LLVMMC LLVMMCParser LLVMSupport L set(MSVC_LIB_DEPS_LLVMARMAsmPrinter LLVMMC LLVMSupport LLVMSystem) set(MSVC_LIB_DEPS_LLVMARMCodeGen LLVMARMAsmPrinter LLVMARMInfo LLVMAnalysis LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMMC LLVMSelectionDAG LLVMSupport LLVMSystem LLVMTarget) set(MSVC_LIB_DEPS_LLVMARMDisassembler LLVMARMCodeGen LLVMARMInfo LLVMMC LLVMSupport LLVMSystem) -set(MSVC_LIB_DEPS_LLVMARMInfo LLVMSupport) +set(MSVC_LIB_DEPS_LLVMARMInfo LLVMMC LLVMSupport) set(MSVC_LIB_DEPS_LLVMAlphaAsmPrinter LLVMAlphaInfo LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMMC LLVMSupport LLVMSystem LLVMTarget) set(MSVC_LIB_DEPS_LLVMAlphaCodeGen LLVMAlphaInfo LLVMCodeGen LLVMCore LLVMMC LLVMSelectionDAG LLVMSupport LLVMSystem LLVMTarget) -set(MSVC_LIB_DEPS_LLVMAlphaInfo LLVMSupport) +set(MSVC_LIB_DEPS_LLVMAlphaInfo LLVMMC LLVMSupport) set(MSVC_LIB_DEPS_LLVMAnalysis LLVMCore LLVMSupport LLVMSystem LLVMTarget) set(MSVC_LIB_DEPS_LLVMArchive LLVMBitReader LLVMCore LLVMSupport LLVMSystem) set(MSVC_LIB_DEPS_LLVMAsmParser LLVMCore LLVMSupport LLVMSystem) @@ -14,16 +14,16 @@ set(MSVC_LIB_DEPS_LLVMBitReader LLVMCore LLVMSupport LLVMSystem) set(MSVC_LIB_DEPS_LLVMBitWriter LLVMCore LLVMSupport LLVMSystem) set(MSVC_LIB_DEPS_LLVMBlackfinAsmPrinter LLVMAsmPrinter LLVMBlackfinInfo LLVMCodeGen LLVMCore LLVMMC LLVMSupport LLVMSystem LLVMTarget) set(MSVC_LIB_DEPS_LLVMBlackfinCodeGen LLVMBlackfinInfo LLVMCodeGen LLVMCore LLVMMC LLVMSelectionDAG LLVMSupport LLVMSystem LLVMTarget) -set(MSVC_LIB_DEPS_LLVMBlackfinInfo LLVMSupport) +set(MSVC_LIB_DEPS_LLVMBlackfinInfo LLVMMC LLVMSupport) set(MSVC_LIB_DEPS_LLVMCBackend LLVMAnalysis LLVMCBackendInfo LLVMCodeGen LLVMCore LLVMMC LLVMScalarOpts LLVMSupport LLVMSystem LLVMTarget LLVMTransformUtils LLVMipa) -set(MSVC_LIB_DEPS_LLVMCBackendInfo LLVMSupport) +set(MSVC_LIB_DEPS_LLVMCBackendInfo LLVMMC LLVMSupport) set(MSVC_LIB_DEPS_LLVMCellSPUAsmPrinter LLVMAsmPrinter LLVMCellSPUInfo LLVMCodeGen LLVMCore LLVMMC LLVMSupport LLVMSystem LLVMTarget) set(MSVC_LIB_DEPS_LLVMCellSPUCodeGen LLVMCellSPUInfo LLVMCodeGen LLVMCore LLVMMC LLVMSelectionDAG LLVMSupport LLVMSystem LLVMTarget) -set(MSVC_LIB_DEPS_LLVMCellSPUInfo LLVMSupport) +set(MSVC_LIB_DEPS_LLVMCellSPUInfo LLVMMC LLVMSupport) set(MSVC_LIB_DEPS_LLVMCodeGen LLVMAnalysis LLVMCore LLVMMC LLVMScalarOpts LLVMSupport LLVMSystem LLVMTarget LLVMTransformUtils) set(MSVC_LIB_DEPS_LLVMCore LLVMSupport LLVMSystem) set(MSVC_LIB_DEPS_LLVMCppBackend LLVMCore LLVMCppBackendInfo LLVMSupport LLVMSystem LLVMTarget) -set(MSVC_LIB_DEPS_LLVMCppBackendInfo LLVMSupport) +set(MSVC_LIB_DEPS_LLVMCppBackendInfo LLVMMC LLVMSupport) set(MSVC_LIB_DEPS_LLVMExecutionEngine LLVMCore LLVMSupport LLVMSystem LLVMTarget) set(MSVC_LIB_DEPS_LLVMInstCombine LLVMAnalysis LLVMCore LLVMSupport LLVMSystem LLVMTarget LLVMTransformUtils) set(MSVC_LIB_DEPS_LLVMInstrumentation LLVMAnalysis LLVMCore LLVMSupport LLVMSystem LLVMTransformUtils) @@ -34,41 +34,41 @@ set(MSVC_LIB_DEPS_LLVMMBlazeAsmParser LLVMMBlazeInfo LLVMMC LLVMMCParser LLVMSup set(MSVC_LIB_DEPS_LLVMMBlazeAsmPrinter LLVMMC LLVMSupport LLVMSystem) set(MSVC_LIB_DEPS_LLVMMBlazeCodeGen LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMMBlazeAsmPrinter LLVMMBlazeInfo LLVMMC LLVMSelectionDAG LLVMSupport LLVMSystem LLVMTarget) set(MSVC_LIB_DEPS_LLVMMBlazeDisassembler LLVMMBlazeCodeGen LLVMMBlazeInfo LLVMMC LLVMSupport) -set(MSVC_LIB_DEPS_LLVMMBlazeInfo LLVMSupport) +set(MSVC_LIB_DEPS_LLVMMBlazeInfo LLVMMC LLVMSupport) set(MSVC_LIB_DEPS_LLVMMC LLVMSupport LLVMSystem) set(MSVC_LIB_DEPS_LLVMMCDisassembler LLVMARMAsmParser LLVMARMCodeGen LLVMARMDisassembler LLVMARMInfo LLVMAlphaAsmPrinter LLVMAlphaCodeGen LLVMAlphaInfo LLVMBlackfinAsmPrinter LLVMBlackfinCodeGen LLVMBlackfinInfo LLVMCBackend LLVMCBackendInfo LLVMCellSPUAsmPrinter LLVMCellSPUCodeGen LLVMCellSPUInfo LLVMCppBackend LLVMCppBackendInfo LLVMMBlazeAsmParser LLVMMBlazeCodeGen LLVMMBlazeDisassembler LLVMMBlazeInfo LLVMMC LLVMMCParser LLVMMSP430CodeGen LLVMMSP430Info LLVMMipsAsmPrinter LLVMMipsCodeGen LLVMMipsInfo LLVMPTXAsmPrinter LLVMPTXCodeGen LLVMPTXInfo LLVMPowerPCAsmPrinter LLVMPowerPCCodeGen LLVMPowerPCInfo LLVMSparcAsmPrinter LLVMSparcCodeGen LLVMSparcInfo LLVMSupport LLVMSystem LLVMSystemZAsmPrinter LLVMSystemZCodeGen LLVMSystemZInfo LLVMX86AsmParser LLVMX86CodeGen LLVMX86Disassembler LLVMX86Info LLVMXCoreAsmPrinter LLVMXCoreCodeGen LLVMXCoreInfo) set(MSVC_LIB_DEPS_LLVMMCParser LLVMMC LLVMSupport LLVMSystem) set(MSVC_LIB_DEPS_LLVMMSP430AsmPrinter LLVMMC LLVMSupport LLVMSystem) set(MSVC_LIB_DEPS_LLVMMSP430CodeGen LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMMC LLVMMSP430AsmPrinter LLVMMSP430Info LLVMSelectionDAG LLVMSupport LLVMSystem LLVMTarget) -set(MSVC_LIB_DEPS_LLVMMSP430Info LLVMSupport) +set(MSVC_LIB_DEPS_LLVMMSP430Info LLVMMC LLVMSupport) set(MSVC_LIB_DEPS_LLVMMipsAsmPrinter LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMMC LLVMMipsCodeGen LLVMMipsInfo LLVMSupport LLVMSystem LLVMTarget) set(MSVC_LIB_DEPS_LLVMMipsCodeGen LLVMCodeGen LLVMCore LLVMMC LLVMMipsInfo LLVMSelectionDAG LLVMSupport LLVMSystem LLVMTarget) -set(MSVC_LIB_DEPS_LLVMMipsInfo LLVMSupport) -set(MSVC_LIB_DEPS_LLVMPTXAsmPrinter LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMPTXInfo LLVMSupport LLVMSystem) +set(MSVC_LIB_DEPS_LLVMMipsInfo LLVMMC LLVMSupport) +set(MSVC_LIB_DEPS_LLVMPTXAsmPrinter LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMMC LLVMPTXCodeGen LLVMPTXInfo LLVMSupport LLVMSystem) set(MSVC_LIB_DEPS_LLVMPTXCodeGen LLVMCodeGen LLVMCore LLVMMC LLVMPTXInfo LLVMSelectionDAG LLVMSupport LLVMSystem LLVMTarget) -set(MSVC_LIB_DEPS_LLVMPTXInfo LLVMSupport) +set(MSVC_LIB_DEPS_LLVMPTXInfo LLVMMC LLVMSupport) set(MSVC_LIB_DEPS_LLVMPowerPCAsmPrinter LLVMAnalysis LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMMC LLVMPowerPCInfo LLVMSupport LLVMSystem LLVMTarget) set(MSVC_LIB_DEPS_LLVMPowerPCCodeGen LLVMCodeGen LLVMCore LLVMMC LLVMPowerPCInfo LLVMSelectionDAG LLVMSupport LLVMSystem LLVMTarget) -set(MSVC_LIB_DEPS_LLVMPowerPCInfo LLVMSupport) +set(MSVC_LIB_DEPS_LLVMPowerPCInfo LLVMMC LLVMSupport) set(MSVC_LIB_DEPS_LLVMScalarOpts LLVMAnalysis LLVMCore LLVMInstCombine LLVMSupport LLVMSystem LLVMTarget LLVMTransformUtils) set(MSVC_LIB_DEPS_LLVMSelectionDAG LLVMAnalysis LLVMCodeGen LLVMCore LLVMMC LLVMSupport LLVMSystem LLVMTarget) set(MSVC_LIB_DEPS_LLVMSparcAsmPrinter LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMMC LLVMSparcInfo LLVMSupport LLVMSystem LLVMTarget) set(MSVC_LIB_DEPS_LLVMSparcCodeGen LLVMCodeGen LLVMCore LLVMMC LLVMSelectionDAG LLVMSparcInfo LLVMSupport LLVMSystem LLVMTarget) -set(MSVC_LIB_DEPS_LLVMSparcInfo LLVMSupport) +set(MSVC_LIB_DEPS_LLVMSparcInfo LLVMMC LLVMSupport) set(MSVC_LIB_DEPS_LLVMSupport LLVMSystem) set(MSVC_LIB_DEPS_LLVMSystem ) set(MSVC_LIB_DEPS_LLVMSystemZAsmPrinter LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMMC LLVMSupport LLVMSystem LLVMSystemZInfo LLVMTarget) set(MSVC_LIB_DEPS_LLVMSystemZCodeGen LLVMCodeGen LLVMCore LLVMMC LLVMSelectionDAG LLVMSupport LLVMSystem LLVMSystemZInfo LLVMTarget) -set(MSVC_LIB_DEPS_LLVMSystemZInfo LLVMSupport) +set(MSVC_LIB_DEPS_LLVMSystemZInfo LLVMMC LLVMSupport) set(MSVC_LIB_DEPS_LLVMTarget LLVMCore LLVMMC LLVMSupport LLVMSystem) set(MSVC_LIB_DEPS_LLVMTransformUtils LLVMAnalysis LLVMCore LLVMSupport LLVMSystem LLVMTarget LLVMipa) set(MSVC_LIB_DEPS_LLVMX86AsmParser LLVMMC LLVMMCParser LLVMSupport LLVMSystem LLVMTarget LLVMX86Info) set(MSVC_LIB_DEPS_LLVMX86AsmPrinter LLVMMC LLVMSupport LLVMSystem) set(MSVC_LIB_DEPS_LLVMX86CodeGen LLVMAnalysis LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMMC LLVMSelectionDAG LLVMSupport LLVMSystem LLVMTarget LLVMX86AsmPrinter LLVMX86Info) set(MSVC_LIB_DEPS_LLVMX86Disassembler LLVMMC LLVMSupport LLVMX86Info) -set(MSVC_LIB_DEPS_LLVMX86Info LLVMSupport) +set(MSVC_LIB_DEPS_LLVMX86Info LLVMMC LLVMSupport) set(MSVC_LIB_DEPS_LLVMXCoreAsmPrinter LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMMC LLVMSupport LLVMSystem LLVMTarget LLVMXCoreInfo) set(MSVC_LIB_DEPS_LLVMXCoreCodeGen LLVMCodeGen LLVMCore LLVMMC LLVMSelectionDAG LLVMSupport LLVMSystem LLVMTarget LLVMXCoreInfo) -set(MSVC_LIB_DEPS_LLVMXCoreInfo LLVMSupport) +set(MSVC_LIB_DEPS_LLVMXCoreInfo LLVMMC LLVMSupport) set(MSVC_LIB_DEPS_LLVMipa LLVMAnalysis LLVMCore LLVMSupport LLVMSystem) set(MSVC_LIB_DEPS_LLVMipo LLVMAnalysis LLVMCore LLVMScalarOpts LLVMSupport LLVMSystem LLVMTarget LLVMTransformUtils LLVMipa) diff --git a/lib/Target/MBlaze/AsmParser/MBlazeAsmParser.cpp b/lib/Target/MBlaze/AsmParser/MBlazeAsmParser.cpp index d7e3047ed6..80d7f3935a 100644 --- a/lib/Target/MBlaze/AsmParser/MBlazeAsmParser.cpp +++ b/lib/Target/MBlaze/AsmParser/MBlazeAsmParser.cpp @@ -1,4 +1,4 @@ -//===-- MBlazeAsmParser.cpp - Parse MBlaze assembly to MCInst instructions ------===// +//===-- MBlazeAsmParser.cpp - Parse MBlaze asm to MCInst instructions -----===// // // The LLVM Compiler Infrastructure // @@ -29,67 +29,25 @@ using namespace llvm; namespace { struct MBlazeOperand; -// The shift types for register controlled shifts in arm memory addressing -enum ShiftType { - Lsl, - Lsr, - Asr, - Ror, - Rrx -}; - class MBlazeAsmParser : public TargetAsmParser { MCAsmParser &Parser; TargetMachine &TM; -private: MCAsmParser &getParser() const { return Parser; } - MCAsmLexer &getLexer() const { return Parser.getLexer(); } void Warning(SMLoc L, const Twine &Msg) { Parser.Warning(L, Msg); } - bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); } - bool MaybeParseRegister(OwningPtr<MBlazeOperand> &Op, bool ParseWriteBack); - - bool ParseRegisterList(OwningPtr<MBlazeOperand> &Op); - - bool ParseMemory(OwningPtr<MBlazeOperand> &Op); - - bool ParseMemoryOffsetReg(bool &Negative, - bool &OffsetRegShifted, - enum ShiftType &ShiftType, - const MCExpr *&ShiftAmount, - const MCExpr *&Offset, - bool &OffsetIsReg, - int &OffsetRegNum, - SMLoc &E); - - bool ParseShift(enum ShiftType &St, const MCExpr *&ShiftAmount, SMLoc &E); - - bool ParseOperand(OwningPtr<MBlazeOperand> &Op); - - bool ParseDirectiveWord(unsigned Size, SMLoc L); - - bool ParseDirectiveCode(SMLoc L); - - bool ParseDirectiveSyntax(SMLoc L); + MBlazeOperand *ParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands); + MBlazeOperand *ParseRegister(); + MBlazeOperand *ParseImmediate(); + MBlazeOperand *ParseFsl(); + MBlazeOperand* ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands); bool MatchAndEmitInstruction(SMLoc IDLoc, SmallVectorImpl<MCParsedAsmOperand*> &Operands, - MCStreamer &Out) { - MCInst Inst; - unsigned ErrorInfo; - if (MatchInstructionImpl(Operands, Inst, ErrorInfo) == Match_Success) { - Out.EmitInstruction(Inst); - return false; - } - - // FIXME: We should give nicer diagnostics about the exact failure. - Error(IDLoc, "unrecognized instruction"); - return true; - } + MCStreamer &Out); /// @name Auto-generated Match Functions /// { @@ -109,101 +67,76 @@ public: virtual bool ParseDirective(AsmToken DirectiveID); }; - + /// MBlazeOperand - Instances of this class represent a parsed MBlaze machine /// instruction. struct MBlazeOperand : public MCParsedAsmOperand { -private: - MBlazeOperand() {} -public: enum KindTy { - CondCode, + Token, Immediate, - Memory, Register, - Token + Memory, + Fsl } Kind; SMLoc StartLoc, EndLoc; union { struct { - MBlazeCC::CC Val; - } CC; - - struct { const char *Data; unsigned Length; } Tok; struct { unsigned RegNum; - bool Writeback; } Reg; struct { const MCExpr *Val; } Imm; - - // This is for all forms of MBlaze address expressions + struct { - unsigned BaseRegNum; - unsigned OffsetRegNum; // used when OffsetIsReg is true - const MCExpr *Offset; // used when OffsetIsReg is false - const MCExpr *ShiftAmount; // used when OffsetRegShifted is true - enum ShiftType ShiftType; // used when OffsetRegShifted is true - unsigned - OffsetRegShifted : 1, // only used when OffsetIsReg is true - Preindexed : 1, - Postindexed : 1, - OffsetIsReg : 1, - Negative : 1, // only used when OffsetIsReg is true - Writeback : 1; + unsigned Base; + unsigned OffReg; + const MCExpr *Off; } Mem; + struct { + const MCExpr *Val; + } FslImm; }; - - //MBlazeOperand(KindTy K, SMLoc S, SMLoc E) - // : Kind(K), StartLoc(S), EndLoc(E) {} - + + MBlazeOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {} +public: MBlazeOperand(const MBlazeOperand &o) : MCParsedAsmOperand() { Kind = o.Kind; StartLoc = o.StartLoc; EndLoc = o.EndLoc; switch (Kind) { - case CondCode: - CC = o.CC; - break; - case Token: - Tok = o.Tok; - break; case Register: Reg = o.Reg; break; case Immediate: Imm = o.Imm; break; + case Token: + Tok = o.Tok; + break; case Memory: Mem = o.Mem; break; + case Fsl: + FslImm = o.FslImm; + break; } } - + /// getStartLoc - Get the location of the first token of this operand. SMLoc getStartLoc() const { return StartLoc; } + /// getEndLoc - Get the location of the last token of this operand. SMLoc getEndLoc() const { return EndLoc; } - MBlazeCC::CC getCondCode() const { - assert(Kind == CondCode && "Invalid access!"); - return CC.Val; - } - - StringRef getToken() const { - assert(Kind == Token && "Invalid access!"); - return StringRef(Tok.Data, Tok.Length); - } - unsigned getReg() const { assert(Kind == Register && "Invalid access!"); return Reg.RegNum; @@ -214,29 +147,42 @@ public: return Imm.Val; } - bool isCondCode() const { return Kind == CondCode; } + const MCExpr *getFslImm() const { + assert(Kind == Fsl && "Invalid access!"); + return FslImm.Val; + } - bool isImm() const { return Kind == Immediate; } + unsigned getMemBase() const { + assert(Kind == Memory && "Invalid access!"); + return Mem.Base; + } - bool isReg() const { return Kind == Register; } + const MCExpr* getMemOff() const { + assert(Kind == Memory && "Invalid access!"); + return Mem.Off; + } + + unsigned getMemOffReg() const { + assert(Kind == Memory && "Invalid access!"); + return Mem.OffReg; + } - bool isToken() const {return Kind == Token; } + bool isToken() const { return Kind == Token; } + bool isImm() const { return Kind == Immediate; } + bool isMem() const { return Kind == Memory; } + bool isFsl() const { return Kind == Fsl; } + bool isReg() const { return Kind == Register; } void addExpr(MCInst &Inst, const MCExpr *Expr) const { - // Add as immediates when possible. - if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) + // Add as immediates when possible. Null MCExpr = 0. + if (Expr == 0) + Inst.addOperand(MCOperand::CreateImm(0)); + else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) Inst.addOperand(MCOperand::CreateImm(CE->getValue())); else Inst.addOperand(MCOperand::CreateExpr(Expr)); } - void addCondCodeOperands(MCInst &Inst, unsigned N) const { - assert(N == 2 && "Invalid number of operands!"); - Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode()))); - // FIXME: What belongs here? - Inst.addOperand(MCOperand::CreateReg(0)); - } - void addRegOperands(MCInst &Inst, unsigned N) const { assert(N == 1 && "Invalid number of operands!"); Inst.addOperand(MCOperand::CreateReg(getReg())); @@ -247,71 +193,83 @@ public: addExpr(Inst, getImm()); } - virtual void dump(raw_ostream &OS) const; + void addFslOperands(MCInst &Inst, unsigned N) const { + assert(N == 1 && "Invalid number of operands!"); + addExpr(Inst, getFslImm()); + } - static void CreateCondCode(OwningPtr<MBlazeOperand> &Op, MBlazeCC::CC CC, - SMLoc S) { - Op.reset(new MBlazeOperand); - Op->Kind = CondCode; - Op->CC.Val = CC; - Op->StartLoc = S; - Op->EndLoc = S; + void addMemOperands(MCInst &Inst, unsigned N) const { + assert(N == 2 && "Invalid number of operands!"); + + unsigned RegOff = getMemOffReg(); + if (RegOff) + Inst.addOperand(MCOperand::CreateReg(RegOff)); + else + addExpr(Inst, getMemOff()); + + Inst.addOperand(MCOperand::CreateReg(getMemBase())); + } + + StringRef getToken() const { + assert(Kind == Token && "Invalid access!"); + return StringRef(Tok.Data, Tok.Length); } - static void CreateToken(OwningPtr<MBlazeOperand> &Op, StringRef Str, - SMLoc S) { - Op.reset(new MBlazeOperand); - Op->Kind = Token; + virtual void dump(raw_ostream &OS) const; + + static MBlazeOperand *CreateToken(StringRef Str, SMLoc S) { + MBlazeOperand *Op = new MBlazeOperand(Token); Op->Tok.Data = Str.data(); Op->Tok.Length = Str.size(); Op->StartLoc = S; Op->EndLoc = S; + return Op; } - static void CreateReg(OwningPtr<MBlazeOperand> &Op, unsigned RegNum, - bool Writeback, SMLoc S, SMLoc E) { - Op.reset(new MBlazeOperand); - Op->Kind = Register; + static MBlazeOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) { + MBlazeOperand *Op = new MBlazeOperand(Register); Op->Reg.RegNum = RegNum; - Op->Reg.Writeback = Writeback; - Op->StartLoc = S; Op->EndLoc = E; + return Op; + } + + static MBlazeOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) { + MBlazeOperand *Op = new MBlazeOperand(Immediate); + Op->Imm.Val = Val; + Op->StartLoc = S; + Op->EndLoc = E; + return Op; } - static void CreateImm(OwningPtr<MBlazeOperand> &Op, const MCExpr *Val, - SMLoc S, SMLoc E) { - Op.reset(new MBlazeOperand); - Op->Kind = Immediate; + static MBlazeOperand *CreateFslImm(const MCExpr *Val, SMLoc S, SMLoc E) { + MBlazeOperand *Op = new MBlazeOperand(Fsl); Op->Imm.Val = Val; - Op->StartLoc = S; Op->EndLoc = E; + return Op; + } + + static MBlazeOperand *CreateMem(unsigned Base, const MCExpr *Off, SMLoc S, + SMLoc E) { + MBlazeOperand *Op = new MBlazeOperand(Memory); + Op->Mem.Base = Base; + Op->Mem.Off = Off; + Op->Mem.OffReg = 0; + Op->StartLoc = S; + Op->EndLoc = E; + return Op; } - static void CreateMem(OwningPtr<MBlazeOperand> &Op, - unsigned BaseRegNum, bool OffsetIsReg, - const MCExpr *Offset, unsigned OffsetRegNum, - bool OffsetRegShifted, enum ShiftType ShiftType, - const MCExpr *ShiftAmount, bool Preindexed, - bool Postindexed, bool Negative, bool Writeback, - SMLoc S, SMLoc E) { - Op.reset(new MBlazeOperand); - Op->Kind = Memory; - Op->Mem.BaseRegNum = BaseRegNum; - Op->Mem.OffsetIsReg = OffsetIsReg; - Op->Mem.Offset = Offset; - Op->Mem.OffsetRegNum = OffsetRegNum; - Op->Mem.OffsetRegShifted = OffsetRegShifted; - Op->Mem.ShiftType = ShiftType; - Op->Mem.ShiftAmount = ShiftAmount; - Op->Mem.Preindexed = Preindexed; - Op->Mem.Postindexed = Postindexed; - Op->Mem.Negative = Negative; - Op->Mem.Writeback = Writeback; - + static MBlazeOperand *CreateMem(unsigned Base, unsigned Off, SMLoc S, + SMLoc E) { + MBlazeOperand *Op = new MBlazeOperand(Memory); + Op->Mem.Base = Base; + Op->Mem.OffReg = Off; + Op->Mem.Off = 0; Op->StartLoc = S; Op->EndLoc = E; + return Op; } }; @@ -319,21 +277,21 @@ public: void MBlazeOperand::dump(raw_ostream &OS) const { switch (Kind) { - case CondCode: - OS << MBlazeCCToString(getCondCode()); - break; case Immediate: getImm()->print(OS); break; - case Memory: - OS << "<memory>"; - break; case Register: OS << "<register " << getReg() << ">"; break; case Token: OS << "'" << getToken() << "'"; break; + case Memory: + OS << "MEMORY"; + break; + case Fsl: + getFslImm()->print(OS); + break; } } @@ -343,487 +301,210 @@ void MBlazeOperand::dump(raw_ostream &OS) const { static unsigned MatchRegisterName(StringRef Name); /// } - -/// Try to parse a register name. The token must be an Identifier when called, -/// and if it is a register name a Reg operand is created, the token is eaten -/// and false is returned. Else true is returned and no token is eaten. -/// TODO this is likely to change to allow different register types and or to -/// parse for a specific register type. -bool MBlazeAsmParser::MaybeParseRegister - (OwningPtr<MBlazeOperand> &Op, bool ParseWriteBack) { - SMLoc S, E; - const AsmToken &Tok = Parser.getTok(); - assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier"); - - // FIXME: Validate register for the current architecture; we have to do - // validation later, so maybe there is no need for this here. - int RegNum; - - RegNum = MatchRegisterName(Tok.getString()); - if (RegNum == -1) - return true; - - S = Tok.getLoc(); - - Parser.Lex(); // Eat identifier token. - - E = Parser.getTok().getLoc(); - - bool Writeback = false; - if (ParseWriteBack) { - const AsmToken &ExclaimTok = Parser.getTok(); - if (ExclaimTok.is(AsmToken::Exclaim)) { - E = ExclaimTok.getLoc(); - Writeback = true; - Parser.Lex(); // Eat exclaim token +// +bool MBlazeAsmParser:: +MatchAndEmitInstruction(SMLoc IDLoc, + SmallVectorImpl<MCParsedAsmOperand*> &Operands, + MCStreamer &Out) { + MCInst Inst; + SMLoc ErrorLoc; + unsigned ErrorInfo; + + switch (MatchInstructionImpl(Operands, Inst, ErrorInfo)) { + case Match_Success: + Out.EmitInstruction(Inst); + return false; + case Match_MissingFeature: + return Error(IDLoc, "instruction use requires an option to be enabled"); + case Match_MnemonicFail: + return Error(IDLoc, "unrecognized instruction mnemonic"); + case Match_InvalidOperand: + ErrorLoc = IDLoc; + if (ErrorInfo != ~0U) { + if (ErrorInfo >= Operands.size()) + return Error(IDLoc, "too few operands for instruction"); + + ErrorLoc = ((MBlazeOperand*)Operands[ErrorInfo])->getStartLoc(); + if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc; } - } - MBlazeOperand::CreateReg(Op, RegNum, Writeback, S, E); + return Error(ErrorLoc, "invalid operand for instruction"); + } - return false; + llvm_unreachable("Implement any new match types added!"); + return true; } -/// Parse a register list, return false if successful else return true or an -/// error. The first token must be a '{' when called. -bool MBlazeAsmParser::ParseRegisterList(OwningPtr<MBlazeOperand> &Op) { - SMLoc S, E; - assert(Parser.getTok().is(AsmToken::LCurly) && - "Token is not an Left Curly Brace"); - S = Parser.getTok().getLoc(); - Parser.Lex(); // Eat left curly brace token. - - const AsmToken &RegTok = Parser.getTok(); - SMLoc RegLoc = RegTok.getLoc(); - if (RegTok.isNot(AsmToken::Identifier)) - return Error(RegLoc, "register expected"); - int RegNum = MatchRegisterName(RegTok.getString()); - if (RegNum == -1) - return Error(RegLoc, "register expected"); - Parser.Lex(); // Eat identifier token. - unsigned RegList = 1 << RegNum; - - int HighRegNum = RegNum; - // TODO ranges like "{Rn-Rm}" - while (Parser.getTok().is(AsmToken::Comma)) { - Parser.Lex(); // Eat comma token. - - const AsmToken &RegTok = Parser.getTok(); - SMLoc RegLoc = RegTok.getLoc(); - if (RegTok.isNot(AsmToken::Identifier)) - return Error(RegLoc, "register expected"); - int RegNum = MatchRegisterName(RegTok.getString()); - if (RegNum == -1) - return Error(RegLoc, "register expected"); - - if (RegList & (1 << RegNum)) - Warning(RegLoc, "register duplicated in register list"); - else if (RegNum <= HighRegNum) - Warning(RegLoc, "register not in ascending order in register list"); - RegList |= 1 << RegNum; - HighRegNum = RegNum; - - Parser.Lex(); // Eat identifier token. - } - const AsmToken &RCurlyTok = Parser.getTok(); - if (RCurlyTok.isNot(AsmToken::RCurly)) - return Error(RCurlyTok.getLoc(), "'}' expected"); - E = RCurlyTok.getLoc(); - Parser.Lex(); // Eat left curly brace token. +MBlazeOperand *MBlazeAsmParser:: +ParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { + if (Operands.size() != 4) + return 0; - return false; -} + MBlazeOperand &Base = *(MBlazeOperand*)Operands[2]; + MBlazeOperand &Offset = *(MBlazeOperand*)Operands[3]; -/// 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 MBlazeAsmParser::ParseMemory(OwningPtr<MBlazeOperand> &Op) { - SMLoc S, E; - assert(Parser.getTok().is(AsmToken::LBrac) && - "Token is not an Left Bracket"); - S = Parser.getTok().getLoc(); - Parser.Lex(); // Eat left bracket token. - - const AsmToken &BaseRegTok = Parser.getTok(); - if (BaseRegTok.isNot(AsmToken::Identifier)) - return Error(BaseRegTok.getLoc(), "register expected"); - if (MaybeParseRegister(Op, false)) - return Error(BaseRegTok.getLoc(), "register expected"); - int BaseRegNum = Op->getReg(); - - bool Preindexed = false; - bool Postindexed = false; - bool OffsetIsReg = false; - bool Negative = false; - bool Writeback = false; - - // First look for preindexed address forms, that is after the "[Rn" we now - // have to see if the next token is a comma. - const AsmToken &Tok = Parser.getTok(); - if (Tok.is(AsmToken::Comma)) { - Preindexed = true; - Parser.Lex(); // Eat comma token. - int OffsetRegNum; - bool OffsetRegShifted; - enum ShiftType ShiftType; - const MCExpr *ShiftAmount; - const MCExpr *Offset; - if(ParseMemoryOffsetReg(Negative, OffsetRegShifted, ShiftType, ShiftAmount, - Offset, OffsetIsReg, OffsetRegNum, E)) - return true; - const AsmToken &RBracTok = Parser.getTok(); - if (RBracTok.isNot(AsmToken::RBrac)) - return Error(RBracTok.getLoc(), "']' expected"); - E = RBracTok.getLoc(); - Parser.Lex(); // Eat right bracket token. - - const AsmToken &ExclaimTok = Parser.getTok(); - if (ExclaimTok.is(AsmToken::Exclaim)) { - E = ExclaimTok.getLoc(); - Writeback = true; - Parser.Lex(); // Eat exclaim token - } - MBlazeOperand::CreateMem(Op, BaseRegNum, OffsetIsReg, Offset, OffsetRegNum, - OffsetRegShifted, ShiftType, ShiftAmount, - Preindexed, Postindexed, Negative, Writeback, S, E); - return false; + SMLoc S = Base.getStartLoc(); + SMLoc O = Offset.getStartLoc(); + SMLoc E = Offset.getEndLoc(); + + if (!Base.isReg()) { + Error(S, "base address must be a register"); + return 0; } - // The "[Rn" we have so far was not followed by a comma. - else if (Tok.is(AsmToken::RBrac)) { - // This is a post indexing addressing forms, that is a ']' follows after - // the "[Rn". - Postindexed = true; - Writeback = true; - E = Tok.getLoc(); - Parser.Lex(); // Eat right bracket token. - - int OffsetRegNum = 0; - bool OffsetRegShifted = false; - enum ShiftType ShiftType; - const MCExpr *ShiftAmount; - const MCExpr *Offset; - - const AsmToken &NextTok = Parser.getTok(); - if (NextTok.isNot(AsmToken::EndOfStatement)) { - if (NextTok.isNot(AsmToken::Comma)) - return Error(NextTok.getLoc(), "',' expected"); - Parser.Lex(); // Eat comma token. - if(ParseMemoryOffsetReg(Negative, OffsetRegShifted, ShiftType, - ShiftAmount, Offset, OffsetIsReg, OffsetRegNum, - E)) - return true; - } - MBlazeOperand::CreateMem(Op, BaseRegNum, OffsetIsReg, Offset, OffsetRegNum, - OffsetRegShifted, ShiftType, ShiftAmount, - Preindexed, Postindexed, Negative, Writeback, S, E); - return false; + if (!Offset.isReg() && !Offset.isImm()) { + Error(O, "offset must be a register or immediate"); + return 0; } - return true; + MBlazeOperand *Op; + if (Offset.isReg()) + Op = MBlazeOperand::CreateMem(Base.getReg(), Offset.getReg(), S, E); + else + Op = MBlazeOperand::CreateMem(Base.getReg(), Offset.getImm(), S, E); + + delete Operands.pop_back_val(); + delete Operands.pop_back_val(); + Operands.push_back(Op); + + return Op; } -/// Parse the offset of a memory operand after we have seen "[Rn," or "[Rn]," -/// we will parse the following (were +/- means that a plus or minus is -/// optional): -/// +/-Rm -/// +/-Rm, shift -/// #offset -/// we return false on success or an error otherwise. -bool MBlazeAsmParser::ParseMemoryOffsetReg(bool &Negative, - bool &OffsetRegShifted, - enum ShiftType &ShiftType, - const MCExpr *&ShiftAmount, - const MCExpr *&Offset, - bool &OffsetIsReg, - int &OffsetRegNum, - SMLoc &E) { - OwningPtr<MBlazeOperand> Op; - Negative = false; - OffsetRegShifted = false; - OffsetIsReg = false; - OffsetRegNum = -1; - const AsmToken &NextTok = Parser.getTok(); - E = NextTok.getLoc(); - if (NextTok.is(AsmToken::Plus)) - Parser.Lex(); // Eat plus token. - else if (NextTok.is(AsmToken::Minus)) { - Negative = true; - Parser.Lex(); // Eat minus token - } - // See if there is a register following the "[Rn," or "[Rn]," we have so far. - const AsmToken &OffsetRegTok = Parser.getTok(); - if (OffsetRegTok.is(AsmToken::Identifier)) { - OffsetIsReg = !MaybeParseRegister(Op, false); - if (OffsetIsReg) { - E = Op->getEndLoc(); - OffsetRegNum = Op->getReg(); - } - } - // If we parsed a register as the offset then their can be a shift after that - if (OffsetRegNum != -1) { - // Look for a comma then a shift - const AsmToken &Tok = Parser.getTok(); - if (Tok.is(AsmToken::Comma)) { - Parser.Lex(); // Eat comma token. - - const AsmToken &Tok = Parser.getTok(); |