ARM: Implement the VFP version of VCMP.

This commit is contained in:
Gabe Black 2010-06-02 12:58:14 -05:00
parent c1f7bf7f0e
commit e478df35f5
2 changed files with 95 additions and 1 deletions

View file

@ -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) {

View file

@ -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);
}}; }};