summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dexdump/OpCodeNames.c16
-rw-r--r--libdex/InstrUtils.c48
-rw-r--r--libdex/OpCode.h37
-rw-r--r--vm/Atomic.c8
-rw-r--r--vm/Atomic.h2
-rw-r--r--vm/DalvikVersion.h2
-rw-r--r--vm/analysis/CodeVerify.c16
-rw-r--r--vm/compiler/Dataflow.c16
-rw-r--r--vm/compiler/codegen/arm/CodegenDriver.c5
-rw-r--r--vm/mterp/armv4t/platform.S6
-rw-r--r--vm/mterp/armv5te/OP_IGET.S3
-rw-r--r--vm/mterp/armv5te/OP_IGET_OBJECT_VOLATILE.S2
-rw-r--r--vm/mterp/armv5te/OP_IGET_VOLATILE.S2
-rw-r--r--vm/mterp/armv5te/OP_IGET_WIDE.S2
-rw-r--r--vm/mterp/armv5te/OP_IPUT.S3
-rw-r--r--vm/mterp/armv5te/OP_IPUT_OBJECT_VOLATILE.S2
-rw-r--r--vm/mterp/armv5te/OP_IPUT_VOLATILE.S2
-rw-r--r--vm/mterp/armv5te/OP_IPUT_WIDE.S2
-rw-r--r--vm/mterp/armv5te/OP_SGET.S2
-rw-r--r--vm/mterp/armv5te/OP_SGET_OBJECT_VOLATILE.S2
-rw-r--r--vm/mterp/armv5te/OP_SGET_VOLATILE.S2
-rw-r--r--vm/mterp/armv5te/OP_SPUT.S2
-rw-r--r--vm/mterp/armv5te/OP_SPUT_OBJECT_VOLATILE.S2
-rw-r--r--vm/mterp/armv5te/OP_SPUT_VOLATILE.S2
-rw-r--r--vm/mterp/armv5te/OP_UNUSED_E3.S1
-rw-r--r--vm/mterp/armv5te/OP_UNUSED_E4.S1
-rw-r--r--vm/mterp/armv5te/OP_UNUSED_E5.S1
-rw-r--r--vm/mterp/armv5te/OP_UNUSED_E6.S1
-rw-r--r--vm/mterp/armv5te/OP_UNUSED_E7.S1
-rw-r--r--vm/mterp/armv5te/OP_UNUSED_FC.S1
-rw-r--r--vm/mterp/armv5te/OP_UNUSED_FD.S1
-rw-r--r--vm/mterp/armv5te/OP_UNUSED_FE.S1
-rw-r--r--vm/mterp/armv5te/header.S1
-rw-r--r--vm/mterp/armv5te/platform.S6
-rw-r--r--vm/mterp/armv7-a/platform.S53
-rw-r--r--vm/mterp/c/OP_IGET_OBJECT_VOLATILE.c2
-rw-r--r--vm/mterp/c/OP_IGET_VOLATILE.c2
-rw-r--r--vm/mterp/c/OP_IPUT_OBJECT_VOLATILE.c2
-rw-r--r--vm/mterp/c/OP_IPUT_VOLATILE.c2
-rw-r--r--vm/mterp/c/OP_SGET_OBJECT_VOLATILE.c2
-rw-r--r--vm/mterp/c/OP_SGET_VOLATILE.c2
-rw-r--r--vm/mterp/c/OP_SPUT_OBJECT_VOLATILE.c2
-rw-r--r--vm/mterp/c/OP_SPUT_VOLATILE.c2
-rw-r--r--vm/mterp/c/OP_UNUSED_E3.c2
-rw-r--r--vm/mterp/c/OP_UNUSED_E4.c2
-rw-r--r--vm/mterp/c/OP_UNUSED_E5.c2
-rw-r--r--vm/mterp/c/OP_UNUSED_E6.c2
-rw-r--r--vm/mterp/c/OP_UNUSED_E7.c2
-rw-r--r--vm/mterp/c/OP_UNUSED_FC.c2
-rw-r--r--vm/mterp/c/OP_UNUSED_FD.c2
-rw-r--r--vm/mterp/c/OP_UNUSED_FE.c2
-rw-r--r--vm/mterp/config-armv7-a2
-rw-r--r--vm/mterp/config-armv7-a-neon2
-rw-r--r--vm/mterp/config-x868
-rw-r--r--vm/mterp/config-x86-atom8
-rw-r--r--vm/mterp/out/InterpAsm-armv4t.S396
-rw-r--r--vm/mterp/out/InterpAsm-armv5te-vfp.S404
-rw-r--r--vm/mterp/out/InterpAsm-armv5te.S404
-rw-r--r--vm/mterp/out/InterpAsm-armv7-a-neon.S411
-rw-r--r--vm/mterp/out/InterpAsm-armv7-a.S411
-rw-r--r--vm/mterp/out/InterpAsm-x86-atom.S352
-rw-r--r--vm/mterp/out/InterpAsm-x86.S144
-rw-r--r--vm/mterp/out/InterpC-allstubs.c32
-rw-r--r--vm/mterp/out/InterpC-portdbg.c32
-rw-r--r--vm/mterp/out/InterpC-portstd.c32
-rw-r--r--vm/mterp/out/InterpC-x86-atom.c32
-rw-r--r--vm/mterp/out/InterpC-x86.c32
-rw-r--r--vm/mterp/x86-atom/TODO.txt4
-rw-r--r--vm/oo/Object.h42
69 files changed, 2368 insertions, 666 deletions
diff --git a/dexdump/OpCodeNames.c b/dexdump/OpCodeNames.c
index e3155743d..1901f15ea 100644
--- a/dexdump/OpCodeNames.c
+++ b/dexdump/OpCodeNames.c
@@ -287,11 +287,11 @@ static const char* gOpNames[256] = {
"shl-int/lit8",
"shr-int/lit8",
"ushr-int/lit8",
- "UNUSED",
- "UNUSED",
- "UNUSED",
- "UNUSED",
- "UNUSED",
+ "+iget-volatile",
+ "+iput-volatile",
+ "+sget-volatile",
+ "+sput-volatile",
+ "+iget-object-volatile",
"+iget-wide-volatile",
"+iput-wide-volatile",
"+sget-wide-volatile",
@@ -314,9 +314,9 @@ static const char* gOpNames[256] = {
"+invoke-virtual-quick/range",
"+invoke-super-quick",
"+invoke-super-quick/range",
- "UNUSED",
- "UNUSED",
- "UNUSED",
+ "+iput-object-volatile",
+ "+sget-object-volatile",
+ "+sput-object-volatile",
"UNUSED",
};
diff --git a/libdex/InstrUtils.c b/libdex/InstrUtils.c
index 79095ae9e..a3ee859bb 100644
--- a/libdex/InstrUtils.c
+++ b/libdex/InstrUtils.c
@@ -297,6 +297,14 @@ InstructionWidth* dexCreateInstrWidthTable(void)
case OP_IPUT_QUICK:
case OP_IPUT_WIDE_QUICK:
case OP_IPUT_OBJECT_QUICK:
+ case OP_IGET_VOLATILE:
+ case OP_IPUT_VOLATILE:
+ case OP_SGET_VOLATILE:
+ case OP_SPUT_VOLATILE:
+ case OP_IGET_OBJECT_VOLATILE:
+ case OP_IPUT_OBJECT_VOLATILE:
+ case OP_SGET_OBJECT_VOLATILE:
+ case OP_SPUT_OBJECT_VOLATILE:
case OP_IGET_WIDE_VOLATILE:
case OP_IPUT_WIDE_VOLATILE:
case OP_SGET_WIDE_VOLATILE:
@@ -324,16 +332,8 @@ InstructionWidth* dexCreateInstrWidthTable(void)
case OP_UNUSED_73:
case OP_UNUSED_79:
case OP_UNUSED_7A:
- case OP_UNUSED_E3:
- case OP_UNUSED_E4:
- case OP_UNUSED_E5:
- case OP_UNUSED_E6:
- case OP_UNUSED_E7:
case OP_BREAKPOINT:
case OP_UNUSED_F1:
- case OP_UNUSED_FC:
- case OP_UNUSED_FD:
- case OP_UNUSED_FE:
case OP_UNUSED_FF:
assert(width == 0);
break;
@@ -628,6 +628,14 @@ InstructionFlags* dexCreateInstrFlagsTable(void)
case OP_IPUT_QUICK:
case OP_IPUT_WIDE_QUICK:
case OP_IPUT_OBJECT_QUICK:
+ case OP_IGET_VOLATILE:
+ case OP_IPUT_VOLATILE:
+ case OP_SGET_VOLATILE:
+ case OP_SPUT_VOLATILE:
+ case OP_IGET_OBJECT_VOLATILE:
+ case OP_IPUT_OBJECT_VOLATILE:
+ case OP_SGET_OBJECT_VOLATILE:
+ case OP_SPUT_OBJECT_VOLATILE:
case OP_IGET_WIDE_VOLATILE:
case OP_IPUT_WIDE_VOLATILE:
case OP_SGET_WIDE_VOLATILE:
@@ -653,16 +661,8 @@ InstructionFlags* dexCreateInstrFlagsTable(void)
case OP_UNUSED_73:
case OP_UNUSED_79:
case OP_UNUSED_7A:
- case OP_UNUSED_E3:
- case OP_UNUSED_E4:
- case OP_UNUSED_E5:
- case OP_UNUSED_E6:
- case OP_UNUSED_E7:
case OP_BREAKPOINT:
case OP_UNUSED_F1:
- case OP_UNUSED_FC:
- case OP_UNUSED_FD:
- case OP_UNUSED_FE:
case OP_UNUSED_FF:
break;
@@ -973,6 +973,14 @@ InstructionFormat* dexCreateInstrFormatTable(void)
case OP_IPUT_WIDE_VOLATILE:
case OP_SGET_WIDE_VOLATILE:
case OP_SPUT_WIDE_VOLATILE:
+ case OP_IGET_VOLATILE:
+ case OP_IPUT_VOLATILE:
+ case OP_SGET_VOLATILE:
+ case OP_SPUT_VOLATILE:
+ case OP_IGET_OBJECT_VOLATILE:
+ case OP_IPUT_OBJECT_VOLATILE:
+ case OP_SGET_OBJECT_VOLATILE:
+ case OP_SPUT_OBJECT_VOLATILE:
fmt = kFmt22c;
break;
case OP_IGET_QUICK:
@@ -1011,16 +1019,8 @@ InstructionFormat* dexCreateInstrFormatTable(void)
case OP_UNUSED_73:
case OP_UNUSED_79:
case OP_UNUSED_7A:
- case OP_UNUSED_E3:
- case OP_UNUSED_E4:
- case OP_UNUSED_E5:
- case OP_UNUSED_E6:
- case OP_UNUSED_E7:
case OP_BREAKPOINT:
case OP_UNUSED_F1:
- case OP_UNUSED_FC:
- case OP_UNUSED_FD:
- case OP_UNUSED_FE:
case OP_UNUSED_FF:
fmt = kFmtUnknown;
break;
diff --git a/libdex/OpCode.h b/libdex/OpCode.h
index f0bc423b4..312ff0175 100644
--- a/libdex/OpCode.h
+++ b/libdex/OpCode.h
@@ -321,13 +321,13 @@ typedef enum OpCode {
OP_SHR_INT_LIT8 = 0xe1,
OP_USHR_INT_LIT8 = 0xe2,
- OP_UNUSED_E3 = 0xe3,
- OP_UNUSED_E4 = 0xe4,
- OP_UNUSED_E5 = 0xe5,
- OP_UNUSED_E6 = 0xe6,
- OP_UNUSED_E7 = 0xe7,
-
/* verifier/optimizer output -- nothing below here is generated by "dx" */
+ OP_IGET_VOLATILE = 0xe3,
+ OP_IPUT_VOLATILE = 0xe4,
+ OP_SGET_VOLATILE = 0xe5,
+ OP_SPUT_VOLATILE = 0xe6,
+ OP_IGET_OBJECT_VOLATILE = 0xe7,
+
OP_IGET_WIDE_VOLATILE = 0xe8,
OP_IPUT_WIDE_VOLATILE = 0xe9,
OP_SGET_WIDE_VOLATILE = 0xea,
@@ -359,10 +359,11 @@ typedef enum OpCode {
OP_INVOKE_VIRTUAL_QUICK_RANGE = 0xf9,
OP_INVOKE_SUPER_QUICK = 0xfa,
OP_INVOKE_SUPER_QUICK_RANGE = 0xfb,
- OP_UNUSED_FC = 0xfc, /* OP_INVOKE_DIRECT_QUICK? */
- OP_UNUSED_FD = 0xfd, /* OP_INVOKE_DIRECT_QUICK_RANGE? */
- OP_UNUSED_FE = 0xfe, /* OP_INVOKE_INTERFACE_QUICK? */
- OP_UNUSED_FF = 0xff, /* OP_INVOKE_INTERFACE_QUICK_RANGE*/
+ OP_IPUT_OBJECT_VOLATILE = 0xfc,
+ OP_SGET_OBJECT_VOLATILE = 0xfd,
+ OP_SPUT_OBJECT_VOLATILE = 0xfe,
+
+ OP_UNUSED_FF = 0xff, /* reserved for code expansion */
} OpCode;
#define kNumDalvikInstructions 256
@@ -628,11 +629,11 @@ typedef enum OpCode {
H(OP_SHL_INT_LIT8), \
H(OP_SHR_INT_LIT8), \
H(OP_USHR_INT_LIT8), \
- H(OP_UNUSED_E3), \
- H(OP_UNUSED_E4), \
- H(OP_UNUSED_E5), \
- H(OP_UNUSED_E6), \
- H(OP_UNUSED_E7), \
+ H(OP_IGET_VOLATILE), \
+ H(OP_IPUT_VOLATILE), \
+ H(OP_SGET_VOLATILE), \
+ H(OP_SPUT_VOLATILE), \
+ H(OP_IGET_OBJECT_VOLATILE), \
H(OP_IGET_WIDE_VOLATILE), \
H(OP_IPUT_WIDE_VOLATILE), \
H(OP_SGET_WIDE_VOLATILE), \
@@ -654,9 +655,9 @@ typedef enum OpCode {
H(OP_INVOKE_VIRTUAL_QUICK_RANGE), \
H(OP_INVOKE_SUPER_QUICK), \
H(OP_INVOKE_SUPER_QUICK_RANGE), \
- H(OP_UNUSED_FC), \
- H(OP_UNUSED_FD), \
- H(OP_UNUSED_FE), \
+ H(OP_IPUT_OBJECT_VOLATILE), \
+ H(OP_SGET_OBJECT_VOLATILE), \
+ H(OP_SPUT_OBJECT_VOLATILE), \
H(OP_UNUSED_FF), \
};
diff --git a/vm/Atomic.c b/vm/Atomic.c
index 6a5381cda..4473c8568 100644
--- a/vm/Atomic.c
+++ b/vm/Atomic.c
@@ -56,7 +56,7 @@ int64_t dvmQuasiAtomicSwap64(int64_t value, volatile int64_t* addr)
return oldValue;
}
-int64_t dvmQuasiAtomicRead64(volatile int64_t* addr)
+int64_t dvmQuasiAtomicRead64(volatile const int64_t* addr)
{
return OSAtomicAdd64Barrier(0, addr);
}
@@ -103,7 +103,7 @@ int dvmQuasiAtomicCas64(int64_t oldvalue, int64_t newvalue,
return prev != oldvalue;
}
-int64_t dvmQuasiAtomicRead64(volatile int64_t* addr)
+int64_t dvmQuasiAtomicRead64(volatile const int64_t* addr)
{
int64_t value;
__asm__ __volatile__ ("@ dvmQuasiAtomicRead64\n"
@@ -171,7 +171,7 @@ int dvmQuasiAtomicCas64(int64_t oldvalue, int64_t newvalue,
return result;
}
-int64_t dvmQuasiAtomicRead64(volatile int64_t* addr)
+int64_t dvmQuasiAtomicRead64(volatile const int64_t* addr)
{
int64_t result;
pthread_mutex_t* lock = SWAP_LOCK(addr);
@@ -242,7 +242,7 @@ int dvmQuasiAtomicCas64(int64_t oldvalue, int64_t newvalue,
return result;
}
-int64_t dvmQuasiAtomicRead64(volatile int64_t* addr)
+int64_t dvmQuasiAtomicRead64(volatile const int64_t* addr)
{
int64_t result;
diff --git a/vm/Atomic.h b/vm/Atomic.h
index 0585c95cf..6c3a66f6b 100644
--- a/vm/Atomic.h
+++ b/vm/Atomic.h
@@ -43,7 +43,7 @@ int64_t dvmQuasiAtomicSwap64(int64_t value, volatile int64_t* addr);
/*
* Read the 64-bit value at "addr".
*/
-int64_t dvmQuasiAtomicRead64(volatile int64_t* addr);
+int64_t dvmQuasiAtomicRead64(volatile const int64_t* addr);
/*
* If the value at "addr" is equal to "oldvalue", replace it with "newvalue"
diff --git a/vm/DalvikVersion.h b/vm/DalvikVersion.h
index 97976ddfd..3bc37b081 100644
--- a/vm/DalvikVersion.h
+++ b/vm/DalvikVersion.h
@@ -32,6 +32,6 @@
* way classes load changes, e.g. field ordering or vtable layout. Changing
* this guarantees that the optimized form of the DEX file is regenerated.
*/
-#define DALVIK_VM_BUILD 22
+#define DALVIK_VM_BUILD 23
#endif /*_DALVIK_VERSION*/
diff --git a/vm/analysis/CodeVerify.c b/vm/analysis/CodeVerify.c
index 30670ec8c..4310a067f 100644
--- a/vm/analysis/CodeVerify.c
+++ b/vm/analysis/CodeVerify.c
@@ -4459,6 +4459,7 @@ aput_1nr_common:
break;
case OP_IGET:
+ case OP_IGET_VOLATILE:
tmpType = kRegTypeInteger;
goto iget_1nr_common;
case OP_IGET_BOOLEAN:
@@ -4548,6 +4549,7 @@ iget_1nr_common:
}
break;
case OP_IGET_OBJECT:
+ case OP_IGET_OBJECT_VOLATILE:
{
ClassObject* fieldClass;
InstField* instField;
@@ -4577,6 +4579,7 @@ iget_1nr_common:
}
break;
case OP_IPUT:
+ case OP_IPUT_VOLATILE:
tmpType = kRegTypeInteger;
goto iput_1nr_common;
case OP_IPUT_BOOLEAN:
@@ -4687,6 +4690,7 @@ iput_1nr_common:
}
break;
case OP_IPUT_OBJECT:
+ case OP_IPUT_OBJECT_VOLATILE:
{
ClassObject* fieldClass;
ClassObject* valueClass;
@@ -4748,6 +4752,7 @@ iput_1nr_common:
break;
case OP_SGET:
+ case OP_SGET_VOLATILE:
tmpType = kRegTypeInteger;
goto sget_1nr_common;
case OP_SGET_BOOLEAN:
@@ -4831,6 +4836,7 @@ sget_1nr_common:
}
break;
case OP_SGET_OBJECT:
+ case OP_SGET_OBJECT_VOLATILE:
{
StaticField* staticField;
ClassObject* fieldClass;
@@ -4855,6 +4861,7 @@ sget_1nr_common:
}
break;
case OP_SPUT:
+ case OP_SPUT_VOLATILE:
tmpType = kRegTypeInteger;
goto sput_1nr_common;
case OP_SPUT_BOOLEAN:
@@ -4958,6 +4965,7 @@ sput_1nr_common:
}
break;
case OP_SPUT_OBJECT:
+ case OP_SPUT_OBJECT_VOLATILE:
{
ClassObject* fieldClass;
ClassObject* valueClass;
@@ -5497,16 +5505,8 @@ sput_1nr_common:
case OP_UNUSED_73:
case OP_UNUSED_79:
case OP_UNUSED_7A:
- case OP_UNUSED_E3:
- case OP_UNUSED_E4:
- case OP_UNUSED_E5:
- case OP_UNUSED_E6:
- case OP_UNUSED_E7:
case OP_BREAKPOINT:
case OP_UNUSED_F1:
- case OP_UNUSED_FC:
- case OP_UNUSED_FD:
- case OP_UNUSED_FE:
case OP_UNUSED_FF:
failure = VERIFY_ERROR_GENERIC;
break;
diff --git a/vm/compiler/Dataflow.c b/vm/compiler/Dataflow.c
index fe04c6733..108420129 100644
--- a/vm/compiler/Dataflow.c
+++ b/vm/compiler/Dataflow.c
@@ -710,19 +710,19 @@ int dvmCompilerDataFlowAttributes[kMirOpLast] = {
// E2 OP_USHR_INT_LIT8 vAA, vBB, #+CC
DF_DA | DF_UB,
- // E3 OP_UNUSED_E3
+ // E3 OP_IGET_VOLATILE
DF_NOP,
- // E4 OP_UNUSED_E4
+ // E4 OP_IPUT_VOLATILE
DF_NOP,
- // E5 OP_UNUSED_E5
+ // E5 OP_SGET_VOLATILE
DF_NOP,
- // E6 OP_UNUSED_E6
+ // E6 OP_SPUT_VOLATILE
DF_NOP,
- // E7 OP_UNUSED_E7
+ // E7 OP_IGET_OBJECT_VOLATILE
DF_NOP,
// E8 OP_IGET_WIDE_VOLATILE
@@ -785,13 +785,13 @@ int dvmCompilerDataFlowAttributes[kMirOpLast] = {
// FB OP_INVOKE_SUPER_QUICK_RANGE
DF_FORMAT_3RC,
- // FC OP_UNUSED_FC
+ // FC OP_IPUT_OBJECT_VOLATILE
DF_NOP,
- // FD OP_UNUSED_FD
+ // FD OP_SGET_OBJECT_VOLATILE
DF_NOP,
- // FE OP_UNUSED_FE
+ // FE OP_SPUT_OBJECT_VOLATILE
DF_NOP,
// FF OP_UNUSED_FF
diff --git a/vm/compiler/codegen/arm/CodegenDriver.c b/vm/compiler/codegen/arm/CodegenDriver.c
index a28e4114d..7f601575c 100644
--- a/vm/compiler/codegen/arm/CodegenDriver.c
+++ b/vm/compiler/codegen/arm/CodegenDriver.c
@@ -1280,8 +1280,7 @@ static bool handleFmt10t_Fmt20t_Fmt30t(CompilationUnit *cUnit, MIR *mir,
static bool handleFmt10x(CompilationUnit *cUnit, MIR *mir)
{
OpCode dalvikOpCode = mir->dalvikInsn.opCode;
- if (((dalvikOpCode >= OP_UNUSED_3E) && (dalvikOpCode <= OP_UNUSED_43)) ||
- ((dalvikOpCode >= OP_UNUSED_E3) && (dalvikOpCode <= OP_UNUSED_E7))) {
+ if ((dalvikOpCode >= OP_UNUSED_3E) && (dalvikOpCode <= OP_UNUSED_43)) {
LOGE("Codegen: got unused opcode 0x%x\n",dalvikOpCode);
return true;
}
@@ -1292,6 +1291,8 @@ static bool handleFmt10x(CompilationUnit *cUnit, MIR *mir)
case OP_UNUSED_73:
case OP_UNUSED_79:
case OP_UNUSED_7A:
+ case OP_UNUSED_F1:
+ case OP_UNUSED_FF:
LOGE("Codegen: got unused opcode 0x%x\n",dalvikOpCode);
return true;
case OP_NOP:
diff --git a/vm/mterp/armv4t/platform.S b/vm/mterp/armv4t/platform.S
index bb2854a23..ff8d8f18d 100644
--- a/vm/mterp/armv4t/platform.S
+++ b/vm/mterp/armv4t/platform.S
@@ -36,3 +36,9 @@
ldmfd sp!, {\regs,lr}
bx lr
.endm
+
+/*
+ * Macro for data memory barrier; not meaningful pre-ARMv6K.
+ */
+.macro SMP_DMB gen
+.endm
diff --git a/vm/mterp/armv5te/OP_IGET.S b/vm/mterp/armv5te/OP_IGET.S
index f463d3f62..202148463 100644
--- a/vm/mterp/armv5te/OP_IGET.S
+++ b/vm/mterp/armv5te/OP_IGET.S
@@ -1,4 +1,4 @@
-%default { "load":"ldr", "sqnum":"0" }
+%default { "load":"ldr", "volatile":"0", "sqnum":"0" }
%verify "executed"
%verify "null object"
%verify "field already resolved"
@@ -38,6 +38,7 @@
ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field
beq common_errNullObject @ object was null
$load r0, [r9, r3] @ r0<- obj.field (8/16/32 bits)
+ SMP_DMB $volatile @ acquiring load
mov r2, rINST, lsr #8 @ r2<- A+
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
and r2, r2, #15 @ r2<- A
diff --git a/vm/mterp/armv5te/OP_IGET_OBJECT_VOLATILE.S b/vm/mterp/armv5te/OP_IGET_OBJECT_VOLATILE.S
new file mode 100644
index 000000000..2ff232177
--- /dev/null
+++ b/vm/mterp/armv5te/OP_IGET_OBJECT_VOLATILE.S
@@ -0,0 +1,2 @@
+%verify "executed"
+%include "armv5te/OP_IGET.S" {"volatile":"1"}
diff --git a/vm/mterp/armv5te/OP_IGET_VOLATILE.S b/vm/mterp/armv5te/OP_IGET_VOLATILE.S
new file mode 100644
index 000000000..2ff232177
--- /dev/null
+++ b/vm/mterp/armv5te/OP_IGET_VOLATILE.S
@@ -0,0 +1,2 @@
+%verify "executed"
+%include "armv5te/OP_IGET.S" {"volatile":"1"}
diff --git a/vm/mterp/armv5te/OP_IGET_WIDE.S b/vm/mterp/armv5te/OP_IGET_WIDE.S
index b1572baf5..95944de17 100644
--- a/vm/mterp/armv5te/OP_IGET_WIDE.S
+++ b/vm/mterp/armv5te/OP_IGET_WIDE.S
@@ -34,7 +34,7 @@
cmp r9, #0 @ check object for null
ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field
beq common_errNullObject @ object was null
- .if $volatile
+ .if $volatile
add r0, r9, r3 @ r0<- address of field
bl dvmQuasiAtomicRead64 @ r0/r1<- contents of field
.else
diff --git a/vm/mterp/armv5te/OP_IPUT.S b/vm/mterp/armv5te/OP_IPUT.S
index cbc5e316d..292ccd7f5 100644
--- a/vm/mterp/armv5te/OP_IPUT.S
+++ b/vm/mterp/armv5te/OP_IPUT.S
@@ -1,4 +1,4 @@
-%default { "store":"str", "sqnum":"0" }
+%default { "store":"str", "volatile":"0", "sqnum":"0" }
%verify "executed"
%verify "null object"
%verify "field already resolved"
@@ -42,5 +42,6 @@
beq common_errNullObject @ object was null
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB $volatile @ releasing store
$store r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0
GOTO_OPCODE(ip) @ jump to next instruction
diff --git a/vm/mterp/armv5te/OP_IPUT_OBJECT_VOLATILE.S b/vm/mterp/armv5te/OP_IPUT_OBJECT_VOLATILE.S
new file mode 100644
index 000000000..3b5eedd11
--- /dev/null
+++ b/vm/mterp/armv5te/OP_IPUT_OBJECT_VOLATILE.S
@@ -0,0 +1,2 @@
+%verify "executed"
+%include "armv5te/OP_IPUT.S" {"volatile":"1"}
diff --git a/vm/mterp/armv5te/OP_IPUT_VOLATILE.S b/vm/mterp/armv5te/OP_IPUT_VOLATILE.S
new file mode 100644
index 000000000..3b5eedd11
--- /dev/null
+++ b/vm/mterp/armv5te/OP_IPUT_VOLATILE.S
@@ -0,0 +1,2 @@
+%verify "executed"
+%include "armv5te/OP_IPUT.S" {"volatile":"1"}
diff --git a/vm/mterp/armv5te/OP_IPUT_WIDE.S b/vm/mterp/armv5te/OP_IPUT_WIDE.S
index 4a287215c..8796cbbcc 100644
--- a/vm/mterp/armv5te/OP_IPUT_WIDE.S
+++ b/vm/mterp/armv5te/OP_IPUT_WIDE.S
@@ -37,7 +37,7 @@
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
ldmia r2, {r0-r1} @ r0/r1<- fp[A]
GET_INST_OPCODE(r10) @ extract opcode from rINST
- .if $volatile
+ .if $volatile
add r2, r9, r3 @ r2<- target address
bl dvmQuasiAtomicSwap64 @ stores r0/r1 into addr r2
.else
diff --git a/vm/mterp/armv5te/OP_SGET.S b/vm/mterp/armv5te/OP_SGET.S
index b71383602..a9a8eedac 100644
--- a/vm/mterp/armv5te/OP_SGET.S
+++ b/vm/mterp/armv5te/OP_SGET.S
@@ -1,3 +1,4 @@
+%default { "volatile":"0" }
%verify "executed"
%verify "field already resolved"
%verify "field not yet resolved"
@@ -16,6 +17,7 @@
beq .L${opcode}_resolve @ yes, do resolve
.L${opcode}_finish: @ field ptr in r0
ldr r1, [r0, #offStaticField_value] @ r1<- field value
+ SMP_DMB $volatile @ acquiring load
mov r2, rINST, lsr #8 @ r2<- AA
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
SET_VREG(r1, r2) @ fp[AA]<- r1
diff --git a/vm/mterp/armv5te/OP_SGET_OBJECT_VOLATILE.S b/vm/mterp/armv5te/OP_SGET_OBJECT_VOLATILE.S
new file mode 100644
index 000000000..f319b8e3b
--- /dev/null
+++ b/vm/mterp/armv5te/OP_SGET_OBJECT_VOLATILE.S
@@ -0,0 +1,2 @@
+%verify "executed"
+%include "armv5te/OP_SGET.S" {"volatile":"1"}
diff --git a/vm/mterp/armv5te/OP_SGET_VOLATILE.S b/vm/mterp/armv5te/OP_SGET_VOLATILE.S
new file mode 100644
index 000000000..f319b8e3b
--- /dev/null
+++ b/vm/mterp/armv5te/OP_SGET_VOLATILE.S
@@ -0,0 +1,2 @@
+%verify "executed"
+%include "armv5te/OP_SGET.S" {"volatile":"1"}
diff --git a/vm/mterp/armv5te/OP_SPUT.S b/vm/mterp/armv5te/OP_SPUT.S
index 2dd542af8..52bfe5209 100644
--- a/vm/mterp/armv5te/OP_SPUT.S
+++ b/vm/mterp/armv5te/OP_SPUT.S
@@ -1,3 +1,4 @@
+%default { "volatile":"0" }
%verify "executed"
%verify "field already resolved"
%verify "field not yet resolved"
@@ -19,6 +20,7 @@
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
GET_VREG(r1, r2) @ r1<- fp[AA]
GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB $volatile @ releasing store
str r1, [r0, #offStaticField_value] @ field<- vAA
GOTO_OPCODE(ip) @ jump to next instruction
%break
diff --git a/vm/mterp/armv5te/OP_SPUT_OBJECT_VOLATILE.S b/vm/mterp/armv5te/OP_SPUT_OBJECT_VOLATILE.S
new file mode 100644
index 000000000..196d8b8e9
--- /dev/null
+++ b/vm/mterp/armv5te/OP_SPUT_OBJECT_VOLATILE.S
@@ -0,0 +1,2 @@
+%verify "executed"
+%include "armv5te/OP_SPUT.S" {"volatile":"1"}
diff --git a/vm/mterp/armv5te/OP_SPUT_VOLATILE.S b/vm/mterp/armv5te/OP_SPUT_VOLATILE.S
new file mode 100644
index 000000000..196d8b8e9
--- /dev/null
+++ b/vm/mterp/armv5te/OP_SPUT_VOLATILE.S
@@ -0,0 +1,2 @@
+%verify "executed"
+%include "armv5te/OP_SPUT.S" {"volatile":"1"}
diff --git a/vm/mterp/armv5te/OP_UNUSED_E3.S b/vm/mterp/armv5te/OP_UNUSED_E3.S
deleted file mode 100644
index faa7246f5..000000000
--- a/vm/mterp/armv5te/OP_UNUSED_E3.S
+++ /dev/null
@@ -1 +0,0 @@
-%include "armv5te/unused.S"
diff --git a/vm/mterp/armv5te/OP_UNUSED_E4.S b/vm/mterp/armv5te/OP_UNUSED_E4.S
deleted file mode 100644
index faa7246f5..000000000
--- a/vm/mterp/armv5te/OP_UNUSED_E4.S
+++ /dev/null
@@ -1 +0,0 @@
-%include "armv5te/unused.S"
diff --git a/vm/mterp/armv5te/OP_UNUSED_E5.S b/vm/mterp/armv5te/OP_UNUSED_E5.S
deleted file mode 100644
index faa7246f5..000000000
--- a/vm/mterp/armv5te/OP_UNUSED_E5.S
+++ /dev/null
@@ -1 +0,0 @@
-%include "armv5te/unused.S"
diff --git a/vm/mterp/armv5te/OP_UNUSED_E6.S b/vm/mterp/armv5te/OP_UNUSED_E6.S
deleted file mode 100644
index faa7246f5..000000000
--- a/vm/mterp/armv5te/OP_UNUSED_E6.S
+++ /dev/null
@@ -1 +0,0 @@
-%include "armv5te/unused.S"
diff --git a/vm/mterp/armv5te/OP_UNUSED_E7.S b/vm/mterp/armv5te/OP_UNUSED_E7.S
deleted file mode 100644
index faa7246f5..000000000
--- a/vm/mterp/armv5te/OP_UNUSED_E7.S
+++ /dev/null
@@ -1 +0,0 @@
-%include "armv5te/unused.S"
diff --git a/vm/mterp/armv5te/OP_UNUSED_FC.S b/vm/mterp/armv5te/OP_UNUSED_FC.S
deleted file mode 100644
index faa7246f5..000000000
--- a/vm/mterp/armv5te/OP_UNUSED_FC.S
+++ /dev/null
@@ -1 +0,0 @@
-%include "armv5te/unused.S"
diff --git a/vm/mterp/armv5te/OP_UNUSED_FD.S b/vm/mterp/armv5te/OP_UNUSED_FD.S
deleted file mode 100644
index faa7246f5..000000000
--- a/vm/mterp/armv5te/OP_UNUSED_FD.S
+++ /dev/null
@@ -1 +0,0 @@
-%include "armv5te/unused.S"
diff --git a/vm/mterp/armv5te/OP_UNUSED_FE.S b/vm/mterp/armv5te/OP_UNUSED_FE.S
deleted file mode 100644
index faa7246f5..000000000
--- a/vm/mterp/armv5te/OP_UNUSED_FE.S
+++ /dev/null
@@ -1 +0,0 @@
-%include "armv5te/unused.S"
diff --git a/vm/mterp/armv5te/header.S b/vm/mterp/armv5te/header.S
index b6e98914a..bd6b7eec8 100644
--- a/vm/mterp/armv5te/header.S
+++ b/vm/mterp/armv5te/header.S
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
/*
* ARMv5 definitions and declarations.
*/
diff --git a/vm/mterp/armv5te/platform.S b/vm/mterp/armv5te/platform.S
index fd8533838..cd4519898 100644
--- a/vm/mterp/armv5te/platform.S
+++ b/vm/mterp/armv5te/platform.S
@@ -33,3 +33,9 @@
.macro LDMFD_PC regs
ldmfd sp!, {\regs,pc}
.endm
+
+/*
+ * Macro for data memory barrier; not meaningful pre-ARMv6K.
+ */
+.macro SMP_DMB gen
+.endm
diff --git a/vm/mterp/armv7-a/platform.S b/vm/mterp/armv7-a/platform.S
new file mode 100644
index 000000000..42713b857
--- /dev/null
+++ b/vm/mterp/armv7-a/platform.S
@@ -0,0 +1,53 @@
+/*
+ * ===========================================================================
+ * CPU-version-specific defines
+ * ===========================================================================
+ */
+
+/*
+ * Macro for "LDR PC,xxx", which is not allowed pre-ARMv5. Essentially a
+ * one-way branch.
+ *
+ * May modify IP. Does not modify LR.
+ */
+.macro LDR_PC source
+ ldr pc, \source
+.endm
+
+/*
+ * Macro for "MOV LR,PC / LDR PC,xxx", which is not allowed pre-ARMv5.
+ * Jump to subroutine.
+ *
+ * May modify IP and LR.
+ */
+.macro LDR_PC_LR source
+ mov lr, pc
+ ldr pc, \source
+.endm
+
+/*
+ * Macro for "LDMFD SP!, {...regs...,PC}".
+ *
+ * May modify IP and LR.
+ */
+.macro LDMFD_PC regs
+ ldmfd sp!, {\regs,pc}
+.endm
+
+#if !defined(ANDROID_SMP)
+# error "Must define ANDROID_SMP"
+#endif
+
+/*
+ * Macro for data memory barrier; not meaningful pre-ARMv6K.
+ * If the argument is nonzero, emit barrier; otherwise, emit nothing.
+ */
+.macro SMP_DMB gen
+#if ANDROID_SMP != 0
+ .if \gen
+ dmb
+ .endif
+#else
+ /* not SMP */
+#endif
+.endm
diff --git a/vm/mterp/c/OP_IGET_OBJECT_VOLATILE.c b/vm/mterp/c/OP_IGET_OBJECT_VOLATILE.c
new file mode 100644
index 000000000..35775521f
--- /dev/null
+++ b/vm/mterp/c/OP_IGET_OBJECT_VOLATILE.c
@@ -0,0 +1,2 @@
+HANDLE_IGET_X(OP_IGET_OBJECT_VOLATILE, "-object-volatile", ObjectVolatile, _AS_OBJECT)
+OP_END
diff --git a/vm/mterp/c/OP_IGET_VOLATILE.c b/vm/mterp/c/OP_IGET_VOLATILE.c
new file mode 100644
index 000000000..7a3be56c8
--- /dev/null
+++ b/vm/mterp/c/OP_IGET_VOLATILE.c
@@ -0,0 +1,2 @@
+HANDLE_IGET_X(OP_IGET_VOLATILE, "-volatile", IntVolatile, )
+OP_END
diff --git a/vm/mterp/c/OP_IPUT_OBJECT_VOLATILE.c b/vm/mterp/c/OP_IPUT_OBJECT_VOLATILE.c
new file mode 100644
index 000000000..cce63c130
--- /dev/null
+++ b/vm/mterp/c/OP_IPUT_OBJECT_VOLATILE.c
@@ -0,0 +1,2 @@
+HANDLE_IPUT_X(OP_IPUT_OBJECT_VOLATILE, "-object-volatile", ObjectVolatile, _AS_OBJECT)
+OP_END
diff --git a/vm/mterp/c/OP_IPUT_VOLATILE.c b/vm/mterp/c/OP_IPUT_VOLATILE.c
new file mode 100644
index 000000000..814379e45
--- /dev/null
+++ b/vm/mterp/c/OP_IPUT_VOLATILE.c
@@ -0,0 +1,2 @@
+HANDLE_IPUT_X(OP_IPUT_VOLATILE, "-volatile", IntVolatile, )
+OP_END
diff --git a/vm/mterp/c/OP_SGET_OBJECT_VOLATILE.c b/vm/mterp/c/OP_SGET_OBJECT_VOLATILE.c
new file mode 100644
index 000000000..0a9049f64
--- /dev/null
+++ b/vm/mterp/c/OP_SGET_OBJECT_VOLATILE.c
@@ -0,0 +1,2 @@
+HANDLE_SGET_X(OP_SGET_OBJECT_VOLATILE, "-object-volatile", ObjectVolatile, _AS_OBJECT)
+OP_END
diff --git a/vm/mterp/c/OP_SGET_VOLATILE.c b/vm/mterp/c/OP_SGET_VOLATILE.c
new file mode 100644
index 000000000..6713a54bb
--- /dev/null
+++ b/vm/mterp/c/OP_SGET_VOLATILE.c
@@ -0,0 +1,2 @@
+HANDLE_SGET_X(OP_SGET_VOLATILE, "-volatile", IntVolatile, )
+OP_END
diff --git a/vm/mterp/c/OP_SPUT_OBJECT_VOLATILE.c b/vm/mterp/c/OP_SPUT_OBJECT_VOLATILE.c
new file mode 100644
index 000000000..38d6c0d2a
--- /dev/null
+++ b/vm/mterp/c/OP_SPUT_OBJECT_VOLATILE.c
@@ -0,0 +1,2 @@
+HANDLE_SPUT_X(OP_SPUT_OBJECT_VOLATILE, "-object-volatile", ObjectVolatile, _AS_OBJECT)
+OP_END
diff --git a/vm/mterp/c/OP_SPUT_VOLATILE.c b/vm/mterp/c/OP_SPUT_VOLATILE.c
new file mode 100644
index 000000000..7899d0546
--- /dev/null
+++ b/vm/mterp/c/OP_SPUT_VOLATILE.c
@@ -0,0 +1,2 @@
+HANDLE_SPUT_X(OP_SPUT_VOLATILE, "-volatile", IntVolatile, )
+OP_END
diff --git a/vm/mterp/c/OP_UNUSED_E3.c b/vm/mterp/c/OP_UNUSED_E3.c
deleted file mode 100644
index d52836b9e..000000000
--- a/vm/mterp/c/OP_UNUSED_E3.c
+++ /dev/null
@@ -1,2 +0,0 @@
-HANDLE_OPCODE(OP_UNUSED_E3)
-OP_END
diff --git a/vm/mterp/c/OP_UNUSED_E4.c b/vm/mterp/c/OP_UNUSED_E4.c
deleted file mode 100644
index 30a714fc3..000000000
--- a/vm/mterp/c/OP_UNUSED_E4.c
+++ /dev/null
@@ -1,2 +0,0 @@
-HANDLE_OPCODE(OP_UNUSED_E4)
-OP_END
diff --git a/vm/mterp/c/OP_UNUSED_E5.c b/vm/mterp/c/OP_UNUSED_E5.c
deleted file mode 100644
index 0cc6ff9a2..000000000
--- a/vm/mterp/c/OP_UNUSED_E5.c
+++ /dev/null
@@ -1,2 +0,0 @@
-HANDLE_OPCODE(OP_UNUSED_E5)
-OP_END
diff --git a/vm/mterp/c/OP_UNUSED_E6.c b/vm/mterp/c/OP_UNUSED_E6.c
deleted file mode 100644
index 255dcd14b..000000000
--- a/vm/mterp/c/OP_UNUSED_E6.c
+++ /dev/null
@@ -1,2 +0,0 @@
-HANDLE_OPCODE(OP_UNUSED_E6)
-OP_END
diff --git a/vm/mterp/c/OP_UNUSED_E7.c b/vm/mterp/c/OP_UNUSED_E7.c
deleted file mode 100644
index b910f714f..000000000
--- a/vm/mterp/c/OP_UNUSED_E7.c
+++ /dev/null
@@ -1,2 +0,0 @@
-HANDLE_OPCODE(OP_UNUSED_E7)
-OP_END
diff --git a/vm/mterp/c/OP_UNUSED_FC.c b/vm/mterp/c/OP_UNUSED_FC.c
deleted file mode 100644
index 4b49684a6..000000000
--- a/vm/mterp/c/OP_UNUSED_FC.c
+++ /dev/null
@@ -1,2 +0,0 @@
-HANDLE_OPCODE(OP_UNUSED_FC)
-OP_END
diff --git a/vm/mterp/c/OP_UNUSED_FD.c b/vm/mterp/c/OP_UNUSED_FD.c
deleted file mode 100644
index c10efaf0b..000000000
--- a/vm/mterp/c/OP_UNUSED_FD.c
+++ /dev/null
@@ -1,2 +0,0 @@
-HANDLE_OPCODE(OP_UNUSED_FD)
-OP_END
diff --git a/vm/mterp/c/OP_UNUSED_FE.c b/vm/mterp/c/OP_UNUSED_FE.c
deleted file mode 100644
index 7b097d905..000000000
--- a/vm/mterp/c/OP_UNUSED_FE.c
+++ /dev/null
@@ -1,2 +0,0 @@
-HANDLE_OPCODE(OP_UNUSED_FE)
-OP_END
diff --git a/vm/mterp/config-armv7-a b/vm/mterp/config-armv7-a
index be32042ef..e66640c65 100644
--- a/vm/mterp/config-armv7-a
+++ b/vm/mterp/config-armv7-a
@@ -34,7 +34,7 @@ import armv5te/header.S
import cstubs/stubdefs.c
# highly-platform-specific defs
-import armv5te/platform.S
+import armv7-a/platform.S
# common defs for the C helpers; include this before the instruction handlers
import c/opcommon.c
diff --git a/vm/mterp/config-armv7-a-neon b/vm/mterp/config-armv7-a-neon
index be32042ef..e66640c65 100644
--- a/vm/mterp/config-armv7-a-neon
+++ b/vm/mterp/config-armv7-a-neon
@@ -34,7 +34,7 @@ import armv5te/header.S
import cstubs/stubdefs.c
# highly-platform-specific defs
-import armv5te/platform.S
+import armv7-a/platform.S
# common defs for the C helpers; include this before the instruction handlers
import c/opcommon.c
diff --git a/vm/mterp/config-x86 b/vm/mterp/config-x86
index 627e06cd6..78ae1a0e3 100644
--- a/vm/mterp/config-x86
+++ b/vm/mterp/config-x86
@@ -35,6 +35,14 @@ import c/opcommon.c
op-start x86
# stub -- need native impl
op OP_EXECUTE_INLINE_RANGE c
+ op OP_IGET_VOLATILE c
+ op OP_IPUT_VOLATILE c
+ op OP_SGET_VOLATILE c
+ op OP_SPUT_VOLATILE c
+ op OP_IGET_OBJECT_VOLATILE c
+ op OP_IPUT_OBJECT_VOLATILE c
+ op OP_SGET_OBJECT_VOLATILE c
+ op OP_SPUT_OBJECT_VOLATILE c
op OP_IGET_WIDE_VOLATILE c
op OP_IPUT_WIDE_VOLATILE c
op OP_SGET_WIDE_VOLATILE c
diff --git a/vm/mterp/config-x86-atom b/vm/mterp/config-x86-atom
index 0d9b193de..970253c09 100644
--- a/vm/mterp/config-x86-atom
+++ b/vm/mterp/config-x86-atom
@@ -286,6 +286,14 @@ op-start x86-atom
# TODO: provide native implementations
op OP_BREAKPOINT c
op OP_EXECUTE_INLINE_RANGE c
+op OP_IGET_VOLATILE c
+op OP_IPUT_VOLATILE c
+op OP_SGET_VOLATILE c
+op OP_SPUT_VOLATILE c
+op OP_IGET_OBJECT_VOLATILE c
+op OP_IPUT_OBJECT_VOLATILE c
+op OP_SGET_OBJECT_VOLATILE c
+op OP_SPUT_OBJECT_VOLATILE c
op OP_IGET_WIDE_VOLATILE c
op OP_IPUT_WIDE_VOLATILE c
op OP_SGET_WIDE_VOLATILE c
diff --git a/vm/mterp/out/InterpAsm-armv4t.S b/vm/mterp/out/InterpAsm-armv4t.S
index 17fb783e6..ec129a341 100644
--- a/vm/mterp/out/InterpAsm-armv4t.S
+++ b/vm/mterp/out/InterpAsm-armv4t.S
@@ -20,6 +20,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
/*
* ARMv5 definitions and declarations.
*/
@@ -242,6 +243,13 @@ unspecified registers or condition codes.
ldmfd sp!, {\regs,pc}
.endm
+/*
+ * Macro for data memory barrier; not meaningful pre-ARMv6K.
+ */
+.macro SMP_DMB gen
+.endm
+
+
/* File: armv5te/entry.S */
/*
* Copyright (C) 2008 The Android Open Source Project
@@ -2807,6 +2815,7 @@ dalvik_inst:
beq .LOP_SGET_resolve @ yes, do resolve
.LOP_SGET_finish: @ field ptr in r0
ldr r1, [r0, #offStaticField_value] @ r1<- field value
+ SMP_DMB 0 @ acquiring load
mov r2, rINST, lsr #8 @ r2<- AA
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
SET_VREG(r1, r2) @ fp[AA]<- r1
@@ -2860,6 +2869,7 @@ dalvik_inst:
beq .LOP_SGET_OBJECT_resolve @ yes, do resolve
.LOP_SGET_OBJECT_finish: @ field ptr in r0
ldr r1, [r0, #offStaticField_value] @ r1<- field value
+ SMP_DMB 0 @ acquiring load
mov r2, rINST, lsr #8 @ r2<- AA
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
SET_VREG(r1, r2) @ fp[AA]<- r1
@@ -2886,6 +2896,7 @@ dalvik_inst:
beq .LOP_SGET_BOOLEAN_resolve @ yes, do resolve
.LOP_SGET_BOOLEAN_finish: @ field ptr in r0
ldr r1, [r0, #offStaticField_value] @ r1<- field value
+ SMP_DMB 0 @ acquiring load
mov r2, rINST, lsr #8 @ r2<- AA
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
SET_VREG(r1, r2) @ fp[AA]<- r1
@@ -2912,6 +2923,7 @@ dalvik_inst:
beq .LOP_SGET_BYTE_resolve @ yes, do resolve
.LOP_SGET_BYTE_finish: @ field ptr in r0
ldr r1, [r0, #offStaticField_value] @ r1<- field value
+ SMP_DMB 0 @ acquiring load
mov r2, rINST, lsr #8 @ r2<- AA
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
SET_VREG(r1, r2) @ fp[AA]<- r1
@@ -2938,6 +2950,7 @@ dalvik_inst:
beq .LOP_SGET_CHAR_resolve @ yes, do resolve
.LOP_SGET_CHAR_finish: @ field ptr in r0
ldr r1, [r0, #offStaticField_value] @ r1<- field value
+ SMP_DMB 0 @ acquiring load
mov r2, rINST, lsr #8 @ r2<- AA
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
SET_VREG(r1, r2) @ fp[AA]<- r1
@@ -2964,6 +2977,7 @@ dalvik_inst:
beq .LOP_SGET_SHORT_resolve @ yes, do resolve
.LOP_SGET_SHORT_finish: @ field ptr in r0
ldr r1, [r0, #offStaticField_value] @ r1<- field value
+ SMP_DMB 0 @ acquiring load
mov r2, rINST, lsr #8 @ r2<- AA
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
SET_VREG(r1, r2) @ fp[AA]<- r1
@@ -2992,6 +3006,7 @@ dalvik_inst:
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
GET_VREG(r1, r2) @ r1<- fp[AA]
GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB 0 @ releasing store
str r1, [r0, #offStaticField_value] @ field<- vAA
GOTO_OPCODE(ip) @ jump to next instruction
@@ -3045,6 +3060,7 @@ dalvik_inst:
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
GET_VREG(r1, r2) @ r1<- fp[AA]
GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB 0 @ releasing store
str r1, [r0, #offStaticField_value] @ field<- vAA
GOTO_OPCODE(ip) @ jump to next instruction
@@ -3071,6 +3087,7 @@ dalvik_inst:
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
GET_VREG(r1, r2) @ r1<- fp[AA]
GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB 0 @ releasing store
str r1, [r0, #offStaticField_value] @ field<- vAA
GOTO_OPCODE(ip) @ jump to next instruction
@@ -3097,6 +3114,7 @@ dalvik_inst:
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
GET_VREG(r1, r2) @ r1<- fp[AA]
GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB 0 @ releasing store
str r1, [r0, #offStaticField_value] @ field<- vAA
GOTO_OPCODE(ip) @ jump to next instruction
@@ -3123,6 +3141,7 @@ dalvik_inst:
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
GET_VREG(r1, r2) @ r1<- fp[AA]
GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB 0 @ releasing store
str r1, [r0, #offStaticField_value] @ field<- vAA
GOTO_OPCODE(ip) @ jump to next instruction
@@ -3149,6 +3168,7 @@ dalvik_inst:
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
GET_VREG(r1, r2) @ r1<- fp[AA]
GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB 0 @ releasing store
str r1, [r0, #offStaticField_value] @ field<- vAA
GOTO_OPCODE(ip) @ jump to next instruction
@@ -7402,42 +7422,140 @@ d2i_doconv:
/* ------------------------------ */
.balign 64
-.L_OP_UNUSED_E3: /* 0xe3 */
-/* File: armv5te/OP_UNUSED_E3.S */
-/* File: armv5te/unused.S */
- bl common_abort
+.L_OP_IGET_VOLATILE: /* 0xe3 */
+/* File: armv5te/OP_IGET_VOLATILE.S */
+/* File: armv5te/OP_IGET.S */
+ /*
+ * General 32-bit instance field get.
+ *
+ * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
+ */
+ /* op vA, vB, field@CCCC */
+ mov r0, rINST, lsr #12 @ r0<- B
+ ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex
+ FETCH(r1, 1) @ r1<- field ref CCCC
+ ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
+ GET_VREG(r9, r0) @ r9<- fp[B], the object pointer
+ ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr
+ cmp r0, #0 @ is resolved entry null?
+ bne .LOP_IGET_VOLATILE_finish @ no, already resolved
+8: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method
+ EXPORT_PC() @ resolve() could throw
+ ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz
+ bl dvmResolveInstField @ r0<- resolved InstField ptr
+ cmp r0, #0
+ bne .LOP_IGET_VOLATILE_finish
+ b common_exceptionThrown
/* ------------------------------ */
.balign 64
-.L_OP_UNUSED_E4: /* 0xe4 */
-/* File: armv5te/OP_UNUSED_E4.S */
-/* File: armv5te/unused.S */
- bl common_abort
+.L_OP_IPUT_VOLATILE: /* 0xe4 */
+/* File: armv5te/OP_IPUT_VOLATILE.S */
+/* File: armv5te/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 */
+ mov r0, rINST, lsr #12 @ r0<- B
+ ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex
+ FETCH(r1, 1) @ r1<- field ref CCCC
+ ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
+ GET_VREG(r9, r0) @ r9<- fp[B], the object pointer
+ ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr
+ cmp r0, #0 @ is resolved entry null?
+ bne .LOP_IPUT_VOLATILE_finish @ no, already resolved
+8: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method
+ EXPORT_PC() @ resolve() could throw
+ ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz
+ bl dvmResolveInstField @ r0<- resolved InstField ptr
+ cmp r0, #0 @ success?
+ bne .LOP_IPUT_VOLATILE_finish @ yes, finish up
+ b common_exceptionThrown
/* ------------------------------ */
.balign 64
-.L_OP_UNUSED_E5: /* 0xe5 */
-/* File: armv5te/OP_UNUSED_E5.S */
-/* File: armv5te/unused.S */
- bl common_abort
+.L_OP_SGET_VOLATILE: /* 0xe5 */
+/* File: armv5te/OP_SGET_VOLATILE.S */
+/* File: armv5te/OP_SGET.S */
+ /*
+ * General 32-bit SGET handler.
+ *
+ * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
+ */
+ /* op vAA, field@BBBB */
+ ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex
+ FETCH(r1, 1) @ r1<- field ref BBBB
+ ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
+ ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr
+ cmp r0, #0 @ is resolved entry null?
+ beq .LOP_SGET_VOLATILE_resolve @ yes, do resolve
+.LOP_SGET_VOLATILE_finish: @ field ptr in r0
+ ldr r1, [r0, #offStaticField_value] @ r1<- field value
+ SMP_DMB 1 @ acquiring load
+ mov r2, rINST, lsr #8 @ r2<- AA
+ FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
+ SET_VREG(r1, r2) @ fp[AA]<- r1
+ GET_INST_OPCODE(ip) @ extract opcode from rINST
+ GOTO_OPCODE(ip) @ jump to next instruction
/* ------------------------------ */
.balign 64
-.L_OP_UNUSED_E6: /* 0xe6 */
-/* File: armv5te/OP_UNUSED_E6.S */
-/* File: armv5te/unused.S */
- bl common_abort
+.L_OP_SPUT_VOLATILE: /* 0xe6 */
+/* File: armv5te/OP_SPUT_VOLATILE.S */
+/* File: armv5te/OP_SPUT.S */
+ /*
+ * General 32-bit SPUT handler.
+ *
+ * for: sput, sput-object, sput-boolean, sput-byte, sput-char, sput-short
+ */
+ /* op vAA, field@BBBB */
+ ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex
+ FETCH(r1, 1) @ r1<- field ref BBBB
+ ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
+ ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr
+ cmp r0, #0 @ is resolved entry null?
+ beq .LOP_SPUT_VOLATILE_resolve @ yes, do resolve
+.LOP_SPUT_VOLATILE_finish: @ field ptr in r0
+ mov r2, rINST, lsr #8 @ r2<- AA
+ FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
+ GET_VREG(r1, r2) @ r1<- fp[AA]
+ GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB 1 @ releasing store
+ str r1, [r0, #offStaticField_value] @ field<- vAA
+ GOTO_OPCODE(ip) @ jump to next instruction
/* ------------------------------ */
.balign 64
-.L_OP_UNUSED_E7: /* 0xe7 */
-/* File: armv5te/OP_UNUSED_E7.S */
-/* File: armv5te/unused.S */
- bl common_abort
+.L_OP_IGET_OBJECT_VOLATILE: /* 0xe7 */
+/* File: armv5te/OP_IGET_OBJECT_VOLATILE.S */
+/* File: armv5te/OP_IGET.S */
+ /*
+ * General 32-bit instance field get.
+ *
+ * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
+ */
+ /* op vA, vB, field@CCCC */
+ mov r0, rINST, lsr #12 @ r0<- B
+ ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex
+ FETCH(r1, 1) @ r1<- field ref CCCC
+ ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
+ GET_VREG(r9, r0) @ r9<- fp[B], the object pointer
+ ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr
+ cmp r0, #0 @ is resolved entry null?
+ bne .LOP_IGET_OBJECT_VOLATILE_finish @ no, already resolved
+8: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method
+ EXPORT_PC() @ resolve() could throw
+ ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz
+ bl dvmResolveInstField @ r0<- resolved InstField ptr
+ cmp r0, #0
+ bne .LOP_IGET_OBJECT_VOLATILE_finish
+ b common_exceptionThrown
/* ------------------------------ */
@@ -7882,26 +8000,84 @@ d2i_doconv:
/* ------------------------------ */
.balign 64
-.L_OP_UNUSED_FC: /* 0xfc */
-/* File: armv5te/OP_UNUSED_FC.S */
-/* File: armv5te/unused.S */
- bl common_abort
+.L_OP_IPUT_OBJECT_VOLATILE: /* 0xfc */
+/* File: armv5te/OP_IPUT_OBJECT_VOLATILE.S */
+/* File: armv5te/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 */
+ mov r0, rINST, lsr #12 @ r0<- B
+ ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex
+ FETCH(r1, 1) @ r1<- field ref CCCC
+ ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
+ GET_VREG(r9, r0) @ r9<- fp[B], the object pointer
+ ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr
+ cmp r0, #0 @ is resolved entry null?
+ bne .LOP_IPUT_OBJECT_VOLATILE_finish @ no, already resolved
+8: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method
+ EXPORT_PC() @ resolve() could throw
+ ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz
+ bl dvmResolveInstField @ r0<- resolved InstField ptr
+ cmp r0, #0 @ success?
+ bne .LOP_IPUT_OBJECT_VOLATILE_finish @ yes, finish up
+ b common_exceptionThrown
/* ------------------------------ */
.balign 64
-.L_OP_UNUSED_FD: /* 0xfd */
-/* File: armv5te/OP_UNUSED_FD.S */
-/* File: armv5te/unused.S */
- bl common_abort
+.L_OP_SGET_OBJECT_VOLATILE: /* 0xfd */
+/* File: armv5te/OP_SGET_OBJECT_VOLATILE.S */
+/* File: armv5te/OP_SGET.S */
+ /*
+ * General 32-bit SGET handler.
+ *
+ * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
+ */
+ /* op vAA, field@BBBB */
+ ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex
+ FETCH(r1, 1) @ r1<- field ref BBBB
+ ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
+ ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr
+ cmp r0, #0 @ is resolved entry null?
+ beq .LOP_SGET_OBJECT_VOLATILE_resolve @ yes, do resolve
+.LOP_SGET_OBJECT_VOLATILE_finish: @ field ptr in r0
+ ldr r1, [r0, #offStaticField_value] @ r1<- field value
+ SMP_DMB 1 @ acquiring load
+ mov r2, rINST, lsr #8 @ r2<- AA
+ FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
+ SET_VREG(r1, r2) @ fp[AA]<- r1
+ GET_INST_OPCODE(ip) @ extract opcode from rINST
+ GOTO_OPCODE(ip) @ jump to next instruction
/* ------------------------------ */
.balign 64
-.L_OP_UNUSED_FE: /* 0xfe */
-/* File: armv5te/OP_UNUSED_FE.S */
-/* File: armv5te/unused.S */
- bl common_abort
+.L_OP_SPUT_OBJECT_VOLATILE: /* 0xfe */
+/* File: armv5te/OP_SPUT_OBJECT_VOLATILE.S */
+/* File: armv5te/OP_SPUT.S */
+ /*
+ * General 32-bit SPUT handler.
+ *
+ * for: sput, sput-object, sput-boolean, sput-byte, sput-char, sput-short
+ */
+ /* op vAA, field@BBBB */
+ ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex
+ FETCH(r1, 1) @ r1<- field ref BBBB
+ ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
+ ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr
+ cmp r0, #0 @ is resolved entry null?
+ beq .LOP_SPUT_OBJECT_VOLATILE_resolve @ yes, do resolve
+.LOP_SPUT_OBJECT_VOLATILE_finish: @ field ptr in r0
+ mov r2, rINST, lsr #8 @ r2<- AA
+ FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
+ GET_VREG(r1, r2) @ r1<- fp[AA]
+ GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB 1 @ releasing store
+ str r1, [r0, #offStaticField_value] @ field<- vAA
+ GOTO_OPCODE(ip) @ jump to next instruction
/* ------------------------------ */
@@ -8555,6 +8731,7 @@ OP_CMPG_FLOAT_nan:
ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field
beq common_errNullObject @ object was null
ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits)
+ SMP_DMB 0 @ acquiring load
mov r2, rINST, lsr #8 @ r2<- A+
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
and r2, r2, #15 @ r2<- A
@@ -8601,6 +8778,7 @@ OP_CMPG_FLOAT_nan:
ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field
beq common_errNullObject @ object was null
ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits)
+ SMP_DMB 0 @ acquiring load
mov r2, rINST, lsr #8 @ r2<- A+
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
and r2, r2, #15 @ r2<- A
@@ -8621,6 +8799,7 @@ OP_CMPG_FLOAT_nan:
ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field
beq common_errNullObject @ object was null
ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits)
+ SMP_DMB 0 @ acquiring load
mov r2, rINST, lsr #8 @ r2<- A+
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
and r2, r2, #15 @ r2<- A
@@ -8641,6 +8820,7 @@ OP_CMPG_FLOAT_nan:
ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field
beq common_errNullObject @ object was null
ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits)
+ SMP_DMB 0 @ acquiring load
mov r2, rINST, lsr #8 @ r2<- A+
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
and r2, r2, #15 @ r2<- A
@@ -8661,6 +8841,7 @@ OP_CMPG_FLOAT_nan:
ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field
beq common_errNullObject @ object was null
ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits)
+ SMP_DMB 0 @ acquiring load
mov r2, rINST, lsr #8 @ r2<- A+
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
and r2, r2, #15 @ r2<- A
@@ -8681,6 +8862,7 @@ OP_CMPG_FLOAT_nan:
ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field
beq common_errNullObject @ object was null
ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits)
+ SMP_DMB 0 @ acquiring load
mov r2, rINST, lsr #8 @ r2<- A+
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
and r2, r2, #15 @ r2<- A
@@ -8705,6 +8887,7 @@ OP_CMPG_FLOAT_nan:
beq common_errNullObject @ object was null
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB 0 @ releasing store
str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0
GOTO_OPCODE(ip) @ jump to next instruction
@@ -8750,6 +8933,7 @@ OP_CMPG_FLOAT_nan:
beq common_errNullObject @ object was null
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB 0 @ releasing store
str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0
GOTO_OPCODE(ip) @ jump to next instruction
@@ -8770,6 +8954,7 @@ OP_CMPG_FLOAT_nan:
beq common_errNullObject @ object was null
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB 0 @ releasing store
str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0
GOTO_OPCODE(ip) @ jump to next instruction
@@ -8790,6 +8975,7 @@ OP_CMPG_FLOAT_nan:
beq common_errNullObject @ object was null
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB 0 @ releasing store
str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0
GOTO_OPCODE(ip) @ jump to next instruction
@@ -8810,6 +8996,7 @@ OP_CMPG_FLOAT_nan:
beq common_errNullObject @ object was null
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB 0 @ releasing store
str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0
GOTO_OPCODE(ip) @ jump to next instruction
@@ -8830,6 +9017,7 @@ OP_CMPG_FLOAT_nan:
beq common_errNullObject @ object was null
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB 0 @ releasing store
str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0
GOTO_OPCODE(ip) @ jump to next instruction
@@ -9324,6 +9512,99 @@ d2l_doconv:
stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1
GOTO_OPCODE(ip) @ jump to next instruction
+/* continuation for OP_IGET_VOLATILE */
+
+ /*
+ * Currently:
+ * r0 holds resolved field
+ * r9 holds object
+ */
+.LOP_IGET_VOLATILE_finish:
+ @bl common_squeak0
+ cmp r9, #0 @ check object for null
+ ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field
+ beq common_errNullObject @ object was null
+ ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits)
+ SMP_DMB 1 @ acquiring load
+ mov r2, rINST, lsr #8 @ r2<- A+
+ FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
+ and r2, r2, #15 @ r2<- A
+ GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SET_VREG(r0, r2) @ fp[A]<- r0
+ GOTO_OPCODE(ip) @ jump to next instruction
+
+/* continuation for OP_IPUT_VOLATILE */
+
+ /*
+ * Currently:
+ * r0 holds resolved field
+ * r9 holds object
+ */
+.LOP_IPUT_VOLATILE_finish:
+ @bl common_squeak0
+ mov r1, rINST, lsr #8 @ r1<- A+
+ ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field
+ and r1, r1, #15 @ r1<- A
+ cmp r9, #0 @ check object for null
+ GET_VREG(r0, r1) @ r0<- fp[A]
+ beq common_errNullObject @ object was null
+ FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
+ GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB 1 @ releasing store
+ str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0
+ GOTO_OPCODE(ip) @ jump to next instruction
+
+/* continuation for OP_SGET_VOLATILE */
+
+ /*
+ * Continuation if the field has not yet been resolved.
+ * r1: BBBB field ref
+ */
+.LOP_SGET_VOLATILE_resolve:
+ ldr r2, [rGLUE, #offGlue_method] @ r2<- current method
+ EXPORT_PC() @ resolve() could throw, so export now
+ ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz
+ bl dvmResolveStaticField @ r0<- resolved StaticField ptr
+ cmp r0, #0 @ success?
+ bne .LOP_SGET_VOLATILE_finish @ yes, finish
+ b common_exceptionThrown @ no, handle exception
+
+/* continuation for OP_SPUT_VOLATILE */
+
+ /*
+ * Continuation if the field has not yet been resolved.
+ * r1: BBBB field ref
+ */
+.LOP_SPUT_VOLATILE_resolve:
+ ldr r2, [rGLUE, #offGlue_method] @ r2<- current method
+ EXPORT_PC() @ resolve() could throw, so export now
+ ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz
+ bl dvmResolveStaticField @ r0<- resolved StaticField ptr
+ cmp r0, #0 @ success?
+ bne .LOP_SPUT_VOLATILE_finish @ yes, finish
+ b common_exceptionThrown @ no, handle exception
+
+/* continuation for OP_IGET_OBJECT_VOLATILE */
+
+ /*
+ * Currently:
+ * r0 holds resolved field
+ * r9 holds object
+ */
+.LOP_IGET_OBJECT_VOLATILE_finish:
+ @bl common_squeak0
+ cmp r9, #0 @ check object for null
+ ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field
+ beq common_errNullObject @ object was null
+ ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits)
+ SMP_DMB 1 @ acquiring load
+ mov r2, rINST, lsr #8 @ r2<- A+
+ FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
+ and r2, r2, #15 @ r2<- A
+ GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SET_VREG(r0, r2) @ fp[A]<- r0
+ GOTO_OPCODE(ip) @ jump to next instruction
+
/* continuation for OP_IGET_WIDE_VOLATILE */
/*
@@ -9475,6 +9756,57 @@ d2l_doconv:
.LOP_EXECUTE_INLINE_RANGE_table:
.word gDvmInlineOpsTable
+/* continuation for OP_IPUT_OBJECT_VOLATILE */
+
+ /*
+ * Currently:
+ * r0 holds resolved field
+ * r9 holds object
+ */
+.LOP_IPUT_OBJECT_VOLATILE_finish:
+ @bl common_squeak0
+ mov r1, rINST, lsr #8 @ r1<- A+
+ ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field
+ and r1, r1, #15 @ r1<- A
+ cmp r9, #0 @ check object for null
+ GET_VREG(r0, r1) @ r0<- fp[A]
+ beq common_errNullObject @ object was null
+ FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
+ GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB 1 @ releasing store
+ str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0
+ GOTO_OPCODE(ip) @ jump to next instruction
+
+/* continuation for OP_SGET_OBJECT_VOLATILE */
+
+ /*
+ * Continuation if the field has not yet been resolved.
+ * r1: BBBB field ref
+ */
+.LOP_SGET_OBJECT_VOLATILE_resolve:
+ ldr r2, [rGLUE, #offGlue_method] @ r2<- current method
+ EXPORT_PC() @ resolve() could throw, so export now
+ ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz
+ bl dvmResolveStaticField @ r0<- resolved StaticField ptr
+ cmp r0, #0 @ success?
+ bne .LOP_SGET_OBJECT_VOLATILE_finish @ yes, finish
+ b common_exceptionThrown @ no, handle exception
+
+/* continuation for OP_SPUT_OBJECT_VOLATILE */
+
+ /*
+ * Continuation if the field has not yet been resolved.
+ * r1: BBBB field ref
+ */
+.LOP_SPUT_OBJECT_VOLATILE_resolve:
+ ldr r2, [rGLUE, #offGlue_method] @ r2<- current method
+ EXPORT_PC() @ resolve() could throw, so export now
+ ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz
+ bl dvmResolveStaticField @ r0<- resolved StaticField ptr
+ cmp r0, #0 @ success?
+ bne .LOP_SPUT_OBJECT_VOLATILE_finish @ yes, finish
+ b common_exceptionThrown @ no, handle exception
+
.size dvmAsmSisterStart, .-dvmAsmSisterStart
.global dvmAsmSisterEnd
dvmAsmSisterEnd:
diff --git a/vm/mterp/out/InterpAsm-armv5te-vfp.S b/vm/mterp/out/InterpAsm-armv5te-vfp.S
index bfcd1108a..de4d148c5 100644
--- a/vm/mterp/out/InterpAsm-armv5te-vfp.S
+++ b/vm/mterp/out/InterpAsm-armv5te-vfp.S
@@ -20,6 +20,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
/*
* ARMv5 definitions and declarations.
*/
@@ -242,6 +243,13 @@ unspecified registers or condition codes.
ldmfd sp!, {\regs,pc}
.endm
+/*
+ * Macro for data memory barrier; not meaningful pre-ARMv6K.
+ */
+.macro SMP_DMB gen
+.endm
+
+
/* File: armv5te/entry.S */
/*
* Copyright (C) 2008 The Android Open Source Project
@@ -2787,6 +2795,7 @@ dalvik_inst:
beq .LOP_SGET_resolve @ yes, do resolve
.LOP_SGET_finish: @ field ptr in r0
ldr r1, [r0, #offStaticField_value] @ r1<- field value
+ SMP_DMB 0 @ acquiring load
mov r2, rINST, lsr #8 @ r2<- AA
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
SET_VREG(r1, r2) @ fp[AA]<- r1
@@ -2840,6 +2849,7 @@ dalvik_inst:
beq .LOP_SGET_OBJECT_resolve @ yes, do resolve
.LOP_SGET_OBJECT_finish: @ field ptr in r0
ldr r1, [r0, #offStaticField_value] @ r1<- field value
+ SMP_DMB 0 @ acquiring load
mov r2, rINST, lsr #8 @ r2<- AA
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
SET_VREG(r1, r2) @ fp[AA]<- r1
@@ -2866,6 +2876,7 @@ dalvik_inst:
beq .LOP_SGET_BOOLEAN_resolve @ yes, do resolve
.LOP_SGET_BOOLEAN_finish: @ field ptr in r0
ldr r1, [r0, #offStaticField_value] @ r1<- field value
+ SMP_DMB 0 @ acquiring load
mov r2, rINST, lsr #8 @ r2<- AA
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
SET_VREG(r1, r2) @ fp[AA]<- r1
@@ -2892,6 +2903,7 @@ dalvik_inst:
beq .LOP_SGET_BYTE_resolve @ yes, do resolve
.LOP_SGET_BYTE_finish: @ field ptr in r0
ldr r1, [r0, #offStaticField_value] @ r1<- field value
+ SMP_DMB 0 @ acquiring load
mov r2, rINST, lsr #8 @ r2<- AA
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
SET_VREG(r1, r2) @ fp[AA]<- r1
@@ -2918,6 +2930,7 @@ dalvik_inst:
beq .LOP_SGET_CHAR_resolve @ yes, do resolve
.LOP_SGET_CHAR_finish: @ field ptr in r0
ldr r1, [r0, #offStaticField_value] @ r1<- field value
+ SMP_DMB 0 @ acquiring load
mov r2, rINST, lsr #8 @ r2<- AA
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
SET_VREG(r1, r2) @ fp[AA]<- r1
@@ -2944,6 +2957,7 @@ dalvik_inst:
beq .LOP_SGET_SHORT_resolve @ yes, do resolve
.LOP_SGET_SHORT_finish: @ field ptr in r0
ldr r1, [r0, #offStaticField_value] @ r1<- field value
+ SMP_DMB 0 @ acquiring load
mov r2, rINST, lsr #8 @ r2<- AA
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
SET_VREG(r1, r2) @ fp[AA]<- r1
@@ -2972,6 +2986,7 @@ dalvik_inst:
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
GET_VREG(r1, r2) @ r1<- fp[AA]
GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB 0 @ releasing store
str r1, [r0, #offStaticField_value] @ field<- vAA
GOTO_OPCODE(ip) @ jump to next instruction
@@ -3025,6 +3040,7 @@ dalvik_inst:
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
GET_VREG(r1, r2) @ r1<- fp[AA]
GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB 0 @ releasing store
str r1, [r0, #offStaticField_value] @ field<- vAA
GOTO_OPCODE(ip) @ jump to next instruction
@@ -3051,6 +3067,7 @@ dalvik_inst:
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
GET_VREG(r1, r2) @ r1<- fp[AA]
GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB 0 @ releasing store
str r1, [r0, #offStaticField_value] @ field<- vAA
GOTO_OPCODE(ip) @ jump to next instruction
@@ -3077,6 +3094,7 @@ dalvik_inst:
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
GET_VREG(r1, r2) @ r1<- fp[AA]
GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB 0 @ releasing store
str r1, [r0, #offStaticField_value] @ field<- vAA
GOTO_OPCODE(ip) @ jump to next instruction
@@ -3103,6 +3121,7 @@ dalvik_inst:
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
GET_VREG(r1, r2) @ r1<- fp[AA]
GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB 0 @ releasing store
str r1, [r0, #offStaticField_value] @ field<- vAA
GOTO_OPCODE(ip) @ jump to next instruction
@@ -3129,6 +3148,7 @@ dalvik_inst:
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
GET_VREG(r1, r2) @ r1<- fp[AA]
GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB 0 @ releasing store
str r1, [r0, #offStaticField_value] @ field<- vAA
GOTO_OPCODE(ip) @ jump to next instruction
@@ -7082,42 +7102,140 @@ dalvik_inst:
/* ------------------------------ */
.balign 64
-.L_OP_UNUSED_E3: /* 0xe3 */
-/* File: armv5te/OP_UNUSED_E3.S */
-/* File: armv5te/unused.S */
- bl common_abort
+.L_OP_IGET_VOLATILE: /* 0xe3 */
+/* File: armv5te/OP_IGET_VOLATILE.S */
+/* File: armv5te/OP_IGET.S */
+ /*
+ * General 32-bit instance field get.
+ *
+ * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
+ */
+ /* op vA, vB, field@CCCC */
+ mov r0, rINST, lsr #12 @ r0<- B
+ ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex
+ FETCH(r1, 1) @ r1<- field ref CCCC
+ ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
+ GET_VREG(r9, r0) @ r9<- fp[B], the object pointer
+ ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr
+ cmp r0, #0 @ is resolved entry null?
+ bne .LOP_IGET_VOLATILE_finish @ no, already resolved
+8: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method
+ EXPORT_PC() @ resolve() could throw
+ ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz
+ bl dvmResolveInstField @ r0<- resolved InstField ptr
+ cmp r0, #0
+ bne .LOP_IGET_VOLATILE_finish
+ b common_exceptionThrown
/* ------------------------------ */
.balign 64
-.L_OP_UNUSED_E4: /* 0xe4 */
-/* File: armv5te/OP_UNUSED_E4.S */
-/* File: armv5te/unused.S */
- bl common_abort
+.L_OP_IPUT_VOLATILE: /* 0xe4 */
+/* File: armv5te/OP_IPUT_VOLATILE.S */
+/* File: armv5te/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 */
+ mov r0, rINST, lsr #12 @ r0<- B
+ ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex
+ FETCH(r1, 1) @ r1<- field ref CCCC
+ ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
+ GET_VREG(r9, r0) @ r9<- fp[B], the object pointer
+ ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr
+ cmp r0, #0 @ is resolved entry null?
+ bne .LOP_IPUT_VOLATILE_finish @ no, already resolved
+8: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method
+ EXPORT_PC() @ resolve() could throw
+ ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz
+ bl dvmResolveInstField @ r0<- resolved InstField ptr
+ cmp r0, #0 @ success?
+ bne .LOP_IPUT_VOLATILE_finish @ yes, finish up
+ b common_exceptionThrown
/* ------------------------------ */
.balign 64
-.L_OP_UNUSED_E5: /* 0xe5 */
-/* File: armv5te/OP_UNUSED_E5.S */
-/* File: armv5te/unused.S */
- bl common_abort
+.L_OP_SGET_VOLATILE: /* 0xe5 */
+/* File: armv5te/OP_SGET_VOLATILE.S */
+/* File: armv5te/OP_SGET.S */
+ /*
+ * General 32-bit SGET handler.
+ *
+ * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
+ */
+ /* op vAA, field@BBBB */
+ ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex
+ FETCH(r1, 1) @ r1<- field ref BBBB
+ ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
+ ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr
+ cmp r0, #0 @ is resolved entry null?
+ beq .LOP_SGET_VOLATILE_resolve @ yes, do resolve
+.LOP_SGET_VOLATILE_finish: @ field ptr in r0
+ ldr r1, [r0, #offStaticField_value] @ r1<- field value
+ SMP_DMB 1 @ acquiring load
+ mov r2, rINST, lsr #8 @ r2<- AA
+ FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
+ SET_VREG(r1, r2) @ fp[AA]<- r1
+ GET_INST_OPCODE(ip) @ extract opcode from rINST
+ GOTO_OPCODE(ip) @ jump to next instruction
/* ------------------------------ */
.balign 64
-.L_OP_UNUSED_E6: /* 0xe6 */
-/* File: armv5te/OP_UNUSED_E6.S */
-/* File: armv5te/unused.S */
- bl common_abort
+.L_OP_SPUT_VOLATILE: /* 0xe6 */
+/* File: armv5te/OP_SPUT_VOLATILE.S */
+/* File: armv5te/OP_SPUT.S */
+ /*
+ * General 32-bit SPUT handler.
+ *
+ * for: sput, sput-object, sput-boolean, sput-byte, sput-char, sput-short
+ */
+ /* op vAA, field@BBBB */
+ ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex
+ FETCH(r1, 1) @ r1<- field ref BBBB
+ ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
+ ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr
+ cmp r0, #0 @ is resolved entry null?
+ beq .LOP_SPUT_VOLATILE_resolve @ yes, do resolve
+.LOP_SPUT_VOLATILE_finish: @ field ptr in r0
+ mov r2, rINST, lsr #8 @ r2<- AA
+ FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
+ GET_VREG(r1, r2) @ r1<- fp[AA]
+ GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB 1 @ releasing store
+ str r1, [r0, #offStaticField_value] @ field<- vAA
+ GOTO_OPCODE(ip) @ jump to next instruction
/* ------------------------------ */
.balign 64
-.L_OP_UNUSED_E7: /* 0xe7 */
-/* File: armv5te/OP_UNUSED_E7.S */
-/* File: armv5te/unused.S */
- bl common_abort
+.L_OP_IGET_OBJECT_VOLATILE: /* 0xe7 */
+/* File: armv5te/OP_IGET_OBJECT_VOLATILE.S */
+/* File: armv5te/OP_IGET.S */
+ /*
+ * General 32-bit instance field get.
+ *
+ * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
+ */
+ /* op vA, vB, field@CCCC */
+ mov r0, rINST, lsr #12 @ r0<- B
+ ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex
+ FETCH(r1, 1) @ r1<- field ref CCCC
+ ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
+ GET_VREG(r9, r0) @ r9<- fp[B], the object pointer
+ ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr
+ cmp r0, #0 @ is resolved entry null?
+ bne .LOP_IGET_OBJECT_VOLATILE_finish @ no, already resolved
+8: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method
+ EXPORT_PC() @ resolve() could throw
+ ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz
+ bl dvmResolveInstField @ r0<- resolved InstField ptr
+ cmp r0, #0
+ bne .LOP_IGET_OBJECT_VOLATILE_finish
+ b common_exceptionThrown
/* ------------------------------ */
@@ -7560,26 +7678,84 @@ dalvik_inst:
/* ------------------------------ */
.balign 64
-.L_OP_UNUSED_FC: /* 0xfc */
-/* File: armv5te/OP_UNUSED_FC.S */
-/* File: armv5te/unused.S */
- bl common_abort
+.L_OP_IPUT_OBJECT_VOLATILE: /* 0xfc */
+/* File: armv5te/OP_IPUT_OBJECT_VOLATILE.S */
+/* File: armv5te/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 */
+ mov r0, rINST, lsr #12 @ r0<- B
+ ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex
+ FETCH(r1, 1) @ r1<- field ref CCCC
+ ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
+ GET_VREG(r9, r0) @ r9<- fp[B], the object pointer
+ ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr
+ cmp r0, #0 @ is resolved entry null?
+ bne .LOP_IPUT_OBJECT_VOLATILE_finish @ no, already resolved
+8: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method
+ EXPORT_PC() @ resolve() could throw
+ ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz
+ bl dvmResolveInstField @ r0<- resolved InstField ptr
+ cmp r0, #0 @ success?
+ bne .LOP_IPUT_OBJECT_VOLATILE_finish @ yes, finish up
+ b common_exceptionThrown
/* ------------------------------ */
.balign 64
-.L_OP_UNUSED_FD: /* 0xfd */
-/* File: armv5te/OP_UNUSED_FD.S */
-/* File: armv5te/unused.S */
- bl common_abort
+.L_OP_SGET_OBJECT_VOLATILE: /* 0xfd */
+/* File: armv5te/OP_SGET_OBJECT_VOLATILE.S */
+/* File: armv5te/OP_SGET.S */
+ /*
+ * General 32-bit SGET handler.
+ *
+ * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
+ */
+ /* op vAA, field@BBBB */
+ ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex
+ FETCH(r1, 1) @ r1<- field ref BBBB
+ ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
+ ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr
+ cmp r0, #0 @ is resolved entry null?
+ beq .LOP_SGET_OBJECT_VOLATILE_resolve @ yes, do resolve
+.LOP_SGET_OBJECT_VOLATILE_finish: @ field ptr in r0
+ ldr r1, [r0, #offStaticField_value] @ r1<- field value
+ SMP_DMB 1 @ acquiring load
+ mov r2, rINST, lsr #8 @ r2<- AA
+ FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
+ SET_VREG(r1, r2) @ fp[AA]<- r1
+ GET_INST_OPCODE(ip) @ extract opcode from rINST
+ GOTO_OPCODE(ip) @ jump to next instruction
/* ------------------------------ */
.balign 64
-.L_OP_UNUSED_FE: /* 0xfe */
-/* File: armv5te/OP_UNUSED_FE.S */
-/* File: armv5te/unused.S */
- bl common_abort
+.L_OP_SPUT_OBJECT_VOLATILE: /* 0xfe */
+/* File: armv5te/OP_SPUT_OBJECT_VOLATILE.S */
+/* File: armv5te/OP_SPUT.S */
+ /*
+ * General 32-bit SPUT handler.
+ *
+ * for: sput, sput-object, sput-boolean, sput-byte, sput-char, sput-short
+ */
+ /* op vAA, field@BBBB */
+ ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex
+ FETCH(r1, 1) @ r1<- field ref BBBB
+ ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
+ ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr
+ cmp r0, #0 @ is resolved entry null?
+ beq .LOP_SPUT_OBJECT_VOLATILE_resolve @ yes, do resolve
+.LOP_SPUT_OBJECT_VOLATILE_finish: @ field ptr in r0
+ mov r2, rINST, lsr #8 @ r2<- AA
+ FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
+ GET_VREG(r1, r2) @ r1<- fp[AA]
+ GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB 1 @ releasing store
+ str r1, [r0, #offStaticField_value] @ field<- vAA
+ GOTO_OPCODE(ip) @ jump to next instruction
/* ------------------------------ */
@@ -8095,6 +8271,7 @@ dvmAsmSisterStart:
ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field
beq common_errNullObject @ object was null
ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits)
+ SMP_DMB 0 @ acquiring load
mov r2, rINST, lsr #8 @ r2<- A+
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
and r2, r2, #15 @ r2<- A
@@ -8113,7 +8290,7 @@ dvmAsmSisterStart:
cmp r9, #0 @ check object for null
ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field
beq common_errNullObject @ object was null
- .if 0
+ .if 0
add r0, r9, r3 @ r0<- address of field
bl dvmQuasiAtomicRead64 @ r0/r1<- contents of field
.else
@@ -8140,6 +8317,7 @@ dvmAsmSisterStart:
ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field
beq common_errNullObject @ object was null
ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits)
+ SMP_DMB 0 @ acquiring load
mov r2, rINST, lsr #8 @ r2<- A+
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
and r2, r2, #15 @ r2<- A
@@ -8160,6 +8338,7 @@ dvmAsmSisterStart:
ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field
beq common_errNullObject @ object was null
ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits)
+ SMP_DMB 0 @ acquiring load
mov r2, rINST, lsr #8 @ r2<- A+
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
and r2, r2, #15 @ r2<- A
@@ -8180,6 +8359,7 @@ dvmAsmSisterStart:
ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field
beq common_errNullObject @ object was null
ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits)
+ SMP_DMB 0 @ acquiring load
mov r2, rINST, lsr #8 @ r2<- A+
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
and r2, r2, #15 @ r2<- A
@@ -8200,6 +8380,7 @@ dvmAsmSisterStart:
ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field
beq common_errNullObject @ object was null
ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits)
+ SMP_DMB 0 @ acquiring load
mov r2, rINST, lsr #8 @ r2<- A+
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
and r2, r2, #15 @ r2<- A
@@ -8220,6 +8401,7 @@ dvmAsmSisterStart:
ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field
beq common_errNullObject @ object was null
ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits)
+ SMP_DMB 0 @ acquiring load
mov r2, rINST, lsr #8 @ r2<- A+
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
and r2, r2, #15 @ r2<- A
@@ -8244,6 +8426,7 @@ dvmAsmSisterStart:
beq common_errNullObject @ object was null
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB 0 @ releasing store
str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0
GOTO_OPCODE(ip) @ jump to next instruction
@@ -8264,7 +8447,7 @@ dvmAsmSisterStart:
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
ldmia r2, {r0-r1} @ r0/r1<- fp[A]
GET_INST_OPCODE(r10) @ extract opcode from rINST
- .if 0
+ .if 0
add r2, r9, r3 @ r2<- target address
bl dvmQuasiAtomicSwap64 @ stores r0/r1 into addr r2
.else
@@ -8289,6 +8472,7 @@ dvmAsmSisterStart:
beq common_errNullObject @ object was null
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB 0 @ releasing store
str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0
GOTO_OPCODE(ip) @ jump to next instruction
@@ -8309,6 +8493,7 @@ dvmAsmSisterStart:
beq common_errNullObject @ object was null
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB 0 @ releasing store
str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0
GOTO_OPCODE(ip) @ jump to next instruction
@@ -8329,6 +8514,7 @@ dvmAsmSisterStart:
beq common_errNullObject @ object was null
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB 0 @ releasing store
str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0
GOTO_OPCODE(ip) @ jump to next instruction
@@ -8349,6 +8535,7 @@ dvmAsmSisterStart:
beq common_errNullObject @ object was null
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB 0 @ releasing store
str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0
GOTO_OPCODE(ip) @ jump to next instruction
@@ -8369,6 +8556,7 @@ dvmAsmSisterStart:
beq common_errNullObject @ object was null
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB 0 @ releasing store
str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0
GOTO_OPCODE(ip) @ jump to next instruction
@@ -8863,6 +9051,99 @@ d2l_doconv:
stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1
GOTO_OPCODE(ip) @ jump to next instruction
+/* continuation for OP_IGET_VOLATILE */
+
+ /*
+ * Currently:
+ * r0 holds resolved field
+ * r9 holds object
+ */
+.LOP_IGET_VOLATILE_finish:
+ @bl common_squeak0
+ cmp r9, #0 @ check object for null
+ ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field
+ beq common_errNullObject @ object was null
+ ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits)
+ SMP_DMB 1 @ acquiring load
+ mov r2, rINST, lsr #8 @ r2<- A+
+ FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
+ and r2, r2, #15 @ r2<- A
+ GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SET_VREG(r0, r2) @ fp[A]<- r0
+ GOTO_OPCODE(ip) @ jump to next instruction
+
+/* continuation for OP_IPUT_VOLATILE */
+
+ /*
+ * Currently:
+ * r0 holds resolved field
+ * r9 holds object
+ */
+.LOP_IPUT_VOLATILE_finish:
+ @bl common_squeak0
+ mov r1, rINST, lsr #8 @ r1<- A+
+ ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field
+ and r1, r1, #15 @ r1<- A
+ cmp r9, #0 @ check object for null
+ GET_VREG(r0, r1) @ r0<- fp[A]
+ beq common_errNullObject @ object was null
+ FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
+ GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB 1 @ releasing store
+ str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0
+ GOTO_OPCODE(ip) @ jump to next instruction
+
+/* continuation for OP_SGET_VOLATILE */
+
+ /*
+ * Continuation if the field has not yet been resolved.
+ * r1: BBBB field ref
+ */
+.LOP_SGET_VOLATILE_resolve:
+ ldr r2, [rGLUE, #offGlue_method] @ r2<- current method
+ EXPORT_PC() @ resolve() could throw, so export now
+ ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz
+ bl dvmResolveStaticField @ r0<- resolved StaticField ptr
+ cmp r0, #0 @ success?
+ bne .LOP_SGET_VOLATILE_finish @ yes, finish
+ b common_exceptionThrown @ no, handle exception
+
+/* continuation for OP_SPUT_VOLATILE */
+
+ /*
+ * Continuation if the field has not yet been resolved.
+ * r1: BBBB field ref
+ */
+.LOP_SPUT_VOLATILE_resolve:
+ ldr r2, [rGLUE, #offGlue_method] @ r2<- current method
+ EXPORT_PC() @ resolve() could throw, so export now
+ ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz
+ bl dvmResolveStaticField @ r0<- resolved StaticField ptr
+ cmp r0, #0 @ success?
+ bne .LOP_SPUT_VOLATILE_finish @ yes, finish
+ b common_exceptionThrown @ no, handle exception
+
+/* continuation for OP_IGET_OBJECT_VOLATILE */
+
+ /*
+ * Currently:
+ * r0 holds resolved field
+ * r9 holds object
+ */
+.LOP_IGET_OBJECT_VOLATILE_finish:
+ @bl common_squeak0
+ cmp r9, #0 @ check object for null
+ ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field
+ beq common_errNullObject @ object was null
+ ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits)
+ SMP_DMB 1 @ acquiring load
+ mov r2, rINST, lsr #8 @ r2<- A+
+ FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
+ and r2, r2, #15 @ r2<- A
+ GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SET_VREG(r0, r2) @ fp[A]<- r0
+ GOTO_OPCODE(ip) @ jump to next instruction
+
/* continuation for OP_IGET_WIDE_VOLATILE */
/*
@@ -8874,7 +9155,7 @@ d2l_doconv:
cmp r9, #0 @ check object for null
ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field
beq common_errNullObject @ object was null
- .if 1
+ .if 1
add r0, r9, r3 @ r0<- address of field
bl dvmQuasiAtomicRead64 @ r0/r1<- contents of field
.else
@@ -8905,7 +9186,7 @@ d2l_doconv:
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
ldmia r2, {r0-r1} @ r0/r1<- fp[A]
GET_INST_OPCODE(r10) @ extract opcode from rINST
- .if 1
+ .if 1
add r2, r9, r3 @ r2<- target address
bl dvmQuasiAtomicSwap64 @ stores r0/r1 into addr r2
.else
@@ -9013,6 +9294,57 @@ d2l_doconv:
.LOP_EXECUTE_INLINE_RANGE_table:
.word gDvmInlineOpsTable
+/* continuation for OP_IPUT_OBJECT_VOLATILE */
+
+ /*
+ * Currently:
+ * r0 holds resolved field
+ * r9 holds object
+ */
+.LOP_IPUT_OBJECT_VOLATILE_finish:
+ @bl common_squeak0
+ mov r1, rINST, lsr #8 @ r1<- A+
+ ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field
+ and r1, r1, #15 @ r1<- A
+ cmp r9, #0 @ check object for null
+ GET_VREG(r0, r1) @ r0<- fp[A]
+ beq common_errNullObject @ object was null
+ FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
+ GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB 1 @ releasing store
+ str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0
+ GOTO_OPCODE(ip) @ jump to next instruction
+
+/* continuation for OP_SGET_OBJECT_VOLATILE */
+
+ /*
+ * Continuation if the field has not yet been resolved.
+ * r1: BBBB field ref
+ */
+.LOP_SGET_OBJECT_VOLATILE_resolve:
+ ldr r2, [rGLUE, #offGlue_method] @ r2<- current method
+ EXPORT_PC() @ resolve() could throw, so export now
+ ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz
+ bl dvmResolveStaticField @ r0<- resolved StaticField ptr
+ cmp r0, #0 @ success?
+ bne .LOP_SGET_OBJECT_VOLATILE_finish @ yes, finish
+ b common_exceptionThrown @ no, handle exception
+
+/* continuation for OP_SPUT_OBJECT_VOLATILE */
+
+ /*
+ * Continuation if the field has not yet been resolved.
+ * r1: BBBB field ref
+ */
+.LOP_SPUT_OBJECT_VOLATILE_resolve:
+ ldr r2, [rGLUE, #offGlue_method] @ r2<- current method
+ EXPORT_PC() @ resolve() could throw, so export now
+ ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz
+ bl dvmResolveStaticField @ r0<- resolved StaticField ptr
+ cmp r0, #0 @ success?
+ bne .LOP_SPUT_OBJECT_VOLATILE_finish @ yes, finish
+ b common_exceptionThrown @ no, handle exception
+
.size dvmAsmSisterStart, .-dvmAsmSisterStart
.global dvmAsmSisterEnd
dvmAsmSisterEnd:
diff --git a/vm/mterp/out/InterpAsm-armv5te.S b/vm/mterp/out/InterpAsm-armv5te.S
index 9f69bd016..f82518367 100644
--- a/vm/mterp/out/InterpAsm-armv5te.S
+++ b/vm/mterp/out/InterpAsm-armv5te.S
@@ -20,6 +20,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
/*
* ARMv5 definitions and declarations.
*/
@@ -242,6 +243,13 @@ unspecified registers or condition codes.
ldmfd sp!, {\regs,pc}
.endm
+/*
+ * Macro for data memory barrier; not meaningful pre-ARMv6K.
+ */
+.macro SMP_DMB gen
+.endm
+
+
/* File: armv5te/entry.S */
/*
* Copyright (C) 2008 The Android Open Source Project
@@ -2809,6 +2817,7 @@ dalvik_inst:
beq .LOP_SGET_resolve @ yes, do resolve
.LOP_SGET_finish: @ field ptr in r0
ldr r1, [r0, #offStaticField_value] @ r1<- field value
+ SMP_DMB 0 @ acquiring load
mov r2, rINST, lsr #8 @ r2<- AA
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
SET_VREG(r1, r2) @ fp[AA]<- r1
@@ -2862,6 +2871,7 @@ dalvik_inst:
beq .LOP_SGET_OBJECT_resolve @ yes, do resolve
.LOP_SGET_OBJECT_finish: @ field ptr in r0
ldr r1, [r0, #offStaticField_value] @ r1<- field value
+ SMP_DMB 0 @ acquiring load
mov r2, rINST, lsr #8 @ r2<- AA
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
SET_VREG(r1, r2) @ fp[AA]<- r1
@@ -2888,6 +2898,7 @@ dalvik_inst:
beq .LOP_SGET_BOOLEAN_resolve @ yes, do resolve
.LOP_SGET_BOOLEAN_finish: @ field ptr in r0
ldr r1, [r0, #offStaticField_value] @ r1<- field value
+ SMP_DMB 0 @ acquiring load
mov r2, rINST, lsr #8 @ r2<- AA
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
SET_VREG(r1, r2) @ fp[AA]<- r1
@@ -2914,6 +2925,7 @@ dalvik_inst:
beq .LOP_SGET_BYTE_resolve @ yes, do resolve
.LOP_SGET_BYTE_finish: @ field ptr in r0
ldr r1, [r0, #offStaticField_value] @ r1<- field value
+ SMP_DMB 0 @ acquiring load
mov r2, rINST, lsr #8 @ r2<- AA
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
SET_VREG(r1, r2) @ fp[AA]<- r1
@@ -2940,6 +2952,7 @@ dalvik_inst:
beq .LOP_SGET_CHAR_resolve @ yes, do resolve
.LOP_SGET_CHAR_finish: @ field ptr in r0
ldr r1, [r0, #offStaticField_value] @ r1<- field value
+ SMP_DMB 0 @ acquiring load
mov r2, rINST, lsr #8 @ r2<- AA
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
SET_VREG(r1, r2) @ fp[AA]<- r1
@@ -2966,6 +2979,7 @@ dalvik_inst:
beq .LOP_SGET_SHORT_resolve @ yes, do resolve
.LOP_SGET_SHORT_finish: @ field ptr in r0
ldr r1, [r0, #offStaticField_value] @ r1<- field value
+ SMP_DMB 0 @ acquiring load
mov r2, rINST, lsr #8 @ r2<- AA
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
SET_VREG(r1, r2) @ fp[AA]<- r1
@@ -2994,6 +3008,7 @@ dalvik_inst:
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
GET_VREG(r1, r2) @ r1<- fp[AA]
GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB 0 @ releasing store
str r1, [r0, #offStaticField_value] @ field<- vAA
GOTO_OPCODE(ip) @ jump to next instruction
@@ -3047,6 +3062,7 @@ dalvik_inst:
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
GET_VREG(r1, r2) @ r1<- fp[AA]
GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB 0 @ releasing store
str r1, [r0, #offStaticField_value] @ field<- vAA
GOTO_OPCODE(ip) @ jump to next instruction
@@ -3073,6 +3089,7 @@ dalvik_inst:
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
GET_VREG(r1, r2) @ r1<- fp[AA]
GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB 0 @ releasing store
str r1, [r0, #offStaticField_value] @ field<- vAA
GOTO_OPCODE(ip) @ jump to next instruction
@@ -3099,6 +3116,7 @@ dalvik_inst:
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
GET_VREG(r1, r2) @ r1<- fp[AA]
GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB 0 @ releasing store
str r1, [r0, #offStaticField_value] @ field<- vAA
GOTO_OPCODE(ip) @ jump to next instruction
@@ -3125,6 +3143,7 @@ dalvik_inst:
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
GET_VREG(r1, r2) @ r1<- fp[AA]
GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB 0 @ releasing store
str r1, [r0, #offStaticField_value] @ field<- vAA
GOTO_OPCODE(ip) @ jump to next instruction
@@ -3151,6 +3170,7 @@ dalvik_inst:
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
GET_VREG(r1, r2) @ r1<- fp[AA]
GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB 0 @ releasing store
str r1, [r0, #offStaticField_value] @ field<- vAA
GOTO_OPCODE(ip) @ jump to next instruction
@@ -7404,42 +7424,140 @@ d2i_doconv:
/* ------------------------------ */
.balign 64
-.L_OP_UNUSED_E3: /* 0xe3 */
-/* File: armv5te/OP_UNUSED_E3.S */
-/* File: armv5te/unused.S */
- bl common_abort
+.L_OP_IGET_VOLATILE: /* 0xe3 */
+/* File: armv5te/OP_IGET_VOLATILE.S */
+/* File: armv5te/OP_IGET.S */
+ /*
+ * General 32-bit instance field get.
+ *
+ * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
+ */
+ /* op vA, vB, field@CCCC */
+ mov r0, rINST, lsr #12 @ r0<- B
+ ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex
+ FETCH(r1, 1) @ r1<- field ref CCCC
+ ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
+ GET_VREG(r9, r0) @ r9<- fp[B], the object pointer
+ ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr
+ cmp r0, #0 @ is resolved entry null?
+ bne .LOP_IGET_VOLATILE_finish @ no, already resolved
+8: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method
+ EXPORT_PC() @ resolve() could throw
+ ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz
+ bl dvmResolveInstField @ r0<- resolved InstField ptr
+ cmp r0, #0
+ bne .LOP_IGET_VOLATILE_finish
+ b common_exceptionThrown
/* ------------------------------ */
.balign 64
-.L_OP_UNUSED_E4: /* 0xe4 */
-/* File: armv5te/OP_UNUSED_E4.S */
-/* File: armv5te/unused.S */
- bl common_abort
+.L_OP_IPUT_VOLATILE: /* 0xe4 */
+/* File: armv5te/OP_IPUT_VOLATILE.S */
+/* File: armv5te/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 */
+ mov r0, rINST, lsr #12 @ r0<- B
+ ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex
+ FETCH(r1, 1) @ r1<- field ref CCCC
+ ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
+ GET_VREG(r9, r0) @ r9<- fp[B], the object pointer
+ ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr
+ cmp r0, #0 @ is resolved entry null?
+ bne .LOP_IPUT_VOLATILE_finish @ no, already resolved
+8: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method
+ EXPORT_PC() @ resolve() could throw
+ ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz
+ bl dvmResolveInstField @ r0<- resolved InstField ptr
+ cmp r0, #0 @ success?
+ bne .LOP_IPUT_VOLATILE_finish @ yes, finish up
+ b common_exceptionThrown
/* ------------------------------ */
.balign 64
-.L_OP_UNUSED_E5: /* 0xe5 */
-/* File: armv5te/OP_UNUSED_E5.S */
-/* File: armv5te/unused.S */
- bl common_abort
+.L_OP_SGET_VOLATILE: /* 0xe5 */
+/* File: armv5te/OP_SGET_VOLATILE.S */
+/* File: armv5te/OP_SGET.S */
+ /*
+ * General 32-bit SGET handler.
+ *
+ * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
+ */
+ /* op vAA, field@BBBB */
+ ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex
+ FETCH(r1, 1) @ r1<- field ref BBBB
+ ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
+ ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr
+ cmp r0, #0 @ is resolved entry null?
+ beq .LOP_SGET_VOLATILE_resolve @ yes, do resolve
+.LOP_SGET_VOLATILE_finish: @ field ptr in r0
+ ldr r1, [r0, #offStaticField_value] @ r1<- field value
+ SMP_DMB 1 @ acquiring load
+ mov r2, rINST, lsr #8 @ r2<- AA
+ FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
+ SET_VREG(r1, r2) @ fp[AA]<- r1
+ GET_INST_OPCODE(ip) @ extract opcode from rINST
+ GOTO_OPCODE(ip) @ jump to next instruction
/* ------------------------------ */
.balign 64
-.L_OP_UNUSED_E6: /* 0xe6 */
-/* File: armv5te/OP_UNUSED_E6.S */
-/* File: armv5te/unused.S */
- bl common_abort
+.L_OP_SPUT_VOLATILE: /* 0xe6 */
+/* File: armv5te/OP_SPUT_VOLATILE.S */
+/* File: armv5te/OP_SPUT.S */
+ /*
+ * General 32-bit SPUT handler.
+ *
+ * for: sput, sput-object, sput-boolean, sput-byte, sput-char, sput-short
+ */
+ /* op vAA, field@BBBB */
+ ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex
+ FETCH(r1, 1) @ r1<- field ref BBBB
+ ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
+ ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr
+ cmp r0, #0 @ is resolved entry null?
+ beq .LOP_SPUT_VOLATILE_resolve @ yes, do resolve
+.LOP_SPUT_VOLATILE_finish: @ field ptr in r0
+ mov r2, rINST, lsr #8 @ r2<- AA
+ FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
+ GET_VREG(r1, r2) @ r1<- fp[AA]
+ GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB 1 @ releasing store
+ str r1, [r0, #offStaticField_value] @ field<- vAA
+ GOTO_OPCODE(ip) @ jump to next instruction
/* ------------------------------ */
.balign 64
-.L_OP_UNUSED_E7: /* 0xe7 */
-/* File: armv5te/OP_UNUSED_E7.S */
-/* File: armv5te/unused.S */
- bl common_abort
+.L_OP_IGET_OBJECT_VOLATILE: /* 0xe7 */
+/* File: armv5te/OP_IGET_OBJECT_VOLATILE.S */
+/* File: armv5te/OP_IGET.S */
+ /*
+ * General 32-bit instance field get.
+ *
+ * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
+ */
+ /* op vA, vB, field@CCCC */
+ mov r0, rINST, lsr #12 @ r0<- B
+ ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex
+ FETCH(r1, 1) @ r1<- field ref CCCC
+ ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
+ GET_VREG(r9, r0) @ r9<- fp[B], the object pointer
+ ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr
+ cmp r0, #0 @ is resolved entry null?
+ bne .LOP_IGET_OBJECT_VOLATILE_finish @ no, already resolved
+8: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method
+ EXPORT_PC() @ resolve() could throw
+ ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz
+ bl dvmResolveInstField @ r0<- resolved InstField ptr
+ cmp r0, #0
+ bne .LOP_IGET_OBJECT_VOLATILE_finish
+ b common_exceptionThrown
/* ------------------------------ */
@@ -7882,26 +8000,84 @@ d2i_doconv:
/* ------------------------------ */
.balign 64
-.L_OP_UNUSED_FC: /* 0xfc */
-/* File: armv5te/OP_UNUSED_FC.S */
-/* File: armv5te/unused.S */
- bl common_abort
+.L_OP_IPUT_OBJECT_VOLATILE: /* 0xfc */
+/* File: armv5te/OP_IPUT_OBJECT_VOLATILE.S */
+/* File: armv5te/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 */
+ mov r0, rINST, lsr #12 @ r0<- B
+ ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex
+ FETCH(r1, 1) @ r1<- field ref CCCC
+ ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
+ GET_VREG(r9, r0) @ r9<- fp[B], the object pointer
+ ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr
+ cmp r0, #0 @ is resolved entry null?
+ bne .LOP_IPUT_OBJECT_VOLATILE_finish @ no, already resolved
+8: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method
+ EXPORT_PC() @ resolve() could throw
+ ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz
+ bl dvmResolveInstField @ r0<- resolved InstField ptr
+ cmp r0, #0 @ success?
+ bne .LOP_IPUT_OBJECT_VOLATILE_finish @ yes, finish up
+ b common_exceptionThrown
/* ------------------------------ */
.balign 64
-.L_OP_UNUSED_FD: /* 0xfd */
-/* File: armv5te/OP_UNUSED_FD.S */
-/* File: armv5te/unused.S */
- bl common_abort
+.L_OP_SGET_OBJECT_VOLATILE: /* 0xfd */
+/* File: armv5te/OP_SGET_OBJECT_VOLATILE.S */
+/* File: armv5te/OP_SGET.S */
+ /*
+ * General 32-bit SGET handler.
+ *
+ * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
+ */
+ /* op vAA, field@BBBB */
+ ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex
+ FETCH(r1, 1) @ r1<- field ref BBBB
+ ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
+ ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr
+ cmp r0, #0 @ is resolved entry null?
+ beq .LOP_SGET_OBJECT_VOLATILE_resolve @ yes, do resolve
+.LOP_SGET_OBJECT_VOLATILE_finish: @ field ptr in r0
+ ldr r1, [r0, #offStaticField_value] @ r1<- field value
+ SMP_DMB 1 @ acquiring load
+ mov r2, rINST, lsr #8 @ r2<- AA
+ FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
+ SET_VREG(r1, r2) @ fp[AA]<- r1
+ GET_INST_OPCODE(ip) @ extract opcode from rINST
+ GOTO_OPCODE(ip) @ jump to next instruction
/* ------------------------------ */
.balign 64
-.L_OP_UNUSED_FE: /* 0xfe */
-/* File: armv5te/OP_UNUSED_FE.S */
-/* File: armv5te/unused.S */
- bl common_abort
+.L_OP_SPUT_OBJECT_VOLATILE: /* 0xfe */
+/* File: armv5te/OP_SPUT_OBJECT_VOLATILE.S */
+/* File: armv5te/OP_SPUT.S */
+ /*
+ * General 32-bit SPUT handler.
+ *
+ * for: sput, sput-object, sput-boolean, sput-byte, sput-char, sput-short
+ */
+ /* op vAA, field@BBBB */
+ ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex
+ FETCH(r1, 1) @ r1<- field ref BBBB
+ ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
+ ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr
+ cmp r0, #0 @ is resolved entry null?
+ beq .LOP_SPUT_OBJECT_VOLATILE_resolve @ yes, do resolve
+.LOP_SPUT_OBJECT_VOLATILE_finish: @ field ptr in r0
+ mov r2, rINST, lsr #8 @ r2<- AA
+ FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
+ GET_VREG(r1, r2) @ r1<- fp[AA]
+ GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB 1 @ releasing store
+ str r1, [r0, #offStaticField_value] @ field<- vAA
+ GOTO_OPCODE(ip) @ jump to next instruction
/* ------------------------------ */
@@ -8553,6 +8729,7 @@ OP_CMPG_FLOAT_nan:
ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field
beq common_errNullObject @ object was null
ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits)
+ SMP_DMB 0 @ acquiring load
mov r2, rINST, lsr #8 @ r2<- A+
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
and r2, r2, #15 @ r2<- A
@@ -8571,7 +8748,7 @@ OP_CMPG_FLOAT_nan:
cmp r9, #0 @ check object for null
ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field
beq common_errNullObject @ object was null
- .if 0
+ .if 0
add r0, r9, r3 @ r0<- address of field
bl dvmQuasiAtomicRead64 @ r0/r1<- contents of field
.else
@@ -8598,6 +8775,7 @@ OP_CMPG_FLOAT_nan:
ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field
beq common_errNullObject @ object was null
ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits)
+ SMP_DMB 0 @ acquiring load
mov r2, rINST, lsr #8 @ r2<- A+
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
and r2, r2, #15 @ r2<- A
@@ -8618,6 +8796,7 @@ OP_CMPG_FLOAT_nan:
ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field
beq common_errNullObject @ object was null
ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits)
+ SMP_DMB 0 @ acquiring load
mov r2, rINST, lsr #8 @ r2<- A+
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
and r2, r2, #15 @ r2<- A
@@ -8638,6 +8817,7 @@ OP_CMPG_FLOAT_nan:
ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field
beq common_errNullObject @ object was null
ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits)
+ SMP_DMB 0 @ acquiring load
mov r2, rINST, lsr #8 @ r2<- A+
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
and r2, r2, #15 @ r2<- A
@@ -8658,6 +8838,7 @@ OP_CMPG_FLOAT_nan:
ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field
beq common_errNullObject @ object was null
ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits)
+ SMP_DMB 0 @ acquiring load
mov r2, rINST, lsr #8 @ r2<- A+
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
and r2, r2, #15 @ r2<- A
@@ -8678,6 +8859,7 @@ OP_CMPG_FLOAT_nan:
ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field
beq common_errNullObject @ object was null
ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits)
+ SMP_DMB 0 @ acquiring load
mov r2, rINST, lsr #8 @ r2<- A+
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
and r2, r2, #15 @ r2<- A
@@ -8702,6 +8884,7 @@ OP_CMPG_FLOAT_nan:
beq common_errNullObject @ object was null
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB 0 @ releasing store
str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0
GOTO_OPCODE(ip) @ jump to next instruction
@@ -8722,7 +8905,7 @@ OP_CMPG_FLOAT_nan:
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
ldmia r2, {r0-r1} @ r0/r1<- fp[A]
GET_INST_OPCODE(r10) @ extract opcode from rINST
- .if 0
+ .if 0
add r2, r9, r3 @ r2<- target address
bl dvmQuasiAtomicSwap64 @ stores r0/r1 into addr r2
.else
@@ -8747,6 +8930,7 @@ OP_CMPG_FLOAT_nan:
beq common_errNullObject @ object was null
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB 0 @ releasing store
str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0
GOTO_OPCODE(ip) @ jump to next instruction
@@ -8767,6 +8951,7 @@ OP_CMPG_FLOAT_nan:
beq common_errNullObject @ object was null
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB 0 @ releasing store
str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0
GOTO_OPCODE(ip) @ jump to next instruction
@@ -8787,6 +8972,7 @@ OP_CMPG_FLOAT_nan:
beq common_errNullObject @ object was null
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB 0 @ releasing store
str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0
GOTO_OPCODE(ip) @ jump to next instruction
@@ -8807,6 +8993,7 @@ OP_CMPG_FLOAT_nan:
beq common_errNullObject @ object was null
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB 0 @ releasing store
str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0
GOTO_OPCODE(ip) @ jump to next instruction
@@ -8827,6 +9014,7 @@ OP_CMPG_FLOAT_nan:
beq common_errNullObject @ object was null
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB 0 @ releasing store
str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0
GOTO_OPCODE(ip) @ jump to next instruction
@@ -9321,6 +9509,99 @@ d2l_doconv:
stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1
GOTO_OPCODE(ip) @ jump to next instruction
+/* continuation for OP_IGET_VOLATILE */
+
+ /*
+ * Currently:
+ * r0 holds resolved field
+ * r9 holds object
+ */
+.LOP_IGET_VOLATILE_finish:
+ @bl common_squeak0
+ cmp r9, #0 @ check object for null
+ ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field
+ beq common_errNullObject @ object was null
+ ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits)
+ SMP_DMB 1 @ acquiring load
+ mov r2, rINST, lsr #8 @ r2<- A+
+ FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
+ and r2, r2, #15 @ r2<- A
+ GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SET_VREG(r0, r2) @ fp[A]<- r0
+ GOTO_OPCODE(ip) @ jump to next instruction
+
+/* continuation for OP_IPUT_VOLATILE */
+
+ /*
+ * Currently:
+ * r0 holds resolved field
+ * r9 holds object
+ */
+.LOP_IPUT_VOLATILE_finish:
+ @bl common_squeak0
+ mov r1, rINST, lsr #8 @ r1<- A+
+ ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field
+ and r1, r1, #15 @ r1<- A
+ cmp r9, #0 @ check object for null
+ GET_VREG(r0, r1) @ r0<- fp[A]
+ beq common_errNullObject @ object was null
+ FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
+ GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB 1 @ releasing store
+ str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0
+ GOTO_OPCODE(ip) @ jump to next instruction
+
+/* continuation for OP_SGET_VOLATILE */
+
+ /*
+ * Continuation if the field has not yet been resolved.
+ * r1: BBBB field ref
+ */
+.LOP_SGET_VOLATILE_resolve:
+ ldr r2, [rGLUE, #offGlue_method] @ r2<- current method
+ EXPORT_PC() @ resolve() could throw, so export now
+ ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz
+ bl dvmResolveStaticField @ r0<- resolved StaticField ptr
+ cmp r0, #0 @ success?
+ bne .LOP_SGET_VOLATILE_finish @ yes, finish
+ b common_exceptionThrown @ no, handle exception
+
+/* continuation for OP_SPUT_VOLATILE */
+
+ /*
+ * Continuation if the field has not yet been resolved.
+ * r1: BBBB field ref
+ */
+.LOP_SPUT_VOLATILE_resolve:
+ ldr r2, [rGLUE, #offGlue_method] @ r2<- current method
+ EXPORT_PC() @ resolve() could throw, so export now
+ ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz
+ bl dvmResolveStaticField @ r0<- resolved StaticField ptr
+ cmp r0, #0 @ success?
+ bne .LOP_SPUT_VOLATILE_finish @ yes, finish
+ b common_exceptionThrown @ no, handle exception
+
+/* continuation for OP_IGET_OBJECT_VOLATILE */
+
+ /*
+ * Currently:
+ * r0 holds resolved field
+ * r9 holds object
+ */
+.LOP_IGET_OBJECT_VOLATILE_finish:
+ @bl common_squeak0
+ cmp r9, #0 @ check object for null
+ ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field
+ beq common_errNullObject @ object was null
+ ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits)
+ SMP_DMB 1 @ acquiring load
+ mov r2, rINST, lsr #8 @ r2<- A+
+ FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
+ and r2, r2, #15 @ r2<- A
+ GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SET_VREG(r0, r2) @ fp[A]<- r0
+ GOTO_OPCODE(ip) @ jump to next instruction
+
/* continuation for OP_IGET_WIDE_VOLATILE */
/*
@@ -9332,7 +9613,7 @@ d2l_doconv:
cmp r9, #0 @ check object for null
ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field
beq common_errNullObject @ object was null
- .if 1
+ .if 1
add r0, r9, r3 @ r0<- address of field
bl dvmQuasiAtomicRead64 @ r0/r1<- contents of field
.else
@@ -9363,7 +9644,7 @@ d2l_doconv:
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
ldmia r2, {r0-r1} @ r0/r1<- fp[A]
GET_INST_OPCODE(r10) @ extract opcode from rINST
- .if 1
+ .if 1
add r2, r9, r3 @ r2<- target address
bl dvmQuasiAtomicSwap64 @ stores r0/r1 into addr r2
.else
@@ -9471,6 +9752,57 @@ d2l_doconv:
.LOP_EXECUTE_INLINE_RANGE_table:
.word gDvmInlineOpsTable
+/* continuation for OP_IPUT_OBJECT_VOLATILE */
+
+ /*
+ * Currently:
+ * r0 holds resolved field
+ * r9 holds object
+ */
+.LOP_IPUT_OBJECT_VOLATILE_finish:
+ @bl common_squeak0
+ mov r1, rINST, lsr #8 @ r1<- A+
+ ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field
+ and r1, r1, #15 @ r1<- A
+ cmp r9, #0 @ check object for null
+ GET_VREG(r0, r1) @ r0<- fp[A]
+ beq common_errNullObject @ object was null
+ FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
+ GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB 1 @ releasing store
+ str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0
+ GOTO_OPCODE(ip) @ jump to next instruction
+
+/* continuation for OP_SGET_OBJECT_VOLATILE */
+
+ /*
+ * Continuation if the field has not yet been resolved.
+ * r1: BBBB field ref
+ */
+.LOP_SGET_OBJECT_VOLATILE_resolve:
+ ldr r2, [rGLUE, #offGlue_method] @ r2<- current method
+ EXPORT_PC() @ resolve() could throw, so export now
+ ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz
+ bl dvmResolveStaticField @ r0<- resolved StaticField ptr
+ cmp r0, #0 @ success?
+ bne .LOP_SGET_OBJECT_VOLATILE_finish @ yes, finish
+ b common_exceptionThrown @ no, handle exception
+
+/* continuation for OP_SPUT_OBJECT_VOLATILE */
+
+ /*
+ * Continuation if the field has not yet been resolved.
+ * r1: BBBB field ref
+ */
+.LOP_SPUT_OBJECT_VOLATILE_resolve:
+ ldr r2, [rGLUE, #offGlue_method] @ r2<- current method
+ EXPORT_PC() @ resolve() could throw, so export now
+ ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz
+ bl dvmResolveStaticField @ r0<- resolved StaticField ptr
+ cmp r0, #0 @ success?
+ bne .LOP_SPUT_OBJECT_VOLATILE_finish @ yes, finish
+ b common_exceptionThrown @ no, handle exception
+
.size dvmAsmSisterStart, .-dvmAsmSisterStart
.global dvmAsmSisterEnd
dvmAsmSisterEnd:
diff --git a/vm/mterp/out/InterpAsm-armv7-a-neon.S b/vm/mterp/out/InterpAsm-armv7-a-neon.S
index 3ac09aaf2..a7f7eb0e1 100644
--- a/vm/mterp/out/InterpAsm-armv7-a-neon.S
+++ b/vm/mterp/out/InterpAsm-armv7-a-neon.S
@@ -20,6 +20,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
/*
* ARMv5 definitions and declarations.
*/
@@ -205,7 +206,7 @@ unspecified registers or condition codes.
#include "../common/jit-config.h"
#endif
-/* File: armv5te/platform.S */
+/* File: armv7-a/platform.S */
/*
* ===========================================================================
* CPU-version-specific defines
@@ -242,6 +243,24 @@ unspecified registers or condition codes.
ldmfd sp!, {\regs,pc}
.endm
+#if !defined(ANDROID_SMP)
+# error "Must define ANDROID_SMP"
+#endif
+
+/*
+ * Macro for data memory barrier; not meaningful pre-ARMv6K.
+ * If the argument is nonzero, emit barrier; otherwise, emit nothing.
+ */
+.macro SMP_DMB gen
+#if ANDROID_SMP != 0
+ .if \gen
+ dmb
+ .endif
+#else
+ /* not SMP */
+#endif
+.endm
+
/* File: armv5te/entry.S */
/*
* Copyright (C) 2008 The Android Open Source Project
@@ -2777,6 +2796,7 @@ dalvik_inst:
beq .LOP_SGET_resolve @ yes, do resolve
.LOP_SGET_finish: @ field ptr in r0
ldr r1, [r0, #offStaticField_value] @ r1<- field value
+ SMP_DMB 0 @ acquiring load
mov r2, rINST, lsr #8 @ r2<- AA
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
SET_VREG(r1, r2) @ fp[AA]<- r1
@@ -2830,6 +2850,7 @@ dalvik_inst:
beq .LOP_SGET_OBJECT_resolve @ yes, do resolve
.LOP_SGET_OBJECT_finish: @ field ptr in r0
ldr r1, [r0, #offStaticField_value] @ r1<- field value
+ SMP_DMB 0 @ acquiring load
mov r2, rINST, lsr #8 @ r2<- AA
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
SET_VREG(r1, r2) @ fp[AA]<- r1
@@ -2856,6 +2877,7 @@ dalvik_inst:
beq .LOP_SGET_BOOLEAN_resolve @ yes, do resolve
.LOP_SGET_BOOLEAN_finish: @ field ptr in r0
ldr r1, [r0, #offStaticField_value] @ r1<- field value
+ SMP_DMB 0 @ acquiring load
mov r2, rINST, lsr #8 @ r2<- AA
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
SET_VREG(r1, r2) @ fp[AA]<- r1
@@ -2882,6 +2904,7 @@ dalvik_inst:
beq .LOP_SGET_BYTE_resolve @ yes, do resolve
.LOP_SGET_BYTE_finish: @ field ptr in r0
ldr r1, [r0, #offStaticField_value] @ r1<- field value
+ SMP_DMB 0 @ acquiring load
mov r2, rINST, lsr #8 @ r2<- AA
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
SET_VREG(r1, r2) @ fp[AA]<- r1
@@ -2908,6 +2931,7 @@ dalvik_inst:
beq .LOP_SGET_CHAR_resolve @ yes, do resolve
.LOP_SGET_CHAR_finish: @ field ptr in r0
ldr r1, [r0, #offStaticField_value] @ r1<- field value
+ SMP_DMB 0 @ acquiring load
mov r2, rINST, lsr #8 @ r2<- AA
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
SET_VREG(r1, r2) @ fp[AA]<- r1
@@ -2934,6 +2958,7 @@ dalvik_inst:
beq .LOP_SGET_SHORT_resolve @ yes, do resolve
.LOP_SGET_SHORT_finish: @ field ptr in r0
ldr r1, [r0, #offStaticField_value] @ r1<- field value
+ SMP_DMB 0 @ acquiring load
mov r2, rINST, lsr #8 @ r2<- AA
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
SET_VREG(r1, r2) @ fp[AA]<- r1
@@ -2962,6 +2987,7 @@ dalvik_inst:
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
GET_VREG(r1, r2) @ r1<- fp[AA]
GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB 0 @ releasing store
str r1, [r0, #offStaticField_value] @ field<- vAA
GOTO_OPCODE(ip) @ jump to next instruction
@@ -3015,6 +3041,7 @@ dalvik_inst:
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
GET_VREG(r1, r2) @ r1<- fp[AA]
GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB 0 @ releasing store
str r1, [r0, #offStaticField_value] @ field<- vAA
GOTO_OPCODE(ip) @ jump to next instruction
@@ -3041,6 +3068,7 @@ dalvik_inst:
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
GET_VREG(r1, r2) @ r1<- fp[AA]
GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB 0 @ releasing store
str r1, [r0, #offStaticField_value] @ field<- vAA
GOTO_OPCODE(ip) @ jump to next instruction
@@ -3067,6 +3095,7 @@ dalvik_inst:
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
GET_VREG(r1, r2) @ r1<- fp[AA]
GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB 0 @ releasing store
str r1, [r0, #offStaticField_value] @ field<- vAA
GOTO_OPCODE(ip) @ jump to next instruction
@@ -3093,6 +3122,7 @@ dalvik_inst:
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
GET_VREG(r1, r2) @ r1<- fp[AA]
GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB 0 @ releasing store
str r1, [r0, #offStaticField_value] @ field<- vAA
GOTO_OPCODE(ip) @ jump to next instruction
@@ -3119,6 +3149,7 @@ dalvik_inst:
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
GET_VREG(r1, r2) @ r1<- fp[AA]
GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB 0 @ releasing store
str r1, [r0, #offStaticField_value] @ field<- vAA
GOTO_OPCODE(ip) @ jump to next instruction
@@ -7026,42 +7057,140 @@ dalvik_inst:
/* ------------------------------ */
.balign 64
-.L_OP_UNUSED_E3: /* 0xe3 */
-/* File: armv5te/OP_UNUSED_E3.S */
-/* File: armv5te/unused.S */
- bl common_abort
+.L_OP_IGET_VOLATILE: /* 0xe3 */
+/* File: armv5te/OP_IGET_VOLATILE.S */
+/* File: armv5te/OP_IGET.S */
+ /*
+ * General 32-bit instance field get.
+ *
+ * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
+ */
+ /* op vA, vB, field@CCCC */
+ mov r0, rINST, lsr #12 @ r0<- B
+ ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex
+ FETCH(r1, 1) @ r1<- field ref CCCC
+ ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
+ GET_VREG(r9, r0) @ r9<- fp[B], the object pointer
+ ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr
+ cmp r0, #0 @ is resolved entry null?
+ bne .LOP_IGET_VOLATILE_finish @ no, already resolved
+8: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method
+ EXPORT_PC() @ resolve() could throw
+ ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz
+ bl dvmResolveInstField @ r0<- resolved InstField ptr
+ cmp r0, #0
+ bne .LOP_IGET_VOLATILE_finish
+ b common_exceptionThrown
/* ------------------------------ */
.balign 64
-.L_OP_UNUSED_E4: /* 0xe4 */
-/* File: armv5te/OP_UNUSED_E4.S */
-/* File: armv5te/unused.S */
- bl common_abort
+.L_OP_IPUT_VOLATILE: /* 0xe4 */
+/* File: armv5te/OP_IPUT_VOLATILE.S */
+/* File: armv5te/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 */
+ mov r0, rINST, lsr #12 @ r0<- B
+ ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex
+ FETCH(r1, 1) @ r1<- field ref CCCC
+ ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
+ GET_VREG(r9, r0) @ r9<- fp[B], the object pointer
+ ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr
+ cmp r0, #0 @ is resolved entry null?
+ bne .LOP_IPUT_VOLATILE_finish @ no, already resolved
+8: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method
+ EXPORT_PC() @ resolve() could throw
+ ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz
+ bl dvmResolveInstField @ r0<- resolved InstField ptr
+ cmp r0, #0 @ success?
+ bne .LOP_IPUT_VOLATILE_finish @ yes, finish up
+ b common_exceptionThrown
/* ------------------------------ */
.balign 64
-.L_OP_UNUSED_E5: /* 0xe5 */
-/* File: armv5te/OP_UNUSED_E5.S */
-/* File: armv5te/unused.S */
- bl common_abort
+.L_OP_SGET_VOLATILE: /* 0xe5 */
+/* File: armv5te/OP_SGET_VOLATILE.S */
+/* File: armv5te/OP_SGET.S */
+ /*
+ * General 32-bit SGET handler.
+ *
+ * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
+ */
+ /* op vAA, field@BBBB */
+ ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex
+ FETCH(r1, 1) @ r1<- field ref BBBB
+ ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
+ ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr
+ cmp r0, #0 @ is resolved entry null?
+ beq .LOP_SGET_VOLATILE_resolve @ yes, do resolve
+.LOP_SGET_VOLATILE_finish: @ field ptr in r0
+ ldr r1, [r0, #offStaticField_value] @ r1<- field value
+ SMP_DMB 1 @ acquiring load
+ mov r2, rINST, lsr #8 @ r2<- AA
+ FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
+ SET_VREG(r1, r2) @ fp[AA]<- r1
+ GET_INST_OPCODE(ip) @ extract opcode from rINST
+ GOTO_OPCODE(ip) @ jump to next instruction
/* ------------------------------ */
.balign 64
-.L_OP_UNUSED_E6: /* 0xe6 */
-/* File: armv5te/OP_UNUSED_E6.S */
-/* File: armv5te/unused.S */
- bl common_abort
+.L_OP_SPUT_VOLATILE: /* 0xe6 */
+/* File: armv5te/OP_SPUT_VOLATILE.S */
+/* File: armv5te/OP_SPUT.S */
+ /*
+ * General 32-bit SPUT handler.
+ *
+ * for: sput, sput-object, sput-boolean, sput-byte, sput-char, sput-short
+ */
+ /* op vAA, field@BBBB */
+ ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex
+ FETCH(r1, 1) @ r1<- field ref BBBB
+ ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
+ ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr
+ cmp r0, #0 @ is resolved entry null?
+ beq .LOP_SPUT_VOLATILE_resolve @ yes, do resolve
+.LOP_SPUT_VOLATILE_finish: @ field ptr in r0
+ mov r2, rINST, lsr #8 @ r2<- AA
+ FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
+ GET_VREG(r1, r2) @ r1<- fp[AA]
+ GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB 1 @ releasing store
+ str r1, [r0, #offStaticField_value] @ field<- vAA
+ GOTO_OPCODE(ip) @ jump to next instruction
/* ------------------------------ */
.balign 64
-.L_OP_UNUSED_E7: /* 0xe7 */
-/* File: armv5te/OP_UNUSED_E7.S */
-/* File: armv5te/unused.S */
- bl common_abort
+.L_OP_IGET_OBJECT_VOLATILE: /* 0xe7 */
+/* File: armv5te/OP_IGET_OBJECT_VOLATILE.S */
+/* File: armv5te/OP_IGET.S */
+ /*
+ * General 32-bit instance field get.
+ *
+ * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
+ */
+ /* op vA, vB, field@CCCC */
+ mov r0, rINST, lsr #12 @ r0<- B
+ ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex
+ FETCH(r1, 1) @ r1<- field ref CCCC
+ ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
+ GET_VREG(r9, r0) @ r9<- fp[B], the object pointer
+ ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr
+ cmp r0, #0 @ is resolved entry null?
+ bne .LOP_IGET_OBJECT_VOLATILE_finish @ no, already resolved
+8: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method
+ EXPORT_PC() @ resolve() could throw
+ ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz
+ bl dvmResolveInstField @ r0<- resolved InstField ptr
+ cmp r0, #0
+ bne .LOP_IGET_OBJECT_VOLATILE_finish
+ b common_exceptionThrown
/* ------------------------------ */
@@ -7500,26 +7629,84 @@ dalvik_inst:
/* ------------------------------ */
.balign 64
-.L_OP_UNUSED_FC: /* 0xfc */
-/* File: armv5te/OP_UNUSED_FC.S */
-/* File: armv5te/unused.S */
- bl common_abort
+.L_OP_IPUT_OBJECT_VOLATILE: /* 0xfc */
+/* File: armv5te/OP_IPUT_OBJECT_VOLATILE.S */
+/* File: armv5te/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 */
+ mov r0, rINST, lsr #12 @ r0<- B
+ ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex
+ FETCH(r1, 1) @ r1<- field ref CCCC
+ ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
+ GET_VREG(r9, r0) @ r9<- fp[B], the object pointer
+ ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr
+ cmp r0, #0 @ is resolved entry null?
+ bne .LOP_IPUT_OBJECT_VOLATILE_finish @ no, already resolved
+8: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method
+ EXPORT_PC() @ resolve() could throw
+ ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz
+ bl dvmResolveInstField @ r0<- resolved InstField ptr
+ cmp r0, #0 @ success?
+ bne .LOP_IPUT_OBJECT_VOLATILE_finish @ yes, finish up
+ b common_exceptionThrown
/* ------------------------------ */
.balign 64
-.L_OP_UNUSED_FD: /* 0xfd */
-/* File: armv5te/OP_UNUSED_FD.S */
-/* File: armv5te/unused.S */
- bl common_abort
+.L_OP_SGET_OBJECT_VOLATILE: /* 0xfd */
+/* File: armv5te/OP_SGET_OBJECT_VOLATILE.S */
+/* File: armv5te/OP_SGET.S */
+ /*
+ * General 32-bit SGET handler.
+ *
+ * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
+ */
+ /* op vAA, field@BBBB */
+ ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex
+ FETCH(r1, 1) @ r1<- field ref BBBB
+ ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
+ ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr
+ cmp r0, #0 @ is resolved entry null?
+ beq .LOP_SGET_OBJECT_VOLATILE_resolve @ yes, do resolve
+.LOP_SGET_OBJECT_VOLATILE_finish: @ field ptr in r0
+ ldr r1, [r0, #offStaticField_value] @ r1<- field value
+ SMP_DMB 1 @ acquiring load
+ mov r2, rINST, lsr #8 @ r2<- AA
+ FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
+ SET_VREG(r1, r2) @ fp[AA]<- r1
+ GET_INST_OPCODE(ip) @ extract opcode from rINST
+ GOTO_OPCODE(ip) @ jump to next instruction
/* ------------------------------ */
.balign 64
-.L_OP_UNUSED_FE: /* 0xfe */
-/* File: armv5te/OP_UNUSED_FE.S */
-/* File: armv5te/unused.S */
- bl common_abort
+.L_OP_SPUT_OBJECT_VOLATILE: /* 0xfe */
+/* File: armv5te/OP_SPUT_OBJECT_VOLATILE.S */
+/* File: armv5te/OP_SPUT.S */
+ /*
+ * General 32-bit SPUT handler.
+ *
+ * for: sput, sput-object, sput-boolean, sput-byte, sput-char, sput-short
+ */
+ /* op vAA, field@BBBB */
+ ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex
+ FETCH(r1, 1) @ r1<- field ref BBBB
+ ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
+ ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr
+ cmp r0, #0 @ is resolved entry null?
+ beq .LOP_SPUT_OBJECT_VOLATILE_resolve @ yes, do resolve
+.LOP_SPUT_OBJECT_VOLATILE_finish: @ field ptr in r0
+ mov r2, rINST, lsr #8 @ r2<- AA
+ FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
+ GET_VREG(r1, r2) @ r1<- fp[AA]
+ GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB 1 @ releasing store
+ str r1, [r0, #offStaticField_value] @ field<- vAA
+ GOTO_OPCODE(ip) @ jump to next instruction
/* ------------------------------ */
@@ -8073,6 +8260,7 @@ dvmAsmSisterStart:
ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field
beq common_errNullObject @ object was null
ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits)
+ SMP_DMB 0 @ acquiring load
mov r2, rINST, lsr #8 @ r2<- A+
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
and r2, r2, #15 @ r2<- A
@@ -8093,6 +8281,7 @@ dvmAsmSisterStart:
ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field
beq common_errNullObject @ object was null
ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits)
+ SMP_DMB 0 @ acquiring load
mov r2, rINST, lsr #8 @ r2<- A+
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
and r2, r2, #15 @ r2<- A
@@ -8113,6 +8302,7 @@ dvmAsmSisterStart:
ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field
beq common_errNullObject @ object was null
ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits)
+ SMP_DMB 0 @ acquiring load
mov r2, rINST, lsr #8 @ r2<- A+
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
and r2, r2, #15 @ r2<- A
@@ -8133,6 +8323,7 @@ dvmAsmSisterStart:
ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field
beq common_errNullObject @ object was null
ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits)
+ SMP_DMB 0 @ acquiring load
mov r2, rINST, lsr #8 @ r2<- A+
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
and r2, r2, #15 @ r2<- A
@@ -8153,6 +8344,7 @@ dvmAsmSisterStart:
ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field
beq common_errNullObject @ object was null
ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits)
+ SMP_DMB 0 @ acquiring load
mov r2, rINST, lsr #8 @ r2<- A+
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
and r2, r2, #15 @ r2<- A
@@ -8215,6 +8407,7 @@ dvmAsmSisterStart:
beq common_errNullObject @ object was null
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB 0 @ releasing store
str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0
GOTO_OPCODE(ip) @ jump to next instruction
@@ -8235,6 +8428,7 @@ dvmAsmSisterStart:
beq common_errNullObject @ object was null
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB 0 @ releasing store
str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0
GOTO_OPCODE(ip) @ jump to next instruction
@@ -8255,6 +8449,7 @@ dvmAsmSisterStart:
beq common_errNullObject @ object was null
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB 0 @ releasing store
str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0
GOTO_OPCODE(ip) @ jump to next instruction
@@ -8275,6 +8470,7 @@ dvmAsmSisterStart:
beq common_errNullObject @ object was null
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB 0 @ releasing store
str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0
GOTO_OPCODE(ip) @ jump to next instruction
@@ -8295,6 +8491,7 @@ dvmAsmSisterStart:
beq common_errNullObject @ object was null
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB 0 @ releasing store
str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0
GOTO_OPCODE(ip) @ jump to next instruction
@@ -8789,6 +8986,99 @@ d2l_doconv:
stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1
GOTO_OPCODE(ip) @ jump to next instruction
+/* continuation for OP_IGET_VOLATILE */
+
+ /*
+ * Currently:
+ * r0 holds resolved field
+ * r9 holds object
+ */
+.LOP_IGET_VOLATILE_finish:
+ @bl common_squeak0
+ cmp r9, #0 @ check object for null
+ ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field
+ beq common_errNullObject @ object was null
+ ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits)
+ SMP_DMB 1 @ acquiring load
+ mov r2, rINST, lsr #8 @ r2<- A+
+ FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
+ and r2, r2, #15 @ r2<- A
+ GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SET_VREG(r0, r2) @ fp[A]<- r0
+ GOTO_OPCODE(ip) @ jump to next instruction
+
+/* continuation for OP_IPUT_VOLATILE */
+
+ /*
+ * Currently:
+ * r0 holds resolved field
+ * r9 holds object
+ */
+.LOP_IPUT_VOLATILE_finish:
+ @bl common_squeak0
+ mov r1, rINST, lsr #8 @ r1<- A+
+ ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field
+ and r1, r1, #15 @ r1<- A
+ cmp r9, #0 @ check object for null
+ GET_VREG(r0, r1) @ r0<- fp[A]
+ beq common_errNullObject @ object was null
+ FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
+ GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB 1 @ releasing store
+ str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0
+ GOTO_OPCODE(ip) @ jump to next instruction
+
+/* continuation for OP_SGET_VOLATILE */
+
+ /*
+ * Continuation if the field has not yet been resolved.
+ * r1: BBBB field ref
+ */
+.LOP_SGET_VOLATILE_resolve:
+ ldr r2, [rGLUE, #offGlue_method] @ r2<- current method
+ EXPORT_PC() @ resolve() could throw, so export now
+ ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz
+ bl dvmResolveStaticField @ r0<- resolved StaticField ptr
+ cmp r0, #0 @ success?
+ bne .LOP_SGET_VOLATILE_finish @ yes, finish
+ b common_exceptionThrown @ no, handle exception
+
+/* continuation for OP_SPUT_VOLATILE */
+
+ /*
+ * Continuation if the field has not yet been resolved.
+ * r1: BBBB field ref
+ */
+.LOP_SPUT_VOLATILE_resolve:
+ ldr r2, [rGLUE, #offGlue_method] @ r2<- current method
+ EXPORT_PC() @ resolve() could throw, so export now
+ ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz
+ bl dvmResolveStaticField @ r0<- resolved StaticField ptr
+ cmp r0, #0 @ success?
+ bne .LOP_SPUT_VOLATILE_finish @ yes, finish
+ b common_exceptionThrown @ no, handle exception
+
+/* continuation for OP_IGET_OBJECT_VOLATILE */
+
+ /*
+ * Currently:
+ * r0 holds resolved field
+ * r9 holds object
+ */
+.LOP_IGET_OBJECT_VOLATILE_finish:
+ @bl common_squeak0
+ cmp r9, #0 @ check object for null
+ ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field
+ beq common_errNullObject @ object was null
+ ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits)
+ SMP_DMB 1 @ acquiring load
+ mov r2, rINST, lsr #8 @ r2<- A+
+ FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
+ and r2, r2, #15 @ r2<- A
+ GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SET_VREG(r0, r2) @ fp[A]<- r0
+ GOTO_OPCODE(ip) @ jump to next instruction
+
/* continuation for OP_IGET_WIDE_VOLATILE */
/*
@@ -8800,7 +9090,7 @@ d2l_doconv:
cmp r9, #0 @ check object for null
ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field
beq common_errNullObject @ object was null
- .if 1
+ .if 1
add r0, r9, r3 @ r0<- address of field
bl dvmQuasiAtomicRead64 @ r0/r1<- contents of field
.else
@@ -8831,7 +9121,7 @@ d2l_doconv:
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
ldmia r2, {r0-r1} @ r0/r1<- fp[A]
GET_INST_OPCODE(r10) @ extract opcode from rINST
- .if 1
+ .if 1
add r2, r9, r3 @ r2<- target address
bl dvmQuasiAtomicSwap64 @ stores r0/r1 into addr r2
.else
@@ -8939,6 +9229,57 @@ d2l_doconv:
.LOP_EXECUTE_INLINE_RANGE_table:
.word gDvmInlineOpsTable
+/* continuation for OP_IPUT_OBJECT_VOLATILE */
+
+ /*
+ * Currently:
+ * r0 holds resolved field
+ * r9 holds object
+ */
+.LOP_IPUT_OBJECT_VOLATILE_finish:
+ @bl common_squeak0
+ mov r1, rINST, lsr #8 @ r1<- A+
+ ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field
+ and r1, r1, #15 @ r1<- A
+ cmp r9, #0 @ check object for null
+ GET_VREG(r0, r1) @ r0<- fp[A]
+ beq common_errNullObject @ object was null
+ FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
+ GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB 1 @ releasing store
+ str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0
+ GOTO_OPCODE(ip) @ jump to next instruction
+
+/* continuation for OP_SGET_OBJECT_VOLATILE */
+
+ /*
+ * Continuation if the field has not yet been resolved.
+ * r1: BBBB field ref
+ */
+.LOP_SGET_OBJECT_VOLATILE_resolve:
+ ldr r2, [rGLUE, #offGlue_method] @ r2<- current method
+ EXPORT_PC() @ resolve() could throw, so export now
+ ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz
+ bl dvmResolveStaticField @ r0<- resolved StaticField ptr
+ cmp r0, #0 @ success?
+ bne .LOP_SGET_OBJECT_VOLATILE_finish @ yes, finish
+ b common_exceptionThrown @ no, handle exception
+
+/* continuation for OP_SPUT_OBJECT_VOLATILE */
+
+ /*
+ * Continuation if the field has not yet been resolved.
+ * r1: BBBB field ref
+ */
+.LOP_SPUT_OBJECT_VOLATILE_resolve:
+ ldr r2, [rGLUE, #offGlue_method] @ r2<- current method
+ EXPORT_PC() @ resolve() could throw, so export now
+ ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz
+ bl dvmResolveStaticField @ r0<- resolved StaticField ptr
+ cmp r0, #0 @ success?
+ bne .LOP_SPUT_OBJECT_VOLATILE_finish @ yes, finish
+ b common_exceptionThrown @ no, handle exception
+
.size dvmAsmSisterStart, .-dvmAsmSisterStart
.global dvmAsmSisterEnd
dvmAsmSisterEnd:
diff --git a/vm/mterp/out/InterpAsm-armv7-a.S b/vm/mterp/out/InterpAsm-armv7-a.S
index db8403107..8e0cac9dd 100644
--- a/vm/mterp/out/InterpAsm-armv7-a.S
+++ b/vm/mterp/out/InterpAsm-armv7-a.S
@@ -20,6 +20,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
/*
* ARMv5 definitions and declarations.
*/
@@ -205,7 +206,7 @@ unspecified registers or condition codes.
#include "../common/jit-config.h"
#endif
-/* File: armv5te/platform.S */
+/* File: armv7-a/platform.S */
/*
* ===========================================================================
* CPU-version-specific defines
@@ -242,6 +243,24 @@ unspecified registers or condition codes.
ldmfd sp!, {\regs,pc}
.endm
+#if !defined(ANDROID_SMP)
+# error "Must define ANDROID_SMP"
+#endif
+
+/*
+ * Macro for data memory barrier; not meaningful pre-ARMv6K.
+ * If the argument is nonzero, emit barrier; otherwise, emit nothing.
+ */
+.macro SMP_DMB gen
+#if ANDROID_SMP != 0
+ .if \gen
+ dmb
+ .endif
+#else
+ /* not SMP */
+#endif
+.endm
+
/* File: armv5te/entry.S */
/*
* Copyright (C) 2008 The Android Open Source Project
@@ -2777,6 +2796,7 @@ dalvik_inst:
beq .LOP_SGET_resolve @ yes, do resolve
.LOP_SGET_finish: @ field ptr in r0
ldr r1, [r0, #offStaticField_value] @ r1<- field value
+ SMP_DMB 0 @ acquiring load
mov r2, rINST, lsr #8 @ r2<- AA
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
SET_VREG(r1, r2) @ fp[AA]<- r1
@@ -2830,6 +2850,7 @@ dalvik_inst:
beq .LOP_SGET_OBJECT_resolve @ yes, do resolve
.LOP_SGET_OBJECT_finish: @ field ptr in r0
ldr r1, [r0, #offStaticField_value] @ r1<- field value
+ SMP_DMB 0 @ acquiring load
mov r2, rINST, lsr #8 @ r2<- AA
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
SET_VREG(r1, r2) @ fp[AA]<- r1
@@ -2856,6 +2877,7 @@ dalvik_inst:
beq .LOP_SGET_BOOLEAN_resolve @ yes, do resolve
.LOP_SGET_BOOLEAN_finish: @ field ptr in r0
ldr r1, [r0, #offStaticField_value] @ r1<- field value
+ SMP_DMB 0 @ acquiring load
mov r2, rINST, lsr #8 @ r2<- AA
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
SET_VREG(r1, r2) @ fp[AA]<- r1
@@ -2882,6 +2904,7 @@ dalvik_inst:
beq .LOP_SGET_BYTE_resolve @ yes, do resolve
.LOP_SGET_BYTE_finish: @ field ptr in r0
ldr r1, [r0, #offStaticField_value] @ r1<- field value
+ SMP_DMB 0 @ acquiring load
mov r2, rINST, lsr #8 @ r2<- AA
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
SET_VREG(r1, r2) @ fp[AA]<- r1
@@ -2908,6 +2931,7 @@ dalvik_inst:
beq .LOP_SGET_CHAR_resolve @ yes, do resolve
.LOP_SGET_CHAR_finish: @ field ptr in r0
ldr r1, [r0, #offStaticField_value] @ r1<- field value
+ SMP_DMB 0 @ acquiring load
mov r2, rINST, lsr #8 @ r2<- AA
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
SET_VREG(r1, r2) @ fp[AA]<- r1
@@ -2934,6 +2958,7 @@ dalvik_inst:
beq .LOP_SGET_SHORT_resolve @ yes, do resolve
.LOP_SGET_SHORT_finish: @ field ptr in r0
ldr r1, [r0, #offStaticField_value] @ r1<- field value
+ SMP_DMB 0 @ acquiring load
mov r2, rINST, lsr #8 @ r2<- AA
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
SET_VREG(r1, r2) @ fp[AA]<- r1
@@ -2962,6 +2987,7 @@ dalvik_inst:
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
GET_VREG(r1, r2) @ r1<- fp[AA]
GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB 0 @ releasing store
str r1, [r0, #offStaticField_value] @ field<- vAA
GOTO_OPCODE(ip) @ jump to next instruction
@@ -3015,6 +3041,7 @@ dalvik_inst:
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
GET_VREG(r1, r2) @ r1<- fp[AA]
GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB 0 @ releasing store
str r1, [r0, #offStaticField_value] @ field<- vAA
GOTO_OPCODE(ip) @ jump to next instruction
@@ -3041,6 +3068,7 @@ dalvik_inst:
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
GET_VREG(r1, r2) @ r1<- fp[AA]
GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB 0 @ releasing store
str r1, [r0, #offStaticField_value] @ field<- vAA
GOTO_OPCODE(ip) @ jump to next instruction
@@ -3067,6 +3095,7 @@ dalvik_inst:
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
GET_VREG(r1, r2) @ r1<- fp[AA]
GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB 0 @ releasing store
str r1, [r0, #offStaticField_value] @ field<- vAA
GOTO_OPCODE(ip) @ jump to next instruction
@@ -3093,6 +3122,7 @@ dalvik_inst:
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
GET_VREG(r1, r2) @ r1<- fp[AA]
GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB 0 @ releasing store
str r1, [r0, #offStaticField_value] @ field<- vAA
GOTO_OPCODE(ip) @ jump to next instruction
@@ -3119,6 +3149,7 @@ dalvik_inst:
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
GET_VREG(r1, r2) @ r1<- fp[AA]
GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB 0 @ releasing store
str r1, [r0, #offStaticField_value] @ field<- vAA
GOTO_OPCODE(ip) @ jump to next instruction
@@ -7026,42 +7057,140 @@ dalvik_inst:
/* ------------------------------ */
.balign 64
-.L_OP_UNUSED_E3: /* 0xe3 */
-/* File: armv5te/OP_UNUSED_E3.S */
-/* File: armv5te/unused.S */
- bl common_abort
+.L_OP_IGET_VOLATILE: /* 0xe3 */
+/* File: armv5te/OP_IGET_VOLATILE.S */
+/* File: armv5te/OP_IGET.S */
+ /*
+ * General 32-bit instance field get.
+ *
+ * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
+ */
+ /* op vA, vB, field@CCCC */
+ mov r0, rINST, lsr #12 @ r0<- B
+ ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex
+ FETCH(r1, 1) @ r1<- field ref CCCC
+ ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
+ GET_VREG(r9, r0) @ r9<- fp[B], the object pointer
+ ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr
+ cmp r0, #0 @ is resolved entry null?
+ bne .LOP_IGET_VOLATILE_finish @ no, already resolved
+8: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method
+ EXPORT_PC() @ resolve() could throw
+ ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz
+ bl dvmResolveInstField @ r0<- resolved InstField ptr
+ cmp r0, #0
+ bne .LOP_IGET_VOLATILE_finish
+ b common_exceptionThrown
/* ------------------------------ */
.balign 64
-.L_OP_UNUSED_E4: /* 0xe4 */
-/* File: armv5te/OP_UNUSED_E4.S */
-/* File: armv5te/unused.S */
- bl common_abort
+.L_OP_IPUT_VOLATILE: /* 0xe4 */
+/* File: armv5te/OP_IPUT_VOLATILE.S */
+/* File: armv5te/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 */
+ mov r0, rINST, lsr #12 @ r0<- B
+ ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex
+ FETCH(r1, 1) @ r1<- field ref CCCC
+ ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
+ GET_VREG(r9, r0) @ r9<- fp[B], the object pointer
+ ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr
+ cmp r0, #0 @ is resolved entry null?
+ bne .LOP_IPUT_VOLATILE_finish @ no, already resolved
+8: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method
+ EXPORT_PC() @ resolve() could throw
+ ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz
+ bl dvmResolveInstField @ r0<- resolved InstField ptr
+ cmp r0, #0 @ success?
+ bne .LOP_IPUT_VOLATILE_finish @ yes, finish up
+ b common_exceptionThrown
/* ------------------------------ */
.balign 64
-.L_OP_UNUSED_E5: /* 0xe5 */
-/* File: armv5te/OP_UNUSED_E5.S */
-/* File: armv5te/unused.S */
- bl common_abort
+.L_OP_SGET_VOLATILE: /* 0xe5 */
+/* File: armv5te/OP_SGET_VOLATILE.S */
+/* File: armv5te/OP_SGET.S */
+ /*
+ * General 32-bit SGET handler.
+ *
+ * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
+ */
+ /* op vAA, field@BBBB */
+ ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex
+ FETCH(r1, 1) @ r1<- field ref BBBB
+ ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
+ ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr
+ cmp r0, #0 @ is resolved entry null?
+ beq .LOP_SGET_VOLATILE_resolve @ yes, do resolve
+.LOP_SGET_VOLATILE_finish: @ field ptr in r0
+ ldr r1, [r0, #offStaticField_value] @ r1<- field value
+ SMP_DMB 1 @ acquiring load
+ mov r2, rINST, lsr #8 @ r2<- AA
+ FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
+ SET_VREG(r1, r2) @ fp[AA]<- r1
+ GET_INST_OPCODE(ip) @ extract opcode from rINST
+ GOTO_OPCODE(ip) @ jump to next instruction
/* ------------------------------ */
.balign 64
-.L_OP_UNUSED_E6: /* 0xe6 */
-/* File: armv5te/OP_UNUSED_E6.S */
-/* File: armv5te/unused.S */
- bl common_abort
+.L_OP_SPUT_VOLATILE: /* 0xe6 */
+/* File: armv5te/OP_SPUT_VOLATILE.S */
+/* File: armv5te/OP_SPUT.S */
+ /*
+ * General 32-bit SPUT handler.
+ *
+ * for: sput, sput-object, sput-boolean, sput-byte, sput-char, sput-short
+ */
+ /* op vAA, field@BBBB */
+ ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex
+ FETCH(r1, 1) @ r1<- field ref BBBB
+ ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
+ ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr
+ cmp r0, #0 @ is resolved entry null?
+ beq .LOP_SPUT_VOLATILE_resolve @ yes, do resolve
+.LOP_SPUT_VOLATILE_finish: @ field ptr in r0
+ mov r2, rINST, lsr #8 @ r2<- AA
+ FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
+ GET_VREG(r1, r2) @ r1<- fp[AA]
+ GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB 1 @ releasing store
+ str r1, [r0, #offStaticField_value] @ field<- vAA
+ GOTO_OPCODE(ip) @ jump to next instruction
/* ------------------------------ */
.balign 64
-.L_OP_UNUSED_E7: /* 0xe7 */
-/* File: armv5te/OP_UNUSED_E7.S */
-/* File: armv5te/unused.S */
- bl common_abort
+.L_OP_IGET_OBJECT_VOLATILE: /* 0xe7 */
+/* File: armv5te/OP_IGET_OBJECT_VOLATILE.S */
+/* File: armv5te/OP_IGET.S */
+ /*
+ * General 32-bit instance field get.
+ *
+ * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
+ */
+ /* op vA, vB, field@CCCC */
+ mov r0, rINST, lsr #12 @ r0<- B
+ ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex
+ FETCH(r1, 1) @ r1<- field ref CCCC
+ ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
+ GET_VREG(r9, r0) @ r9<- fp[B], the object pointer
+ ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr
+ cmp r0, #0 @ is resolved entry null?
+ bne .LOP_IGET_OBJECT_VOLATILE_finish @ no, already resolved
+8: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method
+ EXPORT_PC() @ resolve() could throw
+ ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz
+ bl dvmResolveInstField @ r0<- resolved InstField ptr
+ cmp r0, #0
+ bne .LOP_IGET_OBJECT_VOLATILE_finish
+ b common_exceptionThrown
/* ------------------------------ */
@@ -7500,26 +7629,84 @@ dalvik_inst:
/* ------------------------------ */
.balign 64
-.L_OP_UNUSED_FC: /* 0xfc */
-/* File: armv5te/OP_UNUSED_FC.S */
-/* File: armv5te/unused.S */
- bl common_abort
+.L_OP_IPUT_OBJECT_VOLATILE: /* 0xfc */
+/* File: armv5te/OP_IPUT_OBJECT_VOLATILE.S */
+/* File: armv5te/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 */
+ mov r0, rINST, lsr #12 @ r0<- B
+ ldr r3, [rGLUE, #offGlue_methodClassDex] @ r3<- DvmDex
+ FETCH(r1, 1) @ r1<- field ref CCCC
+ ldr r2, [r3, #offDvmDex_pResFields] @ r2<- pDvmDex->pResFields
+ GET_VREG(r9, r0) @ r9<- fp[B], the object pointer
+ ldr r0, [r2, r1, lsl #2] @ r0<- resolved InstField ptr
+ cmp r0, #0 @ is resolved entry null?
+ bne .LOP_IPUT_OBJECT_VOLATILE_finish @ no, already resolved
+8: ldr r2, [rGLUE, #offGlue_method] @ r2<- current method
+ EXPORT_PC() @ resolve() could throw
+ ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz
+ bl dvmResolveInstField @ r0<- resolved InstField ptr
+ cmp r0, #0 @ success?
+ bne .LOP_IPUT_OBJECT_VOLATILE_finish @ yes, finish up
+ b common_exceptionThrown
/* ------------------------------ */
.balign 64
-.L_OP_UNUSED_FD: /* 0xfd */
-/* File: armv5te/OP_UNUSED_FD.S */
-/* File: armv5te/unused.S */
- bl common_abort
+.L_OP_SGET_OBJECT_VOLATILE: /* 0xfd */
+/* File: armv5te/OP_SGET_OBJECT_VOLATILE.S */
+/* File: armv5te/OP_SGET.S */
+ /*
+ * General 32-bit SGET handler.
+ *
+ * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
+ */
+ /* op vAA, field@BBBB */
+ ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex
+ FETCH(r1, 1) @ r1<- field ref BBBB
+ ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
+ ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr
+ cmp r0, #0 @ is resolved entry null?
+ beq .LOP_SGET_OBJECT_VOLATILE_resolve @ yes, do resolve
+.LOP_SGET_OBJECT_VOLATILE_finish: @ field ptr in r0
+ ldr r1, [r0, #offStaticField_value] @ r1<- field value
+ SMP_DMB 1 @ acquiring load
+ mov r2, rINST, lsr #8 @ r2<- AA
+ FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
+ SET_VREG(r1, r2) @ fp[AA]<- r1
+ GET_INST_OPCODE(ip) @ extract opcode from rINST
+ GOTO_OPCODE(ip) @ jump to next instruction
/* ------------------------------ */
.balign 64
-.L_OP_UNUSED_FE: /* 0xfe */
-/* File: armv5te/OP_UNUSED_FE.S */
-/* File: armv5te/unused.S */
- bl common_abort
+.L_OP_SPUT_OBJECT_VOLATILE: /* 0xfe */
+/* File: armv5te/OP_SPUT_OBJECT_VOLATILE.S */
+/* File: armv5te/OP_SPUT.S */
+ /*
+ * General 32-bit SPUT handler.
+ *
+ * for: sput, sput-object, sput-boolean, sput-byte, sput-char, sput-short
+ */
+ /* op vAA, field@BBBB */
+ ldr r2, [rGLUE, #offGlue_methodClassDex] @ r2<- DvmDex
+ FETCH(r1, 1) @ r1<- field ref BBBB
+ ldr r2, [r2, #offDvmDex_pResFields] @ r2<- dvmDex->pResFields
+ ldr r0, [r2, r1, lsl #2] @ r0<- resolved StaticField ptr
+ cmp r0, #0 @ is resolved entry null?
+ beq .LOP_SPUT_OBJECT_VOLATILE_resolve @ yes, do resolve
+.LOP_SPUT_OBJECT_VOLATILE_finish: @ field ptr in r0
+ mov r2, rINST, lsr #8 @ r2<- AA
+ FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
+ GET_VREG(r1, r2) @ r1<- fp[AA]
+ GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB 1 @ releasing store
+ str r1, [r0, #offStaticField_value] @ field<- vAA
+ GOTO_OPCODE(ip) @ jump to next instruction
/* ------------------------------ */
@@ -8073,6 +8260,7 @@ dvmAsmSisterStart:
ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field
beq common_errNullObject @ object was null
ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits)
+ SMP_DMB 0 @ acquiring load
mov r2, rINST, lsr #8 @ r2<- A+
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
and r2, r2, #15 @ r2<- A
@@ -8093,6 +8281,7 @@ dvmAsmSisterStart:
ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field
beq common_errNullObject @ object was null
ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits)
+ SMP_DMB 0 @ acquiring load
mov r2, rINST, lsr #8 @ r2<- A+
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
and r2, r2, #15 @ r2<- A
@@ -8113,6 +8302,7 @@ dvmAsmSisterStart:
ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field
beq common_errNullObject @ object was null
ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits)
+ SMP_DMB 0 @ acquiring load
mov r2, rINST, lsr #8 @ r2<- A+
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
and r2, r2, #15 @ r2<- A
@@ -8133,6 +8323,7 @@ dvmAsmSisterStart:
ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field
beq common_errNullObject @ object was null
ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits)
+ SMP_DMB 0 @ acquiring load
mov r2, rINST, lsr #8 @ r2<- A+
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
and r2, r2, #15 @ r2<- A
@@ -8153,6 +8344,7 @@ dvmAsmSisterStart:
ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field
beq common_errNullObject @ object was null
ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits)
+ SMP_DMB 0 @ acquiring load
mov r2, rINST, lsr #8 @ r2<- A+
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
and r2, r2, #15 @ r2<- A
@@ -8215,6 +8407,7 @@ dvmAsmSisterStart:
beq common_errNullObject @ object was null
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB 0 @ releasing store
str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0
GOTO_OPCODE(ip) @ jump to next instruction
@@ -8235,6 +8428,7 @@ dvmAsmSisterStart:
beq common_errNullObject @ object was null
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB 0 @ releasing store
str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0
GOTO_OPCODE(ip) @ jump to next instruction
@@ -8255,6 +8449,7 @@ dvmAsmSisterStart:
beq common_errNullObject @ object was null
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB 0 @ releasing store
str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0
GOTO_OPCODE(ip) @ jump to next instruction
@@ -8275,6 +8470,7 @@ dvmAsmSisterStart:
beq common_errNullObject @ object was null
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB 0 @ releasing store
str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0
GOTO_OPCODE(ip) @ jump to next instruction
@@ -8295,6 +8491,7 @@ dvmAsmSisterStart:
beq common_errNullObject @ object was null
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB 0 @ releasing store
str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0
GOTO_OPCODE(ip) @ jump to next instruction
@@ -8789,6 +8986,99 @@ d2l_doconv:
stmia r9, {r0-r1} @ vAA/vAA+1<- r0/r1
GOTO_OPCODE(ip) @ jump to next instruction
+/* continuation for OP_IGET_VOLATILE */
+
+ /*
+ * Currently:
+ * r0 holds resolved field
+ * r9 holds object
+ */
+.LOP_IGET_VOLATILE_finish:
+ @bl common_squeak0
+ cmp r9, #0 @ check object for null
+ ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field
+ beq common_errNullObject @ object was null
+ ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits)
+ SMP_DMB 1 @ acquiring load
+ mov r2, rINST, lsr #8 @ r2<- A+
+ FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
+ and r2, r2, #15 @ r2<- A
+ GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SET_VREG(r0, r2) @ fp[A]<- r0
+ GOTO_OPCODE(ip) @ jump to next instruction
+
+/* continuation for OP_IPUT_VOLATILE */
+
+ /*
+ * Currently:
+ * r0 holds resolved field
+ * r9 holds object
+ */
+.LOP_IPUT_VOLATILE_finish:
+ @bl common_squeak0
+ mov r1, rINST, lsr #8 @ r1<- A+
+ ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field
+ and r1, r1, #15 @ r1<- A
+ cmp r9, #0 @ check object for null
+ GET_VREG(r0, r1) @ r0<- fp[A]
+ beq common_errNullObject @ object was null
+ FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
+ GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB 1 @ releasing store
+ str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0
+ GOTO_OPCODE(ip) @ jump to next instruction
+
+/* continuation for OP_SGET_VOLATILE */
+
+ /*
+ * Continuation if the field has not yet been resolved.
+ * r1: BBBB field ref
+ */
+.LOP_SGET_VOLATILE_resolve:
+ ldr r2, [rGLUE, #offGlue_method] @ r2<- current method
+ EXPORT_PC() @ resolve() could throw, so export now
+ ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz
+ bl dvmResolveStaticField @ r0<- resolved StaticField ptr
+ cmp r0, #0 @ success?
+ bne .LOP_SGET_VOLATILE_finish @ yes, finish
+ b common_exceptionThrown @ no, handle exception
+
+/* continuation for OP_SPUT_VOLATILE */
+
+ /*
+ * Continuation if the field has not yet been resolved.
+ * r1: BBBB field ref
+ */
+.LOP_SPUT_VOLATILE_resolve:
+ ldr r2, [rGLUE, #offGlue_method] @ r2<- current method
+ EXPORT_PC() @ resolve() could throw, so export now
+ ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz
+ bl dvmResolveStaticField @ r0<- resolved StaticField ptr
+ cmp r0, #0 @ success?
+ bne .LOP_SPUT_VOLATILE_finish @ yes, finish
+ b common_exceptionThrown @ no, handle exception
+
+/* continuation for OP_IGET_OBJECT_VOLATILE */
+
+ /*
+ * Currently:
+ * r0 holds resolved field
+ * r9 holds object
+ */
+.LOP_IGET_OBJECT_VOLATILE_finish:
+ @bl common_squeak0
+ cmp r9, #0 @ check object for null
+ ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field
+ beq common_errNullObject @ object was null
+ ldr r0, [r9, r3] @ r0<- obj.field (8/16/32 bits)
+ SMP_DMB 1 @ acquiring load
+ mov r2, rINST, lsr #8 @ r2<- A+
+ FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
+ and r2, r2, #15 @ r2<- A
+ GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SET_VREG(r0, r2) @ fp[A]<- r0
+ GOTO_OPCODE(ip) @ jump to next instruction
+
/* continuation for OP_IGET_WIDE_VOLATILE */
/*
@@ -8800,7 +9090,7 @@ d2l_doconv:
cmp r9, #0 @ check object for null
ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field
beq common_errNullObject @ object was null
- .if 1
+ .if 1
add r0, r9, r3 @ r0<- address of field
bl dvmQuasiAtomicRead64 @ r0/r1<- contents of field
.else
@@ -8831,7 +9121,7 @@ d2l_doconv:
FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
ldmia r2, {r0-r1} @ r0/r1<- fp[A]
GET_INST_OPCODE(r10) @ extract opcode from rINST
- .if 1
+ .if 1
add r2, r9, r3 @ r2<- target address
bl dvmQuasiAtomicSwap64 @ stores r0/r1 into addr r2
.else
@@ -8939,6 +9229,57 @@ d2l_doconv:
.LOP_EXECUTE_INLINE_RANGE_table:
.word gDvmInlineOpsTable
+/* continuation for OP_IPUT_OBJECT_VOLATILE */
+
+ /*
+ * Currently:
+ * r0 holds resolved field
+ * r9 holds object
+ */
+.LOP_IPUT_OBJECT_VOLATILE_finish:
+ @bl common_squeak0
+ mov r1, rINST, lsr #8 @ r1<- A+
+ ldr r3, [r0, #offInstField_byteOffset] @ r3<- byte offset of field
+ and r1, r1, #15 @ r1<- A
+ cmp r9, #0 @ check object for null
+ GET_VREG(r0, r1) @ r0<- fp[A]
+ beq common_errNullObject @ object was null
+ FETCH_ADVANCE_INST(2) @ advance rPC, load rINST
+ GET_INST_OPCODE(ip) @ extract opcode from rINST
+ SMP_DMB 1 @ releasing store
+ str r0, [r9, r3] @ obj.field (8/16/32 bits)<- r0
+ GOTO_OPCODE(ip) @ jump to next instruction
+
+/* continuation for OP_SGET_OBJECT_VOLATILE */
+
+ /*
+ * Continuation if the field has not yet been resolved.
+ * r1: BBBB field ref
+ */
+.LOP_SGET_OBJECT_VOLATILE_resolve:
+ ldr r2, [rGLUE, #offGlue_method] @ r2<- current method
+ EXPORT_PC() @ resolve() could throw, so export now
+ ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz
+ bl dvmResolveStaticField @ r0<- resolved StaticField ptr
+ cmp r0, #0 @ success?
+ bne .LOP_SGET_OBJECT_VOLATILE_finish @ yes, finish
+ b common_exceptionThrown @ no, handle exception
+
+/* continuation for OP_SPUT_OBJECT_VOLATILE */
+
+ /*
+ * Continuation if the field has not yet been resolved.
+ * r1: BBBB field ref
+ */
+.LOP_SPUT_OBJECT_VOLATILE_resolve:
+ ldr r2, [rGLUE, #offGlue_method] @ r2<- current method
+ EXPORT_PC() @ resolve() could throw, so export now
+ ldr r0, [r2, #offMethod_clazz] @ r0<- method->clazz
+ bl dvmResolveStaticField @ r0<- resolved StaticField ptr
+ cmp r0, #0 @ success?
+ bne .LOP_SPUT_OBJECT_VOLATILE_finish @ yes, finish
+ b common_exceptionThrown @ no, handle exception
+
.size dvmAsmSisterStart, .-dvmAsmSisterStart
.global dvmAsmSisterEnd
dvmAsmSisterEnd:
diff --git a/vm/mterp/out/InterpAsm-x86-atom.S b/vm/mterp/out/InterpAsm-x86-atom.S
index 8f8cb0fa5..d259f6e6e 100644
--- a/vm/mterp/out/InterpAsm-x86-atom.S
+++ b/vm/mterp/out/InterpAsm-x86-atom.S
@@ -14281,8 +14281,7 @@ OP_IF_LEZ_2f:
/* ------------------------------ */
.balign 64
-.L_OP_UNUSED_E3: /* 0xe3 */
-/* File: x86-atom/OP_UNUSED_E3.S */
+.L_OP_IGET_VOLATILE: /* 0xe3 */
/* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -14299,46 +14298,18 @@ OP_IF_LEZ_2f:
*/
/*
- * File: OP_UNUSED_E3.S
- */
-
-/* File: x86-atom/unused.S */
- /* Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
- /*
- * File: unused.S
- *
- * Code: Common code for unused bytecodes. Uses no subtitutions.
- *
- * For: all unused bytecodes
- *
- * Description: aborts if executed.
- *
- * Format: ØØ|op (10x)
- *
- * Syntax: op
+ * File: stub.S
*/
- call common_abort
-
-
+ SAVE_PC_FP_TO_GLUE %edx # save program counter and frame pointer
+ pushl rGLUE # push parameter glue
+ call dvmMterp_OP_IGET_VOLATILE # call c-based implementation
+ lea 4(%esp), %esp
+ LOAD_PC_FP_FROM_GLUE # restore program counter and frame pointer
+ FINISH_A # jump to next instruction
/* ------------------------------ */
.balign 64
-.L_OP_UNUSED_E4: /* 0xe4 */
-/* File: x86-atom/OP_UNUSED_E4.S */
+.L_OP_IPUT_VOLATILE: /* 0xe4 */
/* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -14355,46 +14326,18 @@ OP_IF_LEZ_2f:
*/
/*
- * File: OP_UNUSED_E4.S
- */
-
-/* File: x86-atom/unused.S */
- /* Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
- /*
- * File: unused.S
- *
- * Code: Common code for unused bytecodes. Uses no subtitutions.
- *
- * For: all unused bytecodes
- *
- * Description: aborts if executed.
- *
- * Format: ØØ|op (10x)
- *
- * Syntax: op
+ * File: stub.S
*/
- call common_abort
-
-
+ SAVE_PC_FP_TO_GLUE %edx # save program counter and frame pointer
+ pushl rGLUE # push parameter glue
+ call dvmMterp_OP_IPUT_VOLATILE # call c-based implementation
+ lea 4(%esp), %esp
+ LOAD_PC_FP_FROM_GLUE # restore program counter and frame pointer
+ FINISH_A # jump to next instruction
/* ------------------------------ */
.balign 64
-.L_OP_UNUSED_E5: /* 0xe5 */
-/* File: x86-atom/OP_UNUSED_E5.S */
+.L_OP_SGET_VOLATILE: /* 0xe5 */
/* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -14411,46 +14354,18 @@ OP_IF_LEZ_2f:
*/
/*
- * File: OP_UNUSED_E5.S
- */
-
-/* File: x86-atom/unused.S */
- /* Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
- /*
- * File: unused.S
- *
- * Code: Common code for unused bytecodes. Uses no subtitutions.
- *
- * For: all unused bytecodes
- *
- * Description: aborts if executed.
- *
- * Format: ØØ|op (10x)
- *
- * Syntax: op
+ * File: stub.S
*/
- call common_abort
-
-
+ SAVE_PC_FP_TO_GLUE %edx # save program counter and frame pointer
+ pushl rGLUE # push parameter glue
+ call dvmMterp_OP_SGET_VOLATILE # call c-based implementation
+ lea 4(%esp), %esp
+ LOAD_PC_FP_FROM_GLUE # restore program counter and frame pointer
+ FINISH_A # jump to next instruction
/* ------------------------------ */
.balign 64
-.L_OP_UNUSED_E6: /* 0xe6 */
-/* File: x86-atom/OP_UNUSED_E6.S */
+.L_OP_SPUT_VOLATILE: /* 0xe6 */
/* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -14467,46 +14382,18 @@ OP_IF_LEZ_2f:
*/
/*
- * File: OP_UNUSED_E6.S
- */
-
-/* File: x86-atom/unused.S */
- /* Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
- /*
- * File: unused.S
- *
- * Code: Common code for unused bytecodes. Uses no subtitutions.
- *
- * For: all unused bytecodes
- *
- * Description: aborts if executed.
- *
- * Format: ØØ|op (10x)
- *
- * Syntax: op
+ * File: stub.S
*/
- call common_abort
-
-
+ SAVE_PC_FP_TO_GLUE %edx # save program counter and frame pointer
+ pushl rGLUE # push parameter glue
+ call dvmMterp_OP_SPUT_VOLATILE # call c-based implementation
+ lea 4(%esp), %esp
+ LOAD_PC_FP_FROM_GLUE # restore program counter and frame pointer
+ FINISH_A # jump to next instruction
/* ------------------------------ */
.balign 64
-.L_OP_UNUSED_E7: /* 0xe7 */
-/* File: x86-atom/OP_UNUSED_E7.S */
+.L_OP_IGET_OBJECT_VOLATILE: /* 0xe7 */
/* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -14523,42 +14410,15 @@ OP_IF_LEZ_2f:
*/
/*
- * File: OP_UNUSED_E7.S
- */
-
-/* File: x86-atom/unused.S */
- /* Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
- /*
- * File: unused.S
- *
- * Code: Common code for unused bytecodes. Uses no subtitutions.
- *
- * For: all unused bytecodes
- *
- * Description: aborts if executed.
- *
- * Format: ØØ|op (10x)
- *
- * Syntax: op
+ * File: stub.S
*/
- call common_abort
-
-
+ SAVE_PC_FP_TO_GLUE %edx # save program counter and frame pointer
+ pushl rGLUE # push parameter glue
+ call dvmMterp_OP_IGET_OBJECT_VOLATILE # call c-based implementation
+ lea 4(%esp), %esp
+ LOAD_PC_FP_FROM_GLUE # restore program counter and frame pointer
+ FINISH_A # jump to next instruction
/* ------------------------------ */
.balign 64
.L_OP_IGET_WIDE_VOLATILE: /* 0xe8 */
@@ -15415,8 +15275,7 @@ OP_IF_LEZ_2f:
/* ------------------------------ */
.balign 64
-.L_OP_UNUSED_FC: /* 0xfc */
-/* File: x86-atom/OP_UNUSED_FC.S */
+.L_OP_IPUT_OBJECT_VOLATILE: /* 0xfc */
/* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -15433,46 +15292,18 @@ OP_IF_LEZ_2f:
*/
/*
- * File: OP_UNUSED_FC.S
- */
-
-/* File: x86-atom/unused.S */
- /* Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
- /*
- * File: unused.S
- *
- * Code: Common code for unused bytecodes. Uses no subtitutions.
- *
- * For: all unused bytecodes
- *
- * Description: aborts if executed.
- *
- * Format: ØØ|op (10x)
- *
- * Syntax: op
+ * File: stub.S
*/
- call common_abort
-
-
+ SAVE_PC_FP_TO_GLUE %edx # save program counter and frame pointer
+ pushl rGLUE # push parameter glue
+ call dvmMterp_OP_IPUT_OBJECT_VOLATILE # call c-based implementation
+ lea 4(%esp), %esp
+ LOAD_PC_FP_FROM_GLUE # restore program counter and frame pointer
+ FINISH_A # jump to next instruction
/* ------------------------------ */
.balign 64
-.L_OP_UNUSED_FD: /* 0xfd */
-/* File: x86-atom/OP_UNUSED_FD.S */
+.L_OP_SGET_OBJECT_VOLATILE: /* 0xfd */
/* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -15489,46 +15320,18 @@ OP_IF_LEZ_2f:
*/
/*
- * File: OP_UNUSED_FD.S
- */
-
-/* File: x86-atom/unused.S */
- /* Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
- /*
- * File: unused.S
- *
- * Code: Common code for unused bytecodes. Uses no subtitutions.
- *
- * For: all unused bytecodes
- *
- * Description: aborts if executed.
- *
- * Format: ØØ|op (10x)
- *
- * Syntax: op
+ * File: stub.S
*/
- call common_abort
-
-
+ SAVE_PC_FP_TO_GLUE %edx # save program counter and frame pointer
+ pushl rGLUE # push parameter glue
+ call dvmMterp_OP_SGET_OBJECT_VOLATILE # call c-based implementation
+ lea 4(%esp), %esp
+ LOAD_PC_FP_FROM_GLUE # restore program counter and frame pointer
+ FINISH_A # jump to next instruction
/* ------------------------------ */
.balign 64
-.L_OP_UNUSED_FE: /* 0xfe */
-/* File: x86-atom/OP_UNUSED_FE.S */
+.L_OP_SPUT_OBJECT_VOLATILE: /* 0xfe */
/* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -15545,42 +15348,15 @@ OP_IF_LEZ_2f:
*/
/*
- * File: OP_UNUSED_FE.S
- */
-
-/* File: x86-atom/unused.S */
- /* Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
- /*
- * File: unused.S
- *
- * Code: Common code for unused bytecodes. Uses no subtitutions.
- *
- * For: all unused bytecodes
- *
- * Description: aborts if executed.
- *
- * Format: ØØ|op (10x)
- *
- * Syntax: op
+ * File: stub.S
*/
- call common_abort
-
-
+ SAVE_PC_FP_TO_GLUE %edx # save program counter and frame pointer
+ pushl rGLUE # push parameter glue
+ call dvmMterp_OP_SPUT_OBJECT_VOLATILE # call c-based implementation
+ lea 4(%esp), %esp
+ LOAD_PC_FP_FROM_GLUE # restore program counter and frame pointer
+ FINISH_A # jump to next instruction
/* ------------------------------ */
.balign 64
.L_OP_UNUSED_FF: /* 0xff */
diff --git a/vm/mterp/out/InterpAsm-x86.S b/vm/mterp/out/InterpAsm-x86.S
index 8168c598a..914b1d170 100644
--- a/vm/mterp/out/InterpAsm-x86.S
+++ b/vm/mterp/out/InterpAsm-x86.S
@@ -5683,44 +5683,74 @@ dvmAsmInstructionStart = .L_OP_NOP
/* ------------------------------ */
.balign 64
-.L_OP_UNUSED_E3: /* 0xe3 */
-/* File: x86/OP_UNUSED_E3.S */
-/* File: x86/unused.S */
- jmp common_abort
-
-
+.L_OP_IGET_VOLATILE: /* 0xe3 */
+ /* (stub) */
+ GET_GLUE(%ecx)
+ SAVE_PC_TO_GLUE(%ecx) # only need to export these two
+ SAVE_FP_TO_GLUE(%ecx) # only need to export these two
+ movl %ecx,OUT_ARG0(%esp) # glue is first arg to function
+ call dvmMterp_OP_IGET_VOLATILE # do the real work
+ GET_GLUE(%ecx)
+ LOAD_PC_FROM_GLUE(%ecx) # retrieve updated values
+ LOAD_FP_FROM_GLUE(%ecx) # retrieve updated values
+ FETCH_INST()
+ GOTO_NEXT
/* ------------------------------ */
.balign 64
-.L_OP_UNUSED_E4: /* 0xe4 */
-/* File: x86/OP_UNUSED_E4.S */
-/* File: x86/unused.S */
- jmp common_abort
-
-
+.L_OP_IPUT_VOLATILE: /* 0xe4 */
+ /* (stub) */
+ GET_GLUE(%ecx)
+ SAVE_PC_TO_GLUE(%ecx) # only need to export these two
+ SAVE_FP_TO_GLUE(%ecx) # only need to export these two
+ movl %ecx,OUT_ARG0(%esp) # glue is first arg to function
+ call dvmMterp_OP_IPUT_VOLATILE # do the real work
+ GET_GLUE(%ecx)
+ LOAD_PC_FROM_GLUE(%ecx) # retrieve updated values
+ LOAD_FP_FROM_GLUE(%ecx) # retrieve updated values
+ FETCH_INST()
+ GOTO_NEXT
/* ------------------------------ */
.balign 64
-.L_OP_UNUSED_E5: /* 0xe5 */
-/* File: x86/OP_UNUSED_E5.S */
-/* File: x86/unused.S */
- jmp common_abort
-
-
+.L_OP_SGET_VOLATILE: /* 0xe5 */
+ /* (stub) */
+ GET_GLUE(%ecx)
+ SAVE_PC_TO_GLUE(%ecx) # only need to export these two
+ SAVE_FP_TO_GLUE(%ecx) # only need to export these two
+ movl %ecx,OUT_ARG0(%esp) # glue is first arg to function
+ call dvmMterp_OP_SGET_VOLATILE # do the real work
+ GET_GLUE(%ecx)
+ LOAD_PC_FROM_GLUE(%ecx) # retrieve updated values
+ LOAD_FP_FROM_GLUE(%ecx) # retrieve updated values
+ FETCH_INST()
+ GOTO_NEXT
/* ------------------------------ */
.balign 64
-.L_OP_UNUSED_E6: /* 0xe6 */
-/* File: x86/OP_UNUSED_E6.S */
-/* File: x86/unused.S */
- jmp common_abort
-
-
+.L_OP_SPUT_VOLATILE: /* 0xe6 */
+ /* (stub) */
+ GET_GLUE(%ecx)
+ SAVE_PC_TO_GLUE(%ecx) # only need to export these two
+ SAVE_FP_TO_GLUE(%ecx) # only need to export these two
+ movl %ecx,OUT_ARG0(%esp) # glue is first arg to function
+ call dvmMterp_OP_SPUT_VOLATILE # do the real work
+ GET_GLUE(%ecx)
+ LOAD_PC_FROM_GLUE(%ecx) # retrieve updated values
+ LOAD_FP_FROM_GLUE(%ecx) # retrieve updated values
+ FETCH_INST()
+ GOTO_NEXT
/* ------------------------------ */
.balign 64
-.L_OP_UNUSED_E7: /* 0xe7 */
-/* File: x86/OP_UNUSED_E7.S */
-/* File: x86/unused.S */
- jmp common_abort
-
-
+.L_OP_IGET_OBJECT_VOLATILE: /* 0xe7 */
+ /* (stub) */
+ GET_GLUE(%ecx)
+ SAVE_PC_TO_GLUE(%ecx) # only need to export these two
+ SAVE_FP_TO_GLUE(%ecx) # only need to export these two
+ movl %ecx,OUT_ARG0(%esp) # glue is first arg to function
+ call dvmMterp_OP_IGET_OBJECT_VOLATILE # do the real work
+ GET_GLUE(%ecx)
+ LOAD_PC_FROM_GLUE(%ecx) # retrieve updated values
+ LOAD_FP_FROM_GLUE(%ecx) # retrieve updated values
+ FETCH_INST()
+ GOTO_NEXT
/* ------------------------------ */
.balign 64
.L_OP_IGET_WIDE_VOLATILE: /* 0xe8 */
@@ -6111,28 +6141,46 @@ dvmAsmInstructionStart = .L_OP_NOP
/* ------------------------------ */
.balign 64
-.L_OP_UNUSED_FC: /* 0xfc */
-/* File: x86/OP_UNUSED_FC.S */
-/* File: x86/unused.S */
- jmp common_abort
-
-
+.L_OP_IPUT_OBJECT_VOLATILE: /* 0xfc */
+ /* (stub) */
+ GET_GLUE(%ecx)
+ SAVE_PC_TO_GLUE(%ecx) # only need to export these two
+ SAVE_FP_TO_GLUE(%ecx) # only need to export these two
+ movl %ecx,OUT_ARG0(%esp) # glue is first arg to function
+ call dvmMterp_OP_IPUT_OBJECT_VOLATILE # do the real work
+ GET_GLUE(%ecx)
+ LOAD_PC_FROM_GLUE(%ecx) # retrieve updated values
+ LOAD_FP_FROM_GLUE(%ecx) # retrieve updated values
+ FETCH_INST()
+ GOTO_NEXT
/* ------------------------------ */
.balign 64
-.L_OP_UNUSED_FD: /* 0xfd */
-/* File: x86/OP_UNUSED_FD.S */
-/* File: x86/unused.S */
- jmp common_abort
-
-
+.L_OP_SGET_OBJECT_VOLATILE: /* 0xfd */
+ /* (stub) */
+ GET_GLUE(%ecx)
+ SAVE_PC_TO_GLUE(%ecx) # only need to export these two
+ SAVE_FP_TO_GLUE(%ecx) # only need to export these two
+ movl %ecx,OUT_ARG0(%esp) # glue is first arg to function
+ call dvmMterp_OP_SGET_OBJECT_VOLATILE # do the real work
+ GET_GLUE(%ecx)
+ LOAD_PC_FROM_GLUE(%ecx) # retrieve updated values
+ LOAD_FP_FROM_GLUE(%ecx) # retrieve updated values
+ FETCH_INST()
+ GOTO_NEXT
/* ------------------------------ */
.balign 64
-.L_OP_UNUSED_FE: /* 0xfe */
-/* File: x86/OP_UNUSED_FE.S */
-/* File: x86/unused.S */
- jmp common_abort
-
-
+.L_OP_SPUT_OBJECT_VOLATILE: /* 0xfe */
+ /* (stub) */
+ GET_GLUE(%ecx)
+ SAVE_PC_TO_GLUE(%ecx) # only need to export these two
+ SAVE_FP_TO_GLUE(%ecx) # only need to export these two
+ movl %ecx,OUT_ARG0(%esp) # glue is first arg to function
+ call dvmMterp_OP_SPUT_OBJECT_VOLATILE # do the real work
+ GET_GLUE(%ecx)
+ LOAD_PC_FROM_GLUE(%ecx) # retrieve updated values
+ LOAD_FP_FROM_GLUE(%ecx) # retrieve updated values
+ FETCH_INST()
+ GOTO_NEXT
/* ------------------------------ */
.balign 64
.L_OP_UNUSED_FF: /* 0xff */
diff --git a/vm/mterp/out/InterpC-allstubs.c b/vm/mterp/out/InterpC-allstubs.c
index 2a366f690..6a50b6477 100644
--- a/vm/mterp/out/InterpC-allstubs.c
+++ b/vm/mterp/out/InterpC-allstubs.c
@@ -2779,24 +2779,24 @@ OP_END
HANDLE_OP_SHX_INT_LIT8(OP_USHR_INT_LIT8, "ushr", (u4), >>)
OP_END
-/* File: c/OP_UNUSED_E3.c */
-HANDLE_OPCODE(OP_UNUSED_E3)
+/* File: c/OP_IGET_VOLATILE.c */
+HANDLE_IGET_X(OP_IGET_VOLATILE, "-volatile", IntVolatile, )
OP_END
-/* File: c/OP_UNUSED_E4.c */
-HANDLE_OPCODE(OP_UNUSED_E4)
+/* File: c/OP_IPUT_VOLATILE.c */
+HANDLE_IPUT_X(OP_IPUT_VOLATILE, "-volatile", IntVolatile, )
OP_END
-/* File: c/OP_UNUSED_E5.c */
-HANDLE_OPCODE(OP_UNUSED_E5)
+/* File: c/OP_SGET_VOLATILE.c */
+HANDLE_SGET_X(OP_SGET_VOLATILE, "-volatile", IntVolatile, )
OP_END
-/* File: c/OP_UNUSED_E6.c */
-HANDLE_OPCODE(OP_UNUSED_E6)
+/* File: c/OP_SPUT_VOLATILE.c */
+HANDLE_SPUT_X(OP_SPUT_VOLATILE, "-volatile", IntVolatile, )
OP_END
-/* File: c/OP_UNUSED_E7.c */
-HANDLE_OPCODE(OP_UNUSED_E7)
+/* File: c/OP_IGET_OBJECT_VOLATILE.c */
+HANDLE_IGET_X(OP_IGET_OBJECT_VOLATILE, "-object-volatile", ObjectVolatile, _AS_OBJECT)
OP_END
/* File: c/OP_IGET_WIDE_VOLATILE.c */
@@ -3026,16 +3026,16 @@ HANDLE_OPCODE(OP_INVOKE_SUPER_QUICK_RANGE /*{vCCCC..v(CCCC+AA-1)}, meth@BBBB*/)
GOTO_invoke(invokeSuperQuick, true);
OP_END
-/* File: c/OP_UNUSED_FC.c */
-HANDLE_OPCODE(OP_UNUSED_FC)
+/* File: c/OP_IPUT_OBJECT_VOLATILE.c */
+HANDLE_IPUT_X(OP_IPUT_OBJECT_VOLATILE, "-object-volatile", ObjectVolatile, _AS_OBJECT)
OP_END
-/* File: c/OP_UNUSED_FD.c */
-HANDLE_OPCODE(OP_UNUSED_FD)
+/* File: c/OP_SGET_OBJECT_VOLATILE.c */
+HANDLE_SGET_X(OP_SGET_OBJECT_VOLATILE, "-object-volatile", ObjectVolatile, _AS_OBJECT)
OP_END
-/* File: c/OP_UNUSED_FE.c */
-HANDLE_OPCODE(OP_UNUSED_FE)
+/* File: c/OP_SPUT_OBJECT_VOLATILE.c */
+HANDLE_SPUT_X(OP_SPUT_OBJECT_VOLATILE, "-object-volatile", ObjectVolatile, _AS_OBJECT)
OP_END
/* File: c/OP_UNUSED_FF.c */
diff --git a/vm/mterp/out/InterpC-portdbg.c b/vm/mterp/out/InterpC-portdbg.c
index 2b7f33356..18433f8eb 100644
--- a/vm/mterp/out/InterpC-portdbg.c
+++ b/vm/mterp/out/InterpC-portdbg.c
@@ -3145,24 +3145,24 @@ OP_END
HANDLE_OP_SHX_INT_LIT8(OP_USHR_INT_LIT8, "ushr", (u4), >>)
OP_END
-/* File: c/OP_UNUSED_E3.c */
-HANDLE_OPCODE(OP_UNUSED_E3)
+/* File: c/OP_IGET_VOLATILE.c */
+HANDLE_IGET_X(OP_IGET_VOLATILE, "-volatile", IntVolatile, )
OP_END
-/* File: c/OP_UNUSED_E4.c */
-HANDLE_OPCODE(OP_UNUSED_E4)
+/* File: c/OP_IPUT_VOLATILE.c */
+HANDLE_IPUT_X(OP_IPUT_VOLATILE, "-volatile", IntVolatile, )
OP_END
-/* File: c/OP_UNUSED_E5.c */
-HANDLE_OPCODE(OP_UNUSED_E5)
+/* File: c/OP_SGET_VOLATILE.c */
+HANDLE_SGET_X(OP_SGET_VOLATILE, "-volatile", IntVolatile, )
OP_END
-/* File: c/OP_UNUSED_E6.c */
-HANDLE_OPCODE(OP_UNUSED_E6)
+/* File: c/OP_SPUT_VOLATILE.c */
+HANDLE_SPUT_X(OP_SPUT_VOLATILE, "-volatile", IntVolatile, )
OP_END
-/* File: c/OP_UNUSED_E7.c */
-HANDLE_OPCODE(OP_UNUSED_E7)
+/* File: c/OP_IGET_OBJECT_VOLATILE.c */
+HANDLE_IGET_X(OP_IGET_OBJECT_VOLATILE, "-object-volatile", ObjectVolatile, _AS_OBJECT)
OP_END
/* File: c/OP_IGET_WIDE_VOLATILE.c */
@@ -3392,16 +3392,16 @@ HANDLE_OPCODE(OP_INVOKE_SUPER_QUICK_RANGE /*{vCCCC..v(CCCC+AA-1)}, meth@BBBB*/)
GOTO_invoke(invokeSuperQuick, true);
OP_END
-/* File: c/OP_UNUSED_FC.c */
-HANDLE_OPCODE(OP_UNUSED_FC)
+/* File: c/OP_IPUT_OBJECT_VOLATILE.c */
+HANDLE_IPUT_X(OP_IPUT_OBJECT_VOLATILE, "-object-volatile", ObjectVolatile, _AS_OBJECT)
OP_END
-/* File: c/OP_UNUSED_FD.c */
-HANDLE_OPCODE(OP_UNUSED_FD)
+/* File: c/OP_SGET_OBJECT_VOLATILE.c */
+HANDLE_SGET_X(OP_SGET_OBJECT_VOLATILE, "-object-volatile", ObjectVolatile, _AS_OBJECT)
OP_END
-/* File: c/OP_UNUSED_FE.c */
-HANDLE_OPCODE(OP_UNUSED_FE)
+/* File: c/OP_SPUT_OBJECT_VOLATILE.c */
+HANDLE_SPUT_X(OP_SPUT_OBJECT_VOLATILE, "-object-volatile", ObjectVolatile, _AS_OBJECT)
OP_END
/* File: c/OP_UNUSED_FF.c */
diff --git a/vm/mterp/out/InterpC-portstd.c b/vm/mterp/out/InterpC-portstd.c
index d75dead6a..a4c4b54ae 100644
--- a/vm/mterp/out/InterpC-portstd.c
+++ b/vm/mterp/out/InterpC-portstd.c
@@ -2884,24 +2884,24 @@ OP_END
HANDLE_OP_SHX_INT_LIT8(OP_USHR_INT_LIT8, "ushr", (u4), >>)
OP_END
-/* File: c/OP_UNUSED_E3.c */
-HANDLE_OPCODE(OP_UNUSED_E3)
+/* File: c/OP_IGET_VOLATILE.c */
+HANDLE_IGET_X(OP_IGET_VOLATILE, "-volatile", IntVolatile, )
OP_END
-/* File: c/OP_UNUSED_E4.c */
-HANDLE_OPCODE(OP_UNUSED_E4)
+/* File: c/OP_IPUT_VOLATILE.c */
+HANDLE_IPUT_X(OP_IPUT_VOLATILE, "-volatile", IntVolatile, )
OP_END
-/* File: c/OP_UNUSED_E5.c */
-HANDLE_OPCODE(OP_UNUSED_E5)
+/* File: c/OP_SGET_VOLATILE.c */
+HANDLE_SGET_X(OP_SGET_VOLATILE, "-volatile", IntVolatile, )
OP_END
-/* File: c/OP_UNUSED_E6.c */
-HANDLE_OPCODE(OP_UNUSED_E6)
+/* File: c/OP_SPUT_VOLATILE.c */
+HANDLE_SPUT_X(OP_SPUT_VOLATILE, "-volatile", IntVolatile, )
OP_END
-/* File: c/OP_UNUSED_E7.c */
-HANDLE_OPCODE(OP_UNUSED_E7)
+/* File: c/OP_IGET_OBJECT_VOLATILE.c */
+HANDLE_IGET_X(OP_IGET_OBJECT_VOLATILE, "-object-volatile", ObjectVolatile, _AS_OBJECT)
OP_END
/* File: c/OP_IGET_WIDE_VOLATILE.c */
@@ -3131,16 +3131,16 @@ HANDLE_OPCODE(OP_INVOKE_SUPER_QUICK_RANGE /*{vCCCC..v(CCCC+AA-1)}, meth@BBBB*/)
GOTO_invoke(invokeSuperQuick, true);
OP_END
-/* File: c/OP_UNUSED_FC.c */
-HANDLE_OPCODE(OP_UNUSED_FC)
+/* File: c/OP_IPUT_OBJECT_VOLATILE.c */
+HANDLE_IPUT_X(OP_IPUT_OBJECT_VOLATILE, "-object-volatile", ObjectVolatile, _AS_OBJECT)
OP_END
-/* File: c/OP_UNUSED_FD.c */
-HANDLE_OPCODE(OP_UNUSED_FD)
+/* File: c/OP_SGET_OBJECT_VOLATILE.c */
+HANDLE_SGET_X(OP_SGET_OBJECT_VOLATILE, "-object-volatile", ObjectVolatile, _AS_OBJECT)
OP_END
-/* File: c/OP_UNUSED_FE.c */
-HANDLE_OPCODE(OP_UNUSED_FE)
+/* File: c/OP_SPUT_OBJECT_VOLATILE.c */
+HANDLE_SPUT_X(OP_SPUT_OBJECT_VOLATILE, "-object-volatile", ObjectVolatile, _AS_OBJECT)
OP_END
/* File: c/OP_UNUSED_FF.c */
diff --git a/vm/mterp/out/InterpC-x86-atom.c b/vm/mterp/out/InterpC-x86-atom.c
index 0061a61ec..9d208a350 100644
--- a/vm/mterp/out/InterpC-x86-atom.c
+++ b/vm/mterp/out/InterpC-x86-atom.c
@@ -1201,6 +1201,26 @@ GOTO_TARGET_DECL(exceptionThrown);
} \
FINISH(2);
+/* File: c/OP_IGET_VOLATILE.c */
+HANDLE_IGET_X(OP_IGET_VOLATILE, "-volatile", IntVolatile, )
+OP_END
+
+/* File: c/OP_IPUT_VOLATILE.c */
+HANDLE_IPUT_X(OP_IPUT_VOLATILE, "-volatile", IntVolatile, )
+OP_END
+
+/* File: c/OP_SGET_VOLATILE.c */
+HANDLE_SGET_X(OP_SGET_VOLATILE, "-volatile", IntVolatile, )
+OP_END
+
+/* File: c/OP_SPUT_VOLATILE.c */
+HANDLE_SPUT_X(OP_SPUT_VOLATILE, "-volatile", IntVolatile, )
+OP_END
+
+/* File: c/OP_IGET_OBJECT_VOLATILE.c */
+HANDLE_IGET_X(OP_IGET_OBJECT_VOLATILE, "-object-volatile", ObjectVolatile, _AS_OBJECT)
+OP_END
+
/* File: c/OP_IGET_WIDE_VOLATILE.c */
HANDLE_IGET_X(OP_IGET_WIDE_VOLATILE, "-wide-volatile", LongVolatile, _WIDE)
OP_END
@@ -1293,6 +1313,18 @@ HANDLE_OPCODE(OP_EXECUTE_INLINE_RANGE /*{vCCCC..v(CCCC+AA-1)}, inline@BBBB*/)
FINISH(3);
OP_END
+/* File: c/OP_IPUT_OBJECT_VOLATILE.c */
+HANDLE_IPUT_X(OP_IPUT_OBJECT_VOLATILE, "-object-volatile", ObjectVolatile, _AS_OBJECT)
+OP_END
+
+/* File: c/OP_SGET_OBJECT_VOLATILE.c */
+HANDLE_SGET_X(OP_SGET_OBJECT_VOLATILE, "-object-volatile", ObjectVolatile, _AS_OBJECT)
+OP_END
+
+/* File: c/OP_SPUT_OBJECT_VOLATILE.c */
+HANDLE_SPUT_X(OP_SPUT_OBJECT_VOLATILE, "-object-volatile", ObjectVolatile, _AS_OBJECT)
+OP_END
+
/* File: c/gotoTargets.c */
/*
* C footer. This has some common code shared by the various targets.
diff --git a/vm/mterp/out/InterpC-x86.c b/vm/mterp/out/InterpC-x86.c
index c95ef905e..d9e599e6a 100644
--- a/vm/mterp/out/InterpC-x86.c
+++ b/vm/mterp/out/InterpC-x86.c
@@ -1201,6 +1201,26 @@ GOTO_TARGET_DECL(exceptionThrown);
} \
FINISH(2);
+/* File: c/OP_IGET_VOLATILE.c */
+HANDLE_IGET_X(OP_IGET_VOLATILE, "-volatile", IntVolatile, )
+OP_END
+
+/* File: c/OP_IPUT_VOLATILE.c */
+HANDLE_IPUT_X(OP_IPUT_VOLATILE, "-volatile", IntVolatile, )
+OP_END
+
+/* File: c/OP_SGET_VOLATILE.c */
+HANDLE_SGET_X(OP_SGET_VOLATILE, "-volatile", IntVolatile, )
+OP_END
+
+/* File: c/OP_SPUT_VOLATILE.c */
+HANDLE_SPUT_X(OP_SPUT_VOLATILE, "-volatile", IntVolatile, )
+OP_END
+
+/* File: c/OP_IGET_OBJECT_VOLATILE.c */
+HANDLE_IGET_X(OP_IGET_OBJECT_VOLATILE, "-object-volatile", ObjectVolatile, _AS_OBJECT)
+OP_END
+
/* File: c/OP_IGET_WIDE_VOLATILE.c */
HANDLE_IGET_X(OP_IGET_WIDE_VOLATILE, "-wide-volatile", LongVolatile, _WIDE)
OP_END
@@ -1262,6 +1282,18 @@ HANDLE_OPCODE(OP_EXECUTE_INLINE_RANGE /*{vCCCC..v(CCCC+AA-1)}, inline@BBBB*/)
FINISH(3);
OP_END
+/* File: c/OP_IPUT_OBJECT_VOLATILE.c */
+HANDLE_IPUT_X(OP_IPUT_OBJECT_VOLATILE, "-object-volatile", ObjectVolatile, _AS_OBJECT)
+OP_END
+
+/* File: c/OP_SGET_OBJECT_VOLATILE.c */
+HANDLE_SGET_X(OP_SGET_OBJECT_VOLATILE, "-object-volatile", ObjectVolatile, _AS_OBJECT)
+OP_END
+
+/* File: c/OP_SPUT_OBJECT_VOLATILE.c */
+HANDLE_SPUT_X(OP_SPUT_OBJECT_VOLATILE, "-object-volatile", ObjectVolatile, _AS_OBJECT)
+OP_END
+
/* File: c/gotoTargets.c */
/*
* C footer. This has some common code shared by the various targets.
diff --git a/vm/mterp/x86-atom/TODO.txt b/vm/mterp/x86-atom/TODO.txt
index c49532ebb..5b89db95d 100644
--- a/vm/mterp/x86-atom/TODO.txt
+++ b/vm/mterp/x86-atom/TODO.txt
@@ -7,8 +7,8 @@ Items requiring attention:
skip a memory load when debugger support is completely disabled)
(md) Correct OP_MONITOR_EXIT (need to adjust PC before throw)
+(md) OP_THROW needs to export the PC
(lo) Implement OP_BREAKPOINT
(lo) Implement OP_EXECUTE_INLINE_RANGE
-(lo) Implement OP_*_WIDE_VOLATILE
-(lo) OP_THROW needs to export the PC
+(lo) Implement OP_*_VOLATILE (12 instructions)
diff --git a/vm/oo/Object.h b/vm/oo/Object.h
index 92ec1d64f..041e1e8ef 100644
--- a/vm/oo/Object.h
+++ b/vm/oo/Object.h
@@ -714,9 +714,19 @@ INLINE double dvmGetFieldDouble(const Object* obj, int offset) {
INLINE Object* dvmGetFieldObject(const Object* obj, int offset) {
return ((JValue*)BYTE_OFFSET(obj, offset))->l;
}
+INLINE s4 dvmGetFieldIntVolatile(const Object* obj, int offset) {
+ s4* ptr = &((JValue*)BYTE_OFFSET(obj, offset))->i;
+ return android_atomic_acquire_load(ptr);
+}
+INLINE Object* dvmGetFieldObjectVolatile(const Object* obj, int offset) {
+ void** ptr = &((JValue*)BYTE_OFFSET(obj, offset))->l;
+ return (Object*) android_atomic_acquire_load((int32_t*)ptr);
+}
INLINE s8 dvmGetFieldLongVolatile(const Object* obj, int offset) {
const s8* addr = BYTE_OFFSET(obj, offset);
- return dvmQuasiAtomicRead64((s8*)addr);
+ s8 val = dvmQuasiAtomicRead64(addr);
+ ANDROID_MEMBAR_FULL();
+ return val;
}
INLINE void dvmSetFieldBoolean(Object* obj, int offset, bool val) {
@@ -746,8 +756,17 @@ INLINE void dvmSetFieldDouble(Object* obj, int offset, double val) {
INLINE void dvmSetFieldObject(Object* obj, int offset, Object* val) {
((JValue*)BYTE_OFFSET(obj, offset))->l = val;
}
+INLINE void dvmSetFieldIntVolatile(Object* obj, int offset, s4 val) {
+ s4* ptr = &((JValue*)BYTE_OFFSET(obj, offset))->i;
+ android_atomic_release_store(val, ptr);
+}
+INLINE void dvmSetFieldObjectVolatile(Object* obj, int offset, Object* val) {
+ void** ptr = &((JValue*)BYTE_OFFSET(obj, offset))->l;
+ android_atomic_release_store((int32_t)val, (int32_t*)ptr);
+}
INLINE void dvmSetFieldLongVolatile(Object* obj, int offset, s8 val) {
s8* addr = BYTE_OFFSET(obj, offset);
+ ANDROID_MEMBAR_FULL();
dvmQuasiAtomicSwap64(val, addr);
}
@@ -785,9 +804,19 @@ INLINE double dvmGetStaticFieldDouble(const StaticField* sfield) {
INLINE Object* dvmGetStaticFieldObject(const StaticField* sfield) {
return sfield->value.l;
}
+INLINE s4 dvmGetStaticFieldIntVolatile(const StaticField* sfield) {
+ const s4* ptr = &(sfield->value.i);
+ return android_atomic_acquire_load((s4*)ptr);
+}
+INLINE Object* dvmGetStaticFieldObjectVolatile(const StaticField* sfield) {
+ void* const* ptr = &(sfield->value.l);
+ return (Object*) android_atomic_acquire_load((int32_t*)ptr);
+}
INLINE s8 dvmGetStaticFieldLongVolatile(const StaticField* sfield) {
const s8* addr = &sfield->value.j;
- return dvmQuasiAtomicRead64((s8*)addr);
+ s8 val = dvmQuasiAtomicRead64(addr);
+ ANDROID_MEMBAR_FULL();
+ return val;
}
INLINE void dvmSetStaticFieldBoolean(StaticField* sfield, bool val) {
@@ -817,8 +846,17 @@ INLINE void dvmSetStaticFieldDouble(StaticField* sfield, double val) {
INLINE void dvmSetStaticFieldObject(StaticField* sfield, Object* val) {
sfield->value.l = val;
}
+INLINE void dvmSetStaticFieldIntVolatile(StaticField* sfield, s4 val) {
+ s4* ptr = &(sfield->value.i);
+ android_atomic_release_store(val, ptr);
+}
+INLINE void dvmSetStaticFieldObjectVolatile(StaticField* sfield, Object* val) {
+ void** ptr = &(sfield->value.l);
+ android_atomic_release_store((int32_t)val, (int32_t*)ptr);
+}
INLINE void dvmSetStaticFieldLongVolatile(StaticField* sfield, s8 val) {
s8* addr = &sfield->value.j;
+ ANDROID_MEMBAR_FULL();
dvmQuasiAtomicSwap64(val, addr);
}