Mercurial > hg > truffle
comparison src/cpu/x86/vm/assembler_x86.cpp @ 2106:91fe28b03d6a
Merge.
author | Thomas Wuerthinger <wuerthinger@ssw.jku.at> |
---|---|
date | Wed, 26 Jan 2011 18:17:37 +0100 |
parents | 06f017f7daa7 b1a2afa37ec4 |
children | d9e4d0aefc90 |
comparison
equal
deleted
inserted
replaced
2062:231bf6b9f5ad | 2106:91fe28b03d6a |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. | 2 * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | 4 * |
5 * This code is free software; you can redistribute it and/or modify it | 5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as | 6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
818 emit_byte(b1); | 818 emit_byte(b1); |
819 emit_byte(b2 + i); | 819 emit_byte(b2 + i); |
820 } | 820 } |
821 | 821 |
822 | 822 |
823 // Now the Assembler instruction (identical for 32/64 bits) | 823 // Now the Assembler instructions (identical for 32/64 bits) |
824 | |
825 void Assembler::adcl(Address dst, int32_t imm32) { | |
826 InstructionMark im(this); | |
827 prefix(dst); | |
828 emit_arith_operand(0x81, rdx, dst, imm32); | |
829 } | |
830 | |
831 void Assembler::adcl(Address dst, Register src) { | |
832 InstructionMark im(this); | |
833 prefix(dst, src); | |
834 emit_byte(0x11); | |
835 emit_operand(src, dst); | |
836 } | |
824 | 837 |
825 void Assembler::adcl(Register dst, int32_t imm32) { | 838 void Assembler::adcl(Register dst, int32_t imm32) { |
826 prefix(dst); | 839 prefix(dst); |
827 emit_arith(0x81, 0xD0, dst, imm32); | 840 emit_arith(0x81, 0xD0, dst, imm32); |
828 } | 841 } |
2193 } | 2206 } |
2194 | 2207 |
2195 void Assembler::orl(Address dst, int32_t imm32) { | 2208 void Assembler::orl(Address dst, int32_t imm32) { |
2196 InstructionMark im(this); | 2209 InstructionMark im(this); |
2197 prefix(dst); | 2210 prefix(dst); |
2198 emit_byte(0x81); | 2211 emit_arith_operand(0x81, rcx, dst, imm32); |
2199 emit_operand(rcx, dst, 4); | |
2200 emit_long(imm32); | |
2201 } | 2212 } |
2202 | 2213 |
2203 void Assembler::orl(Register dst, int32_t imm32) { | 2214 void Assembler::orl(Register dst, int32_t imm32) { |
2204 prefix(dst); | 2215 prefix(dst); |
2205 emit_arith(0x81, 0xC8, dst, imm32); | 2216 emit_arith(0x81, 0xC8, dst, imm32); |
2206 } | 2217 } |
2207 | 2218 |
2208 | |
2209 void Assembler::orl(Register dst, Address src) { | 2219 void Assembler::orl(Register dst, Address src) { |
2210 InstructionMark im(this); | 2220 InstructionMark im(this); |
2211 prefix(src, dst); | 2221 prefix(src, dst); |
2212 emit_byte(0x0B); | 2222 emit_byte(0x0B); |
2213 emit_operand(dst, src); | 2223 emit_operand(dst, src); |
2214 } | 2224 } |
2215 | |
2216 | 2225 |
2217 void Assembler::orl(Register dst, Register src) { | 2226 void Assembler::orl(Register dst, Register src) { |
2218 (void) prefix_and_encode(dst->encoding(), src->encoding()); | 2227 (void) prefix_and_encode(dst->encoding(), src->encoding()); |
2219 emit_arith(0x0B, 0xC0, dst, src); | 2228 emit_arith(0x0B, 0xC0, dst, src); |
2220 } | 2229 } |
2690 } | 2699 } |
2691 | 2700 |
2692 void Assembler::subl(Address dst, int32_t imm32) { | 2701 void Assembler::subl(Address dst, int32_t imm32) { |
2693 InstructionMark im(this); | 2702 InstructionMark im(this); |
2694 prefix(dst); | 2703 prefix(dst); |
2695 if (is8bit(imm32)) { | 2704 emit_arith_operand(0x81, rbp, dst, imm32); |
2696 emit_byte(0x83); | 2705 } |
2697 emit_operand(rbp, dst, 1); | 2706 |
2698 emit_byte(imm32 & 0xFF); | 2707 void Assembler::subl(Address dst, Register src) { |
2699 } else { | 2708 InstructionMark im(this); |
2700 emit_byte(0x81); | 2709 prefix(dst, src); |
2701 emit_operand(rbp, dst, 4); | 2710 emit_byte(0x29); |
2702 emit_long(imm32); | 2711 emit_operand(src, dst); |
2703 } | |
2704 } | 2712 } |
2705 | 2713 |
2706 void Assembler::subl(Register dst, int32_t imm32) { | 2714 void Assembler::subl(Register dst, int32_t imm32) { |
2707 prefix(dst); | 2715 prefix(dst); |
2708 emit_arith(0x81, 0xE8, dst, imm32); | 2716 emit_arith(0x81, 0xE8, dst, imm32); |
2709 } | |
2710 | |
2711 void Assembler::subl(Address dst, Register src) { | |
2712 InstructionMark im(this); | |
2713 prefix(dst, src); | |
2714 emit_byte(0x29); | |
2715 emit_operand(src, dst); | |
2716 } | 2717 } |
2717 | 2718 |
2718 void Assembler::subl(Register dst, Address src) { | 2719 void Assembler::subl(Register dst, Address src) { |
2719 InstructionMark im(this); | 2720 InstructionMark im(this); |
2720 prefix(src, dst); | 2721 prefix(src, dst); |
4331 void Assembler::sarq(Register dst) { | 4332 void Assembler::sarq(Register dst) { |
4332 int encode = prefixq_and_encode(dst->encoding()); | 4333 int encode = prefixq_and_encode(dst->encoding()); |
4333 emit_byte(0xD3); | 4334 emit_byte(0xD3); |
4334 emit_byte(0xF8 | encode); | 4335 emit_byte(0xF8 | encode); |
4335 } | 4336 } |
4337 | |
4336 void Assembler::sbbq(Address dst, int32_t imm32) { | 4338 void Assembler::sbbq(Address dst, int32_t imm32) { |
4337 InstructionMark im(this); | 4339 InstructionMark im(this); |
4338 prefixq(dst); | 4340 prefixq(dst); |
4339 emit_arith_operand(0x81, rbx, dst, imm32); | 4341 emit_arith_operand(0x81, rbx, dst, imm32); |
4340 } | 4342 } |
4390 } | 4392 } |
4391 | 4393 |
4392 void Assembler::subq(Address dst, int32_t imm32) { | 4394 void Assembler::subq(Address dst, int32_t imm32) { |
4393 InstructionMark im(this); | 4395 InstructionMark im(this); |
4394 prefixq(dst); | 4396 prefixq(dst); |
4395 if (is8bit(imm32)) { | 4397 emit_arith_operand(0x81, rbp, dst, imm32); |
4396 emit_byte(0x83); | 4398 } |
4397 emit_operand(rbp, dst, 1); | 4399 |
4398 emit_byte(imm32 & 0xFF); | 4400 void Assembler::subq(Address dst, Register src) { |
4399 } else { | 4401 InstructionMark im(this); |
4400 emit_byte(0x81); | 4402 prefixq(dst, src); |
4401 emit_operand(rbp, dst, 4); | 4403 emit_byte(0x29); |
4402 emit_long(imm32); | 4404 emit_operand(src, dst); |
4403 } | |
4404 } | 4405 } |
4405 | 4406 |
4406 void Assembler::subq(Register dst, int32_t imm32) { | 4407 void Assembler::subq(Register dst, int32_t imm32) { |
4407 (void) prefixq_and_encode(dst->encoding()); | 4408 (void) prefixq_and_encode(dst->encoding()); |
4408 emit_arith(0x81, 0xE8, dst, imm32); | 4409 emit_arith(0x81, 0xE8, dst, imm32); |
4409 } | |
4410 | |
4411 void Assembler::subq(Address dst, Register src) { | |
4412 InstructionMark im(this); | |
4413 prefixq(dst, src); | |
4414 emit_byte(0x29); | |
4415 emit_operand(src, dst); | |
4416 } | 4410 } |
4417 | 4411 |
4418 void Assembler::subq(Register dst, Address src) { | 4412 void Assembler::subq(Register dst, Address src) { |
4419 InstructionMark im(this); | 4413 InstructionMark im(this); |
4420 prefixq(src, dst); | 4414 prefixq(src, dst); |
7136 } | 7130 } |
7137 verify_tlab(); | 7131 verify_tlab(); |
7138 } | 7132 } |
7139 | 7133 |
7140 // Preserves rbx, and rdx. | 7134 // Preserves rbx, and rdx. |
7141 void MacroAssembler::tlab_refill(Label& retry, | 7135 Register MacroAssembler::tlab_refill(Label& retry, |
7142 Label& try_eden, | 7136 Label& try_eden, |
7143 Label& slow_case) { | 7137 Label& slow_case) { |
7144 Register top = rax; | 7138 Register top = rax; |
7145 Register t1 = rcx; | 7139 Register t1 = rcx; |
7146 Register t2 = rsi; | 7140 Register t2 = rsi; |
7147 Register thread_reg = NOT_LP64(rdi) LP64_ONLY(r15_thread); | 7141 Register thread_reg = NOT_LP64(rdi) LP64_ONLY(r15_thread); |
7148 assert_different_registers(top, thread_reg, t1, t2, /* preserve: */ rbx, rdx); | 7142 assert_different_registers(top, thread_reg, t1, t2, /* preserve: */ rbx, rdx); |
7185 addl(Address(thread_reg, in_bytes(JavaThread::tlab_fast_refill_waste_offset())), t1); | 7179 addl(Address(thread_reg, in_bytes(JavaThread::tlab_fast_refill_waste_offset())), t1); |
7186 } | 7180 } |
7187 | 7181 |
7188 // if tlab is currently allocated (top or end != null) then | 7182 // if tlab is currently allocated (top or end != null) then |
7189 // fill [top, end + alignment_reserve) with array object | 7183 // fill [top, end + alignment_reserve) with array object |
7190 testptr (top, top); | 7184 testptr(top, top); |
7191 jcc(Assembler::zero, do_refill); | 7185 jcc(Assembler::zero, do_refill); |
7192 | 7186 |
7193 // set up the mark word | 7187 // set up the mark word |
7194 movptr(Address(top, oopDesc::mark_offset_in_bytes()), (intptr_t)markOopDesc::prototype()->copy_set_hash(0x2)); | 7188 movptr(Address(top, oopDesc::mark_offset_in_bytes()), (intptr_t)markOopDesc::prototype()->copy_set_hash(0x2)); |
7195 // set the length to the remaining space | 7189 // set the length to the remaining space |
7197 addptr(t1, (int32_t)ThreadLocalAllocBuffer::alignment_reserve()); | 7191 addptr(t1, (int32_t)ThreadLocalAllocBuffer::alignment_reserve()); |
7198 shlptr(t1, log2_intptr(HeapWordSize/sizeof(jint))); | 7192 shlptr(t1, log2_intptr(HeapWordSize/sizeof(jint))); |
7199 movl(Address(top, arrayOopDesc::length_offset_in_bytes()), t1); | 7193 movl(Address(top, arrayOopDesc::length_offset_in_bytes()), t1); |
7200 // set klass to intArrayKlass | 7194 // set klass to intArrayKlass |
7201 // dubious reloc why not an oop reloc? | 7195 // dubious reloc why not an oop reloc? |
7202 movptr(t1, ExternalAddress((address) Universe::intArrayKlassObj_addr())); | 7196 movptr(t1, ExternalAddress((address)Universe::intArrayKlassObj_addr())); |
7203 // store klass last. concurrent gcs assumes klass length is valid if | 7197 // store klass last. concurrent gcs assumes klass length is valid if |
7204 // klass field is not null. | 7198 // klass field is not null. |
7205 store_klass(top, t1); | 7199 store_klass(top, t1); |
7200 | |
7201 movptr(t1, top); | |
7202 subptr(t1, Address(thread_reg, in_bytes(JavaThread::tlab_start_offset()))); | |
7203 incr_allocated_bytes(thread_reg, t1, 0); | |
7206 | 7204 |
7207 // refill the tlab with an eden allocation | 7205 // refill the tlab with an eden allocation |
7208 bind(do_refill); | 7206 bind(do_refill); |
7209 movptr(t1, Address(thread_reg, in_bytes(JavaThread::tlab_size_offset()))); | 7207 movptr(t1, Address(thread_reg, in_bytes(JavaThread::tlab_size_offset()))); |
7210 shlptr(t1, LogHeapWordSize); | 7208 shlptr(t1, LogHeapWordSize); |
7211 // add object_size ?? | 7209 // allocate new tlab, address returned in top |
7212 eden_allocate(top, t1, 0, t2, slow_case); | 7210 eden_allocate(top, t1, 0, t2, slow_case); |
7213 | 7211 |
7214 // Check that t1 was preserved in eden_allocate. | 7212 // Check that t1 was preserved in eden_allocate. |
7215 #ifdef ASSERT | 7213 #ifdef ASSERT |
7216 if (UseTLAB) { | 7214 if (UseTLAB) { |
7234 addptr(top, t1); | 7232 addptr(top, t1); |
7235 subptr(top, (int32_t)ThreadLocalAllocBuffer::alignment_reserve_in_bytes()); | 7233 subptr(top, (int32_t)ThreadLocalAllocBuffer::alignment_reserve_in_bytes()); |
7236 movptr(Address(thread_reg, in_bytes(JavaThread::tlab_end_offset())), top); | 7234 movptr(Address(thread_reg, in_bytes(JavaThread::tlab_end_offset())), top); |
7237 verify_tlab(); | 7235 verify_tlab(); |
7238 jmp(retry); | 7236 jmp(retry); |
7237 | |
7238 return thread_reg; // for use by caller | |
7239 } | |
7240 | |
7241 void MacroAssembler::incr_allocated_bytes(Register thread, | |
7242 Register var_size_in_bytes, | |
7243 int con_size_in_bytes, | |
7244 Register t1) { | |
7245 #ifdef _LP64 | |
7246 if (var_size_in_bytes->is_valid()) { | |
7247 addq(Address(thread, in_bytes(JavaThread::allocated_bytes_offset())), var_size_in_bytes); | |
7248 } else { | |
7249 addq(Address(thread, in_bytes(JavaThread::allocated_bytes_offset())), con_size_in_bytes); | |
7250 } | |
7251 #else | |
7252 if (!thread->is_valid()) { | |
7253 assert(t1->is_valid(), "need temp reg"); | |
7254 thread = t1; | |
7255 get_thread(thread); | |
7256 } | |
7257 | |
7258 if (var_size_in_bytes->is_valid()) { | |
7259 addl(Address(thread, in_bytes(JavaThread::allocated_bytes_offset())), var_size_in_bytes); | |
7260 } else { | |
7261 addl(Address(thread, in_bytes(JavaThread::allocated_bytes_offset())), con_size_in_bytes); | |
7262 } | |
7263 adcl(Address(thread, in_bytes(JavaThread::allocated_bytes_offset())+4), 0); | |
7264 #endif | |
7239 } | 7265 } |
7240 | 7266 |
7241 static const double pi_4 = 0.7853981633974483; | 7267 static const double pi_4 = 0.7853981633974483; |
7242 | 7268 |
7243 void MacroAssembler::trigfunc(char trig, int num_fpu_regs_in_use) { | 7269 void MacroAssembler::trigfunc(char trig, int num_fpu_regs_in_use) { |