~registry/dolphin-emu/triforce

« back to all changes in this revision

Viewing changes to Source/Core/Core/Src/DSP/DSPCodeUtil.cpp

  • Committer: Sérgio Benjamim
  • Date: 2015-02-13 05:54:40 UTC
  • Revision ID: sergio_br2@yahoo.com.br-20150213055440-ey2rt3sjpy27km78
Dolphin Triforce branch from code.google, commit b957980 (4.0-315).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright 2013 Dolphin Emulator Project
 
2
// Licensed under GPLv2
 
3
// Refer to the license.txt file included.
 
4
 
 
5
#include <iostream>
 
6
#include <vector>
 
7
 
 
8
#include "Common.h"
 
9
#include "FileUtil.h"
 
10
#include "StringUtil.h"
 
11
#include "DSPCodeUtil.h"
 
12
#include "assemble.h"
 
13
#include "disassemble.h"
 
14
 
 
15
 
 
16
bool Assemble(const char *text, std::vector<u16> &code, bool force)
 
17
{
 
18
        AssemblerSettings settings;
 
19
        //      settings.pc = 0;
 
20
        // settings.decode_registers = false;
 
21
        // settings.decode_names = false;
 
22
        settings.force = force;
 
23
        //      settings.print_tabs = false;
 
24
        //      settings.ext_separator = '\'';
 
25
 
 
26
        // TODO: fix the terrible api of the assembler.
 
27
        DSPAssembler assembler(settings);
 
28
        if (!assembler.Assemble(text, code))
 
29
        {
 
30
                std::cerr << assembler.GetErrorString() << std::endl;
 
31
                return false;
 
32
        }
 
33
 
 
34
        return true;
 
35
}
 
36
 
 
37
bool Disassemble(const std::vector<u16> &code, bool line_numbers, std::string &text)
 
38
{
 
39
        if (code.empty())
 
40
                return false;
 
41
 
 
42
        AssemblerSettings settings;
 
43
 
 
44
        // These two prevent roundtripping.
 
45
        settings.show_hex = true;
 
46
        settings.show_pc = line_numbers;
 
47
        settings.ext_separator = '\'';
 
48
        settings.decode_names = true;
 
49
        settings.decode_registers = true;
 
50
 
 
51
        DSPDisassembler disasm(settings);
 
52
        bool success = disasm.Disassemble(0, code, 0x0000, text);
 
53
        return success;
 
54
}
 
55
 
 
56
bool Compare(const std::vector<u16> &code1, const std::vector<u16> &code2)
 
57
{               
 
58
        if (code1.size() != code2.size())
 
59
                printf("Size difference! 1=%i 2=%i\n", (int)code1.size(), (int)code2.size());
 
60
        u32 count_equal = 0;
 
61
        const int min_size = (int)std::min(code1.size(), code2.size());
 
62
 
 
63
        AssemblerSettings settings;
 
64
        DSPDisassembler disassembler(settings);
 
65
        for (int i = 0; i < min_size; i++)
 
66
        {
 
67
                if (code1[i] == code2[i])
 
68
                {
 
69
                        count_equal++;
 
70
                }
 
71
                else
 
72
                {
 
73
                        std::string line1, line2;
 
74
                        u16 pc = i;
 
75
                        disassembler.DisOpcode(&code1[0], 0x0000, 2, &pc, line1);
 
76
                        pc = i;
 
77
                        disassembler.DisOpcode(&code2[0], 0x0000, 2, &pc, line2);
 
78
                        printf("!! %04x : %04x vs %04x - %s  vs  %s\n", i, code1[i], code2[i], line1.c_str(), line2.c_str());
 
79
                }
 
80
        }
 
81
        if (code2.size() != code1.size())
 
82
        {
 
83
                printf("Extra code words:\n");
 
84
                const std::vector<u16> &longest = code1.size() > code2.size() ? code1 : code2;
 
85
                for (int i = min_size; i < (int)longest.size(); i++)
 
86
                {
 
87
                        u16 pc = i;
 
88
                        std::string line;
 
89
                        disassembler.DisOpcode(&longest[0], 0x0000, 2, &pc, line);
 
90
                        printf("!! %s\n", line.c_str());
 
91
                }
 
92
        }
 
93
        printf("Equal instruction words: %i / %i\n", count_equal, min_size);
 
94
        return code1.size() == code2.size() && code1.size() == count_equal;
 
95
}
 
96
 
 
97
void GenRandomCode(u32 size, std::vector<u16> &code) 
 
98
{
 
99
        code.resize(size);
 
100
        for (u32 i = 0; i < size; i++)
 
101
        {
 
102
                code[i] = rand() ^ (rand() << 8);
 
103
        }
 
104
}
 
105
 
 
106
void CodeToHeader(const std::vector<u16> &code, std::string _filename,
 
107
                                  const char *name, std::string &header)
 
