OpenCores
URL https://opencores.org/ocsvn/fwrisc/fwrisc/trunk

Subversion Repositories fwrisc

[/] [fwrisc/] [trunk/] [ve/] [fwrisc/] [tests/] [AsmTestCompiler.cpp] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 mballance
/*
2
 * AsmTestCompiler.cpp
3
 *
4
 *
5
 * Copyright 2018 Matthew Ballance
6
 *
7
 * Licensed under the Apache License, Version 2.0 (the
8
 * "License"); you may not use this file except in
9
 * compliance with the License.  You may obtain a copy of
10
 * the License at
11
 *
12
 * http://www.apache.org/licenses/LICENSE-2.0
13
 *
14
 * Unless required by applicable law or agreed to in
15
 * writing, software distributed under the License is
16
 * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
17
 * CONDITIONS OF ANY KIND, either express or implied.  See
18
 * the License for the specific language governing
19
 * permissions and limitations under the License.
20
 *
21
 *  Created on: Oct 28, 2018
22
 *      Author: ballance
23
 */
24
 
25
#include "AsmTestCompiler.h"
26
#include <stdlib.h>
27
#include <stdio.h>
28
#include <vector>
29
#include <ctype.h>
30
#include <string.h>
31
 
32
AsmTestCompiler::AsmTestCompiler(
33
                const std::string       &basename,
34
                const std::string       &program,
35
                const std::string       &out) {
36
        m_basename = basename;
37
        m_program = program;
38
        m_out = out;
39
 
40
}
41
 
42
AsmTestCompiler::~AsmTestCompiler() {
43
        // TODO Auto-generated destructor stub
44
}
45
 
46
bool AsmTestCompiler::compile(
47
                const std::string       &basename,
48
                const std::string       &program,
49
                const std::string       &out) {
50
        AsmTestCompiler compiler(basename, program, out);
51
 
52
        return compiler.compile();
53
}
54
 
55
bool AsmTestCompiler::compile() {
56
        std::string full_program = R"(
57
                .section .text.init;
58
                .globl _start
59
                _start:
60
                        j               test_program
61
                done:
62
                        j               done
63
                test_program:   //
64
        )";
65
        full_program += m_program;
66
 
67
        std::string cmd;
68
 
69
        std::string filename;
70
        FILE *fh;
71
 
72
        filename = m_basename + ".link.ld";
73
        fh = fopen(filename.c_str(), "wb");
74
        fputs(R"(
75
                OUTPUT_ARCH("riscv")
76
                ENTRY(_start)
77
 
78
                SECTIONS
79
                {
80
                        . = 0x00000000;
81
                        .text.init : { *(.text.init) }
82
                        . = ALIGN(0x1000);
83
                        _end = .;
84
                }
85
 
86
        )", fh);
87
        fclose(fh);
88
 
89
 
90
        filename = m_basename + ".test.S";
91
        fh = fopen(filename.c_str(), "wb");
92
 
93
        if (!fh) {
94
                fprintf(stdout, "Error: failed to open file \"%s\"\n", filename.c_str());
95
                return false;
96
        }
97
        fputs(full_program.c_str(), fh);
98
        fclose(fh);
99
 
100
        cmd = "riscv32-unknown-elf-gcc -march=rv32i -mabi=ilp32 -o ";
101
        cmd += m_basename + ".test.elf ";
102
        cmd += "-static -mcmodel=medany -fvisibility=hidden ";
103
        cmd += "-nostdlib -nostartfiles ";
104
        cmd += m_basename + ".test.S ";
105
        cmd += "-T ";
106
        cmd += m_basename + ".link.ld";
107
 
108
        if (system(cmd.c_str()) != 0) {
109
                fprintf(stdout, "compile failed\n");
110
                return false;
111
        }
112
 
113
        cmd = "riscv32-unknown-elf-objcopy ";
114
        cmd += m_basename + ".test.elf ";
115
        cmd += "-O verilog ";
116
        cmd += m_basename + ".test.vlog";
117
 
118
        if (system(cmd.c_str()) != 0) {
119
                fprintf(stdout, "objcopy failed\n");
120
                return false;
121
        }
122
 
123
        if (!tohex(m_basename + ".test.vlog", m_out)) {
124
                fprintf(stdout, "tohex failed\n");
125
                return false;
126
        }
127
 
128
        return true;
129
}
130
 
131
bool AsmTestCompiler::tohex(
132
                const std::string &file_vlog,
133
                const std::string &file_hex) {
134
        char tmp[1024];
135
        bool ret = true;
136
        FILE *fh_vlog = fopen(file_vlog.c_str(), "rb");
137
        FILE *fh_hex = fopen(file_hex.c_str(), "wb");
138
 
139
        if (!fh_vlog || !fh_hex) {
140
                fprintf(stdout, "Error: failed to open files\n");
141
                return false;
142
        }
143
 
144
        // Prime the pump
145
        fgets(tmp, sizeof(tmp), fh_vlog);
146
 
147
        while (true) {
148
                uint32_t wordaddr;
149
                if (tmp[0] != '@') {
150
                        fprintf(stdout, "Error: unknown record: %s", tmp);
151
                        ret = false;
152
                        break;
153
                }
154
 
155
                wordaddr = strtoul(&tmp[1], 0, 16);
156
                wordaddr /= 4;
157
 
158
                fprintf(fh_hex, "@%08x\n", wordaddr);
159
 
160
                while (fgets(tmp, sizeof(tmp), fh_vlog)) {
161
                        if (tmp[0] != '@') {
162
                                std::vector<std::string> bytes;
163
                                uint32_t len = strlen(tmp);
164
                                uint32_t i=0;
165
 
166
                                while (i<len) {
167
                                        std::string byte;
168
                                        // Skip whitespace
169
                                        while (i < len && isspace(tmp[i])) {
170
                                                i++;
171
                                        }
172
 
173
                                        // Stuff non-whitespace into a byte
174
                                        while (i < len && !isspace(tmp[i])) {
175
                                                byte.push_back(tmp[i]);
176
                                                i++;
177
                                        }
178
 
179
                                        if (byte.size() > 0) {
180
                                                bytes.push_back(byte);
181
                                        }
182
                                }
183
 
184
                                for (i=0; i<bytes.size(); i+=4) {
185
                                        for (int j=4-1; j>=0; j--) {
186
                                                if (i+j < bytes.size()) {
187
                                                        fprintf(fh_hex, "%s", bytes.at(i+j).c_str());
188
                                                } else {
189
                                                        fprintf(fh_hex, "00");
190
                                                }
191
                                        }
192
                                        fprintf(fh_hex, "\n");
193
                                }
194
                        } else {
195
                                break;
196
                        }
197
                }
198
 
199
                if (feof(fh_vlog)) {
200
                        break;
201
                }
202
        }
203
 
204
        fclose(fh_vlog);
205
        fclose(fh_hex);
206
 
207
        return ret;
208
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.