mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-09-27 00:21:03 +00:00
Conditional branches and comparisons
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@75947 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -22,12 +22,26 @@ namespace llvm {
|
|||||||
class FunctionPass;
|
class FunctionPass;
|
||||||
class raw_ostream;
|
class raw_ostream;
|
||||||
|
|
||||||
|
namespace SystemZCC {
|
||||||
|
// SystemZ specific condition code. These correspond to SYSTEMZ_*_COND in
|
||||||
|
// SystemZInstrInfo.td. They must be kept in synch.
|
||||||
|
enum CondCodes {
|
||||||
|
E = 0,
|
||||||
|
NE = 1,
|
||||||
|
H = 2,
|
||||||
|
L = 3,
|
||||||
|
HE = 4,
|
||||||
|
LE = 5
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
FunctionPass *createSystemZISelDag(SystemZTargetMachine &TM,
|
FunctionPass *createSystemZISelDag(SystemZTargetMachine &TM,
|
||||||
CodeGenOpt::Level OptLevel);
|
CodeGenOpt::Level OptLevel);
|
||||||
FunctionPass *createSystemZCodePrinterPass(raw_ostream &o,
|
FunctionPass *createSystemZCodePrinterPass(raw_ostream &o,
|
||||||
SystemZTargetMachine &tm,
|
SystemZTargetMachine &tm,
|
||||||
CodeGenOpt::Level OptLevel,
|
CodeGenOpt::Level OptLevel,
|
||||||
bool verbose);
|
bool verbose);
|
||||||
|
|
||||||
} // end namespace llvm;
|
} // end namespace llvm;
|
||||||
|
|
||||||
// Defines symbolic names for SystemZ registers.
|
// Defines symbolic names for SystemZ registers.
|
||||||
|
@@ -57,6 +57,10 @@ SystemZTargetLowering::SystemZTargetLowering(SystemZTargetMachine &tm) :
|
|||||||
setSchedulingPreference(SchedulingForLatency);
|
setSchedulingPreference(SchedulingForLatency);
|
||||||
|
|
||||||
setOperationAction(ISD::RET, MVT::Other, Custom);
|
setOperationAction(ISD::RET, MVT::Other, Custom);
|
||||||
|
|
||||||
|
setOperationAction(ISD::BRCOND, MVT::Other, Expand);
|
||||||
|
setOperationAction(ISD::BR_CC, MVT::i32, Custom);
|
||||||
|
setOperationAction(ISD::BR_CC, MVT::i64, Custom);
|
||||||
}
|
}
|
||||||
|
|
||||||
SDValue SystemZTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) {
|
SDValue SystemZTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) {
|
||||||
@@ -64,6 +68,7 @@ SDValue SystemZTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) {
|
|||||||
case ISD::FORMAL_ARGUMENTS: return LowerFORMAL_ARGUMENTS(Op, DAG);
|
case ISD::FORMAL_ARGUMENTS: return LowerFORMAL_ARGUMENTS(Op, DAG);
|
||||||
case ISD::RET: return LowerRET(Op, DAG);
|
case ISD::RET: return LowerRET(Op, DAG);
|
||||||
case ISD::CALL: return LowerCALL(Op, DAG);
|
case ISD::CALL: return LowerCALL(Op, DAG);
|
||||||
|
case ISD::BR_CC: return LowerBR_CC(Op, DAG);
|
||||||
default:
|
default:
|
||||||
assert(0 && "unimplemented operand");
|
assert(0 && "unimplemented operand");
|
||||||
return SDValue();
|
return SDValue();
|
||||||
@@ -406,10 +411,75 @@ SDValue SystemZTargetLowering::LowerRET(SDValue Op, SelectionDAG &DAG) {
|
|||||||
return DAG.getNode(SystemZISD::RET_FLAG, dl, MVT::Other, Chain);
|
return DAG.getNode(SystemZISD::RET_FLAG, dl, MVT::Other, Chain);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SDValue SystemZTargetLowering::EmitCmp(SDValue LHS, SDValue RHS,
|
||||||
|
ISD::CondCode CC, SDValue &SystemZCC,
|
||||||
|
SelectionDAG &DAG) {
|
||||||
|
assert(!LHS.getValueType().isFloatingPoint() && "We don't handle FP yet");
|
||||||
|
|
||||||
|
// FIXME: Emit a test if RHS is zero
|
||||||
|
|
||||||
|
bool isUnsigned = false;
|
||||||
|
SystemZCC::CondCodes TCC;
|
||||||
|
switch (CC) {
|
||||||
|
default: assert(0 && "Invalid integer condition!");
|
||||||
|
case ISD::SETEQ:
|
||||||
|
TCC = SystemZCC::E;
|
||||||
|
break;
|
||||||
|
case ISD::SETNE:
|
||||||
|
TCC = SystemZCC::NE;
|
||||||
|
break;
|
||||||
|
case ISD::SETULE:
|
||||||
|
isUnsigned = true; // FALLTHROUGH
|
||||||
|
case ISD::SETLE:
|
||||||
|
TCC = SystemZCC::LE;
|
||||||
|
break;
|
||||||
|
case ISD::SETUGE:
|
||||||
|
isUnsigned = true; // FALLTHROUGH
|
||||||
|
case ISD::SETGE:
|
||||||
|
TCC = SystemZCC::HE;
|
||||||
|
break;
|
||||||
|
case ISD::SETUGT:
|
||||||
|
isUnsigned = true;
|
||||||
|
case ISD::SETGT:
|
||||||
|
TCC = SystemZCC::H; // FALLTHROUGH
|
||||||
|
break;
|
||||||
|
case ISD::SETULT:
|
||||||
|
isUnsigned = true;
|
||||||
|
case ISD::SETLT: // FALLTHROUGH
|
||||||
|
TCC = SystemZCC::L;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
SystemZCC = DAG.getConstant(TCC, MVT::i32);
|
||||||
|
|
||||||
|
DebugLoc dl = LHS.getDebugLoc();
|
||||||
|
return DAG.getNode((isUnsigned ? SystemZISD::UCMP : SystemZISD::CMP),
|
||||||
|
dl, MVT::Flag, LHS, RHS);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SDValue SystemZTargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) {
|
||||||
|
SDValue Chain = Op.getOperand(0);
|
||||||
|
ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get();
|
||||||
|
SDValue LHS = Op.getOperand(2);
|
||||||
|
SDValue RHS = Op.getOperand(3);
|
||||||
|
SDValue Dest = Op.getOperand(4);
|
||||||
|
DebugLoc dl = Op.getDebugLoc();
|
||||||
|
|
||||||
|
SDValue SystemZCC;
|
||||||
|
SDValue Flag = EmitCmp(LHS, RHS, CC, SystemZCC, DAG);
|
||||||
|
return DAG.getNode(SystemZISD::BRCOND, dl, Op.getValueType(),
|
||||||
|
Chain, Dest, SystemZCC, Flag);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const char *SystemZTargetLowering::getTargetNodeName(unsigned Opcode) const {
|
const char *SystemZTargetLowering::getTargetNodeName(unsigned Opcode) const {
|
||||||
switch (Opcode) {
|
switch (Opcode) {
|
||||||
case SystemZISD::RET_FLAG: return "SystemZISD::RET_FLAG";
|
case SystemZISD::RET_FLAG: return "SystemZISD::RET_FLAG";
|
||||||
case SystemZISD::CALL: return "SystemZISD::CALL";
|
case SystemZISD::CALL: return "SystemZISD::CALL";
|
||||||
|
case SystemZISD::BRCOND: return "SystemZISD::BRCOND";
|
||||||
|
case SystemZISD::CMP: return "SystemZISD::CMP";
|
||||||
|
case SystemZISD::UCMP: return "SystemZISD::UCMP";
|
||||||
default: return NULL;
|
default: return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -30,7 +30,11 @@ namespace llvm {
|
|||||||
|
|
||||||
/// CALL/TAILCALL - These operations represent an abstract call
|
/// CALL/TAILCALL - These operations represent an abstract call
|
||||||
/// instruction, which includes a bunch of information.
|
/// instruction, which includes a bunch of information.
|
||||||
CALL
|
CALL,
|
||||||
|
|
||||||
|
CMP,
|
||||||
|
UCMP,
|
||||||
|
BRCOND
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,14 +55,18 @@ namespace llvm {
|
|||||||
SDValue LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG);
|
SDValue LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG);
|
||||||
SDValue LowerRET(SDValue Op, SelectionDAG &DAG);
|
SDValue LowerRET(SDValue Op, SelectionDAG &DAG);
|
||||||
SDValue LowerCALL(SDValue Op, SelectionDAG &DAG);
|
SDValue LowerCALL(SDValue Op, SelectionDAG &DAG);
|
||||||
|
SDValue LowerBR_CC(SDValue Op, SelectionDAG &DAG);
|
||||||
|
|
||||||
SDValue LowerCCCArguments(SDValue Op, SelectionDAG &DAG);
|
SDValue LowerCCCArguments(SDValue Op, SelectionDAG &DAG);
|
||||||
SDValue LowerCCCCallTo(SDValue Op, SelectionDAG &DAG, unsigned CC);
|
SDValue LowerCCCCallTo(SDValue Op, SelectionDAG &DAG, unsigned CC);
|
||||||
|
|
||||||
SDNode* LowerCallResult(SDValue Chain, SDValue InFlag,
|
SDNode* LowerCallResult(SDValue Chain, SDValue InFlag,
|
||||||
CallSDNode *TheCall,
|
CallSDNode *TheCall,
|
||||||
unsigned CallingConv, SelectionDAG &DAG);
|
unsigned CallingConv, SelectionDAG &DAG);
|
||||||
|
|
||||||
|
SDValue EmitCmp(SDValue LHS, SDValue RHS,
|
||||||
|
ISD::CondCode CC, SDValue &SystemZCC,
|
||||||
|
SelectionDAG &DAG);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const SystemZSubtarget &Subtarget;
|
const SystemZSubtarget &Subtarget;
|
||||||
const SystemZTargetMachine &TM;
|
const SystemZTargetMachine &TM;
|
||||||
|
@@ -27,6 +27,10 @@ class SDTCisI64<int OpNum> : SDTCisVT<OpNum, i64>;
|
|||||||
def SDT_SystemZCall : SDTypeProfile<0, -1, [SDTCisVT<0, iPTR>]>;
|
def SDT_SystemZCall : SDTypeProfile<0, -1, [SDTCisVT<0, iPTR>]>;
|
||||||
def SDT_SystemZCallSeqStart : SDCallSeqStart<[SDTCisI64<0>]>;
|
def SDT_SystemZCallSeqStart : SDCallSeqStart<[SDTCisI64<0>]>;
|
||||||
def SDT_SystemZCallSeqEnd : SDCallSeqEnd<[SDTCisI64<0>, SDTCisI64<1>]>;
|
def SDT_SystemZCallSeqEnd : SDCallSeqEnd<[SDTCisI64<0>, SDTCisI64<1>]>;
|
||||||
|
def SDT_CmpTest : SDTypeProfile<0, 2, [SDTCisSameAs<0, 1>]>;
|
||||||
|
def SDT_BrCond : SDTypeProfile<0, 2,
|
||||||
|
[SDTCisVT<0, OtherVT>,
|
||||||
|
SDTCisI8<1>]>;
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// SystemZ Specific Node Definitions.
|
// SystemZ Specific Node Definitions.
|
||||||
@@ -41,10 +45,24 @@ def SystemZcallseq_start :
|
|||||||
def SystemZcallseq_end :
|
def SystemZcallseq_end :
|
||||||
SDNode<"ISD::CALLSEQ_END", SDT_SystemZCallSeqEnd,
|
SDNode<"ISD::CALLSEQ_END", SDT_SystemZCallSeqEnd,
|
||||||
[SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
|
[SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
|
||||||
|
def SystemZcmp : SDNode<"SystemZISD::CMP", SDT_CmpTest, [SDNPOutFlag]>;
|
||||||
|
def SystemZucmp : SDNode<"SystemZISD::UCMP", SDT_CmpTest, [SDNPOutFlag]>;
|
||||||
|
def SystemZbrcond : SDNode<"SystemZISD::BRCOND", SDT_BrCond,
|
||||||
|
[SDNPHasChain, SDNPInFlag]>;
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Instruction Pattern Stuff.
|
// Instruction Pattern Stuff.
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
// SystemZ specific condition code. These correspond to CondCode in
|
||||||
|
// SystemZ.h. They must be kept in synch.
|
||||||
|
def SYSTEMZ_COND_E : PatLeaf<(i8 0)>;
|
||||||
|
def SYSTEMZ_COND_NE : PatLeaf<(i8 1)>;
|
||||||
|
def SYSTEMZ_COND_H : PatLeaf<(i8 2)>;
|
||||||
|
def SYSTEMZ_COND_L : PatLeaf<(i8 3)>;
|
||||||
|
def SYSTEMZ_COND_HE : PatLeaf<(i8 4)>;
|
||||||
|
def SYSTEMZ_COND_LE : PatLeaf<(i8 5)>;
|
||||||
|
|
||||||
def LL16 : SDNodeXForm<imm, [{
|
def LL16 : SDNodeXForm<imm, [{
|
||||||
// Transformation function: return low 16 bits.
|
// Transformation function: return low 16 bits.
|
||||||
return getI16Imm(N->getZExtValue() & 0x000000000000FFFFULL);
|
return getI16Imm(N->getZExtValue() & 0x000000000000FFFFULL);
|
||||||
@@ -140,6 +158,18 @@ def i32immSExt16 : PatLeaf<(i32 imm), [{
|
|||||||
return (int32_t)N->getZExtValue() == (int16_t)N->getZExtValue();
|
return (int32_t)N->getZExtValue() == (int16_t)N->getZExtValue();
|
||||||
}]>;
|
}]>;
|
||||||
|
|
||||||
|
def i64immSExt32 : PatLeaf<(i64 imm), [{
|
||||||
|
// i64immSExt32 predicate - True if the 64-bit immediate fits in a 32-bit
|
||||||
|
// sign extended field.
|
||||||
|
return (int64_t)N->getZExtValue() == (int32_t)N->getZExtValue();
|
||||||
|
}]>;
|
||||||
|
|
||||||
|
def i64immZExt32 : PatLeaf<(i64 imm), [{
|
||||||
|
// i64immZExt32 predicate - True if the 64-bit immediate fits in a 32-bit
|
||||||
|
// zero extended field.
|
||||||
|
return (uint64_t)N->getZExtValue() == (uint32_t)N->getZExtValue();
|
||||||
|
}]>;
|
||||||
|
|
||||||
// extloads
|
// extloads
|
||||||
def extloadi64i8 : PatFrag<(ops node:$ptr), (i64 (extloadi8 node:$ptr))>;
|
def extloadi64i8 : PatFrag<(ops node:$ptr), (i64 (extloadi8 node:$ptr))>;
|
||||||
def extloadi64i16 : PatFrag<(ops node:$ptr), (i64 (extloadi16 node:$ptr))>;
|
def extloadi64i16 : PatFrag<(ops node:$ptr), (i64 (extloadi16 node:$ptr))>;
|
||||||
@@ -158,6 +188,10 @@ def zextloadi64i32 : PatFrag<(ops node:$ptr), (i64 (zextloadi32 node:$ptr))>;
|
|||||||
def i32i8imm : Operand<i32>;
|
def i32i8imm : Operand<i32>;
|
||||||
// 32-bits but only 16 bits are significant.
|
// 32-bits but only 16 bits are significant.
|
||||||
def i32i16imm : Operand<i32>;
|
def i32i16imm : Operand<i32>;
|
||||||
|
// 64-bits but only 32 bits are significant.
|
||||||
|
def i64i32imm : Operand<i64>;
|
||||||
|
// Branch targets have OtherVT type.
|
||||||
|
def brtarget : Operand<OtherVT>;
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// SystemZ Operand Definitions.
|
// SystemZ Operand Definitions.
|
||||||
@@ -208,10 +242,34 @@ def ADJCALLSTACKUP : Pseudo<(outs), (ins i64imm:$amt1, i64imm:$amt2),
|
|||||||
//
|
//
|
||||||
|
|
||||||
// FIXME: Provide proper encoding!
|
// FIXME: Provide proper encoding!
|
||||||
let isReturn = 1, isTerminator = 1 in {
|
let isReturn = 1, isTerminator = 1, isBarrier = 1, hasCtrlDep = 1 in {
|
||||||
def RET : Pseudo<(outs), (ins), "br\t%r14", [(SystemZretflag)]>;
|
def RET : Pseudo<(outs), (ins), "br\t%r14", [(SystemZretflag)]>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let isBranch = 1, isTerminator = 1 in {
|
||||||
|
let Uses = [PSW] in {
|
||||||
|
def JE : Pseudo<(outs), (ins brtarget:$dst),
|
||||||
|
"je\t$dst",
|
||||||
|
[(SystemZbrcond bb:$dst, SYSTEMZ_COND_E)]>;
|
||||||
|
def JNE : Pseudo<(outs), (ins brtarget:$dst),
|
||||||
|
"jne\t$dst",
|
||||||
|
[(SystemZbrcond bb:$dst, SYSTEMZ_COND_NE)]>;
|
||||||
|
def JH : Pseudo<(outs), (ins brtarget:$dst),
|
||||||
|
"jh\t$dst",
|
||||||
|
[(SystemZbrcond bb:$dst, SYSTEMZ_COND_H)]>;
|
||||||
|
def JL : Pseudo<(outs), (ins brtarget:$dst),
|
||||||
|
"jl\t$dst",
|
||||||
|
[(SystemZbrcond bb:$dst, SYSTEMZ_COND_L)]>;
|
||||||
|
def JHE : Pseudo<(outs), (ins brtarget:$dst),
|
||||||
|
"jhe\t$dst",
|
||||||
|
[(SystemZbrcond bb:$dst, SYSTEMZ_COND_HE)]>;
|
||||||
|
def JLE : Pseudo<(outs), (ins brtarget:$dst),
|
||||||
|
"jle\t$dst",
|
||||||
|
[(SystemZbrcond bb:$dst, SYSTEMZ_COND_LE)]>;
|
||||||
|
|
||||||
|
} // Uses = [PSW]
|
||||||
|
} // isBranch = 1
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Call Instructions...
|
// Call Instructions...
|
||||||
//
|
//
|
||||||
@@ -560,6 +618,81 @@ def SRA64ri : Pseudo<(outs GR64:$dst), (ins GR64:$src, i32imm:$amt),
|
|||||||
(implicit PSW)]>;
|
(implicit PSW)]>;
|
||||||
} // Defs = [PSW]
|
} // Defs = [PSW]
|
||||||
|
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
// Test instructions (like AND but do not produce any result
|
||||||
|
|
||||||
|
// Integer comparisons
|
||||||
|
let Defs = [PSW] in {
|
||||||
|
def CMP32rr : Pseudo<(outs), (ins GR32:$src1, GR32:$src2),
|
||||||
|
"cr\t$src1, $src2",
|
||||||
|
[(SystemZcmp GR32:$src1, GR32:$src2), (implicit PSW)]>;
|
||||||
|
def CMP64rr : Pseudo<(outs), (ins GR64:$src1, GR64:$src2),
|
||||||
|
"cgr\t$src1, $src2",
|
||||||
|
[(SystemZcmp GR64:$src1, GR64:$src2), (implicit PSW)]>;
|
||||||
|
|
||||||
|
def CMP32ri : Pseudo<(outs), (ins GR32:$src1, i32imm:$src2),
|
||||||
|
"cfi\t$src1, $src2",
|
||||||
|
[(SystemZcmp GR32:$src1, imm:$src2), (implicit PSW)]>;
|
||||||
|
def CMP64ri32 : Pseudo<(outs), (ins GR64:$src1, i64i32imm:$src2),
|
||||||
|
"cgfi\t$src1, $src2",
|
||||||
|
[(SystemZcmp GR64:$src1, i64immSExt32:$src2),
|
||||||
|
(implicit PSW)]>;
|
||||||
|
|
||||||
|
def CMP32rm : Pseudo<(outs), (ins GR32:$src1, rriaddr:$src2),
|
||||||
|
"cy\t$src1, $src2",
|
||||||
|
[(SystemZcmp GR32:$src1, (load rriaddr:$src2)),
|
||||||
|
(implicit PSW)]>;
|
||||||
|
def CMP64rm : Pseudo<(outs), (ins GR64:$src1, rriaddr:$src2),
|
||||||
|
"cg\t$src1, $src2",
|
||||||
|
[(SystemZcmp GR64:$src1, (load rriaddr:$src2)),
|
||||||
|
(implicit PSW)]>;
|
||||||
|
|
||||||
|
def UCMP32rr : Pseudo<(outs), (ins GR32:$src1, GR32:$src2),
|
||||||
|
"clr\t$src1, $src2",
|
||||||
|
[(SystemZucmp GR32:$src1, GR32:$src2), (implicit PSW)]>;
|
||||||
|
def UCMP64rr : Pseudo<(outs), (ins GR64:$src1, GR64:$src2),
|
||||||
|
"clgr\t$src1, $src2",
|
||||||
|
[(SystemZucmp GR64:$src1, GR64:$src2), (implicit PSW)]>;
|
||||||
|
|
||||||
|
def UCMP32ri : Pseudo<(outs), (ins GR32:$src1, i32imm:$src2),
|
||||||
|
"clfi\t$src1, $src2",
|
||||||
|
[(SystemZucmp GR32:$src1, imm:$src2), (implicit PSW)]>;
|
||||||
|
def UCMP64ri32 : Pseudo<(outs), (ins GR64:$src1, i64i32imm:$src2),
|
||||||
|
"clgfi\t$src1, $src2",
|
||||||
|
[(SystemZucmp GR64:$src1, i64immZExt32:$src2),
|
||||||
|
(implicit PSW)]>;
|
||||||
|
|
||||||
|
def UCMP32rm : Pseudo<(outs), (ins GR32:$src1, rriaddr:$src2),
|
||||||
|
"cly\t$src1, $src2",
|
||||||
|
[(SystemZucmp GR32:$src1, (load rriaddr:$src2)),
|
||||||
|
(implicit PSW)]>;
|
||||||
|
def UCMP64rm : Pseudo<(outs), (ins GR64:$src1, rriaddr:$src2),
|
||||||
|
"clg\t$src1, $src2",
|
||||||
|
[(SystemZucmp GR64:$src1, (load rriaddr:$src2)),
|
||||||
|
(implicit PSW)]>;
|
||||||
|
|
||||||
|
def CMPSX64rr32 : Pseudo<(outs), (ins GR64:$src1, GR32:$src2),
|
||||||
|
"cgfr\t$src1, $src2",
|
||||||
|
[(SystemZucmp GR64:$src1, (sext GR32:$src2)),
|
||||||
|
(implicit PSW)]>;
|
||||||
|
def UCMPZX64rr32 : Pseudo<(outs), (ins GR64:$src1, GR32:$src2),
|
||||||
|
"clgfr\t$src1, $src2",
|
||||||
|
[(SystemZucmp GR64:$src1, (zext GR32:$src2)),
|
||||||
|
(implicit PSW)]>;
|
||||||
|
|
||||||
|
def CMPSX64rm32 : Pseudo<(outs), (ins GR64:$src1, rriaddr:$src2),
|
||||||
|
"cgf\t$src1, $src2",
|
||||||
|
[(SystemZucmp GR64:$src1, (sextloadi64i32 rriaddr:$src2)),
|
||||||
|
(implicit PSW)]>;
|
||||||
|
def UCMPZX64rm32 : Pseudo<(outs), (ins GR64:$src1, rriaddr:$src2),
|
||||||
|
"clgf\t$src1, $src2",
|
||||||
|
[(SystemZucmp GR64:$src1, (zextloadi64i32 rriaddr:$src2)),
|
||||||
|
(implicit PSW)]>;
|
||||||
|
|
||||||
|
// FIXME: Add other crazy ucmp forms
|
||||||
|
|
||||||
|
} // Defs = [PSW]
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Non-Instruction Patterns.
|
// Non-Instruction Patterns.
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
Reference in New Issue
Block a user