Add saturated math and expect macros.

This commit is contained in:
Christoffer Lerno
2023-02-03 00:25:29 +01:00
parent 6407eb47a4
commit 6b928c7a3d
9 changed files with 124 additions and 2 deletions

View File

@@ -120,6 +120,17 @@ macro enum_by_name($Type, String enum_name) @builtin
return SearchResult.MISSING!;
}
macro bool @expect_true(bool value) @builtin => $$expect(value, true);
macro bool @expect_false(bool value) @builtin => $$expect(value, false);
/**
* @require values.is_int(value)
* @checked $typeof(value) a = expected
**/
macro @expect(value, expected) @builtin
{
return $$expect(value, ($typeof(value))expected);
}
/**
* Locality for prefetch, levels 0 - 3, corresponding
* to "extremely local" to "no locality"

View File

@@ -593,6 +593,56 @@ macro uint128 uint128[<*>].xor(uint128[<*>] x) => $$reduce_xor(x);
macro uint128 uint128[<*>].max(uint128[<*>] x) => $$reduce_max(x);
macro uint128 uint128[<*>].min(uint128[<*>] x) => $$reduce_min(x);
macro char char.sat_add(char x, char y) => $$sat_add(x, y);
macro char char.sat_sub(char x, char y) => $$sat_sub(x, y);
macro char char.sat_mul(char x, char y) => $$sat_mul(x, y);
macro char char.sat_shl(char x, char y) => $$sat_shl(x, y);
macro ichar ichar.sat_add(ichar x, ichar y) => $$sat_add(x, y);
macro ichar ichar.sat_sub(ichar x, ichar y) => $$sat_sub(x, y);
macro ichar ichar.sat_mul(ichar x, ichar y) => $$sat_mul(x, y);
macro ichar ichar.sat_shl(ichar x, ichar y) => $$sat_shl(x, y);
macro ushort ushort.sat_add(ushort x, ushort y) => $$sat_add(x, y);
macro ushort ushort.sat_sub(ushort x, ushort y) => $$sat_sub(x, y);
macro ushort ushort.sat_mul(ushort x, ushort y) => $$sat_mul(x, y);
macro ushort ushort.sat_shl(ushort x, ushort y) => $$sat_shl(x, y);
macro short short.sat_add(short x, short y) => $$sat_add(x, y);
macro short short.sat_sub(short x, short y) => $$sat_sub(x, y);
macro short short.sat_mul(short x, short y) => $$sat_mul(x, y);
macro short short.sat_shl(short x, short y) => $$sat_shl(x, y);
macro uint uint.sat_add(uint x, uint y) => $$sat_add(x, y);
macro uint uint.sat_sub(uint x, uint y) => $$sat_sub(x, y);
macro uint uint.sat_mul(uint x, uint y) => $$sat_mul(x, y);
macro uint uint.sat_shl(uint x, uint y) => $$sat_shl(x, y);
macro int int.sat_add(int x, int y) => $$sat_add(x, y);
macro int int.sat_sub(int x, int y) => $$sat_sub(x, y);
macro int int.sat_mul(int x, int y) => $$sat_mul(x, y);
macro int int.sat_shl(int x, int y) => $$sat_shl(x, y);
macro ulong ulong.sat_add(ulong x, ulong y) => $$sat_add(x, y);
macro ulong ulong.sat_sub(ulong x, ulong y) => $$sat_sub(x, y);
macro ulong ulong.sat_mul(ulong x, ulong y) => $$sat_mul(x, y);
macro ulong ulong.sat_shl(ulong x, ulong y) => $$sat_shl(x, y);
macro long long.sat_add(long x, long y) => $$sat_add(x, y);
macro long long.sat_sub(long x, long y) => $$sat_sub(x, y);
macro long long.sat_mul(long x, long y) => $$sat_mul(x, y);
macro long long.sat_shl(long x, long y) => $$sat_shl(x, y);
macro uint128 uint128.sat_add(uint128 x, uint128 y) => $$sat_add(x, y);
macro uint128 uint128.sat_sub(uint128 x, uint128 y) => $$sat_sub(x, y);
macro uint128 uint128.sat_mul(uint128 x, uint128 y) => $$sat_mul(x, y);
macro uint128 uint128.sat_shl(uint128 x, uint128 y) => $$sat_shl(x, y);
macro int128 int128.sat_add(int128 x, int128 y) => $$sat_add(x, y);
macro int128 int128.sat_sub(int128 x, int128 y) => $$sat_sub(x, y);
macro int128 int128.sat_mul(int128 x, int128 y) => $$sat_mul(x, y);
macro int128 int128.sat_shl(int128 x, int128 y) => $$sat_shl(x, y);
/**
* @checked x & 1
*/

