Skip to content

Commit 3eba3a0

Browse files
committed
Autodetect between inverted and non-inverted versions of opcodes
1 parent 556fbe1 commit 3eba3a0

1 file changed

Lines changed: 64 additions & 75 deletions

File tree

source/picasso_assembler.cpp

Lines changed: 64 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -316,8 +316,8 @@ static int missingParam()
316316
typedef struct
317317
{
318318
const char* name;
319-
int (* func) (const char*, int);
320-
int opcode;
319+
int (* func) (const char*, int, int);
320+
int opcode, opcodei;
321321
} cmdTableType;
322322

323323
#define NEXT_ARG(_varName) char* _varName; do \
@@ -345,19 +345,23 @@ typedef struct
345345
} while (0)
346346

347347
#define DEF_COMMAND(name) \
348-
static int cmd_##name(const char* cmdName, int opcode)
348+
static int cmd_##name(const char* cmdName, int opcode, int opcodei)
349349

350350
#define DEC_COMMAND(name, fun) \
351-
{ #name, cmd_##fun, MAESTRO_##name }
351+
{ #name, cmd_##fun, MAESTRO_##name, -1 }
352+
353+
#define DEC_COMMAND2(name, fun) \
354+
{ #name, cmd_##fun, MAESTRO_##name, MAESTRO_##name##I }, \
355+
{ #name "i", cmd_##fun, MAESTRO_##name, MAESTRO_##name##I }
352356

353357
#define DEF_DIRECTIVE(name) \
354-
static int dir_##name(const char* cmdName, int dirParam)
358+
static int dir_##name(const char* cmdName, int dirParam, int _unused)
355359

356360
#define DEC_DIRECTIVE(name) \
357-
{ #name, dir_##name, 0 }
361+
{ #name, dir_##name, 0, 0 }
358362

359363
#define DEC_DIRECTIVE2(name, fun, opc) \
360-
{ #name, dir_##fun, opc }
364+
{ #name, dir_##fun, opc, 0 }
361365

362366
static int ensureNoMoreArgs()
363367
{
@@ -383,17 +387,24 @@ static inline int ensure_valid_dest(int reg, const char* name)
383387
return 0;
384388
}
385389

386-
static inline int ensure_valid_src1(int reg, const char* name)
390+
static inline int ensure_valid_src_wide(int reg, const char* name, int srcId)
387391
{
388392
if (reg < 0x00 || reg >= 0x80)
389-
return throwError("invalid source1 register: %s\n", name);
393+
return throwError("invalid source%d register: %s\n", srcId, name);
390394
return 0;
391395
}
392396

393-
static inline int ensure_valid_src2(int reg, const char* name)
397+
static inline int ensure_valid_src_narrow(int reg, const char* name, int srcId)
394398
{
395399
if (reg < 0x00 || reg >= 0x20)
396-
return throwError("invalid source2 register: %s\n", name);
400+
return throwError("invalid source%d register: %s\n", srcId, name);
401+
return 0;
402+
}
403+
404+
static inline int ensure_no_idxreg(int idxreg, int srcId)
405+
{
406+
if (idxreg > 0)
407+
return throwError("index register not allowed in source%d\n", srcId);
397408
return 0;
398409
}
399410

@@ -445,15 +456,15 @@ static inline int ensure_valid_condop(int condop, const char* name)
445456

446457
#define ARG_TO_SRC1_REG(_reg, _name) \
447458
ARG_TO_REG(_reg, _name); \
448-
safe_call(ensure_valid_src1(_reg, _name))
459+
safe_call(ensure_valid_src_wide(_reg, _name, 1))
449460

450461
#define ARG_TO_SRC1_REG2(_reg, _name) \
451462
ARG_TO_REG2(_reg, _name); \
452-
safe_call(ensure_valid_src1(_reg, _name))
463+
safe_call(ensure_valid_src_wide(_reg, _name, 1))
453464

454465
#define ARG_TO_SRC2_REG(_reg, _name) \
455466
ARG_TO_REG(_reg, _name); \
456-
safe_call(ensure_valid_src2(_reg, _name))
467+
safe_call(ensure_valid_src_narrow(_reg, _name, 2))
457468

458469
#define ARG_TO_IREG(_reg, _name) \
459470
ARG_TO_REG(_reg, _name); \
@@ -725,38 +736,33 @@ DEF_COMMAND(format1)
725736
ENSURE_NO_MORE_ARGS();
726737

727738
ARG_TO_DEST_REG(rDest, destName);
728-
ARG_TO_SRC1_REG2(rSrc1, src1Name);
729-
ARG_TO_SRC2_REG(rSrc2, src2Name);
730-
731-
int opdesc = 0;
732-
safe_call(findOrAddOpdesc(opdesc, OPDESC_MAKE(maskFromSwizzling(rDestSw), rSrc1Sw, rSrc2Sw, 0), OPDESC_MASK_D12));
733-
734-
#ifdef DEBUG
735-
printf("%s:%02X d%02X, d%02X, d%02X (0x%X)\n", cmdName, opcode, rDest, rSrc1, rSrc2, opdesc);
736-
#endif
737-
BUF.push_back(FMT_OPCODE(opcode) | opdesc | (rSrc2<<7) | (rSrc1<<12) | (rSrc1Idx<<19) | (rDest<<21));
739+
ARG_TO_REG2(rSrc1, src1Name);
740+
ARG_TO_REG2(rSrc2, src2Name);
738741

739-
return 0;
740-
}
742+
bool inverted = opcodei >= 0 && rSrc1 < 0x20 && rSrc2 >= 0x20;
741743

742-
DEF_COMMAND(format1i)
743-
{
744-
NEXT_ARG(destName);
745-
NEXT_ARG(src1Name);
746-
NEXT_ARG(src2Name);
747-
ENSURE_NO_MORE_ARGS();
748-
749-
ARG_TO_DEST_REG(rDest, destName);
750-
ARG_TO_SRC2_REG(rSrc1, src1Name);
751-
ARG_TO_SRC1_REG2(rSrc2, src2Name);
744+
if (!inverted)
745+
{
746+
safe_call(ensure_valid_src_wide(rSrc1, src1Name, 1));
747+
safe_call(ensure_valid_src_narrow(rSrc2, src2Name, 2));
748+
safe_call(ensure_no_idxreg(rSrc2Idx, 2));
749+
} else
750+
{
751+
safe_call(ensure_valid_src_narrow(rSrc1, src1Name, 1));
752+
safe_call(ensure_no_idxreg(rSrc1Idx, 1));
753+
safe_call(ensure_valid_src_wide(rSrc2, src2Name, 2));
754+
}
752755

753756
int opdesc = 0;
754757
safe_call(findOrAddOpdesc(opdesc, OPDESC_MAKE(maskFromSwizzling(rDestSw), rSrc1Sw, rSrc2Sw, 0), OPDESC_MASK_D12));
755758

756759
#ifdef DEBUG
757760
printf("%s:%02X d%02X, d%02X, d%02X (0x%X)\n", cmdName, opcode, rDest, rSrc1, rSrc2, opdesc);
758761
#endif
759-
BUF.push_back(FMT_OPCODE(opcode) | opdesc | (rSrc2<<7) | (rSrc1<<14) | (rSrc2Idx<<19) | (rDest<<21));
762+
if (!inverted)
763+
BUF.push_back(FMT_OPCODE(opcode) | opdesc | (rSrc2<<7) | (rSrc1<<12) | (rSrc1Idx<<19) | (rDest<<21));
764+
else
765+
BUF.push_back(FMT_OPCODE(opcodei) | opdesc | (rSrc2<<7) | (rSrc1<<14) | (rSrc2Idx<<19) | (rDest<<21));
760766

761767
return 0;
762768
}
@@ -815,35 +821,20 @@ DEF_COMMAND(format5)
815821

816822
ARG_TO_DEST_REG(rDest, destName);
817823
ARG_TO_SRC1_REG(rSrc1, src1Name);
818-
ARG_TO_SRC1_REG(rSrc2, src2Name);
819-
ARG_TO_SRC2_REG(rSrc3, src3Name);
824+
ARG_TO_REG(rSrc2, src2Name);
825+
ARG_TO_REG(rSrc3, src3Name);
820826

821-
int opdesc = 0;
822-
safe_call(findOrAddOpdesc(opdesc, OPDESC_MAKE(maskFromSwizzling(rDestSw), rSrc1Sw, rSrc2Sw, rSrc3Sw), OPDESC_MASK_D123));
823-
824-
if (opdesc >= 32)
825-
return throwError("opdesc allocation error\n");
826-
827-
#ifdef DEBUG
828-
printf("%s:%02X d%02X, d%02X, d%02X, d%02X (0x%X)\n", cmdName, opcode, rDest, rSrc1, rSrc2, rSrc3, opdesc);
829-
#endif
830-
BUF.push_back(FMT_OPCODE(opcode) | opdesc | (rSrc3<<5) | (rSrc2<<10) | (rSrc1<<17) | (rDest<<24));
831-
832-
return 0;
833-
}
834-
835-
DEF_COMMAND(format5i)
836-
{
837-
NEXT_ARG(destName);
838-
NEXT_ARG(src1Name);
839-
NEXT_ARG(src2Name);
840-
NEXT_ARG(src3Name);
841-
ENSURE_NO_MORE_ARGS();
827+
bool inverted = opcodei >= 0 && rSrc2 < 0x20 && rSrc3 >= 0x20;
842828

843-
ARG_TO_DEST_REG(rDest, destName);
844-
ARG_TO_SRC1_REG(rSrc1, src1Name);
845-
ARG_TO_SRC2_REG(rSrc2, src2Name);
846-
ARG_TO_SRC1_REG(rSrc3, src3Name);
829+
if (!inverted)
830+
{
831+
safe_call(ensure_valid_src_wide(rSrc2, src2Name, 2));
832+
safe_call(ensure_valid_src_narrow(rSrc3, src3Name, 3));
833+
} else
834+
{
835+
safe_call(ensure_valid_src_narrow(rSrc2, src2Name, 2));
836+
safe_call(ensure_valid_src_wide(rSrc3, src3Name, 3));
837+
}
847838

848839
int opdesc = 0;
849840
safe_call(findOrAddOpdesc(opdesc, OPDESC_MAKE(maskFromSwizzling(rDestSw), rSrc1Sw, rSrc2Sw, rSrc3Sw), OPDESC_MASK_D123));
@@ -854,7 +845,10 @@ DEF_COMMAND(format5i)
854845
#ifdef DEBUG
855846
printf("%s:%02X d%02X, d%02X, d%02X, d%02X (0x%X)\n", cmdName, opcode, rDest, rSrc1, rSrc2, rSrc3, opdesc);
856847
#endif
857-
BUF.push_back(FMT_OPCODE(opcode) | opdesc | (rSrc3<<5) | (rSrc2<<12) | (rSrc1<<17) | (rDest<<24));
848+
if (!inverted)
849+
BUF.push_back(FMT_OPCODE(opcode) | opdesc | (rSrc3<<5) | (rSrc2<<10) | (rSrc1<<17) | (rDest<<24));
850+
else
851+
BUF.push_back(FMT_OPCODE(opcodei) | opdesc | (rSrc3<<5) | (rSrc2<<12) | (rSrc1<<17) | (rDest<<24));
858852

859853
return 0;
860854
}
@@ -1074,17 +1068,13 @@ static const cmdTableType cmdTable[] =
10741068
DEC_COMMAND(ADD, format1),
10751069
DEC_COMMAND(DP3, format1),
10761070
DEC_COMMAND(DP4, format1),
1077-
DEC_COMMAND(DPH, format1),
1071+
DEC_COMMAND2(DPH, format1),
10781072
DEC_COMMAND(MUL, format1),
1079-
DEC_COMMAND(SGE, format1),
1080-
DEC_COMMAND(SLT, format1),
1073+
DEC_COMMAND2(SGE, format1),
1074+
DEC_COMMAND2(SLT, format1),
10811075
DEC_COMMAND(MAX, format1),
10821076
DEC_COMMAND(MIN, format1),
10831077

1084-
DEC_COMMAND(DPHI, format1i),
1085-
DEC_COMMAND(SGEI, format1i),
1086-
DEC_COMMAND(SLTI, format1i),
1087-
10881078
DEC_COMMAND(EX2, format1u),
10891079
DEC_COMMAND(LG2, format1u),
10901080
DEC_COMMAND(FLR, format1u),
@@ -1109,8 +1099,7 @@ static const cmdTableType cmdTable[] =
11091099
DEC_COMMAND(IFU, format3),
11101100
DEC_COMMAND(JMPU, format3),
11111101

1112-
DEC_COMMAND(MADI, format5i),
1113-
DEC_COMMAND(MAD, format5),
1102+
DEC_COMMAND2(MAD, format5),
11141103

11151104
DEC_COMMAND(SETEMIT, formatsetemit),
11161105

@@ -1513,7 +1502,7 @@ int ProcessCommand(const char* cmd)
15131502

15141503
for (int i = 0; table[i].name; i ++)
15151504
if (stricmp(table[i].name, cmd) == 0)
1516-
return table[i].func(cmd, table[i].opcode);
1505+
return table[i].func(cmd, table[i].opcode, table[i].opcodei);
15171506

15181507
return throwError("invalid instruction: %s\n", cmd);
15191508
}

0 commit comments

Comments
 (0)