Skip to content
This repository was archived by the owner on Oct 28, 2023. It is now read-only.

Commit 1f2558d

Browse files
committed
Merge pull request #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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy