Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 6674c7b

Browse files
committed
Merge branch 'main' into convertops
2 parents ef4c707 + d12fda1 commit 6674c7b

File tree

21 files changed

+1349
-189
lines changed

21 files changed

+1349
-189
lines changed

src/coreclr/jit/codegenarm64test.cpp

Lines changed: 220 additions & 0 deletions
Large diffs are not rendered by default.

src/coreclr/jit/emitarm64.cpp

Lines changed: 813 additions & 127 deletions
Large diffs are not rendered by default.

src/coreclr/jit/emitarm64.h

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ void emitDispBarrier(insBarrier barrier);
4848
void emitDispShiftOpts(insOpts opt);
4949
void emitDispExtendOpts(insOpts opt);
5050
void emitDispSveExtendOpts(insOpts opt);
51+
void emitDispSveExtendOptsModN(insOpts opt, int n);
52+
void emitDispSveModAddr(instruction ins, regNumber reg1, regNumber reg2, insOpts opt, insFormat fmt);
5153
void emitDispLSExtendOpts(insOpts opt);
5254
void emitDispReg(regNumber reg, emitAttr attr, bool addComma);
5355
void emitDispSveReg(regNumber reg, insOpts opt, bool addComma);
@@ -505,6 +507,18 @@ static int insGetSveReg1ListSize(instruction ins);
505507
// Register position is required for instructions with multiple predicates.
506508
static PredicateType insGetPredicateType(insFormat fmt, int regpos = 0);
507509

510+
// Returns true if the SVE instruction has a LSL addr.
511+
// This is for formats that have [<Xn|SP>, <Xm>, LSL #N]
512+
static bool insSveIsLslN(instruction ins, insFormat fmt);
513+
514+
// Returns true if the SVE instruction has a <mod> addr.
515+
// This is for formats that have [<Xn|SP>, <Zm>.T, <mod>], [<Xn|SP>, <Zm>.T, <mod> #N]
516+
static bool insSveIsModN(instruction ins, insFormat fmt);
517+
518+
// Returns 0, 1, 2 or 3 depending on the instruction and format.
519+
// This is for formats that have [<Xn|SP>, <Zm>.T, <mod>], [<Xn|SP>, <Zm>.T, <mod> #N], [<Xn|SP>, <Xm>, LSL #N]
520+
static int insSveGetLslOrModN(instruction ins, insFormat fmt);
521+
508522
// Returns true if the specified instruction can encode the 'dtype' field.
509523
static bool canEncodeSveElemsize_dtype(instruction ins);
510524

@@ -1076,8 +1090,17 @@ inline static bool insOptsScalableWide(insOpts opt)
10761090

10771091
inline static bool insOptsScalable32bitExtends(insOpts opt)
10781092
{
1079-
return ((opt == INS_OPTS_SCALABLE_S_UXTW) || (opt == INS_OPTS_SCALABLE_S_SXTW) ||
1080-
(opt == INS_OPTS_SCALABLE_D_UXTW) || (opt == INS_OPTS_SCALABLE_D_SXTW));
1093+
return insOptsScalableSingleWord32bitExtends(opt) || insOptsScalableDoubleWord32bitExtends(opt);
1094+
}
1095+
1096+
inline static bool insOptsScalableSingleWord32bitExtends(insOpts opt)
1097+
{
1098+
return (opt == INS_OPTS_SCALABLE_S_UXTW) || (opt == INS_OPTS_SCALABLE_S_SXTW);
1099+
}
1100+
1101+
inline static bool insOptsScalableDoubleWord32bitExtends(insOpts opt)
1102+
{
1103+
return (opt == INS_OPTS_SCALABLE_D_UXTW) || (opt == INS_OPTS_SCALABLE_D_SXTW);
10811104
}
10821105

