s37obj.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,459 行 · 第 1/3 页

C
1,459
字号
extern hw_sym *HWSymLook( char  *name ) {
/******************************************************/
    hw_sym *curr;

    curr = HWSyms;
    while( curr != NULL ) {
        if( strcmp( name, curr->name )==0 ) break;
        curr = curr->next;
    }
    return( curr );
}

extern hw_sym *HWSymHandle(void ) {
/***Make a hw sym handle *********/
    hw_sym *curr;

    _Alloc( curr, sizeof( *curr ) );
    curr->name[0] = '\0';
    curr->class = HW_NONE;
    curr->defflag = TXT_NO;
    curr->def = NULL;
    curr->refs = NULL;
    curr->next = HWSyms;
    HWSyms = curr;
    return( curr );
}

extern hw_sym *HWFRefSym( char  *name ) {
/******************************************************/
    hw_sym *curr;

    curr = HWSymAdd( &HWSyms, name );
    return( curr );
}

static hw_sym *HWSymAdd( hw_sym **next_lnk, char *name ) {
/******************************************************/
    hw_sym *curr;

    curr = *next_lnk;
    while( curr != NULL ) {

        if( strcmp( name, curr->name )==0 ) break;
        next_lnk = &curr->next;
        curr = curr->next;
    }
    if( curr == NULL ) {
        _Alloc( curr, sizeof( *curr ) );
        strcpy( curr->name, name );
        curr->class = HW_NONE;
        curr->defflag = TXT_NO;
        curr->def = NULL;
        curr->refs = NULL;
        *next_lnk = curr;
        curr->next = NULL;
    }
    return( curr );
}

static void FreeHWSyms( hw_sym *sym  ){
/*********************************
    Free all those beads
*/
    hw_sym *next;

    while( sym != NULL ){
        next = sym->next;
        _Free( sym, sizeof( sym ) );
        sym = next;
    }
}
static bead_def *AddBead( bead_def *new, int size ) {
/******************************************************/
    /* add bead at end of list */
    new->address = CurrIndex->location;
    CurrIndex->location += size;
    new->next = NULL;
    *CurrIndex->end_lnk = new;
    CurrIndex->end_lnk = &new->next;
    return( new );
}

extern void HWLabelGen( hw_sym *sym, char align  ) {
/*********************************/
    bead_label *bead;

    sym->class = HW_LABEL;
    _Alloc( bead, sizeof( *bead ) );
    bead->common.class = BEAD_LABEL;
    bead->class = LBL_DS;
    bead->align = align;
    AddBead( (bead_def *)bead, 0 );
    bead->sym = sym;
    sym->def = (bead_def*)bead;
    sym->defflag = CurrIndex->txtseg;
}

extern hw_sym *HWMKPLabel( bead_def **end_lnk ) {
/***Insert Internal Label *********************/
    hw_sym     *sym;

    sym  = HWSymHandle();
    HWMKLabel( end_lnk, sym );
    return( sym );
}

extern void HWMKLabel( bead_def **end_lnk, hw_sym *sym ) {
/***Insert Internal Label *********************/
    bead_label *bead;

    sym->class = HW_LABEL;
    _Alloc( bead, sizeof( *bead ) );
    bead->common.class = BEAD_LABEL;
    bead->common.next = *end_lnk;
    bead->class = LBL_DS;
    bead->align = 2;
    *end_lnk = (bead_def*)bead;
    bead->sym = sym;
    sym->def = (bead_def*)bead;
    sym->defflag = TXT_CODE;
}

extern void HWExtern( hw_sym *sym ) {
/***************************/
    bead_xsym *bead;

    if( !(sym->defflag & CurrIndex->txtseg) ) { /*add extern to txtseg */
        bead = HWExSym( XSYM_EXTRN );  /* an EXTERN references a sym */
        sym->def = (bead_def *)bead;
        sym->class = HW_EXTERN;
        sym->defflag |= CurrIndex->txtseg;
        bead->sym = sym;
    }
}

