Skip to content

Commit acf4f9b

Browse files
committed
Fix RISC-V sign extension and parser type size handling
- Fix OP_sign_ext in parser to use source type size instead of target type size - Improve RISC-V 16-bit sign extension to use shift-only approach, avoiding immediate field overflow with 0xFFFF value - Consolidate RISC-V sign extension fallback cases for better code reusability
1 parent c6075a6 commit acf4f9b

File tree

2 files changed

+20
-16
lines changed

2 files changed

+20
-16
lines changed

src/parser.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,8 +247,12 @@ var_t *promote_unchecked(block_t *block,
247247
{
248248
var_t *rd = require_typed_ptr_var(block, target_type, target_ptr);
249249
gen_name_to(rd->var_name);
250+
/* TODO: Use source type size instead of target type size for
251+
* sign extension. The OP_sign_ext instruction may need both
252+
* source and target sizes for proper code generation.
253+
*/
250254
add_insn(block, *bb, OP_sign_ext, rd, var, NULL,
251-
target_ptr ? PTR_SIZE : target_type->size, NULL);
255+
target_ptr ? PTR_SIZE : var->type->size, NULL);
252256
return rd;
253257
}
254258

src/riscv-codegen.c

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,10 @@ void update_elf_offset(ph2_ir_t *ph2_ir)
101101
elf_offset += 4;
102102
return;
103103
case OP_sign_ext:
104-
elf_offset += 12;
104+
if (ph2_ir->src1 == 2)
105+
elf_offset += 8;
106+
else
107+
elf_offset += 12;
105108
return;
106109
case OP_cast:
107110
elf_offset += 4;
@@ -441,22 +444,19 @@ void emit_ph2_ir(ph2_ir_t *ph2_ir)
441444
}
442445
return;
443446
case OP_sign_ext:
444-
if (ph2_ir->src1 == 1) {
445-
/* Sign extend from byte to word */
446-
rs2 = 0xFF;
447-
ofs = 24;
448-
} else if (ph2_ir->src1 == 2) {
449-
/* Sign extend from short to word */
450-
rs2 = 0xFFFF;
451-
ofs = 16;
447+
if (ph2_ir->src1 == 2) {
448+
/* Sign extend from short to word
449+
* For 16-bit sign extension, use only shift operations
450+
* since 0xFFFF is too large for RISC-V immediate field
451+
*/
452+
emit(__slli(rd, rs1, 16));
453+
emit(__srai(rd, rd, 16));
452454
} else {
453-
/* Fallback to original behavior for unknown sizes */
454-
rs2 = 0xFF;
455-
ofs = 24;
455+
/* Sign extend from byte to word (src1 == 1) or fallback */
456+
emit(__andi(rd, rs1, 0xFF));
457+
emit(__slli(rd, rd, 24));
458+
emit(__srai(rd, rd, 24));
456459
}
457-
emit(__andi(rd, rs1, rs2));
458-
emit(__slli(rd, rd, ofs));
459-
emit(__srai(rd, rd, ofs));
460460
return;
461461
case OP_cast:
462462
/* Generic cast operation - for now, just move the value */

0 commit comments

Comments
 (0)