mirror of
https://github.com/AlexAltea/nucleus.git
synced 2024-06-11 16:57:40 -04:00
Updated PPUState::CR def. and fixed some ALU issues
This commit is contained in:
parent
9336985010
commit
8a243a1663
|
@ -9,6 +9,29 @@ namespace cpu {
|
|||
namespace frontend {
|
||||
namespace ppu {
|
||||
|
||||
U32 PPUState::getCR() {
|
||||
U32 value = 0;
|
||||
|
||||
// Going from MSb to LSb
|
||||
int shift = 31;
|
||||
for (const auto& field : cr.field) {
|
||||
for (const auto& bit : field.bit) {
|
||||
value |= (bit << shift--);
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
void PPUState::setCR(U32 value) {
|
||||
// Going from MSb to LSb
|
||||
int shift = 31;
|
||||
for (auto& field : cr.field) {
|
||||
for (auto& bit : field.bit) {
|
||||
bit = ((value >> shift--) & 0x1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace ppu
|
||||
} // namespace frontend
|
||||
} // namespace cpu
|
||||
|
|
|
@ -242,21 +242,23 @@ public:
|
|||
* | CR0 | CR1 | CR2 | CR3 | CR4 | CR5 | CR6 | CR7 |
|
||||
* +-----+-----+-----+-----+-----+-----+-----+-----+
|
||||
*/
|
||||
union CR {
|
||||
struct {
|
||||
U8 lt; // Negative (Bit 0)
|
||||
U8 gt; // Positive (Bit 1)
|
||||
U8 eq; // Zero (Bit 2)
|
||||
U8 so; // Summary overflow (Bit 3)
|
||||
};
|
||||
struct {
|
||||
U8 fx; // Floating-point exception summary (Bit 0)
|
||||
U8 fex; // Floating-point enabled exception summary (Bit 1)
|
||||
U8 vx; // Floating-point invalid operation exception summary (Bit 2)
|
||||
U8 ox; // Floating-point overflow exception (Bit 3)
|
||||
};
|
||||
U8 bit[4];
|
||||
} cr[8];
|
||||
struct CR {
|
||||
union Field {
|
||||
struct {
|
||||
U8 lt; // Negative (Bit 0)
|
||||
U8 gt; // Positive (Bit 1)
|
||||
U8 eq; // Zero (Bit 2)
|
||||
U8 so; // Summary overflow (Bit 3)
|
||||
};
|
||||
struct {
|
||||
U8 fx; // Floating-point exception summary (Bit 0)
|
||||
U8 fex; // Floating-point enabled exception summary (Bit 1)
|
||||
U8 vx; // Floating-point invalid operation exception summary (Bit 2)
|
||||
U8 ox; // Floating-point overflow exception (Bit 3)
|
||||
};
|
||||
U8 bit[4];
|
||||
} field[8];
|
||||
} cr;
|
||||
|
||||
/**
|
||||
* XER register
|
||||
|
@ -294,6 +296,13 @@ public:
|
|||
|
||||
// Program Counter
|
||||
U32 pc;
|
||||
|
||||
public:
|
||||
// Register read
|
||||
U32 getCR();
|
||||
|
||||
// Register write
|
||||
void setCR(U32 value);
|
||||
};
|
||||
|
||||
#ifdef NUCLEUS_ARCH_X86
|
||||
|
|
|
@ -15,25 +15,42 @@ using namespace cpu::hir;
|
|||
|
||||
// Utilities
|
||||
Value* addDidCarry(Builder& builder, Value* v1, Value* v2) {
|
||||
/*// 32-bit
|
||||
return builder.createCmpUGT(
|
||||
builder.createTrunc(v2, TYPE_I32),
|
||||
builder.createNot(builder.createTrunc(v1, TYPE_I32)));
|
||||
builder.createNot(builder.createTrunc(v1, TYPE_I32)));*/
|
||||
|
||||
// 64-bit
|
||||
return builder.createCmpUGT(v2, builder.createNot(v1));
|
||||
}
|
||||
|
||||
Value* subDidCarry(Builder& builder, Value* v1, Value* v2) {
|
||||
/*// 32-bit
|
||||
return builder.createOr(
|
||||
builder.createCmpUGT(
|
||||
builder.createTrunc(v1, TYPE_I32),
|
||||
builder.createNot(builder.createNeg(builder.createTrunc(v2, TYPE_I32)))),
|
||||
builder.createCmpEQ(
|
||||
builder.createTrunc(v2, TYPE_I32),
|
||||
builder.getConstantI32(0)));
|
||||
builder.getConstantI32(0)));*/
|
||||
|
||||
// 64-bit
|
||||
return builder.createOr(
|
||||
builder.createCmpUGT(v1, builder.createNot(builder.createNeg(v2))),
|
||||
builder.createCmpEQ(v2, builder.getConstantI64(0)));
|
||||
}
|
||||
|
||||
Value* addWithCarryDidCarry(Builder& builder, Value* v1, Value* v2, Value* v3) {
|
||||
/*// 32-bit
|
||||
v1 = builder.createTrunc(v1, TYPE_I32);
|
||||
v2 = builder.createTrunc(v2, TYPE_I32);
|
||||
v3 = builder.createZExt(v3, TYPE_I32);
|
||||
return builder.createOr(
|
||||
builder.createCmpULT(builder.createAdd(builder.createAdd(v1, v2), v3), v3),
|
||||
builder.createCmpULT(builder.createAdd(v1, v2), v1));*/
|
||||
|
||||
// 64-bit
|
||||
v3 = builder.createZExt(v3, TYPE_I64);
|
||||
return builder.createOr(
|
||||
builder.createCmpULT(builder.createAdd(builder.createAdd(v1, v2), v3), v3),
|
||||
builder.createCmpULT(builder.createAdd(v1, v2), v1));
|
||||
|
@ -172,16 +189,16 @@ void Recompiler::addis(Instruction code)
|
|||
void Recompiler::addmex(Instruction code)
|
||||
{
|
||||
Value* ra = getGPR(code.ra);
|
||||
Value* ca = getXER_CA();
|
||||
Value* rd;
|
||||
Value* ca;
|
||||
|
||||
if (code.oe) {
|
||||
assert_always("Unimplemented");
|
||||
// TODO: XER OV update
|
||||
} else {
|
||||
rd = builder.createSub(ra, builder.getConstantI64(1));
|
||||
rd = builder.createAdd(rd, builder.createZExt(getXER_CA(), TYPE_I64));
|
||||
ca = addWithCarryDidCarry(builder, ra, builder.getConstantI64(-1), getXER_CA());
|
||||
rd = builder.createAdd(rd, builder.createZExt(ca, TYPE_I64));
|
||||
ca = addWithCarryDidCarry(builder, ra, builder.getConstantI64(-1), ca);
|
||||
}
|
||||
|
||||
if (code.rc) {
|
||||
|
@ -195,15 +212,15 @@ void Recompiler::addmex(Instruction code)
|
|||
void Recompiler::addzex(Instruction code)
|
||||
{
|
||||
Value* ra = getGPR(code.ra);
|
||||
Value* ca = getXER_CA();
|
||||
Value* rd;
|
||||
Value* ca;
|
||||
|
||||
if (code.oe) {
|
||||
assert_always("Unimplemented");
|
||||
// TODO: XER OV update
|
||||
} else {
|
||||
rd = builder.createAdd(ra, builder.createZExt(getXER_CA(), TYPE_I64));
|
||||
ca = addWithCarryDidCarry(builder, ra, builder.getConstantI64(0), getXER_CA());
|
||||
rd = builder.createAdd(ra, builder.createZExt(ca, TYPE_I64));
|
||||
ca = addWithCarryDidCarry(builder, ra, builder.getConstantI64(0), ca);
|
||||
}
|
||||
|
||||
if (code.rc) {
|
||||
|
@ -573,7 +590,7 @@ void Recompiler::nandx(Instruction code)
|
|||
Value* ra;
|
||||
|
||||
ra = builder.createAnd(rs, rb);
|
||||
ra = builder.createNeg(ra);
|
||||
ra = builder.createNot(ra);
|
||||
if (code.rc) {
|
||||
updateCR0(ra);
|
||||
}
|
||||
|
@ -586,7 +603,7 @@ void Recompiler::negx(Instruction code)
|
|||
Value* ra = getGPR(code.ra);
|
||||
Value* rd;
|
||||
|
||||
rd = builder.createSub(builder.getConstantI64(0), ra);
|
||||
rd = builder.createNeg(ra);
|
||||
if (code.oe) {
|
||||
assert_always("Unimplemented");
|
||||
// TODO: XER OV update
|
||||
|
|
Loading…
Reference in a new issue