Skip to content

Commit af1171b

Browse files
authored
[LoongArch64] amend the crossgen2/r2rdump for LA64. (#85038)
1 parent 445dac9 commit af1171b

File tree

15 files changed

+270
-28
lines changed

15 files changed

+270
-28
lines changed

src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/ArgIterator.cs

+1-9
Original file line numberDiff line numberDiff line change
@@ -1732,16 +1732,8 @@ private void ForceSigWalk()
17321732
int floatRegOfsInBytes = argOffset - _transitionBlock.OffsetOfFloatArgumentRegisters;
17331733
Debug.Assert((floatRegOfsInBytes % _transitionBlock.FloatRegisterSize) == 0);
17341734
pLoc.m_idxFloatReg = floatRegOfsInBytes / _transitionBlock.FloatRegisterSize;
1735+
pLoc.m_cFloatReg = 1;
17351736

1736-
if (!_argTypeHandle.IsNull() && _argTypeHandle.IsHomogeneousAggregate())
1737-
{
1738-
int haElementSize = _argTypeHandle.GetHomogeneousAggregateElementSize();
1739-
pLoc.m_cFloatReg = GetArgSize() / haElementSize;
1740-
}
1741-
else
1742-
{
1743-
pLoc.m_cFloatReg = 1;
1744-
}
17451737
return pLoc;
17461738
}
17471739

src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/Target_LoongArch64/ImportThunk.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ protected override void EmitCode(NodeFactory factory, ref LoongArch64Emitter ins
2828

2929
if (!relocsOnly)
3030
{
31-
// movz T0=R12, #index
31+
// ori T0=R12, R0, #index
3232
int index = _containingImportSection.IndexFromBeginningOfArray;
3333
instructionEncoder.EmitMOV(Register.R12, checked((ushort)index));
3434
}

src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/TransitionBlock.cs

+4-12
Original file line numberDiff line numberDiff line change
@@ -651,8 +651,8 @@ private class LoongArch64TransitionBlock : TransitionBlock
651651
public override int NumCalleeSavedRegisters => 12;
652652
// Callee-saves, argument registers
653653
public override int SizeOfTransitionBlock => SizeOfCalleeSavedRegisters + SizeOfArgumentRegisters;
654-
public override int OffsetOfArgumentRegisters => SizeOfCalleeSavedRegisters;
655-
public override int OffsetOfFirstGCRefMapSlot => OffsetOfArgumentRegisters;
654+
public override int OffsetOfFirstGCRefMapSlot => SizeOfCalleeSavedRegisters;
655+
public override int OffsetOfArgumentRegisters => OffsetOfFirstGCRefMapSlot;
656656

657657
// F0..F7
658658
public override int OffsetOfFloatArgumentRegisters => 8 * sizeof(double);
@@ -671,19 +671,11 @@ public override bool IsArgPassedByRef(TypeHandle th)
671671
}
672672
else
673673
{
674-
int numIntroducedFields = 0;
675-
foreach (FieldDesc field in th.GetRuntimeTypeHandle().GetFields())
676-
{
677-
if (!field.IsStatic)
678-
{
679-
numIntroducedFields++;
680-
}
681-
}
682-
return ((numIntroducedFields == 0) || (numIntroducedFields > 2));
674+
return false;
683675
}
684676
}
685677

686-
public sealed override int GetRetBuffArgOffset(bool hasThis) => OffsetOfArgumentRegisters;
678+
public sealed override int GetRetBuffArgOffset(bool hasThis) => OffsetOfFirstGCRefMapSlot + (hasThis ? 8 : 0);
687679

688680
public override int StackElemSize(int parmSize, bool isValueType = false, bool isFloatHfa = false)
689681
{

src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/Amd64/GcInfo.cs

+8
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,14 @@ public override string ToString()
259259

260260
sb.AppendLine($" Has Tailcalls: {_wantsReportOnlyLeaf}");
261261
}
262+
else if (_machine == Machine.LoongArch64)
263+
{
264+
if (StackBaseRegister != 0xffffffff)
265+
{
266+
sb.AppendLine($" StackBaseRegister: {(LoongArch64.Registers)StackBaseRegister}");
267+
}
268+
sb.AppendLine($" Has Tailcalls: {_wantsReportOnlyLeaf}");
269+
}
262270

