singrdk/base/Imported/Bartok/runtime/shared/GCs/CalleeSaveX64.cs

226 lines
8.0 KiB
C#
Raw Normal View History

2008-11-17 18:29:00 -05:00
//
// 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;
}
}