fix bcctr and bclr

This commit is contained in:
Richard Patel 2022-04-07 04:44:38 +02:00
parent 16f955947e
commit 99c7f252f8
3 changed files with 433 additions and 183 deletions

View File

@ -500,10 +500,10 @@ impl Opcode {
if code & 0xfc000000 == 0x40000000 { if code & 0xfc000000 == 0x40000000 {
return Opcode::Bc; return Opcode::Bc;
} }
if code & 0xfc00ffff == 0x4c000210 { if code & 0xfc007ffe == 0x4c000420 {
return Opcode::Bcctr; return Opcode::Bcctr;
} }
if code & 0xfc00fffe == 0x4c000020 { if code & 0xfc007ffe == 0x4c000020 {
return Opcode::Bclr; return Opcode::Bclr;
} }
if code & 0xfc4007ff == 0x7c000000 { if code & 0xfc4007ff == 0x7c000000 {
@ -5022,7 +5022,22 @@ impl Ins {
} }
} }
Opcode::Bcctr => { Opcode::Bcctr => {
if ((self.code >> 21u8) & 0x1f) == 12 { if ((self.code >> 21u8) & 0x1f) == 20 && ((self.code >> 16u8) & 0x1f) == 0 {
return SimplifiedIns {
mnemonic: "bctr",
modifiers: {
let mut m = Modifiers::default();
m.lk = self.bit(31);
m
},
args: vec![],
ins: self,
};
}
if ((self.code >> 21u8) & 0x1f) == 12
&& ((self.code >> 16u8) & 0x1f) & 0b11 == 0b00
&& ((self.code >> 18u8) & 0x7) == 0
{
return SimplifiedIns { return SimplifiedIns {
mnemonic: "bltctr", mnemonic: "bltctr",
modifiers: { modifiers: {
@ -5030,17 +5045,27 @@ impl Ins {
m.lk = self.bit(31); m.lk = self.bit(31);
m m
}, },
args: vec![ args: vec![],
Argument::CRBit(CRBit(((self.code >> 18u8) & 0x7) as _)),
Argument::BranchDest(BranchDest(
(((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000))
<< 2u8) as _,
)),
],
ins: self, ins: self,
}; };
} }
if ((self.code >> 21u8) & 0x1f) == 4 { if ((self.code >> 21u8) & 0x1f) == 12 && ((self.code >> 16u8) & 0x1f) & 0b11 == 0b00
{
return SimplifiedIns {
mnemonic: "bltctr",
modifiers: {
let mut m = Modifiers::default();
m.lk = self.bit(31);
m
},
args: vec![Argument::CRBit(CRBit(((self.code >> 18u8) & 0x7) as _))],
ins: self,
};
}
if ((self.code >> 21u8) & 0x1f) == 4
&& ((self.code >> 16u8) & 0x1f) & 0b11 == 0b01
&& ((self.code >> 18u8) & 0x7) == 0
{
return SimplifiedIns { return SimplifiedIns {
mnemonic: "blectr", mnemonic: "blectr",
modifiers: { modifiers: {
@ -5048,17 +5073,27 @@ impl Ins {
m.lk = self.bit(31); m.lk = self.bit(31);
m m
}, },
args: vec![ args: vec![],
Argument::CRBit(CRBit(((self.code >> 18u8) & 0x7) as _)),
Argument::BranchDest(BranchDest(
(((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000))
<< 2u8) as _,
)),
],
ins: self, ins: self,
}; };
} }
if ((self.code >> 21u8) & 0x1f) == 12 { if ((self.code >> 21u8) & 0x1f) == 4 && ((self.code >> 16u8) & 0x1f) & 0b11 == 0b01
{
return SimplifiedIns {
mnemonic: "blectr",
modifiers: {
let mut m = Modifiers::default();
m.lk = self.bit(31);
m
},
args: vec![Argument::CRBit(CRBit(((self.code >> 18u8) & 0x7) as _))],
ins: self,
};
}
if ((self.code >> 21u8) & 0x1f) == 12
&& ((self.code >> 16u8) & 0x1f) & 0b11 == 0b10
&& ((self.code >> 18u8) & 0x7) == 0
{
return SimplifiedIns { return SimplifiedIns {
mnemonic: "beqctr", mnemonic: "beqctr",
modifiers: { modifiers: {
@ -5066,17 +5101,27 @@ impl Ins {
m.lk = self.bit(31); m.lk = self.bit(31);
m m
}, },
args: vec![ args: vec![],
Argument::CRBit(CRBit(((self.code >> 18u8) & 0x7) as _)),
Argument::BranchDest(BranchDest(
(((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000))
<< 2u8) as _,
)),
],
ins: self, ins: self,
}; };
} }
if ((self.code >> 21u8) & 0x1f) == 4 { if ((self.code >> 21u8) & 0x1f) == 12 && ((self.code >> 16u8) & 0x1f) & 0b11 == 0b10
{
return SimplifiedIns {
mnemonic: "beqctr",
modifiers: {
let mut m = Modifiers::default();
m.lk = self.bit(31);
m
},
args: vec![Argument::CRBit(CRBit(((self.code >> 18u8) & 0x7) as _))],
ins: self,
};
}
if ((self.code >> 21u8) & 0x1f) == 4
&& ((self.code >> 16u8) & 0x1f) & 0b11 == 0b00
&& ((self.code >> 18u8) & 0x7) == 0
{
return SimplifiedIns { return SimplifiedIns {
mnemonic: "bgectr", mnemonic: "bgectr",
modifiers: { modifiers: {
@ -5084,17 +5129,27 @@ impl Ins {
m.lk = self.bit(31); m.lk = self.bit(31);
m m
}, },
args: vec![ args: vec![],
Argument::CRBit(CRBit(((self.code >> 18u8) & 0x7) as _)),
Argument::BranchDest(BranchDest(
(((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000))
<< 2u8) as _,
)),
],
ins: self, ins: self,
}; };
} }
if ((self.code >> 21u8) & 0x1f) == 12 { if ((self.code >> 21u8) & 0x1f) == 4 && ((self.code >> 16u8) & 0x1f) & 0b11 == 0b00
{
return SimplifiedIns {
mnemonic: "bgectr",
modifiers: {
let mut m = Modifiers::default();
m.lk = self.bit(31);
m
},
args: vec![Argument::CRBit(CRBit(((self.code >> 18u8) & 0x7) as _))],
ins: self,
};
}
if ((self.code >> 21u8) & 0x1f) == 12
&& ((self.code >> 16u8) & 0x1f) & 0b11 == 0b01
&& ((self.code >> 18u8) & 0x7) == 0
{
return SimplifiedIns { return SimplifiedIns {
mnemonic: "bgtctr", mnemonic: "bgtctr",
modifiers: { modifiers: {
@ -5102,17 +5157,27 @@ impl Ins {
m.lk = self.bit(31); m.lk = self.bit(31);
m m
}, },
args: vec![ args: vec![],
Argument::CRBit(CRBit(((self.code >> 18u8) & 0x7) as _)),
Argument::BranchDest(BranchDest(
(((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000))
<< 2u8) as _,
)),
],
ins: self, ins: self,
}; };
} }
if ((self.code >> 21u8) & 0x1f) == 4 { if ((self.code >> 21u8) & 0x1f) == 12 && ((self.code >> 16u8) & 0x1f) & 0b11 == 0b01
{
return SimplifiedIns {
mnemonic: "bgtctr",
modifiers: {
let mut m = Modifiers::default();
m.lk = self.bit(31);
m
},
args: vec![Argument::CRBit(CRBit(((self.code >> 18u8) & 0x7) as _))],
ins: self,
};
}
if ((self.code >> 21u8) & 0x1f) == 4
&& ((self.code >> 16u8) & 0x1f) & 0b11 == 0b10
&& ((self.code >> 18u8) & 0x7) == 0
{
return SimplifiedIns { return SimplifiedIns {
mnemonic: "bnectr", mnemonic: "bnectr",
modifiers: { modifiers: {
@ -5120,17 +5185,27 @@ impl Ins {
m.lk = self.bit(31); m.lk = self.bit(31);
m m
}, },
args: vec![ args: vec![],
Argument::CRBit(CRBit(((self.code >> 18u8) & 0x7) as _)),
Argument::BranchDest(BranchDest(
(((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000))
<< 2u8) as _,
)),
],
ins: self, ins: self,
}; };
} }
if ((self.code >> 21u8) & 0x1f) == 12 { if ((self.code >> 21u8) & 0x1f) == 4 && ((self.code >> 16u8) & 0x1f) & 0b11 == 0b10
{
return SimplifiedIns {
mnemonic: "bnectr",
modifiers: {
let mut m = Modifiers::default();
m.lk = self.bit(31);
m
},
args: vec![Argument::CRBit(CRBit(((self.code >> 18u8) & 0x7) as _))],
ins: self,
};
}
if ((self.code >> 21u8) & 0x1f) == 12
&& ((self.code >> 16u8) & 0x1f) & 0b11 == 0b11
&& ((self.code >> 18u8) & 0x7) == 0
{
return SimplifiedIns { return SimplifiedIns {
mnemonic: "bsoctr", mnemonic: "bsoctr",
modifiers: { modifiers: {
@ -5138,17 +5213,27 @@ impl Ins {
m.lk = self.bit(31); m.lk = self.bit(31);
m m
}, },
args: vec![ args: vec![],
Argument::CRBit(CRBit(((self.code >> 18u8) & 0x7) as _)),
Argument::BranchDest(BranchDest(
(((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000))
<< 2u8) as _,
)),
],
ins: self, ins: self,
}; };
} }
if ((self.code >> 21u8) & 0x1f) == 4 { if ((self.code >> 21u8) & 0x1f) == 12 && ((self.code >> 16u8) & 0x1f) & 0b11 == 0b11
{
return SimplifiedIns {
mnemonic: "bsoctr",
modifiers: {
let mut m = Modifiers::default();
m.lk = self.bit(31);
m
},
args: vec![Argument::CRBit(CRBit(((self.code >> 18u8) & 0x7) as _))],
ins: self,
};
}
if ((self.code >> 21u8) & 0x1f) == 4
&& ((self.code >> 16u8) & 0x1f) & 0b11 == 0b11
&& ((self.code >> 18u8) & 0x7) == 0
{
return SimplifiedIns { return SimplifiedIns {
mnemonic: "bnsctr", mnemonic: "bnsctr",
modifiers: { modifiers: {
@ -5156,13 +5241,20 @@ impl Ins {
m.lk = self.bit(31); m.lk = self.bit(31);
m m
}, },
args: vec![ args: vec![],
Argument::CRBit(CRBit(((self.code >> 18u8) & 0x7) as _)), ins: self,
Argument::BranchDest(BranchDest( };
(((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) }
<< 2u8) as _, if ((self.code >> 21u8) & 0x1f) == 4 && ((self.code >> 16u8) & 0x1f) & 0b11 == 0b11
)), {
], return SimplifiedIns {
mnemonic: "bnsctr",
modifiers: {
let mut m = Modifiers::default();
m.lk = self.bit(31);
m
},
args: vec![Argument::CRBit(CRBit(((self.code >> 18u8) & 0x7) as _))],
ins: self, ins: self,
}; };
} }
@ -5171,12 +5263,19 @@ impl Ins {
if ((self.code >> 21u8) & 0x1f) == 20 && ((self.code >> 16u8) & 0x1f) == 0 { if ((self.code >> 21u8) & 0x1f) == 20 && ((self.code >> 16u8) & 0x1f) == 0 {
return SimplifiedIns { return SimplifiedIns {
mnemonic: "blr", mnemonic: "blr",
modifiers: Modifiers::default(), modifiers: {
let mut m = Modifiers::default();
m.lk = self.bit(31);
m
},
args: vec![], args: vec![],
ins: self, ins: self,
}; };
} }
if ((self.code >> 21u8) & 0x1f) == 12 { if ((self.code >> 21u8) & 0x1f) == 12
&& ((self.code >> 16u8) & 0x1f) & 0b11 == 0b00
&& ((self.code >> 18u8) & 0x7) == 0
{
return SimplifiedIns { return SimplifiedIns {
mnemonic: "bltlr", mnemonic: "bltlr",
modifiers: { modifiers: {
@ -5184,17 +5283,27 @@ impl Ins {
m.lk = self.bit(31); m.lk = self.bit(31);
m m
}, },
args: vec![ args: vec![],
Argument::CRBit(CRBit(((self.code >> 18u8) & 0x7) as _)),
Argument::BranchDest(BranchDest(
(((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000))
<< 2u8) as _,
)),
],
ins: self, ins: self,
}; };
} }
if ((self.code >> 21u8) & 0x1f) == 4 { if ((self.code >> 21u8) & 0x1f) == 12 && ((self.code >> 16u8) & 0x1f) & 0b11 == 0b00
{
return SimplifiedIns {
mnemonic: "bltlr",
modifiers: {
let mut m = Modifiers::default();
m.lk = self.bit(31);
m
},
args: vec![Argument::CRBit(CRBit(((self.code >> 18u8) & 0x7) as _))],
ins: self,
};
}
if ((self.code >> 21u8) & 0x1f) == 4
&& ((self.code >> 16u8) & 0x1f) & 0b11 == 0b01
&& ((self.code >> 18u8) & 0x7) == 0
{
return SimplifiedIns { return SimplifiedIns {
mnemonic: "blelr", mnemonic: "blelr",
modifiers: { modifiers: {
@ -5202,17 +5311,27 @@ impl Ins {
m.lk = self.bit(31); m.lk = self.bit(31);
m m
}, },
args: vec![ args: vec![],
Argument::CRBit(CRBit(((self.code >> 18u8) & 0x7) as _)),
Argument::BranchDest(BranchDest(
(((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000))
<< 2u8) as _,
)),
],
ins: self, ins: self,
}; };
} }
if ((self.code >> 21u8) & 0x1f) == 12 { if ((self.code >> 21u8) & 0x1f) == 4 && ((self.code >> 16u8) & 0x1f) & 0b11 == 0b01
{
return SimplifiedIns {
mnemonic: "blelr",
modifiers: {
let mut m = Modifiers::default();
m.lk = self.bit(31);
m
},
args: vec![Argument::CRBit(CRBit(((self.code >> 18u8) & 0x7) as _))],
ins: self,
};
}
if ((self.code >> 21u8) & 0x1f) == 12
&& ((self.code >> 16u8) & 0x1f) & 0b11 == 0b10
&& ((self.code >> 18u8) & 0x7) == 0
{
return SimplifiedIns { return SimplifiedIns {
mnemonic: "beqlr", mnemonic: "beqlr",
modifiers: { modifiers: {
@ -5220,17 +5339,27 @@ impl Ins {
m.lk = self.bit(31); m.lk = self.bit(31);
m m
}, },
args: vec![ args: vec![],
Argument::CRBit(CRBit(((self.code >> 18u8) & 0x7) as _)),
Argument::BranchDest(BranchDest(
(((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000))
<< 2u8) as _,
)),
],
ins: self, ins: self,
}; };
} }
if ((self.code >> 21u8) & 0x1f) == 4 { if ((self.code >> 21u8) & 0x1f) == 12 && ((self.code >> 16u8) & 0x1f) & 0b11 == 0b10
{
return SimplifiedIns {
mnemonic: "beqlr",
modifiers: {
let mut m = Modifiers::default();
m.lk = self.bit(31);
m
},
args: vec![Argument::CRBit(CRBit(((self.code >> 18u8) & 0x7) as _))],
ins: self,
};
}
if ((self.code >> 21u8) & 0x1f) == 4
&& ((self.code >> 16u8) & 0x1f) & 0b11 == 0b00
&& ((self.code >> 18u8) & 0x7) == 0
{
return SimplifiedIns { return SimplifiedIns {
mnemonic: "bgelr", mnemonic: "bgelr",
modifiers: { modifiers: {
@ -5238,17 +5367,27 @@ impl Ins {
m.lk = self.bit(31); m.lk = self.bit(31);
m m
}, },
args: vec![ args: vec![],
Argument::CRBit(CRBit(((self.code >> 18u8) & 0x7) as _)),
Argument::BranchDest(BranchDest(
(((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000))
<< 2u8) as _,
)),
],
ins: self, ins: self,
}; };
} }
if ((self.code >> 21u8) & 0x1f) == 12 { if ((self.code >> 21u8) & 0x1f) == 4 && ((self.code >> 16u8) & 0x1f) & 0b11 == 0b00
{
return SimplifiedIns {
mnemonic: "bgelr",
modifiers: {
let mut m = Modifiers::default();
m.lk = self.bit(31);
m
},
args: vec![Argument::CRBit(CRBit(((self.code >> 18u8) & 0x7) as _))],
ins: self,
};
}
if ((self.code >> 21u8) & 0x1f) == 12
&& ((self.code >> 16u8) & 0x1f) & 0b11 == 0b01
&& ((self.code >> 18u8) & 0x7) == 0
{
return SimplifiedIns { return SimplifiedIns {
mnemonic: "bgtlr", mnemonic: "bgtlr",
modifiers: { modifiers: {
@ -5256,17 +5395,27 @@ impl Ins {
m.lk = self.bit(31); m.lk = self.bit(31);
m m
}, },
args: vec![ args: vec![],
Argument::CRBit(CRBit(((self.code >> 18u8) & 0x7) as _)),
Argument::BranchDest(BranchDest(
(((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000))
<< 2u8) as _,
)),
],
ins: self, ins: self,
}; };
} }
if ((self.code >> 21u8) & 0x1f) == 4 { if ((self.code >> 21u8) & 0x1f) == 12 && ((self.code >> 16u8) & 0x1f) & 0b11 == 0b01
{
return SimplifiedIns {
mnemonic: "bgtlr",
modifiers: {
let mut m = Modifiers::default();
m.lk = self.bit(31);
m
},
args: vec![Argument::CRBit(CRBit(((self.code >> 18u8) & 0x7) as _))],
ins: self,
};
}
if ((self.code >> 21u8) & 0x1f) == 4
&& ((self.code >> 16u8) & 0x1f) & 0b11 == 0b10
&& ((self.code >> 18u8) & 0x7) == 0
{
return SimplifiedIns { return SimplifiedIns {
mnemonic: "bnelr", mnemonic: "bnelr",
modifiers: { modifiers: {
@ -5274,17 +5423,27 @@ impl Ins {
m.lk = self.bit(31); m.lk = self.bit(31);
m m
}, },
args: vec![ args: vec![],
Argument::CRBit(CRBit(((self.code >> 18u8) & 0x7) as _)),
Argument::BranchDest(BranchDest(
(((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000))
<< 2u8) as _,
)),
],
ins: self, ins: self,
}; };
} }
if ((self.code >> 21u8) & 0x1f) == 12 { if ((self.code >> 21u8) & 0x1f) == 4 && ((self.code >> 16u8) & 0x1f) & 0b11 == 0b10
{
return SimplifiedIns {
mnemonic: "bnelr",
modifiers: {
let mut m = Modifiers::default();
m.lk = self.bit(31);
m
},
args: vec![Argument::CRBit(CRBit(((self.code >> 18u8) & 0x7) as _))],
ins: self,
};
}
if ((self.code >> 21u8) & 0x1f) == 12
&& ((self.code >> 16u8) & 0x1f) & 0b11 == 0b11
&& ((self.code >> 18u8) & 0x7) == 0
{
return SimplifiedIns { return SimplifiedIns {
mnemonic: "bsolr", mnemonic: "bsolr",
modifiers: { modifiers: {
@ -5292,17 +5451,27 @@ impl Ins {
m.lk = self.bit(31); m.lk = self.bit(31);
m m
}, },
args: vec![ args: vec![],
Argument::CRBit(CRBit(((self.code >> 18u8) & 0x7) as _)),
Argument::BranchDest(BranchDest(
(((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000))
<< 2u8) as _,
)),
],
ins: self, ins: self,
}; };
} }
if ((self.code >> 21u8) & 0x1f) == 4 { if ((self.code >> 21u8) & 0x1f) == 12 && ((self.code >> 16u8) & 0x1f) & 0b11 == 0b11
{
return SimplifiedIns {
mnemonic: "bsolr",
modifiers: {
let mut m = Modifiers::default();
m.lk = self.bit(31);
m
},
args: vec![Argument::CRBit(CRBit(((self.code >> 18u8) & 0x7) as _))],
ins: self,
};
}
if ((self.code >> 21u8) & 0x1f) == 4
&& ((self.code >> 16u8) & 0x1f) & 0b11 == 0b11
&& ((self.code >> 18u8) & 0x7) == 0
{
return SimplifiedIns { return SimplifiedIns {
mnemonic: "bnslr", mnemonic: "bnslr",
modifiers: { modifiers: {
@ -5310,13 +5479,20 @@ impl Ins {
m.lk = self.bit(31); m.lk = self.bit(31);
m m
}, },
args: vec![ args: vec![],
Argument::CRBit(CRBit(((self.code >> 18u8) & 0x7) as _)), ins: self,
Argument::BranchDest(BranchDest( };
(((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) }
<< 2u8) as _, if ((self.code >> 21u8) & 0x1f) == 4 && ((self.code >> 16u8) & 0x1f) & 0b11 == 0b11
)), {
], return SimplifiedIns {
mnemonic: "bnslr",
modifiers: {
let mut m = Modifiers::default();
m.lk = self.bit(31);
m
},
args: vec![Argument::CRBit(CRBit(((self.code >> 18u8) & 0x7) as _))],
ins: self, ins: self,
}; };
} }

View File

@ -108,7 +108,6 @@ fn test_ins_bc() {
assert_asm!(0x408600D8, "bne cr1, 0xd8"); assert_asm!(0x408600D8, "bne cr1, 0xd8");
assert_asm!(0x4086FECC, "bne cr1, -0x134"); assert_asm!(0x4086FECC, "bne cr1, -0x134");
assert_asm!(0x409C000C, "bge cr7, 0xc"); assert_asm!(0x409C000C, "bge cr7, 0xc");
// assert_asm!(0x40A10010, "ble+ 0x10");
assert_asm!(0x4180000C, "blt 0xc"); assert_asm!(0x4180000C, "blt 0xc");
assert_asm!(0x4180F9C0, "blt -0x640"); assert_asm!(0x4180F9C0, "blt -0x640");
assert_asm!(0x4181021C, "bgt 0x21c"); assert_asm!(0x4181021C, "bgt 0x21c");
@ -124,15 +123,12 @@ fn test_ins_bc() {
assert_asm!(0x4200F560, "bdnz -0xaa0"); assert_asm!(0x4200F560, "bdnz -0xaa0");
} }
/*
#[test] #[test]
fn test_ins_bcctr() { fn test_ins_bcctr() {
assert_asm!(0x4E800420, "bctr"); assert_asm!(0x4E800420, "bctr");
assert_asm!(0x4E800421, "bctrl"); assert_asm!(0x4E800421, "bctrl");
} }
*/
/*
#[test] #[test]
fn test_ins_bclr() { fn test_ins_bclr() {
assert_asm!(0x4C800020, "bgelr"); assert_asm!(0x4C800020, "bgelr");
@ -146,7 +142,6 @@ fn test_ins_bclr() {
assert_asm!(0x4E800020, "blr"); assert_asm!(0x4E800020, "blr");
assert_asm!(0x4E800021, "blrl"); assert_asm!(0x4E800021, "blrl");
} }
*/
#[test] #[test]
fn test_ins_cmp() { fn test_ins_cmp() {

173
isa.yaml
View File

@ -279,15 +279,15 @@ opcodes:
- name: bcctr - name: bcctr
desc: Branch Conditional to Count Register desc: Branch Conditional to Count Register
bitmask: 0xfc00ffff bitmask: 0xfc007ffe
pattern: 0x4c000210 pattern: 0x4c000420
modifiers: [ LK ] modifiers: [ LK ]
args: [ BO, BI ] args: [ BO, BI ]
uses: [ ctr ] uses: [ ctr ]
- name: bclr - name: bclr
desc: Branch Conditional to Link Register desc: Branch Conditional to Link Register
bitmask: 0xfc00fffe bitmask: 0xfc007ffe
pattern: 0x4c000020 pattern: 0x4c000020
modifiers: [ LK ] modifiers: [ LK ]
args: [ BO, BI ] args: [ BO, BI ]
@ -2033,10 +2033,6 @@ mnemonics:
- name: twui - name: twui
args: [ rA, simm ] args: [ rA, simm ]
condition: TO == 31 condition: TO == 31
# Branches
- name: blr
opcode: bclr
condition: BO == 20 && BI == 0
# Move to special-purpose register # Move to special-purpose register
- name: mtxer - name: mtxer
@ -2091,7 +2087,6 @@ mnemonics:
condition: spr == 571 condition: spr == 571
# Branch Conditional # Branch Conditional
# bc branch if negative # bc branch if negative
- name: blt - name: blt
opcode: bc opcode: bc
@ -2103,7 +2098,6 @@ mnemonics:
modifiers: [ AA, LK ] modifiers: [ AA, LK ]
args: [ crfS, BD ] args: [ crfS, BD ]
condition: BO == 12 && BI & 0b11 == 0b00 condition: BO == 12 && BI & 0b11 == 0b00
# bc branch if not positive # bc branch if not positive
- name: ble - name: ble
opcode: bc opcode: bc
@ -2115,7 +2109,6 @@ mnemonics:
modifiers: [ AA, LK ] modifiers: [ AA, LK ]
args: [ crfS, BD ] args: [ crfS, BD ]
condition: BO == 4 && BI & 0b11 == 0b01 condition: BO == 4 && BI & 0b11 == 0b01
# bc branch if zero # bc branch if zero
- name: beq - name: beq
opcode: bc opcode: bc
@ -2127,7 +2120,6 @@ mnemonics:
modifiers: [ AA, LK ] modifiers: [ AA, LK ]
args: [ crfS, BD ] args: [ crfS, BD ]
condition: BO == 12 && BI & 0b11 == 0b10 condition: BO == 12 && BI & 0b11 == 0b10
# bc branch if not negative # bc branch if not negative
- name: bge - name: bge
opcode: bc opcode: bc
@ -2139,7 +2131,6 @@ mnemonics:
modifiers: [ AA, LK ] modifiers: [ AA, LK ]
args: [ crfS, BD ] args: [ crfS, BD ]
condition: BO == 4 && BI & 0b11 == 0b00 condition: BO == 4 && BI & 0b11 == 0b00
# bc branch if positive # bc branch if positive
- name: bgt - name: bgt
opcode: bc opcode: bc
@ -2151,7 +2142,6 @@ mnemonics:
modifiers: [ AA, LK ] modifiers: [ AA, LK ]
args: [ crfS, BD ] args: [ crfS, BD ]
condition: BO == 12 && BI & 0b11 == 0b01 condition: BO == 12 && BI & 0b11 == 0b01
# bc branch if not zero # bc branch if not zero
- name: bne - name: bne
opcode: bc opcode: bc
@ -2163,7 +2153,6 @@ mnemonics:
modifiers: [ AA, LK ] modifiers: [ AA, LK ]
args: [ crfS, BD ] args: [ crfS, BD ]
condition: BO == 4 && BI & 0b11 == 0b10 condition: BO == 4 && BI & 0b11 == 0b10
# bc branch if summary overflow # bc branch if summary overflow
- name: bso - name: bso
opcode: bc opcode: bc
@ -2175,7 +2164,6 @@ mnemonics:
modifiers: [ AA, LK ] modifiers: [ AA, LK ]
args: [ crfS, BD ] args: [ crfS, BD ]
condition: BO == 12 && BI & 0b11 == 0b11 condition: BO == 12 && BI & 0b11 == 0b11
# bc branch if not summary overflow # bc branch if not summary overflow
- name: bns - name: bns
opcode: bc opcode: bc
@ -2201,85 +2189,176 @@ mnemonics:
# TODO support conditional bd... # TODO support conditional bd...
# Branch Conditional to Count Register # Branch Conditional to Count Register
# bcctr branch always
- name: bctr
opcode: bcctr
modifiers: [ LK ]
condition: BO == 20 && BI == 0
# bcctr branch if negative
- name: bltctr - name: bltctr
opcode: bcctr opcode: bcctr
modifiers: [ LK ] modifiers: [ LK ]
args: [ crfS, BD ] condition: BO == 12 && BI & 0b11 == 0b00 && crfS == 0
condition: BO == 12 - name: bltctr
opcode: bcctr
modifiers: [ LK ]
args: [ crfS ]
condition: BO == 12 && BI & 0b11 == 0b00
# bcctr branch if not positive
- name: blectr - name: blectr
opcode: bcctr opcode: bcctr
modifiers: [ LK ] modifiers: [ LK ]
args: [ crfS, BD ] condition: BO == 4 && BI & 0b11 == 0b01 && crfS == 0
condition: BO == 4 - name: blectr
opcode: bcctr
modifiers: [ LK ]
args: [ crfS ]
condition: BO == 4 && BI & 0b11 == 0b01
# bcctr branch if zero
- name: beqctr - name: beqctr
opcode: bcctr opcode: bcctr
modifiers: [ LK ] modifiers: [ LK ]
args: [ crfS, BD ] condition: BO == 12 && BI & 0b11 == 0b10 && crfS == 0
condition: BO == 12 - name: beqctr
opcode: bcctr
modifiers: [ LK ]
args: [ crfS ]
condition: BO == 12 && BI & 0b11 == 0b10
# bcctr branch if not negative
- name: bgectr - name: bgectr
opcode: bcctr opcode: bcctr
modifiers: [ LK ] modifiers: [ LK ]
args: [ crfS, BD ] condition: BO == 4 && BI & 0b11 == 0b00 && crfS == 0
condition: BO == 4 - name: bgectr
opcode: bcctr
modifiers: [ LK ]
args: [ crfS ]
condition: BO == 4 && BI & 0b11 == 0b00
# bcctr branch if positive
- name: bgtctr - name: bgtctr
opcode: bcctr opcode: bcctr
modifiers: [ LK ] modifiers: [ LK ]
args: [ crfS, BD ] condition: BO == 12 && BI & 0b11 == 0b01 && crfS == 0
condition: BO == 12 - name: bgtctr
opcode: bcctr
modifiers: [ LK ]
args: [ crfS ]
condition: BO == 12 && BI & 0b11 == 0b01
# bcctr branch if not zero
- name: bnectr - name: bnectr
opcode: bcctr opcode: bcctr
modifiers: [ LK ] modifiers: [ LK ]
args: [ crfS, BD ] condition: BO == 4 && BI & 0b11 == 0b10 && crfS == 0
condition: BO == 4 - name: bnectr
opcode: bcctr
modifiers: [ LK ]
args: [ crfS ]
condition: BO == 4 && BI & 0b11 == 0b10
# bcctr branch if summary overflow
- name: bsoctr - name: bsoctr
opcode: bcctr opcode: bcctr
modifiers: [ LK ] modifiers: [ LK ]
args: [ crfS, BD ] condition: BO == 12 && BI & 0b11 == 0b11 && crfS == 0
condition: BO == 12 - name: bsoctr
opcode: bcctr
modifiers: [ LK ]
args: [ crfS ]
condition: BO == 12 && BI & 0b11 == 0b11
# bcctr branch if not summary overflow
- name: bnsctr - name: bnsctr
opcode: bcctr opcode: bcctr
modifiers: [ LK ] modifiers: [ LK ]
args: [ crfS, BD ] condition: BO == 4 && BI & 0b11 == 0b11 && crfS == 0
condition: BO == 4 - name: bnsctr
opcode: bcctr
modifiers: [ LK ]
args: [ crfS ]
condition: BO == 4 && BI & 0b11 == 0b11
# Branch Conditional to Link Register # Branch Conditional to Link Register
# bclr branch always
- name: blr
opcode: bclr
modifiers: [ LK ]
condition: BO == 20 && BI == 0
# bclr branch if negative
- name: bltlr - name: bltlr
opcode: bclr opcode: bclr
modifiers: [ LK ] modifiers: [ LK ]
args: [ crfS, BD ] condition: BO == 12 && BI & 0b11 == 0b00 && crfS == 0
condition: BO == 12 - name: bltlr
opcode: bclr
modifiers: [ LK ]
args: [ crfS ]
condition: BO == 12 && BI & 0b11 == 0b00
# bclr branch if not positive
- name: blelr - name: blelr
opcode: bclr opcode: bclr
modifiers: [ LK ] modifiers: [ LK ]
args: [ crfS, BD ] condition: BO == 4 && BI & 0b11 == 0b01 && crfS == 0
condition: BO == 4 - name: blelr
opcode: bclr
modifiers: [ LK ]
args: [ crfS ]
condition: BO == 4 && BI & 0b11 == 0b01
# bclr branch if zero
- name: beqlr - name: beqlr
opcode: bclr opcode: bclr
modifiers: [ LK ] modifiers: [ LK ]
args: [ crfS, BD ] condition: BO == 12 && BI & 0b11 == 0b10 && crfS == 0
condition: BO == 12 - name: beqlr
opcode: bclr
modifiers: [ LK ]
args: [ crfS ]
condition: BO == 12 && BI & 0b11 == 0b10
# bclr branch if not negative
- name: bgelr - name: bgelr
opcode: bclr opcode: bclr
modifiers: [ LK ] modifiers: [ LK ]
args: [ crfS, BD ] condition: BO == 4 && BI & 0b11 == 0b00 && crfS == 0
condition: BO == 4 - name: bgelr
opcode: bclr
modifiers: [ LK ]
args: [ crfS ]
condition: BO == 4 && BI & 0b11 == 0b00
# bclr branch if positive
- name: bgtlr - name: bgtlr
opcode: bclr opcode: bclr
modifiers: [ LK ] modifiers: [ LK ]
args: [ crfS, BD ] condition: BO == 12 && BI & 0b11 == 0b01 && crfS == 0
condition: BO == 12 - name: bgtlr
opcode: bclr
modifiers: [ LK ]
args: [ crfS ]
condition: BO == 12 && BI & 0b11 == 0b01
# bclr branch if not zero
- name: bnelr - name: bnelr
opcode: bclr opcode: bclr
modifiers: [ LK ] modifiers: [ LK ]
args: [ crfS, BD ] condition: BO == 4 && BI & 0b11 == 0b10 && crfS == 0
condition: BO == 4 - name: bnelr
opcode: bclr
modifiers: [ LK ]
args: [ crfS ]
condition: BO == 4 && BI & 0b11 == 0b10
# bclr branch if summary overflow
- name: bsolr - name: bsolr
opcode: bclr opcode: bclr
modifiers: [ LK ] modifiers: [ LK ]
args: [ crfS, BD ] condition: BO == 12 && BI & 0b11 == 0b11 && crfS == 0
condition: BO == 12 - name: bsolr
opcode: bclr
modifiers: [ LK ]
args: [ crfS ]
condition: BO == 12 && BI & 0b11 == 0b11
# bclr branch if not summary overflow
- name: bnslr - name: bnslr
opcode: bclr opcode: bclr
modifiers: [ LK ] modifiers: [ LK ]
args: [ crfS, BD ] condition: BO == 4 && BI & 0b11 == 0b11 && crfS == 0
condition: BO == 4 - name: bnslr
opcode: bclr
modifiers: [ LK ]
args: [ crfS ]
condition: BO == 4 && BI & 0b11 == 0b11