[MIPS] Use sync instruction in dvmCompilerGenMemBarrier
Change-Id: Id647a126b0d6b1666c001a87c59a0930762778b2
Signed-off-by: Douglas Leung <douglas@mips.com>
diff --git a/vm/compiler/codegen/mips/ArchUtility.cpp b/vm/compiler/codegen/mips/ArchUtility.cpp
index 1f6d593..47c4c6d 100644
--- a/vm/compiler/codegen/mips/ArchUtility.cpp
+++ b/vm/compiler/codegen/mips/ArchUtility.cpp
@@ -38,6 +38,7 @@
char *bufEnd = &buf[size-1];
const char *fmtEnd = &fmt[strlen(fmt)];
char tbuf[256];
+ const char *name;
char nc;
while (fmt < fmtEnd) {
int operand;
@@ -142,6 +143,32 @@
assert(operand >= 0 && operand < MIPS_REG_COUNT);
strcpy(tbuf, mipsRegName[operand]);
break;
+ case 'B':
+ switch (operand) {
+ case kSY:
+ name = "0/sy";
+ break;
+ case kWMB:
+ name = "4/wmb";
+ break;
+ case kMB:
+ name = "16/mb";
+ break;
+ case kACQUIRE:
+ name = "17/acquire";
+ break;
+ case kRELEASE:
+ name = "18/release";
+ break;
+ case kRMB:
+ name = "19/rmb";
+ break;
+ default:
+ name = "DecodeError";
+ break;
+ }
+ strcpy(tbuf, name);
+ break;
default:
strcpy(tbuf,"DecodeError");
break;
diff --git a/vm/compiler/codegen/mips/Assemble.cpp b/vm/compiler/codegen/mips/Assemble.cpp
index 713bced..36a301c 100644
--- a/vm/compiler/codegen/mips/Assemble.cpp
+++ b/vm/compiler/codegen/mips/Assemble.cpp
@@ -73,6 +73,7 @@
* n -> complimented Thumb2 modified immediate
* M -> Thumb2 16-bit zero-extended immediate
* b -> 4-digit binary
+ * B -> sync option string (SY, WMB, MB, ACQUIRE, RELEASE, RMB)
*
* [!] escape. To insert "!", use "!!"
*/
@@ -294,6 +295,10 @@
kFmtBitBlt, 20, 16, kFmtBitBlt, 15, 0, kFmtBitBlt, 25, 21,
kFmtUnused, -1, -1, IS_TERTIARY_OP | REG_USE02 | IS_STORE,
"sw", "!0r,!1d(!2r)", 2),
+ ENCODING_MAP(kMipsSync, 0x0000000F,
+ kFmtBitBlt, 10, 6, kFmtUnused, -1, -1, kFmtUnused, -1, -1,
+ kFmtUnused, -1, -1, IS_UNARY_OP,
+ "sync", "!0B", 2),
ENCODING_MAP(kMipsXor, 0x00000026,
kFmtBitBlt, 15, 11, kFmtBitBlt, 25, 21, kFmtBitBlt, 20, 16,
kFmtUnused, -1, -1, IS_TERTIARY_OP | REG_DEF0_USE12,
diff --git a/vm/compiler/codegen/mips/CodegenDriver.cpp b/vm/compiler/codegen/mips/CodegenDriver.cpp
index 62a9a4f..273a154 100644
--- a/vm/compiler/codegen/mips/CodegenDriver.cpp
+++ b/vm/compiler/codegen/mips/CodegenDriver.cpp
@@ -428,7 +428,7 @@
size, rlObj.sRegLow);
HEAP_ACCESS_SHADOW(false);
if (isVolatile) {
- dvmCompilerGenMemBarrier(cUnit, 0);
+ dvmCompilerGenMemBarrier(cUnit, kSY);
}
storeValue(cUnit, rlDest, rlResult);
@@ -450,13 +450,13 @@
NULL);/* null object? */
if (isVolatile) {
- dvmCompilerGenMemBarrier(cUnit, 0);
+ dvmCompilerGenMemBarrier(cUnit, kSY);
}
HEAP_ACCESS_SHADOW(true);
storeBaseDisp(cUnit, rlObj.lowReg, fieldOffset, rlSrc.lowReg, size);
HEAP_ACCESS_SHADOW(false);
if (isVolatile) {
- dvmCompilerGenMemBarrier(cUnit, 0);
+ dvmCompilerGenMemBarrier(cUnit, kSY);
}
if (isObject) {
/* NOTE: marking card based on object head */
@@ -1558,7 +1558,7 @@
}
switch (dalvikOpcode) {
case OP_RETURN_VOID_BARRIER:
- dvmCompilerGenMemBarrier(cUnit, 0);
+ dvmCompilerGenMemBarrier(cUnit, kSY);
// Intentional fallthrough
case OP_RETURN_VOID:
genReturnCommon(cUnit,mir);
@@ -1732,7 +1732,7 @@
loadConstant(cUnit, tReg, (int) fieldPtr + valOffset);
if (isVolatile) {
- dvmCompilerGenMemBarrier(cUnit, 0);
+ dvmCompilerGenMemBarrier(cUnit, kSY);
}
HEAP_ACCESS_SHADOW(true);
loadWordDisp(cUnit, tReg, 0, rlResult.lowReg);
@@ -1810,14 +1810,14 @@
loadWordDisp(cUnit, tReg, OFFSETOF_MEMBER(Field, clazz), objHead);
}
if (isVolatile) {
- dvmCompilerGenMemBarrier(cUnit, 0);
+ dvmCompilerGenMemBarrier(cUnit, kSY);
}
HEAP_ACCESS_SHADOW(true);
storeWordDisp(cUnit, tReg, valOffset ,rlSrc.lowReg);
dvmCompilerFreeTemp(cUnit, tReg);
HEAP_ACCESS_SHADOW(false);
if (isVolatile) {
- dvmCompilerGenMemBarrier(cUnit, 0);
+ dvmCompilerGenMemBarrier(cUnit, kSY);
}
if (isSputObject) {
/* NOTE: marking card based sfield->clazz */
diff --git a/vm/compiler/codegen/mips/MipsLIR.h b/vm/compiler/codegen/mips/MipsLIR.h
index fc82da2..de40755 100644
--- a/vm/compiler/codegen/mips/MipsLIR.h
+++ b/vm/compiler/codegen/mips/MipsLIR.h
@@ -457,6 +457,7 @@
kMipsSrlv, /* srlv d,t,s [000000] s[25..21] t[20..16] d[15..11] [00000000110] */
kMipsSubu, /* subu d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100011] */
kMipsSw, /* sw t,o(b) [101011] b[25..21] t[20..16] o[15..0] */
+ kMipsSync, /* sync hint [000000000000000000000] hint[10..6] [001111] */
kMipsXor, /* xor d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100110] */
kMipsXori, /* xori t,s,imm16 [001110] s[25..21] t[20..16] imm16[15..0] */
#ifdef __mips_hard_float
@@ -487,6 +488,24 @@
kMipsLast
} MipsOpCode;
+/* Sync option encodings */
+typedef enum MipsSyncOptions {
+ /*
+ * sync guarantees ordering of Load/Store operations wrt itself
+ *
+ * Older: instruction classes that must be ordered before the sync instruction completes
+ * Younger: instruction classes that must be ordered after the sync instruction completes
+ * Global: instruction classes that must be performed globally when the sync completes
+ */
+ /* Older Younger Global */
+ kSY = 0x00, /* Load,Store Load,Store Load,Store */
+ kWMB = 0x04, /* Store Store */
+ kMB = 0x10, /* Load,Store Load,Store */
+ kACQUIRE = 0x11, /* Load Load,Store */
+ kRELEASE = 0x12, /* Load,Store Store */
+ kRMB = 0x13 /* Load Load */
+} MipsSyncOptions;
+
/* Bit flags describing the behavior of each native opcode */
typedef enum MipsOpFeatureFlags {
kIsBranch = 0,
diff --git a/vm/compiler/codegen/mips/mips/ArchVariant.cpp b/vm/compiler/codegen/mips/mips/ArchVariant.cpp
index d720f85..4362961 100644
--- a/vm/compiler/codegen/mips/mips/ArchVariant.cpp
+++ b/vm/compiler/codegen/mips/mips/ArchVariant.cpp
@@ -105,5 +105,8 @@
void dvmCompilerGenMemBarrier(CompilationUnit *cUnit, int barrierKind)
{
- __asm__ __volatile__ ("" : : : "memory");
+#if ANDROID_SMP != 0
+ MipsLIR *sync = newLIR1(cUnit, kMipsSync, barrierKind);
+ sync->defMask = ENCODE_ALL;
+#endif
}