DSPTool now accepts multiple files with the '-m' flag. See usage for more information.
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@3406 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
759263351a
commit
aeb7053230
|
@ -113,7 +113,6 @@ void GenRandomCode(int size, std::vector<u16> &code)
|
||||||
|
|
||||||
void CodeToHeader(const std::vector<u16> &code, const char *name, std::string &header)
|
void CodeToHeader(const std::vector<u16> &code, const char *name, std::string &header)
|
||||||
{
|
{
|
||||||
int const ucodes = 1; // TODO: Make variable size
|
|
||||||
std::vector<u16> code_copy = code;
|
std::vector<u16> code_copy = code;
|
||||||
// Add some nops at the end to align the size a bit.
|
// Add some nops at the end to align the size a bit.
|
||||||
while (code_copy.size() & 7)
|
while (code_copy.size() & 7)
|
||||||
|
@ -121,8 +120,7 @@ void CodeToHeader(const std::vector<u16> &code, const char *name, std::string &h
|
||||||
char buffer[1024];
|
char buffer[1024];
|
||||||
header.clear();
|
header.clear();
|
||||||
header.reserve(code.size() * 4);
|
header.reserve(code.size() * 4);
|
||||||
sprintf(buffer, "#define NUM_UCODES %d\n\n", ucodes);
|
header.append("#define NUM_UCODES 1\n\n");
|
||||||
header.append(buffer);
|
|
||||||
header.append("#ifndef _MSCVER\n");
|
header.append("#ifndef _MSCVER\n");
|
||||||
sprintf(buffer, "const unsigned short %s[NUM_UCODES][0x1000] = {\n", name);
|
sprintf(buffer, "const unsigned short %s[NUM_UCODES][0x1000] = {\n", name);
|
||||||
header.append(buffer);
|
header.append(buffer);
|
||||||
|
@ -131,13 +129,55 @@ void CodeToHeader(const std::vector<u16> &code, const char *name, std::string &h
|
||||||
header.append(buffer);
|
header.append(buffer);
|
||||||
header.append("#endif\n\n");
|
header.append("#endif\n\n");
|
||||||
|
|
||||||
for(int i = 0; i < ucodes; i++) {
|
header.append("\t{\n\t\t");
|
||||||
|
for (int j = 0; j < code.size(); j++)
|
||||||
|
{
|
||||||
|
if (j && ((j & 15) == 0))
|
||||||
|
header.append("\n\t\t");
|
||||||
|
sprintf(buffer, "0x%04x, ", code[j]);
|
||||||
|
header.append(buffer);
|
||||||
|
}
|
||||||
|
header.append("\n\t},\n");
|
||||||
|
|
||||||
|
header.append("};\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void CodesToHeader(const std::vector<u16> *codes, int numCodes,
|
||||||
|
const char *name, std::string &header)
|
||||||
|
{
|
||||||
|
char buffer[1024];
|
||||||
|
int reserveSize = 0;
|
||||||
|
for(int i = 0; i < numCodes; i++)
|
||||||
|
reserveSize += (int)codes[i].size();
|
||||||
|
|
||||||
|
|
||||||
|
header.clear();
|
||||||
|
header.reserve(reserveSize * 4);
|
||||||
|
sprintf(buffer, "#define NUM_UCODES %d\n\n", numCodes);
|
||||||
|
header.append(buffer);
|
||||||
|
header.append("#ifndef _MSCVER\n");
|
||||||
|
sprintf(buffer, "const unsigned short %s[NUM_UCODES][0x1000] = {\n", name);
|
||||||
|
header.append(buffer);
|
||||||
|
header.append("#else\n");
|
||||||
|
sprintf(buffer, "const unsigned short %s[NUM_UCODES][0x1000] __attribute__ ((aligned (64))) = {\n", name);
|
||||||
|
header.append(buffer);
|
||||||
|
header.append("#endif\n\n");
|
||||||
|
|
||||||
|
for(int i = 0; i < numCodes; i++) {
|
||||||
|
if(codes[i].size() == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
std::vector<u16> code_copy = codes[i];
|
||||||
|
// Add some nops at the end to align the size a bit.
|
||||||
|
while (code_copy.size() & 7)
|
||||||
|
code_copy.push_back(0);
|
||||||
|
|
||||||
header.append("\t{\n\t\t");
|
header.append("\t{\n\t\t");
|
||||||
for (int j = 0; j < code.size(); j++)
|
for (int j = 0; j < codes[i].size(); j++)
|
||||||
{
|
{
|
||||||
if (j && ((j & 15) == 0))
|
if (j && ((j & 15) == 0))
|
||||||
header.append("\n\t\t");
|
header.append("\n\t\t");
|
||||||
sprintf(buffer, "0x%04x, ", code[j]);
|
sprintf(buffer, "0x%04x, ", codes[i][j]);
|
||||||
header.append(buffer);
|
header.append(buffer);
|
||||||
}
|
}
|
||||||
header.append("\n\t},\n");
|
header.append("\n\t},\n");
|
||||||
|
|
|
@ -28,6 +28,8 @@ bool Disassemble(const std::vector<u16> &code, bool line_numbers, std::string &t
|
||||||
bool Compare(const std::vector<u16> &code1, const std::vector<u16> &code2);
|
bool Compare(const std::vector<u16> &code1, const std::vector<u16> &code2);
|
||||||
void GenRandomCode(int size, std::vector<u16> &code);
|
void GenRandomCode(int size, std::vector<u16> &code);
|
||||||
void CodeToHeader(const std::vector<u16> &code, const char *name, std::string &header);
|
void CodeToHeader(const std::vector<u16> &code, const char *name, std::string &header);
|
||||||
|
void CodesToHeader(const std::vector<u16> *codes, int numCodes,
|
||||||
|
const char *name, std::string &header);
|
||||||
|
|
||||||
// Big-endian, for writing straight to file using File::WriteStringToFile.
|
// Big-endian, for writing straight to file using File::WriteStringToFile.
|
||||||
void CodeToBinaryStringBE(const std::vector<u16> &code, std::string &str);
|
void CodeToBinaryStringBE(const std::vector<u16> &code, std::string &str);
|
||||||
|
|
|
@ -140,7 +140,7 @@ void DSPAssembler::ShowError(err_t err_code, const char *extra_info)
|
||||||
failed = true;
|
failed = true;
|
||||||
char error_buffer[1024];
|
char error_buffer[1024];
|
||||||
char *buf_ptr = error_buffer;
|
char *buf_ptr = error_buffer;
|
||||||
buf_ptr += sprintf(buf_ptr, "%i : %s", code_line, cur_line.c_str());
|
buf_ptr += sprintf(buf_ptr, "%i : %s ", code_line, cur_line.c_str());
|
||||||
if (!extra_info)
|
if (!extra_info)
|
||||||
extra_info = "-";
|
extra_info = "-";
|
||||||
|
|
||||||
|
|
|
@ -210,9 +210,10 @@ int main(int argc, const char *argv[])
|
||||||
{
|
{
|
||||||
if(argc == 1 || (argc == 2 && (!strcmp(argv[1], "--help") || (!strcmp(argv[1], "-?")))))
|
if(argc == 1 || (argc == 2 && (!strcmp(argv[1], "--help") || (!strcmp(argv[1], "-?")))))
|
||||||
{
|
{
|
||||||
printf("USAGE: DSPTool [-?] [--help] [-d] [-o <FILE>] [-h <FILE>] <DSP ASSEMBLER FILE>\n");
|
printf("USAGE: DSPTool [-?] [--help] [-d] [-m] [-o <FILE>] [-h <FILE>] <DSP ASSEMBLER FILE>\n");
|
||||||
printf("-? / --help: Prints this message\n");
|
printf("-? / --help: Prints this message\n");
|
||||||
printf("-d: Disassemble\n");
|
printf("-d: Disassemble\n");
|
||||||
|
printf("-m: Input file contains a list of files (Header assembly only)\n");
|
||||||
printf("-o <OUTPUT FILE>: Results from stdout redirected to a file\n");
|
printf("-o <OUTPUT FILE>: Results from stdout redirected to a file\n");
|
||||||
printf("-h <HEADER FILE>: Output assembly results to a header\n");
|
printf("-h <HEADER FILE>: Output assembly results to a header\n");
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -228,8 +229,7 @@ int main(int argc, const char *argv[])
|
||||||
std::string output_header_name;
|
std::string output_header_name;
|
||||||
std::string output_name;
|
std::string output_name;
|
||||||
|
|
||||||
bool disassemble = false;
|
bool disassemble = false, compare = false, multiple = false;
|
||||||
bool compare = false;
|
|
||||||
for (int i = 1; i < argc; i++)
|
for (int i = 1; i < argc; i++)
|
||||||
{
|
{
|
||||||
if (!strcmp(argv[i], "-d"))
|
if (!strcmp(argv[i], "-d"))
|
||||||
|
@ -240,22 +240,31 @@ int main(int argc, const char *argv[])
|
||||||
output_header_name = argv[++i];
|
output_header_name = argv[++i];
|
||||||
else if (!strcmp(argv[i], "-c"))
|
else if (!strcmp(argv[i], "-c"))
|
||||||
compare = true;
|
compare = true;
|
||||||
|
else if (!strcmp(argv[i], "-m"))
|
||||||
|
multiple = true;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!input_name.empty())
|
if (!input_name.empty())
|
||||||
{
|
{
|
||||||
printf("Can only take one input file.\n");
|
printf("ERROR: Can only take one input file.\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
input_name = argv[i];
|
input_name = argv[i];
|
||||||
if (!File::Exists(input_name.c_str()))
|
if (!File::Exists(input_name.c_str()))
|
||||||
{
|
{
|
||||||
printf("Input path does not exist.\n");
|
printf("ERROR: Input path does not exist.\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(multiple && (compare || disassemble || output_header_name.empty() ||
|
||||||
|
input_name.empty())) {
|
||||||
|
printf("ERROR: Multiple files can only be used with assembly "
|
||||||
|
"and must compile a header file.\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (compare)
|
if (compare)
|
||||||
{
|
{
|
||||||
// Two binary inputs, let's diff.
|
// Two binary inputs, let's diff.
|
||||||
|
@ -297,24 +306,82 @@ int main(int argc, const char *argv[])
|
||||||
std::string source;
|
std::string source;
|
||||||
if (File::ReadFileToString(true, input_name.c_str(), source))
|
if (File::ReadFileToString(true, input_name.c_str(), source))
|
||||||
{
|
{
|
||||||
std::vector<u16> code;
|
if(multiple)
|
||||||
|
|
||||||
if(!Assemble(source.c_str(), code)) {
|
|
||||||
printf("Assemble: Assembly failed due to errors\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!output_name.empty())
|
|
||||||
{
|
{
|
||||||
std::string binary_code;
|
// When specifying a list of files we must compile a header
|
||||||
CodeToBinaryStringBE(code, binary_code);
|
// (we can't assemble multiple files to one binary)
|
||||||
File::WriteStringToFile(false, binary_code, output_name.c_str());
|
// since we checked it before, we assume output_header_name isn't empty
|
||||||
}
|
int lines;
|
||||||
if (!output_header_name.empty())
|
std::vector<u16> *codes;
|
||||||
{
|
std::vector<std::string> files;
|
||||||
std::string header;
|
std::string header, currentSource;
|
||||||
CodeToHeader(code, output_header_name.c_str(), header);
|
size_t lastPos = 0, pos = 0;
|
||||||
|
|
||||||
|
source.append("\n");
|
||||||
|
|
||||||
|
while((pos = source.find('\n', lastPos)) != std::string::npos)
|
||||||
|
{
|
||||||
|
std::string temp = source.substr(lastPos, pos - lastPos);
|
||||||
|
if(!temp.empty())
|
||||||
|
files.push_back(temp);
|
||||||
|
lastPos = pos + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
lines = (int)files.size();
|
||||||
|
|
||||||
|
if(lines == 0)
|
||||||
|
{
|
||||||
|
printf("ERROR: Must specify at least one file\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
codes = new std::vector<u16>[lines];
|
||||||
|
|
||||||
|
for(int i = 0; i < lines; i++)
|
||||||
|
{
|
||||||
|
if (!File::ReadFileToString(true, files[i].c_str(), currentSource))
|
||||||
|
{
|
||||||
|
printf("ERROR reading %s, skipping...\n", files[i].c_str());
|
||||||
|
lines--;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(!Assemble(currentSource.c_str(), codes[i]))
|
||||||
|
{
|
||||||
|
printf("Assemble: Assembly of %s failed due to errors\n",
|
||||||
|
files[i].c_str());
|
||||||
|
lines--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CodesToHeader(codes, lines, output_header_name.c_str(), header);
|
||||||
File::WriteStringToFile(true, header, (output_header_name + ".h").c_str());
|
File::WriteStringToFile(true, header, (output_header_name + ".h").c_str());
|
||||||
|
|
||||||
|
delete[] codes;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::vector<u16> code;
|
||||||
|
|
||||||
|
if(!Assemble(source.c_str(), code)) {
|
||||||
|
printf("Assemble: Assembly failed due to errors\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!output_name.empty())
|
||||||
|
{
|
||||||
|
std::string binary_code;
|
||||||
|
CodeToBinaryStringBE(code, binary_code);
|
||||||
|
File::WriteStringToFile(false, binary_code, output_name.c_str());
|
||||||
|
}
|
||||||
|
if (!output_header_name.empty())
|
||||||
|
{
|
||||||
|
std::string header;
|
||||||
|
CodeToHeader(code, output_header_name.c_str(), header);
|
||||||
|
File::WriteStringToFile(true, header, (output_header_name + ".h").c_str());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
source.clear();
|
source.clear();
|
||||||
|
@ -323,4 +390,4 @@ int main(int argc, const char *argv[])
|
||||||
printf("Assembly completed successfully!\n");
|
printf("Assembly completed successfully!\n");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue