// // 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; } }