/*
 * Android "Almost" C Compiler.
 * This is a compiler for a small subset of the C language, intended for use
 * in scripting environments where speed and memory footprint are important.
 *
 * This code is based upon the "unobfuscated" version of the
 * Obfuscated Tiny C compiler, see the file LICENSE for details.
 *
 */

#define LOG_TAG "acc"
#include <cutils/log.h>

#include <ctype.h>
#include <errno.h>
#include <limits.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <cutils/hashmap.h>

#if defined(__i386__)
#include <sys/mman.h>
#endif


#if defined(__arm__)
#define DEFAULT_ARM_CODEGEN
#define PROVIDE_ARM_CODEGEN
#elif defined(__i386__)
#define DEFAULT_X86_CODEGEN
#define PROVIDE_X86_CODEGEN
#elif defined(__x86_64__)
#define DEFAULT_X64_CODEGEN
#define PROVIDE_X64_CODEGEN
#endif

#if (defined(__VFP_FP__) && !defined(__SOFTFP__))
#define ARM_USE_VFP
#endif

#include <acc/acc.h>

#define LOG_API(...) do {} while(0)
// #define LOG_API(...) fprintf (stderr, __VA_ARGS__)

#define LOG_STACK(...) do {} while(0)
// #define LOG_STACK(...) fprintf (stderr, __VA_ARGS__)

// #define PROVIDE_TRACE_CODEGEN

// Uncomment to disable ARM peephole optimizations
// #define DISABLE_ARM_PEEPHOLE

// Uncomment to save input to a text file in DEBUG_DUMP_PATTERN
// #define DEBUG_SAVE_INPUT_TO_FILE

#ifdef DEBUG_SAVE_INPUT_TO_FILE
#ifdef ARM_USE_VFP
#define DEBUG_DUMP_PATTERN "/data/misc/acc_dump/%d.c"
#else
#define DEBUG_DUMP_PATTERN "/tmp/acc_dump/%d.c"
#endif
#endif

#define assert(b) assertImpl(b, __LINE__)

namespace acc {

// Subset of STL vector.
template<class E> class Vector {
    public:
    Vector() {
        mpBase = 0;
        mUsed = 0;
        mSize = 0;
    }

    ~Vector() {
        if (mpBase) {
            for(size_t i = 0; i < mUsed; i++)  {
                mpBase[mUsed].~E();
            }
            free(mpBase);
        }
    }

    inline E& operator[](size_t i) {
        return mpBase[i];
    }

    inline E& front() {
        return mpBase[0];
    }

    inline E& back() {
        return mpBase[mUsed - 1];
    }

    void pop_back() {
        mUsed -= 1;
        mpBase[mUsed].~E();
    }

    void push_back(const E& item) {
        * ensure(1) = item;
    }

    size_t size() {
        return mUsed;
    }

private:
    E* ensure(int n) {
        size_t newUsed = mUsed + n;
        if (newUsed > mSize) {
            size_t newSize = mSize * 2 + 10;
            if (newSize < newUsed) {
                newSize = newUsed;
            }
            mpBase = (E*) realloc(mpBase, sizeof(E) * newSize);
            mSize = newSize;
        }
        E* result = mpBase + mUsed;
        mUsed = newUsed;
        return result;
    }

    E* mpBase;
    size_t mUsed;
    size_t mSize;
};

class ErrorSink {
public:
    void error(const char *fmt, ...) {
        va_list ap;
        va_start(ap, fmt);
        verror(fmt, ap);
        va_end(ap);
    }

    virtual ~ErrorSink() {}
    virtual void verror(const char* fmt, va_list ap) = 0;
};

class Compiler : public ErrorSink {
    typedef int tokenid_t;
    enum TypeTag {
        TY_INT,       // 0
        TY_CHAR,      // 1
        TY_SHORT,     // 2
        TY_VOID,      // 3
        TY_FLOAT,     // 4
        TY_DOUBLE,    // 5
        TY_POINTER,   // 6
        TY_ARRAY,     // 7
        TY_STRUCT,    // 8
        TY_FUNC,      // 9
        TY_PARAM      // 10
    };

    struct Type {
        TypeTag tag;
        tokenid_t id; // For function arguments, global vars, local vars, struct elements
        tokenid_t structTag; // For structs the name of the struct
        int length; // length of array, offset of struct element. -1 means struct is forward defined
        int alignment; // for structs only
        Type* pHead; // For a struct this is the prototype struct.
        Type* pTail;
    };

    enum ExpressionType {
        ET_RVALUE,
        ET_LVALUE
    };

    struct ExpressionValue {
        ExpressionValue() {
            et = ET_RVALUE;
            pType = NULL;
        }
        ExpressionType et;
        Type* pType;
    };

    class ICodeBuf {
    public:
        virtual ~ICodeBuf() {}
        virtual void init(int size) = 0;
        virtual void setErrorSink(ErrorSink* pErrorSink) = 0;
        virtual void o4(int n) = 0;
        virtual void ob(int n) = 0;
        virtual void* getBase() = 0;
        virtual intptr_t getSize() = 0;
        virtual intptr_t getPC() = 0;
        // Call this before trying to modify code in the buffer.
        virtual void flush() = 0;
    };

    class CodeBuf : public ICodeBuf {
        char* ind; // Output code pointer
        char* pProgramBase;
        ErrorSink* mErrorSink;
        int mSize;
        bool mOverflowed;

        void release() {
            if (pProgramBase != 0) {
                free(pProgramBase);
                pProgramBase = 0;
            }
        }

        bool check(int n) {
            int newSize = ind - pProgramBase + n;
            bool overflow = newSize > mSize;
            if (overflow && !mOverflowed) {
                mOverflowed = true;
                if (mErrorSink) {
                    mErrorSink->error("Code too large: %d bytes", newSize);
                }
            }
            return overflow;
        }

    public:
        CodeBuf() {
            pProgramBase = 0;
            ind = 0;
            mErrorSink = 0;
            mSize = 0;
            mOverflowed = false;
        }

        virtual ~CodeBuf() {
            release();
        }

        virtual void init(int size) {
            release();
            mSize = size;
            pProgramBase = (char*) calloc(1, size);
            ind = pProgramBase;
        }

        virtual void setErrorSink(ErrorSink* pErrorSink) {
            mErrorSink = pErrorSink;
        }

        virtual void o4(int n) {
            if(check(4)) {
                return;
            }
            * (int*) ind = n;
            ind += 4;
        }

        /*
         * Output a byte. Handles all values, 0..ff.
         */
        virtual void ob(int n) {
            if(check(1)) {
                return;
            }
            *ind++ = n;
        }

        virtual void* getBase() {
            return (void*) pProgramBase;
        }

        virtual intptr_t getSize() {
            return ind - pProgramBase;
        }

        virtual intptr_t getPC() {
            return (intptr_t) ind;
        }

        virtual void flush() {}
    };

    /**
     * A code generator creates an in-memory program, generating the code on
     * the fly. There is one code generator implementation for each supported
     * architecture.
     *
     * The code generator implements the following abstract machine:
     * R0 - the accumulator.
     * FP - a frame pointer for accessing function arguments and local
     *      variables.
     * SP - a stack pointer for storing intermediate results while evaluating
     *      expressions. The stack pointer grows downwards.
     *
     * The function calling convention is that all arguments are placed on the
     * stack such that the first argument has the lowest address.
     * After the call, the result is in R0. The caller is responsible for
     * removing the arguments from the stack.
     * The R0 register is not saved across function calls. The
     * FP and SP registers are saved.
     */

    class CodeGenerator {
    public:
        CodeGenerator() {
            mErrorSink = 0;
            pCodeBuf = 0;
            pushType();
        }
        virtual ~CodeGenerator() {}

        virtual void init(ICodeBuf* pCodeBuf) {
            this->pCodeBuf = pCodeBuf;
            pCodeBuf->setErrorSink(mErrorSink);
        }

        virtual void setErrorSink(ErrorSink* pErrorSink) {
            mErrorSink = pErrorSink;
            if (pCodeBuf) {
                pCodeBuf->setErrorSink(mErrorSink);
            }
        }

        /* Give the code generator some utility types so it can
         * use its own types as needed for the results of some
         * operations like gcmp.
         */

        void setTypes(Type* pInt) {
            mkpInt = pInt;
        }

        /* Emit a function prolog.
         * pDecl is the function declaration, which gives the arguments.
         * Save the old value of the FP.
         * Set the new value of the FP.
         * Convert from the native platform calling convention to
         * our stack-based calling convention. This may require
         * pushing arguments from registers to the stack.
         * Allocate "N" bytes of stack space. N isn't known yet, so
         * just emit the instructions for adjusting the stack, and return
         * the address to patch up. The patching will be done in
         * functionExit().
         * returns address to patch with local variable size.
        */
        virtual int functionEntry(Type* pDecl) = 0;

        /* Emit a function epilog.
         * Restore the old SP and FP register values.
         * Return to the calling function.
         * argCount - the number of arguments to the function.
         * localVariableAddress - returned from functionEntry()
         * localVariableSize - the size in bytes of the local variables.
         */
        virtual void functionExit(Type* pDecl, int localVariableAddress,
                                  int localVariableSize) = 0;

        /* load immediate value to R0 */
        virtual void li(int i) = 0;

        /* Load floating point value from global address. */
        virtual void loadFloat(int address, Type* pType) = 0;

        /* Add the struct offset in bytes to R0, change the type to pType */
        virtual void addStructOffsetR0(int offset, Type* pType) = 0;

        /* Jump to a target, and return the address of the word that
         * holds the target data, in case it needs to be fixed up later.
         */
        virtual int gjmp(int t) = 0;

        /* Test R0 and jump to a target if the test succeeds.
         * l = 0: je, l == 1: jne
         * Return the address of the word that holds the targed data, in
         * case it needs to be fixed up later.
         */
        virtual int gtst(bool l, int t) = 0;

        /* Compare TOS against R0, and store the boolean result in R0.
         * Pops TOS.
         * op specifies the comparison.
         */
        virtual void gcmp(int op) = 0;

        /* Perform the arithmetic op specified by op. TOS is the
         * left argument, R0 is the right argument.
         * Pops TOS.
         */
        virtual void genOp(int op) = 0;

        /* Compare 0 against R0, and store the boolean result in R0.
         * op specifies the comparison.
         */
        virtual void gUnaryCmp(int op) = 0;

        /* Perform the arithmetic op specified by op. 0 is the
         * left argument, R0 is the right argument.
         */
        virtual void genUnaryOp(int op) = 0;

        /* Push R0 onto the stack. (Also known as "dup" for duplicate.)
         */
        virtual void pushR0() = 0;

        /* Turn R0, TOS into R0 TOS R0 */

        virtual void over() = 0;

        /* Pop R0 from the stack. (Also known as "drop")
         */
        virtual void popR0() = 0;

        /* Store R0 to the address stored in TOS.
         * The TOS is popped.
         */
        virtual void storeR0ToTOS() = 0;

        /* Load R0 from the address stored in R0.
         */
        virtual void loadR0FromR0() = 0;

        /* Load the absolute address of a variable to R0.
         * If ea <= LOCAL, then this is a local variable, or an
         * argument, addressed relative to FP.
         * else it is an absolute global address.
         *
         * et is ET_RVALUE for things like string constants, ET_LVALUE for
         * variables.
         */
        virtual void leaR0(int ea, Type* pPointerType, ExpressionType et) = 0;

        /* Load the pc-relative address of a forward-referenced variable to R0.
         * Return the address of the 4-byte constant so that it can be filled
         * in later.
         */
        virtual int leaForward(int ea, Type* pPointerType) = 0;

        /**
         * Convert R0 to the given type.
         */

        void convertR0(Type* pType) {
            convertR0Imp(pType, false);
        }

        void castR0(Type* pType) {
            convertR0Imp(pType, true);
        }

        virtual void convertR0Imp(Type* pType, bool isCast) = 0;

        /* Emit code to adjust the stack for a function call. Return the
         * label for the address of the instruction that adjusts the
         * stack size. This will be passed as argument "a" to
         * endFunctionCallArguments.
         */
        virtual int beginFunctionCallArguments() = 0;

        /* Emit code to store R0 to the stack at byte offset l.
         * Returns stack size of object (typically 4 or 8 bytes)
         */
        virtual size_t storeR0ToArg(int l, Type* pArgType) = 0;

        /* Patch the function call preamble.
         * a is the address returned from beginFunctionCallArguments
         * l is the number of bytes the arguments took on the stack.
         * Typically you would also emit code to convert the argument
         * list into whatever the native function calling convention is.
         * On ARM for example you would pop the first 5 arguments into
         * R0..R4
         */
        virtual void endFunctionCallArguments(Type* pDecl, int a, int l) = 0;

        /* Emit a call to an unknown function. The argument "symbol" needs to
         * be stored in the location where the address should go. It forms
         * a chain. The address will be patched later.
         * Return the address of the word that has to be patched.
         */
        virtual int callForward(int symbol, Type* pFunc) = 0;

        /* Call a function pointer. L is the number of bytes the arguments
         * take on the stack. The address of the function is stored at
         * location SP + l.
         */
        virtual void callIndirect(int l, Type* pFunc) = 0;

        /* Adjust SP after returning from a function call. l is the
         * number of bytes of arguments stored on the stack. isIndirect
         * is true if this was an indirect call. (In which case the
         * address of the function is stored at location SP + l.)
         */
        virtual void adjustStackAfterCall(Type* pDecl, int l, bool isIndirect) = 0;

        /* Generate a symbol at the current PC. t is the head of a
         * linked list of addresses to patch.
         */
        virtual void gsym(int t) = 0;

        /* Resolve a forward reference function at the current PC.
         * t is the head of a
         * linked list of addresses to patch.
         * (Like gsym, but using absolute address, not PC relative address.)
         */
        virtual void resolveForward(int t) = 0;

        /*
         * Do any cleanup work required at the end of a compile.
         * For example, an instruction cache might need to be
         * invalidated.
         * Return non-zero if there is an error.
         */
        virtual int finishCompile() = 0;

        /**
         * Adjust relative branches by this amount.
         */
        virtual int jumpOffset() = 0;

        /**
         * Memory alignment (in bytes) for this type of data
         */
        virtual size_t alignmentOf(Type* type) = 0;

        /**
         * Array element alignment (in bytes) for this type of data.
         */
        virtual size_t sizeOf(Type* type) = 0;

        virtual Type* getR0Type() {
            return mExpressionStack.back().pType;
        }

        virtual ExpressionType getR0ExpressionType() {
            return mExpressionStack.back().et;
        }

        virtual void setR0ExpressionType(ExpressionType et) {
            mExpressionStack.back().et = et;
        }

        virtual size_t getExpressionStackDepth() {
            return mExpressionStack.size();
        }

        virtual void forceR0RVal() {
            if (getR0ExpressionType() == ET_LVALUE) {
                loadR0FromR0();
            }
        }

    protected:
        /*
         * Output a byte. Handles all values, 0..ff.
         */
        void ob(int n) {
            pCodeBuf->ob(n);
        }

        void o4(int data) {
            pCodeBuf->o4(data);
        }

        intptr_t getBase() {
            return (intptr_t) pCodeBuf->getBase();
        }

        intptr_t getPC() {
            return pCodeBuf->getPC();
        }

        intptr_t getSize() {
            return pCodeBuf->getSize();
        }

        void flush() {
            pCodeBuf->flush();
        }

        void error(const char* fmt,...) {
            va_list ap;
            va_start(ap, fmt);
            mErrorSink->verror(fmt, ap);
            va_end(ap);
        }

        void assertImpl(bool test, int line) {
            if (!test) {
                error("code generator assertion failed at line %s:%d.", __FILE__, line);
                LOGD("code generator assertion failed at line %s:%d.", __FILE__, line);
                * (char*) 0 = 0;
            }
        }

        void setR0Type(Type* pType) {
            assert(pType != NULL);
            mExpressionStack.back().pType = pType;
            mExpressionStack.back().et = ET_RVALUE;
        }

        void setR0Type(Type* pType, ExpressionType et) {
            assert(pType != NULL);
            mExpressionStack.back().pType = pType;
            mExpressionStack.back().et = et;
        }

        Type* getTOSType() {
            return mExpressionStack[mExpressionStack.size()-2].pType;
        }

        void pushType() {
            if (mExpressionStack.size()) {
                mExpressionStack.push_back(mExpressionStack.back());
            } else {
                mExpressionStack.push_back(ExpressionValue());
            }

        }

        void overType() {
            size_t size = mExpressionStack.size();
            if (size >= 2) {
                mExpressionStack.push_back(mExpressionStack.back());
                mExpressionStack[size-1] = mExpressionStack[size-2];
                mExpressionStack[size-2] = mExpressionStack[size];
            }
        }

        void popType() {
            mExpressionStack.pop_back();
        }

        bool bitsSame(Type* pA, Type* pB) {
            return collapseType(pA->tag) == collapseType(pB->tag);
        }

        TypeTag collapseType(TypeTag tag) {
            static const TypeTag collapsedTag[] = {
                    TY_INT,
                    TY_INT,
                    TY_INT,
                    TY_VOID,
                    TY_FLOAT,
                    TY_DOUBLE,
                    TY_INT,
                    TY_INT,
                    TY_VOID,
                    TY_VOID,
                    TY_VOID
                };
            return collapsedTag[tag];
        }

        TypeTag collapseTypeR0() {
            return collapseType(getR0Type()->tag);
        }

        static bool isFloatType(Type* pType) {
            return isFloatTag(pType->tag);
        }

        static bool isFloatTag(TypeTag tag) {
            return tag == TY_FLOAT || tag == TY_DOUBLE;
        }

        static bool isPointerType(Type* pType) {
            return isPointerTag(pType->tag);
        }

        static bool isPointerTag(TypeTag tag) {
            return tag == TY_POINTER || tag == TY_ARRAY;
        }

        Type* getPointerArithmeticResultType(Type* a, Type* b) {
            TypeTag aTag = a->tag;
            TypeTag bTag = b->tag;
            if (aTag == TY_POINTER) {
                return a;
            }
            if (bTag == TY_POINTER) {
                return b;
            }
            if (aTag == TY_ARRAY) {
                return a->pTail;
            }
            if (bTag == TY_ARRAY) {
                return b->pTail;
            }
            return NULL;
        }
        Type* mkpInt;

    private:
        Vector<ExpressionValue> mExpressionStack;
        ICodeBuf* pCodeBuf;
        ErrorSink* mErrorSink;
    };

#ifdef PROVIDE_ARM_CODEGEN

    static size_t rotateRight(size_t n, size_t rotate) {
        return (n >> rotate) | (n << (32 - rotate));
    }

    static size_t rotateLeft(size_t n, size_t rotate) {
        return (n << rotate) | (n >> (32 - rotate));
    }

    static bool encode12BitImmediate(size_t immediate, size_t* pResult) {
        for(size_t i = 0; i < 16; i++) {
            size_t rotate = i * 2;
            size_t mask = rotateRight(0xff, rotate);
            if ((immediate | mask) == mask) {
                size_t bits8 = rotateLeft(immediate, rotate);
                // assert(bits8 <= 0xff);
                *pResult = (i << 8) | bits8;
                return true;
            }
        }
        return false;
    }

    static size_t decode12BitImmediate(size_t immediate) {
        size_t data = immediate & 0xff;
        size_t rotate = 2 * ((immediate >> 8) & 0xf);
        return rotateRight(data, rotate);
    }

    static bool isPowerOfTwo(size_t n) {
        return (n != 0) & ((n & (n-1)) == 0);
    }

    static size_t log2(size_t n) {
        int result = 0;
        while (n >>= 1) {
            result++;
        }
        return result;
    }

    class ARMCodeBuf : public ICodeBuf {
        ICodeBuf* mpBase;
        ErrorSink* mErrorSink;

        class CircularQueue {
            static const int SIZE = 16; // Must be power of 2
            static const int MASK = SIZE-1;
            unsigned int mBuf[SIZE];
            int mHead;
            int mCount;

        public:
            CircularQueue() {
                mHead = 0;
                mCount = 0;
            }

            void pushBack(unsigned int data) {
                mBuf[(mHead + mCount) & MASK] = data;
                mCount += 1;
            }

            unsigned int popFront() {
                unsigned int result = mBuf[mHead];
                mHead = (mHead + 1) & MASK;
                mCount -= 1;
                return result;
            }

            void popBack(int n) {
                mCount -= n;
            }

            inline int count() {
                return mCount;
            }

            bool empty() {
                return mCount == 0;
            }

            bool full() {
                return mCount == SIZE;
            }

            // The valid indexes are 1 - count() to 0
            unsigned int operator[](int i) {
                return mBuf[(mHead + mCount + i) & MASK];
            }
        };

        CircularQueue mQ;

        void error(const char* fmt,...) {
            va_list ap;
            va_start(ap, fmt);
            mErrorSink->verror(fmt, ap);
            va_end(ap);
        }

        void flush() {
            while (!mQ.empty()) {
                mpBase->o4(mQ.popFront());
            }
            mpBase->flush();
        }

    public:
        ARMCodeBuf(ICodeBuf* pBase) {
            mpBase = pBase;
        }

        virtual ~ARMCodeBuf() {
            delete mpBase;
        }

        void init(int size) {
            mpBase->init(size);
        }

        void setErrorSink(ErrorSink* pErrorSink) {
            mErrorSink = pErrorSink;
            mpBase->setErrorSink(pErrorSink);
        }

