s37enc.c

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

C
1,197
字号
/****************************************************************************
*
*                            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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "standard.h"
#include "coderep.h"
#include "typedef.h"
#include "opcodes.h"
#include "pattern.h"
#include "vergen.h"
#include "offset.h"
#include "model.h"
#include "s37bead.h"
#include "procdef.h"
#include "zoiks.h"
#include "cgaux.h"

#include "s37enc.def"
#ifndef NXDEBUG
extern  void            DumpInsOnly( instruction * );
extern  void            DumpString( char * );
extern  void            DumpPtr( pointer );
extern  void            DumpInt(int);
extern  void            DumpNL(void);
extern  void            DumpGen(struct opcode_entry*);
#endif
extern  name           *DeAlias(name*);
extern  void            HWInsGen( hwins_opcode hwop, hwins_op_any *op1,
                                         hwins_op_any *op2,
                                         hwins_op_any *op3);
extern  void            HWBRGen(char ,hwins_op_any *);
extern void             HWBIndexGen(char ,hw_sym *);

extern  ref_any        *HWSymRef( hw_sym  * );
extern  ref_any        *HWDispRef( hw_sym  *, hw_sym  * );
extern  ref_any        *HWLitIntGen( offset, int );
extern  ref_any        *HWLitFltGen( pointer, int );
extern ref_any         *HWLitAddr(hw_sym *,offset, bool );
extern bead_addr       *HWSymAddr(hw_sym *,offset ,bool );
extern  void            HWEntry(hw_sym *);
extern  void            HWExtern( hw_sym *);
extern void             HWLabelGen(hw_sym *,char );
extern  void            HWQueue(int );
extern  bool            AskIfRTLabel(label_handle);
extern  char           *AskRTName(int);

extern  sym_handle      AskForLblSym(label_handle);
extern  hw_sym         *AskForHWLabel( label_handle );
extern  hw_loc         *AskForBaseHW( label_handle );
extern  offset          AskAddress( label_handle );
extern  label_handle    AskForSymLabel( pointer, cg_class );
extern  char           *FEName(sym_handle);
extern  fe_attr         FEAttr(pointer);
extern  name           *AllocRegName(hw_reg_set);
extern  void            FlipCond(instruction*);
extern  int             Log2(unsigned_32);
extern  pointer         FEAuxInfo(pointer,int);
extern  void            PSBlip();
extern bool             MemNeedsReloc(pointer ,cg_class );
extern  void            AskRTRALN(int,char*,char*);

extern  proc_def        *CurrProc;
extern  type_length     TypeClassSize[];

static byte UCondTable[] = {
        7,              /* OP_BIT_TEST_TRUE*/
        8,              /* OP_BIT_TEST_FALSE*/
        8,              /* OP_CMP_EQUAL*/
        7,              /* OP_CMP_NOT_EQUAL*/
        2,              /* OP_CMP_GREATER*/
        13,             /* OP_CMP_LESS_EQUAL*/
        4,              /* OP_CMP_LESS*/
        11 };           /* OP_CMP_GREATER_EQUAL*/

static byte SCondTable[] = {
        7,              /* OP_BIT_TEST_TRUE*/
        8,              /* OP_BIT_TEST_FALSE*/
        8,              /* OP_CMP_EQUAL*/
        7,              /* OP_CMP_NOT_EQUAL*/
        2,              /* OP_CMP_GREATER*/
        13,             /* OP_CMP_LESS_EQUAL*/
        4,              /* OP_CMP_LESS*/
        11 };           /* OP_CMP_GREATER_EQUAL*/

typedef enum {
        UNSIGNED,
        SIGNED,
        SIGNED_BOTH
} issigned;

