wf77info.c

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

C
2,181
字号
/****************************************************************************
*
*                            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:  Front end routines defined for optimizing code generator.
*
****************************************************************************/


#include "ftnstd.h"
#include "global.h"
#include "cg.h"
#include "wf77defs.h"
#include "wf77aux.h"
#include "fcgbls.h"
#include "ecflags.h"
#include "sdfile.h"
#include "segsw.h"
#include "progsw.h"
#include "cpopt.h"
#include "cgflags.h"
#include "wf77segs.h"
#include "types.h"
#include "errcod.h"
#include "csetinfo.h"
#include "ferror.h"
#include "inout.h"
#include "fctypes.h"

#include "langenvd.h"
#if _CPU == 386 || _CPU == 8086
  #define __TGT_SYS     __TGT_SYS_X86
#elif _CPU == _AXP
  #define __TGT_SYS     __TGT_SYS_AXP_NT
#elif _CPU == _PPC
  #define __TGT_SYS     __TGT_SYS_PPC_NT
#else
  #error Unknown platform
#endif
#include "langenv.h"

#include <string.h>
#include <stdlib.h>

//=================== Back End Code Generation Routines ====================

extern  back_handle     BENewBack(sym_handle);
extern  void            BEFreeBack(back_handle);
extern  void            BEDefSeg(segment_id,seg_attr,char*,uint);
extern  segment_id      BESetSeg(segment_id);
extern  void            BEDefType(cg_type,uint,unsigned long);
extern  void            BEAliasType(cg_type,cg_type);
extern  unsigned long   BETypeLength(cg_type);
extern  dbg_type        DBScalar(char*,cg_type);
extern  dbg_proc        DBBegProc(cg_type,dbg_type);
extern  dbg_type        DBEndProc(dbg_proc);
extern  dbg_array       *DBBegArray(dbg_type,cg_type,bool);
extern  void            DBDimCon(dbg_array *,dbg_type,signed_32,signed_32);
extern  void            DBDimVar(dbg_array *,back_handle,int,cg_type,cg_type);
extern  dbg_type        DBEndArray(dbg_array *);
extern  dbg_type        DBDereference(cg_type,dbg_type);
extern  dbg_type        DBCharBlock(unsigned_32);
extern  dbg_type        DBFtnType(char *,dbg_ftn_type);
extern  unsigned long   DGSeek(unsigned long);
extern  void            DGUBytes(unsigned long);
extern  void            DGBytes(unsigned long,byte*);
extern  void            DGIBytes(unsigned long,byte);
extern  void            DGLabel(back_handle);
extern  unsigned long   DGBackTell(back_handle);
extern  void            DBAddParm(dbg_proc,dbg_type);
extern  dbg_struct      DBBegStruct(cg_type,char);
extern  dbg_type        DBEndStruct(dbg_struct);
extern  void            DBAddField(dbg_struct,unsigned_32,char *,dbg_type);
extern  dbg_loc         DBLocInit(void);
extern  dbg_loc         DBLocSym(dbg_loc,sym_handle);
extern  dbg_loc         DBLocTemp(dbg_loc,temp_handle);
extern  dbg_loc         DBLocConst(dbg_loc,unsigned_32);
extern  dbg_loc         DBLocOp(dbg_loc,dbg_loc_op,unsigned);
extern  dbg_type        DBLocCharBlock(dbg_loc,cg_type);
extern  void            DBLocFini(dbg_loc);

//=========================================================================

extern  int             MakeName(char *,char *,char *);
extern  char            *SDExtn(char *,char *);
extern  char            *SDFName(char *);
extern  char            *STGetName(sym_id,char *);
extern  char            *STExtractName(sym_id,char *);
extern  void            Suicide(void);
extern  intstar4        GetComBlkSize(sym_id);
extern  aux_info        *AuxLookup(sym_id);
extern  void            SendBlip(void);
extern  void            SendStd(char *);
extern  char            *STFieldName(sym_id,char *);
extern  char            *ErrorInitializer(void);
extern  bool            ForceStatic(unsigned_16);
extern  sym_id          FindArgShadow(sym_id);
extern  sym_id          STEqSetShadow(sym_id);
extern  char *          StackBuffer(int *);
#ifdef _EMS
extern  void            InitEMS(void);
extern  void            FiniEMS(void);
#endif

extern  global_seg      *CurrGSeg;
extern  global_seg      *GlobalSeg;
extern  unsigned_8      CGFlags;
extern  aux_info        FortranInfo;
extern  aux_info        DefaultInfo;
extern  character_set   CharSetInfo;
extern  char            ProgName[];
extern  char            ObjExtn[];
extern  default_lib     *DefaultLibs;
extern  dep_info        *DependencyInfo;
#ifdef _EMS
extern  unsigned int    EMSsegment;
#endif

