Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes to UML and DRC backends #13108

Draft
wants to merge 24 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
2745f1f
uml: Add new opcode UML_SETFLGS
987123879113 Dec 20, 2024
147c20d
uml: Add new opcodes MULUH and MULSH
987123879113 Dec 20, 2024
9705f20
uml: Add new opcode BREAK
987123879113 Dec 20, 2024
917fe33
uml: Add note about fcmp opcode flags
987123879113 Dec 20, 2024
1fb75fb
uml: Fix simplified multiplication and division operations to use cor…
987123879113 Dec 20, 2024
d46e0ea
uml: Enforce limit for shift operand to be consistent with the backends
987123879113 Dec 20, 2024
f6eb41f
uml: Add additional documentation for opcodes with unclear naming
987123879113 Dec 20, 2024
9c8a865
drcbec: Add more methods of accessing OP_CARRY
987123879113 Dec 20, 2024
bacafdf
drcbec: Fix flag calculation for BSWAP opcode
987123879113 Dec 20, 2024
1aa065c
drcbec: Implement new MULUH/MULSH opcodes
987123879113 Dec 20, 2024
5a2b3b5
drcbec: Fix flag calculation for MULS
987123879113 Dec 20, 2024
88cfebf
drcbec: Make calculation for shift and rotation opcodes consistent
987123879113 Dec 20, 2024
c6ea674
drcbec: Implement new SETFLGS opcode
987123879113 Dec 20, 2024
942ed0b
drcbec: Add stub for BREAK opcode
987123879113 Dec 20, 2024
e4a1003
drcbex64: Implement new BREAK, SETFLGS, MULUH, MULSH opcodes + variou…
987123879113 Dec 20, 2024
ed93185
drcbex86: Implement new BREAK, SETFLGS, MULUH, and MULSH opcodes + va…
987123879113 Dec 20, 2024
cd4a9c8
ppcdrc: Change MULLWx/MULLWOx to use new MULSH opcode
987123879113 Dec 15, 2024
eb697c5
drcbec: Fix subb
987123879113 Dec 23, 2024
9bbcb5e
Use osd_break_into_debugger instead of int3 for OP_BREAK
987123879113 Dec 23, 2024
2e4d33f
Use lahf/sahf instead of pushfd/popfd
987123879113 Dec 23, 2024
7da0d8e
Pass message to osd_break_into_debugger
987123879113 Dec 23, 2024
ebd4f49
Rename MULUH/MULSH to MULULW/MULSLW
987123879113 Dec 23, 2024
a82298a
x64: Fix status flag calculations
987123879113 Dec 25, 2024
6ca688e
x64: Simplify mululw/mulslw flag calculation
987123879113 Dec 25, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
169 changes: 126 additions & 43 deletions src/devices/cpu/drcbec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -181,24 +181,28 @@ enum
// compute C and V flags for 32-bit add/subtract
#define FLAGS32_C_ADD(a,b) ((uint32_t)~(a) < (uint32_t)(b))
#define FLAGS32_C_SUB(a,b) ((uint32_t)(b) > (uint32_t)(a))
#define FLAGS32_C_SUBC(a,b,c) (((uint32_t)(c) != 0 && ((uint32_t)(b) + (uint32_t)(c)) == 0) || (uint32_t)(b) + (uint32_t)(c) > (uint32_t)(a))
#define FLAGS32_V_SUB(r,a,b) (((((a) ^ (b)) & ((a) ^ (r))) >> 30) & FLAG_V)
#define FLAGS32_V_ADD(r,a,b) (((~((a) ^ (b)) & ((a) ^ (r))) >> 30) & FLAG_V)

// compute N and Z flags for 32-bit operations
#define FLAGS32_NZ(v) ((((v) >> 28) & FLAG_S) | (((uint32_t)(v) == 0) << 2))
#define FLAGS32_NZCV_ADD(r,a,b) (FLAGS32_NZ(r) | FLAGS32_C_ADD(a,b) | FLAGS32_V_ADD(r,a,b))
#define FLAGS32_NZCV_SUB(r,a,b) (FLAGS32_NZ(r) | FLAGS32_C_SUB(a,b) | FLAGS32_V_SUB(r,a,b))
#define FLAGS32_NZCV_SUBC(r,a,b,c) (FLAGS32_NZ(r) | FLAGS32_C_SUBC(a,b,c) | FLAGS32_V_SUB(r,a,b))

