mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-11-11 07:12:16 +00:00
- added a boolean cast VM instruction.
Although this already helps a lot with the messed up code generated for comparisons it's not really a solution for this - it still needs a proper implementation to generate efficient code.
This commit is contained in:
parent
87484950cf
commit
7688e14bec
5 changed files with 43 additions and 21 deletions
|
@ -758,25 +758,7 @@ ExpEmit FxBoolCast::Emit(VMFunctionBuilder *build)
|
||||||
ExpEmit to(build, REGT_INT);
|
ExpEmit to(build, REGT_INT);
|
||||||
from.Free(build);
|
from.Free(build);
|
||||||
// Preload result with 0.
|
// Preload result with 0.
|
||||||
build->Emit(OP_LI, to.RegNum, 0);
|
build->Emit(OP_CASTB, to.RegNum, from.RegNum, from.RegType == REGT_INT ? CASTB_I : from.RegType == REGT_FLOAT ? CASTB_F : CASTB_A);
|
||||||
|
|
||||||
// Check source against 0.
|
|
||||||
if (from.RegType == REGT_INT)
|
|
||||||
{
|
|
||||||
build->Emit(OP_EQ_R, 1, from.RegNum, to.RegNum);
|
|
||||||
}
|
|
||||||
else if (from.RegType == REGT_FLOAT)
|
|
||||||
{
|
|
||||||
build->Emit(OP_EQF_K, 1, from.RegNum, build->GetConstantFloat(0.));
|
|
||||||
}
|
|
||||||
else if (from.RegType == REGT_POINTER)
|
|
||||||
{
|
|
||||||
build->Emit(OP_EQA_K, 1, from.RegNum, build->GetConstantAddress(nullptr, ATAG_GENERIC));
|
|
||||||
}
|
|
||||||
build->Emit(OP_JMP, 1);
|
|
||||||
|
|
||||||
// Reload result with 1 if the comparison fell through.
|
|
||||||
build->Emit(OP_LI, to.RegNum, 1);
|
|
||||||
return to;
|
return to;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -130,6 +130,11 @@ enum
|
||||||
CAST_V32S,
|
CAST_V32S,
|
||||||
CAST_SID2S,
|
CAST_SID2S,
|
||||||
CAST_TID2S,
|
CAST_TID2S,
|
||||||
|
|
||||||
|
CASTB_I,
|
||||||
|
CASTB_F,
|
||||||
|
CASTB_A,
|
||||||
|
CASTB_S
|
||||||
};
|
};
|
||||||
|
|
||||||
// Register types for VMParam
|
// Register types for VMParam
|
||||||
|
|
|
@ -90,6 +90,7 @@
|
||||||
#define THROW MODE_AIMMZ | MODE_BCTHROW
|
#define THROW MODE_AIMMZ | MODE_BCTHROW
|
||||||
#define CATCH MODE_AIMMZ | MODE_BCCATCH
|
#define CATCH MODE_AIMMZ | MODE_BCCATCH
|
||||||
#define CAST MODE_AX | MODE_BX | MODE_CIMMZ | MODE_BCCAST
|
#define CAST MODE_AX | MODE_BX | MODE_CIMMZ | MODE_BCCAST
|
||||||
|
#define CASTB MODE_AI | MODE_BX | MODE_CIMMZ | MODE_BCCAST
|
||||||
|
|
||||||
#define RSRSRS MODE_AS | MODE_BS | MODE_CS
|
#define RSRSRS MODE_AS | MODE_BS | MODE_CS
|
||||||
#define RIRS MODE_AI | MODE_BS | MODE_CUNUSED
|
#define RIRS MODE_AI | MODE_BS | MODE_CUNUSED
|
||||||
|
@ -381,10 +382,18 @@ void VMDisasm(FILE *out, const VMOP *code, int codesize, const VMScriptFunction
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
||||||
|
|
||||||
if ((mode & MODE_BCTYPE) == MODE_BCCAST)
|
if ((mode & MODE_BCTYPE) == MODE_BCCAST)
|
||||||
{
|
{
|
||||||
switch (code[i].c)
|
switch (code[i].c)
|
||||||
{
|
{
|
||||||
|
case CASTB_I:
|
||||||
|
mode = MODE_AI | MODE_BI | MODE_CUNUSED;
|
||||||
|
break;
|
||||||
|
case CASTB_A:
|
||||||
|
mode = MODE_AI | MODE_BP | MODE_CUNUSED;
|
||||||
|
break;
|
||||||
case CAST_I2F:
|
case CAST_I2F:
|
||||||
case CAST_U2F:
|
case CAST_U2F:
|
||||||
mode = MODE_AF | MODE_BI | MODE_CUNUSED;
|
mode = MODE_AF | MODE_BI | MODE_CUNUSED;
|
||||||
|
@ -398,6 +407,7 @@ void VMDisasm(FILE *out, const VMOP *code, int codesize, const VMScriptFunction
|
||||||
break;
|
break;
|
||||||
case CAST_F2I:
|
case CAST_F2I:
|
||||||
case CAST_F2U:
|
case CAST_F2U:
|
||||||
|
case CASTB_F:
|
||||||
mode = MODE_AI | MODE_BF | MODE_CUNUSED;
|
mode = MODE_AI | MODE_BF | MODE_CUNUSED;
|
||||||
break;
|
break;
|
||||||
case CAST_F2S:
|
case CAST_F2S:
|
||||||
|
@ -412,6 +422,7 @@ void VMDisasm(FILE *out, const VMOP *code, int codesize, const VMScriptFunction
|
||||||
case CAST_S2So:
|
case CAST_S2So:
|
||||||
case CAST_S2N:
|
case CAST_S2N:
|
||||||
case CAST_S2I:
|
case CAST_S2I:
|
||||||
|
case CASTB_S:
|
||||||
mode = MODE_AI | MODE_BS | MODE_CUNUSED;
|
mode = MODE_AI | MODE_BS | MODE_CUNUSED;
|
||||||
break;
|
break;
|
||||||
case CAST_S2F:
|
case CAST_S2F:
|
||||||
|
|
|
@ -419,12 +419,12 @@ begin:
|
||||||
if (C == CAST_I2F)
|
if (C == CAST_I2F)
|
||||||
{
|
{
|
||||||
ASSERTF(a); ASSERTD(B);
|
ASSERTF(a); ASSERTD(B);
|
||||||
reg.f[A] = reg.d[B];
|
reg.f[a] = reg.d[B];
|
||||||
}
|
}
|
||||||
else if (C == CAST_F2I)
|
else if (C == CAST_F2I)
|
||||||
{
|
{
|
||||||
ASSERTD(a); ASSERTF(B);
|
ASSERTD(a); ASSERTF(B);
|
||||||
reg.d[A] = (int)reg.f[B];
|
reg.d[a] = (int)reg.f[B];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -432,6 +432,29 @@ begin:
|
||||||
}
|
}
|
||||||
NEXTOP;
|
NEXTOP;
|
||||||
|
|
||||||
|
OP(CASTB):
|
||||||
|
if (C == CASTB_I)
|
||||||
|
{
|
||||||
|
ASSERTD(a); ASSERTD(B);
|
||||||
|
reg.f[a] = !!reg.d[B];
|
||||||
|
}
|
||||||
|
else if (C == CASTB_F)
|
||||||
|
{
|
||||||
|
ASSERTD(a); ASSERTF(B);
|
||||||
|
reg.d[a] = reg.f[B] != 0;
|
||||||
|
}
|
||||||
|
else if (c == CASTB_A)
|
||||||
|
{
|
||||||
|
ASSERTD(a); ASSERTA(B);
|
||||||
|
reg.d[a] = reg.a[B] != nullptr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ASSERTD(a); ASSERTS(B);
|
||||||
|
reg.d[a] = reg.s[B].Len() > 0;
|
||||||
|
}
|
||||||
|
NEXTOP;
|
||||||
|
|
||||||
OP(TEST):
|
OP(TEST):
|
||||||
ASSERTD(a);
|
ASSERTD(a);
|
||||||
if (reg.d[a] != BC)
|
if (reg.d[a] != BC)
|
||||||
|
|
|
@ -83,6 +83,7 @@ xx(MOVEA, mov, RPRP, NOP, 0, 0), // aA = aB
|
||||||
xx(MOVEV2, mov2, RFRF, NOP, 0, 0), // fA = fB (2 elements)
|
xx(MOVEV2, mov2, RFRF, NOP, 0, 0), // fA = fB (2 elements)
|
||||||
xx(MOVEV3, mov3, RFRF, NOP, 0, 0), // fA = fB (3 elements)
|
xx(MOVEV3, mov3, RFRF, NOP, 0, 0), // fA = fB (3 elements)
|
||||||
xx(CAST, cast, CAST, NOP, 0, 0), // xA = xB, conversion specified by C
|
xx(CAST, cast, CAST, NOP, 0, 0), // xA = xB, conversion specified by C
|
||||||
|
xx(CASTB, castb, CAST, NOP, 0, 0), // xA = !!xB, type specified by C
|
||||||
|
|
||||||
// Control flow.
|
// Control flow.
|
||||||
xx(TEST, test, RII16, NOP, 0, 0), // if (dA != BC) then pc++
|
xx(TEST, test, RII16, NOP, 0, 0), // if (dA != BC) then pc++
|
||||||
|
|
Loading…
Reference in a new issue