        void o4(int n) {
            if (mQ.full()) {
                mpBase->o4(mQ.popFront());
            }
            mQ.pushBack(n);

#ifndef DISABLE_ARM_PEEPHOLE
            // Peephole check
            bool didPeep;
            do {
                static const unsigned int opMask = 0x01e00000;
                static const unsigned int immediateMask = 0x00000fff;
                static const unsigned int BMask = 0x00400000;
                didPeep = false;
                if (mQ.count() >= 4) {

                    // Operand by a small constant
                    // push;mov #imm;pop;op ==> op #imm

                    if (mQ[-4] == 0xe92d0001  && // stmfd    r13!, {r0}
                        (mQ[-3] & ~immediateMask) == 0xe3a00000  && // mov    r0, #X
                        mQ[-2] == 0xe8bd0002  && // ldmea    r13!, {r1}
                        (mQ[-1] & ~opMask) == (0xe0810000 & ~opMask)) {  // OP    r0, r1, r0
                        unsigned int movConst = mQ[-3];
                        unsigned int op = mQ[-1];
                        unsigned int combined = 0xe2000000 | (op & opMask) | (movConst & immediateMask);
                        // fprintf(stderr, "op %x movConst %x combined %x\n", op, movConst, combined);
                        if (! (combined == 0xe2800000 || combined == 0xe2400000)) { // add/sub #0
                            mQ.popBack(4);
                            mQ.pushBack(combined);
                            didPeep = true;
                        } else {
                            mQ.popBack(4);
                            didPeep = true;
                        }
                    }
                }

                // Load local variable
                // sub r0,r11,#imm;ldr/ldrb r0,[r0]  ==> ldr/ldrb r0, [r11,#-imm]
                if (mQ.count() >= 2) {
                    if ((mQ[-2] & ~immediateMask) == 0xe24b0000) { // sub r0,r11,#imm
                        const unsigned int encodedImmediate = mQ[-2] & immediateMask;
                        const unsigned int ld = mQ[-1];
                        if ((ld & ~BMask) == 0xe5900000) { // ldr{b} r0, [r0]
                            unsigned int combined = encodedImmediate | (0xE51B0000 | (ld & BMask)); // ldr r0, [r11, #-0]
                            mQ.popBack(2);
                            mQ.pushBack(combined);
                            didPeep = true;
                        } else if (ld == 0xedd07a00) {  // ldcl    p10, c7, [r0, #0x000]
                            unsigned int decodedImmediate = decode12BitImmediate(encodedImmediate);
                            if (decodedImmediate <= 1020 && ((decodedImmediate & 3) == 0)) {
                                unsigned int combined = (decodedImmediate >> 2) | 0xed5b7a00; // ldcl    p10, c7, [r11, #-0]
                                mQ.popBack(2);
                                mQ.pushBack(combined);
                                didPeep = true;
                            }
                        }
                    }
                }

                // Constant array lookup

                if (mQ.count() >= 6 &&
                    mQ[-6] == 0xe92d0001 && // stmfd r13!, {r0}
                    (mQ[-5] & ~immediateMask)== 0xe3a00000 && // mov r0, #0x00000001
                    mQ[-4] == 0xe8bd0002 && // ldmea r13!, {r1}
                    (mQ[-3] & ~immediateMask)== 0xe3a02000 && // mov r2, #0x00000004
                    mQ[-2] == 0xe0000092 && // mul r0, r2, r0
                    mQ[-1] == 0xe0810000) { // add r0, r1, r0
                    unsigned int mov1 = mQ[-5];
                    unsigned int mov2 = mQ[-3];
                    unsigned int const1 = decode12BitImmediate(mov1);
                    unsigned int const2 = decode12BitImmediate(mov2);
                    unsigned int comboConst = const1 * const2;
                    size_t immediate = 0;
                    if (encode12BitImmediate(comboConst, &immediate)) {
                        mQ.popBack(6);
                        unsigned int add = immediate | 0xE2800000; // add r0, r0, #n
                        if (comboConst) {
                            mQ.pushBack(add);
                        }
                        didPeep = true;
                    }
                }

                // Pointer arithmetic with a stride that is a power of two

                if (mQ.count() >= 3 &&
                    (mQ[-3] & ~ immediateMask) == 0xe3a02000 &&  // mov    r2, #stride
                     mQ[-2] == 0xe0000092 && // mul    r0, r2, r0
                     mQ[-1] == 0xe0810000) {  // add r0, r1, r0
                    int stride = decode12BitImmediate(mQ[-3]);
                    if (isPowerOfTwo(stride)) {
                        mQ.popBack(3);
                        unsigned int add = 0xe0810000 | (log2(stride) << 7); // add r0, r1, r0, LSL #log2(stride)
                        mQ.pushBack(add);
                        didPeep = true;
                    }
                }

            } while (didPeep);
#endif
        }

        void ob(int n) {
            error("ob() not supported.");
        }

        void* getBase() {
            flush();
            return mpBase->getBase();
        }

        intptr_t getSize() {
            flush();
            return mpBase->getSize();
        }

        intptr_t getPC() {
            flush();
            return mpBase->getPC();
        }
    };

    class ARMCodeGenerator : public CodeGenerator {
    public:
        ARMCodeGenerator() {
#ifdef ARM_USE_VFP
            // LOGD("Using ARM VFP hardware floating point.");
#else
            // LOGD("Using ARM soft floating point.");
#endif
        }

        virtual ~ARMCodeGenerator() {}

        /* returns address to patch with local variable size
        */
        virtual int functionEntry(Type* pDecl) {
            mStackUse = 0;
            // sp -> arg4 arg5 ...
            // Push our register-based arguments back on the stack
            int regArgCount = calcRegArgCount(pDecl);
            if (regArgCount > 0) {
                mStackUse += regArgCount * 4;
                o4(0xE92D0000 | ((1 << regArgCount) - 1)); // stmfd    sp!, {}
            }
            // sp -> arg0 arg1 ...
            o4(0xE92D4800); // stmfd sp!, {fp, lr}
            mStackUse += 2 * 4;
            // sp, fp -> oldfp, retadr, arg0 arg1 ....
            o4(0xE1A0B00D); // mov    fp, sp
            LOG_STACK("functionEntry: %d\n", mStackUse);
            int pc = getPC();
            o4(0xE24DD000); // sub    sp, sp, # <local variables>
            // We don't know how many local variables we are going to use,
            // but we will round the allocation up to a multiple of
            // STACK_ALIGNMENT, so it won't affect the stack alignment.
            return pc;
        }

        virtual void functionExit(Type* pDecl, int localVariableAddress, int localVariableSize) {
            // Round local variable size up to a multiple of stack alignment
            localVariableSize = ((localVariableSize + STACK_ALIGNMENT - 1) /
                STACK_ALIGNMENT) * STACK_ALIGNMENT;
            // Patch local variable allocation code:
            if (localVariableSize < 0 || localVariableSize > 255) {
                error("localVariables out of range: %d", localVariableSize);
            }
            *(char*) (localVariableAddress) = localVariableSize;

#ifdef ARM_USE_VFP
            {
                Type* pReturnType = pDecl->pHead;
                switch(pReturnType->tag) {
                case TY_FLOAT:
                    o4(0xEE170A90); // fmrs    r0, s15
                    break;
                case TY_DOUBLE:
                    o4(0xEC510B17); // fmrrd r0, r1, d7
                    break;
                default:
                    break;
                }
            }
#endif

            // sp -> locals .... fp -> oldfp, retadr, arg0, arg1, ...
            o4(0xE1A0E00B); // mov lr, fp
            o4(0xE59BB000); // ldr fp, [fp]
            o4(0xE28ED004); // add sp, lr, #4
            // sp -> retadr, arg0, ...
            o4(0xE8BD4000); // ldmfd    sp!, {lr}
            // sp -> arg0 ....

            // We store the PC into the lr so we can adjust the sp before
            // returning. We need to pull off the registers we pushed
            // earlier. We don't need to actually store them anywhere,
            // just adjust the stack.
            int regArgCount = calcRegArgCount(pDecl);
            if (regArgCount) {
                o4(0xE28DD000 | (regArgCount << 2)); // add sp, sp, #argCount << 2
            }
            o4(0xE12FFF1E); // bx lr
        }

        /* load immediate value */
        virtual void li(int t) {
            liReg(t, 0);
            setR0Type(mkpInt);
        }

        virtual void loadFloat(int address, Type* pType) {
            setR0Type(pType);
            // Global, absolute address
            o4(0xE59F0000); //        ldr r0, .L1
            o4(0xEA000000); //        b .L99
            o4(address);         // .L1:   .word ea
                                 // .L99:

            switch (pType->tag) {
            case TY_FLOAT:
#ifdef ARM_USE_VFP
                o4(0xEDD07A00);      // flds    s15, [r0]
#else
                o4(0xE5900000);      // ldr r0, [r0]
#endif
                break;
            case TY_DOUBLE:
#ifdef ARM_USE_VFP
                o4(0xED907B00);      // fldd    d7, [r0]
#else
                o4(0xE1C000D0);      // ldrd r0, [r0]
#endif
                break;
            default:
                assert(false);
                break;
            }
        }


        virtual void addStructOffsetR0(int offset, Type* pType) {
            if (offset) {
                size_t immediate = 0;
                if (encode12BitImmediate(offset, &immediate)) {
                    o4(0xE2800000 | immediate); // add    r0, r0, #offset
                } else {
                    error("structure offset out of range: %d", offset);
                }
            }
            setR0Type(pType, ET_LVALUE);
        }

        virtual int gjmp(int t) {
            int pc = getPC();
            o4(0xEA000000 | encodeAddress(t)); // b .L33
            return pc;
        }

        /* l = 0: je, l == 1: jne */
        virtual int gtst(bool l, int t) {
            Type* pR0Type = getR0Type();
            TypeTag tagR0 = pR0Type->tag;
            switch(tagR0) {
                case TY_FLOAT:
#ifdef ARM_USE_VFP
                    o4(0xEEF57A40); // fcmpzs    s15
                    o4(0xEEF1FA10); // fmstat
#else
                    callRuntime((void*) runtime_is_non_zero_f);
                    o4(0xE3500000); // cmp r0,#0
#endif
                    break;
                case TY_DOUBLE:
#ifdef ARM_USE_VFP
                    o4(0xEEB57B40); // fcmpzd    d7
                    o4(0xEEF1FA10); // fmstat
#else
                    callRuntime((void*) runtime_is_non_zero_d);
                    o4(0xE3500000); // cmp r0,#0
#endif
                    break;
                default:
                    o4(0xE3500000); // cmp r0,#0
                    break;
            }
            int branch = l ? 0x1A000000 : 0x0A000000; // bne : beq
            int pc = getPC();
            o4(branch | encodeAddress(t));
            return pc;
        }

        virtual void gcmp(int op) {
            Type* pR0Type = getR0Type();
            Type* pTOSType = getTOSType();
            TypeTag tagR0 = collapseType(pR0Type->tag);
            TypeTag tagTOS = collapseType(pTOSType->tag);
            if (tagR0 == TY_INT && tagTOS == TY_INT) {
                setupIntPtrArgs();
                o4(0xE1510000); // cmp r1, r1
                switch(op) {
                case OP_EQUALS:
                    o4(0x03A00001); // moveq r0,#1
                    o4(0x13A00000); // movne r0,#0
                    break;
                case OP_NOT_EQUALS:
                    o4(0x03A00000); // moveq r0,#0
                    o4(0x13A00001); // movne r0,#1
                    break;
                case OP_LESS_EQUAL:
                    o4(0xD3A00001); // movle r0,#1
                    o4(0xC3A00000); // movgt r0,#0
                    break;
                case OP_GREATER:
                    o4(0xD3A00000); // movle r0,#0
                    o4(0xC3A00001); // movgt r0,#1
                    break;
                case OP_GREATER_EQUAL:
                    o4(0xA3A00001); // movge r0,#1
                    o4(0xB3A00000); // movlt r0,#0
                    break;
                case OP_LESS:
                    o4(0xA3A00000); // movge r0,#0
                    o4(0xB3A00001); // movlt r0,#1
                    break;
                default:
                    error("Unknown comparison op %d", op);
                    break;
                }
            } else if (tagR0 == TY_DOUBLE || tagTOS == TY_DOUBLE) {
                setupDoubleArgs();
#ifdef ARM_USE_VFP
                o4(0xEEB46BC7); //         fcmped    d6, d7
                   o4(0xEEF1FA10); // fmstat
                switch(op) {
                case OP_EQUALS:
                    o4(0x03A00001); // moveq r0,#1
                    o4(0x13A00000); // movne r0,#0
                    break;
                case OP_NOT_EQUALS:
                    o4(0x03A00000); // moveq r0,#0
                    o4(0x13A00001); // movne r0,#1
                    break;
                case OP_LESS_EQUAL:
                    o4(0xD3A00001); // movle r0,#1
                    o4(0xC3A00000); // movgt r0,#0
                    break;
                case OP_GREATER:
                    o4(0xD3A00000); // movle r0,#0
                    o4(0xC3A00001); // movgt r0,#1
                    break;
                case OP_GREATER_EQUAL:
                    o4(0xA3A00001); // movge r0,#1
                    o4(0xB3A00000); // movlt r0,#0
                    break;
                case OP_LESS:
                    o4(0xA3A00000); // movge r0,#0
                    o4(0xB3A00001); // movlt r0,#1
                    break;
                default:
                    error("Unknown comparison op %d", op);
                    break;
                }
#else
                switch(op) {
                    case OP_EQUALS:
                        callRuntime((void*) runtime_cmp_eq_dd);
                        break;
                    case OP_NOT_EQUALS:
                        callRuntime((void*) runtime_cmp_ne_dd);
                        break;
                    case OP_LESS_EQUAL:
                        callRuntime((void*) runtime_cmp_le_dd);
                        break;
                    case OP_GREATER:
                        callRuntime((void*) runtime_cmp_gt_dd);
                        break;
                    case OP_GREATER_EQUAL:
                        callRuntime((void*) runtime_cmp_ge_dd);
                        break;
                    case OP_LESS:
                        callRuntime((void*) runtime_cmp_lt_dd);
                        break;
                    default:
                        error("Unknown comparison op %d", op);
                        break;
                }
#endif
            } else {
                setupFloatArgs();
#ifdef ARM_USE_VFP
                o4(0xEEB47AE7); // fcmpes s14, s15
                   o4(0xEEF1FA10); // fmstat
                switch(op) {
                case OP_EQUALS:
                    o4(0x03A00001); // moveq r0,#1
                    o4(0x13A00000); // movne r0,#0
                    break;
                case OP_NOT_EQUALS:
                    o4(0x03A00000); // moveq r0,#0
                    o4(0x13A00001); // movne r0,#1
                    break;
                case OP_LESS_EQUAL:
                    o4(0xD3A00001); // movle r0,#1
                    o4(0xC3A00000); // movgt r0,#0
                    break;
                case OP_GREATER:
                    o4(0xD3A00000); // movle r0,#0
                    o4(0xC3A00001); // movgt r0,#1
                    break;
                case OP_GREATER_EQUAL:
                    o4(0xA3A00001); // movge r0,#1
                    o4(0xB3A00000); // movlt r0,#0
                    break;
                case OP_LESS:
                    o4(0xA3A00000); // movge r0,#0
                    o4(0xB3A00001); // movlt r0,#1
                    break;
                default:
                    error("Unknown comparison op %d", op);
                    break;
                }
#else
                switch(op) {
                    case OP_EQUALS:
                        callRuntime((void*) runtime_cmp_eq_ff);
                        break;
                    case OP_NOT_EQUALS:
                        callRuntime((void*) runtime_cmp_ne_ff);
                        break;
                    case OP_LESS_EQUAL:
                        callRuntime((void*) runtime_cmp_le_ff);
                        break;
                    case OP_GREATER:
                        callRuntime((void*) runtime_cmp_gt_ff);
                        break;
                    case OP_GREATER_EQUAL:
                        callRuntime((void*) runtime_cmp_ge_ff);
                        break;
                    case OP_LESS:
                        callRuntime((void*) runtime_cmp_lt_ff);
                        break;
                    default:
                        error("Unknown comparison op %d", op);
                        break;
                }
#endif
            }
            setR0Type(mkpInt);
        }

        virtual void genOp(int op) {
            Type* pR0Type = getR0Type();
            Type* pTOSType = getTOSType();
            TypeTag tagR0 = pR0Type->tag;
            TypeTag tagTOS = pTOSType->tag;
            bool isFloatR0 = isFloatTag(tagR0);
            bool isFloatTOS = isFloatTag(tagTOS);
            if (!isFloatR0 && !isFloatTOS) {
                setupIntPtrArgs();
                bool isPtrR0 = isPointerTag(tagR0);
                bool isPtrTOS = isPointerTag(tagTOS);
                if (isPtrR0 || isPtrTOS) {
                    if (isPtrR0 && isPtrTOS) {
                        if (op != OP_MINUS) {
                            error("Unsupported pointer-pointer operation %d.", op);
                        }
                        if (! typeEqual(pR0Type, pTOSType)) {
                            error("Incompatible pointer types for subtraction.");
                        }
                        o4(0xE0410000); // sub     r0,r1,r0
                        setR0Type(mkpInt);
                        int size = sizeOf(pR0Type->pHead);
                        if (size != 1) {
                            pushR0();
                            li(size);
                            // TODO: Optimize for power-of-two.
                            genOp(OP_DIV);
                        }
                    } else {
                        if (! (op == OP_PLUS || (op == OP_MINUS && isPtrR0))) {
                            error("Unsupported pointer-scalar operation %d", op);
                        }
                        Type* pPtrType = getPointerArithmeticResultType(
                                pR0Type, pTOSType);
                        int size = sizeOf(pPtrType->pHead);
                        if (size != 1) {
                            // TODO: Optimize for power-of-two.
                            liReg(size, 2);
                            if (isPtrR0) {
                                o4(0x0E0010192); // mul     r1,r2,r1
                            } else {
                                o4(0x0E0000092); // mul     r0,r2,r0
                            }
                        }
                        switch(op) {
                            case OP_PLUS:
                            o4(0xE0810000); // add     r0,r1,r0
                            break;
                            case OP_MINUS:
                            o4(0xE0410000); // sub     r0,r1,r0
                            break;
                        }
                        setR0Type(pPtrType);
                    }
                } else {
                    switch(op) {
                        case OP_MUL:
                        o4(0x0E0000091); // mul     r0,r1,r0
                        break;
                        case OP_DIV:
                        callRuntime((void*) runtime_DIV);
                        break;
                        case OP_MOD:
                        callRuntime((void*) runtime_MOD);
                        break;
                        case OP_PLUS:
                        o4(0xE0810000); // add     r0,r1,r0
                        break;
                        case OP_MINUS:
                        o4(0xE0410000); // sub     r0,r1,r0
                        break;
                        case OP_SHIFT_LEFT:
                        o4(0xE1A00011); // lsl     r0,r1,r0
                        break;
                        case OP_SHIFT_RIGHT:
                        o4(0xE1A00051); // asr     r0,r1,r0
                        break;
                        case OP_BIT_AND:
                        o4(0xE0010000); // and     r0,r1,r0
                        break;
                        case OP_BIT_XOR:
                        o4(0xE0210000); // eor     r0,r1,r0
                        break;
                        case OP_BIT_OR:
                        o4(0xE1810000); // orr     r0,r1,r0
                        break;
                        case OP_BIT_NOT:
                        o4(0xE1E00000); // mvn     r0, r0
                        break;
                        default:
                        error("Unimplemented op %d\n", op);
                        break;
                    }
                }
            } else {
                Type* pResultType = tagR0 > tagTOS ? pR0Type : pTOSType;
                if (pResultType->tag == TY_DOUBLE) {
                    setupDoubleArgs();

                    switch(op) {
                    case OP_MUL:
#ifdef ARM_USE_VFP
                        o4(0xEE267B07); // fmuld d7, d6, d7
#else
                        callRuntime((void*) runtime_op_mul_dd);
#endif
                        break;
                    case OP_DIV:
#ifdef ARM_USE_VFP
                        o4(0xEE867B07); // fdivd d7, d6, d7
#else
                        callRuntime((void*) runtime_op_div_dd);
#endif
                        break;
                    case OP_PLUS:
#ifdef ARM_USE_VFP
                        o4(0xEE367B07); // faddd d7, d6, d7
#else
                        callRuntime((void*) runtime_op_add_dd);
#endif
                        break;
                    case OP_MINUS:
#ifdef ARM_USE_VFP
                        o4(0xEE367B47); // fsubd d7, d6, d7
#else
                        callRuntime((void*) runtime_op_sub_dd);
#endif
                        break;
                    default:
                        error("Unsupported binary floating operation %d\n", op);
                        break;
                    }
                } else {
                    setupFloatArgs();
                    switch(op) {
                    case OP_MUL:
#ifdef ARM_USE_VFP
                        o4(0xEE677A27); // fmuls s15, s14, s15
#else
                        callRuntime((void*) runtime_op_mul_ff);
#endif
                        break;
                    case OP_DIV:
#ifdef ARM_USE_VFP
                        o4(0xEEC77A27); // fdivs s15, s14, s15
#else
                        callRuntime((void*) runtime_op_div_ff);
#endif
                        break;
                    case OP_PLUS:
#ifdef ARM_USE_VFP
                        o4(0xEE777A27); // fadds s15, s14, s15
#else
                        callRuntime((void*) runtime_op_add_ff);
#endif
                        break;
                    case OP_MINUS:
#ifdef ARM_USE_VFP
                        o4(0xEE777A67); // fsubs s15, s14, s15
#else
                        callRuntime((void*) runtime_op_sub_ff);
#endif
                        break;
                    default:
                        error("Unsupported binary floating operation %d\n", op);
                        break;
                    }
                }
                setR0Type(pResultType);
            }
        }

        virtual void gUnaryCmp(int op) {
            if (op != OP_LOGICAL_NOT) {
                error("Unknown unary cmp %d", op);
            } else {
                Type* pR0Type = getR0Type();
                TypeTag tag = collapseType(pR0Type->tag);
                switch(tag) {
                    case TY_INT:
                        o4(0xE3A01000); // mov    r1, #0
                        o4(0xE1510000); // cmp r1, r0
                        o4(0x03A00001); // moveq r0,#1
                        o4(0x13A00000); // movne r0,#0
                        break;
                    case TY_FLOAT:
#ifdef ARM_USE_VFP
                        o4(0xEEF57A40); // fcmpzs s15
                        o4(0xEEF1FA10); // fmstat
                        o4(0x03A00001); // moveq r0,#1
                        o4(0x13A00000); // movne r0,#0
#else
                        callRuntime((void*) runtime_is_zero_f);
#endif
                        break;
                    case TY_DOUBLE:
#ifdef ARM_USE_VFP
                        o4(0xEEB57B40); // fcmpzd d7
                        o4(0xEEF1FA10); // fmstat
                        o4(0x03A00001); // moveq r0,#1
                        o4(0x13A00000); // movne r0,#0
#else
                        callRuntime((void*) runtime_is_zero_d);
#endif
                        break;
                    default:
                        error("gUnaryCmp unsupported type");
                        break;
                }
            }
            setR0Type(mkpInt);
        }

