mojoshader_assembler.c
author Ryan C. Gordon <icculus@icculus.org>
Tue, 03 Feb 2009 17:31:37 -0500
changeset 550 2f977a75d2b5
parent 549 13714d3b3fa2
child 551 217200672d64
permissions -rw-r--r--
Fixed error reporting in assembler.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
     1
/**
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
     2
 * MojoShader; generate shader programs from bytecode of compiled
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
     3
 *  Direct3D shaders.
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
     4
 *
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
     5
 * Please see the file LICENSE.txt in the source's root directory.
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
     6
 *
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
     7
 *  This file written by Ryan C. Gordon.
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
     8
 */
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
     9
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    10
#define __MOJOSHADER_INTERNAL__ 1
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    11
#include "mojoshader_internal.h"
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    12
497
5b2465d40b57 Disabled tokenizer debug output for now.
Ryan C. Gordon <icculus@icculus.org>
parents: 495
diff changeset
    13
#define DEBUG_TOKENIZER 0
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    14
498
6a4b881704df Added a FIXME.
Ryan C. Gordon <icculus@icculus.org>
parents: 497
diff changeset
    15
// !!! FIXME: no #define support yet.
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    16
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
    17
typedef struct TokenizerContext
514
ba913834b491 The parse_args_DCL fiasco continues.
Ryan C. Gordon <icculus@icculus.org>
parents: 513
diff changeset
    18
{
ba913834b491 The parse_args_DCL fiasco continues.
Ryan C. Gordon <icculus@icculus.org>
parents: 513
diff changeset
    19
    const char *source;
ba913834b491 The parse_args_DCL fiasco continues.
Ryan C. Gordon <icculus@icculus.org>
parents: 513
diff changeset
    20
    int on_endline;
ba913834b491 The parse_args_DCL fiasco continues.
Ryan C. Gordon <icculus@icculus.org>
parents: 513
diff changeset
    21
    unsigned int linenum;
ba913834b491 The parse_args_DCL fiasco continues.
Ryan C. Gordon <icculus@icculus.org>
parents: 513
diff changeset
    22
    char prevchar;
ba913834b491 The parse_args_DCL fiasco continues.
Ryan C. Gordon <icculus@icculus.org>
parents: 513
diff changeset
    23
    char token[64];
ba913834b491 The parse_args_DCL fiasco continues.
Ryan C. Gordon <icculus@icculus.org>
parents: 513
diff changeset
    24
    char pushedback;
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
    25
} TokenizerContext;
514
ba913834b491 The parse_args_DCL fiasco continues.
Ryan C. Gordon <icculus@icculus.org>
parents: 513
diff changeset
    26
ba913834b491 The parse_args_DCL fiasco continues.
Ryan C. Gordon <icculus@icculus.org>
parents: 513
diff changeset
    27
536
5af65fe6e917 Allow multiple errors from parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 532
diff changeset
    28
typedef struct SourcePos
5af65fe6e917 Allow multiple errors from parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 532
diff changeset
    29
{
5af65fe6e917 Allow multiple errors from parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 532
diff changeset
    30
    const char *filename;
5af65fe6e917 Allow multiple errors from parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 532
diff changeset
    31
    uint32 line;
5af65fe6e917 Allow multiple errors from parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 532
diff changeset
    32
} SourcePos;
5af65fe6e917 Allow multiple errors from parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 532
diff changeset
    33
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    34
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    35
// Context...this is state that changes as we assemble a shader...
536
5af65fe6e917 Allow multiple errors from parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 532
diff changeset
    36
typedef struct Context
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    37
{
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
    38
    int isfail;
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
    39
    int out_of_memory;
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
    40
    int eof;
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    41
    MOJOSHADER_malloc malloc;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    42
    MOJOSHADER_free free;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    43
    void *malloc_data;
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
    44
    int error_count;
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
    45
    ErrorList *errors;
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
    46
    TokenizerContext tctx;
523
699696afd731 Allow errors to specify post-processing problems.
Ryan C. Gordon <icculus@icculus.org>
parents: 522
diff changeset
    47
    MOJOSHADER_parsePhase parse_phase;
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    48
    MOJOSHADER_shaderType shader_type;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    49
    uint8 major_ver;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    50
    uint8 minor_ver;
524
03eea2f0762c First (incomplete!) shot at more robust CTAB support.
Ryan C. Gordon <icculus@icculus.org>
parents: 523
diff changeset
    51
    uint32 version_token;
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    52
    uint32 tokenbuf[16];
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    53
    int tokenbufpos;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    54
    DestArgInfo dest_arg;
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
    55
    uint32 *output;
536
5af65fe6e917 Allow multiple errors from parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 532
diff changeset
    56
    SourcePos *token_to_source;
524
03eea2f0762c First (incomplete!) shot at more robust CTAB support.
Ryan C. Gordon <icculus@icculus.org>
parents: 523
diff changeset
    57
    uint8 *ctab;
03eea2f0762c First (incomplete!) shot at more robust CTAB support.
Ryan C. Gordon <icculus@icculus.org>
parents: 523
diff changeset
    58
    uint32 ctab_len;
03eea2f0762c First (incomplete!) shot at more robust CTAB support.
Ryan C. Gordon <icculus@icculus.org>
parents: 523
diff changeset
    59
    uint32 ctab_allocation;
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
    60
    size_t output_len;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
    61
    size_t output_allocation;
536
5af65fe6e917 Allow multiple errors from parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 532
diff changeset
    62
} Context;
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    63
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
// Convenience functions for allocators...
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    66
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
    67
static inline void out_of_memory(Context *ctx)
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    68
{
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
    69
    ctx->isfail = ctx->out_of_memory = 1;
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    70
} // out_of_memory
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    71
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    72
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
    73
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    74
    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
    75
    if (retval == NULL)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    76
        out_of_memory(ctx);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    77
    return retval;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    78
} // Malloc
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    79
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
    80
static inline char *StrDup(Context *ctx, const char *str)
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
    81
{
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
    82
    char *retval = (char *) Malloc(ctx, strlen(str) + 1);
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
    83
    if (retval == NULL)
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
    84
        out_of_memory(ctx);
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
    85
    else
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
    86
        strcpy(retval, str);
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
    87
    return retval;
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
    88
} // StrDup
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
    89
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    90
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
    91
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    92
    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
    93
        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
    94
} // Free
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    95
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
    96
static void failf(Context *ctx, const char *fmt, ...) ISPRINTF(2,3);
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
    97