static  void            DefDbgStruct( sym_id sym );

#define CS_SUFF_LEN             5
#define G_DATA_LEN              6
#define BLANK_COM_LEN           6

static  char            GData[] = { "GDATA@" };
#if _CPU == 8086 || _CPU == 386
static  char            *CSSuff = TS_SEG_CODE;
static  BYTE_SEQ(2)     CodeAlignSeq = { 2, sizeof( inttarg ), 1 };
static  BYTE_SEQ(1)     DefCodeAlignSeq = { 1, 1 };
#endif
static  sym_id          ImpSym;
static  segment_id      CurrSegId;
static  segment_id      CurrImpSegId;
static  cg_type         UserType;

#ifdef pick
#undef pick
#endif
#define pick(id,type,dbgtype,cgtype) dbgtype,

static  dbg_type        DBGTypes[] = {
#include "ptypdefn.h"
};

extern  sym_id                  STShadow(sym_id);
extern  sym_id                  FindShadow(sym_id);
extern  sym_id                  FindEqSetShadow(sym_id);
extern  uint                    SymAlign(sym_id);

#define _Shadow( s )    if( (s->ns.flags & SY_CLASS) == SY_VARIABLE ) { \
                            if( s->ns.flags & SY_SPECIAL_PARM ) { \
                                s = FindShadow( s ); \
                            } else { \
                                s = STShadow( s ); \
                                s->ns.address = NULL; \
                                _MgcSetClass( s, MAGIC_SHADOW ); \
                            } \
                        }
#define _UnShadow( s )  if( (s != NULL) && (_MgcClass(s) == MAGIC_SHADOW) ) { \
                            s = sym->ns.si.ms.sym; \
                        }

segment_id              CurrCodeSegId;

#define SYM_MANGLE_PRE          "_COMMON_"
#define SYM_MANGLE_POST         "_DATA"
#define SYM_MANGLE_PRE_LEN      8
#define SYM_MANGLE_POST_LEN     5
#define SYM_MANGLE_LEN          (SYM_MANGLE_PRE_LEN + SYM_MANGLE_POST_LEN)
#if _CPU == 8086 || _CPU == 386
static char                     MangleSymBuff[MAX_SYMLEN+4+SYM_MANGLE_LEN];
#endif


static  unsigned        MangleCommonBlockName( sym_id sym, char *buffer,
                                               bool class ) {
//===========================================================

    unsigned    cb_len;

    cb_len = sym->ns.name_len;
    if( CGOpts & CGOPT_MANGLE ) {
        cb_len += SYM_MANGLE_PRE_LEN;
        strcpy( buffer, SYM_MANGLE_PRE );
        STGetName( sym, &buffer[SYM_MANGLE_PRE_LEN] );
        if( class ) {
            strcpy( &buffer[cb_len], SYM_MANGLE_POST );
            cb_len += SYM_MANGLE_POST_LEN;
        }
    } else {
        STGetName( sym, buffer );
    }
    return( cb_len );
}


static  segment_id      AllocSegId( void ) {
//====================================

    segment_id  seg;

    seg = CurrSegId;
    ++CurrSegId;
    return( seg );
}


void    InitSubSegs( void ) {
//=====================

    CurrImpSegId = -1;
}


segment_id      AllocImpSegId( void ) {
//===============================

    segment_id  seg;

    seg = CurrImpSegId;
    --CurrImpSegId;
    return( seg );
}


void    InitSegs( void ) {
//==================

// Define segments.

    CurrSegId = WF77_FREE_SEG;
#if _CPU == _AXP || _CPU == _PPC
    BEDefSeg( WF77_TDATA, EXEC|GLOBAL|GIVEN_NAME, TS_SEG_CODE, ALIGN_DWORD );
    CurrCodeSegId = WF77_TDATA;
#endif
    BEDefSeg( WF77_CDATA, BACK | INIT | ROM, TS_SEG_CONST, ALIGN_SEGMENT );
    BEDefSeg( WF77_LDATA, INIT, TS_SEG_DATA, ALIGN_SEGMENT );
    BEDefSeg( WF77_UDATA, 0, TS_SEG_BSS, ALIGN_SEGMENT );
    DefineGlobalSegs();
    DefineCommonSegs();
    LDSegOffset = 0;
    GSegOffset = 0;
}


