IR: Implement new pseudo-operation GetGEFromOp
This commit is contained in:
parent
370f654590
commit
7cad6949e7
4 changed files with 26 additions and 1 deletions
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
// Pointers to related pseudooperations:
|
||||||
|
// Since not all combinations are possible, we use a union to save space
|
||||||
|
union {
|
||||||
Inst* carry_inst = nullptr;
|
Inst* carry_inst = nullptr;
|
||||||
|
Inst* ge_inst;
|
||||||
|
};
|
||||||
Inst* overflow_inst = nullptr;
|
Inst* overflow_inst = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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 )
|
||||||
|
|
Loading…
Reference in a new issue