10831106
inline static bool insScalableOptsNone(insScalableOpts sopt)
@@ -1212,6 +1235,9 @@ void emitIns_R_R_FLAGS_COND(
12121235

12131236
void emitIns_R_I_FLAGS_COND(instruction ins, emitAttr attr, regNumber reg1, int imm, insCflags flags, insCond cond);
12141237

1238+
void emitIns_R_PATTERN(
1239+
instruction ins, emitAttr attr, regNumber reg1, insOpts opt, insSvePattern pattern = SVE_PATTERN_ALL);
1240+
12151241
void emitIns_R_PATTERN_I(instruction ins, emitAttr attr, regNumber reg1, insSvePattern pattern, int imm);
12161242

12171243
void emitIns_BARR(instruction ins, insBarrier barrier);

src/coreclr/nativeaot/Runtime/arm/Interlocked.S

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,50 @@
77
#include <AsmOffsets.inc> // generated by the build from AsmOffsets.cpp
88
#include <unixasmmacros.inc>
99

10+
// WARNING: Code in EHHelpers.cpp makes assumptions about this helper, in particular:
11+
// - Function "InWriteBarrierHelper" assumes an AV due to passed in null pointer will happen at RhpLockCmpXchg8AVLocation
12+
// - Function "UnwindSimpleHelperToCaller" assumes no registers were pushed and LR contains the return address
13+
// r0 = destination address
14+
// r1 = value
15+
// r2 = comparand
16+
LEAF_ENTRY RhpLockCmpXchg8, _TEXT
17+
dmb
18+
ALTERNATE_ENTRY RhpLockCmpXchg8AVLocation
19+
LOCAL_LABEL(CmpXchg8Retry):
20+
ldrexb r3, [r0]
21+
cmp r2, r3
22+
bne LOCAL_LABEL(CmpXchg8Exit)
23+
strexb r12, r1, [r0]
24+
cmp r12, #0
25+
bne LOCAL_LABEL(CmpXchg8Retry)
26+
LOCAL_LABEL(CmpXchg8Exit):
27+
mov r0, r3
28+
dmb
29+
bx lr
30+
LEAF_END RhpLockCmpXchg8, _TEXT
31+
32+
// WARNING: Code in EHHelpers.cpp makes assumptions about this helper, in particular:
33+
// - Function "InWriteBarrierHelper" assumes an AV due to passed in null pointer will happen at RhpLockCmpXchg16AVLocation
34+
// - Function "UnwindSimpleHelperToCaller" assumes no registers were pushed and LR contains the return address
35+
// r0 = destination address
36+
// r1 = value
37+
// r2 = comparand
38+
LEAF_ENTRY RhpLockCmpXchg16, _TEXT
39+
dmb
40+
ALTERNATE_ENTRY RhpLockCmpXchg16AVLocation
41+
LOCAL_LABEL(CmpXchg16Retry):
42+
ldrexh r3, [r0]
43+
cmp r2, r3
44+
bne LOCAL_LABEL(CmpXchg16Exit)
45+
strexh r12, r1, [r0]
46+
cmp r12, #0
47+
bne LOCAL_LABEL(CmpXchg16Retry)
48+
LOCAL_LABEL(CmpXchg16Exit):
49+
mov r0, r3
50+
dmb
51+
bx lr
52+
LEAF_END RhpLockCmpXchg16, _TEXT
53+
1054
// WARNING: Code in EHHelpers.cpp makes assumptions about this helper, in particular:
1155
// - Function "InWriteBarrierHelper" assumes an AV due to passed in null pointer will happen at RhpLockCmpXchg32AVLocation
1256
// - Function "UnwindSimpleHelperToCaller" assumes no registers were pushed and LR contains the return address

src/coreclr/tools/r2rdump/CoreDisTools.cs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ public enum TargetArch
2222
Target_X64,
2323
Target_Thumb,
2424
Target_Arm64,
25-
Target_LoongArch64
25+
Target_LoongArch64,
26+
Target_RiscV64,
2627
};
2728

2829
[DllImport(_dll, CallingConvention = CallingConvention.Cdecl)]
@@ -77,6 +78,9 @@ public static IntPtr GetDisasm(Machine machine)
7778
case Machine.LoongArch64:
7879
target = TargetArch.Target_LoongArch64;
7980
break;
81+
case Machine.RiscV64:
82+
target = TargetArch.Target_RiscV64;
83+
break;
8084
default:
8185
Program.WriteWarning($"{machine} not supported on CoreDisTools");
8286
return IntPtr.Zero;
@@ -191,6 +195,10 @@ private void SetIndentations()
191195
// Instructions are dumped as 4-byte hexadecimal integers
192196
Machine.LoongArch64 => 4 * 2 + 1,
193197

