Preliminary work on floating point tests

This commit is contained in:
dingusdev 2021-06-25 21:20:53 -07:00
parent 05330bc942
commit 07a4166eef
4 changed files with 306 additions and 43 deletions

View File

@ -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")

View 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

View File

@ -0,0 +1 @@
FADD,0xFC64282A,round=RTN,frD=0x0000000000000000,frA=0.000000e+00,frB=0.000000e+00,FPSCR=0x00002000,CR=0x20000000
1 FADD 0xFC64282A round=RTN frD=0x0000000000000000 frA=0.000000e+00 frB=0.000000e+00 FPSCR=0x00002000 CR=0x20000000

View File

@ -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;