outasm.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 549 行 · 第 1/2 页

C
549
字号
/****************************************************************************
*
*                            Open Watcom Project
*
*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
*  ========================================================================
*
*    This file contains Original Code and/or Modifications of Original
*    Code as defined in and that are subject to the Sybase Open Watcom
*    Public License version 1.0 (the 'License'). You may not use this file
*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
*    provided with the Original Code and Modifications, and is also
*    available at www.sybase.com/developer/opensource.
*
*    The Original Code and all software distributed under the License are
*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
*    NON-INFRINGEMENT. Please see the License for the specific language
*    governing rights and limitations under the License.
*
*  ========================================================================
*
* Description:  WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
*               DESCRIBE IT HERE!
*
****************************************************************************/


#include "wic.h"
#include "output.h"
#include "outasm.h"

#define UNARY_OP_LABEL {2, {"0L"}, NULL}
#define BINARY_OP_LABEL {3, {"L0R"}, NULL}

static char *_asmStrADDR_OF_VALUE[] = { "OFFSET" };
static char *_asmStrAND_AND[] = { "(", "NE 0)", "(", " NE 0)" };
static char *_asmStrEXCLAMATION[] = { "(", "NE 0)" };
static char *_asmStrOR_OR[] = { "(", "NE 0)", "(", "NE 0)" };
static char *_asmStrPRE_DEFINE_MACRO[] = { "EQU" };
PrintCTreeTable printCTreeAsmTable[LABCT_MAX] = {
/* ADDR_OF_VALUE */     {2, {"aL"}, _asmStrADDR_OF_VALUE },
/* AND */               BINARY_OP_LABEL,
/* AND_AND */           {7, {"aLb0cRd"}, _asmStrAND_AND },
/* ARROW */             BINARY_OP_LABEL,
/* CALL */              {4,  {"L0R1"}, NULL},
/* CAST_EXPR */         {1,  {"R"}, NULL},
/* COLON */             BINARY_OP_LABEL,
/* DEFINED */           {4,  {"0123"}, NULL},
/* DIVIDE */            BINARY_OP_LABEL,
/* DOT */               BINARY_OP_LABEL,
/* EQ */                BINARY_OP_LABEL,
/* EXCLAMATION */       { 3, {"aLb"}, _asmStrEXCLAMATION },
/* EXPR_LIST */         BINARY_OP_LABEL,
/* EXPR_SEPARATOR */    BINARY_OP_LABEL,
/* GE */                BINARY_OP_LABEL,
/* GT */                BINARY_OP_LABEL,
/* INDEX */             {4,  {"L0R1"}, NULL},
/* LE */                BINARY_OP_LABEL,
/* LSHIFT */            BINARY_OP_LABEL,
/* LT */                BINARY_OP_LABEL,
/* MINUS */             BINARY_OP_LABEL,
/* NE */                BINARY_OP_LABEL,
/* OR */                BINARY_OP_LABEL,
/* OR_OR */             {7,  {"aLb0cRd"}, _asmStrOR_OR },
/* PAREN_EXPR */        {3,  {"0L1"}, NULL},
/* PERCENT */           BINARY_OP_LABEL,
/* PLUS */              BINARY_OP_LABEL,
/* PRE_DEFINE_MACRO */  {5,  {"0LaRN"}, _asmStrPRE_DEFINE_MACRO},
/* PRE_ELIF */          {3,  {"0LN"}, NULL},
/* PRE_ELSE */          {2,  {"0N"}, NULL},
/* PRE_ENDIF */         {2,  {"0N"}, NULL},
/* PRE_IF */            {3,  {"0LN"}, NULL},
/* PRE_IFDEF */         {3,  {"01N"}, NULL},
/* PRE_IFNDEF */        {3,  {"01N"}, NULL},
/* PRE_INCLUDE */       {3,  {"01N"}, NULL},
/* PRE_DIR_LIST*/       {3,  {"0LN"}, NULL},
/* QUESTION */          BINARY_OP_LABEL,
/* RSHIFT */            BINARY_OP_LABEL,
/* SIZEOF_EXPR */       UNARY_OP_LABEL,
/* SIZEOF_TYPE */       UNARY_OP_LABEL,
/* STRINGS */           {2,  {"LR"}, NULL},
/* TILDE */             UNARY_OP_LABEL,
/* TIMES */             BINARY_OP_LABEL,
/* UNARY_MINUS */       UNARY_OP_LABEL,
/* UNARY_PLUS */        UNARY_OP_LABEL,
/* VALUE_AT_ADDR */     UNARY_OP_LABEL,
/* XOR */               BINARY_OP_LABEL
};

// Declaration types
typedef enum {
    DT_PTR            = 1,
    DT_FUNC           = 2,
    DT_SIMPLE         = 4,
    DT_STRUCT_DEF     = 8,
    DT_STRUCT_VAR     = 16,
    DT_ENUM_DEF       = 32,
    DT_ENUM_VAR       = 64,
    DT_INVALID        = 128
}  DeclType;

