diff options
author | Brian Sullivan <briansul@microsoft.com> | 2017-05-10 13:50:19 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-05-10 13:50:19 -0700 |
commit | 0b625bfdbb97565b7d489d1d083cfaf4dbd47e0d (patch) | |
tree | b7aacfec06408527af04b57e3d3a433e097294a6 | |
parent | c9f469e5fc99a498f46bd2d60fb198b7f7f1c22b (diff) | |
parent | 84e39c38feae031c71ed3861a183ec5017783b7a (diff) | |
download | coreclr-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.cpp | 36 | ||||
-rw-r--r-- | src/jit/codegenarmarch.cpp | 25 |
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); } |