Moving LoadAcquire/StoreRelease behavior up into HIR.

This commit is contained in:
Ben Vanik
2014-01-04 00:50:48 -08:00
parent 88b631b160
commit 93ea56179a
11 changed files with 97 additions and 197 deletions

View File

@@ -185,6 +185,9 @@ typedef struct XECACHEALIGN64 PPCContext_s {
// fpscr.value = (fpscr.value & ~0x000F8000) | v;
// }
// Reserve address for load acquire/store release. Shared.
uint32_t* reserve_address;
// Runtime-specific data pointer. Used on callbacks to get access to the
// current runtime and its data.
uint8_t* membase;

View File

@@ -141,6 +141,8 @@ int PPCHIRBuilder::Emit(FunctionInfo* symbol_info) {
// splits blocks we don't have weird pointers.
if (prev_instr && prev_instr->next) {
instr_offset_list_[offset] = prev_instr->next;
} else if (prev_instr) {
instr_offset_list_[offset] = prev_instr->block->next->instr_head;
} else if (current_block_) {
instr_offset_list_[offset] = current_block_->instr_head;
} else if (block_tail_) {
@@ -326,3 +328,24 @@ void PPCHIRBuilder::StoreVR(uint32_t reg, Value* value) {
StoreContext(
offsetof(PPCContext, v) + reg * 16, value);
}
Value* PPCHIRBuilder::LoadAcquire(
Value* address, TypeName type, uint32_t load_flags) {
AtomicExchange(
LoadContext(offsetof(PPCContext, reserve_address), INT64_TYPE),
Truncate(address, INT32_TYPE));
return Load(address, type, load_flags);
}
Value* PPCHIRBuilder::StoreRelease(
Value* address, Value* value, uint32_t store_flags) {
Value* old_address = AtomicExchange(
LoadContext(offsetof(PPCContext, reserve_address), INT64_TYPE),
LoadZero(INT32_TYPE));
Value* eq = CompareEQ(Truncate(address, INT32_TYPE), old_address);
auto skip_label = NewLabel();
BranchFalse(eq, skip_label, BRANCH_UNLIKELY);
Store(address, value, store_flags);
MarkLabel(skip_label);
return eq;
}

View File

@@ -63,6 +63,9 @@ public:
Value* LoadVR(uint32_t reg);
void StoreVR(uint32_t reg, Value* value);
Value* LoadAcquire(Value* address, hir::TypeName type, uint32_t load_flags = 0);
Value* StoreRelease(Value* address, Value* value, uint32_t store_flags = 0);
private:
void AnnotateLabel(uint64_t address, Label* label);