summaryrefslogtreecommitdiff
path: root/src/arch/arm/isa
diff options
context:
space:
mode:
authorGabe Black <gblack@eecs.umich.edu>2010-06-02 12:58:16 -0500
committerGabe Black <gblack@eecs.umich.edu>2010-06-02 12:58:16 -0500
commit237c0617a0c095e35169c3f4e48e93eaf4ada527 (patch)
treeb4b3c805611a04dc8bcdc923e0133c071374a4b2 /src/arch/arm/isa
parent04e196f4223b5dfd61782edaaac27166a2bfcf3c (diff)
downloadgem5-237c0617a0c095e35169c3f4e48e93eaf4ada527.tar.xz
ARM: Implement conversion to/from half precision.
Diffstat (limited to 'src/arch/arm/isa')
-rw-r--r--src/arch/arm/isa/formats/fp.isa19
-rw-r--r--src/arch/arm/isa/insts/fp.isa69
2 files changed, 86 insertions, 2 deletions
diff --git a/src/arch/arm/isa/formats/fp.isa b/src/arch/arm/isa/formats/fp.isa
index d509fc28a..03e574648 100644
--- a/src/arch/arm/isa/formats/fp.isa
+++ b/src/arch/arm/isa/formats/fp.isa
@@ -655,8 +655,23 @@ let {{
}
case 0x2:
case 0x3:
- // Between half and single precision.
- return new WarnUnimplemented("vcvtb, vcvtt", machInst);
+ {
+ const bool toHalf = bits(machInst, 16);
+ const bool top = bits(machInst, 7);
+ if (top) {
+ if (toHalf) {
+ return new VcvtFpSFpHT(machInst, vd, vm);
+ } else {
+ return new VcvtFpHTFpS(machInst, vd, vm);
+ }
+ } else {
+ if (toHalf) {
+ return new VcvtFpSFpHB(machInst, vd, vm);
+ } else {
+ return new VcvtFpHBFpS(machInst, vd, vm);
+ }
+ }
+ }
case 0x4:
if (single) {
if (e) {
diff --git a/src/arch/arm/isa/insts/fp.isa b/src/arch/arm/isa/insts/fp.isa
index bee63d671..c4682b66c 100644
--- a/src/arch/arm/isa/insts/fp.isa
+++ b/src/arch/arm/isa/insts/fp.isa
@@ -912,6 +912,75 @@ let {{
decoder_output += FpRegRegOpConstructor.subst(vcvtFpDFpSIop);
exec_output += PredOpExecute.subst(vcvtFpDFpSIop);
+ vcvtFpHTFpSCode = '''
+ FPSCR fpscr = Fpscr;
+ vfpFlushToZero(fpscr, FpOp1);
+ VfpSavedState state = prepFpState(fpscr.rMode);
+ __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
+ FpDest = vcvtFpHFpS(fpscr, FpOp1, true);
+ __asm__ __volatile__("" :: "m" (FpDest));
+ finishVfp(fpscr, state);
+ Fpscr = fpscr;
+ '''
+ vcvtFpHTFpSIop = InstObjParams("vcvtt", "VcvtFpHTFpS", "FpRegRegOp",
+ { "code": vcvtFpHTFpSCode,
+ "predicate_test": predicateTest }, [])
+ header_output += FpRegRegOpDeclare.subst(vcvtFpHTFpSIop);
+ decoder_output += FpRegRegOpConstructor.subst(vcvtFpHTFpSIop);
+ exec_output += PredOpExecute.subst(vcvtFpHTFpSIop);
+
+ vcvtFpHBFpSCode = '''
+ FPSCR fpscr = Fpscr;
+ VfpSavedState state = prepFpState(fpscr.rMode);
+ __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
+ FpDest = vcvtFpHFpS(fpscr, FpOp1, false);
+ __asm__ __volatile__("" :: "m" (FpDest));
+ finishVfp(fpscr, state);
+ Fpscr = fpscr;
+ '''
+ vcvtFpHBFpSIop = InstObjParams("vcvtb", "VcvtFpHBFpS", "FpRegRegOp",
+ { "code": vcvtFpHBFpSCode,
+ "predicate_test": predicateTest }, [])
+ header_output += FpRegRegOpDeclare.subst(vcvtFpHBFpSIop);
+ decoder_output += FpRegRegOpConstructor.subst(vcvtFpHBFpSIop);
+ exec_output += PredOpExecute.subst(vcvtFpHBFpSIop);
+
+ vcvtFpSFpHTCode = '''
+ FPSCR fpscr = Fpscr;
+ vfpFlushToZero(fpscr, FpOp1);
+ VfpSavedState state = prepFpState(fpscr.rMode);
+ __asm__ __volatile__("" : "=m" (FpOp1), "=m" (FpDest)
+ : "m" (FpOp1), "m" (FpDest));
+ FpDest = vcvtFpSFpH(fpscr, FpOp1, FpDest, true);
+ __asm__ __volatile__("" :: "m" (FpDest));
+ finishVfp(fpscr, state);
+ Fpscr = fpscr;
+ '''
+ vcvtFpSFpHTIop = InstObjParams("vcvtt", "VcvtFpSFpHT", "FpRegRegOp",
+ { "code": vcvtFpHTFpSCode,
+ "predicate_test": predicateTest }, [])
+ header_output += FpRegRegOpDeclare.subst(vcvtFpSFpHTIop);
+ decoder_output += FpRegRegOpConstructor.subst(vcvtFpSFpHTIop);
+ exec_output += PredOpExecute.subst(vcvtFpSFpHTIop);
+
+ vcvtFpSFpHBCode = '''
+ FPSCR fpscr = Fpscr;
+ vfpFlushToZero(fpscr, FpOp1);
+ VfpSavedState state = prepFpState(fpscr.rMode);
+ __asm__ __volatile__("" : "=m" (FpOp1), "=m" (FpDest)
+ : "m" (FpOp1), "m" (FpDest));
+ FpDest = vcvtFpSFpH(fpscr, FpOp1, FpDest, false);
+ __asm__ __volatile__("" :: "m" (FpDest));
+ finishVfp(fpscr, state);
+ Fpscr = fpscr;
+ '''
+ vcvtFpSFpHBIop = InstObjParams("vcvtb", "VcvtFpSFpHB", "FpRegRegOp",
+ { "code": vcvtFpSFpHBCode,
+ "predicate_test": predicateTest }, [])
+ header_output += FpRegRegOpDeclare.subst(vcvtFpSFpHBIop);
+ decoder_output += FpRegRegOpConstructor.subst(vcvtFpSFpHBIop);
+ exec_output += PredOpExecute.subst(vcvtFpSFpHBIop);
+
vcmpSCode = '''
FPSCR fpscr = Fpscr;
vfpFlushToZero(fpscr, FpDest, FpOp1);