Milán Major

netscape-revival

1 branch
Code

sun-java/jit/win32/jcodegen.h

// $Header: /m/src/ns/sun-java/jit/win32/Attic/jcodegen.h,v 1.1.10.1 1996/09/29 20:54:07 jg Exp $ 
/*
 * Copyright (c) 1996 Borland International. All Rights Reserved.
 *
 * AppAccelerator(tm) for x86
 *
 * JCodeGen.h, R. Crelier, 1/29/96
 *
*/

/*
    Addressing modes.
    Note that the arrangement is such that the base register number
    is always the last three bits.
*/
typedef enum
{
    MR_NONE = -1,

    MR_EAX,		    /* AL, AX, EAX */
    MR_EDX,
    MR_ECX,
    MR_EBX,
    MR_ESI,
    MR_EDI,
    MR_EBP,
    MR_ESP,

    MR_INDIR,		    /* [reg]			    */

    MR_BASE = MR_INDIR + 8, /* [reg + disp]		    */

    MR_INX  = MR_BASE + 8,  /* [reg*scale + disp]	    */

    MR_BINX = MR_INX + 8,   /* [reg1 + reg2*scale + disp]   */

    MR_ABS  = MR_BINX + 8*8,/* [disp32] 		    */

    MR_IMM,		    /* Immediate		    */

    MR_FST,		    /* on floating point stack	    */

    MR_TOS,		    /* spilled to the stack	    */

    MR_FSABS,		    /* addressed via fs: (exception handling) */

    MR_CC,		    /* in condition code	    */

    MR_LAST,

}   ModReg;

#define IsByteReg(mr)	    ((mr) <= MR_EBX)
#define IsIntReg(mr)	    ((mr) <= MR_ESP)
#define IsCallerSaved(mr)   ((mr) <= MR_ECX)
#define IsIndir(mr)	    ((unsigned)((mr) - MR_INDIR) < 8)
#define IsBased(mr)	    ((unsigned)((mr) - MR_BASE)  < 8)
#define IsIndexed(mr)	    ((unsigned)((mr) - MR_INX)	 < 8)
#define IsBasedOrIndexed(mr)((unsigned)((mr) - MR_BASE)  < 16)
#define IsBasedIndexed(mr)  ((unsigned)((mr) - MR_BINX)  < 64)
#define IsRelMem(mr)	    ((unsigned)((mr) - MR_BASE)  < MR_ABS - MR_BASE)
#define IsMem(mr)	    ((unsigned)((mr) - MR_INDIR) < MR_IMM - MR_INDIR)
#define HasIndex(mr)	    ((unsigned)((mr) - MR_INX)	 < MR_ABS - MR_INX)
#define BaseRegOf(mr)	    ((mr) & 0x07)

#define ByteRange(l)	((long)(char)(l) == (l))

#define IsSubSet(s1,s2) (((s1) & ~(s2)) == 0)
#define IsPower(l)	(((l) & (l-1)) == 0)

#define RegOfMr(mr)	(regNumOfMr[mr])
#define RegSetOfMr(mr)	(regSetOfMr[mr])
#define MrFitsTarget(mr,t)  (targOfMr[mr] & (t))

#define IsByteAccessible(mr)	(!MrFitsTarget(mr, (RS_ALL - RS_BYTE)))


typedef unsigned    RegSet;

enum
{
    RS_EAX  = 1<<MR_EAX,
    RS_EDX  = 1<<MR_EDX,
    RS_ECX  = 1<<MR_ECX,
    RS_EBX  = 1<<MR_EBX,

    RS_ESI  = 1<<MR_ESI,
    RS_EDI  = 1<<MR_EDI,
    RS_EBP  = 1<<MR_EBP,
    RS_ESP  = 1<<MR_ESP,

    RS_BYTE	    = RS_EAX|RS_EDX|RS_ECX|RS_EBX,
    RS_ALL	    = RS_BYTE|RS_ESI|RS_EDI|RS_EBP|RS_ESP,
    RS_CALLEE_SAVED = RS_EBX|RS_ESI|RS_EDI |RS_EBP,
    RS_CALLER_SAVED = RS_EAX|RS_EDX|RS_ECX,

    RS_EMPTY= 0x0000,

};

/*
    this table finds the set of registers associated with an
    address mode. This is useful for freeing up registers
    used in address modes.
*/
extern	RegSet	regSetOfMr[MR_LAST];

/*
    this table gives the target register set corresponding
    to a given address mode. this is used for determining
    whether a given address mode fits a target.
*/
extern	RegSet	targOfMr[MR_LAST];

extern	char	lowestBit[256];
extern	char	bitCnt[256];


