src/cpu/x86/vm/x86_32.ad
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File 6827605 Sdiff src/cpu/x86/vm

src/cpu/x86/vm/x86_32.ad

Print this page




3684       if (os::is_MP()) {   masm.lock();    }
3685       masm.cmpxchgptr(tmpReg, Address(objReg, 0)); // Uses EAX which is box
3686       // Intention fall-thru into DONE_LABEL
3687 
3688 
3689       // DONE_LABEL is a hot target - we'd really like to place it at the
3690       // start of cache line by padding with NOPs.
3691       // See the AMD and Intel software optimization manuals for the
3692       // most efficient "long" NOP encodings.
3693       // Unfortunately none of our alignment mechanisms suffice.
3694       if ((EmitSync & 65536) == 0) {
3695          masm.bind (CheckSucc) ;
3696       }
3697       masm.bind(DONE_LABEL);
3698 
3699       // Avoid branch to branch on AMD processors
3700       if (EmitSync & 32768) { masm.nop() ; }
3701     }
3702   %}
3703 
3704   enc_class enc_String_Compare(eDIRegP str1, eSIRegP str2, regXD tmp1, regXD tmp2,
3705                         eAXRegI tmp3, eBXRegI tmp4, eCXRegI result) %{
3706     Label ECX_GOOD_LABEL, LENGTH_DIFF_LABEL,
3707           POP_LABEL, DONE_LABEL, CONT_LABEL,
3708           WHILE_HEAD_LABEL;
3709     MacroAssembler masm(&cbuf);
3710 
3711     XMMRegister tmp1Reg   = as_XMMRegister($tmp1$$reg);
3712     XMMRegister tmp2Reg   = as_XMMRegister($tmp2$$reg);
3713 
3714     // Get the first character position in both strings
3715     //         [8] char array, [12] offset, [16] count
3716     int value_offset  = java_lang_String::value_offset_in_bytes();
3717     int offset_offset = java_lang_String::offset_offset_in_bytes();
3718     int count_offset  = java_lang_String::count_offset_in_bytes();
3719     int base_offset   = arrayOopDesc::base_offset_in_bytes(T_CHAR);
3720 
3721     masm.movptr(rax, Address(rsi, value_offset));
3722     masm.movl(rcx, Address(rsi, offset_offset));
3723     masm.lea(rax, Address(rax, rcx, Address::times_2, base_offset));
3724     masm.movptr(rbx, Address(rdi, value_offset));
3725     masm.movl(rcx, Address(rdi, offset_offset));
3726     masm.lea(rbx, Address(rbx, rcx, Address::times_2, base_offset));
3727 
3728     // Compute the minimum of the string lengths(rsi) and the
3729     // difference of the string lengths (stack)
3730 
3731     if (VM_Version::supports_cmov()) {
3732       masm.movl(rdi, Address(rdi, count_offset));
3733       masm.movl(rsi, Address(rsi, count_offset));
3734       masm.movl(rcx, rdi);
3735       masm.subl(rdi, rsi);
3736       masm.push(rdi);
3737       masm.cmovl(Assembler::lessEqual, rsi, rcx);
3738     } else {
3739       masm.movl(rdi, Address(rdi, count_offset));
3740       masm.movl(rcx, Address(rsi, count_offset));
3741       masm.movl(rsi, rdi);
3742       masm.subl(rdi, rcx);
3743       masm.push(rdi);
3744       masm.jccb(Assembler::lessEqual, ECX_GOOD_LABEL);
3745       masm.movl(rsi, rcx);
3746       // rsi holds min, rcx is unused
3747     }
3748 
3749     // Is the minimum length zero?
3750     masm.bind(ECX_GOOD_LABEL);
3751     masm.testl(rsi, rsi);
3752     masm.jcc(Assembler::zero, LENGTH_DIFF_LABEL);
3753 
3754     // Load first characters
3755     masm.load_unsigned_short(rcx, Address(rbx, 0));
3756     masm.load_unsigned_short(rdi, Address(rax, 0));
3757 
3758     // Compare first characters
3759     masm.subl(rcx, rdi);
3760     masm.jcc(Assembler::notZero,  POP_LABEL);
3761     masm.decrementl(rsi);
3762     masm.jcc(Assembler::zero, LENGTH_DIFF_LABEL);
3763 
3764     {
3765       // Check after comparing first character to see if strings are equivalent
3766       Label LSkip2;
3767       // Check if the strings start at same location
3768       masm.cmpptr(rbx,rax);
3769       masm.jccb(Assembler::notEqual, LSkip2);
3770 
3771       // Check if the length difference is zero (from stack)
3772       masm.cmpl(Address(rsp, 0), 0x0);
3773       masm.jcc(Assembler::equal,  LENGTH_DIFF_LABEL);
3774 
3775       // Strings might not be equivalent
3776       masm.bind(LSkip2);
3777     }
3778 
3779    // Advance to next character
3780     masm.addptr(rax, 2);
3781     masm.addptr(rbx, 2);
3782 
3783     if (UseSSE42Intrinsics) {
3784       // With SSE4.2, use double quad vector compare
3785       Label COMPARE_VECTORS, VECTOR_NOT_EQUAL, COMPARE_TAIL;
3786       // Setup to compare 16-byte vectors
3787       masm.movl(rdi, rsi);
3788       masm.andl(rsi, 0xfffffff8); // rsi holds the vector count
3789       masm.andl(rdi, 0x00000007); // rdi holds the tail count
3790       masm.testl(rsi, rsi);
3791       masm.jccb(Assembler::zero, COMPARE_TAIL);
3792 
3793       masm.lea(rax, Address(rax, rsi, Address::times_2));
3794       masm.lea(rbx, Address(rbx, rsi, Address::times_2));
3795       masm.negl(rsi);
3796 
3797       masm.bind(COMPARE_VECTORS);
3798       masm.movdqu(tmp1Reg, Address(rax, rsi, Address::times_2));
3799       masm.movdqu(tmp2Reg, Address(rbx, rsi, Address::times_2));
3800       masm.pxor(tmp1Reg, tmp2Reg);
3801       masm.ptest(tmp1Reg, tmp1Reg);
3802       masm.jccb(Assembler::notZero, VECTOR_NOT_EQUAL);
3803       masm.addl(rsi, 8);
3804       masm.jcc(Assembler::notZero, COMPARE_VECTORS);
3805       masm.jmpb(COMPARE_TAIL);
3806 
3807       // Mismatched characters in the vectors
3808       masm.bind(VECTOR_NOT_EQUAL);
3809       masm.lea(rax, Address(rax, rsi, Address::times_2));
3810       masm.lea(rbx, Address(rbx, rsi, Address::times_2));
3811       masm.movl(rdi, 8);
3812 
3813       // Compare tail (< 8 chars), or rescan last vectors to
3814       // find 1st mismatched characters
3815       masm.bind(COMPARE_TAIL);
3816       masm.testl(rdi, rdi);
3817       masm.jccb(Assembler::zero, LENGTH_DIFF_LABEL);
3818       masm.movl(rsi, rdi);
3819       // Fallthru to tail compare
3820     }
3821 
3822     //Shift rax, and rbx, to the end of the arrays, negate min
3823     masm.lea(rax, Address(rax, rsi, Address::times_2, 0));
3824     masm.lea(rbx, Address(rbx, rsi, Address::times_2, 0));
3825     masm.negl(rsi);
3826 
3827     // Compare the rest of the characters
3828     masm.bind(WHILE_HEAD_LABEL);
3829     masm.load_unsigned_short(rcx, Address(rbx, rsi, Address::times_2, 0));
3830     masm.load_unsigned_short(rdi, Address(rax, rsi, Address::times_2, 0));
3831     masm.subl(rcx, rdi);
3832     masm.jccb(Assembler::notZero, POP_LABEL);
3833     masm.incrementl(rsi);
3834     masm.jcc(Assembler::notZero, WHILE_HEAD_LABEL);
3835 
3836     // Strings are equal up to min length.  Return the length difference.
3837     masm.bind(LENGTH_DIFF_LABEL);
3838     masm.pop(rcx);
3839     masm.jmpb(DONE_LABEL);
3840 
3841     // Discard the stored length difference
3842     masm.bind(POP_LABEL);
3843     masm.addptr(rsp, 4);
3844 
3845     // That's it
3846     masm.bind(DONE_LABEL);
3847   %}
3848 
3849  enc_class enc_String_Equals(eDIRegP str1, eSIRegP str2, regXD tmp1, regXD tmp2,
3850                        eBXRegI tmp3, eCXRegI tmp4, eAXRegI result) %{
3851     Label RET_TRUE, RET_FALSE, DONE, COMPARE_VECTORS, COMPARE_CHAR;
3852     MacroAssembler masm(&cbuf);
3853 
3854     XMMRegister tmp1Reg   = as_XMMRegister($tmp1$$reg);
3855     XMMRegister tmp2Reg   = as_XMMRegister($tmp2$$reg);
3856 
3857     int value_offset  = java_lang_String::value_offset_in_bytes();
3858     int offset_offset = java_lang_String::offset_offset_in_bytes();
3859     int count_offset  = java_lang_String::count_offset_in_bytes();
3860     int base_offset   = arrayOopDesc::base_offset_in_bytes(T_CHAR);
3861 
3862     // does source == target string?
3863     masm.cmpptr(rdi, rsi);
3864     masm.jcc(Assembler::equal, RET_TRUE);
3865 
3866     // get and compare counts
3867     masm.movl(rcx, Address(rdi, count_offset));
3868     masm.movl(rax, Address(rsi, count_offset));
3869     masm.cmpl(rcx, rax);
3870     masm.jcc(Assembler::notEqual, RET_FALSE);
3871     masm.testl(rax, rax);
3872     masm.jcc(Assembler::zero, RET_TRUE);
3873 
3874     // get source string offset and value
3875     masm.movptr(rbx, Address(rsi, value_offset));
3876     masm.movl(rax, Address(rsi, offset_offset));
3877     masm.leal(rsi, Address(rbx, rax, Address::times_2, base_offset));
3878 
3879     // get compare string offset and value
3880     masm.movptr(rbx, Address(rdi, value_offset));
3881     masm.movl(rax, Address(rdi, offset_offset));
3882     masm.leal(rdi, Address(rbx, rax, Address::times_2, base_offset));
3883 
3884     // Set byte count
3885     masm.shll(rcx, 1);
3886     masm.movl(rax, rcx);
3887 
3888     if (UseSSE42Intrinsics) {
3889       // With SSE4.2, use double quad vector compare
3890       Label COMPARE_WIDE_VECTORS, COMPARE_TAIL;
3891       // Compare 16-byte vectors
3892       masm.andl(rcx, 0xfffffff0);  // vector count (in bytes)
3893       masm.andl(rax, 0x0000000e);  // tail count (in bytes)
3894       masm.testl(rcx, rcx);
3895       masm.jccb(Assembler::zero, COMPARE_TAIL);
3896       masm.lea(rdi, Address(rdi, rcx, Address::times_1));
3897       masm.lea(rsi, Address(rsi, rcx, Address::times_1));
3898       masm.negl(rcx);
3899 
3900       masm.bind(COMPARE_WIDE_VECTORS);
3901       masm.movdqu(tmp1Reg, Address(rdi, rcx, Address::times_1));
3902       masm.movdqu(tmp2Reg, Address(rsi, rcx, Address::times_1));
3903       masm.pxor(tmp1Reg, tmp2Reg);
3904       masm.ptest(tmp1Reg, tmp1Reg);
3905       masm.jccb(Assembler::notZero, RET_FALSE);
3906       masm.addl(rcx, 16);
3907       masm.jcc(Assembler::notZero, COMPARE_WIDE_VECTORS);
3908       masm.bind(COMPARE_TAIL);
3909       masm.movl(rcx, rax);
3910       // Fallthru to tail compare
3911     }
3912 
3913     // Compare 4-byte vectors
3914     masm.andl(rcx, 0xfffffffc);  // vector count (in bytes)
3915     masm.andl(rax, 0x00000002);  // tail char (in bytes)

3916     masm.testl(rcx, rcx);
3917     masm.jccb(Assembler::zero, COMPARE_CHAR);
3918     masm.lea(rdi, Address(rdi, rcx, Address::times_1));
3919     masm.lea(rsi, Address(rsi, rcx, Address::times_1));
3920     masm.negl(rcx);
3921 
3922     masm.bind(COMPARE_VECTORS);
3923     masm.movl(rbx, Address(rdi, rcx, Address::times_1));
3924     masm.cmpl(rbx, Address(rsi, rcx, Address::times_1));
3925     masm.jccb(Assembler::notEqual, RET_FALSE);
3926     masm.addl(rcx, 4);
3927     masm.jcc(Assembler::notZero, COMPARE_VECTORS);
3928 
3929     // Compare trailing char (final 2 bytes), if any
3930     masm.bind(COMPARE_CHAR);
3931     masm.testl(rax, rax);
3932     masm.jccb(Assembler::zero, RET_TRUE);
3933     masm.load_unsigned_short(rbx, Address(rdi, 0));
3934     masm.load_unsigned_short(rcx, Address(rsi, 0));
3935     masm.cmpl(rbx, rcx);
3936     masm.jccb(Assembler::notEqual, RET_FALSE);
3937 
3938     masm.bind(RET_TRUE);
3939     masm.movl(rax, 1);   // return true
3940     masm.jmpb(DONE);
3941 
3942     masm.bind(RET_FALSE);
3943     masm.xorl(rax, rax); // return false
3944 
3945     masm.bind(DONE);
3946     %}
3947 
3948  enc_class enc_String_IndexOf(eSIRegP str1, eDIRegP str2, regXD tmp1, eAXRegI tmp2,
3949                         eCXRegI tmp3, eDXRegI tmp4, eBXRegI result) %{
3950     // SSE4.2 version
3951     Label LOAD_SUBSTR, PREP_FOR_SCAN, SCAN_TO_SUBSTR,
3952           SCAN_SUBSTR, RET_NEG_ONE, RET_NOT_FOUND, CLEANUP, DONE;
3953     MacroAssembler masm(&cbuf);
3954 
3955     XMMRegister tmp1Reg   = as_XMMRegister($tmp1$$reg);
3956 
3957     // Get the first character position in both strings
3958     //         [8] char array, [12] offset, [16] count
3959     int value_offset  = java_lang_String::value_offset_in_bytes();
3960     int offset_offset = java_lang_String::offset_offset_in_bytes();
3961     int count_offset  = java_lang_String::count_offset_in_bytes();
3962     int base_offset   = arrayOopDesc::base_offset_in_bytes(T_CHAR);
3963 
3964     // Get counts for string and substr
3965     masm.movl(rdx, Address(rsi, count_offset));
3966     masm.movl(rax, Address(rdi, count_offset));
3967     // Check for substr count > string count
3968     masm.cmpl(rax, rdx);
3969     masm.jcc(Assembler::greater, RET_NEG_ONE);
3970 
3971     // Start the indexOf operation
3972     // Get start addr of string
3973     masm.movptr(rbx, Address(rsi, value_offset));
3974     masm.movl(rcx, Address(rsi, offset_offset));
3975     masm.lea(rsi, Address(rbx, rcx, Address::times_2, base_offset));
3976     masm.push(rsi);
3977 
3978     // Get start addr of substr
3979     masm.movptr(rbx, Address(rdi, value_offset));
3980     masm.movl(rcx, Address(rdi, offset_offset));
3981     masm.lea(rdi, Address(rbx, rcx, Address::times_2, base_offset));
3982     masm.push(rdi);
3983     masm.push(rax);
3984     masm.jmpb(PREP_FOR_SCAN);
3985 
3986     // Substr count saved at sp
3987     // Substr saved at sp+4
3988     // String saved at sp+8
3989 
3990     // Prep to load substr for scan
3991     masm.bind(LOAD_SUBSTR);
3992     masm.movptr(rdi, Address(rsp, 4));
3993     masm.movl(rax, Address(rsp, 0));
3994 
3995     // Load substr
3996     masm.bind(PREP_FOR_SCAN);
3997     masm.movdqu(tmp1Reg, Address(rdi, 0));
3998     masm.addl(rdx, 8);        // prime the loop
3999     masm.subptr(rsi, 16);
4000 
4001     // Scan string for substr in 16-byte vectors
4002     masm.bind(SCAN_TO_SUBSTR);
4003     masm.subl(rdx, 8);
4004     masm.addptr(rsi, 16);
4005     masm.pcmpestri(tmp1Reg, Address(rsi, 0), 0x0d);
4006     masm.jcc(Assembler::above, SCAN_TO_SUBSTR);     // CF == 0 && ZF == 0
4007     masm.jccb(Assembler::aboveEqual, RET_NOT_FOUND); // CF == 0
4008 
4009     // Fallthru: found a potential substr
4010 
4011     // Make sure string is still long enough
4012     masm.subl(rdx, rcx);
4013     masm.cmpl(rdx, rax);
4014     masm.jccb(Assembler::negative, RET_NOT_FOUND);
4015     // Compute start addr of substr
4016     masm.lea(rsi, Address(rsi, rcx, Address::times_2));
4017     masm.movptr(rbx, rsi);
4018 
4019     // Compare potential substr
4020     masm.addl(rdx, 8);        // prime the loop
4021     masm.addl(rax, 8);
4022     masm.subptr(rsi, 16);
4023     masm.subptr(rdi, 16);
4024 
4025     // Scan 16-byte vectors of string and substr
4026     masm.bind(SCAN_SUBSTR);
4027     masm.subl(rax, 8);
4028     masm.subl(rdx, 8);
4029     masm.addptr(rsi, 16);
4030     masm.addptr(rdi, 16);
4031     masm.movdqu(tmp1Reg, Address(rdi, 0));
4032     masm.pcmpestri(tmp1Reg, Address(rsi, 0), 0x0d);
4033     masm.jcc(Assembler::noOverflow, LOAD_SUBSTR);   // OF == 0
4034     masm.jcc(Assembler::positive, SCAN_SUBSTR);     // SF == 0
4035 
4036     // Compute substr offset
4037     masm.movptr(rsi, Address(rsp, 8));
4038     masm.subptr(rbx, rsi);
4039     masm.shrl(rbx, 1);
4040     masm.jmpb(CLEANUP);
4041 
4042     masm.bind(RET_NEG_ONE);
4043     masm.movl(rbx, -1);
4044     masm.jmpb(DONE);
4045 
4046     masm.bind(RET_NOT_FOUND);
4047     masm.movl(rbx, -1);
4048 
4049     masm.bind(CLEANUP);
4050     masm.addptr(rsp, 12);
4051 
4052     masm.bind(DONE);
4053   %}
4054 
4055   enc_class enc_Array_Equals(eDIRegP ary1, eSIRegP ary2, regXD tmp1, regXD tmp2,
4056                              eBXRegI tmp3, eDXRegI tmp4, eAXRegI result) %{
4057     Label TRUE_LABEL, FALSE_LABEL, DONE, COMPARE_VECTORS, COMPARE_CHAR;
4058     MacroAssembler masm(&cbuf);
4059 
4060     XMMRegister tmp1Reg   = as_XMMRegister($tmp1$$reg);
4061     XMMRegister tmp2Reg   = as_XMMRegister($tmp2$$reg);
4062     Register ary1Reg      = as_Register($ary1$$reg);
4063     Register ary2Reg      = as_Register($ary2$$reg);
4064     Register tmp3Reg      = as_Register($tmp3$$reg);
4065     Register tmp4Reg      = as_Register($tmp4$$reg);
4066     Register resultReg    = as_Register($result$$reg);
4067 
4068     int length_offset  = arrayOopDesc::length_offset_in_bytes();
4069     int base_offset    = arrayOopDesc::base_offset_in_bytes(T_CHAR);
4070 
4071     // Check the input args
4072     masm.cmpptr(ary1Reg, ary2Reg);
4073     masm.jcc(Assembler::equal, TRUE_LABEL);
4074     masm.testptr(ary1Reg, ary1Reg);
4075     masm.jcc(Assembler::zero, FALSE_LABEL);
4076     masm.testptr(ary2Reg, ary2Reg);
4077     masm.jcc(Assembler::zero, FALSE_LABEL);
4078 
4079     // Check the lengths
4080     masm.movl(tmp4Reg, Address(ary1Reg, length_offset));
4081     masm.movl(resultReg, Address(ary2Reg, length_offset));
4082     masm.cmpl(tmp4Reg, resultReg);
4083     masm.jcc(Assembler::notEqual, FALSE_LABEL);
4084     masm.testl(resultReg, resultReg);
4085     masm.jcc(Assembler::zero, TRUE_LABEL);
4086 
4087     // Load array addrs
4088     masm.lea(ary1Reg, Address(ary1Reg, base_offset));
4089     masm.lea(ary2Reg, Address(ary2Reg, base_offset));
4090 
4091     // Set byte count
4092     masm.shll(tmp4Reg, 1);
4093     masm.movl(resultReg, tmp4Reg);
4094 
4095     if (UseSSE42Intrinsics) {
4096       // With SSE4.2, use double quad vector compare
4097       Label COMPARE_WIDE_VECTORS, COMPARE_TAIL;
4098       // Compare 16-byte vectors
4099       masm.andl(tmp4Reg, 0xfffffff0);    // vector count (in bytes)
4100       masm.andl(resultReg, 0x0000000e);  // tail count (in bytes)
4101       masm.testl(tmp4Reg, tmp4Reg);
4102       masm.jccb(Assembler::zero, COMPARE_TAIL);
4103       masm.lea(ary1Reg, Address(ary1Reg, tmp4Reg, Address::times_1));
4104       masm.lea(ary2Reg, Address(ary2Reg, tmp4Reg, Address::times_1));
4105       masm.negl(tmp4Reg);
4106 
4107       masm.bind(COMPARE_WIDE_VECTORS);
4108       masm.movdqu(tmp1Reg, Address(ary1Reg, tmp4Reg, Address::times_1));
4109       masm.movdqu(tmp2Reg, Address(ary2Reg, tmp4Reg, Address::times_1));
4110       masm.pxor(tmp1Reg, tmp2Reg);
4111       masm.ptest(tmp1Reg, tmp1Reg);
4112 
4113       masm.jccb(Assembler::notZero, FALSE_LABEL);
4114       masm.addl(tmp4Reg, 16);
4115       masm.jcc(Assembler::notZero, COMPARE_WIDE_VECTORS);
4116       masm.bind(COMPARE_TAIL);
4117       masm.movl(tmp4Reg, resultReg);
4118       // Fallthru to tail compare
4119     }
4120 
4121     // Compare 4-byte vectors
4122     masm.andl(tmp4Reg, 0xfffffffc);    // vector count (in bytes)
4123     masm.andl(resultReg, 0x00000002);  // tail char (in bytes)
4124     masm.testl(tmp4Reg, tmp4Reg);
4125     masm.jccb(Assembler::zero, COMPARE_CHAR);
4126     masm.lea(ary1Reg, Address(ary1Reg, tmp4Reg, Address::times_1));
4127     masm.lea(ary2Reg, Address(ary2Reg, tmp4Reg, Address::times_1));
4128     masm.negl(tmp4Reg);
4129 
4130     masm.bind(COMPARE_VECTORS);
4131     masm.movl(tmp3Reg, Address(ary1Reg, tmp4Reg, Address::times_1));
4132     masm.cmpl(tmp3Reg, Address(ary2Reg, tmp4Reg, Address::times_1));
4133     masm.jccb(Assembler::notEqual, FALSE_LABEL);
4134     masm.addl(tmp4Reg, 4);
4135     masm.jcc(Assembler::notZero, COMPARE_VECTORS);
4136 
4137     // Compare trailing char (final 2 bytes), if any
4138     masm.bind(COMPARE_CHAR);
4139     masm.testl(resultReg, resultReg);
4140     masm.jccb(Assembler::zero, TRUE_LABEL);
4141     masm.load_unsigned_short(tmp3Reg, Address(ary1Reg, 0));
4142     masm.load_unsigned_short(tmp4Reg, Address(ary2Reg, 0));
4143     masm.cmpl(tmp3Reg, tmp4Reg);
4144     masm.jccb(Assembler::notEqual, FALSE_LABEL);
4145 
4146     masm.bind(TRUE_LABEL);
4147     masm.movl(resultReg, 1);   // return true
4148     masm.jmpb(DONE);
4149 
4150     masm.bind(FALSE_LABEL);
4151     masm.xorl(resultReg, resultReg); // return false
4152 
4153     // That's it
4154     masm.bind(DONE);
4155   %}
4156 
4157   enc_class enc_pop_rdx() %{
4158     emit_opcode(cbuf,0x5A);
4159   %}
4160 
4161   enc_class enc_rethrow() %{
4162     cbuf.set_inst_mark();
4163     emit_opcode(cbuf, 0xE9);        // jmp    entry
4164     emit_d32_reloc(cbuf, (int)OptoRuntime::rethrow_stub() - ((int)cbuf.code_end())-4,
4165                    runtime_call_Relocation::spec(), RELOC_IMM32 );
4166   %}
4167 
4168 
4169   // Convert a double to an int.  Java semantics require we do complex
4170   // manglelations in the corner cases.  So we set the rounding mode to
4171   // 'zero', store the darned double down as an int, and reset the
4172   // rounding mode to 'nearest'.  The hardware throws an exception which
4173   // patches up the correct value directly to the stack.
4174   enc_class D2I_encoding( regD src ) %{
4175     // Flip to round-to-zero mode.  We attempted to allow invalid-op
4176     // exceptions here, so that a NAN or other corner-case value will


12701   format %{ "PXOR  $dst,$dst\t! replicate2F" %}
12702   ins_encode( pxor(dst, dst));
12703   ins_pipe( fpu_reg_reg );
12704 %}
12705 
12706 // =======================================================================
12707 // fast clearing of an array
12708 instruct rep_stos(eCXRegI cnt, eDIRegP base, eAXRegI zero, Universe dummy, eFlagsReg cr) %{
12709   match(Set dummy (ClearArray cnt base));
12710   effect(USE_KILL cnt, USE_KILL base, KILL zero, KILL cr);
12711   format %{ "SHL    ECX,1\t# Convert doublewords to words\n\t"
12712             "XOR    EAX,EAX\n\t"
12713             "REP STOS\t# store EAX into [EDI++] while ECX--" %}
12714   opcode(0,0x4);
12715   ins_encode( Opcode(0xD1), RegOpc(ECX),
12716               OpcRegReg(0x33,EAX,EAX),
12717               Opcode(0xF3), Opcode(0xAB) );
12718   ins_pipe( pipe_slow );
12719 %}
12720 
12721 instruct string_compare(eDIRegP str1, eSIRegP str2, regXD tmp1, regXD tmp2,
12722                         eAXRegI tmp3, eBXRegI tmp4, eCXRegI result, eFlagsReg cr) %{
12723   match(Set result (StrComp str1 str2));
12724   effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, KILL tmp3, KILL tmp4, KILL cr);
12725   //ins_cost(300);
12726 
12727   format %{ "String Compare $str1,$str2 -> $result    // KILL EAX, EBX" %}
12728   ins_encode( enc_String_Compare(str1, str2, tmp1, tmp2, tmp3, tmp4, result) );