        virtual void genUnaryOp(int op) {
            Type* pR0Type = getR0Type();
            TypeTag tag = collapseType(pR0Type->tag);
            switch(tag) {
                case TY_INT:
                    switch(op) {
                    case OP_MINUS:
                        o4(0xE3A01000);  // mov    r1, #0
                        o4(0xE0410000);  // sub     r0,r1,r0
                        break;
                    case OP_BIT_NOT:
                        o4(0xE1E00000);  // mvn     r0, r0
                        break;
                    default:
                        error("Unknown unary op %d\n", op);
                        break;
                    }
                    break;
                case TY_FLOAT:
                case TY_DOUBLE:
                    switch (op) {
                        case OP_MINUS:
                            if (tag == TY_FLOAT) {
#ifdef ARM_USE_VFP
                                o4(0xEEF17A67); // fnegs    s15, s15
#else
                                callRuntime((void*) runtime_op_neg_f);
#endif
                            } else {
#ifdef ARM_USE_VFP
                                o4(0xEEB17B47); // fnegd    d7, d7
#else
                                callRuntime((void*) runtime_op_neg_d);
#endif
                            }
                            break;
                        case OP_BIT_NOT:
                            error("Can't apply '~' operator to a float or double.");
                            break;
                        default:
                            error("Unknown unary op %d\n", op);
                            break;
                        }
                    break;
                default:
                    error("genUnaryOp unsupported type");
                    break;
            }
        }

        virtual void pushR0() {
            Type* pR0Type = getR0Type();
            TypeTag r0ct = collapseType(pR0Type->tag);

#ifdef ARM_USE_VFP
            switch (r0ct ) {
            case TY_FLOAT:
                o4(0xED6D7A01); // fstmfds   sp!,{s15}
                mStackUse += 4;
                break;
            case TY_DOUBLE:
                o4(0xED2D7B02); // fstmfdd   sp!,{d7}
                mStackUse += 8;
                break;
            default:
                o4(0xE92D0001);  // stmfd   sp!,{r0}
                mStackUse += 4;
            }
#else

            if (r0ct != TY_DOUBLE) {
                    o4(0xE92D0001);  // stmfd   sp!,{r0}
                    mStackUse += 4;
            } else {
                    o4(0xE92D0003);  // stmfd   sp!,{r0,r1}
                    mStackUse += 8;
            }
#endif
            pushType();
            LOG_STACK("pushR0: %d\n", mStackUse);
        }

        virtual void over() {
            // We know it's only used for int-ptr ops (++/--)

            Type* pR0Type = getR0Type();
            TypeTag r0ct = collapseType(pR0Type->tag);

            Type* pTOSType = getTOSType();
            TypeTag tosct = collapseType(pTOSType->tag);

            assert (r0ct == TY_INT  && tosct == TY_INT);

            o4(0xE8BD0002);  // ldmfd   sp!,{r1}
            o4(0xE92D0001);  // stmfd   sp!,{r0}
            o4(0xE92D0002);  // stmfd   sp!,{r1}
            overType();
            mStackUse += 4;
        }

        virtual void popR0() {
            Type* pTOSType = getTOSType();
            TypeTag tosct = collapseType(pTOSType->tag);
#ifdef ARM_USE_VFP
            if (tosct == TY_FLOAT || tosct == TY_DOUBLE) {
                error("Unsupported popR0 float/double");
            }
#endif
            switch (tosct){
                case TY_INT:
                case TY_FLOAT:
                    o4(0xE8BD0001);  // ldmfd   sp!,{r0}
                    mStackUse -= 4;
                    break;
                case TY_DOUBLE:
                    o4(0xE8BD0003);  // ldmfd   sp!,{r0, r1}  // Restore R0
                        mStackUse -= 8;
                    break;
                default:
                    error("Can't pop this type.");
                    break;
            }
            popType();
            LOG_STACK("popR0: %d\n", mStackUse);
        }

        virtual void storeR0ToTOS() {
            Type* pPointerType = getTOSType();
            assert(pPointerType->tag == TY_POINTER);
            Type* pDestType = pPointerType->pHead;
            convertR0(pDestType);
            o4(0xE8BD0004);  // ldmfd   sp!,{r2}
            popType();
            mStackUse -= 4;
            switch (pDestType->tag) {
                case TY_POINTER:
                case TY_INT:
                    o4(0xE5820000); // str r0, [r2]
                    break;
                case TY_FLOAT:
#ifdef ARM_USE_VFP
                    o4(0xEDC27A00); // fsts    s15, [r2, #0]
#else
                    o4(0xE5820000); // str r0, [r2]
#endif
                    break;
                case TY_SHORT:
                    o4(0xE1C200B0); // strh r0, [r2]
                    break;
                case TY_CHAR:
                    o4(0xE5C20000); // strb r0, [r2]
                    break;
                case TY_DOUBLE:
#ifdef ARM_USE_VFP
                    o4(0xED827B00); // fstd    d7, [r2, #0]
#else
                    o4(0xE1C200F0); // strd r0, [r2]
#endif
                    break;
                case TY_STRUCT:
                {
                    int size = sizeOf(pDestType);
                    if (size > 0) {
                        liReg(size, 1);
                        callRuntime((void*) runtime_structCopy);
                    }
                }
                    break;
                default:
                    error("storeR0ToTOS: unimplemented type %d",
                            pDestType->tag);
                    break;
            }
        }

        virtual void loadR0FromR0() {
            Type* pPointerType = getR0Type();
            assert(pPointerType->tag == TY_POINTER);
            Type* pNewType = pPointerType->pHead;
            TypeTag tag = pNewType->tag;
            switch (tag) {
                case TY_POINTER:
                case TY_INT:
                    o4(0xE5900000); // ldr r0, [r0]
                    break;
                case TY_FLOAT:
#ifdef ARM_USE_VFP
                    o4(0xEDD07A00); // flds    s15, [r0, #0]
#else
                    o4(0xE5900000); // ldr r0, [r0]
#endif
                    break;
                case TY_SHORT:
                    o4(0xE1D000F0); // ldrsh r0, [r0]
                    break;
                case TY_CHAR:
                    o4(0xE5D00000); // ldrb r0, [r0]
                    break;
                case TY_DOUBLE:
#ifdef ARM_USE_VFP
                    o4(0xED907B00); // fldd    d7, [r0, #0]
#else
                    o4(0xE1C000D0); // ldrd   r0, [r0]
#endif
                    break;
                case TY_ARRAY:
                    pNewType = pNewType->pTail;
                    break;
                case TY_STRUCT:
                    break;
                default:
                    error("loadR0FromR0: unimplemented type %d", tag);
                    break;
            }
            setR0Type(pNewType);
        }

        virtual void leaR0(int ea, Type* pPointerType, ExpressionType et) {
            if (ea > -LOCAL && ea < LOCAL) {
                // Local, fp relative

                size_t immediate = 0;
                bool inRange = false;
                if (ea < 0) {
                    inRange = encode12BitImmediate(-ea, &immediate);
                    o4(0xE24B0000 | immediate); // sub    r0, fp, #ea
                } else {
                    inRange = encode12BitImmediate(ea, &immediate);
                    o4(0xE28B0000 | immediate); // add    r0, fp, #ea
                }
                if (! inRange) {
                    error("Offset out of range: %08x", ea);
                }
            } else {
                // Global, absolute.
                o4(0xE59F0000); //        ldr    r0, .L1
                o4(0xEA000000); //        b .L99
                o4(ea);         // .L1:   .word 0
                                // .L99:
            }
            setR0Type(pPointerType, et);
        }

        virtual int leaForward(int ea, Type* pPointerType) {
            setR0Type(pPointerType);
            int result = ea;
            int pc = getPC();
            int offset = 0;
            if (ea) {
                offset = (pc - ea - 8) >> 2;
                if ((offset & 0xffff) != offset) {
                    error("function forward reference out of bounds");
                }
            } else {
                offset = 0;
            }
            o4(0xE59F0000 | offset); //        ldr    r0, .L1

            if (ea == 0) {
                o4(0xEA000000); //        b .L99
                result = getPC();
                o4(ea);         // .L1:   .word 0
                            // .L99:
            }
            return result;
        }

        virtual void convertR0Imp(Type* pType, bool isCast){
            Type* pR0Type = getR0Type();
            if (isPointerType(pType) && isPointerType(pR0Type)) {
                Type* pA = pR0Type;
                Type* pB = pType;
                // Array decays to pointer
                if (pA->tag == TY_ARRAY && pB->tag == TY_POINTER) {
                    pA = pA->pTail;
                }
                if (! (typeEqual(pA, pB)
                        || pB->pHead->tag == TY_VOID
                        || (pA->tag == TY_POINTER && pB->tag == TY_POINTER && isCast)
                    )) {
                    error("Incompatible pointer or array types");
                }
            } else if (bitsSame(pType, pR0Type)) {
                // do nothing special
            } else {
                TypeTag r0Tag = collapseType(pR0Type->tag);
                TypeTag destTag = collapseType(pType->tag);
                if (r0Tag == TY_INT) {
                    if (destTag == TY_FLOAT) {
#ifdef ARM_USE_VFP
                        o4(0xEE070A90); // fmsr    s15, r0
                        o4(0xEEF87AE7); // fsitos s15, s15

#else
                        callRuntime((void*) runtime_int_to_float);
#endif
                    } else {
                        assert(destTag == TY_DOUBLE);
#ifdef ARM_USE_VFP
                        o4(0xEE070A90); // fmsr s15, r0
                        o4(0xEEB87BE7); // fsitod d7, s15

#else
                        callRuntime((void*) runtime_int_to_double);
#endif
                    }
                } else if (r0Tag == TY_FLOAT) {
                    if (destTag == TY_INT) {
#ifdef ARM_USE_VFP
                        o4(0xEEFD7AE7); // ftosizs s15, s15
                        o4(0xEE170A90); // fmrs r0, s15
#else
                        callRuntime((void*) runtime_float_to_int);
#endif
                    } else {
                        assert(destTag == TY_DOUBLE);
#ifdef ARM_USE_VFP
                        o4(0xEEB77AE7); // fcvtds    d7, s15
#else
                        callRuntime((void*) runtime_float_to_double);
#endif
                    }
                } else {
                    if (r0Tag == TY_DOUBLE) {
                        if (destTag == TY_INT) {
#ifdef ARM_USE_VFP
                            o4(0xEEFD7BC7); // ftosizd s15, d7
                            o4(0xEE170A90); // fmrs r0, s15
#else
                            callRuntime((void*) runtime_double_to_int);
#endif
                        } else {
                            if(destTag == TY_FLOAT) {
#ifdef ARM_USE_VFP
                                o4(0xEEF77BC7); // fcvtsd s15, d7
#else
                                callRuntime((void*) runtime_double_to_float);
#endif
                            } else {
                                incompatibleTypes(pR0Type, pType);
                            }
                        }
                    } else {
                        incompatibleTypes(pR0Type, pType);
                    }
                }
            }
            setR0Type(pType);
        }

        virtual int beginFunctionCallArguments() {
            int pc = getPC();
            o4(0xE24DDF00); // Placeholder sub  sp, sp, #0
            return pc;
        }

        virtual size_t storeR0ToArg(int l, Type* pArgType) {
            convertR0(pArgType);
            Type* pR0Type = getR0Type();
            TypeTag r0ct = collapseType(pR0Type->tag);
#ifdef ARM_USE_VFP
            switch(r0ct) {
                case TY_INT:
                    if (l < 0 || l > 4096-4) {
                        error("l out of range for stack offset: 0x%08x", l);
                    }
                    o4(0xE58D0000 | l); // str r0, [sp, #l]
                    return 4;
                case TY_FLOAT:
                    if (l < 0 || l > 1020 || (l & 3)) {
                        error("l out of range for stack offset: 0x%08x", l);
                    }
                    o4(0xEDCD7A00 | (l >> 2)); // fsts    s15, [sp, #l]
                    return 4;
                case TY_DOUBLE: {
                    // Align to 8 byte boundary
                    int l2 = (l + 7) & ~7;
                    if (l2 < 0 || l2 > 1020 || (l2 & 3)) {
                        error("l out of range for stack offset: 0x%08x", l);
                    }
                    o4(0xED8D7B00 | (l2 >> 2)); // fstd    d7, [sp, #l2]
                    return (l2 - l) + 8;
                }
                default:
                    assert(false);
                    return 0;
            }
#else
            switch(r0ct) {
                case TY_INT:
                case TY_FLOAT:
                    if (l < 0 || l > 4096-4) {
                        error("l out of range for stack offset: 0x%08x", l);
                    }
                    o4(0xE58D0000 + l); // str r0, [sp, #l]
                    return 4;
                case TY_DOUBLE: {
                    // Align to 8 byte boundary
                    int l2 = (l + 7) & ~7;
                    if (l2 < 0 || l2 > 4096-8) {
                        error("l out of range for stack offset: 0x%08x", l);
                    }
                    o4(0xE58D0000 + l2); // str r0, [sp, #l]
                    o4(0xE58D1000 + l2 + 4); // str r1, [sp, #l+4]
                    return (l2 - l) + 8;
                }
                default:
                    assert(false);
                    return 0;
            }
#endif
        }

        virtual void endFunctionCallArguments(Type* pDecl, int a, int l) {
            int argumentStackUse = l;
            // Have to calculate register arg count from actual stack size,
            // in order to properly handle ... functions.
            int regArgCount = l >> 2;
            if (regArgCount > 4) {
                regArgCount = 4;
            }
            if (regArgCount > 0) {
                argumentStackUse -= regArgCount * 4;
                o4(0xE8BD0000 | ((1 << regArgCount) - 1)); // ldmfd   sp!,{}
            }
            mStackUse += argumentStackUse;

            // Align stack.
            int missalignment = mStackUse - ((mStackUse / STACK_ALIGNMENT)
                    * STACK_ALIGNMENT);
            mStackAlignmentAdjustment = 0;
            if (missalignment > 0) {
                mStackAlignmentAdjustment = STACK_ALIGNMENT - missalignment;
            }
            l += mStackAlignmentAdjustment;

            if (l < 0 || l > 0x3FC) {
                error("L out of range for stack adjustment: 0x%08x", l);
            }
            flush();
            * (int*) a = 0xE24DDF00 | (l >> 2); // sub    sp, sp, #0 << 2
            mStackUse += mStackAlignmentAdjustment;
            LOG_STACK("endFunctionCallArguments mStackUse: %d, mStackAlignmentAdjustment %d\n",
                      mStackUse, mStackAlignmentAdjustment);
        }

        virtual int callForward(int symbol, Type* pFunc) {
            setR0Type(pFunc->pHead);
            // Forward calls are always short (local)
            int pc = getPC();
            o4(0xEB000000 | encodeAddress(symbol));
            return pc;
        }

        virtual void callIndirect(int l, Type* pFunc) {
            assert(pFunc->tag == TY_FUNC);
            popType(); // Get rid of indirect fn pointer type
            int argCount = l >> 2;
            int poppedArgs = argCount > 4 ? 4 : argCount;
            int adjustedL = l - (poppedArgs << 2) + mStackAlignmentAdjustment;
            if (adjustedL < 0 || adjustedL > 4096-4) {
                error("l out of range for stack offset: 0x%08x", l);
            }
            o4(0xE59DC000 | (0xfff & adjustedL)); // ldr    r12, [sp,#adjustedL]
            o4(0xE12FFF3C); // blx r12
            Type* pReturnType = pFunc->pHead;
            setR0Type(pReturnType);
#ifdef ARM_USE_VFP
            switch(pReturnType->tag) {
            case TY_FLOAT:
                o4(0xEE070A90); // fmsr s15, r0
                break;
            case TY_DOUBLE:
                o4(0xEC410B17); // fmdrr d7, r0, r1
                break;
            default:
                break;
            }
#endif
        }

        virtual void adjustStackAfterCall(Type* pDecl, int l, bool isIndirect) {
            int argCount = l >> 2;
            // Have to calculate register arg count from actual stack size,
            // in order to properly handle ... functions.
            int regArgCount = l >> 2;
            if (regArgCount > 4) {
                regArgCount = 4;
            }
            int stackArgs = argCount - regArgCount;
            int stackUse =  stackArgs + (isIndirect ? 1 : 0)
                + (mStackAlignmentAdjustment >> 2);
            if (stackUse) {
                if (stackUse < 0 || stackUse > 255) {
                    error("L out of range for stack adjustment: 0x%08x", l);
                }
                o4(0xE28DDF00 | stackUse); // add    sp, sp, #stackUse << 2
                mStackUse -= stackUse * 4;
                LOG_STACK("adjustStackAfterCall: %d\n", mStackUse);
            }
        }

        virtual int jumpOffset() {
            return 8;
        }

        /* output a symbol and patch all calls to it */
        virtual void gsym(int t) {
            int n;
            int base = getBase();
            int pc = getPC();
            while (t) {
                int data = * (int*) t;
                int decodedOffset = ((BRANCH_REL_ADDRESS_MASK & data) << 2);
                if (decodedOffset == 0) {
                    n = 0;
                } else {
                    n = base + decodedOffset; /* next value */
                }
                *(int *) t = (data & ~BRANCH_REL_ADDRESS_MASK)
                    | encodeRelAddress(pc - t - 8);
                t = n;
            }
        }

        /* output a symbol and patch all calls to it */
        virtual void resolveForward(int t) {
            if (t) {
                int pc = getPC();
                *(int *) t = pc;
            }
        }

        virtual int finishCompile() {
#if defined(__arm__)
            const long base = long(getBase());
            const long curr = long(getPC());
            int err = cacheflush(base, curr, 0);
            return err;
#else
            return 0;
#endif
        }

        /**
         * alignment (in bytes) for this type of data
         */
        virtual size_t alignmentOf(Type* pType){
            switch(pType->tag) {
                case TY_CHAR:
                    return 1;
                case TY_SHORT:
                    return 2;
                case TY_DOUBLE:
                    return 8;
                case TY_ARRAY:
                    return alignmentOf(pType->pHead);
                case TY_STRUCT:
                    return pType->pHead->alignment & 0x7fffffff;
                case TY_FUNC:
                    error("alignment of func not supported");
                    return 1;
                default:
                    return 4;
            }
        }

        /**
         * Array element alignment (in bytes) for this type of data.
         */
        virtual size_t sizeOf(Type* pType){
            switch(pType->tag) {
                case TY_INT:
                    return 4;
                case TY_SHORT:
                    return 2;
                case TY_CHAR:
                    return 1;
                case TY_FLOAT:
                    return 4;
                case TY_DOUBLE:
                    return 8;
                case TY_POINTER:
                    return 4;
                case TY_ARRAY:
                    return pType->length * sizeOf(pType->pHead);
                case TY_STRUCT:
                    return pType->pHead->length;
                default:
                    error("Unsupported type %d", pType->tag);
                    return 0;
            }
        }

    private:

        static const int BRANCH_REL_ADDRESS_MASK = 0x00ffffff;

        /** Encode a relative address that might also be
         * a label.
         */
        int encodeAddress(int value) {
            int base = getBase();
            if (value >= base && value <= getPC() ) {
                // This is a label, encode it relative to the base.
                value = value - base;
            }
            return encodeRelAddress(value);
        }

        int encodeRelAddress(int value) {
            return BRANCH_REL_ADDRESS_MASK & (value >> 2);
        }

        int calcRegArgCount(Type* pDecl) {
            int reg = 0;
            Type* pArgs = pDecl->pTail;
            while (pArgs && reg < 4) {
                Type* pArg = pArgs->pHead;
                if ( pArg->tag == TY_DOUBLE) {
                    int evenReg = (reg + 1) & ~1;
                    if (evenReg >= 4) {
                        break;
                    }
                    reg = evenReg + 2;
                } else {
                    reg++;
                }
                pArgs = pArgs->pTail;
            }
            return reg;
        }

        void setupIntPtrArgs() {
            o4(0xE8BD0002);  // ldmfd   sp!,{r1}
            mStackUse -= 4;
            popType();
        }

        /* Pop TOS to R1 (use s14 if VFP)
         * Make sure both R0 and TOS are floats. (Could be ints)
         * We know that at least one of R0 and TOS is already a float
         */
        void setupFloatArgs() {
            Type* pR0Type = getR0Type();
            Type* pTOSType = getTOSType();
            TypeTag tagR0 = collapseType(pR0Type->tag);
            TypeTag tagTOS = collapseType(pTOSType->tag);
            if (tagR0 != TY_FLOAT) {
                assert(tagR0 == TY_INT);
#ifdef ARM_USE_VFP
                o4(0xEE070A90); // fmsr    s15, r0
                o4(0xEEF87AE7); // fsitos s15, s15
#else
                callRuntime((void*) runtime_int_to_float);
#endif
            }
            if (tagTOS != TY_FLOAT) {
                assert(tagTOS == TY_INT);
                assert(tagR0 == TY_FLOAT);
#ifdef ARM_USE_VFP
                o4(0xECBD7A01); // fldmfds sp!, {s14}
                o4(0xEEB87AC7); // fsitos s14, s14
#else
                o4(0xE92D0001);  // stmfd   sp!,{r0}  // push R0
                o4(0xE59D0004);  // ldr     r0, [sp, #4]
                callRuntime((void*) runtime_int_to_float);
                o4(0xE1A01000);  // mov r1, r0
                o4(0xE8BD0001);  // ldmfd   sp!,{r0}  // pop R0
                o4(0xE28DD004);  // add sp, sp, #4 // Pop sp
#endif
            } else {
                // Pop TOS
#ifdef ARM_USE_VFP
                o4(0xECBD7A01); // fldmfds sp!, {s14}

#else
                o4(0xE8BD0002);  // ldmfd   sp!,{r1}
#endif
            }
            mStackUse -= 4;
            popType();
        }

        /* Pop TOS into R2..R3 (use D6 if VFP)
         * Make sure both R0 and TOS are doubles. Could be floats or ints.
         * We know that at least one of R0 and TOS are already a double.
         */

