intrface.c

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

C
1,942
字号
/****************************************************************************
*
*                            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:  Code generator public interface.
*
****************************************************************************/


#include <ctype.h>
#include "standard.h"
#include "coderep.h"
#include "hostsys.h"
#include "cgdefs.h"
#include "model.h"
#include "seldef.h"
#include "memcheck.h"
#include "sysmacro.h"
#include "tree.h"
#include "addrname.h"
#include "cfloat.h"
#include "offset.h"
#include "ptrint.h"
#include "zoiks.h"
#include "cgaux.h"

#define BY_CG
#include "feprotos.h"
#include "cgprotos.h"

#ifndef NDEBUG
#include "echoapi.h"
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#endif

#include "bldins.h"

extern  void            FEPtr(sym_handle,type_def*,offset);
extern  seg_id          AskOP(void);
extern  void            InitBlip(void);
extern  void            FiniBlip(void);
extern  void            InitWeights(uint);
extern  void            CGMemInit(void);
extern  void            InitSegDefs(void);
extern  void            InitDbgInfo(void);
extern  void            TInit(void);
extern  void            TypeInit(void);
extern  bool            CGOpenf(void);
extern  void            InitCG(void);
extern  void            SillyMemLimit(void);
extern  void            FiniCG(void);
extern  void            AbortCG(void);
extern  void            FiniDbgInfo(void);
extern  void            TypeFini(void);
extern  void            TFini(void);
extern  void            CGMemFini(void);
extern  seg_id          SetOP(seg_id);
extern  void            FlushOP(seg_id);
extern  bool            AskSegROM(segment_id);
extern  void            DefSegment(seg_id,seg_attr,char*,uint,bool);
extern  label_handle    AskForNewLabel(void);
extern  void            BGFiniLabel(label_handle);
extern  label_handle    AskForLabel(sym_handle);
extern  seg_id          AskBackSeg(void);
extern  bool            AskSegBlank(seg_id);
extern  void            TellNoSymbol(label_handle);
extern  type_def        *TypeDef(cg_type,type_length,type_length);
extern  type_def        *TypeAlias(cg_type,cg_type);
extern  type_length     TypeLength(cg_type);
extern  void            BGProcDecl(sym_handle,type_def*);
extern  type_def        *TypeAddress(cg_type);
extern  void            BGParmDecl(sym_handle,type_def*);
extern  void            BGAutoDecl(sym_handle,type_def*);
extern  tn              TGLeaf(an);
extern  tn              TGTmpLeaf(an);
extern  tn              TGReLeaf(an);
extern  tn              TGLVAssign(tn,tn,type_def*);
extern  tn              TGAssign(tn,tn,type_def*);
extern  tn              TGPostGets(cg_op,tn,tn,type_def*);
extern  tn              TGLVPreGets(cg_op,tn,tn,type_def*);
extern  tn              TGPreGets(cg_op,tn,tn,type_def*);
extern  tn              TGTrash(tn);
extern  tn              TGBinary(cg_op,tn,tn,type_def*);
extern  tn              TGUnary(cg_op,tn,type_def*);
extern  tn              TGIndex(tn,tn,type_def*,type_def*);
extern  tn              TGInitCall(tn,type_def*,sym_handle);
extern  tn              TGAddParm(tn,tn,type_def*);
extern  tn              TGCall(tn);
extern  tn              TGCompare(cg_op,tn,tn,type_def*);
extern  tn              TGFlow(cg_op,tn,tn);
extern  tn              TGQuestion(tn,tn,tn,type_def*);
extern  tn              TGWarp(tn,label_handle,tn);
extern  void            TGControl(cg_op,tn,label_handle);
extern  void            TG3WayControl(tn,label_handle,label_handle,label_handle);
extern  select_node     *BGSelInit(void);
extern  void            BGSelCase(select_node*,label_handle,signed_32);
extern  void            BGSelRange(select_node*,signed_32,signed_32,label_handle);
extern  void            BGSelOther(select_node*,label_handle);
extern  an              TGen(tn,type_def*);
extern  void            BGSelect(select_node*,an,cg_switch_type);
extern  an              TGReturn(tn,type_def*);
extern  void            BGReturn(an,type_def*);
extern  an              BGSave(an);
extern  cg_type         TGType(tn);
extern  btn             TGBitMask(tn,byte,byte,type_def*);
extern  tn              TGVolatile(tn);
extern  tn              TGAttr( tn, cg_sym_attr );
extern  tn              TGAlign( tn, uint );
extern  void            DGBlip(void);
extern  void            DataLabel(label_handle);
extern  void            BackPtr(bck_info*,seg_id,offset,type_def*);
extern  uint            Length(char*);
extern  type_class_def  TypeClass(type_def*);
extern  void            DataBytes(unsigned_32,byte*);
extern  void            IterBytes(offset,byte);
extern  void            SetLocation(offset);
extern  void            IncLocation(offset);
extern  offset          AskLocation(void);
extern  seg_id          AskCodeSeg(void);
extern  seg_id          AskAltCodeSeg(void);
extern  offset          AskAddress(label_handle);
extern  bool            BGInInline(void);
extern  void            BGParmInline(sym_handle,type_def*);
extern  void            BGRetInline(an,type_def*);
extern  void            BGProcInline(sym_handle,type_def*);
extern  void            TellObjNewProc(sym_handle);
extern  tn              TGCallback( cg_callback, callback_handle );
extern  patch_handle    BGNewPatch(void);
extern  cg_name         BGPatchNode( patch_handle, type_def * );
extern  void            BGPatchInteger( patch_handle, signed_32 );
extern  void            BGFiniPatch( patch_handle );
extern  bool            AskSegBlank( seg_id );
extern  an              MakeConst( cfloat *, type_def * );
extern  void            DataAlign( unsigned_32 );


