mirror of
https://github.com/dingusdev/dingusppc.git
synced 2025-01-11 05:29:43 +00:00
Add tests for shifts and fix their emulation.
This commit is contained in:
parent
8c1c1e0a0d
commit
d25ce6a244
@ -1106,53 +1106,78 @@ void ppc_divwuodot() {
|
||||
|
||||
void ppc_slw() {
|
||||
ppc_grab_regssab();
|
||||
ppc_result_a = (ppc_result_b < 32) ? (ppc_result_d << ppc_result_b) : 0;
|
||||
if (ppc_result_b & 0x20) {
|
||||
ppc_result_a = 0;
|
||||
} else {
|
||||
ppc_result_a = ppc_result_d << (ppc_result_b & 0x1F);
|
||||
}
|
||||
ppc_store_result_rega();
|
||||
}
|
||||
|
||||
void ppc_slwdot() {
|
||||
ppc_grab_regssab();
|
||||
ppc_result_a = (ppc_result_b < 32) ? (ppc_result_d << ppc_result_b) : 0;
|
||||
if (ppc_result_b & 0x20) {
|
||||
ppc_result_a = 0;
|
||||
} else {
|
||||
ppc_result_a = ppc_result_d << (ppc_result_b & 0x1F);
|
||||
}
|
||||
ppc_changecrf0(ppc_result_a);
|
||||
ppc_store_result_rega();
|
||||
}
|
||||
|
||||
void ppc_srw() {
|
||||
ppc_grab_regssab();
|
||||
ppc_result_a = (ppc_result_b < 32) ? (ppc_result_d >> ppc_result_b) : 0;
|
||||
if (ppc_result_b & 0x20) {
|
||||
ppc_result_a = 0;
|
||||
} else {
|
||||
ppc_result_a = ppc_result_d >> (ppc_result_b & 0x1F);
|
||||
}
|
||||
ppc_store_result_rega();
|
||||
}
|
||||
|
||||
void ppc_srwdot() {
|
||||
ppc_grab_regssab();
|
||||
ppc_result_a = (ppc_result_b < 32) ? (ppc_result_d >> ppc_result_b) : 0;
|
||||
if (ppc_result_b & 0x20) {
|
||||
ppc_result_a = 0;
|
||||
} else {
|
||||
ppc_result_a = ppc_result_d >> (ppc_result_b & 0x1F);
|
||||
}
|
||||
ppc_changecrf0(ppc_result_a);
|
||||
ppc_store_result_rega();
|
||||
}
|
||||
|
||||
void ppc_sraw() {
|
||||
ppc_grab_regssab();
|
||||
|
||||
if (ppc_result_b > 32) {
|
||||
ppc_result_a = ((ppc_result_d) > 0x7FFFFFFF) ? 0xFFFFFFFFUL : 0x0;
|
||||
ppc_state.ppc_spr[SPR::XER] = (ppc_state.ppc_spr[SPR::XER] & 0xDFFFFFFFUL) | (((ppc_result_d) > 0x7FFFFFFF) ? 0x20000000 : 0x0);
|
||||
}
|
||||
else {
|
||||
ppc_result_a = (uint32_t)((int32_t)ppc_result_d >> ppc_result_b);
|
||||
ppc_state.ppc_spr[SPR::XER] = (ppc_state.ppc_spr[SPR::XER] & 0xDFFFFFFFUL) | (((ppc_result_d) > 0x7FFFFFFF) ? 0x20000000 : 0x0);
|
||||
if (ppc_result_b & 0x20) {
|
||||
ppc_result_a = (int32_t)ppc_result_d >> 31;
|
||||
ppc_state.ppc_spr[SPR::XER] |= (ppc_result_a & 1) << 29;
|
||||
} else {
|
||||
uint32_t shift = ppc_result_b & 0x1F;
|
||||
uint32_t mask = (1 << shift) - 1;
|
||||
ppc_result_a = (int32_t)ppc_result_d >> shift;
|
||||
if ((ppc_result_d & 0x80000000UL) && (ppc_result_d & mask)) {
|
||||
ppc_state.ppc_spr[SPR::XER] |= 0x20000000UL;
|
||||
} else {
|
||||
ppc_state.ppc_spr[SPR::XER] &= 0xDFFFFFFFUL;
|
||||
}
|
||||
}
|
||||
ppc_store_result_rega();
|
||||
}
|
||||
|
||||
void ppc_srawdot() {
|
||||
ppc_grab_regssab();
|
||||
if (ppc_result_b > 32) {
|
||||
ppc_result_a = ((ppc_result_d) > 0x7FFFFFFF) ? 0xFFFFFFFFUL : 0x0;
|
||||
ppc_state.ppc_spr[SPR::XER] = (ppc_state.ppc_spr[SPR::XER] & 0xDFFFFFFFUL) | (((ppc_result_d) > 0x7FFFFFFF) ? 0x20000000 : 0x0);
|
||||
}
|
||||
else {
|
||||
ppc_result_a = (uint32_t)((int32_t)ppc_result_d >> ppc_result_b);
|
||||
ppc_state.ppc_spr[SPR::XER] = (ppc_state.ppc_spr[SPR::XER] & 0xDFFFFFFFUL) | (((ppc_result_d) > 0x7FFFFFFF) ? 0x20000000 : 0x0);
|
||||
if (ppc_result_b & 0x20) {
|
||||
ppc_result_a = (int32_t)ppc_result_d >> 31;
|
||||
ppc_state.ppc_spr[SPR::XER] |= (ppc_result_a & 1) << 29;
|
||||
} else {
|
||||
uint32_t shift = ppc_result_b & 0x1F;
|
||||
uint32_t mask = (1 << shift) - 1;
|
||||
ppc_result_a = (int32_t)ppc_result_d >> shift;
|
||||
if ((ppc_result_d & 0x80000000UL) && (ppc_result_d & mask)) {
|
||||
ppc_state.ppc_spr[SPR::XER] |= 0x20000000UL;
|
||||
} else {
|
||||
ppc_state.ppc_spr[SPR::XER] &= 0xDFFFFFFFUL;
|
||||
}
|
||||
}
|
||||
ppc_changecrf0(ppc_result_a);
|
||||
ppc_store_result_rega();
|
||||
@ -1160,21 +1185,27 @@ void ppc_srawdot() {
|
||||
|
||||
void ppc_srawi() {
|
||||
ppc_grab_regssa();
|
||||
unsigned rot_sh = (ppc_cur_instruction >> 11) & 31;
|
||||
|
||||
ppc_result_a = (uint32_t)((int32_t)ppc_result_d >> rot_sh);
|
||||
ppc_state.ppc_spr[SPR::XER] = (ppc_state.ppc_spr[SPR::XER] & 0xDFFFFFFFUL) | (((ppc_result_d) > 0x7FFFFFFF) ? 0x20000000 : 0x0);
|
||||
|
||||
unsigned shift = (ppc_cur_instruction >> 11) & 0x1F;
|
||||
uint32_t mask = (1 << shift) - 1;
|
||||
ppc_result_a = (int32_t)ppc_result_d >> shift;
|
||||
if ((ppc_result_d & 0x80000000UL) && (ppc_result_d & mask)) {
|
||||
ppc_state.ppc_spr[SPR::XER] |= 0x20000000UL;
|
||||
} else {
|
||||
ppc_state.ppc_spr[SPR::XER] &= 0xDFFFFFFFUL;
|
||||
}
|
||||
ppc_store_result_rega();
|
||||
}
|
||||
|
||||
void ppc_srawidot() {
|
||||
ppc_grab_regssa();
|
||||
unsigned rot_sh = (ppc_cur_instruction >> 11) & 31;
|
||||
|
||||
ppc_result_a = (uint32_t)((int32_t)ppc_result_d >> rot_sh);
|
||||
ppc_state.ppc_spr[SPR::XER] = (ppc_state.ppc_spr[SPR::XER] & 0xDFFFFFFFUL) | (((ppc_result_d) > 0x7FFFFFFF) ? 0x20000000 : 0x0);
|
||||
|
||||
unsigned shift = (ppc_cur_instruction >> 11) & 0x1F;
|
||||
uint32_t mask = (1 << shift) - 1;
|
||||
ppc_result_a = (int32_t)ppc_result_d >> shift;
|
||||
if ((ppc_result_d & 0x80000000UL) && (ppc_result_d & mask)) {
|
||||
ppc_state.ppc_spr[SPR::XER] |= 0x20000000UL;
|
||||
} else {
|
||||
ppc_state.ppc_spr[SPR::XER] &= 0xDFFFFFFFUL;
|
||||
}
|
||||
ppc_changecrf0(ppc_result_a);
|
||||
ppc_store_result_rega();
|
||||
}
|
||||
|
@ -143,13 +143,34 @@ def gen_ppc_opcode(opc_str, imm):
|
||||
return (0x18 << 26) + (3 << 21) + (3 << 16) + (imm & 0xFFFF)
|
||||
elif opc_str == "ORIS":
|
||||
return (0x19 << 26) + (3 << 21) + (3 << 16) + (imm & 0xFFFF)
|
||||
elif opc_str == "SLW":
|
||||
return (0x1F << 26) + (3 << 21) + (3 << 16) + (4 << 11) + (0x18 << 1)
|
||||
elif opc_str == "SLW.":
|
||||
return (0x1F << 26) + (3 << 21) + (3 << 16) + (4 << 11) + (0x18 << 1) + 1
|
||||
elif opc_str == "SRAW":
|
||||
return (0x1F << 26) + (3 << 21) + (3 << 16) + (4 << 11) + (0x318 << 1)
|
||||
elif opc_str == "SRAW.":
|
||||
return (0x1F << 26) + (3 << 21) + (3 << 16) + (4 << 11) + (0x318 << 1) + 1
|
||||
elif opc_str == "SRAWI":
|
||||
return (0x1F << 26) + (3 << 21) + (3 << 16) + ((imm & 0x1F) << 11) + (0x338 << 1)
|
||||
elif opc_str == "SRW":
|
||||
return (0x1F << 26) + (3 << 21) + (3 << 16) + (4 << 11) + (0x218 << 1)
|
||||
elif opc_str == "SRW.":
|
||||
return (0x1F << 26) + (3 << 21) + (3 << 16) + (4 << 11) + (0x218 << 1) + 1
|
||||
|
||||
def gen_rot_opcode(opc_str, sh, mb, me):
|
||||
if opc_str == "RLWIMI":
|
||||
return (0x14 << 26) + (4 << 21) + (3 << 16) + (sh << 11) + (mb << 6) + (me << 1)
|
||||
|
||||
def find_imm(line):
|
||||
def extract_imm(line):
|
||||
pos = 12
|
||||
while pos < len(line):
|
||||
reg_id = line[pos:pos+4]
|
||||
if reg_id.startswith("rD") or reg_id.startswith("rA") or reg_id.startswith("rB"):
|
||||
if reg_id.startswith("rD") or reg_id.startswith("rA"):
|
||||
pos += 16
|
||||
elif reg_id.startswith("rB"):
|
||||
if opcode.startswith("SRAWI"):
|
||||
return int(line[pos+3:pos+13], base=16)
|
||||
pos += 16
|
||||
elif reg_id.startswith("XER:"):
|
||||
pos += 18
|
||||
@ -159,18 +180,53 @@ def find_imm(line):
|
||||
return int(line[pos+4:pos+14], base=16)
|
||||
return 0
|
||||
|
||||
def extract_rot_params(line):
|
||||
pos = 12
|
||||
sh = 0
|
||||
mb = 0
|
||||
me = 0
|
||||
while pos < len(line):
|
||||
reg_id = line[pos:pos+4]
|
||||
if reg_id.startswith("rD") or reg_id.startswith("rA") or reg_id.startswith("rB") or reg_id.startswith("rS"):
|
||||
pos += 16
|
||||
elif reg_id.startswith("XER:"):
|
||||
pos += 18
|
||||
elif reg_id.startswith("CR:"):
|
||||
pos += 17
|
||||
elif reg_id.startswith("SH"):
|
||||
sh = int(line[pos+3:pos+13], base=16)
|
||||
pos += 16
|
||||
elif reg_id.startswith("MB:"):
|
||||
mb = int(line[pos+4:pos+14], base=16)
|
||||
pos += 17
|
||||
elif reg_id.startswith("ME:"):
|
||||
me = int(line[pos+4:pos+14], base=16)
|
||||
pos += 17
|
||||
return (sh, mb, me)
|
||||
|
||||
|
||||
with open("instruction_tests_console.txt", "r") as in_file:
|
||||
with open("ppcinttests.csv", "w") as out_file:
|
||||
lineno = 0
|
||||
for line in in_file:
|
||||
lineno += 1
|
||||
if lineno >= 536 and lineno < 1688:
|
||||
continue; # skip buggy rotation instructions tests
|
||||
if lineno >= 2728 and lineno < 3248:
|
||||
continue; # skip buggy srawi instructions tests
|
||||
if lineno >= 3768:
|
||||
break
|
||||
|
||||
line = line.strip()
|
||||
opcode = (line[0:8]).rstrip()
|
||||
out_file.write(opcode + ",")
|
||||
|
||||
imm = find_imm(line)
|
||||
|
||||
out_file.write("0x{:X}".format(gen_ppc_opcode(opcode, imm)))
|
||||
if opcode.startswith("RLWI"):
|
||||
sh, mb, me = extract_rot_params(line)
|
||||
out_file.write("0x{:X}".format(gen_rot_opcode(opcode, sh, mb, me)))
|
||||
else:
|
||||
imm = extract_imm(line)
|
||||
out_file.write("0x{:X}".format(gen_ppc_opcode(opcode, imm)))
|
||||
|
||||
pos = 12
|
||||
|
||||
@ -179,11 +235,14 @@ with open("instruction_tests_console.txt", "r") as in_file:
|
||||
if reg_id.startswith("rD"):
|
||||
out_file.write(",rD=" + line[pos+3:pos+13])
|
||||
pos += 16
|
||||
elif reg_id.startswith("rA"):
|
||||
elif reg_id.startswith("rA") or reg_id.startswith("rS"):
|
||||
out_file.write(",rA=" + line[pos+3:pos+13])
|
||||
pos += 16
|
||||
elif reg_id.startswith("rB"):
|
||||
out_file.write(",rB=" + line[pos+3:pos+13])
|
||||
if opcode.startswith("SRAWI"):
|
||||
pass
|
||||
else:
|
||||
out_file.write(",rB=" + line[pos+3:pos+13])
|
||||
pos += 16
|
||||
elif reg_id.startswith("XER:"):
|
||||
out_file.write(",XER=" + line[pos+5:pos+15])
|
||||
@ -193,12 +252,12 @@ with open("instruction_tests_console.txt", "r") as in_file:
|
||||
pos += 17
|
||||
elif reg_id.startswith("imm"):
|
||||
pos += 17 # ignore immediate operands
|
||||
elif reg_id.startswith("SH"):
|
||||
pos += 16
|
||||
elif reg_id.startswith("MB:") or reg_id.startswith("ME:"):
|
||||
pos += 17
|
||||
else:
|
||||
out_file.write("Unknown reg ID" + reg_id)
|
||||
break
|
||||
|
||||
out_file.write("\n")
|
||||
|
||||
lineno += 1
|
||||
if lineno > 534:
|
||||
break
|
||||
|
@ -533,7 +533,6 @@ ORIS :: rD 0x00010001 | rA 0x00000001 | imm 0x00000001 | XER: 0x00000000 | C
|
||||
ORIS :: rD 0x1FFF0001 | rA 0x00000001 | imm 0x00001FFF | XER: 0x00000000 | CR: 0x00000000
|
||||
ORIS :: rD 0x3FFF0001 | rA 0x00000001 | imm 0x00003FFF | XER: 0x00000000 | CR: 0x00000000
|
||||
ORIS :: rD 0x7FFF0001 | rA 0x00000001 | imm 0x00007FFF | XER: 0x00000000 | CR: 0x00000000
|
||||
RL[x] Variants
|
||||
RLWIMI :: rD 0xE00001F9 | rS 0x0000001E | SH 0x00000000 | MB: 0x00000000 | ME: 0x0000000A | XER: 0x00000000 | CR: 0x00000000
|
||||
RLWIMI :: rD 0xE0000001 | rS 0x0000001E | SH 0x00000000 | MB: 0x00000000 | ME: 0x0000000A | XER: 0x00000000 | CR: 0x00000000
|
||||
RLWIMI :: rD 0xE00001F9 | rS 0x0000001E | SH 0x00000000 | MB: 0x00000000 | ME: 0x0000000A | XER: 0x00000000 | CR: 0x00000000
|
||||
@ -1686,7 +1685,6 @@ RLWINM. :: rD 0x00000000 | rS 0x0000001E | SH 0x0000001F | MB: 0x0000000A | ME:
|
||||
RLWINM. :: rD 0x00000000 | rS 0x0000001E | SH 0x0000001F | MB: 0x00000014 | ME: 0x0000001E | XER: 0x00000000 | CR: 0x20000000
|
||||
RLWINM. :: rD 0x00000000 | rS 0x0000001E | SH 0x0000001F | MB: 0x00000014 | ME: 0x0000001E | XER: 0x00000000 | CR: 0x20000000
|
||||
RLWINM. :: rD 0x00000000 | rS 0x0000001E | SH 0x0000001F | MB: 0x00000014 | ME: 0x0000001E | XER: 0x00000000 | CR: 0x20000000
|
||||
Shift Variants
|
||||
SLW :: rD 0x00000000 | rA 0x00000000 | rB 0x00000000 | XER: 0x00000000 | CR: 0x00000000
|
||||
SLW :: rD 0x00000001 | rA 0x00000001 | rB 0x00000000 | XER: 0x00000000 | CR: 0x00000000
|
||||
SLW :: rD 0x7FFFFFFF | rA 0x7FFFFFFF | rB 0x00000000 | XER: 0x00000000 | CR: 0x00000000
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -91,7 +91,8 @@ void read_test_data()
|
||||
<< check_xer << ", CR=0x" << hex << check_cr << endl;
|
||||
cout << "got: dest=0x" << hex << ppc_state.ppc_gpr[3] << ", XER=0x"
|
||||
<< hex << ppc_state.ppc_spr[SPR::XER] << ", CR=0x" << hex
|
||||
<< ppc_state.ppc_cr << endl << endl;
|
||||
<< ppc_state.ppc_cr << endl;
|
||||
cout << "Test file line #: " << dec << lineno << endl << endl;
|
||||
|
||||
nfailed++;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user