        void setupDoubleArgs() {
            Type* pR0Type = getR0Type();
            Type* pTOSType = getTOSType();
            TypeTag tagR0 = collapseType(pR0Type->tag);
            TypeTag tagTOS = collapseType(pTOSType->tag);
            if (tagR0 != TY_DOUBLE) {
                if (tagR0 == TY_INT) {
#ifdef ARM_USE_VFP
                    o4(0xEE070A90); // fmsr s15, r0
                    o4(0xEEB87BE7); // fsitod d7, s15

#else
                    callRuntime((void*) runtime_int_to_double);
#endif
                } else {
                    assert(tagR0 == TY_FLOAT);
#ifdef ARM_USE_VFP
                    o4(0xEEB77AE7); // fcvtds    d7, s15
#else
                    callRuntime((void*) runtime_float_to_double);
#endif
                }
            }
            if (tagTOS != TY_DOUBLE) {
#ifdef ARM_USE_VFP
                if (tagTOS == TY_INT) {
                    o4(0xECFD6A01);  // fldmfds sp!,{s13}
                    o4(0xEEB86BE6);  // fsitod  d6, s13
                } else {
                    assert(tagTOS == TY_FLOAT);
                    o4(0xECFD6A01);  // fldmfds sp!,{s13}
                    o4(0xEEB76AE6);  // fcvtds    d6, s13
                }
#else
                o4(0xE92D0003);  // stmfd   sp!,{r0,r1}  // push r0,r1
                o4(0xE59D0008);  // ldr     r0, [sp, #8]
                if (tagTOS == TY_INT) {
                    callRuntime((void*) runtime_int_to_double);
                } else {
                    assert(tagTOS == TY_FLOAT);
                    callRuntime((void*) runtime_float_to_double);
                }
                o4(0xE1A02000);  // mov r2, r0
                o4(0xE1A03001);  // mov r3, r1
                o4(0xE8BD0003);  // ldmfd   sp!,{r0, r1}  // Restore R0
                o4(0xE28DD004);  // add sp, sp, #4 // Pop sp
#endif
                mStackUse -= 4;
            } else {
#ifdef ARM_USE_VFP
                o4(0xECBD6B02);  // fldmfdd    sp!, {d6}
#else
                o4(0xE8BD000C);  // ldmfd   sp!,{r2,r3}
#endif
                mStackUse -= 8;
            }
            popType();
        }

        void liReg(int t, int reg) {
            assert(reg >= 0 && reg < 16);
            int rN = (reg & 0xf) << 12;
            size_t encodedImmediate;
            if (encode12BitImmediate(t, &encodedImmediate)) {
                 o4(0xE3A00000 | encodedImmediate | rN); // mov    rN, #0
            } else if (encode12BitImmediate(-(t+1), &encodedImmediate)) {
                // mvn means move constant ^ ~0
                o4(0xE3E00000 | encodedImmediate | rN); // mvn    rN, #0
            } else {
                o4(0xE51F0000 | rN); //         ldr    rN, .L3
                o4(0xEA000000); //         b .L99
                o4(t);          // .L3:   .word 0
                                  // .L99:
            }
        }

        void incompatibleTypes(Type* pR0Type, Type* pType) {
            error("Incompatible types old: %d new: %d", pR0Type->tag, pType->tag);
        }

        void callRuntime(void* fn) {
            o4(0xE59FC000); // ldr    r12, .L1
            o4(0xEA000000); // b      .L99
            o4((int) fn);   //.L1:  .word  fn
            o4(0xE12FFF3C); //.L99: blx    r12
        }

        // Integer math:

        static int runtime_DIV(int b, int a) {
            return a / b;
        }

        static int runtime_MOD(int b, int a) {
            return a % b;
        }

        static void runtime_structCopy(void* src, size_t size, void* dest) {
            memcpy(dest, src, size);
        }

#ifndef ARM_USE_VFP

        // Comparison to zero

        static int runtime_is_non_zero_f(float a) {
            return a != 0;
        }

        static int runtime_is_non_zero_d(double a) {
            return a != 0;
        }

        // Comparison to zero

        static int runtime_is_zero_f(float a) {
            return a == 0;
        }

        static int runtime_is_zero_d(double a) {
            return a == 0;
        }

        // Type conversion

        static int runtime_float_to_int(float a) {
            return (int) a;
        }

        static double runtime_float_to_double(float a) {
            return (double) a;
        }

        static int runtime_double_to_int(double a) {
            return (int) a;
        }

        static float runtime_double_to_float(double a) {
            return (float) a;
        }

        static float runtime_int_to_float(int a) {
            return (float) a;
        }

        static double runtime_int_to_double(int a) {
            return (double) a;
        }

        // Comparisons float

        static int runtime_cmp_eq_ff(float b, float a) {
            return a == b;
        }

        static int runtime_cmp_ne_ff(float b, float a) {
            return a != b;
        }

        static int runtime_cmp_lt_ff(float b, float a) {
            return a < b;
        }

        static int runtime_cmp_le_ff(float b, float a) {
            return a <= b;
        }

        static int runtime_cmp_ge_ff(float b, float a) {
            return a >= b;
        }

        static int runtime_cmp_gt_ff(float b, float a) {
            return a > b;
        }

        // Comparisons double

        static int runtime_cmp_eq_dd(double b, double a) {
            return a == b;
        }

        static int runtime_cmp_ne_dd(double b, double a) {
            return a != b;
        }

        static int runtime_cmp_lt_dd(double b, double a) {
            return a < b;
        }

        static int runtime_cmp_le_dd(double b, double a) {
            return a <= b;
        }

        static int runtime_cmp_ge_dd(double b, double a) {
            return a >= b;
        }

        static int runtime_cmp_gt_dd(double b, double a) {
            return a > b;
        }

        // Math float

        static float runtime_op_add_ff(float b, float a) {
            return a + b;
        }

        static float runtime_op_sub_ff(float b, float a) {
            return a - b;
        }

        static float runtime_op_mul_ff(float b, float a) {
            return a * b;
        }

        static float runtime_op_div_ff(float b, float a) {
            return a / b;
        }

        static float runtime_op_neg_f(float a) {
            return -a;
        }

        // Math double

        static double runtime_op_add_dd(double b, double a) {
            return a + b;
        }

        static double runtime_op_sub_dd(double b, double a) {
            return a - b;
        }

        static double runtime_op_mul_dd(double b, double a) {
            return a * b;
        }

        static double runtime_op_div_dd(double b, double a) {
            return a / b;
        }

        static double runtime_op_neg_d(double a) {
            return -a;
        }

#endif

        static const int STACK_ALIGNMENT = 8;
        int mStackUse;
        // This variable holds the amount we adjusted the stack in the most
        // recent endFunctionCallArguments call. It's examined by the
        // following adjustStackAfterCall call.
        int mStackAlignmentAdjustment;
    };

#endif // PROVIDE_ARM_CODEGEN

#ifdef PROVIDE_X86_CODEGEN

    class X86CodeGenerator : public CodeGenerator {
    public:
        X86CodeGenerator() {}
        virtual ~X86CodeGenerator() {}

        /* returns address to patch with local variable size
        */
        virtual int functionEntry(Type* pDecl) {
            o(0xe58955); /* push   %ebp, mov %esp, %ebp */
            return oad(0xec81, 0); /* sub $xxx, %esp */
        }

        virtual void functionExit(Type* pDecl, int localVariableAddress, int localVariableSize) {
            o(0xc3c9); /* leave, ret */
            *(int *) localVariableAddress = localVariableSize; /* save local variables */
        }

        /* load immediate value */
        virtual void li(int i) {
            oad(0xb8, i); /* mov $xx, %eax */
            setR0Type(mkpInt);
        }

        virtual void loadFloat(int address, Type* pType) {
            setR0Type(pType);
            switch (pType->tag) {
            case TY_FLOAT:
                oad(0x05D9, address);      // flds
                break;
            case TY_DOUBLE:
                oad(0x05DD, address);      // fldl
                break;
            default:
                assert(false);
                break;
            }
        }

        virtual void addStructOffsetR0(int offset, Type* pType) {
            if (offset) {
                oad(0x05, offset); // addl offset, %eax
            }
            setR0Type(pType, ET_LVALUE);
        }

        virtual int gjmp(int t) {
            return psym(0xe9, t);
        }

        /* l = 0: je, l == 1: jne */
        virtual int gtst(bool l, int t) {
            Type* pR0Type = getR0Type();
            TypeTag tagR0 = pR0Type->tag;
            bool isFloatR0 = isFloatTag(tagR0);
            if (isFloatR0) {
                o(0xeed9); // fldz
                o(0xe9da); // fucompp
                o(0xe0df); // fnstsw %ax
                o(0x9e);   // sahf
            } else {
                o(0xc085); // test %eax, %eax
            }
            // Use two output statements to generate one instruction.
            o(0x0f);   // je/jne xxx
            return psym(0x84 + l, t);
        }

        virtual void gcmp(int op) {
            Type* pR0Type = getR0Type();
            Type* pTOSType = getTOSType();
            TypeTag tagR0 = pR0Type->tag;
            TypeTag tagTOS = pTOSType->tag;
            bool isFloatR0 = isFloatTag(tagR0);
            bool isFloatTOS = isFloatTag(tagTOS);
            if (!isFloatR0 && !isFloatTOS) {
                int t = decodeOp(op);
                o(0x59); /* pop %ecx */
                o(0xc139); /* cmp %eax,%ecx */
                li(0);
                o(0x0f); /* setxx %al */
                o(t + 0x90);
                o(0xc0);
                popType();
            } else {
                setupFloatOperands();
                switch (op) {
                    case OP_EQUALS:
                        o(0xe9da);   // fucompp
                        o(0xe0df);   // fnstsw %ax
                        o(0x9e);     // sahf
                        o(0xc0940f); // sete %al
                        o(0xc29b0f); // setnp %dl
                        o(0xd021);   // andl %edx, %eax
                        break;
                    case OP_NOT_EQUALS:
                        o(0xe9da);   // fucompp
                        o(0xe0df);   // fnstsw %ax
                        o(0x9e);     // sahf
                        o(0xc0950f); // setne %al
                        o(0xc29a0f); // setp %dl
                        o(0xd009);   // orl %edx, %eax
                        break;
                    case OP_GREATER_EQUAL:
                        o(0xe9da);   // fucompp
                        o(0xe0df);   // fnstsw %ax
                        o(0x05c4f6); // testb $5, %ah
                        o(0xc0940f); // sete %al
                        break;
                    case OP_LESS:
                        o(0xc9d9);   // fxch %st(1)
                        o(0xe9da);   // fucompp
                        o(0xe0df);   // fnstsw %ax
                        o(0x9e);     // sahf
                        o(0xc0970f); // seta %al
                        break;
                    case OP_LESS_EQUAL:
                        o(0xc9d9);   // fxch %st(1)
                        o(0xe9da);   // fucompp
                        o(0xe0df);   // fnstsw %ax
                        o(0x9e);     // sahf
                        o(0xc0930f); // setea %al
                        break;
                    case OP_GREATER:
                        o(0xe9da);   // fucompp
                        o(0xe0df);   // fnstsw %ax
                        o(0x45c4f6); // testb $69, %ah
                        o(0xc0940f); // sete %al
                        break;
                    default:
                        error("Unknown comparison op");
                }
                o(0xc0b60f); // movzbl %al, %eax
            }
            setR0Type(mkpInt);
        }

        virtual void genOp(int op) {
            Type* pR0Type = getR0Type();
            Type* pTOSType = getTOSType();
            TypeTag tagR0 = pR0Type->tag;
            TypeTag tagTOS = pTOSType->tag;
            bool isFloatR0 = isFloatTag(tagR0);
            bool isFloatTOS = isFloatTag(tagTOS);
            if (!isFloatR0 && !isFloatTOS) {
                bool isPtrR0 = isPointerTag(tagR0);
                bool isPtrTOS = isPointerTag(tagTOS);
                if (isPtrR0 || isPtrTOS) {
                    if (isPtrR0 && isPtrTOS) {
                        if (op != OP_MINUS) {
                            error("Unsupported pointer-pointer operation %d.", op);
                        }
                        if (! typeEqual(pR0Type, pTOSType)) {
                            error("Incompatible pointer types for subtraction.");
                        }
                        o(0x59); /* pop %ecx */
                        o(decodeOp(op));
                        popType();
                        setR0Type(mkpInt);
                        int size = sizeOf(pR0Type->pHead);
                        if (size != 1) {
                            pushR0();
                            li(size);
                            // TODO: Optimize for power-of-two.
                            genOp(OP_DIV);
                        }
                    } else {
                        if (! (op == OP_PLUS || (op == OP_MINUS && isPtrR0))) {
                            error("Unsupported pointer-scalar operation %d", op);
                        }
                        Type* pPtrType = getPointerArithmeticResultType(
                                pR0Type, pTOSType);
                        o(0x59); /* pop %ecx */
                        int size = sizeOf(pPtrType->pHead);
                        if (size != 1) {
                            // TODO: Optimize for power-of-two.
                            if (isPtrR0) {
                                oad(0xC969, size); // imull $size, %ecx
                            } else {
                                oad(0xC069, size); // mul $size, %eax
                            }
                        }
                        o(decodeOp(op));
                        popType();
                        setR0Type(pPtrType);
                    }
                } else {
                    o(0x59); /* pop %ecx */
                    o(decodeOp(op));
                    if (op == OP_MOD)
                        o(0x92); /* xchg %edx, %eax */
                    popType();
                }
            } else {
                Type* pResultType = tagR0 > tagTOS ? pR0Type : pTOSType;
                setupFloatOperands();
                // Both float. x87 R0 == left hand, x87 R1 == right hand
                switch (op) {
                    case OP_MUL:
                        o(0xc9de); // fmulp
                        break;
                    case OP_DIV:
                        o(0xf1de); // fdivp
                        break;
                    case OP_PLUS:
                        o(0xc1de); // faddp
                        break;
                    case OP_MINUS:
                        o(0xe1de); // fsubp
                        break;
                    default:
                        error("Unsupported binary floating operation.");
                        break;
                }
                setR0Type(pResultType);
            }
        }

        virtual void gUnaryCmp(int op) {
            if (op != OP_LOGICAL_NOT) {
                error("Unknown unary cmp %d", op);
            } else {
                Type* pR0Type = getR0Type();
                TypeTag tag = collapseType(pR0Type->tag);
                switch(tag) {
                    case TY_INT: {
                            oad(0xb9, 0); /* movl $0, %ecx */
                            int t = decodeOp(op);
                            o(0xc139); /* cmp %eax,%ecx */
                            li(0);
                            o(0x0f); /* setxx %al */
                            o(t + 0x90);
                            o(0xc0);
                        }
                        break;
                    case TY_FLOAT:
                    case TY_DOUBLE:
                        o(0xeed9);   // fldz
                        o(0xe9da);   // fucompp
                        o(0xe0df);   // fnstsw %ax
                        o(0x9e);     // sahf
                        o(0xc0950f); // setne %al
                        o(0xc29a0f); // setp %dl
                        o(0xd009);   // orl %edx, %eax
                        o(0xc0b60f); // movzbl %al, %eax
                        o(0x01f083); // xorl $1,  %eax
                        break;
                    default:
                        error("gUnaryCmp unsupported type");
                        break;
                }
            }
            setR0Type(mkpInt);
        }

        virtual void genUnaryOp(int op) {
            Type* pR0Type = getR0Type();
            TypeTag tag = collapseType(pR0Type->tag);
            switch(tag) {
                case TY_INT:
                    oad(0xb9, 0); /* movl $0, %ecx */
                    o(decodeOp(op));
                    break;
                case TY_FLOAT:
                case TY_DOUBLE:
                    switch (op) {
                        case OP_MINUS:
                            o(0xe0d9);  // fchs
                            break;
                        case OP_BIT_NOT:
                            error("Can't apply '~' operator to a float or double.");
                            break;
                        default:
                            error("Unknown unary op %d\n", op);
                            break;
                        }
                    break;
                default:
                    error("genUnaryOp unsupported type");
                    break;
            }
        }

        virtual void pushR0() {
            Type* pR0Type = getR0Type();
            TypeTag r0ct = collapseType(pR0Type->tag);
            switch(r0ct) {
                case TY_INT:
                    o(0x50); /* push %eax */
                    break;
                case TY_FLOAT:
                    o(0x50); /* push %eax */
                    o(0x241cd9); // fstps 0(%esp)
                    break;
                case TY_DOUBLE:
                    o(0x50); /* push %eax */
                    o(0x50); /* push %eax */
                    o(0x241cdd); // fstpl 0(%esp)
                    break;
                default:
                    error("pushR0 unsupported type %d", r0ct);
                    break;
            }
            pushType();
        }

        virtual void over() {
            // We know it's only used for int-ptr ops (++/--)

            Type* pR0Type = getR0Type();
            TypeTag r0ct = collapseType(pR0Type->tag);

            Type* pTOSType = getTOSType();
            TypeTag tosct = collapseType(pTOSType->tag);

            assert (r0ct == TY_INT && tosct == TY_INT);

            o(0x59); /* pop %ecx */
            o(0x50); /* push %eax */
            o(0x51); /* push %ecx */

            overType();
        }

        virtual void popR0() {
            Type* pR0Type = getR0Type();
            TypeTag r0ct = collapseType(pR0Type->tag);
            switch(r0ct) {
                case TY_INT:
                    o(0x58); /* popl %eax */
                    break;
                case TY_FLOAT:
                    o(0x2404d9); // flds (%esp)
                    o(0x58); /* popl %eax */
                    break;
                case TY_DOUBLE:
                    o(0x2404dd); // fldl (%esp)
                    o(0x58); /* popl %eax */
                    o(0x58); /* popl %eax */
                    break;
                default:
                    error("popR0 unsupported type %d", r0ct);
                    break;
            }
            popType();
        }

        virtual void storeR0ToTOS() {
            Type* pPointerType = getTOSType();
            assert(pPointerType->tag == TY_POINTER);
            Type* pTargetType = pPointerType->pHead;
            convertR0(pTargetType);
            o(0x59); /* pop %ecx */
            popType();
            switch (pTargetType->tag) {
                case TY_POINTER:
                case TY_INT:
                    o(0x0189); /* movl %eax/%al, (%ecx) */
                    break;
                case TY_SHORT:
                    o(0x018966); /* movw %ax, (%ecx) */
                    break;
                case TY_CHAR:
                    o(0x0188); /* movl %eax/%al, (%ecx) */
                    break;
                case TY_FLOAT:
                    o(0x19d9); /* fstps (%ecx) */
                    break;
                case TY_DOUBLE:
                    o(0x19dd); /* fstpl (%ecx) */
                    break;
                case TY_STRUCT:
                {
                    // TODO: use alignment information to use movsw/movsl instead of movsb
                    int size = sizeOf(pTargetType);
                    if (size > 0) {
                        o(0x9c);         // pushf
                        o(0x57);         // pushl %edi
                        o(0x56);         // pushl %esi
                        o(0xcf89);       // movl %ecx, %edi
                        o(0xc689);       // movl %eax, %esi
                        oad(0xb9, size);  // mov #size, %ecx
                        o(0xfc);         // cld
                        o(0xf3);         // rep
                        o(0xa4);         // movsb
                        o(0x5e);         // popl %esi
                        o(0x5f);         // popl %edi
                        o(0x9d);         // popf
                    }
                }
                    break;
                default:
                    error("storeR0ToTOS: unsupported type %d",
                            pTargetType->tag);
                    break;
            }
        }

        virtual void loadR0FromR0() {
            Type* pPointerType = getR0Type();
            assert(pPointerType->tag == TY_POINTER);
            Type* pNewType = pPointerType->pHead;
            TypeTag tag = pNewType->tag;
            switch (tag) {
                case TY_POINTER:
                case TY_INT:
                    o2(0x008b); /* mov (%eax), %eax */
                    break;
                case TY_SHORT:
                    o(0xbf0f); /* movswl (%eax), %eax */
                    ob(0);
                    break;
                case TY_CHAR:
                    o(0xbe0f); /* movsbl (%eax), %eax */
                    ob(0); /* add zero in code */
                    break;
                case TY_FLOAT:
                    o2(0x00d9); // flds (%eax)
                    break;
                case TY_DOUBLE:
                    o2(0x00dd); // fldl (%eax)
                    break;
                case TY_ARRAY:
                    pNewType = pNewType->pTail;
                    break;
                case TY_STRUCT:
                    break;
                default:
                    error("loadR0FromR0: unsupported type %d", tag);
                    break;
            }
            setR0Type(pNewType);
        }

        virtual void leaR0(int ea, Type* pPointerType, ExpressionType et) {
            gmov(10, ea); /* leal EA, %eax */
            setR0Type(pPointerType, et);
        }

        virtual int leaForward(int ea, Type* pPointerType) {
            oad(0xb8, ea); /* mov $xx, %eax */
            setR0Type(pPointerType);
            return getPC() - 4;
        }

        virtual void convertR0Imp(Type* pType, bool isCast){
            Type* pR0Type = getR0Type();
            if (pR0Type == NULL) {
                assert(false);
                setR0Type(pType);
                return;
            }
            if (isPointerType(pType) && isPointerType(pR0Type)) {
                Type* pA = pR0Type;
                Type* pB = pType;
                // Array decays to pointer
                if (pA->tag == TY_ARRAY && pB->tag == TY_POINTER) {
                    pA = pA->pTail;
                }
                if (! (typeEqual(pA, pB)
                        || pB->pHead->tag == TY_VOID
                        || (pA->tag == TY_POINTER && pB->tag == TY_POINTER && isCast)
                    )) {
                    error("Incompatible pointer or array types");
                }
            } else if (bitsSame(pType, pR0Type)) {
                // do nothing special
            } else if (isFloatType(pType) && isFloatType(pR0Type)) {
                // do nothing special, both held in same register on x87.
            } else {
                TypeTag r0Tag = collapseType(pR0Type->tag);
                TypeTag destTag = collapseType(pType->tag);
                if (r0Tag == TY_INT && isFloatTag(destTag)) {
                    // Convert R0 from int to float
                    o(0x50);      // push %eax
                    o(0x2404DB);  // fildl 0(%esp)
                    o(0x58);      // pop %eax
                } else if (isFloatTag(r0Tag) && destTag == TY_INT) {
                    // Convert R0 from float to int. Complicated because
                    // need to save and restore the rounding mode.
                    o(0x50);       // push %eax
                    o(0x50);       // push %eax
                    o(0x02247cD9); // fnstcw 2(%esp)
                    o(0x2444b70f); // movzwl 2(%esp), %eax
                    o(0x02);
                    o(0x0cb4);     // movb $12, %ah
                    o(0x24048966); // movw %ax, 0(%esp)
                    o(0x242cd9);   // fldcw 0(%esp)
                    o(0x04245cdb); // fistpl 4(%esp)
                    o(0x02246cd9); // fldcw  2(%esp)
                    o(0x58); // pop %eax
                    o(0x58); // pop %eax
                } else {
                    error("Incompatible types old: %d new: %d",
                          pR0Type->tag, pType->tag);
                }
            }
            setR0Type(pType);
        }

        virtual int beginFunctionCallArguments() {
            return oad(0xec81, 0); /* sub $xxx, %esp */
        }

