NaplesPUInstrFormats.td
From NaplesPU Documentation
The NuPlusInstrFormats.td contains the classes that describe the nu+ instruction formats, support classes to facilitate the instructions definition and also the definition nodes which make the pattern recognition easier.
//===-- NuPlusInstrFormats.td - NuPlus Instruction Formats ---*- tablegen -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
// Instruction Pattern Stuff
//===----------------------------------------------------------------------===//
def simm16 : PatLeaf<(imm), [{ return isInt<16>(N->getSExtValue()); }]>;
def simm9 : PatLeaf<(imm), [{ return isInt<9>(N->getSExtValue()); }]>;
// Addressing modes as in SPARC
def ADDRri : ComplexPattern<iPTR, 2, "SelectADDRri", [frameindex], []>;
def V16ADDRri : ComplexPattern<v16i32, 2, "SelectADDRri", [], []>;
def V8ADDRri : ComplexPattern<v8i64, 2, "SelectADDRri", [], []>;
//===----------------------------------------------------------------------===//
// NuPlus profiles and nodes
//===----------------------------------------------------------------------===//
// Transformation nodes
def LO32I : SDNodeXForm<imm, [{
return CurDAG->getTargetConstant((unsigned)N->getAPIntValue().getLoBits(32).getZExtValue(), SDLoc(N), MVT::i32);}]>;
def HI32I : SDNodeXForm<imm, [{
// Transformation function: shift the immediate value down into the low bits.
return CurDAG->getTargetConstant((unsigned)N->getAPIntValue().getHiBits(32).getZExtValue(), SDLoc(N), MVT::i32);}]>;
def LO32F : SDNodeXForm<fpimm, [{
return CurDAG->getTargetConstant((unsigned)(N->getValueAPF().bitcastToAPInt().getLoBits(32).getZExtValue()), SDLoc(N), MVT::i32);}]>;
def HI32F : SDNodeXForm<fpimm, [{
// Transformation function: shift the immediate value down into the low bits.
return CurDAG->getTargetConstant((unsigned)(N->getValueAPF().bitcastToAPInt().getHiBits(32).getZExtValue()), SDLoc(N), MVT::i32);}]>;
def DIV2 : SDNodeXForm<imm, [{
return CurDAG->getTargetConstant((unsigned)N->getZExtValue() / 2, SDLoc(N), MVT::i32);}]>;
// Moveil/moveih nodes definition, used for globaladdress lowering
def leah : SDNode<"NuPlusISD::LEAH", SDTypeProfile<1, 1, []>>;
def leal : SDNode<"NuPlusISD::LEAL", SDTypeProfile<1, 2, []>>;
// A splat is a vector with the same value in all lanes. Used to handle operation
// with both vector and scalar operands.
def splat : SDNode<"NuPlusISD::SPLAT", SDTypeProfile<1, 1, [SDTCisEltOfVec<1, 0>]>>;
def return : SDNode<"NuPlusISD::RET_FLAG", SDTypeProfile<0, 0, []>,
[SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
def SDT_SPCall : SDTypeProfile<0, -1, [SDTCisVT<0, i32>]>;
def call : SDNode<"NuPlusISD::CALL", SDT_SPCall,
[SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, SDNPVariadic]>;
//To mark the beginning and end of a call sequence
def SDT_SPCallSeqStart : SDCallSeqStart<[SDTCisVT<0, i32>, SDTCisVT<1, i32>]>;
def SDT_SPCallSeqEnd : SDCallSeqEnd<[SDTCisVT<0, i32>, SDTCisVT<1, i32>]>;
def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_SPCallSeqStart,
[SDNPHasChain, SDNPSideEffect, SDNPOutGlue]>;
def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_SPCallSeqEnd,
[SDNPHasChain, SDNPSideEffect,
SDNPOptInGlue, SDNPOutGlue]>;
//To handle the lack of conditional moves
def selcondresult : SDNode<"NuPlusISD::SEL_COND_RESULT", SDTypeProfile<1, 3,
[SDTCisSameAs<0, 2>, SDTCisSameAs<0, 3>]>>;
//===----------------------------------------------------------------------===//
// Operand Definitions
//===----------------------------------------------------------------------===//
// Used for the LEA_Sym, to detect the lea pseudo instruction
def symref : Operand<OtherVT> {}
def SIMM16OP : Operand<i32> {
let DecoderMethod = "decodeSimm16Value";
}
def SIMM9OP : Operand<i32> {
let DecoderMethod = "decodeSimm9Value";
}
def MemAsmOperand : AsmOperandClass {
let Name = "Mem";
let ParserMethod = "ParseMemoryOperand";
}
def MEMri : Operand<iPTR> {
let PrintMethod = "printMemOperand";
let EncoderMethod = "encodeMemoryOpValue";
let DecoderMethod = "decodeScalarMemoryOpValue";
let ParserMatchClass = MemAsmOperand;
let MIOperandInfo = (ops GPR32, i32imm);
}
def V16MEMri : Operand<v16i32> {
let PrintMethod = "printMemOperand";
let EncoderMethod = "encodeMemoryOpValue";
let DecoderMethod = "decodeVectorWMemoryOpValue";
let ParserMatchClass = MemAsmOperand;
let MIOperandInfo = (ops VR512W, i32imm);
}
def LEAri : Operand<iPTR> {
let PrintMethod = "printMemOperand";
let EncoderMethod = "encodeLEAValue";
let ParserMatchClass = MemAsmOperand; //TODO: controllare se è corretto il ParserMatchClass
let MIOperandInfo = (ops GPR32, i32imm);
}
def ABSh : Operand<iPTR> {
let PrintMethod = "printMemOperand";
let EncoderMethod = "encodeABShValue";
let ParserMatchClass = MemAsmOperand; //TODO: controllare se è corretto il ParserMatchClass
let MIOperandInfo = (ops i32imm);
}
def ABSl : Operand<iPTR> {
let PrintMethod = "printMemOperand";
let EncoderMethod = "encodeABSlValue";
let ParserMatchClass = MemAsmOperand; //TODO: controllare se è corretto il ParserMatchClass
let MIOperandInfo = (ops i32imm);
}
def brtarget : Operand<OtherVT>
{
let EncoderMethod = "encodeBranchTargetOpValue";
let DecoderMethod = "decodeBranchTargetOpValue";
}
def calltarget : Operand<iPTR>
{
let EncoderMethod = "encodeBranchTargetOpValue";
let DecoderMethod = "decodeBranchTargetOpValue";
}
//===----------------------------------------------------------------------===//
// Pattern fragments
//===----------------------------------------------------------------------===//
// Definition of anyextload used in the loading of vector types < 512 bits
def anyextload : PatFrag<(ops node:$ptr), (unindexedload node:$ptr),
[{ return cast<LoadSDNode>(N)->getExtensionType() != ISD::NON_EXTLOAD;}]>;
//----------------------------------------------------------------------------//
//------------------------------ LOAD AND STORE ------------------------------//
//----------------------------------------------------------------------------//
def MemStore : PatFrag<(ops node:$val, node:$ptr), (store node:$val, node:$ptr), [{
if(cast<StoreSDNode>(N)->getAddressSpace() != 77)
return !cast<StoreSDNode>(N)->isTruncatingStore();
else
return false;}]>;
def MemLoad : PatFrag<(ops node:$ptr), (load node:$ptr), [{
if(cast<LoadSDNode>(N)->getAddressSpace() != 77)
return cast<LoadSDNode>(N)->getExtensionType() == ISD::NON_EXTLOAD;
else
return false;}]>;
def ScratchpadStore : PatFrag<(ops node:$val, node:$ptr), (store node:$val, node:$ptr), [{
if(cast<StoreSDNode>(N)->getAddressSpace() == 77)
return !cast<StoreSDNode>(N)->isTruncatingStore();
else
return false;}]>;
def ScratchpadLoad : PatFrag<(ops node:$ptr), (load node:$ptr), [{
if(cast<LoadSDNode>(N)->getAddressSpace() == 77)
return cast<LoadSDNode>(N)->getExtensionType() == ISD::NON_EXTLOAD;
else
return false;}]>;
//---------------- EXTLOAD scalar ----------------//
def extloadi1_mem : PatFrag<(ops node:$ptr), (extload node:$ptr), [{
if(cast<LoadSDNode>(N)->getAddressSpace() != 77)
return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i1;
else
return false;}]>;
def extloadi1_scratch : PatFrag<(ops node:$ptr), (extload node:$ptr), [{
if(cast<LoadSDNode>(N)->getAddressSpace() == 77)
return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i1;
else
return false;}]>;
def extloadi8_mem : PatFrag<(ops node:$ptr), (extload node:$ptr), [{
if(cast<LoadSDNode>(N)->getAddressSpace() != 77)
return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i8;
else
return false;}]>;
def extloadi8_scratch : PatFrag<(ops node:$ptr), (extload node:$ptr), [{
if(cast<LoadSDNode>(N)->getAddressSpace() == 77)
return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i8;
else
return false;}]>;
def extloadi16_mem : PatFrag<(ops node:$ptr), (extload node:$ptr), [{
if(cast<LoadSDNode>(N)->getAddressSpace() != 77)
return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i16;
else
return false;}]>;
def extloadi16_scratch : PatFrag<(ops node:$ptr), (extload node:$ptr), [{
if(cast<LoadSDNode>(N)->getAddressSpace() == 77)
return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i16;
else
return false;}]>;
def extloadi32_mem : PatFrag<(ops node:$ptr), (extload node:$ptr), [{
if(cast<LoadSDNode>(N)->getAddressSpace() != 77)
return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i32;
else
return false;}]>;
def extloadi32_scratch : PatFrag<(ops node:$ptr), (extload node:$ptr), [{
if(cast<LoadSDNode>(N)->getAddressSpace() == 77)
return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i32;
else
return false;}]>;
//---------------- ZEXTLOAD scalar ----------------//
def zextloadi1_mem : PatFrag<(ops node:$ptr), (zextload node:$ptr), [{
if(cast<LoadSDNode>(N)->getAddressSpace() != 77)
return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i1;
else
return false;}]>;
def zextloadi1_scratch : PatFrag<(ops node:$ptr), (zextload node:$ptr), [{
if(cast<LoadSDNode>(N)->getAddressSpace() == 77)
return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i1;
else
return false;}]>;
def zextloadi8_mem : PatFrag<(ops node:$ptr), (zextload node:$ptr), [{
if(cast<LoadSDNode>(N)->getAddressSpace() != 77)
return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i8;
else
return false;}]>;
def zextloadi8_scratch : PatFrag<(ops node:$ptr), (zextload node:$ptr), [{
if(cast<LoadSDNode>(N)->getAddressSpace() == 77)
return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i8;
else
return false;}]>;
def zextloadi16_mem : PatFrag<(ops node:$ptr), (zextload node:$ptr), [{
if(cast<LoadSDNode>(N)->getAddressSpace() != 77)
return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i16;
else
return false;}]>;
def zextloadi16_scratch : PatFrag<(ops node:$ptr), (zextload node:$ptr), [{
if(cast<LoadSDNode>(N)->getAddressSpace() == 77)
return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i16;
else
return false;}]>;
def zextloadi32_mem : PatFrag<(ops node:$ptr), (zextload node:$ptr), [{
if(cast<LoadSDNode>(N)->getAddressSpace() != 77)
return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i32;
else
return false;}]>;
def zextloadi32_scratch : PatFrag<(ops node:$ptr), (zextload node:$ptr), [{
if(cast<LoadSDNode>(N)->getAddressSpace() == 77)
return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i32;
else
return false;}]>;
//---------------- ZEXTLOAD vector ----------------//
def zextloadv16i8_mem: PatFrag<(ops node:$ptr), (zextload node:$ptr),
[{ if(cast<LoadSDNode>(N)->getAddressSpace() != 77)
return cast<LoadSDNode>(N)->getMemoryVT() == MVT::v16i8;
else
return false; }]>;
def zextloadv16i8_scratch: PatFrag<(ops node:$ptr), (zextload node:$ptr),
[{ if(cast<LoadSDNode>(N)->getAddressSpace() == 77)
return cast<LoadSDNode>(N)->getMemoryVT() == MVT::v16i8;
else
return false; }]>;
def zextloadv16i16_mem: PatFrag<(ops node:$ptr), (zextload node:$ptr),
[{ if(cast<LoadSDNode>(N)->getAddressSpace() != 77)
return cast<LoadSDNode>(N)->getMemoryVT() == MVT::v16i16;
else
return false; }]>;
def zextloadv16i16_scratch: PatFrag<(ops node:$ptr), (zextload node:$ptr),
[{ if(cast<LoadSDNode>(N)->getAddressSpace() == 77)
return cast<LoadSDNode>(N)->getMemoryVT() == MVT::v16i16;
else
return false; }]>;
def zextloadv8i8_mem: PatFrag<(ops node:$ptr), (zextload node:$ptr),
[{ if(cast<LoadSDNode>(N)->getAddressSpace() != 77)
return cast<LoadSDNode>(N)->getMemoryVT() == MVT::v8i8;
else
return false; }]>;
def zextloadv8i8_scratch: PatFrag<(ops node:$ptr), (zextload node:$ptr),
[{ if(cast<LoadSDNode>(N)->getAddressSpace() == 77)
return cast<LoadSDNode>(N)->getMemoryVT() == MVT::v8i8;
else
return false; }]>;
def zextloadv8i16_mem: PatFrag<(ops node:$ptr), (zextload node:$ptr),
[{ if(cast<LoadSDNode>(N)->getAddressSpace() != 77)
return cast<LoadSDNode>(N)->getMemoryVT() == MVT::v8i16;
else
return false; }]>;
def zextloadv8i16_scratch: PatFrag<(ops node:$ptr), (zextload node:$ptr),
[{ if(cast<LoadSDNode>(N)->getAddressSpace() == 77)
return cast<LoadSDNode>(N)->getMemoryVT() == MVT::v8i16;
else
return false; }]>;
def zextloadv8i32_mem: PatFrag<(ops node:$ptr), (zextload node:$ptr),
[{ if(cast<LoadSDNode>(N)->getAddressSpace() != 77)
return cast<LoadSDNode>(N)->getMemoryVT() == MVT::v8i32;
else
return false; }]>;
def zextloadv8i32_scratch: PatFrag<(ops node:$ptr), (zextload node:$ptr),
[{ if(cast<LoadSDNode>(N)->getAddressSpace() == 77)
return cast<LoadSDNode>(N)->getMemoryVT() == MVT::v8i32;
else
return false; }]>;
//---------------- SEXTLOAD scalar ----------------//
def sextloadi1_mem : PatFrag<(ops node:$ptr), (sextload node:$ptr), [{
if(cast<LoadSDNode>(N)->getAddressSpace() != 77)
return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i1;
else
return false;}]>;
def sextloadi1_scratch : PatFrag<(ops node:$ptr), (sextload node:$ptr), [{
if(cast<LoadSDNode>(N)->getAddressSpace() == 77)
return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i1;
else
return false;}]>;
def sextloadi8_mem : PatFrag<(ops node:$ptr), (sextload node:$ptr), [{
if(cast<LoadSDNode>(N)->getAddressSpace() != 77)
return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i8;
else
return false;}]>;
def sextloadi8_scratch : PatFrag<(ops node:$ptr), (sextload node:$ptr), [{
if(cast<LoadSDNode>(N)->getAddressSpace() == 77)
return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i8;
else
return false;}]>;
def sextloadi16_mem : PatFrag<(ops node:$ptr), (sextload node:$ptr), [{
if(cast<LoadSDNode>(N)->getAddressSpace() != 77)
return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i16;
else
return false;}]>;
def sextloadi16_scratch : PatFrag<(ops node:$ptr), (sextload node:$ptr), [{
if(cast<LoadSDNode>(N)->getAddressSpace() == 77)
return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i16;
else
return false;}]>;
def sextloadi32_mem : PatFrag<(ops node:$ptr), (sextload node:$ptr), [{
if(cast<LoadSDNode>(N)->getAddressSpace() != 77)
return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i32;
else
return false;}]>;
def sextloadi32_scratch : PatFrag<(ops node:$ptr), (sextload node:$ptr), [{
if(cast<LoadSDNode>(N)->getAddressSpace() == 77)
return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i32;
else
return false;}]>;
//---------------- SEXTLOAD vector ----------------//
def sextloadv16i8_mem: PatFrag<(ops node:$ptr), (sextload node:$ptr),
[{ if(cast<LoadSDNode>(N)->getAddressSpace() != 77)
return cast<LoadSDNode>(N)->getMemoryVT() == MVT::v16i8;
else
return false; }]>;
def sextloadv16i8_scratch: PatFrag<(ops node:$ptr), (sextload node:$ptr),
[{ if(cast<LoadSDNode>(N)->getAddressSpace() == 77)
return cast<LoadSDNode>(N)->getMemoryVT() == MVT::v16i8;
else
return false; }]>;
def sextloadv16i16_mem: PatFrag<(ops node:$ptr), (sextload node:$ptr),
[{ if(cast<LoadSDNode>(N)->getAddressSpace() != 77)
return cast<LoadSDNode>(N)->getMemoryVT() == MVT::v16i16;
else
return false; }]>;
def sextloadv16i16_scratch: PatFrag<(ops node:$ptr), (sextload node:$ptr),
[{ if(cast<LoadSDNode>(N)->getAddressSpace() == 77)
return cast<LoadSDNode>(N)->getMemoryVT() == MVT::v16i16;
else
return false; }]>;
def sextloadv8i8_mem: PatFrag<(ops node:$ptr), (sextload node:$ptr),
[{ if(cast<LoadSDNode>(N)->getAddressSpace() != 77)
return cast<LoadSDNode>(N)->getMemoryVT() == MVT::v8i8;
else
return false; }]>;
def sextloadv8i8_scratch: PatFrag<(ops node:$ptr), (sextload node:$ptr),
[{ if(cast<LoadSDNode>(N)->getAddressSpace() == 77)
return cast<LoadSDNode>(N)->getMemoryVT() == MVT::v8i8;
else
return false; }]>;
def sextloadv8i16_mem: PatFrag<(ops node:$ptr), (sextload node:$ptr),
[{ if(cast<LoadSDNode>(N)->getAddressSpace() != 77)
return cast<LoadSDNode>(N)->getMemoryVT() == MVT::v8i16;
else
return false; }]>;
def sextloadv8i16_scratch: PatFrag<(ops node:$ptr), (sextload node:$ptr),
[{ if(cast<LoadSDNode>(N)->getAddressSpace() == 77)
return cast<LoadSDNode>(N)->getMemoryVT() == MVT::v8i16;
else
return false; }]>;
def sextloadv8i32_mem: PatFrag<(ops node:$ptr), (sextload node:$ptr),
[{ if(cast<LoadSDNode>(N)->getAddressSpace() != 77)
return cast<LoadSDNode>(N)->getMemoryVT() == MVT::v8i32;
else
return false; }]>;
def sextloadv8i32_scratch: PatFrag<(ops node:$ptr), (sextload node:$ptr),
[{ if(cast<LoadSDNode>(N)->getAddressSpace() == 77)
return cast<LoadSDNode>(N)->getMemoryVT() == MVT::v8i32;
else
return false; }]>;
//---------------- ANYEXTLOAD vector ----------------//
def anyextloadv16i8_mem: PatFrag<(ops node:$ptr), (anyextload node:$ptr),
[{ if(cast<LoadSDNode>(N)->getAddressSpace() != 77)
return cast<LoadSDNode>(N)->getMemoryVT() == MVT::v16i8;
else
return false; }]>;
def anyextloadv16i8_scratch: PatFrag<(ops node:$ptr), (anyextload node:$ptr),
[{ if(cast<LoadSDNode>(N)->getAddressSpace() == 77)
return cast<LoadSDNode>(N)->getMemoryVT() == MVT::v16i8;
else
return false; }]>;
def anyextloadv16i16_mem: PatFrag<(ops node:$ptr), (anyextload node:$ptr),
[{ if(cast<LoadSDNode>(N)->getAddressSpace() != 77)
return cast<LoadSDNode>(N)->getMemoryVT() == MVT::v16i16;
else
return false; }]>;
def anyextloadv16i16_scratch: PatFrag<(ops node:$ptr), (anyextload node:$ptr),
[{ if(cast<LoadSDNode>(N)->getAddressSpace() == 77)
return cast<LoadSDNode>(N)->getMemoryVT() == MVT::v16i16;
else
return false; }]>;
def anyextloadv8i8_mem: PatFrag<(ops node:$ptr), (anyextload node:$ptr),
[{ if(cast<LoadSDNode>(N)->getAddressSpace() != 77)
return cast<LoadSDNode>(N)->getMemoryVT() == MVT::v8i8;
else
return false; }]>;
def anyextloadv8i8_scratch: PatFrag<(ops node:$ptr), (anyextload node:$ptr),
[{ if(cast<LoadSDNode>(N)->getAddressSpace() == 77)
return cast<LoadSDNode>(N)->getMemoryVT() == MVT::v8i8;
else
return false; }]>;
def anyextloadv8i16_mem: PatFrag<(ops node:$ptr), (anyextload node:$ptr),
[{ if(cast<LoadSDNode>(N)->getAddressSpace() != 77)
return cast<LoadSDNode>(N)->getMemoryVT() == MVT::v8i16;
else
return false; }]>;
def anyextloadv8i16_scratch: PatFrag<(ops node:$ptr), (anyextload node:$ptr),
[{ if(cast<LoadSDNode>(N)->getAddressSpace() == 77)
return cast<LoadSDNode>(N)->getMemoryVT() == MVT::v8i16;
else
return false; }]>;
def anyextloadv8i32_mem: PatFrag<(ops node:$ptr), (anyextload node:$ptr),
[{ if(cast<LoadSDNode>(N)->getAddressSpace() != 77)
return cast<LoadSDNode>(N)->getMemoryVT() == MVT::v8i32;
else
return false; }]>;
def anyextloadv8i32_scratch: PatFrag<(ops node:$ptr), (anyextload node:$ptr),
[{ if(cast<LoadSDNode>(N)->getAddressSpace() == 77)
return cast<LoadSDNode>(N)->getMemoryVT() == MVT::v8i32;
else
return false; }]>;
//---------------- TRUNCSTORE scalar ----------------//
def truncstorei1_mem : PatFrag<(ops node:$val, node:$ptr),
(truncstore node:$val, node:$ptr), [{
if(cast<StoreSDNode>(N)->getAddressSpace() != 77)
return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i1;
else
return false;}]>;
def truncstorei1_scratch : PatFrag<(ops node:$val, node:$ptr),
(truncstore node:$val, node:$ptr), [{
if(cast<StoreSDNode>(N)->getAddressSpace() == 77)
return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i1;
else
return false;}]>;
def truncstorei8_mem : PatFrag<(ops node:$val, node:$ptr),
(truncstore node:$val, node:$ptr), [{
if(cast<StoreSDNode>(N)->getAddressSpace() != 77)
return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i8;
else
return false;}]>;
def truncstorei8_scratch : PatFrag<(ops node:$val, node:$ptr),
(truncstore node:$val, node:$ptr), [{
if(cast<StoreSDNode>(N)->getAddressSpace() == 77)
return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i8;
else
return false;}]>;
def truncstorei16_mem : PatFrag<(ops node:$val, node:$ptr),
(truncstore node:$val, node:$ptr), [{
if(cast<StoreSDNode>(N)->getAddressSpace() != 77)
return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i16;
else
return false;}]>;
def truncstorei16_scratch : PatFrag<(ops node:$val, node:$ptr),
(truncstore node:$val, node:$ptr), [{
if(cast<StoreSDNode>(N)->getAddressSpace() == 77)
return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i16;
else
return false;}]>;
def truncstorei32_mem : PatFrag<(ops node:$val, node:$ptr),
(truncstore node:$val, node:$ptr), [{
if(cast<StoreSDNode>(N)->getAddressSpace() != 77)
return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i32;
else
return false;}]>;
def truncstorei32_scratch : PatFrag<(ops node:$val, node:$ptr),
(truncstore node:$val, node:$ptr), [{
if(cast<StoreSDNode>(N)->getAddressSpace() == 77)
return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i32;
else
return false;}]>;
//---------------- TRUNCSTORE vector ----------------//
def truncstorev16i8_mem: PatFrag<(ops node:$val, node:$ptr), (truncstore node:$val, node:$ptr),
[{ if(cast<StoreSDNode>(N)->getAddressSpace() != 77)
return cast<StoreSDNode>(N)->getMemoryVT() == MVT::v16i8;
else
return false; }]>;
def truncstorev16i8_scratch: PatFrag<(ops node:$val, node:$ptr), (truncstore node:$val, node:$ptr),
[{ if(cast<StoreSDNode>(N)->getAddressSpace() == 77)
return cast<StoreSDNode>(N)->getMemoryVT() == MVT::v16i8;
else
return false; }]>;
def truncstorev16i16_mem: PatFrag<(ops node:$val, node:$ptr), (truncstore node:$val, node:$ptr),
[{ if(cast<StoreSDNode>(N)->getAddressSpace() != 77)
return cast<StoreSDNode>(N)->getMemoryVT() == MVT::v16i16;
else
return false; }]>;
def truncstorev16i16_scratch: PatFrag<(ops node:$val, node:$ptr), (truncstore node:$val, node:$ptr),
[{ if(cast<StoreSDNode>(N)->getAddressSpace() == 77)
return cast<StoreSDNode>(N)->getMemoryVT() == MVT::v16i16;
else
return false; }]>;
def truncstorev8i8_mem: PatFrag<(ops node:$val, node:$ptr), (truncstore node:$val, node:$ptr),
[{ if(cast<StoreSDNode>(N)->getAddressSpace() != 77)
return cast<StoreSDNode>(N)->getMemoryVT() == MVT::v8i8;
else
return false; }]>;
def truncstorev8i8_scratch: PatFrag<(ops node:$val, node:$ptr), (truncstore node:$val, node:$ptr),
[{ if(cast<StoreSDNode>(N)->getAddressSpace() == 77)
return cast<StoreSDNode>(N)->getMemoryVT() == MVT::v8i8;
else
return false; }]>;
def truncstorev8i16_mem: PatFrag<(ops node:$val, node:$ptr), (truncstore node:$val, node:$ptr),
[{ if(cast<StoreSDNode>(N)->getAddressSpace() != 77)
return cast<StoreSDNode>(N)->getMemoryVT() == MVT::v8i16;
else
return false; }]>;
def truncstorev8i16_scratch: PatFrag<(ops node:$val, node:$ptr), (truncstore node:$val, node:$ptr),
[{ if(cast<StoreSDNode>(N)->getAddressSpace() == 77)
return cast<StoreSDNode>(N)->getMemoryVT() == MVT::v8i16;
else
return false; }]>;
def truncstorev8i32_mem: PatFrag<(ops node:$val, node:$ptr), (truncstore node:$val, node:$ptr),
[{ if(cast<StoreSDNode>(N)->getAddressSpace() != 77)
return cast<StoreSDNode>(N)->getMemoryVT() == MVT::v8i32;
else
return false; }]>;
def truncstorev8i32_scratch: PatFrag<(ops node:$val, node:$ptr), (truncstore node:$val, node:$ptr),
[{ if(cast<StoreSDNode>(N)->getAddressSpace() == 77)
return cast<StoreSDNode>(N)->getMemoryVT() == MVT::v8i32;
else
return false; }]>;
// insertelt SDNode redefinition
def VecInsert : SDTypeProfile<1, 3, [ // vector insert
SDTCisSameAs<0, 1>, SDTCisPtrTy<3>
]>;
def insert_elt : SDNode<"ISD::INSERT_VECTOR_ELT", VecInsert>;
//===----------------------------------------------------------------------===//
// Describe NuPlus Special Registers
//
//
//===----------------------------------------------------------------------===//
class SpReg<bits<6> reg> {
bits<6> Register = reg;
}
def MaskReg : SpReg<59>;
//===----------------------------------------------------------------------===//
// Describe NuPlus scalar or vector instructions
//
// Fmt - 0 if a register is scalar, 1 if vector
//===----------------------------------------------------------------------===//
class Fmt<bit val> {
bit Value = val;
}
def Fmt_S : Fmt<0>;
def Fmt_V : Fmt<1>;
//===----------------------------------------------------------------------===//
// Describe NuPlus instructions format here
//===----------------------------------------------------------------------===//
class InstNuPlus<dag outs, dag ins, string asmstr, list<dag> pattern>
: Instruction {
field bits<32> Inst;
let Namespace = "NuPlus";
let Size = 4;
dag OutOperandList = outs;
dag InOperandList = ins;
let AsmString = asmstr;
let Pattern = pattern;
//let DecoderNamespace = "NuPlus";
field bits<32> SoftFail = 0;
}
//===----------------------------------------------------------------------===//
// Format R instruction class in NuPlus : <00|opcode|rd|rs0|rs1|unused|l|fmt|m|>
// l: if 1, 64 bit mode
// fmt2: FMT value for rd register
// fmt1: FMT value for rs0 register
// fmt0: FMT value for rs1 register
// m: if 1, masked
//
//===----------------------------------------------------------------------===//
class FR<dag outs, dag ins, string asmstr, list<dag> pattern, bits<6> opcode, bit l, Fmt fmt2, Fmt fmt1, Fmt fmt0, bit m>
: InstNuPlus<outs, ins, asmstr, pattern> {
bits <6> dst;
bits <6> src0;
let Inst{31-30} = 0;
let Inst{29-24} = opcode;
let Inst{23-18} = dst;
let Inst{17-12} = src0;
let Inst{5} = 0; //unused
let Inst{4} = l;
let Inst{3} = fmt2.Value;
let Inst{2} = fmt1.Value;
let Inst{1} = fmt0.Value;
let Inst{0} = m;
}
class FR_TwoOp<dag outs, dag ins, string asmstr, list<dag> pattern, bits<6> opcode, bit l, Fmt fmt2, Fmt fmt1, Fmt fmt0, bit m>
: FR<outs, ins, asmstr, pattern, opcode, l, fmt2, fmt1, fmt0, m> {
bits <6> src1;
let Inst{11-6} = src1;
}
class FR_OneOp<dag outs, dag ins, string asmstr, list<dag> pattern, bits<6> opcode, bit l, Fmt fmt2, Fmt fmt1, Fmt fmt0, bit m>
: FR<outs, ins, asmstr, pattern, opcode, l, fmt2, fmt1, fmt0, m> {
let Inst{11-6} = 0;
}
class FR_TwoOp_Masked<dag outs, dag ins, string asmstr, list<dag> pattern, bits<6> opcode, bit l, Fmt fmt2, Fmt fmt1, Fmt fmt0>
: FR_TwoOp<outs, ins, asmstr, pattern, opcode, l, fmt2, fmt1, fmt0, 1> {
let Uses = [MR_REG];
}
class FR_TwoOp_Unmasked<dag outs, dag ins, string asmstr, list<dag> pattern, bits<6> opcode, bit l, Fmt fmt2, Fmt fmt1, Fmt fmt0>
: FR_TwoOp<outs, ins, asmstr, pattern, opcode, l, fmt2, fmt1, fmt0, 0> {
}
class FR_OneOp_Masked<dag outs, dag ins, string asmstr, list<dag> pattern, bits<6> opcode, bit l, Fmt fmt2, Fmt fmt1>
: FR_OneOp<outs, ins, asmstr, pattern, opcode, l, fmt2, fmt1, Fmt_S, 1> {
let Uses = [MR_REG];
}
class FR_OneOp_Unmasked<dag outs, dag ins, string asmstr, list<dag> pattern, bits<6> opcode, bit l, Fmt fmt2, Fmt fmt1>
: FR_OneOp<outs, ins, asmstr, pattern, opcode, l, fmt2, fmt1, Fmt_S, 0> {
}
class FR_TwoOp_Masked_32<dag outs, dag ins, string asmstr, list<dag> pattern, bits<6> opcode, Fmt fmt2, Fmt fmt1, Fmt fmt0>
: FR_TwoOp_Masked<outs, ins, asmstr, pattern, opcode, 0, fmt2, fmt1, fmt0> {
}
class FR_TwoOp_Masked_64<dag outs, dag ins, string asmstr, list<dag> pattern, bits<6> opcode, Fmt fmt2, Fmt fmt1, Fmt fmt0>
: FR_TwoOp_Masked<outs, ins, asmstr, pattern, opcode, 1, fmt2, fmt1, fmt0> {
}
class FR_TwoOp_Unmasked_32<dag outs, dag ins, string asmstr, list<dag> pattern, bits<6> opcode, Fmt fmt2, Fmt fmt1, Fmt fmt0>
: FR_TwoOp_Unmasked<outs, ins, asmstr, pattern, opcode, 0, fmt2, fmt1, fmt0> {
}
class FR_TwoOp_Unmasked_64<dag outs, dag ins, string asmstr, list<dag> pattern, bits<6> opcode, Fmt fmt2, Fmt fmt1, Fmt fmt0>
: FR_TwoOp_Unmasked<outs, ins, asmstr, pattern, opcode, 1, fmt2, fmt1, fmt0> {
}
class FR_OneOp_Masked_32<dag outs, dag ins, string asmstr, list<dag> pattern, bits<6> opcode, Fmt fmt2, Fmt fmt1>
: FR_OneOp_Masked<outs, ins, asmstr, pattern, opcode, 0, fmt2, fmt1> {
}
class FR_OneOp_Masked_64<dag outs, dag ins, string asmstr, list<dag> pattern, bits<6> opcode, Fmt fmt2, Fmt fmt1>
: FR_OneOp_Masked<outs, ins, asmstr, pattern, opcode, 1, fmt2, fmt1> {
}
class FR_OneOp_Unmasked_32<dag outs, dag ins, string asmstr, list<dag> pattern, bits<6> opcode, Fmt fmt2, Fmt fmt1>
: FR_OneOp_Unmasked<outs, ins, asmstr, pattern, opcode, 0, fmt2, fmt1> {
}
class FR_OneOp_Unmasked_64<dag outs, dag ins, string asmstr, list<dag> pattern, bits<6> opcode, Fmt fmt2, Fmt fmt1>
: FR_OneOp_Unmasked<outs, ins, asmstr, pattern, opcode, 1, fmt2, fmt1> {
}
//===----------------------------------------------------------------------===//
// Format I instruction class in NuPlus : <010|opcode|rd|rs|imm|fmt|m|>
// fmt1: FMT value for rd register
// fmt0: FMT value for rs register
// m: if 1 masked
//===----------------------------------------------------------------------===//
class FI<dag outs, dag ins, string asmstr, list<dag> pattern, bits<5> opcode, Fmt fmt1, Fmt fmt0, bit m>
: InstNuPlus<outs, ins, asmstr, pattern> {
bits <6> dst;
bits <9> imm;
let Inst{31-29} = 0b010;
let Inst{28-24} = opcode;
let Inst{23-18} = dst;
let Inst{11-3} = imm;
let Inst{2} = fmt1.Value;
let Inst{1} = fmt0.Value;
let Inst{0} = m;
}
class FI_OneOp<dag outs, dag ins, string asmstr, list<dag> pattern, bits<5> opcode, Fmt fmt1, Fmt fmt0, bit m> : FI<outs, ins, asmstr, pattern, opcode, fmt1, fmt0, m> {
bits <6> src;
let Inst{17-12} = src;
}
class FI_NoOp<dag outs, dag ins, string asmstr, list<dag> pattern, bits<5> opcode, Fmt fmt1> : FI<outs, ins, asmstr, pattern, opcode, fmt1, Fmt_S, 0> {
let Inst{17-12} = 0;
}
class FI_OneOp_Masked<dag outs, dag ins, string asmstr, list<dag> pattern, bits<5> opcode, Fmt fmt1, Fmt fmt0> : FI_OneOp<outs, ins, asmstr, pattern, opcode, fmt1, fmt0, 1> {
let Uses = [MR_REG];
}
class FI_OneOp_Unmasked<dag outs, dag ins, string asmstr, list<dag> pattern, bits<5> opcode, Fmt fmt1, Fmt fmt0> : FI_OneOp<outs, ins, asmstr, pattern, opcode, fmt1, fmt0, 0> {
}
//===----------------------------------------------------------------------===//
// Format MOVEI instruction class in NuPlus : <01100|opcode|rd|imm|fmt|m|>
//===----------------------------------------------------------------------===//
class FMOVEI<dag outs, dag ins, string asmstr, list<dag> pattern, bits<3> opcode, Fmt fmt, bit m>
: InstNuPlus<outs, ins, asmstr, pattern> {
bits <6> dst;
bits <16> imm;
let Inst{31-27} = 0b01100;
let Inst{26-24} = opcode;
let Inst{23-18} = dst;
let Inst{17-2} = imm;
let Inst{1} = fmt.Value;
let Inst{0} = m;
}
//===----------------------------------------------------------------------===//
// Format M instruction class in NuPlus : <10|opcode|rd/rs|rptr|off|l|s|m|>
//===----------------------------------------------------------------------===//
class FM<dag outs, dag ins, string asmstr, list<dag> pattern, bits<6> opcode, bit l, bit s, bit m>
: InstNuPlus<outs, ins, asmstr, pattern> {
bits <6> dstsrc;
bits <15> addr; //base address and offset encoded on the same 15 bits value (check encodeMemoryOpValue)
let Inst{31-30} = 0b10;
let Inst{29-24} = opcode;
let Inst{23-18} = dstsrc;
let Inst{17-12} = addr{5-0};
let Inst{11-3} = addr{14-6};
let Inst{2} = l;
let Inst{1} = s;
let Inst{0} = m;
}
class FM_Unmasked<dag outs, dag ins, string asmstr, list<dag> pattern, bits<6> opcode, bit l, bit s>
: FM<outs, ins, asmstr, pattern, opcode, l, s, 0> {
}
class FM_Masked<dag outs, dag ins, string asmstr, list<dag> pattern, bits<6> opcode, bit l, bit s>
: FM<outs, ins, asmstr, pattern, opcode, l, s, 1> {
let Uses = [MR_REG];
}
class FM_Unmasked_Mainmem<dag outs, dag ins, string asmstr, list<dag> pattern, bits<6> opcode, bit l>
: FM_Unmasked<outs, ins, asmstr, pattern, opcode, l, 0> {
}
class FM_Unmasked_Scratchpad<dag outs, dag ins, string asmstr, list<dag> pattern, bits<6> opcode, bit l>
: FM_Unmasked<outs, ins, asmstr, pattern, opcode, l, 1> {
}
class FM_Masked_Mainmem<dag outs, dag ins, string asmstr, list<dag> pattern, bits<6> opcode, bit l>
: FM_Masked<outs, ins, asmstr, pattern, opcode, l, 0> {
}
class FM_Masked_Scratchpad<dag outs, dag ins, string asmstr, list<dag> pattern, bits<6> opcode, bit l>
: FM_Masked<outs, ins, asmstr, pattern, opcode, l, 1> {
}
class FM_Unmasked_Mainmem_32<dag outs, dag ins, string asmstr, list<dag> pattern, bits<6> opcode>
: FM_Unmasked_Mainmem<outs, ins, asmstr, pattern, opcode, 0> {
}
class FM_Unmasked_Scratchpad_32<dag outs, dag ins, string asmstr, list<dag> pattern, bits<6> opcode>
: FM_Unmasked_Scratchpad<outs, ins, asmstr, pattern, opcode, 0> {
}
class FM_Masked_Mainmem_32<dag outs, dag ins, string asmstr, list<dag> pattern, bits<6> opcode>
: FM_Masked_Mainmem<outs, ins, asmstr, pattern, opcode, 0> {
}
class FM_Masked_Scratchpad_32<dag outs, dag ins, string asmstr, list<dag> pattern, bits<6> opcode>
: FM_Masked_Scratchpad<outs, ins, asmstr, pattern, opcode, 0> {
}
class FM_Unmasked_Mainmem_64<dag outs, dag ins, string asmstr, list<dag> pattern, bits<6> opcode>
: FM_Unmasked_Mainmem<outs, ins, asmstr, pattern, opcode, 1> {
}
class FM_Unmasked_Scratchpad_64<dag outs, dag ins, string asmstr, list<dag> pattern, bits<6> opcode>
: FM_Unmasked_Scratchpad<outs, ins, asmstr, pattern, opcode, 1> {
}
class FM_Masked_Mainmem_64<dag outs, dag ins, string asmstr, list<dag> pattern, bits<6> opcode>
: FM_Masked_Mainmem<outs, ins, asmstr, pattern, opcode, 1> {
}
class FM_Masked_Scratchpad_64<dag outs, dag ins, string asmstr, list<dag> pattern, bits<6> opcode>
: FM_Masked_Scratchpad<outs, ins, asmstr, pattern, opcode, 1> {
}
//===----------------------------------------------------------------------===//
// Format J/BR instruction class in NuPlus
// FJR: <0111|type(0/1)|opcode|rd|imm|>
// FJ: <0111|type(0/1)|opcode|imm|>
//===----------------------------------------------------------------------===//
class FJ_ALL<dag outs, dag ins, string asmstr, list<dag> pattern, bits<3> opcode>
: InstNuPlus<outs, ins, asmstr, pattern> {
let Inst{31-28} = 0b0111;
let Inst{26-24} = opcode;
let isBranch = 1;
}
class FJR<dag outs, dag ins, string asmstr, list<dag> pattern, bits<3> opcode>
: FJ_ALL<outs, ins, asmstr, pattern, opcode> {
bits <6> cond;
bits <18> addr;
let Inst{27} = 0;
let Inst{23-18} = cond;
let Inst{17-0} = addr;
}
class FJ<dag outs, dag ins, string asmstr, list<dag> pattern, bits<3> opcode>
: FJ_ALL<outs, ins, asmstr, pattern, opcode> {
bits <24> addr;
let Inst{27} = 1;
let Inst{23-0} = addr;
}
//===----------------------------------------------------------------------===//
// Format C instruction class in NuPlus
// FC: <01101|opcode|rs0|rs1|unused|>
//===----------------------------------------------------------------------===//
class FC<dag outs, dag ins, string asmstr, list<dag> pattern, bits<3> opcode>
: InstNuPlus<outs, ins, asmstr, pattern> {
bits <6> src0;
bits <6> src1;
let Inst{31-27} = 0b01101;
let Inst{26-24} = opcode;
let Inst{23-18} = src0;
let Inst{17-12} = src1;
let Inst{11-0} = 0; //unused
}
//===----------------------------------------------------------------------===//
// A set of multiclasses is used to handle Vector/Scalar combinations
// SS: Scalar = Op Scalar
// VV: Vector = Op Vector
// SI: Vector = Op Immediate
// SSS: Scalar = Scalar Op Scalar
// VVS: Vector = Vector Op Scalar
// VVV: Vector = Vector Op Vector
// SVV: Scalar = Vector Op Vector
// SSI: Scalar = Vector Op Immediate
// VVI: Scalar = Vector Op Immediate
//===----------------------------------------------------------------------===//
multiclass FArithInt_TwoOp<string operator, SDNode OpNode, bits<6> opcode> {
// FR - SSS - 32 bit integer
def SSS_32 : FR_TwoOp_Unmasked_32<
(outs GPR32:$dst),
(ins GPR32:$src0, GPR32:$src1),
operator # "_i32 $dst, $src0, $src1",
[(set i32:$dst, (OpNode i32:$src0, i32:$src1))],
opcode,
Fmt_S,
Fmt_S,
Fmt_S>;
// FR - VVS unmasked - 32 bit integer
def VVS_U_32 : FR_TwoOp_Unmasked_32<
(outs VR512W:$dst),
(ins VR512W:$src0, GPR32:$src1),
operator # "_i32 $dst, $src0, $src1",
[(set v16i32:$dst, (OpNode v16i32:$src0, (v16i32 (splat i32:$src1))))],
opcode,
Fmt_V,
Fmt_V,
Fmt_S>;
// FR - VVV unmasked - 32 bit integer
def VVV_U_32 : FR_TwoOp_Unmasked_32<
(outs VR512W:$dst),
(ins VR512W:$src0, VR512W:$src1),
operator # "_i32 $dst, $src0, $src1",
[(set v16i32:$dst, (OpNode v16i32:$src0, v16i32:$src1))],
opcode,
Fmt_V,
Fmt_V,
Fmt_V>;
let Constraints = "$dst = $oldvalue" in {
// FR - VVS masked - 32 bit integer
def VVS_M_32 : FR_TwoOp_Masked_32<
(outs VR512W:$dst),
(ins VR512W:$src0, GPR32:$src1, VR512W:$oldvalue),
operator # "_i32.m $dst, $src0, $src1",
[(set v16i32:$dst, (int_nuplus_vector_mixi32 (OpNode v16i32:$src0, (v16i32 (splat i32:$src1))),
v16i32:$oldvalue))],
opcode,
Fmt_V,
Fmt_V,
Fmt_S>;
// FR - VVV masked - 32 bit integer
def VVV_M_32 : FR_TwoOp_Masked_32<
(outs VR512W:$dst),
(ins VR512W:$src0, VR512W:$src1, VR512W:$oldvalue),
operator # "_i32.m $dst, $src0, $src1",
[(set v16i32:$dst, (int_nuplus_vector_mixi32 (OpNode v16i32:$src0, v16i32:$src1),
v16i32:$oldvalue))],
opcode,
Fmt_V,
Fmt_V,
Fmt_V>;
}
// FI - SSI
def SSI : FI_OneOp_Unmasked<
(outs GPR32:$dst),
(ins GPR32:$src, SIMM9OP:$imm),
operator # "i $dst, $src, $imm",
[(set i32:$dst, (OpNode i32:$src, (i32 simm9:$imm)))],
opcode{4-0},
Fmt_S,
Fmt_S>;
// FI - VVI unmasked
def VVI_U : FI_OneOp_Unmasked<
(outs VR512W:$dst),
(ins VR512W:$src, SIMM9OP:$imm),
operator # "i $dst, $src, $imm",
[(set v16i32:$dst, (OpNode v16i32:$src, (v16i32 (splat simm9:$imm))))],
opcode{4-0},
Fmt_V,
Fmt_V>;
// FI - VVI masked
let Constraints = "$dst = $oldvalue" in {
def VVI_M : FI_OneOp_Masked<
(outs VR512W:$dst),
(ins VR512W:$src, SIMM9OP:$imm, VR512W:$oldvalue),
operator # "i.m $dst, $src, $imm",
[(set v16i32:$dst, (int_nuplus_vector_mixi32 (OpNode v16i32:$src, (v16i32 (splat simm9:$imm))), v16i32:$oldvalue))],
opcode{4-0},
Fmt_V,
Fmt_V>;
}
}
multiclass FArithInt_OneOp<string operator, SDNode OpNode, bits<6> opcode> {
// FR - SS - 32 bit integer
def SS_32 : FR_OneOp_Unmasked_32<
(outs GPR32:$dst),
(ins GPR32:$src0),
operator # "_i32 $dst, $src0",
[(set i32:$dst, (OpNode i32:$src0))],
opcode,
Fmt_S,
Fmt_S>;
// FR - VV unmasked - 32 bit integer
def VV_U_32 : FR_OneOp_Unmasked_32<
(outs VR512W:$dst),
(ins VR512W:$src0),
operator # "_i32 $dst, $src0",
[(set v16i32:$dst, (OpNode v16i32:$src0))],
opcode,
Fmt_V,
Fmt_V>;
let Constraints = "$dst = $oldvalue" in {
// FR - VV masked - 32 bit integer
def VV_M_32 : FR_OneOp_Masked_32<
(outs VR512W:$dst),
(ins VR512W:$src0, VR512W:$oldvalue),
operator # "_i32.m $dst, $src0",
[(set v16i32:$dst, (int_nuplus_vector_mixi32 (OpNode v16i32:$src0),
v16i32:$oldvalue))],
opcode,
Fmt_V,
Fmt_V>;
}
}
// per la shift rotate
multiclass FSRInt_TwoOp<string operator, SDNode OpNode, bits<6> opcode> {
// FR - SSS - 32 bit integer
def SSS_32 : FR_TwoOp_Unmasked_32<
(outs GPR32:$dst),
(ins GPR32:$src0, GPR32:$src1),
operator # "_i32 $dst, $src0, $src1",
[(set i32:$dst, (OpNode i32:$src0, i32:$src1))],
opcode,
Fmt_S,
Fmt_S,
Fmt_S>;
// FR - VVS unmasked - 32 bit integer
def VVS_U_32 : FR_TwoOp_Unmasked_32<
(outs VR512W:$dst),
(ins VR512W:$src0, GPR32:$src1),
operator # "_i32 $dst, $src0, $src1",
[(set v16i32:$dst, (OpNode v16i32:$src0, (v16i32 (splat i32:$src1))))],
opcode,
Fmt_V,
Fmt_V,
Fmt_S>;
// FR - VVV unmasked - 32 bit integer
def VVV_U_32 : FR_TwoOp_Unmasked_32<
(outs VR512W:$dst),
(ins VR512W:$src0, VR512W:$src1),
operator # "_i32 $dst, $src0, $src1",
[(set v16i32:$dst, (OpNode v16i32:$src0, v16i32:$src1))],
opcode,
Fmt_V,
Fmt_V,
Fmt_V>;
let Constraints = "$dst = $oldvalue" in {
// FR - VVS masked - 32 bit integer
def VVS_M_32 : FR_TwoOp_Masked_32<
(outs VR512W:$dst),
(ins VR512W:$src0, GPR32:$src1, VR512W:$oldvalue),
operator # "_i32.m $dst, $src0, $src1",
[(set v16i32:$dst, (int_nuplus_vector_mixi32 (OpNode v16i32:$src0, (v16i32 (splat i32:$src1))),
v16i32:$oldvalue))],
opcode,
Fmt_V,
Fmt_V,
Fmt_S>;
// FR - VVV masked - 32 bit integer
def VVV_M_32 : FR_TwoOp_Masked_32<
(outs VR512W:$dst),
(ins VR512W:$src0, VR512W:$src1, VR512W:$oldvalue),
operator # "_i32.m $dst, $src0, $src1",
[(set v16i32:$dst, (int_nuplus_vector_mixi32 (OpNode v16i32:$src0, v16i32:$src1),
v16i32:$oldvalue))],
opcode,
Fmt_V,
Fmt_V,
Fmt_V>;
}
// FI - SSI
def SSI : FI_OneOp_Unmasked<
(outs GPR32:$dst),
(ins GPR32:$src, SIMM9OP:$imm),
operator # "i $dst, $src, $imm",
[(set i32:$dst, (OpNode i32:$src, (i32 simm9:$imm)))],
opcode{4-0},
Fmt_S,
Fmt_S>;
// FI - VVI unmasked
def VVI_U : FI_OneOp_Unmasked<
(outs VR512W:$dst),
(ins VR512W:$src, SIMM9OP:$imm),
operator # "i $dst, $src, $imm",
[(set v16i32:$dst, (OpNode v16i32:$src, (v16i32 (splat simm9:$imm))))],
opcode{4-0},
Fmt_V,
Fmt_V>;
// FI - VVI masked
let Constraints = "$dst = $oldvalue" in {
def VVI_M : FI_OneOp_Masked<
(outs VR512W:$dst),
(ins VR512W:$src, SIMM9OP:$imm, VR512W:$oldvalue),
operator # "i.m $dst, $src, $imm",
[(set v16i32:$dst, (int_nuplus_vector_mixi32 (OpNode v16i32:$src, (v16i32 (splat simm9:$imm))), v16i32:$oldvalue))],
opcode{4-0},
Fmt_V,
Fmt_V>;
}
}
multiclass FArithFloat_TwoOp<string operator, SDNode OpNode, bits<6> opcode> {
// FR - SSS - 32 bit float
def SSS_32 : FR_TwoOp_Unmasked_32<
(outs GPR32:$dst),
(ins GPR32:$src0, GPR32:$src1),
operator # "_f32 $dst, $src0, $src1",
[(set f32:$dst, (OpNode f32:$src0, f32:$src1))],
opcode,
Fmt_S,
Fmt_S,
Fmt_S>;
// FR - VVS unmasked - 32 bit float
def VVS_U_32 : FR_TwoOp_Unmasked_32<
(outs VR512W:$dst),
(ins VR512W:$src0, GPR32:$src1),
operator # "_f32 $dst, $src0, $src1",
[(set v16f32:$dst, (OpNode v16f32:$src0, (splat f32:$src1)))],
opcode,
Fmt_V,
Fmt_V,
Fmt_S>;
// FR - VVV unmasked - 32 bit float
def VVV_U_32 : FR_TwoOp_Unmasked_32<
(outs VR512W:$dst),
(ins VR512W:$src0, VR512W:$src1),
operator # "_f32 $dst, $src0, $src1",
[(set v16f32:$dst, (OpNode v16f32:$src0, v16f32:$src1))],
opcode,
Fmt_V,
Fmt_V,
Fmt_V>;
let Constraints = "$dst = $oldvalue" in {
// FR - VVS masked - 32 bit float
def VVS_M_32 : FR_TwoOp_Masked_32<
(outs VR512W:$dst),
(ins VR512W:$src0, GPR32:$src1, VR512W:$oldvalue),
operator # "_f32.m $dst, $src0, $src1",
[(set v16f32:$dst, (int_nuplus_vector_mixf32 (OpNode v16f32:$src0, (splat f32:$src1)),
v16f32:$oldvalue))],
opcode,
Fmt_V,
Fmt_V,
Fmt_S>;
// FR - VVV masked - 32 bit float
def VVV_M_32 : FR_TwoOp_Masked_32<
(outs VR512W:$dst),
(ins VR512W:$src0, VR512W:$src1, VR512W:$oldvalue),
operator # "_f32.m $dst, $src0, $src1",
[(set v16f32:$dst, (int_nuplus_vector_mixf32 (OpNode v16f32:$src0, v16f32:$src1),
v16f32:$oldvalue))],
opcode,
Fmt_V,
Fmt_V,
Fmt_V>;
}
}
multiclass FArithFloat_OneOp<string operator, SDNode OpNode, bits<6> opcode> {
// FR - SS - 32 bit float
def SS_32 : FR_OneOp_Unmasked_32<
(outs GPR32:$dst),
(ins GPR32:$src0),
operator # "_f32 $dst, $src0",
[(set f32:$dst, (OpNode f32:$src0))],
opcode,
Fmt_S,
Fmt_S>;
// FR - VV unmasked - 32 bit float
def VV_U_32 : FR_OneOp_Unmasked_32<
(outs VR512W:$dst),
(ins VR512W:$src0),
operator # "_f32 $dst, $src0",
[(set v16f32:$dst, (OpNode v16f32:$src0))],
opcode,
Fmt_V,
Fmt_V>;
let Constraints = "$dst = $oldvalue" in {
// FR - VV masked - 32 bit float
def VV_M_32 : FR_OneOp_Masked_32<
(outs VR512W:$dst),
(ins VR512W:$src0, VR512W:$oldvalue),
operator # "_f32.m $dst, $src0",
[(set v16f32:$dst, (int_nuplus_vector_mixi32 (OpNode v16i32:$src0),
v16i32:$oldvalue))],
opcode,
Fmt_V,
Fmt_V>;
}
}
// Condition codes defined in include/llvm/CodeGen/ISDOpcodes.h
// VS and VV comparisons are handled through intrinsics
multiclass FCompInt<string operator, CondCode condition,
bits<6> opcode, Intrinsic vectorIntr32> {
// FR - SSS - 32 bit integer
def SSS_32 : FR_TwoOp_Unmasked_32<
(outs GPR32:$dst),
(ins GPR32:$src0, GPR32:$src1),
operator # "_i32 $dst, $src0, $src1",
[(set i32:$dst, (setcc i32:$src0, i32:$src1, condition))],
opcode,
Fmt_S,
Fmt_S,
Fmt_S>;
// FR - SVS unmasked - 32 bit integer
def SVS_U_32 : FR_TwoOp_Unmasked_32<
(outs GPR32:$dst),
(ins VR512W:$src0, GPR32:$src1),
operator # "_i32 $dst, $src0, $src1",
[(set i32:$dst, (vectorIntr32 v16i32:$src0, (splat i32:$src1)))],
opcode,
Fmt_S,
Fmt_V,
Fmt_S>;
// FR - SVV unmasked - 32 bit integer
def SVV_U_32 : FR_TwoOp_Unmasked_32<
(outs GPR32:$dst),
(ins VR512W:$src0, VR512W:$src1),
operator # "_i32 $dst, $src0, $src1",
[(set i32:$dst, (vectorIntr32 v16i32:$src0, v16i32:$src1))],
opcode,
Fmt_S,
Fmt_V,
Fmt_V>;
// FI - SSI
def SSI : FI_OneOp_Unmasked<
(outs GPR32:$dst),
(ins GPR32:$src, SIMM9OP:$imm),
operator # "i $dst, $src, $imm",
[(set i32:$dst, (setcc i32:$src, simm9:$imm, condition))],
opcode{4-0},
Fmt_S,
Fmt_S>;
// FI - SVI unmasked
def SVI : FI_OneOp_Unmasked<
(outs GPR32:$dst),
(ins VR512W:$src, SIMM9OP:$imm),
operator # "i $dst, $src, $imm",
[(set i32:$dst, (vectorIntr32 v16i32:$src, (splat simm9:$imm)))],
opcode{4-0},
Fmt_S,
Fmt_V>;
}
multiclass FCompFloat<string operator, SDNode OpNode,
bits<6> opcode, Intrinsic vectorIntr32> {
// FR - SSS - 32 bit float
def SSS_32 : FR_TwoOp_Unmasked_32<
(outs GPR32:$dst),
(ins GPR32:$src0, GPR32:$src1),
operator # "_f32 $dst, $src0, $src1",
[(set i32:$dst, (OpNode f32:$src0, f32:$src1))],
opcode,
Fmt_S,
Fmt_S,
Fmt_S>;
// FR - SVS unmasked - 32 bit float
def SVS_U_32 : FR_TwoOp_Unmasked_32<
(outs GPR32:$dst),
(ins VR512W:$src0, GPR32:$src1),
operator # "_f32 $dst, $src0, $src1",
[(set i32:$dst, (vectorIntr32 v16f32:$src0, (splat f32:$src1)))],
opcode,
Fmt_S,
Fmt_V,
Fmt_S>;
// FR - SVV unmasked - 32 bit float
def SVV_U_32 : FR_TwoOp_Unmasked_32<
(outs GPR32:$dst),
(ins VR512W:$src0, VR512W:$src1),
operator # "_f32 $dst, $src0, $src1",
[(set i32:$dst, (vectorIntr32 v16f32:$src0, v16f32:$src1))],
opcode,
Fmt_S,
Fmt_V,
Fmt_V>;
}
multiclass FSext_32<string operator, ValueType vt,
bits<6> opcode, ValueType vt_v> {
// FR - SS
def SS : FR_OneOp_Unmasked_32<
(outs GPR32:$dst),
(ins GPR32:$src0),
operator # "_i32 $dst, $src0",
[(set i32:$dst, (sext_inreg i32:$src0, vt))],
opcode,
Fmt_S,
Fmt_S>;
// FR - VV unmasked
def VV_U : FR_OneOp_Unmasked_32<
(outs VR512W:$dst),
(ins VR512W:$src0),
operator # "_i32 $dst, $src0",
[(set v16i32:$dst, (sext vt_v:$src0))],
opcode,
Fmt_V,
Fmt_V>;
let Constraints = "$dst = $oldvalue" in {
// FR - VV masked
def VV_M : FR_OneOp_Masked_32<
(outs VR512W:$dst),
(ins VR512W:$src0, VR512W:$oldvalue),
operator # "_i32.m $dst, $src0",
[(set v16i32:$dst, (int_nuplus_vector_mixi32 (sext vt_v:$src0),
v16i32:$oldvalue))],
opcode,
Fmt_V,
Fmt_V>;
}
}
//===----------------------------------------------------------------------===//
// A set of multiclasses used to handle Loads and Stores
//===----------------------------------------------------------------------===//
// Scalar LOAD
multiclass FMLoadScalar_32<string suffix, PatFrag op_mem, PatFrag op_scratch, bits<6> opcode> {
def _Mainmem : FM_Unmasked_Mainmem<
(outs GPR32:$dstsrc),
(ins MEMri:$addr),
"load32" # suffix # " $dstsrc, $addr",
[(set i32:$dstsrc, (i32 (op_mem ADDRri:$addr)))],
opcode,
0>;
def _Scratchpad : FM_Unmasked_Scratchpad<
(outs GPR32:$dstsrc),
(ins MEMri:$addr),
"load32" # suffix # "_scratchpad $dstsrc, $addr",
[(set i32:$dstsrc, (i32 (op_scratch ADDRri:$addr)))],
opcode,
0>;
}
// Scalar STORE
multiclass FMStoreScalar_32<string suffix, PatFrag op_mem, PatFrag op_scratch, bits<6> opcode> {
def _Mainmem : FM_Unmasked_Mainmem<
(outs),
(ins GPR32:$dstsrc, MEMri:$addr),
"store32" # suffix # " $dstsrc, $addr",
[(op_mem i32:$dstsrc, ADDRri:$addr)],
opcode,
0>;
def _Scratchpad : FM_Unmasked_Scratchpad<
(outs),
(ins GPR32:$dstsrc, MEMri:$addr),
"store32" # suffix # "_scratchpad $dstsrc, $addr",
[(op_scratch i32:$dstsrc, ADDRri:$addr)],
opcode,
0>{
let hasSideEffects = 1;
let mayStore = 1;
}
}
// Vector LOAD
multiclass FMLoadVector_32<string suffix, PatFrag op_Umem, PatFrag op_Uscratch,
Intrinsic op_Mmem, Intrinsic op_Mscratch, bits<6> opcode> {
// main memory - unmasked - 32
def Mainmem_U : FM_Unmasked_Mainmem_32<
(outs VR512W:$dstsrc),
(ins MEMri:$addr),
"load" # suffix # " $dstsrc, $addr",
[(set v16i32:$dstsrc, (op_Umem ADDRri:$addr))],
opcode>;
// scratchpad memory - unmasked - 32
def Scratchpad_U : FM_Unmasked_Scratchpad_32<
(outs VR512W:$dstsrc),
(ins MEMri:$addr),
"load" # suffix # "_scratchpad $dstsrc, $addr",
[(set v16i32:$dstsrc, (op_Uscratch ADDRri:$addr))],
opcode>;
// main memory - masked - 32
def Mainmem_M : FM_Masked_Mainmem_32<
(outs VR512W:$dstsrc),
(ins MEMri:$addr),
"load" # suffix # ".m $dstsrc, $addr",
[(set v16i32:$dstsrc, (op_Mmem ADDRri:$addr))],
opcode>;
// scratchpad memory - masked - 32
def Scratchpad_M : FM_Masked_Scratchpad_32<
(outs VR512W:$dstsrc),
(ins MEMri:$addr),
"load" # suffix # "_scratchpad.m $dstsrc, $addr",
[(set v16i32:$dstsrc, (op_Mscratch ADDRri:$addr))],
opcode>;
}
// Vector GATHER
multiclass FMGather_32<string suffix, Intrinsic op_Uscratch,
Intrinsic op_Mscratch, bits<6> opcode> {
// scratchpad memory - unmasked - 32
def Scratchpad_U : FM_Unmasked_Scratchpad_32<
(outs VR512W:$dstsrc),
(ins V16MEMri:$addr),
"loadg" # suffix # "_scratchpad $dstsrc, $addr",
[(set v16i32:$dstsrc, (op_Uscratch V16ADDRri:$addr))],
opcode>;
// scratchpad memory - masked - 32
def Scratchpad_M : FM_Masked_Scratchpad_32<
(outs VR512W:$dstsrc),
(ins V16MEMri:$addr),
"loadg" # suffix # "_scratchpad.m $dstsrc, $addr",
[(set v16i32:$dstsrc, (op_Mscratch V16ADDRri:$addr))],
opcode>;
}
// Vector STORE
multiclass FMStoreVector_32<string suffix, PatFrag op_Umem, PatFrag op_Uscratch,
Intrinsic op_Mmem, Intrinsic op_Mscratch, bits<6> opcode> {
// main memory - unmasked - 32
def Mainmem_U : FM_Unmasked_Mainmem_32<
(outs),
(ins VR512W:$dstsrc, MEMri:$addr),
"store" # suffix # " $dstsrc, $addr",
[(op_Umem v16i32:$dstsrc, ADDRri:$addr)],
opcode>;
// scratchpad memory - unmasked - 32
def Scratchpad_U : FM_Unmasked_Scratchpad_32<
(outs),
(ins VR512W:$dstsrc, MEMri:$addr),
"store" # suffix # "_scratchpad $dstsrc, $addr",
[(op_Uscratch v16i32:$dstsrc, ADDRri:$addr)],
opcode>;
// main memory - masked - 32
def Mainmem_M : FM_Masked_Mainmem_32<
(outs),
(ins VR512W:$dstsrc, MEMri:$addr),
"store" # suffix # ".m $dstsrc, $addr",
[(op_Mmem ADDRri:$addr, v16i32:$dstsrc)],
opcode>;
// scratchpad memory - masked - 32
def Scratchpad_M : FM_Masked_Scratchpad_32<
(outs),
(ins VR512W:$dstsrc, MEMri:$addr),
"store" # suffix # "_scratchpad.m $dstsrc, $addr",
[(op_Mscratch ADDRri:$addr, v16i32:$dstsrc)],
opcode>;
}
// Vector SCATTER
multiclass FMScatter_32<string suffix, Intrinsic op_Uscratch,
Intrinsic op_Mscratch, bits<6> opcode> {
// scratchpad memory - unmasked - 32
def Scratchpad_U : FM_Unmasked_Scratchpad_32<
(outs),
(ins VR512W:$dstsrc, V16MEMri:$addr),
"stores" # suffix # "_scratchpad $dstsrc, $addr",
[(op_Uscratch V16ADDRri:$addr, v16i32:$dstsrc)],
opcode>;
// scratchpad memory - masked - 32
def Scratchpad_M : FM_Masked_Scratchpad_32<
(outs),
(ins VR512W:$dstsrc, V16MEMri:$addr),
"stores" # suffix # "_scratchpad.m $dstsrc, $addr",
[(op_Mscratch V16ADDRri:$addr, v16i32:$dstsrc)],
opcode>;
}
//===----------------------------------------------------------------------===//
// A set of multiclasses is used to handle Vector/Scalar
// Masked/Unmasked combinations
// MOVEI operations
//===----------------------------------------------------------------------===//
multiclass FMOVEI_ALL<string operator, bits<3> opcode> {
// SI
def SI : FMOVEI<
(outs GPR32:$dst),
(ins SIMM16OP:$imm),
operator # " $dst, $imm",
[],//[(set i32:$dst, simm16:$imm)],
opcode,
Fmt_S,
0>;
// VI unmasked
def VI_U : FMOVEI<
(outs VR512W:$dst),
(ins SIMM16OP:$imm),
operator # " $dst, $imm",
[],//[(set v16i32:$dst, (splat simm16:$imm))],
opcode,
Fmt_V,
0>;
let Constraints = "$dst = $oldvalue", Uses = [MR_REG] in {
// VI masked
def VI_M : FMOVEI<
(outs VR512W:$dst),
(ins SIMM16OP:$imm, VR512W:$oldvalue),
operator # ".m $dst, $imm",
[(set v16i32:$dst, (int_nuplus_vector_mixi32 (splat simm16:$imm), v16i32:$oldvalue))],
opcode,
Fmt_V,
1>;
}
}
//===----------------------------------------------------------------------===//
// Instruction class used to read/write special register through intrinics
// All these instructions are implemented using a move instruction
//===----------------------------------------------------------------------===//
let DecoderNamespace = "Read_SPR" in {
class READ_SPR<SpReg reg, string operator, Intrinsic read_intr> :
FR_OneOp_Unmasked_32<
(outs GPR32:$dst),
(ins),
operator # " $dst",
[(set i32:$dst, (read_intr))],
32,
Fmt_S,
Fmt_S>
{
bits<6> dst;
let Inst{29-24} = 32; // opcode: move
let Inst{23-18} = dst;
let Inst{17-12} = reg.Register;
let Inst{11-6} = 0;
}
}
let DecoderNamespace = "Write_SPR" in {
class WRITE_SPR<SpReg reg, string operator, Intrinsic read_intr> :
FR_OneOp_Unmasked_32<
(outs),
(ins GPR32:$src),
operator # " $src",
[(read_intr i32:$src)],
32,
Fmt_S,
Fmt_S>
{
bits<6> src;
let Inst{29-24} = 32; // opcode: move
let Inst{23-18} = reg.Register;
let Inst{17-12} = src;
let Inst{11-6} = 0;
}
}
//===----------------------------------------------------------------------===//
// Pseudo-instructions for alternate assembly syntax (never used by codegen).
// These are aliases that require C++ handling to convert to the target
// instruction, while InstAliases can be handled directly by tblgen.
//===----------------------------------------------------------------------===//
class AsmPseudoInst<dag outs, dag ins, string asm>
: InstNuPlus<outs, ins, asm, []> {
let isPseudo = 1;
}
class Pseudo<dag outs, dag ins, list<dag> pattern>
: InstNuPlus<outs, ins, "Pseudo", pattern>
{
let isCodeGenOnly = 1;
let isPseudo = 1;
let Inst{31-0} = 0;
}
multiclass AtomicBinary<SDNode OpNode>
{
def R : Pseudo<
(outs GPR32:$dst),
(ins GPR32:$ptr, GPR32:$amt),
[(set i32:$dst, (OpNode GPR32:$ptr, GPR32:$amt))]>;
def I : Pseudo<
(outs GPR32:$dst),
(ins GPR32:$ptr, SIMM9OP:$amt),
[(set i32:$dst, (OpNode GPR32:$ptr, simm9:$amt))]>;
}