about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2024-02-21 15:14:55 +0100
committerptitSeb <sebastien.chev@gmail.com>2024-02-21 15:14:55 +0100
commit9d1e6b9b960c33bb524cabfd53bb1ce1133e5e3b (patch)
treedef796d773f304f24316c06c173c060a677e4d7f /src
parent0d43b16fd5b6e9dbd3b6683843d8b3c1df4f7c8b (diff)
downloadbox64-9d1e6b9b960c33bb524cabfd53bb1ce1133e5e3b.tar.gz
box64-9d1e6b9b960c33bb524cabfd53bb1ce1133e5e3b.zip
[INTERPRETER] SHRD/SHLD with cnt==0 should not change flags
Diffstat (limited to 'src')
-rw-r--r--src/emu/x64primop.c24
1 files changed, 18 insertions, 6 deletions
diff --git a/src/emu/x64primop.c b/src/emu/x64primop.c
index a9a1eb62..72485ca0 100644
--- a/src/emu/x64primop.c
+++ b/src/emu/x64primop.c
@@ -957,10 +957,12 @@ Implements the SHLD instruction and side effects.
 uint16_t shld16 (x64emu_t *emu, uint16_t d, uint16_t fill, uint8_t s)
 {
 	unsigned int cnt, res, cf;
-	RESET_FLAGS(emu);
 
 	s = s&0x1f;
 	cnt = s % 16;
+	if(!s)
+		return d;
+	RESET_FLAGS(emu);
 	if (s < 16) {
 		if (cnt > 0) {
 			res = (d << cnt) | (fill >> (16-cnt));
@@ -995,9 +997,11 @@ uint16_t shld16 (x64emu_t *emu, uint16_t d, uint16_t fill, uint8_t s)
 uint32_t shld32 (x64emu_t *emu, uint32_t d, uint32_t fill, uint8_t s)
 {
 	unsigned int cnt, res, cf;
-	RESET_FLAGS(emu);
 
 	s = s&0x1f;
+	if(!s)
+		return d;
+	RESET_FLAGS(emu);
 	cnt = s % 32;
 	if (cnt > 0) {
 		res = (d << cnt) | (fill >> (32-cnt));
@@ -1020,9 +1024,11 @@ uint32_t shld32 (x64emu_t *emu, uint32_t d, uint32_t fill, uint8_t s)
 uint64_t shld64 (x64emu_t *emu, uint64_t d, uint64_t fill, uint8_t s)
 {
 	uint64_t cnt, res, cf;
-	RESET_FLAGS(emu);
 
 	s = s&0x3f;
+	if(!s)
+		return d;
+	RESET_FLAGS(emu);
 	cnt = s % 64;
 	if (cnt > 0) {
 		res = (d << cnt) | (fill >> (64-cnt));
@@ -1049,9 +1055,11 @@ Implements the SHRD instruction and side effects.
 uint16_t shrd16 (x64emu_t *emu, uint16_t d, uint16_t fill, uint8_t s)
 {
 	unsigned int cnt, res, cf;
-	RESET_FLAGS(emu);
 
 	s = s&0x1f;
+	if(!s)
+		return d;
+	RESET_FLAGS(emu);
 	cnt = s % 16;
 	if (s < 16) {
 		if (cnt > 0) {
@@ -1096,9 +1104,11 @@ uint16_t shrd16 (x64emu_t *emu, uint16_t d, uint16_t fill, uint8_t s)
 uint32_t shrd32 (x64emu_t *emu, uint32_t d, uint32_t fill, uint8_t s)
 {
 	unsigned int cnt, res, cf;
-	RESET_FLAGS(emu);
 
 	s = s&0x1f;
+	if(!s)
+		return d;
+	RESET_FLAGS(emu);
 	cnt = s % 32;
 	if (cnt > 0) {
 		cf = d & (1 << (cnt - 1));
@@ -1122,9 +1132,11 @@ uint64_t shrd64 (x64emu_t *emu, uint64_t d, uint64_t fill, uint8_t s)
 {
 	unsigned int cnt;
 	uint64_t res, cf;
-	RESET_FLAGS(emu);
 
 	s = s&0x3f;
+	if(!s)
+		return d;
+	RESET_FLAGS(emu);
 	cnt = s % 64;
 	if (cnt > 0) {
 		cf = d & (1LL << (cnt - 1));