enum
{
    ADCI	= 0x10,     /* 2nd byte adc r/m,imm */
    ADCR	= 0x12,     /* adc r,r/m	    */
    ADDM	= 0x00,     /* add r/m,r	    */
    ADDR	= 0x02,     /* add r,r/m	    */
    ADDR_L	= 0x03,     /* add r32,r/m32	    */
    ADDI	= 0x00,     /* 2nd byte add r/m,imm */
    ADDI_AL	= 0x04,     /* add al,imm8	    */
    ADDI_EAX	= 0x05,     /* add eax,imm32	    */
    ADDIB_L	= 0x83,     /* add r/m32,imm8	    */
    ADDI_L	= 0x81,     /* add r/m32,imm32	    */
    ANDM	= 0x20,     /* and r/m,r	    */
    ANDR	= 0x22,     /* and r,r/m	    */
    ANDI	= 0x20,     /* 2nd byte add r/m,imm */
    BOUND	= 0x62,     /* bound		    */
    BT		= 0xA3,     /* 2nd byte of bt ,r    */
    BTR 	= 0xB3,     /* 2nd byte of btr ,r   */
    BTS 	= 0xAB,     /* 2nd byte of bts ,r   */
    BTSI	= 0xBA,     /* 2nd byte of bts ,imm */
    CALLI	= 0x10,     /* 2nd byte call r/m32  */
    CALLN	= 0xE8,     /* call rel32	    */
    CBW 	= 0x98,     /* cbw		    */
    CDQ 	= 0x99,     /* cdq		    */
    CWD 	= 0x99,     /* cwd		    */
    CMPI	= 0x38,     /* 2nd byte cmp r/m,imm */
    CMPI_AL	= 0x3C,     /* cmp al,imm	    */
    CMPR	= 0x3A,     /* cmp r,r/m	    */
    CMPSB	= 0xA6,     /* cmpsb		    */
    DEC2	= 0x08,     /* 2nd byte dec r/m     */
    DECR_L	= 0x48,     /* dec r32		    */
    DIV2	= 0x30,     /* 2nd byte div ax,r/m  */
    FABS	= 0xE1,     /* 2nd byte fabs	    */
    FADD	= 0x00,     /* 2nd byte fadd	    */
    FCHS	= 0xE0,     /* 2nd byte fchs	    */
    FCOMP	= 0x18,     /* 2nd byte fcomp	    */
    FDIV	= 0x30,     /* 2nd byte fdiv	    */
    FDIVR	= 0x38,     /* 2nd byte fdivr	    */
    FILD	= 0x00,     /* 2nd byte fild	    */
    FILD_Q	= 0x28,     /* 2nd byte fild qword  */
    FLD1	= 0xE8,     /* 2nd byte fld1	    */
    FLDLN2	= 0xED,     /* 2nd byte fldln2	    */
    FMUL	= 0x08,     /* 2nd byte fmul	    */
    FNSTSTWAX	= 0xE0,     /* 2nd byte fnstsw ax   */
    FPATAN	= 0xF3,     /* 2nd byte fpatan	    */
    FSQRT	= 0xFA,     /* 2nd byte fsqrt	    */
    FSSEG	= 0x64,     /* FS: segment override */
    FSUB	= 0x20,     /* 2nd byte fsub	    */
    FSUBR	= 0x28,     /* 2nd byte fsubr	    */
    FWAIT	= 0x9B,     /* fwait		    */
    FXCH1	= 0xC9,     /* 2nd byte fxch st(1)  */
    FYL2X	= 0xF1,     /* 2nd byte fyl2x	    */
    IDIV	= 0x38,     /* 2nd byte idiv ax,r/m */
    IMUL_AL	= 0x28,     /* 2nd byte imul r/m8   */
    IMUL	= 0xAF,     /* 2nd byte imul r,r/m  */
    IMULI	= 0x69,     /* imul r32,r/m32,imm32 */
    IMULIB	= 0x6B,     /* imul r32,r/m32,imm8  */
    INC2	= 0x00,     /* 2nd byte inc r/m     */
    INCR_L	= 0x40,     /* inc r32		    */
    JMPI	= 0x20,     /* jmp r/m32	    */
    JMPN	= 0xE9,     /* jmp rel32	    */
    JB		= 0x72,     /* jb rel8		    */
    JBE 	= 0x76,     /* jbe rel8 	    */
    JNB 	= 0x73,     /* jnb rel8 	    */
    JNO 	= 0x71,     /* jno rel8 	    */
    JNS 	= 0x79,     /* jns rel8 	    */
    JNZ 	= 0x75,     /* jnz rel8 	    */
    LEA_L	= 0x8D,     /* lea r32,mem	    */
    LEAVE	= 0xC9,     /* leave		    */
    LOADA_AL	= 0xA0,     /* mov al,r/m8	    */
    LOADI_B	= 0xB0,     /* mov r8,imm8	    */
    LOADI_L	= 0xB8,     /* mov r32,imm32	    */
    LOAD_B	= 0x8A,     /* mov r8,r/m8	    */
    LOAD_L	= 0x8B,     /* mov r32,r/m32	    */
    LOAD_SEG	= 0x8E,     /* mov seg,r/m32	    */
    MOVI	= 0xC6,     /* mov r/m8,imm8	    */
    MOVI_L	= 0xC7,     /* mov r/m32,imm32	    */
    MOVSB	= 0xA4,     /* movsb		    */
    MOVSD	= 0xA5,     /* movsd		    */
    NEG 	= 0x18,     /* 2nd byte neg r/m     */
    NOT2	= 0x10,     /* 2nd byte not r/m     */
    OPNDSIZE	= 0x66,     /* opnd size prefix     */
    ORM 	= 0x08,     /* or r/m,r 	    */
    ORR 	= 0x0A,     /* or r,r/m 	    */
    ORR_B	= 0x0A,     /* or r8,r/m8	    */
    ORI 	= 0x08,     /* 2nd byte or r/m,imm  */
    POP_L	= 0x00,     /* 2nd byte pop m32     */
    POPFD	= 0x9D,     /* popfd		    */
    POPR_L	= 0x58,     /* pop r32		    */
    PUSHFD	= 0x9C,     /* pushfd		    */
    PUSHR_L	= 0x50,     /* push r32 	    */
    PUSH_L	= 0x30,     /* 2nd byte push r/m32  */
    PUSHI_B	= 0x6A,     /* push imm8	    */
    PUSHI_L	= 0x68,     /* push imm32	    */
    REP 	= 0xF3,     /* rep		    */
    REPE	= 0xF3,     /* repe		    */
    REPNE	= 0xF2,     /* repne		    */
    RET 	= 0xC3,     /* ret		    */
    RETF	= 0xCB,     /* retf		    */
    RETP	= 0xC2,     /* ret imm16	    */
    SAHF	= 0x9E,     /* sahf		    */
    SAR 	= 0x38,     /* 2nd byte of sar	    */
    SBBI	= 0x18,     /* 2nd byte sbb r/m,imm */
    SBBR	= 0x1A,     /* sbb r,r/m	    */
    SBBR_L	= 0x1B,     /* sbb r32,r/m32	    */
    SCASB	= 0xAE,     /* scasb		    */
    SET 	= 0x90,     /* 2nd byte of set	    */
    SHL 	= 0x20,     /* 2nd byte of shl	    */
    SHR 	= 0x28,     /* 2nd byte of shr	    */
    STOREA_AL	= 0xA2,     /* mov r/m8,al	    */
    STORE_B	= 0x88,     /* mov r/m8,r8	    */
    STORE_L	= 0x89,     /* mov r/m32,r32	    */
    STORE_SEG	= 0x8C,     /* mov r/m32,seg	    */
    SUBM	= 0x28,     /* sub r/m,r	    */
    SUBR	= 0x2A,     /* sub r,r/m	    */
    SUBR_L	= 0x2B,     /* sub r32,r/m32	    */
    SUBI_AL	= 0x2C,     /* sub al,imm	    */
    SUBI	= 0x28,     /* 2nd byte sub r/m,imm */
    TESTI	= 0x00,     /* 2nd byte test r/m,imm*/
    TESTI_AL	= 0xA8,     /* test al,imm8	    */
    TESTM	= 0x84,     /* test r/m8,r8	    */
    XCHG_EAX	= 0x90,     /* xchg eax,r32	    */
    XCHG_B	= 0x86,     /* xchg r8,r/m8	    */
    XCHG_L	= 0x87,     /* xchg r32,r/m32	    */
    XORM	= 0x30,     /* xor r/m,r	    */
    XORR	= 0x32,     /* xor r,r/m	    */
    XORI	= 0x30,     /* 2nd byte xor r/m,imm */
    XORI_AL	= 0x34,     /* xor al,imm8	    */
    XORR_L	= 0x33,     /* xor r32,r/m32	    */
};