12729   ins_pipe( pipe_slow );
12730 %}
12731 
12732 // fast string equals
12733 instruct string_equals(eDIRegP str1, eSIRegP str2, regXD tmp1, regXD tmp2,
12734                        eBXRegI tmp3, eCXRegI tmp4, eAXRegI result, eFlagsReg cr) %{
12735   match(Set result (StrEquals str1 str2));
12736   effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, KILL tmp3, KILL tmp4, KILL cr);
12737 
12738   format %{ "String Equals $str1,$str2 -> $result    // KILL EBX, ECX" %}
12739   ins_encode( enc_String_Equals(tmp1, tmp2, str1, str2, tmp3, tmp4, result) );




12740   ins_pipe( pipe_slow );
12741 %}
12742 
12743 instruct string_indexof(eSIRegP str1, eDIRegP str2, regXD tmp1, eAXRegI tmp2,
12744                         eCXRegI tmp3, eDXRegI tmp4, eBXRegI result, eFlagsReg cr) %{
12745   predicate(UseSSE42Intrinsics);
12746   match(Set result (StrIndexOf str1 str2));
12747   effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, KILL tmp2, KILL tmp3, KILL tmp4, KILL cr);
12748 
12749   format %{ "String IndexOf $str1,$str2 -> $result    // KILL EAX, ECX, EDX" %}
12750   ins_encode( enc_String_IndexOf(str1, str2, tmp1, tmp2, tmp3, tmp4, result) );




