From 8185bfe8fb238379befa725a97eac1a3ac1e5c99 Mon Sep 17 00:00:00 2001 From: EgorBo Date: Thu, 16 May 2024 23:41:41 +0200 Subject: [PATCH] Handle SIMD16 as well --- src/coreclr/jit/codegenarm64.cpp | 59 +++++++++++++++++++++++++------- src/coreclr/jit/simd.h | 11 ++++++ 2 files changed, 58 insertions(+), 12 deletions(-) diff --git a/src/coreclr/jit/codegenarm64.cpp b/src/coreclr/jit/codegenarm64.cpp index 655c855d88b68..1b9c517a501d9 100644 --- a/src/coreclr/jit/codegenarm64.cpp +++ b/src/coreclr/jit/codegenarm64.cpp @@ -2406,14 +2406,31 @@ void CodeGen::genSetRegToConst(regNumber targetReg, var_types targetType, GenTre } else { - // Get a temp integer register to compute long address. - regNumber addrReg = internalRegisters.GetSingle(tree); + simd8_t val = vecCon->gtSimd8Val; + if (ElementsAreSame(val.i32, 2) && emitter::emitIns_valid_imm_for_movi(val.i32[0], EA_4BYTE)) + { + emit->emitIns_R_I(INS_movi, attr, targetReg, val.i32[0], INS_OPTS_2S); + } + else if (ElementsAreSame(val.i16, 4) && + emitter::emitIns_valid_imm_for_movi(val.i16[0], EA_2BYTE)) + { + emit->emitIns_R_I(INS_movi, attr, targetReg, val.i16[0], INS_OPTS_4H); + } + else if (ElementsAreSame(val.i8, 8) && emitter::emitIns_valid_imm_for_movi(val.i8[0], EA_1BYTE)) + { + emit->emitIns_R_I(INS_movi, attr, targetReg, val.i8[0], INS_OPTS_8B); + } + else + { + // Get a temp integer register to compute long address. + regNumber addrReg = internalRegisters.GetSingle(tree); - simd8_t constValue; - memcpy(&constValue, &vecCon->gtSimdVal, sizeof(simd8_t)); + simd8_t constValue; + memcpy(&constValue, &vecCon->gtSimdVal, sizeof(simd8_t)); - CORINFO_FIELD_HANDLE hnd = emit->emitSimd8Const(constValue); - emit->emitIns_R_C(INS_ldr, attr, targetReg, addrReg, hnd, 0); + CORINFO_FIELD_HANDLE hnd = emit->emitSimd8Const(constValue); + emit->emitIns_R_C(INS_ldr, attr, targetReg, addrReg, hnd, 0); + } } break; } @@ -2454,14 +2471,32 @@ void CodeGen::genSetRegToConst(regNumber targetReg, var_types targetType, GenTre } else { - // Get a temp integer register to compute long address. - regNumber addrReg = internalRegisters.GetSingle(tree); + simd16_t val = vecCon->gtSimd16Val; + if (ElementsAreSame(val.i32, 4) && emitter::emitIns_valid_imm_for_movi(val.i32[0], EA_4BYTE)) + { + emit->emitIns_R_I(INS_movi, attr, targetReg, val.i32[0], INS_OPTS_4S); + } + else if (ElementsAreSame(val.i16, 8) && + emitter::emitIns_valid_imm_for_movi(val.i16[0], EA_2BYTE)) + { + emit->emitIns_R_I(INS_movi, attr, targetReg, val.i16[0], INS_OPTS_8H); + } + else if (ElementsAreSame(val.i8, 16) && + emitter::emitIns_valid_imm_for_movi(val.i8[0], EA_1BYTE)) + { + emit->emitIns_R_I(INS_movi, attr, targetReg, val.i8[0], INS_OPTS_16B); + } + else + { + // Get a temp integer register to compute long address. + regNumber addrReg = internalRegisters.GetSingle(tree); - simd16_t constValue; - memcpy(&constValue, &vecCon->gtSimdVal, sizeof(simd16_t)); + simd16_t constValue; + memcpy(&constValue, &vecCon->gtSimdVal, sizeof(simd16_t)); - CORINFO_FIELD_HANDLE hnd = emit->emitSimd16Const(constValue); - emit->emitIns_R_C(INS_ldr, attr, targetReg, addrReg, hnd, 0); + CORINFO_FIELD_HANDLE hnd = emit->emitSimd16Const(constValue); + emit->emitIns_R_C(INS_ldr, attr, targetReg, addrReg, hnd, 0); + } } break; } diff --git a/src/coreclr/jit/simd.h b/src/coreclr/jit/simd.h index 3a5311aaaa79d..a388eecebdf3c 100644 --- a/src/coreclr/jit/simd.h +++ b/src/coreclr/jit/simd.h @@ -4,6 +4,17 @@ #ifndef _SIMD_H_ #define _SIMD_H_ +template +static bool ElementsAreSame(T* array, size_t size) +{ + for (size_t i = 1; i < size; i++) + { + if (array[0] != array[i]) + return false; + } + return true; +} + struct simd8_t { union