170 lines
5.7 KiB
C#
170 lines
5.7 KiB
C#
|
//
|
||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||
|
//
|
||
|
|
||
|
/*******************************************************************/
|
||
|
/* WARNING */
|
||
|
/* This file should be identical in the Bartok and Singularity */
|
||
|
/* depots. Master copy resides in Bartok Depot. Changes should be */
|
||
|
/* made to Bartok Depot and propagated to Singularity Depot. */
|
||
|
/*******************************************************************/
|
||
|
|
||
|
|
||
|
namespace System.GCs {
|
||
|
|
||
|
using Microsoft.Bartok.Options;
|
||
|
|
||
|
using System.Runtime.CompilerServices;
|
||
|
|
||
|
#if SINGULARITY
|
||
|
using Microsoft.Singularity;
|
||
|
#endif
|
||
|
|
||
|
[MixinConditional("X86")]
|
||
|
[MixinConditional("ISA_IX86")]
|
||
|
[Mixin(typeof(System.GCs.CalleeSaveRegisters))]
|
||
|
[AccessedByRuntime("referenced from halforgc.asm")]
|
||
|
internal struct CalleeSaveRegistersX86 /* : CalleeSaveRegisters */
|
||
|
{
|
||
|
|
||
|
[MixinOverride]
|
||
|
internal void DebugTrace() {
|
||
|
Trace.Log(Trace.Area.Stack,
|
||
|
"Registers: EBX={0:x}, EDI={1:x}, ESI={2:x}, EBP={3:x}",
|
||
|
__arglist(this.EBX, this.EDI, this.ESI, this.EBP));
|
||
|
}
|
||
|
|
||
|
[MixinOverride]
|
||
|
internal UIntPtr GetFramePointer()
|
||
|
{
|
||
|
return this.EBP;
|
||
|
}
|
||
|
|
||
|
[AccessedByRuntime("referenced from halforgc.asm")]
|
||
|
internal UIntPtr EBX;
|
||
|
[AccessedByRuntime("referenced from halforgc.asm")]
|
||
|
internal UIntPtr EDI;
|
||
|
[AccessedByRuntime("referenced from halforgc.asm")]
|
||
|
internal UIntPtr ESI;
|
||
|
[AccessedByRuntime("referenced from halforgc.asm")]
|
||
|
internal UIntPtr EBP;
|
||
|
}
|
||
|
|
||
|
[MixinConditional("X86")]
|
||
|
[MixinConditional("ISA_IX86")]
|
||
|
[Mixin(typeof(System.GCs.CalleeSaveLocations))]
|
||
|
internal unsafe struct CalleeSaveLocationsX86 /* : CalleeSaveLocations */
|
||
|
{
|
||
|
|
||
|
#if SINGULARITY_KERNEL
|
||
|
#if false
|
||
|
[MixinOverride]
|
||
|
internal void SetCalleeSaves(SpillContext *context) {
|
||
|
EBX.SetCalleeReg(&context->ebx);
|
||
|
EDI.SetCalleeReg(&context->edi);
|
||
|
ESI.SetCalleeReg(&context->esi);
|
||
|
EBP.SetCalleeReg(&context->ebp);
|
||
|
}
|
||
|
#endif
|
||
|
#endif
|
||
|
|
||
|
[MixinOverride]
|
||
|
internal
|
||
|
void SetCalleeSaves(CalleeSaveRegistersX86 *calleeSaveRegisters)
|
||
|
{
|
||
|
EBX.SetCalleeReg(&calleeSaveRegisters->EBX);
|
||
|
EDI.SetCalleeReg(&calleeSaveRegisters->EDI);
|
||
|
ESI.SetCalleeReg(&calleeSaveRegisters->ESI);
|
||
|
EBP.SetCalleeReg(&calleeSaveRegisters->EBP);
|
||
|
}
|
||
|
|
||
|
[MixinOverride]
|
||
|
internal void ClearCalleeSaves() {
|
||
|
EBX.ClearCalleeReg();
|
||
|
ESI.ClearCalleeReg();
|
||
|
EDI.ClearCalleeReg();
|
||
|
EBP.ClearCalleeReg();
|
||
|
}
|
||
|
|
||
|
[MixinOverride]
|
||
|
internal void ScanLiveRegs(UIntPtr mask,
|
||
|
NonNullReferenceVisitor referenceVisitor)
|
||
|
{
|
||
|
EDI.ScanLiveReg((mask >> 2) & 0x3, referenceVisitor);
|
||
|
ESI.ScanLiveReg((mask >> 4) & 0x3, referenceVisitor);
|
||
|
EBX.ScanLiveReg((mask >> 0) & 0x3, referenceVisitor);
|
||
|
EBP.ScanLiveReg((mask >> 6) & 0x3, referenceVisitor);
|
||
|
}
|
||
|
|
||
|
[MixinOverride]
|
||
|
internal void PopFrame(UIntPtr *framePointer,
|
||
|
UIntPtr calleeSaveMask,
|
||
|
bool framePointerOmitted,
|
||
|
bool hasTransitionRecord)
|
||
|
{
|
||
|
UIntPtr *calleeSaveStart;
|
||
|
if (framePointerOmitted) {
|
||
|
calleeSaveStart = framePointer - 1;
|
||
|
} else {
|
||
|
VTable.Assert((calleeSaveMask & 0x10) == 0,
|
||
|
"EBP should not be callee saved");
|
||
|
calleeSaveStart = framePointer;
|
||
|
EBP.PopFrameReg(ref calleeSaveStart);
|
||
|
}
|
||
|
if (hasTransitionRecord) {
|
||
|
calleeSaveStart -=
|
||
|
sizeof(CallStack.TransitionRecord) / sizeof(UIntPtr);
|
||
|
}
|
||
|
// Note: the order in which these appear is important!
|
||
|
if ((calleeSaveMask & 0x1) != 0) {
|
||
|
EBX.PopFrameReg(ref calleeSaveStart);
|
||
|
}
|
||
|
if ((calleeSaveMask & 0x8) != 0) {
|
||
|
EBP.PopFrameReg(ref calleeSaveStart);
|
||
|
}
|
||
|
if ((calleeSaveMask & 0x4) != 0) {
|
||
|
ESI.PopFrameReg(ref calleeSaveStart);
|
||
|
}
|
||
|
if ((calleeSaveMask & 0x2) != 0) {
|
||
|
EDI.PopFrameReg(ref calleeSaveStart);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
[MixinOverride]
|
||
|
internal void ClearFrame(UIntPtr calleeSaveMask,
|
||
|
bool framePointerOmitted)
|
||
|
{
|
||
|
if (!framePointerOmitted) {
|
||
|
VTable.Assert((calleeSaveMask & 0x10) == 0,
|
||
|
"EBP should not be callee saved");
|
||
|
EBP.ClearFrameReg();
|
||
|
}
|
||
|
if ((calleeSaveMask & 0x1) != 0) {
|
||
|
EBX.ClearFrameReg();
|
||
|
}
|
||
|
if ((calleeSaveMask & 0x8) != 0) {
|
||
|
EBP.ClearFrameReg();
|
||
|
}
|
||
|
if ((calleeSaveMask & 0x4) != 0) {
|
||
|
ESI.ClearFrameReg();
|
||
|
}
|
||
|
if ((calleeSaveMask & 0x2) != 0) {
|
||
|
EDI.ClearFrameReg();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
[MixinOverride]
|
||
|
internal UIntPtr GetFramePointer()
|
||
|
{
|
||
|
return EBP.value;
|
||
|
}
|
||
|
|
||
|
CalleeSaveLocations.RegLocation EBX;
|
||
|
CalleeSaveLocations.RegLocation EDI;
|
||
|
CalleeSaveLocations.RegLocation ESI;
|
||
|
CalleeSaveLocations.RegLocation EBP;
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|