Jit: Save/restore callee-save floating point registers at interpreter entry/exit
diff --git a/vm/compiler/template/armv5te-vfp/platform.S b/vm/compiler/template/armv5te-vfp/platform.S
new file mode 100644
index 0000000..4c8c2a2
--- /dev/null
+++ b/vm/compiler/template/armv5te-vfp/platform.S
@@ -0,0 +1,36 @@
+/*
+ * ===========================================================================
+ *  CPU-version-specific defines and utility
+ * ===========================================================================
+ */
+
+/*
+ * Macro for "MOV LR,PC / LDR PC,xxx", which is not allowed pre-ARMv5.
+ * Jump to subroutine.
+ *
+ * May modify IP and LR.
+ */
+.macro  LDR_PC_LR source
+    mov     lr, pc
+    ldr     pc, \source
+.endm
+
+/*
+ * Save & restore for callee-save FP registers.
+ * On entry:
+ *    r0 : pointer to save area of JIT_CALLEE_SAVE_WORD_SIZE
+ */
+    .text
+    .align 2
+    .global dvmJitCalleeSave
+    .type dvmJitCalleeSave, %function
+dvmJitCalleeSave:
+    vstmia r0, {d8-d15}
+    bx     lr
+
+    .global dvmJitCalleeRestore
+    .type dvmJitCalleeRestore, %function
+dvmJitCalleeRestore:
+    vldmia r0, {d8-d15}
+    bx     lr
+
diff --git a/vm/compiler/template/armv5te/platform.S b/vm/compiler/template/armv5te/platform.S
index b960a93..3cefa6d 100644
--- a/vm/compiler/template/armv5te/platform.S
+++ b/vm/compiler/template/armv5te/platform.S
@@ -1,6 +1,6 @@
 /*
  * ===========================================================================
- *  CPU-version-specific defines
+ *  CPU-version-specific defines and utility
  * ===========================================================================
  */
 
@@ -14,3 +14,21 @@
     mov     lr, pc
     ldr     pc, \source
 .endm
+
+/*
+ * Save & restore for callee-save FP registers.
+ * On entry:
+ *    r0 : pointer to save area of JIT_CALLEE_SAVE_WORD_SIZE
+ */
+    .text
+    .align 2
+    .global dvmJitCalleeSave
+    .type dvmJitCalleeSave, %function
+dvmJitCalleeSave:
+    bx     lr
+
+    .global dvmJitCalleeRestore
+    .type dvmJitCalleeRestore, %function
+dvmJitCalleeRestore:
+    bx     lr
+
diff --git a/vm/compiler/template/config-armv5te-vfp b/vm/compiler/template/config-armv5te-vfp
index fc968fe..0a1c7c7 100644
--- a/vm/compiler/template/config-armv5te-vfp
+++ b/vm/compiler/template/config-armv5te-vfp
@@ -25,7 +25,7 @@
 #import cstubs/stubdefs.c
 
 # highly-platform-specific defs
-import armv5te/platform.S
+import armv5te-vfp/platform.S
 
 # common defs for the C helpers; include this before the instruction handlers
 #import c/opcommon.c
diff --git a/vm/compiler/template/config-armv7-a b/vm/compiler/template/config-armv7-a
index 7f7b478..89fbb23 100644
--- a/vm/compiler/template/config-armv7-a
+++ b/vm/compiler/template/config-armv7-a
@@ -25,7 +25,7 @@
 #import cstubs/stubdefs.c
 
 # highly-platform-specific defs
-import armv5te/platform.S
+import armv5te-vfp/platform.S
 
 # common defs for the C helpers; include this before the instruction handlers
 #import c/opcommon.c
diff --git a/vm/compiler/template/out/CompilerTemplateAsm-armv5te-vfp.S b/vm/compiler/template/out/CompilerTemplateAsm-armv5te-vfp.S
index 80a9dd8..0dfb986 100644
--- a/vm/compiler/template/out/CompilerTemplateAsm-armv5te-vfp.S
+++ b/vm/compiler/template/out/CompilerTemplateAsm-armv5te-vfp.S
@@ -102,10 +102,10 @@
 #include "../../../mterp/common/asm-constants.h"
 
 
-/* File: armv5te/platform.S */
+/* File: armv5te-vfp/platform.S */
 /*
  * ===========================================================================
- *  CPU-version-specific defines
+ *  CPU-version-specific defines and utility
  * ===========================================================================
  */
 
@@ -120,6 +120,26 @@
     ldr     pc, \source
 .endm
 
+/*
+ * Save & restore for callee-save FP registers.
+ * On entry:
+ *    r0 : pointer to save area of JIT_CALLEE_SAVE_WORD_SIZE
+ */
+    .text
+    .align 2
+    .global dvmJitCalleeSave
+    .type dvmJitCalleeSave, %function
+dvmJitCalleeSave:
+    vstmia r0, {d8-d15}
+    bx     lr
+
+    .global dvmJitCalleeRestore
+    .type dvmJitCalleeRestore, %function
+dvmJitCalleeRestore:
+    vldmia r0, {d8-d15}
+    bx     lr
+
+
 
     .global dvmCompilerTemplateStart
     .type   dvmCompilerTemplateStart, %function
