From 4f1668b50a0611edb5ecceeb67bbcc45709a7bf3 Mon Sep 17 00:00:00 2001 From: tyfkda Date: Mon, 1 Jul 2024 09:55:32 +0900 Subject: [PATCH] LDRB, STRB, etc. --- src/as/arch/aarch64/aarch64_code.h | 10 ++-------- src/as/arch/aarch64/asm_code.c | 27 +++++++++++++++++---------- 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/src/as/arch/aarch64/aarch64_code.h b/src/as/arch/aarch64/aarch64_code.h index 37db4c976..ccbab7f65 100644 --- a/src/as/arch/aarch64/aarch64_code.h +++ b/src/as/arch/aarch64/aarch64_code.h @@ -41,14 +41,8 @@ #define W_LDP(sz, rs1, rs2, ofs, base, prepost) MAKE_CODE32(inst, code, 0x28400000U | ((sz) << 31) | ((prepost) << 23) | (((((ofs) >> 3) & ((1U << 7) - 1))) << 15) | ((rs2) << 10) | ((base) << 5) | (rs1)) #define W_STP(sz, rs1, rs2, ofs, base, prepost) MAKE_CODE32(inst, code, 0x28000000U | ((sz) << 31) | ((prepost) << 23) | (((((ofs) >> 3) & ((1U << 7) - 1))) << 15) | ((rs2) << 10) | ((base) << 5) | (rs1)) -#define W_LDR_R(sz, rt, base, rm, sz2, s, option) MAKE_CODE32(inst, code, 0xb8600800U | ((sz) << 30) | ((rm) << 16) | ((option) << 13) | ((s) << 12) | ((base) << 5) | (rt)) -#define W_LDRB_R(rt, base, rm, option) MAKE_CODE32(inst, code, 0x38400000U | ((((ofs) & ((1U << 9) - 1))) << 12) | ((option) << 10) | ((base) << 5) | (rt)) -#define W_LDRSB_R(rt, base, rm, option) MAKE_CODE32(inst, code, 0x38c00000U | ((((ofs) & ((1U << 9) - 1))) << 12) | ((option) << 10) | ((base) << 5) | (rt)) -#define W_LDRH_R(rt, base, rm, option) MAKE_CODE32(inst, code, 0x78400000U | ((((ofs) & ((1U << 9) - 1))) << 12) | ((option) << 10) | ((base) << 5) | (rt)) -#define W_LDRSH_R(rt, base, rm, option) MAKE_CODE32(inst, code, 0x78c00000U | ((((ofs) & ((1U << 9) - 1))) << 12) | ((option) << 10) | ((base) << 5) | (rt)) -#define W_STR_R(sz, rt, base, rm, option) MAKE_CODE32(inst, code, 0xb8200800U | ((sz) << 30) | ((rm) << 16) | ((option) << 13) | ((base) << 5) | (rt)) -#define W_STRB_R(rt, base, rm, option) MAKE_CODE32(inst, code, 0x38000000U | ((((ofs) & ((1U << 9) - 1))) << 12) | ((option) << 10) | ((base) << 5) | (rt)) -#define W_STRH_R(rt, base, rm, option) MAKE_CODE32(inst, code, 0x78000000U | ((((ofs) & ((1U << 9) - 1))) << 12) | ((option) << 10) | ((base) << 5) | (rt)) +#define W_LDR_R(sz, rt, base, rm, s, option) MAKE_CODE32(inst, code, 0x38600800U | ((sz) << 30) | ((rm) << 16) | ((option) << 13) | ((s) << 12) | ((base) << 5) | (rt)) +#define W_STR_R(sz, rt, base, rm, option) MAKE_CODE32(inst, code, 0x38200800U | ((sz) << 30) | ((rm) << 16) | ((option) << 13) | ((base) << 5) | (rt)) #define W_ADRP(rd, imm) MAKE_CODE32(inst, code, 0x90000000U | (IMM(imm, 31, 30) << 29) | (IMM(imm, 29, 12) << 5) | (rd)) diff --git a/src/as/arch/aarch64/asm_code.c b/src/as/arch/aarch64/asm_code.c index 53a7355bc..38eadd6b7 100644 --- a/src/as/arch/aarch64/asm_code.c +++ b/src/as/arch/aarch64/asm_code.c @@ -292,17 +292,24 @@ static unsigned char *asm_ldrstr(Inst *inst, Code *code) { static const uint32_t opts[] = {3, 6, 2, 3, 3}; uint32_t opt = opts[opr2->register_offset.extend]; - uint32_t s = opr2->register_offset.extend > 0 ? 1 : 0; switch (inst->op) { - case LDR: W_LDR_R(sz, opr1->reg.no, opr2->register_offset.base_reg.no, opr2->register_offset.index_reg.no, sz2, s, opt); break; - // case LDRB: W_LDRB_R(opr1->reg.no, opr2->register_offset.base_reg.no, opr2->register_offset.index_reg.no, opr2->register_offset.extend); break; - // case LDRSB: W_LDRSB_R(opr1->reg.no, opr2->register_offset.base_reg.no, opr2->register_offset.index_reg.no, opr2->register_offset.extend); break; - // case LDRH: W_LDRH_R(opr1->reg.no, opr2->register_offset.base_reg.no, opr2->register_offset.index_reg.no, opr2->register_offset.extend); break; - // case LDRSH: W_LDRSH_R(opr1->reg.no, opr2->register_offset.base_reg.no, opr2->register_offset.index_reg.no, opr2->register_offset.extend); break; - case STR: W_STR_R(sz, opr1->reg.no, opr2->register_offset.base_reg.no, opr2->register_offset.index_reg.no, opt); break; - // case STRB: W_STRB_R(opr1->reg.no, opr2->register_offset.base_reg.no, opr2->register_offset.index_reg.no, opr2->register_offset.extend); break; - // case STRH: W_STRH_R(opr1->reg.no, opr2->register_offset.base_reg.no, opr2->register_offset.index_reg.no, opr2->register_offset.extend); break; + case LDRB: case LDRH: case LDR: + case LDRSB: case LDRSH: + { + uint32_t b = inst->op - LDRB, s = 0; + if (b >= 3) { + b -= 3; + s = 1; + } + b |= sz; + + W_LDR_R(b, opr1->reg.no, opr2->register_offset.base_reg.no, opr2->register_offset.index_reg.no, s, opt); + } + break; + case STRB: case STRH: case STR: + W_STR_R((inst->op - STRB) | sz, opr1->reg.no, opr2->register_offset.base_reg.no, opr2->register_offset.index_reg.no, opt); + break; default: assert(false); break; } return code->buf; @@ -442,7 +449,7 @@ static unsigned char *asm_f_ldrstr(Inst *inst, Code *code) { uint32_t s = opr2->register_offset.extend > 0 ? 1 : 0; switch (inst->op) { - case LDR: W_LDR_R(sz, opr1->reg.no, opr2->register_offset.base_reg.no, opr2->register_offset.index_reg.no, sz2, s, opt); break; + case LDR: W_LDR_R(sz, opr1->reg.no, opr2->register_offset.base_reg.no, opr2->register_offset.index_reg.no, s, opt); break; case STR: W_STR_R(sz, opr1->reg.no, opr2->register_offset.base_reg.no, opr2->register_offset.index_reg.no, opt); break; default: assert(false); break; }