From 1b3b75ee681b1fe83ccf1240bf5d1afa174c6421 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 2 Jun 2010 12:58:15 -0500 Subject: ARM: Implement the version of VCVT float to int that rounds towards zero. --- src/arch/arm/isa/formats/fp.isa | 40 +++++++++++++++++++------- src/arch/arm/isa/insts/fp.isa | 62 +++++++++++++++++++++++++++++++++++++++-- 2 files changed, 90 insertions(+), 12 deletions(-) (limited to 'src/arch') diff --git a/src/arch/arm/isa/formats/fp.isa b/src/arch/arm/isa/formats/fp.isa index 3d40caf9e..2b999f751 100644 --- a/src/arch/arm/isa/formats/fp.isa +++ b/src/arch/arm/isa/formats/fp.isa @@ -725,20 +725,40 @@ let {{ } } case 0xc: - if (single) { - return new VcvtFpUIntS(machInst, vd, vm); + if (bits(machInst, 7) == 0) { + if (single) { + return new VcvtFpUIntSR(machInst, vd, vm); + } else { + vd = (IntRegIndex)(bits(machInst, 22) | + (bits(machInst, 15, 12) << 1)); + return new VcvtFpUIntDR(machInst, vd, vm); + } } else { - vd = (IntRegIndex)(bits(machInst, 22) | - (bits(machInst, 15, 12) << 1)); - return new VcvtFpUIntD(machInst, vd, vm); + if (single) { + return new VcvtFpUIntS(machInst, vd, vm); + } else { + vd = (IntRegIndex)(bits(machInst, 22) | + (bits(machInst, 15, 12) << 1)); + return new VcvtFpUIntD(machInst, vd, vm); + } } case 0xd: - if (single) { - return new VcvtFpSIntS(machInst, vd, vm); + if (bits(machInst, 7) == 0) { + if (single) { + return new VcvtFpSIntSR(machInst, vd, vm); + } else { + vd = (IntRegIndex)(bits(machInst, 22) | + (bits(machInst, 15, 12) << 1)); + return new VcvtFpSIntDR(machInst, vd, vm); + } } else { - vd = (IntRegIndex)(bits(machInst, 22) | - (bits(machInst, 15, 12) << 1)); - return new VcvtFpSIntD(machInst, vd, vm); + if (single) { + return new VcvtFpSIntS(machInst, vd, vm); + } else { + vd = (IntRegIndex)(bits(machInst, 22) | + (bits(machInst, 15, 12) << 1)); + return new VcvtFpSIntD(machInst, vd, vm); + } } case 0xe: { diff --git a/src/arch/arm/isa/insts/fp.isa b/src/arch/arm/isa/insts/fp.isa index db1c5bf6b..93c5cf8b4 100644 --- a/src/arch/arm/isa/insts/fp.isa +++ b/src/arch/arm/isa/insts/fp.isa @@ -829,8 +829,63 @@ let {{ decoder_output += VfpRegRegOpConstructor.subst(vcvtSIntFpDIop); exec_output += PredOpExecute.subst(vcvtSIntFpDIop); + vcvtFpUIntSRCode = ''' + VfpSavedState state = prepVfpFpscr(Fpscr); + FpDest.uw = FpOp1; + Fpscr = setVfpFpscr(Fpscr, state); + ''' + vcvtFpUIntSRIop = InstObjParams("vcvt", "VcvtFpUIntSR", "VfpRegRegOp", + { "code": vcvtFpUIntSRCode, + "predicate_test": predicateTest }, []) + header_output += VfpRegRegOpDeclare.subst(vcvtFpUIntSRIop); + decoder_output += VfpRegRegOpConstructor.subst(vcvtFpUIntSRIop); + exec_output += PredOpExecute.subst(vcvtFpUIntSRIop); + + vcvtFpUIntDRCode = ''' + IntDoubleUnion cOp1; + cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32)); + VfpSavedState state = prepVfpFpscr(Fpscr); + uint64_t result = cOp1.fp; + Fpscr = setVfpFpscr(Fpscr, state); + FpDestP0.uw = result; + ''' + vcvtFpUIntDRIop = InstObjParams("vcvtr", "VcvtFpUIntDR", "VfpRegRegOp", + { "code": vcvtFpUIntDRCode, + "predicate_test": predicateTest }, []) + header_output += VfpRegRegOpDeclare.subst(vcvtFpUIntDRIop); + decoder_output += VfpRegRegOpConstructor.subst(vcvtFpUIntDRIop); + exec_output += PredOpExecute.subst(vcvtFpUIntDRIop); + + vcvtFpSIntSRCode = ''' + VfpSavedState state = prepVfpFpscr(Fpscr); + FpDest.sw = FpOp1; + Fpscr = setVfpFpscr(Fpscr, state); + ''' + vcvtFpSIntSRIop = InstObjParams("vcvtr", "VcvtFpSIntSR", "VfpRegRegOp", + { "code": vcvtFpSIntSRCode, + "predicate_test": predicateTest }, []) + header_output += VfpRegRegOpDeclare.subst(vcvtFpSIntSRIop); + decoder_output += VfpRegRegOpConstructor.subst(vcvtFpSIntSRIop); + exec_output += PredOpExecute.subst(vcvtFpSIntSRIop); + + vcvtFpSIntDRCode = ''' + IntDoubleUnion cOp1; + cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32)); + VfpSavedState state = prepVfpFpscr(Fpscr); + int64_t result = cOp1.fp; + Fpscr = setVfpFpscr(Fpscr, state); + FpDestP0.uw = result; + ''' + vcvtFpSIntDRIop = InstObjParams("vcvtr", "VcvtFpSIntDR", "VfpRegRegOp", + { "code": vcvtFpSIntDRCode, + "predicate_test": predicateTest }, []) + header_output += VfpRegRegOpDeclare.subst(vcvtFpSIntDRIop); + decoder_output += VfpRegRegOpConstructor.subst(vcvtFpSIntDRIop); + exec_output += PredOpExecute.subst(vcvtFpSIntDRIop); + vcvtFpUIntSCode = ''' VfpSavedState state = prepVfpFpscr(Fpscr); + fesetround(FeRoundZero); FpDest.uw = FpOp1; Fpscr = setVfpFpscr(Fpscr, state); ''' @@ -845,6 +900,7 @@ let {{ IntDoubleUnion cOp1; cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32)); VfpSavedState state = prepVfpFpscr(Fpscr); + fesetround(FeRoundZero); uint64_t result = cOp1.fp; Fpscr = setVfpFpscr(Fpscr, state); FpDestP0.uw = result; @@ -858,6 +914,7 @@ let {{ vcvtFpSIntSCode = ''' VfpSavedState state = prepVfpFpscr(Fpscr); + fesetround(FeRoundZero); FpDest.sw = FpOp1; Fpscr = setVfpFpscr(Fpscr, state); ''' @@ -872,6 +929,7 @@ let {{ IntDoubleUnion cOp1; cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32)); VfpSavedState state = prepVfpFpscr(Fpscr); + fesetround(FeRoundZero); int64_t result = cOp1.fp; Fpscr = setVfpFpscr(Fpscr, state); FpDestP0.uw = result; @@ -1062,7 +1120,7 @@ let {{ vcvtSFixedFpSCode = ''' VfpSavedState state = prepVfpFpscr(Fpscr); - FpDest = vfpSFixedToFpS(FpOp1.sw, true, imm); + FpDest = vfpSFixedToFpS(FpOp1.sw, false, imm); Fpscr = setVfpFpscr(Fpscr, state); ''' vcvtSFixedFpSIop = InstObjParams("vcvt", "VcvtSFixedFpS", "VfpRegRegImmOp", @@ -1076,7 +1134,7 @@ let {{ IntDoubleUnion cDest; uint64_t mid = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32)); VfpSavedState state = prepVfpFpscr(Fpscr); - cDest.fp = vfpSFixedToFpD(mid, true, imm); + cDest.fp = vfpSFixedToFpD(mid, false, imm); Fpscr = setVfpFpscr(Fpscr, state); FpDestP0.uw = cDest.bits; FpDestP1.uw = cDest.bits >> 32; -- cgit v1.2.3