Repository: capstone-engine/capstone (C)

Issue:
`negu` not detected as alias of `subu`.
<!-- This template is meant for disassembly related bug reports, please be as descriptive as possible -->

### Work environment

<!-- Filling this table is mandatory -->

| Questions                                | Answers
|------------------------------------------|--------------------
| System Capstone runs on OS/arch/bits     | Fedora x86_64
| Capstone module affected                 | Mips
| Source of Capstone                       | `git clone`
| Version/git commit                       | 8ac2843b9bc91e29c0287d27f9c49cff2ad44776 (HEAD, tag: 6.0.0-Alpha3)

<!-- INCORRECT DISASSEMBLY BUGS -->

### Instruction bytes giving faulty results

```
cstool -d -r mips 00071823
 0  00 07 18 23  negu	$v1, $a3
	ID: 66 (subu)
	Is alias: 0 (invalid) with REAL operand set
	op_count: 3
		operands[0].type: REG = v1
		operands[0].is_reglist: false
		operands[1].type: REG = zero
		operands[1].is_reglist: false
		operands[2].type: REG = a3
		operands[2].is_reglist: false
	Groups: HasStdEnc NotInMicroMips NotNanoMips 
```

### Expected results

It should be:
```
	ID: 66 (subu)
	Is alias: <ALIAS_ID> (negu) with REAL operand set
...
```

### Steps to get the wrong result

With `cstool`:

```sh
cstool -d -r mips 00071823
```

<!-- ADDITIONAL CONTEXT -->

### Additional Logs, screenshots, source code,  configuration dump, ...

...

Instructions marked as alias with alias_id 0
### Work environment


| Questions | Answers |
| ------------- | ------------- |
| Capstone module affected	  | Mips  |
|Source of Capstone | `git clone` |
| Version/git commit | https://github.com/capstone-engine/capstone/commit/8ac2843b9bc91e29c0287d27f9c49cff2ad44776 (HEAD, tag: 6.0.0-Alpha3) |

I've run into some instructions in MIPS that have the `.is_alias` flag set to `true`, with the `alias_id` set to 0. 

```sh
# bnez   $t0, 0x10
cstool -d mipsel "0x03 0x00 0x00 0x15"

 0  03 00 00 15  bnez   $t0, 0x10
        ID: 23 (bne)
        Is alias: 0 (invalid) with REAL operand set
        op_count: 2
                operands[0].type: REG = t0
                operands[0].is_reglist: false
                operands[1].type: IMM = 0x10
                operands[1].is_unsigned: true
        Groups: jump branch_relative HasStdEnc NotInMicroMips NotNanoMips 
```

This problem might be more widespread, but I have only encountered it in MIPS instructions. It is not the case for all instructions.

Other examples here: #2628 (search for the word `invalid`)

### Expected behavior

If the instruction is marked as an alias, the alias_id should be a valid ID.



Discussion: Another MIPS instruction giving faulty disassembly is the `syscall` instruction

Before (cstool v5.0.5)
```
cstool -d mips 0c000000
 0  0c 00 00 00  syscall	
	ID: 594 (syscall)
	Groups: stdenc int 
```

After (latest git clone, 6.0.0alpha3)
```
cstool -d mips 0c000000
 0  0c 00 00 00  jal	0
	ID: 35 (jal)
	op_count: 1
		operands[0].type: IMM = 0x0
		operands[0].is_unsigned: true
	Groups: call HasStdEnc NotInMicroMips NotNanoMips 
```
This happens because you have not selected the correct processor. In `v6` the module is way more strict about it. It has to be, due to duplicates as you see below:

