diff options
author | Gabe Black <gblack@eecs.umich.edu> | 2010-06-02 12:58:15 -0500 |
---|---|---|
committer | Gabe Black <gblack@eecs.umich.edu> | 2010-06-02 12:58:15 -0500 |
commit | 1b3b75ee681b1fe83ccf1240bf5d1afa174c6421 (patch) | |
tree | abe49217ba3ff36794ffbb3d245dfd1b3c433c39 | |
parent | aa05e5401c37c7e60f28e13f8e6de5c5f74e904d (diff) | |
download | gem5-1b3b75ee681b1fe83ccf1240bf5d1afa174c6421.tar.xz |
ARM: Implement the version of VCVT float to int that rounds towards zero.
-rw-r--r-- | src/arch/arm/isa/formats/fp.isa | 40 | ||||
-rw-r--r-- | src/arch/arm/isa/insts/fp.isa | 62 |
2 files changed, 90 insertions, 12 deletions
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; |