mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-08-15 22:28:18 +00:00
Implement a couple improvements:
Remove dead code in ISD::Constant handling Add support for add long, imm16 We now codegen 'long long foo(long long a) { return ++a; }' as: addic r4, r4, 1 addze r3, r3 blr instead of: li r2, 1 li r5, 0 addc r2, r4, r2 adde r3, r3, r5 blr git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22811 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -1436,16 +1436,36 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) {
|
|||||||
case ISD::SUB_PARTS: {
|
case ISD::SUB_PARTS: {
|
||||||
assert(N.getNumOperands() == 4 && N.getValueType() == MVT::i32 &&
|
assert(N.getNumOperands() == 4 && N.getValueType() == MVT::i32 &&
|
||||||
"Not an i64 add/sub!");
|
"Not an i64 add/sub!");
|
||||||
// Emit all of the operands.
|
unsigned Tmp4 = 0;
|
||||||
std::vector<unsigned> InVals;
|
bool ME = isIntImmediate(N.getOperand(3),Tmp3) && ((signed)Tmp3 == -1);
|
||||||
for (unsigned i = 0, e = N.getNumOperands(); i != e; ++i)
|
bool ZE = isIntImmediate(N.getOperand(3),Tmp3) && (Tmp3 == 0);
|
||||||
InVals.push_back(SelectExpr(N.getOperand(i)));
|
bool IM = isIntImmediate(N.getOperand(2),Tmp3) && ((signed)Tmp3 >= -32768 ||
|
||||||
|
(signed)Tmp3 < 32768);
|
||||||
|
Tmp1 = SelectExpr(N.getOperand(0));
|
||||||
|
Tmp2 = SelectExpr(N.getOperand(1));
|
||||||
|
if (!IM || N.getOpcode() == ISD::SUB_PARTS)
|
||||||
|
Tmp3 = SelectExpr(N.getOperand(2));
|
||||||
|
if ((!ME && !ZE) || N.getOpcode() == ISD::SUB_PARTS)
|
||||||
|
Tmp4 = SelectExpr(N.getOperand(3));
|
||||||
|
|
||||||
if (N.getOpcode() == ISD::ADD_PARTS) {
|
if (N.getOpcode() == ISD::ADD_PARTS) {
|
||||||
BuildMI(BB, PPC::ADDC, 2, Result).addReg(InVals[0]).addReg(InVals[2]);
|
// Codegen the low 32 bits of the add. Interestingly, there is no shifted
|
||||||
BuildMI(BB, PPC::ADDE, 2, Result+1).addReg(InVals[1]).addReg(InVals[3]);
|
// form of add immediate carrying.
|
||||||
|
if (IM)
|
||||||
|
BuildMI(BB, PPC::ADDIC, 2, Result).addReg(Tmp1).addSImm(Tmp3);
|
||||||
|
else
|
||||||
|
BuildMI(BB, PPC::ADDC, 2, Result).addReg(Tmp1).addReg(Tmp3);
|
||||||
|
// Codegen the high 32 bits, adding zero, minus one, or the full value
|
||||||
|
// along with the carry flag produced by addc/addic to tmp2.
|
||||||
|
if (ZE)
|
||||||
|
BuildMI(BB, PPC::ADDZE, 1, Result+1).addReg(Tmp2);
|
||||||
|
else if (ME)
|
||||||
|
BuildMI(BB, PPC::ADDME, 1, Result+1).addReg(Tmp2);
|
||||||
|
else
|
||||||
|
BuildMI(BB, PPC::ADDE, 2, Result+1).addReg(Tmp2).addReg(Tmp4);
|
||||||
} else {
|
} else {
|
||||||
BuildMI(BB, PPC::SUBFC, 2, Result).addReg(InVals[2]).addReg(InVals[0]);
|
BuildMI(BB, PPC::SUBFC, 2, Result).addReg(Tmp3).addReg(Tmp1);
|
||||||
BuildMI(BB, PPC::SUBFE, 2, Result+1).addReg(InVals[3]).addReg(InVals[1]);
|
BuildMI(BB, PPC::SUBFE, 2, Result+1).addReg(Tmp4).addReg(Tmp2);
|
||||||
}
|
}
|
||||||
return Result+N.ResNo;
|
return Result+N.ResNo;
|
||||||
}
|
}
|
||||||
@@ -1716,10 +1736,6 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) {
|
|||||||
case ISD::Constant:
|
case ISD::Constant:
|
||||||
switch (N.getValueType()) {
|
switch (N.getValueType()) {
|
||||||
default: assert(0 && "Cannot use constants of this type!");
|
default: assert(0 && "Cannot use constants of this type!");
|
||||||
case MVT::i1:
|
|
||||||
BuildMI(BB, PPC::LI, 1, Result)
|
|
||||||
.addSImm(!cast<ConstantSDNode>(N)->isNullValue());
|
|
||||||
break;
|
|
||||||
case MVT::i32:
|
case MVT::i32:
|
||||||
{
|
{
|
||||||
int v = (int)cast<ConstantSDNode>(N)->getSignExtended();
|
int v = (int)cast<ConstantSDNode>(N)->getSignExtended();
|
||||||
|
Reference in New Issue
Block a user