From 7137e87b4b709fcc2675b7fef3d0c36b96e3b47f Mon Sep 17 00:00:00 2001 From: Edoardo Prezioso Date: Sun, 30 Oct 2016 13:43:20 +0100 Subject: [PATCH 1/4] - Fixed GCC/Clang errors from recent commits. --- src/scripting/codegeneration/codegen.cpp | 28 ++++++++++++++---------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/src/scripting/codegeneration/codegen.cpp b/src/scripting/codegeneration/codegen.cpp index fa5405c601..f1dfab523c 100644 --- a/src/scripting/codegeneration/codegen.cpp +++ b/src/scripting/codegeneration/codegen.cpp @@ -563,8 +563,10 @@ ExpEmit FxVectorValue::Emit(VMFunctionBuilder *build) assert(xyz[1] != nullptr); if (ValueType == TypeVector2) { - ExpEmit xval = EmitKonst(build, xyz[0]->Emit(build)); - ExpEmit yval = EmitKonst(build, xyz[1]->Emit(build)); + ExpEmit tempxval = xyz[0]->Emit(build); + ExpEmit tempyval = xyz[1]->Emit(build); + ExpEmit xval = EmitKonst(build, tempxval); + ExpEmit yval = EmitKonst(build, tempyval); assert(xval.RegType == REGT_FLOAT && yval.RegType == REGT_FLOAT); if (yval.RegNum == xval.RegNum + 1) { @@ -586,7 +588,8 @@ ExpEmit FxVectorValue::Emit(VMFunctionBuilder *build) else if (xyz[0]->ValueType == TypeVector2) // vec2+float { ExpEmit xyval = xyz[0]->Emit(build); - ExpEmit zval = EmitKonst(build, xyz[1]->Emit(build)); + ExpEmit tempzval = xyz[1]->Emit(build); + ExpEmit zval = EmitKonst(build, tempzval); assert(xyval.RegType == REGT_FLOAT && xyval.RegCount == 2 && zval.RegType == REGT_FLOAT); if (zval.RegNum == xyval.RegNum + 2) { @@ -608,9 +611,12 @@ ExpEmit FxVectorValue::Emit(VMFunctionBuilder *build) else // 3*float { assert(xyz[2] != nullptr); - ExpEmit xval = EmitKonst(build, xyz[0]->Emit(build)); - ExpEmit yval = EmitKonst(build, xyz[1]->Emit(build)); - ExpEmit zval = EmitKonst(build, xyz[2]->Emit(build)); + ExpEmit tempxval = xyz[0]->Emit(build); + ExpEmit tempyval = xyz[1]->Emit(build); + ExpEmit tempzval = xyz[2]->Emit(build); + ExpEmit xval = EmitKonst(build, tempxval); + ExpEmit yval = EmitKonst(build, tempyval); + ExpEmit zval = EmitKonst(build, tempzval); assert(xval.RegType == REGT_FLOAT && yval.RegType == REGT_FLOAT && zval.RegType == REGT_FLOAT); if (yval.RegNum == xval.RegNum + 1 && zval.RegNum == xval.RegNum + 2) { @@ -2308,7 +2314,7 @@ bool FxBinary::ResolveLR(FCompileContext& ctx, bool castnumeric) if (left == nullptr) { delete this; - return nullptr; + return false; } } if (right->ValueType != TypeString) @@ -2318,7 +2324,7 @@ bool FxBinary::ResolveLR(FCompileContext& ctx, bool castnumeric) if (right == nullptr) { delete this; - return nullptr; + return false; } } ValueType = TypeBool; @@ -2464,7 +2470,7 @@ bool FxBinary::ResolveLR(FCompileContext& ctx, bool castnumeric) delete this; return false; } - assert(ValueType > nullptr && ValueType < (PType*)0xfffffffffffffff); + assert(ValueType != nullptr && ValueType < (PType*)0xfffffffffffffff); if (castnumeric) { @@ -3206,7 +3212,7 @@ ExpEmit FxCompareEq::Emit(VMFunctionBuilder *build) // See FxUnaryNotBoolean for comments, since it's the same thing. build->Emit(OP_LI, to.RegNum, 0, 0); - build->Emit(instr, Operator == TK_ApproxEq ? CMP_APPROX : Operator != TK_Eq, op1.RegNum, op2.RegNum); + build->Emit(instr, Operator == TK_ApproxEq ? CMP_APPROX : ((Operator != TK_Eq) ? CMP_CHECK : 0), op1.RegNum, op2.RegNum); build->Emit(OP_JMP, 1); build->Emit(OP_LI, to.RegNum, 1); return to; @@ -3925,7 +3931,7 @@ FxExpression *FxConditional::Resolve(FCompileContext& ctx) { ScriptPosition.Message(MSG_ERROR, "Incompatible types for ?: operator"); delete this; - return false; + return nullptr; } if (condition->ValueType != TypeBool) From 88fd47247d41fc3a46f5f41f060591b3f773003a Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 1 Nov 2016 16:32:47 +0100 Subject: [PATCH 2/4] - scriptified several trivial functions from a_action.cpp. --- src/g_shared/a_action.cpp | 223 -------------------------------- src/p_mobj.cpp | 7 + src/scripting/thingdef_data.cpp | 1 + wadsrc/static/zscript/actor.txt | 35 +++-- 4 files changed, 25 insertions(+), 241 deletions(-) diff --git a/src/g_shared/a_action.cpp b/src/g_shared/a_action.cpp index abd58dec11..0ec388de85 100644 --- a/src/g_shared/a_action.cpp +++ b/src/g_shared/a_action.cpp @@ -109,71 +109,6 @@ DEFINE_ACTION_FUNCTION(AActor, A_NoBlocking) return 0; } -DEFINE_ACTION_FUNCTION(AActor, A_Fall) -{ - PARAM_SELF_PROLOGUE(AActor); - A_Unblock(self, true); - return 0; -} - -//========================================================================== -// -// A_SetFloorClip -// -//========================================================================== - -DEFINE_ACTION_FUNCTION(AActor, A_SetFloorClip) -{ - PARAM_SELF_PROLOGUE(AActor); - - self->flags2 |= MF2_FLOORCLIP; - self->AdjustFloorClip (); - return 0; -} - -//========================================================================== -// -// A_UnSetFloorClip -// -//========================================================================== - -DEFINE_ACTION_FUNCTION(AActor, A_UnSetFloorClip) -{ - PARAM_SELF_PROLOGUE(AActor); - - self->flags2 &= ~MF2_FLOORCLIP; - self->Floorclip = 0; - return 0; -} - -//========================================================================== -// -// A_HideThing -// -//========================================================================== - -DEFINE_ACTION_FUNCTION(AActor, A_HideThing) -{ - PARAM_SELF_PROLOGUE(AActor); - - self->renderflags |= RF_INVISIBLE; - return 0; -} - -//========================================================================== -// -// A_UnHideThing -// -//========================================================================== - -DEFINE_ACTION_FUNCTION(AActor, A_UnHideThing) -{ - PARAM_SELF_PROLOGUE(AActor); - - self->renderflags &= ~RF_INVISIBLE; - return 0; -} - //============================================================================ // // A_FreezeDeath @@ -475,164 +410,6 @@ DEFINE_ACTION_FUNCTION(AActor, A_DeQueueCorpse) return 0; } -//============================================================================ -// -// A_SetInvulnerable -// -//============================================================================ - -DEFINE_ACTION_FUNCTION(AActor, A_SetInvulnerable) -{ - PARAM_SELF_PROLOGUE(AActor); - - self->flags2 |= MF2_INVULNERABLE; - return 0; -} - -//============================================================================ -// -// A_UnSetInvulnerable -// -//============================================================================ - -DEFINE_ACTION_FUNCTION(AActor, A_UnSetInvulnerable) -{ - PARAM_SELF_PROLOGUE(AActor); - - self->flags2 &= ~MF2_INVULNERABLE; - return 0; -} - -//============================================================================ -// -// A_SetReflective -// -//============================================================================ - -DEFINE_ACTION_FUNCTION(AActor, A_SetReflective) -{ - PARAM_SELF_PROLOGUE(AActor); - - self->flags2 |= MF2_REFLECTIVE; - return 0; -} - -//============================================================================ -// -// A_UnSetReflective -// -//============================================================================ - -DEFINE_ACTION_FUNCTION(AActor, A_UnSetReflective) -{ - PARAM_SELF_PROLOGUE(AActor); - - self->flags2 &= ~MF2_REFLECTIVE; - return 0; -} - -//============================================================================ -// -// A_SetReflectiveInvulnerable -// -//============================================================================ - -DEFINE_ACTION_FUNCTION(AActor, A_SetReflectiveInvulnerable) -{ - PARAM_SELF_PROLOGUE(AActor); - - self->flags2 |= MF2_REFLECTIVE|MF2_INVULNERABLE; - return 0; -} - -//============================================================================ -// -// A_UnSetReflectiveInvulnerable -// -//============================================================================ - -DEFINE_ACTION_FUNCTION(AActor, A_UnSetReflectiveInvulnerable) -{ - PARAM_SELF_PROLOGUE(AActor); - - self->flags2 &= ~(MF2_REFLECTIVE|MF2_INVULNERABLE); - return 0; -} - -//========================================================================== -// -// A_SetShootable -// -//========================================================================== - -DEFINE_ACTION_FUNCTION(AActor, A_SetShootable) -{ - PARAM_SELF_PROLOGUE(AActor); - - self->flags2 &= ~MF2_NONSHOOTABLE; - self->flags |= MF_SHOOTABLE; - return 0; -} - -//========================================================================== -// -// A_UnSetShootable -// -//========================================================================== - -DEFINE_ACTION_FUNCTION(AActor, A_UnSetShootable) -{ - PARAM_SELF_PROLOGUE(AActor); - - self->flags2 |= MF2_NONSHOOTABLE; - self->flags &= ~MF_SHOOTABLE; - return 0; -} - -//=========================================================================== -// -// A_NoGravity -// -//=========================================================================== - -DEFINE_ACTION_FUNCTION(AActor, A_NoGravity) -{ - PARAM_SELF_PROLOGUE(AActor); - - self->flags |= MF_NOGRAVITY; - return 0; -} - -//=========================================================================== -// -// A_Gravity -// -//=========================================================================== - -DEFINE_ACTION_FUNCTION(AActor, A_Gravity) -{ - PARAM_SELF_PROLOGUE(AActor); - - self->flags &= ~MF_NOGRAVITY; - self->Gravity = 1; - return 0; -} - -//=========================================================================== -// -// A_LowGravity -// -//=========================================================================== - -DEFINE_ACTION_FUNCTION(AActor, A_LowGravity) -{ - PARAM_SELF_PROLOGUE(AActor); - - self->flags &= ~MF_NOGRAVITY; - self->Gravity = 1. / 8;; - return 0; -} - //=========================================================================== // // FaceMovementDirection diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index f597b89c27..bd78fdcef4 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -4509,6 +4509,13 @@ void AActor::AdjustFloorClip () } } +DEFINE_ACTION_FUNCTION(AActor, AdjustFloorClip) +{ + PARAM_SELF_PROLOGUE(AActor); + self->AdjustFloorClip(); + return 0; +} + // // P_SpawnPlayer // Called when a player is spawned on the level. diff --git a/src/scripting/thingdef_data.cpp b/src/scripting/thingdef_data.cpp index c623290daf..b0edcb167f 100644 --- a/src/scripting/thingdef_data.cpp +++ b/src/scripting/thingdef_data.cpp @@ -718,6 +718,7 @@ void InitThingdef() symt.AddSymbol(new PField(NAME_Damage, TypeSInt32, VARF_Native|VARF_ReadOnly, myoffsetof(AActor, DamageVal))); symt.AddSymbol(new PField("visdir", TypeSInt32, VARF_Native, myoffsetof(AActor, visdir))); symt.AddSymbol(new PField("Gravity", TypeFloat64, VARF_Native, myoffsetof(AActor, Gravity))); + symt.AddSymbol(new PField("FloorClip", TypeFloat64, VARF_Native, myoffsetof(AActor, Floorclip))); symt.AddSymbol(new PField("DamageType", TypeName, VARF_Native, myoffsetof(AActor, DamageType))); symt.AddSymbol(new PField("FloatBobPhase", TypeUInt8, VARF_Native, myoffsetof(AActor, FloatBobPhase))); symt.AddSymbol(new PField("tics", TypeSInt32, VARF_Native, myoffsetof(AActor, tics))); diff --git a/wadsrc/static/zscript/actor.txt b/wadsrc/static/zscript/actor.txt index 213ca8b254..1e05d75a79 100644 --- a/wadsrc/static/zscript/actor.txt +++ b/wadsrc/static/zscript/actor.txt @@ -76,6 +76,7 @@ class Actor : Thinker native native vector3 Vec2OffsetZ(float x, float y, float atz, bool absolute = false); native void VelFromAngle(float speed = 0, float angle = 0); native bool isFriend(Actor other); + native void AdjustFloorClip(); // DECORATE compatible functions native bool CheckClass(class checkclass, int ptr_select = AAPTR_DEFAULT, bool match_superclass = false); @@ -98,7 +99,22 @@ class Actor : Thinker native // DECORATE setters - it probably makes more sense to set these values directly now... void A_SetMass(int newmass) { mass = newmass; } + void A_SetInvulnerable() { bInvulnerable = true; } + void A_UnSetInvulnerable() { bInvulnerable = false; } + void A_SetReflective() { bReflective = true; } + void A_UnSetReflective() { bReflective = false; } + void A_SetReflectiveInvulnerable() { bInvulnerable = true; bReflective = true; } + void A_UnSetReflectiveInvulnerable() { bInvulnerable = true; bReflective = false; } + void A_SetShootable() { bShootable = true; bNonShootable = false; } + void A_UnSetShootable() { bShootable = false; bNonShootable = true; } + void A_NoGravity() { bNoGravity = true; } + void A_Gravity() { bNoGravity = false; Gravity = 1; } + void A_LowGravity() { bNoGravity = false; Gravity = 0.125; } void A_SetGravity(float newgravity) { gravity = clamp(newgravity, 0., 10.); } + void A_SetFloorClip() { bFloorClip = true; AdjustFloorClip(); } + void A_UnSetFloorClip() { bFloorClip = false; FloorClip = 0; } + void A_HideThing() { bInvisible = true; } + void A_UnHideThing() { bInvisible = false; } void A_SetArg(int arg, int val) { if (arg >= 0 && arg < 5) args[arg] = val; } void A_Turn(float turn = 0) { angle += turn; } void A_SetDamageType(name newdamagetype) { damagetype = newdamagetype; } @@ -208,6 +224,7 @@ class Actor : Thinker native native void A_BFGSpray(class spraytype = "BFGExtra", int numrays = 40, int damagecount = 15, float angle = 90, float distance = 16*64, float vrange = 32, int damage = 0, int flags = 0); native void A_Pain(); native void A_NoBlocking(); + void A_Fall() { A_NoBlocking(); } native void A_XScream(); native void A_Look(); native void A_Chase(state melee = null, state missile = null, int flags = 0); @@ -224,24 +241,6 @@ class Actor : Thinker native native void A_Detonate(); native bool A_CallSpecial(int special, int arg1=0, int arg2=0, int arg3=0, int arg4=0, int arg5=0); - native void A_SetFloorClip(); - native void A_UnSetFloorClip(); - native void A_HideThing(); - native void A_UnHideThing(); - native void A_SetInvulnerable(); - native void A_UnSetInvulnerable(); - native void A_SetReflective(); - native void A_UnSetReflective(); - native void A_SetReflectiveInvulnerable(); - native void A_UnSetReflectiveInvulnerable(); - native void A_SetShootable(); - native void A_UnSetShootable(); - native void A_NoGravity(); - native void A_Gravity(); - native void A_LowGravity(); - - native void A_Fall(); - native void A_M_Saw(sound fullsound = "weapons/sawfull", sound hitsound = "weapons/sawhit", int damage = 2, class pufftype = "BulletPuff"); native void A_ScreamAndUnblock(); From 5e76d3af186a9ba78955e22d402feb99d0fef6f7 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 2 Nov 2016 00:14:08 +0100 Subject: [PATCH 3/4] - fixed BrainishExplosion and removed some unnecessary checks, the state to be set is being defined in the same file, after all... --- wadsrc/static/zscript/doom/bossbrain.txt | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/wadsrc/static/zscript/doom/bossbrain.txt b/wadsrc/static/zscript/doom/bossbrain.txt index 2193be9542..641263eccb 100644 --- a/wadsrc/static/zscript/doom/bossbrain.txt +++ b/wadsrc/static/zscript/doom/bossbrain.txt @@ -162,13 +162,12 @@ extend class Actor boom.DeathSound = "misc/brainexplode"; boom.Vel.z = random[BrainScream](0, 255)/128.; - State stt = "BossBrain::Brainexplode"; - if (stt) boom.SetState (stt); + boom.SetState ("BossBrain::Brainexplode"); + boom.bRocketTrail = false; + boom.SetDamage(0); // disables collision detection which is not wanted here + boom.tics -= random[BrainScream](0, 7); + if (boom.tics < 1) boom.tics = 1; } - boom.bRocketTrail = false; - boom.SetDamage(0); // disables collision detection which is not wanted here - boom.tics -= random[BrainScream](0, 7); - if (boom.tics < 1) boom.tics = 1; } void A_BrainScream() From 703aaa373e0127657cd88960c48bb330a99324fc Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 2 Nov 2016 10:52:14 +0100 Subject: [PATCH 4/4] SHA-1: 8852bc7278d033bbed66c51bf23aee841ee977a9 * Revert "Modify CMPJMP to produce more compact code (as far as VC++ is concerned, anyway)" This reverts commit 6ff973a06bd97dfd1c2c5191b508fdbd98f62063. This modification did not work and broke the comparisons. Actually this had three problems: * the asserts checked the wrong instruction * the mask was not applied to regular comparisons. * incrementing PC before testing does not work because 'test' references the PC. --- src/scripting/vm/vmexec.cpp | 14 ++++------- src/scripting/vm/vmexec.h | 46 ++++++++++++++++++------------------- 2 files changed, 27 insertions(+), 33 deletions(-) diff --git a/src/scripting/vm/vmexec.cpp b/src/scripting/vm/vmexec.cpp index af25030a9c..57ce48a95a 100644 --- a/src/scripting/vm/vmexec.cpp +++ b/src/scripting/vm/vmexec.cpp @@ -82,17 +82,11 @@ #define THROW(x) throw(EVMAbortException(x)) #define CMPJMP(test) \ - pc++; \ - if (VM_UBYTE(test) == VM_UBYTE(a)) { \ + if ((test) == (a & CMP_CHECK)) { \ assert(pc[1].op == OP_JMP); \ - pc += JMPOFS(pc); \ - } - -#define CMPJMP_MASK(test) \ - pc++; \ - if (VM_UBYTE(test) == (VM_UBYTE(a) & CMP_CHECK)) { \ - assert(pc[1].op == OP_JMP); \ - pc += JMPOFS(pc); \ + pc += 1 + JMPOFS(pc+1); \ + } else { \ + pc += 1; \ } #define GETADDR(a,o,x) \ diff --git a/src/scripting/vm/vmexec.h b/src/scripting/vm/vmexec.h index 500c30c667..69f406dd81 100644 --- a/src/scripting/vm/vmexec.h +++ b/src/scripting/vm/vmexec.h @@ -1199,88 +1199,88 @@ begin: ASSERTF(B); ASSERTF(C); if (a & CMP_APPROX) { - CMPJMP_MASK(fabs(reg.f[C] - reg.f[B]) < VM_EPSILON); + CMPJMP(fabs(reg.f[C] - reg.f[B]) < VM_EPSILON); } else { - CMPJMP_MASK(reg.f[C] == reg.f[B]); + CMPJMP(reg.f[C] == reg.f[B]); } NEXTOP; OP(EQF_K): ASSERTF(B); ASSERTKF(C); if (a & CMP_APPROX) { - CMPJMP_MASK(fabs(konstf[C] - reg.f[B]) < VM_EPSILON); + CMPJMP(fabs(konstf[C] - reg.f[B]) < VM_EPSILON); } else { - CMPJMP_MASK(konstf[C] == reg.f[B]); + CMPJMP(konstf[C] == reg.f[B]); } NEXTOP; OP(LTF_RR): ASSERTF(B); ASSERTF(C); if (a & CMP_APPROX) { - CMPJMP_MASK((reg.f[B] - reg.f[C]) < -VM_EPSILON); + CMPJMP((reg.f[B] - reg.f[C]) < -VM_EPSILON); } else { - CMPJMP_MASK(reg.f[B] < reg.f[C]); + CMPJMP(reg.f[B] < reg.f[C]); } NEXTOP; OP(LTF_RK): ASSERTF(B); ASSERTKF(C); if (a & CMP_APPROX) { - CMPJMP_MASK((reg.f[B] - konstf[C]) < -VM_EPSILON); + CMPJMP((reg.f[B] - konstf[C]) < -VM_EPSILON); } else { - CMPJMP_MASK(reg.f[B] < konstf[C]); + CMPJMP(reg.f[B] < konstf[C]); } NEXTOP; OP(LTF_KR): ASSERTKF(B); ASSERTF(C); if (a & CMP_APPROX) { - CMPJMP_MASK((konstf[B] - reg.f[C]) < -VM_EPSILON); + CMPJMP((konstf[B] - reg.f[C]) < -VM_EPSILON); } else { - CMPJMP_MASK(konstf[B] < reg.f[C]); + CMPJMP(konstf[B] < reg.f[C]); } NEXTOP; OP(LEF_RR): ASSERTF(B); ASSERTF(C); if (a & CMP_APPROX) { - CMPJMP_MASK((reg.f[B] - reg.f[C]) <= -VM_EPSILON); + CMPJMP((reg.f[B] - reg.f[C]) <= -VM_EPSILON); } else { - CMPJMP_MASK(reg.f[B] <= reg.f[C]); + CMPJMP(reg.f[B] <= reg.f[C]); } NEXTOP; OP(LEF_RK): ASSERTF(B); ASSERTKF(C); if (a & CMP_APPROX) { - CMPJMP_MASK((reg.f[B] - konstf[C]) <= -VM_EPSILON); + CMPJMP((reg.f[B] - konstf[C]) <= -VM_EPSILON); } else { - CMPJMP_MASK(reg.f[B] <= konstf[C]); + CMPJMP(reg.f[B] <= konstf[C]); } NEXTOP; OP(LEF_KR): ASSERTKF(B); ASSERTF(C); if (a & CMP_APPROX) { - CMPJMP_MASK((konstf[B] - reg.f[C]) <= -VM_EPSILON); + CMPJMP((konstf[B] - reg.f[C]) <= -VM_EPSILON); } else { - CMPJMP_MASK(konstf[B] <= reg.f[C]); + CMPJMP(konstf[B] <= reg.f[C]); } NEXTOP; @@ -1369,12 +1369,12 @@ begin: Do_EQV2: if (a & CMP_APPROX) { - CMPJMP_MASK(fabs(reg.f[B ] - fcp[0]) < VM_EPSILON && - fabs(reg.f[B+1] - fcp[1]) < VM_EPSILON); + CMPJMP(fabs(reg.f[B ] - fcp[0]) < VM_EPSILON && + fabs(reg.f[B+1] - fcp[1]) < VM_EPSILON); } else { - CMPJMP_MASK(reg.f[B] == fcp[0] && reg.f[B+1] == fcp[1]); + CMPJMP(reg.f[B] == fcp[0] && reg.f[B+1] == fcp[1]); } NEXTOP; OP(EQV2_K): @@ -1496,13 +1496,13 @@ begin: Do_EQV3: if (a & CMP_APPROX) { - CMPJMP_MASK(fabs(reg.f[B ] - fcp[0]) < VM_EPSILON && - fabs(reg.f[B+1] - fcp[1]) < VM_EPSILON && - fabs(reg.f[B+2] - fcp[2]) < VM_EPSILON); + CMPJMP(fabs(reg.f[B ] - fcp[0]) < VM_EPSILON && + fabs(reg.f[B+1] - fcp[1]) < VM_EPSILON && + fabs(reg.f[B+2] - fcp[2]) < VM_EPSILON); } else { - CMPJMP_MASK(reg.f[B] == fcp[0] && reg.f[B+1] == fcp[1] && reg.f[B+2] == fcp[2]); + CMPJMP(reg.f[B] == fcp[0] && reg.f[B+1] == fcp[1] && reg.f[B+2] == fcp[2]); } NEXTOP; OP(EQV3_K):