View File

@@ -833,6 +833,8 @@ typedef enum
BUILTIN_EXACT_SUB,
BUILTIN_EXP,
BUILTIN_EXP2,
BUILTIN_EXPECT,
BUILTIN_EXPECT_WITH_PROBABILITY,
BUILTIN_FLOOR,
BUILTIN_FMA,
BUILTIN_FMULADD,
@@ -895,7 +897,6 @@ typedef enum
BUILTIN_VOLATILE_STORE,
BUILTIN_WASM_MEMORY_SIZE,
BUILTIN_WASM_MEMORY_GROW,
BUILTIN_NONE,
NUMBER_OF_BUILTINS = BUILTIN_NONE,

View File

@@ -633,6 +633,8 @@ static void llvm_codegen_setup()
intrinsic_id.cttz = lookup_intrinsic("llvm.cttz");
intrinsic_id.exp = lookup_intrinsic("llvm.exp");
intrinsic_id.exp2 = lookup_intrinsic("llvm.exp2");
intrinsic_id.expect = lookup_intrinsic("llvm.expect");
intrinsic_id.expect_with_probability = lookup_intrinsic("llvm.expect.with.probability");
intrinsic_id.fabs = lookup_intrinsic("llvm.fabs");
intrinsic_id.floor = lookup_intrinsic("llvm.floor");
intrinsic_id.fma = lookup_intrinsic("llvm.fma");

View File