enum	RegisterEncoding
{
    RC_EAX  =	0x00,
    RC_ECX  =	0x01,
    RC_EDX  =	0x02,
    RC_EBX  =	0x03,
    RC_ESP  =	0x04,
    RC_EBP  =	0x05,
    RC_ESI  =	0x06,
    RC_EDI  =	0x07,

    RC_AL   =	0x00,
    RC_CL   =	0x01,
    RC_DL   =	0x02,
    RC_BL   =	0x03,
    RC_AH   =	0x04,
    RC_CH   =	0x05,
    RC_DH   =	0x06,
    RC_BH   =	0x07,
};

/* this table contains the register encoding */
extern char regMap[MR_ESP+1];

/* this table contains the register encoding shifted left three bits */
extern char reg3Map[MR_ESP+1];

/* this table facilitates encoding of address modes.	*/
/* the low byte contains part of the mod r/m byte,	*/
/* the high byte is the low 6 bits of the s-i-b byte	*/
/* bit 15 on means no s-i-b, -1 is illegal address mode */
unsigned short	sibModRmTab[MR_LAST];

enum	EncodingMask
{
    EM_REG	= 0x38,
    EM_MODRM	= 0xC7,
};

#ifdef	CC_NONE     // from wingdi.h
#undef	CC_NONE
#endif

