ARM: Implement the VFP version of VCMP.
This commit is contained in:
parent
c1f7bf7f0e
commit
e478df35f5
2 changed files with 95 additions and 1 deletions
|
@ -640,8 +640,17 @@ let {{
|
||||||
// Between half and single precision.
|
// Between half and single precision.
|
||||||
return new WarnUnimplemented("vcvtb, vcvtt", machInst);
|
return new WarnUnimplemented("vcvtb, vcvtt", machInst);
|
||||||
case 0x4:
|
case 0x4:
|
||||||
|
if (single) {
|
||||||
|
return new VcmpS(machInst, vd, vm);
|
||||||
|
} else {
|
||||||
|
return new VcmpD(machInst, vd, vm);
|
||||||
|
}
|
||||||
case 0x5:
|
case 0x5:
|
||||||
return new WarnUnimplemented("vcmp, vcmpe", machInst);
|
if (single) {
|
||||||
|
return new VcmpZeroS(machInst, vd, 0);
|
||||||
|
} else {
|
||||||
|
return new VcmpZeroD(machInst, vd, 0);
|
||||||
|
}
|
||||||
case 0x7:
|
case 0x7:
|
||||||
if (opc3 == 0x3) {
|
if (opc3 == 0x3) {
|
||||||
if (single) {
|
if (single) {
|
||||||
|
|
|
@ -851,4 +851,89 @@ let {{
|
||||||
header_output += VfpRegRegOpDeclare.subst(vcvtFpDFpSIop);
|
header_output += VfpRegRegOpDeclare.subst(vcvtFpDFpSIop);
|
||||||
decoder_output += VfpRegRegOpConstructor.subst(vcvtFpDFpSIop);
|
decoder_output += VfpRegRegOpConstructor.subst(vcvtFpDFpSIop);
|
||||||
exec_output += PredOpExecute.subst(vcvtFpDFpSIop);
|
exec_output += PredOpExecute.subst(vcvtFpDFpSIop);
|
||||||
|
|
||||||
|
vcmpSCode = '''
|
||||||
|
FPSCR fpscr = Fpscr;
|
||||||
|
if (FpDest == FpOp1) {
|
||||||
|
fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
|
||||||
|
} else if (FpDest < FpOp1) {
|
||||||
|
fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
|
||||||
|
} else if (FpDest > FpOp1) {
|
||||||
|
fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
|
||||||
|
} else {
|
||||||
|
fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
|
||||||
|
}
|
||||||
|
Fpscr = fpscr;
|
||||||
|
'''
|
||||||
|
vcmpSIop = InstObjParams("vcmps", "VcmpS", "VfpRegRegOp",
|
||||||
|
{ "code": vcmpSCode,
|
||||||
|
"predicate_test": predicateTest }, [])
|
||||||
|
header_output += VfpRegRegOpDeclare.subst(vcmpSIop);
|
||||||
|
decoder_output += VfpRegRegOpConstructor.subst(vcmpSIop);
|
||||||
|
exec_output += PredOpExecute.subst(vcmpSIop);
|
||||||
|
|
||||||
|
vcmpDCode = '''
|
||||||
|
IntDoubleUnion cOp1, cDest;
|
||||||
|
cDest.bits = ((uint64_t)FpDestP0.uw | ((uint64_t)FpDestP1.uw << 32));
|
||||||
|
cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
|
||||||
|
FPSCR fpscr = Fpscr;
|
||||||
|
if (cDest.fp == cOp1.fp) {
|
||||||
|
fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
|
||||||
|
} else if (cDest.fp < cOp1.fp) {
|
||||||
|
fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
|
||||||
|
} else if (cDest.fp > cOp1.fp) {
|
||||||
|
fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
|
||||||
|
} else {
|
||||||
|
fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
|
||||||
|
}
|
||||||
|
Fpscr = fpscr;
|
||||||
|
'''
|
||||||
|
vcmpDIop = InstObjParams("vcmpd", "VcmpD", "VfpRegRegOp",
|
||||||
|
{ "code": vcmpDCode,
|
||||||
|
"predicate_test": predicateTest }, [])
|
||||||
|
header_output += VfpRegRegOpDeclare.subst(vcmpDIop);
|
||||||
|
decoder_output += VfpRegRegOpConstructor.subst(vcmpDIop);
|
||||||
|
exec_output += PredOpExecute.subst(vcmpDIop);
|
||||||
|
|
||||||
|
vcmpZeroSCode = '''
|
||||||
|
FPSCR fpscr = Fpscr;
|
||||||
|
if (FpDest == imm) {
|
||||||
|
fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
|
||||||
|
} else if (FpDest < imm) {
|
||||||
|
fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
|
||||||
|
} else if (FpDest > imm) {
|
||||||
|
fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
|
||||||
|
} else {
|
||||||
|
fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
|
||||||
|
}
|
||||||
|
Fpscr = fpscr;
|
||||||
|
'''
|
||||||
|
vcmpZeroSIop = InstObjParams("vcmpZeros", "VcmpZeroS", "VfpRegImmOp",
|
||||||
|
{ "code": vcmpZeroSCode,
|
||||||
|
"predicate_test": predicateTest }, [])
|
||||||
|
header_output += VfpRegImmOpDeclare.subst(vcmpZeroSIop);
|
||||||
|
decoder_output += VfpRegImmOpConstructor.subst(vcmpZeroSIop);
|
||||||
|
exec_output += PredOpExecute.subst(vcmpZeroSIop);
|
||||||
|
|
||||||
|
vcmpZeroDCode = '''
|
||||||
|
IntDoubleUnion cDest;
|
||||||
|
cDest.bits = ((uint64_t)FpDestP0.uw | ((uint64_t)FpDestP1.uw << 32));
|
||||||
|
FPSCR fpscr = Fpscr;
|
||||||
|
if (cDest.fp == imm) {
|
||||||
|
fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
|
||||||
|
} else if (cDest.fp < imm) {
|
||||||
|
fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
|
||||||
|
} else if (cDest.fp > imm) {
|
||||||
|
fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
|
||||||
|
} else {
|
||||||
|
fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
|
||||||
|
}
|
||||||
|
Fpscr = fpscr;
|
||||||
|
'''
|
||||||
|
vcmpZeroDIop = InstObjParams("vcmpZerod", "VcmpZeroD", "VfpRegImmOp",
|
||||||
|
{ "code": vcmpZeroDCode,
|
||||||
|
"predicate_test": predicateTest }, [])
|
||||||
|
header_output += VfpRegImmOpDeclare.subst(vcmpZeroDIop);
|
||||||
|
decoder_output += VfpRegImmOpConstructor.subst(vcmpZeroDIop);
|
||||||
|
exec_output += PredOpExecute.subst(vcmpZeroDIop);
|
||||||
}};
|
}};
|
||||||
|
|
Loading…
Reference in a new issue