Skip to content

Commit 6f72fb8

Browse files
committed
Implement RISC-V short type code generation
Add RISC-V halfword instruction support for short data type operations with proper truncation and sign extension. - Fix OP_trunc for short types using shift operations instead of large immediate values that exceed instruction limits - Implement OP_sign_ext for short-to-int sign extension using arithmetic shift operations - Update halfword operations to handle 2-byte reads correctly RISC-V short type operations now generate correct instruction sequences with proper bit manipulation and sign extension.
1 parent 6ce385f commit 6f72fb8

File tree

1 file changed

+37
-15
lines changed

1 file changed

+37
-15
lines changed

src/riscv-codegen.c

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,10 @@ void update_elf_offset(ph2_ir_t *ph2_ir)
9595
elf_offset += 24;
9696
return;
9797
case OP_trunc:
98-
elf_offset += 4;
98+
if (ph2_ir->src1 == 2)
99+
elf_offset += 8;
100+
else
101+
elf_offset += 4;
99102
return;
100103
case OP_sign_ext:
101104
elf_offset += 12;
@@ -233,6 +236,8 @@ void emit_ph2_ir(ph2_ir_t *ph2_ir)
233236
case OP_read:
234237
if (ph2_ir->src1 == 1)
235238
emit(__lb(rd, rs1, 0));
239+
else if (ph2_ir->src1 == 2)
240+
emit(__lh(rd, rs1, 0));
236241
else if (ph2_ir->src1 == 4)
237242
emit(__lw(rd, rs1, 0));
238243
else
@@ -241,6 +246,8 @@ void emit_ph2_ir(ph2_ir_t *ph2_ir)
241246
case OP_write:
242247
if (ph2_ir->dest == 1)
243248
emit(__sb(rs2, rs1, 0));
249+
else if (ph2_ir->dest == 2)
250+
emit(__sh(rs2, rs1, 0));
244251
else if (ph2_ir->dest == 4)
245252
emit(__sw(rs2, rs1, 0));
246253
else
@@ -417,24 +424,39 @@ void emit_ph2_ir(ph2_ir_t *ph2_ir)
417424
emit(__xori(rd, rd, 1));
418425
return;
419426
case OP_trunc:
420-
if (ph2_ir->src1 == 1)
427+
if (ph2_ir->src1 == 1) {
421428
rs2 = 0xFF;
422-
else if (ph2_ir->src1 == 2)
423-
rs2 = 0xFFFF;
424-
else if (ph2_ir->src1 == 4)
425-
rs2 = 0xFFFFFFFF;
426-
else
429+
emit(__andi(rd, rs1, rs2));
430+
} else if (ph2_ir->src1 == 2) {
431+
/* For short truncation,
432+
* use shift operations since 0xFFFF is too large
433+
*/
434+
emit(__slli(rd, rs1, 16)); /* Shift left 16 bits */
435+
emit(__srli(rd, rd, 16)); /* Shift right 16 bits logical */
436+
} else if (ph2_ir->src1 == 4) {
437+
/* No truncation needed for 32-bit values */
438+
emit(__add(rd, rs1, __zero));
439+
} else {
427440
fatal("Unsupported truncation operation with invalid target size");
428-
429-
emit(__andi(rd, rs1, rs2));
441+
}
430442
return;
431443
case OP_sign_ext:
432-
/* TODO: Support sign extension to types other than int */
433-
emit(__andi(rd, rs1, 0xFF));
434-
emit(__slli(rd, rd, 24));
435-
emit(__srai(rd, rd, 24));
436-
/* TODO: Consider Zbb extension for improved bit manipulation */
437-
/* emit(__sext_b(rd, rs1)); */
444+
if (ph2_ir->src1 == 1) {
445+
/* Sign extend from byte to word */
446+
emit(__andi(rd, rs1, 0xFF));
447+
emit(__slli(rd, rd, 24));
448+
emit(__srai(rd, rd, 24));
449+
} else if (ph2_ir->src1 == 2) {
450+
/* Sign extend from short to word */
451+
emit(__andi(rd, rs1, 0xFFFF));
452+
emit(__slli(rd, rd, 16)); /* Shift left 16 bits */
453+
emit(__srai(rd, rd, 16)); /* Arithmetic shift right 16 bits */
454+
} else {
455+
/* Fallback to original behavior for unknown sizes */
456+
emit(__andi(rd, rs1, 0xFF));
457+
emit(__slli(rd, rd, 24));
458+
emit(__srai(rd, rd, 24));
459+
}
438460
return;
439461
case OP_cast:
440462
/* Generic cast operation - for now, just move the value */

0 commit comments

Comments
 (0)