summaryrefslogtreecommitdiff
path: root/vm/mterp/x86/OP_EXECUTE_INLINE.S
diff options
context:
space:
mode:
Diffstat (limited to 'vm/mterp/x86/OP_EXECUTE_INLINE.S')
-rw-r--r--vm/mterp/x86/OP_EXECUTE_INLINE.S66
1 files changed, 66 insertions, 0 deletions
diff --git a/vm/mterp/x86/OP_EXECUTE_INLINE.S b/vm/mterp/x86/OP_EXECUTE_INLINE.S
new file mode 100644
index 0000000..1eca6e2
--- /dev/null
+++ b/vm/mterp/x86/OP_EXECUTE_INLINE.S
@@ -0,0 +1,66 @@
+%verify "executed"
+%verify "exception handled"
+ /*
+ * Execute a "native inline" instruction.
+ *
+ * We will be calling through a function table:
+ *
+ * (*gDvmInlineOpsTable[opIndex].func)(arg0, arg1, arg2, arg3, pResult)
+ *
+ */
+ /* [opt] execute-inline vAA, {vC, vD, vE, vF}, inline@BBBB */
+ GET_GLUE(%ecx)
+ EXPORT_PC()
+ movzwl 2(rPC),%eax # eax<- BBBB
+ leal offGlue_retval(%ecx),%ecx # ecx<- & glue->retval
+ movl %ecx,OUT_ARG4(%esp)
+ sarl $$12,rINST_FULL # rINST_FULL<- arg count (0-4)
+ SPILL(rPC)
+ call .L${opcode}_continue # make call; will return after
+ UNSPILL(rPC)
+ testl %eax,%eax # successful?
+ FETCH_INST_WORD(3)
+ je common_exceptionThrown # no, handle exception
+ ADVANCE_PC(3)
+ GOTO_NEXT
+%break
+
+.L${opcode}_continue:
+ /*
+ * Extract args, call function.
+ * ecx = #of args (0-4)
+ * eax = call index
+ * @esp = return addr
+ * esp is -4 from normal
+ *
+ * Go ahead and load all 4 args, even if not used.
+ */
+ movzwl 4(rPC),rPC
+
+ movl $$0xf,%ecx
+ andl rPC,%ecx
+ GET_VREG(%ecx,%ecx)
+ sarl $$4,rPC
+ movl %ecx,4+OUT_ARG0(%esp)
+
+ movl $$0xf,%ecx
+ andl rPC,%ecx
+ GET_VREG(%ecx,%ecx)
+ sarl $$4,rPC
+ movl %ecx,4+OUT_ARG1(%esp)
+
+ movl $$0xf,%ecx
+ andl rPC,%ecx
+ GET_VREG(%ecx,%ecx)
+ sarl $$4,rPC
+ movl %ecx,4+OUT_ARG2(%esp)
+
+ movl $$0xf,%ecx
+ andl rPC,%ecx
+ GET_VREG(%ecx,%ecx)
+ sarl $$4,rPC
+ movl %ecx,4+OUT_ARG3(%esp)
+
+ sall $$4,%eax # index *= sizeof(table entry)
+ jmp *gDvmInlineOpsTable(%eax)
+ # will return to caller of .L${opcode}_continue