mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-11-02 07:11:49 +00:00
bswap implementation
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@25312 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
b69c190c26
commit
d88fc03602
@ -2217,6 +2217,58 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
|
||||
}
|
||||
break;
|
||||
|
||||
case ISD::BSWAP:
|
||||
Tmp1 = LegalizeOp(Node->getOperand(0)); // Op
|
||||
switch (TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0))) {
|
||||
case TargetLowering::Legal:
|
||||
if (Tmp1 != Node->getOperand(0))
|
||||
Result = DAG.getNode(Node->getOpcode(), Node->getValueType(0), Tmp1);
|
||||
break;
|
||||
case TargetLowering::Promote: {
|
||||
MVT::ValueType OVT = Tmp1.getValueType();
|
||||
MVT::ValueType NVT = TLI.getTypeToPromoteTo(Node->getOpcode(), OVT);
|
||||
unsigned DiffBits = getSizeInBits(NVT) - getSizeInBits(OVT);
|
||||
|
||||
Tmp1 = DAG.getNode(ISD::ZERO_EXTEND, NVT, Tmp1);
|
||||
Tmp1 = DAG.getNode(ISD::BSWAP, NVT, Tmp1);
|
||||
Result = DAG.getNode(ISD::SRL, NVT, Tmp1,
|
||||
DAG.getConstant(DiffBits, TLI.getShiftAmountTy()));
|
||||
break;
|
||||
}
|
||||
case TargetLowering::Custom:
|
||||
assert(0 && "Cannot custom legalize this yet!");
|
||||
case TargetLowering::Expand: {
|
||||
MVT::ValueType VT = Tmp1.getValueType();
|
||||
switch (VT) {
|
||||
default: assert(0 && "Unhandled Expand type in BSWAP!"); abort();
|
||||
case MVT::i16:
|
||||
Tmp2 = DAG.getNode(ISD::SHL, VT, Tmp1,
|
||||
DAG.getConstant(8, TLI.getShiftAmountTy()));
|
||||
Tmp1 = DAG.getNode(ISD::SRL, VT, Tmp1,
|
||||
DAG.getConstant(8, TLI.getShiftAmountTy()));
|
||||
Result = DAG.getNode(ISD::OR, VT, Tmp1, Tmp2);
|
||||
break;
|
||||
case MVT::i32:
|
||||
Tmp4 = DAG.getNode(ISD::SHL, VT, Tmp1,
|
||||
DAG.getConstant(24, TLI.getShiftAmountTy()));
|
||||
Tmp3 = DAG.getNode(ISD::SHL, VT, Tmp1,
|
||||
DAG.getConstant(8, TLI.getShiftAmountTy()));
|
||||
Tmp2 = DAG.getNode(ISD::SRL, VT, Tmp1,
|
||||
DAG.getConstant(8, TLI.getShiftAmountTy()));
|
||||
Tmp1 = DAG.getNode(ISD::SRL, VT, Tmp1,
|
||||
DAG.getConstant(24, TLI.getShiftAmountTy()));
|
||||
Tmp3 = DAG.getNode(ISD::AND, VT, Tmp3, DAG.getConstant(0xFF0000, VT));
|
||||
Tmp2 = DAG.getNode(ISD::AND, VT, Tmp2, DAG.getConstant(0xFF00, VT));
|
||||
Tmp4 = DAG.getNode(ISD::OR, VT, Tmp4, Tmp3);
|
||||
Tmp2 = DAG.getNode(ISD::OR, VT, Tmp2, Tmp1);
|
||||
Result = DAG.getNode(ISD::OR, VT, Tmp4, Tmp2);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ISD::CTPOP:
|
||||
case ISD::CTTZ:
|
||||
case ISD::CTLZ:
|
||||
@ -3027,6 +3079,14 @@ SDOperand SelectionDAGLegalize::PromoteOp(SDOperand Op) {
|
||||
AddLegalizedOperand(Op.getValue(1), Result.getValue(1));
|
||||
break;
|
||||
}
|
||||
case ISD::BSWAP:
|
||||
Tmp1 = Node->getOperand(0);
|
||||
Tmp1 = DAG.getNode(ISD::ZERO_EXTEND, NVT, Tmp1);
|
||||
Tmp1 = DAG.getNode(ISD::BSWAP, NVT, Tmp1);
|
||||
Result = DAG.getNode(ISD::SRL, NVT, Tmp1,
|
||||
DAG.getConstant(getSizeInBits(NVT) - getSizeInBits(VT),
|
||||
TLI.getShiftAmountTy()));
|
||||
break;
|
||||
case ISD::CTPOP:
|
||||
case ISD::CTTZ:
|
||||
case ISD::CTLZ:
|
||||
@ -3636,6 +3696,14 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){
|
||||
Lo = DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Lo, Node->getOperand(1));
|
||||
break;
|
||||
|
||||
case ISD::BSWAP: {
|
||||
ExpandOp(Node->getOperand(0), Lo, Hi);
|
||||
SDOperand TempLo = DAG.getNode(ISD::BSWAP, NVT, Hi);
|
||||
Hi = DAG.getNode(ISD::BSWAP, NVT, Lo);
|
||||
Lo = TempLo;
|
||||
break;
|
||||
}
|
||||
|
||||
case ISD::CTPOP:
|
||||
ExpandOp(Node->getOperand(0), Lo, Hi);
|
||||
Lo = DAG.getNode(ISD::ADD, NVT, // ctpop(HL) -> ctpop(H)+ctpop(L)
|
||||
|
@ -989,6 +989,21 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
|
||||
DAG.setRoot(Tmp.getValue(1));
|
||||
return 0;
|
||||
}
|
||||
case Intrinsic::bswap_i16:
|
||||
setValue(&I, DAG.getNode(ISD::BSWAP,
|
||||
getValue(I.getOperand(1)).getValueType(),
|
||||
getValue(I.getOperand(1))));
|
||||
return 0;
|
||||
case Intrinsic::bswap_i32:
|
||||
setValue(&I, DAG.getNode(ISD::BSWAP,
|
||||
getValue(I.getOperand(1)).getValueType(),
|
||||
getValue(I.getOperand(1))));
|
||||
return 0;
|
||||
case Intrinsic::bswap_i64:
|
||||
setValue(&I, DAG.getNode(ISD::BSWAP,
|
||||
getValue(I.getOperand(1)).getValueType(),
|
||||
getValue(I.getOperand(1))));
|
||||
return 0;
|
||||
case Intrinsic::cttz:
|
||||
setValue(&I, DAG.getNode(ISD::CTTZ,
|
||||
getValue(I.getOperand(1)).getValueType(),
|
||||
|
@ -81,6 +81,7 @@ AlphaTargetLowering::AlphaTargetLowering(TargetMachine &TM) : TargetLowering(TM)
|
||||
setOperationAction(ISD::CTTZ , MVT::i64 , Expand);
|
||||
setOperationAction(ISD::CTLZ , MVT::i64 , Expand);
|
||||
}
|
||||
setOperationAction(ISD::BSWAP , MVT::i64, Expand);
|
||||
setOperationAction(ISD::ROTL , MVT::i64, Expand);
|
||||
setOperationAction(ISD::ROTR , MVT::i64, Expand);
|
||||
|
||||
|
@ -82,6 +82,7 @@ IA64TargetLowering::IA64TargetLowering(TargetMachine &TM)
|
||||
setOperationAction(ISD::CTLZ , MVT::i64 , Expand);
|
||||
setOperationAction(ISD::ROTL , MVT::i64 , Expand);
|
||||
setOperationAction(ISD::ROTR , MVT::i64 , Expand);
|
||||
setOperationAction(ISD::BSWAP, MVT::i64 , Expand); // mux @rev
|
||||
|
||||
// Not implemented yet.
|
||||
setOperationAction(ISD::STACKSAVE, MVT::Other, Expand);
|
||||
|
@ -98,6 +98,7 @@ namespace {
|
||||
setOperationAction(ISD::CTLZ , MVT::i64 , Expand);
|
||||
setOperationAction(ISD::ROTL , MVT::i64 , Expand);
|
||||
setOperationAction(ISD::ROTR , MVT::i64 , Expand);
|
||||
setOperationAction(ISD::BSWAP, MVT::i64 , Expand); // mux @rev
|
||||
// FIXME: implement mulhs (xma.h) and mulhu (xma.hu)
|
||||
setOperationAction(ISD::MULHS , MVT::i64 , Expand);
|
||||
setOperationAction(ISD::MULHU , MVT::i64 , Expand);
|
||||
|
@ -64,7 +64,8 @@ PPCTargetLowering::PPCTargetLowering(TargetMachine &TM)
|
||||
setOperationAction(ISD::FSQRT, MVT::f32, Expand);
|
||||
}
|
||||
|
||||
// PowerPC does not have CTPOP or CTTZ
|
||||
// PowerPC does not have BSWAP, CTPOP or CTTZ
|
||||
setOperationAction(ISD::BSWAP, MVT::i32 , Expand);
|
||||
setOperationAction(ISD::CTPOP, MVT::i32 , Expand);
|
||||
setOperationAction(ISD::CTTZ , MVT::i32 , Expand);
|
||||
|
||||
|
@ -150,6 +150,7 @@ SparcV8TargetLowering::SparcV8TargetLowering(TargetMachine &TM)
|
||||
setOperationAction(ISD::CTLZ , MVT::i32, Expand);
|
||||
setOperationAction(ISD::ROTL , MVT::i32, Expand);
|
||||
setOperationAction(ISD::ROTR , MVT::i32, Expand);
|
||||
setOperationAction(ISD::BSWAP, MVT::i32, Expand);
|
||||
|
||||
setOperationAction(ISD::SHL_PARTS, MVT::i32, Expand);
|
||||
setOperationAction(ISD::SRA_PARTS, MVT::i32, Expand);
|
||||
|
@ -150,6 +150,7 @@ SparcV8TargetLowering::SparcV8TargetLowering(TargetMachine &TM)
|
||||
setOperationAction(ISD::CTLZ , MVT::i32, Expand);
|
||||
setOperationAction(ISD::ROTL , MVT::i32, Expand);
|
||||
setOperationAction(ISD::ROTR , MVT::i32, Expand);
|
||||
setOperationAction(ISD::BSWAP, MVT::i32, Expand);
|
||||
|
||||
setOperationAction(ISD::SHL_PARTS, MVT::i32, Expand);
|
||||
setOperationAction(ISD::SRA_PARTS, MVT::i32, Expand);
|
||||
|
@ -240,6 +240,7 @@ def xor : SDNode<"ISD::XOR" , SDTIntBinOp,
|
||||
[SDNPCommutative, SDNPAssociative]>;
|
||||
|
||||
def sext_inreg : SDNode<"ISD::SIGN_EXTEND_INREG", SDTExtInreg>;
|
||||
def bswap : SDNode<"ISD::BSWAP" , SDTIntUnaryOp>;
|
||||
def ctlz : SDNode<"ISD::CTLZ" , SDTIntUnaryOp>;
|
||||
def cttz : SDNode<"ISD::CTTZ" , SDTIntUnaryOp>;
|
||||
def ctpop : SDNode<"ISD::CTPOP" , SDTIntUnaryOp>;
|
||||
|
@ -109,6 +109,7 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
|
||||
setOperationAction(ISD::READCYCLECOUNTER , MVT::i64 , Custom);
|
||||
|
||||
if (!X86DAGIsel) {
|
||||
setOperationAction(ISD::BSWAP , MVT::i32 , Expand);
|
||||
setOperationAction(ISD::ROTL , MVT::i8 , Expand);
|
||||
setOperationAction(ISD::ROTR , MVT::i8 , Expand);
|
||||
setOperationAction(ISD::ROTL , MVT::i16 , Expand);
|
||||
@ -116,6 +117,7 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
|
||||
setOperationAction(ISD::ROTL , MVT::i32 , Expand);
|
||||
setOperationAction(ISD::ROTR , MVT::i32 , Expand);
|
||||
}
|
||||
setOperationAction(ISD::BSWAP , MVT::i16 , Expand);
|
||||
|
||||
setOperationAction(ISD::READIO , MVT::i1 , Expand);
|
||||
setOperationAction(ISD::READIO , MVT::i8 , Expand);
|
||||
|
@ -518,7 +518,9 @@ def POP32r : I<0x58, AddRegFrm,
|
||||
|
||||
let isTwoAddress = 1 in // R32 = bswap R32
|
||||
def BSWAP32r : I<0xC8, AddRegFrm,
|
||||
(ops R32:$dst, R32:$src), "bswap{l} $dst", []>, TB;
|
||||
(ops R32:$dst, R32:$src),
|
||||
"bswap{l} $dst",
|
||||
[(set R32:$dst, (bswap R32:$src))]>, TB;
|
||||
|
||||
def XCHG8rr : I<0x86, MRMDestReg, // xchg R8, R8
|
||||
(ops R8:$src1, R8:$src2),
|
||||
|
23
test/CodeGen/X86/bswap.ll
Normal file
23
test/CodeGen/X86/bswap.ll
Normal file
@ -0,0 +1,23 @@
|
||||
; bswap should be constant folded when it is passed a constant argument
|
||||
|
||||
; RUN: llvm-as < %s | llc -march=x86 -enable-x86-dag-isel | grep bswapl | wc -l | grep 3 &&
|
||||
; RUN: llvm-as < %s | llc -march=x86 -enable-x86-dag-isel | grep rolw | wc -l | grep 1
|
||||
|
||||
declare ushort %llvm.bswap.i16(ushort)
|
||||
declare uint %llvm.bswap.i32(uint)
|
||||
declare ulong %llvm.bswap.i64(ulong)
|
||||
|
||||
ushort %W(ushort %A) {
|
||||
%Z = call ushort %llvm.bswap.i16(ushort %A)
|
||||
ret ushort %Z
|
||||
}
|
||||
|
||||
uint %X(uint %A) {
|
||||
%Z = call uint %llvm.bswap.i32(uint %A)
|
||||
ret uint %Z
|
||||
}
|
||||
|
||||
ulong %Y(ulong %A) {
|
||||
%Z = call ulong %llvm.bswap.i64(ulong %A)
|
||||
ret ulong %Z
|
||||
}
|
Loading…
Reference in New Issue
Block a user