diff options
Diffstat (limited to 'vm/compiler/codegen/mips')
-rw-r--r-- | vm/compiler/codegen/mips/ArchUtility.cpp | 27 | ||||
-rw-r--r-- | vm/compiler/codegen/mips/Assemble.cpp | 5 | ||||
-rw-r--r-- | vm/compiler/codegen/mips/CodegenDriver.cpp | 14 | ||||
-rw-r--r-- | vm/compiler/codegen/mips/MipsLIR.h | 19 | ||||
-rw-r--r-- | vm/compiler/codegen/mips/mips/ArchVariant.cpp | 5 |
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 } |