Fixing stvl/stvr.
This commit is contained in:
@@ -265,18 +265,16 @@ int InstrEmit_stvlx_(PPCHIRBuilder& f, InstrData& i, uint32_t vd, uint32_t ra,
|
||||
// we could optimize this to prevent the other load/mask, in that case.
|
||||
Value* ea = CalculateEA_0(f, ra, rb);
|
||||
Value* eb = f.And(f.Truncate(ea, INT8_TYPE), f.LoadConstant((int8_t)0xF));
|
||||
Value* new_value = f.LoadVR(vd);
|
||||
// ea &= ~0xF
|
||||
ea = f.And(ea, f.LoadConstant(~0xFull));
|
||||
// v = (old & ~mask) | ((new >> eb) & mask)
|
||||
Value* new_value = f.Permute(f.LoadVectorShr(eb), f.LoadZero(VEC128_TYPE),
|
||||
f.LoadVR(vd), INT8_TYPE);
|
||||
Value* old_value = f.ByteSwap(f.Load(ea, VEC128_TYPE));
|
||||
// v = (new >> eb) | (old & (ONE << (16 - eb)))
|
||||
Value* v = f.Permute(f.LoadVectorShr(eb), f.LoadZero(VEC128_TYPE), new_value,
|
||||
INT8_TYPE);
|
||||
v = f.Or(
|
||||
v, f.And(old_value,
|
||||
f.Permute(f.LoadVectorShl(f.Sub(f.LoadConstant((int8_t)16), eb)),
|
||||
f.Not(f.LoadZero(VEC128_TYPE)),
|
||||
f.LoadZero(VEC128_TYPE), INT8_TYPE)));
|
||||
// mask = FFFF... >> eb
|
||||
Value* mask = f.Permute(f.LoadVectorShr(eb), f.LoadZero(VEC128_TYPE),
|
||||
f.Not(f.LoadZero(VEC128_TYPE)), INT8_TYPE);
|
||||
Value* v = f.Or(f.And(old_value, f.Not(mask)), f.And(new_value, mask));
|
||||
// ea &= ~0xF (handled above)
|
||||
f.Store(ea, f.ByteSwap(v));
|
||||
return 0;
|
||||
@@ -301,16 +299,16 @@ int InstrEmit_stvrx_(PPCHIRBuilder& f, InstrData& i, uint32_t vd, uint32_t ra,
|
||||
// we could optimize this to prevent the other load/mask, in that case.
|
||||
Value* ea = CalculateEA_0(f, ra, rb);
|
||||
Value* eb = f.And(f.Truncate(ea, INT8_TYPE), f.LoadConstant((int8_t)0xF));
|
||||
Value* new_value = f.LoadVR(vd);
|
||||
// ea &= ~0xF
|
||||
ea = f.And(ea, f.LoadConstant(~0xFull));
|
||||
// v = (old & ~mask) | ((new << eb) & mask)
|
||||
Value* new_value = f.Permute(f.LoadVectorShr(eb), f.LoadVR(vd),
|
||||
f.LoadZero(VEC128_TYPE), INT8_TYPE);
|
||||
Value* old_value = f.ByteSwap(f.Load(ea, VEC128_TYPE));
|
||||
// v = (new << (16 - eb)) | (old & (ONE >> eb))
|
||||
Value* v = f.Permute(f.LoadVectorShl(f.Sub(f.LoadConstant((int8_t)16), eb)),
|
||||
new_value, f.LoadZero(VEC128_TYPE), INT8_TYPE);
|
||||
v = f.Or(v, f.And(old_value,
|
||||
f.Permute(f.LoadVectorShr(eb), f.LoadZero(VEC128_TYPE),
|
||||
f.Not(f.LoadZero(VEC128_TYPE)), INT8_TYPE)));
|
||||
// mask = ~FFFF... >> eb
|
||||
Value* mask = f.Permute(f.LoadVectorShr(eb), f.Not(f.LoadZero(VEC128_TYPE)),
|
||||
f.LoadZero(VEC128_TYPE), INT8_TYPE);
|
||||
Value* v = f.Or(f.And(old_value, f.Not(mask)), f.And(new_value, mask));
|
||||
// ea &= ~0xF (handled above)
|
||||
f.Store(ea, f.ByteSwap(v));
|
||||
return 0;
|
||||
|
||||
Reference in New Issue
Block a user