[llvm-commits] [llvm] r163346 - in /llvm/trunk: lib/Target/Mips/AsmParser/MipsAsmParser.cpp test/MC/Mips/mips-memory-instructions.s
David Blaikie
dblaikie at gmail.com
Thu Sep 6 16:44:06 PDT 2012
On Thu, Sep 6, 2012 at 4:39 PM, Carter, Jack <jcarter at mips.com> wrote:
> David,
>
> Thanks for catching this. I will watch my builds more carefully and not go for coffee once they are started.
The 'easy' solution is to use LLVM_ENABLE_WERROR in Cmake or
--enable-werror in the configure build. (easy in the sense that it's
now easy not to miss those problems - not easy in the sense that build
breaks for these sort of things might annoy you)
- David
>
> Jack
> ________________________________________
> From: David Blaikie [dblaikie at gmail.com]
> Sent: Thursday, September 06, 2012 4:32 PM
> To: Carter, Jack
> Cc: llvm-commits at cs.uiuc.edu
> Subject: Re: [llvm-commits] [llvm] r163346 - in /llvm/trunk: lib/Target/Mips/AsmParser/MipsAsmParser.cpp test/MC/Mips/mips-memory-instructions.s
>
> On Thu, Sep 6, 2012 at 1:00 PM, Jack Carter <jcarter at mips.com> wrote:
>> Author: jacksprat
>> Date: Thu Sep 6 15:00:02 2012
>> New Revision: 163346
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=163346&view=rev
>> Log:
>> The Mips standalone assembler memory instruction support.
>>
>> This includes sb,sc,sh,sw,lb,lw,lbu,lh,lhu,ll,lw
>>
>> Test case included
>>
>> Contributer: Vladimir Medic
>>
>> Added:
>> llvm/trunk/test/MC/Mips/mips-memory-instructions.s
>> Modified:
>> llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
>>
>> Modified: llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp?rev=163346&r1=163345&r2=163346&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp (original)
>> +++ llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp Thu Sep 6 15:00:02 2012
>> @@ -60,6 +60,9 @@
>> bool tryParseRegisterOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
>> StringRef Mnemonic);
>>
>> + bool parseMemOffset(const MCExpr *&Res);
>> + bool parseRelocOperand(const MCExpr *&Res);
>> + MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
>> bool isMips64() const {
>> return (STI.getFeatureBits() & Mips::FeatureMips64) != 0;
>> }
>> @@ -114,6 +117,11 @@
>> struct {
>> const MCExpr *Val;
>> } Imm;
>> +
>> + struct {
>> + unsigned Base;
>> + const MCExpr *Off;
>> + } Mem;
>> };
>>
>> SMLoc StartLoc, EndLoc;
>> @@ -141,7 +149,12 @@
>> }
>>
>> void addMemOperands(MCInst &Inst, unsigned N) const {
>> - llvm_unreachable("unimplemented!");
>> + assert(N == 2 && "Invalid number of operands!");
>> +
>> + Inst.addOperand(MCOperand::CreateReg(getMemBase()));
>> +
>> + const MCExpr *Expr = getMemOff();
>> + addExpr(Inst,Expr);
>> }
>>
>> bool isReg() const { return Kind == k_Register; }
>> @@ -164,6 +177,16 @@
>> return Imm.Val;
>> }
>>
>> + unsigned getMemBase() const {
>> + assert((Kind == k_Memory) && "Invalid access!");
>> + return Mem.Base;
>> + }
>> +
>> + const MCExpr *getMemOff() const {
>> + assert((Kind == k_Memory) && "Invalid access!");
>> + return Mem.Off;
>> + }
>> +
>> static MipsOperand *CreateToken(StringRef Str, SMLoc S) {
>> MipsOperand *Op = new MipsOperand(k_Token);
>> Op->Tok.Data = Str.data();
>> @@ -189,6 +212,16 @@
>> return Op;
>> }
>>
>> + static MipsOperand *CreateMem(unsigned Base, const MCExpr *Off,
>> + SMLoc S, SMLoc E) {
>> + MipsOperand *Op = new MipsOperand(k_Memory);
>> + Op->Mem.Base = Base;
>> + Op->Mem.Off = Off;
>> + Op->StartLoc = S;
>> + Op->EndLoc = E;
>> + return Op;
>> + }
>> +
>> /// 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.
>> @@ -324,8 +357,8 @@
>> std::string lowerCase = Tok.getString().lower();
>> RegNum = matchRegisterName(lowerCase);
>> } else if (Tok.is(AsmToken::Integer))
>> - RegNum = matchRegisterByNumber(static_cast<unsigned> (Tok.getIntVal()),
>> - Mnemonic.lower());
>> + RegNum = matchRegisterByNumber(static_cast<unsigned> (Tok.getIntVal()),
>> + Mnemonic.lower());
>> return RegNum;
>> }
>>
>> @@ -393,14 +426,13 @@
>> if (Parser.ParseIdentifier(Identifier))
>> return true;
>>
>> - SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer()-1);
>> + SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
>>
>> StringRef Id = StringRef("$" + Identifier.str());
>> MCSymbol *Sym = getContext().GetOrCreateSymbol(Id);
>>
>> // Otherwise create a symbol ref.
>> - const MCExpr *Res = MCSymbolRefExpr::Create(Sym,
>> - MCSymbolRefExpr::VK_None,
>> + const MCExpr *Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None,
>> getContext());
>>
>> Operands.push_back(MipsOperand::CreateImm(Res, S, E));
>> @@ -417,14 +449,89 @@
>> SMLoc S = Parser.getTok().getLoc();
>> if (getParser().ParseExpression(IdVal))
>> return true;
>> - SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer()-1);
>> + SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
>> Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
>> return false;
>> }
>> + case AsmToken::Percent: {
>> + //it is a symbol reference or constant expression
>> + const MCExpr *IdVal;
>> + SMLoc S = Parser.getTok().getLoc(); //start location of the operand
>> + if (parseRelocOperand(IdVal))
>> + return true;
>> +
>> + SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
>
> This variable is unused (identified by a Clang warning). I've removed
> it in r163359 to clean up the build.
>
> - David
>
>> +
>> + Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
>> + return false;
>> + }//case AsmToken::Percent
>> }//switch(getLexer().getKind())
>> return true;
>> }
>>
>> +bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
>> +
>> + Parser.Lex(); //eat % token
>> + const AsmToken &Tok = Parser.getTok(); //get next token, operation
>> + if (Tok.isNot(AsmToken::Identifier))
>> + return true;
>> +
>> + StringRef Str = Tok.getIdentifier();
>> +
>> + Parser.Lex(); //eat identifier
>> + //now make expression from the rest of the operand
>> + const MCExpr *IdVal;
>> + SMLoc EndLoc;
>> +
>> + if (getLexer().getKind() == AsmToken::LParen) {
>> + while (1) {
>> + Parser.Lex(); //eat '(' token
>> + if (getLexer().getKind() == AsmToken::Percent) {
>> + Parser.Lex(); //eat % token
>> + const AsmToken &nextTok = Parser.getTok();
>> + if (nextTok.isNot(AsmToken::Identifier))
>> + return true;
>> + Str = StringRef(Str.str() + "(%" + nextTok.getIdentifier().str());
>> + Parser.Lex(); //eat identifier
>> + if (getLexer().getKind() != AsmToken::LParen)
>> + return true;
>> + } else
>> + break;
>> + }
>> + if (getParser().ParseParenExpression(IdVal,EndLoc))
>> + return true;
>> +
>> + while (getLexer().getKind() == AsmToken::RParen)
>> + Parser.Lex(); //eat ')' token
>> +
>> + } else
>> + return true; //parenthesis must follow reloc operand
>> +
>> + SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
>> +
>> + //Check the type of the expression
>> + if (MCConstantExpr::classof(IdVal)) {
>> + //it's a constant, evaluate lo or hi value
>> + int Val = ((const MCConstantExpr*)IdVal)->getValue();
>> + if (Str == "lo") {
>> + Val = Val & 0xffff;
>> + } else if (Str == "hi") {
>> + Val = (Val & 0xffff0000) >> 16;
>> + }
>> + Res = MCConstantExpr::Create(Val, getContext());
>> + return false;
>> + }
>> +
>> + if (MCSymbolRefExpr::classof(IdVal)) {
>> + //it's a symbol, create symbolic expression from symbol
>> + StringRef Symbol = ((const MCSymbolRefExpr*)IdVal)->getSymbol().getName();
>> + MCSymbolRefExpr::VariantKind VK = getVariantKind(Str);
>> + Res = MCSymbolRefExpr::Create(Symbol,VK,getContext());
>> + return false;
>> + }
>> + return true;
>> +}
>> +
>> bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
>> SMLoc &EndLoc) {
>>
>> @@ -434,11 +541,108 @@
>> return (RegNo == (unsigned)-1);
>> }
>>
>> +bool MipsAsmParser::parseMemOffset(const MCExpr *&Res) {
>> +
>> + SMLoc S;
>> +
>> + switch(getLexer().getKind()) {
>> + default:
>> + return true;
>> + case AsmToken::Integer:
>> + case AsmToken::Minus:
>> + case AsmToken::Plus:
>> + return (getParser().ParseExpression(Res));
>> + case AsmToken::Percent: {
>> + return parseRelocOperand(Res);
>> + }
>> + case AsmToken::LParen:
>> + return false; //it's probably assuming 0
>> + }
>> + return true;
>> +}
>> +
>> MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand(
>> SmallVectorImpl<MCParsedAsmOperand*>&Operands) {
>> +
>> + const MCExpr *IdVal = 0;
>> + SMLoc S;
>> + //first operand is the offset
>> + S = Parser.getTok().getLoc();
>> +
>> + if (parseMemOffset(IdVal))
>> + return MatchOperand_ParseFail;
>> +
>> + const AsmToken &Tok = Parser.getTok(); //get next token
>> + if (Tok.isNot(AsmToken::LParen)) {
>> + Error(Parser.getTok().getLoc(), "'(' expected");
>> + return MatchOperand_ParseFail;
>> + }
>> +
>> + Parser.Lex(); // Eat '(' token.
>> +
>> + const AsmToken &Tok1 = Parser.getTok(); //get next token
>> + if (Tok1.is(AsmToken::Dollar)) {
>> + Parser.Lex(); // Eat '$' token.
>> + if (tryParseRegisterOperand(Operands,"")) {
>> + Error(Parser.getTok().getLoc(), "unexpected token in operand");
>> + return MatchOperand_ParseFail;
>> + }
>> +
>> + } else {
>> + Error(Parser.getTok().getLoc(),"unexpected token in operand");
>> + return MatchOperand_ParseFail;
>> + }
>> +
>> + const AsmToken &Tok2 = Parser.getTok(); //get next token
>> + if (Tok2.isNot(AsmToken::RParen)) {
>> + Error(Parser.getTok().getLoc(), "')' expected");
>> + return MatchOperand_ParseFail;
>> + }
>> +
>> + SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
>> +
>> + Parser.Lex(); // Eat ')' token.
>> +
>> + if (IdVal == 0)
>> + IdVal = MCConstantExpr::Create(0, getContext());
>> +
>> + //now replace register operand with the mem operand
>> + MipsOperand* op = static_cast<MipsOperand*>(Operands.back());
>> + int RegNo = op->getReg();
>> + //remove register from operands
>> + Operands.pop_back();
>> + //and add memory operand
>> + Operands.push_back(MipsOperand::CreateMem(RegNo, IdVal, S, E));
>> + delete op;
>> return MatchOperand_Success;
>> }
>>
>> +MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
>> +
>> + MCSymbolRefExpr::VariantKind VK
>> + = StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
>> + .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
>> + .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
>> + .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
>> + .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
>> + .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
>> + .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
>> + .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
>> + .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
>> + .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
>> + .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
>> + .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
>> + .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
>> + .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
>> + .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
>> + .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
>> + .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
>> + .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
>> + .Default(MCSymbolRefExpr::VK_None);
>> +
>> + return VK;
>> +}
>> +
>> bool MipsAsmParser::
>> ParseInstruction(StringRef Name, SMLoc NameLoc,
>> SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
>>
>> Added: llvm/trunk/test/MC/Mips/mips-memory-instructions.s
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Mips/mips-memory-instructions.s?rev=163346&view=auto
>> ==============================================================================
>> --- llvm/trunk/test/MC/Mips/mips-memory-instructions.s (added)
>> +++ llvm/trunk/test/MC/Mips/mips-memory-instructions.s Thu Sep 6 15:00:02 2012
>> @@ -0,0 +1,41 @@
>> +# RUN: llvm-mc %s -triple=mipsel-unknown-linux -show-encoding -mcpu=mips32r2 | FileCheck %s
>> +# Check that the assembler can handle the documented syntax
>> +# for loads and stores.
>> +# CHECK: .section __TEXT,__text,regular,pure_instructions
>> +#------------------------------------------------------------------------------
>> +# Memory store instructions
>> +#------------------------------------------------------------------------------
>> +# CHECK: sb $4, 16($5) # encoding: [0x10,0x00,0xa4,0xa0]
>> +# CHECK: sc $4, 16($5) # encoding: [0x10,0x00,0xa4,0xe0]
>> +# CHECK: sh $4, 16($5) # encoding: [0x10,0x00,0xa4,0xa4]
>> +# CHECK: sw $4, 16($5) # encoding: [0x10,0x00,0xa4,0xac]
>> +# CHECK: sw $7, 0($5) # encoding: [0x00,0x00,0xa7,0xac]
>> + sb $4, 16($5)
>> + sc $4, 16($5)
>> + sh $4, 16($5)
>> + sw $4, 16($5)
>> + sw $7, ($5)
>> +
>> +#------------------------------------------------------------------------------
>> +# Memory load instructions
>> +#------------------------------------------------------------------------------
>> +
>> +# CHECK: lb $4, 4($5) # encoding: [0x04,0x00,0xa4,0x80]
>> +# CHECK: lw $4, 4($5) # encoding: [0x04,0x00,0xa4,0x8c]
>> +# CHECK: lbu $4, 4($5) # encoding: [0x04,0x00,0xa4,0x90]
>> +# CHECK: lh $4, 4($5) # encoding: [0x04,0x00,0xa4,0x84]
>> +# CHECK: lhu $4, 4($5) # encoding: [0x04,0x00,0xa4,0x94]
>> +# CHECK: ll $4, 4($5) # encoding: [0x04,0x00,0xa4,0xc0]
>> +# CHECK: lw $4, 4($5) # encoding: [0x04,0x00,0xa4,0x8c]
>> +# CHECK: lw $7, 0($7) # encoding: [0x00,0x00,0xe7,0x8c]
>> +# CHECK: lw $2, 16($sp) # encoding: [0x10,0x00,0xa2,0x8f]
>> +
>> + lb $4, 4($5)
>> + lw $4, 4($5)
>> + lbu $4, 4($5)
>> + lh $4, 4($5)
>> + lhu $4, 4($5)
>> + ll $4, 4($5)
>> + lw $4, 4($5)
>> + lw $7, ($7)
>> + lw $2, 16($sp)
>>
>>
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list