[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:32:58 PDT 2012


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