diff --git a/src/thingdef/thingdef_expression.cpp b/src/thingdef/thingdef_expression.cpp index 7c68d99b5..7aa7b8d34 100644 --- a/src/thingdef/thingdef_expression.cpp +++ b/src/thingdef/thingdef_expression.cpp @@ -3995,7 +3995,7 @@ ExpEmit FxDamageValue::Emit(VMFunctionBuilder *build) assert(emitval.RegType == REGT_INT); build->Emit(OP_RET, 0, REGT_INT | (emitval.Konst ? REGT_KONST : 0), emitval.RegNum); } - build->Emit(OP_RETI, 1, 0x8000 | (int)Calculated); + build->Emit(OP_RETI, 1 | RET_FINAL, Calculated); return ExpEmit(); } diff --git a/src/zscript/vm.h b/src/zscript/vm.h index 256578a8e..2d87b7209 100644 --- a/src/zscript/vm.h +++ b/src/zscript/vm.h @@ -119,12 +119,14 @@ enum REGT_KONST = 4, REGT_MULTIREG = 8, // (e.g. a vector) - REGT_FINAL = 16, // used with RET: this is the final return value REGT_ADDROF = 32, // used with PARAM: pass address of this register REGT_NIL = 255 // parameter was omitted }; +#define RET_FINAL (0x80) // Used with RET and RETI in the destination slot: this is the final return value + + // Tags for address registers enum { diff --git a/src/zscript/vmbuilder.cpp b/src/zscript/vmbuilder.cpp index 78051d816..c87ff636a 100644 --- a/src/zscript/vmbuilder.cpp +++ b/src/zscript/vmbuilder.cpp @@ -501,13 +501,14 @@ size_t VMFunctionBuilder::EmitLoadInt(int regnum, int value) size_t VMFunctionBuilder::EmitRetInt(int retnum, bool final, int value) { - if (value >= -16384 && value <= 16383) + assert(retnum >= 0 && retnum <= 127); + if (value >= -32768 && value <= 32767) { - return Emit(OP_RETI, retnum, value | (final << 15)); + return Emit(OP_RETI, retnum | (final << 7), value); } else { - return Emit(OP_RETI, retnum, REGT_INT | REGT_KONST | (final ? REGT_FINAL : 0), GetConstantInt(value)); + return Emit(OP_RET, retnum | (final << 7), REGT_INT | REGT_KONST, GetConstantInt(value)); } } diff --git a/src/zscript/vmdisasm.cpp b/src/zscript/vmdisasm.cpp index 77abf9d12..d2e87956d 100644 --- a/src/zscript/vmdisasm.cpp +++ b/src/zscript/vmdisasm.cpp @@ -231,15 +231,15 @@ void VMDisasm(FILE *out, const VMOP *code, int codesize, const VMScriptFunction case OP_RET: if (code[i].b != REGT_NIL) { - if ((code[i].b & REGT_FINAL) && a == 0) + if (a == RET_FINAL) { col = print_reg(out, 0, code[i].i16u, MODE_PARAM, 16, func); } else { - col = print_reg(out, 0, a, (mode & MODE_ATYPE) >> MODE_ASHIFT, 24, func); + col = print_reg(out, 0, a & ~RET_FINAL, (mode & MODE_ATYPE) >> MODE_ASHIFT, 24, func); col += print_reg(out, col, code[i].i16u, MODE_PARAM, 16, func); - if (code[i].b & REGT_FINAL) + if (a & RET_FINAL) { col += printf_wrapper(out, " [final]"); } @@ -248,15 +248,15 @@ void VMDisasm(FILE *out, const VMOP *code, int codesize, const VMScriptFunction break; case OP_RETI: - if (a == 0 && code[i].i16 & 0x8000) + if (a == RET_FINAL) { - col = printf_wrapper(out, "%d", (code[i].i16 << 17) >> 17); + col = printf_wrapper(out, "%d", code[i].i16); } else { - col = print_reg(out, 0, a, (mode & MODE_ATYPE) >> MODE_ASHIFT, 24, func); - col += print_reg(out, col, (code[i].i16 << 17) >> 17, MODE_IMMS, 16, func); - if (code[i].i16 & 0x8000) + col = print_reg(out, 0, a & ~RET_FINAL, (mode & MODE_ATYPE) >> MODE_ASHIFT, 24, func); + col += print_reg(out, col, code[i].i16, MODE_IMMS, 16, func); + if (a & RET_FINAL) { col += printf_wrapper(out, " [final]"); } diff --git a/src/zscript/vmexec.h b/src/zscript/vmexec.h index a1a22a964..e901e5f03 100644 --- a/src/zscript/vmexec.h +++ b/src/zscript/vmexec.h @@ -584,25 +584,30 @@ begin: return 0; } assert(ret != NULL || numret == 0); - if (a < numret) { - SetReturn(reg, f, &ret[a], B, C); - } - if (B & REGT_FINAL) - { - return a < numret ? a + 1 : numret; + int retnum = a & ~RET_FINAL; + if (retnum < numret) + { + SetReturn(reg, f, &ret[retnum], B, C); + } + if (a & RET_FINAL) + { + return retnum < numret ? retnum + 1 : numret; + } } NEXTOP; OP(RETI): assert(ret != NULL || numret == 0); - if (a < numret) { - // Shifting by 17 to wipe out the final bit - ret[a].SetInt(((pc[-1].i16) << 17) >> 17); - } - if (pc[-1].i16 & 0x8000) - { - return a < numret ? a + 1 : numret; + int retnum = a & ~RET_FINAL; + if (retnum < numret) + { + ret[retnum].SetInt(BCs); + } + if (a & RET_FINAL) + { + return retnum < numret ? retnum + 1 : numret; + } } NEXTOP; OP(RESULT): @@ -1490,7 +1495,7 @@ static void SetReturn(const VMRegisters ®, VMFrame *frame, VMReturn *ret, VM_ VMScriptFunction *func = static_cast(frame->Func); assert(func != NULL && !func->Native); - assert((regtype & ~(REGT_KONST | REGT_FINAL)) == ret->RegType); + assert((regtype & ~REGT_KONST) == ret->RegType); switch (regtype & REGT_TYPE) {