Skip to content

Commit 0684f41

Browse files
committed
Enhance code reusability for the compiler backends
After observing ARM and RISC-V backends, the instruction sequences of load and global load operations are very similar, and both of them just use a different register for two instructions. A similar situation occurs for store and global store operations. Therefore, this commit improves the compiler backends to reuse the same code more efficiently.
1 parent 487d8ec commit 0684f41

File tree

2 files changed

+28
-50
lines changed

2 files changed

+28
-50
lines changed

Diff for: src/arm-codegen.c

+14-25
Original file line numberDiff line numberDiff line change
@@ -194,9 +194,11 @@ void emit_ph2_ir(ph2_ir_t *ph2_ir)
194194
int ofs;
195195

196196
/* Prepare this variable to reuse the same code for
197-
* the instruction sequence of division and modulo.
197+
* the instruction sequence of
198+
* 1. division and modulo.
199+
* 2. load and store operations.
198200
*/
199-
arm_reg soft_div_rd = __r8;
201+
arm_reg interm;
200202

201203
switch (ph2_ir->op) {
202204
case OP_define:
@@ -236,40 +238,26 @@ void emit_ph2_ir(ph2_ir_t *ph2_ir)
236238
emit(__mov_r(__AL, rd, rn));
237239
return;
238240
case OP_load:
239-
if (ph2_ir->src0 > 4095) {
240-
emit(__movw(__AL, __r8, ph2_ir->src0));
241-
emit(__movt(__AL, __r8, ph2_ir->src0));
242-
emit(__add_r(__AL, __r8, __sp, __r8));
243-
emit(__lw(__AL, rd, __r8, 0));
244-
} else
245-
emit(__lw(__AL, rd, __sp, ph2_ir->src0));
246-
return;
247-
case OP_store:
248-
if (ph2_ir->src1 > 4095) {
249-
emit(__movw(__AL, __r8, ph2_ir->src1));
250-
emit(__movt(__AL, __r8, ph2_ir->src1));
251-
emit(__add_r(__AL, __r8, __sp, __r8));
252-
emit(__sw(__AL, rn, __r8, 0));
253-
} else
254-
emit(__sw(__AL, rn, __sp, ph2_ir->src1));
255-
return;
256241
case OP_global_load:
242+
interm = ph2_ir->op == OP_load ? __sp : __r12;
257243
if (ph2_ir->src0 > 4095) {
258244
emit(__movw(__AL, __r8, ph2_ir->src0));
259245
emit(__movt(__AL, __r8, ph2_ir->src0));
260-
emit(__add_r(__AL, __r8, __r12, __r8));
246+
emit(__add_r(__AL, __r8, interm, __r8));
261247
emit(__lw(__AL, rd, __r8, 0));
262248
} else
263-
emit(__lw(__AL, rd, __r12, ph2_ir->src0));
249+
emit(__lw(__AL, rd, interm, ph2_ir->src0));
264250
return;
251+
case OP_store:
265252
case OP_global_store:
253+
interm = ph2_ir->op == OP_store ? __sp : __r12;
266254
if (ph2_ir->src1 > 4095) {
267255
emit(__movw(__AL, __r8, ph2_ir->src1));
268256
emit(__movt(__AL, __r8, ph2_ir->src1));
269-
emit(__add_r(__AL, __r8, __r12, __r8));
257+
emit(__add_r(__AL, __r8, interm, __r8));
270258
emit(__sw(__AL, rn, __r8, 0));
271259
} else
272-
emit(__sw(__AL, rn, __r12, ph2_ir->src1));
260+
emit(__sw(__AL, rn, interm, ph2_ir->src1));
273261
return;
274262
case OP_read:
275263
if (ph2_ir->src1 == 1)
@@ -351,6 +339,7 @@ void emit_ph2_ir(ph2_ir_t *ph2_ir)
351339
}
352340
return;
353341
}
342+
interm = __r8;
354343
/* div/mod emulation */
355344
/* Preserve the values of the dividend and divisor */
356345
emit(__stmdb(__AL, 1, __sp, (1 << rn) | (1 << rm)));
@@ -368,7 +357,7 @@ void emit_ph2_ir(ph2_ir_t *ph2_ir)
368357
* in __r9. The sign of the divisor is irrelevant for determining
369358
* the result's sign.
370359
*/
371-
soft_div_rd = __r9;
360+
interm = __r9;
372361
emit(__mov_r(__AL, __r10, __r8));
373362
}
374363
/* Unsigned integer division */
@@ -399,7 +388,7 @@ void emit_ph2_ir(ph2_ir_t *ph2_ir)
399388
*/
400389
emit(__mov_r(__AL, __r9, rn));
401390
emit(__ldm(__AL, 1, __sp, (1 << rn) | (1 << rm)));
402-
emit(__mov_r(__AL, rd, soft_div_rd));
391+
emit(__mov_r(__AL, rd, interm));
403392
/* Handle the correct sign for the quotient or remainder */
404393
emit(__cmp_i(__AL, __r10, 0));
405394
emit(__rsb_i(__NE, rd, 0, rd));

