OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [native/] [jni/] [java-math/] [gnu_java_math_GMP.c] - Blame information for rev 774

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 774 jeremybenn
/* gnu_java_math_GMP.c -- Native MPI implemenetation over GNU MP
2
   Copyright (C) 2006  Free Software Foundation, Inc.
3
 
4
This file is a part of GNU Classpath.
5
 
6
GNU Classpath is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2 of the License, or (at
9
your option) any later version.
10
 
11
GNU Classpath is distributed in the hope that it will be useful, but
12
WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with GNU Classpath; if not, write to the Free Software
18
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
19
USA
20
 
21
Linking this library statically or dynamically with other modules is
22
making a combined work based on this library.  Thus, the terms and
23
conditions of the GNU General Public License cover the whole
24
combination.
25
 
26
As a special exception, the copyright holders of this library give you
27
permission to link this library with independent modules to produce an
28
executable, regardless of the license terms of these independent
29
modules, and to copy and distribute the resulting executable under
30
terms of your choice, provided that you also meet, for each linked
31
independent module, the terms and conditions of the license of that
32
module.  An independent module is a module which is not derived from
33
or based on this library.  If you modify this library, you may extend
34
this exception to your version of the library, but you are not
35
obligated to do so.  If you do not wish to do so, delete this
36
exception statement from your version.  */
37
 
38
#include <limits.h>
39
#include <stdio.h>
40
#include <stdlib.h>
41
 
42
#ifdef HAVE_CONFIG_H
43
#include "config.h"
44
#endif /* HAVE_CONFIG_H */
45
 
46
#include "gnu_java_math_GMP.h"
47
#include <jcl.h>
48
 
49
#if defined(HAVE_GMP_H)
50
#include <gmp.h>
51
#endif /* defined(HAVE_GMP_H) */
52
 
53
#if defined(WITH_GNU_MP)
54
#else
55
#warning GNU MP not available or wanted!
56
#warning Invocation of natXXX() methods will raise an exception
57
#endif
58
 
59
/*
60
 * This is the implementation of the native BigInteger$NativeMPI methods which
61
 * use the GNU MP (GMP) library.
62
 *
63
 * In all the Java non-statically declared native methods, the second argument,
64
 * an instance of jobject, refers to the current NativeMPI instance; i.e.
65
 * "this" in Java parlance. The corresponding allocated data structure
66
 * representing the GMP's counter-part is pointed-to by the pointer stored in a
67
 * transient java field named "native_ptr". The first thing these methods do is
68
 * (a) access that field with a JNI GetObjectField() call to obtain the
69
 * reference to the gnu.classpath.Pointer subclass instance, then (b) obtain
70
 * the native GMP pointer (an mpz_ptr), in order to perform their job; e.g.
71
 *
72
 *   JCL_GetRawData (env, (*env)->GetObjectField (env, this, native_ptr))
73
 *
74
 * For static methods the second argument, an instance of jclass, is almost
75
 * always unused --except when initializing the library, which is the only time
76
 * we get hold of the native pointer field.
77
 *
78
 * This code was written and tested with GNU MP version 4.1.2. More recent
79
 * versions of that library offer more operations; e.g. in the implementation
80
 * of the method Java_java_math_BigInteger_00024NativeMPI_natFlipBit, mpz_combit()
81
 * should be used with GNU MP versions later than 4.2. As a consequence, this
82
 * code should be reviewed, from time to time, to use newer features of the GNU
83
 * MP library.
84
 */
85
 
86
static jfieldID native_ptr;
87
 
88
#ifdef DEBUG
89
#define TRACE(msg) fprintf (stderr, "%s(%s:%d) -- %s\n", __FUNCTION__, __FILE__, __LINE__, msg)
90
#else
91
#define TRACE(msg)
92
#endif
93
 
94
#define throw_config_exception(env) JCL_ThrowException (env, "java/lang/Error", "GNU MP was not specified/found by configure")
95
 
96
/*
97
 * Initialize the native library. Specifically this method:
98
 *
99
 * a. Pass NULLs to the mp_set_memory_functions implying that GMP should use
100
 *    malloc, realloc and free for memory allocation, and if they fail GMP
101
 *    will print a message to the standard error output and terminates the
102
 *    program.
103
 * b. Find out and store the reference to the NativeMPI class's 'native_ptr'
104
 *    field. This is done so later in the method invocations we can access that
105
 *    field and acquire the native value associated with that Pointer instance.
106
 */
107
JNIEXPORT void JNICALL
108
Java_gnu_java_math_GMP_natInitializeLibrary (JNIEnv *env,
109
                                                               jclass nativeMPI)
110
{
111
#if defined(WITH_GNU_MP)
112
  TRACE("Loading GMP-based BigInteger native library");
113
  mp_set_memory_functions (NULL, NULL, NULL);
114
  native_ptr = (*env)->GetFieldID (env, nativeMPI, "native_ptr",
115
                                   "Lgnu/classpath/Pointer;");
116
  TRACE("Loaded GMP-based BigInteger native library");
117
#else /* !defined(WITH_GNU_MP) */
118
  (void) nativeMPI;
119
  throw_config_exception(env);
120
#endif /* defined(WITH_GNU_MP) */
121
}
122
 
123
/*
124
 * Allocate and initialize the data structure for an instance of a NativeMPI.
125
 *
126
 * @param this  an instance of NativeMPI.
127
 */
128
JNIEXPORT void JNICALL
129
Java_gnu_java_math_GMP_natInitialize(JNIEnv *env, jobject this)
130
{
131
#if defined(WITH_GNU_MP)
132
  mpz_ptr _this;
133
 
134
  TRACE("begin");
135
  _this = (mpz_ptr)JCL_malloc (env, sizeof (mpz_t));
136
  /* initialize --GMP sets the value to zero. */
137
  mpz_init (_this);
138
  /* instantiate the Pointer instance for this NativeMPI. */
139
  jobject native_ptr_fld = JCL_NewRawDataObject (env, _this);
140
  /* ... and assign it to the native_ptr field. */
141
  (*env)->SetObjectField (env, this, native_ptr, native_ptr_fld);
142
  TRACE("end");
143
#else /* !defined(WITH_GNU_MP) */
144
  (void) this;
145
  throw_config_exception(env);
146
#endif /* defined(WITH_GNU_MP) */
147
}
148
 
149
/*
150
 * Clear and free the data structure for an instance of a NativeMPI.
151
 *
152
 * @param this  an instance of NativeMPI.
153
 */
154
JNIEXPORT void JNICALL
155
Java_gnu_java_math_GMP_natFinalize(JNIEnv *env, jobject this)
156
{
157
#if defined(WITH_GNU_MP)
158
  mpz_ptr _this;
159
 
160
  TRACE("begin");
161
  _this = (mpz_ptr)JCL_GetRawData (env, (*env)->GetObjectField (env, this, native_ptr));
162
  if (_this != NULL)
163
    {
164
      mpz_clear (_this);
165
      free (_this);
166
      _this = NULL;
167
    }
168
  else
169
    {
170
      TRACE("WARNING: Already cleared + freed");
171
    }
172
  TRACE("end");
173
#else /* !defined(WITH_GNU_MP) */
174
  (void) this;
175
  throw_config_exception(env);
176
#endif /* defined(WITH_GNU_MP) */
177
}
178
 
