Add subi mnemonics & use capstone-style CR bits

This commit is contained in:
Luke Street 2023-10-06 01:06:50 -04:00
parent 9ae36eef34
commit 87fe934548
5 changed files with 107 additions and 18 deletions

View File

@ -1,4 +1,5 @@
[workspace] [workspace]
resolver = "2"
members = [ members = [
"disasm", "disasm",
"disasm-py", "disasm-py",

View File

@ -4860,6 +4860,61 @@ impl Ins {
ins: self, ins: self,
}; };
} }
if ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) < 0
&& ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) != -0x8000
{
return SimplifiedIns {
mnemonic: "subi",
suffix: String::new(),
args: vec![
Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _)),
Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)),
Argument::Simm(Simm(
(-((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32))
as _,
)),
],
ins: self,
};
}
}
Opcode::Addic => {
if ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) < 0
&& ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) != -0x8000
{
return SimplifiedIns {
mnemonic: "subic",
suffix: String::new(),
args: vec![
Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _)),
Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)),
Argument::Simm(Simm(
(-((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32))
as _,
)),
],
ins: self,
};
}
}
Opcode::Addic_ => {
if ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) < 0
&& ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) != -0x8000
{
return SimplifiedIns {
mnemonic: "subic.",
suffix: String::new(),
args: vec![
Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _)),
Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)),
Argument::Simm(Simm(
(-((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32))
as _,
)),
],
ins: self,
};
}
} }
Opcode::Addis => { Opcode::Addis => {
if ((self.code >> 16u8) & 0x1f) == 0 { if ((self.code >> 16u8) & 0x1f) == 0 {
@ -4873,6 +4928,23 @@ impl Ins {
ins: self, ins: self,
}; };
} }
if ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) < 0
&& ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) != -0x8000
{
return SimplifiedIns {
mnemonic: "subis",
suffix: String::new(),
args: vec![
Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _)),
Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)),
Argument::Simm(Simm(
(-((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32))
as _,
)),
],
ins: self,
};
}
} }
Opcode::Bc => { Opcode::Bc => {
if ((self.code >> 21u8) & 0x1f) & 0b11110 == 12 && ((self.code >> 16u8) & 0x1f) == 0 if ((self.code >> 21u8) & 0x1f) & 0b11110 == 12 && ((self.code >> 16u8) & 0x1f) == 0

View File

@ -189,9 +189,9 @@ impl Display for CRBit {
let cr = self.0 >> 2; let cr = self.0 >> 2;
let cc = self.0 & 3; let cc = self.0 & 3;
if cr != 0 { if cr != 0 {
write!(f, "4*{}+", CRField(cr))?; write!(f, "{}", CRField(cr))?;
} }
const CR_NAMES: [&str; 4] = ["lt", "gt", "eq", "so"]; const CR_NAMES: [&str; 4] = ["lt", "gt", "eq", "un"];
f.write_str(CR_NAMES[cc as usize]) f.write_str(CR_NAMES[cc as usize])
} }
} }

View File

