[llvm-commits] [llvm] r165194 - in /llvm/trunk: lib/Target/Mips/AsmParser/MipsAsmParser.cpp test/MC/Mips/mips_directives.s

Jack Carter jcarter at mips.com
Wed Oct 3 19:29:46 PDT 2012


Author: jacksprat
Date: Wed Oct  3 21:29:46 2012
New Revision: 165194

URL: http://llvm.org/viewvc/llvm-project?rev=165194&view=rev
Log:
This patch is a partial implementation of mips .set assembler directive. Directive is defined as follows:
.set option
The patch implements following options

    at - lets the assembler use the $at register for macros,
         but generates warnings if the source program uses $at

    noat - let source programs use $at without issuingwarnings.

    noreorder - prevents the assembler from reordering machine 
                language instructions.
    nomacro - causes the assembler to print a warning whenever 
              an assembler operation generates more than one 
              machine language instruction.
    macro - lets the assembler generate multiple machine instructions 
            from a single assembler instruction
    reorder - lets the assembler reorder machine language 
               instructions to improve performance

The above variants are parsed and their boolean values set or unset.
The code to actually use them will come later.

Following options are not implemented yet:

nomips16
nomicromips
move
nomove

Contributer: Vladimir Medic

Modified:
    llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
    llvm/trunk/test/MC/Mips/mips_directives.s

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=165194&r1=165193&r2=165194&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp (original)
+++ llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp Wed Oct  3 21:29:46 2012
@@ -24,7 +24,31 @@
 using namespace llvm;
 
 namespace {
+class MipsAssemblerOptions {
+public:
+  MipsAssemblerOptions():
+    aTReg(1), reorder(true), macro(true) {
+  }
+
+  unsigned getATRegNum() {return aTReg;}
+  bool setATReg(unsigned Reg);
 
+  bool isReorder() {return reorder;}
+  void setReorder() {reorder = true;}
+  void setNoreorder() {reorder = false;}
+
+  bool isMacro() {return macro;}
+  void setMacro() {macro = true;}
+  void setNomacro() {macro = false;}
+
+private:
+  unsigned aTReg;
+  bool reorder;
+  bool macro;
+};
+}
+
+namespace {
 class MipsAsmParser : public MCTargetAsmParser {
 
   enum FpFormatTy {
@@ -37,6 +61,8 @@
 
   MCSubtargetInfo &STI;
   MCAsmParser &Parser;
+  MipsAssemblerOptions *Options;
+
 
 #define GET_ASSEMBLER_HEADER
 #include "MipsGenAsmMatcher.inc"
@@ -66,8 +92,20 @@
   bool tryParseRegisterOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
                                StringRef Mnemonic);
 
+  bool reportParseError(StringRef ErrorMsg);
+
   bool parseMemOffset(const MCExpr *&Res);
   bool parseRelocOperand(const MCExpr *&Res);
+
+  bool parseDirectiveSet();
+
+  bool parseSetAtDirective();
+  bool parseSetNoAtDirective();
+  bool parseSetMacroDirective();
+  bool parseSetNoMacroDirective();
+  bool parseSetReorderDirective();
+  bool parseSetNoReorderDirective();
+
   MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
 
   bool isMips64() const {
@@ -96,11 +134,13 @@
 
   unsigned getReg(int RC,int RegNo);
 
+  unsigned getATReg();
 public:
   MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser)
     : MCTargetAsmParser(), STI(sti), Parser(parser) {
     // Initialize the set of available features.
     setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
+    Options = new MipsAssemblerOptions();
   }
 
   MCAsmParser &getParser() const { return Parser; }
@@ -395,11 +435,27 @@
     .Default(FP_FORMAT_NONE);
 }
 
-unsigned MipsAsmParser::getReg(int RC,int RegNo){
+bool MipsAssemblerOptions::setATReg(unsigned Reg) {
+  if (Reg > 31)
+    return false;
+
+  aTReg = Reg;
+  return true;
+}
+
+unsigned MipsAsmParser::getATReg() {
+  unsigned Reg = Options->getATRegNum();
+  if (isMips64())
+    return getReg(Mips::CPU64RegsRegClassID,Reg);
+  else
+    return getReg(Mips::CPURegsRegClassID,Reg);
+}
+
+unsigned MipsAsmParser::getReg(int RC,int RegNo) {
   return *(getContext().getRegisterInfo().getRegClass(RC).begin() + RegNo);
 }
 
-int MipsAsmParser::matchRegisterByNumber(unsigned RegNum,StringRef Mnemonic) {
+int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, StringRef Mnemonic) {
 
   if (Mnemonic.lower() == "rdhwr") {
     //at the moment only hwreg29 is supported
@@ -411,7 +467,7 @@
   if (RegNum > 31)
     return -1;
 
-  return getReg(Mips::CPURegsRegClassID,RegNum);
+  return getReg(Mips::CPURegsRegClassID, RegNum);
 }
 
 int MipsAsmParser::tryParseRegister(StringRef Mnemonic) {
@@ -544,14 +600,14 @@
 
     Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
     return false;
-  }//case AsmToken::Percent
-  }//switch(getLexer().getKind())
+  } // case AsmToken::Percent
+  } // switch(getLexer().getKind())
   return true;
 }
 
 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
 
