From 07099be5bbb33326b992a0520f88bc953b9ca04f Mon Sep 17 00:00:00 2001 From: fincs Date: Wed, 19 Nov 2014 18:28:41 +0100 Subject: [PATCH] Add ARL & support for relative indexing, e.g: someArray[lcnt+1] --- source/maestro_opcodes.h | 3 +- source/picasso_assembler.cpp | 71 +++++++++++++++++++++++++++++++++--- source/picasso_frontend.cpp | 6 ++- 3 files changed, 71 insertions(+), 9 deletions(-) diff --git a/source/maestro_opcodes.h b/source/maestro_opcodes.h index 6dbe290..eb895d6 100644 --- a/source/maestro_opcodes.h +++ b/source/maestro_opcodes.h @@ -12,7 +12,8 @@ enum MAESTRO_RCP, MAESTRO_RSQ, - MAESTRO_MOV = 0x13, + MAESTRO_ARL = 0x12, + MAESTRO_MOV, MAESTRO_NOP = 0x21, MAESTRO_END, diff --git a/source/picasso_assembler.cpp b/source/picasso_assembler.cpp index 6372422..27fa54c 100644 --- a/source/picasso_assembler.cpp +++ b/source/picasso_assembler.cpp @@ -308,6 +308,10 @@ static int ensure_valid_src2(int reg, const char* name) int _varName = 0, _varName##Sw = 0; \ 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) \ safe_call(ensureLabel(_argName)) @@ -321,6 +325,10 @@ static int ensure_valid_src2(int reg, const char* name) ARG_TO_REG(_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) \ ARG_TO_REG(_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'; } -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; outSw = DEFAULT_OPSRC; + if (idxType) *idxType = 0; if (*pos == '-') { pos++; @@ -412,7 +429,29 @@ static int parseReg(char* pos, int& outReg, int& outSw) *closePos = 0; *offPos++ = 0; 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); if (regOffset < 0) return throwError("invalid register offset: %s\n", offPos); @@ -479,7 +518,7 @@ DEF_COMMAND(format1) ENSURE_NO_MORE_ARGS(); ARG_TO_DEST_REG(rDest, destName); - ARG_TO_SRC1_REG(rSrc1, src1Name); + ARG_TO_SRC1_REG2(rSrc1, src1Name); ARG_TO_SRC2_REG(rSrc2, src2Name); int opdesc = 0; @@ -488,7 +527,7 @@ 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) | (rDest<<21)); + BUF.push_back(FMT_OPCODE(opcode) | opdesc | (rSrc2<<7) | (rSrc1<<12) | (rSrc1Idx<<19) | (rDest<<21)); return 0; } @@ -500,7 +539,7 @@ DEF_COMMAND(format2) ENSURE_NO_MORE_ARGS(); ARG_TO_DEST_REG(rDest, destName); - ARG_TO_SRC1_REG(rSrc1, src1Name); + ARG_TO_SRC1_REG2(rSrc1, src1Name); int opdesc = 0; safe_call(findOrAddOpdesc(opdesc, OPDESC_MAKE(maskFromSwizzling(rDestSw), rSrc1Sw, 0, 0), OPDESC_MASK_D1)); @@ -508,7 +547,7 @@ DEF_COMMAND(format2) #ifdef DEBUG printf("%s:%02X d%02X, d%02X (0x%X)\n", cmdName, opcode, rDest, rSrc1, opdesc); #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; } @@ -540,6 +579,24 @@ DEF_COMMAND(format3) 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[] = { DEC_COMMAND(NOP, format0), @@ -558,6 +615,8 @@ static const cmdTableType cmdTable[] = DEC_COMMAND(MAD, format3), + DEC_COMMAND(ARL, format4), + { nullptr, nullptr }, }; diff --git a/source/picasso_frontend.cpp b/source/picasso_frontend.cpp index b7dd8f6..94eca68 100644 --- a/source/picasso_frontend.cpp +++ b/source/picasso_frontend.cpp @@ -71,8 +71,10 @@ int main(int argc, char* argv[]) return 1; } - //if (g_opdescCount > 9) - // printf("WARNING: currently using more than 9 opdescs -- libctru has a bug\n"); + if (g_constantCount > 9) + 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");