mojoshader_assembler.c
author Ryan C. Gordon <icculus@icculus.org>
Thu, 12 Feb 2009 01:47:35 -0500
changeset 573 1cd1d99a79cb
parent 572 cdc8bb82f7d2
child 574 71c06777f95e
permissions -rw-r--r--
Rearrange how we test for register names to avoid substring matches. For example: "oD" would match "oDepth" and cause all sorts of chaos.
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
571
f8f81d832fa0 Disabled assembly parser debug output, for now.
Ryan C. Gordon <icculus@icculus.org>
parents: 570
diff changeset
    13
#define DEBUG_ASSEMBLY_PARSER 0
566
6bd82a5acf62 Added more debug output.
Ryan C. Gordon <icculus@icculus.org>
parents: 562
diff changeset
    14
562
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
    15
// Simple linked list to cache source filenames, so we don't have to copy
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
    16
//  the same string over and over for each opcode.
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
    17
typedef struct FilenameCache
514
ba913834b491 The parse_args_DCL fiasco continues.
Ryan C. Gordon <icculus@icculus.org>
parents: 513
diff changeset
    18
{
562
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
    19
    char *filename;
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
    20
    struct FilenameCache *next;
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
    21
} FilenameCache;
514
ba913834b491 The parse_args_DCL fiasco continues.
Ryan C. Gordon <icculus@icculus.org>
parents: 513
diff changeset
    22
ba913834b491 The parse_args_DCL fiasco continues.
Ryan C. Gordon <icculus@icculus.org>
parents: 513
diff changeset
    23
536
5af65fe6e917 Allow multiple errors from parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 532
diff changeset
    24
typedef struct SourcePos
5af65fe6e917 Allow multiple errors from parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 532
diff changeset
    25
{
5af65fe6e917 Allow multiple errors from parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 532
diff changeset
    26
    const char *filename;
5af65fe6e917 Allow multiple errors from parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 532
diff changeset
    27
    uint32 line;
5af65fe6e917 Allow multiple errors from parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 532
diff changeset
    28
} SourcePos;
5af65fe6e917 Allow multiple errors from parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 532
diff changeset
    29
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    30
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    31
// 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
    32
typedef struct Context
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    33
{
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
    34
    int isfail;
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
    35
    int out_of_memory;
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    36
    MOJOSHADER_malloc malloc;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    37
    MOJOSHADER_free free;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    38
    void *malloc_data;
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
    39
    int error_count;
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
    40
    ErrorList *errors;
562
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
    41
    Preprocessor *preprocessor;
523
699696afd731 Allow errors to specify post-processing problems.
Ryan C. Gordon <icculus@icculus.org>
parents: 522
diff changeset
    42
    MOJOSHADER_parsePhase parse_phase;
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    43
    MOJOSHADER_shaderType shader_type;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    44
    uint8 major_ver;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    45
    uint8 minor_ver;
562
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
    46
    int pushedback;
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
    47
    const char *token;      // assembler token!
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
    48
    unsigned int tokenlen;  // assembler token!
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
    49
    Token tokenval;         // assembler token!
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
    50
    uint32 version_token;   // bytecode token!
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
    51
    uint32 tokenbuf[16];    // bytecode tokens!
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
    52
    int tokenbufpos;        // bytecode tokens!
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    53
    DestArgInfo dest_arg;
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
    54
    uint32 *output;
536
5af65fe6e917 Allow multiple errors from parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 532
diff changeset
    55
    SourcePos *token_to_source;
524
03eea2f0762c First (incomplete!) shot at more robust CTAB support.
Ryan C. Gordon <icculus@icculus.org>
parents: 523
diff changeset
    56
    uint8 *ctab;
03eea2f0762c First (incomplete!) shot at more robust CTAB support.
Ryan C. Gordon <icculus@icculus.org>
parents: 523
diff changeset
    57
    uint32 ctab_len;
03eea2f0762c First (incomplete!) shot at more robust CTAB support.
Ryan C. Gordon <icculus@icculus.org>
parents: 523
diff changeset
    58
    uint32 ctab_allocation;
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
    59
    size_t output_len;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
    60
    size_t output_allocation;
562
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
    61
    FilenameCache *filename_cache;
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);
554
42dd28107cd8 Simplify StrDup().
Ryan C. Gordon <icculus@icculus.org>
parents: 553
diff changeset
    83
    if (retval != NULL)
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
    84
        strcpy(retval, str);
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
    85
    return retval;
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
    86
} // StrDup
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
    87
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    88
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
    89
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    90
    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
    91
        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
    92
} // Free
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    93
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
    94
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
    95
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
    96
{
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
    97
    const char *fname = NULL;
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
    98
    unsigned int linenum = 0;
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
    99
    int error_position = 0;
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   100
550
2f977a75d2b5 Fixed error reporting in assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 549
diff changeset
   101
    ctx->isfail = 1;
2f977a75d2b5 Fixed error reporting in assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 549
diff changeset
   102
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   103
    switch (ctx->parse_phase)
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   104
    {
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   105
        case MOJOSHADER_PARSEPHASE_NOTSTARTED:
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   106
            error_position = -2;
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   107
            break;
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   108
        case MOJOSHADER_PARSEPHASE_WORKING:
567
1a61d0cf86ba Fixed assembler error line numbers.
Ryan C. Gordon <icculus@icculus.org>
parents: 566
diff changeset
   109
            fname = preprocessor_sourcepos(ctx->preprocessor, &linenum);
1a61d0cf86ba Fixed assembler error line numbers.
Ryan C. Gordon <icculus@icculus.org>
parents: 566
diff changeset
   110
            error_position = (int) linenum;
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   111
            break;
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   112
        case MOJOSHADER_PARSEPHASE_DONE:
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   113
            error_position = -1;
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   114
            break;
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   115
        default:
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   116
            assert(0 && "Unexpected value");
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   117
            return;
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   118
    } // switch
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   119
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   120
    ErrorList *error = (ErrorList *) Malloc(ctx, sizeof (ErrorList));
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   121
    if (error == NULL)
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   122
        return;
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   123
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   124
    char scratch = 0;
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   125
    va_list ap;
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   126
    va_start(ap, fmt);
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   127
    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
   128
    va_end(ap);
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   129
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   130
    char *failstr = (char *) Malloc(ctx, len + 1);
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   131
    if (failstr == NULL)
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   132
        Free(ctx, error);
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   133
    else
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   134
    {
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   135
        va_start(ap, fmt);
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   136
        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
   137
        va_end(ap);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   138
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   139
        error->error.error = failstr;
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   140
        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
   141
        error->error.error_position = error_position;
544
f829f48e5214 Fixed stupid linked list bug.
Ryan C. Gordon <icculus@icculus.org>
parents: 543
diff changeset
   142
        error->next = NULL;
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   143
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   144
        ErrorList *prev = NULL;
544
f829f48e5214 Fixed stupid linked list bug.
Ryan C. Gordon <icculus@icculus.org>
parents: 543
diff changeset
   145
        ErrorList *item = ctx->errors;
f829f48e5214 Fixed stupid linked list bug.
Ryan C. Gordon <icculus@icculus.org>
parents: 543
diff changeset
   146
        while (item != NULL)
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   147
        {
544
f829f48e5214 Fixed stupid linked list bug.
Ryan C. Gordon <icculus@icculus.org>
parents: 543
diff changeset
   148
            prev = item;
558
314c86ff14dd Fixed stupid linked list bug.
Ryan C. Gordon <icculus@icculus.org>
parents: 554
diff changeset
   149
            item = item->next;
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   150
        } // while
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   151
544
f829f48e5214 Fixed stupid linked list bug.
Ryan C. Gordon <icculus@icculus.org>
parents: 543
diff changeset
   152
        if (prev == NULL)
f829f48e5214 Fixed stupid linked list bug.
Ryan C. Gordon <icculus@icculus.org>
parents: 543
diff changeset
   153
            ctx->errors = error;
f829f48e5214 Fixed stupid linked list bug.
Ryan C. Gordon <icculus@icculus.org>
parents: 543
diff changeset
   154
        else
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   155
            prev->next = error;
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   156
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   157
        ctx->error_count++;
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   158
    } // else
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   159
} // failf
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   160
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   161
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
   162
{
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   163
    failf(ctx, "%s", reason);
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   164
} // fail
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   165
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   166
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
   167
{
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   168
    return ctx->isfail;
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   169
} // isfail
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   170
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   171
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   172
// Shader model version magic...
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 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
   175
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   176
    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
   177
} // version_ui32
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
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
   180
                                         const uint8 min)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   181
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   182
    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
   183
} // shader_version_atleast
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   184
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   185
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
   186
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   187
    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
   188
} // shader_is_pixel
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   189
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   190
static 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
   191
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   192
    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
   193
} // shader_is_vertex
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   194
562
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   195
static inline void pushback(Context *ctx)
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   196
{
566
6bd82a5acf62 Added more debug output.
Ryan C. Gordon <icculus@icculus.org>
parents: 562
diff changeset
   197
    #if DEBUG_ASSEMBLY_PARSER
6bd82a5acf62 Added more debug output.
Ryan C. Gordon <icculus@icculus.org>
parents: 562
diff changeset
   198
    printf("ASSEMBLER PUSHBACK\n");
6bd82a5acf62 Added more debug output.
Ryan C. Gordon <icculus@icculus.org>
parents: 562
diff changeset
   199
    #endif
562
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   200
    assert(!ctx->pushedback);
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   201
    ctx->pushedback = 1;
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   202
} // pushback
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   203
562
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   204
static Token _nexttoken(Context *ctx)
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   205
{
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   206
    ctx->token = preprocessor_nexttoken(ctx->preprocessor, &ctx->tokenlen,
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   207
                                        &ctx->tokenval);
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   208
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   209
    if (preprocessor_outofmemory(ctx->preprocessor))
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   210
    {
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   211
        out_of_memory(ctx);
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   212
        ctx->tokenval = TOKEN_EOI;
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   213
        ctx->token = NULL;
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   214
        ctx->tokenlen = 0;
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   215
    } // if
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   216
    else
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   217
    {
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   218
        const char *err = preprocessor_error(ctx->preprocessor);
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   219
        if (err)
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   220
            fail(ctx, err);
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   221
    } // else
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   222
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   223
    return ctx->tokenval;
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   224
} // _nexttoken
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   225
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   226
566
6bd82a5acf62 Added more debug output.
Ryan C. Gordon <icculus@icculus.org>
parents: 562
diff changeset
   227
