[llvm] r195004 - [mips][msa] Fix immediate value of LSA instruction as it was being wrongly encoded.

Matheus Almeida matheus.almeida at imgtec.com
Mon Nov 18 04:32:49 PST 2013


Author: matheusalmeida
Date: Mon Nov 18 06:32:49 2013
New Revision: 195004

URL: http://llvm.org/viewvc/llvm-project?rev=195004&view=rev
Log:
[mips][msa] Fix immediate value of LSA instruction as it was being wrongly encoded.
    
The immediate field should be encoded as "imm - 1" as the CPU always adds one to that field.


Modified:
    llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
    llvm/trunk/lib/Target/Mips/Disassembler/MipsDisassembler.cpp
    llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
    llvm/trunk/lib/Target/Mips/MipsCodeEmitter.cpp
    llvm/trunk/lib/Target/Mips/MipsMSAInstrInfo.td
    llvm/trunk/test/MC/Mips/msa/test_lsa.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=195004&r1=195003&r2=195004&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp (original)
+++ llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp Mon Nov 18 06:32:49 2013
@@ -157,7 +157,10 @@ class MipsAsmParser : public MCTargetAsm
   MipsAsmParser::OperandMatchResultTy
   parseInvNum(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
 
-  bool searchSymbolAlias(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
+  MipsAsmParser::OperandMatchResultTy
+  parseLSAImm(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
+
+  bool searchSymbolAlias(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
                          unsigned RegKind);
 
   bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand *> &,
@@ -299,7 +302,8 @@ private:
     k_PostIndexRegister,
     k_Register,
     k_PtrReg,
-    k_Token
+    k_Token,
+    k_LSAImm
   } Kind;
 
   MipsOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
@@ -374,6 +378,7 @@ public:
   bool isMem() const { return Kind == k_Memory; }
   bool isPtrReg() const { return Kind == k_PtrReg; }
   bool isInvNum() const { return Kind == k_Immediate; }
+  bool isLSAImm() const { return Kind == k_LSAImm; }
 
   StringRef getToken() const {
     assert(Kind == k_Token && "Invalid access!");
@@ -396,7 +401,7 @@ public:
   }
 
   const MCExpr *getImm() const {
-    assert((Kind == k_Immediate) && "Invalid access!");
+    assert((Kind == k_Immediate || Kind == k_LSAImm) && "Invalid access!");
     return Imm.Val;
   }
 
@@ -443,8 +448,16 @@ public:
     return Op;
   }
 
-  static MipsOperand *CreateMem(unsigned Base, const MCExpr *Off, SMLoc S,
-                                SMLoc E) {
+  static MipsOperand *CreateLSAImm(const MCExpr *Val, SMLoc S, SMLoc E) {
+    MipsOperand *Op = new MipsOperand(k_LSAImm);
+    Op->Imm.Val = Val;
+    Op->StartLoc = S;
+    Op->EndLoc = E;
+    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;
@@ -2058,6 +2071,45 @@ MipsAsmParser::parseInvNum(SmallVectorIm
   return MatchOperand_Success;
 }
 
+MipsAsmParser::OperandMatchResultTy
+MipsAsmParser::parseLSAImm(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
+  switch (getLexer().getKind()) {
+  default:
+    return MatchOperand_NoMatch;
+  case AsmToken::LParen:
+  case AsmToken::Plus:
+  case AsmToken::Minus:
+  case AsmToken::Integer:
+    break;
+  }
+
+  const MCExpr *Expr;
+  SMLoc S = Parser.getTok().getLoc();
+
+  if (getParser().parseExpression(Expr))
+    return MatchOperand_ParseFail;
+
+  int64_t Val;
+  if (!Expr->EvaluateAsAbsolute(Val)) {
+    Error(S, "expected immediate value");
+    return MatchOperand_ParseFail;
+  }
+
+  // The LSA instruction allows a 2-bit unsigned immediate. For this reason
+  // and because the CPU always adds one to the immediate field, the allowed
+  // range becomes 1..4. We'll only check the range here and will deal
+  // with the addition/subtraction when actually decoding/encoding
+  // the instruction.
+  if (Val < 1 || Val > 4) {
+    Error(S, "immediate not in range (1..4)");
+    return MatchOperand_ParseFail;
+  }
+
+  Operands.push_back(MipsOperand::CreateLSAImm(Expr, S,
+                                               Parser.getTok().getLoc()));
+  return MatchOperand_Success;
+}
+
 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
 
   MCSymbolRefExpr::VariantKind VK =

Modified: llvm/trunk/lib/Target/Mips/Disassembler/MipsDisassembler.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/Disassembler/MipsDisassembler.cpp?rev=195004&r1=195003&r2=195004&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/Disassembler/MipsDisassembler.cpp (original)
+++ llvm/trunk/lib/Target/Mips/Disassembler/MipsDisassembler.cpp Mon Nov 18 06:32:49 2013
@@ -246,6 +246,13 @@ static DecodeStatus DecodeSimm16(MCInst
                                  uint64_t Address,
                                  const void *Decoder);
 
+// Decode the immediate field of an LSA instruction which
+// is off by one.
+static DecodeStatus DecodeLSAImm(MCInst &Inst,
+                                 unsigned Insn,
+                                 uint64_t Address,
+                                 const void *Decoder);
+
 static DecodeStatus DecodeInsSize(MCInst &Inst,
                                   unsigned Insn,
                                   uint64_t Address,
@@ -785,6 +792,15 @@ static DecodeStatus DecodeSimm16(MCInst
   return MCDisassembler::Success;
 }
 
+static DecodeStatus DecodeLSAImm(MCInst &Inst,
+                                 unsigned Insn,
+                                 uint64_t Address,
+                                 const void *Decoder) {
+  // We add one to the immediate field as it was encoded as 'imm - 1'.
+  Inst.addOperand(MCOperand::CreateImm(Insn + 1));
+  return MCDisassembler::Success;
+}
+
 static DecodeStatus DecodeInsSize(MCInst &Inst,
                                   unsigned Insn,
                                   uint64_t Address,

Modified: llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp?rev=195004&r1=195003&r2=195004&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp (original)
+++ llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp Mon Nov 18 06:32:49 2013
@@ -116,6 +116,10 @@ public:
   unsigned getSizeInsEncoding(const MCInst &MI, unsigned OpNo,
                               SmallVectorImpl<MCFixup> &Fixups) const;
 
+  // getLSAImmEncoding - Return binary encoding of LSA immediate.
+  unsigned getLSAImmEncoding(const MCInst &MI, unsigned OpNo,
+                             SmallVectorImpl<MCFixup> &Fixups) const;
+
   unsigned
   getExprOpValue(const MCExpr *Expr,SmallVectorImpl<MCFixup> &Fixups) const;
 
@@ -521,5 +525,13 @@ MipsMCCodeEmitter::getSizeInsEncoding(co
   return Position + Size - 1;
 }
 
+unsigned
+MipsMCCodeEmitter::getLSAImmEncoding(const MCInst &MI, unsigned OpNo,
+                                     SmallVectorImpl<MCFixup> &Fixups) const {
+  assert(MI.getOperand(OpNo).isImm());
+  // The immediate is encoded as 'immediate - 1'.
+  return getMachineOpValue(MI, MI.getOperand(OpNo), Fixups) - 1;
+}
+
 #include "MipsGenMCCodeEmitter.inc"
 

Modified: llvm/trunk/lib/Target/Mips/MipsCodeEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsCodeEmitter.cpp?rev=195004&r1=195003&r2=195004&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsCodeEmitter.cpp (original)
+++ llvm/trunk/lib/Target/Mips/MipsCodeEmitter.cpp Mon Nov 18 06:32:49 2013
@@ -114,6 +114,7 @@ private:
   unsigned getMemEncodingMMImm12(const MachineInstr &MI, unsigned OpNo) const;
   unsigned getSizeExtEncoding(const MachineInstr &MI, unsigned OpNo) const;
   unsigned getSizeInsEncoding(const MachineInstr &MI, unsigned OpNo) const;
+  unsigned getLSAImmEncoding(const MachineInstr &MI, unsigned OpNo) const;
 
   void emitGlobalAddressUnaligned(const GlobalValue *GV, unsigned Reloc,
                                   int Offset) const;
@@ -236,6 +237,12 @@ unsigned MipsCodeEmitter::getSizeInsEnco
          getMachineOpValue(MI, MI.getOperand(OpNo)) - 1;
 }
 
+unsigned MipsCodeEmitter::getLSAImmEncoding(const MachineInstr &MI,
+                                            unsigned OpNo) const {
+  llvm_unreachable("Unimplemented function.");
+  return 0;
+}
+
 /// getMachineOpValue - Return binary encoding of operand. If the machine
 /// operand requires relocation, record the relocation and return zero.
 unsigned MipsCodeEmitter::getMachineOpValue(const MachineInstr &MI,

Modified: llvm/trunk/lib/Target/Mips/MipsMSAInstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsMSAInstrInfo.td?rev=195004&r1=195003&r2=195004&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsMSAInstrInfo.td (original)
+++ llvm/trunk/lib/Target/Mips/MipsMSAInstrInfo.td Mon Nov 18 06:32:49 2013
@@ -65,6 +65,21 @@ def uimm2 : Operand<i32> {
   let PrintMethod = "printUnsignedImm";
 }
 
+// The immediate of an LSA instruction needs special handling
+// as the encoded value should be subtracted by one.
+def uimm2LSAAsmOperand : AsmOperandClass {
+  let Name = "LSAImm";
+  let ParserMethod = "parseLSAImm";
+  let RenderMethod = "addImmOperands";
+}
+
+def LSAImm : Operand<i32> {
+  let PrintMethod = "printUnsignedImm";
+  let EncoderMethod = "getLSAImmEncoding";
+  let DecoderMethod = "DecodeLSAImm";
+  let ParserMatchClass = uimm2LSAAsmOperand;
+}
+
 def uimm3 : Operand<i32> {
   let PrintMethod = "printUnsignedImm8";
 }
@@ -2283,7 +2298,7 @@ class LDI_D_DESC : MSA_I10_LDI_DESC_BASE
 
 class LSA_DESC {
   dag OutOperandList = (outs GPR32Opnd:$rd);
-  dag InOperandList = (ins GPR32Opnd:$rs, GPR32Opnd:$rt, uimm2:$sa);
+  dag InOperandList = (ins GPR32Opnd:$rs, GPR32Opnd:$rt, LSAImm:$sa);
   string AsmString = "lsa\t$rd, $rs, $rt, $sa";
   list<dag> Pattern = [(set GPR32Opnd:$rd, (add GPR32Opnd:$rs,
                                                 (shl GPR32Opnd:$rt,

Modified: llvm/trunk/test/MC/Mips/msa/test_lsa.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Mips/msa/test_lsa.s?rev=195004&r1=195003&r2=195004&view=diff
==============================================================================
--- llvm/trunk/test/MC/Mips/msa/test_lsa.s (original)
+++ llvm/trunk/test/MC/Mips/msa/test_lsa.s Mon Nov 18 06:32:49 2013
@@ -2,8 +2,17 @@
 #
 # RUN: llvm-mc %s -triple=mipsel-unknown-linux -mcpu=mips32r2 -mattr=+msa -arch=mips -filetype=obj -o - | llvm-objdump -d -triple=mipsel-unknown-linux -mattr=+msa -arch=mips - | FileCheck %s -check-prefix=CHECKOBJDUMP
 #
-# CHECK:        lsa        $8, $9, $10, 2              # encoding: [0x01,0x2a,0x40,0x85]
+# CHECK:        lsa        $8, $9, $10, 1              # encoding: [0x01,0x2a,0x40,0x05]
+# CHECK:        lsa        $8, $9, $10, 2              # encoding: [0x01,0x2a,0x40,0x45]
+# CHECK:        lsa        $8, $9, $10, 3              # encoding: [0x01,0x2a,0x40,0x85]
+# CHECK:        lsa        $8, $9, $10, 4              # encoding: [0x01,0x2a,0x40,0xc5]
 
+# CHECKOBJDUMP: lsa        $8, $9, $10, 1
 # CHECKOBJDUMP: lsa        $8, $9, $10, 2
+# CHECKOBJDUMP: lsa        $8, $9, $10, 3
+# CHECKOBJDUMP: lsa        $8, $9, $10, 4
 
+                lsa        $8, $9, $10, 1
                 lsa        $8, $9, $10, 2
+                lsa        $8, $9, $10, 3
+                lsa        $8, $9, $10, 4





More information about the llvm-commits mailing list