i86call.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 505 行 · 第 1/2 页
C
505 行
/****************************************************************************
*
* 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 "standard.h"
#include "coderep.h"
#include "opcodes.h"
#include "procdef.h"
#include "model.h"
#include "sysmacro.h"
#include "addrname.h"
#include "cgdefs.h"
#include "hostsys.h"
#include "cgaux.h"
#include "regset.h"
#include "rtclass.h"
#include "zoiks.h"
#define BY_CG
#include "cgprotos.h"
extern instruction *MakeMove(name*,name*,type_class_def);
extern instruction *MakeUnary(opcode_defs,name*,name*,type_class_def);
extern label_handle AskForNewLabel(void);
extern name *SAllocMemory(pointer,type_length,cg_class,type_class_def,type_length);
extern name *AddrConst(name*,segment_id,constant_class);
extern name *AllocRegName(hw_reg_set);
extern name *AllocTemp(type_class_def);
extern name *NearSegment(void);
extern name *SAllocIndex(name*,name*,type_length,type_class_def,type_length);
extern name *SAllocTemp(type_class_def,type_length);
extern seg_id AskBackSeg(void);
extern seg_id SetOP(seg_id);
extern type_class_def TypeClass(type_def*);
extern void AddIns(instruction*);
extern void DataLabel(label_handle);
extern void SaveDisplay(opcode_defs);
extern void SetDisplay(name*);
extern name *GenIns(an);
extern instruction *MakeBinary(opcode_defs,name*,name*,name*,type_class_def);
extern name *AllocS32Const(signed_32);
extern an MakeTempAddr(name*,type_def*);
extern bool AssgnParms(cn,bool);
extern type_class_def AddCallBlock(sym_handle,type_def*);
extern void AddCallIns(instruction*,cn);
extern void FreeCallNode(cn);
extern name *SegmentPart(name*);
extern name *OffsetPart(name*);
extern name *DoParmDecl(sym_handle,type_def*,hw_reg_set);
extern hw_reg_set ReturnReg(type_class_def,bool);
extern type_length PushSize(type_length);
extern type_def *QParmType(sym_handle,sym_handle,type_def*);
extern label_handle RTLabel( int rtindex );
extern name *AllocMemory(pointer,type_length,cg_class,type_class_def);
extern void ReverseParmNodeList(pn *);
extern name *STempOffset(name*,type_length,type_class_def,type_length);
extern void SuffixIns( instruction *, instruction * );
extern name *BGNewTemp( type_def *tipe );
extern void BGDone( an );
extern type_def *TypeInteger;
extern type_def *TypeNone;
extern type_def *TypeProcParm;
extern type_class_def ClassPointer;
extern proc_def *CurrProc;
extern type_length MaxStack;
extern block *CurrBlock;
extern type_length TypeClassSize[];
static void AddCall( instruction *ins, cn call );
#if _TARGET & _TARG_80386
static void Far16Parms( cn call ) {
/*************************************/
instruction *ins;
type_length parm_size;
pn parm, next;
instruction *call_ins;
name *eax;
name *ecx;
name *esi;
label_handle lbl;
type_length offset;
name *parmlist;
call_state *state;
int thunk_rtn;
call_ins = call->ins;
parm_size = 0;
state = call->state;
for( parm = call->parms; parm != NULL; parm = parm->next ) {
parm_size += (( parm->name->tipe->length ) + 1) & ~1;
}
parmlist = SAllocTemp( XX, parm_size );
parmlist->v.usage |= NEEDS_MEMORY+USE_IN_ANOTHER_BLOCK+USE_ADDRESS;
offset = 0;
for( parm = call->parms; parm != NULL; parm = parm->next ) {
parm->name->u.ins->result = STempOffset( parmlist, offset,
TypeClass( parm->name->tipe ),
parm->name->tipe->length );
offset += (( parm->name->tipe->length ) + 1) & ~1;
}
for( parm = call->parms; parm != NULL; parm = next ) {
parm->name->format = NF_ADDR;
BGDone( parm->name );
next = parm->next;
_Free( parm, sizeof( parm_node ) );
}
eax = AllocRegName( HW_EAX );
ecx = AllocRegName( HW_ECX );
esi = AllocRegName( HW_ESI );
HW_TurnOn( state->parm.used, eax->r.reg );
HW_TurnOn( state->parm.used, ecx->r.reg );
HW_TurnOn( state->parm.used, esi->r.reg );
ins = MakeMove( AllocS32Const( parm_size ), ecx, WD );
AddIns( ins );
ins = MakeUnary( OP_LA, parmlist, esi, WD );
AddIns( ins );
if( ins->head.opcode == OP_CALL ) {
ins = MakeUnary( OP_LA, call->name->u.name, eax, WD );
} else {
ins = MakeMove( GenIns( call->name ), eax, WD );
call_ins->head.opcode = OP_CALL;
}
call_ins->num_operands = 2;
AddIns( ins );
if( call_ins->type_class == XX ) {
if( state->attr & ROUTINE_ALLOCS_RETURN ) {
thunk_rtn = RT_Far16Cdecl;
} else {
thunk_rtn = RT_Far16Pascal;
}
} else {
thunk_rtn = RT_Far16Func;
}
lbl = RTLabel( thunk_rtn - BEG_RTNS );
call->name->u.name = AllocMemory( lbl, 0, CG_LBL, WD );
call_ins->flags.call_flags |= CALL_FAR16 | CALL_POPS_PARMS;
call_ins->operands[CALL_OP_USED] = AllocRegName( state->parm.used );
call_ins->operands[CALL_OP_POPS] = AllocS32Const( 0 );
call_ins->zap = &call_ins->operands[CALL_OP_USED]->r;
}
#endif
extern an BGCall( cn call, bool use_return, bool in_line ) {
/****************************************************************/
instruction *call_ins;
call_state *state;
name *ret_ptr = NULL;
name *result;
name *temp;
name *reg_name;
instruction *ret_ins = NULL;
hw_reg_set return_reg;
hw_reg_set zap_reg;
if( call->name->tipe == TypeProcParm ) {
SaveDisplay( OP_PUSH );
}
state = call->state;
result = BGNewTemp( call->tipe );
call_ins = call->ins;
/* If we have a return value that won't fit in a register*/
/* pass a pointer to result as the first parm*/
if( call_ins->type_class == XX ) {
if( _RoutineIsFar16( state->attr ) ) {
if( state->attr & ROUTINE_ALLOCS_RETURN ) {
HW_CAsgn( state->return_reg, HW_EAX );
} else {
HW_CAsgn( state->return_reg, HW_EBX );
}
}
if( ( state->attr & ROUTINE_ALLOCS_RETURN ) == 0 ) {
if( HW_CEqual( state->return_reg, HW_EMPTY ) ) {
ret_ptr = AllocTemp( WD );
} else {
ret_ptr = AllocRegName( state->return_reg );
}
ret_ins = MakeUnary( OP_LA, result, ret_ptr, WD );
HW_TurnOn( state->parm.used, state->return_reg );
call_ins->flags.call_flags |= CALL_RETURNS_STRUCT;
}
}
if( _IsTargetModel(FLOATING_DS) && (state->attr&ROUTINE_NEEDS_DS_LOADED) ) {
HW_CTurnOn( state->parm.used, HW_DS );
}
if( _RoutineIsFar16( state->attr ) ) {
#if _TARGET & _TARG_80386
Far16Parms( call );
#endif
} else {
if( AssgnParms( call, in_line ) ) {
if( state->attr & ROUTINE_REMOVES_PARMS ) {
call_ins->flags.call_flags |= CALL_POPS_PARMS;
}
}
}
if( state->attr & (ROUTINE_MODIFIES_NO_MEMORY | ROUTINE_NEVER_RETURNS) ) {
/* a routine that never returns can not write any memory as far
as this routine is concerned */
call_ins->flags.call_flags |= CALL_WRITES_NO_MEMORY;
}
if( state->attr & ROUTINE_READS_NO_MEMORY ) {
call_ins->flags.call_flags |= CALL_READS_NO_MEMORY;
}
if( state->attr & ROUTINE_NEVER_RETURNS ) {
call_ins->flags.call_flags |= CALL_ABORTS;
}
if( _RoutineIsInterrupt( state->attr ) ) {
call_ins->flags.call_flags |= CALL_INTERRUPT | CALL_POPS_PARMS;
}
if( use_return == FALSE ) {
call_ins->flags.call_flags |= CALL_IGNORES_RETURN;
}
if( call_ins->type_class == XX ) {
reg_name = AllocRegName( state->return_reg );
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?