Skip to content

Commit

Permalink
Support tcc
Browse files Browse the repository at this point in the history
Needed to add __builtin_uaddl_overflow implementation and make
kLargeintDigitSize a preprocessor macro and name a parameter.
  • Loading branch information
tekknolagi committed Dec 30, 2024
1 parent 89f14f1 commit 4966513
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 11 deletions.
7 changes: 4 additions & 3 deletions compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,7 @@ def _emit_const(self, exp: Object) -> str:
if isinstance(exp, Hole):
return "hole()"
if isinstance(exp, Int):
if -0x4000000000000000 <= exp.value <= 0x3fffffffffffffff:
if -0x4000000000000000 <= exp.value <= 0x3FFFFFFFFFFFFFFF:
return f"_mksmallint({exp.value}ULL)"
# Divide number into 64-bit digits
if exp.value < 0:
Expand All @@ -341,9 +341,9 @@ def _emit_const(self, exp: Object) -> str:
value = exp.value
digits = []
while value:
digits.append(value & 0xffffffffffffffff)
digits.append(value & 0xFFFFFFFFFFFFFFFF)
value >>= 64
tag = self._make_tag("TAG_LARGEINT", f"sizeof(struct large_int)+{len(digits)}ULL*kLargeintDigitSize")
tag = self._make_tag("TAG_LARGEINT", f"sizeof(struct large_int)+{len(digits)}ULL*kLargeIntDigitSize")
parts = ", ".join(f"{digit}ULL" for digit in digits)
return self._const_obj("large_int", tag, f".digits={{ {parts} }}")
if isinstance(exp, List):
Expand Down Expand Up @@ -485,6 +485,7 @@ def compile_to_string(program: Object, debug: bool) -> str:
("uword", "kPrimaryTagMask", "(1ULL << kPrimaryTagBits) - 1"),
("uword", "kImmediateTagMask", "(1ULL << kImmediateTagBits) - 1"),
("uword", "kWordSize", "sizeof(word)"),
("uword", "kLargeIntDigitSize", "sizeof(large_int_digit)"),
("uword", "kMaxSmallStringLength", "kWordSize - 1"),
("uword", "kBitsPerByte", 8),
# Up to the five least significant bits are used to tag the object's layout.
Expand Down
23 changes: 15 additions & 8 deletions runtime.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ typedef intptr_t word;
typedef uintptr_t uword;
typedef unsigned char byte;
typedef uint64_t large_int_digit;
const int kLargeintDigitSize = sizeof(large_int_digit);
const word kMinWord = INTPTR_MIN;
const word kMaxWord = INTPTR_MAX;
const uword kMaxUword = UINTPTR_MAX;
Expand Down Expand Up @@ -483,7 +482,7 @@ static ALWAYS_INLINE struct large_int* as_large_int(struct object* obj) {
uword large_int_num_digits(struct object* obj) {
assert(is_large_int(obj));
size_t size = heap_object_size(as_heap_object(obj)) - sizeof(struct gc_obj);
return size / kLargeintDigitSize;
return size / kLargeIntDigitSize;
}

uword num_digits(struct object* obj) {
Expand Down Expand Up @@ -523,15 +522,15 @@ uword digit_at(struct object* obj, uword index) {

struct object* _mklarge_int_uninit_private(struct gc_heap* heap,
uword num_digits) {
uword digits_size = num_digits * kLargeintDigitSize;
uword digits_size = num_digits * kLargeIntDigitSize;
uword size = align_size(sizeof(struct large_int) + digits_size);
return allocate(heap, TAG_LARGEINT, size);
}

struct object* _mklarge_int(struct gc_heap* heap, uword num_digits,
large_int_digit* digits) {
struct object* result = _mklarge_int_uninit_private(heap, num_digits);
uword digits_size = num_digits * kLargeintDigitSize;
uword digits_size = num_digits * kLargeIntDigitSize;
memcpy(as_large_int(result)->digits, digits, digits_size);
return result;
}
Expand Down Expand Up @@ -788,17 +787,25 @@ void trace_roots(struct gc_heap* heap, VisitFn visit) {
struct gc_heap heap_object;
struct gc_heap* heap = &heap_object;

#if !__has_builtin(__builtin_uaddl_overflow)
bool __builtin_uaddl_overflow(uword left, uword right, uword* result) {
*result = left + right;
return *result < left;
}
#endif

static uword add_with_carry(uword x, uword y, uword carry_in,
uword* carry_out) {
assert(carry_in <= 1 && "carry must be 0 or 1");
uword sum;
uword carry0 = __builtin_add_overflow(x, y, &sum);
uword carry1 = __builtin_add_overflow(sum, carry_in, &sum);
uword carry0 = __builtin_uaddl_overflow(x, y, &sum);
uword carry1 = __builtin_uaddl_overflow(sum, carry_in, &sum);
*carry_out = carry0 | carry1;
return sum;
}

struct object* normalize_large_int(struct gc_heap*, struct object* obj) {
struct object* normalize_large_int(struct gc_heap* heap, struct object* obj) {
(void)heap;
word num_digits = large_int_num_digits(obj);
word shrink_to_digits = num_digits;
for (word digit = large_int_digit_at(obj, shrink_to_digits - 1), next_digit;
Expand Down Expand Up @@ -968,7 +975,7 @@ struct object* print(struct object* obj) {
if (is_small_int(obj)) {
printf("%ld", num_value(obj));
} else if (is_large_int(obj)) {
printf("largeint%d(", kLargeintDigitSize * kPointerSize);
printf("largeint%d(", kLargeIntDigitSize * kPointerSize);
uword num_digits = large_int_num_digits(obj);
for (uword i = 0; i < num_digits; i++) {
if (i > 0) {
Expand Down

0 comments on commit 4966513

Please sign in to comment.