Merge pull request #5336 from roc-lang/dev-backend-list-map

dev backend: many more builtins
This commit is contained in:
Folkert de Vries 2023-05-01 10:20:15 +02:00 committed by GitHub
commit a5a91d428f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 900 additions and 373 deletions

View file

@ -73,6 +73,9 @@ comptime {
exportNumFn(num.bytesToU64C, "bytes_to_u64");
exportNumFn(num.bytesToU128C, "bytes_to_u128");
exportNumFn(num.shiftRightZeroFillI128, "shift_right_zero_fill.i128");
exportNumFn(num.shiftRightZeroFillU128, "shift_right_zero_fill.u128");
inline for (INTEGERS) |T, i| {
num.exportPow(T, ROC_BUILTINS ++ "." ++ NUM ++ ".pow_int.");
num.exportDivCeil(T, ROC_BUILTINS ++ "." ++ NUM ++ ".div_ceil.");
@ -91,6 +94,9 @@ comptime {
num.exportMulWithOverflow(T, WIDEINTS[i], ROC_BUILTINS ++ "." ++ NUM ++ ".mul_with_overflow.");
num.exportMulOrPanic(T, WIDEINTS[i], ROC_BUILTINS ++ "." ++ NUM ++ ".mul_or_panic.");
num.exportMulSaturatedInt(T, WIDEINTS[i], ROC_BUILTINS ++ "." ++ NUM ++ ".mul_saturated.");
num.exportMulWrappedInt(T, ROC_BUILTINS ++ "." ++ NUM ++ ".mul_wrapped.");
num.exportIsMultipleOf(T, ROC_BUILTINS ++ "." ++ NUM ++ ".is_multiple_of.");
num.exportCountLeadingZeroBits(T, ROC_BUILTINS ++ "." ++ NUM ++ ".count_leading_zero_bits.");
num.exportCountTrailingZeroBits(T, ROC_BUILTINS ++ "." ++ NUM ++ ".count_trailing_zero_bits.");

View file

@ -254,6 +254,30 @@ fn bytesToU128(arg: RocList, position: usize) u128 {
return @bitCast(u128, [_]u8{ bytes[position], bytes[position + 1], bytes[position + 2], bytes[position + 3], bytes[position + 4], bytes[position + 5], bytes[position + 6], bytes[position + 7], bytes[position + 8], bytes[position + 9], bytes[position + 10], bytes[position + 11], bytes[position + 12], bytes[position + 13], bytes[position + 14], bytes[position + 15] });
}
fn isMultipleOf(comptime T: type, lhs: T, rhs: T) bool {
if (rhs == 0 or rhs == -1) {
// lhs is a multiple of rhs iff
//
// - rhs == -1
// - both rhs and lhs are 0
//
// the -1 case is important for overflow reasons `isize::MIN % -1` crashes in rust
return (rhs == -1) or (lhs == 0);
} else {
const rem = @mod(lhs, rhs);
return rem == 0;
}
}
pub fn exportIsMultipleOf(comptime T: type, comptime name: []const u8) void {
comptime var f = struct {
fn func(self: T, other: T) callconv(.C) bool {
return @call(.{ .modifier = always_inline }, isMultipleOf, .{ T, self, other });
}
}.func;
@export(f, .{ .name = name ++ @typeName(T), .linkage = .Strong });
}
fn addWithOverflow(comptime T: type, self: T, other: T) WithOverflow(T) {
switch (@typeInfo(T)) {
.Int => {
@ -464,6 +488,31 @@ pub fn exportMulSaturatedInt(comptime T: type, comptime W: type, comptime name:
@export(f, .{ .name = name ++ @typeName(T), .linkage = .Strong });
}
pub fn exportMulWrappedInt(comptime T: type, comptime name: []const u8) void {
comptime var f = struct {
fn func(self: T, other: T) callconv(.C) T {
return self *% other;
}
}.func;
@export(f, .{ .name = name ++ @typeName(T), .linkage = .Strong });
}
pub fn shiftRightZeroFillI128(self: i128, other: u8) callconv(.C) i128 {
if (other & 0b1000_0000 > 0) {
return 0;
} else {
return self >> @intCast(u7, other);
}
}
pub fn shiftRightZeroFillU128(self: u128, other: u8) callconv(.C) u128 {
if (other & 0b1000_0000 > 0) {
return 0;
} else {
return self >> @intCast(u7, other);
}
}
pub fn exportMulOrPanic(comptime T: type, comptime W: type, comptime name: []const u8) void {
comptime var f = struct {
fn func(self: T, other: T) callconv(.C) T {

View file

@ -107,15 +107,16 @@ pub fn memcpy(dst: [*]u8, src: [*]u8, size: usize) void {
// indirection because otherwise zig creates an alias to the panic function which our LLVM code
// does not know how to deal with
pub fn test_panic(c_ptr: *anyopaque, alignment: u32) callconv(.C) void {
pub fn test_panic(c_ptr: *anyopaque, crash_tag: u32) callconv(.C) void {
_ = c_ptr;
_ = alignment;
// const cstr = @ptrCast([*:0]u8, c_ptr);
_ = crash_tag;
// const stderr = std.io.getStdErr().writer();
// stderr.print("Roc panicked: {s}!\n", .{cstr}) catch unreachable;
// std.c.exit(1);
// const cstr = @ptrCast([*:0]u8, c_ptr);
//
// const stderr = std.io.getStdErr().writer();
// stderr.print("Roc panicked: {s}!\n", .{cstr}) catch unreachable;
//
// std.c.exit(1);
}
pub const Inc = fn (?[*]u8) callconv(.C) void;

View file

@ -285,10 +285,16 @@ pub const NUM_SUB_CHECKED_FLOAT: IntrinsicName =
pub const NUM_MUL_OR_PANIC_INT: IntrinsicName = int_intrinsic!("roc_builtins.num.mul_or_panic");
pub const NUM_MUL_SATURATED_INT: IntrinsicName = int_intrinsic!("roc_builtins.num.mul_saturated");
pub const NUM_MUL_WRAP_INT: IntrinsicName = int_intrinsic!("roc_builtins.num.mul_wrapped");
pub const NUM_MUL_CHECKED_INT: IntrinsicName = int_intrinsic!("roc_builtins.num.mul_with_overflow");
pub const NUM_MUL_CHECKED_FLOAT: IntrinsicName =
float_intrinsic!("roc_builtins.num.mul_with_overflow");
pub const NUM_IS_MULTIPLE_OF: IntrinsicName = int_intrinsic!("roc_builtins.num.is_multiple_of");
pub const NUM_SHIFT_RIGHT_ZERO_FILL: IntrinsicName =
int_intrinsic!("roc_builtins.num.shift_right_zero_fill");
pub const NUM_COUNT_LEADING_ZERO_BITS: IntrinsicName =
int_intrinsic!("roc_builtins.num.count_leading_zero_bits");
pub const NUM_COUNT_TRAILING_ZERO_BITS: IntrinsicName =