cpragx86.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,416 行 · 第 1/3 页
C
1,416 行
/****************************************************************************
*
* 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 "plusplus.h"
#include "preproc.h"
#include "name.h"
#include "memmgr.h"
#include "errdefns.h"
#include "cgdata.h"
#include "pragdefn.h"
#include "pdefn2.h"
#include "asminlin.h"
#include "fnovload.h"
#include "cgswitch.h"
#include "initdefs.h"
#include "cginlibs.h"
#include "cginimps.h"
#include "asmstmt.h"
#include "pcheader.h"
static int GetAliasInfo();
static byte_seq *AuxCodeDup( byte_seq *code );
static int GetByteSeq( void );
static hw_reg_set asmRegsSaved = { HW_D( HW_FULL ) };
#define WCPP_ASM // enable assembler
static void pragmaInit( // INITIALIZATION FOR PRAGMAS
INITFINI* defn ) // - definition
{
defn = defn;
PragInit();
PragmaAuxInfoInit( CompFlags.use_stdcall_at_number );
#if _CPU == 386
HW_CTurnOff( asmRegsSaved, HW_EAX );
HW_CTurnOff( asmRegsSaved, HW_EBX );
HW_CTurnOff( asmRegsSaved, HW_ECX );
HW_CTurnOff( asmRegsSaved, HW_EDX );
HW_CTurnOff( asmRegsSaved, HW_ESI );
HW_CTurnOff( asmRegsSaved, HW_EDI );
#else
HW_CTurnOff( asmRegsSaved, HW_ABCD );
HW_CTurnOff( asmRegsSaved, HW_SI );
HW_CTurnOff( asmRegsSaved, HW_DI );
HW_CTurnOff( asmRegsSaved, HW_ES );
#endif
SetAuxDefaultInfo();
}
static void freeInfo( AUX_INFO *info )
{
if( info->code != NULL ) {
CMemFree( info->code );
info->code = NULL;
}
if( !IsAuxParmsBuiltIn( info->parms ) ) {
CMemFree( info->parms );
info->parms = NULL;
}
if( info->objname != NULL ) {
CMemFree( info->objname );
info->objname = NULL;
}
}
static void pragmaFini( // FINISH PRAGMAS
INITFINI* defn ) // - definition
{
register struct aux_entry *next;
register void *junk;
defn = defn;
next = AuxList;
while( next != NULL ) {
junk = next;
if( next->info != NULL ) {
if( next->info->use != 1 ) {
next->info->use--;
} else {
freeInfo( next->info );
#ifndef NDEBUG
if( IsAuxInfoBuiltIn( next->info ) ) {
CFatal( "freeing a static calling convention info" );
}
#endif
if( !IsAuxInfoBuiltIn( next->info ) ) {
CMemFree( next->info );
}
}
}
next = next->next;
CMemFree( junk );
}
freeInfo( &DefaultInfo );
freeInfo( &CdeclInfo );
freeInfo( &PascalInfo );
freeInfo( &SyscallInfo );
freeInfo( &OptlinkInfo );
freeInfo( &StdcallInfo );
freeInfo( &FastcallInfo );
#if _CPU == 386
freeInfo( &Far16CdeclInfo );
freeInfo( &Far16PascalInfo );
#endif
freeInfo( &WatcallInfo );
freeInfo( &FortranInfo );
//CMemFreePtr( &FortranInfo.objname );
AuxList = NULL;
CgInfoFreeLibs();
CgInfoFreeImports();
CgInfoFreeImportsS();
}
INITDEFN( pragmas, pragmaInit, pragmaFini )
static void assemblerInit( // INITIALIZATION OF ASSEMBLER
INITFINI* defn ) // - definition
{
int cpu;
int fpu;
int use32;
defn = defn;
#if _CPU == 386
use32 = 1;
cpu = 3;
#else
use32 = 0;
cpu = 0;
#endif
switch( GET_CPU( CpuSwitches ) ) {
case CPU_86: cpu = 0; break;
case CPU_186: cpu = 1; break;
case CPU_286: cpu = 2; break;
case CPU_386: cpu = 3; break;
case CPU_486: cpu = 4; break;
case CPU_586: cpu = 5; break;
case CPU_686: cpu = 6; break;
}
switch( GET_FPU( CpuSwitches ) ) {
case FPU_NONE: fpu = 0; break;
default: fpu = 1; break;
}
AsmInit( cpu, fpu, use32, 1 );
}
INITDEFN( assembler, assemblerInit, InitFiniStub )
static void AuxCopy( // COPY AUX STRUCTURE
AUX_INFO *to, // - destination
AUX_INFO *from ) // - source
{
freeAuxInfo( to );
*to = *from;
to->parms = AuxParmDup( from->parms );
to->objname = AuxObjnameDup( from->objname );
to->code = AuxCodeDup( from->code );
}
static boolean GetAliasInfo(
void )
{
char buff[256];
boolean isfar16;
boolean retn;
CurrAlias = &DefaultInfo;
if( CurToken != T_LEFT_PAREN ) {
retn = TRUE;
} else {
NextToken();
if( ! PragIdCurToken() ) {
retn = FALSE;
} else {
PragCurrAlias();
strcpy( buff, Buffer );
NextToken();
if( CurToken == T_RIGHT_PAREN ) {
NextToken();
retn = TRUE;
} else if( CurToken == T_COMMA ) {
NextToken();
if( ! PragIdCurToken() ) {
retn = FALSE;
} else {
isfar16 = PragRecog( "far16" );
CreateAux( buff );
PragCurrAlias();
NextToken();
if( CurToken == T_RIGHT_PAREN ) {
AuxCopy( CurrInfo, CurrAlias );
NextToken();
}
if( isfar16 ) {
CurrInfo->flags |= AUX_FLAG_FAR16;
}
PragEnding( TRUE );
retn = FALSE;
}
}
}
}
return retn;
}
static void GetParmInfo(
void )
{
struct {
unsigned f_pop : 1;
unsigned f_reverse : 1;
unsigned f_loadds : 1;
unsigned f_nomemory : 1;
unsigned f_list : 1;
} have;
have.f_pop = 0;
have.f_reverse = 0;
have.f_loadds = 0;
have.f_nomemory = 0;
have.f_list = 0;
for( ;; ) {
if( !have.f_pop && PragRecog( "caller" ) ) {
CurrInfo->cclass |= CALLER_POPS;
have.f_pop = 1;
} else if( !have.f_pop && PragRecog( "routine" ) ) {
CurrInfo->cclass &= ~ CALLER_POPS;
have.f_pop = 1;
} else if( !have.f_reverse && PragRecog( "reverse" ) ) {
CurrInfo->cclass |= REVERSE_PARMS;
have.f_reverse = 1;
} else if( !have.f_nomemory && PragRecog( "nomemory" ) ) {
CurrInfo->cclass |= NO_MEMORY_READ;
have.f_nomemory = 1;
} else if( !have.f_loadds && PragRecog( "loadds" ) ) {
CurrInfo->cclass |= LOAD_DS_ON_CALL;
have.f_loadds = 1;
} else if( !have.f_list && PragSet() != T_NULL ) {
PragManyRegSets();
have.f_list = 1;
} else {
break;
}
}
}
static void GetSTRetInfo(
void )
{
struct {
unsigned f_float : 1;
unsigned f_struct : 1;
unsigned f_allocs : 1;
unsigned f_list : 1;
} have;
have.f_float = 0;
have.f_struct = 0;
have.f_allocs = 0;
have.f_list = 0;
for( ;; ) {
if( !have.f_float && PragRecog( "float" ) ) {
have.f_float = 1;
CurrInfo->cclass |= NO_FLOAT_REG_RETURNS;
} else if( !have.f_struct && PragRecog( "struct" ) ) {
have.f_struct = 1;
CurrInfo->cclass |= NO_STRUCT_REG_RETURNS;
} else if( !have.f_allocs && PragRecog( "routine" ) ) {
have.f_allocs = 1;
CurrInfo->cclass |= ROUTINE_RETURN;
} else if( !have.f_allocs && PragRecog( "caller" ) ) {
have.f_allocs = 1;
CurrInfo->cclass &= ~ROUTINE_RETURN;
} else if( !have.f_list && PragSet() != T_NULL ) {
have.f_list = 1;
CurrInfo->cclass |= SPECIAL_STRUCT_RETURN;
CurrInfo->streturn = PragRegList();
} else {
break;
}
}
}
static void GetRetInfo(
void )
{
struct {
unsigned f_no8087 : 1;
unsigned f_list : 1;
unsigned f_struct : 1;
} have;
have.f_no8087 = 0;
have.f_list = 0;
have.f_struct = 0;
CurrInfo->cclass &= ~ NO_8087_RETURNS;
for( ;; ) {
if( !have.f_no8087 && PragRecog( "no8087" ) ) {
have.f_no8087 = 1;
HW_CTurnOff( CurrInfo->returns, HW_FLTS );
CurrInfo->cclass |= NO_8087_RETURNS;
} else if( !have.f_list && PragSet() != T_NULL ) {
have.f_list = 1;
CurrInfo->cclass |= SPECIAL_RETURN;
CurrInfo->returns = PragRegList();
} else if( !have.f_struct && PragRecog( "struct" ) ) {
have.f_struct = 1;
GetSTRetInfo();
} else {
break;
}
}
}
static void GetSaveInfo(
void )
{
hw_reg_set modlist;
hw_reg_set default_flt_n_seg;
hw_reg_set flt_n_seg;
struct {
unsigned f_exact : 1;
unsigned f_nomemory : 1;
unsigned f_list : 1;
} have;
have.f_exact = 0;
have.f_nomemory = 0;
have.f_list = 0;
for( ;; ) {
if( !have.f_exact && PragRecog( "exact" ) ) {
CurrInfo->cclass |= MODIFY_EXACT;
have.f_exact = 1;
} else if( !have.f_nomemory && PragRecog( "nomemory" ) ) {
CurrInfo->cclass |= NO_MEMORY_CHANGED;
have.f_nomemory = 1;
} else if( !have.f_list && PragSet() != T_NULL ) {
modlist = PragRegList();
have.f_list = 1;
} else {
break;
}
}
if( have.f_list ) {
HW_Asgn( default_flt_n_seg, DefaultInfo.save );
HW_CTurnOn( CurrInfo->save, HW_FULL );
if( !have.f_exact && !CompFlags.save_restore_segregs ) {
HW_CAsgn( flt_n_seg, HW_FLTS );
HW_CTurnOn( flt_n_seg, HW_SEGS );
HW_TurnOff( CurrInfo->save, flt_n_seg );
HW_OnlyOn( default_flt_n_seg, flt_n_seg );
HW_TurnOn( CurrInfo->save, default_flt_n_seg );
}
HW_TurnOff( CurrInfo->save, modlist );
}
}
static void doPragAux( // #PRAGMA AUX ...
void )
{
struct {
unsigned f_call : 1;
unsigned f_loadds : 1;
unsigned f_export : 1;
unsigned f_parm : 1;
unsigned f_value : 1;
unsigned f_modify : 1;
unsigned f_frame : 1;
unsigned uses_auto: 1;
} have;
if( !GetAliasInfo() ) return;
CurrEntry = NULL;
if( !PragIdCurToken() ) return;
SetCurrInfo();
NextToken();
AuxCopy( CurrInfo, CurrAlias );
PragObjNameInfo();
have.f_call = 0;
have.f_loadds = 0;
have.f_export = 0;
have.f_parm = 0;
have.f_value = 0;
have.f_modify = 0;
have.f_frame = 0;
have.uses_auto = 0;
for( ;; ) {
if( !have.f_call && CurToken == T_EQUAL ) {
have.uses_auto = GetByteSeq();
have.f_call = 1;
} else if( !have.f_call && PragRecog( "far" ) ) {
CurrInfo->cclass |= FAR;
have.f_call = 1;
} else if( !have.f_call && PragRecog( "near" ) ) {
CurrInfo->cclass &= ~FAR;
have.f_call = 1;
} else if( !have.f_loadds && PragRecog( "loadds" ) ) {
CurrInfo->cclass |= LOAD_DS_ON_ENTRY;
have.f_loadds = 1;
} else if( !have.f_export && PragRecog( "export" ) ) {
CurrInfo->cclass |= DLL_EXPORT;
have.f_export = 1;
} else if( !have.f_parm && PragRecog( "parm" ) ) {
GetParmInfo();
have.f_parm = 1;
} else if( !have.f_value && PragRecog( "value" ) ) {
GetRetInfo();
have.f_value = 1;
} else if( !have.f_value && PragRecog( "aborts" ) ) {
CurrInfo->cclass |= SUICIDAL;
have.f_value = 1;
} else if( !have.f_modify && PragRecog( "modify" ) ) {
GetSaveInfo();
have.f_modify = 1;
} else if( !have.f_frame && PragRecog( "frame" ) ) {
CurrInfo->cclass |= GENERATE_STACK_FRAME;
have.f_frame = 1;
} else {
break;
}
}
if( have.uses_auto ) {
AsmSysUsesAuto();
}
PragEnding( TRUE );
}
void PragAux( // #PRAGMA AUX ...
void )
{
PPState = PPS_EOL;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?