Skip to content

Commit 1f2558d

Browse files
committed
Merge pull request micropython#889 from Vogtinator/master
Implement missing ARM emitter functions for viper
2 parents 00be7a8 + e526896 commit 1f2558d

File tree

3 files changed

+93
-15
lines changed

3 files changed

+93
-15
lines changed

py/asmarm.c

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -297,10 +297,9 @@ void asm_arm_cmp_reg_reg(asm_arm_t *as, uint rd, uint rn) {
297297
emit_al(as, 0x1500000 | (rd << 16) | rn);
298298
}
299299

300-
void asm_arm_less_op(asm_arm_t *as, uint rd, uint rn, uint rm) {
301-
asm_arm_cmp_reg_reg(as, rn, rm); // cmp rn, rm
302-
emit(as, asm_arm_op_mov_imm(rd, 1) | ASM_ARM_CC_LT); // movlt rd, #1
303-
emit(as, asm_arm_op_mov_imm(rd, 0) | ASM_ARM_CC_GE); // movge rd, #0
300+
void asm_arm_setcc_reg(asm_arm_t *as, uint rd, uint cond) {
301+
emit(as, asm_arm_op_mov_imm(rd, 1) | cond); // movCOND rd, #1
302+
emit(as, asm_arm_op_mov_imm(rd, 0) | (cond ^ (1 << 28))); // mov!COND rd, #0
304303
}
305304

306305
void asm_arm_add_reg_reg_reg(asm_arm_t *as, uint rd, uint rn, uint rm) {
@@ -318,6 +317,47 @@ void asm_arm_mov_reg_local_addr(asm_arm_t *as, uint rd, int local_num) {
318317
emit_al(as, asm_arm_op_add_imm(rd, ASM_ARM_REG_SP, local_num << 2));
319318
}
320319

320+
void asm_arm_lsl_reg_reg(asm_arm_t *as, uint rd, uint rs) {
321+
// mov rd, rd, lsl rs
322+
emit_al(as, 0x1a00010 | (rd << 12) | (rs << 8) | rd);
323+
}
324+
325+
void asm_arm_asr_reg_reg(asm_arm_t *as, uint rd, uint rs) {
326+
// mov rd, rd, asr rs
327+
emit_al(as, 0x1a00050 | (rd << 12) | (rs << 8) | rd);
328+
}
329+
330+
void asm_arm_str_reg_reg(asm_arm_t *as, uint rd, uint rm) {
331+
// str rd, [rm]
332+
emit_al(as, 0x5800000 | (rm << 16) | (rd << 12));
333+
}
334+
335+
void asm_arm_strh_reg_reg(asm_arm_t *as, uint rd, uint rm) {
336+
// strh rd, [rm]
337+
emit_al(as, 0x1c000b0 | (rm << 16) | (rd << 12));
338+
}
339+
340+
void asm_arm_strb_reg_reg(asm_arm_t *as, uint rd, uint rm) {
341+
// strb rd, [rm]
342+
emit_al(as, 0x5c00000 | (rm << 16) | (rd << 12));
343+
}
344+
345+
void asm_arm_str_reg_reg_reg(asm_arm_t *as, uint rd, uint rm, uint rn) {
346+
// str rd, [rm, rn, lsl #2]
347+
emit_al(as, 0x7800100 | (rm << 16) | (rd << 12) | rn);
348+
}
349+
350+
void asm_arm_strh_reg_reg_reg(asm_arm_t *as, uint rd, uint rm, uint rn) {
351+
// strh doesn't support scaled register index
352+
emit_al(as, 0x1a00080 | (ASM_ARM_REG_R8 << 12) | rn); // mov r8, rn, lsl #1
353+
emit_al(as, 0x18000b0 | (rm << 16) | (rd << 12) | ASM_ARM_REG_R8); // strh rd, [rm, r8]
354+
}
355+
356+
void asm_arm_strb_reg_reg_reg(asm_arm_t *as, uint rd, uint rm, uint rn) {
357+
// strb rd, [rm, rn]
358+
emit_al(as, 0x7c00000 | (rm << 16) | (rd << 12) | rn);
359+
}
360+
321361
void asm_arm_bcc_label(asm_arm_t *as, int cond, uint label) {
322362
assert(label < as->max_num_labels);
323363
mp_uint_t dest = as->label_offsets[label];

py/asmarm.h

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,18 +81,35 @@ void asm_arm_align(asm_arm_t* as, uint align);
8181
void asm_arm_data(asm_arm_t* as, uint bytesize, uint val);
8282

8383
void asm_arm_bkpt(asm_arm_t *as);
84+
85+
// mov
8486
void asm_arm_mov_reg_reg(asm_arm_t *as, uint reg_dest, uint reg_src);
8587
void asm_arm_mov_reg_i32(asm_arm_t *as, uint rd, int imm);
8688
void asm_arm_mov_local_reg(asm_arm_t *as, int local_num, uint rd);
8789
void asm_arm_mov_reg_local(asm_arm_t *as, uint rd, int local_num);
90+
void asm_arm_setcc_reg(asm_arm_t *as, uint rd, uint cond);
8891

92+
// compare
8993
void asm_arm_cmp_reg_i8(asm_arm_t *as, uint rd, int imm);
9094
void asm_arm_cmp_reg_reg(asm_arm_t *as, uint rd, uint rn);
91-
void asm_arm_less_op(asm_arm_t *as, uint rd, uint rn, uint rm);
95+
96+
// arithmetic
9297
void asm_arm_add_reg_reg_reg(asm_arm_t *as, uint rd, uint rn, uint rm);
9398
void asm_arm_sub_reg_reg_reg(asm_arm_t *as, uint rd, uint rn, uint rm);
9499
void asm_arm_mov_reg_local_addr(asm_arm_t *as, uint rd, int local_num);
100+
void asm_arm_lsl_reg_reg(asm_arm_t *as, uint rd, uint rs);
101+
void asm_arm_asr_reg_reg(asm_arm_t *as, uint rd, uint rs);
102+
103+
// memory
104+
void asm_arm_str_reg_reg(asm_arm_t *as, uint rd, uint rm);
105+
void asm_arm_strh_reg_reg(asm_arm_t *as, uint rd, uint rm);
106+
void asm_arm_strb_reg_reg(asm_arm_t *as, uint rd, uint rm);
107+
// store to array
108+
void asm_arm_str_reg_reg_reg(asm_arm_t *as, uint rd, uint rm, uint rn);
109+
void asm_arm_strh_reg_reg_reg(asm_arm_t *as, uint rd, uint rm, uint rn);
110+
void asm_arm_strb_reg_reg_reg(asm_arm_t *as, uint rd, uint rm, uint rn);
95111

112+
// control flow
96113
void asm_arm_bcc_label(asm_arm_t *as, int cond, uint label);
97114
void asm_arm_b_label(asm_arm_t *as, uint label);
98115
void asm_arm_bl_ind(asm_arm_t *as, void *fun_ptr, uint fun_id, uint reg_temp);

py/emitnative.c

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -420,16 +420,14 @@ STATIC byte mp_f_n_args[MP_F_NUMBER_OF] = {
420420
#define ASM_MOV_REG_REG(as, reg_dest, reg_src) asm_arm_mov_reg_reg((as), (reg_dest), (reg_src))
421421
#define ASM_MOV_LOCAL_ADDR_TO_REG(as, local_num, reg) asm_arm_mov_reg_local_addr(as, (reg), (local_num))
422422

423-
// TODO someone please implement lsl and asr
424-
#define ASM_LSL_REG_REG(as, reg_dest, reg_shift) asm_arm_lsl_((as), (reg_dest), (reg_shift))
425-
#define ASM_ASR_REG_REG(as, reg_dest, reg_shift) asm_arm_asr_((as), (reg_dest), (reg_shift))
423+
#define ASM_LSL_REG_REG(as, reg_dest, reg_shift) asm_arm_lsl_reg_reg((as), (reg_dest), (reg_shift))
424+
#define ASM_ASR_REG_REG(as, reg_dest, reg_shift) asm_arm_asr_reg_reg((as), (reg_dest), (reg_shift))
426425
#define ASM_ADD_REG_REG(as, reg_dest, reg_src) asm_arm_add_reg_reg_reg((as), (reg_dest), (reg_dest), (reg_src))
427426
#define ASM_SUB_REG_REG(as, reg_dest, reg_src) asm_arm_sub_reg_reg_reg((as), (reg_dest), (reg_dest), (reg_src))
428427

429-
// TODO someone please implement str
430-
#define ASM_STORE_REG_REG(as, reg_src, reg_base) asm_arm_str_reg_reg_i5((as), (reg_src), (reg_base), 0)
431-
#define ASM_STORE8_REG_REG(as, reg_src, reg_base) asm_arm_strb_reg_reg_i5((as), (reg_src), (reg_base), 0)
432-
#define ASM_STORE16_REG_REG(as, reg_src, reg_base) asm_arm_strh_reg_reg_i5((as), (reg_src), (reg_base), 0)
428+
#define ASM_STORE_REG_REG(as, reg_value, reg_base) asm_arm_str_reg_reg((as), (reg_value), (reg_base))
429+
#define ASM_STORE8_REG_REG(as, reg_value, reg_base) asm_arm_strb_reg_reg((as), (reg_value), (reg_base))
430+
#define ASM_STORE16_REG_REG(as, reg_value, reg_base) asm_arm_strh_reg_reg((as), (reg_value), (reg_base))
433431

434432
#else
435433

@@ -1424,6 +1422,10 @@ STATIC void emit_native_store_subscr(emit_t *emit) {
14241422
}
14251423
#endif
14261424
ASM_MOV_IMM_TO_REG(emit->as, index_value, reg_index);
1425+
#if N_ARM
1426+
asm_arm_strb_reg_reg_reg(emit->as, reg_value, reg_base, reg_index);
1427+
return;
1428+
#endif
14271429
ASM_ADD_REG_REG(emit->as, reg_index, reg_base); // add index to base
14281430
reg_base = reg_index;
14291431
}
@@ -1441,6 +1443,10 @@ STATIC void emit_native_store_subscr(emit_t *emit) {
14411443
}
14421444
#endif
14431445
ASM_MOV_IMM_TO_REG(emit->as, index_value << 1, reg_index);
1446+
#if N_ARM
1447+
asm_arm_strh_reg_reg_reg(emit->as, reg_value, reg_base, reg_index);
1448+
return;
1449+
#endif
14441450
ASM_ADD_REG_REG(emit->as, reg_index, reg_base); // add 2*index to base
14451451
reg_base = reg_index;
14461452
}
@@ -1468,13 +1474,21 @@ STATIC void emit_native_store_subscr(emit_t *emit) {
14681474
// pointer to 8-bit memory
14691475
// TODO optimise to use thumb strb r1, [r2, r3]
14701476
assert(vtype_index == VTYPE_INT);
1477+
#if N_ARM
1478+
asm_arm_strb_reg_reg_reg(emit->as, reg_value, REG_ARG_1, reg_index);
1479+
break;
1480+
#endif
14711481
ASM_ADD_REG_REG(emit->as, REG_ARG_1, reg_index); // add index to base
14721482
ASM_STORE8_REG_REG(emit->as, reg_value, REG_ARG_1); // store value to (base+index)
14731483
break;
14741484
}
14751485
case VTYPE_PTR16: {
14761486
// pointer to 16-bit memory
14771487
assert(vtype_index == VTYPE_INT);
1488+
#if N_ARM
1489+
asm_arm_strh_reg_reg_reg(emit->as, reg_value, REG_ARG_1, reg_index);
1490+
break;
1491+
#endif
14781492
ASM_ADD_REG_REG(emit->as, REG_ARG_1, reg_index); // add index to base
14791493
ASM_ADD_REG_REG(emit->as, REG_ARG_1, reg_index); // add index to base
14801494
ASM_STORE16_REG_REG(emit->as, reg_value, REG_ARG_1); // store value to (base+2*index)
@@ -1808,9 +1822,16 @@ STATIC void emit_native_binary_op(emit_t *emit, mp_binary_op_t op) {
18081822
asm_thumb_mov_rlo_i8(emit->as, REG_RET, ret[op - MP_BINARY_OP_LESS]);
18091823
asm_thumb_mov_rlo_i8(emit->as, REG_RET, ret[op - MP_BINARY_OP_LESS] ^ 1);
18101824
#elif N_ARM
1811-
#error generic comparisons for ARM needs implementing
1812-
//asm_arm_less_op(emit->as, REG_RET, REG_ARG_2, reg_rhs);
1813-
//asm_arm_more_op(emit->as, REG_RET, REG_ARG_2, reg_rhs);
1825+
asm_arm_cmp_reg_reg(emit->as, REG_ARG_2, reg_rhs);
1826+
static uint ccs[6] = {
1827+
ASM_ARM_CC_LT,
1828+
ASM_ARM_CC_GT,
1829+
ASM_ARM_CC_EQ,
1830+
ASM_ARM_CC_LE,
1831+
ASM_ARM_CC_GE,
1832+
ASM_ARM_CC_NE,
1833+
};
1834+
asm_arm_setcc_reg(emit->as, REG_RET, ccs[op - MP_BINARY_OP_LESS]);
18141835
#else
18151836
#error not implemented
18161837
#endif

0 commit comments

Comments
 (0)