#ifdef QNX_FLAKEY
unsigned long   OrigModel;
#endif

extern    byte  OptForSize;

#define MAX_BCK_INFO    1000    // number of bck_info's per carve block

typedef union uback_info {
    bck_info    bck;
    union uback_info    *link;
} uback_info;

typedef struct bck_info_block {
    struct bck_info_block       *next;
    uback_info                  bck_infos[MAX_BCK_INFO];
} bck_info_block;

uback_info      *BckInfoHead;           // linked list of available bck_info's
bck_info_block  *BckInfoCarveHead;      // list of big blocks of bck_info's


/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
/*%                                              %%*/
/*%   Module interface                           %%*/
/*%                                              %%*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/

static  bool            memStarted = FALSE;

extern  void _CGAPI     BEMemInit( void )
/***************************************/
{
    cf_callbacks cf_rtns = { CGAlloc, CGFree };

    BckInfoHead = NULL;
    BckInfoCarveHead = NULL;
    InitBlip();
    CGMemInit();
    CFInit( &cf_rtns );
    memStarted = TRUE;
}

extern  cg_init_info _CGAPI     BEInitCg( cg_switches switches,
                                                cg_target_switches platform,
                                                uint optsize,
                                                proc_revision proc )
/**************************************************************************/
{
    cg_init_info        info;

    OptForSize = optsize;
    CGProcessorVersion = proc; /* so _CPULevel works */
    #if  _TARGET & _TARG_80386
        if( !_CPULevel( CPU_386 ) ) {
            SET_CPU( proc, CPU_386 );
        }
        proc &= ~FPU_EMU;   /* don't need funny fixups for 386 */
    #elif _TARGET & _TARG_IAPX86
        /* if it ain't a 386 or better, FS and GS aren't there */
        if( !_CPULevel( CPU_386 ) ) {
            switches &= ~(FLOATING_FS | FLOATING_GS);
        }
    #endif
    Model = switches;
    TargetModel = platform;
#ifdef QNX_FLAKEY
    OrigModel = switches;
#endif
#ifndef NDEBUG
    EchoAPIInit();
    EchoAPI( "BEInit( %x, %x, %i, %x )\n", switches, platform, optsize, proc );
    // must be after Model is set and before InitDBGInfo call
#endif
    CGProcessorVersion = proc;
    InitWeights( optsize );
    InitSegDefs();
    InitDbgInfo();
    TypeInit();
    TInit();
    if( !CGOpenf() ) {
        info.success = 0;
    } else {
    info.success = 1;
        info.version.is_large = TRUE;
#if _TARGET & _TARG_80386
        info.version.target = II_TARG_80386;
#elif _TARGET & _TARG_IAPX86
        info.version.target = II_TARG_8086;
#elif _TARGET & _TARG_370
        info.version.target = II_TARG_370; /* NYI -- for now */
#elif _TARGET & _TARG_AXP
        info.version.target = II_TARG_AXP;
#endif
        info.version.revision = II_REVISION;
    }
    return( info );
}

extern  cg_init_info _CGAPI     BEInit( cg_switches switches,
                                        cg_target_switches platform,
                                        uint optsize, proc_revision proc )
/************************************************************************/
{
    BEMemInit();
    return( BEInitCg( switches, platform, optsize, proc ) );
}

extern  void _CGAPI     BEStart( void )
/*************************************/
{
#ifndef NDEBUG
    EchoAPI( "BEStart()\n" );
#endif
    InitCG();
}

extern  void _CGAPI     BEStop( void )
/************************************/
{
#ifndef NDEBUG
    EchoAPI( "BEStop()\n" );
#endif
    FiniCG();
}

extern  void _CGAPI     BEAbort( void )
/*************************************/
{
#ifndef NDEBUG
    EchoAPI( "BEAbort()\n" );
#endif
    AbortCG();
}


extern  void _CGAPI     BEMemFini( void )
/***************************************/
{
    CFFini();
    CGMemFini();
}