static void failf(Context *ctx, const char *fmt, ...)
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    98
{
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
    99
    const char *fname = NULL;
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   100
    unsigned int linenum = 0;
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   101
    int error_position = 0;
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   102
550
2f977a75d2b5 Fixed error reporting in assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 549
diff changeset
   103
    ctx->isfail = 1;
2f977a75d2b5 Fixed error reporting in assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 549
diff changeset
   104
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   105
    switch (ctx->parse_phase)
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   106
    {
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   107
        case MOJOSHADER_PARSEPHASE_NOTSTARTED:
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   108
            error_position = -2;
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   109
            break;
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   110
        case MOJOSHADER_PARSEPHASE_WORKING:
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   111
            // !!! FIXME: fname == base source file if output_pos == 0.
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   112
            if (ctx->output_len > 0)
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   113
            {
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   114
                const size_t idx = ctx->output_len - 1;
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   115
                linenum = ctx->token_to_source[idx].line;
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   116
                fname = ctx->token_to_source[idx].filename;
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   117
            } // if
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   118
            error_position = linenum;
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   119
            break;
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   120
        case MOJOSHADER_PARSEPHASE_DONE:
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   121
            error_position = -1;
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   122
            break;
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   123
        default:
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   124
            assert(0 && "Unexpected value");
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   125
            return;
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   126
    } // switch
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   127
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   128
    ErrorList *error = (ErrorList *) Malloc(ctx, sizeof (ErrorList));
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   129
    if (error == NULL)
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   130
        return;
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   131
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   132
    char scratch = 0;
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   133
    va_list ap;
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   134
    va_start(ap, fmt);
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   135
    const int len = vsnprintf(&scratch, sizeof (scratch), fmt, ap);
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   136
    va_end(ap);
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   137
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   138
    char *failstr = (char *) Malloc(ctx, len + 1);
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   139
    if (failstr == NULL)
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   140
        Free(ctx, error);
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   141
    else
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   142
    {
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   143
        va_start(ap, fmt);
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   144
        vsnprintf(failstr, len + 1, fmt, ap);  // rebuild it.
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   145
        va_end(ap);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   146
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   147
        error->error.error = failstr;
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   148
        error->error.filename = fname ? StrDup(ctx, fname) : NULL;
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   149
        error->error.error_position = error_position;
544
f829f48e5214 Fixed stupid linked list bug.
Ryan C. Gordon <icculus@icculus.org>
parents: 543
diff changeset
   150
        error->next = NULL;
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   151
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   152
        ErrorList *prev = NULL;
544
f829f48e5214 Fixed stupid linked list bug.
Ryan C. Gordon <icculus@icculus.org>
parents: 543
diff changeset
   153
        ErrorList *item = ctx->errors;
f829f48e5214 Fixed stupid linked list bug.
Ryan C. Gordon <icculus@icculus.org>
parents: 543
diff changeset
   154
        while (item != NULL)
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   155
        {
544
f829f48e5214 Fixed stupid linked list bug.
Ryan C. Gordon <icculus@icculus.org>
parents: 543
diff changeset
   156
            prev = item;
f829f48e5214 Fixed stupid linked list bug.
Ryan C. Gordon <icculus@icculus.org>
parents: 543
diff changeset
   157
            item = error->next;
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   158
        } // while
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   159
544
f829f48e5214 Fixed stupid linked list bug.
Ryan C. Gordon <icculus@icculus.org>
parents: 543
diff changeset
   160
        if (prev == NULL)
f829f48e5214 Fixed stupid linked list bug.
Ryan C. Gordon <icculus@icculus.org>
parents: 543
diff changeset
   161
            ctx->errors = error;
f829f48e5214 Fixed stupid linked list bug.
Ryan C. Gordon <icculus@icculus.org>
parents: 543
diff changeset
   162
        else
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   163
            prev->next = error;
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   164
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   165
        ctx->error_count++;
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   166
    } // else
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   167
} // failf
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   168
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   169
static inline void fail(Context *ctx, const char *reason)
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   170
{
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   171
    failf(ctx, "%s", reason);
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   172
} // fail
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   173
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   174
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
   175
{
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   176
    return ctx->isfail;
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   177
} // isfail
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   178
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   179
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   180
static inline int tokeq(const TokenizerContext *tctx, const char *token)
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   181
{
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   182
    return (strcasecmp(tctx->token, token) == 0);
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   183
} // tokeq
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   184
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   185
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   186
// Shader model version magic...
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   187
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   188
static 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
   189
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   190
    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
   191
} // version_ui32
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   192
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   193
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
   194
                                         const uint8 min)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   195
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   196
    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
   197
} // shader_version_atleast
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
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
   200
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   201
    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
   202
} // shader_is_pixel
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   203
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   204
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
   205
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   206
    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
   207
} // shader_is_vertex
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   208
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   209
482
3f740f25bd7e Fixed relative addressing parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 481
diff changeset
   210
static int ui32fromstr(const char *str, uint32 *ui32)
3f740f25bd7e Fixed relative addressing parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 481
diff changeset
   211
{
3f740f25bd7e Fixed relative addressing parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 481
diff changeset
   212
    //*ui32 = (uint32) atoi(minstr);
3f740f25bd7e Fixed relative addressing parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 481
diff changeset
   213
    char *endptr = NULL;
3f740f25bd7e Fixed relative addressing parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 481
diff changeset
   214
    const long val = strtol(str, &endptr, 10);
3f740f25bd7e Fixed relative addressing parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 481
diff changeset
   215
    *ui32 = (uint32) val;
3f740f25bd7e Fixed relative addressing parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 481
diff changeset
   216
    return ((val >= 0) && (*str != '\0') && (*endptr == '\0'));
3f740f25bd7e Fixed relative addressing parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 481
diff changeset
   217
} // ui32fromstr
3f740f25bd7e Fixed relative addressing parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 481
diff changeset
   218
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   219
536
5af65fe6e917 Allow multiple errors from parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 532
diff changeset
   220
static inline void add_token_sourcepos(Context *ctx, const size_t idx)
5af65fe6e917 Allow multiple errors from parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 532
diff changeset
   221
{
5af65fe6e917 Allow multiple errors from parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 532
diff changeset
   222
    ctx->token_to_source[idx].line = ctx->tctx.linenum;
5af65fe6e917 Allow multiple errors from parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 532
diff changeset
   223
    ctx->token_to_source[idx].filename = NULL;
5af65fe6e917 Allow multiple errors from parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 532
diff changeset
   224
} // add_token_sourcepos
5af65fe6e917 Allow multiple errors from parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 532
diff changeset
   225
5af65fe6e917 Allow multiple errors from parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 532
diff changeset
   226
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   227
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
   228
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   229
    if (isfail(ctx))
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   230
        return;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   231
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   232
    if (ctx->output_len >= ctx->output_allocation)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   233
    {
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   234
        const size_t output_alloc_bump = 1024;  // that's tokens, not bytes.
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   235
        const size_t newsize = ctx->output_allocation + output_alloc_bump;
486
45efac751027 Added error_position to assembly results.
Ryan C. Gordon <icculus@icculus.org>
parents: 485
diff changeset
   236
        void *ptr;
45efac751027 Added error_position to assembly results.
Ryan C. Gordon <icculus@icculus.org>
parents: 485
diff changeset
   237
45efac751027 Added error_position to assembly results.
Ryan C. Gordon <icculus@icculus.org>
parents: 485
diff changeset
   238
        ptr = Malloc(ctx, newsize * sizeof (uint32));
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   239
        if (ptr == NULL)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   240
            return;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   241
        if (ctx->output_len > 0)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   242
            memcpy(ptr, ctx->output, ctx->output_len * sizeof (uint32));
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   243
        Free(ctx, ctx->output);
486
45efac751027 Added error_position to assembly results.
Ryan C. Gordon <icculus@icculus.org>
parents: 485
diff changeset
   244
        ctx->output = (uint32 *) ptr;
45efac751027 Added error_position to assembly results.
Ryan C. Gordon <icculus@icculus.org>
parents: 485
diff changeset
   245
536
5af65fe6e917 Allow multiple errors from parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 532
diff changeset
   246
        ptr = Malloc(ctx, newsize * sizeof (SourcePos));
486
45efac751027 Added error_position to assembly results.
Ryan C. Gordon <icculus@icculus.org>
parents: 485
diff changeset
   247
        if (ptr == NULL)
45efac751027 Added error_position to assembly results.
Ryan C. Gordon <icculus@icculus.org>
parents: 485
diff changeset
   248
            return;
45efac751027 Added error_position to assembly results.
Ryan C. Gordon <icculus@icculus.org>
parents: 485
diff changeset
   249
        if (ctx->output_len > 0)
536
5af65fe6e917 Allow multiple errors from parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 532
diff changeset
   250
            memcpy(ptr, ctx->token_to_source, ctx->output_len * sizeof (SourcePos));
5af65fe6e917 Allow multiple errors from parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 532
diff changeset
   251
        Free(ctx, ctx->token_to_source);
5af65fe6e917 Allow multiple errors from parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 532
diff changeset
   252
        ctx->token_to_source = (SourcePos *) ptr;
486
45efac751027 Added error_position to assembly results.
Ryan C. Gordon <icculus@icculus.org>
parents: 485
diff changeset
   253
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   254
        ctx->output_allocation = newsize;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   255
    } // if
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   256
486
45efac751027 Added error_position to assembly results.
Ryan C. Gordon <icculus@icculus.org>
parents: 485
diff changeset
   257
    ctx->output[ctx->output_len] = token;
