Add support for the MAD opcode

This commit is contained in:
fincs 2014-11-16 23:04:51 +01:00
parent e47de22f60
commit f5e312392b
3 changed files with 36 additions and 7 deletions

View File

@ -28,4 +28,6 @@ enum
MAESTRO_CMP = 0x2E,
MAESTRO_CMP2, // ???
MAESTRO_MAD = 0x38, // only the upper 3 bits are used for the opcode
};

View File

@ -29,16 +29,17 @@ enum
#define SWIZZLE_COMP(n,v) ((v) << (6-(n)*2))
#define OPSRC_MAKE(neg, sw) ((neg) | ((sw) << 1))
#define OPDESC_MAKE(out, src1, src2) ((out) | ((src1) << 4) | ((src2) << (4+9)))
#define OPDESC_MAKE(out, src1, src2, src3) ((out) | ((src1) << 4) | ((src2) << (4+9)) | ((src3) << (4+9*2)))
#define FMT_OPCODE(n) ((n)<<26)
#define OUTPUT_MAKE(i, reg, mask) ((i) | ((reg)<<16) | ((u64)(mask)<<32))
#define DEFAULT_SWIZZLE (SWIZZLE_COMP(0,COMP_X) | SWIZZLE_COMP(1,COMP_Y) | SWIZZLE_COMP(2,COMP_Z) | SWIZZLE_COMP(3,COMP_W))
#define DEFAULT_OPSRC OPSRC_MAKE(0, DEFAULT_SWIZZLE)
#define OPDESC_MASK_ALL OPDESC_MAKE(0xF, 0x1FF, 0x1FF)
#define OPDESC_MASK_NOSRC2 OPDESC_MAKE(0xF, 0x1FF, 0)
#define OPDESC_MASK_ONLYSRC1 OPDESC_MAKE(0, 0x1FF, 0)
#define OPDESC_MASK_D123 OPDESC_MAKE(0xF, 0x1FF, 0x1FF, 0x1FF)
#define OPDESC_MASK_D12 OPDESC_MAKE(0xF, 0x1FF, 0x1FF, 0)
#define OPDESC_MASK_D1 OPDESC_MAKE(0xF, 0x1FF, 0, 0)
#define OPDESC_MASK_1 OPDESC_MAKE(0, 0x1FF, 0, 0)
extern std::vector<u32> g_outputBuf;

View File

@ -352,7 +352,7 @@ static int maskFromSwizzling(int sw)
return out;
}
static int findOrAddOpdesc(int& out, int opdesc, int mask = OPDESC_MASK_ALL)
static int findOrAddOpdesc(int& out, int opdesc, int mask)
{
for (int i = 0; i < g_opdescCount; i ++)
{
@ -478,7 +478,7 @@ DEF_COMMAND(format1)
ARG_TO_SRC2_REG(rSrc2, src2Name);
int opdesc = 0;
safe_call(findOrAddOpdesc(opdesc, OPDESC_MAKE(maskFromSwizzling(rDestSw), rSrc1Sw, rSrc2Sw)));
safe_call(findOrAddOpdesc(opdesc, OPDESC_MAKE(maskFromSwizzling(rDestSw), rSrc1Sw, rSrc2Sw, 0), OPDESC_MASK_D12));
#ifdef DEBUG
printf("%s:%02X d%02X, d%02X, d%02X (0x%X)\n", cmdName, opcode, rDest, rSrc1, rSrc2, opdesc);
@ -498,7 +498,7 @@ DEF_COMMAND(format2)
ARG_TO_SRC1_REG(rSrc1, src1Name);
int opdesc = 0;
safe_call(findOrAddOpdesc(opdesc, OPDESC_MAKE(maskFromSwizzling(rDestSw), rSrc1Sw, 0), OPDESC_MASK_NOSRC2));
safe_call(findOrAddOpdesc(opdesc, OPDESC_MAKE(maskFromSwizzling(rDestSw), rSrc1Sw, 0, 0), OPDESC_MASK_D1));
#ifdef DEBUG
printf("%s:%02X d%02X, d%02X (0x%X)\n", cmdName, opcode, rDest, rSrc1, opdesc);
@ -508,6 +508,30 @@ DEF_COMMAND(format2)
return 0;
}
DEF_COMMAND(format3)
{
NEXT_ARG(destName);
NEXT_ARG(src1Name);
NEXT_ARG(src2Name);
NEXT_ARG(src3Name);
ENSURE_NO_MORE_ARGS();
ARG_TO_DEST_REG(rDest, destName);
ARG_TO_SRC1_REG(rSrc1, src1Name);
ARG_TO_SRC2_REG(rSrc2, src2Name);
ARG_TO_SRC1_REG(rSrc3, src3Name);
int opdesc = 0;
safe_call(findOrAddOpdesc(opdesc, OPDESC_MAKE(maskFromSwizzling(rDestSw), rSrc1Sw, rSrc2Sw, rSrc3Sw), OPDESC_MASK_D123));
#ifdef DEBUG
printf("%s:%02X d%02X, d%02X, d%02X, d%02X (0x%X)\n", cmdName, opcode, rDest, rSrc1, rSrc2, rSrc3, opdesc);
#endif
BUF.push_back(FMT_OPCODE(opcode) | opdesc | (rSrc2<<5) | (rSrc1<<10) | (rSrc3<<17) | (rDest<<24));
return 0;
}
static const cmdTableType cmdTable[] =
{
DEC_COMMAND(NOP, format0),
@ -524,6 +548,8 @@ static const cmdTableType cmdTable[] =
DEC_COMMAND(RSQ, format2),
DEC_COMMAND(MOV, format2),
DEC_COMMAND(MAD, format3),
{ nullptr, nullptr },
};