221 lines
7.7 KiB
C#
221 lines
7.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;
|
||
|
using Microsoft.Singularity.Isal;
|
||
|
using Microsoft.Singularity.Isal.Arm;
|
||
|
#endif
|
||
|
|
||
|
[MixinConditional("ARM")]
|
||
|
[MixinConditional("ISA_ARM")]
|
||
|
[Mixin(typeof(System.GCs.CalleeSaveRegisters))]
|
||
|
[AccessedByRuntime("Referenced from halforgc.asm")]
|
||
|
internal struct CalleeSaveRegistersARM /* : CalleeSaveRegisters */
|
||
|
{
|
||
|
|
||
|
[MixinOverride]
|
||
|
internal void DebugTrace() {
|
||
|
Trace.Log(Trace.Area.Stack,
|
||
|
"Registers: R4={0:x}, R5={0:x}, R6={0:x}, R7={0:x},\n R8={0:x}, R9={0:x}, R10={0:x}, R11={0:x}",
|
||
|
__arglist(this.r4, this.r5, this.r6, this.r7,
|
||
|
this.r8, this.r9, this.r10, this.r11));
|
||
|
}
|
||
|
|
||
|
[MixinOverride]
|
||
|
internal UIntPtr GetFramePointer()
|
||
|
{
|
||
|
return this.r11;
|
||
|
}
|
||
|
|
||
|
[AccessedByRuntime("Referenced from halforgc.asm")]
|
||
|
internal UIntPtr r4;
|
||
|
[AccessedByRuntime("Referenced from halforgc.asm")]
|
||
|
internal UIntPtr r5;
|
||
|
[AccessedByRuntime("Referenced from halforgc.asm")]
|
||
|
internal UIntPtr r6;
|
||
|
[AccessedByRuntime("Referenced from halforgc.asm")]
|
||
|
internal UIntPtr r7;
|
||
|
[AccessedByRuntime("Referenced from halforgc.asm")]
|
||
|
internal UIntPtr r8;
|
||
|
[AccessedByRuntime("Referenced from halforgc.asm")]
|
||
|
internal UIntPtr r9;
|
||
|
[AccessedByRuntime("Referenced from halforgc.asm")]
|
||
|
internal UIntPtr r10;
|
||
|
[AccessedByRuntime("Referenced from halforgc.asm")]
|
||
|
internal UIntPtr r11;
|
||
|
|
||
|
}
|
||
|
|
||
|
[MixinConditional("ARM")]
|
||
|
[MixinConditional("ISA_ARM")]
|
||
|
[Mixin(typeof(System.GCs.CalleeSaveLocations))]
|
||
|
internal unsafe struct CalleeSaveLocationsARM /* : CalleeSaveLocations */
|
||
|
{
|
||
|
|
||
|
#if SINGULARITY_KERNEL
|
||
|
#if false
|
||
|
[MixinOverride]
|
||
|
internal void SetCalleeSaves(SpillContext *context) {
|
||
|
r4.SetCalleeReg(&context->r4);
|
||
|
r5.SetCalleeReg(&context->r5);
|
||
|
r6.SetCalleeReg(&context->r6);
|
||
|
r7.SetCalleeReg(&context->r7);
|
||
|
r8.SetCalleeReg(&context->r8);
|
||
|
r9.SetCalleeReg(&context->r9);
|
||
|
r10.SetCalleeReg(&context->r10);
|
||
|
r11.SetCalleeReg(&context->r11);
|
||
|
}
|
||
|
#endif
|
||
|
#endif
|
||
|
|
||
|
[MixinOverride]
|
||
|
internal
|
||
|
void SetCalleeSaves(CalleeSaveRegistersARM *calleeSaveRegisters)
|
||
|
{
|
||
|
r4.SetCalleeReg(&calleeSaveRegisters->r4);
|
||
|
r5.SetCalleeReg(&calleeSaveRegisters->r5);
|
||
|
r6.SetCalleeReg(&calleeSaveRegisters->r6);
|
||
|
r7.SetCalleeReg(&calleeSaveRegisters->r7);
|
||
|
r8.SetCalleeReg(&calleeSaveRegisters->r8);
|
||
|
r9.SetCalleeReg(&calleeSaveRegisters->r9);
|
||
|
r10.SetCalleeReg(&calleeSaveRegisters->r10);
|
||
|
r11.SetCalleeReg(&calleeSaveRegisters->r11);
|
||
|
}
|
||
|
|
||
|
[MixinOverride]
|
||
|
internal void ClearCalleeSaves() {
|
||
|
r4.ClearCalleeReg();
|
||
|
r5.ClearCalleeReg();
|
||
|
r6.ClearCalleeReg();
|
||
|
r7.ClearCalleeReg();
|
||
|
r8.ClearCalleeReg();
|
||
|
r9.ClearCalleeReg();
|
||
|
r10.ClearCalleeReg();
|
||
|
r11.ClearCalleeReg();
|
||
|
}
|
||
|
|
||
|
[MixinOverride]
|
||
|
internal void ScanLiveRegs(UIntPtr mask,
|
||
|
NonNullReferenceVisitor referenceVisitor)
|
||
|
{
|
||
|
r4.ScanLiveReg((mask >> 0) & 0x3, referenceVisitor);
|
||
|
r5.ScanLiveReg((mask >> 2) & 0x3, referenceVisitor);
|
||
|
r6.ScanLiveReg((mask >> 4) & 0x3, referenceVisitor);
|
||
|
r7.ScanLiveReg((mask >> 6) & 0x3, referenceVisitor);
|
||
|
r8.ScanLiveReg((mask >> 8) & 0x3, referenceVisitor);
|
||
|
r9.ScanLiveReg((mask >> 10) & 0x3, referenceVisitor);
|
||
|
r10.ScanLiveReg((mask >> 12) & 0x3, referenceVisitor);
|
||
|
r11.ScanLiveReg((mask >> 14) & 0x3, referenceVisitor);
|
||
|
}
|
||
|
|
||
|
[MixinOverride]
|
||
|
internal void PopFrame(UIntPtr *framePointer,
|
||
|
UIntPtr calleeSaveMask,
|
||
|
bool framePointerOmitted,
|
||
|
bool hasTransitionRecord)
|
||
|
{
|
||
|
UIntPtr *calleeSaveStart;
|
||
|
calleeSaveStart = framePointer - 3; // Step over SP & LR
|
||
|
|
||
|
if (hasTransitionRecord) {
|
||
|
calleeSaveStart -=
|
||
|
sizeof(CallStack.TransitionRecord) / sizeof(UIntPtr);
|
||
|
}
|
||
|
|
||
|
// Note: the order in which these appear is important!
|
||
|
if (!framePointerOmitted || (calleeSaveMask & 0x80) != 0) {
|
||
|
r11.PopFrameReg(ref calleeSaveStart);
|
||
|
}
|
||
|
if ((calleeSaveMask & 0x40) != 0) {
|
||
|
r10.PopFrameReg(ref calleeSaveStart);
|
||
|
}
|
||
|
if ((calleeSaveMask & 0x20) != 0) {
|
||
|
r9.PopFrameReg(ref calleeSaveStart);
|
||
|
}
|
||
|
if ((calleeSaveMask & 0x10) != 0) {
|
||
|
r8.PopFrameReg(ref calleeSaveStart);
|
||
|
}
|
||
|
if ((calleeSaveMask & 0x8) != 0) {
|
||
|
r7.PopFrameReg(ref calleeSaveStart);
|
||
|
}
|
||
|
if ((calleeSaveMask & 0x4) != 0) {
|
||
|
r6.PopFrameReg(ref calleeSaveStart);
|
||
|
}
|
||
|
if ((calleeSaveMask & 0x2) != 0) {
|
||
|
r5.PopFrameReg(ref calleeSaveStart);
|
||
|
}
|
||
|
if ((calleeSaveMask & 0x1) != 0) {
|
||
|
r4.PopFrameReg(ref calleeSaveStart);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
[MixinOverride]
|
||
|
internal void ClearFrame(UIntPtr calleeSaveMask,
|
||
|
bool framePointerOmitted)
|
||
|
{
|
||
|
if (!framePointerOmitted) {
|
||
|
VTable.Assert((calleeSaveMask & 0x100) == 0,
|
||
|
"EBP should not be callee saved");
|
||
|
r11.ClearFrameReg();
|
||
|
}
|
||
|
if ((calleeSaveMask & 0x1) != 0) {
|
||
|
r4.ClearFrameReg();
|
||
|
}
|
||
|
if ((calleeSaveMask & 0x2) != 0) {
|
||
|
r5.ClearFrameReg();
|
||
|
}
|
||
|
if ((calleeSaveMask & 0x4) != 0) {
|
||
|
r6.ClearFrameReg();
|
||
|
}
|
||
|
if ((calleeSaveMask & 0x8) != 0) {
|
||
|
r7.ClearFrameReg();
|
||
|
}
|
||
|
if ((calleeSaveMask & 0x10) != 0) {
|
||
|
r8.ClearFrameReg();
|
||
|
}
|
||
|
if ((calleeSaveMask & 0x20) != 0) {
|
||
|
r9.ClearFrameReg();
|
||
|
}
|
||
|
if ((calleeSaveMask & 0x40) != 0) {
|
||
|
r10.ClearFrameReg();
|
||
|
}
|
||
|
if ((calleeSaveMask & 0x80) != 0) {
|
||
|
r11.ClearFrameReg();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
[MixinOverride]
|
||
|
internal UIntPtr GetFramePointer()
|
||
|
{
|
||
|
return r11.value;
|
||
|
}
|
||
|
|
||
|
CalleeSaveLocations.RegLocation r4;
|
||
|
CalleeSaveLocations.RegLocation r5;
|
||
|
CalleeSaveLocations.RegLocation r6;
|
||
|
CalleeSaveLocations.RegLocation r7;
|
||
|
CalleeSaveLocations.RegLocation r8;
|
||
|
CalleeSaveLocations.RegLocation r9;
|
||
|
CalleeSaveLocations.RegLocation r10;
|
||
|
CalleeSaveLocations.RegLocation r11;
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|