void    FiniSegs( void ) {
//==================

// Finish segment processing.

    sym_id      sym;

    for( sym = GList; sym != NULL; sym = sym->ns.link ) {
        if( ( sym->ns.flags & SY_CLASS ) != SY_COMMON ) continue;
        BEFreeBack( sym->ns.address );
    }
}


void    AllocSegs( void ) {
//===================

// Allocate segments.

    AllocGlobalSegs();
    AllocCommonSegs();
}


void    SubCodeSeg( void ) {
//====================

// Define a code segment for a subprogram.
#if _CPU == 8086 || _CPU == 386
    DefCodeSeg();
#endif
}


#if _CPU == 8086 || _CPU == 386
static  byte_seq        *AlignmentSeq( void ) {
//=======================================

    if( OZOpts & OZOPT_O_TIME ) {
        return( (byte_seq *)&CodeAlignSeq );
    } else {
        return( (byte_seq *)&DefCodeAlignSeq );
    }
}


static  void    DefCodeSeg( void ) {
//============================

// Define a code segment.

    char        seg_name[MAX_SYMLEN+CS_SUFF_LEN+1];
    BYTE_SEQ(1) *align_seq;
    int         len;
    int         alignment;

    align_seq = (void *) AlignmentSeq();  // variable length
    alignment = 1;
    len = 0;
    while( len != align_seq->length ) {
        if( alignment < align_seq->data[len] ) {
            alignment = align_seq->data[len];
        }
        ++len;
    }
    BldCSName( seg_name );
    CurrCodeSegId = AllocSegId();
    BEDefSeg( CurrCodeSegId, EXEC|GLOBAL|GIVEN_NAME, seg_name, alignment );
}


static  void    BldCSName( char *buff ) {
//=======================================

// Build code segment name.

#if _CPU == 8086
    strcpy( STGetName( SubProgId, buff ), CSSuff );
#else
    strcpy( buff, CSSuff );
#endif
}
#endif


static  void    DefineCommonSegs( void ) {
//==================================

// Define segments for a common blocks.

    unsigned_32 com_size;
    int         seg_count;
    sym_id      sym;
    int         cb_len;
    int         private;

    char        cb_name[MAX_SYMLEN+4+SYM_MANGLE_LEN];

#if _CPU == 386 || _CPU == 8086
    if( _SmallDataModel( CGOpts ) ) {
        private = INIT; // so segment doesn't get put in BSS class
    } else {
        private = PRIVATE;
    }
#endif
    for( sym = GList; sym != NULL; sym = sym->ns.link ) {
        if( ( sym->ns.flags & SY_CLASS ) != SY_COMMON ) continue;
#if _CPU == _AXP || _CPU == _PPC
        if( sym->ns.flags & SY_COMMON_INIT ) {
            private = INIT | COMDAT;
        } else {
            private = 0;
        }
#endif
        cb_len = MangleCommonBlockName( sym, cb_name, FALSE );

        sym->ns.si.cb.seg_id = AllocSegId();
        if( CGOpts & CGOPT_ALIGN ) {
            BEDefSeg( sym->ns.si.cb.seg_id, COMMON | private, cb_name,
                      ALIGN_SEGMENT );
        } else {
            BEDefSeg( sym->ns.si.cb.seg_id, COMMON | private, cb_name,
                      ALIGN_BYTE );
        }
        seg_count = 0;
        cb_name[ cb_len ] = '@';
        com_size = GetComBlkSize( sym );
        for(;;) {
            if( com_size <= MaxSegSize ) break;
            com_size -= MaxSegSize;
            seg_count++;
            itoa( seg_count, &cb_name[ cb_len + 1 ], 10 );
            if( CGOpts & CGOPT_ALIGN ) {
                BEDefSeg( AllocSegId(), COMMON | private , cb_name,
                          ALIGN_SEGMENT );
            } else {
                BEDefSeg( AllocSegId(), COMMON | private , cb_name,
                          ALIGN_BYTE );
            }
        }
    }
}


static  void    AllocCommonSegs( void ) {
//=================================

// Allocate segments for a common blocks.

    sym_id      sym;

    for( sym = GList; sym != NULL; sym = sym->ns.link ) {
        if( ( sym->ns.flags & SY_CLASS ) != SY_COMMON ) continue;
        AllocComBlk( sym );
    }
}


static  void    AllocComBlk( sym_id cb ) {
//========================================

// Allocate a common block.

    int         segment;
    unsigned_32 size;

    segment = cb->ns.si.cb.seg_id;
    BESetSeg( segment );
    cb->ns.address = BENewBack( cb );
    DGLabel( cb->ns.address );

⌨️ 快捷键说明

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