Skip to content

Commit 0b24db1

Browse files
committed
[XLS][c_api] add the following c-apis
- xls_bits_to_bytes - xls_bits_to_uint64 - xls_bits_to_int64 Signed-off-by: Hui Peng <[email protected]>
1 parent 0de695d commit 0b24db1

File tree

4 files changed

+148
-0
lines changed

4 files changed

+148
-0
lines changed

xls/public/c_api.cc

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
#include <string.h> // NOLINT(modernize-deprecated-headers)
1818

19+
#include <algorithm>
1920
#include <cstddef>
2021
#include <cstdint>
2122
#include <cstdlib>
@@ -454,6 +455,50 @@ bool xls_bits_get_bit(const struct xls_bits* bits, int64_t index) {
454455
return cpp_bits->Get(index);
455456
}
456457

458+
bool xls_bits_to_bytes(const struct xls_bits* bits, char** error_out,
459+
uint8_t** bytes_out, size_t* byte_count_out) {
460+
CHECK(bits != nullptr);
461+
CHECK(bytes_out != nullptr);
462+
CHECK(error_out != nullptr);
463+
CHECK(byte_count_out != nullptr);
464+
const auto* cpp_bits = reinterpret_cast<const xls::Bits*>(bits);
465+
std::vector<uint8_t> bytes = cpp_bits->ToBytes();
466+
*byte_count_out = bytes.size();
467+
*bytes_out = new uint8_t[bytes.size()];
468+
std::copy(bytes.begin(), bytes.end(), *bytes_out);
469+
return true;
470+
}
471+
472+
bool xls_bits_to_uint64(const struct xls_bits* bits, char** error_out,
473+
uint64_t* value_out) {
474+
CHECK(bits != nullptr);
475+
CHECK(value_out != nullptr);
476+
CHECK(error_out != nullptr);
477+
const auto* cpp_bits = reinterpret_cast<const xls::Bits*>(bits);
478+
absl::StatusOr<uint64_t> result = cpp_bits->ToUint64();
479+
if (!result.ok()) {
480+
*error_out = xls::ToOwnedCString(result.status().ToString());
481+
return false;
482+
}
483+
*value_out = result.value();
484+
return true;
485+
}
486+
487+
bool xls_bits_to_int64(const struct xls_bits* bits, char** error_out,
488+
int64_t* value_out) {
489+
CHECK(bits != nullptr);
490+
CHECK(value_out != nullptr);
491+
CHECK(error_out != nullptr);
492+
const auto* cpp_bits = reinterpret_cast<const xls::Bits*>(bits);
493+
absl::StatusOr<int64_t> result = cpp_bits->ToInt64();
494+
if (!result.ok()) {
495+
*error_out = xls::ToOwnedCString(result.status().ToString());
496+
return false;
497+
}
498+
*value_out = result.value();
499+
return true;
500+
}
501+
457502
struct xls_bits* xls_bits_width_slice(const struct xls_bits* bits,
458503
int64_t start, int64_t width) {
459504
CHECK(bits != nullptr);
@@ -704,6 +749,10 @@ void xls_c_strs_free(char** c_strs, size_t count) {
704749
delete[] c_strs;
705750
}
706751

752+
void xls_bytes_free(uint8_t *bytes) {
753+
delete[] bytes;
754+
}
755+
707756
bool xls_value_to_string(const struct xls_value* v, char** string_out) {
708757
CHECK(v != nullptr);
709758
CHECK(string_out != nullptr);

xls/public/c_api.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,23 @@ bool xls_bits_eq(const struct xls_bits* a, const struct xls_bits* b);
213213
// returns 1, `xls_bits_get_bit(bits, 1)` returns 0.
214214
bool xls_bits_get_bit(const struct xls_bits* bits, int64_t index);
215215

216+
// Converts the given bits value to a byte array, whose length is saved in
217+
// byte_count_out. The caller must free the returned `bytes_out` pointer
218+
// via `xls_bytes_free` if xls_bits_to_bytes returns true.
219+
// If the conversion fails and it returns false, error_out is populated
220+
// with an error message and the caller must free the
221+
// `error_out` pointer with `xls_c_str_free`.
222+
bool xls_bits_to_bytes(const struct xls_bits* bits, char** error_out,
223+
uint8_t** bytes_out, size_t* byte_count_out);
224+
225+
// Converts the given bits value to a signed or unsigned integer 64-bit integer
226+
// value. If the conversion is not possible, false is returned, `error_out`
227+
// contains the error message and the caller must free the `error_out` pointer
228+
// with `xls_c_str_free`.
229+
bool xls_bits_to_uint64(const struct xls_bits* bits, char** error_out,
230+
uint64_t* value_out);
231+
bool xls_bits_to_int64(const struct xls_bits* bits, char** error_out,
232+
int64_t* value_out);
216233
struct xls_bits* xls_bits_width_slice(const struct xls_bits* bits,
217234
int64_t start, int64_t width);
218235

@@ -319,6 +336,11 @@ void xls_c_str_free(char* c_str);
319336
// Frees an array of C strings that were provided by this XLS public API.
320337
void xls_c_strs_free(char** c_strs, size_t count);
321338

339+
340+
// Frees the given `bytes` -- the bytes should have been allocated by the
341+
// XLS library where ownership was passed back to the caller.
342+
void xls_bytes_free(uint8_t* bytes);
343+
322344
// Returns a string representation of the given IR package `p`.
323345
bool xls_package_to_string(const struct xls_package* p, char** string_out);
324346

xls/public/c_api_symbols.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,11 @@ xls_bits_shift_right_arithmetic
1515
xls_bits_shift_right_logical
1616
xls_bits_smul
1717
xls_bits_sub
18+
xls_bits_to_bytes
1819
xls_bits_to_debug_string
20+
xls_bits_to_int64
1921
xls_bits_to_string
22+
xls_bits_to_uint64
2023
xls_bits_umul
2124
xls_bits_width_slice
2225
xls_bits_xor
@@ -56,6 +59,7 @@ xls_builder_base_add_xor
5659
xls_builder_base_add_xor_reduce
5760
xls_builder_base_add_zero_extend
5861
xls_bvalue_free
62+
xls_bytes_free
5963
xls_c_str_free
6064
xls_c_strs_free
6165
xls_convert_dslx_path_to_ir

xls/public/c_api_test.cc

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
#include <cstddef>
1818
#include <cstdint>
19+
#include <cstdlib>
1920
#include <filesystem> // NOLINT
2021
#include <functional>
2122
#include <initializer_list>
@@ -435,6 +436,78 @@ TEST(XlsCApiTest, MakeBitsFromUint8DataWithMsbPadding) {
435436
EXPECT_EQ(xls_bits_get_bit(bits, 5), 1);
436437
}
437438

439+
TEST(XlsCApiTest, BitsToBytes) {
440+
char* error_out = nullptr;
441+
xls_bits* bits = nullptr;
442+
ASSERT_TRUE(xls_bits_make_ubits(32, 0x0A0B0C0D, &error_out, &bits));
443+
uint8_t* bytes = nullptr;
444+
size_t byte_count = 0;
445+
446+
absl::Cleanup free_memory([&error_out, &bits, &bytes] {
447+
xls_c_str_free(error_out);
448+
xls_bits_free(bits);
449+
xls_bytes_free(bytes);
450+
});
451+
452+
ASSERT_TRUE(xls_bits_to_bytes(bits, &error_out, &bytes, &byte_count));
453+
EXPECT_EQ(byte_count, 4);
454+
EXPECT_EQ(bytes[0], 0x0D);
455+
EXPECT_EQ(bytes[1], 0x0C);
456+
EXPECT_EQ(bytes[2], 0x0B);
457+
EXPECT_EQ(bytes[3], 0x0A);
458+
}
459+
460+
TEST(XlsCApiTest, BitsToBytesWithPadding) {
461+
char* error_out = nullptr;
462+
xls_bits* bits = nullptr;
463+
ASSERT_TRUE(xls_bits_make_ubits(
464+
34, 0b11'0000'0000'0000'0000'0000'0000'0000'0000, &error_out, &bits));
465+
uint8_t* bytes = nullptr;
466+
size_t byte_count = 0;
467+
468+
absl::Cleanup free_memory([&error_out, &bits, &bytes] {
469+
xls_c_str_free(error_out);
470+
xls_bits_free(bits);
471+
xls_bytes_free(bytes);
472+
});
473+
474+
ASSERT_TRUE(xls_bits_to_bytes(bits, &error_out, &bytes, &byte_count));
475+
EXPECT_EQ(byte_count, 5);
476+
EXPECT_EQ(bytes[0], 0x00);
477+
EXPECT_EQ(bytes[1], 0x00);
478+
EXPECT_EQ(bytes[2], 0x00);
479+
EXPECT_EQ(bytes[3], 0x00);
480+
EXPECT_EQ(bytes[4], 0b11);
481+
}
482+
483+
TEST(XlsCApiTest, BitsToUint64Fit) {
484+
char* error_out = nullptr;
485+
xls_bits* bits = nullptr;
486+
ASSERT_TRUE(xls_bits_make_ubits(64, 0x0A0B0C0D, &error_out, &bits));
487+
absl::Cleanup free_memory([&error_out, &bits] {
488+
xls_c_str_free(error_out);
489+
xls_bits_free(bits);
490+
});
491+
492+
uint64_t value = 0;
493+
ASSERT_TRUE(xls_bits_to_uint64(bits, &error_out, &value));
494+
EXPECT_EQ(value, 0x0A0B0C0D);
495+
}
496+
497+
TEST(XlsCApiTest, BitsToInt64Fit) {
498+
char* error_out = nullptr;
499+
xls_bits* bits = nullptr;
500+
ASSERT_TRUE(xls_bits_make_ubits(64, 0x0A0B0C0D, &error_out, &bits));
501+
absl::Cleanup free_memory([&error_out, &bits] {
502+
xls_c_str_free(error_out);
503+
xls_bits_free(bits);
504+
});
505+
506+
int64_t value = 0;
507+
ASSERT_TRUE(xls_bits_to_int64(bits, &error_out, &value));
508+
EXPECT_EQ(value, 0x0A0B0C0D);
509+
}
510+
438511
TEST(XlsCApiTest, MakeSbitsDoesNotFit) {
439512
char* error_out = nullptr;
440513
xls_bits* bits = nullptr;

0 commit comments

Comments
 (0)