@@ -424,6 +424,7 @@ void llvm_emit_simple_builtin(GenContext *c, BEValue *be_value, Expr *expr, unsi
llvm_value_set(be_value, result, expr->type);
}
void llvm_emit_builtin_args_types3(GenContext *c, BEValue *be_value, Expr *expr, unsigned intrinsic, Type *type1, Type *type2, Type *type3)
{
Expr **args = expr->call_expr.arguments;
@@ -710,6 +711,20 @@ void llvm_emit_builtin_call(GenContext *c, BEValue *result_value, Expr *expr)
case BUILTIN_CTLZ:
llvm_emit_int_with_bool_builtin(c, intrinsic_id.ctlz, result_value, expr, false);
return;
case BUILTIN_EXPECT:
llvm_emit_simple_builtin(c, result_value, expr, intrinsic_id.expect);
return;
case BUILTIN_EXPECT_WITH_PROBABILITY:
if (active_target.optimization_level == OPTIMIZATION_NONE)
{
Expr **args = expr->call_expr.arguments;
llvm_emit_expr(c, result_value, args[0]);
BEValue dummy;
llvm_emit_expr(c, &dummy, args[1]);
return;
}
llvm_emit_simple_builtin(c, result_value, expr, intrinsic_id.expect_with_probability);
return;
case BUILTIN_MAX:
llvm_emit_3_variant_builtin(c, result_value, expr, intrinsic_id.smax, intrinsic_id.umax, intrinsic_id.maxnum);
return;

View File

@@ -131,6 +131,8 @@ typedef struct
unsigned cttz;
unsigned exp;
unsigned exp2;
unsigned expect;
unsigned expect_with_probability;
unsigned fabs;
unsigned floor;
unsigned fma;

View File

@@ -15,6 +15,7 @@ typedef enum
BA_INTLIKE,
BA_NUMLIKE,
BA_BOOLINTVEC,
BA_BOOLINT,
BA_INTVEC,
BA_FLOATVEC,
BA_VEC,
@@ -118,6 +119,13 @@ static bool sema_check_builtin_args(Expr **args, BuiltinArg *arg_type, size_t ar
return false;
}
break;
case BA_BOOLINT:
if (!type_is_integer_or_bool_kind(type))
{
SEMA_ERROR(args[i], "Expected a boolean or integer value.");
return false;
}
break;
case BA_BOOLINTVEC:
if (type->type_kind != TYPE_VECTOR || !type_flat_is_boolintlike(type->array.base))
@@ -464,6 +472,35 @@ bool sema_expr_analyse_builtin_call(SemaContext *context, Expr *expr)
if (!sema_check_builtin_args(args, (BuiltinArg[]) { BA_VEC }, arg_count)) return false;
rtype = args[0]->type;
break;
case BUILTIN_EXPECT:
if (!sema_check_builtin_args(args, (BuiltinArg[]) { BA_BOOLINT, BA_BOOLINT }, arg_count)) return false;
if (!sema_check_builtin_args_match(args, arg_count)) return false;
rtype = args[0]->type;
break;
case BUILTIN_EXPECT_WITH_PROBABILITY:
if (!sema_check_builtin_args(args, (BuiltinArg[]) { BA_BOOLINT, BA_BOOLINT }, 2)) return false;
if (!cast_implicit(context, args[2], type_double))
{
SEMA_ERROR(args[2], "Expected a 'double', but was %s.", type_quoted_error_string(args[2]->type));
return false;
}
if (!expr_is_const(args[2]))
{
SEMA_ERROR(args[2], "This value must be a constant.");
return false;
}
else
{
Real r = args[2]->const_expr.fxx.f;
if (r < 0 || r > 1)
{
SEMA_ERROR(args[2], "The probability must be between 0 and 1.");
return false;
}
}
if (!sema_check_builtin_args_match(args, 2)) return false;
rtype = args[0]->type;
break;
case BUILTIN_CEIL:
case BUILTIN_COPYSIGN:
case BUILTIN_COS:
@@ -699,6 +736,7 @@ static inline int builtin_expected_args(BuiltinFunction func)
case BUILTIN_EXACT_MOD:
case BUILTIN_EXACT_MUL:
case BUILTIN_EXACT_SUB:
case BUILTIN_EXPECT:
case BUILTIN_MAX:
case BUILTIN_MIN:
case BUILTIN_POW:
@@ -717,6 +755,7 @@ static inline int builtin_expected_args(BuiltinFunction func)
case BUILTIN_VECCOMPEQ:
case BUILTIN_WASM_MEMORY_GROW:
return 2;
case BUILTIN_EXPECT_WITH_PROBABILITY:
case BUILTIN_FMA:
case BUILTIN_FSHL:
case BUILTIN_FSHR:

View File

@@ -200,6 +200,8 @@ void symtab_init(uint32_t capacity)
builtin_list[BUILTIN_EXACT_SUB] = KW_DEF("sub");
builtin_list[BUILTIN_EXP] = KW_DEF("exp");
builtin_list[BUILTIN_EXP2] = KW_DEF("exp2");
builtin_list[BUILTIN_EXPECT] = KW_DEF("expect");
builtin_list[BUILTIN_EXPECT_WITH_PROBABILITY] = KW_DEF("expect_with_probability");
builtin_list[BUILTIN_FLOOR] = KW_DEF("floor");
builtin_list[BUILTIN_FMA] = KW_DEF("fma");
builtin_list[BUILTIN_FMULADD] = KW_DEF("fmuladd");

View File

@@ -1 +1 @@
#define COMPILER_VERSION "0.4.40"
#define COMPILER_VERSION "0.4.41"