0N/A/*
3050N/A * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
0N/A * published by the Free Software Foundation.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
1472N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
1472N/A * or visit www.oracle.com if you need additional information or have any
1472N/A * questions.
0N/A *
0N/A */
0N/A
1879N/A#include "precompiled.hpp"
1879N/A#include "assembler_x86.inline.hpp"
1879N/A#include "gc_interface/collectedHeap.inline.hpp"
1879N/A#include "interpreter/interpreter.hpp"
1879N/A#include "memory/cardTableModRefBS.hpp"
1879N/A#include "memory/resourceArea.hpp"
1879N/A#include "prims/methodHandles.hpp"
1879N/A#include "runtime/biasedLocking.hpp"
1879N/A#include "runtime/interfaceSupport.hpp"
1879N/A#include "runtime/objectMonitor.hpp"
1879N/A#include "runtime/os.hpp"
1879N/A#include "runtime/sharedRuntime.hpp"
1879N/A#include "runtime/stubRoutines.hpp"
1879N/A#ifndef SERIALGC
1879N/A#include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
1879N/A#include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
1879N/A#include "gc_implementation/g1/heapRegion.hpp"
1879N/A#endif
0N/A
3932N/A#ifdef PRODUCT
3932N/A#define BLOCK_COMMENT(str) /* nothing */
3932N/A#define STOP(error) stop(error)
3932N/A#else
3932N/A#define BLOCK_COMMENT(str) block_comment(str)
3932N/A#define STOP(error) block_comment(error); stop(error)
3932N/A#endif
3932N/A
3932N/A#define BIND(label) bind(label); BLOCK_COMMENT(#label ":")
0N/A// Implementation of AddressLiteral
0N/A
0N/AAddressLiteral::AddressLiteral(address target, relocInfo::relocType rtype) {
0N/A _is_lval = false;
0N/A _target = target;
0N/A switch (rtype) {
0N/A case relocInfo::oop_type:
0N/A // Oops are a special case. Normally they would be their own section
0N/A // but in cases like icBuffer they are literals in the code stream that
0N/A // we don't have a section for. We use none so that we get a literal address
0N/A // which is always patchable.
0N/A break;
0N/A case relocInfo::external_word_type:
0N/A _rspec = external_word_Relocation::spec(target);
0N/A break;
0N/A case relocInfo::internal_word_type:
0N/A _rspec = internal_word_Relocation::spec(target);
0N/A break;
0N/A case relocInfo::opt_virtual_call_type:
0N/A _rspec = opt_virtual_call_Relocation::spec();
0N/A break;
0N/A case relocInfo::static_call_type:
0N/A _rspec = static_call_Relocation::spec();
0N/A break;
0N/A case relocInfo::runtime_call_type:
0N/A _rspec = runtime_call_Relocation::spec();
0N/A break;
0N/A case relocInfo::poll_type:
0N/A case relocInfo::poll_return_type:
0N/A _rspec = Relocation::spec_simple(rtype);
0N/A break;
0N/A case relocInfo::none:
0N/A break;
0N/A default:
0N/A ShouldNotReachHere();
0N/A break;
0N/A }
0N/A}
0N/A
0N/A// Implementation of Address
0N/A
304N/A#ifdef _LP64
304N/A
0N/AAddress Address::make_array(ArrayAddress adr) {
0N/A // Not implementable on 64bit machines
0N/A // Should have been handled higher up the call chain.
0N/A ShouldNotReachHere();
304N/A return Address();
304N/A}
304N/A
304N/A// exceedingly dangerous constructor
304N/AAddress::Address(int disp, address loc, relocInfo::relocType rtype) {
304N/A _base = noreg;
304N/A _index = noreg;
304N/A _scale = no_scale;
304N/A _disp = disp;
304N/A switch (rtype) {
304N/A case relocInfo::external_word_type:
304N/A _rspec = external_word_Relocation::spec(loc);
304N/A break;
304N/A case relocInfo::internal_word_type:
304N/A _rspec = internal_word_Relocation::spec(loc);
304N/A break;
304N/A case relocInfo::runtime_call_type:
304N/A // HMM
304N/A _rspec = runtime_call_Relocation::spec();
304N/A break;
304N/A case relocInfo::poll_type:
304N/A case relocInfo::poll_return_type:
304N/A _rspec = Relocation::spec_simple(rtype);
304N/A break;
304N/A case relocInfo::none:
304N/A break;
304N/A default:
304N/A ShouldNotReachHere();
304N/A }
304N/A}
304N/A#else // LP64
304N/A
304N/AAddress Address::make_array(ArrayAddress adr) {
0N/A AddressLiteral base = adr.base();
0N/A Address index = adr.index();
0N/A assert(index._disp == 0, "must not have disp"); // maybe it can?
0N/A Address array(index._base, index._index, index._scale, (intptr_t) base.target());
0N/A array._rspec = base._rspec;
0N/A return array;
304N/A}
0N/A
0N/A// exceedingly dangerous constructor
0N/AAddress::Address(address loc, RelocationHolder spec) {
0N/A _base = noreg;
0N/A _index = noreg;
0N/A _scale = no_scale;
0N/A _disp = (intptr_t) loc;
0N/A _rspec = spec;
0N/A}
304N/A
0N/A#endif // _LP64
0N/A
304N/A
304N/A
0N/A// Convert the raw encoding form into the form expected by the constructor for
0N/A// Address. An index of 4 (rsp) corresponds to having no index, so convert
0N/A// that to noreg for the Address constructor.
624N/AAddress Address::make_raw(int base, int index, int scale, int disp, bool disp_is_oop) {
624N/A RelocationHolder rspec;
624N/A if (disp_is_oop) {
624N/A rspec = Relocation::spec_simple(relocInfo::oop_type);
624N/A }
0N/A bool valid_index = index != rsp->encoding();
0N/A if (valid_index) {
0N/A Address madr(as_Register(base), as_Register(index), (Address::ScaleFactor)scale, in_ByteSize(disp));
624N/A madr._rspec = rspec;
0N/A return madr;
0N/A } else {
0N/A Address madr(as_Register(base), noreg, Address::no_scale, in_ByteSize(disp));
624N/A madr._rspec = rspec;
0N/A return madr;
0N/A }
0N/A}
0N/A
0N/A// Implementation of Assembler
0N/A
0N/Aint AbstractAssembler::code_fill_byte() {
0N/A return (u_char)'\xF4'; // hlt
0N/A}
0N/A
0N/A// make this go away someday
0N/Avoid Assembler::emit_data(jint data, relocInfo::relocType rtype, int format) {
0N/A if (rtype == relocInfo::none)
0N/A emit_long(data);
0N/A else emit_data(data, Relocation::spec_simple(rtype), format);
0N/A}
0N/A
0N/Avoid Assembler::emit_data(jint data, RelocationHolder const& rspec, int format) {
304N/A assert(imm_operand == 0, "default format must be immediate in this file");
0N/A assert(inst_mark() != NULL, "must be inside InstructionMark");
0N/A if (rspec.type() != relocInfo::none) {
0N/A #ifdef ASSERT
0N/A check_relocation(rspec, format);
0N/A #endif
0N/A // Do not use AbstractAssembler::relocate, which is not intended for
0N/A // embedded words. Instead, relocate to the enclosing instruction.
0N/A
0N/A // hack. call32 is too wide for mask so use disp32
0N/A if (format == call32_operand)
0N/A code_section()->relocate(inst_mark(), rspec, disp32_operand);
0N/A else
0N/A code_section()->relocate(inst_mark(), rspec, format);
0N/A }
0N/A emit_long(data);
0N/A}
0N/A
304N/Astatic int encode(Register r) {
304N/A int enc = r->encoding();
304N/A if (enc >= 8) {
304N/A enc -= 8;
304N/A }
304N/A return enc;
304N/A}
304N/A
304N/Astatic int encode(XMMRegister r) {
304N/A int enc = r->encoding();
304N/A if (enc >= 8) {
304N/A enc -= 8;
304N/A }
304N/A return enc;
304N/A}
0N/A
0N/Avoid Assembler::emit_arith_b(int op1, int op2, Register dst, int imm8) {
0N/A assert(dst->has_byte_register(), "must have byte register");
0N/A assert(isByte(op1) && isByte(op2), "wrong opcode");
0N/A assert(isByte(imm8), "not a byte");
0N/A assert((op1 & 0x01) == 0, "should be 8bit operation");
0N/A emit_byte(op1);
304N/A emit_byte(op2 | encode(dst));
0N/A emit_byte(imm8);
0N/A}
0N/A
0N/A
304N/Avoid Assembler::emit_arith(int op1, int op2, Register dst, int32_t imm32) {
0N/A assert(isByte(op1) && isByte(op2), "wrong opcode");
0N/A assert((op1 & 0x01) == 1, "should be 32bit operation");
0N/A assert((op1 & 0x02) == 0, "sign-extension bit should not be set");
0N/A if (is8bit(imm32)) {
0N/A emit_byte(op1 | 0x02); // set sign bit
304N/A emit_byte(op2 | encode(dst));
0N/A emit_byte(imm32 & 0xFF);
0N/A } else {
0N/A emit_byte(op1);
304N/A emit_byte(op2 | encode(dst));
0N/A emit_long(imm32);
0N/A }
0N/A}
0N/A
3236N/A// Force generation of a 4 byte immediate value even if it fits into 8bit
3236N/Avoid Assembler::emit_arith_imm32(int op1, int op2, Register dst, int32_t imm32) {
3236N/A assert(isByte(op1) && isByte(op2), "wrong opcode");
3236N/A assert((op1 & 0x01) == 1, "should be 32bit operation");
3236N/A assert((op1 & 0x02) == 0, "sign-extension bit should not be set");
3236N/A emit_byte(op1);
3236N/A emit_byte(op2 | encode(dst));
3236N/A emit_long(imm32);
3236N/A}
3236N/A
0N/A// immediate-to-memory forms
304N/Avoid Assembler::emit_arith_operand(int op1, Register rm, Address adr, int32_t imm32) {
0N/A assert((op1 & 0x01) == 1, "should be 32bit operation");
0N/A assert((op1 & 0x02) == 0, "sign-extension bit should not be set");
0N/A if (is8bit(imm32)) {
0N/A emit_byte(op1 | 0x02); // set sign bit
304N/A emit_operand(rm, adr, 1);
0N/A emit_byte(imm32 & 0xFF);
0N/A } else {
0N/A emit_byte(op1);
304N/A emit_operand(rm, adr, 4);
0N/A emit_long(imm32);
0N/A }
0N/A}
0N/A
0N/Avoid Assembler::emit_arith(int op1, int op2, Register dst, jobject obj) {
304N/A LP64_ONLY(ShouldNotReachHere());
0N/A assert(isByte(op1) && isByte(op2), "wrong opcode");
0N/A assert((op1 & 0x01) == 1, "should be 32bit operation");
0N/A assert((op1 & 0x02) == 0, "sign-extension bit should not be set");
0N/A InstructionMark im(this);
0N/A emit_byte(op1);
304N/A emit_byte(op2 | encode(dst));
304N/A emit_data((intptr_t)obj, relocInfo::oop_type, 0);
0N/A}
0N/A
0N/A
0N/Avoid Assembler::emit_arith(int op1, int op2, Register dst, Register src) {
0N/A assert(isByte(op1) && isByte(op2), "wrong opcode");
0N/A emit_byte(op1);
304N/A emit_byte(op2 | encode(dst) << 3 | encode(src));
304N/A}
304N/A
304N/A
304N/Avoid Assembler::emit_operand(Register reg, Register base, Register index,
304N/A Address::ScaleFactor scale, int disp,
304N/A RelocationHolder const& rspec,
304N/A int rip_relative_correction) {
0N/A relocInfo::relocType rtype = (relocInfo::relocType) rspec.type();
304N/A
304N/A // Encode the registers as needed in the fields they are used in
304N/A
304N/A int regenc = encode(reg) << 3;
304N/A int indexenc = index->is_valid() ? encode(index) << 3 : 0;
304N/A int baseenc = base->is_valid() ? encode(base) : 0;
304N/A
0N/A if (base->is_valid()) {
0N/A if (index->is_valid()) {
0N/A assert(scale != Address::no_scale, "inconsistent address");
0N/A // [base + index*scale + disp]
304N/A if (disp == 0 && rtype == relocInfo::none &&
304N/A base != rbp LP64_ONLY(&& base != r13)) {
0N/A // [base + index*scale]
0N/A // [00 reg 100][ss index base]
0N/A assert(index != rsp, "illegal addressing mode");
304N/A emit_byte(0x04 | regenc);
304N/A emit_byte(scale << 6 | indexenc | baseenc);
0N/A } else if (is8bit(disp) && rtype == relocInfo::none) {
0N/A // [base + index*scale + imm8]
0N/A // [01 reg 100][ss index base] imm8
0N/A assert(index != rsp, "illegal addressing mode");
304N/A emit_byte(0x44 | regenc);
304N/A emit_byte(scale << 6 | indexenc | baseenc);
0N/A emit_byte(disp & 0xFF);
0N/A } else {
304N/A // [base + index*scale + disp32]
304N/A // [10 reg 100][ss index base] disp32
0N/A assert(index != rsp, "illegal addressing mode");
304N/A emit_byte(0x84 | regenc);
304N/A emit_byte(scale << 6 | indexenc | baseenc);
0N/A emit_data(disp, rspec, disp32_operand);
0N/A }
304N/A } else if (base == rsp LP64_ONLY(|| base == r12)) {
304N/A // [rsp + disp]
0N/A if (disp == 0 && rtype == relocInfo::none) {
304N/A // [rsp]
0N/A // [00 reg 100][00 100 100]
304N/A emit_byte(0x04 | regenc);
0N/A emit_byte(0x24);
0N/A } else if (is8bit(disp) && rtype == relocInfo::none) {
304N/A // [rsp + imm8]
304N/A // [01 reg 100][00 100 100] disp8
304N/A emit_byte(0x44 | regenc);
0N/A emit_byte(0x24);
0N/A emit_byte(disp & 0xFF);
0N/A } else {
304N/A // [rsp + imm32]
304N/A // [10 reg 100][00 100 100] disp32
304N/A emit_byte(0x84 | regenc);
0N/A emit_byte(0x24);
0N/A emit_data(disp, rspec, disp32_operand);
0N/A }
0N/A } else {
0N/A // [base + disp]
304N/A assert(base != rsp LP64_ONLY(&& base != r12), "illegal addressing mode");
304N/A if (disp == 0 && rtype == relocInfo::none &&
304N/A base != rbp LP64_ONLY(&& base != r13)) {
0N/A // [base]
0N/A // [00 reg base]
304N/A emit_byte(0x00 | regenc | baseenc);
0N/A } else if (is8bit(disp) && rtype == relocInfo::none) {
304N/A // [base + disp8]
304N/A // [01 reg base] disp8
304N/A emit_byte(0x40 | regenc | baseenc);
0N/A emit_byte(disp & 0xFF);
0N/A } else {
304N/A // [base + disp32]
304N/A // [10 reg base] disp32
304N/A emit_byte(0x80 | regenc | baseenc);
0N/A emit_data(disp, rspec, disp32_operand);
0N/A }
0N/A }
0N/A } else {
0N/A if (index->is_valid()) {
0N/A assert(scale != Address::no_scale, "inconsistent address");
0N/A // [index*scale + disp]
304N/A // [00 reg 100][ss index 101] disp32
0N/A assert(index != rsp, "illegal addressing mode");
304N/A emit_byte(0x04 | regenc);
304N/A emit_byte(scale << 6 | indexenc | 0x05);
0N/A emit_data(disp, rspec, disp32_operand);
304N/A } else if (rtype != relocInfo::none ) {
304N/A // [disp] (64bit) RIP-RELATIVE (32bit) abs
304N/A // [00 000 101] disp32
304N/A
304N/A emit_byte(0x05 | regenc);
304N/A // Note that the RIP-rel. correction applies to the generated
304N/A // disp field, but _not_ to the target address in the rspec.
304N/A
304N/A // disp was created by converting the target address minus the pc
304N/A // at the start of the instruction. That needs more correction here.
304N/A // intptr_t disp = target - next_ip;
304N/A assert(inst_mark() != NULL, "must be inside InstructionMark");
304N/A address next_ip = pc() + sizeof(int32_t) + rip_relative_correction;
304N/A int64_t adjusted = disp;
304N/A // Do rip-rel adjustment for 64bit
304N/A LP64_ONLY(adjusted -= (next_ip - inst_mark()));
304N/A assert(is_simm32(adjusted),
304N/A "must be 32bit offset (RIP relative address)");
304N/A emit_data((int32_t) adjusted, rspec, disp32_operand);
304N/A
0N/A } else {
304N/A // 32bit never did this, did everything as the rip-rel/disp code above
304N/A // [disp] ABSOLUTE
304N/A // [00 reg 100][00 100 101] disp32
304N/A emit_byte(0x04 | regenc);
304N/A emit_byte(0x25);
0N/A emit_data(disp, rspec, disp32_operand);
0N/A }
0N/A }
0N/A}
0N/A
304N/Avoid Assembler::emit_operand(XMMRegister reg, Register base, Register index,
304N/A Address::ScaleFactor scale, int disp,
304N/A RelocationHolder const& rspec) {
304N/A emit_operand((Register)reg, base, index, scale, disp, rspec);
304N/A}
304N/A
0N/A// Secret local extension to Assembler::WhichOperand:
0N/A#define end_pc_operand (_WhichOperand_limit)
0N/A
0N/Aaddress Assembler::locate_operand(address inst, WhichOperand which) {
0N/A // Decode the given instruction, and return the address of
0N/A // an embedded 32-bit operand word.
0N/A
0N/A // If "which" is disp32_operand, selects the displacement portion
0N/A // of an effective address specifier.
304N/A // If "which" is imm64_operand, selects the trailing immediate constant.
0N/A // If "which" is call32_operand, selects the displacement of a call or jump.
0N/A // Caller is responsible for ensuring that there is such an operand,
304N/A // and that it is 32/64 bits wide.
0N/A
0N/A // If "which" is end_pc_operand, find the end of the instruction.
0N/A
0N/A address ip = inst;
304N/A bool is_64bit = false;
304N/A
304N/A debug_only(bool has_disp32 = false);
304N/A int tail_size = 0; // other random bytes (#32, #16, etc.) at end of insn
304N/A
304N/A again_after_prefix:
0N/A switch (0xFF & *ip++) {
0N/A
0N/A // These convenience macros generate groups of "case" labels for the switch.
304N/A#define REP4(x) (x)+0: case (x)+1: case (x)+2: case (x)+3
304N/A#define REP8(x) (x)+0: case (x)+1: case (x)+2: case (x)+3: \
0N/A case (x)+4: case (x)+5: case (x)+6: case (x)+7
304N/A#define REP16(x) REP8((x)+0): \
0N/A case REP8((x)+8)
0N/A
0N/A case CS_segment:
0N/A case SS_segment:
0N/A case DS_segment:
0N/A case ES_segment:
0N/A case FS_segment:
0N/A case GS_segment:
304N/A // Seems dubious
304N/A LP64_ONLY(assert(false, "shouldn't have that prefix"));
0N/A assert(ip == inst+1, "only one prefix allowed");
0N/A goto again_after_prefix;
0N/A
304N/A case 0x67:
304N/A case REX:
304N/A case REX_B:
304N/A case REX_X:
304N/A case REX_XB:
304N/A case REX_R:
304N/A case REX_RB:
304N/A case REX_RX:
304N/A case REX_RXB:
304N/A NOT_LP64(assert(false, "64bit prefixes"));
304N/A goto again_after_prefix;
304N/A
304N/A case REX_W:
304N/A case REX_WB:
304N/A case REX_WX:
304N/A case REX_WXB:
304N/A case REX_WR:
304N/A case REX_WRB:
304N/A case REX_WRX:
304N/A case REX_WRXB:
304N/A NOT_LP64(assert(false, "64bit prefixes"));
304N/A is_64bit = true;
304N/A goto again_after_prefix;
304N/A
304N/A case 0xFF: // pushq a; decl a; incl a; call a; jmp a
0N/A case 0x88: // movb a, r
0N/A case 0x89: // movl a, r
0N/A case 0x8A: // movb r, a
0N/A case 0x8B: // movl r, a
0N/A case 0x8F: // popl a
304N/A debug_only(has_disp32 = true);
0N/A break;
0N/A
304N/A case 0x68: // pushq #32
304N/A if (which == end_pc_operand) {
304N/A return ip + 4;
304N/A }
304N/A assert(which == imm_operand && !is_64bit, "pushl has no disp32 or 64bit immediate");
0N/A return ip; // not produced by emit_operand
0N/A
0N/A case 0x66: // movw ... (size prefix)
304N/A again_after_size_prefix2:
0N/A switch (0xFF & *ip++) {
304N/A case REX:
304N/A case REX_B:
304N/A case REX_X:
304N/A case REX_XB:
304N/A case REX_R:
304N/A case REX_RB:
304N/A case REX_RX:
304N/A case REX_RXB:
304N/A case REX_W:
304N/A case REX_WB:
304N/A case REX_WX:
304N/A case REX_WXB:
304N/A case REX_WR:
304N/A case REX_WRB:
304N/A case REX_WRX:
304N/A case REX_WRXB:
304N/A NOT_LP64(assert(false, "64bit prefix found"));
304N/A goto again_after_size_prefix2;
0N/A case 0x8B: // movw r, a
0N/A case 0x89: // movw a, r
304N/A debug_only(has_disp32 = true);
0N/A break;
0N/A case 0xC7: // movw a, #16
304N/A debug_only(has_disp32 = true);
0N/A tail_size = 2; // the imm16
0N/A break;
0N/A case 0x0F: // several SSE/SSE2 variants
Error!

 

There was an error!

null

java.lang.NullPointerException