mirror of
https://github.com/dingusdev/dingusppc.git
synced 2024-09-29 17:56:59 +00:00
Preliminary work on floating point tests
This commit is contained in:
parent
05330bc942
commit
07a4166eef
@ -99,6 +99,90 @@ def gen_ppc_opcode(opc_str, imm):
|
||||
return (0x1F << 26) + (3 << 21) + (3 << 16) + (0x39A << 1)
|
||||
elif opc_str == "EXTSH.":
|
||||
return (0x1F << 26) + (3 << 21) + (3 << 16) + (0x39A << 1) + 1
|
||||
elif opc_str == "FABS":
|
||||
return (0x3F << 26) + (3 << 21) + (3 << 16) + (4 << 11) + (0x108 << 1)
|
||||
elif opc_str == "FABS.":
|
||||
return (0x3F << 26) + (3 << 21) + (3 << 16) + (4 << 11) + (0x108 << 1) + 1
|
||||
elif opc_str == "FADD":
|
||||
return (0x3F << 26) + (3 << 21) + (3 << 16) + (4 << 11) + (0x15 << 1)
|
||||
elif opc_str == "FADD.":
|
||||
return (0x3F << 26) + (3 << 21) + (3 << 16) + (4 << 11) + (0x15 << 1) + 1
|
||||
elif opc_str == "FADDS":
|
||||
return (0x3B << 26) + (3 << 21) + (3 << 16) + (4 << 11) + (0x15 << 1)
|
||||
elif opc_str == "FADDS.":
|
||||
return (0x3B << 26) + (3 << 21) + (3 << 16) + (4 << 11) + (0x15 << 1) + 1
|
||||
elif opc_str == "FCMPO":
|
||||
return (0x3B << 26) + (3 << 16) + (4 << 11) + (0x20 << 1)
|
||||
elif opc_str == "FCMPU":
|
||||
return (0x3B << 26) + (3 << 16) + (4 << 11)
|
||||
elif opc_str == "FCTIW":
|
||||
return (0x3B << 26) + (3 << 16) + (4 << 11) + (0xE << 1)
|
||||
elif opc_str == "FCTIW.":
|
||||
return (0x3B << 26) + (3 << 16) + (4 << 11) + (0xE << 1) + 1
|
||||
elif opc_str == "FCTIWZ":
|
||||
return (0x3B << 26) + (3 << 16) + (4 << 11) + (0xF << 1)
|
||||
elif opc_str == "FCTIWZ.":
|
||||
return (0x3B << 26) + (3 << 16) + (4 << 11) + (0xF << 1) + 1
|
||||
elif opc_str == "FDIV":
|
||||
return (0x3F << 26) + (3 << 21) + (3 << 16) + (4 << 11) + (0x12 << 1)
|
||||
elif opc_str == "FDIV.":
|
||||
return (0x3F << 26) + (3 << 21) + (3 << 16) + (4 << 11) + (0x12 << 1) + 1
|
||||
elif opc_str == "FMADD":
|
||||
return (0x3F << 26) + (3 << 21) + (3 << 16) + (4 << 11) + (4 << 6) + (0x1D << 1)
|
||||
elif opc_str == "FMADD.":
|
||||
return (0x3F << 26) + (3 << 21) + (3 << 16) + (4 << 11) + (4 << 6) + (0x1D << 1) + 1
|
||||
elif opc_str == "FMADDS":
|
||||
return (0x3F << 26) + (3 << 21) + (3 << 16) + (4 << 11) + (4 << 6) + (0x1D << 1)
|
||||
elif opc_str == "FMADDS.":
|
||||
return (0x3F << 26) + (3 << 21) + (3 << 16) + (4 << 11) + (4 << 6) + (0x1D << 1) + 1
|
||||
elif opc_str == "FMUL":
|
||||
return (0x3F << 26) + (3 << 21) + (3 << 16) + (4 << 6) + (0x19 << 1)
|
||||
elif opc_str == "FMUL.":
|
||||
return (0x3F << 26) + (3 << 21) + (3 << 16) + (4 << 6) + (0x19 << 1) + 1
|
||||
elif opc_str == "FMULS":
|
||||
return (0x3B << 26) + (3 << 21) + (3 << 16) + (4 << 6) + (0x19 << 1)
|
||||
elif opc_str == "FMULS.":
|
||||
return (0x3B << 26) + (3 << 21) + (3 << 16) + (4 << 6) + (0x19 << 1) + 1
|
||||
elif opc_str == "FNABS":
|
||||
return (0x3F << 26) + (3 << 21) + (3 << 16) + (4 << 6) + (0x88 << 1)
|
||||
elif opc_str == "FNABS.":
|
||||
return (0x3F << 26) + (3 << 21) + (3 << 16) + (4 << 6) + (0x88 << 1) + 1
|
||||
elif opc_str == "FNEG":
|
||||
return (0x3B << 26) + (3 << 21) + (3 << 16) + (4 << 6) + (0x28 << 1)
|
||||
elif opc_str == "FMULS.":
|
||||
return (0x3B << 26) + (3 << 21) + (3 << 16) + (4 << 6) + (0x28 << 1) + 1
|
||||
elif opc_str == "FMSUB":
|
||||
return (0x3F << 26) + (3 << 21) + (3 << 16) + (4 << 11) + (4 << 6) + (0x1C << 1)
|
||||
elif opc_str == "FMSUB.":
|
||||
return (0x3F << 26) + (3 << 21) + (3 << 16) + (4 << 11) + (4 << 6) + (0x1C << 1) + 1
|
||||
elif opc_str == "FMSUBS":
|
||||
return (0x3F << 26) + (3 << 21) + (3 << 16) + (4 << 11) + (4 << 6) + (0x1C << 1)
|
||||
elif opc_str == "FMSUBS.":
|
||||
return (0x3F << 26) + (3 << 21) + (3 << 16) + (4 << 11) + (4 << 6) + (0x1C << 1) + 1
|
||||
elif opc_str == "FNMADD":
|
||||
return (0x3F << 26) + (3 << 21) + (3 << 16) + (4 << 11) + (4 << 6) + (0x1F << 1)
|
||||
elif opc_str == "FNMADD.":
|
||||
return (0x3F << 26) + (3 << 21) + (3 << 16) + (4 << 11) + (4 << 6) + (0x1F << 1) + 1
|
||||
elif opc_str == "FNMADDS":
|
||||
return (0x3F << 26) + (3 << 21) + (3 << 16) + (4 << 11) + (4 << 6) + (0x1F << 1)
|
||||
elif opc_str == "FNMADDS.":
|
||||
return (0x3F << 26) + (3 << 21) + (3 << 16) + (4 << 11) + (4 << 6) + (0x1F << 1) + 1
|
||||
elif opc_str == "FNMSUB":
|
||||
return (0x3F << 26) + (3 << 21) + (3 << 16) + (4 << 11) + (4 << 6) + (0x1C << 1)
|
||||
elif opc_str == "FNMSUB.":
|
||||
return (0x3F << 26) + (3 << 21) + (3 << 16) + (4 << 11) + (4 << 6) + (0x1C << 1) + 1
|
||||
elif opc_str == "FNMSUBS":
|
||||
return (0x3F << 26) + (3 << 21) + (3 << 16) + (4 << 11) + (4 << 6) + (0x1C << 1)
|
||||
elif opc_str == "FNMSUBS.":
|
||||
return (0x3F << 26) + (3 << 21) + (3 << 16) + (4 << 11) + (4 << 6) + (0x1C << 1) + 1
|
||||
elif opc_str == "FSUB":
|
||||
return (0x3F << 26) + (3 << 21) + (3 << 16) + (4 << 11) + (0x15 << 1)
|
||||
elif opc_str == "FSUB.":
|
||||
return (0x3F << 26) + (3 << 21) + (3 << 16) + (4 << 11) + (0x15 << 1) + 1
|
||||
elif opc_str == "FSUBS":
|
||||
return (0x3B << 26) + (3 << 21) + (3 << 16) + (4 << 11) + (0x15 << 1)
|
||||
elif opc_str == "FSUBS.":
|
||||
return (0x3B << 26) + (3 << 21) + (3 << 16) + (4 << 11) + (0x15 << 1) + 1
|
||||
elif opc_str == "MULHW":
|
||||
return (0x1F << 26) + (3 << 21) + (3 << 16) + (4 << 11) + (0x4B << 1)
|
||||
elif opc_str == "MULHW.":
|
||||
@ -263,50 +347,98 @@ def extract_rot_params(line):
|
||||
return (sh, mb, me)
|
||||
|
||||
|
||||
with open("ppcinttest.txt", "r") as in_file:
|
||||
with open("ppcinttests.csv", "w") as out_file:
|
||||
lineno = 0
|
||||
for line in in_file:
|
||||
lineno += 1
|
||||
if __name__ == "__main__":
|
||||
with open("ppcinttest.txt", "r") as in_file:
|
||||
with open("ppcinttests.csv", "w") as out_file:
|
||||
lineno = 0
|
||||
for line in in_file:
|
||||
lineno += 1
|
||||
|
||||
line = line.strip()
|
||||
opcode = (line[0:8]).rstrip().upper()
|
||||
out_file.write(opcode + ",")
|
||||
line = line.strip()
|
||||
opcode = (line[0:8]).rstrip().upper()
|
||||
out_file.write(opcode + ",")
|
||||
|
||||
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
|
||||
|
||||
while pos < len(line):
|
||||
reg_id = line[pos:pos+4]
|
||||
if reg_id.startswith("rD"):
|
||||
out_file.write(",rD=" + line[pos+3:pos+13])
|
||||
pos += 16
|
||||
elif reg_id.startswith("rA"):
|
||||
out_file.write(",rA=" + line[pos+3:pos+13])
|
||||
pos += 16
|
||||
elif reg_id.startswith("rB") or reg_id.startswith("rS"):
|
||||
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])
|
||||
pos += 18
|
||||
elif reg_id.startswith("CR:"):
|
||||
out_file.write(",CR=" + line[pos+4:pos+14])
|
||||
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 += 16
|
||||
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:
|
||||
out_file.write("Unknown reg ID" + reg_id)
|
||||
break
|
||||
imm = extract_imm(line)
|
||||
out_file.write("0x{:X}".format(gen_ppc_opcode(opcode, imm)))
|
||||
|
||||
out_file.write("\n")
|
||||
pos = 12
|
||||
|
||||
while pos < len(line):
|
||||
reg_id = line[pos:pos+4]
|
||||
if reg_id.startswith("rD"):
|
||||
out_file.write(",rD=" + line[pos+3:pos+13])
|
||||
pos += 16
|
||||
elif reg_id.startswith("rA"):
|
||||
out_file.write(",rA=" + line[pos+3:pos+13])
|
||||
pos += 16
|
||||
elif reg_id.startswith("rB") or reg_id.startswith("rS"):
|
||||
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])
|
||||
pos += 18
|
||||
elif reg_id.startswith("CR:"):
|
||||
out_file.write(",CR=" + line[pos+4:pos+14])
|
||||
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 += 16
|
||||
else:
|
||||
out_file.write("Unknown reg ID" + reg_id)
|
||||
break
|
||||
|
||||
out_file.write("\n")
|
||||
|
||||
with open("ppcfloattest.txt", "r") as in_file:
|
||||
with open("ppcfloattests.csv", "w") as out_file:
|
||||
lineno = 0
|
||||
for line in in_file:
|
||||
lineno += 1
|
||||
|
||||
line = line.strip()
|
||||
opcode = (line[0:8]).rstrip().upper()
|
||||
out_file.write(opcode + ",")
|
||||
|
||||
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
|
||||
|
||||
while pos < len(line):
|
||||
reg_id = line[pos:pos+4]
|
||||
if reg_id.startswith("frD"):
|
||||
out_file.write(",frD=" + line[pos+4:pos+14])
|
||||
pos += 16
|
||||
elif reg_id.startswith("frA"):
|
||||
out_file.write(",frA=" + line[pos+4:pos+14])
|
||||
pos += 16
|
||||
elif reg_id.startswith("frB"):
|
||||
out_file.write(",frB=" + line[pos+4:pos+14])
|
||||
pos += 16
|
||||
elif reg_id.startswith("frC"):
|
||||
out_file.write(",frC=" + line[pos+4:pos+14])
|
||||
pos += 16
|
||||
elif reg_id.startswith("FPSCR:"):
|
||||
out_file.write(",FPSCR=" + line[pos+7:pos+17])
|
||||
pos += 19
|
||||
elif reg_id.startswith("CR:"):
|
||||
out_file.write(",CR=" + line[pos+4:pos+14])
|
||||
pos += 17
|
||||
elif reg_id.startswith("imm"):
|
||||
pos += 17 # ignore immediate operands
|
||||
else:
|
||||
out_file.write("Unknown reg ID" + reg_id)
|
||||
break
|
||||
|
||||
out_file.write("\n")
|
4
cpu/ppc/test/ppcfloattest.txt
Normal file
4
cpu/ppc/test/ppcfloattest.txt
Normal file
@ -0,0 +1,4 @@
|
||||
FADD (RTN) :: frD 0x0000000000000000 | frA 0.000000e+00 | frB 0.000000e+00 | FPSCR: 0x00002000 | CR: 0x20000000
|
||||
FADD (RTZ) :: frD 0x0000000000000000 | frA 0.000000e+00 | frB 0.000000e+00 | FPSCR: 0x00002001 | CR: 0x40000002
|
||||
FADD (RTPI) :: frD 0x0000000000000000 | frA 0.000000e+00 | frB 0.000000e+00 | FPSCR: 0x00002002 | CR: 0x40000002
|
||||
FADD (RTNI) :: frD 0x0000000000000000 | frA 0.000000e+00 | frB 0.000000e+00 | FPSCR: 0x00002003 | CR: 0x40000002
|
1
cpu/ppc/test/ppcfloattests.csv
Normal file
1
cpu/ppc/test/ppcfloattests.csv
Normal file
@ -0,0 +1 @@
|
||||
FADD,0xFC64282A,round=RTN,frD=0x0000000000000000,frA=0.000000e+00,frB=0.000000e+00,FPSCR=0x00002000,CR=0x20000000
|
|
@ -117,6 +117,7 @@ static void read_test_data() {
|
||||
|
||||
ppc_state.gpr[3] = src1;
|
||||
ppc_state.gpr[4] = src2;
|
||||
|
||||
ppc_state.spr[SPR::XER] = 0;
|
||||
ppc_state.cr = 0;
|
||||
|
||||
@ -141,6 +142,127 @@ static void read_test_data() {
|
||||
}
|
||||
}
|
||||
|
||||
static void read_test_float_data() {
|
||||
string line, token;
|
||||
int i, lineno;
|
||||
|
||||
uint32_t opcode, dest, src1, src2, check_xer, check_cr, check_fpscr;
|
||||
uint64_t dest_64, src1_64, src2_64;
|
||||
float sfp_dest, sfp_src1, sfp_src2, sfp_src3;
|
||||
double dfp_dest, dfp_src1, dfp_src2, dfp_src3;
|
||||
string rounding_mode;
|
||||
|
||||
ifstream tf2stream("ppcfloattests.csv");
|
||||
if (!tf2stream.is_open()) {
|
||||
cout << "Could not open tests CSV file. Exiting..." << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
lineno = 0;
|
||||
|
||||
while (getline(tf2stream, line)) {
|
||||
lineno++;
|
||||
|
||||
if (line.empty() || !line.rfind("#", 0))
|
||||
continue; /* skip empty/comment lines */
|
||||
|
||||
istringstream lnstream(line);
|
||||
|
||||
vector<string> tokens;
|
||||
|
||||
while (getline(lnstream, token, ',')) {
|
||||
tokens.push_back(token);
|
||||
}
|
||||
|
||||
if (tokens.size() < 5) {
|
||||
cout << "Too few values in line " << lineno << ". Skipping..." << endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
opcode = stoul(tokens[1], NULL, 16);
|
||||
|
||||
dest = 0;
|
||||
src1 = 0;
|
||||
src2 = 0;
|
||||
check_xer = 0;
|
||||
check_cr = 0;
|
||||
check_fpscr = 0;
|
||||
sfp_dest = 0.0;
|
||||
sfp_src1 = 0.0;
|
||||
sfp_src2 = 0.0;
|
||||
sfp_src3 = 0.0;
|
||||
dfp_dest = 0.0;
|
||||
dfp_src1 = 0.0;
|
||||
dfp_src2 = 0.0;
|
||||
dfp_src3 = 0.0;
|
||||
|
||||
for (i = 2; i < tokens.size(); i++) {
|
||||
if (tokens[i].rfind("frD=", 0) == 0) {
|
||||
dfp_dest = stoul(tokens[i].substr(4), NULL, 16);
|
||||
} else if (tokens[i].rfind("frA=", 0) == 0) {
|
||||
dfp_src1 = stoul(tokens[i].substr(4), NULL, 16);
|
||||
} else if (tokens[i].rfind("frB=", 0) == 0) {
|
||||
dfp_src2 = stoul(tokens[i].substr(4), NULL, 16);
|
||||
} else if (tokens[i].rfind("frC=", 0) == 0) {
|
||||
dfp_src3 = stoul(tokens[i].substr(4), NULL, 16);
|
||||
} else if (tokens[i].rfind("round=", 0) == 0) {
|
||||
rounding_mode = tokens[i].substr(6, 3);
|
||||
ppc_state.fpscr &= 0xFFFFFFFC;
|
||||
if (rounding_mode.compare("RTN") == 0) {
|
||||
ppc_state.fpscr |= 0x0;
|
||||
} else if (rounding_mode.compare("RTZ") == 0) {
|
||||
ppc_state.fpscr |= 0x1;
|
||||
} else if (rounding_mode.compare("RPI") == 0) {
|
||||
ppc_state.fpscr |= 0x2;
|
||||
} else if (rounding_mode.compare("RNI") == 0) {
|
||||
ppc_state.fpscr |= 0x3;
|
||||
} else {
|
||||
cout << "ILLEGAL ROUNDING METHOD: " << tokens[i] << " in line " << lineno
|
||||
<< ". Exiting..." << endl;
|
||||
exit(0);
|
||||
}
|
||||
} else if (tokens[i].rfind("FPSCR=", 0) == 0) {
|
||||
check_cr = stoul(tokens[i].substr(6), NULL, 16);
|
||||
} else if (tokens[i].rfind("CR=", 0) == 0) {
|
||||
check_cr = stoul(tokens[i].substr(3), NULL, 16);
|
||||
} else {
|
||||
cout << "Unknown parameter " << tokens[i] << " in line " << lineno << ". Exiting..."
|
||||
<< endl;
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
ppc_state.gpr[3] = src1;
|
||||
ppc_state.gpr[4] = src2;
|
||||
|
||||
ppc_state.fpr[3].dbl64_r = dfp_src1;
|
||||
ppc_state.fpr[4].dbl64_r = dfp_src2;
|
||||
ppc_state.fpr[5].dbl64_r = dfp_src3;
|
||||
|
||||
ppc_state.spr[SPR::XER] = 0;
|
||||
ppc_state.cr = 0;
|
||||
|
||||
ppc_cur_instruction = opcode;
|
||||
|
||||
ppc_main_opcode();
|
||||
|
||||
ntested++;
|
||||
|
||||
if ((tokens[0].rfind("FCMP") && (ppc_state.gpr[3] != dest)) || (ppc_state.fpscr != check_fpscr) ||
|
||||
(ppc_state.cr != check_cr)) {
|
||||
cout << "Mismatch: instr=" << tokens[0] << ", src1=0x" << hex << src1 << ", src2=0x" << hex
|
||||
<< src2 << endl;
|
||||
cout << "expected: dest=0x" << hex << dest << ", FPSCR=0x" << hex << check_xer << ", CR=0x"
|
||||
<< hex << check_cr << endl;
|
||||
cout << "got: dest=0x" << hex << ppc_state.gpr[3] << ", FPSCR=0x" << hex
|
||||
<< ppc_state.fpscr << ", CR=0x" << hex << ppc_state.cr << endl;
|
||||
cout << "Test file line #: " << dec << lineno << endl << endl;
|
||||
|
||||
nfailed++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
initialize_ppc_opcode_tables(); //kludge
|
||||
|
||||
@ -157,6 +279,10 @@ int main() {
|
||||
|
||||
read_test_data();
|
||||
|
||||
cout << endl << "Testing floating point instructions:" << endl;
|
||||
|
||||
read_test_float_data();
|
||||
|
||||
cout << "... completed." << endl;
|
||||
cout << "--> Tested instructions: " << dec << ntested << endl;
|
||||
cout << "--> Failed: " << dec << nfailed << endl << endl;
|
||||
|
Loading…
Reference in New Issue
Block a user