priv/ir_opt.h \
priv/guest_generic_bb_to_IR.h \
priv/guest_generic_x87.h \
+ priv/guest_generic_sse.h \
priv/guest_x86_defs.h \
priv/guest_amd64_defs.h \
priv/guest_ppc_defs.h \
514094 readlink("/proc/self/exe") overwrites buffer beyond its return value
514206 Assertion '!sr_isError(sr)' failed - mmap fd points to an open
descriptor to a PCI device
+514596 Add SSE4.1 BLENDPD instruction for x86 32 bit
514613 Unclosed leak_summary/still_reachable tag in xml output
514659 ltp 20250930 vs linux 6.18.3 doesn't build
514762 Many "Bad file descriptor" messages when using --track-fds=yes and
}
}
+static IRExpr* mkV128 ( UShort mask )
+{
+ return IRExpr_Const(IRConst_V128(mask));
+}
+
+#include "guest_generic_sse.h"
+
static void storeLE ( IRExpr* addr, IRExpr* data )
{
stmt( IRStmt_Store(Iend_LE, addr, data) );
stmt( IRStmt_Put( ymmGuestRegLane32offset(ymmreg,laneno), e ) );
}
-static IRExpr* mkV128 ( UShort mask )
-{
- return IRExpr_Const(IRConst_V128(mask));
-}
-
/* Write the low half of a YMM reg and zero out the upper half. */
static void putYMMRegLoAndZU ( UInt ymmreg, IRExpr* e )
{
}
-static IRTemp math_BLENDPD_128 ( IRTemp sV, IRTemp dV, UInt imm8 )
-{
- UShort imm8_mask_16;
- IRTemp imm8_mask = newTemp(Ity_V128);
-
- switch( imm8 & 3 ) {
- case 0: imm8_mask_16 = 0x0000; break;
- case 1: imm8_mask_16 = 0x00FF; break;
- case 2: imm8_mask_16 = 0xFF00; break;
- case 3: imm8_mask_16 = 0xFFFF; break;
- default: vassert(0); break;
- }
- assign( imm8_mask, mkV128( imm8_mask_16 ) );
-
- IRTemp res = newTemp(Ity_V128);
- assign ( res, binop( Iop_OrV128,
- binop( Iop_AndV128, mkexpr(sV),
- mkexpr(imm8_mask) ),
- binop( Iop_AndV128, mkexpr(dV),
- unop( Iop_NotV128, mkexpr(imm8_mask) ) ) ) );
- return res;
-}
-
-
static IRTemp math_BLENDPD_256 ( IRTemp sV, IRTemp dV, UInt imm8 )
{
IRTemp sVhi = IRTemp_INVALID, sVlo = IRTemp_INVALID;
--- /dev/null
+/*---------------------------------------------------------------*/
+/*--- begin guest_generic_sse.h ---*/
+/*---------------------------------------------------------------*/
+
+/*
+ This file is part of Valgrind, a dynamic binary instrumentation
+ framework.
+
+ Copyright (C) 2025-2026 Alexandra Hájková <ahajkova@redhat.com>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 3 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+ The GNU General Public License is contained in the file COPYING.
+*/
+
+/* This file contains functions for SSE/SSE2/SSE3/SSE4-specific
+ operations. Both the amd64 and x86 front ends (guests) call
+ these functions. By putting them here, code duplication is
+ avoided. Some of these functions are tricky and hard to verify,
+ so there is much to be said for only having one copy thereof.
+
+ IMPORTANT: This header must be included AFTER the following
+ helper functions/macros are defined in the including file:
+ - newTemp(IRType) - allocate a new IRTemp
+ - assign(IRTemp, IRExpr*) - create assignment statement
+ - mkV128(UShort) - create V128 constant expression
+ - binop(IROp, IRExpr*, IRExpr*) - create binary operation
+ - unop(IROp, IRExpr*) - create unary operation
+ - mkexpr(IRTemp) - create IRTemp expression
+ - vassert(Bool) - assertion macro
+
+ These helper functions are defined locally in each guest_*_toIR.c
+ file because they rely on file-local global state, particularly
+ the 'irsb' variable (the IR super block being built). Moving them
+ to a shared header would require either passing 'irsb' as a
+ parameter to each call (breaking thousands of call sites) or
+ making 'irsb' a shared extern (architecturally problematic).
+
+ Therefore, this header is included after those helpers are defined,
+ typically around line 300 in guest_*_toIR.c files.
+*/
+
+#ifndef __VEX_GUEST_GENERIC_SSE_H
+#define __VEX_GUEST_GENERIC_SSE_H
+
+#include "libvex_basictypes.h"
+#include "libvex_ir.h"
+#include "libvex.h"
+
+
+/* BLENDPD 128-bit */
+static inline IRTemp math_BLENDPD_128 ( IRTemp sV, IRTemp dV, UInt imm8 )
+{
+ UShort imm8_mask_16;
+ IRTemp imm8_mask = newTemp(Ity_V128);
+
+ switch( imm8 & 3 ) {
+ case 0: imm8_mask_16 = 0x0000; break;
+ case 1: imm8_mask_16 = 0x00FF; break;
+ case 2: imm8_mask_16 = 0xFF00; break;
+ case 3: imm8_mask_16 = 0xFFFF; break;
+ default: vassert(0); break;
+ }
+ assign( imm8_mask, mkV128( imm8_mask_16 ) );
+
+ IRTemp res = newTemp(Ity_V128);
+ assign ( res, binop( Iop_OrV128,
+ binop( Iop_AndV128, mkexpr(sV),
+ mkexpr(imm8_mask) ),
+ binop( Iop_AndV128, mkexpr(dV),
+ unop( Iop_NotV128, mkexpr(imm8_mask) ) ) ) );
+ return res;
+}
+
+#endif /* ndef __VEX_GUEST_GENERIC_SSE_H */
+
+/*---------------------------------------------------------------*/
+/*--- end guest_generic_sse.h ---*/
+/*---------------------------------------------------------------*/
return IRExpr_Const(IRConst_V128(mask));
}
+#include "guest_generic_sse.h"
+
static IRExpr* loadLE ( IRType ty, IRExpr* addr )
{
return IRExpr_Load(Iend_LE, ty, addr);
goto decode_success;
}
+ /* 66 0F 3A 0D /r ib = BLENDPD xmm1, xmm2/m128, imm8
+ Blend Packed Double Precision Floating-Point Values (XMM)
+ - 66 = mandatory prefix (this is what makes sz == 2)
+ - 0F 3A 0D = three opcode bytes
+ - /r = ModR/M byte follows (specifies registers or memory addressing)
+ - ib = immediate byte follows (1 byte immediate value)
+ insn[] array layout:
+
+ insn[0] = 0x0F (first opcode byte)
+ insn[1] = 0x3A (second opcode byte)
+ insn[2] = 0x0D (third opcode byte)
+ insn[3] = ModR/M (specifies source/dest registers or memory mode)
+
+ Register-to-register form:
+ insn[3] = ModR/M byte (tells us which registers)
+ insn[4] = immediate byte
+ alen var tells us how many bytes the addressing mode consumed after the ModR/M byte
+*/
+ if (sz == 2 && insn[0] == 0x0F && insn[1] == 0x3A && insn[2] == 0x0D) {
+ Int imm8;
+ IRTemp dst_vec = newTemp(Ity_V128);
+ IRTemp src_vec = newTemp(Ity_V128);
+
+ modrm = insn[3];
+ //no REX prefix on 32bit
+ assign( dst_vec, getXMMReg( gregOfRM(modrm) ) );
+
+ if ( epartIsReg( modrm ) ) {
+ imm8 = insn[4];
+ assign( src_vec, getXMMReg( eregOfRM(modrm) ) );
+ //skip 0F 3A 0D opcode bytes: +3
+ delta += 1+1 + 3;
+ DIP( "blendpd $%d, %s,%s\n", imm8,
+ nameXMMReg( eregOfRM(modrm) ),
+ nameXMMReg( gregOfRM(modrm) ) );
+ } else {
+ //delta+3 skips the 0F 3A 0D bytes
+ addr = disAMode( &alen, sorb, delta + 3, dis_buf);
+ assign( src_vec, loadLE( Ity_V128, mkexpr(addr) ) );
+ imm8 = insn[3+alen];
+ //skip 0F 3A 0D opcode bytes: +3
+ delta += alen+1 + 3;
+ DIP( "blendpd $%d, %s,%s\n",
+ imm8, dis_buf, nameXMMReg( gregOfRM(modrm) ) );
+ }
+
+ putXMMReg( gregOfRM(modrm),
+ mkexpr( math_BLENDPD_128( src_vec, dst_vec, imm8) ) );
+ goto decode_success;
+ }
+
/* 66 0F 38 38 /r - PMINSB xmm1, xmm2/m128
66 0F 38 3C /r - PMAXSB xmm1, xmm2/m128
Minimum/Maximum of Packed Signed Byte Integers (XMM)
-void test_BLENDPD ( void )
-{
- V128 src, dst;
- Int i;
- for (i = 0; i < 10; i++) {
- randV128(&src);
- randV128(&dst);
- DO_imm_mandr_r("blendpd", 0, src, dst);
- DO_imm_mandr_r("blendpd", 1, src, dst);
- DO_imm_mandr_r("blendpd", 2, src, dst);
- DO_imm_mandr_r("blendpd", 3, src, dst);
- }
-}
-
void test_BLENDPS ( void )
{
V128 src, dst;
}
}
+static inline void test_BLENDPD ( void )
+{
+ V128 src, dst;
+ Int i;
+ for (i = 0; i < 10; i++) {
+ randV128(&src);
+ randV128(&dst);
+ DO_imm_mandr_r("blendpd", 0, src, dst);
+ DO_imm_mandr_r("blendpd", 1, src, dst);
+ DO_imm_mandr_r("blendpd", 2, src, dst);
+ DO_imm_mandr_r("blendpd", 3, src, dst);
+ }
+}
+
#endif /* __SSE4_COMMON_H */
test_PMINUD();
test_PMINUW();
test_PMULLD();
+ test_BLENDPD();
return 0;
}
m pmulld a77700084a491a0ef099b6dd61462ec3 e70a9c61f55fce335d68e1a25652a804 306be308b0b974caedc5f4da103eb30c
r pmulld 1dd493f59184345437d5e366d0e20c30 c50f1401e45b82d3086a7a39a1e6217d edbeb7f57c65c93cb53a3db645122370
m pmulld 1dd493f59184345437d5e366d0e20c30 c50f1401e45b82d3086a7a39a1e6217d edbeb7f57c65c93cb53a3db645122370
+r blendpd $0 3a542e238fe5d1793d1148867eb08f81 b79cd058188318692112ca1cf9f1dd31 b79cd058188318692112ca1cf9f1dd31
+m blendpd $0 3a542e238fe5d1793d1148867eb08f81 b79cd058188318692112ca1cf9f1dd31 b79cd058188318692112ca1cf9f1dd31
+r blendpd $1 3a542e238fe5d1793d1148867eb08f81 b79cd058188318692112ca1cf9f1dd31 b79cd058188318693d1148867eb08f81
+m blendpd $1 3a542e238fe5d1793d1148867eb08f81 b79cd058188318692112ca1cf9f1dd31 b79cd058188318693d1148867eb08f81
+r blendpd $2 3a542e238fe5d1793d1148867eb08f81 b79cd058188318692112ca1cf9f1dd31 3a542e238fe5d1792112ca1cf9f1dd31
+m blendpd $2 3a542e238fe5d1793d1148867eb08f81 b79cd058188318692112ca1cf9f1dd31 3a542e238fe5d1792112ca1cf9f1dd31
+r blendpd $3 3a542e238fe5d1793d1148867eb08f81 b79cd058188318692112ca1cf9f1dd31 3a542e238fe5d1793d1148867eb08f81
+m blendpd $3 3a542e238fe5d1793d1148867eb08f81 b79cd058188318692112ca1cf9f1dd31 3a542e238fe5d1793d1148867eb08f81
+r blendpd $0 5842cbfee0f72e2ade18612787bc73e3 19ffced22c62cba0822c4c377b82984c 19ffced22c62cba0822c4c377b82984c
+m blendpd $0 5842cbfee0f72e2ade18612787bc73e3 19ffced22c62cba0822c4c377b82984c 19ffced22c62cba0822c4c377b82984c
+r blendpd $1 5842cbfee0f72e2ade18612787bc73e3 19ffced22c62cba0822c4c377b82984c 19ffced22c62cba0de18612787bc73e3
+m blendpd $1 5842cbfee0f72e2ade18612787bc73e3 19ffced22c62cba0822c4c377b82984c 19ffced22c62cba0de18612787bc73e3
+r blendpd $2 5842cbfee0f72e2ade18612787bc73e3 19ffced22c62cba0822c4c377b82984c 5842cbfee0f72e2a822c4c377b82984c
+m blendpd $2 5842cbfee0f72e2ade18612787bc73e3 19ffced22c62cba0822c4c377b82984c 5842cbfee0f72e2a822c4c377b82984c
+r blendpd $3 5842cbfee0f72e2ade18612787bc73e3 19ffced22c62cba0822c4c377b82984c 5842cbfee0f72e2ade18612787bc73e3
+m blendpd $3 5842cbfee0f72e2ade18612787bc73e3 19ffced22c62cba0822c4c377b82984c 5842cbfee0f72e2ade18612787bc73e3
+r blendpd $0 d4ec68f21f468712f7b8ab3708137382 478209dbbd84d92508847c7642a20df9 478209dbbd84d92508847c7642a20df9
+m blendpd $0 d4ec68f21f468712f7b8ab3708137382 478209dbbd84d92508847c7642a20df9 478209dbbd84d92508847c7642a20df9
+r blendpd $1 d4ec68f21f468712f7b8ab3708137382 478209dbbd84d92508847c7642a20df9 478209dbbd84d925f7b8ab3708137382
+m blendpd $1 d4ec68f21f468712f7b8ab3708137382 478209dbbd84d92508847c7642a20df9 478209dbbd84d925f7b8ab3708137382
+r blendpd $2 d4ec68f21f468712f7b8ab3708137382 478209dbbd84d92508847c7642a20df9 d4ec68f21f46871208847c7642a20df9
+m blendpd $2 d4ec68f21f468712f7b8ab3708137382 478209dbbd84d92508847c7642a20df9 d4ec68f21f46871208847c7642a20df9
+r blendpd $3 d4ec68f21f468712f7b8ab3708137382 478209dbbd84d92508847c7642a20df9 d4ec68f21f468712f7b8ab3708137382
+m blendpd $3 d4ec68f21f468712f7b8ab3708137382 478209dbbd84d92508847c7642a20df9 d4ec68f21f468712f7b8ab3708137382
+r blendpd $0 0b9c016be95f18de62bba1a11cc04c89 9c727edf66767ca38fe6d7c56a5ff965 9c727edf66767ca38fe6d7c56a5ff965
+m blendpd $0 0b9c016be95f18de62bba1a11cc04c89 9c727edf66767ca38fe6d7c56a5ff965 9c727edf66767ca38fe6d7c56a5ff965
+r blendpd $1 0b9c016be95f18de62bba1a11cc04c89 9c727edf66767ca38fe6d7c56a5ff965 9c727edf66767ca362bba1a11cc04c89
+m blendpd $1 0b9c016be95f18de62bba1a11cc04c89 9c727edf66767ca38fe6d7c56a5ff965 9c727edf66767ca362bba1a11cc04c89
+r blendpd $2 0b9c016be95f18de62bba1a11cc04c89 9c727edf66767ca38fe6d7c56a5ff965 0b9c016be95f18de8fe6d7c56a5ff965
+m blendpd $2 0b9c016be95f18de62bba1a11cc04c89 9c727edf66767ca38fe6d7c56a5ff965 0b9c016be95f18de8fe6d7c56a5ff965
+r blendpd $3 0b9c016be95f18de62bba1a11cc04c89 9c727edf66767ca38fe6d7c56a5ff965 0b9c016be95f18de62bba1a11cc04c89
+m blendpd $3 0b9c016be95f18de62bba1a11cc04c89 9c727edf66767ca38fe6d7c56a5ff965 0b9c016be95f18de62bba1a11cc04c89
+r blendpd $0 579f90d5d9cd1c3afceebf50e0d0ba24 761b274ac4c4f0c7f31ed81010c417bc 761b274ac4c4f0c7f31ed81010c417bc
+m blendpd $0 579f90d5d9cd1c3afceebf50e0d0ba24 761b274ac4c4f0c7f31ed81010c417bc 761b274ac4c4f0c7f31ed81010c417bc
+r blendpd $1 579f90d5d9cd1c3afceebf50e0d0ba24 761b274ac4c4f0c7f31ed81010c417bc 761b274ac4c4f0c7fceebf50e0d0ba24
+m blendpd $1 579f90d5d9cd1c3afceebf50e0d0ba24 761b274ac4c4f0c7f31ed81010c417bc 761b274ac4c4f0c7fceebf50e0d0ba24
+r blendpd $2 579f90d5d9cd1c3afceebf50e0d0ba24 761b274ac4c4f0c7f31ed81010c417bc 579f90d5d9cd1c3af31ed81010c417bc
+m blendpd $2 579f90d5d9cd1c3afceebf50e0d0ba24 761b274ac4c4f0c7f31ed81010c417bc 579f90d5d9cd1c3af31ed81010c417bc
+r blendpd $3 579f90d5d9cd1c3afceebf50e0d0ba24 761b274ac4c4f0c7f31ed81010c417bc 579f90d5d9cd1c3afceebf50e0d0ba24
+m blendpd $3 579f90d5d9cd1c3afceebf50e0d0ba24 761b274ac4c4f0c7f31ed81010c417bc 579f90d5d9cd1c3afceebf50e0d0ba24
+r blendpd $0 1541139c8b1cd0d1a11d81326f4e7880 30c9028972f8733d11f7fa4450de2529 30c9028972f8733d11f7fa4450de2529
+m blendpd $0 1541139c8b1cd0d1a11d81326f4e7880 30c9028972f8733d11f7fa4450de2529 30c9028972f8733d11f7fa4450de2529
+r blendpd $1 1541139c8b1cd0d1a11d81326f4e7880 30c9028972f8733d11f7fa4450de2529 30c9028972f8733da11d81326f4e7880
+m blendpd $1 1541139c8b1cd0d1a11d81326f4e7880 30c9028972f8733d11f7fa4450de2529 30c9028972f8733da11d81326f4e7880
+r blendpd $2 1541139c8b1cd0d1a11d81326f4e7880 30c9028972f8733d11f7fa4450de2529 1541139c8b1cd0d111f7fa4450de2529
+m blendpd $2 1541139c8b1cd0d1a11d81326f4e7880 30c9028972f8733d11f7fa4450de2529 1541139c8b1cd0d111f7fa4450de2529
+r blendpd $3 1541139c8b1cd0d1a11d81326f4e7880 30c9028972f8733d11f7fa4450de2529 1541139c8b1cd0d1a11d81326f4e7880
+m blendpd $3 1541139c8b1cd0d1a11d81326f4e7880 30c9028972f8733d11f7fa4450de2529 1541139c8b1cd0d1a11d81326f4e7880
+r blendpd $0 a1cd852d9cd970502d146432e64644c9 25c80a060da03fb0c33ebc4b44b8ddd8 25c80a060da03fb0c33ebc4b44b8ddd8
+m blendpd $0 a1cd852d9cd970502d146432e64644c9 25c80a060da03fb0c33ebc4b44b8ddd8 25c80a060da03fb0c33ebc4b44b8ddd8
+r blendpd $1 a1cd852d9cd970502d146432e64644c9 25c80a060da03fb0c33ebc4b44b8ddd8 25c80a060da03fb02d146432e64644c9
+m blendpd $1 a1cd852d9cd970502d146432e64644c9 25c80a060da03fb0c33ebc4b44b8ddd8 25c80a060da03fb02d146432e64644c9
+r blendpd $2 a1cd852d9cd970502d146432e64644c9 25c80a060da03fb0c33ebc4b44b8ddd8 a1cd852d9cd97050c33ebc4b44b8ddd8
+m blendpd $2 a1cd852d9cd970502d146432e64644c9 25c80a060da03fb0c33ebc4b44b8ddd8 a1cd852d9cd97050c33ebc4b44b8ddd8
+r blendpd $3 a1cd852d9cd970502d146432e64644c9 25c80a060da03fb0c33ebc4b44b8ddd8 a1cd852d9cd970502d146432e64644c9
+m blendpd $3 a1cd852d9cd970502d146432e64644c9 25c80a060da03fb0c33ebc4b44b8ddd8 a1cd852d9cd970502d146432e64644c9
+r blendpd $0 5791e2f2a78f37627c9fe23c60c5d82b b3633c2f304791cde6c097130b5efcf6 b3633c2f304791cde6c097130b5efcf6
+m blendpd $0 5791e2f2a78f37627c9fe23c60c5d82b b3633c2f304791cde6c097130b5efcf6 b3633c2f304791cde6c097130b5efcf6
+r blendpd $1 5791e2f2a78f37627c9fe23c60c5d82b b3633c2f304791cde6c097130b5efcf6 b3633c2f304791cd7c9fe23c60c5d82b
+m blendpd $1 5791e2f2a78f37627c9fe23c60c5d82b b3633c2f304791cde6c097130b5efcf6 b3633c2f304791cd7c9fe23c60c5d82b
+r blendpd $2 5791e2f2a78f37627c9fe23c60c5d82b b3633c2f304791cde6c097130b5efcf6 5791e2f2a78f3762e6c097130b5efcf6
+m blendpd $2 5791e2f2a78f37627c9fe23c60c5d82b b3633c2f304791cde6c097130b5efcf6 5791e2f2a78f3762e6c097130b5efcf6
+r blendpd $3 5791e2f2a78f37627c9fe23c60c5d82b b3633c2f304791cde6c097130b5efcf6 5791e2f2a78f37627c9fe23c60c5d82b
+m blendpd $3 5791e2f2a78f37627c9fe23c60c5d82b b3633c2f304791cde6c097130b5efcf6 5791e2f2a78f37627c9fe23c60c5d82b
+r blendpd $0 94d7265949ca62b46a8a793cf9d5f0d1 35e7926e777aa43f56470887bfdd3daf 35e7926e777aa43f56470887bfdd3daf
+m blendpd $0 94d7265949ca62b46a8a793cf9d5f0d1 35e7926e777aa43f56470887bfdd3daf 35e7926e777aa43f56470887bfdd3daf
+r blendpd $1 94d7265949ca62b46a8a793cf9d5f0d1 35e7926e777aa43f56470887bfdd3daf 35e7926e777aa43f6a8a793cf9d5f0d1
+m blendpd $1 94d7265949ca62b46a8a793cf9d5f0d1 35e7926e777aa43f56470887bfdd3daf 35e7926e777aa43f6a8a793cf9d5f0d1
+r blendpd $2 94d7265949ca62b46a8a793cf9d5f0d1 35e7926e777aa43f56470887bfdd3daf 94d7265949ca62b456470887bfdd3daf
+m blendpd $2 94d7265949ca62b46a8a793cf9d5f0d1 35e7926e777aa43f56470887bfdd3daf 94d7265949ca62b456470887bfdd3daf
+r blendpd $3 94d7265949ca62b46a8a793cf9d5f0d1 35e7926e777aa43f56470887bfdd3daf 94d7265949ca62b46a8a793cf9d5f0d1
+m blendpd $3 94d7265949ca62b46a8a793cf9d5f0d1 35e7926e777aa43f56470887bfdd3daf 94d7265949ca62b46a8a793cf9d5f0d1
+r blendpd $0 b2ed4ecc1e172df2d3a0a41fce854ae7 06a10a317fc4b5b3ef9f8c927c405d2f 06a10a317fc4b5b3ef9f8c927c405d2f
+m blendpd $0 b2ed4ecc1e172df2d3a0a41fce854ae7 06a10a317fc4b5b3ef9f8c927c405d2f 06a10a317fc4b5b3ef9f8c927c405d2f
+r blendpd $1 b2ed4ecc1e172df2d3a0a41fce854ae7 06a10a317fc4b5b3ef9f8c927c405d2f 06a10a317fc4b5b3d3a0a41fce854ae7
+m blendpd $1 b2ed4ecc1e172df2d3a0a41fce854ae7 06a10a317fc4b5b3ef9f8c927c405d2f 06a10a317fc4b5b3d3a0a41fce854ae7
+r blendpd $2 b2ed4ecc1e172df2d3a0a41fce854ae7 06a10a317fc4b5b3ef9f8c927c405d2f b2ed4ecc1e172df2ef9f8c927c405d2f
+m blendpd $2 b2ed4ecc1e172df2d3a0a41fce854ae7 06a10a317fc4b5b3ef9f8c927c405d2f b2ed4ecc1e172df2ef9f8c927c405d2f
+r blendpd $3 b2ed4ecc1e172df2d3a0a41fce854ae7 06a10a317fc4b5b3ef9f8c927c405d2f b2ed4ecc1e172df2d3a0a41fce854ae7
+m blendpd $3 b2ed4ecc1e172df2d3a0a41fce854ae7 06a10a317fc4b5b3ef9f8c927c405d2f b2ed4ecc1e172df2d3a0a41fce854ae7