diff options
author | Damien George <damien@micropython.org> | 2024-03-18 12:29:11 +1100 |
---|---|---|
committer | Damien George <damien@micropython.org> | 2024-03-19 10:31:36 +1100 |
commit | f52b0d0ff1788225fd61a748e0786aa90e953481 (patch) | |
tree | 61f99662e12760408831b85444477fe46212bbb9 /py/asmarm.c | |
parent | d92dff881ca99281893b1d77eee4bf2eca25d0c8 (diff) |
py/asm: Add ASM_NOT_REG and ASM_NEG_REG macros for unary ops.
ASM_NOT_REG is optional, it can be synthesised by xor(reg, -1).
ASM_NEG_REG can also be synthesised with a subtraction, but most
architectures have a dedicated instruction for it.
Signed-off-by: Damien George <damien@micropython.org>
Diffstat (limited to 'py/asmarm.c')
-rw-r--r-- | py/asmarm.c | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/py/asmarm.c b/py/asmarm.c index cd346949e..600649070 100644 --- a/py/asmarm.c +++ b/py/asmarm.c @@ -77,6 +77,11 @@ static uint asm_arm_op_mvn_imm(uint rd, uint imm) { return 0x3e00000 | (rd << 12) | imm; } +static uint asm_arm_op_mvn_reg(uint rd, uint rm) { + // mvn rd, rm + return 0x1e00000 | (rd << 12) | rm; +} + static uint asm_arm_op_add_imm(uint rd, uint rn, uint imm) { // add rd, rn, #imm return 0x2800000 | (rn << 16) | (rd << 12) | (imm & 0xFF); @@ -97,6 +102,11 @@ static uint asm_arm_op_sub_reg(uint rd, uint rn, uint rm) { return 0x0400000 | (rn << 16) | (rd << 12) | rm; } +static uint asm_arm_op_rsb_imm(uint rd, uint rn, uint imm) { + // rsb rd, rn, #imm + return 0x2600000 | (rn << 16) | (rd << 12) | (imm & 0xFF); +} + static uint asm_arm_op_mul_reg(uint rd, uint rm, uint rs) { // mul rd, rm, rs assert(rd != rm); @@ -228,11 +238,23 @@ void asm_arm_setcc_reg(asm_arm_t *as, uint rd, uint cond) { emit(as, asm_arm_op_mov_imm(rd, 0) | (cond ^ (1 << 28))); // mov!COND rd, #0 } +void asm_arm_mvn_reg_reg(asm_arm_t *as, uint rd, uint rm) { + // mvn rd, rm + // computes: rd := ~rm + emit_al(as, asm_arm_op_mvn_reg(rd, rm)); +} + void asm_arm_add_reg_reg_reg(asm_arm_t *as, uint rd, uint rn, uint rm) { // add rd, rn, rm emit_al(as, asm_arm_op_add_reg(rd, rn, rm)); } +void asm_arm_rsb_reg_reg_imm(asm_arm_t *as, uint rd, uint rn, uint imm) { + // rsb rd, rn, #imm + // computes: rd := #imm - rn + emit_al(as, asm_arm_op_rsb_imm(rd, rn, imm)); +} + void asm_arm_sub_reg_reg_reg(asm_arm_t *as, uint rd, uint rn, uint rm) { // sub rd, rn, rm emit_al(as, asm_arm_op_sub_reg(rd, rn, rm)); |