-
Notifications
You must be signed in to change notification settings - Fork 2.1k
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
base: master
Are you sure you want to change the base?
Changes from all commits
2745f1f
147c20d
9705f20
917fe33
1fb75fb
d46e0ea
f6eb41f
9c8a865
bacafdf
1aa065c
5a2b3b5
88cfebf
c6ea674
942ed0b
e4a1003
ed93185
cd4a9c8
eb697c5
9bbcb5e
2e4d33f
7da0d8e
ebd4f49
a82298a
6ca688e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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)) | ||
|
||
|
||
|
||
|
@@ -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; | ||
|
||
// when we hit a MAPVAR opcode, log the change for the current PC | ||
|
@@ -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; | ||
|
@@ -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; | ||
|
||
|
@@ -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; | ||
|
||
|
@@ -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; | ||
|
@@ -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
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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; There was a problem hiding this comment. Choose a reason for hiding this commentThe 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) | ||
{ | ||
|
@@ -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] | ||
|
@@ -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): | ||
|
@@ -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; | ||
|
||
|
@@ -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; | ||
|
||
|
@@ -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): | ||
|
@@ -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; | ||
|
||
|
@@ -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; | ||
|
||
|
@@ -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; | ||
|
||
|
@@ -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
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. 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; | ||
|
@@ -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
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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) | ||
{ | ||
|
@@ -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] | ||
|
@@ -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; | ||
|
||
|
@@ -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; | ||
|
||
|
@@ -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; | ||
|
||
|
@@ -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; | ||
|
||
|
@@ -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): | ||
|
@@ -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; | ||
|
||
|
@@ -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; | ||
|
||
|
@@ -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): | ||
|
@@ -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; | ||
|
||
|
@@ -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); | ||
} | ||
|
||
|
||
|
@@ -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) | ||
|
There was a problem hiding this comment.
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?There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.