sslgen.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 589 行 · 第 1/2 页
C
589 行
/****************************************************************************
*
* 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: Output generation routines for ssl.
*
****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include "ssl.h"
#include "sslint.h"
instruction *FirstIns;
instruction *LastIns;
static instruction *NewIns( op_code op )
{
instruction *ins;
ins = malloc( sizeof( instruction ) );
if( ins == NULL ) Error( "out of memory for instructions" );
ins->ins = op;
ins->flink = NULL;
ins->blink = NULL;
ins->ptr = NULL;
ins->operand = 0;
ins->location = NO_LOCATION;
return( ins );
}
static void CheckLong( instruction *ins )
{
if( (unsigned int)ins->operand != (unsigned char)ins->operand) {
ins->ins |= INS_LONG; /* change to long form of instruction */
}
}
static void AddStream( instruction *after, instruction *ins )
{
if( after == LastIns ) {
if( after != NULL ) after->flink = ins;
ins->blink = after;
ins->flink = NULL;
LastIns = ins;
if( FirstIns == NULL ) FirstIns = ins;
} else if( after == NULL ) {
ins->flink = FirstIns;
ins->blink = NULL;
FirstIns->blink = ins;
FirstIns = ins;
if( LastIns == NULL ) LastIns = ins;
} else {
ins->flink = after->flink;
ins->blink = after;
after->flink = ins;
ins->flink->blink = ins;
}
}
static void DelStream( instruction *ins )
{
choice_entry *tbl;
choice_entry *next;
if( ins == FirstIns ) {
FirstIns = ins->flink;
if( FirstIns != NULL ) {
FirstIns->blink = NULL;
} else {
LastIns = NULL;
}
} else if( ins == LastIns ) {
LastIns = ins->blink;
LastIns->flink = NULL;
} else {
ins->blink->flink = ins->flink;
ins->flink->blink = ins->blink;
}
switch( ins->ins & INS_MASK ) {
case INS_IN_CHOICE:
case INS_CHOICE:
for( tbl = ins->ptr; tbl != NULL; tbl = next ) {
next = tbl->link;
tbl->lbl->operand--; /* decrement label reference count */
free( tbl );
}
break;
case INS_JUMP:
case INS_CALL:
((instruction *)ins->ptr)->operand--;
break;
}
}
instruction *GenNewLbl(void)
{
return( NewIns( INS_LABEL ) );
}
void GenLabel( instruction *lbl )
{
lbl->location = 0;
AddStream( LastIns, lbl );
}
void GenExportLabel( instruction *lbl )
{
GenLabel( lbl );
lbl->operand++; /* so it never gets deleted */
}
void GenInput( unsigned value )
{
instruction *ins;
ins = NewIns( INS_INPUT );
ins->operand = value;
CheckLong( ins );
AddStream( LastIns, ins );
}
void GenInputAny( void )
{
AddStream( LastIns, NewIns( INS_IN_ANY ) );
}
void GenOutput( unsigned value )
{
instruction *ins;
ins = NewIns( INS_OUTPUT );
ins->operand = value;
CheckLong( ins );
AddStream( LastIns, ins );
}
void GenError( unsigned value )
{
instruction *ins;
ins = NewIns( INS_ERROR );
ins->operand = value;
CheckLong( ins );
AddStream( LastIns, ins );
}
void GenJump( instruction *lbl )
{
instruction *ins;
ins = NewIns( INS_JUMP );
ins->ptr = lbl;
lbl->operand++;
AddStream( LastIns, ins );
}
void GenReturn(void)
{
AddStream( LastIns, NewIns( INS_RETURN ) );
}
void GenSetParm( unsigned value )
{
instruction *ins;
ins = NewIns( INS_SET_PARM );
ins->operand = value;
CheckLong( ins );
AddStream( LastIns, ins );
}
void GenSetResult( unsigned value )
{
instruction *ins;
ins = NewIns( INS_SET_RESULT );
ins->operand = value;
CheckLong( ins );
AddStream( LastIns, ins );
}
void GenLblCall( instruction *lbl )
{
instruction *ins;
ins = NewIns( INS_CALL );
ins->ptr = lbl;
lbl->operand++;
AddStream( LastIns, ins );
}
void GenSemCall( unsigned num )
{
instruction *ins;
ins = NewIns( INS_SEMANTIC );
ins->operand = num;
CheckLong( ins );
AddStream( LastIns, ins );
}
instruction *GenInpChoice(void)
{
instruction *ins;
ins = NewIns( INS_IN_CHOICE );
AddStream( LastIns, ins );
return( ins );
}
instruction *GenChoice(void)
{
instruction *ins;
ins = NewIns( INS_CHOICE );
AddStream( LastIns, ins );
return( ins );
}
void GenTblLabel( instruction *choice, instruction *lbl, unsigned value )
{
choice_entry *new;
choice_entry **owner;
choice_entry *curr;
new = malloc( sizeof( choice_entry ) );
if( new == NULL ) Error( "no memory for choice entry" );
lbl->operand++;
new->value = value;
if( (unsigned int)value != (unsigned char)value ) {
choice->ins |= INS_LONG;
}
new->lbl = lbl;
owner = &choice->ptr;
for( ;; ) {
curr = *owner;
if( curr == NULL ) break;
if( curr->value > value ) break;
owner = &curr->link;
}
new->link = curr;
*owner = new;
choice->operand++;
}
void GenKill(void)
{
instruction *ins;
ins = NewIns( INS_KILL );
ins->operand = SrcLine();
CheckLong( ins );
AddStream( LastIns, ins );
}
static char Optimize(void)
{
char change;
instruction *ins;
instruction *next;
instruction *dest;
char dead_code;
dead_code = 0; /* want to keep code at location 0 */
change = 0;
for( ins = FirstIns; ; ins = next ) {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?