mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2025-01-31 12:30:32 +00:00
- added missing min/max unsigned instructions for the VM.
This commit is contained in:
parent
b7d22e2b1e
commit
a42ece4fb4
4 changed files with 74 additions and 9 deletions
|
@ -5214,12 +5214,13 @@ FxMinMax::FxMinMax(TArray<FxExpression*> &expr, FName type, const FScriptPositio
|
||||||
FxExpression *FxMinMax::Resolve(FCompileContext &ctx)
|
FxExpression *FxMinMax::Resolve(FCompileContext &ctx)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
int intcount, floatcount;
|
int intcount, floatcount, uintcount;
|
||||||
|
|
||||||
CHECKRESOLVED();
|
CHECKRESOLVED();
|
||||||
|
|
||||||
// Determine if float or int
|
// Determine if float or int
|
||||||
intcount = floatcount = 0;
|
uintcount = intcount = floatcount = 0;
|
||||||
|
|
||||||
for (i = 0; i < choices.Size(); ++i)
|
for (i = 0; i < choices.Size(); ++i)
|
||||||
{
|
{
|
||||||
RESOLVE(choices[i], ctx);
|
RESOLVE(choices[i], ctx);
|
||||||
|
@ -5232,6 +5233,9 @@ FxExpression *FxMinMax::Resolve(FCompileContext &ctx)
|
||||||
else if (choices[i]->IsInteger())
|
else if (choices[i]->IsInteger())
|
||||||
{
|
{
|
||||||
intcount++;
|
intcount++;
|
||||||
|
auto type = choices[i]->ValueType;
|
||||||
|
if (type == TypeUInt32 || type == TypeUInt16 || type == TypeUInt8 || type == TypeBool) uintcount++;
|
||||||
|
else if (choices[i]->isConstant() && static_cast<FxConstant*>(choices[i])->GetValue().GetInt() > 0) uintcount++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -5258,7 +5262,7 @@ FxExpression *FxMinMax::Resolve(FCompileContext &ctx)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ValueType = TypeSInt32;
|
ValueType = uintcount == intcount? TypeUInt32 : TypeSInt32;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If at least two arguments are constants, they can be solved now.
|
// If at least two arguments are constants, they can be solved now.
|
||||||
|
@ -5364,18 +5368,20 @@ ExpEmit FxMinMax::Emit(VMFunctionBuilder *build)
|
||||||
|
|
||||||
assert(choices.Size() > 0);
|
assert(choices.Size() > 0);
|
||||||
assert(!choices[0]->isConstant());
|
assert(!choices[0]->isConstant());
|
||||||
assert(OP_MAXF_RK == OP_MAXF_RR+1);
|
static_assert(OP_MAXF_RK == OP_MAXF_RR+1, "maxf opcodes not continuous");
|
||||||
assert(OP_MAX_RK == OP_MAX_RR+1);
|
static_assert(OP_MAX_RK == OP_MAX_RR+1, "max opcodes not continuous");
|
||||||
assert(OP_MIN_RK == OP_MIN_RR+1);
|
static_assert(OP_MINF_RK == OP_MINF_RR+1, "minf opcodes not continuous");
|
||||||
assert(OP_MIN_RK == OP_MIN_RR+1);
|
static_assert(OP_MIN_RK == OP_MIN_RR+1, "min opcodes not continuous");
|
||||||
|
static_assert(OP_MAXU_RK == OP_MAXU_RR + 1, "maxu opcodes not continuous");
|
||||||
|
static_assert(OP_MINU_RK == OP_MINU_RR + 1, "minu opcodes not continuous");
|
||||||
|
|
||||||
if (Type == NAME_Min)
|
if (Type == NAME_Min)
|
||||||
{
|
{
|
||||||
opcode = ValueType->GetRegType() == REGT_FLOAT ? OP_MINF_RR : OP_MIN_RR;
|
opcode = ValueType->GetRegType() == REGT_FLOAT ? OP_MINF_RR : ValueType == TypeUInt32? OP_MINU_RR : OP_MIN_RR;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
opcode = ValueType->GetRegType() == REGT_FLOAT ? OP_MAXF_RR : OP_MAX_RR;
|
opcode = ValueType->GetRegType() == REGT_FLOAT ? OP_MAXF_RR : ValueType == TypeUInt32 ? OP_MAXU_RR : OP_MAX_RR;
|
||||||
}
|
}
|
||||||
|
|
||||||
ExpEmit firstreg = choices[0]->Emit(build);
|
ExpEmit firstreg = choices[0]->Emit(build);
|
||||||
|
|
|
@ -483,6 +483,44 @@ void JitCompiler::EmitMAX_RK()
|
||||||
cc.cmovg(regD[A], rc);
|
cc.cmovg(regD[A], rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void JitCompiler::EmitMINU_RR()
|
||||||
|
{
|
||||||
|
auto rc = CheckRegD(C, A);
|
||||||
|
if (A != B)
|
||||||
|
cc.mov(regD[A], regD[B]);
|
||||||
|
cc.cmp(rc, regD[A]);
|
||||||
|
cc.cmovb(regD[A], rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
void JitCompiler::EmitMINU_RK()
|
||||||
|
{
|
||||||
|
auto rc = newTempInt32();
|
||||||
|
if (A != B)
|
||||||
|
cc.mov(regD[A], regD[B]);
|
||||||
|
cc.mov(rc, asmjit::imm(konstd[C]));
|
||||||
|
cc.cmp(rc, regD[A]);
|
||||||
|
cc.cmovb(regD[A], rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
void JitCompiler::EmitMAXU_RR()
|
||||||
|
{
|
||||||
|
auto rc = CheckRegD(C, A);
|
||||||
|
if (A != B)
|
||||||
|
cc.mov(regD[A], regD[B]);
|
||||||
|
cc.cmp(rc, regD[A]);
|
||||||
|
cc.cmova(regD[A], rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
void JitCompiler::EmitMAXU_RK()
|
||||||
|
{
|
||||||
|
auto rc = newTempInt32();
|
||||||
|
if (A != B)
|
||||||
|
cc.mov(regD[A], regD[B]);
|
||||||
|
cc.mov(rc, asmjit::imm(konstd[C]));
|
||||||
|
cc.cmp(rc, regD[A]);
|
||||||
|
cc.cmova(regD[A], rc);
|
||||||
|
}
|
||||||
|
|
||||||
void JitCompiler::EmitABS()
|
void JitCompiler::EmitABS()
|
||||||
{
|
{
|
||||||
auto srcB = CheckRegD(B, A);
|
auto srcB = CheckRegD(B, A);
|
||||||
|
|
|
@ -1163,6 +1163,23 @@ static int ExecScriptFunc(VMFrameStack *stack, VMReturn *ret, int numret)
|
||||||
reg.d[a] = reg.d[B] > konstd[C] ? reg.d[B] : konstd[C];
|
reg.d[a] = reg.d[B] > konstd[C] ? reg.d[B] : konstd[C];
|
||||||
NEXTOP;
|
NEXTOP;
|
||||||
|
|
||||||
|
OP(MINU_RR) :
|
||||||
|
ASSERTD(a); ASSERTD(B); ASSERTD(C);
|
||||||
|
reg.d[a] = (unsigned)reg.d[B] < (unsigned)reg.d[C] ? reg.d[B] : reg.d[C];
|
||||||
|
NEXTOP;
|
||||||
|
OP(MINU_RK) :
|
||||||
|
ASSERTD(a); ASSERTD(B); ASSERTKD(C);
|
||||||
|
reg.d[a] = (unsigned)reg.d[B] < (unsigned)konstd[C] ? reg.d[B] : konstd[C];
|
||||||
|
NEXTOP;
|
||||||
|
OP(MAXU_RR) :
|
||||||
|
ASSERTD(a); ASSERTD(B); ASSERTD(C);
|
||||||
|
reg.d[a] = (unsigned)reg.d[B] > (unsigned)reg.d[C] ? reg.d[B] : reg.d[C];
|
||||||
|
NEXTOP;
|
||||||
|
OP(MAXU_RK) :
|
||||||
|
ASSERTD(a); ASSERTD(B); ASSERTKD(C);
|
||||||
|
reg.d[a] = (unsigned)reg.d[B] > (unsigned)konstd[C] ? reg.d[B] : konstd[C];
|
||||||
|
NEXTOP;
|
||||||
|
|
||||||
OP(ABS):
|
OP(ABS):
|
||||||
ASSERTD(a); ASSERTD(B);
|
ASSERTD(a); ASSERTD(B);
|
||||||
reg.d[a] = abs(reg.d[B]);
|
reg.d[a] = abs(reg.d[B]);
|
||||||
|
|
|
@ -169,6 +169,10 @@ xx(MIN_RR, min, RIRIRI, NOP, 0, 0) // dA = min(dB,dkC)
|
||||||
xx(MIN_RK, min, RIRIKI, MIN_RR, 4, REGT_INT)
|
xx(MIN_RK, min, RIRIKI, MIN_RR, 4, REGT_INT)
|
||||||
xx(MAX_RR, max, RIRIRI, NOP, 0, 0) // dA = max(dB,dkC)
|
xx(MAX_RR, max, RIRIRI, NOP, 0, 0) // dA = max(dB,dkC)
|
||||||
xx(MAX_RK, max, RIRIKI, MAX_RR, 4, REGT_INT)
|
xx(MAX_RK, max, RIRIKI, MAX_RR, 4, REGT_INT)
|
||||||
|
xx(MINU_RR, minu, RIRIRI, NOP, 0, 0) // dA = min(dB,dkC) unsigned
|
||||||
|
xx(MINU_RK, minu, RIRIKI, MIN_RR, 4, REGT_INT)
|
||||||
|
xx(MAXU_RR, maxu, RIRIRI, NOP, 0, 0) // dA = max(dB,dkC) unsigned
|
||||||
|
xx(MAXU_RK, maxu, RIRIKI, MAX_RR, 4, REGT_INT)
|
||||||
xx(ABS, abs, RIRI, NOP, 0, 0) // dA = abs(dB)
|
xx(ABS, abs, RIRI, NOP, 0, 0) // dA = abs(dB)
|
||||||
xx(NEG, neg, RIRI, NOP, 0, 0) // dA = -dB
|
xx(NEG, neg, RIRI, NOP, 0, 0) // dA = -dB
|
||||||
xx(NOT, not, RIRI, NOP, 0, 0) // dA = ~dB
|
xx(NOT, not, RIRI, NOP, 0, 0) // dA = ~dB
|
||||||
|
|
Loading…
Reference in a new issue