179
 
180
/*
181
 * @param this  an instance of NativeMPI. On exit, this will have a value of n.
182
 * @param n  a Java long primitive value.
183
 */
184
JNIEXPORT void JNICALL
185
Java_gnu_java_math_GMP_natFromLong(JNIEnv *env, jobject this,
186
                                                     jlong n)
187
{
188
#if defined(WITH_GNU_MP)
189
  mpz_ptr _this;
190
 
191
  TRACE("begin");
192
  _this = (mpz_ptr)JCL_GetRawData (env, (*env)->GetObjectField (env, this, native_ptr));
193
  /* the size of jlong (64-bit) is either the same as a long, or that of a long long.
194
   * if it's the former, we use as is. */
195
  if (sizeof (jlong) == sizeof (long))
196
    {
197
      mpz_set_si (_this, (signed long)n);
198
    }
199
  else
200
    {
201
      /* ...otherwise, we operate on the two halves of the long long, each half
202
       * being 32-bit wide.  for simplicity, we work with positive
203
       * values negating, if necessary, the final outcome.
204
       */
205
      const int isnegative = n < 0 ? 1 : 0;
206
      if (isnegative)
207
        {
208
          n = -n;
209
        }
210
      mpz_set_ui (_this, (unsigned long)(((unsigned long long)n) >> 32));
211
      mpz_mul_2exp (_this, _this, 32); /* shift left by 32 bits */
212
      mpz_add_ui (_this, _this, (unsigned long)n);
213
      if (isnegative)
214
        {
215
          mpz_neg (_this, _this);
216
        }
217
    }
218
  TRACE("end");
219
#else /* !defined(WITH_GNU_MP) */
220
  (void) n;
221
  (void) r;
222
  throw_config_exception(env);
223
#endif /* defined(WITH_GNU_MP) */
224
}
225
 
226
/*
227
 * @param this  an instance of NativeMPI. On exit, this will have the same
228
 *           value as x.
229
 * @param x  an instance of a NativeMPI's Pointer.
230
 */
231
JNIEXPORT void JNICALL
232
Java_gnu_java_math_GMP_natFromBI(JNIEnv *env, jobject this,
233
                                                   jobject x)
234
{
235
#if defined(WITH_GNU_MP)
236
  mpz_ptr _this;
237
  mpz_srcptr _x;
238
 
239
  TRACE("begin");
240
  _this = (mpz_ptr)JCL_GetRawData (env, (*env)->GetObjectField (env, this, native_ptr));
241
  _x = (mpz_srcptr)JCL_GetRawData (env, x);
242
  mpz_set (_this, _x);
243
  TRACE("end");
244
#else /* !defined(WITH_GNU_MP) */
245
  (void) this;
246
  (void) x;
247
  throw_config_exception(env);
248
#endif /* defined(WITH_GNU_MP) */
249
}
250
 
251
/*
252
 * @param this  an instance of NativeMPI. On exit, this will have the value
253
 *           represented by the v Java byte array (in 2's complement with most
254
 *           significant byte at index position 0). The sign is implied by the
255
 *           value of the most significant byte.
256
 * @param v  a Java byte array containing the byte representation, in 2's
257
 *           complement of the signed value to assign to this.
258
 */
259
JNIEXPORT void JNICALL
260
Java_gnu_java_math_GMP_natFromByteArray(JNIEnv *env,
261
                                                          jobject this,
262
                                                          jbyteArray v)
263
{
264
#if defined(WITH_GNU_MP)
265
  mpz_ptr _this;
266
  jbyte *_v;
267
  unsigned long b;
268
  int vlength, isnegative, i;
269
 
270
  TRACE("begin");
271
  _this = (mpz_ptr)JCL_GetRawData (env, (*env)->GetObjectField (env, this, native_ptr));
272
  _v = (*env)->GetByteArrayElements (env, v, NULL);
273
  vlength = (*env)->GetArrayLength (env, v);
274
  b = (unsigned long)(_v[0] & 0xFF);
275
  isnegative = (b > 0x7F) ? 1 : 0;
276
  mpz_set_ui (_this, 0);
277
  for (i = 0; i < vlength; i++)
278
    {
279
      mpz_mul_2exp (_this, _this, 8); /* shift left 8 positions. */
280
      b = (unsigned long)(_v[i] & 0xFF);
281
      b = (isnegative) ? ~b : b;
282
      mpz_add_ui (_this, _this, (unsigned long)(b & 0xFF));
283
    }
284
  (*env)->ReleaseByteArrayElements (env, v, _v, JNI_ABORT);
285
  if (isnegative)
286
    {
287
      mpz_add_ui (_this, _this, 1);
288
      mpz_neg (_this, _this);
289
    }
290
  TRACE("end");
291
#else /* !defined(WITH_GNU_MP) */
292
  (void) this;
293
  (void) v;
294
  throw_config_exception(env);
295
#endif /* defined(WITH_GNU_MP) */
296
}
297
 
298
/*
299
 * @param this  an instance of NativeMPI. On exit, this will have the value
300
 *           represented by the s Java string.
301
 * @param s  a Java string containing, a possibly signed, value to assign to
302
 *           this.
303
 * @param rdx  the base in which the symbols, in s, are represented.
304
 * @return  0 if the entire string is a valid number in base rdx. Otherwise it
305
 *          returns -1.
306
 *
307
 * Implementation note:
308
 * While the GMP library is more tolerant in what it accepts as parameter values
309
 * for conversions from strings, the BigInteger code, which calls this method,
310
 * ensures that the contract described in the RI's documentation is respected;
311
 * e.g. no white spaces in the middle, limited valid radix values, etc...
312
 */
313
JNIEXPORT jint JNICALL
314
Java_gnu_java_math_GMP_natFromString(JNIEnv *env,
315
                                                       jobject this, jstring s,
316
                                                       jint rdx)
317
{
318
#if defined(WITH_GNU_MP)
319
  mpz_ptr _this;
320
  const char *_s;
321
  int result;
322
 
323
  TRACE("begin");
324
  _this = (mpz_ptr)JCL_GetRawData (env, (*env)->GetObjectField (env, this, native_ptr));
325
  _s = (*env)->GetStringUTFChars (env, s, NULL);
326
  result = mpz_set_str (_this, _s, (int)rdx);
327
  JCL_free_cstring (env, s, _s);
328
  TRACE("end");
329
  return (result);
330
#else /* !defined(WITH_GNU_MP) */
331
  (void) this;
332
  (void) s;
333
  (void) rdx;
334
  throw_config_exception(env);
335
  return (-1);
336
#endif /* defined(WITH_GNU_MP) */
337
}
338
 
339
/*
340
 * @param this  an instance of NativeMPI. On exit, this will have the value
341
 *           represented by the m Java byte array (most significant byte at
342
 *           index position 0). It will be positive, or negative, depending on
343
 *           the value of isnegative.
344
 * @param m  a Java byte array containing the byte representation of the
345
 *           absolute value (most significant byte being at index position 0)
346
 *           to assign to this.
347
 * @param isnegative  true if this should be negative and false if it should
348
 *           be positive.
349
 */