12751   ins_pipe( pipe_slow );
12752 %}
12753 
12754 // fast array equals
12755 instruct array_equals(eDIRegP ary1, eSIRegP ary2, regXD tmp1, regXD tmp2, eBXRegI tmp3,
12756                       eDXRegI tmp4, eAXRegI result, eFlagsReg cr) %{

12757   match(Set result (AryEq ary1 ary2));
12758   effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr);
12759   //ins_cost(300);
12760 
12761   format %{ "Array Equals $ary1,$ary2 -> $result    // KILL EBX, EDX" %}
12762   ins_encode( enc_Array_Equals(ary1, ary2, tmp1, tmp2, tmp3, tmp4, result) );




12763   ins_pipe( pipe_slow );
12764 %}
12765 
12766 //----------Control Flow Instructions------------------------------------------
12767 // Signed compare Instructions
12768 instruct compI_eReg(eFlagsReg cr, eRegI op1, eRegI op2) %{
12769   match(Set cr (CmpI op1 op2));
12770   effect( DEF cr, USE op1, USE op2 );
12771   format %{ "CMP    $op1,$op2" %}
12772   opcode(0x3B);  /* Opcode 3B /r */
12773   ins_encode( OpcP, RegReg( op1, op2) );
12774   ins_pipe( ialu_cr_reg_reg );
12775 %}
12776 
12777 instruct compI_eReg_imm(eFlagsReg cr, eRegI op1, immI op2) %{
12778   match(Set cr (CmpI op1 op2));
12779   effect( DEF cr, USE op1 );
12780   format %{ "CMP    $op1,$op2" %}
12781   opcode(0x81,0x07);  /* Opcode 81 /7 */
12782   // ins_encode( RegImm( op1, op2) );  /* Was CmpImm */




3684       if (os::is_MP()) {   masm.lock();    }
3685       masm.cmpxchgptr(tmpReg, Address(objReg, 0)); // Uses EAX which is box
3686       // Intention fall-thru into DONE_LABEL
3687 
3688 
3689       // DONE_LABEL is a hot target - we'd really like to place it at the
3690       // start of cache line by padding with NOPs.
3691       // See the AMD and Intel software optimization manuals for the
3692       // most efficient "long" NOP encodings.
3693       // Unfortunately none of our alignment mechanisms suffice.
3694       if ((EmitSync & 65536) == 0) {
3695          masm.bind (CheckSucc) ;
3696       }
3697       masm.bind(DONE_LABEL);
3698 
3699       // Avoid branch to branch on AMD processors
3700       if (EmitSync & 32768) { masm.nop() ; }
3701     }
3702   %}
3703 