// !!! FIXME: cut-and-paste from preprocessor.
571
f8f81d832fa0 Disabled assembly parser debug output, for now.
Ryan C. Gordon <icculus@icculus.org>
parents: 570
diff changeset
   228
#if !DEBUG_ASSEMBLY_PARSER
f8f81d832fa0 Disabled assembly parser debug output, for now.
Ryan C. Gordon <icculus@icculus.org>
parents: 570
diff changeset
   229
#define print_debug_token(ctx)
f8f81d832fa0 Disabled assembly parser debug output, for now.
Ryan C. Gordon <icculus@icculus.org>
parents: 570
diff changeset
   230
#else
566
6bd82a5acf62 Added more debug output.
Ryan C. Gordon <icculus@icculus.org>
parents: 562
diff changeset
   231
static void print_debug_token(Context *ctx)
6bd82a5acf62 Added more debug output.
Ryan C. Gordon <icculus@icculus.org>
parents: 562
diff changeset
   232
{
6bd82a5acf62 Added more debug output.
Ryan C. Gordon <icculus@icculus.org>
parents: 562
diff changeset
   233
    printf("ASSEMBLER TOKEN: \"");
6bd82a5acf62 Added more debug output.
Ryan C. Gordon <icculus@icculus.org>
parents: 562
diff changeset
   234
    unsigned int i;
6bd82a5acf62 Added more debug output.
Ryan C. Gordon <icculus@icculus.org>
parents: 562
diff changeset
   235
    for (i = 0; i < ctx->tokenlen; i++)
6bd82a5acf62 Added more debug output.
Ryan C. Gordon <icculus@icculus.org>
parents: 562
diff changeset
   236
    {
6bd82a5acf62 Added more debug output.
Ryan C. Gordon <icculus@icculus.org>
parents: 562
diff changeset
   237
        if (ctx->token[i] == '\n')
6bd82a5acf62 Added more debug output.
Ryan C. Gordon <icculus@icculus.org>
parents: 562
diff changeset
   238
            printf("\\n");
6bd82a5acf62 Added more debug output.
Ryan C. Gordon <icculus@icculus.org>
parents: 562
diff changeset
   239
        else
6bd82a5acf62 Added more debug output.
Ryan C. Gordon <icculus@icculus.org>
parents: 562
diff changeset
   240
            printf("%c", ctx->token[i]);
6bd82a5acf62 Added more debug output.
Ryan C. Gordon <icculus@icculus.org>
parents: 562
diff changeset
   241
    } // for
6bd82a5acf62 Added more debug output.
Ryan C. Gordon <icculus@icculus.org>
parents: 562
diff changeset
   242
    printf("\" (");
6bd82a5acf62 Added more debug output.
Ryan C. Gordon <icculus@icculus.org>
parents: 562
diff changeset
   243
    switch (ctx->tokenval)
6bd82a5acf62 Added more debug output.
Ryan C. Gordon <icculus@icculus.org>
parents: 562
diff changeset
   244
    {
6bd82a5acf62 Added more debug output.
Ryan C. Gordon <icculus@icculus.org>
parents: 562
diff changeset
   245
        #define TOKENCASE(x) case x: printf("%s", #x); break
6bd82a5acf62 Added more debug output.
Ryan C. Gordon <icculus@icculus.org>
parents: 562
diff changeset
   246
        TOKENCASE(TOKEN_UNKNOWN);
6bd82a5acf62 Added more debug output.
Ryan C. Gordon <icculus@icculus.org>
parents: 562
diff changeset
   247
        TOKENCASE(TOKEN_IDENTIFIER);
6bd82a5acf62 Added more debug output.
Ryan C. Gordon <icculus@icculus.org>
parents: 562
diff changeset
   248
        TOKENCASE(TOKEN_INT_LITERAL);
6bd82a5acf62 Added more debug output.
Ryan C. Gordon <icculus@icculus.org>
parents: 562
diff changeset
   249
        TOKENCASE(TOKEN_FLOAT_LITERAL);
6bd82a5acf62 Added more debug output.
Ryan C. Gordon <icculus@icculus.org>
parents: 562
diff changeset
   250
        TOKENCASE(TOKEN_STRING_LITERAL);
6bd82a5acf62 Added more debug output.
Ryan C. Gordon <icculus@icculus.org>
parents: 562
diff changeset
   251
        TOKENCASE(TOKEN_ELLIPSIS);
6bd82a5acf62 Added more debug output.
Ryan C. Gordon <icculus@icculus.org>
parents: 562
diff changeset
   252
        TOKENCASE(TOKEN_RSHIFT);
6bd82a5acf62 Added more debug output.
Ryan C. Gordon <icculus@icculus.org>
parents: 562
diff changeset
   253
        TOKENCASE(TOKEN_LSHIFT);
6bd82a5acf62 Added more debug output.
Ryan C. Gordon <icculus@icculus.org>
parents: 562
diff changeset
   254
        TOKENCASE(TOKEN_ANDAND);
6bd82a5acf62 Added more debug output.
Ryan C. Gordon <icculus@icculus.org>
parents: 562
diff changeset
   255
        TOKENCASE(TOKEN_OROR);
6bd82a5acf62 Added more debug output.
Ryan C. Gordon <icculus@icculus.org>
parents: 562
diff changeset
   256
        TOKENCASE(TOKEN_LEQ);
6bd82a5acf62 Added more debug output.
Ryan C. Gordon <icculus@icculus.org>
parents: 562
diff changeset
   257
        TOKENCASE(TOKEN_GEQ);
6bd82a5acf62 Added more debug output.
Ryan C. Gordon <icculus@icculus.org>
parents: 562
diff changeset
   258
        TOKENCASE(TOKEN_EQL);
6bd82a5acf62 Added more debug output.
Ryan C. Gordon <icculus@icculus.org>
parents: 562
diff changeset
   259
        TOKENCASE(TOKEN_NEQ);
6bd82a5acf62 Added more debug output.
Ryan C. Gordon <icculus@icculus.org>
parents: 562
diff changeset
   260
        TOKENCASE(TOKEN_HASHHASH);
6bd82a5acf62 Added more debug output.
Ryan C. Gordon <icculus@icculus.org>
parents: 562
diff changeset
   261
        TOKENCASE(TOKEN_PP_INCLUDE);
6bd82a5acf62 Added more debug output.
Ryan C. Gordon <icculus@icculus.org>
parents: 562
diff changeset
   262
        TOKENCASE(TOKEN_PP_LINE);
6bd82a5acf62 Added more debug output.
Ryan C. Gordon <icculus@icculus.org>
parents: 562
diff changeset
   263
        TOKENCASE(TOKEN_PP_DEFINE);
6bd82a5acf62 Added more debug output.
Ryan C. Gordon <icculus@icculus.org>
parents: 562
diff changeset
   264
        TOKENCASE(TOKEN_PP_UNDEF);
6bd82a5acf62 Added more debug output.
Ryan C. Gordon <icculus@icculus.org>
parents: 562
diff changeset
   265
        TOKENCASE(TOKEN_PP_IF);
6bd82a5acf62 Added more debug output.
Ryan C. Gordon <icculus@icculus.org>
parents: 562
diff changeset
   266
        TOKENCASE(TOKEN_PP_IFDEF);
6bd82a5acf62 Added more debug output.
Ryan C. Gordon <icculus@icculus.org>
parents: 562
diff changeset
   267
        TOKENCASE(TOKEN_PP_IFNDEF);
6bd82a5acf62 Added more debug output.
Ryan C. Gordon <icculus@icculus.org>
parents: 562
diff changeset
   268
        TOKENCASE(TOKEN_PP_ELSE);
6bd82a5acf62 Added more debug output.
Ryan C. Gordon <icculus@icculus.org>
parents: 562
diff changeset
   269
        TOKENCASE(TOKEN_PP_ELIF);
6bd82a5acf62 Added more debug output.
Ryan C. Gordon <icculus@icculus.org>
parents: 562
diff changeset
   270
        TOKENCASE(TOKEN_PP_ENDIF);
6bd82a5acf62 Added more debug output.
Ryan C. Gordon <icculus@icculus.org>
parents: 562
diff changeset
   271
        TOKENCASE(TOKEN_PP_ERROR);
6bd82a5acf62 Added more debug output.
Ryan C. Gordon <icculus@icculus.org>
parents: 562
diff changeset
   272
        TOKENCASE(TOKEN_PP_INCOMPLETE_COMMENT);
6bd82a5acf62 Added more debug output.
Ryan C. Gordon <icculus@icculus.org>
parents: 562
diff changeset
   273
        TOKENCASE(TOKEN_EOI);
6bd82a5acf62 Added more debug output.
Ryan C. Gordon <icculus@icculus.org>
parents: 562
diff changeset
   274
        #undef TOKENCASE
6bd82a5acf62 Added more debug output.
Ryan C. Gordon <icculus@icculus.org>
parents: 562
diff changeset
   275
6bd82a5acf62 Added more debug output.
Ryan C. Gordon <icculus@icculus.org>
parents: 562
diff changeset
   276
        case ((Token) '\n'):
6bd82a5acf62 Added more debug output.
Ryan C. Gordon <icculus@icculus.org>
parents: 562
diff changeset
   277
            printf("'\\n'");
6bd82a5acf62 Added more debug output.
Ryan C. Gordon <icculus@icculus.org>
parents: 562
diff changeset
   278
            break;
6bd82a5acf62 Added more debug output.
Ryan C. Gordon <icculus@icculus.org>
parents: 562
diff changeset
   279
6bd82a5acf62 Added more debug output.
Ryan C. Gordon <icculus@icculus.org>
parents: 562
diff changeset
   280
        default:
6bd82a5acf62 Added more debug output.
Ryan C. Gordon <icculus@icculus.org>
parents: 562
diff changeset
   281
            assert(((int)ctx->tokenval) < 256);
6bd82a5acf62 Added more debug output.
Ryan C. Gordon <icculus@icculus.org>
parents: 562
diff changeset
   282
            printf("'%c'", (char) ctx->tokenval);
6bd82a5acf62 Added more debug output.
Ryan C. Gordon <icculus@icculus.org>
parents: 562
diff changeset
   283
            break;
6bd82a5acf62 Added more debug output.
Ryan C. Gordon <icculus@icculus.org>
parents: 562
diff changeset
   284
    } // switch
6bd82a5acf62 Added more debug output.
Ryan C. Gordon <icculus@icculus.org>
parents: 562
diff changeset
   285
    printf(")\n");
6bd82a5acf62 Added more debug output.
Ryan C. Gordon <icculus@icculus.org>
parents: 562
diff changeset
   286
}
6bd82a5acf62 Added more debug output.
Ryan C. Gordon <icculus@icculus.org>
parents: 562
diff changeset
   287
