comparison src/cpu/x86/vm/x86_64.ad @ 344:6aae2f9d0294

Merge
author ysr
date Thu, 12 Jun 2008 13:50:55 -0700
parents 44abbb0d4c18
children d1605aabd0a1 1e026f8da827
comparison
equal deleted inserted replaced
342:37f87013dfd8 344:6aae2f9d0294
3806 3806
3807 // That's it 3807 // That's it
3808 masm.bind(DONE_LABEL); 3808 masm.bind(DONE_LABEL);
3809 %} 3809 %}
3810 3810
3811 enc_class enc_Array_Equals(rdi_RegP ary1, rsi_RegP ary2, rax_RegI tmp1, rbx_RegI tmp2, rcx_RegI result) %{
3812 Label TRUE_LABEL, FALSE_LABEL, DONE_LABEL, COMPARE_LOOP_HDR, COMPARE_LOOP;
3813 MacroAssembler masm(&cbuf);
3814
3815 Register ary1Reg = as_Register($ary1$$reg);
3816 Register ary2Reg = as_Register($ary2$$reg);
3817 Register tmp1Reg = as_Register($tmp1$$reg);
3818 Register tmp2Reg = as_Register($tmp2$$reg);
3819 Register resultReg = as_Register($result$$reg);
3820
3821 int length_offset = arrayOopDesc::length_offset_in_bytes();
3822 int base_offset = arrayOopDesc::base_offset_in_bytes(T_CHAR);
3823
3824 // Check the input args
3825 masm.cmpq(ary1Reg, ary2Reg);
3826 masm.jcc(Assembler::equal, TRUE_LABEL);
3827 masm.testq(ary1Reg, ary1Reg);
3828 masm.jcc(Assembler::zero, FALSE_LABEL);
3829 masm.testq(ary2Reg, ary2Reg);
3830 masm.jcc(Assembler::zero, FALSE_LABEL);
3831
3832 // Check the lengths
3833 masm.movl(tmp2Reg, Address(ary1Reg, length_offset));
3834 masm.movl(resultReg, Address(ary2Reg, length_offset));
3835 masm.cmpl(tmp2Reg, resultReg);
3836 masm.jcc(Assembler::notEqual, FALSE_LABEL);
3837 masm.testl(resultReg, resultReg);
3838 masm.jcc(Assembler::zero, TRUE_LABEL);
3839
3840 // Get the number of 4 byte vectors to compare
3841 masm.shrl(resultReg, 1);
3842
3843 // Check for odd-length arrays
3844 masm.andl(tmp2Reg, 1);
3845 masm.testl(tmp2Reg, tmp2Reg);
3846 masm.jcc(Assembler::zero, COMPARE_LOOP_HDR);
3847
3848 // Compare 2-byte "tail" at end of arrays
3849 masm.load_unsigned_word(tmp1Reg, Address(ary1Reg, resultReg, Address::times_4, base_offset));
3850 masm.load_unsigned_word(tmp2Reg, Address(ary2Reg, resultReg, Address::times_4, base_offset));
3851 masm.cmpl(tmp1Reg, tmp2Reg);
3852 masm.jcc(Assembler::notEqual, FALSE_LABEL);
3853 masm.testl(resultReg, resultReg);
3854 masm.jcc(Assembler::zero, TRUE_LABEL);
3855
3856 // Setup compare loop
3857 masm.bind(COMPARE_LOOP_HDR);
3858 // Shift tmp1Reg and tmp2Reg to the last 4-byte boundary of the arrays
3859 masm.leaq(tmp1Reg, Address(ary1Reg, resultReg, Address::times_4, base_offset));
3860 masm.leaq(tmp2Reg, Address(ary2Reg, resultReg, Address::times_4, base_offset));
3861 masm.negq(resultReg);
3862
3863 // 4-byte-wide compare loop
3864 masm.bind(COMPARE_LOOP);
3865 masm.movl(ary1Reg, Address(tmp1Reg, resultReg, Address::times_4, 0));
3866 masm.movl(ary2Reg, Address(tmp2Reg, resultReg, Address::times_4, 0));
3867 masm.cmpl(ary1Reg, ary2Reg);
3868 masm.jcc(Assembler::notEqual, FALSE_LABEL);
3869 masm.incrementq(resultReg);
3870 masm.jcc(Assembler::notZero, COMPARE_LOOP);
3871
3872 masm.bind(TRUE_LABEL);
3873 masm.movl(resultReg, 1); // return true
3874 masm.jmp(DONE_LABEL);
3875
3876 masm.bind(FALSE_LABEL);
3877 masm.xorl(resultReg, resultReg); // return false
3878
3879 // That's it
3880 masm.bind(DONE_LABEL);
3881 %}
3882
3811 enc_class enc_rethrow() 3883 enc_class enc_rethrow()
3812 %{ 3884 %{
3813 cbuf.set_inst_mark(); 3885 cbuf.set_inst_mark();
3814 emit_opcode(cbuf, 0xE9); // jmp entry 3886 emit_opcode(cbuf, 0xE9); // jmp entry
3815 emit_d32_reloc(cbuf, 3887 emit_d32_reloc(cbuf,
5200 scale($scale); 5272 scale($scale);
5201 disp($off); 5273 disp($off);
5202 %} 5274 %}
5203 %} 5275 %}
5204 5276
5205 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 5277 // Indirect Narrow Oop Plus Offset Operand
5206 operand indIndexScaleOffsetComp(rRegN src, immL32 off, r12RegL base) %{ 5278 operand indNarrowOopOffset(rRegN src, immL32 off) %{
5207 constraint(ALLOC_IN_RC(ptr_reg)); 5279 constraint(ALLOC_IN_RC(ptr_reg));
5208 match(AddP (DecodeN src base) off); 5280 match(AddP (DecodeN src) off);
5209 5281
5210 op_cost(10); 5282 op_cost(10);
5211 format %{"[$base + $src << 3 + $off] (compressed)" %} 5283 format %{"[R12 + $src << 3 + $off] (compressed oop addressing)" %}
5212 interface(MEMORY_INTER) %{ 5284 interface(MEMORY_INTER) %{
5213 base($base); 5285 base(0xc); // R12
5214 index($src); 5286 index($src);
5215 scale(0x3); 5287 scale(0x3);
5216 disp($off); 5288 disp($off);
5217 %} 5289 %}
5218 %} 5290 %}
5363 // multiple operand types with the same basic encoding and format. The classic 5435 // multiple operand types with the same basic encoding and format. The classic
5364 // case of this is memory operands. 5436 // case of this is memory operands.
5365 5437
5366 opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex, 5438 opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex,
5367 indIndexScale, indIndexScaleOffset, indPosIndexScaleOffset, 5439 indIndexScale, indIndexScaleOffset, indPosIndexScaleOffset,
5368 indIndexScaleOffsetComp); 5440 indNarrowOopOffset);
5369 5441
5370 //----------PIPELINE----------------------------------------------------------- 5442 //----------PIPELINE-----------------------------------------------------------
5371 // Rules which define the behavior of the target architectures pipeline. 5443 // Rules which define the behavior of the target architectures pipeline.
5372 pipeline %{ 5444 pipeline %{
5373 5445
6042 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 6114 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
6043 ins_pipe(ialu_reg_mem); // XXX 6115 ins_pipe(ialu_reg_mem); // XXX
6044 %} 6116 %}
6045 6117
6046 // Load Compressed Pointer 6118 // Load Compressed Pointer
6047 instruct loadN(rRegN dst, memory mem, rFlagsReg cr) 6119 instruct loadN(rRegN dst, memory mem)
6048 %{ 6120 %{
6049 match(Set dst (LoadN mem)); 6121 match(Set dst (LoadN mem));
6050 effect(KILL cr);
6051 6122
6052 ins_cost(125); // XXX 6123 ins_cost(125); // XXX
6053 format %{ "movl $dst, $mem\t# compressed ptr" %} 6124 format %{ "movl $dst, $mem\t# compressed ptr" %}
6054 ins_encode %{ 6125 ins_encode %{
6055 Address addr = build_address($mem$$base, $mem$$index, $mem$$scale, $mem$$disp); 6126 Address addr = build_address($mem$$base, $mem$$index, $mem$$scale, $mem$$disp);
6062 6133
6063 // Load Klass Pointer 6134 // Load Klass Pointer
6064 instruct loadKlass(rRegP dst, memory mem) 6135 instruct loadKlass(rRegP dst, memory mem)
6065 %{ 6136 %{
6066 match(Set dst (LoadKlass mem)); 6137 match(Set dst (LoadKlass mem));
6067 predicate(!n->in(MemNode::Address)->bottom_type()->is_narrow());
6068 6138
6069 ins_cost(125); // XXX 6139 ins_cost(125); // XXX
6070 format %{ "movq $dst, $mem\t# class" %} 6140 format %{ "movq $dst, $mem\t# class" %}
6071 opcode(0x8B); 6141 opcode(0x8B);
6072 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 6142 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
6073 ins_pipe(ialu_reg_mem); // XXX 6143 ins_pipe(ialu_reg_mem); // XXX
6074 %} 6144 %}
6075 6145
6076 // Load Klass Pointer 6146 // Load narrow Klass Pointer
6077 instruct loadKlassComp(rRegP dst, memory mem) 6147 instruct loadNKlass(rRegN dst, memory mem)
6078 %{ 6148 %{
6079 match(Set dst (LoadKlass mem)); 6149 match(Set dst (LoadNKlass mem));
6080 predicate(n->in(MemNode::Address)->bottom_type()->is_narrow());
6081 6150
6082 ins_cost(125); // XXX 6151 ins_cost(125); // XXX
6083 format %{ "movl $dst, $mem\t# compressed class\n\t" 6152 format %{ "movl $dst, $mem\t# compressed klass ptr" %}
6084 "decode_heap_oop $dst,$dst" %}
6085 ins_encode %{ 6153 ins_encode %{
6086 Address addr = build_address($mem$$base, $mem$$index, $mem$$scale, $mem$$disp); 6154 Address addr = build_address($mem$$base, $mem$$index, $mem$$scale, $mem$$disp);
6087 Register dst = as_Register($dst$$reg); 6155 Register dst = as_Register($dst$$reg);
6088 __ movl(dst, addr); 6156 __ movl(dst, addr);
6089 // klass is never null in the header but this is generated for all
6090 // klass loads not just the _klass field in the header.
6091 __ decode_heap_oop(dst);
6092 %} 6157 %}
6093 ins_pipe(ialu_reg_mem); // XXX 6158 ins_pipe(ialu_reg_mem); // XXX
6094 %} 6159 %}
6095 6160
6096 // Load Float 6161 // Load Float
6360 6425
6361 instruct loadConN(rRegN dst, immN src) %{ 6426 instruct loadConN(rRegN dst, immN src) %{
6362 match(Set dst src); 6427 match(Set dst src);
6363 6428
6364 ins_cost(125); 6429 ins_cost(125);
6365 format %{ "movq $dst, $src\t# compressed ptr\n\t" 6430 format %{ "movl $dst, $src\t# compressed ptr" %}
6366 "encode_heap_oop_not_null $dst,$dst" %}
6367 ins_encode %{ 6431 ins_encode %{
6368 address con = (address)$src$$constant; 6432 address con = (address)$src$$constant;
6369 Register dst = $dst$$Register; 6433 Register dst = $dst$$Register;
6370 if (con == NULL) { 6434 if (con == NULL) {
6371 ShouldNotReachHere(); 6435 ShouldNotReachHere();
6372 } else { 6436 } else {
6373 __ movoop(dst, (jobject)$src$$constant); 6437 __ set_narrow_oop(dst, (jobject)$src$$constant);
6374 __ encode_heap_oop_not_null(dst);
6375 } 6438 }
6376 %} 6439 %}
6377 ins_pipe(ialu_reg_fat); // XXX 6440 ins_pipe(ialu_reg_fat); // XXX
6378 %} 6441 %}
6379 6442
6631 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 6694 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src));
6632 ins_pipe(ialu_mem_imm); 6695 ins_pipe(ialu_mem_imm);
6633 %} 6696 %}
6634 6697
6635 // Store Compressed Pointer 6698 // Store Compressed Pointer
6636 instruct storeN(memory mem, rRegN src, rFlagsReg cr) 6699 instruct storeN(memory mem, rRegN src)
6637 %{ 6700 %{
6638 match(Set mem (StoreN mem src)); 6701 match(Set mem (StoreN mem src));
6639 effect(KILL cr);
6640 6702
6641 ins_cost(125); // XXX 6703 ins_cost(125); // XXX
6642 format %{ "movl $mem, $src\t# ptr" %} 6704 format %{ "movl $mem, $src\t# compressed ptr" %}
6643 ins_encode %{ 6705 ins_encode %{
6644 Address addr = build_address($mem$$base, $mem$$index, $mem$$scale, $mem$$disp); 6706 Address addr = build_address($mem$$base, $mem$$index, $mem$$scale, $mem$$disp);
6645 Register src = as_Register($src$$reg); 6707 Register src = as_Register($src$$reg);
6646 __ movl(addr, src); 6708 __ movl(addr, src);
6647 %} 6709 %}
7025 %} 7087 %}
7026 ins_pipe(ialu_reg_long); 7088 ins_pipe(ialu_reg_long);
7027 %} 7089 %}
7028 7090
7029 instruct decodeHeapOop(rRegP dst, rRegN src, rFlagsReg cr) %{ 7091 instruct decodeHeapOop(rRegP dst, rRegN src, rFlagsReg cr) %{
7030 predicate(n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull); 7092 predicate(n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull &&
7093 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant);
7031 match(Set dst (DecodeN src)); 7094 match(Set dst (DecodeN src));
7032 effect(KILL cr); 7095 effect(KILL cr);
7033 format %{ "decode_heap_oop $dst,$src" %} 7096 format %{ "decode_heap_oop $dst,$src" %}
7034 ins_encode %{ 7097 ins_encode %{
7035 Register s = $src$$Register; 7098 Register s = $src$$Register;
7041 %} 7104 %}
7042 ins_pipe(ialu_reg_long); 7105 ins_pipe(ialu_reg_long);
7043 %} 7106 %}
7044 7107
7045 instruct decodeHeapOop_not_null(rRegP dst, rRegN src) %{ 7108 instruct decodeHeapOop_not_null(rRegP dst, rRegN src) %{
7046 predicate(n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull); 7109 predicate(n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull ||
7110 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant);
7047 match(Set dst (DecodeN src)); 7111 match(Set dst (DecodeN src));
7048 format %{ "decode_heap_oop_not_null $dst,$src" %} 7112 format %{ "decode_heap_oop_not_null $dst,$src" %}
7049 ins_encode %{ 7113 ins_encode %{
7050 Register s = $src$$Register; 7114 Register s = $src$$Register;
7051 Register d = $dst$$Register; 7115 Register d = $dst$$Register;
7138 ins_cost(250); // XXX 7202 ins_cost(250); // XXX
7139 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 7203 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %}
7140 opcode(0x0F, 0x40); 7204 opcode(0x0F, 0x40);
7141 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src)); 7205 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src));
7142 ins_pipe(pipe_cmov_mem); 7206 ins_pipe(pipe_cmov_mem);
7207 %}
7208
7209 // Conditional move
7210 instruct cmovN_reg(rRegN dst, rRegN src, rFlagsReg cr, cmpOp cop)
7211 %{
7212 match(Set dst (CMoveN (Binary cop cr) (Binary dst src)));
7213
7214 ins_cost(200); // XXX
7215 format %{ "cmovl$cop $dst, $src\t# signed, compressed ptr" %}
7216 opcode(0x0F, 0x40);
7217 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src));
7218 ins_pipe(pipe_cmov_reg);
7219 %}
7220
7221 // Conditional move
7222 instruct cmovN_regU(rRegN dst, rRegN src, rFlagsRegU cr, cmpOpU cop)
7223 %{
7224 match(Set dst (CMoveN (Binary cop cr) (Binary dst src)));
7225
7226 ins_cost(200); // XXX
7227 format %{ "cmovl$cop $dst, $src\t# unsigned, compressed ptr" %}
7228 opcode(0x0F, 0x40);
7229 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src));
7230 ins_pipe(pipe_cmov_reg);
7143 %} 7231 %}
7144 7232
7145 // Conditional move 7233 // Conditional move
7146 instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop) 7234 instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop)
7147 %{ 7235 %{
10860 format %{ "String Compare $str1, $str2 -> $result // XXX KILL RAX, RBX" %} 10948 format %{ "String Compare $str1, $str2 -> $result // XXX KILL RAX, RBX" %}
10861 ins_encode( enc_String_Compare() ); 10949 ins_encode( enc_String_Compare() );
10862 ins_pipe( pipe_slow ); 10950 ins_pipe( pipe_slow );
10863 %} 10951 %}
10864 10952
10953 // fast array equals
10954 instruct array_equals(rdi_RegP ary1, rsi_RegP ary2, rax_RegI tmp1,
10955 rbx_RegI tmp2, rcx_RegI result, rFlagsReg cr) %{
10956 match(Set result (AryEq ary1 ary2));
10957 effect(USE_KILL ary1, USE_KILL ary2, KILL tmp1, KILL tmp2, KILL cr);
10958 //ins_cost(300);
10959
10960 format %{ "Array Equals $ary1,$ary2 -> $result // KILL RAX, RBX" %}
10961 ins_encode( enc_Array_Equals(ary1, ary2, tmp1, tmp2, result) );
10962 ins_pipe( pipe_slow );
10963 %}
10964
10865 //----------Control Flow Instructions------------------------------------------ 10965 //----------Control Flow Instructions------------------------------------------
10866 // Signed compare Instructions 10966 // Signed compare Instructions
10867 10967
10868 // XXX more variants!! 10968 // XXX more variants!!
10869 instruct compI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 10969 instruct compI_rReg(rFlagsReg cr, rRegI op1, rRegI op2)
11053 ins_encode(REX_mem_wide(op), 11153 ins_encode(REX_mem_wide(op),
11054 OpcP, RM_opc_mem(0x00, op), Con_d32(0xFFFFFFFF)); 11154 OpcP, RM_opc_mem(0x00, op), Con_d32(0xFFFFFFFF));
11055 ins_pipe(ialu_cr_reg_imm); 11155 ins_pipe(ialu_cr_reg_imm);
11056 %} 11156 %}
11057 11157
11158
11159 instruct compN_rReg(rFlagsRegU cr, rRegN op1, rRegN op2)
11160 %{
11161 match(Set cr (CmpN op1 op2));
11162
11163 format %{ "cmpl $op1, $op2\t# compressed ptr" %}
11164 ins_encode %{ __ cmpl(as_Register($op1$$reg), as_Register($op2$$reg)); %}
11165 ins_pipe(ialu_cr_reg_reg);
11166 %}
11167
11168 instruct compN_rReg_mem(rFlagsRegU cr, rRegN src, memory mem)
11169 %{
11170 match(Set cr (CmpN src (LoadN mem)));
11171
11172 ins_cost(500); // XXX
11173 format %{ "cmpl $src, mem\t# compressed ptr" %}
11174 ins_encode %{
11175 Address adr = build_address($mem$$base, $mem$$index, $mem$$scale, $mem$$disp);
11176 __ cmpl(as_Register($src$$reg), adr);
11177 %}
11178 ins_pipe(ialu_cr_reg_mem);
11179 %}
11180
11058 instruct testN_reg(rFlagsReg cr, rRegN src, immN0 zero) %{ 11181 instruct testN_reg(rFlagsReg cr, rRegN src, immN0 zero) %{
11059 match(Set cr (CmpN src zero)); 11182 match(Set cr (CmpN src zero));
11060 11183
11061 format %{ "testl $src, $src" %} 11184 format %{ "testl $src, $src\t# compressed ptr" %}
11062 ins_encode %{ __ testl($src$$Register, $src$$Register); %} 11185 ins_encode %{ __ testl($src$$Register, $src$$Register); %}
11063 ins_pipe(ialu_cr_reg_imm); 11186 ins_pipe(ialu_cr_reg_imm);
11187 %}
11188
11189 instruct testN_reg_mem(rFlagsReg cr, memory mem, immN0 zero)
11190 %{
11191 match(Set cr (CmpN (LoadN mem) zero));
11192
11193 ins_cost(500); // XXX
11194 format %{ "testl $mem, 0xffffffff\t# compressed ptr" %}
11195 ins_encode %{
11196 Address addr = build_address($mem$$base, $mem$$index, $mem$$scale, $mem$$disp);
11197 __ cmpl(addr, (int)0xFFFFFFFF);
11198 %}
11199 ins_pipe(ialu_cr_reg_mem);
11064 %} 11200 %}
11065 11201
11066 // Yanked all unsigned pointer compare operations. 11202 // Yanked all unsigned pointer compare operations.
11067 // Pointer compares are done with CmpP which is already unsigned. 11203 // Pointer compares are done with CmpP which is already unsigned.
11068 11204