350
JNIEXPORT void JNICALL
351
Java_gnu_java_math_GMP_natFromSignedMagnitude(JNIEnv *env,
352
                                                                jobject this,
353
                                                                jbyteArray m,
354
                                                                jboolean isnegative)
355
{
356
#if defined(WITH_GNU_MP)
357
  mpz_ptr _this;
358
  jbyte *_m;
359
  int mlength, i;
360
 
361
  TRACE("begin");
362
  _this = (mpz_ptr)JCL_GetRawData (env, (*env)->GetObjectField (env, this, native_ptr));
363
  _m = (*env)->GetByteArrayElements (env, m, NULL);
364
  mlength = (*env)->GetArrayLength (env, m);
365
  mpz_set_ui (_this, 0);
366
  for (i = 0; i < mlength; i++)
367
    {
368
      mpz_mul_2exp (_this, _this, 8);
369
      mpz_add_ui (_this, _this, (unsigned long)(_m[i] & 0xFF));
370
    }
371
  (*env)->ReleaseByteArrayElements (env, m, _m, JNI_ABORT);
372
  if (isnegative == JNI_TRUE)
373
    {
374
      mpz_neg (_this, _this);
375
    }
376
  TRACE("end");
377
#else /* !defined(WITH_GNU_MP) */
378
  (void) this;
379
  (void) m;
380
  (void) isnegative;
381
  throw_config_exception(env);
382
#endif /* defined(WITH_GNU_MP) */
383
}
384
 
385
/*
386
 * @param this  an instance of NativeMPI.
387
 * @param n  the base in which to represent this.
388
 * @return  the Java string representing the value of this in base n.
389
 */
390
JNIEXPORT jstring JNICALL
391
Java_gnu_java_math_GMP_natToString(JNIEnv *env, jobject this,
392
                                                     jint n)
393
{
394
#if defined(WITH_GNU_MP)
395
  mpz_srcptr _this;
396
  char *cstr;
397
  jstring result;
398
 
399
  TRACE("begin");
400
  _this = (mpz_srcptr)JCL_GetRawData (env, (*env)->GetObjectField (env, this, native_ptr));
401
  cstr = mpz_get_str (NULL, (int)n, _this);
402
  result  = (*env)->NewStringUTF (env, cstr);
403
  free (cstr);
404
  TRACE("end");
405
  return (result);
406
#else /* !defined(WITH_GNU_MP) */
407
  (void) this;
408
  (void) n;
409
  throw_config_exception(env);
410
  return (NULL);
411
#endif /* defined(WITH_GNU_MP) */
412
}
413
 
414
/*
415
 * @param this  a non-ZERO instance of NativeMPI.
416
 *
417
 * output:
418
 * @param r  a Java byte array which shall contain the byte representation of
419
 *           this.
420
 */
421
JNIEXPORT void JNICALL
422
Java_gnu_java_math_GMP_natToByteArray(JNIEnv *env,
423
                                                        jobject this,
424
                                                        jbyteArray r)
425
{
426
#if defined(WITH_GNU_MP)
427
  mpz_srcptr _this;
428
  mpz_t _w;  /* a temporary work mpi */
429
  jbyte *_r;
430
  int rlength, sign, i;
431
  unsigned long b;
432
 
433
  TRACE("begin");
434
  _this = (mpz_srcptr)JCL_GetRawData (env, (*env)->GetObjectField (env, this, native_ptr));
435
  _r = (*env)->GetByteArrayElements (env, r, NULL);
436
  rlength = (*env)->GetArrayLength (env, r);
437
  mpz_init (_w);
438
  /* if this is negative set w to its 2's complement otherwise use as is. */
439
  sign = mpz_sgn (_this);
440
  if (sign == 1)
441
    {
442
      mpz_set (_w, _this);
443
    }
444
  else
445
    {
446
      mpz_neg (_w, _this);
447
      mpz_sub_ui (_w, _w, 1);
448
    }
449
  /* _w SHOULD be >= 0.
450
   * start filling the array starting from the least significant byte. */
451
  for (i = rlength; --i >= 0; )
452
    {
453
      b = mpz_tdiv_q_ui (_w, _w, 256);
454
      b = (sign == -1) ? ~b : b;
455
      _r[i] = (unsigned long)(b & 0xFF);
456
    }
457
  (*env)->ReleaseByteArrayElements (env, r, _r, JNI_COMMIT);
458
  /* if _w > 0 the byte array was short. */
459
  if (mpz_cmp_ui (_w, 0) > 0)
460
    {
461
      TRACE("WARNING: byte array is too short");
462
    }
463
  mpz_clear (_w);
464
  TRACE("end");
465
#else /* !defined(WITH_GNU_MP) */
466
  (void) this;
467
  (void) r;
468
  throw_config_exception(env);
469
#endif /* defined(WITH_GNU_MP) */
470
}
471
 
472
/*
473
 * @param this  an instance of NativeMPI.
474
 * @return  the "int" value (least significant 32 bits) of the absolute value
475
 *          of this NativeMPI. The calling code MUST handle the sign. We do
476
 *          this so we can use the same method when computing the "long" value
477
 *          as well.
478
 */
479
JNIEXPORT jint JNICALL
480
Java_gnu_java_math_GMP_natAbsIntValue(JNIEnv *env,
481
                                                        jobject this)
482
{
483
#if defined(WITH_GNU_MP)
484
  mpz_srcptr _this;
485
 
486
  TRACE("begin");
487
  _this = (mpz_srcptr)JCL_GetRawData (env, (*env)->GetObjectField (env, this, native_ptr));
488
  TRACE("end");
489
  return ((jint)mpz_get_ui (_this));
490
#else /* !defined(WITH_GNU_MP) */
491
  (void) s;
492
  throw_config_exception(env);
493
  return (-1);
494
#endif /* defined(WITH_GNU_MP) */
495
}
496
 
497
/*
498
 * @param this  an instance of NativeMPI.
499
 * @return  the, eventually truncated, double value of this NativeMPI.
500
 */
501
JNIEXPORT jdouble JNICALL
502
Java_gnu_java_math_GMP_natDoubleValue(JNIEnv *env,
503
                                                        jobject this)
504
{
505
#if defined(WITH_GNU_MP)
506
  mpz_srcptr _this;
507
 
508
  TRACE("begin");
509
  _this = (mpz_srcptr)JCL_GetRawData (env, (*env)->GetObjectField (env, this, native_ptr));
510
  TRACE("end");
511
  return ((jdouble)mpz_get_d (_this));
512
#else /* !defined(WITH_GNU_MP) */
513
  (void) this;
514
  throw_config_exception(env);
515
  return (0.0);
516
#endif /* defined(WITH_GNU_MP) */
517
}
518
 
519
/*
520
 * @param this  a NativeMPI instance.
521
 * @param x  an instance of NativeMPI's Pointer.
522
 * @return  -1, 0, +1 if x is respectively less than, equal to, or greater
523
 *          than y.
524
 */
525
JNIEXPORT jint JNICALL
526
Java_gnu_java_math_GMP_natCompare(JNIEnv *env, jobject this,
527
                                                    jobject x)