Diff for: src/riscv-codegen.c

+14-25
Original file line numberDiff line numberDiff line change
@@ -158,9 +158,11 @@ void emit_ph2_ir(ph2_ir_t *ph2_ir)
158158
int ofs;
159159

160160
/* Prepare the variables to reuse the same code for
161-
* the instruction sequence of division and modulo.
161+
* the instruction sequence of
162+
* 1. division and modulo.
163+
* 2. load and store operations.
162164
*/
163-
rv_reg soft_div_rd = __t0, divisor_mask = __t1;
165+
rv_reg interm, divisor_mask = __t1;
164166

165167
switch (ph2_ir->op) {
166168
case OP_define:
@@ -197,40 +199,26 @@ void emit_ph2_ir(ph2_ir_t *ph2_ir)
197199
emit(__addi(rd, rs1, 0));
198200
return;
199201
case OP_load:
200-
if (ph2_ir->src0 < -2048 || ph2_ir->src0 > 2047) {
201-
emit(__lui(__t0, rv_hi(ph2_ir->src0)));
202-
emit(__addi(__t0, __t0, rv_lo(ph2_ir->src0)));
203-
emit(__add(__t0, __sp, __t0));
204-
emit(__lw(rd, __t0, 0));
205-
} else
206-
emit(__lw(rd, __sp, ph2_ir->src0));
207-
return;
208-
case OP_store:
209-
if (ph2_ir->src1 < -2048 || ph2_ir->src1 > 2047) {
210-
emit(__lui(__t0, rv_hi(ph2_ir->src1)));
211-
emit(__addi(__t0, __t0, rv_lo(ph2_ir->src1)));
212-
emit(__add(__t0, __sp, __t0));
213-
emit(__sw(rs1, __t0, 0));
214-
} else
215-
emit(__sw(rs1, __sp, ph2_ir->src1));
216-
return;
217202
case OP_global_load:
203+
interm = ph2_ir->op == OP_load ? __sp : __gp;
218204
if (ph2_ir->src0 < -2048 || ph2_ir->src0 > 2047) {
219205
emit(__lui(__t0, rv_hi(ph2_ir->src0)));
220206
emit(__addi(__t0, __t0, rv_lo(ph2_ir->src0)));
221-
emit(__add(__t0, __gp, __t0));
207+
emit(__add(__t0, interm, __t0));
222208
emit(__lw(rd, __t0, 0));
223209
} else
224-
emit(__lw(rd, __gp, ph2_ir->src0));
210+
emit(__lw(rd, interm, ph2_ir->src0));
225211
return;
212+
case OP_store:
226213
case OP_global_store:
214+
interm = ph2_ir->op == OP_store ? __sp : __gp;
227215
if (ph2_ir->src1 < -2048 || ph2_ir->src1 > 2047) {
228216
emit(__lui(__t0, rv_hi(ph2_ir->src1)));
229217
emit(__addi(__t0, __t0, rv_lo(ph2_ir->src1)));
230-
emit(__add(__t0, __gp, __t0));
218+
emit(__add(__t0, interm, __t0));
231219
emit(__sw(rs1, __t0, 0));
232220
} else
233-
emit(__sw(rs1, __gp, ph2_ir->src1));
221+
emit(__sw(rs1, interm, ph2_ir->src1));
234222
return;
235223
case OP_read:
236224
if (ph2_ir->src1 == 1)
@@ -325,13 +313,14 @@ void emit_ph2_ir(ph2_ir_t *ph2_ir)
325313
emit(__mod(rd, rs1, rs2));
326314
return;
327315
}
316+
interm = __t0;
328317
/* div/mod emulation */
329318
if (ph2_ir->op == OP_mod) {
330319
/* If the requested operation is modulo, the result will be stored
331320
* in __t2. The sign of the divisor is irrelevant for determining
332321
* the result's sign.
333322
*/
334-
soft_div_rd = __t2;
323+
interm = __t2;
335324
divisor_mask = __zero;
336325
}
337326
/* Obtain absolute values of the dividend and divisor */
@@ -359,7 +348,7 @@ void emit_ph2_ir(ph2_ir_t *ph2_ir)
359348
emit(__srli(__t1, __t1, 1));
360349
emit(__srli(__t3, __t3, 1));
361350
emit(__bne(__t1, __zero, -20));
362-
emit(__addi(rd, soft_div_rd, 0));
351+
emit(__addi(rd, interm, 0));
363352
/* Handle the correct sign for the quotient or remainder */
364353
emit(__beq(__t5, __zero, 8));
365354
emit(__sub(rd, __zero, rd));

0 commit comments

Comments
 (0)