Merge pull request #39 from InusualZ/improv

General ISA Improvement
This commit is contained in:
Richard Patel 2022-06-01 18:21:07 +02:00 committed by GitHub
commit 619c935dc4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 476 additions and 442 deletions

View File

@ -161,14 +161,22 @@ impl Ins {
self.0.field_crm() as i64
}
#[getter]
fn ps_l(&self) -> i64 {
self.0.field_ps_l() as i64
fn ps_I(&self) -> i64 {
self.0.field_ps_I() as i64
}
#[getter]
fn ps_IX(&self) -> i64 {
self.0.field_ps_IX() as i64
}
#[getter]
fn ps_W(&self) -> i64 {
self.0.field_ps_W() as i64
}
#[getter]
fn ps_WX(&self) -> i64 {
self.0.field_ps_WX() as i64
}
#[getter]
fn ps_NB(&self) -> i64 {
self.0.field_NB() as i64
}

File diff suppressed because it is too large Load Diff

View File

@ -229,6 +229,8 @@ pub struct Ins {
}
impl Ins {
const BLR: u32 = 0x4e800020;
/// Constructs an instruction from the given machine code and address.
pub fn new(code: u32, addr: u32) -> Self {
Self {
@ -283,19 +285,24 @@ impl Ins {
pub fn branch_dest(&self) -> Option<u32> {
self.branch_offset().and_then(|offset| {
if offset < 0 {
self.addr.checked_sub((-offset) as u32)
if self.field_AA() {
Some(offset as u32)
} else {
self.addr.checked_add(offset as u32)
if offset < 0 {
self.addr.checked_sub((-offset) as u32)
} else {
self.addr.checked_add(offset as u32)
}
}
})
}
pub fn is_branch(&self) -> bool {
match self.op {
Opcode::B | Opcode::Bc | Opcode::Bcctr | Opcode::Bclr => true,
_ => false,
}
matches!(self.op, Opcode::B | Opcode::Bc | Opcode::Bcctr | Opcode::Bclr)
}
pub fn is_direct_branch(&self) -> bool {
matches!(self.op, Opcode::B | Opcode::Bc)
}
pub fn is_unconditional_branch(&self) -> bool {
@ -312,9 +319,10 @@ impl Ins {
self.is_branch() && !self.is_unconditional_branch()
}
#[inline]
pub fn is_blr(&self) -> bool {
// self.op == Opcode::Bclr && self.is_unconditional_branch() && !self.field_LK()
self.code == 0x4e800020
self.code == Ins::BLR
}
}

View File

@ -94,6 +94,7 @@ fn test_ins_b() {
assert_asm!(0x4823B4D9, "bl 0x23b4d8");
assert_asm!(0x4BE03C99, "bl -0x1fc368");
assert_asm!(0x4BDC1A59, "bl -0x23e5a8");
assert_asm!(0x48000063, "bla 0x60");
}
#[test]
@ -482,7 +483,7 @@ fn test_ins_lwzx() {
#[test]
fn test_ins_mfcr() {
assert_asm!(0x7C000026, "mfcr cr0");
assert_asm!(0x7C000026, "mfcr r0");
}
#[test]
@ -622,8 +623,8 @@ fn test_ins_psq_lx() {
frD(FPR(0)),
rA(GPR(0)),
rB(GPR(0)),
ps_W(OpaqueU(0)),
ps_l(GQR(0))
ps_WX(OpaqueU(0)),
ps_IX(GQR(0))
]
);
assert_eq!(ins.defs(), vec![frD(FPR(0))]);
@ -708,6 +709,11 @@ fn test_ins_ps_merge11() {
assert_asm!(0x10AA14E0, "ps_merge11 f5, f10, f2");
}
#[test]
fn test_ins_ps_mr() {
assert_asm!(0x10200090, "ps_mr f1, f0");
}
#[test]
fn test_ins_ps_msub() {
assert_asm!(0x10A53778, "ps_msub f5, f5, f29, f6");
@ -783,6 +789,9 @@ fn test_ins_rlwimi() {
fn test_ins_rlwinm() {
assert_asm!(0x54000423, "rlwinm. r0, r0, 0, 16, 17");
assert_asm!(0x54000432, "rlwinm r0, r0, 0, 16, 25");
// mnemonics
assert_asm!(0x57E5103A, "slwi r5, r31, 2");
}
#[test]
@ -815,6 +824,7 @@ fn test_ins_srawi() {
#[test]
fn test_ins_srw() {
assert_asm!(0x7C001C30, "srw r0, r0, r3");
assert_asm!(0x7C600430, "srw r0, r3, r0");
}
#[test]
@ -957,6 +967,7 @@ fn test_ins_sync() {
#[test]
fn test_ins_xor() {
assert_asm!(0x7C052A78, "xor r5, r0, r5");
assert_asm!(0x7D275279, "xor. r7, r9, r10");
}
#[test]

View File

@ -136,7 +136,7 @@ impl Field {
if self.signed {
let mask2 = 1u32 << (self.bits.0.len() - 1);
let mask2 = LitInt::new(&format!("0x{:x}", mask2), Span::call_site());
val = quote!(((#val ^ #mask2).wrapping_sub(#mask2)))
val = quote!((((#val ^ #mask2).wrapping_sub(#mask2)) as i32))
}
let val_shift = self.shift_left;

205
isa.yaml
View File

@ -22,6 +22,9 @@ fields:
- name: BI
arg: OpaqueU
bits: 11..16
- name: BH
arg: OpaqueU
bits: 19..21
- name: BD
arg: BranchDest
bits: 16..30
@ -109,12 +112,18 @@ fields:
arg: OpaqueU
bits: 12..20
# Paired single fields
- name: ps_l
- name: ps_I
arg: GQR
bits: 17..20
- name: ps_IX
arg: GQR
bits: 22..25
- name: ps_W
arg: OpaqueU
bits: 16..17
- name: ps_WX
arg: OpaqueU
bits: 21..22
# Misc
- name: NB
arg: OpaqueU
@ -136,6 +145,10 @@ fields:
arg: OpaqueU
desc: Bitset for tw and twi
bits: 6..11
- name: L
arg: OpaqueU
desc: Bitset for cmp, cmpi, cmpl, cmpli
bits: 10..11
- name: xer
- name: ctr
- name: lr
@ -274,14 +287,14 @@ opcodes:
desc: Branch
bitmask: 0xfc000000
pattern: 0x48000000
modifiers: [ AA, LK ]
modifiers: [ LK, AA ]
args: [ LI ]
- name: bc
desc: Branch Conditional
bitmask: 0xfc000000
pattern: 0x40000000
modifiers: [ AA, LK ]
modifiers: [ LK, AA ]
args: [ BO, BI, BD ]
- name: bcctr
@ -289,7 +302,7 @@ opcodes:
bitmask: 0xfc007ffe
pattern: 0x4c000420
modifiers: [ LK ]
args: [ BO, BI ]
args: [ BO, BI, BH ]
uses: [ ctr ]
- name: bclr
@ -297,14 +310,14 @@ opcodes:
bitmask: 0xfc007ffe
pattern: 0x4c000020
modifiers: [ LK ]
args: [ BO, BI ]
args: [ BO, BI, BH ]
uses: [ lr ]
- name: cmp
desc: Compare
bitmask: 0xfc4007ff
pattern: 0x7c000000
args: [ crfD, rA, rB ]
args: [ crfD, L, rA, rB ]
defs: [ crfD ]
uses: [ rA, rB ]
@ -312,7 +325,7 @@ opcodes:
desc: Compare Immediate
bitmask: 0xfc400000
pattern: 0x2c000000
args: [ crfD, rA, simm ]
args: [ crfD, L, rA, simm ]
defs: [ crfD ]
uses: [ rA ]
@ -320,7 +333,7 @@ opcodes:
desc: Compare Logical
bitmask: 0xfc4007ff
pattern: 0x7c000040
args: [ crfD, rA, rB ]
args: [ crfD, L, rA, rB ]
defs: [ crfD ]
uses: [ rA, rB ]
@ -328,7 +341,7 @@ opcodes:
desc: Compare Logical Immediate
bitmask: 0xfc400000
pattern: 0x28000000
args: [ crfD, rA, uimm ]
args: [ crfD, L, rA, uimm ]
defs: [ crfD ]
uses: [ rA ]
@ -1050,14 +1063,13 @@ opcodes:
desc: Move from Condition Register
bitmask: 0xfc1fffff
pattern: 0x7c000026
args: [ crfD ]
defs: [ crfD ]
args: [ rD ]
defs: [ rD ]
- name: mffs
desc: Move from FPSCR
bitmask: 0xfc1ffffe
pattern: 0xfc00048e
modifiers: [ Rc ]
args: [ frD ]
defs: [ frD ]
@ -1186,7 +1198,6 @@ opcodes:
desc: Multiply Low Immediate
bitmask: 0xfc000000
pattern: 0x1c000000
modifiers: [ Rc ]
args: [ rD, rA, simm ]
defs: [ rD ]
uses: [ rA ]
@ -1265,7 +1276,7 @@ opcodes:
desc: Paired Single Quantized Load
bitmask: 0xfc000000
pattern: 0xe0000000
args: [ frD, ps_offset, rA, ps_W, ps_l ]
args: [ frD, ps_offset, rA, ps_W, ps_I ]
defs: [ frD ]
uses: [ rA.nz ]
@ -1273,7 +1284,7 @@ opcodes:
desc: Paired Single Quantized Load with Update
bitmask: 0xfc000000
pattern: 0xe4000000
args: [ frD, ps_offset, rA, ps_W, ps_l ]
args: [ frD, ps_offset, rA, ps_W, ps_I ]
defs: [ frD, rA ]
uses: [ rA ]
@ -1281,7 +1292,7 @@ opcodes:
desc: Paired Single Quantized Load with Update Indexed
bitmask: 0xfc00007f
pattern: 0x1000004c
args: [ frD, rA, rB, ps_W, ps_l ]
args: [ frD, rA, rB, ps_WX, ps_IX ]
defs: [ frD, rA ]
uses: [ rA, rB ]
@ -1289,7 +1300,7 @@ opcodes:
desc: Paired Single Quantized Load Indexed
bitmask: 0xfc00007f
pattern: 0x1000000c
args: [ frD, rA, rB, ps_W, ps_l ]
args: [ frD, rA, rB, ps_WX, ps_IX ]
defs: [ frD ]
uses: [ rA.nz, rB ]
@ -1297,14 +1308,14 @@ opcodes:
desc: Paired Single Quantized Store
bitmask: 0xfc000000
pattern: 0xf0000000
args: [ frS, ps_offset, rA, ps_W, ps_l ]
args: [ frS, ps_offset, rA, ps_W, ps_I ]
uses: [ frS, rA.nz ]
- name: psq_stu
desc: Paired Single Quantized Store with Update
bitmask: 0xfc000000
pattern: 0xf4000000
args: [ frS, ps_offset, rA, ps_W, ps_l ]
args: [ frS, ps_offset, rA, ps_W, ps_I ]
defs: [ rA ]
uses: [ frS, rA ]
@ -1312,7 +1323,7 @@ opcodes:
desc: Paired Single Quantized Store with Update Indexed
bitmask: 0xfc00007f
pattern: 0x1000004e
args: [ frS, rA, rB, ps_W, ps_l ]
args: [ frS, rA, rB, ps_WX, ps_IX ]
defs: [ rA ]
uses: [ frS, rA, rB ]
@ -1320,14 +1331,13 @@ opcodes:
desc: Paired Single Quantized Store Indexed
bitmask: 0xfc00007f
pattern: 0x1000000e
args: [ frS, rA, rB, ps_W, ps_l ]
args: [ frS, rA, rB, ps_WX, ps_IX ]
uses: [ frS, rA.nz, rB ]
- name: ps_abs
desc: Paired Single Absolute Value
bitmask: 0xfc1f07fe
pattern: 0x10000210
modifiers: [ Rc ]
args: [ frD, frB ]
defs: [ frD ]
uses: [ frB ]
@ -1336,7 +1346,6 @@ opcodes:
desc: Paired Single Add
bitmask: 0xfc0007fe
pattern: 0x1000002a
modifiers: [ Rc ]
args: [ frD, frA, frB ]
defs: [ frD ]
uses: [ frA, frB ]
@ -1377,7 +1386,6 @@ opcodes:
desc: Paired Single Divide
bitmask: 0xfc0007fe
pattern: 0x10000024
modifiers: [ Rc ]
args: [ frD, frA, frB ]
defs: [ frD ]
uses: [ frA, frB ]
@ -1386,7 +1394,6 @@ opcodes:
desc: Paired Single Multiply-Add
bitmask: 0xfc00003e
pattern: 0x1000003a
modifiers: [ Rc ]
args: [ frD, frA, frC, frB ]
defs: [ frD ]
uses: [ frA, frC, frB ]
@ -1395,7 +1402,6 @@ opcodes:
desc: Paired Single Multiply-Add Scalar high
bitmask: 0xfc00003e
pattern: 0x1000001c
modifiers: [ Rc ]
args: [ frD, frA, frC, frB ]
defs: [ frD ]
uses: [ frA, frC, frB ]
@ -1404,7 +1410,6 @@ opcodes:
desc: Paired Single Multiply-Add Scalar low
bitmask: 0xfc00003e
pattern: 0x1000001e
modifiers: [ Rc ]
args: [ frD, frA, frC, frB ]
defs: [ frD ]
uses: [ frA, frC, frB ]
@ -1413,7 +1418,6 @@ opcodes:
desc: Paired Single MERGE high
bitmask: 0xfc0007fe
pattern: 0x10000420
modifiers: [ Rc ]
args: [ frD, frA, frB ]
defs: [ frD ]
uses: [ frA, frB ]
@ -1422,7 +1426,6 @@ opcodes:
desc: Paired Single MERGE direct
bitmask: 0xfc0007fe
pattern: 0x10000460
modifiers: [ Rc ]
args: [ frD, frA, frB ]
defs: [ frD ]
uses: [ frA, frB ]
@ -1431,7 +1434,6 @@ opcodes:
desc: Paired Single MERGE swapped
bitmask: 0xfc0007fe
pattern: 0x100004a0
modifiers: [ Rc ]
args: [ frD, frA, frB ]
defs: [ frD ]
uses: [ frA, frB ]
@ -1440,7 +1442,6 @@ opcodes:
desc: Paired Single MERGE low
bitmask: 0xfc0007fe
pattern: 0x100004e0
modifiers: [ Rc ]
args: [ frD, frA, frB ]
defs: [ frD ]
uses: [ frA, frB ]
@ -1449,8 +1450,7 @@ opcodes:
desc: Paired Single Move Register
bitmask: 0xfc1f07fe
pattern: 0x10000090
modifiers: [ Rc ]
args: [ frD, frA, frB ]
args: [ frD, frB ]
defs: [ frD ]
uses: [ frB ]
@ -1458,7 +1458,6 @@ opcodes:
desc: Paired Single Multiply-Subtract
bitmask: 0xfc00003e
pattern: 0x10000038
modifiers: [ Rc ]
args: [ frD, frA, frC, frB ]
defs: [ frD ]
uses: [ frA, frC, frB ]
@ -1467,7 +1466,6 @@ opcodes:
desc: Paired Single Multiply
bitmask: 0xfc00f83e
pattern: 0x10000032
modifiers: [ Rc ]
args: [ frD, frA, frC ]
defs: [ frD ]
uses: [ frA, frC ]
@ -1476,7 +1474,6 @@ opcodes:
desc: Paired Single Multiply Scalar high
bitmask: 0xfc00f83e
pattern: 0x10000018
modifiers: [ Rc ]
args: [ frD, frA, frC ]
defs: [ frD ]
uses: [ frA, frC ]
@ -1485,7 +1482,6 @@ opcodes:
desc: Paired Single Multiply Scalar low
bitmask: 0xfc00f83e
pattern: 0x1000001a
modifiers: [ Rc ]
args: [ frD, frA, frC ]
defs: [ frD ]
uses: [ frA, frC ]
@ -1494,7 +1490,6 @@ opcodes:
desc: Paired Single Negative Absolute Value
bitmask: 0xfc1f07fe
pattern: 0x10000110
modifiers: [ Rc ]
args: [ frD, frB ]
defs: [ frD ]
uses: [ frB ]
@ -1503,7 +1498,6 @@ opcodes:
desc: Paired Single Negate
bitmask: 0xfc1f07fe
pattern: 0x10000050
modifiers: [ Rc ]
args: [ frD, frB ]
defs: [ frD ]
uses: [ frB ]
@ -1512,7 +1506,6 @@ opcodes:
desc: Paired Single Negative Multiply-Add
bitmask: 0xfc00003e
pattern: 0x1000003e
modifiers: [ Rc ]
args: [ frD, frA, frC, frB ]
defs: [ frD ]
uses: [ frA, frC, frB ]
@ -1521,7 +1514,6 @@ opcodes:
desc: Paired Single Negative Multiply-Subtract
bitmask: 0xfc00003e
pattern: 0x1000003c
modifiers: [ Rc ]
args: [ frD, frA, frC, frB ]
defs: [ frD ]
uses: [ frA, frC, frB ]
@ -1530,7 +1522,6 @@ opcodes:
desc: Paired Single Reciprocal Estimate
bitmask: 0xfc1f07fe
pattern: 0x10000030
modifiers: [ Rc ]
args: [ frD, frB ]
defs: [ frD ]
uses: [ frB ]
@ -1539,7 +1530,6 @@ opcodes:
desc: Paired Single Reciprocal Square Root Estimate
bitmask: 0xfc1f07fe
pattern: 0x10000034
modifiers: [ Rc ]
args: [ frD, frB ]
defs: [ frD ]
uses: [ frB ]
@ -1548,7 +1538,6 @@ opcodes:
desc: Paired Single Select
bitmask: 0xfc00003e
pattern: 0x1000002e
modifiers: [ Rc ]
args: [ frD, frA, frC, frB ]
defs: [ frD ]
uses: [ frA, frC, frB ]
@ -1557,7 +1546,6 @@ opcodes:
desc: Paired Single Subtract
bitmask: 0xfc0007fe
pattern: 0x10000028
modifiers: [ Rc ]
args: [ frD, frA, frB ]
defs: [ frD ]
uses: [ frA, frB ]
@ -1566,7 +1554,6 @@ opcodes:
desc: Paired Single vector SUM high
bitmask: 0xfc00003e
pattern: 0x10000014
modifiers: [ Rc ]
args: [ frD, frA, frC, frB ]
defs: [ frD ]
uses: [ frA, frC, frB ]
@ -1575,7 +1562,6 @@ opcodes:
desc: Paired Single vector SUM low
bitmask: 0xfc00003e
pattern: 0x10000016
modifiers: [ Rc ]
args: [ frD, frA, frC, frB ]
defs: [ frD ]
uses: [ frA, frC, frB ]
@ -1649,7 +1635,7 @@ opcodes:
bitmask: 0xfc0007fe
pattern: 0x7c000430
modifiers: [ Rc ]
args: [ rS, rA, rB ]
args: [ rA, rS, rB ]
defs: [ rA ]
uses: [ rA, rB ]
@ -1940,6 +1926,7 @@ opcodes:
desc: XOR
bitmask: 0xfc0007fe
pattern: 0x7c000278
modifiers: [ Rc ]
args: [ rA, rS, rB ]
defs: [ rA ]
uses: [ rS, rB ]
@ -1989,44 +1976,80 @@ mnemonics:
condition: MB == 0 && ME == 31
- name: slwi
opcode: rlwinm
args: [ rA, rS, ME ]
args: [ rA, rS, SH ]
condition: MB == 0 && 31 - SH == ME
- name: srwi
opcode: rlwinm
args: [ rA, rS, MB ]
condition: ME == 31 && 32 - MB == SH
# Compares
- name: cmpw
opcode: cmp
args: [ rA, rB ]
condition: crfD == 0
- name: cmpw
opcode: cmp
args: [ crfD, rA, rB ]
- name: cmplw
opcode: cmpl
args: [ rA, rB ]
condition: crfD == 0
- name: cmplw
opcode: cmpl
args: [ crfD, rA, rB ]
# Compares Word
- name: cmpwi
opcode: cmpi
args: [ rA, simm ]
condition: crfD == 0
condition: crfD == 0 && L == 0
- name: cmpwi
opcode: cmpi
args: [ crfD, rA, simm ]
condition: crfD == 0
condition: L == 0
- name: cmpw
opcode: cmp
args: [ rA, rB ]
condition: crfD == 0 && L == 0
- name: cmpw
opcode: cmp
args: [ crfD, rA, rB ]
condition: L == 0
- name: cmplwi
opcode: cmpli
args: [ rA, uimm ]
condition: crfD == 0
condition: crfD == 0 && L == 0
- name: cmplwi
opcode: cmpli
args: [ crfD, rA, uimm ]
condition: crfD == 0
condition: L == 0
- name: cmplw
opcode: cmpl
args: [ rA, rB ]
condition: crfD == 0 && L == 0
- name: cmplw
opcode: cmpl
args: [ crfD, rA, rB ]
condition: L == 0
# Compares Doubleword
- name: cmpdi
opcode: cmpi
args: [ rA, simm ]
condition: crfD == 0 && L == 1
- name: cmpdi
opcode: cmpi
args: [ crfD, rA, simm ]
condition: L == 1
- name: cmpd
opcode: cmp
args: [ rA, rB ]
condition: crfD == 0 && L == 1
- name: cmpd
opcode: cmp
args: [ crfD, rA, rB ]
condition: L == 1
- name: cmpldi
opcode: cmpli
args: [ rA, uimm ]
condition: crfD == 0 && L == 1
- name: cmpldi
opcode: cmpli
args: [ crfD, rA, uimm ]
condition: L == 1
- name: cmpld
opcode: cmpl
args: [ rA, rB ]
condition: crfD == 0 && L == 1
- name: cmpld
opcode: cmpl
args: [ crfD, rA, rB ]
condition: L == 1
# Condition Register Logical
- name: crset
@ -2080,10 +2103,6 @@ mnemonics:
opcode: mtspr
args: [ rS ]
condition: spr == 397
- name: mttdu
opcode: mtspr
args: [ rS ]
condition: spr == 571
# Move from special-purpose register
- name: mfxer
@ -2106,114 +2125,110 @@ mnemonics:
opcode: mfspr
args: [ rD ]
condition: spr == 397
- name: mftdu
opcode: mfspr
args: [ rD ]
condition: spr == 571
# Branch Conditional
# bc branch always
- name: b
opcode: bc
modifiers: [ AA, LK ]
modifiers: [ LK, AA ]
condition: BO == 20 && BI == 0
# bc branch if negative
- name: blt
opcode: bc
modifiers: [ AA, LK ]
modifiers: [ LK, AA ]
args: [ BD ]
condition: BO == 12 && BI & 0b11 == 0b00 && crfS == 0
- name: blt
opcode: bc
modifiers: [ AA, LK ]
modifiers: [ LK, AA ]
args: [ crfS, BD ]
condition: BO == 12 && BI & 0b11 == 0b00
# bc branch if not positive
- name: ble
opcode: bc
modifiers: [ AA, LK ]
modifiers: [ LK, AA ]
args: [ BD ]
condition: BO == 4 && BI & 0b11 == 0b01 && crfS == 0
- name: ble
opcode: bc
modifiers: [ AA, LK ]
modifiers: [ LK, AA ]
args: [ crfS, BD ]
condition: BO == 4 && BI & 0b11 == 0b01
# bc branch if zero
- name: beq
opcode: bc
modifiers: [ AA, LK ]
modifiers: [ LK, AA ]
args: [ BD ]
condition: BO == 12 && BI & 0b11 == 0b10 && crfS == 0
- name: beq
opcode: bc
modifiers: [ AA, LK ]
modifiers: [ LK, AA ]
args: [ crfS, BD ]
condition: BO == 12 && BI & 0b11 == 0b10
# bc branch if not negative
- name: bge
opcode: bc
modifiers: [ AA, LK ]
modifiers: [ LK, AA ]
args: [ BD ]
condition: BO == 4 && BI & 0b11 == 0b00 && crfS == 0
- name: bge
opcode: bc
modifiers: [ AA, LK ]
modifiers: [ LK, AA ]
args: [ crfS, BD ]
condition: BO == 4 && BI & 0b11 == 0b00
# bc branch if positive
- name: bgt
opcode: bc
modifiers: [ AA, LK ]
modifiers: [ LK, AA ]
args: [ BD ]
condition: BO == 12 && BI & 0b11 == 0b01 && crfS == 0
- name: bgt
opcode: bc
modifiers: [ AA, LK ]
modifiers: [ LK, AA ]
args: [ crfS, BD ]
condition: BO == 12 && BI & 0b11 == 0b01
# bc branch if not zero
- name: bne
opcode: bc
modifiers: [ AA, LK ]
modifiers: [ LK, AA ]
args: [ BD ]
condition: BO == 4 && BI & 0b11 == 0b10 && crfS == 0
- name: bne
opcode: bc
modifiers: [ AA, LK ]
modifiers: [ LK, AA ]
args: [ crfS, BD ]
condition: BO == 4 && BI & 0b11 == 0b10
# bc branch if summary overflow
- name: bso
opcode: bc
modifiers: [ AA, LK ]
modifiers: [ LK, AA ]
args: [ BD ]
condition: BO == 12 && BI & 0b11 == 0b11 && crfS == 0
- name: bso
opcode: bc
modifiers: [ AA, LK ]
modifiers: [ LK, AA ]
args: [ crfS, BD ]
condition: BO == 12 && BI & 0b11 == 0b11
# bc branch if not summary overflow
- name: bns
opcode: bc
modifiers: [ AA, LK ]
modifiers: [ LK, AA ]
args: [ BD ]
condition: BO == 4 && BI & 0b11 == 0b11 && crfS == 0
- name: bns
opcode: bc
modifiers: [ AA, LK ]
modifiers: [ LK, AA ]
args: [ crfS, BD ]
condition: BO == 4 && BI & 0b11 == 0b11
- name: bdnz
opcode: bc
modifiers: [ AA, LK ]
modifiers: [ LK, AA ]
args: [ BD ]
condition: BO == 16 && BI == 0
- name: bdz
opcode: bc
modifiers: [ AA, LK ]
modifiers: [ LK, AA ]
args: [ BD ]
condition: BO == 18 && BI == 0
# TODO support conditional bd...