// compute C and V flags for 64-bit add/subtract
#define FLAGS64_C_ADD(a,b) ((uint64_t)~(a) < (uint64_t)(b))
#define FLAGS64_C_SUB(a,b) ((uint64_t)(b) > (uint64_t)(a))
#define FLAGS64_C_SUBC(a,b,c) (((uint64_t)(c) != 0 && ((uint64_t)(b) + (uint64_t)(c)) == 0) || (uint64_t)(b) + (uint64_t)(c) > (uint64_t)(a))
#define FLAGS64_V_SUB(r,a,b) (((((a) ^ (b)) & ((a) ^ (r))) >> 62) & FLAG_V)
#define FLAGS64_V_ADD(r,a,b) (((~((a) ^ (b)) & ((a) ^ (r))) >> 62) & FLAG_V)

// compute N and Z flags for 64-bit operations
#define FLAGS64_NZ(v) ((((v) >> 60) & FLAG_S) | (((uint64_t)(v) == 0) << 2))
#define FLAGS64_NZCV_ADD(r,a,b) (FLAGS64_NZ(r) | FLAGS64_C_ADD(a,b) | FLAGS64_V_ADD(r,a,b))
#define FLAGS64_NZCV_SUB(r,a,b) (FLAGS64_NZ(r) | FLAGS64_C_SUB(a,b) | FLAGS64_V_SUB(r,a,b))
#define FLAGS64_NZCV_SUBC(r,a,b,c) (FLAGS64_NZ(r) | FLAGS64_C_SUBC(a,b,c) | FLAGS64_V_SUB(r,a,b))



