Functions to convert values to/from inline asm.
This commit is contained in:
parent
dc83382903
commit
e4af64f307
76
py/runtime.c
76
py/runtime.c
@ -71,7 +71,7 @@ typedef struct _py_obj_base_t {
|
|||||||
const char *id;
|
const char *id;
|
||||||
qstr u_str;
|
qstr u_str;
|
||||||
#ifdef PY_FLOAT
|
#ifdef PY_FLOAT
|
||||||
float_t flt;
|
float_t u_flt;
|
||||||
#endif
|
#endif
|
||||||
struct { // for O_FUN_[012N]
|
struct { // for O_FUN_[012N]
|
||||||
int n_args;
|
int n_args;
|
||||||
@ -258,7 +258,7 @@ py_obj_t py_obj_new_str(qstr qstr) {
|
|||||||
py_obj_t py_obj_new_float(float_t val) {
|
py_obj_t py_obj_new_float(float_t val) {
|
||||||
py_obj_base_t *o = m_new(py_obj_base_t, 1);
|
py_obj_base_t *o = m_new(py_obj_base_t, 1);
|
||||||
o->kind = O_FLOAT;
|
o->kind = O_FLOAT;
|
||||||
o->flt = val;
|
o->u_flt = val;
|
||||||
return (py_obj_t)o;
|
return (py_obj_t)o;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -298,7 +298,7 @@ typedef struct _py_code_t {
|
|||||||
py_fun_t fun;
|
py_fun_t fun;
|
||||||
} u_native;
|
} u_native;
|
||||||
struct {
|
struct {
|
||||||
py_fun_t fun;
|
void *fun;
|
||||||
} u_inline_asm;
|
} u_inline_asm;
|
||||||
};
|
};
|
||||||
} py_code_t;
|
} py_code_t;
|
||||||
@ -497,7 +497,7 @@ void py_obj_print(py_obj_t o_in) {
|
|||||||
break;
|
break;
|
||||||
#ifdef PY_FLOAT
|
#ifdef PY_FLOAT
|
||||||
case O_FLOAT:
|
case O_FLOAT:
|
||||||
printf("%f", o->flt);
|
printf("%f", o->u_flt);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
case O_LIST:
|
case O_LIST:
|
||||||
@ -745,16 +745,63 @@ py_obj_t rt_make_function(int n_args, py_fun_t code) {
|
|||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// convert a Python object to a sensible value for inline asm
|
||||||
|
machine_uint_t rt_convert_obj_for_inline_asm(py_obj_t obj) {
|
||||||
|
// TODO for byte_array, pass pointer to the array
|
||||||
|
if (IS_SMALL_INT(obj)) {
|
||||||
|
return FROM_SMALL_INT(obj);
|
||||||
|
} else if (obj == py_const_none) {
|
||||||
|
return 0;
|
||||||
|
} else if (obj == py_const_false) {
|
||||||
|
return 0;
|
||||||
|
} else if (obj == py_const_true) {
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
py_obj_base_t *o = obj;
|
||||||
|
switch (o->kind) {
|
||||||
|
case O_STR:
|
||||||
|
// pointer to the string (it's probably constant though!)
|
||||||
|
return (machine_uint_t)qstr_str(o->u_str);
|
||||||
|
|
||||||
|
case O_FLOAT:
|
||||||
|
// convert float to int (could also pass in float registers)
|
||||||
|
return (machine_int_t)o->u_flt;
|
||||||
|
|
||||||
|
case O_LIST:
|
||||||
|
// pointer to start of list (could pass length, but then could use len(x) for that)
|
||||||
|
return (machine_uint_t)o->u_list.items;
|
||||||
|
|
||||||
|
default:
|
||||||
|
// just pass along a pointer to the object
|
||||||
|
return (machine_uint_t)obj;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// convert a return value from inline asm to a sensible Python object
|
||||||
|
py_obj_t rt_convert_val_from_inline_asm(machine_uint_t val) {
|
||||||
|
return TO_SMALL_INT(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef machine_uint_t (*inline_asm_fun_0_t)();
|
||||||
|
typedef machine_uint_t (*inline_asm_fun_1_t)(machine_uint_t);
|
||||||
|
typedef machine_uint_t (*inline_asm_fun_2_t)(machine_uint_t, machine_uint_t);
|
||||||
|
|
||||||
py_obj_t rt_call_function_0(py_obj_t fun) {
|
py_obj_t rt_call_function_0(py_obj_t fun) {
|
||||||
if (IS_O(fun, O_FUN_0)) {
|
if (IS_O(fun, O_FUN_0)) {
|
||||||
py_obj_base_t *o = fun;
|
py_obj_base_t *o = fun;
|
||||||
DEBUG_OP_printf("calling native %p...\n", o->u_fun.fun);
|
DEBUG_OP_printf("calling native %p with no args\n", o->u_fun.fun);
|
||||||
return ((py_fun_0_t)o->u_fun.fun)();
|
return ((py_fun_0_t)o->u_fun.fun)();
|
||||||
} else if (IS_O(fun, O_FUN_BC)) {
|
} else if (IS_O(fun, O_FUN_BC)) {
|
||||||
py_obj_base_t *o = fun;
|
py_obj_base_t *o = fun;
|
||||||
assert(o->u_fun_bc.n_args == 0);
|
assert(o->u_fun_bc.n_args == 0);
|
||||||
DEBUG_OP_printf("calling byte code %p...\n", o->u_fun_bc.code);
|
DEBUG_OP_printf("calling byte code %p with no args\n", o->u_fun_bc.code);
|
||||||
return py_execute_byte_code(o->u_fun_bc.code, o->u_fun_bc.len, NULL, 0);
|
return py_execute_byte_code(o->u_fun_bc.code, o->u_fun_bc.len, NULL, 0);
|
||||||
|
} else if (IS_O(fun, O_FUN_ASM)) {
|
||||||
|
py_obj_base_t *o = fun;
|
||||||
|
assert(o->u_fun_asm.n_args == 0);
|
||||||
|
DEBUG_OP_printf("calling inline asm %p with no args\n", o->u_fun_asm.fun);
|
||||||
|
return rt_convert_val_from_inline_asm(((inline_asm_fun_0_t)o->u_fun_asm.fun)());
|
||||||
} else {
|
} else {
|
||||||
printf("fun0:%p\n", fun);
|
printf("fun0:%p\n", fun);
|
||||||
assert(0);
|
assert(0);
|
||||||
@ -776,13 +823,7 @@ py_obj_t rt_call_function_1(py_obj_t fun, py_obj_t arg) {
|
|||||||
py_obj_base_t *o = fun;
|
py_obj_base_t *o = fun;
|
||||||
assert(o->u_fun_asm.n_args == 1);
|
assert(o->u_fun_asm.n_args == 1);
|
||||||
DEBUG_OP_printf("calling inline asm %p with 1 arg\n", o->u_fun_asm.fun);
|
DEBUG_OP_printf("calling inline asm %p with 1 arg\n", o->u_fun_asm.fun);
|
||||||
machine_int_t arg_val;
|
return rt_convert_val_from_inline_asm(((inline_asm_fun_1_t)o->u_fun_asm.fun)(rt_convert_obj_for_inline_asm(arg)));
|
||||||
if (IS_SMALL_INT(arg)) {
|
|
||||||
arg_val = FROM_SMALL_INT(arg);
|
|
||||||
} else {
|
|
||||||
arg_val = arg;
|
|
||||||
}
|
|
||||||
return ((py_fun_1_t)o->u_fun_asm.fun)(arg_val);
|
|
||||||
} else if (IS_O(fun, O_BOUND_METH)) {
|
} else if (IS_O(fun, O_BOUND_METH)) {
|
||||||
py_obj_base_t *o = fun;
|
py_obj_base_t *o = fun;
|
||||||
return rt_call_function_2(o->u_bound_meth.meth, o->u_bound_meth.self, arg);
|
return rt_call_function_2(o->u_bound_meth.meth, o->u_bound_meth.self, arg);
|
||||||
@ -796,16 +837,21 @@ py_obj_t rt_call_function_1(py_obj_t fun, py_obj_t arg) {
|
|||||||
py_obj_t rt_call_function_2(py_obj_t fun, py_obj_t arg1, py_obj_t arg2) {
|
py_obj_t rt_call_function_2(py_obj_t fun, py_obj_t arg1, py_obj_t arg2) {
|
||||||
if (IS_O(fun, O_FUN_2)) {
|
if (IS_O(fun, O_FUN_2)) {
|
||||||
py_obj_base_t *o = fun;
|
py_obj_base_t *o = fun;
|
||||||
DEBUG_OP_printf("calling native %p...\n", o->u_fun.fun);
|
DEBUG_OP_printf("calling native %p with 2 args\n", o->u_fun.fun);
|
||||||
return ((py_fun_2_t)o->u_fun.fun)(arg1, arg2);
|
return ((py_fun_2_t)o->u_fun.fun)(arg1, arg2);
|
||||||
} else if (IS_O(fun, O_FUN_BC)) {
|
} else if (IS_O(fun, O_FUN_BC)) {
|
||||||
py_obj_base_t *o = fun;
|
py_obj_base_t *o = fun;
|
||||||
assert(o->u_fun_bc.n_args == 2);
|
assert(o->u_fun_bc.n_args == 2);
|
||||||
DEBUG_OP_printf("calling byte code %p...\n", o->u_fun_bc.code);
|
DEBUG_OP_printf("calling byte code %p with 2 args\n", o->u_fun_bc.code);
|
||||||
py_obj_t args[2];
|
py_obj_t args[2];
|
||||||
args[0] = arg1;
|
args[0] = arg1;
|
||||||
args[1] = arg2;
|
args[1] = arg2;
|
||||||
return py_execute_byte_code(o->u_fun_bc.code, o->u_fun_bc.len, &args[0], 2);
|
return py_execute_byte_code(o->u_fun_bc.code, o->u_fun_bc.len, &args[0], 2);
|
||||||
|
} else if (IS_O(fun, O_FUN_ASM)) {
|
||||||
|
py_obj_base_t *o = fun;
|
||||||
|
assert(o->u_fun_asm.n_args == 2);
|
||||||
|
DEBUG_OP_printf("calling inline asm %p with 2 args\n", o->u_fun_asm.fun);
|
||||||
|
return rt_convert_val_from_inline_asm(((inline_asm_fun_2_t)o->u_fun_asm.fun)(rt_convert_obj_for_inline_asm(arg1), rt_convert_obj_for_inline_asm(arg2)));
|
||||||
} else {
|
} else {
|
||||||
assert(0);
|
assert(0);
|
||||||
return py_const_none;
|
return py_const_none;
|
||||||
|
Loading…
Reference in New Issue
Block a user