diff options
author | Wesley Peck <peckw@wesleypeck.com> | 2010-11-08 19:40:01 +0000 |
---|---|---|
committer | Wesley Peck <peckw@wesleypeck.com> | 2010-11-08 19:40:01 +0000 |
commit | 0a67d92938d77b6a8cde6e1676750264b274cebc (patch) | |
tree | 0c6b0c4c8679380835d14ad474b4e38c0a5c54b7 /lib | |
parent | 554375b707d741c357a78650160ba5d093b4993a (diff) | |
download | external_llvm-0a67d92938d77b6a8cde6e1676750264b274cebc.zip external_llvm-0a67d92938d77b6a8cde6e1676750264b274cebc.tar.gz external_llvm-0a67d92938d77b6a8cde6e1676750264b274cebc.tar.bz2 |
Adding working version of assembly parser for the MBlaze backend
Major cleanup of whitespace and formatting issues in MBlaze backend
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@118434 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
25 files changed, 498 insertions, 810 deletions
diff --git a/lib/Target/MBlaze/AsmParser/MBlazeAsmParser.cpp b/lib/Target/MBlaze/AsmParser/MBlazeAsmParser.cpp index d7e3047..80d7f39 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(); - if (ParseShift(ShiftType, ShiftAmount, E)) - return Error(Tok.getLoc(), "shift expected"); - OffsetRegShifted = true; - } - } - else { // the "[Rn," or "[Rn,]" we have so far was not followed by "Rm" - // Look for #offset following the "[Rn," or "[Rn]," - const AsmToken &HashTok = Parser.getTok(); - if (HashTok.isNot(AsmToken::Hash)) - return Error(HashTok.getLoc(), "'#' expected"); - - Parser.Lex(); // Eat hash token. - - if (getParser().ParseExpression(Offset)) - return true; - E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); +MBlazeOperand *MBlazeAsmParser::ParseRegister() { + SMLoc S = Parser.getTok().getLoc(); + SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); + + switch (getLexer().getKind()) { + default: return 0; + case AsmToken::Identifier: + unsigned RegNo = MatchRegisterName(getLexer().getTok().getIdentifier()); + if (RegNo == 0) + return 0; + + return MBlazeOperand::CreateReg(RegNo, S, E); } - return false; } -/// ParseShift as one of these two: -/// ( lsl | lsr | asr | ror ) , # shift_amount -/// rrx -/// and returns true if it parses a shift otherwise it returns false. -bool MBlazeAsmParser::ParseShift(ShiftType &St, - const MCExpr *&ShiftAmount, - SMLoc &E) { - const AsmToken &Tok = Parser.getTok(); - if (Tok.isNot(AsmToken::Identifier)) - return true; - StringRef ShiftName = Tok.getString(); - if (ShiftName == "lsl" || ShiftName == "LSL") - St = Lsl; - else if (ShiftName == "lsr" || ShiftName == "LSR") - St = Lsr; - else if (ShiftName == "asr" || ShiftName == "ASR") - St = Asr; - else if (ShiftName == "ror" || ShiftName == "ROR") - St = Ror; - else if (ShiftName == "rrx" || ShiftName == "RRX") - St = Rrx; - else - return true; - Parser.Lex(); // Eat shift type token. +static unsigned MatchFslRegister(const StringRef &String) { + if (!String.startswith("rfsl")) + return -1; - // Rrx stands alone. - if (St == Rrx) - return false; + unsigned regNum; + if (String.substr(4).getAsInteger(10,regNum)) + return -1; - // Otherwise, there must be a '#' and a shift amount. - const AsmToken &HashTok = Parser.getTok(); - if (HashTok.isNot(AsmToken::Hash)) - return Error(HashTok.getLoc(), "'#' expected"); - Parser.Lex(); // Eat hash token. + return regNum; +} - if (getParser().ParseExpression(ShiftAmount)) - return true; +MBlazeOperand *MBlazeAsmParser::ParseFsl() { + SMLoc S = Parser.getTok().getLoc(); + SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); - return false; + switch (getLexer().getKind()) { + default: return 0; + case AsmToken::Identifier: + unsigned reg = MatchFslRegister(getLexer().getTok().getIdentifier()); + if (reg >= 16) + return 0; + + const MCExpr *EVal = MCConstantExpr::Create(reg,getContext()); + return MBlazeOperand::CreateFslImm(EVal,S,E); + } } -/// Parse a arm instruction operand. For now this parses the operand regardless -/// of the mnemonic. -bool MBlazeAsmParser::ParseOperand(OwningPtr<MBlazeOperand> &Op) { - SMLoc S, E; - +MBlazeOperand *MBlazeAsmParser::ParseImmediate() { + SMLoc S = Parser.getTok().getLoc(); + SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); + + const MCExpr *EVal; switch (getLexer().getKind()) { + default: return 0; + case AsmToken::LParen: + case AsmToken::Plus: + case AsmToken::Minus: + case AsmToken::Integer: case AsmToken::Identifier: - if (!MaybeParseRegister(Op, true)) - return false; - // This was not a register so parse other operands that start with an - // identifier (like labels) as expressions and create them as immediates. - const MCExpr *IdVal; - S = Parser.getTok().getLoc(); - if (getParser().ParseExpression(IdVal)) - return true; - E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); - MBlazeOperand::CreateImm(Op, IdVal, S, E); - return false; - case AsmToken::LBrac: - return ParseMemory(Op); - case AsmToken::LCurly: - return ParseRegisterList(Op); - case AsmToken::Hash: - // #42 -> immediate. - // TODO: ":lower16:" and ":upper16:" modifiers after # before immediate - S = Parser.getTok().getLoc(); - Parser.Lex(); - const MCExpr *ImmVal; - if (getParser().ParseExpression(ImmVal)) - return true; - E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); - MBlazeOperand::CreateImm(Op, ImmVal, S, E); - return false; - default: - return Error(Parser.getTok().getLoc(), "unexpected token in operand"); + if (getParser().ParseExpression(EVal)) + return 0; + + return MBlazeOperand::CreateImm(EVal, S, E); } } -/// Parse an mblaze instruction mnemonic followed by its operands. -bool MBlazeAsmParser::ParseInstruction(StringRef Name, SMLoc NameLoc, - SmallVectorImpl<MCParsedAsmOperand*> &Operands) { - OwningPtr<MBlazeOperand> Op; - - // Create the leading tokens for the mnemonic, split by '.' characters. - size_t Start = 0, Next = Name.find('.'); - StringRef Head = Name.slice(Start, Next); - - // Determine the predicate, if any. - // - // FIXME: We need a way to check whether a prefix supports predication, - // otherwise we will end up with an ambiguity for instructions that happen to - // end with a predicate name. - unsigned CC = StringSwitch<unsigned>(Head.substr(Head.size()-2)) - .Case("eq", MBlazeCC::EQ) - .Case("ne", MBlazeCC::NE) - .Case("gt", MBlazeCC::GT) - .Case("lt", MBlazeCC::LT) - .Case("ge", MBlazeCC::GE) - .Case("le", MBlazeCC::LE) - .Default(~0U); - if (CC != ~0U) { - Head = Head.slice(0, Head.size() - 2); - } else - CC = MBlazeCC::EQ; - - MBlazeOperand::CreateToken(Op, Head, NameLoc); - Operands.push_back(Op.take()); - - MBlazeOperand::CreateCondCode(Op, MBlazeCC::CC(CC), NameLoc); - Operands.push_back(Op.take()); - - // Add the remaining tokens in the mnemonic. - while (Next != StringRef::npos) { - Start = Next; - Next = Name.find('.', Start + 1); - Head = Name.slice(Start, Next); - - MBlazeOperand::CreateToken(Op, Head, NameLoc); - Operands.push_back(Op.take()); - } +MBlazeOperand *MBlazeAsmParser:: +ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { + MBlazeOperand *Op; - // Read the remaining operands. - if (getLexer().isNot(AsmToken::EndOfStatement)) { - // Read the first operand. - OwningPtr<MBlazeOperand> Op; - if (ParseOperand(Op)) { - Parser.EatToEndOfStatement(); - return true; - } - Operands.push_back(Op.take()); + // Attempt to parse the next token as a register name + Op = ParseRegister(); - while (getLexer().is(AsmToken::Comma)) { - Parser.Lex(); // Eat the comma. + // Attempt to parse the next token as an FSL immediate + if (!Op) + Op = ParseFsl(); - // Parse and remember the operand. - if (ParseOperand(Op)) { - Parser.EatToEndOfStatement(); - return true; - } - Operands.push_back(Op.take()); - } - } - - if (getLexer().isNot(AsmToken::EndOfStatement)) { - Parser.EatToEndOfStatement(); - return TokError("unexpected token in argument list"); - } - Parser.Lex(); // Consume the EndOfStatement - return false; -} + // Attempt to parse the next token as an immediate + if (!Op) + Op = ParseImmediate(); -/// ParseDirective parses the arm specific directives -bool MBlazeAsmParser::ParseDirective(AsmToken DirectiveID) { - StringRef IDVal = DirectiveID.getIdentifier(); - if (IDVal == ".word") - return ParseDirectiveWord(4, DirectiveID.getLoc()); - else if (IDVal == ".code") - return ParseDirectiveCode(DirectiveID.getLoc()); - else if (IDVal == ".syntax") - return ParseDirectiveSyntax(DirectiveID.getLoc()); - return true; -} + // Move past the parsed token in the token stream + getLexer().Lex(); -/// ParseDirectiveWord -/// ::= .word [ expression (, expression)* ] -bool MBlazeAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) { - if (getLexer().isNot(AsmToken::EndOfStatement)) { - for (;;) { - const MCExpr *Value; - if (getParser().ParseExpression(Value)) - return true; - - getParser().getStreamer().EmitValue(Value, Size, 0/*addrspace*/); - - if (getLexer().is(AsmToken::EndOfStatement)) - break; - - // FIXME: Improve diagnostic. - if (getLexer().isNot(AsmToken::Comma)) - return Error(L, "unexpected token in directive"); - Parser.Lex(); - } + // If the token could not be parsed then fail + if (!Op) { + Error(Parser.getTok().getLoc(), "unknown operand"); + return 0; } - Parser.Lex(); - return false; + // Push the parsed operand into the list of operands + Operands.push_back(Op); + return Op; } -/// ParseDirectiveSyntax -/// ::= .syntax unified | divided -bool MBlazeAsmParser::ParseDirectiveSyntax(SMLoc L) { - const AsmToken &Tok = Parser.getTok(); - if (Tok.isNot(AsmToken::Identifier)) - return Error(L, "unexpected token in .syntax directive"); - StringRef Mode = Tok.getString(); - if (Mode == "unified" || Mode == "UNIFIED") - Parser.Lex(); - else if (Mode == "divided" || Mode == "DIVIDED") - Parser.Lex(); - else - return Error(L, "unrecognized syntax mode in .syntax directive"); +/// Parse an mblaze instruction mnemonic followed by its operands. +bool MBlazeAsmParser:: +ParseInstruction(StringRef Name, SMLoc NameLoc, + SmallVectorImpl<MCParsedAsmOperand*> &Operands) { + // The first operand is the token for the instruction name + Operands.push_back(MBlazeOperand::CreateToken(Name, NameLoc)); + + // If there are no more operands then finish + if (getLexer().is(AsmToken::EndOfStatement)) + return false; - if (getLexer().isNot(AsmToken::EndOfStatement)) - return Error(Parser.getTok().getLoc(), "unexpected token in directive"); - Parser.Lex(); + // Parse the first operand + if (ParseOperand(Operands)) + return true; - // TODO tell the MC streamer the mode - // getParser().getStreamer().Emit???(); - return false; -} + while (getLexer().isNot(AsmToken::EndOfStatement) && + getLexer().is(AsmToken::Comma)) { + // Make sure there is a comma separating operands + // if (getLexer().isNot(AsmToken::Comma)) + // return false; -/// ParseDirectiveCode -/// ::= .code 16 | 32 -bool MBlazeAsmParser::ParseDirectiveCode(SMLoc L) { - const AsmToken &Tok = Parser.getTok(); - if (Tok.isNot(AsmToken::Integer)) - return Error(L, "unexpected token in .code directive"); - int64_t Val = Parser.getTok().getIntVal(); - if (Val == 16) - Parser.Lex(); - else if (Val == 32) - Parser.Lex(); - else - return Error(L, "invalid operand to .code directive"); + // Consume the comma token + getLexer().Lex(); + + // Parse the next operand + if (ParseOperand(Operands)) + return true; + } - if (getLexer().isNot(AsmToken::EndOfStatement)) - return Error(Parser.getTok().getLoc(), "unexpected token in directive"); - Parser.Lex(); + // If the instruction requires a memory operand then we need to + // replace the last two operands (base+offset) with a single + // memory operand. + if (Name.startswith("lw") || Name.startswith("sw") || + Name.startswith("lh") || Name.startswith("sh") || + Name.startswith("lb") || Name.startswith("sb")) + return ParseMemory(Operands); - // TODO tell the MC streamer the mode - // getParser().getStreamer().Emit???(); return false; } +/// ParseDirective parses the arm specific directives +bool MBlazeAsmParser::ParseDirective(AsmToken DirectiveID) { + return true; +} + extern "C" void LLVMInitializeMBlazeAsmLexer(); /// Force static initialization. diff --git a/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.cpp b/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.cpp index 01a48b2..e09829c 100644 --- a/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.cpp +++ b/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.cpp @@ -56,38 +56,38 @@ static unsigned mblazeBinary2Opcode[] = { MBlaze::SBI, MBlaze::SHI, MBlaze::SWI, UNSUPPORTED, //3C,3D,3E,3F }; -static unsigned getRD( uint32_t insn ) { - return MBlazeRegisterInfo::getRegisterFromNumbering( (insn>>21)&0x1F ); +static unsigned getRD(uint32_t insn) { + return MBlazeRegisterInfo::getRegisterFromNumbering((insn>>21)&0x1F); } -static unsigned getRA( uint32_t insn ) { - return MBlazeRegisterInfo::getRegisterFromNumbering( (insn>>16)&0x1F ); +static unsigned getRA(uint32_t insn) { + return MBlazeRegisterInfo::getRegisterFromNumbering((insn>>16)&0x1F); } -static unsigned getRB( uint32_t insn ) { - return MBlazeRegisterInfo::getRegisterFromNumbering( (insn>>11)&0x1F ); +static unsigned getRB(uint32_t insn) { + return MBlazeRegisterInfo::getRegisterFromNumbering((insn>>11)&0x1F); } -static int64_t getRS( uint32_t insn ) { +static int64_t getRS(uint32_t insn) { int16_t val = (insn & 0x3FFF); return val; } -static int64_t getIMM( uint32_t insn ) { +static int64_t getIMM(uint32_t insn) { int16_t val = (insn & 0xFFFF); return val; } -static int64_t getSHT( uint32_t insn ) { +static int64_t getSHT(uint32_t insn) { int16_t val = (insn & 0x1F); return val; } -static unsigned getFLAGS( int32_t insn ) { +static unsigned getFLAGS(int32_t insn) { return (insn & 0x7FF); } -static int64_t getFSL( uint32_t insn ) { +static int64_t getFSL(uint32_t insn) { int16_t val = (insn & 0xF); return val; } @@ -412,7 +412,7 @@ static unsigned decodeRTSD(uint32_t insn) { } } -static unsigned getOPCODE( uint32_t insn ) { +static unsigned getOPCODE(uint32_t insn) { unsigned opcode = mblazeBinary2Opcode[ (insn>>26)&0x3F ]; switch (opcode) { case MBlaze::MUL: return decodeMUL(insn); @@ -465,102 +465,99 @@ bool MBlazeDisassembler::getInstruction(MCInst &instr, // Get the MCInst opcode from the binary instruction and make sure // that it is a valid instruction. - unsigned opcode = getOPCODE( insn ); - if( opcode == UNSUPPORTED ) + unsigned opcode = getOPCODE(insn); + if (opcode == UNSUPPORTED) return false; instr.setOpcode(opcode); uint64_t tsFlags = MBlazeInsts[opcode].TSFlags; - switch( (tsFlags & MBlazeII::FormMask) ) { - default: - errs() << "Opcode: " << MBlazeInsts[opcode].Name << "\n"; - errs() << "Flags: "; errs().write_hex( tsFlags ); errs() << "\n"; - return false; + switch ((tsFlags & MBlazeII::FormMask)) { + default: llvm_unreachable("unknown instruction encoding"); case MBlazeII::FRRR: - instr.addOperand( MCOperand::CreateReg( getRD(insn) ) ); - instr.addOperand( MCOperand::CreateReg( getRA(insn) ) ); - instr.addOperand( MCOperand::CreateReg( getRB(insn) ) ); + instr.addOperand(MCOperand::CreateReg(getRD(insn))); + instr.addOperand(MCOperand::CreateReg(getRA(insn))); + instr.addOperand(MCOperand::CreateReg(getRB(insn))); break; case MBlazeII::FRRI: - instr.addOperand( MCOperand::CreateReg( getRD(insn) ) ); - instr.addOperand( MCOperand::CreateReg( getRA(insn) ) ); - instr.addOperand( MCOperand::CreateImm( getIMM(insn) ) ); + instr.addOperand(MCOperand::CreateReg(getRD(insn))); + instr.addOperand(MCOperand::CreateReg(getRA(insn))); + instr.addOperand(MCOperand::CreateImm(getIMM(insn))); break; case MBlazeII::FCRR: - instr.addOperand( MCOperand::CreateReg( getRA(insn) ) ); - instr.addOperand( MCOperand::CreateReg( getRB(insn) ) ); + instr.addOperand(MCOperand::CreateReg(getRA(insn))); + instr.addOperand(MCOperand::CreateReg(getRB(insn))); break; case MBlazeII::FCRI: - instr.addOperand( MCOperand::CreateReg( getRA(insn) ) ); - instr.addOperand( MCOperand::CreateImm( getIMM(insn) ) ); + instr.addOperand(MCOperand::CreateReg(getRA(insn))); + instr.addOperand(MCOperand::CreateImm(getIMM(insn))); break; case MBlazeII::FRCR: - instr.addOperand( MCOperand::CreateReg( getRD(insn) ) ); - instr.addOperand( MCOperand::CreateReg( getRB(insn) ) ); + instr.addOperand(MCOperand::CreateReg(getRD(insn))); + instr.addOperand(MCOperand::CreateReg(getRB(insn))); break; case MBlazeII::FRCI: - instr.addOperand( MCOperand::CreateReg( getRD(insn) ) ); - instr.addOperand( MCOperand::CreateImm( getIMM(insn) ) ); + instr.addOperand(MCOperand::CreateReg(getRD(insn))); + instr.addOperand(MCOperand::CreateImm(getIMM(insn))); break; case MBlazeII::FCCR: - instr.addOperand( MCOperand::CreateReg( getRB(insn) ) ); + instr.addOperand(MCOperand::CreateReg(getRB(insn))); break; case MBlazeII::FCCI: - instr.addOperand( MCOperand::CreateImm( getIMM(insn) ) ); + instr.addOperand(MCOperand::CreateImm(getIMM(insn))); break; case MBlazeII::FRRCI: - instr.addOperand( MCOperand::CreateReg( getRD(insn) ) ); - instr.addOperand( MCOperand::CreateReg( getRA(insn) ) ); - instr.addOperand( MCOperand::CreateImm( getSHT(insn) ) ); + instr.addOperand(MCOperand::CreateReg(getRD(insn))); + instr.addOperand(MCOperand::CreateReg(getRA(insn))); + instr.addOperand(MCOperand::CreateImm(getSHT(insn))); break; case MBlazeII::FRRC: - instr.addOperand( MCOperand::CreateReg( getRD(insn) ) ); - instr.addOperand( MCOperand::CreateReg( getRA(insn) ) ); + instr.addOperand(MCOperand::CreateReg(getRD(insn))); + instr.addOperand(MCOperand::CreateReg(getRA(insn))); break; case MBlazeII::FRCX: - instr.addOperand( MCOperand::CreateReg( getRD(insn) ) ); - instr.addOperand( MCOperand::CreateImm( getFSL(insn) ) ); + instr.addOperand(MCOperand::CreateReg(getRD(insn))); + instr.addOperand(MCOperand::CreateImm(getFSL(insn))); break; case MBlazeII::FRCS: - instr.addOperand( MCOperand::CreateReg( getRD(insn) ) ); - instr.addOperand( MCOperand::CreateImm( getRS(insn) ) ); + instr.addOperand(MCOperand::CreateReg(getRD(insn))); + instr.addOperand(MCOperand::CreateImm(getRS(insn))); break; case MBlazeII::FCRCS: - instr.addOperand( MCOperand::CreateReg( getRA(insn) ) ); - instr.addOperand( MCOperand::CreateImm( getRS(insn) ) ); + instr.addOperand(MCOperand::CreateReg(getRA(insn))); + instr.addOperand(MCOperand::CreateImm(getRS(insn))); break; case MBlazeII::FCRCX: - instr.addOperand( MCOperand::CreateReg( getRA(insn) ) ); - instr.addOperand( MCOperand::CreateImm( getFSL(insn) ) ); + instr.addOperand(MCOperand::CreateReg(getRA(insn))); + instr.addOperand(MCOperand::CreateImm(getFSL(insn))); break; case MBlazeII::FCX: - instr.addOperand( MCOperand::CreateImm( getFSL(insn) ) ); + instr.addOperand(MCOperand::CreateImm(getFSL(insn))); break; case MBlazeII::FCR: - instr.addOperand( MCOperand::CreateReg( getRB(insn) ) ); + instr.addOperand(MCOperand::CreateReg(getRB(insn))); break; case MBlazeII::FRIR: - instr.addOperand( MCOperand::CreateReg( getRD(insn) ) ); - instr.addOperand( MCOperand::CreateImm( getIMM(insn) ) ); - instr.addOperand( MCOperand::CreateReg( getRA(insn) ) ); + instr.addOperand(MCOperand::CreateReg(getRD(insn))); + instr.addOperand(MCOperand::CreateImm(getIMM(insn))); + instr.addOperand(MCOperand::CreateReg(getRA(insn))); break; } diff --git a/lib/Target/MBlaze/InstPrinter/MBlazeInstPrinter.cpp b/lib/Target/MBlaze/InstPrinter/MBlazeInstPrinter.cpp index 4c59b54..30745c6 100644 --- a/lib/Target/MBlaze/InstPrinter/MBlazeInstPrinter.cpp +++ b/lib/Target/MBlaze/InstPrinter/MBlazeInstPrinter.cpp @@ -102,7 +102,7 @@ void MBlazeInstPrinter::printUnsignedImm(const MCInst *MI, int OpNo, } void MBlazeInstPrinter::printMemOperand(const MCInst *MI, int OpNo, - raw_ostream &O, const char *Modifier ) { + raw_ostream &O, const char *Modifier) { printOperand(MI, OpNo+1, O, NULL); O << ", "; printOperand(MI, OpNo, O, NULL); diff --git a/lib/Target/MBlaze/MBlazeAsmBackend.cpp b/lib/Target/MBlaze/MBlazeAsmBackend.cpp index 05d9c90..9167809 100644 --- a/lib/Target/MBlaze/MBlazeAsmBackend.cpp +++ b/lib/Target/MBlaze/MBlazeAsmBackend.cpp @@ -70,8 +70,8 @@ bool MBlazeAsmBackend::WriteNopData(uint64_t Count, MCObjectWriter *OW) const { if ((Count % 4) != 0) return false; - for (uint64_t i = 0; i < Count; i += 4 ) - OW->Write32( 0x00000000 ); + for (uint64_t i = 0; i < Count; i += 4) + OW->Write32(0x00000000); return true; } @@ -114,17 +114,17 @@ public: void ELFMBlazeAsmBackend::ApplyFixup(const MCFixup &Fixup, MCDataFragment &DF, uint64_t Value) const { unsigned Size = getFixupKindSize(Fixup.getKind()); - + assert(Fixup.getOffset() + Size <= DF.getContents().size() && "Invalid fixup offset!"); char *data = DF.getContents().data() + Fixup.getOffset(); switch (Size) { - default: llvm_unreachable( "Cannot fixup unknown value." ); - case 1: llvm_unreachable( "Cannot fixup 1 byte value." ); - case 8: llvm_unreachable( "Cannot fixup 8 byte value." ); + default: llvm_unreachable("Cannot fixup unknown value."); + case 1: llvm_unreachable("Cannot fixup 1 byte value."); + case 8: llvm_unreachable("Cannot fixup 8 byte value."); - case 4: + case 4: *(data+7) = uint8_t(Value); *(data+6) = uint8_t(Value >> 8); *(data+3) = uint8_t(Value >> 16); diff --git a/lib/Target/MBlaze/MBlazeAsmPrinter.cpp b/lib/Target/MBlaze/MBlazeAsmPrinter.cpp index d0b424d..9c9ec75 100644 --- a/lib/Target/MBlaze/MBlazeAsmPrinter.cpp +++ b/lib/Target/MBlaze/MBlazeAsmPrinter.cpp @@ -69,7 +69,7 @@ namespace { void printMemOperand(const MachineInstr *MI, int opNum, raw_ostream &O, const char *Modifier = 0); - void EmitInstruction(const MachineInstr *MI); + void EmitInstruction(const MachineInstr *MI); }; } // end of anonymous namespace diff --git a/lib/Target/MBlaze/MBlazeCallingConv.td b/lib/Target/MBlaze/MBlazeCallingConv.td index d0de59d..d037b0e 100644 --- a/lib/Target/MBlaze/MBlazeCallingConv.td +++ b/lib/Target/MBlaze/MBlazeCallingConv.td @@ -1,16 +1,16 @@ //===- MBlazeCallingConv.td - Calling Conventions for MBlaze -*- tablegen -*-=// -// +// // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. -// +// //===----------------------------------------------------------------------===// // This describes the calling conventions for MBlaze architecture. //===----------------------------------------------------------------------===// /// CCIfSubtarget - Match if the current subtarget has a feature F. -class CCIfSubtarget<string F, CCAction A>: +class CCIfSubtarget<string F, CCAction A>: CCIf<!strconcat("State.getTarget().getSubtarget<MBlazeSubtarget>().", F), A>; //===----------------------------------------------------------------------===// diff --git a/lib/Target/MBlaze/MBlazeDelaySlotFiller.cpp b/lib/Target/MBlaze/MBlazeDelaySlotFiller.cpp index 8918b48..32424e5 100644 --- a/lib/Target/MBlaze/MBlazeDelaySlotFiller.cpp +++ b/lib/Target/MBlaze/MBlazeDelaySlotFiller.cpp @@ -36,7 +36,7 @@ namespace { const TargetInstrInfo *TII; static char ID; - Filler(TargetMachine &tm) + Filler(TargetMachine &tm) : MachineFunctionPass(ID), TM(tm), TII(tm.getInstrInfo()) { } virtual const char *getPassName() const { @@ -56,44 +56,44 @@ namespace { char Filler::ID = 0; } // end of anonymous namespace -static bool hasImmInstruction( MachineBasicBlock::iterator &candidate ) { +static bool hasImmInstruction(MachineBasicBlock::iterator &candidate) { // Any instruction with an immediate mode operand greater than // 16-bits requires an implicit IMM instruction. unsigned numOper = candidate->getNumOperands(); - for( unsigned op = 0; op < numOper; ++op ) { - if( candidate->getOperand(op).isImm() && - (candidate->getOperand(op).getImm() & 0xFFFFFFFFFFFF0000LL) != 0 ) + for (unsigned op = 0; op < numOper; ++op) { + if (candidate->getOperand(op).isImm() && + (candidate->getOperand(op).getImm() & 0xFFFFFFFFFFFF0000LL) != 0) return true; // FIXME: we could probably check to see if the FP value happens // to not need an IMM instruction. For now we just always // assume that FP values always do. - if( candidate->getOperand(op).isFPImm() ) + if (candidate->getOperand(op).isFPImm()) return true; } return false; } -static bool delayHasHazard( MachineBasicBlock::iterator &candidate, - MachineBasicBlock::iterator &slot ) { +static bool delayHasHazard(MachineBasicBlock::iterator &candidate, + MachineBasicBlock::iterator &slot) { // Loop over all of the operands in the branch instruction // and make sure that none of them are defined by the // candidate instruction. unsigned numOper = slot->getNumOperands(); - for( unsigned op = 0; op < numOper; ++op ) { - if( !slot->getOperand(op).isReg() || + for (unsigned op = 0; op < numOper; ++op) { + if (!slot->getOperand(op).isReg() || !slot->getOperand(op).isUse() || - slot->getOperand(op).isImplicit() ) + slot->getOperand(op).isImplicit()) continue; unsigned cnumOper = candidate->getNumOperands(); - for( unsigned cop = 0; cop < cnumOper; ++cop ) { - if( candidate->getOperand(cop).isReg() && + for (unsigned cop = 0; cop < cnumOper; ++cop) { + if (candidate->getOperand(cop).isReg() && candidate->getOperand(cop).isDef() && - candidate->getOperand(cop).getReg() == - slot->getOperand(op).getReg() ) + candidate->getOperand(cop).getReg() == + slot->getOperand(op).getReg()) return true; } } @@ -102,20 +102,20 @@ static bool delayHasHazard( MachineBasicBlock::iterator &candidate, return false; } -static bool usedBeforeDelaySlot( MachineBasicBlock::iterator &candidate, - MachineBasicBlock::iterator &slot ) { +static bool usedBeforeDelaySlot(MachineBasicBlock::iterator &candidate, + MachineBasicBlock::iterator &slot) { MachineBasicBlock::iterator I = candidate; for (++I; I != slot; ++I) { unsigned numOper = I->getNumOperands(); - for( unsigned op = 0; op < numOper; ++op ) { - if( I->getOperand(op).isReg() && - I->getOperand(op).isUse() ) { + for (unsigned op = 0; op < numOper; ++op) { + if (I->getOperand(op).isReg() && + I->getOperand(op).isUse()) { unsigned reg = I->getOperand(op).getReg(); unsigned cops = candidate->getNumOperands(); - for( unsigned cop = 0; cop < cops; ++cop ) { - if( candidate->getOperand(cop).isReg() && + for (unsigned cop = 0; cop < cops; ++cop) { + if (candidate->getOperand(cop).isReg() && candidate->getOperand(cop).isDef() && - candidate->getOperand(cop).getReg() == reg ) + candidate->getOperand(cop).getReg() == reg) return true; } } @@ -130,9 +130,9 @@ findDelayInstr(MachineBasicBlock &MBB,MachineBasicBlock::iterator &slot) { MachineBasicBlock::iterator found = MBB.end(); for (MachineBasicBlock::iterator I = MBB.begin(); I != slot; ++I) { TargetInstrDesc desc = I->getDesc(); - if( desc.hasDelaySlot() || desc.isBranch() || - desc.mayLoad() || desc. mayStore() || - hasImmInstruction(I) || delayHasHazard(I,slot) || + if (desc.hasDelaySlot() || desc.isBranch() || + desc.mayLoad() || desc. mayStore() || + hasImmInstruction(I) || delayHasHazard(I,slot) || usedBeforeDelaySlot(I,slot)) continue; found = I; @@ -155,10 +155,10 @@ bool Filler::runOnMachineBasicBlock(MachineBasicBlock &MBB) { ++FilledSlots; Changed = true; - if( D == MBB.end() ) + if (D == MBB.end()) BuildMI(MBB, J, I->getDebugLoc(), TII->get(MBlaze::NOP)); else - MBB.splice( J, &MBB, D ); + MBB.splice(J, &MBB, D); } return Changed; } diff --git a/lib/Target/MBlaze/MBlazeELFWriterInfo.cpp b/lib/Target/MBlaze/MBlazeELFWriterInfo.cpp index 378b5d4..cf6312f 100644 --- a/lib/Target/MBlaze/MBlazeELFWriterInfo.cpp +++ b/lib/Target/MBlaze/MBlazeELFWriterInfo.cpp @@ -32,7 +32,7 @@ MBlazeELFWriterInfo::MBlazeELFWriterInfo(TargetMachine &TM) MBlazeELFWriterInfo::~MBlazeELFWriterInfo() {} unsigned MBlazeELFWriterInfo::getRelocationType(unsigned MachineRelTy) const { - switch(MachineRelTy) { + switch (MachineRelTy) { case MBlaze::reloc_pcrel_word: return R_MICROBLAZE_64_PCREL; case MBlaze::reloc_absolute_word: @@ -45,7 +45,7 @@ unsigned MBlazeELFWriterInfo::getRelocationType(unsigned MachineRelTy) const { long int MBlazeELFWriterInfo::getDefaultAddendForRelTy(unsigned RelTy, long int Modifier) const { - switch(RelTy) { + switch (RelTy) { case R_MICROBLAZE_32_PCREL: return Modifier - 4; case R_MICROBLAZE_32: @@ -58,7 +58,7 @@ long int MBlazeELFWriterInfo::getDefaultAddendForRelTy(unsigned RelTy, unsigned MBlazeELFWriterInfo::getRelocationTySize(unsigned RelTy) const { // FIXME: Most of these sizes are guesses based on the name - switch(RelTy) { + switch (RelTy) { case R_MICROBLAZE_32: case R_MICROBLAZE_32_PCREL: case R_MICROBLAZE_32_PCREL_LO: @@ -83,7 +83,7 @@ unsigned MBlazeELFWriterInfo::getRelocationTySize(unsigned RelTy) const { bool MBlazeELFWriterInfo::isPCRelativeRel(unsigned RelTy) const { // FIXME: Most of these are guesses based on the name - switch(RelTy) { + switch (RelTy) { case R_MICROBLAZE_32_PCREL: case R_MICROBLAZE_64_PCREL: case R_MICROBLAZE_32_PCREL_LO: diff --git a/lib/Target/MBlaze/MBlazeELFWriterInfo.h b/lib/Target/MBlaze/MBlazeELFWriterInfo.h index 2e6a9f3..abea992 100644 --- a/lib/Target/MBlaze/MBlazeELFWriterInfo.h +++ b/lib/Target/MBlaze/MBlazeELFWriterInfo.h @@ -31,7 +31,7 @@ namespace llvm { R_MICROBLAZE_32_LO = 6, R_MICROBLAZE_SRO32 = 7, R_MICROBLAZE_SRW32 = 8, - R_MICROBLAZE_64_NONE = 9, + R_MICROBLAZE_64_NONE = 9, R_MICROBLAZE_32_SYM_OP_SYM = 10, R_MICROBLAZE_GNU_VTINHERIT = 11, R_MICROBLAZE_GNU_VTENTRY = 12, diff --git a/lib/Target/MBlaze/MBlazeISelDAGToDAG.cpp b/lib/Target/MBlaze/MBlazeISelDAGToDAG.cpp index 688ad70..29350d2 100644 --- a/lib/Target/MBlaze/MBlazeISelDAGToDAG.cpp +++ b/lib/Target/MBlaze/MBlazeISelDAGToDAG.cpp @@ -159,7 +159,6 @@ SelectAddrRegImm(SDValue N, SDValue &Disp, SDValue &Base) { } else { Base = N.getOperand(0); } - DEBUG( errs() << "WESLEY: Using Operand Immediate\n" ); return true; // [r+i] } } else if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N)) { @@ -167,7 +166,6 @@ SelectAddrRegImm(SDValue N, SDValue &Disp, SDValue &Base) { uint32_t Imm = CN->getZExtValue(); Disp = CurDAG->getTargetConstant(Imm, CN->getValueType(0)); Base = CurDAG->getRegister(MBlaze::R0, CN->getValueType(0)); - DEBUG( errs() << "WESLEY: Using Constant Node\n" ); return true; } @@ -192,20 +190,15 @@ SDNode* MBlazeDAGToDAGISel::Select(SDNode *Node) { unsigned Opcode = Node->getOpcode(); DebugLoc dl = Node->getDebugLoc(); - // Dump information about the Node being selected - DEBUG(errs() << "Selecting: "; Node->dump(CurDAG); errs() << "\n"); - // If we have a custom node, we already have selected! - if (Node->isMachineOpcode()) { - DEBUG(errs() << "== "; Node->dump(CurDAG); errs() << "\n"); + if (Node->isMachineOpcode()) return NULL; - } /// // Instruction Selection not handled by the auto-generated // tablegen selection should be handled here. /// - switch(Opcode) { + switch (Opcode) { default: break; // Get target GOT address. @@ -235,8 +228,8 @@ SDNode* MBlazeDAGToDAGISel::Select(SDNode *Node) { SDValue R20Reg = CurDAG->getRegister(MBlaze::R20, MVT::i32); SDValue InFlag(0, 0); - if ( (isa<GlobalAddressSDNode>(Callee)) || - (isa<ExternalSymbolSDNode>(Callee)) ) + if ((isa<GlobalAddressSDNode>(Callee)) || + (isa<ExternalSymbolSDNode>(Callee))) { /// Direct call for global addresses and external symbols SDValue GPReg = CurDAG->getRegister(MBlaze::R15, MVT::i32); diff --git a/lib/Target/MBlaze/MBlazeISelLowering.cpp b/lib/Target/MBlaze/MBlazeISelLowering.cpp index 40201d7..2fc55c5 100644 --- a/lib/Target/MBlaze/MBlazeISelLowering.cpp +++ b/lib/Target/MBlaze/MBlazeISelLowering.cpp @@ -290,7 +290,7 @@ MBlazeTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, else if (MI->getOpcode() == MBlaze::ShiftRL) BuildMI(loop, dl, TII->get(MBlaze::SRL), NDST).addReg(DST); else - llvm_unreachable( "Cannot lower unknown shift instruction" ); + llvm_unreachable("Cannot lower unknown shift instruction"); BuildMI(loop, dl, TII->get(MBlaze::ADDI), NAMT) .addReg(SAMT) @@ -332,7 +332,7 @@ MBlazeTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, unsigned Opc; switch (MI->getOperand(4).getImm()) { - default: llvm_unreachable( "Unknown branch condition" ); + default: llvm_unreachable("Unknown branch condition"); case MBlazeCC::EQ: Opc = MBlaze::BNEID; break; case MBlazeCC::NE: Opc = MBlaze::BEQID; break; case MBlazeCC::GT: Opc = MBlaze::BLEID; break; @@ -396,9 +396,9 @@ SDValue MBlazeTargetLowering::LowerSELECT_CC(SDValue Op, CompareFlag = DAG.getNode(MBlazeISD::ICmp, dl, MVT::i32, LHS, RHS) .getValue(1); } else { - llvm_unreachable( "Cannot lower select_cc with unknown type" ); + llvm_unreachable("Cannot lower select_cc with unknown type"); } - + return DAG.getNode(Opc, dl, TrueVal.getValueType(), TrueVal, FalseVal, CompareFlag); } @@ -429,7 +429,7 @@ LowerJumpTable(SDValue Op, SelectionDAG &DAG) const { EVT PtrVT = Op.getValueType(); JumpTableSDNode *JT = cast<JumpTableSDNode>(Op); - SDValue JTI = DAG.getTargetJumpTable(JT->getIndex(), PtrVT, 0 ); + SDValue JTI = DAG.getTargetJumpTable(JT->getIndex(), PtrVT, 0); return DAG.getNode(MBlazeISD::Wrap, dl, MVT::i32, JTI); } @@ -441,7 +441,7 @@ LowerConstantPool(SDValue Op, SelectionDAG &DAG) const { DebugLoc dl = Op.getDebugLoc(); SDValue CP = DAG.getTargetConstantPool(C, MVT::i32, N->getAlignment(), - N->getOffset(), 0 ); + N->getOffset(), 0); return DAG.getNode(MBlazeISD::Wrap, dl, MVT::i32, CP); } @@ -616,10 +616,10 @@ LowerCall(SDValue Chain, SDValue Callee, CallingConv::ID CallConv, // node so that legalize doesn't hack it. if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) Callee = DAG.getTargetGlobalAddress(G->getGlobal(), dl, - getPointerTy(), 0, 0 ); + getPointerTy(), 0, 0); else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee)) Callee = DAG.getTargetExternalSymbol(S->getSymbol(), - getPointerTy(), 0 ); + getPointerTy(), 0); // MBlazeJmpLink = #chain, #target_address, #opt_in_flags... // = Chain, Callee, Reg#1, Reg#2, ... @@ -675,7 +675,7 @@ LowerCallResult(SDValue Chain, SDValue InFlag, CallingConv::ID CallConv, RVLocs[i].getValVT(), InFlag).getValue(1); InFlag = Chain.getValue(2); InVals.push_back(Chain.getValue(0)); - } + } return Chain; } @@ -785,7 +785,7 @@ LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, // To meet ABI, when VARARGS are passed on registers, the registers // must have their values written to the caller stack frame. If the last - // argument was placed in the stack, there's no need to save any register. + // argument was placed in the stack, there's no need to save any register. if ((isVarArg) && ArgRegEnd) { if (StackPtr.getNode() == 0) StackPtr = DAG.getRegister(StackReg, getPointerTy()); @@ -817,7 +817,7 @@ LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, } } - // All stores are grouped in one node to allow the matching between + // All stores are grouped in one node to allow the matching between // the size of Ins and InVals. This only happens when on varg functions if (!OutChains.empty()) { OutChains.push_back(Chain); diff --git a/lib/Target/MBlaze/MBlazeInstrFPU.td b/lib/Target/MBlaze/MBlazeInstrFPU.td index a26011d..1793fab 100644 --- a/lib/Target/MBlaze/MBlazeInstrFPU.td +++ b/lib/Target/MBlaze/MBlazeInstrFPU.td @@ -100,11 +100,11 @@ let Predicates=[HasFPU] in { def FMUL : ArithF<0x16, 0x100, "fmul ", fmul, IIAlu>; def FDIV : ArithF<0x16, 0x180, "fdiv ", fdiv, IIAlu>; - def LWF : LoadFM<0x32, "lw ", load>; - def LWFI : LoadFMI<0x32, "lwi ", load>; + def LWF : LoadFM<0x32, "lw ", load>; + def LWFI : LoadFMI<0x32, "lwi ", load>; - def SWF : StoreFM<0x32, "sw ", store>; - def SWFI : StoreFMI<0x32, "swi ", store>; + def SWF : StoreFM<0x32, "sw ", store>; + def SWFI : StoreFMI<0x32, "swi ", store>; } let Predicates=[HasFPU,HasSqrt] in { diff --git a/lib/Target/MBlaze/MBlazeInstrFormats.td b/lib/Target/MBlaze/MBlazeInstrFormats.td index 8cd330b..383dc56 100644 --- a/lib/Target/MBlaze/MBlazeInstrFormats.td +++ b/lib/Target/MBlaze/MBlazeInstrFormats.td @@ -58,8 +58,8 @@ class MBlazeInst<bits<6> op, Format form, dag outs, dag ins, string asmstr, bits<6> FormBits = Form.Value; // Top 6 bits are the 'opcode' field - let Inst{0-5} = opcode; - + let Inst{0-5} = opcode; + // If the instruction is marked as a pseudo, set isCodeGenOnly so that the // assembler and disassmbler ignore it. let isCodeGenOnly = !eq(!cast<string>(form), "FPseudo"); @@ -86,15 +86,15 @@ class MBlazePseudo<dag outs, dag ins, string asmstr, list<dag> pattern>: //===----------------------------------------------------------------------===// class TA<bits<6> op, bits<11> flags, dag outs, dag ins, string asmstr, - list<dag> pattern, InstrItinClass itin> : - MBlazeInst<op,FRRR,outs, ins, asmstr, pattern, itin> + list<dag> pattern, InstrItinClass itin> : + MBlazeInst<op,FRRR,outs, ins, asmstr, pattern, itin> { bits<5> rd; bits<5> ra; bits<5> rb; let Inst{6-10} = rd; - let Inst{11-15} = ra; + let Inst{11-15} = ra; let Inst{16-20} = rb; let Inst{21-31} = flags; } @@ -104,15 +104,15 @@ class TA<bits<6> op, bits<11> flags, dag outs, dag ins, string asmstr, //===----------------------------------------------------------------------===// class TB<bits<6> op, dag outs, dag ins, string asmstr, list<dag> pattern, - InstrItinClass itin> : - MBlazeInst<op, FRRI, outs, ins, asmstr, pattern, itin> + InstrItinClass itin> : + MBlazeInst<op, FRRI, outs, ins, asmstr, pattern, itin> { bits<5> rd; bits<5> ra; bits<16> imm16; let Inst{6-10} = rd; - let Inst{11-15} = ra; + let Inst{11-15} = ra; let Inst{16-31} = imm16; } @@ -121,7 +121,7 @@ class TB<bits<6> op, dag outs, dag ins, string asmstr, list<dag> pattern, // the LLVM DAG : <|opcode|rd|ra|immediate|> //===----------------------------------------------------------------------===// class TBR<bits<6> op, dag outs, dag ins, string asmstr, list<dag> pattern, - InstrItinClass itin> : + InstrItinClass itin> : TB<op, outs, ins, asmstr, pattern, itin> { bits<5> rrd; bits<16> rimm16; diff --git a/lib/Target/MBlaze/MBlazeInstrInfo.td b/lib/Target/MBlaze/MBlazeInstrInfo.td index c57c1ce..8aa04df 100644 --- a/lib/Target/MBlaze/MBlazeInstrInfo.td +++ b/lib/Target/MBlaze/MBlazeInstrInfo.td @@ -64,6 +64,16 @@ def HasMMU : Predicate<"Subtarget.hasMMU()">; // MBlaze Operand, Complex Patterns and Transformations Definitions. //===----------------------------------------------------------------------===// +def MBlazeMemAsmOperand : AsmOperandClass { + let Name = "Mem"; + let SuperClasses = []; +} + +def MBlazeFslAsmOperand : AsmOperandClass { + let Name = "Fsl"; + let SuperClasses = []; +} + // Instruction operand types def brtarget : Operand<OtherVT>; def calltarget : Operand<i32>; @@ -79,17 +89,20 @@ def uimm16 : Operand<i32> { // FSL Operand def fslimm : Operand<i32> { let PrintMethod = "printFSLImm"; + let ParserMatchClass = MBlazeFslAsmOperand; } // Address operand def memri : Operand<i32> { let PrintMethod = "printMemOperand"; let MIOperandInfo = (ops simm16, GPR); + let ParserMatchClass = MBlazeMemAsmOperand; } def memrr : Operand<i32> { let PrintMethod = "printMemOperand"; let MIOperandInfo = (ops GPR, GPR); + let ParserMatchClass = MBlazeMemAsmOperand; } // Node immediate fits as 16-bit sign extended on target immediate. @@ -490,31 +503,31 @@ let isReturn=1, isTerminator=1, hasDelaySlot=1, isBarrier=1, hasCtrlDep=1, rd=0x10, Form=FCRI in { def RTSD : TB<0x2D, (outs), (ins GPR:$target, simm16:$imm), "rtsd $target, $imm", - [], + [], IIBranch>; } let isReturn=1, isTerminator=1, hasDelaySlot=1, isBarrier=1, hasCtrlDep=1, rd=0x11, Form=FCRI in { def RTID : TB<0x2D, (outs), (ins GPR:$target, simm16:$imm), - "rtsd $target, $imm", - [], + "rtid $target, $imm", + [], IIBranch>; } let isReturn=1, isTerminator=1, hasDelaySlot=1, isBarrier=1, hasCtrlDep=1, rd=0x12, Form=FCRI in { def RTBD : TB<0x2D, (outs), (ins GPR:$target, simm16:$imm), - "rtsd $target, $imm", - [], + "rtbd $target, $imm", + [], IIBranch>; } let isReturn=1, isTerminator=1, hasDelaySlot=1, isBarrier=1, hasCtrlDep=1, rd=0x14, Form=FCRI in { def RTED : TB<0x2D, (outs), (ins GPR:$target, simm16:$imm), - "rtsd $target, $imm", - [], + "rted $target, $imm", + [], IIBranch>; } @@ -551,20 +564,20 @@ let usesCustomInserter = 1 in { let rb = 0 in { def SEXT16 : TA<0x24, 0x061, (outs GPR:$dst), (ins GPR:$src), - "sext16 $dst, $src", [], IIAlu>; + "sext16 $dst, $src", [], IIAlu>; def SEXT8 : TA<0x24, 0x060, (outs GPR:$dst), (ins GPR:$src), - "sext8 $dst, $src", [], IIAlu>; + "sext8 $dst, $src", [], IIAlu>; def SRL : TA<0x24, 0x041, (outs GPR:$dst), (ins GPR:$src), - "srl $dst, $src", [], IIAlu>; + "srl $dst, $src", [], IIAlu>; def SRA : TA<0x24, 0x001, (outs GPR:$dst), (ins GPR:$src), - "sra $dst, $src", [], IIAlu>; + "sra $dst, $src", [], IIAlu>; def SRC : TA<0x24, 0x021, (outs GPR:$dst), (ins GPR:$src), - "src $dst, $src", [], IIAlu>; + "src $dst, $src", [], IIAlu>; } let opcode=0x08, isCodeGenOnly=1 in { def LEA_ADDI : TB<0x08, (outs GPR:$dst), (ins memri:$addr), - "addi $dst, ${addr:stackloc}", + "addi $dst, ${addr:stackloc}", [(set GPR:$dst, iaddr:$addr)], IIAlu>; } @@ -584,7 +597,7 @@ def MSRCLR : MBlazeInst<0x25, FPseudo, (outs), (ins), "msrclr", [], IIAlu> { } let rd=0x0, Form=FCRR in { - def WDC : TA<0x24, 0x64, (outs), (ins GPR:$a, GPR:$b), + def WDC : TA<0x24, 0x64, (outs), (ins GPR:$a, GPR:$b), "wdc $a, $b", [], IIAlu>; def WDCF : TA<0x24, 0x74, (outs), (ins GPR:$a, GPR:$b), "wdc.flush $a, $b", [], IIAlu>; @@ -597,7 +610,7 @@ let rd=0x0, Form=FCRR in { def BRK : Branch<0x26, 0x0C, 0x000, "brk ">; def BRKI : BranchI<0x2E, 0x0C, "brki ">; -def IMM : MBlazeInst<0x2C, FCCI, (outs), (ins simm16:$imm), +def IMM : MBlazeInst<0x2C, FCCI, (outs), (ins simm16:$imm), "imm $imm", [], IIAlu>; //===----------------------------------------------------------------------===// @@ -633,42 +646,42 @@ def : Pat<(srl GPR:$L, GPR:$R), (ShiftRL GPR:$L, GPR:$R)>; // SET_CC operations def : Pat<(setcc (i32 GPR:$L), (i32 GPR:$R), SETEQ), - (Select_CC (ADDI (i32 R0), 1), (ADDI (i32 R0), 0), + (Select_CC (ADDI (i32 R0), 1), (ADDI (i32 R0), 0), (CMP GPR:$L, GPR:$R), 1)>; def : Pat<(setcc (i32 GPR:$L), (i32 GPR:$R), SETNE), - (Select_CC (ADDI (i32 R0), 1), (ADDI (i32 R0), 0), + (Select_CC (ADDI (i32 R0), 1), (ADDI (i32 R0), 0), (CMP GPR:$L, GPR:$R), 2)>; def : Pat<(setcc (i32 GPR:$L), (i32 GPR:$R), SETGT), - (Select_CC (ADDI (i32 R0), 1), (ADDI (i32 R0), 0), + (Select_CC (ADDI (i32 R0), 1), (ADDI (i32 R0), 0), (CMP GPR:$L, GPR:$R), 3)>; def : Pat<(setcc (i32 GPR:$L), (i32 GPR:$R), SETLT), - (Select_CC (ADDI (i32 R0), 1), (ADDI (i32 R0), 0), + (Select_CC (ADDI (i32 R0), 1), (ADDI (i32 R0), 0), (CMP GPR:$L, GPR:$R), 4)>; def : Pat<(setcc (i32 GPR:$L), (i32 GPR:$R), SETGE), - (Select_CC (ADDI (i32 R0), 1), (ADDI (i32 R0), 0), + (Select_CC (ADDI (i32 R0), 1), (ADDI (i32 R0), 0), (CMP GPR:$L, GPR:$R), 5)>; def : Pat<(setcc (i32 GPR:$L), (i32 GPR:$R), SETLE), - (Select_CC (ADDI (i32 R0), 1), (ADDI (i32 R0), 0), + (Select_CC (ADDI (i32 R0), 1), (ADDI (i32 R0), 0), (CMP GPR:$L, GPR:$R), 6)>; def : Pat<(setcc (i32 GPR:$L), (i32 GPR:$R), SETUGT), - (Select_CC (ADDI (i32 R0), 1), (ADDI (i32 R0), 0), + (Select_CC (ADDI (i32 R0), 1), (ADDI (i32 R0), 0), (CMPU GPR:$L, GPR:$R), 3)>; def : Pat<(setcc (i32 GPR:$L), (i32 GPR:$R), SETULT), - (Select_CC (ADDI (i32 R0), 1), (ADDI (i32 R0), 0), + (Select_CC (ADDI (i32 R0), 1), (ADDI (i32 R0), 0), (CMPU GPR:$L, GPR:$R), 4)>; def : Pat<(setcc (i32 GPR:$L), (i32 GPR:$R), SETUGE), - (Select_CC (ADDI (i32 R0), 1), (ADDI (i32 R0), 0), + (Select_CC (ADDI (i32 R0), 1), (ADDI (i32 R0), 0), (CMPU GPR:$L, GPR:$R), 5)>; def : Pat<(setcc (i32 GPR:$L), (i32 GPR:$R), SETULE), - (Select_CC (ADDI (i32 R0), 1), (ADDI (i32 R0), 0), + (Select_CC (ADDI (i32 R0), 1), (ADDI (i32 R0), 0), (CMPU GPR:$L, GPR:$R), 6)>; // SELECT operations def : Pat<(select (i32 GPR:$C), (i32 GPR:$T), (i32 GPR:$F)), (Select_CC GPR:$T, GPR:$F, GPR:$C, 2)>; -// SELECT_CC -def : Pat<(selectcc (i32 GPR:$L), (i32 GPR:$R), +// SELECT_CC +def : Pat<(selectcc (i32 GPR:$L), (i32 GPR:$R), (i32 GPR:$T), (i32 GPR:$F), SETEQ), (Select_CC GPR:$T, GPR:$F, (CMP GPR:$L, GPR:$R), 1)>; def : Pat<(selectcc (i32 GPR:$L), (i32 GPR:$R), diff --git a/lib/Target/MBlaze/MBlazeIntrinsicInfo.cpp b/lib/Target/MBlaze/MBlazeIntrinsicInfo.cpp index 4931860..7e4a2f5 100644 --- a/lib/Target/MBlaze/MBlazeIntrinsicInfo.cpp +++ b/lib/Target/MBlaze/MBlazeIntrinsicInfo.cpp @@ -48,7 +48,7 @@ std::string MBlazeIntrinsicInfo::getName(unsigned IntrID, const Type **Tys, assert(!isOverloaded(IntrID) && "MBlaze intrinsics are not overloaded"); if (IntrID < Intrinsic::num_intrinsics) return 0; - assert(IntrID < mblazeIntrinsic::num_mblaze_intrinsics && + assert(IntrID < mblazeIntrinsic::num_mblaze_intrinsics && "Invalid intrinsic ID"); std::string Result(names[IntrID - Intrinsic::num_intrinsics]); @@ -94,12 +94,12 @@ static const FunctionType *getType(LLVMContext &Context, unsigned id) { const Type *ResultTy = NULL; std::vector<const Type*> ArgTys; bool IsVarArg = false; - + #define GET_INTRINSIC_GENERATOR #include "MBlazeGenIntrinsics.inc" #undef GET_INTRINSIC_GENERATOR - return FunctionType::get(ResultTy, ArgTys, IsVarArg); + return FunctionType::get(ResultTy, ArgTys, IsVarArg); } Function *MBlazeIntrinsicInfo::getDeclaration(Module *M, unsigned IntrID, diff --git a/lib/Target/MBlaze/MBlazeIntrinsics.td b/lib/Target/MBlaze/MBlazeIntrinsics.td index a27cb5b..278afbe 100644 --- a/lib/Target/MBlaze/MBlazeIntrinsics.td +++ b/lib/Target/MBlaze/MBlazeIntrinsics.td @@ -1,10 +1,10 @@ //===- IntrinsicsMBlaze.td - Defines MBlaze intrinsics -----*- tablegen -*-===// -// +// // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. -// +// //===----------------------------------------------------------------------===// // // This file defines all of the MicroBlaze-specific intrinsics. @@ -16,7 +16,7 @@ // // MBlaze intrinsic classes. -let TargetPrefix = "mblaze", isTarget = 1 in { +let TargetPrefix = "mblaze", isTarget = 1 in { class MBFSL_Get_Intrinsic : Intrinsic<[llvm_i32_ty], [llvm_i32_ty], []>; class MBFSL_Put_Intrinsic : Intrinsic<[], [llvm_i32_ty, llvm_i32_ty], []>; diff --git a/lib/Target/MBlaze/MBlazeMCAsmInfo.h b/lib/Target/MBlaze/MBlazeMCAsmInfo.h index 8c3d32b..e68dd58 100644 --- a/lib/Target/MBlaze/MBlazeMCAsmInfo.h +++ b/lib/Target/MBlaze/MBlazeMCAsmInfo.h @@ -19,7 +19,7 @@ namespace llvm { class Target; - + class MBlazeMCAsmInfo : public MCAsmInfo { public: explicit MBlazeMCAsmInfo(); diff --git a/lib/Target/MBlaze/MBlazeMCCodeEmitter.cpp b/lib/Target/MBlaze/MBlazeMCCodeEmitter.cpp index 9672ebf..ea718f6 100644 --- a/lib/Target/MBlaze/MBlazeMCCodeEmitter.cpp +++ b/lib/Target/MBlaze/MBlazeMCCodeEmitter.cpp @@ -94,7 +94,7 @@ public: void EmitConstant(uint64_t Val, unsigned Size, unsigned &CurByte, raw_ostream &OS) const { - assert(Size <= 8 && "size too big in emit constant" ); + assert(Size <= 8 && "size too big in emit constant"); for (unsigned i = 0; i != Size; ++i) { EmitByte(Val & 255, CurByte, OS); @@ -103,7 +103,7 @@ public: } void EmitIMM(const MCOperand &imm, unsigned &CurByte, raw_ostream &OS) const; - void EmitIMM(const MCInst &MI, unsigned op, unsigned &CurByte, + void EmitIMM(const MCInst &MI, unsigned op, unsigned &CurByte, raw_ostream &OS) const; void EmitImmediate(const MCInst &MI, @@ -132,7 +132,7 @@ unsigned MBlazeMCCodeEmitter::getMachineOpValue(const MCInst &MI, return MBlazeRegisterInfo::getRegisterNumbering(MO.getReg()); else if (MO.isImm()) return static_cast<unsigned>(MO.getImm()); - else if (MO.isExpr() ) + else if (MO.isExpr()) return 0; // The relocation has already been recorded at this point. else { #ifndef NDEBUG @@ -146,7 +146,7 @@ unsigned MBlazeMCCodeEmitter::getMachineOpValue(const MCInst &MI, void MBlazeMCCodeEmitter:: EmitIMM(const MCOperand &imm, unsigned &CurByte, raw_ostream &OS) const { int32_t val = (int32_t)imm.getImm(); - if (val > 32767 || val < -32678 ) { + if (val > 32767 || val < -32678) { EmitByte(0x0D, CurByte, OS); EmitByte(0x00, CurByte, OS); EmitRawByte((val >> 24) & 0xFF, CurByte, OS); @@ -155,7 +155,7 @@ EmitIMM(const MCOperand &imm, unsigned &CurByte, raw_ostream &OS) const { } void MBlazeMCCodeEmitter:: -EmitIMM(const MCInst &MI, unsigned op, unsigned &CurByte, +EmitIMM(const MCInst &MI, unsigned op, unsigned &CurByte, raw_ostream &OS) const { MCOperand mcop = MI.getOperand(op); if (mcop.isExpr()) { @@ -170,11 +170,11 @@ void MBlazeMCCodeEmitter:: EmitImmediate(const MCInst &MI, unsigned opNo, MCFixupKind FixupKind, unsigned &CurByte, raw_ostream &OS, SmallVectorImpl<MCFixup> &Fixups) const { - assert( MI.getNumOperands()>opNo && "Not enought operands for instruction" ); + assert(MI.getNumOperands()>opNo && "Not enought operands for instruction"); MCOperand oper = MI.getOperand(opNo); if (oper.isImm()) { - EmitIMM( oper, CurByte, OS ); + EmitIMM(oper, CurByte, OS); } else if (oper.isExpr()) { Fixups.push_back(MCFixup::Create(0,oper.getExpr(),FixupKind)); } @@ -198,25 +198,25 @@ EncodeInstruction(const MCInst &MI, raw_ostream &OS, return; case MBlazeII::FRRI: - EmitImmediate( MI, 2, FK_Data_4, CurByte, OS, Fixups ); + EmitImmediate(MI, 2, FK_Data_4, CurByte, OS, Fixups); break; case MBlazeII::FRIR: - EmitImmediate( MI, 1, FK_Data_4, CurByte, OS, Fixups ); + EmitImmediate(MI, 1, FK_Data_4, CurByte, OS, Fixups); break; case MBlazeII::FCRI: - EmitImmediate( MI, 1, MCFixupKind(MBlaze::reloc_pcrel_2byte), CurByte, OS, - Fixups ); + EmitImmediate(MI, 1, MCFixupKind(MBlaze::reloc_pcrel_2byte), CurByte, OS, + Fixups); break; case MBlazeII::FRCI: - EmitImmediate( MI, 1, MCFixupKind(MBlaze::reloc_pcrel_4byte), CurByte, OS, - Fixups ); + EmitImmediate(MI, 1, MCFixupKind(MBlaze::reloc_pcrel_4byte), CurByte, OS, + Fixups); case MBlazeII::FCCI: - EmitImmediate( MI, 0, MCFixupKind(MBlaze::reloc_pcrel_4byte), CurByte, OS, - Fixups ); + EmitImmediate(MI, 0, MCFixupKind(MBlaze::reloc_pcrel_4byte), CurByte, OS, + Fixups); break; } diff --git a/lib/Target/MBlaze/MBlazeMCInstLower.cpp b/lib/Target/MBlaze/MBlazeMCInstLower.cpp index 5a8c54e..2a48c0d 100644 --- a/lib/Target/MBlaze/MBlazeMCInstLower.cpp +++ b/lib/Target/MBlaze/MBlazeMCInstLower.cpp @@ -32,7 +32,7 @@ using namespace llvm; MCSymbol *MBlazeMCInstLower:: GetGlobalAddressSymbol(const MachineOperand &MO) const { switch (MO.getTargetFlags()) { - default: + default: llvm_unreachable("Unknown target flag on GV operand"); case 0: break; diff --git a/lib/Target/MBlaze/MBlazeMachineFunction.h b/lib/Target/MBlaze/MBlazeMachineFunction.h index 1f956c1..da74712 100644 --- a/lib/Target/MBlaze/MBlazeMachineFunction.h +++ b/lib/Target/MBlaze/MBlazeMachineFunction.h @@ -26,11 +26,11 @@ namespace llvm { class MBlazeFunctionInfo : public MachineFunctionInfo { private: - /// Holds for each function where on the stack the Frame Pointer must be + /// Holds for each function where on the stack the Frame Pointer must be /// saved. This is used on Prologue and Epilogue to emit FP save/restore int FPStackOffset; - /// Holds for each function where on the stack the Return Address must be + /// Holds for each function where on the stack the Return Address must be /// saved. This is used on Prologue and Epilogue to emit RA save/restore int RAStackOffset; @@ -50,22 +50,22 @@ private: : FI(FrameIndex), SPOffset(StackPointerOffset) {} }; - /// When PIC is used the GP must be saved on the stack on the function - /// prologue and must be reloaded from this stack location after every - /// call. A reference to its stack location and frame index must be kept + /// When PIC is used the GP must be saved on the stack on the function + /// prologue and must be reloaded from this stack location after every + /// call. A reference to its stack location and frame index must be kept /// to be used on emitPrologue and processFunctionBeforeFrameFinalized. MBlazeFIHolder GPHolder; /// On LowerFormalArguments the stack size is unknown, so the Stack - /// Pointer Offset calculation of "not in register arguments" must be - /// postponed to emitPrologue. + /// Pointer Offset calculation of "not in register arguments" must be + /// postponed to emitPrologue. SmallVector<MBlazeFIHolder, 16> FnLoadArgs; bool HasLoadArgs; - // When VarArgs, we must write registers back to caller stack, preserving - // on register arguments. Since the stack size is unknown on + // When VarArgs, we must write registers back to caller stack, preserving + // on register arguments. Since the stack size is unknown on // LowerFormalArguments, the Stack Pointer Offset calculation must be - // postponed to emitPrologue. + // postponed to emitPrologue. SmallVector<MBlazeFIHolder, 4> FnStoreVarArgs; bool HasStoreVarArgs; @@ -83,8 +83,8 @@ private: int VarArgsFrameIndex; public: - MBlazeFunctionInfo(MachineFunction& MF) - : FPStackOffset(0), RAStackOffset(0), CPUTopSavedRegOff(0), + MBlazeFunctionInfo(MachineFunction& MF) + : FPStackOffset(0), RAStackOffset(0), CPUTopSavedRegOff(0), GPHolder(-1,-1), HasLoadArgs(false), HasStoreVarArgs(false), SRetReturnReg(0), GlobalBaseReg(0), VarArgsFrameIndex(0) {} @@ -105,7 +105,7 @@ public: bool needGPSaveRestore() const { return GPHolder.SPOffset != -1; } bool hasLoadArgs() const { return HasLoadArgs; } - bool hasStoreVarArgs() const { return HasStoreVarArgs; } + bool hasStoreVarArgs() const { return HasStoreVarArgs; } void recordLoadArgsFI(int FI, int SPOffset) { if (!HasLoadArgs) HasLoadArgs=true; @@ -118,13 +118,13 @@ public: void adjustLoadArgsFI(MachineFrameInfo *MFI) const { if (!hasLoadArgs()) return; - for (unsigned i = 0, e = FnLoadArgs.size(); i != e; ++i) - MFI->setObjectOffset( FnLoadArgs[i].FI, FnLoadArgs[i].SPOffset ); + for (unsigned i = 0, e = FnLoadArgs.size(); i != e; ++i) + MFI->setObjectOffset(FnLoadArgs[i].FI, FnLoadArgs[i].SPOffset); } void adjustStoreVarArgsFI(MachineFrameInfo *MFI) const { - if (!hasStoreVarArgs()) return; - for (unsigned i = 0, e = FnStoreVarArgs.size(); i != e; ++i) - MFI->setObjectOffset( FnStoreVarArgs[i].FI, FnStoreVarArgs[i].SPOffset ); + if (!hasStoreVarArgs()) return; + for (unsigned i = 0, e = FnStoreVarArgs.size(); i != e; ++i) + MFI->setObjectOffset(FnStoreVarArgs[i].FI, FnStoreVarArgs[i].SPOffset); } unsigned getSRetReturnReg() const { return SRetReturnReg; } diff --git a/lib/Target/MBlaze/MBlazeRegisterInfo.h b/lib/Target/MBlaze/MBlazeRegisterInfo.h index 1e1fde1..78dbb8b 100644 --- a/lib/Target/MBlaze/MBlazeRegisterInfo.h +++ b/lib/Target/MBlaze/MBlazeRegisterInfo.h @@ -25,8 +25,8 @@ class TargetInstrInfo; class Type; namespace MBlaze { - /// SubregIndex - The index of various sized subregister classes. Note that - /// these indices must be kept in sync with the class indices in the + /// SubregIndex - The index of various sized subregister classes. Note that + /// these indices must be kept in sync with the class indices in the /// MBlazeRegisterInfo.td file. enum SubregIndex { SUBREG_FPEVEN = 1, SUBREG_FPODD = 2 @@ -36,7 +36,7 @@ namespace MBlaze { struct MBlazeRegisterInfo : public MBlazeGenRegisterInfo { const MBlazeSubtarget &Subtarget; const TargetInstrInfo &TII; - + MBlazeRegisterInfo(const MBlazeSubtarget &Subtarget, const TargetInstrInfo &tii); @@ -70,7 +70,7 @@ struct MBlazeRegisterInfo : public MBlazeGenRegisterInfo { void emitPrologue(MachineFunction &MF) const; void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const; - + /// Debug information queries. unsigned getRARegister() const; unsigned getFrameRegister(const MachineFunction &MF) const; diff --git a/lib/Target/MBlaze/MBlazeSchedule.td b/lib/Target/MBlaze/MBlazeSchedule.td index a9bf27d..ac4d98c 100644 --- a/lib/Target/MBlaze/MBlazeSchedule.td +++ b/lib/Target/MBlaze/MBlazeSchedule.td @@ -14,7 +14,7 @@ def ALU : FuncUnit; def IMULDIV : FuncUnit; //===----------------------------------------------------------------------===// -// Instruction Itinerary classes used for MBlaze +// Instruction Itinerary classes used for MBlaze //===----------------------------------------------------------------------===// def IIAlu : InstrItinClass; def IILoad : InstrItinClass; diff --git a/lib/Target/MBlaze/MBlazeTargetMachine.cpp b/lib/Target/MBlaze/MBlazeTargetMachine.cpp index 20e61e8..affcb87 100644 --- a/lib/Target/MBlaze/MBlazeTargetMachine.cpp +++ b/lib/Target/MBlaze/MBlazeTargetMachine.cpp @@ -61,7 +61,7 @@ extern "C" void LLVMInitializeMBlazeTarget() { // Register the MC code emitter TargetRegistry::RegisterCodeEmitter(TheMBlazeTarget, llvm::createMBlazeMCCodeEmitter); - + // Register the asm backend TargetRegistry::RegisterAsmBackend(TheMBlazeTarget, createMBlazeAsmBackend); diff --git a/lib/Target/MBlaze/MBlazeTargetObjectFile.h b/lib/Target/MBlaze/MBlazeTargetObjectFile.h index 20e7702..c313722 100644 --- a/lib/Target/MBlaze/MBlazeTargetObjectFile.h +++ b/lib/Target/MBlaze/MBlazeTargetObjectFile.h @@ -18,10 +18,9 @@ namespace llvm { const MCSection *SmallDataSection; const MCSection *SmallBSSSection; public: - + void Initialize(MCContext &Ctx, const TargetMachine &TM); - /// IsGlobalInSmallSection - Return true if this global address should be /// placed into small data/bss section. bool IsGlobalInSmallSection(const GlobalValue *GV, @@ -29,8 +28,8 @@ namespace llvm { SectionKind Kind) const; bool IsGlobalInSmallSection(const GlobalValue *GV, - const TargetMachine &TM) const; - + const TargetMachine &TM) const; + const MCSection *SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind, Mangler *Mang, diff --git a/lib/Target/MBlaze/TODO b/lib/Target/MBlaze/TODO index 95047e7..bbdf4f3 100644 --- a/lib/Target/MBlaze/TODO +++ b/lib/Target/MBlaze/TODO @@ -1,8 +1,5 @@ * Writing out ELF files is close to working but the following needs to be examined more closely: - - ELF files are written with the wrong E_MACHINE value because - ELFObjectWriter::WriteHeader function does not yet support - target specific E_MACHINE values. - ELF relocation records are incorrect because the function ELFObjectWriter::RecordRelocation is hard coded for X86/X86-64. - Relocations use 2-byte / 4-byte to terminology in reference to @@ -32,3 +29,11 @@ and need to be updated to model the MicroBlaze correctly. - Look at the MBlazeGenFastISel.inc stuff and make use of it if appropriate. + +* A basic assembly parser is present now and seems to parse most things. + There are a few things that need to be looked at: + - There are some instructions that are not generated by the backend + and have not been tested as far as the parser is concerned. + - The assembly parser does not use any MicroBlaze specific directives. + I should investigate if there are MicroBlaze specific directive and, + if there are, add them. |