From 8393c4eb74afecaa70267b2a94b9b94c1d1ae384 Mon Sep 17 00:00:00 2001 From: Austin Wise Date: Mon, 17 Oct 2022 18:35:00 -0700 Subject: [PATCH] [NativeAOT] fix debug assert on large number of virtual methods (#77106) According to the ARM docs for this op code: https://developer.arm.com/documentation/ddi0596/2020-12/Base-Instructions/LDR--immediate---Load-Register--immediate--?lang=en > For the 64-bit variant: is the optional positive immediate byte offset, a multiple of 8 in the range 0 to 32760, defaulting to 0 and encoded in the "imm12" field as /8. You can see that once the offset has been devided by 8, it will be in the range [0, 4095], which will fit in the 12 bits allocated for the offset. --- .../DependencyAnalysis/Target_ARM64/ARM64Emitter.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Target_ARM64/ARM64Emitter.cs b/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Target_ARM64/ARM64Emitter.cs index 7ef040f23c285..84f67052d691d 100644 --- a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Target_ARM64/ARM64Emitter.cs +++ b/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Target_ARM64/ARM64Emitter.cs @@ -63,8 +63,7 @@ public void EmitLDR(Register regDst, Register regAddr) public void EmitLDR(Register regDst, Register regSrc, int offset) { - Debug.Assert(offset >= -255 && offset <= 4095); - if (offset >= 0) + if (offset >= 0 && offset <= 32760) { Debug.Assert(offset % 8 == 0); @@ -72,12 +71,16 @@ public void EmitLDR(Register regDst, Register regSrc, int offset) Builder.EmitUInt((uint)(0b11_1110_0_1_0_1_000000000000_00000_00000u | ((uint)offset << 10) | ((uint)regSrc << 5) | (uint)regDst)); } - else + else if (offset >= -255 && offset < 0) { uint o = (uint)offset & 0x1FF; Builder.EmitUInt((uint)(0b11_1110_0_0_010_000000000_1_1_00000_00000u | (o << 12) | ((uint)regSrc << 5) | (uint)regDst)); } + else + { + throw new NotImplementedException(); + } } public void EmitCMP(Register reg, sbyte immediate)