From 1fed0161d94dc0bd89e1c682f1f5d8757bd252a2 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 17 Aug 2009 20:25:13 -0700 Subject: X86: Implement a shuffle media microop. --- src/arch/x86/isa/microops/mediaop.isa | 42 +++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) (limited to 'src') diff --git a/src/arch/x86/isa/microops/mediaop.isa b/src/arch/x86/isa/microops/mediaop.isa index 83962b0f2..1bd99db3a 100644 --- a/src/arch/x86/isa/microops/mediaop.isa +++ b/src/arch/x86/isa/microops/mediaop.isa @@ -365,6 +365,48 @@ let {{ FpDestReg.uqw = result; ''' + class shuffle(MediaOp): + code = ''' + assert(srcSize == destSize); + int size = srcSize; + int sizeBits = size * 8; + int items = sizeof(FloatRegBits) / size; + int options; + int optionBits; + if (size == 8) { + options = 2; + optionBits = 1; + } else { + options = 4; + optionBits = 2; + } + + uint64_t result = 0; + uint8_t sel = ext; + + for (int i = 0; i < items; i++) { + uint64_t resBits; + uint8_t lsel = sel & mask(optionBits); + if (lsel * size >= sizeof(FloatRegBits)) { + lsel -= options / 2; + resBits = bits(FpSrcReg2.uqw, + (lsel + 1) * sizeBits - 1, + (lsel + 0) * sizeBits); + } else { + resBits = bits(FpSrcReg1.uqw, + (lsel + 1) * sizeBits - 1, + (lsel + 0) * sizeBits); + } + + sel >>= optionBits; + + int hiIndex = (i + 1) * sizeBits - 1; + int loIndex = (i + 0) * sizeBits; + result = insertBits(result, hiIndex, loIndex, resBits); + } + FpDestReg.uqw = result; + ''' + class Unpack(MediaOp): code = ''' assert(srcSize == destSize); -- cgit v1.2.3