From 12194b7165201a40a77de478ba2a12c5587bf4fc Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Wed, 10 Dec 2008 03:53:57 -0500 Subject: [PATCH] Fixed relative addressing parsing. --- mojoshader_assembler.c | 64 +++++++++++++++++++++++++++++++----------- 1 file changed, 48 insertions(+), 16 deletions(-) diff --git a/mojoshader_assembler.c b/mojoshader_assembler.c index 13bc7475..79c256b8 100644 --- a/mojoshader_assembler.c +++ b/mojoshader_assembler.c @@ -123,6 +123,15 @@ static inline int shader_is_vertex(const Context *ctx) } // shader_is_vertex +static int ui32fromstr(const char *str, uint32 *ui32) +{ + //*ui32 = (uint32) atoi(minstr); + char *endptr = NULL; + const long val = strtol(str, &endptr, 10); + *ui32 = (uint32) val; + return ((val >= 0) && (*str != '\0') && (*endptr == '\0')); +} // ui32fromstr + static void output_token_noswap(Context *ctx, const uint32 token) { @@ -509,17 +518,34 @@ static int parse_register_name(Context *ctx, RegisterType *rtype, int *rnum) return fail(ctx, "expected register type"); } // else + if (neednum) + { + // cheat the pushback. + const char *origsrc = ctx->source; + const int origonendline = ctx->on_endline; + const int origlinenum = ctx->linenum; + const int origprevchar = ctx->prevchar; + + if (nexttoken(ctx, 0, 1, 1, 1) == FAIL) + return FAIL; + else if (strcmp(ctx->token, "[") == 0) + neednum = 0; + + ctx->source = origsrc; + ctx->on_endline = origonendline; + ctx->linenum = origlinenum; + ctx->prevchar = origprevchar; + } // if + if (neednum) { if (nexttoken(ctx, 0, 0, 0, 0) == FAIL) return FAIL; - //minor = atoi(ctx->token); - char *endptr = NULL; - const long val = strtol(ctx->token, &endptr, 10); - regnum = (int) val; - if ((*ctx->token == '\0') || (*endptr != '\0')) - return fail(ctx, "Invalid version string"); + uint32 ui32 = 0; + if (!ui32fromstr(ctx->token, &ui32)) + return fail(ctx, "Invalid register index"); + regnum = (int) ui32; } // if // split up REG_TYPE_CONST @@ -756,6 +782,22 @@ static int parse_source_token_maybe_relative(Context *ctx, const int relok) return FAIL; retval += rc; relative = 1; + if (nexttoken(ctx, 0, 1, 0, 0) == FAIL) + return FAIL; + else if (strcmp(ctx->token, "+") != 0) + pushback(ctx); + else if (nexttoken(ctx, 0, 1, 0, 0) == FAIL) + return FAIL; + else + { + if (regnum != 0) // !!! FIXME: maybe c3[a0.x + 5] is legal and becomes c[a0.x + 8] ? + fail(ctx, "Relative addressing with explicit register number."); + uint32 ui32 = 0; + if (!ui32fromstr(ctx->token, &ui32)) + return fail(ctx, "Invalid relative addressing offset"); + regnum += (int) ui32; + } // else + if (nexttoken(ctx, 0, 1, 0, 0) == FAIL) return FAIL; else if (strcmp(ctx->token, "]") != 0) @@ -840,16 +882,6 @@ static int parse_args_NULL(Context *ctx) } // parse_args_NULL -static int ui32fromstr(const char *str, uint32 *ui32) -{ - //*ui32 = (uint32) atoi(minstr); - char *endptr = NULL; - const long val = strtol(str, &endptr, 10); - *ui32 = (uint32) val; - return ((val >= 0) && (*str != '\0') && (*endptr == '\0')); -} // ui32fromstr - - static int parse_num(Context *ctx, const int floatok, uint32 *token) { int32 negative = 1;