-  Parser.Lex(); //eat % token
+  Parser.Lex(); // eat % token
   const AsmToken &Tok = Parser.getTok(); //get next token, operation
   if (Tok.isNot(AsmToken::Identifier))
     return true;
@@ -559,21 +615,21 @@
   std::string Str = Tok.getIdentifier().str();
 
   Parser.Lex(); //eat identifier
-  //now make expression from the rest of the operand
+  // 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
+      Parser.Lex(); // eat '(' token
       if (getLexer().getKind() == AsmToken::Percent) {
-        Parser.Lex(); //eat % token
+        Parser.Lex(); // eat % token
         const AsmToken &nextTok = Parser.getTok();
         if (nextTok.isNot(AsmToken::Identifier))
           return true;
         Str += "(%";
         Str += nextTok.getIdentifier();
-        Parser.Lex(); //eat identifier
+        Parser.Lex(); // eat identifier
         if (getLexer().getKind() != AsmToken::LParen)
           return true;
       } else
@@ -583,12 +639,12 @@
       return true;
 
     while (getLexer().getKind() == AsmToken::RParen)
-      Parser.Lex(); //eat ')' token
+      Parser.Lex(); // eat ')' token
 
   } else
-    return true; //parenthesis must follow reloc operand
+    return true; // parenthesis must follow reloc operand
 
-  //Check the type of the expression
+  // Check the type of the expression
   if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal)) {
     //it's a constant, evaluate lo or hi value
     int Val = MCE->getValue();
@@ -602,7 +658,7 @@
   }
 
   if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(IdVal)) {
-    //it's a symbol, create symbolic expression from symbol
+    // it's a symbol, create symbolic expression from symbol
     StringRef Symbol = MSRE->getSymbol().getName();
     MCSymbolRefExpr::VariantKind VK = getVariantKind(Str);
     Res = MCSymbolRefExpr::Create(Symbol,VK,getContext());
@@ -634,7 +690,7 @@
   case AsmToken::Percent:
     return parseRelocOperand(Res);
   case AsmToken::LParen:
-    return false;  //it's probably assuming 0
+    return false;  // it's probably assuming 0
   }
   return true;
 }
@@ -644,13 +700,13 @@
 
   const MCExpr *IdVal = 0;
   SMLoc S;
-  //first operand is the offset
+  // first operand is the offset
   S = Parser.getTok().getLoc();
 
   if (parseMemOffset(IdVal))
     return MatchOperand_ParseFail;
 
-  const AsmToken &Tok = Parser.getTok(); //get next token
+  const AsmToken &Tok = Parser.getTok(); // get next token
   if (Tok.isNot(AsmToken::LParen)) {
     Error(Parser.getTok().getLoc(), "'(' expected");
     return MatchOperand_ParseFail;
@@ -667,11 +723,11 @@
     }
 
   } else {
-    Error(Parser.getTok().getLoc(),"unexpected token in operand");
+    Error(Parser.getTok().getLoc(), "unexpected token in operand");
     return MatchOperand_ParseFail;
   }
 
