Skip to content

Commit

Permalink
Merge pull request #167 from DrXiao/fix-load-store
Browse files Browse the repository at this point in the history
Enhance code reusability for the compiler backends
  • Loading branch information
jserv authored Nov 24, 2024
2 parents 487d8ec + 0684f41 commit a8bc7cf
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 50 deletions.
39 changes: 14 additions & 25 deletions src/arm-codegen.c
Original file line number Diff line number Diff line change
Expand Up @@ -194,9 +194,11 @@ void emit_ph2_ir(ph2_ir_t *ph2_ir)
int ofs;

/* Prepare this variable to reuse the same code for
* the instruction sequence of division and modulo.
* the instruction sequence of
* 1. division and modulo.
* 2. load and store operations.
*/
arm_reg soft_div_rd = __r8;
arm_reg interm;

switch (ph2_ir->op) {
case OP_define:
Expand Down Expand Up @@ -236,40 +238,26 @@ void emit_ph2_ir(ph2_ir_t *ph2_ir)
emit(__mov_r(__AL, rd, rn));
return;
case OP_load:
if (ph2_ir->src0 > 4095) {
emit(__movw(__AL, __r8, ph2_ir->src0));
emit(__movt(__AL, __r8, ph2_ir->src0));
emit(__add_r(__AL, __r8, __sp, __r8));
emit(__lw(__AL, rd, __r8, 0));
} else
emit(__lw(__AL, rd, __sp, ph2_ir->src0));
return;
case OP_store:
if (ph2_ir->src1 > 4095) {
emit(__movw(__AL, __r8, ph2_ir->src1));
emit(__movt(__AL, __r8, ph2_ir->src1));
emit(__add_r(__AL, __r8, __sp, __r8));
emit(__sw(__AL, rn, __r8, 0));
} else
emit(__sw(__AL, rn, __sp, ph2_ir->src1));
return;
case OP_global_load:
interm = ph2_ir->op == OP_load ? __sp : __r12;
if (ph2_ir->src0 > 4095) {
emit(__movw(__AL, __r8, ph2_ir->src0));
emit(__movt(__AL, __r8, ph2_ir->src0));
emit(__add_r(__AL, __r8, __r12, __r8));
emit(__add_r(__AL, __r8, interm, __r8));
emit(__lw(__AL, rd, __r8, 0));
} else
emit(__lw(__AL, rd, __r12, ph2_ir->src0));
emit(__lw(__AL, rd, interm, ph2_ir->src0));
return;
case OP_store:
case OP_global_store:
interm = ph2_ir->op == OP_store ? __sp : __r12;
if (ph2_ir->src1 > 4095) {
emit(__movw(__AL, __r8, ph2_ir->src1));
emit(__movt(__AL, __r8, ph2_ir->src1));
emit(__add_r(__AL, __r8, __r12, __r8));
emit(__add_r(__AL, __r8, interm, __r8));
emit(__sw(__AL, rn, __r8, 0));
} else
emit(__sw(__AL, rn, __r12, ph2_ir->src1));
emit(__sw(__AL, rn, interm, ph2_ir->src1));
return;
case OP_read:
if (ph2_ir->src1 == 1)
Expand Down Expand Up @@ -351,6 +339,7 @@ void emit_ph2_ir(ph2_ir_t *ph2_ir)
}
return;
}
interm = __r8;
/* div/mod emulation */
/* Preserve the values of the dividend and divisor */
emit(__stmdb(__AL, 1, __sp, (1 << rn) | (1 << rm)));
Expand All @@ -368,7 +357,7 @@ void emit_ph2_ir(ph2_ir_t *ph2_ir)
* in __r9. The sign of the divisor is irrelevant for determining
* the result's sign.
*/
soft_div_rd = __r9;
interm = __r9;
emit(__mov_r(__AL, __r10, __r8));
}
/* Unsigned integer division */
Expand Down Expand Up @@ -399,7 +388,7 @@ void emit_ph2_ir(ph2_ir_t *ph2_ir)
*/
emit(__mov_r(__AL, __r9, rn));
emit(__ldm(__AL, 1, __sp, (1 << rn) | (1 << rm)));
emit(__mov_r(__AL, rd, soft_div_rd));
emit(__mov_r(__AL, rd, interm));
/* Handle the correct sign for the quotient or remainder */
emit(__cmp_i(__AL, __r10, 0));
emit(__rsb_i(__NE, rd, 0, rd));
Expand Down
39 changes: 14 additions & 25 deletions src/riscv-codegen.c
Original file line number Diff line number Diff line change
Expand Up @@ -158,9 +158,11 @@ void emit_ph2_ir(ph2_ir_t *ph2_ir)
int ofs;

