@@ -64,22 +64,25 @@ R_IPI int mips_assemble(const char *str, ut64 pc, ut8 *out);
6464
6565
6666// call with delay slot
67- #define ES_CALL_DR (ra , addr ) "pc,4,+,"ra",=,"ES_J (addr)
67+ #define ES_CALL_DR (ra , addr ) "pc,4,+,"ra",=,"ES_J_D (addr)
6868#define ES_CALL_D (addr ) ES_CALL_DR("ra", addr)
6969
7070// call without delay slot
71- #define ES_CALL_NDR (ra , addr ) "pc,"ra",=,"ES_J (addr)
71+ #define ES_CALL_NDR (ra , addr ) "pc,"ra",=,"ES_J_ND (addr)
7272#define ES_CALL_ND (addr ) ES_CALL_NDR("ra", addr)
7373
74- #define USE_DS 0
74+ #define USE_DS 1
7575#if USE_DS
7676// emit ERR trap if executed in a delay slot
7777#define ES_TRAP_DS () "$ds,!,!,?{,$$,1,TRAP,BREAK,},"
78- // jump to address
79- #define ES_J (addr ) addr",SETJT,1,SETD"
78+ // Record jump-to-address and set delay slot flag.
79+ #define ES_J_D (addr ) addr",SETJT,1,SETD"
80+ // Jump to address.
81+ #define ES_J_ND (addr ) addr",pc,:="
8082#else
8183#define ES_TRAP_DS () ""
82- #define ES_J (addr ) addr",pc,:="
84+ #define ES_J_D (addr ) addr",pc,:="
85+ #define ES_J_ND (addr ) ES_J_D(addr)
8386#endif
8487
8588#define ES_B (x ) "0xff,"x",&"
@@ -241,6 +244,7 @@ static const char *arg(csh *handle, cs_insn *insn, char *buf, size_t buf_sz, int
241244static int analop_esil (RArchSession * as , RAnalOp * op , csh * handle , cs_insn * insn ) {
242245 char str [8 ][32 ] = {{0 }};
243246 int i ;
247+ u_int64_t addr = insn -> address ;
244248
245249 r_strbuf_init (& op -> esil );
246250 r_strbuf_set (& op -> esil , "" );
@@ -314,6 +318,15 @@ static int analop_esil(RArchSession *as, RAnalOp *op, csh *handle, cs_insn *insn
314318 case MIPS_INS_SLL :
315319 r_strbuf_appendf (& op -> esil , "%s,%s,<<,%s,=" , ARG (2 ), ARG (1 ), ARG (0 ));
316320 break ;
321+ case MIPS_INS_BALC :
322+ // BALC address
323+ // Branch And Link, Compact. Unconditional PC relative branch to address, placing return address
324+ // in register $31.
325+ r_strbuf_appendf (& op -> esil , ES_TRAP_DS () "" ES_CALL_ND ("%s" ), ARG (0 ));
326+ #if USE_DS
327+ r_strbuf_replacef (& op -> esil , "$$" , "0x%" PFMT64x , addr );
328+ #endif
329+ break ;
317330 case MIPS_INS_BAL :
318331 case MIPS_INS_JAL :
319332 r_strbuf_appendf (& op -> esil , ES_TRAP_DS () "" ES_CALL_D ("%s" ), ARG (0 ));
@@ -348,48 +361,94 @@ static int analop_esil(RArchSession *as, RAnalOp *op, csh *handle, cs_insn *insn
348361 break ;
349362 case MIPS_INS_JRADDIUSP :
350363 // increment stackpointer in X and jump to %ra
351- r_strbuf_appendf (& op -> esil , ES_TRAP_DS () "%s,sp,+=," ES_J ("ra" ), ARG (0 ));
364+ r_strbuf_appendf (& op -> esil , ES_TRAP_DS () "%s,sp,+=," ES_J_D ("ra" ), ARG (0 ));
352365#if USE_DS
353366 r_strbuf_replacef (& op -> esil , "$$" , "0x%" PFMT64x , addr );
354367#endif
355368 break ;
356- case MIPS_INS_JR :
357369 case MIPS_INS_JRC :
370+ case MIPS_INS_BC :
371+ // JRC rt
372+ // Jump Register, Compact. Unconditional jump to address in register $rt.
373+ // BC address
374+ // Branch, Compact. Unconditional PC relative branch to address.
375+ r_strbuf_appendf (& op -> esil , ES_TRAP_DS () "" ES_J_ND ("%s" ), ARG (0 ));
376+ #if USE_DS
377+ r_strbuf_replacef (& op -> esil , "$$" , "0x%" PFMT64x , addr );
378+ #endif
379+ break ;
380+ case MIPS_INS_JR :
358381 case MIPS_INS_J :
359382 case MIPS_INS_B : // ???
360383 // jump to address with conditional
361- r_strbuf_appendf (& op -> esil , ES_TRAP_DS () "" ES_J ("%s" ), ARG (0 ));
384+ r_strbuf_appendf (& op -> esil , ES_TRAP_DS () "" ES_J_D ("%s" ), ARG (0 ));
385+ #if USE_DS
386+ r_strbuf_replacef (& op -> esil , "$$" , "0x%" PFMT64x , addr );
387+ #endif
388+ break ;
389+ case MIPS_INS_BNEC :
390+ // BNEC rs, rt, address
391+ // Branch Not Equal, Compact. PC relative branch to address if register $rs is not equal to
392+ // register $rt.
393+ r_strbuf_appendf (& op -> esil , ES_TRAP_DS () "%s,%s,==,$z,!,?{," ES_J_ND ("%s" ) ",}" ,
394+ ARG (0 ), ARG (1 ), ARG (2 ));
362395#if USE_DS
363396 r_strbuf_replacef (& op -> esil , "$$" , "0x%" PFMT64x , addr );
364397#endif
365398 break ;
366399 case MIPS_INS_BNE : // bne $s, $t, offset
367400 case MIPS_INS_BNEL :
368- r_strbuf_appendf (& op -> esil , ES_TRAP_DS () "%s,%s,==,$z,!,?{," ES_J ("%s" ) ",}" ,
401+ r_strbuf_appendf (& op -> esil , ES_TRAP_DS () "%s,%s,==,$z,!,?{," ES_J_D ("%s" ) ",}" ,
402+ ARG (0 ), ARG (1 ), ARG (2 ));
403+ #if USE_DS
404+ r_strbuf_replacef (& op -> esil , "$$" , "0x%" PFMT64x , addr );
405+ #endif
406+ break ;
407+ case MIPS_INS_BEQC :
408+ // BEQC rs, rt, address
409+ // Branch if Equal, Compact. PC relative branch to address if registers $rs and $rt are are equal.
410+ r_strbuf_appendf (& op -> esil , ES_TRAP_DS () "%s,%s,==,$z,?{," ES_J_ND ("%s" ) ",}" ,
369411 ARG (0 ), ARG (1 ), ARG (2 ));
370412#if USE_DS
371413 r_strbuf_replacef (& op -> esil , "$$" , "0x%" PFMT64x , addr );
372414#endif
373415 break ;
374416 case MIPS_INS_BEQ :
375417 case MIPS_INS_BEQL :
376- r_strbuf_appendf (& op -> esil , ES_TRAP_DS () "%s,%s,==,$z,?{," ES_J ("%s" ) ",}" ,
418+ r_strbuf_appendf (& op -> esil , ES_TRAP_DS () "%s,%s,==,$z,?{," ES_J_D ("%s" ) ",}" ,
377419 ARG (0 ), ARG (1 ), ARG (2 ));
378420#if USE_DS
379421 r_strbuf_replacef (& op -> esil , "$$" , "0x%" PFMT64x , addr );
422+ #endif
423+ break ;
424+ case MIPS_INS_BEQZC :
425+ // BEQZC rt, address # when rt and address are in range
426+ // Branch if Equal to Zero, Compact. PC relative branch to address if register $rt equals zero.
427+ r_strbuf_appendf (& op -> esil , ES_TRAP_DS () "%s,0,==,$z,?{," ES_J_ND ("%s" ) ",}" ,
428+ ARG (0 ), ARG (1 ));
429+ #if USE_DS
430+ r_strbuf_replacef (& op -> esil , "$$" , "0x%" PFMT64x , addr );
380431#endif
381432 break ;
382433 case MIPS_INS_BZ :
383434 case MIPS_INS_BEQZ :
384- case MIPS_INS_BEQZC :
385- r_strbuf_appendf (& op -> esil , ES_TRAP_DS () "%s,0,==,$z,?{," ES_J ("%s" ) ",}" ,
435+ r_strbuf_appendf (& op -> esil , ES_TRAP_DS () "%s,0,==,$z,?{," ES_J_D ("%s" ) ",}" ,
436+ ARG (0 ), ARG (1 ));
437+ #if USE_DS
438+ r_strbuf_replacef (& op -> esil , "$$" , "0x%" PFMT64x , addr );
439+ #endif
440+ break ;
441+ case MIPS_INS_BNEZC :
442+ // BNEZC rt, address
443+ // Branch if Not Equal to Zero, Compact. PC relative branch to address if register $rt is not equal to zero.
444+ r_strbuf_appendf (& op -> esil , ES_TRAP_DS () "%s,0,==,$z,!,?{," ES_J_ND ("%s" ) ",}" ,
386445 ARG (0 ), ARG (1 ));
387446#if USE_DS
388447 r_strbuf_replacef (& op -> esil , "$$" , "0x%" PFMT64x , addr );
389448#endif
390449 break ;
391450 case MIPS_INS_BNEZ :
392- r_strbuf_appendf (& op -> esil , ES_TRAP_DS () "%s,0,==,$z,!,?{," ES_J ("%s" ) ",}" ,
451+ r_strbuf_appendf (& op -> esil , ES_TRAP_DS () "%s,0,==,$z,!,?{," ES_J_D ("%s" ) ",}" ,
393452 ARG (0 ), ARG (1 ));
394453#if USE_DS
395454 r_strbuf_replacef (& op -> esil , "$$" , "0x%" PFMT64x , addr );
@@ -402,21 +461,45 @@ static int analop_esil(RArchSession *as, RAnalOp *op, csh *handle, cs_insn *insn
402461 r_strbuf_replacef (& op -> esil , "$$" , "0x%" PFMT64x , addr );
403462#endif
404463 break ;
405- case MIPS_INS_BLEZ :
406464 case MIPS_INS_BLEZC :
465+ r_strbuf_appendf (& op -> esil , ES_TRAP_DS () "0,%s,==,$z,?{," ES_J_ND ("%s" ) ",BREAK,}," ,
466+ ARG (0 ), ARG (1 ));
467+ r_strbuf_appendf (& op -> esil , ES_TRAP_DS () "1 ," ES_IS_NEGATIVE (" %s ") " ,= = ,$z ,?{," ES_J_ND (" %s ") " ,}",
468+ ARG (0 ), ARG (1 ));
469+ #if USE_DS
470+ r_strbuf_replacef (& op -> esil , "$$" , "0x%" PFMT64x , addr );
471+ #endif
472+ break ;
473+ case MIPS_INS_BLEZ :
407474 case MIPS_INS_BLEZL :
408- r_strbuf_appendf (& op -> esil , ES_TRAP_DS () "0,%s,==,$z,?{," ES_J ("%s" ) ",BREAK,}," ,
475+ r_strbuf_appendf (& op -> esil , ES_TRAP_DS () "0,%s,==,$z,?{," ES_J_D ("%s" ) ",BREAK,}," ,
409476 ARG (0 ), ARG (1 ));
410- r_strbuf_appendf (& op -> esil , ES_TRAP_DS () "1 ," ES_IS_NEGATIVE (" %s ") " ,= = ,$z ,?{," ES_J (" %s ") " ,}",
477+ r_strbuf_appendf (& op -> esil , ES_TRAP_DS () "1 ," ES_IS_NEGATIVE (" %s ") " ,= = ,$z ,?{," ES_J_D (" %s ") " ,}",
411478 ARG (0 ), ARG (1 ));
412479#if USE_DS
413480 r_strbuf_replacef (& op -> esil , "$$" , "0x%" PFMT64x , addr );
414481#endif
415482 break ;
416- case MIPS_INS_BGEZ :
483+ case MIPS_INS_BGEC :
484+ // BGEC rs, rt, address
485+ // Branch if Greater than or Equal, Compact. PC relative branch to address if register $rs
486+ // is greater than or equal to register $rt.
487+ r_strbuf_appendf (& op -> esil , ES_TRAP_DS () "%s,%s,>=,$z,?{," ES_J_ND ("%s" ) ",}" ,
488+ ARG (1 ), ARG (0 ), ARG (2 ));
489+ #if USE_DS
490+ r_strbuf_replacef (& op -> esil , "$$" , "0x%" PFMT64x , addr );
491+ #endif
492+ break ;
417493 case MIPS_INS_BGEZC :
494+ r_strbuf_appendf (& op -> esil , ES_TRAP_DS () "0 ," ES_IS_NEGATIVE (" %s ") " ,= = ,$z ,?{," ES_J_ND (" %s ") " ,}",
495+ ARG (0 ), ARG (1 ));
496+ #if USE_DS
497+ r_strbuf_replacef (& op -> esil , "$$" , "0x%" PFMT64x , addr );
498+ #endif
499+ break ;
500+ case MIPS_INS_BGEZ :
418501 case MIPS_INS_BGEZL :
419- r_strbuf_appendf (& op -> esil , ES_TRAP_DS () "0 ," ES_IS_NEGATIVE (" %s ") " ,= = ,$z ,?{," ES_J (" %s ") " ,}",
502+ r_strbuf_appendf (& op -> esil , ES_TRAP_DS () "0 ," ES_IS_NEGATIVE (" %s ") " ,= = ,$z ,?{," ES_J_D (" %s ") " ,}",
420503 ARG (0 ), ARG (1 ));
421504#if USE_DS
422505 r_strbuf_replacef (& op -> esil , "$$" , "0x%" PFMT64x , addr );
@@ -450,33 +533,46 @@ static int analop_esil(RArchSession *as, RAnalOp *op, csh *handle, cs_insn *insn
450533 r_strbuf_replacef (& op -> esil , "$$" , "0x%" PFMT64x , addr );
451534#endif
452535 break ;
453- case MIPS_INS_BLTZ :
454536 case MIPS_INS_BLTZC :
537+ r_strbuf_appendf (& op -> esil , ES_TRAP_DS () "1 ," ES_IS_NEGATIVE (" %s ") " ,= = ,$z ,?{," ES_J_ND (" %s ") " ,}",
538+ ARG (0 ), ARG (1 ));
539+ #if USE_DS
540+ r_strbuf_replacef (& op -> esil , "$$" , "0x%" PFMT64x , addr );
541+ #endif
542+ break ;
543+ case MIPS_INS_BLTZ :
455544 case MIPS_INS_BLTZL :
456- r_strbuf_appendf (& op -> esil , ES_TRAP_DS () "1 ," ES_IS_NEGATIVE (" %s ") " ,= = ,$z ,?{," ES_J (" %s ") " ,}",
545+ r_strbuf_appendf (& op -> esil , ES_TRAP_DS () "1 ," ES_IS_NEGATIVE (" %s ") " ,= = ,$z ,?{," ES_J_D (" %s ") " ,}",
457546 ARG (0 ), ARG (1 ));
458547#if USE_DS
459548 r_strbuf_replacef (& op -> esil , "$$" , "0x%" PFMT64x , addr );
460549#endif
461550 break ;
462- case MIPS_INS_BGTZ :
463551 case MIPS_INS_BGTZC :
552+ r_strbuf_appendf (& op -> esil , ES_TRAP_DS () "0,%s,==,$z,?{,BREAK,}," , ARG (0 ));
553+ r_strbuf_appendf (& op -> esil , ES_TRAP_DS () "0 ," ES_IS_NEGATIVE (" %s ") " ,= = ,$z ,?{," ES_J_ND (" %s ") " ,}",
554+ ARG (0 ), ARG (1 ));
555+ #if USE_DS
556+ r_strbuf_replacef (& op -> esil , "$$" , "0x%" PFMT64x , addr );
557+ #endif
558+ break ;
559+ case MIPS_INS_BGTZ :
464560 case MIPS_INS_BGTZL :
465561 r_strbuf_appendf (& op -> esil , ES_TRAP_DS () "0,%s,==,$z,?{,BREAK,}," , ARG (0 ));
466- r_strbuf_appendf (& op -> esil , ES_TRAP_DS () "0 ," ES_IS_NEGATIVE (" %s ") " ,= = ,$z ,?{," ES_J (" %s ") " ,}",
562+ r_strbuf_appendf (& op -> esil , ES_TRAP_DS () "0 ," ES_IS_NEGATIVE (" %s ") " ,= = ,$z ,?{," ES_J_D (" %s ") " ,}",
467563 ARG (0 ), ARG (1 ));
468564#if USE_DS
469565 r_strbuf_replacef (& op -> esil , "$$" , "0x%" PFMT64x , addr );
470566#endif
471567 break ;
472568 case MIPS_INS_BTEQZ :
473- r_strbuf_appendf (& op -> esil , ES_TRAP_DS () "0,t,==,$z,?{," ES_J ("%s" ) ",}" , ARG (0 ));
569+ r_strbuf_appendf (& op -> esil , ES_TRAP_DS () "0,t,==,$z,?{," ES_J_D ("%s" ) ",}" , ARG (0 ));
474570#if USE_DS
475571 r_strbuf_replacef (& op -> esil , "$$" , "0x%" PFMT64x , addr );
476572#endif
477573 break ;
478574 case MIPS_INS_BTNEZ :
479- r_strbuf_appendf (& op -> esil , ES_TRAP_DS () "0,t,==,$z,!,?{," ES_J ("%s" ) ",}" , ARG (0 ));
575+ r_strbuf_appendf (& op -> esil , ES_TRAP_DS () "0,t,==,$z,!,?{," ES_J_D ("%s" ) ",}" , ARG (0 ));
480576#if USE_DS
481577 r_strbuf_replacef (& op -> esil , "$$" , "0x%" PFMT64x , addr );
482578#endif
0 commit comments