py: Add 'align' and 'data' meta-instructions to inline assembler.

This commit is contained in:
Damien George 2014-04-21 13:33:15 +01:00
parent 764af4b7c5
commit e5f8a77db6
6 changed files with 59 additions and 1 deletions

View File

@ -209,6 +209,20 @@ void asm_thumb_label_assign(asm_thumb_t *as, uint label) {
}
}
void asm_thumb_align(asm_thumb_t* as, uint align) {
// TODO fill unused data with NOPs?
as->code_offset = (as->code_offset + align - 1) & (~(align - 1));
}
void asm_thumb_data(asm_thumb_t* as, uint bytesize, uint val) {
byte *c = asm_thumb_get_cur_to_write_bytes(as, bytesize);
// little endian
for (uint i = 0; i < bytesize; i++) {
*c++ = val;
val >>= 8;
}
}
STATIC int get_label_dest(asm_thumb_t *as, uint label) {
assert(label < as->max_num_labels);
return as->label_offsets[label];

View File

@ -55,6 +55,9 @@ void asm_thumb_exit(asm_thumb_t *as);
void asm_thumb_label_assign(asm_thumb_t *as, uint label);
void asm_thumb_align(asm_thumb_t* as, uint align);
void asm_thumb_data(asm_thumb_t* as, uint bytesize, uint val);
// argument order follows ARM, in general dest is first
// note there is a difference between movw and mov.w, and many others!

View File

@ -3184,7 +3184,7 @@ void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind_t pass
int n_args = list_get(&pns2->nodes[0], PN_arglist, &pn_arg);
// emit instructions
if (strcmp(qstr_str(op), "label") == 0) {
if (op == MP_QSTR_label) {
if (!(n_args == 1 && MP_PARSE_NODE_IS_ID(pn_arg[0]))) {
compile_syntax_error(comp, nodes[i], "inline assembler 'label' requires 1 argument");
return;
@ -3193,6 +3193,29 @@ void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind_t pass
if (pass > PASS_1) {
EMIT_INLINE_ASM_ARG(label, lab, MP_PARSE_NODE_LEAF_ARG(pn_arg[0]));
}
} else if (op == MP_QSTR_align) {
if (!(n_args == 1 && MP_PARSE_NODE_IS_SMALL_INT(pn_arg[0]))) {
compile_syntax_error(comp, nodes[i], "inline assembler 'align' requires 1 argument");
return;
}
if (pass > PASS_1) {
EMIT_INLINE_ASM_ARG(align, MP_PARSE_NODE_LEAF_SMALL_INT(pn_arg[0]));
}
} else if (op == MP_QSTR_data) {
if (!(n_args >= 2 && MP_PARSE_NODE_IS_SMALL_INT(pn_arg[0]))) {
compile_syntax_error(comp, nodes[i], "inline assembler 'data' requires at least 2 arguments");
return;
}
if (pass > PASS_1) {
machine_int_t bytesize = MP_PARSE_NODE_LEAF_SMALL_INT(pn_arg[0]);
for (uint i = 1; i < n_args; i++) {
if (!MP_PARSE_NODE_IS_SMALL_INT(pn_arg[i])) {
compile_syntax_error(comp, nodes[i], "inline assembler 'data' requires integer arguments");
return;
}
EMIT_INLINE_ASM_ARG(data, bytesize, MP_PARSE_NODE_LEAF_SMALL_INT(pn_arg[i]));
}
}
} else {
if (pass > PASS_1) {
EMIT_INLINE_ASM_ARG(op, op, n_args, pn_arg);

View File

@ -143,6 +143,8 @@ typedef struct _emit_inline_asm_method_table_t {
bool (*end_pass)(emit_inline_asm_t *emit);
int (*count_params)(emit_inline_asm_t *emit, int n_params, mp_parse_node_t *pn_params);
void (*label)(emit_inline_asm_t *emit, uint label_num, qstr label_id);
void (*align)(emit_inline_asm_t *emit, uint align);
void (*data)(emit_inline_asm_t *emit, uint bytesize, uint val);
void (*op)(emit_inline_asm_t *emit, qstr op, int n_args, mp_parse_node_t *pn_args);
} emit_inline_asm_method_table_t;

View File

@ -104,6 +104,14 @@ STATIC void emit_inline_thumb_label(emit_inline_asm_t *emit, uint label_num, qst
asm_thumb_label_assign(emit->as, label_num);
}
STATIC void emit_inline_thumb_align(emit_inline_asm_t *emit, uint align) {
asm_thumb_align(emit->as, align);
}
STATIC void emit_inline_thumb_data(emit_inline_asm_t *emit, uint bytesize, uint val) {
asm_thumb_data(emit->as, bytesize, val);
}
typedef struct _reg_name_t { byte reg; byte name[3]; } reg_name_t;
STATIC const reg_name_t reg_name_table[] = {
{0, "r0\0"},
@ -418,6 +426,8 @@ const emit_inline_asm_method_table_t emit_inline_thumb_method_table = {
emit_inline_thumb_end_pass,
emit_inline_thumb_count_params,
emit_inline_thumb_label,
emit_inline_thumb_align,
emit_inline_thumb_data,
emit_inline_thumb_op,
};

View File

@ -36,7 +36,13 @@ Q(micropython)
Q(byte_code)
Q(native)
Q(viper)
#if MICROPY_EMIT_INLINE_THUMB
Q(asm_thumb)
Q(label)
Q(align)
Q(data)
#endif
Q(Ellipsis)
Q(StopIteration)