528
{
529
#if defined(WITH_GNU_MP)
530
  mpz_ptr _this, _x;
531
  int res;
532
 
533
  TRACE("begin");
534
  _this = (mpz_ptr)JCL_GetRawData (env, (*env)->GetObjectField (env, this, native_ptr));
535
  _x = (mpz_ptr)JCL_GetRawData (env, x);
536
  res = mpz_cmp (_this, _x);
537
  TRACE("end");
538
  if (res == 0)
539
    return ((jint)0);
540
  else if (res < 0)
541
    return ((jint)-1);
542
  else
543
    return ((jint)1);
544
#else /* !defined(WITH_GNU_MP) */
545
  (void) x;
546
  (void) y;
547
  throw_config_exception(env);
548
  return (0);
549
#endif /* defined(WITH_GNU_MP) */
550
}
551
 
552
/*
553
 * @param this  an instance of NativeMPI.
554
 * @param x  an instance of NativeMPI's Pointer.
555
 *
556
 * output:
557
 * @param r  a NativeMPI's Pointer such that r = this + x.
558
 */
559
JNIEXPORT void JNICALL
560
Java_gnu_java_math_GMP_natAdd(JNIEnv *env, jobject this,
561
                                                jobject x, jobject r)
562
{
563
#if defined(WITH_GNU_MP)
564
  mpz_srcptr _this, _x;
565
  mpz_ptr _r;
566
 
567
  TRACE("begin");
568
  _this = (mpz_srcptr)JCL_GetRawData (env, (*env)->GetObjectField (env, this, native_ptr));
569
  _x = (mpz_srcptr)JCL_GetRawData (env, x);
570
  _r = (mpz_ptr)JCL_GetRawData (env, r);
571
  mpz_add (_r, _this, _x);
572
  TRACE("end");
573
#else /* !defined(WITH_GNU_MP) */
574
  (void) this;
575
  (void) x;
576
  (void) r;
577
  throw_config_exception(env);
578
#endif /* defined(WITH_GNU_MP) */
579
}
580
 
581
/*
582
 * @param this  an instance of NativeMPI.
583
 * @param x  an instance of NativeMPI's Pointer.
584
 *
585
 * output:
586
 * @param r  a NativeMPI's Pointer such that r = this - x.
587
 */
588
JNIEXPORT void JNICALL
589
Java_gnu_java_math_GMP_natSubtract(JNIEnv *env, jobject this,
590
                                                     jobject x, jobject r)
591
{
592
#if defined(WITH_GNU_MP)
593
  mpz_srcptr _this, _x;
594
  mpz_ptr _r;
595
 
596
  TRACE("begin");
597
  _this = (mpz_srcptr)JCL_GetRawData (env, (*env)->GetObjectField (env, this, native_ptr));
598
  _x = (mpz_srcptr)JCL_GetRawData (env, x);
599
  _r = (mpz_ptr)JCL_GetRawData (env, r);
600
  mpz_sub (_r, _this, _x);
601
  TRACE("end");
602
#else /* !defined(WITH_GNU_MP) */
603
  (void) this;
604
  (void) x;
605
  (void) r;
606
  throw_config_exception(env);
607
#endif /* defined(WITH_GNU_MP) */
608
}
609
 
610
/*
611
 * @param this  an instance of NativeMPI.
612
 * @param x  an instance of NativeMPI's Pointer.
613
 *
614
 * output:
615
 * @param r  a NativeMPI's Pointer such that r = this * x.
616
 */
617
JNIEXPORT void JNICALL
618
Java_gnu_java_math_GMP_natMultiply(JNIEnv *env, jobject this,
619
                                                     jobject x, jobject r)
620
{
621
#if defined(WITH_GNU_MP)
622
  mpz_srcptr _this, _x;
623
  mpz_ptr _r;
624
 
625
  TRACE("begin");
626
  _this = (mpz_srcptr)JCL_GetRawData (env, (*env)->GetObjectField (env, this, native_ptr));
627
  _x = (mpz_srcptr)JCL_GetRawData (env, x);
628
  _r = (mpz_ptr)JCL_GetRawData (env, r);
629
  mpz_mul (_r, _this, _x);
630
  TRACE("end");
631
#else /* !defined(WITH_GNU_MP) */
632
  (void) this;
633
  (void) x;
634
  (void) r;
635
  throw_config_exception(env);
636
#endif /* defined(WITH_GNU_MP) */
637
}
638
 
639
/*
640
 * @param this  an instance of NativeMPI.
641
 * @param x  an instance of NativeMPI's Pointer.
642
 *
643
 * output:
644
 * @param r  a NativeMPI's Pointer such that r = this div x.
645
 */
646
JNIEXPORT void JNICALL
647
Java_gnu_java_math_GMP_natQuotient(JNIEnv *env, jobject this,
648
                                                     jobject x, jobject r)
649
{
650
#if defined(WITH_GNU_MP)
651
  mpz_srcptr _this, _x;
652
  mpz_ptr _r;
653
 
654
  TRACE("begin");
655
  _this = (mpz_srcptr)JCL_GetRawData (env, (*env)->GetObjectField (env, this, native_ptr));
656
  _x = (mpz_srcptr)JCL_GetRawData (env, x);
657
  _r = (mpz_ptr)JCL_GetRawData (env, r);
658
  mpz_tdiv_q (_r, _this, _x);
659
  TRACE("end");
660
#else /* !defined(WITH_GNU_MP) */
661
  (void) this;
662
  (void) x;
663
  (void) r;
664
  throw_config_exception(env);
665
#endif /* defined(WITH_GNU_MP) */
666
}
667
 
668
/*
669
 * @param this  an instance of NativeMPI.
670
 * @param x  an instance of NativeMPI's Pointer.
671
 *
672
 * output:
673
 * @param r  a NativeMPI's Pointer such that r = this mod x.
674
 */
675
JNIEXPORT void JNICALL
676
Java_gnu_java_math_GMP_natRemainder(JNIEnv *env, jobject this,
677
                                                      jobject x, jobject r)
678
{
679
#if defined(WITH_GNU_MP)
680
  mpz_srcptr _this, _x;
681
  mpz_ptr _r;
682
 
683
  TRACE("begin");
684
  _this = (mpz_srcptr)JCL_GetRawData (env, (*env)->GetObjectField (env, this, native_ptr));
685
  _x = (mpz_srcptr)JCL_GetRawData (env, x);
686
  _r = (mpz_ptr)JCL_GetRawData (env, r);
687
  mpz_tdiv_r (_r, _this, _x);
688
  TRACE("end");
689
#else /* !defined(WITH_GNU_MP) */
690
  (void) this;
691
  (void) x;
692
  (void) r;
693
  throw_config_exception(env);
694
#endif /* defined(WITH_GNU_MP) */
695
}
696
 
697
/*
698
 * @param this  an instance of NativeMPI.
699
 * @param x  an instance of NativeMPI's Pointer.
700
 *
701
 * output:
702
 * @param q  a NativeMPI's Pointer such that q = this div x.
703
 * @param r  a NativeMPI's Pointer such that r = this mod x.
704
 */