#endif
6bd82a5acf62 Added more debug output.
Ryan C. Gordon <icculus@icculus.org>
parents: 562
diff changeset
   288
562
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   289
static Token nexttoken(Context *ctx)
482
3f740f25bd7e Fixed relative addressing parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 481
diff changeset
   290
{
562
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   291
    if (ctx->pushedback)
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   292
    {
566
6bd82a5acf62 Added more debug output.
Ryan C. Gordon <icculus@icculus.org>
parents: 562
diff changeset
   293
        print_debug_token(ctx);
562
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   294
        ctx->pushedback = 0;
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   295
        return ctx->tokenval;
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   296
    } // if
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   297
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   298
    Token token = _nexttoken(ctx);
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   299
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   300
    while (token == ((Token) '\n'))
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   301
        token = _nexttoken(ctx);  // skip endlines.
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   302
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   303
    if (token == ((Token) ';'))  // single line comment in assembler.
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   304
    {
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   305
        do
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   306
        {
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   307
            token = _nexttoken(ctx);
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   308
        } while ((token != ((Token) '\n')) && (token != TOKEN_EOI));
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   309
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   310
        while (token == ((Token) '\n'))
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   311
            token = _nexttoken(ctx);  // skip endlines.
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   312
    } // if
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   313
566
6bd82a5acf62 Added more debug output.
Ryan C. Gordon <icculus@icculus.org>
parents: 562
diff changeset
   314
    print_debug_token(ctx);
562
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   315
    return token;
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   316
} // nexttoken
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   317
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   318
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   319
static const char *cache_filename(Context *ctx, const char *fname)
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   320
{
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   321
    if (fname == NULL)
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   322
        return NULL;
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   323
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   324
    // !!! FIXME: this could be optimized into a hash table, but oh well.
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   325
    FilenameCache *item = ctx->filename_cache;
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   326
    while (item != NULL)
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   327
    {
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   328
        if (strcmp(item->filename, fname) == 0)
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   329
            return item->filename;
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   330
        item = item->next;
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   331
    } // while
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   332
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   333
    // new cache item.
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   334
    item = (FilenameCache *) Malloc(ctx, sizeof (FilenameCache));
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   335
    if (item == NULL)
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   336
        return NULL;
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   337
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   338
    item->filename = (char *) Malloc(ctx, strlen(fname) + 1);
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   339
    if (item->filename == NULL)
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   340
    {
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   341
        Free(ctx, item);
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   342
        return NULL;
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   343
    } // if
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   344
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   345
    strcpy(item->filename, fname);
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   346
    item->next = ctx->filename_cache;
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   347
    ctx->filename_cache = item;
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   348
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   349
    return item->filename;
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   350
} // cache_filename
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   351
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   352
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   353
static void free_filename_cache(Context *ctx)
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   354
{
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   355
    FilenameCache *item = ctx->filename_cache;
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   356
    while (item != NULL)
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   357
    {
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   358
        FilenameCache *next = item->next;
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   359
        Free(ctx, item->filename);
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   360
        Free(ctx, item);
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   361
        item = next;
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   362
    } // while
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   363
} // free_filename_cache
482
3f740f25bd7e Fixed relative addressing parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 481
diff changeset
   364
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   365
536
5af65fe6e917 Allow multiple errors from parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 532
diff changeset
   366
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
   367
{
562
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   368
    unsigned int pos = 0;
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   369
    const char *fname = preprocessor_sourcepos(ctx->preprocessor, &pos);
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   370
    ctx->token_to_source[idx].line = pos;
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   371
    ctx->token_to_source[idx].filename = cache_filename(ctx, fname);
536
5af65fe6e917 Allow multiple errors from parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 532
diff changeset
   372
} // add_token_sourcepos
5af65fe6e917 Allow multiple errors from parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 532
diff changeset
   373