static issigned Signed[] = {
        UNSIGNED,       /* U1*/
        SIGNED_BOTH,    /* I1*/
        UNSIGNED,       /* U2*/
        SIGNED_BOTH,    /* I2*/
        UNSIGNED,       /* U4*/
        SIGNED_BOTH,    /* I4*/
        UNSIGNED,       /* CP*/
        UNSIGNED,       /* PT*/
        SIGNED,         /* FS*/
        SIGNED,         /* FD*/
        UNSIGNED };     /* XX*/


static hwins_opcode GtoHWTable[] = {

    HWOP_LAST, /* G_NO */
    #define _ENC_GHW( op )  HWOP##op,
    #include "ghw.h"
    #undef _ENC_GHW
    HWOP_LAST
};

#define MAXMAP sizeof( GtoHWTable )/sizeof(hwins_opcode)


extern  void    GenObjCode( instruction *ins )  {
/********************************************/

    gentype         gen;
    hwins_opcode    hwins;
    name           *result;
    name           *left;
    name           *right;
    type_class_def  tipe;

    PSBlip();

#ifndef NXDEBUG
    if( _IsModel( INTERNAL_DBG_OUTPUT ) ) { /* debug dump */
        DumpString( "        " );
        DumpGen( ins->u.gen_table );
        DumpString( " - " );
        DumpInsOnly( ins );
        DumpNL();
    }
#endif
    gen = ins->u.gen_table->generate;
    tipe = ins->type_class;
    if( gen != G_NO ) {
        result = ins->result;
        if( ins->num_operands != 0 ) {
            left = ins->operands[ 0 ];
            if( ins->num_operands != 1 ) {
                right = ins->operands[ 1 ];
            }
        }
        if( gen < MAXMAP ) {
            hwins = GtoHWTable[ gen ];
        }
        switch( gen ) {
        case G_AR: /* GPR result right */
        case G_ALR:
        case G_DR:
        case G_MR:
        case G_NR:
        case G_SR:
        case G_SLR:
        case G_XR:
        case G_OR:
            GenRR( hwins, result, right );
            break;
        case G_A: /* GPR RX result right */
        case G_AL:
        case G_D:
        case G_M:
        case G_O:
        case G_N:
        case G_S:
        case G_SL:
        case G_X:
            GenRX( hwins, result, right );
            break;
        case G_AH:/* GPR RX I2 result right */
        case G_MH:
        case G_SH:
            GenRXH( hwins, result, right );
            break;
        case G_SLA:
        case G_SLL:
        case G_SRA:
        case G_SRL:
            GenShift( hwins, result, right );
            break;
        case G_CR: /* GPR RR left right */
        case G_CLR:
            GenRR( hwins, left, right );
            break;
        case G_CH: /* GPR RX I2 left right */
            GenRXH( hwins, left, right );
            break;
        case G_C: /* GPR RX left right */
        case G_CL:
            GenRX( hwins, left, right );
            break;
        case G_CLI:/* SI left right */
            GenSI( hwins, left, right );
            break;
        case G_CLC:/* SS left right */
            GenSS( hwins, left, right, tipe );
            break;
        case G_LH: /* GPR I2 result left */
            GenRXH( hwins, result, left );
            break;
        case G_L: /* GPR RX result, left */
        case G_LA:
        case G_IC:
            GenRX( hwins, result, left );
            break;
        case G_LR:
        case G_LTR:/* GPR RR result left */
        case G_LCR:
        case G_LNR:
        case G_LPR:
            GenRR( hwins, result, left );
            break;
        case G_MVC:/* SS result left */
            GenSS( hwins, result, left, tipe );
            break;
        case G_NC:/* SS result right */
        case G_OC:
        case G_XC:
            GenSS( hwins, result, right, tipe );
            break;
        case G_MVI:/* SI result left */
            GenSI( hwins, result, left );
            break;
        case G_NI:/* SI result, right */
        case G_OI:
        case G_XI:
            GenSI( hwins, result, right );
            break;
        case G_STC:/* GPR RX left result */
        case G_ST:
            GenRX( hwins, left, result );
            break;
        case G_STH: /* GPR I2 left, result */
            GenRXH( hwins, left, result );
            break;
        case G_CLRR:
            GenCLRR( ins->type_class, result );
            break;
        case G_RS_DSHFT:
            break;
        case G_SCONV1 :
            GenRmS( HWOP_ICM, result, 0x8, left );
            GenRDisp( HWOP_SRA, result, 0, 24 );
            break;
        case G_SCONV8 :
            GenRDisp( HWOP_SRDA, result, 0, 32 );
            break;
        case G_UCONV1 :
            GenUConv1( result, left );
            break;
        case G_UCONV2 :
            GenUConv2( result, left );
            break;
        case G_LA1 :
            GenRDisp( HWOP_LA, result, 0, left->c.int_value );
            break;
        case G_LA2 :
            GenRDisp( HWOP_LA, result, RegOp(left), right->c.int_value );
            break;
        case G_LTZ:
            GenRR( HWOP_LTR, left, left );
            break;
        case G_CALL:
            GenCall( ins );
            break;
        case G_ICALL:
            if( ins->operands[ CALL_OP_ADDR ]->n.class == N_REGISTER ) {
                GenRCall( ins );
            } else {
                GenICall( ins );
            }
            break;
        case G_AXR:  /* FPR RR result right*/
        case G_ADR:
        case G_AER:
        case G_AWR:
        case G_AUR:
        case G_DDR:
        case G_DER:
        case G_MXR:
        case G_MDR:
        case G_MXDR:
        case G_MER:
        case G_SXR:
        case G_SDR:
        case G_SER:
        case G_SWR:
        case G_SUR:
            GenRR( hwins, result, right );
            break;
        case G_AE: /* FPR RX SHORT result right */
        case G_AU:
        case G_DE:
        case G_ME:
        case G_SE:
        case G_SU:
            GenRFX( hwins, result, right, FS );
            break;
        case G_AD: /* FPR RX LONG result right */
        case G_AW:
        case G_DD:
        case G_MD:
        case G_MXD:
        case G_SD:
        case G_SW:
            GenRFX( hwins, result, right, FD );
            break;
        case G_CDR: /* FPR RR left right */
        case G_CER: /* FPR RR left right */
            GenRR( hwins, left, right );
            break;
        case G_CE : /* FPR RX SHORT left right */
            GenRFX( hwins, left, right, FS );
            break;
        case G_CD : /* FPR RX LONG left right */
            GenRFX( hwins, left, right, FD );
            break;
        case G_LDR : /* FPR RR result  left */
        case G_LTDR:
        case G_LCDR:
        case G_LNDR:
        case G_LPDR:
        case G_LER :
        case G_LCER:
        case G_LNER:
        case G_LPER:
        case G_HDR:
        case G_HER:
            GenRR( hwins, result, left );
            break;
        case G_LE  : /* FPR RX SHORT  result left */
            GenRFX( hwins, result, left, FS );
            break;
        case G_LD  : /* FPR RX LONG result left */
            GenRFX( hwins, result, left, FD );
            break;
        case G_STE : /* FPR RX SHORT left result */
            GenRFX( hwins, left, result, FS );
            break;
        case G_STD : /* FPR RX LONG left result */
            GenRFX( hwins, left, result, FD );
            break;
        case G_LTEZ:
            GenRR( HWOP_LTER, left, left );
            break;
        case G_LTDZ:
            GenRR( HWOP_LTDR, left, left );
            break;
        case G_BCTR:
            GenRR( hwins, result, AllocRegName( HW_G0 ) );
            break;
        case G_MVCL:
            GenMVCL( hwins, result->i.index, left->i.index );
            break;
        case G_DIVPOW2:
            GenPow2Div( result, right );
            break;
        case G_TM:
            GenSI( hwins, left, right );
            break;
        case G_SELECT:
            GenSelect( left );
            break;
        case G_MEMDOWN:

⌨️ 快捷键说明

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