mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 20:51:52 +01:00
[VE] Clean SDNodeXForm stuff
Summary: Gather definitions of SDNodeXForm and change them to call C functions instead of copying C expressions in td files. Doing this solved some bugs in mimm detections. Differential Revision: https://reviews.llvm.org/D81132
This commit is contained in:
parent
42f802871d
commit
37d0f82ab6
@ -126,6 +126,34 @@ inline static const char *VERDToString(VERD::RoundingMode R) {
|
||||
}
|
||||
}
|
||||
|
||||
// MImm - Special immediate value of sequential bit stream of 0 or 1.
|
||||
// See VEInstrInfo.td for details.
|
||||
inline static bool isMImmVal(uint64_t Val) {
|
||||
if (Val == 0) {
|
||||
// (0)1 is 0
|
||||
return true;
|
||||
}
|
||||
if (isMask_64(Val)) {
|
||||
// (m)0 patterns
|
||||
return true;
|
||||
}
|
||||
// (m)1 patterns
|
||||
return (Val & (1UL << 63)) && isShiftedMask_64(Val);
|
||||
}
|
||||
|
||||
inline static bool isMImm32Val(uint32_t Val) {
|
||||
if (Val == 0) {
|
||||
// (0)1 is 0
|
||||
return true;
|
||||
}
|
||||
if (isMask_32(Val)) {
|
||||
// (m)0 patterns
|
||||
return true;
|
||||
}
|
||||
// (m)1 patterns
|
||||
return (Val & (1 << 31)) && isShiftedMask_32(Val);
|
||||
}
|
||||
|
||||
inline unsigned M0(unsigned Val) { return Val + 64; }
|
||||
inline unsigned M1(unsigned Val) { return Val; }
|
||||
|
||||
|
@ -23,6 +23,105 @@ using namespace llvm;
|
||||
// Instruction Selector Implementation
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
/// Convert a DAG integer condition code to a VE ICC condition.
|
||||
inline static VECC::CondCode intCondCode2Icc(ISD::CondCode CC) {
|
||||
switch (CC) {
|
||||
default:
|
||||
llvm_unreachable("Unknown integer condition code!");
|
||||
case ISD::SETEQ:
|
||||
return VECC::CC_IEQ;
|
||||
case ISD::SETNE:
|
||||
return VECC::CC_INE;
|
||||
case ISD::SETLT:
|
||||
return VECC::CC_IL;
|
||||
case ISD::SETGT:
|
||||
return VECC::CC_IG;
|
||||
case ISD::SETLE:
|
||||
return VECC::CC_ILE;
|
||||
case ISD::SETGE:
|
||||
return VECC::CC_IGE;
|
||||
case ISD::SETULT:
|
||||
return VECC::CC_IL;
|
||||
case ISD::SETULE:
|
||||
return VECC::CC_ILE;
|
||||
case ISD::SETUGT:
|
||||
return VECC::CC_IG;
|
||||
case ISD::SETUGE:
|
||||
return VECC::CC_IGE;
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert a DAG floating point condition code to a VE FCC condition.
|
||||
inline static VECC::CondCode fpCondCode2Fcc(ISD::CondCode CC) {
|
||||
switch (CC) {
|
||||
default:
|
||||
llvm_unreachable("Unknown fp condition code!");
|
||||
case ISD::SETFALSE:
|
||||
return VECC::CC_AF;
|
||||
case ISD::SETEQ:
|
||||
case ISD::SETOEQ:
|
||||
return VECC::CC_EQ;
|
||||
case ISD::SETNE:
|
||||
case ISD::SETONE:
|
||||
return VECC::CC_NE;
|
||||
case ISD::SETLT:
|
||||
case ISD::SETOLT:
|
||||
return VECC::CC_L;
|
||||
case ISD::SETGT:
|
||||
case ISD::SETOGT:
|
||||
return VECC::CC_G;
|
||||
case ISD::SETLE:
|
||||
case ISD::SETOLE:
|
||||
return VECC::CC_LE;
|
||||
case ISD::SETGE:
|
||||
case ISD::SETOGE:
|
||||
return VECC::CC_GE;
|
||||
case ISD::SETO:
|
||||
return VECC::CC_NUM;
|
||||
case ISD::SETUO:
|
||||
return VECC::CC_NAN;
|
||||
case ISD::SETUEQ:
|
||||
return VECC::CC_EQNAN;
|
||||
case ISD::SETUNE:
|
||||
return VECC::CC_NENAN;
|
||||
case ISD::SETULT:
|
||||
return VECC::CC_LNAN;
|
||||
case ISD::SETUGT:
|
||||
return VECC::CC_GNAN;
|
||||
case ISD::SETULE:
|
||||
return VECC::CC_LENAN;
|
||||
case ISD::SETUGE:
|
||||
return VECC::CC_GENAN;
|
||||
case ISD::SETTRUE:
|
||||
return VECC::CC_AT;
|
||||
}
|
||||
}
|
||||
|
||||
/// getImmVal - get immediate representation of integer value
|
||||
inline static uint64_t getImmVal(const ConstantSDNode *N) {
|
||||
return N->getSExtValue();
|
||||
}
|
||||
|
||||
/// getFpImmVal - get immediate representation of floating point value
|
||||
inline static uint64_t getFpImmVal(const ConstantFPSDNode *N) {
|
||||
const APInt &Imm = N->getValueAPF().bitcastToAPInt();
|
||||
uint64_t Val = Imm.getZExtValue();
|
||||
if (Imm.getBitWidth() == 32) {
|
||||
// Immediate value of float place places at higher bits on VE.
|
||||
Val <<= 32;
|
||||
}
|
||||
return Val;
|
||||
}
|
||||
|
||||
/// convMImmVal - Convert a mimm integer immediate value to target immediate.
|
||||
inline static uint64_t convMImmVal(uint64_t Val) {
|
||||
if (Val == 0)
|
||||
return 0; // (0)1
|
||||
if (Val & (1UL << 63))
|
||||
return countLeadingOnes(Val); // (m)1
|
||||
return countLeadingZeros(Val) | 0x40; // (m)0
|
||||
}
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
/// VEDAGToDAGISel - VE specific code to select VE machine
|
||||
/// instructions for SelectionDAG operations.
|
||||
|
@ -16,6 +16,85 @@
|
||||
|
||||
include "VEInstrFormats.td"
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Helper functions to retrieve target constants.
|
||||
//
|
||||
// VE instructions have a space to hold following immediates
|
||||
// $sy has 7 bits to represent simm7, uimm7, simm7fp, or uimm7fp.
|
||||
// $sz also has 7 bits to represent mimm or mimmfp.
|
||||
// $disp has 32 bits to represent simm32.
|
||||
//
|
||||
// The mimm is a special immediate value of sequential bit stream of 0 or 1.
|
||||
// `(m)0`: Represents 0 sequence then 1 sequence like 0b00...0011...11,
|
||||
// where `m` is equal to the number of leading zeros.
|
||||
// `(m)1`: Represents 1 sequence then 0 sequence like 0b11...1100...00,
|
||||
// where `m` is equal to the number of leading ones.
|
||||
// Each bit of mimm's 7 bits is used like below:
|
||||
// bit 6 : If `(m)0`, this bit is 1. Otherwise, this bit is 0.
|
||||
// bit 5-0: Represents the m (0-63).
|
||||
// Use `!add(m, 64)` to generates an immediate value in pattern matchings.
|
||||
//
|
||||
// The floating point immediate value is not something like compacted value.
|
||||
// It is simple integer representation, so it works rarely.
|
||||
// e.g. 0.0 (0x00000000) or -2.0 (0xC0000000=(2)1).
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
def LO7 : SDNodeXForm<imm, [{
|
||||
return CurDAG->getTargetConstant(SignExtend32(N->getSExtValue(), 7),
|
||||
SDLoc(N), MVT::i32);
|
||||
}]>;
|
||||
def MIMM : SDNodeXForm<imm, [{
|
||||
return CurDAG->getTargetConstant(convMImmVal(getImmVal(N)),
|
||||
SDLoc(N), MVT::i32);
|
||||
}]>;
|
||||
def LO32 : SDNodeXForm<imm, [{
|
||||
return CurDAG->getTargetConstant(Lo_32(N->getZExtValue()),
|
||||
SDLoc(N), MVT::i32);
|
||||
}]>;
|
||||
def HI32 : SDNodeXForm<imm, [{
|
||||
// Transformation function: shift the immediate value down into the low bits.
|
||||
return CurDAG->getTargetConstant(Hi_32(N->getZExtValue()),
|
||||
SDLoc(N), MVT::i32);
|
||||
}]>;
|
||||
|
||||
def LO7FP : SDNodeXForm<fpimm, [{
|
||||
uint64_t Val = getFpImmVal(N);
|
||||
return CurDAG->getTargetConstant(SignExtend32(Val, 7), SDLoc(N), MVT::i32);
|
||||
}]>;
|
||||
def MIMMFP : SDNodeXForm<fpimm, [{
|
||||
return CurDAG->getTargetConstant(convMImmVal(getFpImmVal(N)),
|
||||
SDLoc(N), MVT::i32);
|
||||
}]>;
|
||||
def LOFP32 : SDNodeXForm<fpimm, [{
|
||||
return CurDAG->getTargetConstant(Lo_32(getFpImmVal(N) & 0xffffffff),
|
||||
SDLoc(N), MVT::i32);
|
||||
}]>;
|
||||
def HIFP32 : SDNodeXForm<fpimm, [{
|
||||
return CurDAG->getTargetConstant(Hi_32(getFpImmVal(N)), SDLoc(N), MVT::i32);
|
||||
}]>;
|
||||
|
||||
def icond2cc : SDNodeXForm<cond, [{
|
||||
VECC::CondCode VECC = intCondCode2Icc(N->get());
|
||||
return CurDAG->getTargetConstant(VECC, SDLoc(N), MVT::i32);
|
||||
}]>;
|
||||
|
||||
def icond2ccSwap : SDNodeXForm<cond, [{
|
||||
ISD::CondCode CC = getSetCCSwappedOperands(N->get());
|
||||
VECC::CondCode VECC = intCondCode2Icc(CC);
|
||||
return CurDAG->getTargetConstant(VECC, SDLoc(N), MVT::i32);
|
||||
}]>;
|
||||
|
||||
def fcond2cc : SDNodeXForm<cond, [{
|
||||
VECC::CondCode VECC = fpCondCode2Fcc(N->get());
|
||||
return CurDAG->getTargetConstant(VECC, SDLoc(N), MVT::i32);
|
||||
}]>;
|
||||
|
||||
def fcond2ccSwap : SDNodeXForm<cond, [{
|
||||
ISD::CondCode CC = getSetCCSwappedOperands(N->get());
|
||||
VECC::CondCode VECC = fpCondCode2Fcc(CC);
|
||||
return CurDAG->getTargetConstant(VECC, SDLoc(N), MVT::i32);
|
||||
}]>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Feature predicates.
|
||||
//===----------------------------------------------------------------------===//
|
||||
@ -37,90 +116,48 @@ def uimm7 : Operand<i32>, PatLeaf<(imm), [{
|
||||
return isUInt<7>(N->getZExtValue()); }]>;
|
||||
|
||||
// simm7 - Generic immediate value.
|
||||
def LO7 : SDNodeXForm<imm, [{
|
||||
return CurDAG->getTargetConstant(SignExtend32(N->getSExtValue(), 7),
|
||||
SDLoc(N), MVT::i32);
|
||||
}]>;
|
||||
def simm7 : Operand<i32>, PatLeaf<(imm), [{
|
||||
return isInt<7>(N->getSExtValue()); }], LO7> {
|
||||
let DecoderMethod = "DecodeSIMM7";
|
||||
}
|
||||
|
||||
// mimm - Special immediate value of sequential bit stream of 0 or 1.
|
||||
// `(m)0`: Represents 0b00...0011...11 pattern where the number of leading
|
||||
// zeros equal to m.
|
||||
// `(m)1`: Represents 0b11...1100...00 pattern where the number of leading
|
||||
// ones equal to m.
|
||||
// The immediate value of mimm operands:
|
||||
// bit 6 : If `(m)0`, 1. Otherwise, 0.
|
||||
// bit 5-0: Represents 0-63.
|
||||
// Use `!add(m, 64)` to generates an immediate value in pattern matching.
|
||||
def MIMM : SDNodeXForm<imm, [{
|
||||
uint64_t Val = N->getZExtValue();
|
||||
if (isMask_64(Val))
|
||||
Val = countLeadingZeros(Val) | 0x40;
|
||||
else
|
||||
Val = countLeadingOnes(Val);
|
||||
return CurDAG->getTargetConstant(Val, SDLoc(N), MVT::i32);
|
||||
}]>;
|
||||
def mimm : Operand<i32>, PatLeaf<(imm), [{
|
||||
return isMask_64(N->getZExtValue()) ||
|
||||
((N->getZExtValue() & (1UL << 63)) &&
|
||||
isShiftedMask_64(N->getZExtValue())); }], MIMM> {
|
||||
return isMImmVal(getImmVal(N)); }], MIMM> {
|
||||
let PrintMethod = "printMImmOperand";
|
||||
}
|
||||
|
||||
// simm7fp - Generic fp immediate value.
|
||||
def LO7FP : SDNodeXForm<fpimm, [{
|
||||
// Get a integer immediate from fpimm
|
||||
const APInt& imm = N->getValueAPF().bitcastToAPInt();
|
||||
uint64_t val = imm.getSExtValue();
|
||||
if (imm.getBitWidth() == 32)
|
||||
val <<= 32; // Immediate value of float place at higher bits on VE.
|
||||
return CurDAG->getTargetConstant(SignExtend32(val, 7), SDLoc(N), MVT::i32);
|
||||
}]>;
|
||||
def simm7fp : Operand<i32>, PatLeaf<(fpimm), [{
|
||||
const APInt& imm = N->getValueAPF().bitcastToAPInt();
|
||||
uint64_t val = imm.getSExtValue();
|
||||
if (imm.getBitWidth() == 32)
|
||||
val <<= 32; // Immediate value of float place at higher bits on VE.
|
||||
return isInt<7>(val);
|
||||
return isInt<7>(getFpImmVal(N));
|
||||
}], LO7FP> {
|
||||
let DecoderMethod = "DecodeSIMM7";
|
||||
}
|
||||
|
||||
// mimm - Special fp immediate value of sequential bit stream of 0 or 1.
|
||||
def MIMMFP : SDNodeXForm<fpimm, [{
|
||||
const APInt& Imm = N->getValueAPF().bitcastToAPInt();
|
||||
uint64_t Val = Imm.getSExtValue();
|
||||
bool M0Flag = isMask_64(Val);
|
||||
if (Imm.getBitWidth() == 32)
|
||||
Val <<= 32; // Immediate value of float place at higher bits on VE.
|
||||
if (M0Flag) {
|
||||
// bit 6 : If `(m)0`, 1. Otherwise, 0.
|
||||
Val = countLeadingZeros(Val) | 0x40;
|
||||
} else
|
||||
Val = countLeadingOnes(Val);
|
||||
return CurDAG->getTargetConstant(Val, SDLoc(N), MVT::i32);
|
||||
}]>;
|
||||
// mimmfp - Special fp immediate value of sequential bit stream of 0 or 1.
|
||||
def mimmfp : Operand<i32>, PatLeaf<(fpimm), [{
|
||||
const APInt& Imm = N->getValueAPF().bitcastToAPInt();
|
||||
uint64_t Val = Imm.getSExtValue();
|
||||
return isMask_64(Val) ||
|
||||
((Val & (1UL << 63)) && isShiftedMask_64(Val)); }], MIMMFP> {
|
||||
return isMImmVal(getFpImmVal(N)); }], MIMMFP> {
|
||||
let PrintMethod = "printMImmOperand";
|
||||
}
|
||||
|
||||
// mimmfp32 - 32 bit width mimmfp
|
||||
// Float value places at higher bits, so ignore lower 32 bits.
|
||||
def mimmfp32 : Operand<i32>, PatLeaf<(fpimm), [{
|
||||
return isMImm32Val(getFpImmVal(N) >> 32); }], MIMMFP> {
|
||||
let PrintMethod = "printMImmOperand";
|
||||
}
|
||||
|
||||
// other generic patterns to use in pattern matchings
|
||||
def simm32 : PatLeaf<(imm), [{ return isInt<32>(N->getSExtValue()); }]>;
|
||||
def uimm32 : PatLeaf<(imm), [{ return isUInt<32>(N->getZExtValue()); }]>;
|
||||
def lomsbzero : PatLeaf<(imm), [{ return (N->getZExtValue() & 0x80000000)
|
||||
== 0; }]>;
|
||||
def lozero : PatLeaf<(imm), [{ return (N->getZExtValue() & 0xffffffff)
|
||||
== 0; }]>;
|
||||
def fplomsbzero : PatLeaf<(fpimm), [{ return (N->getValueAPF().bitcastToAPInt()
|
||||
.getZExtValue() & 0x80000000) == 0; }]>;
|
||||
def fplozero : PatLeaf<(fpimm), [{ return (N->getValueAPF().bitcastToAPInt()
|
||||
.getZExtValue() & 0xffffffff) == 0; }]>;
|
||||
def fplomsbzero : PatLeaf<(fpimm), [{ return (getFpImmVal(N) & 0x80000000)
|
||||
== 0; }]>;
|
||||
def fplozero : PatLeaf<(fpimm), [{ return (getFpImmVal(N) & 0xffffffff)
|
||||
== 0; }]>;
|
||||
|
||||
def CCSIOp : PatLeaf<(cond), [{
|
||||
switch (N->get()) {
|
||||
@ -142,127 +179,6 @@ def CCUIOp : PatLeaf<(cond), [{
|
||||
}
|
||||
}]>;
|
||||
|
||||
def LOFP32 : SDNodeXForm<fpimm, [{
|
||||
// Get a integer immediate from fpimm
|
||||
const APInt& imm = N->getValueAPF().bitcastToAPInt();
|
||||
return CurDAG->getTargetConstant(Lo_32(imm.getZExtValue() & 0xffffffff),
|
||||
SDLoc(N), MVT::i64);
|
||||
}]>;
|
||||
|
||||
def HIFP32 : SDNodeXForm<fpimm, [{
|
||||
// Get a integer immediate from fpimm
|
||||
const APInt& imm = N->getValueAPF().bitcastToAPInt();
|
||||
return CurDAG->getTargetConstant(Hi_32(imm.getZExtValue()),
|
||||
SDLoc(N), MVT::i64);
|
||||
}]>;
|
||||
|
||||
def LO32 : SDNodeXForm<imm, [{
|
||||
return CurDAG->getTargetConstant(Lo_32(N->getZExtValue()),
|
||||
SDLoc(N), MVT::i64);
|
||||
}]>;
|
||||
|
||||
def HI32 : SDNodeXForm<imm, [{
|
||||
// Transformation function: shift the immediate value down into the low bits.
|
||||
return CurDAG->getTargetConstant(Hi_32(N->getZExtValue()),
|
||||
SDLoc(N), MVT::i32);
|
||||
}]>;
|
||||
|
||||
def icond2cc : SDNodeXForm<cond, [{
|
||||
VECC::CondCode cc;
|
||||
switch (N->get()) {
|
||||
default: llvm_unreachable("Unknown integer condition code!");
|
||||
case ISD::SETEQ: cc = VECC::CC_IEQ; break;
|
||||
case ISD::SETNE: cc = VECC::CC_INE; break;
|
||||
case ISD::SETLT: cc = VECC::CC_IL; break;
|
||||
case ISD::SETGT: cc = VECC::CC_IG; break;
|
||||
case ISD::SETLE: cc = VECC::CC_ILE; break;
|
||||
case ISD::SETGE: cc = VECC::CC_IGE; break;
|
||||
case ISD::SETULT: cc = VECC::CC_IL; break;
|
||||
case ISD::SETULE: cc = VECC::CC_ILE; break;
|
||||
case ISD::SETUGT: cc = VECC::CC_IG; break;
|
||||
case ISD::SETUGE: cc = VECC::CC_IGE; break;
|
||||
}
|
||||
return CurDAG->getTargetConstant(cc, SDLoc(N), MVT::i32);
|
||||
}]>;
|
||||
|
||||
def icond2ccSwap : SDNodeXForm<cond, [{
|
||||
VECC::CondCode cc;
|
||||
switch (N->get()) {
|
||||
default: llvm_unreachable("Unknown integer condition code!");
|
||||
case ISD::SETEQ: cc = VECC::CC_IEQ; break;
|
||||
case ISD::SETNE: cc = VECC::CC_INE; break;
|
||||
case ISD::SETLT: cc = VECC::CC_IG; break;
|
||||
case ISD::SETGT: cc = VECC::CC_IL; break;
|
||||
case ISD::SETLE: cc = VECC::CC_IGE; break;
|
||||
case ISD::SETGE: cc = VECC::CC_ILE; break;
|
||||
case ISD::SETULT: cc = VECC::CC_IG; break;
|
||||
case ISD::SETULE: cc = VECC::CC_IGE; break;
|
||||
case ISD::SETUGT: cc = VECC::CC_IL; break;
|
||||
case ISD::SETUGE: cc = VECC::CC_ILE; break;
|
||||
}
|
||||
return CurDAG->getTargetConstant(cc, SDLoc(N), MVT::i32);
|
||||
}]>;
|
||||
|
||||
def fcond2cc : SDNodeXForm<cond, [{
|
||||
VECC::CondCode cc;
|
||||
switch (N->get()) {
|
||||
default: llvm_unreachable("Unknown float condition code!");
|
||||
case ISD::SETFALSE: cc = VECC::CC_AF; break;
|
||||
case ISD::SETEQ:
|
||||
case ISD::SETOEQ: cc = VECC::CC_EQ; break;
|
||||
case ISD::SETNE:
|
||||
case ISD::SETONE: cc = VECC::CC_NE; break;
|
||||
case ISD::SETLT:
|
||||
case ISD::SETOLT: cc = VECC::CC_L; break;
|
||||
case ISD::SETGT:
|
||||
case ISD::SETOGT: cc = VECC::CC_G; break;
|
||||
case ISD::SETLE:
|
||||
case ISD::SETOLE: cc = VECC::CC_LE; break;
|
||||
case ISD::SETGE:
|
||||
case ISD::SETOGE: cc = VECC::CC_GE; break;
|
||||
case ISD::SETO: cc = VECC::CC_NUM; break;
|
||||
case ISD::SETUO: cc = VECC::CC_NAN; break;
|
||||
case ISD::SETUEQ: cc = VECC::CC_EQNAN; break;
|
||||
case ISD::SETUNE: cc = VECC::CC_NENAN; break;
|
||||
case ISD::SETULT: cc = VECC::CC_LNAN; break;
|
||||
case ISD::SETUGT: cc = VECC::CC_GNAN; break;
|
||||
case ISD::SETULE: cc = VECC::CC_LENAN; break;
|
||||
case ISD::SETUGE: cc = VECC::CC_GENAN; break;
|
||||
case ISD::SETTRUE: cc = VECC::CC_AT; break;
|
||||
}
|
||||
return CurDAG->getTargetConstant(cc, SDLoc(N), MVT::i32);
|
||||
}]>;
|
||||
|
||||
def fcond2ccSwap : SDNodeXForm<cond, [{
|
||||
VECC::CondCode cc;
|
||||
switch (N->get()) {
|
||||
default: llvm_unreachable("Unknown float condition code!");
|
||||
case ISD::SETFALSE: cc = VECC::CC_AF; break;
|
||||
case ISD::SETEQ:
|
||||
case ISD::SETOEQ: cc = VECC::CC_EQ; break;
|
||||
case ISD::SETNE:
|
||||
case ISD::SETONE: cc = VECC::CC_NE; break;
|
||||
case ISD::SETLT:
|
||||
case ISD::SETOLT: cc = VECC::CC_G; break;
|
||||
case ISD::SETGT:
|
||||
case ISD::SETOGT: cc = VECC::CC_L; break;
|
||||
case ISD::SETLE:
|
||||
case ISD::SETOLE: cc = VECC::CC_GE; break;
|
||||
case ISD::SETGE:
|
||||
case ISD::SETOGE: cc = VECC::CC_LE; break;
|
||||
case ISD::SETO: cc = VECC::CC_NUM; break;
|
||||
case ISD::SETUO: cc = VECC::CC_NAN; break;
|
||||
case ISD::SETUEQ: cc = VECC::CC_EQNAN; break;
|
||||
case ISD::SETUNE: cc = VECC::CC_NENAN; break;
|
||||
case ISD::SETULT: cc = VECC::CC_GNAN; break;
|
||||
case ISD::SETUGT: cc = VECC::CC_LNAN; break;
|
||||
case ISD::SETULE: cc = VECC::CC_GENAN; break;
|
||||
case ISD::SETUGE: cc = VECC::CC_LENAN; break;
|
||||
case ISD::SETTRUE: cc = VECC::CC_AT; break;
|
||||
}
|
||||
return CurDAG->getTargetConstant(cc, SDLoc(N), MVT::i32);
|
||||
}]>;
|
||||
|
||||
// Addressing modes.
|
||||
// SX-Aurora has following fields.
|
||||
// sz: register or 0
|
||||
@ -1013,30 +929,39 @@ def : Pat<(i32 (srl i32:$src, i32:$val)),
|
||||
|
||||
// Section 8.7.1 - FAD (Floating Add)
|
||||
defm FADDD : RRFm<"fadd.d", 0x4C, I64, f64, fadd>;
|
||||
let cx = 1 in defm FADDS : RRFm<"fadd.s", 0x4C, F32, f32, fadd>;
|
||||
let cx = 1 in
|
||||
defm FADDS : RRFm<"fadd.s", 0x4C, F32, f32, fadd, simm7fp, mimmfp32>;
|
||||
|
||||
// Section 8.7.2 - FSB (Floating Subtract)
|
||||
defm FSUBD : RRFm<"fsub.d", 0x5C, I64, f64, fsub>;
|
||||
let cx = 1 in defm FSUBS : RRFm<"fsub.s", 0x5C, F32, f32, fsub>;
|
||||
let cx = 1 in
|
||||
defm FSUBS : RRFm<"fsub.s", 0x5C, F32, f32, fsub, simm7fp, mimmfp32>;
|
||||
|
||||
// Section 8.7.3 - FMP (Floating Multiply)
|
||||
defm FMULD : RRFm<"fmul.d", 0x4D, I64, f64, fmul>;
|
||||
let cx = 1 in defm FMULS : RRFm<"fmul.s", 0x4D, F32, f32, fmul>;
|
||||
let cx = 1 in
|
||||
defm FMULS : RRFm<"fmul.s", 0x4D, F32, f32, fmul, simm7fp, mimmfp32>;
|
||||
|
||||
// Section 8.7.4 - FDV (Floating Divide)
|
||||
defm FDIVD : RRFm<"fdiv.d", 0x5D, I64, f64, fdiv>;
|
||||
let cx = 1 in defm FDIVS : RRFm<"fdiv.s", 0x5D, F32, f32, fdiv>;
|
||||
let cx = 1 in
|
||||
defm FDIVS : RRFm<"fdiv.s", 0x5D, F32, f32, fdiv, simm7fp, mimmfp32>;
|
||||
|
||||
// Section 8.7.5 - FCP (Floating Compare)
|
||||
defm FCMPD : RRFm<"fcmp.d", 0x7E, I64, f64>;
|
||||
let cx = 1 in defm FCMPS : RRFm<"fcmp.s", 0x7E, F32, f32>;
|
||||
let cx = 1 in
|
||||
defm FCMPS : RRFm<"fcmp.s", 0x7E, F32, f32, null_frag, simm7fp, mimmfp32>;
|
||||
|
||||
// Section 8.7.6 - CMS (Compare and Select Maximum/Minimum Single)
|
||||
// cx: double/float, cw: max/min
|
||||
defm FMAXD : RRFm<"fmax.d", 0x3E, I64, f64>;
|
||||
let cx = 1 in defm FMAXS : RRFm<"fmax.s", 0x3E, F32, f32>;
|
||||
let cw = 1 in defm FMIND : RRFm<"fmin.d", 0x3E, I64, f64>;
|
||||
let cw = 1, cx = 1 in defm FMINS : RRFm<"fmin.s", 0x3E, F32, f32>;
|
||||
let cw = 0, cx = 0 in
|
||||
defm FMAXD : RRFm<"fmax.d", 0x3E, I64, f64, fmaxnum>;
|
||||
let cw = 0, cx = 1 in
|
||||
defm FMAXS : RRFm<"fmax.s", 0x3E, F32, f32, fmaxnum, simm7fp, mimmfp32>;
|
||||
let cw = 1, cx = 0 in
|
||||
defm FMIND : RRFm<"fmin.d", 0x3E, I64, f64, fminnum>;
|
||||
let cw = 1, cx = 1 in
|
||||
defm FMINS : RRFm<"fmin.s", 0x3E, F32, f32, fminnum, simm7fp, mimmfp32>;
|
||||
|
||||
// Section 8.7.7 - FAQ (Floating Add Quadruple)
|
||||
// Section 8.7.8 - FSQ (Floating Subtract Quadruple)
|
||||
@ -1161,7 +1086,7 @@ def : Pat<(i64 imm:$val),
|
||||
|
||||
// floating point
|
||||
def : Pat<(f32 fpimm:$val),
|
||||
(EXTRACT_SUBREG (LEASLzii 0, 0, (LOFP32 $val)), sub_f32)>;
|
||||
(EXTRACT_SUBREG (LEASLzii 0, 0, (HIFP32 $val)), sub_f32)>;
|
||||
def : Pat<(f64 fplozero:$val),
|
||||
(LEASLzii 0, 0, (HIFP32 $val))>;
|
||||
def : Pat<(f64 fplomsbzero:$val),
|
||||
|
@ -159,8 +159,7 @@ define i64 @func21(i64 %0) {
|
||||
define i32 @func25(i32 %0) {
|
||||
; CHECK-LABEL: func25:
|
||||
; CHECK: .LBB{{[0-9]+}}_2:
|
||||
; CHECK-NEXT: lea %s1, -2147483648
|
||||
; CHECK-NEXT: xor %s0, %s0, %s1
|
||||
; CHECK-NEXT: xor %s0, %s0, (33)1
|
||||
; CHECK-NEXT: or %s11, 0, %s9
|
||||
%2 = xor i32 %0, -2147483648
|
||||
ret i32 %2
|
||||
|
@ -63,7 +63,7 @@ define double @func8(double %a) {
|
||||
define float @fmuls_ir(float %a) {
|
||||
; CHECK-LABEL: fmuls_ir:
|
||||
; CHECK: .LBB{{[0-9]+}}_2:
|
||||
; CHECK-NEXT: fmul.s %s0, 0, %s0
|
||||
; CHECK-NEXT: fmul.s %s0, %s0, (0)1
|
||||
; CHECK-NEXT: or %s11, 0, %s9
|
||||
%r = fmul float 0.e+00, %a
|
||||
ret float %r
|
||||
|
@ -159,8 +159,7 @@ define i64 @func21(i64 %0, i64 %1) {
|
||||
define i32 @func25(i32 %0, i32 %1) {
|
||||
; CHECK-LABEL: func25:
|
||||
; CHECK: .LBB{{[0-9]+}}_2:
|
||||
; CHECK-NEXT: lea %s1, -2147483648
|
||||
; CHECK-NEXT: xor %s0, %s0, %s1
|
||||
; CHECK-NEXT: xor %s0, %s0, (33)1
|
||||
; CHECK-NEXT: or %s11, 0, %s9
|
||||
%3 = xor i32 %0, -2147483648
|
||||
ret i32 %3
|
||||
|
Loading…
x
Reference in New Issue
Block a user