-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlab5.cpp
95 lines (80 loc) · 3.24 KB
/
lab5.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#include "codegen.h"
#include <memory>
#include <optional>
#include <string>
using namespace llvm;
using namespace llvm::sys;
namespace codegen {
bool codeGenerate(const std::string &ir_filename,
const CodeGenFileType &gen_filetype) {
SMDiagnostic error_smdiagnostic;
LLVMContext context;
std::unique_ptr<Module> module =
parseIRFile(ir_filename, error_smdiagnostic, context);
if (!module) {
error_smdiagnostic.print(ir_filename.c_str(), errs());
return false;
}
// Initialize the target registry etc.
// *******************************************************************
// 补充代码1 - 初始化目标
InitializeAllTargetInfos();
InitializeAllTargets();
InitializeAllTargetMCs();
InitializeAllAsmParsers();
InitializeAllAsmPrinters();
//auto target_triple = module->getTargetTriple();
//auto target_triple = getDefaultTargetTriple();
auto target_triple = "riscv64-unknown-elf";
//auto target_triple = "armv7-unknown-linux-gnueagihf";
// **********************************************************************
// 补充代码2 - 指定目标平台
module->setTargetTriple(target_triple);
std::string error_string;
auto target = TargetRegistry::lookupTarget(target_triple, error_string);
// Print an error and exit if we couldn't find the requested target.
// This generally occurs if we've forgotten to initialise the
// TargetRegistry or we have a bogus target triple.
if (!target) {
errs() << error_string;
return 1;
}
auto cpu = "generic-rv64";
// auto cpu = "";
auto features = "";
TargetOptions opt;
auto RM = Optional<Reloc::Model>();
auto TheTargetMachine =
target->createTargetMachine(target_triple, cpu, features, opt, RM);
module->setDataLayout(TheTargetMachine->createDataLayout());
// *************************************************************************
// 补充代码3 - 初始化addPassesToEmitFile()的参数,请按以下顺序
// (1) 调用getGenFilename()函数,获得要写入的目标代码文件名filename
// (2) 实例化raw_fd_ostream类的对象dest。构造函数:
// raw_fd_ostream(StringRef Filename, std::error_code &EC, sys::fs::OpenFlags Flags);
// Flags置sys::fs::OF_None
// 注意EC是一个std::error_code类型的对象,你需要事先声明EC,
// 通常还应在调用函数后检查EC,if (EC) 则表明有错误发生(无法创建目标文件),此时应该输出提示信息后return 1
// (3) 实例化legacy::PassManager类的对象pass
// (4) 为file_type赋初值。
auto filename = getGenFilename(ir_filename, gen_filetype);
std::error_code EC;
raw_fd_ostream dest(filename, EC, sys::fs::OF_None);
if (EC) return 1;
legacy::PassManager pass;
auto file_type = gen_filetype;
if (TheTargetMachine -> addPassesToEmitFile(pass, dest, nullptr, file_type)) {
errs() << "TheTargetMachine can't emit a file of this type";
return 1;
}
pass.run(*module);
dest.flush();
return true;
}
std::string getGenFilename(const std::string &ir_filename, const CodeGenFileType &gen_filetype) {
if (gen_filetype == CGFT_Null) {
return nullptr;
}
return ir_filename.substr(0, ir_filename.find(".")) + (gen_filetype == CGFT_AssemblyFile ? ".s" : ".o");
}
} // namespace codegen