typedef enum	CondCode
{
    CC_NONE = -1,

    CC_O    = 0x00,
    CC_NO   = 0x01,
    CC_B    = 0x02,
    CC_AE   = 0x03,
    CC_E    = 0x04,
    CC_NE   = 0x05,
    CC_BE   = 0x06,
    CC_A    = 0x07,
    CC_S    = 0x08,
    CC_NS   = 0x09,
    CC_PE   = 0x0A,
    CC_PO   = 0x0B,
    CC_L    = 0x0C,
    CC_GE   = 0x0D,
    CC_LE   = 0x0E,
    CC_G    = 0x0F,

    CC_JMP  = 0x10,
    CC_JSR  = 0x11,

}   CondCode;

extern CondCode swapCC[16];
extern CondCode xsgnCC[16];
extern CondCode highCC[16];
extern CondCode revhCC[16];

typedef struct CompEnv;
typedef struct Item;


void GenByte(struct CompEnv *ce, char b);
void Gen2Bytes(struct CompEnv *ce, char b1, char b2);
void Gen3Bytes(struct CompEnv *ce, char b1, char b2, char b3);
void GenByteLong(struct CompEnv *ce, char b1, long l2);
void Gen2BytesLong(struct CompEnv *ce, char b1, char b2, long l2);
void GenWord(struct CompEnv *ce, short w);
void GenLong(struct CompEnv *ce, long l);
void GenEA(struct CompEnv *ce, int r, struct Item *n);
int  GenSiz(struct CompEnv *ce, long siz);
void GenOpSizEA(struct CompEnv *ce, int byte1, int byte2, struct Item *n);
void GenOpSizReg(struct CompEnv *ce, int byte1, int byte2, ModReg mr, long siz);
void GenOpSizRegEA(struct CompEnv *ce, int byte1, ModReg mr, struct Item *n);
void GenOpSizRegReg(struct CompEnv *ce, int byte1, ModReg mr1, ModReg mr2, long siz);
void GenOpRegReg(struct CompEnv *ce, int byte1, ModReg mr1, ModReg mr2);
void GenFLoad(struct CompEnv *ce, struct Item *n);
void GenFStore(struct CompEnv *ce, struct Item *n, int dontPopFlag);
void GenFOpEA(struct CompEnv *ce, int byte2, int byte2reg, struct Item *n);
void GenRegRegMove(struct CompEnv *ce, ModReg dMr, ModReg sMr);
void GenAddImmRL(struct CompEnv *ce, ModReg mr, long val);
void GenLea(struct CompEnv *ce, ModReg mr, struct Item *n);
void GenIndirEA(struct CompEnv *ce, int byte1, int byte2, ModReg ptrReg, long off);
void GenImmVal(struct CompEnv *ce, long val, long siz);
void GenOpImmR(struct CompEnv *ce, int opimm, ModReg mr, long val, long siz);
void GenOpImm(struct CompEnv *ce, int opimm, struct Item *n, long val);
void GenSubImmRSetCC(struct CompEnv *ce, ModReg mr, long val, long siz);
void GenLoad(struct CompEnv *ce, ModReg dMr, struct Item *s);
void GenStore(struct CompEnv *ce, struct Item *d, ModReg sMr);
void GenExg(struct CompEnv *ce, ModReg mr1, ModReg mr2);
void GenCmpRegEA(struct CompEnv *ce, ModReg mr, struct Item *r);
void ShiftLeft(struct CompEnv *ce, ModReg mr, long power);
void ShiftRight(struct CompEnv *ce, ModReg mr, long power, long size, int signedFlag);

int PowerOf(unsigned long val);

void InitCodeGen(void);