diff options
author | Tiezhu Yang <yangtiezhu@loongson.cn> | 2025-04-30 15:10:15 +0800 |
---|---|---|
committer | Tiezhu Yang <yangtiezhu@loongson.cn> | 2025-05-10 21:25:52 +0800 |
commit | 7593801b17f7ef9e8260025a6db73df4ce008c49 (patch) | |
tree | c5faef9befc9d952773a6275304c0e0475119c3c | |
parent | e264ce6ff0f00798fe7ab6cc21eca0fedf62cc34 (diff) | |
download | binutils-7593801b17f7ef9e8260025a6db73df4ce008c49.zip binutils-7593801b17f7ef9e8260025a6db73df4ce008c49.tar.gz binutils-7593801b17f7ef9e8260025a6db73df4ce008c49.tar.bz2 |
gdb: LoongArch: Emulate floating-point branch instructions
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>
-rw-r--r-- | gdb/loongarch-tdep.c | 18 |
1 files changed, 17 insertions, 1 deletions
diff --git a/gdb/loongarch-tdep.c b/gdb/loongarch-tdep.c index 092127dd..d79ec68 100644 --- a/gdb/loongarch-tdep.c +++ b/gdb/loongarch-tdep.c @@ -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) |