IR: Implement new pseudo-operation GetGEFromOp

This commit is contained in:
MerryMage 2016-12-04 20:52:06 +00:00
parent 370f654590
commit 7cad6949e7
4 changed files with 26 additions and 1 deletions

View file

@ -443,6 +443,10 @@ void EmitX64::EmitGetOverflowFromOp(IR::Block&, IR::Inst*) {
ASSERT_MSG(false, "should never happen"); ASSERT_MSG(false, "should never happen");
} }
void EmitX64::EmitGetGEFromOp(IR::Block&, IR::Inst*) {
ASSERT_MSG(false, "should never happen");
}
void EmitX64::EmitPack2x32To1x64(IR::Block&, IR::Inst* inst) { void EmitX64::EmitPack2x32To1x64(IR::Block&, IR::Inst* inst) {
OpArg lo; OpArg lo;
Xbyak::Reg64 result; Xbyak::Reg64 result;

View file

@ -232,9 +232,14 @@ Inst* Inst::GetAssociatedPseudoOperation(Opcode opcode) {
// This is faster than doing a search through the block. // This is faster than doing a search through the block.
switch (opcode) { switch (opcode) {
case IR::Opcode::GetCarryFromOp: case IR::Opcode::GetCarryFromOp:
DEBUG_ASSERT(!carry_inst || carry_inst->GetOpcode() == Opcode::GetCarryFromOp);
return carry_inst; return carry_inst;
case IR::Opcode::GetOverflowFromOp: case IR::Opcode::GetOverflowFromOp:
DEBUG_ASSERT(!overflow_inst || overflow_inst->GetOpcode() == Opcode::GetOverflowFromOp);
return overflow_inst; return overflow_inst;
case IR::Opcode::GetGEFromOp:
DEBUG_ASSERT(!ge_inst || ge_inst->GetOpcode() == Opcode::GetGEFromOp);
return ge_inst;
default: default:
break; break;
} }
@ -302,6 +307,10 @@ void Inst::Use(Value& value) {
ASSERT_MSG(!value.GetInst()->overflow_inst, "Only one of each type of pseudo-op allowed"); ASSERT_MSG(!value.GetInst()->overflow_inst, "Only one of each type of pseudo-op allowed");
value.GetInst()->overflow_inst = this; value.GetInst()->overflow_inst = this;
break; break;
case Opcode::GetGEFromOp:
ASSERT_MSG(!value.GetInst()->ge_inst, "Only one of each type of pseudo-op allowed");
value.GetInst()->ge_inst = this;
break;
default: default:
break; break;
} }
@ -312,11 +321,17 @@ void Inst::UndoUse(Value& value) {
switch (op){ switch (op){
case Opcode::GetCarryFromOp: case Opcode::GetCarryFromOp:
DEBUG_ASSERT(value.GetInst()->carry_inst->GetOpcode() == Opcode::GetCarryFromOp);
value.GetInst()->carry_inst = nullptr; value.GetInst()->carry_inst = nullptr;
break; break;
case Opcode::GetOverflowFromOp: case Opcode::GetOverflowFromOp:
DEBUG_ASSERT(value.GetInst()->overflow_inst->GetOpcode() == Opcode::GetOverflowFromOp);
value.GetInst()->overflow_inst = nullptr; value.GetInst()->overflow_inst = nullptr;
break; break;
case Opcode::GetGEFromOp:
DEBUG_ASSERT(value.GetInst()->ge_inst->GetOpcode() == Opcode::GetGEFromOp);
value.GetInst()->ge_inst = nullptr;
break;
default: default:
break; break;
} }

View file

@ -102,7 +102,12 @@ private:
size_t use_count = 0; size_t use_count = 0;
std::array<Value, 3> args; std::array<Value, 3> args;
Inst* carry_inst = nullptr; // Pointers to related pseudooperations:
// Since not all combinations are possible, we use a union to save space
union {
Inst* carry_inst = nullptr;
Inst* ge_inst;
};
Inst* overflow_inst = nullptr; Inst* overflow_inst = nullptr;
}; };

View file

@ -36,6 +36,7 @@ OPCODE(PushRSB, T::Void, T::U64
// Pseudo-operation, handled specially at final emit // Pseudo-operation, handled specially at final emit
OPCODE(GetCarryFromOp, T::U1, T::U32 ) OPCODE(GetCarryFromOp, T::U1, T::U32 )
OPCODE(GetOverflowFromOp, T::U1, T::U32 ) OPCODE(GetOverflowFromOp, T::U1, T::U32 )
OPCODE(GetGEFromOp, T::U32, T::U32 )
// Calculations // Calculations
OPCODE(Pack2x32To1x64, T::U64, T::U32, T::U32 ) OPCODE(Pack2x32To1x64, T::U64, T::U32, T::U32 )