Bug 1278283 - Introduce popcnt abstraction for ARM. r=nbp

--HG--
extra : rebase_source : 190e685184a2fbd93fc0fe82ff4322f286bc13e6
This commit is contained in:
Lars T Hansen 2016-06-26 15:38:43 +02:00
Родитель af5d06cbe3
Коммит e76ba7a4eb
3 изменённых файлов: 26 добавлений и 15 удалений

Просмотреть файл

@ -873,8 +873,11 @@ class MacroAssembler : public MacroAssemblerSpecific
inline void clz64(Register64 src, Register64 dest) DEFINED_ON(x64);
inline void ctz64(Register64 src, Register64 dest) DEFINED_ON(x64);
// On x86_shared, temp may be Invalid only if the chip has the POPCNT instruction.
// On ARM, temp may never be Invalid.
inline void popcnt32(Register src, Register dest, Register temp) DEFINED_ON(arm, x86_shared);
// temp may be invalid only if the chip has the POPCNT instruction.
inline void popcnt32(Register src, Register dest, Register temp) DEFINED_ON(x86_shared);
inline void popcnt64(Register64 src, Register64 dest, Register64 temp) DEFINED_ON(x64);
// ===============================================================

Просмотреть файл

@ -925,22 +925,9 @@ CodeGeneratorARM::visitPopcntI(LPopcntI* ins)
Register input = ToRegister(ins->input());
Register output = ToRegister(ins->output());
// Equivalent to GCC output of mozilla::CountPopulation32()
Register tmp = ToRegister(ins->temp());
masm.ma_mov(input, output);
masm.as_mov(tmp, asr(output, 1));
masm.ma_and(Imm32(0x55555555), tmp);
masm.ma_sub(output, tmp, output);
masm.as_mov(tmp, asr(output, 2));
masm.ma_and(Imm32(0x33333333), output);
masm.ma_and(Imm32(0x33333333), tmp);
masm.ma_add(output, tmp, output);
masm.as_add(output, output, lsr(output, 4));
masm.ma_and(Imm32(0xF0F0F0F), output);
masm.as_add(output, output, lsl(output, 8));
masm.as_add(output, output, lsl(output, 16));
masm.as_mov(output, asr(output, 24));
masm.popcnt32(input, output, tmp);
}
void

Просмотреть файл

@ -628,6 +628,27 @@ MacroAssembler::ctz32(Register src, Register dest, bool knownNotZero)
ma_ctz(src, dest);
}
void
MacroAssembler::popcnt32(Register input, Register output, Register tmp)
{
// Equivalent to GCC output of mozilla::CountPopulation32()
if (input != output)
ma_mov(input, output);
as_mov(tmp, asr(output, 1));
ma_and(Imm32(0x55555555), tmp);
ma_sub(output, tmp, output);
as_mov(tmp, asr(output, 2));
ma_and(Imm32(0x33333333), output);
ma_and(Imm32(0x33333333), tmp);
ma_add(output, tmp, output);
as_add(output, output, lsr(output, 4));
ma_and(Imm32(0xF0F0F0F), output);
as_add(output, output, lsl(output, 8));
as_add(output, output, lsl(output, 16));
as_mov(output, asr(output, 24));
}
// ===============================================================
// Branch functions