summaryrefslogtreecommitdiff
path: root/vm/mterp/x86/OP_SGET.S
diff options
context:
space:
mode:
Diffstat (limited to 'vm/mterp/x86/OP_SGET.S')
-rw-r--r--vm/mterp/x86/OP_SGET.S43
1 files changed, 43 insertions, 0 deletions
diff --git a/vm/mterp/x86/OP_SGET.S b/vm/mterp/x86/OP_SGET.S
new file mode 100644
index 0000000..f05eae7
--- /dev/null
+++ b/vm/mterp/x86/OP_SGET.S
@@ -0,0 +1,43 @@
+%verify "executed"
+%verify "field already resolved"
+%verify "field not yet resolved"
+%verify "field cannot be resolved"
+ /*
+ * General 32-bit SGET handler.
+ *
+ * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
+ */
+ /* op vAA, field@BBBB */
+ GET_GLUE(%ecx)
+ movzwl 2(rPC),%eax # eax<- field ref BBBB
+ movl offGlue_methodClassDex(%ecx),%ecx # ecx<- DvmDex
+ movl offDvmDex_pResFields(%ecx),%ecx # ecx<- dvmDex->pResFields
+ movl (%ecx,%eax,4),%eax # eax<- resolved StaticField ptr
+ testl %eax,%eax # resolved entry null?
+ je .L${opcode}_resolve # if not, make it so
+.L${opcode}_finish: # field ptr in eax
+ movl offStaticField_value(%eax),%eax
+ movzbl rINST_HI,%ecx # ecx<- AA
+ FETCH_INST_WORD(2)
+ ADVANCE_PC(2)
+ SET_VREG(%eax,%ecx)
+ GOTO_NEXT
+%break
+
+ /*
+ * Go resolve the field
+ */
+.L${opcode}_resolve:
+ GET_GLUE(%ecx)
+ movzwl 2(rPC),%eax # eax<- field ref BBBB
+ movl offGlue_method(%ecx),%ecx # ecx<- current method
+ EXPORT_PC() # could throw, need to export
+ movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz
+ SPILL(rPC)
+ movl %eax,OUT_ARG1(%esp)
+ movl %ecx,OUT_ARG0(%esp)
+ call dvmResolveStaticField # eax<- resolved StaticField ptr
+ UNSPILL(rPC)
+ testl %eax,%eax
+ jne .L${opcode}_finish # success, continue
+ jmp common_exceptionThrown # no, handle exception