Skip to content

Commit 1ef2348

Browse files
committed
py: Implement and,or,xor native ops for viper.
1 parent 1606607 commit 1ef2348

File tree

9 files changed

+110
-0
lines changed

9 files changed

+110
-0
lines changed

py/asmarm.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,21 @@ STATIC uint asm_arm_op_sub_reg(uint rd, uint rn, uint rm) {
175175
return 0x0400000 | (rn << 16) | (rd << 12) | rm;
176176
}
177177

178+
STATIC uint asm_arm_op_and_reg(uint rd, uint rn, uint rm) {
179+
// and rd, rn, rm
180+
return 0x0000000 | (rn << 16) | (rd << 12) | rm;
181+
}
182+
183+
STATIC uint asm_arm_op_eor_reg(uint rd, uint rn, uint rm) {
184+
// eor rd, rn, rm
185+
return 0x0200000 | (rn << 16) | (rd << 12) | rm;
186+
}
187+
188+
STATIC uint asm_arm_op_orr_reg(uint rd, uint rn, uint rm) {
189+
// orr rd, rn, rm
190+
return 0x1800000 | (rn << 16) | (rd << 12) | rm;
191+
}
192+
178193
void asm_arm_bkpt(asm_arm_t *as) {
179194
// bkpt #0
180195
emit_al(as, 0x1200070);
@@ -312,6 +327,21 @@ void asm_arm_sub_reg_reg_reg(asm_arm_t *as, uint rd, uint rn, uint rm) {
312327
emit_al(as, asm_arm_op_sub_reg(rd, rn, rm));
313328
}
314329

330+
void asm_arm_and_reg_reg_reg(asm_arm_t *as, uint rd, uint rn, uint rm) {
331+
// and rd, rn, rm
332+
emit_al(as, asm_arm_op_and_reg(rd, rn, rm));
333+
}
334+
335+
void asm_arm_eor_reg_reg_reg(asm_arm_t *as, uint rd, uint rn, uint rm) {
336+
// eor rd, rn, rm
337+
emit_al(as, asm_arm_op_eor_reg(rd, rn, rm));
338+
}
339+
340+
void asm_arm_orr_reg_reg_reg(asm_arm_t *as, uint rd, uint rn, uint rm) {
341+
// orr rd, rn, rm
342+
emit_al(as, asm_arm_op_orr_reg(rd, rn, rm));
343+
}
344+
315345
void asm_arm_mov_reg_local_addr(asm_arm_t *as, uint rd, int local_num) {
316346
// add rd, sp, #local_num*4
317347
emit_al(as, asm_arm_op_add_imm(rd, ASM_ARM_REG_SP, local_num << 2));

py/asmarm.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,9 @@ void asm_arm_cmp_reg_reg(asm_arm_t *as, uint rd, uint rn);
9696
// arithmetic
9797
void asm_arm_add_reg_reg_reg(asm_arm_t *as, uint rd, uint rn, uint rm);
9898
void asm_arm_sub_reg_reg_reg(asm_arm_t *as, uint rd, uint rn, uint rm);
99+
void asm_arm_and_reg_reg_reg(asm_arm_t *as, uint rd, uint rn, uint rm);
100+
void asm_arm_eor_reg_reg_reg(asm_arm_t *as, uint rd, uint rn, uint rm);
101+
void asm_arm_orr_reg_reg_reg(asm_arm_t *as, uint rd, uint rn, uint rm);
99102
void asm_arm_mov_reg_local_addr(asm_arm_t *as, uint rd, int local_num);
100103
void asm_arm_lsl_reg_reg(asm_arm_t *as, uint rd, uint rs);
101104
void asm_arm_asr_reg_reg(asm_arm_t *as, uint rd, uint rs);

py/asmx64.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@
5353
#define OPCODE_MOV_R64_TO_RM64 (0x89) /* /r */
5454
#define OPCODE_MOV_RM64_TO_R64 (0x8b)
5555
#define OPCODE_LEA_MEM_TO_R64 (0x8d) /* /r */
56+
#define OPCODE_AND_R64_TO_RM64 (0x21) /* /r */
57+
#define OPCODE_OR_R64_TO_RM64 (0x09) /* /r */
5658
#define OPCODE_XOR_R64_TO_RM64 (0x31) /* /r */
5759
#define OPCODE_ADD_R64_TO_RM64 (0x01) /* /r */
5860
#define OPCODE_ADD_I32_TO_RM32 (0x81) /* /0 */
@@ -385,6 +387,14 @@ void asm_x64_mov_i64_to_r64_aligned(asm_x64_t *as, int64_t src_i64, int dest_r64
385387
asm_x64_mov_i64_to_r64(as, src_i64, dest_r64);
386388
}
387389

390+
void asm_x64_and_r64_r64(asm_x64_t *as, int dest_r64, int src_r64) {
391+
asm_x64_generic_r64_r64(as, dest_r64, src_r64, OPCODE_AND_R64_TO_RM64);
392+
}
393+
394+
void asm_x64_or_r64_r64(asm_x64_t *as, int dest_r64, int src_r64) {
395+
asm_x64_generic_r64_r64(as, dest_r64, src_r64, OPCODE_OR_R64_TO_RM64);
396+
}
397+
388398
void asm_x64_xor_r64_r64(asm_x64_t *as, int dest_r64, int src_r64) {
389399
asm_x64_generic_r64_r64(as, dest_r64, src_r64, OPCODE_XOR_R64_TO_RM64);
390400
}

py/asmx64.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@ void asm_x64_mov_i64_to_r64_aligned(asm_x64_t *as, int64_t src_i64, int dest_r64
8686
void asm_x64_mov_r8_to_disp(asm_x64_t *as, int src_r64, int dest_r64, int dest_disp);
8787
void asm_x64_mov_r16_to_disp(asm_x64_t *as, int src_r64, int dest_r64, int dest_disp);
8888
void asm_x64_mov_r64_to_disp(asm_x64_t *as, int src_r64, int dest_r64, int dest_disp);
89+
void asm_x64_and_r64_r64(asm_x64_t *as, int dest_r64, int src_r64);
90+
void asm_x64_or_r64_r64(asm_x64_t *as, int dest_r64, int src_r64);
8991
void asm_x64_xor_r64_r64(asm_x64_t *as, int dest_r64, int src_r64);
9092
void asm_x64_shl_r64_cl(asm_x64_t* as, int dest_r64);
9193
void asm_x64_sar_r64_cl(asm_x64_t* as, int dest_r64);

py/asmx86.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@
5353
#define OPCODE_MOV_R32_TO_RM32 (0x89)
5454
#define OPCODE_MOV_RM32_TO_R32 (0x8b)
5555
#define OPCODE_LEA_MEM_TO_R32 (0x8d) /* /r */
56+
#define OPCODE_AND_R32_TO_RM32 (0x21) /* /r */
57+
#define OPCODE_OR_R32_TO_RM32 (0x09) /* /r */
5658
#define OPCODE_XOR_R32_TO_RM32 (0x31) /* /r */
5759
#define OPCODE_ADD_R32_TO_RM32 (0x01)
5860
#define OPCODE_ADD_I32_TO_RM32 (0x81) /* /0 */
@@ -287,6 +289,14 @@ void asm_x86_mov_i32_to_r32_aligned(asm_x86_t *as, int32_t src_i32, int dest_r32
287289
asm_x86_mov_i32_to_r32(as, src_i32, dest_r32);
288290
}
289291

292+
void asm_x86_and_r32_r32(asm_x86_t *as, int dest_r32, int src_r32) {
293+
asm_x86_generic_r32_r32(as, dest_r32, src_r32, OPCODE_AND_R32_TO_RM32);
294+
}
295+
296+
void asm_x86_or_r32_r32(asm_x86_t *as, int dest_r32, int src_r32) {
297+
asm_x86_generic_r32_r32(as, dest_r32, src_r32, OPCODE_OR_R32_TO_RM32);
298+
}
299+
290300
void asm_x86_xor_r32_r32(asm_x86_t *as, int dest_r32, int src_r32) {
291301
asm_x86_generic_r32_r32(as, dest_r32, src_r32, OPCODE_XOR_R32_TO_RM32);
292302
}

py/asmx86.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@ void asm_x86_mov_i32_to_r32_aligned(asm_x86_t *as, int32_t src_i32, int dest_r32
8383
void asm_x86_mov_r8_to_disp(asm_x86_t *as, int src_r32, int dest_r32, int dest_disp);
8484
void asm_x86_mov_r16_to_disp(asm_x86_t *as, int src_r32, int dest_r32, int dest_disp);
8585
void asm_x86_mov_r32_to_disp(asm_x86_t *as, int src_r32, int dest_r32, int dest_disp);
86+
void asm_x86_and_r32_r32(asm_x86_t *as, int dest_r32, int src_r32);
87+
void asm_x86_or_r32_r32(asm_x86_t *as, int dest_r32, int src_r32);
8688
void asm_x86_xor_r32_r32(asm_x86_t *as, int dest_r32, int src_r32);
8789
void asm_x86_shl_r32_cl(asm_x86_t* as, int dest_r32);
8890
void asm_x86_sar_r32_cl(asm_x86_t* as, int dest_r32);

py/emitnative.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,9 @@
145145

146146
#define ASM_LSL_REG(as, reg) asm_x64_shl_r64_cl((as), (reg))
147147
#define ASM_ASR_REG(as, reg) asm_x64_sar_r64_cl((as), (reg))
148+
#define ASM_OR_REG_REG(as, reg_dest, reg_src) asm_x64_or_r64_r64((as), (reg_dest), (reg_src))
149+
#define ASM_XOR_REG_REG(as, reg_dest, reg_src) asm_x64_xor_r64_r64((as), (reg_dest), (reg_src))
150+
#define ASM_AND_REG_REG(as, reg_dest, reg_src) asm_x64_and_r64_r64((as), (reg_dest), (reg_src))
148151
#define ASM_ADD_REG_REG(as, reg_dest, reg_src) asm_x64_add_r64_r64((as), (reg_dest), (reg_src))
149152
#define ASM_SUB_REG_REG(as, reg_dest, reg_src) asm_x64_sub_r64_r64((as), (reg_dest), (reg_src))
150153

@@ -270,6 +273,9 @@ STATIC byte mp_f_n_args[MP_F_NUMBER_OF] = {
270273

271274
#define ASM_LSL_REG(as, reg) asm_x86_shl_r32_cl((as), (reg))
272275
#define ASM_ASR_REG(as, reg) asm_x86_sar_r32_cl((as), (reg))
276+
#define ASM_OR_REG_REG(as, reg_dest, reg_src) asm_x86_or_r32_r32((as), (reg_dest), (reg_src))
277+
#define ASM_XOR_REG_REG(as, reg_dest, reg_src) asm_x86_xor_r32_r32((as), (reg_dest), (reg_src))
278+
#define ASM_AND_REG_REG(as, reg_dest, reg_src) asm_x86_and_r32_r32((as), (reg_dest), (reg_src))
273279
#define ASM_ADD_REG_REG(as, reg_dest, reg_src) asm_x86_add_r32_r32((as), (reg_dest), (reg_src))
274280
#define ASM_SUB_REG_REG(as, reg_dest, reg_src) asm_x86_sub_r32_r32((as), (reg_dest), (reg_src))
275281

@@ -346,6 +352,9 @@ STATIC byte mp_f_n_args[MP_F_NUMBER_OF] = {
346352

347353
#define ASM_LSL_REG_REG(as, reg_dest, reg_shift) asm_thumb_format_4((as), ASM_THUMB_FORMAT_4_LSL, (reg_dest), (reg_shift))
348354
#define ASM_ASR_REG_REG(as, reg_dest, reg_shift) asm_thumb_format_4((as), ASM_THUMB_FORMAT_4_ASR, (reg_dest), (reg_shift))
355+
#define ASM_OR_REG_REG(as, reg_dest, reg_src) asm_thumb_format_4((as), ASM_THUMB_FORMAT_4_ORR, (reg_dest), (reg_src))
356+
#define ASM_XOR_REG_REG(as, reg_dest, reg_src) asm_thumb_format_4((as), ASM_THUMB_FORMAT_4_EOR, (reg_dest), (reg_src))
357+
#define ASM_AND_REG_REG(as, reg_dest, reg_src) asm_thumb_format_4((as), ASM_THUMB_FORMAT_4_AND, (reg_dest), (reg_src))
349358
#define ASM_ADD_REG_REG(as, reg_dest, reg_src) asm_thumb_add_rlo_rlo_rlo((as), (reg_dest), (reg_dest), (reg_src))
350359
#define ASM_SUB_REG_REG(as, reg_dest, reg_src) asm_thumb_sub_rlo_rlo_rlo((as), (reg_dest), (reg_dest), (reg_src))
351360

@@ -422,6 +431,9 @@ STATIC byte mp_f_n_args[MP_F_NUMBER_OF] = {
422431

423432
#define ASM_LSL_REG_REG(as, reg_dest, reg_shift) asm_arm_lsl_reg_reg((as), (reg_dest), (reg_shift))
424433
#define ASM_ASR_REG_REG(as, reg_dest, reg_shift) asm_arm_asr_reg_reg((as), (reg_dest), (reg_shift))
434+
#define ASM_OR_REG_REG(as, reg_dest, reg_src) asm_arm_orr_reg_reg_reg((as), (reg_dest), (reg_dest), (reg_src))
435+
#define ASM_XOR_REG_REG(as, reg_dest, reg_src) asm_arm_eor_reg_reg_reg((as), (reg_dest), (reg_dest), (reg_src))
436+
#define ASM_AND_REG_REG(as, reg_dest, reg_src) asm_arm_and_reg_reg_reg((as), (reg_dest), (reg_dest), (reg_src))
425437
#define ASM_ADD_REG_REG(as, reg_dest, reg_src) asm_arm_add_reg_reg_reg((as), (reg_dest), (reg_dest), (reg_src))
426438
#define ASM_SUB_REG_REG(as, reg_dest, reg_src) asm_arm_sub_reg_reg_reg((as), (reg_dest), (reg_dest), (reg_src))
427439

@@ -1769,6 +1781,15 @@ STATIC void emit_native_binary_op(emit_t *emit, mp_binary_op_t op) {
17691781
ASM_ASR_REG_REG(emit->as, REG_ARG_2, reg_rhs);
17701782
emit_post_push_reg(emit, VTYPE_INT, REG_ARG_2);
17711783
#endif
1784+
} else if (op == MP_BINARY_OP_OR || op == MP_BINARY_OP_INPLACE_OR) {
1785+
ASM_OR_REG_REG(emit->as, REG_ARG_2, reg_rhs);
1786+
emit_post_push_reg(emit, VTYPE_INT, REG_ARG_2);
1787+
} else if (op == MP_BINARY_OP_XOR || op == MP_BINARY_OP_INPLACE_XOR) {
1788+
ASM_XOR_REG_REG(emit->as, REG_ARG_2, reg_rhs);
1789+
emit_post_push_reg(emit, VTYPE_INT, REG_ARG_2);
1790+
} else if (op == MP_BINARY_OP_AND || op == MP_BINARY_OP_INPLACE_AND) {
1791+
ASM_AND_REG_REG(emit->as, REG_ARG_2, reg_rhs);
1792+
emit_post_push_reg(emit, VTYPE_INT, REG_ARG_2);
17721793
} else if (op == MP_BINARY_OP_ADD || op == MP_BINARY_OP_INPLACE_ADD) {
17731794
ASM_ADD_REG_REG(emit->as, REG_ARG_2, reg_rhs);
17741795
emit_post_push_reg(emit, VTYPE_INT, REG_ARG_2);

tests/micropython/viper_binop_arith.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,25 @@ def shr(x:int, y:int):
3434
shr(1, 3)
3535
shr(42, 2)
3636
shr(-42, 2)
37+
38+
@micropython.viper
39+
def and_(x:int, y:int):
40+
print(x & y, y & x)
41+
and_(1, 0)
42+
and_(1, 3)
43+
and_(0xf0, 0x3f)
44+
and_(-42, 6)
45+
46+
@micropython.viper
47+
def or_(x:int, y:int):
48+
print(x | y, y | x)
49+
or_(1, 0)
50+
or_(1, 2)
51+
or_(-42, 5)
52+
53+
@micropython.viper
54+
def xor(x:int, y:int):
55+
print(x ^ y, y ^ x)
56+
xor(1, 0)
57+
xor(1, 2)
58+
xor(-42, 5)

tests/micropython/viper_binop_arith.py.exp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,13 @@
2323
0
2424
10
2525
-11
26+
0 0
27+
1 1
28+
48 48
29+
6 6
30+
1 1
31+
3 3
32+
-41 -41
33+
1 1
34+
3 3
35+
-45 -45

0 commit comments

Comments
 (0)