From 418d20ea9b3aa357a9de0c92c925d015a7d7f85a Mon Sep 17 00:00:00 2001 From: Yu-En Hsiao Date: Sun, 24 Nov 2024 11:44:15 +0800 Subject: [PATCH] Refine code generation for address-of operations The instruction sequences of address-of and global address-of operations are similar but differ only in the register used for certain instructions. The situation occurs for ARM and RISC-V backends. Thus, this commit adjusts the backend implementation to reuse a unified code path when generating instructions for 'address of' operations. --- src/arm-codegen.c | 13 ++++--------- src/riscv-codegen.c | 15 +++++---------- 2 files changed, 9 insertions(+), 19 deletions(-) diff --git a/src/arm-codegen.c b/src/arm-codegen.c index 808eb6e8..58359619 100644 --- a/src/arm-codegen.c +++ b/src/arm-codegen.c @@ -197,6 +197,7 @@ void emit_ph2_ir(ph2_ir_t *ph2_ir) * the instruction sequence of * 1. division and modulo. * 2. load and store operations. + * 3. address-of operations. */ arm_reg interm; @@ -219,20 +220,14 @@ void emit_ph2_ir(ph2_ir_t *ph2_ir) emit(__mov_i(__AL, rd, ph2_ir->src0)); return; case OP_address_of: - if (ph2_ir->src0 > 255) { - emit(__movw(__AL, __r8, ph2_ir->src0)); - emit(__movt(__AL, __r8, ph2_ir->src0)); - emit(__add_r(__AL, rd, __sp, __r8)); - } else - emit(__add_i(__AL, rd, __sp, ph2_ir->src0)); - return; case OP_global_address_of: + interm = ph2_ir->op == OP_address_of ? __sp : __r12; if (ph2_ir->src0 > 255) { emit(__movw(__AL, __r8, ph2_ir->src0)); emit(__movt(__AL, __r8, ph2_ir->src0)); - emit(__add_r(__AL, rd, __r12, __r8)); + emit(__add_r(__AL, rd, interm, __r8)); } else - emit(__add_i(__AL, rd, __r12, ph2_ir->src0)); + emit(__add_i(__AL, rd, interm, ph2_ir->src0)); return; case OP_assign: emit(__mov_r(__AL, rd, rn)); diff --git a/src/riscv-codegen.c b/src/riscv-codegen.c index ad3db9f4..92329dfa 100644 --- a/src/riscv-codegen.c +++ b/src/riscv-codegen.c @@ -161,6 +161,7 @@ void emit_ph2_ir(ph2_ir_t *ph2_ir) * the instruction sequence of * 1. division and modulo. * 2. load and store operations. + * 3. address-of operations. */ rv_reg interm, divisor_mask = __t1; @@ -179,21 +180,15 @@ void emit_ph2_ir(ph2_ir_t *ph2_ir) } else emit(__addi(rd, __zero, ph2_ir->src0)); return; - case OP_global_address_of: - if (ph2_ir->src0 < -2048 || ph2_ir->src0 > 2047) { - emit(__lui(__t0, rv_hi(ph2_ir->src0))); - emit(__addi(__t0, __t0, rv_lo(ph2_ir->src0))); - emit(__add(rd, __gp, __t0)); - } else - emit(__addi(rd, __gp, ph2_ir->src0)); - return; case OP_address_of: + case OP_global_address_of: + interm = ph2_ir->op == OP_address_of ? __sp : __gp; if (ph2_ir->src0 < -2048 || ph2_ir->src0 > 2047) { emit(__lui(__t0, rv_hi(ph2_ir->src0))); emit(__addi(__t0, __t0, rv_lo(ph2_ir->src0))); - emit(__add(rd, __sp, __t0)); + emit(__add(rd, interm, __t0)); } else - emit(__addi(rd, __sp, ph2_ir->src0)); + emit(__addi(rd, interm, ph2_ir->src0)); return; case OP_assign: emit(__addi(rd, rs1, 0));