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