File: wide-int_plugin.c

package info (click to toggle)
gcc-riscv64-unknown-elf 8.3.0.2019.08%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 680,956 kB
  • sloc: ansic: 3,237,715; cpp: 896,882; ada: 772,854; f90: 144,254; asm: 68,788; makefile: 67,456; sh: 29,743; exp: 28,045; objc: 15,273; fortran: 11,885; python: 7,369; pascal: 5,375; awk: 3,725; perl: 2,872; yacc: 316; xml: 311; ml: 285; lex: 198; haskell: 122
file content (79 lines) | stat: -rw-r--r-- 2,083 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#include "config.h"
#include "gcc-plugin.h"
#include "system.h"
#include "coretypes.h"
#include "tree.h"

int plugin_is_GPL_compatible;

static void
test_double_int_round_udiv (void)
{
  double_int dmin = { 0, HOST_WIDE_INT_MIN };
  double_int dmax = { (unsigned HOST_WIDE_INT)-1, HOST_WIDE_INT_MAX };
  double_int dnegone = { (unsigned HOST_WIDE_INT)-1, -1 };
  double_int mod, div;
  div = dmin.udivmod (dnegone, ROUND_DIV_EXPR, &mod);
  if (div.low != 1 || div.high != 0
      || mod.low != 1 || mod.high != HOST_WIDE_INT_MIN)
    abort ();
  div = dmax.udivmod (dnegone, ROUND_DIV_EXPR, &mod);
  if (div.low != 0 || div.high != 0
      || mod.low != dmax.low || mod.high != dmax.high)
    abort ();
}

static void
test_wide_int_round_sdiv (void)
{
  if (wi::ne_p (wi::div_round (2, 3, SIGNED), 1))
    abort ();
  if (wi::ne_p (wi::div_round (1, 3, SIGNED), 0))
    abort ();
  if (wi::ne_p (wi::mod_round (2, 3, SIGNED), -1))
    abort ();
  if (wi::ne_p (wi::mod_round (1, 3, SIGNED), 1))
    abort ();
}

static void
test_wide_int_mod_trunc (void)
{
  for (unsigned int i = 1; i < MAX_BITSIZE_MODE_ANY_INT; ++i)
    {
      if (wi::smod_trunc (wi::lshift (1, i + 1) - 3,
			  wi::lshift (1, i) - 1)
	  != wi::lshift (1, i) - 2)
	abort ();
      for (unsigned int base = 32; base <= MAX_BITSIZE_MODE_ANY_INT; base *= 2)
	for (int bias = -1; bias <= 1; ++bias)
	  {
	    unsigned int precision = base + bias;
	    if (i + 1 < precision && precision <= MAX_BITSIZE_MODE_ANY_INT)
	      {
		wide_int one = wi::uhwi (1, precision);
		wide_int a = wi::lshift (one, i + 1) - 3;
		wide_int b = wi::lshift (one, i) - 1;
		wide_int c = wi::lshift (one, i) - 2;
		if (wi::umod_trunc (a, b) != c)
		  abort ();
		if (wi::smod_trunc (a, b) != c)
		  abort ();
		if (wi::smod_trunc (-a, b) != -c)
		  abort ();
		if (wi::smod_trunc (a, -b) != c)
		  abort ();
	      }
	  }
    }
}

int
plugin_init (struct plugin_name_args *plugin_info,
	     struct plugin_gcc_version *version)
{
  test_double_int_round_udiv ();
  test_wide_int_round_sdiv ();
  test_wide_int_mod_trunc ();
  return 0;
}