@@ -324,6 +324,49 @@ void LoongArch_rewrite_memory_operand(MCInst *MI)
324324 }
325325}
326326
327+ void LoongArch_rewrite_address_operand (MCInst * MI )
328+ {
329+ // rewrite offset immediate operand to absolute address in direct branch instructions
330+ // convert e.g.
331+ // 0x1000: beqz $t0, 0x100c
332+ // op_count: 2
333+ // operands[0].type: REG = t0
334+ // operands[0].access: READ
335+ // operands[1].type: IMM = 0xc
336+ // operands[1].access: READ
337+ // to:
338+ // op_count: 2
339+ // operands[0].type: REG = t0
340+ // operands[0].access: READ
341+ // operands[1].type: IMM = 0x100c
342+ // operands[1].access: READ
343+
344+ if (!detail_is_set (MI ))
345+ return ;
346+
347+ // handle different types of branch instructions
348+ switch (MI -> flat_insn -> id ) {
349+ case LOONGARCH_INS_B :
350+ case LOONGARCH_INS_BCEQZ :
351+ case LOONGARCH_INS_BCNEZ :
352+ case LOONGARCH_INS_BEQ :
353+ case LOONGARCH_INS_BEQZ :
354+ case LOONGARCH_INS_BGE :
355+ case LOONGARCH_INS_BGEU :
356+ case LOONGARCH_INS_BL :
357+ case LOONGARCH_INS_BLT :
358+ case LOONGARCH_INS_BLTU :
359+ case LOONGARCH_INS_BNE :
360+ case LOONGARCH_INS_BNEZ :
361+ // last operand is address operand
362+ LoongArch_get_detail_op (MI , -1 )-> imm += MI -> address ;
363+ return ;
364+
365+ default :
366+ break ;
367+ }
368+ }
369+
327370void LoongArch_set_instr_map_data (MCInst * MI )
328371{
329372 map_cs_id (MI , loongarch_insns , ARR_SIZE (loongarch_insns ));
@@ -432,6 +475,7 @@ void LoongArch_printer(MCInst *MI, SStream *O,
432475 LoongArch_LLVM_printInst (MI , MI -> address , "" , O );
433476
434477 LoongArch_rewrite_memory_operand (MI );
478+ LoongArch_rewrite_address_operand (MI );
435479 LoongArch_add_cs_groups (MI );
436480#ifndef CAPSTONE_DIET
437481 map_set_alias_id (MI , O , insn_alias_mnem_map ,
0 commit comments