bcx partially implemented
This commit is contained in:
@@ -36,6 +36,9 @@ void broadway::execute(ircolib::u32 instr, mem &mem) {
|
|||||||
case 15: // addis rd, ra, simm
|
case 15: // addis rd, ra, simm
|
||||||
addis(instr);
|
addis(instr);
|
||||||
break;
|
break;
|
||||||
|
case 16: // bcx BO, BI, target
|
||||||
|
bcx(instr);
|
||||||
|
break;
|
||||||
case 18: // bx target
|
case 18: // bx target
|
||||||
bx(instr);
|
bx(instr);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ struct broadway {
|
|||||||
void addi(ircolib::u32);
|
void addi(ircolib::u32);
|
||||||
void ori(ircolib::u32);
|
void ori(ircolib::u32);
|
||||||
void bx(ircolib::u32);
|
void bx(ircolib::u32);
|
||||||
|
void bcx(ircolib::u32);
|
||||||
void move_spr(ircolib::u32);
|
void move_spr(ircolib::u32);
|
||||||
void stwu(ircolib::u32, mem &);
|
void stwu(ircolib::u32, mem &);
|
||||||
void sth(ircolib::u32, mem &);
|
void sth(ircolib::u32, mem &);
|
||||||
|
|||||||
@@ -27,14 +27,54 @@ void broadway::bx(ircolib::u32 instr) {
|
|||||||
const bool link = instr & 1;
|
const bool link = instr & 1;
|
||||||
const bool absolute = instr & 2;
|
const bool absolute = instr & 2;
|
||||||
|
|
||||||
ircolib::s32 LI = (ircolib::s32(instr << 6) >> 6) & 0x03FFFFFC;
|
ircolib::s32 li = (ircolib::s32(instr << 6) >> 6) & 0xFFFFFFFC;
|
||||||
if (!absolute)
|
if (!absolute)
|
||||||
LI += pc - 4;
|
li += pc - 4;
|
||||||
|
|
||||||
if (link)
|
if (link)
|
||||||
lr = pc;
|
lr = pc;
|
||||||
|
|
||||||
pc = LI;
|
pc = li;
|
||||||
|
}
|
||||||
|
|
||||||
|
void broadway::bcx(ircolib::u32 instr) {
|
||||||
|
const bool link = instr & 1;
|
||||||
|
const bool absolute = instr & 2;
|
||||||
|
|
||||||
|
ircolib::s32 bd = (ircolib::s32(instr << 16) >> 16) & 0xFFFFFFFC;
|
||||||
|
if (!absolute)
|
||||||
|
bd += pc - 4;
|
||||||
|
|
||||||
|
if (!ircolib::is_bit_set<ircolib::u32, 25>(instr))
|
||||||
|
ircolib::panic("broadway::bcx unimplemented variants with bit 25 == 0");
|
||||||
|
|
||||||
|
if (ircolib::is_bit_set<ircolib::u32, 23>(instr)) { // always
|
||||||
|
if (link)
|
||||||
|
lr = pc;
|
||||||
|
|
||||||
|
pc = bd;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ircolib::is_bit_set<ircolib::u32, 22>(instr)) { // --ctr == 0
|
||||||
|
if (--ctr != 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (link)
|
||||||
|
lr = pc;
|
||||||
|
|
||||||
|
pc = bd;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --ctr != 0
|
||||||
|
if (--ctr == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (link)
|
||||||
|
lr = pc;
|
||||||
|
|
||||||
|
pc = bd;
|
||||||
}
|
}
|
||||||
|
|
||||||
void broadway::move_spr(ircolib::u32 instr) {
|
void broadway::move_spr(ircolib::u32 instr) {
|
||||||
|
|||||||
Reference in New Issue
Block a user