mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-21 06:30:16 +00:00
Move the handling of ANY_EXTEND, SIGN_EXTEND_INREG, and TRUNCATE
out of X86ISelDAGToDAG.cpp C++ code and into tablegen code. Among other things, using tablegen for these things makes them friendlier to FastISel. Tablegen can handle the case of i8 subregs on x86-32, but currently the C++ code for that case uses MVT::Flag in a tricky way, and it happens to schedule better in some cases. So for now, leave the C++ code in place to handle the i8 case on x86-32. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@55078 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
f990b571c5
commit
0bfa1bfbff
@ -234,9 +234,11 @@ namespace {
|
|||||||
/// base register. Return the virtual register that holds this value.
|
/// base register. Return the virtual register that holds this value.
|
||||||
SDNode *getGlobalBaseReg();
|
SDNode *getGlobalBaseReg();
|
||||||
|
|
||||||
/// getTruncate - return an SDNode that implements a subreg based truncate
|
/// getTruncateTo8Bit - return an SDNode that implements a subreg based
|
||||||
/// of the specified operand to the the specified value type.
|
/// truncate of the specified operand to i8. This can be done with tablegen,
|
||||||
SDNode *getTruncate(SDValue N0, MVT VT);
|
/// except that this code uses MVT::Flag in a tricky way that happens to
|
||||||
|
/// improve scheduling in some cases.
|
||||||
|
SDNode *getTruncateTo8Bit(SDValue N0);
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
unsigned Indent;
|
unsigned Indent;
|
||||||
@ -1133,38 +1135,33 @@ static SDNode *FindCallStartFromCall(SDNode *Node) {
|
|||||||
return FindCallStartFromCall(Node->getOperand(0).Val);
|
return FindCallStartFromCall(Node->getOperand(0).Val);
|
||||||
}
|
}
|
||||||
|
|
||||||
SDNode *X86DAGToDAGISel::getTruncate(SDValue N0, MVT VT) {
|
/// getTruncateTo8Bit - return an SDNode that implements a subreg based
|
||||||
SDValue SRIdx;
|
/// truncate of the specified operand to i8. This can be done with tablegen,
|
||||||
switch (VT.getSimpleVT()) {
|
/// except that this code uses MVT::Flag in a tricky way that happens to
|
||||||
default: assert(0 && "Unknown truncate!");
|
/// improve scheduling in some cases.
|
||||||
case MVT::i8:
|
SDNode *X86DAGToDAGISel::getTruncateTo8Bit(SDValue N0) {
|
||||||
SRIdx = CurDAG->getTargetConstant(1, MVT::i32); // SubRegSet 1
|
assert(!Subtarget->is64Bit() &&
|
||||||
// Ensure that the source register has an 8-bit subreg on 32-bit targets
|
"getTruncateTo8Bit is only needed on x86-32!");
|
||||||
if (!Subtarget->is64Bit()) {
|
SDValue SRIdx = CurDAG->getTargetConstant(1, MVT::i32); // SubRegSet 1
|
||||||
unsigned Opc;
|
|
||||||
MVT N0VT = N0.getValueType();
|
// Ensure that the source register has an 8-bit subreg on 32-bit targets
|
||||||
switch (N0VT.getSimpleVT()) {
|
unsigned Opc;
|
||||||
default: assert(0 && "Unknown truncate!");
|
MVT N0VT = N0.getValueType();
|
||||||
case MVT::i16:
|
switch (N0VT.getSimpleVT()) {
|
||||||
Opc = X86::MOV16to16_;
|
default: assert(0 && "Unknown truncate!");
|
||||||
break;
|
case MVT::i16:
|
||||||
case MVT::i32:
|
Opc = X86::MOV16to16_;
|
||||||
Opc = X86::MOV32to32_;
|
break;
|
||||||
break;
|
case MVT::i32:
|
||||||
}
|
Opc = X86::MOV32to32_;
|
||||||
N0 = SDValue(CurDAG->getTargetNode(Opc, N0VT, MVT::Flag, N0), 0);
|
break;
|
||||||
return CurDAG->getTargetNode(X86::EXTRACT_SUBREG,
|
}
|
||||||
VT, N0, SRIdx, N0.getValue(1));
|
|
||||||
}
|
// The use of MVT::Flag here is not strictly accurate, but it helps
|
||||||
break;
|
// scheduling in some cases.
|
||||||
case MVT::i16:
|
N0 = SDValue(CurDAG->getTargetNode(Opc, N0VT, MVT::Flag, N0), 0);
|
||||||
SRIdx = CurDAG->getTargetConstant(2, MVT::i32); // SubRegSet 2
|
return CurDAG->getTargetNode(X86::EXTRACT_SUBREG,
|
||||||
break;
|
MVT::i8, N0, SRIdx, N0.getValue(1));
|
||||||
case MVT::i32:
|
|
||||||
SRIdx = CurDAG->getTargetConstant(3, MVT::i32); // SubRegSet 3
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return CurDAG->getTargetNode(X86::EXTRACT_SUBREG, VT, N0, SRIdx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1507,90 +1504,45 @@ SDNode *X86DAGToDAGISel::Select(SDValue N) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
case ISD::ANY_EXTEND: {
|
|
||||||
// Check if the type extended to supports subregs.
|
|
||||||
if (NVT == MVT::i8)
|
|
||||||
break;
|
|
||||||
|
|
||||||
SDValue N0 = Node->getOperand(0);
|
|
||||||
// Get the subregsiter index for the type to extend.
|
|
||||||
MVT N0VT = N0.getValueType();
|
|
||||||
// FIXME: In x86-32, 8-bit value may be in AH, etc. which don't have
|
|
||||||
// super-registers.
|
|
||||||
unsigned Idx = (N0VT == MVT::i32) ? X86::SUBREG_32BIT :
|
|
||||||
(N0VT == MVT::i16) ? X86::SUBREG_16BIT :
|
|
||||||
(Subtarget->is64Bit()) ? X86::SUBREG_8BIT : 0;
|
|
||||||
|
|
||||||
// If we don't have a subreg Idx, let generated ISel have a try.
|
|
||||||
if (Idx == 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
// If we have an index, generate an insert_subreg into undef.
|
|
||||||
AddToISelQueue(N0);
|
|
||||||
SDValue Undef =
|
|
||||||
SDValue(CurDAG->getTargetNode(X86::IMPLICIT_DEF, NVT), 0);
|
|
||||||
SDValue SRIdx = CurDAG->getTargetConstant(Idx, MVT::i32);
|
|
||||||
SDNode *ResNode = CurDAG->getTargetNode(X86::INSERT_SUBREG,
|
|
||||||
NVT, Undef, N0, SRIdx);
|
|
||||||
|
|
||||||
#ifndef NDEBUG
|
|
||||||
DOUT << std::string(Indent-2, ' ') << "=> ";
|
|
||||||
DEBUG(ResNode->dump(CurDAG));
|
|
||||||
DOUT << "\n";
|
|
||||||
Indent -= 2;
|
|
||||||
#endif
|
|
||||||
return ResNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
case ISD::SIGN_EXTEND_INREG: {
|
case ISD::SIGN_EXTEND_INREG: {
|
||||||
SDValue N0 = Node->getOperand(0);
|
|
||||||
AddToISelQueue(N0);
|
|
||||||
|
|
||||||
MVT SVT = cast<VTSDNode>(Node->getOperand(1))->getVT();
|
MVT SVT = cast<VTSDNode>(Node->getOperand(1))->getVT();
|
||||||
SDValue TruncOp = SDValue(getTruncate(N0, SVT), 0);
|
if (SVT == MVT::i8 && !Subtarget->is64Bit()) {
|
||||||
unsigned Opc = 0;
|
SDValue N0 = Node->getOperand(0);
|
||||||
switch (NVT.getSimpleVT()) {
|
AddToISelQueue(N0);
|
||||||
default: assert(0 && "Unknown sign_extend_inreg!");
|
|
||||||
case MVT::i16:
|
|
||||||
if (SVT == MVT::i8) Opc = X86::MOVSX16rr8;
|
|
||||||
else assert(0 && "Unknown sign_extend_inreg!");
|
|
||||||
break;
|
|
||||||
case MVT::i32:
|
|
||||||
switch (SVT.getSimpleVT()) {
|
|
||||||
default: assert(0 && "Unknown sign_extend_inreg!");
|
|
||||||
case MVT::i8: Opc = X86::MOVSX32rr8; break;
|
|
||||||
case MVT::i16: Opc = X86::MOVSX32rr16; break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case MVT::i64:
|
|
||||||
switch (SVT.getSimpleVT()) {
|
|
||||||
default: assert(0 && "Unknown sign_extend_inreg!");
|
|
||||||
case MVT::i8: Opc = X86::MOVSX64rr8; break;
|
|
||||||
case MVT::i16: Opc = X86::MOVSX64rr16; break;
|
|
||||||
case MVT::i32: Opc = X86::MOVSX64rr32; break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
SDNode *ResNode = CurDAG->getTargetNode(Opc, NVT, TruncOp);
|
SDValue TruncOp = SDValue(getTruncateTo8Bit(N0), 0);
|
||||||
|
unsigned Opc = 0;
|
||||||
|
switch (NVT.getSimpleVT()) {
|
||||||
|
default: assert(0 && "Unknown sign_extend_inreg!");
|
||||||
|
case MVT::i16:
|
||||||
|
Opc = X86::MOVSX16rr8;
|
||||||
|
break;
|
||||||
|
case MVT::i32:
|
||||||
|
Opc = X86::MOVSX32rr8;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDNode *ResNode = CurDAG->getTargetNode(Opc, NVT, TruncOp);
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
DOUT << std::string(Indent-2, ' ') << "=> ";
|
DOUT << std::string(Indent-2, ' ') << "=> ";
|
||||||
DEBUG(TruncOp.Val->dump(CurDAG));
|
DEBUG(TruncOp.Val->dump(CurDAG));
|
||||||
DOUT << "\n";
|
DOUT << "\n";
|
||||||
DOUT << std::string(Indent-2, ' ') << "=> ";
|
DOUT << std::string(Indent-2, ' ') << "=> ";
|
||||||
DEBUG(ResNode->dump(CurDAG));
|
DEBUG(ResNode->dump(CurDAG));
|
||||||
DOUT << "\n";
|
DOUT << "\n";
|
||||||
Indent -= 2;
|
Indent -= 2;
|
||||||
#endif
|
#endif
|
||||||
return ResNode;
|
return ResNode;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case ISD::TRUNCATE: {
|
case ISD::TRUNCATE: {
|
||||||
SDValue Input = Node->getOperand(0);
|
if (NVT == MVT::i8 && !Subtarget->is64Bit()) {
|
||||||
AddToISelQueue(Node->getOperand(0));
|
SDValue Input = Node->getOperand(0);
|
||||||
SDNode *ResNode = getTruncate(Input, NVT);
|
AddToISelQueue(Node->getOperand(0));
|
||||||
|
SDNode *ResNode = getTruncateTo8Bit(Input);
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
DOUT << std::string(Indent-2, ' ') << "=> ";
|
DOUT << std::string(Indent-2, ' ') << "=> ";
|
||||||
@ -1598,7 +1550,8 @@ SDNode *X86DAGToDAGISel::Select(SDValue N) {
|
|||||||
DOUT << "\n";
|
DOUT << "\n";
|
||||||
Indent -= 2;
|
Indent -= 2;
|
||||||
#endif
|
#endif
|
||||||
return ResNode;
|
return ResNode;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1254,24 +1254,40 @@ def : Pat<(i64 (zext GR32:$src)),
|
|||||||
def : Pat<(zextloadi64i1 addr:$src), (MOVZX64rm8 addr:$src)>;
|
def : Pat<(zextloadi64i1 addr:$src), (MOVZX64rm8 addr:$src)>;
|
||||||
|
|
||||||
// extload
|
// extload
|
||||||
def : Pat<(extloadi64i1 addr:$src), (MOVZX64rm8 addr:$src)>;
|
def : Pat<(extloadi64i1 addr:$src),
|
||||||
def : Pat<(extloadi64i8 addr:$src), (MOVZX64rm8 addr:$src)>;
|
(INSERT_SUBREG (i64 (IMPLICIT_DEF)), (MOV8rm addr:$src),
|
||||||
def : Pat<(extloadi64i16 addr:$src), (MOVZX64rm16 addr:$src)>;
|
x86_subreg_8bit)>;
|
||||||
def : Pat<(extloadi64i32 addr:$src),
|
def : Pat<(extloadi64i8 addr:$src),
|
||||||
(INSERT_SUBREG (i64 (IMPLICIT_DEF)), (MOV32rm addr:$src),
|
(INSERT_SUBREG (i64 (IMPLICIT_DEF)), (MOV8rm addr:$src),
|
||||||
x86_subreg_32bit)>;
|
x86_subreg_8bit)>;
|
||||||
|
def : Pat<(extloadi64i16 addr:$src),
|
||||||
|
(INSERT_SUBREG (i64 (IMPLICIT_DEF)), (MOV16rm addr:$src),
|
||||||
|
x86_subreg_16bit)>;
|
||||||
|
def : Pat<(extloadi64i32 addr:$src),
|
||||||
|
(INSERT_SUBREG (i64 (IMPLICIT_DEF)), (MOV32rm addr:$src),
|
||||||
|
x86_subreg_32bit)>;
|
||||||
|
def : Pat<(extloadi16i1 addr:$src),
|
||||||
|
(INSERT_SUBREG (i16 (IMPLICIT_DEF)), (MOV8rm addr:$src),
|
||||||
|
x86_subreg_8bit)>,
|
||||||
|
Requires<[In64BitMode]>;
|
||||||
|
def : Pat<(extloadi16i8 addr:$src),
|
||||||
|
(INSERT_SUBREG (i16 (IMPLICIT_DEF)), (MOV8rm addr:$src),
|
||||||
|
x86_subreg_8bit)>,
|
||||||
|
Requires<[In64BitMode]>;
|
||||||
|
|
||||||
// anyext -> zext
|
// anyext
|
||||||
def : Pat<(i64 (anyext GR8 :$src)), (MOVZX64rr8 GR8 :$src)>;
|
def : Pat<(i64 (anyext GR8:$src)),
|
||||||
def : Pat<(i64 (anyext GR16:$src)), (MOVZX64rr16 GR16:$src)>;
|
(INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR8:$src, x86_subreg_8bit)>;
|
||||||
|
def : Pat<(i64 (anyext GR16:$src)),
|
||||||
|
(INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR16:$src, x86_subreg_16bit)>;
|
||||||
def : Pat<(i64 (anyext GR32:$src)),
|
def : Pat<(i64 (anyext GR32:$src)),
|
||||||
(INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR32:$src, x86_subreg_32bit)>;
|
(INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR32:$src, x86_subreg_32bit)>;
|
||||||
|
def : Pat<(i16 (anyext GR8:$src)),
|
||||||
def : Pat<(i64 (anyext (loadi8 addr:$src))), (MOVZX64rm8 addr:$src)>;
|
(INSERT_SUBREG (i16 (IMPLICIT_DEF)), GR8:$src, x86_subreg_8bit)>,
|
||||||
def : Pat<(i64 (anyext (loadi16 addr:$src))), (MOVZX64rm16 addr:$src)>;
|
Requires<[In64BitMode]>;
|
||||||
def : Pat<(i64 (anyext (loadi32 addr:$src))),
|
def : Pat<(i32 (anyext GR8:$src)),
|
||||||
(INSERT_SUBREG (i64 (IMPLICIT_DEF)), (MOV32rm addr:$src),
|
(INSERT_SUBREG (i32 (IMPLICIT_DEF)), GR8:$src, x86_subreg_8bit)>,
|
||||||
x86_subreg_32bit)>;
|
Requires<[In64BitMode]>;
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Some peepholes
|
// Some peepholes
|
||||||
@ -1295,6 +1311,34 @@ def : Pat<(and GR16:$src1, 0xff),
|
|||||||
(MOVZX16rr8 (i8 (EXTRACT_SUBREG GR16:$src1, x86_subreg_8bit)))>,
|
(MOVZX16rr8 (i8 (EXTRACT_SUBREG GR16:$src1, x86_subreg_8bit)))>,
|
||||||
Requires<[In64BitMode]>;
|
Requires<[In64BitMode]>;
|
||||||
|
|
||||||
|
// sext_inreg patterns
|
||||||
|
def : Pat<(sext_inreg GR64:$src, i32),
|
||||||
|
(MOVSX64rr32 (i32 (EXTRACT_SUBREG GR64:$src, x86_subreg_32bit)))>;
|
||||||
|
def : Pat<(sext_inreg GR64:$src, i16),
|
||||||
|
(MOVSX64rr16 (i16 (EXTRACT_SUBREG GR64:$src, x86_subreg_16bit)))>;
|
||||||
|
def : Pat<(sext_inreg GR64:$src, i8),
|
||||||
|
(MOVSX64rr8 (i8 (EXTRACT_SUBREG GR64:$src, x86_subreg_8bit)))>;
|
||||||
|
def : Pat<(sext_inreg GR32:$src, i8),
|
||||||
|
(MOVSX32rr8 (i8 (EXTRACT_SUBREG GR32:$src, x86_subreg_8bit)))>,
|
||||||
|
Requires<[In64BitMode]>;
|
||||||
|
def : Pat<(sext_inreg GR16:$src, i8),
|
||||||
|
(MOVSX16rr8 (i8 (EXTRACT_SUBREG GR16:$src, x86_subreg_8bit)))>,
|
||||||
|
Requires<[In64BitMode]>;
|
||||||
|
|
||||||
|
// trunc patterns
|
||||||
|
def : Pat<(i32 (trunc GR64:$src)),
|
||||||
|
(i32 (EXTRACT_SUBREG GR64:$src, x86_subreg_32bit))>;
|
||||||
|
def : Pat<(i16 (trunc GR64:$src)),
|
||||||
|
(i16 (EXTRACT_SUBREG GR64:$src, x86_subreg_16bit))>;
|
||||||
|
def : Pat<(i8 (trunc GR64:$src)),
|
||||||
|
(i8 (EXTRACT_SUBREG GR64:$src, x86_subreg_8bit))>;
|
||||||
|
def : Pat<(i8 (trunc GR32:$src)),
|
||||||
|
(i8 (EXTRACT_SUBREG GR32:$src, x86_subreg_8bit))>,
|
||||||
|
Requires<[In64BitMode]>;
|
||||||
|
def : Pat<(i8 (trunc GR16:$src)),
|
||||||
|
(i8 (EXTRACT_SUBREG GR16:$src, x86_subreg_8bit))>,
|
||||||
|
Requires<[In64BitMode]>;
|
||||||
|
|
||||||
// (shl x, 1) ==> (add x, x)
|
// (shl x, 1) ==> (add x, x)
|
||||||
def : Pat<(shl GR64:$src1, (i8 1)), (ADD64rr GR64:$src1, GR64:$src1)>;
|
def : Pat<(shl GR64:$src1, (i8 1)), (ADD64rr GR64:$src1, GR64:$src1)>;
|
||||||
|
|
||||||
|
@ -2784,19 +2784,21 @@ def : Pat<(zextloadi32i1 addr:$src), (MOVZX32rm8 addr:$src)>;
|
|||||||
|
|
||||||
// extload bool -> extload byte
|
// extload bool -> extload byte
|
||||||
def : Pat<(extloadi8i1 addr:$src), (MOV8rm addr:$src)>;
|
def : Pat<(extloadi8i1 addr:$src), (MOV8rm addr:$src)>;
|
||||||
def : Pat<(extloadi16i1 addr:$src), (MOVZX16rm8 addr:$src)>;
|
def : Pat<(extloadi16i1 addr:$src), (MOVZX16rm8 addr:$src)>,
|
||||||
|
Requires<[In32BitMode]>;
|
||||||
def : Pat<(extloadi32i1 addr:$src), (MOVZX32rm8 addr:$src)>;
|
def : Pat<(extloadi32i1 addr:$src), (MOVZX32rm8 addr:$src)>;
|
||||||
def : Pat<(extloadi16i8 addr:$src), (MOVZX16rm8 addr:$src)>;
|
def : Pat<(extloadi16i8 addr:$src), (MOVZX16rm8 addr:$src)>,
|
||||||
|
Requires<[In32BitMode]>;
|
||||||
def : Pat<(extloadi32i8 addr:$src), (MOVZX32rm8 addr:$src)>;
|
def : Pat<(extloadi32i8 addr:$src), (MOVZX32rm8 addr:$src)>;
|
||||||
def : Pat<(extloadi32i16 addr:$src), (MOVZX32rm16 addr:$src)>;
|
def : Pat<(extloadi32i16 addr:$src), (MOVZX32rm16 addr:$src)>;
|
||||||
|
|
||||||
// anyext -> zext
|
// anyext
|
||||||
def : Pat<(i16 (anyext GR8 :$src)), (MOVZX16rr8 GR8 :$src)>;
|
def : Pat<(i16 (anyext GR8 :$src)), (MOVZX16rr8 GR8 :$src)>,
|
||||||
def : Pat<(i32 (anyext GR8 :$src)), (MOVZX32rr8 GR8 :$src)>;
|
Requires<[In32BitMode]>;
|
||||||
def : Pat<(i32 (anyext GR16:$src)), (MOVZX32rr16 GR16:$src)>;
|
def : Pat<(i32 (anyext GR8 :$src)), (MOVZX32rr8 GR8 :$src)>,
|
||||||
def : Pat<(i16 (anyext (loadi8 addr:$src))), (MOVZX16rm8 addr:$src)>;
|
Requires<[In32BitMode]>;
|
||||||
def : Pat<(i32 (anyext (loadi8 addr:$src))), (MOVZX32rm8 addr:$src)>;
|
def : Pat<(i32 (anyext GR16:$src)),
|
||||||
def : Pat<(i32 (anyext (loadi16 addr:$src))), (MOVZX32rm16 addr:$src)>;
|
(INSERT_SUBREG (i32 (IMPLICIT_DEF)), GR16:$src, x86_subreg_16bit)>;
|
||||||
|
|
||||||
// (and (i32 load), 255) -> (zextload i8)
|
// (and (i32 load), 255) -> (zextload i8)
|
||||||
def : Pat<(i32 (and (loadi32 addr:$src), (i32 255))), (MOVZX32rm8 addr:$src)>;
|
def : Pat<(i32 (and (loadi32 addr:$src), (i32 255))), (MOVZX32rm8 addr:$src)>;
|
||||||
@ -2808,16 +2810,38 @@ def : Pat<(i32 (and (loadi32 addr:$src), (i32 65535))),(MOVZX32rm16 addr:$src)>;
|
|||||||
|
|
||||||
// r & (2^16-1) ==> movz
|
// r & (2^16-1) ==> movz
|
||||||
def : Pat<(and GR32:$src1, 0xffff),
|
def : Pat<(and GR32:$src1, 0xffff),
|
||||||
(MOVZX32rr16 (i16 (EXTRACT_SUBREG GR32:$src1, x86_subreg_16bit)))>;
|
(MOVZX32rr16 (i16 (EXTRACT_SUBREG GR32:$src1, x86_subreg_16bit)))>;
|
||||||
// r & (2^8-1) ==> movz
|
// r & (2^8-1) ==> movz
|
||||||
def : Pat<(and GR32:$src1, 0xff),
|
def : Pat<(and GR32:$src1, 0xff),
|
||||||
(MOVZX32rr8 (i8 (EXTRACT_SUBREG (MOV32to32_ GR32:$src1),
|
(MOVZX32rr8 (i8 (EXTRACT_SUBREG (MOV32to32_ GR32:$src1),
|
||||||
x86_subreg_8bit)))>,
|
x86_subreg_8bit)))>,
|
||||||
Requires<[In32BitMode]>;
|
Requires<[In32BitMode]>;
|
||||||
// r & (2^8-1) ==> movz
|
// r & (2^8-1) ==> movz
|
||||||
def : Pat<(and GR16:$src1, 0xff),
|
def : Pat<(and GR16:$src1, 0xff),
|
||||||
(MOVZX16rr8 (i8 (EXTRACT_SUBREG (MOV16to16_ GR16:$src1),
|
(MOVZX16rr8 (i8 (EXTRACT_SUBREG (MOV16to16_ GR16:$src1),
|
||||||
x86_subreg_8bit)))>,
|
x86_subreg_8bit)))>,
|
||||||
|
Requires<[In32BitMode]>;
|
||||||
|
|
||||||
|
// sext_inreg patterns
|
||||||
|
def : Pat<(sext_inreg GR32:$src, i16),
|
||||||
|
(MOVSX32rr16 (i16 (EXTRACT_SUBREG GR32:$src, x86_subreg_16bit)))>;
|
||||||
|
def : Pat<(sext_inreg GR32:$src, i8),
|
||||||
|
(MOVSX32rr8 (i8 (EXTRACT_SUBREG (MOV32to32_ GR32:$src),
|
||||||
|
x86_subreg_8bit)))>,
|
||||||
|
Requires<[In32BitMode]>;
|
||||||
|
def : Pat<(sext_inreg GR16:$src, i8),
|
||||||
|
(MOVSX16rr8 (i8 (EXTRACT_SUBREG (MOV16to16_ GR16:$src),
|
||||||
|
x86_subreg_8bit)))>,
|
||||||
|
Requires<[In32BitMode]>;
|
||||||
|
|
||||||
|
// trunc patterns
|
||||||
|
def : Pat<(i16 (trunc GR32:$src)),
|
||||||
|
(i16 (EXTRACT_SUBREG GR32:$src, x86_subreg_16bit))>;
|
||||||
|
def : Pat<(i8 (trunc GR32:$src)),
|
||||||
|
(i8 (EXTRACT_SUBREG (MOV32to32_ GR32:$src), x86_subreg_8bit))>,
|
||||||
|
Requires<[In32BitMode]>;
|
||||||
|
def : Pat<(i8 (trunc GR16:$src)),
|
||||||
|
(i8 (EXTRACT_SUBREG (MOV16to16_ GR16:$src), x86_subreg_8bit))>,
|
||||||
Requires<[In32BitMode]>;
|
Requires<[In32BitMode]>;
|
||||||
|
|
||||||
// (shl x, 1) ==> (add x, x)
|
// (shl x, 1) ==> (add x, x)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user