5af65fe6e917 Allow multiple errors from parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 532
diff changeset
   374
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   375
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
   376
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   377
    if (isfail(ctx))
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   378
        return;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   379
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   380
    if (ctx->output_len >= ctx->output_allocation)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   381
    {
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   382
        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
   383
        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
   384
        void *ptr;
45efac751027 Added error_position to assembly results.
Ryan C. Gordon <icculus@icculus.org>
parents: 485
diff changeset
   385
45efac751027 Added error_position to assembly results.
Ryan C. Gordon <icculus@icculus.org>
parents: 485
diff changeset
   386
        ptr = Malloc(ctx, newsize * sizeof (uint32));
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   387
        if (ptr == NULL)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   388
            return;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   389
        if (ctx->output_len > 0)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   390
            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
   391
        Free(ctx, ctx->output);
486
45efac751027 Added error_position to assembly results.
Ryan C. Gordon <icculus@icculus.org>
parents: 485
diff changeset
   392
        ctx->output = (uint32 *) ptr;
45efac751027 Added error_position to assembly results.
Ryan C. Gordon <icculus@icculus.org>
parents: 485
diff changeset
   393
536
5af65fe6e917 Allow multiple errors from parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 532
diff changeset
   394
        ptr = Malloc(ctx, newsize * sizeof (SourcePos));
486
45efac751027 Added error_position to assembly results.
Ryan C. Gordon <icculus@icculus.org>
parents: 485
diff changeset
   395
        if (ptr == NULL)
45efac751027 Added error_position to assembly results.
Ryan C. Gordon <icculus@icculus.org>
parents: 485
diff changeset
   396
            return;
45efac751027 Added error_position to assembly results.
Ryan C. Gordon <icculus@icculus.org>
parents: 485
diff changeset
   397
        if (ctx->output_len > 0)
536
5af65fe6e917 Allow multiple errors from parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 532
diff changeset
   398
            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
   399
        Free(ctx, ctx->token_to_source);
5af65fe6e917 Allow multiple errors from parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 532
diff changeset
   400
        ctx->token_to_source = (SourcePos *) ptr;
486
45efac751027 Added error_position to assembly results.
Ryan C. Gordon <icculus@icculus.org>
parents: 485
diff changeset
   401
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   402
        ctx->output_allocation = newsize;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   403
    } // if
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   404
486
45efac751027 Added error_position to assembly results.
Ryan C. Gordon <icculus@icculus.org>
parents: 485
diff changeset
   405
    ctx->output[ctx->output_len] = token;
