diff options
99 files changed, 2170 insertions, 4765 deletions
diff --git a/compiler/optimizing/code_generator_vector_arm64.cc b/compiler/optimizing/code_generator_vector_arm64.cc index 6d135a9bfb..43169ba7eb 100644 --- a/compiler/optimizing/code_generator_vector_arm64.cc +++ b/compiler/optimizing/code_generator_vector_arm64.cc @@ -1354,6 +1354,7 @@ void InstructionCodeGeneratorARM64::VisitVecLoad(HVecLoad* instruction) { 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 @@ void InstructionCodeGeneratorARM64::VisitVecLoad(HVecLoad* instruction) { 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 086ae07a06..2502275b3a 100644 --- a/compiler/optimizing/code_generator_vector_x86.cc +++ b/compiler/optimizing/code_generator_vector_x86.cc @@ -1205,6 +1205,7 @@ void InstructionCodeGeneratorX86::VisitVecLoad(HVecLoad* instruction) { 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 @@ void InstructionCodeGeneratorX86::VisitVecLoad(HVecLoad* instruction) { 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 4d31ab68d1..4a67dafd8a 100644 --- a/compiler/optimizing/code_generator_vector_x86_64.cc +++ b/compiler/optimizing/code_generator_vector_x86_64.cc @@ -1178,6 +1178,7 @@ void InstructionCodeGeneratorX86_64::VisitVecLoad(HVecLoad* instruction) { 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 @@ void InstructionCodeGeneratorX86_64::VisitVecLoad(HVecLoad* instruction) { 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/runtime/entrypoints/entrypoint_utils-inl.h b/runtime/entrypoints/entrypoint_utils-inl.h index e6f3d0b0d5..1045d2adc9 100644 --- a/runtime/entrypoints/entrypoint_utils-inl.h +++ b/runtime/entrypoints/entrypoint_utils-inl.h @@ -317,20 +317,9 @@ inline ArtField* FindFieldFromCode(uint32_t field_idx, 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 @@ inline ArtField* FindFieldFast(uint32_t field_idx, ArtMethod* referrer, FindFiel 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 9d70b03dfa..c8bf6d08ab 100644 --- a/runtime/entrypoints/entrypoint_utils.h +++ b/runtime/entrypoints/entrypoint_utils.h @@ -103,16 +103,25 @@ ALWAYS_INLINE inline mirror::Array* AllocArrayFromCodeResolved(mirror::Class* kl 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 62cc9dee27..d38e3edce9 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 @@ ALWAYS_INLINE static inline ArtField* FindInstanceField(uint32_t field_idx, 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 3a800088ba..0c187675ba 100644 --- a/runtime/gc/collector/concurrent_copying.cc +++ b/runtime/gc/collector/concurrent_copying.cc @@ -2331,6 +2331,7 @@ void ConcurrentCopying::AssertToSpaceInvariantInNonMovingSpace(mirror::Object* o 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 @@ void ConcurrentCopying::AssertToSpaceInvariantInNonMovingSpace(mirror::Object* o << " 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 0000000000..c46878829e --- /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 1684a768df..1fa32faa99 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 46e9ec869b..ede21ebd35 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 a16795da64..6201d805f0 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 4f401eb4f0..1003d10d4f 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 6a414738d9..f2845ad29c 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 575a8c0760..b382de4c8d 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 5981ec4957..d6905df7d8 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 c4a8978cd1..171f02444b 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 c58918fbbb..8fcd52e2c4 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 0ed4017ce9..c254f7834c 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 0000000000..631c8d191b --- /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 cb453ac524..48b9cad44b 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 3b17144478..9a83b2a596 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 d5ef1d3c2b..f73e634621 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 68e1435201..a5efd9e3ed 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 714f4b9aef..bb81c1708e 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 4fc735ce6b..70061d6577 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 5e21d5c6de..2bc3db9050 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 0c0441a3f0..e9bb93f0a5 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 be6aeb0e3d..e1fafad5a7 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 00b07fa484..78e95b2e7c 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 73f3a107f4..0cf9f09681 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 38c0da614f..7c88a81faa 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 c0801bfa2b..883e944ce5 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 81e043453e..6cb918433d 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 546ab9482d..f5d182e96d 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 7a0dc30c52..d229d0d899 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 a64965614b..536f1b16b8 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 58b3c42333..b4be6b2987 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 0000000000..1333ed77b7 --- /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 33717de640..e218272196 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 858a8898f4..885372a529 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 4dd4075e92..efbdfbad78 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 c96a4d4ec7..6f7e7b760f 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 dccb6b71b1..fc862e4fa7 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 8750a17a41..92d667335b 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 76f78cb35d..be4ae027cb 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 547de3964a..c858679762 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 55c88a6816..683b76789d 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 cfaaaee6f3..1d2ed196f3 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 0000000000..1333ed77b7 --- /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 a8ce94c3ba..e91f09923b 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 08bf544265..40f364571f 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 9a789e612d..81ab911b5e 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 dd1938ec63..d3316dd756 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 62726908fb..05194b33f3 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 b7b0382b1c..200da35a12 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 fe2deb1479..8abb396c57 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 a7e2bef4bc..68623f604c 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 ed86f32588..3c7b962813 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 f708a201ce..9a8579ba5b 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 7c31252aed..14f232c073 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 28b8c3ea26..0bd683767f 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 ff43967666..09bd0fb7ba 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 bfb6983bb4..070d17ff4d 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 7b37c9aaef..65c1aa8a79 100644 --- a/runtime/interpreter/mterp/mterp.cc +++ b/runtime/interpreter/mterp/mterp.cc @@ -490,24 +490,6 @@ extern "C" size_t MterpNewInstance(ShadowFrame* shadow_frame, Thread* self, uint 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 @@ extern "C" size_t MterpSuspendCheck(Thread* self) 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>( +// 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); + } + } + } +} + +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)) { - return 0; // Will throw exception by checking with Thread::Current. + DCHECK(self->IsExceptionPending()); + return false; } - if (UNLIKELY(h == nullptr)) { - ThrowNullPointerExceptionForFieldAccess(field, /*is_read*/ true); - return 0; // Will throw exception by checking with Thread::Current. + 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; } - return Getter::Get(obj, field); + MterpFieldAccess<PrimType, kAccessType>( + inst, inst_data, shadow_frame, obj, field->GetOffset(), field->IsVolatile()); + return true; } -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> +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); -} - -#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 -} - -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 -} - -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 -} - -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 -} - -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; + // Slow path. Last and with identical arguments so that it becomes single instruction tail call. + return MterpFieldAccessSlow<PrimType, kAccessType>(inst, inst_data, shadow_frame, self); } -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>); +#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" 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>); -} +#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" 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>); -} +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" 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>); -} +// 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" 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 394a84924c..25512aec37 100644 --- a/runtime/interpreter/mterp/out/mterp_arm.S +++ b/runtime/interpreter/mterp/out/mterp_arm.S @@ -2246,309 +2246,260 @@ artMterpAsmInstructionStart = .L_op_nop .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 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 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 + 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 - 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_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 @@ artMterpAsmInstructionStart = .L_op_nop .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 @@ artMterpAsmInstructionStart = .L_op_nop .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 @@ artMterpAsmInstructionStart = .L_op_nop .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 @@ artMterpAsmInstructionStart = .L_op_nop .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 @@ artMterpAsmInstructionStart = .L_op_nop .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 @@ artMterpAsmInstructionStart = .L_op_nop .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 @@ artMterpAsmInstructionStart = .L_op_nop .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 @@ artMterpAsmInstructionStart = .L_op_nop .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 @@ artMterpAsmInstructionStart = .L_op_nop .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 @@ artMterpAsmInstructionStart = .L_op_nop .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 5f4aa4f256..fd60c95a37 100644 --- a/runtime/interpreter/mterp/out/mterp_arm64.S +++ b/runtime/interpreter/mterp/out/mterp_arm64.S @@ -2183,303 +2183,249 @@ artMterpAsmInstructionStart = .L_op_nop .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 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 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 + 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 - 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_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 @@ artMterpAsmInstructionStart = .L_op_nop .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 @@ artMterpAsmInstructionStart = .L_op_nop .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 @@ artMterpAsmInstructionStart = .L_op_nop .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 */ - /* - * SGET_WIDE handler wrapper. - * - */ - /* sget-wide vAA, field//BBBB */ +/* File: arm64/op_sget.S */ +/* File: arm64/field.S */ + /* + * General field read / write (iget-* iput-* sget-* sput-*). + */ + .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 @@ artMterpAsmInstructionStart = .L_op_nop .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 @@ artMterpAsmInstructionStart = .L_op_nop .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 @@ artMterpAsmInstructionStart = .L_op_nop .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 @@ artMterpAsmInstructionStart = .L_op_nop .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 */ - /* - * 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 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 +/* File: arm64/field.S */ + /* + * General field read / write (iget-* iput-* sget-* sput-*). + */ + .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 */ - /* - * 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 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 +/* File: arm64/field.S */ + /* + * General field read / write (iget-* iput-* sget-* sput-*). + */ + .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 @@ artMterpAsmInstructionStart = .L_op_nop .L_op_sput_byte: /* 0x6b */ /* File: arm64/op_sput_byte.S */ /* File: arm64/op_sput.S */ - /* - * 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 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 +/* File: arm64/field.S */ + /* + * General field read / write (iget-* iput-* sget-* sput-*). + */ + .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 @@ artMterpAsmInstructionStart = .L_op_nop .L_op_sput_char: /* 0x6c */ /* File: arm64/op_sput_char.S */ /* File: arm64/op_sput.S */ - /* - * 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 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 +/* File: arm64/field.S */ + /* + * General field read / write (iget-* iput-* sget-* sput-*). + */ + .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 @@ artMterpAsmInstructionStart = .L_op_nop .L_op_sput_short: /* 0x6d */ /* File: arm64/op_sput_short.S */ /* File: arm64/op_sput.S */ - /* - * 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 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 +/* File: arm64/field.S */ + /* + * General field read / write (iget-* iput-* sget-* sput-*). + */ + .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 fb7d52eed4..1f5bea0873 100644 --- a/runtime/interpreter/mterp/out/mterp_mips.S +++ b/runtime/interpreter/mterp/out/mterp_mips.S @@ -2665,85 +2665,28 @@ artMterpAsmInstructionStart = .L_op_nop .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 @@ artMterpAsmInstructionStart = .L_op_nop .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 @@ artMterpAsmInstructionStart = .L_op_nop .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 @@ artMterpAsmInstructionStart = .L_op_nop .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 @@ artMterpAsmInstructionStart = .L_op_nop .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 @@ artMterpAsmInstructionStart = .L_op_nop .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 @@ artMterpAsmInstructionStart = .L_op_nop .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 @@ artMterpAsmInstructionStart = .L_op_nop .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 @@ artMterpAsmInstructionStart = .L_op_nop .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 @@ artMterpAsmInstructionStart = .L_op_nop .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 @@ artMterpAsmInstructionStart = .L_op_nop .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 @@ artMterpAsmInstructionStart = .L_op_nop .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 @@ artMterpAsmInstructionStart = .L_op_nop .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 @@ artMterpAsmInstructionStart = .L_op_nop .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 @@ artMterpAsmInstructionStart = .L_op_nop .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 65616919c9..40a8396f77 100644 --- a/runtime/interpreter/mterp/out/mterp_mips64.S +++ b/runtime/interpreter/mterp/out/mterp_mips64.S @@ -2241,88 +2241,28 @@ artMterpAsmInstructionStart = .L_op_nop .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 @@ artMterpAsmInstructionStart = .L_op_nop .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 @@ artMterpAsmInstructionStart = .L_op_nop .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 @@ artMterpAsmInstructionStart = .L_op_nop .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 @@ artMterpAsmInstructionStart = .L_op_nop .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 @@ artMterpAsmInstructionStart = .L_op_nop .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 @@ artMterpAsmInstructionStart = .L_op_nop .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 @@ artMterpAsmInstructionStart = .L_op_nop .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 @@ artMterpAsmInstructionStart = .L_op_nop .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 @@ artMterpAsmInstructionStart = .L_op_nop .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 @@ artMterpAsmInstructionStart = .L_op_nop .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 @@ artMterpAsmInstructionStart = .L_op_nop .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 @@ artMterpAsmInstructionStart = .L_op_nop .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 @@ artMterpAsmInstructionStart = .L_op_nop .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 @@ artMterpAsmInstructionStart = .L_op_nop .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 3f709199b9..32811ff370 100644 --- a/runtime/interpreter/mterp/out/mterp_x86.S +++ b/runtime/interpreter/mterp/out/mterp_x86.S @@ -2120,832 +2120,694 @@ SYMBOL(artMterpAsmInstructionStart) = .L_op_nop .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 89d56372af..6d8bb4c7c4 100644 --- a/runtime/interpreter/mterp/out/mterp_x86_64.S +++ b/runtime/interpreter/mterp/out/mterp_x86_64.S @@ -2067,770 +2067,610 @@ SYMBOL(artMterpAsmInstructionStart) = .L_op_nop .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 0000000000..8432c744ea --- /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 0af1becb24..d85d54c515 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 da27df952b..741a64e4cb 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 4c6603a572..3628ffdb56 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 56e026e40a..a124b7ed41 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 ea22b919c3..2820ede182 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 66c7b0bac5..ada4e0e26a 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 994cc3aebb..59232749a2 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 e99e7a7239..2ad68e7683 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 941b07201e..4452dba272 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 f58150706e..d79b068f33 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 0000000000..f8b0588e1b --- /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 5c6cab6acb..4ab7c27c51 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 d9d174400c..a85a474845 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 12affdbe84..dad5af664b 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 22648cdde7..202e33fa76 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 4f8c47c1e6..db520167d2 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 c15ac1e280..21e8e64b8b 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 65ddb8a09c..c53c0773a5 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 9a33d521b9..7dd24985ff 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 8a47074ec3..c2bd07bcc8 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 464d1697ac..7e77072dce 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/mirror/object-inl.h b/runtime/mirror/object-inl.h index bd89907ae2..40832bc4e9 100644 --- a/runtime/mirror/object-inl.h +++ b/runtime/mirror/object-inl.h @@ -364,7 +364,7 @@ inline size_t Object::SizeOf() { 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 @@ inline void Object::SetFieldBoolean(MemberOffset field_offset, uint8_t new_value 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 @@ inline void Object::SetFieldByte(MemberOffset field_offset, int8_t new_value) { 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 @@ inline void Object::SetFieldByteVolatile(MemberOffset field_offset, int8_t new_v 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 @@ inline void Object::SetFieldChar(MemberOffset field_offset, uint16_t new_value) 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 @@ inline void Object::SetFieldShort(MemberOffset field_offset, int16_t new_value) 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 @@ inline void Object::SetField32(MemberOffset field_offset, int32_t new_value) { 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 @@ inline void Object::SetField64(MemberOffset field_offset, int64_t new_value) { 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 cc375bd796..8689e4dadb 100644 --- a/runtime/mirror/object-readbarrier-inl.h +++ b/runtime/mirror/object-readbarrier-inl.h @@ -131,7 +131,7 @@ inline uint32_t Object::GetReadBarrierState() { 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 47aded3f0c..35946d78fe 100644 --- a/runtime/mirror/object.h +++ b/runtime/mirror/object.h @@ -349,11 +349,35 @@ class MANAGED LOCKABLE Object { 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 @@ class MANAGED LOCKABLE Object { 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 @@ class MANAGED LOCKABLE Object { 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 @@ class MANAGED LOCKABLE Object { 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 2e5f46ca69..cbc3ff8483 100644 --- a/sigchainlib/sigchain.cc +++ b/sigchainlib/sigchain.cc @@ -490,8 +490,13 @@ extern "C" void EnsureFrontOfChain(int signal) { } // 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 9584ded65f..53e1e40454 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 @@ class SigchainTest : public ::testing::Test { } 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 @@ TEST_F(SigchainTest, sigsetmask) { } #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 ff6e335b7f..4097e33564 100644 --- a/test/623-checker-loop-regressions/src/Main.java +++ b/test/623-checker-loop-regressions/src/Main.java @@ -304,6 +304,19 @@ public class Main { } } + /// 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 @@ public class Main { 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/veridex/hidden_api_finder.cc b/tools/veridex/hidden_api_finder.cc index 4eba10e764..d81f133f67 100644 --- a/tools/veridex/hidden_api_finder.cc +++ b/tools/veridex/hidden_api_finder.cc @@ -178,7 +178,8 @@ void HiddenApiFinder::Dump(std::ostream& os, 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 @@ void HiddenApiFinder::Dump(std::ostream& os, } // 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):"; |