arm64-asm.c: consolidate near-identical code generation functions

Three pairs of functions differed only in base opcode constants:
- gen_movz/gen_movn/gen_movk (34 lines → 17 lines core + 9 lines wrappers)
- gen_b/gen_bl (14 lines → 8 lines core + 6 lines wrappers)
- gen_cbz/gen_cbnz (18 lines → 10 lines core + 8 lines wrappers)

Consolidated each into a single core function with base_opcode parameter:
- gen_mov_with_base() - handles MOVZ, MOVN, MOVK
- gen_b_or_bl() - handles B, BL
- gen_cbz_or_cbnz() - handles CBZ, CBNZ

Original functions retained as thin wrappers for backward compatibility.

Net reduction: 20 lines (66 → 46), eliminates code duplication hazard.
This commit is contained in:
Benjamin Oldenburg 2026-03-20 19:01:22 +07:00
parent 1f60eb4574
commit 3f26af7b4c

View File

@ -310,9 +310,11 @@ static void parse_addr_operand(TCCState *s1, Operand *op)
} }
/* Generate MOVZ instruction */ /* Generate MOVZ instruction */
static void gen_movz(int rd, uint16_t imm, int shift, int is_64bit) /* Generate MOVZ/MOVN/MOVK with base opcode */
static void gen_mov_with_base(int rd, uint16_t imm, int shift,
int is_64bit, uint32_t base_opcode)
{ {
uint32_t instr = 0x52800000; uint32_t instr = base_opcode;
if (is_64bit) instr |= (1 << 31); if (is_64bit) instr |= (1 << 31);
/* shift is halfword index (0-3), encode as LSL #0/16/32/48 */ /* shift is halfword index (0-3), encode as LSL #0/16/32/48 */
instr |= ((shift & 3) << 21) & 0x00600000; instr |= ((shift & 3) << 21) & 0x00600000;
@ -321,28 +323,21 @@ static void gen_movz(int rd, uint16_t imm, int shift, int is_64bit)
emit_instr32(instr); emit_instr32(instr);
} }
static void gen_movz(int rd, uint16_t imm, int shift, int is_64bit)
{
gen_mov_with_base(rd, imm, shift, is_64bit, 0x52800000);
}
/* Generate MOVN instruction */ /* Generate MOVN instruction */
static void gen_movn(int rd, uint16_t imm, int shift, int is_64bit) static void gen_movn(int rd, uint16_t imm, int shift, int is_64bit)
{ {
uint32_t instr = 0x12800000; gen_mov_with_base(rd, imm, shift, is_64bit, 0x12800000);
if (is_64bit) instr |= (1 << 31);
/* shift is halfword index (0-3), encode as LSL #0/16/32/48 */
instr |= ((shift & 3) << 21) & 0x00600000;
instr |= (imm << 5) & 0x00FFFFE0;
instr |= rd & 0x1F;
emit_instr32(instr);
} }
/* Generate MOVK instruction */ /* Generate MOVK instruction */
static void gen_movk(int rd, uint16_t imm, int shift, int is_64bit) static void gen_movk(int rd, uint16_t imm, int shift, int is_64bit)
{ {
uint32_t instr = 0xF2800000; gen_mov_with_base(rd, imm, shift, is_64bit, 0xF2800000);
if (is_64bit) instr |= (1 << 31);
/* shift is halfword index (0-3), encode as LSL #0/16/32/48 */
instr |= ((shift & 3) << 21) & 0x00600000;
instr |= (imm << 5) & 0x00FFFFE0;
instr |= rd & 0x1F;
emit_instr32(instr);
} }
/* Generate ADD (immediate) */ /* Generate ADD (immediate) */
@ -445,19 +440,23 @@ static void gen_ldst_pair(uint32_t base_opcode, int rt, int rt2, int rn,
} }
/* Generate B (branch) */ /* Generate B (branch) */
static void gen_b(int32_t offset) /* Generate B/BL with base opcode */
static void gen_b_or_bl(int32_t offset, uint32_t base_opcode)
{ {
uint32_t instr = 0x14000000; uint32_t instr = base_opcode;
instr |= ((offset >> 2) & 0x03FFFFFF); instr |= ((offset >> 2) & 0x03FFFFFF);
emit_instr32(instr); emit_instr32(instr);
} }
static void gen_b(int32_t offset)
{
gen_b_or_bl(offset, 0x14000000);
}
/* Generate BL (branch with link) */ /* Generate BL (branch with link) */
static void gen_bl(int32_t offset) static void gen_bl(int32_t offset)
{ {
uint32_t instr = 0x94000000; gen_b_or_bl(offset, 0x94000000);
instr |= ((offset >> 2) & 0x03FFFFFF);
emit_instr32(instr);
} }
/* Generate BR (branch to register) */ /* Generate BR (branch to register) */
@ -494,23 +493,25 @@ static void gen_b_cond(int cond, int32_t offset)
} }
/* Generate CBZ */ /* Generate CBZ */
static void gen_cbz(int rt, int32_t offset, int is_64bit) /* Generate CBZ/CBNZ with base opcode */
static void gen_cbz_or_cbnz(int rt, int32_t offset, int is_64bit, uint32_t base_opcode)
{ {
uint32_t instr = 0x34000000; uint32_t instr = base_opcode;
if (is_64bit) instr |= (1 << 31); if (is_64bit) instr |= (1 << 31);
instr |= ((offset >> 2) & 0x7FFFF) << 5; instr |= ((offset >> 2) & 0x7FFFF) << 5;
instr |= rt & 0x1F; instr |= rt & 0x1F;
emit_instr32(instr); emit_instr32(instr);
} }
static void gen_cbz(int rt, int32_t offset, int is_64bit)
{
gen_cbz_or_cbnz(rt, offset, is_64bit, 0x34000000);
}
/* Generate CBNZ */ /* Generate CBNZ */
static void gen_cbnz(int rt, int32_t offset, int is_64bit) static void gen_cbnz(int rt, int32_t offset, int is_64bit)
{ {
uint32_t instr = 0x35000000; gen_cbz_or_cbnz(rt, offset, is_64bit, 0x35000000);
if (is_64bit) instr |= (1 << 31);
instr |= ((offset >> 2) & 0x7FFFF) << 5;
instr |= rt & 0x1F;
emit_instr32(instr);
} }
/* Generate MOV (register) - ORR with zero register */ /* Generate MOV (register) - ORR with zero register */