s37page.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 928 行 · 第 1/2 页
C
928 行
op1 = NULL;
op2 = NULL;
switch( bead->ins.class ) {
case HWINS_RR:
break;
case HWINS_RX:
op1 = &bead->rx.s2;
break;
case HWINS_RS1:
op1 = &bead->rs1.s2;
break;
case HWINS_RS2:
op1 = &bead->rs2.s2;
break;
case HWINS_SI:
op1 = &bead->si.s1;
break;
case HWINS_S:
op1 = &bead->s.s2;
break;
case HWINS_SS1:
op1 = &bead->ss1.s1;
op2 = &bead->ss1.s2;
break;
case HWINS_SS2:
op1 = &bead->ss2.s1;
op2 = &bead->ss2.s2;
break;
}
if( op1 == NULL ){
return( NULL );
}
if( op1->ref != NULL && op1->ref->entry.class == REF_LIT ) {
return( op1->ref );
}
if( op2 == NULL ) {
return( NULL );
}
if( op2->ref != NULL && op2->ref->entry.class == REF_LIT ) {
return( op2->ref );
}
return( NULL );
}
static int CalcBackRefs( hw_sym *sym ) {
/* calc number of backward references to label */
offset address;
ref_sym *ref;
int count;
address = sym->def->address;
count = 0;
for( ref = &sym->refs->sym; ref != NULL; ref = ref->common.next ) {
if( ref->use->address > address ) {
count++;
}
}
return( count );
}
static void CodePages( page_entry *head, char br ) {
/****Dump out jumps literal etc*******/
page_entry *curr;
curr = head;
while( curr != NULL ){
DoLongJmps( curr, head, br );
DoIndexJmps( curr, head, br );
DoLits( &curr->pool, curr->code.end );
curr = curr->next;
}
}
static char FirstPage( page_entry *page ) {
/***find entry label and main base reg for function******/
bead_def *bead;
char br;
bead = page->code.start;
br = 0;
if( bead->class == BEAD_LABEL ){
page->usesym = ((bead_label*)bead)->sym;
}else{
Zoiks( ZOIKS_066 ); /* no entry point */
}
while( bead != page->code.end ) {
if( bead->class == BEAD_USING ) {
br = ((bead_using*)bead)->reg;
}
bead = bead->next;
}
return( br );
}
static void AddUsing( page_entry *page, bead_def *prev, char br ) {
/***Add Label if needed and using statement **/
bead_def *start;
while( page != NULL ) {
start = page->code.start;
if( start->class == BEAD_LABEL ){
page->usesym = ((bead_label*)start)->sym;
}else{
page->usesym = HWMKPLabel( &prev->next );
start = prev->next;
start->address = page->code.start_addr;
page->code.start = start;
}
HWMKUsing( &start->next, page->usesym, br );
prev = page->code.end;
page = page->next;
}
}
static void DoLongJmps( page_entry *page, page_entry *head, char br ) {
/***Dump out long branches to far away places*/
sym_list *lsyms;
hw_sym *jmplabel;
hw_sym *basesym;
bead_def *jmpvec;
int jmpdisp;
lsyms = page->refs.lsyms;
jmpvec = page->code.end;
if( !(jmpvec->class == BEAD_BR &&((bead_hwins_rx *)jmpvec)->r1 == 15 )){
/* need branch to next page */
if( page->next != NULL ) {
basesym = page->next->usesym;
AddLoadBase( &jmpvec->next, basesym, &page->pool, br );
jmpvec = jmpvec->next;
AddBCR( &jmpvec->next, br );
jmpvec = jmpvec->next;
}
}
if( lsyms != NULL ) {
jmplabel = HWMKPLabel( &jmpvec->next );
jmpvec = jmpvec->next;
}
jmpdisp = 0;
while( lsyms != NULL ) {
if( !lsyms->defined ) {
basesym = GetBaseFor( lsyms->sym, head );
IndirectRefs( lsyms->sym, &page->code, jmplabel, jmpdisp );
AddLoadBase( &jmpvec->next, basesym, &page->pool, br );
jmpvec = jmpvec->next;
AddFarJmp( &jmpvec->next, lsyms->sym, basesym, br );
jmpvec = jmpvec->next;
jmpdisp += PAGE_JMP_COST;
}
lsyms = lsyms->next;
}
page->code.end = jmpvec;
}
static void DoIndexJmps( page_entry *page, page_entry *head, char br ) {
/***Fixup index table for index jumps*************************/
bindex_list *bri_list;
bead_def *table;
bead_bindex *bri;
bool br_load;
bri_list = page->bri_list;
while( bri_list != NULL ) {
bri = bri_list->bri;
bri->br = br;
table = bri->table->def;
br_load = UpdateDisps( table, page->usesym, head );
ExpandBri( bri, br_load);
bri_list = bri_list->next;
}
}
static void AddFarJmp( bead_def **at, hw_sym *sym, hw_sym *base, char br ) {
hwins_op_any dst;
dst.sx.ref = HWDispRef( sym, base );
dst.sx.disp = 0;
dst.sx.a = 0;
dst.sx.b = br;
HWMKBRGen( at, 15, &dst );
}
static void AddBCR( bead_def **at, char br ) {
/*** to A BCR br *****************************/
hwins_op_any cc;
hwins_op_any dst;
cc.r = 15;
dst.r = br;
HWMKInsGen( at, HWOP_BCR, &cc, &dst, NULL );
}
static void AddLoadBase( bead_def **at, hw_sym *sym,
lit_pool *pool, char br ) {
hwins_op_any hwop1;
hwins_op_any hwop2;
hwop1.r = br;
hwop2.sx.ref = MakeLitAddr( pool, sym );
hwop2.sx.disp = 0;
hwop2.sx.a = 0;
hwop2.sx.b = 0;
HWMKInsGen( at, HWOP_L, &hwop1, &hwop2, NULL );
}
static ref_lit *MakeLitAddr( lit_pool *pool, hw_sym *sym ) {
/*** Add litaddr of sym to pool ***************************/
ref_lit *lit;
bead_def *litdef;
lit = HWLitAddr( sym, 0, FALSE );
lit->common.next = NULL;
litdef = FindLit( pool->head, lit->val );
if( litdef != NULL ) {
lit->def = litdef;
}else { /* then value is def */
litdef = lit->val;
litdef->next = NULL;
lit->def = litdef;
*pool->end_lnk = litdef;
pool->end = litdef;
pool->end_lnk = &litdef->next;
}
return( lit );
}
static hw_sym *GetBaseFor( hw_sym *sym, page_entry *page_list ) {
/* find the using sym for page where sym is defined in */
offset address;
address = sym->def->address;
while( address > page_list->code.end_addr ) {
page_list = page_list->next;
}
return( page_list->usesym );
}
static void IndirectRefs( hw_sym *sym, code_entry *code,
hw_sym *label, int disp ) {
/** Adjust refs of symbol in page to indirect to jmp table */
ref_sym *refs;
ref_sym **end_lnk;
bead_def *use;
end_lnk = &sym->refs;
refs = *end_lnk;
while( refs != NULL ) {
use = refs->use;
if( use->address >= code->start_addr
&& use->address < code->end_addr ) {
*end_lnk = refs->common.next;
refs->sym = label;
refs->common.next = label->refs;
label->refs = refs;
((bead_hwins_rx*)use)->s2.disp = disp;
}else {
end_lnk = &refs->common.next;
}
refs = *end_lnk;
}
}
static void DoLits( lit_pool *pool, bead_def *end ) {
/** Dump literals out************************/
bead_ltorg *ltorg;
if( pool->head != NULL ) {
ltorg = _Alloc( ltorg, sizeof( *ltorg ) );
ltorg->common.class = BEAD_LTORG;
*pool->end_lnk = NULL; /* snip pool at end */
ltorg->align = SortLitPool( pool );
*pool->end_lnk = end->next; /* link to rest of beads */
ltorg->common.next = pool->head;
ltorg->end = pool->end;
end->next = (bead_def*)ltorg;
}
}
static bool UpdateDisps( bead_def *table, hw_sym *curr_base, page_entry *head ){
/*** Update disp addr with base symbol where table used **/
hw_sym *base;
bool expand;
bead_disp *disp;
bead_disp *bead;
expand = FALSE;
disp = (bead_disp *)table->next;
while( disp != NULL && disp->common.class == BEAD_DISP ) {
base = GetBaseFor( disp->ref, head );
disp->base = base;
if( curr_base != base ) {
expand = TRUE;
}
disp = (bead_disp *)disp->common.next;
}
if( expand ) {
disp = (bead_disp *)table->next;
while( disp != NULL && disp->common.class == BEAD_DISP ) {
_Alloc( bead, sizeof( *bead ) );
bead->common.class = BEAD_DISP;
bead->val = 0;
bead->ref = disp->base;
bead->base = curr_base;
bead->op_len = DISP_SUB|2;
bead->common.next = (bead_def *)disp;
table->next = (bead_def *)bead;
table = (bead_def *)disp;
disp = (bead_disp *)disp->common.next;
}
}
return( expand );
}
static void ExpandBri( bead_bindex *bri, bool br_load){
/**** Expand Index macro into AH's and branches**/
bead_def *curr_ins;
hwins_op_any hwop1;
hwins_op_any hwop2;
curr_ins = (bead_def *)bri;
hwop1.r = bri->reg;
if( br_load ) {
HWMKInsGen( &curr_ins->next, HWOP_AR, &hwop1, &hwop1, NULL );
curr_ins = curr_ins->next;
}
hwop2.sx.ref = bri->lit;
hwop2.sx.disp = 0;
hwop2.sx.a = 0;
hwop2.sx.b = 0;
HWMKInsGen( &curr_ins->next, HWOP_A, &hwop1, &hwop2, NULL );
curr_ins = curr_ins->next;
if( br_load ) {
hwop1.r = bri->br;
hwop2.sx.b = bri->reg;
hwop2.sx.ref = NULL;
hwop2.sx.a = 0;
hwop2.sx.disp = 0;
HWMKInsGen( &curr_ins->next, HWOP_AH, &hwop1, &hwop2, NULL );
curr_ins = curr_ins->next;
hwop2.sx.disp = 2;
}else{
hwop2.sx.disp = 0;
}
hwop1.r = bri->reg;
hwop2.sx.b = bri->reg;
hwop2.sx.ref = NULL;
hwop2.sx.a = 0;
HWMKInsGen( &curr_ins->next, HWOP_LH, &hwop1, &hwop2, NULL );
curr_ins = curr_ins->next;
hwop2.sx.ref = NULL;
hwop2.sx.disp = 0;
hwop2.sx.a = bri->reg;
hwop2.sx.b = bri->br;
HWMKBRGen( &curr_ins->next, 15, &hwop2 );
bri->size = 0;
}
static page_entry *PageInit( bead_def *bead ) {
/**** Init page entry to start state *********/
page_entry *page;
_Alloc( page, sizeof( *page ) );
page->next = NULL;
page->size = 8; /* lit pool alignment adjustment */
page->usesym = NULL;
page->code.start = bead;
page->code.start_addr = bead->address;
page->code.end = bead;
page->code.end_addr = bead->address;
page->refs.frefs = 0;
page->refs.brefs = 0;
page->refs.lsyms = NULL;
page->pool.head = NULL;
page->pool.end = NULL;
page->pool.end_lnk = &page->pool.head;
page->pool.size = 8; /* lit pool adjustment */
page->bri_list = NULL;
return( page );
}
static void FreePages( page_entry *page ) {
/*****************************************
Free a page and all it's trash
*/
while( page != NULL ){
page_entry *next;
/*** free syms ***/
{
sym_list *lsyms, *next;
for( lsyms = page->refs.lsyms; lsyms != NULL; lsyms = next ){
next = lsyms->next;
_Free( lsyms, sizeof( *lsyms ) );
}
}
/*** free index branch ***/
{
bindex_list *bri_list, *next;
for( bri_list = page->bri_list; bri_list != NULL; bri_list = next ){
next = bri_list->next;
_Free( bri_list, sizeof( *bri_list ) );
}
}
next = page->next;
_Free( page, sizeof( *page ) );
page = next;
}
}
extern void HWShortRef( bead_startproc *list ){
/**********************************************
convert any L r,=(A) to LA r,A if in range
*/
#if 0
bead_def *bead, *endproc, **lnk;
ref_lit *lit;
bead_def *litdef;
hw_sym *using;
using = NULL;
while( list != NULL ){
lnk = &list->common.next;
endproc = (bead_def *)list->endproc;
while( (bead = *lnk) != endproc ){
if( bead->class == BEAD_USING ) {
using = ((bead_using*)bead->sym;
}else if( bead->class == BEAD_HWINS ) {
if( ((any_bead_hwins*)bead)->ins.op == HWOP_L ){
lit = GetLit( (any_bead_hwins *) bead );
litdef = lit->value;
if( litdef->class == BEAD_ADDR ){
InRange( using->sym, (bead_addr*)litdef, bead );
}
}
}
lnk = &bead->next;
}
list = list->prev;
}
#endif
}
#if 0
static void InRange( hw_sym *base, bead_addr *acon, bead_hwins_rx *ins ){
/****************************************************
is the acon in range of base sym so we can do a LA
*/
hw_sym *sym;
sym = acon->ref;
if( sym->class != HW_EXTERN ){
}
}
#endif
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?