[llvm] 58b810b - [VE] Support fixed-point operation instructions in MC layer
Simon Moll via llvm-commits
llvm-commits at lists.llvm.org
Fri Jun 5 02:57:01 PDT 2020
Author: Kazushi (Jam) Marukawa
Date: 2020-06-05T11:56:26+02:00
New Revision: 58b810b579a8fbe58bac24f7d573f8511c22854c
URL: https://github.com/llvm/llvm-project/commit/58b810b579a8fbe58bac24f7d573f8511c22854c
DIFF: https://github.com/llvm/llvm-project/commit/58b810b579a8fbe58bac24f7d573f8511c22854c.diff
LOG: [VE] Support fixed-point operation instructions in MC layer
Summary:
Add regression tests of asmparser, mccodeemitter, and disassembler for
fixed-point operation instructions. In order to support them, we add
MImm parser to asmparser. Also add a new MPD instruction which is one
of multiply instructions.
Differential Revision: https://reviews.llvm.org/D81207
Added:
llvm/test/MC/VE/ADD.s
llvm/test/MC/VE/CMP.s
llvm/test/MC/VE/DIV.s
llvm/test/MC/VE/MAXMIN.s
llvm/test/MC/VE/MUL.s
llvm/test/MC/VE/SUB.s
Modified:
llvm/lib/Target/VE/AsmParser/VEAsmParser.cpp
llvm/lib/Target/VE/VEInstrInfo.td
Removed:
################################################################################
diff --git a/llvm/lib/Target/VE/AsmParser/VEAsmParser.cpp b/llvm/lib/Target/VE/AsmParser/VEAsmParser.cpp
index 30dd581eddb5..b2d3831e2668 100644
--- a/llvm/lib/Target/VE/AsmParser/VEAsmParser.cpp
+++ b/llvm/lib/Target/VE/AsmParser/VEAsmParser.cpp
@@ -67,6 +67,7 @@ class VEAsmParser : public MCTargetAsmParser {
// Custom parse functions for VE specific operands.
OperandMatchResultTy parseMEMOperand(OperandVector &Operands);
+ OperandMatchResultTy parseMImmOperand(OperandVector &Operands);
OperandMatchResultTy parseOperand(OperandVector &Operands, StringRef Name);
OperandMatchResultTy parseVEAsmOperand(std::unique_ptr<VEOperand> &Operand);
@@ -120,6 +121,8 @@ class VEOperand : public MCParsedAsmOperand {
k_MemoryRegImmImm, // base=reg, index=imm, disp=imm
k_MemoryZeroRegImm, // base=0, index=reg, disp=imm
k_MemoryZeroImmImm, // base=0, index=imm, disp=imm
+ k_MImmOp, // Special immediate value of sequential bit stream
+ // of 0 or 1.
} Kind;
SMLoc StartLoc, EndLoc;
@@ -144,11 +147,17 @@ class VEOperand : public MCParsedAsmOperand {
const MCExpr *Offset;
};
+ struct MImmOp {
+ const MCExpr *Val;
+ bool M0Flag;
+ };
+
union {
struct Token Tok;
struct RegOp Reg;
struct ImmOp Imm;
struct MemOp Mem;
+ struct MImmOp MImm;
};
public:
@@ -179,6 +188,17 @@ class VEOperand : public MCParsedAsmOperand {
}
return false;
}
+ bool isMImm() const {
+ if (Kind != k_MImmOp)
+ return false;
+
+ // Constant case
+ if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(MImm.Val)) {
+ int64_t Value = ConstExpr->getValue();
+ return isUInt<6>(Value);
+ }
+ return false;
+ }
StringRef getToken() const {
assert(Kind == k_Token && "Invalid access!");
@@ -227,6 +247,15 @@ class VEOperand : public MCParsedAsmOperand {
Mem.Offset = off;
}
+ const MCExpr *getMImmVal() const {
+ assert((Kind == k_MImmOp) && "Invalid access!");
+ return MImm.Val;
+ }
+ bool getM0Flag() const {
+ assert((Kind == k_MImmOp) && "Invalid access!");
+ return MImm.M0Flag;
+ }
+
/// getStartLoc - Get the location of the first token of this operand.
SMLoc getStartLoc() const override { return StartLoc; }
/// getEndLoc - Get the location of the last token of this operand.
@@ -261,6 +290,9 @@ class VEOperand : public MCParsedAsmOperand {
assert(getMemIndex() != nullptr && getMemOffset() != nullptr);
OS << "Mem: 0+" << *getMemIndex() << "+" << *getMemOffset() << "\n";
break;
+ case k_MImmOp:
+ OS << "MImm: (" << getMImmVal() << (getM0Flag() ? ")0" : ")1") << "\n";
+ break;
}
}
@@ -329,6 +361,16 @@ class VEOperand : public MCParsedAsmOperand {
// FIXME: implement
}
+ void addMImmOperands(MCInst &Inst, unsigned N) const {
+ assert(N == 1 && "Invalid number of operands!");
+ const auto *ConstExpr = dyn_cast<MCConstantExpr>(getMImmVal());
+ assert(ConstExpr && "Null operands!");
+ int64_t Value = ConstExpr->getValue();
+ if (getM0Flag())
+ Value += 64;
+ Inst.addOperand(MCOperand::createImm(Value));
+ }
+
static std::unique_ptr<VEOperand> CreateToken(StringRef Str, SMLoc S) {
auto Op = std::make_unique<VEOperand>(k_Token);
Op->Tok.Data = Str.data();
@@ -356,6 +398,16 @@ class VEOperand : public MCParsedAsmOperand {
return Op;
}
+ static std::unique_ptr<VEOperand> CreateMImm(const MCExpr *Val, bool Flag,
+ SMLoc S, SMLoc E) {
+ auto Op = std::make_unique<VEOperand>(k_MImmOp);
+ Op->MImm.Val = Val;
+ Op->MImm.M0Flag = Flag;
+ Op->StartLoc = S;
+ Op->EndLoc = E;
+ return Op;
+ }
+
static bool MorphToI32Reg(VEOperand &Op) {
unsigned Reg = Op.getReg();
unsigned regIdx = Reg - VE::SX0;
@@ -651,6 +703,47 @@ OperandMatchResultTy VEAsmParser::parseMEMOperand(OperandVector &Operands) {
return MatchOperand_Success;
}
+OperandMatchResultTy VEAsmParser::parseMImmOperand(OperandVector &Operands) {
+ LLVM_DEBUG(dbgs() << "parseMImmOperand\n");
+
+ // Parsing "(" + number + ")0/1"
+ const AsmToken Tok1 = Parser.getTok();
+ if (!Tok1.is(AsmToken::LParen))
+ return MatchOperand_NoMatch;
+
+ Parser.Lex(); // Eat the '('.
+
+ const AsmToken Tok2 = Parser.getTok();
+ SMLoc E;
+ const MCExpr *EVal;
+ if (!Tok2.is(AsmToken::Integer) || getParser().parseExpression(EVal, E)) {
+ getLexer().UnLex(Tok1);
+ return MatchOperand_NoMatch;
+ }
+
+ const AsmToken Tok3 = Parser.getTok();
+ if (!Tok3.is(AsmToken::RParen)) {
+ getLexer().UnLex(Tok2);
+ getLexer().UnLex(Tok1);
+ return MatchOperand_NoMatch;
+ }
+ Parser.Lex(); // Eat the ')'.
+
+ const AsmToken &Tok4 = Parser.getTok();
+ StringRef Suffix = Tok4.getString();
+ if (Suffix != "1" && Suffix != "0") {
+ getLexer().UnLex(Tok3);
+ getLexer().UnLex(Tok2);
+ getLexer().UnLex(Tok1);
+ return MatchOperand_NoMatch;
+ }
+ Parser.Lex(); // Eat the value.
+ SMLoc EndLoc = SMLoc::getFromPointer(Suffix.end());
+ Operands.push_back(
+ VEOperand::CreateMImm(EVal, Suffix == "0", Tok1.getLoc(), EndLoc));
+ return MatchOperand_Success;
+}
+
OperandMatchResultTy VEAsmParser::parseOperand(OperandVector &Operands,
StringRef Mnemonic) {
LLVM_DEBUG(dbgs() << "parseOperand\n");
diff --git a/llvm/lib/Target/VE/VEInstrInfo.td b/llvm/lib/Target/VE/VEInstrInfo.td
index 89be9bd97ef5..27eb11c8dea8 100644
--- a/llvm/lib/Target/VE/VEInstrInfo.td
+++ b/llvm/lib/Target/VE/VEInstrInfo.td
@@ -116,14 +116,23 @@ def uimm7 : Operand<i32>, PatLeaf<(imm), [{
return isUInt<7>(N->getZExtValue()); }]>;
// simm7 - Generic immediate value.
+def SImm7AsmOperand : AsmOperandClass {
+ let Name = "SImm7";
+}
def simm7 : Operand<i32>, PatLeaf<(imm), [{
return isInt<7>(N->getSExtValue()); }], LO7> {
+ let ParserMatchClass = SImm7AsmOperand;
let DecoderMethod = "DecodeSIMM7";
}
// mimm - Special immediate value of sequential bit stream of 0 or 1.
+def MImmAsmOperand : AsmOperandClass {
+ let Name = "MImm";
+ let ParserMethod = "parseMImmOperand";
+}
def mimm : Operand<i32>, PatLeaf<(imm), [{
return isMImmVal(getImmVal(N)); }], MIMM> {
+ let ParserMatchClass = MImmAsmOperand;
let PrintMethod = "printMImmOperand";
}
@@ -817,6 +826,7 @@ let cx = 1 in defm MULSWZX : RRm<"muls.w.zx", 0x4B, I32, i32>;
defm MULSL : RRm<"muls.l", 0x6E, I64, i64, mul>;
// Section 8.4.10 - MPD (Multiply)
+defm MULSLW : RRbm<"muls.l.w", 0x6B, I64, i64, I32, i32>;
// Section 8.4.11 - DIV (Divide)
defm DIVUL : RRNCm<"divu.l", 0x6F, I64, i64, udiv>;
diff --git a/llvm/test/MC/VE/ADD.s b/llvm/test/MC/VE/ADD.s
new file mode 100644
index 000000000000..9cdc97e0021a
--- /dev/null
+++ b/llvm/test/MC/VE/ADD.s
@@ -0,0 +1,24 @@
+# RUN: llvm-mc -triple=ve --show-encoding < %s \
+# RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+# RUN: llvm-mc -triple=ve -filetype=obj < %s | llvm-objdump -d - \
+# RUN: | FileCheck %s --check-prefixes=CHECK-INST
+
+# CHECK-INST: addu.l %s11, %s20, %s22
+# CHECK-ENCODING: encoding: [0x00,0x00,0x00,0x00,0x96,0x94,0x0b,0x48]
+addu.l %s11, %s20, %s22
+
+# CHECK-INST: addu.w %s11, 22, %s22
+# CHECK-ENCODING: encoding: [0x00,0x00,0x00,0x00,0x96,0x16,0x8b,0x48]
+addu.w %s11, 22, %s22
+
+# CHECK-INST: adds.w.sx %s11, 63, (60)1
+# CHECK-ENCODING: encoding: [0x00,0x00,0x00,0x00,0x3c,0x3f,0x0b,0x4a]
+adds.w.sx %s11, 63, (60)1
+
+# CHECK-INST: adds.w.zx %s11, -64, %s22
+# CHECK-ENCODING: encoding: [0x00,0x00,0x00,0x00,0x96,0x40,0x8b,0x4a]
+adds.w.zx %s11, -64, %s22
+
+# CHECK-INST: adds.l %s11, -64, (22)0
+# CHECK-ENCODING: encoding: [0x00,0x00,0x00,0x00,0x56,0x40,0x0b,0x59]
+adds.l %s11, -64, (22)0
diff --git a/llvm/test/MC/VE/CMP.s b/llvm/test/MC/VE/CMP.s
new file mode 100644
index 000000000000..c2e3af8ad3ad
--- /dev/null
+++ b/llvm/test/MC/VE/CMP.s
@@ -0,0 +1,24 @@
+# RUN: llvm-mc -triple=ve --show-encoding < %s \
+# RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+# RUN: llvm-mc -triple=ve -filetype=obj < %s | llvm-objdump -d - \
+# RUN: | FileCheck %s --check-prefixes=CHECK-INST
+
+# CHECK-INST: cmpu.l %s11, %s20, %s22
+# CHECK-ENCODING: encoding: [0x00,0x00,0x00,0x00,0x96,0x94,0x0b,0x55]
+cmpu.l %s11, %s20, %s22
+
+# CHECK-INST: cmpu.w %s11, 22, %s22
+# CHECK-ENCODING: encoding: [0x00,0x00,0x00,0x00,0x96,0x16,0x8b,0x55]
+cmpu.w %s11, 22, %s22
+
+# CHECK-INST: cmps.w.sx %s11, 63, (60)1
+# CHECK-ENCODING: encoding: [0x00,0x00,0x00,0x00,0x3c,0x3f,0x0b,0x7a]
+cmps.w.sx %s11, 63, (60)1
+
+# CHECK-INST: cmps.w.zx %s11, -64, %s22
+# CHECK-ENCODING: encoding: [0x00,0x00,0x00,0x00,0x96,0x40,0x8b,0x7a]
+cmps.w.zx %s11, -64, %s22
+
+# CHECK-INST: cmps.l %s11, -64, (22)0
+# CHECK-ENCODING: encoding: [0x00,0x00,0x00,0x00,0x56,0x40,0x0b,0x6a]
+cmps.l %s11, -64, (22)0
diff --git a/llvm/test/MC/VE/DIV.s b/llvm/test/MC/VE/DIV.s
new file mode 100644
index 000000000000..a81718c56e1b
--- /dev/null
+++ b/llvm/test/MC/VE/DIV.s
@@ -0,0 +1,24 @@
+# RUN: llvm-mc -triple=ve --show-encoding < %s \
+# RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+# RUN: llvm-mc -triple=ve -filetype=obj < %s | llvm-objdump -d - \
+# RUN: | FileCheck %s --check-prefixes=CHECK-INST
+
+# CHECK-INST: divu.l %s11, %s20, %s22
+# CHECK-ENCODING: encoding: [0x00,0x00,0x00,0x00,0x96,0x94,0x0b,0x6f]
+divu.l %s11, %s20, %s22
+
+# CHECK-INST: divu.w %s11, 22, %s22
+# CHECK-ENCODING: encoding: [0x00,0x00,0x00,0x00,0x96,0x16,0x8b,0x6f]
+divu.w %s11, 22, %s22
+
+# CHECK-INST: divs.w.sx %s11, 63, (60)1
+# CHECK-ENCODING: encoding: [0x00,0x00,0x00,0x00,0x3c,0x3f,0x0b,0x7b]
+divs.w.sx %s11, 63, (60)1
+
+# CHECK-INST: divs.w.zx %s11, -64, %s22
+# CHECK-ENCODING: encoding: [0x00,0x00,0x00,0x00,0x96,0x40,0x8b,0x7b]
+divs.w.zx %s11, -64, %s22
+
+# CHECK-INST: divs.l %s11, -64, (22)0
+# CHECK-ENCODING: encoding: [0x00,0x00,0x00,0x00,0x56,0x40,0x0b,0x7f]
+divs.l %s11, -64, (22)0
diff --git a/llvm/test/MC/VE/MAXMIN.s b/llvm/test/MC/VE/MAXMIN.s
new file mode 100644
index 000000000000..5ccb606cbfed
--- /dev/null
+++ b/llvm/test/MC/VE/MAXMIN.s
@@ -0,0 +1,28 @@
+# RUN: llvm-mc -triple=ve --show-encoding < %s \
+# RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+# RUN: llvm-mc -triple=ve -filetype=obj < %s | llvm-objdump -d - \
+# RUN: | FileCheck %s --check-prefixes=CHECK-INST
+
+# CHECK-INST: maxs.w.sx %s11, %s20, %s22
+# CHECK-ENCODING: encoding: [0x00,0x00,0x00,0x00,0x96,0x94,0x0b,0x78]
+maxs.w.sx %s11, %s20, %s22
+
+# CHECK-INST: maxs.w.zx %s11, 22, %s22
+# CHECK-ENCODING: encoding: [0x00,0x00,0x00,0x00,0x96,0x16,0x8b,0x78]
+maxs.w.zx %s11, 22, %s22
+
+# CHECK-INST: mins.w.sx %s11, 63, (63)1
+# CHECK-ENCODING: encoding: [0x80,0x00,0x00,0x00,0x3f,0x3f,0x0b,0x78]
+mins.w.sx %s11, 63, (63)1
+
+# CHECK-INST: mins.w.zx %s11, -64, %s22
+# CHECK-ENCODING: encoding: [0x80,0x00,0x00,0x00,0x96,0x40,0x8b,0x78]
+mins.w.zx %s11, -64, %s22
+
+# CHECK-INST: maxs.l %s11, -64, (22)0
+# CHECK-ENCODING: encoding: [0x00,0x00,0x00,0x00,0x56,0x40,0x0b,0x68]
+maxs.l %s11, -64, (22)0
+
+# CHECK-INST: mins.l %s11, -64, (22)1
+# CHECK-ENCODING: encoding: [0x80,0x00,0x00,0x00,0x16,0x40,0x0b,0x68]
+mins.l %s11, -64, (22)1
diff --git a/llvm/test/MC/VE/MUL.s b/llvm/test/MC/VE/MUL.s
new file mode 100644
index 000000000000..632562cc3889
--- /dev/null
+++ b/llvm/test/MC/VE/MUL.s
@@ -0,0 +1,28 @@
+# RUN: llvm-mc -triple=ve --show-encoding < %s \
+# RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+# RUN: llvm-mc -triple=ve -filetype=obj < %s | llvm-objdump -d - \
+# RUN: | FileCheck %s --check-prefixes=CHECK-INST
+
+# CHECK-INST: mulu.l %s11, %s20, %s22
+# CHECK-ENCODING: encoding: [0x00,0x00,0x00,0x00,0x96,0x94,0x0b,0x49]
+mulu.l %s11, %s20, %s22
+
+# CHECK-INST: mulu.w %s11, 22, %s22
+# CHECK-ENCODING: encoding: [0x00,0x00,0x00,0x00,0x96,0x16,0x8b,0x49]
+mulu.w %s11, 22, %s22
+
+# CHECK-INST: muls.w.sx %s11, 63, (60)1
+# CHECK-ENCODING: encoding: [0x00,0x00,0x00,0x00,0x3c,0x3f,0x0b,0x4b]
+muls.w.sx %s11, 63, (60)1
+
+# CHECK-INST: muls.w.zx %s11, -64, %s22
+# CHECK-ENCODING: encoding: [0x00,0x00,0x00,0x00,0x96,0x40,0x8b,0x4b]
+muls.w.zx %s11, -64, %s22
+
+# CHECK-INST: muls.l %s11, -64, (22)0
+# CHECK-ENCODING: encoding: [0x00,0x00,0x00,0x00,0x56,0x40,0x0b,0x6e]
+muls.l %s11, -64, (22)0
+
+# CHECK-INST: muls.l.w %s11, -64, (22)0
+# CHECK-ENCODING: encoding: [0x00,0x00,0x00,0x00,0x56,0x40,0x0b,0x6b]
+muls.l.w %s11, -64, (22)0
diff --git a/llvm/test/MC/VE/SUB.s b/llvm/test/MC/VE/SUB.s
new file mode 100644
index 000000000000..c73f238ed3e9
--- /dev/null
+++ b/llvm/test/MC/VE/SUB.s
@@ -0,0 +1,24 @@
+# RUN: llvm-mc -triple=ve --show-encoding < %s \
+# RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+# RUN: llvm-mc -triple=ve -filetype=obj < %s | llvm-objdump -d - \
+# RUN: | FileCheck %s --check-prefixes=CHECK-INST
+
+# CHECK-INST: subu.l %s11, %s20, %s22
+# CHECK-ENCODING: encoding: [0x00,0x00,0x00,0x00,0x96,0x94,0x0b,0x58]
+subu.l %s11, %s20, %s22
+
+# CHECK-INST: subu.w %s11, 22, %s22
+# CHECK-ENCODING: encoding: [0x00,0x00,0x00,0x00,0x96,0x16,0x8b,0x58]
+subu.w %s11, 22, %s22
+
+# CHECK-INST: subs.w.sx %s11, 63, (60)1
+# CHECK-ENCODING: encoding: [0x00,0x00,0x00,0x00,0x3c,0x3f,0x0b,0x5a]
+subs.w.sx %s11, 63, (60)1
+
+# CHECK-INST: subs.w.zx %s11, -64, %s22
+# CHECK-ENCODING: encoding: [0x00,0x00,0x00,0x00,0x96,0x40,0x8b,0x5a]
+subs.w.zx %s11, -64, %s22
+
+# CHECK-INST: subs.l %s11, -64, (22)0
+# CHECK-ENCODING: encoding: [0x00,0x00,0x00,0x00,0x56,0x40,0x0b,0x5b]
+subs.l %s11, -64, (22)0
More information about the llvm-commits
mailing list