10603
10624
goto decode_success;
10627
/* F2 0F 12 = MOVDDUP -- move from E (mem or xmm) to G (xmm),
10628
duplicating some lanes (0:1:0:1). */
10629
if (sz == 4 && insn[0] == 0xF2 && insn[1] == 0x0F && insn[2] == 0x12) {
10630
IRTemp sV = newTemp(Ity_V128);
10631
IRTemp d0 = newTemp(Ity_I64);
10634
if (epartIsReg(modrm)) {
10635
assign( sV, getXMMReg( eregOfRM(modrm)) );
10636
DIP("movddup %s,%s\n", nameXMMReg(eregOfRM(modrm)),
10637
nameXMMReg(gregOfRM(modrm)));
10639
assign ( d0, unop(Iop_V128to64, mkexpr(sV)) );
10641
addr = disAMode ( &alen, sorb, delta+3, dis_buf );
10642
assign( d0, loadLE(Ity_I64, mkexpr(addr)) );
10643
DIP("movddup %s,%s\n", dis_buf,
10644
nameXMMReg(gregOfRM(modrm)));
10648
putXMMReg( gregOfRM(modrm), binop(Iop_64HLtoV128,mkexpr(d0),mkexpr(d0)) );
10649
goto decode_success;
10606
10652
/* F2 0F D0 = ADDSUBPS -- 32x4 +/-/+/- from E (mem or xmm) to G (xmm). */
10607
10653
if (sz == 4 && insn[0] == 0xF2 && insn[1] == 0x0F && insn[2] == 0xD0) {
10608
10654
IRTemp a3, a2, a1, a0, s3, s2, s1, s0;
10638
10684
goto decode_success;
10687
/* 66 0F D0 = ADDSUBPD -- 64x4 +/- from E (mem or xmm) to G (xmm). */
10688
if (sz == 2 && insn[0] == 0x0F && insn[1] == 0xD0) {
10689
IRTemp eV = newTemp(Ity_V128);
10690
IRTemp gV = newTemp(Ity_V128);
10691
IRTemp addV = newTemp(Ity_V128);
10692
IRTemp subV = newTemp(Ity_V128);
10693
IRTemp a1 = newTemp(Ity_I64);
10694
IRTemp s0 = newTemp(Ity_I64);
10697
if (epartIsReg(modrm)) {
10698
assign( eV, getXMMReg( eregOfRM(modrm)) );
10699
DIP("addsubpd %s,%s\n", nameXMMReg(eregOfRM(modrm)),
10700
nameXMMReg(gregOfRM(modrm)));
10703
addr = disAMode ( &alen, sorb, delta+2, dis_buf );
10704
assign( eV, loadLE(Ity_V128, mkexpr(addr)) );
10705
DIP("addsubpd %s,%s\n", dis_buf,
10706
nameXMMReg(gregOfRM(modrm)));
10710
assign( gV, getXMMReg(gregOfRM(modrm)) );
10712
assign( addV, binop(Iop_Add64Fx2, mkexpr(gV), mkexpr(eV)) );
10713
assign( subV, binop(Iop_Sub64Fx2, mkexpr(gV), mkexpr(eV)) );
10715
assign( a1, unop(Iop_V128HIto64, mkexpr(addV) ));
10716
assign( s0, unop(Iop_V128to64, mkexpr(subV) ));
10718
putXMMReg( gregOfRM(modrm),
10719
binop(Iop_64HLtoV128, mkexpr(a1), mkexpr(s0)) );
10720
goto decode_success;
10723
/* F2 0F 7D = HSUBPS -- 32x4 sub across from E (mem or xmm) to G (xmm). */
10724
/* F2 0F 7C = HADDPS -- 32x4 add across from E (mem or xmm) to G (xmm). */
10725
if (sz == 4 && insn[0] == 0xF2 && insn[1] == 0x0F
10726
&& (insn[2] == 0x7C || insn[2] == 0x7D)) {
10727
IRTemp e3, e2, e1, e0, g3, g2, g1, g0;
10728
IRTemp eV = newTemp(Ity_V128);
10729
IRTemp gV = newTemp(Ity_V128);
10730
IRTemp leftV = newTemp(Ity_V128);
10731
IRTemp rightV = newTemp(Ity_V128);
10732
Bool isAdd = insn[2] == 0x7C;
10733
HChar* str = isAdd ? "add" : "sub";
10734
e3 = e2 = e1 = e0 = g3 = g2 = g1 = g0 = IRTemp_INVALID;
10737
if (epartIsReg(modrm)) {
10738
assign( eV, getXMMReg( eregOfRM(modrm)) );
10739
DIP("h%sps %s,%s\n", str, nameXMMReg(eregOfRM(modrm)),
10740
nameXMMReg(gregOfRM(modrm)));
10743
addr = disAMode ( &alen, sorb, delta+3, dis_buf );
10744
assign( eV, loadLE(Ity_V128, mkexpr(addr)) );
10745
DIP("h%sps %s,%s\n", str, dis_buf,
10746
nameXMMReg(gregOfRM(modrm)));
10750
assign( gV, getXMMReg(gregOfRM(modrm)) );
10752
breakup128to32s( eV, &e3, &e2, &e1, &e0 );
10753
breakup128to32s( gV, &g3, &g2, &g1, &g0 );
10755
assign( leftV, mk128from32s( e2, e0, g2, g0 ) );
10756
assign( rightV, mk128from32s( e3, e1, g3, g1 ) );
10758
putXMMReg( gregOfRM(modrm),
10759
binop(isAdd ? Iop_Add32Fx4 : Iop_Sub32Fx4,
10760
mkexpr(leftV), mkexpr(rightV) ) );
10761
goto decode_success;
10764
/* 66 0F 7D = HSUBPD -- 64x2 sub across from E (mem or xmm) to G (xmm). */
10765
/* 66 0F 7C = HADDPD -- 64x2 add across from E (mem or xmm) to G (xmm). */
10766
if (sz == 2 && insn[0] == 0x0F && (insn[1] == 0x7C || insn[1] == 0x7D)) {
10767
IRTemp e1 = newTemp(Ity_I64);
10768
IRTemp e0 = newTemp(Ity_I64);
10769
IRTemp g1 = newTemp(Ity_I64);
10770
IRTemp g0 = newTemp(Ity_I64);
10771
IRTemp eV = newTemp(Ity_V128);
10772
IRTemp gV = newTemp(Ity_V128);
10773
IRTemp leftV = newTemp(Ity_V128);
10774
IRTemp rightV = newTemp(Ity_V128);
10775
Bool isAdd = insn[1] == 0x7C;
10776
HChar* str = isAdd ? "add" : "sub";
10779
if (epartIsReg(modrm)) {
10780
assign( eV, getXMMReg( eregOfRM(modrm)) );
10781
DIP("h%spd %s,%s\n", str, nameXMMReg(eregOfRM(modrm)),
10782
nameXMMReg(gregOfRM(modrm)));
10785
addr = disAMode ( &alen, sorb, delta+2, dis_buf );
10786
assign( eV, loadLE(Ity_V128, mkexpr(addr)) );
10787
DIP("h%spd %s,%s\n", str, dis_buf,
10788
nameXMMReg(gregOfRM(modrm)));
10792
assign( gV, getXMMReg(gregOfRM(modrm)) );
10794
assign( e1, unop(Iop_V128HIto64, mkexpr(eV) ));
10795
assign( e0, unop(Iop_V128to64, mkexpr(eV) ));
10796
assign( g1, unop(Iop_V128HIto64, mkexpr(gV) ));
10797
assign( g0, unop(Iop_V128to64, mkexpr(gV) ));
10799
assign( leftV, binop(Iop_64HLtoV128, mkexpr(e0),mkexpr(g0)) );
10800
assign( rightV, binop(Iop_64HLtoV128, mkexpr(e1),mkexpr(g1)) );
10802
putXMMReg( gregOfRM(modrm),
10803
binop(isAdd ? Iop_Add64Fx2 : Iop_Sub64Fx2,
10804
mkexpr(leftV), mkexpr(rightV) ) );
10805
goto decode_success;
10808
/* F2 0F F0 = LDDQU -- move from E (mem or xmm) to G (xmm). */
10809
if (sz == 4 && insn[0] == 0xF2 && insn[1] == 0x0F && insn[2] == 0xF0) {
10810
modrm = getIByte(delta+3);
10811
if (epartIsReg(modrm)) {
10812
goto decode_failure;
10814
addr = disAMode ( &alen, sorb, delta+3, dis_buf );
10815
putXMMReg( gregOfRM(modrm),
10816
loadLE(Ity_V128, mkexpr(addr)) );
10817
DIP("lddqu %s,%s\n", dis_buf,
10818
nameXMMReg(gregOfRM(modrm)));
10821
goto decode_success;
10641
10824
/* ---------------------------------------------------- */
10642
10825
/* --- end of the SSE3 decoder. --- */
10643
10826
/* ---------------------------------------------------- */