mojoshader_assembler.c
author Ryan C. Gordon <icculus@icculus.org>
Mon, 08 Dec 2008 05:12:54 -0500
changeset 470 7d84d3452125
parent 465 0a75f98f785b
child 472 e52d487e6d91
permissions -rw-r--r--
Bunch More Work on the assembler.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
     1
/**
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
     2
 * MojoShader; generate shader programs from bytecode of compiled
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
     3
 *  Direct3D shaders.
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
     4
 *
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
     5
 * Please see the file LICENSE.txt in the source's root directory.
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
     6
 *
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
     7
 *  This file written by Ryan C. Gordon.
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
     8
 */
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
     9
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    10
#define __MOJOSHADER_INTERNAL__ 1
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    11
#include "mojoshader_internal.h"
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    12
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    13
#define DEBUG_TOKENIZER 1
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    14
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    15
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    16
typedef struct Context Context;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    17
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    18
// Context...this is state that changes as we assemble a shader...
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    19
struct Context
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    20
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    21
    MOJOSHADER_malloc malloc;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    22
    MOJOSHADER_free free;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    23
    void *malloc_data;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    24
    const char *failstr;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    25
    const char *source;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    26
    MOJOSHADER_shaderType shader_type;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    27
    uint8 major_ver;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    28
    uint8 minor_ver;
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
    29
    int on_endline;
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    30
    unsigned int linenum;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    31
    char prevchar;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    32
    char token[64];
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    33
    char pushedback;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    34
    char pushback_token[64];
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    35
    uint32 tokenbuf[16];
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    36
    int tokenbufpos;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    37
    DestArgInfo dest_arg;
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
    38
    uint32 *output;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
    39
    size_t output_len;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
    40
    size_t output_allocation;
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    41
};
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    42
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    43
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    44
// Convenience functions for allocators...
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    45
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    46
static inline int out_of_memory(Context *ctx)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    47
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    48
    if (ctx->failstr == NULL)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    49
        ctx->failstr = out_of_mem_str;  // fail() would call malloc().
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    50
    return FAIL;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    51
} // out_of_memory
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    52
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    53
static inline void *Malloc(Context *ctx, const size_t len)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    54
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    55
    void *retval = ctx->malloc((int) len, ctx->malloc_data);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    56
    if (retval == NULL)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    57
        out_of_memory(ctx);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    58
    return retval;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    59
} // Malloc
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    60
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    61
static inline void Free(Context *ctx, void *ptr)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    62
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    63
    if (ptr != NULL)  // check for NULL in case of dumb free() impl.
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    64
        ctx->free(ptr, ctx->malloc_data);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    65
} // Free
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    66
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    67
static int failf(Context *ctx, const char *fmt, ...) ISPRINTF(2,3);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    68
static int failf(Context *ctx, const char *fmt, ...)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    69
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    70
    if (ctx->failstr == NULL)  // don't change existing error.
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    71
    {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    72
        char scratch = 0;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    73
        va_list ap;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    74
        va_start(ap, fmt);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    75
        const int len = vsnprintf(&scratch, sizeof (scratch), fmt, ap);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    76
        va_end(ap);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    77
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    78
        char *failstr = (char *) Malloc(ctx, len + 1);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    79
        if (failstr != NULL)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    80
        {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    81
            va_start(ap, fmt);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    82
            vsnprintf(failstr, len + 1, fmt, ap);  // rebuild it.
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    83
            va_end(ap);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    84
            ctx->failstr = failstr;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    85
        } // if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    86
    } // if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    87
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    88
    return FAIL;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    89
} // failf
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    90
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    91
static inline int fail(Context *ctx, const char *reason)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    92
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    93
    return failf(ctx, "%s", reason);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    94
} // fail
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    95
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    96
static inline int isfail(const Context *ctx)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    97
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    98
    return (ctx->failstr != NULL);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    99
} // isfail
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   100
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   101
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   102
// Shader model version magic...
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   103
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   104
static inline uint32 ver_ui32(const uint8 major, const uint8 minor)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   105
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   106
    return ( (((uint32) major) << 16) | (((minor) == 0xFF) ? 0 : (minor)) );
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   107
} // version_ui32
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   108
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   109
static inline int shader_version_atleast(const Context *ctx, const uint8 maj,
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   110
                                         const uint8 min)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   111
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   112
    return (ver_ui32(ctx->major_ver, ctx->minor_ver) >= ver_ui32(maj, min));
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   113
} // shader_version_atleast
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   114
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   115
static inline int shader_is_pixel(const Context *ctx)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   116
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   117
    return (ctx->shader_type == MOJOSHADER_TYPE_PIXEL);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   118
} // shader_is_pixel
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   119
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   120
static inline int shader_is_vertex(const Context *ctx)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   121
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   122
    return (ctx->shader_type == MOJOSHADER_TYPE_VERTEX);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   123
} // shader_is_vertex
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   124
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   125
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   126
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   127
static void output_token_noswap(Context *ctx, const uint32 token)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   128
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   129
    if (isfail(ctx))
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   130
        return;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   131
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   132
    if (ctx->output_len >= ctx->output_allocation)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   133
    {
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   134
        const size_t output_alloc_bump = 1024;  // that's tokens, not bytes.
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   135
        const size_t newsize = ctx->output_allocation + output_alloc_bump;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   136
        void *ptr = Malloc(ctx, newsize * sizeof (uint32));
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   137
        if (ptr == NULL)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   138
            return;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   139
        if (ctx->output_len > 0)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   140
            memcpy(ptr, ctx->output, ctx->output_len * sizeof (uint32));
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   141
        Free(ctx, ctx->output);
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   142
        ctx->output_allocation = newsize;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   143
        ctx->output = (uint32 *) ptr;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   144
    } // if
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   145
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   146
    ctx->output[ctx->output_len++] = token;
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   147
} // output_token_noswap
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   148
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   149
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   150
static inline void output_token(Context *ctx, const uint32 token)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   151
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   152
    output_token_noswap(ctx, SWAP32(token));
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   153
} // output_token
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   154
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   155
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   156
static void output_comment_bytes(Context *ctx, const uint8 *buf, size_t len)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   157
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   158
    if (len > (0xFFFF * 4))  // length is stored as token count, in 16 bits.
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   159
        fail(ctx, "Comment field is too big");
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   160
    else if (!isfail(ctx))
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   161
    {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   162
        const uint32 tokencount = (len / 4) + ((len % 4) ? 1 : 0);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   163
        output_token(ctx, 0xFFFE | (tokencount << 16));
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   164
        while (len >= 4)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   165
        {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   166
            output_token_noswap(ctx, *((const uint32 *) buf));
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   167
            len -= 4;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   168
            buf += 4;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   169
        } // while
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   170
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   171
        if (len > 0)  // handle spillover...
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   172
        {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   173
            union { uint8 ui8[4]; uint32 ui32; } overflow;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   174
            overflow.ui32 = 0;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   175
            memcpy(overflow.ui8, buf, len);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   176
            output_token_noswap(ctx, overflow.ui32);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   177
        } // if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   178
    } // else if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   179
} // output_comment_bytes
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   180
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   181
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   182
static inline void output_comment_string(Context *ctx, const char *str)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   183
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   184
    output_comment_bytes(ctx, (const uint8 *) str, strlen(str));
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   185
} // output_comment_string
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   186
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   187
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   188
static int _tokenize(Context *ctx)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   189
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   190
    int idx = 0;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   191
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   192
    if (isfail(ctx))
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   193
        return FAIL;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   194
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   195
    if (ctx->pushedback)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   196
    {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   197
        ctx->pushedback = 0;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   198
        return NOFAIL;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   199
    } // if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   200
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   201
    if (ctx->on_endline)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   202
    {
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   203
        ctx->on_endline = 0;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   204
        ctx->linenum++;  // passed a newline, update.
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   205
    } // if
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   206
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   207
    while (1)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   208
    {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   209
        if (idx >= sizeof (ctx->token))
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   210
            return fail(ctx, "buffer overflow");
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   211
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   212
        char ch = *ctx->source;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   213
        if (ch == '\t')
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   214
            ch = ' ';  // collapse tabs into single spaces.
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   215
        else if (ch == '\r')
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   216
        {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   217
            if (ctx->source[1] == '\n')
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   218
               continue;  // ignore '\r' if this is "\r\n" ...
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   219
            ch = '\n';
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   220
        } // else if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   221
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   222
        if ((ch > '0') && (ch < '9'))
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   223
        {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   224
            // starting a number, but rest of current token was not number.
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   225
            if ((idx > 0) && ((ctx->prevchar < '0') || (ctx->prevchar > '9')))
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   226
            {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   227
                ctx->token[idx++] = '\0';
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   228
                return NOFAIL;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   229
            } // if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   230
        } // if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   231
        else
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   232
        {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   233
            // starting a non-number, but rest of current token was numbers.
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   234
            if ((idx > 0) && ((ctx->prevchar >= '0') || (ctx->prevchar <= '9')))
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   235
            {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   236
                ctx->token[idx++] = '\0';
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   237
                return NOFAIL;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   238
            } // if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   239
        } // else
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   240
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   241
        switch (ch)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   242
        {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   243
            case '/':
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   244
            case ';':  // !!! FIXME: comment, right?
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   245
                if (idx != 0)  // finish off existing token.
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   246
                    ctx->token[idx] = '\0';
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   247
                else
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   248
                {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   249
                    ctx->token[idx++] = ch;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   250
                    ctx->source++;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   251
                    if ((ch == '/') && (ctx->source[1] == '/'))
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   252
                    {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   253
                        ctx->token[idx++] = '/';
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   254
                        ctx->source++;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   255
                    } // if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   256
                    ctx->token[idx++] = '\0';
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   257
                } // else
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   258
                return NOFAIL;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   259
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   260
            case ' ':
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   261
                if (ctx->prevchar == ' ')
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   262
                    break;   // multiple whitespace collapses into one.
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   263
                // intentional fall-through...
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   264
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   265
            case '_':
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   266
            case '[':
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   267
            case ']':
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   268
            case '(':
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   269
            case ')':
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   270
            case '!':
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   271
            case '+':
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   272
            case '-':
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   273
            case ',':
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   274
            case '.':
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   275
            case '\n':
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   276
                if (idx != 0)  // finish off existing token.
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   277
                    ctx->token[idx] = '\0';
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   278
                else  // this is a token in itself.
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   279
                {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   280
                    if (ch == '\n')
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   281
                        ctx->on_endline = 1;
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   282
                    ctx->source++;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   283
                    ctx->token[idx++] = ch;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   284
                    ctx->token[idx++] = '\0';
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   285
                } // else
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   286
                return NOFAIL;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   287
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   288
            case '\0':
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   289
                ctx->token[idx] = '\0';
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   290
                if (idx != 0)  // had any chars? It's a token.
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   291
                    return NOFAIL;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   292
                return END_OF_STREAM;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   293
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   294
            default:
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   295
                ctx->source++;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   296
                ctx->token[idx++] = ch;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   297
                break;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   298
        } // switch
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   299
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   300
        ctx->prevchar = ch;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   301
    } // while
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   302
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   303
    return fail(ctx, "???");  // shouldn't hit this.
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   304
} // _tokenize
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   305
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   306
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   307
static inline int tokenize(Context *ctx)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   308
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   309
    const int rc = _tokenize(ctx);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   310
    #if DEBUG_TOKENIZER
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   311
    printf("TOKENIZE: %s '%s'\n",
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   312
           (rc == END_OF_STREAM) ? "END_OF_STREAM" :
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   313
           (rc == FAIL) ? "FAIL" :
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   314
           (rc == NOFAIL) ? "NOFAIL" : "???",
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   315
           ctx->token);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   316
    #endif
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   317
    return rc;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   318
} // tokenize
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   319
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   320
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   321
static inline void pushback(Context *ctx)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   322
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   323
    #if DEBUG_TOKENIZER
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   324
    printf("PUSHBACK\n");
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   325
    #endif
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   326
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   327
    if (ctx->pushedback)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   328
        fail(ctx, "BUG: Double pushback in parser");
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   329
    else
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   330
        ctx->pushedback = 1;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   331
} // pushback
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   332
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   333
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   334
static int nexttoken(Context *ctx, const int ignoreeol,
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   335
                     const int ignorewhitespace, const int eolok,
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   336
                     const int eosok)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   337
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   338
    int rc = NOFAIL;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   339
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   340
    while ((rc = tokenize(ctx)) == NOFAIL)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   341
    {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   342
        if (strcmp(ctx->token, "\n") == 0)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   343
        {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   344
            if (ignoreeol)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   345
                continue;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   346
            else if (!eolok)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   347
                return fail(ctx, "Unexpected EOL");
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   348
        } // if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   349
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   350
        else if (strcmp(ctx->token, " ") == 0)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   351
        {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   352
            if (ignorewhitespace)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   353
                continue;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   354
        } // else if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   355
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   356
        // skip comments...
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   357
        else if ((strcmp(ctx->token, "//") == 0) || (strcmp(ctx->token, ";") == 0))
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   358
        {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   359
            while ((rc = tokenize(ctx)) == NOFAIL)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   360
            {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   361
                if (strcmp(ctx->token, "\n") == 0)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   362
                    break;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   363
            } // while
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   364
        } // if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   365
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   366
        break;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   367
    } // while
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   368
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   369
    #if DEBUG_TOKENIZER
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   370
    printf("NEXTTOKEN: %s '%s'\n",
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   371
           (rc == END_OF_STREAM) ? "END_OF_STREAM" :
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   372
           (rc == FAIL) ? "FAIL" :
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   373
           (rc == NOFAIL) ? "NOFAIL" : "???",
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   374
           ctx->token);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   375
    #endif
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   376
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   377
    if ((rc == END_OF_STREAM) && (!eosok))
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   378
        return fail(ctx, "Unexpected EOF");
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   379
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   380
    return rc;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   381
} // nexttoken
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   382
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   383
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   384
static int require_endline(Context *ctx)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   385
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   386
    const int rc = nexttoken(ctx, 0, 1, 1, 1);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   387
    if (rc == FAIL)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   388
        return FAIL;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   389
    else if (rc == END_OF_STREAM)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   390
        return NOFAIL;  // we'll call this an EOL.
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   391
    else if (strcmp(ctx->token, "\n") != 0)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   392
        return fail(ctx, "Endline expected");
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   393
    return NOFAIL;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   394
} // require_endline
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   395
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   396
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   397
static int require_comma(Context *ctx)
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   398
{
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   399
    const int rc = nexttoken(ctx, 0, 1, 0, 0);
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   400
    if (rc == FAIL)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   401
        return FAIL;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   402
    else if (strcmp(ctx->token, ",") != 0)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   403
        return fail(ctx, "Comma expected");
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   404
    return NOFAIL;
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   405
} // require_comma
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   406
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   407
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   408
static int parse_register_name(Context *ctx, RegisterType *rtype, int *rnum)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   409
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   410
    if (nexttoken(ctx, 0, 1, 0, 0) == FAIL)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   411
        return FAIL;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   412
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   413
    // !!! FIXME: some of these registers are only valid for some shader types.
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   414
    int neednum = 1;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   415
    int regnum = 0;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   416
    const char *t = ctx->token;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   417
    RegisterType regtype = REG_TYPE_TEMP;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   418
    if (strcasecmp(t, "r") == 0)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   419
        regtype = REG_TYPE_TEMP;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   420
    else if (strcasecmp(t, "v") == 0)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   421
        regtype = REG_TYPE_INPUT;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   422
    else if (strcasecmp(t, "c") == 0)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   423
        regtype = REG_TYPE_CONST;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   424
    else if (strcasecmp(t, "i") == 0)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   425
        regtype = REG_TYPE_CONSTINT;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   426
    else if (strcasecmp(t, "b") == 0)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   427
        regtype = REG_TYPE_CONSTBOOL;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   428
    else if (strcasecmp(t, "oC") == 0)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   429
        regtype = REG_TYPE_COLOROUT;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   430
    else if (strcasecmp(t, "oDepth") == 0)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   431
        regtype = REG_TYPE_DEPTHOUT;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   432
    else if (strcasecmp(t, "s") == 0)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   433
        regtype = REG_TYPE_SAMPLER;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   434
    else if (strcasecmp(t, "oD") == 0)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   435
        regtype = REG_TYPE_ATTROUT;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   436
    else if (strcasecmp(t, "l") == 0)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   437
        regtype = REG_TYPE_LABEL;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   438
    else if (strcasecmp(t, "p") == 0)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   439
        regtype = REG_TYPE_PREDICATE;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   440
    else if (strcasecmp(t, "aL") == 0)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   441
    {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   442
        regtype = REG_TYPE_LOOP;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   443
        neednum = 0;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   444
    } // else if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   445
    else if (strcasecmp(t, "o") == 0)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   446
    {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   447
        if (!shader_is_vertex(ctx) || !shader_version_atleast(ctx, 3, 0))
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   448
            return fail(ctx, "Output register not valid in this shader type");
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   449
        regtype = REG_TYPE_OUTPUT;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   450
    } // else if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   451
    else if (strcasecmp(t, "oT") == 0)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   452
    {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   453
        if (shader_is_vertex(ctx) || shader_version_atleast(ctx, 3, 0))
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   454
            return fail(ctx, "Output register not valid in this shader type");
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   455
        regtype = REG_TYPE_OUTPUT;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   456
    } // else if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   457
    else if (strcasecmp(t, "a") == 0)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   458
    {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   459
        if (!shader_is_vertex(ctx))
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   460
            return fail(ctx, "Address register only valid in vertex shaders.");
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   461
        regtype = REG_TYPE_ADDRESS;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   462
    } // else if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   463
    else if (strcasecmp(t, "t") == 0)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   464
    {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   465
        if (!shader_is_pixel(ctx))
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   466
            return fail(ctx, "Address register only valid in pixel shaders.");
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   467
        regtype = REG_TYPE_ADDRESS;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   468
    } // else if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   469
    else if (strcasecmp(t, "vPos") == 0)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   470
    {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   471
        regtype = REG_TYPE_MISCTYPE;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   472
        regnum = (int) MISCTYPE_TYPE_POSITION;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   473
        neednum = 0;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   474
    } // else if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   475
    else if (strcasecmp(t, "vFace") == 0)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   476
    {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   477
        regtype = REG_TYPE_MISCTYPE;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   478
        regnum = (int) MISCTYPE_TYPE_FACE;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   479
        neednum = 0;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   480
    } // else if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   481
    else if (strcasecmp(t, "oPos") == 0)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   482
    {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   483
        regtype = REG_TYPE_RASTOUT;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   484
        regnum = (int) RASTOUT_TYPE_POSITION;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   485
        neednum = 0;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   486
    } // else if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   487
    else if (strcasecmp(t, "oFog") == 0)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   488
    {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   489
        regtype = REG_TYPE_RASTOUT;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   490
        regnum = (int) RASTOUT_TYPE_FOG;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   491
        neednum = 0;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   492
    } // else if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   493
    else if (strcasecmp(t, "oPts") == 0)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   494
    {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   495
        regtype = REG_TYPE_RASTOUT;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   496
        regnum = (int) RASTOUT_TYPE_POINT_SIZE;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   497
        neednum = 0;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   498
    } // else if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   499
        
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   500
    //case REG_TYPE_TEMPFLOAT16:  // !!! FIXME: don't know this asm string
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   501
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   502
    else
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   503
    {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   504
        return fail(ctx, "expected register type");
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   505
    } // else
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   506
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   507
    if (neednum)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   508
    {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   509
        if (nexttoken(ctx, 0, 0, 0, 0) == FAIL)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   510
            return FAIL;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   511
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   512
        //minor = atoi(ctx->token);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   513
        char *endptr = NULL;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   514
        const long val = strtol(ctx->token, &endptr, 10);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   515
        regnum = (int) val;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   516
        if ((*ctx->token == '\0') || (*endptr != '\0'))
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   517
            return fail(ctx, "Invalid version string");
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   518
    } // if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   519
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   520
    // split up REG_TYPE_CONST
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   521
    if (regtype == REG_TYPE_CONST)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   522
    {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   523
        if (regnum < 2048)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   524
        {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   525
            regtype = REG_TYPE_CONST;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   526
            regnum -= 0;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   527
        } // if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   528
        else if (regnum < 4096)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   529
        {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   530
            regtype = REG_TYPE_CONST2;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   531
            regnum -= 2048;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   532
        } // if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   533
        else if (regnum < 6144)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   534
        {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   535
            regtype = REG_TYPE_CONST3;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   536
            regnum -= 4096;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   537
        } // if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   538
        else if (regnum < 8192)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   539
        {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   540
            regtype = REG_TYPE_CONST4;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   541
            regnum -= 6144;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   542
        } // if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   543
        else
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   544
        {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   545
            return fail(ctx, "Invalid const register index");
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   546
        } // else
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   547
    } // if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   548
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   549
    *rtype = regtype;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   550
    *rnum = regnum;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   551
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   552
    return NOFAIL;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   553
} // parse_register_name
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   554
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   555
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   556
static int set_result_shift(Context *ctx, DestArgInfo *info, const int val)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   557
{
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   558
    if (info->result_shift != 0)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   559
        return fail(ctx, "Multiple result shift modifiers");
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   560
    info->result_shift = val;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   561
    return NOFAIL;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   562
} // set_result_shift
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   563
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   564
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   565
static int parse_destination_token(Context *ctx, DestArgInfo *info)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   566
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   567
    memset(info, '\0', sizeof (info));
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   568
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   569
    // See if there are destination modifiers on the instruction itself...
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   570
    while (1)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   571
    {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   572
        if (nexttoken(ctx, 0, 0, 0, 0) == FAIL)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   573
            return FAIL;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   574
        else if (strcmp(ctx->token, " ") == 0)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   575
            break;  // done with modifiers.
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   576
        else if (strcmp(ctx->token, "_") != 0)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   577
            return fail(ctx, "Expected modifier or whitespace");
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   578
        else if (nexttoken(ctx, 0, 0, 0, 0) == FAIL)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   579
            return FAIL;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   580
        else if (strcasecmp(ctx->token, "x2") == 0)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   581
            set_result_shift(ctx, info, 0x1);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   582
        else if (strcasecmp(ctx->token, "x4") == 0)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   583
            set_result_shift(ctx, info, 0x2);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   584
        else if (strcasecmp(ctx->token, "x8") == 0)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   585
            set_result_shift(ctx, info, 0x3);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   586
        else if (strcasecmp(ctx->token, "d8") == 0)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   587
            set_result_shift(ctx, info, 0xD);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   588
        else if (strcasecmp(ctx->token, "d4") == 0)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   589
            set_result_shift(ctx, info, 0xE);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   590
        else if (strcasecmp(ctx->token, "d2") == 0)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   591
            set_result_shift(ctx, info, 0xF);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   592
        else if (strcasecmp(ctx->token, "sat") == 0)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   593
            info->result_mod |= MOD_SATURATE;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   594
        else if (strcasecmp(ctx->token, "pp") == 0)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   595
            info->result_mod |= MOD_PP;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   596
        else if (strcasecmp(ctx->token, "centroid") == 0)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   597
            info->result_mod |= MOD_CENTROID;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   598
        else
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   599
            return fail(ctx, "Expected modifier");
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   600
    } // while
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   601
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   602
    if (nexttoken(ctx, 0, 1, 0, 0) == FAIL)
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   603
        return FAIL;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   604
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   605
    // !!! FIXME: predicates.
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   606
    if (strcmp(ctx->token, "(") == 0)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   607
        return fail(ctx, "Predicates unsupported at this time");
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   608
    pushback(ctx);  // parse_register_name calls nexttoken().
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   609
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   610
    if (parse_register_name(ctx, &info->regtype, &info->regnum) == FAIL)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   611
        return FAIL;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   612
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   613
    if (nexttoken(ctx, 0, 1, 1, 1) == FAIL)
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   614
        return FAIL;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   615
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   616
    // !!! FIXME: can dest registers do relative addressing?
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   617
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   618
    if (strcmp(ctx->token, ".") != 0)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   619
    {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   620
        info->writemask = 0xF;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   621
        info->writemask0 = info->writemask1 = info->writemask2 = info->writemask3 = 1;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   622
        pushback(ctx);  // no explicit writemask; do full mask.
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   623
    } // if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   624
    else if (scalar_register(info->regtype, info->regnum))
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   625
        return fail(ctx, "Writemask specified for scalar register");
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   626
    else if (nexttoken(ctx, 0, 1, 0, 0) == FAIL)
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   627
        return FAIL;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   628
    else if (ctx->token[0] == '\0')
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   629
        return fail(ctx, "Invalid writemask");
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   630
    else
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   631
    {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   632
        char *ptr = ctx->token;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   633
        info->writemask0 = info->writemask1 = info->writemask2 = info->writemask3 = 0;
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   634
        if (*ptr == 'x') { info->writemask0 = 1; ptr++; }
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   635
        if (*ptr == 'y') { info->writemask1 = 1; ptr++; }
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   636
        if (*ptr == 'z') { info->writemask2 = 1; ptr++; }
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   637
        if (*ptr == 'w') { info->writemask3 = 1; ptr++; }
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   638
        if ((ptr == ctx->token) && (shader_is_pixel(ctx)))
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   639
        {
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   640
            if (*ptr == 'r') { info->writemask0 = 1; ptr++; }
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   641
            if (*ptr == 'g') { info->writemask1 = 1; ptr++; }
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   642
            if (*ptr == 'b') { info->writemask2 = 1; ptr++; }
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   643
            if (*ptr == 'a') { info->writemask3 = 1; ptr++; }
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   644
        } // if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   645
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   646
        if (*ptr != '\0')
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   647
            return fail(ctx, "Invalid writemask");
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   648
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   649
        info->writemask = ( ((info->writemask0 & 0x1) << 0) |
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   650
                            ((info->writemask1 & 0x1) << 1) |
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   651
                            ((info->writemask2 & 0x1) << 2) |
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   652
                            ((info->writemask3 & 0x1) << 3) );
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   653
    } // else
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   654
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   655
    info->orig_writemask = info->writemask;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   656
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   657
    if (ctx->tokenbufpos >= STATICARRAYLEN(ctx->tokenbuf))
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   658
        return fail(ctx, "Too many tokens");
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   659
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   660
    ctx->tokenbuf[ctx->tokenbufpos++] =
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   661
            ( ((((uint32) 1)) << 31) |
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   662
              ((((uint32) info->regnum) & 0x7ff) << 0) |
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   663
              ((((uint32) info->relative) & 0x1) << 13) |
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   664
              ((((uint32) info->result_mod) & 0xF) << 20) |
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   665
              ((((uint32) info->result_shift) & 0xF) << 24) |
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   666
              ((((uint32) info->regtype) & 0x7) << 28) |
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   667
              ((((uint32) info->regtype) & 0x18) << 8) );
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   668
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   669
    return 1;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   670
} // parse_destination_token
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   671
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   672
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   673
static void set_source_mod(const int negate, const SourceMod norm,
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   674
                          const SourceMod negated, SourceMod *srcmod)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   675
{
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   676
    if ( (*srcmod != SRCMOD_NONE) || (negate && (negated == SRCMOD_NONE)) )
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   677
        fail(ctx, "Incompatible source modifiers");
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   678
    else
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   679
        *srcmod = ((negate) ? negated : norm);
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   680
} // set_source_mod
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   681
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   682
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   683
static int parse_source_token_maybe_relative(Context *ctx, const int relok)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   684
{
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   685
    int retval = 1;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   686
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   687
    if (ctx->tokenbufpos >= STATICARRAYLEN(ctx->tokenbuf))
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   688
        return fail(ctx, "Too many tokens");
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   689
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   690
    // mark this now, so optional relative addressing token is placed second.
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   691
    uint32 *token = &ctx->tokenbuf[ctx->tokenbufpos++];
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   692
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   693
    SourceMod srcmod = SRCMOD_NONE;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   694
    int negate = 0;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   695
    if (nexttoken(ctx, 0, 1, 0, 0) == FAIL)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   696
        return FAIL;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   697
    else if (strcmp(ctx->token, "1") == 0)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   698
    {
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   699
        if (nexttoken(ctx, 0, 1, 0, 0) == FAIL)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   700
            return FAIL;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   701
        else if (strcmp(ctx->token, "-") != 0)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   702
            return fail(ctx, "Unexpected value");
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   703
        else
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   704
            srcmod = SRCMOD_COMPLEMENT;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   705
    } // else
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   706
    else if (strcmp(ctx->token, "!") == 0)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   707
        srcmod = SRCMOD_NOT;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   708
    else if (strcmp(ctx->token, "-") == 0)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   709
        negate = 1;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   710
    else
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   711
        pushback(ctx);
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   712
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   713
    RegisterType regtype;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   714
    int regnum;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   715
    if (parse_register_name(ctx, &regtype, &regnum) == FAIL)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   716
        return FAIL;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   717
    else if (nexttoken(ctx, 0, 1, 1, 1) == FAIL)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   718
        return FAIL;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   719
    else if (strcmp(ctx->token, "_") != 0)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   720
        pushback(ctx);
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   721
    else if (nexttoken(ctx, 0, 0, 0, 0) == FAIL)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   722
        return FAIL;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   723
    else if (strcasecmp(ctx->token, "bias") == 0)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   724
        set_source_mod(negate, SRCMOD_BIAS, SRCMOD_BIASNEGATE, &srcmod);
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   725
    else if (strcasecmp(ctx->token, "bx2") == 0)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   726
        set_source_mod(negate, SRCMOD_SIGN, SRCMOD_SIGNNEGATE, &srcmod);
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   727
    else if (strcasecmp(ctx->token, "x2") == 0)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   728
        set_source_mod(negate, SRCMOD_X2, SRCMOD_X2NEGATE, &srcmod);
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   729
    else if (strcasecmp(ctx->token, "dz") == 0)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   730
        set_source_mod(negate, SRCMOD_DZ, SRCMOD_NONE, &srcmod);
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   731
    else if (strcasecmp(ctx->token, "dw") == 0)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   732
        set_source_mod(negate, SRCMOD_DW, SRCMOD_NONE, &srcmod);
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   733
    else if (strcasecmp(ctx->token, "abs") == 0)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   734
        set_source_mod(negate, SRCMOD_ABS, SRCMOD_ABSNEGATE, &srcmod);
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   735
    else
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   736
        return fail(ctx, "Invalid source modifier");
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   737
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   738
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   739
    if (nexttoken(ctx, 0, 1, 1, 1) == FAIL)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   740
        return FAIL;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   741
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   742
    uint32 relative = 0;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   743
    if (strcmp(ctx->token, "[") != 0)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   744
        pushback(ctx);  // not relative addressing?
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   745
    else if (!relok)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   746
        return fail(ctx, "Relative addressing not permitted here.");
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   747
    else
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   748
    {
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   749
        const int rc = parse_source_token_maybe_relative(ctx, 0);
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   750
        if (rc == FAIL)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   751
            return FAIL;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   752
        retval += rc;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   753
        relative = 1;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   754
        if (nexttoken(ctx, 0, 1, 0, 0) == FAIL)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   755
            return FAIL;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   756
        else if (strcmp(ctx->token, "]") != 0)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   757
            return fail(ctx, "Expected ']'");
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   758
    } // else
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   759
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   760
    if (nexttoken(ctx, 0, 1, 1, 1) == FAIL)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   761
        return FAIL;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   762
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   763
    uint32 swizzle = 0;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   764
    if (strcmp(ctx->token, ".") != 0)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   765
    {
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   766
        swizzle = 0xE4;  // 0xE4 == 11100100 ... 0 1 2 3. No swizzle.
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   767
        pushback(ctx);  // no explicit writemask; do full mask.
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   768
    } // if
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   769
    else if (scalar_register(info->regtype, info->regnum))
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   770
        return fail(ctx, "Swizzle specified for scalar register");
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   771
    else if (nexttoken(ctx, 0, 1, 0, 0) == FAIL)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   772
        return FAIL;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   773
    else if (ctx->token[0] == '\0')
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   774
        return fail(ctx, "Invalid swizzle");
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   775
    else
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   776
    {
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   777
        // deal with shortened form (.x = .xxxx, etc).
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   778
        if (ctx->token[1] == '\0')
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   779
            ctx->token[1] = ctx->token[2] = ctx->token[3] = ctx->token[0];
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   780
        else if (ctx->token[2] == '\0')
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   781
            ctx->token[2] = ctx->token[3] = ctx->token[1];
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   782
        else if (ctx->token[3] == '\0')
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   783
            ctx->token[3] = ctx->token[2];
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   784
        else if (ctx->token[4] != '\0')
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   785
            return fail(ctx, "Invalid swizzle");
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   786
        ctx->token[4] = '\0';
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   787
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   788
        uint32 val;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   789
        int saw_xyzw = 0;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   790
        int saw_rgba = 0;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   791
        for (i = 0; i < 4; i++)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   792
        {
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   793
            const int component = (int) ctx->token[i];
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   794
            switch (component)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   795
            {
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   796
                case 'x': val = 0; saw_xyzw = 1; break;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   797
                case 'y': val = 1; saw_xyzw = 1; break;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   798
                case 'z': val = 2; saw_xyzw = 1; break;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   799
                case 'w': val = 3; saw_xyzw = 1; break;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   800
                case 'r': val = 0; saw_rgba = 1; break;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   801
                case 'g': val = 1; saw_rgba = 1; break;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   802
                case 'b': val = 2; saw_rgba = 1; break;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   803
                case 'a': val = 3; saw_rgba = 1; break;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   804
                default: return fail(ctx, "Invalid swizzle");
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   805
            } // switch
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   806
            swizzle |= (val << (i * 2));
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   807
        } // for
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   808
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   809
        if (saw_xyzw && saw_rgba)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   810
            return fail(ctx, "Invalid swizzle");
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   811
    } // else
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   812
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   813
    *token = ( ((((uint32) 1)) << 31) |
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   814
               ((((uint32) regnum) & 0x7ff) << 0) |
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   815
               ((((uint32) relative) & 0x1) << 13) |
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   816
               ((((uint32) swizzle) & 0xFF) << 16) |
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   817
               ((((uint32) srcmod) & 0xF) << 24) |
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   818
               ((((uint32) regtype) & 0x7) << 28) |
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   819
               ((((uint32) regtype) & 0x18) << 8) );
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   820
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   821
    return retval;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   822
} // parse_source_token_maybe_relative
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   823
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   824
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   825
static inline int parse_source_token(Context *ctx)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   826
{
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   827
    return parse_source_token_maybe_relative(ctx, 1);
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   828
} // parse_source_token
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   829
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   830
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   831
static int parse_args_NULL(Context *ctx)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   832
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   833
    return (isfail(ctx) ? FAIL : 1);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   834
} // parse_args_NULL
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   835
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   836
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   837
static int ui32fromstr(const char *str, uint32 *ui32)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   838
{
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   839
    //*ui32 = (uint32) atoi(minstr);
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   840
    char *endptr = NULL;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   841
    const long val = strtol(str, &endptr, 10);
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   842
    *ui32 = (uint32) val;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   843
    return ((val >= 0) && (*str != '\0') && (*endptr == '\0'));
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   844
} // ui32fromstr
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   845
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   846
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   847
static int parse_num(Context *ctx, const int floatok, uint32 *token)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   848
{
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   849
    int32 negative = 1;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   850
    union { float f; int32 si32; uint32 ui32; } cvt;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   851
    cvt.si32 = 0;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   852
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   853
    if (nexttoken(ctx, 0, 1, 0, 0) == FAIL)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   854
        return FAIL;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   855
    else if (strcmp(ctx->token, ",") != 0)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   856
        return fail(ctx, "Expected ','");
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   857
    else if (nexttoken(ctx, 0, 1, 0, 0) == FAIL)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   858
        return FAIL;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   859
    else if (strcmp(ctx->token, "-") == 0)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   860
        negative = -1;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   861
    else
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   862
        pushback(ctx);
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   863
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   864
    uint32 val = 0;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   865
    if (nexttoken(ctx, 0, 1, 0, 0) == FAIL)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   866
        return FAIL;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   867
    else if (!ui32fromstr(ctx->token, &val))
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   868
        return fail(ctx, "Expected number");
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   869
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   870
    uint32 fraction = 0;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   871
    if (nexttoken(ctx, 0, 1, 0, 0) == FAIL)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   872
        return FAIL;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   873
    else if (strcmp(ctx->token, ".") != 0)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   874
        pushback(ctx);  // whole number
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   875
    else if (!floatok)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   876
        return fail(ctx, "Expected whole number");
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   877
    else if (nexttoken(ctx, 0, 1, 0, 0) == FAIL)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   878
        return FAIL;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   879
    else if (!ui32fromstr(ctx->token, &fraction))
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   880
        return fail(ctx, "Expected number");
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   881
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   882
    if (!floatok)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   883
        cvt.si32 = ((int32) val) * negative;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   884
    else
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   885
    {
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   886
        // !!! FIXME: this is lame.
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   887
        char buf[128];
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   888
        snprintf(buf, sizeof (buf), "%s%u.%u", (negative == -1) ? "-" : "",
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   889
                 (uint) val, (uint) fraction);
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   890
        sscanf(buf, "%f", &cvt.f);
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   891
    } // else
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   892
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   893
    *token = cvt.ui32;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   894
    return NOFAIL;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   895
} // parse_num
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   896
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   897
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   898
static int parse_args_DEFx(Context *ctx, const int isflt)
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   899
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   900
    if (parse_destination_token(ctx, &ctx->dest_arg) == FAIL)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   901
        return FAIL;
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   902
    else if (require_comma(ctx) == FAIL)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   903
        return FAIL;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   904
    else if (parse_num(ctx, isflt, &ctx->tokenbuf[ctx->tokenbufpos++]) == FAIL)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   905
        return FAIL;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   906
    else if (require_comma(ctx) == FAIL)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   907
        return FAIL;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   908
    else if (parse_num(ctx, isflt, &ctx->tokenbuf[ctx->tokenbufpos++]) == FAIL)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   909
        return FAIL;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   910
    else if (require_comma(ctx) == FAIL)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   911
        return FAIL;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   912
    else if (parse_num(ctx, isflt, &ctx->tokenbuf[ctx->tokenbufpos++]) == FAIL)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   913
        return FAIL;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   914
    else if (require_comma(ctx) == FAIL)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   915
        return FAIL;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   916
    else if (parse_num(ctx, isflt, &ctx->tokenbuf[ctx->tokenbufpos++]) == FAIL)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   917
        return FAIL;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   918
    return 6;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   919
} // parse_args_DEFx
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   920
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   921
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   922
static int parse_args_DEF(Context *ctx)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   923
{
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   924
    return parse_args_DEFx(ctx, 1);
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   925
} // parse_args_DEF
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   926
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   927
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   928
static int parse_args_DEFI(Context *ctx)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   929
{
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   930
    return parse_args_DEFx(ctx, 0);
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   931
} // parse_args_DEFI
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   932
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   933
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   934
static int parse_args_DEFB(Context *ctx)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   935
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   936
    if (parse_destination_token(ctx, &ctx->dest_arg) == FAIL)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   937
        return FAIL;
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   938
    else if (nexttoken(ctx, 0, 1, 0, 0) == FAIL)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   939
        return FAIL;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   940
    else if (strcmp(ctx->token, ",") != 0)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   941
        return fail(ctx, "Expected ','");
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   942
    else if (nexttoken(ctx, 0, 1, 0, 0) == FAIL)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   943
        return FAIL;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   944
    else if (strcasecmp(ctx->token, "true") == 0)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   945
        ctx->tokenbuf[ctx->tokenbufpos++] = 1;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   946
    else if (strcasecmp(ctx->token, "false") == 0)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   947
        ctx->tokenbuf[ctx->tokenbufpos++] = 0;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   948
    else
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   949
        return fail(ctx, "Expected 'true' or 'false'");
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   950
    return 3;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   951
} // parse_args_DEFB
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   952
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   953
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   954
static int parse_dcl_usage(const char *token, uint32 *val, int *issampler)
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   955
{
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   956
    int i;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   957
    static const char *samplerusagestrs[] = { "2d", "cube", "volume" };
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   958
    static const char *usagestrs[] = {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   959
        "position", "blendweight", "blendindices", "normal", "psize",
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   960
        "texcoord", "tangent", "binormal", "tessfactor", "positiont",
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   961
        "color", "fog", "depth", "sample"
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   962
    };
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   963
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   964
    for (i = 0; i < STATICARRAYLEN(usagestrs); i++)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   965
    {
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   966
        if (strcasecmp(usagestrs[i], token) == 0)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   967
        {
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   968
            *issampler = 0;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   969
            *val = i;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   970
            return NOFAIL;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   971
        } // if
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   972
    } // for
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   973
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   974
    for (i = 0; i < STATICARRAYLEN(samplerusagestrs); i++)
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   975
    {
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   976
        if (strcasecmp(samplerusagestrs[i], token) == 0)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   977
        {
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   978
            *issampler = 1;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   979
            *val = i + 2;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   980
            return NOFAIL;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   981
        } // if
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   982
    } // for
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   983
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   984
    return FAIL;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   985
} // parse_dcl_usage
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   986
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   987
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   988
static int parse_args_DCL(Context *ctx)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   989
{
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   990
    int issampler = 0;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   991
    uint32 usage = 0;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   992
    uint32 index = 0;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   993
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   994
    ctx->tokenbufpos++;  // save a spot for the usage/index token.
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   995
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   996
    if (nexttoken(ctx, 0, 0, 0, 0) == FAIL)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   997
        return FAIL;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   998
    else if (strcmp(ctx->token, " ") == 0)
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   999
        pushback(ctx);
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1000
    else if (strcmp(ctx->token, "_") != 0)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1001
        return fail(ctx, "Expected register or usage");
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1002
    else if (nexttoken(ctx, 0, 0, 0, 0) == FAIL)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1003
        return FAIL;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1004
    else if (parse_dcl_usage(ctx->token, &usage, &issampler) == FAIL)
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1005
        return FAIL;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1006
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1007
    if (nexttoken(ctx, 0, 0, 0, 0) == FAIL)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1008
        return FAIL;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1009
    else if (strcmp(ctx->token, " ") == 0)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1010
        pushback(ctx);
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1011
    else if (!ui32fromstr(ctx->token, &index))
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1012
        return fail(ctx, "Expected usage index or register");
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1013
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1014
    if (nexttoken(ctx, 0, 0, 0, 0) == FAIL)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1015
        return FAIL;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1016
    else if (strcmp(ctx->token, " ") != 0)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1017
        return fail(ctx, "Expected register");
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1018
    else if (parse_destination_token(ctx, &ctx->dest_arg) == FAIL)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1019
        return FAIL;
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1020
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1021
    const int samplerreg = (ctx->dest_arg.regtype == REG_TYPE_SAMPLER);
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1022
    if (issampler != samplerreg)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1023
        return fail(ctx, "Invalid usage");
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1024
    else if (samplerreg)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1025
        ctx->tokenbuf[0] = (usage << 27) | 0x80000000;
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1026
    else
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1027
        ctx->tokenbuf[0] = usage | (index << 16) | 0x80000000;
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1028
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1029
    return 3;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1030
} // parse_args_DCL
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1031
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1032
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1033
static int parse_args_D(Context *ctx)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1034
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1035
    int retval = 1;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1036
    retval += parse_destination_token(ctx, &ctx->dest_arg);
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1037
    return isfail(ctx) ? FAIL : NOFAIL;
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1038
} // parse_args_D
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1039
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1040
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1041
static int parse_args_S(Context *ctx)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1042
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1043
    int retval = 1;
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1044
    retval += parse_source_token(ctx);
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1045
    return isfail(ctx) ? FAIL : retval;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1046
} // parse_args_S
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1047
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1048
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1049
static int parse_args_SS(Context *ctx)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1050
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1051
    int retval = 1;
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1052
    retval += parse_source_token(ctx);
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1053
    if (require_comma(ctx) == FAIL) return FAIL;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1054
    retval += parse_source_token(ctx);
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1055
    return isfail(ctx) ? FAIL : retval;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1056
} // parse_args_SS
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1057
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1058
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1059
static int parse_args_DS(Context *ctx)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1060
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1061
    int retval = 1;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1062
    retval += parse_destination_token(ctx, &ctx->dest_arg);
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1063
    if (require_comma(ctx) == FAIL) return FAIL;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1064
    retval += parse_source_token(ctx);
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1065
    return isfail(ctx) ? FAIL : retval;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1066
} // parse_args_DS
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1067
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1068
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1069
static int parse_args_DSS(Context *ctx)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1070
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1071
    int retval = 1;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1072
    retval += parse_destination_token(ctx, &ctx->dest_arg);
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1073
    if (require_comma(ctx) == FAIL) return FAIL;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1074
    retval += parse_source_token(ctx);
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1075
    if (require_comma(ctx) == FAIL) return FAIL;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1076
    retval += parse_source_token(ctx);
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1077
    return isfail(ctx) ? FAIL : retval;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1078
} // parse_args_DSS
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1079
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1080
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1081
static int parse_args_DSSS(Context *ctx)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1082
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1083
    int retval = 1;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1084
    retval += parse_destination_token(ctx, &ctx->dest_arg);
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1085
    if (require_comma(ctx) == FAIL) return FAIL;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1086
    retval += parse_source_token(ctx);
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1087
    if (require_comma(ctx) == FAIL) return FAIL;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1088
    retval += parse_source_token(ctx);
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1089
    if (require_comma(ctx) == FAIL) return FAIL;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1090
    retval += parse_source_token(ctx);
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1091
    return isfail(ctx) ? FAIL : retval;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1092
} // parse_args_DSSS
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1093
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1094
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1095
static int parse_args_DSSSS(Context *ctx)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1096
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1097
    int retval = 1;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1098
    retval += parse_destination_token(ctx, &ctx->dest_arg);
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1099
    if (require_comma(ctx) == FAIL) return FAIL;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1100
    retval += parse_source_token(ctx);
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1101
    if (require_comma(ctx) == FAIL) return FAIL;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1102
    retval += parse_source_token(ctx);
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1103
    if (require_comma(ctx) == FAIL) return FAIL;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1104
    retval += parse_source_token(ctx);
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1105
    if (require_comma(ctx) == FAIL) return FAIL;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1106
    retval += parse_source_token(ctx);
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1107
    return isfail(ctx) ? FAIL : retval;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1108
} // parse_args_DSSSS
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1109
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1110
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1111
static int parse_args_SINCOS(Context *ctx)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1112
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1113
    // this opcode needs extra registers for sm2 and lower.
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1114
    if (!shader_version_atleast(ctx, 3, 0))
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1115
        return parse_args_DSSS(ctx);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1116
    return parse_args_DS(ctx);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1117
} // parse_args_SINCOS
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1118
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1119
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1120
static int parse_args_TEXCRD(Context *ctx)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1121
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1122
    // added extra register in ps_1_4.
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1123
    if (shader_version_atleast(ctx, 1, 4))
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1124
        return parse_args_DS(ctx);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1125
    return parse_args_D(ctx);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1126
} // parse_args_TEXCRD
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1127
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1128
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1129
static int parse_args_TEXLD(Context *ctx)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1130
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1131
    // different registers in px_1_3, ps_1_4, and ps_2_0!
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1132
    if (shader_version_atleast(ctx, 2, 0))
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1133
        return parse_args_DSS(ctx);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1134
    else if (shader_version_atleast(ctx, 1, 4))
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1135
        return parse_args_DS(ctx);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1136
    return parse_args_D(ctx);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1137
} // parse_args_TEXLD
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1138
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1139
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1140
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1141
// one args function for each possible sequence of opcode arguments.
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1142
typedef int (*args_function)(Context *ctx);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1143
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1144
// Lookup table for instruction opcodes...
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1145
typedef struct
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1146
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1147
    const char *opcode_string;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1148
    args_function parse_args;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1149
} Instruction;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1150
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1151
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1152
static const Instruction instructions[] =
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1153
{
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1154
    #define INSTRUCTION_STATE(op, opstr, s, a, t) { opstr, parse_args_##a },
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1155
    #define INSTRUCTION(op, opstr, slots, a, t) { opstr, parse_args_##a },
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1156
    #define MOJOSHADER_DO_INSTRUCTION_TABLE 1
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1157
    #include "mojoshader_internal.h"
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1158
    #undef MOJOSHADER_DO_INSTRUCTION_TABLE
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1159
    #undef INSTRUCTION
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1160
    #undef INSTRUCTION_STATE
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1161
};
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1162
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1163
static int parse_condition(Context *ctx, uint32 *controls)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1164
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1165
    if (nexttoken(ctx, 0, 0, 0, 0) == FAIL)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1166
        return 0;
0a75f98f785b Initial work on assembler. Not even clos