src/cpu/x86/vm/assembler_x86.cpp
Index
Unified diffs
Context diffs
Sdiffs
Wdiffs
Patch
New
Old
Previous File
Next File
8004250 Cdiff src/cpu/x86/vm/assembler_x86.cpp
src/cpu/x86/vm/assembler_x86.cpp
Print this page
*** 224,284 ****
void Assembler::emit_arith_b(int op1, int op2, Register dst, int imm8) {
assert(dst->has_byte_register(), "must have byte register");
assert(isByte(op1) && isByte(op2), "wrong opcode");
assert(isByte(imm8), "not a byte");
assert((op1 & 0x01) == 0, "should be 8bit operation");
! emit_byte(op1);
! emit_byte(op2 | encode(dst));
! emit_byte(imm8);
}
void Assembler::emit_arith(int op1, int op2, Register dst, int32_t imm32) {
assert(isByte(op1) && isByte(op2), "wrong opcode");
assert((op1 & 0x01) == 1, "should be 32bit operation");
assert((op1 & 0x02) == 0, "sign-extension bit should not be set");
if (is8bit(imm32)) {
! emit_byte(op1 | 0x02); // set sign bit
! emit_byte(op2 | encode(dst));
! emit_byte(imm32 & 0xFF);
} else {
! emit_byte(op1);
! emit_byte(op2 | encode(dst));
emit_long(imm32);
}
}
// Force generation of a 4 byte immediate value even if it fits into 8bit
void Assembler::emit_arith_imm32(int op1, int op2, Register dst, int32_t imm32) {
assert(isByte(op1) && isByte(op2), "wrong opcode");
assert((op1 & 0x01) == 1, "should be 32bit operation");
assert((op1 & 0x02) == 0, "sign-extension bit should not be set");
! emit_byte(op1);
! emit_byte(op2 | encode(dst));
emit_long(imm32);
}
// immediate-to-memory forms
void Assembler::emit_arith_operand(int op1, Register rm, Address adr, int32_t imm32) {
assert((op1 & 0x01) == 1, "should be 32bit operation");
assert((op1 & 0x02) == 0, "sign-extension bit should not be set");
if (is8bit(imm32)) {
! emit_byte(op1 | 0x02); // set sign bit
emit_operand(rm, adr, 1);
! emit_byte(imm32 & 0xFF);
} else {
! emit_byte(op1);
emit_operand(rm, adr, 4);
emit_long(imm32);
}
}
void Assembler::emit_arith(int op1, int op2, Register dst, Register src) {
assert(isByte(op1) && isByte(op2), "wrong opcode");
! emit_byte(op1);
! emit_byte(op2 | encode(dst) << 3 | encode(src));
}
void Assembler::emit_operand(Register reg, Register base, Register index,
Address::ScaleFactor scale, int disp,
--- 224,284 ----
void Assembler::emit_arith_b(int op1, int op2, Register dst, int imm8) {
assert(dst->has_byte_register(), "must have byte register");
assert(isByte(op1) && isByte(op2), "wrong opcode");
assert(isByte(imm8), "not a byte");
assert((op1 & 0x01) == 0, "should be 8bit operation");
! emit_int8(op1);
! emit_int8(op2 | encode(dst));
! emit_int8(imm8);
}
void Assembler::emit_arith(int op1, int op2, Register dst, int32_t imm32) {
assert(isByte(op1) && isByte(op2), "wrong opcode");
assert((op1 & 0x01) == 1, "should be 32bit operation");
assert((op1 & 0x02) == 0, "sign-extension bit should not be set");
if (is8bit(imm32)) {
! emit_int8(op1 | 0x02); // set sign bit
! emit_int8(op2 | encode(dst));
! emit_int8(imm32 & 0xFF);
} else {
! emit_int8(op1);
! emit_int8(op2 | encode(dst));
emit_long(imm32);
}
}
// Force generation of a 4 byte immediate value even if it fits into 8bit
void Assembler::emit_arith_imm32(int op1, int op2, Register dst, int32_t imm32) {
assert(isByte(op1) && isByte(op2), "wrong opcode");
assert((op1 & 0x01) == 1, "should be 32bit operation");
assert((op1 & 0x02) == 0, "sign-extension bit should not be set");
! emit_int8(op1);
! emit_int8(op2 | encode(dst));
emit_long(imm32);
}
// immediate-to-memory forms
void Assembler::emit_arith_operand(int op1, Register rm, Address adr, int32_t imm32) {
assert((op1 & 0x01) == 1, "should be 32bit operation");
assert((op1 & 0x02) == 0, "sign-extension bit should not be set");
if (is8bit(imm32)) {
! emit_int8(op1 | 0x02); // set sign bit
emit_operand(rm, adr, 1);
! emit_int8(imm32 & 0xFF);
} else {
! emit_int8(op1);
emit_operand(rm, adr, 4);
emit_long(imm32);
}
}
void Assembler::emit_arith(int op1, int op2, Register dst, Register src) {
assert(isByte(op1) && isByte(op2), "wrong opcode");
! emit_int8(op1);
! emit_int8(op2 | encode(dst) << 3 | encode(src));
}
void Assembler::emit_operand(Register reg, Register base, Register index,
Address::ScaleFactor scale, int disp,
*** 299,379 ****
if (disp == 0 && rtype == relocInfo::none &&
base != rbp LP64_ONLY(&& base != r13)) {
// [base + index*scale]
// [00 reg 100][ss index base]
assert(index != rsp, "illegal addressing mode");
! emit_byte(0x04 | regenc);
! emit_byte(scale << 6 | indexenc | baseenc);
} else if (is8bit(disp) && rtype == relocInfo::none) {
// [base + index*scale + imm8]
// [01 reg 100][ss index base] imm8
assert(index != rsp, "illegal addressing mode");
! emit_byte(0x44 | regenc);
! emit_byte(scale << 6 | indexenc | baseenc);
! emit_byte(disp & 0xFF);
} else {
// [base + index*scale + disp32]
// [10 reg 100][ss index base] disp32
assert(index != rsp, "illegal addressing mode");
! emit_byte(0x84 | regenc);
! emit_byte(scale << 6 | indexenc | baseenc);
emit_data(disp, rspec, disp32_operand);
}
} else if (base == rsp LP64_ONLY(|| base == r12)) {
// [rsp + disp]
if (disp == 0 && rtype == relocInfo::none) {
// [rsp]
// [00 reg 100][00 100 100]
! emit_byte(0x04 | regenc);
! emit_byte(0x24);
} else if (is8bit(disp) && rtype == relocInfo::none) {
// [rsp + imm8]
// [01 reg 100][00 100 100] disp8
! emit_byte(0x44 | regenc);
! emit_byte(0x24);
! emit_byte(disp & 0xFF);
} else {
// [rsp + imm32]
// [10 reg 100][00 100 100] disp32
! emit_byte(0x84 | regenc);
! emit_byte(0x24);
emit_data(disp, rspec, disp32_operand);
}
} else {
// [base + disp]
assert(base != rsp LP64_ONLY(&& base != r12), "illegal addressing mode");
if (disp == 0 && rtype == relocInfo::none &&
base != rbp LP64_ONLY(&& base != r13)) {
// [base]
// [00 reg base]
! emit_byte(0x00 | regenc | baseenc);
} else if (is8bit(disp) && rtype == relocInfo::none) {
// [base + disp8]
// [01 reg base] disp8
! emit_byte(0x40 | regenc | baseenc);
! emit_byte(disp & 0xFF);
} else {
// [base + disp32]
// [10 reg base] disp32
! emit_byte(0x80 | regenc | baseenc);
emit_data(disp, rspec, disp32_operand);
}
}
} else {
if (index->is_valid()) {
assert(scale != Address::no_scale, "inconsistent address");
// [index*scale + disp]
// [00 reg 100][ss index 101] disp32
assert(index != rsp, "illegal addressing mode");
! emit_byte(0x04 | regenc);
! emit_byte(scale << 6 | indexenc | 0x05);
emit_data(disp, rspec, disp32_operand);
} else if (rtype != relocInfo::none ) {
// [disp] (64bit) RIP-RELATIVE (32bit) abs
// [00 000 101] disp32
! emit_byte(0x05 | regenc);
// Note that the RIP-rel. correction applies to the generated
// disp field, but _not_ to the target address in the rspec.
// disp was created by converting the target address minus the pc
// at the start of the instruction. That needs more correction here.
--- 299,379 ----
if (disp == 0 && rtype == relocInfo::none &&
base != rbp LP64_ONLY(&& base != r13)) {
// [base + index*scale]
// [00 reg 100][ss index base]
assert(index != rsp, "illegal addressing mode");
! emit_int8(0x04 | regenc);
! emit_int8(scale << 6 | indexenc | baseenc);
} else if (is8bit(disp) && rtype == relocInfo::none) {
// [base + index*scale + imm8]
// [01 reg 100][ss index base] imm8
assert(index != rsp, "illegal addressing mode");
! emit_int8(0x44 | regenc);
! emit_int8(scale << 6 | indexenc | baseenc);
! emit_int8(disp & 0xFF);
} else {
// [base + index*scale + disp32]
// [10 reg 100][ss index base] disp32
assert(index != rsp, "illegal addressing mode");
! emit_int8(0x84 | regenc);
! emit_int8(scale << 6 | indexenc | baseenc);
emit_data(disp, rspec, disp32_operand);
}
} else if (base == rsp LP64_ONLY(|| base == r12)) {
// [rsp + disp]
if (disp == 0 && rtype == relocInfo::none) {
// [rsp]
// [00 reg 100][00 100 100]
! emit_int8(0x04 | regenc);
! emit_int8(0x24);
} else if (is8bit(disp) && rtype == relocInfo::none) {
// [rsp + imm8]
// [01 reg 100][00 100 100] disp8
! emit_int8(0x44 | regenc);
! emit_int8(0x24);
! emit_int8(disp & 0xFF);
} else {
// [rsp + imm32]
// [10 reg 100][00 100 100] disp32
! emit_int8(0x84 | regenc);
! emit_int8(0x24);
emit_data(disp, rspec, disp32_operand);
}
} else {
// [base + disp]
assert(base != rsp LP64_ONLY(&& base != r12), "illegal addressing mode");
if (disp == 0 && rtype == relocInfo::none &&
base != rbp LP64_ONLY(&& base != r13)) {
// [base]
// [00 reg base]
! emit_int8(0x00 | regenc | baseenc);
} else if (is8bit(disp) && rtype == relocInfo::none) {
// [base + disp8]
// [01 reg base] disp8
! emit_int8(0x40 | regenc | baseenc);
! emit_int8(disp & 0xFF);
} else {
// [base + disp32]
// [10 reg base] disp32
! emit_int8(0x80 | regenc | baseenc);
emit_data(disp, rspec, disp32_operand);
}
}
} else {
if (index->is_valid()) {
assert(scale != Address::no_scale, "inconsistent address");
// [index*scale + disp]
// [00 reg 100][ss index 101] disp32
assert(index != rsp, "illegal addressing mode");
! emit_int8(0x04 | regenc);
! emit_int8(scale << 6 | indexenc | 0x05);
emit_data(disp, rspec, disp32_operand);
} else if (rtype != relocInfo::none ) {
// [disp] (64bit) RIP-RELATIVE (32bit) abs
// [00 000 101] disp32
! emit_int8(0x05 | regenc);
// Note that the RIP-rel. correction applies to the generated
// disp field, but _not_ to the target address in the rspec.
// disp was created by converting the target address minus the pc
// at the start of the instruction. That needs more correction here.
*** 389,400 ****
} else {
// 32bit never did this, did everything as the rip-rel/disp code above
// [disp] ABSOLUTE
// [00 reg 100][00 100 101] disp32
! emit_byte(0x04 | regenc);
! emit_byte(0x25);
emit_data(disp, rspec, disp32_operand);
}
}
}
--- 389,400 ----
} else {
// 32bit never did this, did everything as the rip-rel/disp code above
// [disp] ABSOLUTE
// [00 reg 100][00 100 101] disp32
! emit_int8(0x04 | regenc);
! emit_int8(0x25);
emit_data(disp, rspec, disp32_operand);
}
}
}
*** 881,892 ****
void Assembler::emit_farith(int b1, int b2, int i) {
assert(isByte(b1) && isByte(b2), "wrong opcode");
assert(0 <= i && i < 8, "illegal stack offset");
! emit_byte(b1);
! emit_byte(b2 + i);
}
// Now the Assembler instructions (identical for 32/64 bits)
--- 881,892 ----
void Assembler::emit_farith(int b1, int b2, int i) {
assert(isByte(b1) && isByte(b2), "wrong opcode");
assert(0 <= i && i < 8, "illegal stack offset");
! emit_int8(b1);
! emit_int8(b2 + i);
}
// Now the Assembler instructions (identical for 32/64 bits)
*** 897,907 ****
}
void Assembler::adcl(Address dst, Register src) {
InstructionMark im(this);
prefix(dst, src);
! emit_byte(0x11);
emit_operand(src, dst);
}
void Assembler::adcl(Register dst, int32_t imm32) {
prefix(dst);
--- 897,907 ----
}
void Assembler::adcl(Address dst, Register src) {
InstructionMark im(this);
prefix(dst, src);
! emit_int8(0x11);
emit_operand(src, dst);
}
void Assembler::adcl(Register dst, int32_t imm32) {
prefix(dst);
*** 909,919 ****
}
void Assembler::adcl(Register dst, Address src) {
InstructionMark im(this);
prefix(src, dst);
! emit_byte(0x13);
emit_operand(dst, src);
}
void Assembler::adcl(Register dst, Register src) {
(void) prefix_and_encode(dst->encoding(), src->encoding());
--- 909,919 ----
}
void Assembler::adcl(Register dst, Address src) {
InstructionMark im(this);
prefix(src, dst);
! emit_int8(0x13);
emit_operand(dst, src);
}
void Assembler::adcl(Register dst, Register src) {
(void) prefix_and_encode(dst->encoding(), src->encoding());
*** 927,937 ****
}
void Assembler::addl(Address dst, Register src) {
InstructionMark im(this);
prefix(dst, src);
! emit_byte(0x01);
emit_operand(src, dst);
}
void Assembler::addl(Register dst, int32_t imm32) {
prefix(dst);
--- 927,937 ----
}
void Assembler::addl(Address dst, Register src) {
InstructionMark im(this);
prefix(dst, src);
! emit_int8(0x01);
emit_operand(src, dst);
}
void Assembler::addl(Register dst, int32_t imm32) {
prefix(dst);
*** 939,949 ****
}
void Assembler::addl(Register dst, Address src) {
InstructionMark im(this);
prefix(src, dst);
! emit_byte(0x03);
emit_operand(dst, src);
}
void Assembler::addl(Register dst, Register src) {
(void) prefix_and_encode(dst->encoding(), src->encoding());
--- 939,949 ----
}
void Assembler::addl(Register dst, Address src) {
InstructionMark im(this);
prefix(src, dst);
! emit_int8(0x03);
emit_operand(dst, src);
}
void Assembler::addl(Register dst, Register src) {
(void) prefix_and_encode(dst->encoding(), src->encoding());
*** 951,992 ****
}
void Assembler::addr_nop_4() {
assert(UseAddressNop, "no CPU support");
// 4 bytes: NOP DWORD PTR [EAX+0]
! emit_byte(0x0F);
! emit_byte(0x1F);
! emit_byte(0x40); // emit_rm(cbuf, 0x1, EAX_enc, EAX_enc);
! emit_byte(0); // 8-bits offset (1 byte)
}
void Assembler::addr_nop_5() {
assert(UseAddressNop, "no CPU support");
// 5 bytes: NOP DWORD PTR [EAX+EAX*0+0] 8-bits offset
! emit_byte(0x0F);
! emit_byte(0x1F);
! emit_byte(0x44); // emit_rm(cbuf, 0x1, EAX_enc, 0x4);
! emit_byte(0x00); // emit_rm(cbuf, 0x0, EAX_enc, EAX_enc);
! emit_byte(0); // 8-bits offset (1 byte)
}
void Assembler::addr_nop_7() {
assert(UseAddressNop, "no CPU support");
// 7 bytes: NOP DWORD PTR [EAX+0] 32-bits offset
! emit_byte(0x0F);
! emit_byte(0x1F);
! emit_byte(0x80); // emit_rm(cbuf, 0x2, EAX_enc, EAX_enc);
emit_long(0); // 32-bits offset (4 bytes)
}
void Assembler::addr_nop_8() {
assert(UseAddressNop, "no CPU support");
// 8 bytes: NOP DWORD PTR [EAX+EAX*0+0] 32-bits offset
! emit_byte(0x0F);
! emit_byte(0x1F);
! emit_byte(0x84); // emit_rm(cbuf, 0x2, EAX_enc, 0x4);
! emit_byte(0x00); // emit_rm(cbuf, 0x0, EAX_enc, EAX_enc);
emit_long(0); // 32-bits offset (4 bytes)
}
void Assembler::addsd(XMMRegister dst, XMMRegister src) {
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
--- 951,992 ----
}
void Assembler::addr_nop_4() {
assert(UseAddressNop, "no CPU support");
// 4 bytes: NOP DWORD PTR [EAX+0]
! emit_int8(0x0F);
! emit_int8(0x1F);
! emit_int8(0x40); // emit_rm(cbuf, 0x1, EAX_enc, EAX_enc);
! emit_int8(0); // 8-bits offset (1 byte)
}
void Assembler::addr_nop_5() {
assert(UseAddressNop, "no CPU support");
// 5 bytes: NOP DWORD PTR [EAX+EAX*0+0] 8-bits offset
! emit_int8(0x0F);
! emit_int8(0x1F);
! emit_int8(0x44); // emit_rm(cbuf, 0x1, EAX_enc, 0x4);
! emit_int8(0x00); // emit_rm(cbuf, 0x0, EAX_enc, EAX_enc);
! emit_int8(0); // 8-bits offset (1 byte)
}
void Assembler::addr_nop_7() {
assert(UseAddressNop, "no CPU support");
// 7 bytes: NOP DWORD PTR [EAX+0] 32-bits offset
! emit_int8(0x0F);
! emit_int8(0x1F);
! emit_int8(0x80); // emit_rm(cbuf, 0x2, EAX_enc, EAX_enc);
emit_long(0); // 32-bits offset (4 bytes)
}
void Assembler::addr_nop_8() {
assert(UseAddressNop, "no CPU support");
// 8 bytes: NOP DWORD PTR [EAX+EAX*0+0] 32-bits offset
! emit_int8(0x0F);
! emit_int8(0x1F);
! emit_int8(0x84); // emit_rm(cbuf, 0x2, EAX_enc, 0x4);
! emit_int8(0x00); // emit_rm(cbuf, 0x0, EAX_enc, EAX_enc);
emit_long(0); // 32-bits offset (4 bytes)
}
void Assembler::addsd(XMMRegister dst, XMMRegister src) {
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
*** 1010,1080 ****
void Assembler::aesdec(XMMRegister dst, Address src) {
assert(VM_Version::supports_aes(), "");
InstructionMark im(this);
simd_prefix(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38);
! emit_byte(0xde);
emit_operand(dst, src);
}
void Assembler::aesdec(XMMRegister dst, XMMRegister src) {
assert(VM_Version::supports_aes(), "");
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38);
! emit_byte(0xde);
! emit_byte(0xC0 | encode);
}
void Assembler::aesdeclast(XMMRegister dst, Address src) {
assert(VM_Version::supports_aes(), "");
InstructionMark im(this);
simd_prefix(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38);
! emit_byte(0xdf);
emit_operand(dst, src);
}
void Assembler::aesdeclast(XMMRegister dst, XMMRegister src) {
assert(VM_Version::supports_aes(), "");
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38);
! emit_byte(0xdf);
! emit_byte(0xC0 | encode);
}
void Assembler::aesenc(XMMRegister dst, Address src) {
assert(VM_Version::supports_aes(), "");
InstructionMark im(this);
simd_prefix(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38);
! emit_byte(0xdc);
emit_operand(dst, src);
}
void Assembler::aesenc(XMMRegister dst, XMMRegister src) {
assert(VM_Version::supports_aes(), "");
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38);
! emit_byte(0xdc);
! emit_byte(0xC0 | encode);
}
void Assembler::aesenclast(XMMRegister dst, Address src) {
assert(VM_Version::supports_aes(), "");
InstructionMark im(this);
simd_prefix(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38);
! emit_byte(0xdd);
emit_operand(dst, src);
}
void Assembler::aesenclast(XMMRegister dst, XMMRegister src) {
assert(VM_Version::supports_aes(), "");
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38);
! emit_byte(0xdd);
! emit_byte(0xC0 | encode);
}
void Assembler::andl(Address dst, int32_t imm32) {
InstructionMark im(this);
prefix(dst);
! emit_byte(0x81);
emit_operand(rsp, dst, 4);
emit_long(imm32);
}
void Assembler::andl(Register dst, int32_t imm32) {
--- 1010,1080 ----
void Assembler::aesdec(XMMRegister dst, Address src) {
assert(VM_Version::supports_aes(), "");
InstructionMark im(this);
simd_prefix(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38);
! emit_int8(0xde);
emit_operand(dst, src);
}
void Assembler::aesdec(XMMRegister dst, XMMRegister src) {
assert(VM_Version::supports_aes(), "");
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38);
! emit_int8(0xde);
! emit_int8(0xC0 | encode);
}
void Assembler::aesdeclast(XMMRegister dst, Address src) {
assert(VM_Version::supports_aes(), "");
InstructionMark im(this);
simd_prefix(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38);
! emit_int8(0xdf);
emit_operand(dst, src);
}
void Assembler::aesdeclast(XMMRegister dst, XMMRegister src) {
assert(VM_Version::supports_aes(), "");
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38);
! emit_int8(0xdf);
! emit_int8(0xC0 | encode);
}
void Assembler::aesenc(XMMRegister dst, Address src) {
assert(VM_Version::supports_aes(), "");
InstructionMark im(this);
simd_prefix(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38);
! emit_int8(0xdc);
emit_operand(dst, src);
}
void Assembler::aesenc(XMMRegister dst, XMMRegister src) {
assert(VM_Version::supports_aes(), "");
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38);
! emit_int8(0xdc);
! emit_int8(0xC0 | encode);
}
void Assembler::aesenclast(XMMRegister dst, Address src) {
assert(VM_Version::supports_aes(), "");
InstructionMark im(this);
simd_prefix(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38);
! emit_int8(0xdd);
emit_operand(dst, src);
}
void Assembler::aesenclast(XMMRegister dst, XMMRegister src) {
assert(VM_Version::supports_aes(), "");
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38);
! emit_int8(0xdd);
! emit_int8(0xC0 | encode);
}
void Assembler::andl(Address dst, int32_t imm32) {
InstructionMark im(this);
prefix(dst);
! emit_int8(0x81);
emit_operand(rsp, dst, 4);
emit_long(imm32);
}
void Assembler::andl(Register dst, int32_t imm32) {
*** 1083,1120 ****
}
void Assembler::andl(Register dst, Address src) {
InstructionMark im(this);
prefix(src, dst);
! emit_byte(0x23);
emit_operand(dst, src);
}
void Assembler::andl(Register dst, Register src) {
(void) prefix_and_encode(dst->encoding(), src->encoding());
emit_arith(0x23, 0xC0, dst, src);
}
void Assembler::bsfl(Register dst, Register src) {
int encode = prefix_and_encode(dst->encoding(), src->encoding());
! emit_byte(0x0F);
! emit_byte(0xBC);
! emit_byte(0xC0 | encode);
}
void Assembler::bsrl(Register dst, Register src) {
assert(!VM_Version::supports_lzcnt(), "encoding is treated as LZCNT");
int encode = prefix_and_encode(dst->encoding(), src->encoding());
! emit_byte(0x0F);
! emit_byte(0xBD);
! emit_byte(0xC0 | encode);
}
void Assembler::bswapl(Register reg) { // bswap
int encode = prefix_and_encode(reg->encoding());
! emit_byte(0x0F);
! emit_byte(0xC8 | encode);
}
void Assembler::call(Label& L, relocInfo::relocType rtype) {
// suspect disp32 is always good
int operand = LP64_ONLY(disp32_operand) NOT_LP64(imm_operand);
--- 1083,1120 ----
}
void Assembler::andl(Register dst, Address src) {
InstructionMark im(this);
prefix(src, dst);
! emit_int8(0x23);
emit_operand(dst, src);
}
void Assembler::andl(Register dst, Register src) {
(void) prefix_and_encode(dst->encoding(), src->encoding());
emit_arith(0x23, 0xC0, dst, src);
}
void Assembler::bsfl(Register dst, Register src) {
int encode = prefix_and_encode(dst->encoding(), src->encoding());
! emit_int8(0x0F);
! emit_int8(0xBC);
! emit_int8(0xC0 | encode);
}
void Assembler::bsrl(Register dst, Register src) {
assert(!VM_Version::supports_lzcnt(), "encoding is treated as LZCNT");
int encode = prefix_and_encode(dst->encoding(), src->encoding());
! emit_int8(0x0F);
! emit_int8(0xBD);
! emit_int8(0xC0 | encode);
}
void Assembler::bswapl(Register reg) { // bswap
int encode = prefix_and_encode(reg->encoding());
! emit_int8(0x0F);
! emit_int8(0xC8 | encode);
}
void Assembler::call(Label& L, relocInfo::relocType rtype) {
// suspect disp32 is always good
int operand = LP64_ONLY(disp32_operand) NOT_LP64(imm_operand);
*** 1123,1208 ****
const int long_size = 5;
int offs = (int)( target(L) - pc() );
assert(offs <= 0, "assembler error");
InstructionMark im(this);
// 1110 1000 #32-bit disp
! emit_byte(0xE8);
emit_data(offs - long_size, rtype, operand);
} else {
InstructionMark im(this);
// 1110 1000 #32-bit disp
L.add_patch_at(code(), locator());
! emit_byte(0xE8);
emit_data(int(0), rtype, operand);
}
}
void Assembler::call(Register dst) {
int encode = prefix_and_encode(dst->encoding());
! emit_byte(0xFF);
! emit_byte(0xD0 | encode);
}
void Assembler::call(Address adr) {
InstructionMark im(this);
prefix(adr);
! emit_byte(0xFF);
emit_operand(rdx, adr);
}
void Assembler::call_literal(address entry, RelocationHolder const& rspec) {
assert(entry != NULL, "call most probably wrong");
InstructionMark im(this);
! emit_byte(0xE8);
intptr_t disp = entry - (pc() + sizeof(int32_t));
assert(is_simm32(disp), "must be 32bit offset (call2)");
// Technically, should use call32_operand, but this format is
// implied by the fact that we're emitting a call instruction.
int operand = LP64_ONLY(disp32_operand) NOT_LP64(call32_operand);
emit_data((int) disp, rspec, operand);
}
void Assembler::cdql() {
! emit_byte(0x99);
}
void Assembler::cld() {
! emit_byte(0xfc);
}
void Assembler::cmovl(Condition cc, Register dst, Register src) {
NOT_LP64(guarantee(VM_Version::supports_cmov(), "illegal instruction"));
int encode = prefix_and_encode(dst->encoding(), src->encoding());
! emit_byte(0x0F);
! emit_byte(0x40 | cc);
! emit_byte(0xC0 | encode);
}
void Assembler::cmovl(Condition cc, Register dst, Address src) {
NOT_LP64(guarantee(VM_Version::supports_cmov(), "illegal instruction"));
prefix(src, dst);
! emit_byte(0x0F);
! emit_byte(0x40 | cc);
emit_operand(dst, src);
}
void Assembler::cmpb(Address dst, int imm8) {
InstructionMark im(this);
prefix(dst);
! emit_byte(0x80);
emit_operand(rdi, dst, 1);
! emit_byte(imm8);
}
void Assembler::cmpl(Address dst, int32_t imm32) {
InstructionMark im(this);
prefix(dst);
! emit_byte(0x81);
emit_operand(rdi, dst, 4);
emit_long(imm32);
}
void Assembler::cmpl(Register dst, int32_t imm32) {
--- 1123,1208 ----
const int long_size = 5;
int offs = (int)( target(L) - pc() );
assert(offs <= 0, "assembler error");
InstructionMark im(this);
// 1110 1000 #32-bit disp
! emit_int8(0xE8);
emit_data(offs - long_size, rtype, operand);
} else {
InstructionMark im(this);
// 1110 1000 #32-bit disp
L.add_patch_at(code(), locator());
! emit_int8(0xE8);
emit_data(int(0), rtype, operand);
}
}
void Assembler::call(Register dst) {
int encode = prefix_and_encode(dst->encoding());
! emit_int8(0xFF);
! emit_int8(0xD0 | encode);
}
void Assembler::call(Address adr) {
InstructionMark im(this);
prefix(adr);
! emit_int8(0xFF);
emit_operand(rdx, adr);
}
void Assembler::call_literal(address entry, RelocationHolder const& rspec) {
assert(entry != NULL, "call most probably wrong");
InstructionMark im(this);
! emit_int8(0xE8);
intptr_t disp = entry - (pc() + sizeof(int32_t));
assert(is_simm32(disp), "must be 32bit offset (call2)");
// Technically, should use call32_operand, but this format is
// implied by the fact that we're emitting a call instruction.
int operand = LP64_ONLY(disp32_operand) NOT_LP64(call32_operand);
emit_data((int) disp, rspec, operand);
}
void Assembler::cdql() {
! emit_int8(0x99);
}
void Assembler::cld() {
! emit_int8(0xfc);
}
void Assembler::cmovl(Condition cc, Register dst, Register src) {
NOT_LP64(guarantee(VM_Version::supports_cmov(), "illegal instruction"));
int encode = prefix_and_encode(dst->encoding(), src->encoding());
! emit_int8(0x0F);
! emit_int8(0x40 | cc);
! emit_int8(0xC0 | encode);
}
void Assembler::cmovl(Condition cc, Register dst, Address src) {
NOT_LP64(guarantee(VM_Version::supports_cmov(), "illegal instruction"));
prefix(src, dst);
! emit_int8(0x0F);
! emit_int8(0x40 | cc);
emit_operand(dst, src);
}
void Assembler::cmpb(Address dst, int imm8) {
InstructionMark im(this);
prefix(dst);
! emit_int8(0x80);
emit_operand(rdi, dst, 1);
! emit_int8(imm8);
}
void Assembler::cmpl(Address dst, int32_t imm32) {
InstructionMark im(this);
prefix(dst);
! emit_int8(0x81);
emit_operand(rdi, dst, 4);
emit_long(imm32);
}
void Assembler::cmpl(Register dst, int32_t imm32) {
*** 1217,1247 ****
void Assembler::cmpl(Register dst, Address src) {
InstructionMark im(this);
prefix(src, dst);
! emit_byte(0x3B);
emit_operand(dst, src);
}
void Assembler::cmpw(Address dst, int imm16) {
InstructionMark im(this);
assert(!dst.base_needs_rex() && !dst.index_needs_rex(), "no extended registers");
! emit_byte(0x66);
! emit_byte(0x81);
emit_operand(rdi, dst, 2);
emit_word(imm16);
}
// 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.
void Assembler::cmpxchgl(Register reg, Address adr) { // cmpxchg
InstructionMark im(this);
prefix(adr, reg);
! emit_byte(0x0F);
! emit_byte(0xB1);
emit_operand(reg, adr);
}
void Assembler::comisd(XMMRegister dst, Address src) {
// NOTE: dbx seems to decode this as comiss even though the
--- 1217,1247 ----
void Assembler::cmpl(Register dst, Address src) {
InstructionMark im(this);
prefix(src, dst);
! emit_int8(0x3B);
emit_operand(dst, src);
}
void Assembler::cmpw(Address dst, int imm16) {
InstructionMark im(this);
assert(!dst.base_needs_rex() && !dst.index_needs_rex(), "no extended registers");
! emit_int8(0x66);
! emit_int8(0x81);
emit_operand(rdi, dst, 2);
emit_word(imm16);
}
// 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.
void Assembler::cmpxchgl(Register reg, Address adr) { // cmpxchg
InstructionMark im(this);
prefix(adr, reg);
! emit_int8(0x0F);
! emit_int8(0xB1);
emit_operand(reg, adr);
}
void Assembler::comisd(XMMRegister dst, Address src) {
// NOTE: dbx seems to decode this as comiss even though the
*** 1264,1275 ****
NOT_LP64(assert(VM_Version::supports_sse(), ""));
emit_simd_arith_nonds(0x2F, dst, src, VEX_SIMD_NONE);
}
void Assembler::cpuid() {
! emit_byte(0x0F);
! emit_byte(0xA2);
}
void Assembler::cvtdq2pd(XMMRegister dst, XMMRegister src) {
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
emit_simd_arith_nonds(0xE6, dst, src, VEX_SIMD_F3);
--- 1264,1275 ----
NOT_LP64(assert(VM_Version::supports_sse(), ""));
emit_simd_arith_nonds(0x2F, dst, src, VEX_SIMD_NONE);
}
void Assembler::cpuid() {
! emit_int8(0x0F);
! emit_int8(0xA2);
}
void Assembler::cvtdq2pd(XMMRegister dst, XMMRegister src) {
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
emit_simd_arith_nonds(0xE6, dst, src, VEX_SIMD_F3);
*** 1291,1314 ****
}
void Assembler::cvtsi2sdl(XMMRegister dst, Register src) {
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_F2);
! emit_byte(0x2A);
! emit_byte(0xC0 | encode);
}
void Assembler::cvtsi2sdl(XMMRegister dst, Address src) {
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
emit_simd_arith(0x2A, dst, src, VEX_SIMD_F2);
}
void Assembler::cvtsi2ssl(XMMRegister dst, Register src) {
NOT_LP64(assert(VM_Version::supports_sse(), ""));
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_F3);
! emit_byte(0x2A);
! emit_byte(0xC0 | encode);
}
void Assembler::cvtsi2ssl(XMMRegister dst, Address src) {
NOT_LP64(assert(VM_Version::supports_sse(), ""));
emit_simd_arith(0x2A, dst, src, VEX_SIMD_F3);
--- 1291,1314 ----
}
void Assembler::cvtsi2sdl(XMMRegister dst, Register src) {
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_F2);
! emit_int8(0x2A);
! emit_int8(0xC0 | encode);
}
void Assembler::cvtsi2sdl(XMMRegister dst, Address src) {
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
emit_simd_arith(0x2A, dst, src, VEX_SIMD_F2);
}
void Assembler::cvtsi2ssl(XMMRegister dst, Register src) {
NOT_LP64(assert(VM_Version::supports_sse(), ""));
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_F3);
! emit_int8(0x2A);
! emit_int8(0xC0 | encode);
}
void Assembler::cvtsi2ssl(XMMRegister dst, Address src) {
NOT_LP64(assert(VM_Version::supports_sse(), ""));
emit_simd_arith(0x2A, dst, src, VEX_SIMD_F3);
*** 1326,1351 ****
void Assembler::cvttsd2sil(Register dst, XMMRegister src) {
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
int encode = simd_prefix_and_encode(dst, src, VEX_SIMD_F2);
! emit_byte(0x2C);
! emit_byte(0xC0 | encode);
}
void Assembler::cvttss2sil(Register dst, XMMRegister src) {
NOT_LP64(assert(VM_Version::supports_sse(), ""));
int encode = simd_prefix_and_encode(dst, src, VEX_SIMD_F3);
! emit_byte(0x2C);
! emit_byte(0xC0 | encode);
}
void Assembler::decl(Address dst) {
// Don't use it directly. Use MacroAssembler::decrement() instead.
InstructionMark im(this);
prefix(dst);
! emit_byte(0xFF);
emit_operand(rcx, dst);
}
void Assembler::divsd(XMMRegister dst, Address src) {
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
--- 1326,1351 ----
void Assembler::cvttsd2sil(Register dst, XMMRegister src) {
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
int encode = simd_prefix_and_encode(dst, src, VEX_SIMD_F2);
! emit_int8(0x2C);
! emit_int8(0xC0 | encode);
}
void Assembler::cvttss2sil(Register dst, XMMRegister src) {
NOT_LP64(assert(VM_Version::supports_sse(), ""));
int encode = simd_prefix_and_encode(dst, src, VEX_SIMD_F3);
! emit_int8(0x2C);
! emit_int8(0xC0 | encode);
}
void Assembler::decl(Address dst) {
// Don't use it directly. Use MacroAssembler::decrement() instead.
InstructionMark im(this);
prefix(dst);
! emit_int8(0xFF);
emit_operand(rcx, dst);
}
void Assembler::divsd(XMMRegister dst, Address src) {
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
*** 1367,1422 ****
emit_simd_arith(0x5E, dst, src, VEX_SIMD_F3);
}
void Assembler::emms() {
NOT_LP64(assert(VM_Version::supports_mmx(), ""));
! emit_byte(0x0F);
! emit_byte(0x77);
}
void Assembler::hlt() {
! emit_byte(0xF4);
}
void Assembler::idivl(Register src) {
int encode = prefix_and_encode(src->encoding());
! emit_byte(0xF7);
! emit_byte(0xF8 | encode);
}
void Assembler::divl(Register src) { // Unsigned
int encode = prefix_and_encode(src->encoding());
! emit_byte(0xF7);
! emit_byte(0xF0 | encode);
}
void Assembler::imull(Register dst, Register src) {
int encode = prefix_and_encode(dst->encoding(), src->encoding());
! emit_byte(0x0F);
! emit_byte(0xAF);
! emit_byte(0xC0 | encode);
}
void Assembler::imull(Register dst, Register src, int value) {
int encode = prefix_and_encode(dst->encoding(), src->encoding());
if (is8bit(value)) {
! emit_byte(0x6B);
! emit_byte(0xC0 | encode);
! emit_byte(value & 0xFF);
} else {
! emit_byte(0x69);
! emit_byte(0xC0 | encode);
emit_long(value);
}
}
void Assembler::incl(Address dst) {
// Don't use it directly. Use MacroAssembler::increment() instead.
InstructionMark im(this);
prefix(dst);
! emit_byte(0xFF);
emit_operand(rax, dst);
}
void Assembler::jcc(Condition cc, Label& L, bool maybe_short) {
InstructionMark im(this);
--- 1367,1422 ----
emit_simd_arith(0x5E, dst, src, VEX_SIMD_F3);
}
void Assembler::emms() {
NOT_LP64(assert(VM_Version::supports_mmx(), ""));
! emit_int8(0x0F);
! emit_int8(0x77);
}
void Assembler::hlt() {
! emit_int8(0xF4);
}
void Assembler::idivl(Register src) {
int encode = prefix_and_encode(src->encoding());
! emit_int8(0xF7);
! emit_int8(0xF8 | encode);
}
void Assembler::divl(Register src) { // Unsigned
int encode = prefix_and_encode(src->encoding());
! emit_int8(0xF7);
! emit_int8(0xF0 | encode);
}
void Assembler::imull(Register dst, Register src) {
int encode = prefix_and_encode(dst->encoding(), src->encoding());
! emit_int8(0x0F);
! emit_int8(0xAF);
! emit_int8(0xC0 | encode);
}
void Assembler::imull(Register dst, Register src, int value) {
int encode = prefix_and_encode(dst->encoding(), src->encoding());
if (is8bit(value)) {
! emit_int8(0x6B);
! emit_int8(0xC0 | encode);
! emit_int8(value & 0xFF);
} else {
! emit_int8(0x69);
! emit_int8(0xC0 | encode);
emit_long(value);
}
}
void Assembler::incl(Address dst) {
// Don't use it directly. Use MacroAssembler::increment() instead.
InstructionMark im(this);
prefix(dst);
! emit_int8(0xFF);
emit_operand(rax, dst);
}
void Assembler::jcc(Condition cc, Label& L, bool maybe_short) {
InstructionMark im(this);
*** 1428,1455 ****
const int short_size = 2;
const int long_size = 6;
intptr_t offs = (intptr_t)dst - (intptr_t)pc();
if (maybe_short && is8bit(offs - short_size)) {
// 0111 tttn #8-bit disp
! emit_byte(0x70 | cc);
! emit_byte((offs - short_size) & 0xFF);
} else {
// 0000 1111 1000 tttn #32-bit disp
assert(is_simm32(offs - long_size),
"must be 32bit offset (call4)");
! emit_byte(0x0F);
! emit_byte(0x80 | cc);
emit_long(offs - long_size);
}
} else {
// Note: could eliminate cond. jumps to this jump if condition
// is the same however, seems to be rather unlikely case.
// Note: use jccb() if label to be bound is very close to get
// an 8-bit displacement
L.add_patch_at(code(), locator());
! emit_byte(0x0F);
! emit_byte(0x80 | cc);
emit_long(0);
}
}
void Assembler::jccb(Condition cc, Label& L) {
--- 1428,1455 ----
const int short_size = 2;
const int long_size = 6;
intptr_t offs = (intptr_t)dst - (intptr_t)pc();
if (maybe_short && is8bit(offs - short_size)) {
// 0111 tttn #8-bit disp
! emit_int8(0x70 | cc);
! emit_int8((offs - short_size) & 0xFF);
} else {
// 0000 1111 1000 tttn #32-bit disp
assert(is_simm32(offs - long_size),
"must be 32bit offset (call4)");
! emit_int8(0x0F);
! emit_int8(0x80 | cc);
emit_long(offs - long_size);
}
} else {
// Note: could eliminate cond. jumps to this jump if condition
// is the same however, seems to be rather unlikely case.
// Note: use jccb() if label to be bound is very close to get
// an 8-bit displacement
L.add_patch_at(code(), locator());
! emit_int8(0x0F);
! emit_int8(0x80 | cc);
emit_long(0);
}
}
void Assembler::jccb(Condition cc, Label& L) {
*** 1464,1487 ****
}
assert(is8bit(dist), "Dispacement too large for a short jmp");
#endif
intptr_t offs = (intptr_t)entry - (intptr_t)pc();
// 0111 tttn #8-bit disp
! emit_byte(0x70 | cc);
! emit_byte((offs - short_size) & 0xFF);
} else {
InstructionMark im(this);
L.add_patch_at(code(), locator());
! emit_byte(0x70 | cc);
! emit_byte(0);
}
}
void Assembler::jmp(Address adr) {
InstructionMark im(this);
prefix(adr);
! emit_byte(0xFF);
emit_operand(rsp, adr);
}
void Assembler::jmp(Label& L, bool maybe_short) {
if (L.is_bound()) {
--- 1464,1487 ----
}
assert(is8bit(dist), "Dispacement too large for a short jmp");
#endif
intptr_t offs = (intptr_t)entry - (intptr_t)pc();
// 0111 tttn #8-bit disp
! emit_int8(0x70 | cc);
! emit_int8((offs - short_size) & 0xFF);
} else {
InstructionMark im(this);
L.add_patch_at(code(), locator());
! emit_int8(0x70 | cc);
! emit_int8(0);
}
}
void Assembler::jmp(Address adr) {
InstructionMark im(this);
prefix(adr);
! emit_int8(0xFF);
emit_operand(rsp, adr);
}
void Assembler::jmp(Label& L, bool maybe_short) {
if (L.is_bound()) {
*** 1490,1526 ****
InstructionMark im(this);
const int short_size = 2;
const int long_size = 5;
intptr_t offs = entry - pc();
if (maybe_short && is8bit(offs - short_size)) {
! emit_byte(0xEB);
! emit_byte((offs - short_size) & 0xFF);
} else {
! emit_byte(0xE9);
emit_long(offs - long_size);
}
} else {
// By default, forward jumps are always 32-bit displacements, since
// we can't yet know where the label will be bound. If you're sure that
// the forward jump will not run beyond 256 bytes, use jmpb to
// force an 8-bit displacement.
InstructionMark im(this);
L.add_patch_at(code(), locator());
! emit_byte(0xE9);
emit_long(0);
}
}
void Assembler::jmp(Register entry) {
int encode = prefix_and_encode(entry->encoding());
! emit_byte(0xFF);
! emit_byte(0xE0 | encode);
}
void Assembler::jmp_literal(address dest, RelocationHolder const& rspec) {
InstructionMark im(this);
! emit_byte(0xE9);
assert(dest != NULL, "must have a target");
intptr_t disp = dest - (pc() + sizeof(int32_t));
assert(is_simm32(disp), "must be 32bit offset (jmp)");
emit_data(disp, rspec.reloc(), call32_operand);
}
--- 1490,1526 ----
InstructionMark im(this);
const int short_size = 2;
const int long_size = 5;
intptr_t offs = entry - pc();
if (maybe_short && is8bit(offs - short_size)) {
! emit_int8(0xEB);
! emit_int8((offs - short_size) & 0xFF);
} else {
! emit_int8(0xE9);
emit_long(offs - long_size);
}
} else {
// By default, forward jumps are always 32-bit displacements, since
// we can't yet know where the label will be bound. If you're sure that
// the forward jump will not run beyond 256 bytes, use jmpb to
// force an 8-bit displacement.
InstructionMark im(this);
L.add_patch_at(code(), locator());
! emit_int8(0xE9);
emit_long(0);
}
}
void Assembler::jmp(Register entry) {
int encode = prefix_and_encode(entry->encoding());
! emit_int8(0xFF);
! emit_int8(0xE0 | encode);
}
void Assembler::jmp_literal(address dest, RelocationHolder const& rspec) {
InstructionMark im(this);
! emit_int8(0xE9);
assert(dest != NULL, "must have a target");
intptr_t disp = dest - (pc() + sizeof(int32_t));
assert(is_simm32(disp), "must be 32bit offset (jmp)");
emit_data(disp, rspec.reloc(), call32_operand);
}
*** 1537,1600 ****
dist += (dist < 0 ? (-delta) :delta);
}
assert(is8bit(dist), "Dispacement too large for a short jmp");
#endif
intptr_t offs = entry - pc();
! emit_byte(0xEB);
! emit_byte((offs - short_size) & 0xFF);
} else {
InstructionMark im(this);
L.add_patch_at(code(), locator());
! emit_byte(0xEB);
! emit_byte(0);
}
}
void Assembler::ldmxcsr( Address src) {
NOT_LP64(assert(VM_Version::supports_sse(), ""));
InstructionMark im(this);
prefix(src);
! emit_byte(0x0F);
! emit_byte(0xAE);
emit_operand(as_Register(2), src);
}
void Assembler::leal(Register dst, Address src) {
InstructionMark im(this);
#ifdef _LP64
! emit_byte(0x67); // addr32
prefix(src, dst);
#endif // LP64
! emit_byte(0x8D);
emit_operand(dst, src);
}
void Assembler::lfence() {
! emit_byte(0x0F);
! emit_byte(0xAE);
! emit_byte(0xE8);
}
void Assembler::lock() {
! emit_byte(0xF0);
}
void Assembler::lzcntl(Register dst, Register src) {
assert(VM_Version::supports_lzcnt(), "encoding is treated as BSR");
! emit_byte(0xF3);
int encode = prefix_and_encode(dst->encoding(), src->encoding());
! emit_byte(0x0F);
! emit_byte(0xBD);
! emit_byte(0xC0 | encode);
}
// Emit mfence instruction
void Assembler::mfence() {
NOT_LP64(assert(VM_Version::supports_sse2(), "unsupported");)
! emit_byte( 0x0F );
! emit_byte( 0xAE );
! emit_byte( 0xF0 );
}
void Assembler::mov(Register dst, Register src) {
LP64_ONLY(movq(dst, src)) NOT_LP64(movl(dst, src));
}
--- 1537,1600 ----
dist += (dist < 0 ? (-delta) :delta);
}
assert(is8bit(dist), "Dispacement too large for a short jmp");
#endif
intptr_t offs = entry - pc();
! emit_int8(0xEB);
! emit_int8((offs - short_size) & 0xFF);
} else {
InstructionMark im(this);
L.add_patch_at(code(), locator());
! emit_int8(0xEB);
! emit_int8(0);
}
}
void Assembler::ldmxcsr( Address src) {
NOT_LP64(assert(VM_Version::supports_sse(), ""));
InstructionMark im(this);
prefix(src);
! emit_int8(0x0F);
! emit_int8(0xAE);
emit_operand(as_Register(2), src);
}
void Assembler::leal(Register dst, Address src) {
InstructionMark im(this);
#ifdef _LP64
! emit_int8(0x67); // addr32
prefix(src, dst);
#endif // LP64
! emit_int8(0x8D);
emit_operand(dst, src);
}
void Assembler::lfence() {
! emit_int8(0x0F);
! emit_int8(0xAE);
! emit_int8(0xE8);
}
void Assembler::lock() {
! emit_int8(0xF0);
}
void Assembler::lzcntl(Register dst, Register src) {
assert(VM_Version::supports_lzcnt(), "encoding is treated as BSR");
! emit_int8(0xF3);
int encode = prefix_and_encode(dst->encoding(), src->encoding());
! emit_int8(0x0F);
! emit_int8(0xBD);
! emit_int8(0xC0 | encode);
}
// Emit mfence instruction
void Assembler::mfence() {
NOT_LP64(assert(VM_Version::supports_sse2(), "unsupported");)
! emit_int8( 0x0F );
! emit_int8( 0xAE );
! emit_int8( 0xF0 );
}
void Assembler::mov(Register dst, Register src) {
LP64_ONLY(movq(dst, src)) NOT_LP64(movl(dst, src));
}
*** 1610,1677 ****
}
void Assembler::movlhps(XMMRegister dst, XMMRegister src) {
NOT_LP64(assert(VM_Version::supports_sse(), ""));
int encode = simd_prefix_and_encode(dst, src, src, VEX_SIMD_NONE);
! emit_byte(0x16);
! emit_byte(0xC0 | encode);
}
void Assembler::movb(Register dst, Address src) {
NOT_LP64(assert(dst->has_byte_register(), "must have byte register"));
InstructionMark im(this);
prefix(src, dst, true);
! emit_byte(0x8A);
emit_operand(dst, src);
}
void Assembler::movb(Address dst, int imm8) {
InstructionMark im(this);
prefix(dst);
! emit_byte(0xC6);
emit_operand(rax, dst, 1);
! emit_byte(imm8);
}
void Assembler::movb(Address dst, Register src) {
assert(src->has_byte_register(), "must have byte register");
InstructionMark im(this);
prefix(dst, src, true);
! emit_byte(0x88);
emit_operand(src, dst);
}
void Assembler::movdl(XMMRegister dst, Register src) {
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
int encode = simd_prefix_and_encode(dst, src, VEX_SIMD_66);
! emit_byte(0x6E);
! emit_byte(0xC0 | encode);
}
void Assembler::movdl(Register dst, XMMRegister src) {
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
// swap src/dst to get correct prefix
int encode = simd_prefix_and_encode(src, dst, VEX_SIMD_66);
! emit_byte(0x7E);
! emit_byte(0xC0 | encode);
}
void Assembler::movdl(XMMRegister dst, Address src) {
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
InstructionMark im(this);
simd_prefix(dst, src, VEX_SIMD_66);
! emit_byte(0x6E);
emit_operand(dst, src);
}
void Assembler::movdl(Address dst, XMMRegister src) {
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
InstructionMark im(this);
simd_prefix(dst, src, VEX_SIMD_66);
! emit_byte(0x7E);
emit_operand(src, dst);
}
void Assembler::movdqa(XMMRegister dst, XMMRegister src) {
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
--- 1610,1677 ----
}
void Assembler::movlhps(XMMRegister dst, XMMRegister src) {
NOT_LP64(assert(VM_Version::supports_sse(), ""));
int encode = simd_prefix_and_encode(dst, src, src, VEX_SIMD_NONE);
! emit_int8(0x16);
! emit_int8(0xC0 | encode);
}
void Assembler::movb(Register dst, Address src) {
NOT_LP64(assert(dst->has_byte_register(), "must have byte register"));
InstructionMark im(this);
prefix(src, dst, true);
! emit_int8(0x8A);
emit_operand(dst, src);
}
void Assembler::movb(Address dst, int imm8) {
InstructionMark im(this);
prefix(dst);
! emit_int8(0xC6);
emit_operand(rax, dst, 1);
! emit_int8(imm8);
}
void Assembler::movb(Address dst, Register src) {
assert(src->has_byte_register(), "must have byte register");
InstructionMark im(this);
prefix(dst, src, true);
! emit_int8(0x88);
emit_operand(src, dst);
}
void Assembler::movdl(XMMRegister dst, Register src) {
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
int encode = simd_prefix_and_encode(dst, src, VEX_SIMD_66);
! emit_int8(0x6E);
! emit_int8(0xC0 | encode);
}
void Assembler::movdl(Register dst, XMMRegister src) {
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
// swap src/dst to get correct prefix
int encode = simd_prefix_and_encode(src, dst, VEX_SIMD_66);
! emit_int8(0x7E);
! emit_int8(0xC0 | encode);
}
void Assembler::movdl(XMMRegister dst, Address src) {
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
InstructionMark im(this);
simd_prefix(dst, src, VEX_SIMD_66);
! emit_int8(0x6E);
emit_operand(dst, src);
}
void Assembler::movdl(Address dst, XMMRegister src) {
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
InstructionMark im(this);
simd_prefix(dst, src, VEX_SIMD_66);
! emit_int8(0x7E);
emit_operand(src, dst);
}
void Assembler::movdqa(XMMRegister dst, XMMRegister src) {
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
*** 1690,1765 ****
void Assembler::movdqu(Address dst, XMMRegister src) {
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
InstructionMark im(this);
simd_prefix(dst, src, VEX_SIMD_F3);
! emit_byte(0x7F);
emit_operand(src, dst);
}
// Move Unaligned 256bit Vector
void Assembler::vmovdqu(XMMRegister dst, XMMRegister src) {
assert(UseAVX, "");
bool vector256 = true;
int encode = vex_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_F3, vector256);
! emit_byte(0x6F);
! emit_byte(0xC0 | encode);
}
void Assembler::vmovdqu(XMMRegister dst, Address src) {
assert(UseAVX, "");
InstructionMark im(this);
bool vector256 = true;
vex_prefix(dst, xnoreg, src, VEX_SIMD_F3, vector256);
! emit_byte(0x6F);
emit_operand(dst, src);
}
void Assembler::vmovdqu(Address dst, XMMRegister src) {
assert(UseAVX, "");
InstructionMark im(this);
bool vector256 = true;
// swap src<->dst for encoding
assert(src != xnoreg, "sanity");
vex_prefix(src, xnoreg, dst, VEX_SIMD_F3, vector256);
! emit_byte(0x7F);
emit_operand(src, dst);
}
// Uses zero extension on 64bit
void Assembler::movl(Register dst, int32_t imm32) {
int encode = prefix_and_encode(dst->encoding());
! emit_byte(0xB8 | encode);
emit_long(imm32);
}
void Assembler::movl(Register dst, Register src) {
int encode = prefix_and_encode(dst->encoding(), src->encoding());
! emit_byte(0x8B);
! emit_byte(0xC0 | encode);
}
void Assembler::movl(Register dst, Address src) {
InstructionMark im(this);
prefix(src, dst);
! emit_byte(0x8B);
emit_operand(dst, src);
}
void Assembler::movl(Address dst, int32_t imm32) {
InstructionMark im(this);
prefix(dst);
! emit_byte(0xC7);
emit_operand(rax, dst, 4);
emit_long(imm32);
}
void Assembler::movl(Address dst, Register src) {
InstructionMark im(this);
prefix(dst, src);
! emit_byte(0x89);
emit_operand(src, dst);
}
// New cpus require to use movsd and movss to avoid partial register stall
// when loading from memory. But for old Opteron use movlpd instead of movsd.
--- 1690,1765 ----
void Assembler::movdqu(Address dst, XMMRegister src) {
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
InstructionMark im(this);
simd_prefix(dst, src, VEX_SIMD_F3);
! emit_int8(0x7F);
emit_operand(src, dst);
}
// Move Unaligned 256bit Vector
void Assembler::vmovdqu(XMMRegister dst, XMMRegister src) {
assert(UseAVX, "");
bool vector256 = true;
int encode = vex_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_F3, vector256);
! emit_int8(0x6F);
! emit_int8(0xC0 | encode);
}
void Assembler::vmovdqu(XMMRegister dst, Address src) {
assert(UseAVX, "");
InstructionMark im(this);
bool vector256 = true;
vex_prefix(dst, xnoreg, src, VEX_SIMD_F3, vector256);
! emit_int8(0x6F);
emit_operand(dst, src);
}
void Assembler::vmovdqu(Address dst, XMMRegister src) {
assert(UseAVX, "");
InstructionMark im(this);
bool vector256 = true;
// swap src<->dst for encoding
assert(src != xnoreg, "sanity");
vex_prefix(src, xnoreg, dst, VEX_SIMD_F3, vector256);
! emit_int8(0x7F);
emit_operand(src, dst);
}
// Uses zero extension on 64bit
void Assembler::movl(Register dst, int32_t imm32) {
int encode = prefix_and_encode(dst->encoding());
! emit_int8(0xB8 | encode);
emit_long(imm32);
}
void Assembler::movl(Register dst, Register src) {
int encode = prefix_and_encode(dst->encoding(), src->encoding());
! emit_int8(0x8B);
! emit_int8(0xC0 | encode);
}
void Assembler::movl(Register dst, Address src) {
InstructionMark im(this);
prefix(src, dst);
! emit_int8(0x8B);
emit_operand(dst, src);
}
void Assembler::movl(Address dst, int32_t imm32) {
InstructionMark im(this);
prefix(dst);
! emit_int8(0xC7);
emit_operand(rax, dst, 4);
emit_long(imm32);
}
void Assembler::movl(Address dst, Register src) {
InstructionMark im(this);
prefix(dst, src);
! emit_int8(0x89);
emit_operand(src, dst);
}
// New cpus require to use movsd and movss to avoid partial register stall
// when loading from memory. But for old Opteron use movlpd instead of movsd.
*** 1769,1787 ****
emit_simd_arith(0x12, dst, src, VEX_SIMD_66);
}
void Assembler::movq( MMXRegister dst, Address src ) {
assert( VM_Version::supports_mmx(), "" );
! emit_byte(0x0F);
! emit_byte(0x6F);
emit_operand(dst, src);
}
void Assembler::movq( Address dst, MMXRegister src ) {
assert( VM_Version::supports_mmx(), "" );
! emit_byte(0x0F);
! emit_byte(0x7F);
// workaround gcc (3.2.1-7a) bug
// In that version of gcc with only an emit_operand(MMX, Address)
// gcc will tail jump and try and reverse the parameters completely
// obliterating dst in the process. By having a version available
// that doesn't need to swap the args at the tail jump the bug is
--- 1769,1787 ----
emit_simd_arith(0x12, dst, src, VEX_SIMD_66);
}
void Assembler::movq( MMXRegister dst, Address src ) {
assert( VM_Version::supports_mmx(), "" );
! emit_int8(0x0F);
! emit_int8(0x6F);
emit_operand(dst, src);
}
void Assembler::movq( Address dst, MMXRegister src ) {
assert( VM_Version::supports_mmx(), "" );
! emit_int8(0x0F);
! emit_int8(0x7F);
// workaround gcc (3.2.1-7a) bug
// In that version of gcc with only an emit_operand(MMX, Address)
// gcc will tail jump and try and reverse the parameters completely
// obliterating dst in the process. By having a version available
// that doesn't need to swap the args at the tail jump the bug is
*** 1791,1826 ****
void Assembler::movq(XMMRegister dst, Address src) {
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
InstructionMark im(this);
simd_prefix(dst, src, VEX_SIMD_F3);
! emit_byte(0x7E);
emit_operand(dst, src);
}
void Assembler::movq(Address dst, XMMRegister src) {
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
InstructionMark im(this);
simd_prefix(dst, src, VEX_SIMD_66);
! emit_byte(0xD6);
emit_operand(src, dst);
}
void Assembler::movsbl(Register dst, Address src) { // movsxb
InstructionMark im(this);
prefix(src, dst);
! emit_byte(0x0F);
! emit_byte(0xBE);
emit_operand(dst, src);
}
void Assembler::movsbl(Register dst, Register src) { // movsxb
NOT_LP64(assert(src->has_byte_register(), "must have byte register"));
int encode = prefix_and_encode(dst->encoding(), src->encoding(), true);
! emit_byte(0x0F);
! emit_byte(0xBE);
! emit_byte(0xC0 | encode);
}
void Assembler::movsd(XMMRegister dst, XMMRegister src) {
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
emit_simd_arith(0x10, dst, src, VEX_SIMD_F2);
--- 1791,1826 ----
void Assembler::movq(XMMRegister dst, Address src) {
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
InstructionMark im(this);
simd_prefix(dst, src, VEX_SIMD_F3);
! emit_int8(0x7E);
emit_operand(dst, src);
}
void Assembler::movq(Address dst, XMMRegister src) {
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
InstructionMark im(this);
simd_prefix(dst, src, VEX_SIMD_66);
! emit_int8(0xD6);
emit_operand(src, dst);
}
void Assembler::movsbl(Register dst, Address src) { // movsxb
InstructionMark im(this);
prefix(src, dst);
! emit_int8(0x0F);
! emit_int8(0xBE);
emit_operand(dst, src);
}
void Assembler::movsbl(Register dst, Register src) { // movsxb
NOT_LP64(assert(src->has_byte_register(), "must have byte register"));
int encode = prefix_and_encode(dst->encoding(), src->encoding(), true);
! emit_int8(0x0F);
! emit_int8(0xBE);
! emit_int8(0xC0 | encode);
}
void Assembler::movsd(XMMRegister dst, XMMRegister src) {
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
emit_simd_arith(0x10, dst, src, VEX_SIMD_F2);
*** 1833,1843 ****
void Assembler::movsd(Address dst, XMMRegister src) {
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
InstructionMark im(this);
simd_prefix(dst, src, VEX_SIMD_F2);
! emit_byte(0x11);
emit_operand(src, dst);
}
void Assembler::movss(XMMRegister dst, XMMRegister src) {
NOT_LP64(assert(VM_Version::supports_sse(), ""));
--- 1833,1843 ----
void Assembler::movsd(Address dst, XMMRegister src) {
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
InstructionMark im(this);
simd_prefix(dst, src, VEX_SIMD_F2);
! emit_int8(0x11);
emit_operand(src, dst);
}
void Assembler::movss(XMMRegister dst, XMMRegister src) {
NOT_LP64(assert(VM_Version::supports_sse(), ""));
*** 1851,1947 ****
void Assembler::movss(Address dst, XMMRegister src) {
NOT_LP64(assert(VM_Version::supports_sse(), ""));
InstructionMark im(this);
simd_prefix(dst, src, VEX_SIMD_F3);
! emit_byte(0x11);
emit_operand(src, dst);
}
void Assembler::movswl(Register dst, Address src) { // movsxw
InstructionMark im(this);
prefix(src, dst);
! emit_byte(0x0F);
! emit_byte(0xBF);
emit_operand(dst, src);
}
void Assembler::movswl(Register dst, Register src) { // movsxw
int encode = prefix_and_encode(dst->encoding(), src->encoding());
! emit_byte(0x0F);
! emit_byte(0xBF);
! emit_byte(0xC0 | encode);
}
void Assembler::movw(Address dst, int imm16) {
InstructionMark im(this);
! emit_byte(0x66); // switch to 16-bit mode
prefix(dst);
! emit_byte(0xC7);
emit_operand(rax, dst, 2);
emit_word(imm16);
}
void Assembler::movw(Register dst, Address src) {
InstructionMark im(this);
! emit_byte(0x66);
prefix(src, dst);
! emit_byte(0x8B);
emit_operand(dst, src);
}
void Assembler::movw(Address dst, Register src) {
InstructionMark im(this);
! emit_byte(0x66);
prefix(dst, src);
! emit_byte(0x89);
emit_operand(src, dst);
}
void Assembler::movzbl(Register dst, Address src) { // movzxb
InstructionMark im(this);
prefix(src, dst);
! emit_byte(0x0F);
! emit_byte(0xB6);
emit_operand(dst, src);
}
void Assembler::movzbl(Register dst, Register src) { // movzxb
NOT_LP64(assert(src->has_byte_register(), "must have byte register"));
int encode = prefix_and_encode(dst->encoding(), src->encoding(), true);
! emit_byte(0x0F);
! emit_byte(0xB6);
! emit_byte(0xC0 | encode);
}
void Assembler::movzwl(Register dst, Address src) { // movzxw
InstructionMark im(this);
prefix(src, dst);
! emit_byte(0x0F);
! emit_byte(0xB7);
emit_operand(dst, src);
}
void Assembler::movzwl(Register dst, Register src) { // movzxw
int encode = prefix_and_encode(dst->encoding(), src->encoding());
! emit_byte(0x0F);
! emit_byte(0xB7);
! emit_byte(0xC0 | encode);
}
void Assembler::mull(Address src) {
InstructionMark im(this);
prefix(src);
! emit_byte(0xF7);
emit_operand(rsp, src);
}
void Assembler::mull(Register src) {
int encode = prefix_and_encode(src->encoding());
! emit_byte(0xF7);
! emit_byte(0xE0 | encode);
}
void Assembler::mulsd(XMMRegister dst, Address src) {
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
emit_simd_arith(0x59, dst, src, VEX_SIMD_F2);
--- 1851,1947 ----
void Assembler::movss(Address dst, XMMRegister src) {
NOT_LP64(assert(VM_Version::supports_sse(), ""));
InstructionMark im(this);
simd_prefix(dst, src, VEX_SIMD_F3);
! emit_int8(0x11);
emit_operand(src, dst);
}
void Assembler::movswl(Register dst, Address src) { // movsxw
InstructionMark im(this);
prefix(src, dst);
! emit_int8(0x0F);
! emit_int8(0xBF);
emit_operand(dst, src);
}
void Assembler::movswl(Register dst, Register src) { // movsxw
int encode = prefix_and_encode(dst->encoding(), src->encoding());
! emit_int8(0x0F);
! emit_int8(0xBF);
! emit_int8(0xC0 | encode);
}
void Assembler::movw(Address dst, int imm16) {
InstructionMark im(this);
! emit_int8(0x66); // switch to 16-bit mode
prefix(dst);
! emit_int8(0xC7);
emit_operand(rax, dst, 2);
emit_word(imm16);
}
void Assembler::movw(Register dst, Address src) {
InstructionMark im(this);
! emit_int8(0x66);
prefix(src, dst);
! emit_int8(0x8B);
emit_operand(dst, src);
}
void Assembler::movw(Address dst, Register src) {
InstructionMark im(this);
! emit_int8(0x66);
prefix(dst, src);
! emit_int8(0x89);
emit_operand(src, dst);
}
void Assembler::movzbl(Register dst, Address src) { // movzxb
InstructionMark im(this);
prefix(src, dst);
! emit_int8(0x0F);
! emit_int8(0xB6);
emit_operand(dst, src);
}
void Assembler::movzbl(Register dst, Register src) { // movzxb
NOT_LP64(assert(src->has_byte_register(), "must have byte register"));
int encode = prefix_and_encode(dst->encoding(), src->encoding(), true);
! emit_int8(0x0F);
! emit_int8(0xB6);
! emit_int8(0xC0 | encode);
}
void Assembler::movzwl(Register dst, Address src) { // movzxw
InstructionMark im(this);
prefix(src, dst);
! emit_int8(0x0F);
! emit_int8(0xB7);
emit_operand(dst, src);
}
void Assembler::movzwl(Register dst, Register src) { // movzxw
int encode = prefix_and_encode(dst->encoding(), src->encoding());
! emit_int8(0x0F);
! emit_int8(0xB7);
! emit_int8(0xC0 | encode);
}
void Assembler::mull(Address src) {
InstructionMark im(this);
prefix(src);
! emit_int8(0xF7);
emit_operand(rsp, src);
}
void Assembler::mull(Register src) {
int encode = prefix_and_encode(src->encoding());
! emit_int8(0xF7);
! emit_int8(0xE0 | encode);
}
void Assembler::mulsd(XMMRegister dst, Address src) {
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
emit_simd_arith(0x59, dst, src, VEX_SIMD_F2);
*** 1962,1984 ****
emit_simd_arith(0x59, dst, src, VEX_SIMD_F3);
}
void Assembler::negl(Register dst) {
int encode = prefix_and_encode(dst->encoding());
! emit_byte(0xF7);
! emit_byte(0xD8 | encode);
}
void Assembler::nop(int i) {
#ifdef ASSERT
assert(i > 0, " ");
// The fancy nops aren't currently recognized by debuggers making it a
// pain to disassemble code while debugging. If asserts are on clearly
// speed is not an issue so simply use the single byte traditional nop
// to do alignment.
! for (; i > 0 ; i--) emit_byte(0x90);
return;
#endif // ASSERT
if (UseAddressNop && VM_Version::is_intel()) {
--- 1962,1984 ----
emit_simd_arith(0x59, dst, src, VEX_SIMD_F3);
}
void Assembler::negl(Register dst) {
int encode = prefix_and_encode(dst->encoding());
! emit_int8(0xF7);
! emit_int8(0xD8 | encode);
}
void Assembler::nop(int i) {
#ifdef ASSERT
assert(i > 0, " ");
// The fancy nops aren't currently recognized by debuggers making it a
// pain to disassemble code while debugging. If asserts are on clearly
// speed is not an issue so simply use the single byte traditional nop
// to do alignment.
! for (; i > 0 ; i--) emit_int8(0x90);
return;
#endif // ASSERT
if (UseAddressNop && VM_Version::is_intel()) {
*** 2004,2061 ****
// 15: 0x66 0x66 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 0x66 0x66 0x66 0x90
while(i >= 15) {
// For Intel don't generate consecutive addess nops (mix with regular nops)
i -= 15;
! emit_byte(0x66); // size prefix
! emit_byte(0x66); // size prefix
! emit_byte(0x66); // size prefix
addr_nop_8();
! emit_byte(0x66); // size prefix
! emit_byte(0x66); // size prefix
! emit_byte(0x66); // size prefix
! emit_byte(0x90); // nop
}
switch (i) {
case 14:
! emit_byte(0x66); // size prefix
case 13:
! emit_byte(0x66); // size prefix
case 12:
addr_nop_8();
! emit_byte(0x66); // size prefix
! emit_byte(0x66); // size prefix
! emit_byte(0x66); // size prefix
! emit_byte(0x90); // nop
break;
case 11:
! emit_byte(0x66); // size prefix
case 10:
! emit_byte(0x66); // size prefix
case 9:
! emit_byte(0x66); // size prefix
case 8:
addr_nop_8();
break;
case 7:
addr_nop_7();
break;
case 6:
! emit_byte(0x66); // size prefix
case 5:
addr_nop_5();
break;
case 4:
addr_nop_4();
break;
case 3:
// Don't use "0x0F 0x1F 0x00" - need patching safe padding
! emit_byte(0x66); // size prefix
case 2:
! emit_byte(0x66); // size prefix
case 1:
! emit_byte(0x90); // nop
break;
default:
assert(i == 0, " ");
}
return;
--- 2004,2061 ----
// 15: 0x66 0x66 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 0x66 0x66 0x66 0x90
while(i >= 15) {
// For Intel don't generate consecutive addess nops (mix with regular nops)
i -= 15;
! emit_int8(0x66); // size prefix
! emit_int8(0x66); // size prefix
! emit_int8(0x66); // size prefix
addr_nop_8();
! emit_int8(0x66); // size prefix
! emit_int8(0x66); // size prefix
! emit_int8(0x66); // size prefix
! emit_int8(0x90); // nop
}
switch (i) {
case 14:
! emit_int8(0x66); // size prefix
case 13:
! emit_int8(0x66); // size prefix
case 12:
addr_nop_8();
! emit_int8(0x66); // size prefix
! emit_int8(0x66); // size prefix
! emit_int8(0x66); // size prefix
! emit_int8(0x90); // nop
break;
case 11:
! emit_int8(0x66); // size prefix
case 10:
! emit_int8(0x66); // size prefix
case 9:
! emit_int8(0x66); // size prefix
case 8:
addr_nop_8();
break;
case 7:
addr_nop_7();
break;
case 6:
! emit_int8(0x66); // size prefix
case 5:
addr_nop_5();
break;
case 4:
addr_nop_4();
break;
case 3:
// Don't use "0x0F 0x1F 0x00" - need patching safe padding
! emit_int8(0x66); // size prefix
case 2:
! emit_int8(0x66); // size prefix
case 1:
! emit_int8(0x90); // nop
break;
default:
assert(i == 0, " ");
}
return;
*** 2084,2111 ****
// 16: 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00
// Size prefixes (0x66) are added for larger sizes
while(i >= 22) {
i -= 11;
! emit_byte(0x66); // size prefix
! emit_byte(0x66); // size prefix
! emit_byte(0x66); // size prefix
addr_nop_8();
}
// Generate first nop for size between 21-12
switch (i) {
case 21:
i -= 1;
! emit_byte(0x66); // size prefix
case 20:
case 19:
i -= 1;
! emit_byte(0x66); // size prefix
case 18:
case 17:
i -= 1;
! emit_byte(0x66); // size prefix
case 16:
case 15:
i -= 8;
addr_nop_8();
break;
--- 2084,2111 ----
// 16: 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00
// Size prefixes (0x66) are added for larger sizes
while(i >= 22) {
i -= 11;
! emit_int8(0x66); // size prefix
! emit_int8(0x66); // size prefix
! emit_int8(0x66); // size prefix
addr_nop_8();
}
// Generate first nop for size between 21-12
switch (i) {
case 21:
i -= 1;
! emit_int8(0x66); // size prefix
case 20:
case 19:
i -= 1;
! emit_int8(0x66); // size prefix
case 18:
case 17:
i -= 1;
! emit_int8(0x66); // size prefix
case 16:
case 15:
i -= 8;
addr_nop_8();
break;
*** 2114,2159 ****
i -= 7;
addr_nop_7();
break;
case 12:
i -= 6;
! emit_byte(0x66); // size prefix
addr_nop_5();
break;
default:
assert(i < 12, " ");
}
// Generate second nop for size between 11-1
switch (i) {
case 11:
! emit_byte(0x66); // size prefix
case 10:
! emit_byte(0x66); // size prefix
case 9:
! emit_byte(0x66); // size prefix
case 8:
addr_nop_8();
break;
case 7:
addr_nop_7();
break;
case 6:
! emit_byte(0x66); // size prefix
case 5:
addr_nop_5();
break;
case 4:
addr_nop_4();
break;
case 3:
// Don't use "0x0F 0x1F 0x00" - need patching safe padding
! emit_byte(0x66); // size prefix
case 2:
! emit_byte(0x66); // size prefix
case 1:
! emit_byte(0x90); // nop
break;
default:
assert(i == 0, " ");
}
return;
--- 2114,2159 ----
i -= 7;
addr_nop_7();
break;
case 12:
i -= 6;
! emit_int8(0x66); // size prefix
addr_nop_5();
break;
default:
assert(i < 12, " ");
}
// Generate second nop for size between 11-1
switch (i) {
case 11:
! emit_int8(0x66); // size prefix
case 10:
! emit_int8(0x66); // size prefix
case 9:
! emit_int8(0x66); // size prefix
case 8:
addr_nop_8();
break;
case 7:
addr_nop_7();
break;
case 6:
! emit_int8(0x66); // size prefix
case 5:
addr_nop_5();
break;
case 4:
addr_nop_4();
break;
case 3:
// Don't use "0x0F 0x1F 0x00" - need patching safe padding
! emit_int8(0x66); // size prefix
case 2:
! emit_int8(0x66); // size prefix
case 1:
! emit_int8(0x90); // nop
break;
default:
assert(i == 0, " ");
}
return;
*** 2172,2227 ****
// 9: 0x66 0x66 0x90 0x66 0x66 0x90 0x66 0x66 0x90
// 10: 0x66 0x66 0x66 0x90 0x66 0x66 0x90 0x66 0x66 0x90
//
while(i > 12) {
i -= 4;
! emit_byte(0x66); // size prefix
! emit_byte(0x66);
! emit_byte(0x66);
! emit_byte(0x90); // nop
}
// 1 - 12 nops
if(i > 8) {
if(i > 9) {
i -= 1;
! emit_byte(0x66);
}
i -= 3;
! emit_byte(0x66);
! emit_byte(0x66);
! emit_byte(0x90);
}
// 1 - 8 nops
if(i > 4) {
if(i > 6) {
i -= 1;
! emit_byte(0x66);
}
i -= 3;
! emit_byte(0x66);
! emit_byte(0x66);
! emit_byte(0x90);
}
switch (i) {
case 4:
! emit_byte(0x66);
case 3:
! emit_byte(0x66);
case 2:
! emit_byte(0x66);
case 1:
! emit_byte(0x90);
break;
default:
assert(i == 0, " ");
}
}
void Assembler::notl(Register dst) {
int encode = prefix_and_encode(dst->encoding());
! emit_byte(0xF7);
! emit_byte(0xD0 | encode );
}
void Assembler::orl(Address dst, int32_t imm32) {
InstructionMark im(this);
prefix(dst);
--- 2172,2227 ----
// 9: 0x66 0x66 0x90 0x66 0x66 0x90 0x66 0x66 0x90
// 10: 0x66 0x66 0x66 0x90 0x66 0x66 0x90 0x66 0x66 0x90
//
while(i > 12) {
i -= 4;
! emit_int8(0x66); // size prefix
! emit_int8(0x66);
! emit_int8(0x66);
! emit_int8(0x90); // nop
}
// 1 - 12 nops
if(i > 8) {
if(i > 9) {
i -= 1;
! emit_int8(0x66);
}
i -= 3;
! emit_int8(0x66);
! emit_int8(0x66);
! emit_int8(0x90);
}
// 1 - 8 nops
if(i > 4) {
if(i > 6) {
i -= 1;
! emit_int8(0x66);
}
i -= 3;
! emit_int8(0x66);
! emit_int8(0x66);
! emit_int8(0x90);
}
switch (i) {
case 4:
! emit_int8(0x66);
case 3:
! emit_int8(0x66);
case 2:
! emit_int8(0x66);
case 1:
! emit_int8(0x90);
break;
default:
assert(i == 0, " ");
}
}
void Assembler::notl(Register dst) {
int encode = prefix_and_encode(dst->encoding());
! emit_int8(0xF7);
! emit_int8(0xD0 | encode );
}
void Assembler::orl(Address dst, int32_t imm32) {
InstructionMark im(this);
prefix(dst);
*** 2234,2244 ****
}
void Assembler::orl(Register dst, Address src) {
InstructionMark im(this);
prefix(src, dst);
! emit_byte(0x0B);
emit_operand(dst, src);
}
void Assembler::orl(Register dst, Register src) {
(void) prefix_and_encode(dst->encoding(), src->encoding());
--- 2234,2244 ----
}
void Assembler::orl(Register dst, Address src) {
InstructionMark im(this);
prefix(src, dst);
! emit_int8(0x0B);
emit_operand(dst, src);
}
void Assembler::orl(Register dst, Register src) {
(void) prefix_and_encode(dst->encoding(), src->encoding());
*** 2258,2467 ****
void Assembler::pcmpestri(XMMRegister dst, Address src, int imm8) {
assert(VM_Version::supports_sse4_2(), "");
InstructionMark im(this);
simd_prefix(dst, src, VEX_SIMD_66, VEX_OPCODE_0F_3A);
! emit_byte(0x61);
emit_operand(dst, src);
! emit_byte(imm8);
}
void Assembler::pcmpestri(XMMRegister dst, XMMRegister src, int imm8) {
assert(VM_Version::supports_sse4_2(), "");
int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F_3A);
! emit_byte(0x61);
! emit_byte(0xC0 | encode);
! emit_byte(imm8);
}
void Assembler::pmovzxbw(XMMRegister dst, Address src) {
assert(VM_Version::supports_sse4_1(), "");
InstructionMark im(this);
simd_prefix(dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38);
! emit_byte(0x30);
emit_operand(dst, src);
}
void Assembler::pmovzxbw(XMMRegister dst, XMMRegister src) {
assert(VM_Version::supports_sse4_1(), "");
int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F_38);
! emit_byte(0x30);
! emit_byte(0xC0 | encode);
}
// generic
void Assembler::pop(Register dst) {
int encode = prefix_and_encode(dst->encoding());
! emit_byte(0x58 | encode);
}
void Assembler::popcntl(Register dst, Address src) {
assert(VM_Version::supports_popcnt(), "must support");
InstructionMark im(this);
! emit_byte(0xF3);
prefix(src, dst);
! emit_byte(0x0F);
! emit_byte(0xB8);
emit_operand(dst, src);
}
void Assembler::popcntl(Register dst, Register src) {
assert(VM_Version::supports_popcnt(), "must support");
! emit_byte(0xF3);
int encode = prefix_and_encode(dst->encoding(), src->encoding());
! emit_byte(0x0F);
! emit_byte(0xB8);
! emit_byte(0xC0 | encode);
}
void Assembler::popf() {
! emit_byte(0x9D);
}
#ifndef _LP64 // no 32bit push/pop on amd64
void Assembler::popl(Address dst) {
// NOTE: this will adjust stack by 8byte on 64bits
InstructionMark im(this);
prefix(dst);
! emit_byte(0x8F);
emit_operand(rax, dst);
}
#endif
void Assembler::prefetch_prefix(Address src) {
prefix(src);
! emit_byte(0x0F);
}
void Assembler::prefetchnta(Address src) {
NOT_LP64(assert(VM_Version::supports_sse(), "must support"));
InstructionMark im(this);
prefetch_prefix(src);
! emit_byte(0x18);
emit_operand(rax, src); // 0, src
}
void Assembler::prefetchr(Address src) {
assert(VM_Version::supports_3dnow_prefetch(), "must support");
InstructionMark im(this);
prefetch_prefix(src);
! emit_byte(0x0D);
emit_operand(rax, src); // 0, src
}
void Assembler::prefetcht0(Address src) {
NOT_LP64(assert(VM_Version::supports_sse(), "must support"));
InstructionMark im(this);
prefetch_prefix(src);
! emit_byte(0x18);
emit_operand(rcx, src); // 1, src
}
void Assembler::prefetcht1(Address src) {
NOT_LP64(assert(VM_Version::supports_sse(), "must support"));
InstructionMark im(this);
prefetch_prefix(src);
! emit_byte(0x18);
emit_operand(rdx, src); // 2, src
}
void Assembler::prefetcht2(Address src) {
NOT_LP64(assert(VM_Version::supports_sse(), "must support"));
InstructionMark im(this);
prefetch_prefix(src);
! emit_byte(0x18);
emit_operand(rbx, src); // 3, src
}
void Assembler::prefetchw(Address src) {
assert(VM_Version::supports_3dnow_prefetch(), "must support");
InstructionMark im(this);
prefetch_prefix(src);
! emit_byte(0x0D);
emit_operand(rcx, src); // 1, src
}
void Assembler::prefix(Prefix p) {
! a_byte(p);
}
void Assembler::pshufb(XMMRegister dst, XMMRegister src) {
assert(VM_Version::supports_ssse3(), "");
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38);
! emit_byte(0x00);
! emit_byte(0xC0 | encode);
}
void Assembler::pshufb(XMMRegister dst, Address src) {
assert(VM_Version::supports_ssse3(), "");
assert((UseAVX > 0), "SSE mode requires address alignment 16 bytes");
InstructionMark im(this);
simd_prefix(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38);
! emit_byte(0x00);
emit_operand(dst, src);
}
void Assembler::pshufd(XMMRegister dst, XMMRegister src, int mode) {
assert(isByte(mode), "invalid value");
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
emit_simd_arith_nonds(0x70, dst, src, VEX_SIMD_66);
! emit_byte(mode & 0xFF);
}
void Assembler::pshufd(XMMRegister dst, Address src, int mode) {
assert(isByte(mode), "invalid value");
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
assert((UseAVX > 0), "SSE mode requires address alignment 16 bytes");
InstructionMark im(this);
simd_prefix(dst, src, VEX_SIMD_66);
! emit_byte(0x70);
emit_operand(dst, src);
! emit_byte(mode & 0xFF);
}
void Assembler::pshuflw(XMMRegister dst, XMMRegister src, int mode) {
assert(isByte(mode), "invalid value");
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
emit_simd_arith_nonds(0x70, dst, src, VEX_SIMD_F2);
! emit_byte(mode & 0xFF);
}
void Assembler::pshuflw(XMMRegister dst, Address src, int mode) {
assert(isByte(mode), "invalid value");
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
assert((UseAVX > 0), "SSE mode requires address alignment 16 bytes");
InstructionMark im(this);
simd_prefix(dst, src, VEX_SIMD_F2);
! emit_byte(0x70);
emit_operand(dst, src);
! emit_byte(mode & 0xFF);
}
void Assembler::psrldq(XMMRegister dst, int shift) {
// Shift 128 bit value in xmm register by number of bytes.
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
int encode = simd_prefix_and_encode(xmm3, dst, dst, VEX_SIMD_66);
! emit_byte(0x73);
! emit_byte(0xC0 | encode);
! emit_byte(shift);
}
void Assembler::ptest(XMMRegister dst, Address src) {
assert(VM_Version::supports_sse4_1(), "");
assert((UseAVX > 0), "SSE mode requires address alignment 16 bytes");
InstructionMark im(this);
simd_prefix(dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38);
! emit_byte(0x17);
emit_operand(dst, src);
}
void Assembler::ptest(XMMRegister dst, XMMRegister src) {
assert(VM_Version::supports_sse4_1(), "");
int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F_38);
! emit_byte(0x17);
! emit_byte(0xC0 | encode);
}
void Assembler::punpcklbw(XMMRegister dst, Address src) {
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
assert((UseAVX > 0), "SSE mode requires address alignment 16 bytes");
--- 2258,2467 ----
void Assembler::pcmpestri(XMMRegister dst, Address src, int imm8) {
assert(VM_Version::supports_sse4_2(), "");
InstructionMark im(this);
simd_prefix(dst, src, VEX_SIMD_66, VEX_OPCODE_0F_3A);
! emit_int8(0x61);
emit_operand(dst, src);
! emit_int8(imm8);
}
void Assembler::pcmpestri(XMMRegister dst, XMMRegister src, int imm8) {
assert(VM_Version::supports_sse4_2(), "");
int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F_3A);
! emit_int8(0x61);
! emit_int8(0xC0 | encode);
! emit_int8(imm8);
}
void Assembler::pmovzxbw(XMMRegister dst, Address src) {
assert(VM_Version::supports_sse4_1(), "");
InstructionMark im(this);
simd_prefix(dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38);
! emit_int8(0x30);
emit_operand(dst, src);
}
void Assembler::pmovzxbw(XMMRegister dst, XMMRegister src) {
assert(VM_Version::supports_sse4_1(), "");
int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F_38);
! emit_int8(0x30);
! emit_int8(0xC0 | encode);
}
// generic
void Assembler::pop(Register dst) {
int encode = prefix_and_encode(dst->encoding());
! emit_int8(0x58 | encode);
}
void Assembler::popcntl(Register dst, Address src) {
assert(VM_Version::supports_popcnt(), "must support");
InstructionMark im(this);
! emit_int8(0xF3);
prefix(src, dst);
! emit_int8(0x0F);
! emit_int8(0xB8);
emit_operand(dst, src);
}
void Assembler::popcntl(Register dst, Register src) {
assert(VM_Version::supports_popcnt(), "must support");
! emit_int8(0xF3);
int encode = prefix_and_encode(dst->encoding(), src->encoding());
! emit_int8(0x0F);
! emit_int8(0xB8);
! emit_int8(0xC0 | encode);
}
void Assembler::popf() {
! emit_int8(0x9D);
}
#ifndef _LP64 // no 32bit push/pop on amd64
void Assembler::popl(Address dst) {
// NOTE: this will adjust stack by 8byte on 64bits
InstructionMark im(this);
prefix(dst);
! emit_int8(0x8F);
emit_operand(rax, dst);
}
#endif
void Assembler::prefetch_prefix(Address src) {
prefix(src);
! emit_int8(0x0F);
}
void Assembler::prefetchnta(Address src) {
NOT_LP64(assert(VM_Version::supports_sse(), "must support"));
InstructionMark im(this);
prefetch_prefix(src);
! emit_int8(0x18);
emit_operand(rax, src); // 0, src
}
void Assembler::prefetchr(Address src) {
assert(VM_Version::supports_3dnow_prefetch(), "must support");
InstructionMark im(this);
prefetch_prefix(src);
! emit_int8(0x0D);
emit_operand(rax, src); // 0, src
}
void Assembler::prefetcht0(Address src) {
NOT_LP64(assert(VM_Version::supports_sse(), "must support"));
InstructionMark im(this);
prefetch_prefix(src);
! emit_int8(0x18);
emit_operand(rcx, src); // 1, src
}
void Assembler::prefetcht1(Address src) {
NOT_LP64(assert(VM_Version::supports_sse(), "must support"));
InstructionMark im(this);
prefetch_prefix(src);
! emit_int8(0x18);
emit_operand(rdx, src); // 2, src
}
void Assembler::prefetcht2(Address src) {
NOT_LP64(assert(VM_Version::supports_sse(), "must support"));
InstructionMark im(this);
prefetch_prefix(src);
! emit_int8(0x18);
emit_operand(rbx, src); // 3, src
}
void Assembler::prefetchw(Address src) {
assert(VM_Version::supports_3dnow_prefetch(), "must support");
InstructionMark im(this);
prefetch_prefix(src);
! emit_int8(0x0D);
emit_operand(rcx, src); // 1, src
}
void Assembler::prefix(Prefix p) {
! emit_int8(p);
}
void Assembler::pshufb(XMMRegister dst, XMMRegister src) {
assert(VM_Version::supports_ssse3(), "");
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38);
! emit_int8(0x00);
! emit_int8(0xC0 | encode);
}
void Assembler::pshufb(XMMRegister dst, Address src) {
assert(VM_Version::supports_ssse3(), "");
assert((UseAVX > 0), "SSE mode requires address alignment 16 bytes");
InstructionMark im(this);
simd_prefix(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38);
! emit_int8(0x00);
emit_operand(dst, src);
}
void Assembler::pshufd(XMMRegister dst, XMMRegister src, int mode) {
assert(isByte(mode), "invalid value");
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
emit_simd_arith_nonds(0x70, dst, src, VEX_SIMD_66);
! emit_int8(mode & 0xFF);
}
void Assembler::pshufd(XMMRegister dst, Address src, int mode) {
assert(isByte(mode), "invalid value");
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
assert((UseAVX > 0), "SSE mode requires address alignment 16 bytes");
InstructionMark im(this);
simd_prefix(dst, src, VEX_SIMD_66);
! emit_int8(0x70);
emit_operand(dst, src);
! emit_int8(mode & 0xFF);
}
void Assembler::pshuflw(XMMRegister dst, XMMRegister src, int mode) {
assert(isByte(mode), "invalid value");
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
emit_simd_arith_nonds(0x70, dst, src, VEX_SIMD_F2);
! emit_int8(mode & 0xFF);
}
void Assembler::pshuflw(XMMRegister dst, Address src, int mode) {
assert(isByte(mode), "invalid value");
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
assert((UseAVX > 0), "SSE mode requires address alignment 16 bytes");
InstructionMark im(this);
simd_prefix(dst, src, VEX_SIMD_F2);
! emit_int8(0x70);
emit_operand(dst, src);
! emit_int8(mode & 0xFF);
}
void Assembler::psrldq(XMMRegister dst, int shift) {
// Shift 128 bit value in xmm register by number of bytes.
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
int encode = simd_prefix_and_encode(xmm3, dst, dst, VEX_SIMD_66);
! emit_int8(0x73);
! emit_int8(0xC0 | encode);
! emit_int8(shift);
}
void Assembler::ptest(XMMRegister dst, Address src) {
assert(VM_Version::supports_sse4_1(), "");
assert((UseAVX > 0), "SSE mode requires address alignment 16 bytes");
InstructionMark im(this);
simd_prefix(dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38);
! emit_int8(0x17);
emit_operand(dst, src);
}
void Assembler::ptest(XMMRegister dst, XMMRegister src) {
assert(VM_Version::supports_sse4_1(), "");
int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F_38);
! emit_int8(0x17);
! emit_int8(0xC0 | encode);
}
void Assembler::punpcklbw(XMMRegister dst, Address src) {
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
assert((UseAVX > 0), "SSE mode requires address alignment 16 bytes");
*** 2490,2607 ****
}
void Assembler::push(int32_t imm32) {
// in 64bits we push 64bits onto the stack but only
// take a 32bit immediate
! emit_byte(0x68);
emit_long(imm32);
}
void Assembler::push(Register src) {
int encode = prefix_and_encode(src->encoding());
! emit_byte(0x50 | encode);
}
void Assembler::pushf() {
! emit_byte(0x9C);
}
#ifndef _LP64 // no 32bit push/pop on amd64
void Assembler::pushl(Address src) {
// Note this will push 64bit on 64bit
InstructionMark im(this);
prefix(src);
! emit_byte(0xFF);
emit_operand(rsi, src);
}
#endif
void Assembler::rcll(Register dst, int imm8) {
assert(isShiftCount(imm8), "illegal shift count");
int encode = prefix_and_encode(dst->encoding());
if (imm8 == 1) {
! emit_byte(0xD1);
! emit_byte(0xD0 | encode);
} else {
! emit_byte(0xC1);
! emit_byte(0xD0 | encode);
! emit_byte(imm8);
}
}
// copies data from [esi] to [edi] using rcx pointer sized words
// generic
void Assembler::rep_mov() {
! emit_byte(0xF3);
// MOVSQ
LP64_ONLY(prefix(REX_W));
! emit_byte(0xA5);
}
// sets rcx pointer sized words with rax, value at [edi]
// generic
void Assembler::rep_set() { // rep_set
! emit_byte(0xF3);
// STOSQ
LP64_ONLY(prefix(REX_W));
! emit_byte(0xAB);
}
// scans rcx pointer sized words at [edi] for occurance of rax,
// generic
void Assembler::repne_scan() { // repne_scan
! emit_byte(0xF2);
// SCASQ
LP64_ONLY(prefix(REX_W));
! emit_byte(0xAF);
}
#ifdef _LP64
// scans rcx 4 byte words at [edi] for occurance of rax,
// generic
void Assembler::repne_scanl() { // repne_scan
! emit_byte(0xF2);
// SCASL
! emit_byte(0xAF);
}
#endif
void Assembler::ret(int imm16) {
if (imm16 == 0) {
! emit_byte(0xC3);
} else {
! emit_byte(0xC2);
emit_word(imm16);
}
}
void Assembler::sahf() {
#ifdef _LP64
// Not supported in 64bit mode
ShouldNotReachHere();
#endif
! emit_byte(0x9E);
}
void Assembler::sarl(Register dst, int imm8) {
int encode = prefix_and_encode(dst->encoding());
assert(isShiftCount(imm8), "illegal shift count");
if (imm8 == 1) {
! emit_byte(0xD1);
! emit_byte(0xF8 | encode);
} else {
! emit_byte(0xC1);
! emit_byte(0xF8 | encode);
! emit_byte(imm8);
}
}
void Assembler::sarl(Register dst) {
int encode = prefix_and_encode(dst->encoding());
! emit_byte(0xD3);
! emit_byte(0xF8 | encode);
}
void Assembler::sbbl(Address dst, int32_t imm32) {
InstructionMark im(this);
prefix(dst);
--- 2490,2607 ----
}
void Assembler::push(int32_t imm32) {
// in 64bits we push 64bits onto the stack but only
// take a 32bit immediate
! emit_int8(0x68);
emit_long(imm32);
}
void Assembler::push(Register src) {
int encode = prefix_and_encode(src->encoding());
! emit_int8(0x50 | encode);
}
void Assembler::pushf() {
! emit_int8(0x9C);
}
#ifndef _LP64 // no 32bit push/pop on amd64
void Assembler::pushl(Address src) {
// Note this will push 64bit on 64bit
InstructionMark im(this);
prefix(src);
! emit_int8(0xFF);
emit_operand(rsi, src);
}
#endif
void Assembler::rcll(Register dst, int imm8) {
assert(isShiftCount(imm8), "illegal shift count");
int encode = prefix_and_encode(dst->encoding());
if (imm8 == 1) {
! emit_int8(0xD1);
! emit_int8(0xD0 | encode);
} else {
! emit_int8(0xC1);
! emit_int8(0xD0 | encode);
! emit_int8(imm8);
}
}
// copies data from [esi] to [edi] using rcx pointer sized words
// generic
void Assembler::rep_mov() {
! emit_int8(0xF3);
// MOVSQ
LP64_ONLY(prefix(REX_W));
! emit_int8(0xA5);
}
// sets rcx pointer sized words with rax, value at [edi]
// generic
void Assembler::rep_set() { // rep_set
! emit_int8(0xF3);
// STOSQ
LP64_ONLY(prefix(REX_W));
! emit_int8(0xAB);
}
// scans rcx pointer sized words at [edi] for occurance of rax,
// generic
void Assembler::repne_scan() { // repne_scan
! emit_int8(0xF2);
// SCASQ
LP64_ONLY(prefix(REX_W));
! emit_int8(0xAF);
}
#ifdef _LP64
// scans rcx 4 byte words at [edi] for occurance of rax,
// generic
void Assembler::repne_scanl() { // repne_scan
! emit_int8(0xF2);
// SCASL
! emit_int8(0xAF);
}
#endif
void Assembler::ret(int imm16) {
if (imm16 == 0) {
! emit_int8(0xC3);
} else {
! emit_int8(0xC2);
emit_word(imm16);
}
}
void Assembler::sahf() {
#ifdef _LP64
// Not supported in 64bit mode
ShouldNotReachHere();
#endif
! emit_int8(0x9E);
}
void Assembler::sarl(Register dst, int imm8) {
int encode = prefix_and_encode(dst->encoding());
assert(isShiftCount(imm8), "illegal shift count");
if (imm8 == 1) {
! emit_int8(0xD1);
! emit_int8(0xF8 | encode);
} else {
! emit_int8(0xC1);
! emit_int8(0xF8 | encode);
! emit_int8(imm8);
}
}
void Assembler::sarl(Register dst) {
int encode = prefix_and_encode(dst->encoding());
! emit_int8(0xD3);
! emit_int8(0xF8 | encode);
}
void Assembler::sbbl(Address dst, int32_t imm32) {
InstructionMark im(this);
prefix(dst);
*** 2615,2625 ****
void Assembler::sbbl(Register dst, Address src) {
InstructionMark im(this);
prefix(src, dst);
! emit_byte(0x1B);
emit_operand(dst, src);
}
void Assembler::sbbl(Register dst, Register src) {
(void) prefix_and_encode(dst->encoding(), src->encoding());
--- 2615,2625 ----
void Assembler::sbbl(Register dst, Address src) {
InstructionMark im(this);
prefix(src, dst);
! emit_int8(0x1B);
emit_operand(dst, src);
}
void Assembler::sbbl(Register dst, Register src) {
(void) prefix_and_encode(dst->encoding(), src->encoding());
*** 2627,2677 ****
}
void Assembler::setb(Condition cc, Register dst) {
assert(0 <= cc && cc < 16, "illegal cc");
int encode = prefix_and_encode(dst->encoding(), true);
! emit_byte(0x0F);
! emit_byte(0x90 | cc);
! emit_byte(0xC0 | encode);
}
void Assembler::shll(Register dst, int imm8) {
assert(isShiftCount(imm8), "illegal shift count");
int encode = prefix_and_encode(dst->encoding());
if (imm8 == 1 ) {
! emit_byte(0xD1);
! emit_byte(0xE0 | encode);
} else {
! emit_byte(0xC1);
! emit_byte(0xE0 | encode);
! emit_byte(imm8);
}
}
void Assembler::shll(Register dst) {
int encode = prefix_and_encode(dst->encoding());
! emit_byte(0xD3);
! emit_byte(0xE0 | encode);
}
void Assembler::shrl(Register dst, int imm8) {
assert(isShiftCount(imm8), "illegal shift count");
int encode = prefix_and_encode(dst->encoding());
! emit_byte(0xC1);
! emit_byte(0xE8 | encode);
! emit_byte(imm8);
}
void Assembler::shrl(Register dst) {
int encode = prefix_and_encode(dst->encoding());
! emit_byte(0xD3);
! emit_byte(0xE8 | encode);
}
// copies a single word from [esi] to [edi]
void Assembler::smovl() {
! emit_byte(0xA5);
}
void Assembler::sqrtsd(XMMRegister dst, XMMRegister src) {
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
emit_simd_arith(0x51, dst, src, VEX_SIMD_F2);
--- 2627,2677 ----
}
void Assembler::setb(Condition cc, Register dst) {
assert(0 <= cc && cc < 16, "illegal cc");
int encode = prefix_and_encode(dst->encoding(), true);
! emit_int8(0x0F);
! emit_int8(0x90 | cc);
! emit_int8(0xC0 | encode);
}
void Assembler::shll(Register dst, int imm8) {
assert(isShiftCount(imm8), "illegal shift count");
int encode = prefix_and_encode(dst->encoding());
if (imm8 == 1 ) {
! emit_int8(0xD1);
! emit_int8(0xE0 | encode);
} else {
! emit_int8(0xC1);
! emit_int8(0xE0 | encode);
! emit_int8(imm8);
}
}
void Assembler::shll(Register dst) {
int encode = prefix_and_encode(dst->encoding());
! emit_int8(0xD3);
! emit_int8(0xE0 | encode);
}
void Assembler::shrl(Register dst, int imm8) {
assert(isShiftCount(imm8), "illegal shift count");
int encode = prefix_and_encode(dst->encoding());
! emit_int8(0xC1);
! emit_int8(0xE8 | encode);
! emit_int8(imm8);
}
void Assembler::shrl(Register dst) {
int encode = prefix_and_encode(dst->encoding());
! emit_int8(0xD3);
! emit_int8(0xE8 | encode);
}
// copies a single word from [esi] to [edi]
void Assembler::smovl() {
! emit_int8(0xA5);
}
void Assembler::sqrtsd(XMMRegister dst, XMMRegister src) {
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
emit_simd_arith(0x51, dst, src, VEX_SIMD_F2);
*** 2686,2696 ****
NOT_LP64(assert(VM_Version::supports_sse(), ""));
emit_simd_arith(0x51, dst, src, VEX_SIMD_F3);
}
void Assembler::std() {
! emit_byte(0xfd);
}
void Assembler::sqrtss(XMMRegister dst, Address src) {
NOT_LP64(assert(VM_Version::supports_sse(), ""));
emit_simd_arith(0x51, dst, src, VEX_SIMD_F3);
--- 2686,2696 ----
NOT_LP64(assert(VM_Version::supports_sse(), ""));
emit_simd_arith(0x51, dst, src, VEX_SIMD_F3);
}
void Assembler::std() {
! emit_int8(0xfd);
}
void Assembler::sqrtss(XMMRegister dst, Address src) {
NOT_LP64(assert(VM_Version::supports_sse(), ""));
emit_simd_arith(0x51, dst, src, VEX_SIMD_F3);
*** 2698,2709 ****
void Assembler::stmxcsr( Address dst) {
NOT_LP64(assert(VM_Version::supports_sse(), ""));
InstructionMark im(this);
prefix(dst);
! emit_byte(0x0F);
! emit_byte(0xAE);
emit_operand(as_Register(3), dst);
}
void Assembler::subl(Address dst, int32_t imm32) {
InstructionMark im(this);
--- 2698,2709 ----
void Assembler::stmxcsr( Address dst) {
NOT_LP64(assert(VM_Version::supports_sse(), ""));
InstructionMark im(this);
prefix(dst);
! emit_int8(0x0F);
! emit_int8(0xAE);
emit_operand(as_Register(3), dst);
}
void Assembler::subl(Address dst, int32_t imm32) {
InstructionMark im(this);
*** 2712,2722 ****
}
void Assembler::subl(Address dst, Register src) {
InstructionMark im(this);
prefix(dst, src);
! emit_byte(0x29);
emit_operand(src, dst);
}
void Assembler::subl(Register dst, int32_t imm32) {
prefix(dst);
--- 2712,2722 ----
}
void Assembler::subl(Address dst, Register src) {
InstructionMark im(this);
prefix(dst, src);
! emit_int8(0x29);
emit_operand(src, dst);
}
void Assembler::subl(Register dst, int32_t imm32) {
prefix(dst);
*** 2730,2740 ****
}
void Assembler::subl(Register dst, Address src) {
InstructionMark im(this);
prefix(src, dst);
! emit_byte(0x2B);
emit_operand(dst, src);
}
void Assembler::subl(Register dst, Register src) {
(void) prefix_and_encode(dst->encoding(), src->encoding());
--- 2730,2740 ----
}
void Assembler::subl(Register dst, Address src) {
InstructionMark im(this);
prefix(src, dst);
! emit_int8(0x2B);
emit_operand(dst, src);
}
void Assembler::subl(Register dst, Register src) {
(void) prefix_and_encode(dst->encoding(), src->encoding());
*** 2771,2785 ****
// not using emit_arith because test
// doesn't support sign-extension of
// 8bit operands
int encode = dst->encoding();
if (encode == 0) {
! emit_byte(0xA9);
} else {
encode = prefix_and_encode(encode);
! emit_byte(0xF7);
! emit_byte(0xC0 | encode);
}
emit_long(imm32);
}
void Assembler::testl(Register dst, Register src) {
--- 2771,2785 ----
// not using emit_arith because test
// doesn't support sign-extension of
// 8bit operands
int encode = dst->encoding();
if (encode == 0) {
! emit_int8(0xA9);
} else {
encode = prefix_and_encode(encode);
! emit_int8(0xF7);
! emit_int8(0xC0 | encode);
}
emit_long(imm32);
}
void Assembler::testl(Register dst, Register src) {
*** 2788,2798 ****
}
void Assembler::testl(Register dst, Address src) {
InstructionMark im(this);
prefix(src, dst);
! emit_byte(0x85);
emit_operand(dst, src);
}
void Assembler::ucomisd(XMMRegister dst, Address src) {
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
--- 2788,2798 ----
}
void Assembler::testl(Register dst, Address src) {
InstructionMark im(this);
prefix(src, dst);
! emit_int8(0x85);
emit_operand(dst, src);
}
void Assembler::ucomisd(XMMRegister dst, Address src) {
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
*** 2816,2858 ****
void Assembler::xaddl(Address dst, Register src) {
InstructionMark im(this);
prefix(dst, src);
! emit_byte(0x0F);
! emit_byte(0xC1);
emit_operand(src, dst);
}
void Assembler::xchgl(Register dst, Address src) { // xchg
InstructionMark im(this);
prefix(src, dst);
! emit_byte(0x87);
emit_operand(dst, src);
}
void Assembler::xchgl(Register dst, Register src) {
int encode = prefix_and_encode(dst->encoding(), src->encoding());
! emit_byte(0x87);
! emit_byte(0xc0 | encode);
}
void Assembler::xgetbv() {
! emit_byte(0x0F);
! emit_byte(0x01);
! emit_byte(0xD0);
}
void Assembler::xorl(Register dst, int32_t imm32) {
prefix(dst);
emit_arith(0x81, 0xF0, dst, imm32);
}
void Assembler::xorl(Register dst, Address src) {
InstructionMark im(this);
prefix(src, dst);
! emit_byte(0x33);
emit_operand(dst, src);
}
void Assembler::xorl(Register dst, Register src) {
(void) prefix_and_encode(dst->encoding(), src->encoding());
--- 2816,2858 ----
void Assembler::xaddl(Address dst, Register src) {
InstructionMark im(this);
prefix(dst, src);
! emit_int8(0x0F);
! emit_int8(0xC1);
emit_operand(src, dst);
}
void Assembler::xchgl(Register dst, Address src) { // xchg
InstructionMark im(this);
prefix(src, dst);
! emit_int8(0x87);
emit_operand(dst, src);
}
void Assembler::xchgl(Register dst, Register src) {
int encode = prefix_and_encode(dst->encoding(), src->encoding());
! emit_int8(0x87);
! emit_int8(0xc0 | encode);
}
void Assembler::xgetbv() {
! emit_int8(0x0F);
! emit_int8(0x01);
! emit_int8(0xD0);
}
void Assembler::xorl(Register dst, int32_t imm32) {
prefix(dst);
emit_arith(0x81, 0xF0, dst, imm32);
}
void Assembler::xorl(Register dst, Address src) {
InstructionMark im(this);
prefix(src, dst);
! emit_int8(0x33);
emit_operand(dst, src);
}
void Assembler::xorl(Register dst, Register src) {
(void) prefix_and_encode(dst->encoding(), src->encoding());
*** 3274,3297 ****
}
void Assembler::pmulld(XMMRegister dst, XMMRegister src) {
assert(VM_Version::supports_sse4_1(), "");
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38);
! emit_byte(0x40);
! emit_byte(0xC0 | encode);
}
void Assembler::vpmullw(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256) {
assert(VM_Version::supports_avx() && !vector256 || VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
emit_vex_arith(0xD5, dst, nds, src, VEX_SIMD_66, vector256);
}
void Assembler::vpmulld(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256) {
assert(VM_Version::supports_avx() && !vector256 || VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
int encode = vex_prefix_and_encode(dst, nds, src, VEX_SIMD_66, vector256, VEX_OPCODE_0F_38);
! emit_byte(0x40);
! emit_byte(0xC0 | encode);
}
void Assembler::vpmullw(XMMRegister dst, XMMRegister nds, Address src, bool vector256) {
assert(VM_Version::supports_avx() && !vector256 || VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
emit_vex_arith(0xD5, dst, nds, src, VEX_SIMD_66, vector256);
--- 3274,3297 ----
}
void Assembler::pmulld(XMMRegister dst, XMMRegister src) {
assert(VM_Version::supports_sse4_1(), "");
int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38);
! emit_int8(0x40);
! emit_int8(0xC0 | encode);
}
void Assembler::vpmullw(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256) {
assert(VM_Version::supports_avx() && !vector256 || VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
emit_vex_arith(0xD5, dst, nds, src, VEX_SIMD_66, vector256);
}
void Assembler::vpmulld(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256) {
assert(VM_Version::supports_avx() && !vector256 || VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
int encode = vex_prefix_and_encode(dst, nds, src, VEX_SIMD_66, vector256, VEX_OPCODE_0F_38);
! emit_int8(0x40);
! emit_int8(0xC0 | encode);
}
void Assembler::vpmullw(XMMRegister dst, XMMRegister nds, Address src, bool vector256) {
assert(VM_Version::supports_avx() && !vector256 || VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
emit_vex_arith(0xD5, dst, nds, src, VEX_SIMD_66, vector256);
*** 3301,3340 ****
assert(VM_Version::supports_avx() && !vector256 || VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
InstructionMark im(this);
int dst_enc = dst->encoding();
int nds_enc = nds->is_valid() ? nds->encoding() : 0;
vex_prefix(src, nds_enc, dst_enc, VEX_SIMD_66, VEX_OPCODE_0F_38, false, vector256);
! emit_byte(0x40);
emit_operand(dst, src);
}
// Shift packed integers left by specified number of bits.
void Assembler::psllw(XMMRegister dst, int shift) {
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
// XMM6 is for /6 encoding: 66 0F 71 /6 ib
int encode = simd_prefix_and_encode(xmm6, dst, dst, VEX_SIMD_66);
! emit_byte(0x71);
! emit_byte(0xC0 | encode);
! emit_byte(shift & 0xFF);
}
void Assembler::pslld(XMMRegister dst, int shift) {
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
// XMM6 is for /6 encoding: 66 0F 72 /6 ib
int encode = simd_prefix_and_encode(xmm6, dst, dst, VEX_SIMD_66);
! emit_byte(0x72);
! emit_byte(0xC0 | encode);
! emit_byte(shift & 0xFF);
}
void Assembler::psllq(XMMRegister dst, int shift) {
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
// XMM6 is for /6 encoding: 66 0F 73 /6 ib
int encode = simd_prefix_and_encode(xmm6, dst, dst, VEX_SIMD_66);
! emit_byte(0x73);
! emit_byte(0xC0 | encode);
! emit_byte(shift & 0xFF);
}
void Assembler::psllw(XMMRegister dst, XMMRegister shift) {
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
emit_simd_arith(0xF1, dst, shift, VEX_SIMD_66);
--- 3301,3340 ----
assert(VM_Version::supports_avx() && !vector256 || VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
InstructionMark im(this);
int dst_enc = dst->encoding();
int nds_enc = nds->is_valid() ? nds->encoding() : 0;
vex_prefix(src, nds_enc, dst_enc, VEX_SIMD_66, VEX_OPCODE_0F_38, false, vector256);
! emit_int8(0x40);
emit_operand(dst, src);
}
// Shift packed integers left by specified number of bits.
void Assembler::psllw(XMMRegister dst, int shift) {
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
// XMM6 is for /6 encoding: 66 0F 71 /6 ib
int encode = simd_prefix_and_encode(xmm6, dst, dst, VEX_SIMD_66);
! emit_int8(0x71);
! emit_int8(0xC0 | encode);
! emit_int8(shift & 0xFF);
}
void Assembler::pslld(XMMRegister dst, int shift) {
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
// XMM6 is for /6 encoding: 66 0F 72 /6 ib
int encode = simd_prefix_and_encode(xmm6, dst, dst, VEX_SIMD_66);
! emit_int8(0x72);
! emit_int8(0xC0 | encode);
! emit_int8(shift & 0xFF);
}
void Assembler::psllq(XMMRegister dst, int shift) {
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
// XMM6 is for /6 encoding: 66 0F 73 /6 ib
int encode = simd_prefix_and_encode(xmm6, dst, dst, VEX_SIMD_66);
! emit_int8(0x73);
! emit_int8(0xC0 | encode);
! emit_int8(shift & 0xFF);
}
void Assembler::psllw(XMMRegister dst, XMMRegister shift) {
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
emit_simd_arith(0xF1, dst, shift, VEX_SIMD_66);
*** 3352,3376 ****
void Assembler::vpsllw(XMMRegister dst, XMMRegister src, int shift, bool vector256) {
assert(VM_Version::supports_avx() && !vector256 || VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
// XMM6 is for /6 encoding: 66 0F 71 /6 ib
emit_vex_arith(0x71, xmm6, dst, src, VEX_SIMD_66, vector256);
! emit_byte(shift & 0xFF);
}
void Assembler::vpslld(XMMRegister dst, XMMRegister src, int shift, bool vector256) {
assert(VM_Version::supports_avx() && !vector256 || VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
// XMM6 is for /6 encoding: 66 0F 72 /6 ib
emit_vex_arith(0x72, xmm6, dst, src, VEX_SIMD_66, vector256);
! emit_byte(shift & 0xFF);
}
void Assembler::vpsllq(XMMRegister dst, XMMRegister src, int shift, bool vector256) {
assert(VM_Version::supports_avx() && !vector256 || VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
// XMM6 is for /6 encoding: 66 0F 73 /6 ib
emit_vex_arith(0x73, xmm6, dst, src, VEX_SIMD_66, vector256);
! emit_byte(shift & 0xFF);
}
void Assembler::vpsllw(XMMRegister dst, XMMRegister src, XMMRegister shift, bool vector256) {
assert(VM_Version::supports_avx() && !vector256 || VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
emit_vex_arith(0xF1, dst, src, shift, VEX_SIMD_66, vector256);
--- 3352,3376 ----
void Assembler::vpsllw(XMMRegister dst, XMMRegister src, int shift, bool vector256) {
assert(VM_Version::supports_avx() && !vector256 || VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
// XMM6 is for /6 encoding: 66 0F 71 /6 ib
emit_vex_arith(0x71, xmm6, dst, src, VEX_SIMD_66, vector256);
! emit_int8(shift & 0xFF);
}
void Assembler::vpslld(XMMRegister dst, XMMRegister src, int shift, bool vector256) {
assert(VM_Version::supports_avx() && !vector256 || VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
// XMM6 is for /6 encoding: 66 0F 72 /6 ib
emit_vex_arith(0x72, xmm6, dst, src, VEX_SIMD_66, vector256);
! emit_int8(shift & 0xFF);
}
void Assembler::vpsllq(XMMRegister dst, XMMRegister src, int shift, bool vector256) {
assert(VM_Version::supports_avx() && !vector256 || VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
// XMM6 is for /6 encoding: 66 0F 73 /6 ib
emit_vex_arith(0x73, xmm6, dst, src, VEX_SIMD_66, vector256);
! emit_int8(shift & 0xFF);
}
void Assembler::vpsllw(XMMRegister dst, XMMRegister src, XMMRegister shift, bool vector256) {
assert(VM_Version::supports_avx() && !vector256 || VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
emit_vex_arith(0xF1, dst, src, shift, VEX_SIMD_66, vector256);
*** 3389,3421 ****
// Shift packed integers logically right by specified number of bits.
void Assembler::psrlw(XMMRegister dst, int shift) {
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
// XMM2 is for /2 encoding: 66 0F 71 /2 ib
int encode = simd_prefix_and_encode(xmm2, dst, dst, VEX_SIMD_66);
! emit_byte(0x71);
! emit_byte(0xC0 | encode);
! emit_byte(shift & 0xFF);
}
void Assembler::psrld(XMMRegister dst, int shift) {
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
// XMM2 is for /2 encoding: 66 0F 72 /2 ib
int encode = simd_prefix_and_encode(xmm2, dst, dst, VEX_SIMD_66);
! emit_byte(0x72);
! emit_byte(0xC0 | encode);
! emit_byte(shift & 0xFF);
}
void Assembler::psrlq(XMMRegister dst, int shift) {
// Do not confuse it with psrldq SSE2 instruction which
// shifts 128 bit value in xmm register by number of bytes.
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
// XMM2 is for /2 encoding: 66 0F 73 /2 ib
int encode = simd_prefix_and_encode(xmm2, dst, dst, VEX_SIMD_66);
! emit_byte(0x73);
! emit_byte(0xC0 | encode);
! emit_byte(shift & 0xFF);
}
void Assembler::psrlw(XMMRegister dst, XMMRegister shift) {
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
emit_simd_arith(0xD1, dst, shift, VEX_SIMD_66);
--- 3389,3421 ----
// Shift packed integers logically right by specified number of bits.
void Assembler::psrlw(XMMRegister dst, int shift) {
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
// XMM2 is for /2 encoding: 66 0F 71 /2 ib
int encode = simd_prefix_and_encode(xmm2, dst, dst, VEX_SIMD_66);
! emit_int8(0x71);
! emit_int8(0xC0 | encode);
! emit_int8(shift & 0xFF);
}
void Assembler::psrld(XMMRegister dst, int shift) {
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
// XMM2 is for /2 encoding: 66 0F 72 /2 ib
int encode = simd_prefix_and_encode(xmm2, dst, dst, VEX_SIMD_66);
! emit_int8(0x72);
! emit_int8(0xC0 | encode);
! emit_int8(shift & 0xFF);
}
void Assembler::psrlq(XMMRegister dst, int shift) {
// Do not confuse it with psrldq SSE2 instruction which
// shifts 128 bit value in xmm register by number of bytes.
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
// XMM2 is for /2 encoding: 66 0F 73 /2 ib
int encode = simd_prefix_and_encode(xmm2, dst, dst, VEX_SIMD_66);
! emit_int8(0x73);
! emit_int8(0xC0 | encode);
! emit_int8(shift & 0xFF);
}
void Assembler::psrlw(XMMRegister dst, XMMRegister shift) {
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
emit_simd_arith(0xD1, dst, shift, VEX_SIMD_66);
*** 3433,3457 ****
void Assembler::vpsrlw(XMMRegister dst, XMMRegister src, int shift, bool vector256) {
assert(VM_Version::supports_avx() && !vector256 || VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
// XMM2 is for /2 encoding: 66 0F 73 /2 ib
emit_vex_arith(0x71, xmm2, dst, src, VEX_SIMD_66, vector256);
! emit_byte(shift & 0xFF);
}
void Assembler::vpsrld(XMMRegister dst, XMMRegister src, int shift, bool vector256) {
assert(VM_Version::supports_avx() && !vector256 || VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
// XMM2 is for /2 encoding: 66 0F 73 /2 ib
emit_vex_arith(0x72, xmm2, dst, src, VEX_SIMD_66, vector256);
! emit_byte(shift & 0xFF);
}
void Assembler::vpsrlq(XMMRegister dst, XMMRegister src, int shift, bool vector256) {
assert(VM_Version::supports_avx() && !vector256 || VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
// XMM2 is for /2 encoding: 66 0F 73 /2 ib
emit_vex_arith(0x73, xmm2, dst, src, VEX_SIMD_66, vector256);
! emit_byte(shift & 0xFF);
}
void Assembler::vpsrlw(XMMRegister dst, XMMRegister src, XMMRegister shift, bool vector256) {
assert(VM_Version::supports_avx() && !vector256 || VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
emit_vex_arith(0xD1, dst, src, shift, VEX_SIMD_66, vector256);
--- 3433,3457 ----
void Assembler::vpsrlw(XMMRegister dst, XMMRegister src, int shift, bool vector256) {
assert(VM_Version::supports_avx() && !vector256 || VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
// XMM2 is for /2 encoding: 66 0F 73 /2 ib
emit_vex_arith(0x71, xmm2, dst, src, VEX_SIMD_66, vector256);
! emit_int8(shift & 0xFF);
}
void Assembler::vpsrld(XMMRegister dst, XMMRegister src, int shift, bool vector256) {
assert(VM_Version::supports_avx() && !vector256 || VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
// XMM2 is for /2 encoding: 66 0F 73 /2 ib
emit_vex_arith(0x72, xmm2, dst, src, VEX_SIMD_66, vector256);
! emit_int8(shift & 0xFF);
}
void Assembler::vpsrlq(XMMRegister dst, XMMRegister src, int shift, bool vector256) {
assert(VM_Version::supports_avx() && !vector256 || VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
// XMM2 is for /2 encoding: 66 0F 73 /2 ib
emit_vex_arith(0x73, xmm2, dst, src, VEX_SIMD_66, vector256);
! emit_int8(shift & 0xFF);
}
void Assembler::vpsrlw(XMMRegister dst, XMMRegister src, XMMRegister shift, bool vector256) {
assert(VM_Version::supports_avx() && !vector256 || VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
emit_vex_arith(0xD1, dst, src, shift, VEX_SIMD_66, vector256);
*** 3470,3491 ****
// Shift packed integers arithmetically right by specified number of bits.
void Assembler::psraw(XMMRegister dst, int shift) {
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
// XMM4 is for /4 encoding: 66 0F 71 /4 ib
int encode = simd_prefix_and_encode(xmm4, dst, dst, VEX_SIMD_66);
! emit_byte(0x71);
! emit_byte(0xC0 | encode);
! emit_byte(shift & 0xFF);
}
void Assembler::psrad(XMMRegister dst, int shift) {
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
// XMM4 is for /4 encoding: 66 0F 72 /4 ib
int encode = simd_prefix_and_encode(xmm4, dst, dst, VEX_SIMD_66);
! emit_byte(0x72);
! emit_byte(0xC0 | encode);
! emit_byte(shift & 0xFF);
}
void Assembler::psraw(XMMRegister dst, XMMRegister shift) {
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
emit_simd_arith(0xE1, dst, shift, VEX_SIMD_66);
--- 3470,3491 ----
// Shift packed integers arithmetically right by specified number of bits.
void Assembler::psraw(XMMRegister dst, int shift) {
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
// XMM4 is for /4 encoding: 66 0F 71 /4 ib
int encode = simd_prefix_and_encode(xmm4, dst, dst, VEX_SIMD_66);
! emit_int8(0x71);
! emit_int8(0xC0 | encode);
! emit_int8(shift & 0xFF);
}
void Assembler::psrad(XMMRegister dst, int shift) {
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
// XMM4 is for /4 encoding: 66 0F 72 /4 ib
int encode = simd_prefix_and_encode(xmm4, dst, dst, VEX_SIMD_66);
! emit_int8(0x72);
! emit_int8(0xC0 | encode);
! emit_int8(shift & 0xFF);
}
void Assembler::psraw(XMMRegister dst, XMMRegister shift) {
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
emit_simd_arith(0xE1, dst, shift, VEX_SIMD_66);
*** 3498,3515 ****
void Assembler::vpsraw(XMMRegister dst, XMMRegister src, int shift, bool vector256) {
assert(VM_Version::supports_avx() && !vector256 || VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
// XMM4 is for /4 encoding: 66 0F 71 /4 ib
emit_vex_arith(0x71, xmm4, dst, src, VEX_SIMD_66, vector256);
! emit_byte(shift & 0xFF);
}
void Assembler::vpsrad(XMMRegister dst, XMMRegister src, int shift, bool vector256) {
assert(VM_Version::supports_avx() && !vector256 || VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
// XMM4 is for /4 encoding: 66 0F 71 /4 ib
emit_vex_arith(0x72, xmm4, dst, src, VEX_SIMD_66, vector256);
! emit_byte(shift & 0xFF);
}
void Assembler::vpsraw(XMMRegister dst, XMMRegister src, XMMRegister shift, bool vector256) {
assert(VM_Version::supports_avx() && !vector256 || VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
emit_vex_arith(0xE1, dst, src, shift, VEX_SIMD_66, vector256);
--- 3498,3515 ----
void Assembler::vpsraw(XMMRegister dst, XMMRegister src, int shift, bool vector256) {
assert(VM_Version::supports_avx() && !vector256 || VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
// XMM4 is for /4 encoding: 66 0F 71 /4 ib
emit_vex_arith(0x71, xmm4, dst, src, VEX_SIMD_66, vector256);
! emit_int8(shift & 0xFF);
}
void Assembler::vpsrad(XMMRegister dst, XMMRegister src, int shift, bool vector256) {
assert(VM_Version::supports_avx() && !vector256 || VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
// XMM4 is for /4 encoding: 66 0F 71 /4 ib
emit_vex_arith(0x72, xmm4, dst, src, VEX_SIMD_66, vector256);
! emit_int8(shift & 0xFF);
}
void Assembler::vpsraw(XMMRegister dst, XMMRegister src, XMMRegister shift, bool vector256) {
assert(VM_Version::supports_avx() && !vector256 || VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
emit_vex_arith(0xE1, dst, src, shift, VEX_SIMD_66, vector256);
*** 3570,3714 ****
void Assembler::vinsertf128h(XMMRegister dst, XMMRegister nds, XMMRegister src) {
assert(VM_Version::supports_avx(), "");
bool vector256 = true;
int encode = vex_prefix_and_encode(dst, nds, src, VEX_SIMD_66, vector256, VEX_OPCODE_0F_3A);
! emit_byte(0x18);
! emit_byte(0xC0 | encode);
// 0x00 - insert into lower 128 bits
// 0x01 - insert into upper 128 bits
! emit_byte(0x01);
}
void Assembler::vinsertf128h(XMMRegister dst, Address src) {
assert(VM_Version::supports_avx(), "");
InstructionMark im(this);
bool vector256 = true;
assert(dst != xnoreg, "sanity");
int dst_enc = dst->encoding();
// swap src<->dst for encoding
vex_prefix(src, dst_enc, dst_enc, VEX_SIMD_66, VEX_OPCODE_0F_3A, false, vector256);
! emit_byte(0x18);
emit_operand(dst, src);
// 0x01 - insert into upper 128 bits
! emit_byte(0x01);
}
void Assembler::vextractf128h(Address dst, XMMRegister src) {
assert(VM_Version::supports_avx(), "");
InstructionMark im(this);
bool vector256 = true;
assert(src != xnoreg, "sanity");
int src_enc = src->encoding();
vex_prefix(dst, 0, src_enc, VEX_SIMD_66, VEX_OPCODE_0F_3A, false, vector256);
! emit_byte(0x19);
emit_operand(src, dst);
// 0x01 - extract from upper 128 bits
! emit_byte(0x01);
}
void Assembler::vinserti128h(XMMRegister dst, XMMRegister nds, XMMRegister src) {
assert(VM_Version::supports_avx2(), "");
bool vector256 = true;
int encode = vex_prefix_and_encode(dst, nds, src, VEX_SIMD_66, vector256, VEX_OPCODE_0F_3A);
! emit_byte(0x38);
! emit_byte(0xC0 | encode);
// 0x00 - insert into lower 128 bits
// 0x01 - insert into upper 128 bits
! emit_byte(0x01);
}
void Assembler::vinserti128h(XMMRegister dst, Address src) {
assert(VM_Version::supports_avx2(), "");
InstructionMark im(this);
bool vector256 = true;
assert(dst != xnoreg, "sanity");
int dst_enc = dst->encoding();
// swap src<->dst for encoding
vex_prefix(src, dst_enc, dst_enc, VEX_SIMD_66, VEX_OPCODE_0F_3A, false, vector256);
! emit_byte(0x38);
emit_operand(dst, src);
// 0x01 - insert into upper 128 bits
! emit_byte(0x01);
}
void Assembler::vextracti128h(Address dst, XMMRegister src) {
assert(VM_Version::supports_avx2(), "");
InstructionMark im(this);
bool vector256 = true;
assert(src != xnoreg, "sanity");
int src_enc = src->encoding();
vex_prefix(dst, 0, src_enc, VEX_SIMD_66, VEX_OPCODE_0F_3A, false, vector256);
! emit_byte(0x39);
emit_operand(src, dst);
// 0x01 - extract from upper 128 bits
! emit_byte(0x01);
}
void Assembler::vzeroupper() {
assert(VM_Version::supports_avx(), "");
(void)vex_prefix_and_encode(xmm0, xmm0, xmm0, VEX_SIMD_NONE);
! emit_byte(0x77);
}
#ifndef _LP64
// 32bit only pieces of the assembler
void Assembler::cmp_literal32(Register src1, int32_t imm32, RelocationHolder const& rspec) {
// NO PREFIX AS NEVER 64BIT
InstructionMark im(this);
! emit_byte(0x81);
! emit_byte(0xF8 | src1->encoding());
emit_data(imm32, rspec, 0);
}
void Assembler::cmp_literal32(Address src1, int32_t imm32, RelocationHolder const& rspec) {
// NO PREFIX AS NEVER 64BIT (not even 32bit versions of 64bit regs
InstructionMark im(this);
! emit_byte(0x81);
emit_operand(rdi, src1);
emit_data(imm32, rspec, 0);
}
// The 64-bit (32bit platform) cmpxchg compares the value at adr with the contents of rdx:rax,
// and stores rcx:rbx into adr if so; otherwise, the value at adr is loaded
// into rdx:rax. The ZF is set if the compared values were equal, and cleared otherwise.
void Assembler::cmpxchg8(Address adr) {
InstructionMark im(this);
! emit_byte(0x0F);
! emit_byte(0xc7);
emit_operand(rcx, adr);
}
void Assembler::decl(Register dst) {
// Don't use it directly. Use MacroAssembler::decrementl() instead.
! emit_byte(0x48 | dst->encoding());
}
#endif // _LP64
// 64bit typically doesn't use the x87 but needs to for the trig funcs
void Assembler::fabs() {
! emit_byte(0xD9);
! emit_byte(0xE1);
}
void Assembler::fadd(int i) {
emit_farith(0xD8, 0xC0, i);
}
void Assembler::fadd_d(Address src) {
InstructionMark im(this);
! emit_byte(0xDC);
emit_operand32(rax, src);
}
void Assembler::fadd_s(Address src) {
InstructionMark im(this);
! emit_byte(0xD8);
emit_operand32(rax, src);
}
void Assembler::fadda(int i) {
emit_farith(0xDC, 0xC0, i);
--- 3570,3714 ----
void Assembler::vinsertf128h(XMMRegister dst, XMMRegister nds, XMMRegister src) {
assert(VM_Version::supports_avx(), "");
bool vector256 = true;
int encode = vex_prefix_and_encode(dst, nds, src, VEX_SIMD_66, vector256, VEX_OPCODE_0F_3A);
! emit_int8(0x18);
! emit_int8(0xC0 | encode);
// 0x00 - insert into lower 128 bits
// 0x01 - insert into upper 128 bits
! emit_int8(0x01);
}
void Assembler::vinsertf128h(XMMRegister dst, Address src) {
assert(VM_Version::supports_avx(), "");
InstructionMark im(this);
bool vector256 = true;
assert(dst != xnoreg, "sanity");
int dst_enc = dst->encoding();
// swap src<->dst for encoding
vex_prefix(src, dst_enc, dst_enc, VEX_SIMD_66, VEX_OPCODE_0F_3A, false, vector256);
! emit_int8(0x18);
emit_operand(dst, src);
// 0x01 - insert into upper 128 bits
! emit_int8(0x01);
}
void Assembler::vextractf128h(Address dst, XMMRegister src) {
assert(VM_Version::supports_avx(), "");
InstructionMark im(this);
bool vector256 = true;
assert(src != xnoreg, "sanity");
int src_enc = src->encoding();
vex_prefix(dst, 0, src_enc, VEX_SIMD_66, VEX_OPCODE_0F_3A, false, vector256);
! emit_int8(0x19);
emit_operand(src, dst);
// 0x01 - extract from upper 128 bits
! emit_int8(0x01);
}
void Assembler::vinserti128h(XMMRegister dst, XMMRegister nds, XMMRegister src) {
assert(VM_Version::supports_avx2(), "");
bool vector256 = true;
int encode = vex_prefix_and_encode(dst, nds, src, VEX_SIMD_66, vector256, VEX_OPCODE_0F_3A);
! emit_int8(0x38);
! emit_int8(0xC0 | encode);
// 0x00 - insert into lower 128 bits
// 0x01 - insert into upper 128 bits
! emit_int8(0x01);
}
void Assembler::vinserti128h(XMMRegister dst, Address src) {
assert(VM_Version::supports_avx2(), "");
InstructionMark im(this);
bool vector256 = true;
assert(dst != xnoreg, "sanity");
int dst_enc = dst->encoding();
// swap src<->dst for encoding
vex_prefix(src, dst_enc, dst_enc, VEX_SIMD_66, VEX_OPCODE_0F_3A, false, vector256);
! emit_int8(0x38);
emit_operand(dst, src);
// 0x01 - insert into upper 128 bits
! emit_int8(0x01);
}
void Assembler::vextracti128h(Address dst, XMMRegister src) {
assert(VM_Version::supports_avx2(), "");
InstructionMark im(this);
bool vector256 = true;
assert(src != xnoreg, "sanity");
int src_enc = src->encoding();
vex_prefix(dst, 0, src_enc, VEX_SIMD_66, VEX_OPCODE_0F_3A, false, vector256);
! emit_int8(0x39);
emit_operand(src, dst);
// 0x01 - extract from upper 128 bits
! emit_int8(0x01);
}
void Assembler::vzeroupper() {
assert(VM_Version::supports_avx(), "");
(void)vex_prefix_and_encode(xmm0, xmm0, xmm0, VEX_SIMD_NONE);
! emit_int8(0x77);
}
#ifndef _LP64
// 32bit only pieces of the assembler
void Assembler::cmp_literal32(Register src1, int32_t imm32, RelocationHolder const& rspec) {
// NO PREFIX AS NEVER 64BIT
InstructionMark im(this);
! emit_int8(0x81);
! emit_int8(0xF8 | src1->encoding());
emit_data(imm32, rspec, 0);
}
void Assembler::cmp_literal32(Address src1, int32_t imm32, RelocationHolder const& rspec) {
// NO PREFIX AS NEVER 64BIT (not even 32bit versions of 64bit regs
InstructionMark im(this);
! emit_int8(0x81);
emit_operand(rdi, src1);
emit_data(imm32, rspec, 0);
}
// The 64-bit (32bit platform) cmpxchg compares the value at adr with the contents of rdx:rax,
// and stores rcx:rbx into adr if so; otherwise, the value at adr is loaded
// into rdx:rax. The ZF is set if the compared values were equal, and cleared otherwise.
void Assembler::cmpxchg8(Address adr) {
InstructionMark im(this);
! emit_int8(0x0F);
! emit_int8(0xc7);
emit_operand(rcx, adr);
}
void Assembler::decl(Register dst) {
// Don't use it directly. Use MacroAssembler::decrementl() instead.
! emit_int8(0x48 | dst->encoding());
}
#endif // _LP64
// 64bit typically doesn't use the x87 but needs to for the trig funcs
void Assembler::fabs() {
! emit_int8(0xD9);
! emit_int8(0xE1);
}
void Assembler::fadd(int i) {
emit_farith(0xD8, 0xC0, i);
}
void Assembler::fadd_d(Address src) {
InstructionMark im(this);
! emit_int8(0xDC);
emit_operand32(rax, src);
}
void Assembler::fadd_s(Address src) {
InstructionMark im(this);
! emit_int8(0xD8);
emit_operand32(rax, src);
}
void Assembler::fadda(int i) {
emit_farith(0xDC, 0xC0, i);
*** 3717,3728 ****
void Assembler::faddp(int i) {
emit_farith(0xDE, 0xC0, i);
}
void Assembler::fchs() {
! emit_byte(0xD9);
! emit_byte(0xE0);
}
void Assembler::fcom(int i) {
emit_farith(0xD8, 0xD0, i);
}
--- 3717,3728 ----
void Assembler::faddp(int i) {
emit_farith(0xDE, 0xC0, i);
}
void Assembler::fchs() {
! emit_int8(0xD9);
! emit_int8(0xE0);
}
void Assembler::fcom(int i) {
emit_farith(0xD8, 0xD0, i);
}
*** 3731,3778 ****
emit_farith(0xD8, 0xD8, i);
}
void Assembler::fcomp_d(Address src) {
InstructionMark im(this);
! emit_byte(0xDC);
emit_operand32(rbx, src);
}
void Assembler::fcomp_s(Address src) {
InstructionMark im(this);
! emit_byte(0xD8);
emit_operand32(rbx, src);
}
void Assembler::fcompp() {
! emit_byte(0xDE);
! emit_byte(0xD9);
}
void Assembler::fcos() {
! emit_byte(0xD9);
! emit_byte(0xFF);
}
void Assembler::fdecstp() {
! emit_byte(0xD9);
! emit_byte(0xF6);
}
void Assembler::fdiv(int i) {
emit_farith(0xD8, 0xF0, i);
}
void Assembler::fdiv_d(Address src) {
InstructionMark im(this);
! emit_byte(0xDC);
emit_operand32(rsi, src);
}
void Assembler::fdiv_s(Address src) {
InstructionMark im(this);
! emit_byte(0xD8);
emit_operand32(rsi, src);
}
void Assembler::fdiva(int i) {
emit_farith(0xDC, 0xF8, i);
--- 3731,3778 ----
emit_farith(0xD8, 0xD8, i);
}
void Assembler::fcomp_d(Address src) {
InstructionMark im(this);
! emit_int8(0xDC);
emit_operand32(rbx, src);
}
void Assembler::fcomp_s(Address src) {
InstructionMark im(this);
! emit_int8(0xD8);
emit_operand32(rbx, src);
}
void Assembler::fcompp() {
! emit_int8(0xDE);
! emit_int8(0xD9);
}
void Assembler::fcos() {
! emit_int8(0xD9);
! emit_int8(0xFF);
}
void Assembler::fdecstp() {
! emit_int8(0xD9);
! emit_int8(0xF6);
}
void Assembler::fdiv(int i) {
emit_farith(0xD8, 0xF0, i);
}
void Assembler::fdiv_d(Address src) {
InstructionMark im(this);
! emit_int8(0xDC);
emit_operand32(rsi, src);
}
void Assembler::fdiv_s(Address src) {
InstructionMark im(this);
! emit_int8(0xD8);
emit_operand32(rsi, src);
}
void Assembler::fdiva(int i) {
emit_farith(0xDC, 0xF8, i);
*** 3789,3805 ****
emit_farith(0xD8, 0xF8, i);
}
void Assembler::fdivr_d(Address src) {
InstructionMark im(this);
! emit_byte(0xDC);
emit_operand32(rdi, src);
}
void Assembler::fdivr_s(Address src) {
InstructionMark im(this);
! emit_byte(0xD8);
emit_operand32(rdi, src);
}
void Assembler::fdivra(int i) {
emit_farith(0xDC, 0xF0, i);
--- 3789,3805 ----
emit_farith(0xD8, 0xF8, i);
}
void Assembler::fdivr_d(Address src) {
InstructionMark im(this);
! emit_int8(0xDC);
emit_operand32(rdi, src);
}
void Assembler::fdivr_s(Address src) {
InstructionMark im(this);
! emit_int8(0xD8);
emit_operand32(rdi, src);
}
void Assembler::fdivra(int i) {
emit_farith(0xDC, 0xF0, i);
*** 3813,3914 ****
emit_farith(0xDD, 0xC0, i);
}
void Assembler::fild_d(Address adr) {
InstructionMark im(this);
! emit_byte(0xDF);
emit_operand32(rbp, adr);
}
void Assembler::fild_s(Address adr) {
InstructionMark im(this);
! emit_byte(0xDB);
emit_operand32(rax, adr);
}
void Assembler::fincstp() {
! emit_byte(0xD9);
! emit_byte(0xF7);
}
void Assembler::finit() {
! emit_byte(0x9B);
! emit_byte(0xDB);
! emit_byte(0xE3);
}
void Assembler::fist_s(Address adr) {
InstructionMark im(this);
! emit_byte(0xDB);
emit_operand32(rdx, adr);
}
void Assembler::fistp_d(Address adr) {
InstructionMark im(this);
! emit_byte(0xDF);
emit_operand32(rdi, adr);
}
void Assembler::fistp_s(Address adr) {
InstructionMark im(this);
! emit_byte(0xDB);
emit_operand32(rbx, adr);
}
void Assembler::fld1() {
! emit_byte(0xD9);
! emit_byte(0xE8);
}
void Assembler::fld_d(Address adr) {
InstructionMark im(this);
! emit_byte(0xDD);
emit_operand32(rax, adr);
}
void Assembler::fld_s(Address adr) {
InstructionMark im(this);
! emit_byte(0xD9);
emit_operand32(rax, adr);
}
void Assembler::fld_s(int index) {
emit_farith(0xD9, 0xC0, index);
}
void Assembler::fld_x(Address adr) {
InstructionMark im(this);
! emit_byte(0xDB);
emit_operand32(rbp, adr);
}
void Assembler::fldcw(Address src) {
InstructionMark im(this);
! emit_byte(0xd9);
emit_operand32(rbp, src);
}
void Assembler::fldenv(Address src) {
InstructionMark im(this);
! emit_byte(0xD9);
emit_operand32(rsp, src);
}
void Assembler::fldlg2() {
! emit_byte(0xD9);
! emit_byte(0xEC);
}
void Assembler::fldln2() {
! emit_byte(0xD9);
! emit_byte(0xED);
}
void Assembler::fldz() {
! emit_byte(0xD9);
! emit_byte(0xEE);
}
void Assembler::flog() {
fldln2();
fxch();
--- 3813,3914 ----
emit_farith(0xDD, 0xC0, i);
}
void Assembler::fild_d(Address adr) {
InstructionMark im(this);
! emit_int8(0xDF);
emit_operand32(rbp, adr);
}
void Assembler::fild_s(Address adr) {
InstructionMark im(this);
! emit_int8(0xDB);
emit_operand32(rax, adr);
}
void Assembler::fincstp() {
! emit_int8(0xD9);
! emit_int8(0xF7);
}
void Assembler::finit() {
! emit_int8(0x9B);
! emit_int8(0xDB);
! emit_int8(0xE3);
}
void Assembler::fist_s(Address adr) {
InstructionMark im(this);
! emit_int8(0xDB);
emit_operand32(rdx, adr);
}
void Assembler::fistp_d(Address adr) {
InstructionMark im(this);
! emit_int8(0xDF);
emit_operand32(rdi, adr);
}
void Assembler::fistp_s(Address adr) {
InstructionMark im(this);
! emit_int8(0xDB);
emit_operand32(rbx, adr);
}
void Assembler::fld1() {
! emit_int8(0xD9);
! emit_int8(0xE8);
}
void Assembler::fld_d(Address adr) {
InstructionMark im(this);
! emit_int8(0xDD);
emit_operand32(rax, adr);
}
void Assembler::fld_s(Address adr) {
InstructionMark im(this);
! emit_int8(0xD9);
emit_operand32(rax, adr);
}
void Assembler::fld_s(int index) {
emit_farith(0xD9, 0xC0, index);
}
void Assembler::fld_x(Address adr) {
InstructionMark im(this);
! emit_int8(0xDB);
emit_operand32(rbp, adr);
}
void Assembler::fldcw(Address src) {
InstructionMark im(this);
! emit_int8(0xd9);
emit_operand32(rbp, src);
}
void Assembler::fldenv(Address src) {
InstructionMark im(this);
! emit_int8(0xD9);
emit_operand32(rsp, src);
}
void Assembler::fldlg2() {
! emit_int8(0xD9);
! emit_int8(0xEC);
}
void Assembler::fldln2() {
! emit_int8(0xD9);
! emit_int8(0xED);
}
void Assembler::fldz() {
! emit_int8(0xD9);
! emit_int8(0xEE);
}
void Assembler::flog() {
fldln2();
fxch();
*** 3925,3941 ****
emit_farith(0xD8, 0xC8, i);
}
void Assembler::fmul_d(Address src) {
InstructionMark im(this);
! emit_byte(0xDC);
emit_operand32(rcx, src);
}
void Assembler::fmul_s(Address src) {
InstructionMark im(this);
! emit_byte(0xD8);
emit_operand32(rcx, src);
}
void Assembler::fmula(int i) {
emit_farith(0xDC, 0xC8, i);
--- 3925,3941 ----
emit_farith(0xD8, 0xC8, i);
}
void Assembler::fmul_d(Address src) {
InstructionMark im(this);
! emit_int8(0xDC);
emit_operand32(rcx, src);
}
void Assembler::fmul_s(Address src) {
InstructionMark im(this);
! emit_int8(0xD8);
emit_operand32(rcx, src);
}
void Assembler::fmula(int i) {
emit_farith(0xDC, 0xC8, i);
*** 3945,4043 ****
emit_farith(0xDE, 0xC8, i);
}
void Assembler::fnsave(Address dst) {
InstructionMark im(this);
! emit_byte(0xDD);
emit_operand32(rsi, dst);
}
void Assembler::fnstcw(Address src) {
InstructionMark im(this);
! emit_byte(0x9B);
! emit_byte(0xD9);
emit_operand32(rdi, src);
}
void Assembler::fnstsw_ax() {
! emit_byte(0xdF);
! emit_byte(0xE0);
}
void Assembler::fprem() {
! emit_byte(0xD9);
! emit_byte(0xF8);
}
void Assembler::fprem1() {
! emit_byte(0xD9);
! emit_byte(0xF5);
}
void Assembler::frstor(Address src) {
InstructionMark im(this);
! emit_byte(0xDD);
emit_operand32(rsp, src);
}
void Assembler::fsin() {
! emit_byte(0xD9);
! emit_byte(0xFE);
}
void Assembler::fsqrt() {
! emit_byte(0xD9);
! emit_byte(0xFA);
}
void Assembler::fst_d(Address adr) {
InstructionMark im(this);
! emit_byte(0xDD);
emit_operand32(rdx, adr);
}
void Assembler::fst_s(Address adr) {
InstructionMark im(this);
! emit_byte(0xD9);
emit_operand32(rdx, adr);
}
void Assembler::fstp_d(Address adr) {
InstructionMark im(this);
! emit_byte(0xDD);
emit_operand32(rbx, adr);
}
void Assembler::fstp_d(int index) {
emit_farith(0xDD, 0xD8, index);
}
void Assembler::fstp_s(Address adr) {
InstructionMark im(this);
! emit_byte(0xD9);
emit_operand32(rbx, adr);
}
void Assembler::fstp_x(Address adr) {
InstructionMark im(this);
! emit_byte(0xDB);
emit_operand32(rdi, adr);
}
void Assembler::fsub(int i) {
emit_farith(0xD8, 0xE0, i);
}
void Assembler::fsub_d(Address src) {
InstructionMark im(this);
! emit_byte(0xDC);
emit_operand32(rsp, src);
}
void Assembler::fsub_s(Address src) {
InstructionMark im(this);
! emit_byte(0xD8);
emit_operand32(rsp, src);
}
void Assembler::fsuba(int i) {
emit_farith(0xDC, 0xE8, i);
--- 3945,4043 ----
emit_farith(0xDE, 0xC8, i);
}
void Assembler::fnsave(Address dst) {
InstructionMark im(this);
! emit_int8(0xDD);
emit_operand32(rsi, dst);
}
void Assembler::fnstcw(Address src) {
InstructionMark im(this);
! emit_int8(0x9B);
! emit_int8(0xD9);
emit_operand32(rdi, src);
}
void Assembler::fnstsw_ax() {
! emit_int8(0xdF);
! emit_int8(0xE0);
}
void Assembler::fprem() {
! emit_int8(0xD9);
! emit_int8(0xF8);
}
void Assembler::fprem1() {
! emit_int8(0xD9);
! emit_int8(0xF5);
}
void Assembler::frstor(Address src) {
InstructionMark im(this);
! emit_int8(0xDD);
emit_operand32(rsp, src);
}
void Assembler::fsin() {
! emit_int8(0xD9);
! emit_int8(0xFE);
}
void Assembler::fsqrt() {
! emit_int8(0xD9);
! emit_int8(0xFA);
}
void Assembler::fst_d(Address adr) {
InstructionMark im(this);
! emit_int8(0xDD);
emit_operand32(rdx, adr);
}
void Assembler::fst_s(Address adr) {
InstructionMark im(this);
! emit_int8(0xD9);
emit_operand32(rdx, adr);
}
void Assembler::fstp_d(Address adr) {
InstructionMark im(this);
! emit_int8(0xDD);
emit_operand32(rbx, adr);
}
void Assembler::fstp_d(int index) {
emit_farith(0xDD, 0xD8, index);
}
void Assembler::fstp_s(Address adr) {
InstructionMark im(this);
! emit_int8(0xD9);
emit_operand32(rbx, adr);
}
void Assembler::fstp_x(Address adr) {
InstructionMark im(this);
! emit_int8(0xDB);
emit_operand32(rdi, adr);
}
void Assembler::fsub(int i) {
emit_farith(0xD8, 0xE0, i);
}
void Assembler::fsub_d(Address src) {
InstructionMark im(this);
! emit_int8(0xDC);
emit_operand32(rsp, src);
}
void Assembler::fsub_s(Address src) {
InstructionMark im(this);
! emit_int8(0xD8);
emit_operand32(rsp, src);
}
void Assembler::fsuba(int i) {
emit_farith(0xDC, 0xE8, i);
*** 4051,4067 ****
emit_farith(0xD8, 0xE8, i);
}
void Assembler::fsubr_d(Address src) {
InstructionMark im(this);
! emit_byte(0xDC);
emit_operand32(rbp, src);
}
void Assembler::fsubr_s(Address src) {
InstructionMark im(this);
! emit_byte(0xD8);
emit_operand32(rbp, src);
}
void Assembler::fsubra(int i) {
emit_farith(0xDC, 0xE0, i);
--- 4051,4067 ----
emit_farith(0xD8, 0xE8, i);
}
void Assembler::fsubr_d(Address src) {
InstructionMark im(this);
! emit_int8(0xDC);
emit_operand32(rbp, src);
}
void Assembler::fsubr_s(Address src) {
InstructionMark im(this);
! emit_int8(0xD8);
emit_operand32(rbp, src);
}
void Assembler::fsubra(int i) {
emit_farith(0xDC, 0xE0, i);
*** 4070,4088 ****
void Assembler::fsubrp(int i) {
emit_farith(0xDE, 0xE0, i); // ST(0) <- ST(1) - ST(0) and pop (Intel manual wrong)
}
void Assembler::ftan() {
! emit_byte(0xD9);
! emit_byte(0xF2);
! emit_byte(0xDD);
! emit_byte(0xD8);
}
void Assembler::ftst() {
! emit_byte(0xD9);
! emit_byte(0xE4);
}
void Assembler::fucomi(int i) {
// make sure the instruction is supported (introduced for P6, together with cmov)
guarantee(VM_Version::supports_cmov(), "illegal instruction");
--- 4070,4088 ----
void Assembler::fsubrp(int i) {
emit_farith(0xDE, 0xE0, i); // ST(0) <- ST(1) - ST(0) and pop (Intel manual wrong)
}
void Assembler::ftan() {
! emit_int8(0xD9);
! emit_int8(0xF2);
! emit_int8(0xDD);
! emit_int8(0xD8);
}
void Assembler::ftst() {
! emit_int8(0xD9);
! emit_int8(0xE4);
}
void Assembler::fucomi(int i) {
// make sure the instruction is supported (introduced for P6, together with cmov)
guarantee(VM_Version::supports_cmov(), "illegal instruction");
*** 4094,4165 ****
guarantee(VM_Version::supports_cmov(), "illegal instruction");
emit_farith(0xDF, 0xE8, i);
}
void Assembler::fwait() {
! emit_byte(0x9B);
}
void Assembler::fxch(int i) {
emit_farith(0xD9, 0xC8, i);
}
void Assembler::fyl2x() {
! emit_byte(0xD9);
! emit_byte(0xF1);
}
void Assembler::frndint() {
! emit_byte(0xD9);
! emit_byte(0xFC);
}
void Assembler::f2xm1() {
! emit_byte(0xD9);
! emit_byte(0xF0);
}
void Assembler::fldl2e() {
! emit_byte(0xD9);
! emit_byte(0xEA);
}
// SSE SIMD prefix byte values corresponding to VexSimdPrefix encoding.
static int simd_pre[4] = { 0, 0x66, 0xF3, 0xF2 };
// SSE opcode second byte values (first is 0x0F) corresponding to VexOpcode encoding.
static int simd_opc[4] = { 0, 0, 0x38, 0x3A };
// Generate SSE legacy REX prefix and SIMD opcode based on VEX encoding.
void Assembler::rex_prefix(Address adr, XMMRegister xreg, VexSimdPrefix pre, VexOpcode opc, bool rex_w) {
if (pre > 0) {
! emit_byte(simd_pre[pre]);
}
if (rex_w) {
prefixq(adr, xreg);
} else {
prefix(adr, xreg);
}
if (opc > 0) {
! emit_byte(0x0F);
int opc2 = simd_opc[opc];
if (opc2 > 0) {
! emit_byte(opc2);
}
}
}
int Assembler::rex_prefix_and_encode(int dst_enc, int src_enc, VexSimdPrefix pre, VexOpcode opc, bool rex_w) {
if (pre > 0) {
! emit_byte(simd_pre[pre]);
}
int encode = (rex_w) ? prefixq_and_encode(dst_enc, src_enc) :
prefix_and_encode(dst_enc, src_enc);
if (opc > 0) {
! emit_byte(0x0F);
int opc2 = simd_opc[opc];
if (opc2 > 0) {
! emit_byte(opc2);
}
}
return encode;
}
--- 4094,4165 ----
guarantee(VM_Version::supports_cmov(), "illegal instruction");
emit_farith(0xDF, 0xE8, i);
}
void Assembler::fwait() {
! emit_int8(0x9B);
}
void Assembler::fxch(int i) {
emit_farith(0xD9, 0xC8, i);
}
void Assembler::fyl2x() {
! emit_int8(0xD9);
! emit_int8(0xF1);
}
void Assembler::frndint() {
! emit_int8(0xD9);
! emit_int8(0xFC);
}
void Assembler::f2xm1() {
! emit_int8(0xD9);
! emit_int8(0xF0);
}
void Assembler::fldl2e() {
! emit_int8(0xD9);
! emit_int8(0xEA);
}
// SSE SIMD prefix byte values corresponding to VexSimdPrefix encoding.
static int simd_pre[4] = { 0, 0x66, 0xF3, 0xF2 };
// SSE opcode second byte values (first is 0x0F) corresponding to VexOpcode encoding.
static int simd_opc[4] = { 0, 0, 0x38, 0x3A };
// Generate SSE legacy REX prefix and SIMD opcode based on VEX encoding.
void Assembler::rex_prefix(Address adr, XMMRegister xreg, VexSimdPrefix pre, VexOpcode opc, bool rex_w) {
if (pre > 0) {
! emit_int8(simd_pre[pre]);
}
if (rex_w) {
prefixq(adr, xreg);
} else {
prefix(adr, xreg);
}
if (opc > 0) {
! emit_int8(0x0F);
int opc2 = simd_opc[opc];
if (opc2 > 0) {
! emit_int8(opc2);
}
}
}
int Assembler::rex_prefix_and_encode(int dst_enc, int src_enc, VexSimdPrefix pre, VexOpcode opc, bool rex_w) {
if (pre > 0) {
! emit_int8(simd_pre[pre]);
}
int encode = (rex_w) ? prefixq_and_encode(dst_enc, src_enc) :
prefix_and_encode(dst_enc, src_enc);
if (opc > 0) {
! emit_int8(0x0F);
int opc2 = simd_opc[opc];
if (opc2 > 0) {
! emit_int8(opc2);
}
}
return encode;
}
*** 4169,4191 ****
prefix(VEX_3bytes);
int byte1 = (vex_r ? VEX_R : 0) | (vex_x ? VEX_X : 0) | (vex_b ? VEX_B : 0);
byte1 = (~byte1) & 0xE0;
byte1 |= opc;
! a_byte(byte1);
int byte2 = ((~nds_enc) & 0xf) << 3;
byte2 |= (vex_w ? VEX_W : 0) | (vector256 ? 4 : 0) | pre;
! emit_byte(byte2);
} else {
prefix(VEX_2bytes);
int byte1 = vex_r ? VEX_R : 0;
byte1 = (~byte1) & 0x80;
byte1 |= ((~nds_enc) & 0xf) << 3;
byte1 |= (vector256 ? 4 : 0) | pre;
! emit_byte(byte1);
}
}
void Assembler::vex_prefix(Address adr, int nds_enc, int xreg_enc, VexSimdPrefix pre, VexOpcode opc, bool vex_w, bool vector256){
bool vex_r = (xreg_enc >= 8);
--- 4169,4191 ----
prefix(VEX_3bytes);
int byte1 = (vex_r ? VEX_R : 0) | (vex_x ? VEX_X : 0) | (vex_b ? VEX_B : 0);
byte1 = (~byte1) & 0xE0;
byte1 |= opc;
! emit_int8(byte1);
int byte2 = ((~nds_enc) & 0xf) << 3;
byte2 |= (vex_w ? VEX_W : 0) | (vector256 ? 4 : 0) | pre;
! emit_int8(byte2);
} else {
prefix(VEX_2bytes);
int byte1 = vex_r ? VEX_R : 0;
byte1 = (~byte1) & 0x80;
byte1 |= ((~nds_enc) & 0xf) << 3;
byte1 |= (vector256 ? 4 : 0) | pre;
! emit_int8(byte1);
}
}
void Assembler::vex_prefix(Address adr, int nds_enc, int xreg_enc, VexSimdPrefix pre, VexOpcode opc, bool vex_w, bool vector256){
bool vex_r = (xreg_enc >= 8);
*** 4227,4340 ****
}
void Assembler::emit_simd_arith(int opcode, XMMRegister dst, Address src, VexSimdPrefix pre) {
InstructionMark im(this);
simd_prefix(dst, dst, src, pre);
! emit_byte(opcode);
emit_operand(dst, src);
}
void Assembler::emit_simd_arith(int opcode, XMMRegister dst, XMMRegister src, VexSimdPrefix pre) {
int encode = simd_prefix_and_encode(dst, dst, src, pre);
! emit_byte(opcode);
! emit_byte(0xC0 | encode);
}
// Versions with no second source register (non-destructive source).
void Assembler::emit_simd_arith_nonds(int opcode, XMMRegister dst, Address src, VexSimdPrefix pre) {
InstructionMark im(this);
simd_prefix(dst, xnoreg, src, pre);
! emit_byte(opcode);
emit_operand(dst, src);
}
void Assembler::emit_simd_arith_nonds(int opcode, XMMRegister dst, XMMRegister src, VexSimdPrefix pre) {
int encode = simd_prefix_and_encode(dst, xnoreg, src, pre);
! emit_byte(opcode);
! emit_byte(0xC0 | encode);
}
// 3-operands AVX instructions
void Assembler::emit_vex_arith(int opcode, XMMRegister dst, XMMRegister nds,
Address src, VexSimdPrefix pre, bool vector256) {
InstructionMark im(this);
vex_prefix(dst, nds, src, pre, vector256);
! emit_byte(opcode);
emit_operand(dst, src);
}
void Assembler::emit_vex_arith(int opcode, XMMRegister dst, XMMRegister nds,
XMMRegister src, VexSimdPrefix pre, bool vector256) {
int encode = vex_prefix_and_encode(dst, nds, src, pre, vector256);
! emit_byte(opcode);
! emit_byte(0xC0 | encode);
}
#ifndef _LP64
void Assembler::incl(Register dst) {
// Don't use it directly. Use MacroAssembler::incrementl() instead.
! emit_byte(0x40 | dst->encoding());
}
void Assembler::lea(Register dst, Address src) {
leal(dst, src);
}
void Assembler::mov_literal32(Address dst, int32_t imm32, RelocationHolder const& rspec) {
InstructionMark im(this);
! emit_byte(0xC7);
emit_operand(rax, dst);
emit_data((int)imm32, rspec, 0);
}
void Assembler::mov_literal32(Register dst, int32_t imm32, RelocationHolder const& rspec) {
InstructionMark im(this);
int encode = prefix_and_encode(dst->encoding());
! emit_byte(0xB8 | encode);
emit_data((int)imm32, rspec, 0);
}
void Assembler::popa() { // 32bit
! emit_byte(0x61);
}
void Assembler::push_literal32(int32_t imm32, RelocationHolder const& rspec) {
InstructionMark im(this);
! emit_byte(0x68);
emit_data(imm32, rspec, 0);
}
void Assembler::pusha() { // 32bit
! emit_byte(0x60);
}
void Assembler::set_byte_if_not_zero(Register dst) {
! emit_byte(0x0F);
! emit_byte(0x95);
! emit_byte(0xE0 | dst->encoding());
}
void Assembler::shldl(Register dst, Register src) {
! emit_byte(0x0F);
! emit_byte(0xA5);
! emit_byte(0xC0 | src->encoding() << 3 | dst->encoding());
}
void Assembler::shrdl(Register dst, Register src) {
! emit_byte(0x0F);
! emit_byte(0xAD);
! emit_byte(0xC0 | src->encoding() << 3 | dst->encoding());
}
#else // LP64
void Assembler::set_byte_if_not_zero(Register dst) {
int enc = prefix_and_encode(dst->encoding(), true);
! emit_byte(0x0F);
! emit_byte(0x95);
! emit_byte(0xE0 | enc);
}
// 64bit only pieces of the assembler
// This should only be used by 64bit instructions that can use rip-relative
// it cannot be used by instructions that want an immediate value.
--- 4227,4340 ----
}
void Assembler::emit_simd_arith(int opcode, XMMRegister dst, Address src, VexSimdPrefix pre) {
InstructionMark im(this);
simd_prefix(dst, dst, src, pre);
! emit_int8(opcode);
emit_operand(dst, src);
}
void Assembler::emit_simd_arith(int opcode, XMMRegister dst, XMMRegister src, VexSimdPrefix pre) {
int encode = simd_prefix_and_encode(dst, dst, src, pre);
! emit_int8(opcode);
! emit_int8(0xC0 | encode);
}
// Versions with no second source register (non-destructive source).
void Assembler::emit_simd_arith_nonds(int opcode, XMMRegister dst, Address src, VexSimdPrefix pre) {
InstructionMark im(this);
simd_prefix(dst, xnoreg, src, pre);
! emit_int8(opcode);
emit_operand(dst, src);
}
void Assembler::emit_simd_arith_nonds(int opcode, XMMRegister dst, XMMRegister src, VexSimdPrefix pre) {
int encode = simd_prefix_and_encode(dst, xnoreg, src, pre);
! emit_int8(opcode);
! emit_int8(0xC0 | encode);
}
// 3-operands AVX instructions
void Assembler::emit_vex_arith(int opcode, XMMRegister dst, XMMRegister nds,
Address src, VexSimdPrefix pre, bool vector256) {
InstructionMark im(this);
vex_prefix(dst, nds, src, pre, vector256);
! emit_int8(opcode);
emit_operand(dst, src);
}
void Assembler::emit_vex_arith(int opcode, XMMRegister dst, XMMRegister nds,
XMMRegister src, VexSimdPrefix pre, bool vector256) {
int encode = vex_prefix_and_encode(dst, nds, src, pre, vector256);
! emit_int8(opcode);
! emit_int8(0xC0 | encode);
}
#ifndef _LP64
void Assembler::incl(Register dst) {
// Don't use it directly. Use MacroAssembler::incrementl() instead.
! emit_int8(0x40 | dst->encoding());
}
void Assembler::lea(Register dst, Address src) {
leal(dst, src);
}
void Assembler::mov_literal32(Address dst, int32_t imm32, RelocationHolder const& rspec) {
InstructionMark im(this);
! emit_int8(0xC7);
emit_operand(rax, dst);
emit_data((int)imm32, rspec, 0);
}
void Assembler::mov_literal32(Register dst, int32_t imm32, RelocationHolder const& rspec) {
InstructionMark im(this);
int encode = prefix_and_encode(dst->encoding());
! emit_int8(0xB8 | encode);
emit_data((int)imm32, rspec, 0);
}
void Assembler::popa() { // 32bit
! emit_int8(0x61);
}
void Assembler::push_literal32(int32_t imm32, RelocationHolder const& rspec) {
InstructionMark im(this);
! emit_int8(0x68);
emit_data(imm32, rspec, 0);
}
void Assembler::pusha() { // 32bit
! emit_int8(0x60);
}
void Assembler::set_byte_if_not_zero(Register dst) {
! emit_int8(0x0F);
! emit_int8(0x95);
! emit_int8(0xE0 | dst->encoding());
}
void Assembler::shldl(Register dst, Register src) {
! emit_int8(0x0F);
! emit_int8(0xA5);
! emit_int8(0xC0 | src->encoding() << 3 | dst->encoding());
}
void Assembler::shrdl(Register dst, Register src) {
! emit_int8(0x0F);
! emit_int8(0xAD);
! emit_int8(0xC0 | src->encoding() << 3 | dst->encoding());
}
#else // LP64
void Assembler::set_byte_if_not_zero(Register dst) {
int enc = prefix_and_encode(dst->encoding(), true);
! emit_int8(0x0F);
! emit_int8(0x95);
! emit_int8(0xE0 | enc);
}
// 64bit only pieces of the assembler
// This should only be used by 64bit instructions that can use rip-relative
// it cannot be used by instructions that want an immediate value.
*** 4668,4678 ****
}
void Assembler::adcq(Register dst, Address src) {
InstructionMark im(this);
prefixq(src, dst);
! emit_byte(0x13);
emit_operand(dst, src);
}
void Assembler::adcq(Register dst, Register src) {
(int) prefixq_and_encode(dst->encoding(), src->encoding());
--- 4668,4678 ----
}
void Assembler::adcq(Register dst, Address src) {
InstructionMark im(this);
prefixq(src, dst);
! emit_int8(0x13);
emit_operand(dst, src);
}
void Assembler::adcq(Register dst, Register src) {
(int) prefixq_and_encode(dst->encoding(), src->encoding());
*** 4686,4696 ****
}
void Assembler::addq(Address dst, Register src) {
InstructionMark im(this);
prefixq(dst, src);
! emit_byte(0x01);
emit_operand(src, dst);
}
void Assembler::addq(Register dst, int32_t imm32) {
(void) prefixq_and_encode(dst->encoding());
--- 4686,4696 ----
}
void Assembler::addq(Address dst, Register src) {
InstructionMark im(this);
prefixq(dst, src);
! emit_int8(0x01);
emit_operand(src, dst);
}
void Assembler::addq(Register dst, int32_t imm32) {
(void) prefixq_and_encode(dst->encoding());
*** 4698,4708 ****
}
void Assembler::addq(Register dst, Address src) {
InstructionMark im(this);
prefixq(src, dst);
! emit_byte(0x03);
emit_operand(dst, src);
}
void Assembler::addq(Register dst, Register src) {
(void) prefixq_and_encode(dst->encoding(), src->encoding());
--- 4698,4708 ----
}
void Assembler::addq(Register dst, Address src) {
InstructionMark im(this);
prefixq(src, dst);
! emit_int8(0x03);
emit_operand(dst, src);
}
void Assembler::addq(Register dst, Register src) {
(void) prefixq_and_encode(dst->encoding(), src->encoding());
*** 4710,4720 ****
}
void Assembler::andq(Address dst, int32_t imm32) {
InstructionMark im(this);
prefixq(dst);
! emit_byte(0x81);
emit_operand(rsp, dst, 4);
emit_long(imm32);
}
void Assembler::andq(Register dst, int32_t imm32) {
--- 4710,4720 ----
}
void Assembler::andq(Address dst, int32_t imm32) {
InstructionMark im(this);
prefixq(dst);
! emit_int8(0x81);
emit_operand(rsp, dst, 4);
emit_long(imm32);
}
void Assembler::andq(Register dst, int32_t imm32) {
*** 4723,4793 ****
}
void Assembler::andq(Register dst, Address src) {
InstructionMark im(this);
prefixq(src, dst);
! emit_byte(0x23);
emit_operand(dst, src);
}
void Assembler::andq(Register dst, Register src) {
(int) prefixq_and_encode(dst->encoding(), src->encoding());
emit_arith(0x23, 0xC0, dst, src);
}
void Assembler::bsfq(Register dst, Register src) {
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
! emit_byte(0x0F);
! emit_byte(0xBC);
! emit_byte(0xC0 | encode);
}
void Assembler::bsrq(Register dst, Register src) {
assert(!VM_Version::supports_lzcnt(), "encoding is treated as LZCNT");
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
! emit_byte(0x0F);
! emit_byte(0xBD);
! emit_byte(0xC0 | encode);
}
void Assembler::bswapq(Register reg) {
int encode = prefixq_and_encode(reg->encoding());
! emit_byte(0x0F);
! emit_byte(0xC8 | encode);
}
void Assembler::cdqq() {
prefix(REX_W);
! emit_byte(0x99);
}
void Assembler::clflush(Address adr) {
prefix(adr);
! emit_byte(0x0F);
! emit_byte(0xAE);
emit_operand(rdi, adr);
}
void Assembler::cmovq(Condition cc, Register dst, Register src) {
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
! emit_byte(0x0F);
! emit_byte(0x40 | cc);
! emit_byte(0xC0 | encode);
}
void Assembler::cmovq(Condition cc, Register dst, Address src) {
InstructionMark im(this);
prefixq(src, dst);
! emit_byte(0x0F);
! emit_byte(0x40 | cc);
emit_operand(dst, src);
}
void Assembler::cmpq(Address dst, int32_t imm32) {
InstructionMark im(this);
prefixq(dst);
! emit_byte(0x81);
emit_operand(rdi, dst, 4);
emit_long(imm32);
}
void Assembler::cmpq(Register dst, int32_t imm32) {
--- 4723,4793 ----
}
void Assembler::andq(Register dst, Address src) {
InstructionMark im(this);
prefixq(src, dst);
! emit_int8(0x23);
emit_operand(dst, src);
}
void Assembler::andq(Register dst, Register src) {
(int) prefixq_and_encode(dst->encoding(), src->encoding());
emit_arith(0x23, 0xC0, dst, src);
}
void Assembler::bsfq(Register dst, Register src) {
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
! emit_int8(0x0F);
! emit_int8(0xBC);
! emit_int8(0xC0 | encode);
}
void Assembler::bsrq(Register dst, Register src) {
assert(!VM_Version::supports_lzcnt(), "encoding is treated as LZCNT");
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
! emit_int8(0x0F);
! emit_int8(0xBD);
! emit_int8(0xC0 | encode);
}
void Assembler::bswapq(Register reg) {
int encode = prefixq_and_encode(reg->encoding());
! emit_int8(0x0F);
! emit_int8(0xC8 | encode);
}
void Assembler::cdqq() {
prefix(REX_W);
! emit_int8(0x99);
}
void Assembler::clflush(Address adr) {
prefix(adr);
! emit_int8(0x0F);
! emit_int8(0xAE);
emit_operand(rdi, adr);
}
void Assembler::cmovq(Condition cc, Register dst, Register src) {
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
! emit_int8(0x0F);
! emit_int8(0x40 | cc);
! emit_int8(0xC0 | encode);
}
void Assembler::cmovq(Condition cc, Register dst, Address src) {
InstructionMark im(this);
prefixq(src, dst);
! emit_int8(0x0F);
! emit_int8(0x40 | cc);
emit_operand(dst, src);
}
void Assembler::cmpq(Address dst, int32_t imm32) {
InstructionMark im(this);
prefixq(dst);
! emit_int8(0x81);
emit_operand(rdi, dst, 4);
emit_long(imm32);
}
void Assembler::cmpq(Register dst, int32_t imm32) {
*** 4796,4806 ****
}
void Assembler::cmpq(Address dst, Register src) {
InstructionMark im(this);
prefixq(dst, src);
! emit_byte(0x3B);
emit_operand(src, dst);
}
void Assembler::cmpq(Register dst, Register src) {
(void) prefixq_and_encode(dst->encoding(), src->encoding());
--- 4796,4806 ----
}
void Assembler::cmpq(Address dst, Register src) {
InstructionMark im(this);
prefixq(dst, src);
! emit_int8(0x3B);
emit_operand(src, dst);
}
void Assembler::cmpq(Register dst, Register src) {
(void) prefixq_and_encode(dst->encoding(), src->encoding());
*** 4808,5172 ****
}
void Assembler::cmpq(Register dst, Address src) {
InstructionMark im(this);
prefixq(src, dst);
! emit_byte(0x3B);
emit_operand(dst, src);
}
void Assembler::cmpxchgq(Register reg, Address adr) {
InstructionMark im(this);
prefixq(adr, reg);
! emit_byte(0x0F);
! emit_byte(0xB1);
emit_operand(reg, adr);
}
void Assembler::cvtsi2sdq(XMMRegister dst, Register src) {
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
int encode = simd_prefix_and_encode_q(dst, dst, src, VEX_SIMD_F2);
! emit_byte(0x2A);
! emit_byte(0xC0 | encode);
}
void Assembler::cvtsi2sdq(XMMRegister dst, Address src) {
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
InstructionMark im(this);
simd_prefix_q(dst, dst, src, VEX_SIMD_F2);
! emit_byte(0x2A);
emit_operand(dst, src);
}
void Assembler::cvtsi2ssq(XMMRegister dst, Register src) {
NOT_LP64(assert(VM_Version::supports_sse(), ""));
int encode = simd_prefix_and_encode_q(dst, dst, src, VEX_SIMD_F3);
! emit_byte(0x2A);
! emit_byte(0xC0 | encode);
}
void Assembler::cvtsi2ssq(XMMRegister dst, Address src) {
NOT_LP64(assert(VM_Version::supports_sse(), ""));
InstructionMark im(this);
simd_prefix_q(dst, dst, src, VEX_SIMD_F3);
! emit_byte(0x2A);
emit_operand(dst, src);
}
void Assembler::cvttsd2siq(Register dst, XMMRegister src) {
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
int encode = simd_prefix_and_encode_q(dst, src, VEX_SIMD_F2);
! emit_byte(0x2C);
! emit_byte(0xC0 | encode);
}
void Assembler::cvttss2siq(Register dst, XMMRegister src) {
NOT_LP64(assert(VM_Version::supports_sse(), ""));
int encode = simd_prefix_and_encode_q(dst, src, VEX_SIMD_F3);
! emit_byte(0x2C);
! emit_byte(0xC0 | encode);
}
void Assembler::decl(Register dst) {
// Don't use it directly. Use MacroAssembler::decrementl() instead.
// Use two-byte form (one-byte form is a REX prefix in 64-bit mode)
int encode = prefix_and_encode(dst->encoding());
! emit_byte(0xFF);
! emit_byte(0xC8 | encode);
}
void Assembler::decq(Register dst) {
// Don't use it directly. Use MacroAssembler::decrementq() instead.
// Use two-byte form (one-byte from is a REX prefix in 64-bit mode)
int encode = prefixq_and_encode(dst->encoding());
! emit_byte(0xFF);
! emit_byte(0xC8 | encode);
}
void Assembler::decq(Address dst) {
// Don't use it directly. Use MacroAssembler::decrementq() instead.
InstructionMark im(this);
prefixq(dst);
! emit_byte(0xFF);
emit_operand(rcx, dst);
}
void Assembler::fxrstor(Address src) {
prefixq(src);
! emit_byte(0x0F);
! emit_byte(0xAE);
emit_operand(as_Register(1), src);
}
void Assembler::fxsave(Address dst) {
prefixq(dst);
! emit_byte(0x0F);
! emit_byte(0xAE);
emit_operand(as_Register(0), dst);
}
void Assembler::idivq(Register src) {
int encode = prefixq_and_encode(src->encoding());
! emit_byte(0xF7);
! emit_byte(0xF8 | encode);
}
void Assembler::imulq(Register dst, Register src) {
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
! emit_byte(0x0F);
! emit_byte(0xAF);
! emit_byte(0xC0 | encode);
}
void Assembler::imulq(Register dst, Register src, int value) {
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
if (is8bit(value)) {
! emit_byte(0x6B);
! emit_byte(0xC0 | encode);
! emit_byte(value & 0xFF);
} else {
! emit_byte(0x69);
! emit_byte(0xC0 | encode);
emit_long(value);
}
}
void Assembler::incl(Register dst) {
// Don't use it directly. Use MacroAssembler::incrementl() instead.
// Use two-byte form (one-byte from is a REX prefix in 64-bit mode)
int encode = prefix_and_encode(dst->encoding());
! emit_byte(0xFF);
! emit_byte(0xC0 | encode);
}
void Assembler::incq(Register dst) {
// Don't use it directly. Use MacroAssembler::incrementq() instead.
// Use two-byte form (one-byte from is a REX prefix in 64-bit mode)
int encode = prefixq_and_encode(dst->encoding());
! emit_byte(0xFF);
! emit_byte(0xC0 | encode);
}
void Assembler::incq(Address dst) {
// Don't use it directly. Use MacroAssembler::incrementq() instead.
InstructionMark im(this);
prefixq(dst);
! emit_byte(0xFF);
emit_operand(rax, dst);
}
void Assembler::lea(Register dst, Address src) {
leaq(dst, src);
}
void Assembler::leaq(Register dst, Address src) {
InstructionMark im(this);
prefixq(src, dst);
! emit_byte(0x8D);
emit_operand(dst, src);
}
void Assembler::mov64(Register dst, int64_t imm64) {
InstructionMark im(this);
int encode = prefixq_and_encode(dst->encoding());
! emit_byte(0xB8 | encode);
emit_int64(imm64);
}
void Assembler::mov_literal64(Register dst, intptr_t imm64, RelocationHolder const& rspec) {
InstructionMark im(this);
int encode = prefixq_and_encode(dst->encoding());
! emit_byte(0xB8 | encode);
emit_data64(imm64, rspec);
}
void Assembler::mov_narrow_oop(Register dst, int32_t imm32, RelocationHolder const& rspec) {
InstructionMark im(this);
int encode = prefix_and_encode(dst->encoding());
! emit_byte(0xB8 | encode);
emit_data((int)imm32, rspec, narrow_oop_operand);
}
void Assembler::mov_narrow_oop(Address dst, int32_t imm32, RelocationHolder const& rspec) {
InstructionMark im(this);
prefix(dst);
! emit_byte(0xC7);
emit_operand(rax, dst, 4);
emit_data((int)imm32, rspec, narrow_oop_operand);
}
void Assembler::cmp_narrow_oop(Register src1, int32_t imm32, RelocationHolder const& rspec) {
InstructionMark im(this);
int encode = prefix_and_encode(src1->encoding());
! emit_byte(0x81);
! emit_byte(0xF8 | encode);
emit_data((int)imm32, rspec, narrow_oop_operand);
}
void Assembler::cmp_narrow_oop(Address src1, int32_t imm32, RelocationHolder const& rspec) {
InstructionMark im(this);
prefix(src1);
! emit_byte(0x81);
emit_operand(rax, src1, 4);
emit_data((int)imm32, rspec, narrow_oop_operand);
}
void Assembler::lzcntq(Register dst, Register src) {
assert(VM_Version::supports_lzcnt(), "encoding is treated as BSR");
! emit_byte(0xF3);
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
! emit_byte(0x0F);
! emit_byte(0xBD);
! emit_byte(0xC0 | encode);
}
void Assembler::movdq(XMMRegister dst, Register src) {
// table D-1 says MMX/SSE2
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
int encode = simd_prefix_and_encode_q(dst, src, VEX_SIMD_66);
! emit_byte(0x6E);
! emit_byte(0xC0 | encode);
}
void Assembler::movdq(Register dst, XMMRegister src) {
// table D-1 says MMX/SSE2
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
// swap src/dst to get correct prefix
int encode = simd_prefix_and_encode_q(src, dst, VEX_SIMD_66);
! emit_byte(0x7E);
! emit_byte(0xC0 | encode);
}
void Assembler::movq(Register dst, Register src) {
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
! emit_byte(0x8B);
! emit_byte(0xC0 | encode);
}
void Assembler::movq(Register dst, Address src) {
InstructionMark im(this);
prefixq(src, dst);
! emit_byte(0x8B);
emit_operand(dst, src);
}
void Assembler::movq(Address dst, Register src) {
InstructionMark im(this);
prefixq(dst, src);
! emit_byte(0x89);
emit_operand(src, dst);
}
void Assembler::movsbq(Register dst, Address src) {
InstructionMark im(this);
prefixq(src, dst);
! emit_byte(0x0F);
! emit_byte(0xBE);
emit_operand(dst, src);
}
void Assembler::movsbq(Register dst, Register src) {
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
! emit_byte(0x0F);
! emit_byte(0xBE);
! emit_byte(0xC0 | encode);
}
void Assembler::movslq(Register dst, int32_t imm32) {
// dbx shows movslq(rcx, 3) as movq $0x0000000049000000,(%rbx)
// and movslq(r8, 3); as movl $0x0000000048000000,(%rbx)
// as a result we shouldn't use until tested at runtime...
ShouldNotReachHere();
InstructionMark im(this);
int encode = prefixq_and_encode(dst->encoding());
! emit_byte(0xC7 | encode);
emit_long(imm32);
}
void Assembler::movslq(Address dst, int32_t imm32) {
assert(is_simm32(imm32), "lost bits");
InstructionMark im(this);
prefixq(dst);
! emit_byte(0xC7);
emit_operand(rax, dst, 4);
emit_long(imm32);
}
void Assembler::movslq(Register dst, Address src) {
InstructionMark im(this);
prefixq(src, dst);
! emit_byte(0x63);
emit_operand(dst, src);
}
void Assembler::movslq(Register dst, Register src) {
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
! emit_byte(0x63);
! emit_byte(0xC0 | encode);
}
void Assembler::movswq(Register dst, Address src) {
InstructionMark im(this);
prefixq(src, dst);
! emit_byte(0x0F);
! emit_byte(0xBF);
emit_operand(dst, src);
}
void Assembler::movswq(Register dst, Register src) {
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
! emit_byte(0x0F);
! emit_byte(0xBF);
! emit_byte(0xC0 | encode);
}
void Assembler::movzbq(Register dst, Address src) {
InstructionMark im(this);
prefixq(src, dst);
! emit_byte(0x0F);
! emit_byte(0xB6);
emit_operand(dst, src);
}
void Assembler::movzbq(Register dst, Register src) {
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
! emit_byte(0x0F);
! emit_byte(0xB6);
! emit_byte(0xC0 | encode);
}
void Assembler::movzwq(Register dst, Address src) {
InstructionMark im(this);
prefixq(src, dst);
! emit_byte(0x0F);
! emit_byte(0xB7);
emit_operand(dst, src);
}
void Assembler::movzwq(Register dst, Register src) {
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
! emit_byte(0x0F);
! emit_byte(0xB7);
! emit_byte(0xC0 | encode);
}
void Assembler::negq(Register dst) {
int encode = prefixq_and_encode(dst->encoding());
! emit_byte(0xF7);
! emit_byte(0xD8 | encode);
}
void Assembler::notq(Register dst) {
int encode = prefixq_and_encode(dst->encoding());
! emit_byte(0xF7);
! emit_byte(0xD0 | encode);
}
void Assembler::orq(Address dst, int32_t imm32) {
InstructionMark im(this);
prefixq(dst);
! emit_byte(0x81);
emit_operand(rcx, dst, 4);
emit_long(imm32);
}
void Assembler::orq(Register dst, int32_t imm32) {
--- 4808,5172 ----
}
void Assembler::cmpq(Register dst, Address src) {
InstructionMark im(this);
prefixq(src, dst);
! emit_int8(0x3B);
emit_operand(dst, src);
}
void Assembler::cmpxchgq(Register reg, Address adr) {
InstructionMark im(this);
prefixq(adr, reg);
! emit_int8(0x0F);
! emit_int8(0xB1);
emit_operand(reg, adr);
}
void Assembler::cvtsi2sdq(XMMRegister dst, Register src) {
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
int encode = simd_prefix_and_encode_q(dst, dst, src, VEX_SIMD_F2);
! emit_int8(0x2A);
! emit_int8(0xC0 | encode);
}
void Assembler::cvtsi2sdq(XMMRegister dst, Address src) {
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
InstructionMark im(this);
simd_prefix_q(dst, dst, src, VEX_SIMD_F2);
! emit_int8(0x2A);
emit_operand(dst, src);
}
void Assembler::cvtsi2ssq(XMMRegister dst, Register src) {
NOT_LP64(assert(VM_Version::supports_sse(), ""));
int encode = simd_prefix_and_encode_q(dst, dst, src, VEX_SIMD_F3);
! emit_int8(0x2A);
! emit_int8(0xC0 | encode);
}
void Assembler::cvtsi2ssq(XMMRegister dst, Address src) {
NOT_LP64(assert(VM_Version::supports_sse(), ""));
InstructionMark im(this);
simd_prefix_q(dst, dst, src, VEX_SIMD_F3);
! emit_int8(0x2A);
emit_operand(dst, src);
}
void Assembler::cvttsd2siq(Register dst, XMMRegister src) {
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
int encode = simd_prefix_and_encode_q(dst, src, VEX_SIMD_F2);
! emit_int8(0x2C);
! emit_int8(0xC0 | encode);
}
void Assembler::cvttss2siq(Register dst, XMMRegister src) {
NOT_LP64(assert(VM_Version::supports_sse(), ""));
int encode = simd_prefix_and_encode_q(dst, src, VEX_SIMD_F3);
! emit_int8(0x2C);
! emit_int8(0xC0 | encode);
}
void Assembler::decl(Register dst) {
// Don't use it directly. Use MacroAssembler::decrementl() instead.
// Use two-byte form (one-byte form is a REX prefix in 64-bit mode)
int encode = prefix_and_encode(dst->encoding());
! emit_int8(0xFF);
! emit_int8(0xC8 | encode);
}
void Assembler::decq(Register dst) {
// Don't use it directly. Use MacroAssembler::decrementq() instead.
// Use two-byte form (one-byte from is a REX prefix in 64-bit mode)
int encode = prefixq_and_encode(dst->encoding());
! emit_int8(0xFF);
! emit_int8(0xC8 | encode);
}
void Assembler::decq(Address dst) {
// Don't use it directly. Use MacroAssembler::decrementq() instead.
InstructionMark im(this);
prefixq(dst);
! emit_int8(0xFF);
emit_operand(rcx, dst);
}
void Assembler::fxrstor(Address src) {
prefixq(src);
! emit_int8(0x0F);
! emit_int8(0xAE);
emit_operand(as_Register(1), src);
}
void Assembler::fxsave(Address dst) {
prefixq(dst);
! emit_int8(0x0F);
! emit_int8(0xAE);
emit_operand(as_Register(0), dst);
}
void Assembler::idivq(Register src) {
int encode = prefixq_and_encode(src->encoding());
! emit_int8(0xF7);
! emit_int8(0xF8 | encode);
}
void Assembler::imulq(Register dst, Register src) {
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
! emit_int8(0x0F);
! emit_int8(0xAF);
! emit_int8(0xC0 | encode);
}
void Assembler::imulq(Register dst, Register src, int value) {
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
if (is8bit(value)) {
! emit_int8(0x6B);
! emit_int8(0xC0 | encode);
! emit_int8(value & 0xFF);
} else {
! emit_int8(0x69);
! emit_int8(0xC0 | encode);
emit_long(value);
}
}
void Assembler::incl(Register dst) {
// Don't use it directly. Use MacroAssembler::incrementl() instead.
// Use two-byte form (one-byte from is a REX prefix in 64-bit mode)
int encode = prefix_and_encode(dst->encoding());
! emit_int8(0xFF);
! emit_int8(0xC0 | encode);
}
void Assembler::incq(Register dst) {
// Don't use it directly. Use MacroAssembler::incrementq() instead.
// Use two-byte form (one-byte from is a REX prefix in 64-bit mode)
int encode = prefixq_and_encode(dst->encoding());
! emit_int8(0xFF);
! emit_int8(0xC0 | encode);
}
void Assembler::incq(Address dst) {
// Don't use it directly. Use MacroAssembler::incrementq() instead.
InstructionMark im(this);
prefixq(dst);
! emit_int8(0xFF);
emit_operand(rax, dst);
}
void Assembler::lea(Register dst, Address src) {
leaq(dst, src);
}
void Assembler::leaq(Register dst, Address src) {
InstructionMark im(this);
prefixq(src, dst);
! emit_int8(0x8D);
emit_operand(dst, src);
}
void Assembler::mov64(Register dst, int64_t imm64) {
InstructionMark im(this);
int encode = prefixq_and_encode(dst->encoding());
! emit_int8(0xB8 | encode);
emit_int64(imm64);
}
void Assembler::mov_literal64(Register dst, intptr_t imm64, RelocationHolder const& rspec) {
InstructionMark im(this);
int encode = prefixq_and_encode(dst->encoding());
! emit_int8(0xB8 | encode);
emit_data64(imm64, rspec);
}
void Assembler::mov_narrow_oop(Register dst, int32_t imm32, RelocationHolder const& rspec) {
InstructionMark im(this);
int encode = prefix_and_encode(dst->encoding());
! emit_int8(0xB8 | encode);
emit_data((int)imm32, rspec, narrow_oop_operand);
}
void Assembler::mov_narrow_oop(Address dst, int32_t imm32, RelocationHolder const& rspec) {
InstructionMark im(this);
prefix(dst);
! emit_int8(0xC7);
emit_operand(rax, dst, 4);
emit_data((int)imm32, rspec, narrow_oop_operand);
}
void Assembler::cmp_narrow_oop(Register src1, int32_t imm32, RelocationHolder const& rspec) {
InstructionMark im(this);
int encode = prefix_and_encode(src1->encoding());
! emit_int8(0x81);
! emit_int8(0xF8 | encode);
emit_data((int)imm32, rspec, narrow_oop_operand);
}
void Assembler::cmp_narrow_oop(Address src1, int32_t imm32, RelocationHolder const& rspec) {
InstructionMark im(this);
prefix(src1);
! emit_int8(0x81);
emit_operand(rax, src1, 4);
emit_data((int)imm32, rspec, narrow_oop_operand);
}
void Assembler::lzcntq(Register dst, Register src) {
assert(VM_Version::supports_lzcnt(), "encoding is treated as BSR");
! emit_int8(0xF3);
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
! emit_int8(0x0F);
! emit_int8(0xBD);
! emit_int8(0xC0 | encode);
}
void Assembler::movdq(XMMRegister dst, Register src) {
// table D-1 says MMX/SSE2
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
int encode = simd_prefix_and_encode_q(dst, src, VEX_SIMD_66);
! emit_int8(0x6E);
! emit_int8(0xC0 | encode);
}
void Assembler::movdq(Register dst, XMMRegister src) {
// table D-1 says MMX/SSE2
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
// swap src/dst to get correct prefix
int encode = simd_prefix_and_encode_q(src, dst, VEX_SIMD_66);
! emit_int8(0x7E);
! emit_int8(0xC0 | encode);
}
void Assembler::movq(Register dst, Register src) {
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
! emit_int8(0x8B);
! emit_int8(0xC0 | encode);
}
void Assembler::movq(Register dst, Address src) {
InstructionMark im(this);
prefixq(src, dst);
! emit_int8(0x8B);
emit_operand(dst, src);
}
void Assembler::movq(Address dst, Register src) {
InstructionMark im(this);
prefixq(dst, src);
! emit_int8(0x89);
emit_operand(src, dst);
}
void Assembler::movsbq(Register dst, Address src) {
InstructionMark im(this);
prefixq(src, dst);
! emit_int8(0x0F);
! emit_int8(0xBE);
emit_operand(dst, src);
}
void Assembler::movsbq(Register dst, Register src) {
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
! emit_int8(0x0F);
! emit_int8(0xBE);
! emit_int8(0xC0 | encode);
}
void Assembler::movslq(Register dst, int32_t imm32) {
// dbx shows movslq(rcx, 3) as movq $0x0000000049000000,(%rbx)
// and movslq(r8, 3); as movl $0x0000000048000000,(%rbx)
// as a result we shouldn't use until tested at runtime...
ShouldNotReachHere();
InstructionMark im(this);
int encode = prefixq_and_encode(dst->encoding());
! emit_int8(0xC7 | encode);
emit_long(imm32);
}
void Assembler::movslq(Address dst, int32_t imm32) {
assert(is_simm32(imm32), "lost bits");
InstructionMark im(this);
prefixq(dst);
! emit_int8(0xC7);
emit_operand(rax, dst, 4);
emit_long(imm32);
}
void Assembler::movslq(Register dst, Address src) {
InstructionMark im(this);
prefixq(src, dst);
! emit_int8(0x63);
emit_operand(dst, src);
}
void Assembler::movslq(Register dst, Register src) {
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
! emit_int8(0x63);
! emit_int8(0xC0 | encode);
}
void Assembler::movswq(Register dst, Address src) {
InstructionMark im(this);
prefixq(src, dst);
! emit_int8(0x0F);
! emit_int8(0xBF);
emit_operand(dst, src);
}
void Assembler::movswq(Register dst, Register src) {
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
! emit_int8(0x0F);
! emit_int8(0xBF);
! emit_int8(0xC0 | encode);
}
void Assembler::movzbq(Register dst, Address src) {
InstructionMark im(this);
prefixq(src, dst);
! emit_int8(0x0F);
! emit_int8(0xB6);
emit_operand(dst, src);
}
void Assembler::movzbq(Register dst, Register src) {
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
! emit_int8(0x0F);
! emit_int8(0xB6);
! emit_int8(0xC0 | encode);
}
void Assembler::movzwq(Register dst, Address src) {
InstructionMark im(this);
prefixq(src, dst);
! emit_int8(0x0F);
! emit_int8(0xB7);
emit_operand(dst, src);
}
void Assembler::movzwq(Register dst, Register src) {
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
! emit_int8(0x0F);
! emit_int8(0xB7);
! emit_int8(0xC0 | encode);
}
void Assembler::negq(Register dst) {
int encode = prefixq_and_encode(dst->encoding());
! emit_int8(0xF7);
! emit_int8(0xD8 | encode);
}
void Assembler::notq(Register dst) {
int encode = prefixq_and_encode(dst->encoding());
! emit_int8(0xF7);
! emit_int8(0xD0 | encode);
}
void Assembler::orq(Address dst, int32_t imm32) {
InstructionMark im(this);
prefixq(dst);
! emit_int8(0x81);
emit_operand(rcx, dst, 4);
emit_long(imm32);
}
void Assembler::orq(Register dst, int32_t imm32) {
*** 5175,5185 ****
}
void Assembler::orq(Register dst, Address src) {
InstructionMark im(this);
prefixq(src, dst);
! emit_byte(0x0B);
emit_operand(dst, src);
}
void Assembler::orq(Register dst, Register src) {
(void) prefixq_and_encode(dst->encoding(), src->encoding());
--- 5175,5185 ----
}
void Assembler::orq(Register dst, Address src) {
InstructionMark im(this);
prefixq(src, dst);
! emit_int8(0x0B);
emit_operand(dst, src);
}
void Assembler::orq(Register dst, Register src) {
(void) prefixq_and_encode(dst->encoding(), src->encoding());
*** 5208,5237 ****
}
void Assembler::popcntq(Register dst, Address src) {
assert(VM_Version::supports_popcnt(), "must support");
InstructionMark im(this);
! emit_byte(0xF3);
prefixq(src, dst);
! emit_byte(0x0F);
! emit_byte(0xB8);
emit_operand(dst, src);
}
void Assembler::popcntq(Register dst, Register src) {
assert(VM_Version::supports_popcnt(), "must support");
! emit_byte(0xF3);
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
! emit_byte(0x0F);
! emit_byte(0xB8);
! emit_byte(0xC0 | encode);
}
void Assembler::popq(Address dst) {
InstructionMark im(this);
prefixq(dst);
! emit_byte(0x8F);
emit_operand(rax, dst);
}
void Assembler::pusha() { // 64bit
// we have to store original rsp. ABI says that 128 bytes
--- 5208,5237 ----
}
void Assembler::popcntq(Register dst, Address src) {
assert(VM_Version::supports_popcnt(), "must support");
InstructionMark im(this);
! emit_int8(0xF3);
prefixq(src, dst);
! emit_int8(0x0F);
! emit_int8(0xB8);
emit_operand(dst, src);
}
void Assembler::popcntq(Register dst, Register src) {
assert(VM_Version::supports_popcnt(), "must support");
! emit_int8(0xF3);
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
! emit_int8(0x0F);
! emit_int8(0xB8);
! emit_int8(0xC0 | encode);
}
void Assembler::popq(Address dst) {
InstructionMark im(this);
prefixq(dst);
! emit_int8(0x8F);
emit_operand(rax, dst);
}
void Assembler::pusha() { // 64bit
// we have to store original rsp. ABI says that 128 bytes
*** 5259,5301 ****
}
void Assembler::pushq(Address src) {
InstructionMark im(this);
prefixq(src);
! emit_byte(0xFF);
emit_operand(rsi, src);
}
void Assembler::rclq(Register dst, int imm8) {
assert(isShiftCount(imm8 >> 1), "illegal shift count");
int encode = prefixq_and_encode(dst->encoding());
if (imm8 == 1) {
! emit_byte(0xD1);
! emit_byte(0xD0 | encode);
} else {
! emit_byte(0xC1);
! emit_byte(0xD0 | encode);
! emit_byte(imm8);
}
}
void Assembler::sarq(Register dst, int imm8) {
assert(isShiftCount(imm8 >> 1), "illegal shift count");
int encode = prefixq_and_encode(dst->encoding());
if (imm8 == 1) {
! emit_byte(0xD1);
! emit_byte(0xF8 | encode);
} else {
! emit_byte(0xC1);
! emit_byte(0xF8 | encode);
! emit_byte(imm8);
}
}
void Assembler::sarq(Register dst) {
int encode = prefixq_and_encode(dst->encoding());
! emit_byte(0xD3);
! emit_byte(0xF8 | encode);
}
void Assembler::sbbq(Address dst, int32_t imm32) {
InstructionMark im(this);
prefixq(dst);
--- 5259,5301 ----
}
void Assembler::pushq(Address src) {
InstructionMark im(this);
prefixq(src);
! emit_int8(0xFF);
emit_operand(rsi, src);
}
void Assembler::rclq(Register dst, int imm8) {
assert(isShiftCount(imm8 >> 1), "illegal shift count");
int encode = prefixq_and_encode(dst->encoding());
if (imm8 == 1) {
! emit_int8(0xD1);
! emit_int8(0xD0 | encode);
} else {
! emit_int8(0xC1);
! emit_int8(0xD0 | encode);
! emit_int8(imm8);
}
}
void Assembler::sarq(Register dst, int imm8) {
assert(isShiftCount(imm8 >> 1), "illegal shift count");
int encode = prefixq_and_encode(dst->encoding());
if (imm8 == 1) {
! emit_int8(0xD1);
! emit_int8(0xF8 | encode);
} else {
! emit_int8(0xC1);
! emit_int8(0xF8 | encode);
! emit_int8(imm8);
}
}
void Assembler::sarq(Register dst) {
int encode = prefixq_and_encode(dst->encoding());
! emit_int8(0xD3);
! emit_int8(0xF8 | encode);
}
void Assembler::sbbq(Address dst, int32_t imm32) {
InstructionMark im(this);
prefixq(dst);
*** 5308,5318 ****
}
void Assembler::sbbq(Register dst, Address src) {
InstructionMark im(this);
prefixq(src, dst);
! emit_byte(0x1B);
emit_operand(dst, src);
}
void Assembler::sbbq(Register dst, Register src) {
(void) prefixq_and_encode(dst->encoding(), src->encoding());
--- 5308,5318 ----
}
void Assembler::sbbq(Register dst, Address src) {
InstructionMark im(this);
prefixq(src, dst);
! emit_int8(0x1B);
emit_operand(dst, src);
}
void Assembler::sbbq(Register dst, Register src) {
(void) prefixq_and_encode(dst->encoding(), src->encoding());
*** 5321,5357 ****
void Assembler::shlq(Register dst, int imm8) {
assert(isShiftCount(imm8 >> 1), "illegal shift count");
int encode = prefixq_and_encode(dst->encoding());
if (imm8 == 1) {
! emit_byte(0xD1);
! emit_byte(0xE0 | encode);
} else {
! emit_byte(0xC1);
! emit_byte(0xE0 | encode);
! emit_byte(imm8);
}
}
void Assembler::shlq(Register dst) {
int encode = prefixq_and_encode(dst->encoding());
! emit_byte(0xD3);
! emit_byte(0xE0 | encode);
}
void Assembler::shrq(Register dst, int imm8) {
assert(isShiftCount(imm8 >> 1), "illegal shift count");
int encode = prefixq_and_encode(dst->encoding());
! emit_byte(0xC1);
! emit_byte(0xE8 | encode);
! emit_byte(imm8);
}
void Assembler::shrq(Register dst) {
int encode = prefixq_and_encode(dst->encoding());
! emit_byte(0xD3);
! emit_byte(0xE8 | encode);
}
void Assembler::subq(Address dst, int32_t imm32) {
InstructionMark im(this);
prefixq(dst);
--- 5321,5357 ----
void Assembler::shlq(Register dst, int imm8) {
assert(isShiftCount(imm8 >> 1), "illegal shift count");
int encode = prefixq_and_encode(dst->encoding());
if (imm8 == 1) {
! emit_int8(0xD1);
! emit_int8(0xE0 | encode);
} else {
! emit_int8(0xC1);
! emit_int8(0xE0 | encode);
! emit_int8(imm8);
}
}
void Assembler::shlq(Register dst) {
int encode = prefixq_and_encode(dst->encoding());
! emit_int8(0xD3);
! emit_int8(0xE0 | encode);
}
void Assembler::shrq(Register dst, int imm8) {
assert(isShiftCount(imm8 >> 1), "illegal shift count");
int encode = prefixq_and_encode(dst->encoding());
! emit_int8(0xC1);
! emit_int8(0xE8 | encode);
! emit_int8(imm8);
}
void Assembler::shrq(Register dst) {
int encode = prefixq_and_encode(dst->encoding());
! emit_int8(0xD3);
! emit_int8(0xE8 | encode);
}
void Assembler::subq(Address dst, int32_t imm32) {
InstructionMark im(this);
prefixq(dst);
*** 5359,5369 ****
}
void Assembler::subq(Address dst, Register src) {
InstructionMark im(this);
prefixq(dst, src);
! emit_byte(0x29);
emit_operand(src, dst);
}
void Assembler::subq(Register dst, int32_t imm32) {
(void) prefixq_and_encode(dst->encoding());
--- 5359,5369 ----
}
void Assembler::subq(Address dst, Register src) {
InstructionMark im(this);
prefixq(dst, src);
! emit_int8(0x29);
emit_operand(src, dst);
}
void Assembler::subq(Register dst, int32_t imm32) {
(void) prefixq_and_encode(dst->encoding());
*** 5377,5387 ****
}
void Assembler::subq(Register dst, Address src) {
InstructionMark im(this);
prefixq(src, dst);
! emit_byte(0x2B);
emit_operand(dst, src);
}
void Assembler::subq(Register dst, Register src) {
(void) prefixq_and_encode(dst->encoding(), src->encoding());
--- 5377,5387 ----
}
void Assembler::subq(Register dst, Address src) {
InstructionMark im(this);
prefixq(src, dst);
! emit_int8(0x2B);
emit_operand(dst, src);
}
void Assembler::subq(Register dst, Register src) {
(void) prefixq_and_encode(dst->encoding(), src->encoding());
*** 5393,5407 ****
// doesn't support sign-extension of
// 8bit operands
int encode = dst->encoding();
if (encode == 0) {
prefix(REX_W);
! emit_byte(0xA9);
} else {
encode = prefixq_and_encode(encode);
! emit_byte(0xF7);
! emit_byte(0xC0 | encode);
}
emit_long(imm32);
}
void Assembler::testq(Register dst, Register src) {
--- 5393,5407 ----
// doesn't support sign-extension of
// 8bit operands
int encode = dst->encoding();
if (encode == 0) {
prefix(REX_W);
! emit_int8(0xA9);
} else {
encode = prefixq_and_encode(encode);
! emit_int8(0xF7);
! emit_int8(0xC0 | encode);
}
emit_long(imm32);
}
void Assembler::testq(Register dst, Register src) {
*** 5410,5445 ****
}
void Assembler::xaddq(Address dst, Register src) {
InstructionMark im(this);
prefixq(dst, src);
! emit_byte(0x0F);
! emit_byte(0xC1);
emit_operand(src, dst);
}
void Assembler::xchgq(Register dst, Address src) {
InstructionMark im(this);
prefixq(src, dst);
! emit_byte(0x87);
emit_operand(dst, src);
}
void Assembler::xchgq(Register dst, Register src) {
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
! emit_byte(0x87);
! emit_byte(0xc0 | encode);
}
void Assembler::xorq(Register dst, Register src) {
(void) prefixq_and_encode(dst->encoding(), src->encoding());
emit_arith(0x33, 0xC0, dst, src);
}
void Assembler::xorq(Register dst, Address src) {
InstructionMark im(this);
prefixq(src, dst);
! emit_byte(0x33);
emit_operand(dst, src);
}
#endif // !LP64
--- 5410,5445 ----
}
void Assembler::xaddq(Address dst, Register src) {
InstructionMark im(this);
prefixq(dst, src);
! emit_int8(0x0F);
! emit_int8(0xC1);
emit_operand(src, dst);
}
void Assembler::xchgq(Register dst, Address src) {
InstructionMark im(this);
prefixq(src, dst);
! emit_int8(0x87);
emit_operand(dst, src);
}
void Assembler::xchgq(Register dst, Register src) {
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
! emit_int8(0x87);
! emit_int8(0xc0 | encode);
}
void Assembler::xorq(Register dst, Register src) {
(void) prefixq_and_encode(dst->encoding(), src->encoding());
emit_arith(0x33, 0xC0, dst, src);
}
void Assembler::xorq(Register dst, Address src) {
InstructionMark im(this);
prefixq(src, dst);
! emit_int8(0x33);
emit_operand(dst, src);
}
#endif // !LP64
src/cpu/x86/vm/assembler_x86.cpp
Index
Unified diffs
Context diffs
Sdiffs
Wdiffs
Patch
New
Old
Previous File
Next File