```
> cstool -d mipsel 0c000000
 0  0c 00 00 00  syscall	
	ID: 1310 (syscall)
	Is alias: 0 (invalid) with REAL operand set
	Groups: HasStdEnc NotInMicroMips NotNanoMips 

> cstool -d mips 0c000000
 0  0c 00 00 00  jal	0
	ID: 35 (jal)
	op_count: 1
		operands[0].type: IMM = 0x0
		operands[0].is_unsigned: true
	Groups: call HasStdEnc NotInMicroMips NotNanoMips 

> cstool -d micromipsel 0c000000
 0  0c 00 00 00  sll	$zero, $t4, 0
	ID: 1185 (sll)
	op_count: 3
		operands[0].type: REG = zero
		operands[0].is_reglist: false
		operands[1].type: REG = t4
		operands[1].is_reglist: false
		operands[2].type: IMM = 0x0
		operands[2].is_unsigned: true
	Groups: InMicroMips 
```
I see, that makes sense - thank you!

A theory is that all aliases have the alias_id set to zero in mips?
I noticed this also on other instructions, tbh, i do not know why, probably missing a change to fix this, like `lapc` is an alias for `addiupc` but doesn't get resolved either.

```
$ ./build/cstool -r -d mipsel64r6 190040ec
 0  19 00 40 ec  lapc   $v0, 0x64
        ID: 99 (addiupc)
        Is alias: 0 (invalid) with REAL operand set
        op_count: 2
                operands[0].type: REG = v0
                operands[0].is_reglist: false
                operands[1].type: IMM = 0x64
                operands[1].is_unsigned: false
        Groups: HasStdEnc HasMips32r6 
```
>  but doesn't get resolved either.

This indicates it is missing in LLVM. Which is annoying to fix. Because it is TableGen land.
It turns out it was my fault, and i forgot to implement the code that does that mapping.



Fix (patch):
diff --git a/arch/Mips/MipsMapping.c b/arch/Mips/MipsMapping.c
index e9344a81c7..479a70c60d 100644
--- a/arch/Mips/MipsMapping.c
+++ b/arch/Mips/MipsMapping.c
@@ -51,9 +51,29 @@ static const char *const insn_name_maps[] = {
 #include "MipsGenCSMappingInsnName.inc"
 };
 
+#ifndef CAPSTONE_DIET
+static const name_map insn_alias_mnem_map[] = {
+#include "MipsGenCSAliasMnemMap.inc"
+	// The followings aliases are not generated by LLVM table gen.
+	{ MIPS_INS_ALIAS_B, "b" }, // beq
+	{ MIPS_INS_ALIAS_BEQZ, "beqz" }, // beq
+	{ MIPS_INS_ALIAS_BNEZ, "bnez" }, // bne
+	{ MIPS_INS_ALIAS_LI, "li" }, // addiu
+	{ MIPS_INS_ALIAS_END, NULL },
+};
+#endif
 const char *Mips_insn_name(csh handle, unsigned int id)
 {
 #ifndef CAPSTONE_DIET
+	if (id < MIPS_INS_ALIAS_END && id > MIPS_INS_ALIAS_BEGIN) {
+		if (id - MIPS_INS_ALIAS_BEGIN >= ARR_SIZE(insn_alias_mnem_map))
+			return NULL;
+
+		return insn_alias_mnem_map[id - MIPS_INS_ALIAS_BEGIN - 1].name;
+	}
+	if (id >= MIPS_INS_ENDING)
+		return NULL;
+
 	if (id < ARR_SIZE(insn_name_maps))
 		return insn_name_maps[id];
 	// not found
@@ -193,6 +213,10 @@ void Mips_printer(MCInst *MI, SStream *O, void * /* MCRegisterInfo* */ info)
 	MI->MRI = MRI;
 
 	Mips_LLVM_printInst(MI, MI->address, O);
+#ifndef CAPSTONE_DIET
+	map_set_alias_id(MI, O, insn_alias_mnem_map,
+			 ARR_SIZE(insn_alias_mnem_map));
+#endif
 }
 
 static void Mips_setup_op(cs_mips_op *op)
