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>
This commit is contained in:
Damien George
2024-03-18 12:29:11 +11:00
parent d92dff881c
commit f52b0d0ff1
8 changed files with 61 additions and 0 deletions

View File

@@ -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));