This is an archive of the discontinued LLVM Phabricator instance.

[mips][microMIPS] Implement SWM32 and LWM32 instructions
ClosedPublic

Authored by zoran.jovanovic on Sep 29 2014, 5:08 AM.

Diff Detail

Repository
rL LLVM

Event Timeline

zoran.jovanovic retitled this revision from to [mips][microMIPS] Implement SWM32 and LWM32 instructions.
zoran.jovanovic updated this object.
zoran.jovanovic edited the test plan for this revision. (Show Details)

Implementation of swm alias removed from patch (it will be posted in separate patch).
Operands checking moved to Predicate methods.

sstankovic added inline comments.Nov 6 2014, 3:06 AM
lib/Target/Mips/AsmParser/MipsAsmParser.cpp
428 ↗(On Diff #14867)

Comment is unaligned.

2471 ↗(On Diff #14867)

Add space after if.

2479 ↗(On Diff #14867)

There are several problems with this "if (RegRange)" statement (and its "else" part). Here are some of the legal instructions that are wrongly assembled:

lwm32 $16-$23, $30, 8($4)
lwm32 $16-$19, $31, 8($4)
lwm32 $16-$23, $30, $31, 8($4)
lwm32 $16-$23, $30-$31, 8($4)

Also, the wrong error message is printed for the following instruction:

lwm32 $16, $17, $18, $19, $20, $21, $22, $23, $24, 8($4)

Instead of printing "invalid register operand" (for $24), it prints "consecutive register numbers expected".

Here is a suggestion for the code that can correctly assemble previous instructions:

if (RegRange) {
  // Range cannot end with Mips::S0 or Mips::FP.
  if (((RegNo < Mips::S1) || (RegNo > Mips::S7)) &&
      (RegNo != Mips::RA)) {
    Error(E, "invalid register operand");
    return MatchOperand_ParseFail;
  }
  if (RegNo == Mips::RA) {
    // Check the range $30-$31.
    if (PrevReg != Mips::FP) {
      Error(E, "invalid register operand");
      return MatchOperand_ParseFail;
    }
    Regs.push_back(RegNo);
  } else {
    // Check the range $Sx-$Sy.
    if (RegNo <= PrevReg) {
      Error(E, "invalid register operand");
      return MatchOperand_ParseFail;
    }

    do {
      Regs.push_back(++PrevReg);
    } while (PrevReg < RegNo);
  }
} else {
  if (((RegNo < Mips::S0) || (RegNo > Mips::S7)) &&
      (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
    Error(E, "invalid register operand");
    return MatchOperand_ParseFail;
  }
  if ((PrevReg == Mips::NoRegister) && (RegNo != Mips::S0) &&
      (RegNo != Mips::RA)) {
    Error(E, "$16 or $31 expected");
    return MatchOperand_ParseFail;
  }
  if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1)) {
    if ((RegNo == Mips::FP) && (PrevReg != Mips::S7)) {
      Error(E, "consecutive register numbers expected");
      return MatchOperand_ParseFail;
    }
  }
  Regs.push_back(RegNo);
}

Note that you also need to close the range (see the comment below).

Whatever your final solution is, please include in the tests all the assembly instructions mentioned above, to make sure that they pass.

2482 ↗(On Diff #14867)

Is this line needed? If I comment it out, all the tests still pass.

2511 ↗(On Diff #14867)

You need to close the range if the comma is encountered:

if (Parser.getTok().is(AsmToken::Comma))
  RegRange = false;
2519 ↗(On Diff #14867)

Add space after if.

lib/Target/Mips/Disassembler/MipsDisassembler.cpp
1427 ↗(On Diff #14867)

Add space after if.

lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp
228 ↗(On Diff #14867)

Add '.' at the end of both lines. (There are two more places with the same comment, so this applies to that comments too.)

340 ↗(On Diff #14867)

typos "regiter" and "iti".

New patch version.
parseRegisterList refactored.
Test cases extended.

sstankovic accepted this revision.Nov 18 2014, 3:03 AM
sstankovic edited edge metadata.
This revision is now accepted and ready to land.Nov 18 2014, 3:03 AM
Diffusion closed this revision.Nov 19 2014, 8:44 AM
Diffusion updated this revision to Diff 16387.

Closed by commit rL222367 (authored by zjovanovic).