        virtual size_t storeR0ToArg(int l, Type* pArgType) {
            convertR0(pArgType);
            Type* pR0Type = getR0Type();
            TypeTag r0ct = collapseType(pR0Type->tag);
            switch(r0ct) {
                case TY_INT:
                    oad(0x248489, l); /* movl %eax, xxx(%esp) */
                    return 4;
                case TY_FLOAT:
                    oad(0x249CD9, l); /* fstps   xxx(%esp) */
                    return 4;
                case TY_DOUBLE:
                    oad(0x249CDD, l); /* fstpl   xxx(%esp) */
                    return 8;
                default:
                    assert(false);
                    return 0;
            }
        }

        virtual void endFunctionCallArguments(Type* pDecl, int a, int l) {
            * (int*) a = l;
        }

        virtual int callForward(int symbol, Type* pFunc) {
            assert(pFunc->tag == TY_FUNC);
            setR0Type(pFunc->pHead);
            return psym(0xe8, symbol); /* call xxx */
        }

        virtual void callIndirect(int l, Type* pFunc) {
            assert(pFunc->tag == TY_FUNC);
            popType(); // Get rid of indirect fn pointer type
            setR0Type(pFunc->pHead);
            oad(0x2494ff, l); /* call *xxx(%esp) */
        }

        virtual void adjustStackAfterCall(Type* pDecl, int l, bool isIndirect) {
            assert(pDecl->tag == TY_FUNC);
            if (isIndirect) {
                l += 4;
            }
            if (l > 0) {
                oad(0xc481, l); /* add $xxx, %esp */
            }
        }

        virtual int jumpOffset() {
            return 5;
        }

        /* output a symbol and patch all calls to it */
        virtual void gsym(int t) {
            int n;
            int pc = getPC();
            while (t) {
                n = *(int *) t; /* next value */
                *(int *) t = pc - t - 4;
                t = n;
            }
        }

        /* output a symbol and patch all calls to it, using absolute address */
        virtual void resolveForward(int t) {
            int n;
            int pc = getPC();
            while (t) {
                n = *(int *) t; /* next value */
                *(int *) t = pc;
                t = n;
            }
        }

        virtual int finishCompile() {
            size_t pagesize = 4096;
            size_t base = (size_t) getBase() & ~ (pagesize - 1);
            size_t top =  ((size_t) getPC() + pagesize - 1) & ~ (pagesize - 1);
            int err = mprotect((void*) base, top - base, PROT_READ | PROT_WRITE | PROT_EXEC);
            if (err) {
               error("mprotect() failed: %d", errno);
            }
            return err;
        }

        /**
         * Alignment (in bytes) for this type of data
         */
        virtual size_t alignmentOf(Type* pType){
            switch (pType->tag) {
            case TY_CHAR:
                return 1;
            case TY_SHORT:
                return 2;
            case TY_ARRAY:
                return alignmentOf(pType->pHead);
            case TY_STRUCT:
                return pType->pHead->alignment & 0x7fffffff;
            case TY_FUNC:
                error("alignment of func not supported");
                return 1;
            default:
                return 4;
            }
        }

        /**
         * Array element alignment (in bytes) for this type of data.
         */
        virtual size_t sizeOf(Type* pType){
            switch(pType->tag) {
                case TY_INT:
                    return 4;
                case TY_SHORT:
                    return 2;
                case TY_CHAR:
                    return 1;
                case TY_FLOAT:
                    return 4;
                case TY_DOUBLE:
                    return 8;
                case TY_POINTER:
                    return 4;
                case TY_ARRAY:
                    return pType->length * sizeOf(pType->pHead);
                case TY_STRUCT:
                    return pType->pHead->length;
                default:
                    error("Unsupported type %d", pType->tag);
                    return 0;
            }
        }

    private:

        /** Output 1 to 4 bytes.
         *
         */
        void o(int n) {
            /* cannot use unsigned, so we must do a hack */
            while (n && n != -1) {
                ob(n & 0xff);
                n = n >> 8;
            }
        }

        /* Output exactly 2 bytes
         */
        void o2(int n) {
            ob(n & 0xff);
            ob(0xff & (n >> 8));
        }

        /* psym is used to put an instruction with a data field which is a
         reference to a symbol. It is in fact the same as oad ! */
        int psym(int n, int t) {
            return oad(n, t);
        }

        /* instruction + address */
        int oad(int n, int t) {
            o(n);
            int result = getPC();
            o4(t);
            return result;
        }

        static const int operatorHelper[];

        int decodeOp(int op) {
            if (op < 0 || op > OP_COUNT) {
                error("Out-of-range operator: %d\n", op);
                op = 0;
            }
            return operatorHelper[op];
        }

        void gmov(int l, int t) {
            o(l + 0x83);
            oad((t > -LOCAL && t < LOCAL) << 7 | 5, t);
        }

        void setupFloatOperands() {
            Type* pR0Type = getR0Type();
            Type* pTOSType = getTOSType();
            TypeTag tagR0 = pR0Type->tag;
            TypeTag tagTOS = pTOSType->tag;
            bool isFloatR0 = isFloatTag(tagR0);
            bool isFloatTOS = isFloatTag(tagTOS);
            if (! isFloatR0) {
                // Convert R0 from int to float
                o(0x50);      // push %eax
                o(0x2404DB);  // fildl 0(%esp)
                o(0x58);      // pop %eax
            }
            if (! isFloatTOS){
                o(0x2404DB);  // fildl 0(%esp);
                o(0x58);      // pop %eax
            } else {
                if (tagTOS == TY_FLOAT) {
                    o(0x2404d9);  // flds (%esp)
                    o(0x58);      // pop %eax
                } else {
                    o(0x2404dd);  // fldl (%esp)
                    o(0x58);      // pop %eax
                    o(0x58);      // pop %eax
                }
            }
            popType();
        }
    };

#endif // PROVIDE_X86_CODEGEN

#ifdef PROVIDE_TRACE_CODEGEN
    class TraceCodeGenerator : public CodeGenerator {
    private:
        CodeGenerator* mpBase;

    public:
        TraceCodeGenerator(CodeGenerator* pBase) {
            mpBase = pBase;
        }

        virtual ~TraceCodeGenerator() {
            delete mpBase;
        }

        virtual void init(ICodeBuf* pCodeBuf) {
            mpBase->init(pCodeBuf);
        }

        void setErrorSink(ErrorSink* pErrorSink) {
            mpBase->setErrorSink(pErrorSink);
        }

        /* returns address to patch with local variable size
        */
        virtual int functionEntry(Type* pDecl) {
            int result = mpBase->functionEntry(pDecl);
            fprintf(stderr, "functionEntry(pDecl) -> %d\n", result);
            return result;
        }

        virtual void functionExit(Type* pDecl, int localVariableAddress, int localVariableSize) {
            fprintf(stderr, "functionExit(pDecl, %d, %d)\n",
                    localVariableAddress, localVariableSize);
            mpBase->functionExit(pDecl, localVariableAddress, localVariableSize);
        }

        /* load immediate value */
        virtual void li(int t) {
            fprintf(stderr, "li(%d)\n", t);
            mpBase->li(t);
        }

        virtual void loadFloat(int address, Type* pType) {
            fprintf(stderr, "loadFloat(%d, type=%d)\n", address, pType->tag);
            mpBase->loadFloat(address, pType);
        }

        virtual void addStructOffsetR0(int offset, Type* pType) {
            fprintf(stderr, "addStructOffsetR0(%d, type=%d)\n", offset, pType->tag);
            mpBase->addStructOffsetR0(offset, pType);
        }

        virtual int gjmp(int t) {
            int result = mpBase->gjmp(t);
            fprintf(stderr, "gjmp(%d) = %d\n", t, result);
            return result;
        }

        /* l = 0: je, l == 1: jne */
        virtual int gtst(bool l, int t) {
            int result = mpBase->gtst(l, t);
            fprintf(stderr, "gtst(%d,%d) = %d\n", l, t, result);
            return result;
        }

        virtual void gcmp(int op) {
            fprintf(stderr, "gcmp(%d)\n", op);
            mpBase->gcmp(op);
        }

        virtual void genOp(int op) {
            fprintf(stderr, "genOp(%d)\n", op);
            mpBase->genOp(op);
        }


        virtual void gUnaryCmp(int op) {
            fprintf(stderr, "gUnaryCmp(%d)\n", op);
            mpBase->gUnaryCmp(op);
        }

        virtual void genUnaryOp(int op) {
            fprintf(stderr, "genUnaryOp(%d)\n", op);
            mpBase->genUnaryOp(op);
        }

        virtual void pushR0() {
            fprintf(stderr, "pushR0()\n");
            mpBase->pushR0();
        }

        virtual void over() {
            fprintf(stderr, "over()\n");
            mpBase->over();
        }

        virtual void popR0() {
            fprintf(stderr, "popR0()\n");
            mpBase->popR0();
        }

        virtual void storeR0ToTOS() {
            fprintf(stderr, "storeR0ToTOS()\n");
            mpBase->storeR0ToTOS();
        }

        virtual void loadR0FromR0() {
            fprintf(stderr, "loadR0FromR0()\n");
            mpBase->loadR0FromR0();
        }

        virtual void leaR0(int ea, Type* pPointerType, ExpressionType et) {
            fprintf(stderr, "leaR0(%d, %d, %d)\n", ea,
                    pPointerType->pHead->tag, et);
            mpBase->leaR0(ea, pPointerType, et);
        }

        virtual int leaForward(int ea, Type* pPointerType) {
            fprintf(stderr, "leaForward(%d)\n", ea);
            return mpBase->leaForward(ea, pPointerType);
        }

        virtual void convertR0Imp(Type* pType, bool isCast){
            fprintf(stderr, "convertR0(pType tag=%d, %d)\n",  pType->tag, isCast);
            mpBase->convertR0Imp(pType, isCast);
        }

        virtual int beginFunctionCallArguments() {
            int result = mpBase->beginFunctionCallArguments();
            fprintf(stderr, "beginFunctionCallArguments() = %d\n", result);
            return result;
        }

        virtual size_t storeR0ToArg(int l, Type* pArgType) {
            fprintf(stderr, "storeR0ToArg(%d, pArgType=%d)\n", l,
                    pArgType->tag);
            return mpBase->storeR0ToArg(l, pArgType);
        }

        virtual void endFunctionCallArguments(Type* pDecl, int a, int l) {
            fprintf(stderr, "endFunctionCallArguments(%d, %d)\n", a, l);
            mpBase->endFunctionCallArguments(pDecl, a, l);
        }

        virtual int callForward(int symbol, Type* pFunc) {
            int result = mpBase->callForward(symbol, pFunc);
            fprintf(stderr, "callForward(%d) = %d\n", symbol, result);
            return result;
        }

        virtual void callIndirect(int l, Type* pFunc) {
            fprintf(stderr, "callIndirect(%d returntype = %d)\n", l,
                    pFunc->pHead->tag);
            mpBase->callIndirect(l, pFunc);
        }

        virtual void adjustStackAfterCall(Type* pDecl, int l, bool isIndirect) {
            fprintf(stderr, "adjustStackAfterCall(pType, %d, %d)\n", l, isIndirect);
            mpBase->adjustStackAfterCall(pDecl, l, isIndirect);
        }

        virtual int jumpOffset() {
            return mpBase->jumpOffset();
        }

        /* output a symbol and patch all calls to it */
        virtual void gsym(int t) {
            fprintf(stderr, "gsym(%d)\n", t);
            mpBase->gsym(t);
        }

        virtual void resolveForward(int t) {
            mpBase->resolveForward(t);
        }

        virtual int finishCompile() {
            int result = mpBase->finishCompile();
            fprintf(stderr, "finishCompile() = %d\n", result);
            return result;
        }

        /**
         * Alignment (in bytes) for this type of data
         */
        virtual size_t alignmentOf(Type* pType){
            return mpBase->alignmentOf(pType);
        }

        /**
         * Array element alignment (in bytes) for this type of data.
         */
        virtual size_t sizeOf(Type* pType){
            return mpBase->sizeOf(pType);
        }

        virtual Type* getR0Type() {
            return mpBase->getR0Type();
        }

        virtual ExpressionType getR0ExpressionType() {
            return mpBase->getR0ExpressionType();
        }

        virtual void setR0ExpressionType(ExpressionType et) {
            mpBase->setR0ExpressionType(et);
        }

        virtual size_t getExpressionStackDepth() {
            return mpBase->getExpressionStackDepth();
        }

        virtual void forceR0RVal() {
            return mpBase->forceR0RVal();
        }
    };

#endif // PROVIDE_TRACE_CODEGEN

    class Arena {
    public:
        // Used to record a given allocation amount.
        // Used:
        // Mark mark = arena.mark();
        // ... lots of arena.allocate()
        // arena.free(mark);

        struct Mark {
            size_t chunk;
            size_t offset;
        };

        Arena() {
            mCurrentChunk = 0;
            Chunk start(CHUNK_SIZE);
            mData.push_back(start);
        }

        ~Arena() {
            for(size_t i = 0; i < mData.size(); i++) {
                mData[i].free();
            }
        }

        // Alloc using the standard alignment size safe for any variable
        void* alloc(size_t size) {
            return alloc(size, 8);
        }

        Mark mark(){
            Mark result;
            result.chunk = mCurrentChunk;
            result.offset = mData[mCurrentChunk].mOffset;
            return result;
        }

        void freeToMark(const Mark& mark) {
            mCurrentChunk = mark.chunk;
            mData[mCurrentChunk].mOffset = mark.offset;
        }

    private:
        // Allocate memory aligned to a given size
        // and a given power-of-two-sized alignment (e.g. 1,2,4,8,...)
        // Memory is not zero filled.

        void* alloc(size_t size, size_t alignment) {
            while (size > mData[mCurrentChunk].remainingCapacity(alignment)) {
                if (mCurrentChunk + 1 < mData.size()) {
                    mCurrentChunk++;
                } else {
                    size_t allocSize = CHUNK_SIZE;
                    if (allocSize < size + alignment - 1) {
                        allocSize = size + alignment - 1;
                    }
                    Chunk chunk(allocSize);
                    mData.push_back(chunk);
                    mCurrentChunk++;
                }
            }
            return mData[mCurrentChunk].allocate(size, alignment);
        }

        static const size_t CHUNK_SIZE = 128*1024;
        // Note: this class does not deallocate its
        // memory when it's destroyed. It depends upon
        // its parent to deallocate the memory.
        struct Chunk {
            Chunk() {
                mpData = 0;
                mSize = 0;
                mOffset = 0;
            }

            Chunk(size_t size) {
                mSize = size;
                mpData = (char*) malloc(size);
                mOffset = 0;
            }

            ~Chunk() {
                // Doesn't deallocate memory.
            }

            void* allocate(size_t size, size_t alignment) {
                size_t alignedOffset = aligned(mOffset, alignment);
                void* result = mpData + alignedOffset;
                mOffset = alignedOffset + size;
                return result;
            }

            void free() {
                if (mpData) {
                    ::free(mpData);
                    mpData = 0;
                }
            }

            size_t remainingCapacity(size_t alignment) {
                return aligned(mSize, alignment) - aligned(mOffset, alignment);
            }

            // Assume alignment is a power of two
            inline size_t aligned(size_t v, size_t alignment) {
                size_t mask = alignment-1;
                return (v + mask) & ~mask;
            }

            char* mpData;
            size_t mSize;
            size_t mOffset;
        };

        size_t mCurrentChunk;

        Vector<Chunk> mData;
    };

    struct VariableInfo;

    struct Token {
        int hash;
        size_t length;
        char* pText;
        tokenid_t id;

        // Current values for the token
        char* mpMacroDefinition;
        VariableInfo* mpVariableInfo;
        VariableInfo* mpStructInfo;
    };

    class TokenTable {
    public:
        // Don't use 0..0xff, allows characters and operators to be tokens too.

        static const int TOKEN_BASE = 0x100;
        TokenTable() {
            mpMap = hashmapCreate(128, hashFn, equalsFn);
        }

        ~TokenTable() {
            hashmapFree(mpMap);
        }

        void setArena(Arena* pArena) {
            mpArena = pArena;
        }

        // Returns a token for a given string of characters.
        tokenid_t intern(const char* pText, size_t length) {
            Token probe;
            int hash = hashmapHash((void*) pText, length);
            {
                Token probe;
                probe.hash = hash;
                probe.length = length;
                probe.pText = (char*) pText;
                Token* pValue = (Token*) hashmapGet(mpMap, &probe);
                if (pValue) {
                    return pValue->id;
                }
            }

            Token* pToken = (Token*) mpArena->alloc(sizeof(Token));
            memset(pToken, 0, sizeof(*pToken));
            pToken->hash = hash;
            pToken->length = length;
            pToken->pText = (char*) mpArena->alloc(length + 1);
            memcpy(pToken->pText, pText, length);
            pToken->pText[length] = 0;
            pToken->id = mTokens.size() + TOKEN_BASE;
            mTokens.push_back(pToken);
            hashmapPut(mpMap, pToken, pToken);
            return pToken->id;
        }

        // Return the Token for a given tokenid.
        Token& operator[](tokenid_t id) {
            return *mTokens[id - TOKEN_BASE];
        }

        inline size_t size() {
            return mTokens.size();
        }

    private:

        static int hashFn(void* pKey) {
            Token* pToken = (Token*) pKey;
            return pToken->hash;
        }

        static bool equalsFn(void* keyA, void* keyB) {
            Token* pTokenA = (Token*) keyA;
            Token* pTokenB = (Token*) keyB;
            // Don't need to compare hash values, they should always be equal
            return pTokenA->length == pTokenB->length
                && strcmp(pTokenA->pText, pTokenB->pText) == 0;
        }

        Hashmap* mpMap;
        Vector<Token*> mTokens;
        Arena* mpArena;
    };

    class InputStream {
    public:
        virtual ~InputStream() {}
        virtual int getChar() = 0;
    };

    class TextInputStream : public InputStream {
    public:
        TextInputStream(const char* text, size_t textLength)
            : pText(text), mTextLength(textLength), mPosition(0) {
        }

        virtual int getChar() {
            return mPosition < mTextLength ? pText[mPosition++] : EOF;
        }

    private:
        const char* pText;
        size_t mTextLength;
        size_t mPosition;
    };

    class String {
    public:
        String() {
            mpBase = 0;
            mUsed = 0;
            mSize = 0;
        }

        String(const char* item, int len, bool adopt) {
            if (len < 0) {
                len = strlen(item);
            }
            if (adopt) {
                mpBase = (char*) item;
                mUsed = len;
                mSize = len + 1;
            } else {
                mpBase = 0;
                mUsed = 0;
                mSize = 0;
                appendBytes(item, len);
            }
        }

        String(const String& other) {
            mpBase = 0;
            mUsed = 0;
            mSize = 0;
            appendBytes(other.getUnwrapped(), other.len());
        }

        ~String() {
            if (mpBase) {
                free(mpBase);
            }
        }

        String& operator=(const String& other) {
            clear();
            appendBytes(other.getUnwrapped(), other.len());
            return *this;
        }

        inline char* getUnwrapped() const {
            return mpBase;
        }

        void clear() {
            mUsed = 0;
            if (mSize > 0) {
                mpBase[0] = 0;
            }
        }

        void appendCStr(const char* s) {
            appendBytes(s, strlen(s));
        }

        void appendBytes(const char* s, int n) {
            memcpy(ensure(n), s, n + 1);
        }

        void append(char c) {
            * ensure(1) = c;
        }

        void append(String& other) {
            appendBytes(other.getUnwrapped(), other.len());
        }

        char* orphan() {
            char* result = mpBase;
            mpBase = 0;
            mUsed = 0;
            mSize = 0;
            return result;
        }

        void printf(const char* fmt,...) {
            va_list ap;
            va_start(ap, fmt);
            vprintf(fmt, ap);
            va_end(ap);
        }

        void vprintf(const char* fmt, va_list ap) {
            char* temp;
            int numChars = vasprintf(&temp, fmt, ap);
            memcpy(ensure(numChars), temp, numChars+1);
            free(temp);
        }

        inline size_t len() const {
            return mUsed;
        }

    private:
        char* ensure(int n) {
            size_t newUsed = mUsed + n;
            if (newUsed > mSize) {
                size_t newSize = mSize * 2 + 10;
                if (newSize < newUsed) {
                    newSize = newUsed;
                }
                mpBase = (char*) realloc(mpBase, newSize + 1);
                mSize = newSize;
            }
            mpBase[newUsed] = '\0';
            char* result = mpBase + mUsed;
            mUsed = newUsed;
            return result;
        }

        char* mpBase;
        size_t mUsed;
        size_t mSize;
    };

    void internKeywords() {
        // Note: order has to match TOK_ constants
        static const char* keywords[] = {
            "int",
            "char",
            "void",
            "if",
            "else",
            "while",
            "break",
            "return",
            "for",
            "auto",
            "case",
            "const",
            "continue",
            "default",
            "do",
            "double",
            "enum",
            "extern",
            "float",
            "goto",
            "long",
            "register",
            "short",
            "signed",
            "sizeof",
            "static",
            "struct",
            "switch",
            "typedef",
            "union",
            "unsigned",
            "volatile",
            "_Bool",
            "_Complex",
            "_Imaginary",
            "inline",
            "restrict",

            // predefined tokens that can also be symbols start here:
            "pragma",
            "define",
            "line",
            0};

        for(int i = 0; keywords[i]; i++) {
            mTokenTable.intern(keywords[i], strlen(keywords[i]));
        }
    }

    struct InputState {
        InputStream* pStream;
        int oldCh;
    };

    struct VariableInfo {
        void* pAddress;
        void* pForward; // For a forward direction, linked list of data to fix up
        tokenid_t tok;
        size_t level;
        VariableInfo* pOldDefinition;
        Type* pType;
        bool isStructTag;
    };

    class SymbolStack {
    public:
        SymbolStack() {
            mpArena = 0;
            mpTokenTable = 0;
        }

        void setArena(Arena* pArena) {
            mpArena = pArena;
        }

        void setTokenTable(TokenTable* pTokenTable) {
            mpTokenTable = pTokenTable;
        }

        void pushLevel() {
            Mark mark;
            mark.mArenaMark = mpArena->mark();
            mark.mSymbolHead = mStack.size();
            mLevelStack.push_back(mark);
        }

        void popLevel() {
            // Undo any shadowing that was done:
            Mark mark = mLevelStack.back();
            mLevelStack.pop_back();
            while (mStack.size() > mark.mSymbolHead) {
                VariableInfo* pV = mStack.back();
                mStack.pop_back();
                if (pV->isStructTag) {
                    (*mpTokenTable)[pV->tok].mpStructInfo = pV->pOldDefinition;
                } else {
                    (*mpTokenTable)[pV->tok].mpVariableInfo = pV->pOldDefinition;
                }
            }
            mpArena->freeToMark(mark.mArenaMark);
        }

