Fixing Altivec lvrx and stvrx

This commit is contained in:
Cesys 2017-03-30 23:00:29 -07:00
parent fd85255846
commit d2605bce18
1 changed files with 8 additions and 0 deletions

View File

@ -246,6 +246,10 @@ int InstrEmit_lvrx_(PPCHIRBuilder& f, const InstrData& i, uint32_t vd,
f.Branch(end_label); f.Branch(end_label);
f.MarkLabel(load_label); f.MarkLabel(load_label);
// ea &= ~0xF // ea &= ~0xF
// NOTE: need to recalculate ea and eb because after Branch we start a new
// block and we can't use their previous instantiation in the new block
ea = CalculateEA_0(f, ra, rb);
eb = f.And(f.Truncate(ea, INT8_TYPE), f.LoadConstantInt8(0xF));
ea = f.And(ea, f.LoadConstantUint64(~0xFull)); ea = f.And(ea, f.LoadConstantUint64(~0xFull));
// v = (new >> (16 - eb)) // v = (new >> (16 - eb))
Value* v = f.Permute(f.LoadVectorShl(eb), f.LoadZeroVec128(), Value* v = f.Permute(f.LoadVectorShl(eb), f.LoadZeroVec128(),
@ -312,6 +316,10 @@ int InstrEmit_stvrx_(PPCHIRBuilder& f, const InstrData& i, uint32_t vd,
auto skip_label = f.NewLabel(); auto skip_label = f.NewLabel();
f.BranchFalse(eb, skip_label); f.BranchFalse(eb, skip_label);
// ea &= ~0xF // ea &= ~0xF
// NOTE: need to recalculate ea and eb because after Branch we start a new
// block and we can't use their previous instantiation in the new block
ea = CalculateEA_0(f, ra, rb);
eb = f.And(f.Truncate(ea, INT8_TYPE), f.LoadConstantInt8(0xF));
ea = f.And(ea, f.LoadConstantUint64(~0xFull)); ea = f.And(ea, f.LoadConstantUint64(~0xFull));
// v = (old & ~mask) | ((new << eb) & mask) // v = (old & ~mask) | ((new << eb) & mask)
Value* new_value = f.Permute(f.LoadVectorShr(eb), f.LoadVR(vd), Value* new_value = f.Permute(f.LoadVectorShr(eb), f.LoadVR(vd),