extern void HWEntry( hw_sym *sym ) {
    bead_xsym *bead;

    bead = HWExSym( XSYM_ENTRY );/* an ENTRY references a sym */
    sym->defflag = CurrIndex->txtseg;
    sym->class = HW_ENTRY;
    bead->sym = sym;
}

extern bead_xsym *HWExSym( xsym_class class ) {
/*** Add a xsym to top of index_rec***********/
    bead_xsym *bead;

    _Alloc( bead, sizeof( *bead ) );
    bead->common.class = BEAD_XSYM;
    AddBead( (bead_def *)bead, 0 );
    bead->class = class;
    bead->sym = NULL;
    bead->id = 0;
    return( bead );
}

extern bead_xsym *HWMKExSym( bead_def **end_lnk, xsym_class class ) {
/*********************************************/
    bead_xsym *bead;

    _Alloc( bead, sizeof( *bead ) );
    bead->common.class = BEAD_XSYM;
    bead->common.address = 0;
    bead->common.next = *end_lnk;
    *end_lnk = (bead_def*)bead;
    bead->class = class;
    bead->sym = NULL;
    bead->id = 0;
    return( bead );
}

extern bead_using *HWUsing( hw_sym *sym, char reg ) {
/** set up using sym,reg if sym null *,reg **/
    bead_using *bead;

    _Alloc( bead, sizeof( *bead ) );
    bead->common.class = BEAD_USING;
    AddBead( (bead_def *)bead, 0 );
    bead->sym = sym;
    bead->reg = reg;
    return( bead );
}

extern void HWMKUsing( bead_def **end_lnk, hw_sym *sym, char reg ) {
/** set up using sym,reg if sym null *,reg **/
    bead_using *bead;

    _Alloc( bead, sizeof( *bead ) );
    bead->common.class = BEAD_USING;
    bead->common.next = *end_lnk;
    *end_lnk = (bead_def*)bead;
    bead->sym = sym;
    bead->reg = reg;
}

extern bead_drop *HWDrop( char reg ) {
/** drop base reg **/
    bead_drop *bead;

    _Alloc( bead, sizeof( *bead ) );
    bead->common.class = BEAD_DROP;
    AddBead( (bead_def *)bead, 0 );
    bead->reg = reg;
    return( bead );
}

extern void HWMKDrop(bead_def **end_lnk, char reg ) {
/** drop base reg **/
    bead_drop *bead;

    _Alloc( bead, sizeof( *bead ) );
    bead->common.class = BEAD_DROP;
    bead->common.next = *end_lnk;
    *end_lnk = (bead_def*)bead;
    bead->reg = reg;
}

extern void HWStartProc(void ) {
/** mark start of a routine **/
    bead_startproc *bead;

    _Alloc( bead, sizeof( *bead ) );
    bead->common.class = BEAD_STARTPROC;
    AddBead( (bead_def *)bead, 0 );
}

extern void HWEpilogue(void ) {
/** mark start of a routine **/
    bead_startproc *bead;

    _Alloc( bead, sizeof( *bead ) );
    bead->common.class = BEAD_EPILOGUE;
    AddBead( (bead_def *)bead, 0 );
}

extern void HWEndProc(void ) {
/** mark end  of a routine **/
    bead_endproc *bead;

    _Alloc( bead, sizeof( *bead ) );
    bead->common.class = BEAD_ENDPROC;
    AddBead( (bead_def *)bead, 0 );
}

extern void HWQueue( int num ) {
/** mark a place in code linenum whatever **/
    bead_queue *bead;

    _Alloc( bead, sizeof( *bead ) );
    bead->common.class = BEAD_QUEUE;
    bead->num = num;
    AddBead( (bead_def *)bead, 0 );
}