-  const AsmToken &Tok2 = Parser.getTok(); //get next token
+  const AsmToken &Tok2 = Parser.getTok(); // get next token
   if (Tok2.isNot(AsmToken::RParen)) {
     Error(Parser.getTok().getLoc(), "')' expected");
     return MatchOperand_ParseFail;
@@ -684,12 +740,12 @@
   if (IdVal == 0)
     IdVal = MCConstantExpr::Create(0, getContext());
 
-  //now replace register operand with the mem operand
+  // now replace register operand with the mem operand
   MipsOperand* op = static_cast<MipsOperand*>(Operands.back());
   int RegNo = op->getReg();
-  //remove register from operands
+  // remove register from operands
   Operands.pop_back();
-  //and add memory operand
+  // and add memory operand
   Operands.push_back(MipsOperand::CreateMem(RegNo, IdVal, S, E));
   delete op;
   return MatchOperand_Success;
@@ -746,17 +802,17 @@
 
 bool MipsAsmParser::
 parseMathOperation(StringRef Name, SMLoc NameLoc,
-                        SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
-  //split the format
+                   SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
+  // split the format
   size_t Start = Name.find('.'), Next = Name.rfind('.');
   StringRef Format1 = Name.slice(Start, Next);
-  //and add the first format to the operands
+  // and add the first format to the operands
   Operands.push_back(MipsOperand::CreateToken(Format1, NameLoc));
-  //now for the second format
+  // now for the second format
   StringRef Format2 = Name.slice(Next, StringRef::npos);
   Operands.push_back(MipsOperand::CreateToken(Format2, NameLoc));
 
-  //set the format for the first register
+  // set the format for the first register
   setFpFormat(Format1);
 
   // Read the remaining operands.
@@ -800,7 +856,7 @@
 bool MipsAsmParser::
 ParseInstruction(StringRef Name, SMLoc NameLoc,
                  SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
-  //floating point instructions: should register be treated as double?
+  // floating point instructions: should register be treated as double?
   if (requestsDoubleOperand(Name)) {
     setFpFormat(FP_FORMAT_D);
   Operands.push_back(MipsOperand::CreateToken(Name, NameLoc));
@@ -814,8 +870,8 @@
     Operands.push_back(MipsOperand::CreateToken(Mnemonic, NameLoc));
 
     if (Next != StringRef::npos) {
-      //there is a format token in mnemonic
-      //StringRef Rest = Name.slice(Next, StringRef::npos);
+      // there is a format token in mnemonic
+      // StringRef Rest = Name.slice(Next, StringRef::npos);
       size_t Dot = Name.find('.', Next+1);
       StringRef Format = Name.slice(Next, Dot);
       if (Dot == StringRef::npos) //only one '.' in a string, it's a format
@@ -833,11 +889,11 @@
           Operands.push_back(MipsOperand::CreateImm(
               MCConstantExpr::Create(Cc, getContext()), NameLoc, E));
         } else {
-          //trunc, ceil, floor ...
+          // trunc, ceil, floor ...
           return parseMathOperation(Name, NameLoc, Operands);
         }
 
-        //the rest is a format
+        // the rest is a format
         Format = Name.slice(Dot, StringRef::npos);
         Operands.push_back(MipsOperand::CreateToken(Format, NameLoc));
       }
@@ -877,47 +933,186 @@
   return false;
 }
 
-bool MipsAsmParser::
-ParseDirective(AsmToken DirectiveID) {
+bool MipsAsmParser::reportParseError(StringRef ErrorMsg) {
+   SMLoc Loc = getLexer().getLoc();
+   Parser.EatToEndOfStatement();
+   return Error(Loc, ErrorMsg);
+}
+
+bool MipsAsmParser::parseSetNoAtDirective() {
+  // line should look like:
+  //  .set noat
+  // set at reg to 0
+  Options->setATReg(0);
+  // eat noat
+  Parser.Lex();
+  // if this is not the end of the statement, report error
+  if (getLexer().isNot(AsmToken::EndOfStatement)) {
+    reportParseError("unexpected token in statement");
+    return false;
+  }
+  Parser.Lex(); // Consume the EndOfStatement
+  return false;
+}
+bool MipsAsmParser::parseSetAtDirective() {
+  // line can be
+  //  .set at - defaults to $1
+  // or .set at=$reg
+  getParser().Lex();
+  if (getLexer().is(AsmToken::EndOfStatement)) {
+    Options->setATReg(1);
+    Parser.Lex(); // Consume the EndOfStatement
+    return false;
+  } else if (getLexer().is(AsmToken::Equal)) {
+    getParser().Lex(); //eat '='
+    if (getLexer().isNot(AsmToken::Dollar)) {
+      reportParseError("unexpected token in statement");
+      return false;
+    }
+    Parser.Lex(); // eat '$'
+    if (getLexer().isNot(AsmToken::Integer)) {
+      reportParseError("unexpected token in statement");
+      return false;
+    }
+    const AsmToken &Reg = Parser.getTok();
+    if (!Options->setATReg(Reg.getIntVal())) {
+      reportParseError("unexpected token in statement");
+      return false;
+    }
+    getParser().Lex(); //eat reg
+
+    if (getLexer().isNot(AsmToken::EndOfStatement)) {
+      reportParseError("unexpected token in statement");
+      return false;
+     }
+    Parser.Lex(); // Consume the EndOfStatement
+    return false;
+  } else {
+    reportParseError("unexpected token in statement");
+    return false;
+  }
+}
+
+bool MipsAsmParser::parseSetReorderDirective() {
+  Parser.Lex();
+  // if this is not the end of the statement, report error
+  if (getLexer().isNot(AsmToken::EndOfStatement)) {
+    reportParseError("unexpected token in statement");
+    return false;
+  }
+  Options->setReorder();
+  Parser.Lex(); // Consume the EndOfStatement
+  return false;
+}
+
+bool MipsAsmParser::parseSetNoReorderDirective() {
+    Parser.Lex();
+    // if this is not the end of the statement, report error
+    if (getLexer().isNot(AsmToken::EndOfStatement)) {
+      reportParseError("unexpected token in statement");
+      return false;
+    }
+    Options->setNoreorder();
+    Parser.Lex(); // Consume the EndOfStatement
+    return false;
+}
+
+bool MipsAsmParser::parseSetMacroDirective() {
+  Parser.Lex();
+  // if this is not the end of the statement, report error
+  if (getLexer().isNot(AsmToken::EndOfStatement)) {
+    reportParseError("unexpected token in statement");
+    return false;
+  }
+  Options->setMacro();
+  Parser.Lex(); // Consume the EndOfStatement
+  return false;
+}
+
+bool MipsAsmParser::parseSetNoMacroDirective() {
+  Parser.Lex();
+  // if this is not the end of the statement, report error
+  if (getLexer().isNot(AsmToken::EndOfStatement)) {
+    reportParseError("`noreorder' must be set before `nomacro'");
+    return false;
+  }
+  if (Options->isReorder()) {
+    reportParseError("`noreorder' must be set before `nomacro'");
+    return false;
+  }
+  Options->setNomacro();
+  Parser.Lex(); // Consume the EndOfStatement
+  return false;
+}
+bool MipsAsmParser::parseDirectiveSet() {
+
+  // get next token
+  const AsmToken &Tok = Parser.getTok();
+
+  if (Tok.getString() == "noat") {
+    return parseSetNoAtDirective();
+  } else if (Tok.getString() == "at") {
+    return parseSetAtDirective();
+  } else if (Tok.getString() == "reorder") {
+    return parseSetReorderDirective();
+  } else if (Tok.getString() == "noreorder") {
+    return parseSetNoReorderDirective();
+  } else if (Tok.getString() == "macro") {
+    return parseSetMacroDirective();
+  } else if (Tok.getString() == "nomacro") {
+    return parseSetNoMacroDirective();
+  } else if (Tok.getString() == "nomips16") {
+    // ignore this directive for now
+    Parser.EatToEndOfStatement();
+    return false;
+  } else if (Tok.getString() == "nomicromips") {
+    // ignore this directive for now
+    Parser.EatToEndOfStatement();
+    return false;
+  }
+  return true;
+}
+
+bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
 
   if (DirectiveID.getString() == ".ent") {
-    //ignore this directive for now
+    // ignore this directive for now
     Parser.Lex();
     return false;
   }
 
   if (DirectiveID.getString() == ".end") {
-    //ignore this directive for now
+    // ignore this directive for now
     Parser.Lex();
     return false;
   }
 
   if (DirectiveID.getString() == ".frame") {
-    //ignore this directive for now
+    // ignore this directive for now
     Parser.EatToEndOfStatement();
     return false;
   }
 
   if (DirectiveID.getString() == ".set") {
-    //ignore this directive for now
-    Parser.EatToEndOfStatement();
-    return false;
+    // ignore this directive for now
+    //Parser.EatToEndOfStatement();
+    return parseDirectiveSet();
   }
 
   if (DirectiveID.getString() == ".fmask") {
-    //ignore this directive for now
+    // ignore this directive for now
     Parser.EatToEndOfStatement();
     return false;
   }
 
   if (DirectiveID.getString() == ".mask") {
-    //ignore this directive for now
+    // ignore this directive for now
     Parser.EatToEndOfStatement();
     return false;
   }
 
   if (DirectiveID.getString() == ".gpword") {
-    //ignore this directive for now
+    // ignore this directive for now
     Parser.EatToEndOfStatement();
     return false;
   }

Modified: llvm/trunk/test/MC/Mips/mips_directives.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Mips/mips_directives.s?rev=165194&r1=165193&r2=165194&view=diff
==============================================================================
--- llvm/trunk/test/MC/Mips/mips_directives.s (original)
+++ llvm/trunk/test/MC/Mips/mips_directives.s Wed Oct  3 21:29:46 2012
@@ -1,10 +1,16 @@
 # RUN: llvm-mc -triple mips-unknown-unknown %s
-
+#this test produces no output so there isS no FileCheck call
 $BB0_2:
+  .ent directives_test
 	.frame	$sp,0,$ra
 	.mask 	0x00000000,0
 	.fmask	0x00000000,0
 	.set	noreorder
 	.set	nomacro
+	.set	noat
 $JTI0_0:
 	.gpword	($BB0_2)
+	.set  at=$12
+	.set macro
+	.set reorder
+	.end directives_test





More information about the llvm-commits mailing list