198+
// Instructions are dumped as 4-byte hexadecimal integers
199+
// TODO: update once RISC-V runtime supports "C" extension (compressed instructions)
200+
Machine.RiscV64 => 4 * 2 + 1,
201+
194202
_ => throw new NotImplementedException()
195203
};
196204

@@ -260,7 +268,8 @@ public int GetInstruction(RuntimeFunction rtf, int imageOffset, int rtfOffset, o
260268
}
261269
else
262270
{
263-
if ((_reader.Machine == Machine.Arm64) || (_reader.Machine == Machine.LoongArch64))
271+
// TODO: update once RISC-V runtime supports "C" extension (compressed instructions)
272+
if (_reader.Machine is Machine.Arm64 or Machine.LoongArch64 or Machine.RiscV64)
264273
{
265274
// Replace " hh hh hh hh " byte dump with " hhhhhhhh ".
266275
// CoreDisTools should be fixed to dump bytes this way for ARM64.

src/coreclr/tools/r2rdump/Program.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,7 @@ public void Dump(ReadyToRunReader r2r)
210210
Machine.ArmThumb2 => TargetArchitecture.ARM,
211211
Machine.Arm64 => TargetArchitecture.ARM64,
212212
Machine.LoongArch64 => TargetArchitecture.LoongArch64,
213+
Machine.RiscV64 => TargetArchitecture.RiscV64,
213214
_ => throw new NotImplementedException(r2r.Machine.ToString()),
214215
};
215216
TargetOS os = r2r.OperatingSystem switch

src/coreclr/tools/r2rdump/R2RDump.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<AssemblyVersion>1.0.0.0</AssemblyVersion>
55
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
66
<OutputType>Exe</OutputType>
7-
<Platforms>x64;x86;arm64;arm;loongarch64</Platforms>
7+
<Platforms>x64;x86;arm64;arm;loongarch64;riscv64</Platforms>
88
<AssemblyKey>Open</AssemblyKey>
99
<IsDotNetFrameworkProductAssembly>true</IsDotNetFrameworkProductAssembly>
1010
<TargetFramework>$(NetCoreAppToolCurrent)</TargetFramework>

src/libraries/System.Linq/src/System/Linq/OrderedEnumerable.SpeedOpt.cs

Lines changed: 127 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
using System.Collections;
55
using System.Collections.Generic;
6+
using System.Diagnostics;
67
using System.Runtime.InteropServices;
78

89
namespace System.Linq
@@ -155,7 +156,7 @@ internal int GetCount(int minIdx, int maxIdx, bool onlyIfCheap)
155156
return default;
156157
}
157158

158-
public TElement? TryGetFirst(out bool found)
159+
public virtual TElement? TryGetFirst(out bool found)
159160
{
160161
CachingComparer<TElement> comparer = GetComparer();
161162
using (IEnumerator<TElement> e = _source.GetEnumerator())
@@ -182,7 +183,7 @@ internal int GetCount(int minIdx, int maxIdx, bool onlyIfCheap)
182183
}
183184
}
184185

185-
public TElement? TryGetLast(out bool found)
186+
public virtual TElement? TryGetLast(out bool found)
186187
{
187188
using (IEnumerator<TElement> e = _source.GetEnumerator())
188189
{
@@ -244,6 +245,70 @@ private TElement Last(TElement[] items)
244245
}
245246
}
246247

