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 17 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
149 changes: 120 additions & 29 deletions src/devices/cpu/drcbec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -359,9 +359,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?


// when we hit a MAPVAR opcode, log the change for the current PC
Expand Down Expand Up @@ -628,6 +629,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 +832,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 @@ -964,6 +971,20 @@ int drcbe_c::execute(code_handle &entry)
flags |= FLAG_V;
break;

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

case MAKE_OPCODE_SHORT(OP_MULUH, 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 +993,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_MULSH, 4, 0): // MULSH dst,src1,src2[,f]
temp64 = mul_32x32(PARAM1, PARAM2);
PARAM0 = (int32_t)temp64;
break;

case MAKE_OPCODE_SHORT(OP_MULSH, 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;

case MAKE_OPCODE_SHORT(OP_DIVU, 4, 0): // DIVU dst,edst,src1,src2[,f]
if (PARAM3 != 0)
{
Expand Down Expand Up @@ -1084,8 +1118,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 +1188,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 +1200,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 +1215,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 +1229,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 +1241,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 +1501,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 @@ -1579,6 +1627,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_MULUH, 8, 0): // DMULUH dst,src1,src2[,f]
dmulu(*inst[0].puint64, *inst[0].puint64, DPARAM1, DPARAM2, false);
break;

case MAKE_OPCODE_SHORT(OP_MULUH, 8, 1):
flags = dmulu(*inst[0].puint64, *inst[0].puint64, DPARAM1, DPARAM2, true);
flags = FLAGS64_NZ(DPARAM0) | (flags & FLAG_V);
break;

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 +1644,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_MULSH, 8, 0): // DMULSH dst,src1,src2[,f]
dmuls(*inst[0].puint64, *inst[0].puint64, DPARAM1, DPARAM2, false);
break;

case MAKE_OPCODE_SHORT(OP_MULSH, 8, 1):
flags = dmuls(*inst[0].puint64, *inst[0].puint64, DPARAM1, DPARAM2, true);
flags = FLAGS64_NZ(DPARAM0) | (flags & FLAG_V);
break;

case MAKE_OPCODE_SHORT(OP_DIVU, 8, 0): // DDIVU dst,edst,src1,src2[,f]
if (DPARAM3 != 0)
{
Expand Down Expand Up @@ -1691,8 +1757,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 +1768,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 +1783,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 +1797,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 +1813,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 +1827,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 +1839,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 +1854,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 +1868,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 +1880,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 +2330,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 +2381,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