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.
This commit is contained in:
Meng Zhuo 2026-05-03 00:09:53 +08:00
parent ff917c09aa
commit 366569eb7a

View File

@ -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 */