536
5af65fe6e917 Allow multiple errors from parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 532
diff changeset
   258
    add_token_sourcepos(ctx, ctx->output_len);
486
45efac751027 Added error_position to assembly results.
Ryan C. Gordon <icculus@icculus.org>
parents: 485
diff changeset
   259
    ctx->output_len++;
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   260
} // output_token_noswap
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   261
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   262
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   263
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
   264
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   265
    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
   266
} // output_token
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   267
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   268
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   269
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
   270
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   271
    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
   272
        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
   273
    else if (!isfail(ctx))
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   274
    {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   275
        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
   276
        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
   277
        while (len >= 4)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   278
        {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   279
            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
   280
            len -= 4;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   281
            buf += 4;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   282
        } // while
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
        if (len > 0)  // handle spillover...
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   285
        {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   286
            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
   287
            overflow.ui32 = 0;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   288
            memcpy(overflow.ui8, buf, len);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   289
            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
   290
        } // if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   291
    } // else if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   292
} // output_comment_bytes
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   293
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   294
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   295
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
   296
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   297
    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
   298
} // output_comment_string
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   299
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   300
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   301
static int tokenize_ctx(Context *ctx, TokenizerContext *tctx)
465
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
    int idx = 0;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   304
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   305
    if (tctx->pushedback)
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   306
    {
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   307
        tctx->pushedback = 0;
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   308
        return 1;
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   309
    } // if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   310
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   311
    if (tctx->on_endline)
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   312
    {
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   313
        tctx->on_endline = 0;
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   314
        tctx->linenum++;  // passed a newline, update.
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   315
    } // if
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   316
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   317
    while (1)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   318
    {
477
e8c74c310a11 Added a FIXME.
Ryan C. Gordon <icculus@icculus.org>
parents: 472
diff changeset
   319
        // !!! FIXME: carefully crafted (but legal) comments can trigger this.
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   320
        if (idx >= sizeof (tctx->token))
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   321
        {
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   322
            fail(ctx, "buffer overflow");
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   323
            return 0;
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   324
        } // if
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   325
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   326
        char ch = *tctx->source;
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   327
        if (ch == '\t')
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   328
            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
   329
        else if (ch == '\r')
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   330
        {
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   331
            if (tctx->source[1] == '\n')
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   332
               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
   333
            ch = '\n';
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   334
        } // else if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   335
478
af4bfa5d615c Some basic tokenizer logic fixes.
Ryan C. Gordon <icculus@icculus.org>
parents: 477
diff changeset
   336
        if ((ch >= '0') && (ch <= '9'))
465
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
            // starting a number, but rest of current token was not number.
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   339
            if ((idx > 0) && ((tctx->prevchar < '0') || (tctx->prevchar > '9')))
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   340
            {
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   341
                tctx->token[idx++] = '\0';
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   342
                return 1;
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   343
            } // if
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
        else
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   346
        {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   347
            // starting a non-number, but rest of current token was numbers.
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   348
            if ((idx > 0) && ((tctx->prevchar >= '0') && (tctx->prevchar <= '9')))
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   349
            {
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   350
                tctx->token[idx++] = '\0';
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   351
                return 1;
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   352
            } // if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   353
        } // else
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
        switch (ch)
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
            case '/':
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   358
            case ';':  // !!! FIXME: comment, right?
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   359
                if (idx != 0)  // finish off existing token.
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   360
                    tctx->token[idx] = '\0';
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   361
                else
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   362
                {
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   363
                    tctx->token[idx++] = ch;
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   364
                    tctx->source++;
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   365
                    if ((ch == '/') && (*tctx->source == '/'))
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   366
                    {
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   367
                        tctx->token[idx++] = '/';
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   368
                        tctx->source++;
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   369
                    } // if
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   370
                    tctx->token[idx++] = '\0';
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   371
                } // else
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   372
                return 1;
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   373
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   374
            case ' ':
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   375
                if (tctx->prevchar == ' ')
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   376
                    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
   377
                // intentional fall-through...
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
            case '_':
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   380
            case '[':
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   381
            case ']':
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   382
            case '(':
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   383
            case ')':
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   384
            case '!':
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   385
            case '+':
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   386
            case '-':
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   387
            case ',':
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   388
            case '.':
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   389
            case '\n':
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   390
                if (idx != 0)  // finish off existing token.
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   391
                    tctx->token[idx] = '\0';
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   392
                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
   393
                {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   394
                    if (ch == '\n')
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   395
                        tctx->on_endline = 1;
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   396
                    tctx->source++;
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   397
                    tctx->token[idx++] = ch;
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   398
                    tctx->token[idx++] = '\0';
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   399
                } // else
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   400
                return 1;
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   401
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   402
            case '\0':
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   403
                tctx->token[idx] = '\0';
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   404
                if (idx != 0)  // had any chars? It's a token.
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   405
                    return 1;
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   406
                ctx->eof = 1;
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   407
                return 0;
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   408
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   409
            default:
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   410
                tctx->source++;
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   411
                tctx->token[idx++] = ch;
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   412
                break;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   413
        } // switch
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   414
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   415
        tctx->prevchar = ch;
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   416
    } // while
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   417
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   418
    assert(0 && "Shouldn't hit this code");
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   419
    return 0;
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   420
} // tokenize_ctx
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   421
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   422
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   423
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
   424
{
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   425
    const int rc = tokenize_ctx(ctx, &ctx->tctx);
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   426
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   427
    #if DEBUG_TOKENIZER
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   428
    printf("TOKENIZE: %d '%s'\n", rc,
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   429
           (ctx->tctx.token[0] == '\n') ? "\\n" : ctx->tctx.token);
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   430
    #endif
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   431
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   432
    return rc;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   433
} // tokenize
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   434
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   435
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   436
static void pushback_ctx(Context *ctx, TokenizerContext *tctx)
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   437
{
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   438
    assert(!tctx->pushedback);
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   439
    tctx->pushedback = 1;
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   440
} // pushback_ctx
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   441
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   442
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   443
static inline void pushback(Context *ctx)
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   444
{
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   445
    pushback_ctx(ctx, &ctx->tctx);
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   446
    #if DEBUG_TOKENIZER
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   447
    printf("PUSHBACK\n");
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   448
    #endif
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   449
} // pushback
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
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   452
static int nexttoken_ctx(Context *ctx, TokenizerContext *tctx,
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   453
                     const int ignoreeol, const int ignorewhitespace,
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   454
                     const int eolok, const int eosok)
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   455
{
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   456
    while (tokenize_ctx(ctx, tctx))
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   457
    {
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   458
        if (tokeq(tctx, "\n"))
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   459
        {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   460
            if (ignoreeol)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   461
                continue;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   462
            else if (!eolok)
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   463
            {
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   464
                fail(ctx, "Unexpected EOL");
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   465
                return 0;
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   466
            } // else if
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   467
        } // if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   468
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   469
        else if (tokeq(tctx, " "))
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   470
        {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   471
            if (ignorewhitespace)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   472
                continue;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   473
        } // else if
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
        // skip comments...
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   476
        else if (tokeq(tctx, "//") || tokeq(tctx, ";"))
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   477
        {
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   478
            while (tokenize_ctx(ctx, tctx))
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   479
            {
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   480
                if (tokeq(tctx, "\n"))
479
f7beff48de5e nexttoken() needs to report the ending newline when throwing away comments.
Ryan C. Gordon <icculus@icculus.org>
parents: 478
diff changeset
   481
                {
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   482
                    pushback_ctx(ctx, tctx);
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   483
                    break;
479
f7beff48de5e nexttoken() needs to report the ending newline when throwing away comments.
Ryan C. Gordon <icculus@icculus.org>
parents: 478
diff changeset
   484
                } // if
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   485
            } // while
479
f7beff48de5e nexttoken() needs to report the ending newline when throwing away comments.
Ryan C. Gordon <icculus@icculus.org>
parents: 478
diff changeset
   486
            continue;  // pick up from newline, go again.
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   487
        } // if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   488
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   489
        break;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   490
    } // while
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   491
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   492
    if ((ctx->eof) && (!eosok))
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   493
    {
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   494
        fail(ctx, "Unexpected EOF");
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   495
        return 0;
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   496
    } // if
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   497
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   498
    return 1;
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   499
} // nexttoken_ctx
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   500
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   501
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   502
static inline int nexttoken(Context *ctx, const int ignoreeol,
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   503
                     const int ignorewhitespace, const int eolok,
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   504
                     const int eosok)
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   505
{
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   506
    const int rc = nexttoken_ctx(ctx, &ctx->tctx, ignoreeol,
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   507
                                 ignorewhitespace, eolok, eosok);
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   508
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   509
    #if DEBUG_TOKENIZER
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   510
    printf("NEXTTOKEN: %d '%s'\n", rc,
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   511
           (ctx->tctx.token[0] == '\n') ? "\\n" : ctx->tctx.token);
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   512
    #endif
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   513
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   514
    return rc;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   515
} // nexttoken
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   516
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   517
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   518
static void skip_line(Context *ctx)
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   519
{
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   520
    if (!tokeq(&ctx->tctx, "\n"))
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   521
    {
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   522
        while (nexttoken(ctx, 0, 1, 1, 1))
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   523
        {
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   524
            if (tokeq(&ctx->tctx, "\n"))
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   525
                break;
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   526
        } // while
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   527
    } // if
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   528
} // skip_line
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   529
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   530
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   531
static void require_endline(Context *ctx)
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   532
{
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   533
    TokenizerContext *tctx = &ctx->tctx;
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   534
    const int rc = nexttoken(ctx, 0, 1, 1, 1);
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   535
    if (ctx->eof)
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   536
        return;  // we'll call this an EOL.
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   537
    else if ((rc == 0) || (!tokeq(tctx, "\n")))
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   538
    {
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   539
        fail(ctx, "Endline expected");
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   540
        skip_line(ctx);
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   541
    } // else if
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   542
} // require_endline
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   543
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   544
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   545
static int require_comma(Context *ctx)
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   546
{
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   547
    TokenizerContext *tctx = &ctx->tctx;
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   548
    const int rc = nexttoken(ctx, 0, 1, 0, 0);
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   549
    if ((rc == 0) || (!tokeq(tctx, ",")))
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   550
    {
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   551
        fail(ctx, "Comma expected");
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   552
        return 0;
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   553
    } // if
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   554
    return 1;
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   555
} // require_comma
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   556
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
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
   559
{
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   560
    TokenizerContext *tctx = &ctx->tctx;
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   561
    if (!nexttoken(ctx, 0, 1, 0, 0))
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   562
        return 0;
465
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
    int neednum = 1;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   565
    int regnum = 0;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   566
    RegisterType regtype = REG_TYPE_TEMP;
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   567
    if (tokeq(tctx, "r"))
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   568
        regtype = REG_TYPE_TEMP;
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   569
    else if (tokeq(tctx, "v"))
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   570
        regtype = REG_TYPE_INPUT;
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   571
    else if (tokeq(tctx, "c"))
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   572
        regtype = REG_TYPE_CONST;
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   573
    else if (tokeq(tctx, "i"))
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   574
        regtype = REG_TYPE_CONSTINT;
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   575
    else if (tokeq(tctx, "b"))
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   576
        regtype = REG_TYPE_CONSTBOOL;
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   577
    else if (tokeq(tctx, "oC"))
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   578
        regtype = REG_TYPE_COLOROUT;
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   579
    else if (tokeq(tctx, "s"))
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   580
        regtype = REG_TYPE_SAMPLER;
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   581
    else if (tokeq(tctx, "oD"))
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   582
        regtype = REG_TYPE_ATTROUT;
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   583
    else if (tokeq(tctx, "l"))
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   584
        regtype = REG_TYPE_LABEL;
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   585
    else if (tokeq(tctx, "p"))
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   586
        regtype = REG_TYPE_PREDICATE;
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   587
    else if (tokeq(tctx, "oDepth"))
513
abd9c85ba168 oDepth register doesn't have an index.
Ryan C. Gordon <icculus@icculus.org>
parents: 512
diff changeset
   588
    {
abd9c85ba168 oDepth register doesn't have an index.
Ryan C. Gordon <icculus@icculus.org>
parents: 512
diff changeset
   589
        regtype = REG_TYPE_DEPTHOUT;
abd9c85ba168 oDepth register doesn't have an index.
Ryan C. Gordon <icculus@icculus.org>
parents: 512
diff changeset
   590
        neednum = 0;
abd9c85ba168 oDepth register doesn't have an index.
Ryan C. Gordon <icculus@icculus.org>
parents: 512
diff changeset
   591
    } // else if
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   592
    else if (tokeq(tctx, "aL"))
465
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
        regtype = REG_TYPE_LOOP;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   595
        neednum = 0;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   596
    } // else if
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   597
    else if (tokeq(tctx, "o"))
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   598
    {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   599
        if (!shader_is_vertex(ctx) || !shader_version_atleast(ctx, 3, 0))
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   600
            fail(ctx, "Output register not valid in this shader type");
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   601
        regtype = REG_TYPE_OUTPUT;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   602
    } // else if
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   603
    else if (tokeq(tctx, "oT"))
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   604
    {
502
3cb501248990 Fixed logic error in assembler, to decide if oTx registers are available.
Ryan C. Gordon <icculus@icculus.org>
parents: 500
diff changeset
   605
        if (shader_is_vertex(ctx) && shader_version_atleast(ctx, 3, 0))
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   606
            fail(ctx, "Output register not valid in this shader type");
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   607
        regtype = REG_TYPE_OUTPUT;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   608
    } // else if
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   609
    else if (tokeq(tctx, "a"))
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   610
    {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   611
        if (!shader_is_vertex(ctx))
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   612
            fail(ctx, "Address register only valid in vertex shaders.");
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   613
        regtype = REG_TYPE_ADDRESS;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   614
    } // else if
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   615
    else if (tokeq(tctx, "t"))
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   616
    {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   617
        if (!shader_is_pixel(ctx))
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   618
            fail(ctx, "Address register only valid in pixel shaders.");
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   619
        regtype = REG_TYPE_ADDRESS;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   620
    } // else if
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   621
    else if (tokeq(tctx, "vPos"))
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   622
    {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   623
        regtype = REG_TYPE_MISCTYPE;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   624
        regnum = (int) MISCTYPE_TYPE_POSITION;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   625
        neednum = 0;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   626
    } // else if
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   627
    else if (tokeq(tctx, "vFace"))
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   628
    {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   629
        regtype = REG_TYPE_MISCTYPE;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   630
        regnum = (int) MISCTYPE_TYPE_FACE;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   631
        neednum = 0;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   632
    } // else if
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   633
    else if (tokeq(tctx, "oPos"))
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   634
    {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   635
        regtype = REG_TYPE_RASTOUT;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   636
        regnum = (int) RASTOUT_TYPE_POSITION;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   637
        neednum = 0;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   638
    } // else if
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   639
    else if (tokeq(tctx, "oFog"))
