sslgen.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 589 行 · 第 1/2 页
C
589 行
for( ;; ) {
if( ins == NULL ) return( change );
next = ins->flink;
if( !dead_code ) break;
if( ins->ins == INS_LABEL ) break;
DelStream( ins );
ins = next;
change = 1;
}
dead_code = 0;
switch( ins->ins & INS_MASK ) {
case INS_JUMP:
for( dest = ins->ptr; dest->ins == INS_LABEL; dest = dest->flink )
;
switch( dest->ins & INS_MASK ) {
case INS_KILL:
/* jump to kill */
next = NewIns( dest->ins );
next->operand = dest->operand;
AddStream( ins, next );
DelStream( ins );
next = next->flink;
change = 1;
break;
case INS_RETURN:
/* jump to return */
next = NewIns( INS_RETURN );
AddStream( ins, next );
DelStream( ins );
next = next->flink;
change = 1;
break;
case INS_JUMP:
/* jump to jump */
if( ins == dest ) {
next = NewIns( INS_KILL );
next->operand = 0;
AddStream( ins, next );
DelStream( ins );
next = next->flink;
} else {
((instruction *)ins->ptr)->operand--;
ins->ptr = dest->ptr;
((instruction *)ins->ptr)->operand++;
}
change = 1;
break;
}
dead_code = 1;
break;
case INS_CALL:
dest = ins->ptr;
if( dest->location == NO_LOCATION ) break;
for( ; dest->ins == INS_LABEL; dest = dest->flink ) {
}
switch( dest->ins & INS_MASK ) {
case INS_KILL:
/* call to kill */
dead_code = 1;
next = NewIns( dest->ins );
next->operand = dest->operand;
AddStream( ins, next );
DelStream( ins );
change = 1;
break;
case INS_RETURN:
/* call to return */
DelStream( ins );
change = 1;
break;
case INS_JUMP:
/* call to jump */
((instruction *)ins->ptr)->operand--;
ins->ptr = dest->ptr;
((instruction *)ins->ptr)->operand++;
change = 1;
break;
default:
for( dest = ins->flink;
dest->ins == INS_LABEL;
dest = dest->flink )
;
if( dest->ins == INS_RETURN ) {
/* call followed by a return */
ins->ins = INS_JUMP;
change = 1;
dead_code = 1;
}
break;
}
break;
case INS_RETURN:
dead_code = 1;
break;
case INS_KILL:
dead_code = 1;
break;
case INS_LABEL:
/* dead label */
if( ins->operand == 0 ) {
DelStream( ins );
change = 1;
}
break;
}
}
}
static unsigned Locate(void)
{
instruction *ins;
unsigned loc;
loc = 0;
for( ins = FirstIns; ins != NULL; ins = ins->flink ) {
ins->location = loc;
switch( ins->ins & INS_MASK ) {
case INS_RETURN:
case INS_IN_ANY:
loc += sizeof( char );
break;
case INS_INPUT:
case INS_ERROR:
case INS_OUTPUT:
loc += sizeof( char ) + sizeof( char );
if( ins->ins & INS_LONG ) loc += sizeof( char );
break;
case INS_JUMP:
case INS_CALL:
loc += sizeof( char ) + sizeof( char );
if( ins->ins & INS_LONG ) loc += sizeof( char );
break;
case INS_IN_CHOICE:
case INS_CHOICE:
loc += sizeof( char ) + sizeof( char ) + ins->operand *
( sizeof( char ) + sizeof( unsigned short ) );
if( ins->ins & INS_LONG ) loc += ins->operand * sizeof( char );
break;
case INS_SET_RESULT:
case INS_SET_PARM:
loc += sizeof( char ) + sizeof( char );
if( ins->ins & INS_LONG ) loc += sizeof( char );
break;
case INS_SEMANTIC:
loc += sizeof( char ) + sizeof( char );
if( ins->ins & INS_LONG ) loc += sizeof( char );
break;
case INS_KILL:
loc += sizeof( char ) + sizeof( char );
if( ins->ins & INS_LONG ) loc += sizeof( char );
break;
case INS_LABEL:
loc += 0;
break;
}
}
return( loc );
}
static char Expand(void)
{
instruction *ins;
instruction *dest;
signed int diff;
char change;
change = 0;
for( ins = FirstIns; ins != NULL; ins = ins->flink ) {
switch( ins->ins ) {
case INS_JUMP: /* short form */
case INS_CALL: /* short form */
dest = ins->ptr;
diff = dest->location - ins->location;
if( diff != (signed char) diff ) {
ins->ins |= INS_LONG; /* change to long form */
change = 1;
}
break;
}
}
return( change );
}
extern void GenCode(void)
{
while( Optimize() )
;
do {
Locate();
} while( Expand() );
}
static void OutOper( instruction *ins )
{
if( ins->ins & INS_LONG ) {
OutWord( ins->operand );
} else {
OutByte( ins->operand );
}
}
static void OutDisp( instruction *ins )
{
int disp;
disp = ((instruction *)ins->ptr)->location - ins->location;
if( ins->ins & INS_LONG ) {
OutWord( disp );
} else {
OutByte( disp );
}
}
void DumpGenCode(void)
{
instruction *ins;
instruction *next;
choice_entry *choice;
OutStartSect( "Code", Locate() );
for( ins = FirstIns; ins != NULL; ins = next ) {
next = ins->flink;
if( ins->ins != INS_LABEL ) OutByte( ins->ins );
Dump( "[%.4x] %c ", ins->location, (ins->ins & INS_LONG) ? 'L' : 'S' );
switch( ins->ins & INS_MASK ) {
case INS_INPUT:
Dump( "INPUT: %d\n", ins->operand );
OutOper( ins );
break;
case INS_IN_ANY:
Dump( "IN_ANY\n" );
break;
case INS_OUTPUT:
Dump( "OUTPUT: %d\n", ins->operand );
OutOper( ins );
break;
case INS_ERROR:
Dump( "ERROR: %d\n", ins->operand );
OutOper( ins );
break;
case INS_JUMP:
Dump( "JUMP L%.4x\n", ((instruction *)ins->ptr)->location );
OutDisp( ins );
break;
case INS_CALL:
Dump( "CALL L%.4x\n", ((instruction *)ins->ptr)->location );
OutDisp( ins );
break;
case INS_SET_RESULT:
Dump( "SET RES: %d\n", ins->operand );
OutOper( ins );
break;
case INS_RETURN:
Dump( "RETURN\n" );
break;
case INS_IN_CHOICE:
case INS_CHOICE:
Dump( "%sCHOICE: %d\n", (ins->ins == INS_IN_CHOICE) ? "IN_" : "",
ins->operand );
OutByte( ins->operand );
for( choice = ins->ptr; choice != NULL; choice = choice->link ) {
Dump( " %4d L%.4x\n", choice->value,
choice->lbl->location );
if( ins->ins & INS_LONG ) {
OutWord( choice->value );
} else {
OutByte( choice->value );
}
OutWord( choice->lbl->location );
}
break;
case INS_SET_PARM:
Dump( "SET PARM: %d\n", ins->operand );
OutOper( ins );
break;
case INS_SEMANTIC:
Dump( "SEMANTIC: %d\n", ins->operand );
OutOper( ins );
break;
case INS_KILL:
Dump( "KILL: %d\n", ins->operand );
OutOper( ins );
break;
case INS_LABEL:
Dump( "LABEL: %d\n", ins->operand );
break;
}
DelStream( ins );
}
OutEndSect();
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?