        bool isDefinedAtCurrentLevel(tokenid_t tok) {
            VariableInfo* pV = (*mpTokenTable)[tok].mpVariableInfo;
            return pV && pV->level == level();
        }

        bool isStructTagDefinedAtCurrentLevel(tokenid_t tok) {
            VariableInfo* pV = (*mpTokenTable)[tok].mpStructInfo;
            return pV && pV->level == level();
        }

        VariableInfo* add(tokenid_t tok) {
            Token& token = (*mpTokenTable)[tok];
            VariableInfo* pOldV = token.mpVariableInfo;
            VariableInfo* pNewV =
                (VariableInfo*) mpArena->alloc(sizeof(VariableInfo));
            memset(pNewV, 0, sizeof(VariableInfo));
            pNewV->tok = tok;
            pNewV->level = level();
            pNewV->pOldDefinition = pOldV;
            token.mpVariableInfo = pNewV;
            mStack.push_back(pNewV);
            return pNewV;
        }

        VariableInfo* addStructTag(tokenid_t tok) {
            Token& token = (*mpTokenTable)[tok];
            VariableInfo* pOldS = token.mpStructInfo;
            VariableInfo* pNewS =
                (VariableInfo*) mpArena->alloc(sizeof(VariableInfo));
            memset(pNewS, 0, sizeof(VariableInfo));
            pNewS->tok = tok;
            pNewS->level = level();
            pNewS->isStructTag = true;
            pNewS->pOldDefinition = pOldS;
            token.mpStructInfo = pNewS;
            mStack.push_back(pNewS);
            return pNewS;
        }

        VariableInfo* add(Type* pType) {
            VariableInfo* pVI = add(pType->id);
            pVI->pType = pType;
            return pVI;
        }

        void forEach(bool (*fn)(VariableInfo*, void*), void* context) {
            for (size_t i = 0; i < mStack.size(); i++) {
                if (! fn(mStack[i], context)) {
                    break;
                }
            }
        }

    private:
        inline size_t level() {
            return mLevelStack.size();
        }

        struct Mark {
            Arena::Mark mArenaMark;
            size_t mSymbolHead;
        };

        Arena* mpArena;
        TokenTable* mpTokenTable;
        Vector<VariableInfo*> mStack;
        Vector<Mark> mLevelStack;
    };

    int ch; // Current input character, or EOF
    tokenid_t tok;      // token
    intptr_t tokc;    // token extra info
    double tokd;     // floating point constant value
    int tokl;         // token operator level
    intptr_t rsym; // return symbol
    Type* pReturnType; // type of the current function's return.
    intptr_t loc; // local variable index
    char* glo;  // global variable index
    String mTokenString;
    bool mbSuppressMacroExpansion;
    char* dptr; // Macro state: Points to macro text during macro playback.
    int dch;    // Macro state: Saves old value of ch during a macro playback.
    char* pGlobalBase;
    ACCSymbolLookupFn mpSymbolLookupFn;
    void* mpSymbolLookupContext;

    // Arena for the duration of the compile
    Arena mGlobalArena;
    // Arena for data that's only needed when compiling a single function
    Arena mLocalArena;

    Arena* mpCurrentArena;

    TokenTable mTokenTable;
    SymbolStack mGlobals;
    SymbolStack mLocals;

    SymbolStack* mpCurrentSymbolStack;

    // Prebuilt types, makes things slightly faster.
    Type* mkpInt;        // int
    Type* mkpShort;      // short
    Type* mkpChar;       // char
    Type* mkpVoid;       // void
    Type* mkpFloat;
    Type* mkpDouble;
    Type* mkpIntFn;
    Type* mkpIntPtr;
    Type* mkpCharPtr;
    Type* mkpFloatPtr;
    Type* mkpDoublePtr;
    Type* mkpPtrIntFn;

    InputStream* file;
    int mLineNumber;
    bool mbBumpLine;

    ICodeBuf* pCodeBuf;
    CodeGenerator* pGen;

    String mErrorBuf;

    String mPragmas;
    int mPragmaStringCount;
    int mCompileResult;

    static const int ALLOC_SIZE = 99999;

    static const int TOK_DUMMY = 1;
    static const int TOK_NUM = 2;
    static const int TOK_NUM_FLOAT = 3;
    static const int TOK_NUM_DOUBLE = 4;
    static const int TOK_OP_ASSIGNMENT = 5;
    static const int TOK_OP_ARROW = 6;

    // 3..255 are character and/or operators

    // Keywords start at 0x100 and increase by 1
    // Order has to match string list in "internKeywords".
    enum {
        TOK_KEYWORD = TokenTable::TOKEN_BASE,
        TOK_INT = TOK_KEYWORD,
        TOK_CHAR,
        TOK_VOID,
        TOK_IF,
        TOK_ELSE,
        TOK_WHILE,
        TOK_BREAK,
        TOK_RETURN,
        TOK_FOR,
        TOK_AUTO,
        TOK_CASE,
        TOK_CONST,
        TOK_CONTINUE,
        TOK_DEFAULT,
        TOK_DO,
        TOK_DOUBLE,
        TOK_ENUM,
        TOK_EXTERN,
        TOK_FLOAT,
        TOK_GOTO,
        TOK_LONG,
        TOK_REGISTER,
        TOK_SHORT,
        TOK_SIGNED,
        TOK_SIZEOF,
        TOK_STATIC,
        TOK_STRUCT,
        TOK_SWITCH,
        TOK_TYPEDEF,
        TOK_UNION,
        TOK_UNSIGNED,
        TOK_VOLATILE,
        TOK__BOOL,
        TOK__COMPLEX,
        TOK__IMAGINARY,
        TOK_INLINE,
        TOK_RESTRICT,

        // Symbols start after keywords

        TOK_SYMBOL,
        TOK_PRAGMA = TOK_SYMBOL,
        TOK_DEFINE,
        TOK_LINE
    };

    static const int LOCAL = 0x200;

    static const int SYM_FORWARD = 0;
    static const int SYM_DEFINE = 1;

    /* tokens in string heap */
    static const int TAG_TOK = ' ';

    static const int OP_INCREMENT = 0;
    static const int OP_DECREMENT = 1;
    static const int OP_MUL = 2;
    static const int OP_DIV = 3;
    static const int OP_MOD = 4;
    static const int OP_PLUS = 5;
    static const int OP_MINUS = 6;
    static const int OP_SHIFT_LEFT = 7;
    static const int OP_SHIFT_RIGHT = 8;
    static const int OP_LESS_EQUAL = 9;
    static const int OP_GREATER_EQUAL = 10;
    static const int OP_LESS = 11;
    static const int OP_GREATER = 12;
    static const int OP_EQUALS = 13;
    static const int OP_NOT_EQUALS = 14;
    static const int OP_LOGICAL_AND = 15;
    static const int OP_LOGICAL_OR = 16;
    static const int OP_BIT_AND = 17;
    static const int OP_BIT_XOR = 18;
    static const int OP_BIT_OR = 19;
    static const int OP_BIT_NOT = 20;
    static const int OP_LOGICAL_NOT = 21;
    static const int OP_COUNT = 22;

    /* Operators are searched from front, the two-character operators appear
     * before the single-character operators with the same first character.
     * @ is used to pad out single-character operators.
     */
    static const char* operatorChars;
    static const char operatorLevel[];

    /* Called when we detect an internal problem. Does nothing in production.
     *
     */
    void internalError() {
        * (char*) 0 = 0;
    }

    void assertImpl(bool isTrue, int line) {
        if (!isTrue) {
            LOGD("%d: assertion failed at line %s:%d.", mLineNumber, __FILE__, line);
            internalError();
        }
    }

    bool isSymbol(tokenid_t t) {
        return t >= TOK_SYMBOL &&
            ((size_t) (t-TOK_SYMBOL)) < mTokenTable.size();
    }

    bool isSymbolOrKeyword(tokenid_t t) {
        return t >= TOK_KEYWORD &&
            ((size_t) (t-TOK_KEYWORD)) < mTokenTable.size();
    }

    VariableInfo* VI(tokenid_t t) {
        assert(isSymbol(t));
        VariableInfo* pV = mTokenTable[t].mpVariableInfo;
        if (pV && pV->tok != t) {
            internalError();
        }
        return pV;
    }

    inline bool isDefined(tokenid_t t) {
        return t >= TOK_SYMBOL && VI(t) != 0;
    }

    const char* nameof(tokenid_t t) {
        assert(isSymbolOrKeyword(t));
        return mTokenTable[t].pText;
    }

    void pdef(int t) {
        mTokenString.append(t);
    }

    void inp() {
        if (dptr) {
            ch = *dptr++;
            if (ch == 0) {
                dptr = 0;
                ch = dch;
            }
        } else {
            if (mbBumpLine) {
                mLineNumber++;
                mbBumpLine = false;
            }
            ch = file->getChar();
            if (ch == '\n') {
                mbBumpLine = true;
            }
        }
#if 0
        printf("ch='%c' 0x%x\n", ch, ch);
#endif
    }

    int isid() {
        return isalnum(ch) | (ch == '_');
    }

    int decodeHex(int c) {
        if (isdigit(c)) {
            c -= '0';
        } else if (c <= 'F') {
            c = c - 'A' + 10;
        } else {
            c =c - 'a' + 10;
        }
        return c;
    }

    /* read a character constant, advances ch to after end of constant */
    int getq() {
        int val = ch;
        if (ch == '\\') {
            inp();
            if (isoctal(ch)) {
                // 1 to 3 octal characters.
                val = 0;
                for(int i = 0; i < 3; i++) {
                    if (isoctal(ch)) {
                        val = (val << 3) + ch - '0';
                        inp();
                    }
                }
                return val;
            } else if (ch == 'x' || ch == 'X') {
                // N hex chars
                inp();
                if (! isxdigit(ch)) {
                    error("'x' character escape requires at least one digit.");
                } else {
                    val = 0;
                    while (isxdigit(ch)) {
                        val = (val << 4) + decodeHex(ch);
                        inp();
                    }
                }
            } else {
                int val = ch;
                switch (ch) {
                    case 'a':
                        val = '\a';
                        break;
                    case 'b':
                        val = '\b';
                        break;
                    case 'f':
                        val = '\f';
                        break;
                    case 'n':
                        val = '\n';
                        break;
                    case 'r':
                        val = '\r';
                        break;
                    case 't':
                        val = '\t';
                        break;
                    case 'v':
                        val = '\v';
                        break;
                    case '\\':
                        val = '\\';
                        break;
                    case '\'':
                        val = '\'';
                        break;
                    case '"':
                        val = '"';
                        break;
                    case '?':
                        val = '?';
                        break;
                    default:
                        error("Undefined character escape %c", ch);
                        break;
                }
                inp();
                return val;
            }
        } else {
            inp();
        }
        return val;
    }

    static bool isoctal(int ch) {
        return ch >= '0' && ch <= '7';
    }

    bool acceptCh(int c) {
        bool result = c == ch;
        if (result) {
            pdef(ch);
            inp();
        }
        return result;
    }

    bool acceptDigitsCh() {
        bool result = false;
        while (isdigit(ch)) {
            result = true;
            pdef(ch);
            inp();
        }
        return result;
    }

    void parseFloat() {
        tok = TOK_NUM_DOUBLE;
        // mTokenString already has the integral part of the number.
        if(mTokenString.len() == 0) {
            mTokenString.append('0');
        }
        acceptCh('.');
        acceptDigitsCh();
        if (acceptCh('e') || acceptCh('E')) {
            acceptCh('-') || acceptCh('+');
            acceptDigitsCh();
        }
        if (ch == 'f' || ch == 'F') {
            tok = TOK_NUM_FLOAT;
            inp();
        } else if (ch == 'l' || ch == 'L') {
            inp();
            error("Long floating point constants not supported.");
        }
        char* pText = mTokenString.getUnwrapped();
        char* pEnd = pText + strlen(pText);
        char* pEndPtr = 0;
        errno = 0;
        if (tok == TOK_NUM_FLOAT) {
            tokd = strtof(pText, &pEndPtr);
        } else {
            tokd = strtod(pText, &pEndPtr);
        }
        if (errno || pEndPtr != pEnd) {
            error("Can't parse constant: %s", pText);
        }
        // fprintf(stderr, "float constant: %s (%d) %g\n", pText, tok, tokd);
    }

    void next() {
        int l, a;

        while (isspace(ch) | (ch == '#')) {
            if (ch == '#') {
                inp();
                next();
                if (tok == TOK_DEFINE) {
                    doDefine();
                } else if (tok == TOK_PRAGMA) {
                    doPragma();
                } else if (tok == TOK_LINE) {
                    doLine();
                } else {
                    error("Unsupported preprocessor directive \"%s\"",
                          mTokenString.getUnwrapped());
                }
            }
            inp();
        }
        tokl = 0;
        tok = ch;
        /* encode identifiers & numbers */
        if (isdigit(ch) || ch == '.') {
            // Start of a numeric constant. Could be integer, float, or
            // double, won't know until we look further.
            mTokenString.clear();
            pdef(ch);
            inp();
            if (tok == '.' && !isdigit(ch)) {
                goto done;
            }
            int base = 10;
            if (tok == '0') {
                if (ch == 'x' || ch == 'X') {
                    base = 16;
                    tok = TOK_NUM;
                    tokc = 0;
                    inp();
                    while ( isxdigit(ch) ) {
                        tokc = (tokc << 4) + decodeHex(ch);
                        inp();
                    }
                } else if (isoctal(ch)){
                    base = 8;
                    tok = TOK_NUM;
                    tokc = 0;
                    while ( isoctal(ch) ) {
                        tokc = (tokc << 3) + (ch - '0');
                        inp();
                    }
                }
            } else if (isdigit(tok)){
                acceptDigitsCh();
            }
            if (base == 10) {
                if (tok == '.' || ch == '.' || ch == 'e' || ch == 'E') {
                    parseFloat();
                } else {
                    // It's an integer constant
                    char* pText = mTokenString.getUnwrapped();
                    char* pEnd = pText + strlen(pText);
                    char* pEndPtr = 0;
                    errno = 0;
                    tokc = strtol(pText, &pEndPtr, base);
                    if (errno || pEndPtr != pEnd) {
                        error("Can't parse constant: %s %d %d", pText, base, errno);
                    }
                    tok = TOK_NUM;
                }
            }
        } else if (isid()) {
            mTokenString.clear();
            while (isid()) {
                pdef(ch);
                inp();
            }
            tok = mTokenTable.intern(mTokenString.getUnwrapped(), mTokenString.len());
            if (! mbSuppressMacroExpansion) {
                // Is this a macro?
                char* pMacroDefinition = mTokenTable[tok].mpMacroDefinition;
                if (pMacroDefinition) {
                    // Yes, it is a macro
                    dptr = pMacroDefinition;
                    dch = ch;
                    inp();
                    next();
                }
            }
        } else {
            inp();
            if (tok == '\'') {
                tok = TOK_NUM;
                tokc = getq();
                if (ch != '\'') {
                    error("Expected a ' character, got %c", ch);
                } else {
                  inp();
                }
            } else if ((tok == '/') & (ch == '*')) {
                inp();
                while (ch && ch != EOF) {
                    while (ch != '*' && ch != EOF)
                        inp();
                    inp();
                    if (ch == '/')
                        ch = 0;
                }
                if (ch == EOF) {
                    error("End of file inside comment.");
                }
                inp();
                next();
            } else if ((tok == '/') & (ch == '/')) {
                inp();
                while (ch && (ch != '\n') && (ch != EOF)) {
                    inp();
                }
                inp();
                next();
            } else if ((tok == '-') & (ch == '>')) {
                inp();
                tok = TOK_OP_ARROW;
            } else {
                const char* t = operatorChars;
                int opIndex = 0;
                while ((l = *t++) != 0) {
                    a = *t++;
                    tokl = operatorLevel[opIndex];
                    tokc = opIndex;
                    if ((l == tok) & ((a == ch) | (a == '@'))) {
#if 0
                        printf("%c%c -> tokl=%d tokc=0x%x\n",
                                l, a, tokl, tokc);
#endif
                        if (a == ch) {
                            inp();
                            tok = TOK_DUMMY; /* dummy token for double tokens */
                        }
                        /* check for op=, valid for * / % + - << >> & ^ | */
                        if (ch == '=' &&
                                ((tokl >= 1 && tokl <= 3)
                                        || (tokl >=6 && tokl <= 8)) ) {
                            inp();
                            tok = TOK_OP_ASSIGNMENT;
                        }
                        break;
                    }
                    opIndex++;
                }
                if (l == 0) {
                    tokl = 0;
                    tokc = 0;
                }
            }
        }

    done: ;
#if 0
        {
            String buf;
            decodeToken(buf, tok, true);
            fprintf(stderr, "%s\n", buf.getUnwrapped());
        }
#endif
    }

    void doDefine() {
        mbSuppressMacroExpansion = true;
        next();
        mbSuppressMacroExpansion = false;
        tokenid_t name = tok;
        String* pName = new String();
        if (ch == '(') {
            delete pName;
            error("Defines with arguments not supported");
            return;
        }
        while (isspace(ch)) {
            inp();
        }
        String value;
        bool appendToValue = true;
        while (ch != '\n' && ch != EOF) {
            // Check for '//' comments.
            if (appendToValue && ch == '/') {
                inp();
                if (ch == '/') {
                    appendToValue = false;
                } else {
                    value.append('/');
                }
            }
            if (appendToValue && ch != EOF) {
                value.append(ch);
            }
            inp();
        }
        char* pDefn = (char*)mGlobalArena.alloc(value.len() + 1);
        memcpy(pDefn, value.getUnwrapped(), value.len());
        pDefn[value.len()] = 0;
        mTokenTable[name].mpMacroDefinition = pDefn;
    }

    void doPragma() {
        // # pragma name(val)
        int state = 0;
        while(ch != EOF && ch != '\n' && state < 10) {
            switch(state) {
                case 0:
                    if (isspace(ch)) {
                        inp();
                    } else {
                        state++;
                    }
                    break;
                case 1:
                    if (isalnum(ch)) {
                        mPragmas.append(ch);
                        inp();
                    } else if (ch == '(') {
                        mPragmas.append(0);
                        inp();
                        state++;
                    } else {
                        state = 11;
                    }
                    break;
                case 2:
                    if (isalnum(ch)) {
                        mPragmas.append(ch);
                        inp();
                    } else if (ch == ')') {
                        mPragmas.append(0);
                        inp();
                        state = 10;
                    } else {
                        state = 11;
                    }
                    break;
            }
        }
        if(state != 10) {
            error("Unexpected pragma syntax");
        }
        mPragmaStringCount += 2;
    }

    void doLine() {
        // # line number { "filename "}
        next();
        if (tok != TOK_NUM) {
            error("Expected a line-number");
        } else {
            mLineNumber = tokc-1; // The end-of-line will increment it.
        }
        while(ch != EOF && ch != '\n') {
            inp();
        }
    }

    virtual void verror(const char* fmt, va_list ap) {
        mErrorBuf.printf("%ld: ", mLineNumber);
        mErrorBuf.vprintf(fmt, ap);
        mErrorBuf.printf("\n");
    }

    void skip(intptr_t c) {
        if (!accept(c)) {
            error("'%c' expected", c);
        }
    }

    bool accept(intptr_t c) {
        if (tok == c) {
            next();
            return true;
        }
        return false;
    }

    bool acceptStringLiteral() {
        if (tok == '"') {
            pGen->leaR0((int) glo, mkpCharPtr, ET_RVALUE);
            // This while loop merges multiple adjacent string constants.
            while (tok == '"') {
                while (ch != '"' && ch != EOF) {
                    *allocGlobalSpace(1,1) = getq();
                }
                if (ch != '"') {
                    error("Unterminated string constant.");
                }
                inp();
                next();
            }
            /* Null terminate */
            *glo = 0;
            /* align heap */
            allocGlobalSpace(1,(char*) (((intptr_t) glo + 4) & -4) - glo);

            return true;
        }
        return false;
    }

    void linkGlobal(tokenid_t t, bool isFunction) {
        VariableInfo* pVI = VI(t);
        void* n = NULL;
        if (mpSymbolLookupFn) {
            n = mpSymbolLookupFn(mpSymbolLookupContext, nameof(t));
        }
        if (pVI->pType == NULL) {
            if (isFunction) {
                pVI->pType = mkpIntFn;
            } else {
                pVI->pType = mkpInt;
            }
        }
        pVI->pAddress = n;
    }

    void unaryOrAssignment() {
        unary();
        if (accept('=')) {
            checkLVal();
            pGen->pushR0();
            expr();
            pGen->forceR0RVal();
            pGen->storeR0ToTOS();
        } else if (tok == TOK_OP_ASSIGNMENT) {
            int t = tokc;
            next();
            checkLVal();
            pGen->pushR0();
            pGen->forceR0RVal();
            pGen->pushR0();
            expr();
            pGen->forceR0RVal();
            pGen->genOp(t);
            pGen->storeR0ToTOS();
        }
    }

