diff --git a/src/Arch/OpenRISC/Aeon/AeonDisassembler.cs b/src/Arch/OpenRISC/Aeon/AeonDisassembler.cs index f4913602e4..63a0cf4804 100644 --- a/src/Arch/OpenRISC/Aeon/AeonDisassembler.cs +++ b/src/Arch/OpenRISC/Aeon/AeonDisassembler.cs @@ -563,7 +563,7 @@ private static Decoder Create24bitI // branch if reg == imm Instr(Mnemonic.bn_beqi__, InstrClass.ConditionalTransfer, R13, simm10_3, disp2_8), // guess Instr(Mnemonic.bn_bf, InstrClass.ConditionalTransfer, disp2_16), // chenxing(mod), source - Instr(Mnemonic.bn_bnei__, InstrClass.ConditionalTransfer, R13, uimm10_3, disp2_8), + Instr(Mnemonic.bn_bnei__, InstrClass.ConditionalTransfer, R13, simm10_3, disp2_8), Instr(Mnemonic.bn_bnf__, InstrClass.ConditionalTransfer, disp2_16)); var decode001001 = Mask(0, 2, " 9", diff --git a/src/Arch/OpenRISC/Aeon/Assembler/AeonAssembler.cs b/src/Arch/OpenRISC/Aeon/Assembler/AeonAssembler.cs index e4a55b3324..ec580b6f9e 100644 --- a/src/Arch/OpenRISC/Aeon/Assembler/AeonAssembler.cs +++ b/src/Arch/OpenRISC/Aeon/Assembler/AeonAssembler.cs @@ -140,7 +140,7 @@ public void bn_bnei(RegisterStorage reg, ParsedOperand imm, ParsedOperand displa { var opcode = (0b001000u << 18) | 0b10; opcode |= R(reg, 13); - opcode |= U(imm, 10, 3); + opcode |= S(imm, 10, 3); opcode |= S(displacement, 2, 8); EmitUInt24(opcode); } diff --git a/src/Arch/OpenRISC/Aeon/Assembler/AeonTextAssembler.cs b/src/Arch/OpenRISC/Aeon/Assembler/AeonTextAssembler.cs index 0c955d7156..9c68350608 100644 --- a/src/Arch/OpenRISC/Aeon/Assembler/AeonTextAssembler.cs +++ b/src/Arch/OpenRISC/Aeon/Assembler/AeonTextAssembler.cs @@ -118,7 +118,7 @@ private void ProcessLine(CDirectiveLexer lex, AeonAssembler asm) R_R_UImm(lex, asm, 0, AeonAssembler.RT_AEON_BG_LO16_0, asm.bg_andi); break; case "beqi": - R_I_Disp(lex, asm, AeonAssembler.RT_AEON_BG_DISP13_3, asm.bg_beqi); + R_UImm_Disp(lex, asm, AeonAssembler.RT_AEON_BG_DISP13_3, asm.bg_beqi); break; case "sb": M_R(lex, asm, PrimitiveType.Byte, AeonAssembler.RT_AEON_BG_LO16_0, asm.bg_sb); @@ -143,7 +143,7 @@ private void ProcessLine(CDirectiveLexer lex, AeonAssembler asm) switch (mnemonic) { case "bnei": - R_I_Disp(lex, asm, AeonAssembler.RT_AEON_BN_DISP8_2, asm.bn_bnei); + R_SImm_Disp(lex, asm, AeonAssembler.RT_AEON_BN_DISP8_2, asm.bn_bnei); break; case "j": Disp(lex, asm, AeonAssembler.RT_AEON_BN_DISP18, asm.bn_j); @@ -335,7 +335,7 @@ private void Disp( assemble(disp); } - private void R_I_Disp( + private void R_UImm_Disp( CDirectiveLexer lex, AeonAssembler asm, int relocationType, @@ -349,6 +349,20 @@ private void R_I_Disp( assemble(rsrc1, immop, disp); } + private void R_SImm_Disp( + CDirectiveLexer lex, + AeonAssembler asm, + int relocationType, + Action assemble) + { + var rsrc1 = ExpectRegister(lex); + Expect(lex, CTokenType.Comma); + var immop = ParseSImmediateOperand(lex); + Expect(lex, CTokenType.Comma); + var disp = ParseDisplacement(lex, asm, relocationType); + assemble(rsrc1, immop, disp); + } + private bool PeekAndDiscard(CDirectiveLexer lex, CTokenType tokenType) { var t = Peek(lex); diff --git a/src/UnitTests/Arch/OpenRISC/AeonAssemblerTests.cs b/src/UnitTests/Arch/OpenRISC/AeonAssemblerTests.cs index b4e2437f4f..fbb095ba50 100644 --- a/src/UnitTests/Arch/OpenRISC/AeonAssemblerTests.cs +++ b/src/UnitTests/Arch/OpenRISC/AeonAssemblerTests.cs @@ -119,6 +119,12 @@ public void AeonAsm_bn_bnei() AssertAsm("bn.bnei\tr6,0x0,0x00100017", "20 C0 5E"); } + [Test] + public void AeonAsm_bn_bnei_signed() + { + AssertAsm("bn.bnei\tr13,-1,0x00FFFFE0", "21 BF 82"); + } + [Test] public void AeonAsm_bn_j() { diff --git a/src/UnitTests/Arch/OpenRISC/AeonRewriterTests.cs b/src/UnitTests/Arch/OpenRISC/AeonRewriterTests.cs index 85875619c0..444a1a0bb3 100644 --- a/src/UnitTests/Arch/OpenRISC/AeonRewriterTests.cs +++ b/src/UnitTests/Arch/OpenRISC/AeonRewriterTests.cs @@ -324,7 +324,7 @@ public void AeonRw_bn_bnei__() Given_HexString("21 4D B6"); AssertCode( // bn.bnei? r10,0x3,0010006D "0|T--|00100000(3): 1 instructions", - "1|T--|if (r10 != 3<32>) branch 0010006D"); + "1|T--|if (r10 != 3) branch 0010006D"); } [Test]