From 625b28e36a7baa351ec0c8bc7066120e0172f63e Mon Sep 17 00:00:00 2001 From: fincs Date: Wed, 27 Dec 2017 18:06:10 +0100 Subject: [PATCH] Rename a0/a1 index regs to a0.x/a0.y to match D3D naming convention --- Manual.md | 4 ++-- source/picasso_assembler.cpp | 33 +++++++++++++++++---------------- 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/Manual.md b/Manual.md index c69049b..f74b498 100644 --- a/Manual.md +++ b/Manual.md @@ -51,7 +51,7 @@ Registers may also be assigned additional names in order to make the code more l For convenience, registers may be addressed using an offset from a known register. This is called indexing. For example, `c8[4]` is equivalent to `c12`; and `r4[-2]` is equivalent to `r2`. Indexing is useful for addressing arrays of registers (such as matrices). -Some source operands of instructions (called SRC1) support relative addressing. This means that it is possible to use one of the three built-in indexing registers (`a0`, `a1` and `a2` aka `lcnt`) to address a register, e.g. `someArray[lcnt]`. Adding an offset is also supported, e.g. `someArray[lcnt+2]`. This is useful in FOR loops. Index registers can only be used with floating-point vector uniform registers, though. +Some source operands of instructions (called SRC1) support relative addressing. This means that it is possible to use one of the three built-in indexing registers (`a0.x`, `a0.y` and `lcnt`) to address a register, e.g. `someArray[lcnt]`. Adding an offset is also supported, e.g. `someArray[lcnt+2]`. This is useful in FOR loops. Index registers can only be used with floating-point vector uniform registers, though. Note: Older versions of `picasso` called these registers `a0`, `a1` and `a2`; these names are still accepted for backwards compatibility. Normal floating-point vector registers may also be negated by prepending a minus sign before it, e.g. `-r2` or `-someArray[lcnt+2]`. @@ -339,7 +339,7 @@ Syntax | Description - In instructions that take two source operands, the first is wide and the second is narrow. - `dph`/`sge`/`slt` have a special form where the first operand is narrow and the second is wide. This usage is detected automatically by `picasso`. - `mad`, which takes three source operands, has two forms: the first is narrow-wide-narrow, and the second is narrow-narrow-wide. This is also detected automatically. -- `idxReg`: Represents an indexing register to write to using the mova instruction. Can be `a0`, `a1` or `a01` (the latter writes to both `a0` and `a1`). +- `idxReg`: Represents an indexing register to write to using the mova instruction. Can be `a0.x`, `a0.y` or `a0.xy` (the latter writes to both components). Note: Older versions of `picasso` accepted `a0`, `a1` and `a01` respectively; this syntax is still supported for backwards compatibility. - `iReg`: Represents an integer vector uniform source operand. - `bReg`: Represents a boolean uniform source operand. - `procName`: Represents the name of a procedure. diff --git a/source/picasso_assembler.cpp b/source/picasso_assembler.cpp index 89d5abf..8e5ebaf 100644 --- a/source/picasso_assembler.cpp +++ b/source/picasso_assembler.cpp @@ -659,8 +659,8 @@ static inline bool isregp(int x) static inline int convertIdxRegName(const char* reg) { - if (stricmp(reg, "a0")==0) return 1; - if (stricmp(reg, "a1")==0) return 2; + if (stricmp(reg, "a0")==0 || stricmp(reg, "a0.x")==0) return 1; + if (stricmp(reg, "a1")==0 || stricmp(reg, "a0.y")==0) return 2; if (stricmp(reg, "a2")==0 || stricmp(reg, "lcnt")==0) return 3; return 0; } @@ -686,22 +686,15 @@ static int parseReg(char* pos, int& outReg, int& outSw, int* idxType = NULL) pos++; outSw |= 1; // negation bit } - char* dotPos = strchr(pos, '.'); - if (dotPos) - { - *dotPos++ = 0; - outSw = parseSwizzling(dotPos) | (outSw&1); - if (outSw < 0) - return throwError("invalid swizzling mask: %s\n", dotPos); - } int regOffset = 0; char* offPos = strchr(pos, '['); + char* dotPos = pos; if (offPos) { - char* closePos = strchr(offPos, ']'); - if (!closePos) + dotPos = strchr(offPos, ']'); + if (!pos) return throwError("missing closing bracket: %s\n", pos); - *closePos = 0; + *dotPos++ = 0; *offPos++ = 0; offPos = trim_whitespace(offPos); @@ -731,6 +724,14 @@ static int parseReg(char* pos, int& outReg, int& outSw, int* idxType = NULL) if (regOffset < 0) return throwError("invalid register offset: %s\n", offPos); } + dotPos = strchr(dotPos, '.'); + if (dotPos) + { + *dotPos++ = 0; + outSw = parseSwizzling(dotPos) | (outSw&1); + if (outSw < 0) + return throwError("invalid swizzling mask: %s\n", dotPos); + } aliasTableIter it = g_aliases.find(pos); if (it != g_aliases.end()) { @@ -1016,9 +1017,9 @@ DEF_COMMAND(formatmova) ENSURE_NO_MORE_ARGS(); int mask; - if (strcmp(targetReg, "a0")==0) mask = BIT(3); - else if (strcmp(targetReg, "a1")==0) mask = BIT(2); - else if (strcmp(targetReg, "a01")==0) mask = BIT(3) | BIT(2); + if (stricmp(targetReg, "a0")==0 || stricmp(targetReg, "a0.x")==0) mask = BIT(3); + else if (stricmp(targetReg, "a1")==0 || stricmp(targetReg, "a0.y")==0) mask = BIT(2); + else if (stricmp(targetReg, "a01")==0 || stricmp(targetReg, "a0.xy")==0) mask = BIT(3) | BIT(2); else return throwError("invalid destination register for mova: %s\n", targetReg); ARG_TO_SRC1_REG2(rSrc1, src1Name);