- added a full set of 2D vector instructions to the VM. The existing one was 3D only but there's also need to handle two-dimensional vectors.

- added the missing divv* instructions.
This commit is contained in:
Christoph Oelckers 2016-10-28 10:13:07 +02:00
parent 35cd48b86b
commit 3b1f411dce
2 changed files with 250 additions and 47 deletions

View file

@ -196,7 +196,25 @@ begin:
reg.a[a] = *(void **)ptr;
reg.atag[a] = ATAG_GENERIC;
NEXTOP;
OP(LV):
OP(LV2):
ASSERTF(a+2); ASSERTA(B); ASSERTKD(C);
GETADDR(PB,KC,X_READ_NIL);
{
auto v = (double *)ptr;
reg.f[a] = v[0];
reg.f[a+1] = v[1];
}
NEXTOP;
OP(LV2_R):
ASSERTF(a+2); ASSERTA(B); ASSERTD(C);
GETADDR(PB,RC,X_READ_NIL);
{
auto v = (double *)ptr;
reg.f[a] = v[0];
reg.f[a+1] = v[1];
}
NEXTOP;
OP(LV3):
ASSERTF(a+2); ASSERTA(B); ASSERTKD(C);
GETADDR(PB,KC,X_READ_NIL);
{
@ -206,7 +224,7 @@ begin:
reg.f[a+2] = v[2];
}
NEXTOP;
OP(LV_R):
OP(LV3_R):
ASSERTF(a+2); ASSERTA(B); ASSERTD(C);
GETADDR(PB,RC,X_READ_NIL);
{
@ -292,7 +310,25 @@ begin:
GETADDR(PA,RC,X_WRITE_NIL);
*(void **)ptr = reg.a[B];
NEXTOP;
OP(SV):
OP(SV2):
ASSERTA(a); ASSERTF(B+2); ASSERTKD(C);
GETADDR(PA,KC,X_WRITE_NIL);
{
auto v = (double *)ptr;
v[0] = reg.f[B];
v[1] = reg.f[B+1];
}
NEXTOP;
OP(SV2_R):
ASSERTA(a); ASSERTF(B+2); ASSERTD(C);
GETADDR(PA,RC,X_WRITE_NIL);
{
auto v = (double *)ptr;
v[0] = reg.f[B];
v[1] = reg.f[B+1];
}
NEXTOP;
OP(SV3):
ASSERTA(a); ASSERTF(B+2); ASSERTKD(C);
GETADDR(PA,KC,X_WRITE_NIL);
{
@ -302,7 +338,7 @@ begin:
v[2] = reg.f[B+2];
}
NEXTOP;
OP(SV_R):
OP(SV3_R):
ASSERTA(a); ASSERTF(B+2); ASSERTD(C);
GETADDR(PA,RC,X_WRITE_NIL);
{
@ -342,6 +378,17 @@ begin:
reg.a[a] = reg.a[B];
reg.atag[a] = reg.atag[B];
NEXTOP;
OP(MOVEV2):
ASSERTF(a); ASSERTF(B);
reg.f[a] = reg.f[B];
reg.f[a+1] = reg.f[B+1];
NEXTOP;
OP(MOVEV3):
ASSERTF(a); ASSERTF(B);
reg.f[a] = reg.f[B];
reg.f[a+1] = reg.f[B+1];
reg.f[a+2] = reg.f[B+2];
NEXTOP;
OP(CAST):
if (C == CAST_I2F)
{
@ -1246,51 +1293,159 @@ begin:
}
NEXTOP;
OP(NEGV):
OP(NEGV2):
ASSERTF(a+1); ASSERTF(B+1);
reg.f[a] = -reg.f[B];
reg.f[a+1] = -reg.f[B+1];
NEXTOP;
OP(ADDV2_RR):
ASSERTF(a+1); ASSERTF(B+1); ASSERTF(C+1);
fcp = &reg.f[C];
Do_ADDV2:
fbp = &reg.f[B];
reg.f[a] = fbp[0] + fcp[0];
reg.f[a+1] = fbp[1] + fcp[1];
NEXTOP;
OP(ADDV2_RK):
fcp = &konstf[C];
goto Do_ADDV2;
OP(SUBV2_RR):
ASSERTF(a+1); ASSERTF(B+1); ASSERTF(C+1);
fbp = &reg.f[B];
fcp = &reg.f[C];
Do_SUBV2:
reg.f[a] = fbp[0] - fcp[0];
reg.f[a+1] = fbp[1] - fcp[1];
NEXTOP;
OP(SUBV2_RK):
ASSERTF(a+1); ASSERTF(B+1); ASSERTKF(C+1);
fbp = &reg.f[B];
fcp = &konstf[C];
goto Do_SUBV2;
OP(SUBV2_KR):
ASSERTF(A+1); ASSERTKF(B+1); ASSERTF(C+1);
fbp = &konstf[B];
fcp = &reg.f[C];
goto Do_SUBV2;
OP(DOTV2_RR):
ASSERTF(a); ASSERTF(B+1); ASSERTF(C+1);
reg.f[a] = reg.f[B] * reg.f[C] + reg.f[B+1] * reg.f[C+1];
NEXTOP;
OP(DOTV2_RK):
ASSERTF(a); ASSERTF(B+1); ASSERTKF(C+1);
reg.f[a] = reg.f[B] * konstf[C] + reg.f[B+1] * konstf[C+1];
NEXTOP;
OP(MULVF2_RR):
ASSERTF(a+1); ASSERTF(B+1); ASSERTF(C);
fc = reg.f[C];
fbp = &reg.f[B];
Do_MULV2:
reg.f[a] = fbp[0] * fc;
reg.f[a+1] = fbp[1] * fc;
NEXTOP;
OP(MULVF2_RK):
ASSERTF(a+1); ASSERTF(B+1); ASSERTKF(C);
fc = konstf[C];
fbp = &reg.f[B];
goto Do_MULV2;
OP(MULVF2_KR):
ASSERTF(a+1); ASSERTKF(B+1); ASSERTF(C);
fc = reg.f[C];
fbp = &konstf[B];
goto Do_MULV2;
OP(DIVVF2_RR):
ASSERTF(a+1); ASSERTF(B+1); ASSERTF(C);
fc = reg.f[C];
fbp = &reg.f[B];
Do_DIVV2:
reg.f[a] = fbp[0] / fc;
reg.f[a+1] = fbp[1] / fc;
NEXTOP;
OP(DIVVF2_RK):
ASSERTF(a+1); ASSERTF(B+1); ASSERTKF(C);
fc = konstf[C];
fbp = &reg.f[B];
goto Do_DIVV2;
OP(DIVVF2_KR):
ASSERTF(a+1); ASSERTKF(B+1); ASSERTF(C);
fc = reg.f[C];
fbp = &konstf[B];
goto Do_DIVV2;
OP(LENV2):
ASSERTF(a); ASSERTF(B+1);
reg.f[a] = g_sqrt(reg.f[B] * reg.f[B] + reg.f[B+1] * reg.f[B+1]);
NEXTOP;
OP(EQV2_R):
ASSERTF(B+1); ASSERTF(C+1);
fcp = &reg.f[C];
Do_EQV2:
if (a & CMP_APPROX)
{
CMPJMP(fabs(reg.f[B ] - fcp[0]) < VM_EPSILON &&
fabs(reg.f[B+1] - fcp[1]) < VM_EPSILON);
}
else
{
CMPJMP(reg.f[B] == fcp[0] && reg.f[B+1] == fcp[1]);
}
NEXTOP;
OP(EQV2_K):
ASSERTF(B+1); ASSERTKF(C+1);
fcp = &konstf[C];
goto Do_EQV2;
OP(NEGV3):
ASSERTF(a+2); ASSERTF(B+2);
reg.f[a] = -reg.f[B];
reg.f[a+1] = -reg.f[B+1];
reg.f[a+2] = -reg.f[B+2];
NEXTOP;
OP(ADDV_RR):
OP(ADDV3_RR):
ASSERTF(a+2); ASSERTF(B+2); ASSERTF(C+2);
fcp = &reg.f[C];
Do_ADDV:
Do_ADDV3:
fbp = &reg.f[B];
reg.f[a] = fbp[0] + fcp[0];
reg.f[a+1] = fbp[1] + fcp[1];
reg.f[a+2] = fbp[2] + fcp[2];
NEXTOP;
OP(ADDV_RK):
OP(ADDV3_RK):
fcp = &konstf[C];
goto Do_ADDV;
goto Do_ADDV3;
OP(SUBV_RR):
OP(SUBV3_RR):
ASSERTF(a+2); ASSERTF(B+2); ASSERTF(C+2);
fbp = &reg.f[B];
fcp = &reg.f[C];
Do_SUBV:
Do_SUBV3:
reg.f[a] = fbp[0] - fcp[0];
reg.f[a+1] = fbp[1] - fcp[1];
reg.f[a+2] = fbp[2] - fcp[2];
NEXTOP;
OP(SUBV_RK):
OP(SUBV3_RK):
ASSERTF(a+2); ASSERTF(B+2); ASSERTKF(C+2);
fbp = &reg.f[B];
fcp = &konstf[C];
goto Do_SUBV;
OP(SUBV_KR):
goto Do_SUBV3;
OP(SUBV3_KR):
ASSERTF(A+2); ASSERTKF(B+2); ASSERTF(C+2);
fbp = &konstf[B];
fcp = &reg.f[C];
goto Do_SUBV;
goto Do_SUBV3;
OP(DOTV_RR):
OP(DOTV3_RR):
ASSERTF(a); ASSERTF(B+2); ASSERTF(C+2);
reg.f[a] = reg.f[B] * reg.f[C] + reg.f[B+1] * reg.f[C+1] + reg.f[B+2] * reg.f[C+2];
NEXTOP;
OP(DOTV_RK):
OP(DOTV3_RK):
ASSERTF(a); ASSERTF(B+2); ASSERTKF(C+2);
reg.f[a] = reg.f[B] * konstf[C] + reg.f[B+1] * konstf[C+1] + reg.f[B+2] * konstf[C+2];
NEXTOP;
@ -1319,35 +1474,55 @@ begin:
fcp = &konstf[C];
goto Do_CROSSV;
OP(MULVF_RR):
OP(MULVF3_RR):
ASSERTF(a+2); ASSERTF(B+2); ASSERTF(C);
fc = reg.f[C];
fbp = &reg.f[B];
Do_MULV:
Do_MULV3:
reg.f[a] = fbp[0] * fc;
reg.f[a+1] = fbp[1] * fc;
reg.f[a+2] = fbp[2] * fc;
NEXTOP;
OP(MULVF_RK):
OP(MULVF3_RK):
ASSERTF(a+2); ASSERTF(B+2); ASSERTKF(C);
fc = konstf[C];
fbp = &reg.f[B];
goto Do_MULV;
OP(MULVF_KR):
goto Do_MULV3;
OP(MULVF3_KR):
ASSERTF(a+2); ASSERTKF(B+2); ASSERTF(C);
fc = reg.f[C];
fbp = &konstf[B];
goto Do_MULV;
goto Do_MULV3;
OP(LENV):
OP(DIVVF3_RR):
ASSERTF(a+2); ASSERTF(B+2); ASSERTF(C);
fc = reg.f[C];
fbp = &reg.f[B];
Do_DIVV3:
reg.f[a] = fbp[0] / fc;
reg.f[a+1] = fbp[1] / fc;
reg.f[a+2] = fbp[2] / fc;
NEXTOP;
OP(DIVVF3_RK):
ASSERTF(a+2); ASSERTF(B+2); ASSERTKF(C);
fc = konstf[C];
fbp = &reg.f[B];
goto Do_DIVV3;
OP(DIVVF3_KR):
ASSERTF(a+2); ASSERTKF(B+2); ASSERTF(C);
fc = reg.f[C];
fbp = &konstf[B];
goto Do_DIVV3;
OP(LENV3):
ASSERTF(a); ASSERTF(B+2);
reg.f[a] = g_sqrt(reg.f[B] * reg.f[B] + reg.f[B+1] * reg.f[B+1] + reg.f[B+2] * reg.f[B+2]);
NEXTOP;
OP(EQV_R):
OP(EQV3_R):
ASSERTF(B+2); ASSERTF(C+2);
fcp = &reg.f[C];
Do_EQV:
Do_EQV3:
if (a & CMP_APPROX)
{
CMPJMP(fabs(reg.f[B ] - fcp[0]) < VM_EPSILON &&
@ -1359,10 +1534,10 @@ begin:
CMPJMP(reg.f[B] == fcp[0] && reg.f[B+1] == fcp[1] && reg.f[B+2] == fcp[2]);
}
NEXTOP;
OP(EQV_K):
OP(EQV3_K):
ASSERTF(B+2); ASSERTKF(C+2);
fcp = &konstf[C];
goto Do_EQV;
goto Do_EQV3;
OP(ADDA_RR):
ASSERTA(a); ASSERTA(B); ASSERTD(C);

View file

@ -33,8 +33,10 @@ xx(LO, lo, RPRPKI), // load object
xx(LO_R, lo, RPRPRI),
xx(LP, lp, RPRPKI), // load pointer
xx(LP_R, lp, RPRPRI),
xx(LV, lv, RVRPKI), // load vector
xx(LV_R, lv, RVRPRI),
xx(LV2, lv2, RVRPKI), // load vector2
xx(LV2_R, lv2, RVRPRI),
xx(LV3, lv3, RVRPKI), // load vector3
xx(LV3_R, lv3, RVRPRI),
xx(LBIT, lbit, RIRPI8), // rA = !!(*rB & C) -- *rB is a byte
@ -53,8 +55,10 @@ xx(SS, ss, RPRSKI), // store string
xx(SS_R, ss, RPRSRI),
xx(SP, sp, RPRPKI), // store pointer
xx(SP_R, sp, RPRPRI),
xx(SV, sv, RPRVKI), // store vector
xx(SV_R, sv, RPRVRI),
xx(SV2, sv2, RPRVKI), // store vector2
xx(SV2_R, sv2, RPRVRI),
xx(SV3, sv3, RPRVKI), // store vector3
xx(SV3_R, sv3, RPRVRI),
xx(SBIT, sbit, RPRII8), // *rA |= C if rB is true, *rA &= ~C otherwise
@ -63,6 +67,8 @@ xx(MOVE, mov, RIRI), // dA = dB
xx(MOVEF, mov, RFRF), // fA = fB
xx(MOVES, mov, RSRS), // sA = sB
xx(MOVEA, mov, RPRP), // aA = aB
xx(MOVEV2, mov2, RFRF), // fA = fB (2 elements)
xx(MOVEV3, mov3, RFRF), // fA = fB (3 elements)
xx(CAST, cast, CAST), // xA = xB, conversion specified by C
xx(DYNCAST_R, dyncast,RPRPRP), // aA = aB after casting to rkC (specifying a class)
xx(DYNCAST_K, dyncast,RPRPKP),
@ -193,24 +199,46 @@ xx(LEF_RR, ble, CFRR), // if ((fkb <= fkC) != (A & 1)) then pc++
xx(LEF_RK, ble, CFRK),
xx(LEF_KR, ble, CFKR),
// Vector math.
xx(NEGV, negv, RVRV), // vA = -vB
xx(ADDV_RR, addv, RVRVRV), // vA = vB + vkC
xx(ADDV_RK, addv, RVRVKV),
xx(SUBV_RR, subv, RVRVRV), // vA = vkB - vkC
xx(SUBV_RK, subv, RVRVKV),
xx(SUBV_KR, subv, RVKVRV),
xx(DOTV_RR, dotv, RVRVRV), // va = vB dot vkC
xx(DOTV_RK, dotv, RVRVKV),
// Vector math. (2D)
xx(NEGV2, negv2, RVRV), // vA = -vB
xx(ADDV2_RR, addv2, RVRVRV), // vA = vB + vkC
xx(ADDV2_RK, addv2, RVRVKV),
xx(SUBV2_RR, subv2, RVRVRV), // vA = vkB - vkC
xx(SUBV2_RK, subv2, RVRVKV),
xx(SUBV2_KR, subv2, RVKVRV),
xx(DOTV2_RR, dotv2, RVRVRV), // va = vB dot vkC
xx(DOTV2_RK, dotv2, RVRVKV),
xx(MULVF2_RR, mulv2, RVRVRV), // vA = vkB * fkC
xx(MULVF2_RK, mulv2, RVRVKV),
xx(MULVF2_KR, mulv2, RVKVRV),
xx(DIVVF2_RR, divv2, RVRVRV), // vA = vkB / fkC
xx(DIVVF2_RK, divv2, RVRVKV),
xx(DIVVF2_KR, divv2, RVKVRV),
xx(LENV2, lenv2, RFRV), // fA = vB.Length
xx(EQV2_R, beqv2, CVRR), // if ((vB == vkC) != A) then pc++ (inexact if A & 32)
xx(EQV2_K, beqv2, CVRK),
// Vector math (3D)
xx(NEGV3, negv3, RVRV), // vA = -vB
xx(ADDV3_RR, addv3, RVRVRV), // vA = vB + vkC
xx(ADDV3_RK, addv3, RVRVKV),
xx(SUBV3_RR, subv3, RVRVRV), // vA = vkB - vkC
xx(SUBV3_RK, subv3, RVRVKV),
xx(SUBV3_KR, subv3, RVKVRV),
xx(DOTV3_RR, dotv3, RVRVRV), // va = vB dot vkC
xx(DOTV3_RK, dotv3, RVRVKV),
xx(CROSSV_RR, crossv, RVRVRV), // vA = vkB cross vkC
xx(CROSSV_RK, crossv, RVRVKV),
xx(CROSSV_KR, crossv, RVKVRV),
xx(MULVF_RR, mulv, RVRVRV), // vA = vkB * fkC
xx(MULVF_RK, mulv, RVRVKV),
xx(MULVF_KR, mulv, RVKVRV),
xx(LENV, lenv, RFRV), // fA = vB.Length
xx(EQV_R, beqv, CVRR), // if ((vB == vkC) != A) then pc++ (inexact if A & 32)
xx(EQV_K, beqv, CVRK),
xx(MULVF3_RR, mulv3, RVRVRV), // vA = vkB * fkC
xx(MULVF3_RK, mulv3, RVRVKV),
xx(MULVF3_KR, mulv3, RVKVRV),
xx(DIVVF3_RR, divv3, RVRVRV), // vA = vkB / fkC
xx(DIVVF3_RK, divv3, RVRVKV),
xx(DIVVF3_KR, divv3, RVKVRV),
xx(LENV3, lenv3, RFRV), // fA = vB.Length
xx(EQV3_R, beqv3, CVRR), // if ((vB == vkC) != A) then pc++ (inexact if A & 33)
xx(EQV3_K, beqv3, CVRK),
// Pointer math.
xx(ADDA_RR, add, RPRPRI), // pA = pB + dkC