diff --git a/llvm/lib/Target/VE/AsmParser/VEAsmParser.cpp b/llvm/lib/Target/VE/AsmParser/VEAsmParser.cpp --- a/llvm/lib/Target/VE/AsmParser/VEAsmParser.cpp +++ b/llvm/lib/Target/VE/AsmParser/VEAsmParser.cpp @@ -67,6 +67,7 @@ // 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 &Operand); @@ -120,6 +121,8 @@ 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 @@ 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 @@ } return false; } + bool isMImm() const { + if (Kind != k_MImmOp) + return false; + + // Constant case + if (const MCConstantExpr *ConstExpr = dyn_cast(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 @@ 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 @@ 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 @@ // FIXME: implement } + void addMImmOperands(MCInst &Inst, unsigned N) const { + assert(N == 1 && "Invalid number of operands!"); + const MCConstantExpr *ConstExpr = dyn_cast(getMImmVal()); + assert(ConstExpr && "Null operands!"); + int64_t Value = ConstExpr->getValue(); + if (getM0Flag()) + Value += 64; + Inst.addOperand(MCOperand::createImm(Value)); + } + static std::unique_ptr CreateToken(StringRef Str, SMLoc S) { auto Op = std::make_unique(k_Token); Op->Tok.Data = Str.data(); @@ -356,6 +398,16 @@ return Op; } + static std::unique_ptr CreateMImm(const MCExpr *Val, bool Flag, + SMLoc S, SMLoc E) { + auto Op = std::make_unique(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 @@ return MatchOperand_Success; } +OperandMatchResultTy VEAsmParser::parseMImmOperand(OperandVector &Operands) { + LLVM_DEBUG(dbgs() << "parseMImmOpeand\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 --- a/llvm/lib/Target/VE/VEInstrInfo.td +++ b/llvm/lib/Target/VE/VEInstrInfo.td @@ -116,14 +116,23 @@ return isUInt<7>(N->getZExtValue()); }]>; // simm7 - Generic immediate value. +def SImm7AsmOperand : AsmOperandClass { + let Name = "SImm7"; +} def simm7 : Operand, 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, PatLeaf<(imm), [{ return isMImmVal(getImmVal(N)); }], MIMM> { + let ParserMatchClass = MImmAsmOperand; let PrintMethod = "printMImmOperand"; } @@ -817,6 +826,7 @@ 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 --- /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 --- /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 --- /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 --- /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 --- /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 --- /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