Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

py/emitnative: Further Viper integer-indexed load/store improvements.#17342

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes fromall commits
Commits
Show all changes
10 commits
Select commitHold shift + click to select a range
78ee1ba
py/emitnative: Let Viper int-indexed code use appropriate operands.
agattiMay 22, 2025
1f5ba69
py/asmthumb: Extend load/store generators with ARMv7-M opcodes.
agattiMay 22, 2025
84ad2c6
py/asmxtensa: Extend existing specialised load/store operations range.
agattiMay 22, 2025
901c96d
py/emitnative: Remove redundant RV32 Viper int-indexed code.
agattiMay 22, 2025
bbab2e9
py/asmarm: Extend int-indexed 32-bit load/store offset ranges.
agattiMay 22, 2025
5b90d6d
py/asmarm: Give a proper name to the temporary register.
agattiJun 8, 2025
c1c73d9
tests/run-tests.py: Unconditionally enable native tests if asked.
agattiJun 4, 2025
0da22b2
tools/ci.sh: Fix nanbox CI test runs.
agattiJun 4, 2025
80b823b
py/asmxtensa: Extend BCCZ range to 18 bits.
agattiJun 8, 2025
43f6013
py/asmxtensa: Extend BCC range to 18 bits.
agattiJun 8, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletionsports/unix/Makefile
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -256,21 +256,24 @@ endif

include $(TOP)/py/mkrules.mk

.PHONY: test test_full
.PHONY: testtest_full_no_nativetest_full

test: $(BUILD)/$(PROG) $(TOP)/tests/run-tests.py
$(eval DIRNAME=ports/$(notdir $(CURDIR)))
cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/$(BUILD)/$(PROG) ./run-tests.py

test_full: $(BUILD)/$(PROG) $(TOP)/tests/run-tests.py
test_full_no_native: $(BUILD)/$(PROG) $(TOP)/tests/run-tests.py
$(eval DIRNAME=ports/$(notdir $(CURDIR)))
cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/$(BUILD)/$(PROG) ./run-tests.py
cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/$(BUILD)/$(PROG) ./run-tests.py -d thread
cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/$(BUILD)/$(PROG) ./run-tests.py --emit native
cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/$(BUILD)/$(PROG) ./run-tests.py --via-mpy $(RUN_TESTS_MPY_CROSS_FLAGS) -d basics float micropython
cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/$(BUILD)/$(PROG) ./run-tests.py --via-mpy $(RUN_TESTS_MPY_CROSS_FLAGS) --emit native -d basics float micropython
cat $(TOP)/tests/basics/0prelim.py | ./$(BUILD)/$(PROG) | grep -q 'abc'

test_full: $(BUILD)/$(PROG) $(TOP)/tests/run-tests.py test_full_no_native
$(eval DIRNAME=ports/$(notdir $(CURDIR)))
cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/$(BUILD)/$(PROG) ./run-tests.py --emit native
cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/$(BUILD)/$(PROG) ./run-tests.py --via-mpy $(RUN_TESTS_MPY_CROSS_FLAGS) --emit native -d basics float micropython