705
JNIEXPORT void JNICALL
706
Java_gnu_java_math_GMP_natQuotientAndRemainder(JNIEnv *env,
707
                                                                 jobject this,
708
                                                                 jobject x,
709
                                                                 jobject q,
710
                                                                 jobject r)
711
{
712
#if defined(WITH_GNU_MP)
713
  mpz_srcptr _this, _x;
714
  mpz_ptr _q, _r;
715
 
716
  TRACE("begin");
717
  _this = (mpz_srcptr)JCL_GetRawData (env, (*env)->GetObjectField (env, this, native_ptr));
718
  _x = (mpz_srcptr)JCL_GetRawData (env, x);
719
  _q = (mpz_ptr)JCL_GetRawData (env, q);
720
  _r = (mpz_ptr)JCL_GetRawData (env, r);
721
  mpz_tdiv_qr (_q, _r, _this, _x);
722
  TRACE("end");
723
#else /* !defined(WITH_GNU_MP) */
724
  (void) this;
725
  (void) x;
726
  (void) q;
727
  (void) r;
728
  throw_config_exception(env);
729
#endif /* defined(WITH_GNU_MP) */
730
}
731
 
732
/*
733
 * @param this  an instance of NativeMPI.
734
 * @param x  an instance of NativeMPI's Pointer.
735
 *
736
 * output:
737
 * @param r  a NativeMPI's Pointer such that r = this mod x.
738
 */
739
JNIEXPORT void JNICALL
740
Java_gnu_java_math_GMP_natModulo(JNIEnv *env, jobject this,
741
                                                   jobject x, jobject r)
742
{
743
#if defined(WITH_GNU_MP)
744
  mpz_srcptr _this, _x;
745
  mpz_ptr _r;
746
 
747
  TRACE("begin");
748
  _this = (mpz_srcptr)JCL_GetRawData (env, (*env)->GetObjectField (env, this, native_ptr));
749
  _x = (mpz_srcptr)JCL_GetRawData (env, x);
750
  _r = (mpz_ptr)JCL_GetRawData (env, r);
751
  mpz_mod (_r, _this, _x);
752
  TRACE("end");
753
#else /* !defined(WITH_GNU_MP) */
754
  (void) this;
755
  (void) x;
756
  (void) r;
757
  throw_config_exception(env);
758
#endif /* defined(WITH_GNU_MP) */
759
}
760
 
761
/*
762
 * @param this  an instance of NativeMPI.
763
 * @param n  a non-negative number to raise this to.
764
 *
765
 * output:
766
 * @param r  a NativeMPI's Pointer such that r = this ** n.
767
 */
768
JNIEXPORT void JNICALL
769
Java_gnu_java_math_GMP_natPow(JNIEnv *env, jobject this,
770
                                                jint n, jobject r)
771
{
772
#if defined(WITH_GNU_MP)
773
  mpz_srcptr _this;
774
  mpz_ptr _r;
775
 
776
  TRACE("begin");
777
  _this = (mpz_srcptr)JCL_GetRawData (env, (*env)->GetObjectField (env, this, native_ptr));
778
  _r = (mpz_ptr)JCL_GetRawData (env, r);
779
  mpz_pow_ui (_r, _this, (unsigned long)n);
780
  TRACE("end");
781
#else /* !defined(WITH_GNU_MP) */
782
  (void) this;
783
  (void) n;
784
  (void) r;
785
  throw_config_exception(env);
786
#endif /* defined(WITH_GNU_MP) */
787
}
788
 
789
/*
790
 * @param this  an instance of NativeMPI.
791
 * @param e  an instance of NativeMPI's Pointer.
792
 * @param m  another instance of NativeMPI's Pointer.
793
 *
794
 * output:
795
 * @param r  a NativeMPI's Pointer such that r = (this**e) mod m.
796
 *
797
 * @throws java.lang.ArithmeticException if e is negative and (1 / this) mod m
798
 *         has no multiplicative inverse.
799
 */
800
JNIEXPORT void JNICALL
801
Java_gnu_java_math_GMP_natModPow(JNIEnv *env, jobject this,
802
                                                   jobject e, jobject m,
803
                                                   jobject r)
804
{
805
#if defined(WITH_GNU_MP)
806
  mpz_srcptr _this, _e, _m;
807
  mpz_ptr _r;
808
 
809
  TRACE("begin");
810
  _this = (mpz_srcptr)JCL_GetRawData (env, (*env)->GetObjectField (env, this, native_ptr));
811
  _e = (mpz_srcptr)JCL_GetRawData (env, e);
812
  _m = (mpz_srcptr)JCL_GetRawData (env, m);
813
  _r = (mpz_ptr)JCL_GetRawData (env, r);
814
  /* the documentation of mpz_powm(rop, b, e, m) states that it: "Set rop to
815
   * (b raised to e) modulo m.  Negative e is supported if an inverse b^-1 mod m
816
   * exists.... If an inverse doesn't exist then a divide by zero is raised."
817
   * to work around this case we use the same code as in the pure java class;
818
   * i.e.:
819
   *     if (e.isNegative())
820
   *       return this.modInverse(m).modPow(e.negate(), m); */
821
  if (mpz_sgn (_e) == -1)
822
    {
823
      mpz_t _w;  /* a temporary work mpi */
824
      const int res = mpz_invert (_r, _this, _m);
825
      if (res == 0)
826
        {
827
          JCL_ThrowException (env, "java/lang/ArithmeticException",
828
                              "No multiplicative inverse modulo the designated number exists");
829
        }
830
      mpz_init (_w);
831
      mpz_neg (_w, _e);
832
      mpz_powm (_r, _r, _w, _m);
833
      mpz_clear (_w);
834
    }
835
  else
836
    {
837
      mpz_powm (_r, _this, _e, _m);
838
    }
839
 
840
  while (mpz_sgn (_r) == -1)
841
    {
842
      mpz_add (_r, _r, _m);
843
    }
844
  TRACE("end");
845
#else /* !defined(WITH_GNU_MP) */
846
  (void) this;
847
  (void) e;
848
  (void) m;
849
  (void) r;
850
  throw_config_exception(env);
851
#endif /* defined(WITH_GNU_MP) */
852
}
853
 
854
/*
855
 * @param this  an instance of NativeMPI.
856
 * @param m  an instance of NativeMPI's Pointer.
857
 *
858
 * output:
859
 * @param r  a NativeMPI's Pointer such that r = (1 / this) mod m.
860
 * @throws java.lang.ArithmeticException if (1 / this) mod m has no
861
 *         multiplicative inverse.
862
 */
863
JNIEXPORT void JNICALL
864
Java_gnu_java_math_GMP_natModInverse(JNIEnv *env,
865
                                                       jobject this,
866
                                                       jobject m, jobject r)