248+
internal sealed partial class OrderedEnumerable<TElement, TKey> : OrderedEnumerable<TElement>
249+
{
250+
// For complicated cases, rely on the base implementation that's more comprehensive.
251+
// For the simple case of OrderBy(...).First() or OrderByDescending(...).First() (i.e. where
252+
// there's just a single comparer we need to factor in), we can just do the iteration directly.
253+
254+
public override TElement? TryGetFirst(out bool found) =>
255+
_parent is not null ?
256+
base.TryGetFirst(out found) :
257+
TryGetFirstOrLast(out found, first: !_descending);
258+
259+
public override TElement? TryGetLast(out bool found) =>
260+
_parent is not null ?
261+
base.TryGetLast(out found) :
262+
TryGetFirstOrLast(out found, first: _descending);
263+
264+
private TElement? TryGetFirstOrLast(out bool found, bool first)
265+
{
266+
using IEnumerator<TElement> e = _source.GetEnumerator();
267+
268+
if (e.MoveNext())
269+
{
270+
IComparer<TKey> comparer = _comparer;
271+
Func<TElement, TKey> keySelector = _keySelector;
272+
273+
TElement resultValue = e.Current;
274+
TKey resultKey = keySelector(resultValue);
275+
276+
if (first)
277+
{
278+
while (e.MoveNext())
279+
{
280+
TElement nextValue = e.Current;
281+
TKey nextKey = keySelector(nextValue);
282+
if (comparer.Compare(nextKey, resultKey) < 0)
283+
{
284+
resultKey = nextKey;
285+
resultValue = nextValue;
286+
}
287+
}
288+
}
289+
else
290+
{
291+
while (e.MoveNext())
292+
{
293+
TElement nextValue = e.Current;
294+
TKey nextKey = keySelector(nextValue);
295+
if (comparer.Compare(nextKey, resultKey) >= 0)
296+
{
297+
resultKey = nextKey;
298+
resultValue = nextValue;
299+
}
300+
}
301+
}
302+
303+
found = true;
304+
return resultValue;
305+
}
306+
307+
found = false;
308+
return default;
309+
}
310+
}
311+
247312
internal sealed partial class OrderedImplicitlyStableEnumerable<TElement> : OrderedEnumerable<TElement>
248313
{
249314
public override TElement[] ToArray()
@@ -259,5 +324,65 @@ public override List<TElement> ToList()
259324
Sort(CollectionsMarshal.AsSpan(list), _descending);
260325
return list;
261326
}
327+
328+
public override TElement? TryGetFirst(out bool found) =>
329+
TryGetFirstOrLast(out found, first: !_descending);
330+
331+
public override TElement? TryGetLast(out bool found) =>
332+
TryGetFirstOrLast(out found, first: _descending);
333+
334+
private TElement? TryGetFirstOrLast(out bool found, bool first)
335+
{
336+
if (Enumerable.TryGetSpan(_source, out ReadOnlySpan<TElement> span))
337+
{
338+
if (span.Length != 0)
339+
{
340+
Debug.Assert(Enumerable.TypeIsImplicitlyStable<TElement>(), "Using Min/Max has different semantics for floating-point values.");
341+
342+
found = true;
343+
return first ?
344+
Enumerable.Min(_source) :
345+
Enumerable.Max(_source);
346+
}
347+
}
348+
else
349+
{
350+
using IEnumerator<TElement> e = _source.GetEnumerator();
351+
352+
if (e.MoveNext())
353+
{
354+
TElement resultValue = e.Current;
355+
356+
if (first)
357+
{
358+
while (e.MoveNext())
359+
{
360+
TElement nextValue = e.Current;
361+
if (Comparer<TElement>.Default.Compare(nextValue, resultValue) < 0)
362+
{
363+
resultValue = nextValue;
364+
}
365+
}
366+
}
367+
else
368+
{
369+
while (e.MoveNext())
370+
{
371+
TElement nextValue = e.Current;
372+
if (Comparer<TElement>.Default.Compare(nextValue, resultValue) >= 0)
373+
{
374+
resultValue = nextValue;
375+
}
376+
}
377+
}
378+
379+
found = true;
380+
return resultValue;
381+
}
382+
}
383+
384+
found = false;
385+
return default;
386+
}
262387
}
263388
}

src/libraries/System.Linq/src/System/Linq/OrderedEnumerable.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ IOrderedEnumerable<TElement> IOrderedEnumerable<TElement>.CreateOrderedEnumerabl
103103
}
104104
}
105105

106-
internal sealed class OrderedEnumerable<TElement, TKey> : OrderedEnumerable<TElement>
106+
internal sealed partial class OrderedEnumerable<TElement, TKey> : OrderedEnumerable<TElement>
107107
{
108108
private readonly OrderedEnumerable<TElement>? _parent;
109109
private readonly Func<TElement, TKey> _keySelector;

0 commit comments

Comments
 (0)