test_gcov: test_full
gcov -o $(BUILD)/py $(TOP)/py/*.c
gcov -o $(BUILD)/extmod $(TOP)/extmod/*.c
Expand Down
60 changes: 38 additions & 22 deletionspy/asmarm.c
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -36,6 +36,8 @@

#include "py/asmarm.h"

#define REG_TEMP ASM_ARM_REG_R8

#define SIGNED_FIT24(x) (((x) & 0xff800000) == 0) || (((x) & 0xff000000) == 0xff000000)

// Insert word into instruction flow
Expand DownExpand Up@@ -171,8 +173,8 @@ void asm_arm_entry(asm_arm_t *as, int num_locals) {
if (as->stack_adjust < 0x100) {
emit_al(as, asm_arm_op_sub_imm(ASM_ARM_REG_SP, ASM_ARM_REG_SP, as->stack_adjust));
} else {
asm_arm_mov_reg_i32_optimised(as,ASM_ARM_REG_R8, as->stack_adjust);
emit_al(as, asm_arm_op_sub_reg(ASM_ARM_REG_SP, ASM_ARM_REG_SP,ASM_ARM_REG_R8));
asm_arm_mov_reg_i32_optimised(as,REG_TEMP, as->stack_adjust);
emit_al(as, asm_arm_op_sub_reg(ASM_ARM_REG_SP, ASM_ARM_REG_SP,REG_TEMP));
}
}
}
Expand All@@ -182,8 +184,8 @@ void asm_arm_exit(asm_arm_t *as) {
if (as->stack_adjust < 0x100) {
emit_al(as, asm_arm_op_add_imm(ASM_ARM_REG_SP, ASM_ARM_REG_SP, as->stack_adjust));
} else {
asm_arm_mov_reg_i32_optimised(as,ASM_ARM_REG_R8, as->stack_adjust);
emit_al(as, asm_arm_op_add_reg(ASM_ARM_REG_SP, ASM_ARM_REG_SP,ASM_ARM_REG_R8));
asm_arm_mov_reg_i32_optimised(as,REG_TEMP, as->stack_adjust);
emit_al(as, asm_arm_op_add_reg(ASM_ARM_REG_SP, ASM_ARM_REG_SP,REG_TEMP));
}
}

Expand DownExpand Up@@ -293,10 +295,10 @@ void asm_arm_orr_reg_reg_reg(asm_arm_t *as, uint rd, uint rn, uint rm) {

void asm_arm_mov_reg_local_addr(asm_arm_t *as, uint rd, int local_num) {
if (local_num >= 0x40) {
// movr8, #local_num*4
// add rd, sp,r8
asm_arm_mov_reg_i32_optimised(as,ASM_ARM_REG_R8, local_num << 2);
emit_al(as, asm_arm_op_add_reg(rd, ASM_ARM_REG_SP,ASM_ARM_REG_R8));
// movtemp, #local_num*4
// add rd, sp,temp
asm_arm_mov_reg_i32_optimised(as,REG_TEMP, local_num << 2);
emit_al(as, asm_arm_op_add_reg(rd, ASM_ARM_REG_SP,REG_TEMP));
} else {
// add rd, sp, #local_num*4
emit_al(as, asm_arm_op_add_imm(rd, ASM_ARM_REG_SP, local_num << 2));
Expand DownExpand Up@@ -333,9 +335,16 @@ void asm_arm_asr_reg_reg(asm_arm_t *as, uint rd, uint rs) {
emit_al(as, 0x1a00050 | (rd << 12) | (rs << 8) | rd);
}

void asm_arm_ldr_reg_reg(asm_arm_t *as, uint rd, uint rn, uint byte_offset) {
// ldr rd, [rn, #off]
emit_al(as, 0x5900000 | (rn << 16) | (rd << 12) | byte_offset);
void asm_arm_ldr_reg_reg_offset(asm_arm_t *as, uint rd, uint rn, uint byte_offset) {
if (byte_offset < 0x1000) {
// ldr rd, [rn, #off]
emit_al(as, 0x5900000 | (rn << 16) | (rd << 12) | byte_offset);
} else {
// mov temp, #off
// ldr rd, [rn, temp]
asm_arm_mov_reg_i32_optimised(as, REG_TEMP, byte_offset);
emit_al(as, 0x7900000 | (rn << 16) | (rd << 12) | REG_TEMP);
}
}

void asm_arm_ldrh_reg_reg(asm_arm_t *as, uint rd, uint rn) {
Expand All@@ -345,19 +354,19 @@ void asm_arm_ldrh_reg_reg(asm_arm_t *as, uint rd, uint rn) {

void asm_arm_ldrh_reg_reg_reg(asm_arm_t *as, uint rd, uint rm, uint rn) {
// ldrh doesn't support scaled register index
emit_al(as, 0x1a00080 | (ASM_ARM_REG_R8 << 12) | rn); // movr8, rn, lsl #1
emit_al(as, 0x19000b0 | (rm << 16) | (rd << 12) |ASM_ARM_REG_R8); // ldrh rd, [rm,r8];
emit_al(as, 0x1a00080 | (REG_TEMP << 12) | rn); // movtemp, rn, lsl #1
emit_al(as, 0x19000b0 | (rm << 16) | (rd << 12) |REG_TEMP); // ldrh rd, [rm,temp];
}

void asm_arm_ldrh_reg_reg_offset(asm_arm_t *as, uint rd, uint rn, uint byte_offset) {
if (byte_offset < 0x100) {
// ldrh rd, [rn, #off]
emit_al(as, 0x1d000b0 | (rn << 16) | (rd << 12) | ((byte_offset & 0xf0) << 4) | (byte_offset & 0xf));
} else {
// movr8, #off
// ldrh rd, [rn,r8]
asm_arm_mov_reg_i32_optimised(as,ASM_ARM_REG_R8, byte_offset);
emit_al(as, 0x19000b0 | (rn << 16) | (rd << 12) |ASM_ARM_REG_R8);
// movtemp, #off
// ldrh rd, [rn,temp]
asm_arm_mov_reg_i32_optimised(as,REG_TEMP, byte_offset);
emit_al(as, 0x19000b0 | (rn << 16) | (rd << 12) |REG_TEMP);
}
}

Expand All@@ -376,9 +385,16 @@ void asm_arm_ldr_reg_reg_reg(asm_arm_t *as, uint rd, uint rm, uint rn) {
emit_al(as, 0x7900100 | (rm << 16) | (rd << 12) | rn);
}

void asm_arm_str_reg_reg(asm_arm_t *as, uint rd, uint rm, uint byte_offset) {
// str rd, [rm, #off]
emit_al(as, 0x5800000 | (rm << 16) | (rd << 12) | byte_offset);
void asm_arm_str_reg_reg_offset(asm_arm_t *as, uint rd, uint rm, uint byte_offset) {
if (byte_offset < 0x1000) {
// str rd, [rm, #off]
emit_al(as, 0x5800000 | (rm << 16) | (rd << 12) | byte_offset);
} else {
// mov temp, #off
// str rd, [rm, temp]
asm_arm_mov_reg_i32_optimised(as, REG_TEMP, byte_offset);
emit_al(as, 0x7800000 | (rm << 16) | (rd << 12) | REG_TEMP);
}
}

void asm_arm_strh_reg_reg(asm_arm_t *as, uint rd, uint rm) {
Expand All@@ -398,8 +414,8 @@ void asm_arm_str_reg_reg_reg(asm_arm_t *as, uint rd, uint rm, uint rn) {

void asm_arm_strh_reg_reg_reg(asm_arm_t *as, uint rd, uint rm, uint rn) {
// strh doesn't support scaled register index
emit_al(as, 0x1a00080 | (ASM_ARM_REG_R8 << 12) | rn); // movr8, rn, lsl #1
emit_al(as, 0x18000b0 | (rm << 16) | (rd << 12) |ASM_ARM_REG_R8); // strh rd, [rm,r8]
emit_al(as, 0x1a00080 | (REG_TEMP << 12) | rn); // movtemp, rn, lsl #1
emit_al(as, 0x18000b0 | (rm << 16) | (rd << 12) |REG_TEMP); // strh rd, [rm,temp]
}

void asm_arm_strb_reg_reg_reg(asm_arm_t *as, uint rd, uint rm, uint rn) {
Expand Down
14 changes: 8 additions & 6 deletionspy/asmarm.h
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -109,11 +109,11 @@ void asm_arm_lsr_reg_reg(asm_arm_t *as, uint rd, uint rs);
void asm_arm_asr_reg_reg(asm_arm_t *as, uint rd, uint rs);

// memory
voidasm_arm_ldr_reg_reg(asm_arm_t *as, uint rd, uint rn, uint byte_offset);
voidasm_arm_ldr_reg_reg_offset(asm_arm_t *as, uint rd, uint rn, uint byte_offset);
void asm_arm_ldrh_reg_reg(asm_arm_t *as, uint rd, uint rn);
void asm_arm_ldrh_reg_reg_offset(asm_arm_t *as, uint rd, uint rn, uint byte_offset);
void asm_arm_ldrb_reg_reg(asm_arm_t *as, uint rd, uint rn);
voidasm_arm_str_reg_reg(asm_arm_t *as, uint rd, uint rm, uint byte_offset);
voidasm_arm_str_reg_reg_offset(asm_arm_t *as, uint rd, uint rm, uint byte_offset);
void asm_arm_strh_reg_reg(asm_arm_t *as, uint rd, uint rm);
void asm_arm_strb_reg_reg(asm_arm_t *as, uint rd, uint rm);

Expand DownExpand Up@@ -208,16 +208,18 @@ void asm_arm_bx_reg(asm_arm_t *as, uint reg_src);
#define ASM_SUB_REG_REG(as, reg_dest, reg_src) asm_arm_sub_reg_reg_reg((as), (reg_dest), (reg_dest), (reg_src))
#define ASM_MUL_REG_REG(as, reg_dest, reg_src) asm_arm_mul_reg_reg_reg((as), (reg_dest), (reg_dest), (reg_src))

#define ASM_LOAD_REG_REG_OFFSET(as, reg_dest, reg_base, word_offset)asm_arm_ldr_reg_reg((as), (reg_dest), (reg_base), 4 * (word_offset))
#define ASM_LOAD_REG_REG_OFFSET(as, reg_dest, reg_base, word_offset)ASM_LOAD32_REG_REG_OFFSET((as), (reg_dest), (reg_base), (word_offset))
#define ASM_LOAD8_REG_REG(as, reg_dest, reg_base) asm_arm_ldrb_reg_reg((as), (reg_dest), (reg_base))
#define ASM_LOAD16_REG_REG(as, reg_dest, reg_base) asm_arm_ldrh_reg_reg((as), (reg_dest), (reg_base))
#define ASM_LOAD16_REG_REG_OFFSET(as, reg_dest, reg_base, uint16_offset) asm_arm_ldrh_reg_reg_offset((as), (reg_dest), (reg_base), 2 * (uint16_offset))
#define ASM_LOAD32_REG_REG(as, reg_dest, reg_base) asm_arm_ldr_reg_reg((as), (reg_dest), (reg_base), 0)
#define ASM_LOAD32_REG_REG(as, reg_dest, reg_base) asm_arm_ldr_reg_reg_offset((as), (reg_dest), (reg_base), 0)
#define ASM_LOAD32_REG_REG_OFFSET(as, reg_dest, reg_base, word_offset) asm_arm_ldr_reg_reg_offset((as), (reg_dest), (reg_base), 4 * (word_offset))

#define ASM_STORE_REG_REG_OFFSET(as,reg_dest, reg_base, word_offset)asm_arm_str_reg_reg((as), (reg_dest), (reg_base), 4 * (word_offset))
#define ASM_STORE_REG_REG_OFFSET(as,reg_value, reg_base, word_offset)ASM_STORE32_REG_REG_OFFSET((as), (reg_value), (reg_base), (word_offset))
#define ASM_STORE8_REG_REG(as, reg_value, reg_base) asm_arm_strb_reg_reg((as), (reg_value), (reg_base))
#define ASM_STORE16_REG_REG(as, reg_value, reg_base) asm_arm_strh_reg_reg((as), (reg_value), (reg_base))
#define ASM_STORE32_REG_REG(as, reg_value, reg_base) asm_arm_str_reg_reg((as), (reg_value), (reg_base), 0)
#define ASM_STORE32_REG_REG(as, reg_value, reg_base) asm_arm_str_reg_reg_offset((as), (reg_value), (reg_base), 0)
#define ASM_STORE32_REG_REG_OFFSET(as, reg_value, reg_base, word_offset) asm_arm_str_reg_reg_offset((as), (reg_value), (reg_base), 4 * (word_offset))

#define ASM_LOAD8_REG_REG_REG(as, reg_dest, reg_base, reg_index) asm_arm_ldrb_reg_reg_reg((as), (reg_dest), (reg_base), (reg_index))
#define ASM_LOAD16_REG_REG_REG(as, reg_dest, reg_base, reg_index) asm_arm_ldrh_reg_reg_reg((as), (reg_dest), (reg_base), (reg_index))
Expand Down
10 changes: 6 additions & 4 deletionspy/asmrv32.h
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -732,11 +732,12 @@ void asm_rv32_emit_store_reg_reg_offset(asm_rv32_t *state, mp_uint_t source, mp_
#define ASM_JUMP_IF_REG_NONZERO(state, rs, label, bool_test) asm_rv32_emit_jump_if_reg_nonzero(state, rs, label)
#define ASM_JUMP_IF_REG_ZERO(state, rs, label, bool_test) asm_rv32_emit_jump_if_reg_eq(state, rs, ASM_RV32_REG_ZERO, label)
#define ASM_JUMP_REG(state, rs) asm_rv32_opcode_cjr(state, rs)
#define ASM_LOAD_REG_REG_OFFSET(state, rd, rs, offset) ASM_LOAD32_REG_REG_OFFSET(state, rd, rs, offset)
#define ASM_LOAD16_REG_REG_OFFSET(state, rd, rs, offset) asm_rv32_emit_load16_reg_reg_offset(state, rd, rs, offset)
#define ASM_LOAD16_REG_REG(state, rd, rs) asm_rv32_opcode_lhu(state, rd, rs, 0)
#define ASM_LOAD32_REG_REG(state, rd, rs) ASM_LOAD_REG_REG_OFFSET(state, rd, rs, 0)
#define ASM_LOAD32_REG_REG(state, rd, rs) ASM_LOAD32_REG_REG_OFFSET(state, rd, rs, 0)
#define ASM_LOAD32_REG_REG_OFFSET(state, rd, rs, offset) asm_rv32_emit_load_reg_reg_offset(state, rd, rs, offset)
#define ASM_LOAD8_REG_REG(state, rd, rs) asm_rv32_opcode_lbu(state, rd, rs, 0)
#define ASM_LOAD_REG_REG_OFFSET(state, rd, rs, offset) asm_rv32_emit_load_reg_reg_offset(state, rd, rs, offset)
#define ASM_LSL_REG_REG(state, rd, rs) asm_rv32_opcode_sll(state, rd, rd, rs)
#define ASM_LSR_REG_REG(state, rd, rs) asm_rv32_opcode_srl(state, rd, rd, rs)
#define ASM_MOV_LOCAL_REG(state, local, rs) asm_rv32_emit_mov_local_reg(state, local, rs)
Expand All@@ -749,10 +750,11 @@ void asm_rv32_emit_store_reg_reg_offset(asm_rv32_t *state, mp_uint_t source, mp_
#define ASM_NEG_REG(state, rd) asm_rv32_opcode_sub(state, rd, ASM_RV32_REG_ZERO, rd)
#define ASM_NOT_REG(state, rd) asm_rv32_opcode_xori(state, rd, rd, -1)
#define ASM_OR_REG_REG(state, rd, rs) asm_rv32_opcode_or(state, rd, rd, rs)
#define ASM_STORE_REG_REG_OFFSET(state, rd, rs, offset) ASM_STORE32_REG_REG_OFFSET(state, rd, rs, offset)
#define ASM_STORE16_REG_REG(state, rs1, rs2) asm_rv32_opcode_sh(state, rs1, rs2, 0)
#define ASM_STORE32_REG_REG(state, rs1, rs2) ASM_STORE_REG_REG_OFFSET(state, rs1, rs2, 0)
#define ASM_STORE32_REG_REG(state, rs1, rs2) ASM_STORE32_REG_REG_OFFSET(state, rs1, rs2, 0)
#define ASM_STORE32_REG_REG_OFFSET(state, rd, rs, offset) asm_rv32_emit_store_reg_reg_offset(state, rd, rs, offset)
#define ASM_STORE8_REG_REG(state, rs1, rs2) asm_rv32_opcode_sb(state, rs1, rs2, 0)
#define ASM_STORE_REG_REG_OFFSET(state, rd, rs, offset) asm_rv32_emit_store_reg_reg_offset(state, rd, rs, offset)
#define ASM_SUB_REG_REG(state, rd, rs) asm_rv32_opcode_sub(state, rd, rd, rs)
#define ASM_XOR_REG_REG(state, rd, rs) asm_rv32_emit_optimised_xor(state, rd, rs)
#define ASM_CLR_REG(state, rd)
Expand Down
66 changes: 35 additions & 31 deletionspy/asmthumb.c
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -40,6 +40,7 @@
#define UNSIGNED_FIT5(x) ((uint32_t)(x) < 32)
#define UNSIGNED_FIT7(x) ((uint32_t)(x) < 128)
#define UNSIGNED_FIT8(x) (((x) & 0xffffff00) == 0)
#define UNSIGNED_FIT12(x) (((x) & 0xfffff000) == 0)
#define UNSIGNED_FIT16(x) (((x) & 0xffff0000) == 0)
#define SIGNED_FIT8(x) (((x) & 0xffffff80) == 0) || (((x) & 0xffffff80) == 0xffffff80)
#define SIGNED_FIT9(x) (((x) & 0xffffff00) == 0) || (((x) & 0xffffff00) == 0xffffff00)
Expand All@@ -52,12 +53,6 @@
#define OP_SUB_W_RRI_HI(reg_src) (0xf2a0 | (reg_src))
#define OP_SUB_W_RRI_LO(reg_dest, imm11) ((imm11 << 4 & 0x7000) | reg_dest << 8 | (imm11 & 0xff))

#define OP_LDR_W_HI(reg_base) (0xf8d0 | (reg_base))
#define OP_LDR_W_LO(reg_dest, imm12) ((reg_dest) << 12 | (imm12))

#define OP_LDRH_W_HI(reg_base) (0xf8b0 | (reg_base))
#define OP_LDRH_W_LO(reg_dest, imm12) ((reg_dest) << 12 | (imm12))

static inline byte *asm_thumb_get_cur_to_write_bytes(asm_thumb_t *as, int n) {
return mp_asm_base_get_cur_to_write_bytes(&as->base, n);
}
Expand DownExpand Up@@ -432,11 +427,6 @@ void asm_thumb_mov_reg_pcrel(asm_thumb_t *as, uint rlo_dest, uint label) {
asm_thumb_add_reg_reg(as, rlo_dest, ASM_THUMB_REG_R15); // 2 bytes
}

// ARMv7-M only
static inline void asm_thumb_ldr_reg_reg_i12(asm_thumb_t *as, uint reg_dest, uint reg_base, uint word_offset) {
asm_thumb_op32(as, OP_LDR_W_HI(reg_base), OP_LDR_W_LO(reg_dest, word_offset * 4));
}

// emits code for: reg_dest = reg_base + offset << offset_shift
static void asm_thumb_add_reg_reg_offset(asm_thumb_t *as, uint reg_dest, uint reg_base, uint offset, uint offset_shift) {
if (reg_dest < ASM_THUMB_REG_R8 && reg_base < ASM_THUMB_REG_R8) {
Expand DownExpand Up@@ -464,30 +454,44 @@ static void asm_thumb_add_reg_reg_offset(asm_thumb_t *as, uint reg_dest, uint re
}
}

void asm_thumb_ldr_reg_reg_i12_optimised(asm_thumb_t *as, uint reg_dest, uint reg_base, uint word_offset) {
if (reg_dest < ASM_THUMB_REG_R8 && reg_base < ASM_THUMB_REG_R8 && UNSIGNED_FIT5(word_offset)) {
asm_thumb_ldr_rlo_rlo_i5(as, reg_dest, reg_base, word_offset);
} else if (asm_thumb_allow_armv7m(as)) {
asm_thumb_ldr_reg_reg_i12(as, reg_dest, reg_base, word_offset);
#define OP_LDR_STR_W_HI(shift, reg) ((0xf880 | (shift) << 5) | (reg))
#define OP_LDR_STR_W_LO(reg, imm12) (((reg) << 12) | (imm12))

#define OP_LDR 0x01
#define OP_STR 0x00

#define OP_LDR_W 0x10
#define OP_STR_W 0x00

static const uint8_t OP_LDR_STR_TABLE[3] = {
0x0E, 0x10, 0x0C
};

void asm_thumb_load_reg_reg_offset(asm_thumb_t *as, uint reg_dest, uint reg_base, uint offset, uint shift) {
if (UNSIGNED_FIT5(offset) && (reg_dest < ASM_THUMB_REG_R8) && (reg_base < ASM_THUMB_REG_R8)) {
// Can use T1 encoding
asm_thumb_op16(as, ((OP_LDR_STR_TABLE[shift] | OP_LDR) << 11) | (offset << 6) | (reg_base << 3) | reg_dest);
} else if (asm_thumb_allow_armv7m(as) && UNSIGNED_FIT12(offset << shift)) {
// Can use T3 encoding
asm_thumb_op32(as, (OP_LDR_STR_W_HI(shift, reg_base) | OP_LDR_W), OP_LDR_STR_W_LO(reg_dest, (offset << shift)));
} else {
asm_thumb_add_reg_reg_offset(as, reg_dest, reg_base, word_offset - 31, 2);
asm_thumb_ldr_rlo_rlo_i5(as, reg_dest, reg_dest, 31);
// Must use the generic sequence
asm_thumb_add_reg_reg_offset(as, reg_dest, reg_base, offset - 31, shift);
asm_thumb_op16(as, ((OP_LDR_STR_TABLE[shift] | OP_LDR) << 11) | (31 << 6) | (reg_dest << 3) | (reg_dest));
}
}

// ARMv7-M only
static inline void asm_thumb_ldrh_reg_reg_i12(asm_thumb_t *as, uint reg_dest, uint reg_base, uint uint16_offset) {
asm_thumb_op32(as, OP_LDRH_W_HI(reg_base), OP_LDRH_W_LO(reg_dest, uint16_offset * 2));
}

void asm_thumb_ldrh_reg_reg_i12_optimised(asm_thumb_t *as, uint reg_dest, uint reg_base, uint uint16_offset) {
if (reg_dest < ASM_THUMB_REG_R8 && reg_base < ASM_THUMB_REG_R8 && UNSIGNED_FIT5(uint16_offset)) {
asm_thumb_ldrh_rlo_rlo_i5(as, reg_dest, reg_base, uint16_offset);
} else if (asm_thumb_allow_armv7m(as)) {
asm_thumb_ldrh_reg_reg_i12(as, reg_dest, reg_base, uint16_offset);
void asm_thumb_store_reg_reg_offset(asm_thumb_t *as, uint reg_src, uint reg_base, uint offset, uint shift) {
if (UNSIGNED_FIT5(offset) && (reg_src < ASM_THUMB_REG_R8) && (reg_base < ASM_THUMB_REG_R8)) {
// Can use T1 encoding
asm_thumb_op16(as, ((OP_LDR_STR_TABLE[shift] | OP_STR) << 11) | (offset << 6) | (reg_base << 3) | reg_src);
} else if (asm_thumb_allow_armv7m(as) && UNSIGNED_FIT12(offset << shift)) {
// Can use T3 encoding
asm_thumb_op32(as, (OP_LDR_STR_W_HI(shift, reg_base) | OP_STR_W), OP_LDR_STR_W_LO(reg_src, (offset << shift)));
} else {
asm_thumb_add_reg_reg_offset(as, reg_dest, reg_base, uint16_offset - 31, 1);
asm_thumb_ldrh_rlo_rlo_i5(as, reg_dest, reg_dest, 31);
// Must use the generic sequence
asm_thumb_add_reg_reg_offset(as, reg_base, reg_base, offset - 31, shift);
asm_thumb_op16(as, ((OP_LDR_STR_TABLE[shift] | OP_STR) << 11) | (31 << 6) | (reg_base << 3) | reg_src);
}
}

Expand DownExpand Up@@ -569,7 +573,7 @@ void asm_thumb_b_rel12(asm_thumb_t *as, int rel) {

void asm_thumb_bl_ind(asm_thumb_t *as, uint fun_id, uint reg_temp) {
// Load ptr to function from table, indexed by fun_id, then call it
asm_thumb_ldr_reg_reg_i12_optimised(as, reg_temp, ASM_THUMB_REG_FUN_TABLE, fun_id);
asm_thumb_load_reg_reg_offset(as, reg_temp, ASM_THUMB_REG_FUN_TABLE, fun_id, 2);
asm_thumb_op16(as, OP_BLX(reg_temp));
}

Expand Down
Loading
Loading

[8]ページ先頭

©2009-2026 Movatter.jp