867
{
868
#if defined(WITH_GNU_MP)
869
  mpz_srcptr _this, _m;
870
  mpz_ptr _r;
871
  int res;
872
 
873
  TRACE("begin");
874
  _this = (mpz_srcptr)JCL_GetRawData (env, (*env)->GetObjectField (env, this, native_ptr));
875
  _m = (mpz_srcptr)JCL_GetRawData (env, m);
876
  _r = (mpz_ptr)JCL_GetRawData (env, r);
877
  res = mpz_invert (_r, _this, _m);
878
  if (res == 0)
879
    {
880
      JCL_ThrowException (env, "java/lang/ArithmeticException",
881
                          "No multiplicative inverse modulo the designated number exists");
882
    }
883
 
884
  while (mpz_sgn (_r) == -1)
885
    {
886
      mpz_add (_r, _r, _m);
887
    }
888
  TRACE("end");
889
#else /* !defined(WITH_GNU_MP) */
890
  (void) this;
891
  (void) x;
892
  (void) r;
893
  throw_config_exception(env);
894
#endif /* defined(WITH_GNU_MP) */
895
}
896
 
897
/*
898
 * @param this  an instance of NativeMPI.
899
 * @param x  an instance of NativeMPI's Pointer.
900
 *
901
 * output:
902
 * @param r  a NativeMPI's Pointer such that r is the GCD of this and x.
903
 */
904
JNIEXPORT void JNICALL
905
Java_gnu_java_math_GMP_natGCD(JNIEnv *env, jobject this,
906
                                                jobject x, jobject r)
907
{
908
#if defined(WITH_GNU_MP)
909
  mpz_srcptr _this, _x;
910
  mpz_ptr _r;
911
 
912
  TRACE("begin");
913
  _this = (mpz_srcptr)JCL_GetRawData (env, (*env)->GetObjectField (env, this, native_ptr));
914
  _x = (mpz_srcptr)JCL_GetRawData (env, x);
915
  _r = (mpz_ptr)JCL_GetRawData (env, r);
916
  mpz_gcd (_r, _this, _x);
917
  TRACE("end");
918
#else /* !defined(WITH_GNU_MP) */
919
  (void) this;
920
  (void) x;
921
  (void) r;
922
  throw_config_exception(env);
923
#endif /* defined(WITH_GNU_MP) */
924
}
925
 
926
/*
927
 * @param this  an instance of NativeMPI.
928
 * @param n  number of Miller-Rabin tests to conduct.
929
 * @return  2 if this is definitely prime. Returns 1 if this is probably prime
930
 *          (without being certain). Finally, returns 0 if this is definitely
931
 *          composite.
932
 */
933
JNIEXPORT jint JNICALL
934
Java_gnu_java_math_GMP_natTestPrimality(JNIEnv *env,
935
                                                          jobject this, jint n)
936
{
937
#if defined(WITH_GNU_MP)
938
  mpz_srcptr _this;
939
 
940
  TRACE("begin");
941
  _this = (mpz_srcptr)JCL_GetRawData (env, (*env)->GetObjectField (env, this, native_ptr));
942
  TRACE("end");
943
  return ((jint)mpz_probab_prime_p (_this, (int)n));
944
#else /* !defined(WITH_GNU_MP) */
945
  (void) this;
946
  (void) n;
947
  throw_config_exception(env);
948
  return (0);
949
#endif /* defined(WITH_GNU_MP) */
950
}
951
 
952
/*
953
 * @param this  an instance of NativeMPI.
954
 * @param n  the non-negative number of positions to shift right this by.
955
 *
956
 * output:
957
 * @param r  a NativeMPI's Pointer such that r = this * 2**n.
958
 */
959
JNIEXPORT void JNICALL
960
Java_gnu_java_math_GMP_natShiftLeft(JNIEnv *env, jobject this,
961
                                                      jint n, jobject r)
962
{
963
#if defined(WITH_GNU_MP)
964
  mpz_srcptr _this;
965
  mpz_ptr _r;
966
 
967
  TRACE("begin");
968
  _this = (mpz_srcptr)JCL_GetRawData (env, (*env)->GetObjectField (env, this, native_ptr));
969
  _r = (mpz_ptr)JCL_GetRawData (env, r);
970
  mpz_mul_2exp (_r, _this, (unsigned long)n);
971
  TRACE("end");
972
#else /* !defined(WITH_GNU_MP) */
973
  (void) this;
974
  (void) n;
975
  (void) r;
976
  throw_config_exception(env);
977
#endif /* defined(WITH_GNU_MP) */
978
}
979
 
980
/*
981
 * @param this  an instance of NativeMPI.
982
 * @param n  the non-negative number of positions to shift left this by.
983
 *
984
 * output:
985
 * @param r  a NativeMPI's Pointer such that r = floor(this / 2**n).
986
 */
987
JNIEXPORT void JNICALL
988
Java_gnu_java_math_GMP_natShiftRight(JNIEnv *env,
989
                                                       jobject this, jint n,
990
                                                       jobject r)
991
{
992
#if defined(WITH_GNU_MP)
993
  mpz_srcptr _this;
994
  mpz_ptr _r;
995
 
996
  TRACE("begin");
997
  _this = (mpz_srcptr)JCL_GetRawData (env, (*env)->GetObjectField (env, this, native_ptr));
998
  _r = (mpz_ptr)JCL_GetRawData (env, r);
999
  mpz_fdiv_q_2exp (_r, _this, (unsigned long)n);
1000
  TRACE("end");
1001
#else /* !defined(WITH_GNU_MP) */
1002
  (void) this;
1003
  (void) n;
1004
  (void) r;
1005
  throw_config_exception(env);
1006
#endif /* defined(WITH_GNU_MP) */
1007
}
1008
 
1009
/*
1010
 * @param this  an instance of NativeMPI.
1011
 * @return  the 0-based index of the lowest significant bit set (to 1) in this.
1012
 */
1013
JNIEXPORT jint JNICALL
1014
Java_gnu_java_math_GMP_natLowestSetBit(JNIEnv *env,
1015
                                                         jobject this)
1016
{
1017
#if defined(WITH_GNU_MP)
1018
  mpz_srcptr _this;
1019
 
1020
  TRACE("begin");
1021
  _this = (mpz_srcptr)JCL_GetRawData (env, (*env)->GetObjectField (env, this, native_ptr));
1022
  TRACE("end");
1023
  return ((jint)mpz_scan1 (_this, 0));
1024
#else /* !defined(WITH_GNU_MP) */
1025
  (void) this;
1026
  throw_config_exception(env);
1027
  return (-1);
1028
#endif /* defined(WITH_GNU_MP) */
1029
}
1030
 
1031
/*
1032
 * @param this  an instance of NativeMPI.
1033
 *
1034
 * output:
1035
 * @param r  a NativeMPI's Pointer such that r = abs(x).
1036
 */
1037
JNIEXPORT void JNICALL
1038
Java_gnu_java_math_GMP_natAbs(JNIEnv *env, jobject this,
1039
                                                jobject r)
1040
{
1041
#if defined(WITH_GNU_MP)
1042
  mpz_srcptr _this;
1043
  mpz_ptr _r;
1044
 
1045
  TRACE("begin");
1046
  _this = (mpz_srcptr)JCL_GetRawData (env, (*env)->GetObjectField (env, this, native_ptr));
1047
  _r = (mpz_ptr)JCL_GetRawData (env, r);
1048
  mpz_abs (_r, _this);
1049
  TRACE("end");
1050
#else /* !defined(WITH_GNU_MP) */
1051
  (void) this;
1052
  (void) r;
1053
  throw_config_exception(env);
1054
#endif /* defined(WITH_GNU_MP) */
1055
}
1056
 