Expand Down Expand Up @@ -359,9 +363,10 @@ void drcbe_c::generate(drcuml_block &block, const instruction *instlist, uint32_
m_labels.set_codeptr(inst.param(0).label(), (drccodeptr)dst);
break;

// ignore COMMENT and NOP opcodes
// ignore COMMENT, NOP, and BREAK opcodes
case OP_COMMENT:
case OP_NOP:
case OP_BREAK:
break;
Comment on lines -362 to 370
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this still call osd_break_in_debugger on BREAK for consistency?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not against it but for the C backend I don't think you can use a debugger to get anything meaningful so I don't think it matters compared to something generating actual assembly where you want to be able to debug the generated assembly. Can you think of a usecase where you'd want to break into a debugger for the C backend?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It still might be useful for examining the state of the emulator when particular generated code is hit. It's considered generally useful enough that we have a convenient function for it.


// when we hit a MAPVAR opcode, log the change for the current PC
Expand Down Expand Up @@ -628,6 +633,11 @@ int drcbe_c::execute(code_handle &entry)
PARAM0 = flags & PARAM1;
break;

case MAKE_OPCODE_SHORT(OP_SETFLGS, 4, 0): // SETFLGS src
case MAKE_OPCODE_SHORT(OP_SETFLGS, 4, 1):
flags = PARAM0;
break;

case MAKE_OPCODE_SHORT(OP_SAVE, 4, 0): // SAVE dst
*inst[0].state = m_state;
inst[0].state->flags = flags;
Expand Down Expand Up @@ -826,7 +836,8 @@ int drcbe_c::execute(code_handle &entry)
m_space[PARAM3]->write_dword(PARAM0, PARAM1, PARAM2);
break;

case MAKE_OPCODE_SHORT(OP_CARRY, 4, 1): // CARRY src,bitnum
case MAKE_OPCODE_SHORT(OP_CARRY, 4, 0): // CARRY src,bitnum
case MAKE_OPCODE_SHORT(OP_CARRY, 4, 1):
flags = (flags & ~FLAG_C) | ((PARAM0 >> (PARAM1 & 31)) & FLAG_C);
break;

Expand Down Expand Up @@ -930,16 +941,7 @@ int drcbe_c::execute(code_handle &entry)

case MAKE_OPCODE_SHORT(OP_SUBB, 4, 1):
temp32 = PARAM1 - PARAM2 - (flags & FLAG_C);
temp64 = (uint64_t)PARAM1 - (uint64_t)PARAM2 - (uint64_t)(flags & FLAG_C);
if (PARAM2 + 1 != 0)
flags = FLAGS32_NZCV_SUB(temp32, PARAM1, PARAM2 + (flags & FLAG_C));
else
{
flags = FLAGS32_NZCV_SUB(temp32, PARAM1 - (flags & FLAG_C), PARAM2);
flags &= ~(FLAG_C | FLAG_V);
flags |= ((temp64>>32) & 1) ? FLAG_C : 0;
flags |= (((PARAM1) ^ (PARAM2)) & ((PARAM1) ^ (temp64)) & 0x80000000) ? FLAG_V : 0;
}
flags = FLAGS32_NZCV_SUBC(temp32, PARAM1, PARAM2, flags & FLAG_C);
PARAM0 = temp32;
break;

Expand All @@ -964,6 +966,20 @@ int drcbe_c::execute(code_handle &entry)
flags |= FLAG_V;
break;

case MAKE_OPCODE_SHORT(OP_MULULW, 4, 0): // MULULW dst,src1,src2[,f]
temp64 = mulu_32x32(PARAM1, PARAM2);
PARAM0 = (uint32_t)temp64;
break;

case MAKE_OPCODE_SHORT(OP_MULULW, 4, 1):
temp64 = mulu_32x32(PARAM1, PARAM2);
temp32 = (uint32_t)temp64;
flags = FLAGS32_NZ(temp32);
PARAM0 = temp32;
if (temp64 > temp32)
flags |= FLAG_V;
break;

case MAKE_OPCODE_SHORT(OP_MULS, 4, 0): // MULS dst,edst,src1,src2[,f]
temp64 = mul_32x32(PARAM2, PARAM3);
PARAM1 = temp64 >> 32;
Expand All @@ -972,14 +988,27 @@ int drcbe_c::execute(code_handle &entry)

case MAKE_OPCODE_SHORT(OP_MULS, 4, 1):
temp64 = mul_32x32(PARAM2, PARAM3);
temp32 = (int32_t)temp64;
flags = FLAGS32_NZ(temp32);
flags = FLAGS64_NZ(temp64);
PARAM1 = temp64 >> 32;
PARAM0 = (uint32_t)temp64;
if (temp64 != (int32_t)temp64)
flags |= FLAG_V;
break;

case MAKE_OPCODE_SHORT(OP_MULSLW, 4, 0): // MULSLW dst,src1,src2[,f]
temp64 = mul_32x32(PARAM1, PARAM2);
PARAM0 = (int32_t)temp64;
break;

case MAKE_OPCODE_SHORT(OP_MULSLW, 4, 1):
temp64 = mul_32x32(PARAM1, PARAM2);
temp32 = (int32_t)temp64;
flags = FLAGS32_NZ(temp32);
PARAM0 = temp32;
if (temp64 != (int32_t)temp64)
flags |= FLAG_V;
break;
Comment on lines +998 to +1010
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are playing fast and loose with undefined corners of integer conversion. Will it work if you do it like this?

			case MAKE_OPCODE_SHORT(OP_MULSLW, 4, 0):      // MULSLW   dst,src1,src2[,f]
				temp64 = mul_32x32(PARAM1, PARAM2);
				PARAM0 = (uint32_t)temp64;
				break;

			case MAKE_OPCODE_SHORT(OP_MULSLW, 4, 1):
				temp64 = mul_32x32(PARAM1, PARAM2);
				temp32 = (uint32_t)temp64;
				flags = FLAGS32_NZ(temp32);
				PARAM0 = temp32;
				if ((int64_t)temp64 != (int32_t)temp32)
					flags |= FLAG_V;
				break;

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From a quick test, yeah this works fine. All of my test cases pass with the change. I'll change it.


case MAKE_OPCODE_SHORT(OP_DIVU, 4, 0): // DIVU dst,edst,src1,src2[,f]
if (PARAM3 != 0)
{
Expand Down Expand Up @@ -1084,8 +1113,8 @@ int drcbe_c::execute(code_handle &entry)

case MAKE_OPCODE_SHORT(OP_BSWAP, 4, 1):
temp32 = PARAM1;
flags = FLAGS32_NZ(temp32);
PARAM0 = swapendian_int32(temp32);
flags = FLAGS32_NZ(PARAM0);
break;

case MAKE_OPCODE_SHORT(OP_SHL, 4, 0): // SHL dst,src,count[,f]
Expand Down Expand Up @@ -1154,6 +1183,8 @@ int drcbe_c::execute(code_handle &entry)
PARAM0 = (PARAM1 << shift) | ((flags & FLAG_C) << (shift - 1)) | (PARAM1 >> (33 - shift));
else if (shift == 1)
PARAM0 = (PARAM1 << shift) | (flags & FLAG_C);
else
PARAM0 = PARAM1;
break;

case MAKE_OPCODE_SHORT(OP_ROLC, 4, 1):
Expand All @@ -1164,8 +1195,11 @@ int drcbe_c::execute(code_handle &entry)
temp32 = (PARAM1 << shift) | (flags & FLAG_C);
else
temp32 = PARAM1;
flags = FLAGS32_NZ(temp32);
if (shift != 0) flags |= ((PARAM1 << (shift - 1)) >> 31) & FLAG_C;
if (shift != 0)
{
flags = FLAGS32_NZ(temp32);
flags |= ((PARAM1 << (shift - 1)) >> 31) & FLAG_C;
}
PARAM0 = temp32;
break;

Expand All @@ -1176,8 +1210,11 @@ int drcbe_c::execute(code_handle &entry)
case MAKE_OPCODE_SHORT(OP_ROR, 4, 1):
shift = PARAM2 & 31;
temp32 = rotr_32(PARAM1, shift);
flags = FLAGS32_NZ(temp32);
if (shift != 0) flags |= (PARAM1 >> (shift - 1)) & FLAG_C;
if (shift != 0)
{
flags = FLAGS32_NZ(temp32);
flags |= (PARAM1 >> (shift - 1)) & FLAG_C;
}
PARAM0 = temp32;
break;

Expand All @@ -1187,6 +1224,8 @@ int drcbe_c::execute(code_handle &entry)
PARAM0 = (PARAM1 >> shift) | (((flags & FLAG_C) << 31) >> (shift - 1)) | (PARAM1 << (33 - shift));
else if (shift == 1)
PARAM0 = (PARAM1 >> shift) | ((flags & FLAG_C) << 31);
else
PARAM0 = PARAM1;
break;

case MAKE_OPCODE_SHORT(OP_RORC, 4, 1):
Expand All @@ -1197,8 +1236,11 @@ int drcbe_c::execute(code_handle &entry)
temp32 = (PARAM1 >> shift) | ((flags & FLAG_C) << 31);
else
temp32 = PARAM1;
flags = FLAGS32_NZ(temp32);
if (shift != 0) flags |= (PARAM1 >> (shift - 1)) & FLAG_C;
if (shift != 0)
{
flags = FLAGS32_NZ(temp32);
flags |= (PARAM1 >> (shift - 1)) & FLAG_C;
}
PARAM0 = temp32;
break;

Expand Down Expand Up @@ -1454,6 +1496,7 @@ int drcbe_c::execute(code_handle &entry)
break;

case MAKE_OPCODE_SHORT(OP_CARRY, 8, 0): // DCARRY src,bitnum
case MAKE_OPCODE_SHORT(OP_CARRY, 8, 1):
flags = (flags & ~FLAG_C) | ((DPARAM0 >> (DPARAM1 & 63)) & FLAG_C);
break;

Expand Down Expand Up @@ -1559,10 +1602,7 @@ int drcbe_c::execute(code_handle &entry)

case MAKE_OPCODE_SHORT(OP_SUBB, 8, 1):
temp64 = DPARAM1 - DPARAM2 - (flags & FLAG_C);
if (DPARAM2 + 1 != 0)
flags = FLAGS64_NZCV_SUB(temp64, DPARAM1, DPARAM2 + (flags & FLAG_C));
else
flags = FLAGS64_NZCV_SUB(temp64, DPARAM1 - (flags & FLAG_C), DPARAM2);
flags = FLAGS64_NZCV_SUBC(temp64, DPARAM1, DPARAM2, flags & FLAG_C);
DPARAM0 = temp64;
break;

Expand All @@ -1579,6 +1619,15 @@ int drcbe_c::execute(code_handle &entry)
flags = dmulu(*inst[0].puint64, *inst[1].puint64, DPARAM2, DPARAM3, true);
break;

case MAKE_OPCODE_SHORT(OP_MULULW, 8, 0): // DMULULW dst,src1,src2[,f]
dmulu(*inst[0].puint64, *inst[0].puint64, DPARAM1, DPARAM2, false);
break;

case MAKE_OPCODE_SHORT(OP_MULULW, 8, 1):
flags = dmulu(*inst[0].puint64, *inst[0].puint64, DPARAM1, DPARAM2, true);
flags = FLAGS64_NZ(DPARAM0) | (flags & FLAG_V);
break;
Comment on lines +1626 to +1629
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would appear to be inconsistent with the 32-bit version in that it doesn’t set V if the result is truncated.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FLAG_V is the overflow flag that I mentioned before, where it sets overflow/FLAG_V if the upper half of the result isn't zero. dmulu sets FLAG_V using ((hi != 0) << 1) so I think it's the same.

Can you think of a specific case where you think it'd fail?


case MAKE_OPCODE_SHORT(OP_MULS, 8, 0): // DMULS dst,edst,src1,src2[,f]
dmuls(*inst[0].puint64, *inst[1].puint64, DPARAM2, DPARAM3, false);
break;
Expand All @@ -1587,6 +1636,15 @@ int drcbe_c::execute(code_handle &entry)
flags = dmuls(*inst[0].puint64, *inst[1].puint64, DPARAM2, DPARAM3, true);
break;

case MAKE_OPCODE_SHORT(OP_MULSLW, 8, 0): // DMULSLW dst,src1,src2[,f]
dmuls(*inst[0].puint64, *inst[0].puint64, DPARAM1, DPARAM2, false);
break;

case MAKE_OPCODE_SHORT(OP_MULSLW, 8, 1):
flags = dmuls(*inst[0].puint64, *inst[0].puint64, DPARAM1, DPARAM2, true);
flags = FLAGS64_NZ(DPARAM0) | (flags & FLAG_V);
break;
Comment on lines +1643 to +1646
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same for this – it’s inconsistent with the 32-bit version.


case MAKE_OPCODE_SHORT(OP_DIVU, 8, 0): // DDIVU dst,edst,src1,src2[,f]
if (DPARAM3 != 0)
{
Expand Down Expand Up @@ -1691,8 +1749,8 @@ int drcbe_c::execute(code_handle &entry)

case MAKE_OPCODE_SHORT(OP_BSWAP, 8, 1):
temp64 = DPARAM1;
flags = FLAGS64_NZ(temp64);
DPARAM0 = swapendian_int64(temp64);
flags = FLAGS64_NZ(DPARAM0);
break;

case MAKE_OPCODE_SHORT(OP_SHL, 8, 0): // DSHL dst,src,count[,f]
Expand All @@ -1702,8 +1760,11 @@ int drcbe_c::execute(code_handle &entry)
case MAKE_OPCODE_SHORT(OP_SHL, 8, 1):
shift = DPARAM2 & 63;
temp64 = DPARAM1 << shift;
flags = FLAGS64_NZ(temp64);
if (shift != 0) flags |= ((DPARAM1 << (shift - 1)) >> 63) & FLAG_C;
if (shift != 0)
{
flags = FLAGS64_NZ(temp64);
flags |= ((DPARAM1 << (shift - 1)) >> 63) & FLAG_C;
}
DPARAM0 = temp64;
break;

Expand All @@ -1714,8 +1775,11 @@ int drcbe_c::execute(code_handle &entry)
case MAKE_OPCODE_SHORT(OP_SHR, 8, 1):
shift = DPARAM2 & 63;
temp64 = DPARAM1 >> shift;
flags = FLAGS64_NZ(temp64);
if (shift != 0) flags |= (DPARAM1 >> (shift - 1)) & FLAG_C;
if (shift != 0)
{
flags = FLAGS64_NZ(temp64);
flags |= (DPARAM1 >> (shift - 1)) & FLAG_C;
}
DPARAM0 = temp64;
break;

Expand All @@ -1725,9 +1789,12 @@ int drcbe_c::execute(code_handle &entry)

case MAKE_OPCODE_SHORT(OP_SAR, 8, 1):
shift = DPARAM2 & 63;
temp64 = (int32_t)DPARAM1 >> shift;
flags = FLAGS64_NZ(temp64);
if (shift != 0) flags |= (DPARAM1 >> (shift - 1)) & FLAG_C;
temp64 = (int64_t)DPARAM1 >> shift;
if (shift != 0)
{
flags = FLAGS64_NZ(temp64);
flags |= (DPARAM1 >> (shift - 1)) & FLAG_C;
}
DPARAM0 = temp64;
break;

Expand All @@ -1738,8 +1805,11 @@ int drcbe_c::execute(code_handle &entry)
case MAKE_OPCODE_SHORT(OP_ROL, 8, 1):
shift = DPARAM2 & 63;
temp64 = rotl_64(DPARAM1, shift);
flags = FLAGS64_NZ(temp64);
if (shift != 0) flags |= ((DPARAM1 << (shift - 1)) >> 63) & FLAG_C;
if (shift != 0)
{
flags = FLAGS64_NZ(temp64);
flags |= ((DPARAM1 << (shift - 1)) >> 63) & FLAG_C;
}
DPARAM0 = temp64;
break;

Expand All @@ -1749,6 +1819,8 @@ int drcbe_c::execute(code_handle &entry)
DPARAM0 = (DPARAM1 << shift) | ((flags & FLAG_C) << (shift - 1)) | (DPARAM1 >> (65 - shift));
else if (shift == 1)
DPARAM0 = (DPARAM1 << shift) | (flags & FLAG_C);
else
DPARAM0 = DPARAM1;
break;

case MAKE_OPCODE_SHORT(OP_ROLC, 8, 1):
Expand All @@ -1759,8 +1831,11 @@ int drcbe_c::execute(code_handle &entry)
temp64 = (DPARAM1 << shift) | (flags & FLAG_C);
else
temp64 = DPARAM1;
flags = FLAGS64_NZ(temp64);
if (shift != 0) flags |= ((DPARAM1 << (shift - 1)) >> 63) & FLAG_C;
if (shift != 0)
{
flags = FLAGS64_NZ(temp64);
flags |= ((DPARAM1 << (shift - 1)) >> 63) & FLAG_C;
}
DPARAM0 = temp64;
break;

Expand All @@ -1771,8 +1846,11 @@ int drcbe_c::execute(code_handle &entry)
case MAKE_OPCODE_SHORT(OP_ROR, 8, 1):
shift = DPARAM2 & 63;
temp64 = rotr_64(DPARAM1, shift);
flags = FLAGS64_NZ(temp64);
if (shift != 0) flags |= (DPARAM1 >> (shift - 1)) & FLAG_C;
if (shift != 0)
{
flags = FLAGS64_NZ(temp64);
flags |= (DPARAM1 >> (shift - 1)) & FLAG_C;
}
DPARAM0 = temp64;
break;

Expand All @@ -1782,6 +1860,8 @@ int drcbe_c::execute(code_handle &entry)
DPARAM0 = (DPARAM1 >> shift) | ((((uint64_t)flags & FLAG_C) << 63) >> (shift - 1)) | (DPARAM1 << (65 - shift));
else if (shift == 1)
DPARAM0 = (DPARAM1 >> shift) | (((uint64_t)flags & FLAG_C) << 63);
else
DPARAM0 = DPARAM1;
break;

case MAKE_OPCODE_SHORT(OP_RORC, 8, 1):
Expand All @@ -1792,8 +1872,11 @@ int drcbe_c::execute(code_handle &entry)
temp64 = (DPARAM1 >> shift) | (((uint64_t)flags & FLAG_C) << 63);
else
temp64 = DPARAM1;
flags = FLAGS64_NZ(temp64);
if (shift != 0) flags |= (DPARAM1 >> (shift - 1)) & FLAG_C;
if (shift != 0)
{
flags = FLAGS64_NZ(temp64);
flags |= (DPARAM1 >> (shift - 1)) & FLAG_C;
}
DPARAM0 = temp64;
break;

Expand Down Expand Up @@ -2239,7 +2322,7 @@ int drcbe_c::dmulu(uint64_t &dstlo, uint64_t &dsthi, uint64_t src1, uint64_t src
// store the results
dsthi = hi;
dstlo = lo;
return ((hi >> 60) & FLAG_S) | ((dsthi != 0) << 1);
return ((hi >> 60) & FLAG_S) | ((hi != 0) << 1);
}


Expand Down Expand Up @@ -2290,7 +2373,7 @@ int drcbe_c::dmuls(uint64_t &dstlo, uint64_t &dsthi, int64_t src1, int64_t src2,
// store the results
dsthi = hi;
dstlo = lo;
return ((hi >> 60) & FLAG_S) | ((dsthi != ((int64_t)lo >> 63)) << 1);
return ((hi >> 60) & FLAG_S) | ((hi != ((int64_t)lo >> 63)) << 1);
}

uint32_t drcbe_c::tzcount32(uint32_t value)
Expand Down
Loading
Loading