📄 cinfo.c
字号:
/****************************************************************************
*
* 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 "cvars.h"
#include "cg.h"
#include "cgdefs.h"
#include "cgswitch.h"
#include "standard.h"
#include "cgprotos.h"
#include "cgaux.h"
#include "langenv.h"
struct user_seg {
struct user_seg *next;
char *name;
SYM_HANDLE sym_handle; /* 15-mar-92 */
int segtype; /* 22-oct-92 */
int segment; /* 22-oct-92 */
char *class_name; /* 22-oct-92 */
hw_reg_set pegged_register; /* 29-may-93 */
bool used;
};
void AssignSeg( SYM_ENTRY *sym )
{
SetFarHuge( sym, 1 );
if( (sym->stg_class == SC_AUTO) || (sym->stg_class == SC_REGISTER)
|| (sym->stg_class == SC_TYPEDEF) ) {
/* if stack/register var, there is no segment */
sym->u.var.segment = 0;
} else if( sym->stg_class != SC_EXTERN ) { /* if not imported */
if( (sym->flags & SYM_INITIALIZED) == 0 ) {
if( sym->u.var.segment == 0 ) { /* 15-mar-92 */
SetSegment( sym );
}
if( sym->u.var.segment == SEG_DATA ) {
sym->u.var.segment = SEG_BSS;
CompFlags.bss_segment_used = 1;
}
SetSegAlign( sym ); /* 02-feb-92 */
}
} else if( sym->attrib & (FLAG_FAR | FLAG_HUGE) ) {
sym->u.var.segment = SegImport;
--SegImport;
} else if( (SegData != 0) && (sym->attrib & FLAG_NEAR) ){ // imported and near
sym->u.var.segment = SegData;
}
}
void SetFarHuge( SYMPTR sym, int report )
{
TYPEPTR typ;
unsigned attrib;
auto unsigned long size;
report = report; /* in case not used */
#if _CPU == 8086
if( sym->declspec == DECLSPEC_DLLIMPORT
|| sym->declspec == DECLSPEC_DLLEXPORT ) { /* 16-dec-94 */
sym->attrib |= FLAG_FAR;
} else if( sym->attrib & FLAG_EXPORT ) {
sym->attrib |= FLAG_FAR;
}
#endif
size = SizeOfArg( sym->sym_type );
if( TargetSwitches & BIG_DATA ) {
attrib = sym->attrib;
if( (attrib & (FLAG_NEAR|FLAG_FAR|FLAG_HUGE)) == 0 ) {
if( size == 0 ) { /* unspecified array size */
if( sym->stg_class == SC_EXTERN ) {
typ = sym->sym_type;
if( typ->decl_type == TYPE_ARRAY ) {
attrib |= FLAG_FAR;
}
}
} else if( size > DataThreshold ) {
attrib |= FLAG_FAR;
} else if( (/* sym->stg_class == SC_STATIC || 17-may-91 */
CompFlags.strings_in_code_segment ) /*JD: 29-oct-90*/
&& sym->attrib & FLAG_CONST ) {
attrib |= FLAG_FAR;
}
#if _CPU == 8086
if( (attrib & FLAG_FAR) && size > 0x10000 ) {
attrib &= ~FLAG_FAR;
attrib |= FLAG_HUGE;
}
#endif
sym->attrib = attrib;
}
}
#if _CPU == 8086
if( report && size > 0x10000 && !(sym->attrib & FLAG_HUGE) ) {
SetSymLoc( sym );
CErr( ERR_VAR_TOO_LARGE );
}
#endif
}
#define CONSTANT( decl_flags ) ( ( decl_flags \
& ( FLAG_CONST | FLAG_VOLATILE ) ) \
== FLAG_CONST )
static fe_attr FESymAttr( SYMPTR sym )
/************************************/
{
fe_attr attr;
attr = 0;
switch( sym->stg_class ) {
case SC_FORWARD:
case SC_EXTERN:
attr = FE_GLOBAL | FE_IMPORT | FE_STATIC;
break;
case SC_NULL:
attr = FE_GLOBAL | FE_STATIC;
break;
case SC_STATIC:
attr = FE_STATIC | FE_VISIBLE;
if( sym->level != 0 ) {
attr |= FE_INTERNAL;
}
break;
}
if( sym->flags & SYM_FUNCTION ) {
attr |= FE_PROC | FE_STATIC;
#if _MACHINE == _ALPHA || _MACHINE == _PPC
if( VarFunc( sym ) ) attr |= FE_VARARGS;
#endif
if( CompFlags.unique_functions ) {
if( (attr & FE_GLOBAL) || (sym->flags & SYM_ADDR_TAKEN) ) {
attr |= FE_UNIQUE;
}
}
}
if( sym->flags & SYM_USED_IN_PRAGMA ) {
attr |= FE_MEMORY | FE_ADDR_TAKEN | FE_VOLATILE;
}
if( sym->flags & SYM_TRY_VOLATILE ) {
attr |= FE_MEMORY | FE_VOLATILE;
}
if( sym->attrib & FLAG_VOLATILE ) {
attr |= FE_MEMORY | FE_VOLATILE;
} else if( sym->attrib & FLAG_CONST ) {
attr |= FE_CONSTANT;
}
switch( sym->declspec ){
case DECLSPEC_DLLIMPORT:
if( (attr & FE_IMPORT) || CompFlags.rent ) {
attr |= FE_DLLIMPORT;
}
break;
case DECLSPEC_DLLEXPORT:
if( sym->stg_class == SC_NULL ) {
attr |= FE_DLLEXPORT;
}
break;
case DECLSPEC_THREAD:
attr |= FE_THREAD_DATA;
break;
}
if( sym->naked ){
attr |= FE_NAKED;
}
if( sym->rent ){ //Override on function or r/w data
attr |= FE_THREAD_DATA;
}
return( attr );
}
void FEGenProc( CGSYM_HANDLE hdl, call_handle call_list )
/***********************************/
{
SYM_HANDLE sym_handle = hdl;
GenInLineFunc( sym_handle );
}
fe_attr FEAttr( CGSYM_HANDLE cgsym_handle )
/*****************************************/
{
SYM_HANDLE sym_handle = cgsym_handle;
return( FESymAttr( SymGetPtr( sym_handle ) ) );
}
segment_id SymSegId( SYMPTR sym )
{
fe_attr attr;
attr = FESymAttr( sym );
if( attr & FE_PROC ) return( SEG_CODE );
if( !CompFlags.rent ){
if( attr & FE_CONSTANT ) return( SEG_CONST2 );
}
return( SEG_DATA );
}
void SetSegment( SYMPTR sym )
{
struct segment_list *seg;
auto unsigned long size;
#if _CPU == 8086
if( ( ( sym->attrib & FLAG_FAR ) && CompFlags.zc_switch_used ) ) {
if( CONSTANT( sym->attrib ) ||
(sym->stg_class == SC_STATIC && (sym->flags & SYM_TEMP) ) ) {
sym->u.var.segment = SEG_CODE;
return;
}
}
#elif _CPU == 386
if( !CompFlags.rent ){
if( ( (sym->attrib & FLAG_FAR) || (TargetSwitches & FLAT_MODEL) ) ) {
if( CONSTANT( sym->attrib ) && CompFlags.zc_switch_used ){
sym->u.var.segment = SEG_CODE;
return;
}
if( (sym->stg_class == SC_STATIC )&& (sym->flags & SYM_TEMP) ) {
sym->u.var.segment = SEG_CODE;
return;
}
}
}
#endif
if( sym->attrib & ( FLAG_FAR | FLAG_HUGE ) ) {
size = SizeOfArg( sym->sym_type );
seg = NULL;
#if _CPU == 8086
if( size < 0x10000 ) {
auto unsigned int isize;
isize = size;
for( seg = SegListHead; seg; seg = seg->next_segment ) {
if( seg->size_left >= isize ) break;
}
}
#else
seg = SegListHead;
#endif
if( seg == NULL ) {
if( SegListHead == NULL ) {
SegListHead = CMemAlloc( sizeof( struct segment_list ) );
seg = SegListHead;
} else {
for( seg = SegListHead; seg->next_segment; ) {
seg = seg->next_segment;
}
seg->next_segment =
CMemAlloc( sizeof( struct segment_list ) );
seg = seg->next_segment;
}
seg->segment_number = SegmentNum;
++SegmentNum;
#if _CPU == 8086
if( size > 0xFFFF ) {
while( size > 0x0FFFF ) { /* while >= 64K */
++SegmentNum;
size -= 0x10000;
}
seg->size_left = 0;
} else {
seg->size_left = 0x10000-size;
}
#endif
} else {
seg->size_left -= size;
}
sym->u.var.segment = seg->segment_number;
} else {
sym->u.var.segment = SymSegId( sym );
}
}
#ifndef WCPP
struct seg_name {
char *name;
int segment;
};
static struct seg_name Predefined_Segs[] = {
{ "_CODE", SEG_CODE },
{ "_CONST", SEG_CONST },
{ "_DATA", SEG_DATA },
{ "_STACK", SEG_STACK }, /* 13-dec-92 */
{ NULL, 0 }
};
static int UserSegment;
#define FIRST_USER_SEGMENT 10000
static struct user_seg *AllocUserSeg( char *segname, char *class_name, seg_type segtype ){
struct user_seg *useg;
useg = CMemAlloc( sizeof( struct user_seg ) );
useg->next = NULL;
useg->name = CStrSave( segname );
useg->class_name = NULL;
useg->segtype = segtype;
if( class_name != NULL ) {
useg->class_name = CStrSave( class_name );
}
useg->segment = UserSegment;
++UserSegment;
return( useg );
}
#define INITFINI_SIZE 12
struct spc_info {
char *name;
char *class_name;
seg_type segtype;
};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -