summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian Sullivan <briansul@microsoft.com>2017-05-10 13:50:19 -0700
committerGitHub <noreply@github.com>2017-05-10 13:50:19 -0700
commit0b625bfdbb97565b7d489d1d083cfaf4dbd47e0d (patch)
treeb7aacfec06408527af04b57e3d3a433e097294a6
parentc9f469e5fc99a498f46bd2d60fb198b7f7f1c22b (diff)
parent84e39c38feae031c71ed3861a183ec5017783b7a (diff)
downloadcoreclr-0b625bfdbb97565b7d489d1d083cfaf4dbd47e0d.tar.gz
coreclr-0b625bfdbb97565b7d489d1d083cfaf4dbd47e0d.tar.bz2
coreclr-0b625bfdbb97565b7d489d1d083cfaf4dbd47e0d.zip
Merge pull request #11478 from sdmaclea/PR-ARM64-9711
[Arm64] Support GTF_IND_VOLATILE
-rw-r--r--src/jit/codegenarm64.cpp36
-rw-r--r--src/jit/codegenarmarch.cpp25
2 files changed, 61 insertions, 0 deletions
diff --git a/src/jit/codegenarm64.cpp b/src/jit/codegenarm64.cpp
index 88240409e6..6535431c08 100644
--- a/src/jit/codegenarm64.cpp
+++ b/src/jit/codegenarm64.cpp
@@ -2522,6 +2522,12 @@ void CodeGen::genCodeForInitBlkUnroll(GenTreeBlk* initBlkNode)
genConsumeOperands(initBlkNode);
+ if (initBlkNode->gtFlags & GTF_BLK_VOLATILE)
+ {
+ // issue a full memory barrier before volatile an initBlockUnroll operation
+ instGen_MemoryBarrier();
+ }
+
regNumber valReg = initVal->IsIntegralConst(0) ? REG_ZR : initVal->gtRegNum;
assert(!initVal->IsIntegralConst(0) || (valReg == REG_ZR));
@@ -2660,6 +2666,12 @@ void CodeGen::genCodeForCpBlkUnroll(GenTreeBlk* cpBlkNode)
emitter* emit = getEmitter();
+ if (cpBlkNode->gtFlags & GTF_BLK_VOLATILE)
+ {
+ // issue a full memory barrier before & after a volatile CpBlkUnroll operation
+ instGen_MemoryBarrier();
+ }
+
if (source->gtOper == GT_IND)
{
srcAddr = source->gtGetOp1();
@@ -2738,6 +2750,12 @@ void CodeGen::genCodeForCpBlkUnroll(GenTreeBlk* cpBlkNode)
genCodeForStoreOffset(INS_strb, EA_1BYTE, tmpReg, dstAddr, offset);
}
}
+
+ if (cpBlkNode->gtFlags & GTF_BLK_VOLATILE)
+ {
+ // issue a full memory barrier before & after a volatile CpBlkUnroll operation
+ instGen_MemoryBarrier();
+ }
}
// Generate code for CpObj nodes wich copy structs that have interleaved
@@ -2816,6 +2834,12 @@ void CodeGen::genCodeForCpObj(GenTreeObj* cpObjNode)
assert(tmpReg2 != REG_WRITE_BARRIER_SRC_BYREF);
}
+ if (cpObjNode->gtFlags & GTF_BLK_VOLATILE)
+ {
+ // issue a full memory barrier before & after a volatile CpObj operation
+ instGen_MemoryBarrier();
+ }
+
emitter* emit = getEmitter();
BYTE* gcPtrs = cpObjNode->gtGcPtrs;
@@ -2888,6 +2912,12 @@ void CodeGen::genCodeForCpObj(GenTreeObj* cpObjNode)
assert(gcPtrCount == 0);
}
+ if (cpObjNode->gtFlags & GTF_BLK_VOLATILE)
+ {
+ // issue a full memory barrier before & after a volatile CpObj operation
+ instGen_MemoryBarrier();
+ }
+
// Clear the gcInfo for REG_WRITE_BARRIER_SRC_BYREF and REG_WRITE_BARRIER_DST_BYREF.
// While we normally update GC info prior to the last instruction that uses them,
// these actually live into the helper call.
@@ -3560,6 +3590,12 @@ void CodeGen::genCodeForStoreInd(GenTreeStoreInd* tree)
dataReg = data->gtRegNum;
}
+ if (tree->gtFlags & GTF_IND_VOLATILE)
+ {
+ // issue a full memory barrier a before volatile StInd
+ instGen_MemoryBarrier();
+ }
+
emit->emitInsLoadStoreOp(ins_Store(targetType), emitTypeSize(tree), dataReg, tree);
}
}
diff --git a/src/jit/codegenarmarch.cpp b/src/jit/codegenarmarch.cpp
index d71a0b776e..0f8700a65d 100644
--- a/src/jit/codegenarmarch.cpp
+++ b/src/jit/codegenarmarch.cpp
@@ -1339,6 +1339,12 @@ void CodeGen::genCodeForIndir(GenTreeIndir* tree)
genConsumeAddress(tree->Addr());
emit->emitInsLoadStoreOp(ins_Load(targetType), emitTypeSize(tree), targetReg, tree);
genProduceReg(tree);
+
+ if (tree->gtFlags & GTF_IND_VOLATILE)
+ {
+ // issue a full memory barrier after a volatile LdInd operation
+ instGen_MemoryBarrier();
+ }
}
// Generate code for a CpBlk node by the means of the VM memcpy helper call
@@ -1361,7 +1367,19 @@ void CodeGen::genCodeForCpBlk(GenTreeBlk* cpBlkNode)
}
#endif // _TARGET_ARM64_
+ if (cpBlkNode->gtFlags & GTF_BLK_VOLATILE)
+ {
+ // issue a full memory barrier before & after a volatile CpBlkUnroll operation
+ instGen_MemoryBarrier();
+ }
+
genEmitHelperCall(CORINFO_HELP_MEMCPY, 0, EA_UNKNOWN);
+
+ if (cpBlkNode->gtFlags & GTF_BLK_VOLATILE)
+ {
+ // issue a full memory barrier before & after a volatile CpBlkUnroll operation
+ instGen_MemoryBarrier();
+ }
}
// Generates code for InitBlk by calling the VM memset helper function.
@@ -1398,6 +1416,13 @@ void CodeGen::genCodeForInitBlk(GenTreeBlk* initBlkNode)
#endif // _TARGET_ARM64_
genConsumeBlockOp(initBlkNode, REG_ARG_0, REG_ARG_1, REG_ARG_2);
+
+ if (initBlkNode->gtFlags & GTF_BLK_VOLATILE)
+ {
+ // issue a full memory barrier before a volatile initBlock Operation
+ instGen_MemoryBarrier();
+ }
+
genEmitHelperCall(CORINFO_HELP_MEMSET, 0, EA_UNKNOWN);
}