1
0
mirror of https://github.com/janet-lang/janet synced 2025-01-12 16:40:27 +00:00

Port some cfunctions in math.c to corelib as

assembled functions.
This commit is contained in:
Calvin Rose 2018-07-08 23:10:02 -04:00
parent 423ebc937a
commit b860b0a3c5
5 changed files with 126 additions and 122 deletions

View File

@ -150,6 +150,9 @@ static DstSlot do_rshift(DstFopts opts, DstSlot *args) {
static DstSlot do_rshiftu(DstFopts opts, DstSlot *args) {
return opreduce(opts, args, DOP_SHIFT_RIGHT, dst_wrap_integer(1));
}
static DstSlot do_bnot(DstFopts opts, DstSlot *args) {
return genericSS(opts, DOP_BNOT, args[0]);
}
/* Arranged by tag */
static const DstFunOptimizer optimizers[] = {
@ -170,7 +173,8 @@ static const DstFunOptimizer optimizers[] = {
{NULL, do_bxor},
{NULL, do_lshift},
{NULL, do_rshift},
{NULL, do_rshiftu}
{NULL, do_rshiftu},
{fixarity1, do_bnot}
};
const DstFunOptimizer *dstc_funopt(uint32_t flags) {

View File

@ -45,6 +45,7 @@
#define DST_FUN_LSHIFT 16
#define DST_FUN_RSHIFT 17
#define DST_FUN_RSHIFTU 18
#define DST_FUN_BNOT 19
/* Compiler typedefs */
typedef struct DstCompiler DstCompiler;

View File

@ -344,57 +344,11 @@ static void dst_quick_asm(
}
/* Macros for easier inline dst assembly */
#define SSS(op, a, b, c) (op | (a << 8) | (b << 16) | (c << 24))
#define SS(op, a, b) (op | (a << 8) | (b << 16))
#define SSI(op, a, b, I) (op | (a << 8) | (b << 16) | ((uint32_t)(I) << 24))
#define S(op, a) (op | (a << 8))
#define SI(op, a, I) (op | (a << 8) | ((uint32_t)(I) << 16))
/* Variadic operator assembly. Must be templatized for each different opcode. */
/* Reg 0: Argument tuple (args) */
/* Reg 1: Argument count (argn) */
/* Reg 2: Jump flag (jump?) */
/* Reg 3: Accumulator (accum) */
/* Reg 4: Next operand (operand) */
/* Reg 5: Loop iterator (i) */
static DST_THREAD_LOCAL uint32_t varop_asm[] = {
SS(DOP_LENGTH, 1, 0), /* Put number of arguments in register 1 -> argn = count(args) */
/* Check nullary */
SSS(DOP_EQUALS_IMMEDIATE, 2, 1, 0), /* Check if numargs equal to 0 */
SI(DOP_JUMP_IF_NOT, 2, 3), /* If not 0, jump to next check */
/* Nullary */
SI(DOP_LOAD_INTEGER, 3, 0), /* accum = nullary value */
S(DOP_RETURN, 3), /* return accum */
/* Check unary */
SSI(DOP_EQUALS_IMMEDIATE, 2, 1, 1), /* Check if numargs equal to 1 */
SI(DOP_JUMP_IF_NOT, 2, 5), /* If not 1, jump to next check */
/* Unary */
S(DOP_LOAD_INTEGER, 3), /* accum = unary value */
SSI(DOP_GET_INDEX, 4, 0, 0), /* operand = args[0] */
SSS(DOP_NOOP, 3, 3, 4), /* accum = accum op operand */
S(DOP_RETURN, 3), /* return accum */
/* Mutli (2 or more) arity */
/* Prime loop */
SSI(DOP_GET_INDEX, 3, 0, 0), /* accum = args[0] */
SI(DOP_LOAD_INTEGER, 5, 1), /* i = 1 */
/* Main loop */
SSS(DOP_GET, 4, 0, 5), /* operand = args[i] */
SSS(DOP_NOOP, 3, 3, 4), /* accum = accum op operand */
SSI(DOP_ADD_IMMEDIATE, 5, 5, 1), /* i++ */
SSI(DOP_EQUALS_INTEGER, 2, 5, 1), /* jump? = (i == argn) */
SI(DOP_JUMP_IF_NOT, 2, -4), /* if not jump? go back 4 */
/* Done, do last and return accumulator */
S(DOP_RETURN, 3) /* return accum */
};
#define VAROP_NULLARY_LOC 3
#define VAROP_UNARY_LOC 7
#define VAROP_OP_LOC1 9
#define VAROP_OP_LOC2 14
#define SSS(op, a, b, c) ((op) | ((a) << 8) | ((b) << 16) | ((c) << 24))
#define SS(op, a, b) ((op) | ((a) << 8) | ((b) << 16))
#define SSI(op, a, b, I) ((op) | ((a) << 8) | ((b) << 16) | ((uint32_t)(I) << 24))
#define S(op, a) ((op) | ((a) << 8))
#define SI(op, a, I) ((op) | ((a) << 8) | ((uint32_t)(I) << 16))
/* Templatize a varop */
static void templatize_varop(
@ -404,10 +358,48 @@ static void templatize_varop(
int32_t nullary,
int32_t unary,
uint32_t op) {
varop_asm[VAROP_NULLARY_LOC] = SS(DOP_LOAD_INTEGER, 3, nullary);
varop_asm[VAROP_UNARY_LOC] = SS(DOP_LOAD_INTEGER, 3, unary);
varop_asm[VAROP_OP_LOC1] = SSS(op, 3, 3, 4);
varop_asm[VAROP_OP_LOC2] = SSS(op, 3, 3, 4);
/* Variadic operator assembly. Must be templatized for each different opcode. */
/* Reg 0: Argument tuple (args) */
/* Reg 1: Argument count (argn) */
/* Reg 2: Jump flag (jump?) */
/* Reg 3: Accumulator (accum) */
/* Reg 4: Next operand (operand) */
/* Reg 5: Loop iterator (i) */
uint32_t varop_asm[] = {
SS(DOP_LENGTH, 1, 0), /* Put number of arguments in register 1 -> argn = count(args) */
/* Check nullary */
SSS(DOP_EQUALS_IMMEDIATE, 2, 1, 0), /* Check if numargs equal to 0 */
SI(DOP_JUMP_IF_NOT, 2, 3), /* If not 0, jump to next check */
/* Nullary */
SI(DOP_LOAD_INTEGER, 3, nullary), /* accum = nullary value */
S(DOP_RETURN, 3), /* return accum */
/* Check unary */
SSI(DOP_EQUALS_IMMEDIATE, 2, 1, 1), /* Check if numargs equal to 1 */
SI(DOP_JUMP_IF_NOT, 2, 5), /* If not 1, jump to next check */
/* Unary */
SI(DOP_LOAD_INTEGER, 3, unary), /* accum = unary value */
SSI(DOP_GET_INDEX, 4, 0, 0), /* operand = args[0] */
SSS(op, 3, 3, 4), /* accum = accum op operand */
S(DOP_RETURN, 3), /* return accum */
/* Mutli (2 or more) arity */
/* Prime loop */
SSI(DOP_GET_INDEX, 3, 0, 0), /* accum = args[0] */
SI(DOP_LOAD_INTEGER, 5, 1), /* i = 1 */
/* Main loop */
SSS(DOP_GET, 4, 0, 5), /* operand = args[i] */
SSS(op, 3, 3, 4), /* accum = accum op operand */
SSI(DOP_ADD_IMMEDIATE, 5, 5, 1), /* i++ */
SSI(DOP_EQUALS_INTEGER, 2, 5, 1), /* jump? = (i == argn) */
SI(DOP_JUMP_IF_NOT, 2, -4), /* if not jump? go back 4 */
/* Done, do last and return accumulator */
S(DOP_RETURN, 3) /* return accum */
};
dst_quick_asm(
env,
flags | DST_FUNCDEF_FLAG_VARARG,
@ -418,38 +410,93 @@ static void templatize_varop(
sizeof(varop_asm));
}
/* Templatize variadic comparators */
static void templatize_comparator(
DstTable *env,
int32_t flags,
const char *name,
int invert,
uint32_t op) {
/* Reg 0: Argument tuple (args) */
/* Reg 1: Argument count (argn) */
/* Reg 2: Jump flag (jump?) */
/* Reg 3: Last value (last) */
/* Reg 4: Next operand (next) */
/* Reg 5: Loop iterator (i) */
uint32_t comparator_asm[] = {
SS(DOP_LENGTH, 1, 0), /* Put number of arguments in register 1 -> argn = count(args) */
SSS(DOP_LESS_THAN_IMMEDIATE, 2, 1, 2), /* Check if numargs less than 2 */
SI(DOP_JUMP_IF, 2, 10), /* If numargs < 2, jump to done */
/* Prime loop */
SSI(DOP_GET_INDEX, 3, 0, 0), /* last = args[0] */
SI(DOP_LOAD_INTEGER, 5, 1), /* i = 1 */
/* Main loop */
SSS(DOP_GET, 4, 0, 5), /* next = args[i] */
SSS(op, 2, 3, 4), /* jump? = last compare next */
SI(DOP_JUMP_IF_NOT, 2, 7), /* if not jump? goto fail (return false) */
SSI(DOP_ADD_IMMEDIATE, 5, 5, 1), /* i++ */
SS(DOP_MOVE_NEAR, 3, 4), /* last = next */
SSI(DOP_EQUALS_INTEGER, 2, 5, 1), /* jump? = (i == argn) */
SI(DOP_JUMP_IF_NOT, 2, -6), /* if not jump? go back 6 */
/* Done, return true */
S(invert ? DOP_LOAD_FALSE : DOP_LOAD_TRUE, 3),
S(DOP_RETURN, 3),
/* Failed, return false */
S(invert ? DOP_LOAD_TRUE : DOP_LOAD_FALSE, 3),
S(DOP_RETURN, 3)
};
dst_quick_asm(
env,
flags | DST_FUNCDEF_FLAG_VARARG,
name,
0,
6,
comparator_asm,
sizeof(comparator_asm));
}
DstTable *dst_core_env(void) {
static uint32_t error_asm[] = {
static const uint32_t error_asm[] = {
DOP_ERROR
};
static uint32_t apply_asm[] = {
static const uint32_t apply_asm[] = {
DOP_PUSH_ARRAY | (1 << 8),
DOP_TAILCALL
};
static uint32_t debug_asm[] = {
static const uint32_t debug_asm[] = {
DOP_SIGNAL | (2 << 24),
DOP_RETURN_NIL
};
static uint32_t yield_asm[] = {
static const uint32_t yield_asm[] = {
DOP_SIGNAL | (3 << 24),
DOP_RETURN
};
static uint32_t resume_asm[] = {
static const uint32_t resume_asm[] = {
DOP_RESUME | (1 << 24),
DOP_RETURN
};
static uint32_t get_asm[] = {
static const uint32_t get_asm[] = {
DOP_GET | (1 << 24),
DOP_RETURN
};
static uint32_t put_asm[] = {
static const uint32_t put_asm[] = {
DOP_PUT | (1 << 16) | (2 << 24),
DOP_RETURN
};
static uint32_t length_asm[] = {
static const uint32_t length_asm[] = {
DOP_LENGTH,
DOP_RETURN
};
static const uint32_t bnot_asm[] = {
DOP_BNOT,
DOP_RETURN
};
DstTable *env = dst_table(0);
Dst ret = dst_wrap_table(env);
@ -465,6 +512,7 @@ DstTable *dst_core_env(void) {
dst_quick_asm(env, DST_FUN_GET, "get", 2, 2, get_asm, sizeof(get_asm));
dst_quick_asm(env, DST_FUN_PUT, "put", 3, 3, put_asm, sizeof(put_asm));
dst_quick_asm(env, DST_FUN_LENGTH, "length", 1, 1, length_asm, sizeof(length_asm));
dst_quick_asm(env, DST_FUN_BNOT, "~", 1, 1, bnot_asm, sizeof(bnot_asm));
/* Variadic ops */
templatize_varop(env, DST_FUN_ADD, "+", 0, 0, DOP_ADD);
@ -478,6 +526,14 @@ DstTable *dst_core_env(void) {
templatize_varop(env, DST_FUN_RSHIFT, ">>", 1, 1, DOP_SHIFT_RIGHT);
templatize_varop(env, DST_FUN_RSHIFTU, ">>>", 1, 1, DOP_SHIFT_RIGHT_UNSIGNED);
/* Variadic comparators */
templatize_comparator(env, 0, "order>", 0, DOP_GREATER_THAN);
templatize_comparator(env, 0, "order<", 0, DOP_LESS_THAN);
templatize_comparator(env, 0, "order>=", 1, DOP_LESS_THAN);
templatize_comparator(env, 0, "order<=", 1, DOP_GREATER_THAN);
templatize_comparator(env, 0, "=", 0, DOP_EQUALS);
templatize_comparator(env, 0, "not=", 1, DOP_EQUALS);
dst_env_def(env, "VERSION", dst_cstringv(DST_VERSION));
/* Set as gc root */

View File

@ -71,19 +71,6 @@ int dst_real(DstArgs args) {
return 0;
}
int dst_bnot(DstArgs args) {
if (args.n != 1) {
*args.ret = dst_cstringv("expected 1 argument");
return 1;
}
if (!dst_checktype(args.v[0], DST_INTEGER)) {
*args.ret = dst_cstringv("expected integer");
return 1;
}
*args.ret = dst_wrap_integer(~dst_unwrap_integer(args.v[0]));
return 0;
}
int dst_remainder(DstArgs args) {
DST_FIXARITY(args, 2);
if (dst_checktype(args.v[0], DST_INTEGER) &&
@ -137,44 +124,6 @@ int dst_##name(DstArgs args) {\
DST_DEFINE_MATH2OP(atan2, atan2)
DST_DEFINE_MATH2OP(pow, pow)
/* Comparison */
#define DST_DEFINE_COMPARATOR(name, pred)\
static int dst_##name(DstArgs args) {\
int32_t i;\
for (i = 0; i < args.n - 1; i++) {\
if (dst_compare(args.v[i], args.v[i+1]) pred) {\
DST_RETURN_FALSE(args);\
}\
}\
DST_RETURN_TRUE(args);\
}
DST_DEFINE_COMPARATOR(ascending, >= 0)
DST_DEFINE_COMPARATOR(descending, <= 0)
DST_DEFINE_COMPARATOR(notdescending, > 0)
DST_DEFINE_COMPARATOR(notascending, < 0)
/* Boolean logic */
static int dst_strict_equal(DstArgs args) {
int32_t i;
for (i = 0; i < args.n - 1; i++) {
if (!dst_equals(args.v[i], args.v[i+1])) {
DST_RETURN_FALSE(args);
}
}
DST_RETURN_TRUE(args);
}
static int dst_strict_notequal(DstArgs args) {
int32_t i;
for (i = 0; i < args.n - 1; i++) {
if (!dst_equals(args.v[i], args.v[i+1])) {
DST_RETURN_TRUE(args);
}
}
DST_RETURN_FALSE(args);
}
static int dst_not(DstArgs args) {
DST_FIXARITY(args, 1);
DST_RETURN_BOOLEAN(args, !dst_truthy(args.v[0]));
@ -203,19 +152,12 @@ DEF_NUMERIC_COMP(neq, !=)
static const DstReg cfuns[] = {
{"%", dst_remainder},
{"=", dst_strict_equal},
{"not=", dst_strict_notequal},
{"order<", dst_ascending},
{"order>", dst_descending},
{"order<=", dst_notdescending},
{"order>=", dst_notascending},
{"==", dst_numeric_eq},
{"not==", dst_numeric_neq},
{"<", dst_numeric_lt},
{">", dst_numeric_gt},
{"<=", dst_numeric_lte},
{">=", dst_numeric_gte},
{"~", dst_bnot},
{"not", dst_not},
{"int", dst_int},
{"real", dst_real},

View File

@ -385,6 +385,7 @@ static void *op_lookup[255] = {
VM_OP(DOP_BNOT)
stack[oparg(1, 0xFF)] = dst_wrap_integer(~dst_unwrap_integer(stack[oparg(2, 0xFFFF)]));
++pc;
vm_next();
VM_OP(DOP_SHIFT_RIGHT_UNSIGNED)