mojoshader_assembler.c
author Ryan C. Gordon <icculus@icculus.org>
Thu, 04 Dec 2008 21:36:11 -0500
changeset 465 0a75f98f785b
child 470 7d84d3452125
permissions -rw-r--r--
Initial work on assembler. Not even close to done.
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;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    29
    unsigned int instruction_count;
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
    int centroid_allowed;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    38
    DestArgInfo dest_arg;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    39
};
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    40
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
// Convenience functions for allocators...
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
static MOJOSHADER_assembleData out_of_mem_data = {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    45
    "Out of memory", 0, 0, 0, MOJOSHADER_TYPE_UNKNOWN, 0, 0, 0, 0, 0
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    46
};
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
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    49
static const char *out_of_mem_str = "Out of memory";
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    50
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
    51
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    52
    if (ctx->failstr == NULL)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    53
        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
    54
    return FAIL;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    55
} // out_of_memory
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    56
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    57
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
    58
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    59
    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
    60
    if (retval == NULL)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    61
        out_of_memory(ctx);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    62
    return retval;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    63
} // Malloc
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    64
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    65
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
    66
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    67
    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
    68
        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
    69
} // Free
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    70
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    71
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
    72
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
    73
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    74
    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
    75
    {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    76
        char scratch = 0;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    77
        va_list ap;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    78
        va_start(ap, fmt);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    79
        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
    80
        va_end(ap);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    81
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    82
        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
    83
        if (failstr != NULL)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    84
        {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    85
            va_start(ap, fmt);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    86
            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
    87
            va_end(ap);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    88
            ctx->failstr = failstr;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    89
        } // if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    90
    } // if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    91
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    92
    return FAIL;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    93
} // failf
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    94
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    95
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
    96
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    97
    return failf(ctx, "%s", reason);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    98
} // fail
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    99
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   100
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
   101
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   102
    return (ctx->failstr != NULL);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   103
} // isfail
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   104
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
// Shader model version magic...
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   107
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   108
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
   109
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   110
    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
   111
} // version_ui32
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   112
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   113
static inline int shader_version_supported(const uint8 maj, const uint8 min)
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
    return (ver_ui32(maj,min) <= ver_ui32(MAX_SHADER_MAJOR, MAX_SHADER_MINOR));
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   116
} // shader_version_supported
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   117
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   118
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
   119
                                         const uint8 min)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   120
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   121
    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
   122
} // shader_version_atleast
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   123
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   124
static inline int shader_version_exactly(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
   125
                                         const uint8 min)
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
    return ((ctx->major_ver == maj) && (ctx->minor_ver == min));
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   128
} // shader_version_exactly
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   129
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   130
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
   131
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   132
    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
   133
} // shader_is_pixel
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   134
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   135
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
   136
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   137
    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
   138
} // shader_is_vertex
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   139
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   140
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   141
extern void writeme(void);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   142
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   143
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
   144
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   145
    if (isfail(ctx))
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   146
        return;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   147
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   148
    writeme();
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   149
} // output_token_noswap
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   150
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
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
   153
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   154
    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
   155
} // output_token
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   156
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
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
   159
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   160
    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
   161
        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
   162
    else if (!isfail(ctx))
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   163
    {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   164
        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
   165
        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
   166
        while (len >= 4)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   167
        {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   168
            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
   169
            len -= 4;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   170
            buf += 4;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   171
        } // while
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
        if (len > 0)  // handle spillover...
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   174
        {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   175
            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
   176
            overflow.ui32 = 0;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   177
            memcpy(overflow.ui8, buf, len);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   178
            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
   179
        } // if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   180
    } // else if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   181
} // output_comment_bytes
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   182
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
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
   185
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   186
    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
   187
} // output_comment_string
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   188
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
static int _tokenize(Context *ctx)
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
    int idx = 0;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   193
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   194
    if (isfail(ctx))
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   195
        return FAIL;
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
    if (ctx->pushedback)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   198
    {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   199
        ctx->pushedback = 0;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   200
        return NOFAIL;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   201
    } // if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   202
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   203
    while (1)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   204
    {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   205
        if (idx >= sizeof (ctx->token))
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   206
            return fail(ctx, "buffer overflow");
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   207
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   208
        char ch = *ctx->source;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   209
        if (ch == '\t')
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   210
            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
   211
        else if (ch == '\r')
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   212
        {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   213
            if (ctx->source[1] == '\n')
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   214
               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
   215
            ch = '\n';
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   216
        } // else if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   217
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   218
        if ((ch > '0') && (ch < '9'))
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   219
        {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   220
            // 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
   221
            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
   222
            {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   223
                ctx->token[idx++] = '\0';
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   224
                return NOFAIL;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   225
            } // if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   226
        } // if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   227
        else
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   228
        {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   229
            // 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
   230
            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
   231
            {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   232
                ctx->token[idx++] = '\0';
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   233
                return NOFAIL;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   234
            } // if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   235
        } // else
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   236
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   237
        switch (ch)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   238
        {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   239
            case '/':
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   240
            case ';':  // !!! FIXME: comment, right?
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   241
                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
   242
                    ctx->token[idx] = '\0';
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   243
                else
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   244
                {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   245
                    ctx->token[idx++] = ch;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   246
                    ctx->source++;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   247
                    if ((ch == '/') && (ctx->source[1] == '/'))
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++] = '/';
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
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   252
                    ctx->token[idx++] = '\0';
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   253
                } // else
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   254
                return NOFAIL;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   255
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   256
            case ' ':
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   257
                if (ctx->prevch == ' ')
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   258
                    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
   259
                // intentional fall-through...
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   260
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   261
            case '_':
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   262
            case '[':
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   263
            case ']':
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   264
            case '(':
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 '\n':
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   272
                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
   273
                    ctx->token[idx] = '\0';
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   274
                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
   275
                {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   276
                    if (ch == '\n')
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   277
                        ctx->linenum++;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   278
                    ctx->source++;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   279
                    ctx->token[idx++] = ch;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   280
                    ctx->token[idx++] = '\0';
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   281
                } // else
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   282
                return NOFAIL;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   283
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   284
            case '\0':
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   285
                ctx->token[idx] = '\0';
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   286
                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
   287
                    return NOFAIL;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   288
                return END_OF_STREAM;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   289
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   290
            default:
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   291
                ctx->source++;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   292
                ctx->token[idx++] = ch;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   293
                break;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   294
        } // switch
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   295
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   296
        ctx->prevchar = ch;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   297
    } // while
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   298
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   299
    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
   300
} // _tokenize
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   301
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
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
   304
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   305
    const int rc = _tokenize(ctx);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   306
    #if DEBUG_TOKENIZER
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   307
    printf("TOKENIZE: %s '%s'\n",
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   308
           (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
   309
           (rc == FAIL) ? "FAIL" :
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   310
           (rc == NOFAIL) ? "NOFAIL" : "???",
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   311
           ctx->token);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   312
    #endif
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   313
    return rc;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   314
} // tokenize
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   315
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   316
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   317
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
   318
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   319
    #if DEBUG_TOKENIZER
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   320
    printf("PUSHBACK\n");
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   321
    #endif
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 (ctx->pushedback)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   324
        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
   325
    else
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   326
        ctx->pushedback = 1;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   327
} // pushback
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   328
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   329
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   330
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
   331
                     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
   332
                     const int eosok)
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
    int rc = NOFAIL;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   335
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   336
    while ((rc = tokenize(ctx)) == NOFAIL)
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
        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
   339
        {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   340
            if (ignoreeol)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   341
                continue;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   342
            else if (!eolok)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   343
                return fail(ctx, "Unexpected EOL");
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   344
        } // if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   345
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   346
        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
   347
        {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   348
            if (ignorewhitespace)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   349
                continue;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   350
        } // else if
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
        // skip comments...
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   353
        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
   354
        {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   355
            while ((rc = tokenize(ctx)) == NOFAIL)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   356
            {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   357
                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
   358
                    break;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   359
            } // while
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   360
        } // if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   361
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
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   365
    #if DEBUG_TOKENIZER
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   366
    printf("NEXTTOKEN: %s '%s'\n",
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   367
           (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
   368
           (rc == FAIL) ? "FAIL" :
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   369
           (rc == NOFAIL) ? "NOFAIL" : "???",
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   370
           ctx->token);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   371
    #endif
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   372
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   373
    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
   374
        return fail(ctx, "Unexpected EOF");
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   375
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   376
    return rc;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   377
} // nexttoken
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   378
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
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
   381
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   382
    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
   383
    if (rc == FAIL)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   384
        return FAIL;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   385
    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
   386
        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
   387
    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
   388
        return fail(ctx, "Endline expected");
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   389
    return NOFAIL;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   390
} // require_endline
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   391
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   392
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   393
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   394
// !!! FIXME: merge parse_* into mojoshader.c to reduce cut-and-paste.
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   395
// !!! FIXME:  we need to merge Context, which is the nastiest part.
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   396
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   397
static int set_result_shift(Context *ctx, DestArgInfo *info, const int val)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   398
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   399
    if (info->result_shift != 0)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   400
        return fail(ctx, "Multiple result shift modifiers");
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   401
    info->result_shift = val;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   402
    return NOFAIL;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   403
} // set_result_shift
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   404
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   405
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   406
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
   407
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   408
    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
   409
        return FAIL;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   410
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   411
    // !!! 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
   412
    int neednum = 1;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   413
    int regnum = 0;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   414
    const char *t = ctx->token;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   415
    RegisterType regtype = REG_TYPE_TEMP;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   416
    if (strcasecmp(t, "r") == 0)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   417
        regtype = REG_TYPE_TEMP;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   418
    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
   419
        regtype = REG_TYPE_INPUT;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   420
    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
   421
        regtype = REG_TYPE_CONST;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   422
    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
   423
        regtype = REG_TYPE_CONSTINT;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   424
    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
   425
        regtype = REG_TYPE_CONSTBOOL;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   426
    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
   427
        regtype = REG_TYPE_COLOROUT;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   428
    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
   429
        regtype = REG_TYPE_DEPTHOUT;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   430
    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
   431
        regtype = REG_TYPE_SAMPLER;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   432
    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
   433
        regtype = REG_TYPE_ATTROUT;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   434
    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
   435
        regtype = REG_TYPE_LABEL;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   436
    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
   437
        regtype = REG_TYPE_PREDICATE;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   438
    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
   439
    {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   440
        regtype = REG_TYPE_LOOP;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   441
        neednum = 0;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   442
    } // else if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   443
    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
   444
    {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   445
        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
   446
            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
   447
        regtype = REG_TYPE_OUTPUT;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   448
    } // else if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   449
    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
   450
    {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   451
        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
   452
            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
   453
        regtype = REG_TYPE_OUTPUT;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   454
    } // else if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   455
    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
   456
    {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   457
        if (!shader_is_vertex(ctx))
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   458
            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
   459
        regtype = REG_TYPE_ADDRESS;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   460
    } // else if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   461
    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
   462
    {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   463
        if (!shader_is_pixel(ctx))
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   464
            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
   465
        regtype = REG_TYPE_ADDRESS;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   466
    } // else if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   467
    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
   468
    {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   469
        regtype = REG_TYPE_MISCTYPE;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   470
        regnum = (int) MISCTYPE_TYPE_POSITION;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   471
        neednum = 0;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   472
    } // else if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   473
    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
   474
    {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   475
        regtype = REG_TYPE_MISCTYPE;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   476
        regnum = (int) MISCTYPE_TYPE_FACE;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   477
        neednum = 0;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   478
    } // else if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   479
    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
   480
    {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   481
        regtype = REG_TYPE_RASTOUT;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   482
        regnum = (int) RASTOUT_TYPE_POSITION;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   483
        neednum = 0;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   484
    } // else if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   485
    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
   486
    {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   487
        regtype = REG_TYPE_RASTOUT;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   488
        regnum = (int) RASTOUT_TYPE_FOG;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   489
        neednum = 0;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   490
    } // else if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   491
    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
   492
    {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   493
        regtype = REG_TYPE_RASTOUT;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   494
        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
   495
        neednum = 0;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   496
    } // else if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   497
        
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   498
    //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
   499
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   500
    else
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
        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
   503
    } // else
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   504
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   505
    if (neednum)
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 (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
   508
            return FAIL;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   509
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   510
        //minor = atoi(ctx->token);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   511
        char *endptr = NULL;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   512
        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
   513
        regnum = (int) val;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   514
        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
   515
            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
   516
    } // if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   517
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   518
    // split up REG_TYPE_CONST
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   519
    if (regtype == REG_TYPE_CONST)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   520
    {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   521
        if (regnum < 2048)
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
            regtype = REG_TYPE_CONST;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   524
            regnum -= 0;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   525
        } // if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   526
        else if (regnum < 4096)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   527
        {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   528
            regtype = REG_TYPE_CONST2;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   529
            regnum -= 2048;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   530
        } // if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   531
        else if (regnum < 6144)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   532
        {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   533
            regtype = REG_TYPE_CONST3;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   534
            regnum -= 4096;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   535
        } // if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   536
        else if (regnum < 8192)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   537
        {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   538
            regtype = REG_TYPE_CONST4;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   539
            regnum -= 6144;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   540
        } // if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   541
        else
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   542
        {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   543
            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
   544
        } // else
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   545
    } // if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   546
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   547
    *rtype = regtype;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   548
    *rnum = regnum;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   549
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   550
    return NOFAIL;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   551
} // parse_register_name
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   552
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   553
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   554
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
   555
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   556
    // !!! FIXME: recheck against the spec for ranges (like RASTOUT values, etc).
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   557
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   558
    memset(info, '\0', sizeof (info));
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   559
    info->token = token;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   560
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   561
    // 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
   562
    while (1)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   563
    {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   564
        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
   565
            return FAIL;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   566
        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
   567
            break;  // done with modifiers.
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   568
        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
   569
            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
   570
        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
   571
            return FAIL;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   572
        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
   573
            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
   574
        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
   575
            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
   576
        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
   577
            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
   578
        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
   579
            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
   580
        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
   581
            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
   582
        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
   583
            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
   584
        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
   585
            info->result_mod |= MOD_SATURATE;
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, "pp") == 0)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   587
            info->result_mod |= MOD_PP;
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, "centroid") == 0)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   589
            info->result_mod |= MOD_CENTROID;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   590
        else
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   591
            return fail(ctx, "Expected modifier");
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   592
    } // while
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   593
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   594
    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
   595
        return FAIL;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   596
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   597
    // !!! FIXME: predicates.
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   598
    if (strcmp(ctx->token, "(") == 0)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   599
        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
   600
    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
   601
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   602
    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
   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
    if (nexttoken(ctx, 0, 0, 1, 1) == FAIL)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   606
        return FAIL;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   607
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   608
    // !!! 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
   609
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   610
    if (strcmp(ctx->token, ".") != 0)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   611
    {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   612
        info->writemask = 0xF;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   613
        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
   614
        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
   615
    } // if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   616
    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
   617
        return fail(ctx, "Writemask specified for scalar register");
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   618
    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
   619
        return FAIL;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   620
    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
   621
        return fail(ctx, "Invalid writemask");
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   622
    else
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   623
    {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   624
        char *ptr = ctx->token;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   625
        info->writemask0 = info->writemask1 = info->writemask2 = info->writemask3 = 0;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   626
        if (*ptr = 'x') { info->writemask0 = 1; ptr++; }
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   627
        if (*ptr = 'y') { info->writemask1 = 1; ptr++; }
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   628
        if (*ptr = 'z') { info->writemask2 = 1; ptr++; }
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   629
        if (*ptr = 'w') { info->writemask3 = 1; ptr++; }
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   630
        if ((ptr == ctx->token) && (is_pixel_shader(ctx))
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
            if (*ptr = 'r') { info->writemask0 = 1; ptr++; }
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   633
            if (*ptr = 'g') { info->writemask1 = 1; ptr++; }
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   634
            if (*ptr = 'b') { info->writemask2 = 1; ptr++; }
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   635
            if (*ptr = 'a') { info->writemask3 = 1; ptr++; }
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   636
        } // if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   637
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   638
        if (*ptr != '\0')
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   639
            return fail(ctx, "Invalid writemask");
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   640
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   641
        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
   642
                            ((info->writemask1 & 0x1) << 1) |
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   643
                            ((info->writemask2 & 0x1) << 2) |
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   644
                            ((info->writemask3 & 0x1) << 3) );
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   645
    } // else
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   646
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   647
    info->orig_writemask = info->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
    // !!! FIXME: cut and paste from mojoshader.c ...
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   650
    if (info->relative)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   651
    {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   652
        if (!shader_is_vertex(ctx))
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   653
            return fail(ctx, "Relative addressing in non-vertex shader");
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   654
        else 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
   655
            return fail(ctx, "Relative addressing in vertex shader version < 3.0");
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   656
        else if (!ctx->have_ctab)  // it's hard to do this efficiently without!
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   657
            return fail(ctx, "relative addressing unsupported without a CTAB");
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   658
        // !!! FIXME: I don't have a shader that has a relative dest currently.
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   659
        return fail(ctx, "Relative addressing of dest tokens is unsupported");
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   660
    } // if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   661
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   662
    const int s = info->result_shift;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   663
    if (s != 0)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   664
    {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   665
        if (!shader_is_pixel(ctx))
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   666
            return fail(ctx, "Result shift scale in non-pixel shader");
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   667
        else 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
   668
            return fail(ctx, "Result shift scale in pixel shader version >= 2.0");
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   669
        else if ( ! (((s >= 1) && (s <= 3)) || ((s >= 0xD) && (s <= 0xF))) )
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   670
            return fail(ctx, "Result shift scale isn't 1 to 3, or 13 to 15.");
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   671
    } // if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   672
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   673
    if (info->result_mod & MOD_PP)  // Partial precision (pixel shaders only)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   674
    {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   675
        if (!shader_is_pixel(ctx))
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   676
            return fail(ctx, "Partial precision result mod in non-pixel shader");
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   677
    } // if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   678
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   679
    if (info->result_mod & MOD_CENTROID)  // Centroid (pixel shaders only)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   680
    {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   681
        if (!shader_is_pixel(ctx))
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   682
            return fail(ctx, "Centroid result mod in non-pixel shader");
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   683
        else if (!ctx->centroid_allowed)  // only on DCL opcodes!
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   684
            return fail(ctx, "Centroid modifier not allowed here");
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   685
    } // if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   686
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   687
    // !!! FIXME: from msdn:
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   688
    //  "_sat cannot be used with instructions writing to output o# registers."
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   689
    // !!! FIXME: actually, just go over this page:
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   690
    //  http://msdn.microsoft.com/archive/default.asp?url=/archive/en-us/directx9_c/directx/graphics/reference/shaders/ps_instructionmodifiers.asp
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   691
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   692
    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
   693
        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
   694
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   695
    ctx->tokenbuf[ctx->tokenbufpos++] =
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   696
            ( ((((uint32) 0x80000000)) << 0) |
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   697
              ((((uint32) info->regnum) & 0x7ff) << 0) |
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   698
              ((((uint32) info->relative) & 0x1) << 13) |
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   699
              ((((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
   700
              ((((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
   701
              ((((uint32) info->regtype) & 0x7) << 28) |
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   702
              ((((uint32) info->regtype) & 0x18) << 8) );
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   703
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   704
    return 1;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   705
} // parse_destination_token
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   706
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   707
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   708
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
   709
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   710
    return (isfail(ctx) ? FAIL : 1);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   711
} // parse_args_NULL
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   712
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   713
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   714
static int parse_args_DEF(Context *ctx)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   715
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   716
    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
   717
        return FAIL;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   718
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   719
    if (ctx->dest_arg.relative)  // I'm pretty sure this is illegal...?
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   720
        return fail(ctx, "relative addressing in DEFB");
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   721
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   722
sdfsdf
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   723
// !!! FIXME: parse out def.
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   724
    ctx->dwords[0] = SWAP32(ctx->tokens[0]);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   725
    ctx->dwords[1] = SWAP32(ctx->tokens[1]);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   726
    ctx->dwords[2] = SWAP32(ctx->tokens[2]);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   727
    ctx->dwords[3] = SWAP32(ctx->tokens[3]);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   728
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   729
    return 6;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   730
} // parse_args_DEF
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   731
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   732
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   733
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
   734
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   735
    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
   736
        return FAIL;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   737
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   738
    if (ctx->dest_arg.relative)  // I'm pretty sure this is illegal...?
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   739
        return fail(ctx, "relative addressing in DEFB");
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   740
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   741
    ctx->dwords[0] = *(ctx->tokens) ? 1 : 0;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   742
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   743
    return 3;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   744
} // parse_args_DEFB
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   745
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   746
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   747
static int valid_texture_type(const uint32 ttype)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   748
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   749
    switch ((const TextureType) ttype)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   750
    {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   751
        case TEXTURE_TYPE_2D:
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   752
        case TEXTURE_TYPE_CUBE:
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   753
        case TEXTURE_TYPE_VOLUME:
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   754
            return 1;  // it's okay.
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   755
    } // switch
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   756
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   757
    return 0;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   758
} // valid_texture_type
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   759
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   760
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   761
// !!! FIXME: this function is kind of a mess.
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   762
// !!! FIXME: cut-and-paste from mojoshader.c ...
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   763
static int parse_args_DCL(Context *ctx)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   764
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   765
    int unsupported = 0;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   766
    char usage[sizeof (ctx->token)];
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   767
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   768
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
   769
                     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
   770
                     const int eosok)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   771
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   772
    char usagestr[sizeof (ctx->token)];
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   773
    static const char *usagestrs[] = {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   774
        "position", "blendweight", "blendindices", "normal", "psize",
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   775
        "texcoord", "tangent", "binormal", "tessfactor", "positiont",
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   776
        "color", "fog", "depth", "sample"
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   777
    };
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   778
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   779
    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
   780
        return FAIL;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   781
    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
   782
    {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   783
        pushback(ctx);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   784
        usagestr[0] = '\0';
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   785
    } // else if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   786
    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
   787
        return fail(ctx, "Expected register or usage");
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   788
    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
   789
        return FAIL;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   790
    else
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   791
        strcpy(usagestr, ctx->token);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   792
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   793
    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
   794
        return FAIL;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   795
    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
   796
        return fail(ctx, "Expected whitespace");
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   797
    
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   798
    ctx->centroid_allowed = 1;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   799
    ctx->tokenbufpos++;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   800
    const int parse_dest_rc = parse_destination_token(ctx, &ctx->dest_arg);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   801
    ctx->centroid_allowed = 0;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   802
    if (parse_dest_rc == FAIL)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   803
        return FAIL;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   804
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   805
    if (ctx->dest_arg.result_shift != 0)  // I'm pretty sure this is illegal...?
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   806
        return fail(ctx, "shift scale in DCL");
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   807
    else if (ctx->dest_arg.relative)  // I'm pretty sure this is illegal...?
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   808
        return fail(ctx, "relative addressing in DCL");
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   809
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   810
    const RegisterType regtype = ctx->dest_arg.regtype;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   811
    const int regnum = ctx->dest_arg.regnum;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   812
    if ( (shader_is_pixel(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
   813
    {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   814
        if (regtype == REG_TYPE_INPUT)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   815
        {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   816
            token |=
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   817
            const uint32 usage = (token & 0xF);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   818
            const uint32 index = ((token >> 16) & 0xF);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   819
            reserved_mask = 0x7FF0FFE0;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   820
            ctx->dwords[0] = usage;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   821
            ctx->dwords[1] = index;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   822
        } // if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   823
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   824
        else if (regtype == REG_TYPE_MISCTYPE)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   825
        {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   826
            const MiscTypeType mt = (MiscTypeType) regnum;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   827
            if (mt == MISCTYPE_TYPE_POSITION)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   828
                reserved_mask = 0x7FFFFFFF;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   829
            else if (mt == MISCTYPE_TYPE_FACE)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   830
            {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   831
                reserved_mask = 0x7FFFFFFF;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   832
                if (!writemask_xyzw(ctx->dest_arg.orig_writemask))
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   833
                    return fail(ctx, "DCL face writemask must be full");
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   834
                else if (ctx->dest_arg.result_mod != 0)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   835
                    return fail(ctx, "DCL face result modifier must be zero");
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   836
                else if (ctx->dest_arg.result_shift != 0)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   837
                    return fail(ctx, "DCL face shift scale must be zero");
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   838
            } // else if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   839
            else
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   840
            {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   841
                unsupported = 1;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   842
            } // else
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   843
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   844
            ctx->dwords[0] = (uint32) MOJOSHADER_USAGE_UNKNOWN;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   845
            ctx->dwords[1] = 0;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   846
        } // else if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   847
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   848
        else if (regtype == REG_TYPE_TEXTURE)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   849
        {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   850
            const uint32 usage = (token & 0xF);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   851
            const uint32 index = ((token >> 16) & 0xF);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   852
            if (usage == MOJOSHADER_USAGE_TEXCOORD)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   853
            {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   854
                if (index > 7)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   855
                    return fail(ctx, "DCL texcoord usage must have 0-7 index");
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   856
            } // if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   857
            else if (usage == MOJOSHADER_USAGE_COLOR)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   858
            {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   859
                if (index != 0)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   860
                    return fail(ctx, "DCL color usage must have 0 index");
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   861
            } // else if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   862
            else
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   863
            {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   864
                return fail(ctx, "Invalid DCL texture usage");
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   865
            } // else
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   866
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   867
            reserved_mask = 0x7FF0FFE0;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   868
            ctx->dwords[0] = usage;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   869
            ctx->dwords[1] = index;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   870
        } // else if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   871
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   872
        else if (regtype == REG_TYPE_SAMPLER)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   873
        {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   874
            const uint32 ttype = ((token >> 27) & 0xF);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   875
            if (!valid_texture_type(ttype))
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   876
                return fail(ctx, "unknown sampler texture type");
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   877
            reserved_mask = 0x7FFFFFF;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   878
            ctx->dwords[0] = ttype;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   879
        } // else if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   880
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   881
        else
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   882
        {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   883
            unsupported = 1;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   884
        } // else
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   885
    } // if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   886
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   887
    else if ( (shader_is_pixel(ctx)) && (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
   888
    {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   889
        if (regtype == REG_TYPE_INPUT)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   890
        {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   891
            ctx->dwords[0] = (uint32) MOJOSHADER_USAGE_COLOR;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   892
            ctx->dwords[1] = regnum;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   893
            reserved_mask = 0x7FFFFFFF;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   894
        } // if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   895
        else if (regtype == REG_TYPE_TEXTURE)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   896
        {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   897
            ctx->dwords[0] = (uint32) MOJOSHADER_USAGE_TEXCOORD;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   898
            ctx->dwords[1] = regnum;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   899
            reserved_mask = 0x7FFFFFFF;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   900
        } // else if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   901
        else if (regtype == REG_TYPE_SAMPLER)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   902
        {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   903
            const uint32 ttype = ((token >> 27) & 0xF);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   904
            if (!valid_texture_type(ttype))
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   905
                return fail(ctx, "unknown sampler texture type");
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   906
            reserved_mask = 0x7FFFFFF;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   907
            ctx->dwords[0] = ttype;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   908
        } // else if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   909
        else
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   910
        {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   911
            unsupported = 1;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   912
        } // else
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   913
    } // if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   914
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   915
    else 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
   916
    {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   917
        if ((regtype == REG_TYPE_INPUT) || (regtype == REG_TYPE_OUTPUT))
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   918
        {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   919
            const uint32 usage = (token & 0xF);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   920
            const uint32 index = ((token >> 16) & 0xF);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   921
            reserved_mask = 0x7FF0FFE0;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   922
            ctx->dwords[0] = usage;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   923
            ctx->dwords[1] = index;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   924
        } // if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   925
        else
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   926
        {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   927
            unsupported = 1;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   928
        } // else
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   929
    } // else if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   930
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   931
    else if ( (shader_is_vertex(ctx)) && (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
   932
    {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   933
        if (regtype == REG_TYPE_INPUT)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   934
        {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   935
            const uint32 usage = (token & 0xF);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   936
            const uint32 index = ((token >> 16) & 0xF);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   937
            reserved_mask = 0x7FF0FFE0;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   938
            ctx->dwords[0] = usage;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   939
            ctx->dwords[1] = index;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   940
        } // if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   941
        else
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   942
        {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   943
            unsupported = 1;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   944
        } // else
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   945
    } // else if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   946
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   947
    else
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   948
    {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   949
        unsupported = 1;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   950
    } // else
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   951
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   952
    if (unsupported)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   953
        return fail(ctx, "invalid DCL register type for this shader model");
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   954
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   955
    if ((token & reserved_mask) != 0)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   956
        return fail(ctx, "reserved bits in DCL dword aren't zero");
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   957
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   958
    return 3;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   959
} // parse_args_DCL
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   960
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   961
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   962
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
   963
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   964
    int retval = 1;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   965
    retval += parse_destination_token(ctx, &ctx->dest_arg);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   966
    return isfail(ctx) ? FAIL : retval;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   967
} // parse_args_D
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   968
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   969
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   970
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
   971
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   972
    int retval = 1;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   973
    retval += parse_source_token(ctx, &ctx->source_args[0]);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   974
    return isfail(ctx) ? FAIL : retval;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   975
} // parse_args_S
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   976
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   977
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   978
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
   979
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   980
    int retval = 1;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   981
    retval += parse_source_token(ctx, &ctx->source_args[0]);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   982
    retval += parse_source_token(ctx, &ctx->source_args[1]);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   983
    return isfail(ctx) ? FAIL : retval;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   984
} // parse_args_SS
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   985
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   986
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   987
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
   988
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   989
    int retval = 1;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   990
    retval += parse_destination_token(ctx, &ctx->dest_arg);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   991
    retval += parse_source_token(ctx, &ctx->source_args[0]);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   992
    return isfail(ctx) ? FAIL : retval;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   993
} // parse_args_DS
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   994
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
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
   997
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   998
    int retval = 1;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   999
    retval += parse_destination_token(ctx, &ctx->dest_arg);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1000
    retval += parse_source_token(ctx, &ctx->source_args[0]);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1001
    retval += parse_source_token(ctx, &ctx->source_args[1]);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1002
    return isfail(ctx) ? FAIL : retval;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1003
} // parse_args_DSS
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1004
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1005
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1006
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
  1007
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1008
    int retval = 1;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1009
    retval += parse_destination_token(ctx, &ctx->dest_arg);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1010
    retval += parse_source_token(ctx, &ctx->source_args[0]);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1011
    retval += parse_source_token(ctx, &ctx->source_args[1]);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1012
    retval += parse_source_token(ctx, &ctx->source_args[2]);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1013
    return isfail(ctx) ? FAIL : retval;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1014
} // parse_args_DSSS
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1015
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1016
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1017
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
  1018
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1019
    int retval = 1;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1020
    retval += parse_destination_token(ctx, &ctx->dest_arg);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1021
    retval += parse_source_token(ctx, &ctx->source_args[0]);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1022
    retval += parse_source_token(ctx, &ctx->source_args[1]);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1023
    retval += parse_source_token(ctx, &ctx->source_args[2]);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1024
    retval += parse_source_token(ctx, &ctx->source_args[3]);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1025
    return isfail(ctx) ? FAIL : retval;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1026
} // parse_args_DSSSS
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1027
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
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
  1030
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1031
    // 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
  1032
    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
  1033
        return parse_args_DSSS(ctx);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1034
    return parse_args_DS(ctx);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1035
} // parse_args_SINCOS
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1036
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1037
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1038
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
  1039
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1040
    // 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
  1041
    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
  1042
        return parse_args_DS(ctx);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1043
    return parse_args_D(ctx);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1044
} // parse_args_TEXCRD
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1045
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1046
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1047
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
  1048
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1049
    // 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
  1050
    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
  1051
        return parse_args_DSS(ctx);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1052
    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
  1053
        return parse_args_DS(ctx);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1054
    return parse_args_D(ctx);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1055
} // parse_args_TEXLD
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1056
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
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
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1062
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1063
// 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
  1064
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
  1065
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1066
// one state function for each opcode where we have state machine updates.
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1067
typedef void (*state_function)(Context *ctx);
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
// Lookup table for instruction opcodes...
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1070
typedef struct
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1071
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1072
    const char *opcode_string;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1073
    int slots;  // number of instruction slots this opcode eats.
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1074
    MOJOSHADER_shaderType shader_types;  // mask of types that can use opcode.
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1075
    args_function parse_args;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1076
    state_function state;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1077
} Instruction;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1078
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
static const Instruction instructions[] =
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1081
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1082
/*  !!! FIXME: push this through mojoshader.c's state machine.
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1083
    #define INSTRUCTION_STATE(op, opstr, slots, a, t) { \
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1084
        opstr, slots, t, parse_args_##a, state_##op \
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1085
    },
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1086
*/
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1087
    #define INSTRUCTION_STATE(op, opstr, slots, a, t) { \
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1088
        opstr, slots, t, parse_args_##a, 0 \
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1089
    },
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1090
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1091
    #define INSTRUCTION(op, opstr, slots, a, t) { \
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1092
        opstr, slots, t, parse_args_##a, 0 \
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
    #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
  1096
    #include "mojoshader_internal.h"
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1097
    #undef MOJOSHADER_DO_INSTRUCTION_TABLE
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1098
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1099
    #undef INSTRUCTION
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1100
    #undef INSTRUCTION_STATE
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1101
};
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1102
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1103
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
  1104
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1105
    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
  1106
        return 0;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1107
    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
  1108
    {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1109
        pushback(ctx);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1110
        return 0;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1111
    } // else if
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
    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
  1114
        return 0;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1115
    else
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1116
    {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1117
        int i;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1118
        static const char *comps[] = {"", "gt", "eq", "ge", "lt", "ne", "le"};
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1119
        for (i = 1; i < STATICARRAYLEN(comps); i++)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1120
        {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1121
            if (strcasecmp(ctx->token, comps[i]) == 0)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1122
            {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1123
                *controls = i;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1124
                return 1;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1125
            }
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1126
        } // for
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
        fail(ctx, "Expected comparison token");
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1129
        return 0;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1130
    } // else if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1131
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1132
    return 0;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1133
} // parse_condition
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1134
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1135
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1136
static int parse_instruction_token(Context *ctx)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1137
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1138
    int coissue = 0;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1139
    int predicated = 0;
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
    if (strcmp(ctx->token, "+") == 0)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1142
    {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1143
        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
  1144
            return FAIL;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1145
        coissue = 1;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1146
    } // if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1147
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1148
    if (coissue)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1149
    {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1150
        if (!shader_is_pixel(ctx))
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1151
            return fail(ctx, "coissue instruction on non-pixel shader");
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1152
        else 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
  1153
            return fail(ctx, "coissue instruction in Shader Model >= 2.0");
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1154
    } // if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1155
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1156
    int i;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1157
    int valid_opcode = 0;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1158
    const Instruction *instruction = NULL;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1159
    for (i = 0; i < STATICARRAYLEN(instructions); i++)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1160
    {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1161
        instruction = &instructions[i];
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1162
        if (instruction->opcode_string == NULL)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1163
            continue;  // skip this.
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1164
        else if (strcasecmp(ctx->token, instruction->opcode_string) != 0)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1165
            continue;  // not us.
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1166
        valid_opcode = 1;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1167
        break;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1168
    } // for
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1169
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1170
    uint32 opcode = (uint32) i;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1171
    uint32 controls = 0;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1172
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1173
    if (!valid_opcode)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1174
        return failf(ctx, "Unknown instruction '%s'", ctx->token);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1175
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1176
    // This might need to be IFC instead of IF.
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1177
    if (strcmp(instruction->opcode_string, "IF") == 0)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1178
    {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1179
        if (parse_condition(ctx, &controls))
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1180
            opcode = OPCODE_IFC;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1181
    } // if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1182
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1183
    // This might need to be BREAKC instead of BREAK.
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1184
    else if (strcmp(instruction->opcode_string, "BREAK") == 0)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1185
    {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1186
        if (parse_condition(ctx, &controls))
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1187
            opcode = OPCODE_BREAKC;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1188
    } // else if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1189
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1190
    // SETP has a conditional code, always.
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1191
    else if (strcmp(instruction->opcode_string, "SETP") == 0)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1192
    {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1193
        if (!parse_condition(ctx, &controls))
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1194
            return fail(ctx, "SETP requires a condition");
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1195
    } // else if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1196
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1197
    instruction = &instructions[opcode];  // ...in case this changed.
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus&#