mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-29 10:32:47 +00:00
Write patterns for the various shl and srl patterns that don't involve
doing something clever. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@23824 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
886eb39170
commit
2d5aff761d
@ -1214,51 +1214,28 @@ SDOperand PPCDAGToDAGISel::Select(SDOperand Op) {
|
||||
case ISD::SHL: {
|
||||
unsigned Imm, SH, MB, ME;
|
||||
if (isOpcWithIntImmediate(N->getOperand(0).Val, ISD::AND, Imm) &&
|
||||
isRotateAndMask(N, Imm, true, SH, MB, ME))
|
||||
isRotateAndMask(N, Imm, true, SH, MB, ME)) {
|
||||
CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32,
|
||||
Select(N->getOperand(0).getOperand(0)),
|
||||
getI32Imm(SH), getI32Imm(MB), getI32Imm(ME));
|
||||
else if (isIntImmediate(N->getOperand(1), Imm)) {
|
||||
if (N->getValueType(0) == MVT::i64)
|
||||
CurDAG->SelectNodeTo(N, PPC::RLDICR, MVT::i64, Select(N->getOperand(0)),
|
||||
getI32Imm(Imm), getI32Imm(63-Imm));
|
||||
else
|
||||
CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, Select(N->getOperand(0)),
|
||||
getI32Imm(Imm), getI32Imm(0), getI32Imm(31-Imm));
|
||||
} else {
|
||||
if (N->getValueType(0) == MVT::i64)
|
||||
CurDAG->SelectNodeTo(N, PPC::SLD, MVT::i64, Select(N->getOperand(0)),
|
||||
Select(N->getOperand(1)));
|
||||
else
|
||||
CurDAG->SelectNodeTo(N, PPC::SLW, MVT::i32, Select(N->getOperand(0)),
|
||||
Select(N->getOperand(1)));
|
||||
return SDOperand(N, 0);
|
||||
}
|
||||
return SDOperand(N, 0);
|
||||
|
||||
// Other cases are autogenerated.
|
||||
break;
|
||||
}
|
||||
case ISD::SRL: {
|
||||
unsigned Imm, SH, MB, ME;
|
||||
if (isOpcWithIntImmediate(N->getOperand(0).Val, ISD::AND, Imm) &&
|
||||
isRotateAndMask(N, Imm, true, SH, MB, ME))
|
||||
isRotateAndMask(N, Imm, true, SH, MB, ME)) {
|
||||
CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32,
|
||||
Select(N->getOperand(0).getOperand(0)),
|
||||
getI32Imm(SH & 0x1F), getI32Imm(MB), getI32Imm(ME));
|
||||
else if (isIntImmediate(N->getOperand(1), Imm)) {
|
||||
if (N->getValueType(0) == MVT::i64)
|
||||
CurDAG->SelectNodeTo(N, PPC::RLDICL, MVT::i64, Select(N->getOperand(0)),
|
||||
getI32Imm(64-Imm), getI32Imm(Imm));
|
||||
else
|
||||
CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, Select(N->getOperand(0)),
|
||||
getI32Imm((32-Imm) & 0x1F), getI32Imm(Imm),
|
||||
getI32Imm(31));
|
||||
} else {
|
||||
if (N->getValueType(0) == MVT::i64)
|
||||
CurDAG->SelectNodeTo(N, PPC::SRD, MVT::i64, Select(N->getOperand(0)),
|
||||
Select(N->getOperand(1)));
|
||||
else
|
||||
CurDAG->SelectNodeTo(N, PPC::SRW, MVT::i32, Select(N->getOperand(0)),
|
||||
Select(N->getOperand(1)));
|
||||
return SDOperand(N, 0);
|
||||
}
|
||||
return SDOperand(N, 0);
|
||||
|
||||
// Other cases are autogenerated.
|
||||
break;
|
||||
}
|
||||
case ISD::FNEG: {
|
||||
SDOperand Val = Select(N->getOperand(0));
|
||||
|
@ -468,13 +468,16 @@ class AForm_3<bits<6> opcode, bits<5> xo, dag OL, string asmstr, list<dag> pat>
|
||||
}
|
||||
|
||||
// 1.7.13 M-Form
|
||||
class MForm_1<bits<6> opcode, dag OL, string asmstr> : I<opcode, OL, asmstr> {
|
||||
class MForm_1<bits<6> opcode, dag OL, string asmstr, list<dag> pattern>
|
||||
: I<opcode, OL, asmstr> {
|
||||
bits<5> RA;
|
||||
bits<5> RS;
|
||||
bits<5> RB;
|
||||
bits<5> MB;
|
||||
bits<5> ME;
|
||||
|
||||
let Pattern = pattern;
|
||||
|
||||
bit RC = 0; // set by isDOT
|
||||
|
||||
let Inst{6-10} = RS;
|
||||
@ -485,18 +488,21 @@ class MForm_1<bits<6> opcode, dag OL, string asmstr> : I<opcode, OL, asmstr> {
|
||||
let Inst{31} = RC;
|
||||
}
|
||||
|
||||
class MForm_2<bits<6> opcode, dag OL, string asmstr>
|
||||
: MForm_1<opcode, OL, asmstr> {
|
||||
class MForm_2<bits<6> opcode, dag OL, string asmstr, list<dag> pattern>
|
||||
: MForm_1<opcode, OL, asmstr, pattern> {
|
||||
}
|
||||
|
||||
// 1.7.14 MD-Form
|
||||
class MDForm_1<bits<6> opcode, bits<3> xo, dag OL, string asmstr>
|
||||
class MDForm_1<bits<6> opcode, bits<3> xo, dag OL, string asmstr,
|
||||
list<dag> pattern>
|
||||
: I<opcode, OL, asmstr> {
|
||||
bits<5> RS;
|
||||
bits<5> RA;
|
||||
bits<6> SH;
|
||||
bits<6> MBE;
|
||||
|
||||
let Pattern = pattern;
|
||||
|
||||
bit RC = 0; // set by isDOT
|
||||
|
||||
let Inst{6-10} = RS;
|
||||
|
@ -19,6 +19,26 @@ include "PPCInstrFormats.td"
|
||||
// PowerPC specific transformation functions and pattern fragments.
|
||||
//
|
||||
|
||||
def SHL32 : SDNodeXForm<imm, [{
|
||||
// Transformation function: 31 - imm
|
||||
return getI32Imm(31 - N->getValue());
|
||||
}]>;
|
||||
|
||||
def SHL64 : SDNodeXForm<imm, [{
|
||||
// Transformation function: 63 - imm
|
||||
return getI32Imm(63 - N->getValue());
|
||||
}]>;
|
||||
|
||||
def SRL32 : SDNodeXForm<imm, [{
|
||||
// Transformation function: 32 - imm
|
||||
return N->getValue() ? getI32Imm(32 - N->getValue()) : getI32Imm(0);
|
||||
}]>;
|
||||
|
||||
def SRL64 : SDNodeXForm<imm, [{
|
||||
// Transformation function: 64 - imm
|
||||
return N->getValue() ? getI32Imm(64 - N->getValue()) : getI32Imm(0);
|
||||
}]>;
|
||||
|
||||
def LO16 : SDNodeXForm<imm, [{
|
||||
// Transformation function: get the low 16 bits.
|
||||
return getI32Imm((unsigned short)N->getValue());
|
||||
@ -354,21 +374,21 @@ def EQV : XForm_6<31, 284, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB),
|
||||
def XOR : XForm_6<31, 316, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB),
|
||||
"xor $rA, $rS, $rB",
|
||||
[(set GPRC:$rA, (xor GPRC:$rS, GPRC:$rB))]>;
|
||||
def SLD : XForm_6<31, 27, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB),
|
||||
def SLD : XForm_6<31, 27, (ops G8RC:$rA, G8RC:$rS, G8RC:$rB),
|
||||
"sld $rA, $rS, $rB",
|
||||
[]>, isPPC64;
|
||||
[(set G8RC:$rA, (shl G8RC:$rS, G8RC:$rB))]>, isPPC64;
|
||||
def SLW : XForm_6<31, 24, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB),
|
||||
"slw $rA, $rS, $rB",
|
||||
[(set GPRC:$rA, (shl GPRC:$rS, GPRC:$rB))]>;
|
||||
def SRD : XForm_6<31, 539, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB),
|
||||
def SRD : XForm_6<31, 539, (ops G8RC:$rA, G8RC:$rS, G8RC:$rB),
|
||||
"srd $rA, $rS, $rB",
|
||||
[]>, isPPC64;
|
||||
[(set G8RC:$rA, (srl G8RC:$rS, G8RC:$rB))]>, isPPC64;
|
||||
def SRW : XForm_6<31, 536, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB),
|
||||
"srw $rA, $rS, $rB",
|
||||
[(set GPRC:$rA, (srl GPRC:$rS, GPRC:$rB))]>;
|
||||
def SRAD : XForm_6<31, 794, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB),
|
||||
def SRAD : XForm_6<31, 794, (ops G8RC:$rA, G8RC:$rS, G8RC:$rB),
|
||||
"srad $rA, $rS, $rB",
|
||||
[]>, isPPC64;
|
||||
[(set G8RC:$rA, (sra G8RC:$rS, G8RC:$rB))]>, isPPC64;
|
||||
def SRAW : XForm_6<31, 792, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB),
|
||||
"sraw $rA, $rS, $rB",
|
||||
[(set GPRC:$rA, (sra GPRC:$rS, GPRC:$rB))]>;
|
||||
@ -663,29 +683,36 @@ let isTwoAddress = 1, isCommutable = 1 in {
|
||||
// RLWIMI can be commuted if the rotate amount is zero.
|
||||
def RLWIMI : MForm_2<20,
|
||||
(ops GPRC:$rA, GPRC:$rSi, GPRC:$rS, u5imm:$SH, u5imm:$MB,
|
||||
u5imm:$ME), "rlwimi $rA, $rS, $SH, $MB, $ME">;
|
||||
u5imm:$ME), "rlwimi $rA, $rS, $SH, $MB, $ME",
|
||||
[]>;
|
||||
def RLDIMI : MDForm_1<30, 3,
|
||||
(ops G8RC:$rA, G8RC:$rSi, G8RC:$rS, u6imm:$SH, u6imm:$MB),
|
||||
"rldimi $rA, $rS, $SH, $MB">, isPPC64;
|
||||
"rldimi $rA, $rS, $SH, $MB",
|
||||
[]>, isPPC64;
|
||||
}
|
||||
def RLWINM : MForm_2<21,
|
||||
(ops GPRC:$rA, GPRC:$rS, u5imm:$SH, u5imm:$MB, u5imm:$ME),
|
||||
"rlwinm $rA, $rS, $SH, $MB, $ME">;
|
||||
"rlwinm $rA, $rS, $SH, $MB, $ME",
|
||||
[]>;
|
||||
def RLWINMo : MForm_2<21,
|
||||
(ops GPRC:$rA, GPRC:$rS, u5imm:$SH, u5imm:$MB, u5imm:$ME),
|
||||
"rlwinm. $rA, $rS, $SH, $MB, $ME">, isDOT;
|
||||
"rlwinm. $rA, $rS, $SH, $MB, $ME",
|
||||
[]>, isDOT;
|
||||
def RLWNM : MForm_2<23,
|
||||
(ops GPRC:$rA, GPRC:$rS, GPRC:$rB, u5imm:$MB, u5imm:$ME),
|
||||
"rlwnm $rA, $rS, $rB, $MB, $ME">;
|
||||
"rlwnm $rA, $rS, $rB, $MB, $ME",
|
||||
[]>;
|
||||
|
||||
// MD-Form instructions. 64 bit rotate instructions.
|
||||
//
|
||||
def RLDICL : MDForm_1<30, 0,
|
||||
(ops G8RC:$rA, G8RC:$rS, u6imm:$SH, u6imm:$MB),
|
||||
"rldicl $rA, $rS, $SH, $MB">, isPPC64;
|
||||
"rldicl $rA, $rS, $SH, $MB",
|
||||
[]>, isPPC64;
|
||||
def RLDICR : MDForm_1<30, 1,
|
||||
(ops G8RC:$rA, G8RC:$rS, u6imm:$SH, u6imm:$ME),
|
||||
"rldicr $rA, $rS, $SH, $ME">, isPPC64;
|
||||
"rldicr $rA, $rS, $SH, $ME",
|
||||
[]>, isPPC64;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// PowerPC Instruction Patterns
|
||||
@ -716,6 +743,17 @@ def : Pat<(anyext GPRC:$in),
|
||||
def : Pat<(trunc G8RC:$in),
|
||||
(OR8To4 G8RC:$in, G8RC:$in)>;
|
||||
|
||||
// SHL
|
||||
def : Pat<(shl GPRC:$in, imm:$imm),
|
||||
(RLWINM GPRC:$in, imm:$imm, 0, (SHL32 imm:$imm))>;
|
||||
def : Pat<(shl G8RC:$in, imm:$imm),
|
||||
(RLDICR G8RC:$in, imm:$imm, (SHL64 imm:$imm))>;
|
||||
// SRL
|
||||
def : Pat<(srl GPRC:$in, imm:$imm),
|
||||
(RLWINM GPRC:$in, (SRL32 imm:$imm), imm:$imm, 31)>;
|
||||
def : Pat<(srl G8RC:$in, imm:$imm),
|
||||
(RLDICL G8RC:$in, (SRL64 imm:$imm), imm:$imm)>;
|
||||
|
||||
// Same as above, but using a temporary. FIXME: implement temporaries :)
|
||||
/*
|
||||
def : Pattern<(xor GPRC:$in, imm:$imm),
|
||||
|
Loading…
Reference in New Issue
Block a user