OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
124 // the V8 heap. We can't, and don't, refer to any relocatable addresses | 124 // the V8 heap. We can't, and don't, refer to any relocatable addresses |
125 // (e.g. the JavaScript nan-object). | 125 // (e.g. the JavaScript nan-object). |
126 | 126 |
127 // Windows 64 ABI passes double arguments in xmm0, xmm1 and | 127 // Windows 64 ABI passes double arguments in xmm0, xmm1 and |
128 // returns result in xmm0. | 128 // returns result in xmm0. |
129 // Argument backing space is allocated on the stack above | 129 // Argument backing space is allocated on the stack above |
130 // the return address. | 130 // the return address. |
131 | 131 |
132 // Compute x mod y. | 132 // Compute x mod y. |
133 // Load y and x (use argument backing store as temporary storage). | 133 // Load y and x (use argument backing store as temporary storage). |
134 __ movsd(Operand(rsp, kPointerSize * 2), xmm1); | 134 __ movsd(Operand(rsp, kRegisterSize * 2), xmm1); |
135 __ movsd(Operand(rsp, kPointerSize), xmm0); | 135 __ movsd(Operand(rsp, kRegisterSize), xmm0); |
136 __ fld_d(Operand(rsp, kPointerSize * 2)); | 136 __ fld_d(Operand(rsp, kRegisterSize * 2)); |
137 __ fld_d(Operand(rsp, kPointerSize)); | 137 __ fld_d(Operand(rsp, kRegisterSize)); |
138 | 138 |
139 // Clear exception flags before operation. | 139 // Clear exception flags before operation. |
140 { | 140 { |
141 Label no_exceptions; | 141 Label no_exceptions; |
142 __ fwait(); | 142 __ fwait(); |
143 __ fnstsw_ax(); | 143 __ fnstsw_ax(); |
144 // Clear if Illegal Operand or Zero Division exceptions are set. | 144 // Clear if Illegal Operand or Zero Division exceptions are set. |
145 __ testb(rax, Immediate(5)); | 145 __ testb(rax, Immediate(5)); |
146 __ j(zero, &no_exceptions); | 146 __ j(zero, &no_exceptions); |
147 __ fnclex(); | 147 __ fnclex(); |
(...skipping 15 matching lines...) Expand all Loading... |
163 | 163 |
164 Label valid_result; | 164 Label valid_result; |
165 Label return_result; | 165 Label return_result; |
166 // If Invalid Operand or Zero Division exceptions are set, | 166 // If Invalid Operand or Zero Division exceptions are set, |
167 // return NaN. | 167 // return NaN. |
168 __ testb(rax, Immediate(5)); | 168 __ testb(rax, Immediate(5)); |
169 __ j(zero, &valid_result); | 169 __ j(zero, &valid_result); |
170 __ fstp(0); // Drop result in st(0). | 170 __ fstp(0); // Drop result in st(0). |
171 int64_t kNaNValue = V8_INT64_C(0x7ff8000000000000); | 171 int64_t kNaNValue = V8_INT64_C(0x7ff8000000000000); |
172 __ movq(rcx, kNaNValue); | 172 __ movq(rcx, kNaNValue); |
173 __ movp(Operand(rsp, kPointerSize), rcx); | 173 __ movq(Operand(rsp, kRegisterSize), rcx); |
174 __ movsd(xmm0, Operand(rsp, kPointerSize)); | 174 __ movsd(xmm0, Operand(rsp, kRegisterSize)); |
175 __ jmp(&return_result); | 175 __ jmp(&return_result); |
176 | 176 |
177 // If result is valid, return that. | 177 // If result is valid, return that. |
178 __ bind(&valid_result); | 178 __ bind(&valid_result); |
179 __ fstp_d(Operand(rsp, kPointerSize)); | 179 __ fstp_d(Operand(rsp, kRegisterSize)); |
180 __ movsd(xmm0, Operand(rsp, kPointerSize)); | 180 __ movsd(xmm0, Operand(rsp, kRegisterSize)); |
181 | 181 |
182 // Clean up FPU stack and exceptions and return xmm0 | 182 // Clean up FPU stack and exceptions and return xmm0 |
183 __ bind(&return_result); | 183 __ bind(&return_result); |
184 __ fstp(0); // Unload y. | 184 __ fstp(0); // Unload y. |
185 | 185 |
186 Label clear_exceptions; | 186 Label clear_exceptions; |
187 __ testb(rax, Immediate(0x3f /* Any Exception*/)); | 187 __ testb(rax, Immediate(0x3f /* Any Exception*/)); |
188 __ j(not_zero, &clear_exceptions); | 188 __ j(not_zero, &clear_exceptions); |
189 __ ret(0); | 189 __ ret(0); |
190 __ bind(&clear_exceptions); | 190 __ bind(&clear_exceptions); |
(...skipping 519 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
710 // argument_count_reg_ * times_pointer_size + (receiver - 1) * kPointerSize. | 710 // argument_count_reg_ * times_pointer_size + (receiver - 1) * kPointerSize. |
711 return Operand(base_reg_, argument_count_reg_, times_pointer_size, | 711 return Operand(base_reg_, argument_count_reg_, times_pointer_size, |
712 displacement_to_last_argument + (receiver - 1 - index) * kPointerSize); | 712 displacement_to_last_argument + (receiver - 1 - index) * kPointerSize); |
713 } | 713 } |
714 } | 714 } |
715 | 715 |
716 | 716 |
717 } } // namespace v8::internal | 717 } } // namespace v8::internal |
718 | 718 |
719 #endif // V8_TARGET_ARCH_X64 | 719 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |