Add constant folding for LVR when 16 aligned, clean up prior commit by removing dead test code for LVR/LVL/STVL/STVR opcodes and legacy hir sequence
Delay using mm_pause in KeAcquireSpinLockAtRaisedIrql_entry, a huge amount of time is spent spinning in halo3
This commit is contained in:
@@ -208,20 +208,10 @@ int InstrEmit_stvxl128(PPCHIRBuilder& f, const InstrData& i) {
|
||||
int InstrEmit_lvlx_(PPCHIRBuilder& f, const InstrData& i, uint32_t vd,
|
||||
uint32_t ra, uint32_t rb) {
|
||||
Value* ea = CalculateEA_0(f, ra, rb);
|
||||
#if 0
|
||||
Value* eb = f.And(f.Truncate(ea, INT8_TYPE), f.LoadConstantInt8(0xF));
|
||||
// ea &= ~0xF
|
||||
ea = f.And(ea, f.LoadConstantUint64(~0xFull));
|
||||
// v = (new << eb)
|
||||
Value* v = f.Permute(f.LoadVectorShl(eb), f.ByteSwap(f.Load(ea, VEC128_TYPE)),
|
||||
f.LoadZeroVec128(), INT8_TYPE);
|
||||
f.StoreVR(vd, v);
|
||||
return 0;
|
||||
#else
|
||||
|
||||
Value* val = f.LoadVectorLeft(ea);
|
||||
f.StoreVR(vd, val);
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
int InstrEmit_lvlx(PPCHIRBuilder& f, const InstrData& i) {
|
||||
return InstrEmit_lvlx_(f, i, i.X.RT, i.X.RA, i.X.RB);
|
||||
@@ -243,32 +233,10 @@ int InstrEmit_lvrx_(PPCHIRBuilder& f, const InstrData& i, uint32_t vd,
|
||||
// buffer, which sometimes may be nothing and hang off the end of the valid
|
||||
// page area. We still need to zero the resulting register, though.
|
||||
Value* ea = CalculateEA_0(f, ra, rb);
|
||||
#if 0
|
||||
Value* eb = f.And(f.Truncate(ea, INT8_TYPE), f.LoadConstantInt8(0xF));
|
||||
// Skip if %16=0 (just load zero).
|
||||
auto load_label = f.NewLabel();
|
||||
auto end_label = f.NewLabel();
|
||||
f.BranchTrue(eb, load_label);
|
||||
f.StoreVR(vd, f.LoadZeroVec128());
|
||||
f.Branch(end_label);
|
||||
f.MarkLabel(load_label);
|
||||
// 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));
|
||||
// v = (new >> (16 - eb))
|
||||
Value* v = f.Permute(f.LoadVectorShl(eb), f.LoadZeroVec128(),
|
||||
f.ByteSwap(f.Load(ea, VEC128_TYPE)), INT8_TYPE);
|
||||
f.StoreVR(vd, v);
|
||||
f.MarkLabel(end_label);
|
||||
return 0;
|
||||
#else
|
||||
|
||||
Value* val = f.LoadVectorRight(ea);
|
||||
f.StoreVR(vd, val);
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
int InstrEmit_lvrx(PPCHIRBuilder& f, const InstrData& i) {
|
||||
return InstrEmit_lvrx_(f, i, i.X.RT, i.X.RA, i.X.RB);
|
||||
@@ -289,34 +257,9 @@ int InstrEmit_stvlx_(PPCHIRBuilder& f, const InstrData& i, uint32_t vd,
|
||||
// we could optimize this to prevent the other load/mask, in that case.
|
||||
|
||||
Value* ea = CalculateEA_0(f, ra, rb);
|
||||
#if 0
|
||||
Value* eb = f.And(f.Truncate(ea, INT8_TYPE), f.LoadConstantInt8(0xF));
|
||||
// ea &= ~0xF
|
||||
ea = f.And(ea, f.LoadConstantUint64(~0xFull));
|
||||
Value* shrs = f.LoadVectorShr(eb);
|
||||
Value* zerovec = f.LoadZeroVec128();
|
||||
|
||||
// v = (old & ~mask) | ((new >> eb) & mask)
|
||||
|
||||
Value* mask = f.Permute(shrs, zerovec, f.Not(zerovec), INT8_TYPE);
|
||||
Value* new_value = f.Permute(shrs, zerovec, f.LoadVR(vd), INT8_TYPE);
|
||||
Value* old_value = f.ByteSwap(f.Load(ea, VEC128_TYPE));
|
||||
/*
|
||||
these permutes need to be looked at closer. keep in mind Permute is meant to
|
||||
emulate vmx's shuffles and does not generate particularly good code. The logic
|
||||
here looks as if it might make more sense as a comparison (
|
||||
*/
|
||||
// mask = FFFF... >> eb
|
||||
|
||||
|
||||
Value* v = f.Select(mask, old_value, new_value);
|
||||
// ea &= ~0xF (handled above)
|
||||
f.Store(ea, f.ByteSwap(v));
|
||||
#else
|
||||
|
||||
Value* vdr = f.LoadVR(vd);
|
||||
f.StoreVectorLeft(ea, vdr);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
int InstrEmit_stvlx(PPCHIRBuilder& f, const InstrData& i) {
|
||||
@@ -339,32 +282,9 @@ int InstrEmit_stvrx_(PPCHIRBuilder& f, const InstrData& i, uint32_t vd,
|
||||
// buffer, which sometimes may be nothing and hang off the end of the valid
|
||||
// page area.
|
||||
Value* ea = CalculateEA_0(f, ra, rb);
|
||||
#if 0
|
||||
Value* eb = f.And(f.Truncate(ea, INT8_TYPE), f.LoadConstantInt8(0xF));
|
||||
// Skip if %16=0 (no data to store).
|
||||
auto skip_label = f.NewLabel();
|
||||
f.BranchFalse(eb, skip_label);
|
||||
// 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));
|
||||
Value* shrs = f.LoadVectorShr(eb);
|
||||
Value* zerovec = f.LoadZeroVec128();
|
||||
// v = (old & ~mask) | ((new << eb) & mask)
|
||||
Value* new_value = f.Permute(shrs, f.LoadVR(vd), zerovec, INT8_TYPE);
|
||||
Value* old_value = f.ByteSwap(f.Load(ea, VEC128_TYPE));
|
||||
// mask = ~FFFF... >> eb
|
||||
Value* mask = f.Permute(shrs, f.Not(zerovec), zerovec, INT8_TYPE);
|
||||
Value* v = f.Select(mask, old_value, new_value);
|
||||
// ea &= ~0xF (handled above)
|
||||
f.Store(ea, f.ByteSwap(v));
|
||||
f.MarkLabel(skip_label);
|
||||
#else
|
||||
|
||||
Value* vdr = f.LoadVR(vd);
|
||||
f.StoreVectorRight(ea, vdr);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
int InstrEmit_stvrx(PPCHIRBuilder& f, const InstrData& i) {
|
||||
|
||||
Reference in New Issue
Block a user