465
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
        regtype = REG_TYPE_RASTOUT;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   642
        regnum = (int) RASTOUT_TYPE_FOG;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   643
        neednum = 0;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   644
    } // else if
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   645
    else if (tokeq(tctx, "oPts"))
465
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
        regtype = REG_TYPE_RASTOUT;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   648
        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
   649
        neednum = 0;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   650
    } // else if
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
    //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
   653
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   654
    else
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   655
    {
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   656
        fail(ctx, "expected register type");
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   657
        regtype = REG_TYPE_CONST;
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   658
        regnum = 0;
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   659
        neednum = 0;
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   660
    } // else
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
    if (neednum)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   663
    {
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   664
        // Make a temp TokenizerContext, since we need to skip whitespace here,
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   665
        //  but if the next non-whitespace token isn't '[', we'll want to get
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   666
        //  that whitespace back.
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   667
        TokenizerContext tmptctx;
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   668
        memcpy(&tmptctx, tctx, sizeof (TokenizerContext));
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   669
        if (!nexttoken_ctx(ctx, &tmptctx, 0, 1, 1, 1))
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   670
            return 0;
522
3c08f4d2aa2e Fixed relative addressing parsing, again.
Ryan C. Gordon <icculus@icculus.org>
parents: 521
diff changeset
   671
        else if (tokeq(&tmptctx, "["))
482
3f740f25bd7e Fixed relative addressing parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 481
diff changeset
   672
            neednum = 0;
3f740f25bd7e Fixed relative addressing parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 481
diff changeset
   673
    } // if
