summaryrefslogtreecommitdiffstats
path: root/vm/compiler/codegen/mips
diff options
context:
space:
mode:
Diffstat (limited to 'vm/compiler/codegen/mips')
-rw-r--r--vm/compiler/codegen/mips/ArchUtility.cpp27
-rw-r--r--vm/compiler/codegen/mips/Assemble.cpp5
-rw-r--r--vm/compiler/codegen/mips/CodegenDriver.cpp14
-rw-r--r--vm/compiler/codegen/mips/MipsLIR.h19
-rw-r--r--vm/compiler/codegen/mips/mips/ArchVariant.cpp5
5 files changed, 62 insertions, 8 deletions
diff --git a/vm/compiler/codegen/mips/ArchUtility.cpp b/vm/compiler/codegen/mips/ArchUtility.cpp
index 1f6d59376..47c4c6de1 100644
--- a/vm/compiler/codegen/mips/ArchUtility.cpp
+++ b/vm/compiler/codegen/mips/ArchUtility.cpp
@@ -38,6 +38,7 @@ static void buildInsnString(const char *fmt, MipsLIR *lir, char* buf,
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 @@ static void buildInsnString(const char *fmt, MipsLIR *lir, char* buf,
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 713bced68..36a301c9a 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 @@ MipsEncodingMap EncodingMap[kMipsLast] = {
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 62a9a4fb9..273a154e2 100644
--- a/vm/compiler/codegen/mips/CodegenDriver.cpp
+++ b/vm/compiler/codegen/mips/CodegenDriver.cpp
@@ -428,7 +428,7 @@ static void genIGet(CompilationUnit *cUnit, MIR *mir, OpSize size,
size, rlObj.sRegLow);
HEAP_ACCESS_SHADOW(false);
if (isVolatile) {
- dvmCompilerGenMemBarrier(cUnit, 0);
+ dvmCompilerGenMemBarrier(cUnit, kSY);
}
storeValue(cUnit, rlDest, rlResult);
@@ -450,13 +450,13 @@ static void genIPut(CompilationUnit *cUnit, MIR *mir, OpSize size,
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 @@ static bool handleFmt10x(CompilationUnit *cUnit, MIR *mir)
}
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 @@ static bool handleFmt21c_Fmt31c(CompilationUnit *cUnit, MIR *mir)
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 @@ static bool handleFmt21c_Fmt31c(CompilationUnit *cUnit, MIR *mir)
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 fc82da255..de407552d 100644
--- a/vm/compiler/codegen/mips/MipsLIR.h
+++ b/vm/compiler/codegen/mips/MipsLIR.h
@@ -457,6 +457,7 @@ typedef enum MipsOpCode {
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 @@ typedef enum MipsOpCode {
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 10f5da10d..473b88e8b 100644
--- a/vm/compiler/codegen/mips/mips/ArchVariant.cpp
+++ b/vm/compiler/codegen/mips/mips/ArchVariant.cpp
@@ -109,5 +109,8 @@ int dvmCompilerTargetOptHint(int key)
void dvmCompilerGenMemBarrier(CompilationUnit *cUnit, int barrierKind)
{
- __asm__ __volatile__ ("" : : : "memory");
+#if ANDROID_SMP != 0
+ MipsLIR *sync = newLIR1(cUnit, kMipsSync, barrierKind);
+ sync->defMask = ENCODE_ALL;
+#endif
}