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

241 lines
5.9 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):
*/
//
// File: x86Formatter.cpp
//
// Authors: Peter DeSantis
// Simon Holmes a Court
// Scott Silver
//
#include "x86Formatter.h"
#include "FieldOrMethod.h"
#include "MemoryAccess.h"
#include "JavaObject.h"
//-----------------------------------------------------------------------------------------------------------
// Constants
const Uint8 kPush_ebp = 0x55;
const Uint8 kPush_edi = 0x57;
const Uint8 kPush_esi = 0x56;
const Uint8 kPush_ebx = 0x53;
const Uint16 kMov_ebp_esp = 0x8bec;
const Uint16 kSub_esp_Imm8 = 0x83ec; // 8-bit immediate subtract (8-bit val extended to 32-bits)
const Uint16 kSub_esp_Imm32 = 0x81ec; // Signed, 32-bit immediate subtract
const Uint8 kPop_ebp = 0x5d;
const Uint8 kPop_ebx = 0x5b;
const Uint8 kPop_esi = 0x5e;
const Uint8 kPop_edi = 0x5f;
const Uint8 kRet = 0xc3;
const Uint8 kRet_Imm16 = 0xc2;
const Uint16 kMov_esp_ebp = 0x8be5;
//-----------------------------------------------------------------------------------------------------------
// x86Formatter
void x86Formatter::
beginFormatting(const FormattedCodeInfo& inInfo)
{
mFCI = inInfo;
}
void x86Formatter::
initStackFrameInfo()
{
mStackFrameInfo.init(mEmitter.mVRAllocator);
}
void x86Formatter::
calculatePrologEpilog(Method& inMethod, Uint32& outPrologSize, Uint32& outEpilogSize)
{
Uint32 GPRwords = mStackFrameInfo.getNumSavedGPRWords();
Uint32 localStoreBytes = mStackFrameInfo.getLocalStoreSizeBytes();
if(localStoreBytes == 0)
{
mPrologSize_bytes = 3 + GPRwords;
mEpilogSize_bytes = 4 + GPRwords;
}
else {
if (localStoreBytes < 128)
mPrologSize_bytes = 6 + GPRwords;
else
mPrologSize_bytes = 9 + GPRwords;
mEpilogSize_bytes = 6 + GPRwords;
}
// determine how many words were passed to us, so the epilog can clean up the stack
const Signature& ourSignature = inMethod.getSignature();
const int numArgs = ourSignature.nArguments;
const Type** ourArgs = ourSignature.argumentTypes;
mNumberOfArgumentWords = 0;
for(int i = 0; i < numArgs; i++)
mNumberOfArgumentWords += nTypeKindSlots(ourArgs[i]->typeKind);
outPrologSize = mPrologSize_bytes;
outEpilogSize = mEpilogSize_bytes;
}
void x86Formatter::
formatPrologToMemory(void* inWhere)
{
Uint8* where = (uint8*)inWhere;
// push ebp
*where++ = kPush_ebp;
//mov ebp, esp
writeBigHalfwordUnaligned(where, kMov_ebp_esp);
where += 2;
// reserve local store space
// sub esp, localstore
Uint32 localStoreBytes = mStackFrameInfo.getLocalStoreSizeBytes();
if (localStoreBytes) {
if (localStoreBytes < 128)
{
writeBigHalfwordUnaligned(where, kSub_esp_Imm8);
where += 2;
*where++ = localStoreBytes;
}
else
{
writeBigHalfwordUnaligned(where, kSub_esp_Imm32);
where += 2;
writeLittleWordUnaligned(where, localStoreBytes);
where += 4;
}
}
// save GPRs -- FIX change to bitfields sometime
Uint32 GPRwords = mStackFrameInfo.getNumSavedGPRWords();
if(GPRwords > 2)
*where++ = kPush_edi;
if(GPRwords > 1)
*where++ = kPush_esi;
if(GPRwords > 0)
*where++ = kPush_ebx;
}
void x86Formatter::
formatEpilogToMemory(void* inWhere)
{
Uint8* where = (uint8*)inWhere;
// restore GPRs -- FIX change to bitfields sometime
Uint32 GPRwords = mStackFrameInfo.getNumSavedGPRWords();
if(GPRwords > 0)
*where++ = kPop_ebx;
if(GPRwords > 1)
*where++ = kPop_esi;
if(GPRwords > 2)
*where++ = kPop_edi;
// mov esp, ebp
Uint32 localStoreBytes = mStackFrameInfo.getLocalStoreSizeBytes();
if(localStoreBytes != 0)
{
writeBigHalfwordUnaligned(where, kMov_esp_ebp);
where+=2;
}
// pop ebp
*where++ = kPop_ebp;
// return cleaning the stack of passed in arguments
if(mNumberOfArgumentWords != 0)
{
*where++ = kRet_Imm16;
writeLittleHalfwordUnaligned(where, mNumberOfArgumentWords * 4);
}
else
{
*where = kRet;
}
}
Uint8* x86Formatter::
createTransitionVector(const FormattedCodeInfo& inInfo)
{
return inInfo.methodStart;
}
Uint8* x86Formatter::
getMethodBegin()
{
return mFCI.methodStart;
}
//-----------------------------------------------------------------------------------------------------------
// Debugging
#ifdef DEBUG_LOG
#include "XDisAsm.h"
#define USING_X86_DISASSEMBLER
const int kMaxDissasemblyBytes = 8; // maximum number of bytes to dump per instruction
// Function: disassemble1
void*
disassemble1(LogModuleObject &f, void* inFrom)
{
#ifdef USING_X86_DISASSEMBLER
char* disasmText;
char* startAddr = (char*)inFrom;
char* curAddr = startAddr;
disasmText = disasmx86( 0,
&curAddr,
curAddr + 32,
kDisAsmFlag32BitSegments);
UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("0x%p: ", inFrom));
// print memory dump
Uint8 numBytes = (Uint8)curAddr - (Uint8)startAddr;
for(int i = 0; i < kMaxDissasemblyBytes; i++)
{
if (i < numBytes) {
Uint8 address= ((Uint8*)startAddr)[i];
UT_OBJECTLOG(f, PR_LOG_ALWAYS, ("%x%x ", address/16, address%16));
}
else
UT_OBJECTLOG(f, PR_LOG_ALWAYS, (" "));
}
UT_OBJECTLOG(f, PR_LOG_ALWAYS, (" %s\n", disasmText));
return (curAddr);
#else
f = NULL; inFrom = NULL;
return NULL;
#endif
}
#endif // DEBUG_LOG