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 + -
显示快捷键?