From 366569eb7aaee8b6e7d94e705033657782e3a14d Mon Sep 17 00:00:00 2001 From: Meng Zhuo Date: Sun, 3 May 2026 00:09:53 +0800 Subject: [PATCH] riscv64-asm: fix neg/negw pseudo-instruction encoding neg/negw were incorrectly using asm_emit_i (I-type/xori) with an immediate of 1, producing 'xori rd, rs, 1' instead of the intended 'sub rd, x0, rs'. Fixed to use asm_emit_r (R-type) with proper SUB/SUBW opcode (0x33/0x3B, func3=0, func7=0x20). The old code generated wrong machine code for these pseudo-instructions. negw now also correctly uses OP-32 (0x3B) for 32-bit subtraction. --- riscv64-asm.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/riscv64-asm.c b/riscv64-asm.c index 63aa468e..e15e8068 100644 --- a/riscv64-asm.c +++ b/riscv64-asm.c @@ -678,14 +678,12 @@ static void asm_binary_opcode(TCCState* s1, int token) asm_emit_i(token, (0x4 << 2) | 3 | (4 << 12), &ops[0], &ops[1], &imm); return; case TOK_ASM_neg: - /* sub rd, x0, rs */ - imm.e.v = 1; - asm_emit_i(token, (0x4 << 2) | 3 | (4 << 12), &ops[0], &zero, &imm); + /* sub rd, x0, rs2 */ + asm_emit_r(token, (0xC << 2) | 3 | (32 << 25), &ops[0], &zero, &ops[1]); return; case TOK_ASM_negw: - /* sub rd, x0, rs */ - imm.e.v = 1; - asm_emit_i(token, (0x4 << 2) | 3 | (4 << 12), &ops[0], &zero, &imm); + /* subw rd, x0, rs2 */ + asm_emit_r(token, (0xE << 2) | 3 | (32 << 25), &ops[0], &zero, &ops[1]); return; case TOK_ASM_jump: /* auipc x5, 0 */