108
{
 
109
        std::vector<u16> code_padded = code;
 
110
        // Pad with nops to 32byte boundary
 
111
        while (code_padded.size() & 0x7f)
 
112
                code_padded.push_back(0);
 
113
 
 
114
        char buffer[1024];
 
115
        header.clear();
 
116
        header.reserve(code_padded.size() * 4);
 
117
        header.append("#define NUM_UCODES 1\n\n");
 
118
        std::string filename;
 
119
        SplitPath(_filename, NULL, &filename, NULL);
 
120
        header.append(StringFromFormat("const char* UCODE_NAMES[NUM_UCODES] = {\"%s\"};\n\n", filename.c_str()));
 
121
        header.append("const unsigned short dsp_code[NUM_UCODES][0x1000] = {\n");
 
122
 
 
123
        header.append("\t{\n\t\t");
 
124
        for (u32 j = 0; j < code_padded.size(); j++)
 
125
        {
 
126
                if (j && ((j & 15) == 0))
 
127
                        header.append("\n\t\t");
 
128
                sprintf(buffer, "0x%04x, ", code_padded[j]);
 
129
                header.append(buffer);
 
130
        }
 
131
        header.append("\n\t},\n");
 
132
 
 
133
        header.append("};\n");
 
134
}
 
135
 
 
136
void CodesToHeader(const std::vector<u16> *codes, const std::vector<std::string>* filenames,
 
137
                                   u32 numCodes, const char *name, std::string &header)
 
138
{
 
139
        std::vector<std::vector<u16> > codes_padded;
 
140
        char buffer[1024];
 
141
        u32 reserveSize = 0;
 
142
        for(u32 i = 0; i < numCodes; i++)
 
143
        {
 
144
                codes_padded.push_back(codes[i]);
 
145
                // Pad with nops to 32byte boundary
 
146
                while (codes_padded.at(i).size() & 0x7f)
 
147
                        codes_padded.at(i).push_back(0);
 
148
 
 
149
                reserveSize += (u32)codes_padded.at(i).size();
 
150
        }
 
151
 
 
152
        
 
153
        header.clear();
 
154
        header.reserve(reserveSize * 4);
 
155
        sprintf(buffer, "#define NUM_UCODES %u\n\n", numCodes);
 
156
        header.append(buffer);
 
157
        header.append("const char* UCODE_NAMES[NUM_UCODES] = {\n");
 
158
        for (u32 i = 0; i < numCodes; i++)
 
159
        {
 
160
                std::string filename;
 
161
                if (! SplitPath(filenames->at(i), NULL, &filename, NULL))
 
162
                        filename = filenames->at(i);
 
163
                sprintf(buffer, "\t\"%s\",\n", filename.c_str());
 
164
                header.append(buffer);
 
165
        }
 
166
        header.append("};\n\n");
 
167
        header.append("const unsigned short dsp_code[NUM_UCODES][0x1000] = {\n");
 
168
 
 
169
        for(u32 i = 0; i < numCodes; i++)
 
170
        {
 
171
                if(codes[i].size() == 0)
 
172
                        continue;
 
173
 
 
174
                header.append("\t{\n\t\t");
 
175
                for (u32 j = 0; j < codes_padded.at(i).size(); j++) 
 
176
                {
 
177
                        if (j && ((j & 15) == 0))
 
178
                                header.append("\n\t\t");
 
179
                        sprintf(buffer, "0x%04x, ", codes_padded.at(i).at(j));
 
180
                        header.append(buffer);
 
181
                }
 
182
                header.append("\n\t},\n");
 
183
        }
 
184
        header.append("};\n");
 
185
}
 
186
 
 
187
void CodeToBinaryStringBE(const std::vector<u16> &code, std::string &str)
 
188
{
 
189
        str.resize(code.size() * 2);
 
190
        for (size_t i = 0; i < code.size(); i++)
 
191
        {
 
192
                str[i * 2 + 0] = code[i] >> 8;
 
193
                str[i * 2 + 1] = code[i] & 0xff;
 
194
        }
 
195
}
 
196
 
 
197
void BinaryStringBEToCode(const std::string &str, std::vector<u16> &code)
 
198
{
 
199
        code.resize(str.size() / 2);
 
200
        for (size_t i = 0; i < code.size(); i++)
 
201
        {
 
202
                code[i] = ((u16)(u8)str[i * 2 + 0] << 8) | ((u16)(u8)str[i * 2 + 1]);
 
203
        }
 
204
}
 
205
 
 
206
bool LoadBinary(const char *filename, std::vector<u16> &code)
 
207
{
 
208
        std::string buffer;
 
209
        if (!File::ReadFileToString(false, filename, buffer))
 
210
                return false;
 
211
 
 
212
        BinaryStringBEToCode(buffer, code);
 
213
        return true;
 
214
}
 
215
 
 
216
bool SaveBinary(const std::vector<u16> &code, const char *filename)
 
217
{
 
218
        std::string buffer;
 
219
        CodeToBinaryStringBE(code, buffer);
 
220
        if (!File::WriteStringToFile(false, buffer, filename))
 
221
                return false;
 
222
        return true;
 
223
}