226 lines
8.0 KiB
C#
226 lines
8.0 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;
|
||
|
using Microsoft.Singularity.Isal;
|
||
|
#endif
|
||
|
|
||
|
|
||
|
[MixinConditional("X64")]
|
||
|
[MixinConditional("ISA_IX64")]
|
||
|
[Mixin(typeof(System.GCs.CalleeSaveRegisters))]
|
||
|
[AccessedByRuntime("referenced from halforgc.asm")]
|
||
|
internal struct CalleeSaveRegistersX64 /* : CalleeSaveRegisters */
|
||
|
{
|
||
|
|
||
|
[MixinOverride]
|
||
|
internal void DebugTrace() {
|
||
|
Trace.Log(Trace.Area.Stack,
|
||
|
"Registers: EBX={0:x}, EDI={1:x}, ESI={2:x}, EBP={3:x}"+
|
||
|
"\nR12={4:x}, R13={5:x}, R14={6:x}, R15={7:x}",
|
||
|
__arglist(this.EBX, this.EDI, this.ESI, this.EBP,
|
||
|
this.R12, this.R13, this.R14, this.R15));
|
||
|
}
|
||
|
|
||
|
[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;
|
||
|
[AccessedByRuntime("referenced from halforgc.asm")]
|
||
|
internal UIntPtr R12;
|
||
|
[AccessedByRuntime("referenced from halforgc.asm")]
|
||
|
internal UIntPtr R13;
|
||
|
[AccessedByRuntime("referenced from halforgc.asm")]
|
||
|
internal UIntPtr R14;
|
||
|
[AccessedByRuntime("referenced from halforgc.asm")]
|
||
|
internal UIntPtr R15;
|
||
|
}
|
||
|
|
||
|
[MixinConditional("X64")]
|
||
|
[MixinConditional("ISA_IX64")]
|
||
|
[Mixin(typeof(System.GCs.CalleeSaveLocations))]
|
||
|
internal unsafe struct CalleeSaveLocationsX64 /* : CalleeSaveLocations */
|
||
|
{
|
||
|
|
||
|
#if SINGULARITY_KERNEL
|
||
|
[MixinOverride]
|
||
|
internal void SetCalleeSaves(SpillContext *context) {
|
||
|
EBX.SetCalleeReg(&context->bx);
|
||
|
EDI.SetCalleeReg(&context->di);
|
||
|
ESI.SetCalleeReg(&context->si);
|
||
|
EBP.SetCalleeReg(&context->bp);
|
||
|
R12.SetCalleeReg(&context->r12);
|
||
|
R13.SetCalleeReg(&context->r13);
|
||
|
R14.SetCalleeReg(&context->r14);
|
||
|
R15.SetCalleeReg(&context->r15);
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
[MixinOverride]
|
||
|
internal
|
||
|
void SetCalleeSaves(CalleeSaveRegistersX64 *calleeSaveRegisters)
|
||
|
{
|
||
|
EBX.SetCalleeReg(&calleeSaveRegisters->EBX);
|
||
|
EDI.SetCalleeReg(&calleeSaveRegisters->EDI);
|
||
|
ESI.SetCalleeReg(&calleeSaveRegisters->ESI);
|
||
|
EBP.SetCalleeReg(&calleeSaveRegisters->EBP);
|
||
|
R12.SetCalleeReg(&calleeSaveRegisters->R12);
|
||
|
R13.SetCalleeReg(&calleeSaveRegisters->R13);
|
||
|
R14.SetCalleeReg(&calleeSaveRegisters->R14);
|
||
|
R15.SetCalleeReg(&calleeSaveRegisters->R15);
|
||
|
}
|
||
|
|
||
|
[MixinOverride]
|
||
|
internal void ClearCalleeSaves() {
|
||
|
EBX.ClearCalleeReg();
|
||
|
ESI.ClearCalleeReg();
|
||
|
EDI.ClearCalleeReg();
|
||
|
EBP.ClearCalleeReg();
|
||
|
R12.ClearCalleeReg();
|
||
|
R13.ClearCalleeReg();
|
||
|
R14.ClearCalleeReg();
|
||
|
R15.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);
|
||
|
R12.ScanLiveReg((mask >> 6) & 0x3, referenceVisitor);
|
||
|
R13.ScanLiveReg((mask >> 8) & 0x3, referenceVisitor);
|
||
|
R14.ScanLiveReg((mask >> 10) & 0x3, referenceVisitor);
|
||
|
R15.ScanLiveReg((mask >> 12) & 0x3, referenceVisitor);
|
||
|
EBP.ScanLiveReg((mask >> 14) & 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 & 0x100) == 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 & 0x80) != 0) {
|
||
|
EBP.PopFrameReg(ref calleeSaveStart);
|
||
|
}
|
||
|
if ((calleeSaveMask & 0x4) != 0) {
|
||
|
ESI.PopFrameReg(ref calleeSaveStart);
|
||
|
}
|
||
|
if ((calleeSaveMask & 0x2) != 0) {
|
||
|
EDI.PopFrameReg(ref calleeSaveStart);
|
||
|
}
|
||
|
if ((calleeSaveMask & 0x8) != 0) {
|
||
|
R12.PopFrameReg(ref calleeSaveStart);
|
||
|
}
|
||
|
if ((calleeSaveMask & 0x10) != 0) {
|
||
|
R13.PopFrameReg(ref calleeSaveStart);
|
||
|
}
|
||
|
if ((calleeSaveMask & 0x20) != 0) {
|
||
|
R14.PopFrameReg(ref calleeSaveStart);
|
||
|
}
|
||
|
if ((calleeSaveMask & 0x40) != 0) {
|
||
|
R15.PopFrameReg(ref calleeSaveStart);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
[MixinOverride]
|
||
|
internal void ClearFrame(UIntPtr calleeSaveMask,
|
||
|
bool framePointerOmitted)
|
||
|
{
|
||
|
if (!framePointerOmitted) {
|
||
|
VTable.Assert((calleeSaveMask & 0x100) == 0,
|
||
|
"EBP should not be callee saved");
|
||
|
EBP.ClearFrameReg();
|
||
|
}
|
||
|
if ((calleeSaveMask & 0x1) != 0) {
|
||
|
EBX.ClearFrameReg();
|
||
|
}
|
||
|
if ((calleeSaveMask & 0x80) != 0) {
|
||
|
EBP.ClearFrameReg();
|
||
|
}
|
||
|
if ((calleeSaveMask & 0x4) != 0) {
|
||
|
ESI.ClearFrameReg();
|
||
|
}
|
||
|
if ((calleeSaveMask & 0x2) != 0) {
|
||
|
EDI.ClearFrameReg();
|
||
|
}
|
||
|
if ((calleeSaveMask & 0x8) != 0) {
|
||
|
R12.ClearFrameReg();
|
||
|
}
|
||
|
if ((calleeSaveMask & 0x10) != 0) {
|
||
|
R13.ClearFrameReg();
|
||
|
}
|
||
|
if ((calleeSaveMask & 0x20) != 0) {
|
||
|
R14.ClearFrameReg();
|
||
|
}
|
||
|
if ((calleeSaveMask & 0x40) != 0) {
|
||
|
R15.ClearFrameReg();
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
[MixinOverride]
|
||
|
internal UIntPtr GetFramePointer()
|
||
|
{
|
||
|
return EBP.value;
|
||
|
}
|
||
|
|
||
|
CalleeSaveLocations.RegLocation EBX;
|
||
|
CalleeSaveLocations.RegLocation EDI;
|
||
|
CalleeSaveLocations.RegLocation ESI;
|
||
|
CalleeSaveLocations.RegLocation EBP;
|
||
|
CalleeSaveLocations.RegLocation R12;
|
||
|
CalleeSaveLocations.RegLocation R13;
|
||
|
CalleeSaveLocations.RegLocation R14;
|
||
|
CalleeSaveLocations.RegLocation R15;
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|