    /* Parse and evaluate a unary expression.
     */
    void unary() {
        tokenid_t t;
        intptr_t a;
        t = 0;
        if (acceptStringLiteral()) {
            // Nothing else to do.
        } else {
            int c = tokl;
            a = tokc;
            double ad = tokd;
            t = tok;
            next();
            if (t == TOK_NUM) {
                pGen->li(a);
            } else if (t == TOK_NUM_FLOAT) {
                // Align to 4-byte boundary
                glo = (char*) (((intptr_t) glo + 3) & -4);
                * (float*) glo = (float) ad;
                pGen->loadFloat((int) glo, mkpFloat);
                glo += 4;
            } else if (t == TOK_NUM_DOUBLE) {
                // Align to 8-byte boundary
                glo = (char*) (((intptr_t) glo + 7) & -8);
                * (double*) glo = ad;
                pGen->loadFloat((int) glo, mkpDouble);
                glo += 8;
            } else if (c == 2) {
                /* -, +, !, ~ */
                unary();
                pGen->forceR0RVal();
                if (t == '!')
                    pGen->gUnaryCmp(a);
                else if (t == '+') {
                    // ignore unary plus.
                } else {
                    pGen->genUnaryOp(a);
                }
            } else if (c == 11) {
                // pre increment / pre decrement
                unary();
                doIncDec(a == OP_INCREMENT, 0);
            }
            else if (t == '(') {
                // It's either a cast or an expression
                Type* pCast = acceptCastTypeDeclaration();
                if (pCast) {
                    skip(')');
                    unary();
                    pGen->forceR0RVal();
                    pGen->castR0(pCast);
                } else {
                    commaExpr();
                    skip(')');
                }
            } else if (t == '*') {
                /* This is a pointer dereference.
                 */
                unary();
                doPointer();
            } else if (t == '&') {
                unary();
                doAddressOf();
            } else if (t == EOF ) {
                error("Unexpected EOF.");
            } else if (t == ';') {
                error("Unexpected ';'");
            } else if (!checkSymbol(t)) {
                // Don't have to do anything special here, the error
                // message was printed by checkSymbol() above.
            } else {
                if (!isDefined(t)) {
                    mGlobals.add(t);
                    // printf("Adding new global function %s\n", nameof(t));
                }
                VariableInfo* pVI = VI(t);
                int n = (intptr_t) pVI->pAddress;
                /* forward reference: try our lookup function */
                if (!n) {
                    linkGlobal(t, tok == '(');
                    n = (intptr_t) pVI->pAddress;
                    if (!n && tok != '(') {
                        error("Undeclared variable %s", nameof(t));
                    }
                }
                if (tok != '(') {
                    /* variable or function name */
                    if (!n) {
                        linkGlobal(t, false);
                        n = (intptr_t) pVI->pAddress;
                        if (!n) {
                            error("Undeclared variable %s", nameof(t));
                        }
                    }
                }
                // load a variable
                Type* pVal;
                ExpressionType et;
                if (pVI->pType->tag == TY_ARRAY) {
                    pVal = pVI->pType;
                    et = ET_RVALUE;
                } else {
                    pVal = createPtrType(pVI->pType);
                    et = ET_LVALUE;
                }
                if (n) {
                    int tag = pVal->pHead->tag;
                    if (tag == TY_FUNC) {
                        et = ET_RVALUE;
                    }
                    pGen->leaR0(n, pVal, et);
                } else {
                    pVI->pForward = (void*) pGen->leaForward(
                            (int) pVI->pForward, pVal);
                }
            }
        }

        /* Now handle postfix operators */
        for(;;) {
            if (tokl == 11) {
                // post inc / post dec
                doIncDec(tokc == OP_INCREMENT, true);
                next();
            } else if (accept('[')) {
                // Array reference
                pGen->forceR0RVal();
                pGen->pushR0();
                commaExpr();
                pGen->forceR0RVal();
                pGen->genOp(OP_PLUS);
                doPointer();
                skip(']');
            } else if (accept('.')) {
                // struct element
                pGen->forceR0RVal();
                Type* pStruct = pGen->getR0Type();
                if (pStruct->tag == TY_STRUCT) {
                    doStructMember(pStruct, true);
                } else {
                    error("expected a struct value to the left of '.'");
                }
            } else if (accept(TOK_OP_ARROW)) {
                pGen->forceR0RVal();
                Type* pPtr = pGen->getR0Type();
                if (pPtr->tag == TY_POINTER && pPtr->pHead->tag == TY_STRUCT) {
                    pGen->loadR0FromR0();
                    doStructMember(pPtr->pHead, false);
                } else {
                    error("Expected a pointer to a struct to the left of '->'");
                }
            } else  if (accept('(')) {
                /* function call */
                Type* pDecl = NULL;
                VariableInfo* pVI = NULL;
                Type* pFn = pGen->getR0Type();
                assert(pFn->tag == TY_POINTER);
                assert(pFn->pHead->tag == TY_FUNC);
                pDecl = pFn->pHead;
                pGen->pushR0();
                Type* pArgList = pDecl->pTail;
                bool varArgs = pArgList == NULL;
                /* push args and invert order */
                a = pGen->beginFunctionCallArguments();
                int l = 0;
                int argCount = 0;
                while (tok != ')' && tok != EOF) {
                    if (! varArgs && !pArgList) {
                        error("Unexpected argument.");
                    }
                    expr();
                    pGen->forceR0RVal();
                    Type* pTargetType;
                    if (pArgList) {
                        pTargetType = pArgList->pHead;
                        pArgList = pArgList->pTail;
                    } else {
                        // This is a ... function, just pass arguments in their
                        // natural type.
                        pTargetType = pGen->getR0Type();
                        if (pTargetType->tag == TY_FLOAT) {
                            pTargetType = mkpDouble;
                        } else if (pTargetType->tag == TY_ARRAY) {
                            // Pass arrays by pointer.
                            pTargetType = pTargetType->pTail;
                        }
                    }
                    if (pTargetType->tag == TY_VOID) {
                        error("Can't pass void value for argument %d",
                              argCount + 1);
                    } else {
                        l += pGen->storeR0ToArg(l, pTargetType);
                    }
                    if (accept(',')) {
                        // fine
                    } else if ( tok != ')') {
                        error("Expected ',' or ')'");
                    }
                    argCount += 1;
                }
                if (! varArgs && pArgList) {
                    error("Expected more argument(s). Saw %d", argCount);
                }
                pGen->endFunctionCallArguments(pDecl, a, l);
                skip(')');
                pGen->callIndirect(l, pDecl);
                pGen->adjustStackAfterCall(pDecl, l, true);
            } else {
                break;
            }
        }
    }

    void doStructMember(Type* pStruct, bool isDot) {
        Type* pStructElement = lookupStructMember(pStruct, tok);
        if (pStructElement) {
            next();
            pGen->addStructOffsetR0(pStructElement->length, createPtrType(pStructElement->pHead));
        } else {
            String buf;
            decodeToken(buf, tok, true);
            error("Expected a struct member to the right of '%s', got %s",
                    isDot ? "." : "->", buf.getUnwrapped());
        }
    }

    void doIncDec(int isInc, int isPost) {
        // R0 already has the lval
        checkLVal();
        int lit = isInc ? 1 : -1;
        pGen->pushR0();
        pGen->loadR0FromR0();
        int tag = pGen->getR0Type()->tag;
        if (!(tag == TY_INT || tag == TY_SHORT || tag == TY_CHAR ||
                tag == TY_POINTER)) {
            error("++/-- illegal for this type. %d", tag);
        }
        if (isPost) {
            pGen->over();
            pGen->pushR0();
            pGen->li(lit);
            pGen->genOp(OP_PLUS);
            pGen->storeR0ToTOS();
            pGen->popR0();
        } else {
            pGen->pushR0();
            pGen->li(lit);
            pGen->genOp(OP_PLUS);
            pGen->over();
            pGen->storeR0ToTOS();
            pGen->popR0();
        }
    }

    void doPointer() {
        pGen->forceR0RVal();
        Type* pR0Type = pGen->getR0Type();
        if (pR0Type->tag != TY_POINTER) {
            error("Expected a pointer type.");
        } else {
            if (pR0Type->pHead->tag != TY_FUNC) {
                pGen->setR0ExpressionType(ET_LVALUE);
            }
        }
    }

    void doAddressOf() {
        Type* pR0 = pGen->getR0Type();
        bool isFuncPtr = pR0->tag == TY_POINTER && pR0->pHead->tag == TY_FUNC;
        if ((! isFuncPtr) && pGen->getR0ExpressionType() != ET_LVALUE) {
            error("Expected an lvalue");
        }
        Type* pR0Type = pGen->getR0Type();
        pGen->setR0ExpressionType(ET_RVALUE);
    }

    /* Recursive descent parser for binary operations.
     */
    void binaryOp(int level) {
        intptr_t t, a;
        t = 0;
        if (level-- == 1)
            unaryOrAssignment();
        else {
            binaryOp(level);
            a = 0;
            while (level == tokl) {
                t = tokc;
                next();
                pGen->forceR0RVal();
                if (level > 8) {
                    a = pGen->gtst(t == OP_LOGICAL_OR, a); /* && and || output code generation */
                    binaryOp(level);
                } else {
                    pGen->pushR0();
                    binaryOp(level);
                    // Check for syntax error.
                    if (pGen->getR0Type() == NULL) {
                        // We failed to parse a right-hand argument.
                        // Push a dummy value so we don't fail
                        pGen->li(0);
                    }
                    pGen->forceR0RVal();
                    if ((level == 4) | (level == 5)) {
                        pGen->gcmp(t);
                    } else {
                        pGen->genOp(t);
                    }
                }
            }
            /* && and || output code generation */
            if (a && level > 8) {
                pGen->forceR0RVal();
                a = pGen->gtst(t == OP_LOGICAL_OR, a);
                pGen->li(t != OP_LOGICAL_OR);
                int b = pGen->gjmp(0);
                pGen->gsym(a);
                pGen->li(t == OP_LOGICAL_OR);
                pGen->gsym(b);
            }
        }
    }

    void commaExpr() {
        for(;;) {
            expr();
            if (!accept(',')) {
                break;
            }
        }
    }

    void expr() {
        binaryOp(11);
    }

    int test_expr() {
        commaExpr();
        pGen->forceR0RVal();
        return pGen->gtst(0, 0);
    }

    void block(intptr_t l, bool outermostFunctionBlock) {
        intptr_t a, n, t;

        Type* pBaseType;
        if ((pBaseType = acceptPrimitiveType())) {
            /* declarations */
            localDeclarations(pBaseType);
        } else if (tok == TOK_IF) {
            next();
            skip('(');
            a = test_expr();
            skip(')');
            block(l, false);
            if (tok == TOK_ELSE) {
                next();
                n = pGen->gjmp(0); /* jmp */
                pGen->gsym(a);
                block(l, false);
                pGen->gsym(n); /* patch else jmp */
            } else {
                pGen->gsym(a); /* patch if test */
            }
        } else if ((tok == TOK_WHILE) | (tok == TOK_FOR)) {
            t = tok;
            next();
            skip('(');
            if (t == TOK_WHILE) {
                n = pCodeBuf->getPC(); // top of loop, target of "next" iteration
                a = test_expr();
            } else {
                if (tok != ';')
                    commaExpr();
                skip(';');
                n = pCodeBuf->getPC();
                a = 0;
                if (tok != ';')
                    a = test_expr();
                skip(';');
                if (tok != ')') {
                    t = pGen->gjmp(0);
                    commaExpr();
                    pGen->gjmp(n - pCodeBuf->getPC() - pGen->jumpOffset());
                    pGen->gsym(t);
                    n = t + 4;
                }
            }
            skip(')');
            block((intptr_t) &a, false);
            pGen->gjmp(n - pCodeBuf->getPC() - pGen->jumpOffset()); /* jmp */
            pGen->gsym(a);
        } else if (tok == '{') {
            if (! outermostFunctionBlock) {
                mLocals.pushLevel();
            }
            next();
            while (tok != '}' && tok != EOF)
                block(l, false);
            skip('}');
            if (! outermostFunctionBlock) {
                mLocals.popLevel();
            }
        } else {
            if (accept(TOK_RETURN)) {
                if (tok != ';') {
                    commaExpr();
                    pGen->forceR0RVal();
                    if (pReturnType->tag == TY_VOID) {
                        error("Must not return a value from a void function");
                    } else {
                        pGen->convertR0(pReturnType);
                    }
                } else {
                    if (pReturnType->tag != TY_VOID) {
                        error("Must specify a value here");
                    }
                }
                rsym = pGen->gjmp(rsym); /* jmp */
            } else if (accept(TOK_BREAK)) {
                *(int *) l = pGen->gjmp(*(int *) l);
            } else if (tok != ';')
                commaExpr();
            skip(';');
        }
    }

    static bool typeEqual(Type* a, Type* b) {
        if (a == b) {
            return true;
        }
        if (a == NULL || b == NULL) {
            return false;
        }
        TypeTag at = a->tag;
        if (at != b->tag) {
            return false;
        }
        if (at == TY_POINTER) {
            return typeEqual(a->pHead, b->pHead);
        } else if (at == TY_ARRAY) {
            return a->length == b->length && typeEqual(a->pHead, b->pHead);
        } else if (at == TY_FUNC || at == TY_PARAM) {
            return typeEqual(a->pHead, b->pHead)
                && typeEqual(a->pTail, b->pTail);
        } else if (at == TY_STRUCT) {
            return a->pHead == b->pHead;
        }
        return true;
    }

    Type* createType(TypeTag tag, Type* pHead, Type* pTail) {
        assert(tag >= TY_INT && tag <= TY_PARAM);
        Type* pType = (Type*) mpCurrentArena->alloc(sizeof(Type));
        memset(pType, 0, sizeof(*pType));
        pType->tag = tag;
        pType->pHead = pHead;
        pType->pTail = pTail;
        return pType;
    }

    Type* createPtrType(Type* pType) {
        return createType(TY_POINTER, pType, NULL);
    }

    /**
     * Try to print a type in declaration order
     */
    void decodeType(String& buffer, Type* pType) {
        buffer.clear();
        if (pType == NULL) {
            buffer.appendCStr("null");
            return;
        }
        decodeTypeImp(buffer, pType);
    }

    void decodeTypeImp(String& buffer, Type* pType) {
        decodeTypeImpPrefix(buffer, pType);
        decodeId(buffer, pType->id);
        decodeTypeImpPostfix(buffer, pType);
    }

    void decodeId(String& buffer, tokenid_t id) {
        if (id) {
            String temp;
            decodeToken(temp, id, false);
            buffer.append(temp);
        }
    }

    void decodeTypeImpPrefix(String& buffer, Type* pType) {
        TypeTag tag = pType->tag;

        if ((tag >= TY_INT && tag <= TY_DOUBLE) || tag == TY_STRUCT) {
            switch (tag) {
                case TY_INT:
                    buffer.appendCStr("int");
                    break;
                case TY_SHORT:
                    buffer.appendCStr("short");
                    break;
                case TY_CHAR:
                    buffer.appendCStr("char");
                    break;
                case TY_VOID:
                    buffer.appendCStr("void");
                    break;
                case TY_FLOAT:
                    buffer.appendCStr("float");
                    break;
                case TY_DOUBLE:
                    buffer.appendCStr("double");
                    break;
                case TY_STRUCT:
                {
                    bool isStruct = (pType->pHead->alignment & 0x80000000) != 0;
                    buffer.appendCStr(isStruct ? "struct" : "union");
                    if (pType->pHead && pType->pHead->structTag) {
                        buffer.append(' ');
                        decodeId(buffer, pType->pHead->structTag);
                    }
                }
                    break;
                default:
                    break;
            }
            buffer.append(' ');
        }

        switch (tag) {
            case TY_INT:
                break;
            case TY_SHORT:
                break;
            case TY_CHAR:
                break;
            case TY_VOID:
                 break;
            case TY_FLOAT:
                 break;
            case TY_DOUBLE:
                break;
            case TY_POINTER:
                decodeTypeImpPrefix(buffer, pType->pHead);
                if(pType->pHead && pType->pHead->tag == TY_FUNC) {
                    buffer.append('(');
                }
                buffer.append('*');
                break;
            case TY_ARRAY:
                decodeTypeImpPrefix(buffer, pType->pHead);
                break;
            case TY_STRUCT:
                break;
            case TY_FUNC:
                decodeTypeImp(buffer, pType->pHead);
                break;
            case TY_PARAM:
                decodeTypeImp(buffer, pType->pHead);
                break;
            default:
                String temp;
                temp.printf("Unknown tag %d", pType->tag);
                buffer.append(temp);
                break;
        }
    }

    void decodeTypeImpPostfix(String& buffer, Type* pType) {
        TypeTag tag = pType->tag;

        switch(tag) {
            case TY_POINTER:
                if(pType->pHead && pType->pHead->tag == TY_FUNC) {
                    buffer.append(')');
                }
                decodeTypeImpPostfix(buffer, pType->pHead);
                break;
            case TY_ARRAY:
                {
                    String temp;
                    temp.printf("[%d]", pType->length);
                    buffer.append(temp);
                }
                break;
            case TY_STRUCT:
                if (pType->pHead->length >= 0) {
                    buffer.appendCStr(" {");
                    for(Type* pArg = pType->pTail; pArg; pArg = pArg->pTail) {
                        decodeTypeImp(buffer, pArg->pHead);
                        buffer.appendCStr(";");
                    }
                    buffer.append('}');
                }
                break;
            case TY_FUNC:
                buffer.append('(');
                for(Type* pArg = pType->pTail; pArg; pArg = pArg->pTail) {
                    decodeTypeImp(buffer, pArg);
                    if (pArg->pTail) {
                        buffer.appendCStr(", ");
                    }
                }
                buffer.append(')');
                break;
            default:
                break;
        }
    }

    void printType(Type* pType) {
        String buffer;
        decodeType(buffer, pType);
        fprintf(stderr, "%s\n", buffer.getUnwrapped());
    }

    Type* acceptPrimitiveType() {
        Type* pType;
        if (tok == TOK_INT) {
            pType = mkpInt;
        } else if (tok == TOK_SHORT) {
            pType = mkpShort;
        } else if (tok == TOK_CHAR) {
            pType = mkpChar;
        } else if (tok == TOK_VOID) {
            pType = mkpVoid;
        } else if (tok == TOK_FLOAT) {
            pType = mkpFloat;
        } else if (tok == TOK_DOUBLE) {
            pType = mkpDouble;
        } else if (tok == TOK_STRUCT || tok == TOK_UNION) {
            return acceptStruct();
        } else {
            return NULL;
        }
        next();
        return pType;
    }

    Type* acceptStruct() {
        assert(tok == TOK_STRUCT || tok == TOK_UNION);
        bool isStruct = tok == TOK_STRUCT;
        next();
        tokenid_t structTag = acceptSymbol();
        bool isDeclaration = accept('{');
        bool fail = false;

        Type* pStructType = createType(TY_STRUCT, NULL, NULL);
        if (structTag) {
            Token* pToken = &mTokenTable[structTag];
            VariableInfo* pStructInfo = pToken->mpStructInfo;
            bool needToDeclare = !pStructInfo;
            if (pStructInfo) {
                if (isDeclaration) {
                    if (mpCurrentSymbolStack->isStructTagDefinedAtCurrentLevel(structTag)) {
                        if (pStructInfo->pType->pHead->length == -1) {
                            // we're filling in a forward declaration.
                            needToDeclare = false;
                        } else {
                            error("A struct with the same name is already defined at this level.");
                            fail = true;
                        }
                    } else {
                        needToDeclare = true;
                    }
                }
                if (!fail) {
                     assert(pStructInfo->isStructTag);
                     pStructType->pHead = pStructInfo->pType;
                     pStructType->pTail = pStructType->pHead->pTail;
                }
            }

            if (needToDeclare) {
                // This is a new struct name
                pToken->mpStructInfo = mpCurrentSymbolStack->addStructTag(structTag);
                pStructType = createType(TY_STRUCT, NULL, NULL);
                pStructType->structTag = structTag;
                pStructType->pHead = pStructType;
                if (! isDeclaration) {
                    // A forward declaration
                    pStructType->length = -1;
                }
                pToken->mpStructInfo->pType = pStructType;
            }
        } else {
            // An anonymous struct
            pStructType->pHead = pStructType;
        }

        if (isDeclaration) {
            size_t offset = 0;
            size_t structSize = 0;
            size_t structAlignment = 0;
            Type** pParamHolder = & pStructType->pHead->pTail;
            while (tok != '}' && tok != EOF) {
                Type* pPrimitiveType = expectPrimitiveType();
                if (pPrimitiveType) {
                    while (tok != ';' && tok != EOF) {
                        Type* pItem = acceptDeclaration(pPrimitiveType, true, false);
                        if (!pItem) {
                            break;
                        }
                        if (lookupStructMember(pStructType, pItem->id)) {
                            String buf;
                            decodeToken(buf, pItem->id, false);
                            error("Duplicate struct member %s", buf.getUnwrapped());
                        }
                        Type* pStructElement = createType(TY_PARAM, pItem, NULL);
                        size_t alignment = pGen->alignmentOf(pItem);
                        if (alignment > structAlignment) {
                            structAlignment = alignment;
                        }
                        size_t alignmentMask = alignment - 1;
                        offset = (offset + alignmentMask) & ~alignmentMask;
                        pStructElement->length = offset;
                        size_t size = pGen->sizeOf(pItem);
                        if (isStruct) {
                            offset += size;
                            structSize = offset;
                        } else {
                            if (size >= structSize) {
                                structSize = size;
                            }
                        }
                        *pParamHolder = pStructElement;
                        pParamHolder = &pStructElement->pTail;
                        accept(',');
                    }
                    skip(';');
                } else {
                    // Some sort of syntax error, skip token and keep trying
                    next();
                }
            }
            if (!fail) {
                pStructType->pHead->length = structSize;
                pStructType->pHead->alignment = structAlignment | (isStruct << 31);
            }
            skip('}');
        }
        if (fail) {
            pStructType = NULL;
        }
        return pStructType;
    }

    Type* lookupStructMember(Type* pStruct, tokenid_t memberId) {
        for(Type* pStructElement = pStruct->pHead->pTail; pStructElement; pStructElement = pStructElement->pTail) {
            if (pStructElement->pHead->id == memberId) {
                return pStructElement;
            }
        }
        return NULL;
    }

    Type* acceptDeclaration(Type* pType, bool nameAllowed, bool nameRequired) {
        tokenid_t declName = 0;
        bool reportFailure = false;
        pType = acceptDecl2(pType, declName, nameAllowed,
                                  nameRequired, reportFailure);
        if (declName) {
            // Clone the parent type so we can set a unique ID
            Type* pOldType = pType;
            pType = createType(pType->tag, pType->pHead, pType->pTail);
            *pType = *pOldType;
            pType->id = declName;
        } else if (nameRequired) {
            error("Expected a variable name");
        }
#if 0
        fprintf(stderr, "Parsed a declaration:       ");
        printType(pType);
#endif
        if (reportFailure) {
            return NULL;
        }
        return pType;
    }

    Type* expectDeclaration(Type* pBaseType) {
        bool nameRequired = pBaseType->tag != TY_STRUCT;
        Type* pType = acceptDeclaration(pBaseType, true, nameRequired);
        if (! pType) {
            error("Expected a declaration");
        }
        return pType;
    }

    /* Used for accepting types that appear in casts */
    Type* acceptCastTypeDeclaration() {
        Type* pType = acceptPrimitiveType();
        if (pType) {
            pType = acceptDeclaration(pType, false, false);
        }
        return pType;
    }

    Type* expectCastTypeDeclaration() {
        Type* pType = acceptCastTypeDeclaration();
        if (! pType) {
            error("Expected a declaration");
        }
        return pType;
    }

