mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-14 17:34:41 +00:00
Implement setcc on longs.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@18088 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
4351857d78
commit
c7b4f1033f
@ -1270,27 +1270,41 @@ void V8ISel::visitSetCondInst(SetCondInst &I) {
|
|||||||
if (getClass (Ty) < cLong) {
|
if (getClass (Ty) < cLong) {
|
||||||
BuildMI(BB, V8::SUBCCrr, 2, V8::G0).addReg(Op0Reg).addReg(Op1Reg);
|
BuildMI(BB, V8::SUBCCrr, 2, V8::G0).addReg(Op0Reg).addReg(Op1Reg);
|
||||||
} else if (getClass (Ty) == cLong) {
|
} else if (getClass (Ty) == cLong) {
|
||||||
// Here is one way to open-code each of the setccs for SIGNED longs...
|
switch (I.getOpcode()) {
|
||||||
// I haven't checked it yet, but you *should* be able to just switch
|
default: assert(0 && "Unknown setcc instruction!");
|
||||||
// bl/bg/ble/bge with bcs/bgu/bleu/bcc to get the version for
|
case Instruction::SetEQ:
|
||||||
// unsigned longs.
|
case Instruction::SetNE: {
|
||||||
// setlt/setge subcc %left_1, %right_1, %g0
|
unsigned TempReg0 = makeAnotherReg (Type::IntTy),
|
||||||
// ^^^^^^^^^^^ subxcc %left_0, %right_0, %g0
|
TempReg1 = makeAnotherReg (Type::IntTy),
|
||||||
// bl/bge (as with ordinary setcc)
|
TempReg2 = makeAnotherReg (Type::IntTy),
|
||||||
// setle/setgt subcc %g0, 1, %g0
|
TempReg3 = makeAnotherReg (Type::IntTy);
|
||||||
// ^^^^^^^^^^^ subxcc %left_1, %right_1, %g0
|
MachineOpCode Opcode;
|
||||||
// subxcc %left_0, %right_0, %g0
|
int Immed;
|
||||||
// ble/bg (as with ordinary setcc)
|
// These guys are special - no branches needed!
|
||||||
// seteq/setne xor %left_1, %right_1, %temp_0
|
BuildMI (BB, V8::XORrr, 2, TempReg0).addReg (Op0Reg+1).addReg (Op1Reg+1);
|
||||||
// ^^^^^^^^^^^ xor %left_0, %right_0, %temp_1
|
BuildMI (BB, V8::XORrr, 2, TempReg1).addReg (Op0Reg).addReg (Op1Reg);
|
||||||
// subcc %g0, %temp_1, %g0
|
BuildMI (BB, V8::SUBCCrr, 2, V8::G0).addReg (V8::G0).addReg (TempReg1);
|
||||||
// seteq setne
|
Opcode = I.getOpcode() == Instruction::SetEQ ? V8::SUBXri : V8::ADDXri;
|
||||||
// ^^^^^ ^^^^^
|
Immed = I.getOpcode() == Instruction::SetEQ ? -1 : 0;
|
||||||
// subx %g0, -1, %temp_2 addx %g0, 0, %temp_2
|
BuildMI (BB, Opcode, 2, TempReg2).addReg (V8::G0).addSImm (Immed);
|
||||||
// subcc %g0, %temp_0, %g0
|
BuildMI (BB, V8::SUBCCrr, 2, V8::G0).addReg (V8::G0).addReg (TempReg0);
|
||||||
// subx %g0, -1, %temp_3 addx %g0, 0, %temp_3
|
BuildMI (BB, Opcode, 2, TempReg3).addReg (V8::G0).addSImm (Immed);
|
||||||
// and %temp_2, %temp_3, %result or %temp_2, %temp_3, %result
|
Opcode = I.getOpcode() == Instruction::SetEQ ? V8::ANDrr : V8::ORrr;
|
||||||
assert (0 && "can't setcc on longs yet");
|
BuildMI (BB, Opcode, 2, DestReg).addReg (TempReg2).addReg (TempReg3);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case Instruction::SetLT:
|
||||||
|
case Instruction::SetGE:
|
||||||
|
BuildMI (BB, V8::SUBCCrr, 2, V8::G0).addReg (Op0Reg+1).addReg (Op1Reg+1);
|
||||||
|
BuildMI (BB, V8::SUBXCCrr, 2, V8::G0).addReg (Op0Reg).addReg (Op1Reg);
|
||||||
|
break;
|
||||||
|
case Instruction::SetGT:
|
||||||
|
case Instruction::SetLE:
|
||||||
|
BuildMI (BB, V8::SUBCCri, 2, V8::G0).addReg (V8::G0).addSImm (1);
|
||||||
|
BuildMI (BB, V8::SUBXCCrr, 2, V8::G0).addReg (Op0Reg+1).addReg (Op1Reg+1);
|
||||||
|
BuildMI (BB, V8::SUBXCCrr, 2, V8::G0).addReg (Op0Reg).addReg (Op1Reg);
|
||||||
|
break;
|
||||||
|
}
|
||||||
} else if (getClass (Ty) == cFloat) {
|
} else if (getClass (Ty) == cFloat) {
|
||||||
BuildMI(BB, V8::FCMPS, 2).addReg(Op0Reg).addReg(Op1Reg);
|
BuildMI(BB, V8::FCMPS, 2).addReg(Op0Reg).addReg(Op1Reg);
|
||||||
} else if (getClass (Ty) == cDouble) {
|
} else if (getClass (Ty) == cDouble) {
|
||||||
@ -1307,6 +1321,7 @@ void V8ISel::visitSetCondInst(SetCondInst &I) {
|
|||||||
case Instruction::SetLE: BranchIdx = 4; break;
|
case Instruction::SetLE: BranchIdx = 4; break;
|
||||||
case Instruction::SetGE: BranchIdx = 5; break;
|
case Instruction::SetGE: BranchIdx = 5; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned Column = 0;
|
unsigned Column = 0;
|
||||||
if (Ty->isSigned() && !Ty->isFloatingPoint()) Column = 1;
|
if (Ty->isSigned() && !Ty->isFloatingPoint()) Column = 1;
|
||||||
if (Ty->isFloatingPoint()) Column = 2;
|
if (Ty->isFloatingPoint()) Column = 2;
|
||||||
|
@ -1270,27 +1270,41 @@ void V8ISel::visitSetCondInst(SetCondInst &I) {
|
|||||||
if (getClass (Ty) < cLong) {
|
if (getClass (Ty) < cLong) {
|
||||||
BuildMI(BB, V8::SUBCCrr, 2, V8::G0).addReg(Op0Reg).addReg(Op1Reg);
|
BuildMI(BB, V8::SUBCCrr, 2, V8::G0).addReg(Op0Reg).addReg(Op1Reg);
|
||||||
} else if (getClass (Ty) == cLong) {
|
} else if (getClass (Ty) == cLong) {
|
||||||
// Here is one way to open-code each of the setccs for SIGNED longs...
|
switch (I.getOpcode()) {
|
||||||
// I haven't checked it yet, but you *should* be able to just switch
|
default: assert(0 && "Unknown setcc instruction!");
|
||||||
// bl/bg/ble/bge with bcs/bgu/bleu/bcc to get the version for
|
case Instruction::SetEQ:
|
||||||
// unsigned longs.
|
case Instruction::SetNE: {
|
||||||
// setlt/setge subcc %left_1, %right_1, %g0
|
unsigned TempReg0 = makeAnotherReg (Type::IntTy),
|
||||||
// ^^^^^^^^^^^ subxcc %left_0, %right_0, %g0
|
TempReg1 = makeAnotherReg (Type::IntTy),
|
||||||
// bl/bge (as with ordinary setcc)
|
TempReg2 = makeAnotherReg (Type::IntTy),
|
||||||
// setle/setgt subcc %g0, 1, %g0
|
TempReg3 = makeAnotherReg (Type::IntTy);
|
||||||
// ^^^^^^^^^^^ subxcc %left_1, %right_1, %g0
|
MachineOpCode Opcode;
|
||||||
// subxcc %left_0, %right_0, %g0
|
int Immed;
|
||||||
// ble/bg (as with ordinary setcc)
|
// These guys are special - no branches needed!
|
||||||
// seteq/setne xor %left_1, %right_1, %temp_0
|
BuildMI (BB, V8::XORrr, 2, TempReg0).addReg (Op0Reg+1).addReg (Op1Reg+1);
|
||||||
// ^^^^^^^^^^^ xor %left_0, %right_0, %temp_1
|
BuildMI (BB, V8::XORrr, 2, TempReg1).addReg (Op0Reg).addReg (Op1Reg);
|
||||||
// subcc %g0, %temp_1, %g0
|
BuildMI (BB, V8::SUBCCrr, 2, V8::G0).addReg (V8::G0).addReg (TempReg1);
|
||||||
// seteq setne
|
Opcode = I.getOpcode() == Instruction::SetEQ ? V8::SUBXri : V8::ADDXri;
|
||||||
// ^^^^^ ^^^^^
|
Immed = I.getOpcode() == Instruction::SetEQ ? -1 : 0;
|
||||||
// subx %g0, -1, %temp_2 addx %g0, 0, %temp_2
|
BuildMI (BB, Opcode, 2, TempReg2).addReg (V8::G0).addSImm (Immed);
|
||||||
// subcc %g0, %temp_0, %g0
|
BuildMI (BB, V8::SUBCCrr, 2, V8::G0).addReg (V8::G0).addReg (TempReg0);
|
||||||
// subx %g0, -1, %temp_3 addx %g0, 0, %temp_3
|
BuildMI (BB, Opcode, 2, TempReg3).addReg (V8::G0).addSImm (Immed);
|
||||||
// and %temp_2, %temp_3, %result or %temp_2, %temp_3, %result
|
Opcode = I.getOpcode() == Instruction::SetEQ ? V8::ANDrr : V8::ORrr;
|
||||||
assert (0 && "can't setcc on longs yet");
|
BuildMI (BB, Opcode, 2, DestReg).addReg (TempReg2).addReg (TempReg3);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case Instruction::SetLT:
|
||||||
|
case Instruction::SetGE:
|
||||||
|
BuildMI (BB, V8::SUBCCrr, 2, V8::G0).addReg (Op0Reg+1).addReg (Op1Reg+1);
|
||||||
|
BuildMI (BB, V8::SUBXCCrr, 2, V8::G0).addReg (Op0Reg).addReg (Op1Reg);
|
||||||
|
break;
|
||||||
|
case Instruction::SetGT:
|
||||||
|
case Instruction::SetLE:
|
||||||
|
BuildMI (BB, V8::SUBCCri, 2, V8::G0).addReg (V8::G0).addSImm (1);
|
||||||
|
BuildMI (BB, V8::SUBXCCrr, 2, V8::G0).addReg (Op0Reg+1).addReg (Op1Reg+1);
|
||||||
|
BuildMI (BB, V8::SUBXCCrr, 2, V8::G0).addReg (Op0Reg).addReg (Op1Reg);
|
||||||
|
break;
|
||||||
|
}
|
||||||
} else if (getClass (Ty) == cFloat) {
|
} else if (getClass (Ty) == cFloat) {
|
||||||
BuildMI(BB, V8::FCMPS, 2).addReg(Op0Reg).addReg(Op1Reg);
|
BuildMI(BB, V8::FCMPS, 2).addReg(Op0Reg).addReg(Op1Reg);
|
||||||
} else if (getClass (Ty) == cDouble) {
|
} else if (getClass (Ty) == cDouble) {
|
||||||
@ -1307,6 +1321,7 @@ void V8ISel::visitSetCondInst(SetCondInst &I) {
|
|||||||
case Instruction::SetLE: BranchIdx = 4; break;
|
case Instruction::SetLE: BranchIdx = 4; break;
|
||||||
case Instruction::SetGE: BranchIdx = 5; break;
|
case Instruction::SetGE: BranchIdx = 5; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned Column = 0;
|
unsigned Column = 0;
|
||||||
if (Ty->isSigned() && !Ty->isFloatingPoint()) Column = 1;
|
if (Ty->isSigned() && !Ty->isFloatingPoint()) Column = 1;
|
||||||
if (Ty->isFloatingPoint()) Column = 2;
|
if (Ty->isFloatingPoint()) Column = 2;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user