static bead_seg *MKSeg( char *str, seg_id id, char align ) {
/** mark a place in code where segment starts **/
    bead_seg *bead;

    _Alloc( bead, sizeof( *bead ) );
    bead->common.class = BEAD_SEG;
    bead->common.address = 0;
    bead->common.next = NULL;
    bead->str = str;
    bead->id = id;
    bead->align = align;
    return( bead );
}

extern void HWInsGen( hwins_opcode opcode, hwins_op_any *hwop1,
                                    hwins_op_any *hwop2,
                                    hwins_op_any *hwop3 )
/*** Add an instruction to current segment***************/
  {
    any_bead_hwins *bead;
    hwins_class    hwclass;


    HWMKInsGen( CurrIndex->end_lnk, opcode, hwop1, hwop2, hwop3 );

    bead = (any_bead_hwins*)*CurrIndex->end_lnk;
    bead->ins.common.address = CurrIndex->location;
    CurrIndex->end_lnk = &bead->ins.common.next;
    hwclass = HWOpTable[opcode].class;
    CurrIndex->location += HWOpICL[hwclass];

}

extern void HWMKInsGen( bead_def **end_lnk, hwins_opcode opcode,
                                    hwins_op_any *hwop1,
                                    hwins_op_any *hwop2,
                                    hwins_op_any *hwop3 )
/*** insert instruction at end_lnk**************************/
  {
    any_bead_hwins *bead;
    hwins_class    hwclass;

    hwclass = HWOpTable[opcode].class;
    _Alloc( bead, HwLength[hwclass] );
    bead->ins.common.class = BEAD_HWINS;
    bead->ins.common.next = *end_lnk;
    *end_lnk = (bead_def*)bead;

    bead->ins.opcode = opcode;
    bead->ins.class = hwclass;
    switch( hwclass ) {
    case HWINS_RR:
        bead->rr.r1 = hwop1->r;
        bead->rr.r2 = hwop2->r;
        break;
    case HWINS_RX:
        bead->rx.r1 = hwop1->r;
        bead->rx.s2 = hwop2->sx;
        break;
    case HWINS_RS1:
        bead->rs1.r1 = hwop1->r;
        bead->rs1.r3 = hwop3->r;
        bead->rs1.s2 = hwop2->sx;
        break;
    case HWINS_RS2:
        bead->rs2.r1 = hwop1->r;
        bead->rs2.s2 = hwop2->sx;
        break;
    case HWINS_SI:
        bead->si.s1 = hwop1->sx;
        bead->si.i2 = hwop2->i;
        break;
    case HWINS_S:
        bead->s.s2 = hwop2->sx;
        break;
    case HWINS_SS1:
        bead->ss1.s1 = hwop1->sx;
        bead->ss1.s2 = hwop2->sx;
        break;
    case HWINS_SS2:
        bead->ss2.s1 = hwop1->sx;
        bead->ss2.s2 = hwop2->sx;
        break;
    case HWINS_SSP: /* SRP is oddball */
        bead->ssp.s1 = hwop1->sx;
        bead->ssp.s2 = hwop2->sx;
        break;
    }
}

extern void HWBRGen(  char cc, hwins_op_any *hwop2 ) {
/*** add branch statement to segement ***************/
    bead_def       *bead;
    hwins_class     hwclass;

    HWMKBRGen( CurrIndex->end_lnk, cc, hwop2 );
    bead = *CurrIndex->end_lnk;
    bead->address = CurrIndex->location;
    CurrIndex->end_lnk = &bead->next;
    hwclass = HWOpTable[HWOP_BC].class;
    CurrIndex->location += HWOpICL[hwclass];
}

