You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

113 lines
2.9 KiB

  1. #include <stdint.h> // for uint32_t etc
  2. #include <sylvan_config.h>
  3. #ifndef CACHE_H
  4. #define CACHE_H
  5. #ifdef __cplusplus
  6. extern "C" {
  7. #endif /* __cplusplus */
  8. #ifndef CACHE_MASK
  9. #define CACHE_MASK 1
  10. #endif
  11. /**
  12. * Operation cache
  13. *
  14. * Use cache_next_opid() at initialization time to generate unique "operation identifiers".
  15. * You should store these operation identifiers as static globals in your implementation .C/.CPP file.
  16. *
  17. * For custom operations, just use the following functions:
  18. * - cache_get3/cache_put3 for any operation with 1 BDD and 2 other values (that can be BDDs)
  19. * int success = cache_get3(opid, dd1, value2, value3, &result);
  20. * int success = cache_put3(opid, dd1, value2, value3, result);
  21. * - cache_get4/cache_put4 for any operation with 4 BDDs
  22. * int success = cache_get4(opid, dd1, dd2, dd3, dd4, &result);
  23. * int success = cache_get4(opid, dd1, dd2, dd3, dd4, result);
  24. *
  25. * Notes:
  26. * - The "result" is any 64-bit value
  27. * - Use "0" for unused parameters
  28. */
  29. typedef struct cache_entry *cache_entry_t;
  30. /**
  31. * Primitives for cache get/put
  32. */
  33. int cache_get(uint64_t a, uint64_t b, uint64_t c, uint64_t *res);
  34. int cache_put(uint64_t a, uint64_t b, uint64_t c, uint64_t res);
  35. /**
  36. * Helper function to get next 'operation id' (during initialization of modules)
  37. */
  38. uint64_t cache_next_opid();
  39. /**
  40. * dd must be MTBDD, d2/d3 can be anything
  41. */
  42. static inline int __attribute__((unused))
  43. cache_get3(uint64_t opid, uint64_t dd, uint64_t d2, uint64_t d3, uint64_t *res)
  44. {
  45. return cache_get(dd | opid, d2, d3, res);
  46. }
  47. /**
  48. * dd/dd2/dd3/dd4 must be MTBDDs
  49. */
  50. static inline int __attribute__((unused))
  51. cache_get4(uint64_t opid, uint64_t dd, uint64_t dd2, uint64_t dd3, uint64_t dd4, uint64_t *res)
  52. {
  53. uint64_t p2 = dd2 | ((dd4 & 0x00000000000fffff) << 40); // 20 bits and complement bit
  54. if (dd4 & 0x8000000000000000) p2 |= 0x4000000000000000;
  55. uint64_t p3 = dd3 | ((dd4 & 0x000000fffff00000) << 20); // 20 bits
  56. return cache_get3(opid, dd, p2, p3, res);
  57. }
  58. /**
  59. * dd must be MTBDD, d2/d3 can be anything
  60. */
  61. static inline int __attribute__((unused))
  62. cache_put3(uint64_t opid, uint64_t dd, uint64_t d2, uint64_t d3, uint64_t res)
  63. {
  64. return cache_put(dd | opid, d2, d3, res);
  65. }
  66. /**
  67. * dd/dd2/dd3/dd4 must be MTBDDs
  68. */
  69. static inline int __attribute__((unused))
  70. cache_put4(uint64_t opid, uint64_t dd, uint64_t dd2, uint64_t dd3, uint64_t dd4, uint64_t res)
  71. {
  72. uint64_t p2 = dd2 | ((dd4 & 0x00000000000fffff) << 40); // 20 bits and complement bit
  73. if (dd4 & 0x8000000000000000) p2 |= 0x4000000000000000;
  74. uint64_t p3 = dd3 | ((dd4 & 0x000000fffff00000) << 20); // 20 bits
  75. return cache_put3(opid, dd, p2, p3, res);
  76. }
  77. /**
  78. * Functions for Sylvan for cache management
  79. */
  80. void cache_create(size_t _cache_size, size_t _max_size);
  81. void cache_free();
  82. void cache_clear();
  83. void cache_setsize(size_t size);
  84. size_t cache_getused();
  85. size_t cache_getsize();
  86. size_t cache_getmaxsize();
  87. #ifdef __cplusplus
  88. }
  89. #endif /* __cplusplus */
  90. #endif