Add ARL & support for relative indexing, e.g: someArray[lcnt+1]
This commit is contained in:
parent
d5c6748e0f
commit
07099be5bb
@ -12,7 +12,8 @@ enum
|
|||||||
MAESTRO_RCP,
|
MAESTRO_RCP,
|
||||||
MAESTRO_RSQ,
|
MAESTRO_RSQ,
|
||||||
|
|
||||||
MAESTRO_MOV = 0x13,
|
MAESTRO_ARL = 0x12,
|
||||||
|
MAESTRO_MOV,
|
||||||
|
|
||||||
MAESTRO_NOP = 0x21,
|
MAESTRO_NOP = 0x21,
|
||||||
MAESTRO_END,
|
MAESTRO_END,
|
||||||
|
@ -308,6 +308,10 @@ static int ensure_valid_src2(int reg, const char* name)
|
|||||||
int _varName = 0, _varName##Sw = 0; \
|
int _varName = 0, _varName##Sw = 0; \
|
||||||
safe_call(parseReg(_argName, _varName, _varName##Sw));
|
safe_call(parseReg(_argName, _varName, _varName##Sw));
|
||||||
|
|
||||||
|
#define ARG_TO_REG2(_varName, _argName) \
|
||||||
|
int _varName = 0, _varName##Sw = 0, _varName##Idx = 0; \
|
||||||
|
safe_call(parseReg(_argName, _varName, _varName##Sw, &_varName##Idx));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
#define ARG_LABEL(_argName) \
|
#define ARG_LABEL(_argName) \
|
||||||
safe_call(ensureLabel(_argName))
|
safe_call(ensureLabel(_argName))
|
||||||
@ -321,6 +325,10 @@ static int ensure_valid_src2(int reg, const char* name)
|
|||||||
ARG_TO_REG(_reg, _name); \
|
ARG_TO_REG(_reg, _name); \
|
||||||
safe_call(ensure_valid_src1(_reg, _name))
|
safe_call(ensure_valid_src1(_reg, _name))
|
||||||
|
|
||||||
|
#define ARG_TO_SRC1_REG2(_reg, _name) \
|
||||||
|
ARG_TO_REG2(_reg, _name); \
|
||||||
|
safe_call(ensure_valid_src1(_reg, _name))
|
||||||
|
|
||||||
#define ARG_TO_SRC2_REG(_reg, _name) \
|
#define ARG_TO_SRC2_REG(_reg, _name) \
|
||||||
ARG_TO_REG(_reg, _name); \
|
ARG_TO_REG(_reg, _name); \
|
||||||
safe_call(ensure_valid_src2(_reg, _name))
|
safe_call(ensure_valid_src2(_reg, _name))
|
||||||
@ -385,10 +393,19 @@ static inline bool isregp(int x)
|
|||||||
return x=='o' || x=='v' || x=='r' || x=='c';
|
return x=='o' || x=='v' || x=='r' || x=='c';
|
||||||
}
|
}
|
||||||
|
|
||||||
static int parseReg(char* pos, int& outReg, int& outSw)
|
static inline int convertIdxRegName(const char* reg)
|
||||||
|
{
|
||||||
|
if (stricmp(reg, "a0")==0) return 1;
|
||||||
|
if (stricmp(reg, "a1")==0) return 2;
|
||||||
|
if (stricmp(reg, "a2")==0 || stricmp(reg, "lcnt")==0) return 2;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int parseReg(char* pos, int& outReg, int& outSw, int* idxType = nullptr)
|
||||||
{
|
{
|
||||||
outReg = 0;
|
outReg = 0;
|
||||||
outSw = DEFAULT_OPSRC;
|
outSw = DEFAULT_OPSRC;
|
||||||
|
if (idxType) *idxType = 0;
|
||||||
if (*pos == '-')
|
if (*pos == '-')
|
||||||
{
|
{
|
||||||
pos++;
|
pos++;
|
||||||
@ -412,7 +429,29 @@ static int parseReg(char* pos, int& outReg, int& outSw)
|
|||||||
*closePos = 0;
|
*closePos = 0;
|
||||||
*offPos++ = 0;
|
*offPos++ = 0;
|
||||||
offPos = trim_whitespace(offPos);
|
offPos = trim_whitespace(offPos);
|
||||||
// TODO: support (idx1[+n]), (idx2[+n]), (lcnt[+n])
|
|
||||||
|
// Check for idxreg+offset
|
||||||
|
int temp = convertIdxRegName(offPos);
|
||||||
|
if (temp>0)
|
||||||
|
{
|
||||||
|
if (!idxType)
|
||||||
|
return throwError("index register not allowed here: %s\n", offPos);
|
||||||
|
*idxType = temp;
|
||||||
|
} else do
|
||||||
|
{
|
||||||
|
auto plusPos = strchr(offPos, '+');
|
||||||
|
if (!plusPos)
|
||||||
|
break;
|
||||||
|
if (!idxType)
|
||||||
|
return throwError("index register not allowed here: %s\n", offPos);
|
||||||
|
*plusPos++ = 0;
|
||||||
|
auto idxRegName = trim_whitespace(offPos);
|
||||||
|
offPos = trim_whitespace(plusPos);
|
||||||
|
*idxType = convertIdxRegName(idxRegName);
|
||||||
|
if (*idxType < 0)
|
||||||
|
return throwError("invalid index register: %s\n", idxRegName);
|
||||||
|
} while (0);
|
||||||
|
|
||||||
regOffset = atoi(offPos);
|
regOffset = atoi(offPos);
|
||||||
if (regOffset < 0)
|
if (regOffset < 0)
|
||||||
return throwError("invalid register offset: %s\n", offPos);
|
return throwError("invalid register offset: %s\n", offPos);
|
||||||
@ -479,7 +518,7 @@ DEF_COMMAND(format1)
|
|||||||
ENSURE_NO_MORE_ARGS();
|
ENSURE_NO_MORE_ARGS();
|
||||||
|
|
||||||
ARG_TO_DEST_REG(rDest, destName);
|
ARG_TO_DEST_REG(rDest, destName);
|
||||||
ARG_TO_SRC1_REG(rSrc1, src1Name);
|
ARG_TO_SRC1_REG2(rSrc1, src1Name);
|
||||||
ARG_TO_SRC2_REG(rSrc2, src2Name);
|
ARG_TO_SRC2_REG(rSrc2, src2Name);
|
||||||
|
|
||||||
int opdesc = 0;
|
int opdesc = 0;
|
||||||
@ -488,7 +527,7 @@ DEF_COMMAND(format1)
|
|||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf("%s:%02X d%02X, d%02X, d%02X (0x%X)\n", cmdName, opcode, rDest, rSrc1, rSrc2, opdesc);
|
printf("%s:%02X d%02X, d%02X, d%02X (0x%X)\n", cmdName, opcode, rDest, rSrc1, rSrc2, opdesc);
|
||||||
#endif
|
#endif
|
||||||
BUF.push_back(FMT_OPCODE(opcode) | opdesc | (rSrc2<<7) | (rSrc1<<12) | (rDest<<21));
|
BUF.push_back(FMT_OPCODE(opcode) | opdesc | (rSrc2<<7) | (rSrc1<<12) | (rSrc1Idx<<19) | (rDest<<21));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -500,7 +539,7 @@ DEF_COMMAND(format2)
|
|||||||
ENSURE_NO_MORE_ARGS();
|
ENSURE_NO_MORE_ARGS();
|
||||||
|
|
||||||
ARG_TO_DEST_REG(rDest, destName);
|
ARG_TO_DEST_REG(rDest, destName);
|
||||||
ARG_TO_SRC1_REG(rSrc1, src1Name);
|
ARG_TO_SRC1_REG2(rSrc1, src1Name);
|
||||||
|
|
||||||
int opdesc = 0;
|
int opdesc = 0;
|
||||||
safe_call(findOrAddOpdesc(opdesc, OPDESC_MAKE(maskFromSwizzling(rDestSw), rSrc1Sw, 0, 0), OPDESC_MASK_D1));
|
safe_call(findOrAddOpdesc(opdesc, OPDESC_MAKE(maskFromSwizzling(rDestSw), rSrc1Sw, 0, 0), OPDESC_MASK_D1));
|
||||||
@ -508,7 +547,7 @@ DEF_COMMAND(format2)
|
|||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf("%s:%02X d%02X, d%02X (0x%X)\n", cmdName, opcode, rDest, rSrc1, opdesc);
|
printf("%s:%02X d%02X, d%02X (0x%X)\n", cmdName, opcode, rDest, rSrc1, opdesc);
|
||||||
#endif
|
#endif
|
||||||
BUF.push_back(FMT_OPCODE(opcode) | opdesc | (rSrc1<<12) | (rDest<<21));
|
BUF.push_back(FMT_OPCODE(opcode) | opdesc | (rSrc1<<12) | (rSrc1Idx<<19) | (rDest<<21));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -540,6 +579,24 @@ DEF_COMMAND(format3)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEF_COMMAND(format4)
|
||||||
|
{
|
||||||
|
NEXT_ARG(src1Name);
|
||||||
|
ENSURE_NO_MORE_ARGS();
|
||||||
|
|
||||||
|
ARG_TO_SRC1_REG2(rSrc1, src1Name);
|
||||||
|
|
||||||
|
int opdesc = 0;
|
||||||
|
safe_call(findOrAddOpdesc(opdesc, OPDESC_MAKE(0, rSrc1Sw, 0, 0), OPDESC_MASK_1));
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf("%s:%02X d%02X (0x%X)\n", cmdName, opcode, rSrc1, opdesc);
|
||||||
|
#endif
|
||||||
|
BUF.push_back(FMT_OPCODE(opcode) | opdesc | (rSrc1<<12) | (rSrc1Idx<<19));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static const cmdTableType cmdTable[] =
|
static const cmdTableType cmdTable[] =
|
||||||
{
|
{
|
||||||
DEC_COMMAND(NOP, format0),
|
DEC_COMMAND(NOP, format0),
|
||||||
@ -558,6 +615,8 @@ static const cmdTableType cmdTable[] =
|
|||||||
|
|
||||||
DEC_COMMAND(MAD, format3),
|
DEC_COMMAND(MAD, format3),
|
||||||
|
|
||||||
|
DEC_COMMAND(ARL, format4),
|
||||||
|
|
||||||
{ nullptr, nullptr },
|
{ nullptr, nullptr },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -71,8 +71,10 @@ int main(int argc, char* argv[])
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//if (g_opdescCount > 9)
|
if (g_constantCount > 9)
|
||||||
// printf("WARNING: currently using more than 9 opdescs -- libctru has a bug\n");
|
fprintf(stderr, "WARNING: ctrulib currently has a bug when using more than 1 constant\n");
|
||||||
|
if (g_opdescCount > 9)
|
||||||
|
fprintf(stderr, "WARNING: ctrulib currently has a bug when using more than 9 opdescs\n");
|
||||||
|
|
||||||
FileClass f(shbinFile, "wb");
|
FileClass f(shbinFile, "wb");
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user