Merge "Fix StackWalk test."
diff --git a/compiler/optimizing/code_generator_vector_arm64.cc b/compiler/optimizing/code_generator_vector_arm64.cc
index 6d135a9..43169ba 100644
--- a/compiler/optimizing/code_generator_vector_arm64.cc
+++ b/compiler/optimizing/code_generator_vector_arm64.cc
@@ -1354,6 +1354,7 @@
Register scratch;
switch (instruction->GetPackedType()) {
+ case DataType::Type::kInt16: // (short) s.charAt(.) can yield HVecLoad/Int16/StringCharAt.
case DataType::Type::kUint16:
DCHECK_EQ(8u, instruction->GetVectorLength());
// Special handling of compressed/uncompressed string load.
@@ -1385,7 +1386,6 @@
case DataType::Type::kBool:
case DataType::Type::kUint8:
case DataType::Type::kInt8:
- case DataType::Type::kInt16:
case DataType::Type::kInt32:
case DataType::Type::kFloat32:
case DataType::Type::kInt64:
diff --git a/compiler/optimizing/code_generator_vector_x86.cc b/compiler/optimizing/code_generator_vector_x86.cc
index 086ae07..2502275 100644
--- a/compiler/optimizing/code_generator_vector_x86.cc
+++ b/compiler/optimizing/code_generator_vector_x86.cc
@@ -1205,6 +1205,7 @@
XmmRegister reg = locations->Out().AsFpuRegister<XmmRegister>();
bool is_aligned16 = instruction->GetAlignment().IsAlignedAt(16);
switch (instruction->GetPackedType()) {
+ case DataType::Type::kInt16: // (short) s.charAt(.) can yield HVecLoad/Int16/StringCharAt.
case DataType::Type::kUint16:
DCHECK_EQ(8u, instruction->GetVectorLength());
// Special handling of compressed/uncompressed string load.
@@ -1232,7 +1233,6 @@
case DataType::Type::kBool:
case DataType::Type::kUint8:
case DataType::Type::kInt8:
- case DataType::Type::kInt16:
case DataType::Type::kInt32:
case DataType::Type::kInt64:
DCHECK_LE(2u, instruction->GetVectorLength());
diff --git a/compiler/optimizing/code_generator_vector_x86_64.cc b/compiler/optimizing/code_generator_vector_x86_64.cc
index 4d31ab6..4a67daf 100644
--- a/compiler/optimizing/code_generator_vector_x86_64.cc
+++ b/compiler/optimizing/code_generator_vector_x86_64.cc
@@ -1178,6 +1178,7 @@
XmmRegister reg = locations->Out().AsFpuRegister<XmmRegister>();
bool is_aligned16 = instruction->GetAlignment().IsAlignedAt(16);
switch (instruction->GetPackedType()) {
+ case DataType::Type::kInt16: // (short) s.charAt(.) can yield HVecLoad/Int16/StringCharAt.
case DataType::Type::kUint16:
DCHECK_EQ(8u, instruction->GetVectorLength());
// Special handling of compressed/uncompressed string load.
@@ -1205,7 +1206,6 @@
case DataType::Type::kBool:
case DataType::Type::kUint8:
case DataType::Type::kInt8:
- case DataType::Type::kInt16:
case DataType::Type::kInt32:
case DataType::Type::kInt64:
DCHECK_LE(2u, instruction->GetVectorLength());
diff --git a/libartbase/base/utils.cc b/libartbase/base/utils.cc
index 761c611..74cc5b9 100644
--- a/libartbase/base/utils.cc
+++ b/libartbase/base/utils.cc
@@ -38,6 +38,12 @@
#include "AvailabilityMacros.h" // For MAC_OS_X_VERSION_MAX_ALLOWED
#endif
+#if defined(__BIONIC__)
+// membarrier(2) is only supported for target builds (b/111199492).
+#include <linux/membarrier.h>
+#include <sys/syscall.h>
+#endif
+
#if defined(__linux__)
#include <linux/unistd.h>
#endif
@@ -207,4 +213,42 @@
}
}
+bool FlushInstructionPipeline() {
+ // membarrier(2) is only supported for target builds (b/111199492).
+#if defined(__BIONIC__)
+ static constexpr int kSyncCoreMask =
+ MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE |
+ MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE;
+ static bool have_probed = false;
+ static bool have_sync_core = false;
+
+ if (UNLIKELY(!have_probed)) {
+ // Probe membarrier(2) commands supported by kernel.
+ int commands = syscall(__NR_membarrier, MEMBARRIER_CMD_QUERY, 0);
+ if (commands >= 0) {
+ have_sync_core = (commands & kSyncCoreMask) == kSyncCoreMask;
+ if (have_sync_core) {
+ // Register with kernel that we'll be using the private expedited sync core command.
+ CheckedCall(syscall,
+ "membarrier register sync core",
+ __NR_membarrier,
+ MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE,
+ 0);
+ }
+ }
+ have_probed = true;
+ }
+
+ if (have_sync_core) {
+ CheckedCall(syscall,
+ "membarrier sync core",
+ __NR_membarrier,
+ MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE,
+ 0);
+ return true;
+ }
+#endif // defined(__BIONIC__)
+ return false;
+}
+
} // namespace art
diff --git a/libartbase/base/utils.h b/libartbase/base/utils.h
index ba61e1b..4449941 100644
--- a/libartbase/base/utils.h
+++ b/libartbase/base/utils.h
@@ -179,16 +179,19 @@
// Sleep forever and never come back.
NO_RETURN void SleepForever();
-inline void FlushInstructionCache(char* begin, char* end) {
- __builtin___clear_cache(begin, end);
-}
-
inline void FlushDataCache(char* begin, char* end) {
// Same as FlushInstructionCache for lack of other builtin. __builtin___clear_cache
// flushes both caches.
__builtin___clear_cache(begin, end);
}
+inline void FlushInstructionCache(char* begin, char* end) {
+ __builtin___clear_cache(begin, end);
+}
+
+// Flush instruction pipeline. Returns true on success, false if feature is unsupported.
+bool FlushInstructionPipeline();
+
template <typename T>
constexpr PointerSize ConvertToPointerSize(T any) {
if (any == 4 || any == 8) {
diff --git a/runtime/art_method-inl.h b/runtime/art_method-inl.h
index f693524..9b69166 100644
--- a/runtime/art_method-inl.h
+++ b/runtime/art_method-inl.h
@@ -417,7 +417,6 @@
case Intrinsics::kMemoryPokeIntNative:
case Intrinsics::kMemoryPokeLongNative:
case Intrinsics::kMemoryPokeShortNative:
- return HiddenApiAccessFlags::kDarkGreylist;
case Intrinsics::kVarHandleFullFence:
case Intrinsics::kVarHandleAcquireFence:
case Intrinsics::kVarHandleReleaseFence:
diff --git a/runtime/entrypoints/entrypoint_utils-inl.h b/runtime/entrypoints/entrypoint_utils-inl.h
index e6f3d0b..1045d2a 100644
--- a/runtime/entrypoints/entrypoint_utils-inl.h
+++ b/runtime/entrypoints/entrypoint_utils-inl.h
@@ -317,20 +317,9 @@
ArtMethod* referrer,
Thread* self,
size_t expected_size) {
- bool is_primitive;
- bool is_set;
- bool is_static;
- switch (type) {
- case InstanceObjectRead: is_primitive = false; is_set = false; is_static = false; break;
- case InstanceObjectWrite: is_primitive = false; is_set = true; is_static = false; break;
- case InstancePrimitiveRead: is_primitive = true; is_set = false; is_static = false; break;
- case InstancePrimitiveWrite: is_primitive = true; is_set = true; is_static = false; break;
- case StaticObjectRead: is_primitive = false; is_set = false; is_static = true; break;
- case StaticObjectWrite: is_primitive = false; is_set = true; is_static = true; break;
- case StaticPrimitiveRead: is_primitive = true; is_set = false; is_static = true; break;
- case StaticPrimitiveWrite: // Keep GCC happy by having a default handler, fall-through.
- default: is_primitive = true; is_set = true; is_static = true; break;
- }
+ constexpr bool is_primitive = (type & FindFieldFlags::PrimitiveBit) != 0;
+ constexpr bool is_set = (type & FindFieldFlags::WriteBit) != 0;
+ constexpr bool is_static = (type & FindFieldFlags::StaticBit) != 0;
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
ArtField* resolved_field;
@@ -611,22 +600,9 @@
return nullptr;
}
// Check for incompatible class change.
- bool is_primitive;
- bool is_set;
- bool is_static;
- switch (type) {
- case InstanceObjectRead: is_primitive = false; is_set = false; is_static = false; break;
- case InstanceObjectWrite: is_primitive = false; is_set = true; is_static = false; break;
- case InstancePrimitiveRead: is_primitive = true; is_set = false; is_static = false; break;
- case InstancePrimitiveWrite: is_primitive = true; is_set = true; is_static = false; break;
- case StaticObjectRead: is_primitive = false; is_set = false; is_static = true; break;
- case StaticObjectWrite: is_primitive = false; is_set = true; is_static = true; break;
- case StaticPrimitiveRead: is_primitive = true; is_set = false; is_static = true; break;
- case StaticPrimitiveWrite: is_primitive = true; is_set = true; is_static = true; break;
- default:
- LOG(FATAL) << "UNREACHABLE";
- UNREACHABLE();
- }
+ const bool is_primitive = (type & FindFieldFlags::PrimitiveBit) != 0;
+ const bool is_set = (type & FindFieldFlags::WriteBit) != 0;
+ const bool is_static = (type & FindFieldFlags::StaticBit) != 0;
if (UNLIKELY(resolved_field->IsStatic() != is_static)) {
// Incompatible class change.
return nullptr;
diff --git a/runtime/entrypoints/entrypoint_utils.h b/runtime/entrypoints/entrypoint_utils.h
index 9d70b03..c8bf6d0 100644
--- a/runtime/entrypoints/entrypoint_utils.h
+++ b/runtime/entrypoints/entrypoint_utils.h
@@ -103,16 +103,25 @@
REQUIRES_SHARED(Locks::mutator_lock_)
REQUIRES(!Roles::uninterruptible_);
+enum FindFieldFlags {
+ InstanceBit = 1 << 0,
+ StaticBit = 1 << 1,
+ ObjectBit = 1 << 2,
+ PrimitiveBit = 1 << 3,
+ ReadBit = 1 << 4,
+ WriteBit = 1 << 5,
+};
+
// Type of find field operation for fast and slow case.
enum FindFieldType {
- InstanceObjectRead,
- InstanceObjectWrite,
- InstancePrimitiveRead,
- InstancePrimitiveWrite,
- StaticObjectRead,
- StaticObjectWrite,
- StaticPrimitiveRead,
- StaticPrimitiveWrite,
+ InstanceObjectRead = InstanceBit | ObjectBit | ReadBit,
+ InstanceObjectWrite = InstanceBit | ObjectBit | WriteBit,
+ InstancePrimitiveRead = InstanceBit | PrimitiveBit | ReadBit,
+ InstancePrimitiveWrite = InstanceBit | PrimitiveBit | WriteBit,
+ StaticObjectRead = StaticBit | ObjectBit | ReadBit,
+ StaticObjectWrite = StaticBit | ObjectBit | WriteBit,
+ StaticPrimitiveRead = StaticBit | PrimitiveBit | ReadBit,
+ StaticPrimitiveWrite = StaticBit | PrimitiveBit | WriteBit,
};
template<FindFieldType type, bool access_check>
diff --git a/runtime/entrypoints/quick/quick_field_entrypoints.cc b/runtime/entrypoints/quick/quick_field_entrypoints.cc
index 62cc9de..d38e3ed 100644
--- a/runtime/entrypoints/quick/quick_field_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_field_entrypoints.cc
@@ -28,13 +28,6 @@
namespace art {
-inline constexpr bool FindFieldTypeIsRead(FindFieldType type) {
- return type == InstanceObjectRead ||
- type == InstancePrimitiveRead ||
- type == StaticObjectRead ||
- type == StaticPrimitiveRead;
-}
-
// Helper function to do a null check after trying to resolve the field. Not for statics since obj
// does not exist there. There is a suspend check, object is a double pointer to update the value
// in the caller in case it moves.
@@ -50,7 +43,7 @@
HandleWrapper<mirror::Object> h(hs.NewHandleWrapper(obj));
ArtField* field = FindFieldFromCode<type, kAccessCheck>(field_idx, referrer, self, size);
if (LIKELY(field != nullptr) && UNLIKELY(h == nullptr)) {
- ThrowNullPointerExceptionForFieldAccess(field, /*is_read*/FindFieldTypeIsRead(type));
+ ThrowNullPointerExceptionForFieldAccess(field, (type & FindFieldFlags::ReadBit) != 0);
return nullptr;
}
return field;
diff --git a/runtime/gc/collector/concurrent_copying.cc b/runtime/gc/collector/concurrent_copying.cc
index 3a80008..0c18767 100644
--- a/runtime/gc/collector/concurrent_copying.cc
+++ b/runtime/gc/collector/concurrent_copying.cc
@@ -2331,6 +2331,7 @@
CHECK(!region_space_->HasAddress(ref)) << "obj=" << obj << " ref=" << ref;
// In a non-moving space. Check that the ref is marked.
if (immune_spaces_.ContainsObject(ref)) {
+ // Immune space case.
if (kUseBakerReadBarrier) {
// Immune object may not be gray if called from the GC.
if (Thread::Current() == thread_running_gc_ && !gc_grays_immune_objects_) {
@@ -2344,28 +2345,68 @@
<< " updated_all_immune_objects=" << updated_all_immune_objects;
}
} else {
+ // Non-moving space and large-object space (LOS) cases.
accounting::ContinuousSpaceBitmap* mark_bitmap =
heap_mark_bitmap_->GetContinuousSpaceBitmap(ref);
accounting::LargeObjectBitmap* los_bitmap =
heap_mark_bitmap_->GetLargeObjectBitmap(ref);
- bool is_los = mark_bitmap == nullptr;
- if ((!is_los && mark_bitmap->Test(ref)) ||
- (is_los && los_bitmap->Test(ref))) {
- // OK.
- } else {
- // If `ref` is on the allocation stack, then it may not be
- // marked live, but considered marked/alive (but not
- // necessarily on the live stack).
- CHECK(IsOnAllocStack(ref))
- << "Unmarked ref that's not on the allocation stack."
- << " obj=" << obj
- << " ref=" << ref
- << " rb_state=" << ref->GetReadBarrierState()
- << " is_los=" << std::boolalpha << is_los << std::noboolalpha
- << " is_marking=" << std::boolalpha << is_marking_ << std::noboolalpha
- << " young_gen=" << std::boolalpha << young_gen_ << std::noboolalpha
- << " self=" << Thread::Current();
- }
+ bool is_los = (mark_bitmap == nullptr);
+
+ bool marked_in_non_moving_space_or_los =
+ (kUseBakerReadBarrier
+ && kEnableGenerationalConcurrentCopyingCollection
+ && young_gen_
+ && !done_scanning_.load(std::memory_order_acquire))
+ // Don't use the mark bitmap to ensure `ref` is marked: check that the
+ // read barrier state is gray instead. This is to take into account a
+ // potential race between two read barriers on the same reference when the
+ // young-generation collector is still scanning the dirty cards.
+ //
+ // For instance consider two concurrent read barriers on the same GC root
+ // reference during the dirty-card-scanning step of a young-generation
+ // collection. Both threads would call ReadBarrier::BarrierForRoot, which
+ // would:
+ // a. mark the reference (leading to a call to
+ // ConcurrentCopying::MarkNonMoving); then
+ // b. check the to-space invariant (leading to a call this
+ // ConcurrentCopying::AssertToSpaceInvariantInNonMovingSpace -- this
+ // method).
+ //
+ // In this situation, the following race could happen:
+ // 1. Thread A successfully changes `ref`'s read barrier state from
+ // non-gray (white) to gray (with AtomicSetReadBarrierState) in
+ // ConcurrentCopying::MarkNonMoving, then gets preempted.
+ // 2. Thread B also tries to change `ref`'s read barrier state with
+ // AtomicSetReadBarrierState from non-gray to gray in
+ // ConcurrentCopying::MarkNonMoving, but fails, as Thread A already
+ // changed it.
+ // 3. Because Thread B failed the previous CAS, it does *not* set the
+ // bit in the mark bitmap for `ref`.
+ // 4. Thread B checks the to-space invariant and calls
+ // ConcurrentCopying::AssertToSpaceInvariantInNonMovingSpace: the bit
+ // is not set in the mark bitmap for `ref`; checking that this bit is
+ // set to check the to-space invariant is therefore not a reliable
+ // test.
+ // 5. (Note that eventually, Thread A will resume its execution and set
+ // the bit for `ref` in the mark bitmap.)
+ ? (ref->GetReadBarrierState() == ReadBarrier::GrayState())
+ // It is safe to use the heap mark bitmap otherwise.
+ : (!is_los && mark_bitmap->Test(ref)) || (is_los && los_bitmap->Test(ref));
+
+ // If `ref` is on the allocation stack, then it may not be
+ // marked live, but considered marked/alive (but not
+ // necessarily on the live stack).
+ CHECK(marked_in_non_moving_space_or_los || IsOnAllocStack(ref))
+ << "Unmarked ref that's not on the allocation stack."
+ << " obj=" << obj
+ << " ref=" << ref
+ << " rb_state=" << ref->GetReadBarrierState()
+ << " is_los=" << std::boolalpha << is_los << std::noboolalpha
+ << " is_marking=" << std::boolalpha << is_marking_ << std::noboolalpha
+ << " young_gen=" << std::boolalpha << young_gen_ << std::noboolalpha
+ << " done_scanning="
+ << std::boolalpha << done_scanning_.load(std::memory_order_acquire) << std::noboolalpha
+ << " self=" << Thread::Current();
}
}
diff --git a/runtime/interpreter/mterp/arm/field.S b/runtime/interpreter/mterp/arm/field.S
new file mode 100644
index 0000000..c468788
--- /dev/null
+++ b/runtime/interpreter/mterp/arm/field.S
@@ -0,0 +1,16 @@
+%default { }
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
+ .extern $helper
+ mov r0, rPC @ arg0: Instruction* inst
+ mov r1, rINST @ arg1: uint16_t inst_data
+ add r2, rFP, #OFF_FP_SHADOWFRAME @ arg2: ShadowFrame* sf
+ mov r3, rSELF @ arg3: Thread* self
+ PREFETCH_INST 2 @ prefetch next opcode
+ bl $helper
+ cmp r0, #0
+ beq MterpPossibleException
+ ADVANCE 2
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ GOTO_OPCODE ip @ jump to next instruction
diff --git a/runtime/interpreter/mterp/arm/op_iget.S b/runtime/interpreter/mterp/arm/op_iget.S
index 1684a76..1fa32fa 100644
--- a/runtime/interpreter/mterp/arm/op_iget.S
+++ b/runtime/interpreter/mterp/arm/op_iget.S
@@ -1,26 +1,2 @@
%default { "is_object":"0", "helper":"MterpIGetU32"}
- /*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
- */
- EXPORT_PC
- FETCH r0, 1 @ r0<- field ref CCCC
- mov r1, rINST, lsr #12 @ r1<- B
- GET_VREG r1, r1 @ r1<- fp[B], the object pointer
- ldr r2, [rFP, #OFF_FP_METHOD] @ r2<- referrer
- mov r3, rSELF @ r3<- self
- bl $helper
- ldr r3, [rSELF, #THREAD_EXCEPTION_OFFSET]
- ubfx r2, rINST, #8, #4 @ r2<- A
- PREFETCH_INST 2
- cmp r3, #0
- bne MterpPossibleException @ bail out
- .if $is_object
- SET_VREG_OBJECT r0, r2 @ fp[A]<- r0
- .else
- SET_VREG r0, r2 @ fp[A]<- r0
- .endif
- ADVANCE 2
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip @ jump to next instruction
+%include "arm/field.S" { }
diff --git a/runtime/interpreter/mterp/arm/op_iget_wide.S b/runtime/interpreter/mterp/arm/op_iget_wide.S
index 46e9ec8..ede21eb 100644
--- a/runtime/interpreter/mterp/arm/op_iget_wide.S
+++ b/runtime/interpreter/mterp/arm/op_iget_wide.S
@@ -1,23 +1 @@
- /*
- * 64-bit instance field get.
- *
- * for: iget-wide
- */
- EXPORT_PC
- FETCH r0, 1 @ r0<- field ref CCCC
- mov r1, rINST, lsr #12 @ r1<- B
- GET_VREG r1, r1 @ r1<- fp[B], the object pointer
- ldr r2, [rFP, #OFF_FP_METHOD] @ r2<- referrer
- mov r3, rSELF @ r3<- self
- bl MterpIGetU64
- ldr r3, [rSELF, #THREAD_EXCEPTION_OFFSET]
- ubfx r2, rINST, #8, #4 @ r2<- A
- PREFETCH_INST 2
- cmp r3, #0
- bne MterpException @ bail out
- CLEAR_SHADOW_PAIR r2, ip, lr @ Zero out the shadow regs
- VREG_INDEX_TO_ADDR r3, r2 @ r3<- &fp[A]
- stmia r3, {r0-r1} @ fp[A]<- r0/r1
- ADVANCE 2
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip @ jump to next instruction
+%include "arm/op_iget.S" { "helper":"MterpIGetU64" }
diff --git a/runtime/interpreter/mterp/arm/op_iput.S b/runtime/interpreter/mterp/arm/op_iput.S
index a16795d..6201d80 100644
--- a/runtime/interpreter/mterp/arm/op_iput.S
+++ b/runtime/interpreter/mterp/arm/op_iput.S
@@ -1,22 +1,2 @@
%default { "is_object":"0", "helper":"MterpIPutU32" }
- /*
- * General 32-bit instance field put.
- *
- * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
- */
- /* op vA, vB, field@CCCC */
- .extern $helper
- EXPORT_PC
- FETCH r0, 1 @ r0<- field ref CCCC
- mov r1, rINST, lsr #12 @ r1<- B
- GET_VREG r1, r1 @ r1<- fp[B], the object pointer
- ubfx r2, rINST, #8, #4 @ r2<- A
- GET_VREG r2, r2 @ r2<- fp[A]
- ldr r3, [rFP, #OFF_FP_METHOD] @ r3<- referrer
- PREFETCH_INST 2
- bl $helper
- cmp r0, #0
- bne MterpPossibleException
- ADVANCE 2 @ advance rPC
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip @ jump to next instruction
+%include "arm/field.S" { }
diff --git a/runtime/interpreter/mterp/arm/op_iput_object.S b/runtime/interpreter/mterp/arm/op_iput_object.S
index 4f401eb..1003d10 100644
--- a/runtime/interpreter/mterp/arm/op_iput_object.S
+++ b/runtime/interpreter/mterp/arm/op_iput_object.S
@@ -1,11 +1 @@
- EXPORT_PC
- add r0, rFP, #OFF_FP_SHADOWFRAME
- mov r1, rPC
- mov r2, rINST
- mov r3, rSELF
- bl MterpIPutObj
- cmp r0, #0
- beq MterpException
- FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip @ jump to next instruction
+%include "arm/op_iput.S" { "is_object":"1", "helper":"MterpIPutObj" }
diff --git a/runtime/interpreter/mterp/arm/op_iput_wide.S b/runtime/interpreter/mterp/arm/op_iput_wide.S
index 6a41473..f2845ad 100644
--- a/runtime/interpreter/mterp/arm/op_iput_wide.S
+++ b/runtime/interpreter/mterp/arm/op_iput_wide.S
@@ -1,16 +1 @@
- /* iput-wide vA, vB, field@CCCC */
- .extern MterpIPutU64
- EXPORT_PC
- FETCH r0, 1 @ r0<- field ref CCCC
- mov r1, rINST, lsr #12 @ r1<- B
- GET_VREG r1, r1 @ r1<- fp[B], the object pointer
- ubfx r2, rINST, #8, #4 @ r2<- A
- VREG_INDEX_TO_ADDR r2, r2 @ r2<- &fp[A]
- ldr r3, [rFP, #OFF_FP_METHOD] @ r3<- referrer
- PREFETCH_INST 2
- bl MterpIPutU64
- cmp r0, #0
- bne MterpPossibleException
- ADVANCE 2 @ advance rPC
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip @ jump to next instruction
+%include "arm/op_iput.S" { "helper":"MterpIPutU64" }
diff --git a/runtime/interpreter/mterp/arm/op_sget.S b/runtime/interpreter/mterp/arm/op_sget.S
index 575a8c0..b382de4 100644
--- a/runtime/interpreter/mterp/arm/op_sget.S
+++ b/runtime/interpreter/mterp/arm/op_sget.S
@@ -1,27 +1,2 @@
%default { "is_object":"0", "helper":"MterpSGetU32" }
- /*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
- */
- /* op vAA, field@BBBB */
-
- .extern $helper
- EXPORT_PC
- FETCH r0, 1 @ r0<- field ref BBBB
- ldr r1, [rFP, #OFF_FP_METHOD]
- mov r2, rSELF
- bl $helper
- ldr r3, [rSELF, #THREAD_EXCEPTION_OFFSET]
- mov r2, rINST, lsr #8 @ r2<- AA
- PREFETCH_INST 2
- cmp r3, #0 @ Fail to resolve?
- bne MterpException @ bail out
-.if $is_object
- SET_VREG_OBJECT r0, r2 @ fp[AA]<- r0
-.else
- SET_VREG r0, r2 @ fp[AA]<- r0
-.endif
- ADVANCE 2
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip
+%include "arm/field.S" { }
diff --git a/runtime/interpreter/mterp/arm/op_sget_wide.S b/runtime/interpreter/mterp/arm/op_sget_wide.S
index 5981ec4..d6905df 100644
--- a/runtime/interpreter/mterp/arm/op_sget_wide.S
+++ b/runtime/interpreter/mterp/arm/op_sget_wide.S
@@ -1,22 +1 @@
- /*
- * SGET_WIDE handler wrapper.
- *
- */
- /* sget-wide vAA, field@BBBB */
-
- .extern MterpSGetU64
- EXPORT_PC
- FETCH r0, 1 @ r0<- field ref BBBB
- ldr r1, [rFP, #OFF_FP_METHOD]
- mov r2, rSELF
- bl MterpSGetU64
- ldr r3, [rSELF, #THREAD_EXCEPTION_OFFSET]
- mov r9, rINST, lsr #8 @ r9<- AA
- VREG_INDEX_TO_ADDR lr, r9 @ r9<- &fp[AA]
- cmp r3, #0 @ Fail to resolve?
- bne MterpException @ bail out
- FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
- CLEAR_SHADOW_PAIR r9, r2, ip @ Zero out the shadow regs
- stmia lr, {r0-r1} @ vAA/vAA+1<- r0/r1
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip @ jump to next instruction
+%include "arm/op_sget.S" {"helper":"MterpSGetU64"}
diff --git a/runtime/interpreter/mterp/arm/op_sput.S b/runtime/interpreter/mterp/arm/op_sput.S
index c4a8978..171f024 100644
--- a/runtime/interpreter/mterp/arm/op_sput.S
+++ b/runtime/interpreter/mterp/arm/op_sput.S
@@ -1,20 +1,2 @@
-%default { "helper":"MterpSPutU32"}
- /*
- * General SPUT handler wrapper.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
- */
- /* op vAA, field@BBBB */
- EXPORT_PC
- FETCH r0, 1 @ r0<- field ref BBBB
- mov r3, rINST, lsr #8 @ r3<- AA
- GET_VREG r1, r3 @ r1<= fp[AA]
- ldr r2, [rFP, #OFF_FP_METHOD]
- mov r3, rSELF
- PREFETCH_INST 2 @ Get next inst, but don't advance rPC
- bl $helper
- cmp r0, #0 @ 0 on success, -1 on failure
- bne MterpException
- ADVANCE 2 @ Past exception point - now advance rPC
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip @ jump to next instruction
+%default { "is_object":"0", "helper":"MterpSPutU32"}
+%include "arm/field.S" { }
diff --git a/runtime/interpreter/mterp/arm/op_sput_object.S b/runtime/interpreter/mterp/arm/op_sput_object.S
index c58918f..8fcd52e 100644
--- a/runtime/interpreter/mterp/arm/op_sput_object.S
+++ b/runtime/interpreter/mterp/arm/op_sput_object.S
@@ -1,11 +1 @@
- EXPORT_PC
- add r0, rFP, #OFF_FP_SHADOWFRAME
- mov r1, rPC
- mov r2, rINST
- mov r3, rSELF
- bl MterpSPutObj
- cmp r0, #0
- beq MterpException
- FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip @ jump to next instruction
+%include "arm/op_sput.S" {"is_object":"1", "helper":"MterpSPutObj"}
diff --git a/runtime/interpreter/mterp/arm/op_sput_wide.S b/runtime/interpreter/mterp/arm/op_sput_wide.S
index 0ed4017..c254f78 100644
--- a/runtime/interpreter/mterp/arm/op_sput_wide.S
+++ b/runtime/interpreter/mterp/arm/op_sput_wide.S
@@ -1,19 +1 @@
- /*
- * SPUT_WIDE handler wrapper.
- *
- */
- /* sput-wide vAA, field@BBBB */
- .extern MterpSPutU64
- EXPORT_PC
- FETCH r0, 1 @ r0<- field ref BBBB
- mov r1, rINST, lsr #8 @ r1<- AA
- VREG_INDEX_TO_ADDR r1, r1
- ldr r2, [rFP, #OFF_FP_METHOD]
- mov r3, rSELF
- PREFETCH_INST 2 @ Get next inst, but don't advance rPC
- bl MterpSPutU64
- cmp r0, #0 @ 0 on success, -1 on failure
- bne MterpException
- ADVANCE 2 @ Past exception point - now advance rPC
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip @ jump to next instruction
+%include "arm/op_sput.S" {"helper":"MterpSPutU64"}
diff --git a/runtime/interpreter/mterp/arm64/field.S b/runtime/interpreter/mterp/arm64/field.S
new file mode 100644
index 0000000..631c8d1
--- /dev/null
+++ b/runtime/interpreter/mterp/arm64/field.S
@@ -0,0 +1,15 @@
+%default { }
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
+ .extern $helper
+ mov x0, xPC // arg0: Instruction* inst
+ mov x1, xINST // arg1: uint16_t inst_data
+ add x2, xFP, #OFF_FP_SHADOWFRAME // arg2: ShadowFrame* sf
+ mov x3, xSELF // arg3: Thread* self
+ PREFETCH_INST 2 // prefetch next opcode
+ bl $helper
+ cbz x0, MterpPossibleException
+ ADVANCE 2
+ GET_INST_OPCODE ip // extract opcode from rINST
+ GOTO_OPCODE ip // jump to next instruction
diff --git a/runtime/interpreter/mterp/arm64/op_iget.S b/runtime/interpreter/mterp/arm64/op_iget.S
index cb453ac..48b9cad 100644
--- a/runtime/interpreter/mterp/arm64/op_iget.S
+++ b/runtime/interpreter/mterp/arm64/op_iget.S
@@ -1,26 +1,2 @@
-%default { "extend":"", "is_object":"0", "helper":"MterpIGetU32"}
- /*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
- */
- EXPORT_PC
- FETCH w0, 1 // w0<- field ref CCCC
- lsr w1, wINST, #12 // w1<- B
- GET_VREG w1, w1 // w1<- fp[B], the object pointer
- ldr x2, [xFP, #OFF_FP_METHOD] // w2<- referrer
- mov x3, xSELF // w3<- self
- bl $helper
- ldr x3, [xSELF, #THREAD_EXCEPTION_OFFSET]
- $extend
- ubfx w2, wINST, #8, #4 // w2<- A
- PREFETCH_INST 2
- cbnz x3, MterpPossibleException // bail out
- .if $is_object
- SET_VREG_OBJECT w0, w2 // fp[A]<- w0
- .else
- SET_VREG w0, w2 // fp[A]<- w0
- .endif
- ADVANCE 2
- GET_INST_OPCODE ip // extract opcode from rINST
- GOTO_OPCODE ip // jump to next instruction
+%default { "is_object":"0", "helper":"MterpIGetU32"}
+%include "arm64/field.S" { }
diff --git a/runtime/interpreter/mterp/arm64/op_iget_boolean.S b/runtime/interpreter/mterp/arm64/op_iget_boolean.S
index 3b17144..9a83b2a 100644
--- a/runtime/interpreter/mterp/arm64/op_iget_boolean.S
+++ b/runtime/interpreter/mterp/arm64/op_iget_boolean.S
@@ -1 +1 @@
-%include "arm64/op_iget.S" { "helper":"MterpIGetU8", "extend":"uxtb w0, w0" }
+%include "arm64/op_iget.S" { "helper":"MterpIGetU8" }
diff --git a/runtime/interpreter/mterp/arm64/op_iget_byte.S b/runtime/interpreter/mterp/arm64/op_iget_byte.S
index d5ef1d3..f73e634 100644
--- a/runtime/interpreter/mterp/arm64/op_iget_byte.S
+++ b/runtime/interpreter/mterp/arm64/op_iget_byte.S
@@ -1 +1 @@
-%include "arm64/op_iget.S" { "helper":"MterpIGetI8", "extend":"sxtb w0, w0" }
+%include "arm64/op_iget.S" { "helper":"MterpIGetI8" }
diff --git a/runtime/interpreter/mterp/arm64/op_iget_char.S b/runtime/interpreter/mterp/arm64/op_iget_char.S
index 68e1435..a5efd9e 100644
--- a/runtime/interpreter/mterp/arm64/op_iget_char.S
+++ b/runtime/interpreter/mterp/arm64/op_iget_char.S
@@ -1 +1 @@
-%include "arm64/op_iget.S" { "helper":"MterpIGetU16", "extend":"uxth w0, w0" }
+%include "arm64/op_iget.S" { "helper":"MterpIGetU16" }
diff --git a/runtime/interpreter/mterp/arm64/op_iget_short.S b/runtime/interpreter/mterp/arm64/op_iget_short.S
index 714f4b9..bb81c17 100644
--- a/runtime/interpreter/mterp/arm64/op_iget_short.S
+++ b/runtime/interpreter/mterp/arm64/op_iget_short.S
@@ -1 +1 @@
-%include "arm64/op_iget.S" { "helper":"MterpIGetI16", "extend":"sxth w0, w0" }
+%include "arm64/op_iget.S" { "helper":"MterpIGetI16" }
diff --git a/runtime/interpreter/mterp/arm64/op_iget_wide.S b/runtime/interpreter/mterp/arm64/op_iget_wide.S
index 4fc735c..70061d6 100644
--- a/runtime/interpreter/mterp/arm64/op_iget_wide.S
+++ b/runtime/interpreter/mterp/arm64/op_iget_wide.S
@@ -1,21 +1 @@
- /*
- * 64-bit instance field get.
- *
- * for: iget-wide
- */
- EXPORT_PC
- FETCH w0, 1 // w0<- field ref CCCC
- lsr w1, wINST, #12 // w1<- B
- GET_VREG w1, w1 // w1<- fp[B], the object pointer
- ldr x2, [xFP, #OFF_FP_METHOD] // w2<- referrer
- mov x3, xSELF // w3<- self
- bl MterpIGetU64
- ldr x3, [xSELF, #THREAD_EXCEPTION_OFFSET]
- ubfx w2, wINST, #8, #4 // w2<- A
- PREFETCH_INST 2
- cmp w3, #0
- cbnz w3, MterpException // bail out
- SET_VREG_WIDE x0, w2
- ADVANCE 2
- GET_INST_OPCODE ip // extract opcode from wINST
- GOTO_OPCODE ip // jump to next instruction
+%include "arm64/op_iget.S" { "helper":"MterpIGetU64" }
diff --git a/runtime/interpreter/mterp/arm64/op_iput.S b/runtime/interpreter/mterp/arm64/op_iput.S
index 5e21d5c..2bc3db9 100644
--- a/runtime/interpreter/mterp/arm64/op_iput.S
+++ b/runtime/interpreter/mterp/arm64/op_iput.S
@@ -1,21 +1,2 @@
%default { "is_object":"0", "helper":"MterpIPutU32" }
- /*
- * General 32-bit instance field put.
- *
- * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
- */
- /* op vA, vB, field//CCCC */
- .extern $helper
- EXPORT_PC
- FETCH w0, 1 // w0<- field ref CCCC
- lsr w1, wINST, #12 // w1<- B
- GET_VREG w1, w1 // w1<- fp[B], the object pointer
- ubfx w2, wINST, #8, #4 // w2<- A
- GET_VREG w2, w2 // w2<- fp[A]
- ldr x3, [xFP, #OFF_FP_METHOD] // w3<- referrer
- PREFETCH_INST 2
- bl $helper
- cbnz w0, MterpPossibleException
- ADVANCE 2 // advance rPC
- GET_INST_OPCODE ip // extract opcode from rINST
- GOTO_OPCODE ip // jump to next instruction
+%include "arm64/field.S" { }
diff --git a/runtime/interpreter/mterp/arm64/op_iput_object.S b/runtime/interpreter/mterp/arm64/op_iput_object.S
index 0c0441a..e9bb93f 100644
--- a/runtime/interpreter/mterp/arm64/op_iput_object.S
+++ b/runtime/interpreter/mterp/arm64/op_iput_object.S
@@ -1,10 +1 @@
- EXPORT_PC
- add x0, xFP, #OFF_FP_SHADOWFRAME
- mov x1, xPC
- mov w2, wINST
- mov x3, xSELF
- bl MterpIPutObj
- cbz w0, MterpException
- FETCH_ADVANCE_INST 2 // advance rPC, load rINST
- GET_INST_OPCODE ip // extract opcode from rINST
- GOTO_OPCODE ip // jump to next instruction
+%include "arm64/op_iput.S" { "is_object":"1", "helper":"MterpIPutObj" }
diff --git a/runtime/interpreter/mterp/arm64/op_iput_wide.S b/runtime/interpreter/mterp/arm64/op_iput_wide.S
index be6aeb0..e1fafad 100644
--- a/runtime/interpreter/mterp/arm64/op_iput_wide.S
+++ b/runtime/interpreter/mterp/arm64/op_iput_wide.S
@@ -1,15 +1 @@
- /* iput-wide vA, vB, field//CCCC */
- .extern MterpIPutU64
- EXPORT_PC
- FETCH w0, 1 // w0<- field ref CCCC
- lsr w1, wINST, #12 // w1<- B
- GET_VREG w1, w1 // w1<- fp[B], the object pointer
- ubfx w2, wINST, #8, #4 // w2<- A
- VREG_INDEX_TO_ADDR x2, x2 // w2<- &fp[A]
- ldr x3, [xFP, #OFF_FP_METHOD] // w3<- referrer
- PREFETCH_INST 2
- bl MterpIPutU64
- cbnz w0, MterpPossibleException
- ADVANCE 2 // advance rPC
- GET_INST_OPCODE ip // extract opcode from wINST
- GOTO_OPCODE ip // jump to next instruction
+%include "arm64/op_iput.S" { "helper":"MterpIPutU64" }
diff --git a/runtime/interpreter/mterp/arm64/op_sget.S b/runtime/interpreter/mterp/arm64/op_sget.S
index 00b07fa..78e95b2 100644
--- a/runtime/interpreter/mterp/arm64/op_sget.S
+++ b/runtime/interpreter/mterp/arm64/op_sget.S
@@ -1,27 +1,2 @@
-%default { "is_object":"0", "helper":"MterpSGetU32", "extend":"" }
- /*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
- */
- /* op vAA, field//BBBB */
-
- .extern $helper
- EXPORT_PC
- FETCH w0, 1 // w0<- field ref BBBB
- ldr x1, [xFP, #OFF_FP_METHOD]
- mov x2, xSELF
- bl $helper
- ldr x3, [xSELF, #THREAD_EXCEPTION_OFFSET]
- lsr w2, wINST, #8 // w2<- AA
- $extend
- PREFETCH_INST 2
- cbnz x3, MterpException // bail out
-.if $is_object
- SET_VREG_OBJECT w0, w2 // fp[AA]<- w0
-.else
- SET_VREG w0, w2 // fp[AA]<- w0
-.endif
- ADVANCE 2
- GET_INST_OPCODE ip // extract opcode from rINST
- GOTO_OPCODE ip
+%default { "is_object":"0", "helper":"MterpSGetU32" }
+%include "arm64/field.S" { }
diff --git a/runtime/interpreter/mterp/arm64/op_sget_boolean.S b/runtime/interpreter/mterp/arm64/op_sget_boolean.S
index 73f3a10..0cf9f09 100644
--- a/runtime/interpreter/mterp/arm64/op_sget_boolean.S
+++ b/runtime/interpreter/mterp/arm64/op_sget_boolean.S
@@ -1 +1 @@
-%include "arm64/op_sget.S" {"helper":"MterpSGetU8", "extend":"uxtb w0, w0"}
+%include "arm64/op_sget.S" {"helper":"MterpSGetU8"}
diff --git a/runtime/interpreter/mterp/arm64/op_sget_byte.S b/runtime/interpreter/mterp/arm64/op_sget_byte.S
index 38c0da6..7c88a81 100644
--- a/runtime/interpreter/mterp/arm64/op_sget_byte.S
+++ b/runtime/interpreter/mterp/arm64/op_sget_byte.S
@@ -1 +1 @@
-%include "arm64/op_sget.S" {"helper":"MterpSGetI8", "extend":"sxtb w0, w0"}
+%include "arm64/op_sget.S" {"helper":"MterpSGetI8"}
diff --git a/runtime/interpreter/mterp/arm64/op_sget_char.S b/runtime/interpreter/mterp/arm64/op_sget_char.S
index c0801bf..883e944 100644
--- a/runtime/interpreter/mterp/arm64/op_sget_char.S
+++ b/runtime/interpreter/mterp/arm64/op_sget_char.S
@@ -1 +1 @@
-%include "arm64/op_sget.S" {"helper":"MterpSGetU16", "extend":"uxth w0, w0"}
+%include "arm64/op_sget.S" {"helper":"MterpSGetU16"}
diff --git a/runtime/interpreter/mterp/arm64/op_sget_short.S b/runtime/interpreter/mterp/arm64/op_sget_short.S
index 81e0434..6cb9184 100644
--- a/runtime/interpreter/mterp/arm64/op_sget_short.S
+++ b/runtime/interpreter/mterp/arm64/op_sget_short.S
@@ -1 +1 @@
-%include "arm64/op_sget.S" {"helper":"MterpSGetI16", "extend":"sxth w0, w0"}
+%include "arm64/op_sget.S" {"helper":"MterpSGetI16"}
diff --git a/runtime/interpreter/mterp/arm64/op_sget_wide.S b/runtime/interpreter/mterp/arm64/op_sget_wide.S
index 546ab94..f5d182e 100644
--- a/runtime/interpreter/mterp/arm64/op_sget_wide.S
+++ b/runtime/interpreter/mterp/arm64/op_sget_wide.S
@@ -1,19 +1 @@
- /*
- * SGET_WIDE handler wrapper.
- *
- */
- /* sget-wide vAA, field//BBBB */
-
- .extern MterpSGetU64
- EXPORT_PC
- FETCH w0, 1 // w0<- field ref BBBB
- ldr x1, [xFP, #OFF_FP_METHOD]
- mov x2, xSELF
- bl MterpSGetU64
- ldr x3, [xSELF, #THREAD_EXCEPTION_OFFSET]
- lsr w4, wINST, #8 // w4<- AA
- cbnz x3, MterpException // bail out
- FETCH_ADVANCE_INST 2 // advance rPC, load wINST
- SET_VREG_WIDE x0, w4
- GET_INST_OPCODE ip // extract opcode from wINST
- GOTO_OPCODE ip // jump to next instruction
+%include "arm64/op_sget.S" {"helper":"MterpSGetU64"}
diff --git a/runtime/interpreter/mterp/arm64/op_sput.S b/runtime/interpreter/mterp/arm64/op_sput.S
index 7a0dc30..d229d0d 100644
--- a/runtime/interpreter/mterp/arm64/op_sput.S
+++ b/runtime/interpreter/mterp/arm64/op_sput.S
@@ -1,19 +1,2 @@
-%default { "helper":"MterpSPutU32"}
- /*
- * General SPUT handler wrapper.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
- */
- /* op vAA, field//BBBB */
- EXPORT_PC
- FETCH w0, 1 // r0<- field ref BBBB
- lsr w3, wINST, #8 // r3<- AA
- GET_VREG w1, w3 // r1<= fp[AA]
- ldr x2, [xFP, #OFF_FP_METHOD]
- mov x3, xSELF
- PREFETCH_INST 2 // Get next inst, but don't advance rPC
- bl $helper
- cbnz w0, MterpException // 0 on success
- ADVANCE 2 // Past exception point - now advance rPC
- GET_INST_OPCODE ip // extract opcode from rINST
- GOTO_OPCODE ip // jump to next instruction
+%default { "is_object":"0", "helper":"MterpSPutU32"}
+%include "arm64/field.S" { }
diff --git a/runtime/interpreter/mterp/arm64/op_sput_object.S b/runtime/interpreter/mterp/arm64/op_sput_object.S
index a649656..536f1b1 100644
--- a/runtime/interpreter/mterp/arm64/op_sput_object.S
+++ b/runtime/interpreter/mterp/arm64/op_sput_object.S
@@ -1,10 +1 @@
- EXPORT_PC
- add x0, xFP, #OFF_FP_SHADOWFRAME
- mov x1, xPC
- mov x2, xINST
- mov x3, xSELF
- bl MterpSPutObj
- cbz w0, MterpException
- FETCH_ADVANCE_INST 2 // advance rPC, load rINST
- GET_INST_OPCODE ip // extract opcode from rINST
- GOTO_OPCODE ip // jump to next instruction
+%include "arm64/op_sput.S" {"is_object":"1", "helper":"MterpSPutObj"}
diff --git a/runtime/interpreter/mterp/arm64/op_sput_wide.S b/runtime/interpreter/mterp/arm64/op_sput_wide.S
index 58b3c42..b4be6b2 100644
--- a/runtime/interpreter/mterp/arm64/op_sput_wide.S
+++ b/runtime/interpreter/mterp/arm64/op_sput_wide.S
@@ -1,18 +1 @@
- /*
- * SPUT_WIDE handler wrapper.
- *
- */
- /* sput-wide vAA, field//BBBB */
- .extern MterpSPutU64
- EXPORT_PC
- FETCH w0, 1 // w0<- field ref BBBB
- lsr w1, wINST, #8 // w1<- AA
- VREG_INDEX_TO_ADDR x1, w1
- ldr x2, [xFP, #OFF_FP_METHOD]
- mov x3, xSELF
- PREFETCH_INST 2 // Get next inst, but don't advance rPC
- bl MterpSPutU64
- cbnz w0, MterpException // 0 on success, -1 on failure
- ADVANCE 2 // Past exception point - now advance rPC
- GET_INST_OPCODE ip // extract opcode from wINST
- GOTO_OPCODE ip // jump to next instruction
+%include "arm64/op_sput.S" {"helper":"MterpSPutU64"}
diff --git a/runtime/interpreter/mterp/mips/field.S b/runtime/interpreter/mterp/mips/field.S
new file mode 100644
index 0000000..1333ed7
--- /dev/null
+++ b/runtime/interpreter/mterp/mips/field.S
@@ -0,0 +1 @@
+TODO
diff --git a/runtime/interpreter/mterp/mips/op_iget.S b/runtime/interpreter/mterp/mips/op_iget.S
index 33717de..e218272 100644
--- a/runtime/interpreter/mterp/mips/op_iget.S
+++ b/runtime/interpreter/mterp/mips/op_iget.S
@@ -1,25 +1,2 @@
%default { "is_object":"0", "helper":"MterpIGetU32"}
- /*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
- */
- /* op vA, vB, field@CCCC */
- EXPORT_PC()
- FETCH(a0, 1) # a0 <- field ref CCCC
- GET_OPB(a1) # a1 <- B
- GET_VREG(a1, a1) # a1 <- fp[B], the object pointer
- lw a2, OFF_FP_METHOD(rFP) # a2 <- referrer
- move a3, rSELF # a3 <- self
- JAL($helper)
- lw a3, THREAD_EXCEPTION_OFFSET(rSELF)
- GET_OPA4(a2) # a2<- A+
- PREFETCH_INST(2) # load rINST
- bnez a3, MterpPossibleException # bail out
- ADVANCE(2) # advance rPC
- GET_INST_OPCODE(t0) # extract opcode from rINST
- .if $is_object
- SET_VREG_OBJECT_GOTO(v0, a2, t0) # fp[A] <- v0
- .else
- SET_VREG_GOTO(v0, a2, t0) # fp[A] <- v0
- .endif
+%include "mips/field.S" { }
diff --git a/runtime/interpreter/mterp/mips/op_iget_wide.S b/runtime/interpreter/mterp/mips/op_iget_wide.S
index 858a889..885372a 100644
--- a/runtime/interpreter/mterp/mips/op_iget_wide.S
+++ b/runtime/interpreter/mterp/mips/op_iget_wide.S
@@ -1,20 +1 @@
- /*
- * 64-bit instance field get.
- *
- * for: iget-wide
- */
- /* op vA, vB, field@CCCC */
- EXPORT_PC()
- FETCH(a0, 1) # a0 <- field byte offset
- GET_OPB(a1) # a1 <- B
- GET_VREG(a1, a1) # a1 <- fp[B], the object pointer
- lw a2, OFF_FP_METHOD(rFP) # a2 <- referrer
- move a3, rSELF # a3 <- self
- JAL(MterpIGetU64)
- lw a3, THREAD_EXCEPTION_OFFSET(rSELF)
- GET_OPA4(a2) # a2<- A+
- PREFETCH_INST(2) # load rINST
- bnez a3, MterpException # bail out
- ADVANCE(2) # advance rPC
- GET_INST_OPCODE(t0) # extract opcode from rINST
- SET_VREG64_GOTO(v0, v1, a2, t0) # fp[A] <- v0/v1
+%include "mips/op_iget.S" { "helper":"MterpIGetU64" }
diff --git a/runtime/interpreter/mterp/mips/op_iput.S b/runtime/interpreter/mterp/mips/op_iput.S
index 4dd4075..efbdfba 100644
--- a/runtime/interpreter/mterp/mips/op_iput.S
+++ b/runtime/interpreter/mterp/mips/op_iput.S
@@ -1,21 +1,2 @@
-%default { "helper":"MterpIPutU32" }
- /*
- * General 32-bit instance field put.
- *
- * for: iput, iput-boolean, iput-byte, iput-char, iput-short
- */
- /* op vA, vB, field@CCCC */
- .extern $helper
- EXPORT_PC()
- FETCH(a0, 1) # a0 <- field ref CCCC
- GET_OPB(a1) # a1 <- B
- GET_VREG(a1, a1) # a1 <- fp[B], the object pointer
- GET_OPA4(a2) # a2 <- A+
- GET_VREG(a2, a2) # a2 <- fp[A]
- lw a3, OFF_FP_METHOD(rFP) # a3 <- referrer
- PREFETCH_INST(2) # load rINST
- JAL($helper)
- bnez v0, MterpPossibleException # bail out
- ADVANCE(2) # advance rPC
- GET_INST_OPCODE(t0) # extract opcode from rINST
- GOTO_OPCODE(t0) # jump to next instruction
+%default { "is_object":"0", "helper":"MterpIPutU32" }
+%include "mips/field.S" { }
diff --git a/runtime/interpreter/mterp/mips/op_iput_object.S b/runtime/interpreter/mterp/mips/op_iput_object.S
index c96a4d4..6f7e7b7 100644
--- a/runtime/interpreter/mterp/mips/op_iput_object.S
+++ b/runtime/interpreter/mterp/mips/op_iput_object.S
@@ -1,16 +1 @@
- /*
- * 32-bit instance field put.
- *
- * for: iput-object, iput-object-volatile
- */
- /* op vA, vB, field@CCCC */
- EXPORT_PC()
- addu a0, rFP, OFF_FP_SHADOWFRAME
- move a1, rPC
- move a2, rINST
- move a3, rSELF
- JAL(MterpIPutObj)
- beqz v0, MterpException
- FETCH_ADVANCE_INST(2) # advance rPC, load rINST
- GET_INST_OPCODE(t0) # extract opcode from rINST
- GOTO_OPCODE(t0) # jump to next instruction
+%include "mips/op_iput.S" { "is_object":"1", "helper":"MterpIPutObj" }
diff --git a/runtime/interpreter/mterp/mips/op_iput_wide.S b/runtime/interpreter/mterp/mips/op_iput_wide.S
index dccb6b7..fc862e4 100644
--- a/runtime/interpreter/mterp/mips/op_iput_wide.S
+++ b/runtime/interpreter/mterp/mips/op_iput_wide.S
@@ -1,15 +1 @@
- /* iput-wide vA, vB, field@CCCC */
- .extern MterpIPutU64
- EXPORT_PC()
- FETCH(a0, 1) # a0 <- field ref CCCC
- GET_OPB(a1) # a1 <- B
- GET_VREG(a1, a1) # a1 <- fp[B], the object pointer
- GET_OPA4(a2) # a2 <- A+
- EAS2(a2, rFP, a2) # a2 <- &fp[A]
- lw a3, OFF_FP_METHOD(rFP) # a3 <- referrer
- PREFETCH_INST(2) # load rINST
- JAL(MterpIPutU64)
- bnez v0, MterpPossibleException # bail out
- ADVANCE(2) # advance rPC
- GET_INST_OPCODE(t0) # extract opcode from rINST
- GOTO_OPCODE(t0) # jump to next instruction
+%include "mips/op_iput.S" { "helper":"MterpIPutU64" }
diff --git a/runtime/interpreter/mterp/mips/op_sget.S b/runtime/interpreter/mterp/mips/op_sget.S
index 8750a17..92d6673 100644
--- a/runtime/interpreter/mterp/mips/op_sget.S
+++ b/runtime/interpreter/mterp/mips/op_sget.S
@@ -1,24 +1,2 @@
%default { "is_object":"0", "helper":"MterpSGetU32" }
- /*
- * General SGET handler.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
- */
- /* op vAA, field@BBBB */
- .extern $helper
- EXPORT_PC()
- FETCH(a0, 1) # a0 <- field ref BBBB
- lw a1, OFF_FP_METHOD(rFP) # a1 <- method
- move a2, rSELF # a2 <- self
- JAL($helper)
- lw a3, THREAD_EXCEPTION_OFFSET(rSELF)
- GET_OPA(a2) # a2 <- AA
- PREFETCH_INST(2)
- bnez a3, MterpException # bail out
- ADVANCE(2)
- GET_INST_OPCODE(t0) # extract opcode from rINST
-.if $is_object
- SET_VREG_OBJECT_GOTO(v0, a2, t0) # fp[AA] <- v0
-.else
- SET_VREG_GOTO(v0, a2, t0) # fp[AA] <- v0
-.endif
+%include "mips/field.S" { }
diff --git a/runtime/interpreter/mterp/mips/op_sget_wide.S b/runtime/interpreter/mterp/mips/op_sget_wide.S
index 76f78cb..be4ae02 100644
--- a/runtime/interpreter/mterp/mips/op_sget_wide.S
+++ b/runtime/interpreter/mterp/mips/op_sget_wide.S
@@ -1,16 +1 @@
- /*
- * 64-bit SGET handler.
- */
- /* sget-wide vAA, field@BBBB */
- .extern MterpSGetU64
- EXPORT_PC()
- FETCH(a0, 1) # a0 <- field ref BBBB
- lw a1, OFF_FP_METHOD(rFP) # a1 <- method
- move a2, rSELF # a2 <- self
- JAL(MterpSGetU64)
- lw a3, THREAD_EXCEPTION_OFFSET(rSELF)
- bnez a3, MterpException
- GET_OPA(a1) # a1 <- AA
- FETCH_ADVANCE_INST(2) # advance rPC, load rINST
- GET_INST_OPCODE(t0) # extract opcode from rINST
- SET_VREG64_GOTO(v0, v1, a1, t0) # vAA/vAA+1 <- v0/v1
+%include "mips/op_sget.S" {"helper":"MterpSGetU64"}
diff --git a/runtime/interpreter/mterp/mips/op_sput.S b/runtime/interpreter/mterp/mips/op_sput.S
index 547de39..c858679 100644
--- a/runtime/interpreter/mterp/mips/op_sput.S
+++ b/runtime/interpreter/mterp/mips/op_sput.S
@@ -1,19 +1,2 @@
-%default { "helper":"MterpSPutU32"}
- /*
- * General SPUT handler.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
- */
- /* op vAA, field@BBBB */
- EXPORT_PC()
- FETCH(a0, 1) # a0 <- field ref BBBB
- GET_OPA(a3) # a3 <- AA
- GET_VREG(a1, a3) # a1 <- fp[AA], the object pointer
- lw a2, OFF_FP_METHOD(rFP) # a2 <- method
- move a3, rSELF # a3 <- self
- PREFETCH_INST(2) # load rINST
- JAL($helper)
- bnez v0, MterpException # bail out
- ADVANCE(2) # advance rPC
- GET_INST_OPCODE(t0) # extract opcode from rINST
- GOTO_OPCODE(t0) # jump to next instruction
+%default { "is_object":"0", "helper":"MterpSPutU32"}
+%include "mips/field.S" { }
diff --git a/runtime/interpreter/mterp/mips/op_sput_object.S b/runtime/interpreter/mterp/mips/op_sput_object.S
index 55c88a6..683b767 100644
--- a/runtime/interpreter/mterp/mips/op_sput_object.S
+++ b/runtime/interpreter/mterp/mips/op_sput_object.S
@@ -1,16 +1 @@
- /*
- * General 32-bit SPUT handler.
- *
- * for: sput-object,
- */
- /* op vAA, field@BBBB */
- EXPORT_PC()
- addu a0, rFP, OFF_FP_SHADOWFRAME
- move a1, rPC
- move a2, rINST
- move a3, rSELF
- JAL(MterpSPutObj)
- beqz v0, MterpException
- FETCH_ADVANCE_INST(2) # advance rPC, load rINST
- GET_INST_OPCODE(t0) # extract opcode from rINST
- GOTO_OPCODE(t0) # jump to next instruction
+%include "mips/op_sput.S" {"is_object":"1", "helper":"MterpSPutObj"}
diff --git a/runtime/interpreter/mterp/mips/op_sput_wide.S b/runtime/interpreter/mterp/mips/op_sput_wide.S
index cfaaaee..1d2ed19 100644
--- a/runtime/interpreter/mterp/mips/op_sput_wide.S
+++ b/runtime/interpreter/mterp/mips/op_sput_wide.S
@@ -1,17 +1 @@
- /*
- * 64-bit SPUT handler.
- */
- /* sput-wide vAA, field@BBBB */
- .extern MterpSPutU64
- EXPORT_PC()
- FETCH(a0, 1) # a0 <- field ref CCCC
- GET_OPA(a1) # a1 <- AA
- EAS2(a1, rFP, a1) # a1 <- &fp[AA]
- lw a2, OFF_FP_METHOD(rFP) # a2 <- method
- move a3, rSELF # a3 <- self
- PREFETCH_INST(2) # load rINST
- JAL(MterpSPutU64)
- bnez v0, MterpException # bail out
- ADVANCE(2) # advance rPC
- GET_INST_OPCODE(t0) # extract opcode from rINST
- GOTO_OPCODE(t0) # jump to next instruction
+%include "mips/op_sput.S" {"helper":"MterpSPutU64"}
diff --git a/runtime/interpreter/mterp/mips64/field.S b/runtime/interpreter/mterp/mips64/field.S
new file mode 100644
index 0000000..1333ed7
--- /dev/null
+++ b/runtime/interpreter/mterp/mips64/field.S
@@ -0,0 +1 @@
+TODO
diff --git a/runtime/interpreter/mterp/mips64/op_iget.S b/runtime/interpreter/mterp/mips64/op_iget.S
index a8ce94c..e91f099 100644
--- a/runtime/interpreter/mterp/mips64/op_iget.S
+++ b/runtime/interpreter/mterp/mips64/op_iget.S
@@ -1,26 +1,2 @@
%default { "is_object":"0", "helper":"MterpIGetU32"}
- /*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
- */
- .extern $helper
- EXPORT_PC
- lhu a0, 2(rPC) # a0 <- field ref CCCC
- srl a1, rINST, 12 # a1 <- B
- GET_VREG_U a1, a1 # a1 <- fp[B], the object pointer
- ld a2, OFF_FP_METHOD(rFP) # a2 <- referrer
- move a3, rSELF # a3 <- self
- jal $helper
- ld a3, THREAD_EXCEPTION_OFFSET(rSELF)
- ext a2, rINST, 8, 4 # a2 <- A
- PREFETCH_INST 2
- bnez a3, MterpPossibleException # bail out
- .if $is_object
- SET_VREG_OBJECT v0, a2 # fp[A] <- v0
- .else
- SET_VREG v0, a2 # fp[A] <- v0
- .endif
- ADVANCE 2
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
+%include "mips64/field.S" { }
diff --git a/runtime/interpreter/mterp/mips64/op_iget_wide.S b/runtime/interpreter/mterp/mips64/op_iget_wide.S
index 08bf544..40f3645 100644
--- a/runtime/interpreter/mterp/mips64/op_iget_wide.S
+++ b/runtime/interpreter/mterp/mips64/op_iget_wide.S
@@ -1,21 +1 @@
- /*
- * 64-bit instance field get.
- *
- * for: iget-wide
- */
- .extern MterpIGetU64
- EXPORT_PC
- lhu a0, 2(rPC) # a0 <- field ref CCCC
- srl a1, rINST, 12 # a1 <- B
- GET_VREG_U a1, a1 # a1 <- fp[B], the object pointer
- ld a2, OFF_FP_METHOD(rFP) # a2 <- referrer
- move a3, rSELF # a3 <- self
- jal MterpIGetU64
- ld a3, THREAD_EXCEPTION_OFFSET(rSELF)
- ext a2, rINST, 8, 4 # a2 <- A
- PREFETCH_INST 2
- bnez a3, MterpPossibleException # bail out
- SET_VREG_WIDE v0, a2 # fp[A] <- v0
- ADVANCE 2
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
+%include "mips64/op_iget.S" { "helper":"MterpIGetU64" }
diff --git a/runtime/interpreter/mterp/mips64/op_iput.S b/runtime/interpreter/mterp/mips64/op_iput.S
index 9a789e6..81ab911 100644
--- a/runtime/interpreter/mterp/mips64/op_iput.S
+++ b/runtime/interpreter/mterp/mips64/op_iput.S
@@ -1,21 +1,2 @@
-%default { "helper":"MterpIPutU32" }
- /*
- * General 32-bit instance field put.
- *
- * for: iput, iput-boolean, iput-byte, iput-char, iput-short
- */
- /* op vA, vB, field//CCCC */
- .extern $helper
- EXPORT_PC
- lhu a0, 2(rPC) # a0 <- field ref CCCC
- srl a1, rINST, 12 # a1 <- B
- GET_VREG_U a1, a1 # a1 <- fp[B], the object pointer
- ext a2, rINST, 8, 4 # a2 <- A
- GET_VREG a2, a2 # a2 <- fp[A]
- ld a3, OFF_FP_METHOD(rFP) # a3 <- referrer
- PREFETCH_INST 2
- jal $helper
- bnez v0, MterpPossibleException # bail out
- ADVANCE 2
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
+%default { "is_object":"0", "helper":"MterpIPutU32" }
+%include "mips64/field.S" { }
diff --git a/runtime/interpreter/mterp/mips64/op_iput_object.S b/runtime/interpreter/mterp/mips64/op_iput_object.S
index dd1938e..d3316dd 100644
--- a/runtime/interpreter/mterp/mips64/op_iput_object.S
+++ b/runtime/interpreter/mterp/mips64/op_iput_object.S
@@ -1,11 +1 @@
- .extern MterpIPutObj
- EXPORT_PC
- daddu a0, rFP, OFF_FP_SHADOWFRAME
- move a1, rPC
- move a2, rINST
- move a3, rSELF
- jal MterpIPutObj
- beqzc v0, MterpException
- FETCH_ADVANCE_INST 2 # advance rPC, load rINST
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
+%include "mips64/op_iput.S" { "is_object":"1", "helper":"MterpIPutObj" }
diff --git a/runtime/interpreter/mterp/mips64/op_iput_wide.S b/runtime/interpreter/mterp/mips64/op_iput_wide.S
index 6272690..05194b3 100644
--- a/runtime/interpreter/mterp/mips64/op_iput_wide.S
+++ b/runtime/interpreter/mterp/mips64/op_iput_wide.S
@@ -1,15 +1 @@
- /* iput-wide vA, vB, field//CCCC */
- .extern MterpIPutU64
- EXPORT_PC
- lhu a0, 2(rPC) # a0 <- field ref CCCC
- srl a1, rINST, 12 # a1 <- B
- GET_VREG_U a1, a1 # a1 <- fp[B], the object pointer
- ext a2, rINST, 8, 4 # a2 <- A
- dlsa a2, a2, rFP, 2 # a2 <- &fp[A]
- ld a3, OFF_FP_METHOD(rFP) # a3 <- referrer
- PREFETCH_INST 2
- jal MterpIPutU64
- bnez v0, MterpPossibleException # bail out
- ADVANCE 2
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
+%include "mips64/op_iput.S" { "helper":"MterpIPutU64" }
diff --git a/runtime/interpreter/mterp/mips64/op_sget.S b/runtime/interpreter/mterp/mips64/op_sget.S
index b7b0382..200da35 100644
--- a/runtime/interpreter/mterp/mips64/op_sget.S
+++ b/runtime/interpreter/mterp/mips64/op_sget.S
@@ -1,26 +1,2 @@
-%default { "is_object":"0", "helper":"MterpSGetU32", "extend":"" }
- /*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
- */
- /* op vAA, field//BBBB */
- .extern $helper
- EXPORT_PC
- lhu a0, 2(rPC) # a0 <- field ref BBBB
- ld a1, OFF_FP_METHOD(rFP)
- move a2, rSELF
- jal $helper
- ld a3, THREAD_EXCEPTION_OFFSET(rSELF)
- srl a2, rINST, 8 # a2 <- AA
- $extend
- PREFETCH_INST 2
- bnez a3, MterpException # bail out
- .if $is_object
- SET_VREG_OBJECT v0, a2 # fp[AA] <- v0
- .else
- SET_VREG v0, a2 # fp[AA] <- v0
- .endif
- ADVANCE 2
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0
+%default { "is_object":"0", "helper":"MterpSGetU32" }
+%include "mips64/field.S" { }
diff --git a/runtime/interpreter/mterp/mips64/op_sget_boolean.S b/runtime/interpreter/mterp/mips64/op_sget_boolean.S
index fe2deb1..8abb396 100644
--- a/runtime/interpreter/mterp/mips64/op_sget_boolean.S
+++ b/runtime/interpreter/mterp/mips64/op_sget_boolean.S
@@ -1 +1 @@
-%include "mips64/op_sget.S" {"helper":"MterpSGetU8", "extend":"and v0, v0, 0xff"}
+%include "mips64/op_sget.S" {"helper":"MterpSGetU8"}
diff --git a/runtime/interpreter/mterp/mips64/op_sget_byte.S b/runtime/interpreter/mterp/mips64/op_sget_byte.S
index a7e2bef..68623f6 100644
--- a/runtime/interpreter/mterp/mips64/op_sget_byte.S
+++ b/runtime/interpreter/mterp/mips64/op_sget_byte.S
@@ -1 +1 @@
-%include "mips64/op_sget.S" {"helper":"MterpSGetI8", "extend":"seb v0, v0"}
+%include "mips64/op_sget.S" {"helper":"MterpSGetI8"}
diff --git a/runtime/interpreter/mterp/mips64/op_sget_char.S b/runtime/interpreter/mterp/mips64/op_sget_char.S
index ed86f32..3c7b962 100644
--- a/runtime/interpreter/mterp/mips64/op_sget_char.S
+++ b/runtime/interpreter/mterp/mips64/op_sget_char.S
@@ -1 +1 @@
-%include "mips64/op_sget.S" {"helper":"MterpSGetU16", "extend":"and v0, v0, 0xffff"}
+%include "mips64/op_sget.S" {"helper":"MterpSGetU16"}
diff --git a/runtime/interpreter/mterp/mips64/op_sget_short.S b/runtime/interpreter/mterp/mips64/op_sget_short.S
index f708a20..9a8579b 100644
--- a/runtime/interpreter/mterp/mips64/op_sget_short.S
+++ b/runtime/interpreter/mterp/mips64/op_sget_short.S
@@ -1 +1 @@
-%include "mips64/op_sget.S" {"helper":"MterpSGetI16", "extend":"seh v0, v0"}
+%include "mips64/op_sget.S" {"helper":"MterpSGetI16"}
diff --git a/runtime/interpreter/mterp/mips64/op_sget_wide.S b/runtime/interpreter/mterp/mips64/op_sget_wide.S
index 7c31252..14f232c 100644
--- a/runtime/interpreter/mterp/mips64/op_sget_wide.S
+++ b/runtime/interpreter/mterp/mips64/op_sget_wide.S
@@ -1,18 +1 @@
- /*
- * SGET_WIDE handler wrapper.
- *
- */
- /* sget-wide vAA, field//BBBB */
- .extern MterpSGetU64
- EXPORT_PC
- lhu a0, 2(rPC) # a0 <- field ref BBBB
- ld a1, OFF_FP_METHOD(rFP)
- move a2, rSELF
- jal MterpSGetU64
- ld a3, THREAD_EXCEPTION_OFFSET(rSELF)
- srl a4, rINST, 8 # a4 <- AA
- bnez a3, MterpException # bail out
- FETCH_ADVANCE_INST 2 # advance rPC, load rINST
- SET_VREG_WIDE v0, a4
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
+%include "mips64/op_sget.S" {"helper":"MterpSGetU64"}
diff --git a/runtime/interpreter/mterp/mips64/op_sput.S b/runtime/interpreter/mterp/mips64/op_sput.S
index 28b8c3e..0bd6837 100644
--- a/runtime/interpreter/mterp/mips64/op_sput.S
+++ b/runtime/interpreter/mterp/mips64/op_sput.S
@@ -1,20 +1,2 @@
-%default { "helper":"MterpSPutU32" }
- /*
- * General SPUT handler wrapper.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
- */
- /* op vAA, field//BBBB */
- .extern $helper
- EXPORT_PC
- lhu a0, 2(rPC) # a0 <- field ref BBBB
- srl a3, rINST, 8 # a3 <- AA
- GET_VREG a1, a3 # a1 <- fp[AA]
- ld a2, OFF_FP_METHOD(rFP)
- move a3, rSELF
- PREFETCH_INST 2 # Get next inst, but don't advance rPC
- jal $helper
- bnezc v0, MterpException # 0 on success
- ADVANCE 2 # Past exception point - now advance rPC
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
+%default { "is_object":"0", "helper":"MterpSPutU32"}
+%include "mips64/field.S" { }
diff --git a/runtime/interpreter/mterp/mips64/op_sput_object.S b/runtime/interpreter/mterp/mips64/op_sput_object.S
index ff43967..09bd0fb 100644
--- a/runtime/interpreter/mterp/mips64/op_sput_object.S
+++ b/runtime/interpreter/mterp/mips64/op_sput_object.S
@@ -1,11 +1 @@
- .extern MterpSPutObj
- EXPORT_PC
- daddu a0, rFP, OFF_FP_SHADOWFRAME
- move a1, rPC
- move a2, rINST
- move a3, rSELF
- jal MterpSPutObj
- beqzc v0, MterpException
- FETCH_ADVANCE_INST 2 # advance rPC, load rINST
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
+%include "mips64/op_sput.S" {"is_object":"1", "helper":"MterpSPutObj"}
diff --git a/runtime/interpreter/mterp/mips64/op_sput_wide.S b/runtime/interpreter/mterp/mips64/op_sput_wide.S
index bfb6983..070d17f 100644
--- a/runtime/interpreter/mterp/mips64/op_sput_wide.S
+++ b/runtime/interpreter/mterp/mips64/op_sput_wide.S
@@ -1,18 +1 @@
- /*
- * SPUT_WIDE handler wrapper.
- *
- */
- /* sput-wide vAA, field//BBBB */
- .extern MterpSPutU64
- EXPORT_PC
- lhu a0, 2(rPC) # a0 <- field ref BBBB
- srl a1, rINST, 8 # a2 <- AA
- dlsa a1, a1, rFP, 2
- ld a2, OFF_FP_METHOD(rFP)
- move a3, rSELF
- PREFETCH_INST 2 # Get next inst, but don't advance rPC
- jal MterpSPutU64
- bnezc v0, MterpException # 0 on success, -1 on failure
- ADVANCE 2 # Past exception point - now advance rPC
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
+%include "mips64/op_sput.S" {"helper":"MterpSPutU64"}
diff --git a/runtime/interpreter/mterp/mterp.cc b/runtime/interpreter/mterp/mterp.cc
index 7b37c9a..65c1aa8 100644
--- a/runtime/interpreter/mterp/mterp.cc
+++ b/runtime/interpreter/mterp/mterp.cc
@@ -490,24 +490,6 @@
return true;
}
-extern "C" size_t MterpSPutObj(ShadowFrame* shadow_frame, uint16_t* dex_pc_ptr,
- uint32_t inst_data, Thread* self)
- REQUIRES_SHARED(Locks::mutator_lock_) {
- const Instruction* inst = Instruction::At(dex_pc_ptr);
- return DoFieldPut<StaticObjectWrite, Primitive::kPrimNot, false, false>
- (self, *shadow_frame, inst, inst_data);
-}
-
-extern "C" size_t MterpIPutObj(ShadowFrame* shadow_frame,
- uint16_t* dex_pc_ptr,
- uint32_t inst_data,
- Thread* self)
- REQUIRES_SHARED(Locks::mutator_lock_) {
- const Instruction* inst = Instruction::At(dex_pc_ptr);
- return DoFieldPut<InstanceObjectWrite, Primitive::kPrimNot, false, false>
- (self, *shadow_frame, inst, inst_data);
-}
-
extern "C" size_t MterpIputObjectQuick(ShadowFrame* shadow_frame,
uint16_t* dex_pc_ptr,
uint32_t inst_data)
@@ -681,352 +663,159 @@
return MterpShouldSwitchInterpreters();
}
-template<typename PrimType, typename RetType, typename Getter, FindFieldType kType>
-NO_INLINE RetType artGetInstanceFromMterp(uint32_t field_idx,
- mirror::Object* obj,
- ArtMethod* referrer,
- Thread* self)
- REQUIRES_SHARED(Locks::mutator_lock_) {
- StackHandleScope<1> hs(self);
- HandleWrapper<mirror::Object> h(hs.NewHandleWrapper(&obj)); // GC might move the object.
- ArtField* field = FindFieldFromCode<kType, /* access_checks */ false>(
- field_idx, referrer, self, sizeof(PrimType));
- if (UNLIKELY(field == nullptr)) {
- return 0; // Will throw exception by checking with Thread::Current.
+// Execute single field access instruction (get/put, static/instance).
+// The template arguments reduce this to fairly small amount of code.
+// It requires the target object and field to be already resolved.
+template<typename PrimType, FindFieldType kAccessType>
+ALWAYS_INLINE void MterpFieldAccess(Instruction* inst,
+ uint16_t inst_data,
+ ShadowFrame* shadow_frame,
+ ObjPtr<mirror::Object> obj,
+ MemberOffset offset,
+ bool is_volatile)
+ REQUIRES_SHARED(Locks::mutator_lock_) {
+ static_assert(std::is_integral<PrimType>::value, "Unexpected primitive type");
+ constexpr bool kIsStatic = (kAccessType & FindFieldFlags::StaticBit) != 0;
+ constexpr bool kIsPrimitive = (kAccessType & FindFieldFlags::PrimitiveBit) != 0;
+ constexpr bool kIsRead = (kAccessType & FindFieldFlags::ReadBit) != 0;
+
+ uint16_t vRegA = kIsStatic ? inst->VRegA_21c(inst_data) : inst->VRegA_22c(inst_data);
+ if (kIsPrimitive) {
+ if (kIsRead) {
+ PrimType value = UNLIKELY(is_volatile)
+ ? obj->GetFieldPrimitive<PrimType, /*kIsVolatile*/ true>(offset)
+ : obj->GetFieldPrimitive<PrimType, /*kIsVolatile*/ false>(offset);
+ if (sizeof(PrimType) == sizeof(uint64_t)) {
+ shadow_frame->SetVRegLong(vRegA, value); // Set two consecutive registers.
+ } else {
+ shadow_frame->SetVReg(vRegA, static_cast<int32_t>(value)); // Sign/zero extend.
+ }
+ } else { // Write.
+ uint64_t value = (sizeof(PrimType) == sizeof(uint64_t))
+ ? shadow_frame->GetVRegLong(vRegA)
+ : shadow_frame->GetVReg(vRegA);
+ if (UNLIKELY(is_volatile)) {
+ obj->SetFieldPrimitive<PrimType, /*kIsVolatile*/ true>(offset, value);
+ } else {
+ obj->SetFieldPrimitive<PrimType, /*kIsVolatile*/ false>(offset, value);
+ }
+ }
+ } else { // Object.
+ if (kIsRead) {
+ ObjPtr<mirror::Object> value = UNLIKELY(is_volatile)
+ ? obj->GetFieldObjectVolatile<mirror::Object>(offset)
+ : obj->GetFieldObject<mirror::Object>(offset);
+ shadow_frame->SetVRegReference(vRegA, value);
+ } else { // Write.
+ ObjPtr<mirror::Object> value = shadow_frame->GetVRegReference(vRegA);
+ if (UNLIKELY(is_volatile)) {
+ obj->SetFieldObjectVolatile</*kTransactionActive*/ false>(offset, value);
+ } else {
+ obj->SetFieldObject</*kTransactionActive*/ false>(offset, value);
+ }
+ }
}
- if (UNLIKELY(h == nullptr)) {
- ThrowNullPointerExceptionForFieldAccess(field, /*is_read*/ true);
- return 0; // Will throw exception by checking with Thread::Current.
- }
- return Getter::Get(obj, field);
}
-template<typename PrimType, typename RetType, typename Getter>
-ALWAYS_INLINE RetType artGetInstanceFromMterpFast(uint32_t field_idx,
- mirror::Object* obj,
- ArtMethod* referrer,
- Thread* self)
- REQUIRES_SHARED(Locks::mutator_lock_) {
- constexpr bool kIsObject = std::is_same<RetType, mirror::Object*>::value;
- constexpr FindFieldType kType = kIsObject ? InstanceObjectRead : InstancePrimitiveRead;
+template<typename PrimType, FindFieldType kAccessType>
+NO_INLINE bool MterpFieldAccessSlow(Instruction* inst,
+ uint16_t inst_data,
+ ShadowFrame* shadow_frame,
+ Thread* self)
+ REQUIRES_SHARED(Locks::mutator_lock_) {
+ constexpr bool kIsStatic = (kAccessType & FindFieldFlags::StaticBit) != 0;
+ constexpr bool kIsRead = (kAccessType & FindFieldFlags::ReadBit) != 0;
+
+ // Update the dex pc in shadow frame, just in case anything throws.
+ shadow_frame->SetDexPCPtr(reinterpret_cast<uint16_t*>(inst));
+ ArtMethod* referrer = shadow_frame->GetMethod();
+ uint32_t field_idx = kIsStatic ? inst->VRegB_21c() : inst->VRegC_22c();
+ ArtField* field = FindFieldFromCode<kAccessType, /* access_checks */ false>(
+ field_idx, referrer, self, sizeof(PrimType));
+ if (UNLIKELY(field == nullptr)) {
+ DCHECK(self->IsExceptionPending());
+ return false;
+ }
+ ObjPtr<mirror::Object> obj = kIsStatic
+ ? field->GetDeclaringClass().Ptr()
+ : shadow_frame->GetVRegReference(inst->VRegB_22c(inst_data));
+ if (UNLIKELY(obj == nullptr)) {
+ ThrowNullPointerExceptionForFieldAccess(field, kIsRead);
+ return false;
+ }
+ MterpFieldAccess<PrimType, kAccessType>(
+ inst, inst_data, shadow_frame, obj, field->GetOffset(), field->IsVolatile());
+ return true;
+}
+
+template<typename PrimType, FindFieldType kAccessType>
+ALWAYS_INLINE bool MterpFieldAccessFast(Instruction* inst,
+ uint16_t inst_data,
+ ShadowFrame* shadow_frame,
+ Thread* self)
+ REQUIRES_SHARED(Locks::mutator_lock_) {
+ constexpr bool kIsStatic = (kAccessType & FindFieldFlags::StaticBit) != 0;
// This effectively inlines the fast path from ArtMethod::GetDexCache.
// It avoids non-inlined call which in turn allows elimination of the prologue and epilogue.
+ ArtMethod* referrer = shadow_frame->GetMethod();
if (LIKELY(!referrer->IsObsolete())) {
// Avoid read barriers, since we need only the pointer to the native (non-movable)
// DexCache field array which we can get even through from-space objects.
ObjPtr<mirror::Class> klass = referrer->GetDeclaringClass<kWithoutReadBarrier>();
mirror::DexCache* dex_cache = klass->GetDexCache<kDefaultVerifyFlags, kWithoutReadBarrier>();
+
// Try to find the desired field in DexCache.
+ uint32_t field_idx = kIsStatic ? inst->VRegB_21c() : inst->VRegC_22c();
ArtField* field = dex_cache->GetResolvedField(field_idx, kRuntimePointerSize);
- if (LIKELY(field != nullptr & obj != nullptr)) {
- if (kIsDebugBuild) {
- // Compare the fast path and slow path.
- StackHandleScope<1> hs(self);
- HandleWrapper<mirror::Object> h(hs.NewHandleWrapper(&obj)); // GC might move the object.
- DCHECK_EQ(field, (FindFieldFromCode<kType, /* access_checks */ false>(
+ if (LIKELY(field != nullptr)) {
+ bool initialized = !kIsStatic || field->GetDeclaringClass()->IsInitialized();
+ if (LIKELY(initialized)) {
+ DCHECK_EQ(field, (FindFieldFromCode<kAccessType, /* access_checks */ false>(
field_idx, referrer, self, sizeof(PrimType))));
+ ObjPtr<mirror::Object> obj = kIsStatic
+ ? field->GetDeclaringClass().Ptr()
+ : shadow_frame->GetVRegReference(inst->VRegB_22c(inst_data));
+ if (LIKELY(kIsStatic || obj != nullptr)) {
+ MterpFieldAccess<PrimType, kAccessType>(
+ inst, inst_data, shadow_frame, obj, field->GetOffset(), field->IsVolatile());
+ return true;
+ }
}
- return Getter::Get(obj, field);
}
}
+
// Slow path. Last and with identical arguments so that it becomes single instruction tail call.
- return artGetInstanceFromMterp<PrimType, RetType, Getter, kType>(field_idx, obj, referrer, self);
+ return MterpFieldAccessSlow<PrimType, kAccessType>(inst, inst_data, shadow_frame, self);
}
-#define ART_GET_FIELD_FROM_MTERP(Suffix, Kind, PrimType, RetType, Ptr) \
-extern "C" RetType MterpIGet ## Suffix(uint32_t field_idx, \
- mirror::Object* obj, \
- ArtMethod* referrer, \
- Thread* self) \
- REQUIRES_SHARED(Locks::mutator_lock_) { \
- struct Getter { /* Specialize the field load depending on the field type */ \
- static RetType Get(mirror::Object* o, ArtField* f) REQUIRES_SHARED(Locks::mutator_lock_) { \
- return f->Get##Kind(o)Ptr; \
- } \
- }; \
- return artGetInstanceFromMterpFast<PrimType, RetType, Getter>(field_idx, obj, referrer, self); \
-} \
-
-ART_GET_FIELD_FROM_MTERP(I8, Byte, int8_t, ssize_t, )
-ART_GET_FIELD_FROM_MTERP(U8, Boolean, uint8_t, size_t, )
-ART_GET_FIELD_FROM_MTERP(I16, Short, int16_t, ssize_t, )
-ART_GET_FIELD_FROM_MTERP(U16, Char, uint16_t, size_t, )
-ART_GET_FIELD_FROM_MTERP(U32, 32, uint32_t, size_t, )
-ART_GET_FIELD_FROM_MTERP(U64, 64, uint64_t, uint64_t, )
-ART_GET_FIELD_FROM_MTERP(Obj, Obj, mirror::HeapReference<mirror::Object>, mirror::Object*, .Ptr())
-
-#undef ART_GET_FIELD_FROM_MTERP
-
-extern "C" ssize_t MterpIPutU8(uint32_t field_idx,
- mirror::Object* obj,
- uint8_t new_value,
- ArtMethod* referrer)
- REQUIRES_SHARED(Locks::mutator_lock_) {
- ArtField* field = referrer->GetDexCache()->GetResolvedField(field_idx, kRuntimePointerSize);
- if (LIKELY(field != nullptr && obj != nullptr)) {
- field->SetBoolean<false>(obj, new_value);
- return 0; // success
- }
- return -1; // failure
+#define MTERP_FIELD_ACCESSOR(Name, PrimType, AccessType) \
+extern "C" bool Name(Instruction* inst, uint16_t inst_data, ShadowFrame* sf, Thread* self) \
+ REQUIRES_SHARED(Locks::mutator_lock_) { \
+ return MterpFieldAccessFast<PrimType, AccessType>(inst, inst_data, sf, self); \
}
-extern "C" ssize_t MterpIPutI8(uint32_t field_idx,
- mirror::Object* obj,
- uint8_t new_value,
- ArtMethod* referrer)
- REQUIRES_SHARED(Locks::mutator_lock_) {
- ArtField* field = referrer->GetDexCache()->GetResolvedField(field_idx, kRuntimePointerSize);
- if (LIKELY(field != nullptr && obj != nullptr)) {
- field->SetByte<false>(obj, new_value);
- return 0; // success
- }
- return -1; // failure
-}
+#define MTERP_FIELD_ACCESSORS_FOR_TYPE(Sufix, PrimType, Kind) \
+ MTERP_FIELD_ACCESSOR(MterpIGet##Sufix, PrimType, Instance##Kind##Read) \
+ MTERP_FIELD_ACCESSOR(MterpIPut##Sufix, PrimType, Instance##Kind##Write) \
+ MTERP_FIELD_ACCESSOR(MterpSGet##Sufix, PrimType, Static##Kind##Read) \
+ MTERP_FIELD_ACCESSOR(MterpSPut##Sufix, PrimType, Static##Kind##Write)
-extern "C" ssize_t MterpIPutU16(uint32_t field_idx,
- mirror::Object* obj,
- uint16_t new_value,
- ArtMethod* referrer)
- REQUIRES_SHARED(Locks::mutator_lock_) {
- ArtField* field = referrer->GetDexCache()->GetResolvedField(field_idx, kRuntimePointerSize);
- if (LIKELY(field != nullptr && obj != nullptr)) {
- field->SetChar<false>(obj, new_value);
- return 0; // success
- }
- return -1; // failure
-}
+MTERP_FIELD_ACCESSORS_FOR_TYPE(I8, int8_t, Primitive)
+MTERP_FIELD_ACCESSORS_FOR_TYPE(U8, uint8_t, Primitive)
+MTERP_FIELD_ACCESSORS_FOR_TYPE(I16, int16_t, Primitive)
+MTERP_FIELD_ACCESSORS_FOR_TYPE(U16, uint16_t, Primitive)
+MTERP_FIELD_ACCESSORS_FOR_TYPE(U32, uint32_t, Primitive)
+MTERP_FIELD_ACCESSORS_FOR_TYPE(U64, uint64_t, Primitive)
+MTERP_FIELD_ACCESSORS_FOR_TYPE(Obj, uint32_t, Object)
-extern "C" ssize_t MterpIPutI16(uint32_t field_idx,
- mirror::Object* obj,
- uint16_t new_value,
- ArtMethod* referrer)
- REQUIRES_SHARED(Locks::mutator_lock_) {
- ArtField* field = referrer->GetDexCache()->GetResolvedField(field_idx, kRuntimePointerSize);
- if (LIKELY(field != nullptr && obj != nullptr)) {
- field->SetShort<false>(obj, new_value);
- return 0; // success
- }
- return -1; // failure
-}
+// Check that the primitive type for Obj variant above is correct.
+// It really must be primitive type for the templates to compile.
+// In the case of objects, it is only used to get the field size.
+static_assert(kHeapReferenceSize == sizeof(uint32_t), "Unexpected kHeapReferenceSize");
-extern "C" ssize_t MterpIPutU32(uint32_t field_idx,
- mirror::Object* obj,
- uint32_t new_value,
- ArtMethod* referrer)
- REQUIRES_SHARED(Locks::mutator_lock_) {
- ArtField* field = referrer->GetDexCache()->GetResolvedField(field_idx, kRuntimePointerSize);
- if (LIKELY(field != nullptr && obj != nullptr)) {
- field->Set32<false>(obj, new_value);
- return 0; // success
- }
- return -1; // failure
-}
-
-extern "C" ssize_t MterpIPutU64(uint32_t field_idx,
- mirror::Object* obj,
- uint64_t* new_value,
- ArtMethod* referrer)
- REQUIRES_SHARED(Locks::mutator_lock_) {
- ArtField* field = referrer->GetDexCache()->GetResolvedField(field_idx, kRuntimePointerSize);
- if (LIKELY(field != nullptr && obj != nullptr)) {
- field->Set64<false>(obj, *new_value);
- return 0; // success
- }
- return -1; // failure
-}
-
-extern "C" ssize_t artSetObjInstanceFromMterp(uint32_t field_idx,
- mirror::Object* obj,
- mirror::Object* new_value,
- ArtMethod* referrer)
- REQUIRES_SHARED(Locks::mutator_lock_) {
- ArtField* field = referrer->GetDexCache()->GetResolvedField(field_idx, kRuntimePointerSize);
- if (LIKELY(field != nullptr && obj != nullptr)) {
- field->SetObj<false>(obj, new_value);
- return 0; // success
- }
- return -1; // failure
-}
-
-template <typename return_type, Primitive::Type primitive_type>
-ALWAYS_INLINE return_type MterpGetStatic(uint32_t field_idx,
- ArtMethod* referrer,
- Thread* self,
- return_type (ArtField::*func)(ObjPtr<mirror::Object>))
- REQUIRES_SHARED(Locks::mutator_lock_) {
- return_type res = 0; // On exception, the result will be ignored.
- ArtField* f =
- FindFieldFromCode<StaticPrimitiveRead, false>(field_idx,
- referrer,
- self,
- primitive_type);
- if (LIKELY(f != nullptr)) {
- ObjPtr<mirror::Object> obj = f->GetDeclaringClass();
- res = (f->*func)(obj);
- }
- return res;
-}
-
-extern "C" int32_t MterpSGetU8(uint32_t field_idx,
- ArtMethod* referrer,
- Thread* self)
- REQUIRES_SHARED(Locks::mutator_lock_) {
- return MterpGetStatic<uint8_t, Primitive::kPrimBoolean>(field_idx,
- referrer,
- self,
- &ArtField::GetBoolean);
-}
-
-extern "C" int32_t MterpSGetI8(uint32_t field_idx,
- ArtMethod* referrer,
- Thread* self)
- REQUIRES_SHARED(Locks::mutator_lock_) {
- return MterpGetStatic<int8_t, Primitive::kPrimByte>(field_idx,
- referrer,
- self,
- &ArtField::GetByte);
-}
-
-extern "C" uint32_t MterpSGetU16(uint32_t field_idx,
- ArtMethod* referrer,
- Thread* self)
- REQUIRES_SHARED(Locks::mutator_lock_) {
- return MterpGetStatic<uint16_t, Primitive::kPrimChar>(field_idx,
- referrer,
- self,
- &ArtField::GetChar);
-}
-
-extern "C" int32_t MterpSGetI16(uint32_t field_idx,
- ArtMethod* referrer,
- Thread* self)
- REQUIRES_SHARED(Locks::mutator_lock_) {
- return MterpGetStatic<int16_t, Primitive::kPrimShort>(field_idx,
- referrer,
- self,
- &ArtField::GetShort);
-}
-
-extern "C" mirror::Object* MterpSGetObj(uint32_t field_idx,
- ArtMethod* referrer,
- Thread* self)
- REQUIRES_SHARED(Locks::mutator_lock_) {
- return MterpGetStatic<ObjPtr<mirror::Object>, Primitive::kPrimNot>(field_idx,
- referrer,
- self,
- &ArtField::GetObject).Ptr();
-}
-
-extern "C" int32_t MterpSGetU32(uint32_t field_idx,
- ArtMethod* referrer,
- Thread* self)
- REQUIRES_SHARED(Locks::mutator_lock_) {
- return MterpGetStatic<int32_t, Primitive::kPrimInt>(field_idx,
- referrer,
- self,
- &ArtField::GetInt);
-}
-
-extern "C" int64_t MterpSGetU64(uint32_t field_idx, ArtMethod* referrer, Thread* self)
- REQUIRES_SHARED(Locks::mutator_lock_) {
- return MterpGetStatic<int64_t, Primitive::kPrimLong>(field_idx,
- referrer,
- self,
- &ArtField::GetLong);
-}
-
-
-template <typename field_type, Primitive::Type primitive_type>
-int MterpSetStatic(uint32_t field_idx,
- field_type new_value,
- ArtMethod* referrer,
- Thread* self,
- void (ArtField::*func)(ObjPtr<mirror::Object>, field_type val))
- REQUIRES_SHARED(Locks::mutator_lock_) {
- int res = 0; // Assume success (following quick_field_entrypoints conventions)
- ArtField* f =
- FindFieldFromCode<StaticPrimitiveWrite, false>(field_idx, referrer, self, primitive_type);
- if (LIKELY(f != nullptr)) {
- ObjPtr<mirror::Object> obj = f->GetDeclaringClass();
- (f->*func)(obj, new_value);
- } else {
- res = -1; // Failure
- }
- return res;
-}
-
-extern "C" int MterpSPutU8(uint32_t field_idx,
- uint8_t new_value,
- ArtMethod* referrer,
- Thread* self)
- REQUIRES_SHARED(Locks::mutator_lock_) {
- return MterpSetStatic<uint8_t, Primitive::kPrimBoolean>(field_idx,
- new_value,
- referrer,
- self,
- &ArtField::SetBoolean<false>);
-}
-
-extern "C" int MterpSPutI8(uint32_t field_idx,
- int8_t new_value,
- ArtMethod* referrer,
- Thread* self)
- REQUIRES_SHARED(Locks::mutator_lock_) {
- return MterpSetStatic<int8_t, Primitive::kPrimByte>(field_idx,
- new_value,
- referrer,
- self,
- &ArtField::SetByte<false>);
-}
-
-extern "C" int MterpSPutU16(uint32_t field_idx,
- uint16_t new_value,
- ArtMethod* referrer,
- Thread* self)
- REQUIRES_SHARED(Locks::mutator_lock_) {
- return MterpSetStatic<uint16_t, Primitive::kPrimChar>(field_idx,
- new_value,
- referrer,
- self,
- &ArtField::SetChar<false>);
-}
-
-extern "C" int MterpSPutI16(uint32_t field_idx,
- int16_t new_value,
- ArtMethod* referrer,
- Thread* self)
- REQUIRES_SHARED(Locks::mutator_lock_) {
- return MterpSetStatic<int16_t, Primitive::kPrimShort>(field_idx,
- new_value,
- referrer,
- self,
- &ArtField::SetShort<false>);
-}
-
-extern "C" int MterpSPutU32(uint32_t field_idx,
- int32_t new_value,
- ArtMethod* referrer,
- Thread* self)
- REQUIRES_SHARED(Locks::mutator_lock_) {
- return MterpSetStatic<int32_t, Primitive::kPrimInt>(field_idx,
- new_value,
- referrer,
- self,
- &ArtField::SetInt<false>);
-}
-
-extern "C" int MterpSPutU64(uint32_t field_idx,
- int64_t* new_value,
- ArtMethod* referrer,
- Thread* self)
- REQUIRES_SHARED(Locks::mutator_lock_) {
- return MterpSetStatic<int64_t, Primitive::kPrimLong>(field_idx,
- *new_value,
- referrer,
- self,
- &ArtField::SetLong<false>);
-}
+#undef MTERP_FIELD_ACCESSORS_FOR_TYPE
+#undef MTERP_FIELD_ACCESSOR
extern "C" mirror::Object* artAGetObjectFromMterp(mirror::Object* arr,
int32_t index)
diff --git a/runtime/interpreter/mterp/out/mterp_arm.S b/runtime/interpreter/mterp/out/mterp_arm.S
index 394a849..25512ae 100644
--- a/runtime/interpreter/mterp/out/mterp_arm.S
+++ b/runtime/interpreter/mterp/out/mterp_arm.S
@@ -2246,215 +2246,185 @@
.balign 128
.L_op_iget: /* 0x52 */
/* File: arm/op_iget.S */
+/* File: arm/field.S */
/*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- EXPORT_PC
- FETCH r0, 1 @ r0<- field ref CCCC
- mov r1, rINST, lsr #12 @ r1<- B
- GET_VREG r1, r1 @ r1<- fp[B], the object pointer
- ldr r2, [rFP, #OFF_FP_METHOD] @ r2<- referrer
- mov r3, rSELF @ r3<- self
+ .extern MterpIGetU32
+ mov r0, rPC @ arg0: Instruction* inst
+ mov r1, rINST @ arg1: uint16_t inst_data
+ add r2, rFP, #OFF_FP_SHADOWFRAME @ arg2: ShadowFrame* sf
+ mov r3, rSELF @ arg3: Thread* self
+ PREFETCH_INST 2 @ prefetch next opcode
bl MterpIGetU32
- ldr r3, [rSELF, #THREAD_EXCEPTION_OFFSET]
- ubfx r2, rINST, #8, #4 @ r2<- A
- PREFETCH_INST 2
- cmp r3, #0
- bne MterpPossibleException @ bail out
- .if 0
- SET_VREG_OBJECT r0, r2 @ fp[A]<- r0
- .else
- SET_VREG r0, r2 @ fp[A]<- r0
- .endif
+ cmp r0, #0
+ beq MterpPossibleException
ADVANCE 2
GET_INST_OPCODE ip @ extract opcode from rINST
GOTO_OPCODE ip @ jump to next instruction
+
/* ------------------------------ */
.balign 128
.L_op_iget_wide: /* 0x53 */
/* File: arm/op_iget_wide.S */
+/* File: arm/op_iget.S */
+/* File: arm/field.S */
/*
- * 64-bit instance field get.
- *
- * for: iget-wide
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- EXPORT_PC
- FETCH r0, 1 @ r0<- field ref CCCC
- mov r1, rINST, lsr #12 @ r1<- B
- GET_VREG r1, r1 @ r1<- fp[B], the object pointer
- ldr r2, [rFP, #OFF_FP_METHOD] @ r2<- referrer
- mov r3, rSELF @ r3<- self
+ .extern MterpIGetU64
+ mov r0, rPC @ arg0: Instruction* inst
+ mov r1, rINST @ arg1: uint16_t inst_data
+ add r2, rFP, #OFF_FP_SHADOWFRAME @ arg2: ShadowFrame* sf
+ mov r3, rSELF @ arg3: Thread* self
+ PREFETCH_INST 2 @ prefetch next opcode
bl MterpIGetU64
- ldr r3, [rSELF, #THREAD_EXCEPTION_OFFSET]
- ubfx r2, rINST, #8, #4 @ r2<- A
- PREFETCH_INST 2
- cmp r3, #0
- bne MterpException @ bail out
- CLEAR_SHADOW_PAIR r2, ip, lr @ Zero out the shadow regs
- VREG_INDEX_TO_ADDR r3, r2 @ r3<- &fp[A]
- stmia r3, {r0-r1} @ fp[A]<- r0/r1
+ cmp r0, #0
+ beq MterpPossibleException
ADVANCE 2
GET_INST_OPCODE ip @ extract opcode from rINST
GOTO_OPCODE ip @ jump to next instruction
+
+
/* ------------------------------ */
.balign 128
.L_op_iget_object: /* 0x54 */
/* File: arm/op_iget_object.S */
/* File: arm/op_iget.S */
+/* File: arm/field.S */
/*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- EXPORT_PC
- FETCH r0, 1 @ r0<- field ref CCCC
- mov r1, rINST, lsr #12 @ r1<- B
- GET_VREG r1, r1 @ r1<- fp[B], the object pointer
- ldr r2, [rFP, #OFF_FP_METHOD] @ r2<- referrer
- mov r3, rSELF @ r3<- self
+ .extern MterpIGetObj
+ mov r0, rPC @ arg0: Instruction* inst
+ mov r1, rINST @ arg1: uint16_t inst_data
+ add r2, rFP, #OFF_FP_SHADOWFRAME @ arg2: ShadowFrame* sf
+ mov r3, rSELF @ arg3: Thread* self
+ PREFETCH_INST 2 @ prefetch next opcode
bl MterpIGetObj
- ldr r3, [rSELF, #THREAD_EXCEPTION_OFFSET]
- ubfx r2, rINST, #8, #4 @ r2<- A
- PREFETCH_INST 2
- cmp r3, #0
- bne MterpPossibleException @ bail out
- .if 1
- SET_VREG_OBJECT r0, r2 @ fp[A]<- r0
- .else
- SET_VREG r0, r2 @ fp[A]<- r0
- .endif
+ cmp r0, #0
+ beq MterpPossibleException
ADVANCE 2
GET_INST_OPCODE ip @ extract opcode from rINST
GOTO_OPCODE ip @ jump to next instruction
+
/* ------------------------------ */
.balign 128
.L_op_iget_boolean: /* 0x55 */
/* File: arm/op_iget_boolean.S */
/* File: arm/op_iget.S */
+/* File: arm/field.S */
/*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- EXPORT_PC
- FETCH r0, 1 @ r0<- field ref CCCC
- mov r1, rINST, lsr #12 @ r1<- B
- GET_VREG r1, r1 @ r1<- fp[B], the object pointer
- ldr r2, [rFP, #OFF_FP_METHOD] @ r2<- referrer
- mov r3, rSELF @ r3<- self
+ .extern MterpIGetU8
+ mov r0, rPC @ arg0: Instruction* inst
+ mov r1, rINST @ arg1: uint16_t inst_data
+ add r2, rFP, #OFF_FP_SHADOWFRAME @ arg2: ShadowFrame* sf
+ mov r3, rSELF @ arg3: Thread* self
+ PREFETCH_INST 2 @ prefetch next opcode
bl MterpIGetU8
- ldr r3, [rSELF, #THREAD_EXCEPTION_OFFSET]
- ubfx r2, rINST, #8, #4 @ r2<- A
- PREFETCH_INST 2
- cmp r3, #0
- bne MterpPossibleException @ bail out
- .if 0
- SET_VREG_OBJECT r0, r2 @ fp[A]<- r0
- .else
- SET_VREG r0, r2 @ fp[A]<- r0
- .endif
+ cmp r0, #0
+ beq MterpPossibleException
ADVANCE 2
GET_INST_OPCODE ip @ extract opcode from rINST
GOTO_OPCODE ip @ jump to next instruction
+
/* ------------------------------ */
.balign 128
.L_op_iget_byte: /* 0x56 */
/* File: arm/op_iget_byte.S */
/* File: arm/op_iget.S */
+/* File: arm/field.S */
/*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- EXPORT_PC
- FETCH r0, 1 @ r0<- field ref CCCC
- mov r1, rINST, lsr #12 @ r1<- B
- GET_VREG r1, r1 @ r1<- fp[B], the object pointer
- ldr r2, [rFP, #OFF_FP_METHOD] @ r2<- referrer
- mov r3, rSELF @ r3<- self
+ .extern MterpIGetI8
+ mov r0, rPC @ arg0: Instruction* inst
+ mov r1, rINST @ arg1: uint16_t inst_data
+ add r2, rFP, #OFF_FP_SHADOWFRAME @ arg2: ShadowFrame* sf
+ mov r3, rSELF @ arg3: Thread* self
+ PREFETCH_INST 2 @ prefetch next opcode
bl MterpIGetI8
- ldr r3, [rSELF, #THREAD_EXCEPTION_OFFSET]
- ubfx r2, rINST, #8, #4 @ r2<- A
- PREFETCH_INST 2
- cmp r3, #0
- bne MterpPossibleException @ bail out
- .if 0
- SET_VREG_OBJECT r0, r2 @ fp[A]<- r0
- .else
- SET_VREG r0, r2 @ fp[A]<- r0
- .endif
+ cmp r0, #0
+ beq MterpPossibleException
ADVANCE 2
GET_INST_OPCODE ip @ extract opcode from rINST
GOTO_OPCODE ip @ jump to next instruction
+
/* ------------------------------ */
.balign 128
.L_op_iget_char: /* 0x57 */
/* File: arm/op_iget_char.S */
/* File: arm/op_iget.S */
+/* File: arm/field.S */
/*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- EXPORT_PC
- FETCH r0, 1 @ r0<- field ref CCCC
- mov r1, rINST, lsr #12 @ r1<- B
- GET_VREG r1, r1 @ r1<- fp[B], the object pointer
- ldr r2, [rFP, #OFF_FP_METHOD] @ r2<- referrer
- mov r3, rSELF @ r3<- self
+ .extern MterpIGetU16
+ mov r0, rPC @ arg0: Instruction* inst
+ mov r1, rINST @ arg1: uint16_t inst_data
+ add r2, rFP, #OFF_FP_SHADOWFRAME @ arg2: ShadowFrame* sf
+ mov r3, rSELF @ arg3: Thread* self
+ PREFETCH_INST 2 @ prefetch next opcode
bl MterpIGetU16
- ldr r3, [rSELF, #THREAD_EXCEPTION_OFFSET]
- ubfx r2, rINST, #8, #4 @ r2<- A
- PREFETCH_INST 2
- cmp r3, #0
- bne MterpPossibleException @ bail out
- .if 0
- SET_VREG_OBJECT r0, r2 @ fp[A]<- r0
- .else
- SET_VREG r0, r2 @ fp[A]<- r0
- .endif
+ cmp r0, #0
+ beq MterpPossibleException
ADVANCE 2
GET_INST_OPCODE ip @ extract opcode from rINST
GOTO_OPCODE ip @ jump to next instruction
+
/* ------------------------------ */
.balign 128
.L_op_iget_short: /* 0x58 */
/* File: arm/op_iget_short.S */
/* File: arm/op_iget.S */
+/* File: arm/field.S */
/*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- EXPORT_PC
- FETCH r0, 1 @ r0<- field ref CCCC
- mov r1, rINST, lsr #12 @ r1<- B
- GET_VREG r1, r1 @ r1<- fp[B], the object pointer
- ldr r2, [rFP, #OFF_FP_METHOD] @ r2<- referrer
- mov r3, rSELF @ r3<- self
+ .extern MterpIGetI16
+ mov r0, rPC @ arg0: Instruction* inst
+ mov r1, rINST @ arg1: uint16_t inst_data
+ add r2, rFP, #OFF_FP_SHADOWFRAME @ arg2: ShadowFrame* sf
+ mov r3, rSELF @ arg3: Thread* self
+ PREFETCH_INST 2 @ prefetch next opcode
bl MterpIGetI16
- ldr r3, [rSELF, #THREAD_EXCEPTION_OFFSET]
- ubfx r2, rINST, #8, #4 @ r2<- A
- PREFETCH_INST 2
- cmp r3, #0
- bne MterpPossibleException @ bail out
- .if 0
- SET_VREG_OBJECT r0, r2 @ fp[A]<- r0
- .else
- SET_VREG r0, r2 @ fp[A]<- r0
- .endif
+ cmp r0, #0
+ beq MterpPossibleException
+ ADVANCE 2
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ GOTO_OPCODE ip @ jump to next instruction
+
+
+
+/* ------------------------------ */
+ .balign 128
+.L_op_iput: /* 0x59 */
+/* File: arm/op_iput.S */
+/* File: arm/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
+ .extern MterpIPutU32
+ mov r0, rPC @ arg0: Instruction* inst
+ mov r1, rINST @ arg1: uint16_t inst_data
+ add r2, rFP, #OFF_FP_SHADOWFRAME @ arg2: ShadowFrame* sf
+ mov r3, rSELF @ arg3: Thread* self
+ PREFETCH_INST 2 @ prefetch next opcode
+ bl MterpIPutU32
+ cmp r0, #0
+ beq MterpPossibleException
ADVANCE 2
GET_INST_OPCODE ip @ extract opcode from rINST
GOTO_OPCODE ip @ jump to next instruction
@@ -2462,93 +2432,74 @@
/* ------------------------------ */
.balign 128
-.L_op_iput: /* 0x59 */
-/* File: arm/op_iput.S */
- /*
- * General 32-bit instance field put.
- *
- * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
- */
- /* op vA, vB, field@CCCC */
- .extern MterpIPutU32
- EXPORT_PC
- FETCH r0, 1 @ r0<- field ref CCCC
- mov r1, rINST, lsr #12 @ r1<- B
- GET_VREG r1, r1 @ r1<- fp[B], the object pointer
- ubfx r2, rINST, #8, #4 @ r2<- A
- GET_VREG r2, r2 @ r2<- fp[A]
- ldr r3, [rFP, #OFF_FP_METHOD] @ r3<- referrer
- PREFETCH_INST 2
- bl MterpIPutU32
- cmp r0, #0
- bne MterpPossibleException
- ADVANCE 2 @ advance rPC
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip @ jump to next instruction
-
-/* ------------------------------ */
- .balign 128
.L_op_iput_wide: /* 0x5a */
/* File: arm/op_iput_wide.S */
- /* iput-wide vA, vB, field@CCCC */
+/* File: arm/op_iput.S */
+/* File: arm/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpIPutU64
- EXPORT_PC
- FETCH r0, 1 @ r0<- field ref CCCC
- mov r1, rINST, lsr #12 @ r1<- B
- GET_VREG r1, r1 @ r1<- fp[B], the object pointer
- ubfx r2, rINST, #8, #4 @ r2<- A
- VREG_INDEX_TO_ADDR r2, r2 @ r2<- &fp[A]
- ldr r3, [rFP, #OFF_FP_METHOD] @ r3<- referrer
- PREFETCH_INST 2
+ mov r0, rPC @ arg0: Instruction* inst
+ mov r1, rINST @ arg1: uint16_t inst_data
+ add r2, rFP, #OFF_FP_SHADOWFRAME @ arg2: ShadowFrame* sf
+ mov r3, rSELF @ arg3: Thread* self
+ PREFETCH_INST 2 @ prefetch next opcode
bl MterpIPutU64
cmp r0, #0
- bne MterpPossibleException
- ADVANCE 2 @ advance rPC
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip @ jump to next instruction
+ beq MterpPossibleException
+ ADVANCE 2
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ GOTO_OPCODE ip @ jump to next instruction
+
+
/* ------------------------------ */
.balign 128
.L_op_iput_object: /* 0x5b */
/* File: arm/op_iput_object.S */
- EXPORT_PC
- add r0, rFP, #OFF_FP_SHADOWFRAME
- mov r1, rPC
- mov r2, rINST
- mov r3, rSELF
- bl MterpIPutObj
- cmp r0, #0
- beq MterpException
- FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip @ jump to next instruction
+/* File: arm/op_iput.S */
+/* File: arm/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
+ .extern MterpIPutObj
+ mov r0, rPC @ arg0: Instruction* inst
+ mov r1, rINST @ arg1: uint16_t inst_data
+ add r2, rFP, #OFF_FP_SHADOWFRAME @ arg2: ShadowFrame* sf
+ mov r3, rSELF @ arg3: Thread* self
+ PREFETCH_INST 2 @ prefetch next opcode
+ bl MterpIPutObj
+ cmp r0, #0
+ beq MterpPossibleException
+ ADVANCE 2
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ GOTO_OPCODE ip @ jump to next instruction
+
+
/* ------------------------------ */
.balign 128
.L_op_iput_boolean: /* 0x5c */
/* File: arm/op_iput_boolean.S */
/* File: arm/op_iput.S */
+/* File: arm/field.S */
/*
- * General 32-bit instance field put.
- *
- * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- /* op vA, vB, field@CCCC */
.extern MterpIPutU8
- EXPORT_PC
- FETCH r0, 1 @ r0<- field ref CCCC
- mov r1, rINST, lsr #12 @ r1<- B
- GET_VREG r1, r1 @ r1<- fp[B], the object pointer
- ubfx r2, rINST, #8, #4 @ r2<- A
- GET_VREG r2, r2 @ r2<- fp[A]
- ldr r3, [rFP, #OFF_FP_METHOD] @ r3<- referrer
- PREFETCH_INST 2
+ mov r0, rPC @ arg0: Instruction* inst
+ mov r1, rINST @ arg1: uint16_t inst_data
+ add r2, rFP, #OFF_FP_SHADOWFRAME @ arg2: ShadowFrame* sf
+ mov r3, rSELF @ arg3: Thread* self
+ PREFETCH_INST 2 @ prefetch next opcode
bl MterpIPutU8
cmp r0, #0
- bne MterpPossibleException
- ADVANCE 2 @ advance rPC
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip @ jump to next instruction
+ beq MterpPossibleException
+ ADVANCE 2
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ GOTO_OPCODE ip @ jump to next instruction
+
/* ------------------------------ */
@@ -2556,27 +2507,23 @@
.L_op_iput_byte: /* 0x5d */
/* File: arm/op_iput_byte.S */
/* File: arm/op_iput.S */
+/* File: arm/field.S */
/*
- * General 32-bit instance field put.
- *
- * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- /* op vA, vB, field@CCCC */
.extern MterpIPutI8
- EXPORT_PC
- FETCH r0, 1 @ r0<- field ref CCCC
- mov r1, rINST, lsr #12 @ r1<- B
- GET_VREG r1, r1 @ r1<- fp[B], the object pointer
- ubfx r2, rINST, #8, #4 @ r2<- A
- GET_VREG r2, r2 @ r2<- fp[A]
- ldr r3, [rFP, #OFF_FP_METHOD] @ r3<- referrer
- PREFETCH_INST 2
+ mov r0, rPC @ arg0: Instruction* inst
+ mov r1, rINST @ arg1: uint16_t inst_data
+ add r2, rFP, #OFF_FP_SHADOWFRAME @ arg2: ShadowFrame* sf
+ mov r3, rSELF @ arg3: Thread* self
+ PREFETCH_INST 2 @ prefetch next opcode
bl MterpIPutI8
cmp r0, #0
- bne MterpPossibleException
- ADVANCE 2 @ advance rPC
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip @ jump to next instruction
+ beq MterpPossibleException
+ ADVANCE 2
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ GOTO_OPCODE ip @ jump to next instruction
+
/* ------------------------------ */
@@ -2584,27 +2531,23 @@
.L_op_iput_char: /* 0x5e */
/* File: arm/op_iput_char.S */
/* File: arm/op_iput.S */
+/* File: arm/field.S */
/*
- * General 32-bit instance field put.
- *
- * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- /* op vA, vB, field@CCCC */
.extern MterpIPutU16
- EXPORT_PC
- FETCH r0, 1 @ r0<- field ref CCCC
- mov r1, rINST, lsr #12 @ r1<- B
- GET_VREG r1, r1 @ r1<- fp[B], the object pointer
- ubfx r2, rINST, #8, #4 @ r2<- A
- GET_VREG r2, r2 @ r2<- fp[A]
- ldr r3, [rFP, #OFF_FP_METHOD] @ r3<- referrer
- PREFETCH_INST 2
+ mov r0, rPC @ arg0: Instruction* inst
+ mov r1, rINST @ arg1: uint16_t inst_data
+ add r2, rFP, #OFF_FP_SHADOWFRAME @ arg2: ShadowFrame* sf
+ mov r3, rSELF @ arg3: Thread* self
+ PREFETCH_INST 2 @ prefetch next opcode
bl MterpIPutU16
cmp r0, #0
- bne MterpPossibleException
- ADVANCE 2 @ advance rPC
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip @ jump to next instruction
+ beq MterpPossibleException
+ ADVANCE 2
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ GOTO_OPCODE ip @ jump to next instruction
+
/* ------------------------------ */
@@ -2612,118 +2555,93 @@
.L_op_iput_short: /* 0x5f */
/* File: arm/op_iput_short.S */
/* File: arm/op_iput.S */
+/* File: arm/field.S */
/*
- * General 32-bit instance field put.
- *
- * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- /* op vA, vB, field@CCCC */
.extern MterpIPutI16
- EXPORT_PC
- FETCH r0, 1 @ r0<- field ref CCCC
- mov r1, rINST, lsr #12 @ r1<- B
- GET_VREG r1, r1 @ r1<- fp[B], the object pointer
- ubfx r2, rINST, #8, #4 @ r2<- A
- GET_VREG r2, r2 @ r2<- fp[A]
- ldr r3, [rFP, #OFF_FP_METHOD] @ r3<- referrer
- PREFETCH_INST 2
+ mov r0, rPC @ arg0: Instruction* inst
+ mov r1, rINST @ arg1: uint16_t inst_data
+ add r2, rFP, #OFF_FP_SHADOWFRAME @ arg2: ShadowFrame* sf
+ mov r3, rSELF @ arg3: Thread* self
+ PREFETCH_INST 2 @ prefetch next opcode
bl MterpIPutI16
cmp r0, #0
- bne MterpPossibleException
- ADVANCE 2 @ advance rPC
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip @ jump to next instruction
+ beq MterpPossibleException
+ ADVANCE 2
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ GOTO_OPCODE ip @ jump to next instruction
+
/* ------------------------------ */
.balign 128
.L_op_sget: /* 0x60 */
/* File: arm/op_sget.S */
+/* File: arm/field.S */
/*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- /* op vAA, field@BBBB */
-
.extern MterpSGetU32
- EXPORT_PC
- FETCH r0, 1 @ r0<- field ref BBBB
- ldr r1, [rFP, #OFF_FP_METHOD]
- mov r2, rSELF
- bl MterpSGetU32
- ldr r3, [rSELF, #THREAD_EXCEPTION_OFFSET]
- mov r2, rINST, lsr #8 @ r2<- AA
- PREFETCH_INST 2
- cmp r3, #0 @ Fail to resolve?
- bne MterpException @ bail out
-.if 0
- SET_VREG_OBJECT r0, r2 @ fp[AA]<- r0
-.else
- SET_VREG r0, r2 @ fp[AA]<- r0
-.endif
+ mov r0, rPC @ arg0: Instruction* inst
+ mov r1, rINST @ arg1: uint16_t inst_data
+ add r2, rFP, #OFF_FP_SHADOWFRAME @ arg2: ShadowFrame* sf
+ mov r3, rSELF @ arg3: Thread* self
+ PREFETCH_INST 2 @ prefetch next opcode
+ bl MterpSGetU32
+ cmp r0, #0
+ beq MterpPossibleException
ADVANCE 2
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ GOTO_OPCODE ip @ jump to next instruction
+
/* ------------------------------ */
.balign 128
.L_op_sget_wide: /* 0x61 */
/* File: arm/op_sget_wide.S */
+/* File: arm/op_sget.S */
+/* File: arm/field.S */
/*
- * SGET_WIDE handler wrapper.
- *
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- /* sget-wide vAA, field@BBBB */
-
.extern MterpSGetU64
- EXPORT_PC
- FETCH r0, 1 @ r0<- field ref BBBB
- ldr r1, [rFP, #OFF_FP_METHOD]
- mov r2, rSELF
- bl MterpSGetU64
- ldr r3, [rSELF, #THREAD_EXCEPTION_OFFSET]
- mov r9, rINST, lsr #8 @ r9<- AA
- VREG_INDEX_TO_ADDR lr, r9 @ r9<- &fp[AA]
- cmp r3, #0 @ Fail to resolve?
- bne MterpException @ bail out
- FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
- CLEAR_SHADOW_PAIR r9, r2, ip @ Zero out the shadow regs
- stmia lr, {r0-r1} @ vAA/vAA+1<- r0/r1
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip @ jump to next instruction
+ mov r0, rPC @ arg0: Instruction* inst
+ mov r1, rINST @ arg1: uint16_t inst_data
+ add r2, rFP, #OFF_FP_SHADOWFRAME @ arg2: ShadowFrame* sf
+ mov r3, rSELF @ arg3: Thread* self
+ PREFETCH_INST 2 @ prefetch next opcode
+ bl MterpSGetU64
+ cmp r0, #0
+ beq MterpPossibleException
+ ADVANCE 2
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ GOTO_OPCODE ip @ jump to next instruction
+
+
/* ------------------------------ */
.balign 128
.L_op_sget_object: /* 0x62 */
/* File: arm/op_sget_object.S */
/* File: arm/op_sget.S */
+/* File: arm/field.S */
/*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- /* op vAA, field@BBBB */
-
.extern MterpSGetObj
- EXPORT_PC
- FETCH r0, 1 @ r0<- field ref BBBB
- ldr r1, [rFP, #OFF_FP_METHOD]
- mov r2, rSELF
- bl MterpSGetObj
- ldr r3, [rSELF, #THREAD_EXCEPTION_OFFSET]
- mov r2, rINST, lsr #8 @ r2<- AA
- PREFETCH_INST 2
- cmp r3, #0 @ Fail to resolve?
- bne MterpException @ bail out
-.if 1
- SET_VREG_OBJECT r0, r2 @ fp[AA]<- r0
-.else
- SET_VREG r0, r2 @ fp[AA]<- r0
-.endif
+ mov r0, rPC @ arg0: Instruction* inst
+ mov r1, rINST @ arg1: uint16_t inst_data
+ add r2, rFP, #OFF_FP_SHADOWFRAME @ arg2: ShadowFrame* sf
+ mov r3, rSELF @ arg3: Thread* self
+ PREFETCH_INST 2 @ prefetch next opcode
+ bl MterpSGetObj
+ cmp r0, #0
+ beq MterpPossibleException
ADVANCE 2
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ GOTO_OPCODE ip @ jump to next instruction
+
/* ------------------------------ */
@@ -2731,32 +2649,23 @@
.L_op_sget_boolean: /* 0x63 */
/* File: arm/op_sget_boolean.S */
/* File: arm/op_sget.S */
+/* File: arm/field.S */
/*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- /* op vAA, field@BBBB */
-
.extern MterpSGetU8
- EXPORT_PC
- FETCH r0, 1 @ r0<- field ref BBBB
- ldr r1, [rFP, #OFF_FP_METHOD]
- mov r2, rSELF
- bl MterpSGetU8
- ldr r3, [rSELF, #THREAD_EXCEPTION_OFFSET]
- mov r2, rINST, lsr #8 @ r2<- AA
- PREFETCH_INST 2
- cmp r3, #0 @ Fail to resolve?
- bne MterpException @ bail out
-.if 0
- SET_VREG_OBJECT r0, r2 @ fp[AA]<- r0
-.else
- SET_VREG r0, r2 @ fp[AA]<- r0
-.endif
+ mov r0, rPC @ arg0: Instruction* inst
+ mov r1, rINST @ arg1: uint16_t inst_data
+ add r2, rFP, #OFF_FP_SHADOWFRAME @ arg2: ShadowFrame* sf
+ mov r3, rSELF @ arg3: Thread* self
+ PREFETCH_INST 2 @ prefetch next opcode
+ bl MterpSGetU8
+ cmp r0, #0
+ beq MterpPossibleException
ADVANCE 2
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ GOTO_OPCODE ip @ jump to next instruction
+
/* ------------------------------ */
@@ -2764,32 +2673,23 @@
.L_op_sget_byte: /* 0x64 */
/* File: arm/op_sget_byte.S */
/* File: arm/op_sget.S */
+/* File: arm/field.S */
/*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- /* op vAA, field@BBBB */
-
.extern MterpSGetI8
- EXPORT_PC
- FETCH r0, 1 @ r0<- field ref BBBB
- ldr r1, [rFP, #OFF_FP_METHOD]
- mov r2, rSELF
- bl MterpSGetI8
- ldr r3, [rSELF, #THREAD_EXCEPTION_OFFSET]
- mov r2, rINST, lsr #8 @ r2<- AA
- PREFETCH_INST 2
- cmp r3, #0 @ Fail to resolve?
- bne MterpException @ bail out
-.if 0
- SET_VREG_OBJECT r0, r2 @ fp[AA]<- r0
-.else
- SET_VREG r0, r2 @ fp[AA]<- r0
-.endif
+ mov r0, rPC @ arg0: Instruction* inst
+ mov r1, rINST @ arg1: uint16_t inst_data
+ add r2, rFP, #OFF_FP_SHADOWFRAME @ arg2: ShadowFrame* sf
+ mov r3, rSELF @ arg3: Thread* self
+ PREFETCH_INST 2 @ prefetch next opcode
+ bl MterpSGetI8
+ cmp r0, #0
+ beq MterpPossibleException
ADVANCE 2
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ GOTO_OPCODE ip @ jump to next instruction
+
/* ------------------------------ */
@@ -2797,32 +2697,23 @@
.L_op_sget_char: /* 0x65 */
/* File: arm/op_sget_char.S */
/* File: arm/op_sget.S */
+/* File: arm/field.S */
/*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- /* op vAA, field@BBBB */
-
.extern MterpSGetU16
- EXPORT_PC
- FETCH r0, 1 @ r0<- field ref BBBB
- ldr r1, [rFP, #OFF_FP_METHOD]
- mov r2, rSELF
- bl MterpSGetU16
- ldr r3, [rSELF, #THREAD_EXCEPTION_OFFSET]
- mov r2, rINST, lsr #8 @ r2<- AA
- PREFETCH_INST 2
- cmp r3, #0 @ Fail to resolve?
- bne MterpException @ bail out
-.if 0
- SET_VREG_OBJECT r0, r2 @ fp[AA]<- r0
-.else
- SET_VREG r0, r2 @ fp[AA]<- r0
-.endif
+ mov r0, rPC @ arg0: Instruction* inst
+ mov r1, rINST @ arg1: uint16_t inst_data
+ add r2, rFP, #OFF_FP_SHADOWFRAME @ arg2: ShadowFrame* sf
+ mov r3, rSELF @ arg3: Thread* self
+ PREFETCH_INST 2 @ prefetch next opcode
+ bl MterpSGetU16
+ cmp r0, #0
+ beq MterpPossibleException
ADVANCE 2
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ GOTO_OPCODE ip @ jump to next instruction
+
/* ------------------------------ */
@@ -2830,122 +2721,117 @@
.L_op_sget_short: /* 0x66 */
/* File: arm/op_sget_short.S */
/* File: arm/op_sget.S */
+/* File: arm/field.S */
/*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- /* op vAA, field@BBBB */
-
.extern MterpSGetI16
- EXPORT_PC
- FETCH r0, 1 @ r0<- field ref BBBB
- ldr r1, [rFP, #OFF_FP_METHOD]
- mov r2, rSELF
- bl MterpSGetI16
- ldr r3, [rSELF, #THREAD_EXCEPTION_OFFSET]
- mov r2, rINST, lsr #8 @ r2<- AA
- PREFETCH_INST 2
- cmp r3, #0 @ Fail to resolve?
- bne MterpException @ bail out
-.if 0
- SET_VREG_OBJECT r0, r2 @ fp[AA]<- r0
-.else
- SET_VREG r0, r2 @ fp[AA]<- r0
-.endif
+ mov r0, rPC @ arg0: Instruction* inst
+ mov r1, rINST @ arg1: uint16_t inst_data
+ add r2, rFP, #OFF_FP_SHADOWFRAME @ arg2: ShadowFrame* sf
+ mov r3, rSELF @ arg3: Thread* self
+ PREFETCH_INST 2 @ prefetch next opcode
+ bl MterpSGetI16
+ cmp r0, #0
+ beq MterpPossibleException
ADVANCE 2
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ GOTO_OPCODE ip @ jump to next instruction
+
/* ------------------------------ */
.balign 128
.L_op_sput: /* 0x67 */
/* File: arm/op_sput.S */
+/* File: arm/field.S */
/*
- * General SPUT handler wrapper.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- /* op vAA, field@BBBB */
- EXPORT_PC
- FETCH r0, 1 @ r0<- field ref BBBB
- mov r3, rINST, lsr #8 @ r3<- AA
- GET_VREG r1, r3 @ r1<= fp[AA]
- ldr r2, [rFP, #OFF_FP_METHOD]
- mov r3, rSELF
- PREFETCH_INST 2 @ Get next inst, but don't advance rPC
- bl MterpSPutU32
- cmp r0, #0 @ 0 on success, -1 on failure
- bne MterpException
- ADVANCE 2 @ Past exception point - now advance rPC
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip @ jump to next instruction
+ .extern MterpSPutU32
+ mov r0, rPC @ arg0: Instruction* inst
+ mov r1, rINST @ arg1: uint16_t inst_data
+ add r2, rFP, #OFF_FP_SHADOWFRAME @ arg2: ShadowFrame* sf
+ mov r3, rSELF @ arg3: Thread* self
+ PREFETCH_INST 2 @ prefetch next opcode
+ bl MterpSPutU32
+ cmp r0, #0
+ beq MterpPossibleException
+ ADVANCE 2
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ GOTO_OPCODE ip @ jump to next instruction
+
/* ------------------------------ */
.balign 128
.L_op_sput_wide: /* 0x68 */
/* File: arm/op_sput_wide.S */
+/* File: arm/op_sput.S */
+/* File: arm/field.S */
/*
- * SPUT_WIDE handler wrapper.
- *
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- /* sput-wide vAA, field@BBBB */
.extern MterpSPutU64
- EXPORT_PC
- FETCH r0, 1 @ r0<- field ref BBBB
- mov r1, rINST, lsr #8 @ r1<- AA
- VREG_INDEX_TO_ADDR r1, r1
- ldr r2, [rFP, #OFF_FP_METHOD]
- mov r3, rSELF
- PREFETCH_INST 2 @ Get next inst, but don't advance rPC
- bl MterpSPutU64
- cmp r0, #0 @ 0 on success, -1 on failure
- bne MterpException
- ADVANCE 2 @ Past exception point - now advance rPC
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip @ jump to next instruction
+ mov r0, rPC @ arg0: Instruction* inst
+ mov r1, rINST @ arg1: uint16_t inst_data
+ add r2, rFP, #OFF_FP_SHADOWFRAME @ arg2: ShadowFrame* sf
+ mov r3, rSELF @ arg3: Thread* self
+ PREFETCH_INST 2 @ prefetch next opcode
+ bl MterpSPutU64
+ cmp r0, #0
+ beq MterpPossibleException
+ ADVANCE 2
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ GOTO_OPCODE ip @ jump to next instruction
+
+
/* ------------------------------ */
.balign 128
.L_op_sput_object: /* 0x69 */
/* File: arm/op_sput_object.S */
- EXPORT_PC
- add r0, rFP, #OFF_FP_SHADOWFRAME
- mov r1, rPC
- mov r2, rINST
- mov r3, rSELF
- bl MterpSPutObj
- cmp r0, #0
- beq MterpException
- FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip @ jump to next instruction
+/* File: arm/op_sput.S */
+/* File: arm/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
+ .extern MterpSPutObj
+ mov r0, rPC @ arg0: Instruction* inst
+ mov r1, rINST @ arg1: uint16_t inst_data
+ add r2, rFP, #OFF_FP_SHADOWFRAME @ arg2: ShadowFrame* sf
+ mov r3, rSELF @ arg3: Thread* self
+ PREFETCH_INST 2 @ prefetch next opcode
+ bl MterpSPutObj
+ cmp r0, #0
+ beq MterpPossibleException
+ ADVANCE 2
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ GOTO_OPCODE ip @ jump to next instruction
+
+
/* ------------------------------ */
.balign 128
.L_op_sput_boolean: /* 0x6a */
/* File: arm/op_sput_boolean.S */
/* File: arm/op_sput.S */
+/* File: arm/field.S */
/*
- * General SPUT handler wrapper.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- /* op vAA, field@BBBB */
- EXPORT_PC
- FETCH r0, 1 @ r0<- field ref BBBB
- mov r3, rINST, lsr #8 @ r3<- AA
- GET_VREG r1, r3 @ r1<= fp[AA]
- ldr r2, [rFP, #OFF_FP_METHOD]
- mov r3, rSELF
- PREFETCH_INST 2 @ Get next inst, but don't advance rPC
- bl MterpSPutU8
- cmp r0, #0 @ 0 on success, -1 on failure
- bne MterpException
- ADVANCE 2 @ Past exception point - now advance rPC
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip @ jump to next instruction
+ .extern MterpSPutU8
+ mov r0, rPC @ arg0: Instruction* inst
+ mov r1, rINST @ arg1: uint16_t inst_data
+ add r2, rFP, #OFF_FP_SHADOWFRAME @ arg2: ShadowFrame* sf
+ mov r3, rSELF @ arg3: Thread* self
+ PREFETCH_INST 2 @ prefetch next opcode
+ bl MterpSPutU8
+ cmp r0, #0
+ beq MterpPossibleException
+ ADVANCE 2
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ GOTO_OPCODE ip @ jump to next instruction
+
/* ------------------------------ */
@@ -2953,25 +2839,23 @@
.L_op_sput_byte: /* 0x6b */
/* File: arm/op_sput_byte.S */
/* File: arm/op_sput.S */
+/* File: arm/field.S */
/*
- * General SPUT handler wrapper.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- /* op vAA, field@BBBB */
- EXPORT_PC
- FETCH r0, 1 @ r0<- field ref BBBB
- mov r3, rINST, lsr #8 @ r3<- AA
- GET_VREG r1, r3 @ r1<= fp[AA]
- ldr r2, [rFP, #OFF_FP_METHOD]
- mov r3, rSELF
- PREFETCH_INST 2 @ Get next inst, but don't advance rPC
- bl MterpSPutI8
- cmp r0, #0 @ 0 on success, -1 on failure
- bne MterpException
- ADVANCE 2 @ Past exception point - now advance rPC
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip @ jump to next instruction
+ .extern MterpSPutI8
+ mov r0, rPC @ arg0: Instruction* inst
+ mov r1, rINST @ arg1: uint16_t inst_data
+ add r2, rFP, #OFF_FP_SHADOWFRAME @ arg2: ShadowFrame* sf
+ mov r3, rSELF @ arg3: Thread* self
+ PREFETCH_INST 2 @ prefetch next opcode
+ bl MterpSPutI8
+ cmp r0, #0
+ beq MterpPossibleException
+ ADVANCE 2
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ GOTO_OPCODE ip @ jump to next instruction
+
/* ------------------------------ */
@@ -2979,25 +2863,23 @@
.L_op_sput_char: /* 0x6c */
/* File: arm/op_sput_char.S */
/* File: arm/op_sput.S */
+/* File: arm/field.S */
/*
- * General SPUT handler wrapper.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- /* op vAA, field@BBBB */
- EXPORT_PC
- FETCH r0, 1 @ r0<- field ref BBBB
- mov r3, rINST, lsr #8 @ r3<- AA
- GET_VREG r1, r3 @ r1<= fp[AA]
- ldr r2, [rFP, #OFF_FP_METHOD]
- mov r3, rSELF
- PREFETCH_INST 2 @ Get next inst, but don't advance rPC
- bl MterpSPutU16
- cmp r0, #0 @ 0 on success, -1 on failure
- bne MterpException
- ADVANCE 2 @ Past exception point - now advance rPC
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip @ jump to next instruction
+ .extern MterpSPutU16
+ mov r0, rPC @ arg0: Instruction* inst
+ mov r1, rINST @ arg1: uint16_t inst_data
+ add r2, rFP, #OFF_FP_SHADOWFRAME @ arg2: ShadowFrame* sf
+ mov r3, rSELF @ arg3: Thread* self
+ PREFETCH_INST 2 @ prefetch next opcode
+ bl MterpSPutU16
+ cmp r0, #0
+ beq MterpPossibleException
+ ADVANCE 2
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ GOTO_OPCODE ip @ jump to next instruction
+
/* ------------------------------ */
@@ -3005,25 +2887,23 @@
.L_op_sput_short: /* 0x6d */
/* File: arm/op_sput_short.S */
/* File: arm/op_sput.S */
+/* File: arm/field.S */
/*
- * General SPUT handler wrapper.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- /* op vAA, field@BBBB */
- EXPORT_PC
- FETCH r0, 1 @ r0<- field ref BBBB
- mov r3, rINST, lsr #8 @ r3<- AA
- GET_VREG r1, r3 @ r1<= fp[AA]
- ldr r2, [rFP, #OFF_FP_METHOD]
- mov r3, rSELF
- PREFETCH_INST 2 @ Get next inst, but don't advance rPC
- bl MterpSPutI16
- cmp r0, #0 @ 0 on success, -1 on failure
- bne MterpException
- ADVANCE 2 @ Past exception point - now advance rPC
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip @ jump to next instruction
+ .extern MterpSPutI16
+ mov r0, rPC @ arg0: Instruction* inst
+ mov r1, rINST @ arg1: uint16_t inst_data
+ add r2, rFP, #OFF_FP_SHADOWFRAME @ arg2: ShadowFrame* sf
+ mov r3, rSELF @ arg3: Thread* self
+ PREFETCH_INST 2 @ prefetch next opcode
+ bl MterpSPutI16
+ cmp r0, #0
+ beq MterpPossibleException
+ ADVANCE 2
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ GOTO_OPCODE ip @ jump to next instruction
+
/* ------------------------------ */
diff --git a/runtime/interpreter/mterp/out/mterp_arm64.S b/runtime/interpreter/mterp/out/mterp_arm64.S
index 5f4aa4f..fd60c95 100644
--- a/runtime/interpreter/mterp/out/mterp_arm64.S
+++ b/runtime/interpreter/mterp/out/mterp_arm64.S
@@ -2183,213 +2183,177 @@
.balign 128
.L_op_iget: /* 0x52 */
/* File: arm64/op_iget.S */
+/* File: arm64/field.S */
/*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- EXPORT_PC
- FETCH w0, 1 // w0<- field ref CCCC
- lsr w1, wINST, #12 // w1<- B
- GET_VREG w1, w1 // w1<- fp[B], the object pointer
- ldr x2, [xFP, #OFF_FP_METHOD] // w2<- referrer
- mov x3, xSELF // w3<- self
+ .extern MterpIGetU32
+ mov x0, xPC // arg0: Instruction* inst
+ mov x1, xINST // arg1: uint16_t inst_data
+ add x2, xFP, #OFF_FP_SHADOWFRAME // arg2: ShadowFrame* sf
+ mov x3, xSELF // arg3: Thread* self
+ PREFETCH_INST 2 // prefetch next opcode
bl MterpIGetU32
- ldr x3, [xSELF, #THREAD_EXCEPTION_OFFSET]
-
- ubfx w2, wINST, #8, #4 // w2<- A
- PREFETCH_INST 2
- cbnz x3, MterpPossibleException // bail out
- .if 0
- SET_VREG_OBJECT w0, w2 // fp[A]<- w0
- .else
- SET_VREG w0, w2 // fp[A]<- w0
- .endif
+ cbz x0, MterpPossibleException
ADVANCE 2
GET_INST_OPCODE ip // extract opcode from rINST
GOTO_OPCODE ip // jump to next instruction
+
/* ------------------------------ */
.balign 128
.L_op_iget_wide: /* 0x53 */
/* File: arm64/op_iget_wide.S */
+/* File: arm64/op_iget.S */
+/* File: arm64/field.S */
/*
- * 64-bit instance field get.
- *
- * for: iget-wide
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- EXPORT_PC
- FETCH w0, 1 // w0<- field ref CCCC
- lsr w1, wINST, #12 // w1<- B
- GET_VREG w1, w1 // w1<- fp[B], the object pointer
- ldr x2, [xFP, #OFF_FP_METHOD] // w2<- referrer
- mov x3, xSELF // w3<- self
+ .extern MterpIGetU64
+ mov x0, xPC // arg0: Instruction* inst
+ mov x1, xINST // arg1: uint16_t inst_data
+ add x2, xFP, #OFF_FP_SHADOWFRAME // arg2: ShadowFrame* sf
+ mov x3, xSELF // arg3: Thread* self
+ PREFETCH_INST 2 // prefetch next opcode
bl MterpIGetU64
- ldr x3, [xSELF, #THREAD_EXCEPTION_OFFSET]
- ubfx w2, wINST, #8, #4 // w2<- A
- PREFETCH_INST 2
- cmp w3, #0
- cbnz w3, MterpException // bail out
- SET_VREG_WIDE x0, w2
+ cbz x0, MterpPossibleException
ADVANCE 2
- GET_INST_OPCODE ip // extract opcode from wINST
+ GET_INST_OPCODE ip // extract opcode from rINST
GOTO_OPCODE ip // jump to next instruction
+
+
/* ------------------------------ */
.balign 128
.L_op_iget_object: /* 0x54 */
/* File: arm64/op_iget_object.S */
/* File: arm64/op_iget.S */
+/* File: arm64/field.S */
/*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- EXPORT_PC
- FETCH w0, 1 // w0<- field ref CCCC
- lsr w1, wINST, #12 // w1<- B
- GET_VREG w1, w1 // w1<- fp[B], the object pointer
- ldr x2, [xFP, #OFF_FP_METHOD] // w2<- referrer
- mov x3, xSELF // w3<- self
+ .extern MterpIGetObj
+ mov x0, xPC // arg0: Instruction* inst
+ mov x1, xINST // arg1: uint16_t inst_data
+ add x2, xFP, #OFF_FP_SHADOWFRAME // arg2: ShadowFrame* sf
+ mov x3, xSELF // arg3: Thread* self
+ PREFETCH_INST 2 // prefetch next opcode
bl MterpIGetObj
- ldr x3, [xSELF, #THREAD_EXCEPTION_OFFSET]
-
- ubfx w2, wINST, #8, #4 // w2<- A
- PREFETCH_INST 2
- cbnz x3, MterpPossibleException // bail out
- .if 1
- SET_VREG_OBJECT w0, w2 // fp[A]<- w0
- .else
- SET_VREG w0, w2 // fp[A]<- w0
- .endif
+ cbz x0, MterpPossibleException
ADVANCE 2
GET_INST_OPCODE ip // extract opcode from rINST
GOTO_OPCODE ip // jump to next instruction
+
/* ------------------------------ */
.balign 128
.L_op_iget_boolean: /* 0x55 */
/* File: arm64/op_iget_boolean.S */
/* File: arm64/op_iget.S */
+/* File: arm64/field.S */
/*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- EXPORT_PC
- FETCH w0, 1 // w0<- field ref CCCC
- lsr w1, wINST, #12 // w1<- B
- GET_VREG w1, w1 // w1<- fp[B], the object pointer
- ldr x2, [xFP, #OFF_FP_METHOD] // w2<- referrer
- mov x3, xSELF // w3<- self
+ .extern MterpIGetU8
+ mov x0, xPC // arg0: Instruction* inst
+ mov x1, xINST // arg1: uint16_t inst_data
+ add x2, xFP, #OFF_FP_SHADOWFRAME // arg2: ShadowFrame* sf
+ mov x3, xSELF // arg3: Thread* self
+ PREFETCH_INST 2 // prefetch next opcode
bl MterpIGetU8
- ldr x3, [xSELF, #THREAD_EXCEPTION_OFFSET]
- uxtb w0, w0
- ubfx w2, wINST, #8, #4 // w2<- A
- PREFETCH_INST 2
- cbnz x3, MterpPossibleException // bail out
- .if 0
- SET_VREG_OBJECT w0, w2 // fp[A]<- w0
- .else
- SET_VREG w0, w2 // fp[A]<- w0
- .endif
+ cbz x0, MterpPossibleException
ADVANCE 2
GET_INST_OPCODE ip // extract opcode from rINST
GOTO_OPCODE ip // jump to next instruction
+
/* ------------------------------ */
.balign 128
.L_op_iget_byte: /* 0x56 */
/* File: arm64/op_iget_byte.S */
/* File: arm64/op_iget.S */
+/* File: arm64/field.S */
/*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- EXPORT_PC
- FETCH w0, 1 // w0<- field ref CCCC
- lsr w1, wINST, #12 // w1<- B
- GET_VREG w1, w1 // w1<- fp[B], the object pointer
- ldr x2, [xFP, #OFF_FP_METHOD] // w2<- referrer
- mov x3, xSELF // w3<- self
+ .extern MterpIGetI8
+ mov x0, xPC // arg0: Instruction* inst
+ mov x1, xINST // arg1: uint16_t inst_data
+ add x2, xFP, #OFF_FP_SHADOWFRAME // arg2: ShadowFrame* sf
+ mov x3, xSELF // arg3: Thread* self
+ PREFETCH_INST 2 // prefetch next opcode
bl MterpIGetI8
- ldr x3, [xSELF, #THREAD_EXCEPTION_OFFSET]
- sxtb w0, w0
- ubfx w2, wINST, #8, #4 // w2<- A
- PREFETCH_INST 2
- cbnz x3, MterpPossibleException // bail out
- .if 0
- SET_VREG_OBJECT w0, w2 // fp[A]<- w0
- .else
- SET_VREG w0, w2 // fp[A]<- w0
- .endif
+ cbz x0, MterpPossibleException
ADVANCE 2
GET_INST_OPCODE ip // extract opcode from rINST
GOTO_OPCODE ip // jump to next instruction
+
/* ------------------------------ */
.balign 128
.L_op_iget_char: /* 0x57 */
/* File: arm64/op_iget_char.S */
/* File: arm64/op_iget.S */
+/* File: arm64/field.S */
/*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- EXPORT_PC
- FETCH w0, 1 // w0<- field ref CCCC
- lsr w1, wINST, #12 // w1<- B
- GET_VREG w1, w1 // w1<- fp[B], the object pointer
- ldr x2, [xFP, #OFF_FP_METHOD] // w2<- referrer
- mov x3, xSELF // w3<- self
+ .extern MterpIGetU16
+ mov x0, xPC // arg0: Instruction* inst
+ mov x1, xINST // arg1: uint16_t inst_data
+ add x2, xFP, #OFF_FP_SHADOWFRAME // arg2: ShadowFrame* sf
+ mov x3, xSELF // arg3: Thread* self
+ PREFETCH_INST 2 // prefetch next opcode
bl MterpIGetU16
- ldr x3, [xSELF, #THREAD_EXCEPTION_OFFSET]
- uxth w0, w0
- ubfx w2, wINST, #8, #4 // w2<- A
- PREFETCH_INST 2
- cbnz x3, MterpPossibleException // bail out
- .if 0
- SET_VREG_OBJECT w0, w2 // fp[A]<- w0
- .else
- SET_VREG w0, w2 // fp[A]<- w0
- .endif
+ cbz x0, MterpPossibleException
ADVANCE 2
GET_INST_OPCODE ip // extract opcode from rINST
GOTO_OPCODE ip // jump to next instruction
+
/* ------------------------------ */
.balign 128
.L_op_iget_short: /* 0x58 */
/* File: arm64/op_iget_short.S */
/* File: arm64/op_iget.S */
+/* File: arm64/field.S */
/*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- EXPORT_PC
- FETCH w0, 1 // w0<- field ref CCCC
- lsr w1, wINST, #12 // w1<- B
- GET_VREG w1, w1 // w1<- fp[B], the object pointer
- ldr x2, [xFP, #OFF_FP_METHOD] // w2<- referrer
- mov x3, xSELF // w3<- self
+ .extern MterpIGetI16
+ mov x0, xPC // arg0: Instruction* inst
+ mov x1, xINST // arg1: uint16_t inst_data
+ add x2, xFP, #OFF_FP_SHADOWFRAME // arg2: ShadowFrame* sf
+ mov x3, xSELF // arg3: Thread* self
+ PREFETCH_INST 2 // prefetch next opcode
bl MterpIGetI16
- ldr x3, [xSELF, #THREAD_EXCEPTION_OFFSET]
- sxth w0, w0
- ubfx w2, wINST, #8, #4 // w2<- A
- PREFETCH_INST 2
- cbnz x3, MterpPossibleException // bail out
- .if 0
- SET_VREG_OBJECT w0, w2 // fp[A]<- w0
- .else
- SET_VREG w0, w2 // fp[A]<- w0
- .endif
+ cbz x0, MterpPossibleException
+ ADVANCE 2
+ GET_INST_OPCODE ip // extract opcode from rINST
+ GOTO_OPCODE ip // jump to next instruction
+
+
+
+/* ------------------------------ */
+ .balign 128
+.L_op_iput: /* 0x59 */
+/* File: arm64/op_iput.S */
+/* File: arm64/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
+ .extern MterpIPutU32
+ mov x0, xPC // arg0: Instruction* inst
+ mov x1, xINST // arg1: uint16_t inst_data
+ add x2, xFP, #OFF_FP_SHADOWFRAME // arg2: ShadowFrame* sf
+ mov x3, xSELF // arg3: Thread* self
+ PREFETCH_INST 2 // prefetch next opcode
+ bl MterpIPutU32
+ cbz x0, MterpPossibleException
ADVANCE 2
GET_INST_OPCODE ip // extract opcode from rINST
GOTO_OPCODE ip // jump to next instruction
@@ -2397,89 +2361,71 @@
/* ------------------------------ */
.balign 128
-.L_op_iput: /* 0x59 */
-/* File: arm64/op_iput.S */
- /*
- * General 32-bit instance field put.
- *
- * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
- */
- /* op vA, vB, field//CCCC */
- .extern MterpIPutU32
- EXPORT_PC
- FETCH w0, 1 // w0<- field ref CCCC
- lsr w1, wINST, #12 // w1<- B
- GET_VREG w1, w1 // w1<- fp[B], the object pointer
- ubfx w2, wINST, #8, #4 // w2<- A
- GET_VREG w2, w2 // w2<- fp[A]
- ldr x3, [xFP, #OFF_FP_METHOD] // w3<- referrer
- PREFETCH_INST 2
- bl MterpIPutU32
- cbnz w0, MterpPossibleException
- ADVANCE 2 // advance rPC
- GET_INST_OPCODE ip // extract opcode from rINST
- GOTO_OPCODE ip // jump to next instruction
-
-/* ------------------------------ */
- .balign 128
.L_op_iput_wide: /* 0x5a */
/* File: arm64/op_iput_wide.S */
- /* iput-wide vA, vB, field//CCCC */
+/* File: arm64/op_iput.S */
+/* File: arm64/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpIPutU64
- EXPORT_PC
- FETCH w0, 1 // w0<- field ref CCCC
- lsr w1, wINST, #12 // w1<- B
- GET_VREG w1, w1 // w1<- fp[B], the object pointer
- ubfx w2, wINST, #8, #4 // w2<- A
- VREG_INDEX_TO_ADDR x2, x2 // w2<- &fp[A]
- ldr x3, [xFP, #OFF_FP_METHOD] // w3<- referrer
- PREFETCH_INST 2
+ mov x0, xPC // arg0: Instruction* inst
+ mov x1, xINST // arg1: uint16_t inst_data
+ add x2, xFP, #OFF_FP_SHADOWFRAME // arg2: ShadowFrame* sf
+ mov x3, xSELF // arg3: Thread* self
+ PREFETCH_INST 2 // prefetch next opcode
bl MterpIPutU64
- cbnz w0, MterpPossibleException
- ADVANCE 2 // advance rPC
- GET_INST_OPCODE ip // extract opcode from wINST
- GOTO_OPCODE ip // jump to next instruction
+ cbz x0, MterpPossibleException
+ ADVANCE 2
+ GET_INST_OPCODE ip // extract opcode from rINST
+ GOTO_OPCODE ip // jump to next instruction
+
+
/* ------------------------------ */
.balign 128
.L_op_iput_object: /* 0x5b */
/* File: arm64/op_iput_object.S */
- EXPORT_PC
- add x0, xFP, #OFF_FP_SHADOWFRAME
- mov x1, xPC
- mov w2, wINST
- mov x3, xSELF
- bl MterpIPutObj
- cbz w0, MterpException
- FETCH_ADVANCE_INST 2 // advance rPC, load rINST
- GET_INST_OPCODE ip // extract opcode from rINST
- GOTO_OPCODE ip // jump to next instruction
+/* File: arm64/op_iput.S */
+/* File: arm64/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
+ .extern MterpIPutObj
+ mov x0, xPC // arg0: Instruction* inst
+ mov x1, xINST // arg1: uint16_t inst_data
+ add x2, xFP, #OFF_FP_SHADOWFRAME // arg2: ShadowFrame* sf
+ mov x3, xSELF // arg3: Thread* self
+ PREFETCH_INST 2 // prefetch next opcode
+ bl MterpIPutObj
+ cbz x0, MterpPossibleException
+ ADVANCE 2
+ GET_INST_OPCODE ip // extract opcode from rINST
+ GOTO_OPCODE ip // jump to next instruction
+
+
/* ------------------------------ */
.balign 128
.L_op_iput_boolean: /* 0x5c */
/* File: arm64/op_iput_boolean.S */
/* File: arm64/op_iput.S */
+/* File: arm64/field.S */
/*
- * General 32-bit instance field put.
- *
- * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- /* op vA, vB, field//CCCC */
.extern MterpIPutU8
- EXPORT_PC
- FETCH w0, 1 // w0<- field ref CCCC
- lsr w1, wINST, #12 // w1<- B
- GET_VREG w1, w1 // w1<- fp[B], the object pointer
- ubfx w2, wINST, #8, #4 // w2<- A
- GET_VREG w2, w2 // w2<- fp[A]
- ldr x3, [xFP, #OFF_FP_METHOD] // w3<- referrer
- PREFETCH_INST 2
+ mov x0, xPC // arg0: Instruction* inst
+ mov x1, xINST // arg1: uint16_t inst_data
+ add x2, xFP, #OFF_FP_SHADOWFRAME // arg2: ShadowFrame* sf
+ mov x3, xSELF // arg3: Thread* self
+ PREFETCH_INST 2 // prefetch next opcode
bl MterpIPutU8
- cbnz w0, MterpPossibleException
- ADVANCE 2 // advance rPC
- GET_INST_OPCODE ip // extract opcode from rINST
- GOTO_OPCODE ip // jump to next instruction
+ cbz x0, MterpPossibleException
+ ADVANCE 2
+ GET_INST_OPCODE ip // extract opcode from rINST
+ GOTO_OPCODE ip // jump to next instruction
+
/* ------------------------------ */
@@ -2487,26 +2433,22 @@
.L_op_iput_byte: /* 0x5d */
/* File: arm64/op_iput_byte.S */
/* File: arm64/op_iput.S */
+/* File: arm64/field.S */
/*
- * General 32-bit instance field put.
- *
- * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- /* op vA, vB, field//CCCC */
.extern MterpIPutI8
- EXPORT_PC
- FETCH w0, 1 // w0<- field ref CCCC
- lsr w1, wINST, #12 // w1<- B
- GET_VREG w1, w1 // w1<- fp[B], the object pointer
- ubfx w2, wINST, #8, #4 // w2<- A
- GET_VREG w2, w2 // w2<- fp[A]
- ldr x3, [xFP, #OFF_FP_METHOD] // w3<- referrer
- PREFETCH_INST 2
+ mov x0, xPC // arg0: Instruction* inst
+ mov x1, xINST // arg1: uint16_t inst_data
+ add x2, xFP, #OFF_FP_SHADOWFRAME // arg2: ShadowFrame* sf
+ mov x3, xSELF // arg3: Thread* self
+ PREFETCH_INST 2 // prefetch next opcode
bl MterpIPutI8
- cbnz w0, MterpPossibleException
- ADVANCE 2 // advance rPC
- GET_INST_OPCODE ip // extract opcode from rINST
- GOTO_OPCODE ip // jump to next instruction
+ cbz x0, MterpPossibleException
+ ADVANCE 2
+ GET_INST_OPCODE ip // extract opcode from rINST
+ GOTO_OPCODE ip // jump to next instruction
+
/* ------------------------------ */
@@ -2514,26 +2456,22 @@
.L_op_iput_char: /* 0x5e */
/* File: arm64/op_iput_char.S */
/* File: arm64/op_iput.S */
+/* File: arm64/field.S */
/*
- * General 32-bit instance field put.
- *
- * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- /* op vA, vB, field//CCCC */
.extern MterpIPutU16
- EXPORT_PC
- FETCH w0, 1 // w0<- field ref CCCC
- lsr w1, wINST, #12 // w1<- B
- GET_VREG w1, w1 // w1<- fp[B], the object pointer
- ubfx w2, wINST, #8, #4 // w2<- A
- GET_VREG w2, w2 // w2<- fp[A]
- ldr x3, [xFP, #OFF_FP_METHOD] // w3<- referrer
- PREFETCH_INST 2
+ mov x0, xPC // arg0: Instruction* inst
+ mov x1, xINST // arg1: uint16_t inst_data
+ add x2, xFP, #OFF_FP_SHADOWFRAME // arg2: ShadowFrame* sf
+ mov x3, xSELF // arg3: Thread* self
+ PREFETCH_INST 2 // prefetch next opcode
bl MterpIPutU16
- cbnz w0, MterpPossibleException
- ADVANCE 2 // advance rPC
- GET_INST_OPCODE ip // extract opcode from rINST
- GOTO_OPCODE ip // jump to next instruction
+ cbz x0, MterpPossibleException
+ ADVANCE 2
+ GET_INST_OPCODE ip // extract opcode from rINST
+ GOTO_OPCODE ip // jump to next instruction
+
/* ------------------------------ */
@@ -2541,114 +2479,89 @@
.L_op_iput_short: /* 0x5f */
/* File: arm64/op_iput_short.S */
/* File: arm64/op_iput.S */
+/* File: arm64/field.S */
/*
- * General 32-bit instance field put.
- *
- * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- /* op vA, vB, field//CCCC */
.extern MterpIPutI16
- EXPORT_PC
- FETCH w0, 1 // w0<- field ref CCCC
- lsr w1, wINST, #12 // w1<- B
- GET_VREG w1, w1 // w1<- fp[B], the object pointer
- ubfx w2, wINST, #8, #4 // w2<- A
- GET_VREG w2, w2 // w2<- fp[A]
- ldr x3, [xFP, #OFF_FP_METHOD] // w3<- referrer
- PREFETCH_INST 2
+ mov x0, xPC // arg0: Instruction* inst
+ mov x1, xINST // arg1: uint16_t inst_data
+ add x2, xFP, #OFF_FP_SHADOWFRAME // arg2: ShadowFrame* sf
+ mov x3, xSELF // arg3: Thread* self
+ PREFETCH_INST 2 // prefetch next opcode
bl MterpIPutI16
- cbnz w0, MterpPossibleException
- ADVANCE 2 // advance rPC
- GET_INST_OPCODE ip // extract opcode from rINST
- GOTO_OPCODE ip // jump to next instruction
+ cbz x0, MterpPossibleException
+ ADVANCE 2
+ GET_INST_OPCODE ip // extract opcode from rINST
+ GOTO_OPCODE ip // jump to next instruction
+
/* ------------------------------ */
.balign 128
.L_op_sget: /* 0x60 */
/* File: arm64/op_sget.S */
+/* File: arm64/field.S */
/*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- /* op vAA, field//BBBB */
-
.extern MterpSGetU32
- EXPORT_PC
- FETCH w0, 1 // w0<- field ref BBBB
- ldr x1, [xFP, #OFF_FP_METHOD]
- mov x2, xSELF
- bl MterpSGetU32
- ldr x3, [xSELF, #THREAD_EXCEPTION_OFFSET]
- lsr w2, wINST, #8 // w2<- AA
-
- PREFETCH_INST 2
- cbnz x3, MterpException // bail out
-.if 0
- SET_VREG_OBJECT w0, w2 // fp[AA]<- w0
-.else
- SET_VREG w0, w2 // fp[AA]<- w0
-.endif
+ mov x0, xPC // arg0: Instruction* inst
+ mov x1, xINST // arg1: uint16_t inst_data
+ add x2, xFP, #OFF_FP_SHADOWFRAME // arg2: ShadowFrame* sf
+ mov x3, xSELF // arg3: Thread* self
+ PREFETCH_INST 2 // prefetch next opcode
+ bl MterpSGetU32
+ cbz x0, MterpPossibleException
ADVANCE 2
- GET_INST_OPCODE ip // extract opcode from rINST
- GOTO_OPCODE ip
+ GET_INST_OPCODE ip // extract opcode from rINST
+ GOTO_OPCODE ip // jump to next instruction
+
/* ------------------------------ */
.balign 128
.L_op_sget_wide: /* 0x61 */
/* File: arm64/op_sget_wide.S */
+/* File: arm64/op_sget.S */
+/* File: arm64/field.S */
/*
- * SGET_WIDE handler wrapper.
- *
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- /* sget-wide vAA, field//BBBB */
+ .extern MterpSGetU64
+ mov x0, xPC // arg0: Instruction* inst
+ mov x1, xINST // arg1: uint16_t inst_data
+ add x2, xFP, #OFF_FP_SHADOWFRAME // arg2: ShadowFrame* sf
+ mov x3, xSELF // arg3: Thread* self
+ PREFETCH_INST 2 // prefetch next opcode
+ bl MterpSGetU64
+ cbz x0, MterpPossibleException
+ ADVANCE 2
+ GET_INST_OPCODE ip // extract opcode from rINST
+ GOTO_OPCODE ip // jump to next instruction
- .extern MterpGet64StaticFromCode
- EXPORT_PC
- FETCH w0, 1 // w0<- field ref BBBB
- ldr x1, [xFP, #OFF_FP_METHOD]
- mov x2, xSELF
- bl MterpSGetU64
- ldr x3, [xSELF, #THREAD_EXCEPTION_OFFSET]
- lsr w4, wINST, #8 // w4<- AA
- cbnz x3, MterpException // bail out
- FETCH_ADVANCE_INST 2 // advance rPC, load wINST
- SET_VREG_WIDE x0, w4
- GET_INST_OPCODE ip // extract opcode from wINST
- GOTO_OPCODE ip // jump to next instruction
+
/* ------------------------------ */
.balign 128
.L_op_sget_object: /* 0x62 */
/* File: arm64/op_sget_object.S */
/* File: arm64/op_sget.S */
+/* File: arm64/field.S */
/*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- /* op vAA, field//BBBB */
-
.extern MterpSGetObj
- EXPORT_PC
- FETCH w0, 1 // w0<- field ref BBBB
- ldr x1, [xFP, #OFF_FP_METHOD]
- mov x2, xSELF
- bl MterpSGetObj
- ldr x3, [xSELF, #THREAD_EXCEPTION_OFFSET]
- lsr w2, wINST, #8 // w2<- AA
-
- PREFETCH_INST 2
- cbnz x3, MterpException // bail out
-.if 1
- SET_VREG_OBJECT w0, w2 // fp[AA]<- w0
-.else
- SET_VREG w0, w2 // fp[AA]<- w0
-.endif
+ mov x0, xPC // arg0: Instruction* inst
+ mov x1, xINST // arg1: uint16_t inst_data
+ add x2, xFP, #OFF_FP_SHADOWFRAME // arg2: ShadowFrame* sf
+ mov x3, xSELF // arg3: Thread* self
+ PREFETCH_INST 2 // prefetch next opcode
+ bl MterpSGetObj
+ cbz x0, MterpPossibleException
ADVANCE 2
- GET_INST_OPCODE ip // extract opcode from rINST
- GOTO_OPCODE ip
+ GET_INST_OPCODE ip // extract opcode from rINST
+ GOTO_OPCODE ip // jump to next instruction
+
/* ------------------------------ */
@@ -2656,32 +2569,22 @@
.L_op_sget_boolean: /* 0x63 */
/* File: arm64/op_sget_boolean.S */
/* File: arm64/op_sget.S */
+/* File: arm64/field.S */
/*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- /* op vAA, field//BBBB */
-
.extern MterpSGetU8
- EXPORT_PC
- FETCH w0, 1 // w0<- field ref BBBB
- ldr x1, [xFP, #OFF_FP_METHOD]
- mov x2, xSELF
- bl MterpSGetU8
- ldr x3, [xSELF, #THREAD_EXCEPTION_OFFSET]
- lsr w2, wINST, #8 // w2<- AA
- uxtb w0, w0
- PREFETCH_INST 2
- cbnz x3, MterpException // bail out
-.if 0
- SET_VREG_OBJECT w0, w2 // fp[AA]<- w0
-.else
- SET_VREG w0, w2 // fp[AA]<- w0
-.endif
+ mov x0, xPC // arg0: Instruction* inst
+ mov x1, xINST // arg1: uint16_t inst_data
+ add x2, xFP, #OFF_FP_SHADOWFRAME // arg2: ShadowFrame* sf
+ mov x3, xSELF // arg3: Thread* self
+ PREFETCH_INST 2 // prefetch next opcode
+ bl MterpSGetU8
+ cbz x0, MterpPossibleException
ADVANCE 2
- GET_INST_OPCODE ip // extract opcode from rINST
- GOTO_OPCODE ip
+ GET_INST_OPCODE ip // extract opcode from rINST
+ GOTO_OPCODE ip // jump to next instruction
+
/* ------------------------------ */
@@ -2689,32 +2592,22 @@
.L_op_sget_byte: /* 0x64 */
/* File: arm64/op_sget_byte.S */
/* File: arm64/op_sget.S */
+/* File: arm64/field.S */
/*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- /* op vAA, field//BBBB */
-
.extern MterpSGetI8
- EXPORT_PC
- FETCH w0, 1 // w0<- field ref BBBB
- ldr x1, [xFP, #OFF_FP_METHOD]
- mov x2, xSELF
- bl MterpSGetI8
- ldr x3, [xSELF, #THREAD_EXCEPTION_OFFSET]
- lsr w2, wINST, #8 // w2<- AA
- sxtb w0, w0
- PREFETCH_INST 2
- cbnz x3, MterpException // bail out
-.if 0
- SET_VREG_OBJECT w0, w2 // fp[AA]<- w0
-.else
- SET_VREG w0, w2 // fp[AA]<- w0
-.endif
+ mov x0, xPC // arg0: Instruction* inst
+ mov x1, xINST // arg1: uint16_t inst_data
+ add x2, xFP, #OFF_FP_SHADOWFRAME // arg2: ShadowFrame* sf
+ mov x3, xSELF // arg3: Thread* self
+ PREFETCH_INST 2 // prefetch next opcode
+ bl MterpSGetI8
+ cbz x0, MterpPossibleException
ADVANCE 2
- GET_INST_OPCODE ip // extract opcode from rINST
- GOTO_OPCODE ip
+ GET_INST_OPCODE ip // extract opcode from rINST
+ GOTO_OPCODE ip // jump to next instruction
+
/* ------------------------------ */
@@ -2722,32 +2615,22 @@
.L_op_sget_char: /* 0x65 */
/* File: arm64/op_sget_char.S */
/* File: arm64/op_sget.S */
+/* File: arm64/field.S */
/*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- /* op vAA, field//BBBB */
-
.extern MterpSGetU16
- EXPORT_PC
- FETCH w0, 1 // w0<- field ref BBBB
- ldr x1, [xFP, #OFF_FP_METHOD]
- mov x2, xSELF
- bl MterpSGetU16
- ldr x3, [xSELF, #THREAD_EXCEPTION_OFFSET]
- lsr w2, wINST, #8 // w2<- AA
- uxth w0, w0
- PREFETCH_INST 2
- cbnz x3, MterpException // bail out
-.if 0
- SET_VREG_OBJECT w0, w2 // fp[AA]<- w0
-.else
- SET_VREG w0, w2 // fp[AA]<- w0
-.endif
+ mov x0, xPC // arg0: Instruction* inst
+ mov x1, xINST // arg1: uint16_t inst_data
+ add x2, xFP, #OFF_FP_SHADOWFRAME // arg2: ShadowFrame* sf
+ mov x3, xSELF // arg3: Thread* self
+ PREFETCH_INST 2 // prefetch next opcode
+ bl MterpSGetU16
+ cbz x0, MterpPossibleException
ADVANCE 2
- GET_INST_OPCODE ip // extract opcode from rINST
- GOTO_OPCODE ip
+ GET_INST_OPCODE ip // extract opcode from rINST
+ GOTO_OPCODE ip // jump to next instruction
+
/* ------------------------------ */
@@ -2755,118 +2638,112 @@
.L_op_sget_short: /* 0x66 */
/* File: arm64/op_sget_short.S */
/* File: arm64/op_sget.S */
+/* File: arm64/field.S */
/*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- /* op vAA, field//BBBB */
-
.extern MterpSGetI16
- EXPORT_PC
- FETCH w0, 1 // w0<- field ref BBBB
- ldr x1, [xFP, #OFF_FP_METHOD]
- mov x2, xSELF
- bl MterpSGetI16
- ldr x3, [xSELF, #THREAD_EXCEPTION_OFFSET]
- lsr w2, wINST, #8 // w2<- AA
- sxth w0, w0
- PREFETCH_INST 2
- cbnz x3, MterpException // bail out
-.if 0
- SET_VREG_OBJECT w0, w2 // fp[AA]<- w0
-.else
- SET_VREG w0, w2 // fp[AA]<- w0
-.endif
+ mov x0, xPC // arg0: Instruction* inst
+ mov x1, xINST // arg1: uint16_t inst_data
+ add x2, xFP, #OFF_FP_SHADOWFRAME // arg2: ShadowFrame* sf
+ mov x3, xSELF // arg3: Thread* self
+ PREFETCH_INST 2 // prefetch next opcode
+ bl MterpSGetI16
+ cbz x0, MterpPossibleException
ADVANCE 2
- GET_INST_OPCODE ip // extract opcode from rINST
- GOTO_OPCODE ip
+ GET_INST_OPCODE ip // extract opcode from rINST
+ GOTO_OPCODE ip // jump to next instruction
+
/* ------------------------------ */
.balign 128
.L_op_sput: /* 0x67 */
/* File: arm64/op_sput.S */
+/* File: arm64/field.S */
/*
- * General SPUT handler wrapper.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- /* op vAA, field//BBBB */
- EXPORT_PC
- FETCH w0, 1 // r0<- field ref BBBB
- lsr w3, wINST, #8 // r3<- AA
- GET_VREG w1, w3 // r1<= fp[AA]
- ldr x2, [xFP, #OFF_FP_METHOD]
- mov x3, xSELF
- PREFETCH_INST 2 // Get next inst, but don't advance rPC
- bl MterpSPutU32
- cbnz w0, MterpException // 0 on success
- ADVANCE 2 // Past exception point - now advance rPC
- GET_INST_OPCODE ip // extract opcode from rINST
- GOTO_OPCODE ip // jump to next instruction
+ .extern MterpSPutU32
+ mov x0, xPC // arg0: Instruction* inst
+ mov x1, xINST // arg1: uint16_t inst_data
+ add x2, xFP, #OFF_FP_SHADOWFRAME // arg2: ShadowFrame* sf
+ mov x3, xSELF // arg3: Thread* self
+ PREFETCH_INST 2 // prefetch next opcode
+ bl MterpSPutU32
+ cbz x0, MterpPossibleException
+ ADVANCE 2
+ GET_INST_OPCODE ip // extract opcode from rINST
+ GOTO_OPCODE ip // jump to next instruction
+
/* ------------------------------ */
.balign 128
.L_op_sput_wide: /* 0x68 */
/* File: arm64/op_sput_wide.S */
+/* File: arm64/op_sput.S */
+/* File: arm64/field.S */
/*
- * SPUT_WIDE handler wrapper.
- *
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- /* sput-wide vAA, field//BBBB */
.extern MterpSPutU64
- EXPORT_PC
- FETCH w0, 1 // w0<- field ref BBBB
- lsr w1, wINST, #8 // w1<- AA
- VREG_INDEX_TO_ADDR x1, w1
- ldr x2, [xFP, #OFF_FP_METHOD]
- mov x3, xSELF
- PREFETCH_INST 2 // Get next inst, but don't advance rPC
- bl MterpSPutU64
- cbnz w0, MterpException // 0 on success, -1 on failure
- ADVANCE 2 // Past exception point - now advance rPC
- GET_INST_OPCODE ip // extract opcode from wINST
- GOTO_OPCODE ip // jump to next instruction
+ mov x0, xPC // arg0: Instruction* inst
+ mov x1, xINST // arg1: uint16_t inst_data
+ add x2, xFP, #OFF_FP_SHADOWFRAME // arg2: ShadowFrame* sf
+ mov x3, xSELF // arg3: Thread* self
+ PREFETCH_INST 2 // prefetch next opcode
+ bl MterpSPutU64
+ cbz x0, MterpPossibleException
+ ADVANCE 2
+ GET_INST_OPCODE ip // extract opcode from rINST
+ GOTO_OPCODE ip // jump to next instruction
+
+
/* ------------------------------ */
.balign 128
.L_op_sput_object: /* 0x69 */
/* File: arm64/op_sput_object.S */
- EXPORT_PC
- add x0, xFP, #OFF_FP_SHADOWFRAME
- mov x1, xPC
- mov x2, xINST
- mov x3, xSELF
- bl MterpSPutObj
- cbz w0, MterpException
- FETCH_ADVANCE_INST 2 // advance rPC, load rINST
- GET_INST_OPCODE ip // extract opcode from rINST
- GOTO_OPCODE ip // jump to next instruction
+/* File: arm64/op_sput.S */
+/* File: arm64/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
+ .extern MterpSPutObj
+ mov x0, xPC // arg0: Instruction* inst
+ mov x1, xINST // arg1: uint16_t inst_data
+ add x2, xFP, #OFF_FP_SHADOWFRAME // arg2: ShadowFrame* sf
+ mov x3, xSELF // arg3: Thread* self
+ PREFETCH_INST 2 // prefetch next opcode
+ bl MterpSPutObj
+ cbz x0, MterpPossibleException
+ ADVANCE 2
+ GET_INST_OPCODE ip // extract opcode from rINST
+ GOTO_OPCODE ip // jump to next instruction
+
+
/* ------------------------------ */
.balign 128
.L_op_sput_boolean: /* 0x6a */
/* File: arm64/op_sput_boolean.S */
/* File: arm64/op_sput.S */
+/* File: arm64/field.S */
/*
- * General SPUT handler wrapper.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- /* op vAA, field//BBBB */
- EXPORT_PC
- FETCH w0, 1 // r0<- field ref BBBB
- lsr w3, wINST, #8 // r3<- AA
- GET_VREG w1, w3 // r1<= fp[AA]
- ldr x2, [xFP, #OFF_FP_METHOD]
- mov x3, xSELF
- PREFETCH_INST 2 // Get next inst, but don't advance rPC
- bl MterpSPutU8
- cbnz w0, MterpException // 0 on success
- ADVANCE 2 // Past exception point - now advance rPC
- GET_INST_OPCODE ip // extract opcode from rINST
- GOTO_OPCODE ip // jump to next instruction
+ .extern MterpSPutU8
+ mov x0, xPC // arg0: Instruction* inst
+ mov x1, xINST // arg1: uint16_t inst_data
+ add x2, xFP, #OFF_FP_SHADOWFRAME // arg2: ShadowFrame* sf
+ mov x3, xSELF // arg3: Thread* self
+ PREFETCH_INST 2 // prefetch next opcode
+ bl MterpSPutU8
+ cbz x0, MterpPossibleException
+ ADVANCE 2
+ GET_INST_OPCODE ip // extract opcode from rINST
+ GOTO_OPCODE ip // jump to next instruction
+
/* ------------------------------ */
@@ -2874,24 +2751,22 @@
.L_op_sput_byte: /* 0x6b */
/* File: arm64/op_sput_byte.S */
/* File: arm64/op_sput.S */
+/* File: arm64/field.S */
/*
- * General SPUT handler wrapper.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- /* op vAA, field//BBBB */
- EXPORT_PC
- FETCH w0, 1 // r0<- field ref BBBB
- lsr w3, wINST, #8 // r3<- AA
- GET_VREG w1, w3 // r1<= fp[AA]
- ldr x2, [xFP, #OFF_FP_METHOD]
- mov x3, xSELF
- PREFETCH_INST 2 // Get next inst, but don't advance rPC
- bl MterpSPutI8
- cbnz w0, MterpException // 0 on success
- ADVANCE 2 // Past exception point - now advance rPC
- GET_INST_OPCODE ip // extract opcode from rINST
- GOTO_OPCODE ip // jump to next instruction
+ .extern MterpSPutI8
+ mov x0, xPC // arg0: Instruction* inst
+ mov x1, xINST // arg1: uint16_t inst_data
+ add x2, xFP, #OFF_FP_SHADOWFRAME // arg2: ShadowFrame* sf
+ mov x3, xSELF // arg3: Thread* self
+ PREFETCH_INST 2 // prefetch next opcode
+ bl MterpSPutI8
+ cbz x0, MterpPossibleException
+ ADVANCE 2
+ GET_INST_OPCODE ip // extract opcode from rINST
+ GOTO_OPCODE ip // jump to next instruction
+
/* ------------------------------ */
@@ -2899,24 +2774,22 @@
.L_op_sput_char: /* 0x6c */
/* File: arm64/op_sput_char.S */
/* File: arm64/op_sput.S */
+/* File: arm64/field.S */
/*
- * General SPUT handler wrapper.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- /* op vAA, field//BBBB */
- EXPORT_PC
- FETCH w0, 1 // r0<- field ref BBBB
- lsr w3, wINST, #8 // r3<- AA
- GET_VREG w1, w3 // r1<= fp[AA]
- ldr x2, [xFP, #OFF_FP_METHOD]
- mov x3, xSELF
- PREFETCH_INST 2 // Get next inst, but don't advance rPC
- bl MterpSPutU16
- cbnz w0, MterpException // 0 on success
- ADVANCE 2 // Past exception point - now advance rPC
- GET_INST_OPCODE ip // extract opcode from rINST
- GOTO_OPCODE ip // jump to next instruction
+ .extern MterpSPutU16
+ mov x0, xPC // arg0: Instruction* inst
+ mov x1, xINST // arg1: uint16_t inst_data
+ add x2, xFP, #OFF_FP_SHADOWFRAME // arg2: ShadowFrame* sf
+ mov x3, xSELF // arg3: Thread* self
+ PREFETCH_INST 2 // prefetch next opcode
+ bl MterpSPutU16
+ cbz x0, MterpPossibleException
+ ADVANCE 2
+ GET_INST_OPCODE ip // extract opcode from rINST
+ GOTO_OPCODE ip // jump to next instruction
+
/* ------------------------------ */
@@ -2924,24 +2797,22 @@
.L_op_sput_short: /* 0x6d */
/* File: arm64/op_sput_short.S */
/* File: arm64/op_sput.S */
+/* File: arm64/field.S */
/*
- * General SPUT handler wrapper.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- /* op vAA, field//BBBB */
- EXPORT_PC
- FETCH w0, 1 // r0<- field ref BBBB
- lsr w3, wINST, #8 // r3<- AA
- GET_VREG w1, w3 // r1<= fp[AA]
- ldr x2, [xFP, #OFF_FP_METHOD]
- mov x3, xSELF
- PREFETCH_INST 2 // Get next inst, but don't advance rPC
- bl MterpSPutI16
- cbnz w0, MterpException // 0 on success
- ADVANCE 2 // Past exception point - now advance rPC
- GET_INST_OPCODE ip // extract opcode from rINST
- GOTO_OPCODE ip // jump to next instruction
+ .extern MterpSPutI16
+ mov x0, xPC // arg0: Instruction* inst
+ mov x1, xINST // arg1: uint16_t inst_data
+ add x2, xFP, #OFF_FP_SHADOWFRAME // arg2: ShadowFrame* sf
+ mov x3, xSELF // arg3: Thread* self
+ PREFETCH_INST 2 // prefetch next opcode
+ bl MterpSPutI16
+ cbz x0, MterpPossibleException
+ ADVANCE 2
+ GET_INST_OPCODE ip // extract opcode from rINST
+ GOTO_OPCODE ip // jump to next instruction
+
/* ------------------------------ */
diff --git a/runtime/interpreter/mterp/out/mterp_mips.S b/runtime/interpreter/mterp/out/mterp_mips.S
index fb7d52e..1f5bea0 100644
--- a/runtime/interpreter/mterp/out/mterp_mips.S
+++ b/runtime/interpreter/mterp/out/mterp_mips.S
@@ -2665,85 +2665,28 @@
.balign 128
.L_op_iget: /* 0x52 */
/* File: mips/op_iget.S */
- /*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
- */
- /* op vA, vB, field@CCCC */
- EXPORT_PC()
- FETCH(a0, 1) # a0 <- field ref CCCC
- GET_OPB(a1) # a1 <- B
- GET_VREG(a1, a1) # a1 <- fp[B], the object pointer
- lw a2, OFF_FP_METHOD(rFP) # a2 <- referrer
- move a3, rSELF # a3 <- self
- JAL(MterpIGetU32)
- lw a3, THREAD_EXCEPTION_OFFSET(rSELF)
- GET_OPA4(a2) # a2<- A+
- PREFETCH_INST(2) # load rINST
- bnez a3, MterpPossibleException # bail out
- ADVANCE(2) # advance rPC
- GET_INST_OPCODE(t0) # extract opcode from rINST
- .if 0
- SET_VREG_OBJECT_GOTO(v0, a2, t0) # fp[A] <- v0
- .else
- SET_VREG_GOTO(v0, a2, t0) # fp[A] <- v0
- .endif
+/* File: mips/field.S */
+TODO
+
/* ------------------------------ */
.balign 128
.L_op_iget_wide: /* 0x53 */
/* File: mips/op_iget_wide.S */
- /*
- * 64-bit instance field get.
- *
- * for: iget-wide
- */
- /* op vA, vB, field@CCCC */
- EXPORT_PC()
- FETCH(a0, 1) # a0 <- field byte offset
- GET_OPB(a1) # a1 <- B
- GET_VREG(a1, a1) # a1 <- fp[B], the object pointer
- lw a2, OFF_FP_METHOD(rFP) # a2 <- referrer
- move a3, rSELF # a3 <- self
- JAL(MterpIGetU64)
- lw a3, THREAD_EXCEPTION_OFFSET(rSELF)
- GET_OPA4(a2) # a2<- A+
- PREFETCH_INST(2) # load rINST
- bnez a3, MterpException # bail out
- ADVANCE(2) # advance rPC
- GET_INST_OPCODE(t0) # extract opcode from rINST
- SET_VREG64_GOTO(v0, v1, a2, t0) # fp[A] <- v0/v1
+/* File: mips/op_iget.S */
+/* File: mips/field.S */
+TODO
+
+
/* ------------------------------ */
.balign 128
.L_op_iget_object: /* 0x54 */
/* File: mips/op_iget_object.S */
/* File: mips/op_iget.S */
- /*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
- */
- /* op vA, vB, field@CCCC */
- EXPORT_PC()
- FETCH(a0, 1) # a0 <- field ref CCCC
- GET_OPB(a1) # a1 <- B
- GET_VREG(a1, a1) # a1 <- fp[B], the object pointer
- lw a2, OFF_FP_METHOD(rFP) # a2 <- referrer
- move a3, rSELF # a3 <- self
- JAL(MterpIGetObj)
- lw a3, THREAD_EXCEPTION_OFFSET(rSELF)
- GET_OPA4(a2) # a2<- A+
- PREFETCH_INST(2) # load rINST
- bnez a3, MterpPossibleException # bail out
- ADVANCE(2) # advance rPC
- GET_INST_OPCODE(t0) # extract opcode from rINST
- .if 1
- SET_VREG_OBJECT_GOTO(v0, a2, t0) # fp[A] <- v0
- .else
- SET_VREG_GOTO(v0, a2, t0) # fp[A] <- v0
- .endif
+/* File: mips/field.S */
+TODO
+
/* ------------------------------ */
@@ -2751,30 +2694,9 @@
.L_op_iget_boolean: /* 0x55 */
/* File: mips/op_iget_boolean.S */
/* File: mips/op_iget.S */
- /*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
- */
- /* op vA, vB, field@CCCC */
- EXPORT_PC()
- FETCH(a0, 1) # a0 <- field ref CCCC
- GET_OPB(a1) # a1 <- B
- GET_VREG(a1, a1) # a1 <- fp[B], the object pointer
- lw a2, OFF_FP_METHOD(rFP) # a2 <- referrer
- move a3, rSELF # a3 <- self
- JAL(MterpIGetU8)
- lw a3, THREAD_EXCEPTION_OFFSET(rSELF)
- GET_OPA4(a2) # a2<- A+
- PREFETCH_INST(2) # load rINST
- bnez a3, MterpPossibleException # bail out
- ADVANCE(2) # advance rPC
- GET_INST_OPCODE(t0) # extract opcode from rINST
- .if 0
- SET_VREG_OBJECT_GOTO(v0, a2, t0) # fp[A] <- v0
- .else
- SET_VREG_GOTO(v0, a2, t0) # fp[A] <- v0
- .endif
+/* File: mips/field.S */
+TODO
+
/* ------------------------------ */
@@ -2782,30 +2704,9 @@
.L_op_iget_byte: /* 0x56 */
/* File: mips/op_iget_byte.S */
/* File: mips/op_iget.S */
- /*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
- */
- /* op vA, vB, field@CCCC */
- EXPORT_PC()
- FETCH(a0, 1) # a0 <- field ref CCCC
- GET_OPB(a1) # a1 <- B
- GET_VREG(a1, a1) # a1 <- fp[B], the object pointer
- lw a2, OFF_FP_METHOD(rFP) # a2 <- referrer
- move a3, rSELF # a3 <- self
- JAL(MterpIGetI8)
- lw a3, THREAD_EXCEPTION_OFFSET(rSELF)
- GET_OPA4(a2) # a2<- A+
- PREFETCH_INST(2) # load rINST
- bnez a3, MterpPossibleException # bail out
- ADVANCE(2) # advance rPC
- GET_INST_OPCODE(t0) # extract opcode from rINST
- .if 0
- SET_VREG_OBJECT_GOTO(v0, a2, t0) # fp[A] <- v0
- .else
- SET_VREG_GOTO(v0, a2, t0) # fp[A] <- v0
- .endif
+/* File: mips/field.S */
+TODO
+
/* ------------------------------ */
@@ -2813,30 +2714,9 @@
.L_op_iget_char: /* 0x57 */
/* File: mips/op_iget_char.S */
/* File: mips/op_iget.S */
- /*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
- */
- /* op vA, vB, field@CCCC */
- EXPORT_PC()
- FETCH(a0, 1) # a0 <- field ref CCCC
- GET_OPB(a1) # a1 <- B
- GET_VREG(a1, a1) # a1 <- fp[B], the object pointer
- lw a2, OFF_FP_METHOD(rFP) # a2 <- referrer
- move a3, rSELF # a3 <- self
- JAL(MterpIGetU16)
- lw a3, THREAD_EXCEPTION_OFFSET(rSELF)
- GET_OPA4(a2) # a2<- A+
- PREFETCH_INST(2) # load rINST
- bnez a3, MterpPossibleException # bail out
- ADVANCE(2) # advance rPC
- GET_INST_OPCODE(t0) # extract opcode from rINST
- .if 0
- SET_VREG_OBJECT_GOTO(v0, a2, t0) # fp[A] <- v0
- .else
- SET_VREG_GOTO(v0, a2, t0) # fp[A] <- v0
- .endif
+/* File: mips/field.S */
+TODO
+
/* ------------------------------ */
@@ -2844,123 +2724,47 @@
.L_op_iget_short: /* 0x58 */
/* File: mips/op_iget_short.S */
/* File: mips/op_iget.S */
- /*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
- */
- /* op vA, vB, field@CCCC */
- EXPORT_PC()
- FETCH(a0, 1) # a0 <- field ref CCCC
- GET_OPB(a1) # a1 <- B
- GET_VREG(a1, a1) # a1 <- fp[B], the object pointer
- lw a2, OFF_FP_METHOD(rFP) # a2 <- referrer
- move a3, rSELF # a3 <- self
- JAL(MterpIGetI16)
- lw a3, THREAD_EXCEPTION_OFFSET(rSELF)
- GET_OPA4(a2) # a2<- A+
- PREFETCH_INST(2) # load rINST
- bnez a3, MterpPossibleException # bail out
- ADVANCE(2) # advance rPC
- GET_INST_OPCODE(t0) # extract opcode from rINST
- .if 0
- SET_VREG_OBJECT_GOTO(v0, a2, t0) # fp[A] <- v0
- .else
- SET_VREG_GOTO(v0, a2, t0) # fp[A] <- v0
- .endif
+/* File: mips/field.S */
+TODO
+
/* ------------------------------ */
.balign 128
.L_op_iput: /* 0x59 */
/* File: mips/op_iput.S */
- /*
- * General 32-bit instance field put.
- *
- * for: iput, iput-boolean, iput-byte, iput-char, iput-short
- */
- /* op vA, vB, field@CCCC */
- .extern MterpIPutU32
- EXPORT_PC()
- FETCH(a0, 1) # a0 <- field ref CCCC
- GET_OPB(a1) # a1 <- B
- GET_VREG(a1, a1) # a1 <- fp[B], the object pointer
- GET_OPA4(a2) # a2 <- A+
- GET_VREG(a2, a2) # a2 <- fp[A]
- lw a3, OFF_FP_METHOD(rFP) # a3 <- referrer
- PREFETCH_INST(2) # load rINST
- JAL(MterpIPutU32)
- bnez v0, MterpPossibleException # bail out
- ADVANCE(2) # advance rPC
- GET_INST_OPCODE(t0) # extract opcode from rINST
- GOTO_OPCODE(t0) # jump to next instruction
+/* File: mips/field.S */
+TODO
+
/* ------------------------------ */
.balign 128
.L_op_iput_wide: /* 0x5a */
/* File: mips/op_iput_wide.S */
- /* iput-wide vA, vB, field@CCCC */
- .extern MterpIPutU64
- EXPORT_PC()
- FETCH(a0, 1) # a0 <- field ref CCCC
- GET_OPB(a1) # a1 <- B
- GET_VREG(a1, a1) # a1 <- fp[B], the object pointer
- GET_OPA4(a2) # a2 <- A+
- EAS2(a2, rFP, a2) # a2 <- &fp[A]
- lw a3, OFF_FP_METHOD(rFP) # a3 <- referrer
- PREFETCH_INST(2) # load rINST
- JAL(MterpIPutU64)
- bnez v0, MterpPossibleException # bail out
- ADVANCE(2) # advance rPC
- GET_INST_OPCODE(t0) # extract opcode from rINST
- GOTO_OPCODE(t0) # jump to next instruction
+/* File: mips/op_iput.S */
+/* File: mips/field.S */
+TODO
+
+
/* ------------------------------ */
.balign 128
.L_op_iput_object: /* 0x5b */
/* File: mips/op_iput_object.S */
- /*
- * 32-bit instance field put.
- *
- * for: iput-object, iput-object-volatile
- */
- /* op vA, vB, field@CCCC */
- EXPORT_PC()
- addu a0, rFP, OFF_FP_SHADOWFRAME
- move a1, rPC
- move a2, rINST
- move a3, rSELF
- JAL(MterpIPutObj)
- beqz v0, MterpException
- FETCH_ADVANCE_INST(2) # advance rPC, load rINST
- GET_INST_OPCODE(t0) # extract opcode from rINST
- GOTO_OPCODE(t0) # jump to next instruction
+/* File: mips/op_iput.S */
+/* File: mips/field.S */
+TODO
+
+
/* ------------------------------ */
.balign 128
.L_op_iput_boolean: /* 0x5c */
/* File: mips/op_iput_boolean.S */
/* File: mips/op_iput.S */
- /*
- * General 32-bit instance field put.
- *
- * for: iput, iput-boolean, iput-byte, iput-char, iput-short
- */
- /* op vA, vB, field@CCCC */
- .extern MterpIPutU8
- EXPORT_PC()
- FETCH(a0, 1) # a0 <- field ref CCCC
- GET_OPB(a1) # a1 <- B
- GET_VREG(a1, a1) # a1 <- fp[B], the object pointer
- GET_OPA4(a2) # a2 <- A+
- GET_VREG(a2, a2) # a2 <- fp[A]
- lw a3, OFF_FP_METHOD(rFP) # a3 <- referrer
- PREFETCH_INST(2) # load rINST
- JAL(MterpIPutU8)
- bnez v0, MterpPossibleException # bail out
- ADVANCE(2) # advance rPC
- GET_INST_OPCODE(t0) # extract opcode from rINST
- GOTO_OPCODE(t0) # jump to next instruction
+/* File: mips/field.S */
+TODO
+
/* ------------------------------ */
@@ -2968,26 +2772,9 @@
.L_op_iput_byte: /* 0x5d */
/* File: mips/op_iput_byte.S */
/* File: mips/op_iput.S */
- /*
- * General 32-bit instance field put.
- *
- * for: iput, iput-boolean, iput-byte, iput-char, iput-short
- */
- /* op vA, vB, field@CCCC */
- .extern MterpIPutI8
- EXPORT_PC()
- FETCH(a0, 1) # a0 <- field ref CCCC
- GET_OPB(a1) # a1 <- B
- GET_VREG(a1, a1) # a1 <- fp[B], the object pointer
- GET_OPA4(a2) # a2 <- A+
- GET_VREG(a2, a2) # a2 <- fp[A]
- lw a3, OFF_FP_METHOD(rFP) # a3 <- referrer
- PREFETCH_INST(2) # load rINST
- JAL(MterpIPutI8)
- bnez v0, MterpPossibleException # bail out
- ADVANCE(2) # advance rPC
- GET_INST_OPCODE(t0) # extract opcode from rINST
- GOTO_OPCODE(t0) # jump to next instruction
+/* File: mips/field.S */
+TODO
+
/* ------------------------------ */
@@ -2995,26 +2782,9 @@
.L_op_iput_char: /* 0x5e */
/* File: mips/op_iput_char.S */
/* File: mips/op_iput.S */
- /*
- * General 32-bit instance field put.
- *
- * for: iput, iput-boolean, iput-byte, iput-char, iput-short
- */
- /* op vA, vB, field@CCCC */
- .extern MterpIPutU16
- EXPORT_PC()
- FETCH(a0, 1) # a0 <- field ref CCCC
- GET_OPB(a1) # a1 <- B
- GET_VREG(a1, a1) # a1 <- fp[B], the object pointer
- GET_OPA4(a2) # a2 <- A+
- GET_VREG(a2, a2) # a2 <- fp[A]
- lw a3, OFF_FP_METHOD(rFP) # a3 <- referrer
- PREFETCH_INST(2) # load rINST
- JAL(MterpIPutU16)
- bnez v0, MterpPossibleException # bail out
- ADVANCE(2) # advance rPC
- GET_INST_OPCODE(t0) # extract opcode from rINST
- GOTO_OPCODE(t0) # jump to next instruction
+/* File: mips/field.S */
+TODO
+
/* ------------------------------ */
@@ -3022,105 +2792,37 @@
.L_op_iput_short: /* 0x5f */
/* File: mips/op_iput_short.S */
/* File: mips/op_iput.S */
- /*
- * General 32-bit instance field put.
- *
- * for: iput, iput-boolean, iput-byte, iput-char, iput-short
- */
- /* op vA, vB, field@CCCC */
- .extern MterpIPutI16
- EXPORT_PC()
- FETCH(a0, 1) # a0 <- field ref CCCC
- GET_OPB(a1) # a1 <- B
- GET_VREG(a1, a1) # a1 <- fp[B], the object pointer
- GET_OPA4(a2) # a2 <- A+
- GET_VREG(a2, a2) # a2 <- fp[A]
- lw a3, OFF_FP_METHOD(rFP) # a3 <- referrer
- PREFETCH_INST(2) # load rINST
- JAL(MterpIPutI16)
- bnez v0, MterpPossibleException # bail out
- ADVANCE(2) # advance rPC
- GET_INST_OPCODE(t0) # extract opcode from rINST
- GOTO_OPCODE(t0) # jump to next instruction
+/* File: mips/field.S */
+TODO
+
/* ------------------------------ */
.balign 128
.L_op_sget: /* 0x60 */
/* File: mips/op_sget.S */
- /*
- * General SGET handler.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
- */
- /* op vAA, field@BBBB */
- .extern MterpSGetU32
- EXPORT_PC()
- FETCH(a0, 1) # a0 <- field ref BBBB
- lw a1, OFF_FP_METHOD(rFP) # a1 <- method
- move a2, rSELF # a2 <- self
- JAL(MterpSGetU32)
- lw a3, THREAD_EXCEPTION_OFFSET(rSELF)
- GET_OPA(a2) # a2 <- AA
- PREFETCH_INST(2)
- bnez a3, MterpException # bail out
- ADVANCE(2)
- GET_INST_OPCODE(t0) # extract opcode from rINST
-.if 0
- SET_VREG_OBJECT_GOTO(v0, a2, t0) # fp[AA] <- v0
-.else
- SET_VREG_GOTO(v0, a2, t0) # fp[AA] <- v0
-.endif
+/* File: mips/field.S */
+TODO
+
/* ------------------------------ */
.balign 128
.L_op_sget_wide: /* 0x61 */
/* File: mips/op_sget_wide.S */
- /*
- * 64-bit SGET handler.
- */
- /* sget-wide vAA, field@BBBB */
- .extern MterpSGetU64
- EXPORT_PC()
- FETCH(a0, 1) # a0 <- field ref BBBB
- lw a1, OFF_FP_METHOD(rFP) # a1 <- method
- move a2, rSELF # a2 <- self
- JAL(MterpSGetU64)
- lw a3, THREAD_EXCEPTION_OFFSET(rSELF)
- bnez a3, MterpException
- GET_OPA(a1) # a1 <- AA
- FETCH_ADVANCE_INST(2) # advance rPC, load rINST
- GET_INST_OPCODE(t0) # extract opcode from rINST
- SET_VREG64_GOTO(v0, v1, a1, t0) # vAA/vAA+1 <- v0/v1
+/* File: mips/op_sget.S */
+/* File: mips/field.S */
+TODO
+
+
/* ------------------------------ */
.balign 128
.L_op_sget_object: /* 0x62 */
/* File: mips/op_sget_object.S */
/* File: mips/op_sget.S */
- /*
- * General SGET handler.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
- */
- /* op vAA, field@BBBB */
- .extern MterpSGetObj
- EXPORT_PC()
- FETCH(a0, 1) # a0 <- field ref BBBB
- lw a1, OFF_FP_METHOD(rFP) # a1 <- method
- move a2, rSELF # a2 <- self
- JAL(MterpSGetObj)
- lw a3, THREAD_EXCEPTION_OFFSET(rSELF)
- GET_OPA(a2) # a2 <- AA
- PREFETCH_INST(2)
- bnez a3, MterpException # bail out
- ADVANCE(2)
- GET_INST_OPCODE(t0) # extract opcode from rINST
-.if 1
- SET_VREG_OBJECT_GOTO(v0, a2, t0) # fp[AA] <- v0
-.else
- SET_VREG_GOTO(v0, a2, t0) # fp[AA] <- v0
-.endif
+/* File: mips/field.S */
+TODO
+
/* ------------------------------ */
@@ -3128,29 +2830,9 @@
.L_op_sget_boolean: /* 0x63 */
/* File: mips/op_sget_boolean.S */
/* File: mips/op_sget.S */
- /*
- * General SGET handler.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
- */
- /* op vAA, field@BBBB */
- .extern MterpSGetU8
- EXPORT_PC()
- FETCH(a0, 1) # a0 <- field ref BBBB
- lw a1, OFF_FP_METHOD(rFP) # a1 <- method
- move a2, rSELF # a2 <- self
- JAL(MterpSGetU8)
- lw a3, THREAD_EXCEPTION_OFFSET(rSELF)
- GET_OPA(a2) # a2 <- AA
- PREFETCH_INST(2)
- bnez a3, MterpException # bail out
- ADVANCE(2)
- GET_INST_OPCODE(t0) # extract opcode from rINST
-.if 0
- SET_VREG_OBJECT_GOTO(v0, a2, t0) # fp[AA] <- v0
-.else
- SET_VREG_GOTO(v0, a2, t0) # fp[AA] <- v0
-.endif
+/* File: mips/field.S */
+TODO
+
/* ------------------------------ */
@@ -3158,29 +2840,9 @@
.L_op_sget_byte: /* 0x64 */
/* File: mips/op_sget_byte.S */
/* File: mips/op_sget.S */
- /*
- * General SGET handler.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
- */
- /* op vAA, field@BBBB */
- .extern MterpSGetI8
- EXPORT_PC()
- FETCH(a0, 1) # a0 <- field ref BBBB
- lw a1, OFF_FP_METHOD(rFP) # a1 <- method
- move a2, rSELF # a2 <- self
- JAL(MterpSGetI8)
- lw a3, THREAD_EXCEPTION_OFFSET(rSELF)
- GET_OPA(a2) # a2 <- AA
- PREFETCH_INST(2)
- bnez a3, MterpException # bail out
- ADVANCE(2)
- GET_INST_OPCODE(t0) # extract opcode from rINST
-.if 0
- SET_VREG_OBJECT_GOTO(v0, a2, t0) # fp[AA] <- v0
-.else
- SET_VREG_GOTO(v0, a2, t0) # fp[AA] <- v0
-.endif
+/* File: mips/field.S */
+TODO
+
/* ------------------------------ */
@@ -3188,29 +2850,9 @@
.L_op_sget_char: /* 0x65 */
/* File: mips/op_sget_char.S */
/* File: mips/op_sget.S */
- /*
- * General SGET handler.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
- */
- /* op vAA, field@BBBB */
- .extern MterpSGetU16
- EXPORT_PC()
- FETCH(a0, 1) # a0 <- field ref BBBB
- lw a1, OFF_FP_METHOD(rFP) # a1 <- method
- move a2, rSELF # a2 <- self
- JAL(MterpSGetU16)
- lw a3, THREAD_EXCEPTION_OFFSET(rSELF)
- GET_OPA(a2) # a2 <- AA
- PREFETCH_INST(2)
- bnez a3, MterpException # bail out
- ADVANCE(2)
- GET_INST_OPCODE(t0) # extract opcode from rINST
-.if 0
- SET_VREG_OBJECT_GOTO(v0, a2, t0) # fp[AA] <- v0
-.else
- SET_VREG_GOTO(v0, a2, t0) # fp[AA] <- v0
-.endif
+/* File: mips/field.S */
+TODO
+
/* ------------------------------ */
@@ -3218,120 +2860,47 @@
.L_op_sget_short: /* 0x66 */
/* File: mips/op_sget_short.S */
/* File: mips/op_sget.S */
- /*
- * General SGET handler.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
- */
- /* op vAA, field@BBBB */
- .extern MterpSGetI16
- EXPORT_PC()
- FETCH(a0, 1) # a0 <- field ref BBBB
- lw a1, OFF_FP_METHOD(rFP) # a1 <- method
- move a2, rSELF # a2 <- self
- JAL(MterpSGetI16)
- lw a3, THREAD_EXCEPTION_OFFSET(rSELF)
- GET_OPA(a2) # a2 <- AA
- PREFETCH_INST(2)
- bnez a3, MterpException # bail out
- ADVANCE(2)
- GET_INST_OPCODE(t0) # extract opcode from rINST
-.if 0
- SET_VREG_OBJECT_GOTO(v0, a2, t0) # fp[AA] <- v0
-.else
- SET_VREG_GOTO(v0, a2, t0) # fp[AA] <- v0
-.endif
+/* File: mips/field.S */
+TODO
+
/* ------------------------------ */
.balign 128
.L_op_sput: /* 0x67 */
/* File: mips/op_sput.S */
- /*
- * General SPUT handler.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
- */
- /* op vAA, field@BBBB */
- EXPORT_PC()
- FETCH(a0, 1) # a0 <- field ref BBBB
- GET_OPA(a3) # a3 <- AA
- GET_VREG(a1, a3) # a1 <- fp[AA], the object pointer
- lw a2, OFF_FP_METHOD(rFP) # a2 <- method
- move a3, rSELF # a3 <- self
- PREFETCH_INST(2) # load rINST
- JAL(MterpSPutU32)
- bnez v0, MterpException # bail out
- ADVANCE(2) # advance rPC
- GET_INST_OPCODE(t0) # extract opcode from rINST
- GOTO_OPCODE(t0) # jump to next instruction
+/* File: mips/field.S */
+TODO
+
/* ------------------------------ */
.balign 128
.L_op_sput_wide: /* 0x68 */
/* File: mips/op_sput_wide.S */
- /*
- * 64-bit SPUT handler.
- */
- /* sput-wide vAA, field@BBBB */
- .extern MterpSPutU64
- EXPORT_PC()
- FETCH(a0, 1) # a0 <- field ref CCCC
- GET_OPA(a1) # a1 <- AA
- EAS2(a1, rFP, a1) # a1 <- &fp[AA]
- lw a2, OFF_FP_METHOD(rFP) # a2 <- method
- move a3, rSELF # a3 <- self
- PREFETCH_INST(2) # load rINST
- JAL(MterpSPutU64)
- bnez v0, MterpException # bail out
- ADVANCE(2) # advance rPC
- GET_INST_OPCODE(t0) # extract opcode from rINST
- GOTO_OPCODE(t0) # jump to next instruction
+/* File: mips/op_sput.S */
+/* File: mips/field.S */
+TODO
+
+
/* ------------------------------ */
.balign 128
.L_op_sput_object: /* 0x69 */
/* File: mips/op_sput_object.S */
- /*
- * General 32-bit SPUT handler.
- *
- * for: sput-object,
- */
- /* op vAA, field@BBBB */
- EXPORT_PC()
- addu a0, rFP, OFF_FP_SHADOWFRAME
- move a1, rPC
- move a2, rINST
- move a3, rSELF
- JAL(MterpSPutObj)
- beqz v0, MterpException
- FETCH_ADVANCE_INST(2) # advance rPC, load rINST
- GET_INST_OPCODE(t0) # extract opcode from rINST
- GOTO_OPCODE(t0) # jump to next instruction
+/* File: mips/op_sput.S */
+/* File: mips/field.S */
+TODO
+
+
/* ------------------------------ */
.balign 128
.L_op_sput_boolean: /* 0x6a */
/* File: mips/op_sput_boolean.S */
/* File: mips/op_sput.S */
- /*
- * General SPUT handler.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
- */
- /* op vAA, field@BBBB */
- EXPORT_PC()
- FETCH(a0, 1) # a0 <- field ref BBBB
- GET_OPA(a3) # a3 <- AA
- GET_VREG(a1, a3) # a1 <- fp[AA], the object pointer
- lw a2, OFF_FP_METHOD(rFP) # a2 <- method
- move a3, rSELF # a3 <- self
- PREFETCH_INST(2) # load rINST
- JAL(MterpSPutU8)
- bnez v0, MterpException # bail out
- ADVANCE(2) # advance rPC
- GET_INST_OPCODE(t0) # extract opcode from rINST
- GOTO_OPCODE(t0) # jump to next instruction
+/* File: mips/field.S */
+TODO
+
/* ------------------------------ */
@@ -3339,24 +2908,9 @@
.L_op_sput_byte: /* 0x6b */
/* File: mips/op_sput_byte.S */
/* File: mips/op_sput.S */
- /*
- * General SPUT handler.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
- */
- /* op vAA, field@BBBB */
- EXPORT_PC()
- FETCH(a0, 1) # a0 <- field ref BBBB
- GET_OPA(a3) # a3 <- AA
- GET_VREG(a1, a3) # a1 <- fp[AA], the object pointer
- lw a2, OFF_FP_METHOD(rFP) # a2 <- method
- move a3, rSELF # a3 <- self
- PREFETCH_INST(2) # load rINST
- JAL(MterpSPutI8)
- bnez v0, MterpException # bail out
- ADVANCE(2) # advance rPC
- GET_INST_OPCODE(t0) # extract opcode from rINST
- GOTO_OPCODE(t0) # jump to next instruction
+/* File: mips/field.S */
+TODO
+
/* ------------------------------ */
@@ -3364,24 +2918,9 @@
.L_op_sput_char: /* 0x6c */
/* File: mips/op_sput_char.S */
/* File: mips/op_sput.S */
- /*
- * General SPUT handler.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
- */
- /* op vAA, field@BBBB */
- EXPORT_PC()
- FETCH(a0, 1) # a0 <- field ref BBBB
- GET_OPA(a3) # a3 <- AA
- GET_VREG(a1, a3) # a1 <- fp[AA], the object pointer
- lw a2, OFF_FP_METHOD(rFP) # a2 <- method
- move a3, rSELF # a3 <- self
- PREFETCH_INST(2) # load rINST
- JAL(MterpSPutU16)
- bnez v0, MterpException # bail out
- ADVANCE(2) # advance rPC
- GET_INST_OPCODE(t0) # extract opcode from rINST
- GOTO_OPCODE(t0) # jump to next instruction
+/* File: mips/field.S */
+TODO
+
/* ------------------------------ */
@@ -3389,24 +2928,9 @@
.L_op_sput_short: /* 0x6d */
/* File: mips/op_sput_short.S */
/* File: mips/op_sput.S */
- /*
- * General SPUT handler.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
- */
- /* op vAA, field@BBBB */
- EXPORT_PC()
- FETCH(a0, 1) # a0 <- field ref BBBB
- GET_OPA(a3) # a3 <- AA
- GET_VREG(a1, a3) # a1 <- fp[AA], the object pointer
- lw a2, OFF_FP_METHOD(rFP) # a2 <- method
- move a3, rSELF # a3 <- self
- PREFETCH_INST(2) # load rINST
- JAL(MterpSPutI16)
- bnez v0, MterpException # bail out
- ADVANCE(2) # advance rPC
- GET_INST_OPCODE(t0) # extract opcode from rINST
- GOTO_OPCODE(t0) # jump to next instruction
+/* File: mips/field.S */
+TODO
+
/* ------------------------------ */
diff --git a/runtime/interpreter/mterp/out/mterp_mips64.S b/runtime/interpreter/mterp/out/mterp_mips64.S
index 6561691..40a8396 100644
--- a/runtime/interpreter/mterp/out/mterp_mips64.S
+++ b/runtime/interpreter/mterp/out/mterp_mips64.S
@@ -2241,88 +2241,28 @@
.balign 128
.L_op_iget: /* 0x52 */
/* File: mips64/op_iget.S */
- /*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
- */
- .extern MterpIGetU32
- EXPORT_PC
- lhu a0, 2(rPC) # a0 <- field ref CCCC
- srl a1, rINST, 12 # a1 <- B
- GET_VREG_U a1, a1 # a1 <- fp[B], the object pointer
- ld a2, OFF_FP_METHOD(rFP) # a2 <- referrer
- move a3, rSELF # a3 <- self
- jal MterpIGetU32
- ld a3, THREAD_EXCEPTION_OFFSET(rSELF)
- ext a2, rINST, 8, 4 # a2 <- A
- PREFETCH_INST 2
- bnez a3, MterpPossibleException # bail out
- .if 0
- SET_VREG_OBJECT v0, a2 # fp[A] <- v0
- .else
- SET_VREG v0, a2 # fp[A] <- v0
- .endif
- ADVANCE 2
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
+/* File: mips64/field.S */
+TODO
+
/* ------------------------------ */
.balign 128
.L_op_iget_wide: /* 0x53 */
/* File: mips64/op_iget_wide.S */
- /*
- * 64-bit instance field get.
- *
- * for: iget-wide
- */
- .extern MterpIGetU64
- EXPORT_PC
- lhu a0, 2(rPC) # a0 <- field ref CCCC
- srl a1, rINST, 12 # a1 <- B
- GET_VREG_U a1, a1 # a1 <- fp[B], the object pointer
- ld a2, OFF_FP_METHOD(rFP) # a2 <- referrer
- move a3, rSELF # a3 <- self
- jal MterpIGetU64
- ld a3, THREAD_EXCEPTION_OFFSET(rSELF)
- ext a2, rINST, 8, 4 # a2 <- A
- PREFETCH_INST 2
- bnez a3, MterpPossibleException # bail out
- SET_VREG_WIDE v0, a2 # fp[A] <- v0
- ADVANCE 2
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
+/* File: mips64/op_iget.S */
+/* File: mips64/field.S */
+TODO
+
+
/* ------------------------------ */
.balign 128
.L_op_iget_object: /* 0x54 */
/* File: mips64/op_iget_object.S */
/* File: mips64/op_iget.S */
- /*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
- */
- .extern MterpIGetObj
- EXPORT_PC
- lhu a0, 2(rPC) # a0 <- field ref CCCC
- srl a1, rINST, 12 # a1 <- B
- GET_VREG_U a1, a1 # a1 <- fp[B], the object pointer
- ld a2, OFF_FP_METHOD(rFP) # a2 <- referrer
- move a3, rSELF # a3 <- self
- jal MterpIGetObj
- ld a3, THREAD_EXCEPTION_OFFSET(rSELF)
- ext a2, rINST, 8, 4 # a2 <- A
- PREFETCH_INST 2
- bnez a3, MterpPossibleException # bail out
- .if 1
- SET_VREG_OBJECT v0, a2 # fp[A] <- v0
- .else
- SET_VREG v0, a2 # fp[A] <- v0
- .endif
- ADVANCE 2
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
+/* File: mips64/field.S */
+TODO
+
/* ------------------------------ */
@@ -2330,31 +2270,9 @@
.L_op_iget_boolean: /* 0x55 */
/* File: mips64/op_iget_boolean.S */
/* File: mips64/op_iget.S */
- /*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
- */
- .extern MterpIGetU8
- EXPORT_PC
- lhu a0, 2(rPC) # a0 <- field ref CCCC
- srl a1, rINST, 12 # a1 <- B
- GET_VREG_U a1, a1 # a1 <- fp[B], the object pointer
- ld a2, OFF_FP_METHOD(rFP) # a2 <- referrer
- move a3, rSELF # a3 <- self
- jal MterpIGetU8
- ld a3, THREAD_EXCEPTION_OFFSET(rSELF)
- ext a2, rINST, 8, 4 # a2 <- A
- PREFETCH_INST 2
- bnez a3, MterpPossibleException # bail out
- .if 0
- SET_VREG_OBJECT v0, a2 # fp[A] <- v0
- .else
- SET_VREG v0, a2 # fp[A] <- v0
- .endif
- ADVANCE 2
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
+/* File: mips64/field.S */
+TODO
+
/* ------------------------------ */
@@ -2362,31 +2280,9 @@
.L_op_iget_byte: /* 0x56 */
/* File: mips64/op_iget_byte.S */
/* File: mips64/op_iget.S */
- /*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
- */
- .extern MterpIGetI8
- EXPORT_PC
- lhu a0, 2(rPC) # a0 <- field ref CCCC
- srl a1, rINST, 12 # a1 <- B
- GET_VREG_U a1, a1 # a1 <- fp[B], the object pointer
- ld a2, OFF_FP_METHOD(rFP) # a2 <- referrer
- move a3, rSELF # a3 <- self
- jal MterpIGetI8
- ld a3, THREAD_EXCEPTION_OFFSET(rSELF)
- ext a2, rINST, 8, 4 # a2 <- A
- PREFETCH_INST 2
- bnez a3, MterpPossibleException # bail out
- .if 0
- SET_VREG_OBJECT v0, a2 # fp[A] <- v0
- .else
- SET_VREG v0, a2 # fp[A] <- v0
- .endif
- ADVANCE 2
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
+/* File: mips64/field.S */
+TODO
+
/* ------------------------------ */
@@ -2394,31 +2290,9 @@
.L_op_iget_char: /* 0x57 */
/* File: mips64/op_iget_char.S */
/* File: mips64/op_iget.S */
- /*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
- */
- .extern MterpIGetU16
- EXPORT_PC
- lhu a0, 2(rPC) # a0 <- field ref CCCC
- srl a1, rINST, 12 # a1 <- B
- GET_VREG_U a1, a1 # a1 <- fp[B], the object pointer
- ld a2, OFF_FP_METHOD(rFP) # a2 <- referrer
- move a3, rSELF # a3 <- self
- jal MterpIGetU16
- ld a3, THREAD_EXCEPTION_OFFSET(rSELF)
- ext a2, rINST, 8, 4 # a2 <- A
- PREFETCH_INST 2
- bnez a3, MterpPossibleException # bail out
- .if 0
- SET_VREG_OBJECT v0, a2 # fp[A] <- v0
- .else
- SET_VREG v0, a2 # fp[A] <- v0
- .endif
- ADVANCE 2
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
+/* File: mips64/field.S */
+TODO
+
/* ------------------------------ */
@@ -2426,119 +2300,47 @@
.L_op_iget_short: /* 0x58 */
/* File: mips64/op_iget_short.S */
/* File: mips64/op_iget.S */
- /*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
- */
- .extern MterpIGetI16
- EXPORT_PC
- lhu a0, 2(rPC) # a0 <- field ref CCCC
- srl a1, rINST, 12 # a1 <- B
- GET_VREG_U a1, a1 # a1 <- fp[B], the object pointer
- ld a2, OFF_FP_METHOD(rFP) # a2 <- referrer
- move a3, rSELF # a3 <- self
- jal MterpIGetI16
- ld a3, THREAD_EXCEPTION_OFFSET(rSELF)
- ext a2, rINST, 8, 4 # a2 <- A
- PREFETCH_INST 2
- bnez a3, MterpPossibleException # bail out
- .if 0
- SET_VREG_OBJECT v0, a2 # fp[A] <- v0
- .else
- SET_VREG v0, a2 # fp[A] <- v0
- .endif
- ADVANCE 2
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
+/* File: mips64/field.S */
+TODO
+
/* ------------------------------ */
.balign 128
.L_op_iput: /* 0x59 */
/* File: mips64/op_iput.S */
- /*
- * General 32-bit instance field put.
- *
- * for: iput, iput-boolean, iput-byte, iput-char, iput-short
- */
- /* op vA, vB, field//CCCC */
- .extern MterpIPutU32
- EXPORT_PC
- lhu a0, 2(rPC) # a0 <- field ref CCCC
- srl a1, rINST, 12 # a1 <- B
- GET_VREG_U a1, a1 # a1 <- fp[B], the object pointer
- ext a2, rINST, 8, 4 # a2 <- A
- GET_VREG a2, a2 # a2 <- fp[A]
- ld a3, OFF_FP_METHOD(rFP) # a3 <- referrer
- PREFETCH_INST 2
- jal MterpIPutU32
- bnez v0, MterpPossibleException # bail out
- ADVANCE 2
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
+/* File: mips64/field.S */
+TODO
+
/* ------------------------------ */
.balign 128
.L_op_iput_wide: /* 0x5a */
/* File: mips64/op_iput_wide.S */
- /* iput-wide vA, vB, field//CCCC */
- .extern MterpIPutU64
- EXPORT_PC
- lhu a0, 2(rPC) # a0 <- field ref CCCC
- srl a1, rINST, 12 # a1 <- B
- GET_VREG_U a1, a1 # a1 <- fp[B], the object pointer
- ext a2, rINST, 8, 4 # a2 <- A
- dlsa a2, a2, rFP, 2 # a2 <- &fp[A]
- ld a3, OFF_FP_METHOD(rFP) # a3 <- referrer
- PREFETCH_INST 2
- jal MterpIPutU64
- bnez v0, MterpPossibleException # bail out
- ADVANCE 2
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
+/* File: mips64/op_iput.S */
+/* File: mips64/field.S */
+TODO
+
+
/* ------------------------------ */
.balign 128
.L_op_iput_object: /* 0x5b */
/* File: mips64/op_iput_object.S */
- .extern MterpIPutObj
- EXPORT_PC
- daddu a0, rFP, OFF_FP_SHADOWFRAME
- move a1, rPC
- move a2, rINST
- move a3, rSELF
- jal MterpIPutObj
- beqzc v0, MterpException
- FETCH_ADVANCE_INST 2 # advance rPC, load rINST
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
+/* File: mips64/op_iput.S */
+/* File: mips64/field.S */
+TODO
+
+
/* ------------------------------ */
.balign 128
.L_op_iput_boolean: /* 0x5c */
/* File: mips64/op_iput_boolean.S */
/* File: mips64/op_iput.S */
- /*
- * General 32-bit instance field put.
- *
- * for: iput, iput-boolean, iput-byte, iput-char, iput-short
- */
- /* op vA, vB, field//CCCC */
- .extern MterpIPutU8
- EXPORT_PC
- lhu a0, 2(rPC) # a0 <- field ref CCCC
- srl a1, rINST, 12 # a1 <- B
- GET_VREG_U a1, a1 # a1 <- fp[B], the object pointer
- ext a2, rINST, 8, 4 # a2 <- A
- GET_VREG a2, a2 # a2 <- fp[A]
- ld a3, OFF_FP_METHOD(rFP) # a3 <- referrer
- PREFETCH_INST 2
- jal MterpIPutU8
- bnez v0, MterpPossibleException # bail out
- ADVANCE 2
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
+/* File: mips64/field.S */
+TODO
+
/* ------------------------------ */
@@ -2546,26 +2348,9 @@
.L_op_iput_byte: /* 0x5d */
/* File: mips64/op_iput_byte.S */
/* File: mips64/op_iput.S */
- /*
- * General 32-bit instance field put.
- *
- * for: iput, iput-boolean, iput-byte, iput-char, iput-short
- */
- /* op vA, vB, field//CCCC */
- .extern MterpIPutI8
- EXPORT_PC
- lhu a0, 2(rPC) # a0 <- field ref CCCC
- srl a1, rINST, 12 # a1 <- B
- GET_VREG_U a1, a1 # a1 <- fp[B], the object pointer
- ext a2, rINST, 8, 4 # a2 <- A
- GET_VREG a2, a2 # a2 <- fp[A]
- ld a3, OFF_FP_METHOD(rFP) # a3 <- referrer
- PREFETCH_INST 2
- jal MterpIPutI8
- bnez v0, MterpPossibleException # bail out
- ADVANCE 2
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
+/* File: mips64/field.S */
+TODO
+
/* ------------------------------ */
@@ -2573,26 +2358,9 @@
.L_op_iput_char: /* 0x5e */
/* File: mips64/op_iput_char.S */
/* File: mips64/op_iput.S */
- /*
- * General 32-bit instance field put.
- *
- * for: iput, iput-boolean, iput-byte, iput-char, iput-short
- */
- /* op vA, vB, field//CCCC */
- .extern MterpIPutU16
- EXPORT_PC
- lhu a0, 2(rPC) # a0 <- field ref CCCC
- srl a1, rINST, 12 # a1 <- B
- GET_VREG_U a1, a1 # a1 <- fp[B], the object pointer
- ext a2, rINST, 8, 4 # a2 <- A
- GET_VREG a2, a2 # a2 <- fp[A]
- ld a3, OFF_FP_METHOD(rFP) # a3 <- referrer
- PREFETCH_INST 2
- jal MterpIPutU16
- bnez v0, MterpPossibleException # bail out
- ADVANCE 2
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
+/* File: mips64/field.S */
+TODO
+
/* ------------------------------ */
@@ -2600,111 +2368,37 @@
.L_op_iput_short: /* 0x5f */
/* File: mips64/op_iput_short.S */
/* File: mips64/op_iput.S */
- /*
- * General 32-bit instance field put.
- *
- * for: iput, iput-boolean, iput-byte, iput-char, iput-short
- */
- /* op vA, vB, field//CCCC */
- .extern MterpIPutI16
- EXPORT_PC
- lhu a0, 2(rPC) # a0 <- field ref CCCC
- srl a1, rINST, 12 # a1 <- B
- GET_VREG_U a1, a1 # a1 <- fp[B], the object pointer
- ext a2, rINST, 8, 4 # a2 <- A
- GET_VREG a2, a2 # a2 <- fp[A]
- ld a3, OFF_FP_METHOD(rFP) # a3 <- referrer
- PREFETCH_INST 2
- jal MterpIPutI16
- bnez v0, MterpPossibleException # bail out
- ADVANCE 2
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
+/* File: mips64/field.S */
+TODO
+
/* ------------------------------ */
.balign 128
.L_op_sget: /* 0x60 */
/* File: mips64/op_sget.S */
- /*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
- */
- /* op vAA, field//BBBB */
- .extern MterpSGetU32
- EXPORT_PC
- lhu a0, 2(rPC) # a0 <- field ref BBBB
- ld a1, OFF_FP_METHOD(rFP)
- move a2, rSELF
- jal MterpSGetU32
- ld a3, THREAD_EXCEPTION_OFFSET(rSELF)
- srl a2, rINST, 8 # a2 <- AA
-
- PREFETCH_INST 2
- bnez a3, MterpException # bail out
- .if 0
- SET_VREG_OBJECT v0, a2 # fp[AA] <- v0
- .else
- SET_VREG v0, a2 # fp[AA] <- v0
- .endif
- ADVANCE 2
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0
+/* File: mips64/field.S */
+TODO
+
/* ------------------------------ */
.balign 128
.L_op_sget_wide: /* 0x61 */
/* File: mips64/op_sget_wide.S */
- /*
- * SGET_WIDE handler wrapper.
- *
- */
- /* sget-wide vAA, field//BBBB */
- .extern MterpSGetU64
- EXPORT_PC
- lhu a0, 2(rPC) # a0 <- field ref BBBB
- ld a1, OFF_FP_METHOD(rFP)
- move a2, rSELF
- jal MterpSGetU64
- ld a3, THREAD_EXCEPTION_OFFSET(rSELF)
- srl a4, rINST, 8 # a4 <- AA
- bnez a3, MterpException # bail out
- FETCH_ADVANCE_INST 2 # advance rPC, load rINST
- SET_VREG_WIDE v0, a4
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
+/* File: mips64/op_sget.S */
+/* File: mips64/field.S */
+TODO
+
+
/* ------------------------------ */
.balign 128
.L_op_sget_object: /* 0x62 */
/* File: mips64/op_sget_object.S */
/* File: mips64/op_sget.S */
- /*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
- */
- /* op vAA, field//BBBB */
- .extern MterpSGetObj
- EXPORT_PC
- lhu a0, 2(rPC) # a0 <- field ref BBBB
- ld a1, OFF_FP_METHOD(rFP)
- move a2, rSELF
- jal MterpSGetObj
- ld a3, THREAD_EXCEPTION_OFFSET(rSELF)
- srl a2, rINST, 8 # a2 <- AA
-
- PREFETCH_INST 2
- bnez a3, MterpException # bail out
- .if 1
- SET_VREG_OBJECT v0, a2 # fp[AA] <- v0
- .else
- SET_VREG v0, a2 # fp[AA] <- v0
- .endif
- ADVANCE 2
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0
+/* File: mips64/field.S */
+TODO
+
/* ------------------------------ */
@@ -2712,31 +2406,9 @@
.L_op_sget_boolean: /* 0x63 */
/* File: mips64/op_sget_boolean.S */
/* File: mips64/op_sget.S */
- /*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
- */
- /* op vAA, field//BBBB */
- .extern MterpSGetU8
- EXPORT_PC
- lhu a0, 2(rPC) # a0 <- field ref BBBB
- ld a1, OFF_FP_METHOD(rFP)
- move a2, rSELF
- jal MterpSGetU8
- ld a3, THREAD_EXCEPTION_OFFSET(rSELF)
- srl a2, rINST, 8 # a2 <- AA
- and v0, v0, 0xff
- PREFETCH_INST 2
- bnez a3, MterpException # bail out
- .if 0
- SET_VREG_OBJECT v0, a2 # fp[AA] <- v0
- .else
- SET_VREG v0, a2 # fp[AA] <- v0
- .endif
- ADVANCE 2
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0
+/* File: mips64/field.S */
+TODO
+
/* ------------------------------ */
@@ -2744,31 +2416,9 @@
.L_op_sget_byte: /* 0x64 */
/* File: mips64/op_sget_byte.S */
/* File: mips64/op_sget.S */
- /*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
- */
- /* op vAA, field//BBBB */
- .extern MterpSGetI8
- EXPORT_PC
- lhu a0, 2(rPC) # a0 <- field ref BBBB
- ld a1, OFF_FP_METHOD(rFP)
- move a2, rSELF
- jal MterpSGetI8
- ld a3, THREAD_EXCEPTION_OFFSET(rSELF)
- srl a2, rINST, 8 # a2 <- AA
- seb v0, v0
- PREFETCH_INST 2
- bnez a3, MterpException # bail out
- .if 0
- SET_VREG_OBJECT v0, a2 # fp[AA] <- v0
- .else
- SET_VREG v0, a2 # fp[AA] <- v0
- .endif
- ADVANCE 2
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0
+/* File: mips64/field.S */
+TODO
+
/* ------------------------------ */
@@ -2776,31 +2426,9 @@
.L_op_sget_char: /* 0x65 */
/* File: mips64/op_sget_char.S */
/* File: mips64/op_sget.S */
- /*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
- */
- /* op vAA, field//BBBB */
- .extern MterpSGetU16
- EXPORT_PC
- lhu a0, 2(rPC) # a0 <- field ref BBBB
- ld a1, OFF_FP_METHOD(rFP)
- move a2, rSELF
- jal MterpSGetU16
- ld a3, THREAD_EXCEPTION_OFFSET(rSELF)
- srl a2, rINST, 8 # a2 <- AA
- and v0, v0, 0xffff
- PREFETCH_INST 2
- bnez a3, MterpException # bail out
- .if 0
- SET_VREG_OBJECT v0, a2 # fp[AA] <- v0
- .else
- SET_VREG v0, a2 # fp[AA] <- v0
- .endif
- ADVANCE 2
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0
+/* File: mips64/field.S */
+TODO
+
/* ------------------------------ */
@@ -2808,120 +2436,47 @@
.L_op_sget_short: /* 0x66 */
/* File: mips64/op_sget_short.S */
/* File: mips64/op_sget.S */
- /*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
- */
- /* op vAA, field//BBBB */
- .extern MterpSGetI16
- EXPORT_PC
- lhu a0, 2(rPC) # a0 <- field ref BBBB
- ld a1, OFF_FP_METHOD(rFP)
- move a2, rSELF
- jal MterpSGetI16
- ld a3, THREAD_EXCEPTION_OFFSET(rSELF)
- srl a2, rINST, 8 # a2 <- AA
- seh v0, v0
- PREFETCH_INST 2
- bnez a3, MterpException # bail out
- .if 0
- SET_VREG_OBJECT v0, a2 # fp[AA] <- v0
- .else
- SET_VREG v0, a2 # fp[AA] <- v0
- .endif
- ADVANCE 2
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0
+/* File: mips64/field.S */
+TODO
+
/* ------------------------------ */
.balign 128
.L_op_sput: /* 0x67 */
/* File: mips64/op_sput.S */
- /*
- * General SPUT handler wrapper.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
- */
- /* op vAA, field//BBBB */
- .extern MterpSPutU32
- EXPORT_PC
- lhu a0, 2(rPC) # a0 <- field ref BBBB
- srl a3, rINST, 8 # a3 <- AA
- GET_VREG a1, a3 # a1 <- fp[AA]
- ld a2, OFF_FP_METHOD(rFP)
- move a3, rSELF
- PREFETCH_INST 2 # Get next inst, but don't advance rPC
- jal MterpSPutU32
- bnezc v0, MterpException # 0 on success
- ADVANCE 2 # Past exception point - now advance rPC
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
+/* File: mips64/field.S */
+TODO
+
/* ------------------------------ */
.balign 128
.L_op_sput_wide: /* 0x68 */
/* File: mips64/op_sput_wide.S */
- /*
- * SPUT_WIDE handler wrapper.
- *
- */
- /* sput-wide vAA, field//BBBB */
- .extern MterpSPutU64
- EXPORT_PC
- lhu a0, 2(rPC) # a0 <- field ref BBBB
- srl a1, rINST, 8 # a2 <- AA
- dlsa a1, a1, rFP, 2
- ld a2, OFF_FP_METHOD(rFP)
- move a3, rSELF
- PREFETCH_INST 2 # Get next inst, but don't advance rPC
- jal MterpSPutU64
- bnezc v0, MterpException # 0 on success, -1 on failure
- ADVANCE 2 # Past exception point - now advance rPC
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
+/* File: mips64/op_sput.S */
+/* File: mips64/field.S */
+TODO
+
+
/* ------------------------------ */
.balign 128
.L_op_sput_object: /* 0x69 */
/* File: mips64/op_sput_object.S */
- .extern MterpSPutObj
- EXPORT_PC
- daddu a0, rFP, OFF_FP_SHADOWFRAME
- move a1, rPC
- move a2, rINST
- move a3, rSELF
- jal MterpSPutObj
- beqzc v0, MterpException
- FETCH_ADVANCE_INST 2 # advance rPC, load rINST
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
+/* File: mips64/op_sput.S */
+/* File: mips64/field.S */
+TODO
+
+
/* ------------------------------ */
.balign 128
.L_op_sput_boolean: /* 0x6a */
/* File: mips64/op_sput_boolean.S */
/* File: mips64/op_sput.S */
- /*
- * General SPUT handler wrapper.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
- */
- /* op vAA, field//BBBB */
- .extern MterpSPutU8
- EXPORT_PC
- lhu a0, 2(rPC) # a0 <- field ref BBBB
- srl a3, rINST, 8 # a3 <- AA
- GET_VREG a1, a3 # a1 <- fp[AA]
- ld a2, OFF_FP_METHOD(rFP)
- move a3, rSELF
- PREFETCH_INST 2 # Get next inst, but don't advance rPC
- jal MterpSPutU8
- bnezc v0, MterpException # 0 on success
- ADVANCE 2 # Past exception point - now advance rPC
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
+/* File: mips64/field.S */
+TODO
+
/* ------------------------------ */
@@ -2929,25 +2484,9 @@
.L_op_sput_byte: /* 0x6b */
/* File: mips64/op_sput_byte.S */
/* File: mips64/op_sput.S */
- /*
- * General SPUT handler wrapper.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
- */
- /* op vAA, field//BBBB */
- .extern MterpSPutI8
- EXPORT_PC
- lhu a0, 2(rPC) # a0 <- field ref BBBB
- srl a3, rINST, 8 # a3 <- AA
- GET_VREG a1, a3 # a1 <- fp[AA]
- ld a2, OFF_FP_METHOD(rFP)
- move a3, rSELF
- PREFETCH_INST 2 # Get next inst, but don't advance rPC
- jal MterpSPutI8
- bnezc v0, MterpException # 0 on success
- ADVANCE 2 # Past exception point - now advance rPC
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
+/* File: mips64/field.S */
+TODO
+
/* ------------------------------ */
@@ -2955,25 +2494,9 @@
.L_op_sput_char: /* 0x6c */
/* File: mips64/op_sput_char.S */
/* File: mips64/op_sput.S */
- /*
- * General SPUT handler wrapper.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
- */
- /* op vAA, field//BBBB */
- .extern MterpSPutU16
- EXPORT_PC
- lhu a0, 2(rPC) # a0 <- field ref BBBB
- srl a3, rINST, 8 # a3 <- AA
- GET_VREG a1, a3 # a1 <- fp[AA]
- ld a2, OFF_FP_METHOD(rFP)
- move a3, rSELF
- PREFETCH_INST 2 # Get next inst, but don't advance rPC
- jal MterpSPutU16
- bnezc v0, MterpException # 0 on success
- ADVANCE 2 # Past exception point - now advance rPC
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
+/* File: mips64/field.S */
+TODO
+
/* ------------------------------ */
@@ -2981,25 +2504,9 @@
.L_op_sput_short: /* 0x6d */
/* File: mips64/op_sput_short.S */
/* File: mips64/op_sput.S */
- /*
- * General SPUT handler wrapper.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
- */
- /* op vAA, field//BBBB */
- .extern MterpSPutI16
- EXPORT_PC
- lhu a0, 2(rPC) # a0 <- field ref BBBB
- srl a3, rINST, 8 # a3 <- AA
- GET_VREG a1, a3 # a1 <- fp[AA]
- ld a2, OFF_FP_METHOD(rFP)
- move a3, rSELF
- PREFETCH_INST 2 # Get next inst, but don't advance rPC
- jal MterpSPutI16
- bnezc v0, MterpException # 0 on success
- ADVANCE 2 # Past exception point - now advance rPC
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
+/* File: mips64/field.S */
+TODO
+
/* ------------------------------ */
diff --git a/runtime/interpreter/mterp/out/mterp_x86.S b/runtime/interpreter/mterp/out/mterp_x86.S
index 3f70919..32811ff 100644
--- a/runtime/interpreter/mterp/out/mterp_x86.S
+++ b/runtime/interpreter/mterp/out/mterp_x86.S
@@ -2120,832 +2120,694 @@
.balign 128
.L_op_iget: /* 0x52 */
/* File: x86/op_iget.S */
-/*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
- */
- EXPORT_PC
- movzwl 2(rPC), %eax # eax <- 0000CCCC
- movl %eax, OUT_ARG0(%esp) # field ref CCCC
- movzbl rINSTbl, %ecx # ecx <- BA
- sarl $4, %ecx # ecx <- B
- GET_VREG %ecx, %ecx
- movl %ecx, OUT_ARG1(%esp) # the object pointer
- movl OFF_FP_METHOD(rFP), %eax
- movl %eax, OUT_ARG2(%esp) # referrer
- mov rSELF, %ecx
- movl %ecx, OUT_ARG3(%esp) # self
+/* File: x86/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
+ .extern MterpIGetU32
+ REFRESH_INST 82 # fix rINST to include opcode
+ movl rPC, OUT_ARG0(%esp) # arg0: Instruction* inst
+ movl rINST, OUT_ARG1(%esp) # arg1: uint16_t inst_data
+ leal OFF_FP_SHADOWFRAME(rFP), %eax
+ movl %eax, OUT_ARG2(%esp) # arg2: ShadowFrame* sf
+ movl rSELF, %eax
+ movl %eax, OUT_ARG3(%esp) # arg3: Thread* self
call SYMBOL(MterpIGetU32)
- movl rSELF, %ecx
- RESTORE_IBASE_FROM_SELF %ecx
- cmpl $0, THREAD_EXCEPTION_OFFSET(%ecx)
- jnz MterpException # bail out
- andb $0xf, rINSTbl # rINST <- A
- .if 0
- SET_VREG_OBJECT %eax, rINST # fp[A] <-value
- .else
- SET_VREG %eax, rINST # fp[A] <-value
- .endif
+ testb %al, %al
+ jz MterpPossibleException
+ RESTORE_IBASE
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_iget_wide: /* 0x53 */
/* File: x86/op_iget_wide.S */
-/*
- * 64-bit instance field get.
- *
- * for: iget-wide
- */
- EXPORT_PC
- movzwl 2(rPC), %eax # eax <- 0000CCCC
- movl %eax, OUT_ARG0(%esp) # field ref CCCC
- movzbl rINSTbl, %ecx # ecx <- BA
- sarl $4, %ecx # ecx <- B
- GET_VREG %ecx, %ecx
- movl %ecx, OUT_ARG1(%esp) # the object pointer
- movl OFF_FP_METHOD(rFP), %eax
- movl %eax, OUT_ARG2(%esp) # referrer
- mov rSELF, %ecx
- movl %ecx, OUT_ARG3(%esp) # self
+/* File: x86/op_iget.S */
+/* File: x86/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
+ .extern MterpIGetU64
+ REFRESH_INST 83 # fix rINST to include opcode
+ movl rPC, OUT_ARG0(%esp) # arg0: Instruction* inst
+ movl rINST, OUT_ARG1(%esp) # arg1: uint16_t inst_data
+ leal OFF_FP_SHADOWFRAME(rFP), %eax
+ movl %eax, OUT_ARG2(%esp) # arg2: ShadowFrame* sf
+ movl rSELF, %eax
+ movl %eax, OUT_ARG3(%esp) # arg3: Thread* self
call SYMBOL(MterpIGetU64)
- mov rSELF, %ecx
- cmpl $0, THREAD_EXCEPTION_OFFSET(%ecx)
- jnz MterpException # bail out
- andb $0xf, rINSTbl # rINST <- A
- SET_VREG %eax, rINST
- SET_VREG_HIGH %edx, rINST
- RESTORE_IBASE_FROM_SELF %ecx
+ testb %al, %al
+ jz MterpPossibleException
+ RESTORE_IBASE
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+
/* ------------------------------ */
.balign 128
.L_op_iget_object: /* 0x54 */
/* File: x86/op_iget_object.S */
/* File: x86/op_iget.S */
-/*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
- */
- EXPORT_PC
- movzwl 2(rPC), %eax # eax <- 0000CCCC
- movl %eax, OUT_ARG0(%esp) # field ref CCCC
- movzbl rINSTbl, %ecx # ecx <- BA
- sarl $4, %ecx # ecx <- B
- GET_VREG %ecx, %ecx
- movl %ecx, OUT_ARG1(%esp) # the object pointer
- movl OFF_FP_METHOD(rFP), %eax
- movl %eax, OUT_ARG2(%esp) # referrer
- mov rSELF, %ecx
- movl %ecx, OUT_ARG3(%esp) # self
+/* File: x86/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
+ .extern MterpIGetObj
+ REFRESH_INST 84 # fix rINST to include opcode
+ movl rPC, OUT_ARG0(%esp) # arg0: Instruction* inst
+ movl rINST, OUT_ARG1(%esp) # arg1: uint16_t inst_data
+ leal OFF_FP_SHADOWFRAME(rFP), %eax
+ movl %eax, OUT_ARG2(%esp) # arg2: ShadowFrame* sf
+ movl rSELF, %eax
+ movl %eax, OUT_ARG3(%esp) # arg3: Thread* self
call SYMBOL(MterpIGetObj)
- movl rSELF, %ecx
- RESTORE_IBASE_FROM_SELF %ecx
- cmpl $0, THREAD_EXCEPTION_OFFSET(%ecx)
- jnz MterpException # bail out
- andb $0xf, rINSTbl # rINST <- A
- .if 1
- SET_VREG_OBJECT %eax, rINST # fp[A] <-value
- .else
- SET_VREG %eax, rINST # fp[A] <-value
- .endif
+ testb %al, %al
+ jz MterpPossibleException
+ RESTORE_IBASE
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_iget_boolean: /* 0x55 */
/* File: x86/op_iget_boolean.S */
/* File: x86/op_iget.S */
-/*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
- */
- EXPORT_PC
- movzwl 2(rPC), %eax # eax <- 0000CCCC
- movl %eax, OUT_ARG0(%esp) # field ref CCCC
- movzbl rINSTbl, %ecx # ecx <- BA
- sarl $4, %ecx # ecx <- B
- GET_VREG %ecx, %ecx
- movl %ecx, OUT_ARG1(%esp) # the object pointer
- movl OFF_FP_METHOD(rFP), %eax
- movl %eax, OUT_ARG2(%esp) # referrer
- mov rSELF, %ecx
- movl %ecx, OUT_ARG3(%esp) # self
+/* File: x86/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
+ .extern MterpIGetU8
+ REFRESH_INST 85 # fix rINST to include opcode
+ movl rPC, OUT_ARG0(%esp) # arg0: Instruction* inst
+ movl rINST, OUT_ARG1(%esp) # arg1: uint16_t inst_data
+ leal OFF_FP_SHADOWFRAME(rFP), %eax
+ movl %eax, OUT_ARG2(%esp) # arg2: ShadowFrame* sf
+ movl rSELF, %eax
+ movl %eax, OUT_ARG3(%esp) # arg3: Thread* self
call SYMBOL(MterpIGetU8)
- movl rSELF, %ecx
- RESTORE_IBASE_FROM_SELF %ecx
- cmpl $0, THREAD_EXCEPTION_OFFSET(%ecx)
- jnz MterpException # bail out
- andb $0xf, rINSTbl # rINST <- A
- .if 0
- SET_VREG_OBJECT %eax, rINST # fp[A] <-value
- .else
- SET_VREG %eax, rINST # fp[A] <-value
- .endif
+ testb %al, %al
+ jz MterpPossibleException
+ RESTORE_IBASE
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_iget_byte: /* 0x56 */
/* File: x86/op_iget_byte.S */
/* File: x86/op_iget.S */
-/*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
- */
- EXPORT_PC
- movzwl 2(rPC), %eax # eax <- 0000CCCC
- movl %eax, OUT_ARG0(%esp) # field ref CCCC
- movzbl rINSTbl, %ecx # ecx <- BA
- sarl $4, %ecx # ecx <- B
- GET_VREG %ecx, %ecx
- movl %ecx, OUT_ARG1(%esp) # the object pointer
- movl OFF_FP_METHOD(rFP), %eax
- movl %eax, OUT_ARG2(%esp) # referrer
- mov rSELF, %ecx
- movl %ecx, OUT_ARG3(%esp) # self
+/* File: x86/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
+ .extern MterpIGetI8
+ REFRESH_INST 86 # fix rINST to include opcode
+ movl rPC, OUT_ARG0(%esp) # arg0: Instruction* inst
+ movl rINST, OUT_ARG1(%esp) # arg1: uint16_t inst_data
+ leal OFF_FP_SHADOWFRAME(rFP), %eax
+ movl %eax, OUT_ARG2(%esp) # arg2: ShadowFrame* sf
+ movl rSELF, %eax
+ movl %eax, OUT_ARG3(%esp) # arg3: Thread* self
call SYMBOL(MterpIGetI8)
- movl rSELF, %ecx
- RESTORE_IBASE_FROM_SELF %ecx
- cmpl $0, THREAD_EXCEPTION_OFFSET(%ecx)
- jnz MterpException # bail out
- andb $0xf, rINSTbl # rINST <- A
- .if 0
- SET_VREG_OBJECT %eax, rINST # fp[A] <-value
- .else
- SET_VREG %eax, rINST # fp[A] <-value
- .endif
+ testb %al, %al
+ jz MterpPossibleException
+ RESTORE_IBASE
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_iget_char: /* 0x57 */
/* File: x86/op_iget_char.S */
/* File: x86/op_iget.S */
-/*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
- */
- EXPORT_PC
- movzwl 2(rPC), %eax # eax <- 0000CCCC
- movl %eax, OUT_ARG0(%esp) # field ref CCCC
- movzbl rINSTbl, %ecx # ecx <- BA
- sarl $4, %ecx # ecx <- B
- GET_VREG %ecx, %ecx
- movl %ecx, OUT_ARG1(%esp) # the object pointer
- movl OFF_FP_METHOD(rFP), %eax
- movl %eax, OUT_ARG2(%esp) # referrer
- mov rSELF, %ecx
- movl %ecx, OUT_ARG3(%esp) # self
+/* File: x86/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
+ .extern MterpIGetU16
+ REFRESH_INST 87 # fix rINST to include opcode
+ movl rPC, OUT_ARG0(%esp) # arg0: Instruction* inst
+ movl rINST, OUT_ARG1(%esp) # arg1: uint16_t inst_data
+ leal OFF_FP_SHADOWFRAME(rFP), %eax
+ movl %eax, OUT_ARG2(%esp) # arg2: ShadowFrame* sf
+ movl rSELF, %eax
+ movl %eax, OUT_ARG3(%esp) # arg3: Thread* self
call SYMBOL(MterpIGetU16)
- movl rSELF, %ecx
- RESTORE_IBASE_FROM_SELF %ecx
- cmpl $0, THREAD_EXCEPTION_OFFSET(%ecx)
- jnz MterpException # bail out
- andb $0xf, rINSTbl # rINST <- A
- .if 0
- SET_VREG_OBJECT %eax, rINST # fp[A] <-value
- .else
- SET_VREG %eax, rINST # fp[A] <-value
- .endif
+ testb %al, %al
+ jz MterpPossibleException
+ RESTORE_IBASE
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_iget_short: /* 0x58 */
/* File: x86/op_iget_short.S */
/* File: x86/op_iget.S */
-/*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
- */
- EXPORT_PC
- movzwl 2(rPC), %eax # eax <- 0000CCCC
- movl %eax, OUT_ARG0(%esp) # field ref CCCC
- movzbl rINSTbl, %ecx # ecx <- BA
- sarl $4, %ecx # ecx <- B
- GET_VREG %ecx, %ecx
- movl %ecx, OUT_ARG1(%esp) # the object pointer
- movl OFF_FP_METHOD(rFP), %eax
- movl %eax, OUT_ARG2(%esp) # referrer
- mov rSELF, %ecx
- movl %ecx, OUT_ARG3(%esp) # self
+/* File: x86/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
+ .extern MterpIGetI16
+ REFRESH_INST 88 # fix rINST to include opcode
+ movl rPC, OUT_ARG0(%esp) # arg0: Instruction* inst
+ movl rINST, OUT_ARG1(%esp) # arg1: uint16_t inst_data
+ leal OFF_FP_SHADOWFRAME(rFP), %eax
+ movl %eax, OUT_ARG2(%esp) # arg2: ShadowFrame* sf
+ movl rSELF, %eax
+ movl %eax, OUT_ARG3(%esp) # arg3: Thread* self
call SYMBOL(MterpIGetI16)
- movl rSELF, %ecx
- RESTORE_IBASE_FROM_SELF %ecx
- cmpl $0, THREAD_EXCEPTION_OFFSET(%ecx)
- jnz MterpException # bail out
- andb $0xf, rINSTbl # rINST <- A
- .if 0
- SET_VREG_OBJECT %eax, rINST # fp[A] <-value
- .else
- SET_VREG %eax, rINST # fp[A] <-value
- .endif
+ testb %al, %al
+ jz MterpPossibleException
+ RESTORE_IBASE
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_iput: /* 0x59 */
/* File: x86/op_iput.S */
-/*
- * General 32-bit instance field put.
- *
- * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
- */
- /* op vA, vB, field@CCCC */
+/* File: x86/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpIPutU32
- EXPORT_PC
- movzwl 2(rPC), %eax # eax<- 0000CCCC
- movl %eax, OUT_ARG0(%esp) # field ref CCCC
- movzbl rINSTbl, %ecx # ecx<- BA
- sarl $4, %ecx # ecx<- B
- GET_VREG %ecx, %ecx
- movl %ecx, OUT_ARG1(%esp) # the object pointer
- andb $0xf, rINSTbl # rINST<- A
- GET_VREG %eax, rINST
- movl %eax, OUT_ARG2(%esp) # fp[A]
- movl OFF_FP_METHOD(rFP), %eax
- movl %eax, OUT_ARG3(%esp) # referrer
+ REFRESH_INST 89 # fix rINST to include opcode
+ movl rPC, OUT_ARG0(%esp) # arg0: Instruction* inst
+ movl rINST, OUT_ARG1(%esp) # arg1: uint16_t inst_data
+ leal OFF_FP_SHADOWFRAME(rFP), %eax
+ movl %eax, OUT_ARG2(%esp) # arg2: ShadowFrame* sf
+ movl rSELF, %eax
+ movl %eax, OUT_ARG3(%esp) # arg3: Thread* self
call SYMBOL(MterpIPutU32)
testb %al, %al
- jnz MterpPossibleException
+ jz MterpPossibleException
RESTORE_IBASE
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_iput_wide: /* 0x5a */
/* File: x86/op_iput_wide.S */
- /* iput-wide vA, vB, field@CCCC */
+/* File: x86/op_iput.S */
+/* File: x86/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpIPutU64
- EXPORT_PC
- movzwl 2(rPC), %eax # eax <- 0000CCCC
- movl %eax, OUT_ARG0(%esp) # field ref CCCC
- movzbl rINSTbl,%ecx # ecx <- BA
- sarl $4,%ecx # ecx <- B
- GET_VREG %ecx, %ecx
- movl %ecx, OUT_ARG1(%esp) # the object pointer
- andb $0xf,rINSTbl # rINST <- A
- leal VREG_ADDRESS(rINST), %eax
- movl %eax, OUT_ARG2(%esp) # &fp[A]
- movl OFF_FP_METHOD(rFP), %eax
- movl %eax, OUT_ARG3(%esp) # referrer
+ REFRESH_INST 90 # fix rINST to include opcode
+ movl rPC, OUT_ARG0(%esp) # arg0: Instruction* inst
+ movl rINST, OUT_ARG1(%esp) # arg1: uint16_t inst_data
+ leal OFF_FP_SHADOWFRAME(rFP), %eax
+ movl %eax, OUT_ARG2(%esp) # arg2: ShadowFrame* sf
+ movl rSELF, %eax
+ movl %eax, OUT_ARG3(%esp) # arg3: Thread* self
call SYMBOL(MterpIPutU64)
testb %al, %al
- jnz MterpPossibleException
+ jz MterpPossibleException
RESTORE_IBASE
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+
/* ------------------------------ */
.balign 128
.L_op_iput_object: /* 0x5b */
/* File: x86/op_iput_object.S */
- EXPORT_PC
+/* File: x86/op_iput.S */
+/* File: x86/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
+ .extern MterpIPutObj
+ REFRESH_INST 91 # fix rINST to include opcode
+ movl rPC, OUT_ARG0(%esp) # arg0: Instruction* inst
+ movl rINST, OUT_ARG1(%esp) # arg1: uint16_t inst_data
leal OFF_FP_SHADOWFRAME(rFP), %eax
- movl %eax, OUT_ARG0(%esp)
- movl rPC, OUT_ARG1(%esp)
- REFRESH_INST 91
- movl rINST, OUT_ARG2(%esp)
+ movl %eax, OUT_ARG2(%esp) # arg2: ShadowFrame* sf
movl rSELF, %eax
- movl %eax, OUT_ARG3(%esp)
+ movl %eax, OUT_ARG3(%esp) # arg3: Thread* self
call SYMBOL(MterpIPutObj)
testb %al, %al
- jz MterpException
+ jz MterpPossibleException
RESTORE_IBASE
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+
/* ------------------------------ */
.balign 128
.L_op_iput_boolean: /* 0x5c */
/* File: x86/op_iput_boolean.S */
/* File: x86/op_iput.S */
-/*
- * General 32-bit instance field put.
- *
- * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
- */
- /* op vA, vB, field@CCCC */
+/* File: x86/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpIPutU8
- EXPORT_PC
- movzwl 2(rPC), %eax # eax<- 0000CCCC
- movl %eax, OUT_ARG0(%esp) # field ref CCCC
- movzbl rINSTbl, %ecx # ecx<- BA
- sarl $4, %ecx # ecx<- B
- GET_VREG %ecx, %ecx
- movl %ecx, OUT_ARG1(%esp) # the object pointer
- andb $0xf, rINSTbl # rINST<- A
- GET_VREG %eax, rINST
- movl %eax, OUT_ARG2(%esp) # fp[A]
- movl OFF_FP_METHOD(rFP), %eax
- movl %eax, OUT_ARG3(%esp) # referrer
+ REFRESH_INST 92 # fix rINST to include opcode
+ movl rPC, OUT_ARG0(%esp) # arg0: Instruction* inst
+ movl rINST, OUT_ARG1(%esp) # arg1: uint16_t inst_data
+ leal OFF_FP_SHADOWFRAME(rFP), %eax
+ movl %eax, OUT_ARG2(%esp) # arg2: ShadowFrame* sf
+ movl rSELF, %eax
+ movl %eax, OUT_ARG3(%esp) # arg3: Thread* self
call SYMBOL(MterpIPutU8)
testb %al, %al
- jnz MterpPossibleException
+ jz MterpPossibleException
RESTORE_IBASE
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_iput_byte: /* 0x5d */
/* File: x86/op_iput_byte.S */
/* File: x86/op_iput.S */
-/*
- * General 32-bit instance field put.
- *
- * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
- */
- /* op vA, vB, field@CCCC */
+/* File: x86/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpIPutI8
- EXPORT_PC
- movzwl 2(rPC), %eax # eax<- 0000CCCC
- movl %eax, OUT_ARG0(%esp) # field ref CCCC
- movzbl rINSTbl, %ecx # ecx<- BA
- sarl $4, %ecx # ecx<- B
- GET_VREG %ecx, %ecx
- movl %ecx, OUT_ARG1(%esp) # the object pointer
- andb $0xf, rINSTbl # rINST<- A
- GET_VREG %eax, rINST
- movl %eax, OUT_ARG2(%esp) # fp[A]
- movl OFF_FP_METHOD(rFP), %eax
- movl %eax, OUT_ARG3(%esp) # referrer
+ REFRESH_INST 93 # fix rINST to include opcode
+ movl rPC, OUT_ARG0(%esp) # arg0: Instruction* inst
+ movl rINST, OUT_ARG1(%esp) # arg1: uint16_t inst_data
+ leal OFF_FP_SHADOWFRAME(rFP), %eax
+ movl %eax, OUT_ARG2(%esp) # arg2: ShadowFrame* sf
+ movl rSELF, %eax
+ movl %eax, OUT_ARG3(%esp) # arg3: Thread* self
call SYMBOL(MterpIPutI8)
testb %al, %al
- jnz MterpPossibleException
+ jz MterpPossibleException
RESTORE_IBASE
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_iput_char: /* 0x5e */
/* File: x86/op_iput_char.S */
/* File: x86/op_iput.S */
-/*
- * General 32-bit instance field put.
- *
- * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
- */
- /* op vA, vB, field@CCCC */
+/* File: x86/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpIPutU16
- EXPORT_PC
- movzwl 2(rPC), %eax # eax<- 0000CCCC
- movl %eax, OUT_ARG0(%esp) # field ref CCCC
- movzbl rINSTbl, %ecx # ecx<- BA
- sarl $4, %ecx # ecx<- B
- GET_VREG %ecx, %ecx
- movl %ecx, OUT_ARG1(%esp) # the object pointer
- andb $0xf, rINSTbl # rINST<- A
- GET_VREG %eax, rINST
- movl %eax, OUT_ARG2(%esp) # fp[A]
- movl OFF_FP_METHOD(rFP), %eax
- movl %eax, OUT_ARG3(%esp) # referrer
+ REFRESH_INST 94 # fix rINST to include opcode
+ movl rPC, OUT_ARG0(%esp) # arg0: Instruction* inst
+ movl rINST, OUT_ARG1(%esp) # arg1: uint16_t inst_data
+ leal OFF_FP_SHADOWFRAME(rFP), %eax
+ movl %eax, OUT_ARG2(%esp) # arg2: ShadowFrame* sf
+ movl rSELF, %eax
+ movl %eax, OUT_ARG3(%esp) # arg3: Thread* self
call SYMBOL(MterpIPutU16)
testb %al, %al
- jnz MterpPossibleException
+ jz MterpPossibleException
RESTORE_IBASE
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_iput_short: /* 0x5f */
/* File: x86/op_iput_short.S */
/* File: x86/op_iput.S */
-/*
- * General 32-bit instance field put.
- *
- * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
- */
- /* op vA, vB, field@CCCC */
+/* File: x86/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpIPutI16
- EXPORT_PC
- movzwl 2(rPC), %eax # eax<- 0000CCCC
- movl %eax, OUT_ARG0(%esp) # field ref CCCC
- movzbl rINSTbl, %ecx # ecx<- BA
- sarl $4, %ecx # ecx<- B
- GET_VREG %ecx, %ecx
- movl %ecx, OUT_ARG1(%esp) # the object pointer
- andb $0xf, rINSTbl # rINST<- A
- GET_VREG %eax, rINST
- movl %eax, OUT_ARG2(%esp) # fp[A]
- movl OFF_FP_METHOD(rFP), %eax
- movl %eax, OUT_ARG3(%esp) # referrer
+ REFRESH_INST 95 # fix rINST to include opcode
+ movl rPC, OUT_ARG0(%esp) # arg0: Instruction* inst
+ movl rINST, OUT_ARG1(%esp) # arg1: uint16_t inst_data
+ leal OFF_FP_SHADOWFRAME(rFP), %eax
+ movl %eax, OUT_ARG2(%esp) # arg2: ShadowFrame* sf
+ movl rSELF, %eax
+ movl %eax, OUT_ARG3(%esp) # arg3: Thread* self
call SYMBOL(MterpIPutI16)
testb %al, %al
- jnz MterpPossibleException
+ jz MterpPossibleException
RESTORE_IBASE
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_sget: /* 0x60 */
/* File: x86/op_sget.S */
-/*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
- */
- /* op vAA, field@BBBB */
+/* File: x86/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpSGetU32
- EXPORT_PC
- movzwl 2(rPC), %eax
- movl %eax, OUT_ARG0(%esp) # field ref CCCC
- movl OFF_FP_METHOD(rFP), %eax
- movl %eax, OUT_ARG1(%esp) # referrer
- movl rSELF, %ecx
- movl %ecx, OUT_ARG2(%esp) # self
+ REFRESH_INST 96 # fix rINST to include opcode
+ movl rPC, OUT_ARG0(%esp) # arg0: Instruction* inst
+ movl rINST, OUT_ARG1(%esp) # arg1: uint16_t inst_data
+ leal OFF_FP_SHADOWFRAME(rFP), %eax
+ movl %eax, OUT_ARG2(%esp) # arg2: ShadowFrame* sf
+ movl rSELF, %eax
+ movl %eax, OUT_ARG3(%esp) # arg3: Thread* self
call SYMBOL(MterpSGetU32)
- movl rSELF, %ecx
- RESTORE_IBASE_FROM_SELF %ecx
- cmpl $0, THREAD_EXCEPTION_OFFSET(%ecx)
- jnz MterpException
- .if 0
- SET_VREG_OBJECT %eax, rINST # fp[A] <- value
- .else
- SET_VREG %eax, rINST # fp[A] <- value
- .endif
+ testb %al, %al
+ jz MterpPossibleException
+ RESTORE_IBASE
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_sget_wide: /* 0x61 */
/* File: x86/op_sget_wide.S */
-/*
- * SGET_WIDE handler wrapper.
- *
- */
- /* sget-wide vAA, field@BBBB */
+/* File: x86/op_sget.S */
+/* File: x86/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpSGetU64
- EXPORT_PC
- movzwl 2(rPC), %eax
- movl %eax, OUT_ARG0(%esp) # field ref CCCC
- movl OFF_FP_METHOD(rFP), %eax
- movl %eax, OUT_ARG1(%esp) # referrer
- movl rSELF, %ecx
- movl %ecx, OUT_ARG2(%esp) # self
+ REFRESH_INST 97 # fix rINST to include opcode
+ movl rPC, OUT_ARG0(%esp) # arg0: Instruction* inst
+ movl rINST, OUT_ARG1(%esp) # arg1: uint16_t inst_data
+ leal OFF_FP_SHADOWFRAME(rFP), %eax
+ movl %eax, OUT_ARG2(%esp) # arg2: ShadowFrame* sf
+ movl rSELF, %eax
+ movl %eax, OUT_ARG3(%esp) # arg3: Thread* self
call SYMBOL(MterpSGetU64)
- movl rSELF, %ecx
- cmpl $0, THREAD_EXCEPTION_OFFSET(%ecx)
- jnz MterpException
- SET_VREG %eax, rINST # fp[A]<- low part
- SET_VREG_HIGH %edx, rINST # fp[A+1]<- high part
- RESTORE_IBASE_FROM_SELF %ecx
+ testb %al, %al
+ jz MterpPossibleException
+ RESTORE_IBASE
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+
/* ------------------------------ */
.balign 128
.L_op_sget_object: /* 0x62 */
/* File: x86/op_sget_object.S */
/* File: x86/op_sget.S */
-/*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
- */
- /* op vAA, field@BBBB */
+/* File: x86/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpSGetObj
- EXPORT_PC
- movzwl 2(rPC), %eax
- movl %eax, OUT_ARG0(%esp) # field ref CCCC
- movl OFF_FP_METHOD(rFP), %eax
- movl %eax, OUT_ARG1(%esp) # referrer
- movl rSELF, %ecx
- movl %ecx, OUT_ARG2(%esp) # self
+ REFRESH_INST 98 # fix rINST to include opcode
+ movl rPC, OUT_ARG0(%esp) # arg0: Instruction* inst
+ movl rINST, OUT_ARG1(%esp) # arg1: uint16_t inst_data
+ leal OFF_FP_SHADOWFRAME(rFP), %eax
+ movl %eax, OUT_ARG2(%esp) # arg2: ShadowFrame* sf
+ movl rSELF, %eax
+ movl %eax, OUT_ARG3(%esp) # arg3: Thread* self
call SYMBOL(MterpSGetObj)
- movl rSELF, %ecx
- RESTORE_IBASE_FROM_SELF %ecx
- cmpl $0, THREAD_EXCEPTION_OFFSET(%ecx)
- jnz MterpException
- .if 1
- SET_VREG_OBJECT %eax, rINST # fp[A] <- value
- .else
- SET_VREG %eax, rINST # fp[A] <- value
- .endif
+ testb %al, %al
+ jz MterpPossibleException
+ RESTORE_IBASE
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_sget_boolean: /* 0x63 */
/* File: x86/op_sget_boolean.S */
/* File: x86/op_sget.S */
-/*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
- */
- /* op vAA, field@BBBB */
+/* File: x86/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpSGetU8
- EXPORT_PC
- movzwl 2(rPC), %eax
- movl %eax, OUT_ARG0(%esp) # field ref CCCC
- movl OFF_FP_METHOD(rFP), %eax
- movl %eax, OUT_ARG1(%esp) # referrer
- movl rSELF, %ecx
- movl %ecx, OUT_ARG2(%esp) # self
+ REFRESH_INST 99 # fix rINST to include opcode
+ movl rPC, OUT_ARG0(%esp) # arg0: Instruction* inst
+ movl rINST, OUT_ARG1(%esp) # arg1: uint16_t inst_data
+ leal OFF_FP_SHADOWFRAME(rFP), %eax
+ movl %eax, OUT_ARG2(%esp) # arg2: ShadowFrame* sf
+ movl rSELF, %eax
+ movl %eax, OUT_ARG3(%esp) # arg3: Thread* self
call SYMBOL(MterpSGetU8)
- movl rSELF, %ecx
- RESTORE_IBASE_FROM_SELF %ecx
- cmpl $0, THREAD_EXCEPTION_OFFSET(%ecx)
- jnz MterpException
- .if 0
- SET_VREG_OBJECT %eax, rINST # fp[A] <- value
- .else
- SET_VREG %eax, rINST # fp[A] <- value
- .endif
+ testb %al, %al
+ jz MterpPossibleException
+ RESTORE_IBASE
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_sget_byte: /* 0x64 */
/* File: x86/op_sget_byte.S */
/* File: x86/op_sget.S */
-/*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
- */
- /* op vAA, field@BBBB */
+/* File: x86/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpSGetI8
- EXPORT_PC
- movzwl 2(rPC), %eax
- movl %eax, OUT_ARG0(%esp) # field ref CCCC
- movl OFF_FP_METHOD(rFP), %eax
- movl %eax, OUT_ARG1(%esp) # referrer
- movl rSELF, %ecx
- movl %ecx, OUT_ARG2(%esp) # self
+ REFRESH_INST 100 # fix rINST to include opcode
+ movl rPC, OUT_ARG0(%esp) # arg0: Instruction* inst
+ movl rINST, OUT_ARG1(%esp) # arg1: uint16_t inst_data
+ leal OFF_FP_SHADOWFRAME(rFP), %eax
+ movl %eax, OUT_ARG2(%esp) # arg2: ShadowFrame* sf
+ movl rSELF, %eax
+ movl %eax, OUT_ARG3(%esp) # arg3: Thread* self
call SYMBOL(MterpSGetI8)
- movl rSELF, %ecx
- RESTORE_IBASE_FROM_SELF %ecx
- cmpl $0, THREAD_EXCEPTION_OFFSET(%ecx)
- jnz MterpException
- .if 0
- SET_VREG_OBJECT %eax, rINST # fp[A] <- value
- .else
- SET_VREG %eax, rINST # fp[A] <- value
- .endif
+ testb %al, %al
+ jz MterpPossibleException
+ RESTORE_IBASE
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_sget_char: /* 0x65 */
/* File: x86/op_sget_char.S */
/* File: x86/op_sget.S */
-/*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
- */
- /* op vAA, field@BBBB */
+/* File: x86/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpSGetU16
- EXPORT_PC
- movzwl 2(rPC), %eax
- movl %eax, OUT_ARG0(%esp) # field ref CCCC
- movl OFF_FP_METHOD(rFP), %eax
- movl %eax, OUT_ARG1(%esp) # referrer
- movl rSELF, %ecx
- movl %ecx, OUT_ARG2(%esp) # self
+ REFRESH_INST 101 # fix rINST to include opcode
+ movl rPC, OUT_ARG0(%esp) # arg0: Instruction* inst
+ movl rINST, OUT_ARG1(%esp) # arg1: uint16_t inst_data
+ leal OFF_FP_SHADOWFRAME(rFP), %eax
+ movl %eax, OUT_ARG2(%esp) # arg2: ShadowFrame* sf
+ movl rSELF, %eax
+ movl %eax, OUT_ARG3(%esp) # arg3: Thread* self
call SYMBOL(MterpSGetU16)
- movl rSELF, %ecx
- RESTORE_IBASE_FROM_SELF %ecx
- cmpl $0, THREAD_EXCEPTION_OFFSET(%ecx)
- jnz MterpException
- .if 0
- SET_VREG_OBJECT %eax, rINST # fp[A] <- value
- .else
- SET_VREG %eax, rINST # fp[A] <- value
- .endif
+ testb %al, %al
+ jz MterpPossibleException
+ RESTORE_IBASE
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_sget_short: /* 0x66 */
/* File: x86/op_sget_short.S */
/* File: x86/op_sget.S */
-/*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
- */
- /* op vAA, field@BBBB */
+/* File: x86/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpSGetI16
- EXPORT_PC
- movzwl 2(rPC), %eax
- movl %eax, OUT_ARG0(%esp) # field ref CCCC
- movl OFF_FP_METHOD(rFP), %eax
- movl %eax, OUT_ARG1(%esp) # referrer
- movl rSELF, %ecx
- movl %ecx, OUT_ARG2(%esp) # self
+ REFRESH_INST 102 # fix rINST to include opcode
+ movl rPC, OUT_ARG0(%esp) # arg0: Instruction* inst
+ movl rINST, OUT_ARG1(%esp) # arg1: uint16_t inst_data
+ leal OFF_FP_SHADOWFRAME(rFP), %eax
+ movl %eax, OUT_ARG2(%esp) # arg2: ShadowFrame* sf
+ movl rSELF, %eax
+ movl %eax, OUT_ARG3(%esp) # arg3: Thread* self
call SYMBOL(MterpSGetI16)
- movl rSELF, %ecx
- RESTORE_IBASE_FROM_SELF %ecx
- cmpl $0, THREAD_EXCEPTION_OFFSET(%ecx)
- jnz MterpException
- .if 0
- SET_VREG_OBJECT %eax, rINST # fp[A] <- value
- .else
- SET_VREG %eax, rINST # fp[A] <- value
- .endif
+ testb %al, %al
+ jz MterpPossibleException
+ RESTORE_IBASE
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_sput: /* 0x67 */
/* File: x86/op_sput.S */
-/*
- * General SPUT handler wrapper.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
- */
- /* op vAA, field@BBBB */
+/* File: x86/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpSPutU32
- EXPORT_PC
- movzwl 2(rPC), %eax
- movl %eax, OUT_ARG0(%esp) # field ref BBBB
- GET_VREG rINST, rINST
- movl rINST, OUT_ARG1(%esp) # fp[AA]
- movl OFF_FP_METHOD(rFP), %eax
- movl %eax, OUT_ARG2(%esp) # referrer
- movl rSELF, %ecx
- movl %ecx, OUT_ARG3(%esp) # self
+ REFRESH_INST 103 # fix rINST to include opcode
+ movl rPC, OUT_ARG0(%esp) # arg0: Instruction* inst
+ movl rINST, OUT_ARG1(%esp) # arg1: uint16_t inst_data
+ leal OFF_FP_SHADOWFRAME(rFP), %eax
+ movl %eax, OUT_ARG2(%esp) # arg2: ShadowFrame* sf
+ movl rSELF, %eax
+ movl %eax, OUT_ARG3(%esp) # arg3: Thread* self
call SYMBOL(MterpSPutU32)
testb %al, %al
- jnz MterpException
+ jz MterpPossibleException
RESTORE_IBASE
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_sput_wide: /* 0x68 */
/* File: x86/op_sput_wide.S */
-/*
- * SPUT_WIDE handler wrapper.
- *
- */
- /* sput-wide vAA, field@BBBB */
+/* File: x86/op_sput.S */
+/* File: x86/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpSPutU64
- EXPORT_PC
- movzwl 2(rPC), %eax
- movl %eax, OUT_ARG0(%esp) # field ref BBBB
- leal VREG_ADDRESS(rINST), %eax
- movl %eax, OUT_ARG1(%esp) # &fp[AA]
- movl OFF_FP_METHOD(rFP), %eax
- movl %eax, OUT_ARG2(%esp) # referrer
- movl rSELF, %ecx
- movl %ecx, OUT_ARG3(%esp) # self
+ REFRESH_INST 104 # fix rINST to include opcode
+ movl rPC, OUT_ARG0(%esp) # arg0: Instruction* inst
+ movl rINST, OUT_ARG1(%esp) # arg1: uint16_t inst_data
+ leal OFF_FP_SHADOWFRAME(rFP), %eax
+ movl %eax, OUT_ARG2(%esp) # arg2: ShadowFrame* sf
+ movl rSELF, %eax
+ movl %eax, OUT_ARG3(%esp) # arg3: Thread* self
call SYMBOL(MterpSPutU64)
testb %al, %al
- jnz MterpException
+ jz MterpPossibleException
RESTORE_IBASE
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+
/* ------------------------------ */
.balign 128
.L_op_sput_object: /* 0x69 */
/* File: x86/op_sput_object.S */
- EXPORT_PC
+/* File: x86/op_sput.S */
+/* File: x86/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
+ .extern MterpSPutObj
+ REFRESH_INST 105 # fix rINST to include opcode
+ movl rPC, OUT_ARG0(%esp) # arg0: Instruction* inst
+ movl rINST, OUT_ARG1(%esp) # arg1: uint16_t inst_data
leal OFF_FP_SHADOWFRAME(rFP), %eax
- movl %eax, OUT_ARG0(%esp)
- movl rPC, OUT_ARG1(%esp)
- REFRESH_INST 105
- movl rINST, OUT_ARG2(%esp)
- movl rSELF, %ecx
- movl %ecx, OUT_ARG3(%esp)
+ movl %eax, OUT_ARG2(%esp) # arg2: ShadowFrame* sf
+ movl rSELF, %eax
+ movl %eax, OUT_ARG3(%esp) # arg3: Thread* self
call SYMBOL(MterpSPutObj)
testb %al, %al
- jz MterpException
+ jz MterpPossibleException
RESTORE_IBASE
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+
/* ------------------------------ */
.balign 128
.L_op_sput_boolean: /* 0x6a */
/* File: x86/op_sput_boolean.S */
/* File: x86/op_sput.S */
-/*
- * General SPUT handler wrapper.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
- */
- /* op vAA, field@BBBB */
+/* File: x86/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpSPutU8
- EXPORT_PC
- movzwl 2(rPC), %eax
- movl %eax, OUT_ARG0(%esp) # field ref BBBB
- GET_VREG rINST, rINST
- movl rINST, OUT_ARG1(%esp) # fp[AA]
- movl OFF_FP_METHOD(rFP), %eax
- movl %eax, OUT_ARG2(%esp) # referrer
- movl rSELF, %ecx
- movl %ecx, OUT_ARG3(%esp) # self
+ REFRESH_INST 106 # fix rINST to include opcode
+ movl rPC, OUT_ARG0(%esp) # arg0: Instruction* inst
+ movl rINST, OUT_ARG1(%esp) # arg1: uint16_t inst_data
+ leal OFF_FP_SHADOWFRAME(rFP), %eax
+ movl %eax, OUT_ARG2(%esp) # arg2: ShadowFrame* sf
+ movl rSELF, %eax
+ movl %eax, OUT_ARG3(%esp) # arg3: Thread* self
call SYMBOL(MterpSPutU8)
testb %al, %al
- jnz MterpException
+ jz MterpPossibleException
RESTORE_IBASE
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_sput_byte: /* 0x6b */
/* File: x86/op_sput_byte.S */
/* File: x86/op_sput.S */
-/*
- * General SPUT handler wrapper.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
- */
- /* op vAA, field@BBBB */
+/* File: x86/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpSPutI8
- EXPORT_PC
- movzwl 2(rPC), %eax
- movl %eax, OUT_ARG0(%esp) # field ref BBBB
- GET_VREG rINST, rINST
- movl rINST, OUT_ARG1(%esp) # fp[AA]
- movl OFF_FP_METHOD(rFP), %eax
- movl %eax, OUT_ARG2(%esp) # referrer
- movl rSELF, %ecx
- movl %ecx, OUT_ARG3(%esp) # self
+ REFRESH_INST 107 # fix rINST to include opcode
+ movl rPC, OUT_ARG0(%esp) # arg0: Instruction* inst
+ movl rINST, OUT_ARG1(%esp) # arg1: uint16_t inst_data
+ leal OFF_FP_SHADOWFRAME(rFP), %eax
+ movl %eax, OUT_ARG2(%esp) # arg2: ShadowFrame* sf
+ movl rSELF, %eax
+ movl %eax, OUT_ARG3(%esp) # arg3: Thread* self
call SYMBOL(MterpSPutI8)
testb %al, %al
- jnz MterpException
+ jz MterpPossibleException
RESTORE_IBASE
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_sput_char: /* 0x6c */
/* File: x86/op_sput_char.S */
/* File: x86/op_sput.S */
-/*
- * General SPUT handler wrapper.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
- */
- /* op vAA, field@BBBB */
+/* File: x86/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpSPutU16
- EXPORT_PC
- movzwl 2(rPC), %eax
- movl %eax, OUT_ARG0(%esp) # field ref BBBB
- GET_VREG rINST, rINST
- movl rINST, OUT_ARG1(%esp) # fp[AA]
- movl OFF_FP_METHOD(rFP), %eax
- movl %eax, OUT_ARG2(%esp) # referrer
- movl rSELF, %ecx
- movl %ecx, OUT_ARG3(%esp) # self
+ REFRESH_INST 108 # fix rINST to include opcode
+ movl rPC, OUT_ARG0(%esp) # arg0: Instruction* inst
+ movl rINST, OUT_ARG1(%esp) # arg1: uint16_t inst_data
+ leal OFF_FP_SHADOWFRAME(rFP), %eax
+ movl %eax, OUT_ARG2(%esp) # arg2: ShadowFrame* sf
+ movl rSELF, %eax
+ movl %eax, OUT_ARG3(%esp) # arg3: Thread* self
call SYMBOL(MterpSPutU16)
testb %al, %al
- jnz MterpException
+ jz MterpPossibleException
RESTORE_IBASE
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_sput_short: /* 0x6d */
/* File: x86/op_sput_short.S */
/* File: x86/op_sput.S */
-/*
- * General SPUT handler wrapper.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
- */
- /* op vAA, field@BBBB */
+/* File: x86/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpSPutI16
- EXPORT_PC
- movzwl 2(rPC), %eax
- movl %eax, OUT_ARG0(%esp) # field ref BBBB
- GET_VREG rINST, rINST
- movl rINST, OUT_ARG1(%esp) # fp[AA]
- movl OFF_FP_METHOD(rFP), %eax
- movl %eax, OUT_ARG2(%esp) # referrer
- movl rSELF, %ecx
- movl %ecx, OUT_ARG3(%esp) # self
+ REFRESH_INST 109 # fix rINST to include opcode
+ movl rPC, OUT_ARG0(%esp) # arg0: Instruction* inst
+ movl rINST, OUT_ARG1(%esp) # arg1: uint16_t inst_data
+ leal OFF_FP_SHADOWFRAME(rFP), %eax
+ movl %eax, OUT_ARG2(%esp) # arg2: ShadowFrame* sf
+ movl rSELF, %eax
+ movl %eax, OUT_ARG3(%esp) # arg3: Thread* self
call SYMBOL(MterpSPutI16)
testb %al, %al
- jnz MterpException
+ jz MterpPossibleException
RESTORE_IBASE
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_invoke_virtual: /* 0x6e */
diff --git a/runtime/interpreter/mterp/out/mterp_x86_64.S b/runtime/interpreter/mterp/out/mterp_x86_64.S
index 89d5637..6d8bb4c 100644
--- a/runtime/interpreter/mterp/out/mterp_x86_64.S
+++ b/runtime/interpreter/mterp/out/mterp_x86_64.S
@@ -2067,770 +2067,610 @@
.balign 128
.L_op_iget: /* 0x52 */
/* File: x86_64/op_iget.S */
-/*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short, iget-wide
- */
- EXPORT_PC
- movzbq rINSTbl, %rcx # rcx <- BA
- movzwl 2(rPC), OUT_32_ARG0 # eax <- field ref CCCC
- sarl $4, %ecx # ecx <- B
- GET_VREG OUT_32_ARG1, %rcx # the object pointer
- movq OFF_FP_METHOD(rFP), OUT_ARG2 # referrer
- movq rSELF, OUT_ARG3
+/* File: x86_64/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
+ .extern MterpIGetU32
+ REFRESH_INST 82 # fix rINST to include opcode
+ movq rPC, OUT_ARG0 # arg0: Instruction* inst
+ movl rINST, OUT_32_ARG1 # arg1: uint16_t inst_data
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG2 # arg2: ShadowFrame* sf
+ movq rSELF, OUT_ARG3 # arg3: Thread* self
call SYMBOL(MterpIGetU32)
- movq rSELF, %rcx
- cmpq $0, THREAD_EXCEPTION_OFFSET(%rcx)
- jnz MterpException # bail out
- andb $0xf, rINSTbl # rINST <- A
- .if 0
- SET_VREG_OBJECT %eax, rINSTq # fp[A] <-value
- .else
- .if 0
- SET_WIDE_VREG %rax, rINSTq # fp[A] <-value
- .else
- SET_VREG %eax, rINSTq # fp[A] <-value
- .endif
- .endif
+ testb %al, %al
+ jz MterpPossibleException
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_iget_wide: /* 0x53 */
/* File: x86_64/op_iget_wide.S */
/* File: x86_64/op_iget.S */
-/*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short, iget-wide
- */
- EXPORT_PC
- movzbq rINSTbl, %rcx # rcx <- BA
- movzwl 2(rPC), OUT_32_ARG0 # eax <- field ref CCCC
- sarl $4, %ecx # ecx <- B
- GET_VREG OUT_32_ARG1, %rcx # the object pointer
- movq OFF_FP_METHOD(rFP), OUT_ARG2 # referrer
- movq rSELF, OUT_ARG3
+/* File: x86_64/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
+ .extern MterpIGetU64
+ REFRESH_INST 83 # fix rINST to include opcode
+ movq rPC, OUT_ARG0 # arg0: Instruction* inst
+ movl rINST, OUT_32_ARG1 # arg1: uint16_t inst_data
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG2 # arg2: ShadowFrame* sf
+ movq rSELF, OUT_ARG3 # arg3: Thread* self
call SYMBOL(MterpIGetU64)
- movq rSELF, %rcx
- cmpq $0, THREAD_EXCEPTION_OFFSET(%rcx)
- jnz MterpException # bail out
- andb $0xf, rINSTbl # rINST <- A
- .if 0
- SET_VREG_OBJECT %eax, rINSTq # fp[A] <-value
- .else
- .if 1
- SET_WIDE_VREG %rax, rINSTq # fp[A] <-value
- .else
- SET_VREG %eax, rINSTq # fp[A] <-value
- .endif
- .endif
+ testb %al, %al
+ jz MterpPossibleException
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_iget_object: /* 0x54 */
/* File: x86_64/op_iget_object.S */
/* File: x86_64/op_iget.S */
-/*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short, iget-wide
- */
- EXPORT_PC
- movzbq rINSTbl, %rcx # rcx <- BA
- movzwl 2(rPC), OUT_32_ARG0 # eax <- field ref CCCC
- sarl $4, %ecx # ecx <- B
- GET_VREG OUT_32_ARG1, %rcx # the object pointer
- movq OFF_FP_METHOD(rFP), OUT_ARG2 # referrer
- movq rSELF, OUT_ARG3
+/* File: x86_64/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
+ .extern MterpIGetObj
+ REFRESH_INST 84 # fix rINST to include opcode
+ movq rPC, OUT_ARG0 # arg0: Instruction* inst
+ movl rINST, OUT_32_ARG1 # arg1: uint16_t inst_data
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG2 # arg2: ShadowFrame* sf
+ movq rSELF, OUT_ARG3 # arg3: Thread* self
call SYMBOL(MterpIGetObj)
- movq rSELF, %rcx
- cmpq $0, THREAD_EXCEPTION_OFFSET(%rcx)
- jnz MterpException # bail out
- andb $0xf, rINSTbl # rINST <- A
- .if 1
- SET_VREG_OBJECT %eax, rINSTq # fp[A] <-value
- .else
- .if 0
- SET_WIDE_VREG %rax, rINSTq # fp[A] <-value
- .else
- SET_VREG %eax, rINSTq # fp[A] <-value
- .endif
- .endif
+ testb %al, %al
+ jz MterpPossibleException
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_iget_boolean: /* 0x55 */
/* File: x86_64/op_iget_boolean.S */
/* File: x86_64/op_iget.S */
-/*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short, iget-wide
- */
- EXPORT_PC
- movzbq rINSTbl, %rcx # rcx <- BA
- movzwl 2(rPC), OUT_32_ARG0 # eax <- field ref CCCC
- sarl $4, %ecx # ecx <- B
- GET_VREG OUT_32_ARG1, %rcx # the object pointer
- movq OFF_FP_METHOD(rFP), OUT_ARG2 # referrer
- movq rSELF, OUT_ARG3
+/* File: x86_64/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
+ .extern MterpIGetU8
+ REFRESH_INST 85 # fix rINST to include opcode
+ movq rPC, OUT_ARG0 # arg0: Instruction* inst
+ movl rINST, OUT_32_ARG1 # arg1: uint16_t inst_data
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG2 # arg2: ShadowFrame* sf
+ movq rSELF, OUT_ARG3 # arg3: Thread* self
call SYMBOL(MterpIGetU8)
- movq rSELF, %rcx
- cmpq $0, THREAD_EXCEPTION_OFFSET(%rcx)
- jnz MterpException # bail out
- andb $0xf, rINSTbl # rINST <- A
- .if 0
- SET_VREG_OBJECT %eax, rINSTq # fp[A] <-value
- .else
- .if 0
- SET_WIDE_VREG %rax, rINSTq # fp[A] <-value
- .else
- SET_VREG %eax, rINSTq # fp[A] <-value
- .endif
- .endif
+ testb %al, %al
+ jz MterpPossibleException
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_iget_byte: /* 0x56 */
/* File: x86_64/op_iget_byte.S */
/* File: x86_64/op_iget.S */
-/*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short, iget-wide
- */
- EXPORT_PC
- movzbq rINSTbl, %rcx # rcx <- BA
- movzwl 2(rPC), OUT_32_ARG0 # eax <- field ref CCCC
- sarl $4, %ecx # ecx <- B
- GET_VREG OUT_32_ARG1, %rcx # the object pointer
- movq OFF_FP_METHOD(rFP), OUT_ARG2 # referrer
- movq rSELF, OUT_ARG3
+/* File: x86_64/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
+ .extern MterpIGetI8
+ REFRESH_INST 86 # fix rINST to include opcode
+ movq rPC, OUT_ARG0 # arg0: Instruction* inst
+ movl rINST, OUT_32_ARG1 # arg1: uint16_t inst_data
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG2 # arg2: ShadowFrame* sf
+ movq rSELF, OUT_ARG3 # arg3: Thread* self
call SYMBOL(MterpIGetI8)
- movq rSELF, %rcx
- cmpq $0, THREAD_EXCEPTION_OFFSET(%rcx)
- jnz MterpException # bail out
- andb $0xf, rINSTbl # rINST <- A
- .if 0
- SET_VREG_OBJECT %eax, rINSTq # fp[A] <-value
- .else
- .if 0
- SET_WIDE_VREG %rax, rINSTq # fp[A] <-value
- .else
- SET_VREG %eax, rINSTq # fp[A] <-value
- .endif
- .endif
+ testb %al, %al
+ jz MterpPossibleException
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_iget_char: /* 0x57 */
/* File: x86_64/op_iget_char.S */
/* File: x86_64/op_iget.S */
-/*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short, iget-wide
- */
- EXPORT_PC
- movzbq rINSTbl, %rcx # rcx <- BA
- movzwl 2(rPC), OUT_32_ARG0 # eax <- field ref CCCC
- sarl $4, %ecx # ecx <- B
- GET_VREG OUT_32_ARG1, %rcx # the object pointer
- movq OFF_FP_METHOD(rFP), OUT_ARG2 # referrer
- movq rSELF, OUT_ARG3
+/* File: x86_64/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
+ .extern MterpIGetU16
+ REFRESH_INST 87 # fix rINST to include opcode
+ movq rPC, OUT_ARG0 # arg0: Instruction* inst
+ movl rINST, OUT_32_ARG1 # arg1: uint16_t inst_data
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG2 # arg2: ShadowFrame* sf
+ movq rSELF, OUT_ARG3 # arg3: Thread* self
call SYMBOL(MterpIGetU16)
- movq rSELF, %rcx
- cmpq $0, THREAD_EXCEPTION_OFFSET(%rcx)
- jnz MterpException # bail out
- andb $0xf, rINSTbl # rINST <- A
- .if 0
- SET_VREG_OBJECT %eax, rINSTq # fp[A] <-value
- .else
- .if 0
- SET_WIDE_VREG %rax, rINSTq # fp[A] <-value
- .else
- SET_VREG %eax, rINSTq # fp[A] <-value
- .endif
- .endif
+ testb %al, %al
+ jz MterpPossibleException
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_iget_short: /* 0x58 */
/* File: x86_64/op_iget_short.S */
/* File: x86_64/op_iget.S */
-/*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short, iget-wide
- */
- EXPORT_PC
- movzbq rINSTbl, %rcx # rcx <- BA
- movzwl 2(rPC), OUT_32_ARG0 # eax <- field ref CCCC
- sarl $4, %ecx # ecx <- B
- GET_VREG OUT_32_ARG1, %rcx # the object pointer
- movq OFF_FP_METHOD(rFP), OUT_ARG2 # referrer
- movq rSELF, OUT_ARG3
+/* File: x86_64/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
+ .extern MterpIGetI16
+ REFRESH_INST 88 # fix rINST to include opcode
+ movq rPC, OUT_ARG0 # arg0: Instruction* inst
+ movl rINST, OUT_32_ARG1 # arg1: uint16_t inst_data
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG2 # arg2: ShadowFrame* sf
+ movq rSELF, OUT_ARG3 # arg3: Thread* self
call SYMBOL(MterpIGetI16)
- movq rSELF, %rcx
- cmpq $0, THREAD_EXCEPTION_OFFSET(%rcx)
- jnz MterpException # bail out
- andb $0xf, rINSTbl # rINST <- A
- .if 0
- SET_VREG_OBJECT %eax, rINSTq # fp[A] <-value
- .else
- .if 0
- SET_WIDE_VREG %rax, rINSTq # fp[A] <-value
- .else
- SET_VREG %eax, rINSTq # fp[A] <-value
- .endif
- .endif
+ testb %al, %al
+ jz MterpPossibleException
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_iput: /* 0x59 */
/* File: x86_64/op_iput.S */
-/*
- * General 32-bit instance field put.
- *
- * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
- */
- /* op vA, vB, field@CCCC */
+/* File: x86_64/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpIPutU32
- EXPORT_PC
- movzwl 2(rPC), OUT_32_ARG0 # field ref <- 0000CCCC
- movzbq rINSTbl, %rcx # rcx<- BA
- sarl $4, %ecx # ecx<- B
- GET_VREG OUT_32_ARG1, %rcx # the object pointer
- andb $0xf, rINSTbl # rINST<- A
- GET_VREG OUT_32_ARG2, rINSTq # fp[A]
- movq OFF_FP_METHOD(rFP), OUT_ARG3 # referrer
+ REFRESH_INST 89 # fix rINST to include opcode
+ movq rPC, OUT_ARG0 # arg0: Instruction* inst
+ movl rINST, OUT_32_ARG1 # arg1: uint16_t inst_data
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG2 # arg2: ShadowFrame* sf
+ movq rSELF, OUT_ARG3 # arg3: Thread* self
call SYMBOL(MterpIPutU32)
testb %al, %al
- jnz MterpPossibleException
+ jz MterpPossibleException
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_iput_wide: /* 0x5a */
/* File: x86_64/op_iput_wide.S */
- /* iput-wide vA, vB, field@CCCC */
+/* File: x86_64/op_iput.S */
+/* File: x86_64/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpIPutU64
- EXPORT_PC
- movzwq 2(rPC), OUT_ARG0 # field ref CCCC
- movzbq rINSTbl, %rcx # rcx <- BA
- sarl $4, %ecx # ecx <- B
- GET_VREG OUT_32_ARG1, %rcx # the object pointer
- andb $0xf, rINSTbl # rINST <- A
- leaq VREG_ADDRESS(rINSTq), OUT_ARG2 # &fp[A]
- movq OFF_FP_METHOD(rFP), OUT_ARG3 # referrer
+ REFRESH_INST 90 # fix rINST to include opcode
+ movq rPC, OUT_ARG0 # arg0: Instruction* inst
+ movl rINST, OUT_32_ARG1 # arg1: uint16_t inst_data
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG2 # arg2: ShadowFrame* sf
+ movq rSELF, OUT_ARG3 # arg3: Thread* self
call SYMBOL(MterpIPutU64)
testb %al, %al
- jnz MterpPossibleException
+ jz MterpPossibleException
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+
/* ------------------------------ */
.balign 128
.L_op_iput_object: /* 0x5b */
/* File: x86_64/op_iput_object.S */
- EXPORT_PC
- leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG0
- movq rPC, OUT_ARG1
- REFRESH_INST 91
- movl rINST, OUT_32_ARG2
- movq rSELF, OUT_ARG3
+/* File: x86_64/op_iput.S */
+/* File: x86_64/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
+ .extern MterpIPutObj
+ REFRESH_INST 91 # fix rINST to include opcode
+ movq rPC, OUT_ARG0 # arg0: Instruction* inst
+ movl rINST, OUT_32_ARG1 # arg1: uint16_t inst_data
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG2 # arg2: ShadowFrame* sf
+ movq rSELF, OUT_ARG3 # arg3: Thread* self
call SYMBOL(MterpIPutObj)
testb %al, %al
- jz MterpException
+ jz MterpPossibleException
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+
/* ------------------------------ */
.balign 128
.L_op_iput_boolean: /* 0x5c */
/* File: x86_64/op_iput_boolean.S */
/* File: x86_64/op_iput.S */
-/*
- * General 32-bit instance field put.
- *
- * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
- */
- /* op vA, vB, field@CCCC */
+/* File: x86_64/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpIPutU8
- EXPORT_PC
- movzwl 2(rPC), OUT_32_ARG0 # field ref <- 0000CCCC
- movzbq rINSTbl, %rcx # rcx<- BA
- sarl $4, %ecx # ecx<- B
- GET_VREG OUT_32_ARG1, %rcx # the object pointer
- andb $0xf, rINSTbl # rINST<- A
- GET_VREG OUT_32_ARG2, rINSTq # fp[A]
- movq OFF_FP_METHOD(rFP), OUT_ARG3 # referrer
+ REFRESH_INST 92 # fix rINST to include opcode
+ movq rPC, OUT_ARG0 # arg0: Instruction* inst
+ movl rINST, OUT_32_ARG1 # arg1: uint16_t inst_data
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG2 # arg2: ShadowFrame* sf
+ movq rSELF, OUT_ARG3 # arg3: Thread* self
call SYMBOL(MterpIPutU8)
testb %al, %al
- jnz MterpPossibleException
+ jz MterpPossibleException
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_iput_byte: /* 0x5d */
/* File: x86_64/op_iput_byte.S */
/* File: x86_64/op_iput.S */
-/*
- * General 32-bit instance field put.
- *
- * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
- */
- /* op vA, vB, field@CCCC */
+/* File: x86_64/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpIPutI8
- EXPORT_PC
- movzwl 2(rPC), OUT_32_ARG0 # field ref <- 0000CCCC
- movzbq rINSTbl, %rcx # rcx<- BA
- sarl $4, %ecx # ecx<- B
- GET_VREG OUT_32_ARG1, %rcx # the object pointer
- andb $0xf, rINSTbl # rINST<- A
- GET_VREG OUT_32_ARG2, rINSTq # fp[A]
- movq OFF_FP_METHOD(rFP), OUT_ARG3 # referrer
+ REFRESH_INST 93 # fix rINST to include opcode
+ movq rPC, OUT_ARG0 # arg0: Instruction* inst
+ movl rINST, OUT_32_ARG1 # arg1: uint16_t inst_data
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG2 # arg2: ShadowFrame* sf
+ movq rSELF, OUT_ARG3 # arg3: Thread* self
call SYMBOL(MterpIPutI8)
testb %al, %al
- jnz MterpPossibleException
+ jz MterpPossibleException
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_iput_char: /* 0x5e */
/* File: x86_64/op_iput_char.S */
/* File: x86_64/op_iput.S */
-/*
- * General 32-bit instance field put.
- *
- * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
- */
- /* op vA, vB, field@CCCC */
+/* File: x86_64/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpIPutU16
- EXPORT_PC
- movzwl 2(rPC), OUT_32_ARG0 # field ref <- 0000CCCC
- movzbq rINSTbl, %rcx # rcx<- BA
- sarl $4, %ecx # ecx<- B
- GET_VREG OUT_32_ARG1, %rcx # the object pointer
- andb $0xf, rINSTbl # rINST<- A
- GET_VREG OUT_32_ARG2, rINSTq # fp[A]
- movq OFF_FP_METHOD(rFP), OUT_ARG3 # referrer
+ REFRESH_INST 94 # fix rINST to include opcode
+ movq rPC, OUT_ARG0 # arg0: Instruction* inst
+ movl rINST, OUT_32_ARG1 # arg1: uint16_t inst_data
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG2 # arg2: ShadowFrame* sf
+ movq rSELF, OUT_ARG3 # arg3: Thread* self
call SYMBOL(MterpIPutU16)
testb %al, %al
- jnz MterpPossibleException
+ jz MterpPossibleException
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_iput_short: /* 0x5f */
/* File: x86_64/op_iput_short.S */
/* File: x86_64/op_iput.S */
-/*
- * General 32-bit instance field put.
- *
- * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
- */
- /* op vA, vB, field@CCCC */
+/* File: x86_64/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpIPutI16
- EXPORT_PC
- movzwl 2(rPC), OUT_32_ARG0 # field ref <- 0000CCCC
- movzbq rINSTbl, %rcx # rcx<- BA
- sarl $4, %ecx # ecx<- B
- GET_VREG OUT_32_ARG1, %rcx # the object pointer
- andb $0xf, rINSTbl # rINST<- A
- GET_VREG OUT_32_ARG2, rINSTq # fp[A]
- movq OFF_FP_METHOD(rFP), OUT_ARG3 # referrer
+ REFRESH_INST 95 # fix rINST to include opcode
+ movq rPC, OUT_ARG0 # arg0: Instruction* inst
+ movl rINST, OUT_32_ARG1 # arg1: uint16_t inst_data
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG2 # arg2: ShadowFrame* sf
+ movq rSELF, OUT_ARG3 # arg3: Thread* self
call SYMBOL(MterpIPutI16)
testb %al, %al
- jnz MterpPossibleException
+ jz MterpPossibleException
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_sget: /* 0x60 */
/* File: x86_64/op_sget.S */
-/*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short, sget-wide
- */
- /* op vAA, field@BBBB */
+/* File: x86_64/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpSGetU32
- EXPORT_PC
- movzwq 2(rPC), OUT_ARG0 # field ref CCCC
- movq OFF_FP_METHOD(rFP), OUT_ARG1 # referrer
- movq rSELF, OUT_ARG2 # self
+ REFRESH_INST 96 # fix rINST to include opcode
+ movq rPC, OUT_ARG0 # arg0: Instruction* inst
+ movl rINST, OUT_32_ARG1 # arg1: uint16_t inst_data
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG2 # arg2: ShadowFrame* sf
+ movq rSELF, OUT_ARG3 # arg3: Thread* self
call SYMBOL(MterpSGetU32)
- movq rSELF, %rcx
- cmpl $0, THREAD_EXCEPTION_OFFSET(%rcx)
- jnz MterpException
- .if 0
- SET_VREG_OBJECT %eax, rINSTq # fp[A] <- value
- .else
- .if 0
- SET_WIDE_VREG %rax, rINSTq # fp[A] <- value
- .else
- SET_VREG %eax, rINSTq # fp[A] <- value
- .endif
- .endif
+ testb %al, %al
+ jz MterpPossibleException
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_sget_wide: /* 0x61 */
/* File: x86_64/op_sget_wide.S */
/* File: x86_64/op_sget.S */
-/*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short, sget-wide
- */
- /* op vAA, field@BBBB */
+/* File: x86_64/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpSGetU64
- EXPORT_PC
- movzwq 2(rPC), OUT_ARG0 # field ref CCCC
- movq OFF_FP_METHOD(rFP), OUT_ARG1 # referrer
- movq rSELF, OUT_ARG2 # self
+ REFRESH_INST 97 # fix rINST to include opcode
+ movq rPC, OUT_ARG0 # arg0: Instruction* inst
+ movl rINST, OUT_32_ARG1 # arg1: uint16_t inst_data
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG2 # arg2: ShadowFrame* sf
+ movq rSELF, OUT_ARG3 # arg3: Thread* self
call SYMBOL(MterpSGetU64)
- movq rSELF, %rcx
- cmpl $0, THREAD_EXCEPTION_OFFSET(%rcx)
- jnz MterpException
- .if 0
- SET_VREG_OBJECT %eax, rINSTq # fp[A] <- value
- .else
- .if 1
- SET_WIDE_VREG %rax, rINSTq # fp[A] <- value
- .else
- SET_VREG %eax, rINSTq # fp[A] <- value
- .endif
- .endif
+ testb %al, %al
+ jz MterpPossibleException
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_sget_object: /* 0x62 */
/* File: x86_64/op_sget_object.S */
/* File: x86_64/op_sget.S */
-/*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short, sget-wide
- */
- /* op vAA, field@BBBB */
+/* File: x86_64/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpSGetObj
- EXPORT_PC
- movzwq 2(rPC), OUT_ARG0 # field ref CCCC
- movq OFF_FP_METHOD(rFP), OUT_ARG1 # referrer
- movq rSELF, OUT_ARG2 # self
+ REFRESH_INST 98 # fix rINST to include opcode
+ movq rPC, OUT_ARG0 # arg0: Instruction* inst
+ movl rINST, OUT_32_ARG1 # arg1: uint16_t inst_data
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG2 # arg2: ShadowFrame* sf
+ movq rSELF, OUT_ARG3 # arg3: Thread* self
call SYMBOL(MterpSGetObj)
- movq rSELF, %rcx
- cmpl $0, THREAD_EXCEPTION_OFFSET(%rcx)
- jnz MterpException
- .if 1
- SET_VREG_OBJECT %eax, rINSTq # fp[A] <- value
- .else
- .if 0
- SET_WIDE_VREG %rax, rINSTq # fp[A] <- value
- .else
- SET_VREG %eax, rINSTq # fp[A] <- value
- .endif
- .endif
+ testb %al, %al
+ jz MterpPossibleException
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_sget_boolean: /* 0x63 */
/* File: x86_64/op_sget_boolean.S */
/* File: x86_64/op_sget.S */
-/*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short, sget-wide
- */
- /* op vAA, field@BBBB */
+/* File: x86_64/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpSGetU8
- EXPORT_PC
- movzwq 2(rPC), OUT_ARG0 # field ref CCCC
- movq OFF_FP_METHOD(rFP), OUT_ARG1 # referrer
- movq rSELF, OUT_ARG2 # self
+ REFRESH_INST 99 # fix rINST to include opcode
+ movq rPC, OUT_ARG0 # arg0: Instruction* inst
+ movl rINST, OUT_32_ARG1 # arg1: uint16_t inst_data
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG2 # arg2: ShadowFrame* sf
+ movq rSELF, OUT_ARG3 # arg3: Thread* self
call SYMBOL(MterpSGetU8)
- movq rSELF, %rcx
- cmpl $0, THREAD_EXCEPTION_OFFSET(%rcx)
- jnz MterpException
- .if 0
- SET_VREG_OBJECT %eax, rINSTq # fp[A] <- value
- .else
- .if 0
- SET_WIDE_VREG %rax, rINSTq # fp[A] <- value
- .else
- SET_VREG %eax, rINSTq # fp[A] <- value
- .endif
- .endif
+ testb %al, %al
+ jz MterpPossibleException
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_sget_byte: /* 0x64 */
/* File: x86_64/op_sget_byte.S */
/* File: x86_64/op_sget.S */
-/*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short, sget-wide
- */
- /* op vAA, field@BBBB */
+/* File: x86_64/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpSGetI8
- EXPORT_PC
- movzwq 2(rPC), OUT_ARG0 # field ref CCCC
- movq OFF_FP_METHOD(rFP), OUT_ARG1 # referrer
- movq rSELF, OUT_ARG2 # self
+ REFRESH_INST 100 # fix rINST to include opcode
+ movq rPC, OUT_ARG0 # arg0: Instruction* inst
+ movl rINST, OUT_32_ARG1 # arg1: uint16_t inst_data
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG2 # arg2: ShadowFrame* sf
+ movq rSELF, OUT_ARG3 # arg3: Thread* self
call SYMBOL(MterpSGetI8)
- movq rSELF, %rcx
- cmpl $0, THREAD_EXCEPTION_OFFSET(%rcx)
- jnz MterpException
- .if 0
- SET_VREG_OBJECT %eax, rINSTq # fp[A] <- value
- .else
- .if 0
- SET_WIDE_VREG %rax, rINSTq # fp[A] <- value
- .else
- SET_VREG %eax, rINSTq # fp[A] <- value
- .endif
- .endif
+ testb %al, %al
+ jz MterpPossibleException
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_sget_char: /* 0x65 */
/* File: x86_64/op_sget_char.S */
/* File: x86_64/op_sget.S */
-/*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short, sget-wide
- */
- /* op vAA, field@BBBB */
+/* File: x86_64/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpSGetU16
- EXPORT_PC
- movzwq 2(rPC), OUT_ARG0 # field ref CCCC
- movq OFF_FP_METHOD(rFP), OUT_ARG1 # referrer
- movq rSELF, OUT_ARG2 # self
+ REFRESH_INST 101 # fix rINST to include opcode
+ movq rPC, OUT_ARG0 # arg0: Instruction* inst
+ movl rINST, OUT_32_ARG1 # arg1: uint16_t inst_data
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG2 # arg2: ShadowFrame* sf
+ movq rSELF, OUT_ARG3 # arg3: Thread* self
call SYMBOL(MterpSGetU16)
- movq rSELF, %rcx
- cmpl $0, THREAD_EXCEPTION_OFFSET(%rcx)
- jnz MterpException
- .if 0
- SET_VREG_OBJECT %eax, rINSTq # fp[A] <- value
- .else
- .if 0
- SET_WIDE_VREG %rax, rINSTq # fp[A] <- value
- .else
- SET_VREG %eax, rINSTq # fp[A] <- value
- .endif
- .endif
+ testb %al, %al
+ jz MterpPossibleException
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_sget_short: /* 0x66 */
/* File: x86_64/op_sget_short.S */
/* File: x86_64/op_sget.S */
-/*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short, sget-wide
- */
- /* op vAA, field@BBBB */
+/* File: x86_64/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpSGetI16
- EXPORT_PC
- movzwq 2(rPC), OUT_ARG0 # field ref CCCC
- movq OFF_FP_METHOD(rFP), OUT_ARG1 # referrer
- movq rSELF, OUT_ARG2 # self
+ REFRESH_INST 102 # fix rINST to include opcode
+ movq rPC, OUT_ARG0 # arg0: Instruction* inst
+ movl rINST, OUT_32_ARG1 # arg1: uint16_t inst_data
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG2 # arg2: ShadowFrame* sf
+ movq rSELF, OUT_ARG3 # arg3: Thread* self
call SYMBOL(MterpSGetI16)
- movq rSELF, %rcx
- cmpl $0, THREAD_EXCEPTION_OFFSET(%rcx)
- jnz MterpException
- .if 0
- SET_VREG_OBJECT %eax, rINSTq # fp[A] <- value
- .else
- .if 0
- SET_WIDE_VREG %rax, rINSTq # fp[A] <- value
- .else
- SET_VREG %eax, rINSTq # fp[A] <- value
- .endif
- .endif
+ testb %al, %al
+ jz MterpPossibleException
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_sput: /* 0x67 */
/* File: x86_64/op_sput.S */
-/*
- * General SPUT handler wrapper.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
- */
- /* op vAA, field@BBBB */
+/* File: x86_64/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpSPutU32
- EXPORT_PC
- movzwq 2(rPC), OUT_ARG0 # field ref BBBB
- GET_VREG OUT_32_ARG1, rINSTq # fp[AA]
- movq OFF_FP_METHOD(rFP), OUT_ARG2 # referrer
- movq rSELF, OUT_ARG3 # self
+ REFRESH_INST 103 # fix rINST to include opcode
+ movq rPC, OUT_ARG0 # arg0: Instruction* inst
+ movl rINST, OUT_32_ARG1 # arg1: uint16_t inst_data
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG2 # arg2: ShadowFrame* sf
+ movq rSELF, OUT_ARG3 # arg3: Thread* self
call SYMBOL(MterpSPutU32)
testb %al, %al
- jnz MterpException
+ jz MterpPossibleException
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_sput_wide: /* 0x68 */
/* File: x86_64/op_sput_wide.S */
-/*
- * SPUT_WIDE handler wrapper.
- *
- */
- /* sput-wide vAA, field@BBBB */
+/* File: x86_64/op_sput.S */
+/* File: x86_64/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpSPutU64
- EXPORT_PC
- movzwq 2(rPC), OUT_ARG0 # field ref BBBB
- leaq VREG_ADDRESS(rINSTq), OUT_ARG1 # &fp[AA]
- movq OFF_FP_METHOD(rFP), OUT_ARG2 # referrer
- movq rSELF, OUT_ARG3 # self
+ REFRESH_INST 104 # fix rINST to include opcode
+ movq rPC, OUT_ARG0 # arg0: Instruction* inst
+ movl rINST, OUT_32_ARG1 # arg1: uint16_t inst_data
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG2 # arg2: ShadowFrame* sf
+ movq rSELF, OUT_ARG3 # arg3: Thread* self
call SYMBOL(MterpSPutU64)
testb %al, %al
- jnz MterpException
+ jz MterpPossibleException
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+
/* ------------------------------ */
.balign 128
.L_op_sput_object: /* 0x69 */
/* File: x86_64/op_sput_object.S */
- EXPORT_PC
- leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG0
- movq rPC, OUT_ARG1
- REFRESH_INST 105
- movq rINSTq, OUT_ARG2
- movq rSELF, OUT_ARG3
+/* File: x86_64/op_sput.S */
+/* File: x86_64/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
+ .extern MterpSPutObj
+ REFRESH_INST 105 # fix rINST to include opcode
+ movq rPC, OUT_ARG0 # arg0: Instruction* inst
+ movl rINST, OUT_32_ARG1 # arg1: uint16_t inst_data
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG2 # arg2: ShadowFrame* sf
+ movq rSELF, OUT_ARG3 # arg3: Thread* self
call SYMBOL(MterpSPutObj)
testb %al, %al
- jz MterpException
+ jz MterpPossibleException
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+
/* ------------------------------ */
.balign 128
.L_op_sput_boolean: /* 0x6a */
/* File: x86_64/op_sput_boolean.S */
/* File: x86_64/op_sput.S */
-/*
- * General SPUT handler wrapper.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
- */
- /* op vAA, field@BBBB */
+/* File: x86_64/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpSPutU8
- EXPORT_PC
- movzwq 2(rPC), OUT_ARG0 # field ref BBBB
- GET_VREG OUT_32_ARG1, rINSTq # fp[AA]
- movq OFF_FP_METHOD(rFP), OUT_ARG2 # referrer
- movq rSELF, OUT_ARG3 # self
+ REFRESH_INST 106 # fix rINST to include opcode
+ movq rPC, OUT_ARG0 # arg0: Instruction* inst
+ movl rINST, OUT_32_ARG1 # arg1: uint16_t inst_data
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG2 # arg2: ShadowFrame* sf
+ movq rSELF, OUT_ARG3 # arg3: Thread* self
call SYMBOL(MterpSPutU8)
testb %al, %al
- jnz MterpException
+ jz MterpPossibleException
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_sput_byte: /* 0x6b */
/* File: x86_64/op_sput_byte.S */
/* File: x86_64/op_sput.S */
-/*
- * General SPUT handler wrapper.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
- */
- /* op vAA, field@BBBB */
+/* File: x86_64/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpSPutI8
- EXPORT_PC
- movzwq 2(rPC), OUT_ARG0 # field ref BBBB
- GET_VREG OUT_32_ARG1, rINSTq # fp[AA]
- movq OFF_FP_METHOD(rFP), OUT_ARG2 # referrer
- movq rSELF, OUT_ARG3 # self
+ REFRESH_INST 107 # fix rINST to include opcode
+ movq rPC, OUT_ARG0 # arg0: Instruction* inst
+ movl rINST, OUT_32_ARG1 # arg1: uint16_t inst_data
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG2 # arg2: ShadowFrame* sf
+ movq rSELF, OUT_ARG3 # arg3: Thread* self
call SYMBOL(MterpSPutI8)
testb %al, %al
- jnz MterpException
+ jz MterpPossibleException
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_sput_char: /* 0x6c */
/* File: x86_64/op_sput_char.S */
/* File: x86_64/op_sput.S */
-/*
- * General SPUT handler wrapper.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
- */
- /* op vAA, field@BBBB */
+/* File: x86_64/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpSPutU16
- EXPORT_PC
- movzwq 2(rPC), OUT_ARG0 # field ref BBBB
- GET_VREG OUT_32_ARG1, rINSTq # fp[AA]
- movq OFF_FP_METHOD(rFP), OUT_ARG2 # referrer
- movq rSELF, OUT_ARG3 # self
+ REFRESH_INST 108 # fix rINST to include opcode
+ movq rPC, OUT_ARG0 # arg0: Instruction* inst
+ movl rINST, OUT_32_ARG1 # arg1: uint16_t inst_data
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG2 # arg2: ShadowFrame* sf
+ movq rSELF, OUT_ARG3 # arg3: Thread* self
call SYMBOL(MterpSPutU16)
testb %al, %al
- jnz MterpException
+ jz MterpPossibleException
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_sput_short: /* 0x6d */
/* File: x86_64/op_sput_short.S */
/* File: x86_64/op_sput.S */
-/*
- * General SPUT handler wrapper.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
- */
- /* op vAA, field@BBBB */
+/* File: x86_64/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpSPutI16
- EXPORT_PC
- movzwq 2(rPC), OUT_ARG0 # field ref BBBB
- GET_VREG OUT_32_ARG1, rINSTq # fp[AA]
- movq OFF_FP_METHOD(rFP), OUT_ARG2 # referrer
- movq rSELF, OUT_ARG3 # self
+ REFRESH_INST 109 # fix rINST to include opcode
+ movq rPC, OUT_ARG0 # arg0: Instruction* inst
+ movl rINST, OUT_32_ARG1 # arg1: uint16_t inst_data
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG2 # arg2: ShadowFrame* sf
+ movq rSELF, OUT_ARG3 # arg3: Thread* self
call SYMBOL(MterpSPutI16)
testb %al, %al
- jnz MterpException
+ jz MterpPossibleException
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_invoke_virtual: /* 0x6e */
diff --git a/runtime/interpreter/mterp/x86/field.S b/runtime/interpreter/mterp/x86/field.S
new file mode 100644
index 0000000..8432c74
--- /dev/null
+++ b/runtime/interpreter/mterp/x86/field.S
@@ -0,0 +1,17 @@
+%default { }
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
+ .extern $helper
+ REFRESH_INST ${opnum} # fix rINST to include opcode
+ movl rPC, OUT_ARG0(%esp) # arg0: Instruction* inst
+ movl rINST, OUT_ARG1(%esp) # arg1: uint16_t inst_data
+ leal OFF_FP_SHADOWFRAME(rFP), %eax
+ movl %eax, OUT_ARG2(%esp) # arg2: ShadowFrame* sf
+ movl rSELF, %eax
+ movl %eax, OUT_ARG3(%esp) # arg3: Thread* self
+ call SYMBOL($helper)
+ testb %al, %al
+ jz MterpPossibleException
+ RESTORE_IBASE
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86/op_iget.S b/runtime/interpreter/mterp/x86/op_iget.S
index 0af1bec..d85d54c 100644
--- a/runtime/interpreter/mterp/x86/op_iget.S
+++ b/runtime/interpreter/mterp/x86/op_iget.S
@@ -1,29 +1,2 @@
%default { "is_object":"0", "helper":"MterpIGetU32"}
-/*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
- */
- EXPORT_PC
- movzwl 2(rPC), %eax # eax <- 0000CCCC
- movl %eax, OUT_ARG0(%esp) # field ref CCCC
- movzbl rINSTbl, %ecx # ecx <- BA
- sarl $$4, %ecx # ecx <- B
- GET_VREG %ecx, %ecx
- movl %ecx, OUT_ARG1(%esp) # the object pointer
- movl OFF_FP_METHOD(rFP), %eax
- movl %eax, OUT_ARG2(%esp) # referrer
- mov rSELF, %ecx
- movl %ecx, OUT_ARG3(%esp) # self
- call SYMBOL($helper)
- movl rSELF, %ecx
- RESTORE_IBASE_FROM_SELF %ecx
- cmpl $$0, THREAD_EXCEPTION_OFFSET(%ecx)
- jnz MterpException # bail out
- andb $$0xf, rINSTbl # rINST <- A
- .if $is_object
- SET_VREG_OBJECT %eax, rINST # fp[A] <-value
- .else
- SET_VREG %eax, rINST # fp[A] <-value
- .endif
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+%include "x86/field.S" { }
diff --git a/runtime/interpreter/mterp/x86/op_iget_wide.S b/runtime/interpreter/mterp/x86/op_iget_wide.S
index da27df9..741a64e 100644
--- a/runtime/interpreter/mterp/x86/op_iget_wide.S
+++ b/runtime/interpreter/mterp/x86/op_iget_wide.S
@@ -1,25 +1 @@
-/*
- * 64-bit instance field get.
- *
- * for: iget-wide
- */
- EXPORT_PC
- movzwl 2(rPC), %eax # eax <- 0000CCCC
- movl %eax, OUT_ARG0(%esp) # field ref CCCC
- movzbl rINSTbl, %ecx # ecx <- BA
- sarl $$4, %ecx # ecx <- B
- GET_VREG %ecx, %ecx
- movl %ecx, OUT_ARG1(%esp) # the object pointer
- movl OFF_FP_METHOD(rFP), %eax
- movl %eax, OUT_ARG2(%esp) # referrer
- mov rSELF, %ecx
- movl %ecx, OUT_ARG3(%esp) # self
- call SYMBOL(MterpIGetU64)
- mov rSELF, %ecx
- cmpl $$0, THREAD_EXCEPTION_OFFSET(%ecx)
- jnz MterpException # bail out
- andb $$0xf, rINSTbl # rINST <- A
- SET_VREG %eax, rINST
- SET_VREG_HIGH %edx, rINST
- RESTORE_IBASE_FROM_SELF %ecx
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+%include "x86/op_iget.S" { "helper":"MterpIGetU64" }
diff --git a/runtime/interpreter/mterp/x86/op_iput.S b/runtime/interpreter/mterp/x86/op_iput.S
index 4c6603a..3628ffd 100644
--- a/runtime/interpreter/mterp/x86/op_iput.S
+++ b/runtime/interpreter/mterp/x86/op_iput.S
@@ -1,25 +1,2 @@
-%default { "helper":"MterpIPutU32" }
-/*
- * General 32-bit instance field put.
- *
- * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
- */
- /* op vA, vB, field@CCCC */
- .extern $helper
- EXPORT_PC
- movzwl 2(rPC), %eax # eax<- 0000CCCC
- movl %eax, OUT_ARG0(%esp) # field ref CCCC
- movzbl rINSTbl, %ecx # ecx<- BA
- sarl $$4, %ecx # ecx<- B
- GET_VREG %ecx, %ecx
- movl %ecx, OUT_ARG1(%esp) # the object pointer
- andb $$0xf, rINSTbl # rINST<- A
- GET_VREG %eax, rINST
- movl %eax, OUT_ARG2(%esp) # fp[A]
- movl OFF_FP_METHOD(rFP), %eax
- movl %eax, OUT_ARG3(%esp) # referrer
- call SYMBOL($helper)
- testb %al, %al
- jnz MterpPossibleException
- RESTORE_IBASE
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+%default { "is_object":"0", "helper":"MterpIPutU32" }
+%include "x86/field.S" { }
diff --git a/runtime/interpreter/mterp/x86/op_iput_object.S b/runtime/interpreter/mterp/x86/op_iput_object.S
index 56e026e..a124b7e 100644
--- a/runtime/interpreter/mterp/x86/op_iput_object.S
+++ b/runtime/interpreter/mterp/x86/op_iput_object.S
@@ -1,13 +1 @@
- EXPORT_PC
- leal OFF_FP_SHADOWFRAME(rFP), %eax
- movl %eax, OUT_ARG0(%esp)
- movl rPC, OUT_ARG1(%esp)
- REFRESH_INST ${opnum}
- movl rINST, OUT_ARG2(%esp)
- movl rSELF, %eax
- movl %eax, OUT_ARG3(%esp)
- call SYMBOL(MterpIPutObj)
- testb %al, %al
- jz MterpException
- RESTORE_IBASE
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+%include "x86/op_iput.S" { "is_object":"1", "helper":"MterpIPutObj" }
diff --git a/runtime/interpreter/mterp/x86/op_iput_wide.S b/runtime/interpreter/mterp/x86/op_iput_wide.S
index ea22b91..2820ede 100644
--- a/runtime/interpreter/mterp/x86/op_iput_wide.S
+++ b/runtime/interpreter/mterp/x86/op_iput_wide.S
@@ -1,19 +1 @@
- /* iput-wide vA, vB, field@CCCC */
- .extern MterpIPutU64
- EXPORT_PC
- movzwl 2(rPC), %eax # eax <- 0000CCCC
- movl %eax, OUT_ARG0(%esp) # field ref CCCC
- movzbl rINSTbl,%ecx # ecx <- BA
- sarl $$4,%ecx # ecx <- B
- GET_VREG %ecx, %ecx
- movl %ecx, OUT_ARG1(%esp) # the object pointer
- andb $$0xf,rINSTbl # rINST <- A
- leal VREG_ADDRESS(rINST), %eax
- movl %eax, OUT_ARG2(%esp) # &fp[A]
- movl OFF_FP_METHOD(rFP), %eax
- movl %eax, OUT_ARG3(%esp) # referrer
- call SYMBOL(MterpIPutU64)
- testb %al, %al
- jnz MterpPossibleException
- RESTORE_IBASE
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+%include "x86/op_iput.S" { "helper":"MterpIPutU64" }
diff --git a/runtime/interpreter/mterp/x86/op_sget.S b/runtime/interpreter/mterp/x86/op_sget.S
index 66c7b0b..ada4e0e 100644
--- a/runtime/interpreter/mterp/x86/op_sget.S
+++ b/runtime/interpreter/mterp/x86/op_sget.S
@@ -1,26 +1,2 @@
%default { "is_object":"0", "helper":"MterpSGetU32" }
-/*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
- */
- /* op vAA, field@BBBB */
- .extern $helper
- EXPORT_PC
- movzwl 2(rPC), %eax
- movl %eax, OUT_ARG0(%esp) # field ref CCCC
- movl OFF_FP_METHOD(rFP), %eax
- movl %eax, OUT_ARG1(%esp) # referrer
- movl rSELF, %ecx
- movl %ecx, OUT_ARG2(%esp) # self
- call SYMBOL($helper)
- movl rSELF, %ecx
- RESTORE_IBASE_FROM_SELF %ecx
- cmpl $$0, THREAD_EXCEPTION_OFFSET(%ecx)
- jnz MterpException
- .if $is_object
- SET_VREG_OBJECT %eax, rINST # fp[A] <- value
- .else
- SET_VREG %eax, rINST # fp[A] <- value
- .endif
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+%include "x86/field.S" { }
diff --git a/runtime/interpreter/mterp/x86/op_sget_wide.S b/runtime/interpreter/mterp/x86/op_sget_wide.S
index 994cc3a..5923274 100644
--- a/runtime/interpreter/mterp/x86/op_sget_wide.S
+++ b/runtime/interpreter/mterp/x86/op_sget_wide.S
@@ -1,21 +1 @@
-/*
- * SGET_WIDE handler wrapper.
- *
- */
- /* sget-wide vAA, field@BBBB */
- .extern MterpSGetU64
- EXPORT_PC
- movzwl 2(rPC), %eax
- movl %eax, OUT_ARG0(%esp) # field ref CCCC
- movl OFF_FP_METHOD(rFP), %eax
- movl %eax, OUT_ARG1(%esp) # referrer
- movl rSELF, %ecx
- movl %ecx, OUT_ARG2(%esp) # self
- call SYMBOL(MterpSGetU64)
- movl rSELF, %ecx
- cmpl $$0, THREAD_EXCEPTION_OFFSET(%ecx)
- jnz MterpException
- SET_VREG %eax, rINST # fp[A]<- low part
- SET_VREG_HIGH %edx, rINST # fp[A+1]<- high part
- RESTORE_IBASE_FROM_SELF %ecx
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+%include "x86/op_sget.S" {"helper":"MterpSGetU64"}
diff --git a/runtime/interpreter/mterp/x86/op_sput.S b/runtime/interpreter/mterp/x86/op_sput.S
index e99e7a7..2ad68e7 100644
--- a/runtime/interpreter/mterp/x86/op_sput.S
+++ b/runtime/interpreter/mterp/x86/op_sput.S
@@ -1,22 +1,2 @@
-%default { "helper":"MterpSPutU32"}
-/*
- * General SPUT handler wrapper.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
- */
- /* op vAA, field@BBBB */
- .extern $helper
- EXPORT_PC
- movzwl 2(rPC), %eax
- movl %eax, OUT_ARG0(%esp) # field ref BBBB
- GET_VREG rINST, rINST
- movl rINST, OUT_ARG1(%esp) # fp[AA]
- movl OFF_FP_METHOD(rFP), %eax
- movl %eax, OUT_ARG2(%esp) # referrer
- movl rSELF, %ecx
- movl %ecx, OUT_ARG3(%esp) # self
- call SYMBOL($helper)
- testb %al, %al
- jnz MterpException
- RESTORE_IBASE
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+%default { "is_object":"0", "helper":"MterpSPutU32"}
+%include "x86/field.S" { }
diff --git a/runtime/interpreter/mterp/x86/op_sput_object.S b/runtime/interpreter/mterp/x86/op_sput_object.S
index 941b072..4452dba 100644
--- a/runtime/interpreter/mterp/x86/op_sput_object.S
+++ b/runtime/interpreter/mterp/x86/op_sput_object.S
@@ -1,13 +1 @@
- EXPORT_PC
- leal OFF_FP_SHADOWFRAME(rFP), %eax
- movl %eax, OUT_ARG0(%esp)
- movl rPC, OUT_ARG1(%esp)
- REFRESH_INST ${opnum}
- movl rINST, OUT_ARG2(%esp)
- movl rSELF, %ecx
- movl %ecx, OUT_ARG3(%esp)
- call SYMBOL(MterpSPutObj)
- testb %al, %al
- jz MterpException
- RESTORE_IBASE
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+%include "x86/op_sput.S" {"is_object":"1", "helper":"MterpSPutObj"}
diff --git a/runtime/interpreter/mterp/x86/op_sput_wide.S b/runtime/interpreter/mterp/x86/op_sput_wide.S
index f581507..d79b068 100644
--- a/runtime/interpreter/mterp/x86/op_sput_wide.S
+++ b/runtime/interpreter/mterp/x86/op_sput_wide.S
@@ -1,20 +1 @@
-/*
- * SPUT_WIDE handler wrapper.
- *
- */
- /* sput-wide vAA, field@BBBB */
- .extern MterpSPutU64
- EXPORT_PC
- movzwl 2(rPC), %eax
- movl %eax, OUT_ARG0(%esp) # field ref BBBB
- leal VREG_ADDRESS(rINST), %eax
- movl %eax, OUT_ARG1(%esp) # &fp[AA]
- movl OFF_FP_METHOD(rFP), %eax
- movl %eax, OUT_ARG2(%esp) # referrer
- movl rSELF, %ecx
- movl %ecx, OUT_ARG3(%esp) # self
- call SYMBOL(MterpSPutU64)
- testb %al, %al
- jnz MterpException
- RESTORE_IBASE
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+%include "x86/op_sput.S" {"helper":"MterpSPutU64"}
diff --git a/runtime/interpreter/mterp/x86_64/field.S b/runtime/interpreter/mterp/x86_64/field.S
new file mode 100644
index 0000000..f8b0588
--- /dev/null
+++ b/runtime/interpreter/mterp/x86_64/field.S
@@ -0,0 +1,14 @@
+%default { }
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
+ .extern $helper
+ REFRESH_INST ${opnum} # fix rINST to include opcode
+ movq rPC, OUT_ARG0 # arg0: Instruction* inst
+ movl rINST, OUT_32_ARG1 # arg1: uint16_t inst_data
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG2 # arg2: ShadowFrame* sf
+ movq rSELF, OUT_ARG3 # arg3: Thread* self
+ call SYMBOL($helper)
+ testb %al, %al
+ jz MterpPossibleException
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86_64/op_iget.S b/runtime/interpreter/mterp/x86_64/op_iget.S
index 5c6cab6..4ab7c27 100644
--- a/runtime/interpreter/mterp/x86_64/op_iget.S
+++ b/runtime/interpreter/mterp/x86_64/op_iget.S
@@ -1,28 +1,2 @@
-%default { "is_object":"0", "helper":"MterpIGetU32", "wide":"0"}
-/*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short, iget-wide
- */
- EXPORT_PC
- movzbq rINSTbl, %rcx # rcx <- BA
- movzwl 2(rPC), OUT_32_ARG0 # eax <- field ref CCCC
- sarl $$4, %ecx # ecx <- B
- GET_VREG OUT_32_ARG1, %rcx # the object pointer
- movq OFF_FP_METHOD(rFP), OUT_ARG2 # referrer
- movq rSELF, OUT_ARG3
- call SYMBOL($helper)
- movq rSELF, %rcx
- cmpq $$0, THREAD_EXCEPTION_OFFSET(%rcx)
- jnz MterpException # bail out
- andb $$0xf, rINSTbl # rINST <- A
- .if $is_object
- SET_VREG_OBJECT %eax, rINSTq # fp[A] <-value
- .else
- .if $wide
- SET_WIDE_VREG %rax, rINSTq # fp[A] <-value
- .else
- SET_VREG %eax, rINSTq # fp[A] <-value
- .endif
- .endif
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+%default { "is_object":"0", "helper":"MterpIGetU32"}
+%include "x86_64/field.S" { }
diff --git a/runtime/interpreter/mterp/x86_64/op_iget_wide.S b/runtime/interpreter/mterp/x86_64/op_iget_wide.S
index d9d1744..a85a474 100644
--- a/runtime/interpreter/mterp/x86_64/op_iget_wide.S
+++ b/runtime/interpreter/mterp/x86_64/op_iget_wide.S
@@ -1 +1 @@
-%include "x86_64/op_iget.S" { "helper":"MterpIGetU64", "wide":"1" }
+%include "x86_64/op_iget.S" { "helper":"MterpIGetU64" }
diff --git a/runtime/interpreter/mterp/x86_64/op_iput.S b/runtime/interpreter/mterp/x86_64/op_iput.S
index 12affdb..dad5af6 100644
--- a/runtime/interpreter/mterp/x86_64/op_iput.S
+++ b/runtime/interpreter/mterp/x86_64/op_iput.S
@@ -1,20 +1,2 @@
-%default { "helper":"MterpIPutU32"}
-/*
- * General 32-bit instance field put.
- *
- * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
- */
- /* op vA, vB, field@CCCC */
- .extern $helper
- EXPORT_PC
- movzwl 2(rPC), OUT_32_ARG0 # field ref <- 0000CCCC
- movzbq rINSTbl, %rcx # rcx<- BA
- sarl $$4, %ecx # ecx<- B
- GET_VREG OUT_32_ARG1, %rcx # the object pointer
- andb $$0xf, rINSTbl # rINST<- A
- GET_VREG OUT_32_ARG2, rINSTq # fp[A]
- movq OFF_FP_METHOD(rFP), OUT_ARG3 # referrer
- call SYMBOL($helper)
- testb %al, %al
- jnz MterpPossibleException
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+%default { "is_object":"0", "helper":"MterpIPutU32" }
+%include "x86_64/field.S" { }
diff --git a/runtime/interpreter/mterp/x86_64/op_iput_object.S b/runtime/interpreter/mterp/x86_64/op_iput_object.S
index 22648cd..202e33f 100644
--- a/runtime/interpreter/mterp/x86_64/op_iput_object.S
+++ b/runtime/interpreter/mterp/x86_64/op_iput_object.S
@@ -1,10 +1 @@
- EXPORT_PC
- leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG0
- movq rPC, OUT_ARG1
- REFRESH_INST ${opnum}
- movl rINST, OUT_32_ARG2
- movq rSELF, OUT_ARG3
- call SYMBOL(MterpIPutObj)
- testb %al, %al
- jz MterpException
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+%include "x86_64/op_iput.S" { "is_object":"1", "helper":"MterpIPutObj" }
diff --git a/runtime/interpreter/mterp/x86_64/op_iput_wide.S b/runtime/interpreter/mterp/x86_64/op_iput_wide.S
index 4f8c47c..db52016 100644
--- a/runtime/interpreter/mterp/x86_64/op_iput_wide.S
+++ b/runtime/interpreter/mterp/x86_64/op_iput_wide.S
@@ -1,14 +1 @@
- /* iput-wide vA, vB, field@CCCC */
- .extern MterpIPutU64
- EXPORT_PC
- movzwq 2(rPC), OUT_ARG0 # field ref CCCC
- movzbq rINSTbl, %rcx # rcx <- BA
- sarl $$4, %ecx # ecx <- B
- GET_VREG OUT_32_ARG1, %rcx # the object pointer
- andb $$0xf, rINSTbl # rINST <- A
- leaq VREG_ADDRESS(rINSTq), OUT_ARG2 # &fp[A]
- movq OFF_FP_METHOD(rFP), OUT_ARG3 # referrer
- call SYMBOL(MterpIPutU64)
- testb %al, %al
- jnz MterpPossibleException
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+%include "x86_64/op_iput.S" { "helper":"MterpIPutU64" }
diff --git a/runtime/interpreter/mterp/x86_64/op_sget.S b/runtime/interpreter/mterp/x86_64/op_sget.S
index c15ac1e..21e8e64 100644
--- a/runtime/interpreter/mterp/x86_64/op_sget.S
+++ b/runtime/interpreter/mterp/x86_64/op_sget.S
@@ -1,26 +1,2 @@
-%default { "is_object":"0", "helper":"MterpSGetU32", "wide":"0" }
-/*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short, sget-wide
- */
- /* op vAA, field@BBBB */
- .extern $helper
- EXPORT_PC
- movzwq 2(rPC), OUT_ARG0 # field ref CCCC
- movq OFF_FP_METHOD(rFP), OUT_ARG1 # referrer
- movq rSELF, OUT_ARG2 # self
- call SYMBOL($helper)
- movq rSELF, %rcx
- cmpl $$0, THREAD_EXCEPTION_OFFSET(%rcx)
- jnz MterpException
- .if $is_object
- SET_VREG_OBJECT %eax, rINSTq # fp[A] <- value
- .else
- .if $wide
- SET_WIDE_VREG %rax, rINSTq # fp[A] <- value
- .else
- SET_VREG %eax, rINSTq # fp[A] <- value
- .endif
- .endif
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+%default { "is_object":"0", "helper":"MterpSGetU32" }
+%include "x86_64/field.S" { }
diff --git a/runtime/interpreter/mterp/x86_64/op_sget_wide.S b/runtime/interpreter/mterp/x86_64/op_sget_wide.S
index 65ddb8a..c53c077 100644
--- a/runtime/interpreter/mterp/x86_64/op_sget_wide.S
+++ b/runtime/interpreter/mterp/x86_64/op_sget_wide.S
@@ -1 +1 @@
-%include "x86_64/op_sget.S" {"helper":"MterpSGetU64", "wide":"1"}
+%include "x86_64/op_sget.S" {"helper":"MterpSGetU64"}
diff --git a/runtime/interpreter/mterp/x86_64/op_sput.S b/runtime/interpreter/mterp/x86_64/op_sput.S
index 9a33d52..7dd2498 100644
--- a/runtime/interpreter/mterp/x86_64/op_sput.S
+++ b/runtime/interpreter/mterp/x86_64/op_sput.S
@@ -1,17 +1,2 @@
-%default { "helper":"MterpSPutU32"}
-/*
- * General SPUT handler wrapper.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
- */
- /* op vAA, field@BBBB */
- .extern $helper
- EXPORT_PC
- movzwq 2(rPC), OUT_ARG0 # field ref BBBB
- GET_VREG OUT_32_ARG1, rINSTq # fp[AA]
- movq OFF_FP_METHOD(rFP), OUT_ARG2 # referrer
- movq rSELF, OUT_ARG3 # self
- call SYMBOL($helper)
- testb %al, %al
- jnz MterpException
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+%default { "is_object":"0", "helper":"MterpSPutU32"}
+%include "x86_64/field.S" { }
diff --git a/runtime/interpreter/mterp/x86_64/op_sput_object.S b/runtime/interpreter/mterp/x86_64/op_sput_object.S
index 8a47074..c2bd07b 100644
--- a/runtime/interpreter/mterp/x86_64/op_sput_object.S
+++ b/runtime/interpreter/mterp/x86_64/op_sput_object.S
@@ -1,10 +1 @@
- EXPORT_PC
- leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG0
- movq rPC, OUT_ARG1
- REFRESH_INST ${opnum}
- movq rINSTq, OUT_ARG2
- movq rSELF, OUT_ARG3
- call SYMBOL(MterpSPutObj)
- testb %al, %al
- jz MterpException
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+%include "x86_64/op_sput.S" {"is_object":"1", "helper":"MterpSPutObj"}
diff --git a/runtime/interpreter/mterp/x86_64/op_sput_wide.S b/runtime/interpreter/mterp/x86_64/op_sput_wide.S
index 464d169..7e77072 100644
--- a/runtime/interpreter/mterp/x86_64/op_sput_wide.S
+++ b/runtime/interpreter/mterp/x86_64/op_sput_wide.S
@@ -1,15 +1 @@
-/*
- * SPUT_WIDE handler wrapper.
- *
- */
- /* sput-wide vAA, field@BBBB */
- .extern MterpSPutU64
- EXPORT_PC
- movzwq 2(rPC), OUT_ARG0 # field ref BBBB
- leaq VREG_ADDRESS(rINSTq), OUT_ARG1 # &fp[AA]
- movq OFF_FP_METHOD(rFP), OUT_ARG2 # referrer
- movq rSELF, OUT_ARG3 # self
- call SYMBOL(MterpSPutU64)
- testb %al, %al
- jnz MterpException
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+%include "x86_64/op_sput.S" {"helper":"MterpSPutU64"}
diff --git a/runtime/jit/jit_code_cache.cc b/runtime/jit/jit_code_cache.cc
index 2b2898c..461eb81 100644
--- a/runtime/jit/jit_code_cache.cc
+++ b/runtime/jit/jit_code_cache.cc
@@ -28,6 +28,7 @@
#include "base/stl_util.h"
#include "base/systrace.h"
#include "base/time_utils.h"
+#include "base/utils.h"
#include "cha.h"
#include "debugger_interface.h"
#include "dex/dex_file_loader.h"
@@ -53,8 +54,9 @@
namespace art {
namespace jit {
-static constexpr int kProtData = PROT_READ | PROT_WRITE;
static constexpr int kProtCode = PROT_READ | PROT_EXEC;
+static constexpr int kProtData = PROT_READ | PROT_WRITE;
+static constexpr int kProtProfile = PROT_READ;
static constexpr size_t kCodeSizeLogThreshold = 50 * KB;
static constexpr size_t kStackMapSizeLogThreshold = 50 * KB;
@@ -192,7 +194,7 @@
// to profile system server.
// NOTE 2: We could just not create the code section at all but we will need to
// special case too many cases.
- int memmap_flags_prot_code = used_only_for_profile_data ? (kProtCode & ~PROT_EXEC) : kProtCode;
+ int memmap_flags_prot_code = used_only_for_profile_data ? kProtProfile : kProtCode;
std::string error_str;
// Map name specific for android_os_Debug.cpp accounting.
@@ -801,6 +803,16 @@
// https://android.googlesource.com/kernel/msm/+/3fbe6bc28a6b9939d0650f2f17eb5216c719950c
FlushInstructionCache(reinterpret_cast<char*>(code_ptr),
reinterpret_cast<char*>(code_ptr + code_size));
+
+ // Ensure CPU instruction pipelines are flushed for all cores. This is necessary for
+ // correctness as code may still be in instruction pipelines despite the i-cache flush. It is
+ // not safe to assume that changing permissions with mprotect (RX->RWX->RX) will cause a TLB
+ // shootdown (incidentally invalidating the CPU pipelines by sending an IPI to all cores to
+ // notify them of the TLB invalidation). Some architectures, notably ARM and ARM64, have
+ // hardware support that broadcasts TLB invalidations and so their kernels have no software
+ // based TLB shootdown. FlushInstructionPipeline() is a wrapper around the Linux
+ // membarrier(MEMBARRIER_CMD_PRIVATE_EXPEDITED) syscall which does the appropriate flushing.
+ FlushInstructionPipeline();
DCHECK(!Runtime::Current()->IsAotCompiler());
if (has_should_deoptimize_flag) {
method_header->SetHasShouldDeoptimizeFlag();
diff --git a/runtime/mirror/object-inl.h b/runtime/mirror/object-inl.h
index bd89907..40832bc 100644
--- a/runtime/mirror/object-inl.h
+++ b/runtime/mirror/object-inl.h
@@ -364,7 +364,7 @@
template<VerifyObjectFlags kVerifyFlags, bool kIsVolatile>
inline int8_t Object::GetFieldByte(MemberOffset field_offset) {
Verify<kVerifyFlags>();
- return GetField<int8_t, kIsVolatile>(field_offset);
+ return GetFieldPrimitive<int8_t, kIsVolatile>(field_offset);
}
template<VerifyObjectFlags kVerifyFlags>
@@ -391,7 +391,7 @@
kIsVolatile);
}
Verify<kVerifyFlags>();
- SetField<uint8_t, kIsVolatile>(field_offset, new_value);
+ SetFieldPrimitive<uint8_t, kIsVolatile>(field_offset, new_value);
}
template<bool kTransactionActive,
@@ -407,7 +407,7 @@
kIsVolatile);
}
Verify<kVerifyFlags>();
- SetField<int8_t, kIsVolatile>(field_offset, new_value);
+ SetFieldPrimitive<int8_t, kIsVolatile>(field_offset, new_value);
}
template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
@@ -425,13 +425,13 @@
template<VerifyObjectFlags kVerifyFlags, bool kIsVolatile>
inline uint16_t Object::GetFieldChar(MemberOffset field_offset) {
Verify<kVerifyFlags>();
- return GetField<uint16_t, kIsVolatile>(field_offset);
+ return GetFieldPrimitive<uint16_t, kIsVolatile>(field_offset);
}
template<VerifyObjectFlags kVerifyFlags, bool kIsVolatile>
inline int16_t Object::GetFieldShort(MemberOffset field_offset) {
Verify<kVerifyFlags>();
- return GetField<int16_t, kIsVolatile>(field_offset);
+ return GetFieldPrimitive<int16_t, kIsVolatile>(field_offset);
}
template<VerifyObjectFlags kVerifyFlags>
@@ -457,7 +457,7 @@
kIsVolatile);
}
Verify<kVerifyFlags>();
- SetField<uint16_t, kIsVolatile>(field_offset, new_value);
+ SetFieldPrimitive<uint16_t, kIsVolatile>(field_offset, new_value);
}
template<bool kTransactionActive,
@@ -473,7 +473,7 @@
kIsVolatile);
}
Verify<kVerifyFlags>();
- SetField<int16_t, kIsVolatile>(field_offset, new_value);
+ SetFieldPrimitive<int16_t, kIsVolatile>(field_offset, new_value);
}
template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
@@ -501,7 +501,7 @@
kIsVolatile);
}
Verify<kVerifyFlags>();
- SetField<int32_t, kIsVolatile>(field_offset, new_value);
+ SetFieldPrimitive<int32_t, kIsVolatile>(field_offset, new_value);
}
template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
@@ -531,7 +531,7 @@
kIsVolatile);
}
Verify<kVerifyFlags>();
- SetField<int64_t, kIsVolatile>(field_offset, new_value);
+ SetFieldPrimitive<int64_t, kIsVolatile>(field_offset, new_value);
}
template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
diff --git a/runtime/mirror/object-readbarrier-inl.h b/runtime/mirror/object-readbarrier-inl.h
index cc375bd..8689e4d 100644
--- a/runtime/mirror/object-readbarrier-inl.h
+++ b/runtime/mirror/object-readbarrier-inl.h
@@ -131,7 +131,7 @@
UNREACHABLE();
}
DCHECK(kUseBakerReadBarrier);
- LockWord lw(GetField<uint32_t, /*kIsVolatile*/false>(MonitorOffset()));
+ LockWord lw(GetFieldPrimitive<uint32_t, /*kIsVolatile*/false>(MonitorOffset()));
uint32_t rb_state = lw.ReadBarrierState();
DCHECK(ReadBarrier::IsValidReadBarrierState(rb_state)) << rb_state;
return rb_state;
diff --git a/runtime/mirror/object.h b/runtime/mirror/object.h
index 47aded3..35946d7 100644
--- a/runtime/mirror/object.h
+++ b/runtime/mirror/object.h
@@ -349,11 +349,35 @@
HeapReference<Object>* GetFieldObjectReferenceAddr(MemberOffset field_offset)
REQUIRES_SHARED(Locks::mutator_lock_);
+ template<typename kType, bool kIsVolatile>
+ ALWAYS_INLINE void SetFieldPrimitive(MemberOffset field_offset, kType new_value)
+ REQUIRES_SHARED(Locks::mutator_lock_) {
+ uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
+ kType* addr = reinterpret_cast<kType*>(raw_addr);
+ if (kIsVolatile) {
+ reinterpret_cast<Atomic<kType>*>(addr)->store(new_value, std::memory_order_seq_cst);
+ } else {
+ reinterpret_cast<Atomic<kType>*>(addr)->StoreJavaData(new_value);
+ }
+ }
+
+ template<typename kType, bool kIsVolatile>
+ ALWAYS_INLINE kType GetFieldPrimitive(MemberOffset field_offset)
+ REQUIRES_SHARED(Locks::mutator_lock_) {
+ const uint8_t* raw_addr = reinterpret_cast<const uint8_t*>(this) + field_offset.Int32Value();
+ const kType* addr = reinterpret_cast<const kType*>(raw_addr);
+ if (kIsVolatile) {
+ return reinterpret_cast<const Atomic<kType>*>(addr)->load(std::memory_order_seq_cst);
+ } else {
+ return reinterpret_cast<const Atomic<kType>*>(addr)->LoadJavaData();
+ }
+ }
+
template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags, bool kIsVolatile = false>
ALWAYS_INLINE uint8_t GetFieldBoolean(MemberOffset field_offset)
REQUIRES_SHARED(Locks::mutator_lock_) {
Verify<kVerifyFlags>();
- return GetField<uint8_t, kIsVolatile>(field_offset);
+ return GetFieldPrimitive<uint8_t, kIsVolatile>(field_offset);
}
template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags, bool kIsVolatile = false>
@@ -440,7 +464,7 @@
ALWAYS_INLINE int32_t GetField32(MemberOffset field_offset)
REQUIRES_SHARED(Locks::mutator_lock_) {
Verify<kVerifyFlags>();
- return GetField<int32_t, kIsVolatile>(field_offset);
+ return GetFieldPrimitive<int32_t, kIsVolatile>(field_offset);
}
template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
@@ -482,7 +506,7 @@
ALWAYS_INLINE int64_t GetField64(MemberOffset field_offset)
REQUIRES_SHARED(Locks::mutator_lock_) {
Verify<kVerifyFlags>();
- return GetField<int64_t, kIsVolatile>(field_offset);
+ return GetFieldPrimitive<int64_t, kIsVolatile>(field_offset);
}
template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
@@ -683,30 +707,6 @@
REQUIRES_SHARED(Locks::mutator_lock_);
private:
- template<typename kSize, bool kIsVolatile>
- ALWAYS_INLINE void SetField(MemberOffset field_offset, kSize new_value)
- REQUIRES_SHARED(Locks::mutator_lock_) {
- uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
- kSize* addr = reinterpret_cast<kSize*>(raw_addr);
- if (kIsVolatile) {
- reinterpret_cast<Atomic<kSize>*>(addr)->store(new_value, std::memory_order_seq_cst);
- } else {
- reinterpret_cast<Atomic<kSize>*>(addr)->StoreJavaData(new_value);
- }
- }
-
- template<typename kSize, bool kIsVolatile>
- ALWAYS_INLINE kSize GetField(MemberOffset field_offset)
- REQUIRES_SHARED(Locks::mutator_lock_) {
- const uint8_t* raw_addr = reinterpret_cast<const uint8_t*>(this) + field_offset.Int32Value();
- const kSize* addr = reinterpret_cast<const kSize*>(raw_addr);
- if (kIsVolatile) {
- return reinterpret_cast<const Atomic<kSize>*>(addr)->load(std::memory_order_seq_cst);
- } else {
- return reinterpret_cast<const Atomic<kSize>*>(addr)->LoadJavaData();
- }
- }
-
// Get a field with acquire semantics.
template<typename kSize>
ALWAYS_INLINE kSize GetFieldAcquire(MemberOffset field_offset)
diff --git a/sigchainlib/sigchain.cc b/sigchainlib/sigchain.cc
index 2e5f46c..cbc3ff8 100644
--- a/sigchainlib/sigchain.cc
+++ b/sigchainlib/sigchain.cc
@@ -490,8 +490,13 @@
}
// Read the current action without looking at the chain, it should be the expected action.
+#if defined(__BIONIC__)
+ struct sigaction64 current_action;
+ linked_sigaction64(signal, nullptr, ¤t_action);
+#else
struct sigaction current_action;
linked_sigaction(signal, nullptr, ¤t_action);
+#endif
// If the sigactions don't match then we put the current action on the chain and make ourself as
// the main action.
diff --git a/sigchainlib/sigchain_test.cc b/sigchainlib/sigchain_test.cc
index 9584ded..53e1e40 100644
--- a/sigchainlib/sigchain_test.cc
+++ b/sigchainlib/sigchain_test.cc
@@ -26,7 +26,8 @@
* SUCH DAMAGE.
*/
-
+#include <dlfcn.h>
+#include <pthread.h>
#include <signal.h>
#include <sys/syscall.h>
@@ -63,10 +64,25 @@
}
art::SigchainAction action = {
- .sc_sigaction = [](int, siginfo_t*, void*) { return true; },
+ .sc_sigaction = [](int, siginfo_t* info, void*) -> bool {
+ return info->si_value.sival_ptr;
+ },
.sc_mask = {},
.sc_flags = 0,
};
+
+ protected:
+ void RaiseHandled() {
+ sigval_t value;
+ value.sival_ptr = &value;
+ pthread_sigqueue(pthread_self(), SIGSEGV, value);
+ }
+
+ void RaiseUnhandled() {
+ sigval_t value;
+ value.sival_ptr = nullptr;
+ pthread_sigqueue(pthread_self(), SIGSEGV, value);
+ }
};
@@ -185,3 +201,40 @@
}
#endif
+
+// Make sure that we properly put ourselves back in front if we get circumvented.
+TEST_F(SigchainTest, EnsureFrontOfChain) {
+#if defined(__BIONIC__)
+ constexpr char kLibcSoName[] = "libc.so";
+#elif defined(__GNU_LIBRARY__) && __GNU_LIBRARY__ == 6
+ constexpr char kLibcSoName[] = "libc.so.6";
+#else
+ #error Unknown libc
+#endif
+ void* libc = dlopen(kLibcSoName, RTLD_LAZY | RTLD_NOLOAD);
+ ASSERT_TRUE(libc);
+
+ static sig_atomic_t called = 0;
+ struct sigaction action = {};
+ action.sa_flags = SA_SIGINFO;
+ action.sa_sigaction = [](int, siginfo_t*, void*) { called = 1; };
+
+ ASSERT_EQ(0, sigaction(SIGSEGV, &action, nullptr));
+
+ // Try before EnsureFrontOfChain.
+ RaiseHandled();
+ ASSERT_EQ(0, called);
+
+ RaiseUnhandled();
+ ASSERT_EQ(1, called);
+ called = 0;
+
+ // ...and after.
+ art::EnsureFrontOfChain(SIGSEGV);
+ ASSERT_EQ(0, called);
+ called = 0;
+
+ RaiseUnhandled();
+ ASSERT_EQ(1, called);
+ called = 0;
+}
diff --git a/test/623-checker-loop-regressions/src/Main.java b/test/623-checker-loop-regressions/src/Main.java
index ff6e335..4097e33 100644
--- a/test/623-checker-loop-regressions/src/Main.java
+++ b/test/623-checker-loop-regressions/src/Main.java
@@ -304,6 +304,19 @@
}
}
+ /// CHECK-START-ARM: void Main.$noinline$stringToShorts(short[], java.lang.String) loop_optimization (after)
+ /// CHECK-NOT: VecLoad
+
+ /// CHECK-START-ARM64: void Main.$noinline$stringToShorts(short[], java.lang.String) loop_optimization (after)
+ /// CHECK-DAG: VecLoad loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: VecStore loop:<<Loop>> outer_loop:none
+ private static void $noinline$stringToShorts(short[] dest, String src) {
+ int min = Math.min(dest.length, src.length());
+ for (int i = 0; i < min; ++i) {
+ dest[i] = (short) src.charAt(i);
+ }
+ }
+
// A strange function that does not inline.
private static void $noinline$foo(boolean x, int n) {
if (n < 0)
@@ -684,6 +697,12 @@
expectEquals(aa[i], cc.charAt(i));
}
+ short[] s2s = new short[12];
+ $noinline$stringToShorts(s2s, "abcdefghijkl");
+ for (int i = 0; i < s2s.length; ++i) {
+ expectEquals((short) "abcdefghijkl".charAt(i), s2s[i]);
+ }
+
envUsesInCond();
short[] dd = new short[23];
diff --git a/tools/ahat/etc/ahat_api.txt b/tools/ahat/etc/ahat_api.txt
index 5426f7b..7aa994a 100644
--- a/tools/ahat/etc/ahat_api.txt
+++ b/tools/ahat/etc/ahat_api.txt
@@ -96,6 +96,7 @@
method public boolean isArrayInstance();
method public boolean isClassInstance();
method public boolean isClassObj();
+ method public boolean isInstanceOfClass(java.lang.String);
method public boolean isPlaceHolder();
method public boolean isRoot();
method public boolean isStronglyReachable();
@@ -226,6 +227,7 @@
method public int getLineNumber();
method public java.lang.String getMethodName();
method public void getObjects(java.lang.String, java.lang.String, java.util.Collection<com.android.ahat.heapdump.AhatInstance>);
+ method public void getObjects(java.util.function.Predicate<com.android.ahat.heapdump.AhatInstance>, java.util.function.Consumer<com.android.ahat.heapdump.AhatInstance>);
method public java.util.List<com.android.ahat.heapdump.Site.ObjectsInfo> getObjectsInfos();
method public com.android.ahat.heapdump.Site getParent();
method public java.lang.String getSignature();
diff --git a/tools/ahat/src/main/com/android/ahat/ObjectsHandler.java b/tools/ahat/src/main/com/android/ahat/ObjectsHandler.java
index 1a8f018..81611b6 100644
--- a/tools/ahat/src/main/com/android/ahat/ObjectsHandler.java
+++ b/tools/ahat/src/main/com/android/ahat/ObjectsHandler.java
@@ -16,6 +16,7 @@
package com.android.ahat;
+import com.android.ahat.heapdump.AhatHeap;
import com.android.ahat.heapdump.AhatInstance;
import com.android.ahat.heapdump.AhatSnapshot;
import com.android.ahat.heapdump.Site;
@@ -24,6 +25,7 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import java.util.function.Predicate;
class ObjectsHandler implements AhatHandler {
private static final String OBJECTS_ID = "objects";
@@ -34,32 +36,102 @@
mSnapshot = snapshot;
}
+ /**
+ * Get the list of instances that match the given site, class, and heap
+ * filters. This method is public to facilitate testing.
+ *
+ * @param site the site to get instances from
+ * @param className non-null name of the class to restrict instances to.
+ * @param subclass if true, include instances of subclasses of the named class.
+ * @param heapName name of the heap to restrict instances to. May be null to
+ * allow instances on any heap.
+ * @return list of matching instances
+ */
+ public static List<AhatInstance> getObjects(
+ Site site, String className, boolean subclass, String heapName) {
+ Predicate<AhatInstance> predicate = (x) -> {
+ return (heapName == null || x.getHeap().getName().equals(heapName))
+ && (subclass ? x.isInstanceOfClass(className) : className.equals(x.getClassName()));
+ };
+
+ List<AhatInstance> insts = new ArrayList<AhatInstance>();
+ site.getObjects(predicate, x -> insts.add(x));
+ return insts;
+ }
+
@Override
public void handle(Doc doc, Query query) throws IOException {
int id = query.getInt("id", 0);
- String className = query.get("class", null);
+ String className = query.get("class", "java.lang.Object");
String heapName = query.get("heap", null);
+ boolean subclass = (query.getInt("subclass", 0) != 0);
Site site = mSnapshot.getSite(id);
- List<AhatInstance> insts = new ArrayList<AhatInstance>();
- site.getObjects(heapName, className, insts);
+ List<AhatInstance> insts = getObjects(site, className, subclass, heapName);
Collections.sort(insts, Sort.defaultInstanceCompare(mSnapshot));
- doc.title("Objects");
+ doc.title("Instances");
- SizeTable.table(doc, mSnapshot.isDiffed(),
- new Column("Heap"),
- new Column("Object"));
+ // Write a description of the current settings, with links to adjust the
+ // settings, such as:
+ // Site: ROOT -
+ // Class: android.os.Binder
+ // Subclasses: excluded (switch to included)
+ // Heap: any (switch to app, image, zygote)
+ // Count: 17,424
+ doc.descriptions();
+ doc.description(DocString.text("Site"), Summarizer.summarize(site));
+ doc.description(DocString.text("Class"), DocString.text(className));
- SubsetSelector<AhatInstance> selector = new SubsetSelector(query, OBJECTS_ID, insts);
- for (AhatInstance inst : selector.selected()) {
- AhatInstance base = inst.getBaseline();
- SizeTable.row(doc, inst.getSize(), base.getSize(),
- DocString.text(inst.getHeap().getName()),
- Summarizer.summarize(inst));
+ DocString subclassChoice = DocString.text(subclass ? "included" : "excluded");
+ subclassChoice.append(" (switch to ");
+ subclassChoice.appendLink(query.with("subclass", subclass ? 0 : 1),
+ DocString.text(subclass ? "excluded" : "included"));
+ subclassChoice.append(")");
+ doc.description(DocString.text("Subclasses"), subclassChoice);
+
+ DocString heapChoice = DocString.text(heapName == null ? "any" : heapName);
+ heapChoice.append(" (switch to ");
+ String comma = "";
+ for (AhatHeap heap : mSnapshot.getHeaps()) {
+ if (!heap.getName().equals(heapName)) {
+ heapChoice.append(comma);
+ heapChoice.appendLink(
+ query.with("heap", heap.getName()),
+ DocString.text(heap.getName()));
+ comma = ", ";
+ }
}
- SizeTable.end(doc);
- selector.render(doc);
+ if (heapName != null) {
+ heapChoice.append(comma);
+ heapChoice.appendLink(
+ query.with("heap", null),
+ DocString.text("any"));
+ }
+ heapChoice.append(")");
+ doc.description(DocString.text("Heap"), heapChoice);
+
+ doc.description(DocString.text("Count"), DocString.format("%,14d", insts.size()));
+ doc.end();
+ doc.println(DocString.text(""));
+
+ if (insts.isEmpty()) {
+ doc.println(DocString.text("(none)"));
+ } else {
+ SizeTable.table(doc, mSnapshot.isDiffed(),
+ new Column("Heap"),
+ new Column("Object"));
+
+ SubsetSelector<AhatInstance> selector = new SubsetSelector(query, OBJECTS_ID, insts);
+ for (AhatInstance inst : selector.selected()) {
+ AhatInstance base = inst.getBaseline();
+ SizeTable.row(doc, inst.getSize(), base.getSize(),
+ DocString.text(inst.getHeap().getName()),
+ Summarizer.summarize(inst));
+ }
+ SizeTable.end(doc);
+ selector.render(doc);
+ }
}
}
diff --git a/tools/ahat/src/main/com/android/ahat/Query.java b/tools/ahat/src/main/com/android/ahat/Query.java
index 9c2783c..5f064cd 100644
--- a/tools/ahat/src/main/com/android/ahat/Query.java
+++ b/tools/ahat/src/main/com/android/ahat/Query.java
@@ -79,7 +79,9 @@
/**
* Return a uri suitable for an href target that links to the current
* page, except with the named query parameter set to the new value.
- *
+ * <p>
+ * <code>value</code> may be null to remove the named query parameter.
+ * <p>
* The generated parameters will be sorted alphabetically so it is easier to
* test.
*/
@@ -92,11 +94,13 @@
params.put(name, value);
String and = "";
for (Map.Entry<String, String> entry : params.entrySet()) {
- newQuery.append(and);
- newQuery.append(entry.getKey());
- newQuery.append('=');
- newQuery.append(entry.getValue());
- and = "&";
+ if (entry.getValue() != null) {
+ newQuery.append(and);
+ newQuery.append(entry.getKey());
+ newQuery.append('=');
+ newQuery.append(entry.getValue());
+ and = "&";
+ }
}
return DocString.uri(newQuery.toString());
}
diff --git a/tools/ahat/src/main/com/android/ahat/heapdump/AhatClassInstance.java b/tools/ahat/src/main/com/android/ahat/heapdump/AhatClassInstance.java
index 4c60d8b..0511798 100644
--- a/tools/ahat/src/main/com/android/ahat/heapdump/AhatClassInstance.java
+++ b/tools/ahat/src/main/com/android/ahat/heapdump/AhatClassInstance.java
@@ -107,21 +107,6 @@
return new ReferenceIterator();
}
- /**
- * Returns true if this is an instance of a (subclass of a) class with the
- * given name.
- */
- private boolean isInstanceOfClass(String className) {
- AhatClassObj cls = getClassObj();
- while (cls != null) {
- if (className.equals(cls.getName())) {
- return true;
- }
- cls = cls.getSuperClassObj();
- }
- return false;
- }
-
@Override public String asString(int maxChars) {
if (!isInstanceOfClass("java.lang.String")) {
return null;
diff --git a/tools/ahat/src/main/com/android/ahat/heapdump/AhatInstance.java b/tools/ahat/src/main/com/android/ahat/heapdump/AhatInstance.java
index 3d691c7..c85a057 100644
--- a/tools/ahat/src/main/com/android/ahat/heapdump/AhatInstance.java
+++ b/tools/ahat/src/main/com/android/ahat/heapdump/AhatInstance.java
@@ -330,6 +330,25 @@
}
/**
+ * Returns true if this is an instance of a (subclass of a) class with the
+ * given name.
+ *
+ * @param className the name of the class to check for
+ * @return true if this is an instance of a (subclass of a) class with the
+ * given name
+ */
+ public boolean isInstanceOfClass(String className) {
+ AhatClassObj cls = getClassObj();
+ while (cls != null) {
+ if (className.equals(cls.getName())) {
+ return true;
+ }
+ cls = cls.getSuperClassObj();
+ }
+ return false;
+ }
+
+ /**
* Returns true if the given instance is an array instance.
*
* @return true if the given instance is an array instance
diff --git a/tools/ahat/src/main/com/android/ahat/heapdump/Site.java b/tools/ahat/src/main/com/android/ahat/heapdump/Site.java
index 46a1729..4f0660f 100644
--- a/tools/ahat/src/main/com/android/ahat/heapdump/Site.java
+++ b/tools/ahat/src/main/com/android/ahat/heapdump/Site.java
@@ -23,6 +23,8 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.function.Consumer;
+import java.util.function.Predicate;
/**
* Used to collection information about objects allocated at a particular
@@ -259,22 +261,37 @@
* every heap should be collected.
* @param className the name of the class the collected objects should
* belong to. This may be null to indicate objects of
- * every class should be collected.
+ * every class should be collected. Instances of subclasses
+ * of this class are not included.
* @param objects out parameter. A collection of objects that all
* collected objects should be added to.
*/
public void getObjects(String heapName, String className, Collection<AhatInstance> objects) {
+ Predicate<AhatInstance> predicate = x -> {
+ return (heapName == null || x.getHeap().getName().equals(heapName))
+ && (className == null || x.getClassName().equals(className));
+ };
+ getObjects(predicate, x -> objects.add(x));
+ }
+
+ /**
+ * Collects the objects allocated under this site, filtered by the given
+ * predicate.
+ * Includes objects allocated in children sites.
+ * @param predicate limit instances to those satisfying this predicate
+ * @param consumer consumer of the objects
+ */
+ public void getObjects(Predicate<AhatInstance> predicate, Consumer<AhatInstance> consumer) {
for (AhatInstance inst : mObjects) {
- if ((heapName == null || inst.getHeap().getName().equals(heapName))
- && (className == null || inst.getClassName().equals(className))) {
- objects.add(inst);
+ if (predicate.test(inst)) {
+ consumer.accept(inst);
}
}
// Recursively visit children. Recursion should be okay here because the
// stack depth is limited by a reasonable amount (128 frames or so).
for (Site child : mChildren) {
- child.getObjects(heapName, className, objects);
+ child.getObjects(predicate, consumer);
}
}
diff --git a/tools/ahat/src/test/com/android/ahat/AhatTestSuite.java b/tools/ahat/src/test/com/android/ahat/AhatTestSuite.java
index 3aa52b5..abc3cc7 100644
--- a/tools/ahat/src/test/com/android/ahat/AhatTestSuite.java
+++ b/tools/ahat/src/test/com/android/ahat/AhatTestSuite.java
@@ -29,6 +29,7 @@
InstanceTest.class,
NativeAllocationTest.class,
ObjectHandlerTest.class,
+ ObjectsHandlerTest.class,
OverviewHandlerTest.class,
PerformanceTest.class,
ProguardMapTest.class,
diff --git a/tools/ahat/src/test/com/android/ahat/ObjectsHandlerTest.java b/tools/ahat/src/test/com/android/ahat/ObjectsHandlerTest.java
new file mode 100644
index 0000000..927e017
--- /dev/null
+++ b/tools/ahat/src/test/com/android/ahat/ObjectsHandlerTest.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ahat;
+
+import com.android.ahat.heapdump.AhatInstance;
+import com.android.ahat.heapdump.AhatSnapshot;
+import com.android.ahat.heapdump.Site;
+import java.io.IOException;
+import java.util.List;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class ObjectsHandlerTest {
+ @Test
+ public void getObjects() throws IOException {
+ TestDump dump = TestDump.getTestDump();
+ AhatSnapshot snapshot = dump.getAhatSnapshot();
+
+ Site root = snapshot.getRootSite();
+
+ // We expect a single instance of DumpedStuff
+ List<AhatInstance> dumped = ObjectsHandler.getObjects(
+ root, "DumpedStuff", /* subclass */ false, /* heapName */ null);
+ assertEquals(1, dumped.size());
+ assertTrue(dumped.get(0).getClassName().equals("DumpedStuff"));
+
+ // We expect no direct instances of SuperDumpedStuff
+ List<AhatInstance> direct = ObjectsHandler.getObjects(
+ root, "SuperDumpedStuff", /* subclass */ false, /* heapName */ null);
+ assertTrue(direct.isEmpty());
+
+ // We expect one subclass instance of SuperDumpedStuff
+ List<AhatInstance> subclass = ObjectsHandler.getObjects(
+ root, "SuperDumpedStuff", /* subclass */ true, /* heapName */ null);
+ assertEquals(1, subclass.size());
+ assertTrue(subclass.get(0).getClassName().equals("DumpedStuff"));
+ assertEquals(dumped.get(0), subclass.get(0));
+ }
+}
diff --git a/tools/ahat/src/test/com/android/ahat/QueryTest.java b/tools/ahat/src/test/com/android/ahat/QueryTest.java
index 5bcf8ea..52cf963 100644
--- a/tools/ahat/src/test/com/android/ahat/QueryTest.java
+++ b/tools/ahat/src/test/com/android/ahat/QueryTest.java
@@ -41,6 +41,7 @@
assertEquals("/object?answer=43&foo=bar", query.with("answer", "43").toString());
assertEquals("/object?answer=43&foo=bar", query.with("answer", 43).toString());
assertEquals("/object?answer=42&bar=finally&foo=bar", query.with("bar", "finally").toString());
+ assertEquals("/object?answer=42", query.with("foo", null).toString());
}
@Test
@@ -55,6 +56,7 @@
assertEquals("/object?answer=43&foo=sludge", query.with("answer", "43").toString());
assertEquals("/object?answer=42&bar=finally&foo=sludge",
query.with("bar", "finally").toString());
+ assertEquals("/object?answer=42", query.with("foo", null).toString());
}
@Test
@@ -66,5 +68,6 @@
assertEquals(2, query.getInt("foo", 2));
assertEquals("/object?foo=sludge", query.with("foo", "sludge").toString());
assertEquals("/object?answer=43", query.with("answer", "43").toString());
+ assertEquals("/object?", query.with("foo", null).toString());
}
}
diff --git a/tools/veridex/hidden_api_finder.cc b/tools/veridex/hidden_api_finder.cc
index 4eba10e..d81f133 100644
--- a/tools/veridex/hidden_api_finder.cc
+++ b/tools/veridex/hidden_api_finder.cc
@@ -178,7 +178,8 @@
stats->linking_count = method_locations_.size() + field_locations_.size();
// Dump methods from hidden APIs linked against.
- for (const std::pair<std::string, std::vector<MethodReference>>& pair : method_locations_) {
+ for (const std::pair<const std::string,
+ std::vector<MethodReference>>& pair : method_locations_) {
HiddenApiAccessFlags::ApiList api_list = hidden_api_.GetApiList(pair.first);
stats->api_counts[api_list]++;
os << "#" << ++stats->count << ": Linking " << api_list << " " << pair.first << " use(s):";
@@ -190,7 +191,8 @@
}
// Dump fields from hidden APIs linked against.
- for (const std::pair<std::string, std::vector<MethodReference>>& pair : field_locations_) {
+ for (const std::pair<const std::string,
+ std::vector<MethodReference>>& pair : field_locations_) {
HiddenApiAccessFlags::ApiList api_list = hidden_api_.GetApiList(pair.first);
stats->api_counts[api_list]++;
os << "#" << ++stats->count << ": Linking " << api_list << " " << pair.first << " use(s):";