mirror of
https://github.com/openjdk/jdk.git
synced 2026-01-28 03:58:21 +00:00
Extract some helper functions for better readability
This commit is contained in:
parent
481c3ee647
commit
fc3dee3d08
@ -1960,6 +1960,87 @@ void C2_MacroAssembler::neon_reduce_logical(int opc, Register dst, BasicType bt,
|
||||
BLOCK_COMMENT("} neon_reduce_logical");
|
||||
}
|
||||
|
||||
// Helper function to decode min/max reduction operation properties
|
||||
static void decode_minmax_reduction_opc(int opc, bool& is_min, bool& is_unsigned,
|
||||
Assembler::Condition& cond) {
|
||||
switch(opc) {
|
||||
case Op_MinReductionV:
|
||||
is_min = true; is_unsigned = false; cond = Assembler::LT; break;
|
||||
case Op_MaxReductionV:
|
||||
is_min = false; is_unsigned = false; cond = Assembler::GT; break;
|
||||
case Op_UMinReductionV:
|
||||
is_min = true; is_unsigned = true; cond = Assembler::LO; break;
|
||||
case Op_UMaxReductionV:
|
||||
is_min = false; is_unsigned = true; cond = Assembler::HI; break;
|
||||
default:
|
||||
ShouldNotReachHere();
|
||||
}
|
||||
}
|
||||
|
||||
// neon minp: pairwise minimum operation
|
||||
void C2_MacroAssembler::neon_minp(bool is_unsigned, FloatRegister dst,
|
||||
SIMD_Arrangement size, FloatRegister src1,
|
||||
FloatRegister src2) {
|
||||
if (is_unsigned) {
|
||||
uminp(dst, size, src1, src2);
|
||||
} else {
|
||||
sminp(dst, size, src1, src2);
|
||||
}
|
||||
}
|
||||
|
||||
// neon maxp: pairwise maximum operation
|
||||
void C2_MacroAssembler::neon_maxp(bool is_unsigned, FloatRegister dst,
|
||||
SIMD_Arrangement size, FloatRegister src1,
|
||||
FloatRegister src2) {
|
||||
if (is_unsigned) {
|
||||
umaxp(dst, size, src1, src2);
|
||||
} else {
|
||||
smaxp(dst, size, src1, src2);
|
||||
}
|
||||
}
|
||||
|
||||
// neon minv: reduction minimum operation
|
||||
void C2_MacroAssembler::neon_minv(bool is_unsigned, FloatRegister dst,
|
||||
SIMD_Arrangement size, FloatRegister src) {
|
||||
if (is_unsigned) {
|
||||
uminv(dst, size, src);
|
||||
} else {
|
||||
sminv(dst, size, src);
|
||||
}
|
||||
}
|
||||
|
||||
// neon maxv: reduction maximum operation
|
||||
void C2_MacroAssembler::neon_maxv(bool is_unsigned, FloatRegister dst,
|
||||
SIMD_Arrangement size, FloatRegister src) {
|
||||
if (is_unsigned) {
|
||||
umaxv(dst, size, src);
|
||||
} else {
|
||||
smaxv(dst, size, src);
|
||||
}
|
||||
}
|
||||
|
||||
// sve minv: reduction minimum operation
|
||||
void C2_MacroAssembler::sve_minv(bool is_unsigned, FloatRegister dst,
|
||||
SIMD_RegVariant size, PRegister pg,
|
||||
FloatRegister src) {
|
||||
if (is_unsigned) {
|
||||
sve_uminv(dst, size, pg, src);
|
||||
} else {
|
||||
sve_sminv(dst, size, pg, src);
|
||||
}
|
||||
}
|
||||
|
||||
// sve maxv: reduction maximum operation
|
||||
void C2_MacroAssembler::sve_maxv(bool is_unsigned, FloatRegister dst,
|
||||
SIMD_RegVariant size, PRegister pg,
|
||||
FloatRegister src) {
|
||||
if (is_unsigned) {
|
||||
sve_umaxv(dst, size, pg, src);
|
||||
} else {
|
||||
sve_smaxv(dst, size, pg, src);
|
||||
}
|
||||
}
|
||||
|
||||
// Vector reduction min/max/umin/umax for integral type with ASIMD instructions.
|
||||
// Note: vtmp is not used and expected to be fnoreg for T_LONG case.
|
||||
// Clobbers: rscratch1, rflags
|
||||
@ -1973,11 +2054,10 @@ void C2_MacroAssembler::neon_reduce_minmax_integral(int opc, Register dst, Basic
|
||||
assert(bt == T_BYTE || bt == T_SHORT || bt == T_INT || bt == T_LONG, "unsupported");
|
||||
assert_different_registers(dst, isrc);
|
||||
bool isQ = vector_length_in_bytes == 16;
|
||||
bool is_min = (opc == Op_MinReductionV || opc == Op_UMinReductionV);
|
||||
bool is_unsigned = (opc == Op_UMinReductionV || opc == Op_UMaxReductionV);
|
||||
Assembler::Condition cond = is_min ? (is_unsigned ? Assembler::LO : Assembler::LT)
|
||||
: (is_unsigned ? Assembler::HI : Assembler::GT);
|
||||
|
||||
bool is_min;
|
||||
bool is_unsigned;
|
||||
Condition cond;
|
||||
decode_minmax_reduction_opc(opc, is_min, is_unsigned, cond);
|
||||
BLOCK_COMMENT("neon_reduce_minmax_integral {");
|
||||
if (bt == T_LONG) {
|
||||
assert(vtmp == fnoreg, "should be");
|
||||
@ -1993,18 +2073,12 @@ void C2_MacroAssembler::neon_reduce_minmax_integral(int opc, Register dst, Basic
|
||||
if (size == T2S) {
|
||||
// For T2S (2x32-bit elements), use pairwise instructions because
|
||||
// uminv/umaxv/sminv/smaxv don't support arrangement 2S.
|
||||
if (is_unsigned) {
|
||||
is_min ? uminp(vtmp, size, vsrc, vsrc) : umaxp(vtmp, size, vsrc, vsrc);
|
||||
} else {
|
||||
is_min ? sminp(vtmp, size, vsrc, vsrc) : smaxp(vtmp, size, vsrc, vsrc);
|
||||
}
|
||||
is_min ? neon_minp(is_unsigned, vtmp, size, vsrc, vsrc)
|
||||
: neon_maxp(is_unsigned, vtmp, size, vsrc, vsrc);
|
||||
} else {
|
||||
// For other sizes, use reduction to scalar instructions.
|
||||
if (is_unsigned) {
|
||||
is_min ? uminv(vtmp, size, vsrc) : umaxv(vtmp, size, vsrc);
|
||||
} else {
|
||||
is_min ? sminv(vtmp, size, vsrc) : smaxv(vtmp, size, vsrc);
|
||||
}
|
||||
is_min ? neon_minv(is_unsigned, vtmp, size, vsrc)
|
||||
: neon_maxv(is_unsigned, vtmp, size, vsrc);
|
||||
}
|
||||
if (bt == T_INT) {
|
||||
umov(dst, vtmp, S, 0);
|
||||
@ -2096,21 +2170,18 @@ void C2_MacroAssembler::sve_reduce_integral(int opc, Register dst, BasicType bt,
|
||||
case Op_MinReductionV:
|
||||
case Op_UMaxReductionV:
|
||||
case Op_UMinReductionV: {
|
||||
bool is_unsigned = (opc == Op_UMaxReductionV || opc == Op_UMinReductionV);
|
||||
bool is_min = (opc == Op_MinReductionV || opc == Op_UMinReductionV);
|
||||
if (is_unsigned) {
|
||||
is_min ? sve_uminv(tmp, size, pg, src2) : sve_umaxv(tmp, size, pg, src2);
|
||||
} else {
|
||||
is_min ? sve_sminv(tmp, size, pg, src2) : sve_smaxv(tmp, size, pg, src2);
|
||||
}
|
||||
bool is_min;
|
||||
bool is_unsigned;
|
||||
Condition cond;
|
||||
decode_minmax_reduction_opc(opc, is_min, is_unsigned, cond);
|
||||
is_min ? sve_minv(is_unsigned, tmp, size, pg, src2)
|
||||
: sve_maxv(is_unsigned, tmp, size, pg, src2);
|
||||
// Move result from vector to general register
|
||||
if (is_unsigned || bt == T_INT || bt == T_LONG) {
|
||||
umov(dst, tmp, size, 0);
|
||||
} else {
|
||||
smov(dst, tmp, size, 0);
|
||||
}
|
||||
Assembler::Condition cond = is_min ? (is_unsigned ? Assembler::LO : Assembler::LT)
|
||||
: (is_unsigned ? Assembler::HI : Assembler::GT);
|
||||
if (bt == T_LONG) {
|
||||
cmp(dst, src1);
|
||||
csel(dst, dst, src1, cond);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2020, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -34,6 +34,20 @@
|
||||
void neon_reduce_logical_helper(int opc, bool sf, Register Rd, Register Rn, Register Rm,
|
||||
enum shift_kind kind = Assembler::LSL, unsigned shift = 0);
|
||||
|
||||
// Helper functions for min/max reduction operations
|
||||
void neon_minp(bool is_unsigned, FloatRegister dst, SIMD_Arrangement size,
|
||||
FloatRegister src1, FloatRegister src2);
|
||||
void neon_maxp(bool is_unsigned, FloatRegister dst, SIMD_Arrangement size,
|
||||
FloatRegister src1, FloatRegister src2);
|
||||
void neon_minv(bool is_unsigned, FloatRegister dst, SIMD_Arrangement size,
|
||||
FloatRegister src);
|
||||
void neon_maxv(bool is_unsigned, FloatRegister dst, SIMD_Arrangement size,
|
||||
FloatRegister src);
|
||||
void sve_minv(bool is_unsigned, FloatRegister dst, SIMD_RegVariant size,
|
||||
PRegister pg, FloatRegister src);
|
||||
void sve_maxv(bool is_unsigned, FloatRegister dst, SIMD_RegVariant size,
|
||||
PRegister pg, FloatRegister src);
|
||||
|
||||
void select_from_two_vectors_neon(FloatRegister dst, FloatRegister src1,
|
||||
FloatRegister src2, FloatRegister index,
|
||||
FloatRegister tmp, unsigned vector_length_in_bytes);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user