168 __ MacroAssembler::verify_FPU(1, "generate_return_entry_for compiled"); |
168 __ MacroAssembler::verify_FPU(1, "generate_return_entry_for compiled"); |
169 } else { |
169 } else { |
170 __ MacroAssembler::verify_FPU(0, "generate_return_entry_for compiled"); |
170 __ MacroAssembler::verify_FPU(0, "generate_return_entry_for compiled"); |
171 } |
171 } |
172 |
172 |
173 // In SSE mode, interpreter returns FP results in xmm0 but they need |
173 if (state == ftos) { |
174 // to end up back on the FPU so it can operate on them. |
174 __ MacroAssembler::verify_FPU(UseSSE >= 1 ? 0 : 1, "generate_return_entry_for in interpreter"); |
175 if (state == ftos && UseSSE >= 1) { |
175 } else if (state == dtos) { |
176 __ subptr(rsp, wordSize); |
176 __ MacroAssembler::verify_FPU(UseSSE >= 2 ? 0 : 1, "generate_return_entry_for in interpreter"); |
177 __ movflt(Address(rsp, 0), xmm0); |
177 } |
178 __ fld_s(Address(rsp, 0)); |
|
179 __ addptr(rsp, wordSize); |
|
180 } else if (state == dtos && UseSSE >= 2) { |
|
181 __ subptr(rsp, 2*wordSize); |
|
182 __ movdbl(Address(rsp, 0), xmm0); |
|
183 __ fld_d(Address(rsp, 0)); |
|
184 __ addptr(rsp, 2*wordSize); |
|
185 } |
|
186 |
|
187 __ MacroAssembler::verify_FPU(state == ftos || state == dtos ? 1 : 0, "generate_return_entry_for in interpreter"); |
|
188 |
178 |
189 // Restore stack bottom in case i2c adjusted stack |
179 // Restore stack bottom in case i2c adjusted stack |
190 __ movptr(rsp, Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize)); |
180 __ movptr(rsp, Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize)); |
191 // and NULL it as marker that rsp is now tos until next java call |
181 // and NULL it as marker that rsp is now tos until next java call |
192 __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD); |
182 __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD); |
215 |
205 |
216 |
206 |
217 address TemplateInterpreterGenerator::generate_deopt_entry_for(TosState state, int step) { |
207 address TemplateInterpreterGenerator::generate_deopt_entry_for(TosState state, int step) { |
218 address entry = __ pc(); |
208 address entry = __ pc(); |
219 |
209 |
220 // In SSE mode, FP results are in xmm0 |
210 if (state == ftos) { |
221 if (state == ftos && UseSSE > 0) { |
211 __ MacroAssembler::verify_FPU(UseSSE >= 1 ? 0 : 1, "generate_deopt_entry_for in interpreter"); |
222 __ subptr(rsp, wordSize); |
212 } else if (state == dtos) { |
223 __ movflt(Address(rsp, 0), xmm0); |
213 __ MacroAssembler::verify_FPU(UseSSE >= 2 ? 0 : 1, "generate_deopt_entry_for in interpreter"); |
224 __ fld_s(Address(rsp, 0)); |
214 } |
225 __ addptr(rsp, wordSize); |
|
226 } else if (state == dtos && UseSSE >= 2) { |
|
227 __ subptr(rsp, 2*wordSize); |
|
228 __ movdbl(Address(rsp, 0), xmm0); |
|
229 __ fld_d(Address(rsp, 0)); |
|
230 __ addptr(rsp, 2*wordSize); |
|
231 } |
|
232 |
|
233 __ MacroAssembler::verify_FPU(state == ftos || state == dtos ? 1 : 0, "generate_deopt_entry_for in interpreter"); |
|
234 |
215 |
235 // The stack is not extended by deopt but we must NULL last_sp as this |
216 // The stack is not extended by deopt but we must NULL last_sp as this |
236 // entry is like a "return". |
217 // entry is like a "return". |
237 __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD); |
218 __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD); |
238 __ restore_bcp(); |
219 __ restore_bcp(); |
837 (void) generate_native_entry(false); |
818 (void) generate_native_entry(false); |
838 |
819 |
839 return entry; |
820 return entry; |
840 } |
821 } |
841 return generate_native_entry(false); |
822 return generate_native_entry(false); |
|
823 } |
|
824 |
|
825 /** |
|
826 * Method entry for static native method: |
|
827 * java.lang.Float.intBitsToFloat(int bits) |
|
828 */ |
|
829 address InterpreterGenerator::generate_Float_intBitsToFloat_entry() { |
|
830 address entry; |
|
831 |
|
832 if (UseSSE >= 1) { |
|
833 entry = __ pc(); |
|
834 |
|
835 // rsi: the sender's SP |
|
836 |
|
837 // Skip safepoint check (compiler intrinsic versions of this method |
|
838 // do not perform safepoint checks either). |
|
839 |
|
840 // Load 'bits' into xmm0 (interpreter returns results in xmm0) |
|
841 __ movflt(xmm0, Address(rsp, wordSize)); |
|
842 |
|
843 // Return |
|
844 __ pop(rdi); // get return address |
|
845 __ mov(rsp, rsi); // set rsp to the sender's SP |
|
846 __ jmp(rdi); |
|
847 } else { |
|
848 entry = generate_native_entry(false); |
|
849 } |
|
850 |
|
851 return entry; |
|
852 } |
|
853 |
|
854 /** |
|
855 * Method entry for static native method: |
|
856 * java.lang.Float.floatToRawIntBits(float value) |
|
857 */ |
|
858 address InterpreterGenerator::generate_Float_floatToRawIntBits_entry() { |
|
859 address entry; |
|
860 |
|
861 if (UseSSE >= 1) { |
|
862 entry = __ pc(); |
|
863 |
|
864 // rsi: the sender's SP |
|
865 |
|
866 // Skip safepoint check (compiler intrinsic versions of this method |
|
867 // do not perform safepoint checks either). |
|
868 |
|
869 // Load the parameter (a floating-point value) into rax. |
|
870 __ movl(rax, Address(rsp, wordSize)); |
|
871 |
|
872 // Return |
|
873 __ pop(rdi); // get return address |
|
874 __ mov(rsp, rsi); // set rsp to the sender's SP |
|
875 __ jmp(rdi); |
|
876 } else { |
|
877 entry = generate_native_entry(false); |
|
878 } |
|
879 |
|
880 return entry; |
|
881 } |
|
882 |
|
883 |
|
884 /** |
|
885 * Method entry for static native method: |
|
886 * java.lang.Double.longBitsToDouble(long bits) |
|
887 */ |
|
888 address InterpreterGenerator::generate_Double_longBitsToDouble_entry() { |
|
889 address entry; |
|
890 |
|
891 if (UseSSE >= 2) { |
|
892 entry = __ pc(); |
|
893 |
|
894 // rsi: the sender's SP |
|
895 |
|
896 // Skip safepoint check (compiler intrinsic versions of this method |
|
897 // do not perform safepoint checks either). |
|
898 |
|
899 // Load 'bits' into xmm0 (interpreter returns results in xmm0) |
|
900 __ movdbl(xmm0, Address(rsp, wordSize)); |
|
901 |
|
902 // Return |
|
903 __ pop(rdi); // get return address |
|
904 __ mov(rsp, rsi); // set rsp to the sender's SP |
|
905 __ jmp(rdi); |
|
906 } else { |
|
907 entry = generate_native_entry(false); |
|
908 } |
|
909 |
|
910 return entry; |
|
911 } |
|
912 |
|
913 /** |
|
914 * Method entry for static native method: |
|
915 * java.lang.Double.doubleToRawLongBits(double value) |
|
916 */ |
|
917 address InterpreterGenerator::generate_Double_doubleToRawLongBits_entry() { |
|
918 address entry; |
|
919 |
|
920 if (UseSSE >= 2) { |
|
921 entry = __ pc(); |
|
922 |
|
923 // rsi: the sender's SP |
|
924 |
|
925 // Skip safepoint check (compiler intrinsic versions of this method |
|
926 // do not perform safepoint checks either). |
|
927 |
|
928 // Load the parameter (a floating-point value) into rax. |
|
929 __ movl(rdx, Address(rsp, 2*wordSize)); |
|
930 __ movl(rax, Address(rsp, wordSize)); |
|
931 |
|
932 // Return |
|
933 __ pop(rdi); // get return address |
|
934 __ mov(rsp, rsi); // set rsp to the sender's SP |
|
935 __ jmp(rdi); |
|
936 } else { |
|
937 entry = generate_native_entry(false); |
|
938 } |
|
939 |
|
940 return entry; |
842 } |
941 } |
843 |
942 |
844 // |
943 // |
845 // Interpreter stub for calling a native method. (asm interpreter) |
944 // Interpreter stub for calling a native method. (asm interpreter) |
846 // This sets up a somewhat different looking stack for calling the native method |
945 // This sets up a somewhat different looking stack for calling the native method |
1088 __ jcc(Assembler::equal, push_double); |
1187 __ jcc(Assembler::equal, push_double); |
1089 __ cmpptr(Address(rbp, (frame::interpreter_frame_oop_temp_offset + 1)*wordSize), |
1188 __ cmpptr(Address(rbp, (frame::interpreter_frame_oop_temp_offset + 1)*wordSize), |
1090 double_handler.addr()); |
1189 double_handler.addr()); |
1091 __ jcc(Assembler::notEqual, L); |
1190 __ jcc(Assembler::notEqual, L); |
1092 __ bind(push_double); |
1191 __ bind(push_double); |
1093 __ push(dtos); |
1192 __ push_d(); // FP values are returned using the FPU, so push FPU contents (even if UseSSE > 0). |
1094 __ bind(L); |
1193 __ bind(L); |
1095 } |
1194 } |
1096 __ push(ltos); |
1195 __ push(ltos); |
1097 |
1196 |
1098 // change thread state |
1197 // change thread state |