180 lines
6.9 KiB
C
180 lines
6.9 KiB
C
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
|
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
|
╞══════════════════════════════════════════════════════════════════════════════╡
|
|
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
|
│ │
|
|
│ 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; version 2 of the License. │
|
|
│ │
|
|
│ 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, write to the Free Software │
|
|
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
|
│ 02110-1301 USA │
|
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
|
#include "tool/build/lib/modrm.h"
|
|
#include "tool/build/lib/xmmtype.h"
|
|
|
|
static void UpdateXmmTypes(struct Machine *m, struct XmmType *xt, int regtype,
|
|
int rmtype) {
|
|
xt->type[RexrReg(m->xedd->op.rde)] = regtype;
|
|
if (IsModrmRegister(m->xedd->op.rde)) {
|
|
xt->type[RexbRm(m->xedd->op.rde)] = rmtype;
|
|
}
|
|
}
|
|
|
|
static void UpdateXmmSizes(struct Machine *m, struct XmmType *xt, int regsize,
|
|
int rmsize) {
|
|
xt->size[RexrReg(m->xedd->op.rde)] = regsize;
|
|
if (IsModrmRegister(m->xedd->op.rde)) {
|
|
xt->size[RexbRm(m->xedd->op.rde)] = rmsize;
|
|
}
|
|
}
|
|
|
|
void UpdateXmmType(struct Machine *m, struct XmmType *xt) {
|
|
switch (m->xedd->op.dispatch) {
|
|
case 0x12E: // UCOMIS
|
|
case 0x12F: // COMIS
|
|
case 0x151: // SQRT
|
|
case 0x152: // RSQRT
|
|
case 0x153: // RCP
|
|
case 0x158: // ADD
|
|
case 0x159: // MUL
|
|
case 0x15C: // SUB
|
|
case 0x15D: // MIN
|
|
case 0x15E: // DIV
|
|
case 0x15F: // MAX
|
|
case 0x1C2: // CMP
|
|
if (Osz(m->xedd->op.rde) || Rep(m->xedd->op.rde) == 2) {
|
|
UpdateXmmTypes(m, xt, kXmmDouble, kXmmDouble);
|
|
} else {
|
|
UpdateXmmTypes(m, xt, kXmmFloat, kXmmFloat);
|
|
}
|
|
break;
|
|
case 0x12A: // CVTPI2PS,CVTSI2SS,CVTPI2PD,CVTSI2SD
|
|
if (Osz(m->xedd->op.rde) || Rep(m->xedd->op.rde) == 2) {
|
|
UpdateXmmSizes(m, xt, 8, 4);
|
|
UpdateXmmTypes(m, xt, kXmmDouble, kXmmIntegral);
|
|
} else {
|
|
UpdateXmmSizes(m, xt, 4, 4);
|
|
UpdateXmmTypes(m, xt, kXmmFloat, kXmmIntegral);
|
|
}
|
|
break;
|
|
case 0x15A: // CVT{P,S}{S,D}2{P,S}{S,D}
|
|
if (Osz(m->xedd->op.rde) || Rep(m->xedd->op.rde) == 2) {
|
|
UpdateXmmTypes(m, xt, kXmmFloat, kXmmDouble);
|
|
} else {
|
|
UpdateXmmTypes(m, xt, kXmmDouble, kXmmFloat);
|
|
}
|
|
break;
|
|
case 0x15B: // CVT{,T}{DQ,PS}2{PS,DQ}
|
|
UpdateXmmSizes(m, xt, 4, 4);
|
|
if (Osz(m->xedd->op.rde) || Rep(m->xedd->op.rde) == 3) {
|
|
UpdateXmmTypes(m, xt, kXmmIntegral, kXmmFloat);
|
|
} else {
|
|
UpdateXmmTypes(m, xt, kXmmFloat, kXmmIntegral);
|
|
}
|
|
break;
|
|
case 0x17C: // HADD
|
|
case 0x17D: // HSUB
|
|
case 0x1D0: // ADDSUB
|
|
if (Osz(m->xedd->op.rde)) {
|
|
UpdateXmmTypes(m, xt, kXmmDouble, kXmmDouble);
|
|
} else {
|
|
UpdateXmmTypes(m, xt, kXmmFloat, kXmmFloat);
|
|
}
|
|
break;
|
|
case 0x164: // PCMPGTB
|
|
case 0x174: // PCMPEQB
|
|
case 0x1D8: // PSUBUSB
|
|
case 0x1DA: // PMINUB
|
|
case 0x1DC: // PADDUSB
|
|
case 0x1DE: // PMAXUB
|
|
case 0x1E0: // PAVGB
|
|
case 0x1E8: // PSUBSB
|
|
case 0x1EC: // PADDSB
|
|
case 0x1F8: // PSUBB
|
|
case 0x1FC: // PADDB
|
|
UpdateXmmSizes(m, xt, 1, 1);
|
|
UpdateXmmTypes(m, xt, kXmmIntegral, kXmmIntegral);
|
|
break;
|
|
case 0x165: // PCMPGTW
|
|
case 0x175: // PCMPEQW
|
|
case 0x171: // PSRLW,PSRAW,PSLLW
|
|
case 0x1D1: // PSRLW
|
|
case 0x1D5: // PMULLW
|
|
case 0x1D9: // PSUBUSW
|
|
case 0x1DD: // PADDUSW
|
|
case 0x1E1: // PSRAW
|
|
case 0x1E3: // PAVGW
|
|
case 0x1E4: // PMULHUW
|
|
case 0x1E5: // PMULHW
|
|
case 0x1E9: // PSUBSW
|
|
case 0x1EA: // PMINSW
|
|
case 0x1ED: // PADDSW
|
|
case 0x1EE: // PMAXSW
|
|
case 0x1F1: // PSLLW
|
|
case 0x1F6: // PSADBW
|
|
case 0x1F9: // PSUBW
|
|
case 0x1FD: // PADDW
|
|
UpdateXmmSizes(m, xt, 2, 2);
|
|
UpdateXmmTypes(m, xt, kXmmIntegral, kXmmIntegral);
|
|
break;
|
|
case 0x166: // PCMPGTD
|
|
case 0x176: // PCMPEQD
|
|
case 0x172: // PSRLD,PSRAD,PSLLD
|
|
case 0x1D2: // PSRLD
|
|
case 0x1E2: // PSRAD
|
|
case 0x1F2: // PSLLD
|
|
case 0x1FA: // PSUBD
|
|
case 0x1FE: // PADDD
|
|
UpdateXmmSizes(m, xt, 4, 4);
|
|
UpdateXmmTypes(m, xt, kXmmIntegral, kXmmIntegral);
|
|
break;
|
|
case 0x173: // PSRLQ,PSRLQ,PSRLDQ,PSLLQ,PSLLDQ
|
|
case 0x1D3: // PSRLQ
|
|
case 0x1D4: // PADDQ
|
|
case 0x1F3: // PSLLQ
|
|
case 0x1F4: // PMULUDQ
|
|
case 0x1FB: // PSUBQ
|
|
UpdateXmmSizes(m, xt, 8, 8);
|
|
UpdateXmmTypes(m, xt, kXmmIntegral, kXmmIntegral);
|
|
break;
|
|
case 0x16B: // PACKSSDW
|
|
case 0x1F5: // PMADDWD
|
|
UpdateXmmSizes(m, xt, 4, 2);
|
|
UpdateXmmTypes(m, xt, kXmmIntegral, kXmmIntegral);
|
|
break;
|
|
case 0x163: // PACKSSWB
|
|
case 0x167: // PACKUSWB
|
|
UpdateXmmSizes(m, xt, 1, 2);
|
|
UpdateXmmTypes(m, xt, kXmmIntegral, kXmmIntegral);
|
|
break;
|
|
case 0x128: // MOVAPS Vps Wps
|
|
if (IsModrmRegister(m->xedd->op.rde)) {
|
|
xt->type[RexrReg(m->xedd->op.rde)] = xt->type[RexbRm(m->xedd->op.rde)];
|
|
xt->size[RexrReg(m->xedd->op.rde)] = xt->size[RexbRm(m->xedd->op.rde)];
|
|
}
|
|
break;
|
|
case 0x129: // MOVAPS Wps Vps
|
|
if (IsModrmRegister(m->xedd->op.rde)) {
|
|
xt->type[RexbRm(m->xedd->op.rde)] = xt->type[RexrReg(m->xedd->op.rde)];
|
|
xt->size[RexbRm(m->xedd->op.rde)] = xt->size[RexrReg(m->xedd->op.rde)];
|
|
}
|
|
break;
|
|
case 0x16F: // MOVDQA Vdq Wdq
|
|
if (Osz(m->xedd->op.rde) && IsModrmRegister(m->xedd->op.rde)) {
|
|
xt->type[RexrReg(m->xedd->op.rde)] = xt->type[RexbRm(m->xedd->op.rde)];
|
|
xt->size[RexrReg(m->xedd->op.rde)] = xt->size[RexbRm(m->xedd->op.rde)];
|
|
}
|
|
break;
|
|
default:
|
|
return;
|
|
}
|
|
}
|