8330844: Add aliases for conditional jumps and additional instruction forms for x86

Reviewed-by: kvn, epeter, sviswanathan
This commit is contained in:
Scott Gibbons 2024-04-23 23:35:59 +00:00 committed by Sandhya Viswanathan
parent f60798a30e
commit 7a895552c8
4 changed files with 160 additions and 0 deletions

View File

@ -1758,6 +1758,22 @@ void Assembler::cmovl(Condition cc, Register dst, Address src) {
emit_operand(dst, src, 0);
}
void Assembler::cmpb(Address dst, Register reg) {
assert(reg->has_byte_register(), "must have byte register");
InstructionMark im(this);
prefix(dst, reg, true);
emit_int8((unsigned char)0x38);
emit_operand(reg, dst, 0);
}
void Assembler::cmpb(Register reg, Address dst) {
assert(reg->has_byte_register(), "must have byte register");
InstructionMark im(this);
prefix(dst, reg, true);
emit_int8((unsigned char)0x3a);
emit_operand(reg, dst, 0);
}
void Assembler::cmpb(Address dst, int imm8) {
InstructionMark im(this);
prefix(dst);
@ -1789,6 +1805,13 @@ void Assembler::cmpl(Register dst, Address src) {
emit_operand(dst, src, 0);
}
void Assembler::cmpl(Address dst, Register reg) {
InstructionMark im(this);
prefix(dst, reg);
emit_int8(0x39);
emit_operand(reg, dst, 0);
}
void Assembler::cmpl_imm32(Address dst, int32_t imm32) {
InstructionMark im(this);
prefix(dst);
@ -1804,6 +1827,14 @@ void Assembler::cmpw(Address dst, int imm16) {
emit_int16(imm16);
}
void Assembler::cmpw(Address dst, Register reg) {
InstructionMark im(this);
emit_int8(0x66);
prefix(dst, reg);
emit_int8((unsigned char)0x39);
emit_operand(reg, dst, 0);
}
// The 32-bit cmpxchg compares the value at adr with the contents of rax,
// and stores reg into adr if so; otherwise, the value at adr is loaded into rax,.
// The ZF is set if the compared values were equal, and cleared otherwise.
@ -4425,6 +4456,16 @@ void Assembler::vpcmpeqb(XMMRegister dst, XMMRegister nds, XMMRegister src, int
emit_int16(0x74, (0xC0 | encode));
}
void Assembler::vpcmpeqb(XMMRegister dst, XMMRegister src1, Address src2, int vector_len) {
assert(vector_len == AVX_128bit ? VM_Version::supports_avx() : VM_Version::supports_avx2(), "");
assert(vector_len <= AVX_256bit, "evex encoding is different - has k register as dest");
InstructionMark im(this);
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
vex_prefix(src2, src1->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
emit_int8(0x74);
emit_operand(dst, src2, 0);
}
// In this context, kdst is written the mask used to process the equal components
void Assembler::evpcmpeqb(KRegister kdst, XMMRegister nds, XMMRegister src, int vector_len) {
assert(VM_Version::supports_avx512bw(), "");
@ -4531,6 +4572,17 @@ void Assembler::vpcmpeqw(XMMRegister dst, XMMRegister nds, XMMRegister src, int
emit_int16(0x75, (0xC0 | encode));
}
// In this context, the dst vector contains the components that are equal, non equal components are zeroed in dst
void Assembler::vpcmpeqw(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
assert(vector_len == AVX_128bit ? VM_Version::supports_avx() : VM_Version::supports_avx2(), "");
assert(vector_len <= AVX_256bit, "evex encoding is different - has k register as dest");
InstructionMark im(this);
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
emit_int8(0x75);
emit_operand(dst, src, 0);
}
// In this context, kdst is written the mask used to process the equal components
void Assembler::evpcmpeqw(KRegister kdst, XMMRegister nds, XMMRegister src, int vector_len) {
assert(VM_Version::supports_avx512bw(), "");
@ -7648,6 +7700,14 @@ void Assembler::vpminsb(XMMRegister dst, XMMRegister nds, XMMRegister src, int v
emit_int16(0x38, (0xC0 | encode));
}
void Assembler::vpminub(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
assert(vector_len == AVX_128bit ? VM_Version::supports_avx() :
(vector_len == AVX_256bit ? VM_Version::supports_avx2() : VM_Version::supports_avx512bw()), "");
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
emit_int16(0xDA, (0xC0 | encode));
}
void Assembler::pminsw(XMMRegister dst, XMMRegister src) {
assert(VM_Version::supports_sse2(), "");
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
@ -12273,6 +12333,13 @@ void Assembler::bzhiq(Register dst, Register src1, Register src2) {
emit_int16((unsigned char)0xF5, (0xC0 | encode));
}
void Assembler::bzhil(Register dst, Register src1, Register src2) {
assert(VM_Version::supports_bmi2(), "bit manipulation instructions not supported");
InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
int encode = vex_prefix_and_encode(dst->encoding(), src2->encoding(), src1->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F_38, &attributes);
emit_int16((unsigned char)0xF5, (0xC0 | encode));
}
void Assembler::pextl(Register dst, Register src1, Register src2) {
assert(VM_Version::supports_bmi2(), "bit manipulation instructions not supported");
InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
@ -13167,6 +13234,10 @@ void Assembler::cdqq() {
emit_int16(REX_W, (unsigned char)0x99);
}
void Assembler::cdqe() {
emit_int16(REX_W, (unsigned char)0x98);
}
void Assembler::clflush(Address adr) {
assert(VM_Version::supports_clflush(), "should do");
prefix(adr);

View File

@ -1094,6 +1094,7 @@ private:
void cdql();
void cdqq();
void cdqe();
void cld();
@ -1109,12 +1110,15 @@ private:
void cmpb(Address dst, int imm8);
void cmpb(Address dst, Register reg);
void cmpb(Register reg, Address dst);
void cmpl(Address dst, int32_t imm32);
void cmpl(Register dst, int32_t imm32);
void cmpl(Register dst, Register src);
void cmpl(Register dst, Address src);
void cmpl_imm32(Address dst, int32_t imm32);
void cmpl(Address dst, Register reg);
void cmpq(Address dst, int32_t imm32);
void cmpq(Address dst, Register src);
@ -1123,6 +1127,7 @@ private:
void cmpq(Register dst, Address src);
void cmpw(Address dst, int imm16);
void cmpw(Address dst, Register reg);
void cmpxchg8 (Address adr);
@ -1802,6 +1807,7 @@ private:
void vpcmpCCbwd(XMMRegister dst, XMMRegister nds, XMMRegister src, int cond_encoding, int vector_len);
void vpcmpeqb(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len);
void vpcmpeqb(XMMRegister dst, XMMRegister src1, Address src2, int vector_len);
void evpcmpeqb(KRegister kdst, XMMRegister nds, XMMRegister src, int vector_len);
void evpcmpeqb(KRegister kdst, XMMRegister nds, Address src, int vector_len);
void evpcmpeqb(KRegister kdst, KRegister mask, XMMRegister nds, Address src, int vector_len);
@ -1816,6 +1822,7 @@ private:
void evpcmpuq(KRegister kdst, XMMRegister nds, XMMRegister src, ComparisonPredicate vcc, int vector_len);
void pcmpeqw(XMMRegister dst, XMMRegister src);
void vpcmpeqw(XMMRegister dst, XMMRegister nds, Address src, int vector_len);
void vpcmpeqw(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len);
void evpcmpeqw(KRegister kdst, XMMRegister nds, XMMRegister src, int vector_len);
void evpcmpeqw(KRegister kdst, XMMRegister nds, Address src, int vector_len);
@ -2306,6 +2313,7 @@ private:
void shrxq(Register dst, Address src1, Register src2);
void bzhiq(Register dst, Register src1, Register src2);
void bzhil(Register dst, Register src1, Register src2);
void pextl(Register dst, Register src1, Register src2);
void pdepl(Register dst, Register src1, Register src2);
@ -2581,6 +2589,7 @@ private:
// Minimum of packed integers
void pminsb(XMMRegister dst, XMMRegister src);
void vpminsb(XMMRegister dst, XMMRegister src1, XMMRegister src2, int vector_len);
void vpminub(XMMRegister dst, XMMRegister src1, XMMRegister src2, int vector_len);
void pminsw(XMMRegister dst, XMMRegister src);
void vpminsw(XMMRegister dst, XMMRegister src1, XMMRegister src2, int vector_len);
void pminsd(XMMRegister dst, XMMRegister src);

View File

@ -3570,11 +3570,21 @@ void MacroAssembler::vpcmpeqb(XMMRegister dst, XMMRegister nds, XMMRegister src,
Assembler::vpcmpeqb(dst, nds, src, vector_len);
}
void MacroAssembler::vpcmpeqb(XMMRegister dst, XMMRegister src1, Address src2, int vector_len) {
assert(((dst->encoding() < 16 && src1->encoding() < 16) || VM_Version::supports_avx512vlbw()),"XMM register should be 0-15");
Assembler::vpcmpeqb(dst, src1, src2, vector_len);
}
void MacroAssembler::vpcmpeqw(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
assert(((dst->encoding() < 16 && src->encoding() < 16 && nds->encoding() < 16) || VM_Version::supports_avx512vlbw()),"XMM register should be 0-15");
Assembler::vpcmpeqw(dst, nds, src, vector_len);
}
void MacroAssembler::vpcmpeqw(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
assert(((dst->encoding() < 16 && nds->encoding() < 16) || VM_Version::supports_avx512vlbw()),"XMM register should be 0-15");
Assembler::vpcmpeqw(dst, nds, src, vector_len);
}
void MacroAssembler::evpcmpeqd(KRegister kdst, KRegister mask, XMMRegister nds, AddressLiteral src, int vector_len, Register rscratch) {
assert(rscratch != noreg || always_reachable(src), "missing");

View File

@ -955,6 +955,74 @@ public:
// contained in the location described by entry (not the address of entry)
void jump(ArrayAddress entry, Register rscratch);
// Adding more natural conditional jump instructions
void ALWAYSINLINE jo(Label& L, bool maybe_short = true) { jcc(Assembler::overflow, L, maybe_short); }
void ALWAYSINLINE jno(Label& L, bool maybe_short = true) { jcc(Assembler::noOverflow, L, maybe_short); }
void ALWAYSINLINE js(Label& L, bool maybe_short = true) { jcc(Assembler::negative, L, maybe_short); }
void ALWAYSINLINE jns(Label& L, bool maybe_short = true) { jcc(Assembler::positive, L, maybe_short); }
void ALWAYSINLINE je(Label& L, bool maybe_short = true) { jcc(Assembler::equal, L, maybe_short); }
void ALWAYSINLINE jz(Label& L, bool maybe_short = true) { jcc(Assembler::zero, L, maybe_short); }
void ALWAYSINLINE jne(Label& L, bool maybe_short = true) { jcc(Assembler::notEqual, L, maybe_short); }
void ALWAYSINLINE jnz(Label& L, bool maybe_short = true) { jcc(Assembler::notZero, L, maybe_short); }
void ALWAYSINLINE jb(Label& L, bool maybe_short = true) { jcc(Assembler::below, L, maybe_short); }
void ALWAYSINLINE jnae(Label& L, bool maybe_short = true) { jcc(Assembler::below, L, maybe_short); }
void ALWAYSINLINE jc(Label& L, bool maybe_short = true) { jcc(Assembler::carrySet, L, maybe_short); }
void ALWAYSINLINE jnb(Label& L, bool maybe_short = true) { jcc(Assembler::aboveEqual, L, maybe_short); }
void ALWAYSINLINE jae(Label& L, bool maybe_short = true) { jcc(Assembler::aboveEqual, L, maybe_short); }
void ALWAYSINLINE jnc(Label& L, bool maybe_short = true) { jcc(Assembler::carryClear, L, maybe_short); }
void ALWAYSINLINE jbe(Label& L, bool maybe_short = true) { jcc(Assembler::belowEqual, L, maybe_short); }
void ALWAYSINLINE jna(Label& L, bool maybe_short = true) { jcc(Assembler::belowEqual, L, maybe_short); }
void ALWAYSINLINE ja(Label& L, bool maybe_short = true) { jcc(Assembler::above, L, maybe_short); }
void ALWAYSINLINE jnbe(Label& L, bool maybe_short = true) { jcc(Assembler::above, L, maybe_short); }
void ALWAYSINLINE jl(Label& L, bool maybe_short = true) { jcc(Assembler::less, L, maybe_short); }
void ALWAYSINLINE jnge(Label& L, bool maybe_short = true) { jcc(Assembler::less, L, maybe_short); }
void ALWAYSINLINE jge(Label& L, bool maybe_short = true) { jcc(Assembler::greaterEqual, L, maybe_short); }
void ALWAYSINLINE jnl(Label& L, bool maybe_short = true) { jcc(Assembler::greaterEqual, L, maybe_short); }
void ALWAYSINLINE jle(Label& L, bool maybe_short = true) { jcc(Assembler::lessEqual, L, maybe_short); }
void ALWAYSINLINE jng(Label& L, bool maybe_short = true) { jcc(Assembler::lessEqual, L, maybe_short); }
void ALWAYSINLINE jg(Label& L, bool maybe_short = true) { jcc(Assembler::greater, L, maybe_short); }
void ALWAYSINLINE jnle(Label& L, bool maybe_short = true) { jcc(Assembler::greater, L, maybe_short); }
void ALWAYSINLINE jp(Label& L, bool maybe_short = true) { jcc(Assembler::parity, L, maybe_short); }
void ALWAYSINLINE jpe(Label& L, bool maybe_short = true) { jcc(Assembler::parity, L, maybe_short); }
void ALWAYSINLINE jnp(Label& L, bool maybe_short = true) { jcc(Assembler::noParity, L, maybe_short); }
void ALWAYSINLINE jpo(Label& L, bool maybe_short = true) { jcc(Assembler::noParity, L, maybe_short); }
// * No condition for this * void ALWAYSINLINE jcxz(Label& L, bool maybe_short = true) { jcc(Assembler::cxz, L, maybe_short); }
// * No condition for this * void ALWAYSINLINE jecxz(Label& L, bool maybe_short = true) { jcc(Assembler::cxz, L, maybe_short); }
// Short versions of the above
void ALWAYSINLINE jo_b(Label& L) { jccb(Assembler::overflow, L); }
void ALWAYSINLINE jno_b(Label& L) { jccb(Assembler::noOverflow, L); }
void ALWAYSINLINE js_b(Label& L) { jccb(Assembler::negative, L); }
void ALWAYSINLINE jns_b(Label& L) { jccb(Assembler::positive, L); }
void ALWAYSINLINE je_b(Label& L) { jccb(Assembler::equal, L); }
void ALWAYSINLINE jz_b(Label& L) { jccb(Assembler::zero, L); }
void ALWAYSINLINE jne_b(Label& L) { jccb(Assembler::notEqual, L); }
void ALWAYSINLINE jnz_b(Label& L) { jccb(Assembler::notZero, L); }
void ALWAYSINLINE jb_b(Label& L) { jccb(Assembler::below, L); }
void ALWAYSINLINE jnae_b(Label& L) { jccb(Assembler::below, L); }
void ALWAYSINLINE jc_b(Label& L) { jccb(Assembler::carrySet, L); }
void ALWAYSINLINE jnb_b(Label& L) { jccb(Assembler::aboveEqual, L); }
void ALWAYSINLINE jae_b(Label& L) { jccb(Assembler::aboveEqual, L); }
void ALWAYSINLINE jnc_b(Label& L) { jccb(Assembler::carryClear, L); }
void ALWAYSINLINE jbe_b(Label& L) { jccb(Assembler::belowEqual, L); }
void ALWAYSINLINE jna_b(Label& L) { jccb(Assembler::belowEqual, L); }
void ALWAYSINLINE ja_b(Label& L) { jccb(Assembler::above, L); }
void ALWAYSINLINE jnbe_b(Label& L) { jccb(Assembler::above, L); }
void ALWAYSINLINE jl_b(Label& L) { jccb(Assembler::less, L); }
void ALWAYSINLINE jnge_b(Label& L) { jccb(Assembler::less, L); }
void ALWAYSINLINE jge_b(Label& L) { jccb(Assembler::greaterEqual, L); }
void ALWAYSINLINE jnl_b(Label& L) { jccb(Assembler::greaterEqual, L); }
void ALWAYSINLINE jle_b(Label& L) { jccb(Assembler::lessEqual, L); }
void ALWAYSINLINE jng_b(Label& L) { jccb(Assembler::lessEqual, L); }
void ALWAYSINLINE jg_b(Label& L) { jccb(Assembler::greater, L); }
void ALWAYSINLINE jnle_b(Label& L) { jccb(Assembler::greater, L); }
void ALWAYSINLINE jp_b(Label& L) { jccb(Assembler::parity, L); }
void ALWAYSINLINE jpe_b(Label& L) { jccb(Assembler::parity, L); }
void ALWAYSINLINE jnp_b(Label& L) { jccb(Assembler::noParity, L); }
void ALWAYSINLINE jpo_b(Label& L) { jccb(Assembler::noParity, L); }
// * No condition for this * void ALWAYSINLINE jcxz_b(Label& L) { jccb(Assembler::cxz, L); }
// * No condition for this * void ALWAYSINLINE jecxz_b(Label& L) { jccb(Assembler::cxz, L); }
// Floating
void push_f(XMMRegister r);
@ -1389,7 +1457,9 @@ public:
void vpbroadcastq(XMMRegister dst, AddressLiteral src, int vector_len, Register rscratch = noreg);
void vpcmpeqb(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len);
void vpcmpeqb(XMMRegister dst, XMMRegister src1, Address src2, int vector_len);
void vpcmpeqw(XMMRegister dst, XMMRegister nds, Address src, int vector_len);
void vpcmpeqw(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len);
void evpcmpeqd(KRegister kdst, KRegister mask, XMMRegister nds, AddressLiteral src, int vector_len, Register rscratch = noreg);