3704 






























































































































































































































































































































































































































































3705   enc_class enc_pop_rdx() %{
3706     emit_opcode(cbuf,0x5A);
3707   %}
3708 
3709   enc_class enc_rethrow() %{
3710     cbuf.set_inst_mark();
3711     emit_opcode(cbuf, 0xE9);        // jmp    entry
3712     emit_d32_reloc(cbuf, (int)OptoRuntime::rethrow_stub() - ((int)cbuf.code_end())-4,
3713                    runtime_call_Relocation::spec(), RELOC_IMM32 );
3714   %}
3715 
3716 
3717   // Convert a double to an int.  Java semantics require we do complex
3718   // manglelations in the corner cases.  So we set the rounding mode to
3719   // 'zero', store the darned double down as an int, and reset the
3720   // rounding mode to 'nearest'.  The hardware throws an exception which
3721   // patches up the correct value directly to the stack.
3722   enc_class D2I_encoding( regD src ) %{
3723     // Flip to round-to-zero mode.  We attempted to allow invalid-op
3724     // exceptions here, so that a NAN or other corner-case value will


12249   format %{ "PXOR  $dst,$dst\t! replicate2F" %}
12250   ins_encode( pxor(dst, dst));
12251   ins_pipe( fpu_reg_reg );
12252 %}
12253 
12254 // =======================================================================
12255 // fast clearing of an array
12256 instruct rep_stos(eCXRegI cnt, eDIRegP base, eAXRegI zero, Universe dummy, eFlagsReg cr) %{
12257   match(Set dummy (ClearArray cnt base));
12258   effect(USE_KILL cnt, USE_KILL base, KILL zero, KILL cr);
12259   format %{ "SHL    ECX,1\t# Convert doublewords to words\n\t"
12260             "XOR    EAX,EAX\n\t"
12261             "REP STOS\t# store EAX into [EDI++] while ECX--" %}
12262   opcode(0,0x4);
12263   ins_encode( Opcode(0xD1), RegOpc(ECX),
12264               OpcRegReg(0x33,EAX,EAX),
12265               Opcode(0xF3), Opcode(0xAB) );
12266   ins_pipe( pipe_slow );
12267 %}
12268 
12269 instruct string_compare(eDIRegP str1, eCXRegI cnt1, eSIRegP str2, eBXRegI cnt2,
12270                         eAXRegI result, regXD tmp1, regXD tmp2, eFlagsReg cr) %{
12271   match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
12272   effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);