536
5af65fe6e917 Allow multiple errors from parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 532
diff changeset
   406
    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
   407
    ctx->output_len++;
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   408
} // output_token_noswap
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   409
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   410
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   411
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
   412
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   413
    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
   414
} // output_token
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   415
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   416
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   417
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
   418
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   419
    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
   420
        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
   421
    else if (!isfail(ctx))
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
        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
   424
        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
   425
        while (len >= 4)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   426
        {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   427
            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
   428
            len -= 4;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   429
            buf += 4;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   430
        } // while
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   431
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   432
        if (len > 0)  // handle spillover...
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   433
        {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   434
            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
   435
            overflow.ui32 = 0;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   436
            memcpy(overflow.ui8, buf, len);
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   437
            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
   438
        } // if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   439
    } // else if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   440
} // output_comment_bytes
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   441
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   442
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   443
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
   444
{
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   445
    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
   446
} // output_comment_string
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   447
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   448
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   449
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
   450
{
562
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   451
    const Token token = nexttoken(ctx);
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   452
    if (token != ((Token) ','))
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   453
    {
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   454
        fail(ctx, "Comma expected");
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   455
        return 0;
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   456
    } // if
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   457
    return 1;
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   458
} // require_comma
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
562
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   461
static int check_token_segment(Context *ctx, const char *str)
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   462
{
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   463
    // !!! FIXME: these are case-insensitive, right?
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   464
    const size_t len = strlen(str);
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   465
    if ( (ctx->tokenlen < len) || (strncasecmp(ctx->token, str, len) != 0) )
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   466
        return 0;
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   467
    ctx->token += len;
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   468
    ctx->tokenlen -= len;
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   469
    return 1;
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   470
} // check_token_segment
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   471
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   472
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   473
static int check_token(Context *ctx, const char *str)
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   474
{
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   475
    const size_t len = strlen(str);
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   476
    if ( (ctx->tokenlen != len) || (strncasecmp(ctx->token, str, len) != 0) )
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   477
        return 0;
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   478
    ctx->token += len;
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   479
    ctx->tokenlen = 0;
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   480
    return 1;
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   481
} // check_token
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   482
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   483
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   484
static int ui32fromtoken(Context *ctx, uint32 *_val)
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   485
{
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   486
    int i;
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   487
    for (i = 0; i < ctx->tokenlen; i++)
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   488
    {
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   489
        if ((ctx->token[i] < '0') || (ctx->token[i] > '9'))
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   490
            break;
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   491
    } // for
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   492
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   493
    if (i == 0)
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   494
    {
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   495
        *_val = 0;
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   496
        return 0;
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   497
    } // if
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   498
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   499
    const int len = i;
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   500
    uint32 val = 0;
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   501
    uint32 mult = 1;
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   502
    while (i--)
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   503
    {
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   504
        val += ((uint32) (ctx->token[i] - '0')) * mult;
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   505
        mult *= 10;
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   506
    } // while
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   507
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   508
    ctx->token += len;
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   509
    ctx->tokenlen -= len;
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   510
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   511
    *_val = val;
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   512
    return 1;
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   513
} // ui32fromtoken
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   514
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   515
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   516
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
   517
{
562
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   518
    if (nexttoken(ctx) != TOKEN_IDENTIFIER)
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   519
    {
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   520
        fail(ctx, "Expected register");
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   521
        return 0;
562
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   522
    } // if
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   523
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   524
    int neednum = 1;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   525
    int regnum = 0;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   526
    RegisterType regtype = REG_TYPE_TEMP;
562
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   527
573
1cd1d99a79cb Rearrange how we test for register names to avoid substring matches.
Ryan C. Gordon <icculus@icculus.org>
parents: 572
diff changeset
   528
    // Watch out for substrings! oDepth must be checked before oD, since
1cd1d99a79cb Rearrange how we test for register names to avoid substring matches.
Ryan C. Gordon <icculus@icculus.org>
parents: 572
diff changeset
   529
    //  the latter will match either case.
1cd1d99a79cb Rearrange how we test for register names to avoid substring matches.
Ryan C. Gordon <icculus@icculus.org>
parents: 572
diff changeset
   530
    if (check_token_segment(ctx, "oDepth"))
513
abd9c85ba168 oDepth register doesn't have an index.
Ryan C. Gordon <icculus@icculus.org>
parents: 512
diff changeset
   531
    {
abd9c85ba168 oDepth register doesn't have an index.
Ryan C. Gordon <icculus@icculus.org>
parents: 512
diff changeset
   532
        regtype = REG_TYPE_DEPTHOUT;
abd9c85ba168 oDepth register doesn't have an index.
Ryan C. Gordon <icculus@icculus.org>
parents: 512
diff changeset
   533
        neednum = 0;
abd9c85ba168 oDepth register doesn't have an index.
Ryan C. Gordon <icculus@icculus.org>
parents: 512
diff changeset
   534
    } // else if
573
1cd1d99a79cb Rearrange how we test for register names to avoid substring matches.
Ryan C. Gordon <icculus@icculus.org>
parents: 572
diff changeset
   535
    else if (check_token_segment(ctx, "vFace"))
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   536
    {
573
1cd1d99a79cb Rearrange how we test for register names to avoid substring matches.
Ryan C. Gordon <icculus@icculus.org>
parents: 572
diff changeset
   537
        regtype = REG_TYPE_MISCTYPE;
1cd1d99a79cb Rearrange how we test for register names to avoid substring matches.
Ryan C. Gordon <icculus@icculus.org>
parents: 572
diff changeset
   538
        regnum = (int) MISCTYPE_TYPE_FACE;
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   539
        neednum = 0;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   540
    } // else if
562
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   541
    else if (check_token_segment(ctx, "vPos"))
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   542
    {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   543
        regtype = REG_TYPE_MISCTYPE;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   544
        regnum = (int) MISCTYPE_TYPE_POSITION;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   545
        neednum = 0;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   546
    } // else if
562
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   547
    else if (check_token_segment(ctx, "oPos"))
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   548
    {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   549
        regtype = REG_TYPE_RASTOUT;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   550
        regnum = (int) RASTOUT_TYPE_POSITION;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   551
        neednum = 0;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   552
    } // else if
562
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   553
    else if (check_token_segment(ctx, "oFog"))
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   554
    {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   555
        regtype = REG_TYPE_RASTOUT;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   556
        regnum = (int) RASTOUT_TYPE_FOG;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   557
        neednum = 0;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   558
    } // else if
562
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   559
    else if (check_token_segment(ctx, "oPts"))
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   560
    {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   561
        regtype = REG_TYPE_RASTOUT;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   562
        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
   563
        neednum = 0;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   564
    } // else if
573
1cd1d99a79cb Rearrange how we test for register names to avoid substring matches.
Ryan C. Gordon <icculus@icculus.org>
parents: 572
diff changeset
   565
    else if (check_token_segment(ctx, "aL"))
1cd1d99a79cb Rearrange how we test for register names to avoid substring matches.
Ryan C. Gordon <icculus@icculus.org>
parents: 572
diff changeset
   566
    {
1cd1d99a79cb Rearrange how we test for register names to avoid substring matches.
Ryan C. Gordon <icculus@icculus.org>
parents: 572
diff changeset
   567
        regtype = REG_TYPE_LOOP;
1cd1d99a79cb Rearrange how we test for register names to avoid substring matches.
Ryan C. Gordon <icculus@icculus.org>
parents: 572
diff changeset
   568
        neednum = 0;
1cd1d99a79cb Rearrange how we test for register names to avoid substring matches.
Ryan C. Gordon <icculus@icculus.org>
parents: 572
diff changeset
   569
    } // else if
1cd1d99a79cb Rearrange how we test for register names to avoid substring matches.
Ryan C. Gordon <icculus@icculus.org>
parents: 572
diff changeset
   570
    else if (check_token_segment(ctx, "oC"))
1cd1d99a79cb Rearrange how we test for register names to avoid substring matches.
Ryan C. Gordon <icculus@icculus.org>
parents: 572
diff changeset
   571
        regtype = REG_TYPE_COLOROUT;
1cd1d99a79cb Rearrange how we test for register names to avoid substring matches.
Ryan C. Gordon <icculus@icculus.org>
parents: 572
diff changeset
   572
    else if (check_token_segment(ctx, "oT"))
1cd1d99a79cb Rearrange how we test for register names to avoid substring matches.
Ryan C. Gordon <icculus@icculus.org>
parents: 572
diff changeset
   573
        regtype = REG_TYPE_OUTPUT;
1cd1d99a79cb Rearrange how we test for register names to avoid substring matches.
Ryan C. Gordon <icculus@icculus.org>
parents: 572
diff changeset
   574
    else if (check_token_segment(ctx, "oD"))
1cd1d99a79cb Rearrange how we test for register names to avoid substring matches.
Ryan C. Gordon <icculus@icculus.org>
parents: 572
diff changeset
   575
        regtype = REG_TYPE_ATTROUT;
1cd1d99a79cb Rearrange how we test for register names to avoid substring matches.
Ryan C. Gordon <icculus@icculus.org>
parents: 572
diff changeset
   576
    else if (check_token_segment(ctx, "r"))
1cd1d99a79cb Rearrange how we test for register names to avoid substring matches.
Ryan C. Gordon <icculus@icculus.org>
parents: 572
diff changeset
   577
        regtype = REG_TYPE_TEMP;
1cd1d99a79cb Rearrange how we test for register names to avoid substring matches.
Ryan C. Gordon <icculus@icculus.org>
parents: 572
diff changeset
   578
    else if (check_token_segment(ctx, "v"))
1cd1d99a79cb Rearrange how we test for register names to avoid substring matches.
Ryan C. Gordon <icculus@icculus.org>
parents: 572
diff changeset
   579
        regtype = REG_TYPE_INPUT;
1cd1d99a79cb Rearrange how we test for register names to avoid substring matches.
Ryan C. Gordon <icculus@icculus.org>
parents: 572
diff changeset
   580
    else if (check_token_segment(ctx, "c"))
1cd1d99a79cb Rearrange how we test for register names to avoid substring matches.
Ryan C. Gordon <icculus@icculus.org>
parents: 572
diff changeset
   581
        regtype = REG_TYPE_CONST;
1cd1d99a79cb Rearrange how we test for register names to avoid substring matches.
Ryan C. Gordon <icculus@icculus.org>
parents: 572
diff changeset
   582
    else if (check_token_segment(ctx, "i"))
1cd1d99a79cb Rearrange how we test for register names to avoid substring matches.
Ryan C. Gordon <icculus@icculus.org>
parents: 572
diff changeset
   583
        regtype = REG_TYPE_CONSTINT;
1cd1d99a79cb Rearrange how we test for register names to avoid substring matches.
Ryan C. Gordon <icculus@icculus.org>
parents: 572
diff changeset
   584
    else if (check_token_segment(ctx, "b"))
1cd1d99a79cb Rearrange how we test for register names to avoid substring matches.
Ryan C. Gordon <icculus@icculus.org>
parents: 572
diff changeset
   585
        regtype = REG_TYPE_CONSTBOOL;
1cd1d99a79cb Rearrange how we test for register names to avoid substring matches.
Ryan C. Gordon <icculus@icculus.org>
parents: 572
diff changeset
   586
    else if (check_token_segment(ctx, "s"))
1cd1d99a79cb Rearrange how we test for register names to avoid substring matches.
Ryan C. Gordon <icculus@icculus.org>
parents: 572
diff changeset
   587
        regtype = REG_TYPE_SAMPLER;
1cd1d99a79cb Rearrange how we test for register names to avoid substring matches.
Ryan C. Gordon <icculus@icculus.org>
parents: 572
diff changeset
   588
    else if (check_token_segment(ctx, "l"))
1cd1d99a79cb Rearrange how we test for register names to avoid substring matches.
Ryan C. Gordon <icculus@icculus.org>
parents: 572
diff changeset
   589
        regtype = REG_TYPE_LABEL;
1cd1d99a79cb Rearrange how we test for register names to avoid substring matches.
Ryan C. Gordon <icculus@icculus.org>
parents: 572
diff changeset
   590
    else if (check_token_segment(ctx, "p"))
1cd1d99a79cb Rearrange how we test for register names to avoid substring matches.
Ryan C. Gordon <icculus@icculus.org>
parents: 572
diff changeset
   591
        regtype = REG_TYPE_PREDICATE;
1cd1d99a79cb Rearrange how we test for register names to avoid substring matches.
Ryan C. Gordon <icculus@icculus.org>
parents: 572
diff changeset
   592
    else if (check_token_segment(ctx, "o"))
1cd1d99a79cb Rearrange how we test for register names to avoid substring matches.
Ryan C. Gordon <icculus@icculus.org>
parents: 572
diff changeset
   593
        regtype = REG_TYPE_OUTPUT;
1cd1d99a79cb Rearrange how we test for register names to avoid substring matches.
Ryan C. Gordon <icculus@icculus.org>
parents: 572
diff changeset
   594
    else if (check_token_segment(ctx, "a"))
1cd1d99a79cb Rearrange how we test for register names to avoid substring matches.
Ryan C. Gordon <icculus@icculus.org>
parents: 572
diff changeset
   595
        regtype = REG_TYPE_ADDRESS;
1cd1d99a79cb Rearrange how we test for register names to avoid substring matches.
Ryan C. Gordon <icculus@icculus.org>
parents: 572
diff changeset
   596
    else if (check_token_segment(ctx, "t"))
1cd1d99a79cb Rearrange how we test for register names to avoid substring matches.
Ryan C. Gordon <icculus@icculus.org>
parents: 572
diff changeset
   597
        regtype = REG_TYPE_ADDRESS;
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
    //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
   600
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   601
    else
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   602
    {
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   603
        fail(ctx, "expected register type");
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   604
        regtype = REG_TYPE_CONST;
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   605
        regnum = 0;
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   606
        neednum = 0;
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   607
    } // else
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   608
570
af6bb8728f9e Fixed register name parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 567
diff changeset
   609
    // "c[5]" is the same as "c5", so if the token is done, see if next is '['.
af6bb8728f9e Fixed register name parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 567
diff changeset
   610
    if ((neednum) && (ctx->tokenlen == 0))
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   611
    {
562
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   612
        if (nexttoken(ctx) == ((Token) '['))
570
af6bb8728f9e Fixed register name parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 567
diff changeset
   613
            neednum = 0;  // don't need a number on register name itself.
562
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   614
        pushback(ctx);
482
3f740f25bd7e Fixed relative addressing parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 481
diff changeset
   615
    } // if
3f740f25bd7e Fixed relative addressing parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 481
diff changeset
   616
3f740f25bd7e Fixed relative addressing parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 481
diff changeset
   617
    if (neednum)
3f740f25bd7e Fixed relative addressing parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 481
diff changeset
   618
    {
3f740f25bd7e Fixed relative addressing parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 481
diff changeset
   619
        uint32 ui32 = 0;
562
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   620
        if (!ui32fromtoken(ctx, &ui32))
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   621
            fail(ctx, "Invalid register index");
482
3f740f25bd7e Fixed relative addressing parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 481
diff changeset
   622
        regnum = (int) ui32;
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   623
    } // if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   624
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   625
    // split up REG_TYPE_CONST
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   626
    if (regtype == REG_TYPE_CONST)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   627
    {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   628
        if (regnum < 2048)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   629
        {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   630
            regtype = REG_TYPE_CONST;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   631
            regnum -= 0;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   632
        } // if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   633
        else if (regnum < 4096)
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_CONST2;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   636
            regnum -= 2048;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   637
        } // if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   638
        else if (regnum < 6144)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   639
        {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   640
            regtype = REG_TYPE_CONST3;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   641
            regnum -= 4096;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   642
        } // if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   643
        else if (regnum < 8192)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   644
        {
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   645
            regtype = REG_TYPE_CONST4;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   646
            regnum -= 6144;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   647
        } // if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   648
        else
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   649
        {
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   650
            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
   651
        } // else
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   652
    } // if
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
    *rtype = regtype;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   655
    *rnum = regnum;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   656
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   657
    return 1;
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   658
} // parse_register_name
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   659
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   660
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   661
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
   662
{
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   663
    if (info->result_shift != 0)
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   664
        fail(ctx, "Multiple result shift modifiers");
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   665
    info->result_shift = val;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   666
} // set_result_shift
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   667
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   668
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   669
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
   670
{
515
58c1a7d98176 First steps of reworking tokenizer.
Ryan C. Gordon <icculus@icculus.org>
parents: 514
diff changeset
   671
    DestArgInfo *info = &ctx->dest_arg;
510
f4433db86f6e Fixed wrong sizeof for a memset() call.
Ryan C. Gordon <icculus@icculus.org>
parents: 508
diff changeset
   672
    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
   673
562
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   674
    // parse_instruction_token() sets ctx->token to the end of the instruction
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   675
    //  so we can see if there are destination modifiers on the instruction
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   676
    //  itself...
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   677
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   678
    int invalid_modifier = 0;
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   679
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   680
    while ((ctx->tokenlen > 0) && (!invalid_modifier))
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   681
    {
562
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   682
        if (check_token_segment(ctx, "_x2"))
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   683
            set_result_shift(ctx, info, 0x1);
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   684
        else if (check_token_segment(ctx, "_x4"))
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   685
            set_result_shift(ctx, info, 0x2);
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   686
        else if (check_token_segment(ctx, "_x8"))
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   687
            set_result_shift(ctx, info, 0x3);
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   688
        else if (check_token_segment(ctx, "_d8"))
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   689
            set_result_shift(ctx, info, 0xD);
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   690
        else if (check_token_segment(ctx, "_d4"))
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   691
            set_result_shift(ctx, info, 0xE);
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   692
        else if (check_token_segment(ctx, "_d2"))
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   693
            set_result_shift(ctx, info, 0xF);
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   694
        else if (check_token_segment(ctx, "_sat"))
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   695
            info->result_mod |= MOD_SATURATE;
562
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   696
        else if (check_token_segment(ctx, "_pp"))
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   697
            info->result_mod |= MOD_PP;
562
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   698
        else if (check_token_segment(ctx, "_centroid"))
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   699
            info->result_mod |= MOD_CENTROID;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   700
        else
562
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   701
            invalid_modifier = 1;
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   702
    } // while
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   703
562
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   704
    if (invalid_modifier)
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   705
        fail(ctx, "Invalid destination modifier");
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   706
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   707
    // !!! FIXME: predicates.
562
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   708
    if (nexttoken(ctx) == ((Token) '('))
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   709
        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
   710
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   711
    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
   712
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   713
    parse_register_name(ctx, &info->regtype, &info->regnum);
562
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   714
    // parse_register_name() can't check this: dest regs might have modifiers.
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   715
    if (ctx->tokenlen > 0)
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   716
        fail(ctx, "invalid register name");
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   717
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   718
    // !!! 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
   719
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   720
    int invalid_writemask = 0;
521
57e1945104cb Workaround for incorrect assembly code generated by Cg.
Ryan C. Gordon <icculus@icculus.org>
parents: 519
diff changeset
   721
    int implicit_writemask = 0;
562
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   722
    if (nexttoken(ctx) != ((Token) '.'))
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   723
    {
521
57e1945104cb Workaround for incorrect assembly code generated by Cg.
Ryan C. Gordon <icculus@icculus.org>
parents: 519
diff changeset
   724
        implicit_writemask = 1;
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   725
        info->writemask = 0xF;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   726
        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
   727
        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
   728
    } // if
562
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   729
521
57e1945104cb Workaround for incorrect assembly code generated by Cg.
Ryan C. Gordon <icculus@icculus.org>
parents: 519
diff changeset
   730
    // !!! 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
   731
    //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
   732
    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
   733
        fail(ctx, "Writemask specified for scalar register");
562
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   734
    else if (nexttoken(ctx) != TOKEN_IDENTIFIER)
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   735
        invalid_writemask = 1;
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   736
    else
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   737
    {
562
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   738
        // !!! FIXME: is out-of-order okay (yxzw instead of xyzw?)
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   739
        char tokenbytes[5] = { '\0', '\0', '\0', '\0', '\0' };
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   740
        const unsigned int tokenlen = ctx->tokenlen;
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   741
        memcpy(tokenbytes, ctx->token, ((tokenlen < 4) ? tokenlen : 4));
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   742
        char *ptr = tokenbytes;
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   743
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   744
        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
   745
        if (*ptr == 'x') { info->writemask0 = 1; ptr++; }
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   746
        if (*ptr == 'y') { info->writemask1 = 1; ptr++; }
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   747
        if (*ptr == 'z') { info->writemask2 = 1; ptr++; }
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   748
        if (*ptr == 'w') { info->writemask3 = 1; ptr++; }
562
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   749
        if ((ptr == ctx->token) && (shader_is_pixel(ctx)))
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   750
        {
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   751
            if (*ptr == 'r') { info->writemask0 = 1; ptr++; }
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   752
            if (*ptr == 'g') { info->writemask1 = 1; ptr++; }
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   753
            if (*ptr == 'b') { info->writemask2 = 1; ptr++; }
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   754
            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
   755
        } // if
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   756
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   757
        if (*ptr != '\0')
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   758
            invalid_writemask = 1;
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   759
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   760
        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
   761
                            ((info->writemask1 & 0x1) << 1) |
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   762
                            ((info->writemask2 & 0x1) << 2) |
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   763
                            ((info->writemask3 & 0x1) << 3) );
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   764
    } // else
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   765
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   766
    if (invalid_writemask)
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   767
        fail(ctx, "Invalid writemask");
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   768
521
57e1945104cb Workaround for incorrect assembly code generated by Cg.
Ryan C. Gordon <icculus@icculus.org>
parents: 519
diff changeset
   769
    // !!! 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
   770
    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
   771
    {
57e1945104cb Workaround for incorrect assembly code generated by Cg.
Ryan C. Gordon <icculus@icculus.org>
parents: 519
diff changeset
   772
        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
   773
               info->writemask2 + info->writemask3) > 1) )
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   774
            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
   775
    } // if