static DeclType getDeclType(pDeclInfo decl) {
    pDclr dclr;
    assert(decl != NULL);
    dclr = decl->dclr;

    if (isDclrFunc(dclr)) {
        return DT_FUNC;
    } else if (isDclrPtr(dclr)) {
        return DT_PTR;
    } else {
        switch (decl->type) {
            case DIT_NULL:
                return DT_INVALID;

            case DIT_SCALAR:
            {
                ScalarType t = decl->repr.scalar.scalar;
                if (t == SCL_DOT_DOT_DOT || t == SCL_VOID || t == SCL_NULL) {
                    debugOut("Bad scalar type: %d", t);
                    return DT_INVALID;
                } else {
                    return DT_SIMPLE;
                }
            }

            case DIT_STRUCT_OR_UNION:
            {
                pDeclStructInfo s = decl->repr.s;
                if (s == NULL) {
                    debugOut("Null structure");
                    return DT_INVALID;
                } else {
                    if (s->body == NULL) {
                        if (s->name == NULL) {
                            return DT_INVALID;
                        } else {
                            return DT_STRUCT_VAR;
                        }
                    } else {
                        return DT_STRUCT_DEF;
                    }
                }
            }

            case DIT_ENUM:
            {
                pDeclEnum e = decl->repr.e;
                if (e == NULL) {
                    return DT_INVALID;
                } else {
                    if (e->list == NULL) {
                        return DT_ENUM_VAR;
                    } else {
                        return DT_ENUM_DEF;
                    }
                }
            }

            default:
                assert(0);
                return DT_INVALID;
        }
    }
}

char *getDeclIdName(pDeclInfo decl, DeclType type) {
    switch (type) {
    case DT_PTR:
    case DT_SIMPLE:
    case DT_STRUCT_VAR:
    case DT_ENUM_VAR:
    case DT_FUNC:
        return getDclrName(decl->dclr);

    case DT_STRUCT_DEF:
        assert(decl->repr.s->name != NULL);
        return getTokenIdName(decl->repr.s->name);

    case DT_ENUM_DEF:
        return NULL;

    case DT_INVALID:
    {
        char *retVal = getDclrName(decl->dclr);
        if (retVal == NULL) {
            return "???";
        } else {
            return retVal;
        }
    }

    default:
        assert(0);
        return NULL;
    }
}

static int getDeclTypeSize(pDeclInfo decl, DeclType type) {
    static int asmSclType[SCL_MAX][SIZE_MAX] = {
                 /* SIZE_16      SIZE_32         SIZE_48*/
    /*NULL*/       {0,           0,              0},
    /*CHAR*/       {1,           1,              1},
    /*SCHAR*/      {1,           1,              1},
    /*UCHAR*/      {1,           1,              1},
    /*WCHAR*/      {4,           4,              4},
    /*SSHORT*/     {2,           2,              2},
    /*USHORT*/     {2,           2,              2},
    /*SINT*/       {2,           4,              4},
    /*UINT*/       {2,           4,              4},
    /*SLONG*/      {4,           4,              6},
    /*ULONG*/      {4,           4,              6},
    /*FLOAT*/      {4,           4,              4},
    /*DOUBLE*/     {8,           8,              8},
    /*LDOUBLE*/    {8,           8,              8},
    /*VOID*/       {0,           0,              0},
    /*DOT_DOT_DOT*/{0,           0,              0}
    };
    static int ptrStr[SIZE_MAX] =
        { 2,  4, 6 };

    switch (type) {
    case DT_PTR:
    {
        SizeType temp;
        switch (decl->dclr->ptr->memType) {
            case MT_NULL: temp = g_opt.ptrSize; break;
            case MT_NEAR: temp = g_opt.nearPtrSize; break;
            case MT_FAR: temp = g_opt.farPtrSize; break;
            case MT_FAR16: temp = g_opt.farPtrSize; break;
            case MT_HUGE: temp = g_opt.hugePtrSize; break;
            default: assert(0);
        }
        return ptrStr[temp];
    }

    case DT_SIMPLE:
        assert(decl->repr.scalar.scalar <= SCL_MAX);
        assert(decl->repr.scalar.scalar >= SCL_NULL);
        return asmSclType[decl->repr.scalar.scalar][g_opt.intSize];

    case DT_ENUM_VAR:
        return asmSclType[SCL_SINT][g_opt.intSize];
    case DT_STRUCT_DEF:
        return 0;
    case DT_ENUM_DEF:
        return NULL;
    case DT_INVALID:
        return 0;
    case DT_FUNC:
    case DT_STRUCT_VAR:
        return 0;
    default:
        assert(0);
        return 0;
    }
}

char* getAsmPragmaName(pDclr dclr) {
    if (dclr == NULL) {
        return NULL;
    }
    if (dclr->pragmaMod == NULL) {
        return NULL;
    }
    switch (dclr->pragmaMod->data->code) {
    case Y___CDECL:  return "C";
    case Y___PASCAL:  return "PASCAL";
    case Y___FORTRAN:  return "FORTRAN";
    case Y__SYSCALL:  return "";  // Leave it up to user

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?