12273 
12274   format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result   // KILL $tmp1, $tmp2" %}
12275   ins_encode %{
12276     __ string_compare($str1$$Register, $str2$$Register,
12277                       $cnt1$$Register, $cnt2$$Register, $result$$Register,
12278                       $tmp1$$XMMRegister, $tmp2$$XMMRegister);
12279   %}
12280   ins_pipe( pipe_slow );
12281 %}
12282 
12283 // fast string equals
12284 instruct string_equals(eDIRegP str1, eSIRegP str2, eCXRegI cnt, eAXRegI result,
12285                        regXD tmp1, regXD tmp2, eBXRegI tmp3, eFlagsReg cr) %{
12286   match(Set result (StrEquals (Binary str1 str2) cnt));
12287   effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr);
12288 
12289   format %{ "String Equals $str1,$str2,$cnt -> $result    // KILL $tmp1, $tmp2, $tmp3" %}
12290   ins_encode %{
12291     __ char_arrays_equals(false, $str1$$Register, $str2$$Register,
12292                           $cnt$$Register, $result$$Register, $tmp3$$Register,
12293                           $tmp1$$XMMRegister, $tmp2$$XMMRegister);
12294   %}
12295   ins_pipe( pipe_slow );
12296 %}
12297 
12298 instruct string_indexof(eDIRegP str1, eDXRegI cnt1, eSIRegP str2, eAXRegI cnt2,
12299                         eBXRegI result, regXD tmp1, eCXRegI tmp2, eFlagsReg cr) %{
12300   predicate(UseSSE42Intrinsics);
12301   match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
12302   effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp2, KILL cr);
12303 
12304   format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result   // KILL $tmp2, $tmp1" %}
12305   ins_encode %{
12306     __ string_indexof($str1$$Register, $str2$$Register,
12307                       $cnt1$$Register, $cnt2$$Register, $result$$Register,
12308                       $tmp1$$XMMRegister, $tmp2$$Register);
12309   %}
12310   ins_pipe( pipe_slow );
12311 %}
12312 
12313 // fast array equals
12314 instruct array_equals(eDIRegP ary1, eSIRegP ary2, eAXRegI result,
12315                       regXD tmp1, regXD tmp2, eCXRegI tmp3, eBXRegI tmp4, eFlagsReg cr)
12316 %{
12317   match(Set result (AryEq ary1 ary2));
12318   effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr);
12319   //ins_cost(300);
12320 
12321   format %{ "Array Equals $ary1,$ary2 -> $result   // KILL $tmp1, $tmp2, $tmp3, $tmp4" %}
12322   ins_encode %{
12323     __ char_arrays_equals(true, $ary1$$Register, $ary2$$Register,
12324                           $tmp3$$Register, $result$$Register, $tmp4$$Register,
12325                           $tmp1$$XMMRegister, $tmp2$$XMMRegister);
12326   %}
12327   ins_pipe( pipe_slow );
12328 %}
12329 
12330 //----------Control Flow Instructions------------------------------------------
12331 // Signed compare Instructions
12332 instruct compI_eReg(eFlagsReg cr, eRegI op1, eRegI op2) %{
12333   match(Set cr (CmpI op1 op2));
12334   effect( DEF cr, USE op1, USE op2 );
12335   format %{ "CMP    $op1,$op2" %}
12336   opcode(0x3B);  /* Opcode 3B /r */
12337   ins_encode( OpcP, RegReg( op1, op2) );
12338   ins_pipe( ialu_cr_reg_reg );
12339 %}
12340 
12341 instruct compI_eReg_imm(eFlagsReg cr, eRegI op1, immI op2) %{
12342   match(Set cr (CmpI op1 op2));
12343   effect( DEF cr, USE op1 );
12344   format %{ "CMP    $op1,$op2" %}
12345   opcode(0x81,0x07);  /* Opcode 81 /7 */
12346   // ins_encode( RegImm( op1, op2) );  /* Was CmpImm */


src/cpu/x86/vm/x86_32.ad
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File