2 * jit-icalls.c: internal calls used by the JIT
5 * Dietmar Maurer (dietmar@ximian.com)
6 * Paolo Molaro (lupus@ximian.com)
8 * (C) 2002 Ximian, Inc.
14 mono_ldftn (MonoMethod *method)
20 EnterCriticalSection (metadata_section);
21 addr = mono_compile_method (method);
22 LeaveCriticalSection (metadata_section);
28 mono_ldvirtfn (MonoObject *obj, MonoMethod *method)
32 method = mono_object_get_virtual_method (obj, method);
33 return mono_ldftn (method);
37 helper_initobj (void *addr, int size)
41 memset (addr, 0, size);
45 helper_memcpy (void *addr, void *src, int size)
49 memcpy (addr, src, size);
53 helper_memset (void *addr, int val, int size)
57 memset (addr, val, size);
61 mono_llmult (gint64 a, gint64 b)
68 mono_llmult_ovf_un (guint32 al, guint32 ah, guint32 bl, guint32 bh)
74 // fixme: this is incredible slow
79 res = (guint64)al * (guint64)bl;
81 t1 = (guint64)ah * (guint64)bl + (guint64)al * (guint64)bh;
86 res += ((guint64)t1) << 32;
91 mono_raise_exception (mono_get_exception_overflow ());
97 mono_llmult_ovf (guint32 al, gint32 ah, guint32 bl, gint32 bh)
100 Use Karatsuba algorithm where:
101 a*b is: AhBh(R^2+R)+(Ah-Al)(Bl-Bh)R+AlBl(R+1)
102 where Ah is the "high half" (most significant 32 bits) of a and
103 where Al is the "low half" (least significant 32 bits) of a and
104 where Bh is the "high half" of b and Bl is the "low half" and
105 where R is the Radix or "size of the half" (in our case 32 bits)
107 Note, for the product of two 64 bit numbers to fit into a 64
108 result, ah and/or bh must be 0. This will save us from doing
109 the AhBh term at all.
111 Also note that we refactor so that we don't overflow 64 bits with
112 intermediate results. So we use [(Ah-Al)(Bl-Bh)+AlBl]R+AlBl
120 /* need to work with absoulte values, so find out what the
121 resulting sign will be and convert any negative numbers
122 from two's complement
126 /* flip the bits and add 1 */
137 /* flip the bits and add 1 */
147 /* we overflow for sure if both upper halves are greater
148 than zero because we would need to shift their
149 product 64 bits to the left and that will not fit
150 in a 64 bit result */
152 goto raise_exception;
154 /* do the AlBl term first */
155 t1 = (gint64)al * (gint64)bl;
159 /* now do the [(Ah-Al)(Bl-Bh)+AlBl]R term */
160 t1 += (gint64)(ah - al) * (gint64)(bl - bh);
162 /* check for overflow */
163 if (t1 > (0x7FFFFFFFFFFFFFFF - res))
164 goto raise_exception;
174 mono_raise_exception (mono_get_exception_overflow ());
179 mono_lldiv (gint64 a, gint64 b)
187 mono_llrem (gint64 a, gint64 b)
195 mono_lldiv_un (guint64 a, guint64 b)
203 mono_llrem_un (guint64 a, guint64 b)
211 mono_lshl (guint64 a, gint32 shamt)
218 /*printf ("TESTL %lld << %d = %lld\n", a, shamt, res);*/
224 mono_lshr_un (guint64 a, gint32 shamt)
231 /*printf ("TESTR %lld >> %d = %lld\n", a, shamt, res);*/
237 mono_lshr (gint64 a, gint32 shamt)
244 /*printf ("TESTR %lld >> %d = %lld\n", a, shamt, res);*/
250 * ves_array_element_address:
251 * @this: a pointer to the array object
253 * Returns: the address of an array element.
256 ves_array_element_address (MonoArray *this, ...)
265 g_assert (this != NULL);
269 class = this->obj.vtable->klass;
271 ind = va_arg(ap, int);
272 g_assert (this->bounds != NULL);
274 ind -= this->bounds [0].lower_bound;
275 for (i = 1; i < class->rank; i++) {
276 ind = ind*this->bounds [i].length + va_arg(ap, int) -
277 this->bounds [i].lower_bound;;
280 if (ind >= this->max_length)
281 mono_raise_exception (mono_get_exception_index_out_of_range ());
283 esize = mono_array_element_size (class);
284 ea = (gpointer*)((char*)this->vector + (ind * esize));
292 mono_array_new_va (MonoMethod *cm, ...)
294 MonoDomain *domain = mono_domain_get ();
297 guint32 *lower_bounds;
304 pcount = cm->signature->param_count;
305 rank = cm->klass->rank;
309 lengths = alloca (sizeof (guint32) * pcount);
310 for (i = 0; i < pcount; ++i)
311 lengths [i] = d = va_arg(ap, int);
313 if (rank == pcount) {
314 /* Only lengths provided. */
317 g_assert (pcount == (rank * 2));
318 /* lower bounds are first. */
319 lower_bounds = lengths;
324 return mono_array_new_full (domain, cm->klass, lengths, lower_bounds);
328 mono_class_static_field_address (MonoDomain *domain, MonoClassField *field)
334 //printf ("SFLDA0 %s.%s::%s %d\n", field->parent->name_space, field->parent->name, field->name, field->offset, field->parent->inited);
336 mono_class_init (field->parent);
338 vtable = mono_class_vtable (domain, field->parent);
340 //printf ("SFLDA1 %p\n", (char*)vtable->data + field->offset);
343 return (char*)vtable->data + field->offset;
347 mono_ldtoken_wrapper (MonoImage *image, int token)
349 MonoClass *handle_class;
353 res = mono_ldtoken (image, token, &handle_class);
354 mono_class_init (handle_class);
360 mono_fconv_u8 (double v)
367 mono_fconv_u4 (double v)
374 mono_fconv_ovf_i8 (double v)
382 if (isnan(v) || v != res) {
383 mono_raise_exception (mono_get_exception_overflow ());
389 mono_fconv_ovf_u8 (double v)
397 if (isnan(v) || v != res) {
398 mono_raise_exception (mono_get_exception_overflow ());