diff --git a/bindings/java/capstone/Mips_const.java b/bindings/java/capstone/Mips_const.java
index a1b66910c6..21c2c3696a 100644
--- a/bindings/java/capstone/Mips_const.java
+++ b/bindings/java/capstone/Mips_const.java
@@ -2113,7 +2113,11 @@ public class Mips_const {
 	public static final int MIPS_INS_ALIAS_MTTLO = 1465;
 	public static final int MIPS_INS_ALIAS_MTTHI = 1466;
 	public static final int MIPS_INS_ALIAS_MTTACX = 1467;
-	public static final int MIPS_INS_ALIAS_END = 1468;
+	public static final int MIPS_INS_ALIAS_B = 1468;
+	public static final int MIPS_INS_ALIAS_BEQZ = 1469;
+	public static final int MIPS_INS_ALIAS_BNEZ = 1470;
+	public static final int MIPS_INS_ALIAS_LI = 1471;
+	public static final int MIPS_INS_ALIAS_END = 1472;
 
 	public static final int MIPS_GRP_INVALID = 0;
 	public static final int MIPS_GRP_JUMP = 1;
diff --git a/bindings/ocaml/mips_const.ml b/bindings/ocaml/mips_const.ml
index fed8ff15b7..1f6ae16165 100644
--- a/bindings/ocaml/mips_const.ml
+++ b/bindings/ocaml/mips_const.ml
@@ -2110,7 +2110,11 @@ let _MIPS_INS_ALIAS_MTTC0 = 1464;;
 let _MIPS_INS_ALIAS_MTTLO = 1465;;
 let _MIPS_INS_ALIAS_MTTHI = 1466;;
 let _MIPS_INS_ALIAS_MTTACX = 1467;;
-let _MIPS_INS_ALIAS_END = 1468;;
+let _MIPS_INS_ALIAS_B = 1468;;
+let _MIPS_INS_ALIAS_BEQZ = 1469;;
+let _MIPS_INS_ALIAS_BNEZ = 1470;;
+let _MIPS_INS_ALIAS_LI = 1471;;
+let _MIPS_INS_ALIAS_END = 1472;;
 
 let _MIPS_GRP_INVALID = 0;;
 let _MIPS_GRP_JUMP = 1;;
diff --git a/bindings/python/capstone/mips_const.py b/bindings/python/capstone/mips_const.py
index 5f6cc8c1b7..43e3318f99 100644
--- a/bindings/python/capstone/mips_const.py
+++ b/bindings/python/capstone/mips_const.py
@@ -2111,7 +2111,11 @@
 MIPS_INS_ALIAS_MTTLO = 1465
 MIPS_INS_ALIAS_MTTHI = 1466
 MIPS_INS_ALIAS_MTTACX = 1467
-MIPS_INS_ALIAS_END = 1468
+MIPS_INS_ALIAS_B = 1468
+MIPS_INS_ALIAS_BEQZ = 1469
+MIPS_INS_ALIAS_BNEZ = 1470
+MIPS_INS_ALIAS_LI = 1471
+MIPS_INS_ALIAS_END = 1472
 
 MIPS_GRP_INVALID = 0
 MIPS_GRP_JUMP = 1
diff --git a/include/capstone/mips.h b/include/capstone/mips.h
index c776d3ac1a..95b2da1325 100644
--- a/include/capstone/mips.h
+++ b/include/capstone/mips.h
@@ -2189,6 +2189,12 @@ typedef enum mips_insn {
 
 	// clang-format on
 	// generated content <MipsGenCSAliasEnum.inc> end
+
+	// The followings aliases are not generated by LLVM table gen.
+	MIPS_INS_ALIAS_B,    // beq $zero, $zero, $L2 => b $L2
+	MIPS_INS_ALIAS_BEQZ, // beq $r0, $zero, $L2 => beqz $r0, $L2
+	MIPS_INS_ALIAS_BNEZ, // bne $r0, $zero, $L2 => bnez $r0, $L2
+	MIPS_INS_ALIAS_LI,   // addiu $rX, $r0, imm => li $r0, imm
 	MIPS_INS_ALIAS_END,
 } mips_insn;