diff --git a/Source/Core/DSPCore/Src/DSPCodeUtil.cpp b/Source/Core/DSPCore/Src/DSPCodeUtil.cpp index 5df23e09c8..3e76694a4a 100644 --- a/Source/Core/DSPCore/Src/DSPCodeUtil.cpp +++ b/Source/Core/DSPCore/Src/DSPCodeUtil.cpp @@ -113,7 +113,6 @@ void GenRandomCode(int size, std::vector &code) void CodeToHeader(const std::vector &code, const char *name, std::string &header) { - int const ucodes = 1; // TODO: Make variable size std::vector code_copy = code; // Add some nops at the end to align the size a bit. while (code_copy.size() & 7) @@ -121,8 +120,7 @@ void CodeToHeader(const std::vector &code, const char *name, std::string &h char buffer[1024]; header.clear(); header.reserve(code.size() * 4); - sprintf(buffer, "#define NUM_UCODES %d\n\n", ucodes); - header.append(buffer); + header.append("#define NUM_UCODES 1\n\n"); header.append("#ifndef _MSCVER\n"); sprintf(buffer, "const unsigned short %s[NUM_UCODES][0x1000] = {\n", name); header.append(buffer); @@ -131,13 +129,55 @@ void CodeToHeader(const std::vector &code, const char *name, std::string &h header.append(buffer); 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 *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 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"); - for (int j = 0; j < code.size(); j++) + for (int j = 0; j < codes[i].size(); j++) { if (j && ((j & 15) == 0)) header.append("\n\t\t"); - sprintf(buffer, "0x%04x, ", code[j]); + sprintf(buffer, "0x%04x, ", codes[i][j]); header.append(buffer); } header.append("\n\t},\n"); diff --git a/Source/Core/DSPCore/Src/DSPCodeUtil.h b/Source/Core/DSPCore/Src/DSPCodeUtil.h index 86477051bc..7cd7cf5a2f 100644 --- a/Source/Core/DSPCore/Src/DSPCodeUtil.h +++ b/Source/Core/DSPCore/Src/DSPCodeUtil.h @@ -28,6 +28,8 @@ bool Disassemble(const std::vector &code, bool line_numbers, std::string &t bool Compare(const std::vector &code1, const std::vector &code2); void GenRandomCode(int size, std::vector &code); void CodeToHeader(const std::vector &code, const char *name, std::string &header); +void CodesToHeader(const std::vector *codes, int numCodes, + const char *name, std::string &header); // Big-endian, for writing straight to file using File::WriteStringToFile. void CodeToBinaryStringBE(const std::vector &code, std::string &str); diff --git a/Source/Core/DSPCore/Src/assemble.cpp b/Source/Core/DSPCore/Src/assemble.cpp index 8032a6e46a..940fb100d7 100644 --- a/Source/Core/DSPCore/Src/assemble.cpp +++ b/Source/Core/DSPCore/Src/assemble.cpp @@ -140,7 +140,7 @@ void DSPAssembler::ShowError(err_t err_code, const char *extra_info) failed = true; char error_buffer[1024]; 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) extra_info = "-"; diff --git a/Source/DSPTool/Src/main.cpp b/Source/DSPTool/Src/main.cpp index 8896f1e79d..7bc9943b00 100644 --- a/Source/DSPTool/Src/main.cpp +++ b/Source/DSPTool/Src/main.cpp @@ -210,9 +210,10 @@ int main(int argc, const char *argv[]) { if(argc == 1 || (argc == 2 && (!strcmp(argv[1], "--help") || (!strcmp(argv[1], "-?"))))) { - printf("USAGE: DSPTool [-?] [--help] [-d] [-o ] [-h ] \n"); + printf("USAGE: DSPTool [-?] [--help] [-d] [-m] [-o ] [-h ] \n"); printf("-? / --help: Prints this message\n"); printf("-d: Disassemble\n"); + printf("-m: Input file contains a list of files (Header assembly only)\n"); printf("-o : Results from stdout redirected to a file\n"); printf("-h
: Output assembly results to a header\n"); return 0; @@ -228,8 +229,7 @@ int main(int argc, const char *argv[]) std::string output_header_name; std::string output_name; - bool disassemble = false; - bool compare = false; + bool disassemble = false, compare = false, multiple = false; for (int i = 1; i < argc; i++) { if (!strcmp(argv[i], "-d")) @@ -240,22 +240,31 @@ int main(int argc, const char *argv[]) output_header_name = argv[++i]; else if (!strcmp(argv[i], "-c")) compare = true; + else if (!strcmp(argv[i], "-m")) + multiple = true; else { if (!input_name.empty()) { - printf("Can only take one input file.\n"); + printf("ERROR: Can only take one input file.\n"); return 1; } input_name = argv[i]; if (!File::Exists(input_name.c_str())) { - printf("Input path does not exist.\n"); + printf("ERROR: Input path does not exist.\n"); 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) { // Two binary inputs, let's diff. @@ -297,24 +306,82 @@ int main(int argc, const char *argv[]) std::string source; if (File::ReadFileToString(true, input_name.c_str(), source)) { - std::vector code; - - if(!Assemble(source.c_str(), code)) { - printf("Assemble: Assembly failed due to errors\n"); - return 1; - } - - if (!output_name.empty()) + if(multiple) { - 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); + // When specifying a list of files we must compile a header + // (we can't assemble multiple files to one binary) + // since we checked it before, we assume output_header_name isn't empty + int lines; + std::vector *codes; + std::vector files; + std::string header, currentSource; + 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[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()); + + delete[] codes; + } + else + { + std::vector 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(); @@ -323,4 +390,4 @@ int main(int argc, const char *argv[]) printf("Assembly completed successfully!\n"); return 0; -} \ No newline at end of file +}