1057
/*
1058
 * @param this  an instance of NativeMPI.
1059
 *
1060
 * output:
1061
 * @param r  a NativeMPI's Pointer such that r = -x.
1062
 */
1063
JNIEXPORT void JNICALL
1064
Java_gnu_java_math_GMP_natNegate(JNIEnv *env, jobject this,
1065
                                                   jobject r)
1066
{
1067
#if defined(WITH_GNU_MP)
1068
  mpz_srcptr _this;
1069
  mpz_ptr _r;
1070
 
1071
  TRACE("begin");
1072
  _this = (mpz_srcptr)JCL_GetRawData (env, (*env)->GetObjectField (env, this, native_ptr));
1073
  _r = (mpz_ptr)JCL_GetRawData (env, r);
1074
  mpz_neg (_r, _this);
1075
  TRACE("end");
1076
#else /* !defined(WITH_GNU_MP) */
1077
  (void) this;
1078
  (void) r;
1079
  throw_config_exception(env);
1080
#endif /* defined(WITH_GNU_MP) */
1081
}
1082
 
1083
/*
1084
 * @param this  an instance of NativeMPI.
1085
 * @return  the number of bits needed to represent this.
1086
 */
1087
JNIEXPORT jint JNICALL
1088
Java_gnu_java_math_GMP_natBitLength(JNIEnv *env, jobject this)
1089
{
1090
#if defined(WITH_GNU_MP)
1091
  mpz_srcptr _this;
1092
 
1093
  TRACE("begin");
1094
  _this = (mpz_srcptr)JCL_GetRawData (env, (*env)->GetObjectField (env, this, native_ptr));
1095
  TRACE("end");
1096
  return ((jint)mpz_sizeinbase (_this, 2));
1097
#else /* !defined(WITH_GNU_MP) */
1098
  (void) this;
1099
  throw_config_exception(env);
1100
  return (-1);
1101
#endif /* defined(WITH_GNU_MP) */
1102
}
1103
 
1104
/*
1105
 * @param this  an instance of NativeMPI. It MUST be >= ZERO.
1106
 * @return  the number of bits set (to 1) in this.
1107
 */
1108
JNIEXPORT jint JNICALL
1109
Java_gnu_java_math_GMP_natSetBitCount(JNIEnv *env,
1110
                                                        jobject this)
1111
{
1112
#if defined(WITH_GNU_MP)
1113
  mpz_srcptr _this;
1114
  mpz_ptr _bi;
1115
  unsigned long res = 0;
1116
 
1117
  TRACE("begin");
1118
  _this = (mpz_srcptr)JCL_GetRawData (env, (*env)->GetObjectField (env, this, native_ptr));
1119
  switch (mpz_sgn (_this))
1120
    {
1121
      case -1:
1122
        /* initialize --GMP sets the value to zero. */
1123
        _bi = (mpz_ptr)JCL_malloc (env, sizeof (mpz_t));
1124
        mpz_init (_bi);
1125
        mpz_neg (_bi, _this);
1126
        res = mpz_popcount (_bi);
1127
        mpz_clear (_bi);
1128
        free (_bi);
1129
        break;
1130
      case 0:
1131
        res = 0;
1132
        break;
1133
      case 1:
1134
        res = mpz_popcount (_this);
1135
      default:
1136
        JCL_ThrowException (env, "java/lang/Error",
1137
                            "Unexpected sign value for a native MPI");
1138
    }
1139
  TRACE("end");
1140
  return ((jint)res);
1141
#else /* !defined(WITH_GNU_MP) */
1142
  (void) this;
1143
  throw_config_exception(env);
1144
  return (ULONG_MAX);
1145
#endif /* defined(WITH_GNU_MP) */
1146
}
1147
 
1148
/*
1149
 * @param this  an instance of NativeMPI.
1150
 * @param x  an instance of NativeMPI's Pointer.
1151
 *
1152
 * output:
1153
 * @param r  a NativeMPI's Pointer such that r = this ^ x.
1154
 */
1155
JNIEXPORT void JNICALL
1156
Java_gnu_java_math_GMP_natXor(JNIEnv *env, jobject this,
1157
                                                jobject x, jobject r)
1158
{
1159
#if defined(WITH_GNU_MP)
1160
  mpz_srcptr _this, _x;
1161
  mpz_ptr _r;
1162
 
1163
  TRACE("begin");
1164
  _this = (mpz_srcptr)JCL_GetRawData (env, (*env)->GetObjectField (env, this, native_ptr));
1165
  _x = (mpz_srcptr)JCL_GetRawData (env, x);
1166
  _r = (mpz_ptr)JCL_GetRawData (env, r);
1167
  mpz_xor (_r, _this, _x);
1168
  TRACE("end");
1169
#else /* !defined(WITH_GNU_MP) */
1170
  (void) this;
1171
  (void) x;
1172
  (void) r;
1173
  throw_config_exception(env);
1174
#endif /* defined(WITH_GNU_MP) */
1175
}
1176
 
1177
/*
1178
 * @param this  an instance of NativeMPI.
1179
 * @param x  an instance of NativeMPI's Pointer.
1180
 *
1181
 * output:
1182
 * @param r  a NativeMPI's Pointer such that r = this | x.
1183
 */
1184
JNIEXPORT void JNICALL
1185
Java_gnu_java_math_GMP_natOr(JNIEnv *env, jobject this,
1186
                                               jobject x, jobject r)
1187
{
1188
#if defined(WITH_GNU_MP)
1189
  mpz_srcptr _this, _x;
1190
  mpz_ptr _r;
1191
 
1192
  TRACE("begin");
1193
  _this = (mpz_srcptr)JCL_GetRawData (env, (*env)->GetObjectField (env, this, native_ptr));
1194
  _x = (mpz_srcptr)JCL_GetRawData (env, x);
1195
  _r = (mpz_ptr)JCL_GetRawData (env, r);
1196
  mpz_ior (_r, _this, _x);
1197
  TRACE("end");
1198
#else /* !defined(WITH_GNU_MP) */
1199
  (void) this;
1200
  (void) x;
1201
  (void) r;
1202
  throw_config_exception(env);
1203
#endif /* defined(WITH_GNU_MP) */
1204
}
1205
 
1206
/*
1207
 * @param this  an instance of NativeMPI.
1208
 * @param x  an instance of NativeMPI's Pointer.
1209
 *
1210
 * output:
1211
 * @param r  a NativeMPI's Pointer such that r = this & x.
1212
 */
1213
JNIEXPORT void JNICALL
1214
Java_gnu_java_math_GMP_natAnd(JNIEnv *env, jobject this,
1215
                                                jobject x, jobject r)
1216
{
1217
#if defined(WITH_GNU_MP)
1218
  mpz_srcptr _this, _x;
1219
  mpz_ptr _r;
1220
 
1221
  TRACE("begin");
1222
  _this = (mpz_srcptr)JCL_GetRawData (env, (*env)->GetObjectField (env, this, native_ptr));
1223
  _x = (mpz_srcptr)JCL_GetRawData (env, x);
1224
  _r = (mpz_ptr)JCL_GetRawData (env, r);
1225
  mpz_and (_r, _this, _x);
1226
  TRACE("end");
1227
#else /* !defined(WITH_GNU_MP) */
1228
  (void) this;
1229
  (void) x;
1230
  (void) r;
1231
  throw_config_exception(env);
1232
#endif /* defined(WITH_GNU_MP) */
1233
}
1234
 
