diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2021-03-23 10:39:51 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2021-03-23 10:39:51 +0100 |
| commit | 604da55f0821a5272bd24a5cfae1d95abfc00839 (patch) | |
| tree | d994e1bbb3d492201688c12ddd120bc32500df21 /src | |
| parent | 57a5d517c8efe9ea7e6027028ff9488f17beeec9 (diff) | |
| download | box64-604da55f0821a5272bd24a5cfae1d95abfc00839.tar.gz box64-604da55f0821a5272bd24a5cfae1d95abfc00839.zip | |
[DYNAREC] Added F3 0F 5F opcode
Diffstat (limited to 'src')
| -rwxr-xr-x | src/dynarec/arm64_emitter.h | 23 | ||||
| -rwxr-xr-x | src/dynarec/dynarec_arm64_f30f.c | 10 |
2 files changed, 33 insertions, 0 deletions
diff --git a/src/dynarec/arm64_emitter.h b/src/dynarec/arm64_emitter.h index 3f1533df..069d65d2 100755 --- a/src/dynarec/arm64_emitter.h +++ b/src/dynarec/arm64_emitter.h @@ -901,6 +901,29 @@ #define SCVTQFS(Vd, Vn) EMIT(SCVTF_vector(1, 0, 0, Vn, VD)) #define SCVTQFD(Vd, Vn) EMIT(SCVTF_vector(1, 0, 1, Vn, VD)) +// FMAX / FMIN +#define FMINMAX_vector(Q, U, o1, sz, Rm, Rn, Rd) ((Q)<<30 | (U)<<29 | 0b01110<<24 | (o1)<<23 | (sz)<<22 | 0b1<<21 | (Rm)<<16 | 0b11110<<11 | 1<<10 | (Rn)<<5 | (Rd)) +#define VFMINS(Vd, Vn, Vm) EMIT(FMINMAX_vector(0, 0, 1, 0, Vm, Vn, Vd)) +#define VFMAXS(Vd, Vn, Vm) EMIT(FMINMAX_vector(0, 0, 0, 0, Vm, Vn, Vd)) +#define VFMINQS(Vd, Vn, Vm) EMIT(FMINMAX_vector(1, 0, 1, 0, Vm, Vn, Vd)) +#define VFMAXQS(Vd, Vn, Vm) EMIT(FMINMAX_vector(1, 0, 0, 0, Vm, Vn, Vd)) +#define VFMINQD(Vd, Vn, Vm) EMIT(FMINMAX_vector(1, 0, 1, 1, Vm, Vn, Vd)) +#define VFMAXQD(Vd, Vn, Vm) EMIT(FMINMAX_vector(1, 0, 0, 1, Vm, Vn, Vd)) + +#define FMINMAX_scalar(type, Rm, op, Rn, Rd) (0b11110<<24 | (type)<<22 | 1<<21 | (Rm)<<16 | 0b01<<14 | (op)<<12 | 0b10<<10 | (Rn)<<5 | (Rd)) +#define FMINS(Sd, Sn, Sm) EMIT(FMINMAX_scalar(0b00, Sm, 0b01, Sn, Sd)) +#define FMIND(Dd, Dn, Dm) EMIT(FMINMAX_scalar(0b01, Dm, 0b01, Dn, Dd)) +#define FMAXS(Sd, Sn, Sm) EMIT(FMINMAX_scalar(0b00, Sm, 0b00, Sn, Sd)) +#define FMAXD(Dd, Dn, Dm) EMIT(FMINMAX_scalar(0b01, Dm, 0b00, Dn, Dd)) +// FMINNM NaN vs Number: number is picked +#define FMINNMS(Sd, Sn, Sm) EMIT(FMINMAX_scalar(0b00, Sm, 0b11, Sn, Sd)) +// FMINNM NaN vs Number: number is picked +#define FMINNMD(Dd, Dn, Dm) EMIT(FMINMAX_scalar(0b01, Dm, 0b11, Dn, Dd)) +// FMAXNM NaN vs Number: number is picked +#define FMAXNMS(Sd, Sn, Sm) EMIT(FMINMAX_scalar(0b00, Sm, 0b10, Sn, Sd)) +// FMAXNM NaN vs Number: number is picked +#define FMAXNMD(Dd, Dn, Dm) EMIT(FMINMAX_scalar(0b01, Dm, 0b10, Dn, Dd)) + // ZIP #define ZIP_gen(Q, size, Rm, op, Rn, Rd) ((Q)<<30 | 0b001110<<24 | (size)<<22 | (Rm)<<16 | (op)<<14 | 0b11<<12 | 0b10<<10 | (Rn)<<5 | (Rd)) #define VZIP1Q_8(Rt, Rn, Rm) EMIT(ZIP_gen(1, 0b00, Rm, 0, Rn, Rt)) diff --git a/src/dynarec/dynarec_arm64_f30f.c b/src/dynarec/dynarec_arm64_f30f.c index c24346a6..24cb0e67 100755 --- a/src/dynarec/dynarec_arm64_f30f.c +++ b/src/dynarec/dynarec_arm64_f30f.c @@ -158,6 +158,16 @@ uintptr_t dynarec64_F30F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n FDIVS(d1, v0, d0); VMOVeS(v0, 0, d1, 0); break; + case 0x5F: + INST_NAME("MAXSS Gx, Ex"); + nextop = F8; + GETGX(v0); + GETEX(v1, 0); + // MAXSS: if any input is NaN, or Ex[0]>Gx[0], copy Ex[0] -> Gx[0] + d0 = fpu_get_scratch(dyn); + FMAXNMS(d0, v0, v1); // NaN handling may be slightly different, is that a problem? + VMOVeS(v0, 0, d0, 0); // to not erase uper part + break; case 0x7E: INST_NAME("MOVQ Gx, Ex"); |