extern void HWMKBRGen(  bead_def **end_lnk, char cc, hwins_op_any *hwop2 ) {
/*** insert  branch at end_lnk***********************************************/
    bead_hwins_rx *bead;
    hwins_class    hwclass;
    ref_any       *ref;

    hwclass = HWOpTable[HWOP_BC].class;
    _Alloc( bead, HwLength[hwclass] );
    bead->common.class = BEAD_BR;
    bead->common.next = *end_lnk;
    *end_lnk = (bead_def*)bead;

    bead->opcode = HWOP_BC;
    bead->class = hwclass;
    bead->r1 = cc;
    bead->s2 = hwop2->sx;
    ref = hwop2->sx.ref;
    if( ref != NULL && ref->entry.class == REF_SYM ) {  /* fill ref in with bead  */
        ref->sym.use = (bead_def *)bead;
    }
}

extern void HWBIndexGen(  char reg, hw_sym *table ) {
/*** Add branch through reg that has table addr *****/
/*** Get's expanded later into some intructions**/
    bead_bindex     *bead;

    _Alloc( bead, sizeof( *bead ) );
    bead->common.class = BEAD_BINDEX;
    bead->size  = 2+4+4+4+4+4;
    /* AR, A,  AH, LH,  BC, =A(table)   */
    AddBead( (bead_def *)bead, bead->size  );

    bead->reg = reg;
    bead->br  = 0;
    bead->table = table;
    bead->lit = HWLitAddr( table, 0, FALSE );
}

extern void HWDataGen( int length, int rep, byte *value ) {
/****** do a DC value *********************/
    bead_data *bead;
    int bead_length;

    bead_length = sizeof( *bead ) +length-1;
    _Alloc( bead, bead_length );
    bead->common.class = BEAD_DATA;
    AddBead( (bead_def *)bead,length*rep );
    bead->length = length;
    bead->rep   = rep;
    memcpy( bead->value, value, length );
}

extern void HWStoreGen( int length ) {
/****** do a DS value *********************/
    bead_store *bead;

    _Alloc( bead, sizeof( *bead ) );
    bead->common.class = BEAD_STORE;
    AddBead( (bead_def *)bead, length );
    bead->length = length;
}

extern void HWIntGen( offset value, int size ) {
/****** do a DC on an int value *********/
    bead_int *bead;

    _Alloc( bead, sizeof( *bead ) );
    bead->common.class = BEAD_INT;
    AddBead( (bead_def *)bead, size );
    bead->size = size;
    bead->value = value;
}

extern void HWFltGen( pointer value, int size ) {
/**** add a float to the current segement ******/
    bead_flt *bead;

    bead = MakeAFlt( value, size );
    AddBead( (bead_def *)bead, size );

}

static bead_flt *MakeAFlt( pointer value, int size ) {
/****** do a DC on an float value *********/
    bead_flt *bead;

    _Alloc( bead, sizeof( *bead ) );
    bead->common.class = BEAD_FLT;
    bead->common.next = NULL;
    bead->common.address = 0;
    bead->size = size;
    bead->value = CFToF( value );
    return( bead );
}

static void HWMKAddrGen( bead_def **end_lnk, hw_sym *sym, offset val ) {
/*** Insert a DC A(sym+val) *************/
    bead_addr *bead;

    bead = MKSymAddr( sym, val, FALSE );
    bead->common.next = *end_lnk;
    *end_lnk = (bead_def*)bead;
}

extern void HWLTblGen( hw_sym *sym ) {
/****** start a label table for switch stmnt **********/
    HWLabelGen( sym, 2 );
}

extern void HWLblDisp( hw_sym *sym  ) {
/****** do a DC AL2(sym-base) for switch statement**/
    bead_disp *bead;

    _Alloc( bead, sizeof( *bead ) );
    bead->common.class = BEAD_DISP;
    AddBead( (bead_def *)bead, 2 );
    bead->val = 0;
    bead->ref = sym;
    bead->base = NULL; /* don't know base yet */
    bead->op_len = DISP_SUB|2;
}

extern ref_any  *HWSymRef( hw_sym *sym ) {
/***************************************/
    ref_sym *ref;

    _Alloc( ref, sizeof( *ref ) );
    ref->common.next = NULL;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?