Skip to content

Commit 18e3bbf

Browse files
authored
[mono][jit] ArmBase methods are now intrinsic. (#85458)
* ArmBase methods are now intrinsic. * Arm.Yield maps to a NOP. * Adding hint operation for arm64's yield.
1 parent 08ba40d commit 18e3bbf

File tree

8 files changed

+91
-1
lines changed

8 files changed

+91
-1
lines changed

src/mono/mono/arch/arm64/arm64-codegen.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,15 @@ typedef enum {
123123
ARMSIZE_X = 0x3
124124
} ARMSize;
125125

126+
typedef enum {
127+
ARMHINT_NOP = 0x0,
128+
ARMHINT_YIELD = 0x1,
129+
ARMHINT_WFE = 0x2,
130+
ARMHINT_WFI = 0x3,
131+
ARMHINT_SEV = 0x4,
132+
ARMHINT_SEVL = 0x5
133+
} ARMHint;
134+
126135
#define arm_emit(p, ins) do { *(guint32*)(p) = (ins); (p) += 4; } while (0)
127136

128137
/* Overwrite bits [offset,offset+nbits] with value */
@@ -703,6 +712,19 @@ arm_encode_arith_imm (int imm, guint32 *shift)
703712
#define arm_mulw(p, rd, rn, rm) arm_maddw ((p), (rd), (rn), (rm), ARMREG_RZR)
704713

705714
/* FIXME: Missing multiple opcodes */
715+
#define arm_format_clx(p, sf, op, rd, rn) arm_emit ((p), 0b01011010110000000001000000000000 | (sf) << 31 | (op) << 10 | (rn) << 5 | (rd))
716+
#define arm_clsw(p, rd, rn) arm_format_clx ((p), 0, 1, (rd), (rn))
717+
#define arm_clsx(p, rd, rn) arm_format_clx ((p), 1, 1, (rd), (rn))
718+
#define arm_clzw(p, rd, rn) arm_format_clx ((p), 0, 0, (rd), (rn))
719+
#define arm_clzx(p, rd, rn) arm_format_clx ((p), 1, 0, (rd), (rn))
720+
721+
#define arm_format_mulh(p, u, rd, rn, rm) arm_emit ((p), 0b10011011010000000111110000000000 | (u) << 23 | (rm) << 16 | (rn) << 5 | (rd))
722+
#define arm_smulh(p, rd, rn, rm) arm_format_mulh ((p), 0, (rd), (rn), (rm))
723+
#define arm_umulh(p, rd, rn, rm) arm_format_mulh ((p), 1, (rd), (rn), (rm))
724+
725+
#define arm_format_rbit(p, sf, rd, rn) arm_emit ((p), 0b01011010110000000000000000000000 | (sf) << 31 | (rn) << 5 | (rd))
726+
#define arm_rbitw(p, rd, rn) arm_format_rbit ((p), 0, (rd), (rn))
727+
#define arm_rbitx(p, rd, rn) arm_format_rbit ((p), 1, (rd), (rn))
706728

707729
/* Division */
708730
#define arm_format_div(p, sf, o1, rd, rn, rm) arm_emit ((p), ((sf) << 31) | (0xd6 << 21) | ((rm) << 16) | (0x1 << 11) | ((o1) << 10) | ((rn) << 5) | ((rd) << 0))

src/mono/mono/mini/cpu-arm64.mdesc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -467,6 +467,15 @@ arm64_cbzw: src1:i len:16
467467
arm64_cbzx: src1:i len:16
468468
arm64_cbnzw: src1:i len:16
469469
arm64_cbnzx: src1:i len:16
470+
lzcnt32: dest:i src1:i len:4
471+
lzcnt64: dest:i src1:i len:4
472+
lscnt32: dest:i src1:i len:4
473+
lscnt64: dest:i src1:i len:4
474+
xop_i8_i8: dest:i src1:i len:4
475+
xop_i4_i4: dest:i src1:i len:4
476+
arm64_smulh: dest:i src1:i src2:i len:4
477+
arm64_umulh: dest:i src1:i src2:i len:4
478+
arm64_hint: len:4
470479

471480
atomic_add_i4: dest:i src1:i src2:i len:32
472481
atomic_add_i8: dest:i src1:i src2:i len:32

src/mono/mono/mini/llvm-intrinsics.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,7 @@ INTRINS(AARCH64_SHA256SU1, aarch64_crypto_sha256su1, Arm64)
318318
INTRINS(AARCH64_SHA256H, aarch64_crypto_sha256h, Arm64)
319319
INTRINS(AARCH64_SHA256H2, aarch64_crypto_sha256h2, Arm64)
320320
INTRINS(AARCH64_PMULL64, aarch64_neon_pmull64, Arm64)
321+
INTRINS(AARCH64_HINT, aarch64_hint, Arm64)
321322

322323
INTRINS_OVR_TAG_KIND(AARCH64_ADV_SIMD_FACGE, aarch64_neon_facge, Arm64, Ftoi, Scalar | V64 | V128 | I4 | I8)
323324
INTRINS_OVR_TAG_KIND(AARCH64_ADV_SIMD_FACGT, aarch64_neon_facgt, Arm64, Ftoi, Scalar | V64 | V128 | I4 | I8)

src/mono/mono/mini/mini-arm64.c

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5337,6 +5337,46 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
53375337
arm_strx (code, i, ins->sreg1, MONO_STRUCT_OFFSET (MonoContext, regs) + i * sizeof (target_mgreg_t));
53385338
break;
53395339

5340+
/**** Arm.ArmBase ****/
5341+
case OP_LZCNT32:
5342+
arm_clzw (code, dreg, sreg1);
5343+
break;
5344+
5345+
case OP_LSCNT32:
5346+
arm_clsw (code, dreg, sreg1);
5347+
break;
5348+
5349+
case OP_LZCNT64:
5350+
arm_clzx (code, dreg, sreg1);
5351+
break;
5352+
5353+
case OP_LSCNT64:
5354+
arm_clsx (code, dreg, sreg1);
5355+
break;
5356+
5357+
case OP_ARM64_SMULH:
5358+
arm_smulh (code, dreg, sreg1, sreg2);
5359+
break;
5360+
5361+
case OP_ARM64_UMULH:
5362+
arm_umulh (code, dreg, sreg1, sreg2);
5363+
break;
5364+
5365+
case OP_XOP_I8_I8:
5366+
g_assert (ins->inst_c0 == INTRINS_BITREVERSE_I64);
5367+
arm_rbitx (code, dreg, sreg1);
5368+
break;
5369+
5370+
case OP_XOP_I4_I4:
5371+
g_assert (ins->inst_c0 == INTRINS_BITREVERSE_I32);
5372+
arm_rbitw (code, dreg, sreg1);
5373+
break;
5374+
5375+
case OP_ARM64_HINT:
5376+
g_assert (ins->inst_c0 <= ARMHINT_SEVL);
5377+
arm_hint (code, ins->inst_c0);
5378+
break;
5379+
53405380
default:
53415381
g_warning ("unknown opcode %s in %s()\n", mono_inst_name (ins->opcode), __FUNCTION__);
53425382
g_assert_not_reached ();

src/mono/mono/mini/mini-llvm.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10271,6 +10271,13 @@ MONO_RESTORE_WARNING
1027110271
values [ins->dreg] = LLVMBuildSExt (builder, result, ret_t, "");
1027210272
break;
1027310273
}
10274+
case OP_ARM64_HINT: {
10275+
g_assert (ins->inst_c0 <= ARMHINT_SEVL);
10276+
LLVMValueRef hintid = LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE);
10277+
LLVMValueRef args [] = { hintid };
10278+
call_intrins (ctx, INTRINS_AARCH64_HINT, args, "");
10279+
break;
10280+
}
1027410281
case OP_ARM64_EXT: {
1027510282
LLVMTypeRef ret_t = LLVMTypeOf (lhs);
1027610283
unsigned int elems = LLVMGetVectorSize (ret_t);

src/mono/mono/mini/mini-ops.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1465,6 +1465,7 @@ MINI_OP(OP_ARM64_CBZX, "arm64_cbzx", NONE, IREG, NONE)
14651465
/* Branch if sreg1 != 0 */
14661466
MINI_OP(OP_ARM64_CBNZW, "arm64_cbnzw", NONE, IREG, NONE)
14671467
MINI_OP(OP_ARM64_CBNZX, "arm64_cbnzx", NONE, IREG, NONE)
1468+
MINI_OP(OP_ARM64_HINT, "arm64_hint", NONE, NONE, NONE)
14681469
#endif
14691470

14701471
/* Same as OUTARG_VT, but has a dreg */

src/mono/mono/mini/simd-intrinsics.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3119,6 +3119,7 @@ static SimdIntrinsic armbase_methods [] = {
31193119
{SN_LeadingZeroCount},
31203120
{SN_MultiplyHigh},
31213121
{SN_ReverseElementBits},
3122+
{SN_Yield},
31223123
{SN_get_IsSupported},
31233124
};
31243125

@@ -3562,7 +3563,7 @@ static const SimdIntrinsic dp_methods [] = {
35623563
static const IntrinGroup supported_arm_intrinsics [] = {
35633564
{ "AdvSimd", MONO_CPU_ARM64_NEON, advsimd_methods, sizeof (advsimd_methods) },
35643565
{ "Aes", MONO_CPU_ARM64_CRYPTO, crypto_aes_methods, sizeof (crypto_aes_methods) },
3565-
{ "ArmBase", MONO_CPU_ARM64_BASE, armbase_methods, sizeof (armbase_methods) },
3566+
{ "ArmBase", MONO_CPU_ARM64_BASE, armbase_methods, sizeof (armbase_methods), TRUE },
35663567
{ "Crc32", MONO_CPU_ARM64_CRC, crc32_methods, sizeof (crc32_methods) },
35673568
{ "Dp", MONO_CPU_ARM64_DP, dp_methods, sizeof (dp_methods) },
35683569
{ "Rdm", MONO_CPU_ARM64_RDM, rdm_methods, sizeof (rdm_methods) },
@@ -3598,6 +3599,14 @@ emit_arm64_intrinsics (
35983599
(is_64bit ? OP_XOP_I8_I8 : OP_XOP_I4_I4),
35993600
(is_64bit ? INTRINS_BITREVERSE_I64 : INTRINS_BITREVERSE_I32),
36003601
arg0_type, fsig, args);
3602+
case SN_Yield: {
3603+
MonoInst* ins;
3604+
MONO_INST_NEW (cfg, ins, OP_ARM64_HINT);
3605+
ins->inst_c0 = ARMHINT_YIELD;
3606+
MONO_ADD_INS (cfg->cbb, ins);
3607+
return ins;
3608+
}
3609+
36013610
default:
36023611
g_assert_not_reached (); // if a new API is added we need to either implement it or change IsSupported to false
36033612
}

src/mono/mono/mini/simd-methods.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,7 @@ METHOD(CarrylessMultiply)
286286
// ArmBase
287287
METHOD(LeadingSignCount)
288288
METHOD(ReverseElementBits)
289+
METHOD(Yield)
289290
// Crc32
290291
METHOD(ComputeCrc32)
291292
METHOD(ComputeCrc32C)

0 commit comments

Comments
 (0)