Autodetect between inverted and non-inverted versions of opcodes

This commit is contained in:
fincs 2015-08-21 12:41:35 +02:00
parent 556fbe1d82
commit 3eba3a0701

View File

@ -316,8 +316,8 @@ static int missingParam()
typedef struct
{
const char* name;
int (* func) (const char*, int);
int opcode;
int (* func) (const char*, int, int);
int opcode, opcodei;
} cmdTableType;
#define NEXT_ARG(_varName) char* _varName; do \
@ -345,19 +345,23 @@ typedef struct
} while (0)
#define DEF_COMMAND(name) \
static int cmd_##name(const char* cmdName, int opcode)
static int cmd_##name(const char* cmdName, int opcode, int opcodei)
#define DEC_COMMAND(name, fun) \
{ #name, cmd_##fun, MAESTRO_##name }
{ #name, cmd_##fun, MAESTRO_##name, -1 }
#define DEC_COMMAND2(name, fun) \
{ #name, cmd_##fun, MAESTRO_##name, MAESTRO_##name##I }, \
{ #name "i", cmd_##fun, MAESTRO_##name, MAESTRO_##name##I }
#define DEF_DIRECTIVE(name) \
static int dir_##name(const char* cmdName, int dirParam)
static int dir_##name(const char* cmdName, int dirParam, int _unused)
#define DEC_DIRECTIVE(name) \
{ #name, dir_##name, 0 }
{ #name, dir_##name, 0, 0 }
#define DEC_DIRECTIVE2(name, fun, opc) \
{ #name, dir_##fun, opc }
{ #name, dir_##fun, opc, 0 }
static int ensureNoMoreArgs()
{
@ -383,17 +387,24 @@ static inline int ensure_valid_dest(int reg, const char* name)
return 0;
}
static inline int ensure_valid_src1(int reg, const char* name)
static inline int ensure_valid_src_wide(int reg, const char* name, int srcId)
{
if (reg < 0x00 || reg >= 0x80)
return throwError("invalid source1 register: %s\n", name);
return throwError("invalid source%d register: %s\n", srcId, name);
return 0;
}
static inline int ensure_valid_src2(int reg, const char* name)
static inline int ensure_valid_src_narrow(int reg, const char* name, int srcId)
{
if (reg < 0x00 || reg >= 0x20)
return throwError("invalid source2 register: %s\n", name);
return throwError("invalid source%d register: %s\n", srcId, name);
return 0;
}
static inline int ensure_no_idxreg(int idxreg, int srcId)
{
if (idxreg > 0)
return throwError("index register not allowed in source%d\n", srcId);
return 0;
}
@ -445,15 +456,15 @@ static inline int ensure_valid_condop(int condop, const char* name)
#define ARG_TO_SRC1_REG(_reg, _name) \
ARG_TO_REG(_reg, _name); \
safe_call(ensure_valid_src1(_reg, _name))
safe_call(ensure_valid_src_wide(_reg, _name, 1))
#define ARG_TO_SRC1_REG2(_reg, _name) \
ARG_TO_REG2(_reg, _name); \
safe_call(ensure_valid_src1(_reg, _name))
safe_call(ensure_valid_src_wide(_reg, _name, 1))
#define ARG_TO_SRC2_REG(_reg, _name) \
ARG_TO_REG(_reg, _name); \
safe_call(ensure_valid_src2(_reg, _name))
safe_call(ensure_valid_src_narrow(_reg, _name, 2))
#define ARG_TO_IREG(_reg, _name) \
ARG_TO_REG(_reg, _name); \
@ -725,8 +736,22 @@ DEF_COMMAND(format1)
ENSURE_NO_MORE_ARGS();
ARG_TO_DEST_REG(rDest, destName);
ARG_TO_SRC1_REG2(rSrc1, src1Name);
ARG_TO_SRC2_REG(rSrc2, src2Name);
ARG_TO_REG2(rSrc1, src1Name);
ARG_TO_REG2(rSrc2, src2Name);
bool inverted = opcodei >= 0 && rSrc1 < 0x20 && rSrc2 >= 0x20;
if (!inverted)
{
safe_call(ensure_valid_src_wide(rSrc1, src1Name, 1));
safe_call(ensure_valid_src_narrow(rSrc2, src2Name, 2));
safe_call(ensure_no_idxreg(rSrc2Idx, 2));
} else
{
safe_call(ensure_valid_src_narrow(rSrc1, src1Name, 1));
safe_call(ensure_no_idxreg(rSrc1Idx, 1));
safe_call(ensure_valid_src_wide(rSrc2, src2Name, 2));
}
int opdesc = 0;
safe_call(findOrAddOpdesc(opdesc, OPDESC_MAKE(maskFromSwizzling(rDestSw), rSrc1Sw, rSrc2Sw, 0), OPDESC_MASK_D12));
@ -734,29 +759,10 @@ DEF_COMMAND(format1)
#ifdef DEBUG
printf("%s:%02X d%02X, d%02X, d%02X (0x%X)\n", cmdName, opcode, rDest, rSrc1, rSrc2, opdesc);
#endif
BUF.push_back(FMT_OPCODE(opcode) | opdesc | (rSrc2<<7) | (rSrc1<<12) | (rSrc1Idx<<19) | (rDest<<21));
return 0;
}
DEF_COMMAND(format1i)
{
NEXT_ARG(destName);
NEXT_ARG(src1Name);
NEXT_ARG(src2Name);
ENSURE_NO_MORE_ARGS();
ARG_TO_DEST_REG(rDest, destName);
ARG_TO_SRC2_REG(rSrc1, src1Name);
ARG_TO_SRC1_REG2(rSrc2, src2Name);
int opdesc = 0;
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);
#endif
BUF.push_back(FMT_OPCODE(opcode) | opdesc | (rSrc2<<7) | (rSrc1<<14) | (rSrc2Idx<<19) | (rDest<<21));
if (!inverted)
BUF.push_back(FMT_OPCODE(opcode) | opdesc | (rSrc2<<7) | (rSrc1<<12) | (rSrc1Idx<<19) | (rDest<<21));
else
BUF.push_back(FMT_OPCODE(opcodei) | opdesc | (rSrc2<<7) | (rSrc1<<14) | (rSrc2Idx<<19) | (rDest<<21));
return 0;
}
@ -815,8 +821,20 @@ DEF_COMMAND(format5)
ARG_TO_DEST_REG(rDest, destName);
ARG_TO_SRC1_REG(rSrc1, src1Name);
ARG_TO_SRC1_REG(rSrc2, src2Name);
ARG_TO_SRC2_REG(rSrc3, src3Name);
ARG_TO_REG(rSrc2, src2Name);
ARG_TO_REG(rSrc3, src3Name);
bool inverted = opcodei >= 0 && rSrc2 < 0x20 && rSrc3 >= 0x20;
if (!inverted)
{
safe_call(ensure_valid_src_wide(rSrc2, src2Name, 2));
safe_call(ensure_valid_src_narrow(rSrc3, src3Name, 3));
} else
{
safe_call(ensure_valid_src_narrow(rSrc2, src2Name, 2));
safe_call(ensure_valid_src_wide(rSrc3, src3Name, 3));
}
int opdesc = 0;
safe_call(findOrAddOpdesc(opdesc, OPDESC_MAKE(maskFromSwizzling(rDestSw), rSrc1Sw, rSrc2Sw, rSrc3Sw), OPDESC_MASK_D123));
@ -827,34 +845,10 @@ DEF_COMMAND(format5)
#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 | (rSrc3<<5) | (rSrc2<<10) | (rSrc1<<17) | (rDest<<24));
return 0;
}
DEF_COMMAND(format5i)
{
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));
if (opdesc >= 32)
return throwError("opdesc allocation error\n");
#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 | (rSrc3<<5) | (rSrc2<<12) | (rSrc1<<17) | (rDest<<24));
if (!inverted)
BUF.push_back(FMT_OPCODE(opcode) | opdesc | (rSrc3<<5) | (rSrc2<<10) | (rSrc1<<17) | (rDest<<24));
else
BUF.push_back(FMT_OPCODE(opcodei) | opdesc | (rSrc3<<5) | (rSrc2<<12) | (rSrc1<<17) | (rDest<<24));
return 0;
}
@ -1074,17 +1068,13 @@ static const cmdTableType cmdTable[] =
DEC_COMMAND(ADD, format1),
DEC_COMMAND(DP3, format1),
DEC_COMMAND(DP4, format1),
DEC_COMMAND(DPH, format1),
DEC_COMMAND2(DPH, format1),
DEC_COMMAND(MUL, format1),
DEC_COMMAND(SGE, format1),
DEC_COMMAND(SLT, format1),
DEC_COMMAND2(SGE, format1),
DEC_COMMAND2(SLT, format1),
DEC_COMMAND(MAX, format1),
DEC_COMMAND(MIN, format1),
DEC_COMMAND(DPHI, format1i),
DEC_COMMAND(SGEI, format1i),
DEC_COMMAND(SLTI, format1i),
DEC_COMMAND(EX2, format1u),
DEC_COMMAND(LG2, format1u),
DEC_COMMAND(FLR, format1u),
@ -1109,8 +1099,7 @@ static const cmdTableType cmdTable[] =
DEC_COMMAND(IFU, format3),
DEC_COMMAND(JMPU, format3),
DEC_COMMAND(MADI, format5i),
DEC_COMMAND(MAD, format5),
DEC_COMMAND2(MAD, format5),
DEC_COMMAND(SETEMIT, formatsetemit),
@ -1513,7 +1502,7 @@ int ProcessCommand(const char* cmd)
for (int i = 0; table[i].name; i ++)
if (stricmp(table[i].name, cmd) == 0)
return table[i].func(cmd, table[i].opcode);
return table[i].func(cmd, table[i].opcode, table[i].opcodei);
return throwError("invalid instruction: %s\n", cmd);
}