263271
sb.AppendLine($" Size of parameter area: 0x{SizeOfStackOutgoingAndScratchArea:X}");
264272
if (SizeOfEditAndContinuePreservedArea != 0xffffffff)

src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/Amd64/GcSlotTable.cs

+3
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,9 @@ private static string GetRegisterName(int registerNumber, Machine machine)
6868
case Machine.Arm64:
6969
return ((Arm64.Registers)registerNumber).ToString();
7070

71+
case Machine.LoongArch64:
72+
return ((LoongArch64.Registers)registerNumber).ToString();
73+
7174
default:
7275
throw new NotImplementedException(machine.ToString());
7376
}

src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/Amd64/GcTransition.cs

+4
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,10 @@ public string GetSlotState(GcSlotTable slotTable, Machine machine)
6565
regType = typeof(Amd64.Registers);
6666
break;
6767

68+
case Machine.LoongArch64:
69+
regType = typeof(LoongArch64.Registers);
70+
break;
71+
6872
default:
6973
throw new NotImplementedException();
7074
}

src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/DebugInfo.cs

+2
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ public static string GetPlatformSpecificRegister(Machine machine, int regnum)
7272
return ((Arm.Registers)regnum).ToString();
7373
case Machine.Arm64:
7474
return ((Arm64.Registers)regnum).ToString();
75+
case Machine.LoongArch64:
76+
return ((LoongArch64.Registers)regnum).ToString();
7577
default:
7678
throw new NotImplementedException($"No implementation for machine type {machine}.");
7779
}

src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/GCInfoTypes.cs

+10
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,11 @@ internal GcInfoTypes(Machine machine)
149149
NUM_UNTRACKED_SLOTS_ENCBASE = 5;
150150
REGISTER_DELTA_ENCBASE = 3;
151151
break;
152+
case Machine.LoongArch64:
153+
SIZE_OF_RETURN_KIND_FAT = 4;
154+
STACK_BASE_REGISTER_ENCBASE = 2;
155+
NUM_REGISTERS_ENCBASE = 3;
156+
break;
152157
}
153158
}
154159