3f740f25bd7e Fixed relative addressing parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 481
diff changeset
   674
3f740f25bd7e Fixed relative addressing parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 481
diff changeset
   675
    if (neednum)
3f740f25bd7e Fixed relative addressing parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 481
diff changeset
   676
    {
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   677
        if (!nexttoken(ctx, 0, 0, 0, 0))
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   678
            return 0;
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   679
482
3f740f25bd7e Fixed relative addressing parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 481
diff changeset
   680
        uint32 ui32 = 0;
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   681
        if (!ui32fromstr(tctx->token, &ui32))
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   682
            fail(ctx, "Invalid register index");
482
3f740f25bd7e Fixed relative addressing parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 481
diff changeset
   683
        regnum = (int) ui32;
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   684
    } // if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   685
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   686
    // split up REG_TYPE_CONST
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   687
    if (regtype == REG_TYPE_CONST)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   688
    {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   689
        if (regnum < 2048)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   690
        {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   691
            regtype = REG_TYPE_CONST;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   692
            regnum -= 0;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   693
        } // if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   694
        else if (regnum < 4096)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   695
        {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   696
            regtype = REG_TYPE_CONST2;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   697
            regnum -= 2048;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   698
        } // if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   699
        else if (regnum < 6144)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   700
        {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   701
            regtype = REG_TYPE_CONST3;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   702
            regnum -= 4096;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   703
        } // if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   704
        else if (regnum < 8192)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   705
        {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   706
            regtype = REG_TYPE_CONST4;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   707
            regnum -= 6144;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   708
        } // if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   709
        else
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   710
        {
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   711
            fail(ctx, "Invalid const register index");
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   712
        } // else
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   713
    } // if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   714
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   715
    *rtype = regtype;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   716
    *rnum = regnum;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   717
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   718
    return 1;
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   719
} // parse_register_name
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   720
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   721
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   722
static void set_result_shift(Context *ctx, DestArgInfo *info, const int val)
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   723
{
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   724
    if (info->result_shift != 0)
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   725
        fail(ctx, "Multiple result shift modifiers");
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   726
    info->result_shift = val;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   727
} // set_result_shift
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   728
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   729
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   730
static int parse_destination_token(Context *ctx)
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   731
{
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   732
    TokenizerContext *tctx = &ctx->tctx;
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   733
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   734
    DestArgInfo *info = &ctx->dest_arg;
510
f4433db86f6e Fixed wrong sizeof for a memset() call.
Ryan C. Gordon <icculus@icculus.org>
parents: 508
diff changeset
   735
    memset(info, '\0', sizeof (DestArgInfo));
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   736
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   737
    // 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
   738
    while (1)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   739
    {
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   740
        if (!nexttoken(ctx, 0, 0, 0, 0))
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   741
            return 1;
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   742
        else if (tokeq(tctx, " "))
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   743
            break;  // done with modifiers.
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   744
        else if (!tokeq(tctx, "_"))
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   745
            fail(ctx, "Expected modifier or whitespace");
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   746
        else if (!nexttoken(ctx, 0, 0, 0, 0))
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   747
            return 1;
511
67d7efa9206b Corrected parsing of result modifiers for my stupid tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 510
diff changeset
   748
        // !!! FIXME: this can be cleaned up when tokenizer is fixed.
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   749
        else if (tokeq(tctx, "x"))
511
67d7efa9206b Corrected parsing of result modifiers for my stupid tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 510
diff changeset
   750
        {
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   751
            if (!nexttoken(ctx, 0, 0, 0, 0))
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   752
                return 1;
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   753
            else if (tokeq(tctx, "2"))
511
67d7efa9206b Corrected parsing of result modifiers for my stupid tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 510
diff changeset
   754
                set_result_shift(ctx, info, 0x1);
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   755
            else if (tokeq(tctx, "4"))
511
67d7efa9206b Corrected parsing of result modifiers for my stupid tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 510
diff changeset
   756
                set_result_shift(ctx, info, 0x2);
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   757
            else if (tokeq(tctx, "8"))
511
67d7efa9206b Corrected parsing of result modifiers for my stupid tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 510
diff changeset
   758
                set_result_shift(ctx, info, 0x3);
67d7efa9206b Corrected parsing of result modifiers for my stupid tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 510
diff changeset
   759
            else
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   760
                fail(ctx, "Expected modifier");
511
67d7efa9206b Corrected parsing of result modifiers for my stupid tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 510
diff changeset
   761
        } // else if
67d7efa9206b Corrected parsing of result modifiers for my stupid tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 510
diff changeset
   762
        // !!! FIXME: this can be cleaned up when tokenizer is fixed.
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   763
        else if (tokeq(tctx, "d"))
511
67d7efa9206b Corrected parsing of result modifiers for my stupid tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 510
diff changeset
   764
        {
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   765
            if (!nexttoken(ctx, 0, 0, 0, 0))
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   766
                return 1;
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   767
            else if (tokeq(tctx, "8"))
511
67d7efa9206b Corrected parsing of result modifiers for my stupid tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 510
diff changeset
   768
                set_result_shift(ctx, info, 0xD);
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   769
            else if (tokeq(tctx, "4"))
511
67d7efa9206b Corrected parsing of result modifiers for my stupid tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 510
diff changeset
   770
                set_result_shift(ctx, info, 0xE);
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   771
            else if (tokeq(tctx, "2"))
511
67d7efa9206b Corrected parsing of result modifiers for my stupid tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 510
diff changeset
   772
                set_result_shift(ctx, info, 0xF);
67d7efa9206b Corrected parsing of result modifiers for my stupid tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 510
diff changeset
   773
            else
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   774
                fail(ctx, "Expected modifier");
511
67d7efa9206b Corrected parsing of result modifiers for my stupid tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 510
diff changeset
   775
        } // else if
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   776
        else if (tokeq(tctx, "sat"))
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   777
            info->result_mod |= MOD_SATURATE;
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   778
        else if (tokeq(tctx, "pp"))
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   779
            info->result_mod |= MOD_PP;
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   780
        else if (tokeq(tctx, "centroid"))
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   781
            info->result_mod |= MOD_CENTROID;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   782
        else
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   783
            fail(ctx, "Expected modifier");
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   784
    } // while
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   785
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   786
    if (!nexttoken(ctx, 0, 1, 0, 0))
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   787
        return 1;
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   788
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   789
    // !!! FIXME: predicates.
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   790
    if (tokeq(tctx, "("))
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   791
        fail(ctx, "Predicates unsupported at this time");  // !!! FIXME: ...
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   792
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   793
    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
   794
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   795
    parse_register_name(ctx, &info->regtype, &info->regnum);
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   796
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   797
    if (!nexttoken(ctx, 0, 1, 1, 1))
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   798
        return 1;
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   799
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   800
    // !!! 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
   801
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   802
    int invalid_writemask = 0;
521
57e1945104cb Workaround for incorrect assembly code generated by Cg.
Ryan C. Gordon <icculus@icculus.org>
parents: 519
diff changeset
   803
    int implicit_writemask = 0;
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   804
    if (!tokeq(tctx, "."))
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   805
    {
521
57e1945104cb Workaround for incorrect assembly code generated by Cg.
Ryan C. Gordon <icculus@icculus.org>
parents: 519
diff changeset
   806
        implicit_writemask = 1;
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   807
        info->writemask = 0xF;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   808
        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
   809
        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
   810
    } // if
521
57e1945104cb Workaround for incorrect assembly code generated by Cg.
Ryan C. Gordon <icculus@icculus.org>
parents: 519
diff changeset
   811
    // !!! FIXME: Cg generates code with oDepth.z ... this is a bug, I think.
57e1945104cb Workaround for incorrect assembly code generated by Cg.
Ryan C. Gordon <icculus@icculus.org>
parents: 519
diff changeset
   812
    //else if (scalar_register(ctx->shader_type, info->regtype, info->regnum))
57e1945104cb Workaround for incorrect assembly code generated by Cg.
Ryan C. Gordon <icculus@icculus.org>
parents: 519
diff changeset
   813
    else if ( (scalar_register(ctx->shader_type, info->regtype, info->regnum)) && (info->regtype != REG_TYPE_DEPTHOUT) )
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   814
        fail(ctx, "Writemask specified for scalar register");
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   815
    else if (!nexttoken(ctx, 0, 1, 0, 0))
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   816
        return 1;
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   817
    else if (tokeq(tctx, ""))
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   818
        invalid_writemask = 1;
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   819
    else
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   820
    {
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   821
        char *ptr = tctx->token;
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   822
        info->writemask0 = info->writemask1 = info->writemask2 = info->writemask3 = 0;
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   823
        if (*ptr == 'x') { info->writemask0 = 1; ptr++; }
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   824
        if (*ptr == 'y') { info->writemask1 = 1; ptr++; }
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   825
        if (*ptr == 'z') { info->writemask2 = 1; ptr++; }
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   826
        if (*ptr == 'w') { info->writemask3 = 1; ptr++; }
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   827
        if ((ptr == tctx->token) && (shader_is_pixel(ctx)))
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   828
        {
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   829
            if (*ptr == 'r') { info->writemask0 = 1; ptr++; }
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   830
            if (*ptr == 'g') { info->writemask1 = 1; ptr++; }
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   831
            if (*ptr == 'b') { info->writemask2 = 1; ptr++; }
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   832
            if (*ptr == 'a') { info->writemask3 = 1; ptr++; }
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   833
        } // if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   834
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   835
        if (*ptr != '\0')
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   836
            invalid_writemask = 1;
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   837
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   838
        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
   839
                            ((info->writemask1 & 0x1) << 1) |
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   840
                            ((info->writemask2 & 0x1) << 2) |
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   841
                            ((info->writemask3 & 0x1) << 3) );
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
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   844
    if (invalid_writemask)
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   845
        fail(ctx, "Invalid writemask");
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   846
521
57e1945104cb Workaround for incorrect assembly code generated by Cg.
Ryan C. Gordon <icculus@icculus.org>
parents: 519
diff changeset
   847
    // !!! FIXME: Cg generates code with oDepth.z ... this is a bug, I think.
57e1945104cb Workaround for incorrect assembly code generated by Cg.
Ryan C. Gordon <icculus@icculus.org>
parents: 519
diff changeset
   848
    if (info->regtype == REG_TYPE_DEPTHOUT)
57e1945104cb Workaround for incorrect assembly code generated by Cg.
Ryan C. Gordon <icculus@icculus.org>
parents: 519
diff changeset
   849
    {
57e1945104cb Workaround for incorrect assembly code generated by Cg.
Ryan C. Gordon <icculus@icculus.org>
parents: 519
diff changeset
   850
        if ( (!implicit_writemask) && ((info->writemask0 + info->writemask1 +
57e1945104cb Workaround for incorrect assembly code generated by Cg.
Ryan C. Gordon <icculus@icculus.org>
parents: 519
diff changeset
   851
               info->writemask2 + info->writemask3) > 1) )
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   852
            fail(ctx, "Writemask specified for scalar register");
521
57e1945104cb Workaround for incorrect assembly code generated by Cg.
Ryan C. Gordon <icculus@icculus.org>
parents: 519
diff changeset
   853
    } // if
57e1945104cb Workaround for incorrect assembly code generated by Cg.
Ryan C. Gordon <icculus@icculus.org>
parents: 519
diff changeset
   854
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   855
    info->orig_writemask = info->writemask;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   856
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   857
    if (ctx->tokenbufpos >= STATICARRAYLEN(ctx->tokenbuf))
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   858
    {
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   859
        fail(ctx, "Too many tokens");
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   860
        return 1;
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   861
    } // if
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   862
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   863
    ctx->tokenbuf[ctx->tokenbufpos++] =
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   864
            ( ((((uint32) 1)) << 31) |
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   865
              ((((uint32) info->regnum) & 0x7ff) << 0) |
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   866
              ((((uint32) info->relative) & 0x1) << 13) |
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   867
              ((((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
   868
              ((((uint32) info->result_shift) & 0xF) << 24) |
500
38ce929323c2 Fixed writemask bits in assembled bytecode.
Ryan C. Gordon <icculus@icculus.org>
parents: 499
diff changeset
   869
              ((((uint32) info->writemask) & 0xF) << 16) |
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   870
              ((((uint32) info->regtype) & 0x7) << 28) |
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   871
              ((((uint32) info->regtype) & 0x18) << 8) );
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   872
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   873
    return 1;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   874
} // parse_destination_token
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   875
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   876
472
e52d487e6d91 Bunch More Work on the assembler. Feature complete now?
Ryan C. Gordon <icculus@icculus.org>
parents: 470
diff changeset
   877
static void set_source_mod(Context *ctx, const int negate,
e52d487e6d91 Bunch More Work on the assembler. Feature complete now?
Ryan C. Gordon <icculus@icculus.org>
parents: 470
diff changeset
   878
                           const SourceMod norm, const SourceMod negated,
e52d487e6d91 Bunch More Work on the assembler. Feature complete now?
Ryan C. Gordon <icculus@icculus.org>
parents: 470
diff changeset
   879
                           SourceMod *srcmod)
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   880
{
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   881
    if ( (*srcmod != SRCMOD_NONE) || (negate && (negated == SRCMOD_NONE)) )
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   882
        fail(ctx, "Incompatible source modifiers");
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   883
    else
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   884
        *srcmod = ((negate) ? negated : norm);
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   885
} // set_source_mod
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   886
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   887
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   888
static int parse_source_token_maybe_relative(Context *ctx, const int relok)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   889
{
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   890
    TokenizerContext *tctx = &ctx->tctx;
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   891
    int retval = 1;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   892
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   893
    if (ctx->tokenbufpos >= STATICARRAYLEN(ctx->tokenbuf))
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   894
    {
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   895
        fail(ctx, "Too many tokens");
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   896
        return 0;
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   897
    } // if
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   898
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   899
    // mark this now, so optional relative addressing token is placed second.
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   900
    uint32 *token = &ctx->tokenbuf[ctx->tokenbufpos++];
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   901
    *token = 0;
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   902
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   903
    SourceMod srcmod = SRCMOD_NONE;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   904
    int negate = 0;
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   905
    if (!nexttoken(ctx, 0, 1, 0, 0))
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   906
        return 1;
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   907
    else if (tokeq(tctx, "1"))
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   908
    {
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   909
        if (!nexttoken(ctx, 0, 1, 0, 0))
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   910
            return 1;
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   911
        else if (!tokeq(tctx, "-"))
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   912
            fail(ctx, "Unexpected value");
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   913
        else
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   914
            srcmod = SRCMOD_COMPLEMENT;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   915
    } // else
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   916
    else if (tokeq(tctx, "!"))
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   917
        srcmod = SRCMOD_NOT;
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   918
    else if (tokeq(tctx, "-"))
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   919
        negate = 1;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   920
    else
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   921
        pushback(ctx);
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   922
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   923
    RegisterType regtype;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   924
    int regnum;
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   925
    parse_register_name(ctx, &regtype, &regnum);
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   926
    if (!nexttoken(ctx, 0, 1, 1, 1))
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   927
        return 1;
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   928
    else if (!tokeq(tctx, "_"))
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   929
        pushback(ctx);
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   930
    else if (!nexttoken(ctx, 0, 0, 0, 0))
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   931
        return 1;
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   932
    else if (tokeq(tctx, "bias"))
472
e52d487e6d91 Bunch More Work on the assembler. Feature complete now?
Ryan C. Gordon <icculus@icculus.org>
parents: 470
diff changeset
   933
        set_source_mod(ctx, negate, SRCMOD_BIAS, SRCMOD_BIASNEGATE, &srcmod);
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   934
    else if (tokeq(tctx, "bx2"))
472
e52d487e6d91 Bunch More Work on the assembler. Feature complete now?
Ryan C. Gordon <icculus@icculus.org>
parents: 470
diff changeset
   935
        set_source_mod(ctx, negate, SRCMOD_SIGN, SRCMOD_SIGNNEGATE, &srcmod);
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   936
    else if (tokeq(tctx, "x2"))
472
e52d487e6d91 Bunch More Work on the assembler. Feature complete now?
Ryan C. Gordon <icculus@icculus.org>
parents: 470
diff changeset
   937
        set_source_mod(ctx, negate, SRCMOD_X2, SRCMOD_X2NEGATE, &srcmod);
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   938
    else if (tokeq(tctx, "dz"))
472
e52d487e6d91 Bunch More Work on the assembler. Feature complete now?
Ryan C. Gordon <icculus@icculus.org>
parents: 470
diff changeset
   939
        set_source_mod(ctx, negate, SRCMOD_DZ, SRCMOD_NONE, &srcmod);
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   940
    else if (tokeq(tctx, "dw"))
472
e52d487e6d91 Bunch More Work on the assembler. Feature complete now?
Ryan C. Gordon <icculus@icculus.org>
parents: 470
diff changeset
   941
        set_source_mod(ctx, negate, SRCMOD_DW, SRCMOD_NONE, &srcmod);
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   942
    else if (tokeq(tctx, "abs"))
472
e52d487e6d91 Bunch More Work on the assembler. Feature complete now?
Ryan C. Gordon <icculus@icculus.org>
parents: 470
diff changeset
   943
        set_source_mod(ctx, negate, SRCMOD_ABS, SRCMOD_ABSNEGATE, &srcmod);
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   944
    else
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   945
        fail(ctx, "Invalid source modifier");
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   946
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   947
    if (!nexttoken(ctx, 0, 1, 1, 1))
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   948
        return 1;
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   949
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   950
    uint32 relative = 0;
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   951
    if (!tokeq(tctx, "["))
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   952
        pushback(ctx);  // not relative addressing?
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   953
    else
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   954
    {
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   955
        if (!relok)
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   956
            fail(ctx, "Relative addressing not permitted here.");
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   957
        else
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   958
            retval++;
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   959
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   960
        parse_source_token_maybe_relative(ctx, 0);
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   961
        relative = 1;
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   962
        if (!nexttoken(ctx, 0, 1, 0, 0))
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   963
            return retval;
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   964
        else if (!tokeq(tctx, "+"))
482
3f740f25bd7e Fixed relative addressing parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 481
diff changeset
   965
            pushback(ctx);
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   966
        else if (!nexttoken(ctx, 0, 1, 0, 0))
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   967
            return retval;
482
3f740f25bd7e Fixed relative addressing parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 481
diff changeset
   968
        else
3f740f25bd7e Fixed relative addressing parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 481
diff changeset
   969
        {
3f740f25bd7e Fixed relative addressing parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 481
diff changeset
   970
            if (regnum != 0)  // !!! FIXME: maybe c3[a0.x + 5] is legal and becomes c[a0.x + 8] ?
3f740f25bd7e Fixed relative addressing parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 481
diff changeset
   971
                fail(ctx, "Relative addressing with explicit register number.");
3f740f25bd7e Fixed relative addressing parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 481
diff changeset
   972
            uint32 ui32 = 0;
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   973
            if (!ui32fromstr(tctx->token, &ui32))
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   974
                fail(ctx, "Invalid relative addressing offset");
482
3f740f25bd7e Fixed relative addressing parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 481
diff changeset
   975
            regnum += (int) ui32;
3f740f25bd7e Fixed relative addressing parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 481
diff changeset
   976
        } // else
3f740f25bd7e Fixed relative addressing parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 481
diff changeset
   977
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   978
        if (!nexttoken(ctx, 0, 1, 0, 0))
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   979
            return retval;
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   980
        else if (!tokeq(tctx, "]"))
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   981
            fail(ctx, "Expected ']'");
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   982
    } // else
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   983
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   984
    if (!nexttoken(ctx, 0, 1, 1, 1))
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   985
        return retval;
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   986
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   987
    int invalid_swizzle = 0;
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   988
    uint32 swizzle = 0;
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   989
    if (!tokeq(tctx, "."))
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   990
    {
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   991
        swizzle = 0xE4;  // 0xE4 == 11100100 ... 0 1 2 3. No swizzle.
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   992
        pushback(ctx);  // no explicit writemask; do full mask.
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   993
    } // if
491
bcc3c215807a Fixed wrong data from scalar_register().
Ryan C. Gordon <icculus@icculus.org>
parents: 490
diff changeset
   994
    else if (scalar_register(ctx->shader_type, regtype, regnum))
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   995
        fail(ctx, "Swizzle specified for scalar register");
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   996
    else if (!nexttoken(ctx, 0, 1, 0, 0))
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   997
        return retval;
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   998
    else if (tokeq(tctx, ""))
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   999
        invalid_swizzle = 1;
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1000
    else
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1001
    {
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1002
        // deal with shortened form (.x = .xxxx, etc).
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
  1003
        if (tctx->token[1] == '\0')
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
  1004
            tctx->token[1] = tctx->token[2] = tctx->token[3] = tctx->token[0];
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
  1005
        else if (tctx->token[2] == '\0')
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
  1006
            tctx->token[2] = tctx->token[3] = tctx->token[1];
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
  1007
        else if (tctx->token[3] == '\0')
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
  1008
            tctx->token[3] = tctx->token[2];
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
  1009
        else if (tctx->token[4] != '\0')
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
  1010
            invalid_swizzle = 1;
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
  1011
        tctx->token[4] = '\0';
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1012
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
  1013
        uint32 val = 0;
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1014
        int saw_xyzw = 0;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1015
        int saw_rgba = 0;
472
e52d487e6d91 Bunch More Work on the assembler. Feature complete now?
Ryan C. Gordon <icculus@icculus.org>
parents: 470
diff changeset
  1016
        int i;
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1017
        for (i = 0; i < 4; i++)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1018
        {
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
  1019
            const int component = (int) tctx->token[i];
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1020
            switch (component)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1021
            {
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1022
                case 'x': val = 0; saw_xyzw = 1; break;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1023
                case 'y': val = 1; saw_xyzw = 1; break;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1024
                case 'z': val = 2; saw_xyzw = 1; break;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1025
                case 'w': val = 3; saw_xyzw = 1; break;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1026
                case 'r': val = 0; saw_rgba = 1; break;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1027
                case 'g': val = 1; saw_rgba = 1; break;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1028
                case 'b': val = 2; saw_rgba = 1; break;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1029
                case 'a': val = 3; saw_rgba = 1; break;
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
  1030
                default: invalid_swizzle = 1; break;
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1031
            } // switch
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1032
            swizzle |= (val << (i * 2));
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1033
        } // for
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1034
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1035
        if (saw_xyzw && saw_rgba)
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
  1036
            invalid_swizzle = 1;
548
b37cdacb50d5 Fixed parsing details of swizzles.
Ryan C. Gordon <icculus@icculus.org>
parents: 544
diff changeset
  1037
        else if (saw_rgba && !shader_is_pixel(ctx))
b37cdacb50d5 Fixed parsing details of swizzles.
Ryan C. Gordon <icculus@icculus.org>
parents: 544
diff changeset
  1038
            invalid_swizzle = 1;
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1039
    } // else
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1040
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
  1041
    if (invalid_swizzle)
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
  1042
        fail(ctx, "Invalid swizzle");
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
  1043
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1044
    *token = ( ((((uint32) 1)) << 31) |
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1045
               ((((uint32) regnum) & 0x7ff) << 0) |
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1046
               ((((uint32) relative) & 0x1) << 13) |
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1047
               ((((uint32) swizzle) & 0xFF) << 16) |
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1048
               ((((uint32) srcmod) & 0xF) << 24) |
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1049
               ((((uint32) regtype) & 0x7) << 28) |
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1050
               ((((uint32) regtype) & 0x18) << 8) );
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1051
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1052
    return retval;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1053
} // parse_source_token_maybe_relative
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1054
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1055
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1056
static inline int parse_source_token(Context *ctx)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1057
{
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1058
    return parse_source_token_maybe_relative(ctx, 1);
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1059
} // parse_source_token
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1060
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1061
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1062
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
  1063
{
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
  1064
    return 1;
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1065
} // parse_args_NULL
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1066
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1067
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1068
static int parse_num(Context *ctx, const int floatok, uint32 *token)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1069
{
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
  1070
    TokenizerContext *tctx = &ctx->tctx;
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1071
    int32 negative = 1;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1072
    union { float f; int32 si32; uint32 ui32; } cvt;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1073
    cvt.si32 = 0;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1074
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
  1075
    *token = 0;
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
  1076
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
  1077
    if (!nexttoken(ctx, 0, 1, 0, 0))
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
  1078
        return 0;
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
  1079
    else if (tokeq(tctx, "-"))
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1080
        negative = -1;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1081
    else
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1082
        pushback(ctx);
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1083
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1084
    uint32 val = 0;
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
  1085
    if (!nexttoken(ctx, 0, 1, 0, 0))
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
  1086
        return 0;
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
  1087
    else if (!ui32fromstr(tctx->token, &val))
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
  1088
        fail(ctx, "Expected number");
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1089
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1090
    uint32 fraction = 0;
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
  1091
    if (!nexttoken(ctx, 0, 1, 1, 1))
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
  1092
        return 0;
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
  1093
    else if (!tokeq(tctx, "."))
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1094
        pushback(ctx);  // whole number
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1095
    else if (!floatok)
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
  1096
        fail(ctx, "Expected whole number");
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
  1097
    else if (!nexttoken(ctx, 0, 1, 0, 0))
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
  1098
        return 0;
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
  1099
    else if (!ui32fromstr(tctx->token, &fraction))
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
  1100
        fail(ctx, "Expected number");
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1101
492
29bfa3448549 Handle exponents in number parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 491
diff changeset
  1102
    uint32 exponent = 0;
29bfa3448549 Handle exponents in number parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 491
diff changeset
  1103
    int negexp = 0;
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
  1104
    if (!nexttoken(ctx, 0, 1, 1, 1))
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
  1105
        return 0;
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
  1106
    else if (!tokeq(tctx, "e"))
492
29bfa3448549 Handle exponents in number parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 491
diff changeset
  1107
        pushback(ctx);
29bfa3448549 Handle exponents in number parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: