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 + -
显示快捷键?