57e1945104cb Workaround for incorrect assembly code generated by Cg.
Ryan C. Gordon <icculus@icculus.org>
parents: 519
diff changeset
   776
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   777
    info->orig_writemask = info->writemask;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   778
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   779
    if (ctx->tokenbufpos >= STATICARRAYLEN(ctx->tokenbuf))
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   780
    {
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   781
        fail(ctx, "Too many tokens");
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   782
        return 1;
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   783
    } // if
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   784
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   785
    ctx->tokenbuf[ctx->tokenbufpos++] =
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   786
            ( ((((uint32) 1)) << 31) |
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   787
              ((((uint32) info->regnum) & 0x7ff) << 0) |
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   788
              ((((uint32) info->relative) & 0x1) << 13) |
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   789
              ((((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
   790
              ((((uint32) info->result_shift) & 0xF) << 24) |
500
38ce929323c2 Fixed writemask bits in assembled bytecode.
Ryan C. Gordon <icculus@icculus.org>
parents: 499
diff changeset
   791
              ((((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
   792
              ((((uint32) info->regtype) & 0x7) << 28) |
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   793
              ((((uint32) info->regtype) & 0x18) << 8) );
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   794
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   795
    return 1;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   796
} // parse_destination_token
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   797
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   798
472
e52d487e6d91 Bunch More Work on the assembler. Feature complete now?
Ryan C. Gordon <icculus@icculus.org>
parents: 470
diff changeset
   799
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
   800
                           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
   801
                           SourceMod *srcmod)
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   802
{
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   803
    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
   804
        fail(ctx, "Incompatible source modifiers");
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   805
    else
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   806
        *srcmod = ((negate) ? negated : norm);
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   807
} // set_source_mod
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   808
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   809
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   810
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
   811
{
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   812
    int retval = 1;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   813
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   814
    if (ctx->tokenbufpos >= STATICARRAYLEN(ctx->tokenbuf))
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   815
    {
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   816
        fail(ctx, "Too many tokens");
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   817
        return 0;
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   818
    } // if
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   819
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   820
    // mark this now, so optional relative addressing token is placed second.
562
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   821
    uint32 *outtoken = &ctx->tokenbuf[ctx->tokenbufpos++];
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   822
    *outtoken = 0;
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   823
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   824
    SourceMod srcmod = SRCMOD_NONE;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   825
    int negate = 0;
562
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   826
    Token token = nexttoken(ctx);
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   827
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   828
    if (token == ((Token) '!'))
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   829
        srcmod = SRCMOD_NOT;
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   830
    else if (token == ((Token) '-'))
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   831
        negate = 1;
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   832
    else if ( (token == TOKEN_INT_LITERAL) && (check_token(ctx, "1")) )
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   833
    {
562
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   834
        if (nexttoken(ctx) != ((Token) '-'))
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   835
            fail(ctx, "Unexpected token");
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   836
        else
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   837
            srcmod = SRCMOD_COMPLEMENT;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   838
    } // else
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   839
    else
562
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   840
    {
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   841
        pushback(ctx);
562
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   842
    } // else
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   843
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   844
    RegisterType regtype;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   845
    int regnum;
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   846
    parse_register_name(ctx, &regtype, &regnum);
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   847
562
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   848
    if (ctx->tokenlen > 0)
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   849
    {
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   850
        if (check_token_segment(ctx, "_bias"))
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   851
            set_source_mod(ctx, negate, SRCMOD_BIAS, SRCMOD_BIASNEGATE, &srcmod);
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   852
        else if (check_token_segment(ctx, "_bx2"))
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   853
            set_source_mod(ctx, negate, SRCMOD_SIGN, SRCMOD_SIGNNEGATE, &srcmod);
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   854
        else if (check_token_segment(ctx, "_x2"))
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   855
            set_source_mod(ctx, negate, SRCMOD_X2, SRCMOD_X2NEGATE, &srcmod);
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   856
        else if (check_token_segment(ctx, "_dz"))
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   857
            set_source_mod(ctx, negate, SRCMOD_DZ, SRCMOD_NONE, &srcmod);
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   858
        else if (check_token_segment(ctx, "_dw"))
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   859
            set_source_mod(ctx, negate, SRCMOD_DW, SRCMOD_NONE, &srcmod);
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   860
        else if (check_token_segment(ctx, "_abs"))
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   861
            set_source_mod(ctx, negate, SRCMOD_ABS, SRCMOD_ABSNEGATE, &srcmod);
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   862
        else
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   863
            fail(ctx, "Invalid source modifier");
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   864
    } // if
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   865
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   866
    uint32 relative = 0;
562
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   867
    if (nexttoken(ctx) != ((Token) '['))
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   868
        pushback(ctx);  // not relative addressing?
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   869
    else
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   870
    {
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   871
        if (!relok)
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   872
            fail(ctx, "Relative addressing not permitted here.");
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   873
        else
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   874
            retval++;
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   875
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   876
        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
   877
        relative = 1;
562
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   878
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   879
        if (nexttoken(ctx) != ((Token) '+'))
482
3f740f25bd7e Fixed relative addressing parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 481
diff changeset
   880
            pushback(ctx);
3f740f25bd7e Fixed relative addressing parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 481
diff changeset
   881
        else
3f740f25bd7e Fixed relative addressing parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 481
diff changeset
   882
        {
562
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   883
            // !!! FIXME: maybe c3[a0.x + 5] is legal and becomes c[a0.x + 8] ?
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   884
            if (regnum != 0)
482
3f740f25bd7e Fixed relative addressing parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 481
diff changeset
   885
                fail(ctx, "Relative addressing with explicit register number.");
562
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   886
482
3f740f25bd7e Fixed relative addressing parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 481
diff changeset
   887
            uint32 ui32 = 0;
562
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   888
            if ( (nexttoken(ctx) != TOKEN_INT_LITERAL) ||
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   889
                 (!ui32fromtoken(ctx, &ui32)) ||
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   890
                 (ctx->tokenlen != 0) )
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   891
            {
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   892
                fail(ctx, "Invalid relative addressing offset");
562
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   893
            } // if
482
3f740f25bd7e Fixed relative addressing parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 481
diff changeset
   894
            regnum += (int) ui32;
3f740f25bd7e Fixed relative addressing parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 481
diff changeset
   895
        } // else
3f740f25bd7e Fixed relative addressing parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 481
diff changeset
   896
562
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   897
        if (nexttoken(ctx) != ((Token) ']'))
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   898
            fail(ctx, "Expected ']'");
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   899
    } // else
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   900
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   901
    int invalid_swizzle = 0;
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   902
    uint32 swizzle = 0;
562
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   903
    if (nexttoken(ctx) != ((Token) '.'))
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   904
    {
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   905
        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
   906
        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
   907
    } // if
491
bcc3c215807a Fixed wrong data from scalar_register().
Ryan C. Gordon <icculus@icculus.org>
parents: 490
diff changeset
   908
    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
   909
        fail(ctx, "Swizzle specified for scalar register");
562
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   910
    else if (nexttoken(ctx) != TOKEN_IDENTIFIER)
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   911
        invalid_swizzle = 1;
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   912
    else
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   913
    {
562
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   914
        char tokenbytes[5] = { '\0', '\0', '\0', '\0', '\0' };
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   915
        const unsigned int tokenlen = ctx->tokenlen;
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   916
        memcpy(tokenbytes, ctx->token, ((tokenlen < 4) ? tokenlen : 4));
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   917
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   918
        // deal with shortened form (.x = .xxxx, etc).
562
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   919
        if (tokenlen == 1)
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   920
            tokenbytes[1] = tokenbytes[2] = tokenbytes[3] = tokenbytes[0];
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   921
        else if (tokenlen == 2)
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   922
            tokenbytes[2] = tokenbytes[3] = tokenbytes[1];
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   923
        else if (tokenlen == 3)
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   924
            tokenbytes[3] = tokenbytes[2];
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   925
        else if (tokenlen != 4)
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   926
            invalid_swizzle = 1;
562
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   927
        tokenbytes[4] = '\0';
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   928
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   929
        uint32 val = 0;
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   930
        int saw_xyzw = 0;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   931
        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
   932
        int i;
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   933
        for (i = 0; i < 4; i++)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   934
        {
562
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   935
            const int component = (int) tokenbytes[i];
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   936
            switch (component)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   937
            {
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   938
                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
   939
                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
   940
                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
   941
                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
   942
                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
   943
                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
   944
                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
   945
                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
   946
                default: invalid_swizzle = 1; break;
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   947
            } // switch
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   948
            swizzle |= (val << (i * 2));
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   949
        } // for
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   950
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   951
        if (saw_xyzw && saw_rgba)
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   952
            invalid_swizzle = 1;
548
b37cdacb50d5 Fixed parsing details of swizzles.
Ryan C. Gordon <icculus@icculus.org>
parents: 544
diff changeset
   953
        else if (saw_rgba && !shader_is_pixel(ctx))
b37cdacb50d5 Fixed parsing details of swizzles.
Ryan C. Gordon <icculus@icculus.org>
parents: 544
diff changeset
   954
            invalid_swizzle = 1;
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   955
    } // else
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   956
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   957
    if (invalid_swizzle)
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   958
        fail(ctx, "Invalid swizzle");
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   959
562
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   960
    *outtoken = ( ((((uint32) 1)) << 31) |
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   961
                  ((((uint32) regnum) & 0x7ff) << 0) |
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   962
                  ((((uint32) relative) & 0x1) << 13) |
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   963
                  ((((uint32) swizzle) & 0xFF) << 16) |
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   964
                  ((((uint32) srcmod) & 0xF) << 24) |
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   965
                  ((((uint32) regtype) & 0x7) << 28) |
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   966
                  ((((uint32) regtype) & 0x18) << 8) );
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   967
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   968
    return retval;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   969
} // parse_source_token_maybe_relative
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   970
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   971
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   972
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
   973
{
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   974
    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
   975
} // parse_source_token
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   976
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   977
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   978
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
   979
{
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
   980
    return 1;
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   981
} // parse_args_NULL
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   982
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   983
562
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   984
static int parse_num(Context *ctx, const int floatok, uint32 *value)
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   985
{
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   986
    union { float f; int32 si32; uint32 ui32; } cvt;
572
cdc8bb82f7d2 Fixed parse_num().
Ryan C. Gordon <icculus@icculus.org>
parents: 571
diff changeset
   987
    int negative = 0;
cdc8bb82f7d2 Fixed parse_num().
Ryan C. Gordon <icculus@icculus.org>
parents: 571
diff changeset
   988
    Token token = nexttoken(ctx);
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
   989
572
cdc8bb82f7d2 Fixed parse_num().
Ryan C. Gordon <icculus@icculus.org>
parents: 571
diff changeset
   990
    if (token == ((Token) '-'))
cdc8bb82f7d2 Fixed parse_num().
Ryan C. Gordon <icculus@icculus.org>
parents: 571
diff changeset
   991
    {
cdc8bb82f7d2 Fixed parse_num().
Ryan C. Gordon <icculus@icculus.org>
parents: 571
diff changeset
   992
        negative = 1;
cdc8bb82f7d2 Fixed parse_num().
Ryan C. Gordon <icculus@icculus.org>
parents: 571
diff changeset
   993
        token = nexttoken(ctx);
cdc8bb82f7d2 Fixed parse_num().
Ryan C. Gordon <icculus@icculus.org>
parents: 571
diff changeset
   994
    } // if
cdc8bb82f7d2 Fixed parse_num().
Ryan C. Gordon <icculus@icculus.org>
parents: 571
diff changeset
   995
562
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   996
    if (token == TOKEN_INT_LITERAL)
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   997
    {
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   998
        int d = 0;
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
   999
        sscanf(ctx->token, "%d", &d);
572
cdc8bb82f7d2 Fixed parse_num().
Ryan C. Gordon <icculus@icculus.org>
parents: 571
diff changeset
  1000
        if (floatok)
cdc8bb82f7d2 Fixed parse_num().
Ryan C. Gordon <icculus@icculus.org>
parents: 571
diff changeset
  1001
            cvt.f = (float) ((negative) ? -d : d);
cdc8bb82f7d2 Fixed parse_num().
Ryan C. Gordon <icculus@icculus.org>
parents: 571
diff changeset
  1002
        else
cdc8bb82f7d2 Fixed parse_num().
Ryan C. Gordon <icculus@icculus.org>
parents: 571
diff changeset
  1003
            cvt.si32 = (int32) ((negative) ? -d : d);
562
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
  1004
    } // if
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
  1005
    else if (token == TOKEN_FLOAT_LITERAL)
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
  1006
    {
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
  1007
        if (!floatok)
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
  1008
        {
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
  1009
            fail(ctx, "Expected whole number");
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
  1010
            *value = 0;
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
  1011
            return 0;
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
  1012
        } // if
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
  1013
        sscanf(ctx->token, "%f", &cvt.f);
572
cdc8bb82f7d2 Fixed parse_num().
Ryan C. Gordon <icculus@icculus.org>
parents: 571
diff changeset
  1014
        if (negative)
cdc8bb82f7d2 Fixed parse_num().
Ryan C. Gordon <icculus@icculus.org>
parents: 571
diff changeset
  1015
            cvt.f = -cvt.f;
562
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
  1016
    } // if
492
29bfa3448549 Handle exponents in number parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 491
diff changeset
  1017
    else
29bfa3448549 Handle exponents in number parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 491
diff changeset
  1018
    {
562
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
  1019
        fail(ctx, "Expected number");
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
  1020
        *value = 0;
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
  1021
        return 0;
492
29bfa3448549 Handle exponents in number parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 491
diff changeset
  1022
    } // else
29bfa3448549 Handle exponents in number parsing.
Ryan C. Gordon <icculus@icculus.org>
parents: 491
diff changeset
  1023
562
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
  1024
    *value = cvt.ui32;
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
  1025
    return 1;
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1026
} // parse_num
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1027
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1028
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1029
static int parse_args_DEFx(Context *ctx, const int isflt)
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1030
{
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
  1031
    parse_destination_token(ctx);
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
  1032
    require_comma(ctx);
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
  1033
    parse_num(ctx, isflt, &ctx->tokenbuf[ctx->tokenbufpos++]);
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
  1034
    require_comma(ctx);
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
  1035
    parse_num(ctx, isflt, &ctx->tokenbuf[ctx->tokenbufpos++]);
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
  1036
    require_comma(ctx);
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
  1037
    parse_num(ctx, isflt, &ctx->tokenbuf[ctx->tokenbufpos++]);
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
  1038
    require_comma(ctx);
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
  1039
    parse_num(ctx, isflt, &ctx->tokenbuf[ctx->tokenbufpos++]);
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1040
    return 6;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1041
} // parse_args_DEFx
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1042
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1043
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1044
static int parse_args_DEF(Context *ctx)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1045
{
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1046
    return parse_args_DEFx(ctx, 1);
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1047
} // parse_args_DEF
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1048
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1049
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1050
static int parse_args_DEFI(Context *ctx)
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 parse_args_DEFx(ctx, 0);
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1053
} // parse_args_DEFI
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1054
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1055
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1056
static int parse_args_DEFB(Context *ctx)
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1057
{
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
  1058
    parse_destination_token(ctx);
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
  1059
    require_comma(ctx);
562
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
  1060
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
  1061
    // !!! FIXME: do a TOKEN_TRUE and TOKEN_FALSE? Is this case-sensitive?
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
  1062
    const Token token = nexttoken(ctx);
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
  1063
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
  1064
    int bad = 0;
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
  1065
    if (token != TOKEN_IDENTIFIER)
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
  1066
        bad = 1;
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
  1067
    else if (check_token_segment(ctx, "true"))
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1068
        ctx->tokenbuf[ctx->tokenbufpos++] = 1;
562
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
  1069
    else if (check_token_segment(ctx, "false"))
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1070
        ctx->tokenbuf[ctx->tokenbufpos++] = 0;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1071
    else
562
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
  1072
        bad = 1;
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
  1073
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
  1074
    if (ctx->tokenlen != 0)
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
  1075
        bad = 1;
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
  1076
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
  1077
    if (bad)
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
  1078
        fail(ctx, "Expected 'true' or 'false'");
562
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
  1079
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1080
    return 3;
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1081
} // parse_args_DEFB
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1082
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1083
504
d79ae3b98f47 Fixed dcl_2d usage.
Ryan C. Gordon <icculus@icculus.org>
parents: 502
diff changeset
  1084
static int parse_dcl_usage(Context *ctx, uint32 *val, int *issampler)
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1085
{
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1086
    int i;
562
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
  1087
    static const char *samplerusagestrs[] = { "_2d", "_cube", "_volume" };
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1088
    static const char *usagestrs[] = {
562
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
  1089
        "_position", "_blendweight", "_blendindices", "_normal", "_psize",
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
  1090
        "_texcoord", "_tangent", "_binormal", "_tessfactor", "_positiont",
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
  1091
        "_color", "_fog", "_depth", "_sample"
465
0a75f98f785b Initial work on assembler. Not even close to done.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
  1092
    };
504
d79ae3b98f47 Fixed dcl_2d usage.
Ryan C. Gordon <icculus@icculus.org>
parents: 502
diff changeset
  1093
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1094
    for (i = 0; i < STATICARRAYLEN(usagestrs); i++)
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1095
    {
562
c9a2bc5129c9 First shot at reworking assembly parser to use preprocessor/lexer.
Ryan C. Gordon <icculus@icculus.org>
parents: 558
diff changeset
  1096
        if (check_token_segment(ctx, usagestrs[i]))
470
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1097
        {
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1098
            *issampler = 0;
7d84d3452125 Bunch More Work on the assembler.
Ryan C. Gordon <icculus@icculus.org>
parents: 465
diff changeset
  1099
            *val = i;
542
a56d3bfd2e36 More work on multiple error messages.
Ryan C. Gordon <icculus@icculus.org>
parents: 539
diff changeset
  1100
            return 1;
470