]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
gdb: LoongArch: Emulate floating-point branch instructions
authorTiezhu Yang <yangtiezhu@loongson.cn>
Wed, 30 Apr 2025 07:10:15 +0000 (15:10 +0800)
committerTiezhu Yang <yangtiezhu@loongson.cn>
Sat, 10 May 2025 13:25:52 +0000 (21:25 +0800)
Add bceqz and bcnez cases in loongarch_insn_is_cond_branch() and
loongarch_next_pc() to emulate floating-point branch instructions.

Here are the references:

https://loongson.github.io/LoongArch-Documentation/LoongArch-Vol1-EN.html#_bceqz_bcnez
https://loongson.github.io/LoongArch-Documentation/LoongArch-Vol1-EN.html#table-table-of-instruction-encoding

Approved-by: Kevin Buettner <kevinb@redhat.com>
Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn>
gdb/loongarch-tdep.c

index 092127dd81007d7f3fba4fc7f3b33fe022e22901..d79ec686e6a19bf8d7e1a3dd6b0b5f37c1a30360 100644 (file)
@@ -74,7 +74,9 @@ loongarch_insn_is_cond_branch (insn_t insn)
       || (insn & 0xfc000000) == 0x68000000     /* bltu  */
       || (insn & 0xfc000000) == 0x6c000000     /* bgeu  */
       || (insn & 0xfc000000) == 0x40000000     /* beqz  */
-      || (insn & 0xfc000000) == 0x44000000)    /* bnez  */
+      || (insn & 0xfc000000) == 0x44000000     /* bnez  */
+      || (insn & 0xfc000300) == 0x48000000     /* bceqz  */
+      || (insn & 0xfc000300) == 0x48000100)    /* bcnez  */
     return true;
   return false;
 }
@@ -314,6 +316,20 @@ loongarch_next_pc (struct regcache *regcache, CORE_ADDR cur_pc)
       if (rj != 0)
        next_pc = cur_pc + loongarch_decode_imm ("0:5|10:16<<2", insn, 1);
     }
+  else if ((insn & 0xfc000300) == 0x48000000)          /* bceqz cj, offs21  */
+    {
+      LONGEST cj = regcache_raw_get_signed (regcache,
+                    loongarch_decode_imm ("5:3", insn, 0) + LOONGARCH_FIRST_FCC_REGNUM);
+      if (cj == 0)
+       next_pc = cur_pc + loongarch_decode_imm ("0:5|10:16<<2", insn, 1);
+    }
+  else if ((insn & 0xfc000300) == 0x48000100)          /* bcnez cj, offs21  */
+    {
+      LONGEST cj = regcache_raw_get_signed (regcache,
+                    loongarch_decode_imm ("5:3", insn, 0) + LOONGARCH_FIRST_FCC_REGNUM);
+      if (cj != 0)
+       next_pc = cur_pc + loongarch_decode_imm ("0:5|10:16<<2", insn, 1);
+    }
   else if ((insn & 0xffff8000) == 0x002b0000)          /* syscall  */
     {
       if (tdep->syscall_next_pc != nullptr)