mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-03-08 19:36:02 +00:00
Implement bitfield clears
Implement divide by negative power of two git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@21240 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
ef9531efed
commit
9f833d3085
@ -604,12 +604,13 @@ static bool IsRunOfOnes(unsigned Val, unsigned &MB, unsigned &ME) {
|
|||||||
/// getImmediateForOpcode - This method returns a value indicating whether
|
/// getImmediateForOpcode - This method returns a value indicating whether
|
||||||
/// the ConstantSDNode N can be used as an immediate to Opcode. The return
|
/// the ConstantSDNode N can be used as an immediate to Opcode. The return
|
||||||
/// values are either 0, 1 or 2. 0 indicates that either N is not a
|
/// values are either 0, 1 or 2. 0 indicates that either N is not a
|
||||||
/// ConstantSDNode, or is not suitable for use by that opcode. A return value
|
/// ConstantSDNode, or is not suitable for use by that opcode.
|
||||||
/// of 1 indicates that the constant may be used in normal immediate form. A
|
/// Return value codes for turning into an enum someday:
|
||||||
/// return value of 2 indicates that the constant may be used in shifted
|
/// 1: constant may be used in normal immediate form.
|
||||||
/// immediate form. A return value of 3 indicates that log base 2 of the
|
/// 2: constant may be used in shifted immediate form.
|
||||||
/// constant may be used. A return value of 4 indicates that the constant is
|
/// 3: log base 2 of the constant may be used.
|
||||||
/// suitable for conversion into a magic number for integer division.
|
/// 4: constant is suitable for integer division conversion
|
||||||
|
/// 5: constant is a bitfield mask
|
||||||
///
|
///
|
||||||
static unsigned getImmediateForOpcode(SDOperand N, unsigned Opcode,
|
static unsigned getImmediateForOpcode(SDOperand N, unsigned Opcode,
|
||||||
unsigned& Imm, bool U = false) {
|
unsigned& Imm, bool U = false) {
|
||||||
@ -623,7 +624,13 @@ static unsigned getImmediateForOpcode(SDOperand N, unsigned Opcode,
|
|||||||
if (v <= 32767 && v >= -32768) { Imm = v & 0xFFFF; return 1; }
|
if (v <= 32767 && v >= -32768) { Imm = v & 0xFFFF; return 1; }
|
||||||
if ((v & 0x0000FFFF) == 0) { Imm = v >> 16; return 2; }
|
if ((v & 0x0000FFFF) == 0) { Imm = v >> 16; return 2; }
|
||||||
break;
|
break;
|
||||||
case ISD::AND:
|
case ISD::AND: {
|
||||||
|
unsigned MB, ME;
|
||||||
|
if (IsRunOfOnes(v, MB, ME)) { Imm = MB << 16 | ME & 0xFFFF; return 5; }
|
||||||
|
if (v >= 0 && v <= 65535) { Imm = v & 0xFFFF; return 1; }
|
||||||
|
if ((v & 0x0000FFFF) == 0) { Imm = v >> 16; return 2; }
|
||||||
|
break;
|
||||||
|
}
|
||||||
case ISD::XOR:
|
case ISD::XOR:
|
||||||
case ISD::OR:
|
case ISD::OR:
|
||||||
if (v >= 0 && v <= 65535) { Imm = v & 0xFFFF; return 1; }
|
if (v >= 0 && v <= 65535) { Imm = v & 0xFFFF; return 1; }
|
||||||
@ -639,6 +646,7 @@ static unsigned getImmediateForOpcode(SDOperand N, unsigned Opcode,
|
|||||||
break;
|
break;
|
||||||
case ISD::SDIV:
|
case ISD::SDIV:
|
||||||
if ((Imm = ExactLog2(v))) { return 3; }
|
if ((Imm = ExactLog2(v))) { return 3; }
|
||||||
|
if ((Imm = ExactLog2(-v))) { Imm = -Imm; return 3; }
|
||||||
if (v <= -2 || v >= 2) { return 4; }
|
if (v <= -2 || v >= 2) { return 4; }
|
||||||
break;
|
break;
|
||||||
case ISD::UDIV:
|
case ISD::UDIV:
|
||||||
@ -695,8 +703,6 @@ static unsigned IndexedOpForOp(unsigned Opcode) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
|
||||||
|
|
||||||
// Structure used to return the necessary information to codegen an SDIV as
|
// Structure used to return the necessary information to codegen an SDIV as
|
||||||
// a multiply.
|
// a multiply.
|
||||||
struct ms {
|
struct ms {
|
||||||
@ -1719,6 +1725,13 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) {
|
|||||||
case 2: // Shifted immediate
|
case 2: // Shifted immediate
|
||||||
BuildMI(BB, PPC::ANDISo, 2, Result).addReg(Tmp1).addImm(Tmp2);
|
BuildMI(BB, PPC::ANDISo, 2, Result).addReg(Tmp1).addImm(Tmp2);
|
||||||
break;
|
break;
|
||||||
|
case 5: // Bitfield mask
|
||||||
|
Opc = Recording ? PPC::RLWINMo : PPC::RLWINM;
|
||||||
|
Tmp3 = Tmp2 >> 16; // MB
|
||||||
|
Tmp2 &= 0xFFFF; // ME
|
||||||
|
BuildMI(BB, Opc, 4, Result).addReg(Tmp1).addImm(0)
|
||||||
|
.addImm(Tmp3).addImm(Tmp2);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
RecordSuccess = true;
|
RecordSuccess = true;
|
||||||
return Result;
|
return Result;
|
||||||
@ -1828,8 +1841,15 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) {
|
|||||||
case 3:
|
case 3:
|
||||||
Tmp1 = MakeReg(MVT::i32);
|
Tmp1 = MakeReg(MVT::i32);
|
||||||
Tmp2 = SelectExpr(N.getOperand(0));
|
Tmp2 = SelectExpr(N.getOperand(0));
|
||||||
BuildMI(BB, PPC::SRAWI, 2, Tmp1).addReg(Tmp2).addImm(Tmp3);
|
if ((int)Tmp3 < 0) {
|
||||||
BuildMI(BB, PPC::ADDZE, 1, Result).addReg(Tmp1);
|
unsigned Tmp4 = MakeReg(MVT::i32);
|
||||||
|
BuildMI(BB, PPC::SRAWI, 2, Tmp1).addReg(Tmp2).addImm(-Tmp3);
|
||||||
|
BuildMI(BB, PPC::ADDZE, 1, Tmp4).addReg(Tmp1);
|
||||||
|
BuildMI(BB, PPC::NEG, 1, Result).addReg(Tmp4);
|
||||||
|
} else {
|
||||||
|
BuildMI(BB, PPC::SRAWI, 2, Tmp1).addReg(Tmp2).addImm(Tmp3);
|
||||||
|
BuildMI(BB, PPC::ADDZE, 1, Result).addReg(Tmp1);
|
||||||
|
}
|
||||||
return Result;
|
return Result;
|
||||||
// If this is a divide by constant, we can emit code using some magic
|
// If this is a divide by constant, we can emit code using some magic
|
||||||
// constants to implement it as a multiply instead.
|
// constants to implement it as a multiply instead.
|
||||||
|
@ -464,6 +464,10 @@ def RLWIMI : MForm_2<20, 0, 0, 0,
|
|||||||
def RLWINM : MForm_2<21, 0, 0, 0,
|
def RLWINM : MForm_2<21, 0, 0, 0,
|
||||||
(ops GPRC:$rA, GPRC:$rS, u5imm:$SH, u5imm:$MB, u5imm:$ME),
|
(ops GPRC:$rA, GPRC:$rS, u5imm:$SH, u5imm:$MB, u5imm:$ME),
|
||||||
"rlwinm $rA, $rS, $SH, $MB, $ME">;
|
"rlwinm $rA, $rS, $SH, $MB, $ME">;
|
||||||
|
let Defs = [CR0] in
|
||||||
|
def RLWINMo : MForm_2<21, 1, 0, 0,
|
||||||
|
(ops GPRC:$rA, GPRC:$rS, u5imm:$SH, u5imm:$MB, u5imm:$ME),
|
||||||
|
"rlwinm. $rA, $rS, $SH, $MB, $ME">;
|
||||||
def RLWNM : MForm_2<23, 0, 0, 0,
|
def RLWNM : MForm_2<23, 0, 0, 0,
|
||||||
(ops GPRC:$rA, GPRC:$rS, GPRC:$rB, u5imm:$MB, u5imm:$ME),
|
(ops GPRC:$rA, GPRC:$rS, GPRC:$rB, u5imm:$MB, u5imm:$ME),
|
||||||
"rlwnm $rA, $rS, $rB, $MB, $ME">;
|
"rlwnm $rA, $rS, $rB, $MB, $ME">;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user