1235
/*
1236
 * @param this  an instance of NativeMPI.
1237
 * @param x  an instance of NativeMPI's Pointer.
1238
 *
1239
 * output:
1240
 * @param r  a NativeMPI's Pointer such that r = this & ~x.
1241
 */
1242
JNIEXPORT void JNICALL
1243
Java_gnu_java_math_GMP_natAndNot(JNIEnv *env, jobject this,
1244
                                                   jobject x, jobject r)
1245
{
1246
#if defined(WITH_GNU_MP)
1247
  mpz_srcptr _this, _x;
1248
  mpz_ptr _r;
1249
 
1250
  TRACE("begin");
1251
  _this = (mpz_srcptr)JCL_GetRawData (env, (*env)->GetObjectField (env, this, native_ptr));
1252
  _x = (mpz_srcptr)JCL_GetRawData (env, x);
1253
  _r = (mpz_ptr)JCL_GetRawData (env, r);
1254
  mpz_com (_r, _x);
1255
  mpz_and (_r, _this, _r);
1256
  TRACE("end");
1257
#else /* !defined(WITH_GNU_MP) */
1258
  (void) this;
1259
  (void) x;
1260
  (void) r;
1261
  throw_config_exception(env);
1262
#endif /* defined(WITH_GNU_MP) */
1263
}
1264
 
1265
/*
1266
 * @param this  an instance of NativeMPI.
1267
 * @param n  the 0-based index position of the bit to flip in this. n MUST be
1268
 *           greater than, or equal to 0.
1269
 *
1270
 * output:
1271
 * @param r  a copy of this NativeMPI's Pointer with its n-th bit flipped.
1272
 */
1273
JNIEXPORT void JNICALL
1274
Java_gnu_java_math_GMP_natFlipBit(JNIEnv *env, jobject this,
1275
                                                    jint n, jobject r)
1276
{
1277
#if defined(WITH_GNU_MP)
1278
  mpz_srcptr _this;
1279
  mpz_ptr _r;
1280
 
1281
  TRACE("begin");
1282
  _this = (mpz_srcptr)JCL_GetRawData (env, (*env)->GetObjectField (env, this, native_ptr));
1283
  _r = (mpz_ptr)JCL_GetRawData (env, r);
1284
  mpz_set (_r, _this);
1285
  /* GNU MP versions earlier than 4.2 do not define this method:
1286
   *   mpz_combit (_r, (unsigned long)n); */
1287
  if (mpz_tstbit (_r, (unsigned long)n) == 1)
1288
    {
1289
      mpz_clrbit (_r, (unsigned long)n);
1290
    }
1291
  else
1292
    {
1293
      mpz_setbit (_r, (unsigned long)n);
1294
    }
1295
  TRACE("end");
1296
#else /* !defined(WITH_GNU_MP) */
1297
  (void) this;
1298
  (void) n;
1299
  (void) r;
1300
  throw_config_exception(env);
1301
#endif /* defined(WITH_GNU_MP) */
1302
}
1303
 
1304
/*
1305
 * @param this  an instance of NativeMPI.
1306
 * @param n  the 0-based index position of the bit to test in this. n MUST be
1307
 *           greater than, or equal to 0.
1308
 * @return  +1, or -1 depending on whether the n-th bit in this is set or not
1309
 *          respectively.
1310
 */
1311
JNIEXPORT jint JNICALL
1312
Java_gnu_java_math_GMP_natTestBit(JNIEnv *env, jobject this,
1313
                                                    jint n)
1314
{
1315
#if defined(WITH_GNU_MP)
1316
  mpz_srcptr _this;
1317
 
1318
  TRACE("begin");
1319
  _this = (mpz_srcptr)JCL_GetRawData (env, (*env)->GetObjectField (env, this, native_ptr));
1320
  TRACE("end");
1321
  return ((jint)mpz_tstbit (_this, (unsigned long)n));
1322
#else /* !defined(WITH_GNU_MP) */
1323
  (void) this;
1324
  (void) n;
1325
  throw_config_exception(env);
1326
  return (-1);
1327
#endif /* defined(WITH_GNU_MP) */
1328
}
1329
 
1330
/*
1331
 * @param this  an instance of NativeMPI.
1332
 * @param n  the 0-based index position of the bit to set, or clear, in this.
1333
 *           n MUST be greater than, or equal to 0.
1334
 * @param setIt  if true, then the n-th bit in this will be set, otherwise it
1335
 *           will be cleared.
1336
 *
1337
 * output:
1338
 * @param r  a copy of this NativeMPI's Pointer with its n-th bit set or cleared
1339
 *           as requested.
1340
 */
1341
JNIEXPORT void JNICALL
1342
Java_gnu_java_math_GMP_natSetBit(JNIEnv *env, jobject this,
1343
                                                   jint n, jboolean setIt,
1344
                                                   jobject r)
1345
{
1346
#if defined(WITH_GNU_MP)
1347
  mpz_srcptr _this;
1348
  mpz_ptr _r;
1349
 
1350
  TRACE("begin");
1351
  _this = (mpz_srcptr)JCL_GetRawData (env, (*env)->GetObjectField (env, this, native_ptr));
1352
  _r = (mpz_ptr)JCL_GetRawData (env, r);
1353
  mpz_set (_r, _this);
1354
  if (setIt == JNI_TRUE)
1355
    {
1356
      mpz_setbit (_r, (unsigned long)n);
1357
    }
1358
  else
1359
    {
1360
      mpz_clrbit (_r, (unsigned long)n);
1361
    }
1362
  TRACE("end");
1363
#else /* !defined(WITH_GNU_MP) */
1364
  (void) this;
1365
  (void) n;
1366
  (void) setIt;
1367
  (void) r;
1368
  throw_config_exception(env);
1369
#endif /* defined(WITH_GNU_MP) */
1370
}
1371
 
1372
/*
1373
 * @param this  an instance of NativeMPI.
1374
 *
1375
 * output:
1376
 * @param r  a NativeMPI's Pointer such that r = ~this.
1377
 */
1378
JNIEXPORT void JNICALL
1379
Java_gnu_java_math_GMP_natNot(JNIEnv *env, jobject this,
1380
                                                jobject r)
1381
{
1382
#if defined(WITH_GNU_MP)
1383
  mpz_srcptr _this;
1384
  mpz_ptr _r;
1385
 
1386
  TRACE("begin");
1387
  _this = (mpz_srcptr)JCL_GetRawData (env, (*env)->GetObjectField (env, this, native_ptr));
1388
  _r = (mpz_ptr)JCL_GetRawData (env, r);
1389
  mpz_com (_r, _this);
1390
  TRACE("end");
1391
#else /* !defined(WITH_GNU_MP) */
1392
  (void) this;
1393
  (void) r;
1394
  throw_config_exception(env);
1395
#endif /* defined(WITH_GNU_MP) */
1396
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.