/* Prepare the variables to reuse the same code for
* the instruction sequence of division and modulo.
* the instruction sequence of
* 1. division and modulo.
* 2. load and store operations.
*/
rv_reg soft_div_rd = __t0, divisor_mask = __t1;
rv_reg interm, divisor_mask = __t1;

switch (ph2_ir->op) {
case OP_define:
Expand Down Expand Up @@ -197,40 +199,26 @@ void emit_ph2_ir(ph2_ir_t *ph2_ir)
emit(__addi(rd, rs1, 0));
return;
case OP_load:
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(__t0, __sp, __t0));
emit(__lw(rd, __t0, 0));
} else
emit(__lw(rd, __sp, ph2_ir->src0));
return;
case OP_store:
if (ph2_ir->src1 < -2048 || ph2_ir->src1 > 2047) {
emit(__lui(__t0, rv_hi(ph2_ir->src1)));
emit(__addi(__t0, __t0, rv_lo(ph2_ir->src1)));
emit(__add(__t0, __sp, __t0));
emit(__sw(rs1, __t0, 0));
} else
emit(__sw(rs1, __sp, ph2_ir->src1));
return;
case OP_global_load:
interm = ph2_ir->op == OP_load ? __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(__t0, __gp, __t0));
emit(__add(__t0, interm, __t0));
emit(__lw(rd, __t0, 0));
} else
emit(__lw(rd, __gp, ph2_ir->src0));
emit(__lw(rd, interm, ph2_ir->src0));
return;
case OP_store:
case OP_global_store:
interm = ph2_ir->op == OP_store ? __sp : __gp;
if (ph2_ir->src1 < -2048 || ph2_ir->src1 > 2047) {
emit(__lui(__t0, rv_hi(ph2_ir->src1)));
emit(__addi(__t0, __t0, rv_lo(ph2_ir->src1)));
emit(__add(__t0, __gp, __t0));
emit(__add(__t0, interm, __t0));
emit(__sw(rs1, __t0, 0));
} else
emit(__sw(rs1, __gp, ph2_ir->src1));
emit(__sw(rs1, interm, ph2_ir->src1));
return;
case OP_read:
if (ph2_ir->src1 == 1)
Expand Down Expand Up @@ -325,13 +313,14 @@ void emit_ph2_ir(ph2_ir_t *ph2_ir)
emit(__mod(rd, rs1, rs2));
return;
}
interm = __t0;
/* div/mod emulation */
if (ph2_ir->op == OP_mod) {
/* If the requested operation is modulo, the result will be stored
* in __t2. The sign of the divisor is irrelevant for determining
* the result's sign.
*/
soft_div_rd = __t2;
interm = __t2;
divisor_mask = __zero;
}
/* Obtain absolute values of the dividend and divisor */
Expand Down Expand Up @@ -359,7 +348,7 @@ void emit_ph2_ir(ph2_ir_t *ph2_ir)
emit(__srli(__t1, __t1, 1));
emit(__srli(__t3, __t3, 1));
emit(__bne(__t1, __zero, -20));
emit(__addi(rd, soft_div_rd, 0));
emit(__addi(rd, interm, 0));
/* Handle the correct sign for the quotient or remainder */
emit(__beq(__t5, __zero, 8));
emit(__sub(rd, __zero, rd));
Expand Down

0 comments on commit a8bc7cf

Please sign in to comment.