    Type* acceptDecl2(Type* pType, tokenid_t& declName,
                      bool nameAllowed, bool nameRequired,
                      bool& reportFailure) {
        while (accept('*')) {
            pType = createType(TY_POINTER, pType, NULL);
        }
        pType = acceptDecl3(pType, declName, nameAllowed, nameRequired,
                            reportFailure);
        return pType;
    }

    Type* acceptDecl3(Type* pType, tokenid_t& declName,
                      bool nameAllowed, bool nameRequired,
                      bool& reportFailure) {
        // direct-dcl :
        //   name
        //  (dcl)
        //   direct-dcl()
        //   direct-dcl[]
        Type* pNewHead = NULL;
        if (accept('(')) {
            pNewHead = acceptDecl2(pNewHead, declName, nameAllowed,
                                nameRequired, reportFailure);
            skip(')');
        } else if ((declName = acceptSymbol()) != 0) {
            if (nameAllowed == false && declName) {
                error("Symbol %s not allowed here", nameof(declName));
                reportFailure = true;
            }
        } else if (nameRequired && ! declName) {
            String temp;
            decodeToken(temp, tok, true);
            error("Expected name. Got %s", temp.getUnwrapped());
            reportFailure = true;
        }
        for(;;) {
            if (accept('(')) {
                // Function declaration
                Type* pTail = acceptArgs(nameAllowed);
                pType = createType(TY_FUNC, pType, pTail);
                skip(')');
            } if (accept('[')) {
                if (tok != ']') {
                    if (tok != TOK_NUM || tokc <= 0) {
                        error("Expected positive integer constant");
                    } else {
                        Type* pDecayType = createPtrType(pType);
                        pType = createType(TY_ARRAY, pType, pDecayType);
                        pType->length = tokc;
                    }
                    next();
                }
                skip(']');
            } else {
                break;
            }
        }

        if (pNewHead) {
            Type* pA = pNewHead;
            while (pA->pHead) {
                pA = pA->pHead;
            }
            pA->pHead = pType;
            pType = pNewHead;
        }
        return pType;
    }

    Type* acceptArgs(bool nameAllowed) {
        Type* pHead = NULL;
        Type* pTail = NULL;
        for(;;) {
            Type* pBaseArg = acceptPrimitiveType();
            if (pBaseArg) {
                Type* pArg = acceptDeclaration(pBaseArg, nameAllowed, false);
                if (pArg) {
                    Type* pParam = createType(TY_PARAM, pArg, NULL);
                    if (!pHead) {
                        pHead = pParam;
                        pTail = pParam;
                    } else {
                        pTail->pTail = pParam;
                        pTail = pParam;
                    }
                }
            }
            if (! accept(',')) {
                break;
            }
        }
        return pHead;
    }

    Type* expectPrimitiveType() {
        Type* pType = acceptPrimitiveType();
        if (!pType) {
            String buf;
            decodeToken(buf, tok, true);
            error("Expected a type, got %s", buf.getUnwrapped());
        }
        return pType;
    }

    void checkLVal() {
        if (pGen->getR0ExpressionType() != ET_LVALUE) {
            error("Expected an lvalue");
        }
    }

    void addGlobalSymbol(Type* pDecl) {
        tokenid_t t = pDecl->id;
        VariableInfo* pVI = VI(t);
        if(pVI && pVI->pAddress) {
            reportDuplicate(t);
        }
        mGlobals.add(pDecl);
    }

    void reportDuplicate(tokenid_t t) {
        error("Duplicate definition of %s", nameof(t));
    }

    void addLocalSymbol(Type* pDecl) {
        tokenid_t t = pDecl->id;
        if (mLocals.isDefinedAtCurrentLevel(t)) {
            reportDuplicate(t);
        }
        mLocals.add(pDecl);
    }

    bool checkUndeclaredStruct(Type* pBaseType) {
        if (pBaseType->tag == TY_STRUCT && pBaseType->length < 0) {
            String temp;
            decodeToken(temp, pBaseType->structTag, false);
            error("Undeclared struct %s", temp.getUnwrapped());
            return true;
        }
        return false;
    }

    void localDeclarations(Type* pBaseType) {
        intptr_t a;

        while (pBaseType) {
            while (tok != ';' && tok != EOF) {
                Type* pDecl = expectDeclaration(pBaseType);
                if (!pDecl) {
                    break;
                }
                if (!pDecl->id) {
                    break;
                }
                if (checkUndeclaredStruct(pDecl)) {
                    break;
                }
                addLocalSymbol(pDecl);
                if (pDecl->tag == TY_FUNC) {
                    if (tok == '{') {
                        error("Nested functions are not allowed. Did you forget a '}' ?");
                        break;
                    }
                    // Else it's a forward declaration of a function.
                } else {
                    int variableAddress = 0;
                    size_t alignment = pGen->alignmentOf(pDecl);
                    assert(alignment > 0);
                    size_t alignmentMask = ~ (alignment - 1);
                    size_t sizeOf = pGen->sizeOf(pDecl);
                    assert(sizeOf > 0);
                    loc = (loc + alignment - 1) & alignmentMask;
                    size_t alignedSize = (sizeOf + alignment - 1) & alignmentMask;
                    loc = loc + alignedSize;
                    variableAddress = -loc;
                    VI(pDecl->id)->pAddress = (void*) variableAddress;
                    if (accept('=')) {
                        /* assignment */
                        pGen->leaR0(variableAddress, createPtrType(pDecl), ET_LVALUE);
                        pGen->pushR0();
                        expr();
                        pGen->forceR0RVal();
                        pGen->storeR0ToTOS();
                    }
                }
                if (tok == ',')
                    next();
            }
            skip(';');
            pBaseType = acceptPrimitiveType();
        }
    }

    bool checkSymbol() {
        return checkSymbol(tok);
    }

    void decodeToken(String& buffer, tokenid_t token, bool quote) {
        if (token == EOF ) {
            buffer.printf("EOF");
        } else if (token == TOK_NUM) {
            buffer.printf("numeric constant");
        } else if (token >= 0 && token < 256) {
            if (token < 32) {
                buffer.printf("'\\x%02x'", token);
            } else {
                buffer.printf("'%c'", token);
            }
        } else {
            if (quote) {
                if (token >= TOK_KEYWORD && token < TOK_SYMBOL) {
                    buffer.printf("keyword \"%s\"", nameof(token));
                } else {
                    buffer.printf("symbol \"%s\"", nameof(token));
                }
            } else {
                buffer.printf("%s", nameof(token));
            }
        }
    }

    void printToken(tokenid_t token) {
        String buffer;
        decodeToken(buffer, token, true);
        fprintf(stderr, "%s\n", buffer.getUnwrapped());
    }

    bool checkSymbol(tokenid_t token) {
        bool result = token >= TOK_SYMBOL;
        if (!result) {
            String temp;
            decodeToken(temp, token, true);
            error("Expected symbol. Got %s", temp.getUnwrapped());
        }
        return result;
    }

    tokenid_t acceptSymbol() {
        tokenid_t result = 0;
        if (tok >= TOK_SYMBOL) {
            result = tok;
            next();
        }
        return result;
    }

    void globalDeclarations() {
        mpCurrentSymbolStack = &mGlobals;
        while (tok != EOF) {
            Type* pBaseType = expectPrimitiveType();
            if (!pBaseType) {
                break;
            }
            Type* pDecl = expectDeclaration(pBaseType);
            if (!pDecl) {
                break;
            }
            if (!pDecl->id) {
                skip(';');
                continue;
            }

            if (checkUndeclaredStruct(pDecl)) {
                skip(';');
                continue;
            }

            if (! isDefined(pDecl->id)) {
                addGlobalSymbol(pDecl);
            }
            VariableInfo* name = VI(pDecl->id);
            if (name && name->pAddress) {
                error("Already defined global %s", nameof(pDecl->id));
            }
            if (pDecl->tag < TY_FUNC) {
                // it's a variable declaration
                for(;;) {
                    if (name && !name->pAddress) {
                        name->pAddress = (int*) allocGlobalSpace(
                                                   pGen->alignmentOf(name->pType),
                                                   pGen->sizeOf(name->pType));
                    }
                    if (accept('=')) {
                        if (tok == TOK_NUM) {
                            if (name) {
                                * (int*) name->pAddress = tokc;
                            }
                            next();
                        } else {
                            error("Expected an integer constant");
                        }
                    }
                    if (!accept(',')) {
                        break;
                    }
                    pDecl = expectDeclaration(pBaseType);
                    if (!pDecl) {
                        break;
                    }
                    if (! isDefined(pDecl->id)) {
                        addGlobalSymbol(pDecl);
                    }
                    name = VI(pDecl->id);
                }
                skip(';');
            } else {
                // Function declaration
                if (accept(';')) {
                    // forward declaration.
                } else if (tok != '{') {
                    error("expected '{'");
                } else {
                    mpCurrentArena = &mLocalArena;
                    mpCurrentSymbolStack = &mLocals;
                    if (name) {
                        /* patch forward references */
                        pGen->resolveForward((int) name->pForward);
                        /* put function address */
                        name->pAddress = (void*) pCodeBuf->getPC();
                    }
                    // Calculate stack offsets for parameters
                    mLocals.pushLevel();
                    intptr_t a = 8;
                    int argCount = 0;
                    for (Type* pP = pDecl->pTail; pP; pP = pP->pTail) {
                        Type* pArg = pP->pHead;
                        if (pArg->id) {
                            addLocalSymbol(pArg);
                        }
                        /* read param name and compute offset */
                        Type* pPassingType = passingType(pArg);
                        size_t alignment = pGen->alignmentOf(pPassingType);
                        a = (a + alignment - 1) & ~ (alignment-1);
                        if (pArg->id) {
                            VI(pArg->id)->pAddress = (void*) a;
                        }
                        a = a + pGen->sizeOf(pPassingType);
                        argCount++;
                    }
                    rsym = loc = 0;
                    pReturnType = pDecl->pHead;
                    a = pGen->functionEntry(pDecl);
                    block(0, true);
                    pGen->gsym(rsym);
                    pGen->functionExit(pDecl, a, loc);
                    mLocals.popLevel();
                    mpCurrentArena = &mGlobalArena;
                    mpCurrentSymbolStack = &mGlobals;
                }
            }
        }
    }

    Type* passingType(Type* pType) {
        switch (pType->tag) {
        case TY_CHAR:
        case TY_SHORT:
            return mkpInt;
        default:
            return pType;
        }
    }

    char* allocGlobalSpace(size_t alignment, size_t bytes) {
        size_t base = (((size_t) glo) + alignment - 1) & ~(alignment-1);
        size_t end = base + bytes;
        if ((end - (size_t) pGlobalBase) > (size_t) ALLOC_SIZE) {
            error("Global space exhausted");
            assert(false);
            return NULL;
        }
        char* result = (char*) base;
        glo = (char*) end;
        return result;
    }

    void cleanup() {
        if (pGlobalBase != 0) {
            free(pGlobalBase);
            pGlobalBase = 0;
        }
        if (pGen) {
            delete pGen;
            pGen = 0;
        }
        if (pCodeBuf) {
            delete pCodeBuf;
            pCodeBuf = 0;
        }
        if (file) {
            delete file;
            file = 0;
        }
    }

    // One-time initialization, when class is constructed.
    void init() {
        mpSymbolLookupFn = 0;
        mpSymbolLookupContext = 0;
    }

    void clear() {
        tok = 0;
        tokc = 0;
        tokl = 0;
        ch = 0;
        rsym = 0;
        loc = 0;
        glo = 0;
        dptr = 0;
        dch = 0;
        file = 0;
        pGlobalBase = 0;
        pCodeBuf = 0;
        pGen = 0;
        mPragmaStringCount = 0;
        mCompileResult = 0;
        mLineNumber = 1;
        mbBumpLine = false;
        mbSuppressMacroExpansion = false;
    }

    void setArchitecture(const char* architecture) {
        delete pGen;
        pGen = 0;

        delete pCodeBuf;
        pCodeBuf = new CodeBuf();

        if (architecture != NULL) {
#ifdef PROVIDE_ARM_CODEGEN
            if (! pGen && strcmp(architecture, "arm") == 0) {
                pGen = new ARMCodeGenerator();
                pCodeBuf = new ARMCodeBuf(pCodeBuf);
            }
#endif
#ifdef PROVIDE_X86_CODEGEN
            if (! pGen && strcmp(architecture, "x86") == 0) {
                pGen = new X86CodeGenerator();
            }
#endif
            if (!pGen ) {
                error("Unknown architecture %s\n", architecture);
            }
        }

        if (pGen == NULL) {
#if defined(DEFAULT_ARM_CODEGEN)
            pGen = new ARMCodeGenerator();
            pCodeBuf = new ARMCodeBuf(pCodeBuf);
#elif defined(DEFAULT_X86_CODEGEN)
            pGen = new X86CodeGenerator();
#endif
        }
        if (pGen == NULL) {
            error("No code generator defined.");
        } else {
            pGen->setErrorSink(this);
            pGen->setTypes(mkpInt);
        }
    }

public:
    struct args {
        args() {
            architecture = 0;
        }
        const char* architecture;
    };

    Compiler() {
        init();
        clear();
    }

    ~Compiler() {
        cleanup();
    }

    void registerSymbolCallback(ACCSymbolLookupFn pFn, ACCvoid* pContext) {
        mpSymbolLookupFn = pFn;
        mpSymbolLookupContext = pContext;
    }

    int compile(const char* text, size_t textLength) {
        int result;

        mpCurrentArena = &mGlobalArena;
        createPrimitiveTypes();
        cleanup();
        clear();
        mTokenTable.setArena(&mGlobalArena);
        mGlobals.setArena(&mGlobalArena);
        mGlobals.setTokenTable(&mTokenTable);
        mLocals.setArena(&mLocalArena);
        mLocals.setTokenTable(&mTokenTable);

        internKeywords();
        setArchitecture(NULL);
        if (!pGen) {
            return -1;
        }
#ifdef PROVIDE_TRACE_CODEGEN
            pGen = new TraceCodeGenerator(pGen);
#endif
        pGen->setErrorSink(this);

        if (pCodeBuf) {
            pCodeBuf->init(ALLOC_SIZE);
        }
        pGen->init(pCodeBuf);
        file = new TextInputStream(text, textLength);
        pGlobalBase = (char*) calloc(1, ALLOC_SIZE);
        glo = pGlobalBase;
        inp();
        next();
        globalDeclarations();
        checkForUndefinedForwardReferences();
        result = pGen->finishCompile();
        if (result == 0) {
            if (mErrorBuf.len()) {
                result = -2;
            }
        }
        mCompileResult = result;
        return result;
    }

    void createPrimitiveTypes() {
        mkpInt = createType(TY_INT, NULL, NULL);
        mkpShort = createType(TY_SHORT, NULL, NULL);
        mkpChar = createType(TY_CHAR, NULL, NULL);
        mkpVoid = createType(TY_VOID, NULL, NULL);
        mkpFloat = createType(TY_FLOAT, NULL, NULL);
        mkpDouble = createType(TY_DOUBLE, NULL, NULL);
        mkpIntFn =  createType(TY_FUNC, mkpInt, NULL);
        mkpIntPtr = createPtrType(mkpInt);
        mkpCharPtr = createPtrType(mkpChar);
        mkpFloatPtr = createPtrType(mkpFloat);
        mkpDoublePtr = createPtrType(mkpDouble);
        mkpPtrIntFn = createPtrType(mkpIntFn);
    }

    void checkForUndefinedForwardReferences() {
        mGlobals.forEach(static_ufrcFn, this);
    }

    static bool static_ufrcFn(VariableInfo* value, void* context) {
        Compiler* pCompiler = (Compiler*) context;
        return pCompiler->undefinedForwardReferenceCheck(value);
    }

    bool undefinedForwardReferenceCheck(VariableInfo* value) {
        if (!value->pAddress && value->pForward) {
            error("Undefined forward reference: %s",
                  mTokenTable[value->tok].pText);
        }
        return true;
    }

    /* Look through the symbol table to find a symbol.
     * If found, return its value.
     */
    void* lookup(const char* name) {
        if (mCompileResult == 0) {
            tokenid_t tok = mTokenTable.intern(name, strlen(name));
            VariableInfo* pVariableInfo = VI(tok);
            if (pVariableInfo) {
                return pVariableInfo->pAddress;
            }
        }
        return NULL;
    }

    void getPragmas(ACCsizei* actualStringCount,
                    ACCsizei maxStringCount, ACCchar** strings) {
        int stringCount = mPragmaStringCount;
        if (actualStringCount) {
            *actualStringCount = stringCount;
        }
        if (stringCount > maxStringCount) {
            stringCount = maxStringCount;
        }
        if (strings) {
            char* pPragmas = mPragmas.getUnwrapped();
            while (stringCount-- > 0) {
                *strings++ = pPragmas;
                pPragmas += strlen(pPragmas) + 1;
            }
        }
    }

    void getProgramBinary(ACCvoid** base, ACCsizei* length) {
        *base = pCodeBuf->getBase();
        *length = (ACCsizei) pCodeBuf->getSize();
    }

    char* getErrorMessage() {
        return mErrorBuf.getUnwrapped();
    }
};

const char* Compiler::operatorChars =
    "++--*@/@%@+@-@<<>><=>=<@>@==!=&&||&@^@|@~@!@";

const char Compiler::operatorLevel[] =
    {11, 11, 1, 1, 1, 2, 2, 3, 3, 4, 4, 4, 4,
            5, 5, /* ==, != */
            9, 10, /* &&, || */
            6, 7, 8, /* & ^ | */
            2, 2 /* ~ ! */
            };

#ifdef PROVIDE_X86_CODEGEN
const int Compiler::X86CodeGenerator::operatorHelper[] = {
        0x1,     // ++
        0xff,    // --
        0xc1af0f, // *
        0xf9f79991, // /
        0xf9f79991, // % (With manual assist to swap results)
        0xc801, // +
        0xd8f7c829, // -
        0xe0d391, // <<
        0xf8d391, // >>
        0xe, // <=
        0xd, // >=
        0xc, // <
        0xf, // >
        0x4, // ==
        0x5, // !=
        0x0, // &&
        0x1, // ||
        0xc821, // &
        0xc831, // ^
        0xc809, // |
        0xd0f7, // ~
        0x4     // !
};
#endif

struct ACCscript {
    ACCscript() {
        text = 0;
        textLength = 0;
        accError = ACC_NO_ERROR;
    }

    ~ACCscript() {
        delete text;
    }

    void registerSymbolCallback(ACCSymbolLookupFn pFn, ACCvoid* pContext) {
        compiler.registerSymbolCallback(pFn, pContext);
    }

    void setError(ACCenum error) {
        if (accError == ACC_NO_ERROR && error != ACC_NO_ERROR) {
            accError = error;
        }
    }

    ACCenum getError() {
        ACCenum result = accError;
        accError = ACC_NO_ERROR;
        return result;
    }

    Compiler compiler;
    char* text;
    int textLength;
    ACCenum accError;
};


extern "C"
ACCscript* accCreateScript() {
    return new ACCscript();
}

extern "C"
ACCenum accGetError( ACCscript* script ) {
    return script->getError();
}

extern "C"
void accDeleteScript(ACCscript* script) {
    delete script;
}

extern "C"
void accRegisterSymbolCallback(ACCscript* script, ACCSymbolLookupFn pFn,
                               ACCvoid* pContext) {
    script->registerSymbolCallback(pFn, pContext);
}

extern "C"
void accScriptSource(ACCscript* script,
    ACCsizei count,
    const ACCchar ** string,
    const ACCint * length) {
    int totalLength = 0;
    for(int i = 0; i < count; i++) {
        int len = -1;
        const ACCchar* s = string[i];
        if (length) {
            len = length[i];
        }
        if (len < 0) {
            len = strlen(s);
        }
        totalLength += len;
    }
    delete script->text;
    char* text = new char[totalLength + 1];
    script->text = text;
    script->textLength = totalLength;
    char* dest = text;
    for(int i = 0; i < count; i++) {
        int len = -1;
        const ACCchar* s = string[i];
        if (length) {
            len = length[i];
        }
        if (len < 0) {
            len = strlen(s);
        }
        memcpy(dest, s, len);
        dest += len;
    }
    text[totalLength] = '\0';

#ifdef DEBUG_SAVE_INPUT_TO_FILE
    LOGD("Saving input to file...");
    int counter;
    char path[PATH_MAX];
    for (counter = 0; counter < 4096; counter++) {
        sprintf(path, DEBUG_DUMP_PATTERN, counter);
        if(access(path, F_OK) != 0) {
            break;
        }
    }
    if (counter < 4096) {
        LOGD("Saving input to file %s", path);
        FILE* fd = fopen(path, "w");
        if (fd) {
            fwrite(text, totalLength, 1, fd);
            fclose(fd);
            LOGD("Saved input to file %s", path);
        } else {
            LOGD("Could not save. errno: %d", errno);
        }
    }
#endif
}

extern "C"
void accCompileScript(ACCscript* script) {
    int result = script->compiler.compile(script->text, script->textLength);
    if (result) {
        script->setError(ACC_INVALID_OPERATION);
    }
}

extern "C"
void accGetScriptiv(ACCscript* script,
    ACCenum pname,
    ACCint * params) {
    switch (pname) {
        case ACC_INFO_LOG_LENGTH:
            *params = 0;
            break;
    }
}

extern "C"
void accGetScriptInfoLog(ACCscript* script,
    ACCsizei maxLength,
    ACCsizei * length,
    ACCchar * infoLog) {
    char* message = script->compiler.getErrorMessage();
    int messageLength = strlen(message) + 1;
    if (length) {
        *length = messageLength;
    }
    if (infoLog && maxLength > 0) {
        int trimmedLength = maxLength < messageLength ?
                maxLength : messageLength;
        memcpy(infoLog, message, trimmedLength);
        infoLog[trimmedLength] = 0;
    }
}

extern "C"
void accGetScriptLabel(ACCscript* script, const ACCchar * name,
                       ACCvoid ** address) {
    void* value = script->compiler.lookup(name);
    if (value) {
        *address = value;
    } else {
        script->setError(ACC_INVALID_VALUE);
    }
}

extern "C"
void accGetPragmas(ACCscript* script, ACCsizei* actualStringCount,
                   ACCsizei maxStringCount, ACCchar** strings){
    script->compiler.getPragmas(actualStringCount, maxStringCount, strings);
}

extern "C"
void accGetProgramBinary(ACCscript* script,
    ACCvoid** base, ACCsizei* length) {
    script->compiler.getProgramBinary(base, length);
}


} // namespace acc

