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