s37proc.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 724 行 · 第 1/2 页
C
724 行
/****************************************************************************
*
* 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 "rtclass.h"
#include "offset.h"
#include "s37bead.h"
#include "zoiks.h"
#include "s37proc.def"
#define _4K (4*1024)
#define DWORD_SIZE (2*WORD_SIZE)
extern sym_handle AskForLblSym(label_handle);
extern void RelocParms();
extern hw_sym *CodeLabel(label_handle,unsigned);
extern unsigned DepthAlign(unsigned);
extern bead_drop *HWDrop(char);
extern bead_using *HWUsing(hw_sym *,char);
extern void CodeLineNum(unsigned_16);
extern seg_id SetOP(seg_id);
extern seg_id AskCodeSeg();
extern hw_reg_set SaveRegs();
extern hw_reg_set StackReg();
extern int RegTrans(hw_reg_set);
extern bool AdjustFarLocals(type_length);
extern void AdjustNearLocals(type_length);
extern ref_any *HWLitIntGen(offset,int);
extern hw_reg_set FixedRegs();
extern hw_reg_set LNReg();
extern void HWStartProc(void );
extern void HWEpilogue(void );
extern void HWEndProc(void );
extern void EmitRtnEnd();
extern memory_name *SAllocMemory(pointer,type_length,cg_class,type_class_def,type_length);
extern name *AllocAddrConst(name*,int,constant_class,type_class_def);
extern label_handle AskForNewLabel(void);
extern seg_id AskBackSeg(void);
extern void DataLabel(label_handle);
extern void DGUBytes(unsigned_32);
extern void GetOpName(hwins_op_any*,name*);
extern label_handle RTLabel(int);
extern bool FEStackChk(sym_handle);
extern void GetRALN(name*,char*,char*);
extern type_length FarLocalSize();
extern void HWInsGen( hwins_opcode hwop, hwins_op_any *op1,
hwins_op_any *op2,
hwins_op_any *op3);
/* debug */
extern void DumpString(char *);
extern void DumpNL();
extern block *HeadBlock;
extern proc_def *CurrProc;
extern bool BlockByBlock;
extern type_length MaxStack;
typedef struct {
hw_reg_set reg;
int i;
} float_save;
float_save FloatSave[] = {
/*****************************/
HW_D( HW_D0 ), 0,
HW_D( HW_D2 ), 2,
HW_D( HW_D4 ), 4,
HW_D( HW_D6 ), 6,
HW_D( HW_EMPTY ), 0
};
static hw_reg_set RegNames[] = {
/******************************/
HW_D( HW_G0 ),
HW_D( HW_G1 ),
HW_D( HW_G2 ),
HW_D( HW_G3 ),
HW_D( HW_G4 ),
HW_D( HW_G5 ),
HW_D( HW_G6 ),
HW_D( HW_G7 ),
HW_D( HW_G8 ),
HW_D( HW_G9 ),
HW_D( HW_G10 ),
HW_D( HW_G11 ),
HW_D( HW_G12 ),
HW_D( HW_G13 ),
HW_D( HW_G14 ),
HW_D( HW_G15 )
};
extern void GenProlog() {
/***************************/
seg_id old;
old = SetOP( AskCodeSeg() );
if( _IsModel( NUMBERS ) ) {
CodeLineNum( HeadBlock->ins.hd.line_num );
}
if( _IsModel( INTERNAL_DBG_OUTPUT ) ) {
DumpNL();
DumpString( "===================================" );
DumpNL();
}
HWStartProc();
CurrProc->targ.using_label = CodeLabel( CurrProc->label, DepthAlign( 1 ) );
CurrProc->parms.base = 0;
CalcUsedRegs();
MakeSaveArea();
RelocParms();
CurrProc->prolog_state |= GENERATED_PROLOG;
SetOP( old );
}
extern void CalcUsedRegs() {
/******************************/
block *blk;
instruction *ins;
name *result;
hw_reg_set used;
HW_CAsgn( used, HW_EMPTY );
blk = HeadBlock;
while( blk != NULL ) {
ins = blk->ins.hd.next;
while( ins->head.opcode != OP_BLOCK ) {
result = ins->result;
if( result != NULL && result->n.class == N_REGISTER ) {
HW_TurnOn( used, result->r.reg );
}
/* place holder for big label doesn't really zap anything*/
if( ins->head.opcode != OP_NOP ) {
HW_TurnOn( used, ins->zap->reg );
}
ins = ins->head.next;
}
blk = blk->next_block;
}
HW_TurnOn( CurrProc->state.used, used );
}
static void RefInt( hwins_op_any *hwop, offset i ) {
/******************************************************/
hwop->sx.a = 0;
hwop->sx.b = CurrProc->state.regs.LN;
hwop->sx.ref = HWLitIntGen( i, WORD_SIZE );
hwop->sx.disp = 0;
}
static long DWord( long x ) {
/*******************************/
return( ( x + ( DWORD_SIZE - 1 ) ) & ~( DWORD_SIZE - 1 ) );
}
static name *GetLabelAddress( hwins_op_any *phwop, label_handle lbl )
/******************************************************************/
{
name *mem;
name *cons;
mem = SAllocMemory( lbl, 0, CG_LBL, WD, WORD_SIZE );
cons = AllocAddrConst( mem, 0, CONS_ADDRESS, WD );
GetOpName( phwop, cons );
return( mem );
}
static void MakeStack( hwins_op_any *phwop )
/*****************************************/
{
seg_id old;
label_handle lbl;
old = SetOP( AskBackSeg() );
lbl = AskForNewLabel();
DataLabel( lbl );
DGUBytes( 72*WORD_SIZE );
SetOP( old );
GetLabelAddress( phwop, lbl );
}
#define SA_BACK_LINK 4
#define SA_FWD_LINK 8
#define SA_FIRST_REG 12
#define MAX_SA_WORDS 18
static int STMPos( int reg, int first_reg )
/*****************************************/
{
int position;
position = reg - first_reg;
if( position > 15 ) position -= 16;
if( position < 0 ) position += 16;
return( position );
}
static int RegPosOS( int reg, int first_reg )
/******************************************/
{
return( SA_FIRST_REG + WORD_SIZE * STMPos( reg, first_reg ) );
}
static int RegPosCLink( int reg, int first_reg )
/**********************************************/
{
return( WORD_SIZE * STMPos( reg, first_reg ) );
}
static void GetOSSTMOps( hwins_op_any *first_reg,
hwins_op_any *last_reg, hwins_op_any *sa_op )
/*****************************************************************/
{
sa_op->r = CurrProc->state.regs.SA;
first_reg->r = CurrProc->state.regs.SA + 1;
if( first_reg->r > 15 ) first_reg->r -= 16;
last_reg->r = CurrProc->state.regs.SA + 15;
if( last_reg->r > 15 ) last_reg->r -= 16;
}
static void RegOffset( hwins_op_any *hwop, int offset, char reg )
/***************************************************************/
{
hwop->sx.a = 0;
hwop->sx.b = reg;
hwop->sx.disp = offset;
hwop->sx.ref = NULL;
}
static void BranchAndLinkTo( int idx ) {
/**************************************/
hwins_op_any hwop;
hwins_op_any hwop2;
name *mem;
char ra,ln;
/*
L LN,=A(routine[idx]) - call routine to save/restore
BALR RA,LN registers 10 and 12
*/
mem = GetLabelAddress( &hwop, RTLabel( idx-BEG_RTNS ) );
GetRALN( mem, &ra, &ln );
hwop2.r = ln;
HWInsGen( HWOP_L, &hwop2, &hwop, NULL );
hwop.r = ra;
HWInsGen( HWOP_BALR, &hwop, &hwop2, NULL );
}
static bool NeedStackCheck()
/**************************/
{
return( FEStackChk( AskForLblSym( CurrProc->label ) ) );
}
static bool AddTo( hwins_op_any *reg_op, long amt )
/**************************************************/
{
hwins_op_any hwop;
if( amt == 0 ) return( FALSE );
if( amt < _4K ) {
RegOffset( &hwop, amt, reg_op->r );
HWInsGen( HWOP_LA, reg_op, &hwop, NULL );
} else {
RefInt( &hwop, amt );
HWInsGen( HWOP_A, reg_op, &hwop, NULL );
}
return( TRUE );
}
static bool SkipOverParms()
/************************/
{
hwins_op_any sp_op;
if( CurrProc->state.attr & ROUTINE_ALTERNATE_AR ||
CurrProc->targ.save_area >= _4K-(16*WORD_SIZE)-(4*DWORD_SIZE) ||
NeedStackCheck() ) {
sp_op.r = CurrProc->state.regs.SP;
/*
A SP,PARM_SIZE - bump SP past parms
*/
CurrProc->targ.save_area -= CurrProc->parms.size;
return( AddTo( &sp_op, CurrProc->parms.size ) );
}
return( FALSE );
}
static void StackCheck( int idx )
/*******************************/
{
hwins_op_any hwop;
hwins_op_any hwop2;
RefInt( &hwop2,
DWord( CurrProc->parms.size
+ CurrProc->locals.size
+ FarLocalSize() )
+ DWord( MAX_SA_WORDS*WORD_SIZE + 4*(DWORD_SIZE) )
+ DWord( MaxStack ) );
hwop.r = CurrProc->state.regs.AR;
HWInsGen( HWOP_L, &hwop, &hwop2, NULL );
BranchAndLinkTo( idx );
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?