dmose%mozilla.org 2ccab49e6d updating license boilerplate to xPL v1.1
git-svn-id: svn://10.0.0.236/trunk@52526 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-02 06:38:29 +00:00

382 lines
11 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
/*
x86Opcode.h
desantis
simon
NOTE:
This file is being phased out -- please do not add to it without speaking to simon
*/
#ifndef _X86OPCODE
#define _X86OPCODE
#include "CatchAssert.h"
#include <stdio.h>
#include "Fundamentals.h"
#include "LogModule.h"
class x86ArgumentList;
class x86ArgListInstruction;
//================================================================================
// enums
enum x86NoArgsCode
{
opCdq,
opBreak,
opSahf
};
enum x86DoubleOpCode
{
opMul,
opMovSxB,
opMovSxH,
opMovZxB,
opMovZxH
};
enum x86DoubleOpDirCode
{
raAdd,
raAdc,
raSub,
raSbb,
raAnd,
raOr,
raXor,
raCmp,
raLoadI,
raCopyI,
raStoreI,
raSaveReg,
raStoreB,
raStoreH
};
// Floating-point instructions in which one operand is a memory location.
// If there is a second operand, then it is implicitly the top of the FPU stack.
enum x86FloatMemoryType
{
fstp32, // TOS => 32-bit float memory. Pop FPU.
fstp64, // TOS => 64-bit double memory. Pop FPU.
fst32, // TOS => 32-bit float memory. (Don't pop FPU stack.)
fst64, // TOS => 64-bit double memory. (Don't pop FPU stack.)
fistp32, // Round(TOS) => 32-bit int memory. Pop FPU.
fistp64, // Round(TOS) => 64-bit long memory. Pop FPU.
fld32, // 32-bit float memory => Push on FPU stack
fld64, // 64-bit float memory => Push on FPU stack
fild32, // 32-bit int memory => convert to FP and push on FPU stack
fild64, // 64-bit long memory => convert to FP and push on FPU stack
fadd32, // Add TOS and 32-bit float memory => replace TOS
fadd64, // Add TOS and 64-bit double memory => replace TOS
fmul32, // Multiply TOS and 32-bit float memory => replace TOS
fmul64, // Multiply TOS and 64-bit double memory => replace TOS
fsub32, // Subtract TOS from 32-bit float memory => replace TOS
fsub64, // Subtract TOS from 64-bit double memory => replace TOS
fsubr32, // Subtract 32-bit float memory from TOS => replace TOS
fsubr64, // Subtract 64-bit double memory from TOS => replace TOS
fdiv32, // Divide TOS by 32-bit float memory => replace TOS
fdiv64, // Divide TOS by 64-bit double memory => replace TOS
fcomp32, // Compare TOS to 32-bit float memory, setting FPU flags, pop TOS
fcomp64 // Compare TOS to 64-bit double memory, setting FPU flags, pop TOS
};
// enums for the x96 conidtion code
enum x86ConditionCode
{
ccJO = 0x00,
ccJNO = 0x01,
ccJB = 0x02,
ccJNB = 0x03,
ccJE = 0x04,
ccJNE = 0x05,
ccJBE = 0x06,
ccJNBE = 0x07,
ccJS = 0x08,
ccJNS = 0x09,
ccJP = 0x0a,
ccJNP = 0x0b,
ccJL = 0x0c,
ccJNL = 0x0d,
ccJLE = 0x0e,
ccJNLE = 0x0f
};
/*================================================================================
x86 Opcodes
- Can be one byte or two bytes in length. If two bytes, the first byte is 0x0f.
- Can have bits to control:
- data flow direction(D),
- sign extension(S) // FIX pete, isn't this 'size' not 'sign'?
- conditions (cond), and
- register field
- opcode extensions (Reg).
- Can have an alternate (condensed) encoding which allows a single register operand to be encoded in the opcode.
*/
enum x86GPR
{
EAX = 0,
ECX = 1,
EDX = 2,
EBX = 3,
ESP = 4,
EBP = 5,
ESI = 6,
EDI = 7,
NOT_A_REG = 255
};
// bit masks
const int kRegfield_Mask = 0x38; // 0b00111000
const int kIs_Memory_Form_Mask = 0x40; // 0b01000000
const int kCondition_Code_Mask = 0x0f; // 0b00001111
const int kCondensed_Op_Mask = 0xf8; // 0b11111000
const int kIs_2_Byte_Mask = 0x80; // 0b10000000
const int kIs_16_Bit_Mask = 0x40; // 0b01000000
const int kExtension_Mask = 0x40; // 0b01000000
const int kPrefix_For_16_Bits = 0x66;
const int kPrefix_For_2_Byte = 0x0f; // 0b00001111
/*--------------------------------------------------------------------------------
Opcode Information
*/
struct x86OpcodeInfo
{
uint8 oiBaseOpcode; // generally the opcode, but can have additional info
uint8 oiOpcodeInformation; // additional info about opcode
char* oiText; // string for fake disassembly
};
extern x86OpcodeInfo iaInfo[];
enum x86ImmediateArithType
{
iaAddImm,
iaCmpImm,
iaJmp,
iaPushImm,
iaAndImm,
iaOrImm,
iaXorImm
};
extern x86OpcodeInfo eInfo[];
enum x86ExtendedType
{
eIDiv,
eDiv,
eMul,
eMoveImm,
ePush,
eSarImm,
eShrImm,
eShlImm,
eSar1,
eShr1,
eShl1,
eSarCl,
eShrCl,
eShlCl,
eNeg
};
extern x86OpcodeInfo ceInfo[];
enum x86CondensableExtendedType
{
ceInc,
ceDec,
ceMoveImm,
cePop
};
extern x86OpcodeInfo srmInfo[];
enum x86SpecialRegMemType
{
srmCmpImm0,
srm1NOTUSED,
srmMoveImm0,
srm3NOTUSED
};
//================================================================================
// Class Declarations
/*--------------------------------------------------------------------------------
x86Opcode -- encodes x86StandardType
Basic opcode
- 8 or 16 bits
- no toggable bits and
- does NOT have a register field opcode extension or alternate encoding.
*/
class x86Opcode
{
public:
virtual void opPrintPretty(LogModuleObject &f) { UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("%-9s", opInfo->oiText)); }
virtual uint8 opSize() { return( (opInfo->oiOpcodeInformation >> 7) + 1); }
virtual void opFormatToMemory(void* inStart, x86ArgumentList& /*inAL*/, x86ArgListInstruction& /*inInsn*/);
virtual bool opHasRegFieldExtension( x86ArgumentList& /*inAL*/, x86ArgListInstruction& /*inInsn*/ ) { return (false); }
virtual uint8 opGetRegFieldExtension() { assert(false); return 0; }
virtual bool opRegOperandCanBeCondensed() { return false; }
virtual void opReverseOperands() { assert(false); }
virtual void opSwitchToRegisterIndirect() { }
virtual bool opCanAccept1ByteImmediate() { assert(false); return false; }
virtual bool opCanAccept4ByteImmediate() { assert(false); return false; }
protected:
x86Opcode() {}
x86Opcode( x86ImmediateArithType inType ) { opInfo = &(iaInfo[inType]); }
x86Opcode( x86ExtendedType inType ) { opInfo = &(eInfo[inType]); }
x86Opcode( x86CondensableExtendedType inType ) { opInfo = &(ceInfo[inType]); }
x86Opcode( x86SpecialRegMemType inType ) { opInfo = &(srmInfo[inType]); }
x86OpcodeInfo* opInfo;
};
inline void x86Opcode::
opFormatToMemory(void* inStart, x86ArgumentList& /*inAL*/, x86ArgListInstruction& /*inInsn*/)
{
uint8* start = (uint8*) inStart;
if(opInfo->oiOpcodeInformation & kIs_2_Byte_Mask)
*start++ = kPrefix_For_2_Byte;
*start = opInfo->oiBaseOpcode;
}
/*--------------------------------------------------------------------------------
x86Opcode_Reg -- encodes x86EntendedType
- no switchable bits
- three bit opcode extension (stored in the REG field of the MODR/M byte)
*/
class x86Opcode_Reg :
public virtual x86Opcode
{
public:
x86Opcode_Reg ( x86ExtendedType inInfo ) : x86Opcode(inInfo) { }
virtual bool opHasRegFieldExtension( x86ArgumentList& /*inAL*/, x86ArgListInstruction& /*inInsn*/ ) { return true; }
virtual uint8 opGetRegFieldExtension() { return (kRegfield_Mask & opInfo->oiOpcodeInformation); }
virtual bool opCanAccept1ByteImmediate() { return ((0x02 & opInfo->oiOpcodeInformation) == 0x02); }
virtual bool opCanAccept4ByteImmediate() { return ((0x01 & opInfo->oiOpcodeInformation) == 0x01); }
protected:
x86Opcode_Reg() { }
};
/*--------------------------------------------------------------------------------
x86Opcode_Condensable_Reg -- encodes x86CondensableExtendedType
- no switchable bits
- three bit opcode extension (stored in the REG field of the MODR/M byte)
- alternate encoding which has a 5-bit opcode + 3-bit register operand
*/
class x86Opcode_Condensable_Reg :
public x86Opcode
{
public:
x86Opcode_Condensable_Reg ( x86CondensableExtendedType inInfo ) : x86Opcode(inInfo) { }
virtual bool opHasRegFieldExtension( x86ArgumentList& inAL, x86ArgListInstruction& inInsn );
virtual uint8 opGetRegFieldExtension() { return ((0x03 & opInfo->oiOpcodeInformation) << 3); }
virtual bool opCanAccept1ByteImmediate() { return false; }
virtual bool opCanAccept4ByteImmediate() { return true; }
virtual bool opRegOperandCanBeCondensed(){ return true; }
virtual uint8 opSize() { return 1; }
virtual void opFormatToMemory(void* inStart, x86ArgumentList& inAL, x86ArgListInstruction& inInsn);
};
/*--------------------------------------------------------------------------------
x86Opcode_ImmArith -- encodes x86ImmediateArithType
- must have sign/size bit which specifies 8 or 32 bits operand
- _possible_ three bit opcode extension (stored in the REG field of the MODR/M byte)
*/
class x86Opcode_ImmArith :
public x86Opcode
{
public:
x86Opcode_ImmArith( x86ImmediateArithType inInfo ) : x86Opcode( inInfo ) { }
virtual void opFormatToMemory( void* inStart, x86ArgumentList& /*inAL*/, x86ArgListInstruction& /*inInsn*/);
virtual bool opHasRegFieldExtension( x86ArgumentList& /*inAL*/, x86ArgListInstruction& /*inInsn*/ )
{ return (bool)((opInfo->oiOpcodeInformation >> 6) && 1); }
virtual uint8 opGetRegFieldExtension()
{ assert(kExtension_Mask & opInfo->oiOpcodeInformation); return (kRegfield_Mask & opInfo->oiOpcodeInformation); }
virtual bool opCanAccept1ByteImmediate() { return true; }
virtual bool opCanAccept4ByteImmediate() { return true; }
virtual void opSwitchToRegisterIndirect() { } // FIX can't do this for imul ???
protected:
x86Opcode_ImmArith() { }
};
/*--------------------------------------------------------------------------------
x86Opcode_SpecialRegMem -- x86SpecialRegMemType
- switches between
x86Opcode_Reg when operand is a memory argument, and
x86Opcode when operand is a register argument
*/
class x86Opcode_SpecialRegMem :
public x86Opcode_Reg // note not x86Opcode!
{
public:
x86Opcode_SpecialRegMem( x86SpecialRegMemType inType) :
x86Opcode(inType) { }
virtual bool opHasRegFieldExtension( x86ArgumentList& /*inAL*/, x86ArgListInstruction& /*inInsn*/ )
{
return((kIs_Memory_Form_Mask & opInfo->oiOpcodeInformation) == kIs_Memory_Form_Mask);
}
virtual uint8 opGetRegFieldExtension()
{
assert(kIs_Memory_Form_Mask & opInfo->oiOpcodeInformation);
return (kRegfield_Mask & opInfo->oiOpcodeInformation);
}
virtual void opSwitchToRegisterIndirect()
{
assert(!(kIs_Memory_Form_Mask & opInfo->oiOpcodeInformation));
opInfo++;
}
};
#endif // _X86OPCODE