diff --git a/vm/compiler/template/out/CompilerTemplateAsm-armv5te.S b/vm/compiler/template/out/CompilerTemplateAsm-armv5te.S
index a83344a..0e79497 100644
--- a/vm/compiler/template/out/CompilerTemplateAsm-armv5te.S
+++ b/vm/compiler/template/out/CompilerTemplateAsm-armv5te.S
@@ -105,7 +105,7 @@
 /* File: armv5te/platform.S */
 /*
  * ===========================================================================
- *  CPU-version-specific defines
+ *  CPU-version-specific defines and utility
  * ===========================================================================
  */
 
@@ -120,6 +120,24 @@
     ldr     pc, \source
 .endm
 
+/*
+ * Save & restore for callee-save FP registers.
+ * On entry:
+ *    r0 : pointer to save area of JIT_CALLEE_SAVE_WORD_SIZE
+ */
+    .text
+    .align 2
+    .global dvmJitCalleeSave
+    .type dvmJitCalleeSave, %function
+dvmJitCalleeSave:
+    bx     lr
+
+    .global dvmJitCalleeRestore
+    .type dvmJitCalleeRestore, %function
+dvmJitCalleeRestore:
+    bx     lr
+
+
 
     .global dvmCompilerTemplateStart
     .type   dvmCompilerTemplateStart, %function
diff --git a/vm/compiler/template/out/CompilerTemplateAsm-armv7-a.S b/vm/compiler/template/out/CompilerTemplateAsm-armv7-a.S
index cb47011..ff69653 100644
--- a/vm/compiler/template/out/CompilerTemplateAsm-armv7-a.S
+++ b/vm/compiler/template/out/CompilerTemplateAsm-armv7-a.S
@@ -102,10 +102,10 @@
 #include "../../../mterp/common/asm-constants.h"
 
 
-/* File: armv5te/platform.S */
+/* File: armv5te-vfp/platform.S */
 /*
  * ===========================================================================
- *  CPU-version-specific defines
+ *  CPU-version-specific defines and utility
  * ===========================================================================
  */
 
@@ -120,6 +120,26 @@
     ldr     pc, \source
 .endm
 
+/*
+ * Save & restore for callee-save FP registers.
+ * On entry:
+ *    r0 : pointer to save area of JIT_CALLEE_SAVE_WORD_SIZE
+ */
+    .text
+    .align 2
+    .global dvmJitCalleeSave
+    .type dvmJitCalleeSave, %function
+dvmJitCalleeSave:
+    vstmia r0, {d8-d15}
+    bx     lr
+
+    .global dvmJitCalleeRestore
+    .type dvmJitCalleeRestore, %function
+dvmJitCalleeRestore:
+    vldmia r0, {d8-d15}
+    bx     lr
+
+
 
     .global dvmCompilerTemplateStart
     .type   dvmCompilerTemplateStart, %function
diff --git a/vm/interp/Interp.c b/vm/interp/Interp.c
index 10b9bb1..2a7476c 100644
--- a/vm/interp/Interp.c
+++ b/vm/interp/Interp.c
@@ -1219,6 +1219,9 @@
     InterpState interpState;
     bool change;
 #if defined(WITH_JIT)
+    /* Target-specific save/restore */
+    extern void dvmJitCalleeSave(double *saveArea);
+    extern void dvmJitCalleeRestore(double *saveArea);
     /* Interpreter entry points from compiled code */
     extern void dvmJitToInterpNormal();
     extern void dvmJitToInterpNoChain();
@@ -1256,6 +1259,7 @@
     interpState.debugIsMethodEntry = true;
 #endif
 #if defined(WITH_JIT)
+    dvmJitCalleeSave(interpState.calleeSave);
     interpState.jitState = gDvmJit.pJitEntryTable ? kJitNormal : kJitOff;
 
     /* Setup the Jit-to-interpreter entry points */
@@ -1333,4 +1337,7 @@
     }
 
     *pResult = interpState.retval;
+#if defined(WITH_JIT)
+    dvmJitCalleeRestore(interpState.calleeSave);
+#endif
 }
diff --git a/vm/interp/InterpDefs.h b/vm/interp/InterpDefs.h
index 744033e..2928371 100644
--- a/vm/interp/InterpDefs.h
+++ b/vm/interp/InterpDefs.h
@@ -93,6 +93,14 @@
 #endif
 };
 
+/*
+ * Size of save area for callee-save FP regs, which are not automatically
+ * saved by interpreter main because it doesn't use them (but Jit'd code
+ * may). Save/restore routine is defined by target, and size should
+ * be >= max needed by any target.
+ */
+#define JIT_CALLEE_SAVE_DOUBLE_COUNT 8
+
 #define JIT_TRACE_THRESH_FILTER_SIZE  16
 #endif
 
@@ -175,6 +183,7 @@
 #endif
     const u2* threshFilter[JIT_TRACE_THRESH_FILTER_SIZE];
     JitTraceRun trace[MAX_JIT_RUN_LEN];
+    double calleeSave[JIT_CALLEE_SAVE_DOUBLE_COUNT];
 #endif
 
 } InterpState;
diff --git a/vm/mterp/common/asm-constants.h b/vm/mterp/common/asm-constants.h
index f982793..c5a6baa 100644
--- a/vm/mterp/common/asm-constants.h
+++ b/vm/mterp/common/asm-constants.h
@@ -247,6 +247,9 @@
 MTERP_CONSTANT(kInlineCacheMiss,        0)
 MTERP_CONSTANT(kCallsiteInterpreted,    1)
 MTERP_CONSTANT(kSwitchOverflow,         2)
+
+/* Size of callee save area */
+MTERP_CONSTANT(JIT_CALLEE_SAVE_DOUBLE_COUNT,   8)
 #endif
 
 /* ClassObject fields */