@@ -159,6 +164,7 @@ internal int DenormalizeCodeLength(int x)
159164
case Machine.ArmThumb2:
160165
return (x << 1);
161166
case Machine.Arm64:
167+
case Machine.LoongArch64:
162168
return (x << 2);
163169
}
164170
return x;
@@ -173,6 +179,7 @@ internal int DenormalizeStackSlot(int x)
173179
case Machine.ArmThumb2:
174180
return (x << 2);
175181
case Machine.Arm64:
182+
case Machine.LoongArch64:
176183
return (x << 3);
177184
}
178185
return x;
@@ -188,6 +195,8 @@ internal uint DenormalizeStackBaseRegister(uint x)
188195
return ((x ^ 7) + 4);
189196
case Machine.Arm64:
190197
return (x ^ 29);
198+
case Machine.LoongArch64:
199+
return ((x ^ 22) & 0x3);
191200
}
192201
return x;
193202
}
@@ -201,6 +210,7 @@ internal uint DenormalizeSizeOfStackArea(uint x)
201210
case Machine.ArmThumb2:
202211
return (x << 2);
203212
case Machine.Arm64:
213+
case Machine.LoongArch64:
204214
return (x << 3);
205215
}
206216
return x;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System;
5+
using System.Collections.Generic;
6+
using System.Text;
7+
8+
namespace ILCompiler.Reflection.ReadyToRun.LoongArch64
9+
{
10+
public enum Registers
11+
{
12+
R0,
13+
Ra,
14+
Tp,
15+
Sp,
16+
A0,
17+
A1,
18+
A2,
19+
A3,
20+
A4,
21+
A5,
22+
A6,
23+
A7,
24+
T0,
25+
T1,
26+
T2,
27+
T3,
28+
T4,
29+
T5,
30+
T6,
31+
T7,
32+
T8,
33+
X0,
34+
Fp,
35+
S0,
36+
S1,
37+
S2,
38+
S3,
39+
S4,
40+
S5,
41+
S6,
42+
S7,
43+
S8
44+
}
45+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System.Text;
5+
6+
namespace ILCompiler.Reflection.ReadyToRun.LoongArch64
7+
{
8+
public class Epilog
9+
{
10+
public int Index { get; set; }
11+
12+
public uint EpilogStartOffset { get; set; }
13+
public uint Res { get; set; }
14+
public uint Condition { get; set; }
15+
public uint EpilogStartIndex { get; set; }
16+
public uint EpilogStartOffsetFromMainFunctionBegin { get; set; }
17+
18+
public Epilog() { }
19+
20+
public Epilog(int index, int dw, uint startOffset)
21+
{
22+
Index = index;
23+
24+
EpilogStartOffset = UnwindInfo.ExtractBits(dw, 0, 18);
25+
Res = UnwindInfo.ExtractBits(dw, 18, 4);
26+
Condition = UnwindInfo.ExtractBits(dw, 20, 4);
27+
EpilogStartIndex = UnwindInfo.ExtractBits(dw, 22, 10);
28+
29+
// Note that epilogStartOffset for a funclet is the offset from the beginning
30+
// of the current funclet, not the offset from the beginning of the main function.
31+
// To help find it when looking through JitDump output, also show the offset from
32+
// the beginning of the main function.
33+
EpilogStartOffsetFromMainFunctionBegin = EpilogStartOffset * 4 + startOffset;
34+
}
35+
36+
public override string ToString()
37+
{
38+
StringBuilder sb = new StringBuilder();
39+
sb.AppendLine($" Epilog Start Offset: 0x{EpilogStartOffset:X5} Actual offset = 0x{EpilogStartOffset * 4:X5} Offset from main function begin = 0x{EpilogStartOffsetFromMainFunctionBegin:X6}");
40+
sb.AppendLine($" Condition: {Condition} (0x{Condition:X})" + ((Condition == 0xE) ? " (always)" : ""));
41+
sb.Append($" Epilog Start Index: {EpilogStartIndex} (0x{EpilogStartIndex:X})");
42+
return sb.ToString();
43+
}
44+
}
45+
46+
public class UnwindCode
47+
{
48+
public int Index { get; set; }
49+
50+
public UnwindCode() { }
51+
52+
public UnwindCode(int index)
53+
{
54+
Index = index;
55+
56+
}
57+
}
58+
59+
/// <summary>
60+
/// based on <a href="https://github.com/dotnet/runtime/src/coreclr/jit/unwindloongarch64.cpp">src/jit/unwindloongarch64.cpp</a> DumpUnwindInfo
61+
/// </summary>
62+
public class UnwindInfo : BaseUnwindInfo
63+
{
64+
public uint CodeWords { get; set; }
65+
public uint EpilogCount { get; set; }
66+
public uint EBit { get; set; }
67+
public uint XBit { get; set; }
68+
public uint Vers { get; set; }
69+
public uint FunctionLength { get; set; }
70+
71+
public uint ExtendedCodeWords { get; set; }
72+
public uint ExtendedEpilogCount { get; set; }
73+
74+
public Epilog[] Epilogs { get; set; }
75+
76+
public UnwindInfo() { }
77+
78+
public UnwindInfo(byte[] image, int offset)
79+
{
80+
uint startOffset = (uint)offset;
81+
82+
int dw = NativeReader.ReadInt32(image, ref offset);
83+
CodeWords = ExtractBits(dw, 27, 5);
84+
EpilogCount = ExtractBits(dw, 22, 5);
85+
EBit = ExtractBits(dw, 21, 1);
86+
XBit = ExtractBits(dw, 20, 1);
87+
Vers = ExtractBits(dw, 18, 2);
88+
FunctionLength = ExtractBits(dw, 0, 18) * 4;
89+
90+
if (CodeWords == 0 && EpilogCount == 0)
91+
{
92+
// We have an extension word specifying a larger number of Code Words or Epilog Counts
93+
// than can be specified in the header word.
94+
dw = NativeReader.ReadInt32(image, ref offset);
95+
ExtendedCodeWords = ExtractBits(dw, 16, 8);
96+
ExtendedEpilogCount = ExtractBits(dw, 0, 16);
97+
}
98+
99+
bool[] epilogStartAt = new bool[1024]; // One byte per possible epilog start index; initialized to false
100+
101+
if (EBit == 0)
102+
{
103+
Epilogs = new Epilog[EpilogCount];
104+
if (EpilogCount != 0)
105+
{
106+
for (int scope = 0; scope < EpilogCount; scope++)
107+
{
108+
dw = NativeReader.ReadInt32(image, ref offset);
109+
Epilogs[scope] = new Epilog(scope, dw, startOffset);
110+
epilogStartAt[Epilogs[scope].EpilogStartIndex] = true; // an epilog starts at this offset in the unwind codes
111+
}
112+
}
113+
}
114+
else
115+
{
116+
Epilogs = new Epilog[0];
117+
epilogStartAt[EpilogCount] = true; // the one and only epilog starts its unwind codes at this offset
118+
}
119+
120+
121+
122+
Size = offset - (int)startOffset + (int)CodeWords * 4;
123+
int alignmentPad = ((Size + sizeof(int) - 1) & ~(sizeof(int) - 1)) - Size;
124+
Size += (alignmentPad + sizeof(uint));
125+
}
126+
127+
public override string ToString()
128+
{
129+
StringBuilder sb = new StringBuilder();
130+
sb.AppendLine($" CodeWords: {CodeWords}");
131+
sb.AppendLine($" EpilogCount: {EpilogCount}");
132+
sb.AppendLine($" EBit: {EBit}");
133+
sb.AppendLine($" XBit: {XBit}");
134+
sb.AppendLine($" Vers: {Vers}");
135+
sb.AppendLine($" FunctionLength: {FunctionLength}");
136+
if (CodeWords == 0 && EpilogCount == 0)
137+
{
138+
sb.AppendLine(" ---- Extension word ----");
139+
sb.AppendLine($" Extended Code Words: {CodeWords}");
140+
sb.AppendLine($" Extended Epilog Count: {EpilogCount}");
141+
}
142+
if (EpilogCount == 0)
143+
{
144+
sb.AppendLine(" No epilogs");
145+
}
146+
else
147+
{
148+
for (int i = 0; i < Epilogs.Length; i++)
149+
{
150+
sb.AppendLine(" -------------------------");
151+
sb.AppendLine(Epilogs[i].ToString());
152+
sb.AppendLine(" -------------------------");
153+
}
154+
}
155+
return sb.ToString();
156+
}
157+
158+
internal static uint ExtractBits(int dw, int start, int length)
159+
{
160+
return (uint)((dw >> start) & ((1 << length) - 1));
161+
}
162+
}
163+
}

src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunMethod.cs

+9-1
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,10 @@ private int GetSize()
225225
{
226226
return (int)arm64Info.FunctionLength;
227227
}
228+
else if (UnwindInfo is LoongArch64.UnwindInfo loongarch64Info)
229+
{
230+
return (int)loongarch64Info.FunctionLength;
231+
}
228232
else if (Method.GcInfo != null)
229233
{
230234
return Method.GcInfo.CodeLength;
@@ -488,7 +492,7 @@ private void EnsureInitialized()
488492
}
489493
else
490494
{
491-
// Arm and Arm64 use the same GcInfo format as Amd64
495+
// Arm, Arm64 and LoongArch64 use the same GcInfo format as Amd64
492496
_gcInfo = new Amd64.GcInfo(_readyToRunReader.Image, gcInfoOffset, _readyToRunReader.Machine, _readyToRunReader.ReadyToRunHeader.MajorVersion);
493497
}
494498
}
@@ -604,6 +608,10 @@ private void ParseRuntimeFunctions(bool partial)
604608
{
605609
unwindInfo = new Arm64.UnwindInfo(_readyToRunReader.Image, unwindOffset);
606610
}
611+
else if (_readyToRunReader.Machine == Machine.LoongArch64)
612+
{
613+
unwindInfo = new LoongArch64.UnwindInfo(_readyToRunReader.Image, unwindOffset);
614+
}
607615

608616
if (i == 0 && unwindInfo != null)
609617
{

src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.cs

+1
Original file line numberDiff line numberDiff line change
@@ -1415,6 +1415,7 @@ private void EnsureImportSections()
14151415

14161416
case Machine.Amd64:
14171417
case Machine.Arm64:
1418+
case Machine.LoongArch64:
14181419
entrySize = 8;
14191420
break;
14201421

0 commit comments

Comments
 (0)