mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-02 07:32:52 +00:00
Proper support for shifts with register shift value.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@24559 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
c121e33e35
commit
640f299b44
@ -134,10 +134,11 @@ void X86DAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) {
|
|||||||
void X86DAGToDAGISel::SelectAddress(SDOperand N, X86ISelAddressMode &AM) {
|
void X86DAGToDAGISel::SelectAddress(SDOperand N, X86ISelAddressMode &AM) {
|
||||||
MatchAddress(N, AM);
|
MatchAddress(N, AM);
|
||||||
|
|
||||||
if (AM.BaseType == X86ISelAddressMode::RegBase && !AM.Base.Reg.Val) {
|
if (AM.BaseType == X86ISelAddressMode::RegBase) {
|
||||||
AM.Base.Reg = CurDAG->getRegister(0, MVT::i32);
|
if (AM.Base.Reg.Val)
|
||||||
} else {
|
AM.Base.Reg = Select(AM.Base.Reg);
|
||||||
AM.Base.Reg = Select(AM.Base.Reg);
|
else
|
||||||
|
AM.Base.Reg = CurDAG->getRegister(0, MVT::i32);
|
||||||
}
|
}
|
||||||
if (!AM.IndexReg.Val) {
|
if (!AM.IndexReg.Val) {
|
||||||
AM.IndexReg = CurDAG->getRegister(0, MVT::i32);
|
AM.IndexReg = CurDAG->getRegister(0, MVT::i32);
|
||||||
@ -277,10 +278,8 @@ SDOperand X86DAGToDAGISel::Select(SDOperand Op) {
|
|||||||
default: break;
|
default: break;
|
||||||
|
|
||||||
case ISD::SHL:
|
case ISD::SHL:
|
||||||
case ISD::SRL:
|
|
||||||
case ISD::SRA:
|
|
||||||
if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N->getOperand(1))) {
|
if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N->getOperand(1))) {
|
||||||
if (N->getOpcode() == ISD::SHL && CN->getValue() == 1) {
|
if (CN->getValue() == 1) {
|
||||||
// X = SHL Y, 1 -> X = ADD Y, Y
|
// X = SHL Y, 1 -> X = ADD Y, Y
|
||||||
switch (OpVT) {
|
switch (OpVT) {
|
||||||
default: assert(0 && "Cannot shift this type!");
|
default: assert(0 && "Cannot shift this type!");
|
||||||
@ -291,34 +290,6 @@ SDOperand X86DAGToDAGISel::Select(SDOperand Op) {
|
|||||||
SDOperand Tmp0 = Select(N->getOperand(0));
|
SDOperand Tmp0 = Select(N->getOperand(0));
|
||||||
return CurDAG->SelectNodeTo(N, Opc, MVT::i32, Tmp0, Tmp0);
|
return CurDAG->SelectNodeTo(N, Opc, MVT::i32, Tmp0, Tmp0);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
static const unsigned SHLTab[] = {
|
|
||||||
X86::SHL8rCL, X86::SHL16rCL, X86::SHL32rCL
|
|
||||||
};
|
|
||||||
static const unsigned SRLTab[] = {
|
|
||||||
X86::SHR8rCL, X86::SHR16rCL, X86::SHR32rCL
|
|
||||||
};
|
|
||||||
static const unsigned SRATab[] = {
|
|
||||||
X86::SAR8rCL, X86::SAR16rCL, X86::SAR32rCL
|
|
||||||
};
|
|
||||||
|
|
||||||
switch (OpVT) {
|
|
||||||
default: assert(0 && "Cannot shift this type!");
|
|
||||||
case MVT::i1:
|
|
||||||
case MVT::i8: Opc = 0; break;
|
|
||||||
case MVT::i16: Opc = 1; break;
|
|
||||||
case MVT::i32: Opc = 2; break;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (N->getOpcode()) {
|
|
||||||
default: assert(0 && "Unreachable!");
|
|
||||||
case ISD::SHL: Opc = SHLTab[Opc]; break;
|
|
||||||
case ISD::SRL: Opc = SRLTab[Opc]; break;
|
|
||||||
case ISD::SRA: Opc = SRATab[Opc]; break;
|
|
||||||
}
|
|
||||||
|
|
||||||
SDOperand Tmp0 = Select(N->getOperand(0));
|
|
||||||
return CurDAG->SelectNodeTo(N, Opc, MVT::i32, Tmp0);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -892,11 +892,14 @@ let isTwoAddress = 0 in {
|
|||||||
// Shift instructions
|
// Shift instructions
|
||||||
// FIXME: provide shorter instructions when imm8 == 1
|
// FIXME: provide shorter instructions when imm8 == 1
|
||||||
def SHL8rCL : I<0xD2, MRM4r, (ops R8 :$dst, R8 :$src),
|
def SHL8rCL : I<0xD2, MRM4r, (ops R8 :$dst, R8 :$src),
|
||||||
"shl{b} {%cl, $dst|$dst, %CL}", []>, Imp<[CL],[]>;
|
"shl{b} {%cl, $dst|$dst, %CL}",
|
||||||
|
[(set R8:$dst, (shl R8:$src, CL))]>, Imp<[CL],[]>;
|
||||||
def SHL16rCL : I<0xD3, MRM4r, (ops R16:$dst, R16:$src),
|
def SHL16rCL : I<0xD3, MRM4r, (ops R16:$dst, R16:$src),
|
||||||
"shl{w} {%cl, $dst|$dst, %CL}", []>, Imp<[CL],[]>, OpSize;
|
"shl{w} {%cl, $dst|$dst, %CL}",
|
||||||
|
[(set R16:$dst, (shl R16:$src, CL))]>, Imp<[CL],[]>, OpSize;
|
||||||
def SHL32rCL : I<0xD3, MRM4r, (ops R32:$dst, R32:$src),
|
def SHL32rCL : I<0xD3, MRM4r, (ops R32:$dst, R32:$src),
|
||||||
"shl{l} {%cl, $dst|$dst, %CL}", []>, Imp<[CL],[]>;
|
"shl{l} {%cl, $dst|$dst, %CL}",
|
||||||
|
[(set R32:$dst, (shl R32:$src, CL))]>, Imp<[CL],[]>;
|
||||||
|
|
||||||
def SHL8ri : Ii8<0xC0, MRM4r, (ops R8 :$dst, R8 :$src1, i8imm:$src2),
|
def SHL8ri : Ii8<0xC0, MRM4r, (ops R8 :$dst, R8 :$src1, i8imm:$src2),
|
||||||
"shl{b} {$src2, $dst|$dst, $src2}",
|
"shl{b} {$src2, $dst|$dst, $src2}",
|
||||||
@ -926,11 +929,14 @@ let isTwoAddress = 0 in {
|
|||||||
}
|
}
|
||||||
|
|
||||||
def SHR8rCL : I<0xD2, MRM5r, (ops R8 :$dst, R8 :$src),
|
def SHR8rCL : I<0xD2, MRM5r, (ops R8 :$dst, R8 :$src),
|
||||||
"shr{b} {%cl, $dst|$dst, %CL}", []>, Imp<[CL],[]>;
|
"shr{b} {%cl, $dst|$dst, %CL}",
|
||||||
|
[(set R8:$dst, (srl R8:$src, CL))]>, Imp<[CL],[]>;
|
||||||
def SHR16rCL : I<0xD3, MRM5r, (ops R16:$dst, R16:$src),
|
def SHR16rCL : I<0xD3, MRM5r, (ops R16:$dst, R16:$src),
|
||||||
"shr{w} {%cl, $dst|$dst, %CL}", []>, Imp<[CL],[]>, OpSize;
|
"shr{w} {%cl, $dst|$dst, %CL}",
|
||||||
|
[(set R16:$dst, (srl R16:$src, CL))]>, Imp<[CL],[]>, OpSize;
|
||||||
def SHR32rCL : I<0xD3, MRM5r, (ops R32:$dst, R32:$src),
|
def SHR32rCL : I<0xD3, MRM5r, (ops R32:$dst, R32:$src),
|
||||||
"shr{l} {%cl, $dst|$dst, %CL}", []>, Imp<[CL],[]>;
|
"shr{l} {%cl, $dst|$dst, %CL}",
|
||||||
|
[(set R32:$dst, (srl R32:$src, CL))]>, Imp<[CL],[]>;
|
||||||
|
|
||||||
def SHR8ri : Ii8<0xC0, MRM5r, (ops R8:$dst, R8:$src1, i8imm:$src2),
|
def SHR8ri : Ii8<0xC0, MRM5r, (ops R8:$dst, R8:$src1, i8imm:$src2),
|
||||||
"shr{b} {$src2, $dst|$dst, $src2}",
|
"shr{b} {$src2, $dst|$dst, $src2}",
|
||||||
@ -958,11 +964,14 @@ let isTwoAddress = 0 in {
|
|||||||
}
|
}
|
||||||
|
|
||||||
def SAR8rCL : I<0xD2, MRM7r, (ops R8 :$dst, R8 :$src),
|
def SAR8rCL : I<0xD2, MRM7r, (ops R8 :$dst, R8 :$src),
|
||||||
"sar{b} {%cl, $dst|$dst, %CL}", []>, Imp<[CL],[]>;
|
"sar{b} {%cl, $dst|$dst, %CL}",
|
||||||
|
[(set R8:$dst, (sra R8:$src, CL))]>, Imp<[CL],[]>;
|
||||||
def SAR16rCL : I<0xD3, MRM7r, (ops R16:$dst, R16:$src),
|
def SAR16rCL : I<0xD3, MRM7r, (ops R16:$dst, R16:$src),
|
||||||
"sar{w} {%cl, $dst|$dst, %CL}", []>, Imp<[CL],[]>, OpSize;
|
"sar{w} {%cl, $dst|$dst, %CL}",
|
||||||
|
[(set R16:$dst, (sra R16:$src, CL))]>, Imp<[CL],[]>, OpSize;
|
||||||
def SAR32rCL : I<0xD3, MRM7r, (ops R32:$dst, R32:$src),
|
def SAR32rCL : I<0xD3, MRM7r, (ops R32:$dst, R32:$src),
|
||||||
"sar{l} {%cl, $dst|$dst, %CL}", []>, Imp<[CL],[]>;
|
"sar{l} {%cl, $dst|$dst, %CL}",
|
||||||
|
[(set R32:$dst, (sra R32:$src, CL))]>, Imp<[CL],[]>;
|
||||||
|
|
||||||
def SAR8ri : Ii8<0xC0, MRM7r, (ops R8 :$dst, R8 :$src1, i8imm:$src2),
|
def SAR8ri : Ii8<0xC0, MRM7r, (ops R8 :$dst, R8 :$src1, i8imm:$src2),
|
||||||
"sar{b} {$src2, $dst|$dst, $src2}",
|
"sar{b} {$src2, $dst|$dst, $src2}",
|
||||||
|
Loading…
Reference in New Issue
Block a user