mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-28 23:12:24 +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);
|
||||
from.Free(build);
|
||||
// Preload result with 0.
|
||||
build->Emit(OP_LI, to.RegNum, 0);
|
||||
|
||||
// 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);
|
||||
build->Emit(OP_CASTB, to.RegNum, from.RegNum, from.RegType == REGT_INT ? CASTB_I : from.RegType == REGT_FLOAT ? CASTB_F : CASTB_A);
|
||||
return to;
|
||||
}
|
||||
else
|
||||
|
|
|
@ -130,6 +130,11 @@ enum
|
|||
CAST_V32S,
|
||||
CAST_SID2S,
|
||||
CAST_TID2S,
|
||||
|
||||
CASTB_I,
|
||||
CASTB_F,
|
||||
CASTB_A,
|
||||
CASTB_S
|
||||
};
|
||||
|
||||
// Register types for VMParam
|
||||
|
|
|
@ -90,6 +90,7 @@
|
|||
#define THROW MODE_AIMMZ | MODE_BCTHROW
|
||||
#define CATCH MODE_AIMMZ | MODE_BCCATCH
|
||||
#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 RIRS MODE_AI | MODE_BS | MODE_CUNUSED
|
||||
|
@ -381,10 +382,18 @@ void VMDisasm(FILE *out, const VMOP *code, int codesize, const VMScriptFunction
|
|||
break;
|
||||
|
||||
default:
|
||||
|
||||
|
||||
if ((mode & MODE_BCTYPE) == MODE_BCCAST)
|
||||
{
|
||||
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_U2F:
|
||||
mode = MODE_AF | MODE_BI | MODE_CUNUSED;
|
||||
|
@ -398,6 +407,7 @@ void VMDisasm(FILE *out, const VMOP *code, int codesize, const VMScriptFunction
|
|||
break;
|
||||
case CAST_F2I:
|
||||
case CAST_F2U:
|
||||
case CASTB_F:
|
||||
mode = MODE_AI | MODE_BF | MODE_CUNUSED;
|
||||
break;
|
||||
case CAST_F2S:
|
||||
|
@ -412,6 +422,7 @@ void VMDisasm(FILE *out, const VMOP *code, int codesize, const VMScriptFunction
|
|||
case CAST_S2So:
|
||||
case CAST_S2N:
|
||||
case CAST_S2I:
|
||||
case CASTB_S:
|
||||
mode = MODE_AI | MODE_BS | MODE_CUNUSED;
|
||||
break;
|
||||
case CAST_S2F:
|
||||
|
|
|
@ -419,12 +419,12 @@ begin:
|
|||
if (C == CAST_I2F)
|
||||
{
|
||||
ASSERTF(a); ASSERTD(B);
|
||||
reg.f[A] = reg.d[B];
|
||||
reg.f[a] = reg.d[B];
|
||||
}
|
||||
else if (C == CAST_F2I)
|
||||
{
|
||||
ASSERTD(a); ASSERTF(B);
|
||||
reg.d[A] = (int)reg.f[B];
|
||||
reg.d[a] = (int)reg.f[B];
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -432,6 +432,29 @@ begin:
|
|||
}
|
||||
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):
|
||||
ASSERTD(a);
|
||||
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(MOVEV3, mov3, RFRF, NOP, 0, 0), // fA = fB (3 elements)
|
||||
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.
|
||||
xx(TEST, test, RII16, NOP, 0, 0), // if (dA != BC) then pc++
|
||||
|
|
Loading…
Reference in a new issue