@ -34,7 +34,7 @@ fn test_ins_addi() {
assert_asm!(0x38010010, "addi r0, r1, 0x10"); assert_asm!(0x38010010, "addi r0, r1, 0x10");
assert_asm!(0x38010018, "addi r0, r1, 0x18"); assert_asm!(0x38010018, "addi r0, r1, 0x18");
assert_asm!(0x38010140, "addi r0, r1, 0x140"); assert_asm!(0x38010140, "addi r0, r1, 0x140");
assert_asm!(0x38049000, "addi r0, r4, -0x7000"); assert_asm!(0x38049000, "subi r0, r4, 0x7000");
assert_asm!(0x38a00000, "li r5, 0x0"); assert_asm!(0x38a00000, "li r5, 0x0");
} }
@ -45,12 +45,12 @@ fn test_ins_adde() {
#[test] #[test]
fn test_ins_addic() { fn test_ins_addic() {
assert_asm!(0x3060ffff, "addic r3, r0, -0x1"); assert_asm!(0x3060ffff, "subic r3, r0, 0x1");
assert_asm!(0x30840800, "addic r4, r4, 0x800"); assert_asm!(0x30840800, "addic r4, r4, 0x800");
assert_asm!(0x30a50008, "addic r5, r5, 0x8"); assert_asm!(0x30a50008, "addic r5, r5, 0x8");
assert_asm!(0x37DF001C, "addic. r30, r31, 0x1c"); assert_asm!(0x37DF001C, "addic. r30, r31, 0x1c");
assert_asm!(0x37E06278, "addic. r31, r0, 0x6278"); assert_asm!(0x37E06278, "addic. r31, r0, 0x6278");
assert_asm!(0x37E3FFFF, "addic. r31, r3, -0x1"); assert_asm!(0x37E3FFFF, "subic. r31, r3, 0x1");
} }
#[test] #[test]
@ -126,8 +126,8 @@ fn test_ins_bc() {
assert_asm!(0x4200F560, "bdnz -0xaa0"); assert_asm!(0x4200F560, "bdnz -0xaa0");
assert_asm!(0x40010014, "bdnzf gt, 0x14"); assert_asm!(0x40010014, "bdnzf gt, 0x14");
assert_asm!(0x40410035, "bdzfl gt, 0x34"); assert_asm!(0x40410035, "bdzfl gt, 0x34");
assert_asm!(0x41430023, "bdztla so, 0x20"); assert_asm!(0x41430023, "bdztla un, 0x20");
assert_asm!(0x4108FFE3, "bdnztla 4*cr2+lt, -0x20"); assert_asm!(0x4108FFE3, "bdnztla cr2lt, -0x20");
assert_asm!(0x40A20008, "bne+ 0x8"); assert_asm!(0x40A20008, "bne+ 0x8");
} }
@ -155,7 +155,7 @@ fn test_ins_bclr() {
assert_asm!(0x4E800020, "blr"); assert_asm!(0x4E800020, "blr");
assert_asm!(0x4E800021, "blrl"); assert_asm!(0x4E800021, "blrl");
assert_asm!(0x4D000020, "bdnztlr lt"); assert_asm!(0x4D000020, "bdnztlr lt");
assert_asm!(0x4C1F0021, "bdnzflrl 4*cr7+so"); assert_asm!(0x4C1F0021, "bdnzflrl cr7un");
} }
#[test] #[test]
@ -187,44 +187,44 @@ fn test_ins_cntlzw() {
#[test] #[test]
fn test_ins_crand() { fn test_ins_crand() {
assert_asm!(0x4C853202, "crand 4*cr1+lt, 4*cr1+gt, 4*cr1+eq"); assert_asm!(0x4C853202, "crand cr1lt, cr1gt, cr1eq");
} }
#[test] #[test]
fn test_ins_crandc() { fn test_ins_crandc() {
assert_asm!(0x4C642902, "crandc so, 4*cr1+lt, 4*cr1+gt"); assert_asm!(0x4C642902, "crandc un, cr1lt, cr1gt");
} }
#[test] #[test]
fn test_ins_creqv() { fn test_ins_creqv() {
assert_asm!(0x4CE00A42, "creqv 4*cr1+so, lt, gt"); assert_asm!(0x4CE00A42, "creqv cr1un, lt, gt");
} }
#[test] #[test]
fn test_ins_crnand() { fn test_ins_crnand() {
assert_asm!(0x4C2219C2, "crnand gt, eq, so"); assert_asm!(0x4C2219C2, "crnand gt, eq, un");
} }
#[test] #[test]
fn test_ins_cror() { fn test_ins_cror() {
assert_asm!(0x4C411382, "cror eq, gt, eq"); assert_asm!(0x4C411382, "cror eq, gt, eq");
assert_asm!(0x4CA63B82, "cror 4*cr1+gt, 4*cr1+eq, 4*cr1+so"); assert_asm!(0x4CA63B82, "cror cr1gt, cr1eq, cr1un");
} }
#[test] #[test]
fn test_ins_crorc() { fn test_ins_crorc() {
assert_asm!(0x4C432342, "crorc eq, so, 4*cr1+lt"); assert_asm!(0x4C432342, "crorc eq, un, cr1lt");
} }
#[test] #[test]
fn test_ins_crnor() { fn test_ins_crnor() {
assert_asm!(0x4C011042, "crnor lt, gt, eq"); assert_asm!(0x4C011042, "crnor lt, gt, eq");
assert_asm!(0x4CA63042, "crnot 4*cr1+gt, 4*cr1+eq"); assert_asm!(0x4CA63042, "crnot cr1gt, cr1eq");
} }
#[test] #[test]
fn test_ins_crxor() { fn test_ins_crxor() {
assert_asm!(0x4CC70182, "crxor 4*cr1+eq, 4*cr1+so, lt"); assert_asm!(0x4CC70182, "crxor cr1eq, cr1un, lt");
} }
#[test] #[test]
@ -585,12 +585,12 @@ fn test_ins_mtcrf() {
#[test] #[test]
fn test_ins_mtfsb0() { fn test_ins_mtfsb0() {
assert_asm!(0xFFA0008C, "mtfsb0 4*cr7+gt") assert_asm!(0xFFA0008C, "mtfsb0 cr7gt")
} }
#[test] #[test]
fn test_ins_mtfsb1() { fn test_ins_mtfsb1() {
assert_asm!(0xFFA0004C, "mtfsb1 4*cr7+gt"); assert_asm!(0xFFA0004C, "mtfsb1 cr7gt");
} }
#[test] #[test]

View File

@ -1973,10 +1973,26 @@ mnemonics:
opcode: addis opcode: addis
args: [ rD, uimm ] args: [ rD, uimm ]
condition: rA == 0 condition: rA == 0
- name: subis
opcode: addis
args: [ rD, rA, simm=-simm ]
condition: simm < 0 && simm != -0x8000
- name: li - name: li
opcode: addi opcode: addi
args: [ rD, simm ] args: [ rD, simm ]
condition: rA == 0 condition: rA == 0
- name: subi
opcode: addi
args: [ rD, rA, simm=-simm ]
condition: simm < 0 && simm != -0x8000
- name: subic
opcode: addic
args: [ rD, rA, simm=-simm ]
condition: simm < 0 && simm != -0x8000
- name: subic.
opcode: addic.
args: [ rD, rA, simm=-simm ]
condition: simm < 0 && simm != -0x8000
- name: mr - name: mr
opcode: or opcode: or
args: [ rA, rS ] args: [ rA, rS ]