static void FreeBckInfoCarveBlocks( void )
{
    bck_info_block      *carve_block;

    for( ; carve_block = BckInfoCarveHead; ) {
        BckInfoCarveHead = carve_block->next;
        _Free( carve_block, sizeof( bck_info_block ) );
    }
    BckInfoHead = NULL;
}

extern  void _CGAPI     BEFiniCg( void )
/**************************************/
{
#ifndef NDEBUG
    EchoAPI( "BEFiniCg()\n" );
    EchoAPIFini();
#endif
    FreeBckInfoCarveBlocks();
    FiniDbgInfo();
    TypeFini();
    TFini();
    FiniBlip();
}

extern  void _CGAPI     BEFini( void )
/************************************/
{
    BEFiniCg();
    BEMemFini();
}

extern  bool _CGAPI     BEMoreMem( void )
/***************************************/
{
    return( _MemCheck( 1 ) );
}

extern  segment_id _CGAPI       BESetSeg( segment_id seg )
/********************************************************/
{
#ifndef NDEBUG
    EchoAPI( "BESetSeg( %x )", seg );
    seg = SetOP(seg);
    return EchoAPIHexReturn( seg );
#else
    return( SetOP( seg ) );
#endif
}

extern  void _CGAPI     BEDefSeg( segment_id id, seg_attr attr, char *str, uint algn )
/************************************************************************************/
{
#ifndef NDEBUG
    EchoAPI( "BEDefSeg( %x, %x, %c, %i )\n", id, attr, str, algn );
#endif
    DefSegment( id, attr, str, algn, FALSE );
}

extern  void _CGAPI     BEFlushSeg( segment_id seg )
/**************************************************/
{
#ifndef NDEBUG
    EchoAPI( "BEFlushSeg( %x )\n", seg );
#endif
    FlushOP( seg );
}

/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
/*%                                              %%*/
/*%   Handle creation/deletion                   %%*/
/*%                                              %%*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/

extern  label_handle _CGAPI BENewLabel( void )
/********************************************/
{
#ifndef NDEBUG
    label_handle retn;

    EchoAPI( "BENewLabel()" );
    retn = AskForNewLabel();
    EchoAPI( " -> %L\n", retn );
    hdlAdd( LABEL_HANDLE, retn );
    return retn;
#else
    return( AskForNewLabel() );
#endif
}

extern  void _CGAPI     BEFiniLabel( label_handle lbl )
/*****************************************************/
{
#ifndef NDEBUG
    EchoAPI( "BEFiniLabel( %L )\n", lbl );
    hdlExists( LABEL_HANDLE, lbl );
    hdlUseOnce( LABEL_HANDLE, lbl );
#endif

    BGFiniLabel( lbl );
}


/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
/*%                                              %%*/
/*%   Miscellaneous stuff                        %%*/
/*%                                              %%*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/


extern  unsigned_32 _CGAPI      BEUnrollCount( unsigned_32 unroll_count )
/***********************************************************************/
{
#ifndef NDEBUG
    unsigned_32 retn;
    EchoAPI( "BEUnrollCount( %i )", unroll_count );
    retn = BGUnrollCount( unroll_count );
    return EchoAPIIntReturn( retn );
#else
    return( BGUnrollCount( unroll_count ) );
#endif
}


/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
/*%                                              %%*/
/*%   Tree patch creation/use/deletion           %%*/
/*%                                              %%*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/

extern  patch_handle _CGAPI     BEPatch( void )
/*********************************************/
{
#ifndef NDEBUG
    patch_handle retn;

    EchoAPI( "BEPatch()" );
    retn = BGNewPatch();
    EchoAPI( " -> %P\n", retn );
    hdlAdd( PATCH_HANDLE, retn );
    return retn;
#else
    return( BGNewPatch() );
#endif
}

extern  cg_name _CGAPI          CGPatchNode( patch_handle hdl, cg_type tipe )
/***************************************************************************/
{
#ifndef NDEBUG
    cg_name retn;
    EchoAPI( "CGPatchNode( %P, %t )", hdl, tipe );
    hdlExists( PATCH_HANDLE, hdl );
    retn = BGPatchNode( hdl, TypeAddress( tipe ) );
    hdlAdd( CG_NAMES, retn );
    return EchoAPICgnameReturn( retn );
#else
    return( BGPatchNode( hdl, TypeAddress( tipe ) ) );
#endif
}

extern  void _CGAPI     BEPatchInteger( patch_handle hdl, signed_32 value )
/*************************************************************************/
{
#ifndef NDEBUG
    EchoAPI( "BEPatchInteger( %P, %x )\n", hdl, value );
    hdlExists( PATCH_HANDLE, hdl );
#endif
    BGPatchInteger( hdl, value );
}

extern  void _CGAPI     BEFiniPatch( patch_handle hdl )
/*****************************************************/
{
#ifndef NDEBUG
    EchoAPI( "BEFiniPatch( %P )\n", hdl );
    hdlUseOnce( PATCH_HANDLE, hdl );
#endif

    BGFiniPatch( hdl );
}


⌨️ 快捷键说明

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